diff --git a/pom.xml b/pom.xml index 13929a872..242137203 100644 --- a/pom.xml +++ b/pom.xml @@ -111,13 +111,13 @@ io.ebean persistence-api - 2.2.1 + 2.2.2 io.ebean ebean-annotation - 4.6 + 4.7 diff --git a/src/main/java/io/ebean/config/dbplatform/clickhouse/ClickHousePlatform.java b/src/main/java/io/ebean/config/dbplatform/clickhouse/ClickHousePlatform.java new file mode 100644 index 000000000..1a1d45a79 --- /dev/null +++ b/src/main/java/io/ebean/config/dbplatform/clickhouse/ClickHousePlatform.java @@ -0,0 +1,52 @@ +package io.ebean.config.dbplatform.clickhouse; + +import io.ebean.annotation.Platform; +import io.ebean.config.dbplatform.DatabasePlatform; +import io.ebean.config.dbplatform.DbPlatformType; +import io.ebean.config.dbplatform.DbType; +import io.ebean.config.dbplatform.IdType; + +import java.sql.Types; + +public class ClickHousePlatform extends DatabasePlatform { + + public ClickHousePlatform() { + super(); + this.platform = Platform.CLICKHOUSE; + //this.dbEncrypt = + //this.historySupport = + //this.exceptionTranslator = + + this.nativeUuidType = true; + this.dbDefaultValue.setNow("now()"); + this.columnAliasPrefix = null; + + this.dbIdentity.setIdType(IdType.IDENTITY); + this.dbIdentity.setSupportsGetGeneratedKeys(false); + this.dbIdentity.setSupportsSequence(false); + this.dbIdentity.setSupportsIdentity(true); + + this.booleanDbType = Types.INTEGER; + dbTypeMap.put(DbType.BOOLEAN, new DbPlatformType("UInt8")); + + // using unsigned as default types ... + dbTypeMap.put(DbType.TINYINT, new DbPlatformType("UInt8", false)); + 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", 16,4)); + dbTypeMap.put(DbType.DOUBLE, new DbPlatformType("Float64", 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/DdlGenerator.java b/src/main/java/io/ebeaninternal/dbmigration/DdlGenerator.java index 64af8454f..fd533a8fd 100644 --- a/src/main/java/io/ebeaninternal/dbmigration/DdlGenerator.java +++ b/src/main/java/io/ebeaninternal/dbmigration/DdlGenerator.java @@ -189,7 +189,7 @@ public class DdlGenerator { runScript(connection, false, createAllContent, getCreateFileName()); if (extraDdl && jaxbPresent) { - if (currentModel.isTablePartitioning()) { + if (currentModel().isTablePartitioning()) { String extraPartitioning = ExtraDdlXmlReader.buildPartitioning(server.getDatabasePlatform().getName()); if (extraPartitioning != null && !extraPartitioning.isEmpty()) { runScript(connection, false, extraPartitioning, "builtin-partitioning-ddl"); @@ -201,7 +201,7 @@ public class DdlGenerator { runScript(connection, false, extraApply, "extra-ddl"); } - if (currentModel.isTablePartitioning()) { + if (currentModel().isTablePartitioning()) { checkInitialTablePartitions(connection); } } diff --git a/src/main/java/io/ebeaninternal/dbmigration/DefaultDbMigration.java b/src/main/java/io/ebeaninternal/dbmigration/DefaultDbMigration.java index 6c40cd09b..464fdfbdc 100644 --- a/src/main/java/io/ebeaninternal/dbmigration/DefaultDbMigration.java +++ b/src/main/java/io/ebeaninternal/dbmigration/DefaultDbMigration.java @@ -8,6 +8,8 @@ import io.ebean.config.DbMigrationConfig; import io.ebean.config.PlatformConfig; import io.ebean.config.ServerConfig; import io.ebean.config.dbplatform.DatabasePlatform; +import io.ebean.config.dbplatform.clickhouse.ClickHousePlatform; +import io.ebean.config.dbplatform.cockroach.CockroachPlatform; import io.ebean.config.dbplatform.db2.DB2Platform; import io.ebean.config.dbplatform.h2.H2Platform; import io.ebean.config.dbplatform.hana.HanaPlatform; @@ -802,6 +804,11 @@ public class DefaultDbMigration implements DbMigration { return new SQLitePlatform(); case HANA: return new HanaPlatform(); + case COCKROACH: + return new CockroachPlatform(); + case CLICKHOUSE: + return new ClickHousePlatform(); + case GENERIC: return new DatabasePlatform(); 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 859c73399..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(); @@ -276,6 +276,7 @@ public class BaseTableDdl implements TableDdl { } apply.newLine().append(")"); + addTableStorageEngine(apply, createTable); addTableCommentInline(apply, createTable); if (partitionMode != null) { platformDdl.addTablePartition(apply, partitionMode, createTable.getPartitionColumn()); @@ -316,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()); } @@ -329,6 +329,15 @@ public class BaseTableDdl implements TableDdl { } } + /** + * Add the table storage engine clause. + */ + private void addTableStorageEngine(DdlBuffer apply, CreateTable createTable) throws IOException { + if (platformDdl.isIncludeStorageEngine()) { + platformDdl.tableStorageEngine(apply, createTable.getStorageEngine()); + } + } + /** * Add the table comment inline with the create table statement. */ @@ -358,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)); } } @@ -394,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)); } } @@ -425,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); } @@ -434,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); } } @@ -448,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)); } } @@ -466,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(); @@ -486,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 { @@ -503,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)); } /** @@ -517,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)); } /** @@ -525,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); @@ -548,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); @@ -650,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))); } } @@ -907,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 @@ -919,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); } } } @@ -977,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 { @@ -1004,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 new file mode 100644 index 000000000..0c680f3eb --- /dev/null +++ b/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/ClickHouseDdl.java @@ -0,0 +1,86 @@ +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); + } + + /** + * Add an table storage engine to the create table statement. + */ + @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 + } + + @Override + public void addTableComment(DdlBuffer apply, String tableName, String tableComment) { + // do nothing + } + + @Override + public void addColumnComment(DdlBuffer apply, String table, String column, String comment) { + // do nothing + } + + @Override + public boolean isInlineComments() { + return false; + } +} 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/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PlatformDdl.java b/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PlatformDdl.java index f6a65da81..d76c6bd44 100644 --- a/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PlatformDdl.java +++ b/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PlatformDdl.java @@ -118,6 +118,8 @@ public class PlatformDdl { */ protected boolean inlineForeignKeys; + protected boolean includeStorageEngine; + protected final DbDefaultValue dbDefaultValue; protected String fallbackArrayType = "varchar(1000)"; @@ -191,6 +193,13 @@ public class PlatformDdl { return inlineComments; } + /** + * Return true if the platform includes storage engine clause. + */ + public boolean isIncludeStorageEngine() { + return includeStorageEngine; + } + /** * Return true if foreign key reference constraints need to inlined with create table. * Ideally we don't do this as then the constraints are not named. Do this for SQLite. @@ -230,13 +239,20 @@ public class PlatformDdl { } } if (isTrue(column.isNotnull()) || isTrue(column.isPrimaryKey())) { - buffer.append(" not null"); + writeColumnNotNull(buffer); } // add check constraints later as we really want to give them a nice name // so that the database can potentially provide a nice SQL error } + /** + * Allow for platform overriding (e.g. ClickHouse). + */ + protected void writeColumnNotNull(DdlBuffer buffer) throws IOException { + buffer.append(" not null"); + } + /** * Convert the DB column default literal to platform specific. */ @@ -409,13 +425,17 @@ public class PlatformDdl { } protected String translate(ConstraintMode mode) { - switch(mode) { - case SET_NULL: return "set null"; - case SET_DEFAULT: return "set default"; - case RESTRICT: return "restrict"; - case CASCADE: return "cascade"; + switch (mode) { + case SET_NULL: + return "set null"; + case SET_DEFAULT: + return "set default"; + case RESTRICT: + return "restrict"; + case CASCADE: + return "cascade"; default: - throw new IllegalStateException("Unknown mode "+mode); + throw new IllegalStateException("Unknown mode " + mode); } } @@ -465,7 +485,7 @@ public class PlatformDdl { if (!onHistoryTable) { if (isTrue(column.isNotnull())) { - buffer.append(" not null"); + writeColumnNotNull(buffer); } buffer.append(addColumnSuffix); buffer.endOfStatement(); @@ -473,7 +493,7 @@ public class PlatformDdl { // check constraints cannot be added in one statement for h2 if (!StringHelper.isNull(column.getCheckConstraint())) { String ddl = alterTableAddCheckConstraint(tableName, column.getCheckConstraintName(), - column.getCheckConstraint()); + column.getCheckConstraint()); buffer.append(ddl).endOfStatement(); } } else { @@ -485,7 +505,7 @@ public class PlatformDdl { public void alterTableDropColumn(DdlBuffer buffer, String tableName, String columnName) throws IOException { buffer.append("alter table ").append(tableName).append(" ").append(dropColumn).append(" ").append(columnName) - .append(dropColumnSuffix).endOfStatement(); + .append(dropColumnSuffix).endOfStatement(); } /** @@ -607,6 +627,13 @@ public class PlatformDdl { // do nothing by default (MySql only) } + /** + * Add an table storage engine to the create table statement. + */ + public void tableStorageEngine(DdlBuffer apply, String storageEngine) throws IOException { + // do nothing by default + } + /** * Add table comment as a separate statement (from the create table statement). */ @@ -643,10 +670,10 @@ public class PlatformDdl { /** * Shortens the given name to the maximum constraint name length of the platform in a deterministic way. - * + *

* First, all vowels are removed, If the string is still to long, 31 bits are taken from the hash code * of the string and base36 encoded (10 digits and 26 chars) string. - * + *

* As 36^6 > 31^2, the resulting string is never longer as 6 chars. */ protected String maxConstraintName(String name) { @@ -654,7 +681,7 @@ public class PlatformDdl { int hash = name.hashCode() & 0x7FFFFFFF; name = VowelRemover.trim(name, 4); if (name.length() > platform.getMaxConstraintNameLength()) { - return name.substring(0, platform.getMaxConstraintNameLength()-7) + "_" + Integer.toString(hash, 36); + return name.substring(0, platform.getMaxConstraintNameLength() - 7) + "_" + Integer.toString(hash, 36); } } return name; diff --git a/src/main/java/io/ebeaninternal/dbmigration/migration/CreateTable.java b/src/main/java/io/ebeaninternal/dbmigration/migration/CreateTable.java index cf27b1ce0..c088ffc09 100644 --- a/src/main/java/io/ebeaninternal/dbmigration/migration/CreateTable.java +++ b/src/main/java/io/ebeaninternal/dbmigration/migration/CreateTable.java @@ -77,6 +77,8 @@ public class CreateTable { protected BigInteger sequenceAllocate; @XmlAttribute(name = "pkName") protected String pkName; + @XmlAttribute(name = "storageEngine") + protected String storageEngine; @XmlAttribute(name = "tablespace") protected String tablespace; @XmlAttribute(name = "indexTablespace") @@ -365,6 +367,26 @@ public class CreateTable { this.pkName = value; } + /** + * Gets the value of the storageEngine property. + * + * @return possible object is + * {@link String } + */ + public String getStorageEngine() { + return storageEngine; + } + + /** + * Sets the value of the storageEngine property. + * + * @param value allowed object is + * {@link String } + */ + public void setStorageEngine(String value) { + this.storageEngine = value; + } + /** * Gets the value of the tablespace property. * diff --git a/src/main/java/io/ebeaninternal/dbmigration/model/CurrentModel.java b/src/main/java/io/ebeaninternal/dbmigration/model/CurrentModel.java index b3f783a0b..e37ca0377 100644 --- a/src/main/java/io/ebeaninternal/dbmigration/model/CurrentModel.java +++ b/src/main/java/io/ebeaninternal/dbmigration/model/CurrentModel.java @@ -67,14 +67,14 @@ public class CurrentModel { * Return true if the model contains tables that are partitioned. */ public boolean isTablePartitioning() { - return model.isTablePartitioning(); + return read().isTablePartitioning(); } /** * Return the tables that have partitioning. */ public List getPartitionedTables() { - return model.getPartitionedTables(); + return read().getPartitionedTables(); } private static DbConstraintNaming.MaxLength maxLength(SpiEbeanServer server, DbConstraintNaming naming) { diff --git a/src/main/java/io/ebeaninternal/dbmigration/model/MTable.java b/src/main/java/io/ebeaninternal/dbmigration/model/MTable.java index 2a6b0a8b3..c80281472 100644 --- a/src/main/java/io/ebeaninternal/dbmigration/model/MTable.java +++ b/src/main/java/io/ebeaninternal/dbmigration/model/MTable.java @@ -79,6 +79,8 @@ public class MTable { */ private String tablespace; + private String storageEngine; + /** * Tablespace to use for indexes on this table. */ @@ -159,6 +161,7 @@ public class MTable { this.name = createTable.getName(); this.pkName = createTable.getPkName(); this.comment = createTable.getComment(); + this.storageEngine = createTable.getStorageEngine(); this.tablespace = createTable.getTablespace(); this.indexTablespace = createTable.getIndexTablespace(); this.withHistory = Boolean.TRUE.equals(createTable.isWithHistory()); @@ -244,6 +247,7 @@ public class MTable { createTable.setPartitionMode(partitionMeta.getMode().name()); createTable.setPartitionColumn(partitionMeta.getProperty()); } + createTable.setStorageEngine(storageEngine); createTable.setTablespace(tablespace); createTable.setIndexTablespace(indexTablespace); createTable.setSequenceName(sequenceName); @@ -452,6 +456,10 @@ public class MTable { this.comment = comment; } + public void setStorageEngine(String storageEngine) { + this.storageEngine = storageEngine; + } + public String getTablespace() { return tablespace; } diff --git a/src/main/java/io/ebeaninternal/dbmigration/model/build/ModelBuildBeanVisitor.java b/src/main/java/io/ebeaninternal/dbmigration/model/build/ModelBuildBeanVisitor.java index 8ac300074..9b6e3147e 100644 --- a/src/main/java/io/ebeaninternal/dbmigration/model/build/ModelBuildBeanVisitor.java +++ b/src/main/java/io/ebeaninternal/dbmigration/model/build/ModelBuildBeanVisitor.java @@ -36,6 +36,7 @@ public class ModelBuildBeanVisitor implements BeanVisitor { } MTable table = new MTable(descriptor.getBaseTable()); + table.setStorageEngine(descriptor.getStorageEngine()); table.setPartitionMeta(descriptor.getPartitionMeta()); table.setComment(descriptor.getDbComment()); if (descriptor.isHistorySupport()) { diff --git a/src/main/java/io/ebeaninternal/server/core/DatabasePlatformFactory.java b/src/main/java/io/ebeaninternal/server/core/DatabasePlatformFactory.java index b5a5b6ef5..9cd221c92 100644 --- a/src/main/java/io/ebeaninternal/server/core/DatabasePlatformFactory.java +++ b/src/main/java/io/ebeaninternal/server/core/DatabasePlatformFactory.java @@ -2,6 +2,7 @@ package io.ebeaninternal.server.core; import io.ebean.config.ServerConfig; import io.ebean.config.dbplatform.DatabasePlatform; +import io.ebean.config.dbplatform.clickhouse.ClickHousePlatform; import io.ebean.config.dbplatform.cockroach.CockroachPlatform; import io.ebean.config.dbplatform.db2.DB2Platform; import io.ebean.config.dbplatform.h2.H2Platform; @@ -104,6 +105,9 @@ public class DatabasePlatformFactory { if (dbName.equals("db2")) { return new DB2Platform(); } + if (dbName.equals("clickhouse")) { + return new ClickHousePlatform(); + } if (dbName.equals("sqlite")) { return new SQLitePlatform(); } @@ -162,6 +166,8 @@ public class DatabasePlatformFactory { return new SqlAnywherePlatform(); } else if (dbProductName.contains("hdb")) { return new HanaPlatform(); + } else if (dbProductName.contains("clickhouse")) { + return new ClickHousePlatform(); } // use the standard one diff --git a/src/main/java/io/ebeaninternal/server/core/PlatformDdlBuilder.java b/src/main/java/io/ebeaninternal/server/core/PlatformDdlBuilder.java index dbf657c49..34e696735 100644 --- a/src/main/java/io/ebeaninternal/server/core/PlatformDdlBuilder.java +++ b/src/main/java/io/ebeaninternal/server/core/PlatformDdlBuilder.java @@ -1,6 +1,7 @@ package io.ebeaninternal.server.core; import io.ebean.config.dbplatform.DatabasePlatform; +import io.ebeaninternal.dbmigration.ddlgeneration.platform.ClickHouseDdl; import io.ebeaninternal.dbmigration.ddlgeneration.platform.CockroachDdl; import io.ebeaninternal.dbmigration.ddlgeneration.platform.DB2Ddl; import io.ebeaninternal.dbmigration.ddlgeneration.platform.H2Ddl; @@ -50,6 +51,8 @@ public class PlatformDdlBuilder { return new SqlServerDdl(platform); case HANA: return new HanaColumnStoreDdl(platform); + case CLICKHOUSE: + return new ClickHouseDdl(platform); default: return new PlatformDdl(platform); } diff --git a/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java b/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java index 8add0f49a..7d3cba9c1 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java +++ b/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java @@ -211,6 +211,7 @@ public class BeanDescriptor implements BeanType, STreeType { private final String draftTable; private final PartitionMeta partitionMeta; + private final String storageEngine; /** * DB table comment. @@ -492,6 +493,7 @@ public class BeanDescriptor implements BeanType, STreeType { this.dependentTables = deploy.getDependentTables(); this.dbComment = deploy.getDbComment(); this.partitionMeta = deploy.getPartitionMeta(); + this.storageEngine = deploy.getStorageEngine(); this.autoTunable = EntityType.ORM == entityType && (beanFinder == null); // helper object used to derive lists of properties @@ -1970,10 +1972,10 @@ public class BeanDescriptor implements BeanType, STreeType { DefaultOrmQuery query = new DefaultOrmQuery<>(this, ebeanServer, ebeanServer.getExpressionFactory()); query.setPersistenceContext(pc); return query - // .select(getIdProperty().getName()) - // we do not select the id because we - // probably have to load the entire bean - .setId(id).findOne(); + // .select(getIdProperty().getName()) + // we do not select the id because we + // probably have to load the entire bean + .setId(id).findOne(); } /** @@ -2874,6 +2876,13 @@ public class BeanDescriptor implements BeanType, STreeType { return partitionMeta; } + /** + * Return the storage engine. + */ + public String getStorageEngine() { + return storageEngine; + } + /** * Return the dependent tables for a view based entity. *

diff --git a/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanDescriptor.java b/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanDescriptor.java index 18873232a..b43b0d6fc 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanDescriptor.java +++ b/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanDescriptor.java @@ -136,6 +136,8 @@ public class DeployBeanDescriptor { private List indexDefinitions; + private String storageEngine; + /** * The base database table. */ @@ -275,6 +277,14 @@ public class DeployBeanDescriptor { return Modifier.isAbstract(beanType.getModifiers()); } + public void setStorageEngine(String storageEngine) { + this.storageEngine = storageEngine; + } + + public String getStorageEngine() { + return storageEngine; + } + /** * Set to true for @History entity beans that have history. */ @@ -315,7 +325,7 @@ public class DeployBeanDescriptor { this.partitionMeta = partitionMeta; } - public PartitionMeta getPartitionMeta() { + public PartitionMeta getPartitionMeta() { if (partitionMeta != null) { DeployBeanProperty beanProperty = getBeanProperty(partitionMeta.getProperty()); if (beanProperty != null) { diff --git a/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationClass.java b/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationClass.java index 083d04b61..657c94797 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationClass.java +++ b/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationClass.java @@ -10,6 +10,7 @@ import io.ebean.annotation.History; import io.ebean.annotation.Index; import io.ebean.annotation.InvalidateQueryCache; import io.ebean.annotation.ReadAudit; +import io.ebean.annotation.StorageEngine; import io.ebean.annotation.UpdateMode; import io.ebean.annotation.View; import io.ebean.config.TableName; @@ -154,6 +155,11 @@ public class AnnotationClass extends AnnotationParser { } } + StorageEngine storage = AnnotationUtil.findAnnotationRecursive(cls, StorageEngine.class); + if (storage != null) { + descriptor.setStorageEngine(storage.value()); + } + DbPartition partition = AnnotationUtil.findAnnotationRecursive(cls, DbPartition.class); if (partition != null) { descriptor.setPartitionMeta(new PartitionMeta(partition.mode(), partition.property())); diff --git a/src/main/resources/ebean-dbmigration-1.0.xsd b/src/main/resources/ebean-dbmigration-1.0.xsd index a78d2fade..3066f38b1 100644 --- a/src/main/resources/ebean-dbmigration-1.0.xsd +++ b/src/main/resources/ebean-dbmigration-1.0.xsd @@ -116,6 +116,7 @@ + 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)"); + } + +}