masterrecord 0.2.10 → 0.2.11
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/Migrations/cli.js +91 -1
- package/Migrations/schema.js +9 -1
- package/mySQLSyncConnect.js +15 -3
- package/package.json +1 -1
package/Migrations/cli.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
// version 0.0.
|
|
3
|
+
// version 0.0.7
|
|
4
4
|
// https://docs.microsoft.com/en-us/ef/ef6/modeling/code-first/migrations/
|
|
5
5
|
// how to add environment variables on cli call example - master=development masterrecord add-migration auth authContext
|
|
6
6
|
|
|
@@ -569,6 +569,96 @@ program.option('-V', 'output the version');
|
|
|
569
569
|
});
|
|
570
570
|
|
|
571
571
|
|
|
572
|
+
program
|
|
573
|
+
.command('update-database-all')
|
|
574
|
+
.alias('uda')
|
|
575
|
+
.description('Scan the project for *Context.js files and run update-database on each')
|
|
576
|
+
.action(function(){
|
|
577
|
+
var executedLocation = process.cwd();
|
|
578
|
+
try{
|
|
579
|
+
// Find all Context files (e.g., chatContext.js)
|
|
580
|
+
var allFiles = globSearch.sync(`${executedLocation}/**/*Context.js`, executedLocation);
|
|
581
|
+
if(!(allFiles && allFiles.length)){
|
|
582
|
+
console.log('No Context files found.');
|
|
583
|
+
return;
|
|
584
|
+
}
|
|
585
|
+
// Deduplicate by basename (case-insensitive)
|
|
586
|
+
var seen = new Set();
|
|
587
|
+
var contextFiles = [];
|
|
588
|
+
for(const f of allFiles){
|
|
589
|
+
var name = path.basename(f).toLowerCase();
|
|
590
|
+
if(!seen.has(name)){
|
|
591
|
+
seen.add(name);
|
|
592
|
+
contextFiles.push(f);
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
var migration = new Migration();
|
|
596
|
+
// Process each context independently
|
|
597
|
+
for(const ctxFile of contextFiles){
|
|
598
|
+
try{
|
|
599
|
+
var base = path.basename(ctxFile);
|
|
600
|
+
var ctxName = base.replace(/\.js$/i, '').toLowerCase();
|
|
601
|
+
// Locate snapshot for this context
|
|
602
|
+
var snapMatches = globSearch.sync(`${executedLocation}/**/*${ctxName}_contextSnapShot.json`, executedLocation);
|
|
603
|
+
var snapFile = snapMatches && snapMatches[0];
|
|
604
|
+
if(!snapFile){
|
|
605
|
+
console.log(`Skipping ${ctxName}: snapshot not found. Run 'masterrecord enable-migrations ${ctxName}'.`);
|
|
606
|
+
continue;
|
|
607
|
+
}
|
|
608
|
+
var contextSnapshot;
|
|
609
|
+
try{ contextSnapshot = require(snapFile); }catch(_){
|
|
610
|
+
console.log(`Skipping ${ctxName}: cannot read context snapshot at '${snapFile}'.`);
|
|
611
|
+
continue;
|
|
612
|
+
}
|
|
613
|
+
// Get migration files for this snapshot folder
|
|
614
|
+
var searchMigration = `${contextSnapshot.migrationFolder}/**/*_migration.js`;
|
|
615
|
+
var migrationFiles = globSearch.sync(searchMigration, contextSnapshot.migrationFolder);
|
|
616
|
+
if(!(migrationFiles && migrationFiles.length)){
|
|
617
|
+
console.log(`Skipping ${ctxName}: no migration files found.`);
|
|
618
|
+
continue;
|
|
619
|
+
}
|
|
620
|
+
// Pick latest
|
|
621
|
+
var mFiles = migrationFiles.slice().sort(function(a, b){
|
|
622
|
+
return __getMigrationTimestamp(a) - __getMigrationTimestamp(b);
|
|
623
|
+
});
|
|
624
|
+
var mFile = mFiles[mFiles.length - 1];
|
|
625
|
+
|
|
626
|
+
var ContextCtor;
|
|
627
|
+
try{ ContextCtor = require(contextSnapshot.contextLocation); }catch(_){
|
|
628
|
+
console.log(`Skipping ${ctxName}: cannot load Context at '${contextSnapshot.contextLocation}'.`);
|
|
629
|
+
continue;
|
|
630
|
+
}
|
|
631
|
+
var contextInstance;
|
|
632
|
+
try{ contextInstance = new ContextCtor(); }catch(_){
|
|
633
|
+
console.log(`Skipping ${ctxName}: failed to construct Context.`);
|
|
634
|
+
continue;
|
|
635
|
+
}
|
|
636
|
+
var migrationProjectFile = require(mFile);
|
|
637
|
+
var newMigrationProjectInstance = new migrationProjectFile(ContextCtor);
|
|
638
|
+
var cleanEntities = migration.cleanEntities(contextInstance.__entities);
|
|
639
|
+
var tableObj = migration.buildUpObject(contextSnapshot.schema, cleanEntities);
|
|
640
|
+
// Run up for this context
|
|
641
|
+
newMigrationProjectInstance.up(tableObj);
|
|
642
|
+
// Update snapshot
|
|
643
|
+
var snap = {
|
|
644
|
+
file : contextSnapshot.contextLocation,
|
|
645
|
+
executedLocation : executedLocation,
|
|
646
|
+
context : contextInstance,
|
|
647
|
+
contextEntities : cleanEntities,
|
|
648
|
+
contextFileName: ctxName
|
|
649
|
+
}
|
|
650
|
+
migration.createSnapShot(snap);
|
|
651
|
+
console.log(`database updated for ${ctxName}`);
|
|
652
|
+
}catch(errCtx){
|
|
653
|
+
console.log('Error updating context: ', errCtx);
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
}catch(e){
|
|
657
|
+
console.log('Error - Cannot read or find file ', e);
|
|
658
|
+
}
|
|
659
|
+
});
|
|
660
|
+
|
|
661
|
+
|
|
572
662
|
program.parse(process.argv);
|
|
573
663
|
|
|
574
664
|
// Handle manual '-V' alias
|
package/Migrations/schema.js
CHANGED
|
@@ -356,7 +356,15 @@ class schema{
|
|
|
356
356
|
const esc = String(v).replace(/'/g, "''");
|
|
357
357
|
return `'${esc}'`;
|
|
358
358
|
}).join(", ");
|
|
359
|
-
|
|
359
|
+
// Idempotent seed: ignore duplicates on unique indexes
|
|
360
|
+
let sql;
|
|
361
|
+
if(this.context.isSQLite){
|
|
362
|
+
sql = `INSERT OR IGNORE INTO ${tableName} (${colList}) VALUES (${vals})`;
|
|
363
|
+
} else if(this.context.isMySQL){
|
|
364
|
+
sql = `INSERT IGNORE INTO ${tableName} (${colList}) VALUES (${vals})`;
|
|
365
|
+
} else {
|
|
366
|
+
sql = `INSERT INTO ${tableName} (${colList}) VALUES (${vals})`;
|
|
367
|
+
}
|
|
360
368
|
this.context._execute(sql);
|
|
361
369
|
}
|
|
362
370
|
}
|
package/mySQLSyncConnect.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// version : 0.0.
|
|
1
|
+
// version : 0.0.4
|
|
2
2
|
|
|
3
3
|
var MySql = require('sync-mysql2');
|
|
4
4
|
|
|
@@ -60,8 +60,20 @@ class MySQLClient {
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
close() {
|
|
63
|
-
|
|
64
|
-
this.connection
|
|
63
|
+
try {
|
|
64
|
+
if (!this.connection) { return; }
|
|
65
|
+
if (typeof this.connection.finishAll === 'function') {
|
|
66
|
+
// Drain any pending RPC calls
|
|
67
|
+
try { this.connection.finishAll(); } catch(_) { /* ignore */ }
|
|
68
|
+
}
|
|
69
|
+
if (typeof this.connection.end === 'function') {
|
|
70
|
+
try { this.connection.end(); } catch(_) { /* ignore */ }
|
|
71
|
+
} else if (typeof this.connection.close === 'function') {
|
|
72
|
+
try { this.connection.close(); } catch(_) { /* ignore */ }
|
|
73
|
+
} else if (typeof this.connection.dispose === 'function') {
|
|
74
|
+
try { this.connection.dispose(); } catch(_) { /* ignore */ }
|
|
75
|
+
}
|
|
76
|
+
} finally {
|
|
65
77
|
this.connection = null;
|
|
66
78
|
}
|
|
67
79
|
}
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"app-root-path": "^3.1.0",
|
|
10
10
|
"better-sqlite3": "^12.4.1"
|
|
11
11
|
},
|
|
12
|
-
"version": "0.2.
|
|
12
|
+
"version": "0.2.11",
|
|
13
13
|
"description": "An Object-relational mapping for the Master framework. Master Record connects classes to relational database tables to establish a database with almost zero-configuration ",
|
|
14
14
|
"homepage": "https://github.com/Tailor/MasterRecord#readme",
|
|
15
15
|
"repository": {
|