alter table

This commit is contained in:
Jan Prochazka 2021-09-12 17:33:51 +02:00
parent e7c64265ae
commit 624ada2873
10 changed files with 141 additions and 16 deletions

View File

@ -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,
];
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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={[

View File

@ -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>

View File

@ -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

View File

@ -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"

View File

@ -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>

View File

@ -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))}

View File

@ -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,