From f73eb1c99230b886f7bc5241d63d04ea5d9ca756 Mon Sep 17 00:00:00 2001 From: Nils Petzaell Date: Tue, 19 Dec 2017 04:35:37 +0100 Subject: [PATCH] Refactored viewSql to viewDefinition, deprecated text in selectViewSQL * Optimized imports * Refactored ViewService * Switched from specified generic to implied (diamond) * Added test for view and added selectViewSQL to h2 --- docs/source/configuration/databaseType.rst | 4 +- src/main/java/org/schemaspy/model/Table.java | 31 +++---- src/main/java/org/schemaspy/model/View.java | 18 ++-- .../output/xml/dom/XmlTableFormatter.java | 2 +- .../schemaspy/service/DatabaseService.java | 16 ++-- .../org/schemaspy/service/ViewService.java | 54 ++++++++--- .../service/helper/BasicTableMeta.java | 12 +-- .../org/schemaspy/view/HtmlTablePage.java | 10 +- .../org/schemaspy/types/db2.properties | 2 +- .../org/schemaspy/types/db2zos.properties | 2 +- .../org/schemaspy/types/db2zosnet.properties | 2 +- .../org/schemaspy/types/h2.properties | 3 +- .../org/schemaspy/types/mssql.properties | 2 +- .../org/schemaspy/types/netezza.properties | 2 +- .../org/schemaspy/types/ora.properties | 2 +- .../org/schemaspy/types/pgsql.properties | 2 +- .../org/schemaspy/types/redshift.properties | 2 +- .../integrationtesting/H2ViewIT.java | 92 +++++++++++++++++++ .../h2ViewIT/dbScripts/2tables1view.sql | 11 +++ 19 files changed, 197 insertions(+), 72 deletions(-) create mode 100644 src/test/java/org/schemaspy/integrationtesting/H2ViewIT.java create mode 100644 src/test/resources/integrationTesting/h2ViewIT/dbScripts/2tables1view.sql diff --git a/docs/source/configuration/databaseType.rst b/docs/source/configuration/databaseType.rst index 1e6320ca2..532cc2b41 100644 --- a/docs/source/configuration/databaseType.rst +++ b/docs/source/configuration/databaseType.rst @@ -145,7 +145,7 @@ So additional columns are ok, but you might need to alias columns so that they a **selectRoutineParametersSql=** specific_name, parameter_name, dtd_identifier, parameter_mode **selectViewSql=** - view_definition, text + view_definition, text (text has been deprecated) **selectCheckConstraintsSql=** table_name, constraint_name **selectTableIdsSql=** @@ -157,6 +157,6 @@ So additional columns are ok, but you might need to alias columns so that they a **selectColumnCommentsSql=** table_name, column_name, comments -**Extend the types of views that exist** +**Define viewTypes** **viewTypes=** default is VIEW \ No newline at end of file diff --git a/src/main/java/org/schemaspy/model/Table.java b/src/main/java/org/schemaspy/model/Table.java index b645c7a9d..eabc794cc 100644 --- a/src/main/java/org/schemaspy/model/Table.java +++ b/src/main/java/org/schemaspy/model/Table.java @@ -25,16 +25,7 @@ import org.slf4j.LoggerFactory; import java.lang.invoke.MethodHandles; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; -import java.util.TreeSet; +import java.util.*; @@ -50,12 +41,12 @@ public class Table implements Comparable { private final String name; private final String fullName; private final String container; - protected CaseInsensitiveMap columns = new CaseInsensitiveMap(); - private final List primaryKeys = new ArrayList(); - private final CaseInsensitiveMap foreignKeys = new CaseInsensitiveMap(); - private final CaseInsensitiveMap indexes = new CaseInsensitiveMap(); + protected CaseInsensitiveMap columns = new CaseInsensitiveMap<>(); + private final List primaryKeys = new ArrayList<>(); + private final CaseInsensitiveMap foreignKeys = new CaseInsensitiveMap<>(); + private final CaseInsensitiveMap indexes = new CaseInsensitiveMap<>(); private Object id; - private final Map checkConstraints = new TreeMap(String.CASE_INSENSITIVE_ORDER); + private final Map checkConstraints = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); private long numRows; protected final Database db; private String comments; @@ -240,7 +231,7 @@ public Map getCheckConstraints() { * @return */ public Set getIndexes() { - return new HashSet(indexes.values()); + return new HashSet<>(indexes.values()); } /** @@ -301,9 +292,9 @@ public TableColumn getColumn(String columnName) { * @return */ public List getColumns() { - Set sorted = new TreeSet(new ByColumnIdComparator()); + Set sorted = new TreeSet<>(new ByColumnIdComparator()); sorted.addAll(columns.values()); - return new ArrayList(sorted); + return new ArrayList<>(sorted); } public void setColumns(CaseInsensitiveMap columns) { @@ -455,7 +446,7 @@ private ForeignKeyConstraint getSelfReferencingConstraint() { * @return */ public List removeNonRealForeignKeys() { - List nonReals = new ArrayList(); + List nonReals = new ArrayList<>(); for (TableColumn column : columns.values()) { for (TableColumn parentColumn : column.getParents()) { @@ -617,7 +608,7 @@ public boolean isRemote() { * @return * @see #isView() */ - public String getViewSql() { + public String getViewDefinition() { return null; } diff --git a/src/main/java/org/schemaspy/model/View.java b/src/main/java/org/schemaspy/model/View.java index cf6a751d5..d57ca1b31 100644 --- a/src/main/java/org/schemaspy/model/View.java +++ b/src/main/java/org/schemaspy/model/View.java @@ -23,7 +23,7 @@ * defined them. */ public class View extends Table { - private String viewSql; + private String viewDefinition; /** * @param db @@ -31,14 +31,14 @@ public class View extends Table { * @param schema * @param name * @param remarks - * @param viewSql + * @param viewDefinition */ public View(Database db, String catalog, String schema, - String name, String remarks, String viewSql) { + String name, String remarks, String viewDefinition) { super(db, catalog, schema, name, remarks); - if (viewSql != null && viewSql.trim().length() > 0) - this.viewSql = viewSql; + if (viewDefinition != null && viewDefinition.trim().length() > 0) + this.viewDefinition = viewDefinition; } /** @@ -50,11 +50,11 @@ public boolean isView() { } @Override - public String getViewSql() { - return viewSql; + public String getViewDefinition() { + return viewDefinition; } - public void setViewSql(String viewSql) { - this.viewSql = viewSql; + public void setViewDefinition(String viewDefinition) { + this.viewDefinition = viewDefinition; } } diff --git a/src/main/java/org/schemaspy/output/xml/dom/XmlTableFormatter.java b/src/main/java/org/schemaspy/output/xml/dom/XmlTableFormatter.java index a38d9b8ae..ea1f6550c 100644 --- a/src/main/java/org/schemaspy/output/xml/dom/XmlTableFormatter.java +++ b/src/main/java/org/schemaspy/output/xml/dom/XmlTableFormatter.java @@ -268,7 +268,7 @@ private void appendIndexes(Node tableNode, Table table) { */ private void appendView(Element tableNode, Table table) { String sql; - if (table.isView() && (sql = table.getViewSql()) != null) { + if (table.isView() && (sql = table.getViewDefinition()) != null) { DOMUtil.appendAttribute(tableNode, "viewSql", sql); } } diff --git a/src/main/java/org/schemaspy/service/DatabaseService.java b/src/main/java/org/schemaspy/service/DatabaseService.java index 7630709a0..bc818acd5 100644 --- a/src/main/java/org/schemaspy/service/DatabaseService.java +++ b/src/main/java/org/schemaspy/service/DatabaseService.java @@ -166,12 +166,12 @@ private void initViews(Config config, Database db, ProgressListener listener, Da for (BasicTableMeta entry : getBasicTableMeta(config, db, listener, metadata, false, types)) { if (validator.isValid(entry.getName(), entry.getType())) { View view = new View(db, entry.getCatalog(), entry.getSchema(), entry.getName(), - entry.getRemarks(), entry.getViewSql()); + entry.getRemarks(), entry.getViewDefinition()); tableService.gatheringTableDetails(db, view); - if (entry.getViewSql() == null) { - view.setViewSql(viewService.fetchViewSql(db, view)); + if (entry.getViewDefinition() == null) { + view.setViewDefinition(viewService.fetchViewDefinition(db, view)); } db.getViewsMap().put(view.getName(), view); @@ -192,7 +192,7 @@ private void initViews(Config config, Database db, ProgressListener listener, Da */ private String[] getTypes(Config config, String propName, String defaultValue) { String value = config.getDbProperties().getProperty(propName, defaultValue); - List types = new ArrayList(); + List types = new ArrayList<>(); for (String type : value.split(",")) { type = type.trim(); if (type.length() > 0) @@ -313,7 +313,7 @@ void join() { * Multi-threaded implementation of a class that creates tables */ private class ThreadedTableCreator extends TableCreator { - private final Set threads = new HashSet(); + private final Set threads = new HashSet<>(); private final int maxThreads; ThreadedTableCreator(int maxThreads) { @@ -393,7 +393,7 @@ private List getBasicTableMeta(Config config, String... types) throws SQLException { String queryName = forTables ? "selectTablesSql" : "selectViewsSql"; String sql = config.getDbProperties().getProperty(queryName); - List basics = new ArrayList(); + List basics = new ArrayList<>(); if (sql != null) { @@ -410,11 +410,11 @@ private List getBasicTableMeta(Config config, if (cat == null && sch == null) sch = db.getSchema().getName(); String remarks = getOptionalString(rs, clazz + "_comment"); - String text = forTables ? null : getOptionalString(rs, "view_definition"); + String viewDefinition = forTables ? null : getOptionalString(rs, "view_definition"); String rows = forTables ? getOptionalString(rs, "table_rows") : null; long numRows = rows == null ? -1 : Long.parseLong(rows); - basics.add(new BasicTableMeta(cat, sch, name, clazz, remarks, text, numRows)); + basics.add(new BasicTableMeta(cat, sch, name, clazz, remarks, viewDefinition, numRows)); } } catch (SQLException sqlException) { // don't die just because this failed diff --git a/src/main/java/org/schemaspy/service/ViewService.java b/src/main/java/org/schemaspy/service/ViewService.java index abc06f63b..6274959be 100644 --- a/src/main/java/org/schemaspy/service/ViewService.java +++ b/src/main/java/org/schemaspy/service/ViewService.java @@ -10,6 +10,7 @@ import java.lang.invoke.MethodHandles; import java.sql.PreparedStatement; import java.sql.ResultSet; +import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.Objects; @@ -23,6 +24,8 @@ public class ViewService { private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + private int deprecatedNagCounter = 0; + public ViewService(SqlService sqlService) { this.sqlService = Objects.requireNonNull(sqlService); } @@ -33,27 +36,54 @@ public ViewService(SqlService sqlService) { * @return * @throws SQLException */ - public String fetchViewSql(Database db, View view) throws SQLException { + public String fetchViewDefinition(Database db, View view) throws SQLException { String selectViewSql = Config.getInstance().getDbProperties().getProperty("selectViewSql"); if (selectViewSql == null) { return null; } - StringBuilder viewDefinition = new StringBuilder(); try (PreparedStatement stmt = sqlService.prepareStatement(selectViewSql, db, view.getName()); - ResultSet rs = stmt.executeQuery()) { - - while (rs.next()) { - try { - viewDefinition.append(rs.getString("view_definition")); - } catch (SQLException tryOldName) { - viewDefinition.append(rs.getString("text")); - } - } - return viewDefinition.toString(); + ResultSet resultSet = stmt.executeQuery()) { + return getViewDefinitionFromResultSet(resultSet); } catch (SQLException sqlException) { LOGGER.error(selectViewSql); throw sqlException; } } + + private String getViewDefinitionFromResultSet(ResultSet resultSet) throws SQLException { + if (isViewDefinitionColumnPresent(resultSet.getMetaData())) { + return getFromViewDefinitionColumn(resultSet); + } + return getFromTextColumn(resultSet); + } + + private boolean isViewDefinitionColumnPresent(ResultSetMetaData resultSetMetaData) throws SQLException { + for(int i = 1; i <= resultSetMetaData.getColumnCount(); i++) { + if ("view_definition".equalsIgnoreCase(resultSetMetaData.getColumnLabel(i))){ + return true; + } + } + return false; + } + + private String getFromViewDefinitionColumn(ResultSet resultSet) throws SQLException { + StringBuilder viewDefinition = new StringBuilder(); + while (resultSet.next()) { + viewDefinition.append(resultSet.getString("view_definition")); + } + return viewDefinition.toString(); + } + + private String getFromTextColumn(ResultSet resultSet) throws SQLException { + StringBuilder viewDefinition = new StringBuilder(); + if (deprecatedNagCounter < 10) { + LOGGER.warn("ColumnLabel 'text' has been deprecated and will be removed"); + deprecatedNagCounter++; + } + while (resultSet.next()) { + viewDefinition.append(resultSet.getString("text")); + } + return viewDefinition.toString(); + } } diff --git a/src/main/java/org/schemaspy/service/helper/BasicTableMeta.java b/src/main/java/org/schemaspy/service/helper/BasicTableMeta.java index a3f5bbef8..a869ec6ce 100644 --- a/src/main/java/org/schemaspy/service/helper/BasicTableMeta.java +++ b/src/main/java/org/schemaspy/service/helper/BasicTableMeta.java @@ -13,7 +13,7 @@ public class BasicTableMeta final String name; final String type; final String remarks; - final String viewSql; + final String viewDefinition; final long numRows; // -1 if not determined /** @@ -21,17 +21,17 @@ public class BasicTableMeta * @param name * @param type typically "TABLE" or "VIEW" * @param remarks - * @param text optional textual SQL used to create the view + * @param viewDefinition optional textual SQL used to create the view * @param numRows number of rows, or -1 if not determined */ - public BasicTableMeta(String catalog, String schema, String name, String type, String remarks, String text, long numRows) + public BasicTableMeta(String catalog, String schema, String name, String type, String remarks, String viewDefinition, long numRows) { this.catalog = catalog; this.schema = schema; this.name = name; this.type = type; this.remarks = remarks; - viewSql = text; + this.viewDefinition = viewDefinition; this.numRows = numRows; } @@ -59,7 +59,7 @@ public String getType() { return type; } - public String getViewSql() { - return viewSql; + public String getViewDefinition() { + return viewDefinition; } } \ No newline at end of file diff --git a/src/main/java/org/schemaspy/view/HtmlTablePage.java b/src/main/java/org/schemaspy/view/HtmlTablePage.java index c9fe5a1b4..26473ddae 100644 --- a/src/main/java/org/schemaspy/view/HtmlTablePage.java +++ b/src/main/java/org/schemaspy/view/HtmlTablePage.java @@ -105,15 +105,15 @@ public void writeMainTable(Database db, Table table, File outputDir, WriteStats private Set
sqlReferences(Table table, Database db) { Set
references = null; - if (table.isView() && table.getViewSql() != null) { + if (table.isView() && table.getViewDefinition() != null) { DefaultSqlFormatter formatter = new DefaultSqlFormatter(); - references = formatter.getReferencedTables(table.getViewSql(), db); + references = formatter.getReferencedTables(table.getViewDefinition(), db); } return references; } private String sqlCode(Table table) { - return table.getViewSql() != null ? table.getViewSql().trim() : ""; + return table.getViewDefinition() != null ? table.getViewDefinition().trim() : ""; } private Object indexExists(Table table, Set indexedColumns) { @@ -126,7 +126,7 @@ private Object indexExists(Table table, Set indexedColumns) private Object definitionExists(Table table) { Object exists = null; - if (table.isView() && table.getViewSql() != null) { + if (table.isView() && table.getViewDefinition() != null) { exists = new Object(); } return exists; @@ -141,7 +141,7 @@ private Object definitionExists(Table table) { * two degrees of separation. * * @param table Table - * @param diagramsDir File + * @param diagramDir File * @return boolean true if the table has implied relatives within two * degrees of separation. * @throws IOException diff --git a/src/main/resources/org/schemaspy/types/db2.properties b/src/main/resources/org/schemaspy/types/db2.properties index 7394c0238..c38d56b1c 100644 --- a/src/main/resources/org/schemaspy/types/db2.properties +++ b/src/main/resources/org/schemaspy/types/db2.properties @@ -14,7 +14,7 @@ driver=COM.ibm.db2.jdbc.app.DB2Driver driverPath=c:/Program Files/IBM/SQLLIB/java/db2java.zip # return text that represents a specific :view / :schema -selectViewSql=select text from syscat.views where viewname=:view and viewschema=:schema +selectViewSql=select text view_definition from syscat.views where viewname=:view and viewschema=:schema # return table_name, constraint_name and text for a specific :schema selectCheckConstraintsSql=select constname constraint_name, tabname table_name, text from syscat.checks where tabschema=:schema diff --git a/src/main/resources/org/schemaspy/types/db2zos.properties b/src/main/resources/org/schemaspy/types/db2zos.properties index 2f3c0459a..9f6fca7fa 100644 --- a/src/main/resources/org/schemaspy/types/db2zos.properties +++ b/src/main/resources/org/schemaspy/types/db2zos.properties @@ -10,7 +10,7 @@ extends=db2 description=IBM DB2 for z/OS with the 'App' Driver # return text that represents a specific :view / :schema -selectViewSql=select TEXT from SYSIBM.SYSVIEWS where NAME=:view and CREATOR=:schema +selectViewSql=select TEXT view_definition from SYSIBM.SYSVIEWS where NAME=:view and CREATOR=:schema # return table_name, constraint_name and text for a specific :schema selectCheckConstraintsSql=select CHECKNAME constraint_name, TBNAME table_name, CHECKCONDITION from SYSIBM.SYSCHECKS where TBOWNER=:schema diff --git a/src/main/resources/org/schemaspy/types/db2zosnet.properties b/src/main/resources/org/schemaspy/types/db2zosnet.properties index a03f6cb0e..91a09ca37 100644 --- a/src/main/resources/org/schemaspy/types/db2zosnet.properties +++ b/src/main/resources/org/schemaspy/types/db2zosnet.properties @@ -10,7 +10,7 @@ extends=db2net description=IBM DB2/zos with the Type 4 'Net' Driver # return text that represents a specific :view / :schema -selectViewSql=select TEXT from SYSIBM.SYSVIEWS where NAME=:view and CREATOR=:schema +selectViewSql=select TEXT view_definition from SYSIBM.SYSVIEWS where NAME=:view and CREATOR=:schema # return table_name, constraint_name and text for a specific :schema selectCheckConstraintsSql=select CHECKNAME constraint_name, TBNAME table_name, CHECKCONDITION from SYSIBM.SYSCHECKS where TBOWNER=:schema diff --git a/src/main/resources/org/schemaspy/types/h2.properties b/src/main/resources/org/schemaspy/types/h2.properties index ac83723c1..b8fd4545d 100644 --- a/src/main/resources/org/schemaspy/types/h2.properties +++ b/src/main/resources/org/schemaspy/types/h2.properties @@ -12,4 +12,5 @@ driver=org.h2.Driver # Use -dp to override. driverPath=/H2/h2-1.2.147.jar -selectSchemasSql=SELECT REMARKS as schema_comment FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME=:schema AND CATALOG_NAME=:catalog \ No newline at end of file +selectSchemasSql=SELECT REMARKS as schema_comment FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME=:schema AND CATALOG_NAME=:catalog +selectViewSql=SELECT view_definition FROM INFORMATION_SCHEMA.VIEWS where TABLE_SCHEMA = :schema AND TABLE_NAME = :view \ No newline at end of file diff --git a/src/main/resources/org/schemaspy/types/mssql.properties b/src/main/resources/org/schemaspy/types/mssql.properties index 1f74beccd..2c3fa30f2 100644 --- a/src/main/resources/org/schemaspy/types/mssql.properties +++ b/src/main/resources/org/schemaspy/types/mssql.properties @@ -16,7 +16,7 @@ driver=com.microsoft.jdbc.sqlserver.SQLServerDriver driverPath=C:/Program Files/Microsoft SQL Server 2000 Driver for JDBC/lib/msbase.jar;C:/Program Files/Microsoft SQL Server 2000 Driver for JDBC/lib/mssqlserver.jar;C:/Program Files/Microsoft SQL Server 2000 Driver for JDBC/lib/msutil.jar # return text that represents a specific :view / :schema -selectViewSql=select text from syscomments sc, sysobjects so where sc.id=so.id and so.name=:table +selectViewSql=select text AS view_definition from syscomments sc, sysobjects so where sc.id=so.id and so.name=:table # return table_name, column_name, comments for current schema selectColumnCommentsSql=SELECT i_s.TABLE_NAME, i_s.COLUMN_NAME, CAST(s.value AS VARCHAR(MAX)) AS comments FROM INFORMATION_SCHEMA.COLUMNS i_s \ diff --git a/src/main/resources/org/schemaspy/types/netezza.properties b/src/main/resources/org/schemaspy/types/netezza.properties index 884aa7779..ee270f698 100644 --- a/src/main/resources/org/schemaspy/types/netezza.properties +++ b/src/main/resources/org/schemaspy/types/netezza.properties @@ -12,4 +12,4 @@ driver=org.netezza.Driver driverPath=c:/jdbc_drivers/nzjdbc.jar -selectViewSql=select definition as text from _v_view where viewname = :table \ No newline at end of file +selectViewSql=select definition as view_definition from _v_view where viewname = :table \ No newline at end of file diff --git a/src/main/resources/org/schemaspy/types/ora.properties b/src/main/resources/org/schemaspy/types/ora.properties index ccf5af880..c0c99d177 100644 --- a/src/main/resources/org/schemaspy/types/ora.properties +++ b/src/main/resources/org/schemaspy/types/ora.properties @@ -18,7 +18,7 @@ driverPath=c:/Oracle8I/ora81/jdbc/lib/classes12.zip dbThreads=1 # return text that represents a specific :view / :schema -selectViewSql=select text from all_views where view_name=:view and owner=:owner +selectViewSql=select text as view_definition from all_views where view_name=:view and owner=:owner # return table_name, constraint_name and text for a specific :schema selectCheckConstraintsSql=select table_name, constraint_name, search_condition text from all_constraints where constraint_type = 'C' and constraint_name not like 'SYS%' and owner = :owner diff --git a/src/main/resources/org/schemaspy/types/pgsql.properties b/src/main/resources/org/schemaspy/types/pgsql.properties index b1e255807..8ebe034e4 100644 --- a/src/main/resources/org/schemaspy/types/pgsql.properties +++ b/src/main/resources/org/schemaspy/types/pgsql.properties @@ -16,7 +16,7 @@ driver=org.postgresql.Driver driverPath=/org/schemaspy/drivers/postgresql-9.4.1208.jre6.jar # return text that represents a specific :view / :schema -selectViewSql=select definition as text from pg_views where viewname = :table +selectViewSql=select definition as view_definition from pg_views where viewname = :table selectSchemasSql=SELECT nspname AS schema_name, pg_catalog.obj_description(oid, 'pg_namespace') AS schema_comment FROM pg_catalog.pg_namespace where nspname = :schema selectCatalogsSql=SELECT datname AS catalog_name, pg_catalog.obj_description(datlastsysoid, 'pg_database') AS catalog_comment FROM pg_catalog.pg_database WHERE datname = :catalog ; diff --git a/src/main/resources/org/schemaspy/types/redshift.properties b/src/main/resources/org/schemaspy/types/redshift.properties index 6b5cbcae5..c8674179d 100644 --- a/src/main/resources/org/schemaspy/types/redshift.properties +++ b/src/main/resources/org/schemaspy/types/redshift.properties @@ -7,4 +7,4 @@ db=database name driver=com.amazon.redshift.jdbc42.Driver # return text that represents a specific :view / :schema -selectViewSql=select definition as text from pg_views where viewname = :table \ No newline at end of file +selectViewSql=select definition as view_definition from pg_views where viewname = :table \ No newline at end of file diff --git a/src/test/java/org/schemaspy/integrationtesting/H2ViewIT.java b/src/test/java/org/schemaspy/integrationtesting/H2ViewIT.java new file mode 100644 index 000000000..b82a1635e --- /dev/null +++ b/src/test/java/org/schemaspy/integrationtesting/H2ViewIT.java @@ -0,0 +1,92 @@ +package org.schemaspy.integrationtesting; + +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.schemaspy.Config; +import org.schemaspy.cli.CommandLineArguments; +import org.schemaspy.model.Database; +import org.schemaspy.model.ProgressListener; +import org.schemaspy.service.DatabaseService; +import org.schemaspy.service.SqlService; +import org.schemaspy.testing.H2MemoryRule; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.junit4.SpringRunner; + +import java.io.File; +import java.io.IOException; +import java.sql.DatabaseMetaData; +import java.sql.SQLException; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class H2ViewIT { + + @ClassRule + public static H2MemoryRule h2MemoryRule = new H2MemoryRule("h2view").addSqlScript("src/test/resources/integrationTesting/h2ViewIT/dbScripts/2tables1view.sql"); + + @Autowired + private SqlService sqlService; + + @Autowired + private DatabaseService databaseService; + + @Mock + private ProgressListener progressListener; + + @MockBean + private CommandLineArguments arguments; + + @MockBean + private CommandLineRunner commandLineRunner; + + private static Database database; + + @Before + public synchronized void createDatabaseRepresentation() throws SQLException, IOException { + if (database == null) { + doCreateDatabaseRepresentation(); + } + } + + private void doCreateDatabaseRepresentation() throws SQLException, IOException { + String[] args = { + "-t", "src/test/resources/integrationTesting/dbTypes/h2memory", + "-db", "h2view", + "-s", "h2view", + "-o", "target/integrationtesting/h2view", + "-u", "sa" + }; + given(arguments.getOutputDirectory()).willReturn(new File("target/integrationtesting/h2view")); + given(arguments.getDatabaseType()).willReturn("src/test/resources/integrationTesting/dbTypes/h2memory"); + given(arguments.getUser()).willReturn("sa"); + given(arguments.getCatalog()).willReturn(h2MemoryRule.getConnection().getCatalog()); + given(arguments.getSchema()).willReturn(h2MemoryRule.getConnection().getSchema()); + given(arguments.getDatabaseName()).willReturn("h2view"); + Config config = new Config(args); + DatabaseMetaData databaseMetaData = sqlService.connect(config); + Database database = new Database(config, databaseMetaData, arguments.getDatabaseName(), arguments.getCatalog(), arguments.getSchema(), null, progressListener); + databaseService.gatheringSchemaDetails(config, database, progressListener); + this.database = database; + } + + @Test + public void databaseShouldExist() { + assertThat(database).isNotNull(); + assertThat(database.getName()).isEqualToIgnoringCase("h2view"); + } + + @Test + public void viewShouldExist() { + assertThat(database.getViews()).extracting(v -> v.getName()).contains("THE_VIEW"); + assertThat(database.getViewsMap().get("THE_VIEW").getViewDefinition()).isNotBlank(); + } +} diff --git a/src/test/resources/integrationTesting/h2ViewIT/dbScripts/2tables1view.sql b/src/test/resources/integrationTesting/h2ViewIT/dbScripts/2tables1view.sql new file mode 100644 index 000000000..01b716205 --- /dev/null +++ b/src/test/resources/integrationTesting/h2ViewIT/dbScripts/2tables1view.sql @@ -0,0 +1,11 @@ +CREATE SCHEMA "h2view" AUTHORIZATION SA; +SET SCHEMA "h2view"; +CREATE TABLE "TABLE1"( + Id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + NAME VARCHAR(255) +); +CREATE TABLE "TABLE2"( + Id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + NAME VARCHAR(255) +); +CREATE VIEW THE_VIEW (NAMES) AS SELECT NAME FROM TABLE1 UNION SELECT NAME FROM TABLE2; \ No newline at end of file