@capacitor-community/sqlite 3.3.1 → 3.3.3-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 (38) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/README.md +27 -2
  3. package/android/src/main/java/com/getcapacitor/community/database/sqlite/CapacitorSQLite.java +83 -7
  4. package/android/src/main/java/com/getcapacitor/community/database/sqlite/CapacitorSQLitePlugin.java +101 -3
  5. package/android/src/main/java/com/getcapacitor/community/database/sqlite/RetHandler.java +24 -0
  6. package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/Database.java +67 -47
  7. package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/ImportExportJson/JsonIndex.java +5 -4
  8. package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsFile.java +9 -0
  9. package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsMigrate.java +34 -15
  10. package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsNCDatabase.java +26 -0
  11. package/dist/esm/definitions.d.ts +111 -2
  12. package/dist/esm/definitions.js +63 -0
  13. package/dist/esm/definitions.js.map +1 -1
  14. package/dist/esm/web.d.ts +5 -1
  15. package/dist/esm/web.js +16 -0
  16. package/dist/esm/web.js.map +1 -1
  17. package/dist/plugin.cjs.js +79 -0
  18. package/dist/plugin.cjs.js.map +1 -1
  19. package/dist/plugin.js +79 -0
  20. package/dist/plugin.js.map +1 -1
  21. package/electron/dist/plugin.js +17 -1
  22. package/electron/dist/plugin.js.map +1 -1
  23. package/ios/Plugin/CapacitorSQLite.swift +122 -19
  24. package/ios/Plugin/CapacitorSQLitePlugin.m +4 -0
  25. package/ios/Plugin/CapacitorSQLitePlugin.swift +236 -64
  26. package/ios/Plugin/Database.swift +57 -28
  27. package/ios/Plugin/ImportExportJson/ImportFromJson.swift +2 -1
  28. package/ios/Plugin/ImportExportJson/JsonSQLite.swift +1 -1
  29. package/ios/Plugin/ReturnHandler.swift +13 -0
  30. package/ios/Plugin/SqliteConfig.swift +10 -0
  31. package/ios/Plugin/Utils/UtilsEncryption.swift +10 -7
  32. package/ios/Plugin/Utils/UtilsFile.swift +207 -38
  33. package/ios/Plugin/Utils/UtilsMigrate.swift +70 -57
  34. package/ios/Plugin/Utils/UtilsNCDatabase.swift +31 -0
  35. package/ios/Plugin/Utils/UtilsSQLCipher.swift +29 -24
  36. package/ios/Plugin/Utils/UtilsSecret.swift +22 -8
  37. package/ios/Plugin/Utils/UtilsUpgrade.swift +6 -2
  38. package/package.json +5 -5
