diff --git a/src/main/java/io/ebean/config/dbplatform/hana/HanaPlatform.java b/src/main/java/io/ebean/config/dbplatform/hana/HanaPlatform.java index f266bb931..3e06d0094 100644 --- a/src/main/java/io/ebean/config/dbplatform/hana/HanaPlatform.java +++ b/src/main/java/io/ebean/config/dbplatform/hana/HanaPlatform.java @@ -11,13 +11,26 @@ import io.ebean.config.dbplatform.IdType; import io.ebean.config.dbplatform.SqlErrorCodes; public class HanaPlatform extends DatabasePlatform { + public HanaPlatform() { - this.basicSqlLimiter = new HanaBasicSqlLimiter(); - + this.platform = Platform.HANA; + this.sqlLimiter = new HanaSqlLimiter(); + this.persistBatchOnCascade = PersistBatch.NONE; + this.supportsResultSetConcurrencyModeUpdatable = false; this.columnAliasPrefix = null; + this.historySupport = new HanaHistorySupport(); + this.basicSqlLimiter = new HanaBasicSqlLimiter(); + + this.likeClauseRaw = "like ?"; + this.maxConstraintNameLength = 127; + this.maxTableNameLength = 127; + this.dbDefaultValue.setNow("current_timestamp"); + this.exceptionTranslator = new SqlErrorCodes().addAcquireLock("131", "133", "146") + .addDataIntegrity("130", "429", "461", "462").addDuplicateKey("144", "301", "349").build(); + this.dbIdentity.setIdType(IdType.IDENTITY); this.dbIdentity.setSelectLastInsertedIdTemplate("select current_identity_value() from sys.dummy"); this.dbIdentity.setSupportsGetGeneratedKeys(false); @@ -44,24 +57,6 @@ public class HanaPlatform extends DatabasePlatform { this.dbTypeMap.put(DbType.UUID, new DbPlatformType("varchar", 40)); this.dbTypeMap.put(DbType.VARBINARY, new DbPlatformType("varbinary", 255)); this.dbTypeMap.put(DbType.VARCHAR, new DbPlatformType("nvarchar", 255)); - - this.exceptionTranslator = new SqlErrorCodes().addAcquireLock("131", "133", "146") - .addDataIntegrity("130", "429", "461", "462").addDuplicateKey("144", "301", "349").build(); - - this.historySupport = new HanaHistorySupport(); - - this.likeClauseRaw = "like ?"; - - this.maxConstraintNameLength = 127; - this.maxTableNameLength = 127; - - this.persistBatchOnCascade = PersistBatch.NONE; - - this.platform = Platform.HANA; - - this.sqlLimiter = new HanaSqlLimiter(); - - this.supportsResultSetConcurrencyModeUpdatable = false; } @Override @@ -77,14 +72,14 @@ public class HanaPlatform extends DatabasePlatform { @Override protected String withForUpdate(String sql, ForUpdate forUpdateMode) { switch (forUpdateMode) { - case BASE: - return sql + " for update"; - case NOWAIT: - return sql + " for update nowait"; - case SKIPLOCKED: - return sql + " for update ignore locked"; - default: - throw new IllegalArgumentException("Unknown update mode: " + forUpdateMode.name()); + case BASE: + return sql + " for update"; + case NOWAIT: + return sql + " for update nowait"; + case SKIPLOCKED: + return sql + " for update ignore locked"; + default: + throw new IllegalArgumentException("Unknown update mode: " + forUpdateMode.name()); } } diff --git a/src/main/java/io/ebeaninternal/dbmigration/DefaultDbMigration.java b/src/main/java/io/ebeaninternal/dbmigration/DefaultDbMigration.java index 19817a924..5ae428a10 100644 --- a/src/main/java/io/ebeaninternal/dbmigration/DefaultDbMigration.java +++ b/src/main/java/io/ebeaninternal/dbmigration/DefaultDbMigration.java @@ -266,6 +266,7 @@ public class DefaultDbMigration implements DbMigration { * migration.generateMigration(); * * } + * * @return the generated migration or null */ @Override @@ -681,7 +682,7 @@ public class DefaultDbMigration implements DbMigration { case SQLITE: return new SQLitePlatform(); case HANA: - return new HanaPlatform(); + return new HanaPlatform(); case GENERIC: return new DatabasePlatform(); diff --git a/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/AbstractHanaDdl.java b/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/AbstractHanaDdl.java index b898c02a6..cd3b580b3 100644 --- a/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/AbstractHanaDdl.java +++ b/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/AbstractHanaDdl.java @@ -1,10 +1,5 @@ package io.ebeaninternal.dbmigration.ddlgeneration.platform; -import java.io.IOException; -import java.util.Objects; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - import io.ebean.config.ServerConfig; import io.ebean.config.dbplatform.DatabasePlatform; import io.ebean.config.dbplatform.DbPlatformType; @@ -12,10 +7,14 @@ import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer; import io.ebeaninternal.dbmigration.ddlgeneration.DdlHandler; import io.ebeaninternal.dbmigration.migration.AlterColumn; +import java.io.IOException; +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + public abstract class AbstractHanaDdl extends PlatformDdl { - private static final Pattern ARRAY_PATTERN = Pattern.compile("(\\w+)\\s*\\[\\s*\\]\\s*(\\(\\d+\\))?", - Pattern.CASE_INSENSITIVE); + private static final Pattern ARRAY_PATTERN = Pattern.compile("(\\w+)\\s*\\[\\s*\\]\\s*(\\(\\d+\\))?", Pattern.CASE_INSENSITIVE); public AbstractHanaDdl(DatabasePlatform platform) { super(platform); @@ -50,7 +49,7 @@ public abstract class AbstractHanaDdl extends PlatformDdl { boolean notnull = (alter.isNotnull() != null) ? alter.isNotnull() : Boolean.TRUE.equals(alter.isCurrentNotnull()); String notnullClause = notnull ? " not null" : ""; String defaultValue = DdlHelp.isDropDefault(alter.getDefaultValue()) ? "null" - : (alter.getDefaultValue() != null ? alter.getDefaultValue() : alter.getCurrentDefaultValue()); + : (alter.getDefaultValue() != null ? alter.getDefaultValue() : alter.getCurrentDefaultValue()); String defaultValueClause = (defaultValue == null || defaultValue.isEmpty()) ? "" : " default " + defaultValue; try { @@ -60,18 +59,19 @@ public abstract class AbstractHanaDdl extends PlatformDdl { if (isNumberType(currentType)) { // numbers can always be converted to decimal buffer.append("alter table ").append(tableName).append(" ").append(alterColumn).append(" ").append(columnName) - .append(" decimal ").append(defaultValueClause).append(notnullClause).append(alterColumnSuffix) - .endOfStatement(); + .append(" decimal ").append(defaultValueClause).append(notnullClause).append(alterColumnSuffix) + .endOfStatement(); + } else if (isStringType(currentType)) { // strings can always be converted to nclob buffer.append("alter table ").append(tableName).append(" ").append(alterColumn).append(" ").append(columnName) - .append(" nclob ").append(defaultValueClause).append(notnullClause).append(alterColumnSuffix) - .endOfStatement(); + .append(" nclob ").append(defaultValueClause).append(notnullClause).append(alterColumnSuffix) + .endOfStatement(); } } buffer.append("alter table ").append(tableName).append(" ").append(alterColumn).append(" ").append(columnName) - .append(" ").append(type).append(defaultValueClause).append(notnullClause).append(alterColumnSuffix); + .append(" ").append(type).append(defaultValueClause).append(notnullClause).append(alterColumnSuffix); return buffer.getBuffer(); } catch (IOException e) { @@ -110,8 +110,7 @@ public abstract class AbstractHanaDdl extends PlatformDdl { } @Override - public String alterTableAddUniqueConstraint(String tableName, String uqName, String[] columns, - String[] nullableColumns) { + public String alterTableAddUniqueConstraint(String tableName, String uqName, String[] columns, String[] nullableColumns) { if (nullableColumns == null || nullableColumns.length == 0) { return super.alterTableAddUniqueConstraint(tableName, uqName, columns, nullableColumns); } else { @@ -128,7 +127,7 @@ public abstract class AbstractHanaDdl extends PlatformDdl { buffer.append("begin").newLine(); buffer.append("declare exit handler for sql_error_code 397 begin end").endOfStatement(); buffer.append("exec 'alter table ").append(tableName).append(" ").append(dropUniqueConstraint).append(" ") - .append(maxConstraintName(uniqueConstraintName)).append("'").endOfStatement(); + .append(maxConstraintName(uniqueConstraintName)).append("'").endOfStatement(); buffer.append("end").endOfStatement(); buffer.append("$$"); return buffer.getBuffer(); @@ -136,7 +135,7 @@ public abstract class AbstractHanaDdl extends PlatformDdl { throw new RuntimeException(e); } } - + @Override public String alterTableDropConstraint(String tableName, String constraintName) { return alterTableDropUniqueConstraint(tableName, constraintName); @@ -149,13 +148,13 @@ public abstract class AbstractHanaDdl extends PlatformDdl { @Override public void alterTableDropColumn(DdlBuffer buffer, String tableName, String columnName) throws IOException { buffer.append("CALL usp_ebean_drop_column('").append(tableName).append("', '").append(columnName).append("')") - .endOfStatement(); + .endOfStatement(); } /** * Check if a data type can be converted to another data type. Data types can't * be converted if the target type has a lower precision than the source type. - * + * * @param sourceType The source data type * @param targetType the target data type * @return {@code true} if the type can be converted, {@code false} otherwise @@ -204,7 +203,7 @@ public abstract class AbstractHanaDdl extends PlatformDdl { DbPlatformType dbPlatformTargetType = DbPlatformType.parse(targetType); if ("decimal".equals(dbPlatformTargetType.getName())) { if (dbPlatformSourceType.getDefaultLength() > dbPlatformTargetType.getDefaultLength() - || dbPlatformSourceType.getDefaultScale() > dbPlatformTargetType.getDefaultScale()) { + || dbPlatformSourceType.getDefaultScale() > dbPlatformTargetType.getDefaultScale()) { return false; } } @@ -215,12 +214,12 @@ public abstract class AbstractHanaDdl extends PlatformDdl { private boolean isNumberType(String type) { return type != null - && ("bigint".equals(type) || "integer".equals(type) || "smallint".equals(type) || "tinyint".equals(type) - || type.startsWith("float") || "real".equals(type) || "double".equals(type) || type.startsWith("decimal")); + && ("bigint".equals(type) || "integer".equals(type) || "smallint".equals(type) || "tinyint".equals(type) + || type.startsWith("float") || "real".equals(type) || "double".equals(type) || type.startsWith("decimal")); } private boolean isStringType(String type) { return type != null - && (type.startsWith("varchar") || type.startsWith("nvarchar") || "clob".equals(type) || "nclob".equals(type)); + && (type.startsWith("varchar") || type.startsWith("nvarchar") || "clob".equals(type) || "nclob".equals(type)); } } diff --git a/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/HanaHistoryDdl.java b/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/HanaHistoryDdl.java index 0ea165ba3..9fd37416f 100644 --- a/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/HanaHistoryDdl.java +++ b/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/HanaHistoryDdl.java @@ -1,11 +1,5 @@ package io.ebeaninternal.dbmigration.ddlgeneration.platform; -import java.io.IOException; -import java.util.Collection; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicInteger; - import io.ebean.config.ServerConfig; import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer; import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite; @@ -14,6 +8,12 @@ import io.ebeaninternal.dbmigration.migration.DropHistoryTable; import io.ebeaninternal.dbmigration.model.MColumn; import io.ebeaninternal.dbmigration.model.MTable; +import java.io.IOException; +import java.util.Collection; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; + public class HanaHistoryDdl implements PlatformHistoryDdl { private String systemPeriodStart; @@ -47,7 +47,7 @@ public class HanaHistoryDdl implements PlatformHistoryDdl { for (MColumn column : cols) { if (!column.isDraftOnly()) { writeColumnDefinition(apply, column.getName(), column.getType(), column.getDefaultValue(), column.isNotnull(), - column.isIdentity() ? platformDdl.identitySuffix : null); + column.isIdentity() ? platformDdl.identitySuffix : null); apply.append(",").newLine(); } } @@ -58,13 +58,12 @@ public class HanaHistoryDdl implements PlatformHistoryDdl { // enable system versioning apply.append("alter table ").append(tableName).append(" add (").newLine(); - apply.append(" ").append(systemPeriodStart).append(" TIMESTAMP NOT NULL GENERATED ALWAYS AS ROW START, ") - .newLine(); + apply.append(" ").append(systemPeriodStart).append(" TIMESTAMP NOT NULL GENERATED ALWAYS AS ROW START, ").newLine(); apply.append(" ").append(systemPeriodEnd).append(" TIMESTAMP NOT NULL GENERATED ALWAYS AS ROW END").newLine(); apply.append(")").endOfStatement(); apply.append("alter table ").append(tableName).append(" add period for system_time(").append(systemPeriodStart) - .append(",").append(systemPeriodEnd).append(")").endOfStatement(); + .append(",").append(systemPeriodEnd).append(")").endOfStatement(); enableSystemVersioning(apply, tableName, historyTableName, true, false); @@ -76,7 +75,7 @@ public class HanaHistoryDdl implements PlatformHistoryDdl { @Override public void dropHistoryTable(DdlWrite writer, DropHistoryTable dropHistoryTable) throws IOException { dropHistoryTable(writer.applyDropDependencies(), dropHistoryTable.getBaseTable(), - dropHistoryTable.getBaseTable() + historySuffix); + dropHistoryTable.getBaseTable() + historySuffix); } protected void dropHistoryTable(DdlBuffer apply, String baseTable, String historyTable) throws IOException { @@ -87,7 +86,7 @@ public class HanaHistoryDdl implements PlatformHistoryDdl { // drop the period columns apply.append("alter table ").append(baseTable).append(" drop (").append(systemPeriodStart).append(",") - .append(systemPeriodEnd).append(")").endOfStatement(); + .append(systemPeriodEnd).append(")").endOfStatement(); // drop the history table apply.append("drop table ").append(historyTable).append(" cascade").endOfStatement(); @@ -97,19 +96,18 @@ public class HanaHistoryDdl implements PlatformHistoryDdl { public void addHistoryTable(DdlWrite writer, AddHistoryTable addHistoryTable) throws IOException { MTable table = writer.getTable(addHistoryTable.getBaseTable()); if (table == null) { - throw new IllegalStateException( - "MTable " + addHistoryTable.getBaseTable() + " not found in writer? (required for history DDL)"); + throw new IllegalStateException("MTable " + addHistoryTable.getBaseTable() + " not found in writer? (required for history DDL)"); } createWithHistory(writer, table); } @Override - public void updateTriggers(DdlWrite write, HistoryTableUpdate baseTable) throws IOException { + public void updateTriggers(DdlWrite write, HistoryTableUpdate baseTable) { // nothing to do } protected void writeColumnDefinition(DdlBuffer buffer, String columnName, String type, String defaultValue, - boolean isNotNull, String generated) throws IOException { + boolean isNotNull, String generated) throws IOException { String platformType = platformDdl.convert(type, false); buffer.append(" ").append(platformDdl.lowerColumnName(columnName)); @@ -140,9 +138,8 @@ public class HanaHistoryDdl implements PlatformHistoryDdl { } public void enableSystemVersioning(DdlBuffer apply, String tableName, String historyTableName, boolean validated, - boolean uniqueStatement) throws IOException { - apply.append("alter table ").append(tableName).append(" add system versioning history table ") - .append(historyTableName); + boolean uniqueStatement) throws IOException { + apply.append("alter table ").append(tableName).append(" add system versioning history table ").append(historyTableName); if (!validated) { apply.append(" not validated"); } diff --git a/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/HanaTableDdl.java b/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/HanaTableDdl.java index 1d0b47abc..943dc3ecd 100644 --- a/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/HanaTableDdl.java +++ b/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/HanaTableDdl.java @@ -21,8 +21,7 @@ public class HanaTableDdl extends BaseTableDdl { super(serverConfig, platformDdl); this.historyDdl = (HanaHistoryDdl) platformDdl.historyDdl; if (serverConfig.getProperties() != null) { - PropertiesWrapper wrapper = new PropertiesWrapper("ebean", "hana", serverConfig.getProperties(), - serverConfig.getClassLoadConfig()); + PropertiesWrapper wrapper = new PropertiesWrapper("ebean", "hana", serverConfig.getProperties(), serverConfig.getClassLoadConfig()); this.generateUniqueDdl = wrapper.getBoolean("generateUniqueDdl", false); } else { this.generateUniqueDdl = false; @@ -86,8 +85,7 @@ public class HanaTableDdl extends BaseTableDdl { if (manageSystemVersioning) { // make same changes to the history table String historyTable = historyTable(tableName); - if (hasValue(alterColumn.getType()) || hasValue(alterColumn.getDefaultValue()) - || alterColumn.isNotnull() != null) { + if (hasValue(alterColumn.getType()) || hasValue(alterColumn.getDefaultValue()) || alterColumn.isNotnull() != null) { AlterColumn alterHistoryColumn = new AlterColumn(); alterHistoryColumn.setTableName(historyTable); alterHistoryColumn.setColumnName(alterColumn.getColumnName()); diff --git a/src/main/java/io/ebeaninternal/server/core/DatabasePlatformFactory.java b/src/main/java/io/ebeaninternal/server/core/DatabasePlatformFactory.java index acf955620..b5a5b6ef5 100644 --- a/src/main/java/io/ebeaninternal/server/core/DatabasePlatformFactory.java +++ b/src/main/java/io/ebeaninternal/server/core/DatabasePlatformFactory.java @@ -160,7 +160,7 @@ public class DatabasePlatformFactory { return new DB2Platform(); } else if (dbProductName.contains("sql anywhere")) { return new SqlAnywherePlatform(); - }else if (dbProductName.contains("hdb")) { + } else if (dbProductName.contains("hdb")) { return new HanaPlatform(); } diff --git a/src/main/java/io/ebeaninternal/server/expression/platform/HanaDbExpression.java b/src/main/java/io/ebeaninternal/server/expression/platform/HanaDbExpression.java index 0593bdb84..a6633edfa 100644 --- a/src/main/java/io/ebeaninternal/server/expression/platform/HanaDbExpression.java +++ b/src/main/java/io/ebeaninternal/server/expression/platform/HanaDbExpression.java @@ -10,8 +10,7 @@ import io.ebeaninternal.server.expression.Op; public class HanaDbExpression extends BaseDbExpression { @Override - public void bitwise(SpiExpressionRequest request, String propName, BitwiseOp operator, long flags, String compare, - long match) { + public void bitwise(SpiExpressionRequest request, String propName, BitwiseOp operator, long flags, String compare, long match) { bitwiseFunction(request, propName, operator, compare); }