@capacitor-community/sqlite 5.0.5-2 → 5.0.5

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.
Files changed (35) hide show
  1. package/android/src/main/java/com/getcapacitor/community/database/sqlite/CapacitorSQLite.java +109 -156
  2. package/android/src/main/java/com/getcapacitor/community/database/sqlite/CapacitorSQLitePlugin.java +81 -249
  3. package/android/src/main/java/com/getcapacitor/community/database/sqlite/NotificationCenter.java +1 -1
  4. package/android/src/main/java/com/getcapacitor/community/database/sqlite/RetHandler.java +0 -12
  5. package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/Database.java +175 -40
  6. package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/ImportExportJson/ExportToJson.java +141 -135
  7. package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/ImportExportJson/ImportFromJson.java +2 -1
  8. package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsBiometric.java +0 -4
  9. package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsFile.java +30 -18
  10. package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsMigrate.java +12 -4
  11. package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsNCDatabase.java +4 -1
  12. package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsSQLCipher.java +8 -6
  13. package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsSQLite.java +14 -28
  14. package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsSecret.java +0 -1
  15. package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsUpgrade.java +0 -1
  16. package/dist/esm/definitions.d.ts +25 -4
  17. package/dist/esm/definitions.js +42 -19
  18. package/dist/esm/definitions.js.map +1 -1
  19. package/dist/plugin.cjs.js +42 -19
  20. package/dist/plugin.cjs.js.map +1 -1
  21. package/dist/plugin.js +42 -19
  22. package/dist/plugin.js.map +1 -1
  23. package/electron/dist/plugin.js +195 -96
  24. package/electron/dist/plugin.js.map +1 -1
  25. package/ios/Plugin/CapacitorSQLite.swift +8 -4
  26. package/ios/Plugin/CapacitorSQLitePlugin.swift +6 -3
  27. package/ios/Plugin/Database.swift +28 -14
  28. package/ios/Plugin/ImportExportJson/ExportToJson.swift +10 -5
  29. package/ios/Plugin/ImportExportJson/ImportFromJson.swift +4 -2
  30. package/ios/Plugin/Utils/UtilsDownloadFromHTTP.swift +61 -61
  31. package/ios/Plugin/Utils/UtilsDrop.swift +2 -1
  32. package/ios/Plugin/Utils/UtilsSQLCipher.swift +255 -23
  33. package/ios/Plugin/Utils/UtilsUpgrade.swift +0 -1
  34. package/package.json +2 -2
  35. package/src/definitions.ts +67 -18
@@ -26,7 +26,7 @@ public class NotificationCenter {
26
26
  public synchronized void addMethodForNotification(String notificationName, MyRunnable r) {
27
27
  ArrayList<MyRunnable> list = registredObjects.get(notificationName);
28
28
  if (list == null) {
29
- list = new ArrayList<MyRunnable>();
29
+ list = new ArrayList<>();
30
30
  registredObjects.put(notificationName, list);
31
31
  }
32
32
  list.add(r);
@@ -27,7 +27,6 @@ public class RetHandler {
27
27
  if (res != null) {
28
28
  ret.put("result", res);
29
29
  call.resolve(ret);
30
- return;
31
30
  } else {
32
31
  call.resolve();
33
32
  }
@@ -51,7 +50,6 @@ public class RetHandler {
51
50
  if (res != null) {
52
51
  ret.put("version", res);
53
52
  call.resolve(ret);
54
- return;
55
53
  } else {
56
54
  call.resolve();
57
55
  }
@@ -70,11 +68,9 @@ public class RetHandler {
70
68
  ret.put("message", message);
71
69
  Log.v(TAG, "*** ERROR " + message);
72
70
  call.reject(message);
73
- return;
74
71
  } else {
75
72
  ret.put("changes", res);
76
73
  call.resolve(ret);
77
- return;
78
74
  }
79
75
  }
80
76
 
@@ -91,11 +87,9 @@ public class RetHandler {
91
87
  ret.put("message", message);
92
88
  Log.v(TAG, "*** ERROR " + message);
93
89
  call.reject(message);
94
- return;
95
90
  } else {
96
91
  ret.put("values", res);
97
92
  call.resolve(ret);
98
- return;
99
93
  }
100
94
  }
101
95
 
@@ -112,11 +106,9 @@ public class RetHandler {
112
106
  ret.put("message", message);
113
107
  Log.v(TAG, "*** ERROR " + message);
114
108
  call.reject(message);
115
- return;
116
109
  } else {
117
110
  ret.put("syncDate", res);
118
111
  call.resolve(ret);
119
- return;
120
112
  }
121
113
  }
122
114
 
@@ -133,11 +125,9 @@ public class RetHandler {
133
125
  ret.put("message", message);
134
126
  Log.v(TAG, "*** ERROR " + message);
135
127
  call.reject(message);
136
- return;
137
128
  } else {
138
129
  ret.put("export", res);
139
130
  call.resolve(ret);
140
- return;
141
131
  }
142
132
  }
