From 2477559fffb45e9799efde7dc7c1045bc409fefe Mon Sep 17 00:00:00 2001 From: Huakun Shen Date: Thu, 20 Mar 2025 08:00:10 -0400 Subject: [PATCH 1/4] feat(sql): add support for SQLite pragma and encryption pragmas - Introduced `libsqlite3-sys` dependency for SQLite support. - Updated the `load` method to accept optional pragmas for database connections. - Enhanced the JavaScript API to demonstrate loading databases with encryption keys and custom pragmas. - Added VSCode settings for Rust analyzer to enable SQLite feature, to facilitate development. - Updated Rust code to handle SQLite options and pragmas in the database connection logic. --- Cargo.lock | 1 + plugins/sql/.vscode/settings.json | 3 ++ plugins/sql/Cargo.toml | 3 +- plugins/sql/api-iife.js | 2 +- plugins/sql/guest-js/index.ts | 21 ++++++++++-- plugins/sql/src/commands.rs | 54 +++++++++++++++++++++++++++++++ plugins/sql/src/lib.rs | 14 ++++++++ plugins/sql/src/wrapper.rs | 36 ++++++++++++++++++--- 8 files changed, 126 insertions(+), 8 deletions(-) create mode 100644 plugins/sql/.vscode/settings.json diff --git a/Cargo.lock b/Cargo.lock index 249f95b0..7f6417b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6906,6 +6906,7 @@ version = "2.2.0" dependencies = [ "futures-core", "indexmap 2.7.0", + "libsqlite3-sys", "log", "serde", "serde_json", diff --git a/plugins/sql/.vscode/settings.json b/plugins/sql/.vscode/settings.json new file mode 100644 index 00000000..95ee6b2e --- /dev/null +++ b/plugins/sql/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "rust-analyzer.cargo.features": ["sqlite"] +} diff --git a/plugins/sql/Cargo.toml b/plugins/sql/Cargo.toml index 0449a4be..5cd27a85 100644 --- a/plugins/sql/Cargo.toml +++ b/plugins/sql/Cargo.toml @@ -36,8 +36,9 @@ time = "0.3" tokio = { version = "1", features = ["sync"] } indexmap = { version = "2", features = ["serde"] } +libsqlite3-sys = { version = "0.30.1", features = ["bundled-sqlcipher"] } + [features] sqlite = ["sqlx/sqlite", "sqlx/runtime-tokio"] mysql = ["sqlx/mysql", "sqlx/runtime-tokio-rustls"] postgres = ["sqlx/postgres", "sqlx/runtime-tokio-rustls"] -# TODO: bundled-cipher etc diff --git a/plugins/sql/api-iife.js b/plugins/sql/api-iife.js index a30f68d9..e5765f1b 100644 --- a/plugins/sql/api-iife.js +++ b/plugins/sql/api-iife.js @@ -1 +1 @@ -if("__TAURI__"in window){var __TAURI_PLUGIN_SQL__=function(){"use strict";async function e(e,t={},s){return window.__TAURI_INTERNALS__.invoke(e,t,s)}"function"==typeof SuppressedError&&SuppressedError;class t{constructor(e){this.path=e}static async load(s){const n=await e("plugin:sql|load",{db:s});return new t(n)}static get(e){return new t(e)}async execute(t,s){const[n,r]=await e("plugin:sql|execute",{db:this.path,query:t,values:s??[]});return{lastInsertId:r,rowsAffected:n}}async select(t,s){return await e("plugin:sql|select",{db:this.path,query:t,values:s??[]})}async close(t){return await e("plugin:sql|close",{db:t})}}return t}();Object.defineProperty(window.__TAURI__,"sql",{value:__TAURI_PLUGIN_SQL__})} +if("__TAURI__"in window){var __TAURI_PLUGIN_SQL__=function(){"use strict";async function e(e,t={},s){return window.__TAURI_INTERNALS__.invoke(e,t,s)}"function"==typeof SuppressedError&&SuppressedError;class t{constructor(e){this.path=e}static async load(s,n){const r=await e("plugin:sql|load",{db:s,pragmas:n?.pragmas});return new t(r)}static get(e){return new t(e)}async execute(t,s){const[n,r]=await e("plugin:sql|execute",{db:this.path,query:t,values:s??[]});return{lastInsertId:r,rowsAffected:n}}async select(t,s){return await e("plugin:sql|select",{db:this.path,query:t,values:s??[]})}async close(t){return await e("plugin:sql|close",{db:t})}}return t}();Object.defineProperty(window.__TAURI__,"sql",{value:__TAURI_PLUGIN_SQL__})} diff --git a/plugins/sql/guest-js/index.ts b/plugins/sql/guest-js/index.ts index 11d39e70..f778e416 100644 --- a/plugins/sql/guest-js/index.ts +++ b/plugins/sql/guest-js/index.ts @@ -42,12 +42,29 @@ export default class Database { * * @example * ```ts + * // Basic connection * const db = await Database.load("sqlite:test.db"); + * + * // With encryption key + * const db = await Database.load("sqlite:encrypted.db", { + * pragmas: { "key": "encryption_key" } + * }); + * + * // With pragmas + * const db = await Database.load("sqlite:test.db", { + * pragmas: { "journal_mode": "WAL", "foreign_keys": "ON" } + * }); * ``` */ - static async load(path: string): Promise { + static async load( + path: string, + options?: { + pragmas?: Record + } + ): Promise { const _path = await invoke('plugin:sql|load', { - db: path + db: path, + pragmas: options?.pragmas }) return new Database(_path) diff --git a/plugins/sql/src/commands.rs b/plugins/sql/src/commands.rs index 760d00b2..0cff4a6b 100644 --- a/plugins/sql/src/commands.rs +++ b/plugins/sql/src/commands.rs @@ -7,8 +7,14 @@ use serde_json::Value as JsonValue; use sqlx::migrate::Migrator; use tauri::{command, AppHandle, Runtime, State}; +#[cfg(feature = "sqlite")] +use std::collections::HashMap; + use crate::{DbInstances, DbPool, Error, LastInsertId, Migrations}; +#[cfg(feature = "sqlite")] +use crate::SqliteOptions; +#[cfg(not(feature = "sqlite"))] #[command] pub(crate) async fn load( app: AppHandle, @@ -28,6 +34,40 @@ pub(crate) async fn load( Ok(db) } +#[cfg(feature = "sqlite")] +#[command] +pub(crate) async fn load( + app: AppHandle, + db_instances: State<'_, DbInstances>, + migrations: State<'_, Migrations>, + db: String, + pragmas: Option>, +) -> Result { + let sqlite_options = if db.starts_with("sqlite:") { + let mut options = SqliteOptions::default(); + + // Apply pragmas if provided + if let Some(provided_pragmas) = pragmas { + options.pragmas.extend(provided_pragmas); + } + + Some(options) + } else { + None + }; + + let pool = DbPool::connect(&db, &app, sqlite_options).await?; + + if let Some(migrations) = migrations.0.lock().await.remove(&db) { + let migrator = Migrator::new(migrations).await?; + pool.migrate(&migrator).await?; + } + + db_instances.0.write().await.insert(db.clone(), pool); + + Ok(db) +} + /// Allows the database connection(s) to be closed; if no database /// name is passed in then _all_ database connection pools will be /// shut down. @@ -78,3 +118,17 @@ pub(crate) async fn select( let db = instances.get(&db).ok_or(Error::DatabaseNotLoaded(db))?; db.select(query, values).await } + +// #[command] +// pub(crate) async fn query( +// db_instances: State<'_, DbInstances>, +// db: String, +// query: String, +// values: Vec, +// ) -> Result>, crate::Error> { +// let instances = db_instances.0.read().await; + +// let db = instances.get(&db).ok_or(Error::DatabaseNotLoaded(db))?; +// db. +// // db.select(query, values).await +// } diff --git a/plugins/sql/src/lib.rs b/plugins/sql/src/lib.rs index 56b2a3a6..ca2d1bfc 100644 --- a/plugins/sql/src/lib.rs +++ b/plugins/sql/src/lib.rs @@ -16,6 +16,8 @@ mod wrapper; pub use error::Error; pub use wrapper::DbPool; +#[cfg(feature = "sqlite")] +pub use wrapper::SqliteOptions; use futures_core::future::BoxFuture; use serde::{Deserialize, Serialize}; @@ -23,6 +25,8 @@ use sqlx::{ error::BoxDynError, migrate::{Migration as SqlxMigration, MigrationSource, MigrationType, Migrator}, }; +#[cfg(feature = "sqlite")] +use sqlx::sqlite::SqliteConnectOptions; use tauri::{ plugin::{Builder as PluginBuilder, TauriPlugin}, Manager, RunEvent, Runtime, @@ -34,6 +38,9 @@ use std::collections::HashMap; #[derive(Default)] pub struct DbInstances(pub RwLock>); +#[cfg(feature = "sqlite")] +struct SqlLiteOptionStore(Mutex>); + #[derive(Serialize)] #[serde(untagged)] pub(crate) enum LastInsertId { @@ -137,6 +144,9 @@ impl Builder { pub fn build(mut self) -> TauriPlugin> { PluginBuilder::>::new("sql") .invoke_handler(tauri::generate_handler![ + #[cfg(feature = "sqlite")] + commands::load, + #[cfg(not(feature = "sqlite"))] commands::load, commands::execute, commands::select, @@ -150,6 +160,10 @@ impl Builder { let mut lock = instances.0.write().await; for db in config.preload { + #[cfg(feature = "sqlite")] + let pool = DbPool::connect(&db, app, None).await?; + + #[cfg(not(feature = "sqlite"))] let pool = DbPool::connect(&db, app).await?; if let Some(migrations) = diff --git a/plugins/sql/src/wrapper.rs b/plugins/sql/src/wrapper.rs index d47b2d1c..e5348ec6 100644 --- a/plugins/sql/src/wrapper.rs +++ b/plugins/sql/src/wrapper.rs @@ -4,9 +4,13 @@ #[cfg(feature = "sqlite")] use std::fs::create_dir_all; +#[cfg(feature = "sqlite")] +use std::collections::HashMap; use indexmap::IndexMap; use serde_json::Value as JsonValue; +#[cfg(feature = "sqlite")] +use sqlx::sqlite::SqliteConnectOptions; #[cfg(any(feature = "sqlite", feature = "mysql", feature = "postgres"))] use sqlx::{migrate::MigrateDatabase, Column, Executor, Pool, Row}; #[cfg(any(feature = "sqlite", feature = "mysql", feature = "postgres"))] @@ -33,6 +37,20 @@ pub enum DbPool { None, } +#[cfg(feature = "sqlite")] +pub struct SqliteOptions { + pub pragmas: HashMap, +} + +#[cfg(feature = "sqlite")] +impl Default for SqliteOptions { + fn default() -> Self { + Self { + pragmas: HashMap::new(), + } + } +} + // public methods /* impl DbPool { /// Get the inner Sqlite Pool. Returns None for MySql and Postgres pools. @@ -68,6 +86,7 @@ impl DbPool { pub(crate) async fn connect( conn_url: &str, _app: &AppHandle, + #[cfg(feature = "sqlite")] sqlite_options: Option, ) -> Result { match conn_url .split_once(':') @@ -82,13 +101,22 @@ impl DbPool { .expect("No App config path was found!"); create_dir_all(&app_path).expect("Couldn't create app config dir"); - let conn_url = &path_mapper(app_path, conn_url); + let filename = conn_url.split_once(':').unwrap().1; - if !Sqlite::database_exists(conn_url).await.unwrap_or(false) { - Sqlite::create_database(conn_url).await?; + let mut options = SqliteConnectOptions::new() + .filename(filename) + .create_if_missing(true); + + // Apply pragmas if provided + if let Some(sqlite_opts) = sqlite_options { + for (pragma_name, pragma_value) in sqlite_opts.pragmas { + options = options.pragma(pragma_name, pragma_value); + } } - Ok(Self::Sqlite(Pool::connect(conn_url).await?)) + + // Connect with options (which includes create_if_missing) + Ok(Self::Sqlite(Pool::connect_with(options).await?)) } #[cfg(feature = "mysql")] "mysql" => { From 65a77b73d5e81b71faf130242f5b7c7230556ba4 Mon Sep 17 00:00:00 2001 From: Huakun Shen Date: Fri, 21 Mar 2025 00:18:15 -0400 Subject: [PATCH 2/4] feat(sql): support multi sql features --- plugins/sql/.vscode/settings.json | 2 +- plugins/sql/api-iife.js | 2 +- plugins/sql/guest-js/index.ts | 6 ++-- plugins/sql/src/commands.rs | 47 ++----------------------------- plugins/sql/src/lib.rs | 10 +------ plugins/sql/src/wrapper.rs | 39 +++++++++++++++++++------ 6 files changed, 40 insertions(+), 66 deletions(-) diff --git a/plugins/sql/.vscode/settings.json b/plugins/sql/.vscode/settings.json index 95ee6b2e..b12ccd3d 100644 --- a/plugins/sql/.vscode/settings.json +++ b/plugins/sql/.vscode/settings.json @@ -1,3 +1,3 @@ { - "rust-analyzer.cargo.features": ["sqlite"] + "rust-analyzer.cargo.features": ["mysql", "postgres", "sqlite"] } diff --git a/plugins/sql/api-iife.js b/plugins/sql/api-iife.js index e5765f1b..86daa539 100644 --- a/plugins/sql/api-iife.js +++ b/plugins/sql/api-iife.js @@ -1 +1 @@ -if("__TAURI__"in window){var __TAURI_PLUGIN_SQL__=function(){"use strict";async function e(e,t={},s){return window.__TAURI_INTERNALS__.invoke(e,t,s)}"function"==typeof SuppressedError&&SuppressedError;class t{constructor(e){this.path=e}static async load(s,n){const r=await e("plugin:sql|load",{db:s,pragmas:n?.pragmas});return new t(r)}static get(e){return new t(e)}async execute(t,s){const[n,r]=await e("plugin:sql|execute",{db:this.path,query:t,values:s??[]});return{lastInsertId:r,rowsAffected:n}}async select(t,s){return await e("plugin:sql|select",{db:this.path,query:t,values:s??[]})}async close(t){return await e("plugin:sql|close",{db:t})}}return t}();Object.defineProperty(window.__TAURI__,"sql",{value:__TAURI_PLUGIN_SQL__})} +if("__TAURI__"in window){var __TAURI_PLUGIN_SQL__=function(){"use strict";async function t(t,e={},s){return window.__TAURI_INTERNALS__.invoke(t,e,s)}"function"==typeof SuppressedError&&SuppressedError;class e{constructor(t){this.path=t}static async load(s,n){const r=await t("plugin:sql|load",{db:s,options:n});return new e(r)}static get(t){return new e(t)}async execute(e,s){const[n,r]=await t("plugin:sql|execute",{db:this.path,query:e,values:s??[]});return{lastInsertId:r,rowsAffected:n}}async select(e,s){return await t("plugin:sql|select",{db:this.path,query:e,values:s??[]})}async close(e){return await t("plugin:sql|close",{db:e})}}return e}();Object.defineProperty(window.__TAURI__,"sql",{value:__TAURI_PLUGIN_SQL__})} diff --git a/plugins/sql/guest-js/index.ts b/plugins/sql/guest-js/index.ts index f778e416..cba9928e 100644 --- a/plugins/sql/guest-js/index.ts +++ b/plugins/sql/guest-js/index.ts @@ -59,12 +59,14 @@ export default class Database { static async load( path: string, options?: { - pragmas?: Record + sqlite?: { + pragmas?: Record + } } ): Promise { const _path = await invoke('plugin:sql|load', { db: path, - pragmas: options?.pragmas + options }) return new Database(_path) diff --git a/plugins/sql/src/commands.rs b/plugins/sql/src/commands.rs index 0cff4a6b..ef6eaf49 100644 --- a/plugins/sql/src/commands.rs +++ b/plugins/sql/src/commands.rs @@ -2,62 +2,21 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT +use crate::{wrapper::ConnectionOptions, DbInstances, DbPool, Error, LastInsertId, Migrations}; use indexmap::IndexMap; use serde_json::Value as JsonValue; use sqlx::migrate::Migrator; use tauri::{command, AppHandle, Runtime, State}; -#[cfg(feature = "sqlite")] -use std::collections::HashMap; - -use crate::{DbInstances, DbPool, Error, LastInsertId, Migrations}; -#[cfg(feature = "sqlite")] -use crate::SqliteOptions; - -#[cfg(not(feature = "sqlite"))] -#[command] -pub(crate) async fn load( - app: AppHandle, - db_instances: State<'_, DbInstances>, - migrations: State<'_, Migrations>, - db: String, -) -> Result { - let pool = DbPool::connect(&db, &app).await?; - - if let Some(migrations) = migrations.0.lock().await.remove(&db) { - let migrator = Migrator::new(migrations).await?; - pool.migrate(&migrator).await?; - } - - db_instances.0.write().await.insert(db.clone(), pool); - - Ok(db) -} - -#[cfg(feature = "sqlite")] #[command] pub(crate) async fn load( app: AppHandle, db_instances: State<'_, DbInstances>, migrations: State<'_, Migrations>, db: String, - pragmas: Option>, + options: Option, ) -> Result { - let sqlite_options = if db.starts_with("sqlite:") { - let mut options = SqliteOptions::default(); - - // Apply pragmas if provided - if let Some(provided_pragmas) = pragmas { - options.pragmas.extend(provided_pragmas); - } - - Some(options) - } else { - None - }; - - let pool = DbPool::connect(&db, &app, sqlite_options).await?; - + let pool = DbPool::connect(&db, &app, options).await?; if let Some(migrations) = migrations.0.lock().await.remove(&db) { let migrator = Migrator::new(migrations).await?; pool.migrate(&migrator).await?; diff --git a/plugins/sql/src/lib.rs b/plugins/sql/src/lib.rs index ca2d1bfc..3de734d1 100644 --- a/plugins/sql/src/lib.rs +++ b/plugins/sql/src/lib.rs @@ -18,6 +18,7 @@ pub use error::Error; pub use wrapper::DbPool; #[cfg(feature = "sqlite")] pub use wrapper::SqliteOptions; +pub use wrapper::ConnectionOptions; use futures_core::future::BoxFuture; use serde::{Deserialize, Serialize}; @@ -25,8 +26,6 @@ use sqlx::{ error::BoxDynError, migrate::{Migration as SqlxMigration, MigrationSource, MigrationType, Migrator}, }; -#[cfg(feature = "sqlite")] -use sqlx::sqlite::SqliteConnectOptions; use tauri::{ plugin::{Builder as PluginBuilder, TauriPlugin}, Manager, RunEvent, Runtime, @@ -38,9 +37,6 @@ use std::collections::HashMap; #[derive(Default)] pub struct DbInstances(pub RwLock>); -#[cfg(feature = "sqlite")] -struct SqlLiteOptionStore(Mutex>); - #[derive(Serialize)] #[serde(untagged)] pub(crate) enum LastInsertId { @@ -160,12 +156,8 @@ impl Builder { let mut lock = instances.0.write().await; for db in config.preload { - #[cfg(feature = "sqlite")] let pool = DbPool::connect(&db, app, None).await?; - #[cfg(not(feature = "sqlite"))] - let pool = DbPool::connect(&db, app).await?; - if let Some(migrations) = self.migrations.as_mut().and_then(|mm| mm.remove(&db)) { diff --git a/plugins/sql/src/wrapper.rs b/plugins/sql/src/wrapper.rs index e5348ec6..cd146764 100644 --- a/plugins/sql/src/wrapper.rs +++ b/plugins/sql/src/wrapper.rs @@ -2,10 +2,10 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -#[cfg(feature = "sqlite")] -use std::fs::create_dir_all; #[cfg(feature = "sqlite")] use std::collections::HashMap; +#[cfg(feature = "sqlite")] +use std::fs::create_dir_all; use indexmap::IndexMap; use serde_json::Value as JsonValue; @@ -38,6 +38,7 @@ pub enum DbPool { } #[cfg(feature = "sqlite")] +#[derive(serde::Serialize, serde::Deserialize, Debug)] pub struct SqliteOptions { pub pragmas: HashMap, } @@ -51,6 +52,25 @@ impl Default for SqliteOptions { } } +#[derive(serde::Serialize, serde::Deserialize, Debug)] +pub struct ConnectionOptions { + #[cfg(feature = "sqlite")] + pub sqlite: Option, + // #[cfg(feature = "mysql")] + // mysql: Option, + // #[cfg(feature = "postgres")] + // postgres: Option, +} + +impl Default for ConnectionOptions { + fn default() -> Self { + Self { + #[cfg(feature = "sqlite")] + sqlite: None, + } + } +} + // public methods /* impl DbPool { /// Get the inner Sqlite Pool. Returns None for MySql and Postgres pools. @@ -86,7 +106,7 @@ impl DbPool { pub(crate) async fn connect( conn_url: &str, _app: &AppHandle, - #[cfg(feature = "sqlite")] sqlite_options: Option, + options: Option, ) -> Result { match conn_url .split_once(':') @@ -104,19 +124,20 @@ impl DbPool { let conn_url = &path_mapper(app_path, conn_url); let filename = conn_url.split_once(':').unwrap().1; - let mut options = SqliteConnectOptions::new() + let mut sqlite_options = SqliteConnectOptions::new() .filename(filename) .create_if_missing(true); - // Apply pragmas if provided - if let Some(sqlite_opts) = sqlite_options { - for (pragma_name, pragma_value) in sqlite_opts.pragmas { - options = options.pragma(pragma_name, pragma_value); + if let Some(conn_opts) = options { + if let Some(sqlite_opts) = conn_opts.sqlite { + for (pragma_name, pragma_value) in sqlite_opts.pragmas { + sqlite_options = sqlite_options.pragma(pragma_name, pragma_value); + } } } // Connect with options (which includes create_if_missing) - Ok(Self::Sqlite(Pool::connect_with(options).await?)) + Ok(Self::Sqlite(Pool::connect_with(sqlite_options).await?)) } #[cfg(feature = "mysql")] "mysql" => { From 30df3929f18deb246386b7b2eb1bb9fb7d10df98 Mon Sep 17 00:00:00 2001 From: Huakun Shen Date: Fri, 21 Mar 2025 00:24:59 -0400 Subject: [PATCH 3/4] docs(sql): enhance examples for database connection with detailed comments on SQLite usage --- plugins/sql/guest-js/index.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/sql/guest-js/index.ts b/plugins/sql/guest-js/index.ts index cba9928e..51f7c014 100644 --- a/plugins/sql/guest-js/index.ts +++ b/plugins/sql/guest-js/index.ts @@ -42,17 +42,17 @@ export default class Database { * * @example * ```ts - * // Basic connection + * // Basic connection to a SQLite database * const db = await Database.load("sqlite:test.db"); * - * // With encryption key + * // Connecting with an encryption key for added security * const db = await Database.load("sqlite:encrypted.db", { - * pragmas: { "key": "encryption_key" } + * sqlite: { pragmas: { "key": "encryption_key" } } * }); * - * // With pragmas + * // Connecting with specific pragmas for configuration * const db = await Database.load("sqlite:test.db", { - * pragmas: { "journal_mode": "WAL", "foreign_keys": "ON" } + * sqlite: { pragmas: { "journal_mode": "WAL", "foreign_keys": "ON" } } * }); * ``` */ From 49d9a384422962981d1c10e9024e7a09e5d268f7 Mon Sep 17 00:00:00 2001 From: Huakun Shen Date: Fri, 21 Mar 2025 00:26:15 -0400 Subject: [PATCH 4/4] refactor(sql): remove commented-out query function and clean up command registration --- plugins/sql/src/commands.rs | 14 -------------- plugins/sql/src/lib.rs | 3 --- 2 files changed, 17 deletions(-) diff --git a/plugins/sql/src/commands.rs b/plugins/sql/src/commands.rs index ef6eaf49..e599e423 100644 --- a/plugins/sql/src/commands.rs +++ b/plugins/sql/src/commands.rs @@ -77,17 +77,3 @@ pub(crate) async fn select( let db = instances.get(&db).ok_or(Error::DatabaseNotLoaded(db))?; db.select(query, values).await } - -// #[command] -// pub(crate) async fn query( -// db_instances: State<'_, DbInstances>, -// db: String, -// query: String, -// values: Vec, -// ) -> Result>, crate::Error> { -// let instances = db_instances.0.read().await; - -// let db = instances.get(&db).ok_or(Error::DatabaseNotLoaded(db))?; -// db. -// // db.select(query, values).await -// } diff --git a/plugins/sql/src/lib.rs b/plugins/sql/src/lib.rs index 3de734d1..64d6cf1c 100644 --- a/plugins/sql/src/lib.rs +++ b/plugins/sql/src/lib.rs @@ -140,9 +140,6 @@ impl Builder { pub fn build(mut self) -> TauriPlugin> { PluginBuilder::>::new("sql") .invoke_handler(tauri::generate_handler![ - #[cfg(feature = "sqlite")] - commands::load, - #[cfg(not(feature = "sqlite"))] commands::load, commands::execute, commands::select,