From 01f2881940732a3dde69c8a4f9f941d5b92b3686 Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Thu, 14 Mar 2019 14:44:30 +1300 Subject: [PATCH] #1653 - ENH: Add support for ClickHouse database With array type conversion etc --- .../clickhouse/ClickHousePlatform.java | 11 +- .../dbmigration/ddlgeneration/DdlBuffer.java | 5 + .../ddlgeneration/platform/BaseDdlBuffer.java | 13 +- .../ddlgeneration/platform/BaseTableDdl.java | 175 ++++++------------ .../platform/ClickHouseDbArray.java | 33 ++++ .../ddlgeneration/platform/ClickHouseDdl.java | 44 +++++ .../platform/ClickHouseDdlHandler.java | 11 ++ .../platform/ClickHouseTableDdl.java | 34 ++++ .../ddlgeneration/platform/MySqlDdl.java | 1 - .../platform/BaseTableDdlTest.java | 18 ++ .../platform/ClickHouseDbArrayTest.java | 24 +++ 11 files changed, 243 insertions(+), 126 deletions(-) create mode 100644 src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/ClickHouseDbArray.java create mode 100644 src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/ClickHouseDdlHandler.java create mode 100644 src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/ClickHouseTableDdl.java create mode 100644 src/test/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/ClickHouseDbArrayTest.java diff --git a/src/main/java/io/ebean/config/dbplatform/clickhouse/ClickHousePlatform.java b/src/main/java/io/ebean/config/dbplatform/clickhouse/ClickHousePlatform.java index c4bf13641..1a1d45a79 100644 --- a/src/main/java/io/ebean/config/dbplatform/clickhouse/ClickHousePlatform.java +++ b/src/main/java/io/ebean/config/dbplatform/clickhouse/ClickHousePlatform.java @@ -34,12 +34,19 @@ public class ClickHousePlatform extends DatabasePlatform { dbTypeMap.put(DbType.SMALLINT, new DbPlatformType("UInt16", false)); dbTypeMap.put(DbType.INTEGER, new DbPlatformType("UInt32", false)); dbTypeMap.put(DbType.BIGINT, new DbPlatformType("UInt64", false)); - dbTypeMap.put(DbType.DECIMAL, new DbPlatformType("Decimal", 38)); + dbTypeMap.put(DbType.DECIMAL, new DbPlatformType("Decimal", 16,4)); + dbTypeMap.put(DbType.DOUBLE, new DbPlatformType("Float64", false)); - dbTypeMap.put(DbType.VARCHAR, new DbPlatformType("String", false)); dbTypeMap.put(DbType.DATE, new DbPlatformType("Date", false)); dbTypeMap.put(DbType.TIMESTAMP, new DbPlatformType("DateTime", false)); + dbTypeMap.put(DbType.VARCHAR, new DbPlatformType("String", false)); + dbTypeMap.put(DbType.LONGVARCHAR, new DbPlatformType("String", false)); + dbTypeMap.put(DbType.CLOB, new DbPlatformType("String", false)); + dbTypeMap.put(DbType.JSONVARCHAR, new DbPlatformType("String", false)); + dbTypeMap.put(DbType.UUID, new DbPlatformType("UUID", false)); + dbTypeMap.put(DbType.INET, new DbPlatformType("String", false)); + dbTypeMap.put(DbType.CDIR, new DbPlatformType("String", false)); } } diff --git a/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/DdlBuffer.java b/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/DdlBuffer.java index 2ecbdc8ea..5d37cb762 100644 --- a/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/DdlBuffer.java +++ b/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/DdlBuffer.java @@ -19,6 +19,11 @@ public interface DdlBuffer { */ boolean isEmpty(); + /** + * Append a statement allowing for null or empty statements. + */ + DdlBuffer appendStatement(String content) throws IOException; + /** * Append DDL content to the buffer. */ diff --git a/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/BaseDdlBuffer.java b/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/BaseDdlBuffer.java index fad70f133..e54e91ba0 100644 --- a/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/BaseDdlBuffer.java +++ b/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/BaseDdlBuffer.java @@ -38,6 +38,15 @@ public class BaseDdlBuffer implements DdlBuffer { return this; } + @Override + public DdlBuffer appendStatement(String content) throws IOException { + if (content != null && !content.isEmpty()) { + writer.append(content); + endOfStatement(); + } + return this; + } + @Override public DdlBuffer append(String content) throws IOException { writer.append(content); @@ -73,7 +82,9 @@ public class BaseDdlBuffer implements DdlBuffer { */ @Override public DdlBuffer end() throws IOException { - writer.append("\n"); + if (!isEmpty()) { + writer.append("\n"); + } return this; } diff --git a/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/BaseTableDdl.java b/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/BaseTableDdl.java index 96fd2a5fc..1de59a353 100644 --- a/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/BaseTableDdl.java +++ b/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/BaseTableDdl.java @@ -37,6 +37,8 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import static io.ebeaninternal.dbmigration.ddlgeneration.platform.SplitColumns.split; + /** * Base implementation for 'create table' and 'alter table' statements. */ @@ -148,8 +150,7 @@ public class BaseTableDdl implements TableDdl { buffer.append("-- NOTE: table has @History - special migration may be necessary").newLine(); } for (String ddlScript : before) { - buffer.append(translate(ddlScript, tableName, columnName, this.defaultValue)); - buffer.endOfStatement(); + buffer.appendStatement(translate(ddlScript, tableName, columnName, this.defaultValue)); } } @@ -159,8 +160,7 @@ public class BaseTableDdl implements TableDdl { } // here we run post migration scripts for (String ddlScript : after) { - buffer.append(translate(ddlScript, tableName, columnName, defaultValue)); - buffer.endOfStatement(); + buffer.appendStatement(translate(ddlScript, tableName, columnName, defaultValue)); } if (!after.isEmpty()) { buffer.end(); @@ -317,12 +317,11 @@ public class BaseTableDdl implements TableDdl { private void addComments(DdlBuffer apply, CreateTable createTable) throws IOException { if (!platformDdl.isInlineComments()) { String tableComment = createTable.getComment(); - if (!StringHelper.isNull(tableComment)) { + if (hasValue(tableComment)) { platformDdl.addTableComment(apply, createTable.getName(), tableComment); } - List columns = createTable.getColumn(); - for (Column column : columns) { + for (Column column : createTable.getColumn()) { if (!StringHelper.isNull(column.getComment())) { platformDdl.addColumnComment(apply, createTable.getName(), column.getName(), column.getComment()); } @@ -335,10 +334,7 @@ public class BaseTableDdl implements TableDdl { */ private void addTableStorageEngine(DdlBuffer apply, CreateTable createTable) throws IOException { if (platformDdl.isIncludeStorageEngine()) { - String storageEngine = createTable.getStorageEngine(); - if (!StringHelper.isNull(storageEngine)) { - platformDdl.tableStorageEngine(apply, storageEngine); - } + platformDdl.tableStorageEngine(apply, createTable.getStorageEngine()); } } @@ -371,26 +367,17 @@ public class BaseTableDdl implements TableDdl { uqName = col.getUnique(); } String[] columnNames = {col.getName()}; - write.apply() - .append(platformDdl.alterTableAddUniqueConstraint(tableName, uqName, columnNames, Boolean.TRUE.equals(col.isNotnull()) ? null : columnNames)) - .endOfStatement(); - - write.dropAllForeignKeys() - .append(platformDdl.dropIndex(uqName, tableName)) - .endOfStatement(); + write.apply().appendStatement(platformDdl.alterTableAddUniqueConstraint(tableName, uqName, columnNames, Boolean.TRUE.equals(col.isNotnull()) ? null : columnNames)); + write.dropAllForeignKeys().appendStatement(platformDdl.dropIndex(uqName, tableName)); } for (UniqueConstraint constraint : externalCompoundUnique) { String uqName = constraint.getName(); - String[] columnNames = SplitColumns.split(constraint.getColumnNames()); - String[] nullableColumns = SplitColumns.split(constraint.getNullableColumns()); - write.apply() - .append(platformDdl.alterTableAddUniqueConstraint(tableName, uqName, columnNames, nullableColumns)) - .endOfStatement(); + String[] columnNames = split(constraint.getColumnNames()); + String[] nullableColumns = split(constraint.getNullableColumns()); - write.dropAllForeignKeys() - .append(platformDdl.dropIndex(uqName, tableName)) - .endOfStatement(); + write.apply().appendStatement(platformDdl.alterTableAddUniqueConstraint(tableName, uqName, columnNames, nullableColumns)); + write.dropAllForeignKeys().appendStatement(platformDdl.dropIndex(uqName, tableName)); } } @@ -407,9 +394,9 @@ public class BaseTableDdl implements TableDdl { } String createSeq = platformDdl.createSequence(seqName, initial, allocate); - if (createSeq != null) { + if (hasValue(createSeq)) { writer.apply().append(createSeq).newLine(); - writer.dropAll().append(platformDdl.dropSequence(seqName)).endOfStatement(); + writer.dropAll().appendStatement(platformDdl.dropSequence(seqName)); } } @@ -438,8 +425,7 @@ public class BaseTableDdl implements TableDdl { protected void writeInlineCompoundForeignKeys(DdlWrite write, CreateTable createTable) throws IOException { - List foreignKey = createTable.getForeignKey(); - for (ForeignKey key : foreignKey) { + for (ForeignKey key : createTable.getForeignKey()) { String fkConstraint = platformDdl.tableInlineForeignKey(new WriteForeignKey(null, key)); write.apply().append(",").newLine().append(" ").append(fkConstraint); } @@ -447,12 +433,10 @@ public class BaseTableDdl implements TableDdl { protected void writeAddForeignKeys(DdlWrite write, CreateTable createTable) throws IOException { - String tableName = createTable.getName(); - List columns = createTable.getColumn(); - for (Column column : columns) { + for (Column column : createTable.getColumn()) { String references = column.getReferences(); if (hasValue(references)) { - writeForeignKey(write, tableName, column); + writeForeignKey(write, createTable.getName(), column); } } @@ -461,11 +445,8 @@ public class BaseTableDdl implements TableDdl { protected void writeAddCompoundForeignKeys(DdlWrite write, CreateTable createTable) throws IOException { - String tableName = createTable.getName(); - - List foreignKey = createTable.getForeignKey(); - for (ForeignKey key : foreignKey) { - writeForeignKey(write, new WriteForeignKey(tableName, key)); + for (ForeignKey key : createTable.getForeignKey()) { + writeForeignKey(write, new WriteForeignKey(createTable.getName(), key)); } } @@ -479,19 +460,15 @@ public class BaseTableDdl implements TableDdl { String tableName = lowerTableName(request.table()); if (request.indexName() != null) { // no matching unique constraint so add the index - fkeyBuffer.append(platformDdl.createIndex(request.indexName(), tableName, request.cols())).endOfStatement(); + fkeyBuffer.appendStatement(platformDdl.createIndex(request.indexName(), tableName, request.cols())); } alterTableAddForeignKey(fkeyBuffer, request); - fkeyBuffer.end(); - write.dropAllForeignKeys() - .append(platformDdl.alterTableDropForeignKey(tableName, request.fkName())).endOfStatement(); - - if (request.indexName() != null) { - write.dropAllForeignKeys() - .append(platformDdl.dropIndex(request.indexName(), tableName)).endOfStatement(); + write.dropAllForeignKeys().appendStatement(platformDdl.alterTableDropForeignKey(tableName, request.fkName())); + if (hasValue(request.indexName())) { + write.dropAllForeignKeys().appendStatement(platformDdl.dropIndex(request.indexName(), tableName)); } write.dropAllForeignKeys().end(); @@ -499,10 +476,7 @@ public class BaseTableDdl implements TableDdl { protected void alterTableAddForeignKey(DdlBuffer buffer, WriteForeignKey request) throws IOException { - String fkConstraint = platformDdl.alterTableAddForeignKey(request); - if (fkConstraint != null && !fkConstraint.isEmpty()) { - buffer.append(fkConstraint).endOfStatement(); - } + buffer.appendStatement(platformDdl.alterTableAddForeignKey(request)); } protected void appendColumns(String[] columns, DdlBuffer buffer) throws IOException { @@ -516,13 +490,12 @@ public class BaseTableDdl implements TableDdl { buffer.append(")"); } - /** * Add 'drop table' statement to the buffer. */ protected void dropTable(DdlBuffer buffer, String tableName) throws IOException { - buffer.append(platformDdl.dropTable(tableName)).endOfStatement(); + buffer.appendStatement(platformDdl.dropTable(tableName)); } /** @@ -530,7 +503,7 @@ public class BaseTableDdl implements TableDdl { */ protected void dropSequence(DdlBuffer buffer, String sequenceName) throws IOException { - buffer.append(platformDdl.dropSequence(sequenceName)).endOfStatement(); + buffer.appendStatement(platformDdl.dropSequence(sequenceName)); } /** @@ -538,8 +511,7 @@ public class BaseTableDdl implements TableDdl { */ protected void writeCheckConstraints(DdlBuffer apply, CreateTable createTable) throws IOException { - List columns = createTable.getColumn(); - for (Column column : columns) { + for (Column column : createTable.getColumn()) { String checkConstraint = column.getCheckConstraint(); if (hasValue(checkConstraint)) { writeCheckConstraint(apply, column, checkConstraint); @@ -561,12 +533,11 @@ public class BaseTableDdl implements TableDdl { protected void writeCompoundUniqueConstraints(DdlBuffer apply, CreateTable createTable) throws IOException { - List uniqueConstraints = createTable.getUniqueConstraint(); boolean inlineUniqueWhenNull = platformDdl.isInlineUniqueWhenNullable(); - for (UniqueConstraint uniqueConstraint : uniqueConstraints) { + for (UniqueConstraint uniqueConstraint : createTable.getUniqueConstraint()) { if (inlineUniqueWhenNull) { String uqName = uniqueConstraint.getName(); - String[] columns = SplitColumns.split(uniqueConstraint.getColumnNames()); + String[] columns = split(uniqueConstraint.getColumnNames()); apply.append(",").newLine(); apply.append(" constraint ").append(uqName).append(" unique"); appendColumns(columns, apply); @@ -663,54 +634,34 @@ public class BaseTableDdl implements TableDdl { @Override public void generate(DdlWrite writer, CreateIndex createIndex) throws IOException { - - String[] cols = SplitColumns.split(createIndex.getColumns()); - writer.apply() - .append(platformDdl.createIndex(createIndex.getIndexName(), createIndex.getTableName(), cols)) - .endOfStatement(); - - writer.dropAll() - .append(platformDdl.dropIndex(createIndex.getIndexName(), createIndex.getTableName())) - .endOfStatement(); + writer.apply().appendStatement(platformDdl.createIndex(createIndex.getIndexName(), createIndex.getTableName(), split(createIndex.getColumns()))); + writer.dropAll().appendStatement(platformDdl.dropIndex(createIndex.getIndexName(), createIndex.getTableName())); } @Override public void generate(DdlWrite writer, DropIndex dropIndex) throws IOException { - - writer.apply() - .append(platformDdl.dropIndex(dropIndex.getIndexName(), dropIndex.getTableName())) - .endOfStatement(); + writer.apply().appendStatement(platformDdl.dropIndex(dropIndex.getIndexName(), dropIndex.getTableName())); } + @Override public void generate(DdlWrite writer, AddUniqueConstraint constraint) throws IOException { if (DdlHelp.isDropConstraint(constraint.getColumnNames())) { - String ddl = platformDdl.alterTableDropUniqueConstraint(constraint.getTableName(), constraint.getConstraintName()); - if (hasValue(ddl)) { - writer.apply().append(ddl).endOfStatement(); - } + writer.apply().appendStatement(platformDdl.alterTableDropUniqueConstraint(constraint.getTableName(), constraint.getConstraintName())); + } else { - String[] cols = SplitColumns.split(constraint.getColumnNames()); - String[] nullableColumns = SplitColumns.split(constraint.getNullableColumns()); - String ddl = platformDdl.alterTableAddUniqueConstraint(constraint.getTableName(), constraint.getConstraintName(), cols, nullableColumns); - if (hasValue(ddl)) { - writer.apply().append(ddl).endOfStatement(); - } + String[] cols = split(constraint.getColumnNames()); + String[] nullableColumns = split(constraint.getNullableColumns()); + writer.apply().appendStatement(platformDdl.alterTableAddUniqueConstraint(constraint.getTableName(), constraint.getConstraintName(), cols, nullableColumns)); } } @Override public void generate(DdlWrite writer, AlterForeignKey alterForeignKey) throws IOException { if (DdlHelp.isDropForeignKey(alterForeignKey.getColumnNames())) { - String ddl = platformDdl.alterTableDropForeignKey(alterForeignKey.getTableName(), alterForeignKey.getName()); - if (hasValue(ddl)) { - writer.apply().append(ddl).endOfStatement(); - } + writer.apply().appendStatement(platformDdl.alterTableDropForeignKey(alterForeignKey.getTableName(), alterForeignKey.getName())); } else { - String ddl = platformDdl.alterTableAddForeignKey(new WriteForeignKey(alterForeignKey)); - if (hasValue(ddl)) { - writer.apply().append(ddl).endOfStatement(); - } + writer.apply().appendStatement(platformDdl.alterTableAddForeignKey(new WriteForeignKey(alterForeignKey))); } } @@ -920,7 +871,7 @@ public class BaseTableDdl implements TableDdl { String ddl = platformDdl.alterColumnBaseAttributes(alter); if (hasValue(ddl)) { - writer.apply().append(ddl).endOfStatement(); + writer.apply().appendStatement(ddl); if (isTrue(alter.isWithHistory()) && alter.getType() != null && historySupport == HistorySupport.TRIGGER_BASED) { // mysql and sql server column type change allowing nulls in the history table column @@ -932,53 +883,41 @@ public class BaseTableDdl implements TableDdl { String histColumnDdl = platformDdl.alterColumnBaseAttributes(alterHistoryColumn); // write the apply to history table - writer.apply().append(histColumnDdl).endOfStatement(); + writer.apply().appendStatement(histColumnDdl); } } } protected void alterColumnDefaultValue(DdlWrite writer, AlterColumn alter) throws IOException { - String ddl = platformDdl.alterColumnDefaultValue(alter.getTableName(), alter.getColumnName(), alter.getDefaultValue()); - if (hasValue(ddl)) { - writer.apply().append(ddl).endOfStatement(); - } + writer.apply().appendStatement(platformDdl.alterColumnDefaultValue(alter.getTableName(), alter.getColumnName(), alter.getDefaultValue())); } protected void dropCheckConstraint(DdlWrite writer, AlterColumn alter, String constraintName) throws IOException { - String ddl = platformDdl.alterTableDropConstraint(alter.getTableName(), constraintName); - if (hasValue(ddl)) { - writer.apply().append(ddl).endOfStatement(); - } + writer.apply().appendStatement(platformDdl.alterTableDropConstraint(alter.getTableName(), constraintName)); } protected void addCheckConstraint(DdlWrite writer, AlterColumn alter) throws IOException { - String ddl = platformDdl.alterTableAddCheckConstraint(alter.getTableName(), alter.getCheckConstraintName(), alter.getCheckConstraint()); - if (hasValue(ddl)) { - writer.apply().append(ddl).endOfStatement(); - } + writer.apply().appendStatement(platformDdl.alterTableAddCheckConstraint(alter.getTableName(), alter.getCheckConstraintName(), alter.getCheckConstraint())); } protected void alterColumnNotnull(DdlWrite writer, AlterColumn alter) throws IOException { - String ddl = platformDdl.alterColumnNotnull(alter.getTableName(), alter.getColumnName(), alter.isNotnull()); - if (hasValue(ddl)) { - writer.apply().append(ddl).endOfStatement(); - } + writer.apply().appendStatement(platformDdl.alterColumnNotnull(alter.getTableName(), alter.getColumnName(), alter.isNotnull())); } protected void alterColumnType(DdlWrite writer, AlterColumn alter) throws IOException { String ddl = platformDdl.alterColumnType(alter.getTableName(), alter.getColumnName(), alter.getType()); if (hasValue(ddl)) { - writer.apply().append(ddl).endOfStatement(); + writer.apply().appendStatement(ddl); if (isTrue(alter.isWithHistory()) && historySupport == HistorySupport.TRIGGER_BASED) { regenerateHistoryTriggers(alter.getTableName(), HistoryTableUpdate.Change.ALTER, alter.getColumnName()); // apply same type change to matching column in the history table ddl = platformDdl.alterColumnType(historyTable(alter.getTableName()), alter.getColumnName(), alter.getType()); - writer.apply().append(ddl).endOfStatement(); + writer.apply().appendStatement(ddl); } } } @@ -990,17 +929,13 @@ public class BaseTableDdl implements TableDdl { protected void alterColumnDropForeignKey(DdlWrite writer, AlterColumn alter) throws IOException { - writer.apply() - .append(platformDdl.alterTableDropForeignKey(alter.getTableName(), alter.getDropForeignKey())) - .endOfStatement(); + writer.apply().appendStatement(platformDdl.alterTableDropForeignKey(alter.getTableName(), alter.getDropForeignKey())); } protected void alterColumnDropUniqueConstraint(DdlWrite writer, AlterColumn alter) throws IOException { - writer.apply() - .append(platformDdl.alterTableDropUniqueConstraint(alter.getTableName(), alter.getDropUnique())) - .endOfStatement(); + writer.apply().appendStatement(platformDdl.alterTableDropUniqueConstraint(alter.getTableName(), alter.getDropUnique())); } protected void alterColumnAddUniqueOneToOneConstraint(DdlWrite writer, AlterColumn alter) throws IOException { @@ -1017,13 +952,9 @@ public class BaseTableDdl implements TableDdl { String[] cols = {alter.getColumnName()}; boolean notNull = alter.isNotnull() != null ? alter.isNotnull() : Boolean.TRUE.equals(alter.isNotnull()); - writer.apply() - .append(platformDdl.alterTableAddUniqueConstraint(alter.getTableName(), uqName, cols, notNull ? null : cols)) - .endOfStatement(); + writer.apply().appendStatement(platformDdl.alterTableAddUniqueConstraint(alter.getTableName(), uqName, cols, notNull ? null : cols)); - writer.dropAllForeignKeys() - .append(platformDdl.dropIndex(uqName, alter.getTableName())) - .endOfStatement(); + writer.dropAllForeignKeys().appendStatement(platformDdl.dropIndex(uqName, alter.getTableName())); } diff --git a/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/ClickHouseDbArray.java b/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/ClickHouseDbArray.java new file mode 100644 index 000000000..ec141d7f0 --- /dev/null +++ b/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/ClickHouseDbArray.java @@ -0,0 +1,33 @@ +package io.ebeaninternal.dbmigration.ddlgeneration.platform; + +import java.util.HashMap; +import java.util.Map; + +/** + * Logical array type to ClickHouse array type conversion. + */ +class ClickHouseDbArray { + + private static final Map mapping = new HashMap<>(); + static { + mapping.put("uuid[]", "Array(UUID)"); + mapping.put("varchar[]", "Array(String)"); + mapping.put("integer[]", "Array(UInt32)"); + mapping.put("bigint[]", "Array(UInt64)"); + } + + /** + * Covert the 'logical' array type to a native one (for Postgres and Cockroach). + */ + static String logicalToNative(String logicalArrayType) { + int colonPos = logicalArrayType.indexOf(':'); + if (colonPos > -1) { + logicalArrayType = logicalArrayType.substring(0, colonPos); + } + String clickHouseType = mapping.get(logicalArrayType); + if (clickHouseType == null) { + throw new IllegalStateException("No mapping for logical array type " + logicalArrayType); + } + return clickHouseType; + } +} diff --git a/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/ClickHouseDdl.java b/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/ClickHouseDdl.java index 4907ce6f0..0c680f3eb 100644 --- a/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/ClickHouseDdl.java +++ b/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/ClickHouseDdl.java @@ -1,15 +1,30 @@ package io.ebeaninternal.dbmigration.ddlgeneration.platform; +import io.ebean.config.ServerConfig; import io.ebean.config.dbplatform.DatabasePlatform; import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer; +import io.ebeaninternal.dbmigration.ddlgeneration.DdlHandler; import java.io.IOException; public class ClickHouseDdl extends PlatformDdl { + private static final String LOG_TABLE = "ENGINE = Log()"; + public ClickHouseDdl(DatabasePlatform platform) { super(platform); this.includeStorageEngine = true; + this.identitySuffix = ""; + } + + @Override + public DdlHandler createDdlHandler(ServerConfig serverConfig) { + return new ClickHouseDdlHandler(serverConfig, this); + } + + @Override + protected String convertArrayType(String logicalArrayType) { + return ClickHouseDbArray.logicalToNative(logicalArrayType); } /** @@ -17,9 +32,38 @@ public class ClickHouseDdl extends PlatformDdl { */ @Override public void tableStorageEngine(DdlBuffer apply, String storageEngine) throws IOException { + if (storageEngine == null) { + // default to Log() table but really should all be explicit (need arguments for MergeTree etc) + storageEngine = LOG_TABLE; + } apply.append(" ").append(storageEngine); } + @Override + public String alterTableAddForeignKey(WriteForeignKey request) { + return null; + } + + @Override + public String alterTableDropForeignKey(String tableName, String fkName) { + return null; + } + + @Override + public String tableInlineForeignKey(WriteForeignKey request) { + return null; + } + + @Override + public String dropIndex(String indexName, String tableName) { + return null; + } + + @Override + public String createIndex(String indexName, String tableName, String[] columns) { + return null; + } + @Override protected void writeColumnNotNull(DdlBuffer buffer) { // do nothing diff --git a/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/ClickHouseDdlHandler.java b/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/ClickHouseDdlHandler.java new file mode 100644 index 000000000..2371cfaee --- /dev/null +++ b/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/ClickHouseDdlHandler.java @@ -0,0 +1,11 @@ +package io.ebeaninternal.dbmigration.ddlgeneration.platform; + +import io.ebean.config.ServerConfig; +import io.ebeaninternal.dbmigration.ddlgeneration.BaseDdlHandler; + +public class ClickHouseDdlHandler extends BaseDdlHandler { + + public ClickHouseDdlHandler(ServerConfig serverConfig, PlatformDdl platformDdl) { + super(serverConfig, platformDdl, new ClickHouseTableDdl(serverConfig, platformDdl)); + } +} diff --git a/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/ClickHouseTableDdl.java b/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/ClickHouseTableDdl.java new file mode 100644 index 000000000..b959d1ff7 --- /dev/null +++ b/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/ClickHouseTableDdl.java @@ -0,0 +1,34 @@ +package io.ebeaninternal.dbmigration.ddlgeneration.platform; + +import io.ebean.config.ServerConfig; +import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer; +import io.ebeaninternal.dbmigration.migration.CreateTable; + +public class ClickHouseTableDdl extends BaseTableDdl { + + public ClickHouseTableDdl(ServerConfig serverConfig, PlatformDdl platformDdl) { + super(serverConfig, platformDdl); + } + + @Override + protected void writePrimaryKeyConstraint(DdlBuffer buffer, String pkName, String[] pkColumns) { + // do nothing + } + + @Override + protected void writeCompoundUniqueConstraints(DdlBuffer apply, CreateTable createTable) { + // do nothing + } + + @Override + protected void writeUniqueConstraints(DdlBuffer apply, CreateTable createTable) { + // do nothing + } + + + @Override + protected void writeCheckConstraints(DdlBuffer apply, CreateTable createTable) { + // do nothing + } + +} diff --git a/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/MySqlDdl.java b/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/MySqlDdl.java index 4159bfb3d..eb69d3be3 100644 --- a/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/MySqlDdl.java +++ b/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/MySqlDdl.java @@ -104,7 +104,6 @@ public class MySqlDdl extends PlatformDdl { } buffer.append(String.format(" comment '%s'", comment)); } - } @Override diff --git a/src/test/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/BaseTableDdlTest.java b/src/test/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/BaseTableDdlTest.java index d36abb449..b141cd979 100644 --- a/src/test/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/BaseTableDdlTest.java +++ b/src/test/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/BaseTableDdlTest.java @@ -2,6 +2,7 @@ package io.ebeaninternal.dbmigration.ddlgeneration.platform; import io.ebean.config.ServerConfig; +import io.ebean.config.dbplatform.clickhouse.ClickHousePlatform; import io.ebean.config.dbplatform.h2.H2Platform; import io.ebean.config.dbplatform.mysql.MySqlPlatform; import io.ebean.config.dbplatform.oracle.OraclePlatform; @@ -62,6 +63,23 @@ public class BaseTableDdlTest { assertThat(ddl).contains("alter table mytable add column col_name varchar2(20)"); } + @Test + public void testAddColumn_withTypeConversion_clickHouseVarchar() throws IOException { + + ClickHouseTableDdl ddlGen = new ClickHouseTableDdl(serverConfig, PlatformDdlBuilder.create(new ClickHousePlatform())); + + DdlWrite write = new DdlWrite(); + + Column column = new Column(); + column.setName("col_name"); + column.setType("varchar(20)"); + + ddlGen.alterTableAddColumn(write.apply(), "mytable", column, false, false); + + String ddl = write.apply().getBuffer(); + assertThat(ddl).contains("alter table mytable add column col_name String"); + } + @Test public void testAlterColumnComment() throws IOException { diff --git a/src/test/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/ClickHouseDbArrayTest.java b/src/test/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/ClickHouseDbArrayTest.java new file mode 100644 index 000000000..181630396 --- /dev/null +++ b/src/test/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/ClickHouseDbArrayTest.java @@ -0,0 +1,24 @@ +package io.ebeaninternal.dbmigration.ddlgeneration.platform; + +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ClickHouseDbArrayTest { + + @Test + public void logicalToNative() { + + assertThat(ClickHouseDbArray.logicalToNative("uuid[]")).isEqualTo("Array(UUID)"); + assertThat(ClickHouseDbArray.logicalToNative("varchar[]")).isEqualTo("Array(String)"); + assertThat(ClickHouseDbArray.logicalToNative("integer[]")).isEqualTo("Array(UInt32)"); + assertThat(ClickHouseDbArray.logicalToNative("bigint[]")).isEqualTo("Array(UInt64)"); + } + + @Test + public void logicalToNative_withFallbackDefined() { + + assertThat(ClickHouseDbArray.logicalToNative("uuid[]:(1000)")).isEqualTo("Array(UUID)"); + } + +}