@capacitor-community/sqlite 5.0.7-2 → 5.0.8

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 (33) hide show
  1. package/README.md +17 -2
  2. package/android/src/main/java/com/getcapacitor/community/database/sqlite/CapacitorSQLite.java +126 -3
  3. package/android/src/main/java/com/getcapacitor/community/database/sqlite/CapacitorSQLitePlugin.java +115 -1
  4. package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/Database.java +142 -80
  5. package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/ImportExportJson/ImportFromJson.java +9 -9
  6. package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsDelete.java +484 -0
  7. package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsDrop.java +3 -3
  8. package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsSQLStatement.java +169 -0
  9. package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsUpgrade.java +4 -4
  10. package/dist/esm/definitions.d.ts +117 -13
  11. package/dist/esm/definitions.js +103 -51
  12. package/dist/esm/definitions.js.map +1 -1
  13. package/dist/esm/web.d.ts +4 -0
  14. package/dist/esm/web.js +44 -0
  15. package/dist/esm/web.js.map +1 -1
  16. package/dist/plugin.cjs.js +147 -51
  17. package/dist/plugin.cjs.js.map +1 -1
  18. package/dist/plugin.js +147 -51
  19. package/dist/plugin.js.map +1 -1
  20. package/electron/dist/plugin.js +605 -181
  21. package/electron/dist/plugin.js.map +1 -1
  22. package/ios/Plugin/CapacitorSQLite.swift +123 -2
  23. package/ios/Plugin/CapacitorSQLitePlugin.m +4 -0
  24. package/ios/Plugin/CapacitorSQLitePlugin.swift +131 -1
  25. package/ios/Plugin/Database.swift +79 -2
  26. package/ios/Plugin/ImportExportJson/ImportFromJson.swift +13 -2
  27. package/ios/Plugin/Utils/UtilsDelete.swift +119 -117
  28. package/ios/Plugin/Utils/UtilsSQLCipher.swift +13 -5
  29. package/ios/Plugin/Utils/UtilsSQLStatement.swift +84 -84
  30. package/ios/Plugin/Utils/UtilsUpgrade.swift +3 -0
  31. package/package.json +5 -2
  32. package/src/definitions.ts +214 -57
  33. package/src/web.ts +48 -0
