masterrecord 0.3.20 → 0.3.22
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/QueryLanguage/queryMethods.js +11 -11
- package/context.js +30 -2
- package/insertManager.js +8 -8
- package/package.json +1 -1
|
@@ -164,7 +164,7 @@ class queryMethods{
|
|
|
164
164
|
// ------------------------------- FUNCTIONS THAT MAKE THE SQL CALL START FROM HERE ON -----------------------------------------------------
|
|
165
165
|
// ---------------------------------------------------------------------------------------------------------------------------------------
|
|
166
166
|
|
|
167
|
-
count(query, ...args){
|
|
167
|
+
async count(query, ...args){
|
|
168
168
|
if(query){
|
|
169
169
|
var str = query.toString();
|
|
170
170
|
str = this.__validateAndCollectParameters(str, args, 'count');
|
|
@@ -173,7 +173,7 @@ class queryMethods{
|
|
|
173
173
|
|
|
174
174
|
if(this.__context.isSQLite){
|
|
175
175
|
// trying to match string select and relace with select Count(*);
|
|
176
|
-
var entityValue = this.__context._SQLEngine.getCount(this.__queryObject, this.__entity, this.__context);
|
|
176
|
+
var entityValue = await this.__context._SQLEngine.getCount(this.__queryObject, this.__entity, this.__context);
|
|
177
177
|
var val = entityValue[Object.keys(entityValue)[0]];
|
|
178
178
|
this.__reset();
|
|
179
179
|
return val;
|
|
@@ -181,7 +181,7 @@ class queryMethods{
|
|
|
181
181
|
|
|
182
182
|
if(this.__context.isMySQL){
|
|
183
183
|
// trying to match string select and relace with select Count(*);
|
|
184
|
-
var entityValue = this.__context._SQLEngine.getCount(this.__queryObject, this.__entity, this.__context);
|
|
184
|
+
var entityValue = await this.__context._SQLEngine.getCount(this.__queryObject, this.__entity, this.__context);
|
|
185
185
|
var val = entityValue[Object.keys(entityValue)[0]];
|
|
186
186
|
this.__reset();
|
|
187
187
|
return val;
|
|
@@ -309,7 +309,7 @@ class queryMethods{
|
|
|
309
309
|
}
|
|
310
310
|
|
|
311
311
|
// Convenience method: Find record by primary key ID
|
|
312
|
-
findById(id){
|
|
312
|
+
async findById(id){
|
|
313
313
|
// Find the primary key field in the entity
|
|
314
314
|
let primaryKeyField = null;
|
|
315
315
|
for (const fieldName in this.__entity) {
|
|
@@ -329,10 +329,10 @@ class queryMethods{
|
|
|
329
329
|
const whereClause = `${entityParam} => ${entityParam}.${primaryKeyField} == $$`;
|
|
330
330
|
|
|
331
331
|
// Chain where() and single()
|
|
332
|
-
return this.where(whereClause, id).single();
|
|
332
|
+
return await this.where(whereClause, id).single();
|
|
333
333
|
}
|
|
334
334
|
|
|
335
|
-
single(){
|
|
335
|
+
async single(){
|
|
336
336
|
// If no clauses were used before single(), seed defaults so SQL is valid
|
|
337
337
|
if(this.__queryObject.script.entityMap.length === 0){
|
|
338
338
|
this.__queryObject.skipClause(this.__entity.__name);
|
|
@@ -357,12 +357,12 @@ class queryMethods{
|
|
|
357
357
|
// Cache miss - execute query
|
|
358
358
|
var result = null;
|
|
359
359
|
if(this.__context.isSQLite){
|
|
360
|
-
var entityValue = this.__context._SQLEngine.get(this.__queryObject.script, this.__entity, this.__context);
|
|
360
|
+
var entityValue = await this.__context._SQLEngine.get(this.__queryObject.script, this.__entity, this.__context);
|
|
361
361
|
result = this.__singleEntityBuilder(entityValue);
|
|
362
362
|
}
|
|
363
363
|
|
|
364
364
|
if(this.__context.isMySQL){
|
|
365
|
-
var entityValue = this.__context._SQLEngine.get(this.__queryObject.script, this.__entity, this.__context);
|
|
365
|
+
var entityValue = await this.__context._SQLEngine.get(this.__queryObject.script, this.__entity, this.__context);
|
|
366
366
|
result = this.__singleEntityBuilder(entityValue[0]);
|
|
367
367
|
}
|
|
368
368
|
|
|
@@ -375,7 +375,7 @@ class queryMethods{
|
|
|
375
375
|
return result;
|
|
376
376
|
}
|
|
377
377
|
|
|
378
|
-
toList(){
|
|
378
|
+
async toList(){
|
|
379
379
|
if(this.__queryObject.script.entityMap.length === 0){
|
|
380
380
|
this.__queryObject.skipClause( this.__entity.__name);
|
|
381
381
|
if(!this.__queryObject.script.take || this.__queryObject.script.take === 0){
|
|
@@ -401,12 +401,12 @@ class queryMethods{
|
|
|
401
401
|
// Cache miss - execute query
|
|
402
402
|
var result = [];
|
|
403
403
|
if(this.__context.isSQLite){
|
|
404
|
-
var entityValue = this.__context._SQLEngine.all(this.__queryObject.script, this.__entity, this.__context);
|
|
404
|
+
var entityValue = await this.__context._SQLEngine.all(this.__queryObject.script, this.__entity, this.__context);
|
|
405
405
|
result = this.__multipleEntityBuilder(entityValue);
|
|
406
406
|
}
|
|
407
407
|
|
|
408
408
|
if(this.__context.isMySQL){
|
|
409
|
-
var entityValue = this.__context._SQLEngine.all(this.__queryObject.script, this.__entity, this.__context);
|
|
409
|
+
var entityValue = await this.__context._SQLEngine.all(this.__queryObject.script, this.__entity, this.__context);
|
|
410
410
|
result = this.__multipleEntityBuilder(entityValue);
|
|
411
411
|
}
|
|
412
412
|
|
package/context.js
CHANGED
|
@@ -452,7 +452,35 @@ class context {
|
|
|
452
452
|
const rel = files[0];
|
|
453
453
|
// Ensure absolute path for require()
|
|
454
454
|
const abs = path.isAbsolute(rel) ? rel : path.resolve(currentRoot, rel);
|
|
455
|
-
|
|
455
|
+
|
|
456
|
+
// Find actual project root by looking for package.json or .git
|
|
457
|
+
// This prevents duplicate paths like "app/models/components/workforce/db/"
|
|
458
|
+
let projectRoot = path.dirname(abs);
|
|
459
|
+
let searchDir = projectRoot;
|
|
460
|
+
let foundProjectRoot = false;
|
|
461
|
+
|
|
462
|
+
// Walk up the directory tree to find package.json or .git
|
|
463
|
+
for (let j = 0; j < MAX_CONFIG_SEARCH_HOPS; j++) {
|
|
464
|
+
const hasPackageJson = fs.existsSync(path.join(searchDir, 'package.json'));
|
|
465
|
+
const hasGit = fs.existsSync(path.join(searchDir, '.git'));
|
|
466
|
+
|
|
467
|
+
if (hasPackageJson || hasGit) {
|
|
468
|
+
projectRoot = searchDir;
|
|
469
|
+
foundProjectRoot = true;
|
|
470
|
+
break;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
const parent = path.dirname(searchDir);
|
|
474
|
+
if (parent === searchDir) break; // Reached filesystem root
|
|
475
|
+
searchDir = parent;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
// Fallback to currentRoot if no project markers found
|
|
479
|
+
if (!foundProjectRoot) {
|
|
480
|
+
projectRoot = currentRoot;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
return { file: abs, rootFolder: projectRoot };
|
|
456
484
|
}
|
|
457
485
|
|
|
458
486
|
// Move to parent directory
|
|
@@ -1450,7 +1478,7 @@ class context {
|
|
|
1450
1478
|
}
|
|
1451
1479
|
|
|
1452
1480
|
// Load entity
|
|
1453
|
-
const entity = EntityClass.findById(primaryKey);
|
|
1481
|
+
const entity = await EntityClass.findById(primaryKey);
|
|
1454
1482
|
if (!entity) {
|
|
1455
1483
|
throw new EntityValidationError(
|
|
1456
1484
|
`${entityName} with id ${primaryKey} not found`,
|
package/insertManager.js
CHANGED
|
@@ -115,15 +115,15 @@ class InsertManager {
|
|
|
115
115
|
const entityProperty = modelEntity[property] ? modelEntity[property] : {};
|
|
116
116
|
|
|
117
117
|
if (entityProperty.type === RELATIONSHIP_TYPES.HAS_ONE) {
|
|
118
|
-
this._processHasOneRelationship(propertyModel, entityProperty, property, currentModel, SQL);
|
|
118
|
+
await this._processHasOneRelationship(propertyModel, entityProperty, property, currentModel, SQL);
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
if (entityProperty.type === RELATIONSHIP_TYPES.HAS_MANY) {
|
|
122
|
-
this._processArrayRelationship(propertyModel, entityProperty, property, currentModel, SQL, RELATIONSHIP_TYPES.HAS_MANY);
|
|
122
|
+
await this._processArrayRelationship(propertyModel, entityProperty, property, currentModel, SQL, RELATIONSHIP_TYPES.HAS_MANY);
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
if (entityProperty.type === RELATIONSHIP_TYPES.HAS_MANY_THROUGH) {
|
|
126
|
-
this._processArrayRelationship(propertyModel, entityProperty, property, currentModel, SQL, RELATIONSHIP_TYPES.HAS_MANY_THROUGH);
|
|
126
|
+
await this._processArrayRelationship(propertyModel, entityProperty, property, currentModel, SQL, RELATIONSHIP_TYPES.HAS_MANY_THROUGH);
|
|
127
127
|
}
|
|
128
128
|
}
|
|
129
129
|
} else {
|
|
@@ -147,7 +147,7 @@ class InsertManager {
|
|
|
147
147
|
* @param {object} SQL - SQL result from parent insert
|
|
148
148
|
* @throws {RelationshipError} If relationship entity is not found
|
|
149
149
|
*/
|
|
150
|
-
_processHasOneRelationship(propertyModel, entityProperty, property, currentModel, SQL) {
|
|
150
|
+
async _processHasOneRelationship(propertyModel, entityProperty, property, currentModel, SQL) {
|
|
151
151
|
// only insert child if user provided a concrete object with data
|
|
152
152
|
if (propertyModel && typeof propertyModel === 'object') {
|
|
153
153
|
// check if model has its own entity
|
|
@@ -169,7 +169,7 @@ class InsertManager {
|
|
|
169
169
|
|
|
170
170
|
propertyModel.__entity = tools.getEntity(property, this._allEntities);
|
|
171
171
|
propertyModel[currentModel.__entity.__name] = SQL.id;
|
|
172
|
-
this.runQueries(propertyModel);
|
|
172
|
+
await this.runQueries(propertyModel);
|
|
173
173
|
|
|
174
174
|
// Hydrate child back as a tracked instance so subsequent property sets are tracked
|
|
175
175
|
try {
|
|
@@ -187,7 +187,7 @@ class InsertManager {
|
|
|
187
187
|
|
|
188
188
|
const ctxSetName = tools.capitalizeFirstLetter(property);
|
|
189
189
|
if (currentModel.__context && currentModel.__context[ctxSetName]) {
|
|
190
|
-
const trackedChild = currentModel.__context[ctxSetName]
|
|
190
|
+
const trackedChild = await currentModel.__context[ctxSetName]
|
|
191
191
|
.where(`r => r.${childPk} == $$`, childId)
|
|
192
192
|
.single();
|
|
193
193
|
if (trackedChild) {
|
|
@@ -218,7 +218,7 @@ class InsertManager {
|
|
|
218
218
|
* @param {string} relationshipType - 'hasMany' or 'hasManyThrough'
|
|
219
219
|
* @throws {RelationshipError} If validation fails or entity not resolved
|
|
220
220
|
*/
|
|
221
|
-
_processArrayRelationship(propertyModel, entityProperty, property, currentModel, SQL, relationshipType) {
|
|
221
|
+
async _processArrayRelationship(propertyModel, entityProperty, property, currentModel, SQL, relationshipType) {
|
|
222
222
|
// skip when not provided; only enforce array type if user supplied a value
|
|
223
223
|
if (propertyModel === undefined || propertyModel === null) {
|
|
224
224
|
return;
|
|
@@ -263,7 +263,7 @@ class InsertManager {
|
|
|
263
263
|
|
|
264
264
|
propertyModel[propertykey].__entity = resolved;
|
|
265
265
|
propertyModel[propertykey][currentModel.__entity.__name] = SQL.id;
|
|
266
|
-
this.runQueries(propertyModel[propertykey]);
|
|
266
|
+
await this.runQueries(propertyModel[propertykey]);
|
|
267
267
|
}
|
|
268
268
|
}
|
|
269
269
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "masterrecord",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.22",
|
|
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": {
|