@memberjunction/codegen-lib 6.2.0-edge.0 → 6.2.0-edge.1

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 (212) hide show
  1. package/dist/Angular/angular-codegen.d.ts +6 -0
  2. package/dist/Angular/angular-codegen.d.ts.map +1 -1
  3. package/dist/Angular/angular-codegen.js +26 -14
  4. package/dist/Angular/angular-codegen.js.map +1 -1
  5. package/dist/Config/config.d.ts +45 -2
  6. package/dist/Config/config.d.ts.map +1 -1
  7. package/dist/Config/config.js +116 -39
  8. package/dist/Config/config.js.map +1 -1
  9. package/dist/Config/db-connection.d.ts +4 -0
  10. package/dist/Config/db-connection.d.ts.map +1 -1
  11. package/dist/Config/db-connection.js +11 -3
  12. package/dist/Config/db-connection.js.map +1 -1
  13. package/dist/Config/pg-connection.d.ts +2 -0
  14. package/dist/Config/pg-connection.d.ts.map +1 -1
  15. package/dist/Config/pg-connection.js +5 -1
  16. package/dist/Config/pg-connection.js.map +1 -1
  17. package/dist/Config/schema-output.d.ts +8 -0
  18. package/dist/Config/schema-output.d.ts.map +1 -1
  19. package/dist/Config/schema-output.js +19 -7
  20. package/dist/Config/schema-output.js.map +1 -1
  21. package/dist/Database/__tests__/exclude-schema-permissions.test.js +3 -3
  22. package/dist/Database/codeGenDatabaseProvider.d.ts +16 -1
  23. package/dist/Database/codeGenDatabaseProvider.d.ts.map +1 -1
  24. package/dist/Database/codeGenDatabaseProvider.js +37 -9
  25. package/dist/Database/codeGenDatabaseProvider.js.map +1 -1
  26. package/dist/Database/dbSchema.d.ts +4 -0
  27. package/dist/Database/dbSchema.d.ts.map +1 -1
  28. package/dist/Database/dbSchema.js +17 -9
  29. package/dist/Database/dbSchema.js.map +1 -1
  30. package/dist/Database/entity-field-change-tracking.d.ts +4 -0
  31. package/dist/Database/entity-field-change-tracking.d.ts.map +1 -1
  32. package/dist/Database/entity-field-change-tracking.js +12 -4
  33. package/dist/Database/entity-field-change-tracking.js.map +1 -1
  34. package/dist/Database/exclude-tables.d.ts +2 -0
  35. package/dist/Database/exclude-tables.d.ts.map +1 -1
  36. package/dist/Database/exclude-tables.js +5 -1
  37. package/dist/Database/exclude-tables.js.map +1 -1
  38. package/dist/Database/field-metadata-lock.d.ts +8 -6
  39. package/dist/Database/field-metadata-lock.d.ts.map +1 -1
  40. package/dist/Database/field-metadata-lock.js +29 -25
  41. package/dist/Database/field-metadata-lock.js.map +1 -1
  42. package/dist/Database/heal-schema-params.d.ts +14 -2
  43. package/dist/Database/heal-schema-params.d.ts.map +1 -1
  44. package/dist/Database/heal-schema-params.js +21 -5
  45. package/dist/Database/heal-schema-params.js.map +1 -1
  46. package/dist/Database/manage-metadata.d.ts +119 -3
  47. package/dist/Database/manage-metadata.d.ts.map +1 -1
  48. package/dist/Database/manage-metadata.js +529 -364
  49. package/dist/Database/manage-metadata.js.map +1 -1
  50. package/dist/Database/materializationAnalysis.d.ts +61 -2
  51. package/dist/Database/materializationAnalysis.d.ts.map +1 -1
  52. package/dist/Database/materializationAnalysis.js +43 -23
  53. package/dist/Database/materializationAnalysis.js.map +1 -1
  54. package/dist/Database/materializationBroadRender.d.ts +5 -3
  55. package/dist/Database/materializationBroadRender.d.ts.map +1 -1
  56. package/dist/Database/materializationBroadRender.js +17 -13
  57. package/dist/Database/materializationBroadRender.js.map +1 -1
  58. package/dist/Database/materializationDrift.d.ts +2 -0
  59. package/dist/Database/materializationDrift.d.ts.map +1 -1
  60. package/dist/Database/materializationDrift.js +5 -1
  61. package/dist/Database/materializationDrift.js.map +1 -1
  62. package/dist/Database/materializationParamClassifier.d.ts +17 -2
  63. package/dist/Database/materializationParamClassifier.d.ts.map +1 -1
  64. package/dist/Database/materializationParamClassifier.js +22 -10
  65. package/dist/Database/materializationParamClassifier.js.map +1 -1
  66. package/dist/Database/materializationParamVerifier.d.ts +2 -0
  67. package/dist/Database/materializationParamVerifier.d.ts.map +1 -1
  68. package/dist/Database/materializationParamVerifier.js +18 -14
  69. package/dist/Database/materializationParamVerifier.js.map +1 -1
  70. package/dist/Database/materializationSqlAst.d.ts +19 -1
  71. package/dist/Database/materializationSqlAst.d.ts.map +1 -1
  72. package/dist/Database/materializationSqlAst.js +53 -17
  73. package/dist/Database/materializationSqlAst.js.map +1 -1
  74. package/dist/Database/providers/postgresql/PostgreSQLCodeGenProvider.js +30 -30
  75. package/dist/Database/providers/postgresql/PostgreSQLCodeGenProvider.js.map +1 -1
  76. package/dist/Database/providers/postgresql/metadataSupportObjects.d.ts +2 -0
  77. package/dist/Database/providers/postgresql/metadataSupportObjects.d.ts.map +1 -1
  78. package/dist/Database/providers/postgresql/metadataSupportObjects.js +5 -1
  79. package/dist/Database/providers/postgresql/metadataSupportObjects.js.map +1 -1
  80. package/dist/Database/providers/postgresql/viewDependencyCapture.d.ts +10 -0
  81. package/dist/Database/providers/postgresql/viewDependencyCapture.d.ts.map +1 -1
  82. package/dist/Database/providers/postgresql/viewDependencyCapture.js +25 -5
  83. package/dist/Database/providers/postgresql/viewDependencyCapture.js.map +1 -1
  84. package/dist/Database/providers/postgresql/viewFallback.d.ts +11 -7
  85. package/dist/Database/providers/postgresql/viewFallback.d.ts.map +1 -1
  86. package/dist/Database/providers/postgresql/viewFallback.js +18 -12
  87. package/dist/Database/providers/postgresql/viewFallback.js.map +1 -1
  88. package/dist/Database/providers/sqlserver/SQLServerCodeGenProvider.js +13 -13
  89. package/dist/Database/providers/sqlserver/SQLServerCodeGenProvider.js.map +1 -1
  90. package/dist/Database/reconcileFieldLevelSecurity.d.ts +2 -0
  91. package/dist/Database/reconcileFieldLevelSecurity.d.ts.map +1 -1
  92. package/dist/Database/reconcileFieldLevelSecurity.js +5 -1
  93. package/dist/Database/reconcileFieldLevelSecurity.js.map +1 -1
  94. package/dist/Database/reorder-columns.d.ts +2 -0
  95. package/dist/Database/reorder-columns.d.ts.map +1 -1
  96. package/dist/Database/reorder-columns.js +5 -1
  97. package/dist/Database/reorder-columns.js.map +1 -1
  98. package/dist/Database/schema-filters.d.ts +6 -0
  99. package/dist/Database/schema-filters.d.ts.map +1 -1
  100. package/dist/Database/schema-filters.js +17 -5
  101. package/dist/Database/schema-filters.js.map +1 -1
  102. package/dist/Database/schema-scope.d.ts +4 -0
  103. package/dist/Database/schema-scope.d.ts.map +1 -1
  104. package/dist/Database/schema-scope.js +13 -5
  105. package/dist/Database/schema-scope.js.map +1 -1
  106. package/dist/Database/search-guardrails.d.ts +42 -0
  107. package/dist/Database/search-guardrails.d.ts.map +1 -1
  108. package/dist/Database/search-guardrails.js +57 -17
  109. package/dist/Database/search-guardrails.js.map +1 -1
  110. package/dist/Database/sql.d.ts +20 -0
  111. package/dist/Database/sql.d.ts.map +1 -1
  112. package/dist/Database/sql.js +72 -32
  113. package/dist/Database/sql.js.map +1 -1
  114. package/dist/Database/sql_codegen.d.ts +92 -0
  115. package/dist/Database/sql_codegen.d.ts.map +1 -1
  116. package/dist/Database/sql_codegen.js +197 -113
  117. package/dist/Database/sql_codegen.js.map +1 -1
  118. package/dist/EntityNameScanner/EntityNameScanner.d.ts +16 -0
  119. package/dist/EntityNameScanner/EntityNameScanner.d.ts.map +1 -1
  120. package/dist/EntityNameScanner/EntityNameScanner.js +47 -15
  121. package/dist/EntityNameScanner/EntityNameScanner.js.map +1 -1
  122. package/dist/EntityNameScanner/HtmlEntityNameScanner.d.ts +6 -0
  123. package/dist/EntityNameScanner/HtmlEntityNameScanner.d.ts.map +1 -1
  124. package/dist/EntityNameScanner/HtmlEntityNameScanner.js +19 -7
  125. package/dist/EntityNameScanner/HtmlEntityNameScanner.js.map +1 -1
  126. package/dist/EntityNameScanner/MetadataNameScanner.d.ts +6 -0
  127. package/dist/EntityNameScanner/MetadataNameScanner.d.ts.map +1 -1
  128. package/dist/EntityNameScanner/MetadataNameScanner.js +19 -7
  129. package/dist/EntityNameScanner/MetadataNameScanner.js.map +1 -1
  130. package/dist/Manifest/GenerateClassRegistrationsManifest.d.ts +6 -0
  131. package/dist/Manifest/GenerateClassRegistrationsManifest.d.ts.map +1 -1
  132. package/dist/Manifest/GenerateClassRegistrationsManifest.js +16 -4
  133. package/dist/Manifest/GenerateClassRegistrationsManifest.js.map +1 -1
  134. package/dist/Misc/action_subclasses_codegen.d.ts +4 -0
  135. package/dist/Misc/action_subclasses_codegen.d.ts.map +1 -1
  136. package/dist/Misc/action_subclasses_codegen.js +11 -3
  137. package/dist/Misc/action_subclasses_codegen.js.map +1 -1
  138. package/dist/Misc/advanced_generation.d.ts +48 -2
  139. package/dist/Misc/advanced_generation.d.ts.map +1 -1
  140. package/dist/Misc/advanced_generation.js +53 -15
  141. package/dist/Misc/advanced_generation.js.map +1 -1
  142. package/dist/Misc/codegen-reporter.d.ts +53 -0
  143. package/dist/Misc/codegen-reporter.d.ts.map +1 -1
  144. package/dist/Misc/codegen-reporter.js +106 -22
  145. package/dist/Misc/codegen-reporter.js.map +1 -1
  146. package/dist/Misc/createNewUser.d.ts +6 -0
  147. package/dist/Misc/createNewUser.d.ts.map +1 -1
  148. package/dist/Misc/createNewUser.js +5 -1
  149. package/dist/Misc/createNewUser.js.map +1 -1
  150. package/dist/Misc/entity_subclasses_codegen.d.ts +8 -0
  151. package/dist/Misc/entity_subclasses_codegen.d.ts.map +1 -1
  152. package/dist/Misc/entity_subclasses_codegen.js +52 -36
  153. package/dist/Misc/entity_subclasses_codegen.js.map +1 -1
  154. package/dist/Misc/externalTypeMapping.d.ts +2 -0
  155. package/dist/Misc/externalTypeMapping.d.ts.map +1 -1
  156. package/dist/Misc/externalTypeMapping.js +5 -1
  157. package/dist/Misc/externalTypeMapping.js.map +1 -1
  158. package/dist/Misc/file-write.d.ts +2 -0
  159. package/dist/Misc/file-write.d.ts.map +1 -1
  160. package/dist/Misc/file-write.js +5 -1
  161. package/dist/Misc/file-write.js.map +1 -1
  162. package/dist/Misc/graphql_server_codegen.d.ts +10 -0
  163. package/dist/Misc/graphql_server_codegen.d.ts.map +1 -1
  164. package/dist/Misc/graphql_server_codegen.js +46 -26
  165. package/dist/Misc/graphql_server_codegen.js.map +1 -1
  166. package/dist/Misc/remote_operations_codegen.d.ts +12 -0
  167. package/dist/Misc/remote_operations_codegen.d.ts.map +1 -1
  168. package/dist/Misc/remote_operations_codegen.js +21 -5
  169. package/dist/Misc/remote_operations_codegen.js.map +1 -1
  170. package/dist/Misc/runCommand.d.ts +6 -0
  171. package/dist/Misc/runCommand.d.ts.map +1 -1
  172. package/dist/Misc/runCommand.js +16 -4
  173. package/dist/Misc/runCommand.js.map +1 -1
  174. package/dist/Misc/schema-emit.d.ts +28 -0
  175. package/dist/Misc/schema-emit.d.ts.map +1 -1
  176. package/dist/Misc/schema-emit.js +75 -23
  177. package/dist/Misc/schema-emit.js.map +1 -1
  178. package/dist/Misc/sql_logging.d.ts +31 -9
  179. package/dist/Misc/sql_logging.d.ts.map +1 -1
  180. package/dist/Misc/sql_logging.js +95 -51
  181. package/dist/Misc/sql_logging.js.map +1 -1
  182. package/dist/Misc/sql_text.d.ts +4 -0
  183. package/dist/Misc/sql_text.d.ts.map +1 -1
  184. package/dist/Misc/sql_text.js +10 -2
  185. package/dist/Misc/sql_text.js.map +1 -1
  186. package/dist/Misc/status_logging.d.ts +36 -0
  187. package/dist/Misc/status_logging.d.ts.map +1 -1
  188. package/dist/Misc/status_logging.js +95 -23
  189. package/dist/Misc/status_logging.js.map +1 -1
  190. package/dist/Misc/system_integrity.js +4 -4
  191. package/dist/Misc/system_integrity.js.map +1 -1
  192. package/dist/Misc/temp_batch_file.d.ts +12 -0
  193. package/dist/Misc/temp_batch_file.d.ts.map +1 -1
  194. package/dist/Misc/temp_batch_file.js +35 -11
  195. package/dist/Misc/temp_batch_file.js.map +1 -1
  196. package/dist/Misc/util.d.ts +33 -0
  197. package/dist/Misc/util.d.ts.map +1 -1
  198. package/dist/Misc/util.js +53 -13
  199. package/dist/Misc/util.js.map +1 -1
  200. package/dist/index.d.ts +1 -1
  201. package/dist/index.d.ts.map +1 -1
  202. package/dist/index.js +1 -1
  203. package/dist/index.js.map +1 -1
  204. package/dist/plugins/index.d.ts +11 -1
  205. package/dist/plugins/index.d.ts.map +1 -1
  206. package/dist/plugins/index.js +9 -1
  207. package/dist/plugins/index.js.map +1 -1
  208. package/dist/runCodeGen.d.ts +6 -0
  209. package/dist/runCodeGen.d.ts.map +1 -1
  210. package/dist/runCodeGen.js +150 -138
  211. package/dist/runCodeGen.js.map +1 -1
  212. package/package.json +29 -29
