(
RevengPattern(ChangeType.TABLE_STR, namePatternType, "(?i)create\\s+(?:\\w+\\s+)?index\\s+$schemaNameSubPattern\\s+on\\s+$schemaNameSubPattern", 2, 1, "INDEX")
.withRemapObjectName(remapObjectName),
RevengPattern(ChangeType.TABLE_STR, namePatternType, "(?i)alter\\s+table\\s+$schemaNameSubPattern\\s+add\\s+constraint\\s+$schemaNameSubPattern\\s+foreign\\s+key", 1, 2, "FK").withShouldBeIgnored(!revengArgs.isGenerateForeignKeys)
+ .withRemapObjectName(remapObjectName),
+ RevengPattern(ChangeType.SEQUENCE_STR, namePatternType, "(?i)create\\s+sequence\\s+$schemaNameSubPattern\\s+")
.withRemapObjectName(remapObjectName)
)
}
diff --git a/pom.xml b/pom.xml
index e1df4149..32fb21ec 100644
--- a/pom.xml
+++ b/pom.xml
@@ -695,7 +695,7 @@
com.puppycrawl.tools
checkstyle
- 6.19
+ 8.18
diff --git a/src/main/build-resources/checkstyle-import-control.xml b/src/main/build-resources/checkstyle-import-control.xml
index 857414b5..b394a34d 100644
--- a/src/main/build-resources/checkstyle-import-control.xml
+++ b/src/main/build-resources/checkstyle-import-control.xml
@@ -1,94 +1,95 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/build-resources/checkstyle.xml b/src/main/build-resources/checkstyle.xml
index e9195b4b..d96b3c24 100644
--- a/src/main/build-resources/checkstyle.xml
+++ b/src/main/build-resources/checkstyle.xml
@@ -1,324 +1,326 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
From 7e6296b5162ca59351fef4ccdf1c7db7cb0116c2 Mon Sep 17 00:00:00 2001
From: shantstepanian <17996546+shantstepanian@users.noreply.github.com>
Date: Wed, 20 Mar 2019 19:55:23 -0400
Subject: [PATCH 3/5] Postgres view drop use case fixes
---
.../java/com/gs/obevo/impl/MainDeployer.kt | 49 ++++-
.../impl/text/TextDependencyExtractable.kt | 2 +-
.../text/TextDependencyExtractableImpl.kt | 2 +-
.../postgresql/PostgreSqlDeployerIT.java | 177 +++++++++---------
.../example1/step1/schema1/view/VIEW1.sql | 34 ++--
.../example1/step1/schema1/view/VIEW4.sql | 17 ++
.../schema1/staticdata/TABLE_SPECIAL_COL.csv | 2 +
.../step2/schema1/table/TABLE_SPECIAL_COL.ddl | 7 +
.../hibernate/HibernateDdlRevengAdapter.kt | 2 +-
9 files changed, 173 insertions(+), 119 deletions(-)
create mode 100644 obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step1/schema1/view/VIEW4.sql
create mode 100644 obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step2/schema1/staticdata/TABLE_SPECIAL_COL.csv
create mode 100644 obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step2/schema1/table/TABLE_SPECIAL_COL.ddl
diff --git a/obevo-core/src/main/java/com/gs/obevo/impl/MainDeployer.kt b/obevo-core/src/main/java/com/gs/obevo/impl/MainDeployer.kt
index 63d68004..68d438dc 100644
--- a/obevo-core/src/main/java/com/gs/obevo/impl/MainDeployer.kt
+++ b/obevo-core/src/main/java/com/gs/obevo/impl/MainDeployer.kt
@@ -15,9 +15,25 @@
*/
package com.gs.obevo.impl
-import com.gs.obevo.api.appdata.*
+import com.gs.obevo.api.appdata.Change
+import com.gs.obevo.api.appdata.ChangeIncremental
+import com.gs.obevo.api.appdata.ChangeKey
+import com.gs.obevo.api.appdata.ChangeRerunnable
+import com.gs.obevo.api.appdata.DeployExecution
+import com.gs.obevo.api.appdata.DeployExecutionImpl
+import com.gs.obevo.api.appdata.DeployExecutionStatus
+import com.gs.obevo.api.appdata.Environment
import com.gs.obevo.api.factory.PlatformConfiguration
-import com.gs.obevo.api.platform.*
+import com.gs.obevo.api.platform.ChangeAuditDao
+import com.gs.obevo.api.platform.ChangeCommand
+import com.gs.obevo.api.platform.CommandExecutionContext
+import com.gs.obevo.api.platform.DeployExecutionDao
+import com.gs.obevo.api.platform.DeployExecutionException
+import com.gs.obevo.api.platform.DeployMetrics
+import com.gs.obevo.api.platform.FailedChange
+import com.gs.obevo.api.platform.GraphExportFormat
+import com.gs.obevo.api.platform.MainDeployerArgs
+import com.gs.obevo.api.platform.Platform
import com.gs.obevo.impl.graph.GraphEnricher
import com.gs.obevo.impl.graph.GraphUtil
import com.gs.obevo.impl.text.TextDependencyExtractableImpl
@@ -35,13 +51,19 @@ import org.eclipse.collections.impl.block.factory.StringFunctions
import org.eclipse.collections.impl.factory.Lists
import org.eclipse.collections.impl.factory.Sets
import org.jgrapht.DirectedGraph
-import org.jgrapht.ext.*
+import org.jgrapht.ext.DOTExporter
+import org.jgrapht.ext.GmlExporter
+import org.jgrapht.ext.GraphMLExporter
+import org.jgrapht.ext.IntegerEdgeNameProvider
+import org.jgrapht.ext.IntegerNameProvider
+import org.jgrapht.ext.MatrixExporter
+import org.jgrapht.ext.VertexNameProvider
import org.jgrapht.graph.DefaultEdge
import org.slf4j.LoggerFactory
import java.io.FileWriter
import java.io.Writer
import java.sql.Timestamp
-import java.util.*
+import java.util.Date
import java.util.concurrent.TimeUnit
/**
@@ -188,23 +210,30 @@ class MainDeployer>(
// TODO refactor into separate method
if (env.platform.isDropOrderRequired) {
+ // In this block, we set the "dependentChanges" field on the drop objects to ensure they can be sorted for dependencies later on
val dropsToEnrich = changePairs
.filter { it.changeKey.changeType.isRerunnable && it.sourceChange == null && it.deployedChange != null }
.map { it.deployedChange!! }
- val drops = dropsToEnrich.map {drop ->
+ val dropsByObjectName = dropsToEnrich.associateBy { env.platform.convertDbObjectName().valueOf(it.objectName) }
+
+ val dropsForTextProcessing = dropsToEnrich.map { drop ->
val sql = changeTypeBehaviorRegistry.getChangeTypeBehavior(drop.changeType).getDefinitionFromEnvironment(drop);
LOG.debug("Found the sql from the DB for dropping: {}", sql)
TextDependencyExtractableImpl(drop.objectName, sql ?: "", drop)
}
- val dropDependencies = this.textDependencyExtractor.calculateDependencies(drops)
-
- drops.forEach { it.codeDependencies = Sets.immutable.ofAll(dropDependencies.get(it)) }
+ val dropDependencies = this.textDependencyExtractor.calculateDependencies(dropsForTextProcessing)
- val dependencyGraph = graphEnricher.createDependencyGraph(sourceChanges, deployerArgs.isRollback)
+ dropsForTextProcessing.forEach { it.codeDependencies = Sets.immutable.ofAll(dropDependencies.get(it)) }
- dropsToEnrich.forEach { it.dependentChanges = GraphUtil.getDependencyNodes(dependencyGraph, it) }
+ for (drop in dropsForTextProcessing) {
+ drop.codeDependencies?.let { deps ->
+ if (deps.notEmpty()) {
+ drop.payload.dependentChanges = Sets.immutable.ofAll(deps.map { dropsByObjectName[it.target] })
+ }
+ }
+ }
}
diff --git a/obevo-core/src/main/java/com/gs/obevo/impl/text/TextDependencyExtractable.kt b/obevo-core/src/main/java/com/gs/obevo/impl/text/TextDependencyExtractable.kt
index b73e8292..3703cc08 100644
--- a/obevo-core/src/main/java/com/gs/obevo/impl/text/TextDependencyExtractable.kt
+++ b/obevo-core/src/main/java/com/gs/obevo/impl/text/TextDependencyExtractable.kt
@@ -37,7 +37,7 @@ interface TextDependencyExtractable {
*
* @since 6.4.0
*/
- val codeDependencies: ImmutableSet
+ val codeDependencies: ImmutableSet?
/**
* The dependencies to exclude from the text. This is to let the user specify the false-positive dependencies that
diff --git a/obevo-core/src/main/java/com/gs/obevo/impl/text/TextDependencyExtractableImpl.kt b/obevo-core/src/main/java/com/gs/obevo/impl/text/TextDependencyExtractableImpl.kt
index 0f0fff68..b8b6ef27 100644
--- a/obevo-core/src/main/java/com/gs/obevo/impl/text/TextDependencyExtractableImpl.kt
+++ b/obevo-core/src/main/java/com/gs/obevo/impl/text/TextDependencyExtractableImpl.kt
@@ -27,7 +27,7 @@ class TextDependencyExtractableImpl (
override val contentForDependencyCalculation: String,
val payload: T
) : TextDependencyExtractable {
- override var codeDependencies: ImmutableSet = Sets.immutable.empty()
+ override var codeDependencies: ImmutableSet? = null
override val excludeDependencies: ImmutableSet
get() = Sets.immutable.empty()
diff --git a/obevo-db-impls/obevo-db-postgresql/src/test/java/com/gs/obevo/db/impl/platforms/postgresql/PostgreSqlDeployerIT.java b/obevo-db-impls/obevo-db-postgresql/src/test/java/com/gs/obevo/db/impl/platforms/postgresql/PostgreSqlDeployerIT.java
index bb85f47f..f9de46fd 100644
--- a/obevo-db-impls/obevo-db-postgresql/src/test/java/com/gs/obevo/db/impl/platforms/postgresql/PostgreSqlDeployerIT.java
+++ b/obevo-db-impls/obevo-db-postgresql/src/test/java/com/gs/obevo/db/impl/platforms/postgresql/PostgreSqlDeployerIT.java
@@ -1,89 +1,88 @@
-/**
- * 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.sql.Timestamp;
-import java.util.List;
-import java.util.Map;
-
-import javax.sql.DataSource;
-
-import com.gs.obevo.db.api.platform.DbDeployerAppContext;
-import com.gs.obevo.db.impl.core.jdbc.JdbcHelper;
-import org.apache.commons.dbutils.DbUtils;
-import org.eclipse.collections.api.block.function.primitive.IntToObjectFunction;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-import static org.junit.Assert.assertEquals;
-
-@RunWith(Parameterized.class)
-public class PostgreSqlDeployerIT {
- @Parameterized.Parameters
- public static Iterable params() {
- return PostgreSqlParamReader.getParamReader().getAppContextAndJdbcDsParams();
- }
-
- private final IntToObjectFunction getAppContext;
- private final DataSource ds;
-
- public PostgreSqlDeployerIT(IntToObjectFunction getAppContext, DataSource ds) {
- this.getAppContext = getAppContext;
- this.ds = ds;
- }
-
- @Test
- public void testDeploy() throws Exception {
- getAppContext.valueOf(1)
- .setupEnvInfra()
- .setupEnvInfra()
- .cleanEnvironment()
- .deploy();
-
- // ensuring that we can modify
- DbDeployerAppContext dbDeployerAppContext = getAppContext.valueOf(2);
- dbDeployerAppContext
- .cleanEnvironment()
- .setupEnvInfra()
- .deploy();
-
- JdbcHelper jdbc = new JdbcHelper();
-
- Connection conn = ds.getConnection();
- try {
- List> results = jdbc.queryForList(conn, "select * from " + dbDeployerAppContext.getEnvironment().getPhysicalSchema("schema1") + ".TABLE_A order by a_id");
- assertEquals(3, results.size());
- this.validateResults(results.get(0), 2, 3, "fasdfasd", "2013-02-02 11:11:11.65432", 9);
- this.validateResults(results.get(1), 3, 4, "ABC", null, 9);
- this.validateResults(results.get(2), 4, 2, "ABC", "2012-01-01 12:12:12", null);
- } finally {
- DbUtils.closeQuietly(conn);
- }
- }
-
- private void validateResults(Map map, Integer aId,
- Integer bId, String stringField, String timestampField, Integer cId) {
-
- assertEquals(aId, map.get("A_ID"));
- assertEquals(bId, map.get("B_ID"));
- assertEquals(stringField, map.get("STRING_FIELD"));
- Timestamp millis = timestampField == null ? null : Timestamp.valueOf(timestampField);
- assertEquals(millis, map.get("TIMESTAMP_FIELD"));
- assertEquals(cId, map.get("C_ID"));
- }
-}
+/**
+ * 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.sql.Timestamp;
+import java.util.List;
+import java.util.Map;
+
+import javax.sql.DataSource;
+
+import com.gs.obevo.db.api.platform.DbDeployerAppContext;
+import com.gs.obevo.db.impl.core.jdbc.JdbcHelper;
+import org.apache.commons.dbutils.DbUtils;
+import org.eclipse.collections.api.block.function.primitive.IntToObjectFunction;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import static org.junit.Assert.assertEquals;
+
+@RunWith(Parameterized.class)
+public class PostgreSqlDeployerIT {
+ @Parameterized.Parameters
+ public static Iterable params() {
+ return PostgreSqlParamReader.getParamReader().getAppContextAndJdbcDsParams();
+ }
+
+ private final IntToObjectFunction getAppContext;
+ private final DataSource ds;
+
+ public PostgreSqlDeployerIT(IntToObjectFunction getAppContext, DataSource ds) {
+ this.getAppContext = getAppContext;
+ this.ds = ds;
+ }
+
+ @Test
+ public void testDeploy() throws Exception {
+ getAppContext.valueOf(1)
+ .setupEnvInfra()
+ .setupEnvInfra()
+ .cleanEnvironment()
+ .deploy();
+
+ // ensuring that we can modify
+ DbDeployerAppContext dbDeployerAppContext = getAppContext.valueOf(2);
+ dbDeployerAppContext
+ .setupEnvInfra()
+ .deploy();
+
+ JdbcHelper jdbc = new JdbcHelper();
+
+ Connection conn = ds.getConnection();
+ try {
+ List> results = jdbc.queryForList(conn, "select * from " + dbDeployerAppContext.getEnvironment().getPhysicalSchema("schema1") + ".TABLE_A order by a_id");
+ assertEquals(3, results.size());
+ this.validateResults(results.get(0), 2, 3, "fasdfasd", "2013-02-02 11:11:11.65432", 9);
+ this.validateResults(results.get(1), 3, 4, "ABC", null, 9);
+ this.validateResults(results.get(2), 4, 2, "ABC", "2012-01-01 12:12:12", null);
+ } finally {
+ DbUtils.closeQuietly(conn);
+ }
+ }
+
+ private void validateResults(Map map, Integer aId,
+ Integer bId, String stringField, String timestampField, Integer cId) {
+
+ assertEquals(aId, map.get("A_ID"));
+ assertEquals(bId, map.get("B_ID"));
+ assertEquals(stringField, map.get("STRING_FIELD"));
+ Timestamp millis = timestampField == null ? null : Timestamp.valueOf(timestampField);
+ assertEquals(millis, map.get("TIMESTAMP_FIELD"));
+ assertEquals(cId, map.get("C_ID"));
+ }
+}
diff --git a/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step1/schema1/view/VIEW1.sql b/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step1/schema1/view/VIEW1.sql
index 6ee34aa5..50edcbcb 100644
--- a/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step1/schema1/view/VIEW1.sql
+++ b/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step1/schema1/view/VIEW1.sql
@@ -1,17 +1,17 @@
---
--- 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.
---
-
-CREATE OR REPLACE VIEW VIEW1 AS SELECT * FROM VIEW3
+--
+-- 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.
+--
+
+CREATE OR REPLACE VIEW VIEW1 AS SELECT * FROM VIEW2
diff --git a/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step1/schema1/view/VIEW4.sql b/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step1/schema1/view/VIEW4.sql
new file mode 100644
index 00000000..f843f561
--- /dev/null
+++ b/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step1/schema1/view/VIEW4.sql
@@ -0,0 +1,17 @@
+--
+-- 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.
+--
+
+CREATE OR REPLACE VIEW VIEW4 AS SELECT * FROM VIEW3
diff --git a/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step2/schema1/staticdata/TABLE_SPECIAL_COL.csv b/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step2/schema1/staticdata/TABLE_SPECIAL_COL.csv
new file mode 100644
index 00000000..007e6fac
--- /dev/null
+++ b/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step2/schema1/staticdata/TABLE_SPECIAL_COL.csv
@@ -0,0 +1,2 @@
+"UUID_PK","STR1"
+"186FFBB4-9A4D-4572-B89F-0D992BB9EB81","test1"
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
new file mode 100644
index 00000000..3114fe83
--- /dev/null
+++ b/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step2/schema1/table/TABLE_SPECIAL_COL.ddl
@@ -0,0 +1,7 @@
+//// CHANGE name=chng1
+CREATE TABLE TABLE_SPECIAL_COL (
+ UUID_PK UUID NOT NULL,
+ STR1 VARCHAR(30) NULL,
+ PRIMARY KEY (UUID_PK)
+)
+GO
diff --git a/obevo-utils/obevo-hibernate-util/src/main/java/com/gs/obevo/hibernate/HibernateDdlRevengAdapter.kt b/obevo-utils/obevo-hibernate-util/src/main/java/com/gs/obevo/hibernate/HibernateDdlRevengAdapter.kt
index 82cb2a8e..d2316c6f 100644
--- a/obevo-utils/obevo-hibernate-util/src/main/java/com/gs/obevo/hibernate/HibernateDdlRevengAdapter.kt
+++ b/obevo-utils/obevo-hibernate-util/src/main/java/com/gs/obevo/hibernate/HibernateDdlRevengAdapter.kt
@@ -70,7 +70,7 @@ internal class HibernateDdlRevengAdapter(
.withRemapObjectName(remapObjectName),
RevengPattern(ChangeType.TABLE_STR, namePatternType, "(?i)create\\s+(?:\\w+\\s+)?index\\s+$schemaNameSubPattern\\s+on\\s+$schemaNameSubPattern", 2, 1, "INDEX")
.withRemapObjectName(remapObjectName),
- RevengPattern(ChangeType.TABLE_STR, namePatternType, "(?i)alter\\s+table\\s+$schemaNameSubPattern\\s+add\\s+constraint\\s+$schemaNameSubPattern\\s+foreign\\s+key", 1, 2, "FK").withShouldBeIgnored(!revengArgs.isGenerateForeignKeys)
+ RevengPattern(ChangeType.TABLE_STR, namePatternType, "(?i)alter\\s+table\\s+(?:if\\s+exists\\s+)?$schemaNameSubPattern\\s+add\\s+constraint\\s+$schemaNameSubPattern\\s+foreign\\s+key", 1, 2, "FK").withShouldBeIgnored(!revengArgs.isGenerateForeignKeys)
.withRemapObjectName(remapObjectName),
RevengPattern(ChangeType.SEQUENCE_STR, namePatternType, "(?i)create\\s+sequence\\s+$schemaNameSubPattern\\s+")
.withRemapObjectName(remapObjectName)
From bac766aa847c52c48bdf73eab05dcd126f7d5de6 Mon Sep 17 00:00:00 2001
From: shantstepanian <17996546+shantstepanian@users.noreply.github.com>
Date: Sat, 23 Mar 2019 10:15:07 -0400
Subject: [PATCH 4/5] Additional postgres reverse engineering fixes
---
.../api/factory/PlatformConfigReader.java | 8 +-
.../postgresql/PostgreSqlDbPlatform.java | 236 +++++++--------
.../postgresql/PostgreSqlPgDumpReveng.java | 43 ++-
.../postgresql/PostgreSqlRevengTest.java | 2 +
.../PostgresqlDbMetadataManagerIT.java | 201 +++++++------
.../step1/schema1/usertype/usertype0.sql | 9 +
.../step2/schema1/usertype/usertype0.sql | 9 +
.../test/resources/postgresql-test-drops.sql | 144 ++++-----
.../src/test/resources/postgresql-test.sql | 211 ++++++-------
.../pgdump/expected/myschema01/sp/sp1.sql | 7 +
.../myschema01/usertype/usertype1.sql | 9 +
.../pgdump/input/input-noschemaqualifier.sql | 265 +++++++++++++++++
.../resources/reveng/pgdump/input/input.sql | 65 ++--
.../gs/obevo/db/api/platform/DbPlatform.java | 6 +
.../db/apps/reveng/AbstractDdlReveng.java | 11 +-
.../dialects/PostgresqlMetadataDialect.java | 278 ++++++++++--------
16 files changed, 945 insertions(+), 559 deletions(-)
create mode 100644 obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step1/schema1/usertype/usertype0.sql
create mode 100644 obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step2/schema1/usertype/usertype0.sql
create mode 100644 obevo-db-impls/obevo-db-postgresql/src/test/resources/reveng/pgdump/expected/myschema01/sp/sp1.sql
create mode 100644 obevo-db-impls/obevo-db-postgresql/src/test/resources/reveng/pgdump/expected/myschema01/usertype/usertype1.sql
create mode 100644 obevo-db-impls/obevo-db-postgresql/src/test/resources/reveng/pgdump/input/input-noschemaqualifier.sql
diff --git a/obevo-core/src/main/java/com/gs/obevo/api/factory/PlatformConfigReader.java b/obevo-core/src/main/java/com/gs/obevo/api/factory/PlatformConfigReader.java
index 4f3c4282..f667f7a3 100644
--- a/obevo-core/src/main/java/com/gs/obevo/api/factory/PlatformConfigReader.java
+++ b/obevo-core/src/main/java/com/gs/obevo/api/factory/PlatformConfigReader.java
@@ -135,7 +135,7 @@ public String valueOf(PropertyInput propertyInput) {
return propertyInput.getFileName();
}
});
- final MutableList warnings = Lists.mutable.empty();
+ final MutableList debugMessages = Lists.mutable.empty();
final MutableList errors = Lists.mutable.empty();
propertiesByFileName.forEachKeyMultiValues(new Procedure2>() {
@@ -157,7 +157,7 @@ public URL valueOf(PropertyInput propertyInput) {
}
}) + "]. Please ensure that priorities are distinct.");
} else if (priorities.size() > 1) {
- warnings.add("File name [" + fileName + "] was found in multiple locations [" + propertyInputs.collect(new Function() {
+ debugMessages.add("File name [" + fileName + "] was found in multiple locations [" + propertyInputs.collect(new Function() {
@Override
public URL valueOf(PropertyInput propertyInput) {
return propertyInput.getPropertyFilePath();
@@ -167,8 +167,8 @@ public URL valueOf(PropertyInput propertyInput) {
}
});
- if (warnings.notEmpty()) {
- LOG.warn("Warnings on platform configuration file setup; please address in the future, but program will proceed:\n{}", warnings.makeString("\n"));
+ if (debugMessages.notEmpty()) {
+ LOG.debug("Debug notices on platform configuration file setup:\n{}", debugMessages.makeString("\n"));
}
if (errors.notEmpty()) {
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 f2782aa4..43f290c4 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
@@ -1,117 +1,119 @@
-/**
- * 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.api.platform.ChangeType;
-import com.gs.obevo.api.platform.DeployerAppContext;
-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.apps.reveng.AbstractDdlReveng;
-import com.gs.obevo.db.impl.platforms.AbstractDbPlatform;
-import org.eclipse.collections.api.block.function.Function;
-import org.eclipse.collections.api.list.ImmutableList;
-import org.eclipse.collections.api.list.MutableList;
-import org.eclipse.collections.api.set.ImmutableSet;
-import org.eclipse.collections.impl.block.factory.Predicates;
-import org.eclipse.collections.impl.block.factory.StringFunctions;
-
-/**
- * PostgreSQL DBMS platform implementation.
- */
-public class PostgreSqlDbPlatform extends AbstractDbPlatform {
- public PostgreSqlDbPlatform() {
- super("POSTGRESQL");
- }
-
- /**
- * Protected constructor to allow for the Amazon-based platforms that leverage PostgreSQL as their SQL interface.
- */
- protected PostgreSqlDbPlatform(String name) {
- super(name);
- }
-
- @Override
- public Class extends DeployerAppContext> initializeAppContextBuilderClass() {
- return PostgreSqlAppContext.class;
- }
-
- @Override
- protected String initializeDefaultDriverClassName() {
- return "org.postgresql.Driver";
- }
-
- @Override
- protected ImmutableList initializeChangeTypes() {
- MutableList changeTypes = super.initializeChangeTypes().toList();
-
- DbChangeType sequenceType = getChangeType(changeTypes, ChangeType.SEQUENCE_STR);
- sequenceType = DbChangeTypeImpl.newDbChangeType(sequenceType).setGrantObjectQualifier("SEQUENCE").build();
- replaceChangeType(changeTypes, sequenceType);
-
- DbChangeType functionType = getChangeType(changeTypes, ChangeType.FUNCTION_STR);
- functionType = DbChangeTypeImpl.newDbChangeType(functionType).setGrantObjectQualifier("FUNCTION").build();
- replaceChangeType(changeTypes, functionType);
-
- return changeTypes.toImmutable();
- }
-
- @Override
- public boolean isDropOrderRequired() {
- return true;
- }
-
- @Override
- protected String getGrantTargetTypeStrDbSpecific(GrantTargetType grantTargetType) {
- // only user must have the blank defined; GROUP can still be specified
- switch (grantTargetType) {
- case USER:
- return "";
- default:
- return grantTargetType.name();
- }
- }
-
- @Override
- public Function convertDbObjectName() {
- return StringFunctions.toLowerCase();
- }
-
- @Override
- public String getNullMarkerForCreateTable() {
- return ""; // for DB2 create statement, a blank implies NULL. Adding NULL explicitly was not allowed prior to
- // v9.7, so we leave this here
- }
-
- @Override
- public String getTimestampType() {
- return "TIMESTAMP";
- }
-
- @Override
- public ImmutableSet getRequiredValidationObjectTypes() {
- // there is currently a quirk w/ PostgreSQL where view SQL definitions will not have the objects qualified w/
- // the schema name in the connection that creates the SQL; but in subsequent connections, it will be qualified.
- // Until we work out this issue, we will exclude views from PostgreSQL processing.
- return super.getRequiredValidationObjectTypes()
- .reject(Predicates.equal(ChangeType.VIEW_STR));
- }
-
- @Override
- public AbstractDdlReveng getDdlReveng() {
- return new PostgreSqlPgDumpReveng();
- }
-}
+/**
+ * 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.api.platform.ChangeType;
+import com.gs.obevo.api.platform.DeployerAppContext;
+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.apps.reveng.AbstractDdlReveng;
+import com.gs.obevo.db.impl.platforms.AbstractDbPlatform;
+import org.eclipse.collections.api.block.function.Function;
+import org.eclipse.collections.api.list.ImmutableList;
+import org.eclipse.collections.api.list.MutableList;
+import org.eclipse.collections.api.set.ImmutableSet;
+import org.eclipse.collections.impl.block.factory.Predicates;
+import org.eclipse.collections.impl.block.factory.StringFunctions;
+
+/**
+ * PostgreSQL DBMS platform implementation.
+ */
+public class PostgreSqlDbPlatform extends AbstractDbPlatform {
+ public PostgreSqlDbPlatform() {
+ super("POSTGRESQL");
+ }
+
+ /**
+ * Protected constructor to allow for the Amazon-based platforms that leverage PostgreSQL as their SQL interface.
+ */
+ protected PostgreSqlDbPlatform(String name) {
+ super(name);
+ }
+
+ @Override
+ public Class extends DeployerAppContext> initializeAppContextBuilderClass() {
+ return PostgreSqlAppContext.class;
+ }
+
+ @Override
+ protected String initializeDefaultDriverClassName() {
+ return "org.postgresql.Driver";
+ }
+
+ @Override
+ protected ImmutableList initializeChangeTypes() {
+ MutableList changeTypes = super.initializeChangeTypes().toList();
+
+ DbChangeType sequenceType = getChangeType(changeTypes, ChangeType.SEQUENCE_STR);
+ sequenceType = DbChangeTypeImpl.newDbChangeType(sequenceType).setGrantObjectQualifier("SEQUENCE").build();
+ replaceChangeType(changeTypes, sequenceType);
+
+ DbChangeType functionType = getChangeType(changeTypes, ChangeType.FUNCTION_STR);
+ functionType = DbChangeTypeImpl.newDbChangeType(functionType).setGrantObjectQualifier("FUNCTION").build();
+ replaceChangeType(changeTypes, functionType);
+
+ DbChangeType typeType = DbChangeTypeImpl.newDbChangeType(ChangeType.USERTYPE_STR, true, 1, "TYPE").build();
+ changeTypes.add(typeType);
+
+ return changeTypes.toImmutable();
+ }
+
+ @Override
+ public boolean isDropOrderRequired() {
+ return true;
+ }
+
+ @Override
+ protected String getGrantTargetTypeStrDbSpecific(GrantTargetType grantTargetType) {
+ // only user must have the blank defined; GROUP can still be specified
+ switch (grantTargetType) {
+ case USER:
+ return "";
+ default:
+ return grantTargetType.name();
+ }
+ }
+
+ @Override
+ public Function convertDbObjectName() {
+ return StringFunctions.toLowerCase();
+ }
+
+ @Override
+ public String getNullMarkerForCreateTable() {
+ return "";
+ }
+
+ @Override
+ public String getTimestampType() {
+ return "TIMESTAMP";
+ }
+
+ @Override
+ public ImmutableSet getRequiredValidationObjectTypes() {
+ // there is currently a quirk w/ PostgreSQL where view SQL definitions will not have the objects qualified w/
+ // the schema name in the connection that creates the SQL; but in subsequent connections, it will be qualified.
+ // Until we work out this issue, we will exclude views from PostgreSQL processing.
+ return super.getRequiredValidationObjectTypes()
+ .reject(Predicates.equal(ChangeType.VIEW_STR));
+ }
+
+ @Override
+ public AbstractDdlReveng getDdlReveng() {
+ return new PostgreSqlPgDumpReveng();
+ }
+}
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 bbf7bd2b..59a27338 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
@@ -56,9 +56,10 @@ public class PostgreSqlPgDumpReveng extends AbstractDdlReveng {
}
private static ImmutableList getRevengPatterns() {
- String schemaNameSubPattern = getObjectPattern("", "");
+ String schemaNameSubPattern = getSchemaObjectPattern("", "");
+ String objectNameSubPattern = getObjectPattern("", "");
- NamePatternType namePatternType = NamePatternType.ONE;
+ NamePatternType namePatternType = NamePatternType.TWO;
return Lists.immutable.with(
new RevengPattern(ChangeType.SEQUENCE_STR, namePatternType, "(?i)create\\s+(?:or\\s+replace\\s+)?sequence\\s+" + schemaNameSubPattern).withPostProcessSql(REPLACE_TABLESPACE).withPostProcessSql(REMOVE_QUOTES),
new RevengPattern(ChangeType.TABLE_STR, namePatternType, "(?i)create\\s+table\\s+" + schemaNameSubPattern).withPostProcessSql(REPLACE_TABLESPACE).withPostProcessSql(REMOVE_QUOTES),
@@ -66,33 +67,51 @@ private static ImmutableList getRevengPatterns() {
new RevengPattern(ChangeType.TABLE_STR, namePatternType, "(?i)alter\\s+sequence\\s+" + schemaNameSubPattern + "\\s+owned\\s+by\\s+" + schemaNameSubPattern, 2, 1, null).withPostProcessSql(REMOVE_QUOTES),
new RevengPattern(ChangeType.TABLE_STR, namePatternType, "(?i)create\\s+(?:unique\\s+)index\\s+" + schemaNameSubPattern + "\\s+on\\s+" + schemaNameSubPattern, 2, 1, "INDEX").withPostProcessSql(REPLACE_TABLESPACE).withPostProcessSql(REMOVE_QUOTES),
new RevengPattern(ChangeType.FUNCTION_STR, namePatternType, "(?i)create\\s+(?:or\\s+replace\\s+)?(?:force\\s+)?(?:editionable\\s+)?function\\s+" + schemaNameSubPattern),
+ new RevengPattern(ChangeType.SP_STR, namePatternType, "(?i)create\\s+(?:or\\s+replace\\s+)?(?:force\\s+)?(?:editionable\\s+)?procedure\\s+" + schemaNameSubPattern),
new RevengPattern(ChangeType.VIEW_STR, namePatternType, "(?i)create\\s+(?:or\\s+replace\\s+)?(?:force\\s+)?(?:editionable\\s+)?view\\s+" + schemaNameSubPattern),
new RevengPattern(ChangeType.SP_STR, namePatternType, "(?i)create\\s+(?:or\\s+replace\\s+)(?:editionable\\s+)procedure\\s+" + schemaNameSubPattern),
new RevengPattern(ChangeType.PACKAGE_STR, namePatternType, "(?i)create\\s+(?:or\\s+replace\\s+)(?:editionable\\s+)package\\s+" + schemaNameSubPattern),
- new RevengPattern(ChangeType.TRIGGER_STR, namePatternType, "(?i)create\\s+or\\s+replace\\s+trigger\\s+" + schemaNameSubPattern)
+ new RevengPattern(ChangeType.TRIGGER_STR, namePatternType, "(?i)create\\s+or\\s+replace\\s+trigger\\s+" + schemaNameSubPattern),
+ new RevengPattern(ChangeType.USERTYPE_STR, namePatternType, "(?i)create\\s+(?:or\\s+replace\\s+)?type\\s+" + schemaNameSubPattern)
);
}
@Override
protected boolean doRevengOrInstructions(PrintStream out, AquaRevengArgs args, File interimDir) {
- out.println("1) Run the following command to generate the DDL file:");
- out.println(getCommandWithDefaults(args, "", "", "", "", "", "", ""));
- out.println("");
+ out.println("1) Create the folder for your interim output:");
+ out.println();
+ out.println("mkdir -p " + interimDir.getAbsolutePath());
+ out.println();
+ out.println();
+ out.println("2) Run the following command to generate the DDL file:");
+ out.println();
+ out.println("(without Docker)");
+ out.println(getCommandWithDefaults(false, args, interimDir, "", "", "", "", "", "", ""));
+ out.println();
+ out.println("(with Docker)");
+ out.println(getCommandWithDefaults(true, args, interimDir, "", "", "", "", "", "", ""));
+ out.println();
out.println("Here is an example command (in case your values are not filled in):");
- out.println(getCommandWithDefaults(args, "myuser", "mypassword", "myhost.myplace.com", "12345", "mydb", "myschema", "H:\\sybase-ddl-output.txt"));
- out.println("");
- out.println("The pg_dump command will ");
+ out.println();
+ out.println("(without Docker)");
+ out.println(getCommandWithDefaults(false, args, interimDir, "myuser", "mypassword", "myhost.myplace.com", "12345", "mydb", "myschema", "H:\\sybase-ddl-output.txt"));
+ out.println();
+ out.println("(with Docker)");
+ out.println(getCommandWithDefaults(true, args, interimDir, "myuser", "mypassword", "myhost.myplace.com", "12345", "mydb", "myschema", "H:\\sybase-ddl-output.txt"));
+ out.println();
return false;
}
- private String getCommandWithDefaults(AquaRevengArgs args, String username, String password, String dbHost, String dbPort, String dbName, String dbSchema, String outputDirectory) {
- return "pg_dump -O --disable-dollar-quoting -s" +
+ 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();
+ return prefix + "pg_dump -O -s --no-privileges" +
" -h " + ObjectUtils.defaultIfNull(args.getDbHost(), dbHost) +
" -p " + ObjectUtils.defaultIfNull(args.getDbPort(), dbPort) +
" --username=" + ObjectUtils.defaultIfNull(args.getUsername(), username) +
" -d " + ObjectUtils.defaultIfNull(args.getDbServer(), dbName) +
" -n " + ObjectUtils.defaultIfNull(args.getDbSchema(), dbSchema) +
- " -f " + ObjectUtils.defaultIfNull(args.getOutputPath(), outputDirectory);
+ " " + fileSuffix;
}
}
diff --git a/obevo-db-impls/obevo-db-postgresql/src/test/java/com/gs/obevo/db/impl/platforms/postgresql/PostgreSqlRevengTest.java b/obevo-db-impls/obevo-db-postgresql/src/test/java/com/gs/obevo/db/impl/platforms/postgresql/PostgreSqlRevengTest.java
index d4f8ae18..41cae661 100644
--- a/obevo-db-impls/obevo-db-postgresql/src/test/java/com/gs/obevo/db/impl/platforms/postgresql/PostgreSqlRevengTest.java
+++ b/obevo-db-impls/obevo-db-postgresql/src/test/java/com/gs/obevo/db/impl/platforms/postgresql/PostgreSqlRevengTest.java
@@ -45,5 +45,7 @@ public void testReverseEngineeringFromFile() throws Exception {
new PostgreSqlDbPlatform().getDdlReveng().reveng(args);
DirectoryAssert.assertDirectoriesEqual(new File("./src/test/resources/reveng/pgdump/expected"), new File(outputDir, "final"));
+
+ // TODO add test for input-noschemaqualifier.sql for older postgres versions
}
}
diff --git a/obevo-db-impls/obevo-db-postgresql/src/test/java/com/gs/obevo/dbmetadata/impl/dialects/PostgresqlDbMetadataManagerIT.java b/obevo-db-impls/obevo-db-postgresql/src/test/java/com/gs/obevo/dbmetadata/impl/dialects/PostgresqlDbMetadataManagerIT.java
index 55b5a956..1e4aed70 100644
--- a/obevo-db-impls/obevo-db-postgresql/src/test/java/com/gs/obevo/dbmetadata/impl/dialects/PostgresqlDbMetadataManagerIT.java
+++ b/obevo-db-impls/obevo-db-postgresql/src/test/java/com/gs/obevo/dbmetadata/impl/dialects/PostgresqlDbMetadataManagerIT.java
@@ -1,98 +1,103 @@
-/**
- * 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.dbmetadata.impl.dialects;
-
-import javax.sql.DataSource;
-
-import com.gs.obevo.api.appdata.PhysicalSchema;
-import com.gs.obevo.db.impl.platforms.postgresql.PostgreSqlDbPlatform;
-import com.gs.obevo.db.impl.platforms.postgresql.PostgreSqlParamReader;
-import com.gs.obevo.dbmetadata.api.DbMetadataManager;
-import org.apache.commons.dbutils.QueryRunner;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-@RunWith(Parameterized.class)
-public class PostgresqlDbMetadataManagerIT extends AbstractDbMetadataManagerIT {
- @Parameterized.Parameters
- public static Iterable params() {
- return PostgreSqlParamReader.getParamReader().getJdbcDsAndSchemaParams();
- }
-
- public PostgresqlDbMetadataManagerIT(DataSource dataSource, PhysicalSchema physicalSchema) {
- super(dataSource, physicalSchema);
- }
-
- @Override
- protected DbMetadataManager createMetadataManager() {
- return new PostgreSqlDbPlatform().getDbMetadataManager();
- }
-
- @Override
- protected String convertName(String name) {
- return name.toLowerCase();
- }
-
- @Override
- protected String get_FUNC1() {
- return "BEGIN -- ensure that func comment remains RETURN 1; END;";
- }
-
- @Override
- protected boolean isInvalidViewPossible() {
- return false; // postgresql does not allow invalid views (i.e. views that have dependent tables dropped first)
- }
-
- @Override
- protected boolean isStoredProcedureSupported() {
- return false; // postgresql only supports functions, not procedures separately
- }
-
- @Override
- protected String get_VIEW1() {
- return "SELECT metadata_test_table.afield, metadata_test_table.bfield FROM metadata_test_table;";
- }
-
- @Override
- protected void setCurrentSchema(QueryRunner jdbc) throws Exception {
- jdbc.update("SET search_path TO " + getSchemaName());
- }
-
- @Override
- protected String getDropSqlFile() {
- return "postgresql-test-drops.sql";
- }
-
- @Override
- protected String getAddSqlFile() {
- return "postgresql-test.sql";
- }
-
- @Override
- protected String get_FUNC_WITH_OVERLOAD_1() {
- return "BEGIN RETURN 1; END;";
- }
-
- @Override
- protected String get_FUNC_WITH_OVERLOAD_2() {
- return "BEGIN RETURN 1; END;";
- }
-
- @Override
- protected String get_FUNC_WITH_OVERLOAD_3() {
- return "BEGIN RETURN 1; END;";
- }
-}
+/**
+ * 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.dbmetadata.impl.dialects;
+
+import javax.sql.DataSource;
+
+import com.gs.obevo.api.appdata.PhysicalSchema;
+import com.gs.obevo.db.impl.platforms.postgresql.PostgreSqlDbPlatform;
+import com.gs.obevo.db.impl.platforms.postgresql.PostgreSqlParamReader;
+import com.gs.obevo.dbmetadata.api.DbMetadataManager;
+import org.apache.commons.dbutils.QueryRunner;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class PostgresqlDbMetadataManagerIT extends AbstractDbMetadataManagerIT {
+ @Parameterized.Parameters
+ public static Iterable params() {
+ return PostgreSqlParamReader.getParamReader().getJdbcDsAndSchemaParams();
+ }
+
+ public PostgresqlDbMetadataManagerIT(DataSource dataSource, PhysicalSchema physicalSchema) {
+ super(dataSource, physicalSchema);
+ }
+
+ @Override
+ protected DbMetadataManager createMetadataManager() {
+ return new PostgreSqlDbPlatform().getDbMetadataManager();
+ }
+
+ @Override
+ protected String convertName(String name) {
+ return name.toLowerCase();
+ }
+
+ @Override
+ protected String get_FUNC1() {
+ return "BEGIN -- ensure that func comment remains RETURN 1; END;";
+ }
+
+ @Override
+ protected boolean isInvalidViewPossible() {
+ return false; // postgresql does not allow invalid views (i.e. views that have dependent tables dropped first)
+ }
+
+ @Override
+ boolean isUserTypeSupported() {
+ return true;
+ }
+
+ @Override
+ protected boolean isStoredProcedureSupported() {
+ return false; // postgresql only supports functions, not procedures separately. Metadata for procedures is stored as functions for now
+ }
+
+ @Override
+ protected String get_VIEW1() {
+ return "SELECT metadata_test_table.afield, metadata_test_table.bfield FROM metadata_test_table;";
+ }
+
+ @Override
+ protected void setCurrentSchema(QueryRunner jdbc) throws Exception {
+ jdbc.update("SET search_path TO " + getSchemaName());
+ }
+
+ @Override
+ protected String getDropSqlFile() {
+ return "postgresql-test-drops.sql";
+ }
+
+ @Override
+ protected String getAddSqlFile() {
+ return "postgresql-test.sql";
+ }
+
+ @Override
+ protected String get_FUNC_WITH_OVERLOAD_1() {
+ return "BEGIN RETURN 1; END;";
+ }
+
+ @Override
+ protected String get_FUNC_WITH_OVERLOAD_2() {
+ return "BEGIN RETURN 1; END;";
+ }
+
+ @Override
+ protected String get_FUNC_WITH_OVERLOAD_3() {
+ return "BEGIN RETURN 1; END;";
+ }
+}
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
new file mode 100644
index 00000000..bfe03d74
--- /dev/null
+++ b/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step1/schema1/usertype/usertype0.sql
@@ -0,0 +1,9 @@
+CREATE TYPE usertype0 AS ENUM (
+ '1',
+ '2',
+ '3'
+);
+
+
+
+GO
\ No newline at end of file
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
new file mode 100644
index 00000000..bfe03d74
--- /dev/null
+++ b/obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step2/schema1/usertype/usertype0.sql
@@ -0,0 +1,9 @@
+CREATE TYPE usertype0 AS ENUM (
+ '1',
+ '2',
+ '3'
+);
+
+
+
+GO
\ No newline at end of file
diff --git a/obevo-db-impls/obevo-db-postgresql/src/test/resources/postgresql-test-drops.sql b/obevo-db-impls/obevo-db-postgresql/src/test/resources/postgresql-test-drops.sql
index 31138ab0..971386c3 100644
--- a/obevo-db-impls/obevo-db-postgresql/src/test/resources/postgresql-test-drops.sql
+++ b/obevo-db-impls/obevo-db-postgresql/src/test/resources/postgresql-test-drops.sql
@@ -1,70 +1,74 @@
---
--- 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.
---
-
-DROP VIEW VIEW1
-GO
-
-
-DROP TABLE METADATA_TEST_TABLE
-GO
-
-DROP TABLE TABLE_B_WITH_FK
-GO
-
-DROP TABLE TABLE_A
-GO
-
-DROP TABLE TABLE_A_ROOT
-GO
-
-DROP TABLE TABLE_B_WITH_MULTICOL_FK
-GO
-
-DROP TABLE TABLE_A_MULTICOL_PK
-GO
-
-DROP TABLE TABLE_GENERATED_ID
-GO
-
-
-
-DROP TABLE INVALID_TABLE
-GO
-
-DROP VIEW INVALID_VIEW
-GO
-
-
-DROP SEQUENCE REGULAR_SEQUENCE
-GO
-
-
-DROP PROCEDURE SP_WITH_OVERLOAD (INT, VARCHAR(32))
-GO
-DROP PROCEDURE SP_WITH_OVERLOAD (INT)
-GO
-DROP PROCEDURE SP_WITH_OVERLOAD ()
-GO
-DROP FUNCTION FUNC_WITH_OVERLOAD (INT, VARCHAR(32))
-GO
-DROP FUNCTION FUNC_WITH_OVERLOAD (INT)
-GO
-DROP FUNCTION FUNC_WITH_OVERLOAD ()
-GO
-DROP PROCEDURE SP1 ()
-GO
-DROP FUNCTION FUNC1 ()
-GO
+--
+-- 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.
+--
+
+DROP VIEW VIEW1
+GO
+
+
+DROP TABLE METADATA_TEST_TABLE
+GO
+
+DROP TABLE TABLE_B_WITH_FK
+GO
+
+DROP TABLE TABLE_A
+GO
+
+DROP TABLE TABLE_A_ROOT
+GO
+
+DROP TABLE TABLE_B_WITH_MULTICOL_FK
+GO
+
+DROP TABLE TABLE_A_MULTICOL_PK
+GO
+
+DROP TABLE TABLE_GENERATED_ID
+GO
+
+
+
+DROP TABLE INVALID_TABLE
+GO
+
+DROP VIEW INVALID_VIEW
+GO
+
+
+DROP SEQUENCE REGULAR_SEQUENCE
+GO
+
+
+DROP PROCEDURE SP_WITH_OVERLOAD (INT, VARCHAR(32))
+GO
+DROP PROCEDURE SP_WITH_OVERLOAD (INT)
+GO
+DROP PROCEDURE SP_WITH_OVERLOAD ()
+GO
+DROP FUNCTION FUNC_WITH_OVERLOAD (INT, VARCHAR(32))
+GO
+DROP FUNCTION FUNC_WITH_OVERLOAD (INT)
+GO
+DROP FUNCTION FUNC_WITH_OVERLOAD ()
+GO
+DROP PROCEDURE SP1 ()
+GO
+DROP FUNCTION FUNC1 ()
+GO
+DROP TYPE MyType
+GO
+DROP TYPE MyType2
+GO
diff --git a/obevo-db-impls/obevo-db-postgresql/src/test/resources/postgresql-test.sql b/obevo-db-impls/obevo-db-postgresql/src/test/resources/postgresql-test.sql
index b0e7bd45..552eadbf 100644
--- a/obevo-db-impls/obevo-db-postgresql/src/test/resources/postgresql-test.sql
+++ b/obevo-db-impls/obevo-db-postgresql/src/test/resources/postgresql-test.sql
@@ -1,103 +1,108 @@
---
--- 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.
---
-
-create table METADATA_TEST_TABLE (afield int, bfield int)
-GO
-
-create table TABLE_A (
- A_ID INT NOT NULL,
- A2_ID INT,
- PRIMARY KEY (A_ID)
-)
-GO
-
-
-create table TABLE_A_MULTICOL_PK (
- A1_ID INT NOT NULL,
- A2_ID INT NOT NULL,
- VAL3 INT,
- PRIMARY KEY (A1_ID, A2_ID)
-)
-GO
-create table TABLE_B_WITH_MULTICOL_FK (
- B_ID INT NOT NULL,
- OTHER_A1_ID INT,
- OTHER_A2_ID INT,
- PRIMARY KEY (B_ID)
-)
-GO
-ALTER TABLE TABLE_B_WITH_MULTICOL_FK ADD CONSTRAINT FK_A_MULTICOL FOREIGN KEY (OTHER_A1_ID, OTHER_A2_ID) REFERENCES TABLE_A_MULTICOL_PK(A1_ID, A2_ID)
-GO
-
-create table TABLE_B_WITH_FK (
- B_ID INT NOT NULL,
- OTHER_A_ID INT,
- PRIMARY KEY (B_ID)
-)
-GO
-ALTER TABLE TABLE_B_WITH_FK ADD CONSTRAINT FK_A FOREIGN KEY (OTHER_A_ID) REFERENCES TABLE_A(A_ID)
-GO
-
-create table TABLE_GENERATED_ID (
- GEN_ID SERIAL,
- FIELD1 INT
-)
-GO
-
-
-
-CREATE VIEW VIEW1 AS SELECT * FROM METADATA_TEST_TABLE
--- my comment
-GO
-
-
--- Postgresql does not allow dropping objects that have dependencies, so the invalid view test is not applicable
-
-
-CREATE SEQUENCE REGULAR_SEQUENCE
-GO
-
-
-CREATE OR REPLACE FUNCTION FUNC1 () RETURNS INT AS $$
-BEGIN
- -- ensure that func comment remains
- RETURN 1;
-END;
-$$ LANGUAGE plpgsql;
-GO
-
-CREATE FUNCTION FUNC_WITH_OVERLOAD () RETURNS INT AS $$
-BEGIN
- RETURN 1;
-END;
-$$ LANGUAGE plpgsql;
-GO
-
-CREATE FUNCTION FUNC_WITH_OVERLOAD (var1 integer) RETURNS INT AS $$
-BEGIN
- RETURN 1;
-END;
-$$ LANGUAGE plpgsql;
-GO
-
-CREATE FUNCTION FUNC_WITH_OVERLOAD (var1 integer, IN INVALSTR VARCHAR(32)) RETURNS INT AS $$
-BEGIN
- RETURN 1;
-END;
-$$ LANGUAGE plpgsql;
-GO
-
-
+--
+-- 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.
+--
+
+CREATE TYPE MyType AS ENUM ('1', '2', '3')
+GO
+CREATE TYPE MyType2 AS ENUM ('1', '2', '3')
+GO
+
+create table METADATA_TEST_TABLE (afield int, bfield int)
+GO
+
+create table TABLE_A (
+ A_ID INT NOT NULL,
+ A2_ID INT,
+ PRIMARY KEY (A_ID)
+)
+GO
+
+
+create table TABLE_A_MULTICOL_PK (
+ A1_ID INT NOT NULL,
+ A2_ID INT NOT NULL,
+ VAL3 INT,
+ PRIMARY KEY (A1_ID, A2_ID)
+)
+GO
+create table TABLE_B_WITH_MULTICOL_FK (
+ B_ID INT NOT NULL,
+ OTHER_A1_ID INT,
+ OTHER_A2_ID INT,
+ PRIMARY KEY (B_ID)
+)
+GO
+ALTER TABLE TABLE_B_WITH_MULTICOL_FK ADD CONSTRAINT FK_A_MULTICOL FOREIGN KEY (OTHER_A1_ID, OTHER_A2_ID) REFERENCES TABLE_A_MULTICOL_PK(A1_ID, A2_ID)
+GO
+
+create table TABLE_B_WITH_FK (
+ B_ID INT NOT NULL,
+ OTHER_A_ID INT,
+ PRIMARY KEY (B_ID)
+)
+GO
+ALTER TABLE TABLE_B_WITH_FK ADD CONSTRAINT FK_A FOREIGN KEY (OTHER_A_ID) REFERENCES TABLE_A(A_ID)
+GO
+
+create table TABLE_GENERATED_ID (
+ GEN_ID SERIAL,
+ FIELD1 INT
+)
+GO
+
+
+
+CREATE VIEW VIEW1 AS SELECT * FROM METADATA_TEST_TABLE
+-- my comment
+GO
+
+
+-- Postgresql does not allow dropping objects that have dependencies, so the invalid view test is not applicable
+
+
+CREATE SEQUENCE REGULAR_SEQUENCE
+GO
+
+
+CREATE OR REPLACE FUNCTION FUNC1 () RETURNS INT AS $$
+BEGIN
+ -- ensure that func comment remains
+ RETURN 1;
+END;
+$$ LANGUAGE plpgsql;
+GO
+
+CREATE FUNCTION FUNC_WITH_OVERLOAD () RETURNS INT AS $$
+BEGIN
+ RETURN 1;
+END;
+$$ LANGUAGE plpgsql;
+GO
+
+CREATE FUNCTION FUNC_WITH_OVERLOAD (var1 integer) RETURNS INT AS $$
+BEGIN
+ RETURN 1;
+END;
+$$ LANGUAGE plpgsql;
+GO
+
+CREATE FUNCTION FUNC_WITH_OVERLOAD (var1 integer, IN INVALSTR VARCHAR(32)) RETURNS INT AS $$
+BEGIN
+ RETURN 1;
+END;
+$$ LANGUAGE plpgsql;
+GO
+
+
diff --git a/obevo-db-impls/obevo-db-postgresql/src/test/resources/reveng/pgdump/expected/myschema01/sp/sp1.sql b/obevo-db-impls/obevo-db-postgresql/src/test/resources/reveng/pgdump/expected/myschema01/sp/sp1.sql
new file mode 100644
index 00000000..4085efd9
--- /dev/null
+++ b/obevo-db-impls/obevo-db-postgresql/src/test/resources/reveng/pgdump/expected/myschema01/sp/sp1.sql
@@ -0,0 +1,7 @@
+CREATE PROCEDURE sp1()
+ LANGUAGE plpgsql
+ AS $$ DECLARE val INTEGER; END $$;
+
+
+
+GO
\ No newline at end of file
diff --git a/obevo-db-impls/obevo-db-postgresql/src/test/resources/reveng/pgdump/expected/myschema01/usertype/usertype1.sql b/obevo-db-impls/obevo-db-postgresql/src/test/resources/reveng/pgdump/expected/myschema01/usertype/usertype1.sql
new file mode 100644
index 00000000..ccbd3070
--- /dev/null
+++ b/obevo-db-impls/obevo-db-postgresql/src/test/resources/reveng/pgdump/expected/myschema01/usertype/usertype1.sql
@@ -0,0 +1,9 @@
+CREATE TYPE usertype1 AS ENUM (
+ '1',
+ '2',
+ '3'
+);
+
+
+
+GO
\ No newline at end of file
diff --git a/obevo-db-impls/obevo-db-postgresql/src/test/resources/reveng/pgdump/input/input-noschemaqualifier.sql b/obevo-db-impls/obevo-db-postgresql/src/test/resources/reveng/pgdump/input/input-noschemaqualifier.sql
new file mode 100644
index 00000000..3d27f6a5
--- /dev/null
+++ b/obevo-db-impls/obevo-db-postgresql/src/test/resources/reveng/pgdump/input/input-noschemaqualifier.sql
@@ -0,0 +1,265 @@
+--
+-- PostgreSQL database dump
+--
+
+-- Dumped from database version 9.6.2
+-- Dumped by pg_dump version 9.6.3
+
+SET statement_timeout = 0;
+SET lock_timeout = 0;
+SET idle_in_transaction_session_timeout = 0;
+SET client_encoding = 'UTF8';
+SET standard_conforming_strings = on;
+SET check_function_bodies = false;
+SET client_min_messages = warning;
+SET row_security = off;
+
+--
+-- Name: myschema01; Type: SCHEMA; Schema: -; Owner: -
+--
+
+CREATE SCHEMA myschema01;
+
+
+SET search_path = myschema01, pg_catalog;
+
+
+--
+-- Name: usertype0; Type: TYPE; Schema: mylargeschema; Owner: -
+--
+
+CREATE TYPE myschema01.usertype1 AS ENUM (
+ '1',
+ '2',
+ '3'
+);
+
+
+--
+-- Name: sp0(); Type: PROCEDURE; Schema: mylargeschema; Owner: -
+--
+
+CREATE PROCEDURE sp1()
+ LANGUAGE plpgsql
+ AS $$ DECLARE val INTEGER; END $$;
+
+
+--
+-- Name: func1(); Type: FUNCTION; Schema: myschema01; Owner: -
+--
+
+CREATE FUNCTION func1() RETURNS integer
+ LANGUAGE plpgsql
+ AS '
+BEGIN
+ -- ensure that func comment remains
+ RETURN 1;
+END;
+';
+
+
+--
+-- Name: func_with_overload(); Type: FUNCTION; Schema: myschema01; Owner: -
+--
+
+CREATE FUNCTION func_with_overload() RETURNS integer
+ LANGUAGE plpgsql
+ AS '
+BEGIN
+ RETURN 1;
+END;
+';
+
+
+--
+-- Name: func_with_overload(integer); Type: FUNCTION; Schema: myschema01; Owner: -
+--
+
+CREATE FUNCTION func_with_overload(var1 integer) RETURNS integer
+ LANGUAGE plpgsql
+ AS '
+BEGIN
+ RETURN 1;
+END;
+';
+
+
+--
+-- Name: func_with_overload(integer, character varying); Type: FUNCTION; Schema: myschema01; Owner: -
+--
+
+CREATE FUNCTION func_with_overload(var1 integer, invalstr character varying) RETURNS integer
+ LANGUAGE plpgsql
+ AS '
+BEGIN
+ RETURN 1;
+END;
+';
+
+
+SET default_tablespace = '';
+
+SET default_with_oids = false;
+
+--
+-- Name: metadata_test_table; Type: TABLE; Schema: myschema01; Owner: -
+--
+
+CREATE TABLE metadata_test_table (
+ afield integer,
+ bfield integer
+);
+
+
+--
+-- Name: regular_sequence; Type: SEQUENCE; Schema: myschema01; Owner: -
+--
+
+CREATE SEQUENCE regular_sequence
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+--
+-- Name: table_a; Type: TABLE; Schema: myschema01; Owner: -
+--
+
+CREATE TABLE table_a (
+ a_id integer NOT NULL,
+ a2_id integer
+);
+
+
+--
+-- Name: table_a_multicol_pk; Type: TABLE; Schema: myschema01; Owner: -
+--
+
+CREATE TABLE table_a_multicol_pk (
+ a1_id integer NOT NULL,
+ a2_id integer NOT NULL,
+ val3 integer
+);
+
+
+--
+-- Name: table_b_with_fk; Type: TABLE; Schema: myschema01; Owner: -
+--
+
+CREATE TABLE table_b_with_fk (
+ b_id integer NOT NULL,
+ other_a_id integer
+);
+
+
+--
+-- Name: table_b_with_multicol_fk; Type: TABLE; Schema: myschema01; Owner: -
+--
+
+CREATE TABLE table_b_with_multicol_fk (
+ b_id integer NOT NULL,
+ other_a1_id integer,
+ other_a2_id integer
+);
+
+
+--
+-- Name: table_generated_id; Type: TABLE; Schema: myschema01; Owner: -
+--
+
+CREATE TABLE table_generated_id (
+ gen_id integer NOT NULL,
+ field1 integer
+);
+
+
+--
+-- Name: table_generated_id_gen_id_seq; Type: SEQUENCE; Schema: myschema01; Owner: -
+--
+
+CREATE SEQUENCE table_generated_id_gen_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+--
+-- Name: table_generated_id_gen_id_seq; Type: SEQUENCE OWNED BY; Schema: myschema01; Owner: -
+--
+
+ALTER SEQUENCE myschema01.table_generated_id_gen_id_seq OWNED BY myschema01.table_generated_id.gen_id;
+
+
+--
+-- Name: view1; Type: VIEW; Schema: myschema01; Owner: -
+--
+
+CREATE VIEW view1 AS
+ SELECT metadata_test_table.afield,
+ metadata_test_table.bfield
+ FROM metadata_test_table;
+
+
+--
+-- Name: table_generated_id gen_id; Type: DEFAULT; Schema: myschema01; Owner: -
+--
+
+ALTER TABLE ONLY table_generated_id ALTER COLUMN gen_id SET DEFAULT nextval('table_generated_id_gen_id_seq'::regclass);
+
+
+--
+-- Name: table_a_multicol_pk table_a_multicol_pk_pkey; Type: CONSTRAINT; Schema: myschema01; Owner: -
+--
+
+ALTER TABLE ONLY table_a_multicol_pk
+ ADD CONSTRAINT table_a_multicol_pk_pkey PRIMARY KEY (a1_id, a2_id);
+
+
+--
+-- Name: table_a table_a_pkey; Type: CONSTRAINT; Schema: myschema01; Owner: -
+--
+
+ALTER TABLE ONLY table_a
+ ADD CONSTRAINT table_a_pkey PRIMARY KEY (a_id);
+
+
+--
+-- Name: table_b_with_fk table_b_with_fk_pkey; Type: CONSTRAINT; Schema: myschema01; Owner: -
+--
+
+ALTER TABLE ONLY table_b_with_fk
+ ADD CONSTRAINT table_b_with_fk_pkey PRIMARY KEY (b_id);
+
+
+--
+-- Name: table_b_with_multicol_fk table_b_with_multicol_fk_pkey; Type: CONSTRAINT; Schema: myschema01; Owner: -
+--
+
+ALTER TABLE ONLY table_b_with_multicol_fk
+ ADD CONSTRAINT table_b_with_multicol_fk_pkey PRIMARY KEY (b_id);
+
+
+--
+-- Name: table_b_with_fk fk_a; Type: FK CONSTRAINT; Schema: myschema01; Owner: -
+--
+
+ALTER TABLE ONLY table_b_with_fk
+ ADD CONSTRAINT fk_a FOREIGN KEY (other_a_id) REFERENCES table_a(a_id);
+
+
+--
+-- Name: table_b_with_multicol_fk fk_a_multicol; Type: FK CONSTRAINT; Schema: myschema01; Owner: -
+--
+
+ALTER TABLE ONLY table_b_with_multicol_fk
+ ADD CONSTRAINT fk_a_multicol FOREIGN KEY (other_a1_id, other_a2_id) REFERENCES table_a_multicol_pk(a1_id, a2_id);
+
+
+--
+-- PostgreSQL database dump complete
+--
+
diff --git a/obevo-db-impls/obevo-db-postgresql/src/test/resources/reveng/pgdump/input/input.sql b/obevo-db-impls/obevo-db-postgresql/src/test/resources/reveng/pgdump/input/input.sql
index 01916509..f89b471e 100644
--- a/obevo-db-impls/obevo-db-postgresql/src/test/resources/reveng/pgdump/input/input.sql
+++ b/obevo-db-impls/obevo-db-postgresql/src/test/resources/reveng/pgdump/input/input.sql
@@ -23,11 +23,32 @@ CREATE SCHEMA myschema01;
SET search_path = myschema01, pg_catalog;
+
+--
+-- Name: usertype0; Type: TYPE; Schema: mylargeschema; Owner: -
+--
+
+CREATE TYPE myschema01.usertype1 AS ENUM (
+ '1',
+ '2',
+ '3'
+);
+
+
+--
+-- Name: sp0(); Type: PROCEDURE; Schema: mylargeschema; Owner: -
+--
+
+CREATE PROCEDURE myschema01.sp1()
+ LANGUAGE plpgsql
+ AS $$ DECLARE val INTEGER; END $$;
+
+
--
-- Name: func1(); Type: FUNCTION; Schema: myschema01; Owner: -
--
-CREATE FUNCTION func1() RETURNS integer
+CREATE FUNCTION myschema01.func1() RETURNS integer
LANGUAGE plpgsql
AS '
BEGIN
@@ -41,7 +62,7 @@ END;
-- Name: func_with_overload(); Type: FUNCTION; Schema: myschema01; Owner: -
--
-CREATE FUNCTION func_with_overload() RETURNS integer
+CREATE FUNCTION myschema01.func_with_overload() RETURNS integer
LANGUAGE plpgsql
AS '
BEGIN
@@ -54,7 +75,7 @@ END;
-- Name: func_with_overload(integer); Type: FUNCTION; Schema: myschema01; Owner: -
--
-CREATE FUNCTION func_with_overload(var1 integer) RETURNS integer
+CREATE FUNCTION myschema01.func_with_overload(var1 integer) RETURNS integer
LANGUAGE plpgsql
AS '
BEGIN
@@ -67,7 +88,7 @@ END;
-- Name: func_with_overload(integer, character varying); Type: FUNCTION; Schema: myschema01; Owner: -
--
-CREATE FUNCTION func_with_overload(var1 integer, invalstr character varying) RETURNS integer
+CREATE FUNCTION myschema01.func_with_overload(var1 integer, invalstr character varying) RETURNS integer
LANGUAGE plpgsql
AS '
BEGIN
@@ -84,7 +105,7 @@ SET default_with_oids = false;
-- Name: metadata_test_table; Type: TABLE; Schema: myschema01; Owner: -
--
-CREATE TABLE metadata_test_table (
+CREATE TABLE myschema01.metadata_test_table (
afield integer,
bfield integer
);
@@ -94,7 +115,7 @@ CREATE TABLE metadata_test_table (
-- Name: regular_sequence; Type: SEQUENCE; Schema: myschema01; Owner: -
--
-CREATE SEQUENCE regular_sequence
+CREATE SEQUENCE myschema01.regular_sequence
START WITH 1
INCREMENT BY 1
NO MINVALUE
@@ -106,7 +127,7 @@ CREATE SEQUENCE regular_sequence
-- Name: table_a; Type: TABLE; Schema: myschema01; Owner: -
--
-CREATE TABLE table_a (
+CREATE TABLE myschema01.table_a (
a_id integer NOT NULL,
a2_id integer
);
@@ -116,7 +137,7 @@ CREATE TABLE table_a (
-- Name: table_a_multicol_pk; Type: TABLE; Schema: myschema01; Owner: -
--
-CREATE TABLE table_a_multicol_pk (
+CREATE TABLE myschema01.table_a_multicol_pk (
a1_id integer NOT NULL,
a2_id integer NOT NULL,
val3 integer
@@ -127,7 +148,7 @@ CREATE TABLE table_a_multicol_pk (
-- Name: table_b_with_fk; Type: TABLE; Schema: myschema01; Owner: -
--
-CREATE TABLE table_b_with_fk (
+CREATE TABLE myschema01.table_b_with_fk (
b_id integer NOT NULL,
other_a_id integer
);
@@ -137,7 +158,7 @@ CREATE TABLE table_b_with_fk (
-- Name: table_b_with_multicol_fk; Type: TABLE; Schema: myschema01; Owner: -
--
-CREATE TABLE table_b_with_multicol_fk (
+CREATE TABLE myschema01.table_b_with_multicol_fk (
b_id integer NOT NULL,
other_a1_id integer,
other_a2_id integer
@@ -148,7 +169,7 @@ CREATE TABLE table_b_with_multicol_fk (
-- Name: table_generated_id; Type: TABLE; Schema: myschema01; Owner: -
--
-CREATE TABLE table_generated_id (
+CREATE TABLE myschema01.table_generated_id (
gen_id integer NOT NULL,
field1 integer
);
@@ -158,7 +179,7 @@ CREATE TABLE table_generated_id (
-- Name: table_generated_id_gen_id_seq; Type: SEQUENCE; Schema: myschema01; Owner: -
--
-CREATE SEQUENCE table_generated_id_gen_id_seq
+CREATE SEQUENCE myschema01.table_generated_id_gen_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
@@ -170,31 +191,31 @@ CREATE SEQUENCE table_generated_id_gen_id_seq
-- Name: table_generated_id_gen_id_seq; Type: SEQUENCE OWNED BY; Schema: myschema01; Owner: -
--
-ALTER SEQUENCE table_generated_id_gen_id_seq OWNED BY table_generated_id.gen_id;
+ALTER SEQUENCE myschema01.table_generated_id_gen_id_seq OWNED BY myschema01.table_generated_id.gen_id;
--
-- Name: view1; Type: VIEW; Schema: myschema01; Owner: -
--
-CREATE VIEW view1 AS
+CREATE VIEW myschema01.view1 AS
SELECT metadata_test_table.afield,
metadata_test_table.bfield
- FROM metadata_test_table;
+ FROM myschema01.metadata_test_table;
--
-- Name: table_generated_id gen_id; Type: DEFAULT; Schema: myschema01; Owner: -
--
-ALTER TABLE ONLY table_generated_id ALTER COLUMN gen_id SET DEFAULT nextval('table_generated_id_gen_id_seq'::regclass);
+ALTER TABLE ONLY myschema01.table_generated_id ALTER COLUMN gen_id SET DEFAULT nextval('table_generated_id_gen_id_seq'::regclass);
--
-- Name: table_a_multicol_pk table_a_multicol_pk_pkey; Type: CONSTRAINT; Schema: myschema01; Owner: -
--
-ALTER TABLE ONLY table_a_multicol_pk
+ALTER TABLE ONLY myschema01.table_a_multicol_pk
ADD CONSTRAINT table_a_multicol_pk_pkey PRIMARY KEY (a1_id, a2_id);
@@ -202,7 +223,7 @@ ALTER TABLE ONLY table_a_multicol_pk
-- Name: table_a table_a_pkey; Type: CONSTRAINT; Schema: myschema01; Owner: -
--
-ALTER TABLE ONLY table_a
+ALTER TABLE ONLY myschema01.table_a
ADD CONSTRAINT table_a_pkey PRIMARY KEY (a_id);
@@ -210,7 +231,7 @@ ALTER TABLE ONLY table_a
-- Name: table_b_with_fk table_b_with_fk_pkey; Type: CONSTRAINT; Schema: myschema01; Owner: -
--
-ALTER TABLE ONLY table_b_with_fk
+ALTER TABLE ONLY myschema01.table_b_with_fk
ADD CONSTRAINT table_b_with_fk_pkey PRIMARY KEY (b_id);
@@ -218,7 +239,7 @@ ALTER TABLE ONLY table_b_with_fk
-- Name: table_b_with_multicol_fk table_b_with_multicol_fk_pkey; Type: CONSTRAINT; Schema: myschema01; Owner: -
--
-ALTER TABLE ONLY table_b_with_multicol_fk
+ALTER TABLE ONLY myschema01.table_b_with_multicol_fk
ADD CONSTRAINT table_b_with_multicol_fk_pkey PRIMARY KEY (b_id);
@@ -226,7 +247,7 @@ ALTER TABLE ONLY table_b_with_multicol_fk
-- Name: table_b_with_fk fk_a; Type: FK CONSTRAINT; Schema: myschema01; Owner: -
--
-ALTER TABLE ONLY table_b_with_fk
+ALTER TABLE ONLY myschema01.table_b_with_fk
ADD CONSTRAINT fk_a FOREIGN KEY (other_a_id) REFERENCES table_a(a_id);
@@ -234,7 +255,7 @@ ALTER TABLE ONLY table_b_with_fk
-- Name: table_b_with_multicol_fk fk_a_multicol; Type: FK CONSTRAINT; Schema: myschema01; Owner: -
--
-ALTER TABLE ONLY table_b_with_multicol_fk
+ALTER TABLE ONLY myschema01.table_b_with_multicol_fk
ADD CONSTRAINT fk_a_multicol FOREIGN KEY (other_a1_id, other_a2_id) REFERENCES table_a_multicol_pk(a1_id, a2_id);
diff --git a/obevo-db/src/main/java/com/gs/obevo/db/api/platform/DbPlatform.java b/obevo-db/src/main/java/com/gs/obevo/db/api/platform/DbPlatform.java
index 0aa5c57d..e1c2e545 100644
--- a/obevo-db/src/main/java/com/gs/obevo/db/api/platform/DbPlatform.java
+++ b/obevo-db/src/main/java/com/gs/obevo/db/api/platform/DbPlatform.java
@@ -71,6 +71,12 @@ public interface DbPlatform extends Platform {
*/
String getSubschemaPrefix(PhysicalSchema schema);
+ /**
+ * The token to use to indicate a null field when creating columns in a table. Some platforms use the NULL keyword,
+ * and others imply a lack of keyword (e.g. "") as null.
+ *
+ * @since 6.0.0
+ */
String getNullMarkerForCreateTable();
String getTimestampType();
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 5f3bc07b..a8ba9f8b 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
@@ -161,23 +161,24 @@ private static String nameWithPrefixPattern(String startQuoteStr, String endQuot
public void reveng(AquaRevengArgs args) {
if (args.getInputPath() == null) {
File interimDir = new File(args.getOutputPath(), "interim");
+ System.out.println();
boolean proceedWithReveng = doRevengOrInstructions(System.out, args, interimDir);
- System.out.println("");
- System.out.println("");
+ System.out.println();
+ System.out.println();
if (proceedWithReveng) {
System.out.println("Interim reverse-engineering from the vendor tool is complete.");
System.out.println("Content was written to: " + interimDir);
System.out.println("Proceeding with full reverse-engineering: " + interimDir);
- System.out.println("");
+ System.out.println();
System.out.println("*** In case the interim content had issues when reverse-engineering to the final output, you can update the interim files and restart from there (without going back to the DB) by specifying the following argument:");
System.out.println(" -inputPath " + ObjectUtils.defaultIfNull(args.getOutputPath(), ""));
revengMain(interimDir, args);
} else {
System.out.println("***********");
- 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("");
+ 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");
}
} else {
diff --git a/obevo-dbmetadata-impl/src/main/java/com/gs/obevo/dbmetadata/impl/dialects/PostgresqlMetadataDialect.java b/obevo-dbmetadata-impl/src/main/java/com/gs/obevo/dbmetadata/impl/dialects/PostgresqlMetadataDialect.java
index 238d0413..8d7c9830 100644
--- a/obevo-dbmetadata-impl/src/main/java/com/gs/obevo/dbmetadata/impl/dialects/PostgresqlMetadataDialect.java
+++ b/obevo-dbmetadata-impl/src/main/java/com/gs/obevo/dbmetadata/impl/dialects/PostgresqlMetadataDialect.java
@@ -1,128 +1,150 @@
-/**
- * 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.dbmetadata.impl.dialects;
-
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.util.Map;
-
-import com.gs.obevo.api.appdata.PhysicalSchema;
-import com.gs.obevo.dbmetadata.api.DaExtension;
-import com.gs.obevo.dbmetadata.api.DaExtensionImpl;
-import com.gs.obevo.dbmetadata.api.DaRoutineType;
-import org.apache.commons.dbutils.handlers.ColumnListHandler;
-import org.apache.commons.dbutils.handlers.MapListHandler;
-import org.eclipse.collections.api.block.function.Function;
-import org.eclipse.collections.api.list.ImmutableList;
-import org.eclipse.collections.api.set.ImmutableSet;
-import org.eclipse.collections.impl.block.factory.StringFunctions;
-import org.eclipse.collections.impl.factory.Lists;
-import org.eclipse.collections.impl.factory.Sets;
-import org.eclipse.collections.impl.list.mutable.ListAdapter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import schemacrawler.schema.RoutineType;
-import schemacrawler.schemacrawler.DatabaseSpecificOverrideOptionsBuilder;
-import schemacrawler.schemacrawler.SchemaCrawlerOptions;
-
-public class PostgresqlMetadataDialect extends AbstractMetadataDialect {
- private static final Logger LOG = LoggerFactory.getLogger(OracleMetadataDialect.class);
-
- @Override
- public void customEdits(SchemaCrawlerOptions options, Connection conn) {
- // postgresql only supports FUNCTIONs in its syntax, not PROCEDUREs. However, the metadata still comes
- // back as procedure. We override the metadata value using the getRoutineOverrideValue method.
- options.setRoutineTypes(Lists.immutable.with(RoutineType.procedure).castToList());
- }
-
- @Override
- public DatabaseSpecificOverrideOptionsBuilder getDbSpecificOptionsBuilder(Connection conn, PhysicalSchema physicalSchema, boolean searchAllTables) {
- DatabaseSpecificOverrideOptionsBuilder dbSpecificOptionsBuilder = super.getDbSpecificOptionsBuilder(conn, physicalSchema, searchAllTables);
-
- String sequenceSql = getSequenceSql(physicalSchema);
- if (sequenceSql != null) {
- // if null, then setting the sequences object to null won't help either
- dbSpecificOptionsBuilder.withInformationSchemaViews().withSequencesSql(sequenceSql);
- }
-
- return dbSpecificOptionsBuilder;
- }
-
- /**
- * Gets the sequence SQL for the JDBC metadata.
- * Protected visibility as subclasses may need to override.
- */
- protected String getSequenceSql(PhysicalSchema physicalSchema) {
- return "SELECT\n" +
- " NULL AS SEQUENCE_CATALOG,\n" +
- " SEQUENCE_SCHEMA,\n" +
- " SEQUENCE_NAME,\n" +
- " INCREMENT,\n" +
- " MINIMUM_VALUE,\n" +
- " MAXIMUM_VALUE,\n" +
- " CYCLE_OPTION\n" +
- "FROM\n" +
- " INFORMATION_SCHEMA.SEQUENCES\n" +
- "WHERE SEQUENCE_SCHEMA = '" + physicalSchema.getPhysicalName() + "'\n" +
- "ORDER BY\n" +
- " SEQUENCE_CATALOG,\n" +
- " SEQUENCE_SCHEMA,\n" +
- " SEQUENCE_NAME\n";
- }
-
- @Override
- public String getSchemaExpression(PhysicalSchema physicalSchema) {
- return "(?i)" + physicalSchema.getPhysicalName();
- }
-
- /**
- * PostgreSQL should override the routine type to "function". PostgreSQL only supports functions in its SQL syntax;
- * however, the JDBC metadata returns it as a "procedure". For consistency w/ the SQL syntax, we do this override.
- */
- @Override
- public DaRoutineType getRoutineOverrideValue() {
- return DaRoutineType.function;
- }
-
- @Override
- public ImmutableSet getExtensionsOptional(Connection conn) throws SQLException {
- final String sql = "SELECT DISTINCT EXTNAME FROM PG_EXTENSION";
- LOG.debug("Executing extension metadata query SQL: {}", sql);
-
- ImmutableList> maps = ListAdapter.adapt(jdbc.query(conn, sql, new MapListHandler())).toImmutable();
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("Results:");
- for (Map map : maps) {
- LOG.debug("ROW: {}", map.toString());
- }
- }
-
- return maps.collect(new Function, DaExtension>() {
- @Override
- public DaExtension valueOf(Map map) {
- return new DaExtensionImpl((String) map.get("EXTNAME"));
- }
- }).toSet().toImmutable();
- }
-
- @Override
- public ImmutableSet getGroupNamesOptional(Connection conn, PhysicalSchema physicalSchema) throws SQLException {
- return Sets.immutable
- .withAll(jdbc.query(conn, "select rolname from pg_roles", new ColumnListHandler()))
- .collect(StringFunctions.trim());
- }
-}
+/**
+ * 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.dbmetadata.impl.dialects;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Map;
+
+import com.gs.obevo.api.appdata.PhysicalSchema;
+import com.gs.obevo.dbmetadata.api.DaExtension;
+import com.gs.obevo.dbmetadata.api.DaExtensionImpl;
+import com.gs.obevo.dbmetadata.api.DaRoutineType;
+import com.gs.obevo.dbmetadata.api.DaSchema;
+import com.gs.obevo.dbmetadata.api.DaUserType;
+import com.gs.obevo.dbmetadata.api.DaUserTypeImpl;
+import org.apache.commons.dbutils.handlers.ColumnListHandler;
+import org.apache.commons.dbutils.handlers.MapListHandler;
+import org.eclipse.collections.api.block.function.Function;
+import org.eclipse.collections.api.collection.ImmutableCollection;
+import org.eclipse.collections.api.list.ImmutableList;
+import org.eclipse.collections.api.set.ImmutableSet;
+import org.eclipse.collections.impl.block.factory.StringFunctions;
+import org.eclipse.collections.impl.factory.Lists;
+import org.eclipse.collections.impl.factory.Sets;
+import org.eclipse.collections.impl.list.mutable.ListAdapter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import schemacrawler.schema.RoutineType;
+import schemacrawler.schemacrawler.DatabaseSpecificOverrideOptionsBuilder;
+import schemacrawler.schemacrawler.SchemaCrawlerOptions;
+
+public class PostgresqlMetadataDialect extends AbstractMetadataDialect {
+ private static final Logger LOG = LoggerFactory.getLogger(OracleMetadataDialect.class);
+
+ @Override
+ public void customEdits(SchemaCrawlerOptions options, Connection conn) {
+ // postgresql only supports FUNCTIONs in its syntax, not PROCEDUREs. However, the metadata still comes
+ // back as procedure. We override the metadata value using the getRoutineOverrideValue method.
+ options.setRoutineTypes(Lists.immutable.with(RoutineType.procedure).castToList());
+ }
+
+ @Override
+ public DatabaseSpecificOverrideOptionsBuilder getDbSpecificOptionsBuilder(Connection conn, PhysicalSchema physicalSchema, boolean searchAllTables) {
+ DatabaseSpecificOverrideOptionsBuilder dbSpecificOptionsBuilder = super.getDbSpecificOptionsBuilder(conn, physicalSchema, searchAllTables);
+
+ String sequenceSql = getSequenceSql(physicalSchema);
+ if (sequenceSql != null) {
+ // if null, then setting the sequences object to null won't help either
+ dbSpecificOptionsBuilder.withInformationSchemaViews().withSequencesSql(sequenceSql);
+ }
+
+ return dbSpecificOptionsBuilder;
+ }
+
+ /**
+ * Gets the sequence SQL for the JDBC metadata.
+ * Protected visibility as subclasses may need to override.
+ */
+ protected String getSequenceSql(PhysicalSchema physicalSchema) {
+ return "SELECT\n" +
+ " NULL AS SEQUENCE_CATALOG,\n" +
+ " SEQUENCE_SCHEMA,\n" +
+ " SEQUENCE_NAME,\n" +
+ " INCREMENT,\n" +
+ " MINIMUM_VALUE,\n" +
+ " MAXIMUM_VALUE,\n" +
+ " CYCLE_OPTION\n" +
+ "FROM\n" +
+ " INFORMATION_SCHEMA.SEQUENCES\n" +
+ "WHERE SEQUENCE_SCHEMA = '" + physicalSchema.getPhysicalName() + "'\n" +
+ "ORDER BY\n" +
+ " SEQUENCE_CATALOG,\n" +
+ " SEQUENCE_SCHEMA,\n" +
+ " SEQUENCE_NAME\n";
+ }
+
+ @Override
+ public String getSchemaExpression(PhysicalSchema physicalSchema) {
+ return "(?i)" + physicalSchema.getPhysicalName();
+ }
+
+ /**
+ * PostgreSQL should override the routine type to "function". PostgreSQL only supports functions in its SQL syntax;
+ * however, the JDBC metadata returns it as a "procedure". For consistency w/ the SQL syntax, we do this override.
+ */
+ @Override
+ public DaRoutineType getRoutineOverrideValue() {
+ return DaRoutineType.function;
+ }
+
+ @Override
+ public ImmutableSet getExtensionsOptional(Connection conn) throws SQLException {
+ final String sql = "SELECT DISTINCT EXTNAME FROM PG_EXTENSION";
+ LOG.debug("Executing extension metadata query SQL: {}", sql);
+
+ ImmutableList> maps = ListAdapter.adapt(jdbc.query(conn, sql, new MapListHandler())).toImmutable();
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Results:");
+ for (Map map : maps) {
+ LOG.debug("ROW: {}", map.toString());
+ }
+ }
+
+ return maps.collect(new Function, DaExtension>() {
+ @Override
+ public DaExtension valueOf(Map map) {
+ return new DaExtensionImpl((String) map.get("EXTNAME"));
+ }
+ }).toSet().toImmutable();
+ }
+
+ @Override
+ public ImmutableCollection searchUserTypes(final DaSchema schema, Connection conn) {
+ String sql = "SELECT t.typname \n" +
+ "FROM pg_type t \n" +
+ "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace \n" +
+ "WHERE (t.typrelid = 0 OR (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid)) \n" +
+ "AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type el WHERE el.oid = t.typelem AND el.typarray = t.oid)\n" +
+ "AND n.nspname IN ('" + schema.getName() + "')";
+ ImmutableList> maps = ListAdapter.adapt(jdbc.query(conn, sql, new MapListHandler())).toImmutable();
+
+ return maps.collect(new Function, DaUserType>() {
+ @Override
+ public DaUserType valueOf(Map map) {
+ return new DaUserTypeImpl((String) map.get("typname"), schema);
+ }
+ });
+ }
+
+ @Override
+ public ImmutableSet getGroupNamesOptional(Connection conn, PhysicalSchema physicalSchema) throws SQLException {
+ return Sets.immutable
+ .withAll(jdbc.query(conn, "select rolname from pg_roles", new ColumnListHandler()))
+ .collect(StringFunctions.trim());
+ }
+}
From 4e78af63b51eafe06ec4ca65577fd4b8179efe5c Mon Sep 17 00:00:00 2001
From: shantstepanian <17996546+shantstepanian@users.noreply.github.com>
Date: Sat, 23 Mar 2019 15:49:52 -0400
Subject: [PATCH 5/5] Supporting postgres in-memory db translation for HSQL
---
CHANGELOG.md | 3 +
.../obevo-db-postgresql.iml | 4 +
obevo-db-impls/obevo-db-postgresql/pom.xml | 15 +
.../postgresql/PostgreSqlDbPlatform.java | 11 +
.../postgresql/PostgreSqlPgDumpReveng.java | 3 +-
.../PostgreSqlToH2TranslationDialect.java | 27 +
.../PostgreSqlToHsqlTranslationDialect.java | 92 +++
.../PostgreSqlInMemConversionTest.java | 53 ++
.../example1/step1/schema1/table/TABLE_A.ddl | 58 +-
.../example1/step1/schema1/table/TABLE_B.ddl | 10 +-
.../step1/schema1/table/TABLE_SPECIAL_COL.ddl | 2 +-
.../step1/schema1/table/TAB_WITH_SEQ.ddl | 16 +-
.../step1/schema1/usertype/usertype0.hsql.sql | 3 +
.../step1/schema1/usertype/usertype0.sql | 1 +
.../example1/step1/system-config-inmem.xml | 27 +
.../example1/step2/schema1/table/TABLE_A.ddl | 64 +-
.../example1/step2/schema1/table/TABLE_B.ddl | 10 +-
.../step2/schema1/table/TABLE_SPECIAL_COL.ddl | 2 +-
.../step2/schema1/table/TAB_WITH_SEQ.ddl | 16 +-
.../step2/schema1/usertype/usertype0.hsql.sql | 3 +
.../step2/schema1/usertype/usertype0.sql | 1 +
.../example1/step2/system-config-inmem.xml | 27 +
.../db/apps/reveng/AbstractDdlReveng.java | 2 +-
.../PostColumnSqlTranslator.java | 46 +-
.../src/main/jjtree/sqlInMemTranslate.jjt | 3 +-
.../obevo/db/unittest/UnitTestDbBuilder.java | 583 +++++++++---------
26 files changed, 679 insertions(+), 403 deletions(-)
create mode 100644 obevo-db-impls/obevo-db-postgresql/src/main/java/com/gs/obevo/db/impl/platforms/postgresql/PostgreSqlToH2TranslationDialect.java
create mode 100644 obevo-db-impls/obevo-db-postgresql/src/main/java/com/gs/obevo/db/impl/platforms/postgresql/PostgreSqlToHsqlTranslationDialect.java
create mode 100644 obevo-db-impls/obevo-db-postgresql/src/test/java/com/gs/obevo/db/impl/platforms/postgresql/PostgreSqlInMemConversionTest.java
create mode 100644 obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step1/schema1/usertype/usertype0.hsql.sql
create mode 100644 obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step1/system-config-inmem.xml
create mode 100644 obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step2/schema1/usertype/usertype0.hsql.sql
create mode 100644 obevo-db-impls/obevo-db-postgresql/src/test/resources/platforms/postgresql/example1/step2/system-config-inmem.xml
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;
+ }
+}