diff --git a/CHANGELOG.md b/CHANGELOG.md
index ce440caf..4df391ec 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,10 +5,13 @@
### Functionality Improvements
#182: Adding Hibernate reverse-engineering API. See [ORM Integration docs](https://goldmansachs.github.io/obevo/orm-integration.html) for more details.
#221 #223 #225: Oracle reverse-engineering improvements - unicode characters, nested tables, types, comments
+#227: PostgreSQL improvements for kata - reverse-engineering, in-memory databases
### Technical Improvements
+#227: Upgrading checkstyle version to avoid security prompts at Github site
### Bug Fixes
+#227: Fixed drop behavior of PostgreSQL for multiple views that depended on each other
## 7.0.2
diff --git a/obevo-db-impls/obevo-db-postgresql/obevo-db-postgresql.iml b/obevo-db-impls/obevo-db-postgresql/obevo-db-postgresql.iml
index 19eb5bfe..78c1e2b2 100644
--- a/obevo-db-impls/obevo-db-postgresql/obevo-db-postgresql.iml
+++ b/obevo-db-impls/obevo-db-postgresql/obevo-db-postgresql.iml
@@ -78,6 +78,10 @@
+
+
+
+
diff --git a/obevo-db-impls/obevo-db-postgresql/pom.xml b/obevo-db-impls/obevo-db-postgresql/pom.xml
index 09914838..2b2db99c 100644
--- a/obevo-db-impls/obevo-db-postgresql/pom.xml
+++ b/obevo-db-impls/obevo-db-postgresql/pom.xml
@@ -49,6 +49,21 @@
postgresql
+
+ com.goldmansachs.obevo
+ obevo-db-h2
+ ${project.version}
+ true
+
+
+
+ com.goldmansachs.obevo
+ obevo-db-hsql
+ ${project.version}
+ true
+
+
+
com.goldmansachs.obevo
obevo-db-internal-test-helper
diff --git a/obevo-db-impls/obevo-db-postgresql/src/main/java/com/gs/obevo/db/impl/platforms/postgresql/PostgreSqlDbPlatform.java b/obevo-db-impls/obevo-db-postgresql/src/main/java/com/gs/obevo/db/impl/platforms/postgresql/PostgreSqlDbPlatform.java
index 43f290c4..97596992 100644
--- a/obevo-db-impls/obevo-db-postgresql/src/main/java/com/gs/obevo/db/impl/platforms/postgresql/PostgreSqlDbPlatform.java
+++ b/obevo-db-impls/obevo-db-postgresql/src/main/java/com/gs/obevo/db/impl/platforms/postgresql/PostgreSqlDbPlatform.java
@@ -20,6 +20,8 @@
import com.gs.obevo.db.api.appdata.GrantTargetType;
import com.gs.obevo.db.api.platform.DbChangeType;
import com.gs.obevo.db.api.platform.DbChangeTypeImpl;
+import com.gs.obevo.db.api.platform.DbPlatform;
+import com.gs.obevo.db.api.platform.DbTranslationDialect;
import com.gs.obevo.db.apps.reveng.AbstractDdlReveng;
import com.gs.obevo.db.impl.platforms.AbstractDbPlatform;
import org.eclipse.collections.api.block.function.Function;
@@ -116,4 +118,13 @@ public ImmutableSet getRequiredValidationObjectTypes() {
public AbstractDdlReveng getDdlReveng() {
return new PostgreSqlPgDumpReveng();
}
+
+ @Override
+ public DbTranslationDialect getDbTranslationDialect(DbPlatform targetDialect) {
+ if (targetDialect.getClass().getName().equals("com.gs.obevo.db.impl.platforms.hsql.HsqlDbPlatform")) {
+ return new PostgreSqlToHsqlTranslationDialect();
+ } else {
+ return super.getDbTranslationDialect(targetDialect);
+ }
+ }
}
diff --git a/obevo-db-impls/obevo-db-postgresql/src/main/java/com/gs/obevo/db/impl/platforms/postgresql/PostgreSqlPgDumpReveng.java b/obevo-db-impls/obevo-db-postgresql/src/main/java/com/gs/obevo/db/impl/platforms/postgresql/PostgreSqlPgDumpReveng.java
index 59a27338..f9729559 100644
--- a/obevo-db-impls/obevo-db-postgresql/src/main/java/com/gs/obevo/db/impl/platforms/postgresql/PostgreSqlPgDumpReveng.java
+++ b/obevo-db-impls/obevo-db-postgresql/src/main/java/com/gs/obevo/db/impl/platforms/postgresql/PostgreSqlPgDumpReveng.java
@@ -105,7 +105,8 @@ protected boolean doRevengOrInstructions(PrintStream out, AquaRevengArgs args, F
private String getCommandWithDefaults(boolean container, AquaRevengArgs args, File interimDir, String username, String password, String dbHost, String dbPort, String dbName, String dbSchema, String outputDirectory) {
String prefix = container ? "docker exec $CONTAINER_NAME " : "";
- String fileSuffix = container ? "> " + interimDir.getAbsolutePath() : " -f " + interimDir.getAbsolutePath();
+ String fileSuffix = container ? "> " : " -f ";
+ fileSuffix += new File(interimDir, "revengoutput.txt").getAbsolutePath();
return prefix + "pg_dump -O -s --no-privileges" +
" -h " + ObjectUtils.defaultIfNull(args.getDbHost(), dbHost) +
" -p " + ObjectUtils.defaultIfNull(args.getDbPort(), dbPort) +
diff --git a/obevo-db-impls/obevo-db-postgresql/src/main/java/com/gs/obevo/db/impl/platforms/postgresql/PostgreSqlToH2TranslationDialect.java b/obevo-db-impls/obevo-db-postgresql/src/main/java/com/gs/obevo/db/impl/platforms/postgresql/PostgreSqlToH2TranslationDialect.java
new file mode 100644
index 00000000..d2efcbbd
--- /dev/null
+++ b/obevo-db-impls/obevo-db-postgresql/src/main/java/com/gs/obevo/db/impl/platforms/postgresql/PostgreSqlToH2TranslationDialect.java
@@ -0,0 +1,27 @@
+/**
+ * Copyright 2017 Goldman Sachs.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.gs.obevo.db.impl.platforms.postgresql;
+
+import com.gs.obevo.db.impl.platforms.DefaultDbTranslationDialect;
+import org.eclipse.collections.api.list.ImmutableList;
+import org.eclipse.collections.impl.factory.Lists;
+
+public class PostgreSqlToH2TranslationDialect extends DefaultDbTranslationDialect {
+ @Override
+ public ImmutableList getInitSqls() {
+ return Lists.immutable.with("SET MODE PostgreSQL");
+ }
+}
diff --git a/obevo-db-impls/obevo-db-postgresql/src/main/java/com/gs/obevo/db/impl/platforms/postgresql/PostgreSqlToHsqlTranslationDialect.java b/obevo-db-impls/obevo-db-postgresql/src/main/java/com/gs/obevo/db/impl/platforms/postgresql/PostgreSqlToHsqlTranslationDialect.java
new file mode 100644
index 00000000..df351769
--- /dev/null
+++ b/obevo-db-impls/obevo-db-postgresql/src/main/java/com/gs/obevo/db/impl/platforms/postgresql/PostgreSqlToHsqlTranslationDialect.java
@@ -0,0 +1,92 @@
+/**
+ * Copyright 2017 Goldman Sachs.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.gs.obevo.db.impl.platforms.postgresql;
+
+import java.sql.Connection;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import com.gs.obevo.api.platform.ChangeType;
+import com.gs.obevo.db.impl.core.jdbc.JdbcHelper;
+import com.gs.obevo.db.impl.platforms.DefaultDbTranslationDialect;
+import com.gs.obevo.db.impl.platforms.sqltranslator.InMemoryTranslator;
+import com.gs.obevo.db.impl.platforms.sqltranslator.PostColumnSqlTranslator;
+import com.gs.obevo.db.impl.platforms.sqltranslator.PreParsedSqlTranslator;
+import com.gs.obevo.db.impl.platforms.sqltranslator.SqlTranslatorConfigHelper;
+import com.gs.obevo.db.sqlparser.syntaxparser.CreateTable;
+import com.gs.obevo.db.sqlparser.syntaxparser.CreateTableColumn;
+import com.gs.obevo.impl.PrepareDbChange;
+import org.eclipse.collections.api.list.ImmutableList;
+import org.eclipse.collections.api.set.ImmutableSet;
+import org.eclipse.collections.impl.factory.Lists;
+import org.eclipse.collections.impl.factory.Sets;
+
+public class PostgreSqlToHsqlTranslationDialect extends DefaultDbTranslationDialect {
+ private final PostColumnSqlTranslator replaceNextvalWithIdentity = new PostColumnSqlTranslator() {
+ private final Pattern defaultPattern = Pattern.compile("(?i)default\\s+nextval.*", Pattern.DOTALL);
+
+ @Override
+ public String handlePostColumnText(String postColumnText, CreateTableColumn column, CreateTable table) {
+ Matcher defaultMatcher = defaultPattern.matcher(postColumnText);
+ if (defaultMatcher.find()) {
+ postColumnText = defaultMatcher.replaceFirst("IDENTITY");
+ }
+
+ return postColumnText;
+ }
+ };
+
+ private final PreParsedSqlTranslator substituteCreateOrReplace = new PreParsedSqlTranslator() {
+ Pattern pattern = Pattern.compile("(?i)^\\s*create\\s+or\\s+replace\\s+", Pattern.DOTALL);
+ @Override
+ public String preprocessSql(String sql) {
+ Matcher matcher = pattern.matcher(sql);
+ if (matcher.find()) {
+ sql = matcher.replaceFirst("create ");
+ }
+ return sql;
+ }
+ };
+
+ @Override
+ public ImmutableList getInitSqls() {
+ return Lists.immutable.with(
+ "SET DATABASE SQL SYNTAX PGS TRUE"
+ , "SET DATABASE TRANSACTION CONTROL MVCC"
+ );
+ }
+
+ @Override
+ public ImmutableList getAdditionalTranslators() {
+ SqlTranslatorConfigHelper configHelper = SqlTranslatorConfigHelper.createInMemoryDefault();
+
+ configHelper.getPreParsedSqlTranslators()
+ .with(substituteCreateOrReplace);
+ configHelper.getPostColumnSqlTranslators()
+ .with(replaceNextvalWithIdentity);
+ return Lists.immutable.with(new InMemoryTranslator(configHelper));
+ }
+
+ @Override
+ public void initSchema(JdbcHelper jdbc, Connection conn) {
+ updateAndIgnoreException(conn, jdbc, "create type int4 as integer");
+ }
+
+ @Override
+ public ImmutableSet getDisabledChangeTypeNames() {
+ return Sets.immutable.of(ChangeType.FUNCTION_STR, ChangeType.SP_STR);
+ }
+}
diff --git a/obevo-db-impls/obevo-db-postgresql/src/test/java/com/gs/obevo/db/impl/platforms/postgresql/PostgreSqlInMemConversionTest.java b/obevo-db-impls/obevo-db-postgresql/src/test/java/com/gs/obevo/db/impl/platforms/postgresql/PostgreSqlInMemConversionTest.java
new file mode 100644
index 00000000..c6d4380d
--- /dev/null
+++ b/obevo-db-impls/obevo-db-postgresql/src/test/java/com/gs/obevo/db/impl/platforms/postgresql/PostgreSqlInMemConversionTest.java
@@ -0,0 +1,53 @@
+/**
+ * Copyright 2017 Goldman Sachs.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.gs.obevo.db.impl.platforms.postgresql;
+
+import com.gs.obevo.db.api.platform.DbDeployerAppContext;
+import com.gs.obevo.db.impl.platforms.h2.H2DbPlatform;
+import com.gs.obevo.db.impl.platforms.hsql.HsqlDbPlatform;
+import com.gs.obevo.db.unittest.UnitTestDbBuilder;
+import org.junit.Test;
+
+public class PostgreSqlInMemConversionTest {
+ @Test
+ public void testInMemoryHsql() {
+ DbDeployerAppContext context = UnitTestDbBuilder.newBuilder()
+ .setSourcePath("platforms/postgresql/example1/step1/system-config-inmem.xml")
+ .setReferenceEnvName("unittestrefhsql")
+ .setDbPlatform(new HsqlDbPlatform())
+ .setDbServer("mydb2testHsql")
+ .buildContext();
+ context.setupEnvInfra();
+ context.cleanAndDeploy();
+
+ // TODO add assertions
+ }
+
+ // Implementation for H2 TBD
+// @Test
+// public void testInMemoryH2() {
+// DbDeployerAppContext context = UnitTestDbBuilder.newBuilder()
+// .setSourcePath("platforms/postgresql/example1/step1/system-config-inmem.xml")
+// .setReferenceEnvName("unittestrefh2")
+// .setDbPlatform(new H2DbPlatform())
+// .setDbServer("mydb2testH2")
+// .buildContext();
+// context.setupEnvInfra();
+// context.cleanAndDeploy();
+//
+// // TODO add assertions
+// }
+}
diff --git a/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step1/schema1/table/TABLE_A.ddl b/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step1/schema1/table/TABLE_A.ddl
index effbdcbb..2891013b 100644
--- a/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step1/schema1/table/TABLE_A.ddl
+++ b/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step1/schema1/table/TABLE_A.ddl
@@ -1,29 +1,29 @@
-//// CHANGE name=chng1
-CREATE TABLE TABLE_A (
- A_ID INT NOT NULL,
- B_ID INT NOT NULL,
- STRING_FIELD VARCHAR(30) NULL,
- TIMESTAMP_FIELD TIMESTAMP NULL,
- PRIMARY KEY (A_ID)
-)
-GO
-
-//// CHANGE name=emptychange
-//// CHANGE name=emptychange2
-
-
-//// CHANGE FK name=chng2
-ALTER TABLE TABLE_A ADD FOREIGN KEY (B_ID) REFERENCES TABLE_B(B_ID)
-GO
-//// CHANGE name=chng3
-ALTER TABLE TABLE_A ADD COLUMN C_ID INT NULL
-GO
-//// CHANGE name=extra1
-ALTER TABLE TABLE_A ADD COLUMN EXTRA1 INT NULL
-GO
-//// CHANGE name=extra2
-ALTER TABLE TABLE_A ADD COLUMN EXTRA2 INT NULL
-GO
-//// CHANGE name=extra3
-ALTER TABLE TABLE_A ADD COLUMN EXTRA3 INT NULL
-GO
+//// CHANGE name=chng1
+CREATE TABLE TABLE_A (
+ A_ID INT NOT NULL,
+ B_ID INT NOT NULL,
+ STRING_FIELD VARCHAR(30) NULL,
+ TIMESTAMP_FIELD TIMESTAMP NULL,
+ PRIMARY KEY (A_ID)
+) WITHOUT OIDS
+GO
+
+//// CHANGE name=emptychange
+//// CHANGE name=emptychange2
+
+
+//// CHANGE FK name=chng2
+ALTER TABLE TABLE_A ADD FOREIGN KEY (B_ID) REFERENCES TABLE_B(B_ID)
+GO
+//// CHANGE name=chng3
+ALTER TABLE TABLE_A ADD COLUMN C_ID INT NULL
+GO
+//// CHANGE name=extra1
+ALTER TABLE TABLE_A ADD COLUMN EXTRA1 INT NULL
+GO
+//// CHANGE name=extra2
+ALTER TABLE TABLE_A ADD COLUMN EXTRA2 INT NULL
+GO
+//// CHANGE name=extra3
+ALTER TABLE TABLE_A ADD COLUMN EXTRA3 INT NULL
+GO
diff --git a/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step1/schema1/table/TABLE_B.ddl b/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step1/schema1/table/TABLE_B.ddl
index cff127c4..81b93691 100644
--- a/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step1/schema1/table/TABLE_B.ddl
+++ b/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step1/schema1/table/TABLE_B.ddl
@@ -1,5 +1,5 @@
-//// CHANGE name=chng1
-CREATE TABLE TABLE_B (
- B_ID INT NOT NULL,
- PRIMARY KEY (B_ID)
-)
+//// CHANGE name=chng1
+CREATE TABLE TABLE_B (
+ B_ID INT NOT NULL,
+ PRIMARY KEY (B_ID)
+) WITHOUT OIDS
diff --git a/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step1/schema1/table/TABLE_SPECIAL_COL.ddl b/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step1/schema1/table/TABLE_SPECIAL_COL.ddl
index 3114fe83..71698aea 100644
--- a/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step1/schema1/table/TABLE_SPECIAL_COL.ddl
+++ b/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step1/schema1/table/TABLE_SPECIAL_COL.ddl
@@ -3,5 +3,5 @@ CREATE TABLE TABLE_SPECIAL_COL (
UUID_PK UUID NOT NULL,
STR1 VARCHAR(30) NULL,
PRIMARY KEY (UUID_PK)
-)
+) WITHOUT OIDS
GO
diff --git a/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step1/schema1/table/TAB_WITH_SEQ.ddl b/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step1/schema1/table/TAB_WITH_SEQ.ddl
index c6e7ed25..24889b18 100644
--- a/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step1/schema1/table/TAB_WITH_SEQ.ddl
+++ b/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step1/schema1/table/TAB_WITH_SEQ.ddl
@@ -1,8 +1,8 @@
-//// METADATA excludePlatforms=REDSHIFT
-//// CHANGE name=chng1
-CREATE TABLE TAB_WITH_SEQ (
- ID int4 NOT NULL DEFAULT nextval('MYSEQ1'::regclass),
- FIELD1 INT NULL,
- PRIMARY KEY (ID)
-)
-GO
+//// METADATA excludePlatforms=REDSHIFT
+//// CHANGE name=chng1
+CREATE TABLE TAB_WITH_SEQ (
+ ID int4 NOT NULL DEFAULT nextval('MYSEQ1'::regclass),
+ FIELD1 INT NULL,
+ PRIMARY KEY (ID)
+) WITHOUT OIDS
+GO
diff --git a/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step1/schema1/usertype/usertype0.hsql.sql b/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step1/schema1/usertype/usertype0.hsql.sql
new file mode 100644
index 00000000..93efe056
--- /dev/null
+++ b/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step1/schema1/usertype/usertype0.hsql.sql
@@ -0,0 +1,3 @@
+//// METADATA includePlatforms="HSQL"
+CREATE TYPE usertype0 AS VARCHAR(1);
+GO
diff --git a/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step1/schema1/usertype/usertype0.sql b/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step1/schema1/usertype/usertype0.sql
index bfe03d74..bf6ab05b 100644
--- a/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step1/schema1/usertype/usertype0.sql
+++ b/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step1/schema1/usertype/usertype0.sql
@@ -1,3 +1,4 @@
+//// METADATA excludePlatforms="HSQL"
CREATE TYPE usertype0 AS ENUM (
'1',
'2',
diff --git a/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step1/system-config-inmem.xml b/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step1/system-config-inmem.xml
new file mode 100644
index 00000000..2a94b414
--- /dev/null
+++ b/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step1/system-config-inmem.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step2/schema1/table/TABLE_A.ddl b/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step2/schema1/table/TABLE_A.ddl
index a8382583..3b88b31f 100644
--- a/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step2/schema1/table/TABLE_A.ddl
+++ b/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step2/schema1/table/TABLE_A.ddl
@@ -1,32 +1,32 @@
-//// CHANGE name=chng1
-CREATE TABLE TABLE_A (
- A_ID INT NOT NULL,
- B_ID INT NOT NULL,
- STRING_FIELD VARCHAR(30) NULL,
- TIMESTAMP_FIELD TIMESTAMP NULL,
- PRIMARY KEY (A_ID)
-)
-GO
-
-//// CHANGE name=emptychange
-//// CHANGE name=emptychange2
-
-
-//// CHANGE FK name=chng2
-ALTER TABLE TABLE_A ADD FOREIGN KEY (B_ID) REFERENCES TABLE_B(B_ID)
-GO
-//// CHANGE name=chng3
-ALTER TABLE TABLE_A ADD COLUMN C_ID INT NULL
-GO
-//// CHANGE name=extra1
-ALTER TABLE TABLE_A ADD COLUMN EXTRA1 INT NULL
-GO
-//// CHANGE name=extra2
-ALTER TABLE TABLE_A ADD COLUMN EXTRA2 INT NULL
-GO
-//// CHANGE name=extra3
-ALTER TABLE TABLE_A ADD COLUMN EXTRA3 INT NULL
-GO
-//// CHANGE name=extra4
-ALTER TABLE TABLE_A ADD COLUMN EXTRA4 INT NULL
-GO
+//// CHANGE name=chng1
+CREATE TABLE TABLE_A (
+ A_ID INT NOT NULL,
+ B_ID INT NOT NULL,
+ STRING_FIELD VARCHAR(30) NULL,
+ TIMESTAMP_FIELD TIMESTAMP NULL,
+ PRIMARY KEY (A_ID)
+) WITHOUT OIDS
+GO
+
+//// CHANGE name=emptychange
+//// CHANGE name=emptychange2
+
+
+//// CHANGE FK name=chng2
+ALTER TABLE TABLE_A ADD FOREIGN KEY (B_ID) REFERENCES TABLE_B(B_ID)
+GO
+//// CHANGE name=chng3
+ALTER TABLE TABLE_A ADD COLUMN C_ID INT NULL
+GO
+//// CHANGE name=extra1
+ALTER TABLE TABLE_A ADD COLUMN EXTRA1 INT NULL
+GO
+//// CHANGE name=extra2
+ALTER TABLE TABLE_A ADD COLUMN EXTRA2 INT NULL
+GO
+//// CHANGE name=extra3
+ALTER TABLE TABLE_A ADD COLUMN EXTRA3 INT NULL
+GO
+//// CHANGE name=extra4
+ALTER TABLE TABLE_A ADD COLUMN EXTRA4 INT NULL
+GO
diff --git a/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step2/schema1/table/TABLE_B.ddl b/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step2/schema1/table/TABLE_B.ddl
index cff127c4..81b93691 100644
--- a/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step2/schema1/table/TABLE_B.ddl
+++ b/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step2/schema1/table/TABLE_B.ddl
@@ -1,5 +1,5 @@
-//// CHANGE name=chng1
-CREATE TABLE TABLE_B (
- B_ID INT NOT NULL,
- PRIMARY KEY (B_ID)
-)
+//// CHANGE name=chng1
+CREATE TABLE TABLE_B (
+ B_ID INT NOT NULL,
+ PRIMARY KEY (B_ID)
+) WITHOUT OIDS
diff --git a/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step2/schema1/table/TABLE_SPECIAL_COL.ddl b/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step2/schema1/table/TABLE_SPECIAL_COL.ddl
index 3114fe83..71698aea 100644
--- a/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step2/schema1/table/TABLE_SPECIAL_COL.ddl
+++ b/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step2/schema1/table/TABLE_SPECIAL_COL.ddl
@@ -3,5 +3,5 @@ CREATE TABLE TABLE_SPECIAL_COL (
UUID_PK UUID NOT NULL,
STR1 VARCHAR(30) NULL,
PRIMARY KEY (UUID_PK)
-)
+) WITHOUT OIDS
GO
diff --git a/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step2/schema1/table/TAB_WITH_SEQ.ddl b/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step2/schema1/table/TAB_WITH_SEQ.ddl
index c6e7ed25..24889b18 100644
--- a/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step2/schema1/table/TAB_WITH_SEQ.ddl
+++ b/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step2/schema1/table/TAB_WITH_SEQ.ddl
@@ -1,8 +1,8 @@
-//// METADATA excludePlatforms=REDSHIFT
-//// CHANGE name=chng1
-CREATE TABLE TAB_WITH_SEQ (
- ID int4 NOT NULL DEFAULT nextval('MYSEQ1'::regclass),
- FIELD1 INT NULL,
- PRIMARY KEY (ID)
-)
-GO
+//// METADATA excludePlatforms=REDSHIFT
+//// CHANGE name=chng1
+CREATE TABLE TAB_WITH_SEQ (
+ ID int4 NOT NULL DEFAULT nextval('MYSEQ1'::regclass),
+ FIELD1 INT NULL,
+ PRIMARY KEY (ID)
+) WITHOUT OIDS
+GO
diff --git a/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step2/schema1/usertype/usertype0.hsql.sql b/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step2/schema1/usertype/usertype0.hsql.sql
new file mode 100644
index 00000000..93efe056
--- /dev/null
+++ b/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step2/schema1/usertype/usertype0.hsql.sql
@@ -0,0 +1,3 @@
+//// METADATA includePlatforms="HSQL"
+CREATE TYPE usertype0 AS VARCHAR(1);
+GO
diff --git a/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step2/schema1/usertype/usertype0.sql b/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step2/schema1/usertype/usertype0.sql
index bfe03d74..bf6ab05b 100644
--- a/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step2/schema1/usertype/usertype0.sql
+++ b/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step2/schema1/usertype/usertype0.sql
@@ -1,3 +1,4 @@
+//// METADATA excludePlatforms="HSQL"
CREATE TYPE usertype0 AS ENUM (
'1',
'2',
diff --git a/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step2/system-config-inmem.xml b/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step2/system-config-inmem.xml
new file mode 100644
index 00000000..2a94b414
--- /dev/null
+++ b/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step2/system-config-inmem.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/obevo-db/src/main/java/com/gs/obevo/db/apps/reveng/AbstractDdlReveng.java b/obevo-db/src/main/java/com/gs/obevo/db/apps/reveng/AbstractDdlReveng.java
index a8ba9f8b..ceacfd39 100644
--- a/obevo-db/src/main/java/com/gs/obevo/db/apps/reveng/AbstractDdlReveng.java
+++ b/obevo-db/src/main/java/com/gs/obevo/db/apps/reveng/AbstractDdlReveng.java
@@ -177,7 +177,7 @@ public void reveng(AquaRevengArgs args) {
System.out.println("***********");
System.out.println();
System.out.println("Once those steps are done, rerun the reverse-engineering command you just ran, but add the following argument based on the value passed in above the argument:");
- System.out.println(" -inputPath " + ObjectUtils.defaultIfNull(args.getOutputPath(), ""));
+ System.out.println(" -inputPath " + interimDir.getAbsolutePath());
System.out.println();
System.out.println("If you need more information on the vendor reverse engineer process, see the doc: https://goldmansachs.github.io/obevo/reverse-engineer-dbmstools.html");
}
diff --git a/obevo-db/src/main/java/com/gs/obevo/db/impl/platforms/sqltranslator/PostColumnSqlTranslator.java b/obevo-db/src/main/java/com/gs/obevo/db/impl/platforms/sqltranslator/PostColumnSqlTranslator.java
index 9e50df7c..9ecbd896 100644
--- a/obevo-db/src/main/java/com/gs/obevo/db/impl/platforms/sqltranslator/PostColumnSqlTranslator.java
+++ b/obevo-db/src/main/java/com/gs/obevo/db/impl/platforms/sqltranslator/PostColumnSqlTranslator.java
@@ -1,23 +1,23 @@
-/**
- * Copyright 2017 Goldman Sachs.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package com.gs.obevo.db.impl.platforms.sqltranslator;
-
-import com.gs.obevo.db.sqlparser.syntaxparser.CreateTable;
-import com.gs.obevo.db.sqlparser.syntaxparser.CreateTableColumn;
-
-public interface PostColumnSqlTranslator {
- String handlePostColumnText(String sql, CreateTableColumn column, CreateTable table);
-}
+/**
+ * Copyright 2017 Goldman Sachs.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.gs.obevo.db.impl.platforms.sqltranslator;
+
+import com.gs.obevo.db.sqlparser.syntaxparser.CreateTable;
+import com.gs.obevo.db.sqlparser.syntaxparser.CreateTableColumn;
+
+public interface PostColumnSqlTranslator {
+ String handlePostColumnText(String postColumnText, CreateTableColumn column, CreateTable table);
+}
diff --git a/obevo-db/src/main/jjtree/sqlInMemTranslate.jjt b/obevo-db/src/main/jjtree/sqlInMemTranslate.jjt
index 5fd2b427..2841294b 100644
--- a/obevo-db/src/main/jjtree/sqlInMemTranslate.jjt
+++ b/obevo-db/src/main/jjtree/sqlInMemTranslate.jjt
@@ -157,7 +157,7 @@ TOKEN :
TOKEN :
{
- < IDENTIFIER: (||||||)+ >
+ < IDENTIFIER: (|||||||)+ >
|
< #LETTER:
[
@@ -211,6 +211,7 @@ TOKEN :
| < DOLLAR: "$" >
| < DOT: "." >
| < POUND: "#" >
+| < COLON: ":" >
}
diff --git a/obevo-utils/obevo-db-unittest-util/src/main/java/com/gs/obevo/db/unittest/UnitTestDbBuilder.java b/obevo-utils/obevo-db-unittest-util/src/main/java/com/gs/obevo/db/unittest/UnitTestDbBuilder.java
index 0b8aa94b..8fdb046e 100644
--- a/obevo-utils/obevo-db-unittest-util/src/main/java/com/gs/obevo/db/unittest/UnitTestDbBuilder.java
+++ b/obevo-utils/obevo-db-unittest-util/src/main/java/com/gs/obevo/db/unittest/UnitTestDbBuilder.java
@@ -1,288 +1,295 @@
-/**
- * Copyright 2017 Goldman Sachs.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package com.gs.obevo.db.unittest;
-
-import java.io.File;
-import java.util.Set;
-
-import com.gs.obevo.api.appdata.ChangeKey;
-import com.gs.obevo.api.platform.ChangeType;
-import com.gs.obevo.api.platform.MainDeployerArgs;
-import com.gs.obevo.db.api.appdata.DbEnvironment;
-import com.gs.obevo.db.api.appdata.Permission;
-import com.gs.obevo.db.api.factory.DbEnvironmentFactory;
-import com.gs.obevo.db.api.platform.DbDeployerAppContext;
-import com.gs.obevo.db.api.platform.DbPlatform;
-import com.gs.obevo.impl.changepredicate.ChangeKeyPredicateBuilder;
-import com.gs.obevo.util.inputreader.Credential;
-import org.apache.commons.lang3.Validate;
-import org.eclipse.collections.api.block.predicate.Predicate;
-import org.eclipse.collections.api.list.MutableList;
-import org.eclipse.collections.api.map.MutableMap;
-import org.eclipse.collections.api.set.ImmutableSet;
-import org.eclipse.collections.impl.block.factory.Predicates;
-import org.eclipse.collections.impl.factory.Lists;
-import org.eclipse.collections.impl.factory.Maps;
-import org.eclipse.collections.impl.factory.Sets;
-
-/**
- * Helper class for building unit test db environments and contexts, i.e. to not have to remember details for each unit
- * test db type and to easily switch between unit test DBMS's if needed
- *
- * Ultimately, this will delegate to Environment.getAppContextBuilder() for building the context. This class will mainly
- * leverage a client's existing DbEnvironment setup and tweak values accordingly
- *
- * If an existing environment is referenced, a copy of that DbEnvironment will be made by this class so that any changes
- * to that object will not impact anything existing
- */
-public class UnitTestDbBuilder {
- public static UnitTestDbBuilder newBuilder() {
- return new UnitTestDbBuilder();
- }
-
- /**
- * Caching the contexts created so that subsequent operations on this can go quickly (i.e. avoiding the costs of
- * reading the contents from the file system).
- */
- private static final MutableMap cachedContexts = Maps.mutable.empty();
-
- private String sourcePath;
- private String envName;
- private String referenceEnvName;
- private DbPlatform dbPlatform;
- private String dbServer = "test";
- private ImmutableSet tables;
- private ImmutableSet views;
- private boolean persistToFile = false;
- private boolean grantsDisabled = true; // disabling grants by default for unit tests as in practice, most teams
- private File workDir = new File("./target/unitdb");
- private Credential credential = new Credential("sa", "");
-
- /**
- * (Required) path to read environment metadata from
- */
- public UnitTestDbBuilder setSourcePath(String sourcePath) {
- this.sourcePath = sourcePath;
- return this;
- }
-
- /**
- * Name to give the environment created during this builder
- *
- * If not specified, will use the name and environment specified by the referenceEnvName parameter
- */
- public UnitTestDbBuilder setEnvName(String envName) {
- this.envName = envName;
- return this;
- }
-
- /**
- * Environment to use as a model for the unit test db environment to create
- *
- * If not specified, then one of the environments read from the source path will be picked arbitrarily. The envName
- * parameter must then be specified to give this unit test db environment a known name
- */
- public UnitTestDbBuilder setReferenceEnvName(String referenceEnvName) {
- this.referenceEnvName = referenceEnvName;
- return this;
- }
-
- /**
- * dbPlatform to use for the new unit test db
- *
- * If not specified, will default to the dbPlatform of the reference environment
- */
- public UnitTestDbBuilder setDbPlatform(DbPlatform dbPlatform) {
- this.dbPlatform = dbPlatform;
- return this;
- }
-
- /**
- * Name of the in-memory db to be created to be used when creating the URL, e.g. jdbc:h2:mem:<dbServer>:etc.
- * This is a convenience for clients to not have to remember the URL convention. The resolved URL can be retrieved
- * from the DbEnvironment instance
- *
- * If not specified, will default to "test"
- */
- public UnitTestDbBuilder setDbServer(String dbServer) {
- this.dbServer = dbServer;
- return this;
- }
-
- /**
- * Specify this to restrict the tables deployed to just the ones provided. If not specified, all tables will be deployed.
- *
- * @deprecated Specify these fields to remove in the {@link DbDeployerAppContext#deploy(MainDeployerArgs)} arguments itself.
- */
- @Deprecated
- public UnitTestDbBuilder setTables(Set tables) {
- this.tables = Sets.immutable.withAll(tables);
- return this;
- }
-
- /**
- * Specify this to restrict the views deployed to just the ones provided. If not specified, all views will be deployed.
- *
- * @deprecated Specify these fields to remove in the {@link DbDeployerAppContext#deploy(MainDeployerArgs)} arguments itself.
- */
- @Deprecated
- public UnitTestDbBuilder setViews(Set views) {
- this.views = Sets.immutable.withAll(views);
- return this;
- }
-
- /**
- * If true, will generate the file-persistent URL for the in-memory database. If false, goes w/ the in-memory URL
- *
- * Defaults to false (in-memory)
- */
- public UnitTestDbBuilder setPersistToFile(boolean persistToFile) {
- this.persistToFile = persistToFile;
- return this;
- }
-
- private boolean isPersistToFile() {
- // We support this system property here to facilitate easy debugging for
- // unit tests (i.e. if we don't want to change the code accidentally when running/debugging)
- // But we can still set this programatically anyway
- if (System.getProperty("debugDbUnit") == null) {
- return this.persistToFile;
- } else {
- return "true".equalsIgnoreCase(System.getProperty("debugDbUnit"));
- }
- }
-
- /**
- * @deprecated Clients should move off this. Leverage the groups and users sections in your DbEnvironment configuration to have the grants created
- */
- @Deprecated
- public UnitTestDbBuilder setGrantsDisabled(boolean grantsDisabled) {
- this.grantsDisabled = grantsDisabled;
- return this;
- }
-
- /**
- * The workDir to use for any temporary files used for the db deployment
- *
- * If not specified, defaults to "./target/unitdb" (i.e. relative to your working directory)
- */
- public UnitTestDbBuilder setWorkDir(File workDir) {
- this.workDir = workDir;
- return this;
- }
-
- /**
- * (optional) credential defaults to username==sa and password==<blank>, per the default convention of h2/hsql
- */
- public UnitTestDbBuilder setCredential(Credential credential) {
- this.credential = credential;
- return this;
- }
-
- private void validateBuilder() {
- if (envName == null && referenceEnvName == null) {
- throw new IllegalArgumentException("One of envName or referenceEnvName must be populated");
- }
- Validate.notNull(sourcePath);
- Validate.notNull(credential);
- }
-
- public DbDeployerAppContext buildContext() {
- validateBuilder();
-
- String instanceLookupKey = instanceLookupKey();
-
- DbDeployerAppContext baseContext = cachedContexts.get(instanceLookupKey);
-
- if (baseContext == null) {
- baseContext = buildContextUncached();
- cachedContexts.put(instanceLookupKey, baseContext);
- }
-
- // set the arguments that should be used as defined in this builder class, e.g. for limiting by specific tables
- return new UnitTestDbDeployerAppContext(baseContext, getMainDeployerArgs());
- }
-
- /**
- * Builds the deployer context. See the class Javadoc for more information
- */
- private DbDeployerAppContext buildContextUncached() {
- validateBuilder();
-
- String[] envsToRequest = this.referenceEnvName != null ? new String[] { this.referenceEnvName } : new String[0];
- DbEnvironment referenceEnv = DbEnvironmentFactory.getInstance().readFromSourcePath(this.sourcePath, envsToRequest)
- .getFirst();
-
- DbEnvironment env = referenceEnv.createCopy();
-
- if (this.envName != null) {
- env.setName(this.envName);
- }
-
- env.setDisableAuditTracking(true);
- env.setPersistToFile(this.isPersistToFile());
-
- if (this.dbPlatform != null) {
- env.setPlatform(this.dbPlatform);
- }
-
- if (this.dbServer != null) {
- env.setDbServer(this.dbServer);
- }
-
- if (this.grantsDisabled) {
- env.setPermissions(Lists.immutable.empty());
- }
-
- env.setDefaultUserId(credential.getUsername());
- env.setDefaultPassword(credential.getPassword());
-
- return env.getAppContextBuilder()
- .setWorkDir(workDir)
- .build();
- }
-
- private MainDeployerArgs getMainDeployerArgs() {
- MainDeployerArgs args = new MainDeployerArgs();
-
- if (this.tables != null || this.views != null) {
- MutableList> predicates = Lists.mutable.empty();
- if (this.tables != null) {
- predicates.add(ChangeKeyPredicateBuilder.newBuilder()
- .setChangeTypes(ChangeType.TABLE_STR, ChangeType.FOREIGN_KEY_STR, ChangeType.TRIGGER_INCREMENTAL_OLD_STR, ChangeType.STATICDATA_STR)
- .setObjectNames(Sets.immutable.withAll(this.tables))
- .build());
- }
- if (this.views != null) {
- predicates.add(ChangeKeyPredicateBuilder.newBuilder()
- .setChangeTypes(ChangeType.VIEW_STR)
- .setObjectNames(Sets.immutable.withAll(this.views))
- .build());
- }
-
- args.setChangeInclusionPredicate(Predicates.or(predicates));
- }
-
- args.setAllChangesets(true); // for unit tests, we always want all changes to deploy
- return args;
- }
-
- private String instanceLookupKey() {
- String envNameToLookup = envName != null ? envName : referenceEnvName;
-
- return this.sourcePath + ":" + envNameToLookup;
- }
-}
+/**
+ * Copyright 2017 Goldman Sachs.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.gs.obevo.db.unittest;
+
+import java.io.File;
+import java.util.Set;
+
+import com.gs.obevo.api.appdata.ChangeKey;
+import com.gs.obevo.api.platform.ChangeType;
+import com.gs.obevo.api.platform.MainDeployerArgs;
+import com.gs.obevo.db.api.appdata.DbEnvironment;
+import com.gs.obevo.db.api.appdata.Permission;
+import com.gs.obevo.db.api.factory.DbEnvironmentFactory;
+import com.gs.obevo.db.api.platform.DbDeployerAppContext;
+import com.gs.obevo.db.api.platform.DbPlatform;
+import com.gs.obevo.impl.changepredicate.ChangeKeyPredicateBuilder;
+import com.gs.obevo.util.inputreader.Credential;
+import org.apache.commons.lang3.Validate;
+import org.eclipse.collections.api.block.predicate.Predicate;
+import org.eclipse.collections.api.list.MutableList;
+import org.eclipse.collections.api.map.MutableMap;
+import org.eclipse.collections.api.set.ImmutableSet;
+import org.eclipse.collections.impl.block.factory.Predicates;
+import org.eclipse.collections.impl.factory.Lists;
+import org.eclipse.collections.impl.factory.Maps;
+import org.eclipse.collections.impl.factory.Sets;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Helper class for building unit test db environments and contexts, i.e. to not have to remember details for each unit
+ * test db type and to easily switch between unit test DBMS's if needed
+ *
+ * Ultimately, this will delegate to Environment.getAppContextBuilder() for building the context. This class will mainly
+ * leverage a client's existing DbEnvironment setup and tweak values accordingly
+ *
+ * If an existing environment is referenced, a copy of that DbEnvironment will be made by this class so that any changes
+ * to that object will not impact anything existing
+ */
+public class UnitTestDbBuilder {
+ private static final Logger LOG = LoggerFactory.getLogger(UnitTestDbBuilder.class);
+ public static UnitTestDbBuilder newBuilder() {
+ return new UnitTestDbBuilder();
+ }
+
+ /**
+ * Caching the contexts created so that subsequent operations on this can go quickly (i.e. avoiding the costs of
+ * reading the contents from the file system).
+ */
+ private static final MutableMap cachedContexts = Maps.mutable.empty();
+
+ private String sourcePath;
+ private String envName;
+ private String referenceEnvName;
+ private DbPlatform dbPlatform;
+ private String dbServer = "test";
+ private ImmutableSet tables;
+ private ImmutableSet views;
+ private boolean persistToFile = false;
+ private boolean grantsDisabled = true; // disabling grants by default for unit tests as in practice, most teams
+ private File workDir = new File("./target/unitdb");
+ private Credential credential = new Credential("sa", "");
+
+ /**
+ * (Required) path to read environment metadata from
+ */
+ public UnitTestDbBuilder setSourcePath(String sourcePath) {
+ this.sourcePath = sourcePath;
+ return this;
+ }
+
+ /**
+ * Name to give the environment created during this builder
+ *
+ * If not specified, will use the name and environment specified by the referenceEnvName parameter
+ */
+ public UnitTestDbBuilder setEnvName(String envName) {
+ this.envName = envName;
+ return this;
+ }
+
+ /**
+ * Environment to use as a model for the unit test db environment to create
+ *
+ * If not specified, then one of the environments read from the source path will be picked arbitrarily. The envName
+ * parameter must then be specified to give this unit test db environment a known name
+ */
+ public UnitTestDbBuilder setReferenceEnvName(String referenceEnvName) {
+ this.referenceEnvName = referenceEnvName;
+ return this;
+ }
+
+ /**
+ * dbPlatform to use for the new unit test db
+ *
+ * If not specified, will default to the dbPlatform of the reference environment
+ */
+ public UnitTestDbBuilder setDbPlatform(DbPlatform dbPlatform) {
+ this.dbPlatform = dbPlatform;
+ return this;
+ }
+
+ /**
+ * Name of the in-memory db to be created to be used when creating the URL, e.g. jdbc:h2:mem:<dbServer>:etc.
+ * This is a convenience for clients to not have to remember the URL convention. The resolved URL can be retrieved
+ * from the DbEnvironment instance
+ *
+ * If not specified, will default to "test"
+ */
+ public UnitTestDbBuilder setDbServer(String dbServer) {
+ this.dbServer = dbServer;
+ return this;
+ }
+
+ /**
+ * Specify this to restrict the tables deployed to just the ones provided. If not specified, all tables will be deployed.
+ *
+ * @deprecated Specify these fields to remove in the {@link DbDeployerAppContext#deploy(MainDeployerArgs)} arguments itself.
+ */
+ @Deprecated
+ public UnitTestDbBuilder setTables(Set tables) {
+ this.tables = Sets.immutable.withAll(tables);
+ return this;
+ }
+
+ /**
+ * Specify this to restrict the views deployed to just the ones provided. If not specified, all views will be deployed.
+ *
+ * @deprecated Specify these fields to remove in the {@link DbDeployerAppContext#deploy(MainDeployerArgs)} arguments itself.
+ */
+ @Deprecated
+ public UnitTestDbBuilder setViews(Set views) {
+ this.views = Sets.immutable.withAll(views);
+ return this;
+ }
+
+ /**
+ * If true, will generate the file-persistent URL for the in-memory database. If false, goes w/ the in-memory URL
+ *
+ * Defaults to false (in-memory)
+ */
+ public UnitTestDbBuilder setPersistToFile(boolean persistToFile) {
+ this.persistToFile = persistToFile;
+ return this;
+ }
+
+ private boolean isPersistToFile() {
+ // We support this system property here to facilitate easy debugging for
+ // unit tests (i.e. if we don't want to change the code accidentally when running/debugging)
+ // But we can still set this programatically anyway
+ if (System.getProperty("debugDbUnit") == null) {
+ return this.persistToFile;
+ } else {
+ return "true".equalsIgnoreCase(System.getProperty("debugDbUnit"));
+ }
+ }
+
+ /**
+ * @deprecated Clients should move off this. Leverage the groups and users sections in your DbEnvironment configuration to have the grants created
+ */
+ @Deprecated
+ public UnitTestDbBuilder setGrantsDisabled(boolean grantsDisabled) {
+ this.grantsDisabled = grantsDisabled;
+ return this;
+ }
+
+ /**
+ * The workDir to use for any temporary files used for the db deployment
+ *
+ * If not specified, defaults to "./target/unitdb" (i.e. relative to your working directory)
+ */
+ public UnitTestDbBuilder setWorkDir(File workDir) {
+ this.workDir = workDir;
+ return this;
+ }
+
+ /**
+ * (optional) credential defaults to username==sa and password==<blank>, per the default convention of h2/hsql
+ */
+ public UnitTestDbBuilder setCredential(Credential credential) {
+ this.credential = credential;
+ return this;
+ }
+
+ private void validateBuilder() {
+ if (envName == null && referenceEnvName == null) {
+ throw new IllegalArgumentException("One of envName or referenceEnvName must be populated");
+ }
+ Validate.notNull(sourcePath);
+ Validate.notNull(credential);
+ }
+
+ public DbDeployerAppContext buildContext() {
+ validateBuilder();
+
+ String instanceLookupKey = instanceLookupKey();
+
+ DbDeployerAppContext baseContext = cachedContexts.get(instanceLookupKey);
+
+ if (baseContext == null) {
+ baseContext = buildContextUncached();
+ cachedContexts.put(instanceLookupKey, baseContext);
+ }
+
+ // set the arguments that should be used as defined in this builder class, e.g. for limiting by specific tables
+ return new UnitTestDbDeployerAppContext(baseContext, getMainDeployerArgs());
+ }
+
+ /**
+ * Builds the deployer context. See the class Javadoc for more information
+ */
+ private DbDeployerAppContext buildContextUncached() {
+ validateBuilder();
+
+ String[] envsToRequest = this.referenceEnvName != null ? new String[] { this.referenceEnvName } : new String[0];
+ DbEnvironment referenceEnv = DbEnvironmentFactory.getInstance().readFromSourcePath(this.sourcePath, envsToRequest)
+ .getFirst();
+
+ DbEnvironment env = referenceEnv.createCopy();
+
+ if (this.envName != null) {
+ env.setName(this.envName);
+ }
+
+ env.setDisableAuditTracking(true);
+ env.setPersistToFile(this.isPersistToFile());
+
+ if (this.dbPlatform != null) {
+ env.setPlatform(this.dbPlatform);
+ }
+
+ if (this.dbServer != null) {
+ if (env.getJdbcUrl() != null) {
+ LOG.debug("Unsetting existing JDBC URL value, as we can rely on the in-memory DB value to be set here");
+ env.setJdbcUrl(null);
+ }
+ env.setDbServer(this.dbServer);
+ }
+
+ if (this.grantsDisabled) {
+ env.setPermissions(Lists.immutable.empty());
+ }
+
+ env.setDefaultUserId(credential.getUsername());
+ env.setDefaultPassword(credential.getPassword());
+
+ return env.getAppContextBuilder()
+ .setWorkDir(workDir)
+ .build();
+ }
+
+ private MainDeployerArgs getMainDeployerArgs() {
+ MainDeployerArgs args = new MainDeployerArgs();
+
+ if (this.tables != null || this.views != null) {
+ MutableList> predicates = Lists.mutable.empty();
+ if (this.tables != null) {
+ predicates.add(ChangeKeyPredicateBuilder.newBuilder()
+ .setChangeTypes(ChangeType.TABLE_STR, ChangeType.FOREIGN_KEY_STR, ChangeType.TRIGGER_INCREMENTAL_OLD_STR, ChangeType.STATICDATA_STR)
+ .setObjectNames(Sets.immutable.withAll(this.tables))
+ .build());
+ }
+ if (this.views != null) {
+ predicates.add(ChangeKeyPredicateBuilder.newBuilder()
+ .setChangeTypes(ChangeType.VIEW_STR)
+ .setObjectNames(Sets.immutable.withAll(this.views))
+ .build());
+ }
+
+ args.setChangeInclusionPredicate(Predicates.or(predicates));
+ }
+
+ args.setAllChangesets(true); // for unit tests, we always want all changes to deploy
+ return args;
+ }
+
+ private String instanceLookupKey() {
+ String envNameToLookup = envName != null ? envName : referenceEnvName;
+
+ return this.sourcePath + ":" + envNameToLookup;
+ }
+}