@capacitor-community/sqlite 4.1.0 → 4.2.0

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.
@@ -20,6 +20,7 @@ export default {
20
20
  'fs',
21
21
  'os',
22
22
  'jszip',
23
+ 'node-fetch',
23
24
  ],
24
25
  plugins: [
25
26
  nodeResolve(),
@@ -10,6 +10,7 @@ enum CapacitorSQLiteError: Error {
10
10
  private var config: SqliteConfig
11
11
  private var dbDict: [String: Database] = [:]
12
12
  private var databaseLocation: String = "Documents"
13
+ private let retHandler: ReturnHandler = ReturnHandler()
13
14
  private var initMessage: String = ""
14
15
  private var isInit: Bool = false
15
16
  private var isEncryption: Bool = true
@@ -457,6 +458,33 @@ enum CapacitorSQLiteError: Error {
457
458
  }
458
459
  }
459
460
 
461
+ // MARK: - GetFromHTTPRequest
462
+
463
+ @objc public func getFromHTTPRequest(_ call: CAPPluginCall, url: String) throws {
464
+ if isInit {
465
+
466
+ UtilsDownloadFromHTTP.download(databaseLocation: databaseLocation,
467
+ url: url) { ( result) in
468
+ switch result {
469
+ case .success(_):
470
+ self.retHandler.rResult(call: call)
471
+ return
472
+ case .failure(let error):
473
+
474
+ if error == .downloadFromHTTPFailed {
475
+ let msg = "Download from HTTP failed"
476
+ self.retHandler.rResult(call: call, message: msg)
477
+ return
478
+ }
479
+
480
+ }
481
+
482
+ }
483
+ } else {
484
+ throw CapacitorSQLiteError.failed(message: initMessage)
485
+ }
486
+ }
487
+
460
488
  // MARK: - Close Connection
461
489
 
462
490
  @objc public func closeConnection(_ dbName: String, readonly: Bool) throws {
@@ -491,7 +519,7 @@ enum CapacitorSQLiteError: Error {
491
519
  var conns: [String] = []
492
520
  for name in dbNames {
493
521
  conns.append("\(openModes[idx])_\(name)")
494
- idx = idx + 1
522
+ idx += 1
495
523
  }
496
524
  do {
497
525
  if conns.count == 0 {
@@ -1246,9 +1274,9 @@ enum CapacitorSQLiteError: Error {
1246
1274
 
1247
1275
  // check if the assets/database folder exists
1248
1276
  do {
1249
- let assetsDbPath: URL = try
1277
+ let assetsDbURL: URL = try
1250
1278
  UtilsFile.getAssetsDatabasesPath()
1251
- let aPath: String = assetsDbPath.path
1279
+ let aPath: String = assetsDbURL.path
1252
1280
  let bRes: Bool = UtilsFile.isDirExist(dirPath: aPath)
1253
1281
  if bRes {
1254
1282
  // get the database files from assets
@@ -1274,9 +1302,11 @@ enum CapacitorSQLiteError: Error {
1274
1302
  for zip in zipList {
1275
1303
  // for each zip uncompress the file to the Application
1276
1304
  // database folder
1277
- _ = try UtilsFile
1278
- .unzipFromAssetToDatabase(databaseLocation: databaseLocation,
1279
- zip: zip, overwrite: overwrite)
1305
+ _ = try UtilsFile.unzipToDatabase(
1306
+ fromURL: assetsDbURL,
1307
+ databaseLocation: databaseLocation,
1308
+ zip: zip,
1309
+ overwrite: overwrite)
1280
1310
  }
1281
1311
  return
1282
1312
  } else {
@@ -1285,7 +1315,7 @@ enum CapacitorSQLiteError: Error {
1285
1315
  }
1286
1316
  } catch UtilsFileError.copyFromAssetToDatabaseFailed(let message) {
1287
1317
  throw CapacitorSQLiteError.failed(message: message)
1288
- } catch UtilsFileError.unzipFromAssetToDatabaseFailed(let message) {
1318
+ } catch UtilsFileError.unzipToDatabaseFailed(let message) {
1289
1319
  throw CapacitorSQLiteError.failed(message: message)
1290
1320
  } catch let error {
1291
1321
  let msg: String = "\(error)"
@@ -44,4 +44,5 @@ CAP_PLUGIN(CapacitorSQLitePlugin, "CapacitorSQLite",
44
44
  CAP_PLUGIN_METHOD(setEncryptionSecret, CAPPluginReturnPromise);
45
45
  CAP_PLUGIN_METHOD(changeEncryptionSecret, CAPPluginReturnPromise);
46
46
  CAP_PLUGIN_METHOD(clearEncryptionSecret, CAPPluginReturnPromise);
47
+ CAP_PLUGIN_METHOD(getFromHTTPRequest, CAPPluginReturnPromise);
47
48
  )
@@ -1158,7 +1158,15 @@ public class CapacitorSQLitePlugin: CAPPlugin {
1158
1158
  if let upgVersionDict: [Int: [String: Any]] = try
1159
1159
  implementation?.addUpgradeStatement(dbName,
1160
1160
  upgrade: upgrade) {
1161
- versionUpgrades = ["\(dbName)": upgVersionDict]
1161
+ if
1162
+ versionUpgrades[dbName] != nil {
1163
+ for (versionKey, upgObj) in upgVersionDict {
1164
+ versionUpgrades[dbName]?[versionKey] = upgObj
1165
+ }
1166
+ } else {
1167
+ versionUpgrades = ["\(dbName)": upgVersionDict]
1168
+ }
1169
+
1162
1170
  retHandler.rResult(call: call)
1163
1171
  return
1164
1172
  } else {
@@ -1315,6 +1323,42 @@ public class CapacitorSQLitePlugin: CAPPlugin {
1315
1323
 
1316
1324
  }
1317
1325
 
1326
+ // MARK: - GetFromHTTPRequest
1327
+
1328
+ @objc func getFromHTTPRequest(_ call: CAPPluginCall) {
1329
+ guard let url = call.options["url"] as? String else {
1330
+ retHandler.rResult(
1331
+ call: call,
1332
+ message: "GetFromHTTPRequest: Must provide a database url")
1333
+ return
1334
+ }
1335
+ DispatchQueue.global(qos: .background).async {
1336
+
1337
+ do {
1338
+ try self.implementation?.getFromHTTPRequest(call, url: url)
1339
+ DispatchQueue.main.async {
1340
+ self.retHandler.rResult(call: call)
1341
+ return
1342
+ }
1343
+ } catch CapacitorSQLiteError.failed(let message) {
1344
+
1345
+ DispatchQueue.main.async {
1346
+ let msg = "GetFromHTTPRequest: \(message)"
1347
+ self.retHandler.rResult(call: call, message: msg)
1348
+ return
1349
+ }
1350
+ } catch let error {
1351
+ DispatchQueue.main.async {
1352
+ let msg = "GetFromHTTPRequest: " +
1353
+ "\(error.localizedDescription)"
1354
+ self.retHandler.rResult(call: call, message: msg)
1355
+ return
1356
+ }
1357
+ }
1358
+ }
1359
+
1360
+ }
1361
+
1318
1362
  // MARK: - Add Observers
1319
1363
 
1320
1364
  @objc func addObserversToNotificationCenter() {
@@ -1364,31 +1408,28 @@ public class CapacitorSQLitePlugin: CAPPlugin {
1364
1408
  config.iosIsEncryption = 1
1365
1409
  config.biometricAuth = 0
1366
1410
  config.iosKeychainPrefix = ""
1367
- if let keychainPrefix = getConfigValue("iosKeychainPrefix") as? String {
1411
+ let configPlugin = getConfig()
1412
+ if let keychainPrefix = configPlugin.getString("iosKeychainPrefix") {
1368
1413
  config.iosKeychainPrefix = keychainPrefix
1369
1414
  }
1370
- if let iosDatabaseLocation = getConfigValue("iosDatabaseLocation")
1371
- as? String {
1415
+ if let iosDatabaseLocation = configPlugin.getString("iosDatabaseLocation") {
1372
1416
  config.iosDatabaseLocation = iosDatabaseLocation
1373
1417
  }
1374
- if let isEncryption = getConfigValue("iosIsEncryption") as? Bool {
1375
- if !isEncryption {
1376
- config.iosIsEncryption = 0
1377
- }
1418
+ let isEncryption = configPlugin.getBoolean("iosIsEncryption", false)
1419
+ if !isEncryption {
1420
+ config.iosIsEncryption = 0
1378
1421
  }
1379
1422
  if config.iosIsEncryption == 1 {
1380
- if let iosBiometric = getConfigValue("iosBiometric") as? [String: Any] {
1381
- if let bioAuth = iosBiometric["biometricAuth"] as? Bool {
1382
- if bioAuth {
1383
- config.biometricAuth = 1
1384
- if let bioTitle = iosBiometric["biometricTitle"] as? String {
1385
- config.biometricTitle = bioTitle.count > 0
1386
- ? bioTitle
1387
- : "Biometric login for capacitor sqlite"
1388
- }
1423
+ let iosBiometric = configPlugin.getObject("iosBiometric")
1424
+ if let bioAuth = iosBiometric?["biometricAuth"] as? Bool {
1425
+ if bioAuth {
1426
+ config.biometricAuth = 1
1427
+ if let bioTitle = iosBiometric?["biometricTitle"] as? String {
1428
+ config.biometricTitle = bioTitle.count > 0
1429
+ ? bioTitle
1430
+ : "Biometric login for capacitor sqlite"
1389
1431
  }
1390
1432
  }
1391
-
1392
1433
  }
1393
1434
  }
1394
1435
  return config
@@ -0,0 +1,122 @@
1
+ //
2
+ // UtilsDownloadFromHTTP.swift
3
+ // CapacitorCommunitySqlite
4
+ //
5
+ // Created by Quéau Jean Pierre on 05/10/2022.
6
+ //
7
+
8
+ import Foundation
9
+ import ZIPFoundation
10
+
11
+ enum UtilsDownloadError: Error {
12
+ case downloadFromHTTPFailed
13
+ }
14
+ class UtilsDownloadFromHTTP {
15
+ // swiftlint:disable cyclomatic_complexity
16
+ // swiftlint:disable function_body_length
17
+ class func download(databaseLocation: String, url: String,
18
+ completion: @escaping (Result<Bool, UtilsDownloadError>)
19
+ -> Void) {
20
+ if let mUrl: URL = URL(string: url) {
21
+ let fileName = mUrl.lastPathComponent
22
+ var dbName = fileName
23
+ var isZip = false
24
+ if !fileName.contains("SQLite.db") {
25
+ if String(fileName.suffix(3)) == ".db" {
26
+ dbName = fileName.replacingOccurrences(
27
+ of: ".db", with: "SQLite.db")
28
+ }
29
+ if String(fileName.suffix(4)) == ".zip" {
30
+ isZip = true
31
+ }
32
+ }
33
+ // compute a path to this Url in the cache
34
+ let cacheURL = UtilsFile.getTmpURL()
35
+ let tmp = cacheURL.lastPathComponent
36
+ let fileCacheURL = FileManager.default.temporaryDirectory
37
+ .appendingPathComponent(
38
+ dbName,
39
+ isDirectory: false
40
+ )
41
+
42
+ let task = URLSession.shared.downloadTask(with: mUrl) {
43
+ (tempURL, response, error) in
44
+ // Early exit on error
45
+ guard let tempURL = tempURL else {
46
+ let msg = "\(String(describing: error?.localizedDescription))"
47
+ print("\(msg)")
48
+ completion(.failure(UtilsDownloadError.downloadFromHTTPFailed))
49
+ return
50
+ }
51
+ if let httpResponse = response as? HTTPURLResponse {
52
+ switch httpResponse.statusCode {
53
+ case 200:
54
+ do {
55
+ // Remove any existing document at file
56
+ if FileManager.default.fileExists(
57
+ atPath: fileCacheURL.path) {
58
+ try FileManager.default.removeItem(
59
+ atPath: fileCacheURL.path)
60
+ }
61
+
62
+ // Copy the tempURL to file
63
+ try FileManager.default.copyItem(
64
+ at: tempURL,
65
+ to: fileCacheURL
66
+ )
67
+ // Delete the tempUrl file
68
+ try FileManager.default.removeItem(at: tempURL)
69
+ let dbURL = try UtilsFile.getDatabaseLocationURL(
70
+ databaseLocation: databaseLocation)
71
+ if isZip {
72
+ // get the zip files
73
+ let zipList: [String] = try UtilsFile
74
+ .getFileList(path: cacheURL.path,
75
+ ext: ".zip")
76
+ // loop through the database files
77
+ for zip in zipList {
78
+ _ = try UtilsFile.unzipToDatabase(
79
+ fromURL: cacheURL,
80
+ databaseLocation: tmp,
81
+ zip: zip,
82
+ overwrite: true)
83
+ }
84
+ // Delete the zip file
85
+ try FileManager.default.removeItem(
86
+ at: fileCacheURL)
87
+
88
+ }
89
+ try UtilsFile.moveAllDBSQLite(
90
+ fromURL: cacheURL,
91
+ dirUrl: dbURL)
92
+ completion(.success(true))
93
+ return
94
+ }
95
+
96
+ // Handle potential file system errors
97
+ catch let error {
98
+ let msg = "\(error.localizedDescription)"
99
+ print("\(msg)")
100
+ completion(.failure(UtilsDownloadError.downloadFromHTTPFailed))
101
+ return
102
+ }
103
+ default:
104
+ let msg = "Download: GET resquest not successful. http status code \(httpResponse.statusCode)"
105
+ print("\(msg)")
106
+ completion(.failure(UtilsDownloadError.downloadFromHTTPFailed))
107
+ return
108
+ }
109
+ } else {
110
+ let msg = "Download: not a valid http response"
111
+ print("\(msg)")
112
+ completion(.failure(UtilsDownloadError.downloadFromHTTPFailed))
113
+ return
114
+ }
115
+ }
116
+ // Start the download
117
+ task.resume()
118
+ }
119
+ }
120
+ // swiftlint:enable cyclomatic_complexity
121
+ // swiftlint:enable function_body_length
122
+ }
@@ -25,12 +25,13 @@ enum UtilsFileError: Error {
25
25
  case getLibraryURLFailed
26
26
  case getFileListFailed
27
27
  case copyFromAssetToDatabaseFailed(message: String)
28
- case unzipFromAssetToDatabaseFailed(message: String)
28
+ case unzipToDatabaseFailed(message: String)
29
29
  case copyFromNamesFailed
30
30
  case getFolderURLFailed(message: String)
31
31
  case createDirFailed(message: String)
32
32
  case moveAllDBSQLiteFailed(message: String)
33
33
  case createDatabaseLocationFailed(message: String)
34
+ case getDatabaseLocationURLFailed(message: String)
34
35
  }
35
36
  // swiftlint:disable file_length
36
37
  // swiftlint:disable type_body_length
@@ -51,12 +52,17 @@ class UtilsFile {
51
52
  // move all existing dbs from "Documents" to location folder
52
53
  if location.prefix(9) != "Documents" &&
53
54
  location.prefix(7) != "default" {
55
+ let databaseURL: URL = try UtilsFile
56
+ .getDatabasesUrl().absoluteURL
54
57
 
55
- try UtilsFile.moveAllDBSQLite(dirUrl: dirUrl)
58
+ try UtilsFile.moveAllDBSQLite(fromURL: databaseURL,
59
+ dirUrl: dirUrl)
56
60
  }
57
61
  }
58
62
  } catch UtilsFileError.getFolderURLFailed(let message) {
59
63
  throw UtilsFileError.createDatabaseLocationFailed(message: message)
64
+ } catch UtilsFileError.getDatabasesURLFailed {
65
+ throw UtilsFileError.createDatabaseLocationFailed(message: "getDatabasesURLFailed")
60
66
  } catch UtilsFileError.moveAllDBSQLiteFailed(let message) {
61
67
  throw UtilsFileError.createDatabaseLocationFailed(message: message)
62
68
  } catch let error {
@@ -77,16 +83,15 @@ class UtilsFile {
77
83
 
78
84
  // MARK: - moveAllDBSQLite
79
85
 
80
- class func moveAllDBSQLite(dirUrl: URL) throws {
86
+ class func moveAllDBSQLite(fromURL: URL, dirUrl: URL) throws {
81
87
  // get the db list from Documents folder
82
88
  do {
83
- let databaseURL: URL = try UtilsFile
84
- .getDatabasesUrl().absoluteURL
89
+
85
90
  let fileList: [String] = try UtilsFile
86
- .getFileList(path: databaseURL.path,
91
+ .getFileList(path: fromURL.path,
87
92
  ext: "SQLite.db")
88
93
  for file in fileList {
89
- let fromFileURL: URL = databaseURL
94
+ let fromFileURL: URL = fromURL
90
95
  .appendingPathComponent(file).absoluteURL
91
96
  let toFileURL = dirUrl
92
97
  .appendingPathComponent(file).absoluteURL
@@ -149,6 +154,8 @@ class UtilsFile {
149
154
  dbPathURL = try UtilsFile.getApplicationURL().absoluteURL
150
155
  } else if first[0] == "Library" {
151
156
  dbPathURL = try UtilsFile.getLibraryURL().absoluteURL
157
+ } else if first[0] == "tmp" {
158
+ dbPathURL = UtilsFile.getTmpURL().absoluteURL
152
159
  } else if first[0].caseInsensitiveCompare("cache") == .orderedSame {
153
160
  dbPathURL = try UtilsFile.getCacheURL().absoluteURL
154
161
  } else if first[0] == "Documents" || first[0] == "default" {
@@ -216,6 +223,19 @@ class UtilsFile {
216
223
  }
217
224
  }
218
225
 
226
+ // MARK: - getDatabaseLocationURL
227
+
228
+ class func getDatabaseLocationURL(databaseLocation: String) throws -> URL {
229
+ do {
230
+ let url: URL = try UtilsFile
231
+ .getFolderURL(folderPath: databaseLocation)
232
+
233
+ return url
234
+ } catch UtilsFileError.getFolderURLFailed(let message) {
235
+ throw UtilsFileError.getDatabaseLocationURLFailed(message: message)
236
+ }
237
+ }
238
+
219
239
  // MARK: - getApplicationURL
220
240
 
221
241
  class func getApplicationURL() throws -> URL {
@@ -255,6 +275,12 @@ class UtilsFile {
255
275
  }
256
276
  }
257
277
 
278
+ // MARK: - getTmpURL
279
+
280
+ class func getTmpURL() -> URL {
281
+ return FileManager.default.temporaryDirectory
282
+ }
283
+
258
284
  // MARK: - getLibraryURL
259
285
 
260
286
  class func getLibraryURL() throws -> URL {
@@ -395,15 +421,14 @@ class UtilsFile {
395
421
 
396
422
  }
397
423
 
398
- class func unzipFromAssetToDatabase(databaseLocation: String, zip: String,
399
- overwrite: Bool) throws {
424
+ class func unzipToDatabase(fromURL: URL, databaseLocation: String, zip: String,
425
+ overwrite: Bool) throws {
400
426
  do {
401
- let zipAsset: URL = try getAssetsDatabasesPath()
402
- .appendingPathComponent(zip)
427
+ let zipAsset: URL = fromURL.appendingPathComponent(zip)
403
428
  guard let archive = Archive(url: zipAsset, accessMode: .read) else {
404
429
  let msg = "Error: Read Archive: \(zipAsset) failed"
405
430
  print("\(msg)")
406
- throw UtilsFileError.unzipFromAssetToDatabaseFailed(message: msg)
431
+ throw UtilsFileError.unzipToDatabaseFailed(message: msg)
407
432
  }
408
433
  let uDb: URL = try getFolderURL(folderPath: databaseLocation)
409
434
  for entry in archive {
@@ -421,20 +446,16 @@ class UtilsFile {
421
446
  } catch {
422
447
  let msg = "Error: Extracting \(entry.path) from archive failed \(error.localizedDescription)"
423
448
  print("\(msg)")
424
- throw UtilsFileError.unzipFromAssetToDatabaseFailed(message: msg)
449
+ throw UtilsFileError.unzipToDatabaseFailed(message: msg)
425
450
  }
426
451
  }
427
- } catch UtilsFileError.getAssetsDatabasesPathFailed {
428
- let msg = "Error: getAssetsDatabasesPath Failed"
429
- print("\(msg)")
430
- throw UtilsFileError.unzipFromAssetToDatabaseFailed(message: msg)
431
452
  } catch UtilsFileError.getFolderURLFailed(let message) {
432
453
  print("Error: getFolderUrl Failed \(message)")
433
- throw UtilsFileError.unzipFromAssetToDatabaseFailed(message: message)
454
+ throw UtilsFileError.unzipToDatabaseFailed(message: message)
434
455
  } catch let error {
435
456
  let msg = "Error: \(error)"
436
457
  print("\(msg)")
437
- throw UtilsFileError.unzipFromAssetToDatabaseFailed(message: msg)
458
+ throw UtilsFileError.unzipToDatabaseFailed(message: msg)
438
459
  }
439
460
  }
440
461
 
@@ -238,7 +238,7 @@ class UtilsMigrate {
238
238
  if !toFile.isEmpty {
239
239
  let uFrom: URL = dbPathURL.appendingPathComponent(fromFile)
240
240
  let uTo: URL = databaseURL.appendingPathComponent(toFile)
241
- try UtilsFile.moveFile(pathName: uFrom.path, toPathName: uTo.path, overwrite: true)
241
+ _ = try UtilsFile.moveFile(pathName: uFrom.path, toPathName: uTo.path, overwrite: true)
242
242
  }
243
243
  }
244
244
  }
@@ -22,10 +22,12 @@ class UtilsUpgrade {
22
22
  currentVersion: Int,
23
23
  targetVersion: Int,
24
24
  databaseLocation: String) throws {
25
- print("UtilsUpgrade.onUpgrade: \(currentVersion) => \(targetVersion)")
25
+ print("UtilsUpgrade.onUpgrade: from \(currentVersion) to \(targetVersion)")
26
26
 
27
27
  for (versionKey, upgrade) in Array(upgDict).sorted(by: {$0.0 < $1.0}) {
28
28
  if versionKey > currentVersion && versionKey <= targetVersion {
29
+ print("- UtilsUpgrade.onUpgrade toVersion: \(versionKey)")
30
+
29
31
  guard let statements = upgrade["statements"] as? [String] else {
30
32
  let msg: String = "Error: onUpgrade statements not given"
31
33
  throw UtilsUpgradeError.onUpgradeFailed(message: msg)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capacitor-community/sqlite",
3
- "version": "4.1.0",
3
+ "version": "4.2.0",
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": "^4.1.0",
59
- "@capacitor/core": "^4.1.0",
58
+ "@capacitor/android": "^4.2.0",
59
+ "@capacitor/core": "^4.2.0",
60
60
  "@capacitor/docgen": "^0.0.17",
61
- "@capacitor/ios": "^4.1.0",
61
+ "@capacitor/ios": "^4.2.0",
62
62
  "@ionic/eslint-config": "^0.3.0",
63
63
  "@ionic/prettier-config": "^1.0.1",
64
64
  "@ionic/swiftlint-config": "^1.1.2",
@@ -93,6 +93,6 @@
93
93
  }
94
94
  },
95
95
  "dependencies": {
96
- "jeep-sqlite": "^1.6.2"
96
+ "jeep-sqlite": "^1.6.5"
97
97
  }
98
98
  }