plugins-workspace icon indicating copy to clipboard operation
plugins-workspace copied to clipboard

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

Open eleroy opened this issue 1 year ago • 3 comments

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 avatar Mar 07 '24 12:03 eleroy

I hope this get merged soon.

ibilux avatar Apr 19 '24 19:04 ibilux

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

eleroy avatar Apr 24 '24 13:04 eleroy

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

tyfiero avatar May 15 '24 13:05 tyfiero

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)

eleroy avatar May 22 '24 19:05 eleroy

I opened a new PR #1441 with a single commit from a specific branch.

eleroy avatar Jun 07 '24 08:06 eleroy