@capacitor-community/sqlite 7.0.0 → 7.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -10,7 +10,7 @@
10
10
  </p>
11
11
  <br>
12
12
  <p align="center">
13
- <img src="https://img.shields.io/maintenance/yes/2024?style=flat-square" />
13
+ <img src="https://img.shields.io/maintenance/yes/2025?style=flat-square" />
14
14
  <a href="https://github.com/capacitor-community/sqlite/actions?query=workflow%3A%22CI%22"><img src="https://img.shields.io/github/actions/workflow/status/capacitor-community/sqlite/ci.yml?style=flat-square" /></a>
15
15
  <a href="https://www.npmjs.com/package/@capacitor-community/sqlite"><img src="https://img.shields.io/npm/l/@capacitor-community/sqlite?branch=master&style=flat-square" /></a>
16
16
  <br>
@@ -122,7 +122,7 @@ You'll need the usual capacitor/android/react npm script to build and copy the a
122
122
 
123
123
  - In case you get the following error when building your app in Android Studio:
124
124
  `x files found with path 'build-data.properties'.`
125
- You can you add the following code to `app/build.gradle`:
125
+ You can add the following code to `app/build.gradle`:
126
126
  ```
127
127
  packagingOptions {
128
128
  exclude 'build-data.properties'
@@ -131,14 +131,14 @@ You'll need the usual capacitor/android/react npm script to build and copy the a
131
131
  See [#301](https://github.com/capacitor-community/sqlite/issues/301) and [SO question](https://stackoverflow.com/questions/63291529/how-to-fix-more-than-one-file-was-found-with-os-independent-path-build-data-pro) for more information.
132
132
 
133
133
  - Check/Add the following:
134
- Gradle JDK version 17
135
- Android Gradle Plugin Version 8.0.0
134
+ Gradle JDK version 21
135
+ Android Gradle Plugin Version 8.7.2
136
136
  In variables.gradle
137
137
 
138
138
  ```
139
- minSdkVersion = 22
140
- compileSdkVersion = 33
141
- targetSdkVersion = 33
139
+ minSdkVersion = 23
140
+ compileSdkVersion = 35
141
+ targetSdkVersion = 35
142
142
  ```
143
143
  In AndroidManifest.xml
144
144
  ```
@@ -355,7 +355,7 @@ npm install --save-dev electron-builder@24.6.4
355
355
  ## Dependencies
356
356
 
357
357
  The iOS and Android codes are using `SQLCipher` allowing for database encryption.
358
- The iOS codes is using `ZIPFoundation` for unzipping assets files
358
+ The iOS code is using `ZIPFoundation` for unzipping assets files
359
359
  The Electron code is using `better-sqlite3-multiple-ciphers` , `electron-json-storage` and `node-fetch` from 5.0.4.
360
360
  The Web code is using the Stencil component `jeep-sqlite` based on `sql.js`, `localforage`. and `jszip`
361
361
 
