diff --git a/src/main/java/com/avaje/ebean/config/AbstractNamingConvention.java b/src/main/java/com/avaje/ebean/config/AbstractNamingConvention.java index 0452b95a3..9c5872766 100644 --- a/src/main/java/com/avaje/ebean/config/AbstractNamingConvention.java +++ b/src/main/java/com/avaje/ebean/config/AbstractNamingConvention.java @@ -35,9 +35,6 @@ public abstract class AbstractNamingConvention implements NamingConvention { /** The database platform. */ protected DatabasePlatform databasePlatform; - /** The max length of constraint names. */ - protected int maxConstraintNameLength; - /** Used to trim off extra prefix for M2M. */ protected int rhsPrefixLength = 3; @@ -71,9 +68,6 @@ public abstract class AbstractNamingConvention implements NamingConvention { public void setDatabasePlatform(DatabasePlatform databasePlatform) { this.databasePlatform = databasePlatform; - this.maxConstraintNameLength = databasePlatform.getDbDdlSyntax().getMaxConstraintNameLength(); - - logger.trace("Using maxConstraintNameLength of " + maxConstraintNameLength); } public String getSequenceName(String tableName, String pkColumn) { @@ -218,11 +212,11 @@ public abstract class AbstractNamingConvention implements NamingConvention { } buffer.append(rhsTableName); - int maxConstraintNameLength = databasePlatform.getDbDdlSyntax().getMaxConstraintNameLength(); + int maxTableNameLength = databasePlatform.getMaxTableNameLength(); // maxConstraintNameLength is used as the max table name length. - if (buffer.length() > maxConstraintNameLength) { - buffer.setLength(maxConstraintNameLength); + if (buffer.length() > maxTableNameLength) { + buffer.setLength(maxTableNameLength); } return new TableName(lhsTable.getCatalog(), lhsTable.getSchema(), buffer.toString()); diff --git a/src/main/java/com/avaje/ebean/config/dbplatform/DB2Platform.java b/src/main/java/com/avaje/ebean/config/dbplatform/DB2Platform.java index 6d76fa78a..028f1ed85 100644 --- a/src/main/java/com/avaje/ebean/config/dbplatform/DB2Platform.java +++ b/src/main/java/com/avaje/ebean/config/dbplatform/DB2Platform.java @@ -5,6 +5,7 @@ import java.sql.Types; import javax.sql.DataSource; import com.avaje.ebean.BackgroundExecutor; +import com.avaje.ebean.dbmigration.ddlgeneration.platform.DB2Ddl; /** * DB2 specific platform. @@ -14,10 +15,9 @@ public class DB2Platform extends DatabasePlatform { public DB2Platform() { super(); this.name = "db2"; - - // only support getGeneratedKeys with non-batch JDBC - // so generally use SEQUENCE instead for H2 this.sqlLimiter = new Db2SqlLimiter(); + this.platformDdl = new DB2Ddl(dbTypeMap, dbIdentity); + this.dbIdentity.setSupportsGetGeneratedKeys(true); this.dbIdentity.setSupportsSequence(true); @@ -26,7 +26,6 @@ public class DB2Platform extends DatabasePlatform { dbTypeMap.put(Types.TINYINT, new DbType("smallint")); dbTypeMap.put(Types.DECIMAL, new DbType("decimal", 15)); - this.dbDdlSyntax.setIdentity("generated by default as identity"); } /** diff --git a/src/main/java/com/avaje/ebean/config/dbplatform/DatabasePlatform.java b/src/main/java/com/avaje/ebean/config/dbplatform/DatabasePlatform.java index dd713c8f2..68c8b7e0e 100644 --- a/src/main/java/com/avaje/ebean/config/dbplatform/DatabasePlatform.java +++ b/src/main/java/com/avaje/ebean/config/dbplatform/DatabasePlatform.java @@ -19,6 +19,7 @@ public class DatabasePlatform { private static final Logger logger = LoggerFactory.getLogger(DatabasePlatform.class); + /** * Behavior used when ending a query only transaction (at read committed isolation level). */ @@ -72,12 +73,7 @@ public class DatabasePlatform { */ protected DbTypeMap dbTypeMap = new DbTypeMap(); - /** - * DB specific DDL syntax. - */ - protected DbDdlSyntax dbDdlSyntax = new DbDdlSyntax(); - - /** + /** * Defines DB identity/sequence features. */ protected DbIdentity dbIdentity = new DbIdentity(); @@ -161,17 +157,31 @@ public class DatabasePlatform { * "generic" is returned when no specific database platform has been set or * found. *

- * - * @return the name */ public String getName() { return name; } + /** + * Return the maximum table name length. + *

+ * This is used when deriving names of intersection tables. + *

+ */ + public int getMaxTableNameLength() { + return platformDdl.getMaxTableNameLength(); + } + + /** + * Return the platform specific DDL. + */ public PlatformDdl getPlatformDdl() { return platformDdl; } + /** + * Create and return a DDL handler for generating DDL scripts. + */ public DdlHandler createDdlHandler() { return platformDdl.createDdlHandler(); } @@ -255,15 +265,6 @@ public class DatabasePlatform { return dbTypeMap; } - /** - * Return the DDL syntax for this platform. - * - * @return the db ddl syntax - */ - public DbDdlSyntax getDbDdlSyntax() { - return dbDdlSyntax; - } - /** * Return the column alias prefix. */ @@ -473,22 +474,4 @@ public class DatabasePlatform { return disallowBatchOnCascade; } - /** - * Generate and return the create sequence DDL. - */ - public String ddlCreateSequence(String sequenceName, int initialValue, int allocationSize) { - - StringBuilder sb = new StringBuilder("create sequence "); - sb.append(sequenceName); - if (initialValue > 1) { - sb.append(" start with ").append(initialValue); - } - if (allocationSize > 0 && allocationSize != 50) { - // at this stage ignoring allocationSize 50 as this is the 'default' and - // not consistent with the way Ebean batch fetches sequence values - sb.append(" increment by ").append(allocationSize); - } - sb.append(";"); - return sb.toString(); - } } diff --git a/src/main/java/com/avaje/ebean/config/dbplatform/DbDdlSyntax.java b/src/main/java/com/avaje/ebean/config/dbplatform/DbDdlSyntax.java deleted file mode 100644 index 799bb507a..000000000 --- a/src/main/java/com/avaje/ebean/config/dbplatform/DbDdlSyntax.java +++ /dev/null @@ -1,333 +0,0 @@ -package com.avaje.ebean.config.dbplatform; - -import com.avaje.ebean.config.TableName; - -/** - * Used to support DB specific syntax for DDL generation. - */ -public class DbDdlSyntax { - - protected boolean renderIndexForFkey = true; - - protected boolean inlinePrimaryKeyConstraint = false; - - protected boolean addOneToOneUniqueContraint = true; - - protected int maxConstraintNameLength = 32; - - protected int columnNameWidth = 25; - - /** - * Flag set when we want to disable constraints on each table (rather than globally). - */ - protected boolean dropKeyConstraints; - - protected String dropTableCascade; - protected String dropIfExists; - - protected String newLine = "\n"; - - protected String identity = "auto_increment"; - protected String identitySuffix = ""; - - protected String pkPrefix = "pk_"; - - protected String disableReferentialIntegrity; - protected String enableReferentialIntegrity; - - protected String foreignKeySuffix; - - /** - * Return the primary key name for a given bean descriptor. - */ - public String getPrimaryKeyName(String tableName) { - - String pk = pkPrefix + tableName; - if (pk.length() > maxConstraintNameLength) { - // need to trim the primary key name - pk = pk.substring(0, maxConstraintNameLength); - } - return pk; - } - - /** - * Return the column definition for an identity column. - */ - public String getIdentityColumnDefn(String columnDefn) { - String identity = getIdentity(); - if (identity != null && identity.length() > 0) { - return columnDefn+" "+identity; - } - return columnDefn; - } - - /** - * Return the identity clause for DB's that have identities. - */ - public String getIdentity() { - return identity; - } - - /** - * Set the identity clause. - */ - public void setIdentity(String identity) { - this.identity = identity; - } - - /** - * Typically returns empty string but for SQLite and perhaps others - * the Identity/AutoIncrement clause comes after the primary key clause. - */ - public String getIdentitySuffix() { - return identitySuffix; - } - - /** - * Set the identity clause that would appear after the primary key clause. - *

- * Only used for SQLite at this stage. - *

- */ - public void setIdentitySuffix(String identitySuffix) { - this.identitySuffix = identitySuffix; - } - - /** - * Return the width for padding whitespace after column names. - */ - public int getColumnNameWidth() { - return columnNameWidth; - } - - /** - * Set the amount of padding to write after the column name. - */ - public void setColumnNameWidth(int columnNameWidth) { - this.columnNameWidth = columnNameWidth; - } - - /** - * Return the new line character. - */ - public String getNewLine() { - return newLine; - } - - /** - * Set the new line character. - */ - public void setNewLine(String newLine) { - this.newLine = newLine; - } - - /** - * Return the prefix used in naming primary keys. - */ - public String getPkPrefix() { - return pkPrefix; - } - - /** - * Set the prefix used in naming primary keys. - */ - public void setPkPrefix(String pkPrefix) { - this.pkPrefix = pkPrefix; - } - - /** - * Return the DB specific command to disable referential integrity - */ - public String getDisableReferentialIntegrity() { - return disableReferentialIntegrity; - } - - /** - * Set the DB specific command to disable referential integrity - */ - public void setDisableReferentialIntegrity(String disableReferentialIntegrity) { - this.disableReferentialIntegrity = disableReferentialIntegrity; - } - - /** - * Return the DB specific command to enable referential integrity - */ - public String getEnableReferentialIntegrity() { - return enableReferentialIntegrity; - } - - /** - * Set the DB specific command to enable referential integrity - */ - public void setEnableReferentialIntegrity(String enableReferentialIntegrity) { - this.enableReferentialIntegrity = enableReferentialIntegrity; - } - - /** - * Return true to is constraints are disabled on each table. - */ - public boolean isDropKeyConstraints() { - return dropKeyConstraints; - } - - /** - * Return some DDL to disable constraints on the given table. - */ - public String dropKeyConstraintPrefix(String tableName, String fkName) { - return null; - } - - /** - * Return true if indexes should be created for the foreign keys. - */ - public boolean isRenderIndexForFkey() { - return renderIndexForFkey; - } - - /** - * Set whether indexes should be created for the foreign keys. - */ - public void setRenderIndexForFkey(boolean renderIndexForFkey) { - this.renderIndexForFkey = renderIndexForFkey; - } - - /** - * Typically returns IF EXISTS (if that is supported by the database platform) - * or null. - */ - public String getDropIfExists() { - return dropIfExists; - } - - /** - * Set the IF EXISTS clause for dropping tables if that is supported by the - * database platform. - */ - public void setDropIfExists(String dropIfExists) { - this.dropIfExists = dropIfExists; - } - - /** - * Return prefix text that goes before drop table. - */ - public String dropTablePrefix(String tableName) { - return ""; - } - - /** - * Return the cascade option for the drop table command. - */ - public String getDropTableCascade() { - return dropTableCascade; - } - - /** - * Set the cascade option for the drop table command. - */ - public void setDropTableCascade(String dropTableCascade) { - this.dropTableCascade = dropTableCascade; - } - - /** - * Return the foreign key suffix. - */ - public String getForeignKeySuffix() { - return foreignKeySuffix; - } - - /** - * Set the foreign key suffix. - */ - public void setForeignKeySuffix(String foreignKeySuffix) { - this.foreignKeySuffix = foreignKeySuffix; - } - - /** - * Return the maximum length that constraint names can be for this database. - */ - public int getMaxConstraintNameLength() { - return maxConstraintNameLength; - } - - /** - * Set the maximum length that constraint names can be for this database. - */ - public void setMaxConstraintNameLength(int maxFkeyLength) { - this.maxConstraintNameLength = maxFkeyLength; - } - - /** - * Return true if imported side of OneToOne's should have unique constraints - * generated. - */ - public boolean isAddOneToOneUniqueContraint() { - return addOneToOneUniqueContraint; - } - - /** - * Set to false for DB's that don't want both a unique and index on the - * imported OneToOne. - */ - public void setAddOneToOneUniqueContraint(boolean addOneToOneUniqueContraint) { - this.addOneToOneUniqueContraint = addOneToOneUniqueContraint; - } - - /** - * Return true if primary key constraints should be inlined when they are a - * single column. - */ - public boolean isInlinePrimaryKeyConstraint() { - return inlinePrimaryKeyConstraint; - } - - /** - * Set whether to inline primary key constraints. - */ - public void setInlinePrimaryKeyConstraint(boolean inlinePrimaryKeyConstraint) { - this.inlinePrimaryKeyConstraint = inlinePrimaryKeyConstraint; - } - - /** - * Builds and returns a fully index name. - */ - public String getIndexName(String table, String propName, int ixCount) { - - - StringBuilder buffer = new StringBuilder(30); - buffer.append("ix_").append(TableName.parse(table)); - buffer.append("_").append(propName); - - addSuffix(buffer, ixCount); - - return buffer.toString(); - } - - /** - * Builds and returns a fully qualified foreign key constraint name. - */ - public String getForeignKeyName(String table, String propName, int fkCount) { - - StringBuilder buffer = new StringBuilder(30); - buffer.append("fk_").append(TableName.parse(table)); - buffer.append("_").append(propName); - - addSuffix(buffer, fkCount); - - return buffer.toString(); - } - - /** - * Adds the suffix. - */ - protected void addSuffix(StringBuilder buffer, int count) { - String suffixNr = Integer.toString(count); - int suffixLen = suffixNr.length() + 1; - - if (buffer.length() + suffixLen > maxConstraintNameLength) { - buffer.setLength(maxConstraintNameLength - suffixLen); - } - buffer.append("_"); - buffer.append(suffixNr); - } - -} diff --git a/src/main/java/com/avaje/ebean/config/dbplatform/H2Platform.java b/src/main/java/com/avaje/ebean/config/dbplatform/H2Platform.java index 716c436a2..521f8b55c 100644 --- a/src/main/java/com/avaje/ebean/config/dbplatform/H2Platform.java +++ b/src/main/java/com/avaje/ebean/config/dbplatform/H2Platform.java @@ -14,9 +14,7 @@ public class H2Platform extends DatabasePlatform { super(); this.name = "h2"; this.dbEncrypt = new H2DbEncrypt(); - // like ? escape'' not working in the latest version H2 so just using no - // escape clause for now noting that backslash is an escape char for like in H2 - this.likeClause = "like ?"; + this.platformDdl = new H2Ddl(this.dbTypeMap, dbIdentity); // only support getGeneratedKeys with non-batch JDBC // so generally use SEQUENCE instead of IDENTITY for H2 @@ -25,18 +23,12 @@ public class H2Platform extends DatabasePlatform { this.dbIdentity.setSupportsSequence(true); this.dbIdentity.setSupportsIdentity(true); - this.platformDdl = new H2Ddl(this.dbTypeMap, dbIdentity); - - this.openQuote = "\""; - this.closeQuote = "\""; + // like ? escape'' not working in the latest version H2 so just using no + // escape clause for now noting that backslash is an escape char for like in H2 + this.likeClause = "like ?"; // H2 data types match default JDBC types // so no changes to dbTypeMap required - - this.dbDdlSyntax.setDropIfExists("if exists"); - this.dbDdlSyntax.setDisableReferentialIntegrity("SET REFERENTIAL_INTEGRITY FALSE"); - this.dbDdlSyntax.setEnableReferentialIntegrity("SET REFERENTIAL_INTEGRITY TRUE"); - this.dbDdlSyntax.setForeignKeySuffix("on delete restrict on update restrict"); } /** diff --git a/src/main/java/com/avaje/ebean/config/dbplatform/HsqldbPlatform.java b/src/main/java/com/avaje/ebean/config/dbplatform/HsqldbPlatform.java index dac3b8f5b..a7a77910d 100644 --- a/src/main/java/com/avaje/ebean/config/dbplatform/HsqldbPlatform.java +++ b/src/main/java/com/avaje/ebean/config/dbplatform/HsqldbPlatform.java @@ -1,6 +1,7 @@ package com.avaje.ebean.config.dbplatform; import com.avaje.ebean.BackgroundExecutor; +import com.avaje.ebean.dbmigration.ddlgeneration.platform.HsqldbDdl; import javax.sql.DataSource; import java.sql.Types; @@ -14,32 +15,18 @@ public class HsqldbPlatform extends DatabasePlatform { super(); this.name = "hsqldb"; this.dbEncrypt = new H2DbEncrypt(); + this.platformDdl = new HsqldbDdl(dbTypeMap, dbIdentity); + this.dbIdentity.setIdType(IdType.IDENTITY); this.dbIdentity.setSupportsGetGeneratedKeys(true); this.dbIdentity.setSupportsSequence(true); this.dbIdentity.setSupportsIdentity(true); - this.openQuote = "\""; - this.closeQuote = "\""; - - // H2 data types match default JDBC types - // so no changes to dbTypeMap required dbTypeMap.put(Types.INTEGER, new DbType("integer", false)); - - this.dbDdlSyntax.setDropIfExists("if exists"); - this.dbDdlSyntax.setDisableReferentialIntegrity("SET DATABASE REFERENTIAL INTEGRITY FALSE"); - this.dbDdlSyntax.setEnableReferentialIntegrity("SET DATABASE REFERENTIAL INTEGRITY TRUE"); - this.dbDdlSyntax.setForeignKeySuffix("on delete restrict on update restrict"); - this.dbDdlSyntax.setIdentity("GENERATED BY DEFAULT AS IDENTITY (START WITH 1) "); } - /** - * Return a H2 specific sequence IdGenerator that supports batch fetching - * sequence values. - */ @Override - public IdGenerator createSequenceIdGenerator(BackgroundExecutor be, - DataSource ds, String seqName, int batchSize) { + public IdGenerator createSequenceIdGenerator(BackgroundExecutor be, DataSource ds, String seqName, int batchSize) { return new H2SequenceIdGenerator(be, ds, seqName, batchSize); } diff --git a/src/main/java/com/avaje/ebean/config/dbplatform/MsSqlServer2005Platform.java b/src/main/java/com/avaje/ebean/config/dbplatform/MsSqlServer2005Platform.java index 6dc722cdb..7a1ba7732 100644 --- a/src/main/java/com/avaje/ebean/config/dbplatform/MsSqlServer2005Platform.java +++ b/src/main/java/com/avaje/ebean/config/dbplatform/MsSqlServer2005Platform.java @@ -1,5 +1,7 @@ package com.avaje.ebean.config.dbplatform; +import com.avaje.ebean.dbmigration.ddlgeneration.platform.MsSqlServerDdl; + import java.sql.Types; /** @@ -22,7 +24,7 @@ public class MsSqlServer2005Platform extends DatabasePlatform { this.disallowBatchOnCascade = true; this.idInExpandedForm = true; this.sqlLimiter = new MsSqlServer2005SqlLimiter(); - this.dbDdlSyntax = new MsDdlSyntax(); + this.platformDdl = new MsSqlServerDdl(dbTypeMap, dbIdentity); this.dbIdentity.setIdType(IdType.IDENTITY); this.dbIdentity.setSupportsGetGeneratedKeys(true); this.dbIdentity.setSupportsIdentity(true); @@ -50,30 +52,4 @@ public class MsSqlServer2005Platform extends DatabasePlatform { } - /** - * MS SQL Server specific DDL Syntax. - */ - public class MsDdlSyntax extends DbDdlSyntax { - - MsDdlSyntax() { - this.identity = "identity(1,1)"; - this.dropKeyConstraints = true; - } - - /** - * Return some DDL to disable constraints on the given table. - */ - public String dropKeyConstraintPrefix(String tableName, String fkName) { - return "IF OBJECT_ID('"+fkName+"', 'F') IS NOT NULL"; - } - - /** - * Return prefix text that goes before drop table. - */ - public String dropTablePrefix(String tableName) { - return "IF OBJECT_ID('"+tableName+"', 'U') IS NOT NULL "; - } - - } - } diff --git a/src/main/java/com/avaje/ebean/config/dbplatform/MySqlPlatform.java b/src/main/java/com/avaje/ebean/config/dbplatform/MySqlPlatform.java index 9cbdb31b8..1948c617d 100644 --- a/src/main/java/com/avaje/ebean/config/dbplatform/MySqlPlatform.java +++ b/src/main/java/com/avaje/ebean/config/dbplatform/MySqlPlatform.java @@ -46,11 +46,6 @@ public class MySqlPlatform extends DatabasePlatform { dbTypeMap.put(Types.BINARY, new DbType("binary", 255)); dbTypeMap.put(Types.VARBINARY, new DbType("varbinary", 255)); - dbDdlSyntax.setMaxConstraintNameLength(64); - dbDdlSyntax.setDisableReferentialIntegrity("SET FOREIGN_KEY_CHECKS=0"); - dbDdlSyntax.setEnableReferentialIntegrity("SET FOREIGN_KEY_CHECKS=1"); - dbDdlSyntax.setForeignKeySuffix("on delete restrict on update restrict"); - } /** diff --git a/src/main/java/com/avaje/ebean/config/dbplatform/Oracle10Platform.java b/src/main/java/com/avaje/ebean/config/dbplatform/Oracle10Platform.java index 2e3bf121b..46282a6f9 100644 --- a/src/main/java/com/avaje/ebean/config/dbplatform/Oracle10Platform.java +++ b/src/main/java/com/avaje/ebean/config/dbplatform/Oracle10Platform.java @@ -18,6 +18,7 @@ public class Oracle10Platform extends DatabasePlatform { this.onQueryOnly = OnQueryOnly.CLOSE; this.dbEncrypt = new Oracle10DbEncrypt(); this.sqlLimiter = new RownumSqlLimiter(); + this.platformDdl = new Oracle10Ddl(this.dbTypeMap, this.dbIdentity); // Not using getGeneratedKeys as instead we will // batch load sequences which enables JDBC batch execution @@ -49,12 +50,6 @@ public class Oracle10Platform extends DatabasePlatform { dbTypeMap.put(Types.BINARY, new DbType("raw", 255)); dbTypeMap.put(Types.TIME, new DbType("timestamp")); - - dbDdlSyntax.setDropTableCascade("cascade constraints purge"); - dbDdlSyntax.setIdentity(null); - dbDdlSyntax.setMaxConstraintNameLength(30); - - this.platformDdl = new Oracle10Ddl(this.dbTypeMap, this.dbIdentity); } @Override diff --git a/src/main/java/com/avaje/ebean/config/dbplatform/Postgres8Platform.java b/src/main/java/com/avaje/ebean/config/dbplatform/Postgres8Platform.java index 3643bc004..a0bd6ed28 100644 --- a/src/main/java/com/avaje/ebean/config/dbplatform/Postgres8Platform.java +++ b/src/main/java/com/avaje/ebean/config/dbplatform/Postgres8Platform.java @@ -1,66 +1,19 @@ package com.avaje.ebean.config.dbplatform; -import com.avaje.ebean.BackgroundExecutor; - -import javax.sql.DataSource; -import java.sql.Types; - /** * Postgres v8.3 specific platform. *

* No support for getGeneratedKeys. *

*/ -public class Postgres8Platform extends DatabasePlatform { +public class Postgres8Platform extends PostgresPlatform { public Postgres8Platform() { super(); - this.name = "postgres"; - this.selectCountWithAlias = true; - this.blobDbType = Types.LONGVARBINARY; - this.clobDbType = Types.VARCHAR; - - this.dbEncrypt = new PostgresDbEncrypt(); - this.historySupport = new PostgresHistorySupport(); - this.dbIdentity.setSupportsGetGeneratedKeys(false); this.dbIdentity.setIdType(IdType.SEQUENCE); this.dbIdentity.setSupportsSequence(true); - this.columnAliasPrefix = "as c"; - this.openQuote = "\""; - this.closeQuote = "\""; - - // dbTypeMap.put(Types.BOOLEAN, new DbType("bit default 0")); - - dbTypeMap.put(Types.INTEGER, new DbType("integer", false)); - dbTypeMap.put(Types.DOUBLE, new DbType("float")); - dbTypeMap.put(Types.TINYINT, new DbType("smallint")); - dbTypeMap.put(Types.DECIMAL, new DbType("decimal", 38)); - - dbTypeMap.put(Types.BINARY, new DbType("bytea", false)); - dbTypeMap.put(Types.VARBINARY, new DbType("bytea", false)); - - dbTypeMap.put(Types.BLOB, new DbType("bytea", false)); - dbTypeMap.put(Types.CLOB, new DbType("text")); - dbTypeMap.put(Types.LONGVARBINARY, new DbType("bytea", false)); - dbTypeMap.put(Types.LONGVARCHAR, new DbType("text")); - - dbDdlSyntax.setDropTableCascade("cascade"); - dbDdlSyntax.setDropIfExists("if exists"); } - /** - * Create a Postgres specific sequence IdGenerator. - */ - @Override - public IdGenerator createSequenceIdGenerator(BackgroundExecutor be, DataSource ds, String seqName, int batchSize) { - - return new PostgresSequenceIdGenerator(be, ds, seqName, batchSize); - } - - @Override - protected String withForUpdate(String sql) { - return sql + " for update"; - } } diff --git a/src/main/java/com/avaje/ebean/config/dbplatform/PostgresDdlSyntax.java b/src/main/java/com/avaje/ebean/config/dbplatform/PostgresDdlSyntax.java deleted file mode 100644 index 09c6cfd92..000000000 --- a/src/main/java/com/avaje/ebean/config/dbplatform/PostgresDdlSyntax.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.avaje.ebean.config.dbplatform; - -public class PostgresDdlSyntax extends DbDdlSyntax { - - /** - * Map bigint, integer and smallint into their equivilent serial types. - */ - @Override - public String getIdentityColumnDefn(String columnDefn) { - - //smallserial, serial and bigserial - if ("bigint".equalsIgnoreCase(columnDefn)) { - return "bigserial"; - } - if ("integer".equalsIgnoreCase(columnDefn)) { - return "serial"; - } - if ("smallint".equalsIgnoreCase(columnDefn)) { - return "smallserial"; - } - - return columnDefn; - } - -} diff --git a/src/main/java/com/avaje/ebean/config/dbplatform/PostgresPlatform.java b/src/main/java/com/avaje/ebean/config/dbplatform/PostgresPlatform.java index 1e527fcb3..92205cba5 100644 --- a/src/main/java/com/avaje/ebean/config/dbplatform/PostgresPlatform.java +++ b/src/main/java/com/avaje/ebean/config/dbplatform/PostgresPlatform.java @@ -23,22 +23,19 @@ public class PostgresPlatform extends DatabasePlatform { this.onQueryOnly = OnQueryOnly.CLOSE; this.likeClause = "like ? escape''"; - this.dbDdlSyntax = new PostgresDdlSyntax(); - this.selectCountWithAlias = true; this.blobDbType = Types.LONGVARBINARY; this.clobDbType = Types.VARCHAR; this.dbEncrypt = new PostgresDbEncrypt(); this.historySupport = new PostgresHistorySupport(); + this.platformDdl = new PostgresDdl(this.dbTypeMap, this.dbIdentity); // Use Identity and getGeneratedKeys this.dbIdentity.setIdType(IdType.IDENTITY); this.dbIdentity.setSupportsGetGeneratedKeys(true); this.dbIdentity.setSupportsSequence(true); - this.platformDdl = new PostgresDdl(this.dbTypeMap, this.dbIdentity); - //this.columnAliasPrefix = "as c"; this.openQuote = "\""; @@ -64,8 +61,6 @@ public class PostgresPlatform extends DatabasePlatform { dbTypeMap.put(Types.LONGVARBINARY, dbBytea); dbTypeMap.put(Types.LONGVARCHAR, dbTypeText); - dbDdlSyntax.setDropTableCascade("cascade"); - dbDdlSyntax.setDropIfExists("if exists"); } /** diff --git a/src/main/java/com/avaje/ebean/config/dbplatform/SQLitePlatform.java b/src/main/java/com/avaje/ebean/config/dbplatform/SQLitePlatform.java index 37d6a1c3c..85c5cee44 100644 --- a/src/main/java/com/avaje/ebean/config/dbplatform/SQLitePlatform.java +++ b/src/main/java/com/avaje/ebean/config/dbplatform/SQLitePlatform.java @@ -1,22 +1,20 @@ package com.avaje.ebean.config.dbplatform; +import com.avaje.ebean.dbmigration.ddlgeneration.platform.SQLiteDdl; + import java.sql.Types; -import javax.sql.DataSource; - -import com.avaje.ebean.BackgroundExecutor; - public class SQLitePlatform extends DatabasePlatform { public SQLitePlatform() { super(); this.name = "sqlite"; + this.platformDdl = new SQLiteDdl(dbTypeMap, dbIdentity); this.dbIdentity.setIdType(IdType.IDENTITY); this.dbIdentity.setSupportsGetGeneratedKeys(false); + this.dbIdentity.setSupportsSequence(false); this.dbIdentity.setSelectLastInsertedIdTemplate("select last_insert_rowid()"); - this.openQuote = "\""; - this.closeQuote = "\""; this.booleanDbType = Types.INTEGER; @@ -24,25 +22,7 @@ public class SQLitePlatform extends DatabasePlatform { dbTypeMap.put(Types.BOOLEAN, new DbType("int default 0")); dbTypeMap.put(Types.BIGINT, new DbType("integer")); dbTypeMap.put(Types.SMALLINT, new DbType("integer")); - - dbDdlSyntax.setInlinePrimaryKeyConstraint(true); - - // AutoIncrement goes the primary key declaration - dbDdlSyntax.setIdentity(""); - dbDdlSyntax.setIdentitySuffix("AUTOINCREMENT"); - dbDdlSyntax.setDisableReferentialIntegrity("PRAGMA foreign_keys = OFF"); - dbDdlSyntax.setEnableReferentialIntegrity("PRAGMA foreign_keys = ON"); - } - - /** - * Return null in case there is a sequence annotation. - */ - @Override - public IdGenerator createSequenceIdGenerator(BackgroundExecutor be, - DataSource ds, String seqName, int batchSize) { - - return null; } } diff --git a/src/main/java/com/avaje/ebean/config/dbplatform/SqlAnywherePlatform.java b/src/main/java/com/avaje/ebean/config/dbplatform/SqlAnywherePlatform.java index dc9b9360f..86d02290a 100644 --- a/src/main/java/com/avaje/ebean/config/dbplatform/SqlAnywherePlatform.java +++ b/src/main/java/com/avaje/ebean/config/dbplatform/SqlAnywherePlatform.java @@ -11,7 +11,6 @@ import java.sql.Types; * *

*/ - public class SqlAnywherePlatform extends DatabasePlatform { public SqlAnywherePlatform() { diff --git a/src/main/java/com/avaje/ebean/dbmigration/ddlgeneration/platform/DB2Ddl.java b/src/main/java/com/avaje/ebean/dbmigration/ddlgeneration/platform/DB2Ddl.java new file mode 100644 index 000000000..04dc07f0b --- /dev/null +++ b/src/main/java/com/avaje/ebean/dbmigration/ddlgeneration/platform/DB2Ddl.java @@ -0,0 +1,16 @@ +package com.avaje.ebean.dbmigration.ddlgeneration.platform; + +import com.avaje.ebean.config.dbplatform.DbIdentity; +import com.avaje.ebean.config.dbplatform.DbTypeMap; + +/** + * DB2 platform specific DDL. + */ +public class DB2Ddl extends PlatformDdl { + + public DB2Ddl(DbTypeMap platformTypes, DbIdentity dbIdentity) { + super(platformTypes, dbIdentity); + this.identitySuffix = " generated by default as identity"; + } + +} diff --git a/src/main/java/com/avaje/ebean/dbmigration/ddlgeneration/platform/DdlNamingConvention.java b/src/main/java/com/avaje/ebean/dbmigration/ddlgeneration/platform/DdlNamingConvention.java index 0c75b7be5..57b91eaeb 100644 --- a/src/main/java/com/avaje/ebean/dbmigration/ddlgeneration/platform/DdlNamingConvention.java +++ b/src/main/java/com/avaje/ebean/dbmigration/ddlgeneration/platform/DdlNamingConvention.java @@ -56,7 +56,7 @@ public class DdlNamingConvention { colPart = normaliseColumn(columns[0]); } else { StringBuilder sb = new StringBuilder(); - for (int i = 0; i 0) { sb.append("_"); } @@ -96,6 +96,16 @@ public class DdlNamingConvention { return (sequenceName != null) ? lowerName(sequenceName) : normaliseTable(tableName) + "_seq"; } + /** + * Return the maximum table name length. + *

+ * This is used when deriving names of intersection tables. + *

+ */ + public int getMaxTableNameLength() { + return maxConstraintNameLength; + } + /** * Apply a maximum length to the constraint name. */ @@ -105,7 +115,7 @@ public class DdlNamingConvention { } // add the count to ensure the constraint name is unique // (relying on the prefix having the table name to be globally unique) - return constraintName.substring(0,maxConstraintNameLength-3)+"_"+count; + return constraintName.substring(0, maxConstraintNameLength - 3) + "_" + count; } /** diff --git a/src/main/java/com/avaje/ebean/dbmigration/ddlgeneration/platform/HsqldbDdl.java b/src/main/java/com/avaje/ebean/dbmigration/ddlgeneration/platform/HsqldbDdl.java new file mode 100644 index 000000000..3bb398cac --- /dev/null +++ b/src/main/java/com/avaje/ebean/dbmigration/ddlgeneration/platform/HsqldbDdl.java @@ -0,0 +1,16 @@ +package com.avaje.ebean.dbmigration.ddlgeneration.platform; + +import com.avaje.ebean.config.dbplatform.DbIdentity; +import com.avaje.ebean.config.dbplatform.DbTypeMap; + +/** + * Hsqldb platform specific DDL. + */ +public class HsqldbDdl extends PlatformDdl { + + public HsqldbDdl(DbTypeMap platformTypes, DbIdentity dbIdentity) { + super(platformTypes, dbIdentity); + this.identitySuffix = " generated by default as identity (start with 1) "; + } + +} diff --git a/src/main/java/com/avaje/ebean/dbmigration/ddlgeneration/platform/MsSqlServerDdl.java b/src/main/java/com/avaje/ebean/dbmigration/ddlgeneration/platform/MsSqlServerDdl.java new file mode 100644 index 000000000..48108a830 --- /dev/null +++ b/src/main/java/com/avaje/ebean/dbmigration/ddlgeneration/platform/MsSqlServerDdl.java @@ -0,0 +1,41 @@ +package com.avaje.ebean.dbmigration.ddlgeneration.platform; + +import com.avaje.ebean.config.dbplatform.DbIdentity; +import com.avaje.ebean.config.dbplatform.DbTypeMap; + +/** + * MS SQL Server platform specific DDL. + */ +public class MsSqlServerDdl extends PlatformDdl { + + public MsSqlServerDdl(DbTypeMap platformTypes, DbIdentity dbIdentity) { + super(platformTypes, dbIdentity); + this.identitySuffix = " generated by default as identity"; + } + +// /** +// * MS SQL Server specific DDL Syntax. +// */ +// public class MsDdlSyntax extends DbDdlSyntax { +// +// MsDdlSyntax() { +// this.identity = "identity(1,1)"; +// this.dropKeyConstraints = true; +// } +// +// /** +// * Return some DDL to disable constraints on the given table. +// */ +// public String dropKeyConstraintPrefix(String tableName, String fkName) { +// return "IF OBJECT_ID('"+fkName+"', 'F') IS NOT NULL"; +// } +// +// /** +// * Return prefix text that goes before drop table. +// */ +// public String dropTablePrefix(String tableName) { +// return "IF OBJECT_ID('"+tableName+"', 'U') IS NOT NULL "; +// } +// +// } +} diff --git a/src/main/java/com/avaje/ebean/dbmigration/ddlgeneration/platform/MySqlDdl.java b/src/main/java/com/avaje/ebean/dbmigration/ddlgeneration/platform/MySqlDdl.java index 207e6ee56..9a1f48517 100644 --- a/src/main/java/com/avaje/ebean/dbmigration/ddlgeneration/platform/MySqlDdl.java +++ b/src/main/java/com/avaje/ebean/dbmigration/ddlgeneration/platform/MySqlDdl.java @@ -10,11 +10,12 @@ public class MySqlDdl extends PlatformDdl { public MySqlDdl(DbTypeMap platformTypes, DbIdentity dbIdentity) { super(platformTypes, dbIdentity); + this.namingConvention.maxConstraintNameLength = 64; } @Override public String dropForeignKeyConstraint(String fkName) { - return "drop foreign key "+fkName; + return "drop foreign key " + fkName; } } diff --git a/src/main/java/com/avaje/ebean/dbmigration/ddlgeneration/platform/PlatformDdl.java b/src/main/java/com/avaje/ebean/dbmigration/ddlgeneration/platform/PlatformDdl.java index 997f600ac..0c2973aa3 100644 --- a/src/main/java/com/avaje/ebean/dbmigration/ddlgeneration/platform/PlatformDdl.java +++ b/src/main/java/com/avaje/ebean/dbmigration/ddlgeneration/platform/PlatformDdl.java @@ -13,7 +13,7 @@ import com.avaje.ebean.dbmigration.model.MTable; import java.io.IOException; /** - * + * Controls the DDL generation for a specific database platform. */ public class PlatformDdl { @@ -21,8 +21,14 @@ public class PlatformDdl { protected DdlNamingConvention namingConvention = new DdlNamingConvention(); + /** + * Converter for logical/standard types to platform specific types. (eg. clob -> text) + */ private final PlatformTypeConverter typeConverter; + /** + * For handling support of sequences and autoincrement. + */ private final DbIdentity dbIdentity; /** @@ -70,6 +76,9 @@ public class PlatformDdl { return foreignKeyRestrict; } + /** + * Return the drop foreign key clause. + */ public String dropForeignKeyConstraint(String fkName) { return "drop constraint "+fkName; } @@ -108,16 +117,35 @@ public class PlatformDdl { return sb.toString(); } + /** + * Return the drop sequence statement (potentially with if exists clause). + */ public String dropSequence(String sequenceName) { return dropSequenceIfExists + sequenceName; } + /** + * Return the drop table statement (potentially with if exists clause). + */ public String dropTable(String tableName) { return dropTableIfExists + tableName + dropTableCascade; } + /** + * Support lower naming tables and columns in DDL generation. + * Tables/Columns with quoted identifiers are exempt. + */ public String lowerName(String name) { return namingConvention.lowerName(name); } + /** + * Return the maximum table name length. + *

+ * This is used when deriving names of intersection tables. + *

+ */ + public int getMaxTableNameLength() { + return namingConvention.getMaxTableNameLength(); + } } diff --git a/src/main/java/com/avaje/ebean/dbmigration/ddlgeneration/platform/SQLiteDdl.java b/src/main/java/com/avaje/ebean/dbmigration/ddlgeneration/platform/SQLiteDdl.java new file mode 100644 index 000000000..1cc55e2fb --- /dev/null +++ b/src/main/java/com/avaje/ebean/dbmigration/ddlgeneration/platform/SQLiteDdl.java @@ -0,0 +1,16 @@ +package com.avaje.ebean.dbmigration.ddlgeneration.platform; + +import com.avaje.ebean.config.dbplatform.DbIdentity; +import com.avaje.ebean.config.dbplatform.DbTypeMap; + +/** + * DB2 platform specific DDL. + */ +public class SQLiteDdl extends PlatformDdl { + + public SQLiteDdl(DbTypeMap platformTypes, DbIdentity dbIdentity) { + super(platformTypes, dbIdentity); + this.identitySuffix = " autoincrement"; + } + +}