mirror of
https://github.com/chatmail/core.git
synced 2026-05-02 21:06:31 +03:00
sql: make all queries persistent and update to upstream sqlx
&str queries are not persistent by default. To make queries persistent, they have to be constructed with sqlx::query. Upstream sqlx does not contain the change that make all queries persistent, but it is not needed anymore. but
This commit is contained in:
18
Cargo.lock
generated
18
Cargo.lock
generated
@@ -115,9 +115,9 @@ checksum = "739f4a8db6605981345c5654f3a85b056ce52f37a39d34da03f25bf2151ea16e"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ahash"
|
name = "ahash"
|
||||||
version = "0.6.3"
|
version = "0.7.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "796540673305a66d127804eef19ad696f1f204b8c1025aaca4958c17eab32877"
|
checksum = "7f200cbb1e856866d9eade941cf3aa0c5d7dd36f74311c4273b494f4ef036957"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom 0.2.2",
|
"getrandom 0.2.2",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
@@ -2132,9 +2132,9 @@ checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libsqlite3-sys"
|
name = "libsqlite3-sys"
|
||||||
version = "0.20.1"
|
version = "0.22.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "64d31059f22935e6c31830db5249ba2b7ecd54fd73a9909286f0a67aa55c2fbd"
|
checksum = "2f6332d94daa84478d55a6aa9dbb3b305ed6500fb0cb9400cb9e1525d0e0e188"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"pkg-config",
|
"pkg-config",
|
||||||
@@ -3465,7 +3465,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "sqlx"
|
name = "sqlx"
|
||||||
version = "0.5.1"
|
version = "0.5.1"
|
||||||
source = "git+https://github.com/deltachat/sqlx?branch=master#8915916c76dd578f1db445f9d6f18af480285aed"
|
source = "git+https://github.com/launchbadge/sqlx?branch=master#9e8e3346970cd382a9baca1bba6462b7df4b4b63"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"sqlx-core",
|
"sqlx-core",
|
||||||
"sqlx-macros",
|
"sqlx-macros",
|
||||||
@@ -3474,9 +3474,9 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "sqlx-core"
|
name = "sqlx-core"
|
||||||
version = "0.5.1"
|
version = "0.5.1"
|
||||||
source = "git+https://github.com/deltachat/sqlx?branch=master#8915916c76dd578f1db445f9d6f18af480285aed"
|
source = "git+https://github.com/launchbadge/sqlx?branch=master#9e8e3346970cd382a9baca1bba6462b7df4b4b63"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash 0.6.3",
|
"ahash 0.7.2",
|
||||||
"atoi",
|
"atoi",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
@@ -3512,7 +3512,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "sqlx-macros"
|
name = "sqlx-macros"
|
||||||
version = "0.5.1"
|
version = "0.5.1"
|
||||||
source = "git+https://github.com/deltachat/sqlx?branch=master#8915916c76dd578f1db445f9d6f18af480285aed"
|
source = "git+https://github.com/launchbadge/sqlx?branch=master#9e8e3346970cd382a9baca1bba6462b7df4b4b63"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dotenv",
|
"dotenv",
|
||||||
"either",
|
"either",
|
||||||
@@ -3530,7 +3530,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "sqlx-rt"
|
name = "sqlx-rt"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
source = "git+https://github.com/deltachat/sqlx?branch=master#8915916c76dd578f1db445f9d6f18af480285aed"
|
source = "git+https://github.com/launchbadge/sqlx?branch=master#9e8e3346970cd382a9baca1bba6462b7df4b4b63"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-native-tls",
|
"async-native-tls",
|
||||||
"async-std",
|
"async-std",
|
||||||
|
|||||||
@@ -61,9 +61,9 @@ async-std-resolver = "0.19.5"
|
|||||||
async-tar = "0.3.0"
|
async-tar = "0.3.0"
|
||||||
uuid = { version = "0.8", features = ["serde", "v4"] }
|
uuid = { version = "0.8", features = ["serde", "v4"] }
|
||||||
rust-hsluv = "0.1.4"
|
rust-hsluv = "0.1.4"
|
||||||
sqlx = { git = "https://github.com/deltachat/sqlx", branch = "master", features = ["runtime-async-std-native-tls", "sqlite"] }
|
sqlx = { git = "https://github.com/launchbadge/sqlx", branch = "master", features = ["runtime-async-std-native-tls", "sqlite"] }
|
||||||
# keep in sync with sqlx
|
# keep in sync with sqlx
|
||||||
libsqlite3-sys = { version = "0.20.1", default-features = false, features = [ "pkg-config", "vcpkg", "bundled" ] }
|
libsqlite3-sys = { version = "0.22.0", default-features = false, features = [ "pkg-config", "vcpkg", "bundled" ] }
|
||||||
|
|
||||||
pretty_env_logger = { version = "0.4.0", optional = true }
|
pretty_env_logger = { version = "0.4.0", optional = true }
|
||||||
log = {version = "0.4.8", optional = true }
|
log = {version = "0.4.8", optional = true }
|
||||||
|
|||||||
@@ -32,13 +32,17 @@ use std::time::{Duration, SystemTime};
|
|||||||
async fn reset_tables(context: &Context, bits: i32) {
|
async fn reset_tables(context: &Context, bits: i32) {
|
||||||
println!("Resetting tables ({})...", bits);
|
println!("Resetting tables ({})...", bits);
|
||||||
if 0 != bits & 1 {
|
if 0 != bits & 1 {
|
||||||
context.sql().execute("DELETE FROM jobs;").await.unwrap();
|
context
|
||||||
|
.sql()
|
||||||
|
.execute(sqlx::query("DELETE FROM jobs;"))
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
println!("(1) Jobs reset.");
|
println!("(1) Jobs reset.");
|
||||||
}
|
}
|
||||||
if 0 != bits & 2 {
|
if 0 != bits & 2 {
|
||||||
context
|
context
|
||||||
.sql()
|
.sql()
|
||||||
.execute("DELETE FROM acpeerstates;")
|
.execute(sqlx::query("DELETE FROM acpeerstates;"))
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
println!("(2) Peerstates reset.");
|
println!("(2) Peerstates reset.");
|
||||||
@@ -46,7 +50,7 @@ async fn reset_tables(context: &Context, bits: i32) {
|
|||||||
if 0 != bits & 4 {
|
if 0 != bits & 4 {
|
||||||
context
|
context
|
||||||
.sql()
|
.sql()
|
||||||
.execute("DELETE FROM keypairs;")
|
.execute(sqlx::query("DELETE FROM keypairs;"))
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
println!("(4) Private keypairs reset.");
|
println!("(4) Private keypairs reset.");
|
||||||
@@ -54,34 +58,34 @@ async fn reset_tables(context: &Context, bits: i32) {
|
|||||||
if 0 != bits & 8 {
|
if 0 != bits & 8 {
|
||||||
context
|
context
|
||||||
.sql()
|
.sql()
|
||||||
.execute("DELETE FROM contacts WHERE id>9;")
|
.execute(sqlx::query("DELETE FROM contacts WHERE id>9;"))
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
context
|
context
|
||||||
.sql()
|
.sql()
|
||||||
.execute("DELETE FROM chats WHERE id>9;")
|
.execute(sqlx::query("DELETE FROM chats WHERE id>9;"))
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
context
|
context
|
||||||
.sql()
|
.sql()
|
||||||
.execute("DELETE FROM chats_contacts;")
|
.execute(sqlx::query("DELETE FROM chats_contacts;"))
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
context
|
context
|
||||||
.sql()
|
.sql()
|
||||||
.execute("DELETE FROM msgs WHERE id>9;")
|
.execute(sqlx::query("DELETE FROM msgs WHERE id>9;"))
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
context
|
context
|
||||||
.sql()
|
.sql()
|
||||||
.execute(
|
.execute(sqlx::query(
|
||||||
"DELETE FROM config WHERE keyname LIKE 'imap.%' OR keyname LIKE 'configured%';",
|
"DELETE FROM config WHERE keyname LIKE 'imap.%' OR keyname LIKE 'configured%';",
|
||||||
)
|
))
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
context
|
context
|
||||||
.sql()
|
.sql()
|
||||||
.execute("DELETE FROM leftgrps;")
|
.execute(sqlx::query("DELETE FROM leftgrps;"))
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
println!("(8) Rest but server config reset.");
|
println!("(8) Rest but server config reset.");
|
||||||
|
|||||||
@@ -2860,7 +2860,9 @@ pub(crate) async fn get_chat_cnt(context: &Context) -> Result<usize, Error> {
|
|||||||
// no database, no chats - this is no error (needed eg. for information)
|
// no database, no chats - this is no error (needed eg. for information)
|
||||||
let count = context
|
let count = context
|
||||||
.sql
|
.sql
|
||||||
.count("SELECT COUNT(*) FROM chats WHERE id>9 AND blocked=0;")
|
.count(sqlx::query(
|
||||||
|
"SELECT COUNT(*) FROM chats WHERE id>9 AND blocked=0;",
|
||||||
|
))
|
||||||
.await?;
|
.await?;
|
||||||
Ok(count as usize)
|
Ok(count as usize)
|
||||||
} else {
|
} else {
|
||||||
@@ -3030,7 +3032,10 @@ pub(crate) async fn delete_and_reset_all_device_msgs(context: &Context) -> Resul
|
|||||||
.sql
|
.sql
|
||||||
.execute(sqlx::query("DELETE FROM msgs WHERE from_id=?;").bind(DC_CONTACT_ID_DEVICE as i32))
|
.execute(sqlx::query("DELETE FROM msgs WHERE from_id=?;").bind(DC_CONTACT_ID_DEVICE as i32))
|
||||||
.await?;
|
.await?;
|
||||||
context.sql.execute("DELETE FROM devmsglabels;").await?;
|
context
|
||||||
|
.sql
|
||||||
|
.execute(sqlx::query("DELETE FROM devmsglabels;"))
|
||||||
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -410,7 +410,9 @@ impl Chatlist {
|
|||||||
pub async fn dc_get_archived_cnt(context: &Context) -> Result<usize> {
|
pub async fn dc_get_archived_cnt(context: &Context) -> Result<usize> {
|
||||||
let count = context
|
let count = context
|
||||||
.sql
|
.sql
|
||||||
.count("SELECT COUNT(*) FROM chats WHERE blocked=0 AND archived=1;")
|
.count(sqlx::query(
|
||||||
|
"SELECT COUNT(*) FROM chats WHERE blocked=0 AND archived=1;",
|
||||||
|
))
|
||||||
.await?;
|
.await?;
|
||||||
Ok(count)
|
Ok(count)
|
||||||
}
|
}
|
||||||
@@ -420,7 +422,7 @@ async fn get_last_deaddrop_fresh_msg(context: &Context) -> Result<Option<MsgId>>
|
|||||||
// sufficient as there are typically only few fresh messages.
|
// sufficient as there are typically only few fresh messages.
|
||||||
let id = context
|
let id = context
|
||||||
.sql
|
.sql
|
||||||
.query_get_value(concat!(
|
.query_get_value(sqlx::query(concat!(
|
||||||
"SELECT m.id",
|
"SELECT m.id",
|
||||||
" FROM msgs m",
|
" FROM msgs m",
|
||||||
" LEFT JOIN chats c",
|
" LEFT JOIN chats c",
|
||||||
@@ -429,7 +431,7 @@ async fn get_last_deaddrop_fresh_msg(context: &Context) -> Result<Option<MsgId>>
|
|||||||
" AND m.hidden=0",
|
" AND m.hidden=0",
|
||||||
" AND c.blocked=2",
|
" AND c.blocked=2",
|
||||||
" ORDER BY m.timestamp DESC, m.id DESC;"
|
" ORDER BY m.timestamp DESC, m.id DESC;"
|
||||||
))
|
)))
|
||||||
.await?;
|
.await?;
|
||||||
Ok(id)
|
Ok(id)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -242,7 +242,7 @@ impl Context {
|
|||||||
match key {
|
match key {
|
||||||
Config::Selfavatar => {
|
Config::Selfavatar => {
|
||||||
self.sql
|
self.sql
|
||||||
.execute("UPDATE contacts SET selfavatar_sent=0;")
|
.execute(sqlx::query("UPDATE contacts SET selfavatar_sent=0;"))
|
||||||
.await?;
|
.await?;
|
||||||
self.sql
|
self.sql
|
||||||
.set_raw_config_bool("attach_selfavatar", true)
|
.set_raw_config_bool("attach_selfavatar", true)
|
||||||
|
|||||||
@@ -290,16 +290,22 @@ impl Context {
|
|||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
let journal_mode = self
|
let journal_mode = self
|
||||||
.sql
|
.sql
|
||||||
.query_get_value("PRAGMA journal_mode;")
|
.query_get_value(sqlx::query("PRAGMA journal_mode;"))
|
||||||
.await?
|
.await?
|
||||||
.unwrap_or_else(|| "unknown".to_string());
|
.unwrap_or_else(|| "unknown".to_string());
|
||||||
let e2ee_enabled = self.get_config_int(Config::E2eeEnabled).await?;
|
let e2ee_enabled = self.get_config_int(Config::E2eeEnabled).await?;
|
||||||
let mdns_enabled = self.get_config_int(Config::MdnsEnabled).await?;
|
let mdns_enabled = self.get_config_int(Config::MdnsEnabled).await?;
|
||||||
let bcc_self = self.get_config_int(Config::BccSelf).await?;
|
let bcc_self = self.get_config_int(Config::BccSelf).await?;
|
||||||
|
|
||||||
let prv_key_cnt = self.sql.count("SELECT COUNT(*) FROM keypairs;").await?;
|
let prv_key_cnt = self
|
||||||
|
.sql
|
||||||
|
.count(sqlx::query("SELECT COUNT(*) FROM keypairs;"))
|
||||||
|
.await?;
|
||||||
|
|
||||||
let pub_key_cnt = self.sql.count("SELECT COUNT(*) FROM acpeerstates;").await?;
|
let pub_key_cnt = self
|
||||||
|
.sql
|
||||||
|
.count(sqlx::query("SELECT COUNT(*) FROM acpeerstates;"))
|
||||||
|
.await?;
|
||||||
let fingerprint_str = match SignedPublicKey::load_self(self).await {
|
let fingerprint_str = match SignedPublicKey::load_self(self).await {
|
||||||
Ok(key) => key.fingerprint().hex(),
|
Ok(key) => key.fingerprint().hex(),
|
||||||
Err(err) => format!("<key failure: {}>", err),
|
Err(err) => format!("<key failure: {}>", err),
|
||||||
|
|||||||
17
src/imex.rs
17
src/imex.rs
@@ -595,7 +595,7 @@ async fn import_backup_old(context: &Context, backup_to_import: impl AsRef<Path>
|
|||||||
|
|
||||||
let total_files_cnt = context
|
let total_files_cnt = context
|
||||||
.sql
|
.sql
|
||||||
.count("SELECT COUNT(*) FROM backup_blobs;")
|
.count(sqlx::query("SELECT COUNT(*) FROM backup_blobs;"))
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
info!(
|
info!(
|
||||||
@@ -607,7 +607,7 @@ async fn import_backup_old(context: &Context, backup_to_import: impl AsRef<Path>
|
|||||||
// consuming too much memory.
|
// consuming too much memory.
|
||||||
let file_ids = context
|
let file_ids = context
|
||||||
.sql
|
.sql
|
||||||
.fetch("SELECT id FROM backup_blobs ORDER BY id")
|
.fetch(sqlx::query("SELECT id FROM backup_blobs ORDER BY id"))
|
||||||
.await?
|
.await?
|
||||||
.map(|row| row?.try_get(0))
|
.map(|row| row?.try_get(0))
|
||||||
.collect::<sqlx::Result<Vec<i64>>>()
|
.collect::<sqlx::Result<Vec<i64>>>()
|
||||||
@@ -648,8 +648,11 @@ async fn import_backup_old(context: &Context, backup_to_import: impl AsRef<Path>
|
|||||||
|
|
||||||
if all_files_extracted {
|
if all_files_extracted {
|
||||||
// only delete backup_blobs if all files were successfully extracted
|
// only delete backup_blobs if all files were successfully extracted
|
||||||
context.sql.execute("DROP TABLE backup_blobs;").await?;
|
context
|
||||||
context.sql.execute("VACUUM;").await.ok();
|
.sql
|
||||||
|
.execute(sqlx::query("DROP TABLE backup_blobs;"))
|
||||||
|
.await?;
|
||||||
|
context.sql.execute(sqlx::query("VACUUM;")).await.ok();
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
bail!("received stop signal");
|
bail!("received stop signal");
|
||||||
@@ -674,7 +677,7 @@ async fn export_backup(context: &Context, dir: impl AsRef<Path>) -> Result<()> {
|
|||||||
|
|
||||||
context
|
context
|
||||||
.sql
|
.sql
|
||||||
.execute("VACUUM;")
|
.execute(sqlx::query("VACUUM;"))
|
||||||
.await
|
.await
|
||||||
.map_err(|e| warn!(context, "Vacuum failed, exporting anyway {}", e));
|
.map_err(|e| warn!(context, "Vacuum failed, exporting anyway {}", e));
|
||||||
|
|
||||||
@@ -829,7 +832,9 @@ async fn export_self_keys(context: &Context, dir: impl AsRef<Path>) -> Result<()
|
|||||||
|
|
||||||
let mut keys = context
|
let mut keys = context
|
||||||
.sql
|
.sql
|
||||||
.fetch("SELECT id, public_key, private_key, is_default FROM keypairs;")
|
.fetch(sqlx::query(
|
||||||
|
"SELECT id, public_key, private_key, is_default FROM keypairs;",
|
||||||
|
))
|
||||||
.await?
|
.await?
|
||||||
.map(|row| -> sqlx::Result<_> {
|
.map(|row| -> sqlx::Result<_> {
|
||||||
let row = row?;
|
let row = row?;
|
||||||
|
|||||||
12
src/key.rs
12
src/key.rs
@@ -123,14 +123,14 @@ impl DcKey for SignedPublicKey {
|
|||||||
async fn load_self(context: &Context) -> Result<Self::KeyType> {
|
async fn load_self(context: &Context) -> Result<Self::KeyType> {
|
||||||
match context
|
match context
|
||||||
.sql
|
.sql
|
||||||
.fetch_optional(
|
.fetch_optional(sqlx::query(
|
||||||
r#"
|
r#"
|
||||||
SELECT public_key
|
SELECT public_key
|
||||||
FROM keypairs
|
FROM keypairs
|
||||||
WHERE addr=(SELECT value FROM config WHERE keyname="configured_addr")
|
WHERE addr=(SELECT value FROM config WHERE keyname="configured_addr")
|
||||||
AND is_default=1;
|
AND is_default=1;
|
||||||
"#,
|
"#,
|
||||||
)
|
))
|
||||||
.await?
|
.await?
|
||||||
{
|
{
|
||||||
Some(row) => Self::from_slice(row.try_get(0)?),
|
Some(row) => Self::from_slice(row.try_get(0)?),
|
||||||
@@ -165,14 +165,14 @@ impl DcKey for SignedSecretKey {
|
|||||||
async fn load_self(context: &Context) -> Result<Self::KeyType> {
|
async fn load_self(context: &Context) -> Result<Self::KeyType> {
|
||||||
match context
|
match context
|
||||||
.sql
|
.sql
|
||||||
.fetch_optional(
|
.fetch_optional(sqlx::query(
|
||||||
r#"
|
r#"
|
||||||
SELECT private_key
|
SELECT private_key
|
||||||
FROM keypairs
|
FROM keypairs
|
||||||
WHERE addr=(SELECT value FROM config WHERE keyname="configured_addr")
|
WHERE addr=(SELECT value FROM config WHERE keyname="configured_addr")
|
||||||
AND is_default=1;
|
AND is_default=1;
|
||||||
"#,
|
"#,
|
||||||
)
|
))
|
||||||
.await?
|
.await?
|
||||||
{
|
{
|
||||||
Some(row) => Self::from_slice(row.try_get(0)?),
|
Some(row) => Self::from_slice(row.try_get(0)?),
|
||||||
@@ -328,7 +328,7 @@ pub async fn store_self_keypair(
|
|||||||
if default == KeyPairUse::Default {
|
if default == KeyPairUse::Default {
|
||||||
context
|
context
|
||||||
.sql
|
.sql
|
||||||
.execute("UPDATE keypairs SET is_default=0;")
|
.execute(sqlx::query("UPDATE keypairs SET is_default=0;"))
|
||||||
.await
|
.await
|
||||||
.map_err(|err| SaveKeyError::new("failed to clear default", err))?;
|
.map_err(|err| SaveKeyError::new("failed to clear default", err))?;
|
||||||
}
|
}
|
||||||
@@ -625,7 +625,7 @@ i8pcjGO+IZffvyZJVRWfVooBJmWWbPB1pueo3tx8w3+fcuzpxz+RLFKaPyqXO+dD
|
|||||||
|
|
||||||
let nrows = || async {
|
let nrows = || async {
|
||||||
ctx.sql
|
ctx.sql
|
||||||
.count("SELECT COUNT(*) FROM keypairs;")
|
.count(sqlx::query("SELECT COUNT(*) FROM keypairs;"))
|
||||||
.await
|
.await
|
||||||
.unwrap()
|
.unwrap()
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -401,7 +401,10 @@ fn is_marker(txt: &str) -> bool {
|
|||||||
|
|
||||||
/// Deletes all locations from the database.
|
/// Deletes all locations from the database.
|
||||||
pub async fn delete_all(context: &Context) -> Result<(), Error> {
|
pub async fn delete_all(context: &Context) -> Result<(), Error> {
|
||||||
context.sql.execute("DELETE FROM locations;").await?;
|
context
|
||||||
|
.sql
|
||||||
|
.execute(sqlx::query("DELETE FROM locations;"))
|
||||||
|
.await?;
|
||||||
context.emit_event(EventType::LocationChanged(None));
|
context.emit_event(EventType::LocationChanged(None));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1878,11 +1878,11 @@ async fn ndn_maybe_add_info_msg(
|
|||||||
pub async fn get_real_msg_cnt(context: &Context) -> usize {
|
pub async fn get_real_msg_cnt(context: &Context) -> usize {
|
||||||
match context
|
match context
|
||||||
.sql
|
.sql
|
||||||
.count(
|
.count(sqlx::query(
|
||||||
"SELECT COUNT(*) \
|
"SELECT COUNT(*) \
|
||||||
FROM msgs m LEFT JOIN chats c ON c.id=m.chat_id \
|
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;",
|
WHERE m.id>9 AND m.chat_id>9 AND c.blocked=0;",
|
||||||
)
|
))
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok(res) => res,
|
Ok(res) => res,
|
||||||
@@ -1896,11 +1896,11 @@ pub async fn get_real_msg_cnt(context: &Context) -> usize {
|
|||||||
pub async fn get_deaddrop_msg_cnt(context: &Context) -> usize {
|
pub async fn get_deaddrop_msg_cnt(context: &Context) -> usize {
|
||||||
match context
|
match context
|
||||||
.sql
|
.sql
|
||||||
.count(
|
.count(sqlx::query(
|
||||||
"SELECT COUNT(*) \
|
"SELECT COUNT(*) \
|
||||||
FROM msgs m LEFT JOIN chats c ON c.id=m.chat_id \
|
FROM msgs m LEFT JOIN chats c ON c.id=m.chat_id \
|
||||||
WHERE c.blocked=2;",
|
WHERE c.blocked=2;",
|
||||||
)
|
))
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok(res) => res,
|
Ok(res) => res,
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use std::fmt;
|
|||||||
|
|
||||||
use anyhow::{bail, Result};
|
use anyhow::{bail, Result};
|
||||||
use num_traits::FromPrimitive;
|
use num_traits::FromPrimitive;
|
||||||
use sqlx::Row;
|
use sqlx::{query::Query, sqlite::Sqlite, Row};
|
||||||
|
|
||||||
use crate::aheader::{Aheader, EncryptPreference};
|
use crate::aheader::{Aheader, EncryptPreference};
|
||||||
use crate::chat;
|
use crate::chat;
|
||||||
@@ -173,10 +173,12 @@ impl Peerstate {
|
|||||||
Self::from_stmt(context, query).await
|
Self::from_stmt(context, query).await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn from_stmt<'e, 'q, E>(context: &Context, query: E) -> Result<Option<Peerstate>>
|
async fn from_stmt<'q, E>(
|
||||||
|
context: &Context,
|
||||||
|
query: Query<'q, Sqlite, E>,
|
||||||
|
) -> Result<Option<Peerstate>>
|
||||||
where
|
where
|
||||||
'q: 'e,
|
E: 'q + sqlx::IntoArguments<'q, sqlx::Sqlite>,
|
||||||
E: 'q + sqlx::Execute<'q, sqlx::Sqlite>,
|
|
||||||
{
|
{
|
||||||
if let Some(row) = context.sql.fetch_optional(query).await? {
|
if let Some(row) = context.sql.fetch_optional(query).await? {
|
||||||
// all the above queries start with this: SELECT
|
// all the above queries start with this: SELECT
|
||||||
|
|||||||
@@ -417,9 +417,9 @@ ALTER TABLE msgs ADD COLUMN mime_modified INTEGER DEFAULT 0;"#,
|
|||||||
if dbversion < 73 {
|
if dbversion < 73 {
|
||||||
use Config::*;
|
use Config::*;
|
||||||
info!(context, "[migration] v73");
|
info!(context, "[migration] v73");
|
||||||
sql.execute(
|
sql.execute(sqlx::query(
|
||||||
r#"
|
r#"
|
||||||
CREATE TABLE imap_sync (folder TEXT PRIMARY KEY, uidvalidity INTEGER DEFAULT 0, uid_next INTEGER DEFAULT 0);"#,
|
CREATE TABLE imap_sync (folder TEXT PRIMARY KEY, uidvalidity INTEGER DEFAULT 0, uid_next INTEGER DEFAULT 0);"#),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
for c in &[
|
for c in &[
|
||||||
|
|||||||
@@ -10,8 +10,9 @@ use async_std::prelude::*;
|
|||||||
use async_std::sync::RwLock;
|
use async_std::sync::RwLock;
|
||||||
use sqlx::{
|
use sqlx::{
|
||||||
pool::PoolOptions,
|
pool::PoolOptions,
|
||||||
|
query::Query,
|
||||||
sqlite::{Sqlite, SqliteConnectOptions, SqliteJournalMode, SqlitePool, SqliteSynchronous},
|
sqlite::{Sqlite, SqliteConnectOptions, SqliteJournalMode, SqlitePool, SqliteSynchronous},
|
||||||
Execute, Executor, Row,
|
Executor, IntoArguments, Row,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::chat::{add_device_msg, update_device_icon, update_saved_messages_icon};
|
use crate::chat::{add_device_msg, update_device_icon, update_saved_messages_icon};
|
||||||
@@ -171,7 +172,9 @@ PRAGMA query_only=1; -- Protect against writes even in read-write mode
|
|||||||
|
|
||||||
if recalc_fingerprints {
|
if recalc_fingerprints {
|
||||||
info!(context, "[migration] recalc fingerprints");
|
info!(context, "[migration] recalc fingerprints");
|
||||||
let mut rows = self.fetch("SELECT addr FROM acpeerstates;").await?;
|
let mut rows = self
|
||||||
|
.fetch(sqlx::query("SELECT addr FROM acpeerstates;"))
|
||||||
|
.await?;
|
||||||
|
|
||||||
while let Some(row) = rows.next().await {
|
while let Some(row) = rows.next().await {
|
||||||
let row = row?;
|
let row = row?;
|
||||||
@@ -208,10 +211,9 @@ PRAGMA query_only=1; -- Protect against writes even in read-write mode
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Execute the given query, returning the number of affected rows.
|
/// Execute the given query, returning the number of affected rows.
|
||||||
pub async fn execute<'e, 'q, E>(&self, query: E) -> Result<u64>
|
pub async fn execute<'q, E>(&self, query: Query<'q, Sqlite, E>) -> Result<u64>
|
||||||
where
|
where
|
||||||
'q: 'e,
|
E: 'q + IntoArguments<'q, Sqlite>,
|
||||||
E: 'q + Execute<'q, Sqlite>,
|
|
||||||
{
|
{
|
||||||
let lock = self.writer.read().await;
|
let lock = self.writer.read().await;
|
||||||
let pool = lock.as_ref().ok_or(Error::SqlNoConnection)?;
|
let pool = lock.as_ref().ok_or(Error::SqlNoConnection)?;
|
||||||
@@ -221,10 +223,9 @@ PRAGMA query_only=1; -- Protect against writes even in read-write mode
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Execute many queries.
|
/// Execute many queries.
|
||||||
pub async fn execute_many<'e, 'q, E>(&self, query: E) -> Result<()>
|
pub async fn execute_many<'q, E>(&self, query: Query<'q, Sqlite, E>) -> Result<()>
|
||||||
where
|
where
|
||||||
'q: 'e,
|
E: 'q + IntoArguments<'q, Sqlite>,
|
||||||
E: 'q + Execute<'q, Sqlite>,
|
|
||||||
{
|
{
|
||||||
let lock = self.writer.read().await;
|
let lock = self.writer.read().await;
|
||||||
let pool = lock.as_ref().ok_or(Error::SqlNoConnection)?;
|
let pool = lock.as_ref().ok_or(Error::SqlNoConnection)?;
|
||||||
@@ -236,13 +237,12 @@ PRAGMA query_only=1; -- Protect against writes even in read-write mode
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Fetch the given query.
|
/// Fetch the given query.
|
||||||
pub async fn fetch<'e, 'q, E>(
|
pub async fn fetch<'q, E>(
|
||||||
&self,
|
&self,
|
||||||
query: E,
|
query: Query<'q, Sqlite, E>,
|
||||||
) -> Result<impl Stream<Item = sqlx::Result<<Sqlite as sqlx::Database>::Row>> + 'e + Send>
|
) -> Result<impl Stream<Item = sqlx::Result<<Sqlite as sqlx::Database>::Row>> + Send + 'q>
|
||||||
where
|
where
|
||||||
'q: 'e,
|
E: 'q + IntoArguments<'q, Sqlite>,
|
||||||
E: 'q + Execute<'q, Sqlite>,
|
|
||||||
{
|
{
|
||||||
let lock = self.reader.read().await;
|
let lock = self.reader.read().await;
|
||||||
let pool = lock.as_ref().ok_or(Error::SqlNoConnection)?;
|
let pool = lock.as_ref().ok_or(Error::SqlNoConnection)?;
|
||||||
@@ -252,10 +252,12 @@ PRAGMA query_only=1; -- Protect against writes even in read-write mode
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Fetch exactly one row, errors if no row is found.
|
/// Fetch exactly one row, errors if no row is found.
|
||||||
pub async fn fetch_one<'e, 'q, E>(&self, query: E) -> Result<<Sqlite as sqlx::Database>::Row>
|
pub async fn fetch_one<'q, E>(
|
||||||
|
&self,
|
||||||
|
query: Query<'q, Sqlite, E>,
|
||||||
|
) -> Result<<Sqlite as sqlx::Database>::Row>
|
||||||
where
|
where
|
||||||
'q: 'e,
|
E: 'q + IntoArguments<'q, Sqlite>,
|
||||||
E: 'q + Execute<'q, Sqlite>,
|
|
||||||
{
|
{
|
||||||
let lock = self.reader.read().await;
|
let lock = self.reader.read().await;
|
||||||
let pool = lock.as_ref().ok_or(Error::SqlNoConnection)?;
|
let pool = lock.as_ref().ok_or(Error::SqlNoConnection)?;
|
||||||
@@ -267,11 +269,10 @@ PRAGMA query_only=1; -- Protect against writes even in read-write mode
|
|||||||
/// Fetches at most one row.
|
/// Fetches at most one row.
|
||||||
pub async fn fetch_optional<'e, 'q, E>(
|
pub async fn fetch_optional<'e, 'q, E>(
|
||||||
&self,
|
&self,
|
||||||
query: E,
|
query: Query<'q, Sqlite, E>,
|
||||||
) -> Result<Option<<Sqlite as sqlx::Database>::Row>>
|
) -> Result<Option<<Sqlite as sqlx::Database>::Row>>
|
||||||
where
|
where
|
||||||
'q: 'e,
|
E: 'q + IntoArguments<'q, Sqlite>,
|
||||||
E: 'q + Execute<'q, Sqlite>,
|
|
||||||
{
|
{
|
||||||
let lock = self.reader.read().await;
|
let lock = self.reader.read().await;
|
||||||
let pool = lock.as_ref().ok_or(Error::SqlNoConnection)?;
|
let pool = lock.as_ref().ok_or(Error::SqlNoConnection)?;
|
||||||
@@ -281,10 +282,9 @@ PRAGMA query_only=1; -- Protect against writes even in read-write mode
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Used for executing `SELECT COUNT` statements only. Returns the resulting count.
|
/// Used for executing `SELECT COUNT` statements only. Returns the resulting count.
|
||||||
pub async fn count<'e, 'q, E>(&self, query: E) -> Result<usize>
|
pub async fn count<'e, 'q, E>(&self, query: Query<'q, Sqlite, E>) -> Result<usize>
|
||||||
where
|
where
|
||||||
'q: 'e,
|
E: 'q + IntoArguments<'q, Sqlite>,
|
||||||
E: 'q + Execute<'q, Sqlite>,
|
|
||||||
{
|
{
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
@@ -296,10 +296,9 @@ PRAGMA query_only=1; -- Protect against writes even in read-write mode
|
|||||||
|
|
||||||
/// Used for executing `SELECT COUNT` statements only. Returns `true`, if the count is at least
|
/// Used for executing `SELECT COUNT` statements only. Returns `true`, if the count is at least
|
||||||
/// one, `false` otherwise.
|
/// one, `false` otherwise.
|
||||||
pub async fn exists<'e, 'q, E>(&self, query: E) -> Result<bool>
|
pub async fn exists<'e, 'q, E>(&self, query: Query<'q, Sqlite, E>) -> Result<bool>
|
||||||
where
|
where
|
||||||
'q: 'e,
|
E: 'q + IntoArguments<'q, Sqlite>,
|
||||||
E: 'q + Execute<'q, Sqlite>,
|
|
||||||
{
|
{
|
||||||
let count = self.count(query).await?;
|
let count = self.count(query).await?;
|
||||||
Ok(count > 0)
|
Ok(count > 0)
|
||||||
@@ -383,10 +382,12 @@ PRAGMA query_only=1; -- Protect against writes even in read-write mode
|
|||||||
/// Executes a query which is expected to return one row and one
|
/// Executes a query which is expected to return one row and one
|
||||||
/// column. If the query does not return a value or returns SQL
|
/// column. If the query does not return a value or returns SQL
|
||||||
/// `NULL`, returns `Ok(None)`.
|
/// `NULL`, returns `Ok(None)`.
|
||||||
pub async fn query_get_value<'e, 'q, E, T>(&self, query: E) -> Result<Option<T>>
|
pub async fn query_get_value<'e, 'q, E, T>(
|
||||||
|
&self,
|
||||||
|
query: Query<'q, Sqlite, E>,
|
||||||
|
) -> Result<Option<T>>
|
||||||
where
|
where
|
||||||
'q: 'e,
|
E: 'q + IntoArguments<'q, Sqlite>,
|
||||||
E: 'q + Execute<'q, Sqlite>,
|
|
||||||
T: for<'r> sqlx::Decode<'r, Sqlite> + sqlx::Type<Sqlite>,
|
T: for<'r> sqlx::Decode<'r, Sqlite> + sqlx::Type<Sqlite>,
|
||||||
{
|
{
|
||||||
let res = self
|
let res = self
|
||||||
@@ -569,7 +570,10 @@ pub async fn housekeeping(context: &Context) -> Result<()> {
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let mut rows = context.sql.fetch("SELECT value FROM config;").await?;
|
let mut rows = context
|
||||||
|
.sql
|
||||||
|
.fetch(sqlx::query("SELECT value FROM config;"))
|
||||||
|
.await?;
|
||||||
while let Some(row) = rows.next().await {
|
while let Some(row) = rows.next().await {
|
||||||
let row: String = row?.try_get(0)?;
|
let row: String = row?.try_get(0)?;
|
||||||
maybe_add_file(&mut files_in_use, row);
|
maybe_add_file(&mut files_in_use, row);
|
||||||
@@ -692,7 +696,7 @@ async fn maybe_add_from_param(
|
|||||||
query: &str,
|
query: &str,
|
||||||
param_id: Param,
|
param_id: Param,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let mut rows = sql.fetch(query).await?;
|
let mut rows = sql.fetch(sqlx::query(query)).await?;
|
||||||
while let Some(row) = rows.next().await {
|
while let Some(row) = rows.next().await {
|
||||||
let row: String = row?.try_get(0)?;
|
let row: String = row?.try_get(0)?;
|
||||||
let param: Params = row.parse().unwrap_or_default();
|
let param: Params = row.parse().unwrap_or_default();
|
||||||
|
|||||||
Reference in New Issue
Block a user