diff --git a/src/dc_chat.rs b/src/dc_chat.rs index a36de0224..33862a8d0 100644 --- a/src/dc_chat.rs +++ b/src/dc_chat.rs @@ -260,14 +260,15 @@ pub unsafe fn dc_create_or_lookup_nchat_by_contact_id( if sql::execute( context, &context.sql, - "INSERT INTO chats (type, name, param, blocked, grpid) VALUES(?, ?, ?, ?, ?)", - params![ + format!( + "INSERT INTO chats (type, name, param, blocked, grpid) VALUES({}, '{}', '{}', {}, '{}')", 100, as_str(chat_name), if contact_id == 1 { "K=1" } else { "" }, create_blocked, as_str((*contact).addr), - ], + ), + params![], ) { chat_id = sql::get_rowid( context, @@ -280,8 +281,8 @@ pub unsafe fn dc_create_or_lookup_nchat_by_contact_id( sql::execute( context, &context.sql, - "INSERT INTO chats_contacts (chat_id, contact_id) VALUES(?, ?)", - params![chat_id, contact_id], + format!("INSERT INTO chats_contacts (chat_id, contact_id) VALUES({}, {})", chat_id, contact_id), + params![], ); } } @@ -1766,8 +1767,12 @@ pub unsafe fn dc_set_chat_name( if sql::execute( context, &context.sql, - "UPDATE chats SET name=? WHERE id={};", - params![as_str(new_name), chat_id as i32], + format!( + "UPDATE chats SET name='{}' WHERE id={};", + as_str(new_name), + chat_id as i32 + ), + params![], ) { if dc_param_get_int((*chat).param, 'U' as i32, 0i32) == 0i32 { (*msg).type_0 = 10i32; @@ -1909,8 +1914,11 @@ pub unsafe fn dc_forward_msgs( context .sql .query_map( - "SELECT id FROM msgs WHERE id IN(?) ORDER BY timestamp,id", - params![as_str(idsstr)], + format!( + "SELECT id FROM msgs WHERE id IN({}) ORDER BY timestamp,id", + as_str(idsstr) + ), + params![], |row| row.get::<_, i32>(0), |ids| { for id in ids { diff --git a/src/dc_chatlist.rs b/src/dc_chatlist.rs index 4b6c9a97e..874482714 100644 --- a/src/dc_chatlist.rs +++ b/src/dc_chatlist.rs @@ -27,19 +27,14 @@ pub unsafe fn dc_get_chatlist<'a>( query_str: *const libc::c_char, query_id: uint32_t, ) -> *mut dc_chatlist_t<'a> { - let mut success: libc::c_int = 0i32; - let obj: *mut dc_chatlist_t = dc_chatlist_new(context); + let obj = dc_chatlist_new(context); - if !(0 == dc_chatlist_load_from_db(obj, listflags, query_str, query_id)) { - success = 1i32 + if 0 != dc_chatlist_load_from_db(obj, listflags, query_str, query_id) { + return obj; } - if 0 != success { - return obj; - } else { - dc_chatlist_unref(obj); - return 0 as *mut dc_chatlist_t; - }; + dc_chatlist_unref(obj); + return 0 as *mut dc_chatlist_t; } /** @@ -122,8 +117,6 @@ unsafe fn dc_chatlist_load_from_db( query__: *const libc::c_char, query_contact_id: u32, ) -> libc::c_int { - //clock_t start = clock(); - if chatlist.is_null() || (*chatlist).magic != 0xc4a71157u32 { return 0; } @@ -142,15 +135,27 @@ unsafe fn dc_chatlist_load_from_db( // for the deaddrop, however, they should really be hidden, however, _currently_ the deaddrop is not // shown at all permanent in the chatlist. - let process_fn = |row: &rusqlite::Row| { - dc_array_add_id((*chatlist).chatNlastmsg_ids, row.get(0)?); - dc_array_add_id((*chatlist).chatNlastmsg_ids, row.get(1)?); + let process_row = |row: &rusqlite::Row| Ok((row.get(0)?, row.get(1)?)); + + let process_rows = |rows: rusqlite::MappedRows<_>| { + for row in rows { + let (id1, id2) = row?; + + dc_array_add_id((*chatlist).chatNlastmsg_ids, id1); + dc_array_add_id((*chatlist).chatNlastmsg_ids, id2); + } Ok(()) }; - let success = - if query_contact_id != 0 { - (*chatlist).context.sql.query_map( + // nb: the query currently shows messages from blocked contacts in groups. + // however, for normal-groups, this is okay as the message is also returned by dc_get_chat_msgs() + // (otherwise it would be hard to follow conversations, wa and tg do the same) + // for the deaddrop, however, they should really be hidden, however, _currently_ the deaddrop is not + // shown at all permanent in the chatlist. + + let success = if query_contact_id != 0 { + // show chats shared with a given contact + (*chatlist).context.sql.query_map( "SELECT c.id, m.id FROM chats c LEFT JOIN msgs m \ ON c.id=m.chat_id \ AND m.timestamp=( SELECT MAX(timestamp) \ @@ -159,74 +164,67 @@ unsafe fn dc_chatlist_load_from_db( 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;", params![query_contact_id as i32], - process_fn, - |res| res.collect::>>().map_err(Into::into), + process_row, + process_rows, ) - } else if 0 != listflags & 0x1 { + } else if 0 != listflags & 0x1 { + // show archived chats + (*chatlist).context.sql.query_map( + "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;", + params![], + process_row, + process_rows, + ) + } else if query__.is_null() { + // show normal chatlist + if 0 == listflags & 0x2 { + let last_deaddrop_fresh_msg_id = get_last_deaddrop_fresh_msg((*chatlist).context); + if last_deaddrop_fresh_msg_id > 0 { + dc_array_add_id((*chatlist).chatNlastmsg_ids, 1); + dc_array_add_id((*chatlist).chatNlastmsg_ids, last_deaddrop_fresh_msg_id); + } + add_archived_link_item = 1; + } + (*chatlist).context.sql.query_map( + "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;", + params![], + process_row, + process_rows, + ) + } else { + let query = to_string(query__).trim().to_string(); + if query.is_empty() { + return 1; + } else { + let strLikeCmd = format!("%{}%", query); (*chatlist).context.sql.query_map( "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;", - params![], - process_fn, - |res| { - res.collect::>>() - .map_err(Into::into) - }, + AND c.blocked=0 AND c.name LIKE ? \ + GROUP BY c.id ORDER BY IFNULL(m.timestamp,0) DESC, m.id DESC;", + params![strLikeCmd], + process_row, + process_rows, ) - } else if query__.is_null() { - if 0 == listflags & 0x2 { - let last_deaddrop_fresh_msg_id = get_last_deaddrop_fresh_msg((*chatlist).context); - if last_deaddrop_fresh_msg_id > 0 { - dc_array_add_id((*chatlist).chatNlastmsg_ids, 1); - dc_array_add_id((*chatlist).chatNlastmsg_ids, last_deaddrop_fresh_msg_id); - } - add_archived_link_item = 1; - } - (*chatlist).context.sql.query_map( - "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;", - params![], - process_fn, - |res| { - res.collect::>>() - .map_err(Into::into) - }, - ) - } else { - let query = to_string(query__).trim().to_string(); - if query.is_empty() { - return 1; - } else { - let strLikeCmd = format!("%{}%", query); - (*chatlist).context.sql.query_map( - "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;", - params![strLikeCmd], - process_fn, - |res| { - res.collect::>>() - .map_err(Into::into) - }, - ) - } - }; + } + }; if 0 != add_archived_link_item && dc_get_archived_cnt((*chatlist).context) > 0 { if dc_array_get_cnt((*chatlist).chatNlastmsg_ids) == 0 && 0 != listflags & 0x4 { @@ -236,9 +234,18 @@ unsafe fn dc_chatlist_load_from_db( dc_array_add_id((*chatlist).chatNlastmsg_ids, 6 as uint32_t); dc_array_add_id((*chatlist).chatNlastmsg_ids, 0 as uint32_t); } - (*chatlist).cnt = dc_array_get_cnt((*chatlist).chatNlastmsg_ids).wrapping_div(2); + (*chatlist).cnt = dc_array_get_cnt((*chatlist).chatNlastmsg_ids) / 2; - success.is_ok() as libc::c_int + match success { + Ok(_) => 1, + Err(err) => { + error!( + (*chatlist).context, + 0, "chatlist: failed to load from database: {:?}", err + ); + 0 + } + } } // Context functions to work with chatlist diff --git a/src/dc_receive_imf.rs b/src/dc_receive_imf.rs index a985f6012..9eccac5d0 100644 --- a/src/dc_receive_imf.rs +++ b/src/dc_receive_imf.rs @@ -1361,9 +1361,12 @@ unsafe fn create_or_lookup_adhoc_group( if dc_array_get_cnt(chat_ids) > 0 { chat_ids_str = dc_array_get_string(chat_ids, b",\x00" as *const u8 as *const _); let res = context.sql.query_row( - "SELECT c.id, c.blocked FROM chats c \ - LEFT JOIN msgs m ON m.chat_id=c.id WHERE c.id IN(?) ORDER BY m.timestamp DESC, m.id DESC LIMIT 1;", - params![as_str(chat_ids_str)], + format!( + "SELECT c.id, c.blocked FROM chats c \ + LEFT JOIN msgs m ON m.chat_id=c.id WHERE c.id IN({}) ORDER BY m.timestamp DESC, m.id DESC LIMIT 1;", + as_str(chat_ids_str), + ), + params![], |row| { Ok((row.get::<_, i32>(0)?, row.get::<_, i32>(1)?)) } @@ -1477,8 +1480,11 @@ unsafe fn create_adhoc_grp_id(context: &Context, member_ids: *mut dc_array_t) -> let members = context .sql .query_map( - "SELECT addr FROM contacts WHERE id IN(?) AND id!=1", - params![as_str(member_ids_str)], + format!( + "SELECT addr FROM contacts WHERE id IN({}) AND id!=1", + as_str(member_ids_str) + ), + params![], |row| row.get::<_, String>(0), |rows| { let mut addrs = rows.collect::, _>>()?; @@ -1535,8 +1541,11 @@ unsafe fn search_chat_ids_by_contact_ids( dc_array_get_string(contact_ids, b",\x00" as *const u8 as *const libc::c_char); context.sql.query_map( - "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(?)) AND c.type=120 AND cc.contact_id!=1 ORDER BY cc.chat_id, cc.contact_id;", - params![as_str(contact_ids_str)], + format!( + "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({})) AND c.type=120 AND cc.contact_id!=1 ORDER BY cc.chat_id, cc.contact_id;", + as_str(contact_ids_str) + ), + params![], |row| Ok((row.get::<_, i32>(0)?, row.get::<_, i32>(1)?)), |rows| { let mut last_chat_id = 0; @@ -1634,9 +1643,12 @@ unsafe fn check_verified_properties( let ok = context .sql .query_map( - "SELECT c.addr, LENGTH(ps.verified_key_fingerprint) FROM contacts c \ - LEFT JOIN acpeerstates ps ON c.addr=ps.addr WHERE c.id IN(?) ", - params![&to_ids_str], + format!( + "SELECT c.addr, LENGTH(ps.verified_key_fingerprint) FROM contacts c \ + LEFT JOIN acpeerstates ps ON c.addr=ps.addr WHERE c.id IN({}) ", + &to_ids_str, + ), + params![], |row| Ok((row.get::<_, String>(0)?, row.get::<_, i32>(1)?)), |rows| { for row in rows { diff --git a/src/sql.rs b/src/sql.rs index 1478c7844..1b0a368e9 100644 --- a/src/sql.rs +++ b/src/sql.rs @@ -98,7 +98,13 @@ impl Sql { /// Prepares and executes the statement and maps a function over the resulting rows. /// Then executes the second function over the returned iterator and returns the /// result of that function. - pub fn query_map(&self, sql: &str, params: P, f: F, mut g: G) -> Result + pub fn query_map( + &self, + sql: impl AsRef, + params: P, + f: F, + mut g: G, + ) -> Result where P: IntoIterator, P::Item: rusqlite::ToSql, @@ -106,7 +112,8 @@ impl Sql { G: FnMut(rusqlite::MappedRows) -> Result, { self.with_conn(|conn| { - let mut stmt = conn.prepare(sql)?; + eprintln!("query_map {}", sql.as_ref()); + let mut stmt = conn.prepare(sql.as_ref())?; let res = stmt.query_map(params, f)?; g(res) }) @@ -126,13 +133,13 @@ impl Sql { }) } - pub fn query_row(&self, sql: &str, params: P, f: F) -> Result + pub fn query_row(&self, sql: impl AsRef, params: P, f: F) -> Result where P: IntoIterator, P::Item: rusqlite::ToSql, F: FnOnce(&rusqlite::Row) -> rusqlite::Result, { - self.with_conn(|conn| conn.query_row(sql, params, f).map_err(Into::into)) + self.with_conn(|conn| conn.query_row(sql.as_ref(), params, f).map_err(Into::into)) } pub fn table_exists(&self, name: impl AsRef) -> bool { @@ -210,12 +217,12 @@ fn open( sql.execute( "CREATE TABLE contacts (\ id INTEGER PRIMARY KEY AUTOINCREMENT, \ - name TEXT DEFAULT \'\', \ - addr TEXT DEFAULT \'\' COLLATE NOCASE, \ + name TEXT DEFAULT '', \ + addr TEXT DEFAULT '' COLLATE NOCASE, \ origin INTEGER DEFAULT 0, \ blocked INTEGER DEFAULT 0, \ last_seen INTEGER DEFAULT 0, \ - param TEXT DEFAULT \'\');", + param TEXT DEFAULT '');", params![], )?; sql.execute( @@ -228,21 +235,21 @@ fn open( )?; sql.execute( "INSERT INTO contacts (id,name,origin) VALUES \ - (1,\'self\',262144), (2,\'device\',262144), (3,\'rsvd\',262144), \ - (4,\'rsvd\',262144), (5,\'rsvd\',262144), (6,\'rsvd\',262144), \ - (7,\'rsvd\',262144), (8,\'rsvd\',262144), (9,\'rsvd\',262144);", + (1,'self',262144), (2,'device',262144), (3,'rsvd',262144), \ + (4,'rsvd',262144), (5,'rsvd',262144), (6,'rsvd',262144), \ + (7,'rsvd',262144), (8,'rsvd',262144), (9,'rsvd',262144);", params![], )?; sql.execute( "CREATE TABLE chats (\ id INTEGER PRIMARY KEY AUTOINCREMENT, \ type INTEGER DEFAULT 0, \ - name TEXT DEFAULT \'\', \ + name TEXT DEFAULT '', \ draft_timestamp INTEGER DEFAULT 0, \ - draft_txt TEXT DEFAULT \'\', \ + draft_txt TEXT DEFAULT '', \ blocked INTEGER DEFAULT 0, \ - grpid TEXT DEFAULT \'\', \ - param TEXT DEFAULT \'\');", + grpid TEXT DEFAULT '', \ + param TEXT DEFAULT '');", params![], )?; sql.execute("CREATE INDEX chats_index1 ON chats (grpid);", params![])?; @@ -256,16 +263,16 @@ fn open( )?; sql.execute( "INSERT INTO chats (id,type,name) VALUES \ - (1,120,\'deaddrop\'), (2,120,\'rsvd\'), (3,120,\'trash\'), \ - (4,120,\'msgs_in_creation\'), (5,120,\'starred\'), (6,120,\'archivedlink\'), \ - (7,100,\'rsvd\'), (8,100,\'rsvd\'), (9,100,\'rsvd\');", + (1,120,'deaddrop'), (2,120,'rsvd'), (3,120,'trash'), \ + (4,120,'msgs_in_creation'), (5,120,'starred'), (6,120,'archivedlink'), \ + (7,100,'rsvd'), (8,100,'rsvd'), (9,100,'rsvd');", params![], )?; sql.execute( "CREATE TABLE msgs (\ id INTEGER PRIMARY KEY AUTOINCREMENT, \ - rfc724_mid TEXT DEFAULT \'\', \ - server_folder TEXT DEFAULT \'\', \ + rfc724_mid TEXT DEFAULT '', \ + server_folder TEXT DEFAULT '', \ server_uid INTEGER DEFAULT 0, \ chat_id INTEGER DEFAULT 0, \ from_id INTEGER DEFAULT 0, \ @@ -275,9 +282,9 @@ fn open( state INTEGER DEFAULT 0, \ msgrmsg INTEGER DEFAULT 1, \ bytes INTEGER DEFAULT 0, \ - txt TEXT DEFAULT \'\', \ - txt_raw TEXT DEFAULT \'\', \ - param TEXT DEFAULT \'\');", + txt TEXT DEFAULT '', \ + txt_raw TEXT DEFAULT '', \ + param TEXT DEFAULT '');", params![], )?; sql.execute("CREATE INDEX msgs_index1 ON msgs (rfc724_mid);", params![])?; @@ -286,9 +293,9 @@ fn open( sql.execute("CREATE INDEX msgs_index4 ON msgs (state);", params![])?; sql.execute( "INSERT INTO msgs (id,msgrmsg,txt) VALUES \ - (1,0,\'marker1\'), (2,0,\'rsvd\'), (3,0,\'rsvd\'), \ - (4,0,\'rsvd\'), (5,0,\'rsvd\'), (6,0,\'rsvd\'), (7,0,\'rsvd\'), \ - (8,0,\'rsvd\'), (9,0,\'daymarker\');", + (1,0,'marker1'), (2,0,'rsvd'), (3,0,'rsvd'), \ + (4,0,'rsvd'), (5,0,'rsvd'), (6,0,'rsvd'), (7,0,'rsvd'), \ + (8,0,'rsvd'), (9,0,'daymarker');", params![], )?; sql.execute( @@ -298,7 +305,7 @@ fn open( desired_timestamp INTEGER DEFAULT 0, \ action INTEGER, \ foreign_id INTEGER, \ - param TEXT DEFAULT \'\');", + param TEXT DEFAULT '');", params![], )?; sql.execute( @@ -338,7 +345,7 @@ fn open( if dbversion < 1 { sql.execute( - "CREATE TABLE leftgrps ( id INTEGER PRIMARY KEY, grpid TEXT DEFAULT \'\');", + "CREATE TABLE leftgrps ( id INTEGER PRIMARY KEY, grpid TEXT DEFAULT '');", params![], )?; sql.execute( @@ -350,7 +357,7 @@ fn open( } if dbversion < 2 { sql.execute( - "ALTER TABLE contacts ADD COLUMN authname TEXT DEFAULT \'\';", + "ALTER TABLE contacts ADD COLUMN authname TEXT DEFAULT '';", params![], )?; dbversion = 2; @@ -360,7 +367,7 @@ fn open( sql.execute( "CREATE TABLE keypairs (\ id INTEGER PRIMARY KEY, \ - addr TEXT DEFAULT \'\' COLLATE NOCASE, \ + addr TEXT DEFAULT '' COLLATE NOCASE, \ is_default INTEGER DEFAULT 0, \ private_key, \ public_key, \ @@ -374,7 +381,7 @@ fn open( sql.execute( "CREATE TABLE acpeerstates (\ id INTEGER PRIMARY KEY, \ - addr TEXT DEFAULT \'\' COLLATE NOCASE, \ + addr TEXT DEFAULT '' COLLATE NOCASE, \ last_seen INTEGER DEFAULT 0, \ last_seen_autocrypt INTEGER DEFAULT 0, \ public_key, \ @@ -450,11 +457,11 @@ fn open( params![], )?; sql.execute( - "ALTER TABLE acpeerstates ADD COLUMN public_key_fingerprint TEXT DEFAULT \'\';", + "ALTER TABLE acpeerstates ADD COLUMN public_key_fingerprint TEXT DEFAULT '';", params![], )?; sql.execute( - "ALTER TABLE acpeerstates ADD COLUMN gossip_key_fingerprint TEXT DEFAULT \'\';", + "ALTER TABLE acpeerstates ADD COLUMN gossip_key_fingerprint TEXT DEFAULT '';", params![], )?; sql.execute( @@ -471,7 +478,7 @@ fn open( } if dbversion < 39 { sql.execute( - "CREATE TABLE tokens ( id INTEGER PRIMARY KEY, namespc INTEGER DEFAULT 0, foreign_id INTEGER DEFAULT 0, token TEXT DEFAULT \'\', timestamp INTEGER DEFAULT 0);", + "CREATE TABLE tokens ( id INTEGER PRIMARY KEY, namespc INTEGER DEFAULT 0, foreign_id INTEGER DEFAULT 0, token TEXT DEFAULT '', timestamp INTEGER DEFAULT 0);", params![] )?; sql.execute( @@ -479,7 +486,7 @@ fn open( params![], )?; sql.execute( - "ALTER TABLE acpeerstates ADD COLUMN verified_key_fingerprint TEXT DEFAULT \'\';", + "ALTER TABLE acpeerstates ADD COLUMN verified_key_fingerprint TEXT DEFAULT '';", params![], )?; sql.execute( @@ -513,7 +520,7 @@ fn open( set_config_int(context, sql, "dbversion", 41); } if dbversion < 42 { - sql.execute("UPDATE msgs SET txt=\'\' WHERE type!=10", params![])?; + sql.execute("UPDATE msgs SET txt='' WHERE type!=10", params![])?; dbversion = 42; set_config_int(context, sql, "dbversion", 42); } @@ -661,7 +668,7 @@ fn open( let repl_from = dc_ensure_no_slash_safe(&repl_from); sql.execute( &format!( - "UPDATE msgs SET param=replace(param, \'f={}/\', \'f=$BLOBDIR/\')", + "UPDATE msgs SET param=replace(param, 'f={}/', 'f=$BLOBDIR/')", repl_from ), NO_PARAMS, @@ -669,7 +676,7 @@ fn open( sql.execute( &format!( - "UPDATE chats SET param=replace(param, \'i={}/\', \'i=$BLOBDIR/\');", + "UPDATE chats SET param=replace(param, 'i={}/', 'i=$BLOBDIR/');", repl_from ), NO_PARAMS, @@ -762,7 +769,13 @@ where match sql.execute(querystr.as_ref(), params) { Ok(_) => true, Err(err) => { - error!(context, 0, "execute failed: {:?}", err); + error!( + context, + 0, + "execute failed: {:?} for {}", + err, + querystr.as_ref() + ); false } }