@@ -1,14 +1,14 @@
1
1
  import { EntityInfo, Metadata, ShouldJoinRecordGeoCodes, HasNativeLatLngFields, NativeLatitudeField, NativeLongitudeField, ListEmbeddedGeoSpecs } from '@memberjunction/core';
2
- import { logError, logStatus, logWarning, startSpinner, updateSpinner, succeedSpinner, failSpinner } from '../Misc/status_logging.js';
2
+ import { logError, logStatus, LogWarning, StartSpinner, UpdateSpinner, SucceedSpinner, FailSpinner } from '../Misc/status_logging.js';
3
3
  import * as fs from 'fs';
4
4
  import path from 'path';
5
5
  import { SQLUtilityBase } from './sql.js';
6
6
  import { CodeGenDatabaseProvider } from './codeGenDatabaseProvider.js';
7
- import { autoIndexForeignKeys, autoIndexSoftPrimaryKeys, configInfo, customSqlScripts, mjCoreSchema } from '../Config/config.js';
8
- import { entityInCustomBaseViewRefreshScope, shouldEmitCascadeForRelatedEntity } from './schema-filters.js';
7
+ import { AutoIndexForeignKeys, AutoIndexSoftPrimaryKeys, configInfo, CustomSqlScripts, mjCoreSchema } from '../Config/config.js';
8
+ import { EntityInCustomBaseViewRefreshScope, ShouldEmitCascadeForRelatedEntity } from './schema-filters.js';
9
9
  import { ManageMetadataBase } from './manage-metadata.js';
10
10
  import { UserCache } from '@memberjunction/generic-database-provider';
11
- import { combineFiles, logIf } from '../Misc/util.js';
11
+ import { CombineFiles, LogIf } from '../Misc/util.js';
12
12
  import { MJGlobal, UUIDsEqual } from '@memberjunction/global';
13
13
  import { SQLLogging } from '../Misc/sql_logging.js';
14
14
  import { TempBatchFile } from '../Misc/temp_batch_file.js';
