mirror of
https://github.com/chatmail/core.git
synced 2026-05-09 01:46:30 +03:00
fix last prepares
This commit is contained in:
139
src/dc_imex.rs
139
src/dc_imex.rs
@@ -1010,81 +1010,82 @@ unsafe fn export_backup(context: &Context, dir: *const libc::c_char) -> libc::c_
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
let dir_handle = dir_handle.unwrap();
|
let dir_handle = dir_handle.unwrap();
|
||||||
let mut stmt = dc_sqlite3_prepare(
|
|
||||||
context,
|
|
||||||
&sql,
|
|
||||||
"INSERT INTO backup_blobs (file_name, file_content) VALUES (?, ?);"
|
|
||||||
).expect("bad sql state");
|
|
||||||
|
|
||||||
let mut processed_files_cnt = 0;
|
sql.prepare(
|
||||||
for entry in dir_handle {
|
"INSERT INTO backup_blobs (file_name, file_content) VALUES (?, ?);",
|
||||||
if entry.is_err() {
|
move |mut stmt| {
|
||||||
current_block = 2631791190359682872;
|
let mut processed_files_cnt = 0;
|
||||||
break;
|
for entry in dir_handle {
|
||||||
}
|
if entry.is_err() {
|
||||||
let entry = entry.unwrap();
|
current_block = 2631791190359682872;
|
||||||
if context
|
break;
|
||||||
.running_state
|
}
|
||||||
.clone()
|
let entry = entry.unwrap();
|
||||||
.read()
|
if context
|
||||||
.unwrap()
|
.running_state
|
||||||
.shall_stop_ongoing
|
.clone()
|
||||||
{
|
.read()
|
||||||
delete_dest_file = 1;
|
.unwrap()
|
||||||
current_block = 11487273724841241105;
|
.shall_stop_ongoing
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
processed_files_cnt += 1;
|
|
||||||
let mut permille =
|
|
||||||
processed_files_cnt * 1000 / total_files_cnt;
|
|
||||||
if permille < 10 {
|
|
||||||
permille = 10;
|
|
||||||
}
|
|
||||||
if permille > 990 {
|
|
||||||
permille = 990;
|
|
||||||
}
|
|
||||||
context.call_cb(
|
|
||||||
Event::IMEX_PROGRESS,
|
|
||||||
permille as uintptr_t,
|
|
||||||
0 as uintptr_t,
|
|
||||||
);
|
|
||||||
|
|
||||||
let name_f = entry.file_name();
|
|
||||||
let name = name_f.to_string_lossy();
|
|
||||||
if name.starts_with("delta-chat") && name.ends_with(".bak")
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
info!(context, 0, "EXPORTing filename={}", name);
|
|
||||||
let curr_pathNfilename = format!(
|
|
||||||
"{}/{}",
|
|
||||||
as_str(context.get_blobdir()),
|
|
||||||
name
|
|
||||||
);
|
|
||||||
|
|
||||||
if let Some(buf) =
|
|
||||||
dc_read_file_safe(context, &curr_pathNfilename)
|
|
||||||
{
|
{
|
||||||
if buf.is_empty() {
|
delete_dest_file = 1;
|
||||||
continue;
|
current_block = 11487273724841241105;
|
||||||
}
|
break;
|
||||||
if stmt.execute(params![name, buf]).is_err() {
|
|
||||||
error!(
|
|
||||||
context,
|
|
||||||
0,
|
|
||||||
"Disk full? Cannot add file \"{}\" to backup.",
|
|
||||||
&curr_pathNfilename,
|
|
||||||
);
|
|
||||||
/* this is not recoverable! writing to the sqlite database should work! */
|
|
||||||
current_block = 11487273724841241105;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
continue;
|
processed_files_cnt += 1;
|
||||||
|
let mut permille =
|
||||||
|
processed_files_cnt * 1000 / total_files_cnt;
|
||||||
|
if permille < 10 {
|
||||||
|
permille = 10;
|
||||||
|
}
|
||||||
|
if permille > 990 {
|
||||||
|
permille = 990;
|
||||||
|
}
|
||||||
|
context.call_cb(
|
||||||
|
Event::IMEX_PROGRESS,
|
||||||
|
permille as uintptr_t,
|
||||||
|
0 as uintptr_t,
|
||||||
|
);
|
||||||
|
|
||||||
|
let name_f = entry.file_name();
|
||||||
|
let name = name_f.to_string_lossy();
|
||||||
|
if name.starts_with("delta-chat") && name.ends_with(".bak")
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
info!(context, 0, "EXPORTing filename={}", name);
|
||||||
|
let curr_pathNfilename = format!(
|
||||||
|
"{}/{}",
|
||||||
|
as_str(context.get_blobdir()),
|
||||||
|
name
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Some(buf) =
|
||||||
|
dc_read_file_safe(context, &curr_pathNfilename)
|
||||||
|
{
|
||||||
|
if buf.is_empty() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if stmt.execute(params![name, buf]).is_err() {
|
||||||
|
error!(
|
||||||
|
context,
|
||||||
|
0,
|
||||||
|
"Disk full? Cannot add file \"{}\" to backup.",
|
||||||
|
&curr_pathNfilename,
|
||||||
|
);
|
||||||
|
/* this is not recoverable! writing to the sqlite database should work! */
|
||||||
|
current_block = 11487273724841241105;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
).unwrap();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
info!(context, 0, "Backup: No files to copy.",);
|
info!(context, 0, "Backup: No files to copy.",);
|
||||||
|
|||||||
@@ -409,71 +409,52 @@ pub unsafe fn dc_save_locations(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
let stmt_test = dc_sqlite3_prepare(
|
context
|
||||||
context,
|
.sql
|
||||||
&context.sql,
|
.prepare2(
|
||||||
"SELECT id FROM locations WHERE timestamp=? AND from_id=?",
|
"SELECT id FROM locations WHERE timestamp=? AND from_id=?",
|
||||||
);
|
"INSERT INTO locations\
|
||||||
let stmt_insert = dc_sqlite3_prepare(
|
(timestamp, from_id, chat_id, latitude, longitude, accuracy, independent) \
|
||||||
context,
|
VALUES (?,?,?,?,?,?,?);",
|
||||||
&context.sql,
|
|mut stmt_test, mut stmt_insert, conn| {
|
||||||
"INSERT INTO locations\
|
let mut newest_timestamp = 0;
|
||||||
(timestamp, from_id, chat_id, latitude, longitude, accuracy, independent) \
|
let mut newest_location_id = 0;
|
||||||
VALUES (?,?,?,?,?,?,?);",
|
|
||||||
);
|
|
||||||
|
|
||||||
if stmt_test.is_none() || stmt_insert.is_none() {
|
for i in 0..dc_array_get_cnt(locations) {
|
||||||
return 0;
|
let location = dc_array_get_ptr(locations, i as size_t) as *mut dc_location_t;
|
||||||
}
|
|
||||||
|
|
||||||
let mut stmt_test = stmt_test.unwrap();
|
let exists =
|
||||||
let mut stmt_insert = stmt_insert.unwrap();
|
stmt_test.exists(params![(*location).timestamp, contact_id as i32])?;
|
||||||
|
|
||||||
let mut newest_timestamp = 0;
|
if 0 != independent || !exists {
|
||||||
let mut newest_location_id = 0;
|
stmt_insert.execute(params![
|
||||||
|
(*location).timestamp,
|
||||||
|
contact_id as i32,
|
||||||
|
chat_id as i32,
|
||||||
|
(*location).latitude,
|
||||||
|
(*location).longitude,
|
||||||
|
(*location).accuracy,
|
||||||
|
independent,
|
||||||
|
])?;
|
||||||
|
|
||||||
for i in 0..dc_array_get_cnt(locations) {
|
if (*location).timestamp > newest_timestamp {
|
||||||
// TODO: do I need to reset?
|
newest_timestamp = (*location).timestamp;
|
||||||
|
newest_location_id = get_rowid2(
|
||||||
let location = dc_array_get_ptr(locations, i as size_t) as *mut dc_location_t;
|
context,
|
||||||
|
conn,
|
||||||
let exists = stmt_test
|
"locations",
|
||||||
.exists(params![(*location).timestamp, contact_id as i32])
|
"timestamp",
|
||||||
.unwrap_or_default();
|
(*location).timestamp,
|
||||||
|
"from_id",
|
||||||
if 0 != independent || !exists {
|
contact_id as i32,
|
||||||
// TODO: do I need to reset?
|
);
|
||||||
if stmt_insert
|
}
|
||||||
.execute(params![
|
}
|
||||||
(*location).timestamp,
|
}
|
||||||
contact_id as i32,
|
Ok(newest_location_id)
|
||||||
chat_id as i32,
|
},
|
||||||
(*location).latitude,
|
)
|
||||||
(*location).longitude,
|
.unwrap_or_default()
|
||||||
(*location).accuracy,
|
|
||||||
independent,
|
|
||||||
])
|
|
||||||
.is_err()
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*location).timestamp > newest_timestamp {
|
|
||||||
newest_timestamp = (*location).timestamp;
|
|
||||||
newest_location_id = dc_sqlite3_get_rowid2(
|
|
||||||
context,
|
|
||||||
&context.sql,
|
|
||||||
"locations",
|
|
||||||
"timestamp",
|
|
||||||
(*location).timestamp,
|
|
||||||
"from_id",
|
|
||||||
contact_id as i32,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
newest_location_id
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn dc_kml_parse(
|
pub unsafe fn dc_kml_parse(
|
||||||
@@ -677,9 +658,7 @@ pub unsafe fn dc_job_do_DC_JOB_MAYBE_SEND_LOCATIONS(context: &Context, _job: *mu
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|rows| {
|
|rows| {
|
||||||
let stmt_locations = dc_sqlite3_prepare(
|
context.sql.prepare(
|
||||||
context,
|
|
||||||
&context.sql,
|
|
||||||
"SELECT id \
|
"SELECT id \
|
||||||
FROM locations \
|
FROM locations \
|
||||||
WHERE from_id=? \
|
WHERE from_id=? \
|
||||||
@@ -687,44 +666,40 @@ pub unsafe fn dc_job_do_DC_JOB_MAYBE_SEND_LOCATIONS(context: &Context, _job: *mu
|
|||||||
AND timestamp>? \
|
AND timestamp>? \
|
||||||
AND independent=0 \
|
AND independent=0 \
|
||||||
ORDER BY timestamp;",
|
ORDER BY timestamp;",
|
||||||
);
|
|mut stmt_locations| {
|
||||||
if stmt_locations.is_none() {
|
for (chat_id, locations_send_begin, locations_last_sent) in
|
||||||
// TODO: handle error
|
rows.filter_map(|r| match r {
|
||||||
return Ok(());
|
Ok(Some(v)) => Some(v),
|
||||||
}
|
_ => None,
|
||||||
let mut stmt_locations = stmt_locations.unwrap();
|
})
|
||||||
|
{
|
||||||
for (chat_id, locations_send_begin, locations_last_sent) in
|
// TODO: do I need to reset?
|
||||||
rows.filter_map(|r| match r {
|
if !stmt_locations
|
||||||
Ok(Some(v)) => Some(v),
|
.exists(params![1, locations_send_begin, locations_last_sent,])
|
||||||
_ => None,
|
.unwrap_or_default()
|
||||||
})
|
{
|
||||||
{
|
// if there is no new location, there's nothing to send.
|
||||||
// TODO: do I need to reset?
|
// however, maybe we want to bypass this test eg. 15 minutes
|
||||||
if !stmt_locations
|
continue;
|
||||||
.exists(params![1, locations_send_begin, locations_last_sent,])
|
}
|
||||||
.unwrap_or_default()
|
// pending locations are attached automatically to every message,
|
||||||
{
|
// so also to this empty text message.
|
||||||
// if there is no new location, there's nothing to send.
|
// DC_CMD_LOCATION is only needed to create a nicer subject.
|
||||||
// however, maybe we want to bypass this test eg. 15 minutes
|
//
|
||||||
continue;
|
// for optimisation and to avoid flooding the sending queue,
|
||||||
}
|
// we could sending these messages only if we're really online.
|
||||||
// pending locations are attached automatically to every message,
|
// the easiest way to determine this, is to check for an empty message queue.
|
||||||
// so also to this empty text message.
|
// (might not be 100%, however, as positions are sent combined later
|
||||||
// DC_CMD_LOCATION is only needed to create a nicer subject.
|
// and dc_set_location() is typically called periodically, this is ok)
|
||||||
//
|
let mut msg = dc_msg_new(context, 10);
|
||||||
// for optimisation and to avoid flooding the sending queue,
|
(*msg).hidden = 1;
|
||||||
// we could sending these messages only if we're really online.
|
dc_param_set_int((*msg).param, 'S' as i32, 9);
|
||||||
// the easiest way to determine this, is to check for an empty message queue.
|
dc_send_msg(context, chat_id as u32, msg);
|
||||||
// (might not be 100%, however, as positions are sent combined later
|
dc_msg_unref(msg);
|
||||||
// and dc_set_location() is typically called periodically, this is ok)
|
}
|
||||||
let mut msg = dc_msg_new(context, 10);
|
Ok(())
|
||||||
(*msg).hidden = 1;
|
},
|
||||||
dc_param_set_int((*msg).param, 'S' as i32, 9);
|
)
|
||||||
dc_send_msg(context, chat_id as u32, msg);
|
|
||||||
dc_msg_unref(msg);
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.unwrap(); // TODO: Better error handling
|
.unwrap(); // TODO: Better error handling
|
||||||
|
|||||||
107
src/dc_msg.rs
107
src/dc_msg.rs
@@ -524,54 +524,50 @@ pub fn dc_update_msg_chat_id(context: &Context, msg_id: u32, chat_id: u32) -> bo
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn dc_markseen_msgs(context: &Context, msg_ids: *const u32, msg_cnt: usize) {
|
pub fn dc_markseen_msgs(context: &Context, msg_ids: *const u32, msg_cnt: usize) -> bool {
|
||||||
if msg_ids.is_null() || msg_cnt <= 0 {
|
if msg_ids.is_null() || msg_cnt <= 0 {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
let stmt = dc_sqlite3_prepare(
|
context.sql.prepare(
|
||||||
context, &context.sql,
|
"SELECT m.state, c.blocked FROM msgs m LEFT JOIN chats c ON c.id=m.chat_id WHERE m.id=? AND m.chat_id>9",
|
||||||
"SELECT m.state, c.blocked FROM msgs m LEFT JOIN chats c ON c.id=m.chat_id WHERE m.id=? AND m.chat_id>9"
|
|mut stmt| {
|
||||||
);
|
let mut send_event = false;
|
||||||
|
|
||||||
if stmt.is_none() {
|
for i in 0..msg_cnt {
|
||||||
// TODO: error handling
|
// TODO: do I need to reset?
|
||||||
return;
|
let id = unsafe { *msg_ids.offset(i as isize) };
|
||||||
}
|
if let Ok((curr_state, curr_blocked)) = stmt
|
||||||
|
.query_row(params![id as i32], |row| {
|
||||||
|
Ok((row.get::<_, i32>(0)?, row.get::<_, i32>(1)?))
|
||||||
|
})
|
||||||
|
{
|
||||||
|
if curr_blocked == 0 {
|
||||||
|
if curr_state == 10 || curr_state == 13 {
|
||||||
|
dc_update_msg_state(context, id, 16);
|
||||||
|
info!(context, 0, "Seen message #{}.", id);
|
||||||
|
|
||||||
let mut stmt = stmt.unwrap();
|
unsafe { dc_job_add(
|
||||||
let mut send_event = false;
|
context,
|
||||||
|
130,
|
||||||
for i in 0..msg_cnt {
|
id as i32,
|
||||||
// TODO: do I need to reset?
|
0 as *const libc::c_char,
|
||||||
if let Ok((curr_state, curr_blocked)) = stmt
|
0,
|
||||||
.query_row(params![*msg_ids.offset(i as isize) as i32], |row| {
|
) };
|
||||||
Ok((row.get::<_, i32>(0)?, row.get::<_, i32>(1)?))
|
send_event = true;
|
||||||
})
|
}
|
||||||
{
|
} else if curr_state == 10 {
|
||||||
if curr_blocked == 0 {
|
dc_update_msg_state(context, id, 13);
|
||||||
if curr_state == 10 || curr_state == 13 {
|
send_event = true;
|
||||||
dc_update_msg_state(context, *msg_ids.offset(i as isize), 16);
|
}
|
||||||
info!(context, 0, "Seen message #{}.", *msg_ids.offset(i as isize),);
|
|
||||||
|
|
||||||
dc_job_add(
|
|
||||||
context,
|
|
||||||
130,
|
|
||||||
*msg_ids.offset(i as isize) as libc::c_int,
|
|
||||||
0 as *const libc::c_char,
|
|
||||||
0,
|
|
||||||
);
|
|
||||||
send_event = true;
|
|
||||||
}
|
}
|
||||||
} else if curr_state == 10 {
|
|
||||||
dc_update_msg_state(context, *msg_ids.offset(i as isize), 13);
|
|
||||||
send_event = true;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if send_event {
|
if send_event {
|
||||||
context.call_cb(Event::MSGS_CHANGED, 0, 0);
|
context.call_cb(Event::MSGS_CHANGED, 0, 0);
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
).is_ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dc_update_msg_state(context: &Context, msg_id: uint32_t, state: libc::c_int) -> bool {
|
pub fn dc_update_msg_state(context: &Context, msg_id: uint32_t, state: libc::c_int) -> bool {
|
||||||
@@ -592,26 +588,15 @@ pub fn dc_star_msgs(
|
|||||||
if msg_ids.is_null() || msg_cnt <= 0 || star != 0 && star != 1 {
|
if msg_ids.is_null() || msg_cnt <= 0 || star != 0 && star != 1 {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
let stmt = dc_sqlite3_prepare(
|
context
|
||||||
context,
|
.sql
|
||||||
&context.sql,
|
.prepare("UPDATE msgs SET starred=? WHERE id=?;", |mut stmt| {
|
||||||
"UPDATE msgs SET starred=? WHERE id=?;",
|
for i in 0..msg_cnt {
|
||||||
);
|
stmt.execute(params![star, unsafe { *msg_ids.offset(i as isize) as i32 }])?;
|
||||||
if stmt.is_none() {
|
}
|
||||||
return false;
|
Ok(())
|
||||||
}
|
})
|
||||||
|
.is_ok()
|
||||||
let mut stmt = stmt.unwrap();
|
|
||||||
for i in 0..msg_cnt {
|
|
||||||
if stmt
|
|
||||||
.execute(params![star, unsafe { *msg_ids.offset(i as isize) as i32 }])
|
|
||||||
.is_err()
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn dc_get_msg<'a>(context: &'a Context, msg_id: uint32_t) -> *mut dc_msg_t<'a> {
|
pub unsafe fn dc_get_msg<'a>(context: &'a Context, msg_id: uint32_t) -> *mut dc_msg_t<'a> {
|
||||||
|
|||||||
@@ -489,122 +489,121 @@ pub unsafe fn dc_receive_imf(
|
|||||||
}
|
}
|
||||||
icnt = carray_count(mime_parser.parts) as size_t;
|
icnt = carray_count(mime_parser.parts) as size_t;
|
||||||
|
|
||||||
let mut stmt = dc_sqlite3_prepare(
|
context.sql.prepare(
|
||||||
context,
|
|
||||||
&context.sql,
|
|
||||||
"INSERT INTO msgs \
|
"INSERT INTO msgs \
|
||||||
(rfc724_mid, server_folder, server_uid, chat_id, from_id, to_id, timestamp, \
|
(rfc724_mid, server_folder, server_uid, chat_id, from_id, to_id, timestamp, \
|
||||||
timestamp_sent, timestamp_rcvd, type, state, msgrmsg, txt, txt_raw, param, \
|
timestamp_sent, timestamp_rcvd, type, state, msgrmsg, txt, txt_raw, param, \
|
||||||
bytes, hidden, mime_headers, mime_in_reply_to, mime_references) \
|
bytes, hidden, mime_headers, mime_in_reply_to, mime_references) \
|
||||||
VALUES (?,?,?,?,?,?, ?,?,?,?,?,?, ?,?,?,?,?,?, ?,?);"
|
VALUES (?,?,?,?,?,?, ?,?,?,?,?,?, ?,?,?,?,?,?, ?,?);",
|
||||||
).unwrap();
|
|mut stmt| {
|
||||||
i = 0;
|
let mut i = 0;
|
||||||
loop {
|
loop {
|
||||||
if !(i < icnt) {
|
if !(i < icnt) {
|
||||||
current_block = 2756754640271984560;
|
current_block = 2756754640271984560;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
let part: *mut dc_mimepart_t =
|
|
||||||
carray_get(mime_parser.parts, i as libc::c_uint)
|
|
||||||
as *mut dc_mimepart_t;
|
|
||||||
if !(0 != (*part).is_meta) {
|
|
||||||
if !mime_parser.location_kml.is_null()
|
|
||||||
&& icnt == 1
|
|
||||||
&& !(*part).msg.is_null()
|
|
||||||
&& (strcmp(
|
|
||||||
(*part).msg,
|
|
||||||
b"-location-\x00" as *const u8 as *const libc::c_char,
|
|
||||||
) == 0
|
|
||||||
|| *(*part).msg.offset(0isize) as libc::c_int == 0)
|
|
||||||
{
|
|
||||||
hidden = 1;
|
|
||||||
if state == 10 {
|
|
||||||
state = 13
|
|
||||||
}
|
}
|
||||||
}
|
let part = carray_get(mime_parser.parts, i as libc::c_uint) as *mut dc_mimepart_t;
|
||||||
if (*part).type_0 == 10 {
|
if !(0 != (*part).is_meta) {
|
||||||
txt_raw = dc_mprintf(
|
if !mime_parser.location_kml.is_null()
|
||||||
b"%s\n\n%s\x00" as *const u8 as *const libc::c_char,
|
&& icnt == 1
|
||||||
if !mime_parser.subject.is_null() {
|
&& !(*part).msg.is_null()
|
||||||
mime_parser.subject
|
&& (strcmp(
|
||||||
|
(*part).msg,
|
||||||
|
b"-location-\x00" as *const u8 as *const libc::c_char,
|
||||||
|
) == 0
|
||||||
|
|| *(*part).msg.offset(0isize) as libc::c_int == 0)
|
||||||
|
{
|
||||||
|
hidden = 1;
|
||||||
|
if state == 10 {
|
||||||
|
state = 13
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (*part).type_0 == 10 {
|
||||||
|
txt_raw = dc_mprintf(
|
||||||
|
b"%s\n\n%s\x00" as *const u8 as *const libc::c_char,
|
||||||
|
if !mime_parser.subject.is_null() {
|
||||||
|
mime_parser.subject
|
||||||
|
} else {
|
||||||
|
b"\x00" as *const u8 as *const libc::c_char
|
||||||
|
},
|
||||||
|
(*part).msg_raw,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if 0 != mime_parser.is_system_message {
|
||||||
|
dc_param_set_int(
|
||||||
|
(*part).param,
|
||||||
|
'S' as i32,
|
||||||
|
mime_parser.is_system_message,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let res = stmt.execute(params![
|
||||||
|
as_str(rfc724_mid),
|
||||||
|
server_folder.as_ref(),
|
||||||
|
server_uid as libc::c_int,
|
||||||
|
chat_id as libc::c_int,
|
||||||
|
from_id as libc::c_int,
|
||||||
|
to_id as libc::c_int,
|
||||||
|
sort_timestamp,
|
||||||
|
sent_timestamp,
|
||||||
|
rcvd_timestamp,
|
||||||
|
(*part).type_0,
|
||||||
|
state,
|
||||||
|
msgrmsg,
|
||||||
|
if !(*part).msg.is_null() {
|
||||||
|
as_str((*part).msg)
|
||||||
|
} else {
|
||||||
|
""
|
||||||
|
},
|
||||||
|
if !txt_raw.is_null() {
|
||||||
|
as_str(txt_raw)
|
||||||
|
} else {
|
||||||
|
""
|
||||||
|
},
|
||||||
|
as_str((*(*part).param).packed),
|
||||||
|
(*part).bytes,
|
||||||
|
hidden,
|
||||||
|
if 0 != save_mime_headers {
|
||||||
|
Some(as_str(imf_raw_not_terminated))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
|
as_str(mime_in_reply_to),
|
||||||
|
as_str(mime_references),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if res.is_err() {
|
||||||
|
info!(context, 0, "Cannot write DB.",);
|
||||||
|
/* i/o error - there is nothing more we can do - in other cases, we try to write at least an empty record */
|
||||||
|
current_block = 16282941964262048061;
|
||||||
|
break;
|
||||||
} else {
|
} else {
|
||||||
b"\x00" as *const u8 as *const libc::c_char
|
free(txt_raw as *mut libc::c_void);
|
||||||
},
|
txt_raw = 0 as *mut libc::c_char;
|
||||||
(*part).msg_raw,
|
insert_msg_id = dc_sqlite3_get_rowid(
|
||||||
)
|
context,
|
||||||
}
|
&context.sql,
|
||||||
if 0 != mime_parser.is_system_message {
|
"msgs",
|
||||||
dc_param_set_int(
|
"rfc724_mid",
|
||||||
(*part).param,
|
as_str(rfc724_mid),
|
||||||
'S' as i32,
|
);
|
||||||
mime_parser.is_system_message,
|
carray_add(
|
||||||
);
|
created_db_entries,
|
||||||
}
|
chat_id as uintptr_t as *mut libc::c_void,
|
||||||
|
0 as *mut libc::c_uint,
|
||||||
let res = stmt.execute(params![
|
);
|
||||||
as_str(rfc724_mid),
|
carray_add(
|
||||||
server_folder.as_ref(),
|
created_db_entries,
|
||||||
server_uid as libc::c_int,
|
insert_msg_id as uintptr_t as *mut libc::c_void,
|
||||||
chat_id as libc::c_int,
|
0 as *mut libc::c_uint,
|
||||||
from_id as libc::c_int,
|
);
|
||||||
to_id as libc::c_int,
|
}
|
||||||
sort_timestamp,
|
}
|
||||||
sent_timestamp,
|
i = i.wrapping_add(1)
|
||||||
rcvd_timestamp,
|
|
||||||
(*part).type_0,
|
|
||||||
state,
|
|
||||||
msgrmsg,
|
|
||||||
if !(*part).msg.is_null() {
|
|
||||||
as_str((*part).msg)
|
|
||||||
} else {
|
|
||||||
""
|
|
||||||
},
|
|
||||||
if !txt_raw.is_null() {
|
|
||||||
as_str(txt_raw)
|
|
||||||
} else {
|
|
||||||
""
|
|
||||||
},
|
|
||||||
as_str((*(*part).param).packed),
|
|
||||||
(*part).bytes,
|
|
||||||
hidden,
|
|
||||||
if 0 != save_mime_headers {
|
|
||||||
Some(as_str(imf_raw_not_terminated))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
as_str(mime_in_reply_to),
|
|
||||||
as_str(mime_references),
|
|
||||||
]);
|
|
||||||
|
|
||||||
if res.is_err() {
|
|
||||||
info!(context, 0, "Cannot write DB.",);
|
|
||||||
/* i/o error - there is nothing more we can do - in other cases, we try to write at least an empty record */
|
|
||||||
current_block = 16282941964262048061;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
free(txt_raw as *mut libc::c_void);
|
|
||||||
txt_raw = 0 as *mut libc::c_char;
|
|
||||||
insert_msg_id = dc_sqlite3_get_rowid(
|
|
||||||
context,
|
|
||||||
&context.sql,
|
|
||||||
"msgs",
|
|
||||||
"rfc724_mid",
|
|
||||||
as_str(rfc724_mid),
|
|
||||||
);
|
|
||||||
carray_add(
|
|
||||||
created_db_entries,
|
|
||||||
chat_id as uintptr_t as *mut libc::c_void,
|
|
||||||
0 as *mut libc::c_uint,
|
|
||||||
);
|
|
||||||
carray_add(
|
|
||||||
created_db_entries,
|
|
||||||
insert_msg_id as uintptr_t as *mut libc::c_void,
|
|
||||||
0 as *mut libc::c_uint,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
i = i.wrapping_add(1)
|
).unwrap(); // TODO: better error handling
|
||||||
}
|
|
||||||
match current_block {
|
match current_block {
|
||||||
16282941964262048061 => {}
|
16282941964262048061 => {}
|
||||||
_ => {
|
_ => {
|
||||||
|
|||||||
@@ -60,6 +60,32 @@ impl SQLite {
|
|||||||
self.connection.read().unwrap()
|
self.connection.read().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn prepare<G, H>(&self, sql: &str, g: G) -> Result<H>
|
||||||
|
where
|
||||||
|
G: FnOnce(Statement<'_>) -> Result<H>,
|
||||||
|
{
|
||||||
|
let conn_lock = self.connection.read().unwrap();
|
||||||
|
let conn = conn_lock.as_ref().expect("database closed");
|
||||||
|
|
||||||
|
let stmt = conn.prepare(sql)?;
|
||||||
|
let res = g(stmt)?;
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn prepare2<G, H>(&self, sql1: &str, sql2: &str, g: G) -> Result<H>
|
||||||
|
where
|
||||||
|
G: FnOnce(Statement<'_>, Statement<'_>, &Connection) -> Result<H>,
|
||||||
|
{
|
||||||
|
let conn_lock = self.connection.read().unwrap();
|
||||||
|
let conn = conn_lock.as_ref().expect("database closed");
|
||||||
|
|
||||||
|
let stmt1 = conn.prepare(sql1)?;
|
||||||
|
let stmt2 = conn.prepare(sql2)?;
|
||||||
|
|
||||||
|
let res = g(stmt1, stmt2, conn)?;
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
|
|
||||||
/// Prepares and executes the statement and maps a function over the resulting rows.
|
/// Prepares and executes the statement and maps a function over the resulting rows.
|
||||||
/// Then executes the second function over the returned iterator and returns the
|
/// Then executes the second function over the returned iterator and returns the
|
||||||
/// result of that function.
|
/// result of that function.
|
||||||
@@ -883,16 +909,6 @@ pub fn dc_sqlite3_set_config(
|
|||||||
1
|
1
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Remove the option from the return type
|
|
||||||
pub fn dc_sqlite3_prepare<'a>(
|
|
||||||
_context: &Context,
|
|
||||||
_sql: &'a SQLite,
|
|
||||||
_querystr: &'a str,
|
|
||||||
) -> Option<Statement<'a>> {
|
|
||||||
// TODO: remove once it is not used anymore
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn dc_sqlite3_get_config(
|
pub fn dc_sqlite3_get_config(
|
||||||
context: &Context,
|
context: &Context,
|
||||||
sql: &SQLite,
|
sql: &SQLite,
|
||||||
@@ -1047,28 +1063,39 @@ pub fn dc_sqlite3_get_rowid2(
|
|||||||
field2: impl AsRef<str>,
|
field2: impl AsRef<str>,
|
||||||
value2: i32,
|
value2: i32,
|
||||||
) -> u32 {
|
) -> u32 {
|
||||||
// same as dc_sqlite3_get_rowid() with a key over two columns
|
|
||||||
if let Some(conn) = &*sql.connection.read().unwrap() {
|
if let Some(conn) = &*sql.connection.read().unwrap() {
|
||||||
match conn.query_row(
|
get_rowid2(context, conn, table, field, value, field2, value2)
|
||||||
&format!(
|
|
||||||
"SELECT id FROM ? WHERE {}=? AND {}=? ORDER BY id DESC",
|
|
||||||
field.as_ref(),
|
|
||||||
field2.as_ref(),
|
|
||||||
),
|
|
||||||
params![table.as_ref(), value, value2],
|
|
||||||
|row| row.get::<_, u32>(0),
|
|
||||||
) {
|
|
||||||
Ok(id) => id,
|
|
||||||
Err(err) => {
|
|
||||||
error!(context, 0, "sql: Failed to retrieve rowid2: {}", err);
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_rowid2(
|
||||||
|
context: &Context,
|
||||||
|
conn: &Connection,
|
||||||
|
table: impl AsRef<str>,
|
||||||
|
field: impl AsRef<str>,
|
||||||
|
value: i64,
|
||||||
|
field2: impl AsRef<str>,
|
||||||
|
value2: i32,
|
||||||
|
) -> u32 {
|
||||||
|
match conn.query_row(
|
||||||
|
&format!(
|
||||||
|
"SELECT id FROM ? WHERE {}=? AND {}=? ORDER BY id DESC",
|
||||||
|
field.as_ref(),
|
||||||
|
field2.as_ref(),
|
||||||
|
),
|
||||||
|
params![table.as_ref(), value, value2],
|
||||||
|
|row| row.get::<_, u32>(0),
|
||||||
|
) {
|
||||||
|
Ok(id) => id,
|
||||||
|
Err(err) => {
|
||||||
|
error!(context, 0, "sql: Failed to retrieve rowid2: {}", err);
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn dc_housekeeping(context: &Context) {
|
pub fn dc_housekeeping(context: &Context) {
|
||||||
let mut files_in_use = HashSet::new();
|
let mut files_in_use = HashSet::new();
|
||||||
let mut unreferenced_count = 0;
|
let mut unreferenced_count = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user