@@ -0,0 +1,484 @@
1
+ package com.getcapacitor.community.database.sqlite.SQLite;
2
+
3
+ import static com.getcapacitor.community.database.sqlite.SQLite.UtilsSQLStatement.addPrefixToWhereClause;
4
+ import static com.getcapacitor.community.database.sqlite.SQLite.UtilsSQLStatement.extractForeignKeyInfo;
5
+ import static com.getcapacitor.community.database.sqlite.SQLite.UtilsSQLStatement.flattenMultilineString;
6
+
7
+ import com.getcapacitor.JSArray;
8
+ import com.getcapacitor.JSObject;
9
+ import java.util.ArrayList;
10
+ import java.util.Arrays;
11
+ import java.util.HashMap;
12
+ import java.util.Iterator;
13
+ import java.util.List;
14
+ import java.util.Map;
15
+ import java.util.regex.Matcher;
16
+ import java.util.regex.Pattern;
17
+ import org.json.JSONException;
18
+ import org.json.JSONObject;
19
+
20
+ public class UtilsDelete {
21
+
22
+ private final UtilsSQLStatement _statUtil = new UtilsSQLStatement();
23
+
24
+ public static class ReferenceResult {
25
+
26
+ String tableWithRefs;
27
+ List<String> retRefs;
28
+ }
29
+
30
+ public static class ForeignKeyInfo {
31
+
32
+ String tableName;
33
+ List<String> forKeys;
34
+ List<String> refKeys;
35
+ String action;
36
+
37
+ public ForeignKeyInfo() {
38
+ this.tableName = "";
39
+ this.forKeys = new ArrayList<>();
40
+ this.refKeys = new ArrayList<>();
41
+ this.action = "NO ACTION";
42
+ }
43
+
44
+ public ForeignKeyInfo(List<String> forKeys, String tableName, List<String> refKeys, String action) {
45
+ this.tableName = tableName;
46
+ this.forKeys = forKeys;
47
+ this.refKeys = refKeys;
48
+ this.action = action;
49
+ }
50
+
51
+ public String getTableName() {
52
+ return tableName;
53
+ }
54
+
55
+ public String getAction() {
56
+ return action;
57
+ }
58
+
59
+ public List<String> getForKeys() {
60
+ return forKeys;
61
+ }
62
+
63
+ public List<String> getRefKeys() {
64
+ return refKeys;
65
+ }
66
+ }
67
+
68
+ public static class UpdateResults {
69
+
70
+ private String setStmt;
71
+ private String updWhereStmt;
72
+
73
+ public UpdateResults() {
74
+ this.setStmt = "";
75
+ this.updWhereStmt = "";
76
+ }
77
+
78
+ public UpdateResults(String setStmt, String updWhereStmt) {
79
+ this.setStmt = setStmt;
80
+ this.updWhereStmt = updWhereStmt;
81
+ }
82
+
83
+ public String getSetStmt() {
84
+ return setStmt;
85
+ }
86
+
87
+ public String getUpdWhereStmt() {
88
+ return updWhereStmt;
89
+ }
90
+ }
91
+
92
+ public static boolean findReferencesAndUpdate(
93
+ Database mDB,
94
+ String tableName,
95
+ String whereStmt,
96
+ String[] initColNames,
97
+ ArrayList<Object> values
98
+ ) throws Exception {
99
+ try {
100
+ boolean retBool = true;
101
+ ReferenceResult result = getReferences(mDB, tableName);
102
+ List<String> references = result.retRefs;
103
+ String tableNameWithRefs = result.tableWithRefs;
104
+
105
+ if (references.size() <= 0) {
106
+ return retBool;
107
+ }
108
+
109
+ if (tableName.equals(tableNameWithRefs)) {
110
+ return retBool;
111
+ }
112
+
113
+ for (String ref : references) {
114
+ ForeignKeyInfo foreignKeyInfo = extractForeignKeyInfo(ref);
115
+
116
+ String refTable = foreignKeyInfo.tableName;
117
+ if (refTable.isEmpty() || !refTable.equals(tableName)) {
118
+ continue;
119
+ }
120
+
121
+ List<String> withRefsNames = foreignKeyInfo.forKeys;
122
+ List<String> colNames = foreignKeyInfo.refKeys;
123
+
124
+ if (colNames.size() != withRefsNames.size()) {
125
+ throw new Error("findReferencesAndUpdate: mismatch length");
126
+ }
127
+
128
+ String action = foreignKeyInfo.action;
129
+ if (action.equals("NO_ACTION")) {
130
+ continue;
131
+ }
132
+
133
+ String updTableName = tableNameWithRefs;
134
+ List<String> updColNames = withRefsNames;
135
+
136
+ UpdateResults results = new UpdateResults();
137
+
138
+ if (!checkValuesMatch(withRefsNames.toArray(new String[0]), initColNames)) {
139
+ Map<String, Object> relatedItemsResult = searchForRelatedItems(
140
+ mDB,
141
+ updTableName,
142
+ tableName,
143
+ whereStmt,
144
+ withRefsNames.toArray(new String[0]),
145
+ colNames.toArray(new String[0]),
146
+ values
147
+ );
148
+
149
+ if (
150
+ ((List<String>) relatedItemsResult.get("relatedItems")).size() == 0 &&
151
+ ((String) relatedItemsResult.get("key")).length() == 0
152
+ ) {
153
+ continue;
154
+ }
155
+
156
+ if (!updTableName.equals(tableName)) {
157
+ switch (action) {
158
+ case "RESTRICT":
159
+ results = upDateWhereForRestrict(relatedItemsResult);
160
+ break;
161
+ case "CASCADE":
162
+ results = upDateWhereForCascade(relatedItemsResult);
163
+ break;
164
+ default:
165
+ results = upDateWhereForDefault(withRefsNames, relatedItemsResult);
166
+ break;
167
+ }
168
+ }
169
+ } else {
170
+ throw new Error("Not implemented. Please transfer your example to the maintainer");
171
+ }
172
+
173
+ if (!results.getSetStmt().isEmpty() && !results.getUpdWhereStmt().isEmpty()) {
174
+ executeUpdateForDelete(mDB, updTableName, results.getUpdWhereStmt(), results.getSetStmt(), updColNames, values);
175
+ }
176
+ }
177
+ return retBool;
178
+ } catch (Exception error) {
179
+ String msg = error.getMessage() != null ? error.getMessage() : error.toString();
180
+ throw new Exception(msg);
181
+ }
182
+ }
183
+
184
+ public static ReferenceResult getReferences(Database mDB, String tableName) throws Exception {
185
+ String sqlStmt =
186
+ "SELECT sql FROM sqlite_master " +
187
+ "WHERE sql LIKE('%FOREIGN KEY%') AND sql LIKE('%REFERENCES%') AND " +
188
+ "sql LIKE('%" +
189
+ tableName +
190
+ "%') AND sql LIKE('%ON DELETE%');";
191
+
192
+ try {
193
+ JSArray references = mDB.selectSQL(sqlStmt, new ArrayList<>());
194
+ ReferenceResult referenceResult = new ReferenceResult();
195
+ List<String> retRefs = new ArrayList<>();
196
+ String tableWithRefs = "";
197
+
198
+ if (references.length() > 0) {
199
+ Map<String, Object> result = getRefs(references.getJSONObject(0).getString("sql"));
200
+ retRefs = (List<String>) result.get("foreignKeys");
201
+ tableWithRefs = (String) result.get("tableName");
202
+ }
203
+
204
+ referenceResult.tableWithRefs = tableWithRefs;
205
+ referenceResult.retRefs = retRefs;
206
+
207
+ return referenceResult;
208
+ } catch (Exception e) {
209
+ String error = e.getMessage() != null ? e.getMessage() : e.toString();
210
+ String msg = "getReferences: " + error;
211
+ throw new Exception(msg);
212
+ }
213
+ }
214
+
215
+ public static Map<String, Object> getRefs(String sqlStatement) throws Exception {
216
+ Map<String, Object> result = new HashMap<>();
217
+ String tableName = "";
218
+ List<String> foreignKeys = new ArrayList<>();
219
+ String statement = flattenMultilineString(sqlStatement);
220
+
221
+ try {
222
+ // Regular expression pattern to match the table name
223
+ String tableNamePattern = "CREATE\\s+TABLE\\s+(\\w+)\\s+\\(";
224
+ Pattern tableNameRegex = Pattern.compile(tableNamePattern);
225
+ Matcher tableNameMatcher = tableNameRegex.matcher(statement);
226
+ if (tableNameMatcher.find()) {
227
+ tableName = tableNameMatcher.group(1);
228
+ }
229
+
230
+ // Regular expression pattern to match the FOREIGN KEY constraints
231
+ String foreignKeyPattern =
232
+ "FOREIGN\\s+KEY\\s+\\([^)]+\\)\\s+REFERENCES\\s+(\\w+)\\s*\\([^)]+\\)\\s+ON\\s+DELETE\\s+(CASCADE|RESTRICT|SET\\s+DEFAULT|SET\\s+NULL|NO\\s+ACTION)";
233
+ Pattern foreignKeyRegex = Pattern.compile(foreignKeyPattern);
234
+ Matcher foreignKeyMatcher = foreignKeyRegex.matcher(statement);
235
+ while (foreignKeyMatcher.find()) {
236
+ String foreignKey = foreignKeyMatcher.group(0);
237
+ foreignKeys.add(foreignKey);
238
+ }
239
+ } catch (Exception e) {
240
+ String msg = "getRefs: Error creating regular expression: " + e.toString();
241
+ throw new Exception(msg);
242
+ }
243
+
244
+ result.put("tableName", tableName);
245
+ result.put("foreignKeys", foreignKeys);
246
+ return result;
247
+ }
248
+
249
+ public static boolean checkValuesMatch(String[] array1, String[] array2) {
250
+ for (String value : array1) {
251
+ boolean found = false;
252
+ for (String item : array2) {
253
+ if (value.equals(item)) {
254
+ found = true;
255
+ break;
256
+ }
257
+ }
258
+ if (!found) {
259
+ return false;
260
+ }
261
+ }
262
+ return true;
263
+ }
264
+
265
+ public static Map<String, Object> searchForRelatedItems(
266
+ Database mDB,
267
+ String updTableName,
268
+ String tableName,
269
+ String whStmt,
270
+ String[] withRefsNames,
271
+ String[] colNames,
272
+ ArrayList<Object> values
273
+ ) throws Exception {
274
+ List<Object> relatedItems = new ArrayList<>();
275
+ String key = "";
276
+ String[] t1Names = new String[withRefsNames.length];
277
+ String[] t2Names = new String[colNames.length];
278
+
279
+ for (int i = 0; i < withRefsNames.length; i++) {
280
+ t1Names[i] = "t1." + withRefsNames[i];
281
+ t2Names[i] = "t2." + colNames[i];
282
+ }
283
+
284
+ try {
285
+ // addPrefix to the whereClause and swap colNames with withRefsNames
286
+ String whereClause = addPrefixToWhereClause(whStmt, colNames, withRefsNames, "t2.");
287
+ // look at the whereclause and change colNames with withRefsNames
288
+ if (whereClause.endsWith(";")) {
289
+ whereClause = whereClause.substring(0, whereClause.length() - 1);
290
+ }
291
+
292
+ StringBuilder resultString = new StringBuilder();
293
+ for (int index = 0; index < t1Names.length; index++) {
294
+ resultString.append(t1Names[index]).append(" = ").append(t2Names[index]);
295
+ if (index < t1Names.length - 1) {
296
+ resultString.append(" AND ");
297
+ }
298
+ }
299
+
300
+ String sql =
301
+ "SELECT t1.rowid FROM " +
302
+ updTableName +
303
+ " t1 " +
304
+ "JOIN " +
305
+ tableName +
306
+ " t2 ON " +
307
+ resultString.toString() +
308
+ " " +
309
+ "WHERE " +
310
+ whereClause +
311
+ " AND t1.sql_deleted = 0;";
312
+
313
+ JSArray jsVals = mDB.selectSQL(sql, values);
314
+ if (jsVals.length() > 0) {
315
+ List<Map<String, Object>> mVals = JSArrayToJavaListMap(jsVals);
316
+ key = mVals.get(0).keySet().iterator().next();
317
+ relatedItems.addAll(mVals);
318
+ }
319
+ Map<String, Object> result = new HashMap<>();
320
+ result.put("key", key);
321
+ result.put("relatedItems", relatedItems);
322
+ return result;
323
+ } catch (Exception error) {
324
+ String msg = error.getMessage() != null ? error.getMessage() : error.toString();
325
+ throw new Exception(msg);
326
+ }
327
+ }
328
+
329
+ public static List<Map<String, Object>> JSArrayToJavaListMap(JSArray jsArray) throws JSONException {
330
+ List<Map<String, Object>> listMap = new ArrayList<>();
331
+
332
+ for (int i = 0; i < jsArray.length(); i++) {
333
+ JSObject jsObject = (JSObject) jsArray.get(i); // Assuming each element is an object
334
+ Map<String, Object> map = new HashMap<>();
335
+
336
+ // Extract key-value pairs from the JSObject and put them into the Map
337
+ for (Iterator<String> it = jsObject.keys(); it.hasNext();) {
338
+ String key = it.next();
339
+ map.put(key, jsObject.get(key)); // Convert JSValue to Java object
340
+ }
341
+
342
+ listMap.add(map); // Add the map to the list
343
+ }
344
+
345
+ return listMap; // Return the List<Map<String, Object>>
346
+ }
347
+
348
+ public static UpdateResults upDateWhereForRestrict(Map<String, Object> results) throws Exception {
349
+ try {
350
+ if (((List<?>) results.get("relatedItems")).size() > 0) {
351
+ String msg = "Restrict mode related items exist, please delete them first";
352
+ throw new Exception(msg);
353
+ }
354
+ return new UpdateResults();
355
+ } catch (Exception error) {
356
+ String msg = error.getMessage() != null ? error.getMessage() : "";
357
+ throw new Exception(msg);
358
+ }
359
+ }
360
+
361
+ public static UpdateResults upDateWhereForCascade(Map<String, Object> results) throws Exception {
362
+ String setStmt = "";
363
+ String uWhereStmt = "";
364
+
365
+ try {
366
+ String key = (String) results.get("key");
367
+ List<Object> cols = new ArrayList<>();
368
+ List<Map<String, Object>> relatedItems = (List<Map<String, Object>>) results.get("relatedItems");
369
+
370
+ for (Map<String, Object> relItem : relatedItems) {
371
+ Object mVal = relItem.get(key);
372
+ if (mVal != null) {
373
+ cols.add(mVal);
374
+ }
375
+ }
376
+
377
+ setStmt += "sql_deleted = 1";
378
+
379
+ // Create the where statement
380
+ StringBuilder uWhereStmtBuilder = new StringBuilder("WHERE " + key + " IN (");
381
+ for (Object col : cols) {
382
+ uWhereStmtBuilder.append(col).append(",");
383
+ }
384
+ if (uWhereStmtBuilder.toString().endsWith(",")) {
385
+ uWhereStmtBuilder.deleteCharAt(uWhereStmtBuilder.length() - 1);
386
+ }
387
+ uWhereStmtBuilder.append(");");
388
+ uWhereStmt = uWhereStmtBuilder.toString();
389
+ } catch (Exception error) {
390
+ String msg = error.getMessage() != null ? error.getMessage() : "";
391
+ throw new Exception(msg);
392
+ }
393
+ return new UpdateResults(setStmt, uWhereStmt);
394
+ }
395
+
396
+ public static UpdateResults upDateWhereForDefault(List<String> withRefsNames, Map<String, Object> results) throws Exception {
397
+ String setStmt = "";
398
+ String uWhereStmt = "";
399
+
400
+ try {
401
+ String key = (String) results.get("key");
402
+ List<Object> cols = new ArrayList<>();
403
+ List<Map<String, Object>> relatedItems = (List<Map<String, Object>>) results.get("relatedItems");
404
+
405
+ for (Map<String, Object> relItem : relatedItems) {
406
+ Object mVal = relItem.get(key);
407
+ if (mVal != null) {
408
+ cols.add(mVal);
409
+ }
410
+ }
411
+
412
+ // Create the set statement
413
+ for (String name : withRefsNames) {
414
+ setStmt += name + " = NULL, ";
415
+ }
416
+ setStmt += "sql_deleted = 0";
417
+
418
+ // Create the where statement
419
+ StringBuilder uWhereStmtBuilder = new StringBuilder("WHERE " + key + " IN (");
420
+ for (Object col : cols) {
421
+ uWhereStmtBuilder.append(col).append(",");
422
+ }
423
+ if (uWhereStmtBuilder.toString().endsWith(",")) {
424
+ uWhereStmtBuilder.deleteCharAt(uWhereStmtBuilder.length() - 1);
425
+ }
426
+ uWhereStmtBuilder.append(");");
427
+ uWhereStmt = uWhereStmtBuilder.toString();
428
+ } catch (Exception error) {
429
+ String msg = error.getMessage() != null ? error.getMessage() : "";
430
+ throw new Exception(msg);
431
+ }
432
+
433
+ return new UpdateResults(setStmt, uWhereStmt);
434
+ }
435
+
436
+ public static void executeUpdateForDelete(
437
+ Database mDB,
438
+ String tableName,
439
+ String whereStmt,
440
+ String setStmt,
441
+ List<String> colNames,
442
+ ArrayList<Object> values
443
+ ) throws Exception {
444
+ try {
445
+ long lastId = -1;
446
+
447
+ // Update sql_deleted for this references
448
+ String stmt = "UPDATE " + tableName + " SET " + setStmt + " " + whereStmt;
449
+ ArrayList<Object> selValues = getSelectedValues(values, whereStmt, colNames);
450
+
451
+ JSObject retObj = mDB.prepareSQL(stmt, selValues, false, "no");
452
+ lastId = retObj.getLong("lastId");
453
+ if (lastId == -1) {
454
+ String msg = "UPDATE sql_deleted failed for table: " + tableName;
455
+ throw new Exception(msg);
456
+ }
457
+ } catch (Exception error) {
458
+ String msg = error.getMessage() != null ? error.getMessage() : "";
459
+ throw new Exception(msg);
460
+ }
461
+ }
462
+
463
+ public static ArrayList<Object> getSelectedValues(ArrayList<Object> values, String whereStmt, List<String> colNames) {
464
+ ArrayList<Object> selValues = new ArrayList<>(); // Initialize the selected values ArrayList
465
+
466
+ if (values.size() > 0) {
467
+ String[] arrVal = whereStmt.split("\\?");
468
+ if (arrVal[arrVal.length - 1].equals(";")) {
469
+ arrVal[arrVal.length - 1] = "";
470
+ }
471
+
472
+ for (int jdx = 0; jdx < arrVal.length; jdx++) {
473
+ for (String updVal : colNames) {
474
+ List<Integer> indices = UtilsSQLStatement.indicesOf(arrVal[jdx], updVal, 0);
475
+ if (!indices.isEmpty()) {
476
+ selValues.add(values.get(jdx));
477
+ }
478
+ }
479
+ }
480
+ }
481
+
482
+ return selValues;
483
+ }
484
+ }
@@ -190,19 +190,19 @@ public class UtilsDrop {
190
190
  public void dropAll(Database db) throws Exception {
191
191
  Boolean success = false;
192
192
  try {
193
- db.getDb().beginTransaction();
193
+ db.beginTransaction();
194
194
  dropTables(db);
195
195
  dropIndexes(db);
196
196
  dropTriggers(db);
197
197
  dropViews(db);
198
- db.getDb().setTransactionSuccessful();
198
+ db.commitTransaction();
199
199
  success = true;
200
200
  } catch (Exception e) {
201
201
  String msg = "DropAll failed: " + e;
202
202
  Log.d(TAG, msg);
203
203
  throw new Exception(msg);
204
204
  } finally {
205
- if (success) db.getDb().endTransaction();
205
+ if (success) db.rollbackTransaction();
206
206
  try {
207
207
  db.getDb().execSQL("VACUUM;");
208
208
  } catch (Exception e) {
@@ -0,0 +1,169 @@
1
+ package com.getcapacitor.community.database.sqlite.SQLite;
2
+
3
+ import java.util.ArrayList;
4
+ import java.util.Arrays;
5
+ import java.util.HashSet;
6
+ import java.util.List;
7
+ import java.util.Set;
8
+ import java.util.regex.Matcher;
9
+ import java.util.regex.Pattern;
10
+
11
+ public class UtilsSQLStatement {
12
+
13
+ public static String flattenMultilineString(String input) {
14
+ String[] lines = input.split("\\r?\\n");
15
+ return String.join(" ", lines);
16
+ }
17
+
18
+ public static String extractTableName(String statement) {
19
+ Pattern pattern = Pattern.compile("(?:INSERT\\s+INTO|UPDATE|DELETE\\s+FROM)\\s+([^\\s]+)", Pattern.CASE_INSENSITIVE);
20
+ Matcher match = pattern.matcher(statement);
21
+ if (match.find() && match.groupCount() > 0) {
22
+ String tableName = match.group(1);
23
+ return tableName;
24
+ }
25
+ return null;
26
+ }
27
+
28
+ public static String extractWhereClause(String statement) {
29
+ Pattern pattern = Pattern.compile("WHERE(.+?)(?:ORDER\\s+BY|LIMIT|$)", Pattern.CASE_INSENSITIVE);
30
+ Matcher match = pattern.matcher(statement);
31
+ if (match.find() && match.groupCount() > 0) {
32
+ String whereClause = match.group(1).trim();
33
+ return whereClause;
34
+ }
35
+ return null;
36
+ }
37
+
38
+ public static String addPrefixToWhereClause(String whereClause, String[] colNames, String[] refNames, String prefix) {
39
+ String[] columnValuePairs = null;
40
+ String[] logicalOperators = new String[] { "AND", "OR", "NOT" };
41
+
42
+ for (String logicalOperator : logicalOperators) {
43
+ if (whereClause.contains(logicalOperator)) {
44
+ columnValuePairs = whereClause.split("\\s*" + logicalOperator + "\\s*");
45
+ break;
46
+ }
47
+ }
48
+
49
+ if (columnValuePairs == null) {
50
+ columnValuePairs = new String[] { whereClause };
51
+ }
52
+
53
+ List<String> modifiedPairs = new ArrayList<>();
54
+
55
+ for (String pair : columnValuePairs) {
56
+ String trimmedPair = pair.trim();
57
+
58
+ int operatorIndex = -1;
59
+ String operator = null;
60
+ for (String op : new String[] { "=", "<>", "<", "<=", ">", ">=", "IN", "BETWEEN", "LIKE" }) {
61
+ operatorIndex = trimmedPair.indexOf(op);
62
+ if (operatorIndex != -1) {
63
+ operator = op;
64
+ break;
65
+ }
66
+ }
67
+
68
+ if (operator == null) {
69
+ modifiedPairs.add(trimmedPair);
70
+ continue;
71
+ }
72
+
73
+ String column = trimmedPair.substring(0, operatorIndex).trim();
74
+ String value = trimmedPair.substring(operatorIndex + operator.length()).trim();
75
+
76
+ String newColumn = column;
77
+ int index = findIndexOfStringInArray(column, refNames);
78
+ if (index != -1) {
79
+ newColumn = getStringAtIndex(colNames, index);
80
+ }
81
+
82
+ String modifiedColumn = prefix + newColumn;
83
+ String modifiedPair = modifiedColumn + " " + operator + " " + value;
84
+ modifiedPairs.add(modifiedPair);
85
+ }
86
+
87
+ String logicalOperatorUsed = logicalOperators[0];
88
+ for (String logicalOperator : logicalOperators) {
89
+ if (whereClause.contains(logicalOperator)) {
90
+ logicalOperatorUsed = logicalOperator;
91
+ break;
92
+ }
93
+ }
94
+ String modWhereClause = String.join(" " + logicalOperatorUsed + " ", modifiedPairs);
95
+ return modWhereClause;
96
+ }
97
+
98
+ public static int findIndexOfStringInArray(String target, String[] array) {
99
+ for (int i = 0; i < array.length; i++) {
100
+ if (array[i].equals(target)) {
101
+ return i;
102
+ }
103
+ }
104
+ return -1;
105
+ }
106
+
107
+ public static String getStringAtIndex(String[] array, int index) {
108
+ if (index >= 0 && index < array.length) {
109
+ return array[index];
110
+ } else {
111
+ return null;
112
+ }
113
+ }
114
+
115
+ public static UtilsDelete.ForeignKeyInfo extractForeignKeyInfo(String sqlStatement) throws Exception {
116
+ // Define the regular expression pattern for extracting the FOREIGN KEY clause
117
+ String foreignKeyPattern =
118
+ "\\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))?";
119
+ Pattern pattern = Pattern.compile(foreignKeyPattern);
120
+ Matcher matcher = pattern.matcher(sqlStatement);
121
+
122
+ if (matcher.find()) {
123
+ String[] forKeys = matcher.group(1).split(",");
124
+ String tableName = matcher.group(2);
125
+ String[] refKeys = matcher.group(3).split(",");
126
+ String action = matcher.group(5) != null ? matcher.group(5) : "NO ACTION";
127
+ List<String> lForKeys = new ArrayList<>(Arrays.asList(forKeys));
128
+ List<String> lRefKeys = new ArrayList<>(Arrays.asList(refKeys));
129
+ return new UtilsDelete.ForeignKeyInfo(lForKeys, tableName, lRefKeys, action);
130
+ } else {
131
+ throw new Exception("extractForeignKeyInfo: No FOREIGN KEY found");
132
+ }
133
+ }
134
+
135
+ public static List<String> extractColumnNames(String whereClause) {
136
+ Set<String> keywords = new HashSet<>(Arrays.asList("AND", "OR", "IN", "VALUES", "LIKE", "BETWEEN", "NOT"));
137
+ String[] tokens = whereClause.split("\\s|,|\\(|\\)");
138
+
139
+ List<String> columns = new ArrayList<>();
140
+ boolean inClause = false;
141
+ boolean inValues = false;
142
+
143
+ for (String token : tokens) {
144
+ if (token.equals("IN")) {
145
+ inClause = true;
146
+ } else if (inClause && token.equals("(")) {
147
+ inValues = true;
148
+ } else if (inValues && token.equals(")")) {
149
+ inValues = false;
150
+ } else if (token.matches("\\b[a-zA-Z]\\w*\\b") && !inValues && !keywords.contains(token.toUpperCase())) {
151
+ columns.add(token);
152
+ }
153
+ }
154
+
155
+ return new ArrayList<>(new HashSet<>(columns));
156
+ }
157
+
158
+ public static List<Integer> indicesOf(String str, String searchStr, int fromIndex) {
159
+ List<Integer> indices = new ArrayList<>();
160
+
161
+ int currentIndex = str.indexOf(searchStr, fromIndex);
162
+ while (currentIndex != -1) {
163
+ indices.add(currentIndex);
164
+ currentIndex = str.indexOf(searchStr, currentIndex + 1);
165
+ }
166
+
167
+ return indices;
168
+ }
169
+ }
@@ -69,15 +69,15 @@ public class UtilsUpgrade {
69
69
  * @throws Exception
70
70
  */
71
71
  private void executeStatementsProcess(Database db, String[] statements) throws Exception {
72
- db.getDb().beginTransaction();
72
+ db.beginTransaction();
73
73
  try {
74
- db.execute(statements);
74
+ db.execute(statements, false);
75
75
 
76
- db.getDb().setTransactionSuccessful();
76
+ db.commitTransaction();
77
77
  } catch (Exception e) {
78
78
  throw new Exception("Error: executeStatementsProcess " + " failed " + e);
79
79
  } finally {
80
- db.getDb().endTransaction();
80
+ db.rollbackTransaction();
81
81
  }
82
82
  }
83
83
  }