@capacitor-community/sqlite 3.4.0 → 3.4.1-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 (25) hide show
  1. package/README.md +7 -0
  2. package/android/src/main/java/com/getcapacitor/community/database/sqlite/CapacitorSQLite.java +134 -89
  3. package/android/src/main/java/com/getcapacitor/community/database/sqlite/CapacitorSQLitePlugin.java +449 -264
  4. package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/Database.java +41 -27
  5. package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/ImportExportJson/ExportToJson.java +5 -0
  6. package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/ImportExportJson/ImportFromJson.java +24 -15
  7. package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/ImportExportJson/JsonSQLite.java +4 -1
  8. package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/ImportExportJson/UtilsJson.java +23 -0
  9. package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/SqliteConfig.java +9 -0
  10. package/dist/esm/definitions.js +1 -1
  11. package/dist/esm/definitions.js.map +1 -1
  12. package/dist/plugin.cjs.js +1 -1
  13. package/dist/plugin.cjs.js.map +1 -1
  14. package/dist/plugin.js +1 -1
  15. package/dist/plugin.js.map +1 -1
  16. package/electron/dist/plugin.js +228 -176
  17. package/electron/dist/plugin.js.map +1 -1
  18. package/ios/Plugin/CapacitorSQLite.swift +150 -109
  19. package/ios/Plugin/CapacitorSQLitePlugin.swift +17 -10
  20. package/ios/Plugin/Database.swift +50 -20
  21. package/ios/Plugin/ImportExportJson/ExportToJson.swift +8 -0
  22. package/ios/Plugin/ImportExportJson/ImportFromJson.swift +20 -14
  23. package/ios/Plugin/SqliteConfig.swift +1 -0
  24. package/ios/Plugin/Utils/UtilsJson.swift +28 -0
  25. package/package.json +9 -6
