@memberjunction/codegen-lib 2.104.0 → 2.106.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +84 -2
- package/dist/Angular/angular-codegen.d.ts.map +1 -1
- package/dist/Angular/angular-codegen.js +9 -4
- package/dist/Angular/angular-codegen.js.map +1 -1
- package/dist/Config/config.d.ts.map +1 -1
- package/dist/Config/config.js +4 -0
- package/dist/Config/config.js.map +1 -1
- package/dist/Database/manage-metadata.d.ts.map +1 -1
- package/dist/Database/manage-metadata.js +47 -11
- package/dist/Database/manage-metadata.js.map +1 -1
- package/dist/Database/sql_codegen.d.ts +26 -1
- package/dist/Database/sql_codegen.d.ts.map +1 -1
- package/dist/Database/sql_codegen.js +176 -40
- package/dist/Database/sql_codegen.js.map +1 -1
- package/dist/Misc/advanced_generation.d.ts.map +1 -1
- package/dist/Misc/advanced_generation.js +4 -13
- package/dist/Misc/advanced_generation.js.map +1 -1
- package/dist/Misc/entity_subclasses_codegen.d.ts.map +1 -1
- package/dist/Misc/entity_subclasses_codegen.js +9 -4
- package/dist/Misc/entity_subclasses_codegen.js.map +1 -1
- package/dist/Misc/graphql_server_codegen.d.ts +64 -0
- package/dist/Misc/graphql_server_codegen.d.ts.map +1 -1
- package/dist/Misc/graphql_server_codegen.js +128 -27
- package/dist/Misc/graphql_server_codegen.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/package.json +8 -11
|
@@ -502,8 +502,10 @@ class SQLCodeGenBase {
|
|
|
502
502
|
sRet += s + '\nGO\n';
|
|
503
503
|
}
|
|
504
504
|
// BASE VIEW
|
|
505
|
+
// Only generate if BaseViewGenerated is true (respects custom views where it's false)
|
|
506
|
+
// forceRegeneration.baseViews only forces regeneration of views where BaseViewGenerated=true
|
|
505
507
|
if (!options.onlyPermissions &&
|
|
506
|
-
|
|
508
|
+
options.entity.BaseViewGenerated &&
|
|
507
509
|
!options.entity.VirtualEntity) {
|
|
508
510
|
// generate the base view
|
|
509
511
|
const s = this.generateSingleEntitySQLFileHeader(options.entity, options.entity.BaseView) + await this.generateBaseView(options.pool, options.entity);
|
|
@@ -532,9 +534,9 @@ class SQLCodeGenBase {
|
|
|
532
534
|
// CREATE SP
|
|
533
535
|
if (options.entity.AllowCreateAPI && !options.entity.VirtualEntity) {
|
|
534
536
|
const spName = this.getSPName(options.entity, exports.SPType.Create);
|
|
535
|
-
if (
|
|
536
|
-
|
|
537
|
-
|
|
537
|
+
// Only generate if spCreateGenerated is true (respects custom SPs where it's false)
|
|
538
|
+
// forceRegeneration only forces regeneration of SPs where spCreateGenerated=true
|
|
539
|
+
if (!options.onlyPermissions && options.entity.spCreateGenerated) {
|
|
538
540
|
// generate the create SP
|
|
539
541
|
const s = this.generateSingleEntitySQLFileHeader(options.entity, spName) + this.generateSPCreate(options.entity);
|
|
540
542
|
if (options.writeFiles) {
|
|
@@ -562,9 +564,9 @@ class SQLCodeGenBase {
|
|
|
562
564
|
// UPDATE SP
|
|
563
565
|
if (options.entity.AllowUpdateAPI && !options.entity.VirtualEntity) {
|
|
564
566
|
const spName = this.getSPName(options.entity, exports.SPType.Update);
|
|
565
|
-
if (
|
|
566
|
-
|
|
567
|
-
|
|
567
|
+
// Only generate if spUpdateGenerated is true (respects custom SPs where it's false)
|
|
568
|
+
// forceRegeneration only forces regeneration of SPs where spUpdateGenerated=true
|
|
569
|
+
if (!options.onlyPermissions && options.entity.spUpdateGenerated) {
|
|
568
570
|
// generate the update SP
|
|
569
571
|
const s = this.generateSingleEntitySQLFileHeader(options.entity, spName) + this.generateSPUpdate(options.entity);
|
|
570
572
|
if (options.writeFiles) {
|
|
@@ -592,9 +594,11 @@ class SQLCodeGenBase {
|
|
|
592
594
|
// DELETE SP
|
|
593
595
|
if (options.entity.AllowDeleteAPI && !options.entity.VirtualEntity) {
|
|
594
596
|
const spName = this.getSPName(options.entity, exports.SPType.Delete);
|
|
597
|
+
// Only generate if spDeleteGenerated is true (respects custom SPs where it's false)
|
|
598
|
+
// OR if this entity has cascade delete dependencies that require regeneration
|
|
599
|
+
// forceRegeneration only forces regeneration of SPs where spDeleteGenerated=true
|
|
595
600
|
if (!options.onlyPermissions &&
|
|
596
|
-
(options.entity.spDeleteGenerated ||
|
|
597
|
-
(config_1.configInfo.forceRegeneration?.enabled && (config_1.configInfo.forceRegeneration?.spDelete || config_1.configInfo.forceRegeneration?.allStoredProcedures)) ||
|
|
601
|
+
(options.entity.spDeleteGenerated ||
|
|
598
602
|
this.entitiesNeedingDeleteSPRegeneration.has(options.entity.ID))) {
|
|
599
603
|
// generate the delete SP
|
|
600
604
|
if (this.entitiesNeedingDeleteSPRegeneration.has(options.entity.ID)) {
|
|
@@ -892,6 +896,77 @@ CREATE INDEX ${indexName} ON [${entity.SchemaName}].[${entity.BaseTable}] ([${f.
|
|
|
892
896
|
}
|
|
893
897
|
return sOutput;
|
|
894
898
|
}
|
|
899
|
+
/**
|
|
900
|
+
* Detects self-referential foreign keys in an entity (e.g., ParentTaskID pointing back to Task table)
|
|
901
|
+
* Returns array of field info objects representing recursive relationships
|
|
902
|
+
*/
|
|
903
|
+
detectRecursiveForeignKeys(entity) {
|
|
904
|
+
return entity.Fields.filter(field => field.RelatedEntityID != null &&
|
|
905
|
+
field.RelatedEntityID === entity.ID);
|
|
906
|
+
}
|
|
907
|
+
/**
|
|
908
|
+
* Generates the WITH clause containing recursive CTEs for root ID calculation
|
|
909
|
+
* Each recursive FK gets its own CTE that traverses the hierarchy to find the root
|
|
910
|
+
*/
|
|
911
|
+
generateRecursiveCTEs(entity, recursiveFKs) {
|
|
912
|
+
const primaryKey = entity.FirstPrimaryKey.Name;
|
|
913
|
+
const schemaName = entity.SchemaName;
|
|
914
|
+
const tableName = entity.BaseTable;
|
|
915
|
+
const classNameFirstChar = entity.ClassName.charAt(0).toLowerCase();
|
|
916
|
+
const ctes = recursiveFKs.map(field => {
|
|
917
|
+
const fieldName = field.Name;
|
|
918
|
+
const rootFieldName = `Root${fieldName}`;
|
|
919
|
+
const cteName = `CTE_${rootFieldName}`;
|
|
920
|
+
return ` ${cteName} AS (
|
|
921
|
+
-- Anchor: rows with no parent (root nodes)
|
|
922
|
+
SELECT
|
|
923
|
+
[${primaryKey}],
|
|
924
|
+
[${primaryKey}] AS [${rootFieldName}]
|
|
925
|
+
FROM
|
|
926
|
+
[${schemaName}].[${tableName}]
|
|
927
|
+
WHERE
|
|
928
|
+
[${fieldName}] IS NULL
|
|
929
|
+
|
|
930
|
+
UNION ALL
|
|
931
|
+
|
|
932
|
+
-- Recursive: traverse up the hierarchy
|
|
933
|
+
SELECT
|
|
934
|
+
child.[${primaryKey}],
|
|
935
|
+
parent.[${rootFieldName}]
|
|
936
|
+
FROM
|
|
937
|
+
[${schemaName}].[${tableName}] child
|
|
938
|
+
INNER JOIN
|
|
939
|
+
${cteName} parent ON child.[${fieldName}] = parent.[${primaryKey}]
|
|
940
|
+
)`;
|
|
941
|
+
}).join(',\n');
|
|
942
|
+
return `WITH\n${ctes}\n`;
|
|
943
|
+
}
|
|
944
|
+
/**
|
|
945
|
+
* Generates the SELECT clause additions for root fields
|
|
946
|
+
* Example: , cte_root.[RootParentTaskID]
|
|
947
|
+
*/
|
|
948
|
+
generateRootFieldSelects(recursiveFKs, classNameFirstChar) {
|
|
949
|
+
return recursiveFKs.map(field => {
|
|
950
|
+
const rootFieldName = `Root${field.Name}`;
|
|
951
|
+
const cteName = `CTE_${rootFieldName}`;
|
|
952
|
+
return `,\n ${cteName}.[${rootFieldName}]`;
|
|
953
|
+
}).join('');
|
|
954
|
+
}
|
|
955
|
+
/**
|
|
956
|
+
* Generates LEFT OUTER JOINs to the recursive CTEs
|
|
957
|
+
*/
|
|
958
|
+
generateRecursiveCTEJoins(recursiveFKs, classNameFirstChar, entity) {
|
|
959
|
+
if (recursiveFKs.length === 0) {
|
|
960
|
+
return '';
|
|
961
|
+
}
|
|
962
|
+
const primaryKey = entity.FirstPrimaryKey.Name;
|
|
963
|
+
const joins = recursiveFKs.map(field => {
|
|
964
|
+
const rootFieldName = `Root${field.Name}`;
|
|
965
|
+
const cteName = `CTE_${rootFieldName}`;
|
|
966
|
+
return `LEFT OUTER JOIN\n ${cteName}\n ON\n [${classNameFirstChar}].[${primaryKey}] = ${cteName}.[${primaryKey}]`;
|
|
967
|
+
}).join('\n');
|
|
968
|
+
return '\n' + joins;
|
|
969
|
+
}
|
|
895
970
|
async generateBaseView(pool, entity) {
|
|
896
971
|
const viewName = entity.BaseView ? entity.BaseView : `vw${entity.CodeName}`;
|
|
897
972
|
const classNameFirstChar = entity.ClassName.charAt(0).toLowerCase();
|
|
@@ -901,6 +976,10 @@ CREATE INDEX ${indexName} ON [${entity.SchemaName}].[${entity.BaseTable}] ([${f.
|
|
|
901
976
|
const whereClause = entity.DeleteType === 'Soft' ? `WHERE
|
|
902
977
|
${classNameFirstChar}.[${core_1.EntityInfo.DeletedAtFieldName}] IS NULL
|
|
903
978
|
` : '';
|
|
979
|
+
// Detect recursive foreign keys and generate CTEs
|
|
980
|
+
const recursiveFKs = this.detectRecursiveForeignKeys(entity);
|
|
981
|
+
const cteClause = recursiveFKs.length > 0 ? this.generateRecursiveCTEs(entity, recursiveFKs) : '';
|
|
982
|
+
const rootFields = recursiveFKs.length > 0 ? this.generateRootFieldSelects(recursiveFKs, classNameFirstChar) : '';
|
|
904
983
|
return `
|
|
905
984
|
------------------------------------------------------------
|
|
906
985
|
----- BASE VIEW FOR ENTITY: ${entity.Name}
|
|
@@ -908,15 +987,16 @@ CREATE INDEX ${indexName} ON [${entity.SchemaName}].[${entity.BaseTable}] ([${f.
|
|
|
908
987
|
----- BASE TABLE: ${entity.BaseTable}
|
|
909
988
|
----- PRIMARY KEY: ${entity.PrimaryKeys.map(pk => pk.Name).join(', ')}
|
|
910
989
|
------------------------------------------------------------
|
|
911
|
-
|
|
990
|
+
IF OBJECT_ID('[${entity.SchemaName}].[${viewName}]', 'V') IS NOT NULL
|
|
991
|
+
DROP VIEW [${entity.SchemaName}].[${viewName}];
|
|
912
992
|
GO
|
|
913
993
|
|
|
914
994
|
CREATE VIEW [${entity.SchemaName}].[${viewName}]
|
|
915
995
|
AS
|
|
916
|
-
SELECT
|
|
917
|
-
${classNameFirstChar}.*${relatedFieldsString.length > 0 ? ',' : ''}${relatedFieldsString}
|
|
996
|
+
${cteClause}SELECT
|
|
997
|
+
${classNameFirstChar}.*${relatedFieldsString.length > 0 ? ',' : ''}${relatedFieldsString}${rootFields}
|
|
918
998
|
FROM
|
|
919
|
-
[${entity.SchemaName}].[${entity.BaseTable}] AS ${classNameFirstChar}${relatedFieldsJoinString ? '\n' + relatedFieldsJoinString : ''}
|
|
999
|
+
[${entity.SchemaName}].[${entity.BaseTable}] AS ${classNameFirstChar}${relatedFieldsJoinString ? '\n' + relatedFieldsJoinString : ''}${this.generateRecursiveCTEJoins(recursiveFKs, classNameFirstChar, entity)}
|
|
920
1000
|
${whereClause}GO${permissions}
|
|
921
1001
|
`;
|
|
922
1002
|
}
|
|
@@ -1108,7 +1188,8 @@ ${whereClause}GO${permissions}
|
|
|
1108
1188
|
------------------------------------------------------------
|
|
1109
1189
|
----- CREATE PROCEDURE FOR ${entity.BaseTable}
|
|
1110
1190
|
------------------------------------------------------------
|
|
1111
|
-
|
|
1191
|
+
IF OBJECT_ID('[${entity.SchemaName}].[${spName}]', 'P') IS NOT NULL
|
|
1192
|
+
DROP PROCEDURE [${entity.SchemaName}].[${spName}];
|
|
1112
1193
|
GO
|
|
1113
1194
|
|
|
1114
1195
|
CREATE PROCEDURE [${entity.SchemaName}].[${spName}]
|
|
@@ -1140,7 +1221,8 @@ GO${permissions}
|
|
|
1140
1221
|
------------------------------------------------------------
|
|
1141
1222
|
----- TRIGGER FOR ${core_1.EntityInfo.UpdatedAtFieldName} field for the ${entity.BaseTable} table
|
|
1142
1223
|
------------------------------------------------------------
|
|
1143
|
-
|
|
1224
|
+
IF OBJECT_ID('[${entity.SchemaName}].[trgUpdate${entity.ClassName}]', 'TR') IS NOT NULL
|
|
1225
|
+
DROP TRIGGER [${entity.SchemaName}].[trgUpdate${entity.ClassName}];
|
|
1144
1226
|
GO
|
|
1145
1227
|
CREATE TRIGGER [${entity.SchemaName}].trgUpdate${entity.ClassName}
|
|
1146
1228
|
ON [${entity.SchemaName}].[${entity.BaseTable}]
|
|
@@ -1178,7 +1260,8 @@ GO`;
|
|
|
1178
1260
|
------------------------------------------------------------
|
|
1179
1261
|
----- UPDATE PROCEDURE FOR ${entity.BaseTable}
|
|
1180
1262
|
------------------------------------------------------------
|
|
1181
|
-
|
|
1263
|
+
IF OBJECT_ID('[${entity.SchemaName}].[${spName}]', 'P') IS NOT NULL
|
|
1264
|
+
DROP PROCEDURE [${entity.SchemaName}].[${spName}];
|
|
1182
1265
|
GO
|
|
1183
1266
|
|
|
1184
1267
|
CREATE PROCEDURE [${entity.SchemaName}].[${spName}]
|
|
@@ -1207,7 +1290,52 @@ GO
|
|
|
1207
1290
|
${updatedAtTrigger}
|
|
1208
1291
|
`;
|
|
1209
1292
|
}
|
|
1210
|
-
|
|
1293
|
+
/**
|
|
1294
|
+
* Formats a default value for use in SQL, handling special cases like SQL functions
|
|
1295
|
+
* @param defaultValue The default value from the database metadata
|
|
1296
|
+
* @param needsQuotes Whether the field type typically needs quotes
|
|
1297
|
+
* @returns Properly formatted default value for SQL
|
|
1298
|
+
*/
|
|
1299
|
+
formatDefaultValue(defaultValue, needsQuotes) {
|
|
1300
|
+
if (!defaultValue || defaultValue.trim().length === 0) {
|
|
1301
|
+
return 'NULL';
|
|
1302
|
+
}
|
|
1303
|
+
let trimmedValue = defaultValue.trim();
|
|
1304
|
+
const lowerValue = trimmedValue.toLowerCase();
|
|
1305
|
+
// SQL functions that should not be quoted
|
|
1306
|
+
const sqlFunctions = [
|
|
1307
|
+
'newid()',
|
|
1308
|
+
'newsequentialid()',
|
|
1309
|
+
'getdate()',
|
|
1310
|
+
'getutcdate()',
|
|
1311
|
+
'sysdatetime()',
|
|
1312
|
+
'sysdatetimeoffset()',
|
|
1313
|
+
'current_timestamp',
|
|
1314
|
+
'user_name()',
|
|
1315
|
+
'suser_name()',
|
|
1316
|
+
'system_user'
|
|
1317
|
+
];
|
|
1318
|
+
// Check if this is a SQL function
|
|
1319
|
+
for (const func of sqlFunctions) {
|
|
1320
|
+
if (lowerValue.includes(func)) {
|
|
1321
|
+
// Remove outer parentheses if they exist (e.g., "(getutcdate())" -> "getutcdate()")
|
|
1322
|
+
if (trimmedValue.startsWith('(') && trimmedValue.endsWith(')')) {
|
|
1323
|
+
trimmedValue = trimmedValue.substring(1, trimmedValue.length - 1);
|
|
1324
|
+
}
|
|
1325
|
+
return trimmedValue;
|
|
1326
|
+
}
|
|
1327
|
+
}
|
|
1328
|
+
// If the value already has quotes, remove them first
|
|
1329
|
+
let cleanValue = trimmedValue;
|
|
1330
|
+
if (cleanValue.startsWith("'") && cleanValue.endsWith("'")) {
|
|
1331
|
+
cleanValue = cleanValue.substring(1, cleanValue.length - 1);
|
|
1332
|
+
}
|
|
1333
|
+
// Add quotes if needed
|
|
1334
|
+
if (needsQuotes) {
|
|
1335
|
+
return `'${cleanValue}'`;
|
|
1336
|
+
}
|
|
1337
|
+
return cleanValue;
|
|
1338
|
+
}
|
|
1211
1339
|
createEntityFieldsParamString(entityFields, isUpdate) {
|
|
1212
1340
|
let sOutput = '', isFirst = true;
|
|
1213
1341
|
for (let i = 0; i < entityFields.length; ++i) {
|
|
@@ -1228,6 +1356,11 @@ ${updatedAtTrigger}
|
|
|
1228
1356
|
// This allows callers to omit the PK and let the DB/sproc handle it
|
|
1229
1357
|
defaultParamValue = ' = NULL';
|
|
1230
1358
|
}
|
|
1359
|
+
else if (!isUpdate && ef.HasDefaultValue && !ef.AllowsNull) {
|
|
1360
|
+
// For non-nullable fields with database defaults, make the parameter optional
|
|
1361
|
+
// This allows callers to pass NULL and let the database default be used
|
|
1362
|
+
defaultParamValue = ' = NULL';
|
|
1363
|
+
}
|
|
1231
1364
|
sOutput += `@${ef.CodeName} ${ef.SQLFullType}${defaultParamValue}`;
|
|
1232
1365
|
}
|
|
1233
1366
|
}
|
|
@@ -1238,7 +1371,6 @@ ${updatedAtTrigger}
|
|
|
1238
1371
|
let sOutput = '', isFirst = true;
|
|
1239
1372
|
for (let i = 0; i < entityFields.length; ++i) {
|
|
1240
1373
|
const ef = entityFields[i];
|
|
1241
|
-
const quotes = ef.NeedsQuotes ? "'" : "";
|
|
1242
1374
|
// 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)
|
|
1243
1375
|
// ALSO: if excludePrimaryKey is true, skip all primary key fields
|
|
1244
1376
|
if ((excludePrimaryKey && ef.IsPrimaryKey) || (ef.IsPrimaryKey && autoGeneratedPrimaryKey) || ef.IsVirtual || !ef.AllowUpdateAPI || ef.AutoIncrement) {
|
|
@@ -1254,32 +1386,35 @@ ${updatedAtTrigger}
|
|
|
1254
1386
|
else
|
|
1255
1387
|
sOutput += `NULL`; // we don't set the deleted at field on an insert, only on a delete
|
|
1256
1388
|
}
|
|
1257
|
-
else if ((prefix && prefix !== '') && !ef.IsPrimaryKey && ef.IsUniqueIdentifier && ef.HasDefaultValue) {
|
|
1258
|
-
// this is the VALUE side (prefix not null/blank), is NOT a primary key, and is a uniqueidentifier column
|
|
1259
|
-
//
|
|
1260
|
-
//
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
let defValue = ef.DefaultValue;
|
|
1264
|
-
if (ef.TSType === core_1.EntityFieldTSType.String) {
|
|
1265
|
-
if (defValue.startsWith("'") && defValue.endsWith("'")) {
|
|
1266
|
-
defValue = defValue.substring(1, defValue.length - 1).trim(); // remove the quotes
|
|
1267
|
-
}
|
|
1268
|
-
}
|
|
1269
|
-
const defValueLowered = defValue.toLowerCase().trim();
|
|
1270
|
-
//If the default value is NEWID or NEWSEQUENTIALID, we will use the default value as is, without quotes.
|
|
1271
|
-
//Otherwise, wrap the default value with the quotes variable value.
|
|
1272
|
-
if (!defValueLowered.includes('newid()') && !defValueLowered.includes('newsequentialid()')) {
|
|
1273
|
-
defValue = `${quotes}${defValue}${quotes}`;
|
|
1274
|
-
}
|
|
1275
|
-
sOutput += `CASE @${ef.CodeName} WHEN '${this.__specialUUIDValue}' THEN ${defValue} ELSE @${ef.CodeName} END`;
|
|
1389
|
+
else if ((prefix && prefix !== '') && !ef.IsPrimaryKey && ef.IsUniqueIdentifier && ef.HasDefaultValue && !ef.AllowsNull) {
|
|
1390
|
+
// this is the VALUE side (prefix not null/blank), is NOT a primary key, and is a uniqueidentifier column with a default value and does NOT allow NULL
|
|
1391
|
+
// We need to handle both NULL and the special value '00000000-0000-0000-0000-000000000000' for backward compatibility
|
|
1392
|
+
// Existing code uses the special value to indicate "use the default", so we preserve that behavior
|
|
1393
|
+
const formattedDefault = this.formatDefaultValue(ef.DefaultValue, ef.NeedsQuotes);
|
|
1394
|
+
sOutput += `CASE @${ef.CodeName} WHEN '00000000-0000-0000-0000-000000000000' THEN ${formattedDefault} ELSE ISNULL(@${ef.CodeName}, ${formattedDefault}) END`;
|
|
1276
1395
|
}
|
|
1277
1396
|
else {
|
|
1278
1397
|
let sVal = '';
|
|
1279
|
-
if (!prefix || prefix.length === 0)
|
|
1398
|
+
if (!prefix || prefix.length === 0) {
|
|
1399
|
+
// Column name side
|
|
1280
1400
|
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
|
|
1281
|
-
|
|
1401
|
+
}
|
|
1402
|
+
else {
|
|
1403
|
+
// Value/parameter side
|
|
1282
1404
|
sVal = prefix + ef.CodeName;
|
|
1405
|
+
// If this field has a default value and doesn't allow NULL, wrap with ISNULL
|
|
1406
|
+
// For UniqueIdentifier fields, also handle the special value '00000000-0000-0000-0000-000000000000' for backward compatibility
|
|
1407
|
+
if (ef.HasDefaultValue && !ef.AllowsNull) {
|
|
1408
|
+
const formattedDefault = this.formatDefaultValue(ef.DefaultValue, ef.NeedsQuotes);
|
|
1409
|
+
if (ef.IsUniqueIdentifier) {
|
|
1410
|
+
// Handle both NULL and the special UUID value for backward compatibility with existing code
|
|
1411
|
+
sVal = `CASE ${sVal} WHEN '00000000-0000-0000-0000-000000000000' THEN ${formattedDefault} ELSE ISNULL(${sVal}, ${formattedDefault}) END`;
|
|
1412
|
+
}
|
|
1413
|
+
else {
|
|
1414
|
+
sVal = `ISNULL(${sVal}, ${formattedDefault})`;
|
|
1415
|
+
}
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1283
1418
|
sOutput += sVal;
|
|
1284
1419
|
}
|
|
1285
1420
|
}
|
|
@@ -1345,7 +1480,8 @@ ${deleteCode} AND ${core_1.EntityInfo.DeletedAtFieldName} IS NULL -- don'
|
|
|
1345
1480
|
------------------------------------------------------------
|
|
1346
1481
|
----- DELETE PROCEDURE FOR ${entity.BaseTable}
|
|
1347
1482
|
------------------------------------------------------------
|
|
1348
|
-
|
|
1483
|
+
IF OBJECT_ID('[${entity.SchemaName}].[${spName}]', 'P') IS NOT NULL
|
|
1484
|
+
DROP PROCEDURE [${entity.SchemaName}].[${spName}];
|
|
1349
1485
|
GO
|
|
1350
1486
|
|
|
1351
1487
|
CREATE PROCEDURE [${entity.SchemaName}].[${spName}]
|