@capacitor-community/sqlite 3.4.3-1 → 3.4.3

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 (30) hide show
  1. package/README.md +55 -21
  2. package/android/src/main/java/com/getcapacitor/community/database/sqlite/CapacitorSQLite.java +41 -2
  3. package/android/src/main/java/com/getcapacitor/community/database/sqlite/CapacitorSQLitePlugin.java +26 -0
  4. package/android/src/main/java/com/getcapacitor/community/database/sqlite/NotificationCenter.java +1 -1
  5. package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/Database.java +220 -7
  6. package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/ImportExportJson/ExportToJson.java +100 -3
  7. package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/ImportExportJson/ImportFromJson.java +37 -34
  8. package/dist/esm/definitions.d.ts +18 -4
  9. package/dist/esm/definitions.js +9 -17
  10. package/dist/esm/definitions.js.map +1 -1
  11. package/dist/esm/web.d.ts +2 -1
  12. package/dist/esm/web.js +11 -0
  13. package/dist/esm/web.js.map +1 -1
  14. package/dist/plugin.cjs.js +22 -19
  15. package/dist/plugin.cjs.js.map +1 -1
  16. package/dist/plugin.js +1035 -1032
  17. package/dist/plugin.js.map +1 -1
  18. package/electron/dist/plugin.js +662 -335
  19. package/electron/dist/plugin.js.map +1 -1
  20. package/ios/Plugin/CapacitorSQLite.swift +34 -1
  21. package/ios/Plugin/CapacitorSQLitePlugin.m +1 -0
  22. package/ios/Plugin/CapacitorSQLitePlugin.swift +25 -0
  23. package/ios/Plugin/Database.swift +29 -1
  24. package/ios/Plugin/Extensions/String.swift +8 -0
  25. package/ios/Plugin/ImportExportJson/ExportToJson.swift +154 -25
  26. package/ios/Plugin/ImportExportJson/ImportFromJson.swift +53 -27
  27. package/ios/Plugin/Utils/UtilsDrop.swift +2 -2
  28. package/ios/Plugin/Utils/UtilsSQLCipher.swift +277 -8
  29. package/ios/Plugin/Utils/UtilsUpgrade.swift +0 -1
  30. package/package.json +2 -2
