mirror of
https://github.com/ebean-orm/ebean.git
synced 2026-10-27 00:02:42 +00:00
#1788 - ENH: Add support for NuoDB database platform
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
package io.ebean.config.dbplatform.nuodb;
|
||||
|
||||
import io.ebean.config.dbplatform.DbViewHistorySupport;
|
||||
|
||||
/**
|
||||
* Runtime support for @History with NuoDB.
|
||||
*/
|
||||
public class NuoDbHistorySupport extends DbViewHistorySupport {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package io.ebean.config.dbplatform.nuodb;
|
||||
|
||||
import io.ebean.BackgroundExecutor;
|
||||
import io.ebean.Query;
|
||||
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 io.ebean.config.dbplatform.PlatformIdGenerator;
|
||||
import io.ebean.config.dbplatform.SqlErrorCodes;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
/**
|
||||
* NuoDb specific platform.
|
||||
*/
|
||||
public class NuoDbPlatform extends DatabasePlatform {
|
||||
|
||||
public NuoDbPlatform() {
|
||||
super();
|
||||
this.platform = Platform.NUODB;
|
||||
this.idInExpandedForm = true;
|
||||
this.supportsResultSetConcurrencyModeUpdatable = false;
|
||||
this.supportsDeleteTableAlias = true;
|
||||
this.columnAliasPrefix = null;
|
||||
this.likeClauseRaw = "like ?";
|
||||
this.historySupport = new NuoDbHistorySupport();
|
||||
//this.dbEncrypt = ...
|
||||
dbIdentity.setIdType(IdType.IDENTITY);
|
||||
dbIdentity.setSupportsIdentity(true);
|
||||
dbIdentity.setSupportsSequence(true);
|
||||
dbIdentity.setSupportsGetGeneratedKeys(true);
|
||||
|
||||
// No referential integrity exception to map
|
||||
this.exceptionTranslator =
|
||||
new SqlErrorCodes()
|
||||
//.addAcquireLock("")
|
||||
.addDuplicateKey("23000")
|
||||
.build();
|
||||
|
||||
dbTypeMap.put(DbType.INTEGER, new DbPlatformType("integer", false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlatformIdGenerator createSequenceIdGenerator(BackgroundExecutor be, DataSource ds, int stepSize, String seqName) {
|
||||
return new NuoDbSequence(be, ds, seqName, stepSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String withForUpdate(String sql, Query.ForUpdate forUpdateMode) {
|
||||
switch (forUpdateMode) {
|
||||
case NOWAIT:
|
||||
return sql + " for update nowait";
|
||||
case SKIPLOCKED:
|
||||
default:
|
||||
return sql + " for update";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package io.ebean.config.dbplatform.nuodb;
|
||||
|
||||
import io.ebean.BackgroundExecutor;
|
||||
import io.ebean.config.dbplatform.SequenceStepIdGenerator;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
public class NuoDbSequence extends SequenceStepIdGenerator {
|
||||
|
||||
private final String nextSql;
|
||||
|
||||
/**
|
||||
* Construct where batchSize is the sequence step size.
|
||||
*/
|
||||
public NuoDbSequence(BackgroundExecutor be, DataSource ds, String seqName, int stepSize) {
|
||||
super(be, ds, seqName, stepSize);
|
||||
this.nextSql = "select next value for " + seqName + " from dual";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSql(int batchSize) {
|
||||
return nextSql;
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import io.ebean.config.dbplatform.h2.H2Platform;
|
||||
import io.ebean.config.dbplatform.hana.HanaPlatform;
|
||||
import io.ebean.config.dbplatform.hsqldb.HsqldbPlatform;
|
||||
import io.ebean.config.dbplatform.mysql.MySqlPlatform;
|
||||
import io.ebean.config.dbplatform.nuodb.NuoDbPlatform;
|
||||
import io.ebean.config.dbplatform.oracle.OraclePlatform;
|
||||
import io.ebean.config.dbplatform.postgres.PostgresPlatform;
|
||||
import io.ebean.config.dbplatform.sqlanywhere.SqlAnywherePlatform;
|
||||
@@ -804,6 +805,8 @@ public class DefaultDbMigration implements DbMigration {
|
||||
return new SQLitePlatform();
|
||||
case HANA:
|
||||
return new HanaPlatform();
|
||||
case NUODB:
|
||||
return new NuoDbPlatform();
|
||||
case COCKROACH:
|
||||
return new CockroachPlatform();
|
||||
case CLICKHOUSE:
|
||||
|
||||
+7
-7
@@ -29,9 +29,9 @@ public abstract class DbTriggerBasedHistoryDdl implements PlatformHistoryDdl {
|
||||
protected String viewSuffix;
|
||||
protected String historySuffix;
|
||||
|
||||
|
||||
protected String currentTimestamp = "now(6)";
|
||||
protected String sysPeriodType = "datetime(6)";
|
||||
protected String now = "now(6)";
|
||||
protected String sysPeriodEndValue = "now(6)";
|
||||
|
||||
DbTriggerBasedHistoryDdl() {
|
||||
}
|
||||
@@ -164,7 +164,7 @@ public abstract class DbTriggerBasedHistoryDdl implements PlatformHistoryDdl {
|
||||
protected void addSysPeriodColumns(DdlBuffer apply, String baseTableName, String whenCreatedColumn) throws IOException {
|
||||
|
||||
apply.append("alter table ").append(baseTableName).append(" add column ")
|
||||
.append(sysPeriodStart).append(" ").append(sysPeriodType).append(" default ").append(currentTimestamp).endOfStatement();
|
||||
.append(sysPeriodStart).append(" ").append(sysPeriodType).append(" default ").append(now).endOfStatement();
|
||||
apply.append("alter table ").append(baseTableName).append(" add column ")
|
||||
.append(sysPeriodEnd).append(" ").append(sysPeriodType).endOfStatement();
|
||||
|
||||
@@ -246,12 +246,12 @@ public abstract class DbTriggerBasedHistoryDdl implements PlatformHistoryDdl {
|
||||
|
||||
buffer.append(" insert into ").append(historyTable).append(" (").append(sysPeriodStart).append(",").append(sysPeriodEnd).append(",");
|
||||
appendColumnNames(buffer, columns, "");
|
||||
buffer.append(") values (OLD.").append(sysPeriodStart).append(", ").append(currentTimestamp).append(",");
|
||||
buffer.append(") values (OLD.").append(sysPeriodStart).append(", ").append(sysPeriodEndValue).append(",");
|
||||
appendColumnNames(buffer, columns, "OLD.");
|
||||
buffer.append(");").newLine();
|
||||
}
|
||||
|
||||
protected void appendColumnNames(DdlBuffer buffer, List<String> columns, String columnPrefix) throws IOException {
|
||||
void appendColumnNames(DdlBuffer buffer, List<String> columns, String columnPrefix) throws IOException {
|
||||
for (int i = 0; i < columns.size(); i++) {
|
||||
if (i > 0) {
|
||||
buffer.append(", ");
|
||||
@@ -264,7 +264,7 @@ public abstract class DbTriggerBasedHistoryDdl implements PlatformHistoryDdl {
|
||||
/**
|
||||
* Append a single column to the buffer if it is not null.
|
||||
*/
|
||||
protected void appendColumnName(DdlBuffer buffer, String prefix, String columnName) throws IOException {
|
||||
void appendColumnName(DdlBuffer buffer, String prefix, String columnName) throws IOException {
|
||||
if (columnName != null) {
|
||||
buffer.append(prefix).append(columnName);
|
||||
}
|
||||
@@ -278,7 +278,7 @@ public abstract class DbTriggerBasedHistoryDdl implements PlatformHistoryDdl {
|
||||
* the column.
|
||||
* </p>
|
||||
*/
|
||||
protected List<String> columnNamesForApply(MTable table) {
|
||||
List<String> columnNamesForApply(MTable table) {
|
||||
return table.allHistoryColumns(true);
|
||||
}
|
||||
|
||||
|
||||
@@ -14,9 +14,10 @@ public class H2HistoryDdl extends DbTriggerBasedHistoryDdl {
|
||||
|
||||
private static final String TRIGGER_CLASS = H2HistoryTrigger.class.getName();
|
||||
|
||||
public H2HistoryDdl() {
|
||||
H2HistoryDdl() {
|
||||
this.sysPeriodType = "timestamp";
|
||||
this.currentTimestamp = "now()";
|
||||
this.now = "now()";
|
||||
this.sysPeriodEndValue = "now()";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-3
@@ -11,13 +11,11 @@ import java.io.IOException;
|
||||
*/
|
||||
public class MySqlHistoryDdl extends DbTriggerBasedHistoryDdl {
|
||||
|
||||
|
||||
public MySqlHistoryDdl() {
|
||||
MySqlHistoryDdl() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dropTriggers(DdlBuffer buffer, String baseTable) throws IOException {
|
||||
|
||||
buffer.append("drop trigger ").append(updateTriggerName(baseTable)).endOfStatement();
|
||||
buffer.append("drop trigger ").append(deleteTriggerName(baseTable)).endOfStatement();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.annotation.ConstraintMode;
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
|
||||
public class NuoDbDdl extends PlatformDdl {
|
||||
|
||||
public NuoDbDdl(DatabasePlatform platform) {
|
||||
super(platform);
|
||||
this.historyDdl = new NuoDbHistoryDdl();
|
||||
this.identitySuffix = " generated by default as identity";
|
||||
this.dropConstraintIfExists = "drop constraint";
|
||||
}
|
||||
|
||||
@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
|
||||
protected void appendForeignKeyOnUpdate(StringBuilder buffer, ConstraintMode mode) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendForeignKeyOnDelete(StringBuilder buffer, ConstraintMode mode) {
|
||||
if (mode == ConstraintMode.RESTRICT) {
|
||||
// do nothing
|
||||
} else if (mode == ConstraintMode.SET_NULL) {
|
||||
// do nothing
|
||||
} else {
|
||||
super.appendForeignKeyOnDelete(buffer, mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
||||
import io.ebeaninternal.dbmigration.model.MTable;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* NuoDB history support using DB triggers to maintain a history table.
|
||||
*/
|
||||
public class NuoDbHistoryDdl extends DbTriggerBasedHistoryDdl {
|
||||
|
||||
NuoDbHistoryDdl() {
|
||||
this.now = "now()";
|
||||
this.sysPeriodEndValue = "NEW.sys_period_start";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dropTriggers(DdlBuffer buffer, String baseTable) throws IOException {
|
||||
|
||||
buffer.append("drop trigger ").append(updateTriggerName(baseTable)).endOfStatement();
|
||||
buffer.append("drop trigger ").append(deleteTriggerName(baseTable)).endOfStatement();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createTriggers(DdlWrite writer, MTable table) throws IOException {
|
||||
|
||||
DbTriggerUpdate update = createDbTriggerUpdate(writer, table);
|
||||
|
||||
addBeforeUpdate(updateTriggerName(update.getBaseTable()), update);
|
||||
addBeforeDelete(deleteTriggerName(update.getBaseTable()), update);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateHistoryTriggers(DbTriggerUpdate update) throws IOException {
|
||||
|
||||
recreateHistoryView(update);
|
||||
|
||||
DdlBuffer buffer = update.historyTriggerBuffer();
|
||||
String baseTable = update.getBaseTable();
|
||||
|
||||
dropTriggers(buffer, baseTable);
|
||||
addBeforeUpdate(updateTriggerName(baseTable), update);
|
||||
addBeforeDelete(deleteTriggerName(baseTable), update);
|
||||
}
|
||||
|
||||
private void addBeforeUpdate(String triggerName, DbTriggerUpdate update) throws IOException {
|
||||
|
||||
DdlBuffer apply = update.historyTriggerBuffer();
|
||||
addTriggerStart(triggerName, update, apply, " before update for each row as ");
|
||||
apply.append(" NEW.sys_period_start = greatest(current_timestamp, date_add(OLD.sys_period_start, interval 1 microsecond))").endOfStatement();
|
||||
appendInsertIntoHistory(apply, update.getHistoryTable(), update.getColumns());
|
||||
addEndTrigger(apply);
|
||||
}
|
||||
|
||||
private void addBeforeDelete(String triggerName, DbTriggerUpdate update) throws IOException {
|
||||
|
||||
DdlBuffer apply = update.historyTriggerBuffer();
|
||||
addTriggerStart(triggerName, update, apply, " before delete for each row as");
|
||||
appendInsertIntoHistory(apply, update.getHistoryTable(), update.getColumns());
|
||||
addEndTrigger(apply);
|
||||
}
|
||||
|
||||
private void addTriggerStart(String triggerName, DbTriggerUpdate update, DdlBuffer apply, String s) throws IOException {
|
||||
apply
|
||||
.append("delimiter $$").newLine()
|
||||
.append("create or replace trigger ").append(triggerName).append(" for ").append(update.getBaseTable())
|
||||
.append(s).newLine();
|
||||
}
|
||||
|
||||
private void addEndTrigger(DdlBuffer apply) throws IOException {
|
||||
apply.append("end_trigger")
|
||||
.endOfStatement()
|
||||
.append("$$").newLine()
|
||||
.newLine();
|
||||
}
|
||||
|
||||
}
|
||||
+4
-4
@@ -12,9 +12,9 @@ import java.util.List;
|
||||
*/
|
||||
public class PostgresHistoryDdl extends DbTriggerBasedHistoryDdl {
|
||||
|
||||
|
||||
public PostgresHistoryDdl() {
|
||||
this.currentTimestamp = "current_timestamp";
|
||||
PostgresHistoryDdl() {
|
||||
this.now = "current_timestamp";
|
||||
this.sysPeriodEndValue = "current_timestamp";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -36,7 +36,7 @@ public class PostgresHistoryDdl extends DbTriggerBasedHistoryDdl {
|
||||
protected void addSysPeriodColumns(DdlBuffer apply, String baseTableName, String whenCreatedColumn) throws IOException {
|
||||
apply
|
||||
.append("alter table ").append(baseTableName)
|
||||
.append(" add column ").append(sysPeriod).append(" tstzrange not null default tstzrange(").append(currentTimestamp).append(", null)")
|
||||
.append(" add column ").append(sysPeriod).append(" tstzrange not null default tstzrange(").append(now).append(", null)")
|
||||
.endOfStatement();
|
||||
|
||||
if (whenCreatedColumn != null) {
|
||||
|
||||
@@ -9,6 +9,7 @@ import io.ebean.config.dbplatform.h2.H2Platform;
|
||||
import io.ebean.config.dbplatform.hana.HanaPlatform;
|
||||
import io.ebean.config.dbplatform.hsqldb.HsqldbPlatform;
|
||||
import io.ebean.config.dbplatform.mysql.MySqlPlatform;
|
||||
import io.ebean.config.dbplatform.nuodb.NuoDbPlatform;
|
||||
import io.ebean.config.dbplatform.oracle.OraclePlatform;
|
||||
import io.ebean.config.dbplatform.postgres.Postgres8Platform;
|
||||
import io.ebean.config.dbplatform.postgres.PostgresPlatform;
|
||||
@@ -108,6 +109,9 @@ public class DatabasePlatformFactory {
|
||||
if (dbName.equals("clickhouse")) {
|
||||
return new ClickHousePlatform();
|
||||
}
|
||||
if (dbName.equals("nuodb")) {
|
||||
return new NuoDbPlatform();
|
||||
}
|
||||
if (dbName.equals("sqlite")) {
|
||||
return new SQLitePlatform();
|
||||
}
|
||||
@@ -158,6 +162,8 @@ public class DatabasePlatformFactory {
|
||||
return new HsqldbPlatform();
|
||||
} else if (dbProductName.contains("postgres")) {
|
||||
return readPostgres(connection);
|
||||
} else if (dbProductName.contains("nuo")) {
|
||||
return new NuoDbPlatform();
|
||||
} else if (dbProductName.contains("sqlite")) {
|
||||
return new SQLitePlatform();
|
||||
} else if (dbProductName.contains("db2")) {
|
||||
@@ -177,7 +183,7 @@ public class DatabasePlatformFactory {
|
||||
/**
|
||||
* Use a select version() query as it could be Postgres or CockroachDB.
|
||||
*/
|
||||
private static PostgresPlatform readPostgres(Connection connection) {
|
||||
private static DatabasePlatform readPostgres(Connection connection) {
|
||||
// Postgres driver uses a hardcoded product name so use version() query
|
||||
PreparedStatement statement = null;
|
||||
ResultSet resultSet = null;
|
||||
|
||||
@@ -8,6 +8,7 @@ import io.ebeaninternal.dbmigration.ddlgeneration.platform.H2Ddl;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.platform.HanaColumnStoreDdl;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.platform.HsqldbDdl;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.platform.MySqlDdl;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.platform.NuoDbDdl;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.platform.Oracle10Ddl;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.platform.PlatformDdl;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.platform.PostgresDdl;
|
||||
@@ -33,6 +34,8 @@ public class PlatformDdlBuilder {
|
||||
return new MySqlDdl(platform);
|
||||
case HSQLDB:
|
||||
return new HsqldbDdl(platform);
|
||||
case NUODB:
|
||||
return new NuoDbDdl(platform);
|
||||
case ORACLE:
|
||||
return new Oracle10Ddl(platform);
|
||||
case SQLITE:
|
||||
|
||||
Reference in New Issue
Block a user