mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-18 00:56:02 +00:00
212 lines
5.3 KiB
JavaScript
212 lines
5.3 KiB
JavaScript
const { driverBase } = global.DBGATE_PACKAGES['dbgate-tools'];
|
|
const Dumper = require('./Dumper');
|
|
const { mysqlSplitterOptions } = require('dbgate-query-splitter/lib/options');
|
|
const _cloneDeepWith = require('lodash/cloneDeepWith');
|
|
|
|
const clickhouseIcon = '<svg height="2500" viewBox="0 0 150 150" width="2500" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h150v150h-150z" fill="#f9ff69"/><path d="m30 28.3c0-.6.5-1.1 1.1-1.1h8.4c.6 0 1.1.5 1.1 1.1v93.3c0 .6-.5 1.1-1.1 1.1h-8.4c-.6 0-1.1-.5-1.1-1.1zm21.2 0c0-.6.5-1.1 1.1-1.1h8.4c.6 0 1.1.5 1.1 1.1v93.3c0 .6-.5 1.1-1.1 1.1h-8.4c-.6 0-1.1-.5-1.1-1.1zm21.2 0c0-.6.5-1.1 1.1-1.1h8.4c.6 0 1.1.5 1.1 1.1v93.3c0 .6-.5 1.1-1.1 1.1h-8.4c-.6 0-1.1-.5-1.1-1.1zm21.3 0c0-.6.5-1.1 1.1-1.1h8.4c.6 0 1.1.5 1.1 1.1v93.3c0 .6-.5 1.1-1.1 1.1h-8.4c-.6 0-1.1-.5-1.1-1.1zm21.2 37.2c0-.6.5-1.1 1.1-1.1h8.4c.6 0 1.1.5 1.1 1.1v19c0 .6-.5 1.1-1.1 1.1h-8.4c-.6 0-1.1-.5-1.1-1.1z" fill="#161616"/></svg>';
|
|
|
|
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',
|
|
];
|
|
|
|
const clickhouseDataTypes = [
|
|
'Int8',
|
|
'Int16',
|
|
'Int32',
|
|
'Int64',
|
|
'UInt8',
|
|
'UInt16',
|
|
'UInt32',
|
|
'UInt64',
|
|
'Float32',
|
|
'Float64',
|
|
'Decimal',
|
|
'String',
|
|
'FixedString',
|
|
'UUID',
|
|
'Date',
|
|
'DateTime',
|
|
'DateTime64',
|
|
"DateTime('UTC')",
|
|
'Date32',
|
|
'Enum8',
|
|
'Enum16',
|
|
'Array',
|
|
'Tuple',
|
|
'Nullable',
|
|
'LowCardinality',
|
|
'Map',
|
|
'JSON',
|
|
'IPv4',
|
|
'IPv6',
|
|
'Nested',
|
|
'AggregateFunction',
|
|
'SimpleAggregateFunction',
|
|
];
|
|
|
|
/** @type {import('dbgate-types').SqlDialect} */
|
|
const dialect = {
|
|
limitSelect: true,
|
|
rangeSelect: true,
|
|
stringEscapeChar: "'",
|
|
fallbackDataType: 'String',
|
|
dropColumnDependencies: ['primaryKey', 'sortingKey'],
|
|
changeColumnDependencies: ['primaryKey', 'sortingKey'],
|
|
renameColumnDependencies: ['primaryKey', 'sortingKey'],
|
|
createColumn: true,
|
|
dropColumn: true,
|
|
changeColumn: true,
|
|
changeAutoIncrement: true,
|
|
createIndex: true,
|
|
dropIndex: true,
|
|
anonymousPrimaryKey: true,
|
|
createColumnWithColumnKeyword: true,
|
|
specificNullabilityImplementation: true,
|
|
omitForeignKeys: true,
|
|
omitUniqueConstraints: true,
|
|
omitIndexes: true,
|
|
sortingKeys: true,
|
|
|
|
columnProperties: {
|
|
columnComment: true,
|
|
},
|
|
|
|
quoteIdentifier(s) {
|
|
return `"${s}"`;
|
|
},
|
|
|
|
getTableFormOptions(intent) {
|
|
const isNewTable = intent == 'newTableForm' || intent == 'sqlCreateTable';
|
|
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',
|
|
allowEmptyValue: true,
|
|
},
|
|
];
|
|
},
|
|
|
|
predefinedDataTypes: clickhouseDataTypes,
|
|
};
|
|
|
|
/** @type {import('dbgate-types').EngineDriver} */
|
|
const driver = {
|
|
...driverBase,
|
|
dumperClass: Dumper,
|
|
dialect,
|
|
engine: 'clickhouse@dbgate-plugin-clickhouse',
|
|
title: 'ClickHouse',
|
|
supportsIncrementalAnalysis: true,
|
|
icon: clickhouseIcon,
|
|
showConnectionField: (field, values) => {
|
|
return ['databaseUrl', 'defaultDatabase', 'singleDatabase', 'isReadOnly', 'user', 'password'].includes(field);
|
|
},
|
|
getQuerySplitterOptions: (usage) =>
|
|
usage == 'editor'
|
|
? { ...mysqlSplitterOptions, ignoreComments: true, preventSingleLineSplit: true }
|
|
: mysqlSplitterOptions,
|
|
|
|
createSaveChangeSetScript(changeSet, dbinfo, defaultCreator) {
|
|
function removeConditionSource(cmd) {
|
|
cmd.where = _cloneDeepWith(cmd.where, (expr) => {
|
|
if (expr.exprType == 'column') {
|
|
return {
|
|
...expr,
|
|
source: undefined,
|
|
};
|
|
}
|
|
});
|
|
}
|
|
|
|
const res = defaultCreator(changeSet, dbinfo);
|
|
for (const cmd of res) {
|
|
if (cmd.commandType == 'update') {
|
|
cmd.alterTableUpdateSyntax = true;
|
|
removeConditionSource(cmd);
|
|
}
|
|
if (cmd.commandType == 'delete') {
|
|
const table = dbinfo?.tables?.find((x) => x.pureName == cmd?.from?.name?.pureName);
|
|
if (table?.tableEngine != 'MergeTree') {
|
|
cmd.alterTableDeleteSyntax = true;
|
|
}
|
|
removeConditionSource(cmd);
|
|
}
|
|
}
|
|
return res;
|
|
},
|
|
|
|
beforeConnectionSave: (connection) => {
|
|
return {
|
|
...connection,
|
|
useDatabaseUrl: 1,
|
|
};
|
|
},
|
|
|
|
adaptTableInfo(table) {
|
|
const baseAdapted = driverBase.adaptTableInfo(table);
|
|
|
|
if (!baseAdapted.primaryKey && !baseAdapted.sortingKey) {
|
|
return {
|
|
...baseAdapted,
|
|
tableEngine: 'Log',
|
|
};
|
|
}
|
|
return baseAdapted;
|
|
},
|
|
};
|
|
|
|
module.exports = driver;
|