Support for @Identity - use identity options with sequence

This commit is contained in:
rob bygrave
2020-03-04 21:29:56 +13:00
parent a5880fca97
commit bfc2b57df5
9 changed files with 98 additions and 68 deletions
@@ -248,18 +248,19 @@ public class BaseTableDdl implements TableDdl {
List<Column> columns = createTable.getColumn();
List<Column> pk = determinePrimaryKeyColumns(columns);
DdlIdentity idMode = DdlIdentity.NONE;
DdlIdentity identity = DdlIdentity.NONE;
if ((pk.size() == 1)) {
final IdentityMode identityMode = MTableIdentity.fromCreateTable(createTable);
IdType idType = platformDdl.useIdentityType(identityMode.getIdType());
idMode = new DdlIdentity(idType, identityMode);
String sequenceName = (IdType.SEQUENCE != idType) ? null : sequenceName(createTable, pk, identity);
identity = new DdlIdentity(idType, identityMode, sequenceName);
}
String partitionMode = createTable.getPartitionMode();
DdlBuffer apply = writer.apply();
apply.append(platformDdl.getCreateTableCommandPrefix()).append(" ").append(tableName).append(" (");
writeTableColumns(apply, columns, idMode);
writeTableColumns(apply, columns, identity);
writeUniqueConstraints(apply, createTable);
writeCompoundUniqueConstraints(apply, createTable);
if (!pk.isEmpty()) {
@@ -294,9 +295,8 @@ public class BaseTableDdl implements TableDdl {
// we drop the related sequence (if sequences are used)
dropTable(writer.dropAll(), tableName);
if (idMode.useSequence()) {
String pkCol = pk.get(0).getName();
writeSequence(writer, createTable, pkCol);
if (identity.useSequence()) {
writeSequence(writer, identity);
}
// add blank line for a bit of whitespace between tables
@@ -308,6 +308,14 @@ public class BaseTableDdl implements TableDdl {
}
}
private String sequenceName(CreateTable createTable, List<Column> pk, DdlIdentity identity) {
String seqName = identity.getSequenceName();
if (seqName == null || seqName.isEmpty()) {
seqName = namingConvention.getSequenceName(createTable.getName(), pk.get(0).getName());
}
return seqName;
}
/**
* Add table and column comments (separate from the create table statement).
*/
@@ -377,18 +385,9 @@ public class BaseTableDdl implements TableDdl {
}
}
protected void writeSequence(DdlWrite writer, CreateTable createTable, String pk) throws IOException {
// explicit sequence use or platform decides
String explicitSequenceName = createTable.getSequenceName();
int initial = toInt(createTable.getSequenceInitial());
int allocate = toInt(createTable.getSequenceAllocate());
String seqName = explicitSequenceName;
if (seqName == null || seqName.isEmpty()) {
seqName = namingConvention.getSequenceName(createTable.getName(), pk);
}
String createSeq = platformDdl.createSequence(seqName, initial, allocate);
protected void writeSequence(DdlWrite writer, DdlIdentity identity) throws IOException {
String seqName = identity.getSequenceName();
String createSeq = platformDdl.createSequence(seqName, identity);
if (hasValue(createSeq)) {
writer.apply().append(createSeq).newLine();
writer.dropAll().appendStatement(platformDdl.dropSequence(seqName));
@@ -10,15 +10,18 @@ public class DdlIdentity {
private final IdType idType;
private final IdentityMode identityMode;
private final String sequenceName;
public DdlIdentity(IdType idType, IdentityMode identityMode) {
public DdlIdentity(IdType idType, IdentityMode identityMode, String sequenceName) {
this.idType = idType;
this.identityMode = identityMode;
this.sequenceName = sequenceName;
}
private DdlIdentity() {
this.idType = null;
this.identityMode = null;
this.sequenceName = null;
}
public boolean useSequence() {
@@ -29,6 +32,10 @@ public class DdlIdentity {
return idType == IdType.IDENTITY;
}
public String getSequenceName() {
return sequenceName;
}
private String generatedBy() {
return isAlways() ? "always" : "by default";
}
@@ -41,16 +48,28 @@ public class DdlIdentity {
return " generated " + generatedBy() +" as identity";
}
public String options(String startWith, String incrementBy, String cache) {
public String identityOptions(String startWith, String incrementBy, String cache) {
return options(true, startWith, incrementBy, cache);
}
public String sequenceOptions(String startWith, String incrementBy, String cache) {
return options(false, startWith, incrementBy, cache);
}
private String options(boolean brackets, String startWith, String incrementBy, String cache) {
if (!identityMode.hasOptions()) {
return "";
}
StringBuilder sb = new StringBuilder(40);
sb.append(" (");
if (brackets) {
sb.append(" (");
}
optionFor(sb, startWith, identityMode.getStart());
optionFor(sb, incrementBy, identityMode.getIncrement());
optionFor(sb, cache, identityMode.getCache());
sb.append(")");
if (brackets) {
sb.append(")");
}
return sb.toString();
}
@@ -63,4 +82,15 @@ public class DdlIdentity {
}
}
public int getStart() {
return identityMode.getStart();
}
public int getIncrement() {
return identityMode.getIncrement();
}
public int getCache() {
return identityMode.getCache();
}
}
@@ -68,6 +68,9 @@ public class PlatformDdl {
protected String identityStartWith = "start with";
protected String identityIncrementBy = "increment by";
protected String identityCache = "cache";
protected String sequenceStartWith = "start with";
protected String sequenceIncrementBy = "increment by";
protected String sequenceCache = "cache";
protected String alterTableIfExists = "";
@@ -195,7 +198,7 @@ public class PlatformDdl {
StringBuilder sb = new StringBuilder(columnDefn.length() + 60);
sb.append(columnDefn).append(identity.optionGenerated());
sb.append(identity.options(identityStartWith, identityIncrementBy, identityCache));
sb.append(identity.identityOptions(identityStartWith, identityIncrementBy, identityCache));
return sb.toString();
}
@@ -362,16 +365,10 @@ public class PlatformDdl {
/**
* Generate and return the create sequence DDL.
*/
public String createSequence(String sequenceName, int initialValue, int allocationSize) {
public String createSequence(String sequenceName, DdlIdentity identity) {
StringBuilder sb = new StringBuilder("create sequence ");
sb.append(sequenceName);
if (initialValue > 1) {
sb.append(" start with ").append(initialValue);
}
if (allocationSize > 1) {
sb.append(" increment by ").append(allocationSize);
}
identity.sequenceOptions(sequenceStartWith, sequenceIncrementBy, sequenceCache);
sb.append(";");
return sb.toString();
}
@@ -114,18 +114,22 @@ public class SqlServerDdl extends PlatformDdl {
* Generate and return the create sequence DDL.
*/
@Override
public String createSequence(String sequenceName, int initialValue, int allocationSize) {
StringBuilder sb = new StringBuilder("create sequence ");
sb.append(sequenceName);
sb.append(" as bigint ");
if (initialValue > 1) {
sb.append(" start with ").append(initialValue);
public String createSequence(String sequenceName, DdlIdentity identity) {
StringBuilder sb = new StringBuilder(80);
sb.append("create sequence ").append(sequenceName).append(" as bigint");
final int start = identity.getStart();
if (start > 1) {
sb.append(" start with ").append(start);
} else {
sb.append(" start with 1 ");
sb.append(" start with 1");
}
if (allocationSize > 1) {
sb.append(" increment by ").append(allocationSize);
final int increment = identity.getIncrement();
if (increment > 1) {
sb.append(" increment by ").append(increment);
}
final int cache = identity.getCache();
if (cache > 1) {
sb.append(" cache ").append(increment);
}
sb.append(";");
return sb.toString();
@@ -56,7 +56,7 @@ public class TestQueryFilterMany extends BaseTestCase {
final Query<Customer> query = DB.find(Customer.class)
.where().ieq("name", "Rob")
// fluid style adding maxRows/firstRow to filterMany
.filterMany("orders").eq("status", Order.Status.NEW).setMaxRows(100).setFirstRow(3)
.filterMany("orders").eq("status", Order.Status.NEW).order("id desc").setMaxRows(100).setFirstRow(3)
.order().asc("id").setMaxRows(5);
final List<Customer> customers = query.findList();
@@ -86,7 +86,7 @@ public class TestQueryFilterMany extends BaseTestCase {
.order().asc("id").setMaxRows(5);
// non-fluid style adding maxRows/firstRow
final ExpressionList<Customer> filterMany = query.filterMany("orders").eq("status", Order.Status.NEW);
final ExpressionList<Customer> filterMany = query.filterMany("orders").order("id desc").eq("status", Order.Status.NEW);
filterMany.setMaxRows(100);
filterMany.setFirstRow(3);
@@ -5,14 +5,14 @@ create table migtest_ckey_assoc (
assoc_one nvarchar(255),
constraint pk_migtest_ckey_assoc primary key (id)
);
create sequence migtest_ckey_assoc_seq as bigint start with 1 ;
create sequence migtest_ckey_assoc_seq as bigint start with 1;
create table migtest_ckey_detail (
id integer not null,
something nvarchar(255),
constraint pk_migtest_ckey_detail primary key (id)
);
create sequence migtest_ckey_detail_seq as bigint start with 1 ;
create sequence migtest_ckey_detail_seq as bigint start with 1;
create table migtest_ckey_parent (
one_key integer not null,
@@ -27,40 +27,40 @@ create table migtest_fk_cascade (
one_id numeric(19),
constraint pk_migtest_fk_cascade primary key (id)
);
create sequence migtest_fk_cascade_seq as bigint start with 1 ;
create sequence migtest_fk_cascade_seq as bigint start with 1;
create table migtest_fk_cascade_one (
id numeric(19) not null,
constraint pk_migtest_fk_cascade_one primary key (id)
);
create sequence migtest_fk_cascade_one_seq as bigint start with 1 ;
create sequence migtest_fk_cascade_one_seq as bigint start with 1;
create table migtest_fk_none (
id numeric(19) not null,
one_id numeric(19),
constraint pk_migtest_fk_none primary key (id)
);
create sequence migtest_fk_none_seq as bigint start with 1 ;
create sequence migtest_fk_none_seq as bigint start with 1;
create table migtest_fk_none_via_join (
id numeric(19) not null,
one_id numeric(19),
constraint pk_migtest_fk_none_via_join primary key (id)
);
create sequence migtest_fk_none_via_join_seq as bigint start with 1 ;
create sequence migtest_fk_none_via_join_seq as bigint start with 1;
create table migtest_fk_one (
id numeric(19) not null,
constraint pk_migtest_fk_one primary key (id)
);
create sequence migtest_fk_one_seq as bigint start with 1 ;
create sequence migtest_fk_one_seq as bigint start with 1;
create table migtest_fk_set_null (
id numeric(19) not null,
one_id numeric(19),
constraint pk_migtest_fk_set_null primary key (id)
);
create sequence migtest_fk_set_null_seq as bigint start with 1 ;
create sequence migtest_fk_set_null_seq as bigint start with 1;
create table migtest_e_basic (
id integer not null,
@@ -85,7 +85,7 @@ create table migtest_e_basic (
);
create unique nonclustered index uq_migtest_e_basic_indextest2 on migtest_e_basic(indextest2) where indextest2 is not null;
create unique nonclustered index uq_migtest_e_basic_indextest6 on migtest_e_basic(indextest6) where indextest6 is not null;
create sequence migtest_e_basic_seq as bigint start with 1 ;
create sequence migtest_e_basic_seq as bigint start with 1;
create table migtest_e_enum (
id integer not null,
@@ -93,14 +93,14 @@ create table migtest_e_enum (
constraint ck_migtest_e_enum_test_status check ( test_status in ('N','A','I')),
constraint pk_migtest_e_enum primary key (id)
);
create sequence migtest_e_enum_seq as bigint start with 1 ;
create sequence migtest_e_enum_seq as bigint start with 1;
create table migtest_e_history (
id integer not null,
test_string nvarchar(255),
constraint pk_migtest_e_history primary key (id)
);
create sequence migtest_e_history_seq as bigint start with 1 ;
create sequence migtest_e_history_seq as bigint start with 1;
create table migtest_e_history2 (
id integer not null,
@@ -109,28 +109,28 @@ create table migtest_e_history2 (
obsolete_string2 nvarchar(255),
constraint pk_migtest_e_history2 primary key (id)
);
create sequence migtest_e_history2_seq as bigint start with 1 ;
create sequence migtest_e_history2_seq as bigint start with 1;
create table migtest_e_history3 (
id integer not null,
test_string nvarchar(255),
constraint pk_migtest_e_history3 primary key (id)
);
create sequence migtest_e_history3_seq as bigint start with 1 ;
create sequence migtest_e_history3_seq as bigint start with 1;
create table migtest_e_history4 (
id integer not null,
test_number integer,
constraint pk_migtest_e_history4 primary key (id)
);
create sequence migtest_e_history4_seq as bigint start with 1 ;
create sequence migtest_e_history4_seq as bigint start with 1;
create table migtest_e_history5 (
id integer not null,
test_number integer,
constraint pk_migtest_e_history5 primary key (id)
);
create sequence migtest_e_history5_seq as bigint start with 1 ;
create sequence migtest_e_history5_seq as bigint start with 1;
create table migtest_e_history6 (
id integer not null,
@@ -138,7 +138,7 @@ create table migtest_e_history6 (
test_number2 integer not null,
constraint pk_migtest_e_history6 primary key (id)
);
create sequence migtest_e_history6_seq as bigint start with 1 ;
create sequence migtest_e_history6_seq as bigint start with 1;
create table migtest_e_ref (
id integer not null,
@@ -146,42 +146,42 @@ create table migtest_e_ref (
constraint pk_migtest_e_ref primary key (id)
);
alter table migtest_e_ref add constraint uq_migtest_e_ref_name unique (name);
create sequence migtest_e_ref_seq as bigint start with 1 ;
create sequence migtest_e_ref_seq as bigint start with 1;
create table migtest_e_softdelete (
id integer not null,
test_string nvarchar(255),
constraint pk_migtest_e_softdelete primary key (id)
);
create sequence migtest_e_softdelete_seq as bigint start with 1 ;
create sequence migtest_e_softdelete_seq as bigint start with 1;
create table migtest_mtm_c (
id integer not null,
name nvarchar(255),
constraint pk_migtest_mtm_c primary key (id)
);
create sequence migtest_mtm_c_seq as bigint start with 1 ;
create sequence migtest_mtm_c_seq as bigint start with 1;
create table migtest_mtm_m (
id numeric(19) not null,
name nvarchar(255),
constraint pk_migtest_mtm_m primary key (id)
);
create sequence migtest_mtm_m_seq as bigint start with 1 ;
create sequence migtest_mtm_m_seq as bigint start with 1;
create table migtest_oto_child (
id integer not null,
name nvarchar(255),
constraint pk_migtest_oto_child primary key (id)
);
create sequence migtest_oto_child_seq as bigint start with 1 ;
create sequence migtest_oto_child_seq as bigint start with 1;
create table migtest_oto_master (
id numeric(19) not null,
name nvarchar(255),
constraint pk_migtest_oto_master primary key (id)
);
create sequence migtest_oto_master_seq as bigint start with 1 ;
create sequence migtest_oto_master_seq as bigint start with 1;
create index ix_migtest_e_basic_indextest1 on migtest_e_basic (indextest1);
create index ix_migtest_e_basic_indextest5 on migtest_e_basic (indextest5);
@@ -4,7 +4,7 @@ create table migtest_e_user (
id integer not null,
constraint pk_migtest_e_user primary key (id)
);
create sequence migtest_e_user_seq as bigint start with 1 ;
create sequence migtest_e_user_seq as bigint start with 1;
create table migtest_mtm_c_migtest_mtm_m (
migtest_mtm_c_id integer not null,
@@ -6,7 +6,7 @@ create table migtest_e_ref (
constraint pk_migtest_e_ref primary key (id)
);
alter table migtest_e_ref add constraint uq_migtest_e_ref_name unique (name);
create sequence migtest_e_ref_seq as bigint start with 1 ;
create sequence migtest_e_ref_seq as bigint start with 1;
IF OBJECT_ID('fk_migtest_ckey_detail_parent', 'F') IS NOT NULL alter table migtest_ckey_detail drop constraint fk_migtest_ckey_detail_parent;
IF OBJECT_ID('fk_migtest_fk_cascade_one_id', 'F') IS NOT NULL alter table migtest_fk_cascade drop constraint fk_migtest_fk_cascade_one_id;
+1 -1
View File
@@ -22,7 +22,7 @@ ebean.ddl.generate=true
ebean.ddl.run=true
ebean.ddl.header=-- Generated by ebean ${version} at ${timestamp}
ebean.packages=org.tests
datasource.default=h2
datasource.default=sqlserver
#datasource.h2.capturestacktrace=true
ebean.dumpMetricsOnShutdown=true