mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-05-03 08:13:57 +00:00
clickhouse: edit table options
This commit is contained in:
@@ -294,12 +294,25 @@ export class SqlDumper implements AlterProcessor {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.put('&<&n)');
|
this.put('&<&n)');
|
||||||
|
|
||||||
|
this.tableOptions(table);
|
||||||
|
|
||||||
this.endCommand();
|
this.endCommand();
|
||||||
(table.indexes || []).forEach(ix => {
|
(table.indexes || []).forEach(ix => {
|
||||||
this.createIndex(ix);
|
this.createIndex(ix);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tableOptions(table: TableInfo) {
|
||||||
|
const options = this.driver.getTableFormOptions('sqlCreateTable');
|
||||||
|
for (const option of options) {
|
||||||
|
if (table[option.name]) {
|
||||||
|
this.put('&n');
|
||||||
|
this.put(option.sqlFormatString, table[option.name]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
createTablePrimaryKeyCore(table: TableInfo) {
|
createTablePrimaryKeyCore(table: TableInfo) {
|
||||||
if (table.primaryKey) {
|
if (table.primaryKey) {
|
||||||
this.put(',&n');
|
this.put(',&n');
|
||||||
|
|||||||
5
packages/types/engines.d.ts
vendored
5
packages/types/engines.d.ts
vendored
@@ -155,6 +155,11 @@ export interface EngineDriver extends FilterBehaviourProvider {
|
|||||||
collectionNameLabel?: string;
|
collectionNameLabel?: string;
|
||||||
newCollectionFormParams?: any[];
|
newCollectionFormParams?: any[];
|
||||||
|
|
||||||
|
getTableFormOptions(intent: 'newTableForm' | 'editTableForm' | 'sqlCreateTable' | 'sqlAlterTable'): {
|
||||||
|
name: string;
|
||||||
|
sqlFormatString: string;
|
||||||
|
}[];
|
||||||
|
|
||||||
supportedCreateDatabase?: boolean;
|
supportedCreateDatabase?: boolean;
|
||||||
showConnectionField?: (
|
showConnectionField?: (
|
||||||
field: string,
|
field: string,
|
||||||
|
|||||||
67
packages/web/src/elements/ObjectFieldsEditor.svelte
Normal file
67
packages/web/src/elements/ObjectFieldsEditor.svelte
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import _ from 'lodash';
|
||||||
|
import FontIcon from '../icons/FontIcon.svelte';
|
||||||
|
import FormArgumentList from '../forms/FormArgumentList.svelte';
|
||||||
|
import { writable } from 'svelte/store';
|
||||||
|
import FormProviderCore from '../forms/FormProviderCore.svelte';
|
||||||
|
|
||||||
|
export let title;
|
||||||
|
export let fieldDefinitions;
|
||||||
|
export let values;
|
||||||
|
export let onChangeValues;
|
||||||
|
|
||||||
|
let collapsed = false;
|
||||||
|
|
||||||
|
const valuesStore = writable(values || {});
|
||||||
|
|
||||||
|
$: onChangeValues($valuesStore);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="header">
|
||||||
|
<span
|
||||||
|
class="collapse"
|
||||||
|
on:click={() => {
|
||||||
|
collapsed = !collapsed;
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<FontIcon icon={collapsed ? 'icon chevron-down' : 'icon chevron-up'} />
|
||||||
|
</span>
|
||||||
|
<span class="title mr-1">{title}</span>
|
||||||
|
</div>
|
||||||
|
{#if !collapsed}
|
||||||
|
<FormProviderCore values={valuesStore}>
|
||||||
|
<FormArgumentList args={fieldDefinitions} />
|
||||||
|
</FormProviderCore>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.wrapper {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
background-color: var(--theme-bg-1);
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-weight: bold;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.body {
|
||||||
|
margin: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.collapse {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.collapse:hover {
|
||||||
|
color: var(--theme-font-hover);
|
||||||
|
background: var(--theme-bg-3);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -5,11 +5,15 @@
|
|||||||
import FormSelectField from './FormSelectField.svelte';
|
import FormSelectField from './FormSelectField.svelte';
|
||||||
import FormTextField from './FormTextField.svelte';
|
import FormTextField from './FormTextField.svelte';
|
||||||
import FormStringList from './FormStringList.svelte';
|
import FormStringList from './FormStringList.svelte';
|
||||||
|
import FormDropDownTextField from './FormDropDownTextField.svelte';
|
||||||
|
import { getFormContext } from './FormProviderCore.svelte';
|
||||||
|
|
||||||
export let arg;
|
export let arg;
|
||||||
export let namePrefix;
|
export let namePrefix;
|
||||||
|
|
||||||
$: name = `${namePrefix}${arg.name}`;
|
$: name = `${namePrefix}${arg.name}`;
|
||||||
|
|
||||||
|
const { setFieldValue } = getFormContext();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if arg.type == 'text'}
|
{#if arg.type == 'text'}
|
||||||
@@ -19,14 +23,10 @@
|
|||||||
defaultValue={arg.default}
|
defaultValue={arg.default}
|
||||||
focused={arg.focused}
|
focused={arg.focused}
|
||||||
placeholder={arg.placeholder}
|
placeholder={arg.placeholder}
|
||||||
|
disabled={arg.disabled}
|
||||||
/>
|
/>
|
||||||
{:else if arg.type == 'stringlist'}
|
{:else if arg.type == 'stringlist'}
|
||||||
<FormStringList
|
<FormStringList label={arg.label} addButtonLabel={arg.addButtonLabel} {name} placeholder={arg.placeholder} />
|
||||||
label={arg.label}
|
|
||||||
addButtonLabel={arg.addButtonLabel}
|
|
||||||
{name}
|
|
||||||
placeholder={arg.placeholder}
|
|
||||||
/>
|
|
||||||
{:else if arg.type == 'number'}
|
{:else if arg.type == 'number'}
|
||||||
<FormTextField
|
<FormTextField
|
||||||
label={arg.label}
|
label={arg.label}
|
||||||
@@ -48,4 +48,16 @@
|
|||||||
_.isString(opt) ? { label: opt, value: opt } : { label: opt.name, value: opt.value }
|
_.isString(opt) ? { label: opt, value: opt } : { label: opt.name, value: opt.value }
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
{:else if arg.type == 'dropdowntext'}
|
||||||
|
<FormDropDownTextField
|
||||||
|
label={arg.label}
|
||||||
|
{name}
|
||||||
|
defaultValue={arg.default}
|
||||||
|
menu={() => {
|
||||||
|
return arg.options.map(opt => ({
|
||||||
|
text: _.isString(opt) ? opt : opt.name,
|
||||||
|
onClick: () => setFieldValue(name, _.isString(opt) ? opt : opt.value),
|
||||||
|
}));
|
||||||
|
}}
|
||||||
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -81,6 +81,7 @@
|
|||||||
import IndexEditorModal from './IndexEditorModal.svelte';
|
import IndexEditorModal from './IndexEditorModal.svelte';
|
||||||
import PrimaryKeyEditorModal from './PrimaryKeyEditorModal.svelte';
|
import PrimaryKeyEditorModal from './PrimaryKeyEditorModal.svelte';
|
||||||
import UniqueEditorModal from './UniqueEditorModal.svelte';
|
import UniqueEditorModal from './UniqueEditorModal.svelte';
|
||||||
|
import ObjectFieldsEditor from '../elements/ObjectFieldsEditor.svelte';
|
||||||
|
|
||||||
export const activator = createActivator('TableEditor', true);
|
export const activator = createActivator('TableEditor', true);
|
||||||
|
|
||||||
@@ -154,9 +155,24 @@
|
|||||||
tableInfo;
|
tableInfo;
|
||||||
invalidateCommands();
|
invalidateCommands();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$: tableFormOptions = driver?.getTableFormOptions(tableInfo?.objectId ? 'editTableForm' : 'newTableForm');
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
|
{#if tableFormOptions}
|
||||||
|
<ObjectFieldsEditor
|
||||||
|
title="Table properties"
|
||||||
|
fieldDefinitions={tableFormOptions}
|
||||||
|
values={tableInfo}
|
||||||
|
onChangeValues={vals => {
|
||||||
|
if (!_.isEmpty(vals)) {
|
||||||
|
setTableInfo(tbl => ({ ...tbl, ...vals }));
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
|
|
||||||
<ObjectListControl
|
<ObjectListControl
|
||||||
collection={columns?.map((x, index) => ({ ...x, ordinal: index + 1 }))}
|
collection={columns?.map((x, index) => ({ ...x, ordinal: index + 1 }))}
|
||||||
title={`Columns (${columns?.length || 0})`}
|
title={`Columns (${columns?.length || 0})`}
|
||||||
|
|||||||
@@ -3,6 +3,53 @@ const Dumper = require('./Dumper');
|
|||||||
const { mysqlSplitterOptions } = require('dbgate-query-splitter/lib/options');
|
const { mysqlSplitterOptions } = require('dbgate-query-splitter/lib/options');
|
||||||
const _cloneDeepWith = require('lodash/cloneDeepWith');
|
const _cloneDeepWith = require('lodash/cloneDeepWith');
|
||||||
|
|
||||||
|
const clickhouseEngines = [
|
||||||
|
'MergeTree',
|
||||||
|
'ReplacingMergeTree',
|
||||||
|
'SummingMergeTree',
|
||||||
|
'AggregatingMergeTree',
|
||||||
|
'CollapsingMergeTree',
|
||||||
|
'VersionedCollapsingMergeTree',
|
||||||
|
'GraphiteMergeTree',
|
||||||
|
'Distributed',
|
||||||
|
'Log',
|
||||||
|
'TinyLog',
|
||||||
|
'StripeLog',
|
||||||
|
'Memory',
|
||||||
|
'File',
|
||||||
|
'URL',
|
||||||
|
'JDBC',
|
||||||
|
'ODBC',
|
||||||
|
'Buffer',
|
||||||
|
'Null',
|
||||||
|
'Kafka',
|
||||||
|
'HDFS',
|
||||||
|
'S3',
|
||||||
|
'Merge',
|
||||||
|
'Join',
|
||||||
|
'MaterializedView',
|
||||||
|
'Dictionary',
|
||||||
|
'MySQL',
|
||||||
|
'PostgreSQL',
|
||||||
|
'MongoDB',
|
||||||
|
'EmbeddedRocksDB',
|
||||||
|
'View',
|
||||||
|
'MaterializeMySQL',
|
||||||
|
'MaterializePostgreSQL',
|
||||||
|
'ReplicatedMergeTree',
|
||||||
|
'ReplicatedReplacingMergeTree',
|
||||||
|
'ReplicatedSummingMergeTree',
|
||||||
|
'ReplicatedAggregatingMergeTree',
|
||||||
|
'ReplicatedCollapsingMergeTree',
|
||||||
|
'ReplicatedVersionedCollapsingMergeTree',
|
||||||
|
'ReplicatedGraphiteMergeTree',
|
||||||
|
'ExternalDistributed',
|
||||||
|
'Iceberg',
|
||||||
|
'Parquet',
|
||||||
|
'ORC',
|
||||||
|
'DeltaLake',
|
||||||
|
];
|
||||||
|
|
||||||
/** @type {import('dbgate-types').SqlDialect} */
|
/** @type {import('dbgate-types').SqlDialect} */
|
||||||
const dialect = {
|
const dialect = {
|
||||||
limitSelect: true,
|
limitSelect: true,
|
||||||
@@ -70,6 +117,26 @@ const driver = {
|
|||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getTableFormOptions: (intent) => {
|
||||||
|
const isNewTable = intent == 'newTableForm';
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
type: isNewTable ? 'dropdowntext' : text,
|
||||||
|
options: clickhouseEngines,
|
||||||
|
label: 'Engine',
|
||||||
|
name: 'tableEngine',
|
||||||
|
sqlFormatString: '^engine = %s',
|
||||||
|
disabled: !isNewTable,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'text',
|
||||||
|
label: 'Comment',
|
||||||
|
name: 'objectComment',
|
||||||
|
sqlFormatString: '^comment %v',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = driver;
|
module.exports = driver;
|
||||||
|
|||||||
Reference in New Issue
Block a user