@memberjunction/codegen-lib 2.47.0 → 2.49.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Angular/angular-codegen.d.ts +164 -6
- package/dist/Angular/angular-codegen.d.ts.map +1 -1
- package/dist/Angular/angular-codegen.js +179 -25
- package/dist/Angular/angular-codegen.js.map +1 -1
- package/dist/Angular/join-grid-related-entity-component.d.ts +52 -3
- package/dist/Angular/join-grid-related-entity-component.d.ts.map +1 -1
- package/dist/Angular/join-grid-related-entity-component.js +58 -3
- package/dist/Angular/join-grid-related-entity-component.js.map +1 -1
- package/dist/Angular/related-entity-components.d.ts +99 -42
- package/dist/Angular/related-entity-components.d.ts.map +1 -1
- package/dist/Angular/related-entity-components.js +116 -26
- package/dist/Angular/related-entity-components.js.map +1 -1
- package/dist/Angular/timeline-related-entity-component.d.ts +46 -7
- package/dist/Angular/timeline-related-entity-component.d.ts.map +1 -1
- package/dist/Angular/timeline-related-entity-component.js +64 -7
- package/dist/Angular/timeline-related-entity-component.js.map +1 -1
- package/dist/Angular/user-view-grid-related-entity-component.d.ts +33 -1
- package/dist/Angular/user-view-grid-related-entity-component.d.ts.map +1 -1
- package/dist/Angular/user-view-grid-related-entity-component.js +33 -1
- package/dist/Angular/user-view-grid-related-entity-component.js.map +1 -1
- package/dist/Config/config.d.ts +369 -45
- package/dist/Config/config.d.ts.map +1 -1
- package/dist/Config/config.js +136 -2
- package/dist/Config/config.js.map +1 -1
- package/dist/Config/db-connection.d.ts +17 -3
- package/dist/Config/db-connection.d.ts.map +1 -1
- package/dist/Config/db-connection.js +31 -19
- package/dist/Config/db-connection.js.map +1 -1
- package/dist/Database/dbSchema.d.ts +44 -1
- package/dist/Database/dbSchema.d.ts.map +1 -1
- package/dist/Database/dbSchema.js +46 -13
- package/dist/Database/dbSchema.js.map +1 -1
- package/dist/Database/manage-metadata.d.ts +52 -46
- package/dist/Database/manage-metadata.d.ts.map +1 -1
- package/dist/Database/manage-metadata.js +235 -191
- package/dist/Database/manage-metadata.js.map +1 -1
- package/dist/Database/reorder-columns.d.ts +2 -2
- package/dist/Database/reorder-columns.d.ts.map +1 -1
- package/dist/Database/reorder-columns.js +23 -17
- package/dist/Database/reorder-columns.js.map +1 -1
- package/dist/Database/sql.d.ts +4 -4
- package/dist/Database/sql.d.ts.map +1 -1
- package/dist/Database/sql.js +5 -16
- package/dist/Database/sql.js.map +1 -1
- package/dist/Database/sql_codegen.d.ts +15 -15
- package/dist/Database/sql_codegen.d.ts.map +1 -1
- package/dist/Database/sql_codegen.js +186 -123
- package/dist/Database/sql_codegen.js.map +1 -1
- package/dist/Misc/action_subclasses_codegen.d.ts.map +1 -1
- package/dist/Misc/action_subclasses_codegen.js +2 -12
- package/dist/Misc/action_subclasses_codegen.js.map +1 -1
- package/dist/Misc/advanced_generation.d.ts.map +1 -1
- package/dist/Misc/advanced_generation.js +82 -92
- package/dist/Misc/advanced_generation.js.map +1 -1
- package/dist/Misc/createNewUser.d.ts.map +1 -1
- package/dist/Misc/createNewUser.js +2 -12
- package/dist/Misc/createNewUser.js.map +1 -1
- package/dist/Misc/entity_subclasses_codegen.d.ts +5 -5
- package/dist/Misc/entity_subclasses_codegen.d.ts.map +1 -1
- package/dist/Misc/entity_subclasses_codegen.js +12 -20
- package/dist/Misc/entity_subclasses_codegen.js.map +1 -1
- package/dist/Misc/graphql_server_codegen.d.ts.map +1 -1
- package/dist/Misc/graphql_server_codegen.js +35 -40
- package/dist/Misc/graphql_server_codegen.js.map +1 -1
- package/dist/Misc/runCommand.d.ts.map +1 -1
- package/dist/Misc/runCommand.js +2 -12
- package/dist/Misc/runCommand.js.map +1 -1
- package/dist/Misc/sql_logging.d.ts +2 -2
- package/dist/Misc/sql_logging.d.ts.map +1 -1
- package/dist/Misc/sql_logging.js +4 -3
- package/dist/Misc/sql_logging.js.map +1 -1
- package/dist/Misc/status_logging.d.ts +37 -0
- package/dist/Misc/status_logging.d.ts.map +1 -1
- package/dist/Misc/status_logging.js +147 -14
- package/dist/Misc/status_logging.js.map +1 -1
- package/dist/Misc/system_integrity.d.ts +9 -9
- package/dist/Misc/system_integrity.d.ts.map +1 -1
- package/dist/Misc/system_integrity.js +23 -21
- package/dist/Misc/system_integrity.js.map +1 -1
- package/dist/index.d.ts +45 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +51 -7
- package/dist/index.js.map +1 -1
- package/dist/runCodeGen.d.ts +84 -6
- package/dist/runCodeGen.d.ts.map +1 -1
- package/dist/runCodeGen.js +244 -93
- package/dist/runCodeGen.js.map +1 -1
- package/package.json +14 -14
|
@@ -15,12 +15,6 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
15
|
}) : function(o, v) {
|
|
16
16
|
o["default"] = v;
|
|
17
17
|
});
|
|
18
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
19
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
20
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
21
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
22
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
23
|
-
};
|
|
24
18
|
var __importStar = (this && this.__importStar) || function (mod) {
|
|
25
19
|
if (mod && mod.__esModule) return mod;
|
|
26
20
|
var result = {};
|
|
@@ -54,34 +48,37 @@ exports.SPType = {
|
|
|
54
48
|
* 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
|
|
55
49
|
* of that abstract base class and other databases will be sub-classes of the abstract base class as well.
|
|
56
50
|
*/
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
this._sqlUtilityObject = global_1.MJGlobal.Instance.ClassFactory.CreateInstance(sql_1.SQLUtilityBase);
|
|
60
|
-
this.__specialUUIDValue = '00000000-0000-0000-0000-000000000000';
|
|
61
|
-
}
|
|
51
|
+
class SQLCodeGenBase {
|
|
52
|
+
_sqlUtilityObject = global_1.MJGlobal.Instance.ClassFactory.CreateInstance(sql_1.SQLUtilityBase);
|
|
62
53
|
get SQLUtilityObject() {
|
|
63
54
|
return this._sqlUtilityObject;
|
|
64
55
|
}
|
|
65
|
-
async manageSQLScriptsAndExecution(
|
|
56
|
+
async manageSQLScriptsAndExecution(pool, entities, directory, currentUser) {
|
|
66
57
|
try {
|
|
67
58
|
// STEP 1 - execute any custom SQL scripts for object creation that need to happen first - for example, if
|
|
68
59
|
// we have custom base views, need to have them defined before we do
|
|
69
60
|
// the rest as the generated stuff might use custom base views in compiled
|
|
70
61
|
// objects like spCreate for a given entity might reference the vw for that entity
|
|
62
|
+
(0, status_logging_1.startSpinner)('Running custom SQL scripts...');
|
|
71
63
|
const startTime = new Date();
|
|
72
|
-
if (!await this.runCustomSQLScripts(
|
|
64
|
+
if (!await this.runCustomSQLScripts(pool, 'before-sql')) {
|
|
65
|
+
(0, status_logging_1.failSpinner)('Failed to run custom SQL scripts');
|
|
73
66
|
return false;
|
|
74
|
-
|
|
67
|
+
}
|
|
68
|
+
(0, status_logging_1.succeedSpinner)(`Custom SQL scripts completed (${(new Date().getTime() - startTime.getTime()) / 1000}s)`);
|
|
75
69
|
// ALWAYS use the first filter where we only include entities that have IncludeInAPI = 1
|
|
76
70
|
const baselineEntities = entities.filter(e => e.IncludeInAPI);
|
|
77
71
|
const includedEntities = baselineEntities.filter(e => config_1.configInfo.excludeSchemas.find(s => s.toLowerCase() === e.SchemaName.toLowerCase()) === undefined); //only include entities that are NOT in the excludeSchemas list
|
|
78
72
|
const excludedEntities = baselineEntities.filter(e => config_1.configInfo.excludeSchemas.find(s => s.toLowerCase() === e.SchemaName.toLowerCase()) !== undefined); //only include entities that ARE in the excludeSchemas list in this array
|
|
79
73
|
// STEP 2(a) - clean out all *.generated.sql and *.permissions.generated.sql files from the directory
|
|
74
|
+
(0, status_logging_1.startSpinner)('Cleaning generated files...');
|
|
80
75
|
this.deleteGeneratedEntityFiles(directory, baselineEntities);
|
|
76
|
+
(0, status_logging_1.succeedSpinner)('Cleaned generated files');
|
|
81
77
|
// STEP 2(b) - generate all the SQL files and execute them
|
|
78
|
+
(0, status_logging_1.startSpinner)(`Generating SQL for ${includedEntities.length} entities...`);
|
|
82
79
|
const step2StartTime = new Date();
|
|
83
80
|
const genResult = await this.generateAndExecuteEntitySQLToSeparateFiles({
|
|
84
|
-
|
|
81
|
+
pool,
|
|
85
82
|
entities: includedEntities,
|
|
86
83
|
directory,
|
|
87
84
|
onlyPermissions: false,
|
|
@@ -91,12 +88,13 @@ let SQLCodeGenBase = class SQLCodeGenBase {
|
|
|
91
88
|
enableSQLLoggingForNewOrModifiedEntities: true
|
|
92
89
|
}); // enable sql logging for NEW entities....
|
|
93
90
|
if (!genResult.Success) {
|
|
94
|
-
(0, status_logging_1.
|
|
91
|
+
(0, status_logging_1.failSpinner)('Failed to generate entity SQL files');
|
|
95
92
|
return false;
|
|
96
93
|
}
|
|
97
94
|
// STEP 2(c) - for the excludedEntities, while we don't want to generate SQL, we do want to generate the permissions files for them
|
|
95
|
+
(0, status_logging_1.updateSpinner)(`Generating permissions for ${excludedEntities.length} excluded entities...`);
|
|
98
96
|
const genResult2 = await this.generateAndExecuteEntitySQLToSeparateFiles({
|
|
99
|
-
|
|
97
|
+
pool,
|
|
100
98
|
entities: excludedEntities,
|
|
101
99
|
directory,
|
|
102
100
|
onlyPermissions: true,
|
|
@@ -106,41 +104,50 @@ let SQLCodeGenBase = class SQLCodeGenBase {
|
|
|
106
104
|
enableSQLLoggingForNewOrModifiedEntities: false /*don't log this stuff, it is just permissions for excluded entities*/
|
|
107
105
|
});
|
|
108
106
|
if (!genResult2.Success) {
|
|
109
|
-
(0, status_logging_1.
|
|
107
|
+
(0, status_logging_1.failSpinner)('Failed to generate permissions for excluded entities');
|
|
110
108
|
return false;
|
|
111
109
|
}
|
|
112
|
-
(0, status_logging_1.
|
|
110
|
+
(0, status_logging_1.succeedSpinner)(`Entity generation completed (${(new Date().getTime() - step2StartTime.getTime()) / 1000}s)`);
|
|
113
111
|
// 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
|
|
112
|
+
(0, status_logging_1.startSpinner)('Creating combined SQL files...');
|
|
114
113
|
const allEntityFiles = this.createCombinedEntitySQLFiles(directory, baselineEntities);
|
|
114
|
+
(0, status_logging_1.succeedSpinner)(`Created combined SQL files for ${allEntityFiles.length} schemas`);
|
|
115
115
|
// STEP 2(e) ---- FINALLY, we now execute all the combined files by schema;
|
|
116
|
+
(0, status_logging_1.startSpinner)('Executing combined entity SQL files...');
|
|
116
117
|
const step2eStartTime = new Date();
|
|
117
|
-
if (!await this.SQLUtilityObject.executeSQLFiles(allEntityFiles,
|
|
118
|
-
(0, status_logging_1.
|
|
118
|
+
if (!await this.SQLUtilityObject.executeSQLFiles(allEntityFiles, config_1.configInfo?.verboseOutput ?? false)) {
|
|
119
|
+
(0, status_logging_1.failSpinner)('Failed to execute combined entity SQL files');
|
|
119
120
|
return false;
|
|
120
121
|
}
|
|
121
122
|
const step2eEndTime = new Date();
|
|
122
|
-
(0, status_logging_1.
|
|
123
|
+
(0, status_logging_1.succeedSpinner)(`SQL execution completed (${(step2eEndTime.getTime() - step2eStartTime.getTime()) / 1000}s)`);
|
|
123
124
|
const manageMD = global_1.MJGlobal.Instance.ClassFactory.CreateInstance(manage_metadata_1.ManageMetadataBase);
|
|
124
125
|
// 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
|
|
125
126
|
// we CAN skip the entity field values part because that wouldn't change from the first time we ran it
|
|
126
|
-
|
|
127
|
-
|
|
127
|
+
(0, status_logging_1.startSpinner)('Managing entity fields metadata...');
|
|
128
|
+
if (!await manageMD.manageEntityFields(pool, config_1.configInfo.excludeSchemas, true, true, currentUser)) {
|
|
129
|
+
(0, status_logging_1.failSpinner)('Failed to manage entity fields');
|
|
128
130
|
return false;
|
|
129
131
|
}
|
|
132
|
+
(0, status_logging_1.succeedSpinner)('Entity fields metadata updated');
|
|
130
133
|
// 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
|
|
131
134
|
// STEP 4- Apply permissions, executing all .permissions files
|
|
135
|
+
(0, status_logging_1.startSpinner)('Applying permissions...');
|
|
132
136
|
const step4StartTime = new Date();
|
|
133
|
-
if (!await this.applyPermissions(
|
|
134
|
-
(0, status_logging_1.
|
|
137
|
+
if (!await this.applyPermissions(pool, directory, baselineEntities)) {
|
|
138
|
+
(0, status_logging_1.failSpinner)('Failed to apply permissions');
|
|
135
139
|
return false;
|
|
136
140
|
}
|
|
137
|
-
(0, status_logging_1.
|
|
141
|
+
(0, status_logging_1.succeedSpinner)(`Permissions applied (${(new Date().getTime() - step4StartTime.getTime()) / 1000}s)`);
|
|
138
142
|
// STEP 5 - execute any custom SQL scripts that should run afterwards
|
|
143
|
+
(0, status_logging_1.startSpinner)('Running post-generation SQL scripts...');
|
|
139
144
|
const step5StartTime = new Date();
|
|
140
|
-
if (!await this.runCustomSQLScripts(
|
|
145
|
+
if (!await this.runCustomSQLScripts(pool, 'after-sql')) {
|
|
146
|
+
(0, status_logging_1.failSpinner)('Failed to run post-generation SQL scripts');
|
|
141
147
|
return false;
|
|
142
|
-
|
|
143
|
-
(0, status_logging_1.
|
|
148
|
+
}
|
|
149
|
+
(0, status_logging_1.succeedSpinner)(`Post-generation scripts completed (${(new Date().getTime() - step5StartTime.getTime()) / 1000}s)`);
|
|
150
|
+
(0, status_logging_1.succeedSpinner)(`CodeGen completed successfully (${((new Date().getTime() - startTime.getTime()) / 1000)}s total)`);
|
|
144
151
|
// now - we need to tell our metadata object to refresh itself
|
|
145
152
|
const md = new core_1.Metadata();
|
|
146
153
|
await md.Refresh();
|
|
@@ -151,7 +158,7 @@ let SQLCodeGenBase = class SQLCodeGenBase {
|
|
|
151
158
|
return false;
|
|
152
159
|
}
|
|
153
160
|
}
|
|
154
|
-
async runCustomSQLScripts(
|
|
161
|
+
async runCustomSQLScripts(pool, when) {
|
|
155
162
|
try {
|
|
156
163
|
const scripts = (0, config_1.customSqlScripts)(when);
|
|
157
164
|
let bSuccess = true;
|
|
@@ -171,7 +178,7 @@ let SQLCodeGenBase = class SQLCodeGenBase {
|
|
|
171
178
|
return false;
|
|
172
179
|
}
|
|
173
180
|
}
|
|
174
|
-
async applyPermissions(
|
|
181
|
+
async applyPermissions(pool, directory, entities, batchSize = 5) {
|
|
175
182
|
try {
|
|
176
183
|
let bSuccess = true;
|
|
177
184
|
for (let i = 0; i < entities.length; i += batchSize) {
|
|
@@ -186,7 +193,7 @@ let SQLCodeGenBase = class SQLCodeGenBase {
|
|
|
186
193
|
const fileBuffer = fs.readFileSync(fullPath);
|
|
187
194
|
const fileContents = fileBuffer.toString();
|
|
188
195
|
try {
|
|
189
|
-
await
|
|
196
|
+
await pool.request().query(fileContents);
|
|
190
197
|
}
|
|
191
198
|
catch (e) {
|
|
192
199
|
(0, status_logging_1.logError)(`Error executing permissions file ${fullPath} for entity ${e.Name}: ${e}`);
|
|
@@ -237,7 +244,7 @@ let SQLCodeGenBase = class SQLCodeGenBase {
|
|
|
237
244
|
return { Success: false, Files: [] };
|
|
238
245
|
}
|
|
239
246
|
return this.generateAndExecuteSingleEntitySQLToSeparateFiles({
|
|
240
|
-
|
|
247
|
+
pool: options.pool,
|
|
241
248
|
entity: e,
|
|
242
249
|
directory: options.directory,
|
|
243
250
|
onlyPermissions: options.onlyPermissions,
|
|
@@ -310,7 +317,7 @@ let SQLCodeGenBase = class SQLCodeGenBase {
|
|
|
310
317
|
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
|
|
311
318
|
if (!options.skipExecution) {
|
|
312
319
|
return {
|
|
313
|
-
Success: await this.SQLUtilityObject.executeSQLScript(options.
|
|
320
|
+
Success: await this.SQLUtilityObject.executeSQLScript(options.pool, sql + "\n\nGO\n\n" + permissionsSQL, true), // combine the SQL and permissions and execute it,
|
|
314
321
|
Files: files
|
|
315
322
|
};
|
|
316
323
|
}
|
|
@@ -323,9 +330,26 @@ let SQLCodeGenBase = class SQLCodeGenBase {
|
|
|
323
330
|
}
|
|
324
331
|
}
|
|
325
332
|
logSQLForNewOrModifiedEntity(entity, sql, description, logSql = false) {
|
|
326
|
-
if
|
|
327
|
-
|
|
328
|
-
|
|
333
|
+
// Check if we should log this SQL
|
|
334
|
+
let shouldLog = false;
|
|
335
|
+
if (logSql) {
|
|
336
|
+
// Check if entity is in new or modified lists
|
|
337
|
+
const isNewOrModified = !!manage_metadata_1.ManageMetadataBase.newEntityList.find(e => e === entity.Name) ||
|
|
338
|
+
!!manage_metadata_1.ManageMetadataBase.modifiedEntityList.find(e => e === entity.Name);
|
|
339
|
+
// Check if force regeneration is enabled for relevant SQL types
|
|
340
|
+
const isForceRegeneration = config_1.configInfo.forceRegeneration?.enabled && ((description.toLowerCase().includes('base view') && config_1.configInfo.forceRegeneration.baseViews) ||
|
|
341
|
+
(description.toLowerCase().includes('spcreate') && config_1.configInfo.forceRegeneration.spCreate) ||
|
|
342
|
+
(description.toLowerCase().includes('spupdate') && config_1.configInfo.forceRegeneration.spUpdate) ||
|
|
343
|
+
(description.toLowerCase().includes('spdelete') && config_1.configInfo.forceRegeneration.spDelete) ||
|
|
344
|
+
(description.toLowerCase().includes('index') && config_1.configInfo.forceRegeneration.indexes) ||
|
|
345
|
+
(description.toLowerCase().includes('full text search') && config_1.configInfo.forceRegeneration.fullTextSearch) ||
|
|
346
|
+
(config_1.configInfo.forceRegeneration.allStoredProcedures &&
|
|
347
|
+
(description.toLowerCase().includes('spcreate') ||
|
|
348
|
+
description.toLowerCase().includes('spupdate') ||
|
|
349
|
+
description.toLowerCase().includes('spdelete'))));
|
|
350
|
+
shouldLog = isNewOrModified || isForceRegeneration;
|
|
351
|
+
}
|
|
352
|
+
if (shouldLog) {
|
|
329
353
|
sql_logging_1.SQLLogging.appendToSQLLogFile(sql, description);
|
|
330
354
|
}
|
|
331
355
|
(0, util_1.logIf)(config_1.configInfo.verboseOutput, `SQL Generated for ${entity.Name}: ${description}`);
|
|
@@ -344,7 +368,8 @@ let SQLCodeGenBase = class SQLCodeGenBase {
|
|
|
344
368
|
let permissionsSQL = '';
|
|
345
369
|
// Indexes for Fkeys for the table
|
|
346
370
|
if (!options.onlyPermissions) {
|
|
347
|
-
const
|
|
371
|
+
const shouldGenerateIndexes = (0, config_1.autoIndexForeignKeys)() || (config_1.configInfo.forceRegeneration?.enabled && config_1.configInfo.forceRegeneration?.indexes);
|
|
372
|
+
const indexSQL = shouldGenerateIndexes ? this.generateIndexesForForeignKeys(options.pool, options.entity) : ''; // generate indexes if auto-indexing is on OR force regeneration is enabled
|
|
348
373
|
const s = this.generateSingleEntitySQLFileHeader(options.entity, 'Index for Foreign Keys') + indexSQL;
|
|
349
374
|
if (options.writeFiles) {
|
|
350
375
|
const filePath = path_1.default.join(options.directory, this.SQLUtilityObject.getDBObjectFileName('index', options.entity.SchemaName, options.entity.BaseTable, false, true));
|
|
@@ -355,9 +380,11 @@ let SQLCodeGenBase = class SQLCodeGenBase {
|
|
|
355
380
|
sRet += s + '\nGO\n';
|
|
356
381
|
}
|
|
357
382
|
// BASE VIEW
|
|
358
|
-
if (!options.onlyPermissions &&
|
|
383
|
+
if (!options.onlyPermissions &&
|
|
384
|
+
(options.entity.BaseViewGenerated || (config_1.configInfo.forceRegeneration?.enabled && config_1.configInfo.forceRegeneration?.baseViews)) &&
|
|
385
|
+
!options.entity.VirtualEntity) {
|
|
359
386
|
// generate the base view
|
|
360
|
-
const s = this.generateSingleEntitySQLFileHeader(options.entity, options.entity.BaseView) + await this.generateBaseView(options.
|
|
387
|
+
const s = this.generateSingleEntitySQLFileHeader(options.entity, options.entity.BaseView) + await this.generateBaseView(options.pool, options.entity);
|
|
361
388
|
const filePath = path_1.default.join(options.directory, this.SQLUtilityObject.getDBObjectFileName('view', options.entity.SchemaName, options.entity.BaseView, false, true));
|
|
362
389
|
if (options.writeFiles) {
|
|
363
390
|
this.logSQLForNewOrModifiedEntity(options.entity, s, `Base View SQL for ${options.entity.Name}`, options.enableSQLLoggingForNewOrModifiedEntities);
|
|
@@ -383,7 +410,9 @@ let SQLCodeGenBase = class SQLCodeGenBase {
|
|
|
383
410
|
// CREATE SP
|
|
384
411
|
if (options.entity.AllowCreateAPI && !options.entity.VirtualEntity) {
|
|
385
412
|
const spName = this.getSPName(options.entity, exports.SPType.Create);
|
|
386
|
-
if (!options.onlyPermissions &&
|
|
413
|
+
if (!options.onlyPermissions &&
|
|
414
|
+
(options.entity.spCreateGenerated ||
|
|
415
|
+
(config_1.configInfo.forceRegeneration?.enabled && (config_1.configInfo.forceRegeneration?.spCreate || config_1.configInfo.forceRegeneration?.allStoredProcedures)))) {
|
|
387
416
|
// generate the create SP
|
|
388
417
|
const s = this.generateSingleEntitySQLFileHeader(options.entity, spName) + this.generateSPCreate(options.entity);
|
|
389
418
|
if (options.writeFiles) {
|
|
@@ -411,7 +440,9 @@ let SQLCodeGenBase = class SQLCodeGenBase {
|
|
|
411
440
|
// UPDATE SP
|
|
412
441
|
if (options.entity.AllowUpdateAPI && !options.entity.VirtualEntity) {
|
|
413
442
|
const spName = this.getSPName(options.entity, exports.SPType.Update);
|
|
414
|
-
if (!options.onlyPermissions &&
|
|
443
|
+
if (!options.onlyPermissions &&
|
|
444
|
+
(options.entity.spUpdateGenerated ||
|
|
445
|
+
(config_1.configInfo.forceRegeneration?.enabled && (config_1.configInfo.forceRegeneration?.spUpdate || config_1.configInfo.forceRegeneration?.allStoredProcedures)))) {
|
|
415
446
|
// generate the update SP
|
|
416
447
|
const s = this.generateSingleEntitySQLFileHeader(options.entity, spName) + this.generateSPUpdate(options.entity);
|
|
417
448
|
if (options.writeFiles) {
|
|
@@ -439,7 +470,9 @@ let SQLCodeGenBase = class SQLCodeGenBase {
|
|
|
439
470
|
// DELETE SP
|
|
440
471
|
if (options.entity.AllowDeleteAPI && !options.entity.VirtualEntity) {
|
|
441
472
|
const spName = this.getSPName(options.entity, exports.SPType.Delete);
|
|
442
|
-
if (!options.onlyPermissions &&
|
|
473
|
+
if (!options.onlyPermissions &&
|
|
474
|
+
(options.entity.spDeleteGenerated ||
|
|
475
|
+
(config_1.configInfo.forceRegeneration?.enabled && (config_1.configInfo.forceRegeneration?.spDelete || config_1.configInfo.forceRegeneration?.allStoredProcedures)))) {
|
|
443
476
|
// generate the delete SP
|
|
444
477
|
const s = this.generateSingleEntitySQLFileHeader(options.entity, spName) + this.generateSPDelete(options.entity);
|
|
445
478
|
if (options.writeFiles) {
|
|
@@ -465,9 +498,9 @@ let SQLCodeGenBase = class SQLCodeGenBase {
|
|
|
465
498
|
sRet += s + '\nGO\n';
|
|
466
499
|
}
|
|
467
500
|
// check to see if the options.entity supports full text search or not
|
|
468
|
-
if (options.entity.FullTextSearchEnabled) {
|
|
501
|
+
if (options.entity.FullTextSearchEnabled || (config_1.configInfo.forceRegeneration?.enabled && config_1.configInfo.forceRegeneration?.fullTextSearch)) {
|
|
469
502
|
// always generate the code so we can get the function name from the below function call
|
|
470
|
-
const ft = await this.generateEntityFullTextSearchSQL(options.
|
|
503
|
+
const ft = await this.generateEntityFullTextSearchSQL(options.pool, options.entity);
|
|
471
504
|
if (!options.onlyPermissions) {
|
|
472
505
|
// only write the actual sql out if we're not only generating permissions
|
|
473
506
|
const filePath = path_1.default.join(options.directory, this.SQLUtilityObject.getDBObjectFileName('full_text_search_function', options.entity.SchemaName, options.entity.BaseTable, false, true));
|
|
@@ -534,11 +567,11 @@ let SQLCodeGenBase = class SQLCodeGenBase {
|
|
|
534
567
|
* @param entity
|
|
535
568
|
* @returns
|
|
536
569
|
*/
|
|
537
|
-
async generateEntitySQL(
|
|
570
|
+
async generateEntitySQL(pool, entity) {
|
|
538
571
|
let sOutput = '';
|
|
539
572
|
if (entity.BaseViewGenerated && !entity.VirtualEntity)
|
|
540
573
|
// generated the base view (will include permissions)
|
|
541
|
-
sOutput += await this.generateBaseView(
|
|
574
|
+
sOutput += await this.generateBaseView(pool, entity) + '\n\n';
|
|
542
575
|
else
|
|
543
576
|
// still generate the permissions for the view even if a custom view
|
|
544
577
|
sOutput += this.generateViewPermissions(entity) + '\n\n';
|
|
@@ -568,11 +601,11 @@ let SQLCodeGenBase = class SQLCodeGenBase {
|
|
|
568
601
|
}
|
|
569
602
|
// check to see if the entity supports full text search or not
|
|
570
603
|
if (entity.FullTextSearchEnabled) {
|
|
571
|
-
sOutput += await this.generateEntityFullTextSearchSQL(
|
|
604
|
+
sOutput += await this.generateEntityFullTextSearchSQL(pool, entity) + '\n\n';
|
|
572
605
|
}
|
|
573
606
|
return sOutput;
|
|
574
607
|
}
|
|
575
|
-
async generateEntityFullTextSearchSQL(
|
|
608
|
+
async generateEntityFullTextSearchSQL(pool, entity) {
|
|
576
609
|
let sql = '';
|
|
577
610
|
const catalogName = entity.FullTextCatalog && entity.FullTextCatalog.length > 0 ? entity.FullTextCatalog : config_1.dbDatabase + '_FullTextCatalog';
|
|
578
611
|
if (entity.FullTextCatalogGenerated) {
|
|
@@ -592,7 +625,7 @@ let SQLCodeGenBase = class SQLCodeGenBase {
|
|
|
592
625
|
if (fullTextFields.length === 0)
|
|
593
626
|
throw new Error(`FullTextIndexGenerated is true for entity ${entity.Name}, but no fields are marked as FullTextSearchEnabled`);
|
|
594
627
|
// drop and recreate the full text index
|
|
595
|
-
const entity_pk_name = await this.getEntityPrimaryKeyIndexName(
|
|
628
|
+
const entity_pk_name = await this.getEntityPrimaryKeyIndexName(pool, entity);
|
|
596
629
|
sql += ` -- DROP AND RECREATE THE FULL TEXT INDEX
|
|
597
630
|
IF EXISTS (
|
|
598
631
|
SELECT *
|
|
@@ -659,7 +692,7 @@ let SQLCodeGenBase = class SQLCodeGenBase {
|
|
|
659
692
|
}
|
|
660
693
|
return { sql, functionName };
|
|
661
694
|
}
|
|
662
|
-
async getEntityPrimaryKeyIndexName(
|
|
695
|
+
async getEntityPrimaryKeyIndexName(pool, entity) {
|
|
663
696
|
const sSQL = ` SELECT
|
|
664
697
|
i.name AS IndexName
|
|
665
698
|
FROM
|
|
@@ -674,7 +707,8 @@ let SQLCodeGenBase = class SQLCodeGenBase {
|
|
|
674
707
|
o.schema_id = SCHEMA_ID('${entity.SchemaName}') AND
|
|
675
708
|
kc.type = 'PK';
|
|
676
709
|
`;
|
|
677
|
-
const
|
|
710
|
+
const resultResult = await pool.request().query(sSQL);
|
|
711
|
+
const result = resultResult.recordset;
|
|
678
712
|
if (result && result.length > 0)
|
|
679
713
|
return result[0].IndexName;
|
|
680
714
|
else
|
|
@@ -706,10 +740,10 @@ let SQLCodeGenBase = class SQLCodeGenBase {
|
|
|
706
740
|
}
|
|
707
741
|
/**
|
|
708
742
|
* Generates the SQL for creating indexes for the foreign keys in the entity
|
|
709
|
-
* @param
|
|
743
|
+
* @param pool
|
|
710
744
|
* @param entity
|
|
711
745
|
*/
|
|
712
|
-
generateIndexesForForeignKeys(
|
|
746
|
+
generateIndexesForForeignKeys(pool, entity) {
|
|
713
747
|
// iterate through all of the fields in the entity that are foreign keys and generate an index for each one
|
|
714
748
|
let sOutput = '';
|
|
715
749
|
for (const f of entity.Fields) {
|
|
@@ -732,10 +766,10 @@ CREATE INDEX ${indexName} ON [${entity.SchemaName}].[${entity.BaseTable}] ([${f.
|
|
|
732
766
|
}
|
|
733
767
|
return sOutput;
|
|
734
768
|
}
|
|
735
|
-
async generateBaseView(
|
|
769
|
+
async generateBaseView(pool, entity) {
|
|
736
770
|
const viewName = entity.BaseView ? entity.BaseView : `vw${entity.CodeName}`;
|
|
737
771
|
const classNameFirstChar = entity.ClassName.charAt(0).toLowerCase();
|
|
738
|
-
const relatedFieldsString = await this.generateBaseViewRelatedFieldsString(
|
|
772
|
+
const relatedFieldsString = await this.generateBaseViewRelatedFieldsString(pool, entity.Fields);
|
|
739
773
|
const relatedFieldsJoinString = this.generateBaseViewJoins(entity, entity.Fields);
|
|
740
774
|
const permissions = this.generateViewPermissions(entity);
|
|
741
775
|
const whereClause = entity.DeleteType === 'Soft' ? `WHERE
|
|
@@ -782,7 +816,7 @@ ${whereClause}GO${permissions}
|
|
|
782
816
|
}
|
|
783
817
|
return sOutput;
|
|
784
818
|
}
|
|
785
|
-
async generateBaseViewRelatedFieldsString(
|
|
819
|
+
async generateBaseViewRelatedFieldsString(pool, entityFields) {
|
|
786
820
|
let sOutput = '';
|
|
787
821
|
let fieldCount = 0;
|
|
788
822
|
const manageMD = global_1.MJGlobal.Instance.ClassFactory.CreateInstance(manage_metadata_1.ManageMetadataBase);
|
|
@@ -814,7 +848,7 @@ ${whereClause}GO${permissions}
|
|
|
814
848
|
// and it also reflects what the DB will hold
|
|
815
849
|
ef.RelatedEntityNameFieldMap = ef._RelatedEntityNameFieldMap;
|
|
816
850
|
// then update the database itself
|
|
817
|
-
await manageMD.updateEntityFieldRelatedEntityNameFieldMap(
|
|
851
|
+
await manageMD.updateEntityFieldRelatedEntityNameFieldMap(pool, ef.ID, ef.RelatedEntityNameFieldMap);
|
|
818
852
|
}
|
|
819
853
|
fieldCount++;
|
|
820
854
|
}
|
|
@@ -869,8 +903,8 @@ ${whereClause}GO${permissions}
|
|
|
869
903
|
const spName = entity.spCreate ? entity.spCreate : `spCreate${entity.ClassName}`;
|
|
870
904
|
const firstKey = entity.FirstPrimaryKey;
|
|
871
905
|
//double exclamations used on the firstKey.DefaultValue property otherwise the type of this variable is 'number | ""';
|
|
872
|
-
const primaryKeyAutomatic = firstKey.AutoIncrement
|
|
873
|
-
const efString = this.createEntityFieldsParamString(entity.Fields,
|
|
906
|
+
const primaryKeyAutomatic = firstKey.AutoIncrement; // Only exclude auto-increment fields, allow manual override for all other PKs including UUIDs with defaults
|
|
907
|
+
const efString = this.createEntityFieldsParamString(entity.Fields, false); // Always pass false for isUpdate since this is generateSPCreate
|
|
874
908
|
const permissions = this.generateSPPermissions(entity, spName, exports.SPType.Create);
|
|
875
909
|
let preInsertCode = '';
|
|
876
910
|
let outputCode = '';
|
|
@@ -880,29 +914,58 @@ ${whereClause}GO${permissions}
|
|
|
880
914
|
if (entity.FirstPrimaryKey.AutoIncrement) {
|
|
881
915
|
selectInsertedRecord = `SELECT * FROM [${entity.SchemaName}].[${entity.BaseView}] WHERE [${entity.FirstPrimaryKey.Name}] = SCOPE_IDENTITY()`;
|
|
882
916
|
}
|
|
883
|
-
else if (entity.FirstPrimaryKey.Type.toLowerCase().trim() === 'uniqueidentifier') {
|
|
884
|
-
// our primary key is a uniqueidentifier.
|
|
885
|
-
//
|
|
886
|
-
//
|
|
887
|
-
//
|
|
917
|
+
else if (entity.FirstPrimaryKey.Type.toLowerCase().trim() === 'uniqueidentifier' && entity.PrimaryKeys.length === 1) {
|
|
918
|
+
// our primary key is a uniqueidentifier. Now we support optional override:
|
|
919
|
+
// - If PKEY is provided (not NULL), use it
|
|
920
|
+
// - If PKEY is NULL and there's a default value, let the database use it
|
|
921
|
+
// - If PKEY is NULL and no default value, generate NEWID()
|
|
888
922
|
const hasDefaultValue = entity.FirstPrimaryKey.DefaultValue && entity.FirstPrimaryKey.DefaultValue.trim().length > 0;
|
|
889
|
-
// if we have a default value, then we do NOT want to insert a new value, let the database use the default
|
|
890
923
|
if (hasDefaultValue) {
|
|
891
|
-
//
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
924
|
+
// Has default value - use conditional logic to either include the field or let DB use default
|
|
925
|
+
preInsertCode = `DECLARE @InsertedRow TABLE ([${entity.FirstPrimaryKey.Name}] UNIQUEIDENTIFIER)
|
|
926
|
+
|
|
927
|
+
IF @${entity.FirstPrimaryKey.Name} IS NOT NULL
|
|
928
|
+
BEGIN
|
|
929
|
+
-- User provided a value, use it
|
|
930
|
+
INSERT INTO [${entity.SchemaName}].[${entity.BaseTable}]
|
|
931
|
+
(
|
|
932
|
+
[${entity.FirstPrimaryKey.Name}],
|
|
933
|
+
${this.createEntityFieldsInsertString(entity, entity.Fields, '', true)}
|
|
934
|
+
)
|
|
935
|
+
OUTPUT INSERTED.[${entity.FirstPrimaryKey.Name}] INTO @InsertedRow
|
|
936
|
+
VALUES
|
|
937
|
+
(
|
|
938
|
+
@${entity.FirstPrimaryKey.Name},
|
|
939
|
+
${this.createEntityFieldsInsertString(entity, entity.Fields, '@', true)}
|
|
940
|
+
)
|
|
941
|
+
END
|
|
942
|
+
ELSE
|
|
943
|
+
BEGIN
|
|
944
|
+
-- No value provided, let database use its default (e.g., NEWSEQUENTIALID())
|
|
945
|
+
INSERT INTO [${entity.SchemaName}].[${entity.BaseTable}]
|
|
946
|
+
(
|
|
947
|
+
${this.createEntityFieldsInsertString(entity, entity.Fields, '', true)}
|
|
948
|
+
)
|
|
949
|
+
OUTPUT INSERTED.[${entity.FirstPrimaryKey.Name}] INTO @InsertedRow
|
|
950
|
+
VALUES
|
|
951
|
+
(
|
|
952
|
+
${this.createEntityFieldsInsertString(entity, entity.Fields, '@', true)}
|
|
953
|
+
)
|
|
954
|
+
END`;
|
|
955
|
+
// Clear these as we're handling the INSERT in preInsertCode
|
|
956
|
+
additionalFieldList = '';
|
|
957
|
+
additionalValueList = '';
|
|
958
|
+
outputCode = '';
|
|
897
959
|
selectInsertedRecord = `SELECT * FROM [${entity.SchemaName}].[${entity.BaseView}] WHERE [${entity.FirstPrimaryKey.Name}] = (SELECT [${entity.FirstPrimaryKey.Name}] FROM @InsertedRow)`;
|
|
898
960
|
}
|
|
899
961
|
else {
|
|
900
|
-
//
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
962
|
+
// No default value - we calculate the ID upfront, so no need for OUTPUT clause
|
|
963
|
+
preInsertCode = `DECLARE @ActualID UNIQUEIDENTIFIER = ISNULL(@${entity.FirstPrimaryKey.Name}, NEWID())`;
|
|
964
|
+
additionalFieldList = ',\n [' + entity.FirstPrimaryKey.Name + ']';
|
|
965
|
+
additionalValueList = ',\n @ActualID';
|
|
966
|
+
outputCode = ''; // No OUTPUT clause needed
|
|
967
|
+
// We already know the ID, so just select using it directly
|
|
968
|
+
selectInsertedRecord = `SELECT * FROM [${entity.SchemaName}].[${entity.BaseView}] WHERE [${entity.FirstPrimaryKey.Name}] = @ActualID`;
|
|
906
969
|
}
|
|
907
970
|
}
|
|
908
971
|
else {
|
|
@@ -927,7 +990,7 @@ CREATE PROCEDURE [${entity.SchemaName}].[${spName}]
|
|
|
927
990
|
AS
|
|
928
991
|
BEGIN
|
|
929
992
|
SET NOCOUNT ON;
|
|
930
|
-
${preInsertCode}
|
|
993
|
+
${preInsertCode}${preInsertCode.includes('INSERT INTO') ? '' : `
|
|
931
994
|
INSERT INTO
|
|
932
995
|
[${entity.SchemaName}].[${entity.BaseTable}]
|
|
933
996
|
(
|
|
@@ -936,7 +999,7 @@ BEGIN
|
|
|
936
999
|
${outputCode}VALUES
|
|
937
1000
|
(
|
|
938
1001
|
${this.createEntityFieldsInsertString(entity, entity.Fields, '@')}${additionalValueList}
|
|
939
|
-
)
|
|
1002
|
+
)`}
|
|
940
1003
|
-- return the new record from the base view, which might have some calculated fields
|
|
941
1004
|
${selectInsertedRecord}
|
|
942
1005
|
END
|
|
@@ -1013,12 +1076,13 @@ GO
|
|
|
1013
1076
|
${updatedAtTrigger}
|
|
1014
1077
|
`;
|
|
1015
1078
|
}
|
|
1079
|
+
__specialUUIDValue = '00000000-0000-0000-0000-000000000000';
|
|
1016
1080
|
createEntityFieldsParamString(entityFields, isUpdate) {
|
|
1017
1081
|
let sOutput = '', isFirst = true;
|
|
1018
1082
|
for (let i = 0; i < entityFields.length; ++i) {
|
|
1019
1083
|
const ef = entityFields[i];
|
|
1020
|
-
const autoGeneratedPrimaryKey = ef.AutoIncrement
|
|
1021
|
-
if ((ef.AllowUpdateAPI || (ef.IsPrimaryKey && isUpdate)) &&
|
|
1084
|
+
const autoGeneratedPrimaryKey = ef.AutoIncrement; // Only exclude auto-increment fields from params
|
|
1085
|
+
if ((ef.AllowUpdateAPI || (ef.IsPrimaryKey && isUpdate) || (ef.IsPrimaryKey && !autoGeneratedPrimaryKey && !isUpdate)) &&
|
|
1022
1086
|
!ef.IsVirtual &&
|
|
1023
1087
|
(!ef.IsPrimaryKey || !autoGeneratedPrimaryKey || isUpdate) &&
|
|
1024
1088
|
!ef.IsSpecialDateField) {
|
|
@@ -1026,58 +1090,60 @@ ${updatedAtTrigger}
|
|
|
1026
1090
|
sOutput += ',\n ';
|
|
1027
1091
|
else
|
|
1028
1092
|
isFirst = false;
|
|
1029
|
-
//
|
|
1030
|
-
// to the sproc param with '00000000-0000-0000-0000-000000000000' so that the sproc can be called without passing in a value
|
|
1031
|
-
// within the sproc body for spCreate, we will look for this special value and substitute it with the actual default value for the column (typically newid() or newsequentialid())
|
|
1093
|
+
// Check if we need a default value
|
|
1032
1094
|
let defaultParamValue = '';
|
|
1033
|
-
if (!isUpdate && ef.
|
|
1034
|
-
|
|
1095
|
+
if (!isUpdate && ef.IsPrimaryKey && !ef.AutoIncrement) {
|
|
1096
|
+
// For primary keys (non-auto-increment), make them optional with NULL default
|
|
1097
|
+
// This allows callers to omit the PK and let the DB/sproc handle it
|
|
1098
|
+
defaultParamValue = ' = NULL';
|
|
1035
1099
|
}
|
|
1036
1100
|
sOutput += `@${ef.CodeName} ${ef.SQLFullType}${defaultParamValue}`;
|
|
1037
1101
|
}
|
|
1038
1102
|
}
|
|
1039
1103
|
return sOutput;
|
|
1040
1104
|
}
|
|
1041
|
-
createEntityFieldsInsertString(entity, entityFields, prefix) {
|
|
1042
|
-
const autoGeneratedPrimaryKey = entity.FirstPrimaryKey.AutoIncrement
|
|
1105
|
+
createEntityFieldsInsertString(entity, entityFields, prefix, excludePrimaryKey = false) {
|
|
1106
|
+
const autoGeneratedPrimaryKey = entity.FirstPrimaryKey.AutoIncrement; // Only exclude auto-increment PKs from insert
|
|
1043
1107
|
let sOutput = '', isFirst = true;
|
|
1044
1108
|
const filteredFields = entityFields.filter(f => f.AllowUpdateAPI);
|
|
1045
1109
|
for (let i = 0; i < entityFields.length; ++i) {
|
|
1046
1110
|
const ef = entityFields[i];
|
|
1047
1111
|
const quotes = ef.NeedsQuotes ? "'" : "";
|
|
1048
1112
|
// we only want fields that are (a) not primary keys, or if a pkey, not an auto-increment pkey and (b) not virtual fields and (c) updateable fields and (d) not auto-increment fields if they're not pkeys)
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1113
|
+
// ALSO: if excludePrimaryKey is true, skip all primary key fields
|
|
1114
|
+
if ((excludePrimaryKey && ef.IsPrimaryKey) || (ef.IsPrimaryKey && autoGeneratedPrimaryKey) || ef.IsVirtual || !ef.AllowUpdateAPI || ef.AutoIncrement) {
|
|
1115
|
+
continue; // skip this field
|
|
1116
|
+
}
|
|
1117
|
+
if (!isFirst)
|
|
1118
|
+
sOutput += ',\n ';
|
|
1119
|
+
else
|
|
1120
|
+
isFirst = false;
|
|
1121
|
+
if (prefix !== '' && ef.IsSpecialDateField) {
|
|
1122
|
+
if (ef.IsCreatedAtField || ef.IsUpdatedAtField)
|
|
1123
|
+
sOutput += `GETUTCDATE()`; // we set the inserted row value to the current date for created and updated at fields
|
|
1052
1124
|
else
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
// next check to make sure ef.DefaultValue does not contain quotes around the value if it is a string type, if it does, we need to remove them
|
|
1065
|
-
let defValue = ef.DefaultValue;
|
|
1066
|
-
if (ef.TSType === core_1.EntityFieldTSType.String) {
|
|
1067
|
-
if (defValue.startsWith("'") && defValue.endsWith("'")) {
|
|
1068
|
-
defValue = defValue.substring(1, defValue.length - 1).trim(); // remove the quotes
|
|
1069
|
-
}
|
|
1125
|
+
sOutput += `NULL`; // we don't set the deleted at field on an insert, only on a delete
|
|
1126
|
+
}
|
|
1127
|
+
else if ((prefix && prefix !== '') && !ef.IsPrimaryKey && ef.IsUniqueIdentifier && ef.HasDefaultValue) {
|
|
1128
|
+
// this is the VALUE side (prefix not null/blank), is NOT a primary key, and is a uniqueidentifier column, and has a default value specified
|
|
1129
|
+
// in this situation we need to check if the value being passed in is the special value '00000000-0000-0000-0000-000000000000' (which is in __specialUUIDValue) if it is, we substitute it with the actual default value
|
|
1130
|
+
// otherwise we use the value passed in
|
|
1131
|
+
// next check to make sure ef.DefaultValue does not contain quotes around the value if it is a string type, if it does, we need to remove them
|
|
1132
|
+
let defValue = ef.DefaultValue;
|
|
1133
|
+
if (ef.TSType === core_1.EntityFieldTSType.String) {
|
|
1134
|
+
if (defValue.startsWith("'") && defValue.endsWith("'")) {
|
|
1135
|
+
defValue = defValue.substring(1, defValue.length - 1).trim(); // remove the quotes
|
|
1070
1136
|
}
|
|
1071
|
-
sOutput += `CASE @${ef.CodeName} WHEN '${this.__specialUUIDValue}' THEN ${quotes}${defValue}${quotes} ELSE @${ef.CodeName} END`;
|
|
1072
|
-
}
|
|
1073
|
-
else {
|
|
1074
|
-
let sVal = '';
|
|
1075
|
-
if (!prefix || prefix.length === 0)
|
|
1076
|
-
sVal = '[' + ef.Name + ']'; // always put field names in brackets so that if reserved words are being used for field names in a table like "USER" and so on, they still work
|
|
1077
|
-
else
|
|
1078
|
-
sVal = prefix + ef.CodeName;
|
|
1079
|
-
sOutput += sVal;
|
|
1080
1137
|
}
|
|
1138
|
+
sOutput += `CASE @${ef.CodeName} WHEN '${this.__specialUUIDValue}' THEN ${quotes}${defValue}${quotes} ELSE @${ef.CodeName} END`;
|
|
1139
|
+
}
|
|
1140
|
+
else {
|
|
1141
|
+
let sVal = '';
|
|
1142
|
+
if (!prefix || prefix.length === 0)
|
|
1143
|
+
sVal = '[' + ef.Name + ']'; // always put field names in brackets so that if reserved words are being used for field names in a table like "USER" and so on, they still work
|
|
1144
|
+
else
|
|
1145
|
+
sVal = prefix + ef.CodeName;
|
|
1146
|
+
sOutput += sVal;
|
|
1081
1147
|
}
|
|
1082
1148
|
}
|
|
1083
1149
|
return sOutput;
|
|
@@ -1196,9 +1262,6 @@ GO${permissions}
|
|
|
1196
1262
|
}
|
|
1197
1263
|
return sOutput === '' ? '' : `${sOutput}\n `;
|
|
1198
1264
|
}
|
|
1199
|
-
}
|
|
1265
|
+
}
|
|
1200
1266
|
exports.SQLCodeGenBase = SQLCodeGenBase;
|
|
1201
|
-
exports.SQLCodeGenBase = SQLCodeGenBase = __decorate([
|
|
1202
|
-
(0, global_1.RegisterClass)(SQLCodeGenBase)
|
|
1203
|
-
], SQLCodeGenBase);
|
|
1204
1267
|
//# sourceMappingURL=sql_codegen.js.map
|