diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.lock b/frontend/appflowy_tauri/src-tauri/Cargo.lock index c4138ae6a6..a258f965c5 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.lock +++ b/frontend/appflowy_tauri/src-tauri/Cargo.lock @@ -1560,37 +1560,49 @@ checksum = "850878694b7933ca4c9569d30a34b55031b9b139ee1fc7b94a527c4ef960d690" [[package]] name = "diesel" -version = "1.4.8" +version = "2.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b28135ecf6b7d446b43e27e225622a038cc4e2930a1022f51cdb97ada19b8e4d" +checksum = "62c6fcf842f17f8c78ecf7c81d75c5ce84436b41ee07e03f490fbb5f5a8731d8" dependencies = [ - "byteorder", "chrono", "diesel_derives", "libsqlite3-sys", + "r2d2", + "time", ] [[package]] name = "diesel_derives" -version = "1.4.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45f5098f628d02a7a0f68ddba586fb61e80edec3bdc1be3b921f4ceec60858d3" +checksum = "ef8337737574f55a468005a83499da720f20c65586241ffea339db9ecdfd2b44" dependencies = [ + "diesel_table_macro_syntax", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.32", ] [[package]] name = "diesel_migrations" -version = "1.4.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf3cde8413353dc7f5d72fa8ce0b99a560a359d2c5ef1e5817ca731cd9008f4c" +checksum = "6036b3f0120c5961381b570ee20a02432d7e2d27ea60de9578799cf9156914ac" dependencies = [ + "diesel", "migrations_internals", "migrations_macros", ] +[[package]] +name = "diesel_table_macro_syntax" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc5557efc453706fed5e4fa85006fe9817c224c3f480a34c7e5959fd700921c5" +dependencies = [ + "syn 2.0.32", +] + [[package]] name = "digest" version = "0.10.7" @@ -3746,23 +3758,23 @@ dependencies = [ [[package]] name = "migrations_internals" -version = "1.4.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b4fc84e4af020b837029e017966f86a1c2d5e83e64b589963d5047525995860" +checksum = "0f23f71580015254b020e856feac3df5878c2c7a8812297edd6c0a485ac9dada" dependencies = [ - "diesel", + "serde", + "toml 0.7.5", ] [[package]] name = "migrations_macros" -version = "1.4.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9753f12909fd8d923f75ae5c3258cae1ed3c8ec052e1b38c93c21a6d157f789c" +checksum = "cce3325ac70e67bbab5bd837a31cae01f1a6db64e0e744a33cb03a543469ef08" dependencies = [ "migrations_internals", "proc-macro2", "quote", - "syn 1.0.109", ] [[package]] diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.toml b/frontend/appflowy_tauri/src-tauri/Cargo.toml index a42be9b43e..7a83598b44 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.toml +++ b/frontend/appflowy_tauri/src-tauri/Cargo.toml @@ -20,7 +20,7 @@ bytes = "1.5.0" serde = "1.0.108" serde_json = "1.0.108" protobuf = { version = "2.28.0" } -diesel = { version = "1.4.8", features = ["sqlite", "chrono"] } +diesel = { version = "2.1.0", features = ["sqlite", "chrono", "r2d2"] } uuid = { version = "1.5.0", features = ["serde", "v4"] } serde_repr = "0.1" parking_lot = "0.12" diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index c3da8c7298..2b86b72076 100644 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -1373,37 +1373,49 @@ checksum = "d95203a6a50906215a502507c0f879a0ce7ff205a6111e2db2a5ef8e4bb92e43" [[package]] name = "diesel" -version = "1.4.8" +version = "2.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b28135ecf6b7d446b43e27e225622a038cc4e2930a1022f51cdb97ada19b8e4d" +checksum = "62c6fcf842f17f8c78ecf7c81d75c5ce84436b41ee07e03f490fbb5f5a8731d8" dependencies = [ - "byteorder", "chrono", "diesel_derives", "libsqlite3-sys", + "r2d2", + "time", ] [[package]] name = "diesel_derives" -version = "1.4.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45f5098f628d02a7a0f68ddba586fb61e80edec3bdc1be3b921f4ceec60858d3" +checksum = "ef8337737574f55a468005a83499da720f20c65586241ffea339db9ecdfd2b44" dependencies = [ + "diesel_table_macro_syntax", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.31", ] [[package]] name = "diesel_migrations" -version = "1.4.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf3cde8413353dc7f5d72fa8ce0b99a560a359d2c5ef1e5817ca731cd9008f4c" +checksum = "6036b3f0120c5961381b570ee20a02432d7e2d27ea60de9578799cf9156914ac" dependencies = [ + "diesel", "migrations_internals", "migrations_macros", ] +[[package]] +name = "diesel_table_macro_syntax" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc5557efc453706fed5e4fa85006fe9817c224c3f480a34c7e5959fd700921c5" +dependencies = [ + "syn 2.0.31", +] + [[package]] name = "digest" version = "0.10.7" @@ -1730,7 +1742,7 @@ dependencies = [ "similar 1.3.0", "syn 1.0.109", "tera", - "toml", + "toml 0.5.11", "walkdir", ] @@ -3199,23 +3211,23 @@ dependencies = [ [[package]] name = "migrations_internals" -version = "1.4.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b4fc84e4af020b837029e017966f86a1c2d5e83e64b589963d5047525995860" +checksum = "0f23f71580015254b020e856feac3df5878c2c7a8812297edd6c0a485ac9dada" dependencies = [ - "diesel", + "serde", + "toml 0.7.8", ] [[package]] name = "migrations_macros" -version = "1.4.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9753f12909fd8d923f75ae5c3258cae1ed3c8ec052e1b38c93c21a6d157f789c" +checksum = "cce3325ac70e67bbab5bd837a31cae01f1a6db64e0e744a33cb03a543469ef08" dependencies = [ "migrations_internals", "proc-macro2", "quote", - "syn 1.0.109", ] [[package]] @@ -3897,7 +3909,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" dependencies = [ - "toml", + "toml 0.5.11", ] [[package]] @@ -4925,6 +4937,15 @@ dependencies = [ "syn 2.0.31", ] +[[package]] +name = "serde_spanned" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +dependencies = [ + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -5655,6 +5676,40 @@ dependencies = [ "serde", ] +[[package]] +name = "toml" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap 2.1.0", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + [[package]] name = "tonic" version = "0.10.2" @@ -6324,6 +6379,15 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "winnow" +version = "0.5.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b5c3db89721d50d0e2a673f5043fc4722f76dcc352d7b1ab8b8288bed4ed2c5" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" version = "0.50.0" diff --git a/frontend/rust-lib/Cargo.toml b/frontend/rust-lib/Cargo.toml index aa65f3ffcb..0204a1f1a9 100644 --- a/frontend/rust-lib/Cargo.toml +++ b/frontend/rust-lib/Cargo.toml @@ -59,7 +59,7 @@ bytes = "1.5.0" serde_json = "1.0.108" serde = "1.0.108" protobuf = { version = "2.28.0" } -diesel = { version = "1.4.8", features = ["sqlite", "chrono"] } +diesel = { version = "2.1.0", features = ["sqlite", "chrono", "r2d2"] } uuid = { version = "1.5.0", features = ["serde", "v4"] } serde_repr = "0.1" parking_lot = "0.12" diff --git a/frontend/rust-lib/flowy-core/src/deps_resolve/collab_backup.rs b/frontend/rust-lib/flowy-core/src/deps_resolve/collab_backup.rs index d725ca30b0..3c396feb6b 100644 --- a/frontend/rust-lib/flowy-core/src/deps_resolve/collab_backup.rs +++ b/frontend/rust-lib/flowy-core/src/deps_resolve/collab_backup.rs @@ -36,7 +36,7 @@ impl RocksdbBackup for RocksdbBackupImpl { self .get_pool(uid) - .map(|pool| RocksdbBackupTableSql::create(row, &*pool.get()?))??; + .map(|pool| RocksdbBackupTableSql::create(row, &mut *pool.get()?))??; Ok(()) } @@ -48,15 +48,15 @@ impl RocksdbBackup for RocksdbBackupImpl { let pool = self.get_pool(uid)?; let row = pool .get() - .map(|conn| sql.first::(&*conn))??; + .map(|mut conn| sql.first::(&mut *conn))??; Ok(EncodedCollabV1::decode_from_bytes(&row.data)?) } } -#[derive(PartialEq, Clone, Debug, Queryable, Identifiable, Insertable, Associations)] -#[table_name = "rocksdb_backup"] -#[primary_key(object_id)] +#[derive(PartialEq, Clone, Debug, Queryable, Identifiable, Insertable)] +#[diesel(table_name = rocksdb_backup)] +#[diesel(primary_key(object_id))] struct RocksdbBackupRow { object_id: String, timestamp: i64, @@ -65,7 +65,7 @@ struct RocksdbBackupRow { struct RocksdbBackupTableSql; impl RocksdbBackupTableSql { - fn create(row: RocksdbBackupRow, conn: &SqliteConnection) -> Result<(), FlowyError> { + fn create(row: RocksdbBackupRow, conn: &mut SqliteConnection) -> Result<(), FlowyError> { let _ = replace_into(dsl::rocksdb_backup) .values(&row) .execute(conn)?; @@ -73,7 +73,7 @@ impl RocksdbBackupTableSql { } #[allow(dead_code)] - fn get_row(object_id: &str, conn: &SqliteConnection) -> Result { + fn get_row(object_id: &str, conn: &mut SqliteConnection) -> Result { let sql = dsl::rocksdb_backup .filter(dsl::object_id.eq(object_id)) .into_boxed(); diff --git a/frontend/rust-lib/flowy-core/src/deps_resolve/collab_deps.rs b/frontend/rust-lib/flowy-core/src/deps_resolve/collab_deps.rs index 8d7ec7adcb..71a50f46e9 100644 --- a/frontend/rust-lib/flowy-core/src/deps_resolve/collab_deps.rs +++ b/frontend/rust-lib/flowy-core/src/deps_resolve/collab_deps.rs @@ -21,8 +21,8 @@ impl SnapshotPersistence for SnapshotDBImpl { Some(user_session) => user_session .db_pool(uid) .and_then(|pool| Ok(pool.get()?)) - .and_then(|conn| { - CollabSnapshotTableSql::get_all_snapshots(object_id, &conn) + .and_then(|mut conn| { + CollabSnapshotTableSql::get_all_snapshots(object_id, &mut conn) .map(|rows| rows.into_iter().map(|row| row.into()).collect()) }) .unwrap_or_else(|_| vec![]), @@ -43,7 +43,7 @@ impl SnapshotPersistence for SnapshotDBImpl { .upgrade() .and_then(|user_session| user_session.db_pool(uid).ok()) { - let conn = pool + let mut conn = pool .get() .map_err(|e| PersistenceError::Internal(e.into()))?; @@ -58,7 +58,7 @@ impl SnapshotPersistence for SnapshotDBImpl { timestamp: timestamp(), data: snapshot_data, }, - &conn, + &mut conn, ) .map_err(|e| PersistenceError::Internal(e.into())); @@ -72,8 +72,8 @@ impl SnapshotPersistence for SnapshotDBImpl { } } -#[derive(PartialEq, Clone, Debug, Queryable, Identifiable, Insertable, Associations)] -#[table_name = "collab_snapshot"] +#[derive(PartialEq, Clone, Debug, Queryable, Identifiable, Insertable)] +#[diesel(table_name = collab_snapshot)] struct CollabSnapshotRow { id: String, object_id: String, @@ -95,7 +95,7 @@ impl From for CollabSnapshot { struct CollabSnapshotTableSql; impl CollabSnapshotTableSql { - fn create(row: CollabSnapshotRow, conn: &SqliteConnection) -> Result<(), FlowyError> { + fn create(row: CollabSnapshotRow, conn: &mut SqliteConnection) -> Result<(), FlowyError> { // Batch insert: https://diesel.rs/guides/all-about-inserts.html let values = ( dsl::id.eq(row.id), @@ -114,7 +114,7 @@ impl CollabSnapshotTableSql { fn get_all_snapshots( object_id: &str, - conn: &SqliteConnection, + conn: &mut SqliteConnection, ) -> Result, FlowyError> { let sql = dsl::collab_snapshot .filter(dsl::object_id.eq(object_id)) @@ -128,7 +128,10 @@ impl CollabSnapshotTableSql { } #[allow(dead_code)] - fn get_latest_snapshot(object_id: &str, conn: &SqliteConnection) -> Option { + fn get_latest_snapshot( + object_id: &str, + conn: &mut SqliteConnection, + ) -> Option { let sql = dsl::collab_snapshot .filter(dsl::object_id.eq(object_id)) .into_boxed(); @@ -143,7 +146,7 @@ impl CollabSnapshotTableSql { fn delete( object_id: &str, snapshot_ids: Option>, - conn: &SqliteConnection, + conn: &mut SqliteConnection, ) -> Result<(), FlowyError> { let mut sql = diesel::delete(dsl::collab_snapshot).into_boxed(); sql = sql.filter(dsl::object_id.eq(object_id)); diff --git a/frontend/rust-lib/flowy-sqlite/Cargo.toml b/frontend/rust-lib/flowy-sqlite/Cargo.toml index b6639960d5..da45d11167 100644 --- a/frontend/rust-lib/flowy-sqlite/Cargo.toml +++ b/frontend/rust-lib/flowy-sqlite/Cargo.toml @@ -7,8 +7,8 @@ edition = "2018" [dependencies] diesel.workspace = true -diesel_derives = { version = "1.4.1", features = ["sqlite"] } -diesel_migrations = { version = "1.4.0", features = ["sqlite"] } +diesel_derives = { version = "2.1.0", features = ["sqlite", "r2d2"] } +diesel_migrations = { version = "2.1.0", features = ["sqlite"] } tracing.workspace = true lazy_static = "1.4.0" serde.workspace = true @@ -16,8 +16,8 @@ serde_json.workspace = true anyhow.workspace = true parking_lot.workspace = true -r2d2 = "0.8.10" -libsqlite3-sys = { version = ">=0.8.0, <0.24.0", features = ["bundled"] } +r2d2 = ">= 0.8.2, < 0.9.0" +libsqlite3-sys = { version = ">=0.17.2, <0.28.0", features = ["bundled"] } scheduled-thread-pool = "0.2.6" error-chain = "=0.12.0" openssl = { version = "0.10.45", optional = true, features = ["vendored"] } diff --git a/frontend/rust-lib/flowy-sqlite/src/kv/kv.rs b/frontend/rust-lib/flowy-sqlite/src/kv/kv.rs index bcbd2e2e16..14794a0500 100644 --- a/frontend/rust-lib/flowy-sqlite/src/kv/kv.rs +++ b/frontend/rust-lib/flowy-sqlite/src/kv/kv.rs @@ -2,7 +2,7 @@ use std::path::Path; use ::diesel::{query_dsl::*, ExpressionMethods}; use anyhow::anyhow; -use diesel::{Connection, SqliteConnection}; +use diesel::sql_query; use serde::de::DeserializeOwned; use serde::Serialize; @@ -25,8 +25,8 @@ impl StorePreferences { let pool_config = PoolConfig::default(); let database = Database::new(root, DB_NAME, pool_config).unwrap(); - let conn = database.get_connection().unwrap(); - SqliteConnection::execute(&*conn, KV_SQL).unwrap(); + let mut conn = database.get_connection().unwrap(); + sql_query(KV_SQL).execute(&mut conn).unwrap(); tracing::trace!("Init StorePreferences with path: {}", root); Ok(Self { @@ -86,13 +86,13 @@ impl StorePreferences { } pub fn remove(&self, key: &str) { - if let Some(conn) = self + if let Some(mut conn) = self .database .as_ref() .and_then(|database| database.get_connection().ok()) { let sql = dsl::kv_table.filter(kv_table::key.eq(key)); - let _ = diesel::delete(sql).execute(&*conn); + let _ = diesel::delete(sql).execute(&mut *conn); } } @@ -103,30 +103,30 @@ impl StorePreferences { .and_then(|database| database.get_connection().ok()) { None => Err(anyhow!("StorePreferences is not initialized")), - Some(conn) => { + Some(mut conn) => { diesel::replace_into(kv_table::table) .values(KeyValue { key: key.to_string(), value, }) - .execute(&*conn)?; + .execute(&mut *conn)?; Ok(()) }, } } fn get_key_value(&self, key: &str) -> Option { - let conn = self.database.as_ref().unwrap().get_connection().ok()?; + let mut conn = self.database.as_ref().unwrap().get_connection().ok()?; dsl::kv_table .filter(kv_table::key.eq(key)) - .first::(&*conn) + .first::(&mut *conn) .ok() } } #[derive(Clone, Debug, Default, Queryable, Identifiable, Insertable, AsChangeset)] -#[table_name = "kv_table"] -#[primary_key(key)] +#[diesel(table_name = kv_table)] +#[diesel(primary_key(key))] pub struct KeyValue { pub key: String, pub value: Option, diff --git a/frontend/rust-lib/flowy-sqlite/src/lib.rs b/frontend/rust-lib/flowy-sqlite/src/lib.rs index 85982bb5e4..a052d7afe5 100644 --- a/frontend/rust-lib/flowy-sqlite/src/lib.rs +++ b/frontend/rust-lib/flowy-sqlite/src/lib.rs @@ -9,6 +9,7 @@ use std::{fmt::Debug, io, path::Path}; pub use diesel::*; pub use diesel_derives::*; +use diesel_migrations::{EmbeddedMigrations, MigrationHarness}; use crate::sqlite_impl::PoolConfig; pub use crate::sqlite_impl::{ConnectionPool, DBConnection, Database}; @@ -29,7 +30,7 @@ pub mod prelude { pub use crate::*; } -embed_migrations!("../flowy-sqlite/migrations/"); +pub const MIGRATIONS: EmbeddedMigrations = embed_migrations!("../flowy-sqlite/migrations/"); pub const DB_NAME: &str = "flowy-database.db"; pub fn init>(storage_path: P) -> Result { @@ -39,8 +40,10 @@ pub fn init>(storage_path: P) -> Result { } let pool_config = PoolConfig::default(); let database = Database::new(storage_path, DB_NAME, pool_config).map_err(as_io_error)?; - let conn = database.get_connection().map_err(as_io_error)?; - embedded_migrations::run(&*conn).map_err(as_io_error)?; + let mut conn = database.get_connection().map_err(as_io_error)?; + (*conn) + .run_pending_migrations(MIGRATIONS) + .map_err(|e| io::Error::new(io::ErrorKind::Other, format!("{:?}", e)))?; Ok(database) } diff --git a/frontend/rust-lib/flowy-sqlite/src/sqlite_impl/conn_ext.rs b/frontend/rust-lib/flowy-sqlite/src/sqlite_impl/conn_ext.rs index 90a55b82aa..b783a51500 100644 --- a/frontend/rust-lib/flowy-sqlite/src/sqlite_impl/conn_ext.rs +++ b/frontend/rust-lib/flowy-sqlite/src/sqlite_impl/conn_ext.rs @@ -1,26 +1,29 @@ use diesel::{ - dsl::sql, expression::SqlLiteral, query_dsl::LoadQuery, Connection, RunQueryDsl, SqliteConnection, + dsl::sql, expression::SqlLiteral, query_dsl::LoadQuery, sql_query, sql_types::SingleValue, + Connection, RunQueryDsl, SqliteConnection, }; use crate::sqlite_impl::errors::*; pub trait ConnectionExtension: Connection { - fn query(&self, query: &str) -> Result + fn query<'query, ST, T>(&mut self, query: &str) -> Result where - SqlLiteral: LoadQuery; + SqlLiteral: LoadQuery<'query, SqliteConnection, T>, + ST: SingleValue; - fn exec(&self, query: impl AsRef) -> Result; + fn exec(&mut self, query: impl AsRef) -> Result; } impl ConnectionExtension for SqliteConnection { - fn query(&self, query: &str) -> Result + fn query<'query, ST, T>(&mut self, query: &str) -> Result where - SqlLiteral: LoadQuery, + SqlLiteral: LoadQuery<'query, SqliteConnection, T>, + ST: SingleValue, { Ok(sql::(query).get_result(self)?) } - fn exec(&self, query: impl AsRef) -> Result { - Ok(SqliteConnection::execute(self, query.as_ref())?) + fn exec(&mut self, query: impl AsRef) -> Result { + Ok(sql_query(query.as_ref()).execute(self)?) } } diff --git a/frontend/rust-lib/flowy-sqlite/src/sqlite_impl/errors.rs b/frontend/rust-lib/flowy-sqlite/src/sqlite_impl/errors.rs index 031fe8b303..984f6feccc 100644 --- a/frontend/rust-lib/flowy-sqlite/src/sqlite_impl/errors.rs +++ b/frontend/rust-lib/flowy-sqlite/src/sqlite_impl/errors.rs @@ -11,7 +11,7 @@ error_chain! { } foreign_links { R2D2(::r2d2::Error); - Migrations(::diesel_migrations::RunMigrationsError); + Migrations(::diesel_migrations::MigrationError); Diesel(::diesel::result::Error); Connection(::diesel::ConnectionError); Io(::std::io::Error); diff --git a/frontend/rust-lib/flowy-sqlite/src/sqlite_impl/pool.rs b/frontend/rust-lib/flowy-sqlite/src/sqlite_impl/pool.rs index 8dc0eb3e6d..fd64a98508 100644 --- a/frontend/rust-lib/flowy-sqlite/src/sqlite_impl/pool.rs +++ b/frontend/rust-lib/flowy-sqlite/src/sqlite_impl/pool.rs @@ -1,6 +1,6 @@ use std::{sync::Arc, time::Duration}; -use diesel::{connection::Connection, SqliteConnection}; +use diesel::{connection::Connection, r2d2::R2D2Connection, SqliteConnection}; use r2d2::{CustomizeConnection, ManageConnection, Pool}; use scheduled_thread_pool::ScheduledThreadPool; @@ -94,7 +94,7 @@ impl ManageConnection for ConnectionManager { } fn is_valid(&self, conn: &mut Self::Connection) -> Result<()> { - Ok(conn.execute("SELECT 1").map(|_| ())?) + Ok(conn.ping()?) } fn has_broken(&self, _conn: &mut Self::Connection) -> bool { diff --git a/frontend/rust-lib/flowy-sqlite/src/sqlite_impl/pragma.rs b/frontend/rust-lib/flowy-sqlite/src/sqlite_impl/pragma.rs index 51830197c1..636c5cd09d 100644 --- a/frontend/rust-lib/flowy-sqlite/src/sqlite_impl/pragma.rs +++ b/frontend/rust-lib/flowy-sqlite/src/sqlite_impl/pragma.rs @@ -9,7 +9,7 @@ use std::{ use diesel::{ expression::SqlLiteral, query_dsl::load_dsl::LoadQuery, - sql_types::{Integer, Text}, + sql_types::{Integer, SingleValue, Text}, SqliteConnection, }; @@ -17,7 +17,12 @@ use crate::sqlite_impl::conn_ext::ConnectionExtension; use crate::sqlite_impl::errors::{Error, Result}; pub trait PragmaExtension: ConnectionExtension { - fn pragma(&self, key: &str, val: D, schema: Option<&str>) -> Result<()> { + fn pragma( + &mut self, + key: &str, + val: D, + schema: Option<&str>, + ) -> Result<()> { let query = match schema { Some(schema) => format!("PRAGMA {}.{} = '{}'", schema, key, val), None => format!("PRAGMA {} = '{}'", key, val), @@ -27,14 +32,15 @@ pub trait PragmaExtension: ConnectionExtension { Ok(()) } - fn pragma_ret( - &self, + fn pragma_ret<'query, ST, T, D: std::fmt::Display>( + &mut self, key: &str, val: D, schema: Option<&str>, ) -> Result where - SqlLiteral: LoadQuery, + SqlLiteral: LoadQuery<'query, SqliteConnection, T>, + ST: SingleValue, { let query = match schema { Some(schema) => format!("PRAGMA {}.{} = '{}'", schema, key, val), @@ -44,9 +50,10 @@ pub trait PragmaExtension: ConnectionExtension { self.query::(&query) } - fn pragma_get(&self, key: &str, schema: Option<&str>) -> Result + fn pragma_get<'query, ST, T>(&mut self, key: &str, schema: Option<&str>) -> Result where - SqlLiteral: LoadQuery, + SqlLiteral: LoadQuery<'query, SqliteConnection, T>, + ST: SingleValue, { let query = match schema { Some(schema) => format!("PRAGMA {}.{}", schema, key), @@ -56,33 +63,37 @@ pub trait PragmaExtension: ConnectionExtension { self.query::(&query) } - fn pragma_set_busy_timeout(&self, timeout_ms: i32) -> Result { + fn pragma_set_busy_timeout(&mut self, timeout_ms: i32) -> Result { self.pragma_ret::("busy_timeout", timeout_ms, None) } - fn pragma_get_busy_timeout(&self) -> Result { + fn pragma_get_busy_timeout(&mut self) -> Result { self.pragma_get::("busy_timeout", None) } - fn pragma_set_journal_mode(&self, mode: SQLiteJournalMode, schema: Option<&str>) -> Result { + fn pragma_set_journal_mode( + &mut self, + mode: SQLiteJournalMode, + schema: Option<&str>, + ) -> Result { self.pragma_ret::("journal_mode", mode, schema) } - fn pragma_get_journal_mode(&self, schema: Option<&str>) -> Result { + fn pragma_get_journal_mode(&mut self, schema: Option<&str>) -> Result { self .pragma_get::("journal_mode", schema)? .parse() } fn pragma_set_synchronous( - &self, + &mut self, synchronous: SQLiteSynchronous, schema: Option<&str>, ) -> Result<()> { self.pragma("synchronous", synchronous as u8, schema) } - fn pragma_get_synchronous(&self, schema: Option<&str>) -> Result { + fn pragma_get_synchronous(&mut self, schema: Option<&str>) -> Result { self .pragma_get::("synchronous", schema)? .try_into() diff --git a/frontend/rust-lib/flowy-user/Cargo.toml b/frontend/rust-lib/flowy-user/Cargo.toml index dce4628ee1..ca3cc39412 100644 --- a/frontend/rust-lib/flowy-user/Cargo.toml +++ b/frontend/rust-lib/flowy-user/Cargo.toml @@ -32,7 +32,7 @@ serde_repr.workspace = true protobuf.workspace = true lazy_static = "1.4.0" diesel.workspace = true -diesel_derives = { version = "1.4.1", features = ["sqlite"] } +diesel_derives = { version = "2.1.0", features = ["sqlite", "r2d2"] } once_cell = "1.17.1" parking_lot.workspace = true strum = "0.25" diff --git a/frontend/rust-lib/flowy-user/src/manager.rs b/frontend/rust-lib/flowy-user/src/manager.rs index 7f7f1ab025..6007a73541 100644 --- a/frontend/rust-lib/flowy-user/src/manager.rs +++ b/frontend/rust-lib/flowy-user/src/manager.rs @@ -533,7 +533,7 @@ impl UserManager { pub async fn get_user_profile_from_disk(&self, uid: i64) -> Result { let user: UserProfile = user_table::dsl::user_table .filter(user_table::id.eq(&uid.to_string())) - .first::(&*(self.db_connection(uid)?)) + .first::(&mut *(self.db_connection(uid)?)) .map_err(|err| { FlowyError::record_not_found().with_context(format!( "Can't find the user profile for user id: {}, error: {:?}", @@ -639,15 +639,15 @@ impl UserManager { } async fn save_user(&self, uid: i64, user: UserTable) -> Result<(), FlowyError> { - let conn = self.db_connection(uid)?; - conn.immediate_transaction(|| { + let mut conn = self.db_connection(uid)?; + conn.immediate_transaction(|conn| { // delete old user if exists diesel::delete(user_table::dsl::user_table.filter(user_table::dsl::id.eq(&user.id))) - .execute(&*conn)?; + .execute(conn)?; let _ = diesel::insert_into(user_table::table) .values(user) - .execute(&*conn)?; + .execute(conn)?; Ok::<(), FlowyError>(()) })?; @@ -858,11 +858,11 @@ fn upsert_user_profile_change( "Update user profile with changeset: {:?}", changeset ); - let conn = pool.get()?; - diesel_update_table!(user_table, changeset, &*conn); + let mut conn = pool.get()?; + diesel_update_table!(user_table, changeset, &mut *conn); let user: UserProfile = user_table::dsl::user_table .filter(user_table::id.eq(&uid.to_string())) - .first::(&*conn)? + .first::(&mut *conn)? .into(); send_notification(&uid.to_string(), UserNotification::DidUpdateUserProfile) .payload(UserProfilePB::from(user)) diff --git a/frontend/rust-lib/flowy-user/src/migrations/migration.rs b/frontend/rust-lib/flowy-user/src/migrations/migration.rs index dee59f58c5..3ea7969d23 100644 --- a/frontend/rust-lib/flowy-user/src/migrations/migration.rs +++ b/frontend/rust-lib/flowy-user/src/migrations/migration.rs @@ -49,8 +49,8 @@ impl UserLocalDataMigration { authenticator: &Authenticator, ) -> FlowyResult> { let mut applied_migrations = vec![]; - let conn = self.sqlite_pool.get()?; - let record = get_all_records(&conn)?; + let mut conn = self.sqlite_pool.get()?; + let record = get_all_records(&mut conn)?; let mut duplicated_names = vec![]; for migration in migrations { if !record @@ -61,7 +61,7 @@ impl UserLocalDataMigration { if !duplicated_names.contains(&migration_name) { migration.run(&self.session, &self.collab_db, authenticator)?; applied_migrations.push(migration.name().to_string()); - save_record(&conn, &migration_name); + save_record(&mut conn, &migration_name); duplicated_names.push(migration_name); } else { tracing::error!("Duplicated migration name: {}", migration_name); @@ -83,7 +83,7 @@ pub trait UserDataMigration { ) -> FlowyResult<()>; } -fn save_record(conn: &SqliteConnection, migration_name: &str) { +fn save_record(conn: &mut SqliteConnection, migration_name: &str) { let new_record = NewUserDataMigrationRecord { migration_name: migration_name.to_string(), }; @@ -93,7 +93,7 @@ fn save_record(conn: &SqliteConnection, migration_name: &str) { .expect("Error inserting new migration record"); } -fn get_all_records(conn: &SqliteConnection) -> FlowyResult> { +fn get_all_records(conn: &mut SqliteConnection) -> FlowyResult> { Ok( user_data_migration_records::table .load::(conn) @@ -102,7 +102,7 @@ fn get_all_records(conn: &SqliteConnection) -> FlowyResult, uid: i64) -> Result { let uid = uid.to_string(); - let conn = pool.get()?; + let mut conn = pool.get()?; let user = dsl::user_table .filter(user_table::id.eq(&uid)) - .first::(&*conn)?; + .first::(&mut *conn)?; Ok(user.into()) } @@ -160,10 +160,10 @@ pub fn get_user_workspace( pool: &Arc, uid: i64, ) -> Result, FlowyError> { - let conn = pool.get()?; + let mut conn = pool.get()?; let row = user_workspace_table::dsl::user_workspace_table .filter(user_workspace_table::uid.eq(uid)) - .first::(&*conn)?; + .first::(&mut *conn)?; Ok(Some(UserWorkspace::from(row))) } diff --git a/frontend/rust-lib/flowy-user/src/services/user_sql.rs b/frontend/rust-lib/flowy-user/src/services/user_sql.rs index 9b1a252118..e18fef33e3 100644 --- a/frontend/rust-lib/flowy-user/src/services/user_sql.rs +++ b/frontend/rust-lib/flowy-user/src/services/user_sql.rs @@ -7,7 +7,7 @@ use flowy_user_deps::entities::*; /// The order of the fields in the struct must be the same as the order of the fields in the table. /// Check out the [schema.rs] for table schema. #[derive(Clone, Default, Queryable, Identifiable, Insertable)] -#[table_name = "user_table"] +#[diesel(table_name = user_table)] pub struct UserTable { pub(crate) id: String, pub(crate) name: String, @@ -68,7 +68,7 @@ impl From for UserProfile { } #[derive(AsChangeset, Identifiable, Default, Debug)] -#[table_name = "user_table"] +#[diesel(table_name = user_table)] pub struct UserTableChangeset { pub id: String, pub workspace: Option, // deprecated diff --git a/frontend/rust-lib/flowy-user/src/services/user_workspace.rs b/frontend/rust-lib/flowy-user/src/services/user_workspace.rs index 3d3c6ff93d..6c72aefec8 100644 --- a/frontend/rust-lib/flowy-user/src/services/user_workspace.rs +++ b/frontend/rust-lib/flowy-user/src/services/user_workspace.rs @@ -91,19 +91,19 @@ impl UserManager { } pub fn get_user_workspace(&self, uid: i64, workspace_id: &str) -> Option { - let conn = self.db_connection(uid).ok()?; + let mut conn = self.db_connection(uid).ok()?; let row = user_workspace_table::dsl::user_workspace_table .filter(user_workspace_table::id.eq(workspace_id)) - .first::(&*conn) + .first::(&mut *conn) .ok()?; Some(UserWorkspace::from(row)) } pub fn get_all_user_workspaces(&self, uid: i64) -> FlowyResult> { - let conn = self.db_connection(uid)?; + let mut conn = self.db_connection(uid)?; let rows = user_workspace_table::dsl::user_workspace_table .filter(user_workspace_table::uid.eq(uid)) - .load::(&*conn)?; + .load::(&mut *conn)?; if let Ok(service) = self.cloud_services.get_user_service() { if let Ok(pool) = self.db_pool(uid) { @@ -150,8 +150,8 @@ pub fn save_user_workspaces( .flat_map(|user_workspace| UserWorkspaceTable::try_from((uid, user_workspace)).ok()) .collect::>(); - let conn = pool.get()?; - conn.immediate_transaction(|| { + let mut conn = pool.get()?; + conn.immediate_transaction(|conn| { for user_workspace in user_workspaces { if let Err(err) = diesel::update( user_workspace_table::dsl::user_workspace_table @@ -162,12 +162,12 @@ pub fn save_user_workspaces( user_workspace_table::created_at.eq(&user_workspace.created_at), user_workspace_table::database_storage_id.eq(&user_workspace.database_storage_id), )) - .execute(&*conn) + .execute(conn) .and_then(|rows| { if rows == 0 { let _ = diesel::insert_into(user_workspace_table::table) .values(user_workspace) - .execute(&*conn)?; + .execute(conn)?; } Ok(()) }) { diff --git a/frontend/rust-lib/flowy-user/src/services/workspace_sql.rs b/frontend/rust-lib/flowy-user/src/services/workspace_sql.rs index 457fd24d9a..1fd5b1b054 100644 --- a/frontend/rust-lib/flowy-user/src/services/workspace_sql.rs +++ b/frontend/rust-lib/flowy-user/src/services/workspace_sql.rs @@ -7,7 +7,7 @@ use flowy_sqlite::schema::user_workspace_table; use flowy_user_deps::entities::UserWorkspace; #[derive(Clone, Default, Queryable, Identifiable, Insertable)] -#[table_name = "user_workspace_table"] +#[diesel(table_name = user_workspace_table)] pub struct UserWorkspaceTable { pub id: String, pub name: String,