@@ -16,14 +16,15 @@ const _isWeb = _isCompilingToJavaScript || _isDart2Wasm;
1616///
1717/// On native platforms, the `sqlite3` package provides a copy of SQLite with
1818/// your app. To use encryption, we need to replace SQLite with
19- /// [SQLite3MultipleCiphers] (https://utelle.github.io/SQLite3MultipleCiphers/).
19+ /// [SQLite3MultipleCiphers] (https://utelle.github.io/SQLite3MultipleCiphers/)
20+ /// or [SQLCipher] (https://www.zetetic.net/sqlcipher/).
2021/// To enable that, add this to your `pubspec.yaml` :
2122///
2223/// ```yaml
2324/// hooks:
2425/// user_defines:
2526/// sqlite3:
26- /// source: sqlite3mc
27+ /// source: sqlite3mc # or sqlcipher
2728/// ```
2829///
2930/// If you're using pub workspaces, this needs to be added to the `pubspec.yaml`
@@ -38,6 +39,8 @@ const _isWeb = _isCompilingToJavaScript || _isDart2Wasm;
3839/// To use encryption, download `sqlite3mc.wasm` as `web/sqlite3.wasm` . If you
3940/// use the `powersync:setup_web` tool to download that file, pass the
4041/// `--encryption` option.
42+ ///
43+ /// Note that SQLCipher is not available on the web.
4144final class EncryptionOptions {
4245 /// The key used to encrypt the database file.
4346 ///
@@ -59,8 +62,12 @@ final class EncryptionOptions {
5962 this .sqlcipherCompatibility = ! _isWeb,
6063 });
6164
62- Iterable <String >? pragmaStatements () sync * {
63- if (sqlcipherCompatibility) {
65+ Iterable <String > pragmaStatements ({
66+ EncryptedSqliteVariant variant =
67+ EncryptedSqliteVariant .sqlite3MultipleCiphers,
68+ }) sync * {
69+ if (sqlcipherCompatibility &&
70+ variant == EncryptedSqliteVariant .sqlite3MultipleCiphers) {
6471 yield "PRAGMA cipher = 'sqlcipher'" ;
6572 yield 'PRAGMA legacy = 4' ;
6673 }
@@ -71,6 +78,7 @@ final class EncryptionOptions {
7178
7279 /// Throws if the `cipher` pragma doesn't exist, as that indicates that
7380 /// SQLite3MultipleCiphers is not available.
81+ @Deprecated ('Unused in PowerSync SDK' )
7482 static void checkHasCipherPragma (CommonDatabase database) {
7583 if (database.select ('pragma cipher' ).isEmpty) {
7684 throw UnsupportedError (
@@ -80,3 +88,34 @@ final class EncryptionOptions {
8088 }
8189 }
8290}
91+
92+ /// A fork of SQLite with encryption support.
93+ enum EncryptedSqliteVariant {
94+ /// [SQLCipher] (https://www.zetetic.net/sqlcipher/) can encrypt databases with
95+ /// AES.
96+ ///
97+ /// Encrypting databases with SQLCipher can be more performant than
98+ /// [sqlite3MultipleCiphers] because it uses optimized system encryption
99+ /// libraries (on Apple platform) and OpenSSL (on other platforms).
100+ ///
101+ /// Note that SQLCipher is not available on the web.
102+ sqlcipher,
103+
104+ /// [SQLite3 Multiple Ciphers] (https://utelle.github.io/SQLite3MultipleCiphers/)
105+ /// provides compatibility with multiple encryption schemes from a single
106+ /// build.
107+ ///
108+ /// On the web, this is the only option available to encrypt databases.
109+ sqlite3MultipleCiphers;
110+
111+ /// The [EncryptedSqliteVariant] enabled on the database, or null.
112+ static EncryptedSqliteVariant ? resolveOnDatabase (CommonDatabase db) {
113+ if (db.select ('pragma cipher' ).isNotEmpty) {
114+ return EncryptedSqliteVariant .sqlite3MultipleCiphers;
115+ } else if (db.select ('pragma cipher_version' ).isNotEmpty) {
116+ return EncryptedSqliteVariant .sqlcipher;
117+ } else {
118+ return null ;
119+ }
120+ }
121+ }
0 commit comments