@capacitor-community/sqlite 5.0.5 → 5.0.7-1
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 +3 -0
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/CapacitorSQLite.java +9 -0
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/Database.java +9 -0
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/ImportExportJson/UtilsEncryption.java +111 -0
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsSecret.java +3 -3
- package/dist/esm/definitions.d.ts +66 -0
- package/dist/esm/definitions.js +37 -0
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/web.d.ts +3 -1
- package/dist/esm/web.js +8 -0
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +45 -0
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +45 -0
- package/dist/plugin.js.map +1 -1
- package/electron/dist/plugin.js +138 -52
- package/electron/dist/plugin.js.map +1 -1
- package/electron/rollup.config.js +2 -0
- package/ios/Plugin/CapacitorSQLite.swift +117 -88
- package/ios/Plugin/Database.swift +17 -5
- package/ios/Plugin/ImportExportJson/ImportData.swift +434 -0
- package/ios/Plugin/ImportExportJson/ImportFromJson.swift +43 -57
- package/ios/Plugin/ImportExportJson/JsonSQLite.swift +7 -0
- package/ios/Plugin/Utils/UtilsDelete.swift +506 -0
- package/ios/Plugin/Utils/UtilsJson.swift +123 -1
- package/ios/Plugin/Utils/UtilsSQLCipher.swift +173 -477
- package/ios/Plugin/Utils/UtilsSQLStatement.swift +450 -0
- package/package.json +2 -2
- package/src/definitions.ts +104 -0
- package/src/web.ts +10 -0
|
@@ -0,0 +1,450 @@
|
|
|
1
|
+
//
|
|
2
|
+
// UtilsSQLStatement.swift
|
|
3
|
+
// CapacitorCommunitySqlite
|
|
4
|
+
//
|
|
5
|
+
// Created by Quéau Jean Pierre on 30/07/2023.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import Foundation
|
|
9
|
+
enum UtilsSQLStatementError: Error {
|
|
10
|
+
case extractColumnNames(message:String)
|
|
11
|
+
case extractForeignKeyInfo(message:String)
|
|
12
|
+
case addPrefixToWhereClause(message:String)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
class UtilsSQLStatement {
|
|
16
|
+
|
|
17
|
+
// MARK: - extractTableName
|
|
18
|
+
|
|
19
|
+
class func extractTableName(from statement: String) -> String? {
|
|
20
|
+
let pattern =
|
|
21
|
+
"(?:INSERT\\s+INTO|UPDATE|DELETE\\s+FROM)\\s+([^\\s]+)"
|
|
22
|
+
guard let regex = try? NSRegularExpression(pattern: pattern,
|
|
23
|
+
options: []) else {
|
|
24
|
+
return nil }
|
|
25
|
+
|
|
26
|
+
let range = NSRange(location: 0, length: statement.count)
|
|
27
|
+
if let match = regex.firstMatch(in: statement, options: [],
|
|
28
|
+
range: range) {
|
|
29
|
+
let tableNameRange = match.range(at: 1)
|
|
30
|
+
if let tableNameRange = Range(tableNameRange,
|
|
31
|
+
in: statement) {
|
|
32
|
+
let tableName = String(statement[tableNameRange])
|
|
33
|
+
return tableName
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return nil
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// MARK: - extractWhereClause
|
|
41
|
+
|
|
42
|
+
class func extractWhereClause(from statement: String) -> String? {
|
|
43
|
+
let pattern = "WHERE(.+?)(?:ORDER\\s+BY|LIMIT|$)"
|
|
44
|
+
guard let regex = try? NSRegularExpression(
|
|
45
|
+
pattern: pattern,
|
|
46
|
+
options: [.caseInsensitive,
|
|
47
|
+
.dotMatchesLineSeparators]) else {
|
|
48
|
+
return nil
|
|
49
|
+
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
let range = NSRange(location: 0, length: statement.count)
|
|
53
|
+
if let match = regex.firstMatch(in: statement, options: [],
|
|
54
|
+
range: range) {
|
|
55
|
+
let whereClauseRange = match.range(at: 1)
|
|
56
|
+
if let whereClauseRange = Range(whereClauseRange,
|
|
57
|
+
in: statement) {
|
|
58
|
+
let whereClause = String(statement[whereClauseRange])
|
|
59
|
+
return whereClause
|
|
60
|
+
.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return nil
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// MARK: - addPrefixToWhereClause
|
|
68
|
+
|
|
69
|
+
class func addPrefixToWhereClause(_ whereClause: String, from: [String],
|
|
70
|
+
to: [String],prefix: String)
|
|
71
|
+
throws -> String {
|
|
72
|
+
var columnValuePairs: [String]
|
|
73
|
+
if whereClause.contains("AND") {
|
|
74
|
+
if #available(iOS 16.0, *) {
|
|
75
|
+
let subSequenceArray = whereClause
|
|
76
|
+
.split(separator: "AND")
|
|
77
|
+
columnValuePairs = subSequenceArray.map { String($0) }
|
|
78
|
+
} else {
|
|
79
|
+
columnValuePairs = whereClause
|
|
80
|
+
.components(separatedBy: "AND")
|
|
81
|
+
}
|
|
82
|
+
} else {
|
|
83
|
+
columnValuePairs = [whereClause]
|
|
84
|
+
}
|
|
85
|
+
let modifiedPairs = try columnValuePairs.map { pair -> String in
|
|
86
|
+
let pattern = #"(\w+)\s*(=|IN|BETWEEN|LIKE)\s*(.+)"#
|
|
87
|
+
|
|
88
|
+
if let range = pair.range(of: pattern, options: .regularExpression) {
|
|
89
|
+
let match = String(pair[range])
|
|
90
|
+
let regex = try NSRegularExpression(pattern: pattern)
|
|
91
|
+
let matchRange = NSRange(match.startIndex..., in: match)
|
|
92
|
+
|
|
93
|
+
if let matchResult = regex.firstMatch(in: match, range: matchRange) {
|
|
94
|
+
let columnRange = Range(matchResult.range(at: 1), in: match)!
|
|
95
|
+
let operatorRange = Range(matchResult.range(at: 2), in: match)!
|
|
96
|
+
let valueRange = Range(matchResult.range(at: 3), in: match)!
|
|
97
|
+
|
|
98
|
+
let column = String(match[columnRange]).trimmingCharacters(in: .whitespacesAndNewlines)
|
|
99
|
+
let mOperator = String(match[operatorRange]).trimmingCharacters(in: .whitespacesAndNewlines)
|
|
100
|
+
let value = String(match[valueRange]).trimmingCharacters(in: .whitespacesAndNewlines)
|
|
101
|
+
|
|
102
|
+
var newColumn = column
|
|
103
|
+
if let index = UtilsSQLStatement
|
|
104
|
+
.findIndexOfStringInArray(column, to), index != -1 {
|
|
105
|
+
guard let mNewColumn = UtilsSQLStatement
|
|
106
|
+
.getStringAtIndex(from, index) else {
|
|
107
|
+
let msg = "addPrefixToWhereClause: index " +
|
|
108
|
+
"mistmatch "
|
|
109
|
+
throw UtilsSQLStatementError
|
|
110
|
+
.addPrefixToWhereClause(message: msg)
|
|
111
|
+
}
|
|
112
|
+
newColumn = mNewColumn
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
let modifiedColumn = "\(prefix)\(newColumn)"
|
|
116
|
+
return "\(modifiedColumn) \(mOperator) \(value)"
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return pair
|
|
120
|
+
}
|
|
121
|
+
return modifiedPairs.joined(separator: " AND ")
|
|
122
|
+
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// MARK: - findIndexOfStringInArray
|
|
126
|
+
|
|
127
|
+
class func findIndexOfStringInArray(_ target: String, _ array: [String]) -> Int? {
|
|
128
|
+
return array.firstIndex(of: target)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// MARK: - getStringAtIndex
|
|
132
|
+
|
|
133
|
+
class func getStringAtIndex(_ array: [String], _ index: Int) -> String? {
|
|
134
|
+
if index >= 0 && index < array.count {
|
|
135
|
+
return array[index]
|
|
136
|
+
} else {
|
|
137
|
+
return nil
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
// MARK: - extractForeignKeyInfo
|
|
141
|
+
|
|
142
|
+
class func extractForeignKeyInfo(from sqlStatement: String)
|
|
143
|
+
throws ->
|
|
144
|
+
[String: Any] {
|
|
145
|
+
var foreignKeyInfo: [String: Any] = [:]
|
|
146
|
+
// Define the regular expression patterns for extracting the
|
|
147
|
+
// FOREIGN KEY clause and composite primary keys
|
|
148
|
+
let foreignKeyPattern = #"\bFOREIGN\s+KEY\s*\(([^)]+)\)\s+REFERENCES\s+(\w+)\s*\(([^)]+)\)\s+(ON\s+DELETE\s+(RESTRICT|CASCADE|SET\s+NULL|SET\s+DEFAULT|NO\s+ACTION))?"#
|
|
149
|
+
|
|
150
|
+
// Create a regular expression object
|
|
151
|
+
guard let regex = try? NSRegularExpression(
|
|
152
|
+
pattern: foreignKeyPattern, options: []) else {
|
|
153
|
+
let msg = "extractForeignKeyInfo: creating regular " +
|
|
154
|
+
"expression pattern"
|
|
155
|
+
throw UtilsSQLStatementError
|
|
156
|
+
.extractForeignKeyInfo(message: msg)
|
|
157
|
+
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Find the range of the FOREIGN KEY clause in the SQL
|
|
161
|
+
// statement
|
|
162
|
+
let range = NSRange(location: 0,
|
|
163
|
+
length: sqlStatement.utf16.count)
|
|
164
|
+
if let match = regex.firstMatch(in: sqlStatement, options: [],
|
|
165
|
+
range: range) {
|
|
166
|
+
// Extract the column names for the FOREIGN KEY
|
|
167
|
+
let foreignKeyColumnsRange = match.range(at: 1)
|
|
168
|
+
if let foreignKeyColumnsRangeInString =
|
|
169
|
+
Range(foreignKeyColumnsRange, in: sqlStatement) {
|
|
170
|
+
let foreignKeyColumns =
|
|
171
|
+
String(sqlStatement[foreignKeyColumnsRangeInString])
|
|
172
|
+
.components(separatedBy: ", ")
|
|
173
|
+
|
|
174
|
+
// Extract the referenced table and columns
|
|
175
|
+
let referencedTableRange = match.range(at: 2)
|
|
176
|
+
let referencedColumnsRange = match.range(at: 3)
|
|
177
|
+
if
|
|
178
|
+
let referencedTableRangeInString =
|
|
179
|
+
Range(referencedTableRange, in: sqlStatement),
|
|
180
|
+
let referencedColumnsRangeInString =
|
|
181
|
+
Range(referencedColumnsRange, in: sqlStatement)
|
|
182
|
+
{
|
|
183
|
+
let referencedTable = String(
|
|
184
|
+
sqlStatement[referencedTableRangeInString])
|
|
185
|
+
let referencedColumns = String(
|
|
186
|
+
sqlStatement[referencedColumnsRangeInString])
|
|
187
|
+
.components(separatedBy: ", ")
|
|
188
|
+
|
|
189
|
+
// Extract the ON DELETE action if available
|
|
190
|
+
let onDeleteActionRange = match.range(at: 5)
|
|
191
|
+
if let onDeleteActionRangeInString =
|
|
192
|
+
Range(onDeleteActionRange, in: sqlStatement) {
|
|
193
|
+
let onDeleteAction = String(
|
|
194
|
+
sqlStatement[onDeleteActionRangeInString])
|
|
195
|
+
foreignKeyInfo["forKeys"] = foreignKeyColumns
|
|
196
|
+
foreignKeyInfo["tableName"] = referencedTable
|
|
197
|
+
foreignKeyInfo["refKeys"] = referencedColumns
|
|
198
|
+
foreignKeyInfo["action"] = onDeleteAction
|
|
199
|
+
return foreignKeyInfo
|
|
200
|
+
} else {
|
|
201
|
+
foreignKeyInfo["forKeys"] = foreignKeyColumns
|
|
202
|
+
foreignKeyInfo["tableName"] = referencedTable
|
|
203
|
+
foreignKeyInfo["refKeys"] = referencedColumns
|
|
204
|
+
foreignKeyInfo["action"] = "NO_ACTION"
|
|
205
|
+
return foreignKeyInfo
|
|
206
|
+
}
|
|
207
|
+
} else {
|
|
208
|
+
let msg = "extractForeignKeyInfo: No match found"
|
|
209
|
+
throw UtilsSQLStatementError
|
|
210
|
+
.extractForeignKeyInfo(message: msg)
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
} else {
|
|
214
|
+
let msg = "extractForeignKeyInfo: No FOREIGN KEY found"
|
|
215
|
+
throw UtilsSQLStatementError
|
|
216
|
+
.extractForeignKeyInfo(message: msg)
|
|
217
|
+
}
|
|
218
|
+
foreignKeyInfo["forKeys"] = []
|
|
219
|
+
foreignKeyInfo["tableName"] = ""
|
|
220
|
+
foreignKeyInfo["refKeys"] = []
|
|
221
|
+
foreignKeyInfo["action"] = "NO_ACTION"
|
|
222
|
+
return foreignKeyInfo
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
// MARK: - extractColumnNames
|
|
227
|
+
|
|
228
|
+
class func extractColumnNames(from whereClause: String)
|
|
229
|
+
throws -> [String] {
|
|
230
|
+
let regexPattern = #"\b(\w+)\s*(?=(?:[=<>]|IN\s*\(VALUES\s*|\bBETWEEN\b|\bLIKE\s*'))|(?<=\()\s*(\w+),\s*(\w+)\s*(?=\))"#
|
|
231
|
+
|
|
232
|
+
do {
|
|
233
|
+
|
|
234
|
+
let regex = try NSRegularExpression(pattern: regexPattern)
|
|
235
|
+
let matches = regex.matches(in: whereClause, range: NSRange(whereClause.startIndex..., in: whereClause))
|
|
236
|
+
var columnNames: [String] = []
|
|
237
|
+
|
|
238
|
+
for match in matches {
|
|
239
|
+
for rangeIdx in 1..<match.numberOfRanges {
|
|
240
|
+
let range = match.range(at: rangeIdx)
|
|
241
|
+
if range.location != NSNotFound, let columnNameRange = Range(range, in: whereClause) {
|
|
242
|
+
let columnName = String(whereClause[columnNameRange])
|
|
243
|
+
columnNames.append(columnName)
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
return columnNames
|
|
249
|
+
|
|
250
|
+
} catch {
|
|
251
|
+
let msg = "Error creating regular expression: " +
|
|
252
|
+
"\(error.localizedDescription)"
|
|
253
|
+
throw UtilsSQLStatementError.extractColumnNames(message: msg)
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// MARK: - flattenMultilineString
|
|
258
|
+
|
|
259
|
+
class func flattenMultilineString(_ input: String) -> String {
|
|
260
|
+
let lines = input
|
|
261
|
+
.components(separatedBy: CharacterSet.newlines)
|
|
262
|
+
return lines.joined(separator: " ")
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// MARK: - getStmtAndRetColNames
|
|
266
|
+
|
|
267
|
+
class func getStmtAndRetColNames(sqlStmt: String, retMode: String)
|
|
268
|
+
-> [String: String] {
|
|
269
|
+
let retWord = "RETURNING"
|
|
270
|
+
|
|
271
|
+
var retStmtNames: [String: String] = [:]
|
|
272
|
+
retStmtNames["stmt"] = sqlStmt
|
|
273
|
+
retStmtNames["names"] = ""
|
|
274
|
+
if let range = sqlStmt.uppercased().range(of: retWord) {
|
|
275
|
+
let prefix = sqlStmt.prefix(upTo: range.lowerBound)
|
|
276
|
+
retStmtNames["stmt"] = "\(prefix);"
|
|
277
|
+
retStmtNames["names"] = ""
|
|
278
|
+
if retMode.prefix(2) == "wA" {
|
|
279
|
+
let suffix = sqlStmt.suffix(from: range.upperBound)
|
|
280
|
+
let names =
|
|
281
|
+
"\(suffix)".trimmingLeadingAndTrailingSpaces()
|
|
282
|
+
if names.suffix(1) == ";" {
|
|
283
|
+
retStmtNames["names"] = String(names.dropLast())
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
}
|
|
288
|
+
return retStmtNames
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// MARK: - extractCombinedPrimaryKey
|
|
292
|
+
|
|
293
|
+
class func extractCombinedPrimaryKey(from whereClause: String)
|
|
294
|
+
-> [[String]]? {
|
|
295
|
+
// Regular expression pattern to match the combined primary
|
|
296
|
+
// key comparison with IN operator or without it
|
|
297
|
+
// meaning = operator
|
|
298
|
+
let pattern = #"WHERE\s*\((.+?)\)\s*(?:=|IN)\s*\((.+?)\)"#
|
|
299
|
+
|
|
300
|
+
guard let regex = try? NSRegularExpression(pattern: pattern,
|
|
301
|
+
options: []) else {
|
|
302
|
+
print("Invalid regular expression pattern.")
|
|
303
|
+
return nil
|
|
304
|
+
}
|
|
305
|
+
let range = NSRange(location: 0,
|
|
306
|
+
length: whereClause.utf16.count)
|
|
307
|
+
let matches = regex.matches(in: whereClause, options: [],
|
|
308
|
+
range: range)
|
|
309
|
+
var primaryKeySets: [[String]] = []
|
|
310
|
+
|
|
311
|
+
for match in matches {
|
|
312
|
+
|
|
313
|
+
let keysRange = Range(match.range(at: 1), in: whereClause)!
|
|
314
|
+
let keysString = String(whereClause[keysRange])
|
|
315
|
+
let keys = keysString.split(separator: ",").map {
|
|
316
|
+
String($0.trimmingCharacters(in: .whitespaces)) }
|
|
317
|
+
primaryKeySets.append(keys)
|
|
318
|
+
}
|
|
319
|
+
return primaryKeySets.isEmpty ? nil : primaryKeySets
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// MARK: - getWhereStatementForCombinedPK
|
|
323
|
+
|
|
324
|
+
class func getWhereStmtForCombinedPK(whStmt: String,
|
|
325
|
+
withRefs: [String],
|
|
326
|
+
colNames: [String],
|
|
327
|
+
keys: [[String]])
|
|
328
|
+
-> String {
|
|
329
|
+
var retWhere: String = whStmt
|
|
330
|
+
var repKeys: [String] = []
|
|
331
|
+
for grpKeys in keys {
|
|
332
|
+
if grpKeys == withRefs {
|
|
333
|
+
repKeys = colNames
|
|
334
|
+
} else {
|
|
335
|
+
repKeys = withRefs
|
|
336
|
+
}
|
|
337
|
+
for (index, key) in grpKeys.enumerated() {
|
|
338
|
+
retWhere = replaceAllString(originalStr: retWhere,
|
|
339
|
+
searchStr: key,
|
|
340
|
+
replaceStr: repKeys[index])
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
return retWhere
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// MARK: - replaceAllString
|
|
347
|
+
|
|
348
|
+
class func replaceAllString(originalStr: String, searchStr: String,
|
|
349
|
+
replaceStr: String) -> String {
|
|
350
|
+
let modifiedStr = originalStr
|
|
351
|
+
.replacingOccurrences(of: searchStr, with: replaceStr)
|
|
352
|
+
return modifiedStr
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// MARK: - replaceString
|
|
356
|
+
|
|
357
|
+
class func replaceString(originalStr: String, searchStr: String,
|
|
358
|
+
replaceStr: String) -> String {
|
|
359
|
+
var modifiedStr = originalStr
|
|
360
|
+
if let range = originalStr.range(of: searchStr) {
|
|
361
|
+
modifiedStr.replaceSubrange(range, with: replaceStr)
|
|
362
|
+
}
|
|
363
|
+
return modifiedStr
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// MARK: - getWhereStmtForNonCombinedPK
|
|
367
|
+
|
|
368
|
+
class func getWhereStmtForNonCombinedPK(whStmt: String,
|
|
369
|
+
withRefs: [String],
|
|
370
|
+
colNames: [String])
|
|
371
|
+
-> String {
|
|
372
|
+
var whereStmt = ""
|
|
373
|
+
var stmt: String = String(whStmt.stringRange(
|
|
374
|
+
fromIdx: 6,
|
|
375
|
+
toIdx: whStmt.count))
|
|
376
|
+
for (idx, wRf) in withRefs.enumerated() {
|
|
377
|
+
var colType: String = "withRefsNames"
|
|
378
|
+
var idxs: [Int] = stmt.indicesOf(string: wRf)
|
|
379
|
+
if idxs.count == 0 {
|
|
380
|
+
idxs = stmt.indicesOf(string: colNames[idx])
|
|
381
|
+
colType = "colNames"
|
|
382
|
+
}
|
|
383
|
+
if idxs.count > 0 {
|
|
384
|
+
var valStr: String = ""
|
|
385
|
+
let indicesEqual: [Int] = stmt
|
|
386
|
+
.indicesOf(string: "=",
|
|
387
|
+
fromIdx: idxs[0])
|
|
388
|
+
|
|
389
|
+
if indicesEqual.count > 0 {
|
|
390
|
+
let indicesAnd: [Int] = stmt
|
|
391
|
+
.indicesOf(string: "AND",
|
|
392
|
+
fromIdx: indicesEqual[0])
|
|
393
|
+
if indicesAnd.count > 0 {
|
|
394
|
+
valStr = String(stmt.stringRange(
|
|
395
|
+
fromIdx: indicesEqual[0] + 1,
|
|
396
|
+
toIdx: indicesAnd[0] - 1))
|
|
397
|
+
stmt = String(stmt.stringRange(
|
|
398
|
+
fromIdx: indicesAnd[0] + 3,
|
|
399
|
+
toIdx: stmt.count))
|
|
400
|
+
} else {
|
|
401
|
+
valStr = String(stmt.stringRange(
|
|
402
|
+
fromIdx: indicesEqual[0] + 1,
|
|
403
|
+
toIdx: stmt.count))
|
|
404
|
+
}
|
|
405
|
+
if idx > 0 {
|
|
406
|
+
whereStmt += " AND "
|
|
407
|
+
}
|
|
408
|
+
if colType == "withRefsNames" {
|
|
409
|
+
whereStmt += colNames[idx] + " = " + valStr
|
|
410
|
+
} else {
|
|
411
|
+
whereStmt += withRefs[idx] + " = " + valStr
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
whereStmt = "WHERE " + whereStmt
|
|
417
|
+
return whereStmt
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// MARK: - updateWhere
|
|
421
|
+
|
|
422
|
+
class func updateWhere(whStmt: String, withRefs: [String],
|
|
423
|
+
colNames: [String]) -> String {
|
|
424
|
+
var whereStmt = ""
|
|
425
|
+
if whStmt.count <= 0 {
|
|
426
|
+
return whereStmt
|
|
427
|
+
}
|
|
428
|
+
if whStmt.uppercased().prefix(5) != "WHERE" {
|
|
429
|
+
return whereStmt
|
|
430
|
+
}
|
|
431
|
+
if withRefs.count == colNames.count {
|
|
432
|
+
// get whereStmt for primary combined key
|
|
433
|
+
if let keys: [[String]] = UtilsSQLStatement
|
|
434
|
+
.extractCombinedPrimaryKey(from: whStmt) {
|
|
435
|
+
whereStmt = UtilsSQLStatement
|
|
436
|
+
.getWhereStmtForCombinedPK(whStmt: whStmt,
|
|
437
|
+
withRefs: withRefs,
|
|
438
|
+
colNames: colNames,
|
|
439
|
+
keys: keys)
|
|
440
|
+
} else {
|
|
441
|
+
// get for non primary combined key
|
|
442
|
+
whereStmt = UtilsSQLStatement
|
|
443
|
+
.getWhereStmtForNonCombinedPK(whStmt: whStmt,
|
|
444
|
+
withRefs: withRefs,
|
|
445
|
+
colNames: colNames)
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
return whereStmt
|
|
449
|
+
}
|
|
450
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@capacitor-community/sqlite",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.7-1",
|
|
4
4
|
"description": "Community plugin for native & electron SQLite databases",
|
|
5
5
|
"main": "dist/plugin.cjs.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -95,6 +95,6 @@
|
|
|
95
95
|
}
|
|
96
96
|
},
|
|
97
97
|
"dependencies": {
|
|
98
|
-
"jeep-sqlite": "^2.
|
|
98
|
+
"jeep-sqlite": "^2.4.1"
|
|
99
99
|
}
|
|
100
100
|
}
|
package/src/definitions.ts
CHANGED
|
@@ -120,6 +120,20 @@ export interface CapacitorSQLitePlugin {
|
|
|
120
120
|
* @since 0.0.1
|
|
121
121
|
*/
|
|
122
122
|
close(options: capSQLiteOptions): Promise<void>;
|
|
123
|
+
/**
|
|
124
|
+
* Load a SQlite extension
|
|
125
|
+
* @param options :capSQLiteExtensionPath
|
|
126
|
+
* @returns Promise<void>
|
|
127
|
+
* @since 5.0.6
|
|
128
|
+
*/
|
|
129
|
+
// loadExtension(options: capSQLiteExtensionPath): Promise<void>;
|
|
130
|
+
/**
|
|
131
|
+
* Enable Or Disable Extension Loading
|
|
132
|
+
* @param options
|
|
133
|
+
* @returns Promise<void>
|
|
134
|
+
* @since 5.0.6
|
|
135
|
+
*/
|
|
136
|
+
// enableLoadExtension(options: capSQLiteExtensionEnable): Promise<void>;
|
|
123
137
|
/**
|
|
124
138
|
* GetUrl get the database Url
|
|
125
139
|
* @param options: capSQLiteOptions
|
|
@@ -391,6 +405,38 @@ export interface capEchoOptions {
|
|
|
391
405
|
*/
|
|
392
406
|
value?: string;
|
|
393
407
|
}
|
|
408
|
+
export interface capSQLiteExtensionPath {
|
|
409
|
+
/**
|
|
410
|
+
* The database name
|
|
411
|
+
*/
|
|
412
|
+
database?: string;
|
|
413
|
+
/**
|
|
414
|
+
* The extension path
|
|
415
|
+
*/
|
|
416
|
+
path?: string;
|
|
417
|
+
/**
|
|
418
|
+
* ReadOnly / ReadWrite
|
|
419
|
+
* default ReadWrite (false)
|
|
420
|
+
* @since 4.1.0-7
|
|
421
|
+
*/
|
|
422
|
+
readonly?: boolean;
|
|
423
|
+
}
|
|
424
|
+
export interface capSQLiteExtensionEnable {
|
|
425
|
+
/**
|
|
426
|
+
* The database name
|
|
427
|
+
*/
|
|
428
|
+
database?: string;
|
|
429
|
+
/**
|
|
430
|
+
* The enabling toggle (1: ON, 0: OFF)
|
|
431
|
+
*/
|
|
432
|
+
toggle?: boolean;
|
|
433
|
+
/**
|
|
434
|
+
* ReadOnly / ReadWrite
|
|
435
|
+
* default ReadWrite (false)
|
|
436
|
+
* @since 4.1.0-7
|
|
437
|
+
*/
|
|
438
|
+
readonly?: boolean;
|
|
439
|
+
}
|
|
394
440
|
export interface capConnectionOptions {
|
|
395
441
|
/**
|
|
396
442
|
* The database name
|
|
@@ -436,6 +482,7 @@ export interface capSQLiteOptions {
|
|
|
436
482
|
*/
|
|
437
483
|
readonly?: boolean;
|
|
438
484
|
}
|
|
485
|
+
|
|
439
486
|
export interface capNCDatabasePathOptions {
|
|
440
487
|
/**
|
|
441
488
|
* the database path
|
|
@@ -769,6 +816,12 @@ export interface capSQLiteSyncDate {
|
|
|
769
816
|
}
|
|
770
817
|
|
|
771
818
|
/* JSON Types */
|
|
819
|
+
export interface EncryptJson {
|
|
820
|
+
/**
|
|
821
|
+
* The encrypted JsonSQLite base64 string
|
|
822
|
+
*/
|
|
823
|
+
expData: string;
|
|
824
|
+
}
|
|
772
825
|
export interface JsonSQLite {
|
|
773
826
|
/**
|
|
774
827
|
* The database name
|
|
@@ -1699,6 +1752,20 @@ export interface ISQLiteDBConnection {
|
|
|
1699
1752
|
* @since 3.2.0
|
|
1700
1753
|
*/
|
|
1701
1754
|
getVersion(): Promise<capVersionResult>;
|
|
1755
|
+
/**
|
|
1756
|
+
* Load a SQlite extension
|
|
1757
|
+
* @param path :SQlite extension path
|
|
1758
|
+
* @returns Promise<void>
|
|
1759
|
+
* @since 5.0.6
|
|
1760
|
+
*/
|
|
1761
|
+
loadExtension(path: string): Promise<void>;
|
|
1762
|
+
/**
|
|
1763
|
+
* Enable Or Disable Extension Loading
|
|
1764
|
+
* @param toggle true:on false:off
|
|
1765
|
+
* @returns Promise<void>
|
|
1766
|
+
* @since 5.0.6
|
|
1767
|
+
*/
|
|
1768
|
+
enableLoadExtension(toggle: boolean): Promise<void>;
|
|
1702
1769
|
/**
|
|
1703
1770
|
* Execute SQLite DB Connection Statements
|
|
1704
1771
|
* @param statements
|
|
@@ -1849,6 +1916,43 @@ export class SQLiteDBConnection implements ISQLiteDBConnection {
|
|
|
1849
1916
|
return Promise.reject(err);
|
|
1850
1917
|
}
|
|
1851
1918
|
}
|
|
1919
|
+
|
|
1920
|
+
async loadExtension(path: string): Promise<void> {
|
|
1921
|
+
try {
|
|
1922
|
+
console.log(`database: ${this.dbName}`);
|
|
1923
|
+
console.log(`readonly: ${this.readonly}}`);
|
|
1924
|
+
console.log(`path: ${path}}`);
|
|
1925
|
+
await this.sqlite.loadExtension({
|
|
1926
|
+
database: this.dbName,
|
|
1927
|
+
path: path,
|
|
1928
|
+
readonly: this.readonly,
|
|
1929
|
+
});
|
|
1930
|
+
console.log(`loadExtension successful`);
|
|
1931
|
+
return Promise.resolve();
|
|
1932
|
+
} catch (err) {
|
|
1933
|
+
console.log(`loadExtension failed `);
|
|
1934
|
+
return Promise.reject(err);
|
|
1935
|
+
}
|
|
1936
|
+
}
|
|
1937
|
+
async enableLoadExtension(toggle: boolean): Promise<void> {
|
|
1938
|
+
try {
|
|
1939
|
+
console.log(`database: ${this.dbName}`);
|
|
1940
|
+
console.log(`readonly: ${this.readonly}`);
|
|
1941
|
+
console.log(`toggle: ${toggle}`);
|
|
1942
|
+
await this.sqlite.enableLoadExtension({
|
|
1943
|
+
database: this.dbName,
|
|
1944
|
+
toggle: toggle,
|
|
1945
|
+
readonly: this.readonly,
|
|
1946
|
+
});
|
|
1947
|
+
console.log(`enableLoadExtension successful`);
|
|
1948
|
+
return Promise.resolve();
|
|
1949
|
+
} catch (err) {
|
|
1950
|
+
console.log(err);
|
|
1951
|
+
console.log(`enableLoadExtension failed `);
|
|
1952
|
+
return Promise.reject(err);
|
|
1953
|
+
}
|
|
1954
|
+
}
|
|
1955
|
+
|
|
1852
1956
|
async getUrl(): Promise<capSQLiteUrl> {
|
|
1853
1957
|
try {
|
|
1854
1958
|
const res: capSQLiteUrl = await this.sqlite.getUrl({
|
package/src/web.ts
CHANGED
|
@@ -32,6 +32,8 @@ import type {
|
|
|
32
32
|
capSQLiteUrl,
|
|
33
33
|
capSQLiteValues,
|
|
34
34
|
capVersionResult,
|
|
35
|
+
capSQLiteExtensionPath,
|
|
36
|
+
capSQLiteExtensionEnable,
|
|
35
37
|
} from './definitions';
|
|
36
38
|
|
|
37
39
|
export class CapacitorSQLiteWeb
|
|
@@ -591,4 +593,12 @@ export class CapacitorSQLiteWeb
|
|
|
591
593
|
async isInConfigBiometricAuth(): Promise<capSQLiteResult> {
|
|
592
594
|
throw this.unimplemented('Not implemented on web.');
|
|
593
595
|
}
|
|
596
|
+
async loadExtension(options: capSQLiteExtensionPath): Promise<void> {
|
|
597
|
+
console.log('loadExtension', options);
|
|
598
|
+
throw this.unimplemented('Not implemented on web.');
|
|
599
|
+
}
|
|
600
|
+
async enableLoadExtension(options: capSQLiteExtensionEnable): Promise<void> {
|
|
601
|
+
console.log('enableLoadExtension', options);
|
|
602
|
+
throw this.unimplemented('Not implemented on web.');
|
|
603
|
+
}
|
|
594
604
|
}
|