@memberjunction/codegen-lib 2.48.0 → 2.50.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.
Files changed (78) hide show
  1. package/dist/Angular/angular-codegen.d.ts +164 -6
  2. package/dist/Angular/angular-codegen.d.ts.map +1 -1
  3. package/dist/Angular/angular-codegen.js +177 -13
  4. package/dist/Angular/angular-codegen.js.map +1 -1
  5. package/dist/Angular/join-grid-related-entity-component.d.ts +52 -3
  6. package/dist/Angular/join-grid-related-entity-component.d.ts.map +1 -1
  7. package/dist/Angular/join-grid-related-entity-component.js +58 -3
  8. package/dist/Angular/join-grid-related-entity-component.js.map +1 -1
  9. package/dist/Angular/related-entity-components.d.ts +99 -42
  10. package/dist/Angular/related-entity-components.d.ts.map +1 -1
  11. package/dist/Angular/related-entity-components.js +116 -26
  12. package/dist/Angular/related-entity-components.js.map +1 -1
  13. package/dist/Angular/timeline-related-entity-component.d.ts +46 -7
  14. package/dist/Angular/timeline-related-entity-component.d.ts.map +1 -1
  15. package/dist/Angular/timeline-related-entity-component.js +64 -7
  16. package/dist/Angular/timeline-related-entity-component.js.map +1 -1
  17. package/dist/Angular/user-view-grid-related-entity-component.d.ts +33 -1
  18. package/dist/Angular/user-view-grid-related-entity-component.d.ts.map +1 -1
  19. package/dist/Angular/user-view-grid-related-entity-component.js +33 -1
  20. package/dist/Angular/user-view-grid-related-entity-component.js.map +1 -1
  21. package/dist/Config/config.d.ts +369 -45
  22. package/dist/Config/config.d.ts.map +1 -1
  23. package/dist/Config/config.js +136 -2
  24. package/dist/Config/config.js.map +1 -1
  25. package/dist/Config/db-connection.d.ts +17 -3
  26. package/dist/Config/db-connection.d.ts.map +1 -1
  27. package/dist/Config/db-connection.js +31 -19
  28. package/dist/Config/db-connection.js.map +1 -1
  29. package/dist/Database/dbSchema.d.ts +44 -1
  30. package/dist/Database/dbSchema.d.ts.map +1 -1
  31. package/dist/Database/dbSchema.js +44 -1
  32. package/dist/Database/dbSchema.js.map +1 -1
  33. package/dist/Database/manage-metadata.d.ts +52 -46
  34. package/dist/Database/manage-metadata.d.ts.map +1 -1
  35. package/dist/Database/manage-metadata.js +221 -167
  36. package/dist/Database/manage-metadata.js.map +1 -1
  37. package/dist/Database/reorder-columns.d.ts +2 -2
  38. package/dist/Database/reorder-columns.d.ts.map +1 -1
  39. package/dist/Database/reorder-columns.js +23 -17
  40. package/dist/Database/reorder-columns.js.map +1 -1
  41. package/dist/Database/sql.d.ts +4 -4
  42. package/dist/Database/sql.d.ts.map +1 -1
  43. package/dist/Database/sql.js +2 -2
  44. package/dist/Database/sql.js.map +1 -1
  45. package/dist/Database/sql_codegen.d.ts +15 -15
  46. package/dist/Database/sql_codegen.d.ts.map +1 -1
  47. package/dist/Database/sql_codegen.js +184 -112
  48. package/dist/Database/sql_codegen.js.map +1 -1
  49. package/dist/Misc/advanced_generation.js +81 -81
  50. package/dist/Misc/advanced_generation.js.map +1 -1
  51. package/dist/Misc/entity_subclasses_codegen.d.ts +5 -5
  52. package/dist/Misc/entity_subclasses_codegen.d.ts.map +1 -1
  53. package/dist/Misc/entity_subclasses_codegen.js +10 -8
  54. package/dist/Misc/entity_subclasses_codegen.js.map +1 -1
  55. package/dist/Misc/graphql_server_codegen.d.ts.map +1 -1
  56. package/dist/Misc/graphql_server_codegen.js +33 -28
  57. package/dist/Misc/graphql_server_codegen.js.map +1 -1
  58. package/dist/Misc/sql_logging.d.ts +2 -2
  59. package/dist/Misc/sql_logging.d.ts.map +1 -1
  60. package/dist/Misc/sql_logging.js +4 -3
  61. package/dist/Misc/sql_logging.js.map +1 -1
  62. package/dist/Misc/status_logging.d.ts +37 -0
  63. package/dist/Misc/status_logging.d.ts.map +1 -1
  64. package/dist/Misc/status_logging.js +145 -3
  65. package/dist/Misc/status_logging.js.map +1 -1
  66. package/dist/Misc/system_integrity.d.ts +9 -9
  67. package/dist/Misc/system_integrity.d.ts.map +1 -1
  68. package/dist/Misc/system_integrity.js +23 -21
  69. package/dist/Misc/system_integrity.js.map +1 -1
  70. package/dist/index.d.ts +45 -7
  71. package/dist/index.d.ts.map +1 -1
  72. package/dist/index.js +51 -7
  73. package/dist/index.js.map +1 -1
  74. package/dist/runCodeGen.d.ts +84 -6
  75. package/dist/runCodeGen.d.ts.map +1 -1
  76. package/dist/runCodeGen.js +242 -82
  77. package/dist/runCodeGen.js.map +1 -1
  78. package/package.json +14 -14
@@ -27,6 +27,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
29
  exports.ManageMetadataBase = exports.ValidatorResult = void 0;
30
+ const sql = __importStar(require("mssql"));
30
31
  const config_1 = require("../Config/config");
31
32
  const core_1 = require("@memberjunction/core");
32
33
  const status_logging_1 = require("../Misc/status_logging");
@@ -39,23 +40,22 @@ const path_1 = __importDefault(require("path"));
39
40
  const sql_logging_1 = require("../Misc/sql_logging");
40
41
  const aiengine_1 = require("@memberjunction/aiengine");
41
42
  class ValidatorResult {
42
- constructor() {
43
- this.entityName = "";
44
- this.sourceCheckConstraint = "";
45
- this.functionText = "";
46
- this.functionName = "";
47
- this.functionDescription = "";
48
- /**
49
- * The ID value in the Generated Codes entity that was created for this validator.
50
- */
51
- this.generatedCodeId = "";
52
- /**
53
- * The ID for the AI Model that was used to generate the code
54
- */
55
- this.aiModelID = "";
56
- this.wasGenerated = true;
57
- this.success = false;
58
- }
43
+ entityName = "";
44
+ fieldName;
45
+ sourceCheckConstraint = "";
46
+ functionText = "";
47
+ functionName = "";
48
+ functionDescription = "";
49
+ /**
50
+ * The ID value in the Generated Codes entity that was created for this validator.
51
+ */
52
+ generatedCodeId = "";
53
+ /**
54
+ * The ID for the AI Model that was used to generate the code
55
+ */
56
+ aiModelID = "";
57
+ wasGenerated = true;
58
+ success = false;
59
59
  }
60
60
  exports.ValidatorResult = ValidatorResult;
61
61
  /**
@@ -63,24 +63,25 @@ exports.ValidatorResult = ValidatorResult;
63
63
  * to properly register your subclass with a priority of 1+ to ensure it gets instantiated.
64
64
  */