@@ -12,6 +12,7 @@ enum CapacitorSQLiteError: Error {
12
12
  private var databaseLocation: String = "Documents"
13
13
  private var initMessage: String = ""
14
14
  private var isInit: Bool = false
15
+ private var isEncryption: Bool = true
15
16
  private var isBiometricAuth: Bool = false
16
17
  private var biometricTitle: String = ""
17
18
  private var bioIdAuth: BiometricIDAuthentication =
@@ -28,45 +29,53 @@ enum CapacitorSQLiteError: Error {
28
29
  init(config: SqliteConfig) {
29
30
  self.config = config
30
31
  super.init()
31
- if let kcPrefix: String = config.iosKeychainPrefix {
32
- account = "\(kcPrefix)_\(oldAccount)"
33
- prefixKeychain = kcPrefix
32
+
33
+ if let isEncrypt = config.iosIsEncryption {
34
+ if isEncrypt == 0 {
35
+ isEncryption = false
36
+ }
34
37
  }
35
- if let isBioAuth = config.biometricAuth {
36
- if isBioAuth == 1 {
37
- if let bTitle = config.biometricTitle {
38
- biometricTitle = bTitle
39
- bioIdAuth.biometricTitle = bTitle
40
- }
41
- do {
42
- let bioType: BiometricType = try
43
- bioIdAuth.biometricType()
44
- if bioType == BiometricType.faceID ||
45
- bioType == BiometricType.touchID {
46
- isBiometricAuth = true
47
- isInit = true
48
- bioIdAuth.authenticateUser { [weak self] message in
49
- if let message = message {
50
- self?.notifyBiometricEvents(name: .biometricEvent,
51
- result: false,
52
- msg: message)
53
- } else {
54
- self?.notifyBiometricEvents(name: .biometricEvent,
55
- result: true,
56
- msg: "")
38
+ if isEncryption {
39
+ if let kcPrefix: String = config.iosKeychainPrefix {
40
+ account = "\(kcPrefix)_\(oldAccount)"
41
+ prefixKeychain = kcPrefix
42
+ }
43
+ if let isBioAuth = config.biometricAuth {
44
+ if isBioAuth == 1 {
45
+ if let bTitle = config.biometricTitle {
46
+ biometricTitle = bTitle
47
+ bioIdAuth.biometricTitle = bTitle
48
+ }
49
+ do {
50
+ let bioType: BiometricType = try
51
+ bioIdAuth.biometricType()
52
+ if bioType == BiometricType.faceID ||
53
+ bioType == BiometricType.touchID {
54
+ isBiometricAuth = true
55
+ isInit = true
56
+ bioIdAuth.authenticateUser { [weak self] message in
57
+ if let message = message {
58
+ self?.notifyBiometricEvents(name: .biometricEvent,
59
+ result: false,
60
+ msg: message)
61
+ } else {
62
+ self?.notifyBiometricEvents(name: .biometricEvent,
63
+ result: true,
64
+ msg: "")
65
+ }
57
66
  }
67
+ } else {
68
+ self.notifyBiometricEvents(name: .biometricEvent,
69
+ result: false,
70
+ msg: "Biometric not set-up")
58
71
  }
59
- } else {
60
- self.notifyBiometricEvents(name: .biometricEvent,
61
- result: false,
62
- msg: "Biometric not set-up")
72
+ } catch BiometricIDAuthenticationError
73
+ .biometricType(let message) {
74
+ initMessage = message
75
+ } catch let error {
76
+ initMessage = "Init Plugin failed :"
77
+ initMessage.append(" \(error.localizedDescription)")
63
78
  }
64
- } catch BiometricIDAuthenticationError
65
- .biometricType(let message) {
66
- initMessage = message
67
- } catch let error {
68
- initMessage = "Init Plugin failed :"
69
- initMessage.append(" \(error.localizedDescription)")
70
79
  }
71
80
  }
72
81
  }
@@ -101,18 +110,21 @@ enum CapacitorSQLiteError: Error {
101
110
 
102
111
  @objc public func isSecretStored() throws -> NSNumber {
103
112
  if isInit {
104
- do {
105
- let isSecretExists: Bool = try UtilsSecret.isPassphrase(
106
- account: account)
107
- if isSecretExists {
108
- return 1
109
- } else {
110
- return 0
113
+ if isEncryption {
114
+ do {
115
+ let isSecretExists: Bool = try UtilsSecret.isPassphrase(
116
+ account: account)
117
+ if isSecretExists {
118
+ return 1
119
+ } else {
120
+ return 0
121
+ }
122
+ } catch UtilsSecretError.prefixPassphrase(let message) {
123
+ throw CapacitorSQLiteError.failed(message: message)
111
124
  }
112
- } catch UtilsSecretError.prefixPassphrase(let message) {
113
- throw CapacitorSQLiteError.failed(message: message)
125
+ } else {
126
+ throw CapacitorSQLiteError.failed(message: "No Encryption set in capacitor.config")
114
127
  }
115
-
116
128
  } else {
117
129
  throw CapacitorSQLiteError.failed(message: initMessage)
118
130
  }
@@ -122,19 +134,23 @@ enum CapacitorSQLiteError: Error {
122
134
 
123
135
  @objc public func setEncryptionSecret(passphrase: String) throws {
124
136
  if isInit {
125
- do {
126
- // close all connections
127
- try closeAllConnections()
128
- // set encryption secret
129
- try UtilsSecret
130
- .setEncryptionSecret(prefix: prefixKeychain,
131
- passphrase: passphrase,
132
- databaseLocation: databaseLocation)
133
- return
134
- } catch UtilsSecretError.setEncryptionSecret(let message) {
135
- throw CapacitorSQLiteError.failed(message: message)
136
- } catch let error {
137
- throw CapacitorSQLiteError.failed(message: "\(error)")
137
+ if isEncryption {
138
+ do {
139
+ // close all connections
140
+ try closeAllConnections()
141
+ // set encryption secret
142
+ try UtilsSecret
143
+ .setEncryptionSecret(prefix: prefixKeychain,
144
+ passphrase: passphrase,
145
+ databaseLocation: databaseLocation)
146
+ return
147
+ } catch UtilsSecretError.setEncryptionSecret(let message) {
148
+ throw CapacitorSQLiteError.failed(message: message)
149
+ } catch let error {
150
+ throw CapacitorSQLiteError.failed(message: "\(error)")
151
+ }
152
+ } else {
153
+ throw CapacitorSQLiteError.failed(message: "No Encryption set in capacitor.config")
138
154
  }
139
155
  } else {
140
156
  throw CapacitorSQLiteError.failed(message: initMessage)
@@ -147,58 +163,62 @@ enum CapacitorSQLiteError: Error {
147
163
  @objc public func changeEncryptionSecret(call: CAPPluginCall, passphrase: String,
148
164
  oldPassphrase: String) throws {
149
165
  if isInit {
150
- self.call = call
151
- let retHandler: ReturnHandler = ReturnHandler()
152
- do {
153
- // close all connections
154
- try closeAllConnections()
155
- if isBiometricAuth {
156
- let dbLocation = databaseLocation
157
- let mPrefixKeychain = prefixKeychain
158
- bioIdAuth.authenticateUser { [weak self] message in
159
- if let message = message {
160
- self?.intBioMessage = message
161
- return
162
- } else {
163
- do {
164
- try UtilsSecret.changeEncryptionSecret(
165
- prefix: mPrefixKeychain,
166
- passphrase: passphrase,
167
- oldPassphrase: oldPassphrase,
168
- databaseLocation: dbLocation)
169
- retHandler.rResult(call: call)
170
- return
171
- } catch UtilsSecretError.changeEncryptionSecret(let message) {
172
- let msg = "ChangeEncryptionSecret: \(message)"
173
- retHandler.rResult(call: call, message: msg)
174
- return
175
- } catch let error {
176
- retHandler.rResult(
177
- call: call,
178
- message: "ChangeEncryptionSecret: \(error.localizedDescription)")
166
+ if isEncryption {
167
+ self.call = call
168
+ let retHandler: ReturnHandler = ReturnHandler()
169
+ do {
170
+ // close all connections
171
+ try closeAllConnections()
172
+ if isBiometricAuth {
173
+ let dbLocation = databaseLocation
174
+ let mPrefixKeychain = prefixKeychain
175
+ bioIdAuth.authenticateUser { [weak self] message in
176
+ if let message = message {
177
+ self?.intBioMessage = message
179
178
  return
179
+ } else {
180
+ do {
181
+ try UtilsSecret.changeEncryptionSecret(
182
+ prefix: mPrefixKeychain,
183
+ passphrase: passphrase,
184
+ oldPassphrase: oldPassphrase,
185
+ databaseLocation: dbLocation)
186
+ retHandler.rResult(call: call)
187
+ return
188
+ } catch UtilsSecretError.changeEncryptionSecret(let message) {
189
+ let msg = "ChangeEncryptionSecret: \(message)"
190
+ retHandler.rResult(call: call, message: msg)
191
+ return
192
+ } catch let error {
193
+ retHandler.rResult(
194
+ call: call,
195
+ message: "ChangeEncryptionSecret: \(error.localizedDescription)")
196
+ return
197
+ }
180
198
  }
181
199
  }
200
+ } else {
201
+ // set encryption secret
202
+ try UtilsSecret
203
+ .changeEncryptionSecret(prefix: prefixKeychain,
204
+ passphrase: passphrase,
205
+ oldPassphrase: oldPassphrase,
206
+ databaseLocation: databaseLocation)
207
+ retHandler.rResult(call: call)
208
+ return
182
209
  }
183
- } else {
184
- // set encryption secret
185
- try UtilsSecret
186
- .changeEncryptionSecret(prefix: prefixKeychain,
187
- passphrase: passphrase,
188
- oldPassphrase: oldPassphrase,
189
- databaseLocation: databaseLocation)
190
- retHandler.rResult(call: call)
210
+ } catch UtilsSecretError.changeEncryptionSecret(let message) {
211
+ let msg = "ChangeEncryptionSecret: \(message)"
212
+ retHandler.rResult(call: call, message: msg)
213
+ return
214
+ } catch let error {
215
+ retHandler.rResult(
216
+ call: call,
217
+ message: "ChangeEncryptionSecret: \(error.localizedDescription)")
191
218
  return
192
219
  }
193
- } catch UtilsSecretError.changeEncryptionSecret(let message) {
194
- let msg = "ChangeEncryptionSecret: \(message)"
195
- retHandler.rResult(call: call, message: msg)
196
- return
197
- } catch let error {
198
- retHandler.rResult(
199
- call: call,
200
- message: "ChangeEncryptionSecret: \(error.localizedDescription)")
201
- return
220
+ } else {
221
+ throw CapacitorSQLiteError.failed(message: "No Encryption set in capacitor.config")
202
222
  }
203
223
  } else {
204
224
  throw CapacitorSQLiteError.failed(message: initMessage)
@@ -247,7 +267,7 @@ enum CapacitorSQLiteError: Error {
247
267
  let mDb: Database = try Database(
248
268
  databaseLocation: databaseLocation,
249
269
  databaseName: databasePath,
250
- encrypted: false, account: account,
270
+ encrypted: false, isEncryption: isEncryption, account: account,
251
271
  mode: "no-encryption", version: version,
252
272
  vUpgDict: [:])
253
273
  dbDict[databasePath] = mDb
@@ -297,12 +317,15 @@ enum CapacitorSQLiteError: Error {
297
317
  let msg = "Connection \(mDbName) already exists"
298
318
  throw CapacitorSQLiteError.failed(message: msg)
299
319
  }
300
-
320
+ if encrypted && !isEncryption {
321
+ let msg = "Database cannot be encrypted as 'No Encryption' set in capacitor.config"
322
+ throw CapacitorSQLiteError.failed(message: msg)
323
+ }
301
324
  do {
302
325
  let mDb: Database = try Database(
303
326
  databaseLocation: databaseLocation,
304
327
  databaseName: "\(mDbName)SQLite.db",
305
- encrypted: encrypted, account: account,
328
+ encrypted: encrypted, isEncryption: isEncryption, account: account,
306
329
  mode: mode, version: version,
307
330
  vUpgDict: vUpgDict)
308
331
  dbDict[mDbName] = mDb
@@ -738,7 +761,25 @@ enum CapacitorSQLiteError: Error {
738
761
 
739
762
  do {
740
763
  if !mDb.isDBOpen() {
741
- try mDb.open()
764
+ // check the state of the DB
765
+ let state: State = UtilsSQLCipher.getDatabaseState(databaseLocation: databaseLocation, databaseName: "\(mDbName)SQLite.db", account: account)
766
+ if !isEncryption && (state.rawValue == "ENCRYPTEDGLOBALSECRET" ||
767
+ state.rawValue == "ENCRYPTEDSECRET") {
768
+ var msg = "Cannot delete an Encrypted database with "
769
+ msg += "No Encryption set in capacitor.config"
770
+ throw CapacitorSQLiteError.failed(message: msg)
771
+ } else if state.rawValue == "UNENCRYPTED" {
772
+ do {
773
+ try UtilsSQLCipher.deleteDB(databaseLocation: databaseLocation,
774
+ databaseName: "\(mDbName)SQLite.db")
775
+ return
776
+ } catch UtilsSQLCipherError.deleteDB(let message ) {
777
+ throw CapacitorSQLiteError.failed(message: message)
778
+ }
779
+
780
+ } else {
781
+ try mDb.open()
782
+ }
742
783
  }
743
784
  let res: Bool = try mDb.deleteDB(databaseName: "\(mDbName)SQLite.db")
744
785
  if res {
@@ -809,7 +850,7 @@ enum CapacitorSQLiteError: Error {
809
850
  do {
810
851
  mDb = try Database(
811
852
  databaseLocation: databaseLocation, databaseName: dbName,
812
- encrypted: encrypted, account: account,
853
+ encrypted: encrypted, isEncryption: isEncryption, account: account,
813
854
  mode: inMode, version: version, vUpgDict: [:])
814
855
  try mDb.open()
815
856
  } catch DatabaseError.open(let message) {
@@ -1215,6 +1215,7 @@ public class CapacitorSQLitePlugin: CAPPlugin {
1215
1215
  }
1216
1216
  private func sqliteConfig() -> SqliteConfig {
1217
1217
  var config = SqliteConfig()
1218
+ config.iosIsEncryption = 1
1218
1219
  config.biometricAuth = 0
1219
1220
  config.iosKeychainPrefix = ""
1220
1221
  if let keychainPrefix = getConfigValue("iosKeychainPrefix") as? String {
@@ -1224,19 +1225,25 @@ public class CapacitorSQLitePlugin: CAPPlugin {
1224
1225
  as? String {
1225
1226
  config.iosDatabaseLocation = iosDatabaseLocation
1226
1227
  }
1227
-
1228
- if let iosBiometric = getConfigValue("iosBiometric") as? [String: Any] {
1229
- if let bioAuth = iosBiometric["biometricAuth"] as? Bool {
1230
- if bioAuth {
1231
- config.biometricAuth = 1
1232
- if let bioTitle = iosBiometric["biometricTitle"] as? String {
1233
- config.biometricTitle = bioTitle.count > 0
1234
- ? bioTitle
1235
- : "Biometric login for capacitor sqlite"
1228
+ if let isEncryption = getConfigValue("iosIsEncryption") as? Bool {
1229
+ if !isEncryption {
1230
+ config.iosIsEncryption = 0
1231
+ }
1232
+ }
1233
+ if config.iosIsEncryption == 1 {
1234
+ if let iosBiometric = getConfigValue("iosBiometric") as? [String: Any] {
1235
+ if let bioAuth = iosBiometric["biometricAuth"] as? Bool {
1236
+ if bioAuth {
1237
+ config.biometricAuth = 1
1238
+ if let bioTitle = iosBiometric["biometricTitle"] as? String {
1239
+ config.biometricTitle = bioTitle.count > 0
1240
+ ? bioTitle
1241
+ : "Biometric login for capacitor sqlite"
1242
+ }
1236
1243
  }
1237
1244
  }
1238
- }
1239
1245
 
1246
+ }
1240
1247
  }
1241
1248
  return config
1242
1249
  }
@@ -31,6 +31,7 @@ class Database {
31
31
  var dbName: String
32
32
  var dbVersion: Int
33
33
  var encrypted: Bool
34
+ var isEncryption: Bool
34
35
  var mode: String
35
36
  var vUpgDict: [Int: [String: Any]]
36
37
  var databaseLocation: String
@@ -44,10 +45,11 @@ class Database {
44
45
 
45
46
  // MARK: - Init
46
47
  init(databaseLocation: String, databaseName: String, encrypted: Bool,
47
- account: String, mode: String, version: Int,
48
+ isEncryption: Bool, account: String, mode: String, version: Int,
48
49
  vUpgDict: [Int: [String: Any]] = [:]) throws {
49
50
  self.dbVersion = version
50
51
  self.encrypted = encrypted
52
+ self.isEncryption = isEncryption
51
53
  self.account = account
52
54
  self.dbName = databaseName
53
55
  self.mode = mode
@@ -95,23 +97,28 @@ class Database {
95
97
  // swiftlint:disable function_body_length
96
98
  func open () throws {
97
99
  var password: String = ""
98
- if encrypted && (mode == "secret" || mode == "encryption") {
100
+ if isEncryption && encrypted && (mode == "secret" || mode == "encryption") {
99
101
  password = UtilsSecret.getPassphrase(account: account)
100
102
  }
101
103
  if mode == "encryption" {
102
- do {
103
- let ret: Bool = try UtilsEncryption
104
- .encryptDatabase(databaseLocation: databaseLocation,
105
- filePath: path, password: password)
106
- if !ret {
107
- let msg: String = "Failed in encryption"
104
+ if isEncryption {
105
+ do {
106
+ let ret: Bool = try UtilsEncryption
107
+ .encryptDatabase(databaseLocation: databaseLocation,
108
+ filePath: path, password: password)
109
+ if !ret {
110
+ let msg: String = "Failed in encryption"
111
+ throw DatabaseError.open(message: msg)
112
+ }
113
+ } catch UtilsEncryptionError.encryptionFailed(let message) {
114
+ let msg: String = "Failed in encryption \(message)"
108
115
  throw DatabaseError.open(message: msg)
109
116
  }
110
- } catch UtilsEncryptionError.encryptionFailed(let message) {
111
- let msg: String = "Failed in encryption \(message)"
117
+ } else {
118
+ let msg: String = "No Encryption set in capacitor.config"
112
119
  throw DatabaseError.open(message: msg)
113
-
114
120
  }
121
+
115
122
  }
116
123
 
117
124
  do {
@@ -446,18 +453,27 @@ class Database {
446
453
  let isExists: Bool = try UtilsJson.isTableExists(
447
454
  mDB: self, tableName: "sync_table")
448
455
  if !isExists {
449
- let date = Date()
450
- let syncTime: Int = Int(date.timeIntervalSince1970)
451
- var stmt: String = "CREATE TABLE IF NOT EXISTS "
452
- stmt.append("sync_table (")
453
- stmt.append("id INTEGER PRIMARY KEY NOT NULL,")
454
- stmt.append("sync_date INTEGER);")
455
- stmt.append("INSERT INTO sync_table (sync_date) ")
456
- stmt.append("VALUES ('\(syncTime)');")
457
- retObj = try executeSQL(sql: stmt)
456
+ // check if there are tables with last_modified column
457
+ let isLastModified: Bool = try UtilsJson.isLastModified(mDB: self)
458
+ if isLastModified {
459
+ let date = Date()
460
+ let syncTime: Int = Int(date.timeIntervalSince1970)
461
+ var stmt: String = "CREATE TABLE IF NOT EXISTS "
462
+ stmt.append("sync_table (")
463
+ stmt.append("id INTEGER PRIMARY KEY NOT NULL,")
464
+ stmt.append("sync_date INTEGER);")
465
+ stmt.append("INSERT INTO sync_table (sync_date) ")
466
+ stmt.append("VALUES ('\(syncTime)');")
467
+ retObj = try executeSQL(sql: stmt)
468
+ } else {
469
+ let msg = "No last_modified column in tables"
470
+ throw DatabaseError.createSyncTable(message: msg)
471
+ }
458
472
  } else {
459
473
  retObj = 0
460
474
  }
475
+ } catch UtilsJsonError.isLastModified(let message) {
476
+ throw DatabaseError.createSyncTable(message: message)
461
477
  } catch UtilsJsonError.tableNotExists(let message) {
462
478
  throw DatabaseError.createSyncTable(message: message)
463
479
  } catch DatabaseError.executeSQL(let message) {
@@ -471,6 +487,11 @@ class Database {
471
487
  func setSyncDate(syncDate: String ) throws -> Bool {
472
488
  var retBool: Bool = false
473
489
  do {
490
+ let isExists: Bool = try UtilsJson.isTableExists(
491
+ mDB: self, tableName: "sync_table")
492
+ if !isExists {
493
+ throw DatabaseError.createSyncDate(message: "No sync_table available")
494
+ }
474
495
  let dateFormatter = DateFormatter()
475
496
  dateFormatter.locale = Locale(identifier: "en_US_POSIX")
476
497
  dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
@@ -487,6 +508,8 @@ class Database {
487
508
  } else {
488
509
  throw DatabaseError.createSyncDate(message: "wrong syncDate")
489
510
  }
511
+ } catch UtilsJsonError.tableNotExists(let message) {
512
+ throw DatabaseError.createSyncDate(message: message)
490
513
  } catch DatabaseError.runSQL(let message) {
491
514
  throw DatabaseError.createSyncDate(message: message)
492
515
  }
@@ -498,7 +521,14 @@ class Database {
498
521
  func getSyncDate( ) throws -> Int64 {
499
522
  var syncDate: Int64 = 0
500
523
  do {
524
+ let isExists: Bool = try UtilsJson.isTableExists(
525
+ mDB: self, tableName: "sync_table")
526
+ if !isExists {
527
+ throw DatabaseError.getSyncDate(message: "No sync_table available")
528
+ }
501
529
  syncDate = try ExportToJson.getSyncDate(mDB: self)
530
+ } catch UtilsJsonError.tableNotExists(let message) {
531
+ throw DatabaseError.getSyncDate(message: message)
502
532
  } catch ExportToJsonError.getSyncDate(let message) {
503
533
  throw DatabaseError.getSyncDate(message: message)
504
534
  }
@@ -88,6 +88,12 @@ class ExportToJson {
88
88
  let resTables = try UtilsSQLCipher.querySQL(
89
89
  mDB: mDB, sql: query, values: [])
90
90
  if resTables.count > 0 {
91
+ let isExists: Bool = try UtilsJson.isTableExists(
92
+ mDB: mDB, tableName: "sync_table")
93
+ if !isExists && expMode == "partial" {
94
+ throw ExportToJsonError.createExportObject(message: "No sync_table available")
95
+ }
96
+
91
97
  switch expMode {
92
98
  case "partial" :
93
99
  tables = try ExportToJson
@@ -102,6 +108,8 @@ class ExportToJson {
102
108
  message: "expMode \(expMode) not defined")
103
109
  }
104
110
  }
111
+ } catch UtilsJsonError.tableNotExists(let message) {
112
+ throw ExportToJsonError.createExportObject(message: message)
105
113
  } catch UtilsSQLCipherError.querySQL(let message) {
106
114
  throw ExportToJsonError.createExportObject(
107
115
  message: "Error get table's names failed : \(message)")
@@ -194,12 +194,16 @@ class ImportFromJson {
194
194
  -> [String] {
195
195
  var statements: [String] = []
196
196
  var stmt: String
197
+ var isLastModified: Bool = false
197
198
  stmt = "CREATE TABLE IF NOT EXISTS "
198
199
  stmt.append(tableName)
199
200
  stmt.append(" (")
200
201
  for jpos in 0..<mSchema.count {
201
202
  if let jSchColumn = mSchema[jpos].column {
202
203
  if jSchColumn.count > 0 {
204
+ if jSchColumn == "last_modified" {
205
+ isLastModified = true
206
+ }
203
207
  stmt.append(jSchColumn)
204
208
  }
205
209
  }
@@ -221,20 +225,22 @@ class ImportFromJson {
221
225
  }
222
226
  stmt.append(");")
223
227
  statements.append(stmt)
224
- // create trigger last_modified associated with the table
225
- let triggerName: String = tableName + "_trigger_last_modified"
226
- stmt = "CREATE TRIGGER IF NOT EXISTS "
227
- stmt.append(triggerName)
228
- stmt.append(" AFTER UPDATE ON ")
229
- stmt.append(tableName)
230
- stmt.append(" FOR EACH ROW ")
231
- stmt.append("WHEN NEW.last_modified <= OLD.last_modified ")
232
- stmt.append("BEGIN UPDATE ")
233
- stmt.append(tableName)
234
- stmt.append(" SET last_modified = (strftime('%s','now')) ")
235
- stmt.append("WHERE id=OLD.id; ")
236
- stmt.append("END;")
237
- statements.append(stmt)
228
+ if isLastModified {
229
+ // create trigger last_modified associated with the table
230
+ let triggerName: String = tableName + "_trigger_last_modified"
231
+ stmt = "CREATE TRIGGER IF NOT EXISTS "
232
+ stmt.append(triggerName)
233
+ stmt.append(" AFTER UPDATE ON ")
234
+ stmt.append(tableName)
235
+ stmt.append(" FOR EACH ROW ")
236
+ stmt.append("WHEN NEW.last_modified <= OLD.last_modified ")
237
+ stmt.append("BEGIN UPDATE ")
238
+ stmt.append(tableName)
239
+ stmt.append(" SET last_modified = (strftime('%s','now')) ")
240
+ stmt.append("WHERE id=OLD.id; ")
241
+ stmt.append("END;")
242
+ statements.append(stmt)
243
+ }
238
244
  return statements
239
245
  }
240
246
 
@@ -7,6 +7,7 @@
7
7
 
8
8
  public struct SqliteConfig {
9
9
  var iosDatabaseLocation: String?
10
+ var iosIsEncryption: Int?
10
11
  var biometricAuth: Int?
11
12
  var biometricTitle: String?
12
13
  var iosKeychainPrefix: String?
@@ -17,6 +17,7 @@ enum UtilsJsonError: Error {
17
17
  case validateIndexes(message: String)
18
18
  case validateTriggers(message: String)
19
19
  case validateViews(message: String)
20
+ case isLastModified(message: String)
20
21
  }
21
22
 
22
23
  // swiftlint:disable type_body_length
@@ -46,6 +47,33 @@ class UtilsJson {
46
47
  return ret
47
48
  }
48
49
 
50
+ // MARK: - ImportFromJson - IsLastModified
51
+
52
+ class func isLastModified(mDB: Database) throws -> Bool {
53
+ var msg: String = "Error LastModified: "
54
+ if !mDB.isDBOpen() {
55
+ msg.append("Database not opened")
56
+ throw UtilsJsonError.isLastModified(message: msg)
57
+ }
58
+ var ret: Bool = false
59
+ do {
60
+ let tableList: [String] = try UtilsDrop.getTablesNames(mDB: mDB)
61
+ for table in tableList {
62
+ let namesTypes: JsonNamesTypes = try getTableColumnNamesTypes(mDB: mDB,
63
+ tableName: table)
64
+ if namesTypes.names.contains("last_modified") {
65
+ ret = true
66
+ break
67
+ }
68
+ }
69
+ } catch UtilsJsonError.getTableColumnNamesTypes(let message) {
70
+ throw UtilsJsonError.isLastModified(message: message)
71
+ } catch UtilsDropError.getTablesNamesFailed(let message) {
72
+ throw UtilsJsonError.isLastModified(message: message)
73
+ }
74
+ return ret
75
+ }
76
+
49
77
  // MARK: - ImportFromJson - IsViewExists
50
78
 
51
79
  class func isViewExists(mDB: Database, viewName: String)