From 2d75dc3c98b951d6fe5576a04abcb43d51114af4 Mon Sep 17 00:00:00 2001 From: Paul Morris <10599524+pmorris-dev@users.noreply.github.com> Date: Mon, 2 Feb 2026 08:34:23 -0500 Subject: [PATCH] fix: expose necessary types for Rust API usage --- README.md | 45 ++++++++++++------- .../sqlx-sqlite-conn-mgr/migrations/.gitkeep | 2 + src/lib.rs | 4 +- src/wrapper.rs | 27 +++++++++-- 4 files changed, 59 insertions(+), 19 deletions(-) create mode 100644 crates/sqlx-sqlite-conn-mgr/migrations/.gitkeep diff --git a/README.md b/README.md index 0b384f1..da35bde 100644 --- a/README.md +++ b/README.md @@ -571,35 +571,50 @@ tx.commit().await?; ### Cross-Database Operations -Attach other databases for cross-database queries: +Attach other databases for cross-database queries. For Rust API usage, you need to load +both databases first, then create `AttachedSpec` instances using their inner database +references: ```rust -use tauri_plugin_sqlite::AttachedDatabaseSpec; +use tauri_plugin_sqlite::{DatabaseWrapper, AttachedSpec, AttachedMode}; +use std::sync::Arc; + +// Load both databases +let main_db = DatabaseWrapper::load("/path/to/main.db".into(), None).await?; +let stats_db = DatabaseWrapper::load("/path/to/stats.db".into(), None).await?; + +// Create attached spec using the inner database reference +let stats_spec = AttachedSpec { + database: Arc::clone(stats_db.inner()), + schema_name: "stats".to_string(), + mode: AttachedMode::ReadWrite, +}; // Simple transaction with attached database -let results = db.execute_transaction(vec![ +let results = main_db.execute_transaction(vec![ ("INSERT INTO main.orders (user_id) VALUES (?)", vec![json!(1)]), ("UPDATE stats.order_count SET count = count + 1", vec![]), ]) -.attach(vec![AttachedDatabaseSpec { - database_path: "stats.db".into(), - schema_name: "stats".into(), - mode: tauri_plugin_sqlite::AttachedDatabaseMode::ReadWrite, -}]) +.attach(vec![stats_spec]) .await?; - println!("Cross-database transaction completed: {} statements", results.len()); // Interruptible transaction with attached database +// Load the inventory database +let inventory_db = DatabaseWrapper::load("/path/to/inventory.db".into(), None).await?; + +// Create spec for inventory database +let inv_spec = AttachedSpec { + database: Arc::clone(inventory_db.inner()), + schema_name: "inv".to_string(), + mode: AttachedMode::ReadWrite, +}; + // Assuming product_id is defined in your application context let product_id = 789; -let _tx = db.begin_interruptible_transaction() - .attach(vec![AttachedDatabaseSpec { - database_path: "inventory.db".into(), - schema_name: "inv".into(), - mode: tauri_plugin_sqlite::AttachedDatabaseMode::ReadWrite, - }]) +let _tx = main_db.begin_interruptible_transaction() + .attach(vec![inv_spec]) .execute(vec![ ("UPDATE inv.stock SET quantity = quantity - ? WHERE product_id = ?", vec![json!(1), json!(product_id)]), ]) diff --git a/crates/sqlx-sqlite-conn-mgr/migrations/.gitkeep b/crates/sqlx-sqlite-conn-mgr/migrations/.gitkeep new file mode 100644 index 0000000..11a41ae --- /dev/null +++ b/crates/sqlx-sqlite-conn-mgr/migrations/.gitkeep @@ -0,0 +1,2 @@ +# Placeholder migrations directory for doctest compilation +# sqlx::migrate! requires a migrations directory to exist at compile time diff --git a/src/lib.rs b/src/lib.rs index 36424d5..d479bb4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,7 +15,9 @@ mod transactions; mod wrapper; pub use error::{Error, Result}; -pub use sqlx_sqlite_conn_mgr::Migrator as SqliteMigrator; +pub use sqlx_sqlite_conn_mgr::{ + AttachedMode, AttachedSpec, Migrator as SqliteMigrator, SqliteDatabaseConfig, +}; pub use transactions::{ActiveInterruptibleTransactions, ActiveRegularTransactions, Statement}; pub use wrapper::{ DatabaseWrapper, InterruptibleTransaction, InterruptibleTransactionBuilder, diff --git a/src/wrapper.rs b/src/wrapper.rs index fb61690..ab5cea7 100644 --- a/src/wrapper.rs +++ b/src/wrapper.rs @@ -29,7 +29,28 @@ pub struct DatabaseWrapper { impl DatabaseWrapper { /// Get the inner Arc for advanced usage - pub(crate) fn inner(&self) -> &Arc { + /// + /// This is useful when you need to create `AttachedSpec` instances for cross-database + /// operations with interruptible transactions. + /// + /// # Example + /// + /// ```no_run + /// # use tauri_plugin_sqlite::{DatabaseWrapper, AttachedSpec, AttachedMode}; + /// # use std::sync::Arc; + /// # async fn example() -> Result<(), Box> { + /// # let db1: DatabaseWrapper = todo!(); + /// # let db2: DatabaseWrapper = todo!(); + /// // Create an attached spec using the inner database reference + /// let spec = AttachedSpec { + /// database: Arc::clone(db2.inner()), + /// schema_name: "other".to_string(), + /// mode: AttachedMode::ReadOnly, + /// }; + /// # Ok(()) + /// # } + /// ``` + pub fn inner(&self) -> &Arc { &self.inner } @@ -50,7 +71,7 @@ impl DatabaseWrapper { /// # Example /// /// ```no_run - /// # use tauri_plugin_sqlite::DatabaseWrapper; + /// # use tauri_plugin_sqlite::{DatabaseWrapper, Statement}; /// # use serde_json::json; /// # async fn example() -> Result<(), Box> { /// # let db: DatabaseWrapper = todo!(); @@ -64,7 +85,7 @@ impl DatabaseWrapper { /// /// // Continue with more work /// let results = tx.continue_with(vec![ - /// crate::transactions::Statement { + /// Statement { /// query: "INSERT INTO items (name) VALUES (?)".to_string(), /// values: vec![json!("item1")], /// }