masterrecord 0.2.30 ā 0.2.32
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/.claude/settings.local.json +11 -0
- package/Migrations/cli.js +160 -40
- package/QueryLanguage/queryMethods.js +1 -25
- package/package.json +1 -1
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Read(//Users/alexanderrich/Documents/development/bookbaghq/bookbag-ce/components/models/app/models/**)",
|
|
5
|
+
"Read(//Users/alexanderrich/Documents/development/bookbaghq/bookbag-ce/components/models/app/controllers/api/**)",
|
|
6
|
+
"Read(//Users/alexanderrich/Documents/development/bookbaghq/bookbag-ce/config/environments/**)"
|
|
7
|
+
],
|
|
8
|
+
"deny": [],
|
|
9
|
+
"ask": []
|
|
10
|
+
}
|
|
11
|
+
}
|
package/Migrations/cli.js
CHANGED
|
@@ -280,53 +280,173 @@ program.option('-V', 'output the version');
|
|
|
280
280
|
contextFileName = contextFileName.toLowerCase();
|
|
281
281
|
var migration = new Migration();
|
|
282
282
|
try{
|
|
283
|
+
console.log(`\nš Searching for context snapshot '${contextFileName}_contextSnapShot.json'...`);
|
|
283
284
|
// find context snapshot (cwd-based glob)
|
|
284
285
|
var files = globSearch.sync(`**/*${contextFileName}_contextSnapShot.json`, { cwd: executedLocation, dot: true, windowsPathsNoEscape: true, nocase: true });
|
|
285
286
|
var file = files && files[0] ? path.resolve(executedLocation, files[0]) : null;
|
|
286
|
-
if(file){
|
|
287
|
-
var contextSnapshot = require(file);
|
|
288
|
-
const snapDir = path.dirname(file);
|
|
289
|
-
const contextAbs = path.resolve(snapDir, contextSnapshot.contextLocation || '');
|
|
290
|
-
const migBase = path.resolve(snapDir, contextSnapshot.migrationFolder || '.');
|
|
291
|
-
var migrationFiles = globSearch.sync(`**/*_migration.js`, { cwd: migBase, dot: true, windowsPathsNoEscape: true });
|
|
292
|
-
migrationFiles = (migrationFiles || []).map(f => path.resolve(migBase, f));
|
|
293
|
-
if( migrationFiles && migrationFiles.length){
|
|
294
|
-
// sort by timestamp prefix or file mtime as fallback
|
|
295
|
-
var mFiles = migrationFiles.slice().sort(function(a, b){
|
|
296
|
-
return __getMigrationTimestamp(a) - __getMigrationTimestamp(b);
|
|
297
|
-
});
|
|
298
|
-
var mFile = mFiles[mFiles.length -1];
|
|
299
|
-
|
|
300
|
-
var migrationProjectFile = require(mFile);
|
|
301
|
-
var ContextCtor = require(contextAbs);
|
|
302
|
-
var contextInstance = new ContextCtor();
|
|
303
|
-
var newMigrationProjectInstance = new migrationProjectFile(ContextCtor);
|
|
304
287
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
context : contextInstance,
|
|
313
|
-
contextEntities : cleanEntities,
|
|
314
|
-
contextFileName: contextFileName
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
migration.createSnapShot(snap);
|
|
318
|
-
console.log("ā Database updated successfully");
|
|
319
|
-
}
|
|
320
|
-
else{
|
|
321
|
-
console.log("Error - Cannot read or find migration file");
|
|
322
|
-
}
|
|
288
|
+
if(!file){
|
|
289
|
+
console.error(`\nā Error - Cannot find Context snapshot file`);
|
|
290
|
+
console.error(`\nSearched for: ${contextFileName}_contextSnapShot.json`);
|
|
291
|
+
console.error(`Searched in: ${executedLocation}`);
|
|
292
|
+
console.error(`\nš” Solution: Run 'masterrecord enable-migrations ${contextFileName}' first`);
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
323
295
|
|
|
296
|
+
console.log(`ā Found snapshot: ${file}`);
|
|
297
|
+
|
|
298
|
+
var contextSnapshot;
|
|
299
|
+
try{
|
|
300
|
+
contextSnapshot = require(file);
|
|
301
|
+
}catch(err){
|
|
302
|
+
console.error(`\nā Error - Cannot load context snapshot`);
|
|
303
|
+
console.error(`\nFile: ${file}`);
|
|
304
|
+
console.error(`Details: ${err.message}`);
|
|
305
|
+
return;
|
|
324
306
|
}
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
307
|
+
|
|
308
|
+
const snapDir = path.dirname(file);
|
|
309
|
+
const contextAbs = path.resolve(snapDir, contextSnapshot.contextLocation || '');
|
|
310
|
+
const migBase = path.resolve(snapDir, contextSnapshot.migrationFolder || '.');
|
|
311
|
+
|
|
312
|
+
console.log(`\nš Searching for migration files in: ${migBase}`);
|
|
313
|
+
var migrationFiles = globSearch.sync(`**/*_migration.js`, { cwd: migBase, dot: true, windowsPathsNoEscape: true });
|
|
314
|
+
migrationFiles = (migrationFiles || []).map(f => path.resolve(migBase, f));
|
|
315
|
+
|
|
316
|
+
if(!(migrationFiles && migrationFiles.length)){
|
|
317
|
+
console.error(`\nā Error - No migration files found`);
|
|
318
|
+
console.error(`\nSearched in: ${migBase}`);
|
|
319
|
+
console.error(`\nš” Solution: Run 'masterrecord add-migration Init ${contextFileName}' to create your first migration`);
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// sort by timestamp prefix or file mtime as fallback
|
|
324
|
+
var mFiles = migrationFiles.slice().sort(function(a, b){
|
|
325
|
+
return __getMigrationTimestamp(a) - __getMigrationTimestamp(b);
|
|
326
|
+
});
|
|
327
|
+
var mFile = mFiles[mFiles.length -1];
|
|
328
|
+
console.log(`ā Found ${mFiles.length} migration file(s), using latest: ${path.basename(mFile)}`);
|
|
329
|
+
|
|
330
|
+
console.log(`\nš Loading Context file from: ${contextAbs}`);
|
|
331
|
+
var migrationProjectFile;
|
|
332
|
+
var ContextCtor;
|
|
333
|
+
try{
|
|
334
|
+
migrationProjectFile = require(mFile);
|
|
335
|
+
ContextCtor = require(contextAbs);
|
|
336
|
+
}catch(err){
|
|
337
|
+
console.error(`\nā Error - Cannot load Context or migration file`);
|
|
338
|
+
console.error(`\nContext file: ${contextAbs}`);
|
|
339
|
+
console.error(`Migration file: ${mFile}`);
|
|
340
|
+
console.error(`\nDetails: ${err.message}`);
|
|
341
|
+
if(err.stack){
|
|
342
|
+
console.error(`\nStack trace:`);
|
|
343
|
+
console.error(err.stack);
|
|
344
|
+
}
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
console.log(`ā Context file loaded successfully`);
|
|
349
|
+
console.log(`\nš Instantiating Context (this will create the database if it doesn't exist)...`);
|
|
350
|
+
|
|
351
|
+
var contextInstance;
|
|
352
|
+
try{
|
|
353
|
+
contextInstance = new ContextCtor();
|
|
354
|
+
}catch(err){
|
|
355
|
+
console.error(`\nā Error - Failed to instantiate Context`);
|
|
356
|
+
console.error(`\nContext file: ${contextAbs}`);
|
|
357
|
+
console.error(`\nThis usually happens when:`);
|
|
358
|
+
console.error(` ⢠Environment configuration file is missing`);
|
|
359
|
+
console.error(` ⢠Database connection settings are incorrect`);
|
|
360
|
+
console.error(` ⢠The 'master' environment variable is not set`);
|
|
361
|
+
console.error(` ⢠Required dependencies are not installed`);
|
|
362
|
+
console.error(`\nDetails: ${err.message}`);
|
|
363
|
+
if(err.stack){
|
|
364
|
+
console.error(`\nStack trace:`);
|
|
365
|
+
console.error(err.stack);
|
|
366
|
+
}
|
|
367
|
+
console.error(`\nš” Check your environment config file (e.g., config/environments/env.development.json)`);
|
|
368
|
+
console.error(`š” Make sure you're running: master=development masterrecord update-database ${contextFileName}`);
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
console.log(`ā Context instantiated successfully`);
|
|
373
|
+
|
|
374
|
+
// Log database connection details
|
|
375
|
+
if(contextInstance.isSQLite && contextInstance.db){
|
|
376
|
+
const dbPath = contextInstance.db.name || 'unknown';
|
|
377
|
+
console.log(`\nš Database Type: SQLite`);
|
|
378
|
+
console.log(`š Database Path: ${dbPath}`);
|
|
379
|
+
|
|
380
|
+
// Check if the database file exists
|
|
381
|
+
if(fs.existsSync(dbPath)){
|
|
382
|
+
const stats = fs.statSync(dbPath);
|
|
383
|
+
console.log(`ā Database file exists (${(stats.size / 1024).toFixed(2)} KB)`);
|
|
384
|
+
}else{
|
|
385
|
+
console.log(`ā ļø Database file does not exist yet (will be created during migration)`);
|
|
386
|
+
}
|
|
387
|
+
}else if(contextInstance.isMySQL){
|
|
388
|
+
console.log(`\nš Database Type: MySQL`);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
console.log(`\nš Loading entities from context...`);
|
|
392
|
+
var cleanEntities = migration.cleanEntities(contextInstance.__entities);
|
|
393
|
+
console.log(`ā Found ${cleanEntities.length} entity/entities`);
|
|
394
|
+
|
|
395
|
+
if(cleanEntities.length === 0){
|
|
396
|
+
console.error(`\nā ļø Warning - No entities found in Context`);
|
|
397
|
+
console.error(`\nMake sure your Context file has dbset() calls to register entities`);
|
|
398
|
+
console.error(`Example:`);
|
|
399
|
+
console.error(` this.dbset(User, 'User');`);
|
|
400
|
+
console.error(` this.dbset(Post, 'Post');`);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
console.log(`\nš Running migration...`);
|
|
404
|
+
try{
|
|
405
|
+
var newMigrationProjectInstance = new migrationProjectFile(ContextCtor);
|
|
406
|
+
var tableObj = migration.buildUpObject(contextSnapshot.schema, cleanEntities);
|
|
407
|
+
newMigrationProjectInstance.up(tableObj);
|
|
408
|
+
}catch(err){
|
|
409
|
+
console.error(`\nā Error - Migration failed during execution`);
|
|
410
|
+
console.error(`\nMigration file: ${mFile}`);
|
|
411
|
+
console.error(`\nDetails: ${err.message}`);
|
|
412
|
+
if(err.stack){
|
|
413
|
+
console.error(`\nStack trace:`);
|
|
414
|
+
console.error(err.stack);
|
|
415
|
+
}
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
console.log(`\nš¾ Updating snapshot...`);
|
|
420
|
+
var snap = {
|
|
421
|
+
file : contextAbs,
|
|
422
|
+
executedLocation : executedLocation,
|
|
423
|
+
context : contextInstance,
|
|
424
|
+
contextEntities : cleanEntities,
|
|
425
|
+
contextFileName: contextFileName
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
migration.createSnapShot(snap);
|
|
429
|
+
console.log(`\nā
Database updated successfully!`);
|
|
430
|
+
|
|
431
|
+
// Final verification for SQLite
|
|
432
|
+
if(contextInstance.isSQLite && contextInstance.db){
|
|
433
|
+
const dbPath = contextInstance.db.name || 'unknown';
|
|
434
|
+
if(fs.existsSync(dbPath)){
|
|
435
|
+
const stats = fs.statSync(dbPath);
|
|
436
|
+
console.log(`\nš Database file: ${dbPath}`);
|
|
437
|
+
console.log(`š Size: ${(stats.size / 1024).toFixed(2)} KB`);
|
|
438
|
+
}else{
|
|
439
|
+
console.error(`\nā ļø Warning - Database file was not created at expected path: ${dbPath}`);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
|
|
328
443
|
}catch (e){
|
|
329
|
-
console.
|
|
444
|
+
console.error(`\nā Unexpected error during update-database`);
|
|
445
|
+
console.error(`\nDetails: ${e.message}`);
|
|
446
|
+
if(e.stack){
|
|
447
|
+
console.error(`\nStack trace:`);
|
|
448
|
+
console.error(e.stack);
|
|
449
|
+
}
|
|
330
450
|
}
|
|
331
451
|
});
|
|
332
452
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
// version 0.0.
|
|
2
|
+
// version 0.0.16
|
|
3
3
|
var entityTrackerModel = require('masterrecord/Entity/entityTrackerModel');
|
|
4
4
|
var tools = require('masterrecord/Tools');
|
|
5
5
|
var queryScript = require('masterrecord/QueryLanguage/queryScript');
|
|
@@ -249,18 +249,6 @@ class queryMethods{
|
|
|
249
249
|
entityValue.__state = "delete";
|
|
250
250
|
entityValue.__entity = this.__entity;
|
|
251
251
|
entityValue.__context = this.__context;
|
|
252
|
-
|
|
253
|
-
// If the entity has an __ID, try to find and update it in tracked entities
|
|
254
|
-
if(entityValue.__ID){
|
|
255
|
-
var tracked = this.__context.__findTracked(entityValue.__ID);
|
|
256
|
-
if(tracked){
|
|
257
|
-
// Update the tracked entity's state
|
|
258
|
-
tracked.__state = "delete";
|
|
259
|
-
return;
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
// If not already tracked, track it now
|
|
264
252
|
this.__context.__track(entityValue);
|
|
265
253
|
}
|
|
266
254
|
|
|
@@ -270,18 +258,6 @@ class queryMethods{
|
|
|
270
258
|
entityValue.__state = "delete";
|
|
271
259
|
entityValue.__entity = this.__entity;
|
|
272
260
|
entityValue.__context = this.__context;
|
|
273
|
-
|
|
274
|
-
// If the entity has an __ID, try to find and update it in tracked entities
|
|
275
|
-
if(entityValue.__ID){
|
|
276
|
-
var tracked = this.__context.__findTracked(entityValue.__ID);
|
|
277
|
-
if(tracked){
|
|
278
|
-
// Update the tracked entity's state
|
|
279
|
-
tracked.__state = "delete";
|
|
280
|
-
continue;
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
// If not already tracked, track it now
|
|
285
261
|
this.__context.__track(entityValue);
|
|
286
262
|
}
|
|
287
263
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "masterrecord",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.32",
|
|
4
4
|
"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 ",
|
|
5
5
|
"main": "MasterRecord.js",
|
|
6
6
|
"bin": {
|