143
133
 
@@ -159,7 +149,6 @@ public class RetHandler {
159
149
  if (res != null) {
160
150
  ret.put("path", res);
161
151
  call.resolve(ret);
162
- return;
163
152
  } else {
164
153
  call.resolve();
165
154
  }
@@ -183,7 +172,6 @@ public class RetHandler {
183
172
  if (res != null) {
184
173
  ret.put("url", res);
185
174
  call.resolve(ret);
186
- return;
187
175
  } else {
188
176
  call.resolve();
189
177
  }
@@ -23,12 +23,12 @@ import java.io.File;
23
23
  import java.text.SimpleDateFormat;
24
24
  import java.util.ArrayList;
25
25
  import java.util.Arrays;
26
- import java.util.Base64;
27
- import java.util.Collections;
28
26
  import java.util.Date;
29
27
  import java.util.Dictionary;
30
- import java.util.Hashtable;
31
28
  import java.util.List;
29
+ import java.util.Objects;
30
+ import java.util.regex.Matcher;
31
+ import java.util.regex.Pattern;
32
32
  import net.sqlcipher.Cursor;
33
33
  import net.sqlcipher.database.SQLiteDatabase;
34
34
  import net.sqlcipher.database.SQLiteException;
@@ -43,14 +43,11 @@ public class Database {
43
43
  private final String _dbName;
44
44
  private final Context _context;
45
45
  private final String _mode;
46
- private String _secret;
47
46
  private final Boolean _encrypted;
48
47
  private final Boolean _isEncryption;
49
- private final SharedPreferences _sharedPreferences;
50
48
  private final Boolean _readOnly;
51
49
  private final File _file;
52
50
  private final int _version;
53
- private final GlobalSQLite _globVar;
54
51
  private SupportSQLiteDatabase _db = null;
55
52
  private final UtilsSQLite _uSqlite;
56
53
  private final UtilsSQLCipher _uCipher;
@@ -59,7 +56,7 @@ public class Database {
59
56
  private final UtilsUpgrade _uUpg;
60
57
  private final UtilsDrop _uDrop;
61
58
  private final UtilsSecret _uSecret;
62
- private Dictionary<Integer, JSONObject> _vUpgObject = new Hashtable<>();
59
+ private final Dictionary<Integer, JSONObject> _vUpgObject;
63
60
  private final ImportFromJson fromJson = new ImportFromJson();
64
61
  private final ExportToJson toJson = new ExportToJson();
65
62
  private Boolean ncDB = false;
@@ -82,7 +79,6 @@ public class Database {
82
79
  this._isEncryption = isEncryption;
83
80
  this._version = version;
84
81
  this._vUpgObject = vUpgObject;
85
- this._sharedPreferences = sharedPreferences;
86
82
  this._readOnly = readonly;
87
83
  if (dbName.contains("/") && dbName.endsWith("SQLite.db")) {
88
84
  this.ncDB = true;
@@ -90,7 +86,6 @@ public class Database {
90
86
  } else {
91
87
  this._file = this._context.getDatabasePath(dbName);
92
88
  }
93
- this._globVar = new GlobalSQLite();
94
89
  this._uSqlite = new UtilsSQLite();
95
90
  this._uCipher = new UtilsSQLCipher();
96
91
  this._uFile = new UtilsFile();
@@ -99,8 +94,11 @@ public class Database {
99
94
  this._uDrop = new UtilsDrop();
100
95
  this._uSecret = isEncryption ? new UtilsSecret(context, sharedPreferences) : null;
101
96
  InitializeSQLCipher();
102
- if (!this._file.getParentFile().exists()) {
103
- this._file.getParentFile().mkdirs();
97
+ if (!Objects.requireNonNull(this._file.getParentFile()).exists()) {
98
+ boolean dirCreated = this._file.getParentFile().mkdirs();
99
+ if (!dirCreated) {
100
+ System.out.println("Failed to create parent directories.");
101
+ }
104
102
  }
105
103
  Log.v(TAG, "&&& file path " + this._file.getAbsolutePath());
106
104
  }
@@ -350,14 +348,14 @@ public class Database {
350
348
  * @param set JSArray of statements
351
349
  * @return
352
350
  */
353
- public JSObject executeSet(JSArray set, Boolean... others) throws Exception {
354
- Boolean transaction = others.length == 1 ? others[0] : true;
351
+ public JSObject executeSet(JSArray set, Boolean transaction, String returnMode) throws Exception {
355
352
  JSObject retObj = new JSObject();
356
- Long lastId = Long.valueOf(-1);
357
- Integer changes = Integer.valueOf(-1);
353
+ Long lastId = (long) -1;
354
+ Integer changes = -1;
355
+ JSObject response = new JSObject();
358
356
  try {
359
357
  if (_db != null && _db.isOpen()) {
360
- Integer initChanges = _uSqlite.dbChanges(_db);
358
+ int initChanges = _uSqlite.dbChanges(_db);
361
359
  if (transaction) _db.beginTransaction();
362
360
  for (int i = 0; i < set.length(); i++) {
363
361
  JSONObject row = set.getJSONObject(i);
@@ -375,13 +373,17 @@ public class Database {
375
373
  for (int k = 0; k < valsJson.length(); k++) {
376
374
  vals.add(valsJson.get(k));
377
375
  }
378
- lastId = prepareSQL(statement, vals, false);
376
+ JSObject respSet = prepareSQL(statement, vals, false, returnMode);
377
+ lastId = respSet.getLong("lastId");
379
378
  if (lastId == -1) break;
379
+ response = addToResponse(response, respSet);
380
380
  }
381
381
  } else {
382
- lastId = prepareSQL(statement, values, false);
382
+ JSObject respSet = prepareSQL(statement, values, false, returnMode);
383
+ lastId = respSet.getLong("lastId");
384
+ if (lastId == -1) break;
385
+ response = addToResponse(response, respSet);
383
386
  }
384
- if (lastId == -1) break;
385
387
  }
386
388
  changes = _uSqlite.dbChanges(_db) - initChanges;
387
389
  if (changes >= 0) {
@@ -389,6 +391,7 @@ public class Database {
389
391
  changes = _uSqlite.dbChanges(_db) - initChanges;
390
392
  retObj.put("changes", changes);
391
393
  retObj.put("lastId", lastId);
394
+ retObj.put("values", response.getJSONArray("values"));
392
395
  return retObj;
393
396
  } else {
394
397
  throw new Exception("lastId equals -1");
@@ -403,6 +406,27 @@ public class Database {
403
406
  }
404
407
  }
405
408
 
409
+ public JSObject addToResponse(JSObject response, JSObject respSet) throws JSONException {
410
+ JSObject retResp = response;
411
+ long lastId = respSet.getLong("lastId");
412
+ JSONArray respVals = respSet.getJSONArray("values");
413
+ if (retResp.keys().hasNext()) {
414
+ JSONArray retVals = respSet.getJSONArray("values");
415
+ respVals = response.getJSONArray("values");
416
+ mergeJSONArrays(respVals, retVals);
417
+ }
418
+ retResp.put("lastId", lastId);
419
+ retResp.put("values", respVals);
420
+ return retResp;
421
+ }
422
+
423
+ public static void mergeJSONArrays(JSONArray target, JSONArray source) throws JSONException {
424
+ for (int i = 0; i < source.length(); i++) {
425
+ Object element = source.get(i);
426
+ target.put(element);
427
+ }
428
+ }
429
+
406
430
  /**
407
431
  * InTransaction Method
408
432
  * Check if a transaction is still running
@@ -420,20 +444,21 @@ public class Database {
420
444
  * @param values Array of Strings to bind to the statement
421
445
  * @return
422
446
  */
423
- public JSObject runSQL(String statement, ArrayList<Object> values, Boolean... others) throws Exception {
424
- Boolean transaction = others.length == 1 ? others[0] : true;
447
+ public JSObject runSQL(String statement, ArrayList<Object> values, Boolean transaction, String returnMode) throws Exception {
425
448
  JSObject retObj = new JSObject();
426
- long lastId = Long.valueOf(-1);
427
- int changes = Integer.valueOf(-1);
449
+ long lastId = (long) -1;
450
+ int changes = -1;
428
451
  try {
429
452
  if (_db != null && _db.isOpen() && statement.length() > 0) {
430
- Integer initChanges = _uSqlite.dbChanges(_db);
453
+ int initChanges = _uSqlite.dbChanges(_db);
431
454
  if (transaction) _db.beginTransaction();
432
- lastId = prepareSQL(statement, values, false);
455
+ JSObject response = prepareSQL(statement, values, false, returnMode);
456
+ lastId = response.getLong("lastId");
433
457
  if (lastId != -1 && transaction) _db.setTransactionSuccessful();
434
458
  changes = _uSqlite.dbChanges(_db) - initChanges;
435
459
  retObj.put("changes", changes);
436
460
  retObj.put("lastId", lastId);
461
+ retObj.put("values", response.getJSONArray("values"));
437
462
  return retObj;
438
463
  } else {
439
464
  throw new Exception("Database not opened");
@@ -448,26 +473,49 @@ public class Database {
448
473
  /**
449
474
  * PrepareSQL Method
450
475
  *
451
- * @param statement
452
- * @param values
453
- * @return
476
+ * @param statement SQL statement
477
+ * @param values SQL Values if any
478
+ * @param fromJson is the statement from importFromJson
479
+ * @param returnMode return mode to handle RETURNING
480
+ * @return JSObject
481
+ * @throws Exception message
454
482
  */
455
- public long prepareSQL(String statement, ArrayList<Object> values, Boolean fromJson) throws Exception {
483
+ public JSObject prepareSQL(String statement, ArrayList<Object> values, Boolean fromJson, String returnMode) throws Exception {
456
484
  String stmtType = statement.replaceAll("\n", "").trim().substring(0, 6).toUpperCase();
457
485
  SupportSQLiteStatement stmt = null;
458
486
  String sqlStmt = statement;
487
+ String retMode = returnMode;
488
+ JSArray retValues = new JSArray();
489
+ JSObject retObject = new JSObject();
490
+ String colNames = "";
491
+ long initLastId = (long) -1;
492
+ boolean isReturning = sqlStmt.toUpperCase().contains("RETURNING");
459
493
  try {
460
494
  if (!fromJson && stmtType.equals("DELETE")) {
461
495
  sqlStmt = deleteSQL(this, statement, values);
462
496
  }
463
- stmt = _db.compileStatement(sqlStmt);
497
+ if (isReturning && Build.VERSION.SDK_INT > Build.VERSION_CODES.TIRAMISU) {
498
+ throw new Exception("Not implemented for above TIRAMISU");
499
+ }
500
+ if (isReturning) {
501
+ // get the lastID
502
+ initLastId = _uSqlite.dbLastId(_db);
503
+ // get the statement and the returning column names
504
+ JSObject stmtObj = getStmtAndRetColNames(sqlStmt);
505
+ sqlStmt = stmtObj.getString("stmt");
506
+ colNames = stmtObj.getString("names");
507
+ }
508
+ if (sqlStmt != null) {
509
+ stmt = _db.compileStatement(sqlStmt);
510
+ } else {
511
+ throw new Exception("sqlStmt is null");
512
+ }
464
513
  if (values != null && values.size() > 0) {
514
+ // retMode = "no";
465
515
  Object[] valObj = new Object[values.size()];
466
516
  for (int i = 0; i < values.size(); i++) {
467
517
  if (values.get(i) == null) {
468
518
  valObj[i] = null;
469
- // } else if (values.get(i).equals("NULL")) {
470
- // valObj[i] = null;
471
519
  } else if (JSONObject.NULL == values.get(i)) {
472
520
  valObj[i] = null;
473
521
  } else {
@@ -479,13 +527,28 @@ public class Database {
479
527
  if (stmtType.equals("INSERT")) {
480
528
  stmt.executeInsert();
481
529
  } else {
530
+ if (isReturning && stmtType.equals("DELETE")) {
531
+ isReturning = false;
532
+ retValues = getUpdDelReturnedValues(this, sqlStmt, colNames);
533
+ }
482
534
  stmt.executeUpdateDelete();
483
535
  }
484
- return _uSqlite.dbLastId(_db);
485
- } catch (IllegalStateException e) {
486
- throw new Exception(e.getMessage());
487
- } catch (IllegalArgumentException e) {
488
- throw new Exception(e.getMessage());
536
+ Long lastId = _uSqlite.dbLastId(_db);
537
+ if (isReturning) {
538
+ if (stmtType.equals("INSERT")) {
539
+ String tableName = extractTableName(sqlStmt);
540
+ if (tableName != null) {
541
+ if (retMode.equals("one") || retMode.equals("all")) {
542
+ retValues = getInsertReturnedValues(this, colNames, tableName, initLastId, lastId, retMode);
543
+ }
544
+ }
545
+ } else if (stmtType.equals("UPDATE")) {
546
+ retValues = getUpdDelReturnedValues(this, sqlStmt, colNames);
547
+ }
548
+ }
549
+ retObject.put("lastId", lastId);
550
+ retObject.put("values", retValues);
551
+ return retObject;
489
552
  } catch (Exception e) {
490
553
  throw new Exception(e.getMessage());
491
554
  } finally {
@@ -495,6 +558,76 @@ public class Database {
495
558
  }
496
559
  }
497
560
 
561
+ private JSObject getStmtAndRetColNames(String sqlStmt) {
562
+ JSObject retObj = new JSObject();
563
+ int idx = sqlStmt.toUpperCase().indexOf("RETURNING");
564
+ String retStmt = sqlStmt.substring(0, idx - 1) + ";";
565
+ String names = sqlStmt.substring(idx + 9);
566
+ String retNames = names;
567
+ if (names.contains(";")) retNames = names.substring(0, names.length() - 1).trim();
568
+ retObj.put("stmt", retStmt);
569
+ retObj.put("names", retNames);
570
+ return retObj;
571
+ }
572
+
573
+ private JSArray getInsertReturnedValues(Database mDB, String colNames, String tableName, Long iLastId, Long lastId, String rMode)
574
+ throws Exception {
575
+ JSArray retVals = new JSArray();
576
+ if (iLastId < 0 || colNames.length() == 0) return retVals;
577
+ Long sLastId = iLastId + 1;
578
+ StringBuilder sbQuery = new StringBuilder("SELECT ").append(colNames).append(" FROM ");
579
+
580
+ sbQuery.append(tableName).append(" WHERE ").append("rowid ");
581
+ if (rMode.equals("one")) {
582
+ sbQuery.append("= ").append(sLastId);
583
+ }
584
+ if (rMode.equals("all")) {
585
+ sbQuery.append("BETWEEN ").append(sLastId).append(" AND ").append(lastId);
586
+ }
587
+ sbQuery.append(";");
588
+ retVals = mDB.selectSQL(sbQuery.toString(), new ArrayList<>());
589
+
590
+ return retVals;
591
+ }
592
+
593
+ private JSArray getUpdDelReturnedValues(Database mDB, String stmt, String colNames) throws Exception {
594
+ JSArray retVals = new JSArray();
595
+ String tableName = extractTableName(stmt);
596
+ String whereClause = extractWhereClause(stmt);
597
+ if (whereClause != null && tableName != null) {
598
+ StringBuilder sbQuery = new StringBuilder("SELECT ").append(colNames).append(" FROM ");
599
+ sbQuery.append(tableName).append(" WHERE ").append(whereClause).append(";");
600
+ retVals = mDB.selectSQL(sbQuery.toString(), new ArrayList<>());
601
+ }
602
+ return retVals;
603
+ }
604
+
605
+ private static String extractTableName(String statement) {
606
+ Pattern pattern = Pattern.compile("(?i)(?:INSERT\\s+INTO|UPDATE|DELETE\\s+FROM)\\s+(\\w+)");
607
+ Matcher matcher = pattern.matcher(statement);
608
+ if (matcher.find()) {
609
+ return matcher.group(1);
610
+ }
611
+ return null;
612
+ }
613
+
614
+ private static String extractWhereClause(String sqlStatement) {
615
+ // Regular expression pattern to match the WHERE clause and removing the
616
+ // ORDER BY and LIMIT if any
617
+ Pattern pattern = Pattern.compile("(?i)\\bWHERE\\b\\s*(.*?)(?:\\s*\\b(?:ORDER\\s+BY|LIMIT)\\b|$)");
618
+ Matcher matcher = pattern.matcher(sqlStatement);
619
+
620
+ if (matcher.find()) {
621
+ String whereClause = matcher.group(1);
622
+ if (whereClause != null && whereClause.endsWith(";")) {
623
+ whereClause = whereClause.substring(0, whereClause.length() - 1);
624
+ }
625
+ return whereClause.trim();
626
+ }
627
+
628
+ return null;
629
+ }
630
+
498
631
  /**
499
632
  * DeleteSQL method
500
633
  *
@@ -575,10 +708,11 @@ public class Database {
575
708
  ArrayList<Object> selValues = new ArrayList<Object>();
576
709
  if (values != null && values.size() > 0) {
577
710
  String[] arrVal = whereStmt.split("\\?");
711
+ String[] modArr = arrVal;
578
712
  if (arrVal[arrVal.length - 1].equals(";")) {
579
- Arrays.copyOf(arrVal, arrVal.length - 1);
713
+ modArr = Arrays.copyOf(arrVal, arrVal.length - 1);
580
714
  }
581
- for (int j = 0; j < arrVal.length; j++) {
715
+ for (int j = 0; j < modArr.length; j++) {
582
716
  for (String updVal : updColNames) {
583
717
  int idxVal = arrVal[j].indexOf(updVal);
584
718
  if (idxVal > -1) {
@@ -588,7 +722,8 @@ public class Database {
588
722
  }
589
723
  }
590
724
 
591
- long lastId = prepareSQL(stmt, selValues, false);
725
+ JSObject retObj = prepareSQL(stmt, selValues, false, "no");
726
+ long lastId = retObj.getLong("lastId");
592
727
  if (lastId == -1) {
593
728
  String msg = "UPDATE sql_deleted failed for references " + "table: " + refTable + ";";
594
729
  throw new Exception(msg);