@capacitor-community/sqlite 5.0.7-1 → 5.0.7
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 +6 -1
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/CapacitorSQLite.java +123 -1
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/CapacitorSQLitePlugin.java +112 -0
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/Database.java +140 -78
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/ImportExportJson/ImportFromJson.java +9 -9
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsDelete.java +484 -0
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsDrop.java +3 -3
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsSQLStatement.java +169 -0
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsUpgrade.java +4 -4
- package/dist/esm/definitions.d.ts +96 -11
- package/dist/esm/definitions.js +99 -50
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/web.d.ts +4 -0
- package/dist/esm/web.js +44 -0
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +143 -50
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +143 -50
- package/dist/plugin.js.map +1 -1
- package/electron/dist/plugin.js +1102 -260
- package/electron/dist/plugin.js.map +1 -1
- package/ios/Plugin/CapacitorSQLite.swift +119 -0
- package/ios/Plugin/CapacitorSQLitePlugin.m +4 -0
- package/ios/Plugin/CapacitorSQLitePlugin.swift +128 -0
- package/ios/Plugin/Database.swift +76 -0
- package/ios/Plugin/ImportExportJson/ImportFromJson.swift +13 -2
- package/ios/Plugin/Utils/UtilsDelete.swift +116 -114
- package/ios/Plugin/Utils/UtilsSQLCipher.swift +10 -3
- package/ios/Plugin/Utils/UtilsSQLStatement.swift +84 -84
- package/ios/Plugin/Utils/UtilsUpgrade.swift +3 -0
- package/package.json +2 -2
- package/src/definitions.ts +187 -53
- package/src/web.ts +48 -0
package/electron/dist/plugin.js
CHANGED
|
@@ -9,9 +9,9 @@ var require$$3 = require('node-fetch');
|
|
|
9
9
|
var require$$4 = require('os');
|
|
10
10
|
var require$$5 = require('jszip');
|
|
11
11
|
var require$$6 = require('electron');
|
|
12
|
-
var require$$
|
|
12
|
+
var require$$4$1 = require('better-sqlite3-multiple-ciphers');
|
|
13
13
|
var require$$3$1 = require('electron-json-storage');
|
|
14
|
-
var require$$1$
|
|
14
|
+
var require$$1$1 = require('crypto');
|
|
15
15
|
var require$$2$1 = require('crypto-js');
|
|
16
16
|
|
|
17
17
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
@@ -23,9 +23,9 @@ var require$$3__default = /*#__PURE__*/_interopDefaultLegacy(require$$3);
|
|
|
23
23
|
var require$$4__default = /*#__PURE__*/_interopDefaultLegacy(require$$4);
|
|
24
24
|
var require$$5__default = /*#__PURE__*/_interopDefaultLegacy(require$$5);
|
|
25
25
|
var require$$6__default = /*#__PURE__*/_interopDefaultLegacy(require$$6);
|
|
26
|
-
var require$$
|
|
26
|
+
var require$$4__default$1 = /*#__PURE__*/_interopDefaultLegacy(require$$4$1);
|
|
27
27
|
var require$$3__default$1 = /*#__PURE__*/_interopDefaultLegacy(require$$3$1);
|
|
28
|
-
var require$$1__default$
|
|
28
|
+
var require$$1__default$1 = /*#__PURE__*/_interopDefaultLegacy(require$$1$1);
|
|
29
29
|
var require$$2__default$1 = /*#__PURE__*/_interopDefaultLegacy(require$$2$1);
|
|
30
30
|
|
|
31
31
|
var src = {};
|
|
@@ -48,6 +48,330 @@ var exportToJson = {};
|
|
|
48
48
|
|
|
49
49
|
var utilsSQLite = {};
|
|
50
50
|
|
|
51
|
+
var UtilsSQL92Compatibility$1 = {};
|
|
52
|
+
|
|
53
|
+
Object.defineProperty(UtilsSQL92Compatibility$1, "__esModule", { value: true });
|
|
54
|
+
UtilsSQL92Compatibility$1.UtilsSQL92Compatibility = void 0;
|
|
55
|
+
class UtilsSQL92Compatibility {
|
|
56
|
+
compatibleSQL92(statement) {
|
|
57
|
+
let newStatement = "";
|
|
58
|
+
const action = (statement.trim().substring(0, 6)).toUpperCase();
|
|
59
|
+
switch (action) {
|
|
60
|
+
case "INSERT":
|
|
61
|
+
newStatement = this.insertSQL92(statement);
|
|
62
|
+
break;
|
|
63
|
+
case "UPDATE":
|
|
64
|
+
newStatement = this.updateSQL92(statement);
|
|
65
|
+
break;
|
|
66
|
+
case "DELETE":
|
|
67
|
+
case "SELECT":
|
|
68
|
+
newStatement = this.whereSQL92(statement);
|
|
69
|
+
break;
|
|
70
|
+
default:
|
|
71
|
+
throw new Error(`Error: ${action} not implemented`);
|
|
72
|
+
}
|
|
73
|
+
return newStatement;
|
|
74
|
+
}
|
|
75
|
+
;
|
|
76
|
+
insertSQL92(insertStatement) {
|
|
77
|
+
// Split the statement into parts
|
|
78
|
+
const inStmt = insertStatement.trim();
|
|
79
|
+
const valuesStartIndex = inStmt.indexOf('VALUES');
|
|
80
|
+
const columnsPart = inStmt.substring(0, valuesStartIndex);
|
|
81
|
+
const valuesPart = inStmt.substring(valuesStartIndex);
|
|
82
|
+
// Extract values and replace double quotes with single quotes
|
|
83
|
+
const modifiedValuesPart = valuesPart.replace(/"([^"]+)"/g, "'$1'");
|
|
84
|
+
// Reconstruct the modified statement
|
|
85
|
+
const modifiedStatement = columnsPart + modifiedValuesPart;
|
|
86
|
+
return modifiedStatement;
|
|
87
|
+
}
|
|
88
|
+
;
|
|
89
|
+
updateSQL92(updateStatement) {
|
|
90
|
+
// Split the statement into SET and WHERE parts
|
|
91
|
+
let isWhere = true;
|
|
92
|
+
const setWhereSplit = updateStatement.toUpperCase().split('WHERE');
|
|
93
|
+
if (setWhereSplit.length <= 1)
|
|
94
|
+
isWhere = false;
|
|
95
|
+
const setUpdate = setWhereSplit[0].toUpperCase().split('SET')[0].trim();
|
|
96
|
+
const setPart = setWhereSplit[0].toUpperCase().split('SET')[1].trim();
|
|
97
|
+
const modifiedSetPart = this.modSetPart(setPart);
|
|
98
|
+
let modifiedStatement = `${setUpdate} SET ${modifiedSetPart}`;
|
|
99
|
+
if (isWhere) {
|
|
100
|
+
for (let i = 1; i < setWhereSplit.length; i++) {
|
|
101
|
+
const wherePart = setWhereSplit[i].trim();
|
|
102
|
+
const modifiedWherePart = this.modWherePart(wherePart);
|
|
103
|
+
modifiedStatement += ` WHERE ${modifiedWherePart}`;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return modifiedStatement;
|
|
107
|
+
}
|
|
108
|
+
;
|
|
109
|
+
whereSQL92(statement) {
|
|
110
|
+
// Split the statement into SET and WHERE parts
|
|
111
|
+
const setWhereSplit = statement.toUpperCase().split('WHERE');
|
|
112
|
+
if (setWhereSplit.length <= 1)
|
|
113
|
+
return statement;
|
|
114
|
+
let modifiedStatement = `${setWhereSplit[0].trim()}`;
|
|
115
|
+
for (let i = 1; i < setWhereSplit.length; i++) {
|
|
116
|
+
const wherePart = setWhereSplit[1].trim();
|
|
117
|
+
const modifiedWherePart = this.modWherePart(wherePart);
|
|
118
|
+
modifiedStatement += `WHERE ${modifiedWherePart}`;
|
|
119
|
+
}
|
|
120
|
+
return modifiedStatement;
|
|
121
|
+
}
|
|
122
|
+
;
|
|
123
|
+
modSetPart(setStatement) {
|
|
124
|
+
const commaPart = setStatement.split(",");
|
|
125
|
+
const modCommaPart = [];
|
|
126
|
+
for (const com of commaPart) {
|
|
127
|
+
const equalPart = com.split("=");
|
|
128
|
+
const value = equalPart[1].replaceAll(`"`, `'`);
|
|
129
|
+
modCommaPart.push(`${equalPart[0].trim()} = ${value.trim()}`);
|
|
130
|
+
}
|
|
131
|
+
return modCommaPart.toString();
|
|
132
|
+
}
|
|
133
|
+
;
|
|
134
|
+
modWherePart(whereStatement) {
|
|
135
|
+
const keywords = new Set([
|
|
136
|
+
'=',
|
|
137
|
+
'<>',
|
|
138
|
+
'>',
|
|
139
|
+
'>=',
|
|
140
|
+
'<',
|
|
141
|
+
'<=',
|
|
142
|
+
'IN',
|
|
143
|
+
'VALUES',
|
|
144
|
+
'(',
|
|
145
|
+
',',
|
|
146
|
+
')',
|
|
147
|
+
'BETWEEN',
|
|
148
|
+
'LIKE',
|
|
149
|
+
'AND',
|
|
150
|
+
'OR',
|
|
151
|
+
'NOT'
|
|
152
|
+
]);
|
|
153
|
+
const newTokens = [];
|
|
154
|
+
const tokens = whereStatement.split(/(\s|,|\(|\))/).filter(item => item !== ' ').filter(item => item !== '');
|
|
155
|
+
let inClause = false;
|
|
156
|
+
let inValues = false;
|
|
157
|
+
let modValue = false;
|
|
158
|
+
let betwClause = false;
|
|
159
|
+
let opsClause = false;
|
|
160
|
+
let inValValues = false;
|
|
161
|
+
let inValPar = false;
|
|
162
|
+
for (const token of tokens) {
|
|
163
|
+
if ((new Set(['=', '<>', '>', '>=', '<', '<='])).has(token)) {
|
|
164
|
+
newTokens.push(token);
|
|
165
|
+
modValue = true;
|
|
166
|
+
opsClause = false;
|
|
167
|
+
}
|
|
168
|
+
else if (token.toUpperCase() === 'BETWEEN') {
|
|
169
|
+
newTokens.push(token);
|
|
170
|
+
betwClause = true;
|
|
171
|
+
modValue = true;
|
|
172
|
+
opsClause = false;
|
|
173
|
+
}
|
|
174
|
+
else if (betwClause && token.toUpperCase() === 'AND') {
|
|
175
|
+
newTokens.push(token);
|
|
176
|
+
modValue = true;
|
|
177
|
+
betwClause = false;
|
|
178
|
+
}
|
|
179
|
+
else if (token.toUpperCase() === 'LIKE') {
|
|
180
|
+
newTokens.push(token);
|
|
181
|
+
opsClause = false;
|
|
182
|
+
modValue = true;
|
|
183
|
+
}
|
|
184
|
+
else if (token.toUpperCase() === 'AND' ||
|
|
185
|
+
token.toUpperCase() === 'OR' ||
|
|
186
|
+
token.toUpperCase() === 'NOT') {
|
|
187
|
+
newTokens.push(token);
|
|
188
|
+
opsClause = true;
|
|
189
|
+
}
|
|
190
|
+
else if (token.toUpperCase() === 'IN') {
|
|
191
|
+
newTokens.push(token);
|
|
192
|
+
opsClause = false;
|
|
193
|
+
inClause = true;
|
|
194
|
+
}
|
|
195
|
+
else if (inClause && token === '(') {
|
|
196
|
+
newTokens.push(token);
|
|
197
|
+
modValue = true;
|
|
198
|
+
inValues = true;
|
|
199
|
+
}
|
|
200
|
+
else if (inValues && token.toUpperCase() === ',') {
|
|
201
|
+
newTokens.push(token);
|
|
202
|
+
modValue = true;
|
|
203
|
+
}
|
|
204
|
+
else if (inValues && token.toUpperCase() === 'VALUES') {
|
|
205
|
+
newTokens.push(token);
|
|
206
|
+
inValues = false;
|
|
207
|
+
inValValues = true;
|
|
208
|
+
inClause = false;
|
|
209
|
+
}
|
|
210
|
+
else if (inValValues && token === '(') {
|
|
211
|
+
newTokens.push(token);
|
|
212
|
+
inValPar = true;
|
|
213
|
+
modValue = true;
|
|
214
|
+
}
|
|
215
|
+
else if (inValPar && token.toUpperCase() === ',') {
|
|
216
|
+
newTokens.push(token);
|
|
217
|
+
modValue = true;
|
|
218
|
+
}
|
|
219
|
+
else if (inValPar && inValValues && token === ')') {
|
|
220
|
+
newTokens.push(token);
|
|
221
|
+
inValPar = false;
|
|
222
|
+
inValues = true;
|
|
223
|
+
}
|
|
224
|
+
else if ((inValues || inValValues) && token === ')') {
|
|
225
|
+
newTokens.push(token);
|
|
226
|
+
inValValues = false;
|
|
227
|
+
inValues = false;
|
|
228
|
+
inClause = false;
|
|
229
|
+
}
|
|
230
|
+
else if (modValue &&
|
|
231
|
+
!opsClause &&
|
|
232
|
+
!keywords.has(token.toUpperCase())) {
|
|
233
|
+
if (token.length > 0) {
|
|
234
|
+
const nwToken = token.replaceAll(`"`, `'`);
|
|
235
|
+
newTokens.push(nwToken);
|
|
236
|
+
modValue = false;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
newTokens.push(token);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
const ns = newTokens.join(" ");
|
|
244
|
+
return ns;
|
|
245
|
+
}
|
|
246
|
+
;
|
|
247
|
+
}
|
|
248
|
+
UtilsSQL92Compatibility$1.UtilsSQL92Compatibility = UtilsSQL92Compatibility;
|
|
249
|
+
|
|
250
|
+
var utilsDelete = {};
|
|
251
|
+
|
|
252
|
+
Object.defineProperty(utilsDelete, "__esModule", { value: true });
|
|
253
|
+
utilsDelete.UtilsDelete = void 0;
|
|
254
|
+
class UtilsDeleteError {
|
|
255
|
+
constructor(message) {
|
|
256
|
+
this.message = message;
|
|
257
|
+
}
|
|
258
|
+
static upDateWhereForDefault(message) {
|
|
259
|
+
return new UtilsDeleteError(message);
|
|
260
|
+
}
|
|
261
|
+
static upDateWhereForRestrict(message) {
|
|
262
|
+
return new UtilsDeleteError(message);
|
|
263
|
+
}
|
|
264
|
+
static upDateWhereForCascade(message) {
|
|
265
|
+
return new UtilsDeleteError(message);
|
|
266
|
+
}
|
|
267
|
+
static executeUpdateForDelete(message) {
|
|
268
|
+
return new UtilsDeleteError(message);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
class UtilsDelete {
|
|
272
|
+
getReferencedTableName(refValue) {
|
|
273
|
+
let tableName = '';
|
|
274
|
+
if (refValue.length > 0) {
|
|
275
|
+
const arr = refValue.split(new RegExp('REFERENCES', 'i'));
|
|
276
|
+
if (arr.length === 2) {
|
|
277
|
+
const oPar = arr[1].indexOf('(');
|
|
278
|
+
tableName = arr[1].substring(0, oPar).trim();
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
return tableName;
|
|
282
|
+
}
|
|
283
|
+
upDateWhereForDefault(withRefsNames, results) {
|
|
284
|
+
let setStmt = '';
|
|
285
|
+
let uWhereStmt = '';
|
|
286
|
+
try {
|
|
287
|
+
const key = results.key;
|
|
288
|
+
const cols = [];
|
|
289
|
+
for (const relItem of results.relatedItems) {
|
|
290
|
+
const mVal = relItem[key];
|
|
291
|
+
if (mVal !== undefined) {
|
|
292
|
+
cols.push(mVal);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
// Create the set statement
|
|
296
|
+
for (const name of withRefsNames) {
|
|
297
|
+
setStmt += `${name} = NULL, `;
|
|
298
|
+
}
|
|
299
|
+
setStmt += 'sql_deleted = 0';
|
|
300
|
+
// Create the where statement
|
|
301
|
+
uWhereStmt = `WHERE ${key} IN (`;
|
|
302
|
+
for (const col of cols) {
|
|
303
|
+
uWhereStmt += `${col},`;
|
|
304
|
+
}
|
|
305
|
+
if (uWhereStmt.endsWith(',')) {
|
|
306
|
+
uWhereStmt = uWhereStmt.slice(0, -1);
|
|
307
|
+
}
|
|
308
|
+
uWhereStmt += ');';
|
|
309
|
+
}
|
|
310
|
+
catch (error) {
|
|
311
|
+
const msg = error.message ? error.message : error;
|
|
312
|
+
throw UtilsDeleteError.upDateWhereForDefault(msg);
|
|
313
|
+
}
|
|
314
|
+
return { setStmt, uWhereStmt };
|
|
315
|
+
}
|
|
316
|
+
upDateWhereForRestrict(results) {
|
|
317
|
+
try {
|
|
318
|
+
const setStmt = '';
|
|
319
|
+
const uWhereStmt = '';
|
|
320
|
+
if (results.relatedItems.length > 0) {
|
|
321
|
+
const msg = 'Restrict mode related items exist, please delete them first';
|
|
322
|
+
throw UtilsDeleteError.upDateWhereForRestrict(msg);
|
|
323
|
+
}
|
|
324
|
+
return { setStmt, uWhereStmt };
|
|
325
|
+
}
|
|
326
|
+
catch (error) {
|
|
327
|
+
const msg = error.message ? error.message : error;
|
|
328
|
+
throw UtilsDeleteError.upDateWhereForRestrict(msg);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
upDateWhereForCascade(results) {
|
|
332
|
+
let setStmt = '';
|
|
333
|
+
let uWhereStmt = '';
|
|
334
|
+
try {
|
|
335
|
+
const key = results.key;
|
|
336
|
+
const cols = [];
|
|
337
|
+
for (const relItem of results.relatedItems) {
|
|
338
|
+
const mVal = relItem[key];
|
|
339
|
+
if (mVal !== undefined) {
|
|
340
|
+
cols.push(mVal);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
setStmt += 'sql_deleted = 1';
|
|
344
|
+
// Create the where statement
|
|
345
|
+
uWhereStmt = `WHERE ${key} IN (`;
|
|
346
|
+
for (const col of cols) {
|
|
347
|
+
uWhereStmt += `${col},`;
|
|
348
|
+
}
|
|
349
|
+
if (uWhereStmt.endsWith(',')) {
|
|
350
|
+
uWhereStmt = uWhereStmt.slice(0, -1);
|
|
351
|
+
}
|
|
352
|
+
uWhereStmt += ');';
|
|
353
|
+
}
|
|
354
|
+
catch (error) {
|
|
355
|
+
const msg = error.message ? error.message : error;
|
|
356
|
+
throw UtilsDeleteError.upDateWhereForCascade(msg);
|
|
357
|
+
}
|
|
358
|
+
return { setStmt, uWhereStmt };
|
|
359
|
+
}
|
|
360
|
+
getCurrentTimeAsInteger() {
|
|
361
|
+
const currentTime = Math.floor(Date.now() / 1000);
|
|
362
|
+
return currentTime;
|
|
363
|
+
}
|
|
364
|
+
checkValuesMatch(array1, array2) {
|
|
365
|
+
for (const value of array1) {
|
|
366
|
+
if (!array2.includes(value)) {
|
|
367
|
+
return false;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
return true;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
utilsDelete.UtilsDelete = UtilsDelete;
|
|
374
|
+
|
|
51
375
|
var utilsFile = {};
|
|
52
376
|
|
|
53
377
|
Object.defineProperty(utilsFile, "__esModule", { value: true });
|
|
@@ -653,14 +977,300 @@ class UtilsFile {
|
|
|
653
977
|
}
|
|
654
978
|
utilsFile.UtilsFile = UtilsFile;
|
|
655
979
|
|
|
980
|
+
var utilsSqlstatement = {};
|
|
981
|
+
|
|
982
|
+
Object.defineProperty(utilsSqlstatement, "__esModule", { value: true });
|
|
983
|
+
utilsSqlstatement.UtilsSQLStatement = void 0;
|
|
984
|
+
class UtilsSQLStatement {
|
|
985
|
+
constructor() {
|
|
986
|
+
this.replaceString = (originalStr, searchStr, replaceStr) => {
|
|
987
|
+
const range = originalStr.indexOf(searchStr);
|
|
988
|
+
if (range !== -1) {
|
|
989
|
+
const modifiedStr = originalStr.substring(0, range) +
|
|
990
|
+
replaceStr +
|
|
991
|
+
originalStr.substring(range + searchStr.length);
|
|
992
|
+
return modifiedStr;
|
|
993
|
+
}
|
|
994
|
+
return originalStr;
|
|
995
|
+
};
|
|
996
|
+
}
|
|
997
|
+
extractTableName(statement) {
|
|
998
|
+
const pattern = /(?:INSERT\s+INTO|UPDATE|DELETE\s+FROM)\s+([^\s]+)/i;
|
|
999
|
+
const match = statement.match(pattern);
|
|
1000
|
+
if (match?.[1]) {
|
|
1001
|
+
const tableName = match[1];
|
|
1002
|
+
return tableName;
|
|
1003
|
+
}
|
|
1004
|
+
return null;
|
|
1005
|
+
}
|
|
1006
|
+
extractWhereClause(statement) {
|
|
1007
|
+
const pattern = /WHERE(.+?)(?:ORDER\s+BY|LIMIT|$)/i;
|
|
1008
|
+
const match = statement.match(pattern);
|
|
1009
|
+
if (match?.[1]) {
|
|
1010
|
+
const whereClause = match[1].trim();
|
|
1011
|
+
return whereClause;
|
|
1012
|
+
}
|
|
1013
|
+
return null;
|
|
1014
|
+
}
|
|
1015
|
+
addPrefixToWhereClause(whereClause, colNames, refNames, prefix) {
|
|
1016
|
+
let columnValuePairs;
|
|
1017
|
+
if (whereClause.includes('AND')) {
|
|
1018
|
+
// Split the WHERE clause based on the "AND" keyword
|
|
1019
|
+
const subSequenceArray = whereClause.split('AND');
|
|
1020
|
+
columnValuePairs = subSequenceArray.map(pair => pair.trim());
|
|
1021
|
+
}
|
|
1022
|
+
else {
|
|
1023
|
+
columnValuePairs = [whereClause];
|
|
1024
|
+
}
|
|
1025
|
+
const modifiedPairs = columnValuePairs.map(pair => {
|
|
1026
|
+
const match = pair.match(/(\w+)\s*(=|IN|BETWEEN|LIKE)\s*(.+)/);
|
|
1027
|
+
if (!match) {
|
|
1028
|
+
return pair;
|
|
1029
|
+
}
|
|
1030
|
+
const column = match[1].trim();
|
|
1031
|
+
const operator = match[2].trim();
|
|
1032
|
+
const value = match[3].trim();
|
|
1033
|
+
let newColumn = column;
|
|
1034
|
+
const index = this.findIndexOfStringInArray(column, refNames);
|
|
1035
|
+
if (index !== -1) {
|
|
1036
|
+
newColumn = this.getStringAtIndex(colNames, index);
|
|
1037
|
+
}
|
|
1038
|
+
const modifiedColumn = `${prefix}${newColumn}`;
|
|
1039
|
+
const ret = `${modifiedColumn} ${operator} ${value}`;
|
|
1040
|
+
return ret;
|
|
1041
|
+
});
|
|
1042
|
+
return modifiedPairs.join(' AND ');
|
|
1043
|
+
}
|
|
1044
|
+
findIndexOfStringInArray(target, array) {
|
|
1045
|
+
return array.indexOf(target);
|
|
1046
|
+
}
|
|
1047
|
+
getStringAtIndex(array, index) {
|
|
1048
|
+
if (index >= 0 && index < array.length) {
|
|
1049
|
+
return array[index];
|
|
1050
|
+
}
|
|
1051
|
+
else {
|
|
1052
|
+
return undefined;
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
extractForeignKeyInfo(sqlStatement) {
|
|
1056
|
+
// Define the regular expression pattern for extracting the FOREIGN KEY clause
|
|
1057
|
+
const 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))?/;
|
|
1058
|
+
const matches = sqlStatement.match(foreignKeyPattern);
|
|
1059
|
+
if (matches) {
|
|
1060
|
+
const foreignKeyInfo = {
|
|
1061
|
+
forKeys: matches[1].split(',').map(key => key.trim()),
|
|
1062
|
+
tableName: matches[2],
|
|
1063
|
+
refKeys: matches[3].split(',').map(key => key.trim()),
|
|
1064
|
+
action: matches[5] ? matches[5] : 'NO ACTION',
|
|
1065
|
+
};
|
|
1066
|
+
return foreignKeyInfo;
|
|
1067
|
+
}
|
|
1068
|
+
else {
|
|
1069
|
+
throw new Error('extractForeignKeyInfo: No FOREIGN KEY found');
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
/*
|
|
1073
|
+
public extractColumnNames(whereClause: string): string[] {
|
|
1074
|
+
const regex = /\b(\w+)\s*(?=[=<>])|(?<=\()\s*(\w+),\s*(\w+)\s*(?=\))|(?<=\bIN\s*\(VALUES\s*\().*?(?=\))|(?<=\bIN\s*\().*?(?=\))|(?<=\bBETWEEN\s*).*?(?=\bAND\b)|(?<=\bLIKE\s*')\w+|\bAND\b/g;
|
|
1075
|
+
const matches = whereClause.matchAll(regex);
|
|
1076
|
+
const columnNames: string[] = [];
|
|
1077
|
+
|
|
1078
|
+
let andGroup: string[] = [];
|
|
1079
|
+
|
|
1080
|
+
for (const match of matches) {
|
|
1081
|
+
if (match[0] === 'AND') {
|
|
1082
|
+
columnNames.push(...andGroup);
|
|
1083
|
+
andGroup = [];
|
|
1084
|
+
} else if (match[1]) {
|
|
1085
|
+
andGroup.push(match[1]);
|
|
1086
|
+
} else if (match[2] && match[3]) {
|
|
1087
|
+
andGroup.push(match[2]);
|
|
1088
|
+
andGroup.push(match[3]);
|
|
1089
|
+
} else if (match[0]) {
|
|
1090
|
+
const values = match[0]
|
|
1091
|
+
.replace(/[()']/g, '') // Remove parentheses and single quotes
|
|
1092
|
+
.split(',')
|
|
1093
|
+
.map(value => value.trim());
|
|
1094
|
+
andGroup.push(...values);
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
columnNames.push(...andGroup);
|
|
1099
|
+
|
|
1100
|
+
return columnNames;
|
|
1101
|
+
}
|
|
1102
|
+
*/
|
|
1103
|
+
extractColumnNames(whereClause) {
|
|
1104
|
+
const keywords = new Set([
|
|
1105
|
+
'AND',
|
|
1106
|
+
'OR',
|
|
1107
|
+
'IN',
|
|
1108
|
+
'VALUES',
|
|
1109
|
+
'LIKE',
|
|
1110
|
+
'BETWEEN',
|
|
1111
|
+
'NOT',
|
|
1112
|
+
]);
|
|
1113
|
+
const tokens = whereClause.split(/(\s|,|\(|\))/).filter(item => item !== ' ');
|
|
1114
|
+
const columns = [];
|
|
1115
|
+
let inClause = false;
|
|
1116
|
+
let inValues = false;
|
|
1117
|
+
for (const token of tokens) {
|
|
1118
|
+
if (token === 'IN') {
|
|
1119
|
+
inClause = true;
|
|
1120
|
+
}
|
|
1121
|
+
else if (inClause && token === '(') {
|
|
1122
|
+
inValues = true;
|
|
1123
|
+
}
|
|
1124
|
+
else if (inValues && token === ')') {
|
|
1125
|
+
inValues = false;
|
|
1126
|
+
}
|
|
1127
|
+
else if (token.match(/\b[a-zA-Z]\w*\b/) &&
|
|
1128
|
+
!inValues &&
|
|
1129
|
+
!keywords.has(token.toUpperCase())) {
|
|
1130
|
+
if (token.length > 0) {
|
|
1131
|
+
columns.push(token);
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
return Array.from(new Set(columns));
|
|
1136
|
+
}
|
|
1137
|
+
flattenMultilineString(input) {
|
|
1138
|
+
const lines = input.split(/\r?\n/);
|
|
1139
|
+
return lines.join(' ');
|
|
1140
|
+
}
|
|
1141
|
+
getStmtAndRetColNames(sqlStmt, retMode) {
|
|
1142
|
+
const retWord = 'RETURNING';
|
|
1143
|
+
const retStmtNames = {
|
|
1144
|
+
stmt: sqlStmt,
|
|
1145
|
+
names: '',
|
|
1146
|
+
};
|
|
1147
|
+
const retWordIndex = sqlStmt.toUpperCase().indexOf(retWord);
|
|
1148
|
+
if (retWordIndex !== -1) {
|
|
1149
|
+
const prefix = sqlStmt.substring(0, retWordIndex);
|
|
1150
|
+
retStmtNames.stmt = `${prefix};`;
|
|
1151
|
+
if (retMode.substring(0, 2) === 'wA') {
|
|
1152
|
+
const suffix = sqlStmt.substring(retWordIndex + retWord.length);
|
|
1153
|
+
const names = suffix.trim();
|
|
1154
|
+
if (names.endsWith(';')) {
|
|
1155
|
+
retStmtNames.names = names.substring(0, names.length - 1);
|
|
1156
|
+
}
|
|
1157
|
+
else {
|
|
1158
|
+
retStmtNames.names = names;
|
|
1159
|
+
}
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1162
|
+
return retStmtNames;
|
|
1163
|
+
}
|
|
1164
|
+
extractCombinedPrimaryKey(whereClause) {
|
|
1165
|
+
const pattern = /WHERE\s*\((.+?)\)\s*(?:=|IN)\s*\((.+?)\)/g;
|
|
1166
|
+
const regex = new RegExp(pattern);
|
|
1167
|
+
const matches = whereClause.matchAll(regex);
|
|
1168
|
+
const primaryKeySets = [];
|
|
1169
|
+
for (const match of matches) {
|
|
1170
|
+
const keysString = match[1].trim();
|
|
1171
|
+
const keys = keysString.split(',').map(key => key.trim());
|
|
1172
|
+
primaryKeySets.push(keys);
|
|
1173
|
+
}
|
|
1174
|
+
return primaryKeySets.length === 0 ? null : primaryKeySets;
|
|
1175
|
+
}
|
|
1176
|
+
getWhereStmtForCombinedPK(whStmt, withRefs, colNames, keys) {
|
|
1177
|
+
let retWhere = whStmt;
|
|
1178
|
+
for (const grpKeys of keys) {
|
|
1179
|
+
const repKeys = grpKeys.join(',') === withRefs.join(',') ? colNames : withRefs;
|
|
1180
|
+
for (const [index, key] of grpKeys.entries()) {
|
|
1181
|
+
retWhere = this.replaceAllString(retWhere, key, repKeys[index]);
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
return retWhere;
|
|
1185
|
+
}
|
|
1186
|
+
replaceAllString(originalStr, searchStr, replaceStr) {
|
|
1187
|
+
return originalStr.split(searchStr).join(replaceStr);
|
|
1188
|
+
}
|
|
1189
|
+
indicesOf(str, searchStr, fromIndex = 0) {
|
|
1190
|
+
// Helper function to find indices of a substring within a string
|
|
1191
|
+
const indices = [];
|
|
1192
|
+
let currentIndex = str.indexOf(searchStr, fromIndex);
|
|
1193
|
+
while (currentIndex !== -1) {
|
|
1194
|
+
indices.push(currentIndex);
|
|
1195
|
+
currentIndex = str.indexOf(searchStr, currentIndex + 1);
|
|
1196
|
+
}
|
|
1197
|
+
return indices;
|
|
1198
|
+
}
|
|
1199
|
+
getWhereStmtForNonCombinedPK(whStmt, withRefs, colNames) {
|
|
1200
|
+
let whereStmt = '';
|
|
1201
|
+
let stmt = whStmt.substring(6);
|
|
1202
|
+
for (let idx = 0; idx < withRefs.length; idx++) {
|
|
1203
|
+
let colType = 'withRefsNames';
|
|
1204
|
+
let idxs = this.indicesOf(stmt, withRefs[idx]);
|
|
1205
|
+
if (idxs.length === 0) {
|
|
1206
|
+
idxs = this.indicesOf(stmt, colNames[idx]);
|
|
1207
|
+
colType = 'colNames';
|
|
1208
|
+
}
|
|
1209
|
+
if (idxs.length > 0) {
|
|
1210
|
+
let valStr = '';
|
|
1211
|
+
const indicesEqual = this.indicesOf(stmt, '=', idxs[0]);
|
|
1212
|
+
if (indicesEqual.length > 0) {
|
|
1213
|
+
const indicesAnd = this.indicesOf(stmt, 'AND', indicesEqual[0]);
|
|
1214
|
+
if (indicesAnd.length > 0) {
|
|
1215
|
+
valStr = stmt.substring(indicesEqual[0] + 1, indicesAnd[0] - 1);
|
|
1216
|
+
stmt = stmt.substring(indicesAnd[0] + 3);
|
|
1217
|
+
}
|
|
1218
|
+
else {
|
|
1219
|
+
valStr = stmt.substring(indicesEqual[0] + 1);
|
|
1220
|
+
}
|
|
1221
|
+
if (idx > 0) {
|
|
1222
|
+
whereStmt += ' AND ';
|
|
1223
|
+
}
|
|
1224
|
+
if (colType === 'withRefsNames') {
|
|
1225
|
+
whereStmt += colNames[idx] + ' = ' + valStr;
|
|
1226
|
+
}
|
|
1227
|
+
else {
|
|
1228
|
+
whereStmt += withRefs[idx] + ' = ' + valStr;
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
whereStmt = 'WHERE ' + whereStmt;
|
|
1234
|
+
return whereStmt;
|
|
1235
|
+
}
|
|
1236
|
+
updateWhere(whStmt, withRefs, colNames) {
|
|
1237
|
+
let whereStmt = '';
|
|
1238
|
+
if (whStmt.length <= 0) {
|
|
1239
|
+
return whereStmt;
|
|
1240
|
+
}
|
|
1241
|
+
if (whStmt.toUpperCase().substring(0, 5) !== 'WHERE') {
|
|
1242
|
+
return whereStmt;
|
|
1243
|
+
}
|
|
1244
|
+
if (withRefs.length === colNames.length) {
|
|
1245
|
+
// get whereStmt for primary combined key
|
|
1246
|
+
const keys = this.extractCombinedPrimaryKey(whStmt);
|
|
1247
|
+
if (keys) {
|
|
1248
|
+
whereStmt = this.getWhereStmtForCombinedPK(whStmt, withRefs, colNames, keys);
|
|
1249
|
+
}
|
|
1250
|
+
else {
|
|
1251
|
+
// get for non primary combined key
|
|
1252
|
+
whereStmt = this.getWhereStmtForNonCombinedPK(whStmt, withRefs, colNames);
|
|
1253
|
+
}
|
|
1254
|
+
}
|
|
1255
|
+
return whereStmt;
|
|
1256
|
+
}
|
|
1257
|
+
}
|
|
1258
|
+
utilsSqlstatement.UtilsSQLStatement = UtilsSQLStatement;
|
|
1259
|
+
|
|
656
1260
|
Object.defineProperty(utilsSQLite, "__esModule", { value: true });
|
|
657
1261
|
utilsSQLite.UtilsSQLite = void 0;
|
|
1262
|
+
const UtilsSQL92Compatibility_1$1 = UtilsSQL92Compatibility$1;
|
|
1263
|
+
const utilsDelete_1 = utilsDelete;
|
|
658
1264
|
const utilsFile_1$4 = utilsFile;
|
|
1265
|
+
const utilsSqlstatement_1 = utilsSqlstatement;
|
|
659
1266
|
//const SQLITE_OPEN_READONLY = 1;
|
|
660
1267
|
class UtilsSQLite {
|
|
661
1268
|
constructor() {
|
|
662
1269
|
this.fileUtil = new utilsFile_1$4.UtilsFile();
|
|
663
|
-
this.
|
|
1270
|
+
this.statUtil = new utilsSqlstatement_1.UtilsSQLStatement();
|
|
1271
|
+
this.delUtil = new utilsDelete_1.UtilsDelete();
|
|
1272
|
+
this.sql92Utils = new UtilsSQL92Compatibility_1$1.UtilsSQL92Compatibility();
|
|
1273
|
+
this.BCSQLite3 = require$$4__default$1["default"];
|
|
664
1274
|
}
|
|
665
1275
|
/**
|
|
666
1276
|
* OpenOrCreateDatabase
|
|
@@ -945,7 +1555,7 @@ class UtilsSQLite {
|
|
|
945
1555
|
* @param mDB
|
|
946
1556
|
* @param sql
|
|
947
1557
|
*/
|
|
948
|
-
execute(mDB, sql, fromJson) {
|
|
1558
|
+
execute(mDB, sql, fromJson, isSQL92) {
|
|
949
1559
|
const result = { changes: 0, lastId: -1 };
|
|
950
1560
|
const msg = 'Execute';
|
|
951
1561
|
let changes = -1;
|
|
@@ -954,11 +1564,8 @@ class UtilsSQLite {
|
|
|
954
1564
|
try {
|
|
955
1565
|
initChanges = this.dbChanges(mDB);
|
|
956
1566
|
let sqlStmt = sql;
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
sql.toLowerCase().includes('UPDATE'.toLowerCase())) {
|
|
960
|
-
sqlStmt = this.checkStatements(mDB, sql, fromJson);
|
|
961
|
-
}
|
|
1567
|
+
// modify sql to sql92 compatible
|
|
1568
|
+
sqlStmt = this.statementsToSQL92(mDB, sql, fromJson, isSQL92);
|
|
962
1569
|
this.execDB(mDB, sqlStmt);
|
|
963
1570
|
changes = this.dbChanges(mDB) - initChanges;
|
|
964
1571
|
lastId = this.getLastId(mDB);
|
|
@@ -971,7 +1578,7 @@ class UtilsSQLite {
|
|
|
971
1578
|
throw new Error(`${msg} ${errmsg}`);
|
|
972
1579
|
}
|
|
973
1580
|
}
|
|
974
|
-
|
|
1581
|
+
statementsToSQL92(mDB, sql, fromJson, isSQL92) {
|
|
975
1582
|
// split the statements in an array of statement
|
|
976
1583
|
let sqlStmt = sql.replace(/\n/g, '');
|
|
977
1584
|
// deal with trigger
|
|
@@ -981,11 +1588,10 @@ class UtilsSQLite {
|
|
|
981
1588
|
const resArr = [];
|
|
982
1589
|
// loop through the statement
|
|
983
1590
|
for (const stmt of sqlStmts) {
|
|
984
|
-
|
|
985
|
-
|
|
1591
|
+
let rStmt = stmt.trim();
|
|
1592
|
+
const method = rStmt
|
|
986
1593
|
.substring(0, Math.min(stmt.trim().length, 6))
|
|
987
1594
|
.toUpperCase();
|
|
988
|
-
let rStmt = stmt.trim();
|
|
989
1595
|
switch (method) {
|
|
990
1596
|
case 'CREATE':
|
|
991
1597
|
if (rStmt.includes('&END')) {
|
|
@@ -993,24 +1599,29 @@ class UtilsSQLite {
|
|
|
993
1599
|
}
|
|
994
1600
|
break;
|
|
995
1601
|
case 'DELETE':
|
|
996
|
-
if (!fromJson &&
|
|
997
|
-
|
|
1602
|
+
if (!fromJson && rStmt.toLowerCase().includes('WHERE'.toLowerCase())) {
|
|
1603
|
+
let whereStmt = rStmt;
|
|
1604
|
+
if (!isSQL92)
|
|
1605
|
+
whereStmt = this.cleanStatement(rStmt);
|
|
998
1606
|
rStmt = this.deleteSQL(mDB, whereStmt, []);
|
|
999
1607
|
}
|
|
1000
1608
|
break;
|
|
1001
1609
|
case 'INSERT':
|
|
1002
|
-
if (
|
|
1003
|
-
|
|
1610
|
+
if (rStmt.toLowerCase().includes('VALUES'.toLowerCase())) {
|
|
1611
|
+
if (!isSQL92)
|
|
1612
|
+
rStmt = this.cleanStatement(rStmt);
|
|
1004
1613
|
}
|
|
1005
1614
|
break;
|
|
1006
1615
|
case 'UPDATE':
|
|
1007
|
-
if (
|
|
1008
|
-
|
|
1616
|
+
if (rStmt.toLowerCase().includes('SET'.toLowerCase())) {
|
|
1617
|
+
if (!isSQL92)
|
|
1618
|
+
rStmt = this.cleanStatement(`${stmt.trim()}`);
|
|
1009
1619
|
}
|
|
1010
1620
|
break;
|
|
1011
1621
|
case 'SELECT':
|
|
1012
|
-
if (!fromJson &&
|
|
1013
|
-
|
|
1622
|
+
if (!fromJson && rStmt.toLowerCase().includes('WHERE'.toLowerCase())) {
|
|
1623
|
+
if (!isSQL92)
|
|
1624
|
+
rStmt = this.cleanStatement(rStmt);
|
|
1014
1625
|
}
|
|
1015
1626
|
break;
|
|
1016
1627
|
}
|
|
@@ -1041,7 +1652,7 @@ class UtilsSQLite {
|
|
|
1041
1652
|
* @param set
|
|
1042
1653
|
* @param fromJson
|
|
1043
1654
|
*/
|
|
1044
|
-
executeSet(mDB, set, fromJson, returnMode) {
|
|
1655
|
+
executeSet(mDB, set, fromJson, returnMode, isSQL92) {
|
|
1045
1656
|
const ret = { changes: 0, lastId: -1, values: [] };
|
|
1046
1657
|
let result = { changes: 0, lastId: -1 };
|
|
1047
1658
|
const msg = 'ExecuteSet';
|
|
@@ -1072,7 +1683,11 @@ class UtilsSQLite {
|
|
|
1072
1683
|
result = this.prepareRun(mDB, statement, mVal, fromJson, returnMode);
|
|
1073
1684
|
}
|
|
1074
1685
|
else {
|
|
1075
|
-
|
|
1686
|
+
let nStatement = statement;
|
|
1687
|
+
if (!isSQL92) {
|
|
1688
|
+
nStatement = this.cleanStatement(statement);
|
|
1689
|
+
}
|
|
1690
|
+
result = this.prepareRun(mDB, nStatement, [], fromJson, returnMode);
|
|
1076
1691
|
}
|
|
1077
1692
|
ret.changes += result.changes;
|
|
1078
1693
|
ret.lastId = result.lastId;
|
|
@@ -1095,6 +1710,7 @@ class UtilsSQLite {
|
|
|
1095
1710
|
* @param statement
|
|
1096
1711
|
* @param values
|
|
1097
1712
|
* @param fromJson
|
|
1713
|
+
* @param returnMode
|
|
1098
1714
|
*/
|
|
1099
1715
|
prepareRun(mDB, statement, values, fromJson, returnMode) {
|
|
1100
1716
|
const result = { changes: 0, lastId: -1 };
|
|
@@ -1142,8 +1758,7 @@ class UtilsSQLite {
|
|
|
1142
1758
|
let result = { changes: 0, lastInsertRowid: -1, values: [] };
|
|
1143
1759
|
const msg = 'runExec: ';
|
|
1144
1760
|
try {
|
|
1145
|
-
const
|
|
1146
|
-
const params = this.getStmtAndNames(cStmt, returnMode);
|
|
1761
|
+
const params = this.getStmtAndNames(stmt, returnMode);
|
|
1147
1762
|
switch (params.mMode) {
|
|
1148
1763
|
case 'one': {
|
|
1149
1764
|
const iniChanges = this.dbChanges(mDB);
|
|
@@ -1158,7 +1773,7 @@ class UtilsSQLite {
|
|
|
1158
1773
|
const res = statement.run(values);
|
|
1159
1774
|
result.lastInsertRowid = res.lastInsertRowid;
|
|
1160
1775
|
const sql = `SELECT ${params.names} FROM ${params.tableName} WHERE rowid = ${lowerId};`;
|
|
1161
|
-
const value = this.queryOne(mDB, sql, []);
|
|
1776
|
+
const value = this.queryOne(mDB, sql, [], true);
|
|
1162
1777
|
result.values.push(value);
|
|
1163
1778
|
}
|
|
1164
1779
|
result.changes = this.dbChanges(mDB) - iniChanges;
|
|
@@ -1176,7 +1791,7 @@ class UtilsSQLite {
|
|
|
1176
1791
|
const res = statement.run(values);
|
|
1177
1792
|
const upperId = res.lastInsertRowid;
|
|
1178
1793
|
const sql = `SELECT ${params.names} FROM ${params.tableName} WHERE rowid BETWEEN ${lowerId} AND ${upperId};`;
|
|
1179
|
-
result.values = this.queryAll(mDB, sql, []);
|
|
1794
|
+
result.values = this.queryAll(mDB, sql, [], true);
|
|
1180
1795
|
result.lastInsertRowid = res.lastInsertRowid;
|
|
1181
1796
|
}
|
|
1182
1797
|
result.changes = this.dbChanges(mDB) - iniChanges;
|
|
@@ -1229,17 +1844,39 @@ class UtilsSQLite {
|
|
|
1229
1844
|
try {
|
|
1230
1845
|
const isLast = this.isLastModified(mDB, true);
|
|
1231
1846
|
const isDel = this.isSqlDeleted(mDB, true);
|
|
1232
|
-
if (isLast
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1847
|
+
if (!isLast || !isDel) {
|
|
1848
|
+
return sqlStmt;
|
|
1849
|
+
}
|
|
1850
|
+
// Replace DELETE by UPDATE
|
|
1851
|
+
// set sql_deleted to 1 and the last_modified to
|
|
1852
|
+
// timenow
|
|
1853
|
+
const whereClause = this.statUtil.extractWhereClause(sqlStmt);
|
|
1854
|
+
if (!whereClause) {
|
|
1855
|
+
const msg = 'deleteSQL: cannot find a WHERE clause';
|
|
1856
|
+
throw new Error(`${msg}`);
|
|
1857
|
+
}
|
|
1858
|
+
const tableName = this.statUtil.extractTableName(sqlStmt);
|
|
1859
|
+
if (!tableName) {
|
|
1860
|
+
const msg = 'deleteSQL: cannot find a WHERE clause';
|
|
1861
|
+
throw new Error(`${msg}`);
|
|
1862
|
+
}
|
|
1863
|
+
const colNames = this.statUtil.extractColumnNames(whereClause);
|
|
1864
|
+
if (colNames.length === 0) {
|
|
1865
|
+
const msg = 'deleteSQL: Did not find column names in the WHERE Statement';
|
|
1866
|
+
throw new Error(`${msg}`);
|
|
1867
|
+
}
|
|
1868
|
+
const setStmt = 'sql_deleted = 1';
|
|
1869
|
+
// Find REFERENCES if any and update the sql_deleted
|
|
1870
|
+
// column
|
|
1871
|
+
const hasToUpdate = this.findReferencesAndUpdate(mDB, tableName, whereClause, colNames, values);
|
|
1872
|
+
if (hasToUpdate) {
|
|
1873
|
+
const whereStmt = whereClause.endsWith(';')
|
|
1874
|
+
? whereClause.slice(0, -1)
|
|
1875
|
+
: whereClause;
|
|
1876
|
+
sqlStmt = `UPDATE ${tableName} SET ${setStmt} WHERE ${whereStmt} AND sql_deleted = 0;`;
|
|
1877
|
+
}
|
|
1878
|
+
else {
|
|
1879
|
+
sqlStmt = '';
|
|
1243
1880
|
}
|
|
1244
1881
|
return sqlStmt;
|
|
1245
1882
|
}
|
|
@@ -1253,192 +1890,184 @@ class UtilsSQLite {
|
|
|
1253
1890
|
* @param mDB
|
|
1254
1891
|
* @param tableName
|
|
1255
1892
|
* @param whereStmt
|
|
1893
|
+
* @param initColNames
|
|
1256
1894
|
* @param values
|
|
1257
1895
|
* @returns
|
|
1258
1896
|
*/
|
|
1259
|
-
findReferencesAndUpdate(mDB, tableName, whereStmt, values) {
|
|
1260
|
-
const msg = 'FindReferencesAndUpdate';
|
|
1897
|
+
findReferencesAndUpdate(mDB, tableName, whereStmt, initColNames, values) {
|
|
1261
1898
|
try {
|
|
1262
|
-
const
|
|
1899
|
+
const retBool = true;
|
|
1900
|
+
const result = this.getReferences(mDB, tableName);
|
|
1901
|
+
const references = result.retRefs;
|
|
1902
|
+
const tableNameWithRefs = result.tableWithRefs;
|
|
1263
1903
|
if (references.length <= 0) {
|
|
1264
|
-
return;
|
|
1265
|
-
}
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1904
|
+
return retBool;
|
|
1905
|
+
}
|
|
1906
|
+
if (tableName === tableNameWithRefs) {
|
|
1907
|
+
return retBool;
|
|
1908
|
+
}
|
|
1909
|
+
// Loop through references
|
|
1910
|
+
for (const ref of references) {
|
|
1911
|
+
// Extract the FOREIGN KEY constraint info from the ref statement
|
|
1912
|
+
const foreignKeyInfo = this.statUtil.extractForeignKeyInfo(ref);
|
|
1913
|
+
// Get the tableName of the references
|
|
1914
|
+
const refTable = foreignKeyInfo.tableName;
|
|
1915
|
+
if (refTable === '' || refTable !== tableName) {
|
|
1271
1916
|
continue;
|
|
1272
1917
|
}
|
|
1273
|
-
//
|
|
1274
|
-
const withRefsNames =
|
|
1275
|
-
|
|
1276
|
-
|
|
1918
|
+
// Get the with ref column names
|
|
1919
|
+
const withRefsNames = foreignKeyInfo.forKeys;
|
|
1920
|
+
// Get the column names
|
|
1921
|
+
const colNames = foreignKeyInfo.refKeys;
|
|
1922
|
+
if (colNames.length !== withRefsNames.length) {
|
|
1923
|
+
const msg = 'findReferencesAndUpdate: mismatch length';
|
|
1924
|
+
throw new Error(msg);
|
|
1277
1925
|
}
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
if (colNames.length <= 0) {
|
|
1926
|
+
const action = foreignKeyInfo.action;
|
|
1927
|
+
if (action === 'NO_ACTION') {
|
|
1281
1928
|
continue;
|
|
1282
1929
|
}
|
|
1283
|
-
|
|
1284
|
-
const
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
}
|
|
1930
|
+
const updTableName = tableNameWithRefs;
|
|
1931
|
+
const updColNames = withRefsNames;
|
|
1932
|
+
let results = {
|
|
1933
|
+
uWhereStmt: '',
|
|
1934
|
+
setStmt: '',
|
|
1935
|
+
};
|
|
1936
|
+
if (!this.delUtil.checkValuesMatch(withRefsNames, initColNames)) {
|
|
1937
|
+
// Case: no match
|
|
1938
|
+
// Search for related items in tableName
|
|
1939
|
+
const result = this.searchForRelatedItems(mDB, updTableName, tableName, whereStmt, withRefsNames, colNames, values);
|
|
1940
|
+
if (result.relatedItems.length === 0 && result.key.length <= 0) {
|
|
1941
|
+
continue;
|
|
1942
|
+
}
|
|
1943
|
+
if (updTableName !== tableName) {
|
|
1944
|
+
switch (action) {
|
|
1945
|
+
case 'RESTRICT':
|
|
1946
|
+
results = this.delUtil.upDateWhereForRestrict(result);
|
|
1947
|
+
break;
|
|
1948
|
+
case 'CASCADE':
|
|
1949
|
+
results = this.delUtil.upDateWhereForCascade(result);
|
|
1950
|
+
break;
|
|
1951
|
+
default:
|
|
1952
|
+
results = this.delUtil.upDateWhereForDefault(withRefsNames, result);
|
|
1953
|
+
break;
|
|
1308
1954
|
}
|
|
1309
1955
|
}
|
|
1310
1956
|
}
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
if (lastId == -1) {
|
|
1314
|
-
const msg = `UPDATE sql_deleted failed for references table: ${refTable}`;
|
|
1315
|
-
throw new Error(`findReferencesAndUpdate: ${msg}`);
|
|
1957
|
+
else {
|
|
1958
|
+
throw new Error('Not implemented. Please transfer your example to the maintener');
|
|
1316
1959
|
}
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
}
|
|
1320
|
-
catch (err) {
|
|
1321
|
-
const errmsg = err.message ? err.message : err;
|
|
1322
|
-
throw new Error(`${msg} ${errmsg}`);
|
|
1323
|
-
}
|
|
1324
|
-
}
|
|
1325
|
-
getReferenceTableName(refValue) {
|
|
1326
|
-
let tableName = '';
|
|
1327
|
-
if (refValue.length > 0) {
|
|
1328
|
-
const arr = refValue.split(new RegExp('REFERENCES', 'i'));
|
|
1329
|
-
if (arr.length === 2) {
|
|
1330
|
-
const oPar = arr[1].indexOf('(');
|
|
1331
|
-
tableName = arr[1].substring(0, oPar).trim();
|
|
1332
|
-
}
|
|
1333
|
-
}
|
|
1334
|
-
return tableName;
|
|
1335
|
-
}
|
|
1336
|
-
getReferencedColumnName(refValue) {
|
|
1337
|
-
let colNames = [];
|
|
1338
|
-
if (refValue.length > 0) {
|
|
1339
|
-
const arr = refValue.split(new RegExp('REFERENCES', 'i'));
|
|
1340
|
-
if (arr.length === 2) {
|
|
1341
|
-
const oPar = arr[1].indexOf('(');
|
|
1342
|
-
const cPar = arr[1].indexOf(')');
|
|
1343
|
-
const colStr = arr[1].substring(oPar + 1, cPar).trim();
|
|
1344
|
-
colNames = colStr.split(',');
|
|
1345
|
-
}
|
|
1346
|
-
}
|
|
1347
|
-
return colNames;
|
|
1348
|
-
}
|
|
1349
|
-
getWithRefsColumnName(refValue) {
|
|
1350
|
-
let colNames = [];
|
|
1351
|
-
if (refValue.length > 0) {
|
|
1352
|
-
const arr = refValue.split(new RegExp('REFERENCES', 'i'));
|
|
1353
|
-
if (arr.length === 2) {
|
|
1354
|
-
const oPar = arr[0].indexOf('(');
|
|
1355
|
-
const cPar = arr[0].indexOf(')');
|
|
1356
|
-
const colStr = arr[0].substring(oPar + 1, cPar).trim();
|
|
1357
|
-
colNames = colStr.split(',');
|
|
1358
|
-
}
|
|
1359
|
-
}
|
|
1360
|
-
return colNames;
|
|
1361
|
-
}
|
|
1362
|
-
updateWhere(whStmt, withRefsNames, colNames) {
|
|
1363
|
-
let whereStmt = '';
|
|
1364
|
-
if (whStmt.length > 0) {
|
|
1365
|
-
const index = whStmt.toLowerCase().indexOf('WHERE'.toLowerCase());
|
|
1366
|
-
const stmt = whStmt.substring(index + 6);
|
|
1367
|
-
if (withRefsNames.length === colNames.length) {
|
|
1368
|
-
for (let i = 0; i < withRefsNames.length; i++) {
|
|
1369
|
-
let colType = 'withRefsNames';
|
|
1370
|
-
let idx = stmt.indexOf(withRefsNames[i]);
|
|
1371
|
-
if (idx === -1) {
|
|
1372
|
-
idx = stmt.indexOf(colNames[i]);
|
|
1373
|
-
colType = 'colNames';
|
|
1374
|
-
}
|
|
1375
|
-
if (idx > -1) {
|
|
1376
|
-
let valStr = '';
|
|
1377
|
-
const fEqual = stmt.indexOf('=', idx);
|
|
1378
|
-
if (fEqual > -1) {
|
|
1379
|
-
const iAnd = stmt.indexOf('AND', fEqual);
|
|
1380
|
-
const ilAnd = stmt.indexOf('and', fEqual);
|
|
1381
|
-
if (iAnd > -1) {
|
|
1382
|
-
valStr = stmt.substring(fEqual + 1, iAnd - 1).trim();
|
|
1383
|
-
}
|
|
1384
|
-
else if (ilAnd > -1) {
|
|
1385
|
-
valStr = stmt.substring(fEqual + 1, ilAnd - 1).trim();
|
|
1386
|
-
}
|
|
1387
|
-
else {
|
|
1388
|
-
valStr = stmt.substring(fEqual + 1, stmt.length).trim();
|
|
1389
|
-
}
|
|
1390
|
-
if (i > 0) {
|
|
1391
|
-
whereStmt += ' AND ';
|
|
1392
|
-
}
|
|
1393
|
-
if (colType === 'withRefsNames') {
|
|
1394
|
-
whereStmt += `${colNames[i]} = ${valStr}`;
|
|
1395
|
-
}
|
|
1396
|
-
else {
|
|
1397
|
-
whereStmt += `${withRefsNames[i]} = ${valStr}`;
|
|
1398
|
-
}
|
|
1399
|
-
}
|
|
1400
|
-
}
|
|
1960
|
+
if (results.setStmt.length > 0 && results.uWhereStmt.length > 0) {
|
|
1961
|
+
this.executeUpdateForDelete(mDB, updTableName, results.uWhereStmt, results.setStmt, updColNames, values);
|
|
1401
1962
|
}
|
|
1402
|
-
whereStmt = 'WHERE ' + whereStmt;
|
|
1403
1963
|
}
|
|
1964
|
+
return retBool;
|
|
1965
|
+
}
|
|
1966
|
+
catch (error) {
|
|
1967
|
+
const msg = error.message ? error.message : error;
|
|
1968
|
+
throw new Error(msg);
|
|
1404
1969
|
}
|
|
1405
|
-
return whereStmt;
|
|
1406
1970
|
}
|
|
1407
|
-
|
|
1408
|
-
|
|
1971
|
+
/**
|
|
1972
|
+
* getReferences
|
|
1973
|
+
* @param db
|
|
1974
|
+
* @param tableName
|
|
1975
|
+
* @returns
|
|
1976
|
+
*/
|
|
1977
|
+
getReferences(db, tableName) {
|
|
1409
1978
|
const sqlStmt = 'SELECT sql FROM sqlite_master ' +
|
|
1410
1979
|
"WHERE sql LIKE('%FOREIGN KEY%') AND sql LIKE('%REFERENCES%') AND " +
|
|
1411
1980
|
"sql LIKE('%" +
|
|
1412
1981
|
tableName +
|
|
1413
1982
|
"%') AND sql LIKE('%ON DELETE%');";
|
|
1414
1983
|
try {
|
|
1415
|
-
const res = this.queryAll(
|
|
1984
|
+
const res = this.queryAll(db, sqlStmt, [], true);
|
|
1416
1985
|
// get the reference's string(s)
|
|
1417
1986
|
let retRefs = [];
|
|
1987
|
+
let tableWithRefs = '';
|
|
1418
1988
|
if (res.length > 0) {
|
|
1419
|
-
|
|
1989
|
+
const result = this.getRefs(res[0].sql);
|
|
1990
|
+
retRefs = result.foreignKeys;
|
|
1991
|
+
tableWithRefs = result.tableName;
|
|
1420
1992
|
}
|
|
1421
|
-
return retRefs;
|
|
1993
|
+
return { tableWithRefs: tableWithRefs, retRefs: retRefs };
|
|
1422
1994
|
}
|
|
1423
1995
|
catch (err) {
|
|
1424
|
-
const
|
|
1425
|
-
|
|
1996
|
+
const error = err.message ? err.message : err;
|
|
1997
|
+
const msg = `getReferences: ${error}`;
|
|
1998
|
+
throw new Error(msg);
|
|
1426
1999
|
}
|
|
1427
2000
|
}
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
2001
|
+
/**
|
|
2002
|
+
* getRefs
|
|
2003
|
+
* @param sqlStatement
|
|
2004
|
+
* @returns
|
|
2005
|
+
*/
|
|
2006
|
+
getRefs(sqlStatement) {
|
|
2007
|
+
let tableName = '';
|
|
2008
|
+
const foreignKeys = [];
|
|
2009
|
+
const statement = this.statUtil.flattenMultilineString(sqlStatement);
|
|
2010
|
+
try {
|
|
2011
|
+
// Regular expression pattern to match the table name
|
|
2012
|
+
const tableNamePattern = /CREATE\s+TABLE\s+(\w+)\s+\(/;
|
|
2013
|
+
const tableNameMatch = statement.match(tableNamePattern);
|
|
2014
|
+
if (tableNameMatch) {
|
|
2015
|
+
tableName = tableNameMatch[1];
|
|
2016
|
+
}
|
|
2017
|
+
// Regular expression pattern to match the FOREIGN KEY constraints
|
|
2018
|
+
const foreignKeyPattern = /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)/g;
|
|
2019
|
+
const foreignKeyMatches = statement.matchAll(foreignKeyPattern);
|
|
2020
|
+
for (const foreignKeyMatch of foreignKeyMatches) {
|
|
2021
|
+
const foreignKey = foreignKeyMatch[0];
|
|
2022
|
+
foreignKeys.push(foreignKey);
|
|
2023
|
+
}
|
|
2024
|
+
}
|
|
2025
|
+
catch (error) {
|
|
2026
|
+
const msg = `getRefs: Error creating regular expression: ${error}`;
|
|
2027
|
+
throw new Error(msg);
|
|
2028
|
+
}
|
|
2029
|
+
return { tableName, foreignKeys };
|
|
2030
|
+
}
|
|
2031
|
+
/**
|
|
2032
|
+
* executeUpdateForDelete
|
|
2033
|
+
* @param mDB
|
|
2034
|
+
* @param tableName
|
|
2035
|
+
* @param whereStmt
|
|
2036
|
+
* @param setStmt
|
|
2037
|
+
* @param colNames
|
|
2038
|
+
* @param values
|
|
2039
|
+
*/
|
|
2040
|
+
executeUpdateForDelete(mDB, tableName, whereStmt, setStmt, colNames, values) {
|
|
2041
|
+
try {
|
|
2042
|
+
let lastId = -1;
|
|
2043
|
+
// Update sql_deleted for this references
|
|
2044
|
+
const stmt = `UPDATE ${tableName} SET ${setStmt} ${whereStmt}`;
|
|
2045
|
+
const selValues = [];
|
|
2046
|
+
if (values.length > 0) {
|
|
2047
|
+
const arrVal = whereStmt.split('?');
|
|
2048
|
+
if (arrVal[arrVal.length - 1] === ';') {
|
|
2049
|
+
arrVal.pop();
|
|
2050
|
+
}
|
|
2051
|
+
for (let jdx = 0; jdx < arrVal.length; jdx++) {
|
|
2052
|
+
for (const updVal of colNames) {
|
|
2053
|
+
const indices = this.statUtil.indicesOf(arrVal[jdx], updVal);
|
|
2054
|
+
if (indices.length > 0) {
|
|
2055
|
+
selValues.push(values[jdx]);
|
|
2056
|
+
}
|
|
2057
|
+
}
|
|
2058
|
+
}
|
|
2059
|
+
}
|
|
2060
|
+
const retObj = this.runExec(mDB, stmt, selValues, 'no');
|
|
2061
|
+
lastId = retObj['lastInsertRowid'];
|
|
2062
|
+
if (lastId === -1) {
|
|
2063
|
+
const msg = `UPDATE sql_deleted failed for table: ${tableName}`;
|
|
2064
|
+
throw new Error(msg);
|
|
2065
|
+
}
|
|
1434
2066
|
}
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
const tableName = str.substring(13, oPar).trim();
|
|
1439
|
-
retRefs.push(tableName);
|
|
2067
|
+
catch (error) {
|
|
2068
|
+
const msg = error.message ? error.message : error;
|
|
2069
|
+
throw new Error(msg);
|
|
1440
2070
|
}
|
|
1441
|
-
return retRefs;
|
|
1442
2071
|
}
|
|
1443
2072
|
/**
|
|
1444
2073
|
* QueryAll
|
|
@@ -1446,11 +2075,24 @@ class UtilsSQLite {
|
|
|
1446
2075
|
* @param sql
|
|
1447
2076
|
* @param values
|
|
1448
2077
|
*/
|
|
1449
|
-
queryAll(mDB, sql, values) {
|
|
2078
|
+
queryAll(mDB, sql, values, isSQL92) {
|
|
1450
2079
|
const msg = 'QueryAll';
|
|
1451
2080
|
try {
|
|
1452
|
-
|
|
2081
|
+
let cSql = sql;
|
|
2082
|
+
if (!isSQL92) {
|
|
2083
|
+
cSql = this.cleanStatement(sql);
|
|
2084
|
+
}
|
|
1453
2085
|
const stmt = mDB.prepare(cSql);
|
|
2086
|
+
if (!stmt.reader) {
|
|
2087
|
+
// statement doesn't returns data
|
|
2088
|
+
if (values != null && values.length > 0) {
|
|
2089
|
+
stmt.run(values);
|
|
2090
|
+
}
|
|
2091
|
+
else {
|
|
2092
|
+
stmt.run();
|
|
2093
|
+
}
|
|
2094
|
+
return [];
|
|
2095
|
+
}
|
|
1454
2096
|
let rows;
|
|
1455
2097
|
if (values != null && values.length > 0) {
|
|
1456
2098
|
rows = stmt.all(values);
|
|
@@ -1474,10 +2116,13 @@ class UtilsSQLite {
|
|
|
1474
2116
|
* @param sql
|
|
1475
2117
|
* @param values
|
|
1476
2118
|
*/
|
|
1477
|
-
queryOne(mDB, sql, values) {
|
|
2119
|
+
queryOne(mDB, sql, values, isSQL92) {
|
|
1478
2120
|
const msg = 'QueryOne';
|
|
1479
2121
|
try {
|
|
1480
|
-
|
|
2122
|
+
let cSql = sql;
|
|
2123
|
+
if (!isSQL92) {
|
|
2124
|
+
cSql = this.cleanStatement(sql);
|
|
2125
|
+
}
|
|
1481
2126
|
const stmt = mDB.prepare(cSql);
|
|
1482
2127
|
let row;
|
|
1483
2128
|
if (values != null && values.length > 0) {
|
|
@@ -1506,7 +2151,7 @@ class UtilsSQLite {
|
|
|
1506
2151
|
sql += 'ORDER BY rootpage DESC;';
|
|
1507
2152
|
const retArr = [];
|
|
1508
2153
|
try {
|
|
1509
|
-
const retQuery = this.queryAll(mDb, sql, []);
|
|
2154
|
+
const retQuery = this.queryAll(mDb, sql, [], true);
|
|
1510
2155
|
for (const query of retQuery) {
|
|
1511
2156
|
retArr.push(query.name);
|
|
1512
2157
|
}
|
|
@@ -1528,7 +2173,7 @@ class UtilsSQLite {
|
|
|
1528
2173
|
sql += 'ORDER BY rootpage DESC;';
|
|
1529
2174
|
const retArr = [];
|
|
1530
2175
|
try {
|
|
1531
|
-
const retQuery = this.queryAll(mDb, sql, []);
|
|
2176
|
+
const retQuery = this.queryAll(mDb, sql, [], true);
|
|
1532
2177
|
for (const query of retQuery) {
|
|
1533
2178
|
retArr.push(query.name);
|
|
1534
2179
|
}
|
|
@@ -1657,6 +2302,36 @@ class UtilsSQLite {
|
|
|
1657
2302
|
throw new Error(`${msg} ${errmsg}`);
|
|
1658
2303
|
}
|
|
1659
2304
|
}
|
|
2305
|
+
searchForRelatedItems(mDB, updTableName, tableName, whStmt, withRefsNames, colNames, values) {
|
|
2306
|
+
const relatedItems = [];
|
|
2307
|
+
let key = '';
|
|
2308
|
+
const t1Names = withRefsNames.map(name => `t1.${name}`);
|
|
2309
|
+
const t2Names = colNames.map(name => `t2.${name}`);
|
|
2310
|
+
try {
|
|
2311
|
+
// addPrefix to the whereClause and swap colNames with withRefsNames
|
|
2312
|
+
let whereClause = this.statUtil.addPrefixToWhereClause(whStmt, colNames, withRefsNames, 't2.');
|
|
2313
|
+
// look at the whereclause and change colNames with withRefsNames
|
|
2314
|
+
if (whereClause.endsWith(';')) {
|
|
2315
|
+
whereClause = whereClause.slice(0, -1);
|
|
2316
|
+
}
|
|
2317
|
+
const resultString = t1Names
|
|
2318
|
+
.map((t1, index) => `${t1} = ${t2Names[index]}`)
|
|
2319
|
+
.join(' AND ');
|
|
2320
|
+
const sql = `SELECT t1.rowid FROM ${updTableName} t1 ` +
|
|
2321
|
+
`JOIN ${tableName} t2 ON ${resultString} ` +
|
|
2322
|
+
`WHERE ${whereClause} AND t1.sql_deleted = 0;`;
|
|
2323
|
+
const vals = this.queryAll(mDB, sql, values, true);
|
|
2324
|
+
if (vals.length > 0) {
|
|
2325
|
+
key = Object.keys(vals[0])[0];
|
|
2326
|
+
relatedItems.push(...vals);
|
|
2327
|
+
}
|
|
2328
|
+
return { key: key, relatedItems: relatedItems };
|
|
2329
|
+
}
|
|
2330
|
+
catch (error) {
|
|
2331
|
+
const msg = error.message ? error.message : error;
|
|
2332
|
+
throw new Error(msg);
|
|
2333
|
+
}
|
|
2334
|
+
}
|
|
1660
2335
|
cleanStatement(stmt) {
|
|
1661
2336
|
let sql = '';
|
|
1662
2337
|
if (stmt.toLowerCase().includes('INSERT INTO'.toLowerCase()) ||
|
|
@@ -1665,7 +2340,7 @@ class UtilsSQLite {
|
|
|
1665
2340
|
stmt.toLowerCase().includes('DELETE FROM'.toLowerCase())) {
|
|
1666
2341
|
// check for JSON string
|
|
1667
2342
|
sql = this.dealJsonString(stmt);
|
|
1668
|
-
sql =
|
|
2343
|
+
sql = this.sql92Utils.compatibleSQL92(sql);
|
|
1669
2344
|
sql = sql.replaceAll('§', '"');
|
|
1670
2345
|
}
|
|
1671
2346
|
else {
|
|
@@ -1759,7 +2434,7 @@ class UtilsJson {
|
|
|
1759
2434
|
}
|
|
1760
2435
|
let query = 'SELECT name FROM sqlite_master WHERE ';
|
|
1761
2436
|
query += `type='table' AND name='${tableName}';`;
|
|
1762
|
-
const rows = this.sqliteUtil.queryAll(mDB, query, []);
|
|
2437
|
+
const rows = this.sqliteUtil.queryAll(mDB, query, [], true);
|
|
1763
2438
|
if (rows.length > 0) {
|
|
1764
2439
|
ret = true;
|
|
1765
2440
|
}
|
|
@@ -1779,7 +2454,7 @@ class UtilsJson {
|
|
|
1779
2454
|
}
|
|
1780
2455
|
let query = 'SELECT name FROM sqlite_master WHERE ';
|
|
1781
2456
|
query += `type='view' AND name='${viewName}';`;
|
|
1782
|
-
const rows = this.sqliteUtil.queryAll(mDB, query, []);
|
|
2457
|
+
const rows = this.sqliteUtil.queryAll(mDB, query, [], true);
|
|
1783
2458
|
if (rows.length > 0) {
|
|
1784
2459
|
ret = true;
|
|
1785
2460
|
}
|
|
@@ -1796,7 +2471,8 @@ class UtilsJson {
|
|
|
1796
2471
|
let changes = 0;
|
|
1797
2472
|
try {
|
|
1798
2473
|
// start a transaction
|
|
1799
|
-
this.sqliteUtil.beginTransaction(mDB, true);
|
|
2474
|
+
this.sqliteUtil.beginTransaction(mDB.database, true);
|
|
2475
|
+
mDB.setIsTransActive(true);
|
|
1800
2476
|
}
|
|
1801
2477
|
catch (err) {
|
|
1802
2478
|
throw new Error(`${msg} ${err}`);
|
|
@@ -1805,11 +2481,12 @@ class UtilsJson {
|
|
|
1805
2481
|
if (stmts.length > 0) {
|
|
1806
2482
|
const schemaStmt = stmts.join('\n');
|
|
1807
2483
|
try {
|
|
1808
|
-
const results = this.sqliteUtil.execute(mDB, schemaStmt, true);
|
|
2484
|
+
const results = this.sqliteUtil.execute(mDB.database, schemaStmt, true, true);
|
|
1809
2485
|
changes = results.changes;
|
|
1810
2486
|
if (changes < 0) {
|
|
1811
2487
|
try {
|
|
1812
|
-
this.sqliteUtil.rollbackTransaction(mDB, true);
|
|
2488
|
+
this.sqliteUtil.rollbackTransaction(mDB.database, true);
|
|
2489
|
+
mDB.setIsTransActive(false);
|
|
1813
2490
|
}
|
|
1814
2491
|
catch (err) {
|
|
1815
2492
|
throw new Error(`${msg} changes < 0 ${err}`);
|
|
@@ -1819,7 +2496,8 @@ class UtilsJson {
|
|
|
1819
2496
|
catch (err) {
|
|
1820
2497
|
const msg = err;
|
|
1821
2498
|
try {
|
|
1822
|
-
this.sqliteUtil.rollbackTransaction(mDB, true);
|
|
2499
|
+
this.sqliteUtil.rollbackTransaction(mDB.database, true);
|
|
2500
|
+
mDB.setIsTransActive(false);
|
|
1823
2501
|
throw new Error(`CreateSchema: ${msg}`);
|
|
1824
2502
|
}
|
|
1825
2503
|
catch (err) {
|
|
@@ -1828,7 +2506,8 @@ class UtilsJson {
|
|
|
1828
2506
|
}
|
|
1829
2507
|
}
|
|
1830
2508
|
try {
|
|
1831
|
-
this.sqliteUtil.commitTransaction(mDB, true);
|
|
2509
|
+
this.sqliteUtil.commitTransaction(mDB.database, true);
|
|
2510
|
+
mDB.setIsTransActive(false);
|
|
1832
2511
|
return changes;
|
|
1833
2512
|
}
|
|
1834
2513
|
catch (err) {
|
|
@@ -2113,7 +2792,7 @@ class UtilsJson {
|
|
|
2113
2792
|
else {
|
|
2114
2793
|
throw new Error(`${msg} Table ${tableName} no names`);
|
|
2115
2794
|
}
|
|
2116
|
-
const retValues = this.sqliteUtil.queryAll(mDb, query, []);
|
|
2795
|
+
const retValues = this.sqliteUtil.queryAll(mDb, query, [], true);
|
|
2117
2796
|
for (const rValue of retValues) {
|
|
2118
2797
|
const row = [];
|
|
2119
2798
|
for (const rName of rowNames) {
|
|
@@ -2192,7 +2871,7 @@ class UtilsJson {
|
|
|
2192
2871
|
if (typeof key === 'string')
|
|
2193
2872
|
query += `'${key}';`;
|
|
2194
2873
|
try {
|
|
2195
|
-
const resQuery = this.sqliteUtil.queryAll(mDB, query, []);
|
|
2874
|
+
const resQuery = this.sqliteUtil.queryAll(mDB, query, [], true);
|
|
2196
2875
|
if (resQuery.length === 1)
|
|
2197
2876
|
ret = true;
|
|
2198
2877
|
return ret;
|
|
@@ -2566,7 +3245,7 @@ class UtilsJson {
|
|
|
2566
3245
|
const msg = 'CreateView';
|
|
2567
3246
|
const stmt = `CREATE VIEW IF NOT EXISTS ${view.name} AS ${view.value};`;
|
|
2568
3247
|
try {
|
|
2569
|
-
const results = this.sqliteUtil.execute(mDB, stmt, true);
|
|
3248
|
+
const results = this.sqliteUtil.execute(mDB, stmt, true, true);
|
|
2570
3249
|
if (results.changes < 0) {
|
|
2571
3250
|
throw new Error(`${msg} ${view.name} failed`);
|
|
2572
3251
|
}
|
|
@@ -2658,7 +3337,7 @@ class ExportToJson {
|
|
|
2658
3337
|
sql += "AND name NOT LIKE 'sqlite_%';";
|
|
2659
3338
|
let retQuery = [];
|
|
2660
3339
|
try {
|
|
2661
|
-
retQuery = this.sqliteUtil.queryAll(mDb, sql, []);
|
|
3340
|
+
retQuery = this.sqliteUtil.queryAll(mDb, sql, [], true);
|
|
2662
3341
|
return retQuery;
|
|
2663
3342
|
}
|
|
2664
3343
|
catch (err) {
|
|
@@ -2671,7 +3350,7 @@ class ExportToJson {
|
|
|
2671
3350
|
try {
|
|
2672
3351
|
// get the last sync date
|
|
2673
3352
|
const stmt = `SELECT sync_date FROM sync_table WHERE id = ?;`;
|
|
2674
|
-
const row = this.sqliteUtil.queryOne(mDb, stmt, [2]);
|
|
3353
|
+
const row = this.sqliteUtil.queryOne(mDb, stmt, [2], true);
|
|
2675
3354
|
if (row != null) {
|
|
2676
3355
|
const key = Object.keys(row)[0];
|
|
2677
3356
|
retDate = row[key];
|
|
@@ -2703,7 +3382,7 @@ class ExportToJson {
|
|
|
2703
3382
|
else {
|
|
2704
3383
|
stmt = `INSERT INTO sync_table (sync_date) VALUES (${sDate});`;
|
|
2705
3384
|
}
|
|
2706
|
-
const results = this.sqliteUtil.execute(mDb, stmt, false);
|
|
3385
|
+
const results = this.sqliteUtil.execute(mDb, stmt, false, true);
|
|
2707
3386
|
if (results.changes < 0) {
|
|
2708
3387
|
return { result: false, message: `${msg} failed` };
|
|
2709
3388
|
}
|
|
@@ -2763,7 +3442,7 @@ class ExportToJson {
|
|
|
2763
3442
|
sql += "type='view' AND name NOT LIKE 'sqlite_%';";
|
|
2764
3443
|
let retQuery = [];
|
|
2765
3444
|
try {
|
|
2766
|
-
retQuery = this.sqliteUtil.queryAll(mDb, sql, []);
|
|
3445
|
+
retQuery = this.sqliteUtil.queryAll(mDb, sql, [], true);
|
|
2767
3446
|
for (const query of retQuery) {
|
|
2768
3447
|
const view = {};
|
|
2769
3448
|
view.name = query.name;
|
|
@@ -2785,7 +3464,7 @@ class ExportToJson {
|
|
|
2785
3464
|
let retDate = -1;
|
|
2786
3465
|
// get the last sync date
|
|
2787
3466
|
const stmt = `SELECT sync_date FROM sync_table WHERE id = ?;`;
|
|
2788
|
-
const row = this.sqliteUtil.queryOne(mDb, stmt, [1]);
|
|
3467
|
+
const row = this.sqliteUtil.queryOne(mDb, stmt, [1], true);
|
|
2789
3468
|
if (row != null) {
|
|
2790
3469
|
const key = Object.keys(row)[0];
|
|
2791
3470
|
retDate = row[key];
|
|
@@ -2959,7 +3638,7 @@ class ExportToJson {
|
|
|
2959
3638
|
let stmt = 'SELECT name,tbl_name,sql FROM sqlite_master WHERE ';
|
|
2960
3639
|
stmt += `type = 'index' AND tbl_name = '${tableName}' `;
|
|
2961
3640
|
stmt += `AND sql NOTNULL;`;
|
|
2962
|
-
const retIndexes = this.sqliteUtil.queryAll(mDb, stmt, []);
|
|
3641
|
+
const retIndexes = this.sqliteUtil.queryAll(mDb, stmt, [], true);
|
|
2963
3642
|
if (retIndexes.length > 0) {
|
|
2964
3643
|
for (const rIndex of retIndexes) {
|
|
2965
3644
|
const keys = Object.keys(rIndex);
|
|
@@ -3009,7 +3688,7 @@ class ExportToJson {
|
|
|
3009
3688
|
let stmt = 'SELECT name,tbl_name,sql FROM sqlite_master WHERE ';
|
|
3010
3689
|
stmt += `type = 'trigger' AND tbl_name = '${tableName}' `;
|
|
3011
3690
|
stmt += `AND sql NOT NULL;`;
|
|
3012
|
-
const retTriggers = this.sqliteUtil.queryAll(mDb, stmt, []);
|
|
3691
|
+
const retTriggers = this.sqliteUtil.queryAll(mDb, stmt, [], true);
|
|
3013
3692
|
if (retTriggers.length > 0) {
|
|
3014
3693
|
for (const rTrg of retTriggers) {
|
|
3015
3694
|
const keys = Object.keys(rTrg);
|
|
@@ -3213,7 +3892,7 @@ class ExportToJson {
|
|
|
3213
3892
|
// get total count of the table
|
|
3214
3893
|
let stmt = 'SELECT count(*) AS tcount ';
|
|
3215
3894
|
stmt += `FROM ${rTable.name};`;
|
|
3216
|
-
let retQuery = this.sqliteUtil.queryAll(mDb, stmt, []);
|
|
3895
|
+
let retQuery = this.sqliteUtil.queryAll(mDb, stmt, [], true);
|
|
3217
3896
|
if (retQuery.length != 1) {
|
|
3218
3897
|
errmsg = `${msg} total count not returned`;
|
|
3219
3898
|
break;
|
|
@@ -3223,7 +3902,7 @@ class ExportToJson {
|
|
|
3223
3902
|
stmt = 'SELECT count(*) AS mcount FROM ';
|
|
3224
3903
|
stmt += `${rTable.name} WHERE last_modified > `;
|
|
3225
3904
|
stmt += `${syncDate};`;
|
|
3226
|
-
retQuery = this.sqliteUtil.queryAll(mDb, stmt, []);
|
|
3905
|
+
retQuery = this.sqliteUtil.queryAll(mDb, stmt, [], true);
|
|
3227
3906
|
if (retQuery.length != 1)
|
|
3228
3907
|
break;
|
|
3229
3908
|
const totalModifiedCount = retQuery[0]['mcount'];
|
|
@@ -3330,7 +4009,7 @@ class UtilsDrop {
|
|
|
3330
4009
|
let stmt = 'SELECT name FROM sqlite_master WHERE ';
|
|
3331
4010
|
stmt += `type = '${type}' ${stmt1};`;
|
|
3332
4011
|
try {
|
|
3333
|
-
const elements = this.sqliteUtil.queryAll(db, stmt, []);
|
|
4012
|
+
const elements = this.sqliteUtil.queryAll(db, stmt, [], true);
|
|
3334
4013
|
if (elements.length > 0) {
|
|
3335
4014
|
const upType = type.toUpperCase();
|
|
3336
4015
|
const statements = [];
|
|
@@ -3389,7 +4068,7 @@ class UtilsDrop {
|
|
|
3389
4068
|
statements.push(stmt);
|
|
3390
4069
|
}
|
|
3391
4070
|
try {
|
|
3392
|
-
const results = this.sqliteUtil.execute(db, statements.join('\n'), false);
|
|
4071
|
+
const results = this.sqliteUtil.execute(db, statements.join('\n'), false, true);
|
|
3393
4072
|
if (results.changes < 0) {
|
|
3394
4073
|
throw new Error('DropTempTables: changes < 0');
|
|
3395
4074
|
}
|
|
@@ -3423,10 +4102,10 @@ class ImportFromJson {
|
|
|
3423
4102
|
const version = jsonData.version;
|
|
3424
4103
|
try {
|
|
3425
4104
|
// set User Version PRAGMA
|
|
3426
|
-
this.sqliteUtil.setVersion(mDB, version);
|
|
4105
|
+
this.sqliteUtil.setVersion(mDB.database, version);
|
|
3427
4106
|
// DROP ALL when mode="full"
|
|
3428
4107
|
if (jsonData.mode === 'full') {
|
|
3429
|
-
this.dropUtil.dropAll(mDB);
|
|
4108
|
+
this.dropUtil.dropAll(mDB.database);
|
|
3430
4109
|
}
|
|
3431
4110
|
// create database schema
|
|
3432
4111
|
changes = this.jsonUtil.createSchema(mDB, jsonData);
|
|
@@ -3443,7 +4122,8 @@ class ImportFromJson {
|
|
|
3443
4122
|
let message = '';
|
|
3444
4123
|
try {
|
|
3445
4124
|
// start a transaction
|
|
3446
|
-
this.sqliteUtil.beginTransaction(mDB, true);
|
|
4125
|
+
this.sqliteUtil.beginTransaction(mDB.database, true);
|
|
4126
|
+
mDB.setIsTransActive(true);
|
|
3447
4127
|
}
|
|
3448
4128
|
catch (err) {
|
|
3449
4129
|
throw new Error(`${msg} ${err}`);
|
|
@@ -3452,7 +4132,7 @@ class ImportFromJson {
|
|
|
3452
4132
|
if (jTable.values != null && jTable.values.length >= 1) {
|
|
3453
4133
|
// Create the table's data
|
|
3454
4134
|
try {
|
|
3455
|
-
results = this.jsonUtil.createDataTable(mDB, jTable, jsonData.mode);
|
|
4135
|
+
results = this.jsonUtil.createDataTable(mDB.database, jTable, jsonData.mode);
|
|
3456
4136
|
if (results.lastId < 0)
|
|
3457
4137
|
break;
|
|
3458
4138
|
isValue = true;
|
|
@@ -3466,7 +4146,8 @@ class ImportFromJson {
|
|
|
3466
4146
|
}
|
|
3467
4147
|
if (isValue) {
|
|
3468
4148
|
try {
|
|
3469
|
-
this.sqliteUtil.commitTransaction(mDB, true);
|
|
4149
|
+
this.sqliteUtil.commitTransaction(mDB.database, true);
|
|
4150
|
+
mDB.setIsTransActive(false);
|
|
3470
4151
|
return results.changes;
|
|
3471
4152
|
}
|
|
3472
4153
|
catch (err) {
|
|
@@ -3476,7 +4157,8 @@ class ImportFromJson {
|
|
|
3476
4157
|
else {
|
|
3477
4158
|
if (message.length > 0) {
|
|
3478
4159
|
try {
|
|
3479
|
-
this.sqliteUtil.rollbackTransaction(mDB, true);
|
|
4160
|
+
this.sqliteUtil.rollbackTransaction(mDB.database, true);
|
|
4161
|
+
mDB.setIsTransActive(false);
|
|
3480
4162
|
throw new Error(`${msg} ${message}`);
|
|
3481
4163
|
}
|
|
3482
4164
|
catch (err) {
|
|
@@ -3501,7 +4183,8 @@ class ImportFromJson {
|
|
|
3501
4183
|
let results;
|
|
3502
4184
|
try {
|
|
3503
4185
|
// start a transaction
|
|
3504
|
-
this.sqliteUtil.beginTransaction(mDB, true);
|
|
4186
|
+
this.sqliteUtil.beginTransaction(mDB.database, true);
|
|
4187
|
+
mDB.setIsTransActive(true);
|
|
3505
4188
|
}
|
|
3506
4189
|
catch (err) {
|
|
3507
4190
|
throw new Error(`${msg} ${err}`);
|
|
@@ -3510,7 +4193,7 @@ class ImportFromJson {
|
|
|
3510
4193
|
if (jView.value != null) {
|
|
3511
4194
|
// Create the view
|
|
3512
4195
|
try {
|
|
3513
|
-
results = this.jsonUtil.createView(mDB, jView);
|
|
4196
|
+
results = this.jsonUtil.createView(mDB.database, jView);
|
|
3514
4197
|
isView = true;
|
|
3515
4198
|
}
|
|
3516
4199
|
catch (err) {
|
|
@@ -3522,7 +4205,8 @@ class ImportFromJson {
|
|
|
3522
4205
|
}
|
|
3523
4206
|
if (isView) {
|
|
3524
4207
|
try {
|
|
3525
|
-
this.sqliteUtil.commitTransaction(mDB, true);
|
|
4208
|
+
this.sqliteUtil.commitTransaction(mDB.database, true);
|
|
4209
|
+
mDB.setIsTransActive(false);
|
|
3526
4210
|
return results.changes;
|
|
3527
4211
|
}
|
|
3528
4212
|
catch (err) {
|
|
@@ -3532,7 +4216,8 @@ class ImportFromJson {
|
|
|
3532
4216
|
else {
|
|
3533
4217
|
if (message.length > 0) {
|
|
3534
4218
|
try {
|
|
3535
|
-
this.sqliteUtil.rollbackTransaction(mDB, true);
|
|
4219
|
+
this.sqliteUtil.rollbackTransaction(mDB.database, true);
|
|
4220
|
+
mDB.setIsTransActive(false);
|
|
3536
4221
|
throw new Error(`${msg} ${message}`);
|
|
3537
4222
|
}
|
|
3538
4223
|
catch (err) {
|
|
@@ -3689,7 +4374,7 @@ class UtilsJsonEncryption {
|
|
|
3689
4374
|
constructor() {
|
|
3690
4375
|
this.fileSecret = new utilsSecret_1$2.UtilsSecret();
|
|
3691
4376
|
this.SALT = 'jeep_capacitor_sqlite';
|
|
3692
|
-
this.Crypto = require$$1__default$
|
|
4377
|
+
this.Crypto = require$$1__default$1["default"];
|
|
3693
4378
|
this.CryptoJS = require$$2__default$1["default"];
|
|
3694
4379
|
}
|
|
3695
4380
|
/**
|
|
@@ -3807,13 +4492,13 @@ class UtilsUpgrade {
|
|
|
3807
4492
|
}
|
|
3808
4493
|
try {
|
|
3809
4494
|
// set Foreign Keys Off
|
|
3810
|
-
|
|
3811
|
-
const initChanges =
|
|
4495
|
+
this.sqliteUtil.setForeignKeyConstraintsEnabled(mDB.database, false);
|
|
4496
|
+
const initChanges = this.sqliteUtil.dbChanges(mDB.database);
|
|
3812
4497
|
await this.executeStatementsProcess(mDB, statements);
|
|
3813
|
-
|
|
4498
|
+
this.sqliteUtil.setVersion(mDB.database, versionKey);
|
|
3814
4499
|
// set Foreign Keys On
|
|
3815
|
-
|
|
3816
|
-
changes = (await this.sqliteUtil.dbChanges(mDB)) - initChanges;
|
|
4500
|
+
this.sqliteUtil.setForeignKeyConstraintsEnabled(mDB.database, true);
|
|
4501
|
+
changes = (await this.sqliteUtil.dbChanges(mDB.database)) - initChanges;
|
|
3817
4502
|
}
|
|
3818
4503
|
catch (err) {
|
|
3819
4504
|
return Promise.reject(`onUpgrade: ${err}`);
|
|
@@ -3829,15 +4514,18 @@ class UtilsUpgrade {
|
|
|
3829
4514
|
*/
|
|
3830
4515
|
async executeStatementsProcess(mDB, statements) {
|
|
3831
4516
|
try {
|
|
3832
|
-
|
|
4517
|
+
this.sqliteUtil.beginTransaction(mDB.database, true);
|
|
4518
|
+
mDB.setIsTransActive(true);
|
|
3833
4519
|
for (const statement of statements) {
|
|
3834
|
-
|
|
4520
|
+
this.sqliteUtil.execute(mDB.database, statement, false, true);
|
|
3835
4521
|
}
|
|
3836
|
-
|
|
4522
|
+
this.sqliteUtil.commitTransaction(mDB.database, true);
|
|
4523
|
+
mDB.setIsTransActive(false);
|
|
3837
4524
|
return Promise.resolve();
|
|
3838
4525
|
}
|
|
3839
4526
|
catch (err) {
|
|
3840
|
-
|
|
4527
|
+
this.sqliteUtil.rollbackTransaction(mDB.database, true);
|
|
4528
|
+
mDB.setIsTransActive(false);
|
|
3841
4529
|
return Promise.reject(`ExecuteStatementProcess: ${err}`);
|
|
3842
4530
|
}
|
|
3843
4531
|
}
|
|
@@ -3851,6 +4539,7 @@ const exportToJson_1 = exportToJson;
|
|
|
3851
4539
|
const importFromJson_1 = importFromJson;
|
|
3852
4540
|
const utilsJson_1$1 = utilsJson;
|
|
3853
4541
|
const utilsJsonEncryption_1$1 = utilsJsonEncryption;
|
|
4542
|
+
const UtilsSQL92Compatibility_1 = UtilsSQL92Compatibility$1;
|
|
3854
4543
|
const utilsEncryption_1 = utilsEncryption;
|
|
3855
4544
|
const utilsFile_1$1 = utilsFile;
|
|
3856
4545
|
const utilsSQLite_1$1 = utilsSQLite;
|
|
@@ -3869,6 +4558,7 @@ class Database {
|
|
|
3869
4558
|
this.importFromJsonUtil = new importFromJson_1.ImportFromJson();
|
|
3870
4559
|
this.exportToJsonUtil = new exportToJson_1.ExportToJson();
|
|
3871
4560
|
this.upgradeVersionDict = {};
|
|
4561
|
+
this.sql92Utils = new UtilsSQL92Compatibility_1.UtilsSQL92Compatibility();
|
|
3872
4562
|
this.dbName = dbName;
|
|
3873
4563
|
this._encrypted = encrypted;
|
|
3874
4564
|
this._mode = mode;
|
|
@@ -3878,6 +4568,7 @@ class Database {
|
|
|
3878
4568
|
this.upgradeVersionDict = upgDict;
|
|
3879
4569
|
this.pathDB = this.fileUtil.getFilePath(dbName);
|
|
3880
4570
|
this._isDbOpen = false;
|
|
4571
|
+
this.isTransactionActive = false;
|
|
3881
4572
|
this.globalUtil = globalUtil ? globalUtil : new GlobalSQLite_1$1.GlobalSQLite();
|
|
3882
4573
|
if (this.pathDB.length === 0)
|
|
3883
4574
|
throw new Error('Could not generate a path to ' + dbName);
|
|
@@ -3921,7 +4612,7 @@ class Database {
|
|
|
3921
4612
|
try {
|
|
3922
4613
|
await this.fileUtil.copyFileName(this.dbName, `backup-${this.dbName}`);
|
|
3923
4614
|
// execute the upgrade flow process
|
|
3924
|
-
await this.upgradeUtil.onUpgrade(this
|
|
4615
|
+
await this.upgradeUtil.onUpgrade(this, this.upgradeVersionDict, curVersion, this.version);
|
|
3925
4616
|
// delete the backup database
|
|
3926
4617
|
await this.fileUtil.deleteFileName(`backup-${this.dbName}`);
|
|
3927
4618
|
}
|
|
@@ -3950,8 +4641,8 @@ class Database {
|
|
|
3950
4641
|
* @returns Promise<boolean>
|
|
3951
4642
|
*/
|
|
3952
4643
|
dbClose() {
|
|
3953
|
-
this.ensureDatabaseIsOpen();
|
|
3954
4644
|
try {
|
|
4645
|
+
this.ensureDatabaseIsOpen();
|
|
3955
4646
|
this.sqliteUtil.closeDB(this.database);
|
|
3956
4647
|
}
|
|
3957
4648
|
catch (err) {
|
|
@@ -3962,6 +4653,70 @@ class Database {
|
|
|
3962
4653
|
}
|
|
3963
4654
|
return;
|
|
3964
4655
|
}
|
|
4656
|
+
/**
|
|
4657
|
+
* IsTransActive
|
|
4658
|
+
* Is Database Transaction Active
|
|
4659
|
+
* @returns
|
|
4660
|
+
*/
|
|
4661
|
+
isTransActive() {
|
|
4662
|
+
return this.isTransactionActive;
|
|
4663
|
+
}
|
|
4664
|
+
/**
|
|
4665
|
+
* SetIsTransActive
|
|
4666
|
+
* Set the Database Transaction to Active
|
|
4667
|
+
* @returns
|
|
4668
|
+
*/
|
|
4669
|
+
setIsTransActive(value) {
|
|
4670
|
+
this.isTransactionActive = value;
|
|
4671
|
+
}
|
|
4672
|
+
/**
|
|
4673
|
+
* DbBeginTransaction
|
|
4674
|
+
* Database Begin Transaction
|
|
4675
|
+
* @returns
|
|
4676
|
+
*/
|
|
4677
|
+
dbBeginTransaction() {
|
|
4678
|
+
try {
|
|
4679
|
+
this.ensureDatabaseIsOpen();
|
|
4680
|
+
this.sqliteUtil.beginTransaction(this.database, true);
|
|
4681
|
+
this.setIsTransActive(true);
|
|
4682
|
+
return 0;
|
|
4683
|
+
}
|
|
4684
|
+
catch (err) {
|
|
4685
|
+
throw new Error(`DbBeginTransaction: ${err}`);
|
|
4686
|
+
}
|
|
4687
|
+
}
|
|
4688
|
+
/**
|
|
4689
|
+
* DbCommitTransaction
|
|
4690
|
+
* Database Commit Transaction
|
|
4691
|
+
* @returns
|
|
4692
|
+
*/
|
|
4693
|
+
dbCommitTransaction() {
|
|
4694
|
+
try {
|
|
4695
|
+
this.ensureDatabaseIsOpen();
|
|
4696
|
+
this.sqliteUtil.commitTransaction(this.database, true);
|
|
4697
|
+
this.setIsTransActive(false);
|
|
4698
|
+
return 0;
|
|
4699
|
+
}
|
|
4700
|
+
catch (err) {
|
|
4701
|
+
throw new Error(`DbCommitTransaction: ${err}`);
|
|
4702
|
+
}
|
|
4703
|
+
}
|
|
4704
|
+
/**
|
|
4705
|
+
* DbRollbackTransaction
|
|
4706
|
+
* Database Rollback Transaction
|
|
4707
|
+
* @returns
|
|
4708
|
+
*/
|
|
4709
|
+
dbRollbackTransaction() {
|
|
4710
|
+
try {
|
|
4711
|
+
this.ensureDatabaseIsOpen();
|
|
4712
|
+
this.sqliteUtil.rollbackTransaction(this.database, true);
|
|
4713
|
+
this.setIsTransActive(false);
|
|
4714
|
+
return 0;
|
|
4715
|
+
}
|
|
4716
|
+
catch (err) {
|
|
4717
|
+
throw new Error(`DbCommitTransaction: ${err}`);
|
|
4718
|
+
}
|
|
4719
|
+
}
|
|
3965
4720
|
/**
|
|
3966
4721
|
* ChangeSecret
|
|
3967
4722
|
* open the @journeyapps/sqlcipher sqlite3 database
|
|
@@ -4074,7 +4829,7 @@ class Database {
|
|
|
4074
4829
|
);`;
|
|
4075
4830
|
stmts += `INSERT INTO sync_table (sync_date) VALUES (
|
|
4076
4831
|
${date});`;
|
|
4077
|
-
const results = this.sqliteUtil.execute(this.database, stmts, false);
|
|
4832
|
+
const results = this.sqliteUtil.execute(this.database, stmts, false, true);
|
|
4078
4833
|
changes = results.changes;
|
|
4079
4834
|
if (results.changes < 0) {
|
|
4080
4835
|
throw new Error(`CreateSyncTable: failed changes < 0`);
|
|
@@ -4109,7 +4864,7 @@ class Database {
|
|
|
4109
4864
|
const syncDateUnixTimestamp = Math.round(new Date(syncDate).getTime() / 1000);
|
|
4110
4865
|
let stmt = `UPDATE sync_table SET sync_date = `;
|
|
4111
4866
|
stmt += `${syncDateUnixTimestamp} WHERE id = 1;`;
|
|
4112
|
-
const results = this.sqliteUtil.execute(this.database, stmt, false);
|
|
4867
|
+
const results = this.sqliteUtil.execute(this.database, stmt, false, true);
|
|
4113
4868
|
if (results.changes < 0) {
|
|
4114
4869
|
return { result: false, message: 'setSyncDate failed' };
|
|
4115
4870
|
}
|
|
@@ -4149,9 +4904,11 @@ class Database {
|
|
|
4149
4904
|
* ExecuteSQL
|
|
4150
4905
|
* execute raw sql statements store in a string
|
|
4151
4906
|
* @param sql: string
|
|
4907
|
+
* @param transaction: boolean
|
|
4908
|
+
* @param isSQL92: boolean
|
|
4152
4909
|
* @returns Promise<number>
|
|
4153
4910
|
*/
|
|
4154
|
-
executeSQL(sql, transaction) {
|
|
4911
|
+
executeSQL(sql, transaction, isSQL92) {
|
|
4155
4912
|
this.ensureDatabaseIsOpen();
|
|
4156
4913
|
try {
|
|
4157
4914
|
if (transaction) {
|
|
@@ -4159,7 +4916,7 @@ class Database {
|
|
|
4159
4916
|
console.log(`$$$ in executeSQL journal_mode: ${mode} $$$`);
|
|
4160
4917
|
this.sqliteUtil.beginTransaction(this.database, this._isDbOpen);
|
|
4161
4918
|
}
|
|
4162
|
-
const results = this.sqliteUtil.execute(this.database, sql, false);
|
|
4919
|
+
const results = this.sqliteUtil.execute(this.database, sql, false, isSQL92);
|
|
4163
4920
|
if (results.changes < 0) {
|
|
4164
4921
|
throw new Error('ExecuteSQL: changes < 0');
|
|
4165
4922
|
}
|
|
@@ -4186,12 +4943,13 @@ class Database {
|
|
|
4186
4943
|
* execute a sql query with/without binding values
|
|
4187
4944
|
* @param sql: string
|
|
4188
4945
|
* @param values: string[]
|
|
4946
|
+
* @param isSQL92: boolean
|
|
4189
4947
|
* @returns Promise<any[]>
|
|
4190
4948
|
*/
|
|
4191
|
-
selectSQL(sql, values) {
|
|
4949
|
+
selectSQL(sql, values, isSQL92) {
|
|
4192
4950
|
this.ensureDatabaseIsOpen();
|
|
4193
4951
|
try {
|
|
4194
|
-
const selectResult = this.sqliteUtil.queryAll(this.database, sql, values);
|
|
4952
|
+
const selectResult = this.sqliteUtil.queryAll(this.database, sql, values, isSQL92);
|
|
4195
4953
|
return selectResult;
|
|
4196
4954
|
}
|
|
4197
4955
|
catch (err) {
|
|
@@ -4203,9 +4961,10 @@ class Database {
|
|
|
4203
4961
|
* execute a raw sql statement with/without binding values
|
|
4204
4962
|
* @param sql: string
|
|
4205
4963
|
* @param values: string[]
|
|
4964
|
+
* @param isSQL92: boolean,
|
|
4206
4965
|
* @returns Promise<{changes:number, lastId:number}>
|
|
4207
4966
|
*/
|
|
4208
|
-
runSQL(statement, values, transaction, returnMode) {
|
|
4967
|
+
runSQL(statement, values, transaction, returnMode, isSQL92) {
|
|
4209
4968
|
this.ensureDatabaseIsOpen();
|
|
4210
4969
|
try {
|
|
4211
4970
|
// start a transaction
|
|
@@ -4219,7 +4978,11 @@ class Database {
|
|
|
4219
4978
|
throw new Error(`RunSQL: ${err}`);
|
|
4220
4979
|
}
|
|
4221
4980
|
try {
|
|
4222
|
-
|
|
4981
|
+
let nStmt = statement;
|
|
4982
|
+
if (!isSQL92 && values.length === 0) {
|
|
4983
|
+
nStmt = this.sql92Utils.compatibleSQL92(statement);
|
|
4984
|
+
}
|
|
4985
|
+
const results = this.sqliteUtil.prepareRun(this.database, nStmt, values, false, returnMode);
|
|
4223
4986
|
if (results.lastId < 0) {
|
|
4224
4987
|
if (transaction) {
|
|
4225
4988
|
this.sqliteUtil.rollbackTransaction(this.database, this._isDbOpen);
|
|
@@ -4242,9 +5005,12 @@ class Database {
|
|
|
4242
5005
|
* ExecSet
|
|
4243
5006
|
* execute a set of raw sql statements with/without binding values
|
|
4244
5007
|
* @param set: any[]
|
|
5008
|
+
* @param transaction: boolean,
|
|
5009
|
+
* @param returnMode: string,
|
|
5010
|
+
* @param isSQL92: boolean,
|
|
4245
5011
|
* @returns Promise<{changes:number, lastId:number}>
|
|
4246
5012
|
*/
|
|
4247
|
-
execSet(set, transaction, returnMode) {
|
|
5013
|
+
execSet(set, transaction, returnMode, isSQL92) {
|
|
4248
5014
|
this.ensureDatabaseIsOpen();
|
|
4249
5015
|
let results = { changes: 0, lastId: -1 };
|
|
4250
5016
|
try {
|
|
@@ -4259,7 +5025,7 @@ class Database {
|
|
|
4259
5025
|
throw new Error(`ExecSet: ${err}`);
|
|
4260
5026
|
}
|
|
4261
5027
|
try {
|
|
4262
|
-
results = this.sqliteUtil.executeSet(this.database, set, false, returnMode);
|
|
5028
|
+
results = this.sqliteUtil.executeSet(this.database, set, false, returnMode, isSQL92);
|
|
4263
5029
|
if (transaction) {
|
|
4264
5030
|
this.sqliteUtil.commitTransaction(this.database, this._isDbOpen);
|
|
4265
5031
|
}
|
|
@@ -4310,15 +5076,15 @@ class Database {
|
|
|
4310
5076
|
this.sqliteUtil.setForeignKeyConstraintsEnabled(this.database, false);
|
|
4311
5077
|
if (jsonData.tables && jsonData.tables.length > 0) {
|
|
4312
5078
|
// create the database schema
|
|
4313
|
-
changes = this.importFromJsonUtil.createDatabaseSchema(this
|
|
5079
|
+
changes = this.importFromJsonUtil.createDatabaseSchema(this, jsonData);
|
|
4314
5080
|
if (changes != -1) {
|
|
4315
5081
|
// create the tables data
|
|
4316
|
-
changes += this.importFromJsonUtil.createTablesData(this
|
|
5082
|
+
changes += this.importFromJsonUtil.createTablesData(this, jsonData);
|
|
4317
5083
|
}
|
|
4318
5084
|
}
|
|
4319
5085
|
if (jsonData.views && jsonData.views.length > 0) {
|
|
4320
5086
|
// create the views
|
|
4321
|
-
changes += this.importFromJsonUtil.createViews(this
|
|
5087
|
+
changes += this.importFromJsonUtil.createViews(this, jsonData);
|
|
4322
5088
|
}
|
|
4323
5089
|
// set Foreign Keys On
|
|
4324
5090
|
this.sqliteUtil.setForeignKeyConstraintsEnabled(this.database, true);
|
|
@@ -4391,9 +5157,9 @@ class CapacitorSQLite {
|
|
|
4391
5157
|
this.versionUpgrades = {};
|
|
4392
5158
|
this.databases = {};
|
|
4393
5159
|
this.fileUtil = new utilsFile_1.UtilsFile();
|
|
5160
|
+
this.sqliteUtil = new utilsSQLite_1.UtilsSQLite();
|
|
4394
5161
|
this.jsonUtil = new utilsJson_1.UtilsJson();
|
|
4395
5162
|
this.jsonEncryptUtil = new utilsJsonEncryption_1.UtilsJsonEncryption();
|
|
4396
|
-
this.sqliteUtil = new utilsSQLite_1.UtilsSQLite();
|
|
4397
5163
|
this.secretUtil = new utilsSecret_1.UtilsSecret();
|
|
4398
5164
|
this.globalUtil = new GlobalSQLite_1.GlobalSQLite();
|
|
4399
5165
|
this.isEncryption = this.fileUtil.getIsEncryption();
|
|
@@ -4488,6 +5254,78 @@ class CapacitorSQLite {
|
|
|
4488
5254
|
throw new Error(`Close: ${msg}`);
|
|
4489
5255
|
}
|
|
4490
5256
|
}
|
|
5257
|
+
async beginTransaction(options) {
|
|
5258
|
+
const dbName = this.getOptionValue(options, 'database');
|
|
5259
|
+
const connName = 'RW_' + dbName;
|
|
5260
|
+
const database = this.getDatabaseConnectionOrThrowError(connName);
|
|
5261
|
+
if (database.isDBOpen()) {
|
|
5262
|
+
try {
|
|
5263
|
+
const changes = database.dbBeginTransaction();
|
|
5264
|
+
return { changes: { changes: changes } };
|
|
5265
|
+
}
|
|
5266
|
+
catch (err) {
|
|
5267
|
+
throw new Error(`BeginTransaction: ${err}`);
|
|
5268
|
+
}
|
|
5269
|
+
}
|
|
5270
|
+
else {
|
|
5271
|
+
const msg = `Database ${dbName} not opened`;
|
|
5272
|
+
throw new Error(`BeginTransaction: ${msg}`);
|
|
5273
|
+
}
|
|
5274
|
+
}
|
|
5275
|
+
async commitTransaction(options) {
|
|
5276
|
+
const dbName = this.getOptionValue(options, 'database');
|
|
5277
|
+
const connName = 'RW_' + dbName;
|
|
5278
|
+
const database = this.getDatabaseConnectionOrThrowError(connName);
|
|
5279
|
+
if (database.isDBOpen()) {
|
|
5280
|
+
try {
|
|
5281
|
+
const changes = database.dbCommitTransaction();
|
|
5282
|
+
return { changes: { changes: changes } };
|
|
5283
|
+
}
|
|
5284
|
+
catch (err) {
|
|
5285
|
+
throw new Error(`CommitTransaction: ${err}`);
|
|
5286
|
+
}
|
|
5287
|
+
}
|
|
5288
|
+
else {
|
|
5289
|
+
const msg = `Database ${dbName} not opened`;
|
|
5290
|
+
throw new Error(`CommitTransaction: ${msg}`);
|
|
5291
|
+
}
|
|
5292
|
+
}
|
|
5293
|
+
async rollbackTransaction(options) {
|
|
5294
|
+
const dbName = this.getOptionValue(options, 'database');
|
|
5295
|
+
const connName = 'RW_' + dbName;
|
|
5296
|
+
const database = this.getDatabaseConnectionOrThrowError(connName);
|
|
5297
|
+
if (database.isDBOpen()) {
|
|
5298
|
+
try {
|
|
5299
|
+
const changes = database.dbRollbackTransaction();
|
|
5300
|
+
return { changes: { changes: changes } };
|
|
5301
|
+
}
|
|
5302
|
+
catch (err) {
|
|
5303
|
+
throw new Error(`RollbackTransaction: ${err}`);
|
|
5304
|
+
}
|
|
5305
|
+
}
|
|
5306
|
+
else {
|
|
5307
|
+
const msg = `Database ${dbName} not opened`;
|
|
5308
|
+
throw new Error(`RollbackTransaction: ${msg}`);
|
|
5309
|
+
}
|
|
5310
|
+
}
|
|
5311
|
+
async isTransactionActive(options) {
|
|
5312
|
+
const dbName = this.getOptionValue(options, 'database');
|
|
5313
|
+
const connName = 'RW_' + dbName;
|
|
5314
|
+
const database = this.getDatabaseConnectionOrThrowError(connName);
|
|
5315
|
+
if (database.isDBOpen()) {
|
|
5316
|
+
try {
|
|
5317
|
+
const ret = database.isTransActive();
|
|
5318
|
+
return { result: ret };
|
|
5319
|
+
}
|
|
5320
|
+
catch (err) {
|
|
5321
|
+
throw new Error(`IsTransactionActive: ${err}`);
|
|
5322
|
+
}
|
|
5323
|
+
}
|
|
5324
|
+
else {
|
|
5325
|
+
const msg = `Database ${dbName} not opened`;
|
|
5326
|
+
throw new Error(`IsTransactionActive: ${msg}`);
|
|
5327
|
+
}
|
|
5328
|
+
}
|
|
4491
5329
|
async getVersion(options) {
|
|
4492
5330
|
const dbName = this.getOptionValue(options, 'database');
|
|
4493
5331
|
const readonly = options.readonly ? options.readonly : false;
|
|
@@ -4535,6 +5373,7 @@ class CapacitorSQLite {
|
|
|
4535
5373
|
const statements = this.getOptionValue(options, 'statements');
|
|
4536
5374
|
const transaction = this.getOptionValue(options, 'transaction', true);
|
|
4537
5375
|
const readonly = options.readonly ? options.readonly : false;
|
|
5376
|
+
const isSQL92 = (Object.keys(options)).includes('isSQL92') ? options.isSQL92 : true;
|
|
4538
5377
|
const connName = 'RW_' + dbName;
|
|
4539
5378
|
const database = this.getDatabaseConnectionOrThrowError(connName);
|
|
4540
5379
|
if (database.isDBOpen()) {
|
|
@@ -4543,7 +5382,7 @@ class CapacitorSQLite {
|
|
|
4543
5382
|
throw new Error(`Execute: ${msg}`);
|
|
4544
5383
|
}
|
|
4545
5384
|
try {
|
|
4546
|
-
const executeResult = database.executeSQL(statements, transaction);
|
|
5385
|
+
const executeResult = database.executeSQL(statements, transaction, isSQL92);
|
|
4547
5386
|
if (executeResult < 0) {
|
|
4548
5387
|
throw new Error('Execute changes < 0');
|
|
4549
5388
|
}
|
|
@@ -4566,6 +5405,7 @@ class CapacitorSQLite {
|
|
|
4566
5405
|
const transaction = this.getOptionValue(options, 'transaction', true);
|
|
4567
5406
|
const readonly = options.readonly ? options.readonly : false;
|
|
4568
5407
|
const returnMode = options.returnMode ? options.returnMode : 'no';
|
|
5408
|
+
const isSQL92 = (Object.keys(options)).includes('isSQL92') ? options.isSQL92 : true;
|
|
4569
5409
|
const connName = 'RW_' + dbName;
|
|
4570
5410
|
const database = this.getDatabaseConnectionOrThrowError(connName);
|
|
4571
5411
|
for (const sStmt of setOfStatements) {
|
|
@@ -4579,7 +5419,7 @@ class CapacitorSQLite {
|
|
|
4579
5419
|
throw new Error(`ExecuteSet failed: ${msg}`);
|
|
4580
5420
|
}
|
|
4581
5421
|
try {
|
|
4582
|
-
const execSetResult = database.execSet(setOfStatements, transaction, returnMode);
|
|
5422
|
+
const execSetResult = database.execSet(setOfStatements, transaction, returnMode, isSQL92);
|
|
4583
5423
|
if (execSetResult.lastId < 0) {
|
|
4584
5424
|
throw new Error(`ExecuteSet failed changes <0`);
|
|
4585
5425
|
}
|
|
@@ -4603,6 +5443,7 @@ class CapacitorSQLite {
|
|
|
4603
5443
|
const transaction = this.getOptionValue(options, 'transaction', true);
|
|
4604
5444
|
const readonly = options.readonly ? options.readonly : false;
|
|
4605
5445
|
const returnMode = options.returnMode ? options.returnMode : 'no';
|
|
5446
|
+
const isSQL92 = (Object.keys(options)).includes('isSQL92') ? options.isSQL92 : true;
|
|
4606
5447
|
const connName = 'RW_' + dbName;
|
|
4607
5448
|
const database = this.getDatabaseConnectionOrThrowError(connName);
|
|
4608
5449
|
if (database.isDBOpen()) {
|
|
@@ -4611,7 +5452,7 @@ class CapacitorSQLite {
|
|
|
4611
5452
|
throw new Error(`Run failed: ${msg}`);
|
|
4612
5453
|
}
|
|
4613
5454
|
try {
|
|
4614
|
-
const runResult = database.runSQL(statement, values, transaction, returnMode);
|
|
5455
|
+
const runResult = database.runSQL(statement, values, transaction, returnMode, isSQL92);
|
|
4615
5456
|
return { changes: runResult };
|
|
4616
5457
|
}
|
|
4617
5458
|
catch (err) {
|
|
@@ -4631,11 +5472,12 @@ class CapacitorSQLite {
|
|
|
4631
5472
|
throw new Error('Query: Statement may not be an empty string.');
|
|
4632
5473
|
}
|
|
4633
5474
|
const readonly = options.readonly ? options.readonly : false;
|
|
5475
|
+
const isSQL92 = (Object.keys(options)).includes('isSQL92') ? options.isSQL92 : true;
|
|
4634
5476
|
const connName = readonly ? 'RO_' + dbName : 'RW_' + dbName;
|
|
4635
5477
|
const database = this.getDatabaseConnectionOrThrowError(connName);
|
|
4636
5478
|
if (database.isDBOpen()) {
|
|
4637
5479
|
try {
|
|
4638
|
-
const queryResult = database.selectSQL(statement, values);
|
|
5480
|
+
const queryResult = database.selectSQL(statement, values, isSQL92);
|
|
4639
5481
|
return { values: queryResult };
|
|
4640
5482
|
}
|
|
4641
5483
|
catch (err) {
|