Skip to content
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

feat(sql) Adding support for Sqlite database encryption + Other pragma (journal, read only...) + In memory database #1044

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

Conversation

eleroy
Copy link

@eleroy eleroy commented Mar 7, 2024

Hi everyone,

Here is a pull request referring to issues #7 #875 and PR #877 (in-memory database).

This is my first pull request, and I'm very new to rust so if the code and PR are not well written/formatted please feel free to edit it.

I propose a way to specify SqlLite options similarly to Migrations. For this I had to review also how non-existing database are created. Here is how it works:

Sqlite options

Adding Sqlite options

Similarly as adding migrations, it is possible to add Sqlite options such as database encryption or regular Sqlite options.

use tauri_plugin_sql::{Builder, Migration, MigrationKind, SqliteConfig};

fn main() {
    let migrations = vec![
        // Define your migrations here
        Migration {
            version: 1,
            description: "create_initial_tables",
            sql: "CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT);",
            kind: MigrationKind::Up,
        }
    ];

    tauri::Builder::default()
        .plugin(
            tauri_plugin_sql::Builder::default()
                .add_migrations("sqlite:mydatabase.db", migrations)
                .add_sqlite_options("sqlite:mydatabase.db", SqliteConfig{key:"my_database_key", journal_mode:"OFF", foreign_keys:true, read_only:false,..Default::default()})
                .build(),
        )
        ...
}

All the options are specified in the struct definition

pub struct SqliteConfig {
    pub key: &'static str, // Database key
    pub cipher_page_size: i32, // Page size of encrypted database. Default for SQLCipher v4 is 4096.
    pub cipher_plaintext_header_size: i32,
    pub kdf_iter: i32, // Number of iterations used in PBKDF2 key derivation. Default for SQLCipher v4 is 256000
    pub cipher_kdf_algorithm: &'static str,  // Define KDF algorithm to be used. Default for SQLCipher v4 is PBKDF2_HMAC_SHA512.
    pub cipher_hmac_algorithm: &'static str, // Choose algorithm used for HMAC. Default for SQLCipher v4 is HMAC_SHA512.                                        
    pub cipher_salt: Option<&'static str>, // Allows to provide salt manually. By default SQLCipher sets salt automatically, use only in conjunction with 'cipher_plaintext_header_size' pragma
    pub cipher_compatibility: Option<i32>, // 1, 2, 3, 4
    pub journal_mode: &'static str,        // DELETE | TRUNCATE | PERSIST | MEMORY | WAL | OFF
    pub foreign_keys: bool,
    pub synchronous: &'static str,  // EXTRA | FULL | NORMAL |  OFF
    pub locking_mode: &'static str, // NORMAL | EXCLUSIVE
    pub read_only: bool, // NORMAL | EXCLUSIVE
}

In memory

A database name containing :memory will be loaded as an in-memory database.

SqlCipher

To make it work with SqlCipher, you'll need to make additionnal changes to you cargo.toml:

[dependencies]
...
libsqlite3-sys = { version = "*", features = ["bundled-sqlcipher"] }

You'll also need openssl to build. Please refer to libsqlite3-sys documentation to understand how to build.

On windows, I recommend building and installing openssl using vcpkg https://github.com/Microsoft/vcpkg

  • Clone vcpkg to C:\src\vcpkg for example
  • Bootstrap vcpkg C:\src\vcpkg\bootstrap-vcpkg.bat
  • C:\src\vcpkg\vcpkg.exe integrate install
  • C:\src\vcpkg\vcpkg.exe install openssl:x64-windows
  • Add env variable OPENSSL_DIR = C:\src\vcpkg\installed\x64-windows

@eleroy eleroy requested a review from a team as a code owner March 7, 2024 12:11
@FabianLars FabianLars self-assigned this Mar 7, 2024
@ibilux
Copy link

ibilux commented Apr 19, 2024

I hope this get merged soon.

eleroy and others added 3 commits April 24, 2024 08:49
- Splitted load method to add sqlite options state only for sqlite feature
- replaced JsonValue as_number that would not be found by is_number in execute and select
@eleroy
Copy link
Author

eleroy commented Apr 24, 2024

The tests would not run because I did not check the PR with all features. They should work now with the last commit.

@tyfiero
Copy link

tyfiero commented May 15, 2024

This would be an awesome feature, I really hope this gets merged

@eleroy
Copy link
Author

eleroy commented May 22, 2024

Hello @FabianLars,

I've sync the fork and i just checked cargo check with each features and it is working.
I did also run cargo +nightly fmt --check without errors.

Edit : the sample project https://github.com/eleroy/test-sql-cipher is also working (with sqlite feature)

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.

None yet

4 participants