@memberjunction/codegen-lib 5.30.0 → 5.31.0
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 +2 -0
- package/dist/Angular/angular-codegen.js +3 -3
- package/dist/Angular/angular-codegen.js.map +1 -1
- package/dist/Angular/related-entity-components.js +1 -1
- package/dist/Angular/related-entity-components.js.map +1 -1
- package/dist/Config/config.js +1 -1
- package/dist/Config/config.js.map +1 -1
- package/dist/Database/codeGenDatabaseProvider.d.ts +266 -12
- package/dist/Database/codeGenDatabaseProvider.d.ts.map +1 -1
- package/dist/Database/codeGenDatabaseProvider.js +352 -0
- package/dist/Database/codeGenDatabaseProvider.js.map +1 -1
- package/dist/Database/manage-metadata.d.ts.map +1 -1
- package/dist/Database/manage-metadata.js +86 -87
- package/dist/Database/manage-metadata.js.map +1 -1
- package/dist/Database/providers/postgresql/PostgreSQLCodeGenProvider.d.ts +105 -17
- package/dist/Database/providers/postgresql/PostgreSQLCodeGenProvider.d.ts.map +1 -1
- package/dist/Database/providers/postgresql/PostgreSQLCodeGenProvider.js +324 -94
- package/dist/Database/providers/postgresql/PostgreSQLCodeGenProvider.js.map +1 -1
- package/dist/Database/providers/postgresql/viewDependencyCapture.d.ts +99 -0
- package/dist/Database/providers/postgresql/viewDependencyCapture.d.ts.map +1 -0
- package/dist/Database/providers/postgresql/viewDependencyCapture.js +170 -0
- package/dist/Database/providers/postgresql/viewDependencyCapture.js.map +1 -0
- package/dist/Database/providers/postgresql/viewFallback.d.ts +75 -0
- package/dist/Database/providers/postgresql/viewFallback.d.ts.map +1 -0
- package/dist/Database/providers/postgresql/viewFallback.js +172 -0
- package/dist/Database/providers/postgresql/viewFallback.js.map +1 -0
- package/dist/Database/providers/sqlserver/SQLServerCodeGenProvider.d.ts +0 -25
- package/dist/Database/providers/sqlserver/SQLServerCodeGenProvider.d.ts.map +1 -1
- package/dist/Database/providers/sqlserver/SQLServerCodeGenProvider.js +9 -113
- package/dist/Database/providers/sqlserver/SQLServerCodeGenProvider.js.map +1 -1
- package/dist/Database/providers/sqlserver/__tests__/SQLServerCodeGenProvider.test.d.ts +2 -0
- package/dist/Database/providers/sqlserver/__tests__/SQLServerCodeGenProvider.test.d.ts.map +1 -0
- package/dist/Database/providers/sqlserver/__tests__/SQLServerCodeGenProvider.test.js +207 -0
- package/dist/Database/providers/sqlserver/__tests__/SQLServerCodeGenProvider.test.js.map +1 -0
- package/dist/Database/sql.d.ts +9 -1
- package/dist/Database/sql.d.ts.map +1 -1
- package/dist/Database/sql.js +41 -7
- package/dist/Database/sql.js.map +1 -1
- package/dist/Database/sql_codegen.d.ts +30 -0
- package/dist/Database/sql_codegen.d.ts.map +1 -1
- package/dist/Database/sql_codegen.js +205 -44
- package/dist/Database/sql_codegen.js.map +1 -1
- package/dist/Misc/advanced_generation.js +1 -1
- package/dist/Misc/advanced_generation.js.map +1 -1
- package/dist/Misc/createNewUser.js +2 -2
- package/dist/Misc/createNewUser.js.map +1 -1
- package/dist/Misc/entity_subclasses_codegen.js +5 -5
- package/dist/Misc/entity_subclasses_codegen.js.map +1 -1
- package/dist/Misc/graphql_server_codegen.js +6 -6
- package/dist/Misc/graphql_server_codegen.js.map +1 -1
- package/dist/Misc/sql_logging.d.ts.map +1 -1
- package/dist/Misc/sql_logging.js +14 -4
- package/dist/Misc/sql_logging.js.map +1 -1
- package/dist/runCodeGen.d.ts.map +1 -1
- package/dist/runCodeGen.js +66 -2
- package/dist/runCodeGen.js.map +1 -1
- package/package.json +18 -18
|
@@ -618,8 +618,8 @@ export class ManageMetadataBase {
|
|
|
618
618
|
const setClauses = [];
|
|
619
619
|
for (const [key, value] of attrs) {
|
|
620
620
|
const paramName = `attr_${key}`;
|
|
621
|
-
//
|
|
622
|
-
const sqlValue =
|
|
621
|
+
// Pass booleans through — both mssql and pg drivers handle native boolean values
|
|
622
|
+
const sqlValue = value;
|
|
623
623
|
queryParams[paramName] = sqlValue;
|
|
624
624
|
setClauses.push(`${this.qi(key)} = @${paramName}`);
|
|
625
625
|
}
|
|
@@ -710,7 +710,7 @@ export class ManageMetadataBase {
|
|
|
710
710
|
* @returns
|
|
711
711
|
*/
|
|
712
712
|
async manageMetadata(pool, currentUser) {
|
|
713
|
-
const md = new Metadata();
|
|
713
|
+
const md = new Metadata(); // global-provider-ok: codegen runs offline against a single provider
|
|
714
714
|
// Auto-exclude platform-specific system schemas.
|
|
715
715
|
// We mutate configInfo.excludeSchemas directly so that all downstream code
|
|
716
716
|
// (including createExcludeTablesAndSchemasFilter) picks up the exclusions.
|
|
@@ -803,7 +803,7 @@ export class ManageMetadataBase {
|
|
|
803
803
|
logStatus(` > Created ${vecResult.createdCount} virtual entit${vecResult.createdCount === 1 ? 'y' : 'ies'} from config`);
|
|
804
804
|
// Refresh metadata so manageVirtualEntities can find the newly-created entities
|
|
805
805
|
// in the cache — otherwise EntityByName() returns null and field sync is silently skipped
|
|
806
|
-
const md = new Metadata();
|
|
806
|
+
const md = new Metadata(); // global-provider-ok: codegen runs offline against a single provider
|
|
807
807
|
await md.Refresh();
|
|
808
808
|
}
|
|
809
809
|
const veResult = await this.manageVirtualEntities(pool);
|
|
@@ -845,7 +845,7 @@ export class ManageMetadataBase {
|
|
|
845
845
|
// virtual entities are records defined in the entity metadata and do NOT define a distinct base table
|
|
846
846
|
// but they do specify a base view. We DO NOT generate a base view for a virtual entity, we simply use it to figure
|
|
847
847
|
// out the fields that should be in the entity definition and add/update/delete the entity definition to match what's in the view when this runs
|
|
848
|
-
const sql = `SELECT * FROM ${this.qs(mj_core_schema(), 'vwEntities')} WHERE VirtualEntity =
|
|
848
|
+
const sql = `SELECT * FROM ${this.qs(mj_core_schema(), 'vwEntities')} WHERE VirtualEntity = ${this.boolLit(true)}`;
|
|
849
849
|
const virtualEntitiesResult = await this.runQuery(pool, sql);
|
|
850
850
|
const virtualEntities = virtualEntitiesResult.recordset;
|
|
851
851
|
let anyUpdates = false;
|
|
@@ -874,7 +874,7 @@ export class ManageMetadataBase {
|
|
|
874
874
|
if (veFields && veFields.length > 0) {
|
|
875
875
|
// we have 1+ fields, now loop through them and process each one
|
|
876
876
|
// first though, remove any fields that are no longer in the view
|
|
877
|
-
const md = new Metadata();
|
|
877
|
+
const md = new Metadata(); // global-provider-ok: codegen runs offline against a single provider
|
|
878
878
|
const entity = md.EntityByName(virtualEntity.Name);
|
|
879
879
|
if (entity) {
|
|
880
880
|
const removeList = [];
|
|
@@ -919,7 +919,7 @@ export class ManageMetadataBase {
|
|
|
919
919
|
// this protected checks to see if the field exists in the entity definition, and if not, adds it
|
|
920
920
|
// if it exist it updates the entity field to match the view's data type and nullability attributes
|
|
921
921
|
// first, get the entity definition
|
|
922
|
-
const md = new Metadata();
|
|
922
|
+
const md = new Metadata(); // global-provider-ok: codegen runs offline against a single provider
|
|
923
923
|
const entity = md.EntityByName(virtualEntity.Name);
|
|
924
924
|
let newEntityFieldUUID = null;
|
|
925
925
|
let didUpdate = false;
|
|
@@ -940,8 +940,8 @@ export class ManageMetadataBase {
|
|
|
940
940
|
SET
|
|
941
941
|
Sequence=${fieldSequence},
|
|
942
942
|
Type='${veField.Type}',
|
|
943
|
-
AllowsNull=${veField.AllowsNull
|
|
944
|
-
${makePrimaryKey ?
|
|
943
|
+
AllowsNull=${this.boolLit(veField.AllowsNull)},
|
|
944
|
+
${makePrimaryKey ? `IsPrimaryKey=${this.boolLit(true)},IsUnique=${this.boolLit(true)},` : ''}
|
|
945
945
|
Length=${veField.Length},
|
|
946
946
|
Precision=${veField.Precision},
|
|
947
947
|
Scale=${veField.Scale}
|
|
@@ -960,9 +960,9 @@ export class ManageMetadataBase {
|
|
|
960
960
|
${q('Length')}, ${q('Precision')}, ${q('Scale')},
|
|
961
961
|
${q('Sequence')}, ${q('IsPrimaryKey')}, ${q('IsUnique')},
|
|
962
962
|
${q('__mj_CreatedAt')}, ${q('__mj_UpdatedAt')} )
|
|
963
|
-
VALUES ( '${newEntityFieldUUID}', '${entity.ID}', '${veField.FieldName}', '${veField.Type}', ${veField.AllowsNull
|
|
963
|
+
VALUES ( '${newEntityFieldUUID}', '${entity.ID}', '${veField.FieldName}', '${veField.Type}', ${this.boolLit(veField.AllowsNull)},
|
|
964
964
|
${veField.Length}, ${veField.Precision}, ${veField.Scale},
|
|
965
|
-
${fieldSequence}, ${makePrimaryKey
|
|
965
|
+
${fieldSequence}, ${this.boolLit(makePrimaryKey)}, ${this.boolLit(makePrimaryKey)},
|
|
966
966
|
${this.utcNow()}, ${this.utcNow()}
|
|
967
967
|
)`;
|
|
968
968
|
await this.LogSQLAndExecute(pool, sqlAdd, `SQL text to add virtual entity field ${veField.FieldName} for entity ${virtualEntity.Name}`);
|
|
@@ -982,7 +982,7 @@ export class ManageMetadataBase {
|
|
|
982
982
|
if (!ag.featureEnabled('VirtualEntityFieldDecoration')) {
|
|
983
983
|
return; // Feature not enabled, nothing to do
|
|
984
984
|
}
|
|
985
|
-
const md = new Metadata();
|
|
985
|
+
const md = new Metadata(); // global-provider-ok: codegen runs offline against a single provider
|
|
986
986
|
const virtualEntities = md.Entities.filter(e => e.VirtualEntity);
|
|
987
987
|
if (virtualEntities.length === 0) {
|
|
988
988
|
return;
|
|
@@ -1086,7 +1086,7 @@ export class ManageMetadataBase {
|
|
|
1086
1086
|
*/
|
|
1087
1087
|
buildSourceEntityContext(viewDefinition) {
|
|
1088
1088
|
const tableRefs = SQLParser.ExtractTableRefs(viewDefinition);
|
|
1089
|
-
const md = new Metadata();
|
|
1089
|
+
const md = new Metadata(); // global-provider-ok: codegen runs offline against a single provider
|
|
1090
1090
|
const sourceEntities = [];
|
|
1091
1091
|
const seen = new Set();
|
|
1092
1092
|
for (const tableRef of tableRefs) {
|
|
@@ -1178,12 +1178,12 @@ export class ManageMetadataBase {
|
|
|
1178
1178
|
const sqlStatements = [];
|
|
1179
1179
|
// Clear existing default PK (field #1 fallback) before applying LLM-identified PKs
|
|
1180
1180
|
sqlStatements.push(`UPDATE ${this.qs(schema, 'EntityField')}
|
|
1181
|
-
SET IsPrimaryKey
|
|
1182
|
-
WHERE EntityID='${entity.ID}' AND IsPrimaryKey
|
|
1181
|
+
SET IsPrimaryKey=${this.boolLit(false)}, IsUnique=${this.boolLit(false)}
|
|
1182
|
+
WHERE EntityID='${entity.ID}' AND IsPrimaryKey=${this.boolLit(true)} AND IsSoftPrimaryKey=${this.boolLit(false)}`);
|
|
1183
1183
|
// Set LLM-identified PKs
|
|
1184
1184
|
for (const pk of validPKs) {
|
|
1185
1185
|
sqlStatements.push(`UPDATE ${this.qs(schema, 'EntityField')}
|
|
1186
|
-
SET IsPrimaryKey
|
|
1186
|
+
SET IsPrimaryKey=${this.boolLit(true)}, IsUnique=${this.boolLit(true)}, IsSoftPrimaryKey=${this.boolLit(true)}
|
|
1187
1187
|
WHERE EntityID='${entity.ID}' AND Name='${pk}'`);
|
|
1188
1188
|
logStatus(` ✓ Set PK for ${entity.Name}.${pk} (LLM-identified)`);
|
|
1189
1189
|
}
|
|
@@ -1200,7 +1200,7 @@ export class ManageMetadataBase {
|
|
|
1200
1200
|
if (!foreignKeys || foreignKeys.length === 0) {
|
|
1201
1201
|
return false;
|
|
1202
1202
|
}
|
|
1203
|
-
const md = new Metadata();
|
|
1203
|
+
const md = new Metadata(); // global-provider-ok: codegen runs offline against a single provider
|
|
1204
1204
|
const sqlStatements = [];
|
|
1205
1205
|
for (const fk of foreignKeys) {
|
|
1206
1206
|
// Only apply high/medium confidence
|
|
@@ -1336,7 +1336,7 @@ export class ManageMetadataBase {
|
|
|
1336
1336
|
async manageParentEntityFields(pool) {
|
|
1337
1337
|
let bSuccess = true;
|
|
1338
1338
|
let anyUpdates = false;
|
|
1339
|
-
const md = new Metadata();
|
|
1339
|
+
const md = new Metadata(); // global-provider-ok: codegen runs offline against a single provider
|
|
1340
1340
|
const childEntities = md.Entities.filter(e => e.IsChildType);
|
|
1341
1341
|
if (childEntities.length === 0) {
|
|
1342
1342
|
return { success: true, anyUpdates: false };
|
|
@@ -1397,13 +1397,13 @@ export class ManageMetadataBase {
|
|
|
1397
1397
|
!existingRow.AllowUpdateAPI;
|
|
1398
1398
|
if (needsUpdate) {
|
|
1399
1399
|
const sqlUpdate = `UPDATE ${this.qs(mj_core_schema(), 'EntityField')}
|
|
1400
|
-
SET IsVirtual
|
|
1400
|
+
SET IsVirtual=${this.boolLit(true)},
|
|
1401
1401
|
Type='${parentField.Type}',
|
|
1402
1402
|
Length=${parentField.Length},
|
|
1403
1403
|
Precision=${parentField.Precision},
|
|
1404
1404
|
Scale=${parentField.Scale},
|
|
1405
|
-
AllowsNull=${parentField.AllowsNull
|
|
1406
|
-
AllowUpdateAPI
|
|
1405
|
+
AllowsNull=${this.boolLit(parentField.AllowsNull)},
|
|
1406
|
+
AllowUpdateAPI=${this.boolLit(true)}
|
|
1407
1407
|
WHERE ID='${existingRow.ID}'`;
|
|
1408
1408
|
await this.LogSQLAndExecute(pool, sqlUpdate, `Update IS-A parent field ${parentField.Name} on ${childEntity.Name}`);
|
|
1409
1409
|
bUpdated = true;
|
|
@@ -1423,9 +1423,9 @@ export class ManageMetadataBase {
|
|
|
1423
1423
|
${q('__mj_CreatedAt')}, ${q('__mj_UpdatedAt')})
|
|
1424
1424
|
VALUES (
|
|
1425
1425
|
'${newFieldID}', '${childEntity.ID}', '${parentField.Name}',
|
|
1426
|
-
'${parentField.Type}', ${parentField.AllowsNull
|
|
1426
|
+
'${parentField.Type}', ${this.boolLit(parentField.AllowsNull)},
|
|
1427
1427
|
${parentField.Length}, ${parentField.Precision}, ${parentField.Scale},
|
|
1428
|
-
${sequence},
|
|
1428
|
+
${sequence}, ${this.boolLit(true)}, ${this.boolLit(true)}, ${this.boolLit(false)}, ${this.boolLit(false)},
|
|
1429
1429
|
${this.utcNow()}, ${this.utcNow()})`;
|
|
1430
1430
|
await this.LogSQLAndExecute(pool, sqlInsert, `Create IS-A parent field ${parentField.Name} on ${childEntity.Name}`);
|
|
1431
1431
|
bUpdated = true;
|
|
@@ -1498,7 +1498,7 @@ export class ManageMetadataBase {
|
|
|
1498
1498
|
FROM ${this.qs(mj_core_schema(), 'vwEntityFields')}
|
|
1499
1499
|
WHERE
|
|
1500
1500
|
RelatedEntityID IS NOT NULL AND
|
|
1501
|
-
IsVirtual =
|
|
1501
|
+
IsVirtual = ${this.boolLit(false)} AND
|
|
1502
1502
|
EntityID NOT IN (SELECT ID FROM ${this.qs(mj_core_schema(), 'Entity')} WHERE SchemaName IN (${excludeSchemas.map(s => `'${s}'`).join(',')}))
|
|
1503
1503
|
ORDER BY RelatedEntityID`;
|
|
1504
1504
|
const entityFieldsResult = await this.runQuery(pool, sSQL);
|
|
@@ -1666,7 +1666,7 @@ export class ManageMetadataBase {
|
|
|
1666
1666
|
FROM ${this.qs(mj_core_schema(), 'vwEntityFields')}
|
|
1667
1667
|
WHERE
|
|
1668
1668
|
RelatedEntityID IS NOT NULL AND
|
|
1669
|
-
IsVirtual =
|
|
1669
|
+
IsVirtual = ${this.boolLit(false)} AND
|
|
1670
1670
|
EntityID NOT IN (SELECT ID FROM ${this.qs(mj_core_schema(), 'Entity')} WHERE SchemaName IN (${excludeSchemas.map(s => `'${s}'`).join(',')}))
|
|
1671
1671
|
ORDER BY RelatedEntityID`;
|
|
1672
1672
|
const entityFieldsResult = await this.runQuery(pool, sSQL);
|
|
@@ -1743,7 +1743,7 @@ export class ManageMetadataBase {
|
|
|
1743
1743
|
}
|
|
1744
1744
|
}
|
|
1745
1745
|
// if we get here we now need to refresh our metadata object
|
|
1746
|
-
const md = new Metadata();
|
|
1746
|
+
const md = new Metadata(); // global-provider-ok: codegen runs offline against a single provider
|
|
1747
1747
|
await md.Refresh();
|
|
1748
1748
|
}
|
|
1749
1749
|
return true;
|
|
@@ -1810,7 +1810,7 @@ export class ManageMetadataBase {
|
|
|
1810
1810
|
* other lookup failure (e.g., name shape we didn't anticipate).
|
|
1811
1811
|
*/
|
|
1812
1812
|
resolveEntityNamesToIDs(entityNames) {
|
|
1813
|
-
const md = new Metadata();
|
|
1813
|
+
const md = new Metadata(); // global-provider-ok: codegen runs offline against a single provider
|
|
1814
1814
|
const ids = [];
|
|
1815
1815
|
for (const name of entityNames) {
|
|
1816
1816
|
if (typeof name !== 'string' || name.trim().length === 0)
|
|
@@ -1915,7 +1915,7 @@ export class ManageMetadataBase {
|
|
|
1915
1915
|
// because entity.Fields and entity.PrimaryKeys won't reflect the updated flags
|
|
1916
1916
|
if (configInfo.additionalSchemaInfo) {
|
|
1917
1917
|
logStatus(' Refreshing metadata after applying soft PK/FK configuration...');
|
|
1918
|
-
const md = new Metadata();
|
|
1918
|
+
const md = new Metadata(); // global-provider-ok: codegen runs offline against a single provider
|
|
1919
1919
|
await md.Refresh();
|
|
1920
1920
|
logStatus(' Metadata refresh complete');
|
|
1921
1921
|
}
|
|
@@ -1973,7 +1973,7 @@ export class ManageMetadataBase {
|
|
|
1973
1973
|
FROM
|
|
1974
1974
|
${this.qs(mj_core_schema(), 'vwEntities')}
|
|
1975
1975
|
WHERE
|
|
1976
|
-
VirtualEntity
|
|
1976
|
+
VirtualEntity=${this.boolLit(false)} AND
|
|
1977
1977
|
DeleteType='Soft' AND
|
|
1978
1978
|
SchemaName NOT IN (${excludeSchemas.map(s => `'${s}'`).join(',')})`;
|
|
1979
1979
|
const entitiesResult = await this.runQuery(pool, sqlEntities);
|
|
@@ -2111,8 +2111,8 @@ export class ManageMetadataBase {
|
|
|
2111
2111
|
FROM
|
|
2112
2112
|
${this.qs(mj_core_schema(), 'vwEntities')}
|
|
2113
2113
|
WHERE
|
|
2114
|
-
VirtualEntity =
|
|
2115
|
-
TrackRecordChanges =
|
|
2114
|
+
VirtualEntity = ${this.boolLit(false)} AND
|
|
2115
|
+
TrackRecordChanges = ${this.boolLit(true)} AND
|
|
2116
2116
|
SchemaName NOT IN (${excludeSchemas.map(s => `'${s}'`).join(',')})`;
|
|
2117
2117
|
const entitiesResult = await this.runQuery(pool, sqlEntities);
|
|
2118
2118
|
const entities = entitiesResult.recordset;
|
|
@@ -2432,19 +2432,19 @@ export class ManageMetadataBase {
|
|
|
2432
2432
|
${n.Length},
|
|
2433
2433
|
${n.Precision},
|
|
2434
2434
|
${n.Scale},
|
|
2435
|
-
${n.AllowsNull
|
|
2435
|
+
${this.boolLit(n.AllowsNull)},
|
|
2436
2436
|
${quotedDefaultValue},
|
|
2437
|
-
${n.AutoIncrement
|
|
2438
|
-
${n.AllowUpdateAPI
|
|
2439
|
-
${n.IsVirtual
|
|
2437
|
+
${this.boolLit(n.AutoIncrement)},
|
|
2438
|
+
${this.boolLit(n.AllowUpdateAPI)},
|
|
2439
|
+
${this.boolLit(n.IsVirtual)},
|
|
2440
2440
|
${n.RelatedEntityID && n.RelatedEntityID.length > 0 ? `'${n.RelatedEntityID}'` : 'NULL'},
|
|
2441
2441
|
${n.RelatedEntityFieldName && n.RelatedEntityFieldName.length > 0 ? `'${n.RelatedEntityFieldName}'` : 'NULL'},
|
|
2442
|
-
${n.IsNameField !== null ? n.IsNameField :
|
|
2443
|
-
${n.FieldName === 'ID' || n.IsNameField
|
|
2444
|
-
${n.RelatedEntityID && n.RelatedEntityID.length > 0
|
|
2445
|
-
${bDefaultInView
|
|
2446
|
-
${n.IsPrimaryKey},
|
|
2447
|
-
${n.IsUnique},
|
|
2442
|
+
${this.boolLit(n.IsNameField !== null ? n.IsNameField : false)},
|
|
2443
|
+
${this.boolLit(n.FieldName === 'ID' || n.IsNameField)},
|
|
2444
|
+
${this.boolLit(n.RelatedEntityID && n.RelatedEntityID.length > 0)},
|
|
2445
|
+
${this.boolLit(bDefaultInView)},
|
|
2446
|
+
${this.boolLit(n.IsPrimaryKey)},
|
|
2447
|
+
${this.boolLit(n.IsUnique)},
|
|
2448
2448
|
'${n.RelationshipDefaultDisplayType}',
|
|
2449
2449
|
${this.utcNow()},
|
|
2450
2450
|
${this.utcNow()}
|
|
@@ -3050,7 +3050,7 @@ export class ManageMetadataBase {
|
|
|
3050
3050
|
const newEntitiesResult = await this.runQuery(pool, sSQL);
|
|
3051
3051
|
const newEntities = newEntitiesResult.recordset;
|
|
3052
3052
|
if (newEntities && newEntities.length > 0) {
|
|
3053
|
-
const md = new Metadata();
|
|
3053
|
+
const md = new Metadata(); // global-provider-ok: codegen runs offline against a single provider
|
|
3054
3054
|
const transaction = await pool.beginTransaction();
|
|
3055
3055
|
try {
|
|
3056
3056
|
// wrap in a transaction so we get all of it or none of it
|
|
@@ -3082,7 +3082,7 @@ export class ManageMetadataBase {
|
|
|
3082
3082
|
// criteria:
|
|
3083
3083
|
// 1) entity has a field that is a primary key
|
|
3084
3084
|
// validate all of these factors by getting the sql from SQL Server and check the result, if failure, shouldCreate=false and generate validation message, otherwise return empty validation message and true for shouldCreate.
|
|
3085
|
-
const query = this.dbProvider.callRoutineSQL(Metadata.Provider.ConfigData.MJCoreSchemaName, 'spGetPrimaryKeyForTable', [`'${newEntity.TableName}'`, `'${newEntity.SchemaName}'`], ['TableName', 'SchemaName']);
|
|
3085
|
+
const query = this.dbProvider.callRoutineSQL(Metadata.Provider.ConfigData.MJCoreSchemaName, 'spGetPrimaryKeyForTable', [`'${newEntity.TableName}'`, `'${newEntity.SchemaName}'`], ['TableName', 'SchemaName']); // global-provider-ok: codegen runs offline against a single provider
|
|
3086
3086
|
try {
|
|
3087
3087
|
const resultResult = await ds.query(query);
|
|
3088
3088
|
const result = resultResult.recordset;
|
|
@@ -3353,7 +3353,7 @@ export class ManageMetadataBase {
|
|
|
3353
3353
|
if (RoleID) {
|
|
3354
3354
|
const sSQLInsertPermission = `INSERT INTO ${this.qs(mj_core_schema(), 'EntityPermission')}
|
|
3355
3355
|
(${this.qi('EntityID')}, ${this.qi('RoleID')}, ${this.qi('CanRead')}, ${this.qi('CanCreate')}, ${this.qi('CanUpdate')}, ${this.qi('CanDelete')}, ${this.qi('__mj_CreatedAt')}, ${this.qi('__mj_UpdatedAt')}) VALUES
|
|
3356
|
-
('${newEntityID}', '${RoleID}', ${p.CanRead
|
|
3356
|
+
('${newEntityID}', '${RoleID}', ${this.boolLit(p.CanRead)}, ${this.boolLit(p.CanCreate)}, ${this.boolLit(p.CanUpdate)}, ${this.boolLit(p.CanDelete)}, ${this.utcNow()}, ${this.utcNow()})`;
|
|
3357
3357
|
await this.LogSQLAndExecute(pool, sSQLInsertPermission, `SQL generated to add new permission for entity ${newEntityName} for role ${p.RoleName}`);
|
|
3358
3358
|
}
|
|
3359
3359
|
else
|
|
@@ -3430,13 +3430,13 @@ export class ManageMetadataBase {
|
|
|
3430
3430
|
if (!defaults?.AutoAddRolesForNewApplications) {
|
|
3431
3431
|
return;
|
|
3432
3432
|
}
|
|
3433
|
-
const md = new Metadata();
|
|
3433
|
+
const md = new Metadata(); // global-provider-ok: codegen runs offline against a single provider
|
|
3434
3434
|
for (const roleDef of defaults.Roles) {
|
|
3435
3435
|
const role = md.Roles.find(r => r.Name.trim().toLowerCase() === roleDef.RoleName.trim().toLowerCase());
|
|
3436
3436
|
if (role) {
|
|
3437
3437
|
const sSQLInsert = `INSERT INTO ${this.qs(mj_core_schema(), 'ApplicationRole')}
|
|
3438
3438
|
(${this.qi('ApplicationID')}, ${this.qi('RoleID')}, ${this.qi('CanAccess')}, ${this.qi('CanAdmin')}) VALUES
|
|
3439
|
-
('${appId}', '${role.ID}', ${roleDef.CanAccess
|
|
3439
|
+
('${appId}', '${role.ID}', ${this.boolLit(roleDef.CanAccess)}, ${this.boolLit(roleDef.CanAdmin)})`;
|
|
3440
3440
|
await this.LogSQLAndExecute(pool, sSQLInsert, `Adding role ${roleDef.RoleName} to application ${appName}`);
|
|
3441
3441
|
}
|
|
3442
3442
|
else {
|
|
@@ -3484,7 +3484,7 @@ export class ManageMetadataBase {
|
|
|
3484
3484
|
const newAppID = await this.createNewApplication(pool, appUUID, schemaName, schemaName, currentUser);
|
|
3485
3485
|
if (newAppID) {
|
|
3486
3486
|
apps = [newAppID];
|
|
3487
|
-
const md = new Metadata();
|
|
3487
|
+
const md = new Metadata(); // global-provider-ok: codegen runs offline against a single provider
|
|
3488
3488
|
await md.Refresh();
|
|
3489
3489
|
}
|
|
3490
3490
|
else {
|
|
@@ -3513,14 +3513,14 @@ export class ManageMetadataBase {
|
|
|
3513
3513
|
if (!configInfo.newEntityDefaults.PermissionDefaults?.AutoAddPermissionsForNewEntities) {
|
|
3514
3514
|
return;
|
|
3515
3515
|
}
|
|
3516
|
-
const md = new Metadata();
|
|
3516
|
+
const md = new Metadata(); // global-provider-ok: codegen runs offline against a single provider
|
|
3517
3517
|
const permissions = configInfo.newEntityDefaults.PermissionDefaults.Permissions;
|
|
3518
3518
|
for (const p of permissions) {
|
|
3519
3519
|
const RoleID = md.Roles.find(r => r.Name.trim().toLowerCase() === p.RoleName.trim().toLowerCase())?.ID;
|
|
3520
3520
|
if (RoleID) {
|
|
3521
3521
|
const sSQLInsert = `INSERT INTO ${this.qs(mj_core_schema(), 'EntityPermission')}
|
|
3522
3522
|
(${this.qi('EntityID')}, ${this.qi('RoleID')}, ${this.qi('CanRead')}, ${this.qi('CanCreate')}, ${this.qi('CanUpdate')}, ${this.qi('CanDelete')}, ${this.qi('__mj_CreatedAt')}, ${this.qi('__mj_UpdatedAt')}) VALUES
|
|
3523
|
-
('${entityId}', '${RoleID}', ${p.CanRead
|
|
3523
|
+
('${entityId}', '${RoleID}', ${this.boolLit(p.CanRead)}, ${this.boolLit(p.CanCreate)}, ${this.boolLit(p.CanUpdate)}, ${this.boolLit(p.CanDelete)}, ${this.utcNow()}, ${this.utcNow()})`;
|
|
3524
3524
|
await this.LogSQLAndExecute(pool, sSQLInsert, `SQL generated to add permission for entity ${entityName} for role ${p.RoleName}`);
|
|
3525
3525
|
}
|
|
3526
3526
|
else {
|
|
@@ -3566,16 +3566,16 @@ export class ManageMetadataBase {
|
|
|
3566
3566
|
'${newEntity.TableName}',
|
|
3567
3567
|
'vw${generatePluralName(newEntity.TableName, { capitalizeFirstLetterOnly: true }) + (newEntitySuffix && newEntitySuffix.length > 0 ? newEntitySuffix : '')}',
|
|
3568
3568
|
'${newEntity.SchemaName}',
|
|
3569
|
-
|
|
3570
|
-
${newEntityDefaults.AllowUserSearchAPI === undefined ?
|
|
3571
|
-
${allowCaching
|
|
3572
|
-
${newEntityDefaults.TrackRecordChanges === undefined ? '' : ', ' + (newEntityDefaults.TrackRecordChanges
|
|
3573
|
-
${newEntityDefaults.AuditRecordAccess === undefined ? '' : ', ' + (newEntityDefaults.AuditRecordAccess
|
|
3574
|
-
${newEntityDefaults.AuditViewRuns === undefined ? '' : ', ' + (newEntityDefaults.AuditViewRuns
|
|
3575
|
-
${newEntityDefaults.AllowAllRowsAPI === undefined ? '' : ', ' + (newEntityDefaults.AllowAllRowsAPI
|
|
3576
|
-
${newEntityDefaults.AllowCreateAPI === undefined ? '' : ', ' + (newEntityDefaults.AllowCreateAPI
|
|
3577
|
-
${newEntityDefaults.AllowUpdateAPI === undefined ? '' : ', ' + (newEntityDefaults.AllowUpdateAPI
|
|
3578
|
-
${newEntityDefaults.AllowDeleteAPI === undefined ? '' : ', ' + (newEntityDefaults.AllowDeleteAPI
|
|
3569
|
+
${this.boolLit(true)},
|
|
3570
|
+
${newEntityDefaults.AllowUserSearchAPI === undefined ? this.boolLit(true) : this.boolLit(newEntityDefaults.AllowUserSearchAPI)},
|
|
3571
|
+
${this.boolLit(allowCaching)}
|
|
3572
|
+
${newEntityDefaults.TrackRecordChanges === undefined ? '' : ', ' + this.boolLit(newEntityDefaults.TrackRecordChanges)}
|
|
3573
|
+
${newEntityDefaults.AuditRecordAccess === undefined ? '' : ', ' + this.boolLit(newEntityDefaults.AuditRecordAccess)}
|
|
3574
|
+
${newEntityDefaults.AuditViewRuns === undefined ? '' : ', ' + this.boolLit(newEntityDefaults.AuditViewRuns)}
|
|
3575
|
+
${newEntityDefaults.AllowAllRowsAPI === undefined ? '' : ', ' + this.boolLit(newEntityDefaults.AllowAllRowsAPI)}
|
|
3576
|
+
${newEntityDefaults.AllowCreateAPI === undefined ? '' : ', ' + this.boolLit(newEntityDefaults.AllowCreateAPI)}
|
|
3577
|
+
${newEntityDefaults.AllowUpdateAPI === undefined ? '' : ', ' + this.boolLit(newEntityDefaults.AllowUpdateAPI)}
|
|
3578
|
+
${newEntityDefaults.AllowDeleteAPI === undefined ? '' : ', ' + this.boolLit(newEntityDefaults.AllowDeleteAPI)}
|
|
3579
3579
|
${newEntityDefaults.UserViewMaxRows === undefined ? '' : ', ' + (newEntityDefaults.UserViewMaxRows)}
|
|
3580
3580
|
, ${this.utcNow()}
|
|
3581
3581
|
, ${this.utcNow()}
|
|
@@ -3620,7 +3620,7 @@ export class ManageMetadataBase {
|
|
|
3620
3620
|
if (configInfo.forceRegeneration?.enabled) {
|
|
3621
3621
|
// Force regeneration mode - process all entities (or filtered by entityWhereClause)
|
|
3622
3622
|
logStatus(` Force regeneration enabled - processing all entities...`);
|
|
3623
|
-
whereClause =
|
|
3623
|
+
whereClause = `e.VirtualEntity = ${this.boolLit(false)}`;
|
|
3624
3624
|
if (configInfo.forceRegeneration.entityWhereClause && configInfo.forceRegeneration.entityWhereClause.trim().length > 0) {
|
|
3625
3625
|
whereClause += ` AND (${configInfo.forceRegeneration.entityWhereClause})`;
|
|
3626
3626
|
logStatus(` Filtered by: ${configInfo.forceRegeneration.entityWhereClause}`);
|
|
@@ -3640,7 +3640,7 @@ export class ManageMetadataBase {
|
|
|
3640
3640
|
return true;
|
|
3641
3641
|
}
|
|
3642
3642
|
logStatus(` Advanced Generation enabled, processing ${entitiesToProcess.length} entities...`);
|
|
3643
|
-
whereClause = `e.VirtualEntity =
|
|
3643
|
+
whereClause = `e.VirtualEntity = ${this.boolLit(false)} AND e.Name IN (${entitiesToProcess.map(name => `'${name}'`).join(',')}) AND e.SchemaName NOT IN (${excludeSchemas.map(s => `'${s}'`).join(',')})`;
|
|
3644
3644
|
}
|
|
3645
3645
|
// Get entity details for entities that need processing
|
|
3646
3646
|
const entitiesSQL = `
|
|
@@ -3697,7 +3697,7 @@ export class ManageMetadataBase {
|
|
|
3697
3697
|
ef.AutoUpdateUserSearchPredicate,
|
|
3698
3698
|
ef.FullTextSearchEnabled,
|
|
3699
3699
|
ef.AutoUpdateFullTextSearch,
|
|
3700
|
-
ef.Length as MaxLength
|
|
3700
|
+
ef.${this.qi('Length')} as MaxLength
|
|
3701
3701
|
FROM
|
|
3702
3702
|
${this.qs(mj_core_schema(), 'vwEntityFields')} ef
|
|
3703
3703
|
WHERE
|
|
@@ -3850,7 +3850,7 @@ export class ManageMetadataBase {
|
|
|
3850
3850
|
return {};
|
|
3851
3851
|
}
|
|
3852
3852
|
// Walk the IS-A chain using in-memory metadata
|
|
3853
|
-
const md = new Metadata();
|
|
3853
|
+
const md = new Metadata(); // global-provider-ok: codegen runs offline against a single provider
|
|
3854
3854
|
const allEntities = md.Entities;
|
|
3855
3855
|
const parentChain = [];
|
|
3856
3856
|
const visited = new Set();
|
|
@@ -3932,9 +3932,9 @@ export class ManageMetadataBase {
|
|
|
3932
3932
|
if (nameField && nameField.AutoUpdateIsNameField && nameField.ID && !nameField.IsNameField) {
|
|
3933
3933
|
sqlStatements.push(`
|
|
3934
3934
|
UPDATE ${this.qs(mj_core_schema(), 'EntityField')}
|
|
3935
|
-
SET IsNameField =
|
|
3935
|
+
SET IsNameField = ${this.boolLit(true)}
|
|
3936
3936
|
WHERE ID = '${nameField.ID}'
|
|
3937
|
-
AND AutoUpdateIsNameField =
|
|
3937
|
+
AND AutoUpdateIsNameField = ${this.boolLit(true)}
|
|
3938
3938
|
`);
|
|
3939
3939
|
}
|
|
3940
3940
|
else if (!nameField) {
|
|
@@ -3955,9 +3955,9 @@ export class ManageMetadataBase {
|
|
|
3955
3955
|
if (!field.DefaultInView) {
|
|
3956
3956
|
sqlStatements.push(`
|
|
3957
3957
|
UPDATE ${this.qs(mj_core_schema(), 'EntityField')}
|
|
3958
|
-
SET DefaultInView =
|
|
3958
|
+
SET DefaultInView = ${this.boolLit(true)}
|
|
3959
3959
|
WHERE ID = '${field.ID}'
|
|
3960
|
-
AND AutoUpdateDefaultInView =
|
|
3960
|
+
AND AutoUpdateDefaultInView = ${this.boolLit(true)}
|
|
3961
3961
|
`);
|
|
3962
3962
|
}
|
|
3963
3963
|
}
|
|
@@ -3978,9 +3978,9 @@ export class ManageMetadataBase {
|
|
|
3978
3978
|
if (!field.IncludeInUserSearchAPI) {
|
|
3979
3979
|
sqlStatements.push(`
|
|
3980
3980
|
UPDATE ${this.qs(mj_core_schema(), 'EntityField')}
|
|
3981
|
-
SET IncludeInUserSearchAPI =
|
|
3981
|
+
SET IncludeInUserSearchAPI = ${this.boolLit(true)}
|
|
3982
3982
|
WHERE ID = '${field.ID}'
|
|
3983
|
-
AND AutoUpdateIncludeInUserSearchAPI =
|
|
3983
|
+
AND AutoUpdateIncludeInUserSearchAPI = ${this.boolLit(true)}
|
|
3984
3984
|
`);
|
|
3985
3985
|
}
|
|
3986
3986
|
}
|
|
@@ -4007,7 +4007,7 @@ export class ManageMetadataBase {
|
|
|
4007
4007
|
UPDATE ${this.qs(mj_core_schema(), 'EntityField')}
|
|
4008
4008
|
SET UserSearchPredicateAPI = '${sp.predicate}'
|
|
4009
4009
|
WHERE ID = '${field.ID}'
|
|
4010
|
-
AND AutoUpdateUserSearchPredicate =
|
|
4010
|
+
AND AutoUpdateUserSearchPredicate = ${this.boolLit(true)}
|
|
4011
4011
|
`);
|
|
4012
4012
|
}
|
|
4013
4013
|
}
|
|
@@ -4019,14 +4019,14 @@ export class ManageMetadataBase {
|
|
|
4019
4019
|
if (result.allowUserSearch == null || !entity.AutoUpdateAllowUserSearchAPI) {
|
|
4020
4020
|
return;
|
|
4021
4021
|
}
|
|
4022
|
-
const newValue = result.allowUserSearch
|
|
4023
|
-
const currentValue = entity.AllowUserSearchAPI
|
|
4022
|
+
const newValue = result.allowUserSearch;
|
|
4023
|
+
const currentValue = !!entity.AllowUserSearchAPI;
|
|
4024
4024
|
if (newValue !== currentValue) {
|
|
4025
4025
|
sqlStatements.push(`
|
|
4026
4026
|
UPDATE ${this.qs(mj_core_schema(), 'Entity')}
|
|
4027
|
-
SET AllowUserSearchAPI = ${newValue}
|
|
4027
|
+
SET AllowUserSearchAPI = ${this.boolLit(newValue)}
|
|
4028
4028
|
WHERE ID = '${entity.ID}'
|
|
4029
|
-
AND AutoUpdateAllowUserSearchAPI =
|
|
4029
|
+
AND AutoUpdateAllowUserSearchAPI = ${this.boolLit(true)}
|
|
4030
4030
|
`);
|
|
4031
4031
|
}
|
|
4032
4032
|
}
|
|
@@ -4036,14 +4036,14 @@ export class ManageMetadataBase {
|
|
|
4036
4036
|
applyFullTextSearchUpdates(sqlStatements, entity, fields, result) {
|
|
4037
4037
|
// Entity-level FullTextSearchEnabled
|
|
4038
4038
|
if (result.enableFullTextSearch != null && entity.AutoUpdateFullTextSearch) {
|
|
4039
|
-
const newValue = result.enableFullTextSearch
|
|
4040
|
-
const currentValue = entity.FullTextSearchEnabled
|
|
4039
|
+
const newValue = result.enableFullTextSearch;
|
|
4040
|
+
const currentValue = !!entity.FullTextSearchEnabled;
|
|
4041
4041
|
if (newValue !== currentValue) {
|
|
4042
4042
|
sqlStatements.push(`
|
|
4043
4043
|
UPDATE ${this.qs(mj_core_schema(), 'Entity')}
|
|
4044
|
-
SET FullTextSearchEnabled = ${newValue}
|
|
4044
|
+
SET FullTextSearchEnabled = ${this.boolLit(newValue)}
|
|
4045
4045
|
WHERE ID = '${entity.ID}'
|
|
4046
|
-
AND AutoUpdateFullTextSearch =
|
|
4046
|
+
AND AutoUpdateFullTextSearch = ${this.boolLit(true)}
|
|
4047
4047
|
`);
|
|
4048
4048
|
}
|
|
4049
4049
|
}
|
|
@@ -4063,9 +4063,9 @@ export class ManageMetadataBase {
|
|
|
4063
4063
|
if (!field.FullTextSearchEnabled) {
|
|
4064
4064
|
sqlStatements.push(`
|
|
4065
4065
|
UPDATE ${this.qs(mj_core_schema(), 'EntityField')}
|
|
4066
|
-
SET FullTextSearchEnabled =
|
|
4066
|
+
SET FullTextSearchEnabled = ${this.boolLit(true)}
|
|
4067
4067
|
WHERE ID = '${field.ID}'
|
|
4068
|
-
AND AutoUpdateFullTextSearch =
|
|
4068
|
+
AND AutoUpdateFullTextSearch = ${this.boolLit(true)}
|
|
4069
4069
|
`);
|
|
4070
4070
|
}
|
|
4071
4071
|
}
|
|
@@ -4135,9 +4135,9 @@ export class ManageMetadataBase {
|
|
|
4135
4135
|
if (shouldSupportGeo !== currentValue) {
|
|
4136
4136
|
await this.LogSQLAndExecute(pool, `
|
|
4137
4137
|
UPDATE ${this.qs(schema, 'Entity')}
|
|
4138
|
-
SET ${this.qi('SupportsGeoCoding')} = ${shouldSupportGeo
|
|
4139
|
-
WHERE ${this.qi('ID')} = '${entity.ID}' AND ${this.qi('AutoUpdateSupportsGeoCoding')} =
|
|
4140
|
-
`, `Set SupportsGeoCoding = ${shouldSupportGeo
|
|
4138
|
+
SET ${this.qi('SupportsGeoCoding')} = ${this.boolLit(shouldSupportGeo)}
|
|
4139
|
+
WHERE ${this.qi('ID')} = '${entity.ID}' AND ${this.qi('AutoUpdateSupportsGeoCoding')} = ${this.boolLit(true)}
|
|
4140
|
+
`, `Set SupportsGeoCoding = ${shouldSupportGeo} for ${entity.Name}`);
|
|
4141
4141
|
logStatus(` Entity ${entity.Name}: SupportsGeoCoding = ${shouldSupportGeo ? 1 : 0} (auto-detected from ${hasGeoFields ? 'LLM' : 'existing'} geo fields)`);
|
|
4142
4142
|
// Queue for late-phase view regeneration — the view was already generated
|
|
4143
4143
|
// before this flag was set, so it needs to be regenerated with the geo JOIN
|
|
@@ -4229,7 +4229,7 @@ export class ManageMetadataBase {
|
|
|
4229
4229
|
SET
|
|
4230
4230
|
${setClauses.join(',\n ')}
|
|
4231
4231
|
WHERE
|
|
4232
|
-
ID = '${field.ID}' AND AutoUpdateCategory =
|
|
4232
|
+
ID = '${field.ID}' AND AutoUpdateCategory = ${this.boolLit(true)}`);
|
|
4233
4233
|
}
|
|
4234
4234
|
}
|
|
4235
4235
|
else if (!field) {
|
|
@@ -4346,14 +4346,13 @@ WHERE
|
|
|
4346
4346
|
* Only called for NEW entities to set DefaultForNewUser.
|
|
4347
4347
|
*/
|
|
4348
4348
|
async applyEntityImportance(pool, entityId, importance) {
|
|
4349
|
-
const defaultForNewUser = importance.defaultForNewUser ? 1 : 0;
|
|
4350
4349
|
const updateSQL = `
|
|
4351
4350
|
UPDATE ${this.qs(mj_core_schema(), 'ApplicationEntity')}
|
|
4352
|
-
SET DefaultForNewUser = ${defaultForNewUser}, __mj_UpdatedAt = ${this.utcNow()}
|
|
4351
|
+
SET DefaultForNewUser = ${this.boolLit(importance.defaultForNewUser)}, __mj_UpdatedAt = ${this.utcNow()}
|
|
4353
4352
|
WHERE EntityID = '${entityId}'
|
|
4354
4353
|
`;
|
|
4355
4354
|
try {
|
|
4356
|
-
await this.LogSQLAndExecute(pool, updateSQL, `Set DefaultForNewUser=${defaultForNewUser} for NEW entity (category: ${importance.entityCategory}, confidence: ${importance.confidence})`, false);
|
|
4355
|
+
await this.LogSQLAndExecute(pool, updateSQL, `Set DefaultForNewUser=${importance.defaultForNewUser} for NEW entity (category: ${importance.entityCategory}, confidence: ${importance.confidence})`, false);
|
|
4357
4356
|
logStatus(` Entity importance (NEW Entity): ${importance.entityCategory} (defaultForNewUser: ${importance.defaultForNewUser}, confidence: ${importance.confidence})`);
|
|
4358
4357
|
logStatus(` Reasoning: ${importance.reasoning}`);
|
|
4359
4358
|
}
|