diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PlatformDdl.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PlatformDdl.java index 648cfac83..59cf38e0d 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PlatformDdl.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PlatformDdl.java @@ -3,7 +3,6 @@ package io.ebeaninternal.dbmigration.ddlgeneration.platform; import io.ebean.annotation.ConstraintMode; import io.ebean.config.DatabaseConfig; import io.ebean.config.DbConstraintNaming; -import io.ebean.config.ServerConfig; import io.ebean.config.dbplatform.DatabasePlatform; import io.ebean.config.dbplatform.DbDefaultValue; import io.ebean.config.dbplatform.DbIdentity; @@ -113,6 +112,7 @@ public class PlatformDdl { protected String uniqueIndex = "unique"; protected String indexConcurrent = ""; + protected String createIndexIfNotExists = ""; /** * Set false for MsSqlServer to allow multiple nulls for OneToOne mapping. @@ -414,6 +414,9 @@ public class PlatformDdl { if (create.isConcurrent()) { buffer.append(indexConcurrent); } + if (create.isNotExistsCheck()) { + buffer.append(createIndexIfNotExists); + } buffer.append(maxConstraintName(create.getIndexName())).append(" on ").append(create.getTableName()); appendColumns(create.getColumns(), buffer); return buffer.toString(); diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PostgresDdl.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PostgresDdl.java index daeaf57fb..807bec456 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PostgresDdl.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PostgresDdl.java @@ -18,6 +18,7 @@ public class PostgresDdl extends PlatformDdl { this.dropTableCascade = " cascade"; this.columnSetType = "type "; this.alterTableIfExists = "if exists "; + this.createIndexIfNotExists = "if not exists "; this.columnSetNull = "drop not null"; this.addForeignKeySkipCheck = " not valid"; this.indexConcurrent = "concurrently "; diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/WriteCreateIndex.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/WriteCreateIndex.java index c743c979c..fbb7b72ce 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/WriteCreateIndex.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/WriteCreateIndex.java @@ -12,7 +12,11 @@ class WriteCreateIndex { private final boolean unique; private final boolean concurrent; private final String definition; + private final boolean notExistsCheck; + /** + * Create index for foreign key. + */ WriteCreateIndex(String indexName, String tableName, String[] columns, boolean unique) { this.indexName = indexName; this.tableName = tableName; @@ -20,8 +24,12 @@ class WriteCreateIndex { this.unique = unique; this.concurrent = false; this.definition = null; + this.notExistsCheck = false; } + /** + * Create non-foreign key index. + */ public WriteCreateIndex(CreateIndex index) { this.indexName = index.getIndexName(); this.tableName = index.getTableName(); @@ -29,6 +37,7 @@ class WriteCreateIndex { this.unique = Boolean.TRUE.equals(index.isUnique()); this.concurrent = Boolean.TRUE.equals(index.isConcurrent()); this.definition = index.getDefinition(); + this.notExistsCheck = true; } public String getIndexName() { @@ -58,4 +67,8 @@ class WriteCreateIndex { public boolean useDefinition() { return definition != null && !definition.isEmpty(); } + + public boolean isNotExistsCheck() { + return notExistsCheck; + } } diff --git a/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PlatformDdl_CreateIndexTest.java b/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PlatformDdl_CreateIndexTest.java new file mode 100644 index 000000000..d7d33feae --- /dev/null +++ b/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PlatformDdl_CreateIndexTest.java @@ -0,0 +1,98 @@ +package io.ebeaninternal.dbmigration.ddlgeneration.platform; + +import io.ebean.DB; +import io.ebean.config.DatabaseConfig; +import io.ebean.config.dbplatform.h2.H2Platform; +import io.ebean.config.dbplatform.hana.HanaPlatform; +import io.ebean.config.dbplatform.mysql.MySqlPlatform; +import io.ebean.config.dbplatform.oracle.OraclePlatform; +import io.ebean.config.dbplatform.postgres.PostgresPlatform; +import io.ebean.config.dbplatform.sqlserver.SqlServer17Platform; +import io.ebeaninternal.dbmigration.ddlgeneration.PlatformDdlBuilder; +import io.ebeaninternal.dbmigration.migration.CreateIndex; +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertEquals; + +public class PlatformDdl_CreateIndexTest { + + private final PlatformDdl h2Ddl = PlatformDdlBuilder.create(new H2Platform()); + private final PlatformDdl pgDdl = PlatformDdlBuilder.create(new PostgresPlatform()); + private final PlatformDdl mysqlDdl = PlatformDdlBuilder.create(new MySqlPlatform()); + private final PlatformDdl oraDdl = PlatformDdlBuilder.create(new OraclePlatform()); + private final PlatformDdl sqlServerDdl = PlatformDdlBuilder.create(new SqlServer17Platform()); + private final PlatformDdl hanaDdl = PlatformDdlBuilder.create(new HanaPlatform()); + + { + DatabaseConfig config = DB.getDefault().getPluginApi().getServerConfig(); + h2Ddl.configure(config); + pgDdl.configure(config); + mysqlDdl.configure(config); + oraDdl.configure(config); + sqlServerDdl.configure(config); + hanaDdl.configure(config); + } + + WriteCreateIndex writeCreateIndex() { + + return writeCreateIndex(true, true); + } + + WriteCreateIndex writeCreateIndex(boolean unique, boolean concurrent) { + CreateIndex createIndex = new CreateIndex(); + createIndex.setIndexName("ix_mytab_acol"); + createIndex.setTableName("mytab"); + createIndex.setColumns("acol"); + createIndex.setUnique(unique); + createIndex.setConcurrent(concurrent); + return new WriteCreateIndex(createIndex); + } + + WriteCreateIndex fkeyCreateIndex(boolean unique) { + return new WriteCreateIndex("ix_mytab_acol", "mytab", new String[]{"acol"}, unique); + } + + + @Test + public void createUniqueIndex() { + + WriteCreateIndex createIndex = writeCreateIndex(); + + String sql = h2Ddl.createIndex(createIndex); + assertEquals("create unique index ix_mytab_acol on mytab (acol)", sql); + sql = pgDdl.createIndex(createIndex); + assertEquals("create unique index concurrently if not exists ix_mytab_acol on mytab (acol)", sql); + sql = mysqlDdl.createIndex(createIndex); + assertEquals("create unique index ix_mytab_acol on mytab (acol)", sql); + sql = sqlServerDdl.createIndex(createIndex); + assertEquals("create unique index ix_mytab_acol on mytab (acol)", sql); + sql = oraDdl.createIndex(createIndex); + assertEquals("create unique index ix_mytab_acol on mytab (acol)", sql); + sql = hanaDdl.createIndex(createIndex); + assertThat(sql).isEqualTo("-- explicit index \"ix_mytab_acol\" for single column \"acol\" of table \"mytab\" is not necessary"); + } + + @Test + public void postgres_createIndex() { + + String sql = pgDdl.createIndex(writeCreateIndex(true, true)); + assertEquals("create unique index concurrently if not exists ix_mytab_acol on mytab (acol)", sql); + sql = pgDdl.createIndex(writeCreateIndex(false, false)); + assertEquals("create index if not exists ix_mytab_acol on mytab (acol)", sql); + sql = pgDdl.createIndex(writeCreateIndex(true, false)); + assertEquals("create unique index if not exists ix_mytab_acol on mytab (acol)", sql); + sql = pgDdl.createIndex(writeCreateIndex(false, true)); + assertEquals("create index concurrently if not exists ix_mytab_acol on mytab (acol)", sql); + } + + @Test + public void postgres_fkeyCreateIndex() { + String sql = pgDdl.createIndex(fkeyCreateIndex(true)); + assertEquals("create unique index ix_mytab_acol on mytab (acol)", sql); + + sql = pgDdl.createIndex(fkeyCreateIndex(false)); + assertEquals("create index ix_mytab_acol on mytab (acol)", sql); + } + +}