#1511 - Add SAP HANA support - format only changes

This commit is contained in:
rob bygrave
2018-10-24 21:49:48 +13:00
parent 158ee9a081
commit 2dbb5ea80d
7 changed files with 67 additions and 78 deletions
@@ -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());
}
}
@@ -266,6 +266,7 @@ public class DefaultDbMigration implements DbMigration {
* migration.generateMigration();
*
* }</pre>
*
* @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();
@@ -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));
}
}
@@ -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");
}
@@ -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());
@@ -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();
}
@@ -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);
}