@@ -33,27 +33,38 @@ class Database {
33
33
  var encrypted: Bool
34
34
  var mode: String
35
35
  var vUpgDict: [Int: [String: Any]]
36
+ var databaseLocation: String
36
37
  var path: String = ""
37
38
  var mDb: OpaquePointer?
38
39
  let globalData: GlobalSQLite = GlobalSQLite()
39
40
  let uUpg: UtilsUpgrade = UtilsUpgrade()
41
+ var readOnly: Bool = false
42
+ var ncDB: Bool = false
40
43
 
41
44
  // MARK: - Init
42
- init(databaseName: String, encrypted: Bool,
45
+ init(databaseLocation: String, databaseName: String, encrypted: Bool,
43
46
  mode: String, version: Int,
44
47
  vUpgDict: [Int: [String: Any]] = [:]) throws {
45
- print("databaseName: \(databaseName) ")
46
48
  self.dbVersion = version
47
49
  self.encrypted = encrypted
48
50
  self.dbName = databaseName
49
51
  self.mode = mode
50
52
  self.vUpgDict = vUpgDict
51
- do {
52
- self.path = try UtilsFile.getFilePath(
53
- fileName: databaseName)
54
- } catch UtilsFileError.getFilePathFailed {
55
- throw DatabaseError.filePath(
56
- message: "Could not generate the file path")
53
+ self.databaseLocation = databaseLocation
54
+ if databaseName.contains("/") &&
55
+ databaseName.suffix(9) != "SQLite.db" {
56
+ self.readOnly = true
57
+ self.path = databaseName
58
+ self.ncDB = true
59
+ } else {
60
+ do {
61
+ self.path = try UtilsFile.getFilePath(
62
+ databaseLocation: databaseLocation,
63
+ fileName: databaseName)
64
+ } catch UtilsFileError.getFilePathFailed {
65
+ throw DatabaseError.filePath(
66
+ message: "Could not generate the file path")
67
+ }
57
68
  }
58
69
  print("database path \(self.path)")
59
70
  }
@@ -64,6 +75,12 @@ class Database {
64
75
  return isOpen
65
76
  }
66
77
 
78
+ // MARK: - isNCDB
79
+
80
+ func isNCDB () -> Bool {
81
+ return ncDB
82
+ }
83
+
67
84
  // MARK: - Open
68
85
 
69
86
  // swiftlint:disable cyclomatic_complexity
@@ -76,7 +93,8 @@ class Database {
76
93
  if mode == "encryption" {
77
94
  do {
78
95
  let ret: Bool = try UtilsEncryption
79
- .encryptDatabase(filePath: path, password: password)
96
+ .encryptDatabase(databaseLocation: databaseLocation,
97
+ filePath: path, password: password)
80
98
  if !ret {
81
99
  let msg: String = "Failed in encryption"
82
100
  throw DatabaseError.open(message: msg)
@@ -92,27 +110,33 @@ class Database {
92
110
  mDb = try UtilsSQLCipher
93
111
  .openOrCreateDatabase(filename: path,
94
112
  password: password,
95
- readonly: false)
113
+ readonly: self.readOnly)
96
114
  isOpen = true
97
115
  // PRAGMA foreign_keys = ON;
98
116
  try UtilsSQLCipher
99
117
  .setForeignKeyConstraintsEnabled(mDB: self,
100
118
  toggle: true)
101
- var curVersion: Int = try UtilsSQLCipher
102
- .getVersion(mDB: self)
103
- if curVersion == 0 {
104
- try UtilsSQLCipher.setVersion(mDB: self, version: 1)
105
- curVersion = try UtilsSQLCipher.getVersion(mDB: self)
106
- }
107
- if dbVersion > curVersion {
108
- if vUpgDict.count > 0 {
109
- _ = try uUpg.onUpgrade(mDB: self, upgDict: vUpgDict,
110
- dbName: dbName,
111
- currentVersion: curVersion,
112
- targetVersion: dbVersion)
113
- try UtilsSQLCipher.deleteBackupDB(databaseName: dbName)
114
- } else {
115
- try UtilsSQLCipher.setVersion(mDB: self, version: dbVersion)
119
+ if !ncDB {
120
+ var curVersion: Int = try UtilsSQLCipher
121
+ .getVersion(mDB: self)
122
+ if curVersion == 0 {
123
+ try UtilsSQLCipher.setVersion(mDB: self, version: 1)
124
+ curVersion = try UtilsSQLCipher.getVersion(mDB: self)
125
+ }
126
+ if dbVersion > curVersion {
127
+ if vUpgDict.count > 0 {
128
+ _ = try uUpg
129
+ .onUpgrade(mDB: self, upgDict: vUpgDict,
130
+ dbName: dbName,
131
+ currentVersion: curVersion,
132
+ targetVersion: dbVersion,
133
+ databaseLocation: databaseLocation)
134
+ try UtilsSQLCipher
135
+ .deleteBackupDB(databaseLocation: databaseLocation,
136
+ databaseName: dbName)
137
+ } else {
138
+ try UtilsSQLCipher.setVersion(mDB: self, version: dbVersion)
139
+ }
116
140
  }
117
141
  }
118
142
  } catch UtilsSQLCipherError.openOrCreateDatabase(let message) {
@@ -140,7 +164,9 @@ class Database {
140
164
  } catch UtilsUpgradeError.onUpgradeFailed(let message) {
141
165
  //restore the database
142
166
  do {
143
- try UtilsSQLCipher.restoreDB(databaseName: dbName)
167
+ try UtilsSQLCipher
168
+ .restoreDB(databaseLocation: databaseLocation,
169
+ databaseName: dbName)
144
170
  let msg: String = "Failed OnUpgrade \(message)"
145
171
  try close()
146
172
  throw DatabaseError.open(message: msg)
@@ -210,6 +236,7 @@ class Database {
210
236
  do {
211
237
  try UtilsSQLCipher.execute(mDB: self, sql: sql)
212
238
  changes = UtilsSQLCipher.dbChanges(mDB: mDb) - initChanges
239
+
213
240
  } catch UtilsSQLCipherError.execute(let message) {
214
241
  if transaction {
215
242
  do {
@@ -361,7 +388,8 @@ class Database {
361
388
 
362
389
  func deleteDB(databaseName: String) throws -> Bool {
363
390
  let isFileExists: Bool = UtilsFile
364
- .isFileExist(fileName: databaseName)
391
+ .isFileExist(databaseLocation: databaseLocation,
392
+ fileName: databaseName)
365
393
  if isFileExists && !isOpen {
366
394
  // open the database
367
395
  do {
@@ -379,7 +407,8 @@ class Database {
379
407
  // delete the database
380
408
  if isFileExists {
381
409
  do {
382
- try UtilsSQLCipher.deleteDB(databaseName: databaseName)
410
+ try UtilsSQLCipher.deleteDB(databaseLocation: databaseLocation,
411
+ databaseName: databaseName)
383
412
  } catch UtilsSQLCipherError.deleteDB(let message ) {
384
413
  throw DatabaseError.deleteDB(message: message)
385
414
  }
@@ -245,7 +245,8 @@ class ImportFromJson {
245
245
  var statements: [String] = []
246
246
  for jpos in 0..<mIndexes.count {
247
247
  var mUnique: String = ""
248
- if let mMode = mIndexes[jpos].mode {
248
+ if var mMode = mIndexes[jpos].mode {
249
+ mMode = mMode.uppercased()
249
250
  if mMode == "UNIQUE" {
250
251
  mUnique = mMode + " "
251
252
  }
@@ -108,7 +108,7 @@ public struct JsonIndex: Codable {
108
108
  print("value: \(value) ")
109
109
  if let mMode = mode {
110
110
  if mMode.count > 0 {
111
- print("mode: \(mMode) ")
111
+ print("mode: \(mMode.uppercased()) ")
112
112
  }
113
113
  }
114
114
  }
@@ -93,4 +93,17 @@ class ReturnHandler {
93
93
  return
94
94
  }
95
95
  }
96
+
97
+ // MARK: - rPath
98
+
99
+ func rPath(call: CAPPluginCall, ret: String,
100
+ message: String? = nil) {
101
+ if let intMessage = message {
102
+ call.reject(intMessage)
103
+ return
104
+ } else {
105
+ call.resolve(["path": ret])
106
+ return
107
+ }
108
+ }
96
109
  }
@@ -0,0 +1,10 @@
1
+ //
2
+ // config.swift
3
+ // CapacitorCommunitySqlite
4
+ //
5
+ // Created by Quéau Jean Pierre on 01/01/2022.
6
+ //
7
+
8
+ public struct SqliteConfig {
9
+ var iosDatabaseLocation: String?
10
+ }
@@ -17,17 +17,19 @@ class UtilsEncryption {
17
17
  // MARK: - EncryptDatabase
18
18
 
19
19
  // swiftlint:disable function_body_length
20
- class func encryptDatabase(filePath: String, password: String)
21
- throws -> Bool {
20
+ class func encryptDatabase(databaseLocation: String, filePath: String,
21
+ password: String) throws -> Bool {
22
22
  var ret: Bool = false
23
23
  var oDB: OpaquePointer?
24
24
  do {
25
25
  if UtilsFile.isFileExist(filePath: filePath) {
26
26
  do {
27
- let tempPath: String = try UtilsFile.getFilePath(
28
- fileName: "temp.db")
27
+ let tempPath: String = try UtilsFile
28
+ .getFilePath(databaseLocation: databaseLocation,
29
+ fileName: "temp.db")
29
30
  try UtilsFile.renameFile(filePath: filePath,
30
- toFilePath: tempPath)
31
+ toFilePath: tempPath,
32
+ databaseLocation: databaseLocation)
31
33
  oDB = try UtilsSQLCipher
32
34
  .openOrCreateDatabase(filename: tempPath,
33
35
  password: "",
@@ -43,8 +45,9 @@ class UtilsEncryption {
43
45
  stmt.append("DETACH DATABASE encrypted;")
44
46
  if sqlite3_exec(oDB, stmt, nil, nil, nil) ==
45
47
  SQLITE_OK {
46
- try _ = UtilsFile.deleteFile(
47
- fileName: "temp.db")
48
+ try _ = UtilsFile
49
+ .deleteFile(fileName: "temp.db",
50
+ databaseLocation: databaseLocation)
48
51
  ret = true
49
52
  }
50
53
  // close the db
@@ -12,6 +12,7 @@ import ZIPFoundation
12
12
  enum UtilsFileError: Error {
13
13
  case getFilePathFailed
14
14
  case copyFileFailed
15
+ case moveFileFailed
15
16
  case renameFileFailed
16
17
  case deleteFileFailed
17
18
  case getAssetsDatabasesPathFailed
@@ -25,6 +26,9 @@ enum UtilsFileError: Error {
25
26
  case copyFromAssetToDatabaseFailed(message: String)
26
27
  case unzipFromAssetToDatabaseFailed(message: String)
27
28
  case copyFromNamesFailed
29
+ case getFolderURLFailed(message: String)
30
+ case createDirFailed(message: String)
31
+ case moveAllDBSQLiteFailed(message: String)
28
32
  }
29
33
  // swiftlint:disable file_length
30
34
  // swiftlint:disable type_body_length
@@ -39,6 +43,70 @@ class UtilsFile {
39
43
  return exists && isDir.boolValue
40
44
  }
41
45
 
46
+ class func createDirCopyDB(url: URL) throws {
47
+ do {
48
+ var dirUrl = url
49
+ let dirPath: String = url.path
50
+ if !UtilsFile.isDirExist(dirPath: dirPath) {
51
+ // create the directory
52
+ try FileManager.default
53
+ .createDirectory(at: dirUrl, withIntermediateDirectories: true)
54
+ // exclude the directory from iCloud Backup
55
+ try UtilsFile.setExcludeFromiCloudBackup(&dirUrl,
56
+ isExcluded: true)
57
+ // move all SQLite database from Documents folder
58
+ // to this new directory
59
+ try UtilsFile.moveAllDBSQLite(dirUrl: dirUrl)
60
+ }
61
+ } catch UtilsFileError.getFolderURLFailed(let message) {
62
+ throw UtilsFileError.createDirFailed(message: message)
63
+ } catch UtilsFileError.moveAllDBSQLiteFailed(let message) {
64
+ throw UtilsFileError.createDirFailed(message: message)
65
+ } catch let error {
66
+ var msg: String = "createDir command failed :"
67
+ msg.append(" \(error.localizedDescription)")
68
+ throw UtilsFileError.createDirFailed(message: msg)
69
+ }
70
+
71
+ }
72
+
73
+ // MARK: - moveAllDBSQLite
74
+
75
+ class func moveAllDBSQLite(dirUrl: URL) throws {
76
+ // get the db list from Documents folder
77
+ do {
78
+ let databaseURL: URL = try UtilsFile
79
+ .getDatabasesUrl().absoluteURL
80
+ let fileList: [String] = try UtilsFile
81
+ .getFileList(path: databaseURL.path,
82
+ ext: "SQLite.db")
83
+ for file in fileList {
84
+ let fromFileURL: URL = databaseURL
85
+ .appendingPathComponent(file).absoluteURL
86
+ let toFileURL = dirUrl
87
+ .appendingPathComponent(file).absoluteURL
88
+ let retB: Bool = try UtilsFile
89
+ .moveFile(pathName: fromFileURL.path,
90
+ toPathName: toFileURL.path, overwrite: true)
91
+ if !retB {
92
+ let msg: String = "moveFile command failed :"
93
+ throw UtilsFileError.moveAllDBSQLiteFailed(message: msg)
94
+ }
95
+ }
96
+
97
+ } catch UtilsFileError.getFileListFailed {
98
+ let msg: String = "getFileList command failed :"
99
+ throw UtilsFileError.moveAllDBSQLiteFailed(message: msg)
100
+ } catch UtilsFileError.moveFileFailed {
101
+ let msg: String = "moveFile command failed :"
102
+ throw UtilsFileError.moveAllDBSQLiteFailed(message: msg)
103
+ } catch let error {
104
+ var msg: String = "moveAllDBSQLite command failed :"
105
+ msg.append(" \(error.localizedDescription)")
106
+ throw UtilsFileError.moveAllDBSQLiteFailed(message: msg)
107
+ }
108
+
109
+ }
42
110
  // MARK: - IsFileExist
43
111
 
44
112
  class func isFileExist(filePath: String) -> Bool {
@@ -49,11 +117,12 @@ class UtilsFile {
49
117
  }
50
118
  return ret
51
119
  }
52
- class func isFileExist(fileName: String) -> Bool {
120
+ class func isFileExist(databaseLocation: String, fileName: String) -> Bool {
53
121
  var ret: Bool = false
54
122
  do {
55
123
  let filePath: String =
56
124
  try UtilsFile.getFilePath(
125
+ databaseLocation: databaseLocation,
57
126
  fileName: fileName)
58
127
  ret = UtilsFile.isFileExist(filePath: filePath)
59
128
  return ret
@@ -64,14 +133,58 @@ class UtilsFile {
64
133
  }
65
134
  }
66
135
 
67
- // MARK: - GetFilePath
136
+ // MARK: - getFolderURL
68
137
 
69
- class func getFilePath(fileName: String) throws -> String {
138
+ class func getFolderURL(folderPath: String) throws -> URL {
70
139
  do {
71
- let url = try getDatabasesUrl()
72
- return url.appendingPathComponent("\(fileName)").path
140
+ let databaseURL = try UtilsFile.getDatabasesUrl().absoluteURL
141
+ var dbPathURL: URL
142
+ let first = folderPath.split(separator: "/", maxSplits: 1)
143
+ if first[0] == "Applications" {
144
+ dbPathURL = try UtilsFile.getApplicationURL().absoluteURL
145
+ } else if first[0] == "Library" {
146
+ dbPathURL = try UtilsFile.getLibraryURL().absoluteURL
147
+ } else if first[0] == "Documents" || first[0] == "default" {
148
+ dbPathURL = databaseURL
149
+ } else {
150
+ var msg: String = "getFolderURL command failed :"
151
+ msg.append(" Folder '\(first[0])' not allowed")
152
+ throw UtilsFileError.getFolderURLFailed(message: msg)
153
+ }
154
+ if first.count > 1 {
155
+ dbPathURL = dbPathURL
156
+ .appendingPathComponent(String(first[1])).absoluteURL
157
+ }
158
+ return dbPathURL
73
159
  } catch UtilsFileError.getDatabasesURLFailed {
74
- print("Error: getDatabasesUrl Failed")
160
+ throw UtilsFileError.getFolderURLFailed(message: "getDatabasesURLFailed")
161
+ } catch UtilsFileError.getApplicationURLFailed {
162
+ throw UtilsFileError
163
+ .getFolderURLFailed(message: "getApplicationURLFailed")
164
+ } catch let error {
165
+ var msg: String = "getFolderURL command failed :"
166
+ msg.append(" \(error.localizedDescription)")
167
+ throw UtilsFileError.getFolderURLFailed(message: msg)
168
+ }
169
+ }
170
+
171
+ // MARK: - GetFilePath
172
+
173
+ class func getFilePath(databaseLocation: String,
174
+ fileName: String) throws -> String {
175
+ do {
176
+ let url: URL = try UtilsFile
177
+ .getFolderURL(folderPath: databaseLocation)
178
+ if databaseLocation.prefix(9) != "Documents" &&
179
+ databaseLocation.prefix(7) != "default" {
180
+ // create the directories if they do not exists
181
+ try UtilsFile.createDirCopyDB(url: url)
182
+ }
183
+ let dbPath: String = url
184
+ .appendingPathComponent("\(fileName)").path
185
+ return dbPath
186
+ } catch UtilsFileError.getFolderURLFailed(let message) {
187
+ print("Error: getFilePath Failed \(message)")
75
188
  throw UtilsFileError.getFilePathFailed
76
189
  }
77
190
  }
@@ -157,7 +270,6 @@ class UtilsFile {
157
270
 
158
271
  class func getAssetsDatabasesPath() throws -> URL {
159
272
  if let appFolder = Bundle.main.resourceURL {
160
- print("getAssetsDatabasesPath appFolder \(appFolder)")
161
273
  return appFolder.appendingPathComponent("public/assets/databases")
162
274
  } else {
163
275
  print("Error: getAssetsDatabasePath did not find app folder")
@@ -180,17 +292,24 @@ class UtilsFile {
180
292
 
181
293
  // MARK: - GetFileList
182
294
 
183
- class func getFileList(path: String, ext: String) throws -> [String] {
295
+ class func getFileList(path: String, ext: String? = nil) throws -> [String] {
296
+
184
297
  do {
185
- var dbs: [String] = []
298
+ var files: [String] = []
186
299
  let filenames = try FileManager.default
187
300
  .contentsOfDirectory(atPath: path)
188
301
  for file in filenames {
189
- if file.hasSuffix(ext) {
190
- dbs.append(file)
302
+ if let mExtension = ext {
303
+ if file.hasSuffix(mExtension) {
304
+ files.append(file)
305
+ }
306
+ } else {
307
+ if file.prefix(1) != "." {
308
+ files.append(file)
309
+ }
191
310
  }
192
311
  }
193
- return dbs
312
+ return files
194
313
  } catch let error {
195
314
  print("Error: \(error)")
196
315
  throw UtilsFileError.getFileListFailed
@@ -223,16 +342,16 @@ class UtilsFile {
223
342
 
224
343
  // MARK: - CopyFromAssetToDatabase
225
344
 
226
- class func copyFromAssetToDatabase(fromDb: String, toDb: String,
227
- overwrite: Bool) throws {
345
+ class func copyFromAssetToDatabase(databaseLocation: String, fromDb: String,
346
+ toDb: String, overwrite: Bool) throws {
228
347
  do {
229
348
  let uAsset: URL = try getAssetsDatabasesPath()
230
349
  .appendingPathComponent(fromDb)
231
- let pAsset: String = uAsset.path
232
- let uDb: URL = try getDatabasesUrl()
350
+
351
+ let uDb: URL = try getFolderURL(folderPath: databaseLocation)
233
352
  .appendingPathComponent(toDb)
234
- let pDb: String = uDb.path
235
- let bRet: Bool = try copyFile(pathName: pAsset, toPathName: pDb,
353
+ let bRet: Bool = try copyFile(pathName: uAsset.path,
354
+ toPathName: uDb.path,
236
355
  overwrite: overwrite)
237
356
  if bRet {
238
357
  return
@@ -245,11 +364,9 @@ class UtilsFile {
245
364
  let msg = "Error: getAssetsDatabasesPath Failed"
246
365
  print("\(msg)")
247
366
  throw UtilsFileError.copyFromAssetToDatabaseFailed(message: msg)
248
- } catch UtilsFileError.getDatabasesURLFailed {
249
- let msg = "Error: getDatabasesUrl Failed"
250
- print("\(msg)")
251
-
252
- throw UtilsFileError.copyFromAssetToDatabaseFailed(message: msg)
367
+ } catch UtilsFileError.getFolderURLFailed(let message) {
368
+ print("Error: getFolderUrl Failed \(message)")
369
+ throw UtilsFileError.copyFromAssetToDatabaseFailed(message: message)
253
370
  } catch UtilsFileError.copyFileFailed {
254
371
  let msg = "Error: copyFile Failed"
255
372
  print("\(msg)")
@@ -263,7 +380,8 @@ class UtilsFile {
263
380
 
264
381
  }
265
382
 
266
- class func unzipFromAssetToDatabase(zip: String, overwrite: Bool) throws {
383
+ class func unzipFromAssetToDatabase(databaseLocation: String, zip: String,
384
+ overwrite: Bool) throws {
267
385
  do {
268
386
  let zipAsset: URL = try getAssetsDatabasesPath()
269
387
  .appendingPathComponent(zip)
@@ -272,10 +390,10 @@ class UtilsFile {
272
390
  print("\(msg)")
273
391
  throw UtilsFileError.unzipFromAssetToDatabaseFailed(message: msg)
274
392
  }
393
+ let uDb: URL = try getFolderURL(folderPath: databaseLocation)
275
394
  for entry in archive {
276
395
  let dbEntry = setPathSuffix(sDb: entry.path)
277
- let zipCopy: URL = try getDatabasesUrl()
278
- .appendingPathComponent(dbEntry)
396
+ let zipCopy: URL = uDb.appendingPathComponent(dbEntry)
279
397
  do {
280
398
  let isExist: Bool = isFileExist(filePath: zipCopy.path)
281
399
  if !isExist || overwrite {
@@ -295,10 +413,9 @@ class UtilsFile {
295
413
  let msg = "Error: getAssetsDatabasesPath Failed"
296
414
  print("\(msg)")
297
415
  throw UtilsFileError.unzipFromAssetToDatabaseFailed(message: msg)
298
- } catch UtilsFileError.getDatabasesURLFailed {
299
- let msg = "Error: getDatabasesUrl Failed"
300
- print("\(msg)")
301
- throw UtilsFileError.unzipFromAssetToDatabaseFailed(message: msg)
416
+ } catch UtilsFileError.getFolderURLFailed(let message) {
417
+ print("Error: getFolderUrl Failed \(message)")
418
+ throw UtilsFileError.unzipFromAssetToDatabaseFailed(message: message)
302
419
  } catch let error {
303
420
  let msg = "Error: \(error)"
304
421
  print("\(msg)")
@@ -306,6 +423,36 @@ class UtilsFile {
306
423
  }
307
424
  }
308
425
 
426
+ // MARK: - MoveFile
427
+
428
+ class func moveFile(pathName: String, toPathName: String, overwrite: Bool) throws -> Bool {
429
+ if pathName.count > 0 && toPathName.count > 0 {
430
+ let isPath = isFileExist(filePath: pathName)
431
+ if isPath {
432
+ do {
433
+ let isExist: Bool = isFileExist(filePath: toPathName)
434
+ if !isExist || overwrite {
435
+ if overwrite && isExist {
436
+ _ = try deleteFile(filePath: toPathName)
437
+ }
438
+ let fileManager = FileManager.default
439
+ try fileManager.moveItem(atPath: pathName,
440
+ toPath: toPathName)
441
+ }
442
+ return true
443
+ } catch let error {
444
+ print("Error: \(error)")
445
+ throw UtilsFileError.moveFileFailed
446
+ }
447
+ } else {
448
+ print("Error: MoveFile Failed pathName does not exist")
449
+ throw UtilsFileError.moveFileFailed
450
+ }
451
+ } else {
452
+ print("Error: MoveFile Failed paths count = 0")
453
+ throw UtilsFileError.moveFileFailed
454
+ }
455
+ }
309
456
  // MARK: - CopyFile
310
457
 
311
458
  class func copyFile(pathName: String, toPathName: String, overwrite: Bool) throws -> Bool {
@@ -339,12 +486,17 @@ class UtilsFile {
339
486
 
340
487
  // MARK: - CopyFile
341
488
 
342
- class func copyFile(fileName: String, toFileName: String)
489
+ class func copyFile(fileName: String, toFileName: String,
490
+ databaseLocation: String)
343
491
  throws -> Bool {
344
492
  var ret: Bool = false
345
493
  do {
346
- let fromPath: String = try getFilePath(fileName: fileName)
347
- let toPath: String = try getFilePath(fileName: toFileName)
494
+ let fromPath: String = try
495
+ getFilePath(databaseLocation: databaseLocation,
496
+ fileName: fileName)
497
+ let toPath: String = try
498
+ getFilePath(databaseLocation: databaseLocation,
499
+ fileName: toFileName)
348
500
  ret = try copyFile(pathName: fromPath, toPathName: toPath, overwrite: true)
349
501
  return ret
350
502
  } catch UtilsFileError.getFilePathFailed {
@@ -380,10 +532,13 @@ class UtilsFile {
380
532
 
381
533
  // MARK: - DeleteFile
382
534
 
383
- class func deleteFile(fileName: String) throws -> Bool {
535
+ class func deleteFile(fileName: String,
536
+ databaseLocation: String) throws -> Bool {
384
537
  var ret: Bool = false
385
538
  do {
386
- let filePath: String = try getFilePath(fileName: fileName)
539
+ let filePath: String = try
540
+ getFilePath(databaseLocation: databaseLocation,
541
+ fileName: fileName)
387
542
  ret = try deleteFile(filePath: filePath)
388
543
  } catch let error {
389
544
  print("Error: \(error)")
@@ -411,14 +566,15 @@ class UtilsFile {
411
566
 
412
567
  // MARK: - RenameFile
413
568
 
414
- class func renameFile (filePath: String, toFilePath: String)
415
- throws {
569
+ class func renameFile (filePath: String, toFilePath: String,
570
+ databaseLocation: String) throws {
416
571
  let fileManager = FileManager.default
417
572
  do {
418
573
  if isFileExist(filePath: toFilePath) {
419
574
  let fileName = URL(
420
575
  fileURLWithPath: toFilePath).lastPathComponent
421
- try _ = deleteFile(fileName: fileName)
576
+ try _ = deleteFile(fileName: fileName,
577
+ databaseLocation: databaseLocation)
422
578
  }
423
579
  try fileManager.moveItem(atPath: filePath,
424
580
  toPath: toFilePath)
@@ -427,6 +583,19 @@ class UtilsFile {
427
583
  throw UtilsFileError.renameFileFailed
428
584
  }
429
585
  }
586
+
587
+ class func setExcludeFromiCloudBackup(_ fileOrDirectoryURL: inout URL, isExcluded: Bool) throws {
588
+ var values = URLResourceValues()
589
+ values.isExcludedFromBackup = isExcluded
590
+ try fileOrDirectoryURL.setResourceValues(values)
591
+ }
592
+
593
+ class func getExcludeFromiCloudBackup(_ fileOrDirectoryURL: URL) throws -> Bool {
594
+ let keySet: Set<URLResourceKey> = [.isExcludedFromBackupKey]
595
+
596
+ return try
597
+ fileOrDirectoryURL.resourceValues(forKeys: keySet).isExcludedFromBackup ?? false
598
+ }
430
599
  }
431
600
  // swiftlint:enable type_body_length
432
601
  // swiftlint:enable file_length