diff --git a/Cargo.lock b/Cargo.lock index 539bc132f..322a5f5d2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -461,6 +461,7 @@ name = "deltachat" version = "1.0.0-alpha.3" dependencies = [ "addr 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)", "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", "charset 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -495,6 +496,7 @@ dependencies = [ "strum 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "strum_macros 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "thread-local-object 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2237,6 +2239,14 @@ dependencies = [ "wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "thread-local-object" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unsafe-any 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "thread_local" version = "0.3.6" @@ -2386,6 +2396,11 @@ dependencies = [ "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "traitobject" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "try-lock" version = "0.2.2" @@ -2466,6 +2481,14 @@ name = "unicode-xid" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "unsafe-any" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "url" version = "1.7.2" @@ -2869,6 +2892,7 @@ dependencies = [ "checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" "checksum termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "adc4587ead41bf016f11af03e55a624c06568b5a19db4e90fde573d805074f83" "checksum termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "96d6098003bde162e4277c70665bd87c326f5a0c3f3fbfb285787fa482d54e6e" +"checksum thread-local-object 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7da3caa820d0308c84c8654f6cafd81cc3195d45433311cbe22fcf44fc8be071" "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" "checksum tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)" = "5a09c0b5bb588872ab2f09afa13ee6e9dac11e10a0ec9e8e3ba39a5a5d530af6" @@ -2882,6 +2906,7 @@ dependencies = [ "checksum tokio-threadpool 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "90ca01319dea1e376a001e8dc192d42ebde6dd532532a5bad988ac37db365b19" "checksum tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "f2106812d500ed25a4f38235b9cae8f78a09edf43203e16e59c3b769a342a60e" "checksum toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f" +"checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" "checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" "checksum try_from 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "283d3b89e1368717881a9d51dad843cc435380d8109c9e47d38780a324698d8b" "checksum twofish 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712d261e83e727c8e2dbb75dacac67c36e35db36a958ee504f2164fc052434e1" @@ -2894,6 +2919,7 @@ dependencies = [ "checksum unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1967f4cdfc355b37fd76d2a954fb2ed3871034eb4f26d60537d88795cfc332a9" "checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" +"checksum unsafe-any 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f30360d7979f5e9c6e6cea48af192ea8fab4afb3cf72597154b8f08935bc9c7f" "checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" "checksum utf8-ranges 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9d50aa7650df78abf942826607c62468ce18d9019673d4a2ebe1865dbb96ffde" "checksum utf8parse 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8772a4ccbb4e89959023bc5b7cb8623a795caa7092d99f3aa9501b9484d4557d" diff --git a/Cargo.toml b/Cargo.toml index 12a2e462b..741425119 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,6 +41,8 @@ r2d2_sqlite = "0.11.0" r2d2 = "0.8.5" strum = "0.15.0" strum_macros = "0.15.0" +thread-local-object = "0.1.0" +backtrace = "0.3.33" [dev-dependencies] tempfile = "3.0" diff --git a/src/dc_imex.rs b/src/dc_imex.rs index f55bcdfc1..c70a4b65d 100644 --- a/src/dc_imex.rs +++ b/src/dc_imex.rs @@ -806,77 +806,75 @@ unsafe fn import_backup(context: &Context, backup_to_import: *const libc::c_char 0, "***IMPORT-in-progress: total_files_cnt={:?}", total_files_cnt, ); - context - .sql - .query_map( - "SELECT file_name, file_content FROM backup_blobs ORDER BY id;", - params![], - |row| { - let name: String = row.get(0)?; - let blob: Vec = row.get(1)?; + let res = context.sql.query_map( + "SELECT file_name, file_content FROM backup_blobs ORDER BY id;", + params![], + |row| { + let name: String = row.get(0)?; + let blob: Vec = row.get(1)?; - Ok((name, blob)) - }, - |files| { - let mut loop_success = true; - let mut processed_files_cnt = 0; + Ok((name, blob)) + }, + |files| { + let mut loop_success = true; + let mut processed_files_cnt = 0; - for file in files { - if file.is_err() { - loop_success = false; - break; - } - let (file_name, file_blob) = file.unwrap(); + for file in files { + let (file_name, file_blob) = file?; - if context - .running_state - .clone() - .read() - .unwrap() - .shall_stop_ongoing - { - loop_success = false; - break; - } - 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); - if file_blob.is_empty() { - continue; - } - - let pathNfilename = format!("{}/{}", as_str(context.get_blobdir()), file_name); - if dc_write_file_safe(context, &pathNfilename, &file_blob) { - continue; - } - - error!( - context, - 0, - "Storage full? Cannot write file {} with {} bytes.", - &pathNfilename, - file_blob.len(), - ); - // otherwise the user may believe the stuff is imported correctly, but there are files missing ... + if context + .running_state + .clone() + .read() + .unwrap() + .shall_stop_ongoing + { loop_success = false; break; } - - if !loop_success { - return Err(format_err!("fail").into()); + processed_files_cnt += 1; + let mut permille = processed_files_cnt * 1000 / total_files_cnt; + if permille < 10 { + permille = 10 } - sql::execute(context, &context.sql, "DROP TABLE backup_blobs;", params![])?; - sql::try_execute(context, &context.sql, "VACUUM;"); - Ok(()) - }, - ) - .is_ok() as libc::c_int + if permille > 990 { + permille = 990 + } + context.call_cb(Event::IMEX_PROGRESS, permille as uintptr_t, 0); + if file_blob.is_empty() { + continue; + } + + let pathNfilename = format!("{}/{}", as_str(context.get_blobdir()), file_name); + if dc_write_file_safe(context, &pathNfilename, &file_blob) { + continue; + } + + error!( + context, + 0, + "Storage full? Cannot write file {} with {} bytes.", + &pathNfilename, + file_blob.len(), + ); + // otherwise the user may believe the stuff is imported correctly, but there are files missing ... + loop_success = false; + break; + } + + if !loop_success { + return Err(format_err!("fail").into()); + } + Ok(()) + }, + ); + + res.and_then(|_| { + sql::execute(context, &context.sql, "DROP TABLE backup_blobs;", params![])?; + sql::try_execute(context, &context.sql, "VACUUM;")?; + Ok(()) + }) + .is_ok() as libc::c_int } /******************************************************************************* @@ -973,7 +971,7 @@ unsafe fn export_backup(context: &Context, dir: *const libc::c_char) -> libc::c_ sql.prepare( "INSERT INTO backup_blobs (file_name, file_content) VALUES (?, ?);", - move |mut stmt| { + move |mut stmt, _| { let mut processed_files_cnt = 0; for entry in dir_handle { if entry.is_err() { diff --git a/src/dc_location.rs b/src/dc_location.rs index e9924ae45..3c7555610 100644 --- a/src/dc_location.rs +++ b/src/dc_location.rs @@ -661,7 +661,7 @@ pub unsafe fn dc_job_do_DC_JOB_MAYBE_SEND_LOCATIONS(context: &Context, _job: *mu AND timestamp>? \ AND independent=0 \ ORDER BY timestamp;", - |mut stmt_locations| { + |mut stmt_locations, _| { for (chat_id, locations_send_begin, locations_last_sent) in rows.filter_map(|r| match r { Ok(Some(v)) => Some(v), diff --git a/src/dc_msg.rs b/src/dc_msg.rs index 66e6ccd52..fa5a31419 100644 --- a/src/dc_msg.rs +++ b/src/dc_msg.rs @@ -538,46 +538,48 @@ pub fn dc_markseen_msgs(context: &Context, msg_ids: *const u32, msg_cnt: usize) if msg_ids.is_null() || msg_cnt <= 0 { return false; } - context.sql.prepare( + let msgs = context.sql.prepare( "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; - + |mut stmt, _| { + let mut res = Vec::with_capacity(msg_cnt); for i in 0..msg_cnt { - // TODO: do I need to reset? 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); - - unsafe { dc_job_add( - context, - 130, - id as i32, - 0 as *const libc::c_char, - 0, - ) }; - send_event = true; - } - } else if curr_state == 10 { - dc_update_msg_state(context, id, 13); - send_event = true; - } - } + let (state, blocked) = stmt.query_row(params![id as i32], |row| { + Ok((row.get::<_, i32>(0)?, row.get::<_, i32>(1)?)) + })?; + res.push((id, state, blocked)); } - - if send_event { - context.call_cb(Event::MSGS_CHANGED, 0, 0); - } - Ok(()) + Ok(res) } - ).is_ok() + ); + + if msgs.is_err() { + warn!(context, 0, "markseen_msgs failed: {:?}", msgs); + return false; + } + let mut send_event = false; + let msgs = msgs.unwrap(); + + for (id, curr_state, curr_blocked) in msgs.into_iter() { + if curr_blocked == 0 { + if curr_state == 10 || curr_state == 13 { + dc_update_msg_state(context, id, 16); + info!(context, 0, "Seen message #{}.", id); + + unsafe { dc_job_add(context, 130, id as i32, 0 as *const libc::c_char, 0) }; + send_event = true; + } + } else if curr_state == 10 { + dc_update_msg_state(context, id, 13); + send_event = true; + } + } + + if send_event { + context.call_cb(Event::MSGS_CHANGED, 0, 0); + } + + true } pub fn dc_update_msg_state(context: &Context, msg_id: uint32_t, state: libc::c_int) -> bool { @@ -601,7 +603,7 @@ pub fn dc_star_msgs( } context .sql - .prepare("UPDATE msgs SET starred=? WHERE id=?;", |mut stmt| { + .prepare("UPDATE msgs SET starred=? WHERE id=?;", |mut stmt, _| { for i in 0..msg_cnt { stmt.execute(params![star, unsafe { *msg_ids.offset(i as isize) as i32 }])?; } diff --git a/src/dc_receive_imf.rs b/src/dc_receive_imf.rs index 1483e74d6..ff95417de 100644 --- a/src/dc_receive_imf.rs +++ b/src/dc_receive_imf.rs @@ -443,7 +443,7 @@ pub unsafe fn dc_receive_imf( timestamp_sent, timestamp_rcvd, type, state, msgrmsg, txt, txt_raw, param, \ bytes, hidden, mime_headers, mime_in_reply_to, mime_references) \ VALUES (?,?,?,?,?,?, ?,?,?,?,?,?, ?,?,?,?,?,?, ?,?);", - |mut stmt| { + |mut stmt, conn| { let mut i = 0; loop { if !(i < icnt) { @@ -528,9 +528,9 @@ pub unsafe fn dc_receive_imf( } else { free(txt_raw as *mut libc::c_void); txt_raw = 0 as *mut libc::c_char; - insert_msg_id = sql::get_rowid( + insert_msg_id = sql::get_rowid_with_conn( context, - &context.sql, + conn, "msgs", "rfc724_mid", as_str(rfc724_mid), diff --git a/src/dc_tools.rs b/src/dc_tools.rs index 52797b0c2..ecd8086fc 100644 --- a/src/dc_tools.rs +++ b/src/dc_tools.rs @@ -1,4 +1,5 @@ use std::borrow::Cow; +use std::ffi::{CStr, CString}; use std::fs; use std::time::SystemTime; @@ -1506,20 +1507,20 @@ pub trait OsStrExt { /// /// On windows when the string contains invalid Unicode /// `[Err]([CStringError::NotUnicode])` is returned. - fn to_c_string(&self) -> Result; + fn to_c_string(&self) -> Result; } impl> OsStrExt for T { #[cfg(not(target_os = "windows"))] - fn to_c_string(&self) -> Result { + fn to_c_string(&self) -> Result { use std::os::unix::ffi::OsStrExt; - std::ffi::CString::new(self.as_ref().as_bytes()).map_err(|err| match err { + CString::new(self.as_ref().as_bytes()).map_err(|err| match err { std::ffi::NulError { .. } => CStringError::InteriorNullByte, }) } #[cfg(target_os = "windows")] - fn to_c_string(&self) -> Result { + fn to_c_string(&self) -> Result { os_str_to_c_string_unicode(&self) } } @@ -1528,29 +1529,50 @@ impl> OsStrExt for T { #[allow(dead_code)] fn os_str_to_c_string_unicode( os_str: &dyn AsRef, -) -> Result { +) -> Result { match os_str.as_ref().to_str() { - Some(val) => std::ffi::CString::new(val.as_bytes()).map_err(|err| match err { + Some(val) => CString::new(val.as_bytes()).map_err(|err| match err { std::ffi::NulError { .. } => CStringError::InteriorNullByte, }), None => Err(CStringError::NotUnicode), } } -pub fn to_cstring>(s: S) -> std::ffi::CString { - std::ffi::CString::new(s.as_ref()).unwrap() +pub fn to_cstring>(s: S) -> CString { + CString::new(s.as_ref()).unwrap() } pub fn to_string(s: *const libc::c_char) -> String { if s.is_null() { return "".into(); } - unsafe { std::ffi::CStr::from_ptr(s).to_str().unwrap().to_string() } + match unsafe { CStr::from_ptr(s).to_str() } { + Ok(s) => s.to_string(), + Err(err) => { + eprintln!( + "invalid string: '{:?}', {:?}", + unsafe { CStr::from_ptr(s).to_bytes() }, + err + ); + panic!( + "Non utf8 string: '{:?}' ({:?})", + unsafe { CStr::from_ptr(s).to_bytes() }, + err + ); + } + } } pub fn as_str<'a>(s: *const libc::c_char) -> &'a str { assert!(!s.is_null(), "cannot be used on null pointers"); - unsafe { std::ffi::CStr::from_ptr(s).to_str().unwrap() } + match unsafe { CStr::from_ptr(s).to_str() } { + Ok(s) => s, + Err(err) => panic!( + "Non utf8 string: '{:?}' ({:?})", + unsafe { CStr::from_ptr(s).to_bytes() }, + err + ), + } } /// Convert a C `*char` pointer to a [std::path::Path] slice. @@ -1981,7 +2003,7 @@ mod tests { let some_dir = std::path::Path::new(&some_str); assert_eq!( some_dir.as_os_str().to_c_string().unwrap(), - std::ffi::CString::new("/some/valid/utf8").unwrap() + CString::new("/some/valid/utf8").unwrap() ); } @@ -2006,7 +2028,7 @@ mod tests { let some_dir = std::path::Path::new(&some_str); assert_eq!( some_dir.as_os_str().to_c_string().unwrap(), - std::ffi::CString::new("/some/valid/utf8").unwrap() + CString::new("/some/valid/utf8").unwrap() ); } @@ -2015,7 +2037,7 @@ mod tests { let some_str = std::ffi::OsString::from("foo"); assert_eq!( os_str_to_c_string_unicode(&some_str).unwrap(), - std::ffi::CString::new("foo").unwrap() + CString::new("foo").unwrap() ); } @@ -2025,7 +2047,7 @@ mod tests { let some_path = std::path::Path::new(&some_str); assert_eq!( os_str_to_c_string_unicode(&some_path).unwrap(), - std::ffi::CString::new("/some/path").unwrap() + CString::new("/some/path").unwrap() ); } @@ -2040,15 +2062,180 @@ mod tests { #[test] fn test_as_path() { - let some_path = std::ffi::CString::new("/some/path").unwrap(); + let some_path = CString::new("/some/path").unwrap(); let ptr = some_path.as_ptr(); assert_eq!(as_path(ptr), std::ffi::OsString::from("/some/path")) } #[test] fn test_as_path_unicode_fn() { - let some_path = std::ffi::CString::new("/some/path").unwrap(); + let some_path = CString::new("/some/path").unwrap(); let ptr = some_path.as_ptr(); - assert_eq!(as_path_unicode(ptr), std::ffi::OsString::from("/some/path")) + assert_eq!(as_path_unicode(ptr), std::ffi::OsString::from("/some/path")); + + let a = [ + 82, 101, 116, 117, 114, 110, 45, 80, 97, 116, 104, 58, 32, 60, 100, 105, 103, 116, 101, + 115, 116, 52, 64, 116, 101, 115, 116, 114, 117, 110, 46, 111, 114, 103, 62, 13, 10, 82, + 101, 99, 101, 105, 118, 101, 100, 58, 32, 102, 114, 111, 109, 32, 104, 113, 53, 46, + 109, 101, 114, 108, 105, 110, 117, 120, 46, 101, 117, 13, 10, 9, 98, 121, 32, 104, 113, + 53, 46, 109, 101, 114, 108, 105, 110, 117, 120, 46, 101, 117, 32, 40, 68, 111, 118, + 101, 99, 111, 116, 41, 32, 119, 105, 116, 104, 32, 76, 77, 84, 80, 32, 105, 100, 32, + 109, 81, 119, 78, 68, 100, 113, 98, 77, 70, 51, 72, 69, 81, 65, 65, 80, 122, 118, 70, + 68, 103, 13, 10, 9, 59, 32, 84, 104, 117, 44, 32, 49, 56, 32, 74, 117, 108, 32, 50, 48, + 49, 57, 32, 49, 56, 58, 49, 56, 58, 51, 52, 32, 43, 48, 50, 48, 48, 13, 10, 82, 101, + 99, 101, 105, 118, 101, 100, 58, 32, 102, 114, 111, 109, 32, 115, 112, 97, 99, 101, + 109, 97, 99, 46, 102, 114, 105, 116, 122, 46, 98, 111, 120, 32, 40, 72, 83, 73, 45, 75, + 66, 87, 45, 49, 48, 57, 45, 49, 57, 50, 45, 49, 57, 53, 45, 49, 52, 55, 46, 104, 115, + 105, 54, 46, 107, 97, 98, 101, 108, 45, 98, 97, 100, 101, 110, 119, 117, 101, 114, 116, + 116, 101, 109, 98, 101, 114, 103, 46, 100, 101, 32, 91, 49, 48, 57, 46, 49, 57, 50, 46, + 49, 57, 53, 46, 49, 52, 55, 93, 41, 13, 10, 9, 98, 121, 32, 104, 113, 53, 46, 109, 101, + 114, 108, 105, 110, 117, 120, 46, 101, 117, 32, 40, 80, 111, 115, 116, 102, 105, 120, + 41, 32, 119, 105, 116, 104, 32, 85, 84, 70, 56, 83, 77, 84, 80, 83, 65, 32, 105, 100, + 32, 49, 65, 69, 52, 53, 52, 48, 48, 65, 48, 59, 13, 10, 9, 84, 104, 117, 44, 32, 49, + 56, 32, 74, 117, 108, 32, 50, 48, 49, 57, 32, 49, 56, 58, 49, 56, 58, 51, 52, 32, 43, + 48, 50, 48, 48, 32, 40, 67, 69, 83, 84, 41, 13, 10, 68, 75, 73, 77, 45, 83, 105, 103, + 110, 97, 116, 117, 114, 101, 58, 32, 118, 61, 49, 59, 32, 97, 61, 114, 115, 97, 45, + 115, 104, 97, 50, 53, 54, 59, 32, 99, 61, 115, 105, 109, 112, 108, 101, 47, 115, 105, + 109, 112, 108, 101, 59, 32, 100, 61, 116, 101, 115, 116, 114, 117, 110, 46, 111, 114, + 103, 59, 13, 10, 9, 115, 61, 116, 101, 115, 116, 114, 117, 110, 59, 32, 116, 61, 49, + 53, 54, 51, 52, 54, 54, 55, 49, 52, 59, 13, 10, 9, 98, 104, 61, 120, 81, 109, 120, 55, + 99, 110, 104, 57, 50, 71, 74, 117, 56, 74, 98, 116, 82, 105, 73, 109, 111, 79, 111, 79, + 50, 56, 114, 108, 115, 83, 90, 69, 66, 99, 109, 112, 50, 73, 67, 120, 54, 81, 61, 59, + 13, 10, 9, 104, 61, 68, 97, 116, 101, 58, 70, 114, 111, 109, 58, 84, 111, 58, 83, 117, + 98, 106, 101, 99, 116, 58, 70, 114, 111, 109, 59, 13, 10, 9, 98, 61, 99, 99, 104, 118, + 74, 117, 117, 56, 67, 104, 89, 98, 78, 52, 105, 121, 110, 49, 70, 81, 85, 119, 68, 97, + 48, 101, 77, 68, 103, 88, 56, 109, 112, 76, 72, 82, 80, 117, 78, 79, 57, 56, 69, 98, + 50, 119, 112, 89, 115, 47, 57, 118, 53, 120, 97, 70, 68, 116, 83, 115, 86, 56, 73, 52, + 48, 13, 10, 9, 32, 87, 81, 102, 89, 111, 88, 52, 56, 50, 90, 84, 114, 77, 104, 51, 98, + 68, 89, 56, 83, 74, 98, 43, 97, 102, 90, 89, 110, 74, 106, 82, 77, 53, 79, 121, 81, 71, + 101, 110, 49, 73, 90, 122, 73, 82, 101, 78, 122, 54, 43, 43, 56, 52, 106, 48, 66, 84, + 54, 65, 80, 83, 110, 121, 118, 56, 114, 13, 10, 9, 32, 113, 51, 79, 90, 108, 69, 98, + 102, 107, 101, 83, 66, 112, 115, 75, 103, 86, 80, 90, 88, 88, 122, 85, 114, 108, 56, + 54, 122, 48, 73, 48, 110, 83, 85, 81, 88, 70, 52, 77, 85, 80, 66, 70, 43, 81, 118, 108, + 81, 101, 90, 77, 65, 80, 98, 55, 105, 53, 102, 79, 121, 83, 55, 102, 65, 97, 84, 13, + 10, 9, 32, 79, 72, 74, 72, 85, 77, 57, 53, 100, 84, 103, 67, 122, 109, 114, 114, 103, + 108, 50, 105, 85, 114, 116, 114, 71, 116, 100, 120, 89, 71, 68, 84, 110, 120, 113, 66, + 51, 48, 90, 75, 81, 110, 108, 122, 78, 55, 86, 105, 86, 83, 75, 83, 77, 43, 75, 50, 72, + 88, 100, 56, 120, 71, 121, 109, 122, 97, 13, 10, 9, 32, 50, 77, 112, 113, 68, 83, 83, + 106, 89, 51, 113, 54, 79, 116, 116, 74, 73, 71, 109, 66, 90, 98, 73, 122, 75, 87, 89, + 67, 103, 70, 81, 105, 73, 104, 48, 120, 101, 55, 48, 113, 53, 80, 118, 65, 85, 112, + 105, 83, 103, 98, 114, 54, 50, 103, 82, 122, 114, 87, 109, 49, 113, 111, 106, 118, 47, + 85, 13, 10, 9, 32, 67, 53, 106, 74, 65, 86, 76, 47, 88, 66, 118, 102, 119, 61, 61, 13, + 10, 68, 97, 116, 101, 58, 32, 84, 104, 117, 44, 32, 49, 56, 32, 74, 117, 108, 32, 50, + 48, 49, 57, 32, 49, 56, 58, 49, 56, 58, 51, 50, 32, 43, 48, 50, 48, 48, 13, 10, 70, + 114, 111, 109, 58, 32, 32, 60, 100, 105, 103, 116, 101, 115, 116, 52, 64, 116, 101, + 115, 116, 114, 117, 110, 46, 111, 114, 103, 62, 13, 10, 84, 111, 58, 32, 100, 105, 103, + 116, 101, 115, 116, 53, 64, 116, 101, 115, 116, 114, 117, 110, 46, 111, 114, 103, 13, + 10, 77, 101, 115, 115, 97, 103, 101, 45, 73, 68, 58, 32, 60, 77, 114, 46, 95, 74, 99, + 101, 57, 73, 56, 82, 108, 120, 83, 46, 86, 112, 88, 80, 109, 77, 104, 80, 80, 110, 103, + 64, 116, 101, 115, 116, 114, 117, 110, 46, 111, 114, 103, 62, 13, 10, 88, 45, 77, 97, + 105, 108, 101, 114, 58, 32, 68, 101, 108, 116, 97, 32, 67, 104, 97, 116, 32, 67, 111, + 114, 101, 32, 49, 46, 48, 46, 48, 45, 97, 108, 112, 104, 97, 46, 51, 13, 10, 67, 104, + 97, 116, 45, 86, 101, 114, 115, 105, 111, 110, 58, 32, 49, 46, 48, 13, 10, 67, 104, 97, + 116, 45, 68, 105, 115, 112, 111, 115, 105, 116, 105, 111, 110, 45, 78, 111, 116, 105, + 102, 105, 99, 97, 116, 105, 111, 110, 45, 84, 111, 58, 32, 100, 105, 103, 116, 101, + 115, 116, 52, 64, 116, 101, 115, 116, 114, 117, 110, 46, 111, 114, 103, 13, 10, 83, + 117, 98, 106, 101, 99, 116, 58, 32, 61, 63, 117, 116, 102, 45, 56, 63, 81, 63, 67, 104, + 97, 116, 61, 51, 65, 63, 61, 32, 109, 101, 115, 115, 97, 103, 101, 49, 13, 10, 65, 117, + 116, 111, 99, 114, 121, 112, 116, 58, 32, 97, 100, 100, 114, 61, 100, 105, 103, 116, + 101, 115, 116, 52, 64, 116, 101, 115, 116, 114, 117, 110, 46, 111, 114, 103, 59, 32, + 112, 114, 101, 102, 101, 114, 45, 101, 110, 99, 114, 121, 112, 116, 61, 110, 111, 112, + 114, 101, 102, 101, 114, 101, 110, 99, 101, 59, 13, 10, 32, 107, 101, 121, 100, 97, + 116, 97, 61, 120, 115, 66, 78, 66, 70, 48, 119, 109, 57, 103, 66, 67, 65, 67, 86, 70, + 84, 115, 112, 97, 85, 117, 99, 102, 118, 69, 97, 72, 88, 52, 70, 48, 121, 115, 55, 70, + 104, 120, 105, 79, 54, 69, 117, 65, 97, 89, 78, 53, 83, 120, 56, 78, 68, 85, 99, 99, + 102, 68, 110, 113, 52, 78, 103, 98, 104, 83, 79, 119, 110, 104, 73, 104, 54, 122, 72, + 98, 67, 13, 10, 32, 104, 82, 118, 55, 108, 84, 51, 83, 79, 49, 51, 67, 121, 99, 97, 84, + 82, 109, 122, 56, 75, 57, 73, 65, 75, 120, 71, 108, 50, 111, 77, 102, 115, 54, 119, 72, + 87, 99, 51, 69, 112, 82, 102, 52, 87, 117, 48, 49, 79, 77, 85, 109, 51, 47, 66, 66, + 102, 85, 79, 54, 113, 115, 47, 47, 50, 121, 101, 53, 113, 103, 119, 110, 48, 83, 86, + 120, 43, 105, 13, 10, 32, 72, 98, 74, 115, 77, 90, 76, 67, 121, 107, 98, 68, 119, 107, + 100, 105, 57, 99, 86, 88, 80, 87, 77, 43, 103, 84, 67, 87, 72, 104, 101, 47, 97, 116, + 102, 90, 83, 115, 69, 100, 75, 110, 112, 56, 72, 84, 56, 97, 98, 86, 66, 68, 50, 54, + 102, 86, 48, 56, 85, 87, 77, 49, 77, 68, 69, 86, 113, 120, 109, 54, 57, 54, 67, 99, + 101, 52, 55, 74, 13, 10, 32, 106, 104, 108, 108, 115, 54, 50, 98, 74, 108, 81, 103, 73, + 47, 104, 111, 43, 70, 77, 75, 101, 53, 76, 87, 101, 110, 87, 49, 77, 115, 70, 101, 78, + 66, 85, 108, 77, 87, 98, 75, 120, 85, 71, 108, 74, 83, 114, 109, 79, 108, 114, 78, 101, + 97, 65, 119, 57, 57, 51, 78, 89, 109, 87, 114, 98, 74, 114, 97, 72, 83, 121, 55, 86, + 82, 57, 80, 51, 73, 13, 10, 32, 79, 71, 113, 72, 87, 57, 49, 77, 116, 49, 122, 115, 89, + 88, 103, 77, 87, 120, 78, 119, 79, 103, 74, 73, 71, 86, 55, 49, 84, 110, 116, 76, 55, + 113, 85, 86, 87, 56, 115, 99, 73, 116, 116, 66, 65, 66, 69, 66, 65, 65, 72, 78, 70, + 106, 120, 107, 97, 87, 100, 48, 90, 88, 78, 48, 78, 69, 66, 48, 90, 88, 78, 48, 99, + 110, 86, 117, 76, 109, 13, 10, 32, 57, 121, 90, 122, 55, 67, 119, 73, 107, 69, 69, 65, + 69, 73, 65, 68, 77, 67, 71, 81, 69, 70, 65, 108, 48, 119, 109, 57, 103, 67, 71, 119, + 77, 69, 67, 119, 107, 73, 66, 119, 89, 86, 67, 65, 107, 75, 67, 119, 73, 68, 70, 103, + 73, 66, 70, 105, 69, 69, 83, 105, 87, 110, 118, 80, 73, 73, 102, 78, 66, 88, 78, 56, + 103, 84, 48, 70, 98, 85, 13, 10, 32, 84, 47, 79, 66, 104, 103, 119, 65, 67, 103, 107, + 81, 48, 70, 98, 85, 84, 47, 79, 66, 104, 103, 119, 100, 114, 81, 102, 43, 79, 99, 119, + 115, 73, 51, 65, 83, 119, 69, 90, 108, 66, 48, 100, 88, 104, 88, 83, 50, 55, 71, 72, + 115, 122, 47, 53, 107, 71, 101, 112, 90, 99, 90, 75, 114, 72, 74, 111, 117, 69, 43, 88, + 74, 55, 109, 57, 100, 74, 67, 13, 10, 32, 70, 69, 118, 103, 54, 51, 117, 81, 111, 70, + 83, 47, 76, 76, 67, 111, 47, 109, 55, 51, 122, 97, 82, 118, 109, 85, 98, 68, 43, 120, + 111, 55, 57, 51, 103, 43, 84, 118, 84, 109, 101, 78, 75, 87, 82, 101, 70, 104, 66, 113, + 69, 48, 82, 121, 80, 121, 51, 79, 89, 116, 81, 52, 73, 77, 104, 87, 104, 76, 53, 121, + 56, 53, 98, 118, 84, 81, 107, 100, 13, 10, 32, 47, 86, 116, 101, 68, 98, 103, 52, 52, + 86, 57, 119, 116, 47, 56, 86, 119, 85, 118, 65, 107, 101, 55, 68, 114, 65, 82, 65, 87, + 99, 99, 79, 65, 56, 122, 108, 83, 48, 97, 56, 106, 86, 76, 118, 54, 50, 113, 112, 49, + 67, 115, 103, 98, 98, 47, 114, 118, 122, 119, 97, 85, 117, 115, 88, 52, 121, 119, 69, + 84, 77, 47, 90, 108, 97, 106, 88, 56, 106, 13, 10, 32, 79, 114, 69, 114, 119, 109, 75, + 112, 87, 102, 117, 66, 67, 84, 84, 102, 103, 86, 122, 76, 68, 50, 89, 74, 117, 52, 51, + 90, 118, 118, 114, 121, 106, 83, 56, 79, 98, 114, 112, 104, 67, 80, 97, 70, 97, 103, + 86, 99, 89, 65, 65, 102, 68, 81, 118, 74, 49, 88, 89, 113, 65, 71, 43, 85, 82, 120, + 121, 117, 113, 50, 54, 53, 118, 65, 114, 77, 108, 50, 13, 10, 32, 115, 121, 77, 108, + 115, 102, 49, 108, 70, 55, 81, 74, 109, 100, 101, 51, 121, 54, 75, 107, 84, 89, 70, + 103, 110, 105, 77, 113, 85, 56, 80, 72, 52, 115, 115, 65, 47, 114, 70, 81, 76, 51, 99, + 74, 119, 50, 75, 105, 101, 81, 79, 76, 122, 114, 111, 97, 56, 56, 55, 65, 84, 81, 82, + 100, 77, 74, 118, 89, 65, 81, 103, 65, 54, 90, 121, 108, 47, 89, 13, 10, 32, 88, 102, + 55, 76, 119, 119, 103, 110, 76, 106, 98, 54, 74, 104, 67, 89, 81, 122, 66, 88, 75, 114, + 67, 88, 83, 110, 56, 112, 70, 113, 55, 105, 65, 76, 55, 78, 113, 79, 108, 117, 115, 78, + 51, 110, 80, 117, 68, 115, 57, 90, 90, 50, 81, 117, 50, 49, 120, 69, 114, 109, 53, 68, + 102, 85, 76, 47, 85, 122, 103, 88, 68, 87, 89, 75, 98, 68, 68, 50, 13, 10, 32, 49, 81, + 73, 106, 89, 74, 84, 69, 80, 87, 53, 102, 102, 122, 90, 77, 78, 116, 106, 104, 108, 70, + 54, 115, 53, 55, 74, 99, 70, 55, 56, 115, 72, 97, 108, 53, 75, 57, 85, 114, 98, 120, + 48, 97, 86, 55, 86, 56, 74, 99, 114, 87, 110, 89, 100, 54, 78, 88, 86, 68, 67, 103, 56, + 83, 122, 110, 107, 117, 49, 50, 106, 97, 98, 55, 56, 118, 84, 66, 13, 10, 32, 120, 77, + 47, 55, 98, 80, 108, 111, 81, 53, 120, 55, 43, 104, 100, 49, 67, 104, 74, 48, 105, 74, + 85, 101, 68, 51, 85, 52, 119, 47, 109, 86, 108, 114, 81, 82, 77, 75, 89, 110, 71, 99, + 82, 79, 100, 112, 67, 77, 119, 99, 52, 80, 69, 109, 116, 119, 108, 74, 104, 113, 101, + 51, 98, 48, 75, 79, 85, 71, 54, 65, 78, 78, 65, 48, 51, 78, 112, 117, 13, 10, 32, 106, + 112, 43, 82, 113, 99, 54, 105, 111, 53, 65, 55, 57, 89, 87, 78, 115, 74, 69, 53, 43, + 98, 103, 101, 97, 110, 118, 109, 107, 65, 87, 110, 99, 100, 97, 84, 87, 89, 112, 117, + 50, 115, 67, 116, 67, 76, 75, 120, 118, 57, 81, 55, 118, 121, 49, 100, 89, 89, 112, + 110, 116, 50, 54, 74, 55, 119, 107, 67, 112, 89, 79, 120, 111, 100, 76, 89, 77, 119, + 13, 10, 32, 120, 108, 72, 113, 102, 122, 108, 105, 100, 74, 65, 111, 116, 105, 116, 79, + 50, 119, 108, 68, 104, 99, 82, 119, 65, 82, 65, 81, 65, 66, 119, 115, 66, 50, 66, 66, + 103, 66, 67, 65, 65, 103, 66, 81, 74, 100, 77, 74, 118, 89, 65, 104, 115, 77, 70, 105, + 69, 69, 83, 105, 87, 110, 118, 80, 73, 73, 102, 78, 66, 88, 78, 56, 103, 84, 48, 70, + 98, 85, 13, 10, 32, 84, 47, 79, 66, 104, 103, 119, 65, 67, 103, 107, 81, 48, 70, 98, + 85, 84, 47, 79, 66, 104, 103, 119, 99, 77, 119, 103, 65, 107, 52, 84, 83, 114, 97, 89, + 110, 86, 68, 79, 69, 108, 106, 43, 70, 118, 120, 121, 99, 107, 113, 69, 103, 119, 71, + 107, 107, 101, 78, 72, 109, 78, 88, 101, 78, 99, 87, 52, 65, 117, 81, 121, 51, 50, 75, + 101, 112, 113, 83, 13, 10, 32, 109, 85, 72, 71, 108, 87, 99, 88, 119, 82, 112, 79, 74, + 54, 53, 86, 57, 117, 121, 66, 101, 76, 90, 52, 53, 106, 73, 68, 119, 101, 98, 76, 57, + 78, 69, 82, 81, 83, 49, 98, 80, 69, 90, 85, 100, 120, 118, 79, 121, 53, 108, 57, 65, + 100, 97, 115, 121, 88, 116, 89, 98, 56, 113, 72, 116, 69, 54, 79, 80, 81, 110, 80, 56, + 116, 82, 101, 77, 106, 13, 10, 32, 112, 71, 113, 75, 90, 50, 47, 66, 50, 88, 80, 97, + 55, 81, 53, 83, 71, 66, 77, 81, 74, 83, 114, 102, 109, 99, 72, 98, 105, 84, 67, 87, + 102, 53, 75, 57, 120, 120, 50, 81, 103, 65, 78, 104, 69, 99, 70, 77, 84, 85, 53, 49, + 108, 50, 117, 54, 102, 106, 107, 112, 111, 109, 76, 88, 87, 104, 66, 101, 53, 74, 83, + 121, 85, 86, 78, 87, 103, 112, 13, 10, 32, 113, 47, 82, 50, 87, 103, 83, 118, 79, 116, + 79, 70, 103, 115, 76, 101, 108, 79, 119, 49, 72, 66, 120, 51, 82, 87, 104, 49, 72, 52, + 90, 54, 43, 109, 109, 70, 89, 119, 102, 77, 100, 77, 77, 105, 110, 74, 89, 81, 69, 73, + 102, 119, 99, 55, 79, 75, 68, 69, 121, 86, 81, 106, 71, 90, 50, 77, 50, 116, 116, 65, + 70, 80, 90, 56, 113, 90, 112, 119, 13, 10, 32, 51, 56, 89, 118, 98, 82, 55, 66, 56, 77, + 111, 56, 77, 43, 55, 78, 79, 57, 47, 50, 80, 55, 110, 122, 55, 75, 110, 43, 51, 57, 74, + 122, 90, 48, 57, 105, 69, 80, 120, 55, 102, 73, 56, 122, 120, 71, 88, 79, 89, 49, 68, + 111, 108, 115, 118, 57, 51, 65, 61, 61, 13, 10, 77, 73, 77, 69, 45, 86, 101, 114, 115, + 105, 111, 110, 58, 32, 49, 46, 48, 13, 10, 67, 111, 110, 116, 101, 110, 116, 45, 84, + 121, 112, 101, 58, 32, 116, 101, 120, 116, 47, 112, 108, 97, 105, 110, 59, 32, 99, 104, + 97, 114, 115, 101, 116, 61, 34, 117, 116, 102, 45, 56, 34, 13, 10, 67, 111, 110, 116, + 101, 110, 116, 45, 84, 114, 97, 110, 115, 102, 101, 114, 45, 69, 110, 99, 111, 100, + 105, 110, 103, 58, 32, 56, 98, 105, 116, 13, 10, 13, 10, 109, 101, 115, 115, 97, 103, + 101, 49, 13, 10, 41, 13, 10, 97, 56, 32, 79, 75, 32, 70, 101, 116, 99, 104, 32, 99, + 111, 109, 112, 108, 101, 116, 101, 100, 32, 40, 48, 46, 48, 48, 49, 32, 43, 32, 48, 46, + 48, 48, 48, 32, 115, 101, 99, 115, 41, 46, 13, 10, 26, 92, 125, 53, 30, 37, 157, 44, + 188, 143, 233, 124, 158, 226, 98, 150, 123, 175, 24, 157, 208, 127, 90, 101, 106, 113, + 61, 176, 189, 180, 233, 43, 167, 24, 98, 74, 126, 92, 15, 146, 127, 4, + ]; } } diff --git a/src/imap.rs b/src/imap.rs index d4157cb5b..c86d0aba8 100644 --- a/src/imap.rs +++ b/src/imap.rs @@ -1053,7 +1053,8 @@ impl Imap { let mut idle = match session.idle() { Ok(idle) => idle, Err(err) => { - panic!("failed to setup idle: {:?}", err); + eprintln!("failed to setup idle: {:?}", err); + return; } }; diff --git a/src/sql.rs b/src/sql.rs index 6de9786f8..d63731b19 100644 --- a/src/sql.rs +++ b/src/sql.rs @@ -1,7 +1,8 @@ use std::collections::HashSet; -use std::sync::RwLock; +use std::sync::{Arc, RwLock}; use rusqlite::{Connection, OpenFlags, Statement, NO_PARAMS}; +use thread_local_object::ThreadLocal; use crate::constants::*; use crate::context::Context; @@ -16,12 +17,14 @@ const DC_OPEN_READONLY: usize = 0x01; /// A wrapper around the underlying Sqlite3 object. pub struct Sql { pool: RwLock>>, + in_use: Arc>, } impl Sql { pub fn new() -> Sql { Sql { pool: RwLock::new(None), + in_use: Arc::new(ThreadLocal::new()), } } @@ -31,6 +34,7 @@ impl Sql { pub fn close(&self, context: &Context) { let _ = self.pool.write().unwrap().take(); + self.in_use.remove(); // drop closes the connection info!(context, 0, "Database closed."); @@ -53,6 +57,8 @@ impl Sql { P: IntoIterator, P::Item: rusqlite::ToSql, { + eprintln!("SQL EXECUTE: {}", sql); + self.start_stmt(sql.to_string()); self.with_conn(|conn| conn.execute(sql, params).map_err(Into::into)) } @@ -60,22 +66,25 @@ impl Sql { where G: FnOnce(&Connection) -> Result, { - match &*self.pool.read().unwrap() { + let res = match &*self.pool.read().unwrap() { Some(pool) => { let conn = pool.get()?; g(&conn) } None => Err(Error::SqlNoConnection), - } + }; + self.in_use.remove(); + res } pub fn prepare(&self, sql: &str, g: G) -> Result where - G: FnOnce(Statement<'_>) -> Result, + G: FnOnce(Statement<'_>, &Connection) -> Result, { + self.start_stmt(sql.to_string()); self.with_conn(|conn| { let stmt = conn.prepare(sql)?; - let res = g(stmt)?; + let res = g(stmt, conn)?; Ok(res) }) } @@ -84,6 +93,7 @@ impl Sql { where G: FnOnce(Statement<'_>, Statement<'_>, &Connection) -> Result, { + self.start_stmt(format!("{} - {}", sql1, sql2)); self.with_conn(|conn| { let stmt1 = conn.prepare(sql1)?; let stmt2 = conn.prepare(sql2)?; @@ -109,6 +119,7 @@ impl Sql { F: FnMut(&rusqlite::Row) -> rusqlite::Result, G: FnMut(rusqlite::MappedRows) -> Result, { + self.start_stmt(sql.as_ref().to_string()); self.with_conn(|conn| { let mut stmt = conn.prepare(sql.as_ref())?; let res = stmt.query_map(params, f)?; @@ -123,6 +134,7 @@ impl Sql { P: IntoIterator, P::Item: rusqlite::ToSql, { + self.start_stmt(sql.to_string()); self.with_conn(|conn| { let mut stmt = conn.prepare(sql)?; let res = stmt.exists(params)?; @@ -136,6 +148,7 @@ impl Sql { P::Item: rusqlite::ToSql, F: FnOnce(&rusqlite::Row) -> rusqlite::Result, { + self.start_stmt(sql.as_ref().to_string()); self.with_conn(|conn| conn.query_row(sql.as_ref(), params, f).map_err(Into::into)) } @@ -258,6 +271,17 @@ impl Sql { pub fn get_config_int64(&self, context: &Context, key: impl AsRef) -> Option { self.get_config(context, key).and_then(|r| r.parse().ok()) } + + fn start_stmt(&self, stmt: impl AsRef) { + if let Some(query) = self.in_use.get_cloned() { + let bt = backtrace::Backtrace::new(); + eprintln!("old query: {}", query); + eprintln!("Connection is already used from this thread: {:?}", bt); + panic!("Connection is already used from this thread"); + } + + self.in_use.set(stmt.as_ref().to_string()); + } } fn table_exists(conn: &Connection, name: impl AsRef) -> Result { @@ -838,6 +862,18 @@ pub fn get_rowid( table: impl AsRef, field: impl AsRef, value: impl AsRef, +) -> u32 { + sql.start_stmt("get rowid".to_string()); + sql.with_conn(|conn| Ok(get_rowid_with_conn(context, conn, table, field, value))) + .unwrap_or_else(|_| 0) +} + +pub fn get_rowid_with_conn( + context: &Context, + conn: &Connection, + table: impl AsRef, + field: impl AsRef, + value: impl AsRef, ) -> u32 { // alternative to sqlite3_last_insert_rowid() which MUST NOT be used due to race conditions, see comment above. // the ORDER BY ensures, this function always returns the most recent id, @@ -849,7 +885,7 @@ pub fn get_rowid( value.as_ref() ); - match sql.query_row(&query, NO_PARAMS, |row| row.get::<_, u32>(0)) { + match conn.query_row(&query, NO_PARAMS, |row| row.get::<_, u32>(0)) { Ok(id) => id, Err(err) => { error!( @@ -860,7 +896,6 @@ pub fn get_rowid( } } } - pub fn get_rowid2( context: &Context, sql: &Sql, @@ -870,6 +905,7 @@ pub fn get_rowid2( field2: impl AsRef, value2: i32, ) -> u32 { + sql.start_stmt("get rowid2".to_string()); sql.with_conn(|conn| { Ok(get_rowid2_with_conn( context, conn, table, field, value, field2, value2,