diff --git a/packages/tools/src/SqlDumper.ts b/packages/tools/src/SqlDumper.ts index 9c1a0732..ec45907a 100644 --- a/packages/tools/src/SqlDumper.ts +++ b/packages/tools/src/SqlDumper.ts @@ -304,7 +304,7 @@ export class SqlDumper implements AlterProcessor { } tableOptions(table: TableInfo) { - const options = this.driver.getTableFormOptions('sqlCreateTable'); + const options = this.driver?.dialect?.getTableFormOptions?.('sqlCreateTable') || []; for (const option of options) { if (table[option.name]) { this.put('&n'); @@ -686,6 +686,23 @@ export class SqlDumper implements AlterProcessor { this.putCmd('^drop %s %f', this.getSqlObjectSqlName(obj.objectTypeField), obj); } + setTableOption(table: TableInfo, optionName: string, optionValue: string) { + const options = this?.dialect?.getTableFormOptions?.('sqlAlterTable'); + const option = options?.find(x => x.name == optionName && !x.disabled); + if (!option) { + return; + } + + this.setTableOptionCore(table, optionName, optionValue, option.sqlFormatString); + + this.endCommand(); + } + + setTableOptionCore(table: TableInfo, optionName: string, optionValue: string, formatString: string) { + this.put('^alter ^table %f ', table); + this.put(formatString, optionValue); + } + fillPreloadedRows( table: NamedObjectInfo, oldRows: any[], diff --git a/packages/tools/src/alterPlan.ts b/packages/tools/src/alterPlan.ts index c47ecdc9..b8720978 100644 --- a/packages/tools/src/alterPlan.ts +++ b/packages/tools/src/alterPlan.ts @@ -97,6 +97,13 @@ interface AlterOperation_FillPreloadedRows { autoIncrementColumn: string; } +interface AlterOperation_SetTableOption { + operationType: 'setTableOption'; + table: TableInfo; + optionName: string; + optionValue: string; +} + type AlterOperation = | AlterOperation_CreateColumn | AlterOperation_ChangeColumn @@ -112,7 +119,8 @@ type AlterOperation = | AlterOperation_CreateSqlObject | AlterOperation_DropSqlObject | AlterOperation_RecreateTable - | AlterOperation_FillPreloadedRows; + | AlterOperation_FillPreloadedRows + | AlterOperation_SetTableOption; export class AlterPlan { recreates = { @@ -253,6 +261,15 @@ export class AlterPlan { }); } + setTableOption(table: TableInfo, optionName: string, optionValue: string) { + this.operations.push({ + operationType: 'setTableOption', + table, + optionName, + optionValue, + }); + } + run(processor: AlterProcessor) { for (const op of this.operations) { runAlterOperation(op, processor); @@ -575,6 +592,9 @@ export function runAlterOperation(op: AlterOperation, processor: AlterProcessor) case 'dropSqlObject': processor.dropSqlObject(op.oldObject); break; + case 'setTableOption': + processor.setTableOption(op.table, op.optionName, op.optionValue); + break; case 'fillPreloadedRows': processor.fillPreloadedRows(op.table, op.oldRows, op.newRows, op.key, op.insertOnly, op.autoIncrementColumn); break; diff --git a/packages/tools/src/database-info-alter-processor.ts b/packages/tools/src/database-info-alter-processor.ts index 2b8c2b23..53325243 100644 --- a/packages/tools/src/database-info-alter-processor.ts +++ b/packages/tools/src/database-info-alter-processor.ts @@ -129,4 +129,9 @@ export class DatabaseInfoAlterProcessor { tableInfo.preloadedRowsKey = key; tableInfo.preloadedRowsInsertOnly = insertOnly; } + + setTableOption(table: TableInfo, optionName: string, optionValue: string) { + const tableInfo = this.db.tables.find(x => x.pureName == table.pureName && x.schemaName == table.schemaName); + tableInfo[optionName] = optionValue; + } } diff --git a/packages/tools/src/diffTools.ts b/packages/tools/src/diffTools.ts index 6f939cb8..a92506ee 100644 --- a/packages/tools/src/diffTools.ts +++ b/packages/tools/src/diffTools.ts @@ -425,6 +425,20 @@ function planAlterTable(plan: AlterPlan, oldTable: TableInfo, newTable: TableInf constraintPairs.filter(x => x[0] == null).forEach(x => plan.createConstraint(x[1])); planTablePreload(plan, oldTable, newTable); + + planChangeTableOptions(plan, oldTable, newTable, opts); +} + +function planChangeTableOptions(plan: AlterPlan, oldTable: TableInfo, newTable: TableInfo, opts: DbDiffOptions) { + for(const option of plan.dialect?.getTableFormOptions?.('sqlAlterTable') || []) { + if (option.disabled) { + continue; + } + const name = option.name; + if (oldTable[name] != newTable[name] && (oldTable[name]||newTable[name])) { + plan.setTableOption(newTable, name, newTable[name]); + } + } } export function testEqualTables( diff --git a/packages/types/alter-processor.d.ts b/packages/types/alter-processor.d.ts index e2d1d6d7..fae6d4fe 100644 --- a/packages/types/alter-processor.d.ts +++ b/packages/types/alter-processor.d.ts @@ -15,6 +15,7 @@ export interface AlterProcessor { recreateTable(oldTable: TableInfo, newTable: TableInfo); createSqlObject(obj: SqlObjectInfo); dropSqlObject(obj: SqlObjectInfo); + setTableOption(table: TableInfo, optionName: string, optionValue: string); fillPreloadedRows( table: NamedObjectInfo, oldRows: any[], diff --git a/packages/types/dialect.d.ts b/packages/types/dialect.d.ts index 9a6460d3..2173a9cb 100644 --- a/packages/types/dialect.d.ts +++ b/packages/types/dialect.d.ts @@ -48,5 +48,6 @@ export interface SqlDialect { getTableFormOptions(intent: 'newTableForm' | 'editTableForm' | 'sqlCreateTable' | 'sqlAlterTable'): { name: string; sqlFormatString: string; + disabled?: boolean; }[]; } diff --git a/packages/web/src/elements/ObjectFieldsEditor.svelte b/packages/web/src/elements/ObjectFieldsEditor.svelte index cc5dcf8a..caa2fbf6 100644 --- a/packages/web/src/elements/ObjectFieldsEditor.svelte +++ b/packages/web/src/elements/ObjectFieldsEditor.svelte @@ -4,6 +4,7 @@ import FormArgumentList from '../forms/FormArgumentList.svelte'; import { writable } from 'svelte/store'; import FormProviderCore from '../forms/FormProviderCore.svelte'; + import createRef from '../utility/createRef'; export let title; export let fieldDefinitions; diff --git a/packages/web/src/tableeditor/TableEditor.svelte b/packages/web/src/tableeditor/TableEditor.svelte index 63b9d32f..953ec9cf 100644 --- a/packages/web/src/tableeditor/TableEditor.svelte +++ b/packages/web/src/tableeditor/TableEditor.svelte @@ -89,6 +89,7 @@ export let setTableInfo; export let dbInfo; export let driver; + export let resetCounter; $: isWritable = !!setTableInfo; @@ -161,19 +162,21 @@
{#if tableFormOptions} - x.name) - )} - onChangeValues={vals => { - if (!_.isEmpty(vals)) { - setTableInfo(tbl => ({ ...tbl, ...vals })); - } - }} - /> + {#key resetCounter} + x.name) + )} + onChangeValues={vals => { + if (!_.isEmpty(vals)) { + setTableInfo(tbl => ({ ...tbl, ...vals })); + } + }} + /> + {/key} {/if} setEditorData(tbl => diff --git a/plugins/dbgate-plugin-clickhouse/src/frontend/Dumper.js b/plugins/dbgate-plugin-clickhouse/src/frontend/Dumper.js index afcc6473..f7842c04 100644 --- a/plugins/dbgate-plugin-clickhouse/src/frontend/Dumper.js +++ b/plugins/dbgate-plugin-clickhouse/src/frontend/Dumper.js @@ -1,6 +1,10 @@ const { SqlDumper } = require('dbgate-tools'); class Dumper extends SqlDumper { + setTableOptionCore(table, optionName, optionValue, formatString) { + this.put('^alter ^table %f ^modify ', table); + this.put(formatString, optionValue); + } } module.exports = Dumper; diff --git a/plugins/dbgate-plugin-clickhouse/src/frontend/driver.js b/plugins/dbgate-plugin-clickhouse/src/frontend/driver.js index f7607b3b..d0364ce4 100644 --- a/plugins/dbgate-plugin-clickhouse/src/frontend/driver.js +++ b/plugins/dbgate-plugin-clickhouse/src/frontend/driver.js @@ -74,7 +74,7 @@ const dialect = { }, getTableFormOptions(intent) { - const isNewTable = intent == 'newTableForm'; + const isNewTable = intent == 'newTableForm' || intent == 'sqlCreateTable'; return [ { type: isNewTable ? 'dropdowntext' : 'text', diff --git a/plugins/dbgate-plugin-mysql/src/frontend/drivers.js b/plugins/dbgate-plugin-mysql/src/frontend/drivers.js index 1131c2cc..7be9aaf5 100644 --- a/plugins/dbgate-plugin-mysql/src/frontend/drivers.js +++ b/plugins/dbgate-plugin-mysql/src/frontend/drivers.js @@ -105,21 +105,19 @@ const dialect = { }, getTableFormOptions(intent) { - const isNewTable = intent == 'newTableForm'; return [ { - type: isNewTable ? 'dropdowntext' : 'text', + type: 'dropdowntext', options: this.getSupportedEngines(), label: 'Engine', name: 'tableEngine', sqlFormatString: '^engine = %s', - disabled: !isNewTable, }, { type: 'text', label: 'Comment', name: 'objectComment', - sqlFormatString: '^comment %v', + sqlFormatString: '^comment = %v', }, ]; },