@capacitor-community/sqlite 3.4.2-5 → 3.4.3-2
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 +46 -4
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/CapacitorSQLite.java +41 -2
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/CapacitorSQLitePlugin.java +26 -0
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/NotificationCenter.java +1 -1
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/Database.java +220 -7
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/ImportExportJson/ExportToJson.java +102 -86
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/ImportExportJson/ImportFromJson.java +127 -38
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/ImportExportJson/UtilsJson.java +90 -0
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsUpgrade.java +8 -4
- package/dist/esm/definitions.d.ts +17 -1
- package/dist/esm/definitions.js +22 -28
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/web.d.ts +20 -11
- package/dist/esm/web.js +288 -473
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +286 -477
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +1036 -1227
- package/dist/plugin.js.map +1 -1
- package/electron/dist/plugin.js +589 -744
- package/electron/dist/plugin.js.map +1 -1
- package/ios/Plugin/CapacitorSQLite.swift +34 -1
- package/ios/Plugin/CapacitorSQLitePlugin.m +1 -0
- package/ios/Plugin/CapacitorSQLitePlugin.swift +25 -0
- package/ios/Plugin/Database.swift +29 -1
- package/ios/Plugin/Extensions/String.swift +8 -0
- package/ios/Plugin/ImportExportJson/ExportToJson.swift +190 -32
- package/ios/Plugin/ImportExportJson/ImportFromJson.swift +73 -38
- package/ios/Plugin/Utils/UtilsDrop.swift +2 -2
- package/ios/Plugin/Utils/UtilsJson.swift +68 -1
- package/ios/Plugin/Utils/UtilsSQLCipher.swift +277 -29
- package/ios/Plugin/Utils/UtilsUpgrade.swift +33 -13
- package/package.json +6 -6
|
@@ -232,8 +232,8 @@ class UtilsDrop {
|
|
|
232
232
|
changes += retChanges
|
|
233
233
|
retChanges = try self.dropViews(mDB: mDB)
|
|
234
234
|
if changes >= 0 {
|
|
235
|
-
_ = try UtilsSQLCipher.prepareSQL(mDB: mDB,
|
|
236
|
-
|
|
235
|
+
_ = try UtilsSQLCipher.prepareSQL(mDB: mDB, sql: "VACUUM;",
|
|
236
|
+
values: [], fromJson: false)
|
|
237
237
|
changes = UtilsSQLCipher.dbChanges(mDB: mDB.mDb) -
|
|
238
238
|
initChanges
|
|
239
239
|
}
|
|
@@ -18,8 +18,10 @@ enum UtilsJsonError: Error {
|
|
|
18
18
|
case validateTriggers(message: String)
|
|
19
19
|
case validateViews(message: String)
|
|
20
20
|
case isLastModified(message: String)
|
|
21
|
-
|
|
21
|
+
case checkUpdate(message: String)
|
|
22
|
+
case checkValues(message: String)}
|
|
22
23
|
|
|
24
|
+
// swiftlint:disable file_length
|
|
23
25
|
// swiftlint:disable type_body_length
|
|
24
26
|
class UtilsJson {
|
|
25
27
|
|
|
@@ -238,6 +240,70 @@ class UtilsJson {
|
|
|
238
240
|
return retArray
|
|
239
241
|
}
|
|
240
242
|
|
|
243
|
+
// MARK: - ImportFromJson - CheckUpdate
|
|
244
|
+
|
|
245
|
+
// swiftlint:disable function_parameter_count
|
|
246
|
+
class func checkUpdate(mDB: Database, stmt: String, values: [Any],
|
|
247
|
+
tableName: String, names: [String],
|
|
248
|
+
types: [String]) throws -> Bool {
|
|
249
|
+
var isRun: Bool = true
|
|
250
|
+
if stmt.prefix(6) == "UPDATE" {
|
|
251
|
+
var query: String = "SELECT * FROM \(tableName) WHERE \(names[0]) = "
|
|
252
|
+
if type(of: values[0]) == String.self {
|
|
253
|
+
query.append("'\(values[0])';")
|
|
254
|
+
} else {
|
|
255
|
+
query.append("\(values[0]);")
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
do {
|
|
259
|
+
// create the table data
|
|
260
|
+
let resValues: [[Any]] = try ExportToJson
|
|
261
|
+
.createValues(mDB: mDB, query: query, names: names,
|
|
262
|
+
types: types)
|
|
263
|
+
if resValues.count > 0 {
|
|
264
|
+
isRun = try checkValues(values: values, nValues: resValues[0])
|
|
265
|
+
return isRun
|
|
266
|
+
} else {
|
|
267
|
+
let msg = "CheckUpdate statement returns nothing"
|
|
268
|
+
throw UtilsJsonError.checkUpdate(message: msg)
|
|
269
|
+
}
|
|
270
|
+
} catch ExportToJsonError.createValues(let message) {
|
|
271
|
+
throw UtilsJsonError.checkUpdate(message: message)
|
|
272
|
+
} catch UtilsJsonError.checkValues(let message) {
|
|
273
|
+
throw UtilsJsonError.checkUpdate(message: message)
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
return isRun
|
|
277
|
+
}
|
|
278
|
+
// swiftlint:enable function_parameter_count
|
|
279
|
+
|
|
280
|
+
// MARK: - ImportFromJson - CheckValues
|
|
281
|
+
|
|
282
|
+
class func checkValues(values: [Any], nValues: [Any]) throws -> Bool {
|
|
283
|
+
if values.count > 0 && nValues.count > 0
|
|
284
|
+
&& values.count == nValues.count {
|
|
285
|
+
let valuesWithIndex = values.enumerated()
|
|
286
|
+
for (index, mValue) in valuesWithIndex {
|
|
287
|
+
let rValue = nValues[index]
|
|
288
|
+
if type(of: rValue) == Double.self {
|
|
289
|
+
if let dValue = rValue as? Double {
|
|
290
|
+
if let dValues = mValue as? Double {
|
|
291
|
+
if !dValue.isEqual(to: dValues) {
|
|
292
|
+
return true
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
} else if rValue as AnyObject !== values[index] as AnyObject {
|
|
297
|
+
return true
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
return false
|
|
301
|
+
} else {
|
|
302
|
+
let msg = "CheckValues Both arrays not the same length"
|
|
303
|
+
throw UtilsJsonError.checkValues(message: msg)
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
}
|
|
241
307
|
// MARK: - ImportFromJson - SetNameForUpdate
|
|
242
308
|
|
|
243
309
|
class func setNameForUpdate(names: [String]) -> String {
|
|
@@ -374,3 +440,4 @@ class UtilsJson {
|
|
|
374
440
|
|
|
375
441
|
}
|
|
376
442
|
// swiftlint:enable type_body_length
|
|
443
|
+
// swiftlint:enable file_length
|
|
@@ -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)
|
|
@@ -159,27 +163,6 @@ class UtilsSQLCipher {
|
|
|
159
163
|
let msg: String = "Cannot open the DB"
|
|
160
164
|
throw UtilsSQLCipherError.openOrCreateDatabase(message: msg)
|
|
161
165
|
}
|
|
162
|
-
|
|
163
|
-
/* this should work but doe not sqlite3_key_v2 is not known
|
|
164
|
-
if password.count > 0 {
|
|
165
|
-
let nKey:Int32 = Int32(password.count)
|
|
166
|
-
if sqlite3_key_v2(mDB!, filename, password, nKey) == SQLITE_OK {
|
|
167
|
-
var stmt: String = "SELECT count(*) FROM "
|
|
168
|
-
stmt.append("sqlite_master;")
|
|
169
|
-
if sqlite3_exec(mDB, stmt, nil, nil, nil) !=
|
|
170
|
-
SQLITE_OK {
|
|
171
|
-
print("Unable to open a database \(filename)")
|
|
172
|
-
throw UtilsSQLCipherError
|
|
173
|
-
.openOrCreateDatabase(message: msg)
|
|
174
|
-
}
|
|
175
|
-
} else {
|
|
176
|
-
print("Unable to open a database \(filename)")
|
|
177
|
-
throw UtilsSQLCipherError
|
|
178
|
-
.openOrCreateDatabase(message: msg)
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
print("Successfully opened database \(filename)")
|
|
182
|
-
*/
|
|
183
166
|
return mDB
|
|
184
167
|
} else {
|
|
185
168
|
let message: String = "open_v2 failed"
|
|
@@ -254,6 +237,40 @@ class UtilsSQLCipher {
|
|
|
254
237
|
|
|
255
238
|
}
|
|
256
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
|
+
|
|
257
274
|
// MARK: - GetVersion
|
|
258
275
|
|
|
259
276
|
class func getVersion(mDB: Database) throws -> Int {
|
|
@@ -283,7 +300,7 @@ class UtilsSQLCipher {
|
|
|
283
300
|
}
|
|
284
301
|
return version
|
|
285
302
|
} catch UtilsSQLCipherError.querySQL(let message) {
|
|
286
|
-
throw
|
|
303
|
+
throw UtilsSQLCipherError.getVersion(
|
|
287
304
|
message: message)
|
|
288
305
|
}
|
|
289
306
|
}
|
|
@@ -394,8 +411,9 @@ class UtilsSQLCipher {
|
|
|
394
411
|
// MARK: - PrepareSQL
|
|
395
412
|
|
|
396
413
|
// swiftlint:disable function_body_length
|
|
397
|
-
|
|
398
|
-
|
|
414
|
+
// swiftlint:disable cyclomatic_complexity
|
|
415
|
+
class func prepareSQL(mDB: Database, sql: String, values: [Any],
|
|
416
|
+
fromJson: Bool) throws -> Int64 {
|
|
399
417
|
var msg: String = "Error prepareSQL: "
|
|
400
418
|
if !mDB.isDBOpen() {
|
|
401
419
|
msg.append("Database not opened")
|
|
@@ -404,9 +422,19 @@ class UtilsSQLCipher {
|
|
|
404
422
|
var runSQLStatement: OpaquePointer?
|
|
405
423
|
var message: String = ""
|
|
406
424
|
var lastId: Int64 = -1
|
|
407
|
-
|
|
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
|
+
}
|
|
408
436
|
var returnCode: Int32 = sqlite3_prepare_v2(
|
|
409
|
-
mDB.mDb,
|
|
437
|
+
mDB.mDb, sqlStmt, -1, &runSQLStatement, nil)
|
|
410
438
|
if returnCode == SQLITE_OK {
|
|
411
439
|
if !values.isEmpty {
|
|
412
440
|
// do the binding of values
|
|
@@ -450,8 +478,198 @@ class UtilsSQLCipher {
|
|
|
450
478
|
return lastId
|
|
451
479
|
}
|
|
452
480
|
}
|
|
481
|
+
// swiftlint:enable cyclomatic_complexity
|
|
453
482
|
// swiftlint:enable function_body_length
|
|
454
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
|
+
|
|
455
673
|
// MARK: - querySQL
|
|
456
674
|
|
|
457
675
|
class func querySQL(mDB: Database, sql: String,
|
|
@@ -586,8 +804,34 @@ class UtilsSQLCipher {
|
|
|
586
804
|
msg.append("Database not opened")
|
|
587
805
|
throw UtilsSQLCipherError.execute(message: msg)
|
|
588
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
|
+
}
|
|
589
833
|
|
|
590
|
-
let returnCode: Int32 = sqlite3_exec(mDB.mDb,
|
|
834
|
+
let returnCode: Int32 = sqlite3_exec(mDB.mDb, sqlStmt, nil,
|
|
591
835
|
nil, nil)
|
|
592
836
|
if returnCode != SQLITE_OK {
|
|
593
837
|
let errmsg: String = String(
|
|
@@ -654,7 +898,7 @@ class UtilsSQLCipher {
|
|
|
654
898
|
for vals in arrValues {
|
|
655
899
|
lastId = try UtilsSQLCipher
|
|
656
900
|
.prepareSQL(mDB: mDB, sql: sql,
|
|
657
|
-
values: vals)
|
|
901
|
+
values: vals, fromJson: false)
|
|
658
902
|
if lastId == -1 {
|
|
659
903
|
let message: String = "lastId < 0"
|
|
660
904
|
throw UtilsSQLCipherError
|
|
@@ -664,7 +908,8 @@ class UtilsSQLCipher {
|
|
|
664
908
|
}
|
|
665
909
|
} else {
|
|
666
910
|
lastId = try UtilsSQLCipher
|
|
667
|
-
.prepareSQL(mDB: mDB, sql: sql, values: values
|
|
911
|
+
.prepareSQL(mDB: mDB, sql: sql, values: values,
|
|
912
|
+
fromJson: false)
|
|
668
913
|
if lastId == -1 {
|
|
669
914
|
let message: String = "lastId < 0"
|
|
670
915
|
throw UtilsSQLCipherError.executeSet(
|
|
@@ -762,6 +1007,9 @@ class UtilsSQLCipher {
|
|
|
762
1007
|
}
|
|
763
1008
|
|
|
764
1009
|
}
|
|
1010
|
+
|
|
1011
|
+
// MARK: - parse
|
|
1012
|
+
|
|
765
1013
|
class func parse(mVar: Any) -> Bool {
|
|
766
1014
|
var ret: Bool = false
|
|
767
1015
|
if mVar is NSArray {
|
|
@@ -15,14 +15,13 @@ 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)
|
|
22
21
|
case executeStatementProcessFailed(message: String)
|
|
23
22
|
case executeSetProcessFailed(message: String)
|
|
24
23
|
}
|
|
25
|
-
|
|
24
|
+
// swiftlint:disable file_length
|
|
26
25
|
// swiftlint:disable type_body_length
|
|
27
26
|
class UtilsUpgrade {
|
|
28
27
|
let utilsDrop: UtilsDrop = UtilsDrop()
|
|
@@ -88,6 +87,13 @@ class UtilsUpgrade {
|
|
|
88
87
|
if statement.count > 0 {
|
|
89
88
|
_ = try executeStatementProcess(mDB: mDB,
|
|
90
89
|
statement: statement)
|
|
90
|
+
// -> Drop _temp_tables
|
|
91
|
+
_ = try UtilsDrop
|
|
92
|
+
.dropTempTables(mDB: mDB,
|
|
93
|
+
alterTables: self.alterTables)
|
|
94
|
+
// -> Do some cleanup
|
|
95
|
+
self.alterTables = [:]
|
|
96
|
+
self.commonColumns = [:]
|
|
91
97
|
|
|
92
98
|
// here we assume that the Set contains only
|
|
93
99
|
// - the data for new tables as INSERT statements
|
|
@@ -116,6 +122,25 @@ class UtilsUpgrade {
|
|
|
116
122
|
throw UtilsUpgradeError.onUpgradeFailed(message: msg)
|
|
117
123
|
} catch UtilsUpgradeError.executeStatementProcessFailed(
|
|
118
124
|
let message) {
|
|
125
|
+
var msg: String = message
|
|
126
|
+
do {
|
|
127
|
+
// -> Drop _temp_tables
|
|
128
|
+
_ = try UtilsDrop
|
|
129
|
+
.dropTempTables(mDB: mDB,
|
|
130
|
+
alterTables: self.alterTables)
|
|
131
|
+
// -> Do some cleanup
|
|
132
|
+
self.alterTables = [:]
|
|
133
|
+
self.commonColumns = [:]
|
|
134
|
+
|
|
135
|
+
} catch UtilsDropError.dropTempTablesFailed(let message) {
|
|
136
|
+
msg += ": \(message)"
|
|
137
|
+
throw UtilsUpgradeError.onUpgradeFailed(
|
|
138
|
+
message: message)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
throw UtilsUpgradeError.onUpgradeFailed(
|
|
142
|
+
message: message)
|
|
143
|
+
} catch UtilsDropError.dropTempTablesFailed(let message) {
|
|
119
144
|
throw UtilsUpgradeError.onUpgradeFailed(
|
|
120
145
|
message: message)
|
|
121
146
|
} catch UtilsUpgradeError.executeSetProcessFailed(
|
|
@@ -194,6 +219,7 @@ class UtilsUpgrade {
|
|
|
194
219
|
throws {
|
|
195
220
|
var changes: Int = -1
|
|
196
221
|
do {
|
|
222
|
+
|
|
197
223
|
// -> backup all existing tables "tableName" in
|
|
198
224
|
// "temp_tableName"
|
|
199
225
|
_ = try backupTables(mDB: mDB)
|
|
@@ -216,13 +242,6 @@ class UtilsUpgrade {
|
|
|
216
242
|
// -> Update the new table's data from old table's data
|
|
217
243
|
_ = try updateNewTablesData(mDB: mDB)
|
|
218
244
|
|
|
219
|
-
// -> Drop _temp_tables
|
|
220
|
-
_ = try UtilsDrop
|
|
221
|
-
.dropTempTables(mDB: mDB,
|
|
222
|
-
alterTables: self.alterTables)
|
|
223
|
-
// -> Do some cleanup
|
|
224
|
-
self.alterTables = [:]
|
|
225
|
-
self.commonColumns = [:]
|
|
226
245
|
} catch UtilsUpgradeError.backupTablesFailed(let message) {
|
|
227
246
|
throw UtilsUpgradeError.executeStatementProcessFailed(
|
|
228
247
|
message: message)
|
|
@@ -243,9 +262,6 @@ class UtilsUpgrade {
|
|
|
243
262
|
let message) {
|
|
244
263
|
throw UtilsUpgradeError.executeStatementProcessFailed(
|
|
245
264
|
message: message)
|
|
246
|
-
} catch UtilsDropError.dropTempTablesFailed(let message) {
|
|
247
|
-
throw UtilsUpgradeError.executeStatementProcessFailed(
|
|
248
|
-
message: message)
|
|
249
265
|
}
|
|
250
266
|
|
|
251
267
|
}
|
|
@@ -276,9 +292,12 @@ class UtilsUpgrade {
|
|
|
276
292
|
columnNames = try getTableColumnNames(mDB: mDB,
|
|
277
293
|
tableName: tableName)
|
|
278
294
|
alterTables["\(tableName)"] = columnNames
|
|
295
|
+
let tmpTable = "_temp_\(tableName)"
|
|
296
|
+
let delStmt: String = "DROP TABLE IF EXISTS \(tmpTable);"
|
|
297
|
+
_ = try mDB.runSQL(sql: delStmt, values: [])
|
|
279
298
|
// prefix the table with _temp_
|
|
280
299
|
var stmt: String = "ALTER TABLE \(tableName) RENAME "
|
|
281
|
-
stmt.append("TO
|
|
300
|
+
stmt.append("TO \(tmpTable);")
|
|
282
301
|
let retRun: [String: Int64] = try mDB.runSQL(
|
|
283
302
|
sql: stmt, values: [])
|
|
284
303
|
guard let changes: Int64 = retRun["changes"] else {
|
|
@@ -392,3 +411,4 @@ class UtilsUpgrade {
|
|
|
392
411
|
}
|
|
393
412
|
}
|
|
394
413
|
// swiftlint:enable type_body_length
|
|
414
|
+
// swiftlint:enable file_length
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@capacitor-community/sqlite",
|
|
3
|
-
"version": "3.4.2
|
|
3
|
+
"version": "3.4.3-2",
|
|
4
4
|
"description": "Community plugin for native & electron SQLite databases",
|
|
5
5
|
"main": "dist/plugin.cjs.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -55,10 +55,10 @@
|
|
|
55
55
|
"prepublishOnly": "npm run build && npm run build-electron && npm run docgen"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
|
-
"@capacitor/android": "^3.4.
|
|
59
|
-
"@capacitor/core": "^3.4.
|
|
58
|
+
"@capacitor/android": "^3.4.3",
|
|
59
|
+
"@capacitor/core": "^3.4.3",
|
|
60
60
|
"@capacitor/docgen": "^0.0.17",
|
|
61
|
-
"@capacitor/ios": "^3.4.
|
|
61
|
+
"@capacitor/ios": "^3.4.3",
|
|
62
62
|
"@ionic/eslint-config": "^0.3.0",
|
|
63
63
|
"@ionic/prettier-config": "^1.0.1",
|
|
64
64
|
"@ionic/swiftlint-config": "^1.1.2",
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
"typescript": "~4.0.5"
|
|
75
75
|
},
|
|
76
76
|
"peerDependencies": {
|
|
77
|
-
"@capacitor/core": "~3.4.
|
|
77
|
+
"@capacitor/core": "~3.4.3"
|
|
78
78
|
},
|
|
79
79
|
"prettier": "@ionic/prettier-config",
|
|
80
80
|
"swiftlint": "@ionic/swiftlint-config",
|
|
@@ -93,6 +93,6 @@
|
|
|
93
93
|
}
|
|
94
94
|
},
|
|
95
95
|
"dependencies": {
|
|
96
|
-
"jeep-sqlite": "^1.
|
|
96
|
+
"jeep-sqlite": "^1.5.0"
|
|
97
97
|
}
|
|
98
98
|
}
|