@@ -23,10 +23,14 @@ export const SPType = {
23
23
  * This is the CodeGen run's in-scope set: SQL objects and GRANTs are
24
24
  * generated and executed only for these. excludeSchemas means "not this run".
25
25
  */
26
- export function entitiesNotInExcludedSchemas(entities, excludeSchemas) {
26
+ export function EntitiesNotInExcludedSchemas(entities, excludeSchemas) {
27
27
  const exclude = new Set(excludeSchemas.map((s) => s.toLowerCase()));
28
28
  return entities.filter((e) => !exclude.has(e.SchemaName.toLowerCase()));
29
29
  }
30
+ /** @deprecated Use {@link EntitiesNotInExcludedSchemas}. */
31
+ export function entitiesNotInExcludedSchemas(entities, excludeSchemas) {
32
+ return EntitiesNotInExcludedSchemas(entities, excludeSchemas);
33
+ }
30
34
  /**
31
35
  * This class is responsible for generating database level objects like views, stored procedures, permissions, etc. You can sub-class this class to create your own SQL generation logic or implement support for other
32
36
  * databases. The base class implements support for SQL Server. In future versions of MJ, we will break out an abstract base class that has the skeleton of the logic and then the SQL Server version will be a sub-class
@@ -85,7 +89,7 @@ export class SQLCodeGenBase {
85
89
  set DBProvider(value) {
86
90
  this._dbProvider = value;
87
91
  }
88
- async manageSQLScriptsAndExecution(pool, entities, directory, currentUser) {
92
+ async ManageSQLScriptsAndExecution(pool, entities, directory, currentUser) {
89
93
  try {
90
94
  this.existingRoutines = null;
91
95
  // Build list of entities qualified for forced regeneration if entityWhereClause is provided
@@ -116,31 +120,31 @@ export class SQLCodeGenBase {
116
120
  // we have custom base views, need to have them defined before we do
117
121
  // the rest as the generated stuff might use custom base views in compiled
118
122
  // objects like spCreate for a given entity might reference the vw for that entity
119
- startSpinner('Running custom SQL scripts...');
123
+ StartSpinner('Running custom SQL scripts...');
120
124
  const startTime = new Date();
121
- if (!await this.runCustomSQLScripts(pool, 'before-sql')) {
122
- failSpinner('Failed to run custom SQL scripts');
125
+ if (!await this.RunCustomSQLScripts(pool, 'before-sql')) {
126
+ FailSpinner('Failed to run custom SQL scripts');
123
127
  return false;
124
128
  }
125
- succeedSpinner(`Custom SQL scripts completed (${(new Date().getTime() - startTime.getTime()) / 1000}s)`);
129
+ SucceedSpinner(`Custom SQL scripts completed (${(new Date().getTime() - startTime.getTime()) / 1000}s)`);
126
130
  await this.loadExistingRoutines(pool, entities);
127
131
  // ALWAYS use the first filter where we only include entities that have IncludeInAPI = 1
128
132
  // Entities are already sorted by name in PostProcessEntityMetadata (see providerBase.ts)
129
133
  const baselineEntities = entities.filter(e => e.IncludeInAPI);
130
134
  // OPTIMIZATION: Use a Set for O(1) lookups instead of O(n) array finds to improve performance
131
- const includedEntities = entitiesNotInExcludedSchemas(baselineEntities, configInfo.excludeSchemas);
135
+ const includedEntities = EntitiesNotInExcludedSchemas(baselineEntities, configInfo.excludeSchemas);
132
136
  // Initialize temp batch files for each schema
133
137
  // These will be populated as SQL is generated and will be used for actual execution
134
138
  const schemas = Array.from(new Set(baselineEntities.map(e => e.SchemaName))).sort();
135
139
  TempBatchFile.initialize(directory, schemas);
136
140
  // STEP 1.5 - Check for cascade delete dependencies that require regeneration
137
- startSpinner('Analyzing cascade delete dependencies...');
141
+ StartSpinner('Analyzing cascade delete dependencies...');
138
142
  await this.markEntitiesForCascadeDeleteRegeneration(pool, includedEntities);
139
- succeedSpinner('Cascade delete dependency analysis completed');
143
+ SucceedSpinner('Cascade delete dependency analysis completed');
140
144
  // STEP 2(a) - clean out all *.generated.sql and *.permissions.generated.sql files from the directory
141
- startSpinner('Cleaning generated files...');
142
- this.deleteGeneratedEntityFiles(directory, baselineEntities);
143
- succeedSpinner('Cleaned generated files');
145
+ StartSpinner('Cleaning generated files...');
146
+ this.DeleteGeneratedEntityFiles(directory, baselineEntities);
147
+ SucceedSpinner('Cleaned generated files');
144
148
  // STEP 2(a.5) - field-level security / permission-reconciliation run context.
145
149
  // One async pass over the live catalog (permission state + service-login role
146
150
  // memberships) so the synchronous permission emitters can (1) REVOKE-and-reassert
@@ -149,7 +153,7 @@ export class SQLCodeGenBase {
149
153
  // only: PostgreSQL has no DENY primitive, so per decision D2 it emits nothing.
150
154
  await this.prepareFieldSecurityRunContext(pool);
151
155
  // STEP 2(b) - generate all the SQL files and execute them
152
- startSpinner(`Generating SQL for ${includedEntities.length} entities...`);
156
+ StartSpinner(`Generating SQL for ${includedEntities.length} entities...`);
153
157
  const step2StartTime = new Date();
154
158
  // When the provider offers a phased executor (PG today), run per-entity
155
159
  // execution DURING file generation. This gives us view → CRUD fns →
@@ -207,7 +211,7 @@ export class SQLCodeGenBase {
207
211
  const configuredBatch = configInfo.fileEmit?.sqlEntityBatchSize ?? 8;
208
212
  const perEntityBatchSize = configInfo.dbPlatform === 'postgresql' ? 1 : configuredBatch;
209
213
  // Generate SQL for entities that don't need cascade delete regeneration
210
- const genResult = await this.generateAndExecuteEntitySQLToSeparateFiles({
214
+ const genResult = await this.GenerateAndExecuteEntitySQLToSeparateFiles({
211
215
  pool,
212
216
  entities: entitiesWithoutCascadeRegeneration,
213
217
  directory,
@@ -226,8 +230,8 @@ export class SQLCodeGenBase {
226
230
  }
227
231
  // Generate SQL for cascade delete regenerations in dependency order (sequentially)
228
232
  if (entitiesForCascadeRegeneration.length > 0) {
229
- updateSpinner(`Regenerating ${entitiesForCascadeRegeneration.length} delete SPs in dependency order...`);
230
- const cascadeGenResult = await this.generateAndExecuteEntitySQLToSeparateFiles({
233
+ UpdateSpinner(`Regenerating ${entitiesForCascadeRegeneration.length} delete SPs in dependency order...`);
234
+ const cascadeGenResult = await this.GenerateAndExecuteEntitySQLToSeparateFiles({
231
235
  pool,
232
236
  entities: entitiesForCascadeRegeneration,
233
237
  directory,
@@ -258,18 +262,18 @@ export class SQLCodeGenBase {
258
262
  //
259
263
  // Permissions are applied in STEP 4 for includedEntities only.
260
264
  if (entityGenSuccess) {
261
- succeedSpinner(`Entity generation completed (${(new Date().getTime() - step2StartTime.getTime()) / 1000}s)`);
265
+ SucceedSpinner(`Entity generation completed (${(new Date().getTime() - step2StartTime.getTime()) / 1000}s)`);
262
266
  }
263
267
  else {
264
- failSpinner(`Entity generation completed with batch failures (${(new Date().getTime() - step2StartTime.getTime()) / 1000}s) — see post-run CRUD validator for the authoritative gap report`);
268
+ FailSpinner(`Entity generation completed with batch failures (${(new Date().getTime() - step2StartTime.getTime()) / 1000}s) — see post-run CRUD validator for the authoritative gap report`);
265
269
  }
266
270
  // STEP 2(d) now that we've generated the SQL, let's create a combined file in each schema sub-directory for convenience for a DBA
267
- startSpinner('Creating combined SQL files...');
268
- const allEntityFiles = this.createCombinedEntitySQLFiles(directory, includedEntities);
269
- succeedSpinner(`Created combined SQL files for ${allEntityFiles.length} file(s)`);
271
+ StartSpinner('Creating combined SQL files...');
272
+ const allEntityFiles = this.CreateCombinedEntitySQLFiles(directory, includedEntities);
273
+ SucceedSpinner(`Created combined SQL files for ${allEntityFiles.length} file(s)`);
270
274
  // STEP 2(e) ---- FINALLY, we execute SQL in proper dependency order
271
275
  // Use temp batch files (which maintain CodeGen log order) if available, otherwise fall back to combined files
272
- startSpinner('Executing entity SQL files...');
276
+ StartSpinner('Executing entity SQL files...');
273
277
  const step2eStartTime = new Date();
274
278
  let executionSuccess = false;
275
279
  if (useProviderPhasedExecution) {
@@ -279,26 +283,26 @@ export class SQLCodeGenBase {
279
283
  // undo the work the phased executor just did.
280
284
  TempBatchFile.cleanup();
281
285
  executionSuccess = true;
282
- logIf(configInfo?.verboseOutput ?? false, 'Skipping bulk SQL file execution — per-entity phased execution already ran');
286
+ LogIf(configInfo?.verboseOutput ?? false, 'Skipping bulk SQL file execution — per-entity phased execution already ran');
283
287
  }
284
288
  else if (TempBatchFile.hasContent()) {
285
289
  // Execute temp batch files in dependency order (matches CodeGen run log)
286
290
  const tempFiles = TempBatchFile.getTempFilePaths();
287
- logIf(configInfo?.verboseOutput ?? false, `Executing ${tempFiles.length} temp batch file(s) in dependency order`);
291
+ LogIf(configInfo?.verboseOutput ?? false, `Executing ${tempFiles.length} temp batch file(s) in dependency order`);
288
292
  executionSuccess = await this.SQLUtilityObject.executeSQLFiles(tempFiles, configInfo?.verboseOutput ?? false);
289
293
  // Clean up temp files after execution
290
294
  TempBatchFile.cleanup();
291
295
  }
292
296
  else {
293
297
  // Fall back to combined files (for backward compatibility or if temp files weren't created)
294
- logIf(configInfo?.verboseOutput ?? false, `Executing ${allEntityFiles.length} combined file(s)`);
298
+ LogIf(configInfo?.verboseOutput ?? false, `Executing ${allEntityFiles.length} combined file(s)`);
295
299
  executionSuccess = await this.SQLUtilityObject.executeSQLFiles(allEntityFiles, configInfo?.verboseOutput ?? false);
296
300
  }
297
301
  // Initialize from entityGenSuccess so any per-batch failures from
298
302
  // STEP 2(b)/(c) carry forward instead of being lost. Bug 2 fix.
299
303
  let overallSuccess = entityGenSuccess;
300
304
  if (!executionSuccess) {
301
- failSpinner('Failed to execute entity SQL files');
305
+ FailSpinner('Failed to execute entity SQL files');
302
306
  TempBatchFile.cleanup(); // Cleanup on error
303
307
  overallSuccess = false;
304
308
  // Continue to manage entity fields metadata even after SQL execution failure.
@@ -307,7 +311,7 @@ export class SQLCodeGenBase {
307
311
  }
308
312
  else {
309
313
  const step2eEndTime = new Date();
310
- succeedSpinner(`SQL execution completed (${(step2eEndTime.getTime() - step2eStartTime.getTime()) / 1000}s)`);
314
+ SucceedSpinner(`SQL execution completed (${(step2eEndTime.getTime() - step2eStartTime.getTime()) / 1000}s)`);
311
315
  }
312
316
  const manageMD = MJGlobal.Instance.ClassFactory.CreateInstance(ManageMetadataBase);
313
317
  // STEP 3 - re-run the process to manage entity fields since the Step 1 and 2 above might have resulted in differences in base view columns compared to what we had at first
@@ -324,13 +328,13 @@ export class SQLCodeGenBase {
324
328
  ...ManageMetadataBase.newEntityList,
325
329
  ...ManageMetadataBase.modifiedEntityList,
326
330
  ])];
327
- startSpinner('Managing entity fields metadata...');
331
+ StartSpinner('Managing entity fields metadata...');
328
332
  if (!await manageMD.manageEntityFields(pool, configInfo.excludeSchemas, true, true, currentUser, false, false, pass2EntityFilter)) {
329
- failSpinner('Failed to manage entity fields');
333
+ FailSpinner('Failed to manage entity fields');
330
334
  overallSuccess = false;
331
335
  }
332
336
  else {
333
- succeedSpinner('Entity fields metadata updated');
337
+ SucceedSpinner('Entity fields metadata updated');
334
338
  }
335
339
  // no logStatus/timer for this because manageEntityFields() has its own internal logging for this including the total, so it is redundant to log it here
336
340
  // STEP 3.5 - Late-phase view regeneration
@@ -340,7 +344,7 @@ export class SQLCodeGenBase {
340
344
  const regenList = ManageMetadataBase.EntitiesRequiringViewRegen;
341
345
  if (regenList.length > 0) {
342
346
  const uniqueEntityNames = [...new Set(regenList.map(e => e.EntityName))];
343
- startSpinner(`Regenerating ${uniqueEntityNames.length} entities with late-phase view changes...`);
347
+ StartSpinner(`Regenerating ${uniqueEntityNames.length} entities with late-phase view changes...`);
344
348
  // Refresh metadata to pick up DB changes from Step 3 (e.g., SupportsGeoCoding = 1)
345
349
  const regenMd = new Metadata(); // global-provider-ok: codegen runs offline against a single provider
346
350
  await regenMd.Refresh();
@@ -355,7 +359,7 @@ export class SQLCodeGenBase {
355
359
  .filter((e) => e !== null);
356
360
  if (entitiesToRegen.length > 0) {
357
361
  // Regenerate views + SPs for affected entities only
358
- const regenResult = await this.generateAndExecuteEntitySQLToSeparateFiles({
362
+ const regenResult = await this.GenerateAndExecuteEntitySQLToSeparateFiles({
359
363
  pool,
360
364
  entities: entitiesToRegen,
361
365
  directory,
@@ -373,45 +377,45 @@ export class SQLCodeGenBase {
373
377
  await manageMD.manageEntityFields(pool, configInfo.excludeSchemas, true, true, currentUser, true, false, lateRegenFilter);
374
378
  // Apply reason-specific fixups
375
379
  await this.applyLatePhaseFixups(pool, regenList, entitiesToRegen);
376
- succeedSpinner(`Regenerated ${entitiesToRegen.length} late-phase entities`);
380
+ SucceedSpinner(`Regenerated ${entitiesToRegen.length} late-phase entities`);
377
381
  }
378
382
  else {
379
- failSpinner('Late-phase view regeneration failed');
383
+ FailSpinner('Late-phase view regeneration failed');
380
384
  overallSuccess = false;
381
385
  }
382
386
  }
383
387
  else {
384
- succeedSpinner('No valid entities to regenerate');
388
+ SucceedSpinner('No valid entities to regenerate');
385
389
  }
386
390
  }
387
391
  // STEP 4- Apply permissions for THIS run's schemas only. Excluded-schema
388
392
  // GRANT files are not generated (see STEP 2(c) note) and must not be
389
393
  // executed: a missing sibling object would fail CodeGen with
390
394
  // "Cannot find the object 'vw…'" even though this app's work succeeded.
391
- startSpinner('Applying permissions...');
395
+ StartSpinner('Applying permissions...');
392
396
  const step4StartTime = new Date();
393
- if (!await this.applyPermissions(pool, directory, includedEntities)) {
394
- failSpinner('Failed to apply permissions');
397
+ if (!await this.ApplyPermissions(pool, directory, includedEntities)) {
398
+ FailSpinner('Failed to apply permissions');
395
399
  overallSuccess = false;
396
400
  }
397
401
  else {
398
- succeedSpinner(`Permissions applied (${(new Date().getTime() - step4StartTime.getTime()) / 1000}s)`);
402
+ SucceedSpinner(`Permissions applied (${(new Date().getTime() - step4StartTime.getTime()) / 1000}s)`);
399
403
  }
400
404
  // STEP 4.5 - Emit sp_refreshview for modified custom base view entities into the
401
405
  // migration log file so other environments pick up schema changes automatically.
402
406
  this.emitCustomBaseViewRefreshes();
403
407
  // STEP 5 - execute any custom SQL scripts that should run afterwards
404
- startSpinner('Running post-generation SQL scripts...');
408
+ StartSpinner('Running post-generation SQL scripts...');
405
409
  const step5StartTime = new Date();
406
- if (!await this.runCustomSQLScripts(pool, 'after-sql')) {
407
- failSpinner('Failed to run post-generation SQL scripts');
410
+ if (!await this.RunCustomSQLScripts(pool, 'after-sql')) {
411
+ FailSpinner('Failed to run post-generation SQL scripts');
408
412
  overallSuccess = false;
409
413
  }
410
414
  else {
411
- succeedSpinner(`Post-generation scripts completed (${(new Date().getTime() - step5StartTime.getTime()) / 1000}s)`);
415
+ SucceedSpinner(`Post-generation scripts completed (${(new Date().getTime() - step5StartTime.getTime()) / 1000}s)`);
412
416
  }
413
417
  if (overallSuccess) {
414
- succeedSpinner(`SQL CodeGen completed successfully (${((new Date().getTime() - startTime.getTime()) / 1000)}s total)`);
418
+ SucceedSpinner(`SQL CodeGen completed successfully (${((new Date().getTime() - startTime.getTime()) / 1000)}s total)`);
415
419
  }
416
420
  // now - we need to tell our metadata object to refresh itself
417
421
  const md = new Metadata(); // global-provider-ok: codegen runs offline against a single provider
@@ -425,6 +429,10 @@ export class SQLCodeGenBase {
425
429
  return false;
426
430
  }
427
431
  }
432
+ /** @deprecated Use {@link ManageSQLScriptsAndExecution}. */
433
+ async manageSQLScriptsAndExecution(pool, entities, directory, currentUser) {
434
+ return this.ManageSQLScriptsAndExecution(pool, entities, directory, currentUser);
435
+ }
428
436
  /**
429
437
  * Apply reason-specific fixups after late-phase view regeneration.
430
438
  * Each regen reason may require additional SQL to be executed and logged
@@ -446,9 +454,9 @@ export class SQLCodeGenBase {
446
454
  await pool.query(lngSQL);
447
455
  }
448
456
  }
449
- async runCustomSQLScripts(pool, when) {
457
+ async RunCustomSQLScripts(pool, when) {
450
458
  try {
451
- const scripts = customSqlScripts(when);
459
+ const scripts = CustomSqlScripts(when);
452
460
  let bSuccess = true;
453
461
  if (scripts) {
454
462
  for (let i = 0; i < scripts.length; ++i) {
@@ -466,6 +474,10 @@ export class SQLCodeGenBase {
466
474
  return false;
467
475
  }
468
476
  }
477
+ /** @deprecated Use {@link RunCustomSQLScripts}. */
478
+ async runCustomSQLScripts(pool, when) {
479
+ return this.RunCustomSQLScripts(pool, when);
480
+ }
469
481
  /**
470
482
  * Builds the once-per-run {@link FieldSecurityRunContext} and hands it to the dialect
471
483
  * provider (whose permission emitters are synchronous string builders and cannot query).
@@ -553,19 +565,19 @@ export class SQLCodeGenBase {
553
565
  logStatus(` Field-security run context ready: ${roleSQLNameByID.size} custom role(s), ${serviceProtected.size} service-protected role(s), ${catalog.size} object(s) with managed permissions`);
554
566
  }
555
567
  catch (e) {
556
- logWarning(` ⚠️ Could not build the field-security run context (${e instanceof Error ? e.message : String(e)}). ` +
568
+ LogWarning(` ⚠️ Could not build the field-security run context (${e instanceof Error ? e.message : String(e)}). ` +
557
569
  `Permission emission degrades to grants-only for this run: no field-security DENYs and no reconciliation REVOKEs.`);
558
570
  this._dbProvider.SetFieldSecurityRunContext(null);
559
571
  }
560
572
  }
561
- async applyPermissions(pool, directory, entities, batchSize = 5) {
573
+ async ApplyPermissions(pool, directory, entities, batchSize = 5) {
562
574
  try {
563
575
  let bSuccess = true;
564
576
  for (let i = 0; i < entities.length; i += batchSize) {
565
577
  const batch = entities.slice(i, i + batchSize);
566
578
  const promises = batch.map(async (e) => {
567
579
  // generate the file names for the entity
568
- const files = this.getEntityPermissionFileNames(e);
580
+ const files = this.GetEntityPermissionFileNames(e);
569
581
  let innerSuccess = true;
570
582
  for (const f of files) {
571
583
  const fullPath = path.join(directory, f);
@@ -608,6 +620,10 @@ export class SQLCodeGenBase {
608
620
  return false;
609
621
  }
610
622
  }
623
+ /** @deprecated Use {@link ApplyPermissions}. */
624
+ async applyPermissions(pool, directory, entities, batchSize = 5) {
625
+ return this.ApplyPermissions(pool, directory, entities, batchSize);
626
+ }
611
627
  /**
612
628
  * This function will handle the process of creating all of the generated objects like base view, stored procedures, etc. for all entities in the entities array. It will generate the SQL for each entity and then execute it.
613
629
  * @param ds The DataSource object to use to execute the SQL
@@ -615,7 +631,7 @@ export class SQLCodeGenBase {
615
631
  * @param directory The directory to save the generated SQL files to
616
632
  * @param onlyPermissions If true, only the permissions files will be generated and executed, not the actual SQL files. Use this if you are simply setting permission changes but no actual changes to the entities have occured.
617
633
  */
618
- async generateAndExecuteEntitySQLToSeparateFiles(options) {
634
+ async GenerateAndExecuteEntitySQLToSeparateFiles(options) {
619
635
  if (!options.batchSize)
620
636
  options.batchSize = 5; // default to 5 if not specified
621
637
  const files = [];
@@ -637,7 +653,7 @@ export class SQLCodeGenBase {
637
653
  logError(`SKIPPING SQL GENERATION: Entity ${e.Name} has no primary key field in metadata. If using soft primary keys, ensure metadata was refreshed after applySoftPKFKConfig().`);
638
654
  return { entity: e, result: { Success: false, Files: [] } };
639
655
  }
640
- const result = await this.generateAndExecuteSingleEntitySQLToSeparateFiles({
656
+ const result = await this.GenerateAndExecuteSingleEntitySQLToSeparateFiles({
641
657
  pool: options.pool,
642
658
  entity: e,
643
659
  directory: options.directory,
@@ -673,7 +689,11 @@ export class SQLCodeGenBase {
673
689
  return { Success: false, Files: files };
674
690
  }
675
691
  }
676
- deleteGeneratedEntityFiles(directory, entities) {
692
+ /** @deprecated Use {@link GenerateAndExecuteEntitySQLToSeparateFiles}. */
693
+ async generateAndExecuteEntitySQLToSeparateFiles(options) {
694
+ return this.GenerateAndExecuteEntitySQLToSeparateFiles(options);
695
+ }
696
+ DeleteGeneratedEntityFiles(directory, entities) {
677
697
  try {
678
698
  // for the schemas associated with the specified entities, clean out all the generated files
679
699
  const schemaNames = entities.map(e => e.SchemaName).filter((value, index, self) => self.indexOf(value) === index).sort();
@@ -702,7 +722,11 @@ export class SQLCodeGenBase {
702
722
  logError(e);
703
723
  }
704
724
  }
705
- createCombinedEntitySQLFiles(directory, entities) {
725
+ /** @deprecated Use {@link DeleteGeneratedEntityFiles}. */
726
+ deleteGeneratedEntityFiles(directory, entities) {
727
+ return this.DeleteGeneratedEntityFiles(directory, entities);
728
+ }
729
+ CreateCombinedEntitySQLFiles(directory, entities) {
706
730
  // first, get a disinct list of schemanames from the entities
707
731
  const files = [];
708
732
  const schemaNames = entities.map(e => e.SchemaName).filter((value, index, self) => self.indexOf(value) === index).sort();
@@ -710,17 +734,21 @@ export class SQLCodeGenBase {
710
734
  // generate the all-entities.sql file and all-entities.permissions.sql file in each schema folder
711
735
  const fullPath = path.join(directory, s);
712
736
  if (fs.statSync(fullPath).isDirectory()) {
713
- combineFiles(fullPath, '_all_entities.sql', '*.generated.sql', true);
737
+ CombineFiles(fullPath, '_all_entities.sql', '*.generated.sql', true);
714
738
  files.push(path.join(fullPath, '_all_entities.sql'));
715
- combineFiles(fullPath, '_all_entities.permissions.sql', '*.permissions.generated.sql', true);
739
+ CombineFiles(fullPath, '_all_entities.permissions.sql', '*.permissions.generated.sql', true);
716
740
  files.push(path.join(fullPath, '_all_entities.permissions.sql'));
717
741
  }
718
742
  }
719
743
  return files;
720
744
  }
721
- async generateAndExecuteSingleEntitySQLToSeparateFiles(options) {
745
+ /** @deprecated Use {@link CreateCombinedEntitySQLFiles}. */
746
+ createCombinedEntitySQLFiles(directory, entities) {
747
+ return this.CreateCombinedEntitySQLFiles(directory, entities);
748
+ }
749
+ async GenerateAndExecuteSingleEntitySQLToSeparateFiles(options) {
722
750
  try {
723
- const { sql, permissionsSQL, files } = await this.generateSingleEntitySQLToSeparateFiles(options); // this creates the files and returns a single string with all the SQL we can then execute
751
+ const { sql, permissionsSQL, files } = await this.GenerateSingleEntitySQLToSeparateFiles(options); // this creates the files and returns a single string with all the SQL we can then execute
724
752
  if (options.skipExecution) {
725
753
  return { Success: true, Files: files };
726
754
  }
@@ -731,7 +759,7 @@ export class SQLCodeGenBase {
731
759
  // is explicitly gated on phase 1 success so we never create fn_*
732
760
  // against a missing or stale view rowtype.
733
761
  if (!options.onlyPermissions && this._dbProvider.executeEntityPhased) {
734
- const phaseResult = await this.executeEntityInPhases(options.pool, options.entity, options.willRegenerate);
762
+ const phaseResult = await this.ExecuteEntityInPhases(options.pool, options.entity, options.willRegenerate);
735
763
  if (!phaseResult.success) {
736
764
  const where = phaseResult.phase ?? 'unknown';
737
765
  logError(`Phased execution for ${options.entity.SchemaName}.${options.entity.Name} failed in phase "${where}": ${phaseResult.error?.message ?? '(no message)'}`);
@@ -751,13 +779,17 @@ export class SQLCodeGenBase {
751
779
  return { Success: false, Files: [] };
752
780
  }
753
781
  }
782
+ /** @deprecated Use {@link GenerateAndExecuteSingleEntitySQLToSeparateFiles}. */
783
+ async generateAndExecuteSingleEntitySQLToSeparateFiles(options) {
784
+ return this.GenerateAndExecuteSingleEntitySQLToSeparateFiles(options);
785
+ }
754
786
  /**
755
787
  * Generates the entity's per-phase SQL pieces (view, CRUD functions, view
756
788
  * permissions) and dispatches them to the provider's phased executor. Lives
757
789
  * here because it needs access to the internal generators; the provider
758
790
  * doesn't own context building for the view.
759
791
  */
760
- async executeEntityInPhases(pool, entity, willRegenerate) {
792
+ async ExecuteEntityInPhases(pool, entity, willRegenerate) {
761
793
  // External-data-source entities have no physical MJ table/view/sproc — their data is
762
794
  // proxied live. Skip all DDL generation/execution (mirrors the early-return in
763
795
  // generateSingleEntitySQLToSeparateFiles). Without this, the view phase would
@@ -784,7 +816,7 @@ export class SQLCodeGenBase {
784
816
  const generatesView = (entity.BaseViewGenerated || entity.HasLayeredBaseView) && !entity.VirtualEntity;
785
817
  const tvfSQL = generatesView ? this.generateRecursiveFKTVFs(entity) : '';
786
818
  const viewPieces = generatesView
787
- ? await this.generateBaseViewPieces(pool, entity)
819
+ ? await this.GenerateBaseViewPieces(pool, entity)
788
820
  : { viewSQL: '', viewPermSQL: '' };
789
821
  const crudCreateSQL = entity.AllowCreateAPI && entity.spCreateGenerated && !entity.VirtualEntity
790
822
  ? this.generateSPCreate(entity)
@@ -806,6 +838,10 @@ export class SQLCodeGenBase {
806
838
  willRegenerate,
807
839
  });
808
840
  }
841
+ /** @deprecated Use {@link ExecuteEntityInPhases}. */
842
+ async executeEntityInPhases(pool, entity, willRegenerate) {
843
+ return this.ExecuteEntityInPhases(pool, entity, willRegenerate);
844
+ }
809
845
  /**
810
846
  * Concatenates the hierarchy TVF SQL for every recursive ParentID-style FK
811
847
  * on this entity. Mirrors the inline TVF generation in
@@ -885,7 +921,7 @@ export class SQLCodeGenBase {
885
921
  }
886
922
  catch (e) {
887
923
  // Non-fatal — if we can't compare, the existing logic still runs
888
- logIf(configInfo.verboseOutput, `Could not compare base view for ${entity.Name}: ${e}`);
924
+ LogIf(configInfo.verboseOutput, `Could not compare base view for ${entity.Name}: ${e}`);
889
925
  return false;
890
926
  }
891
927
  }
@@ -1004,7 +1040,7 @@ export class SQLCodeGenBase {
1004
1040
  SQLLogging.appendToSQLLogFile(sql, description);
1005
1041
  TempBatchFile.appendToTempBatchFile(sql, entity.SchemaName);
1006
1042
  }
1007
- logIf(configInfo.verboseOutput, `SQL Generated for ${entity.Name}: ${description}`);
1043
+ LogIf(configInfo.verboseOutput, `SQL Generated for ${entity.Name}: ${description}`);
1008
1044
  }
1009
1045
  /**
1010
1046
  * Emits sp_refreshview statements into the migration log file for modified custom base view
@@ -1037,7 +1073,7 @@ export class SQLCodeGenBase {
1037
1073
  !e.BaseViewGenerated &&
1038
1074
  e.IncludeInAPI &&
1039
1075
  !e.VirtualEntity &&
1040
- entityInCustomBaseViewRefreshScope(e.SchemaName, configInfo.excludeSchemas ?? [], configInfo.includeSchemas));
1076
+ EntityInCustomBaseViewRefreshScope(e.SchemaName, configInfo.excludeSchemas ?? [], configInfo.includeSchemas));
1041
1077
  }
1042
1078
  /**
1043
1079
  * Builds a combined SQL string of sp_refreshview statements for the given entities.
@@ -1074,7 +1110,7 @@ export class SQLCodeGenBase {
1074
1110
  })
1075
1111
  .join('\n');
1076
1112
  }
1077
- async generateSingleEntitySQLToSeparateFiles(options) {
1113
+ async GenerateSingleEntitySQLToSeparateFiles(options) {
1078
1114
  const files = [];
1079
1115
  try {
1080
1116
  // External-data-source entities are backed by a remote system (Snowflake/MongoDB/
@@ -1101,18 +1137,18 @@ export class SQLCodeGenBase {
1101
1137
  // Indexes for Fkeys for the table (skip for virtual entities — views can't have indexes)
1102
1138
  if (!options.onlyPermissions && !options.entity.VirtualEntity) {
1103
1139
  const forceIndexes = !!(configInfo.forceRegeneration?.enabled && configInfo.forceRegeneration?.indexes);
1104
- const shouldGenerateIndexes = autoIndexForeignKeys() || forceIndexes;
1105
- const indexSQL = shouldGenerateIndexes ? this.generateIndexesForForeignKeys(options.pool, options.entity) : ''; // generate indexes if auto-indexing is on OR force regeneration is enabled
1140
+ const shouldGenerateIndexes = AutoIndexForeignKeys() || forceIndexes;
1141
+ const indexSQL = shouldGenerateIndexes ? this.GenerateIndexesForForeignKeys(options.pool, options.entity) : ''; // generate indexes if auto-indexing is on OR force regeneration is enabled
1106
1142
  // The soft-PK index rides in the same generated file (and therefore the same
1107
1143
  // migration log), but on its own setting — see generateIndexForSoftPrimaryKey.
1108
1144
  // Appended rather than prepended so the file's existing content stays
1109
1145
  // byte-identical for every entity that has no soft PK, which is nearly all of
1110
1146
  // them: writeFileIfChanged compares content, and reordering would rewrite the
1111
1147
  // whole tree for no functional gain.
1112
- const softPKSQL = (autoIndexSoftPrimaryKeys() || forceIndexes)
1113
- ? this.generateIndexForSoftPrimaryKey(options.entity)
1148
+ const softPKSQL = (AutoIndexSoftPrimaryKeys() || forceIndexes)
1149
+ ? this.GenerateIndexForSoftPrimaryKey(options.entity)
1114
1150
  : '';
1115
- const s = this.generateSingleEntitySQLFileHeader(options.entity, 'Index for Foreign Keys')
1151
+ const s = this.GenerateSingleEntitySQLFileHeader(options.entity, 'Index for Foreign Keys')
1116
1152
  + indexSQL
1117
1153
  + (softPKSQL ? (indexSQL ? '\n\n' : '') + softPKSQL : '');
1118
1154
  if (options.writeFiles) {
@@ -1153,7 +1189,7 @@ export class SQLCodeGenBase {
1153
1189
  }
1154
1190
  }
1155
1191
  // Generate the base view (which may reference the TVFs created above)
1156
- const s = this.generateSingleEntitySQLFileHeader(options.entity, options.entity.GeneratedViewName) + await this.generateBaseView(options.pool, options.entity);
1192
+ const s = this.GenerateSingleEntitySQLFileHeader(options.entity, options.entity.GeneratedViewName) + await this.GenerateBaseView(options.pool, options.entity);
1157
1193
  // Compare generated view SQL against what's currently in the database.
1158
1194
  // If the SELECT body differs, force-log just this base view via the forceLog flag
1159
1195
  // so logging stays centralized in logSQLForNewOrModifiedEntity.
@@ -1176,7 +1212,7 @@ export class SQLCodeGenBase {
1176
1212
  sRet += s + '\n' + this._dbProvider.BatchSeparator + '\n';
1177
1213
  }
1178
1214
  // always generate permissions for the base view
1179
- const permHeader = this.generateSingleEntitySQLFileHeader(options.entity, 'Permissions for ' + options.entity.BaseView);
1215
+ const permHeader = this.GenerateSingleEntitySQLFileHeader(options.entity, 'Permissions for ' + options.entity.BaseView);
1180
1216
  const rawPermBody = this.generateViewPermissions(options.entity);
1181
1217
  // Guarded for the same reason as in generateBaseViewPieces: these GRANTs target the
1182
1218
  // application-owned BaseView, which does not exist during a layered entity's bootstrap
@@ -1202,12 +1238,12 @@ export class SQLCodeGenBase {
1202
1238
  }
1203
1239
  // CREATE SP
1204
1240
  if (options.entity.AllowCreateAPI && !options.entity.VirtualEntity) {
1205
- const spName = this.getSPName(options.entity, SPType.Create);
1241
+ const spName = this.GetSPName(options.entity, SPType.Create);
1206
1242
  // Only generate if spCreateGenerated is true (respects custom SPs where it's false)
1207
1243
  // forceRegeneration only forces regeneration of SPs where spCreateGenerated=true
1208
1244
  if (!options.onlyPermissions && options.entity.spCreateGenerated) {
1209
1245
  // generate the create SP
1210
- const s = this.generateSingleEntitySQLFileHeader(options.entity, spName) + this.generateSPCreate(options.entity);
1246
+ const s = this.GenerateSingleEntitySQLFileHeader(options.entity, spName) + this.generateSPCreate(options.entity);
1211
1247
  if (options.writeFiles) {
1212
1248
  const filePath = path.join(options.directory, this.SQLUtilityObject.getDBObjectFileName('sp', options.entity.SchemaName, spName, false, true));
1213
1249
  this.writeFileIfChanged(filePath, s);
@@ -1232,12 +1268,12 @@ export class SQLCodeGenBase {
1232
1268
  }
1233
1269
  // UPDATE SP
1234
1270
  if (options.entity.AllowUpdateAPI && !options.entity.VirtualEntity) {
1235
- const spName = this.getSPName(options.entity, SPType.Update);
1271
+ const spName = this.GetSPName(options.entity, SPType.Update);
1236
1272
  // Only generate if spUpdateGenerated is true (respects custom SPs where it's false)
1237
1273
  // forceRegeneration only forces regeneration of SPs where spUpdateGenerated=true
1238
1274
  if (!options.onlyPermissions && options.entity.spUpdateGenerated) {
1239
1275
  // generate the update SP
1240
- const s = this.generateSingleEntitySQLFileHeader(options.entity, spName) + this.generateSPUpdate(options.entity);
1276
+ const s = this.GenerateSingleEntitySQLFileHeader(options.entity, spName) + this.generateSPUpdate(options.entity);
1241
1277
  if (options.writeFiles) {
1242
1278
  const filePath = path.join(options.directory, this.SQLUtilityObject.getDBObjectFileName('sp', options.entity.SchemaName, spName, false, true));
1243
1279
  this.writeFileIfChanged(filePath, s);
@@ -1262,7 +1298,7 @@ export class SQLCodeGenBase {
1262
1298
  }
1263
1299
  // DELETE SP
1264
1300
  if (options.entity.AllowDeleteAPI && !options.entity.VirtualEntity) {
1265
- const spName = this.getSPName(options.entity, SPType.Delete);
1301
+ const spName = this.GetSPName(options.entity, SPType.Delete);
1266
1302
  // Only generate if spDeleteGenerated is true (respects custom SPs where it's false)
1267
1303
  // OR if this entity has cascade delete dependencies that require regeneration
1268
1304
  // forceRegeneration only forces regeneration of SPs where spDeleteGenerated=true
@@ -1273,7 +1309,7 @@ export class SQLCodeGenBase {
1273
1309
  if (this.entitiesNeedingDeleteSPRegeneration.has(options.entity.ID)) {
1274
1310
  logStatus(` Regenerating ${spName} due to cascade dependency changes`);
1275
1311
  }
1276
- const s = this.generateSingleEntitySQLFileHeader(options.entity, spName) + await this.generateSPDelete(options.entity, options.pool);
1312
+ const s = this.GenerateSingleEntitySQLFileHeader(options.entity, spName) + await this.generateSPDelete(options.entity, options.pool);
1277
1313
  if (options.writeFiles) {
1278
1314
  const filePath = path.join(options.directory, this.SQLUtilityObject.getDBObjectFileName('sp', options.entity.SchemaName, spName, false, true));
1279
1315
  this.writeFileIfChanged(filePath, s);
@@ -1299,7 +1335,7 @@ export class SQLCodeGenBase {
1299
1335
  // check to see if the options.entity supports full text search or not
1300
1336
  if (options.entity.FullTextSearchEnabled || (configInfo.forceRegeneration?.enabled && configInfo.forceRegeneration?.fullTextSearch)) {
1301
1337
  // always generate the code so we can get the function name from the below function call
1302
- const ft = await this.generateEntityFullTextSearchSQL(options.pool, options.entity);
1338
+ const ft = await this.GenerateEntityFullTextSearchSQL(options.pool, options.entity);
1303
1339
  if (!options.onlyPermissions) {
1304
1340
  // only write the actual sql out if we're not only generating permissions
1305
1341
  const filePath = path.join(options.directory, this.SQLUtilityObject.getDBObjectFileName('full_text_search_function', options.entity.SchemaName, options.entity.BaseTable, false, true));
@@ -1331,9 +1367,17 @@ export class SQLCodeGenBase {
1331
1367
  return null;
1332
1368
  }
1333
1369
  }
1334
- getSPName(entity, type) {
1370
+ /** @deprecated Use {@link GenerateSingleEntitySQLToSeparateFiles}. */
1371
+ async generateSingleEntitySQLToSeparateFiles(options) {
1372
+ return this.GenerateSingleEntitySQLToSeparateFiles(options);
1373
+ }
1374
+ GetSPName(entity, type) {
1335
1375
  return this._dbProvider.getCRUDRoutineName(entity, type);
1336
1376
  }
1377
+ /** @deprecated Use {@link GetSPName}. */
1378
+ getSPName(entity, type) {
1379
+ return this.GetSPName(entity, type);
1380
+ }
1337
1381
  /**
1338
1382
  * Snapshot every CRUD routine currently in the database (one query) so
1339
1383
  * generate-and-log can force-emit CREATE PROC for objects that vanished
@@ -1357,7 +1401,7 @@ export class SQLCodeGenBase {
1357
1401
  }
1358
1402
  }
1359
1403
  catch (e) {
1360
- logWarning(`Could not load existing CRUD routines (missing-proc self-heal disabled this run): ${e instanceof Error ? e.message : String(e)}`);
1404
+ LogWarning(`Could not load existing CRUD routines (missing-proc self-heal disabled this run): ${e instanceof Error ? e.message : String(e)}`);
1361
1405
  this.existingRoutines = null;
1362
1406
  }
1363
1407
  }
@@ -1370,7 +1414,7 @@ export class SQLCodeGenBase {
1370
1414
  forceLogForRoutine(entity, routineName, baseViewChanged) {
1371
1415
  return baseViewChanged || this.isRoutineMissing(entity.SchemaName, routineName);
1372
1416
  }
1373
- getEntityPermissionFileNames(entity) {
1417
+ GetEntityPermissionFileNames(entity) {
1374
1418
  const files = [];
1375
1419
  // all entities have a base view - and we always generate permissions for the base view even if not generated base view
1376
1420
  files.push(this.SQLUtilityObject.getDBObjectFileName('view', entity.SchemaName, entity.BaseView, true, true));
@@ -1378,16 +1422,20 @@ export class SQLCodeGenBase {
1378
1422
  if (!entity.VirtualEntity) {
1379
1423
  // only add each SP file if the Allow flags are set to true, doesn't matter if the SPs are generated or not, we always generate permissions
1380
1424
  if (entity.AllowCreateAPI)
1381
- files.push(this.SQLUtilityObject.getDBObjectFileName('sp', entity.SchemaName, this.getSPName(entity, SPType.Create), true, true));
1425
+ files.push(this.SQLUtilityObject.getDBObjectFileName('sp', entity.SchemaName, this.GetSPName(entity, SPType.Create), true, true));
1382
1426
  if (entity.AllowUpdateAPI)
1383
- files.push(this.SQLUtilityObject.getDBObjectFileName('sp', entity.SchemaName, this.getSPName(entity, SPType.Update), true, true));
1427
+ files.push(this.SQLUtilityObject.getDBObjectFileName('sp', entity.SchemaName, this.GetSPName(entity, SPType.Update), true, true));
1384
1428
  if (entity.AllowDeleteAPI)
1385
- files.push(this.SQLUtilityObject.getDBObjectFileName('sp', entity.SchemaName, this.getSPName(entity, SPType.Delete), true, true));
1429
+ files.push(this.SQLUtilityObject.getDBObjectFileName('sp', entity.SchemaName, this.GetSPName(entity, SPType.Delete), true, true));
1386
1430
  }
1387
1431
  if (entity.FullTextSearchEnabled)
1388
1432
  files.push(this.SQLUtilityObject.getDBObjectFileName('full_text_search_function', entity.SchemaName, entity.BaseTable, true, true));
1389
1433
  return files;
1390
1434
  }
1435
+ /** @deprecated Use {@link GetEntityPermissionFileNames}. */
1436
+ getEntityPermissionFileNames(entity) {
1437
+ return this.GetEntityPermissionFileNames(entity);
1438
+ }
1391
1439
  /**
1392
1440
  * Deprecated - do not use
1393
1441
  * @deprecated
@@ -1399,7 +1447,7 @@ export class SQLCodeGenBase {
1399
1447
  let sOutput = '';
1400
1448
  if (entity.BaseViewGenerated && !entity.VirtualEntity)
1401
1449
  // generated the base view (will include permissions)
1402
- sOutput += await this.generateBaseView(pool, entity) + '\n\n';
1450
+ sOutput += await this.GenerateBaseView(pool, entity) + '\n\n';
1403
1451
  else
1404
1452
  // still generate the permissions for the view even if a custom view
1405
1453
  sOutput += this.generateViewPermissions(entity) + '\n\n';
@@ -1429,11 +1477,11 @@ export class SQLCodeGenBase {
1429
1477
  }
1430
1478
  // check to see if the entity supports full text search or not
1431
1479
  if (entity.FullTextSearchEnabled) {
1432
- sOutput += await this.generateEntityFullTextSearchSQL(pool, entity) + '\n\n';
1480
+ sOutput += await this.GenerateEntityFullTextSearchSQL(pool, entity) + '\n\n';
1433
1481
  }
1434
1482
  return sOutput;
1435
1483
  }
1436
- async generateEntityFullTextSearchSQL(pool, entity) {
1484
+ async GenerateEntityFullTextSearchSQL(pool, entity) {
1437
1485
  const searchFields = entity.Fields.filter(f => f.FullTextSearchEnabled);
1438
1486
  // Validate search fields exist when needed
1439
1487
  if (entity.FullTextIndexGenerated && searchFields.length === 0)
@@ -1443,7 +1491,7 @@ export class SQLCodeGenBase {
1443
1491
  // Get the primary key index name (needed for full text index)
1444
1492
  let primaryKeyIndexName = '';
1445
1493
  if (entity.FullTextIndexGenerated) {
1446
- primaryKeyIndexName = await this.getEntityPrimaryKeyIndexName(pool, entity);
1494
+ primaryKeyIndexName = await this.GetEntityPrimaryKeyIndexName(pool, entity);
1447
1495
  }
1448
1496
  // If the function name is not set, save it to the DB
1449
1497
  const functionName = entity.FullTextSearchFunction && entity.FullTextSearchFunction.length > 0
@@ -1468,7 +1516,11 @@ export class SQLCodeGenBase {
1468
1516
  }
1469
1517
  return result;
1470
1518
  }
1471
- async getEntityPrimaryKeyIndexName(pool, entity) {
1519
+ /** @deprecated Use {@link GenerateEntityFullTextSearchSQL}. */
1520
+ async generateEntityFullTextSearchSQL(pool, entity) {
1521
+ return this.GenerateEntityFullTextSearchSQL(pool, entity);
1522
+ }
1523
+ async GetEntityPrimaryKeyIndexName(pool, entity) {
1472
1524
  const sSQL = this._dbProvider.getPrimaryKeyIndexNameSQL(entity.SchemaName, entity.BaseTable);
1473
1525
  const resultResult = await pool.query(sSQL);
1474
1526
  const result = resultResult.recordset;
@@ -1477,20 +1529,36 @@ export class SQLCodeGenBase {
1477
1529
  else
1478
1530
  throw new Error(`Could not find primary key index for entity ${entity.Name}`);
1479
1531
  }
1480
- generateAllEntitiesSQLFileHeader() {
1532
+ /** @deprecated Use {@link GetEntityPrimaryKeyIndexName}. */
1533
+ async getEntityPrimaryKeyIndexName(pool, entity) {
1534
+ return this.GetEntityPrimaryKeyIndexName(pool, entity);
1535
+ }
1536
+ GenerateAllEntitiesSQLFileHeader() {
1481
1537
  return this._dbProvider.generateAllEntitiesSQLFileHeader();
1482
1538
  }
1483
- generateSingleEntitySQLFileHeader(entity, itemName) {
1539
+ /** @deprecated Use {@link GenerateAllEntitiesSQLFileHeader}. */
1540
+ generateAllEntitiesSQLFileHeader() {
1541
+ return this.GenerateAllEntitiesSQLFileHeader();
1542
+ }
1543
+ GenerateSingleEntitySQLFileHeader(entity, itemName) {
1484
1544
  return this._dbProvider.generateSQLFileHeader(entity, itemName);
1485
1545
  }
1546
+ /** @deprecated Use {@link GenerateSingleEntitySQLFileHeader}. */
1547
+ generateSingleEntitySQLFileHeader(entity, itemName) {
1548
+ return this.GenerateSingleEntitySQLFileHeader(entity, itemName);
1549
+ }
1486
1550
  /**
1487
1551
  * Generates the SQL for creating indexes for the foreign keys in the entity.
1488
1552
  * Delegates to the database provider for platform-specific index DDL.
1489
1553
  */
1490
- generateIndexesForForeignKeys(pool, entity) {
1554
+ GenerateIndexesForForeignKeys(pool, entity) {
1491
1555
  const indexStatements = this._dbProvider.generateForeignKeyIndexes(entity);
1492
1556
  return indexStatements.join('\n\n');
1493
1557
  }
1558
+ /** @deprecated Use {@link GenerateIndexesForForeignKeys}. */
1559
+ generateIndexesForForeignKeys(pool, entity) {
1560
+ return this.GenerateIndexesForForeignKeys(pool, entity);
1561
+ }
1494
1562
  /**
1495
1563
  * Generates the composite index covering the entity's SOFT primary key. Empty for every
1496
1564
  * entity with a real `PRIMARY KEY` constraint, which is nearly all of them.
@@ -1500,10 +1568,14 @@ export class SQLCodeGenBase {
1500
1568
  * different concern from indexing foreign keys for joins and filters, and an operator's
1501
1569
  * opinion about one is not an opinion about the other.
1502
1570
  */
1503
- generateIndexForSoftPrimaryKey(entity) {
1571
+ GenerateIndexForSoftPrimaryKey(entity) {
1504
1572
  const indexStatements = this._dbProvider.generateSoftPrimaryKeyIndex(entity);
1505
1573
  return indexStatements.join('\n\n');
1506
1574
  }
1575
+ /** @deprecated Use {@link GenerateIndexForSoftPrimaryKey}. */
1576
+ generateIndexForSoftPrimaryKey(entity) {
1577
+ return this.GenerateIndexForSoftPrimaryKey(entity);
1578
+ }
1507
1579
  /**
1508
1580
  * Detects self-referential foreign keys in an entity (e.g., ParentTaskID pointing back to Task table)
1509
1581
  * Returns array of field info objects representing recursive relationships
@@ -1517,7 +1589,7 @@ export class SQLCodeGenBase {
1517
1589
  return [];
1518
1590
  }
1519
1591
  if (entity.PrimaryKeys.length !== 1) {
1520
- logWarning(`[Hierarchy] Entity '${entity.Name}' has ${hierarchyFKs.length} hierarchy foreign key(s) ` +
1592
+ LogWarning(`[Hierarchy] Entity '${entity.Name}' has ${hierarchyFKs.length} hierarchy foreign key(s) ` +
1521
1593
  `(${hierarchyFKs.map(f => f.Name).join(', ')}), but has ${entity.PrimaryKeys.length} primary key fields. ` +
1522
1594
  `MemberJunction hierarchy TVF generation and traversal require a single-column primary key. Skipping hierarchy generation for this entity.`);
1523
1595
  return [];
@@ -1535,25 +1607,25 @@ export class SQLCodeGenBase {
1535
1607
  return [
1536
1608
  {
1537
1609
  functionName: metaFnName,
1538
- sql: this.generateSingleEntitySQLFileHeader(entity, metaFnName) + this._dbProvider.generateHierarchyMetaFunction(entity, field),
1610
+ sql: this.GenerateSingleEntitySQLFileHeader(entity, metaFnName) + this._dbProvider.generateHierarchyMetaFunction(entity, field),
1539
1611
  description: `Hierarchy Metadata Function SQL for ${entity.Name}.${field.Name}`,
1540
1612
  fieldName: field.Name
1541
1613
  },
1542
1614
  {
1543
1615
  functionName: descFnName,
1544
- sql: this.generateSingleEntitySQLFileHeader(entity, descFnName) + this._dbProvider.generateDescendantsFunction(entity, field),
1616
+ sql: this.GenerateSingleEntitySQLFileHeader(entity, descFnName) + this._dbProvider.generateDescendantsFunction(entity, field),
1545
1617
  description: `Descendants Traversal Function SQL for ${entity.Name}.${field.Name}`,
1546
1618
  fieldName: field.Name
1547
1619
  },
1548
1620
  {
1549
1621
  functionName: ancFnName,
1550
- sql: this.generateSingleEntitySQLFileHeader(entity, ancFnName) + this._dbProvider.generateAncestorsFunction(entity, field),
1622
+ sql: this.GenerateSingleEntitySQLFileHeader(entity, ancFnName) + this._dbProvider.generateAncestorsFunction(entity, field),
1551
1623
  description: `Ancestors Traversal Function SQL for ${entity.Name}.${field.Name}`,
1552
1624
  fieldName: field.Name
1553
1625
  },
1554
1626
  {
1555
1627
  functionName: rootFnName,
1556
- sql: this.generateSingleEntitySQLFileHeader(entity, rootFnName) + this._dbProvider.generateRootIDFunction(entity, field),
1628
+ sql: this.GenerateSingleEntitySQLFileHeader(entity, rootFnName) + this._dbProvider.generateRootIDFunction(entity, field),
1557
1629
  description: `Root ID Function SQL for ${entity.Name}.${field.Name}`,
1558
1630
  fieldName: field.Name
1559
1631
  }
@@ -1681,10 +1753,14 @@ export class SQLCodeGenBase {
1681
1753
  }
1682
1754
  return joins.join('\n');
1683
1755
  }
1684
- async generateBaseView(pool, entity) {
1685
- const { viewSQL, viewPermSQL } = await this.generateBaseViewPieces(pool, entity);
1756
+ async GenerateBaseView(pool, entity) {
1757
+ const { viewSQL, viewPermSQL } = await this.GenerateBaseViewPieces(pool, entity);
1686
1758
  return viewSQL + viewPermSQL;
1687
1759
  }
1760
+ /** @deprecated Use {@link GenerateBaseView}. */
1761
+ async generateBaseView(pool, entity) {
1762
+ return this.GenerateBaseView(pool, entity);
1763
+ }
1688
1764
  /**
1689
1765
  * Same as `generateBaseView`, but returns the view DDL and the GRANT/permissions
1690
1766
  * DDL as separate strings rather than concatenating. Used by phased per-entity
@@ -1693,9 +1769,9 @@ export class SQLCodeGenBase {
1693
1769
  * phase — concatenating them would prevent the executor from detecting where
1694
1770
  * a failure actually occurred.
1695
1771
  */
1696
- async generateBaseViewPieces(pool, entity) {
1772
+ async GenerateBaseViewPieces(pool, entity) {
1697
1773
  const classNameFirstChar = entity.BaseTableCodeName.charAt(0).toLowerCase();
1698
- let relatedFieldsString = await this.generateBaseViewRelatedFieldsString(pool, entity.Fields);
1774
+ let relatedFieldsString = await this.GenerateBaseViewRelatedFieldsString(pool, entity.Fields);
1699
1775
  const relatedFieldsJoinString = this.generateBaseViewJoins(entity, entity.Fields);
1700
1776
  // Geo WRITE source: native lat/lng aliases, or RecordGeoCode JOIN when the entity
1701
1777
  // has writable Geo* fields and no native coords. Display-only entities (Person/Org
@@ -1750,6 +1826,10 @@ export class SQLCodeGenBase {
1750
1826
  viewPermSQL: permissions,
1751
1827
  };
1752
1828
  }
1829
+ /** @deprecated Use {@link GenerateBaseViewPieces}. */
1830
+ async generateBaseViewPieces(pool, entity) {
1831
+ return this.GenerateBaseViewPieces(pool, entity);
1832
+ }
1753
1833
  generateViewPermissions(entity) {
1754
1834
  return this._dbProvider.generateViewPermissions(entity);
1755
1835
  }
@@ -1922,7 +2002,7 @@ export class SQLCodeGenBase {
1922
2002
  generateRecordGeoCodeFields(qi) {
1923
2003
  return ` __mj_rgc.${qi('Latitude')} AS ${qi('__mj_Latitude')},\n __mj_rgc.${qi('Longitude')} AS ${qi('__mj_Longitude')}`;
1924
2004
  }
1925
- async generateBaseViewRelatedFieldsString(pool, entityFields) {
2005
+ async GenerateBaseViewRelatedFieldsString(pool, entityFields) {
1926
2006
  let sOutput = '';
1927
2007
  let fieldCount = 0;
1928
2008
  const manageMD = MJGlobal.Instance.ClassFactory.CreateInstance(ManageMetadataBase);
@@ -2084,6 +2164,10 @@ export class SQLCodeGenBase {
2084
2164
  }
2085
2165
  return sOutput;
2086
2166
  }
2167
+ /** @deprecated Use {@link GenerateBaseViewRelatedFieldsString}. */
2168
+ async generateBaseViewRelatedFieldsString(pool, entityFields) {
2169
+ return this.GenerateBaseViewRelatedFieldsString(pool, entityFields);
2170
+ }
2087
2171
  getIsNameFieldForSingleEntity(entityName) {
2088
2172
  const md = new Metadata(); // use the full metadata entity list, not the filtered version that we receive // global-provider-ok: codegen runs offline against a single provider
2089
2173
  const e = md.EntityByName(entityName);
@@ -2172,7 +2256,7 @@ export class SQLCodeGenBase {
2172
2256
  const md = new Metadata(); // global-provider-ok: codegen runs offline against a single provider
2173
2257
  // Find all fields in other entities that are foreign keys to this entity
2174
2258
  for (const e of md.Entities) {
2175
- if (!shouldEmitCascadeForRelatedEntity(entity.SchemaName, e.SchemaName, configInfo.allowCrossSchemaCascadeDeletes === true)) {
2259
+ if (!ShouldEmitCascadeForRelatedEntity(entity.SchemaName, e.SchemaName, configInfo.allowCrossSchemaCascadeDeletes === true)) {
2176
2260
  continue;
2177
2261
  }
2178
2262
  for (const ef of e.Fields) {
@@ -2203,7 +2287,7 @@ export class SQLCodeGenBase {
2203
2287
  else {
2204
2288
  // Can't delete and can't safely update - warn
2205
2289
  const msg = `${relatedEntity.Name}.${fkField.Name} is part of composite unique constraint but entity doesn't allow delete API`;
2206
- logWarning(`WARNING in spDelete${parentEntity.BaseTableCodeName}: ${msg}`);
2290
+ LogWarning(`WARNING in spDelete${parentEntity.BaseTableCodeName}: ${msg}`);
2207
2291
  return `
2208
2292
  -- WARNING: ${msg} - cascade operation may fail due to unique constraint violation`;
2209
2293
  }
@@ -2221,7 +2305,7 @@ export class SQLCodeGenBase {
2221
2305
  // Nullable FK but no update API - this is a configuration error
2222
2306
  const sqlComment = `WARNING: ${relatedEntity.BaseTable} has nullable FK to ${parentEntity.BaseTable} but doesn't allow update API - cascade operation will fail`;
2223
2307
  const consoleMsg = `WARNING in spDelete${parentEntity.BaseTableCodeName} generation: ${relatedEntity.BaseTable} has nullable FK to ${parentEntity.BaseTable} but doesn't allow update API - cascade operation will fail`;
2224
- logWarning(consoleMsg);
2308
+ LogWarning(consoleMsg);
2225
2309
  return `
2226
2310
  -- ${sqlComment}
2227
2311
  -- This will cause the delete operation to fail due to referential integrity`;
@@ -2230,7 +2314,7 @@ export class SQLCodeGenBase {
2230
2314
  // Entity doesn't allow delete API, so we can't cascade delete
2231
2315
  const sqlComment = `WARNING: ${relatedEntity.BaseTable} has non-nullable FK to ${parentEntity.BaseTable} but doesn't allow delete API - cascade operation will fail`;
2232
2316
  const consoleMsg = `WARNING in spDelete${parentEntity.BaseTableCodeName} generation: ${relatedEntity.BaseTable} has non-nullable FK to ${parentEntity.BaseTable} but doesn't allow delete API - cascade operation will fail`;
2233
- logWarning(consoleMsg);
2317
+ LogWarning(consoleMsg);
2234
2318
  return `
2235
2319
  -- ${sqlComment}
2236
2320
  -- This will cause a referential integrity violation`;
@@ -2272,7 +2356,7 @@ export class SQLCodeGenBase {
2272
2356
  return result.recordset.length > 0;
2273
2357
  }
2274
2358
  catch (error) {
2275
- logWarning(`Failed to check composite unique constraint for ${schemaName}.${tableName}.${columnName}: ${error}`);
2359
+ LogWarning(`Failed to check composite unique constraint for ${schemaName}.${tableName}.${columnName}: ${error}`);
2276
2360
  return false; // Fallback to existing UPDATE behavior
2277
2361
  }
2278
2362
  }
@@ -2285,7 +2369,7 @@ export class SQLCodeGenBase {
2285
2369
  const md = new Metadata(); // global-provider-ok: codegen runs offline against a single provider
2286
2370
  // Find all fields in other entities that are foreign keys to this entity
2287
2371
  for (const e of md.Entities) {
2288
- if (!shouldEmitCascadeForRelatedEntity(entity.SchemaName, e.SchemaName, configInfo.allowCrossSchemaCascadeDeletes === true)) {
2372
+ if (!ShouldEmitCascadeForRelatedEntity(entity.SchemaName, e.SchemaName, configInfo.allowCrossSchemaCascadeDeletes === true)) {
2289
2373
  continue;
2290
2374
  }
2291
2375
  for (const ef of e.Fields) {