mirror of
https://github.com/chatmail/core.git
synced 2026-05-20 07:16:31 +03:00
less preparation
This commit is contained in:
@@ -700,61 +700,53 @@ pub fn dc_search_msgs(
|
|||||||
chat_id: uint32_t,
|
chat_id: uint32_t,
|
||||||
query: *const libc::c_char,
|
query: *const libc::c_char,
|
||||||
) -> *mut dc_array_t {
|
) -> *mut dc_array_t {
|
||||||
let mut success = false;
|
if query.is_null() {
|
||||||
|
return std::ptr::null_mut();
|
||||||
|
}
|
||||||
|
|
||||||
|
let real_query = to_string(query).trim().to_string();
|
||||||
|
if real_query.is_empty() {
|
||||||
|
return std::ptr::null_mut();
|
||||||
|
}
|
||||||
|
let strLikeInText = format!("%{}%", &real_query);
|
||||||
|
let strLikeBeg = format!("{}%", &real_query);
|
||||||
|
|
||||||
|
let query = if 0 != chat_id {
|
||||||
|
"SELECT m.id, m.timestamp FROM msgs m LEFT JOIN contacts ct ON m.from_id=ct.id WHERE m.chat_id=? \
|
||||||
|
AND m.hidden=0 \
|
||||||
|
AND ct.blocked=0 AND (txt LIKE ? OR ct.name LIKE ?) ORDER BY m.timestamp,m.id;"
|
||||||
|
} else {
|
||||||
|
"SELECT m.id, m.timestamp FROM msgs m LEFT JOIN contacts ct ON m.from_id=ct.id \
|
||||||
|
LEFT JOIN chats c ON m.chat_id=c.id WHERE m.chat_id>9 AND m.hidden=0 \
|
||||||
|
AND (c.blocked=0 OR c.blocked=?) \
|
||||||
|
AND ct.blocked=0 AND (m.txt LIKE ? OR ct.name LIKE ?) ORDER BY m.timestamp DESC,m.id DESC;"
|
||||||
|
};
|
||||||
|
|
||||||
let ret = unsafe { dc_array_new(100 as size_t) };
|
let ret = unsafe { dc_array_new(100 as size_t) };
|
||||||
|
|
||||||
if !(ret.is_null() || query.is_null()) {
|
let success = context
|
||||||
let real_query = to_string(query).trim().to_string();
|
.sql
|
||||||
if real_query.is_empty() {
|
.query_map(
|
||||||
success = true;
|
query,
|
||||||
} else {
|
params![chat_id as libc::c_int, &strLikeInText, &strLikeBeg],
|
||||||
let strLikeInText = format!("%{}%", &real_query);
|
|row| row.get::<_, i32>(0),
|
||||||
let strLikeBeg = format!("{}%", &real_query);
|
|rows| {
|
||||||
|
for id in rows {
|
||||||
let rows = if 0 != chat_id {
|
unsafe { dc_array_add_id(ret, id? as u32) };
|
||||||
dc_sqlite3_prepare(
|
|
||||||
context,
|
|
||||||
&context.sql,
|
|
||||||
"SELECT m.id, m.timestamp FROM msgs m LEFT JOIN contacts ct ON m.from_id=ct.id WHERE m.chat_id=? \
|
|
||||||
AND m.hidden=0 \
|
|
||||||
AND ct.blocked=0 AND (txt LIKE ? OR ct.name LIKE ?) ORDER BY m.timestamp,m.id;"
|
|
||||||
).and_then(|mut stmt| stmt.query_map(
|
|
||||||
params![chat_id as libc::c_int, &strLikeInText, &strLikeBeg],
|
|
||||||
|row| row.get::<_, i32>(0)
|
|
||||||
).and_then(|res| res.collect::<rusqlite::Result<Vec<i32>>>()).ok())
|
|
||||||
} else {
|
|
||||||
let show_deaddrop = 0;
|
|
||||||
dc_sqlite3_prepare(
|
|
||||||
context,
|
|
||||||
&context.sql,
|
|
||||||
"SELECT m.id, m.timestamp FROM msgs m LEFT JOIN contacts ct ON m.from_id=ct.id \
|
|
||||||
LEFT JOIN chats c ON m.chat_id=c.id WHERE m.chat_id>9 AND m.hidden=0 \
|
|
||||||
AND (c.blocked=0 OR c.blocked=?) \
|
|
||||||
AND ct.blocked=0 AND (m.txt LIKE ? OR ct.name LIKE ?) ORDER BY m.timestamp DESC,m.id DESC;"
|
|
||||||
).and_then(|mut stmt|
|
|
||||||
stmt.query_map(params![
|
|
||||||
if 0 != show_deaddrop { 2 } else { 0 },
|
|
||||||
strLikeInText, strLikeBeg,
|
|
||||||
], |row| row.get::<_, i32>(0)).and_then(|res| res.collect::<rusqlite::Result<Vec<i32>>>()).ok()
|
|
||||||
)
|
|
||||||
};
|
|
||||||
if let Some(ids) = rows {
|
|
||||||
for id in ids {
|
|
||||||
unsafe { dc_array_add_id(ret, id as u32) };
|
|
||||||
}
|
}
|
||||||
success = true;
|
Ok(())
|
||||||
}
|
},
|
||||||
}
|
)
|
||||||
}
|
.is_ok();
|
||||||
|
|
||||||
if success {
|
if success {
|
||||||
ret
|
return ret;
|
||||||
} else {
|
|
||||||
if !ret.is_null() {
|
|
||||||
unsafe { dc_array_unref(ret) };
|
|
||||||
}
|
|
||||||
0 as *mut dc_array_t
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !ret.is_null() {
|
||||||
|
unsafe { dc_array_unref(ret) };
|
||||||
|
}
|
||||||
|
std::ptr::null_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dc_is_inbox(_context: &Context, folder_name: impl AsRef<str>) -> bool {
|
pub fn dc_is_inbox(_context: &Context, folder_name: impl AsRef<str>) -> bool {
|
||||||
|
|||||||
@@ -149,9 +149,7 @@ unsafe fn dc_chatlist_load_from_db(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let success = if query_contact_id != 0 {
|
let success = if query_contact_id != 0 {
|
||||||
if let Some(mut stmt) = dc_sqlite3_prepare(
|
(*chatlist).context.sql.query_map(
|
||||||
(*chatlist).context,
|
|
||||||
&(*chatlist).context.sql,
|
|
||||||
"SELECT c.id, m.id FROM chats c LEFT JOIN msgs m \
|
"SELECT c.id, m.id FROM chats c LEFT JOIN msgs m \
|
||||||
ON c.id=m.chat_id \
|
ON c.id=m.chat_id \
|
||||||
AND m.timestamp=( SELECT MAX(timestamp) \
|
AND m.timestamp=( SELECT MAX(timestamp) \
|
||||||
@@ -159,17 +157,12 @@ unsafe fn dc_chatlist_load_from_db(
|
|||||||
AND (hidden=0 OR (hidden=1 AND state=19))) WHERE c.id>9 \
|
AND (hidden=0 OR (hidden=1 AND state=19))) WHERE c.id>9 \
|
||||||
AND c.blocked=0 AND c.id IN(SELECT chat_id FROM chats_contacts WHERE contact_id=?) \
|
AND c.blocked=0 AND c.id IN(SELECT chat_id FROM chats_contacts WHERE contact_id=?) \
|
||||||
GROUP BY c.id ORDER BY IFNULL(m.timestamp,0) DESC, m.id DESC;",
|
GROUP BY c.id ORDER BY IFNULL(m.timestamp,0) DESC, m.id DESC;",
|
||||||
) {
|
params![query_contact_id as i32],
|
||||||
stmt.query_map(params![query_contact_id as i32], process_fn)
|
process_fn,
|
||||||
.and_then(|res| res.collect::<rusqlite::Result<Vec<_>>>())
|
|res| res.collect::<rusqlite::Result<Vec<_>>>(),
|
||||||
.is_ok()
|
)
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
} else if 0 != listflags & 0x1 {
|
} else if 0 != listflags & 0x1 {
|
||||||
if let Some(mut stmt) = dc_sqlite3_prepare(
|
(*chatlist).context.sql.query_map(
|
||||||
(*chatlist).context,
|
|
||||||
&(*chatlist).context.sql,
|
|
||||||
"SELECT c.id, m.id FROM chats c LEFT JOIN msgs m \
|
"SELECT c.id, m.id FROM chats c LEFT JOIN msgs m \
|
||||||
ON c.id=m.chat_id \
|
ON c.id=m.chat_id \
|
||||||
AND m.timestamp=( SELECT MAX(timestamp) \
|
AND m.timestamp=( SELECT MAX(timestamp) \
|
||||||
@@ -177,13 +170,10 @@ unsafe fn dc_chatlist_load_from_db(
|
|||||||
AND (hidden=0 OR (hidden=1 AND state=19))) WHERE c.id>9 \
|
AND (hidden=0 OR (hidden=1 AND state=19))) WHERE c.id>9 \
|
||||||
AND c.blocked=0 AND c.archived=1 GROUP BY c.id \
|
AND c.blocked=0 AND c.archived=1 GROUP BY c.id \
|
||||||
ORDER BY IFNULL(m.timestamp,0) DESC, m.id DESC;",
|
ORDER BY IFNULL(m.timestamp,0) DESC, m.id DESC;",
|
||||||
) {
|
params![],
|
||||||
stmt.query_map(params![], process_fn)
|
process_fn,
|
||||||
.and_then(|res| res.collect::<rusqlite::Result<Vec<_>>>())
|
|res| res.collect::<rusqlite::Result<Vec<_>>>(),
|
||||||
.is_ok()
|
)
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
} else if query__.is_null() {
|
} else if query__.is_null() {
|
||||||
if 0 == listflags & 0x2 {
|
if 0 == listflags & 0x2 {
|
||||||
let last_deaddrop_fresh_msg_id = get_last_deaddrop_fresh_msg((*chatlist).context);
|
let last_deaddrop_fresh_msg_id = get_last_deaddrop_fresh_msg((*chatlist).context);
|
||||||
@@ -193,9 +183,7 @@ unsafe fn dc_chatlist_load_from_db(
|
|||||||
}
|
}
|
||||||
add_archived_link_item = 1;
|
add_archived_link_item = 1;
|
||||||
}
|
}
|
||||||
if let Some(mut stmt) = dc_sqlite3_prepare(
|
(*chatlist).context.sql.query_map(
|
||||||
(*chatlist).context,
|
|
||||||
&(*chatlist).context.sql,
|
|
||||||
"SELECT c.id, m.id FROM chats c \
|
"SELECT c.id, m.id FROM chats c \
|
||||||
LEFT JOIN msgs m \
|
LEFT JOIN msgs m \
|
||||||
ON c.id=m.chat_id \
|
ON c.id=m.chat_id \
|
||||||
@@ -205,22 +193,17 @@ unsafe fn dc_chatlist_load_from_db(
|
|||||||
AND c.blocked=0 AND c.archived=0 \
|
AND c.blocked=0 AND c.archived=0 \
|
||||||
GROUP BY c.id \
|
GROUP BY c.id \
|
||||||
ORDER BY IFNULL(m.timestamp,0) DESC, m.id DESC;",
|
ORDER BY IFNULL(m.timestamp,0) DESC, m.id DESC;",
|
||||||
) {
|
params![],
|
||||||
stmt.query_map(params![], process_fn)
|
process_fn,
|
||||||
.and_then(|res| res.collect::<rusqlite::Result<Vec<_>>>())
|
|res| res.collect::<rusqlite::Result<Vec<_>>>(),
|
||||||
.is_ok()
|
)
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
let query = to_string(query__).trim().to_string();
|
let query = to_string(query__).trim().to_string();
|
||||||
if query.is_empty() {
|
if query.is_empty() {
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
let strLikeCmd = format!("%{}%", query);
|
let strLikeCmd = format!("%{}%", query);
|
||||||
if let Some(mut stmt) = dc_sqlite3_prepare(
|
(*chatlist).context.sql.query_map(
|
||||||
(*chatlist).context,
|
|
||||||
&(*chatlist).context.sql,
|
|
||||||
"SELECT c.id, m.id FROM chats c LEFT JOIN msgs m \
|
"SELECT c.id, m.id FROM chats c LEFT JOIN msgs m \
|
||||||
ON c.id=m.chat_id \
|
ON c.id=m.chat_id \
|
||||||
AND m.timestamp=( SELECT MAX(timestamp) \
|
AND m.timestamp=( SELECT MAX(timestamp) \
|
||||||
@@ -228,13 +211,10 @@ unsafe fn dc_chatlist_load_from_db(
|
|||||||
AND (hidden=0 OR (hidden=1 AND state=19))) WHERE c.id>9 \
|
AND (hidden=0 OR (hidden=1 AND state=19))) WHERE c.id>9 \
|
||||||
AND c.blocked=0 AND c.name LIKE ? \
|
AND c.blocked=0 AND c.name LIKE ? \
|
||||||
GROUP BY c.id ORDER BY IFNULL(m.timestamp,0) DESC, m.id DESC;",
|
GROUP BY c.id ORDER BY IFNULL(m.timestamp,0) DESC, m.id DESC;",
|
||||||
) {
|
params![strLikeCmd],
|
||||||
stmt.query_map(params![strLikeCmd], process_fn)
|
process_fn,
|
||||||
.and_then(|res| res.collect::<rusqlite::Result<Vec<_>>>())
|
|res| res.collect::<rusqlite::Result<Vec<_>>>(),
|
||||||
.is_ok()
|
)
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -248,7 +228,7 @@ unsafe fn dc_chatlist_load_from_db(
|
|||||||
}
|
}
|
||||||
(*chatlist).cnt = dc_array_get_cnt((*chatlist).chatNlastmsg_ids).wrapping_div(2);
|
(*chatlist).cnt = dc_array_get_cnt((*chatlist).chatNlastmsg_ids).wrapping_div(2);
|
||||||
|
|
||||||
success as libc::c_int
|
success.is_ok() as libc::c_int
|
||||||
}
|
}
|
||||||
|
|
||||||
// Context functions to work with chatlist
|
// Context functions to work with chatlist
|
||||||
|
|||||||
286
src/dc_job.rs
286
src/dc_job.rs
@@ -85,128 +85,121 @@ unsafe fn dc_job_perform(context: &Context, thread: libc::c_int, probe_network:
|
|||||||
Ok(job)
|
Ok(job)
|
||||||
};
|
};
|
||||||
|
|
||||||
let jobs = if probe_network == 0 {
|
let query = if probe_network == 0 {
|
||||||
if let Some(mut stmt) = dc_sqlite3_prepare(
|
"SELECT id, action, foreign_id, param, added_timestamp, desired_timestamp, tries \
|
||||||
context,
|
FROM jobs WHERE thread=? AND desired_timestamp<=? ORDER BY action DESC, added_timestamp;"
|
||||||
&context.sql,
|
|
||||||
"SELECT id, action, foreign_id, param, added_timestamp, desired_timestamp, tries \
|
|
||||||
FROM jobs WHERE thread=? AND desired_timestamp<=? ORDER BY action DESC, added_timestamp;"
|
|
||||||
) {
|
|
||||||
stmt.query_map(params![thread as i64, time()], process_row)
|
|
||||||
.and_then(|res| res.collect::<rusqlite::Result<Vec<_>>>()).ok()
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if let Some(mut stmt) = dc_sqlite3_prepare(
|
"SELECT id, action, foreign_id, param, added_timestamp, desired_timestamp, tries \
|
||||||
context,
|
FROM jobs WHERE thread=? AND tries>0 ORDER BY desired_timestamp, action DESC;"
|
||||||
&context.sql,
|
|
||||||
"SELECT id, action, foreign_id, param, added_timestamp, desired_timestamp, tries \
|
|
||||||
FROM jobs WHERE thread=? AND tries>0 ORDER BY desired_timestamp, action DESC;",
|
|
||||||
) {
|
|
||||||
stmt.query_map(params![thread as i64], process_row)
|
|
||||||
.and_then(|res| res.collect::<rusqlite::Result<Vec<_>>>())
|
|
||||||
.ok()
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if jobs.is_none() {
|
let params_no_probe = params![thread as i64, time()];
|
||||||
return;
|
let params_probe = params![thread as i64];
|
||||||
}
|
let params: &[&dyn rusqlite::ToSql] = if probe_network == 0 {
|
||||||
|
params_no_probe
|
||||||
|
} else {
|
||||||
|
params_probe
|
||||||
|
};
|
||||||
|
|
||||||
for mut job in jobs.unwrap() {
|
context
|
||||||
info!(
|
.sql
|
||||||
context,
|
.query_map(query, params, process_row, |jobs| {
|
||||||
0,
|
for job in jobs {
|
||||||
"{}-job #{}, action {} started...",
|
let mut job: dc_job_t = job?;
|
||||||
if thread == 100 { "INBOX" } else { "SMTP" },
|
|
||||||
job.job_id,
|
|
||||||
job.action,
|
|
||||||
);
|
|
||||||
|
|
||||||
if 900 == job.action || 910 == job.action {
|
|
||||||
dc_job_kill_action(context, job.action);
|
|
||||||
dc_jobthread_suspend(context, &context.sentbox_thread.clone().read().unwrap(), 1);
|
|
||||||
dc_jobthread_suspend(context, &context.mvbox_thread.clone().read().unwrap(), 1);
|
|
||||||
dc_suspend_smtp_thread(context, 1);
|
|
||||||
}
|
|
||||||
let mut tries = 0;
|
|
||||||
while tries <= 1 {
|
|
||||||
job.try_again = 0;
|
|
||||||
match job.action {
|
|
||||||
5901 => {
|
|
||||||
dc_job_do_DC_JOB_SEND(context, &mut job);
|
|
||||||
}
|
|
||||||
110 => {
|
|
||||||
dc_job_do_DC_JOB_DELETE_MSG_ON_IMAP(context, &mut job);
|
|
||||||
}
|
|
||||||
130 => {
|
|
||||||
dc_job_do_DC_JOB_MARKSEEN_MSG_ON_IMAP(context, &mut job);
|
|
||||||
}
|
|
||||||
120 => {
|
|
||||||
dc_job_do_DC_JOB_MARKSEEN_MDN_ON_IMAP(context, &mut job);
|
|
||||||
}
|
|
||||||
200 => {
|
|
||||||
dc_job_do_DC_JOB_MOVE_MSG(context, &mut job);
|
|
||||||
}
|
|
||||||
5011 => {
|
|
||||||
dc_job_do_DC_JOB_SEND(context, &mut job);
|
|
||||||
}
|
|
||||||
900 => {
|
|
||||||
dc_job_do_DC_JOB_CONFIGURE_IMAP(context, &mut job);
|
|
||||||
}
|
|
||||||
910 => {
|
|
||||||
dc_job_do_DC_JOB_IMEX_IMAP(context, &mut job);
|
|
||||||
}
|
|
||||||
5005 => {
|
|
||||||
dc_job_do_DC_JOB_MAYBE_SEND_LOCATIONS(context, &mut job);
|
|
||||||
}
|
|
||||||
5007 => {
|
|
||||||
dc_job_do_DC_JOB_MAYBE_SEND_LOC_ENDED(context, &mut job);
|
|
||||||
}
|
|
||||||
105 => {
|
|
||||||
dc_housekeeping(context);
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
if job.try_again != -1 {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
tries += 1
|
|
||||||
}
|
|
||||||
if 900 == job.action || 910 == job.action {
|
|
||||||
dc_jobthread_suspend(
|
|
||||||
context,
|
|
||||||
&mut context.sentbox_thread.clone().read().unwrap(),
|
|
||||||
0,
|
|
||||||
);
|
|
||||||
dc_jobthread_suspend(
|
|
||||||
context,
|
|
||||||
&mut context.mvbox_thread.clone().read().unwrap(),
|
|
||||||
0,
|
|
||||||
);
|
|
||||||
dc_suspend_smtp_thread(context, 0);
|
|
||||||
break;
|
|
||||||
} else if job.try_again == 2 {
|
|
||||||
info!(
|
|
||||||
context,
|
|
||||||
0,
|
|
||||||
"{}-job #{} not yet ready and will be delayed.",
|
|
||||||
if thread == 100 { "INBOX" } else { "SMTP" },
|
|
||||||
job.job_id
|
|
||||||
);
|
|
||||||
} else if job.try_again == -1 || job.try_again == 3 {
|
|
||||||
let tries = job.tries + 1;
|
|
||||||
if tries < 17 {
|
|
||||||
job.tries = tries;
|
|
||||||
let time_offset = get_backoff_time_offset(tries);
|
|
||||||
job.desired_timestamp = job.added_timestamp + time_offset;
|
|
||||||
dc_job_update(context, &mut job);
|
|
||||||
info!(
|
info!(
|
||||||
context,
|
context,
|
||||||
0,
|
0,
|
||||||
|
"{}-job #{}, action {} started...",
|
||||||
|
if thread == 100 { "INBOX" } else { "SMTP" },
|
||||||
|
job.job_id,
|
||||||
|
job.action,
|
||||||
|
);
|
||||||
|
|
||||||
|
if 900 == job.action || 910 == job.action {
|
||||||
|
dc_job_kill_action(context, job.action);
|
||||||
|
dc_jobthread_suspend(
|
||||||
|
context,
|
||||||
|
&context.sentbox_thread.clone().read().unwrap(),
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
dc_jobthread_suspend(context, &context.mvbox_thread.clone().read().unwrap(), 1);
|
||||||
|
dc_suspend_smtp_thread(context, 1);
|
||||||
|
}
|
||||||
|
let mut tries = 0;
|
||||||
|
while tries <= 1 {
|
||||||
|
job.try_again = 0;
|
||||||
|
match job.action {
|
||||||
|
5901 => {
|
||||||
|
dc_job_do_DC_JOB_SEND(context, &mut job);
|
||||||
|
}
|
||||||
|
110 => {
|
||||||
|
dc_job_do_DC_JOB_DELETE_MSG_ON_IMAP(context, &mut job);
|
||||||
|
}
|
||||||
|
130 => {
|
||||||
|
dc_job_do_DC_JOB_MARKSEEN_MSG_ON_IMAP(context, &mut job);
|
||||||
|
}
|
||||||
|
120 => {
|
||||||
|
dc_job_do_DC_JOB_MARKSEEN_MDN_ON_IMAP(context, &mut job);
|
||||||
|
}
|
||||||
|
200 => {
|
||||||
|
dc_job_do_DC_JOB_MOVE_MSG(context, &mut job);
|
||||||
|
}
|
||||||
|
5011 => {
|
||||||
|
dc_job_do_DC_JOB_SEND(context, &mut job);
|
||||||
|
}
|
||||||
|
900 => {
|
||||||
|
dc_job_do_DC_JOB_CONFIGURE_IMAP(context, &mut job);
|
||||||
|
}
|
||||||
|
910 => {
|
||||||
|
dc_job_do_DC_JOB_IMEX_IMAP(context, &mut job);
|
||||||
|
}
|
||||||
|
5005 => {
|
||||||
|
dc_job_do_DC_JOB_MAYBE_SEND_LOCATIONS(context, &mut job);
|
||||||
|
}
|
||||||
|
5007 => {
|
||||||
|
dc_job_do_DC_JOB_MAYBE_SEND_LOC_ENDED(context, &mut job);
|
||||||
|
}
|
||||||
|
105 => {
|
||||||
|
dc_housekeeping(context);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
if job.try_again != -1 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
tries += 1
|
||||||
|
}
|
||||||
|
if 900 == job.action || 910 == job.action {
|
||||||
|
dc_jobthread_suspend(
|
||||||
|
context,
|
||||||
|
&mut context.sentbox_thread.clone().read().unwrap(),
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
dc_jobthread_suspend(
|
||||||
|
context,
|
||||||
|
&mut context.mvbox_thread.clone().read().unwrap(),
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
dc_suspend_smtp_thread(context, 0);
|
||||||
|
break;
|
||||||
|
} else if job.try_again == 2 {
|
||||||
|
info!(
|
||||||
|
context,
|
||||||
|
0,
|
||||||
|
"{}-job #{} not yet ready and will be delayed.",
|
||||||
|
if thread == 100 { "INBOX" } else { "SMTP" },
|
||||||
|
job.job_id
|
||||||
|
);
|
||||||
|
} else if job.try_again == -1 || job.try_again == 3 {
|
||||||
|
let tries = job.tries + 1;
|
||||||
|
if tries < 17 {
|
||||||
|
job.tries = tries;
|
||||||
|
let time_offset = get_backoff_time_offset(tries);
|
||||||
|
job.desired_timestamp = job.added_timestamp + time_offset;
|
||||||
|
dc_job_update(context, &mut job);
|
||||||
|
info!(
|
||||||
|
context,
|
||||||
|
0,
|
||||||
"{}-job #{} not succeeded on try #{}, retry in ADD_TIME+{} (in {} seconds).",
|
"{}-job #{} not succeeded on try #{}, retry in ADD_TIME+{} (in {} seconds).",
|
||||||
if thread == 100 { "INBOX" } else { "SMTP" },
|
if thread == 100 { "INBOX" } else { "SMTP" },
|
||||||
job.job_id as libc::c_int,
|
job.job_id as libc::c_int,
|
||||||
@@ -214,35 +207,39 @@ unsafe fn dc_job_perform(context: &Context, thread: libc::c_int, probe_network:
|
|||||||
time_offset,
|
time_offset,
|
||||||
job.added_timestamp + time_offset - time()
|
job.added_timestamp + time_offset - time()
|
||||||
);
|
);
|
||||||
if thread == 5000 && tries < 17 - 1 {
|
if thread == 5000 && tries < 17 - 1 {
|
||||||
context
|
context
|
||||||
.smtp_state
|
.smtp_state
|
||||||
.clone()
|
.clone()
|
||||||
.0
|
.0
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.perform_jobs_needed = 2;
|
.perform_jobs_needed = 2;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if job.action == 5901 {
|
||||||
|
dc_set_msg_failed(context, job.foreign_id, job.pending_error);
|
||||||
|
}
|
||||||
|
dc_job_delete(context, &mut job);
|
||||||
|
}
|
||||||
|
if 0 == probe_network {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// on dc_maybe_network() we stop trying here;
|
||||||
|
// these jobs are already tried once.
|
||||||
|
// otherwise, we just continue with the next job
|
||||||
|
// to give other jobs a chance being tried at least once.
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
dc_job_delete(context, &mut job);
|
||||||
}
|
}
|
||||||
} else {
|
dc_param_unref(job.param);
|
||||||
if job.action == 5901 {
|
free(job.pending_error as *mut libc::c_void);
|
||||||
dc_set_msg_failed(context, job.foreign_id, job.pending_error);
|
|
||||||
}
|
|
||||||
dc_job_delete(context, &mut job);
|
|
||||||
}
|
}
|
||||||
if 0 == probe_network {
|
|
||||||
continue;
|
Ok(())
|
||||||
}
|
})
|
||||||
// on dc_maybe_network() we stop trying here;
|
.unwrap(); // TODO: better error handling
|
||||||
// these jobs are already tried once.
|
|
||||||
// otherwise, we just continue with the next job
|
|
||||||
// to give other jobs a chance being tried at least once.
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
dc_job_delete(context, &mut job);
|
|
||||||
}
|
|
||||||
dc_param_unref(job.param);
|
|
||||||
free(job.pending_error as *mut libc::c_void);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dc_job_delete(context: &Context, job: &dc_job_t) -> bool {
|
fn dc_job_delete(context: &Context, job: &dc_job_t) -> bool {
|
||||||
@@ -1166,8 +1163,9 @@ pub unsafe fn dc_maybe_network(context: &Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn dc_job_action_exists(context: &Context, action: libc::c_int) -> bool {
|
pub fn dc_job_action_exists(context: &Context, action: libc::c_int) -> bool {
|
||||||
dc_sqlite3_prepare(context, &context.sql, "SELECT id FROM jobs WHERE action=?;")
|
context
|
||||||
.and_then(|mut stmt| stmt.exists(params![action]).ok())
|
.sql
|
||||||
|
.exists("SELECT id FROM jobs WHERE action=?;", params![action])
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -140,47 +140,48 @@ pub unsafe fn dc_mimefactory_load_msg(
|
|||||||
dc_strdup((*factory).from_addr) as *mut libc::c_void,
|
dc_strdup((*factory).from_addr) as *mut libc::c_void,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
let rows = if let Some(mut stmt) = dc_sqlite3_prepare(
|
context
|
||||||
context,
|
.sql
|
||||||
&context.sql,
|
.query_map(
|
||||||
"SELECT c.authname, c.addr \
|
"SELECT c.authname, c.addr \
|
||||||
FROM chats_contacts cc \
|
FROM chats_contacts cc \
|
||||||
LEFT JOIN contacts c ON cc.contact_id=c.id \
|
LEFT JOIN contacts c ON cc.contact_id=c.id \
|
||||||
WHERE cc.chat_id=? AND cc.contact_id>9;",
|
WHERE cc.chat_id=? AND cc.contact_id>9;",
|
||||||
) {
|
params![(*(*factory).msg).chat_id as i32],
|
||||||
stmt.query_map(params![(*(*factory).msg).chat_id as i32], |row| {
|
|row| {
|
||||||
let authname: String = row.get(0)?;
|
let authname: String = row.get(0)?;
|
||||||
let addr: String = row.get(1)?;
|
let addr: String = row.get(1)?;
|
||||||
Ok((authname, addr))
|
Ok((authname, addr))
|
||||||
})
|
},
|
||||||
.and_then(|res| res.collect::<rusqlite::Result<Vec<_>>>())
|
|rows| {
|
||||||
.ok()
|
for row in rows {
|
||||||
} else {
|
let (authname, addr) = row?;
|
||||||
None
|
let addr_c = to_cstring(addr);
|
||||||
};
|
if clist_search_string_nocase(
|
||||||
|
(*factory).recipients_addr,
|
||||||
if let Some(rows) = rows {
|
addr_c.as_ptr(),
|
||||||
for (authname, addr) in rows {
|
) == 0
|
||||||
let addr_c = to_cstring(addr);
|
{
|
||||||
if clist_search_string_nocase((*factory).recipients_addr, addr_c.as_ptr()) == 0
|
clist_insert_after(
|
||||||
{
|
(*factory).recipients_names,
|
||||||
clist_insert_after(
|
(*(*factory).recipients_names).last,
|
||||||
(*factory).recipients_names,
|
if !authname.is_empty() {
|
||||||
(*(*factory).recipients_names).last,
|
dc_strdup(to_cstring(authname).as_ptr())
|
||||||
if !authname.is_empty() {
|
} else {
|
||||||
dc_strdup(to_cstring(authname).as_ptr())
|
0 as *mut libc::c_char
|
||||||
} else {
|
} as *mut libc::c_void,
|
||||||
0 as *mut libc::c_char
|
);
|
||||||
} as *mut libc::c_void,
|
clist_insert_after(
|
||||||
);
|
(*factory).recipients_addr,
|
||||||
clist_insert_after(
|
(*(*factory).recipients_addr).last,
|
||||||
(*factory).recipients_addr,
|
dc_strdup(addr_c.as_ptr()) as *mut libc::c_void,
|
||||||
(*(*factory).recipients_addr).last,
|
);
|
||||||
dc_strdup(addr_c.as_ptr()) as *mut libc::c_void,
|
}
|
||||||
);
|
}
|
||||||
}
|
Ok(())
|
||||||
}
|
},
|
||||||
}
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let command = dc_param_get_int((*(*factory).msg).param, 'S' as i32, 0);
|
let command = dc_param_get_int((*(*factory).msg).param, 'S' as i32, 0);
|
||||||
if command == 5 {
|
if command == 5 {
|
||||||
@@ -219,21 +220,17 @@ pub unsafe fn dc_mimefactory_load_msg(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let row = dc_sqlite3_prepare(
|
let row = context.sql.query_row(
|
||||||
context,
|
|
||||||
&context.sql,
|
|
||||||
"SELECT mime_in_reply_to, mime_references FROM msgs WHERE id=?",
|
"SELECT mime_in_reply_to, mime_references FROM msgs WHERE id=?",
|
||||||
)
|
params![(*(*factory).msg).id as i32],
|
||||||
.and_then(|mut stmt| {
|
|row| {
|
||||||
stmt.query_row(params![(*(*factory).msg).id as i32], |row| {
|
|
||||||
let in_reply_to: String = row.get(0)?;
|
let in_reply_to: String = row.get(0)?;
|
||||||
let references: String = row.get(1)?;
|
let references: String = row.get(1)?;
|
||||||
|
|
||||||
Ok((in_reply_to, references))
|
Ok((in_reply_to, references))
|
||||||
})
|
},
|
||||||
.ok()
|
);
|
||||||
});
|
if let Ok((in_reply_to, references)) = row {
|
||||||
if let Some((in_reply_to, references)) = row {
|
|
||||||
(*factory).in_reply_to = dc_strdup(to_cstring(in_reply_to).as_ptr());
|
(*factory).in_reply_to = dc_strdup(to_cstring(in_reply_to).as_ptr());
|
||||||
(*factory).references = dc_strdup(to_cstring(references).as_ptr());
|
(*factory).references = dc_strdup(to_cstring(references).as_ptr());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,6 +59,9 @@ impl SQLite {
|
|||||||
self.connection.read().unwrap()
|
self.connection.read().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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
|
||||||
|
/// result of that function.
|
||||||
pub fn query_map<T, P, F, G, H>(
|
pub fn query_map<T, P, F, G, H>(
|
||||||
&self,
|
&self,
|
||||||
sql: &str,
|
sql: &str,
|
||||||
@@ -80,6 +83,21 @@ impl SQLite {
|
|||||||
g(res)
|
g(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return `true` if a query in the SQL statement it executes returns one or more
|
||||||
|
/// rows and false if the SQL returns an empty set.
|
||||||
|
pub fn exists<P>(&self, sql: &str, params: P) -> rusqlite::Result<bool>
|
||||||
|
where
|
||||||
|
P: IntoIterator,
|
||||||
|
P::Item: rusqlite::ToSql,
|
||||||
|
{
|
||||||
|
let conn_lock = self.connection.read().unwrap();
|
||||||
|
let conn = conn_lock.as_ref().expect("database closed");
|
||||||
|
|
||||||
|
let mut stmt = conn.prepare(sql)?;
|
||||||
|
let res = stmt.exists(params)?;
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn query_row<T, P, F>(&self, sql: &str, params: P, f: F) -> rusqlite::Result<T>
|
pub fn query_row<T, P, F>(&self, sql: &str, params: P, f: F) -> rusqlite::Result<T>
|
||||||
where
|
where
|
||||||
P: IntoIterator,
|
P: IntoIterator,
|
||||||
|
|||||||
Reference in New Issue
Block a user