diff --git a/packages/tools/src/SqlDumper.ts b/packages/tools/src/SqlDumper.ts index abc10807..c8f551a5 100644 --- a/packages/tools/src/SqlDumper.ts +++ b/packages/tools/src/SqlDumper.ts @@ -181,6 +181,8 @@ export class SqlDumper implements AlterProcessor { this.put(' ^auto_increment'); } + specialColumnOptions(column) {} + columnDefinition(column: ColumnInfo, { includeDefault = true, includeNullable = true, includeCollate = true } = {}) { if (column.computedExpression) { this.put('^as %s', column.computedExpression); @@ -193,9 +195,7 @@ export class SqlDumper implements AlterProcessor { } this.putRaw(' '); - if (column.isSparse) { - this.put(' ^sparse '); - } + this.specialColumnOptions(column); if (includeNullable) { this.put(column.notNull ? '^not ^null' : '^null'); } diff --git a/packages/tools/src/diffTools.ts b/packages/tools/src/diffTools.ts index 326a21a3..c7f19d3f 100644 --- a/packages/tools/src/diffTools.ts +++ b/packages/tools/src/diffTools.ts @@ -217,6 +217,24 @@ export function testEqualColumns( // opts.DiffLogger.Trace('Column {0}, {1}: different is_sparse: {2}; {3}', a, b, a.IsSparse, b.IsSparse); return false; } + if ((a.isUnsigned || false) != (b.isUnsigned || false)) { + console.debug( + `Column ${a.pureName}.${a.columnName}, ${b.pureName}.${b.columnName}: different unsigned: ${a.isUnsigned}, ${b.isUnsigned}` + ); + return false; + } + if ((a.isZerofill || false) != (b.isZerofill || false)) { + console.debug( + `Column ${a.pureName}.${a.columnName}, ${b.pureName}.${b.columnName}: different zerofill: ${a.isZerofill}, ${b.isZerofill}` + ); + return false; + } + if ((a.columnComment || '') != (b.columnComment || '')) { + console.debug( + `Column ${a.pureName}.${a.columnName}, ${b.pureName}.${b.columnName}: different comment: ${a.columnComment}, ${b.columnComment}` + ); + return false; + } if (!testEqualTypes(a, b, opts)) { return false; diff --git a/packages/types/dbinfo.d.ts b/packages/types/dbinfo.d.ts index 2f0ed7cc..0793b8d8 100644 --- a/packages/types/dbinfo.d.ts +++ b/packages/types/dbinfo.d.ts @@ -55,6 +55,8 @@ export interface ColumnInfo extends NamedObjectInfo { defaultValue?: string; defaultConstraint?: string; columnComment?: string; + isUnsigned?: boolean; + isZerofill?: boolean; } export interface DatabaseObjectInfo extends NamedObjectInfo { diff --git a/packages/web/src/tableeditor/ColumnEditorModal.svelte b/packages/web/src/tableeditor/ColumnEditorModal.svelte index bad74949..91c12075 100644 --- a/packages/web/src/tableeditor/ColumnEditorModal.svelte +++ b/packages/web/src/tableeditor/ColumnEditorModal.svelte @@ -20,6 +20,7 @@ export let setTableInfo; export let tableInfo; export let onAddNext; + export let driver; @@ -36,6 +37,18 @@ + {#if driver?.dialect?.columnProperties?.isUnsigned} + + {/if} + {#if driver?.dialect?.columnProperties?.isZerofill} + + {/if} + {#if driver?.dialect?.columnProperties?.columnComment} + + {/if} + {#if driver?.dialect?.columnProperties?.isSparse} + + {/if} { await tick(); addColumn(); @@ -158,7 +159,7 @@ title={`Columns (${columns?.length || 0})`} emptyMessage="No columns defined" clickable={writable()} - on:clickrow={e => showModal(ColumnEditorModal, { columnInfo: e.detail, tableInfo, setTableInfo })} + on:clickrow={e => showModal(ColumnEditorModal, { columnInfo: e.detail, tableInfo, setTableInfo, driver })} onAddNew={writable() ? addColumn : null} columns={[ { @@ -194,6 +195,18 @@ sortable: true, slot: 2, }, + driver?.dialect?.columnProperties?.isUnsigned && { + fieldName: 'isUnsigned', + header: 'Unsigned', + sortable: true, + slot: 4, + }, + driver?.dialect?.columnProperties?.isZerofill && { + fieldName: 'isZerofill', + header: 'Zero fill', + sortable: true, + slot: 5, + }, driver?.dialect?.columnProperties?.columnComment && { fieldName: 'columnComment', header: 'Comment', @@ -219,6 +232,8 @@ }}>Remove + {row?.isUnsigned ? 'YES' : 'NO'} + {row?.isZerofill ? 'YES' : 'NO'} diff --git a/plugins/dbgate-plugin-mssql/src/frontend/MsSqlDumper.js b/plugins/dbgate-plugin-mssql/src/frontend/MsSqlDumper.js index 0f56a80e..f83cba1e 100644 --- a/plugins/dbgate-plugin-mssql/src/frontend/MsSqlDumper.js +++ b/plugins/dbgate-plugin-mssql/src/frontend/MsSqlDumper.js @@ -129,6 +129,12 @@ class MsSqlDumper extends SqlDumper { } } + specialColumnOptions(column) { + if (column.isSparse) { + this.put('^sparse '); + } + } + renameConstraint(cnt, newname) { if (cnt.constraintType == 'index') this.putCmd("^execute sp_rename '%f.%i', '%s', 'INDEX'", cnt, cnt.constraintName, newname); diff --git a/plugins/dbgate-plugin-mysql/src/backend/Analyser.js b/plugins/dbgate-plugin-mysql/src/backend/Analyser.js index 117015cc..5be38c86 100644 --- a/plugins/dbgate-plugin-mysql/src/backend/Analyser.js +++ b/plugins/dbgate-plugin-mysql/src/backend/Analyser.js @@ -15,7 +15,9 @@ function getColumnInfo({ numericScale, defaultValue, columnComment, + columnType, }) { + const columnTypeTokens = _.isString(columnType) ? columnType.split(' ').map(x => x.trim().toLowerCase()) : []; let fullDataType = dataType; if (charMaxLength && isTypeString(dataType)) fullDataType = `${dataType}(${charMaxLength})`; if (numericPrecision && numericScale && isTypeNumeric(dataType)) @@ -27,6 +29,8 @@ function getColumnInfo({ columnComment, dataType: fullDataType, defaultValue, + isUnsigned: columnTypeTokens.includes('unsigned'), + isZerofill: columnTypeTokens.includes('zerofill'), }; } diff --git a/plugins/dbgate-plugin-mysql/src/backend/sql/columns.js b/plugins/dbgate-plugin-mysql/src/backend/sql/columns.js index 31fcd752..c7f89ccf 100644 --- a/plugins/dbgate-plugin-mysql/src/backend/sql/columns.js +++ b/plugins/dbgate-plugin-mysql/src/backend/sql/columns.js @@ -9,6 +9,7 @@ select NUMERIC_SCALE as numericScale, COLUMN_DEFAULT as defaultValue, COLUMN_COMMENT as columnComment, + COLUMN_TYPE as columnType, EXTRA as extra from INFORMATION_SCHEMA.COLUMNS where TABLE_SCHEMA = '#DATABASE#' and TABLE_NAME =OBJECT_ID_CONDITION diff --git a/plugins/dbgate-plugin-mysql/src/frontend/Dumper.js b/plugins/dbgate-plugin-mysql/src/frontend/Dumper.js index 58840745..1ab7fffd 100644 --- a/plugins/dbgate-plugin-mysql/src/frontend/Dumper.js +++ b/plugins/dbgate-plugin-mysql/src/frontend/Dumper.js @@ -38,6 +38,22 @@ class Dumper extends SqlDumper { this.endCommand(); } + specialColumnOptions(column) { + if (column.isUnsigned) { + this.put('^unsigned '); + } + if (column.isZerofill) { + this.put('^zerofill '); + } + } + + columnDefinition(col, options) { + super.columnDefinition(col, options); + if (col.columnComment) { + this.put(' ^comment %v ', col.columnComment); + } + } + renameColumn(column, newcol) { this.changeColumn( column, diff --git a/plugins/dbgate-plugin-mysql/src/frontend/drivers.js b/plugins/dbgate-plugin-mysql/src/frontend/drivers.js index b340740a..49a08910 100644 --- a/plugins/dbgate-plugin-mysql/src/frontend/drivers.js +++ b/plugins/dbgate-plugin-mysql/src/frontend/drivers.js @@ -33,6 +33,8 @@ const dialect = { columnProperties: { columnComment: true, + isUnsigned: true, + isZerofill: true, }, }; diff --git a/plugins/dbgate-plugin-postgres/src/frontend/Dumper.js b/plugins/dbgate-plugin-postgres/src/frontend/Dumper.js index 3dcd9fd6..d08e7146 100644 --- a/plugins/dbgate-plugin-postgres/src/frontend/Dumper.js +++ b/plugins/dbgate-plugin-postgres/src/frontend/Dumper.js @@ -54,7 +54,6 @@ class Dumper extends SqlDumper { } columnDefinition(col, options) { - const { autoIncrement } = options || {}; if (col.autoIncrement) { this.put('^serial'); return;