SqlQueryManager ve ListFormWizard düzenlemeleri
This commit is contained in:
parent
f3a922a5a8
commit
7bb154c936
6 changed files with 190 additions and 113 deletions
|
|
@ -28,10 +28,7 @@ public class ListFormWizardAppService(
|
||||||
IRepository<PermissionDefinitionRecord, Guid> repoPerm,
|
IRepository<PermissionDefinitionRecord, Guid> repoPerm,
|
||||||
IRepository<PermissionGroupDefinitionRecord, Guid> repoPermGroup,
|
IRepository<PermissionGroupDefinitionRecord, Guid> repoPermGroup,
|
||||||
IRepository<Menu, Guid> repoMenu,
|
IRepository<Menu, Guid> repoMenu,
|
||||||
IIdentityRoleRepository roleRepository,
|
|
||||||
IIdentityUserRepository userRepository,
|
|
||||||
IPermissionGrantRepository permissionGrantRepository,
|
IPermissionGrantRepository permissionGrantRepository,
|
||||||
ILookupNormalizer LookupNormalizer,
|
|
||||||
IConfiguration configuration,
|
IConfiguration configuration,
|
||||||
LanguageTextAppService languageTextAppService
|
LanguageTextAppService languageTextAppService
|
||||||
) : PlatformAppService(), IListFormWizardAppService
|
) : PlatformAppService(), IListFormWizardAppService
|
||||||
|
|
@ -44,10 +41,7 @@ public class ListFormWizardAppService(
|
||||||
private readonly IRepository<PermissionDefinitionRecord, Guid> repoPerm = repoPerm;
|
private readonly IRepository<PermissionDefinitionRecord, Guid> repoPerm = repoPerm;
|
||||||
private readonly IRepository<PermissionGroupDefinitionRecord, Guid> repoPermGroup = repoPermGroup;
|
private readonly IRepository<PermissionGroupDefinitionRecord, Guid> repoPermGroup = repoPermGroup;
|
||||||
private readonly IRepository<Menu, Guid> repoMenu = repoMenu;
|
private readonly IRepository<Menu, Guid> repoMenu = repoMenu;
|
||||||
private readonly IIdentityRoleRepository roleRepository = roleRepository;
|
|
||||||
private readonly IIdentityUserRepository userRepository = userRepository;
|
|
||||||
private readonly IPermissionGrantRepository permissionGrantRepository = permissionGrantRepository;
|
private readonly IPermissionGrantRepository permissionGrantRepository = permissionGrantRepository;
|
||||||
private readonly ILookupNormalizer lookupNormalizer = LookupNormalizer;
|
|
||||||
private readonly IConfiguration _configuration = configuration;
|
private readonly IConfiguration _configuration = configuration;
|
||||||
private readonly LanguageTextAppService _languageTextAppService = languageTextAppService;
|
private readonly LanguageTextAppService _languageTextAppService = languageTextAppService;
|
||||||
private readonly string cultureNameDefault = PlatformConsts.DefaultLanguage;
|
private readonly string cultureNameDefault = PlatformConsts.DefaultLanguage;
|
||||||
|
|
@ -101,21 +95,23 @@ public class ListFormWizardAppService(
|
||||||
var permNote = existingPerms.FirstOrDefault(a => a.Name == WizardConsts.PermNote(wizardName)) ??
|
var permNote = existingPerms.FirstOrDefault(a => a.Name == WizardConsts.PermNote(wizardName)) ??
|
||||||
await repoPerm.InsertAsync(new PermissionDefinitionRecord(Guid.NewGuid(), groupName, WizardConsts.PermNote(wizardName), permRead.Name, WizardConsts.LangKeyNote, true, MultiTenancySides.Both), autoSave: false);
|
await repoPerm.InsertAsync(new PermissionDefinitionRecord(Guid.NewGuid(), groupName, WizardConsts.PermNote(wizardName), permRead.Name, WizardConsts.LangKeyNote, true, MultiTenancySides.Both), autoSave: false);
|
||||||
|
|
||||||
// Permission Grants - Bulk Insert
|
// Permission Grants - Bulk Insert (only missing ones)
|
||||||
var adminUserName = PlatformConsts.AbpIdentity.User.AdminEmailDefaultValue;
|
var existingGrants = await permissionGrantRepository.GetListAsync("R", PlatformConsts.AbpIdentity.User.AdminRoleName);
|
||||||
var adminUser = await userRepository.FindByNormalizedUserNameAsync(lookupNormalizer.NormalizeName(adminUserName));
|
var existingGrantNames = existingGrants.Select(g => g.Name).ToHashSet();
|
||||||
var adminRole = await roleRepository.FindByNormalizedNameAsync(lookupNormalizer.NormalizeName(PlatformConsts.AbpIdentity.User.AdminRoleName));
|
|
||||||
|
|
||||||
await permissionGrantRepository.InsertManyAsync(
|
var grantsToInsert = new[]
|
||||||
[
|
{
|
||||||
new PermissionGrant(Guid.NewGuid(), permRead.Name, "R", PlatformConsts.AbpIdentity.User.AdminRoleName),
|
permRead.Name, permCreate.Name, permUpdate.Name,
|
||||||
new PermissionGrant(Guid.NewGuid(), permCreate.Name, "R", PlatformConsts.AbpIdentity.User.AdminRoleName),
|
permDelete.Name, permExport.Name, permImport.Name, permNote.Name
|
||||||
new PermissionGrant(Guid.NewGuid(), permUpdate.Name, "R", PlatformConsts.AbpIdentity.User.AdminRoleName),
|
}
|
||||||
new PermissionGrant(Guid.NewGuid(), permDelete.Name, "R", PlatformConsts.AbpIdentity.User.AdminRoleName),
|
.Where(name => !existingGrantNames.Contains(name))
|
||||||
new PermissionGrant(Guid.NewGuid(), permExport.Name, "R", PlatformConsts.AbpIdentity.User.AdminRoleName),
|
.Select(name => new PermissionGrant(Guid.NewGuid(), name, "R", PlatformConsts.AbpIdentity.User.AdminRoleName))
|
||||||
new PermissionGrant(Guid.NewGuid(), permImport.Name, "R", PlatformConsts.AbpIdentity.User.AdminRoleName),
|
.ToList();
|
||||||
new PermissionGrant(Guid.NewGuid(), permNote.Name, "R", PlatformConsts.AbpIdentity.User.AdminRoleName),
|
|
||||||
], autoSave: false);
|
if (grantsToInsert.Count > 0)
|
||||||
|
{
|
||||||
|
await permissionGrantRepository.InsertManyAsync(grantsToInsert, autoSave: false);
|
||||||
|
}
|
||||||
|
|
||||||
//Menu Parent
|
//Menu Parent
|
||||||
var menuQueryable = await repoMenu.GetQueryableAsync();
|
var menuQueryable = await repoMenu.GetQueryableAsync();
|
||||||
|
|
@ -185,44 +181,68 @@ public class ListFormWizardAppService(
|
||||||
})
|
})
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
//ListForm
|
//ListForm - varsa sil, yeniden ekle
|
||||||
var listForm = await repoListForm.InsertAsync(new ListForm
|
var listFormQueryable = await repoListForm.GetQueryableAsync();
|
||||||
|
var existingListForm = await AsyncExecuter.FirstOrDefaultAsync(listFormQueryable.Where(a => a.ListFormCode == input.ListFormCode));
|
||||||
|
|
||||||
|
var listFormFieldQueryable = await repoListFormField.GetQueryableAsync();
|
||||||
|
var existingListFormFields = await AsyncExecuter.ToListAsync(
|
||||||
|
listFormFieldQueryable.Where(a => a.ListFormCode == input.ListFormCode));
|
||||||
|
if (existingListFormFields.Count > 0)
|
||||||
{
|
{
|
||||||
ListFormType = ListFormTypeEnum.List,
|
await repoListFormField.DeleteManyAsync(existingListFormFields, autoSave: true);
|
||||||
PageSize = 10,
|
}
|
||||||
ExportJson = WizardConsts.DefaultExportJson,
|
|
||||||
IsSubForm = false,
|
void ApplyListFormValues(ListForm lf)
|
||||||
ShowNote = true,
|
{
|
||||||
LayoutJson = WizardConsts.DefaultLayoutJson(),
|
lf.ListFormType = ListFormTypeEnum.List;
|
||||||
CultureName = LanguageCodes.En,
|
lf.PageSize = 10;
|
||||||
ListFormCode = input.ListFormCode,
|
lf.ExportJson = WizardConsts.DefaultExportJson;
|
||||||
Name = nameLangKey,
|
lf.IsSubForm = false;
|
||||||
Title = titleLangKey,
|
lf.ShowNote = true;
|
||||||
Description = descLangKey,
|
lf.LayoutJson = WizardConsts.DefaultLayoutJson();
|
||||||
DataSourceCode = input.DataSourceCode,
|
lf.CultureName = LanguageCodes.En;
|
||||||
IsTenant = input.IsTenant,
|
lf.ListFormCode = input.ListFormCode;
|
||||||
IsBranch = input.IsBranch,
|
lf.Name = nameLangKey;
|
||||||
IsOrganizationUnit = input.IsOrganizationUnit,
|
lf.Title = titleLangKey;
|
||||||
SelectCommandType = input.SelectCommandType,
|
lf.Description = descLangKey;
|
||||||
SelectCommand = input.SelectCommand,
|
lf.DataSourceCode = input.DataSourceCode;
|
||||||
KeyFieldName = input.KeyFieldName,
|
lf.IsTenant = input.IsTenant;
|
||||||
KeyFieldDbSourceType = input.KeyFieldDbSourceType,
|
lf.IsBranch = input.IsBranch;
|
||||||
DefaultFilter = WizardConsts.DefaultFilterJson,
|
lf.IsOrganizationUnit = input.IsOrganizationUnit;
|
||||||
SortMode = GridOptions.SortModeSingle,
|
lf.SelectCommandType = input.SelectCommandType;
|
||||||
FilterRowJson = WizardConsts.DefaultFilterRowJson,
|
lf.SelectCommand = input.SelectCommand;
|
||||||
HeaderFilterJson = WizardConsts.DefaultHeaderFilterJson,
|
lf.KeyFieldName = input.KeyFieldName;
|
||||||
SearchPanelJson = WizardConsts.DefaultSearchPanelJson,
|
lf.KeyFieldDbSourceType = input.KeyFieldDbSourceType;
|
||||||
GroupPanelJson = JsonSerializer.Serialize(new { Visible = false }),
|
lf.DefaultFilter = WizardConsts.DefaultFilterJson;
|
||||||
SelectionJson = WizardConsts.DefaultSelectionSingleJson,
|
lf.SortMode = GridOptions.SortModeSingle;
|
||||||
ColumnOptionJson = WizardConsts.DefaultColumnOptionJson(),
|
lf.FilterRowJson = WizardConsts.DefaultFilterRowJson;
|
||||||
PermissionJson = WizardConsts.DefaultPermissionJson(code),
|
lf.HeaderFilterJson = WizardConsts.DefaultHeaderFilterJson;
|
||||||
DeleteCommand = WizardConsts.DefaultDeleteCommand(input.SelectCommand),
|
lf.SearchPanelJson = WizardConsts.DefaultSearchPanelJson;
|
||||||
DeleteFieldsDefaultValueJson = WizardConsts.DefaultDeleteFieldsDefaultValueJson(input.KeyFieldDbSourceType),
|
lf.GroupPanelJson = JsonSerializer.Serialize(new { Visible = false });
|
||||||
InsertFieldsDefaultValueJson = WizardConsts.DefaultInsertFieldsDefaultValueJson(input.KeyFieldDbSourceType),
|
lf.SelectionJson = WizardConsts.DefaultSelectionSingleJson;
|
||||||
PagerOptionJson = WizardConsts.DefaultPagerOptionJson,
|
lf.ColumnOptionJson = WizardConsts.DefaultColumnOptionJson();
|
||||||
EditingOptionJson = WizardConsts.DefaultEditingOptionJson(titleLangKey, 600, 500, input.AllowDeleting, input.AllowAdding, input.AllowUpdating, input.ConfirmDelete, false, input.AllowDetail),
|
lf.PermissionJson = WizardConsts.DefaultPermissionJson(code);
|
||||||
EditingFormJson = editingFormDtos.Count > 0 ? JsonSerializer.Serialize(editingFormDtos) : null,
|
lf.DeleteCommand = WizardConsts.DefaultDeleteCommand(input.SelectCommand);
|
||||||
}, autoSave: true);
|
lf.DeleteFieldsDefaultValueJson = WizardConsts.DefaultDeleteFieldsDefaultValueJson(input.KeyFieldDbSourceType);
|
||||||
|
lf.InsertFieldsDefaultValueJson = WizardConsts.DefaultInsertFieldsDefaultValueJson(input.KeyFieldDbSourceType);
|
||||||
|
lf.PagerOptionJson = WizardConsts.DefaultPagerOptionJson;
|
||||||
|
lf.EditingOptionJson = WizardConsts.DefaultEditingOptionJson(titleLangKey, 600, 500, input.AllowDeleting, input.AllowAdding, input.AllowUpdating, input.ConfirmDelete, false, input.AllowDetail);
|
||||||
|
lf.EditingFormJson = editingFormDtos.Count > 0 ? JsonSerializer.Serialize(editingFormDtos) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
ListForm listForm;
|
||||||
|
if (existingListForm != null)
|
||||||
|
{
|
||||||
|
ApplyListFormValues(existingListForm);
|
||||||
|
listForm = await repoListForm.UpdateAsync(existingListForm, autoSave: true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var newListForm = new ListForm();
|
||||||
|
ApplyListFormValues(newListForm);
|
||||||
|
listForm = await repoListForm.InsertAsync(newListForm, autoSave: true);
|
||||||
|
}
|
||||||
|
|
||||||
// ListFormField - each item in each group becomes a visible field record
|
// ListFormField - each item in each group becomes a visible field record
|
||||||
var fieldOrder = 0;
|
var fieldOrder = 0;
|
||||||
|
|
|
||||||
|
|
@ -203,6 +203,11 @@ public class ListFormSeeder_Administration : IDataSeedContributor, ITransientDep
|
||||||
HeaderFilterJson = DefaultHeaderFilterJson,
|
HeaderFilterJson = DefaultHeaderFilterJson,
|
||||||
SearchPanelJson = DefaultSearchPanelJson,
|
SearchPanelJson = DefaultSearchPanelJson,
|
||||||
GroupPanelJson = DefaultGroupPanelJson,
|
GroupPanelJson = DefaultGroupPanelJson,
|
||||||
|
SelectionJson = JsonSerializer.Serialize(new SelectionDto
|
||||||
|
{
|
||||||
|
Mode = GridOptions.SelectionAllModeAllPages,
|
||||||
|
AllowSelectAll = true
|
||||||
|
}),
|
||||||
ColumnOptionJson = DefaultColumnOptionJson(),
|
ColumnOptionJson = DefaultColumnOptionJson(),
|
||||||
PermissionJson = DefaultPermissionJson(AbpIdentity.Permissions.Create, listFormName, AbpIdentity.Permissions.Update, AbpIdentity.Permissions.Delete, AbpIdentity.Permissions.Export, AbpIdentity.Permissions.Import, AbpIdentity.Permissions.Note),
|
PermissionJson = DefaultPermissionJson(AbpIdentity.Permissions.Create, listFormName, AbpIdentity.Permissions.Update, AbpIdentity.Permissions.Delete, AbpIdentity.Permissions.Export, AbpIdentity.Permissions.Import, AbpIdentity.Permissions.Note),
|
||||||
PagerOptionJson = DefaultPagerOptionJson,
|
PagerOptionJson = DefaultPagerOptionJson,
|
||||||
|
|
|
||||||
|
|
@ -49,4 +49,28 @@ WITH INIT;'
|
||||||
|
|
||||||
EXEC sp_executesql @SQL;
|
EXEC sp_executesql @SQL;
|
||||||
END
|
END
|
||||||
GO
|
GO
|
||||||
|
|
||||||
|
IF OBJECT_ID(N'[dbo].[Adm_T_Deparment]', 'U') IS NULL
|
||||||
|
BEGIN
|
||||||
|
CREATE TABLE [dbo].[Adm_T_Deparment]
|
||||||
|
(
|
||||||
|
[Id] uniqueidentifier NOT NULL DEFAULT NEWID(),
|
||||||
|
[CreationTime] datetime2 NOT NULL DEFAULT GETUTCDATE(),
|
||||||
|
[CreatorId] uniqueidentifier NULL,
|
||||||
|
[LastModificationTime] datetime2 NULL,
|
||||||
|
[LastModifierId] uniqueidentifier NULL,
|
||||||
|
[IsDeleted] bit NOT NULL DEFAULT 0,
|
||||||
|
[DeletionTime] datetime2 NULL,
|
||||||
|
[DeleterId] uniqueidentifier NULL,
|
||||||
|
[TenantId] uniqueidentifier NULL,
|
||||||
|
[BranchId] uniqueidentifier NOT NULL,
|
||||||
|
[Name] nvarchar(64) NOT NULL,
|
||||||
|
[ParentId] uniqueidentifier NULL,
|
||||||
|
CONSTRAINT [PK_Adm_T_Deparment] PRIMARY KEY CLUSTERED
|
||||||
|
(
|
||||||
|
[Id] ASC
|
||||||
|
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
|
||||||
|
) ON [PRIMARY]
|
||||||
|
END
|
||||||
|
GO
|
||||||
|
|
|
||||||
|
|
@ -166,6 +166,10 @@ const Wizard = () => {
|
||||||
const selectableColumns = cols.filter((c) => !isAuditColumn(c.columnName))
|
const selectableColumns = cols.filter((c) => !isAuditColumn(c.columnName))
|
||||||
setSelectedColumns(new Set(selectableColumns.map((c) => c.columnName)))
|
setSelectedColumns(new Set(selectableColumns.map((c) => c.columnName)))
|
||||||
setEditingGroups([])
|
setEditingGroups([])
|
||||||
|
// Auto-check isTenant / isBranch based on column presence
|
||||||
|
const colNames = new Set(cols.map((c) => c.columnName.toLowerCase()))
|
||||||
|
formikRef.current?.setFieldValue('isTenant', colNames.has('tenantid'))
|
||||||
|
formikRef.current?.setFieldValue('isBranch', colNames.has('branchid'))
|
||||||
// Auto-select first column as key field
|
// Auto-select first column as key field
|
||||||
if (cols.length > 0) {
|
if (cols.length > 0) {
|
||||||
const first = cols[0]
|
const first = cols[0]
|
||||||
|
|
|
||||||
|
|
@ -155,7 +155,7 @@ END;
|
||||||
(
|
(
|
||||||
SELECT
|
SELECT
|
||||||
c.column_id,
|
c.column_id,
|
||||||
' ' + QUOTENAME(c.name) + ' ' +
|
' ' + QUOTENAME(c.name) + ' ' +
|
||||||
CASE
|
CASE
|
||||||
WHEN t.name IN ('varchar', 'char', 'varbinary', 'binary') THEN
|
WHEN t.name IN ('varchar', 'char', 'varbinary', 'binary') THEN
|
||||||
t.name + '(' + CASE WHEN c.max_length = -1 THEN 'MAX' ELSE CAST(c.max_length AS VARCHAR(10)) END + ')'
|
t.name + '(' + CASE WHEN c.max_length = -1 THEN 'MAX' ELSE CAST(c.max_length AS VARCHAR(10)) END + ')'
|
||||||
|
|
@ -183,29 +183,30 @@ END;
|
||||||
pk AS
|
pk AS
|
||||||
(
|
(
|
||||||
SELECT
|
SELECT
|
||||||
' CONSTRAINT ' + QUOTENAME(k.name) + ' PRIMARY KEY ' +
|
' CONSTRAINT ' + QUOTENAME(k.name) + ' PRIMARY KEY ' +
|
||||||
CASE WHEN i.type = 1 THEN 'CLUSTERED' ELSE 'NONCLUSTERED' END +
|
CASE WHEN i.type = 1 THEN 'CLUSTERED' ELSE 'NONCLUSTERED' END +
|
||||||
' (' +
|
CHAR(13) + CHAR(10) + ' (' + CHAR(13) + CHAR(10) +
|
||||||
STUFF(
|
(
|
||||||
(
|
SELECT ' ' + QUOTENAME(c.name) + CASE WHEN ic.is_descending_key = 1 THEN ' DESC' ELSE ' ASC' END + CHAR(13) + CHAR(10)
|
||||||
SELECT ', ' + QUOTENAME(c.name) + CASE WHEN ic.is_descending_key = 1 THEN ' DESC' ELSE ' ASC' END
|
FROM sys.index_columns ic
|
||||||
FROM sys.index_columns ic
|
INNER JOIN sys.columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_id
|
||||||
INNER JOIN sys.columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_id
|
WHERE ic.object_id = i.object_id
|
||||||
WHERE ic.object_id = i.object_id
|
AND ic.index_id = i.index_id
|
||||||
AND ic.index_id = i.index_id
|
AND ic.is_included_column = 0
|
||||||
AND ic.is_included_column = 0
|
ORDER BY ic.key_ordinal
|
||||||
ORDER BY ic.key_ordinal
|
FOR XML PATH(''), TYPE
|
||||||
FOR XML PATH(''), TYPE
|
).value('.', 'NVARCHAR(MAX)') +
|
||||||
).value('.', 'NVARCHAR(MAX)')
|
' )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]' AS line
|
||||||
,1,2,'') + ')' AS line
|
|
||||||
FROM sys.key_constraints k
|
FROM sys.key_constraints k
|
||||||
INNER JOIN sys.indexes i ON k.parent_object_id = i.object_id AND k.unique_index_id = i.index_id
|
INNER JOIN sys.indexes i ON k.parent_object_id = i.object_id AND k.unique_index_id = i.index_id
|
||||||
WHERE k.parent_object_id = @ObjectId
|
WHERE k.parent_object_id = @ObjectId
|
||||||
AND k.type = 'PK'
|
AND k.type = 'PK'
|
||||||
)
|
)
|
||||||
SELECT
|
SELECT
|
||||||
'CREATE TABLE ${fullName}' + CHAR(13) + CHAR(10) +
|
'IF OBJECT_ID(N''${escapedFullName}'', ''U'') IS NULL' + CHAR(13) + CHAR(10) +
|
||||||
'(' + CHAR(13) + CHAR(10) +
|
'BEGIN' + CHAR(13) + CHAR(10) +
|
||||||
|
' CREATE TABLE ${fullName}' + CHAR(13) + CHAR(10) +
|
||||||
|
' (' + CHAR(13) + CHAR(10) +
|
||||||
STUFF(
|
STUFF(
|
||||||
(
|
(
|
||||||
SELECT ',' + CHAR(13) + CHAR(10) + line
|
SELECT ',' + CHAR(13) + CHAR(10) + line
|
||||||
|
|
@ -220,7 +221,7 @@ SELECT
|
||||||
FROM pk
|
FROM pk
|
||||||
),
|
),
|
||||||
''
|
''
|
||||||
) + CHAR(13) + CHAR(10) + ');' AS Script;`
|
) + CHAR(13) + CHAR(10) + ' ) ON [PRIMARY]' + CHAR(13) + CHAR(10) + 'END' + CHAR(13) + CHAR(10) + 'GO' AS Script;`
|
||||||
}
|
}
|
||||||
|
|
||||||
const getTableCreateScript = async (schemaName: string, tableName: string): Promise<string> => {
|
const getTableCreateScript = async (schemaName: string, tableName: string): Promise<string> => {
|
||||||
|
|
|
||||||
|
|
@ -245,7 +245,7 @@ function colToSqlLine(col: ColumnDefinition, addComma = true): string {
|
||||||
}
|
}
|
||||||
const nullPart = col.isNullable ? 'NULL' : 'NOT NULL'
|
const nullPart = col.isNullable ? 'NULL' : 'NOT NULL'
|
||||||
const defaultPart = col.defaultValue ? ` DEFAULT ${col.defaultValue}` : ''
|
const defaultPart = col.defaultValue ? ` DEFAULT ${col.defaultValue}` : ''
|
||||||
return ` [${col.columnName}] ${typeSql} ${nullPart}${defaultPart}${addComma ? ',' : ''}`
|
return ` [${col.columnName}] ${typeSql} ${nullPart}${defaultPart}${addComma ? ',' : ''}`
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateCreateTableSql(
|
function generateCreateTableSql(
|
||||||
|
|
@ -256,10 +256,57 @@ function generateCreateTableSql(
|
||||||
): string {
|
): string {
|
||||||
const tableName = settings.tableName || 'NewTable'
|
const tableName = settings.tableName || 'NewTable'
|
||||||
const fullTableName = `[dbo].[${tableName}]`
|
const fullTableName = `[dbo].[${tableName}]`
|
||||||
|
const escapedFullTableName = fullTableName.replace(/'/g, "''")
|
||||||
|
|
||||||
const userCols = columns.filter((c) => c.columnName.trim())
|
const userCols = columns.filter((c) => c.columnName.trim())
|
||||||
const allBodyCols = userCols
|
const bodyLines = userCols.map((c) => colToSqlLine(c, false))
|
||||||
const bodyLines = allBodyCols.map((c, i) => colToSqlLine(c, i < allBodyCols.length - 1))
|
|
||||||
|
// Inline PRIMARY KEY constraint inside CREATE TABLE
|
||||||
|
const pkIndex = indexes.find((idx) => idx.indexType === 'PrimaryKey' && idx.columns.length > 0)
|
||||||
|
const pkConstraintLines: string[] = []
|
||||||
|
if (pkIndex) {
|
||||||
|
const clustered = pkIndex.isClustered ? 'CLUSTERED' : 'NONCLUSTERED'
|
||||||
|
const colsSql = pkIndex.columns.map((c) => ` [${c.columnName}] ${c.order}`).join(',\n')
|
||||||
|
pkConstraintLines.push(
|
||||||
|
` CONSTRAINT [${pkIndex.indexName}] PRIMARY KEY ${clustered}`,
|
||||||
|
` (`,
|
||||||
|
colsSql,
|
||||||
|
` )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]`,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build all column + pk lines with commas
|
||||||
|
const allInnerLines: string[] = []
|
||||||
|
for (let i = 0; i < bodyLines.length; i++) {
|
||||||
|
allInnerLines.push(bodyLines[i] + ',')
|
||||||
|
}
|
||||||
|
if (pkConstraintLines.length > 0) {
|
||||||
|
for (let i = 0; i < pkConstraintLines.length; i++) {
|
||||||
|
allInnerLines.push(pkConstraintLines[i])
|
||||||
|
}
|
||||||
|
} else if (allInnerLines.length > 0) {
|
||||||
|
// Remove trailing comma from last column if no PK
|
||||||
|
allInnerLines[allInnerLines.length - 1] = allInnerLines[allInnerLines.length - 1].replace(/,$/, '')
|
||||||
|
}
|
||||||
|
|
||||||
|
// Non-PK index lines (UNIQUE, regular INDEX) — outside CREATE TABLE
|
||||||
|
const extraIndexLines: string[] = []
|
||||||
|
for (const idx of indexes) {
|
||||||
|
if (idx.columns.length === 0 || idx.indexType === 'PrimaryKey') continue
|
||||||
|
const clustered = idx.isClustered ? 'CLUSTERED' : 'NONCLUSTERED'
|
||||||
|
const colsSql = idx.columns.map((c) => `[${c.columnName}] ${c.order}`).join(', ')
|
||||||
|
extraIndexLines.push('')
|
||||||
|
if (idx.indexType === 'UniqueKey') {
|
||||||
|
extraIndexLines.push(`-- 🔒 Unique Key: [${idx.indexName}]`)
|
||||||
|
extraIndexLines.push(`ALTER TABLE ${fullTableName}`)
|
||||||
|
extraIndexLines.push(` ADD CONSTRAINT [${idx.indexName}] UNIQUE ${clustered} (${colsSql});`)
|
||||||
|
} else {
|
||||||
|
extraIndexLines.push(`-- 📋 Index: [${idx.indexName}]`)
|
||||||
|
extraIndexLines.push(
|
||||||
|
`CREATE ${idx.isClustered ? 'CLUSTERED ' : ''}INDEX [${idx.indexName}] ON ${fullTableName} (${colsSql});`,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// FK constraint lines
|
// FK constraint lines
|
||||||
const fkLines: string[] = []
|
const fkLines: string[] = []
|
||||||
|
|
@ -291,42 +338,18 @@ function generateCreateTableSql(
|
||||||
fkLines.push(` ON UPDATE ${cascadeUpdate};`)
|
fkLines.push(` ON UPDATE ${cascadeUpdate};`)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Index / Key SQL lines
|
|
||||||
const indexLines: string[] = []
|
|
||||||
for (const idx of indexes) {
|
|
||||||
if (idx.columns.length === 0) continue
|
|
||||||
const clustered = idx.isClustered ? 'CLUSTERED' : 'NONCLUSTERED'
|
|
||||||
const colsSql = idx.columns.map((c) => `[${c.columnName}] ${c.order}`).join(', ')
|
|
||||||
indexLines.push('')
|
|
||||||
if (idx.indexType === 'PrimaryKey') {
|
|
||||||
indexLines.push(`-- 🔑 Primary Key: [${idx.indexName}]`)
|
|
||||||
indexLines.push(`ALTER TABLE ${fullTableName}`)
|
|
||||||
indexLines.push(` ADD CONSTRAINT [${idx.indexName}] PRIMARY KEY ${clustered} (${colsSql});`)
|
|
||||||
} else if (idx.indexType === 'UniqueKey') {
|
|
||||||
indexLines.push(`-- 🔒 Unique Key: [${idx.indexName}]`)
|
|
||||||
indexLines.push(`ALTER TABLE ${fullTableName}`)
|
|
||||||
indexLines.push(` ADD CONSTRAINT [${idx.indexName}] UNIQUE ${clustered} (${colsSql});`)
|
|
||||||
} else {
|
|
||||||
indexLines.push(`-- 📋 Index: [${idx.indexName}]`)
|
|
||||||
indexLines.push(
|
|
||||||
`CREATE ${idx.isClustered ? 'CLUSTERED ' : ''}INDEX [${idx.indexName}] ON ${fullTableName} (${colsSql});`,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const lines: string[] = [
|
const lines: string[] = [
|
||||||
`/* ── Table: ${fullTableName} ── */`,
|
`IF OBJECT_ID(N'${escapedFullTableName}', 'U') IS NULL`,
|
||||||
...(settings.entityName ? [`/* Entity Name: ${settings.entityName} */`] : []),
|
`BEGIN`,
|
||||||
'',
|
` CREATE TABLE ${fullTableName}`,
|
||||||
`CREATE TABLE ${fullTableName}`,
|
` (`,
|
||||||
`(`,
|
...allInnerLines,
|
||||||
...bodyLines,
|
` ) ON [PRIMARY]`,
|
||||||
`);`,
|
`END`,
|
||||||
...indexLines,
|
`GO`,
|
||||||
...(fkLines.length > 0 ? ['/* Foreign Key Constraints */'] : []),
|
...extraIndexLines,
|
||||||
|
...(fkLines.length > 0 ? ['', '/* Foreign Key Constraints */'] : []),
|
||||||
...fkLines,
|
...fkLines,
|
||||||
'',
|
|
||||||
`/* Verify: SELECT TOP 10 * FROM ${fullTableName}; */`,
|
|
||||||
]
|
]
|
||||||
|
|
||||||
return lines.join('\n')
|
return lines.join('\n')
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue