mirror of
https://github.com/dbgate/dbgate
synced 2024-11-07 20:26:23 +00:00
alter table
This commit is contained in:
parent
e7c64265ae
commit
624ada2873
@ -248,10 +248,13 @@ export class AlterPlan {
|
||||
|
||||
if (op.operationType == 'dropTable') {
|
||||
return [
|
||||
...(op.oldObject.dependencies || []).map(oldObject => ({
|
||||
operationType: 'dropConstraint',
|
||||
oldObject,
|
||||
})),
|
||||
...(op.oldObject.dependencies || []).map(oldObject => {
|
||||
const opRes: AlterOperation = {
|
||||
operationType: 'dropConstraint',
|
||||
oldObject,
|
||||
};
|
||||
return opRes;
|
||||
}),
|
||||
op,
|
||||
];
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { ColumnInfo, DatabaseInfo, DatabaseInfoObjects, TableInfo } from 'dbgate-types';
|
||||
import _ from 'lodash';
|
||||
import { ColumnInfo, ColumnReference, DatabaseInfo, DatabaseInfoObjects, TableInfo } from 'dbgate-types';
|
||||
|
||||
export function fullNameFromString(name) {
|
||||
const m = name.match(/\[([^\]]+)\]\.\[([^\]]+)\]/);
|
||||
@ -68,3 +69,28 @@ export function makeUniqueColumnNames(res: ColumnInfo[]) {
|
||||
usedNames.add(res[i].columnName);
|
||||
}
|
||||
}
|
||||
|
||||
function columnsConstraintName(prefix: string, table: TableInfo, columns: ColumnReference[]) {
|
||||
return `${prefix}_${table.pureName}_${columns.map(x => x.columnName.replace(' ', '_')).join('_')}`;
|
||||
}
|
||||
|
||||
export function fillConstraintNames(table: TableInfo) {
|
||||
if (!table) return table;
|
||||
const res = _.cloneDeep(table);
|
||||
if (res.primaryKey && !res.primaryKey.constraintName) {
|
||||
res.primaryKey.constraintName = `PK_${res.pureName}`;
|
||||
}
|
||||
for (const fk of res.foreignKeys) {
|
||||
if (fk.constraintName) continue;
|
||||
fk.constraintName = columnsConstraintName('FK', res, fk.columns);
|
||||
}
|
||||
for (const ix of res.indexes) {
|
||||
if (ix.constraintName) continue;
|
||||
ix.constraintName = columnsConstraintName('IX', res, ix.columns);
|
||||
}
|
||||
for (const uq of res.uniques) {
|
||||
if (uq.constraintName) continue;
|
||||
uq.constraintName = columnsConstraintName('UQ', res, uq.columns);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -1,6 +1,14 @@
|
||||
import uuidv1 from 'uuid/v1';
|
||||
import _omit from 'lodash/omit';
|
||||
import { ColumnInfo, ConstraintInfo, ForeignKeyInfo, PrimaryKeyInfo, TableInfo } from 'dbgate-types';
|
||||
import {
|
||||
ColumnInfo,
|
||||
ConstraintInfo,
|
||||
ForeignKeyInfo,
|
||||
IndexInfo,
|
||||
PrimaryKeyInfo,
|
||||
TableInfo,
|
||||
UniqueInfo,
|
||||
} from 'dbgate-types';
|
||||
|
||||
export interface EditorColumnInfo extends ColumnInfo {
|
||||
isPrimaryKey?: boolean;
|
||||
@ -8,7 +16,7 @@ export interface EditorColumnInfo extends ColumnInfo {
|
||||
|
||||
export function fillEditorColumnInfo(column: ColumnInfo, table: TableInfo): EditorColumnInfo {
|
||||
return {
|
||||
isPrimaryKey: !!(table?.primaryKey && table.primaryKey.columns.find(x => x.columnName == column.columnName)),
|
||||
isPrimaryKey: !!table?.primaryKey?.columns?.find(x => x.columnName == column.columnName),
|
||||
dataType: column ? undefined : 'int',
|
||||
...column,
|
||||
};
|
||||
@ -118,6 +126,26 @@ export function editorAddConstraint(table: TableInfo, constraint: ConstraintInfo
|
||||
];
|
||||
}
|
||||
|
||||
if (constraint.constraintType == 'index') {
|
||||
res.indexes = [
|
||||
...(res.indexes || []),
|
||||
{
|
||||
pairingId: uuidv1(),
|
||||
...constraint,
|
||||
} as IndexInfo,
|
||||
];
|
||||
}
|
||||
|
||||
if (constraint.constraintType == 'unique') {
|
||||
res.uniques = [
|
||||
...(res.uniques || []),
|
||||
{
|
||||
pairingId: uuidv1(),
|
||||
...constraint,
|
||||
} as UniqueInfo,
|
||||
];
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -139,6 +167,14 @@ export function editorModifyConstraint(table: TableInfo, constraint: ConstraintI
|
||||
);
|
||||
}
|
||||
|
||||
if (constraint.constraintType == 'index') {
|
||||
res.indexes = table.indexes.map(fk => (fk.pairingId == constraint.pairingId ? { ...fk, ...constraint } : fk));
|
||||
}
|
||||
|
||||
if (constraint.constraintType == 'unique') {
|
||||
res.uniques = table.uniques.map(fk => (fk.pairingId == constraint.pairingId ? { ...fk, ...constraint } : fk));
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -10,11 +10,13 @@
|
||||
export let title;
|
||||
export let clickable;
|
||||
export let onRemove = null;
|
||||
export let onAddNew = null;
|
||||
</script>
|
||||
|
||||
<ObjectListControl
|
||||
{collection}
|
||||
{title}
|
||||
{onAddNew}
|
||||
{clickable}
|
||||
on:clickrow
|
||||
columns={[
|
||||
|
@ -1,4 +1,8 @@
|
||||
<script lang="ts">
|
||||
import FontIcon from '../icons/FontIcon.svelte';
|
||||
|
||||
import Link from './Link.svelte';
|
||||
|
||||
import TableControl from './TableControl.svelte';
|
||||
|
||||
export let title;
|
||||
@ -6,13 +10,16 @@
|
||||
export let columns;
|
||||
export let showIfEmpty = false;
|
||||
export let clickable;
|
||||
|
||||
export let onAddNew;
|
||||
</script>
|
||||
|
||||
{#if collection?.length > 0 || showIfEmpty}
|
||||
<div class="wrapper">
|
||||
<div class="header">
|
||||
<span class="title">{title}</span>
|
||||
<span class="title mr-1">{title}</span>
|
||||
{#if onAddNew}
|
||||
<Link onClick={onAddNew}><FontIcon icon="icon add" /> Add new</Link>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="body">
|
||||
<TableControl
|
||||
@ -78,5 +85,4 @@
|
||||
.body {
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
@ -22,7 +22,7 @@
|
||||
export let onAddNext;
|
||||
</script>
|
||||
|
||||
<FormProvider initialValues={fillEditorColumnInfo(columnInfo, tableInfo)}>
|
||||
<FormProvider initialValues={fillEditorColumnInfo(columnInfo || {}, tableInfo)}>
|
||||
<ModalBase {...$$restProps}>
|
||||
<svelte:fragment slot="header"
|
||||
>{columnInfo ? 'Edit column' : `Add column ${(tableInfo?.columns || []).length + 1}`}</svelte:fragment
|
||||
|
@ -56,7 +56,7 @@
|
||||
{#each columns as column, index}
|
||||
<div class="row">
|
||||
<div class="label col-3">Column {index + 1}</div>
|
||||
<div class="col-6">
|
||||
<div class={$$slots.column ? 'col-3' : 'col-6'}>
|
||||
{#key column.columnName}
|
||||
<SelectField
|
||||
value={column.columnName}
|
||||
@ -73,6 +73,11 @@
|
||||
/>
|
||||
{/key}
|
||||
</div>
|
||||
{#if $$slots.column}
|
||||
<div class="col-3">
|
||||
<slot name="column" {column} setColumns={changeFunc => (columns = changeFunc(columns))} {index} />
|
||||
</div>
|
||||
{/if}
|
||||
<div class="col-3 button">
|
||||
<FormStyledButton
|
||||
value="Delete"
|
||||
|
@ -1,10 +1,11 @@
|
||||
<script lang="ts">
|
||||
import SelectField from '../forms/SelectField.svelte';
|
||||
|
||||
import ColumnsConstraintEditorModal from './ColumnsConstraintEditorModal.svelte';
|
||||
|
||||
export let constraintInfo;
|
||||
export let setTableInfo;
|
||||
export let tableInfo;
|
||||
|
||||
</script>
|
||||
|
||||
<ColumnsConstraintEditorModal
|
||||
@ -14,4 +15,27 @@
|
||||
{constraintInfo}
|
||||
{setTableInfo}
|
||||
{tableInfo}
|
||||
/>
|
||||
>
|
||||
<svelte:fragment slot="column" let:column let:setColumns let:index>
|
||||
<SelectField
|
||||
value={column.isDescending ? 'desc' : 'asc'}
|
||||
isNative
|
||||
options={[
|
||||
{ label: 'ASC', value: 'asc' },
|
||||
{ label: 'DESC', value: 'desc' },
|
||||
]}
|
||||
on:change={e => {
|
||||
setColumns(columns =>
|
||||
columns.map((col, i) =>
|
||||
i == index
|
||||
? {
|
||||
...col,
|
||||
isDescending: e.detail == 'desc',
|
||||
}
|
||||
: col
|
||||
)
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</svelte:fragment>
|
||||
</ColumnsConstraintEditorModal>
|
||||
|
@ -33,6 +33,17 @@
|
||||
testEnabled: () => getCurrentEditor()?.writable(),
|
||||
onClick: () => getCurrentEditor().addForeignKey(),
|
||||
});
|
||||
|
||||
registerCommand({
|
||||
id: 'tableEditor.addINdex',
|
||||
category: 'Table editor',
|
||||
name: 'Add index',
|
||||
icon: 'icon add-key',
|
||||
toolbar: true,
|
||||
isRelatedToTab: true,
|
||||
testEnabled: () => getCurrentEditor()?.writable(),
|
||||
onClick: () => getCurrentEditor().addIndex(),
|
||||
});
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
@ -99,6 +110,14 @@
|
||||
});
|
||||
}
|
||||
|
||||
export function addIndex() {
|
||||
showModal(IndexEditorModal, {
|
||||
setTableInfo,
|
||||
tableInfo,
|
||||
dbInfo,
|
||||
});
|
||||
}
|
||||
|
||||
$: columns = tableInfo?.columns;
|
||||
$: primaryKey = tableInfo?.primaryKey;
|
||||
$: foreignKeys = tableInfo?.foreignKeys;
|
||||
@ -118,6 +137,7 @@
|
||||
showIfEmpty
|
||||
clickable={writable()}
|
||||
on:clickrow={e => showModal(ColumnEditorModal, { columnInfo: e.detail, tableInfo, setTableInfo })}
|
||||
onAddNew={addColumn}
|
||||
columns={[
|
||||
{
|
||||
fieldName: 'notNull',
|
||||
@ -173,6 +193,7 @@
|
||||
<ObjectListControl
|
||||
collection={_.compact([primaryKey])}
|
||||
title="Primary key"
|
||||
onAddNew={primaryKey ? null : addPrimaryKey}
|
||||
clickable={writable()}
|
||||
on:clickrow={e => showModal(PrimaryKeyEditorModal, { constraintInfo: e.detail, tableInfo, setTableInfo })}
|
||||
columns={[
|
||||
@ -199,6 +220,7 @@
|
||||
|
||||
<ObjectListControl
|
||||
collection={indexes}
|
||||
onAddNew={addIndex}
|
||||
title={`Indexes (${indexes?.length || 0})`}
|
||||
clickable={writable()}
|
||||
on:clickrow={e => showModal(IndexEditorModal, { constraintInfo: e.detail, tableInfo, setTableInfo })}
|
||||
@ -226,6 +248,7 @@
|
||||
|
||||
<ForeignKeyObjectListControl
|
||||
collection={foreignKeys}
|
||||
onAddNew={addForeignKey}
|
||||
title={`Foreign keys (${foreignKeys?.length || 0})`}
|
||||
clickable={writable()}
|
||||
onRemove={row => setTableInfo(tbl => editorDeleteConstraint(tbl, row))}
|
||||
|
@ -28,7 +28,7 @@
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { findEngineDriver, generateTablePairingId, getAlterTableScript } from 'dbgate-tools';
|
||||
import { fillConstraintNames, findEngineDriver, generateTablePairingId, getAlterTableScript } from 'dbgate-tools';
|
||||
|
||||
import _ from 'lodash';
|
||||
import registerCommand from '../commands/registerCommand';
|
||||
@ -102,7 +102,7 @@
|
||||
|
||||
function doSave(createTableName) {
|
||||
const driver = findEngineDriver($connection, $extensions);
|
||||
const sql = getAlterTableScript($editorValue.base, $editorValue.current, {}, $dbInfo, driver);
|
||||
const sql = getAlterTableScript($editorValue.base, fillConstraintNames($editorValue.current), {}, $dbInfo, driver);
|
||||
|
||||
showModal(ConfirmSqlModal, {
|
||||
sql,
|
||||
|
Loading…
Reference in New Issue
Block a user