mirror of
https://github.com/t8y2/dbx.git
synced 2026-10-30 00:19:35 +00:00
feat: add index type, included columns, filter, and comment support
- Add filter, index_type, included_columns, and comment fields to IndexInfo - PostgreSQL: query pg_am for index type, use indnkeyatts to split key/included columns, retrieve index comments via obj_description() - SQL Server: add type_desc, filter_definition, included columns via is_included_column - MySQL: add INDEX_TYPE from information_schema.STATISTICS - Oracle: add INDEX_TYPE from ALL_INDEXES - DDL generation: add USING (PostgreSQL), type prefix + INCLUDE + WHERE (SQL Server), COMMENT ON INDEX (PostgreSQL) - Frontend: update types, state mapping, SQL generation, and i18n translations
This commit is contained in:
@@ -335,7 +335,12 @@ export default {
|
||||
actions: "Actions",
|
||||
indexName: "Index",
|
||||
indexColumns: "Columns",
|
||||
indexColumnsPlaceholder: "Select columns...",
|
||||
unique: "Unique",
|
||||
indexType: "Type",
|
||||
includedColumns: "Included",
|
||||
includedColumnsPlaceholder: "Select columns...",
|
||||
filter: "Filter",
|
||||
primary: "Primary",
|
||||
drop: "Drop",
|
||||
restore: "Restore",
|
||||
|
||||
@@ -335,7 +335,12 @@ export default {
|
||||
actions: "操作",
|
||||
indexName: "索引名",
|
||||
indexColumns: "字段列表",
|
||||
indexColumnsPlaceholder: "选择列...",
|
||||
unique: "唯一",
|
||||
indexType: "类型",
|
||||
includedColumns: "包含列",
|
||||
includedColumnsPlaceholder: "选择列...",
|
||||
filter: "过滤条件",
|
||||
primary: "主键",
|
||||
drop: "删除",
|
||||
restore: "恢复",
|
||||
|
||||
@@ -180,7 +180,13 @@ export function generateSyncSql(
|
||||
if (idx.type === "added" && idx.source) {
|
||||
const cols = idx.source.columns.map((c) => quoteId(c, dbType)).join(", ");
|
||||
const unique = idx.source.is_unique ? "UNIQUE " : "";
|
||||
lines.push(`CREATE ${unique}INDEX ${quoteId(idx.name, dbType)} ON ${qt} (${cols});`);
|
||||
const idxType = idx.source.index_type ?? "";
|
||||
const usingClause = idxType && dbType === "postgres" ? ` USING ${idxType}` : "";
|
||||
const typePrefix = idxType && dbType === "sqlserver" ? `${idxType} ` : "";
|
||||
const incCols = idx.source.included_columns ?? [];
|
||||
const includeClause = incCols.length > 0 ? ` INCLUDE (${incCols.map((c) => quoteId(c, dbType)).join(", ")})` : "";
|
||||
const filter = idx.source.filter ? ` WHERE ${idx.source.filter}` : "";
|
||||
lines.push(`CREATE ${unique}${typePrefix}INDEX ${quoteId(idx.name, dbType)} ON ${qt}${usingClause} (${cols})${includeClause}${filter};`);
|
||||
} else if (idx.type === "removed") {
|
||||
if (isMySQL) {
|
||||
lines.push(`DROP INDEX ${quoteId(idx.name, dbType)} ON ${qt};`);
|
||||
|
||||
@@ -18,6 +18,10 @@ export interface EditableStructureIndex {
|
||||
columns: string[];
|
||||
isUnique: boolean;
|
||||
isPrimary: boolean;
|
||||
filter: string;
|
||||
indexType: string;
|
||||
includedColumns: string[];
|
||||
comment: string;
|
||||
original?: IndexInfo;
|
||||
markedForDrop: boolean;
|
||||
}
|
||||
@@ -245,7 +249,18 @@ function buildIndexSql(options: BuildTableStructureChangeSqlOptions, warnings: s
|
||||
if (!name || columns.length === 0) continue;
|
||||
const unique = index.isUnique ? "UNIQUE " : "";
|
||||
const cols = columns.map((column) => quoteIdent(databaseType, column)).join(", ");
|
||||
statements.push(`CREATE ${unique}INDEX ${quoteIdent(databaseType, name)} ON ${table} (${cols});`);
|
||||
const idxType = clean(index.indexType);
|
||||
const usingClause = idxType && databaseType === "postgres" ? ` USING ${idxType}` : "";
|
||||
const typePrefix = idxType && databaseType === "sqlserver" ? `${idxType} ` : "";
|
||||
const incCols = index.includedColumns.map(clean).filter(Boolean);
|
||||
const includeClause = incCols.length > 0 ? ` INCLUDE (${incCols.map((c) => quoteIdent(databaseType, c)).join(", ")})` : "";
|
||||
const filter = clean(index.filter);
|
||||
const whereClause = filter ? ` WHERE ${filter}` : "";
|
||||
statements.push(`CREATE ${unique}${typePrefix}INDEX ${quoteIdent(databaseType, name)} ON ${table}${usingClause} (${cols})${includeClause}${whereClause};`);
|
||||
const comment = clean(index.comment);
|
||||
if (comment && databaseType === "postgres") {
|
||||
statements.push(`COMMENT ON INDEX ${quoteIdent(databaseType, name)} IS ${quoteString(comment)};`);
|
||||
}
|
||||
}
|
||||
|
||||
return statements;
|
||||
|
||||
@@ -22,18 +22,15 @@ export function createIndexDrafts(indexes: IndexInfo[]): EditableStructureIndex[
|
||||
columns: [...index.columns],
|
||||
isUnique: index.is_unique,
|
||||
isPrimary: index.is_primary,
|
||||
filter: index.filter ?? "",
|
||||
indexType: index.index_type ?? "",
|
||||
includedColumns: index.included_columns ? [...index.included_columns] : [],
|
||||
comment: index.comment ?? "",
|
||||
original: index,
|
||||
markedForDrop: false,
|
||||
}));
|
||||
}
|
||||
|
||||
export function splitIndexColumns(value: string): string[] {
|
||||
return value
|
||||
.split(/[,\s]+/g)
|
||||
.map((part) => part.trim())
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
export function toColumnNames(columns: string[]): string {
|
||||
return columns.join(", ");
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@ export interface ColumnInfo {
|
||||
comment?: string | null;
|
||||
numeric_precision?: number | null;
|
||||
numeric_scale?: number | null;
|
||||
character_maximum_length?: number | null;
|
||||
}
|
||||
|
||||
export interface IndexInfo {
|
||||
@@ -51,6 +52,10 @@ export interface IndexInfo {
|
||||
columns: string[];
|
||||
is_unique: boolean;
|
||||
is_primary: boolean;
|
||||
filter?: string | null;
|
||||
index_type?: string | null;
|
||||
included_columns?: string[] | null;
|
||||
comment?: string | null;
|
||||
}
|
||||
|
||||
export interface ForeignKeyInfo {
|
||||
|
||||
Reference in New Issue
Block a user