65
65
  class ManageMetadataBase {
66
- constructor() {
67
- this._sqlUtilityObject = global_1.MJGlobal.Instance.ClassFactory.CreateInstance(sql_1.SQLUtilityBase);
68
- }
66
+ _sqlUtilityObject = global_1.MJGlobal.Instance.ClassFactory.CreateInstance(sql_1.SQLUtilityBase);
69
67
  get SQLUtilityObject() {
70
68
  return this._sqlUtilityObject;
71
69
  }
70
+ static _newEntityList = [];
72
71
  /**
73
72
  * Globally scoped list of entities that have been created during the metadata management process.
74
73
  */
75
74
  static get newEntityList() {
76
75
  return this._newEntityList;
77
76
  }
77
+ static _modifiedEntityList = [];
78
78
  /**
79
79
  * Globally scoped list of entities that have been modified during the metadata management process.
80
80
  */
81
81
  static get modifiedEntityList() {
82
82
  return this._modifiedEntityList;
83
83
  }
84
+ static _generatedValidators = [];
84
85
  /**
85
86
  * Globally scoped list of validators that have been generated during the metadata management process.
86
87
  */
@@ -89,30 +90,30 @@ class ManageMetadataBase {
89
90
  }
90
91
  /**
91
92
  * Primary function to manage metadata within the CodeGen system. This function will call a series of sub-functions to manage the metadata.
92
- * @param ds - the DataSource object to use for querying and updating the database
93
+ * @param pool - the ConnectionPool object to use for querying and updating the database
93
94
  * @returns
94
95
  */
95
- async manageMetadata(ds, currentUser) {
96
+ async manageMetadata(pool, currentUser) {
96
97
  const md = new core_1.Metadata();
97
98
  const excludeSchemas = config_1.configInfo.excludeSchemas ? config_1.configInfo.excludeSchemas : [];
98
99
  let bSuccess = true;
99
100
  let start = new Date();
100
101
  (0, status_logging_1.logStatus)(' Creating new entities...');
101
- if (!await this.createNewEntities(ds)) {
102
+ if (!await this.createNewEntities(pool)) {
102
103
  (0, status_logging_1.logError)(' Error creating new entities');
103
104
  bSuccess = false;
104
105
  }
105
106
  (0, status_logging_1.logStatus)(` > Created new entities in ${(new Date().getTime() - start.getTime()) / 1000} seconds`);
106
107
  start = new Date();
107
108
  (0, status_logging_1.logStatus)(' Updating existing entities...');
108
- if (!await this.updateExistingEntitiesFromSchema(ds, excludeSchemas)) {
109
+ if (!await this.updateExistingEntitiesFromSchema(pool, excludeSchemas)) {
109
110
  (0, status_logging_1.logError)(' Error updating existing entities');
110
111
  bSuccess = false;
111
112
  }
112
113
  (0, status_logging_1.logStatus)(` > Updated existing entities in ${(new Date().getTime() - start.getTime()) / 1000} seconds`);
113
114
  start = new Date();
114
115
  (0, status_logging_1.logStatus)(' Scanning for tables that were deleted where entity metadata still exists...');
115
- if (!await this.checkAndRemoveMetadataForDeletedTables(ds, excludeSchemas)) {
116
+ if (!await this.checkAndRemoveMetadataForDeletedTables(pool, excludeSchemas)) {
116
117
  (0, status_logging_1.logError)(' Error removing metadata for tables that were removed');
117
118
  bSuccess = false;
118
119
  }
@@ -124,7 +125,7 @@ class ManageMetadataBase {
124
125
  const schemasToExclude = (0, config_1.getSettingValue)('recompile_mj_views', true)
125
126
  ? excludeSchemas.filter((s) => s !== adminSchema)
126
127
  : excludeSchemas;
127
- if (!await sqlUtility.recompileAllBaseViews(ds, schemasToExclude, true, ManageMetadataBase._newEntityList /*exclude the newly created entities from the above step the first time we run as those views don't exist yet*/)) {
128
+ if (!await sqlUtility.recompileAllBaseViews(pool, schemasToExclude, true, ManageMetadataBase._newEntityList /*exclude the newly created entities from the above step the first time we run as those views don't exist yet*/)) {
128
129
  (0, status_logging_1.logMessage)(' Warning: Non-Fatal error recompiling base views', core_1.SeverityType.Warning, false);
129
130
  // many times the former versions of base views will NOT succesfully recompile, so don't consider that scenario to be a
130
131
  // failure for this entire function
@@ -132,40 +133,41 @@ class ManageMetadataBase {
132
133
  (0, status_logging_1.logStatus)(` > Recompiled base views in ${(new Date().getTime() - start.getTime()) / 1000} seconds`);
133
134
  start = new Date();
134
135
  (0, status_logging_1.logStatus)(' Managing entity fields...');
135
- if (!await this.manageEntityFields(ds, excludeSchemas, false, false, currentUser)) {
136
+ if (!await this.manageEntityFields(pool, excludeSchemas, false, false, currentUser)) {
136
137
  (0, status_logging_1.logError)(' Error managing entity fields');
137
138
  bSuccess = false;
138
139
  }
139
140
  (0, status_logging_1.logStatus)(` > Managed entity fields in ${(new Date().getTime() - start.getTime()) / 1000} seconds`);
140
141
  start = new Date();
141
142
  (0, status_logging_1.logStatus)(' Managing entity relationships...');
142
- if (!await this.manageEntityRelationships(ds, excludeSchemas, md)) {
143
+ if (!await this.manageEntityRelationships(pool, excludeSchemas, md)) {
143
144
  (0, status_logging_1.logError)(' Error managing entity relationships');
144
145
  bSuccess = false;
145
146
  }
146
147
  (0, status_logging_1.logStatus)(` > Managed entity relationships in ${(new Date().getTime() - start.getTime()) / 1000} seconds`);
147
148
  if (ManageMetadataBase.newEntityList.length > 0) {
148
- await this.generateNewEntityDescriptions(ds, md); // don't pass excludeSchemas becuase by definition this is the NEW entities we created
149
+ await this.generateNewEntityDescriptions(pool, md); // don't pass excludeSchemas becuase by definition this is the NEW entities we created
149
150
  }
150
- const veResult = await this.manageVirtualEntities(ds);
151
+ const veResult = await this.manageVirtualEntities(pool);
151
152
  if (!veResult.success) {
152
153
  (0, status_logging_1.logError)(' Error managing virtual entities');
153
154
  bSuccess = false;
154
155
  }
155
156
  return bSuccess;
156
157
  }
157
- async manageVirtualEntities(ds) {
158
+ async manageVirtualEntities(pool) {
158
159
  let bSuccess = true;
159
160
  // virtual entities are records defined in the entity metadata and do NOT define a distinct base table
160
161
  // but they do specify a base view. We DO NOT generate a base view for a virtual entity, we simply use it to figure
161
162
  // 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
162
163
  const sql = `SELECT * FROM [${(0, config_1.mj_core_schema)()}].vwEntities WHERE VirtualEntity = 1`;
163
- const virtualEntities = await ds.query(sql);
164
+ const virtualEntitiesResult = await pool.request().query(sql);
165
+ const virtualEntities = virtualEntitiesResult.recordset;
164
166
  let anyUpdates = false;
165
167
  if (virtualEntities && virtualEntities.length > 0) {
166
168
  // we have 1+ virtual entities, now loop through them and process each one
167
169
  for (const ve of virtualEntities) {
168
- const { success, updatedEntity } = await this.manageSingleVirtualEntity(ds, ve);
170
+ const { success, updatedEntity } = await this.manageSingleVirtualEntity(pool, ve);
169
171
  anyUpdates = anyUpdates || updatedEntity;
170
172
  if (!success) {
171
173
  (0, status_logging_1.logError)(` Error managing virtual entity ${ve.Name}`);
@@ -175,7 +177,7 @@ class ManageMetadataBase {
175
177
  }
176
178
  return { success: bSuccess, anyUpdates: anyUpdates };
177
179
  }
178
- async manageSingleVirtualEntity(ds, virtualEntity) {
180
+ async manageSingleVirtualEntity(pool, virtualEntity) {
179
181
  let bSuccess = true;
180
182
  let bUpdated = false;
181
183
  try {
@@ -194,7 +196,8 @@ class ManageMetadataBase {
194
196
  SCHEMA_NAME(v.schema_id) = '${virtualEntity.SchemaName}'
195
197
  ORDER BY
196
198
  c.column_id`;
197
- const veFields = await ds.query(sql);
199
+ const veFieldsResult = await pool.request().query(sql);
200
+ const veFields = veFieldsResult.recordset;
198
201
  if (veFields && veFields.length > 0) {
199
202
  // we have 1+ fields, now loop through them and process each one
200
203
  // first though, remove any fields that are no longer in the view
@@ -209,7 +212,7 @@ class ManageMetadataBase {
209
212
  if (removeList.length > 0) {
210
213
  const sqlRemove = `DELETE FROM [${(0, config_1.mj_core_schema)()}].EntityField WHERE ID IN (${removeList.map(removeId => `'${removeId}'`).join(',')})`;
211
214
  // this removes the fields that shouldn't be there anymore
212
- await this.LogSQLAndExecute(ds, sqlRemove, `SQL text to remove fields from entity ${virtualEntity.Name}`);
215
+ await this.LogSQLAndExecute(pool, sqlRemove, `SQL text to remove fields from entity ${virtualEntity.Name}`);
213
216
  bUpdated = true;
214
217
  }
215
218
  // check to see if any of the fields in the virtual entity have Pkey attribute set. If not, we will default to the first field
@@ -218,7 +221,7 @@ class ManageMetadataBase {
218
221
  // now create/update the fields that are in the view
219
222
  for (let i = 0; i < veFields.length; i++) {
220
223
  const vef = veFields[i];
221
- const { success, updatedField } = await this.manageSingleVirtualEntityField(ds, virtualEntity, vef, i + 1, !hasPkey && i === 0);
224
+ const { success, updatedField } = await this.manageSingleVirtualEntityField(pool, virtualEntity, vef, i + 1, !hasPkey && i === 0);
222
225
  bUpdated = bUpdated || updatedField;
223
226
  if (!success) {
224
227
  (0, status_logging_1.logError)(`Error managing virtual entity field ${vef.FieldName} for virtual entity ${virtualEntity.Name}`);
@@ -230,7 +233,7 @@ class ManageMetadataBase {
230
233
  if (bUpdated) {
231
234
  // finally make sure we update the UpdatedAt field for the entity if we made changes to its fields
232
235
  const sqlUpdate = `UPDATE [${(0, config_1.mj_core_schema)()}].Entity SET [${core_1.EntityInfo.UpdatedAtFieldName}]=GETUTCDATE() WHERE ID='${virtualEntity.ID}'`;
233
- await this.LogSQLAndExecute(ds, sqlUpdate, `SQL text to update virtual entity updated date for ${virtualEntity.Name}`);
236
+ await this.LogSQLAndExecute(pool, sqlUpdate, `SQL text to update virtual entity updated date for ${virtualEntity.Name}`);
234
237
  }
235
238
  return { success: bSuccess, updatedEntity: bUpdated };
236
239
  }
@@ -239,7 +242,7 @@ class ManageMetadataBase {
239
242
  return { success: false, updatedEntity: bUpdated };
240
243
  }
241
244
  }
242
- async manageSingleVirtualEntityField(ds, virtualEntity, veField, fieldSequence, makePrimaryKey) {
245
+ async manageSingleVirtualEntityField(pool, virtualEntity, veField, fieldSequence, makePrimaryKey) {
243
246
  // this protected checks to see if the field exists in the entity definition, and if not, adds it
244
247
  // if it exist it updates the entity field to match the view's data type and nullability attributes
245
248
  // first, get the entity definition
@@ -271,7 +274,7 @@ class ManageMetadataBase {
271
274
  Scale=${veField.Scale}
272
275
  WHERE
273
276
  ID = '${field.ID}'`; // don't need to update the __mj_UpdatedAt field here, that happens automatically via the trigger
274
- await this.LogSQLAndExecute(ds, sqlUpdate, `SQL text to update virtual entity field ${veField.FieldName} for entity ${virtualEntity.Name}`);
277
+ await this.LogSQLAndExecute(pool, sqlUpdate, `SQL text to update virtual entity field ${veField.FieldName} for entity ${virtualEntity.Name}`);
275
278
  didUpdate = true;
276
279
  }
277
280
  }
@@ -286,7 +289,7 @@ class ManageMetadataBase {
286
289
  ${veField.Length}, ${veField.Precision}, ${veField.Scale},
287
290
  ${fieldSequence}, ${makePrimaryKey ? 1 : 0}, ${makePrimaryKey ? 1 : 0}
288
291
  )`;
289
- await this.LogSQLAndExecute(ds, sqlAdd, `SQL text to add virtual entity field ${veField.FieldName} for entity ${virtualEntity.Name}`);
292
+ await this.LogSQLAndExecute(pool, sqlAdd, `SQL text to add virtual entity field ${veField.FieldName} for entity ${virtualEntity.Name}`);
290
293
  didUpdate = true;
291
294
  }
292
295
  }
@@ -294,25 +297,25 @@ class ManageMetadataBase {
294
297
  }
295
298
  /**
296
299
  * This method creates and updates relationships in the metadata based on foreign key relationships in the database.
297
- * @param ds
300
+ * @param pool
298
301
  * @param excludeSchemas - specify any schemas to exclude here and any relationships to/from the specified schemas will be ignored
299
302
  * @param md
300
303
  * @returns
301
304
  */
302
- async manageEntityRelationships(ds, excludeSchemas, md, batchItems = 5) {
305
+ async manageEntityRelationships(pool, excludeSchemas, md, batchItems = 5) {
303
306
  let bResult = true;
304
- bResult = bResult && await this.manageManyToManyEntityRelationships(ds, excludeSchemas, batchItems);
305
- bResult = bResult && await this.manageOneToManyEntityRelationships(ds, excludeSchemas, md, batchItems);
307
+ bResult = bResult && await this.manageManyToManyEntityRelationships(pool, excludeSchemas, batchItems);
308
+ bResult = bResult && await this.manageOneToManyEntityRelationships(pool, excludeSchemas, md, batchItems);
306
309
  return bResult;
307
310
  }
308
311
  /**
309
312
  * Manages 1->M relationships between entities in the metadata based on foreign key relationships in the database.
310
- * @param ds
313
+ * @param pool
311
314
  * @param excludeSchemas - specify any schemas to exclude here and any relationships to/from the specified schemas will be ignored
312
315
  * @param md
313
316
  * @returns
314
317
  */
315
- async manageOneToManyEntityRelationships(ds, excludeSchemas, md, batchItems = 5) {
318
+ async manageOneToManyEntityRelationships(pool, excludeSchemas, md, batchItems = 5) {
316
319
  // the way this works is that we look for entities in our catalog and we look for
317
320
  // foreign keys in those entities. For example, if we saw an entity called Persons and that entity
318
321
  // had a foreign key linking to an entity called Organizations via a field called OrganizationID, then we would create a relationship
@@ -334,17 +337,20 @@ class ManageMetadataBase {
334
337
  IsVirtual = 0 AND
335
338
  EntityID NOT IN (SELECT ID FROM ${(0, config_1.mj_core_schema)()}.Entity WHERE SchemaName IN (${excludeSchemas.map(s => `'${s}'`).join(',')}))
336
339
  ORDER BY RelatedEntityID`;
337
- const entityFields = await ds.query(sSQL);
340
+ const entityFieldsResult = await pool.request().query(sSQL);
341
+ const entityFields = entityFieldsResult.recordset;
338
342
  // Get the relationship counts for each entity
339
343
  const sSQLRelationshipCount = `SELECT EntityID, COUNT(*) AS Count FROM ${(0, config_1.mj_core_schema)()}.EntityRelationship GROUP BY EntityID`;
340
- const relationshipCounts = await ds.query(sSQLRelationshipCount);
344
+ const relationshipCountsResult = await pool.request().query(sSQLRelationshipCount);
345
+ const relationshipCounts = relationshipCountsResult.recordset;
341
346
  const relationshipCountMap = new Map();
342
347
  for (const rc of relationshipCounts) {
343
348
  relationshipCountMap.set(rc.EntityID, rc.Count);
344
349
  }
345
350
  // get all relationships in one query for performance improvement
346
351
  const sSQLRelationship = `SELECT * FROM ${(0, config_1.mj_core_schema)()}.EntityRelationship`;
347
- const allRelationships = await ds.query(sSQLRelationship);
352
+ const allRelationshipsResult = await pool.request().query(sSQLRelationship);
353
+ const allRelationships = allRelationshipsResult.recordset;
348
354
  // Function to process a batch of entity fields
349
355
  const processBatch = async (batch) => {
350
356
  let batchSQL = '';
@@ -374,7 +380,7 @@ class ManageMetadataBase {
374
380
  }
375
381
  });
376
382
  if (batchSQL.length > 0) {
377
- await this.LogSQLAndExecute(ds, batchSQL, `SQL text to create Entitiy Relationships`);
383
+ await this.LogSQLAndExecute(pool, batchSQL, `SQL text to create Entitiy Relationships`);
378
384
  }
379
385
  };
380
386
  // Split entityFields into batches and process each batch
@@ -395,10 +401,11 @@ class ManageMetadataBase {
395
401
  * @param ds
396
402
  * @param excludeSchemas
397
403
  */
398
- async checkAndRemoveMetadataForDeletedTables(ds, excludeSchemas) {
404
+ async checkAndRemoveMetadataForDeletedTables(pool, excludeSchemas) {
399
405
  try {
400
406
  const sql = `SELECT * FROM ${(0, config_1.mj_core_schema)()}.vwEntitiesWithMissingBaseTables WHERE VirtualEntity=0`;
401
- const entities = await ds.query(sql);
407
+ const entitiesResult = await pool.request().query(sql);
408
+ const entities = entitiesResult.recordset;
402
409
  if (entities && entities.length > 0) {
403
410
  for (const e of entities) {
404
411
  // for the given entity, wipe out the entity metadata and its core deps.
@@ -406,15 +413,15 @@ class ManageMetadataBase {
406
413
  // for the admin to handle manually
407
414
  try {
408
415
  const sqlDelete = `__mj.spDeleteEntityWithCoreDependencies @EntityID='${e.ID}'`;
409
- await this.LogSQLAndExecute(ds, sqlDelete, `SQL text to remove entity ${e.Name}`);
416
+ await this.LogSQLAndExecute(pool, sqlDelete, `SQL text to remove entity ${e.Name}`);
410
417
  (0, status_logging_1.logStatus)(` > Removed metadata for table ${e.SchemaName}.${e.BaseTable}`);
411
418
  // next up we need to remove the spCreate, spDelete, spUpdate, BaseView, and FullTextSearchFunction, if provided.
412
419
  // We only remoe these artifcacts when they are generated which is info we have in the BaseViewGenerated, spCreateGenerated, etc. fields
413
- await this.checkDropSQLObject(ds, e.BaseViewGenerated, 'view', e.SchemaName, e.BaseView);
414
- await this.checkDropSQLObject(ds, e.spCreateGenerated, 'procedure', e.SchemaName, e.spCreate ? e.spCreate : `spCreate${e.ClassName}`);
415
- await this.checkDropSQLObject(ds, e.spDeleteGenerated, 'procedure', e.SchemaName, e.spDelete ? e.spDelete : `spDelete${e.ClassName}`);
416
- await this.checkDropSQLObject(ds, e.spUpdateGenerated, 'procedure', e.SchemaName, e.spUpdate ? e.spUpdate : `spUpdate${e.ClassName}`);
417
- await this.checkDropSQLObject(ds, e.FullTextSearchFunctionGenerated, 'function', e.SchemaName, e.FullTextSearchFunction);
420
+ await this.checkDropSQLObject(pool, e.BaseViewGenerated, 'view', e.SchemaName, e.BaseView);
421
+ await this.checkDropSQLObject(pool, e.spCreateGenerated, 'procedure', e.SchemaName, e.spCreate ? e.spCreate : `spCreate${e.ClassName}`);
422
+ await this.checkDropSQLObject(pool, e.spDeleteGenerated, 'procedure', e.SchemaName, e.spDelete ? e.spDelete : `spDelete${e.ClassName}`);
423
+ await this.checkDropSQLObject(pool, e.spUpdateGenerated, 'procedure', e.SchemaName, e.spUpdate ? e.spUpdate : `spUpdate${e.ClassName}`);
424
+ await this.checkDropSQLObject(pool, e.FullTextSearchFunctionGenerated, 'function', e.SchemaName, e.FullTextSearchFunction);
418
425
  }
419
426
  catch (ex) {
420
427
  (0, status_logging_1.logError)(`Error removing metadata for entity ${ex.Name}, error: ${ex}`);
@@ -431,11 +438,11 @@ class ManageMetadataBase {
431
438
  return false;
432
439
  }
433
440
  }
434
- async checkDropSQLObject(ds, proceed, type, schemaName, name) {
441
+ async checkDropSQLObject(pool, proceed, type, schemaName, name) {
435
442
  try {
436
443
  if (proceed && schemaName && name && schemaName.trim().length > 0 && name.trim().length > 0) {
437
444
  const sqlDelete = `DROP ${type} IF EXISTS [${schemaName}].[${name}]`;
438
- await this.LogSQLAndExecute(ds, sqlDelete, `SQL text to remove ${type} ${schemaName}.${name}`);
445
+ await this.LogSQLAndExecute(pool, sqlDelete, `SQL text to remove ${type} ${schemaName}.${name}`);
439
446
  // next up, we need to clean up the cache of saved DB objects that may exist for this entity in the appropriate sub-directory.
440
447
  const sqlOutputDir = (0, config_1.outputDir)('SQL', true);
441
448
  if (sqlOutputDir) {
@@ -464,52 +471,58 @@ class ManageMetadataBase {
464
471
  * @param excludeSchemas
465
472
  * @returns
466
473
  */
467
- async manageManyToManyEntityRelationships(ds, excludeSchemas, batchItems = 5) {
474
+ async manageManyToManyEntityRelationships(pool, excludeSchemas, batchItems = 5) {
468
475
  return true; // not implemented for now, require the admin to manually create these relationships
469
476
  }
470
477
  /**
471
478
  * Manages the creation, updating and deletion of entity field records in the metadata based on the database schema.
472
- * @param ds
479
+ * @param pool
473
480
  * @param excludeSchemas
474
481
  * @returns
475
482
  */
476
- async manageEntityFields(ds, excludeSchemas, skipCreatedAtUpdatedAtDeletedAtFieldValidation, skipEntityFieldValues, currentUser) {
483
+ async manageEntityFields(pool, excludeSchemas, skipCreatedAtUpdatedAtDeletedAtFieldValidation, skipEntityFieldValues, currentUser) {
477
484
  let bSuccess = true;
478
485
  const startTime = new Date();
479
486
  if (!skipCreatedAtUpdatedAtDeletedAtFieldValidation) {
480
- if (!await this.ensureCreatedAtUpdatedAtFieldsExist(ds, excludeSchemas) ||
481
- !await this.ensureDeletedAtFieldsExist(ds, excludeSchemas)) {
487
+ if (!await this.ensureCreatedAtUpdatedAtFieldsExist(pool, excludeSchemas) ||
488
+ !await this.ensureDeletedAtFieldsExist(pool, excludeSchemas)) {
482
489
  (0, status_logging_1.logError)(`Error ensuring ${core_1.EntityInfo.CreatedAtFieldName}, ${core_1.EntityInfo.UpdatedAtFieldName} and ${core_1.EntityInfo.DeletedAtFieldName} fields exist`);
483
490
  bSuccess = false;
484
491
  }
485
492
  (0, status_logging_1.logStatus)(` Ensured ${core_1.EntityInfo.CreatedAtFieldName}/${core_1.EntityInfo.UpdatedAtFieldName}/${core_1.EntityInfo.DeletedAtFieldName} fields exist in ${(new Date().getTime() - startTime.getTime()) / 1000} seconds`);
486
493
  }
487
494
  const step1StartTime = new Date();
488
- if (!await this.deleteUnneededEntityFields(ds, excludeSchemas)) {
495
+ if (!await this.deleteUnneededEntityFields(pool, excludeSchemas)) {
489
496
  (0, status_logging_1.logError)('Error deleting unneeded entity fields');
490
497
  bSuccess = false;
491
498
  }
492
499
  (0, status_logging_1.logStatus)(` Deleted unneeded entity fields in ${(new Date().getTime() - step1StartTime.getTime()) / 1000} seconds`);
500
+ // AN: 14-June-2025 - See note below about the new order of these steps, this must
501
+ // happen before we update existing entity fields from schema.
493
502
  const step2StartTime = new Date();
494
- if (!await this.updateExistingEntityFieldsFromSchema(ds, excludeSchemas)) {
495
- (0, status_logging_1.logError)('Error updating existing entity fields from schema');
503
+ if (!await this.createNewEntityFieldsFromSchema(pool)) { // has its own internal filtering for exclude schema/table so don't pass in
504
+ (0, status_logging_1.logError)('Error creating new entity fields from schema');
496
505
  bSuccess = false;
497
506
  }
498
- (0, status_logging_1.logStatus)(` Updated existing entity fields from schema in ${(new Date().getTime() - step2StartTime.getTime()) / 1000} seconds`);
507
+ (0, status_logging_1.logStatus)(` Created new entity fields from schema in ${(new Date().getTime() - step2StartTime.getTime()) / 1000} seconds`);
508
+ // AN: 14-June-2025 - we are now running this AFTER we create new entity fields from schema
509
+ // which results in the same pattern of behavior as migrations where we first create new fields
510
+ // with VERY HIGH sequence numbers (e.g. 100,000 above what they will be approx) and then
511
+ // we align them properly in sequential order from 1+ via this method below.
499
512
  const step3StartTime = new Date();
500
- if (!await this.createNewEntityFieldsFromSchema(ds)) { // has its own internal filtering for exclude schema/table so don't pass in
501
- (0, status_logging_1.logError)('Error creating new entity fields from schema');
513
+ if (!await this.updateExistingEntityFieldsFromSchema(pool, excludeSchemas)) {
514
+ (0, status_logging_1.logError)('Error updating existing entity fields from schema');
502
515
  bSuccess = false;
503
516
  }
504
- (0, status_logging_1.logStatus)(` Created new entity fields from schema in ${(new Date().getTime() - step3StartTime.getTime()) / 1000} seconds`);
517
+ (0, status_logging_1.logStatus)(` Updated existing entity fields from schema in ${(new Date().getTime() - step3StartTime.getTime()) / 1000} seconds`);
505
518
  const step4StartTime = new Date();
506
- if (!await this.setDefaultColumnWidthWhereNeeded(ds, excludeSchemas)) {
519
+ if (!await this.setDefaultColumnWidthWhereNeeded(pool, excludeSchemas)) {
507
520
  (0, status_logging_1.logError)('Error setting default column width where needed');
508
521
  bSuccess = false;
509
522
  }
510
523
  (0, status_logging_1.logStatus)(` Set default column width where needed in ${(new Date().getTime() - step4StartTime.getTime()) / 1000} seconds`);
511
524
  const step5StartTime = new Date();
512
- if (!await this.updateEntityFieldDisplayNameWhereNull(ds, excludeSchemas)) {
525
+ if (!await this.updateEntityFieldDisplayNameWhereNull(pool, excludeSchemas)) {
513
526
  (0, status_logging_1.logError)('Error updating entity field display name where null');
514
527
  bSuccess = false;
515
528
  }
@@ -517,7 +530,7 @@ class ManageMetadataBase {
517
530
  if (!skipEntityFieldValues) {
518
531
  const step6StartTime = new Date();
519
532
  (0, status_logging_1.logStatus)(` Starting to manage entity field values...`);
520
- if (!await this.manageEntityFieldValuesAndValidatorFunctions(ds, excludeSchemas, currentUser, false)) {
533
+ if (!await this.manageEntityFieldValuesAndValidatorFunctions(pool, excludeSchemas, currentUser, false)) {
521
534
  (0, status_logging_1.logError)('Error managing entity field values');
522
535
  bSuccess = false;
523
536
  }
@@ -529,7 +542,7 @@ class ManageMetadataBase {
529
542
  /**
530
543
  * This method ensures that the __mj_DeletedAt field exists in each entity that has DeleteType=Soft. If the field does not exist, it is created.
531
544
  */
532
- async ensureDeletedAtFieldsExist(ds, excludeSchemas) {
545
+ async ensureDeletedAtFieldsExist(pool, excludeSchemas) {
533
546
  try {
534
547
  const sqlEntities = `SELECT
535
548
  *
@@ -539,7 +552,8 @@ class ManageMetadataBase {
539
552
  VirtualEntity=0 AND
540
553
  DeleteType='Soft' AND
541
554
  SchemaName NOT IN (${excludeSchemas.map(s => `'${s}'`).join(',')})`;
542
- const entities = await ds.query(sqlEntities);
555
+ const entitiesResult = await pool.request().query(sqlEntities);
556
+ const entities = entitiesResult.recordset;
543
557
  let overallResult = true;
544
558
  if (entities.length > 0) {
545
559
  // we have 1+ entities that need the special fields, so loop through them and ensure the fields exist
@@ -549,12 +563,13 @@ class ManageMetadataBase {
549
563
  WHERE
550
564
  ${entities.map((e) => `(TABLE_SCHEMA='${e.SchemaName}' AND TABLE_NAME='${e.BaseTable}')`).join(' OR ')}
551
565
  AND COLUMN_NAME='${core_1.EntityInfo.DeletedAtFieldName}'`;
552
- const result = await ds.query(sql);
566
+ const resultResult = await pool.request().query(sql);
567
+ const result = resultResult.recordset;
553
568
  for (const e of entities) {
554
569
  const eResult = result.filter((r) => r.TABLE_NAME === e.BaseTable && r.TABLE_SCHEMA === e.SchemaName); // get just the fields for this entity
555
570
  const deletedAt = eResult.find((r) => r.COLUMN_NAME.trim().toLowerCase() === core_1.EntityInfo.DeletedAtFieldName.trim().toLowerCase());
556
571
  // now, if we have the fields, we need to check the default value and update if necessary
557
- const fieldResult = await this.ensureSpecialDateFieldExistsAndHasCorrectDefaultValue(ds, e, core_1.EntityInfo.DeletedAtFieldName, deletedAt, true);
572
+ const fieldResult = await this.ensureSpecialDateFieldExistsAndHasCorrectDefaultValue(pool, e, core_1.EntityInfo.DeletedAtFieldName, deletedAt, true);
558
573
  overallResult = overallResult && fieldResult;
559
574
  }
560
575
  }
@@ -569,9 +584,9 @@ class ManageMetadataBase {
569
584
  * This method ensures that the __mj_CreatedAt and __mj_UpdatedAt fields exist in each entity that has TrackRecordChanges set to true. If the fields do not exist, they are created.
570
585
  * If the fields exist but have incorrect default values, the default values are updated. The default value that is to be used for these special fields is GETUTCDATE() which is the
571
586
  * UTC date and time. This method is called as part of the manageEntityFields method and is not intended to be called directly.
572
- * @param ds
587
+ * @param pool
573
588
  */
574
- async ensureCreatedAtUpdatedAtFieldsExist(ds, excludeSchemas) {
589
+ async ensureCreatedAtUpdatedAtFieldsExist(pool, excludeSchemas) {
575
590
  try {
576
591
  const sqlEntities = `SELECT
577
592
  *
@@ -581,7 +596,8 @@ class ManageMetadataBase {
581
596
  VirtualEntity = 0 AND
582
597
  TrackRecordChanges = 1 AND
583
598
  SchemaName NOT IN (${excludeSchemas.map(s => `'${s}'`).join(',')})`;
584
- const entities = await ds.query(sqlEntities);
599
+ const entitiesResult = await pool.request().query(sqlEntities);
600
+ const entities = entitiesResult.recordset;
585
601
  let overallResult = true;
586
602
  if (entities.length > 0) {
587
603
  // we have 1+ entities that need the special fields, so loop through them and ensure the fields exist
@@ -592,15 +608,16 @@ class ManageMetadataBase {
592
608
  WHERE
593
609
  ${entities.map((e) => `(TABLE_SCHEMA='${e.SchemaName}' AND TABLE_NAME='${e.BaseTable}')`).join(' OR ')}
594
610
  AND COLUMN_NAME IN ('${core_1.EntityInfo.CreatedAtFieldName}','${core_1.EntityInfo.UpdatedAtFieldName}')`;
595
- const result = await ds.query(sqlCreatedUpdated);
611
+ const resultResult = await pool.request().query(sqlCreatedUpdated);
612
+ const result = resultResult.recordset;
596
613
  for (const e of entities) {
597
614
  // result has both created at and updated at fields, so filter on the result for each and do what we need to based on that
598
615
  const eResult = result.filter((r) => r.TABLE_NAME === e.BaseTable && r.TABLE_SCHEMA === e.SchemaName); // get just the fields for this entity
599
616
  const createdAt = eResult.find((r) => r.COLUMN_NAME.trim().toLowerCase() === core_1.EntityInfo.CreatedAtFieldName.trim().toLowerCase());
600
617
  const updatedAt = eResult.find((r) => r.COLUMN_NAME.trim().toLowerCase() === core_1.EntityInfo.UpdatedAtFieldName.trim().toLowerCase());
601
618
  // now, if we have the fields, we need to check the default value and update if necessary
602
- const fieldResult = await this.ensureSpecialDateFieldExistsAndHasCorrectDefaultValue(ds, e, core_1.EntityInfo.CreatedAtFieldName, createdAt, false) &&
603
- await this.ensureSpecialDateFieldExistsAndHasCorrectDefaultValue(ds, e, core_1.EntityInfo.UpdatedAtFieldName, updatedAt, false);
619
+ const fieldResult = await this.ensureSpecialDateFieldExistsAndHasCorrectDefaultValue(pool, e, core_1.EntityInfo.CreatedAtFieldName, createdAt, false) &&
620
+ await this.ensureSpecialDateFieldExistsAndHasCorrectDefaultValue(pool, e, core_1.EntityInfo.UpdatedAtFieldName, updatedAt, false);
604
621
  overallResult = overallResult && fieldResult;
605
622
  }
606
623
  }
@@ -618,12 +635,12 @@ class ManageMetadataBase {
618
635
  * @param fieldName
619
636
  * @param currentFieldData
620
637
  */
621
- async ensureSpecialDateFieldExistsAndHasCorrectDefaultValue(ds, entity, fieldName, currentFieldData, allowNull) {
638
+ async ensureSpecialDateFieldExistsAndHasCorrectDefaultValue(pool, entity, fieldName, currentFieldData, allowNull) {
622
639
  try {
623
640
  if (!currentFieldData) {
624
641
  // field doesn't exist, let's create it
625
642
  const sql = `ALTER TABLE [${entity.SchemaName}].[${entity.BaseTable}] ADD ${fieldName} DATETIMEOFFSET ${allowNull ? 'NULL' : 'NOT NULL DEFAULT GETUTCDATE()'}`;
626
- await this.LogSQLAndExecute(ds, sql, `SQL text to add special date field ${fieldName} to entity ${entity.SchemaName}.${entity.BaseTable}`);
643
+ await this.LogSQLAndExecute(pool, sql, `SQL text to add special date field ${fieldName} to entity ${entity.SchemaName}.${entity.BaseTable}`);
627
644
  }
628
645
  else {
629
646
  // field does exist, let's first check the data type/nullability
@@ -632,11 +649,11 @@ class ManageMetadataBase {
632
649
  (currentFieldData.IS_NULLABLE.trim().toLowerCase() === 'no' && allowNull)) {
633
650
  // the column is the wrong type, or has wrong nullability attribute, so let's update it, first removing the default constraint, then
634
651
  // modifying the column, and finally adding the default constraint back in.
635
- await this.dropExistingDefaultConstraint(ds, entity, fieldName);
652
+ await this.dropExistingDefaultConstraint(pool, entity, fieldName);
636
653
  const sql = `ALTER TABLE [${entity.SchemaName}].[${entity.BaseTable}] ALTER COLUMN ${fieldName} DATETIMEOFFSET ${allowNull ? 'NULL' : 'NOT NULL'}`;
637
- await this.LogSQLAndExecute(ds, sql, `SQL text to update special date field ${fieldName} in entity ${entity.SchemaName}.${entity.BaseTable}`);
654
+ await this.LogSQLAndExecute(pool, sql, `SQL text to update special date field ${fieldName} in entity ${entity.SchemaName}.${entity.BaseTable}`);
638
655
  if (!allowNull)
639
- await this.createDefaultConstraintForSpecialDateField(ds, entity, fieldName);
656
+ await this.createDefaultConstraintForSpecialDateField(pool, entity, fieldName);
640
657
  }
641
658
  else {
642
659
  // if we get here that means the column is the correct type and nullability, so now let's check the default value, but we only do that if we are dealing with a
@@ -645,7 +662,7 @@ class ManageMetadataBase {
645
662
  const defaultValue = currentFieldData.COLUMN_DEFAULT;
646
663
  const realDefaultValue = (0, core_1.ExtractActualDefaultValue)(defaultValue);
647
664
  if (!realDefaultValue || realDefaultValue.trim().toLowerCase() !== 'getutcdate()') {
648
- await this.dropAndCreateDefaultConstraintForSpecialDateField(ds, entity, fieldName);
665
+ await this.dropAndCreateDefaultConstraintForSpecialDateField(pool, entity, fieldName);
649
666
  }
650
667
  }
651
668
  }
@@ -661,10 +678,10 @@ class ManageMetadataBase {
661
678
  /**
662
679
  * Creates the default constraint for a special date field. This method is called as part of the ensureSpecialDateFieldExistsAndHasCorrectDefaultValue method and is not intended to be called directly.
663
680
  */
664
- async createDefaultConstraintForSpecialDateField(ds, entity, fieldName) {
681
+ async createDefaultConstraintForSpecialDateField(pool, entity, fieldName) {
665
682
  try {
666
683
  const sqlAddDefaultConstraint = `ALTER TABLE [${entity.SchemaName}].[${entity.BaseTable}] ADD CONSTRAINT DF_${entity.SchemaName}_${(0, core_1.CodeNameFromString)(entity.BaseTable)}_${fieldName} DEFAULT GETUTCDATE() FOR [${fieldName}]`;
667
- await this.LogSQLAndExecute(ds, sqlAddDefaultConstraint, `SQL text to add default constraint for special date field ${fieldName} in entity ${entity.SchemaName}.${entity.BaseTable}`);
684
+ await this.LogSQLAndExecute(pool, sqlAddDefaultConstraint, `SQL text to add default constraint for special date field ${fieldName} in entity ${entity.SchemaName}.${entity.BaseTable}`);
668
685
  }
669
686
  catch (e) {
670
687
  (0, status_logging_1.logError)(e);
@@ -676,18 +693,18 @@ class ManageMetadataBase {
676
693
  * @param entity
677
694
  * @param fieldName
678
695
  */
679
- async dropAndCreateDefaultConstraintForSpecialDateField(ds, entity, fieldName) {
696
+ async dropAndCreateDefaultConstraintForSpecialDateField(pool, entity, fieldName) {
680
697
  // default value is not correct, so let's update it
681
- await this.dropExistingDefaultConstraint(ds, entity, fieldName);
682
- await this.createDefaultConstraintForSpecialDateField(ds, entity, fieldName);
698
+ await this.dropExistingDefaultConstraint(pool, entity, fieldName);
699
+ await this.createDefaultConstraintForSpecialDateField(pool, entity, fieldName);
683
700
  }
684
701
  /**
685
702
  * Drops an existing default constraint from a given column within a given entity, if it exists
686
- * @param ds
703
+ * @param pool
687
704
  * @param entity
688
705
  * @param fieldName
689
706
  */
690
- async dropExistingDefaultConstraint(ds, entity, fieldName) {
707
+ async dropExistingDefaultConstraint(pool, entity, fieldName) {
691
708
  try {
692
709
  const sqlDropDefaultConstraint = `
693
710
  DECLARE @constraintName NVARCHAR(255);
@@ -708,7 +725,7 @@ class ManageMetadataBase {
708
725
  EXEC('ALTER TABLE [${entity.SchemaName}].[${entity.BaseTable}] DROP CONSTRAINT ' + @constraintName);
709
726
  END
710
727
  `;
711
- await this.LogSQLAndExecute(ds, sqlDropDefaultConstraint, `SQL text to drop default existing default constraints in entity ${entity.SchemaName}.${entity.BaseTable}`);
728
+ await this.LogSQLAndExecute(pool, sqlDropDefaultConstraint, `SQL text to drop default existing default constraints in entity ${entity.SchemaName}.${entity.BaseTable}`);
712
729
  }
713
730
  catch (e) {
714
731
  (0, status_logging_1.logError)(e);
@@ -717,10 +734,10 @@ class ManageMetadataBase {
717
734
  /**
718
735
  * This method generates descriptions for entities in teh system where there is no existing description. This is an experimental feature and is done using AI. In order for it
719
736
  * to be invoked, the EntityDescriptions feature must be enabled in the Advanced Generation configuration.
720
- * @param ds
737
+ * @param pool
721
738
  * @param md
722
739
  */
723
- async generateNewEntityDescriptions(ds, md) {
740
+ async generateNewEntityDescriptions(pool, md) {
724
741
  // for the list of new entities, go through and attempt to generate new entity descriptions
725
742
  const ag = new advanced_generation_1.AdvancedGeneration();
726
743
  if (ag.featureEnabled('EntityDescriptions')) {
@@ -731,8 +748,10 @@ class ManageMetadataBase {
731
748
  const userMessage = prompt.userMessage + '\n\n';
732
749
  // now loop through the new entities and generate descriptions for them
733
750
  for (let e of ManageMetadataBase.newEntityList) {
734
- const data = await ds.query(`SELECT * FROM [${(0, config_1.mj_core_schema)()}].vwEntities WHERE Name = '${e}'`);
735
- const fields = await ds.query(`SELECT * FROM [${(0, config_1.mj_core_schema)()}].vwEntityFields WHERE EntityID='${data[0].ID}'`);
751
+ const dataResult = await pool.request().query(`SELECT * FROM [${(0, config_1.mj_core_schema)()}].vwEntities WHERE Name = '${e}'`);
752
+ const data = dataResult.recordset;
753
+ const fieldsResult = await pool.request().query(`SELECT * FROM [${(0, config_1.mj_core_schema)()}].vwEntityFields WHERE EntityID='${data[0].ID}'`);
754
+ const fields = fieldsResult.recordset;
736
755
  const entityUserMessage = userMessage + `Entity Name: ${e},
737
756
  Base Table: ${data[0].BaseTable},
738
757
  Schema: ${data[0].SchemaName}.
@@ -757,7 +776,7 @@ class ManageMetadataBase {
757
776
  const structuredResult = JSON.parse(resultText);
758
777
  if (structuredResult?.entityDescription && structuredResult.entityDescription.length > 0) {
759
778
  const sSQL = `UPDATE [${(0, config_1.mj_core_schema)()}].Entity SET Description = '${structuredResult.entityDescription}' WHERE Name = '${e}'`;
760
- await this.LogSQLAndExecute(ds, sSQL, `SQL text to update entity description for entity ${e}`);
779
+ await this.LogSQLAndExecute(pool, sSQL, `SQL text to update entity description for entity ${e}`);
761
780
  }
762
781
  else {
763
782
  console.warn(' >>> Advanced Generation Error: LLM returned a blank entity description, skipping entity description for entity ' + e);
@@ -781,7 +800,7 @@ class ManageMetadataBase {
781
800
  * @param excludeSchemas
782
801
  * @returns
783
802
  */
784
- async updateEntityFieldDisplayNameWhereNull(ds, excludeSchemas) {
803
+ async updateEntityFieldDisplayNameWhereNull(pool, excludeSchemas) {
785
804
  try {
786
805
  const sql = `SELECT
787
806
  ef.ID, ef.Name
@@ -797,13 +816,14 @@ class ManageMetadataBase {
797
816
  ef.Name <> \'ID\' AND
798
817
  e.SchemaName NOT IN (${excludeSchemas.map(s => `'${s}'`).join(',')})
799
818
  `;
800
- const fields = await ds.query(sql);
819
+ const fieldsResult = await pool.request().query(sql);
820
+ const fields = fieldsResult.recordset;
801
821
  if (fields && fields.length > 0)
802
822
  for (const field of fields) {
803
823
  const sDisplayName = (0, global_1.stripTrailingChars)((0, global_1.convertCamelCaseToHaveSpaces)(field.Name), 'ID', true).trim();
804
824
  if (sDisplayName.length > 0 && sDisplayName.toLowerCase().trim() !== field.Name.toLowerCase().trim()) {
805
825
  const sSQL = `UPDATE [${(0, config_1.mj_core_schema)()}].EntityField SET ${core_1.EntityInfo.UpdatedAtFieldName}=GETUTCDATE(), DisplayName = '${sDisplayName}' WHERE ID = '${field.ID}'`;
806
- await this.LogSQLAndExecute(ds, sSQL, `SQL text to update display name for field ${field.Name}`);
826
+ await this.LogSQLAndExecute(pool, sSQL, `SQL text to update display name for field ${field.Name}`);
807
827
  }
808
828
  }
809
829
  return true;
@@ -817,14 +837,14 @@ class ManageMetadataBase {
817
837
  * This method updates the DefaultColumnWidth field in the EntityField metadata. The default logic uses a stored procedure called spSetDefaultColumnWidthWhereNeeded
818
838
  * which is part of the MJ Core Schema. You can override this method to implement custom logic for setting default column widths. It is NOT recommended to
819
839
  * modify the stored procedure in the MJ Core Schema because your changes will be overriden during a future upgrade.
820
- * @param ds
840
+ * @param pool
821
841
  * @param excludeSchemas
822
842
  * @returns
823
843
  */
824
- async setDefaultColumnWidthWhereNeeded(ds, excludeSchemas) {
844
+ async setDefaultColumnWidthWhereNeeded(pool, excludeSchemas) {
825
845
  try {
826
846
  const sSQL = `EXEC ${(0, config_1.mj_core_schema)()}.spSetDefaultColumnWidthWhereNeeded @ExcludedSchemaNames='${excludeSchemas.join(',')}'`;
827
- await this.LogSQLAndExecute(ds, sSQL, `SQL text to set default column width where needed`, true);
847
+ await this.LogSQLAndExecute(pool, sSQL, `SQL text to set default column width where needed`, true);
828
848
  return true;
829
849
  }
830
850
  catch (e) {
@@ -835,12 +855,18 @@ class ManageMetadataBase {
835
855
  /**
836
856
  * Creates a SQL statement to retrieve all of the pending entity fields that need to be created in the metadata. This method looks for fields that exist in the underlying
837
857
  * database but are NOT in the metadata.
858
+ *
859
+ * IMPORTANT: The sequence shown below has a 100,000 added to it to ensure that there is no collision with existing sequences. The spUpdateExistingEntityFieldsFromSchema
860
+ * stored procedure runs AFTER this method and will correct the sequences to ensure they are in the correct order. In a migration, the spUpdateExistingEntityFieldsFromSchema
861
+ * runs afterwards as well so this behavior ensures CodeGen works consistently.
862
+ *
863
+ * @returns {string} - The SQL statement to retrieve pending entity fields.
838
864
  */
839
865
  getPendingEntityFieldsSELECTSQL() {
840
866
  const sSQL = `WITH NumberedRows AS (
841
867
  SELECT
842
868
  sf.EntityID,
843
- sf.Sequence,
869
+ sf.Sequence + 100000 Sequence, -- add a large number to the sequence to ensure no collision with existing sequences - spUpdateExistingEntityFieldsFromSchema runs AFTER this and will correct them.
844
870
  sf.FieldName,
845
871
  sf.Description,
846
872
  sf.Type,
@@ -1044,11 +1070,14 @@ class ManageMetadataBase {
1044
1070
  }
1045
1071
  return sResult;
1046
1072
  }
1047
- async createNewEntityFieldsFromSchema(ds) {
1073
+ async createNewEntityFieldsFromSchema(pool) {
1048
1074
  try {
1049
1075
  const sSQL = this.getPendingEntityFieldsSELECTSQL();
1050
- const newEntityFields = await ds.query(sSQL);
1051
- await ds.transaction(async () => {
1076
+ const newEntityFieldsResult = await pool.request().query(sSQL);
1077
+ const newEntityFields = newEntityFieldsResult.recordset;
1078
+ const transaction = new sql.Transaction(pool);
1079
+ await transaction.begin();
1080
+ try {
1052
1081
  // wrap in a transaction so we get all of it or none of it
1053
1082
  for (let i = 0; i < newEntityFields.length; ++i) {
1054
1083
  const n = newEntityFields[i];
@@ -1058,7 +1087,7 @@ class ManageMetadataBase {
1058
1087
  const newEntityFieldUUID = this.createNewUUID();
1059
1088
  const sSQLInsert = this.getPendingEntityFieldINSERTSQL(newEntityFieldUUID, n);
1060
1089
  try {
1061
- await this.LogSQLAndExecute(ds, sSQLInsert, `SQL text to insert new entity field`);
1090
+ await this.LogSQLAndExecute(pool, sSQLInsert, `SQL text to insert new entity field`);
1062
1091
  // if we get here, we're okay, otherwise we have an exception, which we want as it blows up transaction
1063
1092
  }
1064
1093
  catch (e) {
@@ -1068,7 +1097,12 @@ class ManageMetadataBase {
1068
1097
  }
1069
1098
  }
1070
1099
  }
1071
- });
1100
+ await transaction.commit();
1101
+ }
1102
+ catch (e) {
1103
+ await transaction.rollback();
1104
+ throw e;
1105
+ }
1072
1106
  // if we get here now send a distinct list of the entities that had new fields to the modified entity list
1073
1107
  // column in the resultset is called EntityName, we dont have to dedupe them here because the method below
1074
1108
  // will do that for us
@@ -1087,12 +1121,12 @@ class ManageMetadataBase {
1087
1121
  * @param relatedEntityNameFieldMap
1088
1122
  * @returns
1089
1123
  */
1090
- async updateEntityFieldRelatedEntityNameFieldMap(ds, entityFieldID, relatedEntityNameFieldMap) {
1124
+ async updateEntityFieldRelatedEntityNameFieldMap(pool, entityFieldID, relatedEntityNameFieldMap) {
1091
1125
  try {
1092
1126
  const sSQL = `EXEC [${(0, config_1.mj_core_schema)()}].spUpdateEntityFieldRelatedEntityNameFieldMap
1093
1127
  @EntityFieldID='${entityFieldID}',
1094
1128
  @RelatedEntityNameFieldMap='${relatedEntityNameFieldMap}'`;
1095
- await this.LogSQLAndExecute(ds, sSQL, `SQL text to update entity field related entity name field map for entity field ID ${entityFieldID}`);
1129
+ await this.LogSQLAndExecute(pool, sSQL, `SQL text to update entity field related entity name field map for entity field ID ${entityFieldID}`);
1096
1130
  return true;
1097
1131
  }
1098
1132
  catch (e) {
@@ -1100,10 +1134,10 @@ class ManageMetadataBase {
1100
1134
  return false;
1101
1135
  }
1102
1136
  }
1103
- async updateExistingEntitiesFromSchema(ds, excludeSchemas) {
1137
+ async updateExistingEntitiesFromSchema(pool, excludeSchemas) {
1104
1138
  try {
1105
1139
  const sSQL = `EXEC [${(0, config_1.mj_core_schema)()}].spUpdateExistingEntitiesFromSchema @ExcludedSchemaNames='${excludeSchemas.join(',')}'`;
1106
- const result = await this.LogSQLAndExecute(ds, sSQL, `SQL text to update existing entities from schema`, true);
1140
+ const result = await this.LogSQLAndExecute(pool, sSQL, `SQL text to update existing entities from schema`, true);
1107
1141
  // result contains the updated entities, and there is a property of each row called Name which has the entity name that was modified
1108
1142
  // add these to the modified entity list if they're not already in there
1109
1143
  if (result && result.length > 0) {
@@ -1125,10 +1159,10 @@ class ManageMetadataBase {
1125
1159
  // now make sure that each of these entity names is in the modified entity list
1126
1160
  ManageMetadataBase._modifiedEntityList = ManageMetadataBase._modifiedEntityList.concat(newlyModifiedEntityNames);
1127
1161
  }
1128
- async updateExistingEntityFieldsFromSchema(ds, excludeSchemas) {
1162
+ async updateExistingEntityFieldsFromSchema(pool, excludeSchemas) {
1129
1163
  try {
1130
1164
  const sSQL = `EXEC [${(0, config_1.mj_core_schema)()}].spUpdateExistingEntityFieldsFromSchema @ExcludedSchemaNames='${excludeSchemas.join(',')}'`;
1131
- const result = await this.LogSQLAndExecute(ds, sSQL, `SQL text to update existing entity fields from schema`, true);
1165
+ const result = await this.LogSQLAndExecute(pool, sSQL, `SQL text to update existing entity fields from schema`, true);
1132
1166
  // result contains the updated entity fields
1133
1167
  // there is a field in there called EntityName. Get a distinct list of entity names from this and add them
1134
1168
  // to the modified entity list if they're not already in there
@@ -1142,10 +1176,10 @@ class ManageMetadataBase {
1142
1176
  return false;
1143
1177
  }
1144
1178
  }
1145
- async deleteUnneededEntityFields(ds, excludeSchemas) {
1179
+ async deleteUnneededEntityFields(pool, excludeSchemas) {
1146
1180
  try {
1147
1181
  const sSQL = `EXEC [${(0, config_1.mj_core_schema)()}].spDeleteUnneededEntityFields @ExcludedSchemaNames='${excludeSchemas.join(',')}'`;
1148
- const result = await this.LogSQLAndExecute(ds, sSQL, `SQL text to delete unneeded entity fields`, true);
1182
+ const result = await this.LogSQLAndExecute(pool, sSQL, `SQL text to delete unneeded entity fields`, true);
1149
1183
  // result contains the DELETED entity fields
1150
1184
  // there is a field in there called Entity. Get a distinct list of entity names from this and add them
1151
1185
  // to the modified entity list if they're not already in there
@@ -1159,7 +1193,7 @@ class ManageMetadataBase {
1159
1193
  return false;
1160
1194
  }
1161
1195
  }
1162
- async manageEntityFieldValuesAndValidatorFunctions(ds, excludeSchemas, currentUser, skipDBUpdate) {
1196
+ async manageEntityFieldValuesAndValidatorFunctions(pool, excludeSchemas, currentUser, skipDBUpdate) {
1163
1197
  try {
1164
1198
  // here we want to get all of the entity fields that have check constraints attached to them. For each field that has a check constraint, we want to
1165
1199
  // evaluate it to see if it is a simple series of OR statements or not, if it is a simple series of OR statements, we can parse the possible values
@@ -1167,11 +1201,14 @@ class ManageMetadataBase {
1167
1201
  // just ignore it.
1168
1202
  const filter = excludeSchemas && excludeSchemas.length > 0 ? ` WHERE SchemaName NOT IN (${excludeSchemas.map(s => `'${s}'`).join(',')})` : '';
1169
1203
  const sSQL = `SELECT * FROM [${(0, config_1.mj_core_schema)()}].vwEntityFieldsWithCheckConstraints${filter}`;
1170
- const result = await ds.query(sSQL);
1204
+ const resultResult = await pool.request().query(sSQL);
1205
+ const result = resultResult.recordset;
1171
1206
  const efvSQL = `SELECT * FROM [${(0, config_1.mj_core_schema)()}].EntityFieldValue`;
1172
- const allEntityFieldValues = await ds.query(efvSQL);
1207
+ const allEntityFieldValuesResult = await pool.request().query(efvSQL);
1208
+ const allEntityFieldValues = allEntityFieldValuesResult.recordset;
1173
1209
  const efSQL = `SELECT * FROM [${(0, config_1.mj_core_schema)()}].vwEntityFields ORDER BY EntityID, Sequence`;
1174
- const allEntityFields = await ds.query(efSQL);
1210
+ const allEntityFieldsResult = await pool.request().query(efSQL);
1211
+ const allEntityFields = allEntityFieldsResult.recordset;
1175
1212
  const generationPromises = [];
1176
1213
  const columnLevelResults = result.filter((r) => r.EntityFieldID); // get the column level constraints
1177
1214
  const tableLevelResults = result.filter((r) => !r.EntityFieldID); // get the table level constraints
@@ -1186,14 +1223,15 @@ class ManageMetadataBase {
1186
1223
  // 1st, flip the order of parsedValues because they come out in reverse order from SQL Server
1187
1224
  parsedValues.reverse();
1188
1225
  // we have parsed values from the check constraint, so sync them with the entity field values
1189
- await this.syncEntityFieldValues(ds, r.EntityFieldID, parsedValues, allEntityFieldValues);
1226
+ await this.syncEntityFieldValues(pool, r.EntityFieldID, parsedValues, allEntityFieldValues);
1190
1227
  // finally, make sure the ValueListType column within the EntityField table is set to "List" because for check constraints we only allow the values specified in the list.
1191
1228
  // check to see if the ValueListType is already set to "List", if not, update it
1192
1229
  const sSQLCheck = `SELECT ValueListType FROM [${(0, config_1.mj_core_schema)()}].EntityField WHERE ID='${r.EntityFieldID}'`;
1193
- const checkResult = await ds.query(sSQLCheck);
1230
+ const checkResultResult = await pool.request().query(sSQLCheck);
1231
+ const checkResult = checkResultResult.recordset;
1194
1232
  if (checkResult && checkResult.length > 0 && checkResult[0].ValueListType.trim().toLowerCase() !== 'list') {
1195
1233
  const sSQL = `UPDATE [${(0, config_1.mj_core_schema)()}].EntityField SET ValueListType='List' WHERE ID='${r.EntityFieldID}'`;
1196
- await this.LogSQLAndExecute(ds, sSQL, `SQL text to update ValueListType for entity field ID ${r.EntityFieldID}`);
1234
+ await this.LogSQLAndExecute(pool, sSQL, `SQL text to update ValueListType for entity field ID ${r.EntityFieldID}`);
1197
1235
  }
1198
1236
  }
1199
1237
  else {
@@ -1232,13 +1270,13 @@ class ManageMetadataBase {
1232
1270
  }
1233
1271
  /**
1234
1272
  * This method will load all generated code from the database - this is intended to be used when you are bypassing managing the metadata.
1235
- * @param ds
1273
+ * @param pool
1236
1274
  * @param currentUser
1237
1275
  */
1238
- async loadGeneratedCode(ds, currentUser) {
1276
+ async loadGeneratedCode(pool, currentUser) {
1239
1277
  try {
1240
1278
  // right now we're just doing validator functions which are handled here
1241
- return await this.manageEntityFieldValuesAndValidatorFunctions(ds, [], currentUser, true);
1279
+ return await this.manageEntityFieldValuesAndValidatorFunctions(pool, [], currentUser, true);
1242
1280
  }
1243
1281
  catch (e) {
1244
1282
  (0, status_logging_1.logError)(e);
@@ -1356,7 +1394,9 @@ class ManageMetadataBase {
1356
1394
  // now, loop through the possible values and add any that are not already in the database
1357
1395
  // Step 1: for any existing value that is NOT in the list of possible Values, delete it
1358
1396
  let numRemoved = 0;
1359
- await ds.transaction(async () => {
1397
+ const transaction = new sql.Transaction(ds);
1398
+ await transaction.begin();
1399
+ try {
1360
1400
  for (const ev of existingValues) {
1361
1401
  if (!possibleValues.find(v => v === ev.Value)) {
1362
1402
  // delete the value from the database
@@ -1389,7 +1429,12 @@ class ManageMetadataBase {
1389
1429
  numUpdated++;
1390
1430
  }
1391
1431
  }
1392
- });
1432
+ await transaction.commit();
1433
+ }
1434
+ catch (e) {
1435
+ await transaction.rollback();
1436
+ throw e;
1437
+ }
1393
1438
  return true;
1394
1439
  }
1395
1440
  catch (e) {
@@ -1454,19 +1499,27 @@ class ManageMetadataBase {
1454
1499
  (sExcludeSchemas.length > 0 ? (sExcludeTables.length > 0 ? ` AND ` : ``) + '(' + sExcludeSchemas + ')' : '');
1455
1500
  return sWhere;
1456
1501
  }
1457
- async createNewEntities(ds) {
1502
+ async createNewEntities(pool) {
1458
1503
  try {
1459
1504
  const sSQL = `SELECT * FROM [${(0, config_1.mj_core_schema)()}].vwSQLTablesAndEntities WHERE EntityID IS NULL ` + this.createExcludeTablesAndSchemasFilter('');
1460
- const newEntities = await ds.query(sSQL);
1505
+ const newEntitiesResult = await pool.request().query(sSQL);
1506
+ const newEntities = newEntitiesResult.recordset;
1461
1507
  if (newEntities && newEntities.length > 0) {
1462
1508
  const md = new core_1.Metadata();
1463
- await ds.transaction(async () => {
1509
+ const transaction = new sql.Transaction(pool);
1510
+ await transaction.begin();
1511
+ try {
1464
1512
  // wrap in a transaction so we get all of it or none of it
1465
1513
  for (let i = 0; i < newEntities.length; ++i) {
1466
1514
  // process each of the new entities
1467
- await this.createNewEntity(ds, newEntities[i], md);
1515
+ await this.createNewEntity(pool, newEntities[i], md);
1468
1516
  }
1469
- });
1517
+ await transaction.commit();
1518
+ }
1519
+ catch (e) {
1520
+ await transaction.rollback();
1521
+ throw e;
1522
+ }
1470
1523
  if (ManageMetadataBase.newEntityList.length > 0) {
1471
1524
  // only do this if we actually created new entities
1472
1525
  (0, core_1.LogStatus)(` Done creating entities, refreshing metadata to reflect new entities...`);
@@ -1487,7 +1540,8 @@ class ManageMetadataBase {
1487
1540
  // 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.
1488
1541
  const query = `EXEC ${core_1.Metadata.Provider.ConfigData.MJCoreSchemaName}.spGetPrimaryKeyForTable @TableName='${newEntity.TableName}', @SchemaName='${newEntity.SchemaName}'`;
1489
1542
  try {
1490
- const result = await ds.query(query);
1543
+ const resultResult = await ds.request().query(query);
1544
+ const result = resultResult.recordset;
1491
1545
  if (result.length === 0) {
1492
1546
  return { shouldCreate: false, validationMessage: "No primary key found" };
1493
1547
  }
@@ -1580,9 +1634,9 @@ class ManageMetadataBase {
1580
1634
  createNewUUID() {
1581
1635
  return (0, uuid_1.v4)();
1582
1636
  }
1583
- async createNewEntity(ds, newEntity, md) {
1637
+ async createNewEntity(pool, newEntity, md) {
1584
1638
  try {
1585
- const { shouldCreate, validationMessage } = await this.shouldCreateNewEntity(ds, newEntity);
1639
+ const { shouldCreate, validationMessage } = await this.shouldCreateNewEntity(pool, newEntity);
1586
1640
  if (shouldCreate) {
1587
1641
  // process a single new entity
1588
1642
  let newEntityName = await this.createNewEntityName(newEntity);
@@ -1596,10 +1650,10 @@ class ManageMetadataBase {
1596
1650
  newEntityName = newEntityName + suffix;
1597
1651
  (0, core_1.LogError)(` >>>> WARNING: Entity name already exists, so using ${newEntityName} instead. If you did not intend for this, please rename the ${newEntity.SchemaName}.${newEntity.TableName} table in the database.`);
1598
1652
  }
1599
- const isNewSchema = await this.isSchemaNew(ds, newEntity.SchemaName);
1653
+ const isNewSchema = await this.isSchemaNew(pool, newEntity.SchemaName);
1600
1654
  const newEntityID = this.createNewUUID();
1601
1655
  const sSQLInsert = this.createNewEntityInsertSQL(newEntityID, newEntityName, newEntity, suffix);
1602
- await this.LogSQLAndExecute(ds, sSQLInsert, `SQL generated to create new entity ${newEntityName}`);
1656
+ await this.LogSQLAndExecute(pool, sSQLInsert, `SQL generated to create new entity ${newEntityName}`);
1603
1657
  // if we get here we created a new entity safely, otherwise we get exception
1604
1658
  // add it to the new entity list
1605
1659
  ManageMetadataBase.newEntityList.push(newEntityName);
@@ -1609,11 +1663,11 @@ class ManageMetadataBase {
1609
1663
  if (isNewSchema && config_1.configInfo.newSchemaDefaults.CreateNewApplicationWithSchemaName) {
1610
1664
  // new schema and config option is to create a new application from the schema name so do that
1611
1665
  // check to see if the app already exists
1612
- apps = await this.getApplicationIDForSchema(ds, newEntity.SchemaName);
1666
+ apps = await this.getApplicationIDForSchema(pool, newEntity.SchemaName);
1613
1667
  if (!apps || apps.length === 0) {
1614
1668
  // doesn't already exist, so create it
1615
1669
  const appUUID = this.createNewUUID();
1616
- const newAppID = await this.createNewApplication(ds, appUUID, newEntity.SchemaName, newEntity.SchemaName);
1670
+ const newAppID = await this.createNewApplication(pool, appUUID, newEntity.SchemaName, newEntity.SchemaName);
1617
1671
  if (newAppID) {
1618
1672
  apps = [newAppID];
1619
1673
  }
@@ -1626,7 +1680,7 @@ class ManageMetadataBase {
1626
1680
  }
1627
1681
  else {
1628
1682
  // not a new schema, attempt to look up the application for this schema
1629
- apps = await this.getApplicationIDForSchema(ds, newEntity.SchemaName);
1683
+ apps = await this.getApplicationIDForSchema(pool, newEntity.SchemaName);
1630
1684
  }
1631
1685
  if (apps && apps.length > 0) {
1632
1686
  if (config_1.configInfo.newEntityDefaults.AddToApplicationWithSchemaName) {
@@ -1635,7 +1689,7 @@ class ManageMetadataBase {
1635
1689
  const sSQLInsertApplicationEntity = `INSERT INTO ${(0, config_1.mj_core_schema)()}.ApplicationEntity
1636
1690
  (ApplicationID, EntityID, Sequence) VALUES
1637
1691
  ('${appUUID}', '${newEntityID}', (SELECT ISNULL(MAX(Sequence),0)+1 FROM ${(0, config_1.mj_core_schema)()}.ApplicationEntity WHERE ApplicationID = '${appUUID}'))`;
1638
- await this.LogSQLAndExecute(ds, sSQLInsertApplicationEntity, `SQL generated to add new entity ${newEntityName} to application ID: '${appUUID}'`);
1692
+ await this.LogSQLAndExecute(pool, sSQLInsertApplicationEntity, `SQL generated to add new entity ${newEntityName} to application ID: '${appUUID}'`);
1639
1693
  }
1640
1694
  }
1641
1695
  else {
@@ -1656,7 +1710,7 @@ class ManageMetadataBase {
1656
1710
  const sSQLInsertPermission = `INSERT INTO ${(0, config_1.mj_core_schema)()}.EntityPermission
1657
1711
  (EntityID, RoleID, CanRead, CanCreate, CanUpdate, CanDelete) VALUES
1658
1712
  ('${newEntityID}', '${RoleID}', ${p.CanRead ? 1 : 0}, ${p.CanCreate ? 1 : 0}, ${p.CanUpdate ? 1 : 0}, ${p.CanDelete ? 1 : 0})`;
1659
- await this.LogSQLAndExecute(ds, sSQLInsertPermission, `SQL generated to add new permission for entity ${newEntityName} for role ${p.RoleName}`);
1713
+ await this.LogSQLAndExecute(pool, sSQLInsertPermission, `SQL generated to add new permission for entity ${newEntityName} for role ${p.RoleName}`);
1660
1714
  }
1661
1715
  else
1662
1716
  (0, core_1.LogError)(` >>>> ERROR: Unable to find Role ID for role ${p.RoleName} to add permissions for new entity ${newEntityName}`);
@@ -1673,16 +1727,17 @@ class ManageMetadataBase {
1673
1727
  (0, core_1.LogError)(`Failed to create new entity ${newEntity?.TableName}`);
1674
1728
  }
1675
1729
  }
1676
- async isSchemaNew(ds, schemaName) {
1730
+ async isSchemaNew(pool, schemaName) {
1677
1731
  // check to see if there are any entities in the db with this schema name
1678
1732
  const sSQL = `SELECT COUNT(*) AS Count FROM [${(0, config_1.mj_core_schema)()}].Entity WHERE SchemaName = '${schemaName}'`;
1679
- const result = await ds.query(sSQL);
1733
+ const resultResult = await pool.request().query(sSQL);
1734
+ const result = resultResult.recordset;
1680
1735
  return result && result.length > 0 ? result[0].Count === 0 : true;
1681
1736
  }
1682
- async createNewApplication(ds, appID, appName, schemaName) {
1737
+ async createNewApplication(pool, appID, appName, schemaName) {
1683
1738
  try {
1684
1739
  const sSQL = "INSERT INTO [" + (0, config_1.mj_core_schema)() + "].Application (ID, Name, Description, SchemaAutoAddNewEntities) VALUES ('" + appID + "', '" + appName + "', 'Generated for schema', '" + schemaName + "')";
1685
- await this.LogSQLAndExecute(ds, sSQL, `SQL generated to create new application ${appName}`);
1740
+ await this.LogSQLAndExecute(pool, sSQL, `SQL generated to create new application ${appName}`);
1686
1741
  return appID; // if we get here, we successfully created the application, so return the ID
1687
1742
  }
1688
1743
  catch (e) {
@@ -1690,15 +1745,17 @@ class ManageMetadataBase {
1690
1745
  return null; // if we get here, we failed to create the application
1691
1746
  }
1692
1747
  }
1693
- async applicationExists(ds, applicationName) {
1748
+ async applicationExists(pool, applicationName) {
1694
1749
  const sSQL = `SELECT ID FROM [${(0, config_1.mj_core_schema)()}].Application WHERE Name = '${applicationName}'`;
1695
- const result = await ds.query(sSQL);
1750
+ const resultResult = await pool.request().query(sSQL);
1751
+ const result = resultResult.recordset;
1696
1752
  return result && result.length > 0 ? result[0].ID.length > 0 : false;
1697
1753
  }
1698
- async getApplicationIDForSchema(ds, schemaName) {
1754
+ async getApplicationIDForSchema(pool, schemaName) {
1699
1755
  // get all the apps each time from DB as we might be adding, don't use Metadata here for that reason
1700
1756
  const sSQL = `SELECT ID, Name, SchemaAutoAddNewEntities FROM [${(0, config_1.mj_core_schema)()}].vwApplications`;
1701
- const result = await ds.query(sSQL);
1757
+ const resultResult = await pool.request().query(sSQL);
1758
+ const result = resultResult.recordset;
1702
1759
  if (!result || result.length === 0) {
1703
1760
  // no applications found, return null
1704
1761
  return null;
@@ -1761,21 +1818,18 @@ class ManageMetadataBase {
1761
1818
  return sSQLInsert;
1762
1819
  }
1763
1820
  /**
1764
- * Executes the given SQL query using the given DataSource object.
1821
+ * Executes the given SQL query using the given ConnectionPool object.
1765
1822
  * If the appendToLogFile parameter is true, the query will also be appended to the log file.
1766
1823
  * Note that in order to append to the log file, ManageMetadataBase.manageMetaDataLogging must be called first.
1767
- * @param ds - The DataSource object to use to execute the query.
1824
+ * @param pool - The ConnectionPool object to use to execute the query.
1768
1825
  * @param query - The SQL query to execute.
1769
1826
  * @param description - A description of the query to append to the log file.
1770
1827
  * @param isRecurringScript - if set to true tells the logger that the provided SQL represents a recurring script meaning it is something that is executed, generally, for all CodeGen runs. In these cases, the Config settings can result in omitting these recurring scripts from being logged because the configuration environment may have those recurring scripts already set to run after all run-specific migrations get run.
1771
1828
  * @returns - The result of the query execution.
1772
1829
  */
1773
- async LogSQLAndExecute(ds, query, description, isRecurringScript = false) {
1774
- return await sql_logging_1.SQLLogging.LogSQLAndExecute(ds, query, description, isRecurringScript);
1830
+ async LogSQLAndExecute(pool, query, description, isRecurringScript = false) {
1831
+ return await sql_logging_1.SQLLogging.LogSQLAndExecute(pool, query, description, isRecurringScript);
1775
1832
  }
1776
1833
  }
1777
1834
  exports.ManageMetadataBase = ManageMetadataBase;
1778
- ManageMetadataBase._newEntityList = [];
1779
- ManageMetadataBase._modifiedEntityList = [];
1780
- ManageMetadataBase._generatedValidators = [];
1781
1835
  //# sourceMappingURL=manage-metadata.js.map