@capacitor-community/sqlite 3.4.2 → 3.4.3-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 +42 -2
- 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/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsUpgrade.java +8 -4
- package/dist/esm/definitions.d.ts +17 -1
- package/dist/esm/definitions.js +9 -17
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/web.d.ts +20 -11
- package/dist/esm/web.js +288 -473
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +273 -466
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +1036 -1229
- package/dist/plugin.js.map +1 -1
- package/electron/dist/plugin.js +1147 -1032
- 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 +33 -13
- package/package.json +6 -6
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
|
-
}
|
|
538
|
-
catch (err) {
|
|
539
|
-
return Promise.reject(`${msg}: ${err}`);
|
|
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
669
|
}
|
|
561
670
|
catch (err) {
|
|
562
|
-
return Promise.reject(`
|
|
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,65 +947,138 @@ 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
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
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]};`;
|
|
930
1007
|
}
|
|
931
1008
|
}
|
|
932
|
-
return Promise.resolve(false);
|
|
933
|
-
}
|
|
934
|
-
else {
|
|
935
|
-
const msg = 'Both arrays not the same length';
|
|
936
|
-
return Promise.reject(new Error(`CheckUpdate: ${msg}`));
|
|
937
1009
|
}
|
|
1010
|
+
return Promise.resolve(stmt);
|
|
938
1011
|
}
|
|
939
1012
|
catch (err) {
|
|
940
|
-
return Promise.reject(new Error(`
|
|
1013
|
+
return Promise.reject(new Error(`CreateRowStatement: ${err.message}`));
|
|
941
1014
|
}
|
|
942
1015
|
}
|
|
943
1016
|
/**
|
|
944
|
-
*
|
|
945
|
-
* @param
|
|
946
|
-
* @param
|
|
947
|
-
* @param
|
|
1017
|
+
*
|
|
1018
|
+
* @param db
|
|
1019
|
+
* @param values
|
|
1020
|
+
* @param tbName
|
|
1021
|
+
* @param tColNames
|
|
1022
|
+
* @returns
|
|
948
1023
|
*/
|
|
949
|
-
async
|
|
950
|
-
const
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
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
|
+
}
|
|
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}`));
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
catch (err) {
|
|
1056
|
+
return Promise.reject(new Error(`CheckUpdate: ${err.message}`));
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
else {
|
|
1060
|
+
return Promise.resolve(isRun);
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
/**
|
|
1064
|
+
* GetValues
|
|
1065
|
+
* @param mDb
|
|
1066
|
+
* @param query
|
|
1067
|
+
* @param tableName
|
|
1068
|
+
*/
|
|
1069
|
+
async getValues(mDb, query, tableName) {
|
|
1070
|
+
const values = [];
|
|
1071
|
+
try {
|
|
1072
|
+
// get table column names and types
|
|
1073
|
+
const tableNamesTypes = await this.sqliteUtil.getTableColumnNamesTypes(mDb, tableName);
|
|
1074
|
+
let rowNames = [];
|
|
955
1075
|
if (Object.keys(tableNamesTypes).includes('names')) {
|
|
956
1076
|
rowNames = tableNamesTypes.names;
|
|
957
1077
|
}
|
|
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
|
}
|
|
@@ -2735,16 +3026,18 @@ class UtilsUpgrade {
|
|
|
2735
3026
|
if (Object.keys(this._commonColumns).length > 0) {
|
|
2736
3027
|
await this.updateNewTablesData(mDB);
|
|
2737
3028
|
}
|
|
2738
|
-
// -> Drop _temp_tables
|
|
2739
|
-
await this._uDrop.dropTempTables(mDB, this._alterTables);
|
|
2740
|
-
// -> Do some cleanup
|
|
2741
|
-
this._alterTables = {};
|
|
2742
|
-
this._commonColumns = {};
|
|
2743
3029
|
return Promise.resolve();
|
|
2744
3030
|
}
|
|
2745
3031
|
catch (err) {
|
|
2746
3032
|
return Promise.reject(`ExecuteStatementProcess: ${err}`);
|
|
2747
3033
|
}
|
|
3034
|
+
finally {
|
|
3035
|
+
// -> Drop _temp_tables
|
|
3036
|
+
await this.dropUtil.dropTempTables(mDB, this._alterTables);
|
|
3037
|
+
// -> Do some cleanup
|
|
3038
|
+
this._alterTables = {};
|
|
3039
|
+
this._commonColumns = {};
|
|
3040
|
+
}
|
|
2748
3041
|
}
|
|
2749
3042
|
/**
|
|
2750
3043
|
* ExecuteSetProcess
|
|
@@ -2755,19 +3048,19 @@ class UtilsUpgrade {
|
|
|
2755
3048
|
async executeSetProcess(mDB, set, toVersion) {
|
|
2756
3049
|
try {
|
|
2757
3050
|
// -> load new data
|
|
2758
|
-
const lastId = await this.
|
|
3051
|
+
const lastId = await this.sqliteUtil.executeSet(mDB, set, false);
|
|
2759
3052
|
if (lastId < 0) {
|
|
2760
3053
|
return Promise.reject('ExecuteSetProcess: lastId ' + '< 0');
|
|
2761
3054
|
}
|
|
2762
3055
|
// -> update database version
|
|
2763
|
-
await this.
|
|
3056
|
+
await this.sqliteUtil.setVersion(mDB, toVersion);
|
|
2764
3057
|
// -> update syncDate if any
|
|
2765
|
-
const retB = await this.
|
|
3058
|
+
const retB = await this.jsonUtil.isTableExists(mDB, true, 'sync_table');
|
|
2766
3059
|
if (retB) {
|
|
2767
3060
|
const sDate = Math.round(new Date().getTime() / 1000);
|
|
2768
3061
|
let stmt = 'UPDATE sync_table SET ';
|
|
2769
3062
|
stmt += `sync_date = ${sDate} WHERE id = 1;`;
|
|
2770
|
-
const changes = await this.
|
|
3063
|
+
const changes = await this.sqliteUtil.execute(mDB, stmt, false);
|
|
2771
3064
|
if (changes < 0) {
|
|
2772
3065
|
return Promise.reject('ExecuteSetProcess: changes ' + '< 0');
|
|
2773
3066
|
}
|
|
@@ -2785,7 +3078,7 @@ class UtilsUpgrade {
|
|
|
2785
3078
|
async backupTables(mDB) {
|
|
2786
3079
|
const msg = 'BackupTables: ';
|
|
2787
3080
|
try {
|
|
2788
|
-
const tables = await this.
|
|
3081
|
+
const tables = await this.sqliteUtil.getTablesNames(mDB);
|
|
2789
3082
|
for (const table of tables) {
|
|
2790
3083
|
try {
|
|
2791
3084
|
await this.backupTable(mDB, table);
|
|
@@ -2808,18 +3101,22 @@ class UtilsUpgrade {
|
|
|
2808
3101
|
async backupTable(mDB, table) {
|
|
2809
3102
|
try {
|
|
2810
3103
|
// start a transaction
|
|
2811
|
-
await this.
|
|
3104
|
+
await this.sqliteUtil.beginTransaction(mDB, true);
|
|
2812
3105
|
// get the table's column names
|
|
2813
3106
|
const colNames = await this.getTableColumnNames(mDB, table);
|
|
2814
3107
|
this._alterTables[`${table}`] = colNames;
|
|
3108
|
+
const tmpTable = `_temp_${table}`;
|
|
3109
|
+
// Drop the tmpTable if exists
|
|
3110
|
+
const delStmt = `DROP TABLE IF EXISTS ${tmpTable};`;
|
|
3111
|
+
await this.sqliteUtil.prepareRun(mDB, delStmt, [], false);
|
|
2815
3112
|
// prefix the table with _temp_
|
|
2816
3113
|
let stmt = `ALTER TABLE ${table} RENAME `;
|
|
2817
|
-
stmt += `TO
|
|
2818
|
-
const lastId = await this.
|
|
3114
|
+
stmt += `TO ${tmpTable};`;
|
|
3115
|
+
const lastId = await this.sqliteUtil.prepareRun(mDB, stmt, [], false);
|
|
2819
3116
|
if (lastId < 0) {
|
|
2820
3117
|
let msg = 'BackupTable: lastId < 0';
|
|
2821
3118
|
try {
|
|
2822
|
-
await this.
|
|
3119
|
+
await this.sqliteUtil.rollbackTransaction(mDB, true);
|
|
2823
3120
|
}
|
|
2824
3121
|
catch (err) {
|
|
2825
3122
|
msg += `: ${err}`;
|
|
@@ -2828,7 +3125,7 @@ class UtilsUpgrade {
|
|
|
2828
3125
|
}
|
|
2829
3126
|
else {
|
|
2830
3127
|
try {
|
|
2831
|
-
await this.
|
|
3128
|
+
await this.sqliteUtil.commitTransaction(mDB, true);
|
|
2832
3129
|
}
|
|
2833
3130
|
catch (err) {
|
|
2834
3131
|
return Promise.reject('BackupTable: ' + `${err}`);
|
|
@@ -2850,7 +3147,7 @@ class UtilsUpgrade {
|
|
|
2850
3147
|
const retNames = [];
|
|
2851
3148
|
const query = `PRAGMA table_info('${tableName}');`;
|
|
2852
3149
|
try {
|
|
2853
|
-
resQuery = await this.
|
|
3150
|
+
resQuery = await this.sqliteUtil.queryAll(mDB, query, []);
|
|
2854
3151
|
if (resQuery.length > 0) {
|
|
2855
3152
|
for (const query of resQuery) {
|
|
2856
3153
|
retNames.push(query.name);
|
|
@@ -2869,7 +3166,7 @@ class UtilsUpgrade {
|
|
|
2869
3166
|
async findCommonColumns(mDB) {
|
|
2870
3167
|
try {
|
|
2871
3168
|
// Get new table list
|
|
2872
|
-
const tables = await this.
|
|
3169
|
+
const tables = await this.sqliteUtil.getTablesNames(mDB);
|
|
2873
3170
|
if (tables.length === 0) {
|
|
2874
3171
|
return Promise.reject('FindCommonColumns: get ' + "table's names failed");
|
|
2875
3172
|
}
|
|
@@ -2910,7 +3207,7 @@ class UtilsUpgrade {
|
|
|
2910
3207
|
async updateNewTablesData(mDB) {
|
|
2911
3208
|
try {
|
|
2912
3209
|
// start a transaction
|
|
2913
|
-
await this.
|
|
3210
|
+
await this.sqliteUtil.beginTransaction(mDB, true);
|
|
2914
3211
|
const statements = [];
|
|
2915
3212
|
const keys = Object.keys(this._commonColumns);
|
|
2916
3213
|
keys.forEach(key => {
|
|
@@ -2920,11 +3217,11 @@ class UtilsUpgrade {
|
|
|
2920
3217
|
stmt += `SELECT ${columns} FROM _temp_${key};`;
|
|
2921
3218
|
statements.push(stmt);
|
|
2922
3219
|
});
|
|
2923
|
-
const changes = await this.
|
|
3220
|
+
const changes = await this.sqliteUtil.execute(mDB, statements.join('\n'), false);
|
|
2924
3221
|
if (changes < 0) {
|
|
2925
3222
|
let msg = 'updateNewTablesData: ' + 'changes < 0';
|
|
2926
3223
|
try {
|
|
2927
|
-
await this.
|
|
3224
|
+
await this.sqliteUtil.rollbackTransaction(mDB, true);
|
|
2928
3225
|
}
|
|
2929
3226
|
catch (err) {
|
|
2930
3227
|
msg += `: ${err}`;
|
|
@@ -2933,7 +3230,7 @@ class UtilsUpgrade {
|
|
|
2933
3230
|
}
|
|
2934
3231
|
else {
|
|
2935
3232
|
try {
|
|
2936
|
-
await this.
|
|
3233
|
+
await this.sqliteUtil.commitTransaction(mDB, true);
|
|
2937
3234
|
return Promise.resolve();
|
|
2938
3235
|
}
|
|
2939
3236
|
catch (err) {
|
|
@@ -2954,7 +3251,6 @@ const exportToJson_1 = exportToJson;
|
|
|
2954
3251
|
const importFromJson_1 = importFromJson;
|
|
2955
3252
|
const utilsJson_1$1 = utilsJson;
|
|
2956
3253
|
//import { UtilsEncryption } from './utilsEncryption';
|
|
2957
|
-
const utilsDrop_1 = utilsDrop;
|
|
2958
3254
|
const utilsFile_1$1 = utilsFile;
|
|
2959
3255
|
const utilsSQLite_1 = utilsSQLite;
|
|
2960
3256
|
const utilsUpgrade_1 = utilsUpgrade;
|
|
@@ -2963,24 +3259,23 @@ class Database {
|
|
|
2963
3259
|
// encrypted: boolean,
|
|
2964
3260
|
// mode: string,
|
|
2965
3261
|
version, upgDict) {
|
|
2966
|
-
this.
|
|
2967
|
-
this.
|
|
2968
|
-
this.
|
|
2969
|
-
this._uDrop = new utilsDrop_1.UtilsDrop();
|
|
3262
|
+
this.fileUtil = new utilsFile_1$1.UtilsFile();
|
|
3263
|
+
this.sqliteUtil = new utilsSQLite_1.UtilsSQLite();
|
|
3264
|
+
this.jsonUtil = new utilsJson_1$1.UtilsJson();
|
|
2970
3265
|
// private _uGlobal: GlobalSQLite = new GlobalSQLite();
|
|
2971
3266
|
// private _uEncrypt: UtilsEncryption = new UtilsEncryption();
|
|
2972
|
-
this.
|
|
2973
|
-
this.
|
|
2974
|
-
this.
|
|
2975
|
-
this.
|
|
2976
|
-
this.
|
|
3267
|
+
this.upgradeUtil = new utilsUpgrade_1.UtilsUpgrade();
|
|
3268
|
+
this.importFromJsonUtil = new importFromJson_1.ImportFromJson();
|
|
3269
|
+
this.exportToJsonUtil = new exportToJson_1.ExportToJson();
|
|
3270
|
+
this.upgradeVersionDict = {};
|
|
3271
|
+
this.dbName = dbName;
|
|
2977
3272
|
// this._encrypted = encrypted;
|
|
2978
3273
|
// this._mode = mode;
|
|
2979
|
-
this.
|
|
2980
|
-
this.
|
|
2981
|
-
this.
|
|
2982
|
-
this.
|
|
2983
|
-
if (this.
|
|
3274
|
+
this.version = version;
|
|
3275
|
+
this.upgradeVersionDict = upgDict;
|
|
3276
|
+
this.pathDB = this.fileUtil.getFilePath(dbName);
|
|
3277
|
+
this._isDbOpen = false;
|
|
3278
|
+
if (this.pathDB.length === 0)
|
|
2984
3279
|
throw new Error('Could not generate a path to ' + dbName);
|
|
2985
3280
|
}
|
|
2986
3281
|
/**
|
|
@@ -2991,7 +3286,7 @@ class Database {
|
|
|
2991
3286
|
* @since 0.0.1
|
|
2992
3287
|
*/
|
|
2993
3288
|
isDBOpen() {
|
|
2994
|
-
return this.
|
|
3289
|
+
return this._isDbOpen;
|
|
2995
3290
|
}
|
|
2996
3291
|
/**
|
|
2997
3292
|
* Open
|
|
@@ -2999,7 +3294,7 @@ class Database {
|
|
|
2999
3294
|
* @returns Promise<boolean>
|
|
3000
3295
|
*/
|
|
3001
3296
|
async open() {
|
|
3002
|
-
this.
|
|
3297
|
+
this._isDbOpen = false;
|
|
3003
3298
|
// let password = '';
|
|
3004
3299
|
try {
|
|
3005
3300
|
/*
|
|
@@ -3021,34 +3316,34 @@ class Database {
|
|
|
3021
3316
|
await this._uEncrypt.encryptDatabase(this._pathDB, password);
|
|
3022
3317
|
}
|
|
3023
3318
|
*/
|
|
3024
|
-
this.
|
|
3319
|
+
this.database = await this.sqliteUtil.openOrCreateDatabase(this.pathDB /*,
|
|
3025
3320
|
password,*/);
|
|
3026
|
-
const curVersion = await this.
|
|
3027
|
-
this.
|
|
3028
|
-
if (this.
|
|
3029
|
-
Object.keys(this.
|
|
3321
|
+
const curVersion = await this.sqliteUtil.getVersion(this.database);
|
|
3322
|
+
this._isDbOpen = true;
|
|
3323
|
+
if (this.version > curVersion &&
|
|
3324
|
+
Object.keys(this.upgradeVersionDict).length > 0) {
|
|
3030
3325
|
try {
|
|
3031
3326
|
// execute the upgrade flow process
|
|
3032
|
-
await this.
|
|
3327
|
+
await this.upgradeUtil.onUpgrade(this.database, this.upgradeVersionDict, this.dbName, curVersion, this.version);
|
|
3033
3328
|
// delete the backup database
|
|
3034
|
-
await this.
|
|
3329
|
+
await this.fileUtil.deleteFileName(`backup-${this.dbName}`);
|
|
3035
3330
|
}
|
|
3036
3331
|
catch (err) {
|
|
3037
3332
|
// restore the database from backup
|
|
3038
3333
|
try {
|
|
3039
|
-
await this.
|
|
3334
|
+
await this.fileUtil.restoreFileName(this.dbName, 'backup');
|
|
3040
3335
|
}
|
|
3041
3336
|
catch (err) {
|
|
3042
|
-
|
|
3337
|
+
throw new Error(`Open: ${err}`);
|
|
3043
3338
|
}
|
|
3044
3339
|
}
|
|
3045
3340
|
}
|
|
3046
|
-
return
|
|
3341
|
+
return;
|
|
3047
3342
|
}
|
|
3048
3343
|
catch (err) {
|
|
3049
|
-
if (this.
|
|
3344
|
+
if (this._isDbOpen)
|
|
3050
3345
|
this.close();
|
|
3051
|
-
|
|
3346
|
+
throw new Error(`Open: ${err}`);
|
|
3052
3347
|
}
|
|
3053
3348
|
}
|
|
3054
3349
|
/**
|
|
@@ -3057,18 +3352,13 @@ class Database {
|
|
|
3057
3352
|
* @returns Promise<boolean>
|
|
3058
3353
|
*/
|
|
3059
3354
|
async close() {
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
this._isDBOpen = false;
|
|
3068
|
-
return Promise.resolve();
|
|
3069
|
-
});
|
|
3070
|
-
}
|
|
3071
|
-
return Promise.resolve();
|
|
3355
|
+
this.ensureDatabaseIsOpen();
|
|
3356
|
+
this.database.close((err) => {
|
|
3357
|
+
if (err) {
|
|
3358
|
+
throw new Error('Close failed: ${this.dbName} ${err}');
|
|
3359
|
+
}
|
|
3360
|
+
this._isDbOpen = false;
|
|
3361
|
+
});
|
|
3072
3362
|
}
|
|
3073
3363
|
/**
|
|
3074
3364
|
* GetVersion
|
|
@@ -3076,21 +3366,15 @@ class Database {
|
|
|
3076
3366
|
* @returns Promise<number>
|
|
3077
3367
|
*/
|
|
3078
3368
|
async getVersion() {
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
}
|
|
3084
|
-
catch (err) {
|
|
3085
|
-
if (this._isDBOpen)
|
|
3086
|
-
this.close();
|
|
3087
|
-
return Promise.reject(`getVersion: ${err}`);
|
|
3088
|
-
}
|
|
3369
|
+
this.ensureDatabaseIsOpen();
|
|
3370
|
+
try {
|
|
3371
|
+
const currentVersion = await this.sqliteUtil.getVersion(this.database);
|
|
3372
|
+
return currentVersion;
|
|
3089
3373
|
}
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
|
|
3374
|
+
catch (err) {
|
|
3375
|
+
if (this._isDbOpen)
|
|
3376
|
+
this.close();
|
|
3377
|
+
throw new Error(`getVersion: ${err}`);
|
|
3094
3378
|
}
|
|
3095
3379
|
}
|
|
3096
3380
|
/**
|
|
@@ -3101,14 +3385,14 @@ class Database {
|
|
|
3101
3385
|
*/
|
|
3102
3386
|
async deleteDB(dbName) {
|
|
3103
3387
|
// test if file exists
|
|
3104
|
-
const isExists = this.
|
|
3105
|
-
if (isExists && !this.
|
|
3388
|
+
const isExists = this.fileUtil.isFileExists(dbName);
|
|
3389
|
+
if (isExists && !this._isDbOpen) {
|
|
3106
3390
|
// open the database
|
|
3107
3391
|
try {
|
|
3108
3392
|
await this.open();
|
|
3109
3393
|
}
|
|
3110
3394
|
catch (err) {
|
|
3111
|
-
|
|
3395
|
+
throw new Error(`DeleteDB: ${err}`);
|
|
3112
3396
|
}
|
|
3113
3397
|
}
|
|
3114
3398
|
// close the database
|
|
@@ -3116,20 +3400,18 @@ class Database {
|
|
|
3116
3400
|
await this.close();
|
|
3117
3401
|
}
|
|
3118
3402
|
catch (err) {
|
|
3119
|
-
|
|
3403
|
+
throw new Error('DeleteDB: Close failed');
|
|
3120
3404
|
}
|
|
3121
3405
|
// delete the database
|
|
3122
3406
|
if (isExists) {
|
|
3123
3407
|
try {
|
|
3124
|
-
await this.
|
|
3408
|
+
await this.fileUtil.deleteFileName(dbName);
|
|
3125
3409
|
}
|
|
3126
3410
|
catch (err) {
|
|
3127
|
-
|
|
3128
|
-
msg += ` failed ${err}`;
|
|
3129
|
-
return Promise.reject(msg);
|
|
3411
|
+
throw new Error(`DeleteDB: deleteFile ${dbName} failed ${err}`);
|
|
3130
3412
|
}
|
|
3131
3413
|
}
|
|
3132
|
-
return
|
|
3414
|
+
return;
|
|
3133
3415
|
}
|
|
3134
3416
|
/**
|
|
3135
3417
|
* IsTableExists
|
|
@@ -3137,20 +3419,14 @@ class Database {
|
|
|
3137
3419
|
* @returns
|
|
3138
3420
|
*/
|
|
3139
3421
|
async isTableExists(tableName) {
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
}
|
|
3146
|
-
catch (err) {
|
|
3147
|
-
return Promise.reject(`IsTableExists: ${err}`);
|
|
3148
|
-
}
|
|
3422
|
+
this.ensureDatabaseIsOpen();
|
|
3423
|
+
const isOpen = this._isDbOpen;
|
|
3424
|
+
try {
|
|
3425
|
+
const tableExistsResult = await this.jsonUtil.isTableExists(this.database, isOpen, tableName);
|
|
3426
|
+
return tableExistsResult;
|
|
3149
3427
|
}
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
msg += `not opened`;
|
|
3153
|
-
return Promise.reject(msg);
|
|
3428
|
+
catch (err) {
|
|
3429
|
+
throw new Error(`IsTableExists: ${err}`);
|
|
3154
3430
|
}
|
|
3155
3431
|
}
|
|
3156
3432
|
/**
|
|
@@ -3159,18 +3435,14 @@ class Database {
|
|
|
3159
3435
|
* @returns Promise<number>
|
|
3160
3436
|
*/
|
|
3161
3437
|
async createSyncTable() {
|
|
3162
|
-
|
|
3163
|
-
let msg = `CreateSyncTable: Database ${this._dbName} `;
|
|
3164
|
-
msg += `not opened`;
|
|
3165
|
-
return Promise.reject(msg);
|
|
3166
|
-
}
|
|
3438
|
+
this.ensureDatabaseIsOpen();
|
|
3167
3439
|
let changes = -1;
|
|
3168
|
-
const isOpen = this.
|
|
3440
|
+
const isOpen = this._isDbOpen;
|
|
3169
3441
|
// check if the table has already being created
|
|
3170
3442
|
try {
|
|
3171
|
-
const retB = await this.
|
|
3443
|
+
const retB = await this.jsonUtil.isTableExists(this.database, isOpen, 'sync_table');
|
|
3172
3444
|
if (!retB) {
|
|
3173
|
-
const isLastModified = await this.
|
|
3445
|
+
const isLastModified = await this.sqliteUtil.isLastModified(this.database, isOpen);
|
|
3174
3446
|
if (isLastModified) {
|
|
3175
3447
|
const date = Math.round(new Date().getTime() / 1000);
|
|
3176
3448
|
let stmts = `
|
|
@@ -3180,23 +3452,22 @@ class Database {
|
|
|
3180
3452
|
);`;
|
|
3181
3453
|
stmts += `INSERT INTO sync_table (sync_date) VALUES (
|
|
3182
3454
|
"${date}");`;
|
|
3183
|
-
changes = await this.
|
|
3455
|
+
changes = await this.sqliteUtil.execute(this.database, stmts, false);
|
|
3184
3456
|
if (changes < 0) {
|
|
3185
|
-
|
|
3457
|
+
throw new Error(`CreateSyncTable: failed changes < 0`);
|
|
3186
3458
|
}
|
|
3187
3459
|
}
|
|
3188
3460
|
else {
|
|
3189
|
-
|
|
3461
|
+
throw new Error('No last_modified column in tables');
|
|
3190
3462
|
}
|
|
3191
3463
|
}
|
|
3192
3464
|
else {
|
|
3193
3465
|
changes = 0;
|
|
3194
3466
|
}
|
|
3195
|
-
|
|
3196
|
-
return Promise.resolve(changes);
|
|
3467
|
+
return changes;
|
|
3197
3468
|
}
|
|
3198
3469
|
catch (err) {
|
|
3199
|
-
|
|
3470
|
+
throw new Error(`CreateSyncTable: ${err}`);
|
|
3200
3471
|
}
|
|
3201
3472
|
}
|
|
3202
3473
|
/**
|
|
@@ -3206,20 +3477,16 @@ class Database {
|
|
|
3206
3477
|
* @returns Promise<{result: boolean, message: string}>
|
|
3207
3478
|
*/
|
|
3208
3479
|
async setSyncDate(syncDate) {
|
|
3209
|
-
|
|
3210
|
-
let msg = `SetSyncDate: Database ${this._dbName} `;
|
|
3211
|
-
msg += `not opened`;
|
|
3212
|
-
return { result: false, message: msg };
|
|
3213
|
-
}
|
|
3480
|
+
this.ensureDatabaseIsOpen();
|
|
3214
3481
|
try {
|
|
3215
|
-
const isTable = await this.
|
|
3482
|
+
const isTable = await this.jsonUtil.isTableExists(this.database, this._isDbOpen, 'sync_table');
|
|
3216
3483
|
if (!isTable) {
|
|
3217
|
-
|
|
3484
|
+
throw new Error('No sync_table available');
|
|
3218
3485
|
}
|
|
3219
|
-
const
|
|
3486
|
+
const syncDateUnixTimestamp = Math.round(new Date(syncDate).getTime() / 1000);
|
|
3220
3487
|
let stmt = `UPDATE sync_table SET sync_date = `;
|
|
3221
|
-
stmt += `${
|
|
3222
|
-
const changes = await this.
|
|
3488
|
+
stmt += `${syncDateUnixTimestamp} WHERE id = 1;`;
|
|
3489
|
+
const changes = await this.sqliteUtil.execute(this.database, stmt, false);
|
|
3223
3490
|
if (changes < 0) {
|
|
3224
3491
|
return { result: false, message: 'setSyncDate failed' };
|
|
3225
3492
|
}
|
|
@@ -3237,19 +3504,15 @@ class Database {
|
|
|
3237
3504
|
* @returns Promise<{syncDate: number, message: string}>
|
|
3238
3505
|
*/
|
|
3239
3506
|
async getSyncDate() {
|
|
3240
|
-
|
|
3241
|
-
let msg = `GetSyncDate: Database ${this._dbName} `;
|
|
3242
|
-
msg += `not opened`;
|
|
3243
|
-
return { syncDate: 0, message: msg };
|
|
3244
|
-
}
|
|
3507
|
+
this.ensureDatabaseIsOpen();
|
|
3245
3508
|
try {
|
|
3246
|
-
const isTable = await this.
|
|
3509
|
+
const isTable = await this.jsonUtil.isTableExists(this.database, this._isDbOpen, 'sync_table');
|
|
3247
3510
|
if (!isTable) {
|
|
3248
|
-
|
|
3511
|
+
throw new Error('No sync_table available');
|
|
3249
3512
|
}
|
|
3250
|
-
const syncDate = await this.
|
|
3513
|
+
const syncDate = await this.exportToJsonUtil.getSyncDate(this.database);
|
|
3251
3514
|
if (syncDate > 0) {
|
|
3252
|
-
return { syncDate
|
|
3515
|
+
return { syncDate };
|
|
3253
3516
|
}
|
|
3254
3517
|
else {
|
|
3255
3518
|
return { syncDate: 0, message: `setSyncDate failed` };
|
|
@@ -3266,32 +3529,31 @@ class Database {
|
|
|
3266
3529
|
* @returns Promise<number>
|
|
3267
3530
|
*/
|
|
3268
3531
|
async executeSQL(sql, transaction) {
|
|
3269
|
-
|
|
3270
|
-
let msg = `ExecuteSQL: Database ${this._dbName} `;
|
|
3271
|
-
msg += `not opened`;
|
|
3272
|
-
return Promise.reject(msg);
|
|
3273
|
-
}
|
|
3532
|
+
this.ensureDatabaseIsOpen();
|
|
3274
3533
|
try {
|
|
3275
|
-
if (transaction)
|
|
3276
|
-
await this.
|
|
3277
|
-
|
|
3534
|
+
if (transaction) {
|
|
3535
|
+
await this.sqliteUtil.beginTransaction(this.database, this._isDbOpen);
|
|
3536
|
+
}
|
|
3537
|
+
const changes = await this.sqliteUtil.execute(this.database, sql, false);
|
|
3278
3538
|
if (changes < 0) {
|
|
3279
|
-
|
|
3539
|
+
throw new Error('ExecuteSQL: changes < 0');
|
|
3280
3540
|
}
|
|
3281
|
-
if (transaction)
|
|
3282
|
-
await this.
|
|
3283
|
-
|
|
3541
|
+
if (transaction) {
|
|
3542
|
+
await this.sqliteUtil.commitTransaction(this.database, this._isDbOpen);
|
|
3543
|
+
}
|
|
3544
|
+
return changes;
|
|
3284
3545
|
}
|
|
3285
|
-
catch (
|
|
3286
|
-
let
|
|
3546
|
+
catch (executeError) {
|
|
3547
|
+
let message = `${executeError}`;
|
|
3287
3548
|
try {
|
|
3288
|
-
if (transaction)
|
|
3289
|
-
await this.
|
|
3549
|
+
if (transaction) {
|
|
3550
|
+
await this.sqliteUtil.rollbackTransaction(this.database, this._isDbOpen);
|
|
3551
|
+
}
|
|
3290
3552
|
}
|
|
3291
|
-
catch (
|
|
3292
|
-
|
|
3553
|
+
catch (rollbackErr) {
|
|
3554
|
+
message += ` : ${rollbackErr}`;
|
|
3293
3555
|
}
|
|
3294
|
-
|
|
3556
|
+
throw new Error(`ExecuteSQL: ${message}`);
|
|
3295
3557
|
}
|
|
3296
3558
|
}
|
|
3297
3559
|
/**
|
|
@@ -3302,17 +3564,13 @@ class Database {
|
|
|
3302
3564
|
* @returns Promise<any[]>
|
|
3303
3565
|
*/
|
|
3304
3566
|
async selectSQL(sql, values) {
|
|
3305
|
-
|
|
3306
|
-
let msg = `SelectSQL: Database ${this._dbName} `;
|
|
3307
|
-
msg += `not opened`;
|
|
3308
|
-
return Promise.reject(msg);
|
|
3309
|
-
}
|
|
3567
|
+
this.ensureDatabaseIsOpen();
|
|
3310
3568
|
try {
|
|
3311
|
-
const
|
|
3312
|
-
return
|
|
3569
|
+
const selectResult = await this.sqliteUtil.queryAll(this.database, sql, values);
|
|
3570
|
+
return selectResult;
|
|
3313
3571
|
}
|
|
3314
3572
|
catch (err) {
|
|
3315
|
-
|
|
3573
|
+
throw new Error(`SelectSQL: ${err}`);
|
|
3316
3574
|
}
|
|
3317
3575
|
}
|
|
3318
3576
|
/**
|
|
@@ -3323,39 +3581,40 @@ class Database {
|
|
|
3323
3581
|
* @returns Promise<{changes:number, lastId:number}>
|
|
3324
3582
|
*/
|
|
3325
3583
|
async runSQL(statement, values, transaction) {
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
msg += `not opened`;
|
|
3329
|
-
return Promise.reject(msg);
|
|
3330
|
-
}
|
|
3331
|
-
const retRes = { changes: -1, lastId: -1 };
|
|
3584
|
+
this.ensureDatabaseIsOpen();
|
|
3585
|
+
const result = { changes: -1, lastId: -1 };
|
|
3332
3586
|
let initChanges = -1;
|
|
3333
3587
|
try {
|
|
3334
|
-
initChanges = await this.
|
|
3588
|
+
initChanges = await this.sqliteUtil.dbChanges(this.database);
|
|
3335
3589
|
// start a transaction
|
|
3336
|
-
if (transaction)
|
|
3337
|
-
await this.
|
|
3590
|
+
if (transaction) {
|
|
3591
|
+
await this.sqliteUtil.beginTransaction(this.database, this._isDbOpen);
|
|
3592
|
+
}
|
|
3338
3593
|
}
|
|
3339
3594
|
catch (err) {
|
|
3340
|
-
|
|
3595
|
+
throw new Error(`RunSQL: ${err}`);
|
|
3341
3596
|
}
|
|
3342
3597
|
try {
|
|
3343
|
-
const lastId = await this.
|
|
3598
|
+
const lastId = await this.sqliteUtil.prepareRun(this.database, statement, values, false);
|
|
3344
3599
|
if (lastId < 0) {
|
|
3345
|
-
if (transaction)
|
|
3346
|
-
await this.
|
|
3347
|
-
|
|
3600
|
+
if (transaction) {
|
|
3601
|
+
await this.sqliteUtil.rollbackTransaction(this.database, this._isDbOpen);
|
|
3602
|
+
}
|
|
3603
|
+
throw new Error(`RunSQL: return LastId < 0`);
|
|
3604
|
+
}
|
|
3605
|
+
if (transaction) {
|
|
3606
|
+
await this.sqliteUtil.commitTransaction(this.database, this._isDbOpen);
|
|
3348
3607
|
}
|
|
3349
|
-
|
|
3350
|
-
await this.
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
return Promise.resolve(retRes);
|
|
3608
|
+
result.changes =
|
|
3609
|
+
(await this.sqliteUtil.dbChanges(this.database)) - initChanges;
|
|
3610
|
+
result.lastId = lastId;
|
|
3611
|
+
return result;
|
|
3354
3612
|
}
|
|
3355
3613
|
catch (err) {
|
|
3356
|
-
if (transaction)
|
|
3357
|
-
await this.
|
|
3358
|
-
|
|
3614
|
+
if (transaction) {
|
|
3615
|
+
await this.sqliteUtil.rollbackTransaction(this.database, this._isDbOpen);
|
|
3616
|
+
}
|
|
3617
|
+
throw new Error(`RunSQL: ${err}`);
|
|
3359
3618
|
}
|
|
3360
3619
|
}
|
|
3361
3620
|
/**
|
|
@@ -3365,103 +3624,124 @@ class Database {
|
|
|
3365
3624
|
* @returns Promise<{changes:number, lastId:number}>
|
|
3366
3625
|
*/
|
|
3367
3626
|
async execSet(set, transaction) {
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
msg += `not opened`;
|
|
3371
|
-
return Promise.reject(msg);
|
|
3372
|
-
}
|
|
3373
|
-
const retRes = { changes: -1, lastId: -1 };
|
|
3627
|
+
this.ensureDatabaseIsOpen();
|
|
3628
|
+
const result = { changes: -1, lastId: -1 };
|
|
3374
3629
|
let initChanges = -1;
|
|
3375
3630
|
try {
|
|
3376
|
-
initChanges = await this.
|
|
3631
|
+
initChanges = await this.sqliteUtil.dbChanges(this.database);
|
|
3377
3632
|
// start a transaction
|
|
3378
|
-
if (transaction)
|
|
3379
|
-
await this.
|
|
3633
|
+
if (transaction) {
|
|
3634
|
+
await this.sqliteUtil.beginTransaction(this.database, this._isDbOpen);
|
|
3635
|
+
}
|
|
3380
3636
|
}
|
|
3381
3637
|
catch (err) {
|
|
3382
|
-
|
|
3638
|
+
throw new Error(`ExecSet: ${err}`);
|
|
3383
3639
|
}
|
|
3384
3640
|
try {
|
|
3385
|
-
|
|
3386
|
-
if (transaction)
|
|
3387
|
-
await this.
|
|
3388
|
-
|
|
3389
|
-
|
|
3641
|
+
result.lastId = await this.sqliteUtil.executeSet(this.database, set, false);
|
|
3642
|
+
if (transaction) {
|
|
3643
|
+
await this.sqliteUtil.commitTransaction(this.database, this._isDbOpen);
|
|
3644
|
+
}
|
|
3645
|
+
result.changes =
|
|
3646
|
+
(await this.sqliteUtil.dbChanges(this.database)) - initChanges;
|
|
3647
|
+
return result;
|
|
3390
3648
|
}
|
|
3391
3649
|
catch (err) {
|
|
3392
|
-
const
|
|
3650
|
+
const message = err;
|
|
3393
3651
|
try {
|
|
3394
|
-
if (transaction)
|
|
3395
|
-
await this.
|
|
3652
|
+
if (transaction) {
|
|
3653
|
+
await this.sqliteUtil.rollbackTransaction(this.database, this._isDbOpen);
|
|
3654
|
+
}
|
|
3396
3655
|
}
|
|
3397
3656
|
catch (err) {
|
|
3398
|
-
|
|
3657
|
+
throw new Error(`ExecSet: ${message}: ` + `${err}`);
|
|
3399
3658
|
}
|
|
3400
3659
|
}
|
|
3401
3660
|
}
|
|
3402
|
-
async
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
return
|
|
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}`);
|
|
3407
3669
|
}
|
|
3670
|
+
}
|
|
3671
|
+
/**
|
|
3672
|
+
* GetTableList
|
|
3673
|
+
* get the table's list
|
|
3674
|
+
* @returns
|
|
3675
|
+
*/
|
|
3676
|
+
async getTableList() {
|
|
3677
|
+
this.ensureDatabaseIsOpen();
|
|
3408
3678
|
try {
|
|
3409
|
-
const
|
|
3410
|
-
return
|
|
3679
|
+
const tableNames = await this.sqliteUtil.getTablesNames(this.database);
|
|
3680
|
+
return tableNames;
|
|
3411
3681
|
}
|
|
3412
3682
|
catch (err) {
|
|
3413
|
-
|
|
3683
|
+
throw new Error(`GetTableList: ${err}`);
|
|
3414
3684
|
}
|
|
3415
3685
|
}
|
|
3416
3686
|
async importJson(jsonData) {
|
|
3417
3687
|
let changes = 0;
|
|
3418
|
-
|
|
3419
|
-
|
|
3420
|
-
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
|
|
3425
|
-
|
|
3426
|
-
|
|
3427
|
-
|
|
3428
|
-
if (jsonData.views && jsonData.views.length > 0) {
|
|
3429
|
-
// create the views
|
|
3430
|
-
changes += await this._iFJson.createViews(this._mDB, jsonData);
|
|
3688
|
+
this.ensureDatabaseIsOpen();
|
|
3689
|
+
try {
|
|
3690
|
+
// set Foreign Keys Off
|
|
3691
|
+
await this.sqliteUtil.setForeignKeyConstraintsEnabled(this.database, false);
|
|
3692
|
+
if (jsonData.tables && jsonData.tables.length > 0) {
|
|
3693
|
+
// create the database schema
|
|
3694
|
+
changes = await this.importFromJsonUtil.createDatabaseSchema(this.database, jsonData);
|
|
3695
|
+
if (changes != -1) {
|
|
3696
|
+
// create the tables data
|
|
3697
|
+
changes += await this.importFromJsonUtil.createTablesData(this.database, jsonData);
|
|
3431
3698
|
}
|
|
3432
|
-
return Promise.resolve(changes);
|
|
3433
3699
|
}
|
|
3434
|
-
|
|
3435
|
-
|
|
3700
|
+
if (jsonData.views && jsonData.views.length > 0) {
|
|
3701
|
+
// create the views
|
|
3702
|
+
changes += await this.importFromJsonUtil.createViews(this.database, jsonData);
|
|
3436
3703
|
}
|
|
3704
|
+
// set Foreign Keys On
|
|
3705
|
+
await this.sqliteUtil.setForeignKeyConstraintsEnabled(this.database, true);
|
|
3706
|
+
return changes;
|
|
3437
3707
|
}
|
|
3438
|
-
|
|
3439
|
-
|
|
3708
|
+
catch (err) {
|
|
3709
|
+
throw new Error(`ImportJson: ${err}`);
|
|
3440
3710
|
}
|
|
3441
3711
|
}
|
|
3442
3712
|
async exportJson(mode) {
|
|
3443
3713
|
const inJson = {};
|
|
3444
|
-
inJson.database = this.
|
|
3445
|
-
inJson.version = this.
|
|
3714
|
+
inJson.database = this.dbName.slice(0, -9);
|
|
3715
|
+
inJson.version = this.version;
|
|
3446
3716
|
inJson.encrypted = false;
|
|
3447
3717
|
inJson.mode = mode;
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
return Promise.reject(`ExportJson: retJson not valid`);
|
|
3457
|
-
}
|
|
3718
|
+
this.ensureDatabaseIsOpen();
|
|
3719
|
+
try {
|
|
3720
|
+
await this.exportToJsonUtil.setLastExportDate(this.database, new Date().toISOString());
|
|
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);
|
|
3458
3726
|
}
|
|
3459
|
-
|
|
3460
|
-
|
|
3727
|
+
const isValid = this.jsonUtil.isJsonSQLite(jsonResult);
|
|
3728
|
+
if (isValid) {
|
|
3729
|
+
return jsonResult;
|
|
3730
|
+
}
|
|
3731
|
+
else {
|
|
3732
|
+
throw new Error(`ExportJson: retJson not valid`);
|
|
3461
3733
|
}
|
|
3462
3734
|
}
|
|
3463
|
-
|
|
3464
|
-
|
|
3735
|
+
catch (err) {
|
|
3736
|
+
throw new Error(`ExportJson: ${err}`);
|
|
3737
|
+
}
|
|
3738
|
+
}
|
|
3739
|
+
/**
|
|
3740
|
+
* Throws an error if `this._isDbOpen` is `false`.
|
|
3741
|
+
*/
|
|
3742
|
+
ensureDatabaseIsOpen() {
|
|
3743
|
+
if (!this._isDbOpen || !this.database) {
|
|
3744
|
+
throw new Error(`getVersion: Database ${this.dbName} is not open yet. You should open it first.`);
|
|
3465
3745
|
}
|
|
3466
3746
|
}
|
|
3467
3747
|
}
|
|
@@ -3474,49 +3754,15 @@ const utilsJson_1 = utilsJson;
|
|
|
3474
3754
|
const utilsFile_1 = utilsFile;
|
|
3475
3755
|
class CapacitorSQLite {
|
|
3476
3756
|
constructor() {
|
|
3477
|
-
this.
|
|
3478
|
-
this.
|
|
3479
|
-
this.
|
|
3480
|
-
this.
|
|
3481
|
-
}
|
|
3482
|
-
async initWebStore() {
|
|
3483
|
-
return Promise.reject('Method not implemented.');
|
|
3484
|
-
}
|
|
3485
|
-
async saveToStore(options) {
|
|
3486
|
-
console.log(`${JSON.stringify(options)}`);
|
|
3487
|
-
return Promise.reject('Method not implemented.');
|
|
3488
|
-
}
|
|
3489
|
-
async isSecretStored() {
|
|
3490
|
-
return Promise.reject('Method not implemented.');
|
|
3491
|
-
}
|
|
3492
|
-
async setEncryptionSecret(options) {
|
|
3493
|
-
console.log(`${JSON.stringify(options)}`);
|
|
3494
|
-
return Promise.reject('Method not implemented.');
|
|
3495
|
-
}
|
|
3496
|
-
async changeEncryptionSecret(options) {
|
|
3497
|
-
console.log(`${JSON.stringify(options)}`);
|
|
3498
|
-
return Promise.reject('Method not implemented.');
|
|
3499
|
-
}
|
|
3500
|
-
async getNCDatabasePath(options) {
|
|
3501
|
-
console.log('getNCDatabasePath', options);
|
|
3502
|
-
return Promise.reject('Method not implemented.');
|
|
3503
|
-
}
|
|
3504
|
-
async createNCConnection(options) {
|
|
3505
|
-
console.log('createNCConnection', options);
|
|
3506
|
-
return Promise.reject('Method not implemented.');
|
|
3507
|
-
}
|
|
3508
|
-
async closeNCConnection(options) {
|
|
3509
|
-
console.log('closeNCConnection', options);
|
|
3510
|
-
return Promise.reject('Method not implemented.');
|
|
3511
|
-
}
|
|
3512
|
-
async isNCDatabase(options) {
|
|
3513
|
-
console.log('isNCDatabase', options);
|
|
3514
|
-
return Promise.reject('Method not implemented.');
|
|
3757
|
+
this.versionUpgrades = {};
|
|
3758
|
+
this.databases = {};
|
|
3759
|
+
this.fileUtil = new utilsFile_1.UtilsFile();
|
|
3760
|
+
this.jsonUtil = new utilsJson_1.UtilsJson();
|
|
3515
3761
|
}
|
|
3516
3762
|
async createConnection(options) {
|
|
3517
|
-
const
|
|
3518
|
-
if (!
|
|
3519
|
-
|
|
3763
|
+
const optionKeys = Object.keys(options);
|
|
3764
|
+
if (!optionKeys.includes('database')) {
|
|
3765
|
+
throw new Error('Must provide a database name');
|
|
3520
3766
|
}
|
|
3521
3767
|
const dbName = options.database;
|
|
3522
3768
|
const version = options.version ? options.version : 1;
|
|
@@ -3532,612 +3778,393 @@ class CapacitorSQLite {
|
|
|
3532
3778
|
? options.mode
|
|
3533
3779
|
: 'no-encryption';
|
|
3534
3780
|
*/
|
|
3535
|
-
let
|
|
3536
|
-
const
|
|
3537
|
-
if (
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
}
|
|
3549
|
-
catch (err) {
|
|
3550
|
-
return Promise.reject(err);
|
|
3551
|
-
}
|
|
3781
|
+
let upgrades = {};
|
|
3782
|
+
const versionUpgradeKeys = Object.keys(this.versionUpgrades);
|
|
3783
|
+
if (versionUpgradeKeys.length !== 0 &&
|
|
3784
|
+
versionUpgradeKeys.includes(dbName)) {
|
|
3785
|
+
upgrades = this.versionUpgrades[dbName];
|
|
3786
|
+
}
|
|
3787
|
+
const databaseConnection = new Database_1.Database(dbName + 'SQLite.db',
|
|
3788
|
+
/* encrypted,
|
|
3789
|
+
inMode,
|
|
3790
|
+
*/
|
|
3791
|
+
version, upgrades);
|
|
3792
|
+
this.databases[dbName] = databaseConnection;
|
|
3793
|
+
return;
|
|
3552
3794
|
}
|
|
3553
3795
|
async closeConnection(options) {
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
}
|
|
3558
|
-
const dbName = options.database;
|
|
3559
|
-
keys = Object.keys(this._dbDict);
|
|
3560
|
-
if (!keys.includes(dbName)) {
|
|
3561
|
-
return Promise.resolve();
|
|
3562
|
-
}
|
|
3563
|
-
const mDB = this._dbDict[dbName];
|
|
3564
|
-
if (mDB.isDBOpen()) {
|
|
3796
|
+
const dbName = this.getOptionValue(options, 'database');
|
|
3797
|
+
const database = this.getDatabaseConnectionOrThrowError(dbName);
|
|
3798
|
+
if (database.isDBOpen()) {
|
|
3565
3799
|
// close the database
|
|
3566
3800
|
try {
|
|
3567
|
-
await
|
|
3801
|
+
await database.close();
|
|
3568
3802
|
}
|
|
3569
3803
|
catch (err) {
|
|
3570
|
-
|
|
3571
|
-
'close ' +
|
|
3572
|
-
dbName +
|
|
3573
|
-
' failed ' +
|
|
3574
|
-
err);
|
|
3804
|
+
throw new Error(`CloseConnection command failed: close ${dbName} failed ${err.message}`);
|
|
3575
3805
|
}
|
|
3576
3806
|
}
|
|
3577
3807
|
// remove the connection from dictionary
|
|
3578
|
-
delete this.
|
|
3579
|
-
return Promise.resolve();
|
|
3808
|
+
delete this.databases[dbName];
|
|
3580
3809
|
}
|
|
3581
3810
|
async echo(options) {
|
|
3582
|
-
const
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
const ret = {};
|
|
3587
|
-
ret.value = options.value;
|
|
3588
|
-
return Promise.resolve(ret);
|
|
3811
|
+
const echoValue = this.getOptionValue(options, 'value');
|
|
3812
|
+
const echoResult = {};
|
|
3813
|
+
echoResult.value = echoValue;
|
|
3814
|
+
return echoResult;
|
|
3589
3815
|
}
|
|
3590
3816
|
async open(options) {
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
return Promise.reject('Must provide a database name');
|
|
3594
|
-
}
|
|
3595
|
-
const dbName = options.database;
|
|
3596
|
-
keys = Object.keys(this._dbDict);
|
|
3597
|
-
if (!keys.includes(dbName)) {
|
|
3598
|
-
return Promise.reject(`Open: No available connection for ${dbName}`);
|
|
3599
|
-
}
|
|
3600
|
-
const mDB = this._dbDict[dbName];
|
|
3817
|
+
const dbName = this.getOptionValue(options, 'database');
|
|
3818
|
+
const database = this.getDatabaseConnectionOrThrowError(dbName);
|
|
3601
3819
|
try {
|
|
3602
|
-
await
|
|
3603
|
-
return
|
|
3820
|
+
await database.open();
|
|
3821
|
+
return;
|
|
3604
3822
|
}
|
|
3605
3823
|
catch (err) {
|
|
3606
|
-
|
|
3824
|
+
throw new Error(`Open: ${err}`);
|
|
3607
3825
|
}
|
|
3608
3826
|
}
|
|
3609
3827
|
async close(options) {
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
return Promise.reject('Must provide a database name');
|
|
3613
|
-
}
|
|
3614
|
-
const dbName = options.database;
|
|
3615
|
-
keys = Object.keys(this._dbDict);
|
|
3616
|
-
if (!keys.includes(dbName)) {
|
|
3617
|
-
return Promise.reject(`Close: No available connection for ${dbName}`);
|
|
3618
|
-
}
|
|
3619
|
-
const mDB = this._dbDict[dbName];
|
|
3828
|
+
const dbName = this.getOptionValue(options, 'database');
|
|
3829
|
+
const database = this.getDatabaseConnectionOrThrowError(dbName);
|
|
3620
3830
|
try {
|
|
3621
|
-
await
|
|
3622
|
-
return
|
|
3831
|
+
await database.close();
|
|
3832
|
+
return;
|
|
3623
3833
|
}
|
|
3624
3834
|
catch (err) {
|
|
3625
|
-
|
|
3835
|
+
throw new Error(`Close: ${err}`);
|
|
3626
3836
|
}
|
|
3627
3837
|
}
|
|
3628
|
-
async getUrl() {
|
|
3629
|
-
return Promise.reject('Method not implemented.');
|
|
3630
|
-
}
|
|
3631
3838
|
async getVersion(options) {
|
|
3632
|
-
|
|
3633
|
-
|
|
3634
|
-
return Promise.reject('Must provide a database name');
|
|
3635
|
-
}
|
|
3636
|
-
const dbName = options.database;
|
|
3637
|
-
keys = Object.keys(this._dbDict);
|
|
3638
|
-
if (!keys.includes(dbName)) {
|
|
3639
|
-
return Promise.reject(`Open: No available connection for ${dbName}`);
|
|
3640
|
-
}
|
|
3641
|
-
const mDB = this._dbDict[dbName];
|
|
3839
|
+
const dbName = this.getOptionValue(options, 'database');
|
|
3840
|
+
const database = this.getDatabaseConnectionOrThrowError(dbName);
|
|
3642
3841
|
try {
|
|
3643
|
-
const version = await
|
|
3644
|
-
const
|
|
3645
|
-
|
|
3646
|
-
return
|
|
3842
|
+
const version = await database.getVersion();
|
|
3843
|
+
const versionResult = {};
|
|
3844
|
+
versionResult.version = version;
|
|
3845
|
+
return versionResult;
|
|
3647
3846
|
}
|
|
3648
3847
|
catch (err) {
|
|
3649
|
-
|
|
3848
|
+
throw new Error(`GetVersion: ${err}`);
|
|
3650
3849
|
}
|
|
3651
3850
|
}
|
|
3652
3851
|
async getTableList(options) {
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
return Promise.reject('Must provide a database name');
|
|
3656
|
-
}
|
|
3657
|
-
const dbName = options.database;
|
|
3658
|
-
keys = Object.keys(this._dbDict);
|
|
3659
|
-
if (!keys.includes(dbName)) {
|
|
3660
|
-
return Promise.reject(`Open: No available connection for ${dbName}`);
|
|
3661
|
-
}
|
|
3662
|
-
const mDB = this._dbDict[dbName];
|
|
3852
|
+
const dbName = this.getOptionValue(options, 'database');
|
|
3853
|
+
const database = this.getDatabaseConnectionOrThrowError(dbName);
|
|
3663
3854
|
try {
|
|
3664
|
-
const tableList = await
|
|
3665
|
-
const
|
|
3666
|
-
|
|
3667
|
-
return
|
|
3855
|
+
const tableList = await database.getTableList();
|
|
3856
|
+
const tableListResult = {};
|
|
3857
|
+
tableListResult.values = tableList;
|
|
3858
|
+
return tableListResult;
|
|
3668
3859
|
}
|
|
3669
3860
|
catch (err) {
|
|
3670
|
-
|
|
3861
|
+
throw new Error(`GetTableList: ${err}`);
|
|
3671
3862
|
}
|
|
3672
3863
|
}
|
|
3673
3864
|
async execute(options) {
|
|
3674
|
-
|
|
3675
|
-
|
|
3676
|
-
|
|
3677
|
-
|
|
3678
|
-
if (!keys.includes('statements') || options.statements.length === 0) {
|
|
3679
|
-
return Promise.reject('Must provide raw SQL statements');
|
|
3680
|
-
}
|
|
3681
|
-
const dbName = options.database;
|
|
3682
|
-
const statements = options.statements;
|
|
3683
|
-
let transaction;
|
|
3684
|
-
if (!keys.includes('transaction')) {
|
|
3685
|
-
transaction = true;
|
|
3686
|
-
}
|
|
3687
|
-
else {
|
|
3688
|
-
transaction = options.transaction;
|
|
3689
|
-
}
|
|
3690
|
-
keys = Object.keys(this._dbDict);
|
|
3691
|
-
if (!keys.includes(dbName)) {
|
|
3692
|
-
return Promise.reject(`Execute: No available connection for ${dbName}`);
|
|
3693
|
-
}
|
|
3694
|
-
const mDB = this._dbDict[dbName];
|
|
3865
|
+
const dbName = this.getOptionValue(options, 'database');
|
|
3866
|
+
const statements = this.getOptionValue(options, 'statements');
|
|
3867
|
+
const transaction = this.getOptionValue(options, 'transaction', true);
|
|
3868
|
+
const database = this.getDatabaseConnectionOrThrowError(dbName);
|
|
3695
3869
|
try {
|
|
3696
|
-
const
|
|
3697
|
-
if (
|
|
3698
|
-
|
|
3870
|
+
const executeResult = await database.executeSQL(statements, transaction);
|
|
3871
|
+
if (executeResult < 0) {
|
|
3872
|
+
throw new Error('Execute failed changes < 0');
|
|
3699
3873
|
}
|
|
3700
3874
|
else {
|
|
3701
|
-
return
|
|
3875
|
+
return { changes: { changes: executeResult } };
|
|
3702
3876
|
}
|
|
3703
3877
|
}
|
|
3704
3878
|
catch (err) {
|
|
3705
|
-
|
|
3879
|
+
throw new Error(`Execute failed: ${err}`);
|
|
3706
3880
|
}
|
|
3707
3881
|
}
|
|
3708
3882
|
async executeSet(options) {
|
|
3709
|
-
|
|
3710
|
-
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
if (!keys.includes('set') || options.set.length === 0) {
|
|
3714
|
-
return Promise.reject('Must provide a non-empty set of SQL statements');
|
|
3715
|
-
}
|
|
3716
|
-
const dbName = options.database;
|
|
3717
|
-
const setOfStatements = options.set;
|
|
3718
|
-
let transaction;
|
|
3719
|
-
if (!keys.includes('transaction')) {
|
|
3720
|
-
transaction = true;
|
|
3721
|
-
}
|
|
3722
|
-
else {
|
|
3723
|
-
transaction = options.transaction;
|
|
3724
|
-
}
|
|
3725
|
-
keys = Object.keys(this._dbDict);
|
|
3726
|
-
if (!keys.includes(dbName)) {
|
|
3727
|
-
return Promise.reject(`ExecuteSet: No available connection for ${dbName}`);
|
|
3728
|
-
}
|
|
3729
|
-
const mDB = this._dbDict[dbName];
|
|
3883
|
+
const dbName = this.getOptionValue(options, 'database');
|
|
3884
|
+
const setOfStatements = this.getOptionValue(options, 'set');
|
|
3885
|
+
const transaction = this.getOptionValue(options, 'transaction', true);
|
|
3886
|
+
const database = this.getDatabaseConnectionOrThrowError(dbName);
|
|
3730
3887
|
for (const sStmt of setOfStatements) {
|
|
3731
3888
|
if (!('statement' in sStmt) || !('values' in sStmt)) {
|
|
3732
|
-
|
|
3889
|
+
throw new Error('ExecuteSet: Must provide a set as ' + 'Array of {statement,values}');
|
|
3733
3890
|
}
|
|
3734
3891
|
}
|
|
3735
3892
|
try {
|
|
3736
|
-
const
|
|
3737
|
-
if (
|
|
3738
|
-
|
|
3893
|
+
const execSetResult = await database.execSet(setOfStatements, transaction);
|
|
3894
|
+
if (execSetResult < 0) {
|
|
3895
|
+
throw new Error(`ExecuteSet failed changes <0`);
|
|
3739
3896
|
}
|
|
3740
3897
|
else {
|
|
3741
|
-
return
|
|
3898
|
+
return { changes: execSetResult };
|
|
3742
3899
|
}
|
|
3743
3900
|
}
|
|
3744
3901
|
catch (err) {
|
|
3745
|
-
|
|
3902
|
+
throw new Error(`ExecuteSet failed: ${err}`);
|
|
3746
3903
|
}
|
|
3747
3904
|
}
|
|
3748
3905
|
async run(options) {
|
|
3749
|
-
|
|
3750
|
-
|
|
3751
|
-
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
return Promise.reject('Must provide a query statement');
|
|
3755
|
-
}
|
|
3756
|
-
if (!keys.includes('values')) {
|
|
3757
|
-
return Promise.reject('Must provide an Array of values');
|
|
3758
|
-
}
|
|
3759
|
-
const dbName = options.database;
|
|
3760
|
-
const statement = options.statement;
|
|
3761
|
-
const values = options.values.length > 0 ? options.values : [];
|
|
3762
|
-
let transaction;
|
|
3763
|
-
if (!keys.includes('transaction')) {
|
|
3764
|
-
transaction = true;
|
|
3765
|
-
}
|
|
3766
|
-
else {
|
|
3767
|
-
transaction = options.transaction;
|
|
3768
|
-
}
|
|
3769
|
-
keys = Object.keys(this._dbDict);
|
|
3770
|
-
if (!keys.includes(dbName)) {
|
|
3771
|
-
return Promise.reject(`Run: No available connection for ${dbName}`);
|
|
3772
|
-
}
|
|
3773
|
-
const mDB = this._dbDict[dbName];
|
|
3906
|
+
const dbName = this.getOptionValue(options, 'database');
|
|
3907
|
+
const statement = this.getOptionValue(options, 'statement');
|
|
3908
|
+
const values = this.getOptionValue(options, 'values', []);
|
|
3909
|
+
const transaction = this.getOptionValue(options, 'transaction', true);
|
|
3910
|
+
const database = this.getDatabaseConnectionOrThrowError(dbName);
|
|
3774
3911
|
try {
|
|
3775
|
-
const
|
|
3776
|
-
return
|
|
3912
|
+
const runResult = await database.runSQL(statement, values, transaction);
|
|
3913
|
+
return { changes: runResult };
|
|
3777
3914
|
}
|
|
3778
3915
|
catch (err) {
|
|
3779
|
-
|
|
3916
|
+
throw new Error(`RUN failed: ${err} `);
|
|
3780
3917
|
}
|
|
3781
3918
|
}
|
|
3782
3919
|
async query(options) {
|
|
3783
|
-
|
|
3784
|
-
|
|
3785
|
-
|
|
3786
|
-
|
|
3787
|
-
|
|
3788
|
-
return Promise.reject('Must provide a query statement');
|
|
3920
|
+
const dbName = this.getOptionValue(options, 'database');
|
|
3921
|
+
const statement = this.getOptionValue(options, 'statement');
|
|
3922
|
+
const values = this.getOptionValue(options, 'values', []);
|
|
3923
|
+
if (statement.length === 0) {
|
|
3924
|
+
throw new Error('Statement may not be an empty string.');
|
|
3789
3925
|
}
|
|
3790
|
-
|
|
3791
|
-
return Promise.reject('Must provide an Array of any');
|
|
3792
|
-
}
|
|
3793
|
-
const dbName = options.database;
|
|
3794
|
-
const statement = options.statement;
|
|
3795
|
-
const values = options.values.length > 0 ? options.values : [];
|
|
3796
|
-
keys = Object.keys(this._dbDict);
|
|
3797
|
-
if (!keys.includes(dbName)) {
|
|
3798
|
-
return Promise.reject(`Query: No available connection for ${dbName}`);
|
|
3799
|
-
}
|
|
3800
|
-
const mDB = this._dbDict[dbName];
|
|
3801
|
-
let ret = [];
|
|
3926
|
+
const database = this.getDatabaseConnectionOrThrowError(dbName);
|
|
3802
3927
|
try {
|
|
3803
|
-
|
|
3804
|
-
return
|
|
3928
|
+
const queryResult = await database.selectSQL(statement, values);
|
|
3929
|
+
return { values: queryResult };
|
|
3805
3930
|
}
|
|
3806
3931
|
catch (err) {
|
|
3807
|
-
|
|
3932
|
+
throw new Error(`Query failed: ${err}`);
|
|
3808
3933
|
}
|
|
3809
3934
|
}
|
|
3810
3935
|
async isDBExists(options) {
|
|
3811
|
-
|
|
3812
|
-
if
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
|
|
3816
|
-
keys = Object.keys(this._dbDict);
|
|
3817
|
-
if (!keys.includes(dbName)) {
|
|
3818
|
-
return Promise.reject('IsDBExists command failed: No available ' + 'connection for ' + dbName);
|
|
3819
|
-
}
|
|
3820
|
-
const isExists = this._uFile.isFileExists(dbName + 'SQLite.db');
|
|
3821
|
-
return Promise.resolve({
|
|
3822
|
-
result: isExists,
|
|
3823
|
-
});
|
|
3936
|
+
const dbName = this.getOptionValue(options, 'database');
|
|
3937
|
+
// Throw an error, if db connection is not opened yet:
|
|
3938
|
+
this.getDatabaseConnectionOrThrowError(dbName);
|
|
3939
|
+
const isExists = this.fileUtil.isFileExists(dbName + 'SQLite.db');
|
|
3940
|
+
return { result: isExists };
|
|
3824
3941
|
}
|
|
3825
3942
|
async isDBOpen(options) {
|
|
3826
|
-
|
|
3827
|
-
|
|
3828
|
-
|
|
3829
|
-
}
|
|
3830
|
-
const dbName = options.database;
|
|
3831
|
-
keys = Object.keys(this._dbDict);
|
|
3832
|
-
if (!keys.includes(dbName)) {
|
|
3833
|
-
return Promise.reject('isDBOpen command failed: No available ' + 'connection for ' + dbName);
|
|
3834
|
-
}
|
|
3835
|
-
const mDB = this._dbDict[dbName];
|
|
3836
|
-
const isOpen = await mDB.isDBOpen();
|
|
3837
|
-
return Promise.resolve({ result: isOpen });
|
|
3943
|
+
const dbName = this.getOptionValue(options, 'database');
|
|
3944
|
+
const database = this.getDatabaseConnectionOrThrowError(dbName);
|
|
3945
|
+
const isOpen = await database.isDBOpen();
|
|
3946
|
+
return { result: isOpen };
|
|
3838
3947
|
}
|
|
3839
3948
|
async isDatabase(options) {
|
|
3840
|
-
const
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
}
|
|
3844
|
-
const dbName = options.database;
|
|
3845
|
-
const isExists = this._uFile.isFileExists(dbName + 'SQLite.db');
|
|
3846
|
-
return Promise.resolve({
|
|
3847
|
-
result: isExists,
|
|
3848
|
-
});
|
|
3949
|
+
const dbName = this.getOptionValue(options, 'database');
|
|
3950
|
+
const isExists = this.fileUtil.isFileExists(dbName + 'SQLite.db');
|
|
3951
|
+
return { result: isExists };
|
|
3849
3952
|
}
|
|
3850
3953
|
async isTableExists(options) {
|
|
3851
|
-
|
|
3852
|
-
|
|
3853
|
-
|
|
3854
|
-
}
|
|
3855
|
-
const dbName = options.database;
|
|
3856
|
-
if (!keys.includes('table')) {
|
|
3857
|
-
return Promise.reject('Must provide a table name');
|
|
3858
|
-
}
|
|
3859
|
-
const tableName = options.table;
|
|
3860
|
-
keys = Object.keys(this._dbDict);
|
|
3861
|
-
if (!keys.includes(dbName)) {
|
|
3862
|
-
return Promise.reject('isTableExists command failed: No available ' +
|
|
3863
|
-
'connection for ' +
|
|
3864
|
-
dbName);
|
|
3865
|
-
}
|
|
3866
|
-
const mDB = this._dbDict[dbName];
|
|
3954
|
+
const dbName = this.getOptionValue(options, 'database');
|
|
3955
|
+
const tableName = this.getOptionValue(options, 'table');
|
|
3956
|
+
const database = this.getDatabaseConnectionOrThrowError(dbName);
|
|
3867
3957
|
try {
|
|
3868
|
-
const
|
|
3869
|
-
return
|
|
3958
|
+
const isTableExistsResult = await database.isTableExists(tableName);
|
|
3959
|
+
return { result: isTableExistsResult };
|
|
3870
3960
|
}
|
|
3871
3961
|
catch (err) {
|
|
3872
|
-
|
|
3962
|
+
throw new Error(`isTableExists: ${err}`);
|
|
3873
3963
|
}
|
|
3874
3964
|
}
|
|
3875
3965
|
async deleteDatabase(options) {
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
return Promise.reject('Must provide a database name');
|
|
3879
|
-
}
|
|
3880
|
-
const dbName = options.database;
|
|
3881
|
-
keys = Object.keys(this._dbDict);
|
|
3882
|
-
if (!keys.includes(dbName)) {
|
|
3883
|
-
return Promise.reject('deleteDatabase: No available connection for ' + `${dbName}`);
|
|
3884
|
-
}
|
|
3885
|
-
const mDB = this._dbDict[dbName];
|
|
3966
|
+
const dbName = this.getOptionValue(options, 'database');
|
|
3967
|
+
const database = this.getDatabaseConnectionOrThrowError(dbName);
|
|
3886
3968
|
try {
|
|
3887
|
-
await
|
|
3888
|
-
return
|
|
3969
|
+
await database.deleteDB(dbName + 'SQLite.db');
|
|
3970
|
+
return;
|
|
3889
3971
|
}
|
|
3890
3972
|
catch (err) {
|
|
3891
|
-
|
|
3973
|
+
throw new Error(`Delete: ${err}`);
|
|
3892
3974
|
}
|
|
3893
3975
|
}
|
|
3894
3976
|
async isJsonValid(options) {
|
|
3895
|
-
const
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
}
|
|
3899
|
-
const jsonStrObj = options.jsonstring;
|
|
3900
|
-
const jsonObj = JSON.parse(jsonStrObj);
|
|
3901
|
-
const isValid = this._uJson.isJsonSQLite(jsonObj);
|
|
3977
|
+
const jsonString = this.getOptionValue(options, 'jsonstring');
|
|
3978
|
+
const jsonObj = JSON.parse(jsonString);
|
|
3979
|
+
const isValid = this.jsonUtil.isJsonSQLite(jsonObj);
|
|
3902
3980
|
if (!isValid) {
|
|
3903
|
-
|
|
3981
|
+
throw new Error('Stringify Json Object not Valid');
|
|
3904
3982
|
}
|
|
3905
3983
|
else {
|
|
3906
|
-
return
|
|
3984
|
+
return { result: true };
|
|
3907
3985
|
}
|
|
3908
3986
|
}
|
|
3909
3987
|
async importFromJson(options) {
|
|
3910
3988
|
var _a, _b;
|
|
3911
|
-
const
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
}
|
|
3915
|
-
const jsonStrObj = options.jsonstring;
|
|
3916
|
-
const jsonObj = JSON.parse(jsonStrObj);
|
|
3917
|
-
const isValid = this._uJson.isJsonSQLite(jsonObj);
|
|
3989
|
+
const jsonString = this.getOptionValue(options, 'jsonstring');
|
|
3990
|
+
const jsonObj = JSON.parse(jsonString);
|
|
3991
|
+
const isValid = this.jsonUtil.isJsonSQLite(jsonObj);
|
|
3918
3992
|
if (!isValid) {
|
|
3919
|
-
|
|
3993
|
+
throw new Error('Must provide a valid JsonSQLite Object');
|
|
3920
3994
|
}
|
|
3921
3995
|
const vJsonObj = jsonObj;
|
|
3922
3996
|
const dbName = `${vJsonObj.database}SQLite.db`;
|
|
3923
|
-
const
|
|
3997
|
+
const targetDbVersion = (_a = vJsonObj.version) !== null && _a !== void 0 ? _a : 1;
|
|
3924
3998
|
const mode = vJsonObj.mode;
|
|
3925
3999
|
const overwrite = (_b = vJsonObj.overwrite) !== null && _b !== void 0 ? _b : false;
|
|
3926
4000
|
// const encrypted: boolean = vJsonObj.encrypted ?? false;
|
|
3927
4001
|
// const mode: string = encrypted ? 'secret' : 'no-encryption';
|
|
3928
4002
|
// Create the database
|
|
3929
|
-
const
|
|
3930
|
-
/*encrypted, mode, */
|
|
4003
|
+
const database = new Database_1.Database(dbName,
|
|
4004
|
+
/*encrypted, mode, */
|
|
4005
|
+
targetDbVersion, {});
|
|
3931
4006
|
try {
|
|
3932
4007
|
if (overwrite && mode === 'full') {
|
|
3933
|
-
const isExists = this.
|
|
4008
|
+
const isExists = this.fileUtil.isFileExists(dbName);
|
|
3934
4009
|
if (isExists) {
|
|
3935
|
-
await this.
|
|
4010
|
+
await this.fileUtil.deleteFileName(dbName);
|
|
3936
4011
|
}
|
|
3937
4012
|
}
|
|
3938
4013
|
// Open the database
|
|
3939
|
-
await
|
|
3940
|
-
const tableList = await
|
|
4014
|
+
await database.open();
|
|
4015
|
+
const tableList = await database.getTableList();
|
|
3941
4016
|
if (mode === 'full' && tableList.length > 0) {
|
|
3942
|
-
const
|
|
3943
|
-
if (
|
|
3944
|
-
|
|
4017
|
+
const currentVersion = await database.getVersion();
|
|
4018
|
+
if (targetDbVersion < currentVersion) {
|
|
4019
|
+
throw new Error(`ImportFromJson: Cannot import a version lower than ${currentVersion}`);
|
|
3945
4020
|
}
|
|
3946
|
-
if (
|
|
3947
|
-
return
|
|
4021
|
+
if (currentVersion === targetDbVersion) {
|
|
4022
|
+
return { changes: { changes: 0 } };
|
|
3948
4023
|
}
|
|
3949
4024
|
}
|
|
3950
4025
|
// Import the JsonSQLite Object
|
|
3951
|
-
const changes = await
|
|
4026
|
+
const changes = await database.importJson(vJsonObj);
|
|
3952
4027
|
// Close the database
|
|
3953
|
-
await
|
|
3954
|
-
return
|
|
4028
|
+
await database.close();
|
|
4029
|
+
return { changes: { changes: changes } };
|
|
3955
4030
|
}
|
|
3956
4031
|
catch (err) {
|
|
3957
|
-
|
|
4032
|
+
throw new Error(`ImportFromJson: ${err}`);
|
|
3958
4033
|
}
|
|
3959
4034
|
}
|
|
3960
4035
|
async exportToJson(options) {
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
|
|
3964
|
-
}
|
|
3965
|
-
if (!keys.includes('jsonexportmode')) {
|
|
3966
|
-
return Promise.reject('Must provide a json export mode');
|
|
3967
|
-
}
|
|
3968
|
-
const dbName = options.database;
|
|
3969
|
-
const exportMode = options.jsonexportmode;
|
|
3970
|
-
keys = Object.keys(this._dbDict);
|
|
3971
|
-
if (!keys.includes(dbName)) {
|
|
3972
|
-
return Promise.reject('exportToJson: No available connection for ' + `${dbName}`);
|
|
3973
|
-
}
|
|
3974
|
-
const mDB = this._dbDict[dbName];
|
|
4036
|
+
const dbName = this.getOptionValue(options, 'database');
|
|
4037
|
+
const exportMode = this.getOptionValue(options, 'jsonexportmode');
|
|
4038
|
+
const database = this.getDatabaseConnectionOrThrowError(dbName);
|
|
3975
4039
|
try {
|
|
3976
|
-
const
|
|
3977
|
-
const
|
|
3978
|
-
if (
|
|
3979
|
-
|
|
4040
|
+
const exportJsonResult = await database.exportJson(exportMode);
|
|
4041
|
+
const resultKeys = Object.keys(exportJsonResult);
|
|
4042
|
+
if (resultKeys.includes('message')) {
|
|
4043
|
+
throw new Error(`exportToJson: ${exportJsonResult.message}`);
|
|
3980
4044
|
}
|
|
3981
4045
|
else {
|
|
3982
|
-
return
|
|
4046
|
+
return { export: exportJsonResult };
|
|
3983
4047
|
}
|
|
3984
4048
|
}
|
|
3985
4049
|
catch (err) {
|
|
3986
|
-
|
|
4050
|
+
throw new Error(`exportToJson: ${err}`);
|
|
3987
4051
|
}
|
|
3988
4052
|
}
|
|
3989
4053
|
async createSyncTable(options) {
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
return Promise.reject('Must provide a database name');
|
|
3993
|
-
}
|
|
3994
|
-
const dbName = options.database;
|
|
3995
|
-
keys = Object.keys(this._dbDict);
|
|
3996
|
-
if (!keys.includes(dbName)) {
|
|
3997
|
-
return Promise.reject('CreateSyncTable: No available connection for ' + `${dbName}`);
|
|
3998
|
-
}
|
|
3999
|
-
const mDB = this._dbDict[dbName];
|
|
4054
|
+
const dbName = this.getOptionValue(options, 'database');
|
|
4055
|
+
const database = this.getDatabaseConnectionOrThrowError(dbName);
|
|
4000
4056
|
try {
|
|
4001
|
-
const
|
|
4002
|
-
return
|
|
4057
|
+
const createTableSyncResult = await database.createSyncTable();
|
|
4058
|
+
return {
|
|
4059
|
+
changes: { changes: createTableSyncResult },
|
|
4060
|
+
};
|
|
4003
4061
|
}
|
|
4004
4062
|
catch (err) {
|
|
4005
|
-
|
|
4063
|
+
throw new Error(`createSyncTable: ${err}`);
|
|
4006
4064
|
}
|
|
4007
4065
|
}
|
|
4008
4066
|
async setSyncDate(options) {
|
|
4009
|
-
|
|
4010
|
-
|
|
4011
|
-
|
|
4012
|
-
}
|
|
4013
|
-
if (!keys.includes('syncdate')) {
|
|
4014
|
-
return Promise.reject('Must provide a synchronization date');
|
|
4015
|
-
}
|
|
4016
|
-
const dbName = options.database;
|
|
4017
|
-
const syncDate = options.syncdate;
|
|
4018
|
-
keys = Object.keys(this._dbDict);
|
|
4019
|
-
if (!keys.includes(dbName)) {
|
|
4020
|
-
return Promise.reject(`SetSyncDate: No available connection for ${dbName}`);
|
|
4021
|
-
}
|
|
4022
|
-
const mDB = this._dbDict[dbName];
|
|
4067
|
+
const dbName = this.getOptionValue(options, 'database');
|
|
4068
|
+
const syncDate = this.getOptionValue(options, 'syncdate');
|
|
4069
|
+
const database = this.getDatabaseConnectionOrThrowError(dbName);
|
|
4023
4070
|
try {
|
|
4024
|
-
await
|
|
4025
|
-
return
|
|
4071
|
+
await database.setSyncDate(syncDate);
|
|
4072
|
+
return;
|
|
4026
4073
|
}
|
|
4027
4074
|
catch (err) {
|
|
4028
|
-
|
|
4075
|
+
throw new Error(`SetSyncDate: ${err}`);
|
|
4029
4076
|
}
|
|
4030
4077
|
}
|
|
4031
4078
|
async getSyncDate(options) {
|
|
4032
|
-
|
|
4033
|
-
|
|
4034
|
-
return Promise.reject('Must provide a database name');
|
|
4035
|
-
}
|
|
4036
|
-
const dbName = options.database;
|
|
4037
|
-
keys = Object.keys(this._dbDict);
|
|
4038
|
-
if (!keys.includes(dbName)) {
|
|
4039
|
-
return Promise.reject(`GetSyncDate: No available connection for ${dbName}`);
|
|
4040
|
-
}
|
|
4041
|
-
const mDB = this._dbDict[dbName];
|
|
4079
|
+
const dbName = this.getOptionValue(options, 'database');
|
|
4080
|
+
const database = this.getDatabaseConnectionOrThrowError(dbName);
|
|
4042
4081
|
try {
|
|
4043
|
-
const ret = await
|
|
4082
|
+
const ret = await database.getSyncDate();
|
|
4044
4083
|
return Promise.resolve(ret);
|
|
4045
4084
|
}
|
|
4046
4085
|
catch (err) {
|
|
4047
|
-
|
|
4086
|
+
throw new Error(`GetSyncDate: ${err}`);
|
|
4048
4087
|
}
|
|
4049
4088
|
}
|
|
4050
|
-
async
|
|
4051
|
-
|
|
4052
|
-
|
|
4053
|
-
|
|
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();
|
|
4054
4095
|
}
|
|
4055
|
-
|
|
4056
|
-
|
|
4096
|
+
catch (err) {
|
|
4097
|
+
throw new Error(`DeleteExportedRows: ${err}`);
|
|
4057
4098
|
}
|
|
4058
|
-
|
|
4059
|
-
|
|
4060
|
-
|
|
4061
|
-
|
|
4062
|
-
|
|
4063
|
-
|
|
4064
|
-
|
|
4065
|
-
|
|
4066
|
-
|
|
4067
|
-
|
|
4068
|
-
}
|
|
4069
|
-
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
|
|
4099
|
+
}
|
|
4100
|
+
async addUpgradeStatement(options) {
|
|
4101
|
+
const dbName = this.getOptionValue(options, 'database');
|
|
4102
|
+
const upgrades = this.getOptionValue(options, 'upgrade');
|
|
4103
|
+
const firstUpgrade = upgrades[0];
|
|
4104
|
+
const versionUpgradeKeys = Object.keys(firstUpgrade);
|
|
4105
|
+
if (!versionUpgradeKeys.includes('fromVersion') ||
|
|
4106
|
+
!versionUpgradeKeys.includes('toVersion') ||
|
|
4107
|
+
!versionUpgradeKeys.includes('statement')) {
|
|
4108
|
+
throw new Error('Must provide an upgrade capSQLiteVersionUpgrade Object');
|
|
4109
|
+
}
|
|
4110
|
+
if (typeof firstUpgrade.fromVersion != 'number') {
|
|
4111
|
+
throw new Error('upgrade.fromVersion must be a number');
|
|
4112
|
+
}
|
|
4113
|
+
const upgradeVersionDict = {};
|
|
4114
|
+
upgradeVersionDict[firstUpgrade.fromVersion] = firstUpgrade;
|
|
4115
|
+
this.versionUpgrades[dbName] = upgradeVersionDict;
|
|
4116
|
+
return;
|
|
4073
4117
|
}
|
|
4074
4118
|
async copyFromAssets(options) {
|
|
4075
|
-
const
|
|
4076
|
-
const mOverwrite = keys.includes('overwrite') ? options.overwrite : true;
|
|
4119
|
+
const overwrite = this.getOptionValue(options, 'overwrite', false);
|
|
4077
4120
|
// check if the assets/database folder exists
|
|
4078
|
-
const assetsDbPath = this.
|
|
4079
|
-
const
|
|
4080
|
-
if (
|
|
4121
|
+
const assetsDbPath = this.fileUtil.getAssetsDatabasesPath();
|
|
4122
|
+
const pathExists = this.fileUtil.isPathExists(assetsDbPath);
|
|
4123
|
+
if (pathExists) {
|
|
4081
4124
|
// get the database files
|
|
4082
|
-
const dbList = await this.
|
|
4125
|
+
const dbList = await this.fileUtil.getFileList(assetsDbPath);
|
|
4083
4126
|
// loop through the database files
|
|
4084
4127
|
dbList.forEach(async (db) => {
|
|
4085
4128
|
if (db.substring(db.length - 3) === '.db') {
|
|
4086
4129
|
// for each copy the file to the Application database folder
|
|
4087
|
-
await this.
|
|
4130
|
+
await this.fileUtil.copyFromAssetToDatabase(db, overwrite);
|
|
4088
4131
|
}
|
|
4089
4132
|
if (db.substring(db.length - 4) === '.zip') {
|
|
4090
|
-
await this.
|
|
4133
|
+
await this.fileUtil.unzipDatabase(db, overwrite);
|
|
4091
4134
|
}
|
|
4092
4135
|
});
|
|
4093
|
-
return
|
|
4136
|
+
return;
|
|
4094
4137
|
}
|
|
4095
4138
|
else {
|
|
4096
|
-
|
|
4139
|
+
throw new Error('CopyFromAssets: assets/databases folder does not exist');
|
|
4097
4140
|
}
|
|
4098
4141
|
}
|
|
4099
4142
|
async getDatabaseList() {
|
|
4100
4143
|
// get the database folder
|
|
4101
|
-
const pathDatabase = this.
|
|
4144
|
+
const pathDatabase = this.fileUtil.getDatabasesPath();
|
|
4102
4145
|
// get the list of databases
|
|
4103
|
-
const files = await this.
|
|
4146
|
+
const files = await this.fileUtil.getFileList(pathDatabase);
|
|
4104
4147
|
if (files.length > 0) {
|
|
4105
|
-
return
|
|
4148
|
+
return { values: files };
|
|
4106
4149
|
}
|
|
4107
4150
|
else {
|
|
4108
|
-
|
|
4151
|
+
throw new Error(`isTableExists: No databases found`);
|
|
4109
4152
|
}
|
|
4110
4153
|
}
|
|
4111
|
-
async getMigratableDbList(options) {
|
|
4112
|
-
console.log('getCordovaDbList', options);
|
|
4113
|
-
return Promise.reject('Method not implemented.');
|
|
4114
|
-
}
|
|
4115
|
-
async addSQLiteSuffix(options) {
|
|
4116
|
-
console.log(`${JSON.stringify(options)}`);
|
|
4117
|
-
throw new Error('Method not implemented.');
|
|
4118
|
-
}
|
|
4119
|
-
async deleteOldDatabases(options) {
|
|
4120
|
-
console.log(`${JSON.stringify(options)}`);
|
|
4121
|
-
throw new Error('Method not implemented.');
|
|
4122
|
-
}
|
|
4123
4154
|
async checkConnectionsConsistency(options) {
|
|
4124
|
-
const
|
|
4125
|
-
|
|
4126
|
-
|
|
4127
|
-
}
|
|
4128
|
-
const dbNames = options.dbNames;
|
|
4129
|
-
const ret = {};
|
|
4130
|
-
ret.result = false;
|
|
4155
|
+
const dbNames = this.getOptionValue(options, 'dbNames');
|
|
4156
|
+
const checkConsistencyResult = {};
|
|
4157
|
+
checkConsistencyResult.result = false;
|
|
4131
4158
|
try {
|
|
4132
|
-
let inConnectionsSet = new Set(Object.keys(this.
|
|
4159
|
+
let inConnectionsSet = new Set(Object.keys(this.databases));
|
|
4133
4160
|
const outConnectionSet = new Set(dbNames);
|
|
4134
4161
|
if (outConnectionSet.size === 0) {
|
|
4135
|
-
await this.resetDbDict(Object.keys(this.
|
|
4136
|
-
return Promise.resolve(
|
|
4162
|
+
await this.resetDbDict(Object.keys(this.databases));
|
|
4163
|
+
return Promise.resolve(checkConsistencyResult);
|
|
4137
4164
|
}
|
|
4138
4165
|
if (inConnectionsSet.size < outConnectionSet.size) {
|
|
4139
|
-
await this.resetDbDict(Object.keys(this.
|
|
4140
|
-
return Promise.resolve(
|
|
4166
|
+
await this.resetDbDict(Object.keys(this.databases));
|
|
4167
|
+
return Promise.resolve(checkConsistencyResult);
|
|
4141
4168
|
}
|
|
4142
4169
|
if (inConnectionsSet.size > outConnectionSet.size) {
|
|
4143
4170
|
for (const key of inConnectionsSet) {
|
|
@@ -4148,25 +4175,25 @@ class CapacitorSQLite {
|
|
|
4148
4175
|
}
|
|
4149
4176
|
}
|
|
4150
4177
|
}
|
|
4151
|
-
inConnectionsSet = new Set(Object.keys(this.
|
|
4178
|
+
inConnectionsSet = new Set(Object.keys(this.databases));
|
|
4152
4179
|
if (inConnectionsSet.size === outConnectionSet.size) {
|
|
4153
|
-
const
|
|
4154
|
-
if (
|
|
4155
|
-
|
|
4156
|
-
return
|
|
4180
|
+
const symmetricDifferenceSet = await this.symmetricDifference(inConnectionsSet, outConnectionSet);
|
|
4181
|
+
if (symmetricDifferenceSet.size === 0) {
|
|
4182
|
+
checkConsistencyResult.result = true;
|
|
4183
|
+
return checkConsistencyResult;
|
|
4157
4184
|
}
|
|
4158
4185
|
else {
|
|
4159
|
-
await this.resetDbDict(Object.keys(this.
|
|
4160
|
-
return
|
|
4186
|
+
await this.resetDbDict(Object.keys(this.databases));
|
|
4187
|
+
return checkConsistencyResult;
|
|
4161
4188
|
}
|
|
4162
4189
|
}
|
|
4163
4190
|
else {
|
|
4164
|
-
await this.resetDbDict(Object.keys(this.
|
|
4165
|
-
return
|
|
4191
|
+
await this.resetDbDict(Object.keys(this.databases));
|
|
4192
|
+
return checkConsistencyResult;
|
|
4166
4193
|
}
|
|
4167
4194
|
}
|
|
4168
4195
|
catch (err) {
|
|
4169
|
-
|
|
4196
|
+
throw new Error(`CheckConnectionsConsistency: ${err}`);
|
|
4170
4197
|
}
|
|
4171
4198
|
}
|
|
4172
4199
|
async resetDbDict(keys) {
|
|
@@ -4178,7 +4205,7 @@ class CapacitorSQLite {
|
|
|
4178
4205
|
}
|
|
4179
4206
|
}
|
|
4180
4207
|
catch (err) {
|
|
4181
|
-
|
|
4208
|
+
throw new Error(`ResetDbDict: ${err}`);
|
|
4182
4209
|
}
|
|
4183
4210
|
}
|
|
4184
4211
|
async symmetricDifference(setA, setB) {
|
|
@@ -4191,7 +4218,95 @@ class CapacitorSQLite {
|
|
|
4191
4218
|
difference.add(elem);
|
|
4192
4219
|
}
|
|
4193
4220
|
}
|
|
4194
|
-
return
|
|
4221
|
+
return difference;
|
|
4222
|
+
}
|
|
4223
|
+
/**
|
|
4224
|
+
* Returns a database connection, if it already exists.
|
|
4225
|
+
* If the conneciton does not exist yet, it throws an error.
|
|
4226
|
+
*
|
|
4227
|
+
* @param dbName
|
|
4228
|
+
* @returns
|
|
4229
|
+
*/
|
|
4230
|
+
getDatabaseConnectionOrThrowError(dbName) {
|
|
4231
|
+
const databaseNames = Object.keys(this.databases);
|
|
4232
|
+
if (!databaseNames.includes(dbName)) {
|
|
4233
|
+
throw new Error(`No connection available for database "${dbName}"`);
|
|
4234
|
+
}
|
|
4235
|
+
return this.databases[dbName];
|
|
4236
|
+
}
|
|
4237
|
+
/**
|
|
4238
|
+
* Gets the value of an option from the options object.
|
|
4239
|
+
* If the `optionKey` does not exist and there is no `defaultValue` defined, an exception is thrown.
|
|
4240
|
+
* If the `optionKey` does not exist but there is a `defaultValue`, the `defaultValue` is returned.
|
|
4241
|
+
*
|
|
4242
|
+
* @param options
|
|
4243
|
+
* @param optionKey
|
|
4244
|
+
* @param defaultValue
|
|
4245
|
+
* @returns
|
|
4246
|
+
*/
|
|
4247
|
+
getOptionValue(options, optionKey, defaultValue = undefined) {
|
|
4248
|
+
const optionKeys = Object.keys(options);
|
|
4249
|
+
if (!optionKeys.includes(optionKey)) {
|
|
4250
|
+
if (defaultValue === undefined) {
|
|
4251
|
+
throw new Error(`Must provide "${optionKey}" in options.`);
|
|
4252
|
+
}
|
|
4253
|
+
else {
|
|
4254
|
+
return defaultValue;
|
|
4255
|
+
}
|
|
4256
|
+
}
|
|
4257
|
+
return options[optionKey];
|
|
4258
|
+
}
|
|
4259
|
+
////////////////////////////////
|
|
4260
|
+
//// UNIMPLEMENTED MTEHODS
|
|
4261
|
+
////////////////////////////////
|
|
4262
|
+
async getMigratableDbList(options) {
|
|
4263
|
+
console.log('getCordovaDbList', options);
|
|
4264
|
+
throw new Error('Method not implemented.');
|
|
4265
|
+
}
|
|
4266
|
+
async addSQLiteSuffix(options) {
|
|
4267
|
+
console.log(`${JSON.stringify(options)}`);
|
|
4268
|
+
throw new Error('Method not implemented.');
|
|
4269
|
+
}
|
|
4270
|
+
async deleteOldDatabases(options) {
|
|
4271
|
+
console.log(`${JSON.stringify(options)}`);
|
|
4272
|
+
throw new Error('Method not implemented.');
|
|
4273
|
+
}
|
|
4274
|
+
async getUrl() {
|
|
4275
|
+
throw new Error('Method not implemented.');
|
|
4276
|
+
}
|
|
4277
|
+
async initWebStore() {
|
|
4278
|
+
throw new Error('Method not implemented.');
|
|
4279
|
+
}
|
|
4280
|
+
async saveToStore(options) {
|
|
4281
|
+
console.log(`${JSON.stringify(options)}`);
|
|
4282
|
+
throw new Error('Method not implemented.');
|
|
4283
|
+
}
|
|
4284
|
+
async isSecretStored() {
|
|
4285
|
+
throw new Error('Method not implemented.');
|
|
4286
|
+
}
|
|
4287
|
+
async setEncryptionSecret(options) {
|
|
4288
|
+
console.log(`${JSON.stringify(options)}`);
|
|
4289
|
+
throw new Error('Method not implemented.');
|
|
4290
|
+
}
|
|
4291
|
+
async changeEncryptionSecret(options) {
|
|
4292
|
+
console.log(`${JSON.stringify(options)}`);
|
|
4293
|
+
throw new Error('Method not implemented.');
|
|
4294
|
+
}
|
|
4295
|
+
async getNCDatabasePath(options) {
|
|
4296
|
+
console.log('getNCDatabasePath', options);
|
|
4297
|
+
throw new Error('Method not implemented.');
|
|
4298
|
+
}
|
|
4299
|
+
async createNCConnection(options) {
|
|
4300
|
+
console.log('createNCConnection', options);
|
|
4301
|
+
throw new Error('Method not implemented.');
|
|
4302
|
+
}
|
|
4303
|
+
async closeNCConnection(options) {
|
|
4304
|
+
console.log('closeNCConnection', options);
|
|
4305
|
+
throw new Error('Method not implemented.');
|
|
4306
|
+
}
|
|
4307
|
+
async isNCDatabase(options) {
|
|
4308
|
+
console.log('isNCDatabase', options);
|
|
4309
|
+
throw new Error('Method not implemented.');
|
|
4195
4310
|
}
|
|
4196
4311
|
}
|
|
4197
4312
|
exports.CapacitorSQLite = src.CapacitorSQLite = CapacitorSQLite;
|