@capacitor-community/sqlite 3.4.3-1 → 3.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -21
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/CapacitorSQLite.java +41 -2
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/CapacitorSQLitePlugin.java +26 -0
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/NotificationCenter.java +1 -1
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/Database.java +220 -7
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/ImportExportJson/ExportToJson.java +100 -3
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/ImportExportJson/ImportFromJson.java +37 -34
- package/dist/esm/definitions.d.ts +18 -4
- package/dist/esm/definitions.js +9 -17
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/web.d.ts +2 -1
- package/dist/esm/web.js +11 -0
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +22 -19
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +1035 -1032
- package/dist/plugin.js.map +1 -1
- package/electron/dist/plugin.js +662 -335
- package/electron/dist/plugin.js.map +1 -1
- package/ios/Plugin/CapacitorSQLite.swift +34 -1
- package/ios/Plugin/CapacitorSQLitePlugin.m +1 -0
- package/ios/Plugin/CapacitorSQLitePlugin.swift +25 -0
- package/ios/Plugin/Database.swift +29 -1
- package/ios/Plugin/Extensions/String.swift +8 -0
- package/ios/Plugin/ImportExportJson/ExportToJson.swift +154 -25
- package/ios/Plugin/ImportExportJson/ImportFromJson.swift +53 -27
- package/ios/Plugin/Utils/UtilsDrop.swift +2 -2
- package/ios/Plugin/Utils/UtilsSQLCipher.swift +277 -8
- package/ios/Plugin/Utils/UtilsUpgrade.swift +0 -1
- package/package.json +2 -2
package/electron/dist/plugin.js
CHANGED
|
@@ -325,12 +325,33 @@ class UtilsSQLite {
|
|
|
325
325
|
* @param mDB
|
|
326
326
|
* @param sql
|
|
327
327
|
*/
|
|
328
|
-
async execute(mDB, sql) {
|
|
328
|
+
async execute(mDB, sql, fromJson) {
|
|
329
329
|
let changes = -1;
|
|
330
330
|
let initChanges = -1;
|
|
331
331
|
try {
|
|
332
332
|
initChanges = await this.dbChanges(mDB);
|
|
333
|
-
|
|
333
|
+
let sqlStmt = sql;
|
|
334
|
+
// Check for DELETE FROM in sql string
|
|
335
|
+
if (!fromJson &&
|
|
336
|
+
sql.toLowerCase().includes('DELETE FROM'.toLowerCase())) {
|
|
337
|
+
sqlStmt = sql.replace(/\n/g, '');
|
|
338
|
+
const sqlStmts = sqlStmt.split(';');
|
|
339
|
+
const resArr = [];
|
|
340
|
+
for (const stmt of sqlStmts) {
|
|
341
|
+
const trimStmt = stmt.trim().substring(0, 11).toUpperCase();
|
|
342
|
+
if (trimStmt === 'DELETE FROM' &&
|
|
343
|
+
stmt.toLowerCase().includes('WHERE'.toLowerCase())) {
|
|
344
|
+
const whereStmt = `${stmt.trim()};`;
|
|
345
|
+
const rStmt = await this.deleteSQL(mDB, whereStmt, []);
|
|
346
|
+
resArr.push(rStmt);
|
|
347
|
+
}
|
|
348
|
+
else {
|
|
349
|
+
resArr.push(stmt);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
sqlStmt = resArr.join(';');
|
|
353
|
+
}
|
|
354
|
+
await this.execDB(mDB, sqlStmt);
|
|
334
355
|
changes = (await this.dbChanges(mDB)) - initChanges;
|
|
335
356
|
return Promise.resolve(changes);
|
|
336
357
|
}
|
|
@@ -358,7 +379,7 @@ class UtilsSQLite {
|
|
|
358
379
|
* @param db
|
|
359
380
|
* @param set
|
|
360
381
|
*/
|
|
361
|
-
async executeSet(db, set) {
|
|
382
|
+
async executeSet(db, set, fromJson) {
|
|
362
383
|
let lastId = -1;
|
|
363
384
|
for (let i = 0; i < set.length; i++) {
|
|
364
385
|
const statement = 'statement' in set[i] ? set[i].statement : null;
|
|
@@ -371,11 +392,13 @@ class UtilsSQLite {
|
|
|
371
392
|
try {
|
|
372
393
|
if (Array.isArray(values[0])) {
|
|
373
394
|
for (const val of values) {
|
|
374
|
-
|
|
395
|
+
const mVal = await this.replaceUndefinedByNull(val);
|
|
396
|
+
lastId = await this.prepareRun(db, statement, mVal, fromJson);
|
|
375
397
|
}
|
|
376
398
|
}
|
|
377
399
|
else {
|
|
378
|
-
|
|
400
|
+
const mVal = await this.replaceUndefinedByNull(values);
|
|
401
|
+
lastId = await this.prepareRun(db, statement, mVal, fromJson);
|
|
379
402
|
}
|
|
380
403
|
}
|
|
381
404
|
catch (err) {
|
|
@@ -390,24 +413,175 @@ class UtilsSQLite {
|
|
|
390
413
|
* @param statement
|
|
391
414
|
* @param values
|
|
392
415
|
*/
|
|
393
|
-
prepareRun(db, statement, values) {
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
416
|
+
async prepareRun(db, statement, values, fromJson) {
|
|
417
|
+
const stmtType = statement
|
|
418
|
+
.replace(/\n/g, '')
|
|
419
|
+
.trim()
|
|
420
|
+
.substring(0, 6)
|
|
421
|
+
.toUpperCase();
|
|
422
|
+
let sqlStmt = statement;
|
|
423
|
+
let lastId = -1;
|
|
424
|
+
try {
|
|
425
|
+
if (!fromJson && stmtType === 'DELETE') {
|
|
426
|
+
sqlStmt = await this.deleteSQL(db, statement, values);
|
|
427
|
+
}
|
|
428
|
+
let mVal = [];
|
|
429
|
+
if (values != null && values.length > 0) {
|
|
430
|
+
mVal = await this.replaceUndefinedByNull(values);
|
|
431
|
+
}
|
|
432
|
+
if (mVal.length > 0) {
|
|
433
|
+
await db.run(sqlStmt, mVal);
|
|
434
|
+
}
|
|
435
|
+
else {
|
|
436
|
+
await db.exec(sqlStmt);
|
|
437
|
+
}
|
|
438
|
+
lastId = await this.getLastId(db);
|
|
439
|
+
return Promise.resolve(lastId);
|
|
440
|
+
}
|
|
441
|
+
catch (err) {
|
|
442
|
+
return Promise.reject(`PrepareRun: ${err}`);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* replaceUndefinedByNull
|
|
447
|
+
* @param values
|
|
448
|
+
* @returns
|
|
449
|
+
*/
|
|
450
|
+
async replaceUndefinedByNull(values) {
|
|
451
|
+
const retValues = [];
|
|
452
|
+
if (values.length > 0) {
|
|
453
|
+
for (const val of values) {
|
|
454
|
+
let mVal = val;
|
|
455
|
+
if (typeof val === 'undefined')
|
|
456
|
+
mVal = null;
|
|
457
|
+
retValues.push(mVal);
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
return Promise.resolve(retValues);
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* deleteSQL
|
|
464
|
+
* @param db
|
|
465
|
+
* @param statement
|
|
466
|
+
* @param values
|
|
467
|
+
* @returns
|
|
468
|
+
*/
|
|
469
|
+
async deleteSQL(db, statement, values) {
|
|
470
|
+
let sqlStmt = statement;
|
|
471
|
+
try {
|
|
472
|
+
const isLast = await this.isLastModified(db, true);
|
|
473
|
+
if (isLast) {
|
|
474
|
+
// Replace DELETE by UPDATE and set sql_deleted to 1
|
|
475
|
+
const wIdx = statement.toUpperCase().indexOf('WHERE');
|
|
476
|
+
const preStmt = statement.substring(0, wIdx - 1);
|
|
477
|
+
const clauseStmt = statement.substring(wIdx, statement.length);
|
|
478
|
+
const tableName = preStmt
|
|
479
|
+
.substring('DELETE FROM'.length)
|
|
480
|
+
.trim();
|
|
481
|
+
sqlStmt = `UPDATE ${tableName} SET sql_deleted = 1 ${clauseStmt}`;
|
|
482
|
+
// Find REFERENCES if any and update the sql_deleted column
|
|
483
|
+
await this.findReferencesAndUpdate(db, tableName, clauseStmt, values);
|
|
484
|
+
}
|
|
485
|
+
return sqlStmt;
|
|
486
|
+
}
|
|
487
|
+
catch (err) {
|
|
488
|
+
return Promise.reject(`DeleteSL: ${err}`);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
/**
|
|
492
|
+
* findReferencesAndUpdate
|
|
493
|
+
* @param db
|
|
494
|
+
* @param tableName
|
|
495
|
+
* @param whereStmt
|
|
496
|
+
* @param values
|
|
497
|
+
* @returns
|
|
498
|
+
*/
|
|
499
|
+
async findReferencesAndUpdate(db, tableName, whereStmt, values) {
|
|
500
|
+
try {
|
|
501
|
+
const references = await this.getReferences(db, tableName);
|
|
502
|
+
for (const refe of references) {
|
|
503
|
+
// get the tableName of the reference
|
|
504
|
+
const refTable = await this.getReferenceTableName(refe.sql);
|
|
505
|
+
if (refTable.length <= 0) {
|
|
506
|
+
continue;
|
|
507
|
+
}
|
|
508
|
+
// get the columnName
|
|
509
|
+
const colName = await this.getReferenceColumnName(refe.sql);
|
|
510
|
+
if (colName.length <= 0) {
|
|
511
|
+
continue;
|
|
512
|
+
}
|
|
513
|
+
// update the where clause
|
|
514
|
+
const uWhereStmt = await this.updateWhere(whereStmt, colName);
|
|
515
|
+
if (uWhereStmt.length <= 0) {
|
|
516
|
+
continue;
|
|
517
|
+
}
|
|
518
|
+
//update sql_deleted for this reference
|
|
519
|
+
const stmt = `UPDATE ${refTable} SET sql_deleted = 1 ${uWhereStmt}`;
|
|
520
|
+
if (values != null && values.length > 0) {
|
|
521
|
+
const mVal = await this.replaceUndefinedByNull(values);
|
|
522
|
+
await db.run(stmt, mVal);
|
|
399
523
|
}
|
|
400
524
|
else {
|
|
401
|
-
|
|
402
|
-
lastId = await this.getLastId(db);
|
|
403
|
-
resolve(lastId);
|
|
404
|
-
}
|
|
405
|
-
catch (err) {
|
|
406
|
-
reject(`PrepareRun: lastId ${err}`);
|
|
407
|
-
}
|
|
525
|
+
await db.exec(stmt);
|
|
408
526
|
}
|
|
409
|
-
|
|
410
|
-
|
|
527
|
+
const lastId = await this.getLastId(db);
|
|
528
|
+
if (lastId == -1) {
|
|
529
|
+
const msg = `UPDATE sql_deleted failed for references table: ${refTable}`;
|
|
530
|
+
return Promise.reject(new Error(`findReferencesAndUpdate: ${msg}`));
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
return Promise.resolve();
|
|
534
|
+
}
|
|
535
|
+
catch (err) {
|
|
536
|
+
return Promise.reject(new Error(`findReferencesAndUpdate: ${err.message}`));
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
async getReferenceTableName(refValue) {
|
|
540
|
+
let tableName = '';
|
|
541
|
+
if (refValue.length > 0 &&
|
|
542
|
+
refValue.substring(0, 12).toLowerCase() === 'CREATE TABLE'.toLowerCase()) {
|
|
543
|
+
const oPar = refValue.indexOf('(');
|
|
544
|
+
tableName = refValue.substring(13, oPar).trim();
|
|
545
|
+
}
|
|
546
|
+
return tableName;
|
|
547
|
+
}
|
|
548
|
+
async getReferenceColumnName(refValue) {
|
|
549
|
+
let colName = '';
|
|
550
|
+
if (refValue.length > 0) {
|
|
551
|
+
const index = refValue
|
|
552
|
+
.toLowerCase()
|
|
553
|
+
.indexOf('FOREIGN KEY'.toLowerCase());
|
|
554
|
+
const stmt = refValue.substring(index + 12);
|
|
555
|
+
const oPar = stmt.indexOf('(');
|
|
556
|
+
const cPar = stmt.indexOf(')');
|
|
557
|
+
colName = stmt.substring(oPar + 1, cPar).trim();
|
|
558
|
+
}
|
|
559
|
+
return colName;
|
|
560
|
+
}
|
|
561
|
+
async updateWhere(whStmt, colName) {
|
|
562
|
+
let whereStmt = '';
|
|
563
|
+
if (whStmt.length > 0) {
|
|
564
|
+
const index = whStmt.toLowerCase().indexOf('WHERE'.toLowerCase());
|
|
565
|
+
const stmt = whStmt.substring(index + 6);
|
|
566
|
+
const fEqual = stmt.indexOf('=');
|
|
567
|
+
const whereColName = stmt.substring(0, fEqual).trim();
|
|
568
|
+
whereStmt = whStmt.replace(whereColName, colName);
|
|
569
|
+
}
|
|
570
|
+
return whereStmt;
|
|
571
|
+
}
|
|
572
|
+
async getReferences(db, tableName) {
|
|
573
|
+
const sqlStmt = 'SELECT sql FROM sqlite_master ' +
|
|
574
|
+
"WHERE sql LIKE('%REFERENCES%') AND " +
|
|
575
|
+
"sql LIKE('%" +
|
|
576
|
+
tableName +
|
|
577
|
+
"%') AND sql LIKE('%ON DELETE%');";
|
|
578
|
+
try {
|
|
579
|
+
const res = await this.queryAll(db, sqlStmt, []);
|
|
580
|
+
return Promise.resolve(res);
|
|
581
|
+
}
|
|
582
|
+
catch (err) {
|
|
583
|
+
return Promise.reject(new Error(`getReferences: ${err.message}`));
|
|
584
|
+
}
|
|
411
585
|
}
|
|
412
586
|
/**
|
|
413
587
|
* QueryAll
|
|
@@ -432,20 +606,6 @@ class UtilsSQLite {
|
|
|
432
606
|
});
|
|
433
607
|
});
|
|
434
608
|
}
|
|
435
|
-
}
|
|
436
|
-
utilsSQLite.UtilsSQLite = UtilsSQLite;
|
|
437
|
-
|
|
438
|
-
var utilsJson = {};
|
|
439
|
-
|
|
440
|
-
var utilsDrop = {};
|
|
441
|
-
|
|
442
|
-
Object.defineProperty(utilsDrop, "__esModule", { value: true });
|
|
443
|
-
utilsDrop.UtilsDrop = void 0;
|
|
444
|
-
const utilsSQLite_1$5 = utilsSQLite;
|
|
445
|
-
class UtilsDrop {
|
|
446
|
-
constructor() {
|
|
447
|
-
this._uSQLite = new utilsSQLite_1$5.UtilsSQLite();
|
|
448
|
-
}
|
|
449
609
|
/**
|
|
450
610
|
* GetTablesNames
|
|
451
611
|
* @param mDb
|
|
@@ -458,7 +618,7 @@ class UtilsDrop {
|
|
|
458
618
|
sql += 'ORDER BY rootpage DESC;';
|
|
459
619
|
const retArr = [];
|
|
460
620
|
try {
|
|
461
|
-
const retQuery = await this.
|
|
621
|
+
const retQuery = await this.queryAll(mDb, sql, []);
|
|
462
622
|
for (const query of retQuery) {
|
|
463
623
|
retArr.push(query.name);
|
|
464
624
|
}
|
|
@@ -478,7 +638,7 @@ class UtilsDrop {
|
|
|
478
638
|
sql += 'ORDER BY rootpage DESC;';
|
|
479
639
|
const retArr = [];
|
|
480
640
|
try {
|
|
481
|
-
const retQuery = await this.
|
|
641
|
+
const retQuery = await this.queryAll(mDb, sql, []);
|
|
482
642
|
for (const query of retQuery) {
|
|
483
643
|
retArr.push(query.name);
|
|
484
644
|
}
|
|
@@ -489,137 +649,63 @@ class UtilsDrop {
|
|
|
489
649
|
}
|
|
490
650
|
}
|
|
491
651
|
/**
|
|
492
|
-
*
|
|
652
|
+
* isLastModified
|
|
493
653
|
* @param db
|
|
494
|
-
* @param
|
|
654
|
+
* @param isOpen
|
|
495
655
|
*/
|
|
496
|
-
async
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
switch (type) {
|
|
500
|
-
case 'index':
|
|
501
|
-
msg = 'DropIndexes';
|
|
502
|
-
break;
|
|
503
|
-
case 'trigger':
|
|
504
|
-
msg = 'DropTriggers';
|
|
505
|
-
break;
|
|
506
|
-
case 'table':
|
|
507
|
-
msg = 'DropTables';
|
|
508
|
-
stmt1 += ` AND name NOT IN ('sync_table')`;
|
|
509
|
-
break;
|
|
510
|
-
case 'view':
|
|
511
|
-
msg = 'DropViews';
|
|
512
|
-
break;
|
|
513
|
-
default:
|
|
514
|
-
return Promise.reject(`DropElements: ${type} ` + 'not found');
|
|
656
|
+
async isLastModified(db, isOpen) {
|
|
657
|
+
if (!isOpen) {
|
|
658
|
+
return Promise.reject('isLastModified: database not opened');
|
|
515
659
|
}
|
|
516
|
-
// get the element's names
|
|
517
|
-
let stmt = 'SELECT name FROM sqlite_master WHERE ';
|
|
518
|
-
stmt += `type = '${type}' ${stmt1};`;
|
|
519
660
|
try {
|
|
520
|
-
const
|
|
521
|
-
|
|
522
|
-
const
|
|
523
|
-
const
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
stmt += `${elem.name};`;
|
|
527
|
-
statements.push(stmt);
|
|
528
|
-
}
|
|
529
|
-
for (const stmt of statements) {
|
|
530
|
-
const lastId = await this._uSQLite.prepareRun(db, stmt, []);
|
|
531
|
-
if (lastId < 0) {
|
|
532
|
-
return Promise.reject(`${msg}: lastId < 0`);
|
|
533
|
-
}
|
|
661
|
+
const tableList = await this.getTablesNames(db);
|
|
662
|
+
for (const table of tableList) {
|
|
663
|
+
const tableNamesTypes = await this.getTableColumnNamesTypes(db, table);
|
|
664
|
+
const tableColumnNames = tableNamesTypes.names;
|
|
665
|
+
if (tableColumnNames.includes('last_modified')) {
|
|
666
|
+
return Promise.resolve(true);
|
|
534
667
|
}
|
|
535
668
|
}
|
|
536
|
-
return Promise.resolve();
|
|
537
669
|
}
|
|
538
670
|
catch (err) {
|
|
539
|
-
return Promise.reject(
|
|
540
|
-
}
|
|
541
|
-
}
|
|
542
|
-
/**
|
|
543
|
-
* DropAll
|
|
544
|
-
* Drop all database's elements
|
|
545
|
-
* @param db
|
|
546
|
-
*/
|
|
547
|
-
async dropAll(db) {
|
|
548
|
-
try {
|
|
549
|
-
// drop tables
|
|
550
|
-
await this.dropElements(db, 'table');
|
|
551
|
-
// drop indexes
|
|
552
|
-
await this.dropElements(db, 'index');
|
|
553
|
-
// drop triggers
|
|
554
|
-
await this.dropElements(db, 'trigger');
|
|
555
|
-
// drop views
|
|
556
|
-
await this.dropElements(db, 'view');
|
|
557
|
-
// vacuum the database
|
|
558
|
-
await this._uSQLite.prepareRun(db, 'VACUUM;', []);
|
|
559
|
-
return Promise.resolve();
|
|
560
|
-
}
|
|
561
|
-
catch (err) {
|
|
562
|
-
return Promise.reject(`DropAll: ${err}`);
|
|
671
|
+
return Promise.reject(`isLastModified: ${err}`);
|
|
563
672
|
}
|
|
564
673
|
}
|
|
565
674
|
/**
|
|
566
|
-
*
|
|
567
|
-
* @param
|
|
568
|
-
* @param
|
|
675
|
+
* GetTableColumnNamesTypes
|
|
676
|
+
* @param mDB
|
|
677
|
+
* @param tableName
|
|
569
678
|
*/
|
|
570
|
-
async
|
|
571
|
-
|
|
572
|
-
const
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
stmt += `_temp_${tTable};`;
|
|
576
|
-
statements.push(stmt);
|
|
577
|
-
}
|
|
679
|
+
async getTableColumnNamesTypes(mDB, tableName) {
|
|
680
|
+
let resQuery = [];
|
|
681
|
+
const retNames = [];
|
|
682
|
+
const retTypes = [];
|
|
683
|
+
const query = `PRAGMA table_info('${tableName}');`;
|
|
578
684
|
try {
|
|
579
|
-
|
|
580
|
-
if (
|
|
581
|
-
|
|
685
|
+
resQuery = await this.queryAll(mDB, query, []);
|
|
686
|
+
if (resQuery.length > 0) {
|
|
687
|
+
for (const query of resQuery) {
|
|
688
|
+
retNames.push(query.name);
|
|
689
|
+
retTypes.push(query.type);
|
|
690
|
+
}
|
|
582
691
|
}
|
|
583
|
-
return Promise.resolve();
|
|
692
|
+
return Promise.resolve({ names: retNames, types: retTypes });
|
|
584
693
|
}
|
|
585
694
|
catch (err) {
|
|
586
|
-
return Promise.reject(
|
|
695
|
+
return Promise.reject('GetTableColumnNamesTypes: ' + `${err}`);
|
|
587
696
|
}
|
|
588
697
|
}
|
|
589
698
|
}
|
|
590
|
-
|
|
699
|
+
utilsSQLite.UtilsSQLite = UtilsSQLite;
|
|
700
|
+
|
|
701
|
+
var utilsJson = {};
|
|
591
702
|
|
|
592
703
|
Object.defineProperty(utilsJson, "__esModule", { value: true });
|
|
593
704
|
utilsJson.UtilsJson = void 0;
|
|
594
|
-
const
|
|
595
|
-
const utilsSQLite_1$4 = utilsSQLite;
|
|
705
|
+
const utilsSQLite_1$5 = utilsSQLite;
|
|
596
706
|
class UtilsJson {
|
|
597
707
|
constructor() {
|
|
598
|
-
this.
|
|
599
|
-
this._uDrop = new utilsDrop_1$3.UtilsDrop();
|
|
600
|
-
}
|
|
601
|
-
/**
|
|
602
|
-
* isLastModified
|
|
603
|
-
* @param db
|
|
604
|
-
* @param isOpen
|
|
605
|
-
*/
|
|
606
|
-
async isLastModified(db, isOpen) {
|
|
607
|
-
if (!isOpen) {
|
|
608
|
-
return Promise.reject('isLastModified: database not opened');
|
|
609
|
-
}
|
|
610
|
-
try {
|
|
611
|
-
const tableList = await this._uDrop.getTablesNames(db);
|
|
612
|
-
for (const table of tableList) {
|
|
613
|
-
const tableNamesTypes = await this.getTableColumnNamesTypes(db, table);
|
|
614
|
-
const tableColumnNames = tableNamesTypes.names;
|
|
615
|
-
if (tableColumnNames.includes('last_modified')) {
|
|
616
|
-
return Promise.resolve(true);
|
|
617
|
-
}
|
|
618
|
-
}
|
|
619
|
-
}
|
|
620
|
-
catch (err) {
|
|
621
|
-
return Promise.reject(`isLastModified: ${err}`);
|
|
622
|
-
}
|
|
708
|
+
this.sqliteUtil = new utilsSQLite_1$5.UtilsSQLite();
|
|
623
709
|
}
|
|
624
710
|
/**
|
|
625
711
|
* IsTableExists
|
|
@@ -689,7 +775,7 @@ class UtilsJson {
|
|
|
689
775
|
let changes = 0;
|
|
690
776
|
try {
|
|
691
777
|
// start a transaction
|
|
692
|
-
await this.
|
|
778
|
+
await this.sqliteUtil.beginTransaction(mDB, true);
|
|
693
779
|
}
|
|
694
780
|
catch (err) {
|
|
695
781
|
return Promise.reject(`CreateDatabaseSchema: ${err}`);
|
|
@@ -698,10 +784,10 @@ class UtilsJson {
|
|
|
698
784
|
if (stmts.length > 0) {
|
|
699
785
|
const schemaStmt = stmts.join('\n');
|
|
700
786
|
try {
|
|
701
|
-
changes = await this.
|
|
787
|
+
changes = await this.sqliteUtil.execute(mDB, schemaStmt, true);
|
|
702
788
|
if (changes < 0) {
|
|
703
789
|
try {
|
|
704
|
-
await this.
|
|
790
|
+
await this.sqliteUtil.rollbackTransaction(mDB, true);
|
|
705
791
|
}
|
|
706
792
|
catch (err) {
|
|
707
793
|
return Promise.reject('CreateSchema: changes < 0 ' + `${err}`);
|
|
@@ -711,7 +797,7 @@ class UtilsJson {
|
|
|
711
797
|
catch (err) {
|
|
712
798
|
const msg = err;
|
|
713
799
|
try {
|
|
714
|
-
await this.
|
|
800
|
+
await this.sqliteUtil.rollbackTransaction(mDB, true);
|
|
715
801
|
return Promise.reject(`CreateSchema: ${msg}`);
|
|
716
802
|
}
|
|
717
803
|
catch (err) {
|
|
@@ -720,7 +806,7 @@ class UtilsJson {
|
|
|
720
806
|
}
|
|
721
807
|
}
|
|
722
808
|
try {
|
|
723
|
-
await this.
|
|
809
|
+
await this.sqliteUtil.commitTransaction(mDB, true);
|
|
724
810
|
return Promise.resolve(changes);
|
|
725
811
|
}
|
|
726
812
|
catch (err) {
|
|
@@ -829,7 +915,7 @@ class UtilsJson {
|
|
|
829
915
|
return Promise.reject('CreateDataTable: Table ' + `${table.name} does not exist`);
|
|
830
916
|
}
|
|
831
917
|
// Get the column names and types
|
|
832
|
-
const tableNamesTypes = await this.getTableColumnNamesTypes(mDB, table.name);
|
|
918
|
+
const tableNamesTypes = await this.sqliteUtil.getTableColumnNamesTypes(mDB, table.name);
|
|
833
919
|
const tableColumnTypes = tableNamesTypes.types;
|
|
834
920
|
const tableColumnNames = tableNamesTypes.names;
|
|
835
921
|
if (tableColumnTypes.length === 0) {
|
|
@@ -837,54 +923,15 @@ class UtilsJson {
|
|
|
837
923
|
}
|
|
838
924
|
// Loop on Table Values
|
|
839
925
|
for (let j = 0; j < table.values.length; j++) {
|
|
840
|
-
|
|
841
|
-
if (table.values[j].length != tableColumnTypes.length) {
|
|
842
|
-
return Promise.reject(`CreateDataTable: Table ${table.name} ` +
|
|
843
|
-
`values row ${j} not correct length`);
|
|
844
|
-
}
|
|
845
|
-
// Check the column's type before proceeding
|
|
846
|
-
// remove type checking for allowing RDBMS Types
|
|
847
|
-
/* const isColumnTypes: boolean = await this.checkColumnTypes(
|
|
848
|
-
tableColumnTypes,
|
|
849
|
-
table.values[j],
|
|
850
|
-
);
|
|
851
|
-
if (!isColumnTypes) {
|
|
852
|
-
return Promise.reject(
|
|
853
|
-
new Error(
|
|
854
|
-
`CreateDataTable: Table ${table.name} ` +
|
|
855
|
-
`values row ${j} not correct types`,
|
|
856
|
-
),
|
|
857
|
-
);
|
|
858
|
-
}
|
|
859
|
-
*/
|
|
860
|
-
const retisIdExists = await this.isIdExists(mDB, table.name, tableColumnNames[0], table.values[j][0]);
|
|
861
|
-
let stmt;
|
|
926
|
+
let row = table.values[j];
|
|
862
927
|
let isRun = true;
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
const nameString = tableColumnNames.join();
|
|
866
|
-
const questionMarkString = await this.createQuestionMarkString(tableColumnNames.length);
|
|
867
|
-
stmt = `INSERT INTO ${table.name} (${nameString}) VALUES (`;
|
|
868
|
-
stmt += `${questionMarkString});`;
|
|
869
|
-
}
|
|
870
|
-
else {
|
|
871
|
-
// Update
|
|
872
|
-
const setString = await this.setNameForUpdate(tableColumnNames);
|
|
873
|
-
if (setString.length === 0) {
|
|
874
|
-
return Promise.reject(`CreateDataTable: Table ${table.name} ` +
|
|
875
|
-
`values row ${j} not set to String`);
|
|
876
|
-
}
|
|
877
|
-
stmt = `UPDATE ${table.name} SET ${setString} WHERE `;
|
|
878
|
-
if (typeof table.values[j][0] == 'string') {
|
|
879
|
-
stmt += `${tableColumnNames[0]} = '${table.values[j][0]}';`;
|
|
880
|
-
}
|
|
881
|
-
else {
|
|
882
|
-
stmt += `${tableColumnNames[0]} = ${table.values[j][0]};`;
|
|
883
|
-
}
|
|
884
|
-
isRun = await this.checkUpdate(mDB, table.values[j], table.name, tableColumnNames);
|
|
885
|
-
}
|
|
928
|
+
const stmt = await this.createRowStatement(mDB, tableColumnNames, row, j, table.name, mode);
|
|
929
|
+
isRun = await this.checkUpdate(mDB, stmt, row, table.name, tableColumnNames);
|
|
886
930
|
if (isRun) {
|
|
887
|
-
|
|
931
|
+
if (stmt.substring(0, 6).toUpperCase() === 'DELETE') {
|
|
932
|
+
row = [];
|
|
933
|
+
}
|
|
934
|
+
lastId = await this.sqliteUtil.prepareRun(mDB, stmt, row, true);
|
|
888
935
|
if (lastId < 0) {
|
|
889
936
|
return Promise.reject('CreateDataTable: lastId < 0');
|
|
890
937
|
}
|
|
@@ -900,44 +947,117 @@ class UtilsJson {
|
|
|
900
947
|
}
|
|
901
948
|
}
|
|
902
949
|
/**
|
|
903
|
-
*
|
|
904
|
-
* @param
|
|
905
|
-
* @param values
|
|
906
|
-
* @param tbName
|
|
950
|
+
* CreateRowStatement
|
|
951
|
+
* @param mDB
|
|
907
952
|
* @param tColNames
|
|
953
|
+
* @param row
|
|
954
|
+
* @param j
|
|
955
|
+
* @param tableName
|
|
956
|
+
* @param mode
|
|
908
957
|
* @returns
|
|
909
958
|
*/
|
|
910
|
-
async
|
|
959
|
+
async createRowStatement(mDB, tColNames, row, j, tableName, mode) {
|
|
960
|
+
// Check the row number of columns
|
|
961
|
+
if (row.length != tColNames.length ||
|
|
962
|
+
row.length === 0 ||
|
|
963
|
+
tColNames.length === 0) {
|
|
964
|
+
return Promise.reject(new Error(`CreateRowStatement: Table ${tableName} ` +
|
|
965
|
+
`values row ${j} not correct length`));
|
|
966
|
+
}
|
|
911
967
|
try {
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
968
|
+
const retisIdExists = await this.isIdExists(mDB, tableName, tColNames[0], row[0]);
|
|
969
|
+
let stmt;
|
|
970
|
+
if (mode === 'full' || (mode === 'partial' && !retisIdExists)) {
|
|
971
|
+
// Insert
|
|
972
|
+
const nameString = tColNames.join();
|
|
973
|
+
const questionMarkString = await this.createQuestionMarkString(tColNames.length);
|
|
974
|
+
stmt = `INSERT INTO ${tableName} (${nameString}) VALUES (`;
|
|
975
|
+
stmt += `${questionMarkString});`;
|
|
915
976
|
}
|
|
916
977
|
else {
|
|
917
|
-
|
|
978
|
+
// Update or Delete
|
|
979
|
+
let isUpdate = true;
|
|
980
|
+
const isColDeleted = (element) => element === `sql_deleted`;
|
|
981
|
+
const idxDelete = tColNames.findIndex(isColDeleted);
|
|
982
|
+
if (idxDelete >= 0) {
|
|
983
|
+
if (row[idxDelete] === 1) {
|
|
984
|
+
isUpdate = false;
|
|
985
|
+
stmt = `DELETE FROM ${tableName} WHERE `;
|
|
986
|
+
if (typeof row[0] == 'string') {
|
|
987
|
+
stmt += `${tColNames[0]} = '${row[0]}';`;
|
|
988
|
+
}
|
|
989
|
+
else {
|
|
990
|
+
stmt += `${tColNames[0]} = ${row[0]};`;
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
if (isUpdate) {
|
|
995
|
+
// Update
|
|
996
|
+
const setString = await this.setNameForUpdate(tColNames);
|
|
997
|
+
if (setString.length === 0) {
|
|
998
|
+
return Promise.reject(new Error(`CreateRowStatement: Table ${tableName} ` +
|
|
999
|
+
`values row ${j} not set to String`));
|
|
1000
|
+
}
|
|
1001
|
+
stmt = `UPDATE ${tableName} SET ${setString} WHERE `;
|
|
1002
|
+
if (typeof row[0] == 'string') {
|
|
1003
|
+
stmt += `${tColNames[0]} = '${row[0]}';`;
|
|
1004
|
+
}
|
|
1005
|
+
else {
|
|
1006
|
+
stmt += `${tColNames[0]} = ${row[0]};`;
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
918
1009
|
}
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
1010
|
+
return Promise.resolve(stmt);
|
|
1011
|
+
}
|
|
1012
|
+
catch (err) {
|
|
1013
|
+
return Promise.reject(new Error(`CreateRowStatement: ${err.message}`));
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
/**
|
|
1017
|
+
*
|
|
1018
|
+
* @param db
|
|
1019
|
+
* @param values
|
|
1020
|
+
* @param tbName
|
|
1021
|
+
* @param tColNames
|
|
1022
|
+
* @returns
|
|
1023
|
+
*/
|
|
1024
|
+
async checkUpdate(db, stmt, values, tbName, tColNames) {
|
|
1025
|
+
const isRun = true;
|
|
1026
|
+
if (stmt.substring(0, 6) === 'UPDATE') {
|
|
1027
|
+
try {
|
|
1028
|
+
let query = `SELECT * FROM ${tbName} WHERE `;
|
|
1029
|
+
if (typeof values[0] == 'string') {
|
|
1030
|
+
query += `${tColNames[0]} = '${values[0]}';`;
|
|
1031
|
+
}
|
|
1032
|
+
else {
|
|
1033
|
+
query += `${tColNames[0]} = ${values[0]};`;
|
|
1034
|
+
}
|
|
1035
|
+
const resQuery = await this.getValues(db, query, tbName);
|
|
1036
|
+
let resValues = [];
|
|
1037
|
+
if (resQuery.length > 0) {
|
|
1038
|
+
resValues = resQuery[0];
|
|
1039
|
+
}
|
|
1040
|
+
if (values.length > 0 &&
|
|
1041
|
+
resValues.length > 0 &&
|
|
1042
|
+
values.length === resValues.length) {
|
|
1043
|
+
for (let i = 0; i < values.length; i++) {
|
|
1044
|
+
if (values[i] !== resValues[i]) {
|
|
1045
|
+
return Promise.resolve(true);
|
|
1046
|
+
}
|
|
930
1047
|
}
|
|
1048
|
+
return Promise.resolve(false);
|
|
1049
|
+
}
|
|
1050
|
+
else {
|
|
1051
|
+
const msg = 'Both arrays not the same length';
|
|
1052
|
+
return Promise.reject(new Error(`CheckUpdate: ${msg}`));
|
|
931
1053
|
}
|
|
932
|
-
return Promise.resolve(false);
|
|
933
1054
|
}
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
return Promise.reject(new Error(`CheckUpdate: ${msg}`));
|
|
1055
|
+
catch (err) {
|
|
1056
|
+
return Promise.reject(new Error(`CheckUpdate: ${err.message}`));
|
|
937
1057
|
}
|
|
938
1058
|
}
|
|
939
|
-
|
|
940
|
-
return Promise.
|
|
1059
|
+
else {
|
|
1060
|
+
return Promise.resolve(isRun);
|
|
941
1061
|
}
|
|
942
1062
|
}
|
|
943
1063
|
/**
|
|
@@ -950,7 +1070,7 @@ class UtilsJson {
|
|
|
950
1070
|
const values = [];
|
|
951
1071
|
try {
|
|
952
1072
|
// get table column names and types
|
|
953
|
-
const tableNamesTypes = await this.getTableColumnNamesTypes(mDb, tableName);
|
|
1073
|
+
const tableNamesTypes = await this.sqliteUtil.getTableColumnNamesTypes(mDb, tableName);
|
|
954
1074
|
let rowNames = [];
|
|
955
1075
|
if (Object.keys(tableNamesTypes).includes('names')) {
|
|
956
1076
|
rowNames = tableNamesTypes.names;
|
|
@@ -958,7 +1078,7 @@ class UtilsJson {
|
|
|
958
1078
|
else {
|
|
959
1079
|
return Promise.reject(`GetValues: Table ${tableName} no names`);
|
|
960
1080
|
}
|
|
961
|
-
const retValues = await this.
|
|
1081
|
+
const retValues = await this.sqliteUtil.queryAll(mDb, query, []);
|
|
962
1082
|
for (const rValue of retValues) {
|
|
963
1083
|
const row = [];
|
|
964
1084
|
for (const rName of rowNames) {
|
|
@@ -977,30 +1097,6 @@ class UtilsJson {
|
|
|
977
1097
|
return Promise.reject(`GetValues: ${err}`);
|
|
978
1098
|
}
|
|
979
1099
|
}
|
|
980
|
-
/**
|
|
981
|
-
* GetTableColumnNamesTypes
|
|
982
|
-
* @param mDB
|
|
983
|
-
* @param tableName
|
|
984
|
-
*/
|
|
985
|
-
async getTableColumnNamesTypes(mDB, tableName) {
|
|
986
|
-
let resQuery = [];
|
|
987
|
-
const retNames = [];
|
|
988
|
-
const retTypes = [];
|
|
989
|
-
const query = `PRAGMA table_info('${tableName}');`;
|
|
990
|
-
try {
|
|
991
|
-
resQuery = await this._uSQLite.queryAll(mDB, query, []);
|
|
992
|
-
if (resQuery.length > 0) {
|
|
993
|
-
for (const query of resQuery) {
|
|
994
|
-
retNames.push(query.name);
|
|
995
|
-
retTypes.push(query.type);
|
|
996
|
-
}
|
|
997
|
-
}
|
|
998
|
-
return Promise.resolve({ names: retNames, types: retTypes });
|
|
999
|
-
}
|
|
1000
|
-
catch (err) {
|
|
1001
|
-
return Promise.reject('GetTableColumnNamesTypes: ' + `${err}`);
|
|
1002
|
-
}
|
|
1003
|
-
}
|
|
1004
1100
|
/**
|
|
1005
1101
|
* CheckColumnTypes
|
|
1006
1102
|
* @param tableTypes
|
|
@@ -1060,7 +1156,7 @@ class UtilsJson {
|
|
|
1060
1156
|
if (typeof key === 'string')
|
|
1061
1157
|
query += `'${key}';`;
|
|
1062
1158
|
try {
|
|
1063
|
-
const resQuery = await this.
|
|
1159
|
+
const resQuery = await this.sqliteUtil.queryAll(db, query, []);
|
|
1064
1160
|
if (resQuery.length === 1)
|
|
1065
1161
|
ret = true;
|
|
1066
1162
|
return Promise.resolve(ret);
|
|
@@ -1426,7 +1522,7 @@ class UtilsJson {
|
|
|
1426
1522
|
async createView(mDB, view) {
|
|
1427
1523
|
const stmt = `CREATE VIEW IF NOT EXISTS ${view.name} AS ${view.value};`;
|
|
1428
1524
|
try {
|
|
1429
|
-
const changes = await this.
|
|
1525
|
+
const changes = await this.sqliteUtil.execute(mDB, stmt, true);
|
|
1430
1526
|
if (changes < 0) {
|
|
1431
1527
|
return Promise.reject(`CreateView: ${view.name} failed`);
|
|
1432
1528
|
}
|
|
@@ -1441,12 +1537,12 @@ utilsJson.UtilsJson = UtilsJson;
|
|
|
1441
1537
|
|
|
1442
1538
|
Object.defineProperty(exportToJson, "__esModule", { value: true });
|
|
1443
1539
|
exportToJson.ExportToJson = void 0;
|
|
1444
|
-
const utilsSQLite_1$
|
|
1540
|
+
const utilsSQLite_1$4 = utilsSQLite;
|
|
1445
1541
|
const utilsJson_1$4 = utilsJson;
|
|
1446
1542
|
class ExportToJson {
|
|
1447
1543
|
constructor() {
|
|
1448
|
-
this.
|
|
1449
|
-
this.
|
|
1544
|
+
this.sqliteUtil = new utilsSQLite_1$4.UtilsSQLite();
|
|
1545
|
+
this.jsonUtil = new utilsJson_1$4.UtilsJson();
|
|
1450
1546
|
}
|
|
1451
1547
|
/**
|
|
1452
1548
|
* CreateExportObject
|
|
@@ -1467,7 +1563,7 @@ class ExportToJson {
|
|
|
1467
1563
|
return Promise.reject("createExportObject: table's names failed");
|
|
1468
1564
|
}
|
|
1469
1565
|
else {
|
|
1470
|
-
const isTable = await this.
|
|
1566
|
+
const isTable = await this.jsonUtil.isTableExists(mDB, true, 'sync_table');
|
|
1471
1567
|
if (!isTable && sqlObj.mode === 'partial') {
|
|
1472
1568
|
return Promise.reject('No sync_table available');
|
|
1473
1569
|
}
|
|
@@ -1517,13 +1613,102 @@ class ExportToJson {
|
|
|
1517
1613
|
sql += "AND name NOT LIKE 'sqlite_%';";
|
|
1518
1614
|
let retQuery = [];
|
|
1519
1615
|
try {
|
|
1520
|
-
retQuery = await this.
|
|
1616
|
+
retQuery = await this.sqliteUtil.queryAll(mDb, sql, []);
|
|
1521
1617
|
return Promise.resolve(retQuery);
|
|
1522
1618
|
}
|
|
1523
1619
|
catch (err) {
|
|
1524
1620
|
return Promise.reject(`getTablesNameSQL: ${err}`);
|
|
1525
1621
|
}
|
|
1526
1622
|
}
|
|
1623
|
+
async getLastExportDate(mDb) {
|
|
1624
|
+
return new Promise((resolve, reject) => {
|
|
1625
|
+
let retDate = -1;
|
|
1626
|
+
// get the last sync date
|
|
1627
|
+
const stmt = `SELECT sync_date FROM sync_table WHERE id = 2;`;
|
|
1628
|
+
mDb.get(stmt, [], (err, row) => {
|
|
1629
|
+
// process the row here
|
|
1630
|
+
if (err) {
|
|
1631
|
+
reject(`getLastExportDate: ${err.message}`);
|
|
1632
|
+
}
|
|
1633
|
+
else {
|
|
1634
|
+
if (row != null) {
|
|
1635
|
+
const key = Object.keys(row)[0];
|
|
1636
|
+
retDate = row[key];
|
|
1637
|
+
}
|
|
1638
|
+
resolve(retDate);
|
|
1639
|
+
}
|
|
1640
|
+
});
|
|
1641
|
+
});
|
|
1642
|
+
}
|
|
1643
|
+
/**
|
|
1644
|
+
* SetLastExportDate
|
|
1645
|
+
* @param mDb
|
|
1646
|
+
* @param lastExportedDate
|
|
1647
|
+
* @returns
|
|
1648
|
+
*/
|
|
1649
|
+
async setLastExportDate(mDb, lastExportedDate) {
|
|
1650
|
+
try {
|
|
1651
|
+
const isTable = await this.jsonUtil.isTableExists(mDb, true, 'sync_table');
|
|
1652
|
+
if (!isTable) {
|
|
1653
|
+
return Promise.reject(new Error('setLastExportDate: No sync_table available'));
|
|
1654
|
+
}
|
|
1655
|
+
const sDate = Math.round(new Date(lastExportedDate).getTime() / 1000);
|
|
1656
|
+
let stmt = '';
|
|
1657
|
+
if ((await this.getLastExportDate(mDb)) > 0) {
|
|
1658
|
+
stmt = `UPDATE sync_table SET sync_date = ${sDate} WHERE id = 2;`;
|
|
1659
|
+
}
|
|
1660
|
+
else {
|
|
1661
|
+
stmt = `INSERT INTO sync_table (sync_date) VALUES (${sDate});`;
|
|
1662
|
+
}
|
|
1663
|
+
const changes = await this.sqliteUtil.execute(mDb, stmt, false);
|
|
1664
|
+
if (changes < 0) {
|
|
1665
|
+
return { result: false, message: 'setLastExportDate failed' };
|
|
1666
|
+
}
|
|
1667
|
+
else {
|
|
1668
|
+
return { result: true };
|
|
1669
|
+
}
|
|
1670
|
+
}
|
|
1671
|
+
catch (err) {
|
|
1672
|
+
return {
|
|
1673
|
+
result: false,
|
|
1674
|
+
message: `setLastExportDate failed: ${err.message}`,
|
|
1675
|
+
};
|
|
1676
|
+
}
|
|
1677
|
+
}
|
|
1678
|
+
async delExportedRows(mDb) {
|
|
1679
|
+
let lastExportDate;
|
|
1680
|
+
try {
|
|
1681
|
+
// check if synchronization table exists
|
|
1682
|
+
const isTable = await this.jsonUtil.isTableExists(mDb, true, 'sync_table');
|
|
1683
|
+
if (!isTable) {
|
|
1684
|
+
return Promise.reject('DelExportedRows: No sync_table available');
|
|
1685
|
+
}
|
|
1686
|
+
// get the last export date
|
|
1687
|
+
lastExportDate = await this.getLastExportDate(mDb);
|
|
1688
|
+
if (lastExportDate < 0) {
|
|
1689
|
+
return Promise.reject('DelExportedRows: no last exported date available');
|
|
1690
|
+
}
|
|
1691
|
+
// get the table' name list
|
|
1692
|
+
const resTables = await this.sqliteUtil.getTablesNames(mDb);
|
|
1693
|
+
if (resTables.length === 0) {
|
|
1694
|
+
return Promise.reject("DelExportedRows: No table's names returned");
|
|
1695
|
+
}
|
|
1696
|
+
// Loop through the tables
|
|
1697
|
+
for (const table of resTables) {
|
|
1698
|
+
let lastId = -1;
|
|
1699
|
+
// define the delete statement
|
|
1700
|
+
const delStmt = `DELETE FROM ${table}
|
|
1701
|
+
WHERE sql_deleted = 1 AND last_modified < ${lastExportDate};`;
|
|
1702
|
+
lastId = await this.sqliteUtil.prepareRun(mDb, delStmt, [], true);
|
|
1703
|
+
if (lastId < 0) {
|
|
1704
|
+
return Promise.reject('DelExportedRows: lastId < 0');
|
|
1705
|
+
}
|
|
1706
|
+
}
|
|
1707
|
+
}
|
|
1708
|
+
catch (err) {
|
|
1709
|
+
return Promise.reject(`DelExportedRows failed: ${err.message}`);
|
|
1710
|
+
}
|
|
1711
|
+
}
|
|
1527
1712
|
/**
|
|
1528
1713
|
* GetViewsNameSQL
|
|
1529
1714
|
* @param mDb
|
|
@@ -1534,7 +1719,7 @@ class ExportToJson {
|
|
|
1534
1719
|
sql += "type='view' AND name NOT LIKE 'sqlite_%';";
|
|
1535
1720
|
let retQuery = [];
|
|
1536
1721
|
try {
|
|
1537
|
-
retQuery = await this.
|
|
1722
|
+
retQuery = await this.sqliteUtil.queryAll(mDb, sql, []);
|
|
1538
1723
|
for (const query of retQuery) {
|
|
1539
1724
|
const view = {};
|
|
1540
1725
|
view.name = query.name;
|
|
@@ -1555,7 +1740,7 @@ class ExportToJson {
|
|
|
1555
1740
|
return new Promise((resolve, reject) => {
|
|
1556
1741
|
let retDate = -1;
|
|
1557
1742
|
// get the last sync date
|
|
1558
|
-
const stmt = `SELECT sync_date FROM sync_table;`;
|
|
1743
|
+
const stmt = `SELECT sync_date FROM sync_table WHERE id = 1;`;
|
|
1559
1744
|
mDb.get(stmt, [], (err, row) => {
|
|
1560
1745
|
// process the row here
|
|
1561
1746
|
if (err) {
|
|
@@ -1609,22 +1794,22 @@ class ExportToJson {
|
|
|
1609
1794
|
break;
|
|
1610
1795
|
}
|
|
1611
1796
|
// check schema validity
|
|
1612
|
-
await this.
|
|
1797
|
+
await this.jsonUtil.checkSchemaValidity(schema);
|
|
1613
1798
|
// create Table's indexes if any
|
|
1614
1799
|
const indexes = await this.getIndexes(mDb, tableName);
|
|
1615
1800
|
if (indexes.length > 0) {
|
|
1616
1801
|
// check indexes validity
|
|
1617
|
-
await this.
|
|
1802
|
+
await this.jsonUtil.checkIndexesValidity(indexes);
|
|
1618
1803
|
}
|
|
1619
1804
|
// create Table's triggers if any
|
|
1620
1805
|
const triggers = await this.getTriggers(mDb, tableName);
|
|
1621
1806
|
if (triggers.length > 0) {
|
|
1622
1807
|
// check triggers validity
|
|
1623
|
-
await this.
|
|
1808
|
+
await this.jsonUtil.checkTriggersValidity(triggers);
|
|
1624
1809
|
}
|
|
1625
1810
|
// create Table's Data
|
|
1626
1811
|
const query = `SELECT * FROM ${tableName};`;
|
|
1627
|
-
const values = await this.
|
|
1812
|
+
const values = await this.jsonUtil.getValues(mDb, query, tableName);
|
|
1628
1813
|
table.name = tableName;
|
|
1629
1814
|
if (schema.length > 0) {
|
|
1630
1815
|
table.schema = schema;
|
|
@@ -1722,7 +1907,7 @@ class ExportToJson {
|
|
|
1722
1907
|
let stmt = 'SELECT name,tbl_name,sql FROM sqlite_master WHERE ';
|
|
1723
1908
|
stmt += `type = 'index' AND tbl_name = '${tableName}' `;
|
|
1724
1909
|
stmt += `AND sql NOTNULL;`;
|
|
1725
|
-
const retIndexes = await this.
|
|
1910
|
+
const retIndexes = await this.sqliteUtil.queryAll(mDb, stmt, []);
|
|
1726
1911
|
if (retIndexes.length > 0) {
|
|
1727
1912
|
for (const rIndex of retIndexes) {
|
|
1728
1913
|
const keys = Object.keys(rIndex);
|
|
@@ -1771,7 +1956,7 @@ class ExportToJson {
|
|
|
1771
1956
|
let stmt = 'SELECT name,tbl_name,sql FROM sqlite_master WHERE ';
|
|
1772
1957
|
stmt += `type = 'trigger' AND tbl_name = '${tableName}' `;
|
|
1773
1958
|
stmt += `AND sql NOT NULL;`;
|
|
1774
|
-
const retTriggers = await this.
|
|
1959
|
+
const retTriggers = await this.sqliteUtil.queryAll(mDb, stmt, []);
|
|
1775
1960
|
if (retTriggers.length > 0) {
|
|
1776
1961
|
for (const rTrg of retTriggers) {
|
|
1777
1962
|
const keys = Object.keys(rTrg);
|
|
@@ -1881,19 +2066,19 @@ class ExportToJson {
|
|
|
1881
2066
|
schema = await this.getSchema(sqlStmt);
|
|
1882
2067
|
if (schema.length > 0) {
|
|
1883
2068
|
// check schema validity
|
|
1884
|
-
await this.
|
|
2069
|
+
await this.jsonUtil.checkSchemaValidity(schema);
|
|
1885
2070
|
}
|
|
1886
2071
|
// create Table's indexes if any
|
|
1887
2072
|
indexes = await this.getIndexes(mDb, tableName);
|
|
1888
2073
|
if (indexes.length > 0) {
|
|
1889
2074
|
// check indexes validity
|
|
1890
|
-
await this.
|
|
2075
|
+
await this.jsonUtil.checkIndexesValidity(indexes);
|
|
1891
2076
|
}
|
|
1892
2077
|
// create Table's triggers if any
|
|
1893
2078
|
triggers = await this.getTriggers(mDb, tableName);
|
|
1894
2079
|
if (triggers.length > 0) {
|
|
1895
2080
|
// check triggers validity
|
|
1896
|
-
await this.
|
|
2081
|
+
await this.jsonUtil.checkTriggersValidity(triggers);
|
|
1897
2082
|
}
|
|
1898
2083
|
}
|
|
1899
2084
|
// create Table's Data
|
|
@@ -1906,7 +2091,7 @@ class ExportToJson {
|
|
|
1906
2091
|
`SELECT * FROM ${tableName} ` +
|
|
1907
2092
|
`WHERE last_modified > ${syncDate};`;
|
|
1908
2093
|
}
|
|
1909
|
-
const values = await this.
|
|
2094
|
+
const values = await this.jsonUtil.getValues(mDb, query, tableName);
|
|
1910
2095
|
// check the table object validity
|
|
1911
2096
|
table.name = tableName;
|
|
1912
2097
|
if (schema.length > 0) {
|
|
@@ -1972,7 +2157,7 @@ class ExportToJson {
|
|
|
1972
2157
|
// get total count of the table
|
|
1973
2158
|
let stmt = 'SELECT count(*) AS tcount ';
|
|
1974
2159
|
stmt += `FROM ${rTable.name};`;
|
|
1975
|
-
let retQuery = await this.
|
|
2160
|
+
let retQuery = await this.sqliteUtil.queryAll(db, stmt, []);
|
|
1976
2161
|
if (retQuery.length != 1) {
|
|
1977
2162
|
errmsg = 'GetTableModified: total ' + 'count not returned';
|
|
1978
2163
|
break;
|
|
@@ -1982,7 +2167,7 @@ class ExportToJson {
|
|
|
1982
2167
|
stmt = 'SELECT count(*) AS mcount FROM ';
|
|
1983
2168
|
stmt += `${rTable.name} WHERE last_modified > `;
|
|
1984
2169
|
stmt += `${syncDate};`;
|
|
1985
|
-
retQuery = await this.
|
|
2170
|
+
retQuery = await this.sqliteUtil.queryAll(db, stmt, []);
|
|
1986
2171
|
if (retQuery.length != 1)
|
|
1987
2172
|
break;
|
|
1988
2173
|
const totalModifiedCount = retQuery[0]['mcount'];
|
|
@@ -2050,16 +2235,126 @@ exportToJson.ExportToJson = ExportToJson;
|
|
|
2050
2235
|
|
|
2051
2236
|
var importFromJson = {};
|
|
2052
2237
|
|
|
2238
|
+
var utilsDrop = {};
|
|
2239
|
+
|
|
2240
|
+
Object.defineProperty(utilsDrop, "__esModule", { value: true });
|
|
2241
|
+
utilsDrop.UtilsDrop = void 0;
|
|
2242
|
+
const utilsSQLite_1$3 = utilsSQLite;
|
|
2243
|
+
class UtilsDrop {
|
|
2244
|
+
constructor() {
|
|
2245
|
+
this.sqliteUtil = new utilsSQLite_1$3.UtilsSQLite();
|
|
2246
|
+
}
|
|
2247
|
+
/**
|
|
2248
|
+
* DropElements
|
|
2249
|
+
* @param db
|
|
2250
|
+
* @param type ["table","index","trigger"]
|
|
2251
|
+
*/
|
|
2252
|
+
async dropElements(db, type) {
|
|
2253
|
+
let msg = '';
|
|
2254
|
+
let stmt1 = `AND name NOT LIKE ('sqlite_%')`;
|
|
2255
|
+
switch (type) {
|
|
2256
|
+
case 'index':
|
|
2257
|
+
msg = 'DropIndexes';
|
|
2258
|
+
break;
|
|
2259
|
+
case 'trigger':
|
|
2260
|
+
msg = 'DropTriggers';
|
|
2261
|
+
break;
|
|
2262
|
+
case 'table':
|
|
2263
|
+
msg = 'DropTables';
|
|
2264
|
+
stmt1 += ` AND name NOT IN ('sync_table')`;
|
|
2265
|
+
break;
|
|
2266
|
+
case 'view':
|
|
2267
|
+
msg = 'DropViews';
|
|
2268
|
+
break;
|
|
2269
|
+
default:
|
|
2270
|
+
return Promise.reject(`DropElements: ${type} ` + 'not found');
|
|
2271
|
+
}
|
|
2272
|
+
// get the element's names
|
|
2273
|
+
let stmt = 'SELECT name FROM sqlite_master WHERE ';
|
|
2274
|
+
stmt += `type = '${type}' ${stmt1};`;
|
|
2275
|
+
try {
|
|
2276
|
+
const elements = await this.sqliteUtil.queryAll(db, stmt, []);
|
|
2277
|
+
if (elements.length > 0) {
|
|
2278
|
+
const upType = type.toUpperCase();
|
|
2279
|
+
const statements = [];
|
|
2280
|
+
for (const elem of elements) {
|
|
2281
|
+
let stmt = `DROP ${upType} IF EXISTS `;
|
|
2282
|
+
stmt += `${elem.name};`;
|
|
2283
|
+
statements.push(stmt);
|
|
2284
|
+
}
|
|
2285
|
+
for (const stmt of statements) {
|
|
2286
|
+
const lastId = await this.sqliteUtil.prepareRun(db, stmt, [], false);
|
|
2287
|
+
if (lastId < 0) {
|
|
2288
|
+
return Promise.reject(`${msg}: lastId < 0`);
|
|
2289
|
+
}
|
|
2290
|
+
}
|
|
2291
|
+
}
|
|
2292
|
+
return Promise.resolve();
|
|
2293
|
+
}
|
|
2294
|
+
catch (err) {
|
|
2295
|
+
return Promise.reject(`${msg}: ${err}`);
|
|
2296
|
+
}
|
|
2297
|
+
}
|
|
2298
|
+
/**
|
|
2299
|
+
* DropAll
|
|
2300
|
+
* Drop all database's elements
|
|
2301
|
+
* @param db
|
|
2302
|
+
*/
|
|
2303
|
+
async dropAll(db) {
|
|
2304
|
+
try {
|
|
2305
|
+
// drop tables
|
|
2306
|
+
await this.dropElements(db, 'table');
|
|
2307
|
+
// drop indexes
|
|
2308
|
+
await this.dropElements(db, 'index');
|
|
2309
|
+
// drop triggers
|
|
2310
|
+
await this.dropElements(db, 'trigger');
|
|
2311
|
+
// drop views
|
|
2312
|
+
await this.dropElements(db, 'view');
|
|
2313
|
+
// vacuum the database
|
|
2314
|
+
await this.sqliteUtil.prepareRun(db, 'VACUUM;', [], false);
|
|
2315
|
+
return Promise.resolve();
|
|
2316
|
+
}
|
|
2317
|
+
catch (err) {
|
|
2318
|
+
return Promise.reject(`DropAll: ${err}`);
|
|
2319
|
+
}
|
|
2320
|
+
}
|
|
2321
|
+
/**
|
|
2322
|
+
* DropTempTables
|
|
2323
|
+
* @param db
|
|
2324
|
+
* @param alterTables
|
|
2325
|
+
*/
|
|
2326
|
+
async dropTempTables(db, alterTables) {
|
|
2327
|
+
const tempTables = Object.keys(alterTables);
|
|
2328
|
+
const statements = [];
|
|
2329
|
+
for (const tTable of tempTables) {
|
|
2330
|
+
let stmt = 'DROP TABLE IF EXISTS ';
|
|
2331
|
+
stmt += `_temp_${tTable};`;
|
|
2332
|
+
statements.push(stmt);
|
|
2333
|
+
}
|
|
2334
|
+
try {
|
|
2335
|
+
const changes = await this.sqliteUtil.execute(db, statements.join('\n'), false);
|
|
2336
|
+
if (changes < 0) {
|
|
2337
|
+
return Promise.reject('DropTempTables: changes < 0');
|
|
2338
|
+
}
|
|
2339
|
+
return Promise.resolve();
|
|
2340
|
+
}
|
|
2341
|
+
catch (err) {
|
|
2342
|
+
return Promise.reject(`DropTempTables: ${err}`);
|
|
2343
|
+
}
|
|
2344
|
+
}
|
|
2345
|
+
}
|
|
2346
|
+
utilsDrop.UtilsDrop = UtilsDrop;
|
|
2347
|
+
|
|
2053
2348
|
Object.defineProperty(importFromJson, "__esModule", { value: true });
|
|
2054
2349
|
importFromJson.ImportFromJson = void 0;
|
|
2055
|
-
const utilsDrop_1$
|
|
2350
|
+
const utilsDrop_1$1 = utilsDrop;
|
|
2056
2351
|
const utilsSQLite_1$2 = utilsSQLite;
|
|
2057
2352
|
const utilsJson_1$3 = utilsJson;
|
|
2058
2353
|
class ImportFromJson {
|
|
2059
2354
|
constructor() {
|
|
2060
|
-
this.
|
|
2061
|
-
this.
|
|
2062
|
-
this.
|
|
2355
|
+
this.jsonUtil = new utilsJson_1$3.UtilsJson();
|
|
2356
|
+
this.sqliteUtil = new utilsSQLite_1$2.UtilsSQLite();
|
|
2357
|
+
this.dropUtil = new utilsDrop_1$1.UtilsDrop();
|
|
2063
2358
|
}
|
|
2064
2359
|
/**
|
|
2065
2360
|
* CreateDatabaseSchema
|
|
@@ -2071,17 +2366,13 @@ class ImportFromJson {
|
|
|
2071
2366
|
const version = jsonData.version;
|
|
2072
2367
|
try {
|
|
2073
2368
|
// set User Version PRAGMA
|
|
2074
|
-
await this.
|
|
2369
|
+
await this.sqliteUtil.setVersion(mDB, version);
|
|
2075
2370
|
// DROP ALL when mode="full"
|
|
2076
2371
|
if (jsonData.mode === 'full') {
|
|
2077
|
-
|
|
2078
|
-
await this._uSQLite.setForeignKeyConstraintsEnabled(mDB, false);
|
|
2079
|
-
await this._uDrop.dropAll(mDB);
|
|
2372
|
+
await this.dropUtil.dropAll(mDB);
|
|
2080
2373
|
}
|
|
2081
|
-
// set Foreign Keys On
|
|
2082
|
-
await this._uSQLite.setForeignKeyConstraintsEnabled(mDB, true);
|
|
2083
2374
|
// create database schema
|
|
2084
|
-
changes = await this.
|
|
2375
|
+
changes = await this.jsonUtil.createSchema(mDB, jsonData);
|
|
2085
2376
|
return Promise.resolve(changes);
|
|
2086
2377
|
}
|
|
2087
2378
|
catch (err) {
|
|
@@ -2095,9 +2386,9 @@ class ImportFromJson {
|
|
|
2095
2386
|
let msg = '';
|
|
2096
2387
|
let initChanges = -1;
|
|
2097
2388
|
try {
|
|
2098
|
-
initChanges = await this.
|
|
2389
|
+
initChanges = await this.sqliteUtil.dbChanges(mDB);
|
|
2099
2390
|
// start a transaction
|
|
2100
|
-
await this.
|
|
2391
|
+
await this.sqliteUtil.beginTransaction(mDB, true);
|
|
2101
2392
|
}
|
|
2102
2393
|
catch (err) {
|
|
2103
2394
|
return Promise.reject(`createTablesData: ${err}`);
|
|
@@ -2106,7 +2397,7 @@ class ImportFromJson {
|
|
|
2106
2397
|
if (jTable.values != null && jTable.values.length >= 1) {
|
|
2107
2398
|
// Create the table's data
|
|
2108
2399
|
try {
|
|
2109
|
-
lastId = await this.
|
|
2400
|
+
lastId = await this.jsonUtil.createDataTable(mDB, jTable, jsonData.mode);
|
|
2110
2401
|
if (lastId < 0)
|
|
2111
2402
|
break;
|
|
2112
2403
|
isValue = true;
|
|
@@ -2120,8 +2411,8 @@ class ImportFromJson {
|
|
|
2120
2411
|
}
|
|
2121
2412
|
if (isValue) {
|
|
2122
2413
|
try {
|
|
2123
|
-
await this.
|
|
2124
|
-
changes = (await this.
|
|
2414
|
+
await this.sqliteUtil.commitTransaction(mDB, true);
|
|
2415
|
+
changes = (await this.sqliteUtil.dbChanges(mDB)) - initChanges;
|
|
2125
2416
|
return Promise.resolve(changes);
|
|
2126
2417
|
}
|
|
2127
2418
|
catch (err) {
|
|
@@ -2131,7 +2422,7 @@ class ImportFromJson {
|
|
|
2131
2422
|
else {
|
|
2132
2423
|
if (msg.length > 0) {
|
|
2133
2424
|
try {
|
|
2134
|
-
await this.
|
|
2425
|
+
await this.sqliteUtil.rollbackTransaction(mDB, true);
|
|
2135
2426
|
return Promise.reject(new Error(`createTablesData: ${msg}`));
|
|
2136
2427
|
}
|
|
2137
2428
|
catch (err) {
|
|
@@ -2155,9 +2446,9 @@ class ImportFromJson {
|
|
|
2155
2446
|
let initChanges = -1;
|
|
2156
2447
|
let changes = -1;
|
|
2157
2448
|
try {
|
|
2158
|
-
initChanges = await this.
|
|
2449
|
+
initChanges = await this.sqliteUtil.dbChanges(mDB);
|
|
2159
2450
|
// start a transaction
|
|
2160
|
-
await this.
|
|
2451
|
+
await this.sqliteUtil.beginTransaction(mDB, true);
|
|
2161
2452
|
}
|
|
2162
2453
|
catch (err) {
|
|
2163
2454
|
return Promise.reject(`createViews: ${err}`);
|
|
@@ -2166,7 +2457,7 @@ class ImportFromJson {
|
|
|
2166
2457
|
if (jView.value != null) {
|
|
2167
2458
|
// Create the view
|
|
2168
2459
|
try {
|
|
2169
|
-
await this.
|
|
2460
|
+
await this.jsonUtil.createView(mDB, jView);
|
|
2170
2461
|
isView = true;
|
|
2171
2462
|
}
|
|
2172
2463
|
catch (err) {
|
|
@@ -2178,8 +2469,8 @@ class ImportFromJson {
|
|
|
2178
2469
|
}
|
|
2179
2470
|
if (isView) {
|
|
2180
2471
|
try {
|
|
2181
|
-
await this.
|
|
2182
|
-
changes = (await this.
|
|
2472
|
+
await this.sqliteUtil.commitTransaction(mDB, true);
|
|
2473
|
+
changes = (await this.sqliteUtil.dbChanges(mDB)) - initChanges;
|
|
2183
2474
|
return Promise.resolve(changes);
|
|
2184
2475
|
}
|
|
2185
2476
|
catch (err) {
|
|
@@ -2189,7 +2480,7 @@ class ImportFromJson {
|
|
|
2189
2480
|
else {
|
|
2190
2481
|
if (msg.length > 0) {
|
|
2191
2482
|
try {
|
|
2192
|
-
await this.
|
|
2483
|
+
await this.sqliteUtil.rollbackTransaction(mDB, true);
|
|
2193
2484
|
return Promise.reject(new Error(`createViews: ${msg}`));
|
|
2194
2485
|
}
|
|
2195
2486
|
catch (err) {
|
|
@@ -2635,15 +2926,15 @@ var utilsUpgrade = {};
|
|
|
2635
2926
|
Object.defineProperty(utilsUpgrade, "__esModule", { value: true });
|
|
2636
2927
|
utilsUpgrade.UtilsUpgrade = void 0;
|
|
2637
2928
|
const utilsJson_1$2 = utilsJson;
|
|
2638
|
-
const utilsDrop_1
|
|
2929
|
+
const utilsDrop_1 = utilsDrop;
|
|
2639
2930
|
const utilsFile_1$2 = utilsFile;
|
|
2640
2931
|
const utilsSQLite_1$1 = utilsSQLite;
|
|
2641
2932
|
class UtilsUpgrade {
|
|
2642
2933
|
constructor() {
|
|
2643
|
-
this.
|
|
2644
|
-
this.
|
|
2645
|
-
this.
|
|
2646
|
-
this.
|
|
2934
|
+
this.sqliteUtil = new utilsSQLite_1$1.UtilsSQLite();
|
|
2935
|
+
this.fileUtil = new utilsFile_1$2.UtilsFile();
|
|
2936
|
+
this.dropUtil = new utilsDrop_1.UtilsDrop();
|
|
2937
|
+
this.jsonUtil = new utilsJson_1$2.UtilsJson();
|
|
2647
2938
|
this._alterTables = {};
|
|
2648
2939
|
this._commonColumns = {};
|
|
2649
2940
|
}
|
|
@@ -2681,9 +2972,9 @@ class UtilsUpgrade {
|
|
|
2681
2972
|
}
|
|
2682
2973
|
try {
|
|
2683
2974
|
// set Foreign Keys Off
|
|
2684
|
-
await this.
|
|
2685
|
-
await this.
|
|
2686
|
-
const initChanges = await this.
|
|
2975
|
+
await this.sqliteUtil.setForeignKeyConstraintsEnabled(mDB, false);
|
|
2976
|
+
await this.fileUtil.copyFileName(dbName, `backup-${dbName}`);
|
|
2977
|
+
const initChanges = await this.sqliteUtil.dbChanges(mDB);
|
|
2687
2978
|
// Here we assume that all table schemas are given
|
|
2688
2979
|
// in the upgrade statement
|
|
2689
2980
|
if (statement.length > 0) {
|
|
@@ -2698,8 +2989,8 @@ class UtilsUpgrade {
|
|
|
2698
2989
|
}
|
|
2699
2990
|
}
|
|
2700
2991
|
// set Foreign Keys On
|
|
2701
|
-
await this.
|
|
2702
|
-
const changes = (await this.
|
|
2992
|
+
await this.sqliteUtil.setForeignKeyConstraintsEnabled(mDB, true);
|
|
2993
|
+
const changes = (await this.sqliteUtil.dbChanges(mDB)) - initChanges;
|
|
2703
2994
|
return Promise.resolve(changes);
|
|
2704
2995
|
}
|
|
2705
2996
|
catch (err) {
|
|
@@ -2721,11 +3012,11 @@ class UtilsUpgrade {
|
|
|
2721
3012
|
// "temp_tableName"
|
|
2722
3013
|
await this.backupTables(mDB);
|
|
2723
3014
|
// -> Drop all Indexes
|
|
2724
|
-
await this.
|
|
3015
|
+
await this.dropUtil.dropElements(mDB, 'index');
|
|
2725
3016
|
// -> Drop all Triggers
|
|
2726
|
-
await this.
|
|
3017
|
+
await this.dropUtil.dropElements(mDB, 'trigger');
|
|
2727
3018
|
// -> Create new tables from upgrade.statement
|
|
2728
|
-
const changes = await this.
|
|
3019
|
+
const changes = await this.sqliteUtil.execute(mDB, statement, false);
|
|
2729
3020
|
if (changes < 0) {
|
|
2730
3021
|
return Promise.reject('ExecuteStatementProcess: ' + 'changes < 0');
|
|
2731
3022
|
}
|
|
@@ -2742,7 +3033,7 @@ class UtilsUpgrade {
|
|
|
2742
3033
|
}
|
|
2743
3034
|
finally {
|
|
2744
3035
|
// -> Drop _temp_tables
|
|
2745
|
-
await this.
|
|
3036
|
+
await this.dropUtil.dropTempTables(mDB, this._alterTables);
|
|
2746
3037
|
// -> Do some cleanup
|
|
2747
3038
|
this._alterTables = {};
|
|
2748
3039
|
this._commonColumns = {};
|
|
@@ -2757,19 +3048,19 @@ class UtilsUpgrade {
|
|
|
2757
3048
|
async executeSetProcess(mDB, set, toVersion) {
|
|
2758
3049
|
try {
|
|
2759
3050
|
// -> load new data
|
|
2760
|
-
const lastId = await this.
|
|
3051
|
+
const lastId = await this.sqliteUtil.executeSet(mDB, set, false);
|
|
2761
3052
|
if (lastId < 0) {
|
|
2762
3053
|
return Promise.reject('ExecuteSetProcess: lastId ' + '< 0');
|
|
2763
3054
|
}
|
|
2764
3055
|
// -> update database version
|
|
2765
|
-
await this.
|
|
3056
|
+
await this.sqliteUtil.setVersion(mDB, toVersion);
|
|
2766
3057
|
// -> update syncDate if any
|
|
2767
|
-
const retB = await this.
|
|
3058
|
+
const retB = await this.jsonUtil.isTableExists(mDB, true, 'sync_table');
|
|
2768
3059
|
if (retB) {
|
|
2769
3060
|
const sDate = Math.round(new Date().getTime() / 1000);
|
|
2770
3061
|
let stmt = 'UPDATE sync_table SET ';
|
|
2771
3062
|
stmt += `sync_date = ${sDate} WHERE id = 1;`;
|
|
2772
|
-
const changes = await this.
|
|
3063
|
+
const changes = await this.sqliteUtil.execute(mDB, stmt, false);
|
|
2773
3064
|
if (changes < 0) {
|
|
2774
3065
|
return Promise.reject('ExecuteSetProcess: changes ' + '< 0');
|
|
2775
3066
|
}
|
|
@@ -2787,7 +3078,7 @@ class UtilsUpgrade {
|
|
|
2787
3078
|
async backupTables(mDB) {
|
|
2788
3079
|
const msg = 'BackupTables: ';
|
|
2789
3080
|
try {
|
|
2790
|
-
const tables = await this.
|
|
3081
|
+
const tables = await this.sqliteUtil.getTablesNames(mDB);
|
|
2791
3082
|
for (const table of tables) {
|
|
2792
3083
|
try {
|
|
2793
3084
|
await this.backupTable(mDB, table);
|
|
@@ -2810,22 +3101,22 @@ class UtilsUpgrade {
|
|
|
2810
3101
|
async backupTable(mDB, table) {
|
|
2811
3102
|
try {
|
|
2812
3103
|
// start a transaction
|
|
2813
|
-
await this.
|
|
3104
|
+
await this.sqliteUtil.beginTransaction(mDB, true);
|
|
2814
3105
|
// get the table's column names
|
|
2815
3106
|
const colNames = await this.getTableColumnNames(mDB, table);
|
|
2816
3107
|
this._alterTables[`${table}`] = colNames;
|
|
2817
3108
|
const tmpTable = `_temp_${table}`;
|
|
2818
3109
|
// Drop the tmpTable if exists
|
|
2819
3110
|
const delStmt = `DROP TABLE IF EXISTS ${tmpTable};`;
|
|
2820
|
-
await this.
|
|
3111
|
+
await this.sqliteUtil.prepareRun(mDB, delStmt, [], false);
|
|
2821
3112
|
// prefix the table with _temp_
|
|
2822
3113
|
let stmt = `ALTER TABLE ${table} RENAME `;
|
|
2823
3114
|
stmt += `TO ${tmpTable};`;
|
|
2824
|
-
const lastId = await this.
|
|
3115
|
+
const lastId = await this.sqliteUtil.prepareRun(mDB, stmt, [], false);
|
|
2825
3116
|
if (lastId < 0) {
|
|
2826
3117
|
let msg = 'BackupTable: lastId < 0';
|
|
2827
3118
|
try {
|
|
2828
|
-
await this.
|
|
3119
|
+
await this.sqliteUtil.rollbackTransaction(mDB, true);
|
|
2829
3120
|
}
|
|
2830
3121
|
catch (err) {
|
|
2831
3122
|
msg += `: ${err}`;
|
|
@@ -2834,7 +3125,7 @@ class UtilsUpgrade {
|
|
|
2834
3125
|
}
|
|
2835
3126
|
else {
|
|
2836
3127
|
try {
|
|
2837
|
-
await this.
|
|
3128
|
+
await this.sqliteUtil.commitTransaction(mDB, true);
|
|
2838
3129
|
}
|
|
2839
3130
|
catch (err) {
|
|
2840
3131
|
return Promise.reject('BackupTable: ' + `${err}`);
|
|
@@ -2856,7 +3147,7 @@ class UtilsUpgrade {
|
|
|
2856
3147
|
const retNames = [];
|
|
2857
3148
|
const query = `PRAGMA table_info('${tableName}');`;
|
|
2858
3149
|
try {
|
|
2859
|
-
resQuery = await this.
|
|
3150
|
+
resQuery = await this.sqliteUtil.queryAll(mDB, query, []);
|
|
2860
3151
|
if (resQuery.length > 0) {
|
|
2861
3152
|
for (const query of resQuery) {
|
|
2862
3153
|
retNames.push(query.name);
|
|
@@ -2875,7 +3166,7 @@ class UtilsUpgrade {
|
|
|
2875
3166
|
async findCommonColumns(mDB) {
|
|
2876
3167
|
try {
|
|
2877
3168
|
// Get new table list
|
|
2878
|
-
const tables = await this.
|
|
3169
|
+
const tables = await this.sqliteUtil.getTablesNames(mDB);
|
|
2879
3170
|
if (tables.length === 0) {
|
|
2880
3171
|
return Promise.reject('FindCommonColumns: get ' + "table's names failed");
|
|
2881
3172
|
}
|
|
@@ -2916,7 +3207,7 @@ class UtilsUpgrade {
|
|
|
2916
3207
|
async updateNewTablesData(mDB) {
|
|
2917
3208
|
try {
|
|
2918
3209
|
// start a transaction
|
|
2919
|
-
await this.
|
|
3210
|
+
await this.sqliteUtil.beginTransaction(mDB, true);
|
|
2920
3211
|
const statements = [];
|
|
2921
3212
|
const keys = Object.keys(this._commonColumns);
|
|
2922
3213
|
keys.forEach(key => {
|
|
@@ -2926,11 +3217,11 @@ class UtilsUpgrade {
|
|
|
2926
3217
|
stmt += `SELECT ${columns} FROM _temp_${key};`;
|
|
2927
3218
|
statements.push(stmt);
|
|
2928
3219
|
});
|
|
2929
|
-
const changes = await this.
|
|
3220
|
+
const changes = await this.sqliteUtil.execute(mDB, statements.join('\n'), false);
|
|
2930
3221
|
if (changes < 0) {
|
|
2931
3222
|
let msg = 'updateNewTablesData: ' + 'changes < 0';
|
|
2932
3223
|
try {
|
|
2933
|
-
await this.
|
|
3224
|
+
await this.sqliteUtil.rollbackTransaction(mDB, true);
|
|
2934
3225
|
}
|
|
2935
3226
|
catch (err) {
|
|
2936
3227
|
msg += `: ${err}`;
|
|
@@ -2939,7 +3230,7 @@ class UtilsUpgrade {
|
|
|
2939
3230
|
}
|
|
2940
3231
|
else {
|
|
2941
3232
|
try {
|
|
2942
|
-
await this.
|
|
3233
|
+
await this.sqliteUtil.commitTransaction(mDB, true);
|
|
2943
3234
|
return Promise.resolve();
|
|
2944
3235
|
}
|
|
2945
3236
|
catch (err) {
|
|
@@ -2960,7 +3251,6 @@ const exportToJson_1 = exportToJson;
|
|
|
2960
3251
|
const importFromJson_1 = importFromJson;
|
|
2961
3252
|
const utilsJson_1$1 = utilsJson;
|
|
2962
3253
|
//import { UtilsEncryption } from './utilsEncryption';
|
|
2963
|
-
const utilsDrop_1 = utilsDrop;
|
|
2964
3254
|
const utilsFile_1$1 = utilsFile;
|
|
2965
3255
|
const utilsSQLite_1 = utilsSQLite;
|
|
2966
3256
|
const utilsUpgrade_1 = utilsUpgrade;
|
|
@@ -2972,7 +3262,6 @@ class Database {
|
|
|
2972
3262
|
this.fileUtil = new utilsFile_1$1.UtilsFile();
|
|
2973
3263
|
this.sqliteUtil = new utilsSQLite_1.UtilsSQLite();
|
|
2974
3264
|
this.jsonUtil = new utilsJson_1$1.UtilsJson();
|
|
2975
|
-
this.dropUtil = new utilsDrop_1.UtilsDrop();
|
|
2976
3265
|
// private _uGlobal: GlobalSQLite = new GlobalSQLite();
|
|
2977
3266
|
// private _uEncrypt: UtilsEncryption = new UtilsEncryption();
|
|
2978
3267
|
this.upgradeUtil = new utilsUpgrade_1.UtilsUpgrade();
|
|
@@ -3153,7 +3442,7 @@ class Database {
|
|
|
3153
3442
|
try {
|
|
3154
3443
|
const retB = await this.jsonUtil.isTableExists(this.database, isOpen, 'sync_table');
|
|
3155
3444
|
if (!retB) {
|
|
3156
|
-
const isLastModified = await this.
|
|
3445
|
+
const isLastModified = await this.sqliteUtil.isLastModified(this.database, isOpen);
|
|
3157
3446
|
if (isLastModified) {
|
|
3158
3447
|
const date = Math.round(new Date().getTime() / 1000);
|
|
3159
3448
|
let stmts = `
|
|
@@ -3163,7 +3452,7 @@ class Database {
|
|
|
3163
3452
|
);`;
|
|
3164
3453
|
stmts += `INSERT INTO sync_table (sync_date) VALUES (
|
|
3165
3454
|
"${date}");`;
|
|
3166
|
-
changes = await this.sqliteUtil.execute(this.database, stmts);
|
|
3455
|
+
changes = await this.sqliteUtil.execute(this.database, stmts, false);
|
|
3167
3456
|
if (changes < 0) {
|
|
3168
3457
|
throw new Error(`CreateSyncTable: failed changes < 0`);
|
|
3169
3458
|
}
|
|
@@ -3175,7 +3464,6 @@ class Database {
|
|
|
3175
3464
|
else {
|
|
3176
3465
|
changes = 0;
|
|
3177
3466
|
}
|
|
3178
|
-
console.log(`>>> CreateSyncTable changes: ${changes}`);
|
|
3179
3467
|
return changes;
|
|
3180
3468
|
}
|
|
3181
3469
|
catch (err) {
|
|
@@ -3198,7 +3486,7 @@ class Database {
|
|
|
3198
3486
|
const syncDateUnixTimestamp = Math.round(new Date(syncDate).getTime() / 1000);
|
|
3199
3487
|
let stmt = `UPDATE sync_table SET sync_date = `;
|
|
3200
3488
|
stmt += `${syncDateUnixTimestamp} WHERE id = 1;`;
|
|
3201
|
-
const changes = await this.sqliteUtil.execute(this.database, stmt);
|
|
3489
|
+
const changes = await this.sqliteUtil.execute(this.database, stmt, false);
|
|
3202
3490
|
if (changes < 0) {
|
|
3203
3491
|
return { result: false, message: 'setSyncDate failed' };
|
|
3204
3492
|
}
|
|
@@ -3246,7 +3534,7 @@ class Database {
|
|
|
3246
3534
|
if (transaction) {
|
|
3247
3535
|
await this.sqliteUtil.beginTransaction(this.database, this._isDbOpen);
|
|
3248
3536
|
}
|
|
3249
|
-
const changes = await this.sqliteUtil.execute(this.database, sql);
|
|
3537
|
+
const changes = await this.sqliteUtil.execute(this.database, sql, false);
|
|
3250
3538
|
if (changes < 0) {
|
|
3251
3539
|
throw new Error('ExecuteSQL: changes < 0');
|
|
3252
3540
|
}
|
|
@@ -3307,7 +3595,7 @@ class Database {
|
|
|
3307
3595
|
throw new Error(`RunSQL: ${err}`);
|
|
3308
3596
|
}
|
|
3309
3597
|
try {
|
|
3310
|
-
const lastId = await this.sqliteUtil.prepareRun(this.database, statement, values);
|
|
3598
|
+
const lastId = await this.sqliteUtil.prepareRun(this.database, statement, values, false);
|
|
3311
3599
|
if (lastId < 0) {
|
|
3312
3600
|
if (transaction) {
|
|
3313
3601
|
await this.sqliteUtil.rollbackTransaction(this.database, this._isDbOpen);
|
|
@@ -3317,7 +3605,8 @@ class Database {
|
|
|
3317
3605
|
if (transaction) {
|
|
3318
3606
|
await this.sqliteUtil.commitTransaction(this.database, this._isDbOpen);
|
|
3319
3607
|
}
|
|
3320
|
-
result.changes =
|
|
3608
|
+
result.changes =
|
|
3609
|
+
(await this.sqliteUtil.dbChanges(this.database)) - initChanges;
|
|
3321
3610
|
result.lastId = lastId;
|
|
3322
3611
|
return result;
|
|
3323
3612
|
}
|
|
@@ -3349,11 +3638,12 @@ class Database {
|
|
|
3349
3638
|
throw new Error(`ExecSet: ${err}`);
|
|
3350
3639
|
}
|
|
3351
3640
|
try {
|
|
3352
|
-
result.lastId = await this.sqliteUtil.executeSet(this.database, set);
|
|
3641
|
+
result.lastId = await this.sqliteUtil.executeSet(this.database, set, false);
|
|
3353
3642
|
if (transaction) {
|
|
3354
3643
|
await this.sqliteUtil.commitTransaction(this.database, this._isDbOpen);
|
|
3355
3644
|
}
|
|
3356
|
-
result.changes =
|
|
3645
|
+
result.changes =
|
|
3646
|
+
(await this.sqliteUtil.dbChanges(this.database)) - initChanges;
|
|
3357
3647
|
return result;
|
|
3358
3648
|
}
|
|
3359
3649
|
catch (err) {
|
|
@@ -3368,10 +3658,25 @@ class Database {
|
|
|
3368
3658
|
}
|
|
3369
3659
|
}
|
|
3370
3660
|
}
|
|
3661
|
+
async deleteExportedRows() {
|
|
3662
|
+
this.ensureDatabaseIsOpen();
|
|
3663
|
+
try {
|
|
3664
|
+
await this.exportToJsonUtil.delExportedRows(this.database);
|
|
3665
|
+
return;
|
|
3666
|
+
}
|
|
3667
|
+
catch (err) {
|
|
3668
|
+
throw new Error(`DeleteExportedRows: ${err}`);
|
|
3669
|
+
}
|
|
3670
|
+
}
|
|
3671
|
+
/**
|
|
3672
|
+
* GetTableList
|
|
3673
|
+
* get the table's list
|
|
3674
|
+
* @returns
|
|
3675
|
+
*/
|
|
3371
3676
|
async getTableList() {
|
|
3372
3677
|
this.ensureDatabaseIsOpen();
|
|
3373
3678
|
try {
|
|
3374
|
-
const tableNames = await this.
|
|
3679
|
+
const tableNames = await this.sqliteUtil.getTablesNames(this.database);
|
|
3375
3680
|
return tableNames;
|
|
3376
3681
|
}
|
|
3377
3682
|
catch (err) {
|
|
@@ -3382,6 +3687,8 @@ class Database {
|
|
|
3382
3687
|
let changes = 0;
|
|
3383
3688
|
this.ensureDatabaseIsOpen();
|
|
3384
3689
|
try {
|
|
3690
|
+
// set Foreign Keys Off
|
|
3691
|
+
await this.sqliteUtil.setForeignKeyConstraintsEnabled(this.database, false);
|
|
3385
3692
|
if (jsonData.tables && jsonData.tables.length > 0) {
|
|
3386
3693
|
// create the database schema
|
|
3387
3694
|
changes = await this.importFromJsonUtil.createDatabaseSchema(this.database, jsonData);
|
|
@@ -3394,6 +3701,8 @@ class Database {
|
|
|
3394
3701
|
// create the views
|
|
3395
3702
|
changes += await this.importFromJsonUtil.createViews(this.database, jsonData);
|
|
3396
3703
|
}
|
|
3704
|
+
// set Foreign Keys On
|
|
3705
|
+
await this.sqliteUtil.setForeignKeyConstraintsEnabled(this.database, true);
|
|
3397
3706
|
return changes;
|
|
3398
3707
|
}
|
|
3399
3708
|
catch (err) {
|
|
@@ -3408,7 +3717,13 @@ class Database {
|
|
|
3408
3717
|
inJson.mode = mode;
|
|
3409
3718
|
this.ensureDatabaseIsOpen();
|
|
3410
3719
|
try {
|
|
3720
|
+
await this.exportToJsonUtil.setLastExportDate(this.database, new Date().toISOString());
|
|
3411
3721
|
const jsonResult = await this.exportToJsonUtil.createExportObject(this.database, inJson);
|
|
3722
|
+
const keys = Object.keys(jsonResult);
|
|
3723
|
+
if (keys.length === 0) {
|
|
3724
|
+
const msg = `ExportJson: return Object is empty ` + `No data to synchronize`;
|
|
3725
|
+
throw new Error(msg);
|
|
3726
|
+
}
|
|
3412
3727
|
const isValid = this.jsonUtil.isJsonSQLite(jsonResult);
|
|
3413
3728
|
if (isValid) {
|
|
3414
3729
|
return jsonResult;
|
|
@@ -3465,7 +3780,8 @@ class CapacitorSQLite {
|
|
|
3465
3780
|
*/
|
|
3466
3781
|
let upgrades = {};
|
|
3467
3782
|
const versionUpgradeKeys = Object.keys(this.versionUpgrades);
|
|
3468
|
-
if (versionUpgradeKeys.length !== 0 &&
|
|
3783
|
+
if (versionUpgradeKeys.length !== 0 &&
|
|
3784
|
+
versionUpgradeKeys.includes(dbName)) {
|
|
3469
3785
|
upgrades = this.versionUpgrades[dbName];
|
|
3470
3786
|
}
|
|
3471
3787
|
const databaseConnection = new Database_1.Database(dbName + 'SQLite.db',
|
|
@@ -3740,7 +4056,7 @@ class CapacitorSQLite {
|
|
|
3740
4056
|
try {
|
|
3741
4057
|
const createTableSyncResult = await database.createSyncTable();
|
|
3742
4058
|
return {
|
|
3743
|
-
changes: { changes: createTableSyncResult }
|
|
4059
|
+
changes: { changes: createTableSyncResult },
|
|
3744
4060
|
};
|
|
3745
4061
|
}
|
|
3746
4062
|
catch (err) {
|
|
@@ -3770,6 +4086,17 @@ class CapacitorSQLite {
|
|
|
3770
4086
|
throw new Error(`GetSyncDate: ${err}`);
|
|
3771
4087
|
}
|
|
3772
4088
|
}
|
|
4089
|
+
async deleteExportedRows(options) {
|
|
4090
|
+
const dbName = this.getOptionValue(options, 'database');
|
|
4091
|
+
const database = this.getDatabaseConnectionOrThrowError(dbName);
|
|
4092
|
+
try {
|
|
4093
|
+
await database.deleteExportedRows();
|
|
4094
|
+
return Promise.resolve();
|
|
4095
|
+
}
|
|
4096
|
+
catch (err) {
|
|
4097
|
+
throw new Error(`DeleteExportedRows: ${err}`);
|
|
4098
|
+
}
|
|
4099
|
+
}
|
|
3773
4100
|
async addUpgradeStatement(options) {
|
|
3774
4101
|
const dbName = this.getOptionValue(options, 'database');
|
|
3775
4102
|
const upgrades = this.getOptionValue(options, 'upgrade');
|