@@ -13,6 +13,7 @@ enum UtilsSQLCipherError: Error {
13
13
  case openOrCreateDatabase(message: String)
14
14
  case bindFailed
15
15
  case setForeignKeyConstraintsEnabled(message: String)
16
+ case getForeignKeysStateFailed(message: String)
16
17
  case getVersion(message: String)
17
18
  case setVersion(message: String)
18
19
  case closeDB(message: String)
@@ -23,6 +24,9 @@ enum UtilsSQLCipherError: Error {
23
24
  case commitTransaction(message: String)
24
25
  case execute(message: String)
25
26
  case prepareSQL(message: String)
27
+ case deleteSQL(message: String)
28
+ case findReferenciesAndUpdate(message: String)
29
+ case getReferencies(message: String)
26
30
  case querySQL(message: String)
27
31
  case fetchColumnInfo(message: String)
28
32
  case deleteDB(message: String)
@@ -233,6 +237,40 @@ class UtilsSQLCipher {
233
237
 
234
238
  }
235
239
 
240
+ // MARK: - GetForeignKeysState
241
+
242
+ class func getForeignKeysState(mDB: Database) throws -> Int {
243
+ var msg: String = "Error ForeignKeysState: "
244
+ if !mDB.isDBOpen() {
245
+ msg.append("Database not opened")
246
+ throw UtilsSQLCipherError.getForeignKeysStateFailed(message: msg)
247
+ }
248
+ var fkState: Int = 0
249
+
250
+ let sqltr: String = "PRAGMA foreign_keys;"
251
+ do {
252
+ var resForKeys = try UtilsSQLCipher.querySQL(mDB: mDB,
253
+ sql: sqltr,
254
+ values: [])
255
+ if resForKeys.count > 1 {
256
+ resForKeys.removeFirst()
257
+ guard let res: Int64 = resForKeys[0]["foreign_keys"]
258
+ as? Int64 else {
259
+ throw UtilsSQLCipherError.getForeignKeysStateFailed(
260
+ message: "Error get foreign keys failed")
261
+ }
262
+ if res > 0 {
263
+ fkState = Int(truncatingIfNeeded: res)
264
+
265
+ }
266
+ }
267
+ return fkState
268
+ } catch UtilsSQLCipherError.querySQL(let message) {
269
+ throw UtilsSQLCipherError.getForeignKeysStateFailed(
270
+ message: message)
271
+ }
272
+ }
273
+
236
274
  // MARK: - GetVersion
237
275
 
238
276
  class func getVersion(mDB: Database) throws -> Int {
@@ -262,7 +300,7 @@ class UtilsSQLCipher {
262
300
  }
263
301
  return version
264
302
  } catch UtilsSQLCipherError.querySQL(let message) {
265
- throw UtilsUpgradeError.getDatabaseVersionFailed(
303
+ throw UtilsSQLCipherError.getVersion(
266
304
  message: message)
267
305
  }
268
306
  }
@@ -373,8 +411,9 @@ class UtilsSQLCipher {
373
411
  // MARK: - PrepareSQL
374
412
 
375
413
  // swiftlint:disable function_body_length
376
- class func prepareSQL(mDB: Database,
377
- sql: String, values: [Any]) throws -> Int64 {
414
+ // swiftlint:disable cyclomatic_complexity
415
+ class func prepareSQL(mDB: Database, sql: String, values: [Any],
416
+ fromJson: Bool) throws -> Int64 {
378
417
  var msg: String = "Error prepareSQL: "
379
418
  if !mDB.isDBOpen() {
380
419
  msg.append("Database not opened")
@@ -383,9 +422,19 @@ class UtilsSQLCipher {
383
422
  var runSQLStatement: OpaquePointer?
384
423
  var message: String = ""
385
424
  var lastId: Int64 = -1
386
-
425
+ var sqlStmt = sql
426
+ // Check for DELETE statement
427
+ if !fromJson && sqlStmt.prefix(6).uppercased() == "DELETE" {
428
+ do {
429
+ sqlStmt = try deleteSQL(mDB: mDB, sql: sql,
430
+ values: values)
431
+ } catch UtilsSQLCipherError.deleteSQL(let message) {
432
+ let msg = "Error: prepareSQL \(message)"
433
+ throw UtilsSQLCipherError.prepareSQL(message: msg)
434
+ }
435
+ }
387
436
  var returnCode: Int32 = sqlite3_prepare_v2(
388
- mDB.mDb, sql, -1, &runSQLStatement, nil)
437
+ mDB.mDb, sqlStmt, -1, &runSQLStatement, nil)
389
438
  if returnCode == SQLITE_OK {
390
439
  if !values.isEmpty {
391
440
  // do the binding of values
@@ -429,8 +478,198 @@ class UtilsSQLCipher {
429
478
  return lastId
430
479
  }
431
480
  }
481
+ // swiftlint:enable cyclomatic_complexity
432
482
  // swiftlint:enable function_body_length
433
483
 
484
+ // MARK: - deleteSQL
485
+
486
+ class func deleteSQL(mDB: Database, sql: String, values: [Any]) throws -> String {
487
+ var sqlStmt = sql
488
+ do {
489
+ let isLast: Bool = try UtilsJson.isLastModified(mDB: mDB)
490
+ if isLast {
491
+ if let range: Range<String.Index> = sql
492
+ .range(of: "WHERE", options: .caseInsensitive) {
493
+ let index: Int = sql
494
+ .distance(from: sql.startIndex, to: range.lowerBound)
495
+ let preStmt = String(sql.stringRange(fromIdx: 0,
496
+ toIdx: (index - 1)))
497
+ let clauseStmt = String(sql.stringRange(fromIdx: index,
498
+ toIdx: sql.count))
499
+ let tableName = (preStmt.deletingPrefix("DELETE FROM"))
500
+ .trimmingLeadingAndTrailingSpaces()
501
+ sqlStmt = "UPDATE \(tableName) SET sql_deleted = 1 "
502
+ sqlStmt += clauseStmt
503
+ // Find REFERENCIES if any and update the sql_deleted column
504
+ try findReferenciesAndUpdate(mDB: mDB,
505
+ tableName: tableName,
506
+ whereStmt: clauseStmt,
507
+ values: values)
508
+ } else {
509
+ let msg: String = "deleteSQL cannot find a WHERE clause"
510
+ throw UtilsSQLCipherError.deleteSQL(message: msg)
511
+ }
512
+ }
513
+ return sqlStmt
514
+ } catch UtilsSQLCipherError.findReferenciesAndUpdate(let message) {
515
+ throw UtilsSQLCipherError.deleteSQL(message: message)
516
+ } catch UtilsJsonError.isLastModified(let message) {
517
+ throw UtilsSQLCipherError.deleteSQL(message: message)
518
+ }
519
+ }
520
+
521
+ // MARK: - findReferencesAndUpdate
522
+
523
+ class func findReferenciesAndUpdate(mDB: Database, tableName: String,
524
+ whereStmt: String,
525
+ values: [Any]) throws {
526
+ do {
527
+ let referencies = try getReferencies(mDB: mDB,
528
+ tableName: tableName)
529
+ if referencies.count <= 0 {
530
+ return
531
+ }
532
+ // Loop through referencies
533
+ for ref in referencies {
534
+ // get the tableName of the references
535
+ let refTable: String = getReferencesTableName(value: ref)
536
+ if refTable.count <= 0 {
537
+ continue
538
+ }
539
+ // get the columnName
540
+ let colName: String = getReferencesColumnName(value: ref)
541
+ if colName.count <= 0 {
542
+ continue
543
+ }
544
+ // update the where clause
545
+ let uWhereStmt: String = updateWhere(whStmt: whereStmt,
546
+ colName: colName)
547
+
548
+ if uWhereStmt.count <= 0 {
549
+ continue
550
+ }
551
+ //update sql_deleted for this references
552
+ let stmt = "UPDATE \(refTable) SET sql_deleted = 1 " +
553
+ uWhereStmt
554
+ let lastId = try prepareSQL(mDB: mDB, sql: stmt,
555
+ values: values, fromJson: false)
556
+ if lastId == -1 {
557
+ let msg = "UPDATE sql_deleted failed for references " +
558
+ "table: \(refTable) "
559
+ throw UtilsSQLCipherError
560
+ .findReferenciesAndUpdate(message: msg)
561
+ }
562
+ }
563
+ return
564
+ } catch UtilsSQLCipherError.prepareSQL(let message) {
565
+ throw UtilsSQLCipherError
566
+ .findReferenciesAndUpdate(message: message)
567
+ } catch UtilsSQLCipherError.querySQL(let message) {
568
+ throw UtilsSQLCipherError
569
+ .findReferenciesAndUpdate(message: message)
570
+ }
571
+
572
+ }
573
+
574
+ // MARK: - getReferencies
575
+
576
+ class func getReferencies(mDB: Database, tableName: String)
577
+ throws -> [[String: Any]] {
578
+ // find the REFERENCIES
579
+ var sqlStmt = "SELECT sql FROM sqlite_master "
580
+ sqlStmt += "WHERE sql LIKE('%REFERENCES%') AND "
581
+ sqlStmt += "sql LIKE('%\(tableName)%') AND sql LIKE('%ON DELETE%');"
582
+ do {
583
+ var referencies: [[String: Any]] = try querySQL(mDB: mDB,
584
+ sql: sqlStmt,
585
+ values: [])
586
+ if referencies.count > 1 {
587
+ referencies.removeFirst()
588
+ }
589
+ return referencies
590
+ } catch UtilsSQLCipherError.querySQL(let message) {
591
+ throw UtilsSQLCipherError
592
+ .getReferencies(message: message)
593
+ }
594
+ }
595
+
596
+ // MARK: - getReferencesTableName
597
+
598
+ class func getReferencesTableName(value: [String: Any]) -> String {
599
+
600
+ var tableName: String = ""
601
+ if let refValue = value["sql"] as? String {
602
+
603
+ if let range: Range<String.Index> = refValue
604
+ .range(of: "CREATE TABLE", options: .caseInsensitive) {
605
+ let index: Int = refValue
606
+ .distance(from: refValue.startIndex, to: range.lowerBound)
607
+ let stmt = String(refValue.stringRange(fromIdx: index + 13,
608
+ toIdx: refValue.count))
609
+ if let oPar = stmt.firstIndex(of: "(") {
610
+ let idx: Int = stmt.distance(from: stmt.startIndex, to: oPar)
611
+ tableName = String(stmt.stringRange(fromIdx: 0, toIdx: idx))
612
+ .trimmingLeadingAndTrailingSpaces()
613
+ }
614
+ }
615
+ }
616
+ return tableName
617
+ }
618
+
619
+ // MARK: - getReferencesColumnName
620
+
621
+ class func getReferencesColumnName(value: [String: Any]) -> String {
622
+
623
+ var colName: String = ""
624
+ if let refValue = value["sql"] as? String {
625
+
626
+ if let range: Range<String.Index> = refValue
627
+ .range(of: "FOREIGN KEY", options: .caseInsensitive) {
628
+ let index: Int = refValue
629
+ .distance(from: refValue.startIndex, to: range.lowerBound)
630
+ let stmt = String(refValue.stringRange(fromIdx: index + 12,
631
+ toIdx: refValue.count))
632
+ if let oPar = stmt.firstIndex(of: "(") {
633
+ let idxOPar: Int = stmt.distance(from: stmt.startIndex,
634
+ to: oPar) + 1
635
+ if let cPar = stmt.firstIndex(of: ")") {
636
+ let idxCPar: Int = stmt
637
+ .distance(from: stmt.startIndex,
638
+ to: cPar)
639
+ colName = String(stmt.stringRange(fromIdx: idxOPar,
640
+ toIdx: idxCPar))
641
+ .trimmingLeadingAndTrailingSpaces()
642
+
643
+ }
644
+ }
645
+ }
646
+ }
647
+
648
+ return colName
649
+ }
650
+
651
+ class func updateWhere(whStmt: String, colName: String) -> String {
652
+ var whereStmt = ""
653
+ if let range: Range<String.Index> = whStmt
654
+ .range(of: "WHERE", options: .caseInsensitive) {
655
+ let index: Int = whStmt
656
+ .distance(from: whStmt.startIndex, to: range.lowerBound)
657
+ let stmt = String(whStmt.stringRange(fromIdx: index + 6,
658
+ toIdx: whStmt.count))
659
+ if let fEqual = stmt.firstIndex(of: "=") {
660
+ let idxfEqual: Int = stmt.distance(from: stmt.startIndex,
661
+ to: fEqual)
662
+ let whereColName = String(stmt.stringRange(fromIdx: 0,
663
+ toIdx: idxfEqual))
664
+ .trimmingLeadingAndTrailingSpaces()
665
+ whereStmt = whStmt.replacingOccurrences(of: whereColName, with: colName)
666
+
667
+ }
668
+ }
669
+
670
+ return whereStmt
671
+ }
672
+
434
673
  // MARK: - querySQL
435
674
 
436
675
  class func querySQL(mDB: Database, sql: String,
@@ -565,8 +804,34 @@ class UtilsSQLCipher {
565
804
  msg.append("Database not opened")
566
805
  throw UtilsSQLCipherError.execute(message: msg)
567
806
  }
807
+ var sqlStmt = sql
808
+ if sql.localizedCaseInsensitiveContains("DELETE FROM") {
809
+ sqlStmt = sqlStmt.replacingOccurrences(of: "\n",
810
+ with: "")
811
+ var stmtArr = sqlStmt.components(separatedBy: ";")
812
+ stmtArr.removeLast()
813
+ var resArr: [String] = []
814
+ for stmt in stmtArr {
815
+ let trimStmt = stmt
816
+ .trimmingLeadingAndTrailingSpaces().prefix(11).uppercased()
817
+ if trimStmt == "DELETE FROM" &&
818
+ stmt.localizedCaseInsensitiveContains("WHERE") {
819
+ let whereStmt = stmt.trimmingLeadingAndTrailingSpaces()
820
+ do {
821
+ let rStmt: String = try deleteSQL(mDB: mDB, sql: whereStmt, values: [])
822
+ resArr.append(rStmt)
823
+ } catch UtilsSQLCipherError.deleteSQL(let message) {
824
+ let msg = "Error: execute \(message)"
825
+ throw UtilsSQLCipherError.execute(message: msg)
826
+ }
827
+ } else {
828
+ resArr.append(String(stmt))
829
+ }
830
+ }
831
+ sqlStmt = resArr.joined(separator: ";")
832
+ }
568
833
 
569
- let returnCode: Int32 = sqlite3_exec(mDB.mDb, sql, nil,
834
+ let returnCode: Int32 = sqlite3_exec(mDB.mDb, sqlStmt, nil,
570
835
  nil, nil)
571
836
  if returnCode != SQLITE_OK {
572
837
  let errmsg: String = String(
@@ -633,7 +898,7 @@ class UtilsSQLCipher {
633
898
  for vals in arrValues {
634
899
  lastId = try UtilsSQLCipher
635
900
  .prepareSQL(mDB: mDB, sql: sql,
636
- values: vals)
901
+ values: vals, fromJson: false)
637
902
  if lastId == -1 {
638
903
  let message: String = "lastId < 0"
639
904
  throw UtilsSQLCipherError
@@ -643,7 +908,8 @@ class UtilsSQLCipher {
643
908
  }
644
909
  } else {
645
910
  lastId = try UtilsSQLCipher
646
- .prepareSQL(mDB: mDB, sql: sql, values: values)
911
+ .prepareSQL(mDB: mDB, sql: sql, values: values,
912
+ fromJson: false)
647
913
  if lastId == -1 {
648
914
  let message: String = "lastId < 0"
649
915
  throw UtilsSQLCipherError.executeSet(
@@ -741,6 +1007,9 @@ class UtilsSQLCipher {
741
1007
  }
742
1008
 
743
1009
  }
1010
+
1011
+ // MARK: - parse
1012
+
744
1013
  class func parse(mVar: Any) -> Bool {
745
1014
  var ret: Bool = false
746
1015
  if mVar is NSArray {
@@ -15,7 +15,6 @@ enum UtilsUpgradeError: Error {
15
15
  case backupTableFailed(message: String)
16
16
  case getTableColumnNamesFailed(message: String)
17
17
  case updateDatabaseVersionFailed(message: String)
18
- case getDatabaseVersionFailed(message: String)
19
18
  case findCommonColumnsFailed(message: String)
20
19
  case arrayIntersectionFailed(message: String)
21
20
  case updateNewTablesDataFailed(message: String)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capacitor-community/sqlite",
3
- "version": "3.4.3-1",
3
+ "version": "3.4.3",
4
4
  "description": "Community plugin for native & electron SQLite databases",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",
@@ -93,6 +93,6 @@
93
93
  }
94
94
  },
95
95
  "dependencies": {
96
- "jeep-sqlite": "^1.4.2"
96
+ "jeep-sqlite": "^1.5.1"
97
97
  }
98
98
  }