diff --git a/examples/repl/cmdline.rs b/examples/repl/cmdline.rs index 66be4e7e0..566998c6d 100644 --- a/examples/repl/cmdline.rs +++ b/examples/repl/cmdline.rs @@ -27,7 +27,7 @@ pub unsafe fn dc_reset_tables(context: &Context, bits: i32) -> i32 { if 0 != bits & 1 { dc_sqlite3_execute( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"DELETE FROM jobs;\x00" as *const u8 as *const libc::c_char, ); info!(context, 0, "(1) Jobs reset."); @@ -35,7 +35,7 @@ pub unsafe fn dc_reset_tables(context: &Context, bits: i32) -> i32 { if 0 != bits & 2 { dc_sqlite3_execute( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"DELETE FROM acpeerstates;\x00" as *const u8 as *const libc::c_char, ); info!(context, 0, "(2) Peerstates reset."); @@ -43,7 +43,7 @@ pub unsafe fn dc_reset_tables(context: &Context, bits: i32) -> i32 { if 0 != bits & 4 { dc_sqlite3_execute( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"DELETE FROM keypairs;\x00" as *const u8 as *const libc::c_char, ); info!(context, 0, "(4) Private keypairs reset."); @@ -51,33 +51,33 @@ pub unsafe fn dc_reset_tables(context: &Context, bits: i32) -> i32 { if 0 != bits & 8 { dc_sqlite3_execute( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"DELETE FROM contacts WHERE id>9;\x00" as *const u8 as *const libc::c_char, ); dc_sqlite3_execute( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"DELETE FROM chats WHERE id>9;\x00" as *const u8 as *const libc::c_char, ); dc_sqlite3_execute( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"DELETE FROM chats_contacts;\x00" as *const u8 as *const libc::c_char, ); dc_sqlite3_execute( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"DELETE FROM msgs WHERE id>9;\x00" as *const u8 as *const libc::c_char, ); dc_sqlite3_execute( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"DELETE FROM config WHERE keyname LIKE \'imap.%\' OR keyname LIKE \'configured%\';\x00" as *const u8 as *const libc::c_char, ); dc_sqlite3_execute( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"DELETE FROM leftgrps;\x00" as *const u8 as *const libc::c_char, ); info!(context, 0, "(8) Rest but server config reset."); @@ -124,7 +124,7 @@ unsafe fn dc_poke_eml_file(context: &Context, filename: *const libc::c_char) -> /// @param spec The file or directory to import. NULL for the last command. /// @return 1=success, 0=error. unsafe fn poke_spec(context: &Context, spec: *const libc::c_char) -> libc::c_int { - if 0 == dc_sqlite3_is_open(&context.sql.clone().read().unwrap()) { + if !context.sql.is_open() { error!(context, 0, "Import: Database not opened."); return 0; } @@ -140,7 +140,7 @@ unsafe fn poke_spec(context: &Context, spec: *const libc::c_char) -> libc::c_int real_spec = dc_strdup(spec); dc_sqlite3_set_config( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"import_spec\x00" as *const u8 as *const libc::c_char, real_spec, ); @@ -148,7 +148,7 @@ unsafe fn poke_spec(context: &Context, spec: *const libc::c_char) -> libc::c_int } else { real_spec = dc_sqlite3_get_config( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"import_spec\x00" as *const u8 as *const libc::c_char, 0 as *const libc::c_char, ); @@ -356,8 +356,7 @@ unsafe fn log_contactlist(context: &Context, contacts: *mut dc_array_t) { "addr unset" } ); - let peerstate = - Peerstate::from_addr(context, &context.sql.clone().read().unwrap(), as_str(addr)); + let peerstate = Peerstate::from_addr(context, &context.sql, as_str(addr)); if peerstate.is_some() && contact_id != 1 as libc::c_uint { line2 = format!( ", prefer-encrypt={}", diff --git a/src/context.rs b/src/context.rs index 51f6605c7..37b154cc4 100644 --- a/src/context.rs +++ b/src/context.rs @@ -26,7 +26,7 @@ pub struct Context { pub userdata: *mut libc::c_void, pub dbfile: Arc>, pub blobdir: Arc>, - pub sql: Arc>, + pub sql: SQLite, pub inbox: Arc>, pub perform_inbox_jobs_needed: Arc>, pub probe_imap_network: Arc>, @@ -150,7 +150,7 @@ pub fn dc_context_new( cb, os_name: unsafe { dc_strdup_keep_null(os_name) }, running_state: Arc::new(RwLock::new(Default::default())), - sql: Arc::new(RwLock::new(dc_sqlite3_new())), + sql: SQLite::new(), smtp: Arc::new(Mutex::new(Smtp::new())), smtp_state: Arc::new((Mutex::new(Default::default()), Condvar::new())), oauth2_critical: Arc::new(Mutex::new(())), @@ -261,7 +261,7 @@ unsafe fn cb_precheck_imf( } unsafe fn cb_set_config(context: &Context, key: *const libc::c_char, value: *const libc::c_char) { - dc_sqlite3_set_config(context, &context.sql.clone().read().unwrap(), key, value); + dc_sqlite3_set_config(context, &context.sql, key, value); } /* * @@ -276,14 +276,13 @@ unsafe fn cb_get_config( key: *const libc::c_char, def: *const libc::c_char, ) -> *mut libc::c_char { - dc_sqlite3_get_config(context, &context.sql.clone().read().unwrap(), key, def) + dc_sqlite3_get_config(context, &context.sql, key, def) } pub unsafe fn dc_context_unref(context: &mut Context) { if 0 != dc_is_open(context) { dc_close(context); } - dc_sqlite3_unref(context, &mut context.sql.clone().write().unwrap()); dc_jobthread_exit(&mut context.sentbox_thread.clone().write().unwrap()); dc_jobthread_exit(&mut context.mvbox_thread.clone().write().unwrap()); @@ -308,9 +307,7 @@ pub unsafe fn dc_close(context: &Context) { context.smtp.clone().lock().unwrap().disconnect(); - if 0 != dc_sqlite3_is_open(&context.sql.clone().read().unwrap()) { - dc_sqlite3_close(context, &mut context.sql.clone().write().unwrap()); - } + context.sql.close(context); let mut dbfile = context.dbfile.write().unwrap(); free(*dbfile as *mut libc::c_void); *dbfile = 0 as *mut libc::c_char; @@ -320,7 +317,10 @@ pub unsafe fn dc_close(context: &Context) { } pub unsafe fn dc_is_open(context: &Context) -> libc::c_int { - dc_sqlite3_is_open(&context.sql.clone().read().unwrap()) + match context.sql.is_open() { + true => 1, + false => 0, + } } pub unsafe fn dc_get_userdata(context: &mut Context) -> *mut libc::c_void { @@ -348,7 +348,7 @@ pub unsafe fn dc_open( *context.blobdir.write().unwrap() = dir; } // Create/open sqlite database, this may already use the blobdir - if !(0 == dc_sqlite3_open(context, &mut context.sql.write().unwrap(), dbfile, 0i32)) { + if context.sql.open(context, as_path(dbfile), 0) { success = 1i32 } } @@ -376,27 +376,26 @@ pub unsafe fn dc_set_config( if strcmp(key, b"selfavatar\x00" as *const u8 as *const libc::c_char) == 0 && !value.is_null() { rel_path = dc_strdup(value); if !(0 == dc_make_rel_and_copy(context, &mut rel_path)) { - ret = - dc_sqlite3_set_config(context, &context.sql.clone().read().unwrap(), key, rel_path) + ret = dc_sqlite3_set_config(context, &context.sql, key, rel_path) } } else if strcmp(key, b"inbox_watch\x00" as *const u8 as *const libc::c_char) == 0 { - ret = dc_sqlite3_set_config(context, &context.sql.clone().read().unwrap(), key, value); + ret = dc_sqlite3_set_config(context, &context.sql, key, value); dc_interrupt_imap_idle(context); } else if strcmp( key, b"sentbox_watch\x00" as *const u8 as *const libc::c_char, ) == 0 { - ret = dc_sqlite3_set_config(context, &context.sql.clone().read().unwrap(), key, value); + ret = dc_sqlite3_set_config(context, &context.sql, key, value); dc_interrupt_sentbox_idle(context); } else if strcmp(key, b"mvbox_watch\x00" as *const u8 as *const libc::c_char) == 0 { - ret = dc_sqlite3_set_config(context, &context.sql.clone().read().unwrap(), key, value); + ret = dc_sqlite3_set_config(context, &context.sql, key, value); dc_interrupt_mvbox_idle(context); } else if strcmp(key, b"selfstatus\x00" as *const u8 as *const libc::c_char) == 0 { let def = dc_stock_str(context, 13); ret = dc_sqlite3_set_config( context, - &context.sql.clone().read().unwrap(), + &context.sql, key, if value.is_null() || strcmp(value, def) == 0 { 0 as *const libc::c_char @@ -406,7 +405,7 @@ pub unsafe fn dc_set_config( ); free(def as *mut libc::c_void); } else { - ret = dc_sqlite3_set_config(context, &context.sql.clone().read().unwrap(), key, value); + ret = dc_sqlite3_set_config(context, &context.sql, key, value); } free(rel_path as *mut libc::c_void); ret @@ -482,23 +481,14 @@ pub unsafe fn dc_get_config(context: &Context, key: *const libc::c_char) -> *mut } if strcmp(key, b"selfavatar\x00" as *const u8 as *const libc::c_char) == 0 { - let rel_path: *mut libc::c_char = dc_sqlite3_get_config( - context, - &context.sql.clone().read().unwrap(), - key, - 0 as *const libc::c_char, - ); + let rel_path: *mut libc::c_char = + dc_sqlite3_get_config(context, &context.sql, key, 0 as *const libc::c_char); if !rel_path.is_null() { value = dc_get_abs_path(context, rel_path); free(rel_path as *mut libc::c_void); } } else { - value = dc_sqlite3_get_config( - context, - &context.sql.clone().read().unwrap(), - key, - 0 as *const libc::c_char, - ) + value = dc_sqlite3_get_config(context, &context.sql, key, 0 as *const libc::c_char) } if value.is_null() { @@ -613,18 +603,18 @@ pub unsafe fn dc_get_info(context: &Context) -> *mut libc::c_char { dc_loginparam_read( context, l, - &context.sql.clone().read().unwrap(), + &context.sql, b"\x00" as *const u8 as *const libc::c_char, ); dc_loginparam_read( context, l2, - &context.sql.clone().read().unwrap(), + &context.sql, b"configured_\x00" as *const u8 as *const libc::c_char, ); let displayname = dc_sqlite3_get_config( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"displayname\x00" as *const u8 as *const libc::c_char, 0 as *const libc::c_char, ); @@ -634,31 +624,31 @@ pub unsafe fn dc_get_info(context: &Context) -> *mut libc::c_char { let contacts = dc_get_real_contact_cnt(context) as usize; let is_configured = dc_sqlite3_get_config_int( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"configured\x00" as *const u8 as *const libc::c_char, 0, ); let dbversion = dc_sqlite3_get_config_int( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"dbversion\x00" as *const u8 as *const libc::c_char, 0, ); let e2ee_enabled = dc_sqlite3_get_config_int( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"e2ee_enabled\x00" as *const u8 as *const libc::c_char, 1, ); let mdns_enabled = dc_sqlite3_get_config_int( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"mdns_enabled\x00" as *const u8 as *const libc::c_char, 1, ); let mut stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT COUNT(*) FROM keypairs;\x00" as *const u8 as *const libc::c_char, ); sqlite3_step(stmt); @@ -666,61 +656,60 @@ pub unsafe fn dc_get_info(context: &Context) -> *mut libc::c_char { sqlite3_finalize(stmt); stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT COUNT(*) FROM acpeerstates;\x00" as *const u8 as *const libc::c_char, ); sqlite3_step(stmt); let pub_key_cnt = sqlite3_column_int(stmt, 0); sqlite3_finalize(stmt); - let fingerprint_str = if let Some(key) = - Key::from_self_public(context, (*l2).addr, &context.sql.clone().read().unwrap()) - { - key.fingerprint() - } else { - "".into() - }; + let fingerprint_str = + if let Some(key) = Key::from_self_public(context, (*l2).addr, &context.sql) { + key.fingerprint() + } else { + "".into() + }; let l_readable_str = dc_loginparam_get_readable(l); let l2_readable_str = dc_loginparam_get_readable(l2); let inbox_watch = dc_sqlite3_get_config_int( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"inbox_watch\x00" as *const u8 as *const libc::c_char, 1, ); let sentbox_watch = dc_sqlite3_get_config_int( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"sentbox_watch\x00" as *const u8 as *const libc::c_char, 1, ); let mvbox_watch = dc_sqlite3_get_config_int( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"mvbox_watch\x00" as *const u8 as *const libc::c_char, 1, ); let mvbox_move = dc_sqlite3_get_config_int( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"mvbox_move\x00" as *const u8 as *const libc::c_char, 1, ); let folders_configured = dc_sqlite3_get_config_int( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"folders_configured\x00" as *const u8 as *const libc::c_char, 0, ); let configured_sentbox_folder = dc_sqlite3_get_config( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"configured_sentbox_folder\x00" as *const u8 as *const libc::c_char, b"\x00" as *const u8 as *const libc::c_char, ); let configured_mvbox_folder = dc_sqlite3_get_config( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"configured_mvbox_folder\x00" as *const u8 as *const libc::c_char, b"\x00" as *const u8 as *const libc::c_char, ); @@ -818,7 +807,7 @@ pub unsafe fn dc_get_fresh_msgs(context: &Context) -> *mut dc_array_t { if !ret.is_null() { stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT m.id 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.state=? \ AND m.hidden=0 \ @@ -864,7 +853,7 @@ pub unsafe fn dc_search_msgs( if 0 != chat_id { stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"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;\x00" @@ -877,7 +866,7 @@ pub unsafe fn dc_search_msgs( let show_deaddrop = 0; stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"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=?) \ @@ -929,7 +918,7 @@ pub unsafe fn dc_is_inbox(_context: &Context, folder_name: *const libc::c_char) pub unsafe fn dc_is_sentbox(context: &Context, folder_name: *const libc::c_char) -> libc::c_int { let sentbox_name = dc_sqlite3_get_config( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"configured_sentbox_folder\x00" as *const u8 as *const libc::c_char, 0 as *const libc::c_char, ); @@ -948,7 +937,7 @@ pub unsafe fn dc_is_sentbox(context: &Context, folder_name: *const libc::c_char) pub unsafe fn dc_is_mvbox(context: &Context, folder_name: *const libc::c_char) -> libc::c_int { let mvbox_name = dc_sqlite3_get_config( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"configured_mvbox_folder\x00" as *const u8 as *const libc::c_char, 0 as *const libc::c_char, ); diff --git a/src/dc_chat.rs b/src/dc_chat.rs index 1eb8c87e2..ee5c1cd36 100644 --- a/src/dc_chat.rs +++ b/src/dc_chat.rs @@ -115,7 +115,7 @@ pub unsafe fn dc_block_chat(context: &Context, chat_id: uint32_t, new_blocking: let stmt: *mut sqlite3_stmt; stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"UPDATE chats SET blocked=? WHERE id=?;\x00" as *const u8 as *const libc::c_char, ); sqlite3_bind_int(stmt, 1i32, new_blocking); @@ -131,7 +131,7 @@ pub unsafe fn dc_chat_load_from_db(chat: *mut dc_chat_t, chat_id: uint32_t) -> b dc_chat_empty(chat); stmt = dc_sqlite3_prepare( (*chat).context, - &(*chat).context.sql.read().unwrap(), + &(*chat).context.sql, b"SELECT c.id,c.type,c.name, c.grpid,c.param,c.archived, \ c.blocked, c.gossiped_timestamp, c.locations_send_until \ FROM chats c WHERE c.id=?;\x00" as *const u8 as *const libc::c_char, @@ -263,7 +263,7 @@ pub unsafe fn dc_create_or_lookup_nchat_by_contact_id( if !ret_chat_blocked.is_null() { *ret_chat_blocked = 0i32 } - if context.sql.read().unwrap().cobj.is_null() { + if !context.sql.is_open() { return; } if contact_id == 0i32 as libc::c_uint { @@ -280,7 +280,7 @@ pub unsafe fn dc_create_or_lookup_nchat_by_contact_id( return; } contact = dc_contact_new(context); - if dc_contact_load_from_db(contact, &context.sql.clone().read().unwrap(), contact_id) { + if dc_contact_load_from_db(contact, &context.sql, contact_id) { chat_name = if !(*contact).name.is_null() && 0 != *(*contact).name.offset(0isize) as libc::c_int { (*contact).name @@ -300,12 +300,12 @@ pub unsafe fn dc_create_or_lookup_nchat_by_contact_id( create_blocked, (*contact).addr, ); - stmt = dc_sqlite3_prepare(context, &context.sql.clone().read().unwrap(), q); + stmt = dc_sqlite3_prepare(context, &context.sql, q); if !stmt.is_null() { if !(sqlite3_step(stmt) != 101i32) { chat_id = dc_sqlite3_get_rowid( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"chats\x00" as *const u8 as *const libc::c_char, b"grpid\x00" as *const u8 as *const libc::c_char, (*contact).addr, @@ -318,7 +318,7 @@ pub unsafe fn dc_create_or_lookup_nchat_by_contact_id( chat_id, contact_id, ); - stmt = dc_sqlite3_prepare(context, &context.sql.clone().read().unwrap(), q); + stmt = dc_sqlite3_prepare(context, &context.sql, q); if !(sqlite3_step(stmt) != 101i32) { sqlite3_free(q as *mut libc::c_void); q = 0 as *mut libc::c_char; @@ -353,13 +353,13 @@ pub unsafe fn dc_lookup_real_nchat_by_contact_id( if !ret_chat_blocked.is_null() { *ret_chat_blocked = 0i32 } - if context.sql.clone().read().unwrap().cobj.is_null() { + if !context.sql.is_open() { return; } stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT c.id, c.blocked FROM chats c INNER JOIN chats_contacts j ON c.id=j.chat_id WHERE c.type=100 AND c.id>9 AND j.contact_id=?;\x00" as *const u8 as *const libc::c_char); sqlite3_bind_int(stmt, 1i32, contact_id as libc::c_int); @@ -542,7 +542,7 @@ unsafe fn prepare_msg_raw( } else { let from: *mut libc::c_char = dc_sqlite3_get_config( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"configured_addr\x00" as *const u8 as *const libc::c_char, 0 as *const libc::c_char, ); @@ -565,7 +565,7 @@ unsafe fn prepare_msg_raw( if (*chat).type_0 == 100i32 { stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT contact_id FROM chats_contacts WHERE chat_id=?;\x00" as *const u8 as *const libc::c_char, ); @@ -604,7 +604,7 @@ unsafe fn prepare_msg_raw( do_guarantee_e2ee = 0i32; e2ee_enabled = dc_sqlite3_get_config_int( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"e2ee_enabled\x00" as *const u8 as *const libc::c_char, 1i32, ); @@ -613,7 +613,7 @@ unsafe fn prepare_msg_raw( let mut can_encrypt: libc::c_int = 1i32; let mut all_mutual: libc::c_int = 1i32; stmt = - dc_sqlite3_prepare(context, &context.sql.clone().read().unwrap(), + dc_sqlite3_prepare(context, &context.sql, b"SELECT ps.prefer_encrypted, c.addr FROM chats_contacts cc LEFT JOIN contacts c ON cc.contact_id=c.id LEFT JOIN acpeerstates ps ON c.addr=ps.addr WHERE cc.chat_id=? AND cc.contact_id>9;\x00" as *const u8 as *const libc::c_char); @@ -653,11 +653,7 @@ unsafe fn prepare_msg_raw( if 0 != all_mutual { do_guarantee_e2ee = 1i32 } else if 0 - != last_msg_in_chat_encrypted( - context, - &context.sql.clone().read().unwrap(), - (*chat).id, - ) + != last_msg_in_chat_encrypted(context, &context.sql, (*chat).id) { do_guarantee_e2ee = 1i32 } @@ -723,7 +719,7 @@ unsafe fn prepare_msg_raw( if 0 != dc_param_exists((*msg).param, DC_PARAM_SET_LATITUDE as libc::c_int) { stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"INSERT INTO locations \ (timestamp,from_id,chat_id, latitude,longitude,independent)\ VALUES (?,?,?, ?,?,1);\x00" as *const u8 @@ -755,7 +751,7 @@ unsafe fn prepare_msg_raw( location_id = dc_sqlite3_get_rowid2( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"locations\x00" as *const u8 as *const libc::c_char, b"timestamp\x00" as *const u8 as *const libc::c_char, timestamp as u64, @@ -768,7 +764,7 @@ unsafe fn prepare_msg_raw( stmt = dc_sqlite3_prepare( - context,&context.sql.clone().read().unwrap(), + context,&context.sql, b"INSERT INTO msgs (rfc724_mid, chat_id, from_id, to_id, timestamp, type, state, txt, param, hidden, mime_in_reply_to, mime_references, location_id) VALUES (?,?,?,?,?, ?,?,?,?,?, ?,?,?);\x00" as *const u8 as *const libc::c_char); @@ -806,7 +802,7 @@ unsafe fn prepare_msg_raw( } else { msg_id = dc_sqlite3_get_rowid( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"msgs\x00" as *const u8 as *const libc::c_char, b"rfc724_mid\x00" as *const u8 as *const libc::c_char, new_rfc724_mid, @@ -843,7 +839,7 @@ unsafe fn get_parent_mime_headers( { stmt = dc_sqlite3_prepare( - (*chat).context,&mut (*chat).context.sql.clone().read().unwrap(), + (*chat).context, &(*chat).context.sql, b"SELECT rfc724_mid, mime_in_reply_to, mime_references FROM msgs WHERE timestamp=(SELECT max(timestamp) FROM msgs WHERE chat_id=? AND from_id!=?);\x00" as *const u8 as *const libc::c_char); sqlite3_bind_int(stmt, 1i32, (*chat).id as libc::c_int); @@ -859,7 +855,7 @@ unsafe fn get_parent_mime_headers( if 0 == success { stmt = dc_sqlite3_prepare( - (*chat).context,&mut (*chat).context.sql.clone().read().unwrap(), + (*chat).context, &(*chat).context.sql, b"SELECT rfc724_mid, mime_in_reply_to, mime_references FROM msgs WHERE timestamp=(SELECT min(timestamp) FROM msgs WHERE chat_id=? AND from_id==?);\x00" as *const u8 as *const libc::c_char); sqlite3_bind_int(stmt, 1i32, (*chat).id as libc::c_int); @@ -892,15 +888,16 @@ pub unsafe fn dc_chat_is_self_talk(chat: *const dc_chat_t) -> libc::c_int { // TODO should return bool /rtn unsafe fn last_msg_in_chat_encrypted( context: &Context, - sql: &dc_sqlite3_t, + sql: &SQLite, chat_id: uint32_t, ) -> libc::c_int { let mut last_is_encrypted: libc::c_int = 0i32; let stmt: *mut sqlite3_stmt = dc_sqlite3_prepare( - context,sql, - b"SELECT param FROM msgs WHERE timestamp=(SELECT MAX(timestamp) FROM msgs WHERE chat_id=?) ORDER BY id DESC;\x00" - as *const u8 as *const libc::c_char); + context, + sql, + b"SELECT param FROM msgs WHERE timestamp=(SELECT MAX(timestamp) FROM msgs WHERE chat_id=?) ORDER BY id DESC;\x00" + as *const u8 as *const libc::c_char); sqlite3_bind_int(stmt, 1i32, chat_id as libc::c_int); if sqlite3_step(stmt) == 100i32 { let msg_param: *mut dc_param_t = dc_param_new(); @@ -922,7 +919,7 @@ pub unsafe fn dc_chat_update_param(chat: *mut dc_chat_t) -> libc::c_int { let success: libc::c_int; let stmt: *mut sqlite3_stmt = dc_sqlite3_prepare( (*chat).context, - &mut (*chat).context.sql.clone().read().unwrap(), + &(*chat).context.sql, b"UPDATE chats SET param=? WHERE id=?\x00" as *const u8 as *const libc::c_char, ); sqlite3_bind_text(stmt, 1i32, (*(*chat).param).packed, -1i32, None); @@ -948,7 +945,7 @@ pub unsafe fn dc_is_contact_in_chat( stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT contact_id FROM chats_contacts WHERE chat_id=? AND contact_id=?;\x00" as *const u8 as *const libc::c_char, ); @@ -967,7 +964,7 @@ pub unsafe fn dc_is_contact_in_chat( pub unsafe fn dc_unarchive_chat(context: &Context, chat_id: uint32_t) { let stmt: *mut sqlite3_stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"UPDATE chats SET archived=0 WHERE id=?\x00" as *const u8 as *const libc::c_char, ); sqlite3_bind_int(stmt, 1i32, chat_id as libc::c_int); @@ -1106,7 +1103,7 @@ unsafe fn set_draft_raw(context: &Context, chat_id: uint32_t, msg: *mut dc_msg_t _ => { stmt = dc_sqlite3_prepare( - context,&context.sql.clone().read().unwrap(), + context,&context.sql, b"INSERT INTO msgs (chat_id, from_id, timestamp, type, state, txt, param, hidden) VALUES (?,?,?, ?,?,?,?,?);\x00" as *const u8 as *const libc::c_char); @@ -1143,7 +1140,7 @@ unsafe fn get_draft_msg_id(context: &Context, chat_id: uint32_t) -> uint32_t { let mut draft_msg_id: uint32_t = 0i32 as uint32_t; let stmt: *mut sqlite3_stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT id FROM msgs WHERE chat_id=? AND state=?;\x00" as *const u8 as *const libc::c_char, ); sqlite3_bind_int(stmt, 1i32, chat_id as libc::c_int); @@ -1193,26 +1190,26 @@ pub unsafe fn dc_get_chat_msgs( if chat_id == 1i32 as libc::c_uint { let show_emails: libc::c_int = dc_sqlite3_get_config_int( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"show_emails\x00" as *const u8 as *const libc::c_char, 0i32, ); stmt = dc_sqlite3_prepare( - context,&context.sql.clone().read().unwrap(), + context,&context.sql, b"SELECT m.id, m.timestamp FROM msgs m LEFT JOIN chats ON m.chat_id=chats.id LEFT JOIN contacts ON m.from_id=contacts.id WHERE m.from_id!=1 AND m.from_id!=2 AND m.hidden=0 AND chats.blocked=2 AND contacts.blocked=0 AND m.msgrmsg>=? ORDER BY m.timestamp,m.id;\x00" as *const u8 as *const libc::c_char); sqlite3_bind_int(stmt, 1i32, if show_emails == 2i32 { 0i32 } else { 1i32 }); } else if chat_id == 5i32 as libc::c_uint { stmt = dc_sqlite3_prepare( - context,&context.sql.clone().read().unwrap(), + context,&context.sql, b"SELECT m.id, m.timestamp FROM msgs m LEFT JOIN contacts ct ON m.from_id=ct.id WHERE m.starred=1 AND m.hidden=0 AND ct.blocked=0 ORDER BY m.timestamp,m.id;\x00" as *const u8 as *const libc::c_char) } else { stmt = dc_sqlite3_prepare( - context,&context.sql.clone().read().unwrap(), + context,&context.sql, b"SELECT m.id, m.timestamp FROM msgs m WHERE m.chat_id=? AND m.hidden=0 ORDER BY m.timestamp,m.id;\x00" as *const u8 as *const libc::c_char); sqlite3_bind_int(stmt, 1i32, chat_id as libc::c_int); @@ -1251,7 +1248,7 @@ pub unsafe fn dc_get_msg_cnt(context: &Context, chat_id: uint32_t) -> libc::c_in let stmt: *mut sqlite3_stmt; stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT COUNT(*) FROM msgs WHERE chat_id=?;\x00" as *const u8 as *const libc::c_char, ); sqlite3_bind_int(stmt, 1i32, chat_id as libc::c_int); @@ -1268,7 +1265,7 @@ pub unsafe fn dc_get_fresh_msg_cnt(context: &Context, chat_id: uint32_t) -> libc let stmt: *mut sqlite3_stmt; stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT COUNT(*) FROM msgs WHERE state=10 AND hidden=0 AND chat_id=?;\x00" as *const u8 as *const libc::c_char, ); @@ -1286,7 +1283,7 @@ pub unsafe fn dc_marknoticed_chat(context: &Context, chat_id: uint32_t) { check = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT id FROM msgs WHERE chat_id=? AND state=10;\x00" as *const u8 as *const libc::c_char, ); @@ -1294,7 +1291,7 @@ pub unsafe fn dc_marknoticed_chat(context: &Context, chat_id: uint32_t) { if !(sqlite3_step(check) != 100i32) { update = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"UPDATE msgs SET state=13 WHERE chat_id=? AND state=10;\x00" as *const u8 as *const libc::c_char, ); @@ -1313,13 +1310,13 @@ pub unsafe fn dc_marknoticed_all_chats(context: &Context) { check = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT id FROM msgs WHERE state=10;\x00" as *const u8 as *const libc::c_char, ); if !(sqlite3_step(check) != 100i32) { update = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"UPDATE msgs SET state=13 WHERE state=10;\x00" as *const u8 as *const libc::c_char, ); sqlite3_step(update); @@ -1340,7 +1337,7 @@ pub unsafe fn dc_get_chat_media( let ret: *mut dc_array_t = dc_array_new(100i32 as size_t); let stmt: *mut sqlite3_stmt = dc_sqlite3_prepare( - context,&context.sql.clone().read().unwrap(), + context,&context.sql, b"SELECT id FROM msgs WHERE chat_id=? AND (type=? OR type=? OR type=?) ORDER BY timestamp, id;\x00" as *const u8 as *const libc::c_char); sqlite3_bind_int(stmt, 1i32, chat_id as libc::c_int); @@ -1430,7 +1427,7 @@ pub unsafe fn dc_archive_chat(context: &Context, chat_id: uint32_t, archive: lib if 0 != archive { let stmt: *mut sqlite3_stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"UPDATE msgs SET state=13 WHERE chat_id=? AND state=10;\x00" as *const u8 as *const libc::c_char, ); @@ -1440,7 +1437,7 @@ pub unsafe fn dc_archive_chat(context: &Context, chat_id: uint32_t, archive: lib } let stmt_0: *mut sqlite3_stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"UPDATE chats SET archived=? WHERE id=?;\x00" as *const u8 as *const libc::c_char, ); sqlite3_bind_int(stmt_0, 1i32, archive); @@ -1461,34 +1458,27 @@ pub unsafe fn dc_delete_chat(context: &Context, chat_id: uint32_t) { as *const u8 as *const libc::c_char, chat_id, ); - if !(0 == dc_sqlite3_execute(context, &context.sql.clone().read().unwrap(), q3)) { + if !(0 == dc_sqlite3_execute(context, &context.sql, q3)) { sqlite3_free(q3 as *mut libc::c_void); q3 = sqlite3_mprintf( b"DELETE FROM msgs WHERE chat_id=%i;\x00" as *const u8 as *const libc::c_char, chat_id, ); - if !(0 == dc_sqlite3_execute(context, &context.sql.clone().read().unwrap(), q3)) { + if !(0 == dc_sqlite3_execute(context, &context.sql, q3)) { sqlite3_free(q3 as *mut libc::c_void); q3 = sqlite3_mprintf( b"DELETE FROM chats_contacts WHERE chat_id=%i;\x00" as *const u8 as *const libc::c_char, chat_id, ); - if !(0 == dc_sqlite3_execute(context, &context.sql.clone().read().unwrap(), q3)) - { + if !(0 == dc_sqlite3_execute(context, &context.sql, q3)) { sqlite3_free(q3 as *mut libc::c_void); q3 = sqlite3_mprintf( b"DELETE FROM chats WHERE id=%i;\x00" as *const u8 as *const libc::c_char, chat_id, ); - if !(0 - == dc_sqlite3_execute( - context, - &context.sql.clone().read().unwrap(), - q3, - )) - { + if !(0 == dc_sqlite3_execute(context, &context.sql, q3)) { sqlite3_free(q3 as *mut libc::c_void); q3 = 0 as *mut libc::c_char; context.call_cb( @@ -1518,7 +1508,7 @@ pub unsafe fn dc_get_chat_contacts(context: &Context, chat_id: uint32_t) -> *mut /* we could also create a list for all contacts in the deaddrop by searching contacts belonging to chats with chats.blocked=2, however, currently this is not needed */ stmt = dc_sqlite3_prepare( - context,&context.sql.clone().read().unwrap(), + context,&context.sql, b"SELECT cc.contact_id FROM chats_contacts cc LEFT JOIN contacts c ON c.id=cc.contact_id WHERE cc.chat_id=? ORDER BY c.id=1, LOWER(c.name||c.addr), c.id;\x00" as *const u8 as *const libc::c_char); sqlite3_bind_int(stmt, 1i32, chat_id as libc::c_int); @@ -1565,7 +1555,7 @@ pub unsafe fn dc_create_group_chat( grpid = dc_create_id(); stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"INSERT INTO chats (type, name, grpid, param) VALUES(?, ?, ?, \'U=1\');\x00" as *const u8 as *const libc::c_char, ); @@ -1575,7 +1565,7 @@ pub unsafe fn dc_create_group_chat( if !(sqlite3_step(stmt) != 101i32) { chat_id = dc_sqlite3_get_rowid( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"chats\x00" as *const u8 as *const libc::c_char, b"grpid\x00" as *const u8 as *const libc::c_char, grpid, @@ -1611,7 +1601,7 @@ pub unsafe fn dc_add_to_chat_contacts_table( let ret: libc::c_int; let stmt: *mut sqlite3_stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"INSERT INTO chats_contacts (chat_id, contact_id) VALUES(?, ?)\x00" as *const u8 as *const libc::c_char, ); @@ -1671,7 +1661,7 @@ pub unsafe fn dc_add_contact_to_chat_ex( } self_addr = dc_sqlite3_get_config( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"configured_addr\x00" as *const u8 as *const libc::c_char, b"\x00" as *const u8 as *const libc::c_char, ); @@ -1759,12 +1749,12 @@ unsafe fn real_group_exists(context: &Context, chat_id: uint32_t) -> libc::c_int // check if a group or a verified group exists under the given ID let stmt: *mut sqlite3_stmt; let mut ret: libc::c_int = 0i32; - if (*context.sql.clone().read().unwrap()).cobj.is_null() || chat_id <= 9i32 as libc::c_uint { + if !context.sql.is_open() || chat_id <= 9i32 as libc::c_uint { return 0i32; } stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT id FROM chats WHERE id=? AND (type=120 OR type=130);\x00" as *const u8 as *const libc::c_char, ); @@ -1792,7 +1782,7 @@ pub unsafe fn dc_set_gossiped_timestamp(context: &Context, chat_id: uint32_t, ti ); stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"UPDATE chats SET gossiped_timestamp=? WHERE id=?;\x00" as *const u8 as *const libc::c_char, ); @@ -1807,7 +1797,7 @@ pub unsafe fn dc_set_gossiped_timestamp(context: &Context, chat_id: uint32_t, ti ); stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"UPDATE chats SET gossiped_timestamp=?;\x00" as *const u8 as *const libc::c_char, ); sqlite3_bind_int64(stmt, 1i32, timestamp as sqlite3_int64); @@ -1880,7 +1870,7 @@ pub unsafe fn dc_remove_contact_from_chat( chat_id, contact_id, ); - if !(0 == dc_sqlite3_execute(context, &context.sql.clone().read().unwrap(), q3)) { + if !(0 == dc_sqlite3_execute(context, &context.sql, q3)) { context.call_cb( Event::CHAT_MODIFIED, chat_id as uintptr_t, @@ -1903,7 +1893,7 @@ pub unsafe fn dc_set_group_explicitly_left(context: &Context, grpid: *const libc if 0 == dc_is_group_explicitly_left(context, grpid) { let stmt: *mut sqlite3_stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"INSERT INTO leftgrps (grpid) VALUES(?);\x00" as *const u8 as *const libc::c_char, ); sqlite3_bind_text(stmt, 1i32, grpid, -1i32, None); @@ -1919,7 +1909,7 @@ pub unsafe fn dc_is_group_explicitly_left( ) -> libc::c_int { let stmt: *mut sqlite3_stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT id FROM leftgrps WHERE grpid=?;\x00" as *const u8 as *const libc::c_char, ); sqlite3_bind_text(stmt, 1i32, grpid, -1i32, None); @@ -1962,7 +1952,7 @@ pub unsafe fn dc_set_chat_name( new_name, chat_id, ); - if !(0 == dc_sqlite3_execute(context, &context.sql.clone().read().unwrap(), q3)) { + if !(0 == dc_sqlite3_execute(context, &context.sql, q3)) { if dc_param_get_int((*chat).param, 'U' as i32, 0i32) == 0i32 { (*msg).type_0 = 10i32; (*msg).text = dc_stock_system_msg( @@ -2104,7 +2094,7 @@ pub unsafe fn dc_forward_msgs( as *const libc::c_char, idsstr, ); - stmt = dc_sqlite3_prepare(context, &context.sql.clone().read().unwrap(), q3); + stmt = dc_sqlite3_prepare(context, &context.sql, q3); loop { if !(sqlite3_step(stmt) == 100i32) { break; @@ -2218,7 +2208,7 @@ pub unsafe fn dc_chat_get_subtitle(chat: *const dc_chat_t) -> *mut libc::c_char let r: libc::c_int; let stmt: *mut sqlite3_stmt = dc_sqlite3_prepare( - (*chat).context,&mut (*chat).context.sql.clone().read().unwrap(), + (*chat).context, &(*chat).context.sql, b"SELECT c.addr FROM chats_contacts cc LEFT JOIN contacts c ON c.id=cc.contact_id WHERE cc.chat_id=?;\x00" as *const u8 as *const libc::c_char); sqlite3_bind_int(stmt, 1i32, (*chat).id as libc::c_int); @@ -2247,7 +2237,7 @@ pub unsafe fn dc_get_chat_contact_cnt(context: &Context, chat_id: uint32_t) -> l let mut ret: libc::c_int = 0i32; let stmt: *mut sqlite3_stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT COUNT(*) FROM chats_contacts WHERE chat_id=?;\x00" as *const u8 as *const libc::c_char, ); @@ -2347,11 +2337,11 @@ pub unsafe fn dc_chat_is_sending_locations(chat: *const dc_chat_t) -> libc::c_in pub unsafe fn dc_get_chat_cnt(context: &Context) -> size_t { let mut ret: size_t = 0i32 as size_t; let mut stmt: *mut sqlite3_stmt = 0 as *mut sqlite3_stmt; - if !(*context.sql.clone().read().unwrap()).cobj.is_null() { + if context.sql.is_open() { /* no database, no chats - this is no error (needed eg. for information) */ stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT COUNT(*) FROM chats WHERE id>9 AND blocked=0;\x00" as *const u8 as *const libc::c_char, ); @@ -2380,7 +2370,7 @@ pub unsafe fn dc_get_chat_id_by_grpid( stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT id, blocked, type FROM chats WHERE grpid=?;\x00" as *const u8 as *const libc::c_char, ); @@ -2409,7 +2399,7 @@ pub unsafe fn dc_add_device_msg(context: &Context, chat_id: uint32_t, text: *con if !text.is_null() { stmt = dc_sqlite3_prepare( - context,&context.sql.clone().read().unwrap(), + context,&context.sql, b"INSERT INTO msgs (chat_id,from_id,to_id, timestamp,type,state, txt,rfc724_mid) VALUES (?,?,?, ?,?,?, ?,?);\x00" as *const u8 as *const libc::c_char); sqlite3_bind_int(stmt, 1i32, chat_id as libc::c_int); @@ -2427,7 +2417,7 @@ pub unsafe fn dc_add_device_msg(context: &Context, chat_id: uint32_t, text: *con if !(sqlite3_step(stmt) != 101i32) { msg_id = dc_sqlite3_get_rowid( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"msgs\x00" as *const u8 as *const libc::c_char, b"rfc724_mid\x00" as *const u8 as *const libc::c_char, rfc724_mid, diff --git a/src/dc_chatlist.rs b/src/dc_chatlist.rs index 420e00b54..b4ecec737 100644 --- a/src/dc_chatlist.rs +++ b/src/dc_chatlist.rs @@ -145,7 +145,7 @@ unsafe fn dc_chatlist_load_from_db( stmt = dc_sqlite3_prepare( (*chatlist).context, - &mut (*chatlist).context.sql.clone().read().unwrap(), + &(*chatlist).context.sql, b"SELECT c.id, m.id FROM chats c LEFT JOIN msgs m ON c.id=m.chat_id AND m.timestamp=( SELECT MAX(timestamp) FROM msgs WHERE chat_id=c.id 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=?) GROUP BY c.id ORDER BY IFNULL(m.timestamp,0) DESC, m.id DESC;\x00" as *const u8 as *const libc::c_char ); @@ -155,7 +155,7 @@ unsafe fn dc_chatlist_load_from_db( stmt = dc_sqlite3_prepare( (*chatlist).context, - &mut (*chatlist).context.sql.clone().read().unwrap(), + &(*chatlist).context.sql, b"SELECT c.id, m.id FROM chats c LEFT JOIN msgs m ON c.id=m.chat_id AND m.timestamp=( SELECT MAX(timestamp) FROM msgs WHERE chat_id=c.id 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 ORDER BY IFNULL(m.timestamp,0) DESC, m.id DESC;\x00" as *const u8 as *const libc::c_char); current_block = 3437258052017859086; @@ -172,7 +172,7 @@ unsafe fn dc_chatlist_load_from_db( stmt = dc_sqlite3_prepare( (*chatlist).context, - &mut (*chatlist).context.sql.clone().read().unwrap(), + &(*chatlist).context.sql, b"SELECT c.id, m.id FROM chats c LEFT JOIN msgs m ON c.id=m.chat_id AND m.timestamp=( SELECT MAX(timestamp) FROM msgs WHERE chat_id=c.id AND (hidden=0 OR (hidden=1 AND state=19))) WHERE c.id>9 AND c.blocked=0 AND c.archived=0 GROUP BY c.id ORDER BY IFNULL(m.timestamp,0) DESC, m.id DESC;\x00" as *const u8 as *const libc::c_char); current_block = 3437258052017859086; @@ -187,7 +187,7 @@ unsafe fn dc_chatlist_load_from_db( stmt = dc_sqlite3_prepare( (*chatlist).context, - &mut (*chatlist).context.sql.clone().read().unwrap(), + &(*chatlist).context.sql, b"SELECT c.id, m.id FROM chats c LEFT JOIN msgs m ON c.id=m.chat_id AND m.timestamp=( SELECT MAX(timestamp) FROM msgs WHERE chat_id=c.id AND (hidden=0 OR (hidden=1 AND state=19))) WHERE c.id>9 AND c.blocked=0 AND c.name LIKE ? GROUP BY c.id ORDER BY IFNULL(m.timestamp,0) DESC, m.id DESC;\x00" as *const u8 as *const libc::c_char); @@ -234,7 +234,7 @@ pub unsafe fn dc_get_archived_cnt(context: &Context) -> libc::c_int { let mut ret: libc::c_int = 0i32; let stmt: *mut sqlite3_stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT COUNT(*) FROM chats WHERE blocked=0 AND archived=1;\x00" as *const u8 as *const libc::c_char, ); @@ -251,7 +251,7 @@ unsafe fn get_last_deaddrop_fresh_msg(context: &Context) -> uint32_t { stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT m.id FROM msgs m LEFT JOIN chats c ON c.id=m.chat_id WHERE m.state=10 AND m.hidden=0 AND c.blocked=2 ORDER BY m.timestamp DESC, m.id DESC;\x00" as *const u8 as *const libc::c_char); /* we have an index over the state-column, this should be sufficient as there are typically only few fresh messages */ @@ -346,7 +346,7 @@ pub unsafe fn dc_chatlist_get_summary<'a>( lastcontact = dc_contact_new((*chatlist).context); dc_contact_load_from_db( lastcontact, - &mut (*chatlist).context.sql.clone().read().unwrap(), + &(*chatlist).context.sql, (*lastmsg).from_id, ); } diff --git a/src/dc_configure.rs b/src/dc_configure.rs index 74fcd05c2..1ec517cde 100644 --- a/src/dc_configure.rs +++ b/src/dc_configure.rs @@ -82,7 +82,7 @@ pub unsafe fn dc_is_configured(context: &Context) -> libc::c_int { return if 0 != dc_sqlite3_get_config_int( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"configured\x00" as *const u8 as *const libc::c_char, 0i32, ) { @@ -127,7 +127,7 @@ pub unsafe fn dc_job_do_DC_JOB_CONFIGURE_IMAP(context: &Context, _job: *mut dc_j if !(0 == dc_alloc_ongoing(context)) { ongoing_allocated_here = 1i32; - if 0 == dc_sqlite3_is_open(&context.sql.clone().read().unwrap()) { + if !context.sql.is_open() { dc_log_error( context, 0i32, @@ -173,7 +173,7 @@ pub unsafe fn dc_job_do_DC_JOB_CONFIGURE_IMAP(context: &Context, _job: *mut dc_j dc_loginparam_read( context, param, - &context.sql.clone().read().unwrap(), + &context.sql, b"\x00" as *const u8 as *const libc::c_char, ); @@ -213,7 +213,7 @@ pub unsafe fn dc_job_do_DC_JOB_CONFIGURE_IMAP(context: &Context, _job: *mut dc_j (*param).addr = strdup(to_cstring(oauth2_addr.unwrap()).as_ptr()); dc_sqlite3_set_config( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"addr\x00" as *const u8 as *const libc::c_char, (*param).addr, ); @@ -1119,7 +1119,7 @@ pub unsafe fn dc_job_do_DC_JOB_CONFIGURE_IMAP(context: &Context, _job: *mut dc_j = if 0 != - dc_sqlite3_get_config_int(context, &context.sql.clone().read().unwrap(), + dc_sqlite3_get_config_int(context, &context.sql, b"mvbox_watch\x00" as *const u8 @@ -1129,7 +1129,7 @@ pub unsafe fn dc_job_do_DC_JOB_CONFIGURE_IMAP(context: &Context, _job: *mut dc_j || 0 != - dc_sqlite3_get_config_int(context, &context.sql.clone().read().unwrap(), + dc_sqlite3_get_config_int(context, &context.sql, b"mvbox_move\x00" as *const u8 @@ -1170,13 +1170,13 @@ pub unsafe fn dc_job_do_DC_JOB_CONFIGURE_IMAP(context: &Context, _job: *mut dc_j as uintptr_t); dc_loginparam_write(context, param, - &context.sql.clone().read().unwrap(), + &context.sql, b"configured_\x00" as *const u8 as *const libc::c_char); - dc_sqlite3_set_config_int(context, &context.sql.clone().read().unwrap(), + dc_sqlite3_set_config_int(context, &context.sql, b"configured\x00" as *const u8 @@ -1725,7 +1725,7 @@ pub unsafe fn dc_connect_to_configured_imap(context: &Context, imap: &Imap) -> l ret_connected = 1i32 } else if dc_sqlite3_get_config_int( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"configured\x00" as *const u8 as *const libc::c_char, 0i32, ) == 0i32 @@ -1739,7 +1739,7 @@ pub unsafe fn dc_connect_to_configured_imap(context: &Context, imap: &Imap) -> l dc_loginparam_read( context, param, - &context.sql.clone().read().unwrap(), + &context.sql, b"configured_\x00" as *const u8 as *const libc::c_char, ); /*the trailing underscore is correct*/ diff --git a/src/dc_contact.rs b/src/dc_contact.rs index bcacf2576..78858389a 100644 --- a/src/dc_contact.rs +++ b/src/dc_contact.rs @@ -30,7 +30,7 @@ pub struct dc_contact_t<'a> { pub unsafe fn dc_marknoticed_contact(context: &Context, contact_id: uint32_t) { let stmt: *mut sqlite3_stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"UPDATE msgs SET state=13 WHERE from_id=? AND state=10;\x00" as *const u8 as *const libc::c_char, ); @@ -73,7 +73,7 @@ pub unsafe fn dc_lookup_contact_id_by_addr( addr_normalized = dc_addr_normalize(addr); addr_self = dc_sqlite3_get_config( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"configured_addr\x00" as *const u8 as *const libc::c_char, b"\x00" as *const u8 as *const libc::c_char, ); @@ -82,7 +82,7 @@ pub unsafe fn dc_lookup_contact_id_by_addr( } else { stmt = dc_sqlite3_prepare( - context,&context.sql.clone().read().unwrap(), + context,&context.sql, b"SELECT id FROM contacts WHERE addr=?1 COLLATE NOCASE AND id>?2 AND origin>=?3 AND blocked=0;\x00" as *const u8 as *const libc::c_char); sqlite3_bind_text( @@ -158,12 +158,12 @@ pub unsafe fn dc_block_contact(context: &Context, contact_id: uint32_t, new_bloc let contact: *mut dc_contact_t = dc_contact_new(context); let mut stmt: *mut sqlite3_stmt = 0 as *mut sqlite3_stmt; if !(contact_id <= 9i32 as libc::c_uint) { - if dc_contact_load_from_db(contact, &context.sql.clone().read().unwrap(), contact_id) + if dc_contact_load_from_db(contact, &context.sql, contact_id) && (*contact).blocked != new_blocking { stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"UPDATE contacts SET blocked=? WHERE id=?;\x00" as *const u8 as *const libc::c_char, ); @@ -175,7 +175,7 @@ pub unsafe fn dc_block_contact(context: &Context, contact_id: uint32_t, new_bloc sqlite3_finalize(stmt); stmt = dc_sqlite3_prepare( - context,&context.sql.clone().read().unwrap(), + context,&context.sql, b"UPDATE chats SET blocked=? WHERE type=? AND id IN (SELECT chat_id FROM chats_contacts WHERE contact_id=?);\x00" as *const u8 as *const libc::c_char); @@ -285,7 +285,7 @@ pub unsafe fn dc_contact_empty(mut contact: *mut dc_contact_t) { /* contacts with at least this origin value start a new "normal" chat, defaults to off */ pub unsafe fn dc_contact_load_from_db( contact: *mut dc_contact_t, - sql: &dc_sqlite3_t, + sql: &SQLite, contact_id: uint32_t, ) -> bool { let current_block: u64; @@ -336,7 +336,7 @@ pub unsafe fn dc_contact_load_from_db( pub unsafe fn dc_is_contact_blocked(context: &Context, contact_id: uint32_t) -> bool { let mut is_blocked = false; let contact: *mut dc_contact_t = dc_contact_new(context); - if dc_contact_load_from_db(contact, &context.sql.clone().read().unwrap(), contact_id) { + if dc_contact_load_from_db(contact, &context.sql, contact_id) { if 0 != (*contact).blocked { is_blocked = true } @@ -370,7 +370,7 @@ pub unsafe fn dc_add_or_lookup_contact( addr = dc_addr_normalize(addr__); addr_self = dc_sqlite3_get_config( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"configured_addr\x00" as *const u8 as *const libc::c_char, b"\x00" as *const u8 as *const libc::c_char, ); @@ -391,7 +391,7 @@ pub unsafe fn dc_add_or_lookup_contact( } else { stmt = dc_sqlite3_prepare( - context,&context.sql.clone().read().unwrap(), + context,&context.sql, b"SELECT id, name, addr, origin, authname FROM contacts WHERE addr=? COLLATE NOCASE;\x00" as *const u8 as *const libc::c_char); sqlite3_bind_text(stmt, 1i32, addr as *const libc::c_char, -1i32, None); @@ -429,7 +429,7 @@ pub unsafe fn dc_add_or_lookup_contact( { stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"UPDATE contacts SET name=?, addr=?, origin=?, authname=? WHERE id=?;\x00" as *const u8 as *const libc::c_char, ); @@ -474,7 +474,7 @@ pub unsafe fn dc_add_or_lookup_contact( if 0 != update_name { stmt = dc_sqlite3_prepare( - context,&context.sql.clone().read().unwrap(), + context,&context.sql, b"UPDATE chats SET name=? WHERE type=? AND id IN(SELECT chat_id FROM chats_contacts WHERE contact_id=?);\x00" as *const u8 as *const libc::c_char); @@ -489,7 +489,7 @@ pub unsafe fn dc_add_or_lookup_contact( sqlite3_finalize(stmt); stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"INSERT INTO contacts (name, addr, origin) VALUES(?, ?, ?);\x00" as *const u8 as *const libc::c_char, ); @@ -509,7 +509,7 @@ pub unsafe fn dc_add_or_lookup_contact( if sqlite3_step(stmt) == 101i32 { row_id = dc_sqlite3_get_rowid( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"contacts\x00" as *const u8 as *const libc::c_char, b"addr\x00" as *const u8 as *const libc::c_char, addr, @@ -623,7 +623,7 @@ pub unsafe fn dc_get_contacts( self_addr = dc_sqlite3_get_config( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"configured_addr\x00" as *const u8 as *const libc::c_char, b"\x00" as *const u8 as *const libc::c_char, ); @@ -641,7 +641,7 @@ pub unsafe fn dc_get_contacts( } else { stmt = dc_sqlite3_prepare( - context,&context.sql.clone().read().unwrap(), + context,&context.sql, b"SELECT c.id FROM contacts c LEFT JOIN acpeerstates ps ON c.addr=ps.addr WHERE c.addr!=?1 AND c.id>?2 AND c.origin>=?3 AND c.blocked=0 AND (c.name LIKE ?4 OR c.addr LIKE ?5) AND (1=?6 OR LENGTH(ps.verified_key_fingerprint)!=0) ORDER BY LOWER(c.name||c.addr),c.id;\x00" as *const u8 as *const libc::c_char); @@ -661,7 +661,7 @@ pub unsafe fn dc_get_contacts( ); self_name = dc_sqlite3_get_config( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"displayname\x00" as *const u8 as *const libc::c_char, b"\x00" as *const u8 as *const libc::c_char, ); @@ -678,7 +678,7 @@ pub unsafe fn dc_get_contacts( } else { stmt = dc_sqlite3_prepare( - context,&context.sql.clone().read().unwrap(), + context,&context.sql, b"SELECT id FROM contacts WHERE addr!=?1 AND id>?2 AND origin>=?3 AND blocked=0 ORDER BY LOWER(name||addr),id;\x00" as *const u8 as *const libc::c_char); sqlite3_bind_text(stmt, 1i32, self_addr, -1i32, None); @@ -714,7 +714,7 @@ pub unsafe fn dc_get_blocked_cnt(context: &Context) -> libc::c_int { stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT COUNT(*) FROM contacts WHERE id>? AND blocked!=0\x00" as *const u8 as *const libc::c_char, ); @@ -733,7 +733,7 @@ pub unsafe fn dc_get_blocked_contacts(context: &Context) -> *mut dc_array_t { stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT id FROM contacts WHERE id>? AND blocked!=0 ORDER BY LOWER(name||addr),id;\x00" as *const u8 as *const libc::c_char, ); @@ -759,23 +759,15 @@ pub unsafe fn dc_get_contact_encrinfo( let mut fingerprint_other_unverified: *mut libc::c_char = 0 as *mut libc::c_char; let mut p: *mut libc::c_char; - if !(!dc_contact_load_from_db(contact, &context.sql.clone().read().unwrap(), contact_id)) { - let peerstate = Peerstate::from_addr( - context, - &context.sql.clone().read().unwrap(), - as_str((*contact).addr), - ); + if !(!dc_contact_load_from_db(contact, &context.sql, contact_id)) { + let peerstate = Peerstate::from_addr(context, &context.sql, as_str((*contact).addr)); dc_loginparam_read( context, loginparam, - &context.sql.clone().read().unwrap(), + &context.sql, b"configured_\x00" as *const u8 as *const libc::c_char, ); - let mut self_key = Key::from_self_public( - context, - (*loginparam).addr, - &context.sql.clone().read().unwrap(), - ); + let mut self_key = Key::from_self_public(context, (*loginparam).addr, &context.sql); if peerstate.is_some() && peerstate.as_ref().and_then(|p| p.peek_key(0)).is_some() { let peerstate = peerstate.as_ref().unwrap(); @@ -791,11 +783,7 @@ pub unsafe fn dc_get_contact_encrinfo( free(p as *mut libc::c_void); if self_key.is_none() { dc_ensure_secret_key_exists(context); - self_key = Key::from_self_public( - context, - (*loginparam).addr, - &context.sql.clone().read().unwrap(), - ); + self_key = Key::from_self_public(context, (*loginparam).addr, &context.sql); } p = dc_stock_str(context, 30i32); ret += &format!(" {}:", as_str(p)); @@ -901,7 +889,7 @@ pub unsafe fn dc_delete_contact(context: &Context, contact_id: uint32_t) -> bool if !(contact_id <= 9i32 as libc::c_uint) { stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT COUNT(*) FROM chats_contacts WHERE contact_id=?;\x00" as *const u8 as *const libc::c_char, ); @@ -910,7 +898,7 @@ pub unsafe fn dc_delete_contact(context: &Context, contact_id: uint32_t) -> bool sqlite3_finalize(stmt); stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT COUNT(*) FROM msgs WHERE from_id=? OR to_id=?;\x00" as *const u8 as *const libc::c_char, ); @@ -920,7 +908,7 @@ pub unsafe fn dc_delete_contact(context: &Context, contact_id: uint32_t) -> bool sqlite3_finalize(stmt); stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"DELETE FROM contacts WHERE id=?;\x00" as *const u8 as *const libc::c_char, ); sqlite3_bind_int(stmt, 1i32, contact_id as libc::c_int); @@ -942,7 +930,7 @@ pub unsafe fn dc_delete_contact(context: &Context, contact_id: uint32_t) -> bool pub unsafe fn dc_get_contact(context: &Context, contact_id: uint32_t) -> *mut dc_contact_t { let mut ret: *mut dc_contact_t = dc_contact_new(context); - if !dc_contact_load_from_db(ret, &context.sql.clone().read().unwrap(), contact_id) { + if !dc_contact_load_from_db(ret, &context.sql, contact_id) { dc_contact_unref(ret); ret = 0 as *mut dc_contact_t } @@ -1089,7 +1077,7 @@ pub unsafe fn dc_contact_is_verified_ex<'a>( } else { let peerstate = Peerstate::from_addr( (*contact).context, - &(*contact).context.sql.clone().read().unwrap(), + &(*contact).context.sql, as_str((*contact).addr), ); @@ -1125,7 +1113,7 @@ pub unsafe fn dc_addr_equals_self(context: &Context, addr: *const libc::c_char) normalized_addr = dc_addr_normalize(addr); self_addr = dc_sqlite3_get_config( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"configured_addr\x00" as *const u8 as *const libc::c_char, 0 as *const libc::c_char, ); @@ -1150,7 +1138,7 @@ pub unsafe fn dc_addr_equals_contact( let mut addr_are_equal = false; if !addr.is_null() { let contact: *mut dc_contact_t = dc_contact_new(context); - if dc_contact_load_from_db(contact, &context.sql.clone().read().unwrap(), contact_id) { + if dc_contact_load_from_db(contact, &context.sql, contact_id) { if !(*contact).addr.is_null() { let normalized_addr: *mut libc::c_char = dc_addr_normalize(addr); if strcasecmp((*contact).addr, normalized_addr) == 0i32 { @@ -1168,10 +1156,10 @@ pub unsafe fn dc_addr_equals_contact( pub unsafe fn dc_get_real_contact_cnt(context: &Context) -> size_t { let mut ret: size_t = 0i32 as size_t; let mut stmt: *mut sqlite3_stmt = 0 as *mut sqlite3_stmt; - if !context.sql.clone().read().unwrap().cobj.is_null() { + if context.sql.is_open() { stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT COUNT(*) FROM contacts WHERE id>?;\x00" as *const u8 as *const libc::c_char, ); sqlite3_bind_int(stmt, 1i32, 9i32); @@ -1195,7 +1183,7 @@ pub unsafe fn dc_get_contact_origin( } let contact: *mut dc_contact_t = dc_contact_new(context); *ret_blocked = 0i32; - if dc_contact_load_from_db(contact, &context.sql.clone().read().unwrap(), contact_id) { + if dc_contact_load_from_db(contact, &context.sql, contact_id) { /* we could optimize this by loading only the needed fields */ if 0 != (*contact).blocked { *ret_blocked = 1i32 @@ -1210,10 +1198,10 @@ pub unsafe fn dc_get_contact_origin( pub unsafe fn dc_real_contact_exists(context: &Context, contact_id: uint32_t) -> bool { let mut stmt: *mut sqlite3_stmt = 0 as *mut sqlite3_stmt; let mut ret = false; - if !(context.sql.clone().read().unwrap().cobj.is_null() || contact_id <= 9i32 as libc::c_uint) { + if !(!context.sql.is_open() || contact_id <= 9i32 as libc::c_uint) { stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT id FROM contacts WHERE id=?;\x00" as *const u8 as *const libc::c_char, ); sqlite3_bind_int(stmt, 1i32, contact_id as libc::c_int); @@ -1232,7 +1220,7 @@ pub unsafe fn dc_scaleup_contact_origin( ) { let stmt: *mut sqlite3_stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"UPDATE contacts SET origin=? WHERE id=? AND origin 0 && !from.is_null() { - peerstate = - Peerstate::from_addr(context, &context.sql.clone().read().unwrap(), as_str(from)); + peerstate = Peerstate::from_addr(context, &context.sql, as_str(from)); if let Some(ref mut peerstate) = peerstate { if let Some(ref header) = autocryptheader { peerstate.apply_header(&header, message_time as u64); - peerstate.save_to_db(&context.sql.clone().read().unwrap(), false); + peerstate.save_to_db(&context.sql, false); } else if message_time as u64 > peerstate.last_seen_autocrypt && 0 == contains_report(in_out_message) { peerstate.degrade_encryption(message_time as u64); - peerstate.save_to_db(&context.sql.clone().read().unwrap(), false); + peerstate.save_to_db(&context.sql, false); } } else if let Some(ref header) = autocryptheader { let p = Peerstate::from_header(context, header, message_time as u64); - p.save_to_db(&context.sql.clone().read().unwrap(), true); + p.save_to_db(&context.sql, true); peerstate = Some(p); } } /* load private key for decryption */ self_addr = dc_sqlite3_get_config( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"configured_addr\x00" as *const u8 as *const libc::c_char, 0 as *const libc::c_char, ); if !self_addr.is_null() { - if private_keyring.load_self_private_for_decrypting( - context, - self_addr, - &context.sql.clone().read().unwrap(), - ) { + if private_keyring.load_self_private_for_decrypting(context, self_addr, &context.sql) { if peerstate.as_ref().map(|p| p.last_seen).unwrap_or_else(|| 0) == 0 { - peerstate = Peerstate::from_addr( - &context, - &context.sql.clone().read().unwrap(), - as_str(from), - ); + peerstate = Peerstate::from_addr(&context, &context.sql, as_str(from)); } if let Some(ref peerstate) = peerstate { if peerstate.degrade_event.is_some() { @@ -732,17 +719,14 @@ unsafe fn update_gossip_peerstates( recipients = Some(mailimf_get_recipients(imffields)); } if recipients.as_ref().unwrap().contains(&header.addr) { - let mut peerstate = Peerstate::from_addr( - context, - &context.sql.clone().read().unwrap(), - &header.addr, - ); + let mut peerstate = + Peerstate::from_addr(context, &context.sql, &header.addr); if let Some(ref mut peerstate) = peerstate { peerstate.apply_gossip(header, message_time as u64); - peerstate.save_to_db(&context.sql.clone().read().unwrap(), false); + peerstate.save_to_db(&context.sql, false); } else { let p = Peerstate::from_gossip(context, header, message_time as u64); - p.save_to_db(&context.sql.clone().read().unwrap(), true); + p.save_to_db(&context.sql, true); peerstate = Some(p); } if let Some(peerstate) = peerstate { @@ -1121,7 +1105,7 @@ pub unsafe fn dc_ensure_secret_key_exists(context: &Context) -> libc::c_int { let self_addr = dc_sqlite3_get_config( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"configured_addr\x00" as *const u8 as *const libc::c_char, 0 as *const libc::c_char, ); diff --git a/src/dc_imex.rs b/src/dc_imex.rs index bce1bdd41..30fee341f 100644 --- a/src/dc_imex.rs +++ b/src/dc_imex.rs @@ -42,74 +42,66 @@ pub unsafe fn dc_imex( dc_param_unref(param); } +/// Returns the filename of the backup if found, nullptr otherwise. pub unsafe fn dc_imex_has_backup( context: &Context, dir_name: *const libc::c_char, ) -> *mut libc::c_char { - let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; - let mut ret_backup_time = 0; - let mut curr_pathNfilename: *mut libc::c_char = 0 as *mut libc::c_char; - let mut test_sql: Option = None; - - let dir = std::path::Path::new(as_str(dir_name)); - - if dir.is_dir() { - match std::fs::read_dir(dir) { - Ok(dir_handle) => { - for entry in dir_handle { - if entry.is_err() { - continue; - } - let entry = entry.unwrap(); - let name_f = entry.file_name(); - let name = name_f.to_string_lossy(); - if name.starts_with("delta-chat") && name.ends_with(".bak") { - free(curr_pathNfilename as *mut libc::c_void); - curr_pathNfilename = dc_mprintf( - b"%s/%s\x00" as *const u8 as *const libc::c_char, - dir_name, - to_cstring(name).as_ptr(), - ); - if test_sql.is_some() { - let mut test_sql = test_sql.take().unwrap(); - dc_sqlite3_unref(context, &mut test_sql); + let dir_name = as_path(dir_name); + let dir_iter = std::fs::read_dir(dir_name); + if dir_iter.is_err() { + dc_log_info( + context, + 0i32, + b"Backup check: Cannot open directory \"%s\".\x00" as *const u8 as *const libc::c_char, + CString::new(format!("{}", dir_name.display())) + .unwrap() + .as_ptr(), + ); + return 0 as *mut libc::c_char; + } + let mut newest_backup_time = 0; + let mut newest_backup_path: Option = None; + for dirent in dir_iter.unwrap() { + match dirent { + Ok(dirent) => { + let path = dirent.path(); + let name = dirent.file_name(); + let name = name.to_string_lossy(); + if name.starts_with("delta-chat") && name.ends_with(".bak") { + let mut sql = SQLite::new(); + if sql.open(context, &path, 0x1i32) { + let curr_backup_time = dc_sqlite3_get_config_int( + context, + &mut sql, + b"backup_time\x00" as *const u8 as *const libc::c_char, + 0i32, + ) as u64; + if curr_backup_time > newest_backup_time { + newest_backup_path = Some(path); + newest_backup_time = curr_backup_time; } - let mut sql = dc_sqlite3_new(); - if 0 != dc_sqlite3_open(context, &mut sql, curr_pathNfilename, 0x1i32) { - let curr_backup_time = dc_sqlite3_get_config_int( - context, - &mut sql, - b"backup_time\x00" as *const u8 as *const libc::c_char, - 0, - ) as u64; - if curr_backup_time > 0 && curr_backup_time > ret_backup_time { - free(ret as *mut libc::c_void); - ret = curr_pathNfilename; - ret_backup_time = curr_backup_time; - curr_pathNfilename = 0 as *mut libc::c_char - } - } - test_sql = Some(sql); } } } - Err(_) => { - dc_log_info( - context, - 0i32, - b"Backup check: Cannot open directory \"%s\".\x00" as *const u8 - as *const libc::c_char, - dir_name, - ); - } + Err(_) => (), } } - - free(curr_pathNfilename as *mut libc::c_void); - if let Some(ref mut sql) = test_sql { - dc_sqlite3_unref(context, sql); + match newest_backup_path { + Some(path) => match path.to_c_string() { + Ok(cstr) => dc_strdup(cstr.as_ptr()), + Err(err) => { + dc_log_error( + context, + 0i32, + b"Invalid backup filename: %s\x00" as *const u8 as *const libc::c_char, + CString::new(format!("{}", err)).unwrap().as_ptr(), + ); + std::ptr::null_mut() + } + }, + None => std::ptr::null_mut(), } - ret } pub unsafe fn dc_initiate_key_transfer(context: &Context) -> *mut libc::c_char { @@ -255,15 +247,14 @@ pub unsafe extern "C" fn dc_render_setup_file( if !(0 == dc_ensure_secret_key_exists(context)) { self_addr = dc_sqlite3_get_config( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"configured_addr\x00" as *const u8 as *const libc::c_char, 0 as *const libc::c_char, ); - let curr_private_key = - Key::from_self_private(context, self_addr, &context.sql.clone().read().unwrap()); + let curr_private_key = Key::from_self_private(context, self_addr, &context.sql); let e2ee_enabled: libc::c_int = dc_sqlite3_get_config_int( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"e2ee_enabled\x00" as *const u8 as *const libc::c_char, 1i32, ); @@ -470,7 +461,7 @@ unsafe fn set_self_key( { stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"DELETE FROM keypairs WHERE public_key=? OR private_key=?;\x00" as *const u8 as *const libc::c_char, ); @@ -496,13 +487,13 @@ unsafe fn set_self_key( if 0 != set_default { dc_sqlite3_execute( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"UPDATE keypairs SET is_default=0;\x00" as *const u8 as *const libc::c_char, ); } self_addr = dc_sqlite3_get_config( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"configured_addr\x00" as *const u8 as *const libc::c_char, 0 as *const libc::c_char, ); @@ -512,7 +503,7 @@ unsafe fn set_self_key( &private_key, self_addr, set_default, - &context.sql.clone().read().unwrap(), + &context.sql, ) { dc_log_error( context, @@ -528,7 +519,7 @@ unsafe fn set_self_key( { dc_sqlite3_set_config_int( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"e2ee_enabled\x00" as *const u8 as *const libc::c_char, 0i32, ); @@ -539,7 +530,7 @@ unsafe fn set_self_key( { dc_sqlite3_set_config_int( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"e2ee_enabled\x00" as *const u8 as *const libc::c_char, 1i32, ); @@ -679,7 +670,7 @@ pub unsafe fn dc_job_do_DC_JOB_IMEX_IMAP(context: &Context, job: *mut dc_job_t) b"Import/export process started.\x00" as *const u8 as *const libc::c_char, ); context.call_cb(Event::IMEX_PROGRESS, 10i32 as uintptr_t, 0i32 as uintptr_t); - if 0 == dc_sqlite3_is_open(&context.sql.clone().read().unwrap()) { + if !context.sql.is_open() { dc_log_error( context, 0i32, @@ -931,9 +922,7 @@ unsafe fn import_backup(context: &Context, backup_to_import: *const libc::c_char b"Cannot import backups to accounts in use.\x00" as *const u8 as *const libc::c_char, ); } else { - if 0 != dc_sqlite3_is_open(&context.sql.clone().read().unwrap()) { - dc_sqlite3_close(context, &mut context.sql.clone().write().unwrap()); - } + &context.sql.close(&context); dc_delete_file(context, context.get_dbfile()); if 0 != dc_file_exist(context, context.get_dbfile()) { dc_log_error( @@ -945,17 +934,10 @@ unsafe fn import_backup(context: &Context, backup_to_import: *const libc::c_char } else if !(0 == dc_copy_file(context, backup_to_import, context.get_dbfile())) { /* error already logged */ /* re-open copied database file */ - if !(0 - == dc_sqlite3_open( - context, - &mut context.sql.clone().write().unwrap(), - context.get_dbfile(), - 0i32, - )) - { + if context.sql.open(&context, as_path(context.get_dbfile()), 0) { stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT COUNT(*) FROM backup_blobs;\x00" as *const u8 as *const libc::c_char, ); sqlite3_step(stmt); @@ -963,7 +945,7 @@ unsafe fn import_backup(context: &Context, backup_to_import: *const libc::c_char sqlite3_finalize(stmt); stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT file_name, file_content FROM backup_blobs ORDER BY id;\x00" as *const u8 as *const libc::c_char, ); @@ -1037,12 +1019,12 @@ unsafe fn import_backup(context: &Context, backup_to_import: *const libc::c_char stmt = 0 as *mut sqlite3_stmt; dc_sqlite3_execute( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"DROP TABLE backup_blobs;\x00" as *const u8 as *const libc::c_char, ); dc_sqlite3_try_execute( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"VACUUM;\x00" as *const u8 as *const libc::c_char, ); success = 1i32 @@ -1075,7 +1057,7 @@ unsafe fn export_backup(context: &Context, dir: *const libc::c_char) -> libc::c_ let mut buf_bytes: size_t = 0i32 as size_t; let mut stmt: *mut sqlite3_stmt = 0 as *mut sqlite3_stmt; let mut delete_dest_file: libc::c_int = 0i32; - let mut dest_sql: Option = None; + let mut dest_sql: Option = None; // get a fine backup file name (the name includes the date so that multiple backup instances are possible) // FIXME: we should write to a temporary file first and rename it on success. this would guarantee the backup is complete. however, currently it is not clear it the import exists in the long run (may be replaced by a restore-from-imap) let now = time(); @@ -1097,10 +1079,10 @@ unsafe fn export_backup(context: &Context, dir: *const libc::c_char) -> libc::c_ dc_housekeeping(context); dc_sqlite3_try_execute( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"VACUUM;\x00" as *const u8 as *const libc::c_char, ); - dc_sqlite3_close(context, &mut context.sql.clone().write().unwrap()); + context.sql.close(&context); closed = 1i32; dc_log_info( context, @@ -1110,26 +1092,19 @@ unsafe fn export_backup(context: &Context, dir: *const libc::c_char) -> libc::c_ dest_pathNfilename, ); if !(0 == dc_copy_file(context, context.get_dbfile(), dest_pathNfilename)) { - /* error already logged */ - dc_sqlite3_open( - context, - &mut context.sql.clone().write().unwrap(), - context.get_dbfile(), - 0i32, - ); + context.sql.open(&context, as_path(context.get_dbfile()), 0); closed = 0i32; /* add all files as blobs to the database copy (this does not require the source to be locked, neigher the destination as it is used only here) */ /*for logging only*/ - let mut sql = dc_sqlite3_new(); - if 0 != dc_sqlite3_open(context, &mut sql, dest_pathNfilename, 0i32) { - /* error already logged */ + let sql = SQLite::new(); + if sql.open(context, as_path(dest_pathNfilename), 0) { if 0 == dc_sqlite3_table_exists( context, - &mut sql, + &sql, b"backup_blobs\x00" as *const u8 as *const libc::c_char, ) { if 0 == - dc_sqlite3_execute(context, &mut sql, + dc_sqlite3_execute(context, &sql, b"CREATE TABLE backup_blobs (id INTEGER PRIMARY KEY, file_name, file_content);\x00" as *const u8 as *const libc::c_char) { @@ -1173,7 +1148,7 @@ unsafe fn export_backup(context: &Context, dir: *const libc::c_char) -> libc::c_ let dir_handle = dir_handle.unwrap(); stmt = dc_sqlite3_prepare( context, - &mut sql, + &sql, b"INSERT INTO backup_blobs (file_name, file_content) VALUES (?, ?);\x00" as *const u8 as *const libc::c_char @@ -1282,7 +1257,7 @@ unsafe fn export_backup(context: &Context, dir: *const libc::c_char) -> libc::c_ _ => { dc_sqlite3_set_config_int( context, - &mut sql, + &sql, b"backup_time\x00" as *const u8 as *const libc::c_char, now as int32_t, ); @@ -1301,17 +1276,11 @@ unsafe fn export_backup(context: &Context, dir: *const libc::c_char) -> libc::c_ dest_sql = Some(sql); } if 0 != closed { - dc_sqlite3_open( - context, - &mut context.sql.clone().write().unwrap(), - context.get_dbfile(), - 0i32, - ); + context.sql.open(&context, as_path(context.get_dbfile()), 0); } sqlite3_finalize(stmt); - if let Some(ref mut sql) = dest_sql { - dc_sqlite3_close(context, sql); - dc_sqlite3_unref(context, sql); + if let Some(sql) = dest_sql.take() { + sql.close(&context); } if 0 != delete_dest_file { dc_delete_file(context, dest_pathNfilename); @@ -1464,7 +1433,7 @@ unsafe fn export_self_keys(context: &Context, dir: *const libc::c_char) -> libc: let mut is_default: libc::c_int; let stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT id, public_key, private_key, is_default FROM keypairs;\x00" as *const u8 as *const libc::c_char, ); diff --git a/src/dc_job.rs b/src/dc_job.rs index 2d711310f..18dbfd395 100644 --- a/src/dc_job.rs +++ b/src/dc_job.rs @@ -85,7 +85,7 @@ unsafe fn dc_job_perform(context: &Context, thread: libc::c_int, probe_network: select_stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT id, action, foreign_id, param, added_timestamp, desired_timestamp, tries FROM jobs WHERE thread=? AND desired_timestamp<=? ORDER BY action DESC, added_timestamp;\x00" as *const u8 as *const libc::c_char); sqlite3_bind_int64(select_stmt, 1i32, thread as sqlite3_int64); @@ -94,7 +94,7 @@ unsafe fn dc_job_perform(context: &Context, thread: libc::c_int, probe_network: select_stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT id, action, foreign_id, param, added_timestamp, desired_timestamp, tries FROM jobs WHERE thread=? AND tries>0 ORDER BY desired_timestamp, action DESC;\x00" as *const u8 as *const libc::c_char); sqlite3_bind_int64(select_stmt, 1i32, thread as sqlite3_int64); @@ -255,7 +255,7 @@ unsafe fn dc_job_perform(context: &Context, thread: libc::c_int, probe_network: unsafe fn dc_job_delete(context: &Context, job: &dc_job_t) { let delete_stmt: *mut sqlite3_stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"DELETE FROM jobs WHERE id=?;\x00" as *const u8 as *const libc::c_char, ); sqlite3_bind_int(delete_stmt, 1i32, job.job_id as libc::c_int); @@ -282,7 +282,7 @@ unsafe fn get_backoff_time_offset(c_tries: libc::c_int) -> i64 { unsafe fn dc_job_update(context: &Context, job: &dc_job_t) { let stmt: *mut sqlite3_stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"UPDATE jobs SET desired_timestamp=?, tries=?, param=? WHERE id=?;\x00" as *const u8 as *const libc::c_char, ); @@ -317,7 +317,7 @@ unsafe fn dc_job_do_DC_JOB_SEND(context: &Context, job: &mut dc_job_t) { dc_loginparam_read( context, loginparam, - &context.sql.clone().read().unwrap(), + &context.sql, b"configured_\x00" as *const u8 as *const libc::c_char, ); let connected = context.smtp.lock().unwrap().connect(context, loginparam); @@ -406,7 +406,7 @@ unsafe fn dc_job_do_DC_JOB_SEND(context: &Context, job: &mut dc_job_t) { dc_update_msg_state(context, job.foreign_id, 26i32); stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT chat_id FROM msgs WHERE id=?\x00" as *const u8 as *const libc::c_char, ); @@ -470,7 +470,7 @@ unsafe fn dc_job_do_DC_JOB_MOVE_MSG(context: &Context, job: &mut dc_job_t) { if dc_msg_load_from_db(msg, context, job.foreign_id) { if dc_sqlite3_get_config_int( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"folders_configured\x00" as *const u8 as *const libc::c_char, 0i32, ) < 3i32 @@ -479,7 +479,7 @@ unsafe fn dc_job_do_DC_JOB_MOVE_MSG(context: &Context, job: &mut dc_job_t) { } dest_folder = dc_sqlite3_get_config( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"configured_mvbox_folder\x00" as *const u8 as *const libc::c_char, 0 as *const libc::c_char, ); @@ -578,7 +578,7 @@ unsafe fn dc_job_do_DC_JOB_MARKSEEN_MDN_ON_IMAP(context: &Context, job: &mut dc_ if 0 != dc_param_get_int(job.param, 'M' as i32, 0i32) { if dc_sqlite3_get_config_int( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"folders_configured\x00" as *const u8 as *const libc::c_char, 0i32, ) < 3i32 @@ -587,7 +587,7 @@ unsafe fn dc_job_do_DC_JOB_MARKSEEN_MDN_ON_IMAP(context: &Context, job: &mut dc_ } dest_folder = dc_sqlite3_get_config( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"configured_mvbox_folder\x00" as *const u8 as *const libc::c_char, 0 as *const libc::c_char, ); @@ -638,7 +638,7 @@ unsafe fn dc_job_do_DC_JOB_MARKSEEN_MSG_ON_IMAP(context: &Context, job: &mut dc_ if 0 != dc_param_get_int((*msg).param, 'r' as i32, 0i32) && 0 != dc_sqlite3_get_config_int( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"mdns_enabled\x00" as *const u8 as *const libc::c_char, 1i32, ) @@ -694,7 +694,7 @@ unsafe fn dc_job_do_DC_JOB_MARKSEEN_MSG_ON_IMAP(context: &Context, job: &mut dc_ if 0 != dc_param_get_int((*msg).param, 'r' as i32, 0i32) && 0 != dc_sqlite3_get_config_int( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"mdns_enabled\x00" as *const u8 as *const libc::c_char, 1i32, ) @@ -874,7 +874,7 @@ pub unsafe fn dc_job_add( stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"INSERT INTO jobs (added_timestamp, thread, action, foreign_id, param, desired_timestamp) VALUES (?,?,?,?,?,?);\x00" as *const u8 as *const libc::c_char); sqlite3_bind_int64(stmt, 1i32, timestamp as sqlite3_int64); @@ -994,7 +994,7 @@ unsafe fn dc_job_do_DC_JOB_DELETE_MSG_ON_IMAP(context: &Context, job: &mut dc_jo pub unsafe fn dc_job_kill_action(context: &Context, action: libc::c_int) { let stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"DELETE FROM jobs WHERE action=?;\x00" as *const u8 as *const libc::c_char, ); sqlite3_bind_int(stmt, 1i32, action); @@ -1011,7 +1011,7 @@ pub unsafe fn dc_perform_imap_fetch(context: &Context) { } if dc_sqlite3_get_config_int( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"inbox_watch\x00" as *const u8 as *const libc::c_char, 1i32, ) == 0i32 @@ -1065,7 +1065,7 @@ pub fn dc_perform_imap_idle(context: &Context) { pub unsafe fn dc_perform_mvbox_fetch(context: &Context) { let use_network: libc::c_int = dc_sqlite3_get_config_int( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"mvbox_watch\x00" as *const u8 as *const libc::c_char, 1i32, ); @@ -1079,7 +1079,7 @@ pub unsafe fn dc_perform_mvbox_fetch(context: &Context) { pub unsafe fn dc_perform_mvbox_idle(context: &Context) { let use_network: libc::c_int = dc_sqlite3_get_config_int( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"mvbox_watch\x00" as *const u8 as *const libc::c_char, 1i32, ); @@ -1097,7 +1097,7 @@ pub unsafe fn dc_interrupt_mvbox_idle(context: &Context) { pub unsafe fn dc_perform_sentbox_fetch(context: &Context) { let use_network: libc::c_int = dc_sqlite3_get_config_int( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"sentbox_watch\x00" as *const u8 as *const libc::c_char, 1i32, ); @@ -1111,7 +1111,7 @@ pub unsafe fn dc_perform_sentbox_fetch(context: &Context) { pub unsafe fn dc_perform_sentbox_idle(context: &Context) { let use_network: libc::c_int = dc_sqlite3_get_config_int( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"sentbox_watch\x00" as *const u8 as *const libc::c_char, 1i32, ); @@ -1210,7 +1210,7 @@ pub unsafe fn dc_perform_smtp_idle(context: &Context) { unsafe fn get_next_wakeup_time(context: &Context, thread: libc::c_int) -> Duration { let stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT MIN(desired_timestamp) FROM jobs WHERE thread=?;\x00" as *const u8 as *const libc::c_char, ); @@ -1254,7 +1254,7 @@ pub unsafe fn dc_job_action_exists(context: &Context, action: libc::c_int) -> li let stmt; stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT id FROM jobs WHERE action=?;\x00" as *const u8 as *const libc::c_char, ); sqlite3_bind_int(stmt, 1i32, action); diff --git a/src/dc_jobthread.rs b/src/dc_jobthread.rs index 933ad38a8..76712110b 100644 --- a/src/dc_jobthread.rs +++ b/src/dc_jobthread.rs @@ -173,7 +173,7 @@ unsafe fn connect_to_imap(context: &Context, jobthread: &dc_jobthread_t) -> libc if !(0 == ret_connected) { if dc_sqlite3_get_config_int( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"folders_configured\x00" as *const u8 as *const libc::c_char, 0, ) < 3 @@ -182,7 +182,7 @@ unsafe fn connect_to_imap(context: &Context, jobthread: &dc_jobthread_t) -> libc } mvbox_name = dc_sqlite3_get_config( context, - &context.sql.clone().read().unwrap(), + &context.sql, jobthread.folder_config_name, 0 as *const libc::c_char, ); diff --git a/src/dc_location.rs b/src/dc_location.rs index cab9ed3f7..6d1082713 100644 --- a/src/dc_location.rs +++ b/src/dc_location.rs @@ -53,7 +53,7 @@ pub unsafe fn dc_send_locations_to_chat( stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"UPDATE chats SET locations_send_begin=?, locations_send_until=? WHERE id=?\x00" as *const u8 as *const libc::c_char); sqlite3_bind_int64( @@ -129,7 +129,7 @@ pub unsafe fn dc_is_sending_locations_to_chat(context: &Context, chat_id: uint32 stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT id FROM chats WHERE (? OR id=?) AND locations_send_until>?;\x00" as *const u8 as *const libc::c_char, ); @@ -167,7 +167,7 @@ pub unsafe fn dc_set_location( } else { stmt_chats = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT id FROM chats WHERE locations_send_until>?;\x00" as *const u8 as *const libc::c_char, ); @@ -177,7 +177,7 @@ pub unsafe fn dc_set_location( stmt_insert = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"INSERT INTO locations (latitude, longitude, accuracy, timestamp, chat_id, from_id) VALUES (?,?,?,?,?,?);\x00" as *const u8 as *const libc::c_char); sqlite3_bind_double(stmt_insert, 1i32, latitude); @@ -219,7 +219,7 @@ pub unsafe fn dc_get_locations( } stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT l.id, l.latitude, l.longitude, l.accuracy, l.timestamp, l.independent, \ m.id, l.from_id, l.chat_id, m.txt \ FROM locations l LEFT JOIN msgs m ON l.id=m.location_id WHERE (? OR l.chat_id=?) \ @@ -297,7 +297,7 @@ pub unsafe fn dc_delete_all_locations(context: &Context) { stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"DELETE FROM locations;\x00" as *const u8 as *const libc::c_char, ); sqlite3_step(stmt); @@ -327,14 +327,14 @@ pub unsafe fn dc_get_location_kml( self_addr = dc_sqlite3_get_config( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"configured_addr\x00" as *const u8 as *const libc::c_char, b"\x00" as *const u8 as *const libc::c_char, ); stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT locations_send_begin, locations_send_until, locations_last_sent FROM chats WHERE id=?;\x00" as *const u8 as *const libc::c_char); sqlite3_bind_int(stmt, 1i32, chat_id as libc::c_int); @@ -352,7 +352,7 @@ pub unsafe fn dc_get_location_kml( ); stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT id, latitude, longitude, accuracy, timestamp\ FROM locations WHERE from_id=? \ AND timestamp>=? \ @@ -448,7 +448,7 @@ pub unsafe fn dc_get_message_kml( pub unsafe fn dc_set_kml_sent_timestamp(context: &Context, chat_id: uint32_t, timestamp: i64) { let stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"UPDATE chats SET locations_last_sent=? WHERE id=?;\x00" as *const u8 as *const libc::c_char, ); @@ -462,7 +462,7 @@ pub unsafe fn dc_set_msg_location_id(context: &Context, msg_id: uint32_t, locati let stmt: *mut sqlite3_stmt; stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"UPDATE msgs SET location_id=? WHERE id=?;\x00" as *const u8 as *const libc::c_char, ); sqlite3_bind_int64(stmt, 1i32, location_id as sqlite3_int64); @@ -485,13 +485,13 @@ pub unsafe fn dc_save_locations( if !(chat_id <= 9i32 as libc::c_uint || locations.is_null()) { stmt_test = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT id FROM locations WHERE timestamp=? AND from_id=?\x00" as *const u8 as *const libc::c_char, ); stmt_insert = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"INSERT INTO locations\ (timestamp, from_id, chat_id, latitude, longitude, accuracy, independent) \ VALUES (?,?,?,?,?,?,?);\x00" as *const u8 as *const libc::c_char, @@ -518,7 +518,7 @@ pub unsafe fn dc_save_locations( newest_timestamp = (*location).timestamp; newest_location_id = dc_sqlite3_get_rowid2( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"locations\x00" as *const u8 as *const libc::c_char, b"timestamp\x00" as *const u8 as *const libc::c_char, (*location).timestamp as uint64_t, @@ -718,7 +718,7 @@ pub unsafe fn dc_job_do_DC_JOB_MAYBE_SEND_LOCATIONS(context: &Context, _job: *mu ); stmt_chats = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT id, locations_send_begin, locations_last_sent \ FROM chats \ WHERE locations_send_until>?;\x00" as *const u8 as *const libc::c_char, @@ -736,7 +736,7 @@ pub unsafe fn dc_job_do_DC_JOB_MAYBE_SEND_LOCATIONS(context: &Context, _job: *mu if stmt_locations.is_null() { stmt_locations = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT id \ FROM locations \ WHERE from_id=? \ @@ -789,7 +789,7 @@ pub unsafe fn dc_job_do_DC_JOB_MAYBE_SEND_LOC_ENDED(context: &Context, job: &mut let mut stock_str: *mut libc::c_char = 0 as *mut libc::c_char; stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT locations_send_begin, locations_send_until FROM chats WHERE id=?\x00" as *const u8 as *const libc::c_char, ); @@ -808,7 +808,7 @@ pub unsafe fn dc_job_do_DC_JOB_MAYBE_SEND_LOC_ENDED(context: &Context, job: &mut stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"UPDATE chats SET locations_send_begin=0, locations_send_until=0 WHERE id=?\x00" as *const u8 as *const libc::c_char); diff --git a/src/dc_loginparam.rs b/src/dc_loginparam.rs index 2e41981c5..11d29f784 100644 --- a/src/dc_loginparam.rs +++ b/src/dc_loginparam.rs @@ -62,7 +62,7 @@ pub unsafe fn dc_loginparam_empty(mut loginparam: *mut dc_loginparam_t) { pub unsafe fn dc_loginparam_read( context: &Context, loginparam: *mut dc_loginparam_t, - sql: &dc_sqlite3_t, + sql: &SQLite, prefix: *const libc::c_char, ) { let mut key: *mut libc::c_char = 0 as *mut libc::c_char; @@ -143,7 +143,7 @@ pub unsafe fn dc_loginparam_read( pub unsafe fn dc_loginparam_write( context: &Context, loginparam: *const dc_loginparam_t, - sql: &dc_sqlite3_t, + sql: &SQLite, prefix: *const libc::c_char, ) { let mut key: *mut libc::c_char = 0 as *mut libc::c_char; diff --git a/src/dc_mimefactory.rs b/src/dc_mimefactory.rs index c5cbe070e..a3e09fef0 100644 --- a/src/dc_mimefactory.rs +++ b/src/dc_mimefactory.rs @@ -140,7 +140,7 @@ pub unsafe fn dc_mimefactory_load_msg( stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT c.authname, c.addr FROM chats_contacts cc LEFT JOIN contacts c ON cc.contact_id=c.id WHERE cc.chat_id=? AND cc.contact_id>9;\x00" as *const u8 as *const libc::c_char); @@ -179,7 +179,7 @@ pub unsafe fn dc_mimefactory_load_msg( ); let self_addr: *mut libc::c_char = dc_sqlite3_get_config( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"configured_addr\x00" as *const u8 as *const libc::c_char, b"\x00" as *const u8 as *const libc::c_char, ); @@ -206,7 +206,7 @@ pub unsafe fn dc_mimefactory_load_msg( && command != 7i32 && 0 != dc_sqlite3_get_config_int( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"mdns_enabled\x00" as *const u8 as *const libc::c_char, 1i32, ) @@ -216,7 +216,7 @@ pub unsafe fn dc_mimefactory_load_msg( } stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT mime_in_reply_to, mime_references FROM msgs WHERE id=?\x00" as *const u8 as *const libc::c_char, ); @@ -245,19 +245,19 @@ pub unsafe fn dc_mimefactory_load_msg( unsafe fn load_from(mut factory: *mut dc_mimefactory_t) { (*factory).from_addr = dc_sqlite3_get_config( (*factory).context, - &mut (*factory).context.sql.clone().read().unwrap(), + &(*factory).context.sql, b"configured_addr\x00" as *const u8 as *const libc::c_char, 0 as *const libc::c_char, ); (*factory).from_displayname = dc_sqlite3_get_config( (*factory).context, - &mut (*factory).context.sql.clone().read().unwrap(), + &(*factory).context.sql, b"displayname\x00" as *const u8 as *const libc::c_char, 0 as *const libc::c_char, ); (*factory).selfstatus = dc_sqlite3_get_config( (*factory).context, - &mut (*factory).context.sql.clone().read().unwrap(), + &(*factory).context.sql, b"selfstatus\x00" as *const u8 as *const libc::c_char, 0 as *const libc::c_char, ); @@ -279,7 +279,7 @@ pub unsafe fn dc_mimefactory_load_mdn( if !(0 == dc_sqlite3_get_config_int( (*factory).context, - &mut (*factory).context.sql.clone().read().unwrap(), + &(*factory).context.sql, b"mdns_enabled\x00" as *const u8 as *const libc::c_char, 1i32, )) @@ -289,7 +289,7 @@ pub unsafe fn dc_mimefactory_load_mdn( if !(!dc_msg_load_from_db((*factory).msg, (*factory).context, msg_id) || !dc_contact_load_from_db( contact, - &mut (*factory).context.sql.clone().read().unwrap(), + &(*factory).context.sql, (*(*factory).msg).from_id, )) { diff --git a/src/dc_move.rs b/src/dc_move.rs index 547ad9611..c48008899 100644 --- a/src/dc_move.rs +++ b/src/dc_move.rs @@ -15,7 +15,7 @@ pub unsafe fn dc_do_heuristics_moves( let stmt: *mut sqlite3_stmt = 0 as *mut sqlite3_stmt; if !(dc_sqlite3_get_config_int( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"mvbox_move\x00" as *const u8 as *const libc::c_char, 1i32, ) == 0i32) diff --git a/src/dc_msg.rs b/src/dc_msg.rs index 33c499ede..4a0a00f65 100644 --- a/src/dc_msg.rs +++ b/src/dc_msg.rs @@ -57,14 +57,10 @@ pub unsafe fn dc_get_msg_info(context: &Context, msg_id: uint32_t) -> *mut libc: let mut ret = String::new(); dc_msg_load_from_db(msg, context, msg_id); - dc_contact_load_from_db( - contact_from, - &context.sql.clone().read().unwrap(), - (*msg).from_id, - ); + dc_contact_load_from_db(contact_from, &context.sql, (*msg).from_id); stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT txt_raw FROM msgs WHERE id=?;\x00" as *const u8 as *const libc::c_char, ); sqlite3_bind_int(stmt, 1, msg_id as libc::c_int); @@ -99,7 +95,7 @@ pub unsafe fn dc_get_msg_info(context: &Context, msg_id: uint32_t) -> *mut libc: // device-internal message, no further details needed stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT contact_id, timestamp_sent FROM msgs_mdns WHERE msg_id=?;\x00" as *const u8 as *const libc::c_char, ); @@ -111,7 +107,7 @@ pub unsafe fn dc_get_msg_info(context: &Context, msg_id: uint32_t) -> *mut libc: let contact = dc_contact_new(context); dc_contact_load_from_db( contact, - &context.sql.clone().read().unwrap(), + &context.sql, sqlite3_column_int64(stmt, 0) as uint32_t, ); p = dc_contact_get_name_n_addr(contact); @@ -444,7 +440,7 @@ pub unsafe fn dc_msg_load_from_db<'a>( stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT m.id,rfc724_mid,m.mime_in_reply_to,m.server_folder,m.server_uid,m.move_state,m.chat_id, m.from_id,m.to_id,m.timestamp,m.timestamp_sent,m.timestamp_rcvd, m.type,m.state,m.msgrmsg,m.txt, m.param,m.starred,m.hidden,m.location_id, c.blocked FROM msgs m LEFT JOIN chats c ON c.id=m.chat_id WHERE m.id=?;\x00" as *const u8 as *const libc::c_char); sqlite3_bind_int(stmt, 1i32, id as libc::c_int); @@ -546,7 +542,7 @@ pub unsafe fn dc_get_mime_headers(context: &Context, msg_id: uint32_t) -> *mut l stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT mime_headers FROM msgs WHERE id=?;\x00" as *const u8 as *const libc::c_char, ); sqlite3_bind_int(stmt, 1i32, msg_id as libc::c_int); @@ -586,7 +582,7 @@ pub unsafe fn dc_delete_msgs(context: &Context, msg_ids: *const uint32_t, msg_cn pub unsafe fn dc_update_msg_chat_id(context: &Context, msg_id: uint32_t, chat_id: uint32_t) { let stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"UPDATE msgs SET chat_id=? WHERE id=?;\x00" as *const u8 as *const libc::c_char, ); sqlite3_bind_int(stmt, 1i32, chat_id as libc::c_int); @@ -603,7 +599,7 @@ pub unsafe fn dc_markseen_msgs(context: &Context, msg_ids: *const uint32_t, msg_ let mut stmt = 0 as *mut sqlite3_stmt; if !(msg_ids.is_null() || msg_cnt <= 0i32) { stmt = - dc_sqlite3_prepare(context, &context.sql.clone().read().unwrap(), + dc_sqlite3_prepare(context, &context.sql, b"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\x00" as *const u8 as *const libc::c_char); i = 0i32; @@ -649,7 +645,7 @@ pub unsafe fn dc_markseen_msgs(context: &Context, msg_ids: *const uint32_t, msg_ pub unsafe fn dc_update_msg_state(context: &Context, msg_id: uint32_t, state: libc::c_int) { let stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"UPDATE msgs SET state=? WHERE id=?;\x00" as *const u8 as *const libc::c_char, ); sqlite3_bind_int(stmt, 1i32, state); @@ -669,7 +665,7 @@ pub unsafe fn dc_star_msgs( } let stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"UPDATE msgs SET starred=? WHERE id=?;\x00" as *const u8 as *const libc::c_char, ); let mut i: libc::c_int = 0i32; @@ -1163,7 +1159,7 @@ pub unsafe fn dc_msg_save_param_to_disk(msg: *mut dc_msg_t) { } let stmt: *mut sqlite3_stmt = dc_sqlite3_prepare( (*msg).context, - &mut (*msg).context.sql.clone().read().unwrap(), + &(*msg).context.sql, b"UPDATE msgs SET param=? WHERE id=?;\x00" as *const u8 as *const libc::c_char, ); sqlite3_bind_text(stmt, 1i32, (*(*msg).param).packed, -1i32, None); @@ -1184,7 +1180,7 @@ pub unsafe fn dc_delete_msg_from_db(context: &Context, msg_id: uint32_t) { if dc_msg_load_from_db(msg, context, msg_id) { stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"DELETE FROM msgs WHERE id=?;\x00" as *const u8 as *const libc::c_char, ); sqlite3_bind_int(stmt, 1i32, (*msg).id as libc::c_int); @@ -1192,7 +1188,7 @@ pub unsafe fn dc_delete_msg_from_db(context: &Context, msg_id: uint32_t) { sqlite3_finalize(stmt); stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"DELETE FROM msgs_mdns WHERE msg_id=?;\x00" as *const u8 as *const libc::c_char, ); sqlite3_bind_int(stmt, 1i32, (*msg).id as libc::c_int); @@ -1218,7 +1214,7 @@ pub unsafe fn dc_msg_exists(context: &Context, msg_id: uint32_t) -> libc::c_int if msg_id > 9 { stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT chat_id FROM msgs WHERE id=?;\x00" as *const u8 as *const libc::c_char, ); sqlite3_bind_int(stmt, 1i32, msg_id as libc::c_int); @@ -1244,7 +1240,7 @@ pub unsafe fn dc_update_msg_move_state( // so that the state stay intact when parts are deleted let stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"UPDATE msgs SET move_state=? WHERE rfc724_mid=?;\x00" as *const u8 as *const libc::c_char, ); sqlite3_bind_int(stmt, 1i32, state as libc::c_int); @@ -1271,7 +1267,7 @@ pub unsafe fn dc_set_msg_failed(context: &Context, msg_id: uint32_t, error: *con } stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"UPDATE msgs SET state=?, param=? WHERE id=?;\x00" as *const u8 as *const libc::c_char, ); sqlite3_bind_int(stmt, 1i32, (*msg).state); @@ -1314,7 +1310,7 @@ pub unsafe fn dc_mdn_from_ext( stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT m.id, c.id, c.type, m.state FROM msgs m LEFT JOIN chats c ON m.chat_id=c.id WHERE rfc724_mid=? AND from_id=1 ORDER BY m.id;\x00" as *const u8 as *const libc::c_char ); @@ -1330,7 +1326,7 @@ pub unsafe fn dc_mdn_from_ext( /* eg. already marked as MDNS_RCVD. however, it is importent, that the message ID is set above as this will allow the caller eg. to move the message away */ stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT contact_id FROM msgs_mdns WHERE msg_id=? AND contact_id=?;\x00" as *const u8 as *const libc::c_char, ); @@ -1347,7 +1343,7 @@ pub unsafe fn dc_mdn_from_ext( stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"INSERT INTO msgs_mdns (msg_id, contact_id, timestamp_sent) VALUES (?, ?, ?);\x00" as *const u8 as *const libc::c_char); @@ -1366,7 +1362,7 @@ pub unsafe fn dc_mdn_from_ext( /* send event about new state */ stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT COUNT(*) FROM msgs_mdns WHERE msg_id=?;\x00" as *const u8 as *const libc::c_char, ); @@ -1409,17 +1405,17 @@ pub unsafe fn dc_mdn_from_ext( pub unsafe fn dc_get_real_msg_cnt(context: &Context) -> size_t { let mut stmt: *mut sqlite3_stmt = 0 as *mut sqlite3_stmt; let mut ret: size_t = 0i32 as size_t; - if !(*&context.sql.clone().read().unwrap()).cobj.is_null() { + if (*&context.sql).is_open() { stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT COUNT(*) FROM msgs m LEFT JOIN chats c ON c.id=m.chat_id WHERE m.id>9 AND m.chat_id>9 AND c.blocked=0;\x00" as *const u8 as *const libc::c_char); if sqlite3_step(stmt) != 100i32 { dc_sqlite3_log_error( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"dc_get_real_msg_cnt() failed.\x00" as *const u8 as *const libc::c_char, ); } else { @@ -1434,9 +1430,9 @@ pub unsafe fn dc_get_real_msg_cnt(context: &Context) -> size_t { pub unsafe fn dc_get_deaddrop_msg_cnt(context: &Context) -> size_t { let mut stmt: *mut sqlite3_stmt = 0 as *mut sqlite3_stmt; let mut ret: size_t = 0i32 as size_t; - if !context.sql.clone().read().unwrap().cobj.is_null() { + if context.sql.is_open() { stmt = - dc_sqlite3_prepare(context, &context.sql.clone().read().unwrap(), + dc_sqlite3_prepare(context, &context.sql, b"SELECT COUNT(*) FROM msgs m LEFT JOIN chats c ON c.id=m.chat_id WHERE c.blocked=2;\x00" as *const u8 as *const libc::c_char); if !(sqlite3_step(stmt) != 100i32) { @@ -1452,10 +1448,10 @@ pub unsafe fn dc_rfc724_mid_cnt(context: &Context, rfc724_mid: *const libc::c_ch /* check the number of messages with the same rfc724_mid */ let mut ret: libc::c_int = 0i32; let mut stmt = 0 as *mut sqlite3_stmt; - if !context.sql.clone().read().unwrap().cobj.is_null() { + if context.sql.is_open() { stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT COUNT(*) FROM msgs WHERE rfc724_mid=?;\x00" as *const u8 as *const libc::c_char, ); @@ -1480,7 +1476,7 @@ pub unsafe fn dc_rfc724_mid_exists( if !(rfc724_mid.is_null() || *rfc724_mid.offset(0isize) as libc::c_int == 0i32) { stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT server_folder, server_uid, id FROM msgs WHERE rfc724_mid=?;\x00" as *const u8 as *const libc::c_char, ); @@ -1515,7 +1511,7 @@ pub unsafe fn dc_update_server_uid( ) { let stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"UPDATE msgs SET server_folder=?, server_uid=? WHERE rfc724_mid=?;\x00" as *const u8 as *const libc::c_char, ); diff --git a/src/dc_qr.rs b/src/dc_qr.rs index 14f3337c0..0aafdae72 100644 --- a/src/dc_qr.rs +++ b/src/dc_qr.rs @@ -239,7 +239,7 @@ pub unsafe fn dc_check_qr(context: &Context, qr: *const libc::c_char) -> *mut dc if !fingerprint.is_null() { let peerstate = Peerstate::from_fingerprint( context, - &context.sql.clone().read().unwrap(), + &context.sql, as_str(fingerprint), ); if addr.is_null() || invitenumber.is_null() || auth.is_null() { diff --git a/src/dc_receive_imf.rs b/src/dc_receive_imf.rs index 2e99194d2..0f4aab40c 100644 --- a/src/dc_receive_imf.rs +++ b/src/dc_receive_imf.rs @@ -250,7 +250,7 @@ pub unsafe fn dc_receive_imf( if msgrmsg == 0i32 { let show_emails: libc::c_int = dc_sqlite3_get_config_int( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"show_emails\x00" as *const u8 as *const libc::c_char, 0i32, ); @@ -454,7 +454,7 @@ pub unsafe fn dc_receive_imf( // (the mime-header ends with an empty line) let save_mime_headers: libc::c_int = dc_sqlite3_get_config_int( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"save_mime_headers\x00" as *const u8 as *const libc::c_char, 0i32, ); @@ -517,7 +517,7 @@ pub unsafe fn dc_receive_imf( stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"INSERT INTO msgs (rfc724_mid, server_folder, server_uid, chat_id, from_id, to_id, timestamp, timestamp_sent, timestamp_rcvd, type, state, msgrmsg, txt, txt_raw, param, bytes, hidden, mime_headers, mime_in_reply_to, mime_references) VALUES (?,?,?,?,?,?, ?,?,?,?,?,?, ?,?,?,?,?,?, ?,?);\x00" as *const u8 as *const libc::c_char); @@ -635,7 +635,7 @@ pub unsafe fn dc_receive_imf( txt_raw = 0 as *mut libc::c_char; insert_msg_id = dc_sqlite3_get_rowid( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"msgs\x00" as *const u8 as *const libc::c_char, b"rfc724_mid\x00" as *const u8 as *const libc::c_char, rfc724_mid, @@ -696,7 +696,7 @@ pub unsafe fn dc_receive_imf( if carray_count(mime_parser.reports) > 0i32 as libc::c_uint { let mdns_enabled: libc::c_int = dc_sqlite3_get_config_int( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"mdns_enabled\x00" as *const u8 as *const libc::c_char, 1i32, ); @@ -878,7 +878,7 @@ pub unsafe fn dc_receive_imf( if 0 != mime_parser.is_send_by_messenger && 0 != dc_sqlite3_get_config_int( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"mvbox_move\x00" as *const u8 as *const libc::c_char, 1i32, @@ -1028,7 +1028,7 @@ unsafe fn calc_timestamps( if 0 != is_fresh_msg { let stmt: *mut sqlite3_stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT MAX(timestamp) FROM msgs WHERE chat_id=? and from_id!=? AND timestamp>=?\x00" as *const u8 as *const libc::c_char, ); @@ -1289,7 +1289,7 @@ unsafe fn create_or_lookup_group( group_explicitly_left = dc_is_group_explicitly_left(context, grpid); self_addr = dc_sqlite3_get_config( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"configured_addr\x00" as *const u8 as *const libc::c_char, b"\x00" as *const u8 as *const libc::c_char, ); @@ -1367,7 +1367,7 @@ unsafe fn create_or_lookup_group( { stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"UPDATE chats SET name=? WHERE id=?;\x00" as *const u8 as *const libc::c_char, ); @@ -1436,7 +1436,7 @@ unsafe fn create_or_lookup_group( }; stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"DELETE FROM chats_contacts WHERE chat_id=?;\x00" as *const u8 as *const libc::c_char, ); @@ -1567,7 +1567,7 @@ unsafe fn create_or_lookup_adhoc_group( sqlite3_mprintf(b"SELECT c.id, c.blocked FROM chats c LEFT JOIN msgs m ON m.chat_id=c.id WHERE c.id IN(%s) ORDER BY m.timestamp DESC, m.id DESC LIMIT 1;\x00" as *const u8 as *const libc::c_char, chat_ids_str); - stmt = dc_sqlite3_prepare(context, &context.sql.clone().read().unwrap(), q3); + stmt = dc_sqlite3_prepare(context, &context.sql, q3); if sqlite3_step(stmt) == 100i32 { chat_id = sqlite3_column_int(stmt, 0i32) as uint32_t; chat_id_blocked = sqlite3_column_int(stmt, 1i32); @@ -1648,7 +1648,7 @@ unsafe fn create_group_record( let stmt: *mut sqlite3_stmt; stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"INSERT INTO chats (type, name, grpid, blocked) VALUES(?, ?, ?, ?);\x00" as *const u8 as *const libc::c_char, ); @@ -1663,7 +1663,7 @@ unsafe fn create_group_record( if !(sqlite3_step(stmt) != 101i32) { chat_id = dc_sqlite3_get_rowid( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"chats\x00" as *const u8 as *const libc::c_char, b"grpid\x00" as *const u8 as *const libc::c_char, grpid, @@ -1693,10 +1693,10 @@ unsafe fn create_adhoc_grp_id(context: &Context, member_ids: *mut dc_array_t) -> as *const libc::c_char, member_ids_str, ); - stmt = dc_sqlite3_prepare(context, &context.sql.clone().read().unwrap(), q3); + stmt = dc_sqlite3_prepare(context, &context.sql, q3); addr = dc_sqlite3_get_config( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"configured_addr\x00" as *const u8 as *const libc::c_char, b"no-self\x00" as *const u8 as *const libc::c_char, ); @@ -1769,7 +1769,7 @@ unsafe fn search_chat_ids_by_contact_ids( sqlite3_mprintf(b"SELECT DISTINCT cc.chat_id, cc.contact_id FROM chats_contacts cc LEFT JOIN chats c ON c.id=cc.chat_id WHERE cc.chat_id IN(SELECT chat_id FROM chats_contacts WHERE contact_id IN(%s)) AND c.type=120 AND cc.contact_id!=1 ORDER BY cc.chat_id, cc.contact_id;\x00" as *const u8 as *const libc::c_char, contact_ids_str); - stmt = dc_sqlite3_prepare(context, &context.sql.clone().read().unwrap(), q3); + stmt = dc_sqlite3_prepare(context, &context.sql, q3); let mut last_chat_id = 0; let mut matches = 0; let mut mismatches = 0; @@ -1817,7 +1817,7 @@ unsafe fn check_verified_properties( let mut to_ids_str: *mut libc::c_char = 0 as *mut libc::c_char; let mut q3: *mut libc::c_char = 0 as *mut libc::c_char; let mut stmt: *mut sqlite3_stmt = 0 as *mut sqlite3_stmt; - if !dc_contact_load_from_db(contact, &context.sql.clone().read().unwrap(), from_id) { + if !dc_contact_load_from_db(contact, &context.sql, from_id) { *failure_reason = dc_mprintf( b"%s. See \"Info\" for details.\x00" as *const u8 as *const libc::c_char, b"Internal Error; cannot load contact.\x00" as *const u8 as *const libc::c_char, @@ -1835,11 +1835,7 @@ unsafe fn check_verified_properties( // this check is skipped for SELF as there is no proper SELF-peerstate // and results in group-splits otherwise. if from_id != 1i32 as libc::c_uint { - let peerstate = Peerstate::from_addr( - context, - &context.sql.clone().read().unwrap(), - as_str((*contact).addr), - ); + let peerstate = Peerstate::from_addr(context, &context.sql, as_str((*contact).addr)); if peerstate.is_none() || dc_contact_is_verified_ex(contact, peerstate.as_ref()) != 2 { *failure_reason = dc_mprintf( @@ -1874,7 +1870,7 @@ unsafe fn check_verified_properties( sqlite3_mprintf(b"SELECT c.addr, LENGTH(ps.verified_key_fingerprint) FROM contacts c LEFT JOIN acpeerstates ps ON c.addr=ps.addr WHERE c.id IN(%s) \x00" as *const u8 as *const libc::c_char, to_ids_str); - stmt = dc_sqlite3_prepare(context, &context.sql.clone().read().unwrap(), q3); + stmt = dc_sqlite3_prepare(context, &context.sql, q3); loop { if !(sqlite3_step(stmt) == 100i32) { current_block = 2604890879466389055; @@ -1884,11 +1880,8 @@ unsafe fn check_verified_properties( sqlite3_column_text(stmt, 0i32) as *const libc::c_char; let mut is_verified: libc::c_int = sqlite3_column_int(stmt, 1i32); - let mut peerstate = Peerstate::from_addr( - context, - &context.sql.clone().read().unwrap(), - as_str(to_addr), - ); + let mut peerstate = + Peerstate::from_addr(context, &context.sql, as_str(to_addr)); if mimeparser .e2ee_helper .gossipped_addr @@ -1912,7 +1905,7 @@ unsafe fn check_verified_properties( let fp = peerstate.gossip_key_fingerprint.clone(); if let Some(fp) = fp { peerstate.set_verified(0, &fp, 2); - peerstate.save_to_db(&context.sql.clone().read().unwrap(), false); + peerstate.save_to_db(&context.sql, false); is_verified = 1i32; } } @@ -2039,7 +2032,7 @@ unsafe fn is_known_rfc724_mid(context: &Context, rfc724_mid: *const libc::c_char let mut is_known: libc::c_int = 0i32; if !rfc724_mid.is_null() { let stmt: *mut sqlite3_stmt = - dc_sqlite3_prepare(context, &context.sql.clone().read().unwrap(), + dc_sqlite3_prepare(context, &context.sql, b"SELECT m.id FROM msgs m LEFT JOIN chats c ON m.chat_id=c.id WHERE m.rfc724_mid=? AND m.chat_id>9 AND c.blocked=0;\x00" as *const u8 as *const libc::c_char); sqlite3_bind_text(stmt, 1i32, rfc724_mid, -1i32, None); @@ -2123,7 +2116,7 @@ unsafe fn is_msgrmsg_rfc724_mid(context: &Context, rfc724_mid: *const libc::c_ch if !rfc724_mid.is_null() { let stmt: *mut sqlite3_stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT id FROM msgs WHERE rfc724_mid=? AND msgrmsg!=0 AND chat_id>9;\x00" as *const u8 as *const libc::c_char, ); @@ -2241,7 +2234,7 @@ unsafe fn add_or_lookup_contact_by_addr( *check_self = 0i32; let self_addr: *mut libc::c_char = dc_sqlite3_get_config( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"configured_addr\x00" as *const u8 as *const libc::c_char, b"\x00" as *const u8 as *const libc::c_char, ); diff --git a/src/dc_securejoin.rs b/src/dc_securejoin.rs index 1fa5079a9..2158118e8 100644 --- a/src/dc_securejoin.rs +++ b/src/dc_securejoin.rs @@ -58,7 +58,7 @@ pub unsafe fn dc_get_securejoin_qr( } self_addr = dc_sqlite3_get_config( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"configured_addr\x00" as *const u8 as *const libc::c_char, 0 as *const libc::c_char, ); @@ -71,7 +71,7 @@ pub unsafe fn dc_get_securejoin_qr( } else { self_name = dc_sqlite3_get_config( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"displayname\x00" as *const u8 as *const libc::c_char, b"\x00" as *const u8 as *const libc::c_char, ); @@ -150,7 +150,7 @@ pub unsafe fn dc_get_securejoin_qr( unsafe fn get_self_fingerprint(context: &Context) -> *mut libc::c_char { let self_addr = dc_sqlite3_get_config( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"configured_addr\x00" as *const u8 as *const libc::c_char, 0 as *const libc::c_char, ); @@ -158,9 +158,7 @@ unsafe fn get_self_fingerprint(context: &Context) -> *mut libc::c_char { return std::ptr::null_mut(); } - if let Some(key) = - Key::from_self_public(context, self_addr, &context.sql.clone().read().unwrap()) - { + if let Some(key) = Key::from_self_public(context, self_addr, &context.sql) { return key.fingerprint_c(); } @@ -362,17 +360,15 @@ unsafe fn fingerprint_equals_sender( if !(dc_array_get_cnt(contacts) != 1) { if !dc_contact_load_from_db( contact, - &context.sql.clone().read().unwrap(), + &context.sql, dc_array_get_id(contacts, 0i32 as size_t), ) { return 0; } - if let Some(peerstate) = Peerstate::from_addr( - context, - &context.sql.clone().read().unwrap(), - as_str((*contact).addr), - ) { + if let Some(peerstate) = + Peerstate::from_addr(context, &context.sql, as_str((*contact).addr)) + { let fingerprint_normalized = dc_normalize_fingerprint(as_str(fingerprint)); if peerstate.public_key_fingerprint.is_some() && &fingerprint_normalized == peerstate.public_key_fingerprint.as_ref().unwrap() @@ -985,15 +981,13 @@ unsafe fn mark_peer_as_verified( ) -> libc::c_int { let mut success = 0; - if let Some(ref mut peerstate) = Peerstate::from_fingerprint( - context, - &context.sql.clone().read().unwrap(), - as_str(fingerprint), - ) { + if let Some(ref mut peerstate) = + Peerstate::from_fingerprint(context, &context.sql, as_str(fingerprint)) + { if peerstate.set_verified(1, as_str(fingerprint), 2) { peerstate.prefer_encrypt = EncryptPreference::Mutual; peerstate.to_save = Some(ToSave::All); - peerstate.save_to_db(&context.sql.clone().read().unwrap(), false); + peerstate.save_to_db(&context.sql, false); success = 1; } } @@ -1065,7 +1059,7 @@ pub unsafe fn dc_handle_degrade_event(context: &Context, peerstate: &Peerstate) if Some(DegradeEvent::FingerprintChanged) == peerstate.degrade_event { stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT id FROM contacts WHERE addr=?;\x00" as *const u8 as *const libc::c_char, ); let c_addr = peerstate.addr.as_ref().map(to_cstring).unwrap_or_default(); diff --git a/src/dc_sqlite3.rs b/src/dc_sqlite3.rs index 385f07ab9..42be10256 100644 --- a/src/dc_sqlite3.rs +++ b/src/dc_sqlite3.rs @@ -11,45 +11,69 @@ use crate::x::*; const DC_OPEN_READONLY: usize = 0x01; -/// A simple wrapper around the underlying Sqlite3 object. +/// A wrapper around the underlying Sqlite3 object. #[repr(C)] -pub struct dc_sqlite3_t { - pub cobj: *mut sqlite3, +pub struct SQLite { + pub cobj: std::sync::RwLock<*mut sqlite3>, } -pub fn dc_sqlite3_new() -> dc_sqlite3_t { - dc_sqlite3_t { - cobj: std::ptr::null_mut(), +impl SQLite { + pub fn new() -> SQLite { + SQLite { + cobj: std::sync::RwLock::new(std::ptr::null_mut()), + } + } + + pub fn is_open(&self) -> bool { + !self.cobj.read().unwrap().is_null() + } + + // TODO: refactor this further to remove open() and close() + // completely, relying entirely on drop(). + pub fn close(&self, context: &Context) { + unsafe { + let mut cobj = self.cobj.write().unwrap(); + if !cobj.is_null() { + sqlite3_close(*cobj); + *cobj = std::ptr::null_mut(); + } + } + info!(context, 0, "Database closed."); + } + + // return true on success, false on failure + pub fn open(&self, context: &Context, dbfile: &std::path::Path, flags: libc::c_int) -> bool { + let dbfile_c = dbfile.to_c_string().unwrap(); + unsafe { + match dc_sqlite3_open(context, self, dbfile_c.as_ptr(), flags) { + 1 => true, + _ => false, + } + } } } -pub unsafe fn dc_sqlite3_unref(context: &Context, sql: &mut dc_sqlite3_t) { - if !sql.cobj.is_null() { - dc_sqlite3_close(context, sql); +impl Drop for SQLite { + fn drop(&mut self) { + unsafe { + let cobj = self.cobj.write().unwrap(); + if !cobj.is_null() { + sqlite3_close(*cobj); + } + } } } -pub unsafe fn dc_sqlite3_close(context: &Context, sql: &mut dc_sqlite3_t) { - if !sql.cobj.is_null() { - sqlite3_close(sql.cobj); - sql.cobj = 0 as *mut sqlite3 - } - - dc_log_info( - context, - 0, - b"Database closed.\x00" as *const u8 as *const libc::c_char, - ); -} - -pub unsafe fn dc_sqlite3_open( +// Return 1 -> success +// Return 0 -> failure +unsafe fn dc_sqlite3_open( context: &Context, - sql: &mut dc_sqlite3_t, + sql: &SQLite, dbfile: *const libc::c_char, flags: libc::c_int, ) -> libc::c_int { let mut current_block: u64; - if 0 != dc_sqlite3_is_open(sql) { + if sql.is_open() { return 0; } if !dbfile.is_null() { @@ -60,7 +84,7 @@ pub unsafe fn dc_sqlite3_open( b"Sqlite3 compiled thread-unsafe; this is not supported.\x00" as *const u8 as *const libc::c_char, ); - } else if !sql.cobj.is_null() { + } else if sql.is_open() { dc_log_error( context, 0, @@ -70,7 +94,7 @@ pub unsafe fn dc_sqlite3_open( ); } else if sqlite3_open_v2( dbfile, - &mut sql.cobj, + &mut *sql.cobj.write().unwrap(), SQLITE_OPEN_FULLMUTEX | (if 0 != (flags & DC_OPEN_READONLY as i32) { SQLITE_OPEN_READONLY @@ -92,7 +116,7 @@ pub unsafe fn dc_sqlite3_open( sql, b"PRAGMA secure_delete=on;\x00" as *const u8 as *const libc::c_char, ); - sqlite3_busy_timeout(sql.cobj, 10 * 1000); + sqlite3_busy_timeout(*sql.cobj.read().unwrap(), 10 * 1000); if 0 == flags & DC_OPEN_READONLY as i32 { let mut exists_before_update = 0; let mut dbversion_before_update = 0; @@ -923,14 +947,14 @@ pub unsafe fn dc_sqlite3_open( } } - dc_sqlite3_close(context, sql); + sql.close(context); 0 } // handle configurations, private pub unsafe fn dc_sqlite3_set_config( context: &Context, - sql: &dc_sqlite3_t, + sql: &SQLite, key: *const libc::c_char, value: *const libc::c_char, ) -> libc::c_int { @@ -944,7 +968,7 @@ pub unsafe fn dc_sqlite3_set_config( ); return 0; } - if 0 == dc_sqlite3_is_open(sql) { + if !sql.is_open() { dc_log_error( context, 0, @@ -1019,15 +1043,15 @@ pub unsafe fn dc_sqlite3_set_config( /* the result mus be freed using sqlite3_finalize() */ pub unsafe fn dc_sqlite3_prepare( context: &Context, - sql: &dc_sqlite3_t, + sql: &SQLite, querystr: *const libc::c_char, ) -> *mut sqlite3_stmt { let mut stmt = 0 as *mut sqlite3_stmt; - if querystr.is_null() || sql.cobj.is_null() { + if querystr.is_null() || !sql.is_open() { return 0 as *mut sqlite3_stmt; } if sqlite3_prepare_v2( - sql.cobj, + *sql.cobj.read().unwrap(), querystr, -1, &mut stmt, @@ -1047,7 +1071,7 @@ pub unsafe fn dc_sqlite3_prepare( pub unsafe extern "C" fn dc_sqlite3_log_error( context: &Context, - sql: &dc_sqlite3_t, + sql: &SQLite, msg_format: *const libc::c_char, va: ... ) { @@ -1066,8 +1090,8 @@ pub unsafe extern "C" fn dc_sqlite3_log_error( } else { b"\x00" as *const u8 as *const libc::c_char }, - if !sql.cobj.is_null() { - sqlite3_errmsg(sql.cobj) + if sql.is_open() { + sqlite3_errmsg(*sql.cobj.read().unwrap()) } else { b"SQLite object not set up.\x00" as *const u8 as *const libc::c_char }, @@ -1075,23 +1099,15 @@ pub unsafe extern "C" fn dc_sqlite3_log_error( sqlite3_free(msg as *mut libc::c_void); } -pub unsafe fn dc_sqlite3_is_open(sql: &dc_sqlite3_t) -> libc::c_int { - if sql.cobj.is_null() { - 0 - } else { - 1 - } -} - /* the returned string must be free()'d, returns NULL on errors */ pub unsafe fn dc_sqlite3_get_config( context: &Context, - sql: &dc_sqlite3_t, + sql: &SQLite, key: *const libc::c_char, def: *const libc::c_char, ) -> *mut libc::c_char { let stmt; - if 0 == dc_sqlite3_is_open(sql) || key.is_null() { + if !sql.is_open() || key.is_null() { return dc_strdup_keep_null(def); } stmt = dc_sqlite3_prepare( @@ -1114,7 +1130,7 @@ pub unsafe fn dc_sqlite3_get_config( pub unsafe fn dc_sqlite3_execute( context: &Context, - sql: &dc_sqlite3_t, + sql: &SQLite, querystr: *const libc::c_char, ) -> libc::c_int { let mut success = 0; @@ -1139,7 +1155,7 @@ pub unsafe fn dc_sqlite3_execute( pub unsafe fn dc_sqlite3_set_config_int( context: &Context, - sql: &dc_sqlite3_t, + sql: &SQLite, key: *const libc::c_char, value: int32_t, ) -> libc::c_int { @@ -1158,7 +1174,7 @@ pub unsafe fn dc_sqlite3_set_config_int( pub unsafe fn dc_sqlite3_get_config_int( context: &Context, - sql: &dc_sqlite3_t, + sql: &SQLite, key: *const libc::c_char, def: int32_t, ) -> int32_t { @@ -1173,7 +1189,7 @@ pub unsafe fn dc_sqlite3_get_config_int( pub unsafe fn dc_sqlite3_table_exists( context: &Context, - sql: &dc_sqlite3_t, + sql: &SQLite, name: *const libc::c_char, ) -> libc::c_int { let mut ret = 0; @@ -1212,7 +1228,7 @@ pub unsafe fn dc_sqlite3_table_exists( pub unsafe fn dc_sqlite3_set_config_int64( context: &Context, - sql: &dc_sqlite3_t, + sql: &SQLite, key: *const libc::c_char, value: int64_t, ) -> libc::c_int { @@ -1230,7 +1246,7 @@ pub unsafe fn dc_sqlite3_set_config_int64( pub fn dc_sqlite3_get_config_int64( context: &Context, - sql: &dc_sqlite3_t, + sql: &SQLite, key: *const libc::c_char, def: i64, ) -> i64 { @@ -1246,7 +1262,7 @@ pub fn dc_sqlite3_get_config_int64( pub unsafe fn dc_sqlite3_try_execute( context: &Context, - sql: &dc_sqlite3_t, + sql: &SQLite, querystr: *const libc::c_char, ) -> libc::c_int { // same as dc_sqlite3_execute() but does not pass error to ui @@ -1261,7 +1277,7 @@ pub unsafe fn dc_sqlite3_try_execute( 0, b"Try-execute for \"%s\" failed: %s\x00" as *const u8 as *const libc::c_char, querystr, - sqlite3_errmsg(sql.cobj), + sqlite3_errmsg(*sql.cobj.read().unwrap()), ); } else { success = 1 @@ -1273,7 +1289,7 @@ pub unsafe fn dc_sqlite3_try_execute( pub unsafe fn dc_sqlite3_get_rowid( context: &Context, - sql: &dc_sqlite3_t, + sql: &SQLite, table: *const libc::c_char, field: *const libc::c_char, value: *const libc::c_char, @@ -1299,7 +1315,7 @@ pub unsafe fn dc_sqlite3_get_rowid( pub unsafe fn dc_sqlite3_get_rowid2( context: &Context, - sql: &dc_sqlite3_t, + sql: &SQLite, table: *const libc::c_char, field: *const libc::c_char, value: uint64_t, @@ -1365,7 +1381,7 @@ pub unsafe fn dc_housekeeping(context: &Context) { ); stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT value FROM config;\x00" as *const u8 as *const libc::c_char, ); while sqlite3_step(stmt) == 100 { @@ -1518,7 +1534,7 @@ unsafe fn maybe_add_from_param( param_id: libc::c_int, ) { let param = dc_param_new(); - let stmt = dc_sqlite3_prepare(context, &context.sql.clone().read().unwrap(), query); + let stmt = dc_sqlite3_prepare(context, &context.sql, query); while sqlite3_step(stmt) == 100 { dc_param_set_packed(param, sqlite3_column_text(stmt, 0) as *const libc::c_char); let file = dc_param_get(param, param_id, 0 as *const libc::c_char); diff --git a/src/dc_token.rs b/src/dc_token.rs index 9a4682204..72a13bc0a 100644 --- a/src/dc_token.rs +++ b/src/dc_token.rs @@ -19,7 +19,7 @@ pub unsafe fn dc_token_save( // foreign_id may be 0 stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"INSERT INTO tokens (namespc, foreign_id, token, timestamp) VALUES (?, ?, ?, ?);\x00" as *const u8 as *const libc::c_char, ); @@ -40,7 +40,7 @@ pub unsafe fn dc_token_lookup( let stmt: *mut sqlite3_stmt; stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT token FROM tokens WHERE namespc=? AND foreign_id=?;\x00" as *const u8 as *const libc::c_char, ); @@ -63,7 +63,7 @@ pub unsafe fn dc_token_exists( if !token.is_null() { stmt = dc_sqlite3_prepare( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"SELECT id FROM tokens WHERE namespc=? AND token=?;\x00" as *const u8 as *const libc::c_char, ); diff --git a/src/dc_tools.rs b/src/dc_tools.rs index d858fa9e8..ee037b053 100644 --- a/src/dc_tools.rs +++ b/src/dc_tools.rs @@ -1562,6 +1562,45 @@ pub fn as_str<'a>(s: *const libc::c_char) -> &'a str { unsafe { std::ffi::CStr::from_ptr(s).to_str().unwrap() } } +/// Convert a C `*char` pointer to a [std::path::Path] slice. +/// +/// This converts a `*libc::c_char` pointer to a [Path] slice. This +/// essentially has to convert the pointer to [std::ffi::OsStr] to do +/// so and thus is the inverse of [OsStrExt::to_c_string]. Just like +/// [OsStrExt::to_c_string] requires valid Unicode on Windows, this +/// requires that the pointer contains valid UTF-8 on Windows. +/// +/// Because this returns a reference the [Path] silce can not outlive +/// the original pointer. +/// +/// [Path]: std::path::Path +#[cfg(not(target_os = "windows"))] +pub fn as_path<'a>(s: *const libc::c_char) -> &'a std::path::Path { + assert!(!s.is_null(), "cannot be used on null pointers"); + use std::os::unix::ffi::OsStrExt; + unsafe { + let c_str = std::ffi::CStr::from_ptr(s).to_bytes(); + let os_str = std::ffi::OsStr::from_bytes(c_str); + std::path::Path::new(os_str) + } +} + +// as_path() implementation for windows, documented above. +#[cfg(target_os = "windows")] +pub fn as_path<'a>(s: *const libc::c_char) -> &'a std::path::Path { + as_path_unicode(s) +} + +// Implmentation for as_path() on Windows. +// +// Having this as a separate function means it can be tested on unix +// too. +#[allow(dead_code)] +fn as_path_unicode<'a>(s: *const libc::c_char) -> &'a std::path::Path { + assert!(!s.is_null(), "cannot be used on null pointers"); + std::path::Path::new(as_str(s)) +} + pub fn time() -> i64 { SystemTime::now() .duration_since(SystemTime::UNIX_EPOCH) @@ -2038,4 +2077,18 @@ mod tests { CStringError::InteriorNullByte ); } + + #[test] + fn test_as_path() { + let some_path = std::ffi::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 ptr = some_path.as_ptr(); + assert_eq!(as_path_unicode(ptr), std::ffi::OsString::from("/some/path")) + } } diff --git a/src/imap.rs b/src/imap.rs index 5b619adfd..43696b2ee 100644 --- a/src/imap.rs +++ b/src/imap.rs @@ -1600,14 +1600,14 @@ impl Imap { unsafe { dc_sqlite3_set_config_int( context, - &context.sql.read().unwrap(), + &context.sql, b"folders_configured\x00" as *const u8 as *const libc::c_char, 3, ); if let Some(ref mvbox_folder) = mvbox_folder { dc_sqlite3_set_config( context, - &context.sql.read().unwrap(), + &context.sql, b"configured_mvbox_folder\x00" as *const u8 as *const libc::c_char, CString::new(mvbox_folder.clone()).unwrap().as_ptr(), ); @@ -1615,7 +1615,7 @@ impl Imap { if let Some(ref sentbox_folder) = sentbox_folder { dc_sqlite3_set_config( context, - &context.sql.read().unwrap(), + &context.sql, b"configured_sentbox_folder\x00" as *const u8 as *const libc::c_char, CString::new(sentbox_folder.name()).unwrap().as_ptr(), ); diff --git a/src/key.rs b/src/key.rs index 2052ff2f5..7744132ab 100644 --- a/src/key.rs +++ b/src/key.rs @@ -139,7 +139,7 @@ impl Key { pub fn from_self_public( context: &Context, self_addr: *const libc::c_char, - sql: &dc_sqlite3_t, + sql: &SQLite, ) -> Option { if self_addr.is_null() { return None; @@ -169,7 +169,7 @@ impl Key { pub fn from_self_private( context: &Context, self_addr: *const libc::c_char, - sql: &dc_sqlite3_t, + sql: &SQLite, ) -> Option { if self_addr.is_null() { return None; @@ -332,7 +332,7 @@ pub fn dc_key_save_self_keypair( private_key: &Key, addr: *const libc::c_char, is_default: libc::c_int, - sql: &dc_sqlite3_t, + sql: &SQLite, ) -> bool { if addr.is_null() { return false; diff --git a/src/keyring.rs b/src/keyring.rs index 18180052a..8aba979ba 100644 --- a/src/keyring.rs +++ b/src/keyring.rs @@ -32,7 +32,7 @@ impl<'a> Keyring<'a> { &mut self, context: &Context, self_addr: *const libc::c_char, - sql: &dc_sqlite3_t, + sql: &SQLite, ) -> bool { // Can we prevent keyring and self_addr to be null? if self_addr.is_null() { diff --git a/src/oauth2.rs b/src/oauth2.rs index e51b57d9c..7d86622ae 100644 --- a/src/oauth2.rs +++ b/src/oauth2.rs @@ -281,14 +281,8 @@ impl Oauth2 { fn get_config(context: &Context, key: &str) -> Option { let key_c = CString::new(key).unwrap(); - let res = unsafe { - dc_sqlite3_get_config( - context, - &context.sql.clone().read().unwrap(), - key_c.as_ptr(), - std::ptr::null(), - ) - }; + let res = + unsafe { dc_sqlite3_get_config(context, &context.sql, key_c.as_ptr(), std::ptr::null()) }; if res.is_null() { return None; } @@ -299,32 +293,18 @@ fn get_config(context: &Context, key: &str) -> Option { fn set_config(context: &Context, key: &str, value: &str) { let key_c = CString::new(key).unwrap(); let value_c = CString::new(value).unwrap(); - unsafe { - dc_sqlite3_set_config( - context, - &context.sql.clone().read().unwrap(), - key_c.as_ptr(), - value_c.as_ptr(), - ) - }; + unsafe { dc_sqlite3_set_config(context, &context.sql, key_c.as_ptr(), value_c.as_ptr()) }; } fn set_config_int64(context: &Context, key: &str, value: i64) { let key_c = CString::new(key).unwrap(); - unsafe { - dc_sqlite3_set_config_int64( - context, - &context.sql.clone().read().unwrap(), - key_c.as_ptr(), - value, - ) - }; + unsafe { dc_sqlite3_set_config_int64(context, &context.sql, key_c.as_ptr(), value) }; } fn is_expired(context: &Context) -> bool { let expire_timestamp = dc_sqlite3_get_config_int64( context, - &context.sql.clone().read().unwrap(), + &context.sql, b"oauth2_timestamp_expires\x00" as *const u8 as *const libc::c_char, 0i32 as int64_t, ); diff --git a/src/peerstate.rs b/src/peerstate.rs index c0fa5283f..46cc580be 100644 --- a/src/peerstate.rs +++ b/src/peerstate.rs @@ -167,7 +167,7 @@ impl<'a> Peerstate<'a> { res } - pub fn from_addr(context: &'a Context, sql: &dc_sqlite3_t, addr: &str) -> Option { + pub fn from_addr(context: &'a Context, sql: &SQLite, addr: &str) -> Option { let mut res = None; let stmt = unsafe { @@ -187,11 +187,7 @@ impl<'a> Peerstate<'a> { res } - pub fn from_fingerprint( - context: &'a Context, - sql: &dc_sqlite3_t, - fingerprint: &str, - ) -> Option { + pub fn from_fingerprint(context: &'a Context, sql: &SQLite, fingerprint: &str) -> Option { let mut res = None; let stmt = unsafe { @@ -404,7 +400,7 @@ impl<'a> Peerstate<'a> { success } - pub fn save_to_db(&self, sql: &dc_sqlite3_t, create: bool) -> bool { + pub fn save_to_db(&self, sql: &SQLite, create: bool) -> bool { let mut success = false; if self.addr.is_none() { @@ -538,7 +534,7 @@ impl<'a> Peerstate<'a> { } else if self.to_save == Some(ToSave::Timestamps) { let stmt = unsafe { dc_sqlite3_prepare( - self.context,sql, + &self.context,sql, b"UPDATE acpeerstates SET last_seen=?, last_seen_autocrypt=?, gossip_timestamp=? WHERE addr=?;\x00" as *const u8 as *const libc::c_char) }; @@ -615,14 +611,10 @@ mod tests { degrade_event: None, }; - assert!( - peerstate.save_to_db(&ctx.ctx.sql.clone().read().unwrap(), true), - "failed to save" - ); + assert!(peerstate.save_to_db(&ctx.ctx.sql, true), "failed to save"); - let peerstate_new = - Peerstate::from_addr(&ctx.ctx, &ctx.ctx.sql.clone().read().unwrap(), addr.into()) - .expect("failed to load peerstate from db"); + let peerstate_new = Peerstate::from_addr(&ctx.ctx, &ctx.ctx.sql, addr.into()) + .expect("failed to load peerstate from db"); // clear to_save, as that is not persissted peerstate.to_save = None; diff --git a/tests/stress.rs b/tests/stress.rs index 01e354634..534e1c550 100644 --- a/tests/stress.rs +++ b/tests/stress.rs @@ -1,7 +1,7 @@ //! Stress some functions for testing; if used as a lib, this file is obsolete. use std::collections::HashSet; -use std::ffi::{CStr, CString}; +use std::ffi::CString; use mmime::mailimf_types::*; use tempfile::{tempdir, TempDir};