masterrecord 0.2.4 → 0.2.6
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
CHANGED
|
@@ -21,6 +21,19 @@ var Migration = require('./migrations');
|
|
|
21
21
|
var globSearch = require("glob");
|
|
22
22
|
const pkg = require(path.join(__dirname, '..', 'package.json'));
|
|
23
23
|
|
|
24
|
+
// Extract numeric timestamp from migration filename (e.g., 1737999999999_name_migration.js)
|
|
25
|
+
function __getMigrationTimestamp(file){
|
|
26
|
+
try{
|
|
27
|
+
const base = path.basename(file);
|
|
28
|
+
const match = /^([0-9]{10,})_/i.exec(base);
|
|
29
|
+
if(match){ return Number(match[1]); }
|
|
30
|
+
const stat = fs.statSync(file);
|
|
31
|
+
return stat.mtimeMs || 0;
|
|
32
|
+
}catch(_){
|
|
33
|
+
return 0;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
24
37
|
|
|
25
38
|
const [,, ...args] = process.argv
|
|
26
39
|
|
|
@@ -45,11 +58,13 @@ program.option('-V', 'output the version');
|
|
|
45
58
|
var executedLocation = process.cwd();
|
|
46
59
|
// find context file from main folder location
|
|
47
60
|
var contextInstance = migration.findContext(executedLocation, contextFileName);
|
|
48
|
-
|
|
61
|
+
if(!contextInstance){
|
|
62
|
+
console.log(`Error - Cannot read or find Context file '${contextFileName}.js' in '${executedLocation}'.`);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
49
65
|
var snap = {
|
|
50
66
|
file : contextInstance.fileLocation,
|
|
51
67
|
executedLocation : executedLocation,
|
|
52
|
-
context : context,
|
|
53
68
|
contextEntities : [],
|
|
54
69
|
contextFileName: contextFileName.toLowerCase()
|
|
55
70
|
}
|
|
@@ -105,23 +120,41 @@ program.option('-V', 'output the version');
|
|
|
105
120
|
// find context file from main folder location
|
|
106
121
|
var search = `${executedLocation}/**/*${contextFileName}_contextSnapShot.json`;
|
|
107
122
|
var files = globSearch.sync(search, executedLocation);
|
|
108
|
-
var file = files[0];
|
|
109
|
-
if(file){
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
var contextInstance = new context();
|
|
113
|
-
var cleanEntities = migration.cleanEntities(contextInstance.__entities);
|
|
114
|
-
var newEntity = migration.template(name, contextSnapshot.schema, cleanEntities);
|
|
115
|
-
var migrationDate = Date.now();
|
|
116
|
-
var file = `${contextSnapshot.migrationFolder}/${migrationDate}_${name}_migration.js`
|
|
117
|
-
fs.writeFile(file, newEntity, 'utf8', function (err) {
|
|
118
|
-
if (err) return console.log("--- Error running cammand, re-run command add-migration ---- ", err);
|
|
119
|
-
});
|
|
120
|
-
console.log(`${name} migration file created`);
|
|
123
|
+
var file = files && files[0];
|
|
124
|
+
if(!file){
|
|
125
|
+
console.log(`Error - Cannot read or find Context snapshot '${contextFileName}_contextSnapShot.json' in '${executedLocation}'. Run 'masterrecord enable-migrations ${contextFileName}'.`);
|
|
126
|
+
return;
|
|
121
127
|
}
|
|
122
|
-
|
|
123
|
-
|
|
128
|
+
var contextSnapshot = null;
|
|
129
|
+
try{
|
|
130
|
+
contextSnapshot = require(file);
|
|
131
|
+
}catch(_){
|
|
132
|
+
console.log(`Error - Cannot read context snapshot at '${file}'.`);
|
|
133
|
+
return;
|
|
124
134
|
}
|
|
135
|
+
|
|
136
|
+
let ContextCtor;
|
|
137
|
+
try{
|
|
138
|
+
ContextCtor = require(contextSnapshot.contextLocation);
|
|
139
|
+
}catch(_){
|
|
140
|
+
console.log(`Error - Cannot load Context file at '${contextSnapshot.contextLocation}'.`);
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
let contextInstance;
|
|
144
|
+
try{
|
|
145
|
+
contextInstance = new ContextCtor();
|
|
146
|
+
}catch(_){
|
|
147
|
+
console.log(`Error - Failed to construct Context from '${contextSnapshot.contextLocation}'.`);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
var cleanEntities = migration.cleanEntities(contextInstance.__entities);
|
|
151
|
+
var newEntity = migration.template(name, contextSnapshot.schema, cleanEntities);
|
|
152
|
+
var migrationDate = Date.now();
|
|
153
|
+
var outputFile = `${contextSnapshot.migrationFolder}/${migrationDate}_${name}_migration.js`
|
|
154
|
+
fs.writeFile(outputFile, newEntity, 'utf8', function (err) {
|
|
155
|
+
if (err) return console.log("--- Error running cammand, re-run command add-migration ---- ", err);
|
|
156
|
+
});
|
|
157
|
+
console.log(`${name} migration file created`);
|
|
125
158
|
}catch (e){
|
|
126
159
|
console.log("Error - Cannot read or find file ", e);
|
|
127
160
|
}
|
|
@@ -144,25 +177,20 @@ program.option('-V', 'output the version');
|
|
|
144
177
|
var contextSnapshot = require(file);
|
|
145
178
|
var searchMigration = `${contextSnapshot.migrationFolder}/**/*_migration.js`;
|
|
146
179
|
var migrationFiles = globSearch.sync(searchMigration, contextSnapshot.migrationFolder);
|
|
147
|
-
if( migrationFiles){
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
});
|
|
154
|
-
/** ENd of BUG */
|
|
155
|
-
|
|
156
|
-
var mFile = mFiles[mFiles.length -1];
|
|
180
|
+
if( migrationFiles && migrationFiles.length){
|
|
181
|
+
// sort by timestamp prefix or file mtime as fallback
|
|
182
|
+
var mFiles = migrationFiles.slice().sort(function(a, b){
|
|
183
|
+
return __getMigrationTimestamp(a) - __getMigrationTimestamp(b);
|
|
184
|
+
});
|
|
185
|
+
var mFile = mFiles[mFiles.length -1];
|
|
157
186
|
|
|
158
187
|
var migrationProjectFile = require(mFile);
|
|
159
188
|
var context = require(contextSnapshot.contextLocation);
|
|
160
189
|
var contextInstance = new context();
|
|
161
190
|
var newMigrationProjectInstance = new migrationProjectFile(context);
|
|
162
191
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
var cleanEntities = migration.cleanEntities(contextInstance.__entities);
|
|
192
|
+
var cleanEntities = migration.cleanEntities(contextInstance.__entities);
|
|
193
|
+
var tableObj = migration.buildUpObject(contextSnapshot.schema, cleanEntities);
|
|
166
194
|
newMigrationProjectInstance.up(tableObj);
|
|
167
195
|
|
|
168
196
|
var snap = {
|
|
@@ -207,12 +235,10 @@ program.option('-V', 'output the version');
|
|
|
207
235
|
var contextSnapshot = require(file);
|
|
208
236
|
var searchMigration = `${contextSnapshot.migrationFolder}/**/*_migration.js`;
|
|
209
237
|
var migrationFiles = globSearch.sync(searchMigration, contextSnapshot.migrationFolder);
|
|
210
|
-
if( migrationFiles){
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
var mFiles = migrationFiles.sort(function(x, y){
|
|
215
|
-
return new Date(x.timestamp) < new Date(y.timestamp) ? 1 : -1;
|
|
238
|
+
if( migrationFiles && migrationFiles.length){
|
|
239
|
+
// organize by time using filename timestamp or file mtime
|
|
240
|
+
var mFiles = migrationFiles.slice().sort(function(a, b){
|
|
241
|
+
return __getMigrationTimestamp(a) - __getMigrationTimestamp(b);
|
|
216
242
|
});
|
|
217
243
|
var context = require(contextSnapshot.contextLocation);
|
|
218
244
|
|
|
@@ -222,8 +248,8 @@ program.option('-V', 'output the version');
|
|
|
222
248
|
|
|
223
249
|
var contextInstance = new context();
|
|
224
250
|
var newMigrationProjectInstance = new migrationProjectFile(context);
|
|
225
|
-
var tableObj = migration.buildUpObject(contextSnapshot.schema, contextInstance.__entities);
|
|
226
251
|
var cleanEntities = migration.cleanEntities(contextInstance.__entities);
|
|
252
|
+
var tableObj = migration.buildUpObject(contextSnapshot.schema, cleanEntities);
|
|
227
253
|
newMigrationProjectInstance.up(tableObj);
|
|
228
254
|
}
|
|
229
255
|
|
|
@@ -8,10 +8,17 @@ class migrationMySQLQuery {
|
|
|
8
8
|
var columnList = [];
|
|
9
9
|
for (var key in table) {
|
|
10
10
|
if(typeof table[key] === "object"){
|
|
11
|
-
|
|
11
|
+
var col = table[key];
|
|
12
|
+
// Skip relationship-only fields
|
|
13
|
+
if(col.type === 'hasOne' || col.type === 'hasMany' || col.type === 'hasManyThrough'){
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
// Map belongsTo to its foreignKey name
|
|
17
|
+
var name = (col.relationshipType === 'belongsTo' && col.foreignKey) ? col.foreignKey : col.name;
|
|
18
|
+
columnList.push(name);
|
|
12
19
|
}
|
|
13
20
|
}
|
|
14
|
-
return columnList.join(',')
|
|
21
|
+
return columnList.join(',');
|
|
15
22
|
}
|
|
16
23
|
|
|
17
24
|
#columnMapping(table){
|
|
@@ -8,10 +8,17 @@ class migrationSQLiteQuery {
|
|
|
8
8
|
var columnList = [];
|
|
9
9
|
for (var key in table) {
|
|
10
10
|
if(typeof table[key] === "object"){
|
|
11
|
-
|
|
11
|
+
var col = table[key];
|
|
12
|
+
// Skip relationship-only fields
|
|
13
|
+
if(col.type === 'hasOne' || col.type === 'hasMany' || col.type === 'hasManyThrough'){
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
// Map belongsTo to its foreignKey name
|
|
17
|
+
var name = (col.relationshipType === 'belongsTo' && col.foreignKey) ? col.foreignKey : col.name;
|
|
18
|
+
columnList.push(name);
|
|
12
19
|
}
|
|
13
20
|
}
|
|
14
|
-
return columnList.join(',')
|
|
21
|
+
return columnList.join(',');
|
|
15
22
|
}
|
|
16
23
|
|
|
17
24
|
#columnMapping(table){
|
|
@@ -134,7 +141,12 @@ class migrationSQLiteQuery {
|
|
|
134
141
|
var queryVar = "";
|
|
135
142
|
for (var key in table) {
|
|
136
143
|
if(typeof table[key] === "object"){
|
|
137
|
-
|
|
144
|
+
var col = table[key];
|
|
145
|
+
// Skip relationship-only fields
|
|
146
|
+
if(col.type === 'hasOne' || col.type === 'hasMany' || col.type === 'hasManyThrough'){
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
queryVar += `${this.#columnMapping(col)}, `;
|
|
138
150
|
}
|
|
139
151
|
}
|
|
140
152
|
|
package/Migrations/migrations.js
CHANGED
|
@@ -167,7 +167,10 @@ class Migrations{
|
|
|
167
167
|
findContext(executedLocation, contextFileName){
|
|
168
168
|
var search = `${executedLocation}/**/*${contextFileName}.js`
|
|
169
169
|
var files = globSearch.sync(search, executedLocation);
|
|
170
|
-
var file = files[0];
|
|
170
|
+
var file = files && files[0];
|
|
171
|
+
if(!file){
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
171
174
|
var context = require(file);
|
|
172
175
|
return {
|
|
173
176
|
context : context,
|
package/package.json
CHANGED
|
@@ -6,9 +6,10 @@
|
|
|
6
6
|
"deep-object-diff" : "^1.1.9",
|
|
7
7
|
"pg" : "^8.16.3",
|
|
8
8
|
"sync-mysql2" : "^1.0.6",
|
|
9
|
-
"app-root-path": "^3.1.0"
|
|
9
|
+
"app-root-path": "^3.1.0",
|
|
10
|
+
"better-sqlite3": "^12.4.1"
|
|
10
11
|
},
|
|
11
|
-
"version": "0.2.
|
|
12
|
+
"version": "0.2.6",
|
|
12
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 ",
|
|
13
14
|
"homepage": "https://github.com/Tailor/MasterRecord#readme",
|
|
14
15
|
"repository": {
|