Skip to content

feat(sql): support for SQLite pragma and encryption pragmas #2553

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: v2
Choose a base branch
from

Conversation

HuakunShen
Copy link

@HuakunShen HuakunShen commented Mar 20, 2025

resolve #7

  • 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.

Now sqlite encryption can be enabled like this.

const db = await Database.load("sqlite:encrypted.db", {
  sqlite: { pragmas: { "key": "encryption_key" } }
});

I already tested on Mac, further testing needed on Windows and Linux.

- 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.
@HuakunShen HuakunShen requested a review from a team as a code owner March 20, 2025 12:01
@HuakunShen
Copy link
Author

Preload doesn't support pragma yet, because that will introduce breaking APIs here

preload: Vec<String>,

If we have to support pragma in preload, then maybe something like this?

{
  "plugins": {
    "sql": {
      "preload": ["sqlite:mydatabase.db"],
      "sqlite_options": {
        "sqlite:mydatabase.db": {
          "pragmas": {
            "journal_mode": "WAL",
            "foreign_keys": "ON"
          }
        }
      }
    }
  }
}

@HuakunShen
Copy link
Author

HuakunShen commented Mar 21, 2025

I realized one problem, there are two load commands now, one for sqlite one for others. So the current implementation doesn't support multiple features. Either sqlite only or turn off sqlite feature.
Will need a more robust design.

Problem fixed, the latest version supports connecting to sqlite, mysql and postgres at the same time

@haexhub
Copy link

haexhub commented Mar 25, 2025

I'm desperately waiting for this feature

@HuakunShen
Copy link
Author

HuakunShen commented Mar 25, 2025

I'm desperately waiting for this feature

No one is reviewing this PR.

In the meanwhile, if anyone wants to try this, you can set dependency to my branch in Cargo.toml.
And for JS dependency, you may want to clone my branch and link to it with pnpm/npm/bun link.

@roniemartinez
Copy link

+1 on this! I am also waiting to move from my custom implementation to fully adapting to this plugin. Thanks for the PR!

@HuakunShen
Copy link
Author

+1 on this! I am also waiting to move from my custom implementation to fully adapting to this plugin. Thanks for the PR!

I was also using my custom implementation with cipher using rusqlite.
While I made this PR, it will be a lot of work to migrate from my implementation to this.
And I want to at least wait til this PR get merged to migrate.

BTW I also figured out how to use drizzle to work with this sql plugin and also rusqlite.
Working with sqlite in Tauri now feels like in Electron.

Copy link

@c6p c6p left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe out of scope of this PR, but with minimal change, it can support loading sqlite extensions.

path: string,
options?: {
sqlite?: {
pragmas?: Record<string, string>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you are already adding options. Could you add support for extensions, to fix #1705

extensions?: Record<string, Option<string>>  // extension, entry_point

Sqlite::create_database(conn_url).await?;
let mut sqlite_options = SqliteConnectOptions::new()
.filename(filename)
.create_if_missing(true);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Load extensions with entry points.

@roniemartinez
Copy link

Had the chance to test this PR.... but I added my changes for my use: roniemartinez@7ca825d

@fokx
Copy link

fokx commented May 16, 2025

Hope this PR could be merged soon!

fokx added a commit to fokx/localshare that referenced this pull request May 16, 2025
@FabianLars
Copy link
Member

Sorry i don't have much time for plugins at the moment and this also comes a bit in the middle of a refactor of the sql plugin (which is my bad since that should've been long done).

One thing that sure would help is to do what Huakun also asked for and try this PR yourself before it's merged so we get a bit of feedback on the API and issues.

Preload doesn't support pragma yet, because that will introduce breaking APIs here

We can do it without a breaking change by creating an untagged enum for use in that Vec with string and struct variants.

@fokx
Copy link

fokx commented May 17, 2025

try this PR yourself

I've tried this PR and can confirm pragmas works on Linux.

To build for Android, you need to use bundled-sqlcipher-vendored-openssl feature of libsqlite3-sys instead of bundled-sqlcipher, which cause openssl related build error.

libsqlite3-sys = { version = "0.30", features = ["bundled-sqlcipher-vendored-openssl"] }

It works on Android after makes such modification. Test method: pull the db file from Android device and open it in Sqlite DB Browser.

@roniemartinez
Copy link

Is it safe to put “PRAGMA key” in the config file? Putting it in the Rust code like what I did in #2553 (comment) looks a lot more safe because I can get the key dynamically from a server.

@FabianLars
Copy link
Member

Is it safe to put “PRAGMA key” in the config file?

Not reallyyy. But since we consider the js side unsafe as well a config option is not much worse than that. Assuming of course that it's not committed to git but injected at build time (true for config, js, and rust). That's a bit less obvious for the config option so maybe you're right and we shouldn't add it (yet).

@FabianLars
Copy link
Member

I've tried this PR and can confirm pragmas works on Linux.

Thanks for testing :)

To build for Android, you need to use bundled-sqlcipher-vendored-openssl feature of libsqlite3-sys instead of bundled-sqlcipher, which cause openssl related build error.

That's a bit problematic for those that build their apps on Windows but i guess there's no way around that. But with that both feature flags should be exposed as plugin features and users should enable what they need (making sqlcipher as a whole option again as well).

@salemdomain
Copy link

I've tried this PR and can confirm pragmas works on Linux.

Thanks for testing :)

To build for Android, you need to use bundled-sqlcipher-vendored-openssl feature of libsqlite3-sys instead of bundled-sqlcipher, which cause openssl related build error.

That's a bit problematic for those that build their apps on Windows but i guess there's no way around that. But with that both feature flags should be exposed as plugin features and users should enable what they need (making sqlcipher as a whole option again as well).

hey everything works fine with npm run tauri dev, but I encounter issues when building a Windows package from macOS using this command npm run tauri build -- --target x86_64-pc-windows-msvc --runner cargo-xwin and here is the error error: failed to run custom build command for 'libsqlite3-sys v0.30.1' and here is my cargo.toml

[dependencies.tauri-plugin-sql]
features = ["bundled-sqlcipher"] # or "postgres", or "mysql"
version = "^2.0.0-beta"
# alternatively with Git
git = "https://github.com/eleroy/plugins-workspace"
branch = "sql/sqlcipher"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[sql] SQLCipher Encryption
7 participants