@@ -61,7 +61,7 @@ dependencies {
61
61
  androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
62
62
  androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
63
63
  implementation "androidx.coordinatorlayout:coordinatorlayout:1.2.0"
64
- implementation 'net.zetetic:android-database-sqlcipher:4.5.3'
64
+ implementation 'net.zetetic:sqlcipher-android:4.6.1@aar'
65
65
  implementation "androidx.sqlite:sqlite:2.4.0"
66
66
  //security library
67
67
  implementation "androidx.security:security-crypto:1.1.0-alpha06"
@@ -26,6 +26,7 @@ import com.getcapacitor.community.database.sqlite.SQLite.ImportExportJson.JsonSQ
26
26
  import com.getcapacitor.community.database.sqlite.SQLite.ImportExportJson.UtilsEncryption;
27
27
  import com.getcapacitor.community.database.sqlite.SQLite.ImportExportJson.UtilsJson;
28
28
  import java.io.File;
29
+ import java.nio.charset.StandardCharsets;
29
30
  import java.text.SimpleDateFormat;
30
31
  import java.util.ArrayList;
31
32
  import java.util.Arrays;
@@ -35,9 +36,8 @@ import java.util.List;
35
36
  import java.util.Objects;
36
37
  import java.util.regex.Matcher;
37
38
  import java.util.regex.Pattern;
38
- import net.sqlcipher.Cursor;
39
- import net.sqlcipher.database.SQLiteDatabase;
40
- import net.sqlcipher.database.SQLiteException;
39
+ import net.zetetic.database.sqlcipher.SQLiteCursor;
40
+ import net.zetetic.database.sqlcipher.SQLiteDatabase;
41
41
  import org.json.JSONArray;
42
42
  import org.json.JSONException;
43
43
  import org.json.JSONObject;
@@ -115,7 +115,7 @@ public class Database {
115
115
  * Initialize the SQLCipher Libraries
116
116
  */
117
117
  private void InitializeSQLCipher() {
118
- SQLiteDatabase.loadLibs(_context);
118
+ System.loadLibrary("sqlcipher");
119
119
  }
120
120
 
121
121
  public SupportSQLiteDatabase getDb() {
@@ -247,7 +247,7 @@ public class Database {
247
247
  if (_mode.equals("encryption")) {
248
248
  if (_isEncryption) {
249
249
  try {
250
- _uCipher.encrypt(_context, _file, SQLiteDatabase.getBytes(password.toCharArray()));
250
+ _uCipher.encrypt(_context, _file, password.getBytes(StandardCharsets.UTF_8));
251
251
  } catch (Exception e) {
252
252
  String msg = "Failed in encryption " + e.getMessage();
253
253
  Log.v(TAG, msg);
@@ -260,7 +260,7 @@ public class Database {
260
260
  if (_mode.equals("decryption")) {
261
261
  if (_isEncryption) {
262
262
  try {
263
- _uCipher.decrypt(_context, _file, SQLiteDatabase.getBytes(password.toCharArray()));
263
+ _uCipher.decrypt(_context, _file, password.getBytes());
264
264
  password = "";
265
265
  } catch (Exception e) {
266
266
  String msg = "Failed in decryption " + e.getMessage();
@@ -273,9 +273,9 @@ public class Database {
273
273
  }
274
274
  try {
275
275
  if (!isNCDB() && !this._readOnly) {
276
- _db = SQLiteDatabase.openOrCreateDatabase(_file, password, null);
276
+ _db = SQLiteDatabase.openOrCreateDatabase(_file, password, null, null);
277
277
  } else {
278
- _db = SQLiteDatabase.openDatabase(String.valueOf(_file), password, null, SQLiteDatabase.OPEN_READONLY);
278
+ _db = SQLiteDatabase.openDatabase(String.valueOf(_file), password, null, SQLiteDatabase.OPEN_READONLY, null);
279
279
  }
280
280
  if (_db != null) {
281
281
  if (_db.isOpen()) {
@@ -301,12 +301,6 @@ public class Database {
301
301
  close();
302
302
  _db = null;
303
303
  throw new Exception(msg);
304
- } catch (SQLiteException e) {
305
- String msg = "Failed in setVersion " + e.getMessage();
306
- Log.v(TAG, msg);
307
- close();
308
- _db = null;
309
- throw new Exception(msg);
310
304
  }
311
305
  if (_version > curVersion && _vUpgObject != null && _vUpgObject.size() > 0) {
312
306
  // if (_vUpgObject != null && _vUpgObject.size() > 0) {
@@ -973,12 +967,12 @@ public class Database {
973
967
  */
974
968
  public JSArray selectSQL(String statement, ArrayList<Object> values) throws Exception {
975
969
  JSArray retArray = new JSArray();
976
- Cursor c = null;
970
+ SQLiteCursor c = null;
977
971
  if (_db == null) {
978
972
  return retArray;
979
973
  }
980
974
  try {
981
- c = (Cursor) _db.query(statement, values.toArray(new Object[0]));
975
+ c = (SQLiteCursor) _db.query(statement, values.toArray(new Object[0]));
982
976
  while (c.moveToNext()) {
983
977
  JSObject row = new JSObject();
984
978
  for (int i = 0; i < c.getColumnCount(); i++) {
@@ -6,7 +6,7 @@ import java.util.ArrayList;
6
6
  import java.util.Dictionary;
7
7
  import java.util.Enumeration;
8
8
  import java.util.List;
9
- import net.sqlcipher.Cursor;
9
+ import net.zetetic.database.sqlcipher.SQLiteCursor;
10
10
 
11
11
  public class UtilsDrop {
12
12
 
@@ -20,7 +20,7 @@ public class UtilsDrop {
20
20
 
21
21
  public List<String> getTablesNames(Database db) throws Exception {
22
22
  List<String> tables = new ArrayList<String>();
23
- Cursor cursor = null;
23
+ SQLiteCursor cursor = null;
24
24
  String query = "SELECT name FROM sqlite_master WHERE ";
25
25
  query += "type='table' AND name NOT LIKE 'sync_table' ";
26
26
  query += "AND name NOT LIKE '_temp_%' ";
@@ -28,7 +28,7 @@ public class UtilsDrop {
28
28
  query += "AND name NOT LIKE 'android_%' ";
29
29
  query += "ORDER BY rootpage DESC;";
30
30
  try {
31
- cursor = (Cursor) db.getDb().query(query);
31
+ cursor = (SQLiteCursor) db.getDb().query(query);
32
32
  cursor.moveToFirst();
33
33
  while (!cursor.isAfterLast()) {
34
34
  String tableName = cursor.getString(0);
@@ -51,12 +51,12 @@ public class UtilsDrop {
51
51
 
52
52
  public List<String> getViewNames(Database db) throws Exception {
53
53
  List<String> views = new ArrayList<String>();
54
- Cursor cursor = null;
54
+ SQLiteCursor cursor = null;
55
55
  String query = "SELECT name FROM sqlite_master WHERE ";
56
56
  query += "type='view' AND name NOT LIKE 'sqlite_%' ";
57
57
  query += "ORDER BY rootpage DESC;";
58
58
  try {
59
- cursor = (Cursor) db.getDb().query(query);
59
+ cursor = (SQLiteCursor) db.getDb().query(query);
60
60
  cursor.moveToFirst();
61
61
  while (!cursor.isAfterLast()) {
62
62
  String viewName = cursor.getString(0);
@@ -113,10 +113,10 @@ public class UtilsDrop {
113
113
 
114
114
  public List<String> getIndexesNames(Database db) {
115
115
  List<String> indexes = new ArrayList<String>();
116
- Cursor cursor = null;
116
+ SQLiteCursor cursor = null;
117
117
  String query = "SELECT name FROM sqlite_master WHERE ";
118
118
  query += "type='index' AND name NOT LIKE 'sqlite_%';";
119
- cursor = (Cursor) db.getDb().query(query);
119
+ cursor = (SQLiteCursor) db.getDb().query(query);
120
120
  cursor.moveToFirst();
121
121
  while (!cursor.isAfterLast()) {
122
122
  String indexName = cursor.getString(0);
@@ -152,10 +152,10 @@ public class UtilsDrop {
152
152
 
153
153
  public List<String> getTriggersNames(Database db) {
154
154
  List<String> triggers = new ArrayList<String>();
155
- Cursor cursor = null;
155
+ SQLiteCursor cursor = null;
156
156
  String query = "SELECT name FROM sqlite_master WHERE ";
157
157
  query += "type='trigger';";
158
- cursor = (Cursor) db.getDb().query(query);
158
+ cursor = (SQLiteCursor) db.getDb().query(query);
159
159
  cursor.moveToFirst();
160
160
  while (!cursor.isAfterLast()) {
161
161
  String triggerName = cursor.getString(0);
@@ -5,9 +5,8 @@ import android.content.SharedPreferences;
5
5
  import java.io.File;
6
6
  import java.io.FileNotFoundException;
7
7
  import java.io.IOException;
8
- import net.sqlcipher.database.SQLiteDatabase;
9
- import net.sqlcipher.database.SQLiteException;
10
- import net.sqlcipher.database.SQLiteStatement;
8
+ import net.zetetic.database.sqlcipher.SQLiteDatabase;
9
+ import net.zetetic.database.sqlcipher.SQLiteStatement;
11
10
 
12
11
  public class UtilsSQLCipher {
13
12
 
@@ -36,12 +35,12 @@ public class UtilsSQLCipher {
36
35
  * @return the detected state of the database
37
36
  */
38
37
  public State getDatabaseState(Context ctxt, File dbPath, SharedPreferences sharedPreferences, GlobalSQLite globVar) {
39
- SQLiteDatabase.loadLibs(ctxt);
38
+ System.loadLibrary("sqlcipher");
40
39
  if (dbPath.exists()) {
41
40
  SQLiteDatabase db = null;
42
41
 
43
42
  try {
44
- db = SQLiteDatabase.openDatabase(dbPath.getAbsolutePath(), "", null, SQLiteDatabase.OPEN_READONLY);
43
+ db = SQLiteDatabase.openDatabase(dbPath.getAbsolutePath(), "", null, SQLiteDatabase.OPEN_READONLY, null);
45
44
 
46
45
  db.getVersion();
47
46
 
@@ -50,7 +49,7 @@ public class UtilsSQLCipher {
50
49
  try {
51
50
  String passphrase = sharedPreferences.getString("secret", "");
52
51
  if (passphrase.length() > 0) {
53
- db = SQLiteDatabase.openDatabase(dbPath.getAbsolutePath(), passphrase, null, SQLiteDatabase.OPEN_READONLY);
52
+ db = SQLiteDatabase.openDatabase(dbPath.getAbsolutePath(), passphrase, null, SQLiteDatabase.OPEN_READONLY, null);
54
53
  db.getVersion();
55
54
  return (State.ENCRYPTED_SECRET);
56
55
  } else {
@@ -59,7 +58,13 @@ public class UtilsSQLCipher {
59
58
  } catch (Exception e1) {
60
59
  try {
61
60
  if (globVar.secret.length() > 0) {
62
- db = SQLiteDatabase.openDatabase(dbPath.getAbsolutePath(), globVar.secret, null, SQLiteDatabase.OPEN_READONLY);
61
+ db = SQLiteDatabase.openDatabase(
62
+ dbPath.getAbsolutePath(),
63
+ globVar.secret,
64
+ null,
65
+ SQLiteDatabase.OPEN_READONLY,
66
+ null
67
+ );
63
68
  db.getVersion();
64
69
  return (State.ENCRYPTED_GLOBAL_SECRET);
65
70
  } else {
@@ -92,11 +97,11 @@ public class UtilsSQLCipher {
92
97
  * @throws IOException
93
98
  */
94
99
  public void encrypt(Context ctxt, File originalFile, byte[] passphrase) throws IOException {
95
- SQLiteDatabase.loadLibs(ctxt);
100
+ System.loadLibrary("sqlcipher");
96
101
 
97
102
  if (originalFile.exists()) {
98
103
  File newFile = File.createTempFile("sqlcipherutils", "tmp", ctxt.getCacheDir());
99
- SQLiteDatabase db = SQLiteDatabase.openDatabase(originalFile.getAbsolutePath(), "", null, SQLiteDatabase.OPEN_READWRITE);
104
+ SQLiteDatabase db = SQLiteDatabase.openDatabase(originalFile.getAbsolutePath(), "", null, SQLiteDatabase.OPEN_READWRITE, null);
100
105
  int version = db.getVersion();
101
106
 
102
107
  db.close();
@@ -135,7 +140,7 @@ public class UtilsSQLCipher {
135
140
  }
136
141
 
137
142
  public void decrypt(Context ctxt, File originalFile, byte[] passphrase) throws IOException {
138
- SQLiteDatabase.loadLibs(ctxt);
143
+ System.loadLibrary("sqlcipher");
139
144
 
140
145
  if (originalFile.exists()) {
141
146
  // Create a temporary file for the decrypted database in the cache directory
@@ -146,7 +151,8 @@ public class UtilsSQLCipher {
146
151
  decryptedFile.getAbsolutePath(),
147
152
  "",
148
153
  null,
149
- SQLiteDatabase.OPEN_READWRITE
154
+ SQLiteDatabase.OPEN_READWRITE,
155
+ null
150
156
  );
151
157
 
152
158
  // Open the encrypted database with the provided passphrase
@@ -154,7 +160,8 @@ public class UtilsSQLCipher {
154
160
  originalFile.getAbsolutePath(),
155
161
  new String(passphrase),
156
162
  null,
157
- SQLiteDatabase.OPEN_READWRITE
163
+ SQLiteDatabase.OPEN_READWRITE,
164
+ null
158
165
  );
159
166
 
160
167
  int version = encryptedDb.getVersion();
@@ -196,14 +203,14 @@ public class UtilsSQLCipher {
196
203
  }
197
204
  }
198
205
 
199
- public void changePassword(Context ctxt, File file, String password, String nwpassword) throws IOException {
200
- SQLiteDatabase.loadLibs(ctxt);
206
+ public void changePassword(Context ctxt, File file, String password, String nwpassword) throws Exception {
207
+ System.loadLibrary("sqlcipher");
201
208
 
202
209
  if (file.exists()) {
203
- SQLiteDatabase db = SQLiteDatabase.openDatabase(file.getAbsolutePath(), password, null, SQLiteDatabase.OPEN_READWRITE);
210
+ SQLiteDatabase db = SQLiteDatabase.openDatabase(file.getAbsolutePath(), password, null, SQLiteDatabase.OPEN_READWRITE, null);
204
211
 
205
212
  if (!db.isOpen()) {
206
- throw new SQLiteException("database " + file.getAbsolutePath() + " open failed");
213
+ throw new Exception("database " + file.getAbsolutePath() + " open failed");
207
214
  }
208
215
  db.changePassword(nwpassword);
209
216
  db.close();
@@ -6,7 +6,7 @@ import com.getcapacitor.JSArray;
6
6
  import java.util.ArrayList;
7
7
  import java.util.Arrays;
8
8
  import java.util.List;
9
- import net.sqlcipher.Cursor;
9
+ import net.zetetic.database.sqlcipher.SQLiteCursor;
10
10
  import org.json.JSONArray;
11
11
  import org.json.JSONException;
12
12
  import org.json.JSONObject;
@@ -19,7 +19,7 @@ public class UtilsSQLite {
19
19
  String SELECT_CHANGE = "SELECT total_changes()";
20
20
  Boolean success = true;
21
21
  int ret = Integer.valueOf(-1);
22
- Cursor cursor = (Cursor) db.query(SELECT_CHANGE, null);
22
+ SQLiteCursor cursor = (SQLiteCursor) db.query(SELECT_CHANGE, null);
23
23
  if (cursor != null) {
24
24
  if (cursor.moveToFirst()) {
25
25
  ret = Integer.parseInt(cursor.getString(0));
@@ -33,7 +33,7 @@ public class UtilsSQLite {
33
33
  String SELECT_CHANGE = "SELECT last_insert_rowid()";
34
34
  Boolean success = true;
35
35
  long ret = (long) -1;
36
- Cursor cursor = (Cursor) db.query(SELECT_CHANGE, null);
36
+ SQLiteCursor cursor = (SQLiteCursor) db.query(SELECT_CHANGE, null);
37
37
  if (cursor.moveToFirst()) {
38
38
  ret = Long.parseLong(cursor.getString(0));
39
39
  }
@@ -1259,13 +1259,6 @@ function requireUtilsSQLite () {
1259
1259
  });
1260
1260
  }
1261
1261
  if (mDB != null) {
1262
- try {
1263
- this.dbChanges(mDB);
1264
- }
1265
- catch (err) {
1266
- const errmsg = err.message ? err.message : err;
1267
- throw new Error(`${msg} ${errmsg}`);
1268
- }
1269
1262
  try {
1270
1263
  // set the password
1271
1264
  if (password.length > 0) {
@@ -1278,6 +1271,13 @@ function requireUtilsSQLite () {
1278
1271
  const errmsg = err.message ? err.message : err;
1279
1272
  throw new Error(`${msg} ${errmsg}`);
1280
1273
  }
1274
+ try {
1275
+ this.dbChanges(mDB);
1276
+ }
1277
+ catch (err) {
1278
+ const errmsg = err.message ? err.message : err;
1279
+ throw new Error(`${msg} ${errmsg}`);
1280
+ }
1281
1281
  return mDB;
1282
1282
  }
1283
1283
  else {