From 720a3595ff47aa3ac28278bd7bc24042cba6d098 Mon Sep 17 00:00:00 2001 From: Jean Bisutti Date: Tue, 17 Mar 2026 16:19:23 +0100 Subject: [PATCH 1/2] Add spotless --- pom.xml | 32 + src/main/java/org/qstd/ColumnMappingPart.java | 23 +- .../java/org/qstd/ColumnNamesComparator.java | 43 +- .../java/org/qstd/ColumnNamesExtractor.java | 82 +- .../java/org/qstd/ColumnOrdersFinder.java | 3 +- .../java/org/qstd/ColumnValueFormatter.java | 155 +-- src/main/java/org/qstd/ColumnsMapping.java | 26 +- .../java/org/qstd/ColumnsMappingGroup.java | 25 +- .../java/org/qstd/ColumnsMappingsFinder.java | 3 +- .../java/org/qstd/DatabaseMetadataFinder.java | 21 +- src/main/java/org/qstd/DatasetRow.java | 265 ++-- .../org/qstd/DatasetRowComparatorBuilder.java | 155 ++- src/main/java/org/qstd/DatasetRowSet.java | 119 +- src/main/java/org/qstd/DatasetRowsFinder.java | 150 +-- .../java/org/qstd/DatasetRowsGenerator.java | 43 +- .../org/qstd/DeleteToSelectTransformer.java | 49 +- .../org/qstd/InsertStatementsGenerator.java | 78 +- .../org/qstd/MissingNotNullColumnsFinder.java | 53 +- .../java/org/qstd/NotNullColumnsFinder.java | 3 +- .../org/qstd/PreparedStatementBuilder.java | 21 +- .../org/qstd/PrimaryKeyColumnsFinder.java | 3 +- src/main/java/org/qstd/QuickSqlTestData.java | 251 ++-- src/main/java/org/qstd/ReferencedTable.java | 23 +- .../java/org/qstd/ReferencedTableSet.java | 29 +- .../java/org/qstd/ReferencedTablesFinder.java | 3 +- src/main/java/org/qstd/RowFinder.java | 64 +- src/main/java/org/qstd/SelectTransformer.java | 10 +- .../org/qstd/SelectTransformerFactory.java | 68 +- src/main/java/org/qstd/SqlQuery.java | 145 ++- .../org/qstd/UpdateToSelectTransformer.java | 90 +- .../qstd/dbtype/BaseColumnOrdersFinder.java | 67 +- .../dbtype/BaseColumnsMappingsFinder.java | 78 +- .../qstd/dbtype/BaseNotNullColumnsFinder.java | 67 +- .../dbtype/BasePrimaryKeyColumnsFinder.java | 54 +- .../dbtype/BaseReferencedTablesFinder.java | 65 +- .../dbtype/DatabaseMetadataFinderFactory.java | 67 +- .../DatabaseMetadataFinderWithCache.java | 120 +- .../java/org/qstd/dbtype/DatabaseType.java | 81 +- .../org/qstd/dbtype/DatabaseUrlFinder.java | 34 +- .../dbtype/DefaultColumnOrdersFinder.java | 45 +- .../dbtype/DefaultDatabaseMetadataFinder.java | 59 +- .../dbtype/DefaultNotNullColumnsFinder.java | 43 +- .../DefaultPrimaryKeyColumnsFinder.java | 57 +- .../org/qstd/dbtype/H2MetadataFinder.java | 193 +-- .../org/qstd/dbtype/HsqlDbMetadataFinder.java | 221 ++-- .../dbtype/MSSQLServerMetadataFinder.java | 218 ++-- .../dbtype/MariaDBMySQLMetadataFinder.java | 131 +- .../org/qstd/dbtype/OracleMetadataFinder.java | 256 ++-- ...stgreSqlMariaDbReferencedTablesFinder.java | 83 +- .../qstd/dbtype/PostgreSqlMetadataFinder.java | 122 +- .../java/org/qstd/test/DataSourceBuilder.java | 20 +- .../java/org/qstd/test/DatasetRowApiTest.java | 72 +- .../org/qstd/test/DatasetRowsMergingTest.java | 220 ++-- src/test/java/org/qstd/test/DeleteTest.java | 116 +- .../java/org/qstd/test/FastTestSuite.java | 29 +- src/test/java/org/qstd/test/H2Config.java | 24 +- .../java/org/qstd/test/H2DateTypesTest.java | 248 ++-- src/test/java/org/qstd/test/H2Test.java | 599 ++++----- src/test/java/org/qstd/test/HsqlDbTest.java | 917 +++++++------ src/test/java/org/qstd/test/InsertTest.java | 34 +- .../java/org/qstd/test/JdbcRoundtripTest.java | 159 ++- .../java/org/qstd/test/MSSQLServerTest.java | 917 +++++++------ .../java/org/qstd/test/MariaDBSlowTest.java | 160 +-- src/test/java/org/qstd/test/MariaDBTest.java | 742 ++++++----- .../test/NotFullyManagedDatabaseTest.java | 72 +- src/test/java/org/qstd/test/OracleTest.java | 1136 ++++++++--------- .../java/org/qstd/test/PostgreSqlTest.java | 914 +++++++------ src/test/java/org/qstd/test/SelectTest.java | 134 +- .../qstd/test/SortInsertStatementsTest.java | 169 ++- .../test/SortInsertStatementsWithPkTest.java | 333 ++--- src/test/java/org/qstd/test/SqlExecutor.java | 33 +- src/test/java/org/qstd/test/TestTable.java | 172 ++- src/test/java/org/qstd/test/UpdateTest.java | 297 +++-- 73 files changed, 5723 insertions(+), 5890 deletions(-) diff --git a/pom.xml b/pom.xml index f993295..e660fb3 100644 --- a/pom.xml +++ b/pom.xml @@ -297,6 +297,38 @@ + + spotless + + + [17,) + + + + + com.diffplug.spotless + spotless-maven-plugin + 2.44.3 + + + + 1.25.2 + + + + + + + check + + verify + + + + + + release diff --git a/src/main/java/org/qstd/ColumnMappingPart.java b/src/main/java/org/qstd/ColumnMappingPart.java index b3a5b6d..1bfc191 100644 --- a/src/main/java/org/qstd/ColumnMappingPart.java +++ b/src/main/java/org/qstd/ColumnMappingPart.java @@ -14,18 +14,17 @@ public class ColumnMappingPart { - final String tableName; - final String tableColumn; - private final String tableSchema; + final String tableName; + final String tableColumn; + private final String tableSchema; - public ColumnMappingPart(String tableSchema, String tableName, String tableColumn) { - this.tableSchema = tableSchema; - this.tableName = tableName; - this.tableColumn = tableColumn; - } - - boolean hasColumn(String columnName) { - return tableColumn.equals(columnName); - } + public ColumnMappingPart(String tableSchema, String tableName, String tableColumn) { + this.tableSchema = tableSchema; + this.tableName = tableName; + this.tableColumn = tableColumn; + } + boolean hasColumn(String columnName) { + return tableColumn.equals(columnName); + } } diff --git a/src/main/java/org/qstd/ColumnNamesComparator.java b/src/main/java/org/qstd/ColumnNamesComparator.java index f930a6e..2034008 100644 --- a/src/main/java/org/qstd/ColumnNamesComparator.java +++ b/src/main/java/org/qstd/ColumnNamesComparator.java @@ -19,32 +19,31 @@ class ColumnNamesComparator implements Comparator { - private final Map positionByColumnName; + private final Map positionByColumnName; - private ColumnNamesComparator(Map positionByColumnName) { - this.positionByColumnName = positionByColumnName; - } + private ColumnNamesComparator(Map positionByColumnName) { + this.positionByColumnName = positionByColumnName; + } - public static ColumnNamesComparator from(List orderedColumns) { - Map positionByColumnName = buildIndexByColumnName(orderedColumns); - return new ColumnNamesComparator(positionByColumnName); - } + public static ColumnNamesComparator from(List orderedColumns) { + Map positionByColumnName = buildIndexByColumnName(orderedColumns); + return new ColumnNamesComparator(positionByColumnName); + } - private static Map buildIndexByColumnName(List orderedColumns) { - final Map positionByColumnName = new HashMap<>(); - for (int i = 0; i < orderedColumns.size(); i++) { - positionByColumnName.put(orderedColumns.get(i), i + 1); - } - return positionByColumnName; + private static Map buildIndexByColumnName(List orderedColumns) { + final Map positionByColumnName = new HashMap<>(); + for (int i = 0; i < orderedColumns.size(); i++) { + positionByColumnName.put(orderedColumns.get(i), i + 1); } + return positionByColumnName; + } - @Override - public int compare(String colName1, String colName2) { - return findPositionOf(colName1) - findPositionOf(colName2); - } - - private int findPositionOf(String colName1) { - return positionByColumnName.get(colName1); - } + @Override + public int compare(String colName1, String colName2) { + return findPositionOf(colName1) - findPositionOf(colName2); + } + private int findPositionOf(String colName1) { + return positionByColumnName.get(colName1); + } } diff --git a/src/main/java/org/qstd/ColumnNamesExtractor.java b/src/main/java/org/qstd/ColumnNamesExtractor.java index 6d1db2d..886c816 100644 --- a/src/main/java/org/qstd/ColumnNamesExtractor.java +++ b/src/main/java/org/qstd/ColumnNamesExtractor.java @@ -12,64 +12,60 @@ */ package org.qstd; -import net.sf.jsqlparser.expression.BinaryExpression; -import net.sf.jsqlparser.expression.Expression; -import net.sf.jsqlparser.expression.ExpressionVisitorAdapter; -import net.sf.jsqlparser.schema.Column; - import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Set; +import net.sf.jsqlparser.expression.BinaryExpression; +import net.sf.jsqlparser.expression.Expression; +import net.sf.jsqlparser.expression.ExpressionVisitorAdapter; +import net.sf.jsqlparser.schema.Column; class ColumnNamesExtractor { - static final ColumnNamesExtractor INSTANCE = new ColumnNamesExtractor(); - - private ColumnNamesExtractor() { - } - - private static class ColumnExpressionVisitor extends ExpressionVisitorAdapter { + static final ColumnNamesExtractor INSTANCE = new ColumnNamesExtractor(); - private String visitedColumnName; + private ColumnNamesExtractor() {} - @Override - public void visit(Column column) { - this.visitedColumnName = column.getColumnName(); - } + private static class ColumnExpressionVisitor extends ExpressionVisitorAdapter { - String getVisitedColumnName() { - return visitedColumnName; - } + private String visitedColumnName; + @Override + public void visit(Column column) { + this.visitedColumnName = column.getColumnName(); } - Set findColumnNamesOf(Expression expression) { - Set columnNames = new HashSet<>(); - if (expression instanceof BinaryExpression) { - // AndExpression, OrExpression, LikeExpression, ... - BinaryExpression binaryExpression = (BinaryExpression) expression; - Collection leftRightColumnNames = extractColumnNamesOf(binaryExpression); - columnNames.addAll(leftRightColumnNames); - } else if (expression != null) { - // Column names - ColumnExpressionVisitor columnExpressionVisitor = new ColumnExpressionVisitor(); - expression.accept(columnExpressionVisitor); - String visitedColumnName = columnExpressionVisitor.getVisitedColumnName(); - if(visitedColumnName != null) { - columnNames.add(visitedColumnName); - } - } - return columnNames; + String getVisitedColumnName() { + return visitedColumnName; } + } - private Collection extractColumnNamesOf(BinaryExpression binaryExpression) { - Collection leftRightColumnNames = new ArrayList<>(); - Collection leftColumnNames = findColumnNamesOf(binaryExpression.getLeftExpression()); - Collection rightColumnNames = findColumnNamesOf(binaryExpression.getRightExpression()); - leftRightColumnNames.addAll(leftColumnNames); - leftRightColumnNames.addAll(rightColumnNames); - return leftRightColumnNames; + Set findColumnNamesOf(Expression expression) { + Set columnNames = new HashSet<>(); + if (expression instanceof BinaryExpression) { + // AndExpression, OrExpression, LikeExpression, ... + BinaryExpression binaryExpression = (BinaryExpression) expression; + Collection leftRightColumnNames = extractColumnNamesOf(binaryExpression); + columnNames.addAll(leftRightColumnNames); + } else if (expression != null) { + // Column names + ColumnExpressionVisitor columnExpressionVisitor = new ColumnExpressionVisitor(); + expression.accept(columnExpressionVisitor); + String visitedColumnName = columnExpressionVisitor.getVisitedColumnName(); + if (visitedColumnName != null) { + columnNames.add(visitedColumnName); + } } + return columnNames; + } + private Collection extractColumnNamesOf(BinaryExpression binaryExpression) { + Collection leftRightColumnNames = new ArrayList<>(); + Collection leftColumnNames = findColumnNamesOf(binaryExpression.getLeftExpression()); + Collection rightColumnNames = findColumnNamesOf(binaryExpression.getRightExpression()); + leftRightColumnNames.addAll(leftColumnNames); + leftRightColumnNames.addAll(rightColumnNames); + return leftRightColumnNames; + } } diff --git a/src/main/java/org/qstd/ColumnOrdersFinder.java b/src/main/java/org/qstd/ColumnOrdersFinder.java index a0ce02a..ff8a6e0 100644 --- a/src/main/java/org/qstd/ColumnOrdersFinder.java +++ b/src/main/java/org/qstd/ColumnOrdersFinder.java @@ -16,6 +16,5 @@ public interface ColumnOrdersFinder { - List findDatabaseColumnOrdersOf(String tableName); - + List findDatabaseColumnOrdersOf(String tableName); } diff --git a/src/main/java/org/qstd/ColumnValueFormatter.java b/src/main/java/org/qstd/ColumnValueFormatter.java index b4d6a05..871128f 100644 --- a/src/main/java/org/qstd/ColumnValueFormatter.java +++ b/src/main/java/org/qstd/ColumnValueFormatter.java @@ -12,99 +12,104 @@ */ package org.qstd; -import java.time.OffsetDateTime; -import java.time.format.DateTimeFormatter; -import java.time.format.DateTimeFormatterBuilder; -import org.qstd.dbtype.DatabaseType; - import java.sql.Time; import java.sql.Timestamp; +import java.time.OffsetDateTime; import java.time.OffsetTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeFormatterBuilder; import java.util.Calendar; +import org.qstd.dbtype.DatabaseType; class ColumnValueFormatter { - static final ColumnValueFormatter INSTANCE = new ColumnValueFormatter(); + static final ColumnValueFormatter INSTANCE = new ColumnValueFormatter(); - private ColumnValueFormatter() { } + private ColumnValueFormatter() {} - String formatColumnValue(Object columnValue, DatabaseType dbType) { - if(columnValue == null) { - return "NULL"; - } else if(DatabaseType.ORACLE.equals(dbType) - && columnValue instanceof Timestamp) { - Timestamp timeStamp = (Timestamp) columnValue; - return buildOracleToDateFunctionFor(timeStamp); - } else if(DatabaseType.ORACLE.equals(dbType) - && isOracleSqlTimestamp(columnValue)) { - return buildOracleToTimeStampFunctionFor(columnValue); - }else if(DatabaseType.HSQLDB.equals(dbType) - && columnValue instanceof OffsetDateTime){ - OffsetDateTime offsetDateTime = (OffsetDateTime) columnValue; - return formatForHsqlDBOffsetDateTime(offsetDateTime); - } else if (columnValue instanceof String - || columnValue instanceof java.sql.Date - || columnValue instanceof Timestamp - || columnValue instanceof Time - || columnValue instanceof OffsetTime - || isTimestampWithTimeZoneH2Type(columnValue) - || isMicrosoftDateTimeOffset(columnValue)) { - String stringColumnValue = columnValue.toString(); - return "'" + stringColumnValue + "'"; - } - return columnValue.toString(); + String formatColumnValue(Object columnValue, DatabaseType dbType) { + if (columnValue == null) { + return "NULL"; + } else if (DatabaseType.ORACLE.equals(dbType) && columnValue instanceof Timestamp) { + Timestamp timeStamp = (Timestamp) columnValue; + return buildOracleToDateFunctionFor(timeStamp); + } else if (DatabaseType.ORACLE.equals(dbType) && isOracleSqlTimestamp(columnValue)) { + return buildOracleToTimeStampFunctionFor(columnValue); + } else if (DatabaseType.HSQLDB.equals(dbType) && columnValue instanceof OffsetDateTime) { + OffsetDateTime offsetDateTime = (OffsetDateTime) columnValue; + return formatForHsqlDBOffsetDateTime(offsetDateTime); + } else if (columnValue instanceof String + || columnValue instanceof java.sql.Date + || columnValue instanceof Timestamp + || columnValue instanceof Time + || columnValue instanceof OffsetTime + || isTimestampWithTimeZoneH2Type(columnValue) + || isMicrosoftDateTimeOffset(columnValue)) { + String stringColumnValue = columnValue.toString(); + return "'" + stringColumnValue + "'"; } + return columnValue.toString(); + } - private boolean isMicrosoftDateTimeOffset(Object columnValue) { - Class columnValueClass = columnValue.getClass(); - String classCanonicalName = columnValueClass.getCanonicalName(); - return "microsoft.sql.DateTimeOffset".equals(classCanonicalName); - } + private boolean isMicrosoftDateTimeOffset(Object columnValue) { + Class columnValueClass = columnValue.getClass(); + String classCanonicalName = columnValueClass.getCanonicalName(); + return "microsoft.sql.DateTimeOffset".equals(classCanonicalName); + } - private String formatForHsqlDBOffsetDateTime(OffsetDateTime offsetDateTime) { - DateTimeFormatter fmt = new DateTimeFormatterBuilder() + private String formatForHsqlDBOffsetDateTime(OffsetDateTime offsetDateTime) { + DateTimeFormatter fmt = + new DateTimeFormatterBuilder() .appendPattern("yyyy-MM-dd HH:mm:ss") .parseLenient() .appendOffset("+HH:MM", "Z") .toFormatter(); - return "'" + fmt.format(offsetDateTime) + "'"; - } - - private String buildOracleToDateFunctionFor(Timestamp timeStamp) { - //https://stackoverflow.com/questions/9180014/using-oracle-to-date-function-for-date-string-with-milliseconds - // "An Oracle DATE does not store times with more precision than a second." - Calendar calendar = Calendar.getInstance(); - calendar.setTime(timeStamp); - int monthNumber = calendar.get(Calendar.MONTH) + 1; - int secondNumber = calendar.get(Calendar.SECOND); - String toDateString = calendar.get(Calendar.YEAR) - + "-" + (monthNumber < 10 ? "0" : "") + monthNumber - + "-" + calendar.get(Calendar.DAY_OF_MONTH) - + "-" + calendar.get(Calendar.HOUR_OF_DAY) - + "-" + calendar.get(Calendar.MINUTE) - + "-" + (secondNumber < 10 ? "0" : "") + secondNumber; - return "TO_DATE('" + toDateString + "', 'yyyy-mm-dd-HH24-mi-ss')"; - } + return "'" + fmt.format(offsetDateTime) + "'"; + } - private boolean isOracleSqlTimestamp(Object columnValue) { - Class columnValueClass = columnValue.getClass(); - String classCanonicalName = columnValueClass.getCanonicalName(); - return classCanonicalName.equals("oracle.sql.TIMESTAMP"); - } + private String buildOracleToDateFunctionFor(Timestamp timeStamp) { + // https://stackoverflow.com/questions/9180014/using-oracle-to-date-function-for-date-string-with-milliseconds + // "An Oracle DATE does not store times with more precision than a second." + Calendar calendar = Calendar.getInstance(); + calendar.setTime(timeStamp); + int monthNumber = calendar.get(Calendar.MONTH) + 1; + int secondNumber = calendar.get(Calendar.SECOND); + String toDateString = + calendar.get(Calendar.YEAR) + + "-" + + (monthNumber < 10 ? "0" : "") + + monthNumber + + "-" + + calendar.get(Calendar.DAY_OF_MONTH) + + "-" + + calendar.get(Calendar.HOUR_OF_DAY) + + "-" + + calendar.get(Calendar.MINUTE) + + "-" + + (secondNumber < 10 ? "0" : "") + + secondNumber; + return "TO_DATE('" + toDateString + "', 'yyyy-mm-dd-HH24-mi-ss')"; + } - private String buildOracleToTimeStampFunctionFor(Object columnValue) { - String oracleTimeStampAsString = columnValue.toString(); - String aDateWithMsLessThan100 = "2012-09-17 19:56:47.10"; - boolean dateHasMsLessThan100 = oracleTimeStampAsString.length() == aDateWithMsLessThan100.length(); - String dateForTimeStampCreation = dateHasMsLessThan100 ? oracleTimeStampAsString + "0" : oracleTimeStampAsString; - return "TO_TIMESTAMP('" + dateForTimeStampCreation - + "', 'YYYY-MM-DD HH24:MI:SS.FF')"; - } + private boolean isOracleSqlTimestamp(Object columnValue) { + Class columnValueClass = columnValue.getClass(); + String classCanonicalName = columnValueClass.getCanonicalName(); + return classCanonicalName.equals("oracle.sql.TIMESTAMP"); + } - private boolean isTimestampWithTimeZoneH2Type(Object columnValue) { - Class columnValueClass = columnValue.getClass(); - String classCanonicalName = columnValueClass.getCanonicalName(); - return classCanonicalName.equals("org.h2.api.TimestampWithTimeZone"); - } + private String buildOracleToTimeStampFunctionFor(Object columnValue) { + String oracleTimeStampAsString = columnValue.toString(); + String aDateWithMsLessThan100 = "2012-09-17 19:56:47.10"; + boolean dateHasMsLessThan100 = + oracleTimeStampAsString.length() == aDateWithMsLessThan100.length(); + String dateForTimeStampCreation = + dateHasMsLessThan100 ? oracleTimeStampAsString + "0" : oracleTimeStampAsString; + return "TO_TIMESTAMP('" + dateForTimeStampCreation + "', 'YYYY-MM-DD HH24:MI:SS.FF')"; + } + private boolean isTimestampWithTimeZoneH2Type(Object columnValue) { + Class columnValueClass = columnValue.getClass(); + String classCanonicalName = columnValueClass.getCanonicalName(); + return classCanonicalName.equals("org.h2.api.TimestampWithTimeZone"); + } } diff --git a/src/main/java/org/qstd/ColumnsMapping.java b/src/main/java/org/qstd/ColumnsMapping.java index 3eee748..24d4278 100644 --- a/src/main/java/org/qstd/ColumnsMapping.java +++ b/src/main/java/org/qstd/ColumnsMapping.java @@ -14,21 +14,21 @@ public class ColumnsMapping { - private final ColumnMappingPart columnMappingPart1; + private final ColumnMappingPart columnMappingPart1; - private final ColumnMappingPart columnMappingPart2; + private final ColumnMappingPart columnMappingPart2; - public ColumnsMapping(ColumnMappingPart columnMappingPart1, ColumnMappingPart columnMappingPart2) { - this.columnMappingPart1 = columnMappingPart1; - this.columnMappingPart2 = columnMappingPart2; - } + public ColumnsMapping( + ColumnMappingPart columnMappingPart1, ColumnMappingPart columnMappingPart2) { + this.columnMappingPart1 = columnMappingPart1; + this.columnMappingPart2 = columnMappingPart2; + } - boolean hasMappingForColumn(String columnName) { - return columnMappingPart1.hasColumn(columnName); - } - - ColumnMappingPart getMapping() { - return columnMappingPart2; - } + boolean hasMappingForColumn(String columnName) { + return columnMappingPart1.hasColumn(columnName); + } + ColumnMappingPart getMapping() { + return columnMappingPart2; + } } diff --git a/src/main/java/org/qstd/ColumnsMappingGroup.java b/src/main/java/org/qstd/ColumnsMappingGroup.java index a982cb2..47dff98 100644 --- a/src/main/java/org/qstd/ColumnsMappingGroup.java +++ b/src/main/java/org/qstd/ColumnsMappingGroup.java @@ -19,20 +19,19 @@ public class ColumnsMappingGroup { - public static final ColumnsMappingGroup NO_MAPPING = new ColumnsMappingGroup(Collections.emptyList()); + public static final ColumnsMappingGroup NO_MAPPING = + new ColumnsMappingGroup(Collections.emptyList()); - private final Collection columnsMappings; + private final Collection columnsMappings; - public ColumnsMappingGroup(Collection columnsMappings) { - this.columnsMappings = new ArrayList<>(columnsMappings); - } - - Optional findMappingForColumn(String columnName) { - return columnsMappings - .stream() - .filter(columnsMapping -> columnsMapping.hasMappingForColumn(columnName)) - .map(ColumnsMapping::getMapping) - .findFirst(); - } + public ColumnsMappingGroup(Collection columnsMappings) { + this.columnsMappings = new ArrayList<>(columnsMappings); + } + Optional findMappingForColumn(String columnName) { + return columnsMappings.stream() + .filter(columnsMapping -> columnsMapping.hasMappingForColumn(columnName)) + .map(ColumnsMapping::getMapping) + .findFirst(); + } } diff --git a/src/main/java/org/qstd/ColumnsMappingsFinder.java b/src/main/java/org/qstd/ColumnsMappingsFinder.java index 7bbe37c..f72855a 100644 --- a/src/main/java/org/qstd/ColumnsMappingsFinder.java +++ b/src/main/java/org/qstd/ColumnsMappingsFinder.java @@ -14,6 +14,5 @@ public interface ColumnsMappingsFinder { - ColumnsMappingGroup findColumnsMappingsOf(String tableName); - + ColumnsMappingGroup findColumnsMappingsOf(String tableName); } diff --git a/src/main/java/org/qstd/DatabaseMetadataFinder.java b/src/main/java/org/qstd/DatabaseMetadataFinder.java index b55af76..fc98a4a 100644 --- a/src/main/java/org/qstd/DatabaseMetadataFinder.java +++ b/src/main/java/org/qstd/DatabaseMetadataFinder.java @@ -12,25 +12,24 @@ */ package org.qstd; +import java.util.function.Function; import org.qstd.dbtype.DatabaseMetadataFinderFactory; import org.qstd.dbtype.DatabaseMetadataFinderWithCache; -import java.util.function.Function; - /** * Interface describing the methods needed by the library to retrieve some database metadata. * * @see DatabaseMetadataFinderFactory * @see DatabaseMetadataFinderWithCache */ -public interface DatabaseMetadataFinder extends NotNullColumnsFinder - , ColumnOrdersFinder - , ReferencedTablesFinder - , ColumnsMappingsFinder - , PrimaryKeyColumnsFinder { - - default Function getFunctionToHaveMetadataTableName() { - return tableName -> tableName; - } +public interface DatabaseMetadataFinder + extends NotNullColumnsFinder, + ColumnOrdersFinder, + ReferencedTablesFinder, + ColumnsMappingsFinder, + PrimaryKeyColumnsFinder { + default Function getFunctionToHaveMetadataTableName() { + return tableName -> tableName; + } } diff --git a/src/main/java/org/qstd/DatasetRow.java b/src/main/java/org/qstd/DatasetRow.java index 494e68c..8d501e4 100644 --- a/src/main/java/org/qstd/DatasetRow.java +++ b/src/main/java/org/qstd/DatasetRow.java @@ -12,149 +12,148 @@ */ package org.qstd; +import static java.util.stream.Collectors.toList; + import java.util.*; import java.util.function.Function; import java.util.stream.Stream; -import static java.util.stream.Collectors.toList; - public class DatasetRow { - private String tableName; - - private TreeMap columnValueByColumnName = new TreeMap<>(); - - private DatasetRow(String tableName) { - this.tableName = tableName; - } - - public static DatasetRow ofTable(String tableName) { - return new DatasetRow(tableName); - } - - protected void addColumnValues(Map columnValues) { - columnValueByColumnName.putAll(columnValues); - } - - Set getColumnNames() { - return columnValueByColumnName.keySet(); - } - - Collection getColumnValues() { - return columnValueByColumnName.values(); - } - - Map getColumnValueByColumnName() { - return new HashMap<>(columnValueByColumnName); - } - - boolean hasNotNullValueForColumn(String columnName) { - return columnValueByColumnName.get(columnName) != null; - } - - void sortColumnsFollowing(List databaseColumnOrders) { - if (!databaseColumnOrders.isEmpty()) { - ColumnNamesComparator columnNamesComparator = ColumnNamesComparator.from(databaseColumnOrders); - TreeMap columnValueByColumnName = new TreeMap<>(columnNamesComparator); - columnValueByColumnName.putAll(this.columnValueByColumnName); - this.columnValueByColumnName = columnValueByColumnName; - } - } - - boolean mergeWithARowOf(Collection datasetRows) { - Optional optionalRowToMergeWith = searchARowToMergeIn(datasetRows); - if(optionalRowToMergeWith.isPresent()) { - DatasetRow rowToMergeWith = optionalRowToMergeWith.get(); - rowToMergeWith.addValuesOf(this); - return true; + private String tableName; + + private TreeMap columnValueByColumnName = new TreeMap<>(); + + private DatasetRow(String tableName) { + this.tableName = tableName; + } + + public static DatasetRow ofTable(String tableName) { + return new DatasetRow(tableName); + } + + protected void addColumnValues(Map columnValues) { + columnValueByColumnName.putAll(columnValues); + } + + Set getColumnNames() { + return columnValueByColumnName.keySet(); + } + + Collection getColumnValues() { + return columnValueByColumnName.values(); + } + + Map getColumnValueByColumnName() { + return new HashMap<>(columnValueByColumnName); + } + + boolean hasNotNullValueForColumn(String columnName) { + return columnValueByColumnName.get(columnName) != null; + } + + void sortColumnsFollowing(List databaseColumnOrders) { + if (!databaseColumnOrders.isEmpty()) { + ColumnNamesComparator columnNamesComparator = + ColumnNamesComparator.from(databaseColumnOrders); + TreeMap columnValueByColumnName = new TreeMap<>(columnNamesComparator); + columnValueByColumnName.putAll(this.columnValueByColumnName); + this.columnValueByColumnName = columnValueByColumnName; + } + } + + boolean mergeWithARowOf(Collection datasetRows) { + Optional optionalRowToMergeWith = searchARowToMergeIn(datasetRows); + if (optionalRowToMergeWith.isPresent()) { + DatasetRow rowToMergeWith = optionalRowToMergeWith.get(); + rowToMergeWith.addValuesOf(this); + return true; + } + return false; + } + + private Optional searchARowToMergeIn(Collection datasetRows) { + return datasetRows.stream().filter(this::isMergeableWith).findFirst(); + } + + void addValuesOf(DatasetRow datasetRow) { + TreeMap columnValueByColumnName = datasetRow.columnValueByColumnName; + for (Map.Entry columnValueOfColumnName : columnValueByColumnName.entrySet()) { + Object value = columnValueOfColumnName.getValue(); + if (value != null) { + String columnName = columnValueOfColumnName.getKey(); + this.columnValueByColumnName.put(columnName, value); + } + } + } + + boolean isMergeableWith(DatasetRow otherDatasetRow) { + if (!this.tableName.equals(otherDatasetRow.getTableName())) { + return false; + } + return sameNotNullColumns(otherDatasetRow); + } + + String getTableName() { + return tableName; + } + + private boolean sameNotNullColumns(DatasetRow otherDatasetRow) { + TreeMap columnValueByColumnName = otherDatasetRow.columnValueByColumnName; + for (Map.Entry columnValueOfColumnName : columnValueByColumnName.entrySet()) { + Object mergeableValue = columnValueOfColumnName.getValue(); + if (mergeableValue != null) { + String column = columnValueOfColumnName.getKey(); + Object value = this.columnValueByColumnName.get(column); + if (!mergeableValue.equals(value) && value != null) { + return false; } - return false; - } - - private Optional searchARowToMergeIn(Collection datasetRows) { - return datasetRows - .stream() - .filter(this::isMergeableWith) - .findFirst(); - } - - void addValuesOf(DatasetRow datasetRow) { - TreeMap columnValueByColumnName = datasetRow.columnValueByColumnName; - for (Map.Entry columnValueOfColumnName : columnValueByColumnName.entrySet()) { - Object value = columnValueOfColumnName.getValue(); - if(value != null) { - String columnName = columnValueOfColumnName.getKey(); - this.columnValueByColumnName.put(columnName, value); - } - } - } - - boolean isMergeableWith(DatasetRow otherDatasetRow) { - if(!this.tableName.equals(otherDatasetRow.getTableName())) { - return false; - } - return sameNotNullColumns(otherDatasetRow); - } - - String getTableName() { - return tableName; - } - - private boolean sameNotNullColumns(DatasetRow otherDatasetRow) { - TreeMap columnValueByColumnName = otherDatasetRow.columnValueByColumnName; - for (Map.Entry columnValueOfColumnName : columnValueByColumnName.entrySet()) { - Object mergeableValue = columnValueOfColumnName.getValue(); - if(mergeableValue != null) { - String column = columnValueOfColumnName.getKey(); - Object value = this.columnValueByColumnName.get(column); - if(!mergeableValue.equals(value) && value != null) { - return false; - } - } - } - - return true; - } - - Collection extractJoinedRowsFrom(ColumnsMappingGroup columnsMappingGroup) { - return columnValueByColumnName - .entrySet() - .stream() - .map(valueForColumn -> { - String column = valueForColumn.getKey(); - Optional optionalMappingForColumn = - columnsMappingGroup.findMappingForColumn(column); - return buildOptionalRowFrom(valueForColumn, optionalMappingForColumn); - }) - .flatMap(DatasetRow::streamOf) - .collect(toList()); - } - - private Optional buildOptionalRowFrom(Map.Entry valueForColumn, Optional optionalMappingForColumn) { - return optionalMappingForColumn.map(columnMappingPart -> { - Object value = valueForColumn.getValue(); - DatasetRow joinedRow = new DatasetRow(columnMappingPart.tableName); - joinedRow.addColumnValue(columnMappingPart.tableColumn, value); - return joinedRow; + } + } + + return true; + } + + Collection extractJoinedRowsFrom(ColumnsMappingGroup columnsMappingGroup) { + return columnValueByColumnName.entrySet().stream() + .map( + valueForColumn -> { + String column = valueForColumn.getKey(); + Optional optionalMappingForColumn = + columnsMappingGroup.findMappingForColumn(column); + return buildOptionalRowFrom(valueForColumn, optionalMappingForColumn); + }) + .flatMap(DatasetRow::streamOf) + .collect(toList()); + } + + private Optional buildOptionalRowFrom( + Map.Entry valueForColumn, + Optional optionalMappingForColumn) { + return optionalMappingForColumn.map( + columnMappingPart -> { + Object value = valueForColumn.getValue(); + DatasetRow joinedRow = new DatasetRow(columnMappingPart.tableName); + joinedRow.addColumnValue(columnMappingPart.tableColumn, value); + return joinedRow; }); - } + } - private static Stream streamOf(Optional optional) { - return optional.map(Stream::of).orElseGet(Stream::empty); - } + private static Stream streamOf(Optional optional) { + return optional.map(Stream::of).orElseGet(Stream::empty); + } - public DatasetRow addColumnValue(String columnName, Object value) { - columnValueByColumnName.put(columnName, value); - return this; - } + public DatasetRow addColumnValue(String columnName, Object value) { + columnValueByColumnName.put(columnName, value); + return this; + } - Object getValueOf(String columnName) { - return columnValueByColumnName.get(columnName); - } - - void updateTableNameWith(Function tableNameFunction) { - String newTableName = tableNameFunction.apply(tableName); - tableName = newTableName; - } + Object getValueOf(String columnName) { + return columnValueByColumnName.get(columnName); + } + void updateTableNameWith(Function tableNameFunction) { + String newTableName = tableNameFunction.apply(tableName); + tableName = newTableName; + } } diff --git a/src/main/java/org/qstd/DatasetRowComparatorBuilder.java b/src/main/java/org/qstd/DatasetRowComparatorBuilder.java index 0487ab5..8a5941a 100644 --- a/src/main/java/org/qstd/DatasetRowComparatorBuilder.java +++ b/src/main/java/org/qstd/DatasetRowComparatorBuilder.java @@ -18,108 +18,105 @@ class DatasetRowComparatorBuilder { - private DatasetRowComparatorBuilder() { } - - static Comparator buildFrom(DatabaseMetadataFinder databaseMetadataFinder) { - ComparatorOnTableDependencies comparatorOnTableDependencies = new ComparatorOnTableDependencies(databaseMetadataFinder); - ComparatorOnPrimaryKey comparatorOnPrimaryKey = new ComparatorOnPrimaryKey(databaseMetadataFinder); - ComparatorOnTableName comparatorOnTableName = new ComparatorOnTableName(); - return comparatorOnTableDependencies.thenComparing(comparatorOnPrimaryKey) - .thenComparing(comparatorOnTableName); - } - - private static class ComparatorOnPrimaryKey implements Comparator { - - private final PrimaryKeyColumnsFinder primaryKeyColumnsFinder; - - ComparatorOnPrimaryKey(PrimaryKeyColumnsFinder primaryKeyColumnsFinder) { - this.primaryKeyColumnsFinder = primaryKeyColumnsFinder; - } + private DatasetRowComparatorBuilder() {} - @Override - public int compare(DatasetRow datasetRow1, DatasetRow datasetRow2) { + static Comparator buildFrom(DatabaseMetadataFinder databaseMetadataFinder) { + ComparatorOnTableDependencies comparatorOnTableDependencies = + new ComparatorOnTableDependencies(databaseMetadataFinder); + ComparatorOnPrimaryKey comparatorOnPrimaryKey = + new ComparatorOnPrimaryKey(databaseMetadataFinder); + ComparatorOnTableName comparatorOnTableName = new ComparatorOnTableName(); + return comparatorOnTableDependencies + .thenComparing(comparatorOnPrimaryKey) + .thenComparing(comparatorOnTableName); + } - if(!sameTableNames(datasetRow1, datasetRow2)) { - return 0; - } + private static class ComparatorOnPrimaryKey implements Comparator { - String tableName = datasetRow1.getTableName(); - List primaryKeyColumns = primaryKeyColumnsFinder.findPrimaryColumnsOf(tableName); + private final PrimaryKeyColumnsFinder primaryKeyColumnsFinder; - for (String primaryKeyColumn : primaryKeyColumns) { - int intComparison = compareIntPkValues(primaryKeyColumn, datasetRow1, datasetRow2); - if(intComparison != 0) { - return intComparison; - } - } + ComparatorOnPrimaryKey(PrimaryKeyColumnsFinder primaryKeyColumnsFinder) { + this.primaryKeyColumnsFinder = primaryKeyColumnsFinder; + } - return 0; + @Override + public int compare(DatasetRow datasetRow1, DatasetRow datasetRow2) { - } + if (!sameTableNames(datasetRow1, datasetRow2)) { + return 0; + } - private boolean sameTableNames(DatasetRow datasetRow1, DatasetRow datasetRow2) { - return datasetRow1.getTableName().equals(datasetRow2.getTableName()); - } + String tableName = datasetRow1.getTableName(); + List primaryKeyColumns = primaryKeyColumnsFinder.findPrimaryColumnsOf(tableName); - private int compareIntPkValues(String primaryKeyColumn, DatasetRow datasetRow1, DatasetRow datasetRow2) { - Object pkValue1 = datasetRow1.getValueOf(primaryKeyColumn); - Object pkValue2 = datasetRow2.getValueOf(primaryKeyColumn); - boolean integerPrimaryKey = pkValue1 instanceof Integer - || pkValue1 instanceof Long - || pkValue1 instanceof BigDecimal; - if(integerPrimaryKey) { - Number pkValue1AsNumber = (Number) pkValue1; - Number pkValue2AsNumber = (Number) pkValue2; - long pkValue1AsLong = pkValue1AsNumber.longValue(); - long pkValue2AsLong = pkValue2AsNumber.longValue(); - return Long.compare(pkValue1AsLong, pkValue2AsLong ); - } - return 0; + for (String primaryKeyColumn : primaryKeyColumns) { + int intComparison = compareIntPkValues(primaryKeyColumn, datasetRow1, datasetRow2); + if (intComparison != 0) { + return intComparison; } + } + return 0; } - private static class ComparatorOnTableDependencies implements Comparator { + private boolean sameTableNames(DatasetRow datasetRow1, DatasetRow datasetRow2) { + return datasetRow1.getTableName().equals(datasetRow2.getTableName()); + } - private final ReferencedTablesFinder referencedTablesFinder; + private int compareIntPkValues( + String primaryKeyColumn, DatasetRow datasetRow1, DatasetRow datasetRow2) { + Object pkValue1 = datasetRow1.getValueOf(primaryKeyColumn); + Object pkValue2 = datasetRow2.getValueOf(primaryKeyColumn); + boolean integerPrimaryKey = + pkValue1 instanceof Integer || pkValue1 instanceof Long || pkValue1 instanceof BigDecimal; + if (integerPrimaryKey) { + Number pkValue1AsNumber = (Number) pkValue1; + Number pkValue2AsNumber = (Number) pkValue2; + long pkValue1AsLong = pkValue1AsNumber.longValue(); + long pkValue2AsLong = pkValue2AsNumber.longValue(); + return Long.compare(pkValue1AsLong, pkValue2AsLong); + } + return 0; + } + } - public ComparatorOnTableDependencies(ReferencedTablesFinder referencedTablesFinder) { - this.referencedTablesFinder = referencedTablesFinder; - } + private static class ComparatorOnTableDependencies implements Comparator { - @Override - public int compare(DatasetRow datasetRow1, DatasetRow datasetRow2) { + private final ReferencedTablesFinder referencedTablesFinder; - String tableName1 = datasetRow1.getTableName(); - String tableName2 = datasetRow2.getTableName(); + public ComparatorOnTableDependencies(ReferencedTablesFinder referencedTablesFinder) { + this.referencedTablesFinder = referencedTablesFinder; + } - ReferencedTableSet referencedTableSetOfTable1 - = referencedTablesFinder.findReferencedTablesOf(tableName1); - if(referencedTableSetOfTable1.referencesTable(tableName2)) { - return 1; - } + @Override + public int compare(DatasetRow datasetRow1, DatasetRow datasetRow2) { - ReferencedTableSet referencedTableSetOfTable2 - = referencedTablesFinder.findReferencedTablesOf(tableName2); - if(referencedTableSetOfTable2.referencesTable(tableName1)) { - return -1; - } + String tableName1 = datasetRow1.getTableName(); + String tableName2 = datasetRow2.getTableName(); - return 0; + ReferencedTableSet referencedTableSetOfTable1 = + referencedTablesFinder.findReferencedTablesOf(tableName1); + if (referencedTableSetOfTable1.referencesTable(tableName2)) { + return 1; + } - } + ReferencedTableSet referencedTableSetOfTable2 = + referencedTablesFinder.findReferencedTablesOf(tableName2); + if (referencedTableSetOfTable2.referencesTable(tableName1)) { + return -1; + } + return 0; } + } - private static class ComparatorOnTableName implements Comparator { - - @Override - public int compare(DatasetRow row1, DatasetRow row2) { - String row1TableName = row1.getTableName(); - String row2TableName = row2.getTableName(); - return row1TableName.compareTo(row2TableName); - } + private static class ComparatorOnTableName implements Comparator { + @Override + public int compare(DatasetRow row1, DatasetRow row2) { + String row1TableName = row1.getTableName(); + String row2TableName = row2.getTableName(); + return row1TableName.compareTo(row2TableName); } - + } } diff --git a/src/main/java/org/qstd/DatasetRowSet.java b/src/main/java/org/qstd/DatasetRowSet.java index 6b5a966..e599e30 100644 --- a/src/main/java/org/qstd/DatasetRowSet.java +++ b/src/main/java/org/qstd/DatasetRowSet.java @@ -12,83 +12,80 @@ */ package org.qstd; -import org.qstd.dbtype.DatabaseType; - -import javax.sql.DataSource; import java.util.*; import java.util.function.Function; +import javax.sql.DataSource; +import org.qstd.dbtype.DatabaseType; class DatasetRowSet { - private final MissingNotNullColumnsFinder missingNotNullColumnsFinder; + private final MissingNotNullColumnsFinder missingNotNullColumnsFinder; - private final DatabaseMetadataFinder databaseMetadataFinder; + private final DatabaseMetadataFinder databaseMetadataFinder; - private final Collection datasetRows = new ArrayDeque<>(); + private final Collection datasetRows = new ArrayDeque<>(); - DatasetRowSet( DataSource dataSource - , DatabaseType dbType - , DatabaseMetadataFinder databaseMetadataFinder) { - this.databaseMetadataFinder = databaseMetadataFinder; - this.missingNotNullColumnsFinder = new MissingNotNullColumnsFinder(dataSource - , dbType - , databaseMetadataFinder); - } + DatasetRowSet( + DataSource dataSource, DatabaseType dbType, DatabaseMetadataFinder databaseMetadataFinder) { + this.databaseMetadataFinder = databaseMetadataFinder; + this.missingNotNullColumnsFinder = + new MissingNotNullColumnsFinder(dataSource, dbType, databaseMetadataFinder); + } - void add(Collection datasetRows) { - for (DatasetRow datasetRow : datasetRows) { - add(datasetRow); - } + void add(Collection datasetRows) { + for (DatasetRow datasetRow : datasetRows) { + add(datasetRow); } + } - private void add(DatasetRow datasetRow) { + private void add(DatasetRow datasetRow) { - Function functionToHaveMetadataTableName = databaseMetadataFinder.getFunctionToHaveMetadataTableName(); - datasetRow.updateTableNameWith(functionToHaveMetadataTableName); + Function functionToHaveMetadataTableName = + databaseMetadataFinder.getFunctionToHaveMetadataTableName(); + datasetRow.updateTableNameWith(functionToHaveMetadataTableName); - boolean rowIsMerged = datasetRow.mergeWithARowOf(datasetRows); + boolean rowIsMerged = datasetRow.mergeWithARowOf(datasetRows); - if (!rowIsMerged) { - Map missingNotNullColumns = - missingNotNullColumnsFinder.findMissingNoNullColumnsOf(datasetRow); - datasetRow.addColumnValues(missingNotNullColumns); + if (!rowIsMerged) { + Map missingNotNullColumns = + missingNotNullColumnsFinder.findMissingNoNullColumnsOf(datasetRow); + datasetRow.addColumnValues(missingNotNullColumns); - datasetRows.add(datasetRow); - - Collection joinedRows = findJoinedRowsOf(datasetRow); - for (DatasetRow joinRow : joinedRows) { - add(joinRow); - } - } + datasetRows.add(datasetRow); + Collection joinedRows = findJoinedRowsOf(datasetRow); + for (DatasetRow joinRow : joinedRows) { + add(joinRow); + } } - - private Collection findJoinedRowsOf(DatasetRow datasetRow) { - String tableName = datasetRow.getTableName(); - ColumnsMappingGroup columnsMappingGroup = - databaseMetadataFinder.findColumnsMappingsOf(tableName); - return datasetRow.extractJoinedRowsFrom(columnsMappingGroup); + } + + private Collection findJoinedRowsOf(DatasetRow datasetRow) { + String tableName = datasetRow.getTableName(); + ColumnsMappingGroup columnsMappingGroup = + databaseMetadataFinder.findColumnsMappingsOf(tableName); + return datasetRow.extractJoinedRowsFrom(columnsMappingGroup); + } + + List sort() { + sortColumnsFollowingDatabaseDeclaration(datasetRows); + return sortRows(); + } + + private void sortColumnsFollowingDatabaseDeclaration(Collection allRows) { + for (DatasetRow datasetRow : allRows) { + String tableName = datasetRow.getTableName(); + List databaseColumnOrders = + databaseMetadataFinder.findDatabaseColumnOrdersOf(tableName); + datasetRow.sortColumnsFollowing(databaseColumnOrders); } - - List sort() { - sortColumnsFollowingDatabaseDeclaration(datasetRows); - return sortRows(); - } - - private void sortColumnsFollowingDatabaseDeclaration(Collection allRows) { - for (DatasetRow datasetRow : allRows) { - String tableName = datasetRow.getTableName(); - List databaseColumnOrders = databaseMetadataFinder.findDatabaseColumnOrdersOf(tableName); - datasetRow.sortColumnsFollowing(databaseColumnOrders); - } - } - - private List sortRows() { - List rowsAsList = new ArrayList<>(datasetRows); - Comparator datasetRowComparator = - DatasetRowComparatorBuilder.buildFrom(databaseMetadataFinder); - rowsAsList.sort(datasetRowComparator); - return rowsAsList; - } - + } + + private List sortRows() { + List rowsAsList = new ArrayList<>(datasetRows); + Comparator datasetRowComparator = + DatasetRowComparatorBuilder.buildFrom(databaseMetadataFinder); + rowsAsList.sort(datasetRowComparator); + return rowsAsList; + } } diff --git a/src/main/java/org/qstd/DatasetRowsFinder.java b/src/main/java/org/qstd/DatasetRowsFinder.java index a33389c..88e0792 100644 --- a/src/main/java/org/qstd/DatasetRowsFinder.java +++ b/src/main/java/org/qstd/DatasetRowsFinder.java @@ -12,104 +12,104 @@ */ package org.qstd; +import static java.util.Collections.emptyList; +import static org.qstd.SelectTransformerFactory.createSelectTransformer; + +import java.sql.*; +import java.util.*; +import javax.sql.DataSource; import net.sf.jsqlparser.JSQLParserException; import net.sf.jsqlparser.parser.CCJSqlParserUtil; import net.sf.jsqlparser.statement.Statement; import net.sf.jsqlparser.statement.select.Select; import net.sf.jsqlparser.util.TablesNamesFinder; -import javax.sql.DataSource; -import java.sql.*; -import java.util.*; - -import static java.util.Collections.emptyList; -import static org.qstd.SelectTransformerFactory.createSelectTransformer; - class DatasetRowsFinder { - private final DataSource dataSource; - - DatasetRowsFinder(DataSource dataSource) { - this.dataSource = dataSource; - } + private final DataSource dataSource; - Collection findDatasetRowsOf(SqlQuery sqlQuery) { + DatasetRowsFinder(DataSource dataSource) { + this.dataSource = dataSource; + } - SelectTransformer selectTransformer = createSelectTransformer(sqlQuery); - Optional optionalSelectQuery = selectTransformer.toSelect(sqlQuery); + Collection findDatasetRowsOf(SqlQuery sqlQuery) { - if (optionalSelectQuery.isPresent()) { - SqlQuery selectQuery = optionalSelectQuery.get(); - return execute(selectQuery); - } + SelectTransformer selectTransformer = createSelectTransformer(sqlQuery); + Optional optionalSelectQuery = selectTransformer.toSelect(sqlQuery); - return emptyList(); + if (optionalSelectQuery.isPresent()) { + SqlQuery selectQuery = optionalSelectQuery.get(); + return execute(selectQuery); } - private Collection execute(SqlQuery sqlQuery) { + return emptyList(); + } - List datasetRowsToReturn = new ArrayList<>(); + private Collection execute(SqlQuery sqlQuery) { - try (Connection connection = dataSource.getConnection(); - PreparedStatement selectStatement = PreparedStatementBuilder.buildFrom(sqlQuery, connection)) { + List datasetRowsToReturn = new ArrayList<>(); - ResultSet resultSet = selectStatement.executeQuery(); + try (Connection connection = dataSource.getConnection(); + PreparedStatement selectStatement = + PreparedStatementBuilder.buildFrom(sqlQuery, connection)) { - ResultSetMetaData resultSetMetaData = resultSet.getMetaData(); - int columnCount = resultSetMetaData.getColumnCount(); + ResultSet resultSet = selectStatement.executeQuery(); - while (resultSet.next()) { - Collection datasetRows = - buildDatasetRowsFrom(resultSet, resultSetMetaData - , columnCount, sqlQuery); - datasetRowsToReturn.addAll(datasetRows); - } - } catch (SQLException sqlException) { - sqlException.printStackTrace(); - } - - return datasetRowsToReturn; + ResultSetMetaData resultSetMetaData = resultSet.getMetaData(); + int columnCount = resultSetMetaData.getColumnCount(); + while (resultSet.next()) { + Collection datasetRows = + buildDatasetRowsFrom( + resultSet, resultSetMetaData, + columnCount, sqlQuery); + datasetRowsToReturn.addAll(datasetRows); + } + } catch (SQLException sqlException) { + sqlException.printStackTrace(); } - private Collection buildDatasetRowsFrom(ResultSet resultSet, ResultSetMetaData resultSetMetaData - , int columnCount, SqlQuery sqlQuery) throws SQLException { - Map rowsByTableName = new HashMap<>(); - for (int colIndex = 1; colIndex <= columnCount; colIndex++) { - final String tableName = findTableName(resultSetMetaData, colIndex, sqlQuery); - DatasetRow datasetRow = - rowsByTableName.computeIfAbsent(tableName - , t -> DatasetRow.ofTable(tableName)); - - String column = resultSetMetaData.getColumnName(colIndex); - Object value = resultSet.getObject(colIndex); - datasetRow.addColumnValue(column, value); - } - return rowsByTableName.values(); + return datasetRowsToReturn; + } + + private Collection buildDatasetRowsFrom( + ResultSet resultSet, ResultSetMetaData resultSetMetaData, int columnCount, SqlQuery sqlQuery) + throws SQLException { + Map rowsByTableName = new HashMap<>(); + for (int colIndex = 1; colIndex <= columnCount; colIndex++) { + final String tableName = findTableName(resultSetMetaData, colIndex, sqlQuery); + DatasetRow datasetRow = + rowsByTableName.computeIfAbsent(tableName, t -> DatasetRow.ofTable(tableName)); + + String column = resultSetMetaData.getColumnName(colIndex); + Object value = resultSet.getObject(colIndex); + datasetRow.addColumnValue(column, value); } - - private String findTableName(ResultSetMetaData resultSetMetaData, int colIndex, SqlQuery sqlQuery) throws SQLException { - String tableName = resultSetMetaData.getTableName(colIndex); - if (!tableName.isEmpty()) { - return tableName; - } - String queryAsString = sqlQuery.getQueryAsString(); - return extractTableNameFrom(queryAsString); + return rowsByTableName.values(); + } + + private String findTableName(ResultSetMetaData resultSetMetaData, int colIndex, SqlQuery sqlQuery) + throws SQLException { + String tableName = resultSetMetaData.getTableName(colIndex); + if (!tableName.isEmpty()) { + return tableName; } - - private String extractTableNameFrom(String sqlQueryAsString) { - try { - Statement statement = CCJSqlParserUtil.parse(sqlQueryAsString); - Select select = (Select) statement; - TablesNamesFinder tablesNamesFinder = new TablesNamesFinder(); - List tableList = tablesNamesFinder.getTableList(select); - if(tableList.size() == 1) { - return tableList.get(0); - } - } catch (JSQLParserException e) { - e.printStackTrace(); - } - return ""; + String queryAsString = sqlQuery.getQueryAsString(); + return extractTableNameFrom(queryAsString); + } + + private String extractTableNameFrom(String sqlQueryAsString) { + try { + Statement statement = CCJSqlParserUtil.parse(sqlQueryAsString); + Select select = (Select) statement; + TablesNamesFinder tablesNamesFinder = new TablesNamesFinder(); + List tableList = tablesNamesFinder.getTableList(select); + if (tableList.size() == 1) { + return tableList.get(0); + } + } catch (JSQLParserException e) { + e.printStackTrace(); } - + return ""; + } } diff --git a/src/main/java/org/qstd/DatasetRowsGenerator.java b/src/main/java/org/qstd/DatasetRowsGenerator.java index 227e0e8..0383da5 100644 --- a/src/main/java/org/qstd/DatasetRowsGenerator.java +++ b/src/main/java/org/qstd/DatasetRowsGenerator.java @@ -12,38 +12,35 @@ */ package org.qstd; -import org.qstd.dbtype.DatabaseType; - -import javax.sql.DataSource; import java.util.Collection; import java.util.List; +import javax.sql.DataSource; +import org.qstd.dbtype.DatabaseType; class DatasetRowsGenerator { - private final DataSource dataSource; + private final DataSource dataSource; - private final DatabaseType dbType; + private final DatabaseType dbType; - private final DatabaseMetadataFinder databaseMetadataFinder; + private final DatabaseMetadataFinder databaseMetadataFinder; - private final DatasetRowsFinder datasetRowsFinder; + private final DatasetRowsFinder datasetRowsFinder; - DatasetRowsGenerator(DataSource dataSource - , DatabaseType dbType - , DatabaseMetadataFinder databaseMetadataFinder) { - this.dataSource = dataSource; - this.dbType = dbType; - this.databaseMetadataFinder = databaseMetadataFinder; - this.datasetRowsFinder = new DatasetRowsFinder(dataSource); - } + DatasetRowsGenerator( + DataSource dataSource, DatabaseType dbType, DatabaseMetadataFinder databaseMetadataFinder) { + this.dataSource = dataSource; + this.dbType = dbType; + this.databaseMetadataFinder = databaseMetadataFinder; + this.datasetRowsFinder = new DatasetRowsFinder(dataSource); + } - List generateDatasetRowsFor(List sqlQueries) { - DatasetRowSet datasetRowSet = new DatasetRowSet(dataSource, dbType, databaseMetadataFinder); - for (SqlQuery sqlQuery : sqlQueries) { - Collection datasetRows = datasetRowsFinder.findDatasetRowsOf(sqlQuery); - datasetRowSet.add(datasetRows); - } - return datasetRowSet.sort(); + List generateDatasetRowsFor(List sqlQueries) { + DatasetRowSet datasetRowSet = new DatasetRowSet(dataSource, dbType, databaseMetadataFinder); + for (SqlQuery sqlQuery : sqlQueries) { + Collection datasetRows = datasetRowsFinder.findDatasetRowsOf(sqlQuery); + datasetRowSet.add(datasetRows); } - + return datasetRowSet.sort(); + } } diff --git a/src/main/java/org/qstd/DeleteToSelectTransformer.java b/src/main/java/org/qstd/DeleteToSelectTransformer.java index 0d6a947..c46be0c 100644 --- a/src/main/java/org/qstd/DeleteToSelectTransformer.java +++ b/src/main/java/org/qstd/DeleteToSelectTransformer.java @@ -12,42 +12,37 @@ */ package org.qstd; +import java.util.Optional; import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.statement.delete.Delete; -import java.util.Optional; - class DeleteToSelectTransformer implements SelectTransformer { - private Delete deleteStatement; - - DeleteToSelectTransformer(Delete delete) { - deleteStatement = delete; - } + private Delete deleteStatement; - @Override - public Optional toSelect(SqlQuery sqlQuery) { - String deleteAsString = sqlQuery.getQueryAsString(); - String deleteString = toSelect(deleteAsString); - SqlQuery deleteQuery = new SqlQuery(deleteString); - return Optional.of(deleteQuery); - } + DeleteToSelectTransformer(Delete delete) { + deleteStatement = delete; + } - private String toSelect(String sqlQueryAsString) { - String tableName = deleteStatement.getTable().getName(); + @Override + public Optional toSelect(SqlQuery sqlQuery) { + String deleteAsString = sqlQuery.getQueryAsString(); + String deleteString = toSelect(deleteAsString); + SqlQuery deleteQuery = new SqlQuery(deleteString); + return Optional.of(deleteQuery); + } - String whereClauseAsString = findWhereClauseAsString(); + private String toSelect(String sqlQueryAsString) { + String tableName = deleteStatement.getTable().getName(); - return " SELECT " + "*" - + " FROM " + tableName - + whereClauseAsString; - } + String whereClauseAsString = findWhereClauseAsString(); - private String findWhereClauseAsString() { - Expression whereExpression = deleteStatement.getWhere(); - String whereClauseAsString = whereExpression == null ? "" - :" WHERE " + whereExpression; - return whereClauseAsString; - } + return " SELECT " + "*" + " FROM " + tableName + whereClauseAsString; + } + private String findWhereClauseAsString() { + Expression whereExpression = deleteStatement.getWhere(); + String whereClauseAsString = whereExpression == null ? "" : " WHERE " + whereExpression; + return whereClauseAsString; + } } diff --git a/src/main/java/org/qstd/InsertStatementsGenerator.java b/src/main/java/org/qstd/InsertStatementsGenerator.java index ee60418..dfcfd6f 100644 --- a/src/main/java/org/qstd/InsertStatementsGenerator.java +++ b/src/main/java/org/qstd/InsertStatementsGenerator.java @@ -12,57 +12,55 @@ */ package org.qstd; -import org.qstd.dbtype.DatabaseType; +import static java.lang.System.lineSeparator; +import static java.util.stream.Collectors.joining; +import static java.util.stream.Collectors.toList; import java.util.Collection; import java.util.List; import java.util.Set; - -import static java.lang.System.lineSeparator; -import static java.util.stream.Collectors.joining; -import static java.util.stream.Collectors.toList; +import org.qstd.dbtype.DatabaseType; class InsertStatementsGenerator { - private final DatabaseType dbType; - - InsertStatementsGenerator(DatabaseType dbType) { - this.dbType = dbType; - } + private final DatabaseType dbType; - String generateInsertScriptFor(List datasetRows) { - return datasetRows - .stream() - .map(this::generateInsertStatementFrom) - .map(insertStatement -> insertStatement + ";" + lineSeparator()) - .collect(joining()); - } + InsertStatementsGenerator(DatabaseType dbType) { + this.dbType = dbType; + } - private String generateInsertStatementFrom(DatasetRow datasetRow) { - String tableName = datasetRow.getTableName(); - Set columnNames = datasetRow.getColumnNames(); - Collection columnValues = datasetRow.getColumnValues(); - return "INSERT INTO " + tableName + "(" + formatColumnNames(columnNames) + ")" - + " VALUES(" + formatColumnValues(columnValues) + ")"; - } + String generateInsertScriptFor(List datasetRows) { + return datasetRows.stream() + .map(this::generateInsertStatementFrom) + .map(insertStatement -> insertStatement + ";" + lineSeparator()) + .collect(joining()); + } - private String formatColumnNames(Set columnNames) { - return String.join(", ", columnNames); - } + private String generateInsertStatementFrom(DatasetRow datasetRow) { + String tableName = datasetRow.getTableName(); + Set columnNames = datasetRow.getColumnNames(); + Collection columnValues = datasetRow.getColumnValues(); + return "INSERT INTO " + + tableName + + "(" + + formatColumnNames(columnNames) + + ")" + + " VALUES(" + + formatColumnValues(columnValues) + + ")"; + } - private String formatColumnValues(Collection columnValues) { - return columnValues - .stream() - .map(columnValue -> ColumnValueFormatter.INSTANCE - .formatColumnValue(columnValue, dbType)) - .collect(joining(", ")); - } + private String formatColumnNames(Set columnNames) { + return String.join(", ", columnNames); + } - List generateInsertStatementsFor(List datasetRows) { - return datasetRows - .stream() - .map(this::generateInsertStatementFrom) - .collect(toList()); - } + private String formatColumnValues(Collection columnValues) { + return columnValues.stream() + .map(columnValue -> ColumnValueFormatter.INSTANCE.formatColumnValue(columnValue, dbType)) + .collect(joining(", ")); + } + List generateInsertStatementsFor(List datasetRows) { + return datasetRows.stream().map(this::generateInsertStatementFrom).collect(toList()); + } } diff --git a/src/main/java/org/qstd/MissingNotNullColumnsFinder.java b/src/main/java/org/qstd/MissingNotNullColumnsFinder.java index ca07325..5e8ea64 100644 --- a/src/main/java/org/qstd/MissingNotNullColumnsFinder.java +++ b/src/main/java/org/qstd/MissingNotNullColumnsFinder.java @@ -12,48 +12,47 @@ */ package org.qstd; -import org.qstd.dbtype.DatabaseType; +import static java.util.stream.Collectors.toList; -import javax.sql.DataSource; import java.util.Collection; import java.util.Collections; import java.util.Map; - -import static java.util.stream.Collectors.toList; +import javax.sql.DataSource; +import org.qstd.dbtype.DatabaseType; class MissingNotNullColumnsFinder { - private final DataSource dataSource; - - private final DatabaseType dbType; + private final DataSource dataSource; - private final DatabaseMetadataFinder databaseMetadataFinder; - - MissingNotNullColumnsFinder(DataSource dataSource, DatabaseType dbType, DatabaseMetadataFinder databaseMetadataFinder) { - this.dataSource = dataSource; - this.dbType = dbType; - this.databaseMetadataFinder = databaseMetadataFinder; - } + private final DatabaseType dbType; - Map findMissingNoNullColumnsOf(DatasetRow datasetRow) { + private final DatabaseMetadataFinder databaseMetadataFinder; - String tableName = datasetRow.getTableName(); + MissingNotNullColumnsFinder( + DataSource dataSource, DatabaseType dbType, DatabaseMetadataFinder databaseMetadataFinder) { + this.dataSource = dataSource; + this.dbType = dbType; + this.databaseMetadataFinder = databaseMetadataFinder; + } - Collection notNullColumns = databaseMetadataFinder.findNotNullColumnsOf(tableName); + Map findMissingNoNullColumnsOf(DatasetRow datasetRow) { - Collection missingNotNullColumns = notNullColumns - .stream() - .filter(columnName -> !datasetRow.hasNotNullValueForColumn(columnName)) - .collect(toList()); + String tableName = datasetRow.getTableName(); - if (!missingNotNullColumns.isEmpty()) { - RowFinder rowFinder = new RowFinder(dataSource, dbType); - DatasetRow datasetRowWithMissingNotNullColumns = rowFinder.findOneRowFrom(datasetRow.getTableName(), missingNotNullColumns, datasetRow); - return datasetRowWithMissingNotNullColumns.getColumnValueByColumnName(); - } + Collection notNullColumns = databaseMetadataFinder.findNotNullColumnsOf(tableName); - return Collections.emptyMap(); + Collection missingNotNullColumns = + notNullColumns.stream() + .filter(columnName -> !datasetRow.hasNotNullValueForColumn(columnName)) + .collect(toList()); + if (!missingNotNullColumns.isEmpty()) { + RowFinder rowFinder = new RowFinder(dataSource, dbType); + DatasetRow datasetRowWithMissingNotNullColumns = + rowFinder.findOneRowFrom(datasetRow.getTableName(), missingNotNullColumns, datasetRow); + return datasetRowWithMissingNotNullColumns.getColumnValueByColumnName(); } + return Collections.emptyMap(); + } } diff --git a/src/main/java/org/qstd/NotNullColumnsFinder.java b/src/main/java/org/qstd/NotNullColumnsFinder.java index 2dbc2fe..0f5b107 100644 --- a/src/main/java/org/qstd/NotNullColumnsFinder.java +++ b/src/main/java/org/qstd/NotNullColumnsFinder.java @@ -16,6 +16,5 @@ public interface NotNullColumnsFinder { - Collection findNotNullColumnsOf(String tableName); - + Collection findNotNullColumnsOf(String tableName); } diff --git a/src/main/java/org/qstd/PreparedStatementBuilder.java b/src/main/java/org/qstd/PreparedStatementBuilder.java index 52bb18f..1e8b62b 100644 --- a/src/main/java/org/qstd/PreparedStatementBuilder.java +++ b/src/main/java/org/qstd/PreparedStatementBuilder.java @@ -19,17 +19,16 @@ public class PreparedStatementBuilder { - private PreparedStatementBuilder() { - } + private PreparedStatementBuilder() {} - public static PreparedStatement buildFrom(SqlQuery sqlQuery, Connection connection) throws SQLException { - String queryAsString = sqlQuery.getQueryAsString(); - PreparedStatement preparedStatement = connection.prepareStatement(queryAsString); - List parameters = sqlQuery.getParameters(); - for (int i = 0; i < parameters.size(); i++) { - preparedStatement.setObject(i + 1, parameters.get(i)); - } - return preparedStatement; + public static PreparedStatement buildFrom(SqlQuery sqlQuery, Connection connection) + throws SQLException { + String queryAsString = sqlQuery.getQueryAsString(); + PreparedStatement preparedStatement = connection.prepareStatement(queryAsString); + List parameters = sqlQuery.getParameters(); + for (int i = 0; i < parameters.size(); i++) { + preparedStatement.setObject(i + 1, parameters.get(i)); } - + return preparedStatement; + } } diff --git a/src/main/java/org/qstd/PrimaryKeyColumnsFinder.java b/src/main/java/org/qstd/PrimaryKeyColumnsFinder.java index 0b4ff34..972e86f 100644 --- a/src/main/java/org/qstd/PrimaryKeyColumnsFinder.java +++ b/src/main/java/org/qstd/PrimaryKeyColumnsFinder.java @@ -16,6 +16,5 @@ public interface PrimaryKeyColumnsFinder { - List findPrimaryColumnsOf(String tableName); - + List findPrimaryColumnsOf(String tableName); } diff --git a/src/main/java/org/qstd/QuickSqlTestData.java b/src/main/java/org/qstd/QuickSqlTestData.java index 9c24266..278edae 100644 --- a/src/main/java/org/qstd/QuickSqlTestData.java +++ b/src/main/java/org/qstd/QuickSqlTestData.java @@ -12,22 +12,21 @@ */ package org.qstd; -import org.qstd.dbtype.DatabaseMetadataFinderFactory; -import org.qstd.dbtype.DatabaseMetadataFinderWithCache; -import org.qstd.dbtype.DatabaseType; -import org.qstd.dbtype.DatabaseUrlFinder; - -import javax.sql.DataSource; -import java.util.List; - import static java.util.Arrays.stream; import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; import static java.util.stream.Collectors.toList; +import java.util.List; +import javax.sql.DataSource; +import org.qstd.dbtype.DatabaseMetadataFinderFactory; +import org.qstd.dbtype.DatabaseMetadataFinderWithCache; +import org.qstd.dbtype.DatabaseType; +import org.qstd.dbtype.DatabaseUrlFinder; + /** - * Class allowing to ease the generation of datasets to test SQL queries. - * Methods produce INSERT statements taking account of database integrity constraints. + * Class allowing to ease the generation of datasets to test SQL queries. Methods produce INSERT + * statements taking account of database integrity constraints. * * @see SqlQuery * @see DatasetRow @@ -37,117 +36,123 @@ */ public class QuickSqlTestData { - private final DatasetRowsGenerator datasetRowsGenerator; - - private final DatabaseType dbType; - - private InsertStatementsGenerator insertStatementGenerator; - - private QuickSqlTestData(DatasetRowsGenerator datasetRowsGenerator, DatabaseType dbType) { - this.datasetRowsGenerator = datasetRowsGenerator; - this.dbType = dbType; - insertStatementGenerator = new InsertStatementsGenerator(dbType); - } - - /** - * Factory method to build an instance of org.qstd.QuickSqlTestData from a data source. - * The retrieval of database metadata, such as not null columns or primary keys, is cached for each table. - * @param dataSource A data source - * @return An instance of org.qstd.QuickSqlTestData - */ - public static QuickSqlTestData buildFrom(DataSource dataSource) { - String dbUrl = DatabaseUrlFinder.INSTANCE.findDbUrlFrom(dataSource); - DatabaseType dbType = DatabaseType.findFromDbUrl(dbUrl); - DatabaseMetadataFinder databaseMetadataFinder = DatabaseMetadataFinderFactory.createDatabaseMetadataFinderFrom(dataSource, dbType); - DatabaseMetadataFinder databaseMetadataFinderWithCache = DatabaseMetadataFinderWithCache.buildFrom(databaseMetadataFinder); - return buildFrom(dataSource, dbType, databaseMetadataFinderWithCache); - } - - /** - * Factory method to build an instance of org.qstd.QuickSqlTestData from a data source, - * a database type and a database metadata finder. - * @param dataSource A datasource - * @param dbType A database type - * @param databaseMetadataFinder A database metadata finder - * @return An instance of org.qstd.QuickSqlTestData - */ - public static QuickSqlTestData buildFrom(DataSource dataSource, DatabaseType dbType, DatabaseMetadataFinder databaseMetadataFinder) { - DatasetRowsGenerator datasetRowsGenerator = new DatasetRowsGenerator(dataSource, dbType, databaseMetadataFinder); - return new QuickSqlTestData(datasetRowsGenerator, dbType); - } - - /** - * Generates an SQL script allowing to test the SQL query given in parameter. - * This script contains INSERT statements. - * It takes into account the database integrity constraints. - * @param sqlQuery An SQL query - * @return An SQL script allowing to test the SQL query given in parameter - */ - public String generateInsertScriptFor(String sqlQuery) { - return generateInsertScriptFor(sqlQuery, emptyList()); - } - - /** - * Generates an SQL script allowing to test an SQL query with its bind parameter values. - * This script contains INSERT statements. - * It takes into account the database integrity constraints. - * @param query An SQL query with bind parameters - * @param parameters Bind parameter values - * @return An SQL script allowing to test the SQL query with its bind parameter values - */ - public String generateInsertScriptFor(String query, List parameters) { - List sqlQueries = singletonList(new SqlQuery(query, parameters)); - return generateInsertScriptFor(sqlQueries); - } - - /** - * Generates an SQL script allowing to test the list of SQL queries given in parameter. - * This script contains INSERT statements. - * It takes into account the database integrity constraints. - * @param sqlQueries SQL queries - * @return An SQL script allowing to test the SQL queries given in parameter - */ - public String generateInsertScriptFor(List sqlQueries) { - List datasetRows = datasetRowsGenerator.generateDatasetRowsFor(sqlQueries); - return insertStatementGenerator.generateInsertScriptFor(datasetRows); - } - - /** - * Generates a list of INSERT statements allowing to test the list of SQL queries given in parameter. - * These INSERT statements take into account the database integrity constraints. - * @param sqlQueries SQL queries - * @return An SQL script allowing to test the SQL queries given in parameter - */ - public String generateInsertScriptFor(String... sqlQueries) { - List queries = stream(sqlQueries) - .map(SqlQuery::new) - .collect(toList()); - return generateInsertScriptFor(queries); - } - - /** - * Generates a list of INSERT statements allowing to create in database the dataset row given in parameter. - * These INSERT statements take into account the database integrity constraints. - * @param datasetRow A dataset row - * @return A list of INSERT statements allowing to create in database the dataset row given in parameter - */ - public List generateInsertListFor(DatasetRow datasetRow) { - SqlQuery sqlQuery = SqlQuery.buildFromRow(datasetRow, dbType); - return generateInsertListFor(sqlQuery.toString()); - } - - /** - * Generates a list of INSERT statements allowing to test the SQL queries given in parameter. - * These INSERT statements take into account the database integrity constraints. - * @param sqlQueries SQL queries - * @return A list of INSERT statements allowing to test the SQL queries given in parameter - */ - public List generateInsertListFor(String... sqlQueries) { - List sqlQueryObjects = stream(sqlQueries) - .map(SqlQuery::new) - .collect(toList()); - List datasetRows = datasetRowsGenerator.generateDatasetRowsFor(sqlQueryObjects); - return insertStatementGenerator.generateInsertStatementsFor(datasetRows); - } - + private final DatasetRowsGenerator datasetRowsGenerator; + + private final DatabaseType dbType; + + private InsertStatementsGenerator insertStatementGenerator; + + private QuickSqlTestData(DatasetRowsGenerator datasetRowsGenerator, DatabaseType dbType) { + this.datasetRowsGenerator = datasetRowsGenerator; + this.dbType = dbType; + insertStatementGenerator = new InsertStatementsGenerator(dbType); + } + + /** + * Factory method to build an instance of org.qstd.QuickSqlTestData from a data + * source. The retrieval of database metadata, such as not null columns or primary keys, is + * cached for each table. + * + * @param dataSource A data source + * @return An instance of org.qstd.QuickSqlTestData + */ + public static QuickSqlTestData buildFrom(DataSource dataSource) { + String dbUrl = DatabaseUrlFinder.INSTANCE.findDbUrlFrom(dataSource); + DatabaseType dbType = DatabaseType.findFromDbUrl(dbUrl); + DatabaseMetadataFinder databaseMetadataFinder = + DatabaseMetadataFinderFactory.createDatabaseMetadataFinderFrom(dataSource, dbType); + DatabaseMetadataFinder databaseMetadataFinderWithCache = + DatabaseMetadataFinderWithCache.buildFrom(databaseMetadataFinder); + return buildFrom(dataSource, dbType, databaseMetadataFinderWithCache); + } + + /** + * Factory method to build an instance of org.qstd.QuickSqlTestData from a data + * source, a database type and a database metadata finder. + * + * @param dataSource A datasource + * @param dbType A database type + * @param databaseMetadataFinder A database metadata finder + * @return An instance of org.qstd.QuickSqlTestData + */ + public static QuickSqlTestData buildFrom( + DataSource dataSource, DatabaseType dbType, DatabaseMetadataFinder databaseMetadataFinder) { + DatasetRowsGenerator datasetRowsGenerator = + new DatasetRowsGenerator(dataSource, dbType, databaseMetadataFinder); + return new QuickSqlTestData(datasetRowsGenerator, dbType); + } + + /** + * Generates an SQL script allowing to test the SQL query given in parameter. This script contains + * INSERT statements. It takes into account the database integrity constraints. + * + * @param sqlQuery An SQL query + * @return An SQL script allowing to test the SQL query given in parameter + */ + public String generateInsertScriptFor(String sqlQuery) { + return generateInsertScriptFor(sqlQuery, emptyList()); + } + + /** + * Generates an SQL script allowing to test an SQL query with its bind parameter values. This + * script contains INSERT statements. It takes into account the database integrity constraints. + * + * @param query An SQL query with bind parameters + * @param parameters Bind parameter values + * @return An SQL script allowing to test the SQL query with its bind parameter values + */ + public String generateInsertScriptFor(String query, List parameters) { + List sqlQueries = singletonList(new SqlQuery(query, parameters)); + return generateInsertScriptFor(sqlQueries); + } + + /** + * Generates an SQL script allowing to test the list of SQL queries given in parameter. This + * script contains INSERT statements. It takes into account the database integrity constraints. + * + * @param sqlQueries SQL queries + * @return An SQL script allowing to test the SQL queries given in parameter + */ + public String generateInsertScriptFor(List sqlQueries) { + List datasetRows = datasetRowsGenerator.generateDatasetRowsFor(sqlQueries); + return insertStatementGenerator.generateInsertScriptFor(datasetRows); + } + + /** + * Generates a list of INSERT statements allowing to test the list of SQL queries given in + * parameter. These INSERT statements take into account the database integrity constraints. + * + * @param sqlQueries SQL queries + * @return An SQL script allowing to test the SQL queries given in parameter + */ + public String generateInsertScriptFor(String... sqlQueries) { + List queries = stream(sqlQueries).map(SqlQuery::new).collect(toList()); + return generateInsertScriptFor(queries); + } + + /** + * Generates a list of INSERT statements allowing to create in database the dataset row given in + * parameter. These INSERT statements take into account the database integrity constraints. + * + * @param datasetRow A dataset row + * @return A list of INSERT statements allowing to create in database the dataset row given in + * parameter + */ + public List generateInsertListFor(DatasetRow datasetRow) { + SqlQuery sqlQuery = SqlQuery.buildFromRow(datasetRow, dbType); + return generateInsertListFor(sqlQuery.toString()); + } + + /** + * Generates a list of INSERT statements allowing to test the SQL queries given in parameter. + * These INSERT statements take into account the database integrity constraints. + * + * @param sqlQueries SQL queries + * @return A list of INSERT statements allowing to test the SQL queries given in parameter + */ + public List generateInsertListFor(String... sqlQueries) { + List sqlQueryObjects = stream(sqlQueries).map(SqlQuery::new).collect(toList()); + List datasetRows = datasetRowsGenerator.generateDatasetRowsFor(sqlQueryObjects); + return insertStatementGenerator.generateInsertStatementsFor(datasetRows); + } } diff --git a/src/main/java/org/qstd/ReferencedTable.java b/src/main/java/org/qstd/ReferencedTable.java index 7100f6a..8cc5df9 100644 --- a/src/main/java/org/qstd/ReferencedTable.java +++ b/src/main/java/org/qstd/ReferencedTable.java @@ -14,20 +14,19 @@ public class ReferencedTable { - private final String tableName; + private final String tableName; - private final String referencedTableName; + private final String referencedTableName; - private final int level; + private final int level; - public ReferencedTable(String tableName, String referencedTableName, int level) { - this.tableName = tableName; - this.referencedTableName = referencedTableName; - this.level = level; - } - - boolean references(String tableName) { - return tableName.equals(referencedTableName); - } + public ReferencedTable(String tableName, String referencedTableName, int level) { + this.tableName = tableName; + this.referencedTableName = referencedTableName; + this.level = level; + } + boolean references(String tableName) { + return tableName.equals(referencedTableName); + } } diff --git a/src/main/java/org/qstd/ReferencedTableSet.java b/src/main/java/org/qstd/ReferencedTableSet.java index efb1665..7495281 100644 --- a/src/main/java/org/qstd/ReferencedTableSet.java +++ b/src/main/java/org/qstd/ReferencedTableSet.java @@ -12,27 +12,26 @@ */ package org.qstd; -import java.util.Collection; - import static java.util.Collections.emptyList; +import java.util.Collection; + public class ReferencedTableSet { - public static final ReferencedTableSet NONE = new ReferencedTableSet(emptyList()); + public static final ReferencedTableSet NONE = new ReferencedTableSet(emptyList()); - private final Collection referencedTablesOfTable; + private final Collection referencedTablesOfTable; - public ReferencedTableSet(Collection referencedTablesOfTable) { - this.referencedTablesOfTable = referencedTablesOfTable; - } + public ReferencedTableSet(Collection referencedTablesOfTable) { + this.referencedTablesOfTable = referencedTablesOfTable; + } - boolean referencesTable(String tableName) { - for (ReferencedTable referencedTable : referencedTablesOfTable) { - if (referencedTable.references(tableName)) { - return true; - } - } - return false; + boolean referencesTable(String tableName) { + for (ReferencedTable referencedTable : referencedTablesOfTable) { + if (referencedTable.references(tableName)) { + return true; + } } - + return false; + } } diff --git a/src/main/java/org/qstd/ReferencedTablesFinder.java b/src/main/java/org/qstd/ReferencedTablesFinder.java index fee72bd..877a7e9 100644 --- a/src/main/java/org/qstd/ReferencedTablesFinder.java +++ b/src/main/java/org/qstd/ReferencedTablesFinder.java @@ -14,6 +14,5 @@ public interface ReferencedTablesFinder { - ReferencedTableSet findReferencedTablesOf(String tableName); - + ReferencedTableSet findReferencedTablesOf(String tableName); } diff --git a/src/main/java/org/qstd/RowFinder.java b/src/main/java/org/qstd/RowFinder.java index 1760eae..5136806 100644 --- a/src/main/java/org/qstd/RowFinder.java +++ b/src/main/java/org/qstd/RowFinder.java @@ -12,49 +12,47 @@ */ package org.qstd; -import org.qstd.dbtype.DatabaseType; - -import javax.sql.DataSource; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Collection; +import javax.sql.DataSource; +import org.qstd.dbtype.DatabaseType; class RowFinder { - private final DataSource dataSource; + private final DataSource dataSource; - private final DatabaseType dbType; + private final DatabaseType dbType; - RowFinder(DataSource dataSource, DatabaseType dbType) { - this.dataSource = dataSource; - this.dbType = dbType; - } + RowFinder(DataSource dataSource, DatabaseType dbType) { + this.dataSource = dataSource; + this.dbType = dbType; + } - DatasetRow findOneRowFrom(String tableName - , Collection columnNamesToSearch - , DatasetRow rowToSearch) { - - SqlQuery missingColumnValuesQuery = - SqlQuery.buildFromRow(columnNamesToSearch, rowToSearch, dbType); - - DatasetRow missingColumnValues = DatasetRow.ofTable(tableName); - try (Connection connection = dataSource.getConnection(); - PreparedStatement missingColumnStatement = PreparedStatementBuilder.buildFrom(missingColumnValuesQuery, connection)) { - ResultSet queryResult = missingColumnStatement.executeQuery(); - - queryResult.next(); // We keep only the first row found - - for (String missingColumnName : columnNamesToSearch) { - Object columnValue = queryResult.getObject(missingColumnName); - missingColumnValues.addColumnValue(missingColumnName, columnValue); - } - } catch (SQLException sqlException) { - System.err.println("Unable to execute " + missingColumnValuesQuery); - sqlException.printStackTrace(); - } - return missingColumnValues; - } + DatasetRow findOneRowFrom( + String tableName, Collection columnNamesToSearch, DatasetRow rowToSearch) { + + SqlQuery missingColumnValuesQuery = + SqlQuery.buildFromRow(columnNamesToSearch, rowToSearch, dbType); + + DatasetRow missingColumnValues = DatasetRow.ofTable(tableName); + try (Connection connection = dataSource.getConnection(); + PreparedStatement missingColumnStatement = + PreparedStatementBuilder.buildFrom(missingColumnValuesQuery, connection)) { + ResultSet queryResult = missingColumnStatement.executeQuery(); + queryResult.next(); // We keep only the first row found + + for (String missingColumnName : columnNamesToSearch) { + Object columnValue = queryResult.getObject(missingColumnName); + missingColumnValues.addColumnValue(missingColumnName, columnValue); + } + } catch (SQLException sqlException) { + System.err.println("Unable to execute " + missingColumnValuesQuery); + sqlException.printStackTrace(); + } + return missingColumnValues; + } } diff --git a/src/main/java/org/qstd/SelectTransformer.java b/src/main/java/org/qstd/SelectTransformer.java index 52d95c6..7d9bc9d 100644 --- a/src/main/java/org/qstd/SelectTransformer.java +++ b/src/main/java/org/qstd/SelectTransformer.java @@ -16,13 +16,13 @@ interface SelectTransformer { - SelectTransformer NO_SELECT_TRANSFORMER = new SelectTransformer() { + SelectTransformer NO_SELECT_TRANSFORMER = + new SelectTransformer() { @Override public Optional toSelect(SqlQuery sqlQuery) { - return Optional.empty(); + return Optional.empty(); } - }; - - Optional toSelect(SqlQuery sqlQuery); + }; + Optional toSelect(SqlQuery sqlQuery); } diff --git a/src/main/java/org/qstd/SelectTransformerFactory.java b/src/main/java/org/qstd/SelectTransformerFactory.java index 7786a8f..fc14ec9 100644 --- a/src/main/java/org/qstd/SelectTransformerFactory.java +++ b/src/main/java/org/qstd/SelectTransformerFactory.java @@ -12,6 +12,7 @@ */ package org.qstd; +import java.util.Optional; import net.sf.jsqlparser.JSQLParserException; import net.sf.jsqlparser.parser.CCJSqlParserUtil; import net.sf.jsqlparser.statement.Statement; @@ -19,49 +20,44 @@ import net.sf.jsqlparser.statement.select.Select; import net.sf.jsqlparser.statement.update.Update; -import java.util.Optional; - class SelectTransformerFactory { - private SelectTransformerFactory() { - } - - private static final SelectTransformer SELECT_TO_SELECT_TRANSFORMER = + private SelectTransformerFactory() {} - new SelectTransformer() { - @Override - public Optional toSelect(SqlQuery sqlQuery) { - return Optional.of(sqlQuery); - } - }; + private static final SelectTransformer SELECT_TO_SELECT_TRANSFORMER = + new SelectTransformer() { + @Override + public Optional toSelect(SqlQuery sqlQuery) { + return Optional.of(sqlQuery); + } + }; - static SelectTransformer createSelectTransformer(SqlQuery sqlQuery) { + static SelectTransformer createSelectTransformer(SqlQuery sqlQuery) { - String sqlQueryAsString = sqlQuery.getQueryAsString(); - Statement statement = parse(sqlQueryAsString); + String sqlQueryAsString = sqlQuery.getQueryAsString(); + Statement statement = parse(sqlQueryAsString); - if(statement instanceof Select) { - return SELECT_TO_SELECT_TRANSFORMER; - } - if(statement instanceof Update) { - Update update = (Update) statement; - return new UpdateToSelectTransformer(update); - } - if(statement instanceof Delete) { - Delete delete = (Delete) statement; - return new DeleteToSelectTransformer(delete); - } - - return SelectTransformer.NO_SELECT_TRANSFORMER; + if (statement instanceof Select) { + return SELECT_TO_SELECT_TRANSFORMER; } - - private static Statement parse(String sqlQuery) { - try { - return CCJSqlParserUtil.parse(sqlQuery); - } catch (JSQLParserException e) { - e.printStackTrace(); - return null; - } + if (statement instanceof Update) { + Update update = (Update) statement; + return new UpdateToSelectTransformer(update); } + if (statement instanceof Delete) { + Delete delete = (Delete) statement; + return new DeleteToSelectTransformer(delete); + } + + return SelectTransformer.NO_SELECT_TRANSFORMER; + } + private static Statement parse(String sqlQuery) { + try { + return CCJSqlParserUtil.parse(sqlQuery); + } catch (JSQLParserException e) { + e.printStackTrace(); + return null; + } + } } diff --git a/src/main/java/org/qstd/SqlQuery.java b/src/main/java/org/qstd/SqlQuery.java index 472f226..bf8ea64 100644 --- a/src/main/java/org/qstd/SqlQuery.java +++ b/src/main/java/org/qstd/SqlQuery.java @@ -12,82 +12,81 @@ */ package org.qstd; -import org.qstd.dbtype.DatabaseType; +import static java.util.stream.Collectors.joining; import java.util.*; +import org.qstd.dbtype.DatabaseType; -import static java.util.stream.Collectors.joining; - -/** - * Class to represent an SQL query - */ +/** Class to represent an SQL query */ public class SqlQuery { - private final String queryAsString; - - private final List parameters; - - /** - * Constructor to instantiate an SQL Query from an SQL query as String - * @param queryAsString An SQL query as string - */ - public SqlQuery(String queryAsString) { - this.queryAsString = queryAsString; - this.parameters = Collections.emptyList(); - } - - /** - * Constructor to instantiate an SQL query from an SQL query with bind parameters and its bind parameter values - * @param queryAsString An SQL query as String with bind parameters - * @param parameters Bind parameter values - */ - public SqlQuery(String queryAsString, List parameters) { - this.queryAsString = queryAsString; - this.parameters = parameters; - } - - static SqlQuery buildFromRow(DatasetRow rowToSearch, DatabaseType dbType) { - Set columnNames = rowToSearch.getColumnNames(); - return buildFromRow(columnNames, rowToSearch, dbType); - - } - - static SqlQuery buildFromRow(Collection columnNamesToSearch - , DatasetRow rowToSearch - , DatabaseType dbType) { - Map valuesToMatch = rowToSearch.getColumnValueByColumnName(); - String whereConditions = - valuesToMatch.entrySet() - .stream() - .map(entry -> { - String columnName = entry.getKey(); - return columnName - + (entry.getValue() == null - ? " IS NULL" - : "=" + ColumnValueFormatter.INSTANCE - .formatColumnValue(entry.getValue(), dbType)); - }) - .collect(joining(" AND ")); - String queryAsString = - "SELECT " - + String.join(", ", columnNamesToSearch) - + " FROM " + rowToSearch.getTableName() - + " WHERE " + whereConditions; - return new SqlQuery(queryAsString); - - } - - @Override - public String toString() { - return getQueryAsString(); - } - - String getQueryAsString() { - return queryAsString; - } - - List getParameters() { - return parameters; - } - + private final String queryAsString; + + private final List parameters; + + /** + * Constructor to instantiate an SQL Query from an SQL query as String + * + * @param queryAsString An SQL query as string + */ + public SqlQuery(String queryAsString) { + this.queryAsString = queryAsString; + this.parameters = Collections.emptyList(); + } + + /** + * Constructor to instantiate an SQL query from an SQL query with bind parameters and its bind + * parameter values + * + * @param queryAsString An SQL query as String with bind parameters + * @param parameters Bind parameter values + */ + public SqlQuery(String queryAsString, List parameters) { + this.queryAsString = queryAsString; + this.parameters = parameters; + } + + static SqlQuery buildFromRow(DatasetRow rowToSearch, DatabaseType dbType) { + Set columnNames = rowToSearch.getColumnNames(); + return buildFromRow(columnNames, rowToSearch, dbType); + } + + static SqlQuery buildFromRow( + Collection columnNamesToSearch, DatasetRow rowToSearch, DatabaseType dbType) { + Map valuesToMatch = rowToSearch.getColumnValueByColumnName(); + String whereConditions = + valuesToMatch.entrySet().stream() + .map( + entry -> { + String columnName = entry.getKey(); + return columnName + + (entry.getValue() == null + ? " IS NULL" + : "=" + + ColumnValueFormatter.INSTANCE.formatColumnValue( + entry.getValue(), dbType)); + }) + .collect(joining(" AND ")); + String queryAsString = + "SELECT " + + String.join(", ", columnNamesToSearch) + + " FROM " + + rowToSearch.getTableName() + + " WHERE " + + whereConditions; + return new SqlQuery(queryAsString); + } + + @Override + public String toString() { + return getQueryAsString(); + } + + String getQueryAsString() { + return queryAsString; + } + + List getParameters() { + return parameters; + } } diff --git a/src/main/java/org/qstd/UpdateToSelectTransformer.java b/src/main/java/org/qstd/UpdateToSelectTransformer.java index 15f2bc2..73e4a4e 100644 --- a/src/main/java/org/qstd/UpdateToSelectTransformer.java +++ b/src/main/java/org/qstd/UpdateToSelectTransformer.java @@ -12,66 +12,62 @@ */ package org.qstd; -import net.sf.jsqlparser.expression.Expression; -import net.sf.jsqlparser.schema.Column; -import net.sf.jsqlparser.statement.update.Update; +import static java.util.stream.Collectors.toList; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Optional; - -import static java.util.stream.Collectors.toList; +import net.sf.jsqlparser.expression.Expression; +import net.sf.jsqlparser.schema.Column; +import net.sf.jsqlparser.statement.update.Update; class UpdateToSelectTransformer implements SelectTransformer { - private Update updateStatement; - - UpdateToSelectTransformer(Update update) { - updateStatement = update; - } + private Update updateStatement; - @Override - public Optional toSelect(SqlQuery sqlQuery) { - String tableName = updateStatement.getTable().getName(); - String selectAsString = " SELECT " + findSelectedColumnsSeparatedWithCommas() - + " FROM " + tableName - + findWhereClauseIfExists(); - List parameters = sqlQuery.getParameters(); - SqlQuery selectQuery = new SqlQuery(selectAsString, parameters); - return Optional.of(selectQuery); - } + UpdateToSelectTransformer(Update update) { + updateStatement = update; + } - private String findSelectedColumnsSeparatedWithCommas() { - Collection columns = findColumnsToSelect(); - return String.join(", ", columns); - } + @Override + public Optional toSelect(SqlQuery sqlQuery) { + String tableName = updateStatement.getTable().getName(); + String selectAsString = + " SELECT " + + findSelectedColumnsSeparatedWithCommas() + + " FROM " + + tableName + + findWhereClauseIfExists(); + List parameters = sqlQuery.getParameters(); + SqlQuery selectQuery = new SqlQuery(selectAsString, parameters); + return Optional.of(selectQuery); + } - private Collection findColumnsToSelect() { - Collection columnNames = findUpdatedColumnNames(); - Collection columnsToSelect = new ArrayList<>(columnNames); - Collection whereColumnNames = findWhereColumnNames(); - columnsToSelect.addAll(whereColumnNames); - return columnsToSelect; - } + private String findSelectedColumnsSeparatedWithCommas() { + Collection columns = findColumnsToSelect(); + return String.join(", ", columns); + } - private List findUpdatedColumnNames() { - return updateStatement - .getColumns() - .stream() - .map(Column::getColumnName) - .collect(toList()); - } + private Collection findColumnsToSelect() { + Collection columnNames = findUpdatedColumnNames(); + Collection columnsToSelect = new ArrayList<>(columnNames); + Collection whereColumnNames = findWhereColumnNames(); + columnsToSelect.addAll(whereColumnNames); + return columnsToSelect; + } - private String findWhereClauseIfExists() { - Expression whereExpression = updateStatement.getWhere(); - return whereExpression == null ? "" - :" WHERE " + whereExpression; - } + private List findUpdatedColumnNames() { + return updateStatement.getColumns().stream().map(Column::getColumnName).collect(toList()); + } - private Collection findWhereColumnNames() { - Expression whereExpression = updateStatement.getWhere(); - return ColumnNamesExtractor.INSTANCE.findColumnNamesOf(whereExpression); - } + private String findWhereClauseIfExists() { + Expression whereExpression = updateStatement.getWhere(); + return whereExpression == null ? "" : " WHERE " + whereExpression; + } + private Collection findWhereColumnNames() { + Expression whereExpression = updateStatement.getWhere(); + return ColumnNamesExtractor.INSTANCE.findColumnNamesOf(whereExpression); + } } diff --git a/src/main/java/org/qstd/dbtype/BaseColumnOrdersFinder.java b/src/main/java/org/qstd/dbtype/BaseColumnOrdersFinder.java index 5fbda67..24249ad 100644 --- a/src/main/java/org/qstd/dbtype/BaseColumnOrdersFinder.java +++ b/src/main/java/org/qstd/dbtype/BaseColumnOrdersFinder.java @@ -12,11 +12,6 @@ */ package org.qstd.dbtype; -import org.qstd.ColumnOrdersFinder; -import org.qstd.PreparedStatementBuilder; -import org.qstd.SqlQuery; - -import javax.sql.DataSource; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -24,38 +19,42 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import javax.sql.DataSource; +import org.qstd.ColumnOrdersFinder; +import org.qstd.PreparedStatementBuilder; +import org.qstd.SqlQuery; class BaseColumnOrdersFinder implements ColumnOrdersFinder { - private final DataSource dataSource; - - private final SqlQuery notNullColumnsQuery; - - BaseColumnOrdersFinder(DataSource dataSource, SqlQuery notNullColumnsQuery) { - this.dataSource = dataSource; - this.notNullColumnsQuery = notNullColumnsQuery; + private final DataSource dataSource; + + private final SqlQuery notNullColumnsQuery; + + BaseColumnOrdersFinder(DataSource dataSource, SqlQuery notNullColumnsQuery) { + this.dataSource = dataSource; + this.notNullColumnsQuery = notNullColumnsQuery; + } + + @Override + public List findDatabaseColumnOrdersOf(String tableName) { + try (Connection connection = dataSource.getConnection(); + PreparedStatement columnOrderStatement = + PreparedStatementBuilder.buildFrom(notNullColumnsQuery, connection)) { + columnOrderStatement.setString(1, tableName); + ResultSet queryResult = columnOrderStatement.executeQuery(); + return findColumnOrderFrom(queryResult); + } catch (SQLException sqlException) { + sqlException.printStackTrace(); } - - @Override - public List findDatabaseColumnOrdersOf(String tableName) { - try (Connection connection = dataSource.getConnection(); - PreparedStatement columnOrderStatement = PreparedStatementBuilder.buildFrom(notNullColumnsQuery, connection)) { - columnOrderStatement.setString(1, tableName); - ResultSet queryResult = columnOrderStatement.executeQuery(); - return findColumnOrderFrom(queryResult); - } catch (SQLException sqlException) { - sqlException.printStackTrace(); - } - return Collections.emptyList(); + return Collections.emptyList(); + } + + private List findColumnOrderFrom(ResultSet queryResult) throws SQLException { + List columnOrder = new ArrayList<>(); + while (queryResult.next()) { + String columnName = queryResult.getString(3); + columnOrder.add(columnName); } - - private List findColumnOrderFrom(ResultSet queryResult) throws SQLException { - List columnOrder = new ArrayList<>(); - while (queryResult.next()) { - String columnName = queryResult.getString(3); - columnOrder.add(columnName); - } - return columnOrder; - } - + return columnOrder; + } } diff --git a/src/main/java/org/qstd/dbtype/BaseColumnsMappingsFinder.java b/src/main/java/org/qstd/dbtype/BaseColumnsMappingsFinder.java index a9dced1..47fba5b 100644 --- a/src/main/java/org/qstd/dbtype/BaseColumnsMappingsFinder.java +++ b/src/main/java/org/qstd/dbtype/BaseColumnsMappingsFinder.java @@ -12,69 +12,65 @@ */ package org.qstd.dbtype; -import org.qstd.*; - -import javax.sql.DataSource; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; +import javax.sql.DataSource; +import org.qstd.*; class BaseColumnsMappingsFinder implements ColumnsMappingsFinder { - private final DataSource dataSource; + private final DataSource dataSource; - private final SqlQuery columnsMappingQuery; + private final SqlQuery columnsMappingQuery; - public BaseColumnsMappingsFinder(DataSource dataSource, SqlQuery columnsMappingQuery) { - this.dataSource = dataSource; - this.columnsMappingQuery = columnsMappingQuery; - } + public BaseColumnsMappingsFinder(DataSource dataSource, SqlQuery columnsMappingQuery) { + this.dataSource = dataSource; + this.columnsMappingQuery = columnsMappingQuery; + } - @Override - public ColumnsMappingGroup findColumnsMappingsOf(String tableName) { + @Override + public ColumnsMappingGroup findColumnsMappingsOf(String tableName) { - Collection columnsMappings = new ArrayList<>(); + Collection columnsMappings = new ArrayList<>(); - try (Connection connection = dataSource.getConnection(); - PreparedStatement referencedTablesStatement = PreparedStatementBuilder.buildFrom(columnsMappingQuery, connection)) { - referencedTablesStatement.setString(1, tableName); + try (Connection connection = dataSource.getConnection(); + PreparedStatement referencedTablesStatement = + PreparedStatementBuilder.buildFrom(columnsMappingQuery, connection)) { + referencedTablesStatement.setString(1, tableName); - ResultSet queryResult = referencedTablesStatement.executeQuery(); + ResultSet queryResult = referencedTablesStatement.executeQuery(); - while (queryResult.next()) { - ColumnsMapping columnsMapping = buildColumnsMappingFrom(queryResult); - columnsMappings.add(columnsMapping); - } - - - } catch (SQLException sqlException) { - sqlException.printStackTrace(); - } - - - return new ColumnsMappingGroup(columnsMappings); + while (queryResult.next()) { + ColumnsMapping columnsMapping = buildColumnsMappingFrom(queryResult); + columnsMappings.add(columnsMapping); + } + } catch (SQLException sqlException) { + sqlException.printStackTrace(); } - private ColumnsMapping buildColumnsMappingFrom(ResultSet queryResult) throws SQLException { - String firstTableSchema = queryResult.getString(1); - String firstTableName = queryResult.getString(2); - String firstTableColumn = queryResult.getString(3); + return new ColumnsMappingGroup(columnsMappings); + } - ColumnMappingPart columnMappingPart1 - = new ColumnMappingPart(firstTableSchema, firstTableName, firstTableColumn); + private ColumnsMapping buildColumnsMappingFrom(ResultSet queryResult) throws SQLException { + String firstTableSchema = queryResult.getString(1); + String firstTableName = queryResult.getString(2); + String firstTableColumn = queryResult.getString(3); - String secondTableSchema = queryResult.getString(4); - String secondTableName = queryResult.getString(5); - String secondTableColumn = queryResult.getString(6); + ColumnMappingPart columnMappingPart1 = + new ColumnMappingPart(firstTableSchema, firstTableName, firstTableColumn); - ColumnMappingPart columnMappingPart2 - = new ColumnMappingPart(secondTableSchema, secondTableName, secondTableColumn); + String secondTableSchema = queryResult.getString(4); + String secondTableName = queryResult.getString(5); + String secondTableColumn = queryResult.getString(6); - return new ColumnsMapping(columnMappingPart1, columnMappingPart2); - } + ColumnMappingPart columnMappingPart2 = + new ColumnMappingPart(secondTableSchema, secondTableName, secondTableColumn); + return new ColumnsMapping(columnMappingPart1, columnMappingPart2); + } } diff --git a/src/main/java/org/qstd/dbtype/BaseNotNullColumnsFinder.java b/src/main/java/org/qstd/dbtype/BaseNotNullColumnsFinder.java index 44bcc4f..c65b0d9 100644 --- a/src/main/java/org/qstd/dbtype/BaseNotNullColumnsFinder.java +++ b/src/main/java/org/qstd/dbtype/BaseNotNullColumnsFinder.java @@ -12,11 +12,6 @@ */ package org.qstd.dbtype; -import org.qstd.NotNullColumnsFinder; -import org.qstd.PreparedStatementBuilder; -import org.qstd.SqlQuery; - -import javax.sql.DataSource; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -25,38 +20,42 @@ import java.util.Collection; import java.util.Collections; import java.util.List; +import javax.sql.DataSource; +import org.qstd.NotNullColumnsFinder; +import org.qstd.PreparedStatementBuilder; +import org.qstd.SqlQuery; public class BaseNotNullColumnsFinder implements NotNullColumnsFinder { - private final DataSource dataSource; - - private final SqlQuery notNullColumnsQuery; - - BaseNotNullColumnsFinder(DataSource dataSource, SqlQuery notNullColumnsQuery) { - this.dataSource = dataSource; - this.notNullColumnsQuery = notNullColumnsQuery; + private final DataSource dataSource; + + private final SqlQuery notNullColumnsQuery; + + BaseNotNullColumnsFinder(DataSource dataSource, SqlQuery notNullColumnsQuery) { + this.dataSource = dataSource; + this.notNullColumnsQuery = notNullColumnsQuery; + } + + @Override + public Collection findNotNullColumnsOf(String tableName) { + try (Connection connection = dataSource.getConnection(); + PreparedStatement columnOrderStatement = + PreparedStatementBuilder.buildFrom(notNullColumnsQuery, connection)) { + columnOrderStatement.setString(1, tableName); + ResultSet queryResult = columnOrderStatement.executeQuery(); + return findNotNullColumnsFrom(queryResult); + } catch (SQLException sqlException) { + sqlException.printStackTrace(); } - - @Override - public Collection findNotNullColumnsOf(String tableName) { - try (Connection connection = dataSource.getConnection(); - PreparedStatement columnOrderStatement = PreparedStatementBuilder.buildFrom(notNullColumnsQuery, connection)) { - columnOrderStatement.setString(1, tableName); - ResultSet queryResult = columnOrderStatement.executeQuery(); - return findNotNullColumnsFrom(queryResult); - } catch (SQLException sqlException) { - sqlException.printStackTrace(); - } - return Collections.emptyList(); + return Collections.emptyList(); + } + + private List findNotNullColumnsFrom(ResultSet resultSet) throws SQLException { + List notNullColumns = new ArrayList<>(); + while (resultSet.next()) { + String columnName = resultSet.getString(3); + notNullColumns.add(columnName); } - - private List findNotNullColumnsFrom(ResultSet resultSet) throws SQLException { - List notNullColumns = new ArrayList<>(); - while (resultSet.next()) { - String columnName = resultSet.getString(3); - notNullColumns.add(columnName); - } - return notNullColumns; - } - + return notNullColumns; + } } diff --git a/src/main/java/org/qstd/dbtype/BasePrimaryKeyColumnsFinder.java b/src/main/java/org/qstd/dbtype/BasePrimaryKeyColumnsFinder.java index c368c91..6a93fab 100644 --- a/src/main/java/org/qstd/dbtype/BasePrimaryKeyColumnsFinder.java +++ b/src/main/java/org/qstd/dbtype/BasePrimaryKeyColumnsFinder.java @@ -12,51 +12,49 @@ */ package org.qstd.dbtype; -import org.qstd.PreparedStatementBuilder; -import org.qstd.PrimaryKeyColumnsFinder; -import org.qstd.SqlQuery; - -import javax.sql.DataSource; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; +import javax.sql.DataSource; +import org.qstd.PreparedStatementBuilder; +import org.qstd.PrimaryKeyColumnsFinder; +import org.qstd.SqlQuery; class BasePrimaryKeyColumnsFinder implements PrimaryKeyColumnsFinder { - private final DataSource dataSource; - - private final SqlQuery primaryKeyColumnsQuery; - - public BasePrimaryKeyColumnsFinder(DataSource dataSource, SqlQuery primaryKeyColumnsQuery) { - this.dataSource = dataSource; - this.primaryKeyColumnsQuery = primaryKeyColumnsQuery; - } + private final DataSource dataSource; - @Override - public List findPrimaryColumnsOf(String tableName) { + private final SqlQuery primaryKeyColumnsQuery; - List primaryKeyColumns = new ArrayList<>(); + public BasePrimaryKeyColumnsFinder(DataSource dataSource, SqlQuery primaryKeyColumnsQuery) { + this.dataSource = dataSource; + this.primaryKeyColumnsQuery = primaryKeyColumnsQuery; + } - try (Connection connection = dataSource.getConnection(); - PreparedStatement primaryKeyColumnsStatement = PreparedStatementBuilder.buildFrom(primaryKeyColumnsQuery, connection)) { + @Override + public List findPrimaryColumnsOf(String tableName) { - primaryKeyColumnsStatement.setString(1, tableName); - ResultSet queryResult = primaryKeyColumnsStatement.executeQuery(); + List primaryKeyColumns = new ArrayList<>(); - while(queryResult.next()) { - String column = queryResult.getString(4); - primaryKeyColumns.add(column); - } + try (Connection connection = dataSource.getConnection(); + PreparedStatement primaryKeyColumnsStatement = + PreparedStatementBuilder.buildFrom(primaryKeyColumnsQuery, connection)) { - } catch (SQLException sqlException) { - sqlException.printStackTrace(); - } + primaryKeyColumnsStatement.setString(1, tableName); + ResultSet queryResult = primaryKeyColumnsStatement.executeQuery(); - return primaryKeyColumns; + while (queryResult.next()) { + String column = queryResult.getString(4); + primaryKeyColumns.add(column); + } + } catch (SQLException sqlException) { + sqlException.printStackTrace(); } + return primaryKeyColumns; + } } diff --git a/src/main/java/org/qstd/dbtype/BaseReferencedTablesFinder.java b/src/main/java/org/qstd/dbtype/BaseReferencedTablesFinder.java index f2979a5..2c6f470 100644 --- a/src/main/java/org/qstd/dbtype/BaseReferencedTablesFinder.java +++ b/src/main/java/org/qstd/dbtype/BaseReferencedTablesFinder.java @@ -12,55 +12,52 @@ */ package org.qstd.dbtype; -import org.qstd.*; - -import javax.sql.DataSource; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; +import javax.sql.DataSource; +import org.qstd.*; class BaseReferencedTablesFinder implements ReferencedTablesFinder { - private final DataSource dataSource; + private final DataSource dataSource; - private final SqlQuery referencedTableQuery; + private final SqlQuery referencedTableQuery; - BaseReferencedTablesFinder(DataSource dataSource, SqlQuery referencedTableQuery) { - this.dataSource = dataSource; - this.referencedTableQuery = referencedTableQuery; - } - - @Override - public ReferencedTableSet findReferencedTablesOf(String tableName) { + BaseReferencedTablesFinder(DataSource dataSource, SqlQuery referencedTableQuery) { + this.dataSource = dataSource; + this.referencedTableQuery = referencedTableQuery; + } - Collection referencedTables = new ArrayList<>(); - try (Connection connection = dataSource.getConnection(); - PreparedStatement referencedTablesStatement = PreparedStatementBuilder.buildFrom(referencedTableQuery, connection)) { + @Override + public ReferencedTableSet findReferencedTablesOf(String tableName) { - referencedTablesStatement.setString(1, tableName); - ResultSet queryResult = referencedTablesStatement.executeQuery(); + Collection referencedTables = new ArrayList<>(); + try (Connection connection = dataSource.getConnection(); + PreparedStatement referencedTablesStatement = + PreparedStatementBuilder.buildFrom(referencedTableQuery, connection)) { - while(queryResult.next()) { - ReferencedTable referencedTable = buildReferencedTableFrom(queryResult); - referencedTables.add(referencedTable); - } + referencedTablesStatement.setString(1, tableName); + ResultSet queryResult = referencedTablesStatement.executeQuery(); - } catch (SQLException sqlException) { - sqlException.printStackTrace(); - } - return new ReferencedTableSet(referencedTables); - } + while (queryResult.next()) { + ReferencedTable referencedTable = buildReferencedTableFrom(queryResult); + referencedTables.add(referencedTable); + } - private ReferencedTable buildReferencedTableFrom(ResultSet queryResult) throws SQLException { - String resultTableName = queryResult.getString(1); - String referencedTableName = queryResult.getString(2); - int level = queryResult.getInt(3); - return new ReferencedTable(resultTableName - , referencedTableName - , level); + } catch (SQLException sqlException) { + sqlException.printStackTrace(); } - + return new ReferencedTableSet(referencedTables); + } + + private ReferencedTable buildReferencedTableFrom(ResultSet queryResult) throws SQLException { + String resultTableName = queryResult.getString(1); + String referencedTableName = queryResult.getString(2); + int level = queryResult.getInt(3); + return new ReferencedTable(resultTableName, referencedTableName, level); + } } diff --git a/src/main/java/org/qstd/dbtype/DatabaseMetadataFinderFactory.java b/src/main/java/org/qstd/dbtype/DatabaseMetadataFinderFactory.java index e54e842..d8c0dfb 100644 --- a/src/main/java/org/qstd/dbtype/DatabaseMetadataFinderFactory.java +++ b/src/main/java/org/qstd/dbtype/DatabaseMetadataFinderFactory.java @@ -12,53 +12,50 @@ */ package org.qstd.dbtype; -import org.qstd.DatabaseMetadataFinder; +import static org.qstd.dbtype.DatabaseType.*; import javax.sql.DataSource; +import org.qstd.DatabaseMetadataFinder; -import static org.qstd.dbtype.DatabaseType.*; - -/** - * Factory to create an instance of {@link org.qstd.DatabaseMetadataFinder}. - */ +/** Factory to create an instance of {@link org.qstd.DatabaseMetadataFinder}. */ public class DatabaseMetadataFinderFactory { - private DatabaseMetadataFinderFactory() { } - - /** - * Creates a DatabaseMetadataFinder - * @param dataSource A data source - * @param dbType A database type - * @return An instance of DatabaseMetadataFinder - */ - public static DatabaseMetadataFinder createDatabaseMetadataFinderFrom(DataSource dataSource, DatabaseType dbType) { + private DatabaseMetadataFinderFactory() {} - if(dbType.equals(H2)) { - return new H2MetadataFinder(dataSource); - } + /** + * Creates a DatabaseMetadataFinder + * + * @param dataSource A data source + * @param dbType A database type + * @return An instance of DatabaseMetadataFinder + */ + public static DatabaseMetadataFinder createDatabaseMetadataFinderFrom( + DataSource dataSource, DatabaseType dbType) { - if(dbType.equals(HSQLDB)) { - return new HsqlDbMetadataFinder(dataSource); - } - - if(dbType.equals(POSTGRE_SQL)) { - return new PostgreSqlMetadataFinder(dataSource); - } + if (dbType.equals(H2)) { + return new H2MetadataFinder(dataSource); + } - if (dbType.equals(MARIA_DB) || dbType.equals(MY_SQL)) { - return new MariaDBMySQLMetadataFinder(dataSource); - } + if (dbType.equals(HSQLDB)) { + return new HsqlDbMetadataFinder(dataSource); + } - if(dbType.equals(MICROSOFT_SQL_SERVER)) { - return new MSSQLServerMetadataFinder(dataSource); - } + if (dbType.equals(POSTGRE_SQL)) { + return new PostgreSqlMetadataFinder(dataSource); + } - if(dbType.equals(ORACLE)) { - return new OracleMetadataFinder(dataSource); - } + if (dbType.equals(MARIA_DB) || dbType.equals(MY_SQL)) { + return new MariaDBMySQLMetadataFinder(dataSource); + } - return new DefaultDatabaseMetadataFinder(dataSource); + if (dbType.equals(MICROSOFT_SQL_SERVER)) { + return new MSSQLServerMetadataFinder(dataSource); + } + if (dbType.equals(ORACLE)) { + return new OracleMetadataFinder(dataSource); } + return new DefaultDatabaseMetadataFinder(dataSource); + } } diff --git a/src/main/java/org/qstd/dbtype/DatabaseMetadataFinderWithCache.java b/src/main/java/org/qstd/dbtype/DatabaseMetadataFinderWithCache.java index 5e2a785..4ff7a97 100644 --- a/src/main/java/org/qstd/dbtype/DatabaseMetadataFinderWithCache.java +++ b/src/main/java/org/qstd/dbtype/DatabaseMetadataFinderWithCache.java @@ -12,68 +12,74 @@ */ package org.qstd.dbtype; -import org.qstd.ColumnsMappingGroup; -import org.qstd.DatabaseMetadataFinder; -import org.qstd.ReferencedTableSet; - import java.util.Collection; import java.util.List; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; +import org.qstd.ColumnsMappingGroup; +import org.qstd.DatabaseMetadataFinder; +import org.qstd.ReferencedTableSet; -/** - * A DatabaseMetadataFinder caching method calls - */ +/** A DatabaseMetadataFinder caching method calls */ public class DatabaseMetadataFinderWithCache implements DatabaseMetadataFinder { - private final DatabaseMetadataFinder delegate; - - private final ConcurrentHashMap> notNullColumnsByTableName = new ConcurrentHashMap<>(); - - private final ConcurrentHashMap> databaseColumnOrdersByTableName = new ConcurrentHashMap<>(); - - private final ConcurrentHashMap columnsMappingsByTableName = new ConcurrentHashMap<>(); - - private final ConcurrentHashMap referencedTableSetByTableName = new ConcurrentHashMap<>(); - - private final ConcurrentHashMap> primaryColumnsByTableName = new ConcurrentHashMap<>(); - - public DatabaseMetadataFinderWithCache(DatabaseMetadataFinder delegate) { - this.delegate = delegate; - } - - public static DatabaseMetadataFinder buildFrom(DatabaseMetadataFinder databaseMetadataFinder) { - return new DatabaseMetadataFinderWithCache(databaseMetadataFinder); - } - - @Override - public List findDatabaseColumnOrdersOf(String tableName) { - return databaseColumnOrdersByTableName.computeIfAbsent(tableName, t -> delegate.findDatabaseColumnOrdersOf(tableName)); - } - - @Override - public ColumnsMappingGroup findColumnsMappingsOf(String tableName) { - return columnsMappingsByTableName.computeIfAbsent(tableName, t -> delegate.findColumnsMappingsOf(tableName)); - } - - @Override - public Collection findNotNullColumnsOf(String tableName) { - return notNullColumnsByTableName.computeIfAbsent(tableName, t -> delegate.findNotNullColumnsOf(tableName)); - } - - @Override - public ReferencedTableSet findReferencedTablesOf(String tableName) { - return referencedTableSetByTableName.computeIfAbsent(tableName, t -> delegate.findReferencedTablesOf(tableName)); - } - - @Override - public List findPrimaryColumnsOf(String tableName) { - return primaryColumnsByTableName.computeIfAbsent(tableName, t -> delegate.findPrimaryColumnsOf(tableName)); - } - - @Override - public Function getFunctionToHaveMetadataTableName() { - return delegate.getFunctionToHaveMetadataTableName(); - } - + private final DatabaseMetadataFinder delegate; + + private final ConcurrentHashMap> notNullColumnsByTableName = + new ConcurrentHashMap<>(); + + private final ConcurrentHashMap> databaseColumnOrdersByTableName = + new ConcurrentHashMap<>(); + + private final ConcurrentHashMap columnsMappingsByTableName = + new ConcurrentHashMap<>(); + + private final ConcurrentHashMap referencedTableSetByTableName = + new ConcurrentHashMap<>(); + + private final ConcurrentHashMap> primaryColumnsByTableName = + new ConcurrentHashMap<>(); + + public DatabaseMetadataFinderWithCache(DatabaseMetadataFinder delegate) { + this.delegate = delegate; + } + + public static DatabaseMetadataFinder buildFrom(DatabaseMetadataFinder databaseMetadataFinder) { + return new DatabaseMetadataFinderWithCache(databaseMetadataFinder); + } + + @Override + public List findDatabaseColumnOrdersOf(String tableName) { + return databaseColumnOrdersByTableName.computeIfAbsent( + tableName, t -> delegate.findDatabaseColumnOrdersOf(tableName)); + } + + @Override + public ColumnsMappingGroup findColumnsMappingsOf(String tableName) { + return columnsMappingsByTableName.computeIfAbsent( + tableName, t -> delegate.findColumnsMappingsOf(tableName)); + } + + @Override + public Collection findNotNullColumnsOf(String tableName) { + return notNullColumnsByTableName.computeIfAbsent( + tableName, t -> delegate.findNotNullColumnsOf(tableName)); + } + + @Override + public ReferencedTableSet findReferencedTablesOf(String tableName) { + return referencedTableSetByTableName.computeIfAbsent( + tableName, t -> delegate.findReferencedTablesOf(tableName)); + } + + @Override + public List findPrimaryColumnsOf(String tableName) { + return primaryColumnsByTableName.computeIfAbsent( + tableName, t -> delegate.findPrimaryColumnsOf(tableName)); + } + + @Override + public Function getFunctionToHaveMetadataTableName() { + return delegate.getFunctionToHaveMetadataTableName(); + } } diff --git a/src/main/java/org/qstd/dbtype/DatabaseType.java b/src/main/java/org/qstd/dbtype/DatabaseType.java index 3664bd1..aa4aaa9 100644 --- a/src/main/java/org/qstd/dbtype/DatabaseType.java +++ b/src/main/java/org/qstd/dbtype/DatabaseType.java @@ -14,49 +14,44 @@ import static java.util.Arrays.stream; -/** - * Database type - */ +/** Database type */ public enum DatabaseType { - /**H2*/ - H2("jdbc:h2") - ,/**HSQLDB*/ - HSQLDB("jdbc:hsqldb") - ,/**MariaDB*/ - MARIA_DB("jdbc:mariadb") - ,/**Microsoft SQL Server*/ - MICROSOFT_SQL_SERVER("jdbc:sqlserver") - ,/**MySQL*/ - MY_SQL("jdbc:mysql") - ,/**Oracle*/ - ORACLE("jdbc:oracle") - ,/**PostgreSQL*/ - POSTGRE_SQL("jdbc:postgresql") - ,/**Other database type*/ - OTHER("jdbc:"); - - private final String jdbcUrlStart; - - DatabaseType(String jdbcUrlStart) { - this.jdbcUrlStart = jdbcUrlStart; - } - - /** - * Find the database type from the JDBC URL - * @param jdbcUrl A JDBC URL - * @return The database type - */ - public static DatabaseType findFromDbUrl(String jdbcUrl) { - DatabaseType[] databaseTypes = DatabaseType.values(); - return stream(databaseTypes) - .filter(dbType -> dbType.accept(jdbcUrl)) - .findFirst() - .get(); - } - - private boolean accept(String jdbcUrl) { - return jdbcUrl.startsWith(jdbcUrlStart); - } - + /** H2 */ + H2("jdbc:h2"), + /** HSQLDB */ + HSQLDB("jdbc:hsqldb"), + /** MariaDB */ + MARIA_DB("jdbc:mariadb"), + /** Microsoft SQL Server */ + MICROSOFT_SQL_SERVER("jdbc:sqlserver"), + /** MySQL */ + MY_SQL("jdbc:mysql"), + /** Oracle */ + ORACLE("jdbc:oracle"), + /** PostgreSQL */ + POSTGRE_SQL("jdbc:postgresql"), + /** Other database type */ + OTHER("jdbc:"); + + private final String jdbcUrlStart; + + DatabaseType(String jdbcUrlStart) { + this.jdbcUrlStart = jdbcUrlStart; + } + + /** + * Find the database type from the JDBC URL + * + * @param jdbcUrl A JDBC URL + * @return The database type + */ + public static DatabaseType findFromDbUrl(String jdbcUrl) { + DatabaseType[] databaseTypes = DatabaseType.values(); + return stream(databaseTypes).filter(dbType -> dbType.accept(jdbcUrl)).findFirst().get(); + } + + private boolean accept(String jdbcUrl) { + return jdbcUrl.startsWith(jdbcUrlStart); + } } diff --git a/src/main/java/org/qstd/dbtype/DatabaseUrlFinder.java b/src/main/java/org/qstd/dbtype/DatabaseUrlFinder.java index 7592192..6362199 100644 --- a/src/main/java/org/qstd/dbtype/DatabaseUrlFinder.java +++ b/src/main/java/org/qstd/dbtype/DatabaseUrlFinder.java @@ -12,30 +12,28 @@ */ package org.qstd.dbtype; -import javax.sql.DataSource; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.SQLException; +import javax.sql.DataSource; -/** - * Class helping to find database URL - */ +/** Class helping to find database URL */ public class DatabaseUrlFinder { - public static final DatabaseUrlFinder INSTANCE = new DatabaseUrlFinder(); + public static final DatabaseUrlFinder INSTANCE = new DatabaseUrlFinder(); - /** - * Find the database URL from a data source - * @param dataSource A data source - * @return The database URL - */ - public static String findDbUrlFrom(DataSource dataSource) { - try (Connection connection = dataSource.getConnection()) { - DatabaseMetaData metaData = connection.getMetaData(); - return metaData.getURL().toLowerCase(); - } catch (SQLException sqlException) { - throw new IllegalStateException(sqlException); - } + /** + * Find the database URL from a data source + * + * @param dataSource A data source + * @return The database URL + */ + public static String findDbUrlFrom(DataSource dataSource) { + try (Connection connection = dataSource.getConnection()) { + DatabaseMetaData metaData = connection.getMetaData(); + return metaData.getURL().toLowerCase(); + } catch (SQLException sqlException) { + throw new IllegalStateException(sqlException); } - + } } diff --git a/src/main/java/org/qstd/dbtype/DefaultColumnOrdersFinder.java b/src/main/java/org/qstd/dbtype/DefaultColumnOrdersFinder.java index c97f7f0..94baf78 100644 --- a/src/main/java/org/qstd/dbtype/DefaultColumnOrdersFinder.java +++ b/src/main/java/org/qstd/dbtype/DefaultColumnOrdersFinder.java @@ -12,32 +12,31 @@ */ package org.qstd.dbtype; +import java.util.List; +import javax.sql.DataSource; import org.qstd.ColumnOrdersFinder; import org.qstd.SqlQuery; -import javax.sql.DataSource; -import java.util.List; - class DefaultColumnOrdersFinder implements ColumnOrdersFinder { - private static final SqlQuery COLUMN_ORDER_QUERY = new SqlQuery( - " select table_schema," + - " table_name," + - " column_name," + - " ordinal_position as position" + - " from information_schema.columns" + - " where table_name=?" + - " order by position"); - - private BaseColumnOrdersFinder delegate; - - DefaultColumnOrdersFinder(DataSource dataSource) { - delegate = new BaseColumnOrdersFinder(dataSource, COLUMN_ORDER_QUERY); - } - - @Override - public List findDatabaseColumnOrdersOf(String tableName) { - return delegate.findDatabaseColumnOrdersOf(tableName); - } - + private static final SqlQuery COLUMN_ORDER_QUERY = + new SqlQuery( + " select table_schema," + + " table_name," + + " column_name," + + " ordinal_position as position" + + " from information_schema.columns" + + " where table_name=?" + + " order by position"); + + private BaseColumnOrdersFinder delegate; + + DefaultColumnOrdersFinder(DataSource dataSource) { + delegate = new BaseColumnOrdersFinder(dataSource, COLUMN_ORDER_QUERY); + } + + @Override + public List findDatabaseColumnOrdersOf(String tableName) { + return delegate.findDatabaseColumnOrdersOf(tableName); + } } diff --git a/src/main/java/org/qstd/dbtype/DefaultDatabaseMetadataFinder.java b/src/main/java/org/qstd/dbtype/DefaultDatabaseMetadataFinder.java index 26455a9..b90bf13 100644 --- a/src/main/java/org/qstd/dbtype/DefaultDatabaseMetadataFinder.java +++ b/src/main/java/org/qstd/dbtype/DefaultDatabaseMetadataFinder.java @@ -12,47 +12,44 @@ */ package org.qstd.dbtype; -import org.qstd.ColumnsMappingGroup; -import org.qstd.DatabaseMetadataFinder; -import org.qstd.ReferencedTableSet; - -import javax.sql.DataSource; import java.util.Collection; import java.util.Collections; import java.util.List; +import javax.sql.DataSource; +import org.qstd.ColumnsMappingGroup; +import org.qstd.DatabaseMetadataFinder; +import org.qstd.ReferencedTableSet; class DefaultDatabaseMetadataFinder implements DatabaseMetadataFinder { + private final DefaultNotNullColumnsFinder defaultNotNullColumnsFinder; - private final DefaultNotNullColumnsFinder defaultNotNullColumnsFinder; - - public DefaultDatabaseMetadataFinder(DataSource dataSource) { - this.defaultNotNullColumnsFinder = new DefaultNotNullColumnsFinder(dataSource); - } - - @Override - public List findDatabaseColumnOrdersOf(String tableName) { - return Collections.emptyList(); - } + public DefaultDatabaseMetadataFinder(DataSource dataSource) { + this.defaultNotNullColumnsFinder = new DefaultNotNullColumnsFinder(dataSource); + } - @Override - public ReferencedTableSet findReferencedTablesOf(String tableName) { - return ReferencedTableSet.NONE; - } + @Override + public List findDatabaseColumnOrdersOf(String tableName) { + return Collections.emptyList(); + } - @Override - public Collection findNotNullColumnsOf(String tableName) { - return defaultNotNullColumnsFinder.findNotNullColumnsOf(tableName); - } + @Override + public ReferencedTableSet findReferencedTablesOf(String tableName) { + return ReferencedTableSet.NONE; + } - @Override - public ColumnsMappingGroup findColumnsMappingsOf(String tableName) { - return ColumnsMappingGroup.NO_MAPPING; - } + @Override + public Collection findNotNullColumnsOf(String tableName) { + return defaultNotNullColumnsFinder.findNotNullColumnsOf(tableName); + } - @Override - public List findPrimaryColumnsOf(String tableName) { - return Collections.emptyList(); - } + @Override + public ColumnsMappingGroup findColumnsMappingsOf(String tableName) { + return ColumnsMappingGroup.NO_MAPPING; + } + @Override + public List findPrimaryColumnsOf(String tableName) { + return Collections.emptyList(); + } } diff --git a/src/main/java/org/qstd/dbtype/DefaultNotNullColumnsFinder.java b/src/main/java/org/qstd/dbtype/DefaultNotNullColumnsFinder.java index fe0aaf9..8a7f527 100644 --- a/src/main/java/org/qstd/dbtype/DefaultNotNullColumnsFinder.java +++ b/src/main/java/org/qstd/dbtype/DefaultNotNullColumnsFinder.java @@ -12,31 +12,30 @@ */ package org.qstd.dbtype; +import java.util.Collection; +import javax.sql.DataSource; import org.qstd.NotNullColumnsFinder; import org.qstd.SqlQuery; -import javax.sql.DataSource; -import java.util.Collection; - class DefaultNotNullColumnsFinder implements NotNullColumnsFinder { - private static final SqlQuery NOT_NULL_COLUMNS_QUERY = new SqlQuery( - "select table_schema as table_schema,\n" + - " table_name as table_name,\n" + - " column_name as not_null_column\n" + - "from information_schema.columns\n" + - "where is_nullable = 'NO'\n" + - " AND table_name=?"); - - private BaseNotNullColumnsFinder delegate; - - DefaultNotNullColumnsFinder(DataSource dataSource) { - delegate = new BaseNotNullColumnsFinder(dataSource, NOT_NULL_COLUMNS_QUERY); - } - - @Override - public Collection findNotNullColumnsOf(String tableName) { - return delegate.findNotNullColumnsOf(tableName); - } - + private static final SqlQuery NOT_NULL_COLUMNS_QUERY = + new SqlQuery( + "select table_schema as table_schema,\n" + + " table_name as table_name,\n" + + " column_name as not_null_column\n" + + "from information_schema.columns\n" + + "where is_nullable = 'NO'\n" + + " AND table_name=?"); + + private BaseNotNullColumnsFinder delegate; + + DefaultNotNullColumnsFinder(DataSource dataSource) { + delegate = new BaseNotNullColumnsFinder(dataSource, NOT_NULL_COLUMNS_QUERY); + } + + @Override + public Collection findNotNullColumnsOf(String tableName) { + return delegate.findNotNullColumnsOf(tableName); + } } diff --git a/src/main/java/org/qstd/dbtype/DefaultPrimaryKeyColumnsFinder.java b/src/main/java/org/qstd/dbtype/DefaultPrimaryKeyColumnsFinder.java index 33ffd80..d6b3c88 100644 --- a/src/main/java/org/qstd/dbtype/DefaultPrimaryKeyColumnsFinder.java +++ b/src/main/java/org/qstd/dbtype/DefaultPrimaryKeyColumnsFinder.java @@ -12,38 +12,37 @@ */ package org.qstd.dbtype; +import java.util.List; +import javax.sql.DataSource; import org.qstd.PrimaryKeyColumnsFinder; import org.qstd.SqlQuery; -import javax.sql.DataSource; -import java.util.List; - class DefaultPrimaryKeyColumnsFinder implements PrimaryKeyColumnsFinder { - private static final SqlQuery PRIMARY_COLUMNS_QUERY = new SqlQuery( - "select \n" + - " cons.table_schema,\n" + - " cons.table_name,\n" + - " cons.constraint_name,\n" + - " cols.column_name,\n" + - " cols.ordinal_position as position\n" + - " from information_schema.table_constraints cons\n" + - " join information_schema.key_column_usage cols on (cons.table_schema = cols.table_schema \n" + - " and cons.table_name = cols.table_name\n" + - " and cons.constraint_name = cols.constraint_name)\n" + - " where cons.table_name = ?" + "\n" + - " and cons.constraint_type='PRIMARY KEY'" - ); - - private final PrimaryKeyColumnsFinder delegate; - - DefaultPrimaryKeyColumnsFinder(DataSource dataSource) { - delegate = new BasePrimaryKeyColumnsFinder(dataSource, PRIMARY_COLUMNS_QUERY); - } - - @Override - public List findPrimaryColumnsOf(String tableName) { - return delegate.findPrimaryColumnsOf(tableName); - } - + private static final SqlQuery PRIMARY_COLUMNS_QUERY = + new SqlQuery( + "select \n" + + " cons.table_schema,\n" + + " cons.table_name,\n" + + " cons.constraint_name,\n" + + " cols.column_name,\n" + + " cols.ordinal_position as position\n" + + " from information_schema.table_constraints cons\n" + + " join information_schema.key_column_usage cols on (cons.table_schema = cols.table_schema \n" + + " and cons.table_name = cols.table_name\n" + + " and cons.constraint_name = cols.constraint_name)\n" + + " where cons.table_name = ?" + + "\n" + + " and cons.constraint_type='PRIMARY KEY'"); + + private final PrimaryKeyColumnsFinder delegate; + + DefaultPrimaryKeyColumnsFinder(DataSource dataSource) { + delegate = new BasePrimaryKeyColumnsFinder(dataSource, PRIMARY_COLUMNS_QUERY); + } + + @Override + public List findPrimaryColumnsOf(String tableName) { + return delegate.findPrimaryColumnsOf(tableName); + } } diff --git a/src/main/java/org/qstd/dbtype/H2MetadataFinder.java b/src/main/java/org/qstd/dbtype/H2MetadataFinder.java index 743d381..4f70f3e 100644 --- a/src/main/java/org/qstd/dbtype/H2MetadataFinder.java +++ b/src/main/java/org/qstd/dbtype/H2MetadataFinder.java @@ -12,105 +12,106 @@ */ package org.qstd.dbtype; -import org.qstd.*; - -import javax.sql.DataSource; import java.util.Collection; import java.util.List; +import javax.sql.DataSource; +import org.qstd.*; class H2MetadataFinder implements DatabaseMetadataFinder { - private static final SqlQuery H2_REFERENCED_TABLES_QUERY = new SqlQuery( - "with\n" + - " recursive parent_child_tree (table_name, ref_table_name, level) as\n" + - " (\n" + - " select distinct\n" + - " child.table_name as table_name,\n" + - " parent.table_name as ref_table_name,\n" + - " 1 as level\n" + - " from information_schema.table_constraints child\n" + - " join information_schema.referential_constraints rco\n" + - " on rco.constraint_name = child.constraint_name\n" + - " join information_schema.constraints parent\n" + - " on parent.unique_index_name = rco.unique_constraint_name\n" + - " where\n" + - " child.table_name != parent.table_name and\n" + - " child.table_name=?\n" + - " UNION ALL\n" + - " select pc.table_name, pc.ref_table_name, pct.level + 1 as level\n" + - " from\n" + - " (\n" + - " select \n" + - " child.table_name as table_name,\n" + - " parent.table_name as ref_table_name,\n" + - " 1 as level\n" + - " from information_schema.table_constraints child\n" + - " join information_schema.referential_constraints rco\n" + - " on rco.constraint_name = child.constraint_name\n" + - " join information_schema.constraints parent\n" + - " on parent.unique_index_name = rco.unique_constraint_name\n" + - " where\n" + - " child.table_name != parent.table_name\n" + - " ) pc\n" + - " join parent_child_tree pct on (pc.table_name = pct.ref_table_name)\n" + - " )\n" + - "select distinct *\n" + - "from parent_child_tree\n" + - "order by level desc"); - - private static final SqlQuery H2_COLUMNS_MAPPINGS_QUERY = new SqlQuery( - "select \n" + - " fktable_schema as table_schema,\n" + - " fktable_name as table_name,\n" + - " fkcolumn_name as column_name,\n" + - " pktable_schema as ref_table_schema,\n" + - " pktable_name as ref_table_name,\n" + - " pkcolumn_name as ref_column_name\n" + - " from information_schema.cross_references \n" + - " where fktable_name = ?" - ); - - private final DefaultColumnOrdersFinder defaultColumnOrdersFinder; - - private final NotNullColumnsFinder defaultNotNullColumnsFinder; - - private final ReferencedTablesFinder h2ReferencedTablesFinder; - - private final ColumnsMappingsFinder h2ColumnsMappingsFinder; - - private final PrimaryKeyColumnsFinder primaryKeyColumnsFinder; - - H2MetadataFinder(DataSource dataSource) { - this.defaultColumnOrdersFinder = new DefaultColumnOrdersFinder(dataSource); - this.defaultNotNullColumnsFinder = new DefaultNotNullColumnsFinder(dataSource); - this.h2ReferencedTablesFinder = new BaseReferencedTablesFinder(dataSource, H2_REFERENCED_TABLES_QUERY); - this.h2ColumnsMappingsFinder = new BaseColumnsMappingsFinder(dataSource, H2_COLUMNS_MAPPINGS_QUERY); - this.primaryKeyColumnsFinder = new DefaultPrimaryKeyColumnsFinder(dataSource); - } - - @Override - public List findDatabaseColumnOrdersOf(String tableName) { - return defaultColumnOrdersFinder.findDatabaseColumnOrdersOf(tableName); - } - - @Override - public Collection findNotNullColumnsOf(String tableName) { - return defaultNotNullColumnsFinder.findNotNullColumnsOf(tableName); - } - - @Override - public ReferencedTableSet findReferencedTablesOf(String tableName) { - return h2ReferencedTablesFinder.findReferencedTablesOf(tableName); - } - - @Override - public ColumnsMappingGroup findColumnsMappingsOf(String tableName) { - return h2ColumnsMappingsFinder.findColumnsMappingsOf(tableName); - } - - @Override - public List findPrimaryColumnsOf(String tableName) { - return primaryKeyColumnsFinder.findPrimaryColumnsOf(tableName); - } - + private static final SqlQuery H2_REFERENCED_TABLES_QUERY = + new SqlQuery( + "with\n" + + " recursive parent_child_tree (table_name, ref_table_name, level) as\n" + + " (\n" + + " select distinct\n" + + " child.table_name as table_name,\n" + + " parent.table_name as ref_table_name,\n" + + " 1 as level\n" + + " from information_schema.table_constraints child\n" + + " join information_schema.referential_constraints rco\n" + + " on rco.constraint_name = child.constraint_name\n" + + " join information_schema.constraints parent\n" + + " on parent.unique_index_name = rco.unique_constraint_name\n" + + " where\n" + + " child.table_name != parent.table_name and\n" + + " child.table_name=?\n" + + " UNION ALL\n" + + " select pc.table_name, pc.ref_table_name, pct.level + 1 as level\n" + + " from\n" + + " (\n" + + " select \n" + + " child.table_name as table_name,\n" + + " parent.table_name as ref_table_name,\n" + + " 1 as level\n" + + " from information_schema.table_constraints child\n" + + " join information_schema.referential_constraints rco\n" + + " on rco.constraint_name = child.constraint_name\n" + + " join information_schema.constraints parent\n" + + " on parent.unique_index_name = rco.unique_constraint_name\n" + + " where\n" + + " child.table_name != parent.table_name\n" + + " ) pc\n" + + " join parent_child_tree pct on (pc.table_name = pct.ref_table_name)\n" + + " )\n" + + "select distinct *\n" + + "from parent_child_tree\n" + + "order by level desc"); + + private static final SqlQuery H2_COLUMNS_MAPPINGS_QUERY = + new SqlQuery( + "select \n" + + " fktable_schema as table_schema,\n" + + " fktable_name as table_name,\n" + + " fkcolumn_name as column_name,\n" + + " pktable_schema as ref_table_schema,\n" + + " pktable_name as ref_table_name,\n" + + " pkcolumn_name as ref_column_name\n" + + " from information_schema.cross_references \n" + + " where fktable_name = ?"); + + private final DefaultColumnOrdersFinder defaultColumnOrdersFinder; + + private final NotNullColumnsFinder defaultNotNullColumnsFinder; + + private final ReferencedTablesFinder h2ReferencedTablesFinder; + + private final ColumnsMappingsFinder h2ColumnsMappingsFinder; + + private final PrimaryKeyColumnsFinder primaryKeyColumnsFinder; + + H2MetadataFinder(DataSource dataSource) { + this.defaultColumnOrdersFinder = new DefaultColumnOrdersFinder(dataSource); + this.defaultNotNullColumnsFinder = new DefaultNotNullColumnsFinder(dataSource); + this.h2ReferencedTablesFinder = + new BaseReferencedTablesFinder(dataSource, H2_REFERENCED_TABLES_QUERY); + this.h2ColumnsMappingsFinder = + new BaseColumnsMappingsFinder(dataSource, H2_COLUMNS_MAPPINGS_QUERY); + this.primaryKeyColumnsFinder = new DefaultPrimaryKeyColumnsFinder(dataSource); + } + + @Override + public List findDatabaseColumnOrdersOf(String tableName) { + return defaultColumnOrdersFinder.findDatabaseColumnOrdersOf(tableName); + } + + @Override + public Collection findNotNullColumnsOf(String tableName) { + return defaultNotNullColumnsFinder.findNotNullColumnsOf(tableName); + } + + @Override + public ReferencedTableSet findReferencedTablesOf(String tableName) { + return h2ReferencedTablesFinder.findReferencedTablesOf(tableName); + } + + @Override + public ColumnsMappingGroup findColumnsMappingsOf(String tableName) { + return h2ColumnsMappingsFinder.findColumnsMappingsOf(tableName); + } + + @Override + public List findPrimaryColumnsOf(String tableName) { + return primaryKeyColumnsFinder.findPrimaryColumnsOf(tableName); + } } diff --git a/src/main/java/org/qstd/dbtype/HsqlDbMetadataFinder.java b/src/main/java/org/qstd/dbtype/HsqlDbMetadataFinder.java index ff812fe..6239141 100644 --- a/src/main/java/org/qstd/dbtype/HsqlDbMetadataFinder.java +++ b/src/main/java/org/qstd/dbtype/HsqlDbMetadataFinder.java @@ -12,119 +12,120 @@ */ package org.qstd.dbtype; -import org.qstd.*; - -import javax.sql.DataSource; import java.util.Collection; import java.util.List; +import javax.sql.DataSource; +import org.qstd.*; class HsqlDbMetadataFinder implements DatabaseMetadataFinder { - private static final SqlQuery HSQL_DB_REFERENCED_TABLES_QUERY = new SqlQuery( - "with\n" + - " recursive parent_child_tree (table_name, ref_table_name, level) as\n" + - " (\n" + - " select distinct\n" + - " child.table_name as table_name,\n" + - " parent.table_name as ref_table_name,\n" + - " 1 as level\n" + - " from information_schema.table_constraints child\n" + - " join information_schema.referential_constraints rco\n" + - " on rco.constraint_name = child.constraint_name\n" + - " join information_schema.table_constraints parent\n" + - " on parent.constraint_name = rco.unique_constraint_name\n" + - " where\n" + - " child.table_name != parent.table_name and\n" + - " child.table_name=?\n" + - " UNION\n" + - " select pc.table_name, pc.ref_table_name, pct.level + 1 as level\n" + - " from\n" + - " (\n" + - " select distinct\n" + - " child.table_name as table_name,\n" + - " parent.table_name as ref_table_name,\n" + - " 1 as level\n" + - " from information_schema.table_constraints child\n" + - " join information_schema.referential_constraints rco\n" + - " on rco.constraint_name = child.constraint_name\n" + - " join information_schema.table_constraints parent\n" + - " on parent.constraint_name = rco.unique_constraint_name\n" + - " where\n" + - " child.table_name != parent.table_name\n" + - " ) pc\n" + - " join parent_child_tree pct on (pc.table_name = pct.ref_table_name)\n" + - " )\n" + - "select distinct *\n" + - "from parent_child_tree\n" + - "order by level desc"); - - private static final SqlQuery HSQL_DB_COLUMNS_MAPPINGS_QUERY = new SqlQuery( - "select\n" + - " child_constraint.table_schema as table_schema,\n" + - " child_constraint.table_name as table_name,\n" + - " child_cons_cols.column_name as column_name,\n" + - " parent_cons_cols.table_schema as ref_table_schema,\n" + - " parent_cons_cols.table_name as ref_table_name,\n" + - " parent_cons_cols.column_name as ref_column_name\n" + - " from information_schema.table_constraints as child_constraint\n" + - " join information_schema.key_column_usage as child_cons_cols\n" + - " on (child_constraint.constraint_schema = child_cons_cols.constraint_schema\n" + - " and\n" + - " child_constraint.constraint_name = child_cons_cols.constraint_name\n" + - " and\n" + - " child_constraint.table_schema = child_cons_cols.table_schema)\n" + - " join information_schema.referential_constraints as ref\n" + - " on (child_constraint.constraint_schema = ref.constraint_schema\n" + - " and\n" + - " child_constraint.constraint_name = ref.constraint_name)\n" + - " join information_schema.key_column_usage as parent_cons_cols\n" + - " on (parent_cons_cols.constraint_schema = ref.unique_constraint_schema\n" + - " and\n" + - " parent_cons_cols.constraint_name = ref.unique_constraint_name)\n" + - "where child_constraint.constraint_type = 'FOREIGN KEY' and child_constraint.table_name=?" - ); - - private final DefaultColumnOrdersFinder defaultColumnOrdersFinder; - - private final NotNullColumnsFinder defaultNotNullColumnsFinder; - - private final ReferencedTablesFinder hsqlDbReferencedTablesFinder; - - private final ColumnsMappingsFinder hsqlDbColumnsMappingsFinder; - - private final DefaultPrimaryKeyColumnsFinder primaryKeyColumnsFinder; - - HsqlDbMetadataFinder(DataSource dataSource) { - this.defaultColumnOrdersFinder = new DefaultColumnOrdersFinder(dataSource); - this.defaultNotNullColumnsFinder = new DefaultNotNullColumnsFinder(dataSource); - this.hsqlDbReferencedTablesFinder = new BaseReferencedTablesFinder(dataSource, HSQL_DB_REFERENCED_TABLES_QUERY); - this.hsqlDbColumnsMappingsFinder = new BaseColumnsMappingsFinder(dataSource, HSQL_DB_COLUMNS_MAPPINGS_QUERY); - this.primaryKeyColumnsFinder = new DefaultPrimaryKeyColumnsFinder(dataSource); - } - - @Override - public List findDatabaseColumnOrdersOf(String tableName) { - return defaultColumnOrdersFinder.findDatabaseColumnOrdersOf(tableName); - } - - @Override - public Collection findNotNullColumnsOf(String tableName) { - return defaultNotNullColumnsFinder.findNotNullColumnsOf(tableName); - } - - @Override - public ReferencedTableSet findReferencedTablesOf(String tableName) { - return hsqlDbReferencedTablesFinder.findReferencedTablesOf(tableName); - } - - @Override - public ColumnsMappingGroup findColumnsMappingsOf(String tableName) { - return hsqlDbColumnsMappingsFinder.findColumnsMappingsOf(tableName); - } - - @Override - public List findPrimaryColumnsOf(String tableName) { - return primaryKeyColumnsFinder.findPrimaryColumnsOf(tableName); - } - + private static final SqlQuery HSQL_DB_REFERENCED_TABLES_QUERY = + new SqlQuery( + "with\n" + + " recursive parent_child_tree (table_name, ref_table_name, level) as\n" + + " (\n" + + " select distinct\n" + + " child.table_name as table_name,\n" + + " parent.table_name as ref_table_name,\n" + + " 1 as level\n" + + " from information_schema.table_constraints child\n" + + " join information_schema.referential_constraints rco\n" + + " on rco.constraint_name = child.constraint_name\n" + + " join information_schema.table_constraints parent\n" + + " on parent.constraint_name = rco.unique_constraint_name\n" + + " where\n" + + " child.table_name != parent.table_name and\n" + + " child.table_name=?\n" + + " UNION\n" + + " select pc.table_name, pc.ref_table_name, pct.level + 1 as level\n" + + " from\n" + + " (\n" + + " select distinct\n" + + " child.table_name as table_name,\n" + + " parent.table_name as ref_table_name,\n" + + " 1 as level\n" + + " from information_schema.table_constraints child\n" + + " join information_schema.referential_constraints rco\n" + + " on rco.constraint_name = child.constraint_name\n" + + " join information_schema.table_constraints parent\n" + + " on parent.constraint_name = rco.unique_constraint_name\n" + + " where\n" + + " child.table_name != parent.table_name\n" + + " ) pc\n" + + " join parent_child_tree pct on (pc.table_name = pct.ref_table_name)\n" + + " )\n" + + "select distinct *\n" + + "from parent_child_tree\n" + + "order by level desc"); + + private static final SqlQuery HSQL_DB_COLUMNS_MAPPINGS_QUERY = + new SqlQuery( + "select\n" + + " child_constraint.table_schema as table_schema,\n" + + " child_constraint.table_name as table_name,\n" + + " child_cons_cols.column_name as column_name,\n" + + " parent_cons_cols.table_schema as ref_table_schema,\n" + + " parent_cons_cols.table_name as ref_table_name,\n" + + " parent_cons_cols.column_name as ref_column_name\n" + + " from information_schema.table_constraints as child_constraint\n" + + " join information_schema.key_column_usage as child_cons_cols\n" + + " on (child_constraint.constraint_schema = child_cons_cols.constraint_schema\n" + + " and\n" + + " child_constraint.constraint_name = child_cons_cols.constraint_name\n" + + " and\n" + + " child_constraint.table_schema = child_cons_cols.table_schema)\n" + + " join information_schema.referential_constraints as ref\n" + + " on (child_constraint.constraint_schema = ref.constraint_schema\n" + + " and\n" + + " child_constraint.constraint_name = ref.constraint_name)\n" + + " join information_schema.key_column_usage as parent_cons_cols\n" + + " on (parent_cons_cols.constraint_schema = ref.unique_constraint_schema\n" + + " and\n" + + " parent_cons_cols.constraint_name = ref.unique_constraint_name)\n" + + "where child_constraint.constraint_type = 'FOREIGN KEY' and child_constraint.table_name=?"); + + private final DefaultColumnOrdersFinder defaultColumnOrdersFinder; + + private final NotNullColumnsFinder defaultNotNullColumnsFinder; + + private final ReferencedTablesFinder hsqlDbReferencedTablesFinder; + + private final ColumnsMappingsFinder hsqlDbColumnsMappingsFinder; + + private final DefaultPrimaryKeyColumnsFinder primaryKeyColumnsFinder; + + HsqlDbMetadataFinder(DataSource dataSource) { + this.defaultColumnOrdersFinder = new DefaultColumnOrdersFinder(dataSource); + this.defaultNotNullColumnsFinder = new DefaultNotNullColumnsFinder(dataSource); + this.hsqlDbReferencedTablesFinder = + new BaseReferencedTablesFinder(dataSource, HSQL_DB_REFERENCED_TABLES_QUERY); + this.hsqlDbColumnsMappingsFinder = + new BaseColumnsMappingsFinder(dataSource, HSQL_DB_COLUMNS_MAPPINGS_QUERY); + this.primaryKeyColumnsFinder = new DefaultPrimaryKeyColumnsFinder(dataSource); + } + + @Override + public List findDatabaseColumnOrdersOf(String tableName) { + return defaultColumnOrdersFinder.findDatabaseColumnOrdersOf(tableName); + } + + @Override + public Collection findNotNullColumnsOf(String tableName) { + return defaultNotNullColumnsFinder.findNotNullColumnsOf(tableName); + } + + @Override + public ReferencedTableSet findReferencedTablesOf(String tableName) { + return hsqlDbReferencedTablesFinder.findReferencedTablesOf(tableName); + } + + @Override + public ColumnsMappingGroup findColumnsMappingsOf(String tableName) { + return hsqlDbColumnsMappingsFinder.findColumnsMappingsOf(tableName); + } + + @Override + public List findPrimaryColumnsOf(String tableName) { + return primaryKeyColumnsFinder.findPrimaryColumnsOf(tableName); + } } diff --git a/src/main/java/org/qstd/dbtype/MSSQLServerMetadataFinder.java b/src/main/java/org/qstd/dbtype/MSSQLServerMetadataFinder.java index e0d47fd..fe3e891 100644 --- a/src/main/java/org/qstd/dbtype/MSSQLServerMetadataFinder.java +++ b/src/main/java/org/qstd/dbtype/MSSQLServerMetadataFinder.java @@ -12,118 +12,120 @@ */ package org.qstd.dbtype; -import org.qstd.*; - -import javax.sql.DataSource; import java.util.Collection; import java.util.Collections; import java.util.List; +import javax.sql.DataSource; +import org.qstd.*; class MSSQLServerMetadataFinder implements DatabaseMetadataFinder { - private static final SqlQuery MS_SQL_SERVER_REFERENCED_TABLES_QUERY = new SqlQuery( - "with\n" + - " parent_child_tree as\n" + - " (\n" + - " select distinct\n" + - " child.table_name as table_name,\n" + - " parent.table_name as ref_table_name,\n" + - " 1 as level\n" + - " from information_schema.referential_constraints rco\n" + - " join information_schema.table_constraints child\n" + - " on rco.constraint_name = child.constraint_name\n" + - " and rco.constraint_schema = child.table_schema\n" + - " join information_schema.table_constraints parent\n" + - " on rco.unique_constraint_name = parent.constraint_name\n" + - " and rco.unique_constraint_schema = parent.table_schema\n" + - " where child.table_name != parent.table_name\n" + - " and child.table_name=?\n" + - " UNION ALL\n" + - " select pc.table_name, pc.ref_table_name, pct.level + 1 as level\n" + - " from\n" + - " (\n" + - " select \n" + - " child.table_name as table_name,\n" + - " parent.table_name as ref_table_name,\n" + - " 1 as level\n" + - " from information_schema.referential_constraints rco\n" + - " join information_schema.table_constraints child\n" + - " on rco.constraint_name = child.constraint_name\n" + - " and rco.constraint_schema = child.table_schema\n" + - " join information_schema.table_constraints parent\n" + - " on rco.unique_constraint_name = parent.constraint_name\n" + - " and rco.unique_constraint_schema = parent.table_schema\n" + - " where child.table_name != parent.table_name\n" + - " ) pc\n" + - " join parent_child_tree pct on (pc.table_name = pct.ref_table_name)\n" + - " )\n" + - "select distinct *\n" + - "from parent_child_tree\n" + - "order by level desc"); - - private static final SqlQuery MS_SQL_SERVER_COLUMNS_MAPPINGS_QUERY = new SqlQuery( - "select\n" + - " child_constraint.table_schema as table_schema,\n" + - " child_constraint.table_name as table_name,\n" + - " child_cons_cols.column_name as column_name,\n" + - " parent_cons_cols.table_schema as ref_table_schema,\n" + - " parent_cons_cols.table_name as ref_table_name,\n" + - " parent_cons_cols.column_name as ref_column_name\n" + - " from information_schema.table_constraints as child_constraint\n" + - " join information_schema.key_column_usage as child_cons_cols\n" + - " on (child_constraint.constraint_schema = child_cons_cols.constraint_schema\n" + - " and\n" + - " child_constraint.constraint_name = child_cons_cols.constraint_name\n" + - " and\n" + - " child_constraint.table_schema = child_cons_cols.table_schema)\n" + - " join information_schema.referential_constraints as ref\n" + - " on (child_constraint.constraint_schema = ref.constraint_schema\n" + - " and\n" + - " child_constraint.constraint_name = ref.constraint_name)\n" + - " join information_schema.key_column_usage as parent_cons_cols\n" + - " on (parent_cons_cols.constraint_schema = ref.unique_constraint_schema\n" + - " and\n" + - " parent_cons_cols.constraint_name = ref.unique_constraint_name)\n" + - "where child_constraint.constraint_type = 'FOREIGN KEY' and child_constraint.table_name=?"); - - private final DefaultColumnOrdersFinder defaultColumnOrdersFinder; - - private final NotNullColumnsFinder defaultNotNullColumnsFinder; - - private final ReferencedTablesFinder mssqlServerReferencedTablesFinder; - - private final ColumnsMappingsFinder mssqlServerColumnsMappingsFinder; - - MSSQLServerMetadataFinder(DataSource dataSource) { - this.defaultColumnOrdersFinder = new DefaultColumnOrdersFinder(dataSource); - this.defaultNotNullColumnsFinder = new DefaultNotNullColumnsFinder(dataSource); - this.mssqlServerReferencedTablesFinder = new BaseReferencedTablesFinder(dataSource, MS_SQL_SERVER_REFERENCED_TABLES_QUERY); - this.mssqlServerColumnsMappingsFinder = new BaseColumnsMappingsFinder(dataSource, MS_SQL_SERVER_COLUMNS_MAPPINGS_QUERY); - } - - @Override - public List findDatabaseColumnOrdersOf(String tableName) { - return defaultColumnOrdersFinder.findDatabaseColumnOrdersOf(tableName); - } - - @Override - public Collection findNotNullColumnsOf(String tableName) { - return defaultNotNullColumnsFinder.findNotNullColumnsOf(tableName); - } - - @Override - public ReferencedTableSet findReferencedTablesOf(String tableName) { - return mssqlServerReferencedTablesFinder.findReferencedTablesOf(tableName); - } - - @Override - public ColumnsMappingGroup findColumnsMappingsOf(String tableName) { - return mssqlServerColumnsMappingsFinder.findColumnsMappingsOf(tableName); - } - - @Override - public List findPrimaryColumnsOf(String tableName) { - return Collections.emptyList(); - } - + private static final SqlQuery MS_SQL_SERVER_REFERENCED_TABLES_QUERY = + new SqlQuery( + "with\n" + + " parent_child_tree as\n" + + " (\n" + + " select distinct\n" + + " child.table_name as table_name,\n" + + " parent.table_name as ref_table_name,\n" + + " 1 as level\n" + + " from information_schema.referential_constraints rco\n" + + " join information_schema.table_constraints child\n" + + " on rco.constraint_name = child.constraint_name\n" + + " and rco.constraint_schema = child.table_schema\n" + + " join information_schema.table_constraints parent\n" + + " on rco.unique_constraint_name = parent.constraint_name\n" + + " and rco.unique_constraint_schema = parent.table_schema\n" + + " where child.table_name != parent.table_name\n" + + " and child.table_name=?\n" + + " UNION ALL\n" + + " select pc.table_name, pc.ref_table_name, pct.level + 1 as level\n" + + " from\n" + + " (\n" + + " select \n" + + " child.table_name as table_name,\n" + + " parent.table_name as ref_table_name,\n" + + " 1 as level\n" + + " from information_schema.referential_constraints rco\n" + + " join information_schema.table_constraints child\n" + + " on rco.constraint_name = child.constraint_name\n" + + " and rco.constraint_schema = child.table_schema\n" + + " join information_schema.table_constraints parent\n" + + " on rco.unique_constraint_name = parent.constraint_name\n" + + " and rco.unique_constraint_schema = parent.table_schema\n" + + " where child.table_name != parent.table_name\n" + + " ) pc\n" + + " join parent_child_tree pct on (pc.table_name = pct.ref_table_name)\n" + + " )\n" + + "select distinct *\n" + + "from parent_child_tree\n" + + "order by level desc"); + + private static final SqlQuery MS_SQL_SERVER_COLUMNS_MAPPINGS_QUERY = + new SqlQuery( + "select\n" + + " child_constraint.table_schema as table_schema,\n" + + " child_constraint.table_name as table_name,\n" + + " child_cons_cols.column_name as column_name,\n" + + " parent_cons_cols.table_schema as ref_table_schema,\n" + + " parent_cons_cols.table_name as ref_table_name,\n" + + " parent_cons_cols.column_name as ref_column_name\n" + + " from information_schema.table_constraints as child_constraint\n" + + " join information_schema.key_column_usage as child_cons_cols\n" + + " on (child_constraint.constraint_schema = child_cons_cols.constraint_schema\n" + + " and\n" + + " child_constraint.constraint_name = child_cons_cols.constraint_name\n" + + " and\n" + + " child_constraint.table_schema = child_cons_cols.table_schema)\n" + + " join information_schema.referential_constraints as ref\n" + + " on (child_constraint.constraint_schema = ref.constraint_schema\n" + + " and\n" + + " child_constraint.constraint_name = ref.constraint_name)\n" + + " join information_schema.key_column_usage as parent_cons_cols\n" + + " on (parent_cons_cols.constraint_schema = ref.unique_constraint_schema\n" + + " and\n" + + " parent_cons_cols.constraint_name = ref.unique_constraint_name)\n" + + "where child_constraint.constraint_type = 'FOREIGN KEY' and child_constraint.table_name=?"); + + private final DefaultColumnOrdersFinder defaultColumnOrdersFinder; + + private final NotNullColumnsFinder defaultNotNullColumnsFinder; + + private final ReferencedTablesFinder mssqlServerReferencedTablesFinder; + + private final ColumnsMappingsFinder mssqlServerColumnsMappingsFinder; + + MSSQLServerMetadataFinder(DataSource dataSource) { + this.defaultColumnOrdersFinder = new DefaultColumnOrdersFinder(dataSource); + this.defaultNotNullColumnsFinder = new DefaultNotNullColumnsFinder(dataSource); + this.mssqlServerReferencedTablesFinder = + new BaseReferencedTablesFinder(dataSource, MS_SQL_SERVER_REFERENCED_TABLES_QUERY); + this.mssqlServerColumnsMappingsFinder = + new BaseColumnsMappingsFinder(dataSource, MS_SQL_SERVER_COLUMNS_MAPPINGS_QUERY); + } + + @Override + public List findDatabaseColumnOrdersOf(String tableName) { + return defaultColumnOrdersFinder.findDatabaseColumnOrdersOf(tableName); + } + + @Override + public Collection findNotNullColumnsOf(String tableName) { + return defaultNotNullColumnsFinder.findNotNullColumnsOf(tableName); + } + + @Override + public ReferencedTableSet findReferencedTablesOf(String tableName) { + return mssqlServerReferencedTablesFinder.findReferencedTablesOf(tableName); + } + + @Override + public ColumnsMappingGroup findColumnsMappingsOf(String tableName) { + return mssqlServerColumnsMappingsFinder.findColumnsMappingsOf(tableName); + } + + @Override + public List findPrimaryColumnsOf(String tableName) { + return Collections.emptyList(); + } } diff --git a/src/main/java/org/qstd/dbtype/MariaDBMySQLMetadataFinder.java b/src/main/java/org/qstd/dbtype/MariaDBMySQLMetadataFinder.java index 27eb483..9cb32f5 100644 --- a/src/main/java/org/qstd/dbtype/MariaDBMySQLMetadataFinder.java +++ b/src/main/java/org/qstd/dbtype/MariaDBMySQLMetadataFinder.java @@ -12,75 +12,76 @@ */ package org.qstd.dbtype; -import org.qstd.*; - -import javax.sql.DataSource; import java.util.Collection; import java.util.Collections; import java.util.List; +import javax.sql.DataSource; +import org.qstd.*; class MariaDBMySQLMetadataFinder implements DatabaseMetadataFinder { - private static final SqlQuery MARIA_DB_MY_SQL_COLUMNS_MAPPINGS_QUERY - = new SqlQuery("select\n" + - " child_constraint.table_schema as table_schema,\n" + - " child_constraint.table_name as table_name,\n" + - " child_cons_cols.column_name as column_name,\n" + - " child_cons_cols.referenced_table_schema as ref_table_schema,\n" + - " child_cons_cols.referenced_table_name as ref_table_name,\n" + - " child_cons_cols.referenced_column_name as ref_column_name\n" + - " from information_schema.table_constraints as child_constraint\n" + - " join information_schema.key_column_usage as child_cons_cols\n" + - " on (child_constraint.constraint_schema = child_cons_cols.constraint_schema\n" + - " and\n" + - " child_constraint.constraint_name = child_cons_cols.constraint_name\n" + - " and\n" + - " child_constraint.table_schema = child_cons_cols.table_schema\n" + - " and\n" + - " child_constraint.table_name = child_cons_cols.table_name)\n" + - "where child_constraint.constraint_type = 'FOREIGN KEY' and child_constraint.table_name=?"); - - private final DefaultColumnOrdersFinder defaultColumnOrdersFinder; - - private final NotNullColumnsFinder defaultNotNullColumnsFinder; - - private final PostgreSqlMariaDbReferencedTablesFinder postgreSqlMariaDbReferencedTablesFinder; - - private final BaseColumnsMappingsFinder mariaDbMySqlColumnsMappingsFinder; - - private final PrimaryKeyColumnsFinder primaryKeyColumnsFinder; - - MariaDBMySQLMetadataFinder(DataSource dataSource) { - this.defaultColumnOrdersFinder = new DefaultColumnOrdersFinder(dataSource); - this.defaultNotNullColumnsFinder = new DefaultNotNullColumnsFinder(dataSource); - this.postgreSqlMariaDbReferencedTablesFinder = new PostgreSqlMariaDbReferencedTablesFinder(dataSource); - this.mariaDbMySqlColumnsMappingsFinder = new BaseColumnsMappingsFinder(dataSource, MARIA_DB_MY_SQL_COLUMNS_MAPPINGS_QUERY); - this.primaryKeyColumnsFinder = new DefaultPrimaryKeyColumnsFinder(dataSource); - } - - @Override - public List findDatabaseColumnOrdersOf(String tableName) { - return defaultColumnOrdersFinder.findDatabaseColumnOrdersOf(tableName); - } - - @Override - public Collection findNotNullColumnsOf(String tableName) { - return defaultNotNullColumnsFinder.findNotNullColumnsOf(tableName); - } - - @Override - public ReferencedTableSet findReferencedTablesOf(String tableName) { - return postgreSqlMariaDbReferencedTablesFinder.findReferencedTablesOf(tableName); - } - - @Override - public ColumnsMappingGroup findColumnsMappingsOf(String tableName) { - return mariaDbMySqlColumnsMappingsFinder.findColumnsMappingsOf(tableName); - } - - @Override - public List findPrimaryColumnsOf(String tableName) { - return Collections.emptyList(); - } - + private static final SqlQuery MARIA_DB_MY_SQL_COLUMNS_MAPPINGS_QUERY = + new SqlQuery( + "select\n" + + " child_constraint.table_schema as table_schema,\n" + + " child_constraint.table_name as table_name,\n" + + " child_cons_cols.column_name as column_name,\n" + + " child_cons_cols.referenced_table_schema as ref_table_schema,\n" + + " child_cons_cols.referenced_table_name as ref_table_name,\n" + + " child_cons_cols.referenced_column_name as ref_column_name\n" + + " from information_schema.table_constraints as child_constraint\n" + + " join information_schema.key_column_usage as child_cons_cols\n" + + " on (child_constraint.constraint_schema = child_cons_cols.constraint_schema\n" + + " and\n" + + " child_constraint.constraint_name = child_cons_cols.constraint_name\n" + + " and\n" + + " child_constraint.table_schema = child_cons_cols.table_schema\n" + + " and\n" + + " child_constraint.table_name = child_cons_cols.table_name)\n" + + "where child_constraint.constraint_type = 'FOREIGN KEY' and child_constraint.table_name=?"); + + private final DefaultColumnOrdersFinder defaultColumnOrdersFinder; + + private final NotNullColumnsFinder defaultNotNullColumnsFinder; + + private final PostgreSqlMariaDbReferencedTablesFinder postgreSqlMariaDbReferencedTablesFinder; + + private final BaseColumnsMappingsFinder mariaDbMySqlColumnsMappingsFinder; + + private final PrimaryKeyColumnsFinder primaryKeyColumnsFinder; + + MariaDBMySQLMetadataFinder(DataSource dataSource) { + this.defaultColumnOrdersFinder = new DefaultColumnOrdersFinder(dataSource); + this.defaultNotNullColumnsFinder = new DefaultNotNullColumnsFinder(dataSource); + this.postgreSqlMariaDbReferencedTablesFinder = + new PostgreSqlMariaDbReferencedTablesFinder(dataSource); + this.mariaDbMySqlColumnsMappingsFinder = + new BaseColumnsMappingsFinder(dataSource, MARIA_DB_MY_SQL_COLUMNS_MAPPINGS_QUERY); + this.primaryKeyColumnsFinder = new DefaultPrimaryKeyColumnsFinder(dataSource); + } + + @Override + public List findDatabaseColumnOrdersOf(String tableName) { + return defaultColumnOrdersFinder.findDatabaseColumnOrdersOf(tableName); + } + + @Override + public Collection findNotNullColumnsOf(String tableName) { + return defaultNotNullColumnsFinder.findNotNullColumnsOf(tableName); + } + + @Override + public ReferencedTableSet findReferencedTablesOf(String tableName) { + return postgreSqlMariaDbReferencedTablesFinder.findReferencedTablesOf(tableName); + } + + @Override + public ColumnsMappingGroup findColumnsMappingsOf(String tableName) { + return mariaDbMySqlColumnsMappingsFinder.findColumnsMappingsOf(tableName); + } + + @Override + public List findPrimaryColumnsOf(String tableName) { + return Collections.emptyList(); + } } diff --git a/src/main/java/org/qstd/dbtype/OracleMetadataFinder.java b/src/main/java/org/qstd/dbtype/OracleMetadataFinder.java index 5903851..0eaa89d 100644 --- a/src/main/java/org/qstd/dbtype/OracleMetadataFinder.java +++ b/src/main/java/org/qstd/dbtype/OracleMetadataFinder.java @@ -12,138 +12,138 @@ */ package org.qstd.dbtype; -import org.qstd.*; - -import javax.sql.DataSource; import java.util.Collection; import java.util.List; import java.util.function.Function; +import javax.sql.DataSource; +import org.qstd.*; public class OracleMetadataFinder implements DatabaseMetadataFinder { - private static final SqlQuery COLUMNS_ORDER_QUERY = new SqlQuery( - "select owner as table_schema," + - " table_name as table_name," + - " column_name as column_name," + - " column_id as position" + - " from all_tab_columns\n" + - " where table_name = ?" + - " order by position" - ); - - private static final SqlQuery NOT_NULL_COLUMNS_QUERY = new SqlQuery( - "select owner as table_schema," + - " table_name as table_name," + - " column_name as mandatory_column" + - " from all_tab_columns" + - " where table_name = ?" + - " and nullable = 'N'" - ); - - private static final SqlQuery REFERENCED_TABLES_QUERY = new SqlQuery( - "select\n" + - " table_name,\n" + - " ref_table_name,\n" + - " level\n" + - " from\n" + - " (\n" + - " select\n" + - " c.owner as table_schema,\n" + - " c.table_name,\n" + - " c.r_owner as ref_table_schema,\n" + - " ref_c.table_name as ref_table_name\n" + - " from\n" + - " all_constraints c\n" + - " inner join all_constraints ref_c on ref_c.constraint_name = c.r_constraint_name\n" + - " where\n" + - " c.constraint_type = 'R'\n" + - " and c.table_name != ref_c.table_name\n" + - " )\n" + - " start with table_name = ?\n" + - " connect by table_name = prior ref_table_name\n" + - "order by level desc" - ); - - private static final SqlQuery COLUMNS_MAPPING_QUERY = new SqlQuery( - "select\n" + - " c.owner as table_schema,\n" + - " c.table_name,\n" + - " col.column_name,\n" + - " c.r_owner as ref_table_schema,\n" + - " ref_col.table_name as ref_table_name,\n" + - " ref_col.column_name as ref_column_name\n" + - " from\n" + - " all_constraints c\n" + - " inner join all_cons_columns col on col.owner = c.owner\n" + - " and col.constraint_name = c.constraint_name\n" + - " inner join all_cons_columns ref_col on ref_col.owner = c.r_owner\n" + - " and ref_col.constraint_name = c.r_constraint_name\n" + - " and ref_col.position = col.position\n" + - " where \n" + - " c.table_name = ?\n" + - " and c.constraint_type = 'R'"); - - private static final SqlQuery PRIMARY_KEY_QUERY = new SqlQuery( - "select\n" + - " c.owner as table_schema,\n" + - " c.table_name,\n" + - " c.constraint_name,\n" + - " col.column_name,\n" + - " col.position\n" + - " from\n" + - " all_constraints c\n" + - " inner join all_cons_columns col on col.owner = c.owner\n" + - " and col.constraint_name = c.constraint_name\n" + - " where c.table_name = ?\n" + - " and c.constraint_type = 'P'\n" + - " order by position"); - - private final BaseColumnOrdersFinder columnOrdersFinder; - - private final NotNullColumnsFinder notNullColumnsFinder; - - private final ReferencedTablesFinder referencedTablesFinder; - - private final BaseColumnsMappingsFinder columnsMappingsFinder; - - private final PrimaryKeyColumnsFinder primaryKeyColumnsFinder; - - @Override - public Function getFunctionToHaveMetadataTableName() { - return tableName -> tableName.toUpperCase(); - } - - OracleMetadataFinder(DataSource dataSource) { - columnOrdersFinder = new BaseColumnOrdersFinder(dataSource, COLUMNS_ORDER_QUERY); - notNullColumnsFinder = new BaseNotNullColumnsFinder(dataSource, NOT_NULL_COLUMNS_QUERY); - referencedTablesFinder = new BaseReferencedTablesFinder(dataSource, REFERENCED_TABLES_QUERY); - columnsMappingsFinder = new BaseColumnsMappingsFinder(dataSource, COLUMNS_MAPPING_QUERY); - primaryKeyColumnsFinder = new BasePrimaryKeyColumnsFinder(dataSource, PRIMARY_KEY_QUERY); - } - - @Override - public List findDatabaseColumnOrdersOf(String tableName) { - return columnOrdersFinder.findDatabaseColumnOrdersOf(tableName); - } - - @Override - public ColumnsMappingGroup findColumnsMappingsOf(String tableName) { - return columnsMappingsFinder.findColumnsMappingsOf(tableName); - } - - @Override - public Collection findNotNullColumnsOf(String tableName) { - return notNullColumnsFinder.findNotNullColumnsOf(tableName); - } - - @Override - public List findPrimaryColumnsOf(String tableName) { - return primaryKeyColumnsFinder.findPrimaryColumnsOf(tableName); - } - - @Override - public ReferencedTableSet findReferencedTablesOf(String tableName) { - return referencedTablesFinder.findReferencedTablesOf(tableName); - } - + private static final SqlQuery COLUMNS_ORDER_QUERY = + new SqlQuery( + "select owner as table_schema," + + " table_name as table_name," + + " column_name as column_name," + + " column_id as position" + + " from all_tab_columns\n" + + " where table_name = ?" + + " order by position"); + + private static final SqlQuery NOT_NULL_COLUMNS_QUERY = + new SqlQuery( + "select owner as table_schema," + + " table_name as table_name," + + " column_name as mandatory_column" + + " from all_tab_columns" + + " where table_name = ?" + + " and nullable = 'N'"); + + private static final SqlQuery REFERENCED_TABLES_QUERY = + new SqlQuery( + "select\n" + + " table_name,\n" + + " ref_table_name,\n" + + " level\n" + + " from\n" + + " (\n" + + " select\n" + + " c.owner as table_schema,\n" + + " c.table_name,\n" + + " c.r_owner as ref_table_schema,\n" + + " ref_c.table_name as ref_table_name\n" + + " from\n" + + " all_constraints c\n" + + " inner join all_constraints ref_c on ref_c.constraint_name = c.r_constraint_name\n" + + " where\n" + + " c.constraint_type = 'R'\n" + + " and c.table_name != ref_c.table_name\n" + + " )\n" + + " start with table_name = ?\n" + + " connect by table_name = prior ref_table_name\n" + + "order by level desc"); + + private static final SqlQuery COLUMNS_MAPPING_QUERY = + new SqlQuery( + "select\n" + + " c.owner as table_schema,\n" + + " c.table_name,\n" + + " col.column_name,\n" + + " c.r_owner as ref_table_schema,\n" + + " ref_col.table_name as ref_table_name,\n" + + " ref_col.column_name as ref_column_name\n" + + " from\n" + + " all_constraints c\n" + + " inner join all_cons_columns col on col.owner = c.owner\n" + + " and col.constraint_name = c.constraint_name\n" + + " inner join all_cons_columns ref_col on ref_col.owner = c.r_owner\n" + + " and ref_col.constraint_name = c.r_constraint_name\n" + + " and ref_col.position = col.position\n" + + " where \n" + + " c.table_name = ?\n" + + " and c.constraint_type = 'R'"); + + private static final SqlQuery PRIMARY_KEY_QUERY = + new SqlQuery( + "select\n" + + " c.owner as table_schema,\n" + + " c.table_name,\n" + + " c.constraint_name,\n" + + " col.column_name,\n" + + " col.position\n" + + " from\n" + + " all_constraints c\n" + + " inner join all_cons_columns col on col.owner = c.owner\n" + + " and col.constraint_name = c.constraint_name\n" + + " where c.table_name = ?\n" + + " and c.constraint_type = 'P'\n" + + " order by position"); + + private final BaseColumnOrdersFinder columnOrdersFinder; + + private final NotNullColumnsFinder notNullColumnsFinder; + + private final ReferencedTablesFinder referencedTablesFinder; + + private final BaseColumnsMappingsFinder columnsMappingsFinder; + + private final PrimaryKeyColumnsFinder primaryKeyColumnsFinder; + + @Override + public Function getFunctionToHaveMetadataTableName() { + return tableName -> tableName.toUpperCase(); + } + + OracleMetadataFinder(DataSource dataSource) { + columnOrdersFinder = new BaseColumnOrdersFinder(dataSource, COLUMNS_ORDER_QUERY); + notNullColumnsFinder = new BaseNotNullColumnsFinder(dataSource, NOT_NULL_COLUMNS_QUERY); + referencedTablesFinder = new BaseReferencedTablesFinder(dataSource, REFERENCED_TABLES_QUERY); + columnsMappingsFinder = new BaseColumnsMappingsFinder(dataSource, COLUMNS_MAPPING_QUERY); + primaryKeyColumnsFinder = new BasePrimaryKeyColumnsFinder(dataSource, PRIMARY_KEY_QUERY); + } + + @Override + public List findDatabaseColumnOrdersOf(String tableName) { + return columnOrdersFinder.findDatabaseColumnOrdersOf(tableName); + } + + @Override + public ColumnsMappingGroup findColumnsMappingsOf(String tableName) { + return columnsMappingsFinder.findColumnsMappingsOf(tableName); + } + + @Override + public Collection findNotNullColumnsOf(String tableName) { + return notNullColumnsFinder.findNotNullColumnsOf(tableName); + } + + @Override + public List findPrimaryColumnsOf(String tableName) { + return primaryKeyColumnsFinder.findPrimaryColumnsOf(tableName); + } + + @Override + public ReferencedTableSet findReferencedTablesOf(String tableName) { + return referencedTablesFinder.findReferencedTablesOf(tableName); + } } diff --git a/src/main/java/org/qstd/dbtype/PostgreSqlMariaDbReferencedTablesFinder.java b/src/main/java/org/qstd/dbtype/PostgreSqlMariaDbReferencedTablesFinder.java index bda0aa3..23e8f05 100644 --- a/src/main/java/org/qstd/dbtype/PostgreSqlMariaDbReferencedTablesFinder.java +++ b/src/main/java/org/qstd/dbtype/PostgreSqlMariaDbReferencedTablesFinder.java @@ -12,54 +12,55 @@ */ package org.qstd.dbtype; +import javax.sql.DataSource; import org.qstd.ReferencedTableSet; import org.qstd.ReferencedTablesFinder; import org.qstd.SqlQuery; -import javax.sql.DataSource; - class PostgreSqlMariaDbReferencedTablesFinder implements ReferencedTablesFinder { - private static final SqlQuery REFERENCED_TABLES_QUERY = new SqlQuery("with \n" + - " recursive parent_child_tree as\n" + - " (\n" + - " with parent_child as\n" + - " (\n" + - " select distinct\n" + - " child.table_schema as table_schema,\n" + - " child.table_name as table_name,\n" + - " parent.table_schema as ref_table_schema,\n" + - " parent.table_name as ref_table_name\n" + - " from information_schema.referential_constraints rco\n" + - " join information_schema.table_constraints child\n" + - " on rco.constraint_name = child.constraint_name\n" + - " and rco.constraint_schema = child.table_schema\n" + - " join information_schema.table_constraints parent\n" + - " on rco.unique_constraint_name = parent.constraint_name\n" + - " and rco.unique_constraint_schema = parent.table_schema\n" + - " where child.table_name != parent.table_name\n" + - " )\n" + - " select table_name, ref_table_name, 1 as level\n" + - " from parent_child\n" + - " where table_name=?\n" + - " UNION\n" + - " select pc.table_name, pc.ref_table_name, pct.level + 1 as level\n" + - " from parent_child_tree pct\n" + - " join parent_child pc on (pc.table_name = pct.ref_table_name)\n" + - " )\n" + - "select *\n" + - "from parent_child_tree\n" + - "order by level desc"); - - private final BaseReferencedTablesFinder referencedTablesFinder; + private static final SqlQuery REFERENCED_TABLES_QUERY = + new SqlQuery( + "with \n" + + " recursive parent_child_tree as\n" + + " (\n" + + " with parent_child as\n" + + " (\n" + + " select distinct\n" + + " child.table_schema as table_schema,\n" + + " child.table_name as table_name,\n" + + " parent.table_schema as ref_table_schema,\n" + + " parent.table_name as ref_table_name\n" + + " from information_schema.referential_constraints rco\n" + + " join information_schema.table_constraints child\n" + + " on rco.constraint_name = child.constraint_name\n" + + " and rco.constraint_schema = child.table_schema\n" + + " join information_schema.table_constraints parent\n" + + " on rco.unique_constraint_name = parent.constraint_name\n" + + " and rco.unique_constraint_schema = parent.table_schema\n" + + " where child.table_name != parent.table_name\n" + + " )\n" + + " select table_name, ref_table_name, 1 as level\n" + + " from parent_child\n" + + " where table_name=?\n" + + " UNION\n" + + " select pc.table_name, pc.ref_table_name, pct.level + 1 as level\n" + + " from parent_child_tree pct\n" + + " join parent_child pc on (pc.table_name = pct.ref_table_name)\n" + + " )\n" + + "select *\n" + + "from parent_child_tree\n" + + "order by level desc"); - PostgreSqlMariaDbReferencedTablesFinder(DataSource dataSource) { - this.referencedTablesFinder = new BaseReferencedTablesFinder(dataSource, REFERENCED_TABLES_QUERY); - } + private final BaseReferencedTablesFinder referencedTablesFinder; - @Override - public ReferencedTableSet findReferencedTablesOf(String tableName) { - return referencedTablesFinder.findReferencedTablesOf(tableName); - } + PostgreSqlMariaDbReferencedTablesFinder(DataSource dataSource) { + this.referencedTablesFinder = + new BaseReferencedTablesFinder(dataSource, REFERENCED_TABLES_QUERY); + } + @Override + public ReferencedTableSet findReferencedTablesOf(String tableName) { + return referencedTablesFinder.findReferencedTablesOf(tableName); + } } diff --git a/src/main/java/org/qstd/dbtype/PostgreSqlMetadataFinder.java b/src/main/java/org/qstd/dbtype/PostgreSqlMetadataFinder.java index 806f879..5f953cb 100644 --- a/src/main/java/org/qstd/dbtype/PostgreSqlMetadataFinder.java +++ b/src/main/java/org/qstd/dbtype/PostgreSqlMetadataFinder.java @@ -12,69 +12,71 @@ */ package org.qstd.dbtype; -import org.qstd.*; - -import javax.sql.DataSource; import java.util.Collection; import java.util.List; +import javax.sql.DataSource; +import org.qstd.*; class PostgreSqlMetadataFinder implements DatabaseMetadataFinder { - private static final SqlQuery POSTGRE_SQL_COLUMNS_MAPPINGS_QUERY = new SqlQuery("select\n" + - " tc.table_schema as table_schema,\n" + - " tc.table_name as table_name,\n" + - " kcu.column_name as column_name,\n" + - " ccu.table_schema as ref_table_schema,\n" + - " ccu.table_name as ref_table_name,\n" + - " ccu.column_name as ref_column_name\n" + - " from information_schema.table_constraints as tc\n" + - " join information_schema.key_column_usage as kcu\n" + - " using (constraint_schema, constraint_name, table_schema)\n" + - " join information_schema.constraint_column_usage as ccu\n" + - " using (constraint_schema, constraint_name, table_schema)\n" + - "where tc.constraint_type = 'FOREIGN KEY' and tc.table_name=?"); - - private final DefaultColumnOrdersFinder defaultColumnOrdersFinder; - - private final NotNullColumnsFinder defaultNotNullColumnsFinder; - - private final PostgreSqlMariaDbReferencedTablesFinder postgreSqlMariaDbReferencedTablesFinder; - - private final ColumnsMappingsFinder postgreSqlColumnsMappingsFinder; - - private final PrimaryKeyColumnsFinder primaryKeyColumnsFinder; - - PostgreSqlMetadataFinder(DataSource dataSource) { - this.defaultColumnOrdersFinder = new DefaultColumnOrdersFinder(dataSource); - this.defaultNotNullColumnsFinder = new DefaultNotNullColumnsFinder(dataSource); - this.postgreSqlMariaDbReferencedTablesFinder = new PostgreSqlMariaDbReferencedTablesFinder(dataSource); - this.postgreSqlColumnsMappingsFinder = new BaseColumnsMappingsFinder(dataSource, POSTGRE_SQL_COLUMNS_MAPPINGS_QUERY); - this.primaryKeyColumnsFinder = new DefaultPrimaryKeyColumnsFinder(dataSource); - } - - @Override - public List findDatabaseColumnOrdersOf(String tableName) { - return defaultColumnOrdersFinder.findDatabaseColumnOrdersOf(tableName); - } - - @Override - public Collection findNotNullColumnsOf(String tableName) { - return defaultNotNullColumnsFinder.findNotNullColumnsOf(tableName); - } - - @Override - public ReferencedTableSet findReferencedTablesOf(String tableName) { - return postgreSqlMariaDbReferencedTablesFinder.findReferencedTablesOf(tableName); - } - - @Override - public ColumnsMappingGroup findColumnsMappingsOf(String tableName) { - return postgreSqlColumnsMappingsFinder.findColumnsMappingsOf(tableName); - } - - @Override - public List findPrimaryColumnsOf(String tableName) { - return primaryKeyColumnsFinder.findPrimaryColumnsOf(tableName); - } - + private static final SqlQuery POSTGRE_SQL_COLUMNS_MAPPINGS_QUERY = + new SqlQuery( + "select\n" + + " tc.table_schema as table_schema,\n" + + " tc.table_name as table_name,\n" + + " kcu.column_name as column_name,\n" + + " ccu.table_schema as ref_table_schema,\n" + + " ccu.table_name as ref_table_name,\n" + + " ccu.column_name as ref_column_name\n" + + " from information_schema.table_constraints as tc\n" + + " join information_schema.key_column_usage as kcu\n" + + " using (constraint_schema, constraint_name, table_schema)\n" + + " join information_schema.constraint_column_usage as ccu\n" + + " using (constraint_schema, constraint_name, table_schema)\n" + + "where tc.constraint_type = 'FOREIGN KEY' and tc.table_name=?"); + + private final DefaultColumnOrdersFinder defaultColumnOrdersFinder; + + private final NotNullColumnsFinder defaultNotNullColumnsFinder; + + private final PostgreSqlMariaDbReferencedTablesFinder postgreSqlMariaDbReferencedTablesFinder; + + private final ColumnsMappingsFinder postgreSqlColumnsMappingsFinder; + + private final PrimaryKeyColumnsFinder primaryKeyColumnsFinder; + + PostgreSqlMetadataFinder(DataSource dataSource) { + this.defaultColumnOrdersFinder = new DefaultColumnOrdersFinder(dataSource); + this.defaultNotNullColumnsFinder = new DefaultNotNullColumnsFinder(dataSource); + this.postgreSqlMariaDbReferencedTablesFinder = + new PostgreSqlMariaDbReferencedTablesFinder(dataSource); + this.postgreSqlColumnsMappingsFinder = + new BaseColumnsMappingsFinder(dataSource, POSTGRE_SQL_COLUMNS_MAPPINGS_QUERY); + this.primaryKeyColumnsFinder = new DefaultPrimaryKeyColumnsFinder(dataSource); + } + + @Override + public List findDatabaseColumnOrdersOf(String tableName) { + return defaultColumnOrdersFinder.findDatabaseColumnOrdersOf(tableName); + } + + @Override + public Collection findNotNullColumnsOf(String tableName) { + return defaultNotNullColumnsFinder.findNotNullColumnsOf(tableName); + } + + @Override + public ReferencedTableSet findReferencedTablesOf(String tableName) { + return postgreSqlMariaDbReferencedTablesFinder.findReferencedTablesOf(tableName); + } + + @Override + public ColumnsMappingGroup findColumnsMappingsOf(String tableName) { + return postgreSqlColumnsMappingsFinder.findColumnsMappingsOf(tableName); + } + + @Override + public List findPrimaryColumnsOf(String tableName) { + return primaryKeyColumnsFinder.findPrimaryColumnsOf(tableName); + } } diff --git a/src/test/java/org/qstd/test/DataSourceBuilder.java b/src/test/java/org/qstd/test/DataSourceBuilder.java index 1abd35a..657d1dd 100644 --- a/src/test/java/org/qstd/test/DataSourceBuilder.java +++ b/src/test/java/org/qstd/test/DataSourceBuilder.java @@ -14,21 +14,19 @@ import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; - import javax.sql.DataSource; class DataSourceBuilder { - static final DataSourceBuilder INSTANCE = new DataSourceBuilder(); - - private DataSourceBuilder() { } + static final DataSourceBuilder INSTANCE = new DataSourceBuilder(); - static DataSource build(String jdbcUrl, String dbUserName, String dbPassword) { - HikariConfig hikariConfig = new HikariConfig(); - hikariConfig.setJdbcUrl(jdbcUrl); - hikariConfig.setUsername(dbUserName); - hikariConfig.setPassword(dbPassword); - return new HikariDataSource(hikariConfig); - } + private DataSourceBuilder() {} + static DataSource build(String jdbcUrl, String dbUserName, String dbPassword) { + HikariConfig hikariConfig = new HikariConfig(); + hikariConfig.setJdbcUrl(jdbcUrl); + hikariConfig.setUsername(dbUserName); + hikariConfig.setPassword(dbPassword); + return new HikariDataSource(hikariConfig); + } } diff --git a/src/test/java/org/qstd/test/DatasetRowApiTest.java b/src/test/java/org/qstd/test/DatasetRowApiTest.java index 30eb6d4..5ca7cee 100644 --- a/src/test/java/org/qstd/test/DatasetRowApiTest.java +++ b/src/test/java/org/qstd/test/DatasetRowApiTest.java @@ -12,47 +12,45 @@ */ package org.qstd.test; +import static org.qstd.test.TestTable.TestTableAssert.assertThat; +import static org.qstd.test.TestTable.buildUniqueTable; + +import java.util.List; import org.junit.jupiter.api.Test; import org.qstd.DatasetRow; import org.qstd.QuickSqlTestData; -import java.util.List; - -import static org.qstd.test.TestTable.TestTableAssert.assertThat; -import static org.qstd.test.TestTable.buildUniqueTable; - public class DatasetRowApiTest extends H2Config { - @Test public void - should_generate_working_insert_from_a_dataset_row() { - - // GIVEN - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Player" - , " id bigint" - + ", firstName varchar(255)" - + ", lastName varchar(255)") - .create() - .insertValues("1, 'Paul', 'Pogba'"); - - // WHEN - DatasetRow datasetRow = - DatasetRow.ofTable(playerTable.getTableName()) - .addColumnValue("id", 1) - .addColumnValue("firstName", "Paul") - .addColumnValue("lastName", "Pogba"); - - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - List insertStatements = quickSqlTestData.generateInsertListFor(datasetRow); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertStatements); - assertThat(playerTable).withGeneratedInserts(insertStatements) - .hasNumberOfRows(1) - .row(0).hasValues(1, "Paul", "Pogba"); - - } - + @Test + public void should_generate_working_insert_from_a_dataset_row() { + + // GIVEN + TestTable playerTable = + buildUniqueTable( + DATA_SOURCE, + "Player", + " id bigint" + ", firstName varchar(255)" + ", lastName varchar(255)") + .create() + .insertValues("1, 'Paul', 'Pogba'"); + + // WHEN + DatasetRow datasetRow = + DatasetRow.ofTable(playerTable.getTableName()) + .addColumnValue("id", 1) + .addColumnValue("firstName", "Paul") + .addColumnValue("lastName", "Pogba"); + + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + List insertStatements = quickSqlTestData.generateInsertListFor(datasetRow); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertStatements); + assertThat(playerTable) + .withGeneratedInserts(insertStatements) + .hasNumberOfRows(1) + .row(0) + .hasValues(1, "Paul", "Pogba"); + } } diff --git a/src/test/java/org/qstd/test/DatasetRowsMergingTest.java b/src/test/java/org/qstd/test/DatasetRowsMergingTest.java index 44cf252..fe2922b 100644 --- a/src/test/java/org/qstd/test/DatasetRowsMergingTest.java +++ b/src/test/java/org/qstd/test/DatasetRowsMergingTest.java @@ -12,117 +12,121 @@ */ package org.qstd.test; -import org.junit.jupiter.api.Test; -import org.qstd.QuickSqlTestData; +import static org.qstd.test.TestTable.TestTableAssert.assertThat; import java.util.Random; - -import static org.qstd.test.TestTable.TestTableAssert.assertThat; +import org.junit.jupiter.api.Test; +import org.qstd.QuickSqlTestData; public class DatasetRowsMergingTest extends H2Config { - @Test public void - should_merge_dataset_rows_if_columns_in_common_have_same_values() { - - // GIVEN - TestTable table = - TestTable.buildUniqueTable(DATA_SOURCE - , "Table" - , "col1 varchar(255)" - + ", col2 varchar(255)" - + ", col3 varchar(255)" - ) - .create() - .insertValues("'val1', 'val2', 'val3'"); - - String tableName = table.getTableName(); - String select1 = "SELECT col1, col2 FROM " + tableName; - String select2 = "SELECT col1, col3 FROM " + tableName; - - // WHEN - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select1, select2); - - // THEN - table.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(table).withScript(insertScript) - .hasNumberOfRows(1) - .row(0).hasValues("val1", "val2", "val3"); - - } - - @Test public void - should_merge_dataset_rows_in_case_of_joined_rows() { - - // GIVEN - TestTable sponsorTable = - TestTable.buildUniqueTable(DATA_SOURCE - , "Sponsor" - , " id bigint" + - ", name varchar(255) not null" + - ", country varchar(255)" + - ", primary key (id)" - ) - .create() - .insertValues("1, 'Sponsor name', 'France'"); - - String teamSponsorForeignKey = "add constraint team_sponsor_fk" + generateRandomPositiveInt() - + " foreign key (sponsor_id)" - + " references " + sponsorTable.getTableName(); - - TestTable teamTable = - TestTable.buildUniqueTable(DATA_SOURCE - , "Team" - ," id bigint not null" + - ", name varchar(255) not null" + - ", sponsor_id bigint not null" + - ", primary key (id)" - ) - .create() - .alter(teamSponsorForeignKey) - .insertValues("1, 'Manchester United', 1"); - - String playerTeamForeignKey = "add constraint player_team_fk" + generateRandomPositiveInt() - + " foreign key (team_id)" - + " references " + teamTable.getTableName(); - TestTable playerTable = - TestTable.buildUniqueTable(DATA_SOURCE - , "Player" - , "id bigint not null" - + ", firstName varchar(255)" - + ", lastName varchar(255)" - + ", team_id bigint not null" - + ", primary key (id)" - ) - .create() - .alter(playerTeamForeignKey) - .insertValues("1, 'Paul', 'Pogba', 1"); - - String playerSelect = "SELECT * FROM " + playerTable.getTableName(); - String sponsorSelect = "SELECT * FROM " + sponsorTable.getTableName(); - - // WHEN - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(playerSelect, sponsorSelect); - - // THEN - playerTable.drop(); - teamTable.drop(); - sponsorTable.drop().create(); - teamTable.create().alter(teamSponsorForeignKey); - playerTable.create().alter(playerTeamForeignKey); - SQL_EXECUTOR.execute(insertScript); - - assertThat(sponsorTable).withScript(insertScript) - .hasNumberOfRows(1) - .row(0).hasValues(1, "Sponsor name", "France"); - - } - - private int generateRandomPositiveInt() { - Random random = new Random(); - return Math.abs(random.nextInt()); - } - + @Test + public void should_merge_dataset_rows_if_columns_in_common_have_same_values() { + + // GIVEN + TestTable table = + TestTable.buildUniqueTable( + DATA_SOURCE, + "Table", + "col1 varchar(255)" + ", col2 varchar(255)" + ", col3 varchar(255)") + .create() + .insertValues("'val1', 'val2', 'val3'"); + + String tableName = table.getTableName(); + String select1 = "SELECT col1, col2 FROM " + tableName; + String select2 = "SELECT col1, col3 FROM " + tableName; + + // WHEN + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select1, select2); + + // THEN + table.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(table) + .withScript(insertScript) + .hasNumberOfRows(1) + .row(0) + .hasValues("val1", "val2", "val3"); + } + + @Test + public void should_merge_dataset_rows_in_case_of_joined_rows() { + + // GIVEN + TestTable sponsorTable = + TestTable.buildUniqueTable( + DATA_SOURCE, + "Sponsor", + " id bigint" + + ", name varchar(255) not null" + + ", country varchar(255)" + + ", primary key (id)") + .create() + .insertValues("1, 'Sponsor name', 'France'"); + + String teamSponsorForeignKey = + "add constraint team_sponsor_fk" + + generateRandomPositiveInt() + + " foreign key (sponsor_id)" + + " references " + + sponsorTable.getTableName(); + + TestTable teamTable = + TestTable.buildUniqueTable( + DATA_SOURCE, + "Team", + " id bigint not null" + + ", name varchar(255) not null" + + ", sponsor_id bigint not null" + + ", primary key (id)") + .create() + .alter(teamSponsorForeignKey) + .insertValues("1, 'Manchester United', 1"); + + String playerTeamForeignKey = + "add constraint player_team_fk" + + generateRandomPositiveInt() + + " foreign key (team_id)" + + " references " + + teamTable.getTableName(); + TestTable playerTable = + TestTable.buildUniqueTable( + DATA_SOURCE, + "Player", + "id bigint not null" + + ", firstName varchar(255)" + + ", lastName varchar(255)" + + ", team_id bigint not null" + + ", primary key (id)") + .create() + .alter(playerTeamForeignKey) + .insertValues("1, 'Paul', 'Pogba', 1"); + + String playerSelect = "SELECT * FROM " + playerTable.getTableName(); + String sponsorSelect = "SELECT * FROM " + sponsorTable.getTableName(); + + // WHEN + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(playerSelect, sponsorSelect); + + // THEN + playerTable.drop(); + teamTable.drop(); + sponsorTable.drop().create(); + teamTable.create().alter(teamSponsorForeignKey); + playerTable.create().alter(playerTeamForeignKey); + SQL_EXECUTOR.execute(insertScript); + + assertThat(sponsorTable) + .withScript(insertScript) + .hasNumberOfRows(1) + .row(0) + .hasValues(1, "Sponsor name", "France"); + } + + private int generateRandomPositiveInt() { + Random random = new Random(); + return Math.abs(random.nextInt()); + } } diff --git a/src/test/java/org/qstd/test/DeleteTest.java b/src/test/java/org/qstd/test/DeleteTest.java index c2f38e3..ae6ca51 100644 --- a/src/test/java/org/qstd/test/DeleteTest.java +++ b/src/test/java/org/qstd/test/DeleteTest.java @@ -12,75 +12,77 @@ */ package org.qstd.test; -import org.junit.jupiter.api.Test; -import org.qstd.QuickSqlTestData; - import static org.qstd.test.TestTable.TestTableAssert.assertThat; import static org.qstd.test.TestTable.buildUniqueTable; -public class DeleteTest extends H2Config { - - @Test - public void - should_generate_insert_if_all_rows_are_deleted_and_no_mandatory_columns() { +import org.junit.jupiter.api.Test; +import org.qstd.QuickSqlTestData; - // GIVEN - TestTable table1 = - buildUniqueTable(DATA_SOURCE - , "Table_1" - , " id bigint" - + ", Col_A varchar(255)" - + ", Col_B varchar(255)" - + ", Col_dec decimal") - .create() - .insertValues("1, 'A1', 'B1', 1.80") - .insertValues("2, 'A2', 'B2', 2.99"); +public class DeleteTest extends H2Config { - String deleteQuery = "DELETE FROM " + table1.getTableName(); + @Test + public void should_generate_insert_if_all_rows_are_deleted_and_no_mandatory_columns() { - // WHEN - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(deleteQuery); + // GIVEN + TestTable table1 = + buildUniqueTable( + DATA_SOURCE, + "Table_1", + " id bigint" + + ", Col_A varchar(255)" + + ", Col_B varchar(255)" + + ", Col_dec decimal") + .create() + .insertValues("1, 'A1', 'B1', 1.80") + .insertValues("2, 'A2', 'B2', 2.99"); - // THEN - table1.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(table1).withScript(insertScript) - .hasNumberOfRows(2) - .row(0).hasValues(1, "A1", "B1", 1.80) - .row(1).hasValues(2, "A2", "B2", 2.99); - } + String deleteQuery = "DELETE FROM " + table1.getTableName(); - @Test - public void - should_generate_one_insert_if_one_rows_is_deleted() { + // WHEN + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(deleteQuery); - // GIVEN - TestTable table1 = - buildUniqueTable(DATA_SOURCE - , "Table_1" - , " id bigint" - + ", Col_A varchar(255)" - + ", Col_B varchar(255)" - + ", Col_dec decimal") - .create() - .insertValues("1, 'A1', 'B1', 1.80") - .insertValues("2, 'A2', 'B2', 2.99"); + // THEN + table1.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(table1) + .withScript(insertScript) + .hasNumberOfRows(2) + .row(0) + .hasValues(1, "A1", "B1", 1.80) + .row(1) + .hasValues(2, "A2", "B2", 2.99); + } - String updateQuery = "DELETE FROM " + table1.getTableName() - + " WHERE Col_A = 'A1'"; + @Test + public void should_generate_one_insert_if_one_rows_is_deleted() { - // WHEN - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(updateQuery); + // GIVEN + TestTable table1 = + buildUniqueTable( + DATA_SOURCE, + "Table_1", + " id bigint" + + ", Col_A varchar(255)" + + ", Col_B varchar(255)" + + ", Col_dec decimal") + .create() + .insertValues("1, 'A1', 'B1', 1.80") + .insertValues("2, 'A2', 'B2', 2.99"); - // THEN - table1.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(table1).withScript(insertScript) - .hasNumberOfRows(1) - .row(0).hasValues(1, "A1", "B1", 1.80); + String updateQuery = "DELETE FROM " + table1.getTableName() + " WHERE Col_A = 'A1'"; - } + // WHEN + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(updateQuery); + // THEN + table1.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(table1) + .withScript(insertScript) + .hasNumberOfRows(1) + .row(0) + .hasValues(1, "A1", "B1", 1.80); + } } diff --git a/src/test/java/org/qstd/test/FastTestSuite.java b/src/test/java/org/qstd/test/FastTestSuite.java index 31109c3..6904dcc 100644 --- a/src/test/java/org/qstd/test/FastTestSuite.java +++ b/src/test/java/org/qstd/test/FastTestSuite.java @@ -19,17 +19,18 @@ @RunWith(JUnitPlatform.class) @SuiteDisplayName("Fast tests") -@SelectClasses( { H2Test.class - , NotFullyManagedDatabaseTest.class - , DatasetRowApiTest.class - , SelectTest.class - , UpdateTest.class - , DeleteTest.class - , InsertTest.class - , H2DateTypesTest.class - , SortInsertStatementsTest.class - , SortInsertStatementsWithPkTest.class - , DatasetRowsMergingTest.class - , JdbcRoundtripTest.class} ) -public class FastTestSuite { -} +@SelectClasses({ + H2Test.class, + NotFullyManagedDatabaseTest.class, + DatasetRowApiTest.class, + SelectTest.class, + UpdateTest.class, + DeleteTest.class, + InsertTest.class, + H2DateTypesTest.class, + SortInsertStatementsTest.class, + SortInsertStatementsWithPkTest.class, + DatasetRowsMergingTest.class, + JdbcRoundtripTest.class +}) +public class FastTestSuite {} diff --git a/src/test/java/org/qstd/test/H2Config.java b/src/test/java/org/qstd/test/H2Config.java index 5fa9326..e690d20 100644 --- a/src/test/java/org/qstd/test/H2Config.java +++ b/src/test/java/org/qstd/test/H2Config.java @@ -12,25 +12,23 @@ */ package org.qstd.test; -import org.junit.jupiter.api.BeforeAll; -import org.quickperf.junit5.QuickPerfTest; +import static org.quickperf.sql.config.QuickPerfSqlDataSourceBuilder.aDataSourceBuilder; import javax.sql.DataSource; - -import static org.quickperf.sql.config.QuickPerfSqlDataSourceBuilder.aDataSourceBuilder; +import org.junit.jupiter.api.BeforeAll; +import org.quickperf.junit5.QuickPerfTest; @QuickPerfTest class H2Config { - static DataSource DATA_SOURCE; - - static SqlExecutor SQL_EXECUTOR; + static DataSource DATA_SOURCE; - @BeforeAll - public static void beforeAll() { - DataSource h2Datasource = DataSourceBuilder.build("jdbc:h2:mem:test", "user", "pwd"); - DATA_SOURCE = aDataSourceBuilder().buildProxy(h2Datasource); - SQL_EXECUTOR = new SqlExecutor(DATA_SOURCE); - } + static SqlExecutor SQL_EXECUTOR; + @BeforeAll + public static void beforeAll() { + DataSource h2Datasource = DataSourceBuilder.build("jdbc:h2:mem:test", "user", "pwd"); + DATA_SOURCE = aDataSourceBuilder().buildProxy(h2Datasource); + SQL_EXECUTOR = new SqlExecutor(DATA_SOURCE); + } } diff --git a/src/test/java/org/qstd/test/H2DateTypesTest.java b/src/test/java/org/qstd/test/H2DateTypesTest.java index c447421..0cfe048 100644 --- a/src/test/java/org/qstd/test/H2DateTypesTest.java +++ b/src/test/java/org/qstd/test/H2DateTypesTest.java @@ -12,146 +12,122 @@ */ package org.qstd.test; +import static org.qstd.test.TestTable.TestTableAssert.assertThat; +import static org.qstd.test.TestTable.buildUniqueTable; + import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.qstd.QuickSqlTestData; -import static org.qstd.test.TestTable.TestTableAssert.assertThat; -import static org.qstd.test.TestTable.buildUniqueTable; - public class H2DateTypesTest extends H2Config { - @Test public void - should_generate_an_insert_statement_with_a_date_type() { - - // GIVEN - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Table" - , "date Date" - ) - .create() - .insertValues("'2012-09-17'"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1) - .row(0).hasValues("2012-09-17"); - - } - - @Test public void - should_generate_an_insert_statement_with_a_timestamp_type() { - - // GIVEN - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Table" - , "timestampCol TIMESTAMP" - ) - .create() - .insertValues("'2012-09-17 19:56:47.32'"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1); - Assertions.assertThat(insertScript).contains("'2012-09-17 19:56:47.32'"); - - } - - @Test public void - should_generate_an_insert_statement_with_a_timestamp_with_time_zone_type() { - - // GIVEN - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Table" - , "col TIMESTAMP WITH TIME ZONE" - ) - .create() - .insertValues("'2012-09-17 19:56:47.32 UTC'"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1); - - } - - @Test public void - should_generate_an_insert_statement_with_a_time_type() { - - // GIVEN - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Table" - , "col TIME" - ) - .create() - .insertValues("'23:59:59'"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1) - .row(0).hasValues("23:59:59"); - - } - - @Test public void - should_generate_an_insert_statement_with_a_time_with_timezone_type() { - - // GIVEN - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Table" - , "col TIME WITH TIME ZONE" - ) - .create() - .insertValues("'23:59:59 UTC'"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1); - - } - + @Test + public void should_generate_an_insert_statement_with_a_date_type() { + + // GIVEN + TestTable playerTable = + buildUniqueTable(DATA_SOURCE, "Table", "date Date").create().insertValues("'2012-09-17'"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable) + .withScript(insertScript) + .hasNumberOfRows(1) + .row(0) + .hasValues("2012-09-17"); + } + + @Test + public void should_generate_an_insert_statement_with_a_timestamp_type() { + + // GIVEN + TestTable playerTable = + buildUniqueTable(DATA_SOURCE, "Table", "timestampCol TIMESTAMP") + .create() + .insertValues("'2012-09-17 19:56:47.32'"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable).withScript(insertScript).hasNumberOfRows(1); + Assertions.assertThat(insertScript).contains("'2012-09-17 19:56:47.32'"); + } + + @Test + public void should_generate_an_insert_statement_with_a_timestamp_with_time_zone_type() { + + // GIVEN + TestTable playerTable = + buildUniqueTable(DATA_SOURCE, "Table", "col TIMESTAMP WITH TIME ZONE") + .create() + .insertValues("'2012-09-17 19:56:47.32 UTC'"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable).withScript(insertScript).hasNumberOfRows(1); + } + + @Test + public void should_generate_an_insert_statement_with_a_time_type() { + + // GIVEN + TestTable playerTable = + buildUniqueTable(DATA_SOURCE, "Table", "col TIME").create().insertValues("'23:59:59'"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable) + .withScript(insertScript) + .hasNumberOfRows(1) + .row(0) + .hasValues("23:59:59"); + } + + @Test + public void should_generate_an_insert_statement_with_a_time_with_timezone_type() { + + // GIVEN + TestTable playerTable = + buildUniqueTable(DATA_SOURCE, "Table", "col TIME WITH TIME ZONE") + .create() + .insertValues("'23:59:59 UTC'"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable).withScript(insertScript).hasNumberOfRows(1); + } } diff --git a/src/test/java/org/qstd/test/H2Test.java b/src/test/java/org/qstd/test/H2Test.java index 1e81b55..a69ae50 100644 --- a/src/test/java/org/qstd/test/H2Test.java +++ b/src/test/java/org/qstd/test/H2Test.java @@ -12,306 +12,313 @@ */ package org.qstd.test; -import org.junit.jupiter.api.Test; -import org.qstd.QuickSqlTestData; - -import java.util.Random; - import static org.assertj.core.api.Assertions.assertThat; import static org.qstd.test.TestTable.*; import static org.qstd.test.TestTable.TestTableAssert.assertThat; -public class H2Test extends H2Config { +import java.util.Random; +import org.junit.jupiter.api.Test; +import org.qstd.QuickSqlTestData; - @Test public void - should_generate_an_insert_statement_with_columns_declared_in_the_same_order_as_in_the_table() { - - // GIVEN - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "player" - , "id bigint" - + ", firstName varchar(255)" - + ", lastName varchar(255)" - ) - .create() - .insertValues("1, 'Paul', 'Pogba'"); - - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - - // WHEN - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - assertThat(insertScript).contains("ID, FIRSTNAME, LASTNAME"); - - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1); - - } - - @Test public void - should_generate_an_insert_statement_with_not_null_columns() { - - // GIVEN - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Player" - , " id bigint not null" - + ", firstName varchar(255) not null" - + ", lastName varchar(255) not null" - ) - .create() - .insertValues("1, 'Paul', 'Pogba'"); - - String playerTableName = playerTable.getTableName(); - String select = "SELECT id FROM " + playerTableName + " WHERE lastName = 'Pogba'"; - - // WHEN - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1) - .row(0).hasValues(1, "Paul", "Pogba"); - - } - - @Test public void - should_generate_an_insert_statement_with_not_null_columns_from_a_statement_selecting_a_null_column() { - - // GIVEN - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Player" - , " id bigint not null" - + ", firstName varchar(255) not null" - + ", lastName varchar(255) not null" - + ", team_id bigint" - ) - .create() - .insertValues("1, 'Paul', 'Pogba', NULL"); - - String playerTableName = playerTable.getTableName(); - String select = "SELECT team_id FROM " + playerTableName + " WHERE lastName = 'Pogba'"; - - // WHEN - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1) - .row(0).hasValues(1, "Paul", "Pogba", null); - - } - - @Test public void - should_generate_an_insert_statement_with_not_null_columns_from_a_statement_selecting_2_columns() { - - // GIVEN - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Player" - , " id bigint not null" - + ", firstName varchar(255) not null" - + ", lastName varchar(255) not null" - + ", team_id bigint" - ) - .create() - .insertValues("1, 'Paul', 'Pogba', NULL"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT id, team_id FROM " + playerTableName + " WHERE lastName = 'Pogba'"; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1) - .row(0).hasValues(1, "Paul", "Pogba", null); - - } - - private int generateRandomPositiveInt() { - Random random = new Random(); - return Math.abs(random.nextInt()); - } - - @Test public void - should_add_rows_related_to_a_not_null_foreign_key() { - - // GIVEN - TestTable teamTable = - buildUniqueTable(DATA_SOURCE - , "Team" - ," id bigint not null" + - ", name varchar(255)" + - ", primary key (id)" - ) - .create() - .insertValues("1, 'Manchester United'"); - - String playerTableConstraint = "add constraint player_team_fk" + generateRandomPositiveInt() - + " foreign key (team_id)" - + " references " + teamTable.getTableName(); - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Player" - , "id bigint not null" - + ", firstName varchar(255)" - + ", lastName varchar(255)" - + ", team_id bigint not null" - + ", primary key (id)" - ) - .create() - .alter(playerTableConstraint) - .insertValues("1, 'Paul', 'Pogba', 1"); - - String playerSelect = "SELECT * FROM " + playerTable.getTableName(); - - // WHEN - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(playerSelect); - - // THEN - playerTable.drop(); - teamTable.drop().create(); - playerTable.create().alter(playerTableConstraint); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1); - assertThat(teamTable).withScript(insertScript) - .hasNumberOfRows(1); - - } - - @Test public void - should_add_not_null_columns_to_rows_related_to_a_not_null_foreign_key() { - - // GIVEN - TestTable teamTable = - buildUniqueTable(DATA_SOURCE - , "Team" - ," id bigint not null" + - ", name varchar(255) not null" + - ", primary key (id)") - .create() - .insertValues("1, 'Manchester United'"); - - String playerTableConstraint = "add constraint player_team_fk" + generateRandomPositiveInt() - + " foreign key (team_id)" - + " references " + teamTable.getTableName(); - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Player" - , "id bigint not null" - + ", firstName varchar(255)" - + ", lastName varchar(255)" - + ", team_id bigint not null" - + ", primary key (id)" - ) - .create() - .alter(playerTableConstraint) - .insertValues("1, 'Paul', 'Pogba', 1"); - - String playerSelect = "SELECT * FROM " + playerTable.getTableName(); - - // WHEN - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(playerSelect); - - // THEN - playerTable.drop(); - teamTable.drop().create(); - playerTable.create().alter(playerTableConstraint); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1); - assertThat(teamTable).hasNumberOfRows(1) - .row(0).column(0).hasValues(1) - .row(0).column(1).hasValues("Manchester United"); - - } - - @Test public void - should_add_joined_rows_of_joined_rows_because_of_not_null_foreign_keys() { - - // GIVEN - TestTable sponsorTable = - buildUniqueTable(DATA_SOURCE - , "Sponsor" - , " id bigint" + - ", name varchar(255) not null" + - ", primary key (id)" - ) - .create() - .insertValues("1, 'Sponsor name'"); - - String teamSponsorForeignKey = "add constraint team_sponsor_fk" + generateRandomPositiveInt() - + " foreign key (sponsor_id)" - + " references " + sponsorTable.getTableName(); - - TestTable teamTable = - buildUniqueTable(DATA_SOURCE - , "Team" - ," id bigint not null" + - ", name varchar(255) not null" + - ", sponsor_id bigint not null" + - ", primary key (id)" - ) - .create() - .alter(teamSponsorForeignKey) - .insertValues("1, 'Manchester United', 1"); - - String playerTeamForeignKey = "add constraint player_team_fk" + generateRandomPositiveInt() - + " foreign key (team_id)" - + " references " + teamTable.getTableName(); - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Player" - , "id bigint not null" - + ", firstName varchar(255)" - + ", lastName varchar(255)" - + ", team_id bigint not null" - + ", primary key (id)") - .create() - .alter(playerTeamForeignKey) - .insertValues("1, 'Paul', 'Pogba', 1"); - - String playerSelect = "SELECT * FROM " + playerTable.getTableName(); - - // WHEN - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(playerSelect); - - // THEN - playerTable.drop(); - teamTable.drop(); - sponsorTable.drop().create(); - teamTable.create().alter(teamSponsorForeignKey); - playerTable.create().alter(playerTeamForeignKey); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1); - assertThat(teamTable).withScript(insertScript) - .hasNumberOfRows(1) - .row(0).hasValues(1, "Manchester United", 1); - assertThat(sponsorTable).withScript(insertScript) - .hasNumberOfRows(1); - - } +public class H2Test extends H2Config { + @Test + public void + should_generate_an_insert_statement_with_columns_declared_in_the_same_order_as_in_the_table() { + + // GIVEN + TestTable playerTable = + buildUniqueTable( + DATA_SOURCE, + "player", + "id bigint" + ", firstName varchar(255)" + ", lastName varchar(255)") + .create() + .insertValues("1, 'Paul', 'Pogba'"); + + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + + // WHEN + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + assertThat(insertScript).contains("ID, FIRSTNAME, LASTNAME"); + + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable).withScript(insertScript).hasNumberOfRows(1); + } + + @Test + public void should_generate_an_insert_statement_with_not_null_columns() { + + // GIVEN + TestTable playerTable = + buildUniqueTable( + DATA_SOURCE, + "Player", + " id bigint not null" + + ", firstName varchar(255) not null" + + ", lastName varchar(255) not null") + .create() + .insertValues("1, 'Paul', 'Pogba'"); + + String playerTableName = playerTable.getTableName(); + String select = "SELECT id FROM " + playerTableName + " WHERE lastName = 'Pogba'"; + + // WHEN + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable) + .withScript(insertScript) + .hasNumberOfRows(1) + .row(0) + .hasValues(1, "Paul", "Pogba"); + } + + @Test + public void + should_generate_an_insert_statement_with_not_null_columns_from_a_statement_selecting_a_null_column() { + + // GIVEN + TestTable playerTable = + buildUniqueTable( + DATA_SOURCE, + "Player", + " id bigint not null" + + ", firstName varchar(255) not null" + + ", lastName varchar(255) not null" + + ", team_id bigint") + .create() + .insertValues("1, 'Paul', 'Pogba', NULL"); + + String playerTableName = playerTable.getTableName(); + String select = "SELECT team_id FROM " + playerTableName + " WHERE lastName = 'Pogba'"; + + // WHEN + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable) + .withScript(insertScript) + .hasNumberOfRows(1) + .row(0) + .hasValues(1, "Paul", "Pogba", null); + } + + @Test + public void + should_generate_an_insert_statement_with_not_null_columns_from_a_statement_selecting_2_columns() { + + // GIVEN + TestTable playerTable = + buildUniqueTable( + DATA_SOURCE, + "Player", + " id bigint not null" + + ", firstName varchar(255) not null" + + ", lastName varchar(255) not null" + + ", team_id bigint") + .create() + .insertValues("1, 'Paul', 'Pogba', NULL"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT id, team_id FROM " + playerTableName + " WHERE lastName = 'Pogba'"; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable) + .withScript(insertScript) + .hasNumberOfRows(1) + .row(0) + .hasValues(1, "Paul", "Pogba", null); + } + + private int generateRandomPositiveInt() { + Random random = new Random(); + return Math.abs(random.nextInt()); + } + + @Test + public void should_add_rows_related_to_a_not_null_foreign_key() { + + // GIVEN + TestTable teamTable = + buildUniqueTable( + DATA_SOURCE, + "Team", + " id bigint not null" + ", name varchar(255)" + ", primary key (id)") + .create() + .insertValues("1, 'Manchester United'"); + + String playerTableConstraint = + "add constraint player_team_fk" + + generateRandomPositiveInt() + + " foreign key (team_id)" + + " references " + + teamTable.getTableName(); + TestTable playerTable = + buildUniqueTable( + DATA_SOURCE, + "Player", + "id bigint not null" + + ", firstName varchar(255)" + + ", lastName varchar(255)" + + ", team_id bigint not null" + + ", primary key (id)") + .create() + .alter(playerTableConstraint) + .insertValues("1, 'Paul', 'Pogba', 1"); + + String playerSelect = "SELECT * FROM " + playerTable.getTableName(); + + // WHEN + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(playerSelect); + + // THEN + playerTable.drop(); + teamTable.drop().create(); + playerTable.create().alter(playerTableConstraint); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable).withScript(insertScript).hasNumberOfRows(1); + assertThat(teamTable).withScript(insertScript).hasNumberOfRows(1); + } + + @Test + public void should_add_not_null_columns_to_rows_related_to_a_not_null_foreign_key() { + + // GIVEN + TestTable teamTable = + buildUniqueTable( + DATA_SOURCE, + "Team", + " id bigint not null" + ", name varchar(255) not null" + ", primary key (id)") + .create() + .insertValues("1, 'Manchester United'"); + + String playerTableConstraint = + "add constraint player_team_fk" + + generateRandomPositiveInt() + + " foreign key (team_id)" + + " references " + + teamTable.getTableName(); + TestTable playerTable = + buildUniqueTable( + DATA_SOURCE, + "Player", + "id bigint not null" + + ", firstName varchar(255)" + + ", lastName varchar(255)" + + ", team_id bigint not null" + + ", primary key (id)") + .create() + .alter(playerTableConstraint) + .insertValues("1, 'Paul', 'Pogba', 1"); + + String playerSelect = "SELECT * FROM " + playerTable.getTableName(); + + // WHEN + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(playerSelect); + + // THEN + playerTable.drop(); + teamTable.drop().create(); + playerTable.create().alter(playerTableConstraint); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable).withScript(insertScript).hasNumberOfRows(1); + assertThat(teamTable) + .hasNumberOfRows(1) + .row(0) + .column(0) + .hasValues(1) + .row(0) + .column(1) + .hasValues("Manchester United"); + } + + @Test + public void should_add_joined_rows_of_joined_rows_because_of_not_null_foreign_keys() { + + // GIVEN + TestTable sponsorTable = + buildUniqueTable( + DATA_SOURCE, + "Sponsor", + " id bigint" + ", name varchar(255) not null" + ", primary key (id)") + .create() + .insertValues("1, 'Sponsor name'"); + + String teamSponsorForeignKey = + "add constraint team_sponsor_fk" + + generateRandomPositiveInt() + + " foreign key (sponsor_id)" + + " references " + + sponsorTable.getTableName(); + + TestTable teamTable = + buildUniqueTable( + DATA_SOURCE, + "Team", + " id bigint not null" + + ", name varchar(255) not null" + + ", sponsor_id bigint not null" + + ", primary key (id)") + .create() + .alter(teamSponsorForeignKey) + .insertValues("1, 'Manchester United', 1"); + + String playerTeamForeignKey = + "add constraint player_team_fk" + + generateRandomPositiveInt() + + " foreign key (team_id)" + + " references " + + teamTable.getTableName(); + TestTable playerTable = + buildUniqueTable( + DATA_SOURCE, + "Player", + "id bigint not null" + + ", firstName varchar(255)" + + ", lastName varchar(255)" + + ", team_id bigint not null" + + ", primary key (id)") + .create() + .alter(playerTeamForeignKey) + .insertValues("1, 'Paul', 'Pogba', 1"); + + String playerSelect = "SELECT * FROM " + playerTable.getTableName(); + + // WHEN + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(playerSelect); + + // THEN + playerTable.drop(); + teamTable.drop(); + sponsorTable.drop().create(); + teamTable.create().alter(teamSponsorForeignKey); + playerTable.create().alter(playerTeamForeignKey); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable).withScript(insertScript).hasNumberOfRows(1); + assertThat(teamTable) + .withScript(insertScript) + .hasNumberOfRows(1) + .row(0) + .hasValues(1, "Manchester United", 1); + assertThat(sponsorTable).withScript(insertScript).hasNumberOfRows(1); + } } diff --git a/src/test/java/org/qstd/test/HsqlDbTest.java b/src/test/java/org/qstd/test/HsqlDbTest.java index 4c6aba1..f3147c0 100644 --- a/src/test/java/org/qstd/test/HsqlDbTest.java +++ b/src/test/java/org/qstd/test/HsqlDbTest.java @@ -12,492 +12,461 @@ */ package org.qstd.test; +import static org.assertj.core.api.Assertions.assertThat; +import static org.qstd.test.TestTable.TestTableAssert.assertThat; +import static org.qstd.test.TestTable.buildUniqueTable; + import java.time.OffsetTime; +import java.util.List; +import java.util.Random; +import javax.sql.DataSource; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.*; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; import org.qstd.QuickSqlTestData; -import javax.sql.DataSource; -import java.util.List; -import java.util.Random; +public class HsqlDbTest { -import static org.assertj.core.api.Assertions.assertThat; -import static org.qstd.test.TestTable.TestTableAssert.assertThat; -import static org.qstd.test.TestTable.buildUniqueTable; + private static DataSource DATA_SOURCE; -public class HsqlDbTest { + private static SqlExecutor SQL_EXECUTOR; + + @BeforeAll + public static void beforeAll() { + DATA_SOURCE = DataSourceBuilder.build("jdbc:hsqldb:mem:test", "user", "pwd"); + SQL_EXECUTOR = new SqlExecutor(DATA_SOURCE); + } - private static DataSource DATA_SOURCE; - - private static SqlExecutor SQL_EXECUTOR; - - @BeforeAll - public static void beforeAll() { - DATA_SOURCE = DataSourceBuilder.build("jdbc:hsqldb:mem:test", "user", "pwd"); - SQL_EXECUTOR = new SqlExecutor(DATA_SOURCE); - } - - @Test public void - should_generate_working_insert_from_a_select_statement() { - - // GIVEN - TestTable playerTable = - TestTable.buildUniqueTable(DATA_SOURCE - , "Player" - , " id bigint" - + ", firstName varchar(255)" - + ", lastName varchar(255)") - .create() - .insertValues("1, 'Paul', 'Pogba'"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1) - .row(0).hasValues(1, "Paul", "Pogba"); - - } - - @Test public void - should_generate_an_insert_statement_with_columns_declared_in_the_same_order_as_in_the_table() { - - // GIVEN - String colDescsAndConstraints = "id bigint" - + ", firstName varchar(255)" - + ", lastName varchar(255)"; - TestTable playerTable = - TestTable.buildUniqueTable(DATA_SOURCE - , "player" - , colDescsAndConstraints - ) - .create() - .insertValues("1, 'Paul', 'Pogba'"); - - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - - // WHEN - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - assertThat(insertScript).contains("ID, FIRSTNAME, LASTNAME"); - - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1); - - } - - @Test public void - should_generate_an_insert_statement_with_not_null_columns() { - - // GIVEN - TestTable playerTable = - TestTable.buildUniqueTable(DATA_SOURCE - , "Player" - , " id bigint not null" - + ", firstName varchar(255) not null" - + ", lastName varchar(255) not null" - ) - .create() - .insertValues("1, 'Paul', 'Pogba'"); - - String playerTableName = playerTable.getTableName(); - String select = "SELECT id FROM " + playerTableName + " WHERE lastName = 'Pogba'"; - - // WHEN - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1) - .row(0).hasValues(1, "Paul", "Pogba"); - - } - - @RepeatedTest(9) public void - should_sort_insert_statements_following_table_dependencies() { - - // GIVEN - TestTable teamTable = - TestTable.buildUniqueTable(DATA_SOURCE - , "Team" - ," id bigint not null" + - ", name varchar(255)" + - ", primary key (id)" - ) - .create() - .insertValues("1, 'Manchester United'"); - - String playerTableConstraint = "add constraint player_team_fk" + generateRandomPositiveInt() - + " foreign key (team_id)" - + " references " + teamTable.getTableName(); - TestTable playerTable = - TestTable.buildUniqueTable(DATA_SOURCE - , "Player" - , "id bigint not null" - + ", firstName varchar(255)" - + ", lastName varchar(255)" - + ", team_id bigint" - + ", primary key (id)") - .create() - .alter(playerTableConstraint) - .insertValues("1, 'Paul', 'Pogba', 1"); - - String playerSelect = "SELECT * FROM " + playerTable.getTableName(); - String teamSelect = "SELECT * FROM " + teamTable.getTableName(); - - // WHEN - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - List insertStatements = quickSqlTestData.generateInsertListFor(playerSelect, teamSelect); - - // THEN - playerTable.drop(); - teamTable.drop().create(); - playerTable.create().alter(playerTableConstraint); - SQL_EXECUTOR.execute(insertStatements); - assertThat(playerTable).withGeneratedInserts(insertStatements) - .hasNumberOfRows(1); - assertThat(teamTable).withGeneratedInserts(insertStatements) - .hasNumberOfRows(1); - - } - - private int generateRandomPositiveInt() { - Random random = new Random(); - return Math.abs(random.nextInt()); - } - - @Test public void - should_add_rows_related_to_a_not_null_foreign_key() { - - // GIVEN - TestTable teamTable = - TestTable.buildUniqueTable(DATA_SOURCE - , "Team" - ," id bigint not null" + - ", name varchar(255)" + - ", primary key (id)") - .create() - .insertValues("1, 'Manchester United'"); - - String playerTableConstraint = " add constraint player_team_fk" + generateRandomPositiveInt() - + " foreign key (team_id)" - + " references " + teamTable.getTableName(); - TestTable playerTable = - TestTable.buildUniqueTable(DATA_SOURCE - , "Player" - , "id bigint not null" - + ", firstName varchar(255)" - + ", lastName varchar(255)" - + ", team_id bigint not null" - + ", primary key (id)" - ) - .create() - .alter(playerTableConstraint) - .insertValues("1, 'Paul', 'Pogba', 1"); - - String playerSelect = "SELECT * FROM " + playerTable.getTableName(); - - // WHEN - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - List insertStatements = quickSqlTestData.generateInsertListFor(playerSelect); - - // THEN - playerTable.drop(); - teamTable.drop().create(); - playerTable.create().alter(playerTableConstraint); - SQL_EXECUTOR.execute(insertStatements); - assertThat(playerTable).withGeneratedInserts(insertStatements) - .hasNumberOfRows(1); - assertThat(teamTable).withGeneratedInserts(insertStatements) - .hasNumberOfRows(1); - - } - - @ParameterizedTest - @ValueSource(strings = {"INT", "TINYINT", "SMALLINT", "BIGINT"}) - public void - should_sort_insert_statements_following_an_integer_primary_key(String intType) { - - TestTable table = - buildUniqueTable(DATA_SOURCE - , "table_with_int_pk" - , "col_id " + intType + "," + - "colA varchar(20), " + - "colB varchar(20), " + - "constraint int_pk" + generateRandomPositiveInt() + " primary key (col_id)" - ) - .create() - .insertValues("2, 'A', 'B'") - .insertValues("10, 'C', 'D'") - .insertValues("1, 'E', 'F'"); - - String selectAll = "SELECT * FROM " + table.getTableName(); - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - - // WHEN - List insertStatements = quickSqlTestData.generateInsertListFor(selectAll); - - // THEN - String insertStatementsAsString = insertStatements.toString(); - - String firstQuery = insertStatements.get(0); - assertThat(firstQuery).as(insertStatementsAsString).contains("VALUES(1"); - - String secondQuery = insertStatements.get(1); - assertThat(secondQuery).as(insertStatementsAsString).contains("VALUES(2"); - - String thirdQuery = insertStatements.get(2); - assertThat(thirdQuery).as(insertStatementsAsString).contains("VALUES(10"); - - } - - @RepeatedTest(9) public void - should_sort_insert_statements_following_a_composite_primary_key() { - - // GIVEN - TestTable table = - TestTable.buildUniqueTable(DATA_SOURCE - , "comp_pk" - , "col_id1 integer," + - "col_id2 integer, " + - "colA varchar(20), " + - "colB varchar(20), " + - "constraint comp_pk_pk" + generateRandomPositiveInt() + " primary key (col_id1, col_id2)" - ) - .create() - .insertValues("1, 2, 'colA_r1_value', 'colB_r1_value'") - .insertValues("1, 1, 'colA_r1_value', 'colB_r1_value'") - .insertValues("2, 2, 'colA_r1_value', 'colB_r1_value'") - .insertValues("2, 1, 'colA_r1_value', 'colB_r1_value'"); - - String select1 = "SELECT * FROM " + table.getTableName() + " WHERE col_id1 = 1"; - String select2 = "SELECT * FROM " + table.getTableName() + " WHERE col_id1 = 2"; - - // WHEN - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - List insertStatements = quickSqlTestData.generateInsertListFor(select1, select2); - - // THEN - String insertQueriesAsString = insertStatements.toString(); - - String firstInsert = insertStatements.get(0); - assertThat(firstInsert).as(insertQueriesAsString).contains("VALUES(1, 1"); - - String secondInsert = insertStatements.get(1); - assertThat(secondInsert).as(insertQueriesAsString).contains("VALUES(1, 2"); - - String thirdInsert = insertStatements.get(2); - assertThat(thirdInsert).as(insertQueriesAsString).contains("VALUES(2, 1"); - - String fourthInsert = insertStatements.get(3); - assertThat(fourthInsert).as(insertQueriesAsString).contains("VALUES(2, 2"); - - } - - - @Test public void - should_generate_an_insert_statement_with_a_date_type() { - - // GIVEN - TestTable playerTable = - buildUniqueTable( DATA_SOURCE - , "Table" - , "date Date" - ) - .create() - .insertValues("'2012-09-17'"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1) - .row(0).hasValues("2012-09-17"); - - } - - @Test public void - should_generate_an_insert_statement_with_a_timestamp_type() { - - // GIVEN - TestTable playerTable = - buildUniqueTable( DATA_SOURCE - , "Table" - , "timestampCol TIMESTAMP" - ) - .create() - .insertValues("'2012-09-17 19:56:47.32'"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1); - Assertions.assertThat(insertScript).contains("'2012-09-17 19:56:47.32'"); - - } - - @Test public void - should_generate_an_insert_statement_with_a_timestamp_without_declared_time_zone_type() { - - // GIVEN - TestTable playerTable = - buildUniqueTable( DATA_SOURCE - , "Table" - , "timestampCol TIMESTAMP WITHOUT TIME ZONE" - ) + @Test + public void should_generate_working_insert_from_a_select_statement() { + + // GIVEN + TestTable playerTable = + TestTable.buildUniqueTable( + DATA_SOURCE, + "Player", + " id bigint" + ", firstName varchar(255)" + ", lastName varchar(255)") + .create() + .insertValues("1, 'Paul', 'Pogba'"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable) + .withScript(insertScript) + .hasNumberOfRows(1) + .row(0) + .hasValues(1, "Paul", "Pogba"); + } + + @Test + public void + should_generate_an_insert_statement_with_columns_declared_in_the_same_order_as_in_the_table() { + + // GIVEN + String colDescsAndConstraints = + "id bigint" + ", firstName varchar(255)" + ", lastName varchar(255)"; + TestTable playerTable = + TestTable.buildUniqueTable(DATA_SOURCE, "player", colDescsAndConstraints) + .create() + .insertValues("1, 'Paul', 'Pogba'"); + + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + + // WHEN + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + assertThat(insertScript).contains("ID, FIRSTNAME, LASTNAME"); + + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable).withScript(insertScript).hasNumberOfRows(1); + } + + @Test + public void should_generate_an_insert_statement_with_not_null_columns() { + + // GIVEN + TestTable playerTable = + TestTable.buildUniqueTable( + DATA_SOURCE, + "Player", + " id bigint not null" + + ", firstName varchar(255) not null" + + ", lastName varchar(255) not null") + .create() + .insertValues("1, 'Paul', 'Pogba'"); + + String playerTableName = playerTable.getTableName(); + String select = "SELECT id FROM " + playerTableName + " WHERE lastName = 'Pogba'"; + + // WHEN + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable) + .withScript(insertScript) + .hasNumberOfRows(1) + .row(0) + .hasValues(1, "Paul", "Pogba"); + } + + @RepeatedTest(9) + public void should_sort_insert_statements_following_table_dependencies() { + + // GIVEN + TestTable teamTable = + TestTable.buildUniqueTable( + DATA_SOURCE, + "Team", + " id bigint not null" + ", name varchar(255)" + ", primary key (id)") + .create() + .insertValues("1, 'Manchester United'"); + + String playerTableConstraint = + "add constraint player_team_fk" + + generateRandomPositiveInt() + + " foreign key (team_id)" + + " references " + + teamTable.getTableName(); + TestTable playerTable = + TestTable.buildUniqueTable( + DATA_SOURCE, + "Player", + "id bigint not null" + + ", firstName varchar(255)" + + ", lastName varchar(255)" + + ", team_id bigint" + + ", primary key (id)") + .create() + .alter(playerTableConstraint) + .insertValues("1, 'Paul', 'Pogba', 1"); + + String playerSelect = "SELECT * FROM " + playerTable.getTableName(); + String teamSelect = "SELECT * FROM " + teamTable.getTableName(); + + // WHEN + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + List insertStatements = + quickSqlTestData.generateInsertListFor(playerSelect, teamSelect); + + // THEN + playerTable.drop(); + teamTable.drop().create(); + playerTable.create().alter(playerTableConstraint); + SQL_EXECUTOR.execute(insertStatements); + assertThat(playerTable).withGeneratedInserts(insertStatements).hasNumberOfRows(1); + assertThat(teamTable).withGeneratedInserts(insertStatements).hasNumberOfRows(1); + } + + private int generateRandomPositiveInt() { + Random random = new Random(); + return Math.abs(random.nextInt()); + } + + @Test + public void should_add_rows_related_to_a_not_null_foreign_key() { + + // GIVEN + TestTable teamTable = + TestTable.buildUniqueTable( + DATA_SOURCE, + "Team", + " id bigint not null" + ", name varchar(255)" + ", primary key (id)") + .create() + .insertValues("1, 'Manchester United'"); + + String playerTableConstraint = + " add constraint player_team_fk" + + generateRandomPositiveInt() + + " foreign key (team_id)" + + " references " + + teamTable.getTableName(); + TestTable playerTable = + TestTable.buildUniqueTable( + DATA_SOURCE, + "Player", + "id bigint not null" + + ", firstName varchar(255)" + + ", lastName varchar(255)" + + ", team_id bigint not null" + + ", primary key (id)") + .create() + .alter(playerTableConstraint) + .insertValues("1, 'Paul', 'Pogba', 1"); + + String playerSelect = "SELECT * FROM " + playerTable.getTableName(); + + // WHEN + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + List insertStatements = quickSqlTestData.generateInsertListFor(playerSelect); + + // THEN + playerTable.drop(); + teamTable.drop().create(); + playerTable.create().alter(playerTableConstraint); + SQL_EXECUTOR.execute(insertStatements); + assertThat(playerTable).withGeneratedInserts(insertStatements).hasNumberOfRows(1); + assertThat(teamTable).withGeneratedInserts(insertStatements).hasNumberOfRows(1); + } + + @ParameterizedTest + @ValueSource(strings = {"INT", "TINYINT", "SMALLINT", "BIGINT"}) + public void should_sort_insert_statements_following_an_integer_primary_key(String intType) { + + TestTable table = + buildUniqueTable( + DATA_SOURCE, + "table_with_int_pk", + "col_id " + + intType + + "," + + "colA varchar(20), " + + "colB varchar(20), " + + "constraint int_pk" + + generateRandomPositiveInt() + + " primary key (col_id)") + .create() + .insertValues("2, 'A', 'B'") + .insertValues("10, 'C', 'D'") + .insertValues("1, 'E', 'F'"); + + String selectAll = "SELECT * FROM " + table.getTableName(); + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + + // WHEN + List insertStatements = quickSqlTestData.generateInsertListFor(selectAll); + + // THEN + String insertStatementsAsString = insertStatements.toString(); + + String firstQuery = insertStatements.get(0); + assertThat(firstQuery).as(insertStatementsAsString).contains("VALUES(1"); + + String secondQuery = insertStatements.get(1); + assertThat(secondQuery).as(insertStatementsAsString).contains("VALUES(2"); + + String thirdQuery = insertStatements.get(2); + assertThat(thirdQuery).as(insertStatementsAsString).contains("VALUES(10"); + } + + @RepeatedTest(9) + public void should_sort_insert_statements_following_a_composite_primary_key() { + + // GIVEN + TestTable table = + TestTable.buildUniqueTable( + DATA_SOURCE, + "comp_pk", + "col_id1 integer," + + "col_id2 integer, " + + "colA varchar(20), " + + "colB varchar(20), " + + "constraint comp_pk_pk" + + generateRandomPositiveInt() + + " primary key (col_id1, col_id2)") + .create() + .insertValues("1, 2, 'colA_r1_value', 'colB_r1_value'") + .insertValues("1, 1, 'colA_r1_value', 'colB_r1_value'") + .insertValues("2, 2, 'colA_r1_value', 'colB_r1_value'") + .insertValues("2, 1, 'colA_r1_value', 'colB_r1_value'"); + + String select1 = "SELECT * FROM " + table.getTableName() + " WHERE col_id1 = 1"; + String select2 = "SELECT * FROM " + table.getTableName() + " WHERE col_id1 = 2"; + + // WHEN + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + List insertStatements = quickSqlTestData.generateInsertListFor(select1, select2); + + // THEN + String insertQueriesAsString = insertStatements.toString(); + + String firstInsert = insertStatements.get(0); + assertThat(firstInsert).as(insertQueriesAsString).contains("VALUES(1, 1"); + + String secondInsert = insertStatements.get(1); + assertThat(secondInsert).as(insertQueriesAsString).contains("VALUES(1, 2"); + + String thirdInsert = insertStatements.get(2); + assertThat(thirdInsert).as(insertQueriesAsString).contains("VALUES(2, 1"); + + String fourthInsert = insertStatements.get(3); + assertThat(fourthInsert).as(insertQueriesAsString).contains("VALUES(2, 2"); + } + + @Test + public void should_generate_an_insert_statement_with_a_date_type() { + + // GIVEN + TestTable playerTable = + buildUniqueTable(DATA_SOURCE, "Table", "date Date").create().insertValues("'2012-09-17'"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable) + .withScript(insertScript) + .hasNumberOfRows(1) + .row(0) + .hasValues("2012-09-17"); + } + + @Test + public void should_generate_an_insert_statement_with_a_timestamp_type() { + + // GIVEN + TestTable playerTable = + buildUniqueTable(DATA_SOURCE, "Table", "timestampCol TIMESTAMP") .create() .insertValues("'2012-09-17 19:56:47.32'"); - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1); - Assertions.assertThat(insertScript).contains("'2012-09-17 19:56:47.32'"); - - } - - @Test public void - should_generate_an_insert_statement_with_a_timestamp_with_time_zone_type() { - - // GIVEN - TestTable playerTable = - buildUniqueTable( DATA_SOURCE - , "Table" - , "col TIMESTAMP WITH TIME ZONE" - ) - .create() - .insertValues("'2008-08-28 10:28:38+8:00'"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1); - Assertions.assertThat(insertScript).contains("'2008-08-28 10:28:38+08:00'"); - } - - - @Test public void - should_generate_an_insert_statement_with_a_time_without_declared_time_zone_type() { - - // GIVEN - TestTable playerTable = - buildUniqueTable( DATA_SOURCE - , "Table" - , "col TIME WITHOUT TIME ZONE" - ) - .create() - .insertValues("'23:59:59'"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1) - .row(0).hasValues("23:59:59"); - - } - - @Test public void - should_generate_an_insert_statement_with_a_time_with_timezone_type() { - - // GIVEN - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Table" - , "col TIME WITH TIME ZONE" - ) - .create() - .insertValues("'23:59:59+8:00'"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1) - .row(0).hasValues(OffsetTime.parse("23:59:59+08:00")); - } - - - @Test public void - should_generate_an_insert_statement_with_a_time_type() { - - // GIVEN - TestTable playerTable = - buildUniqueTable( DATA_SOURCE - , "Table" - , "col TIME" - ) - .create() - .insertValues("'23:59:59'"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1) - .row(0).hasValues("23:59:59"); - - } + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable).withScript(insertScript).hasNumberOfRows(1); + Assertions.assertThat(insertScript).contains("'2012-09-17 19:56:47.32'"); + } + + @Test + public void + should_generate_an_insert_statement_with_a_timestamp_without_declared_time_zone_type() { + + // GIVEN + TestTable playerTable = + buildUniqueTable(DATA_SOURCE, "Table", "timestampCol TIMESTAMP WITHOUT TIME ZONE") + .create() + .insertValues("'2012-09-17 19:56:47.32'"); + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable).withScript(insertScript).hasNumberOfRows(1); + Assertions.assertThat(insertScript).contains("'2012-09-17 19:56:47.32'"); + } + + @Test + public void should_generate_an_insert_statement_with_a_timestamp_with_time_zone_type() { + + // GIVEN + TestTable playerTable = + buildUniqueTable(DATA_SOURCE, "Table", "col TIMESTAMP WITH TIME ZONE") + .create() + .insertValues("'2008-08-28 10:28:38+8:00'"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable).withScript(insertScript).hasNumberOfRows(1); + Assertions.assertThat(insertScript).contains("'2008-08-28 10:28:38+08:00'"); + } + + @Test + public void should_generate_an_insert_statement_with_a_time_without_declared_time_zone_type() { + + // GIVEN + TestTable playerTable = + buildUniqueTable(DATA_SOURCE, "Table", "col TIME WITHOUT TIME ZONE") + .create() + .insertValues("'23:59:59'"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable) + .withScript(insertScript) + .hasNumberOfRows(1) + .row(0) + .hasValues("23:59:59"); + } + + @Test + public void should_generate_an_insert_statement_with_a_time_with_timezone_type() { + + // GIVEN + TestTable playerTable = + buildUniqueTable(DATA_SOURCE, "Table", "col TIME WITH TIME ZONE") + .create() + .insertValues("'23:59:59+8:00'"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable) + .withScript(insertScript) + .hasNumberOfRows(1) + .row(0) + .hasValues(OffsetTime.parse("23:59:59+08:00")); + } + + @Test + public void should_generate_an_insert_statement_with_a_time_type() { + + // GIVEN + TestTable playerTable = + buildUniqueTable(DATA_SOURCE, "Table", "col TIME").create().insertValues("'23:59:59'"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable) + .withScript(insertScript) + .hasNumberOfRows(1) + .row(0) + .hasValues("23:59:59"); + } } diff --git a/src/test/java/org/qstd/test/InsertTest.java b/src/test/java/org/qstd/test/InsertTest.java index 1360dcb..d5c3e3e 100644 --- a/src/test/java/org/qstd/test/InsertTest.java +++ b/src/test/java/org/qstd/test/InsertTest.java @@ -12,27 +12,27 @@ */ package org.qstd.test; +import static org.assertj.core.api.Assertions.assertThat; + import org.junit.jupiter.api.Test; -import org.quickperf.sql.annotation.ExpectJdbcQueryExecution; import org.qstd.QuickSqlTestData; - -import static org.assertj.core.api.Assertions.assertThat; +import org.quickperf.sql.annotation.ExpectJdbcQueryExecution; public class InsertTest extends H2Config { - @Test public void - should_generate_an_empty_insert_script_for_an_insert_input() { - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String anInsertStatement = "INSERT INTO A_TABLE VALUES(1, 2, 3)"; - String insertScript = quickSqlTestData.generateInsertScriptFor(anInsertStatement); - assertThat(insertScript).isEmpty(); - } - - @Test @ExpectJdbcQueryExecution(0) public void - should_not_use_jdbc_execution_for_an_insert_input() { - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String anInsertStatement = "INSERT INTO A_TABLE VALUES(1, 2, 3)"; - quickSqlTestData.generateInsertScriptFor(anInsertStatement); - } + @Test + public void should_generate_an_empty_insert_script_for_an_insert_input() { + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String anInsertStatement = "INSERT INTO A_TABLE VALUES(1, 2, 3)"; + String insertScript = quickSqlTestData.generateInsertScriptFor(anInsertStatement); + assertThat(insertScript).isEmpty(); + } + @Test + @ExpectJdbcQueryExecution(0) + public void should_not_use_jdbc_execution_for_an_insert_input() { + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String anInsertStatement = "INSERT INTO A_TABLE VALUES(1, 2, 3)"; + quickSqlTestData.generateInsertScriptFor(anInsertStatement); + } } diff --git a/src/test/java/org/qstd/test/JdbcRoundtripTest.java b/src/test/java/org/qstd/test/JdbcRoundtripTest.java index 18cf04f..63f4181 100644 --- a/src/test/java/org/qstd/test/JdbcRoundtripTest.java +++ b/src/test/java/org/qstd/test/JdbcRoundtripTest.java @@ -12,99 +12,98 @@ */ package org.qstd.test; +import static org.qstd.test.TestTable.TestTableAssert.assertThat; + +import java.util.Random; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.quickperf.sql.annotation.ExpectJdbcQueryExecution; import org.qstd.QuickSqlTestData; - -import java.util.Random; - -import static org.qstd.test.TestTable.TestTableAssert.assertThat; +import org.quickperf.sql.annotation.ExpectJdbcQueryExecution; public class JdbcRoundtripTest extends H2Config { - private TestTable t1Table; - private TestTable t2Table; - private TestTable t3Table; - private String t2TableConstraint; - private String insertScript; - - @BeforeEach - public void prepare_test_data() { - - t1Table = - TestTable.buildUniqueTable(DATA_SOURCE - , "t1" - , "id_t1 bigint not null" + - ", c2_t1 varchar(255) not null" + - ", c3_t1 varchar(255) not null" + - ", c4_t1 varchar(255) not null" + - ", primary key (id_t1)" - ) - .create() - .insertValues("1, 't1_r1_c1_val', 't1_r1_c2_val', 't1_r1_c3_val'") - .insertValues("2, 't1_r2_c1_val', 't1_r2_c2_val', 't1_r2_c3_val'"); + private TestTable t1Table; + private TestTable t2Table; + private TestTable t3Table; + private String t2TableConstraint; + private String insertScript; - t2TableConstraint = "add constraint t1_t2_fk" + generateRandomPositiveInt() - + " foreign key (t1_id)" - + " references " + t1Table.getTableName(); + @BeforeEach + public void prepare_test_data() { - t2Table = - TestTable.buildUniqueTable(DATA_SOURCE - , "t2" - , "id_t2 bigint not null" + - ", t1_id bigint not null" + - ", c1_t2 varchar(255) not null" + - ", c2_t2 varchar(255) not null" + - ", c3_t2 varchar(255) not null" + - ", primary key (id_t2)") - .create() - .alter(t2TableConstraint) - .insertValues("1, 1, 't2_r1_c1_val', 't2_r1_c2_val', 't2_r1_c3_val'") - .insertValues("2, 2, 't2_r2_c1_val', 't2_r2_c2_val', 't2_r2_c3_val'"); + t1Table = + TestTable.buildUniqueTable( + DATA_SOURCE, + "t1", + "id_t1 bigint not null" + + ", c2_t1 varchar(255) not null" + + ", c3_t1 varchar(255) not null" + + ", c4_t1 varchar(255) not null" + + ", primary key (id_t1)") + .create() + .insertValues("1, 't1_r1_c1_val', 't1_r1_c2_val', 't1_r1_c3_val'") + .insertValues("2, 't1_r2_c1_val', 't1_r2_c2_val', 't1_r2_c3_val'"); - t3Table = - TestTable.buildUniqueTable(DATA_SOURCE - , "t3" - , "id_t3 bigint not null" + - ", c2_t3 varchar(255) not null" + - ", c3_t3 varchar(255) not null" + - ", c4_t3 varchar(255) not null" + - ", primary key (id_t3)") - .create() - .insertValues("1, 't3_r1_c1_val', 't3_r1_c2_val', 't3_r1_c3_val'") - .insertValues("2, 't3_r2_c1_val', 't3_r2_c2_val', 't3_r2_c3_val'"); + t2TableConstraint = + "add constraint t1_t2_fk" + + generateRandomPositiveInt() + + " foreign key (t1_id)" + + " references " + + t1Table.getTableName(); - } + t2Table = + TestTable.buildUniqueTable( + DATA_SOURCE, + "t2", + "id_t2 bigint not null" + + ", t1_id bigint not null" + + ", c1_t2 varchar(255) not null" + + ", c2_t2 varchar(255) not null" + + ", c3_t2 varchar(255) not null" + + ", primary key (id_t2)") + .create() + .alter(t2TableConstraint) + .insertValues("1, 1, 't2_r1_c1_val', 't2_r1_c2_val', 't2_r1_c3_val'") + .insertValues("2, 2, 't2_r2_c1_val', 't2_r2_c2_val', 't2_r2_c3_val'"); - private int generateRandomPositiveInt() { - Random random = new Random(); - return Math.abs(random.nextInt()); - } + t3Table = + TestTable.buildUniqueTable( + DATA_SOURCE, + "t3", + "id_t3 bigint not null" + + ", c2_t3 varchar(255) not null" + + ", c3_t3 varchar(255) not null" + + ", c4_t3 varchar(255) not null" + + ", primary key (id_t3)") + .create() + .insertValues("1, 't3_r1_c1_val', 't3_r1_c2_val', 't3_r1_c3_val'") + .insertValues("2, 't3_r2_c1_val', 't3_r2_c2_val', 't3_r2_c3_val'"); + } - @ExpectJdbcQueryExecution(23) - @Test public void - should_limit_jdbc_roundtrips() { - String t2Select = "SELECT c1_t2 FROM " + t2Table.getTableName(); - String t3Select = "SELECT c2_t3 FROM " + t3Table.getTableName(); - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - insertScript = quickSqlTestData.generateInsertScriptFor(t2Select, t3Select); - } + private int generateRandomPositiveInt() { + Random random = new Random(); + return Math.abs(random.nextInt()); + } - @AfterEach - public void check_inserted_data() { - t3Table.recreate(); - t2Table.drop(); - t1Table.drop().create(); - t2Table.create().alter(t2TableConstraint); - SQL_EXECUTOR.execute(insertScript); - assertThat(t1Table).withScript(insertScript) - .hasNumberOfRows(2); - assertThat(t2Table).withScript(insertScript) - .hasNumberOfRows(2); - assertThat(t3Table).withScript(insertScript) - .hasNumberOfRows(2); - } + @ExpectJdbcQueryExecution(23) + @Test + public void should_limit_jdbc_roundtrips() { + String t2Select = "SELECT c1_t2 FROM " + t2Table.getTableName(); + String t3Select = "SELECT c2_t3 FROM " + t3Table.getTableName(); + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + insertScript = quickSqlTestData.generateInsertScriptFor(t2Select, t3Select); + } + @AfterEach + public void check_inserted_data() { + t3Table.recreate(); + t2Table.drop(); + t1Table.drop().create(); + t2Table.create().alter(t2TableConstraint); + SQL_EXECUTOR.execute(insertScript); + assertThat(t1Table).withScript(insertScript).hasNumberOfRows(2); + assertThat(t2Table).withScript(insertScript).hasNumberOfRows(2); + assertThat(t3Table).withScript(insertScript).hasNumberOfRows(2); + } } diff --git a/src/test/java/org/qstd/test/MSSQLServerTest.java b/src/test/java/org/qstd/test/MSSQLServerTest.java index 238dd60..bc10300 100644 --- a/src/test/java/org/qstd/test/MSSQLServerTest.java +++ b/src/test/java/org/qstd/test/MSSQLServerTest.java @@ -12,6 +12,12 @@ */ package org.qstd.test; +import static org.qstd.test.TestTable.TestTableAssert.assertThat; +import static org.qstd.test.TestTable.buildUniqueTable; + +import java.util.List; +import java.util.Random; +import javax.sql.DataSource; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.*; import org.junit.jupiter.params.ParameterizedTest; @@ -19,475 +25,448 @@ import org.qstd.QuickSqlTestData; import org.testcontainers.containers.MSSQLServerContainer; -import javax.sql.DataSource; -import java.util.List; -import java.util.Random; - -import static org.qstd.test.TestTable.TestTableAssert.assertThat; -import static org.qstd.test.TestTable.buildUniqueTable; - public class MSSQLServerTest { - private static final MSSQLServerContainer MS_SQL_SERVER - = new MSSQLServerContainer("mcr.microsoft.com/mssql/server:2019-CU9-ubuntu-16.04") - .acceptLicense(); - - private static DataSource DATA_SOURCE; - - private static SqlExecutor SQL_EXECUTOR; - - @BeforeAll - public static void beforeAll() { - MS_SQL_SERVER.start(); - String jdbcUrl = MS_SQL_SERVER.getJdbcUrl(); - String userName = MS_SQL_SERVER.getUsername(); - String password = MS_SQL_SERVER.getPassword(); - DATA_SOURCE = DataSourceBuilder.INSTANCE.build(jdbcUrl, userName, password); - SQL_EXECUTOR = new SqlExecutor(DATA_SOURCE); - } - - @AfterAll - public static void stopContainer() { - MS_SQL_SERVER.stop(); - } - - @Test public void - should_generate_working_insert_from_a_select_statement() { - - // GIVEN - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Player" - , "id bigint not null, firstName varchar(255)" - + ", lastName varchar(255), primary key (id)") - .create() - .insertValues("1, 'Paul', 'Pogba'") - .insertValues("2, 'Antoine', 'Griezmann'"); - - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - - // WHEN - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(2); - - } - - - @Test public void - should_generate_an_insert_statement_with_columns_declared_in_the_same_order_as_in_the_table() { - - // GIVEN - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "player" - , "id bigint" - + ", firstName varchar(255)" - + ", lastName varchar(255)") - .create() - .insertValues("1, 'Paul', 'Pogba'"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - Assertions.assertThat(insertScript).contains("id, firstName, lastName"); - - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1); - - } - - @Test public void - should_generate_an_insert_statement_with_not_null_columns() { - - // GIVEN - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Player" - , " id bigint not null" - + ", firstName varchar(255) not null" - + ", lastName varchar(255) not null") - .create() - .insertValues("1, 'Paul', 'Pogba'"); - - String playerTableName = playerTable.getTableName(); - String select = "SELECT id FROM " + playerTableName + " WHERE lastName = 'Pogba'"; - - // WHEN - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1) - .row(0).hasValues(1, "Paul", "Pogba"); - - } - - @RepeatedTest(9) public void - should_sort_insert_statements_following_table_dependencies() { - - // GIVEN - TestTable teamTable = - buildUniqueTable(DATA_SOURCE - , "Team" - ," id bigint not null" - + ", name varchar(255)" - + ", primary key (id)") - .create() - .insertValues("1, 'Manchester United'"); - - String playerTableConstraint = "add constraint FKqfn7q18rx1dwkwui2tyl30e08" + generateRandomPositiveInt() - + " foreign key (team_id)" - + " references " + teamTable.getTableName(); - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Player" - , "id bigint not null" - + ", firstName varchar(255)" - + ", lastName varchar(255)" - + ", team_id bigint" - + ", primary key (id)") - .create() - .alter(playerTableConstraint) - .insertValues("1, 'Paul', 'Pogba', 1"); - - String playerSelect = "SELECT * FROM " + playerTable.getTableName(); - String teamSelect = "SELECT * FROM " + teamTable.getTableName(); - - // WHEN - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData - .generateInsertScriptFor(playerSelect, teamSelect); - - // THEN - playerTable.drop(); - teamTable.drop().create(); - playerTable.create().alter(playerTableConstraint); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1); - assertThat(teamTable).withScript(insertScript) - .hasNumberOfRows(1); - - } - - private int generateRandomPositiveInt() { - Random random = new Random(); - return Math.abs(random.nextInt()); - } - - @Test public void - should_add_rows_related_to_a_not_null_foreign_key() { - - // GIVEN - TestTable teamTable = - buildUniqueTable(DATA_SOURCE - , "Team" - ," id bigint not null" + - ", name varchar(255)" + - ", primary key (id)") - .create() - .insertValues("1, 'Manchester United'"); - - String playerTableConstraint = "add constraint player_team_fk" + generateRandomPositiveInt() - + " foreign key (team_id)" - + " references " + teamTable.getTableName(); - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Player" - , "id bigint not null" - + ", firstName varchar(255)" - + ", lastName varchar(255)" - + ", team_id bigint not null" - + ", primary key (id)") - .create() - .alter(playerTableConstraint) - .insertValues("1, 'Paul', 'Pogba', 1"); - - // WHEN - String playerSelect = "SELECT * FROM " + playerTable.getTableName(); - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(playerSelect); - - // THEN - playerTable.drop(); - teamTable.drop().create(); - playerTable.create().alter(playerTableConstraint); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript).hasNumberOfRows(1); - assertThat(teamTable).hasNumberOfRows(1); - - } - - @RepeatedTest(9) public void - should_sort_insert_statements_following_the_primary_key_values() { - - // GIVEN - TestTable table = - buildUniqueTable(DATA_SOURCE - , "comp_pk" - , "col_id1 integer," + - "col_id2 integer, " + - "colA varchar(20), " + - "colB varchar(20), " + - "constraint comp_pk_pk" + generateRandomPositiveInt() + " primary key (col_id1, col_id2)" - ) - .create() - .insertValues("1, 2, 'colA_r1_value', 'colB_r1_value'") - .insertValues("1, 1, 'colA_r1_value', 'colB_r1_value'") - .insertValues("2, 2, 'colA_r1_value', 'colB_r1_value'") - .insertValues("2, 1, 'colA_r1_value', 'colB_r1_value'"); - - // WHEN - String select1 = "SELECT * FROM " + table.getTableName() + " WHERE col_id1 = 1"; - String select2 = "SELECT * FROM " + table.getTableName() + " WHERE col_id1 = 2"; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - List insertStatements = quickSqlTestData.generateInsertListFor(select1, select2); - - // THEN - String insertStatementsAsString = insertStatements.toString(); - - String firstInsert = insertStatements.get(0); - Assertions.assertThat(firstInsert).as(insertStatementsAsString).contains("VALUES(1, 1"); - - String secondInsert = insertStatements.get(1); - Assertions.assertThat(secondInsert).as(insertStatementsAsString).contains("VALUES(1, 2"); - - String thirdInsert = insertStatements.get(2); - Assertions.assertThat(thirdInsert).as(insertStatementsAsString).contains("VALUES(2, 1"); - - String fourthInsert = insertStatements.get(3); - Assertions.assertThat(fourthInsert).as(insertStatementsAsString).contains("VALUES(2, 2"); - - } - - @RepeatedTest(9) public void - should_sort_insert_statements_following_the_primary_key_values_with_a_composite_composite_primary_key_having_columns_not_in_same_order_as_in_table_declaration() { - - // GIVEN - TestTable table = - buildUniqueTable(DATA_SOURCE - , "comp_pk" - , "col_id1 integer," + - "col_id2 integer, " + - "colA varchar(20), " + - "colB varchar(20), " + - "constraint comp_pk_pk" + generateRandomPositiveInt() + " primary key (col_id2, col_id1)" - ) - .create() - .insertValues("1, 2, 'colA_r1_value', 'colB_r1_value'") - .insertValues("1, 1, 'colA_r1_value', 'colB_r1_value'") - .insertValues("2, 2, 'colA_r1_value', 'colB_r1_value'") - .insertValues("2, 1, 'colA_r1_value', 'colB_r1_value'"); - - // WHEN - String selectAll = "SELECT * FROM " + table.getTableName(); - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - List insertStatements = quickSqlTestData.generateInsertListFor(selectAll); - - // THEN - String insertStatementsAsString = insertStatements.toString(); - - String firstInsert = insertStatements.get(0); - Assertions.assertThat(firstInsert).as(insertStatementsAsString).contains("VALUES(1, 1"); - - String secondInsert = insertStatements.get(1); - Assertions.assertThat(secondInsert).as(insertStatementsAsString).contains("VALUES(2, 1"); - - String thirdInsert = insertStatements.get(2); - Assertions.assertThat(thirdInsert).as(insertStatementsAsString).contains("VALUES(1, 2"); - - String fourthInsert = insertStatements.get(3); - Assertions.assertThat(fourthInsert).as(insertStatementsAsString).contains("VALUES(2, 2"); - - } - - // Not possible to both repeat and parameterize a JUnit 5 test - @ParameterizedTest - @ValueSource(strings = {"INT", "SMALLINT", "TINYINT", "BIGINT"}) - public void - should_sort_insert_statements_following_an_integer_primary_key(String intType) { - - TestTable table = - buildUniqueTable(DATA_SOURCE - , "table_with_int_pk" - , "col_id " + intType + "," + - "colA varchar(20), " + - "colB varchar(20), " + - "constraint int_pk" + generateRandomPositiveInt() + " primary key (col_id)" - ) - .create() - .insertValues("2, 'A', 'B'") - .insertValues("10, 'C', 'D'") - .insertValues("1, 'E', 'F'"); - - String selectAll = "SELECT * FROM " + table.getTableName(); - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - - // WHEN - List insertStatements = quickSqlTestData.generateInsertListFor(selectAll); - - // THEN - String insertStatementsAsString = insertStatements.toString(); - - String firstQuery = insertStatements.get(0); - Assertions.assertThat(firstQuery).as(insertStatementsAsString).contains("VALUES(1"); - - String secondQuery = insertStatements.get(1); - Assertions.assertThat(secondQuery).as(insertStatementsAsString).contains("VALUES(2"); - - String thirdQuery = insertStatements.get(2); - Assertions.assertThat(thirdQuery).as(insertStatementsAsString).contains("VALUES(10"); - - } - - - @Test public void - should_generate_an_insert_statement_with_a_date_type() { - - // GIVEN - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Table" - , "date Date" - ) - .create() - .insertValues("'2012-09-17'"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1) - .row(0).hasValues("2012-09-17"); - - } - - @Test public void - should_generate_an_insert_statement_with_a_timestamp_type() { - // DATETIME2 is a timestamp type an accuracy of 100 nanoseconds - TestTable playerTable = - buildUniqueTable( DATA_SOURCE - , "Table" - , "timestampCol DATETIME2" - ) - .create() - .insertValues("'2012-09-17 19:56:47.32'"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1); - Assertions.assertThat(insertScript).contains("'2012-09-17 19:56:47.32'"); - } - - @Test public void - should_generate_an_insert_statement_with_a_small_datetime_type() { - // SMALLDATETIME is a timestamp type an accuracy of 1 minute - TestTable playerTable = - buildUniqueTable( DATA_SOURCE - , "Table" - , "timestampCol SMALLDATETIME" - ) - .create() - .insertValues("'2012-09-17 19:56:47.32'"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1); - Assertions.assertThat(insertScript).contains("'2012-09-17 19:57:00.0'"); - } - - - @Test public void - should_generate_an_insert_statement_with_a_timestamp_with_time_zone_type() { - - // GIVEN - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Table" - , "col DATETIMEOFFSET" - ) - .create() - .insertValues("'2020-12-20 17:20:13 +03:00'"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1); - Assertions.assertThat(insertScript).contains("'2020-12-20 17:20:13 +03:00'"); - } - - - @Test public void - should_generate_an_insert_statement_with_a_time_type() { - - // GIVEN - TestTable playerTable = - buildUniqueTable( DATA_SOURCE - , "Table" - , "col TIME" - ) - .create() - .insertValues("'23:59:59'"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1) - .row(0).hasValues("23:59:59"); - - } - + private static final MSSQLServerContainer MS_SQL_SERVER = + new MSSQLServerContainer("mcr.microsoft.com/mssql/server:2019-CU9-ubuntu-16.04") + .acceptLicense(); + + private static DataSource DATA_SOURCE; + + private static SqlExecutor SQL_EXECUTOR; + + @BeforeAll + public static void beforeAll() { + MS_SQL_SERVER.start(); + String jdbcUrl = MS_SQL_SERVER.getJdbcUrl(); + String userName = MS_SQL_SERVER.getUsername(); + String password = MS_SQL_SERVER.getPassword(); + DATA_SOURCE = DataSourceBuilder.INSTANCE.build(jdbcUrl, userName, password); + SQL_EXECUTOR = new SqlExecutor(DATA_SOURCE); + } + + @AfterAll + public static void stopContainer() { + MS_SQL_SERVER.stop(); + } + + @Test + public void should_generate_working_insert_from_a_select_statement() { + + // GIVEN + TestTable playerTable = + buildUniqueTable( + DATA_SOURCE, + "Player", + "id bigint not null, firstName varchar(255)" + + ", lastName varchar(255), primary key (id)") + .create() + .insertValues("1, 'Paul', 'Pogba'") + .insertValues("2, 'Antoine', 'Griezmann'"); + + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + + // WHEN + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable).withScript(insertScript).hasNumberOfRows(2); + } + + @Test + public void + should_generate_an_insert_statement_with_columns_declared_in_the_same_order_as_in_the_table() { + + // GIVEN + TestTable playerTable = + buildUniqueTable( + DATA_SOURCE, + "player", + "id bigint" + ", firstName varchar(255)" + ", lastName varchar(255)") + .create() + .insertValues("1, 'Paul', 'Pogba'"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + Assertions.assertThat(insertScript).contains("id, firstName, lastName"); + + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable).withScript(insertScript).hasNumberOfRows(1); + } + + @Test + public void should_generate_an_insert_statement_with_not_null_columns() { + + // GIVEN + TestTable playerTable = + buildUniqueTable( + DATA_SOURCE, + "Player", + " id bigint not null" + + ", firstName varchar(255) not null" + + ", lastName varchar(255) not null") + .create() + .insertValues("1, 'Paul', 'Pogba'"); + + String playerTableName = playerTable.getTableName(); + String select = "SELECT id FROM " + playerTableName + " WHERE lastName = 'Pogba'"; + + // WHEN + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable) + .withScript(insertScript) + .hasNumberOfRows(1) + .row(0) + .hasValues(1, "Paul", "Pogba"); + } + + @RepeatedTest(9) + public void should_sort_insert_statements_following_table_dependencies() { + + // GIVEN + TestTable teamTable = + buildUniqueTable( + DATA_SOURCE, + "Team", + " id bigint not null" + ", name varchar(255)" + ", primary key (id)") + .create() + .insertValues("1, 'Manchester United'"); + + String playerTableConstraint = + "add constraint FKqfn7q18rx1dwkwui2tyl30e08" + + generateRandomPositiveInt() + + " foreign key (team_id)" + + " references " + + teamTable.getTableName(); + TestTable playerTable = + buildUniqueTable( + DATA_SOURCE, + "Player", + "id bigint not null" + + ", firstName varchar(255)" + + ", lastName varchar(255)" + + ", team_id bigint" + + ", primary key (id)") + .create() + .alter(playerTableConstraint) + .insertValues("1, 'Paul', 'Pogba', 1"); + + String playerSelect = "SELECT * FROM " + playerTable.getTableName(); + String teamSelect = "SELECT * FROM " + teamTable.getTableName(); + + // WHEN + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(playerSelect, teamSelect); + + // THEN + playerTable.drop(); + teamTable.drop().create(); + playerTable.create().alter(playerTableConstraint); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable).withScript(insertScript).hasNumberOfRows(1); + assertThat(teamTable).withScript(insertScript).hasNumberOfRows(1); + } + + private int generateRandomPositiveInt() { + Random random = new Random(); + return Math.abs(random.nextInt()); + } + + @Test + public void should_add_rows_related_to_a_not_null_foreign_key() { + + // GIVEN + TestTable teamTable = + buildUniqueTable( + DATA_SOURCE, + "Team", + " id bigint not null" + ", name varchar(255)" + ", primary key (id)") + .create() + .insertValues("1, 'Manchester United'"); + + String playerTableConstraint = + "add constraint player_team_fk" + + generateRandomPositiveInt() + + " foreign key (team_id)" + + " references " + + teamTable.getTableName(); + TestTable playerTable = + buildUniqueTable( + DATA_SOURCE, + "Player", + "id bigint not null" + + ", firstName varchar(255)" + + ", lastName varchar(255)" + + ", team_id bigint not null" + + ", primary key (id)") + .create() + .alter(playerTableConstraint) + .insertValues("1, 'Paul', 'Pogba', 1"); + + // WHEN + String playerSelect = "SELECT * FROM " + playerTable.getTableName(); + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(playerSelect); + + // THEN + playerTable.drop(); + teamTable.drop().create(); + playerTable.create().alter(playerTableConstraint); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable).withScript(insertScript).hasNumberOfRows(1); + assertThat(teamTable).hasNumberOfRows(1); + } + + @RepeatedTest(9) + public void should_sort_insert_statements_following_the_primary_key_values() { + + // GIVEN + TestTable table = + buildUniqueTable( + DATA_SOURCE, + "comp_pk", + "col_id1 integer," + + "col_id2 integer, " + + "colA varchar(20), " + + "colB varchar(20), " + + "constraint comp_pk_pk" + + generateRandomPositiveInt() + + " primary key (col_id1, col_id2)") + .create() + .insertValues("1, 2, 'colA_r1_value', 'colB_r1_value'") + .insertValues("1, 1, 'colA_r1_value', 'colB_r1_value'") + .insertValues("2, 2, 'colA_r1_value', 'colB_r1_value'") + .insertValues("2, 1, 'colA_r1_value', 'colB_r1_value'"); + + // WHEN + String select1 = "SELECT * FROM " + table.getTableName() + " WHERE col_id1 = 1"; + String select2 = "SELECT * FROM " + table.getTableName() + " WHERE col_id1 = 2"; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + List insertStatements = quickSqlTestData.generateInsertListFor(select1, select2); + + // THEN + String insertStatementsAsString = insertStatements.toString(); + + String firstInsert = insertStatements.get(0); + Assertions.assertThat(firstInsert).as(insertStatementsAsString).contains("VALUES(1, 1"); + + String secondInsert = insertStatements.get(1); + Assertions.assertThat(secondInsert).as(insertStatementsAsString).contains("VALUES(1, 2"); + + String thirdInsert = insertStatements.get(2); + Assertions.assertThat(thirdInsert).as(insertStatementsAsString).contains("VALUES(2, 1"); + + String fourthInsert = insertStatements.get(3); + Assertions.assertThat(fourthInsert).as(insertStatementsAsString).contains("VALUES(2, 2"); + } + + @RepeatedTest(9) + public void + should_sort_insert_statements_following_the_primary_key_values_with_a_composite_composite_primary_key_having_columns_not_in_same_order_as_in_table_declaration() { + + // GIVEN + TestTable table = + buildUniqueTable( + DATA_SOURCE, + "comp_pk", + "col_id1 integer," + + "col_id2 integer, " + + "colA varchar(20), " + + "colB varchar(20), " + + "constraint comp_pk_pk" + + generateRandomPositiveInt() + + " primary key (col_id2, col_id1)") + .create() + .insertValues("1, 2, 'colA_r1_value', 'colB_r1_value'") + .insertValues("1, 1, 'colA_r1_value', 'colB_r1_value'") + .insertValues("2, 2, 'colA_r1_value', 'colB_r1_value'") + .insertValues("2, 1, 'colA_r1_value', 'colB_r1_value'"); + + // WHEN + String selectAll = "SELECT * FROM " + table.getTableName(); + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + List insertStatements = quickSqlTestData.generateInsertListFor(selectAll); + + // THEN + String insertStatementsAsString = insertStatements.toString(); + + String firstInsert = insertStatements.get(0); + Assertions.assertThat(firstInsert).as(insertStatementsAsString).contains("VALUES(1, 1"); + + String secondInsert = insertStatements.get(1); + Assertions.assertThat(secondInsert).as(insertStatementsAsString).contains("VALUES(2, 1"); + + String thirdInsert = insertStatements.get(2); + Assertions.assertThat(thirdInsert).as(insertStatementsAsString).contains("VALUES(1, 2"); + + String fourthInsert = insertStatements.get(3); + Assertions.assertThat(fourthInsert).as(insertStatementsAsString).contains("VALUES(2, 2"); + } + + // Not possible to both repeat and parameterize a JUnit 5 test + @ParameterizedTest + @ValueSource(strings = {"INT", "SMALLINT", "TINYINT", "BIGINT"}) + public void should_sort_insert_statements_following_an_integer_primary_key(String intType) { + + TestTable table = + buildUniqueTable( + DATA_SOURCE, + "table_with_int_pk", + "col_id " + + intType + + "," + + "colA varchar(20), " + + "colB varchar(20), " + + "constraint int_pk" + + generateRandomPositiveInt() + + " primary key (col_id)") + .create() + .insertValues("2, 'A', 'B'") + .insertValues("10, 'C', 'D'") + .insertValues("1, 'E', 'F'"); + + String selectAll = "SELECT * FROM " + table.getTableName(); + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + + // WHEN + List insertStatements = quickSqlTestData.generateInsertListFor(selectAll); + + // THEN + String insertStatementsAsString = insertStatements.toString(); + + String firstQuery = insertStatements.get(0); + Assertions.assertThat(firstQuery).as(insertStatementsAsString).contains("VALUES(1"); + + String secondQuery = insertStatements.get(1); + Assertions.assertThat(secondQuery).as(insertStatementsAsString).contains("VALUES(2"); + + String thirdQuery = insertStatements.get(2); + Assertions.assertThat(thirdQuery).as(insertStatementsAsString).contains("VALUES(10"); + } + + @Test + public void should_generate_an_insert_statement_with_a_date_type() { + + // GIVEN + TestTable playerTable = + buildUniqueTable(DATA_SOURCE, "Table", "date Date").create().insertValues("'2012-09-17'"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable) + .withScript(insertScript) + .hasNumberOfRows(1) + .row(0) + .hasValues("2012-09-17"); + } + + @Test + public void should_generate_an_insert_statement_with_a_timestamp_type() { + // DATETIME2 is a timestamp type an accuracy of 100 nanoseconds + TestTable playerTable = + buildUniqueTable(DATA_SOURCE, "Table", "timestampCol DATETIME2") + .create() + .insertValues("'2012-09-17 19:56:47.32'"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable).withScript(insertScript).hasNumberOfRows(1); + Assertions.assertThat(insertScript).contains("'2012-09-17 19:56:47.32'"); + } + + @Test + public void should_generate_an_insert_statement_with_a_small_datetime_type() { + // SMALLDATETIME is a timestamp type an accuracy of 1 minute + TestTable playerTable = + buildUniqueTable(DATA_SOURCE, "Table", "timestampCol SMALLDATETIME") + .create() + .insertValues("'2012-09-17 19:56:47.32'"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable).withScript(insertScript).hasNumberOfRows(1); + Assertions.assertThat(insertScript).contains("'2012-09-17 19:57:00.0'"); + } + + @Test + public void should_generate_an_insert_statement_with_a_timestamp_with_time_zone_type() { + + // GIVEN + TestTable playerTable = + buildUniqueTable(DATA_SOURCE, "Table", "col DATETIMEOFFSET") + .create() + .insertValues("'2020-12-20 17:20:13 +03:00'"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable).withScript(insertScript).hasNumberOfRows(1); + Assertions.assertThat(insertScript).contains("'2020-12-20 17:20:13 +03:00'"); + } + + @Test + public void should_generate_an_insert_statement_with_a_time_type() { + + // GIVEN + TestTable playerTable = + buildUniqueTable(DATA_SOURCE, "Table", "col TIME").create().insertValues("'23:59:59'"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable) + .withScript(insertScript) + .hasNumberOfRows(1) + .row(0) + .hasValues("23:59:59"); + } } diff --git a/src/test/java/org/qstd/test/MariaDBSlowTest.java b/src/test/java/org/qstd/test/MariaDBSlowTest.java index 897c185..98cc773 100644 --- a/src/test/java/org/qstd/test/MariaDBSlowTest.java +++ b/src/test/java/org/qstd/test/MariaDBSlowTest.java @@ -12,91 +12,91 @@ */ package org.qstd.test; +import static org.qstd.test.TestTable.TestTableAssert.assertThat; +import static org.qstd.test.TestTable.buildUniqueTable; + +import java.util.List; +import java.util.Random; +import javax.sql.DataSource; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.qstd.QuickSqlTestData; import org.testcontainers.containers.MariaDBContainer; -import javax.sql.DataSource; -import java.util.List; -import java.util.Random; - -import static org.qstd.test.TestTable.TestTableAssert.assertThat; -import static org.qstd.test.TestTable.buildUniqueTable; - public class MariaDBSlowTest { - private static final String DB_USER_NAME = "user"; - - private static final String DB_PASSWORD = "pwd"; - - private static final MariaDBContainer MARIA_DB_CONTAINER - = new MariaDBContainer<>("mariadb:10.5.2") - .withDatabaseName("mariadb") - .withUsername(DB_USER_NAME) - .withPassword(DB_PASSWORD); - - private static DataSource DATA_SOURCE; - - private static SqlExecutor SQL_EXECUTOR; - - @BeforeAll - public static void beforeAll() { - MARIA_DB_CONTAINER.start(); - String jdbcUrl = MARIA_DB_CONTAINER.getJdbcUrl(); - DATA_SOURCE = DataSourceBuilder.INSTANCE.build(jdbcUrl, DB_USER_NAME, DB_PASSWORD); - SQL_EXECUTOR = new SqlExecutor(DATA_SOURCE); - } - - @Test public void - should_sort_insert_statements_following_table_dependencies() { - - // GIVEN - TestTable teamTable = - buildUniqueTable(DATA_SOURCE - , "Team" - ," id bigint not null" + - ", name varchar(255)" + - ", primary key (id)") - .create() - .insertValues("1, 'Manchester United'"); - - String playerTableConstraint = "add constraint player_team_fk" + generateRandomPositiveInt() - + " foreign key (team_id)" - + " references " + teamTable.getTableName() + " (id)"; - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Player" - , "id bigint not null" - + ", firstName varchar(255)" - + ", lastName varchar(255)" - + ", team_id bigint" - + ", primary key (id)") - .create() - .alter(playerTableConstraint) - .insertValues("1, 'Paul', 'Pogba', 1"); - - // WHEN - String playerSelect = "SELECT * FROM " + playerTable.getTableName(); - String teamSelect = "SELECT * FROM " + teamTable.getTableName(); - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - List insertStatements = quickSqlTestData.generateInsertListFor(playerSelect, teamSelect); - - // THEN - playerTable.drop(); - teamTable.drop().create(); - playerTable.create().alter(playerTableConstraint); - SQL_EXECUTOR.execute(insertStatements); - assertThat(playerTable).withGeneratedInserts(insertStatements) - .hasNumberOfRows(1); - assertThat(teamTable).withGeneratedInserts(insertStatements) - .hasNumberOfRows(1); - - } - - private int generateRandomPositiveInt() { - Random random = new Random(); - return Math.abs(random.nextInt()); - } - + private static final String DB_USER_NAME = "user"; + + private static final String DB_PASSWORD = "pwd"; + + private static final MariaDBContainer MARIA_DB_CONTAINER = + new MariaDBContainer<>("mariadb:10.5.2") + .withDatabaseName("mariadb") + .withUsername(DB_USER_NAME) + .withPassword(DB_PASSWORD); + + private static DataSource DATA_SOURCE; + + private static SqlExecutor SQL_EXECUTOR; + + @BeforeAll + public static void beforeAll() { + MARIA_DB_CONTAINER.start(); + String jdbcUrl = MARIA_DB_CONTAINER.getJdbcUrl(); + DATA_SOURCE = DataSourceBuilder.INSTANCE.build(jdbcUrl, DB_USER_NAME, DB_PASSWORD); + SQL_EXECUTOR = new SqlExecutor(DATA_SOURCE); + } + + @Test + public void should_sort_insert_statements_following_table_dependencies() { + + // GIVEN + TestTable teamTable = + buildUniqueTable( + DATA_SOURCE, + "Team", + " id bigint not null" + ", name varchar(255)" + ", primary key (id)") + .create() + .insertValues("1, 'Manchester United'"); + + String playerTableConstraint = + "add constraint player_team_fk" + + generateRandomPositiveInt() + + " foreign key (team_id)" + + " references " + + teamTable.getTableName() + + " (id)"; + TestTable playerTable = + buildUniqueTable( + DATA_SOURCE, + "Player", + "id bigint not null" + + ", firstName varchar(255)" + + ", lastName varchar(255)" + + ", team_id bigint" + + ", primary key (id)") + .create() + .alter(playerTableConstraint) + .insertValues("1, 'Paul', 'Pogba', 1"); + + // WHEN + String playerSelect = "SELECT * FROM " + playerTable.getTableName(); + String teamSelect = "SELECT * FROM " + teamTable.getTableName(); + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + List insertStatements = + quickSqlTestData.generateInsertListFor(playerSelect, teamSelect); + + // THEN + playerTable.drop(); + teamTable.drop().create(); + playerTable.create().alter(playerTableConstraint); + SQL_EXECUTOR.execute(insertStatements); + assertThat(playerTable).withGeneratedInserts(insertStatements).hasNumberOfRows(1); + assertThat(teamTable).withGeneratedInserts(insertStatements).hasNumberOfRows(1); + } + + private int generateRandomPositiveInt() { + Random random = new Random(); + return Math.abs(random.nextInt()); + } } diff --git a/src/test/java/org/qstd/test/MariaDBTest.java b/src/test/java/org/qstd/test/MariaDBTest.java index 5f000ae..e79f261 100644 --- a/src/test/java/org/qstd/test/MariaDBTest.java +++ b/src/test/java/org/qstd/test/MariaDBTest.java @@ -12,389 +12,375 @@ */ package org.qstd.test; +import static org.assertj.core.api.Assertions.assertThat; +import static org.qstd.test.TestTable.TestTableAssert.assertThat; +import static org.qstd.test.TestTable.buildUniqueTable; + +import java.util.List; +import java.util.Random; +import javax.sql.DataSource; import org.junit.jupiter.api.*; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; import org.qstd.QuickSqlTestData; import org.testcontainers.containers.MariaDBContainer; -import javax.sql.DataSource; -import java.util.List; -import java.util.Random; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.qstd.test.TestTable.TestTableAssert.assertThat; -import static org.qstd.test.TestTable.buildUniqueTable; - public class MariaDBTest { - private static final String DB_USER_NAME = "user"; - - private static final String DB_PASSWORD = "pwd"; - - private static final MariaDBContainer MARIA_DB_CONTAINER - = new MariaDBContainer<>("mariadb:10.5.2") - .withDatabaseName("mariadb") - .withUsername(DB_USER_NAME) - .withPassword(DB_PASSWORD); - - private static DataSource DATA_SOURCE; - - private static SqlExecutor SQL_EXECUTOR; - - @BeforeAll - public static void beforeAll() { - MARIA_DB_CONTAINER.start(); - String jdbcUrl = MARIA_DB_CONTAINER.getJdbcUrl(); - DATA_SOURCE = DataSourceBuilder.INSTANCE.build(jdbcUrl, DB_USER_NAME, DB_PASSWORD); - SQL_EXECUTOR = new SqlExecutor(DATA_SOURCE); - } - - @AfterAll - public static void stopContainer() { - MARIA_DB_CONTAINER.stop(); - } - - @Test public void - should_generate_working_insert_from_a_select_statement() { - - // GIVEN - String colDescsAndConstraints = " id bigint" - + ", firstName varchar(255)" - + ", lastName varchar(255)"; - TestTable playerTable = buildUniqueTable(DATA_SOURCE - , "Player" - , colDescsAndConstraints); - playerTable.create() - .insertValues("1, 'Paul', 'Pogba'"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1) - .row(0).hasValues(1, "Paul", "Pogba"); - - } - - @Test public void - should_generate_an_insert_statement_with_columns_declared_in_the_same_order_as_in_the_table() { - - // GIVEN - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "player" - , "id bigint" - + ", firstName varchar(255)" - + ", lastName varchar(255)" - ) - .create() - .insertValues("1, 'Paul', 'Pogba'"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - assertThat(insertScript).contains("id, firstName, lastName"); - - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1); - - } - - @Test public void - should_generate_an_insert_statement_with_not_null_columns() { - - // GIVEN - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Player" - , " id bigint not null" - + ", firstName varchar(255) not null" - + ", lastName varchar(255) not null" - ) - .create() - .insertValues("1, 'Paul', 'Pogba'"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT id FROM " + playerTableName + " WHERE lastName = 'Pogba'"; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1) - .row(0).hasValues(1, "Paul", "Pogba"); - - } - - private int generateRandomPositiveInt() { - Random random = new Random(); - return Math.abs(random.nextInt()); - } - - @Test public void - should_add_rows_related_to_a_not_null_foreign_key() { - - // GIVEN - TestTable teamTable = - buildUniqueTable(DATA_SOURCE - , "Team" - ," id bigint not null" + - ", name varchar(255)" + - ", primary key (id)" - ) - .create() - .insertValues("1, 'Manchester United'"); - - String playerTableConstraint = "add constraint player_team_fk" + generateRandomPositiveInt() - + " foreign key (team_id)" - + " references " + teamTable.getTableName() + " (id)"; - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Player" - , "id bigint not null" - + ", firstName varchar(255)" - + ", lastName varchar(255)" - + ", team_id bigint not null" - + ", primary key (id)" - ) - .create() - .alter(playerTableConstraint) - .insertValues("1, 'Paul', 'Pogba', 1"); - - // WHEN - String playerSelect = "SELECT * FROM " + playerTable.getTableName(); - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - List insertStatements = quickSqlTestData.generateInsertListFor(playerSelect); - - // THEN - playerTable.drop(); - teamTable.drop().create(); - playerTable.create().alter(playerTableConstraint); - SQL_EXECUTOR.execute(insertStatements); - assertThat(playerTable).withGeneratedInserts(insertStatements) - .hasNumberOfRows(1); - assertThat(teamTable).withGeneratedInserts(insertStatements) - .hasNumberOfRows(1); - - } - - @RepeatedTest(9) public void - should_sort_insert_statements_following_the_primary_key_values() { - - // GIVEN - TestTable table = - buildUniqueTable(DATA_SOURCE - , "comp_pk" - , "col_id1 integer," + - "col_id2 integer, " + - "colA varchar(20), " + - "colB varchar(20), " + - "constraint comp_pk_pk" + generateRandomPositiveInt() + " primary key (col_id1, col_id2)" - ) - .create() - .insertValues("1, 2, 'colA_r1_value', 'colB_r1_value'") - .insertValues("1, 1, 'colA_r1_value', 'colB_r1_value'") - .insertValues("2, 2, 'colA_r1_value', 'colB_r1_value'") - .insertValues("2, 1, 'colA_r1_value', 'colB_r1_value'"); - - // WHEN - String select1 = "SELECT * FROM " + table.getTableName() + " WHERE col_id1 = 1"; - String select2 = "SELECT * FROM " + table.getTableName() + " WHERE col_id1 = 2"; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - List insertStatements = quickSqlTestData.generateInsertListFor(select1, select2); - - // THEN - String insertStatementsAsString = insertStatements.toString(); - - String firstInsert = insertStatements.get(0); - assertThat(firstInsert).as(insertStatementsAsString).contains("VALUES(1, 1"); - - String secondInsert = insertStatements.get(1); - assertThat(secondInsert).as(insertStatementsAsString).contains("VALUES(1, 2"); - - String thirdInsert = insertStatements.get(2); - assertThat(thirdInsert).as(insertStatementsAsString).contains("VALUES(2, 1"); - - String fourthInsert = insertStatements.get(3); - assertThat(fourthInsert).as(insertStatementsAsString).contains("VALUES(2, 2"); - - } - - // Not possible to both repeat and parameterize a JUnit 5 test - @ParameterizedTest - @ValueSource(strings = {"INT", "TINYINT", "SMALLINT", "MEDIUMINT", "BIGINT"}) - public void - should_sort_insert_statements_following_an_integer_primary_key(String intType) { - - TestTable table = - buildUniqueTable(DATA_SOURCE - , "table_with_int_pk" - , "col_id " + intType + "," + - "colA varchar(20), " + - "colB varchar(20), " + - "constraint int_pk" + generateRandomPositiveInt() + " primary key (col_id)" - ) - .create() - .insertValues("2, 'A', 'B'") - .insertValues("10, 'C', 'D'") - .insertValues("1, 'E', 'F'"); - - String selectAll = "SELECT * FROM " + table.getTableName(); - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - - // WHEN - List insertStatements = quickSqlTestData.generateInsertListFor(selectAll); - - // THEN - String insertStatementsAsString = insertStatements.toString(); - - String firstQuery = insertStatements.get(0); - assertThat(firstQuery).as(insertStatementsAsString).contains("VALUES(1"); - - String secondQuery = insertStatements.get(1); - assertThat(secondQuery).as(insertStatementsAsString).contains("VALUES(2"); - - String thirdQuery = insertStatements.get(2); - assertThat(thirdQuery).as(insertStatementsAsString).contains("VALUES(10"); - - } - - @RepeatedTest(9) public void - should_sort_insert_statements_following_the_primary_key_values_with_a_composite_composite_primary_key_having_columns_not_in_same_order_as_in_table_declaration() { - - // GIVEN - TestTable table = - buildUniqueTable(DATA_SOURCE - , "comp_pk" - , "col_id1 integer," + - "col_id2 integer, " + - "colA varchar(20), " + - "colB varchar(20), " + - "constraint comp_pk_pk" + generateRandomPositiveInt() + " primary key (col_id2, col_id1)" - ) - .create() - .insertValues("1, 2, 'colA_r1_value', 'colB_r1_value'") - .insertValues("1, 1, 'colA_r1_value', 'colB_r1_value'") - .insertValues("2, 2, 'colA_r1_value', 'colB_r1_value'") - .insertValues("2, 1, 'colA_r1_value', 'colB_r1_value'"); - - // WHEN - String selectAll = "SELECT * FROM " + table.getTableName(); - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - List insertStatements = quickSqlTestData.generateInsertListFor(selectAll); - - // THEN - String insertQueriesAsString = insertStatements.toString(); - - String firstInsert = insertStatements.get(0); - assertThat(firstInsert).as(insertQueriesAsString).contains("VALUES(1, 1"); - - String secondInsert = insertStatements.get(1); - assertThat(secondInsert).as(insertQueriesAsString).contains("VALUES(2, 1"); - - String thirdInsert = insertStatements.get(2); - assertThat(thirdInsert).as(insertQueriesAsString).contains("VALUES(1, 2"); - - String fourthInsert = insertStatements.get(3); - assertThat(fourthInsert).as(insertQueriesAsString).contains("VALUES(2, 2"); - - } - - // Currently there is no "timestamp with timezone" ( https://jira.mariadb.org/browse/MDEV-10018 ) - - @Test public void - should_generate_an_insert_statement_with_a_date_type() { - - // GIVEN - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Table" - , "date Date" - ) - .create() - .insertValues("'2012-09-17'"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1) - .row(0).hasValues("2012-09-17"); - - } - - @Test public void - should_generate_an_insert_statement_with_a_timestamp_type() { - - // GIVEN - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Table" - , "timestampCol TIMESTAMP" - ) - .create() - .insertValues("'2012-09-17 19:56:47.32'"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1); - assertThat(insertScript).contains("'2012-09-17 19:56:47.0'"); - } - - @Test public void - should_generate_an_insert_statement_with_a_time_type() { - - // GIVEN - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Table" - , "col TIME" - ) - .create() - .insertValues("'23:59:59'"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1) - .row(0).hasValues("23:59:59"); - } - -} \ No newline at end of file + private static final String DB_USER_NAME = "user"; + + private static final String DB_PASSWORD = "pwd"; + + private static final MariaDBContainer MARIA_DB_CONTAINER = + new MariaDBContainer<>("mariadb:10.5.2") + .withDatabaseName("mariadb") + .withUsername(DB_USER_NAME) + .withPassword(DB_PASSWORD); + + private static DataSource DATA_SOURCE; + + private static SqlExecutor SQL_EXECUTOR; + + @BeforeAll + public static void beforeAll() { + MARIA_DB_CONTAINER.start(); + String jdbcUrl = MARIA_DB_CONTAINER.getJdbcUrl(); + DATA_SOURCE = DataSourceBuilder.INSTANCE.build(jdbcUrl, DB_USER_NAME, DB_PASSWORD); + SQL_EXECUTOR = new SqlExecutor(DATA_SOURCE); + } + + @AfterAll + public static void stopContainer() { + MARIA_DB_CONTAINER.stop(); + } + + @Test + public void should_generate_working_insert_from_a_select_statement() { + + // GIVEN + String colDescsAndConstraints = + " id bigint" + ", firstName varchar(255)" + ", lastName varchar(255)"; + TestTable playerTable = buildUniqueTable(DATA_SOURCE, "Player", colDescsAndConstraints); + playerTable.create().insertValues("1, 'Paul', 'Pogba'"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable) + .withScript(insertScript) + .hasNumberOfRows(1) + .row(0) + .hasValues(1, "Paul", "Pogba"); + } + + @Test + public void + should_generate_an_insert_statement_with_columns_declared_in_the_same_order_as_in_the_table() { + + // GIVEN + TestTable playerTable = + buildUniqueTable( + DATA_SOURCE, + "player", + "id bigint" + ", firstName varchar(255)" + ", lastName varchar(255)") + .create() + .insertValues("1, 'Paul', 'Pogba'"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + assertThat(insertScript).contains("id, firstName, lastName"); + + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable).withScript(insertScript).hasNumberOfRows(1); + } + + @Test + public void should_generate_an_insert_statement_with_not_null_columns() { + + // GIVEN + TestTable playerTable = + buildUniqueTable( + DATA_SOURCE, + "Player", + " id bigint not null" + + ", firstName varchar(255) not null" + + ", lastName varchar(255) not null") + .create() + .insertValues("1, 'Paul', 'Pogba'"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT id FROM " + playerTableName + " WHERE lastName = 'Pogba'"; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable) + .withScript(insertScript) + .hasNumberOfRows(1) + .row(0) + .hasValues(1, "Paul", "Pogba"); + } + + private int generateRandomPositiveInt() { + Random random = new Random(); + return Math.abs(random.nextInt()); + } + + @Test + public void should_add_rows_related_to_a_not_null_foreign_key() { + + // GIVEN + TestTable teamTable = + buildUniqueTable( + DATA_SOURCE, + "Team", + " id bigint not null" + ", name varchar(255)" + ", primary key (id)") + .create() + .insertValues("1, 'Manchester United'"); + + String playerTableConstraint = + "add constraint player_team_fk" + + generateRandomPositiveInt() + + " foreign key (team_id)" + + " references " + + teamTable.getTableName() + + " (id)"; + TestTable playerTable = + buildUniqueTable( + DATA_SOURCE, + "Player", + "id bigint not null" + + ", firstName varchar(255)" + + ", lastName varchar(255)" + + ", team_id bigint not null" + + ", primary key (id)") + .create() + .alter(playerTableConstraint) + .insertValues("1, 'Paul', 'Pogba', 1"); + + // WHEN + String playerSelect = "SELECT * FROM " + playerTable.getTableName(); + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + List insertStatements = quickSqlTestData.generateInsertListFor(playerSelect); + + // THEN + playerTable.drop(); + teamTable.drop().create(); + playerTable.create().alter(playerTableConstraint); + SQL_EXECUTOR.execute(insertStatements); + assertThat(playerTable).withGeneratedInserts(insertStatements).hasNumberOfRows(1); + assertThat(teamTable).withGeneratedInserts(insertStatements).hasNumberOfRows(1); + } + + @RepeatedTest(9) + public void should_sort_insert_statements_following_the_primary_key_values() { + + // GIVEN + TestTable table = + buildUniqueTable( + DATA_SOURCE, + "comp_pk", + "col_id1 integer," + + "col_id2 integer, " + + "colA varchar(20), " + + "colB varchar(20), " + + "constraint comp_pk_pk" + + generateRandomPositiveInt() + + " primary key (col_id1, col_id2)") + .create() + .insertValues("1, 2, 'colA_r1_value', 'colB_r1_value'") + .insertValues("1, 1, 'colA_r1_value', 'colB_r1_value'") + .insertValues("2, 2, 'colA_r1_value', 'colB_r1_value'") + .insertValues("2, 1, 'colA_r1_value', 'colB_r1_value'"); + + // WHEN + String select1 = "SELECT * FROM " + table.getTableName() + " WHERE col_id1 = 1"; + String select2 = "SELECT * FROM " + table.getTableName() + " WHERE col_id1 = 2"; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + List insertStatements = quickSqlTestData.generateInsertListFor(select1, select2); + + // THEN + String insertStatementsAsString = insertStatements.toString(); + + String firstInsert = insertStatements.get(0); + assertThat(firstInsert).as(insertStatementsAsString).contains("VALUES(1, 1"); + + String secondInsert = insertStatements.get(1); + assertThat(secondInsert).as(insertStatementsAsString).contains("VALUES(1, 2"); + + String thirdInsert = insertStatements.get(2); + assertThat(thirdInsert).as(insertStatementsAsString).contains("VALUES(2, 1"); + + String fourthInsert = insertStatements.get(3); + assertThat(fourthInsert).as(insertStatementsAsString).contains("VALUES(2, 2"); + } + + // Not possible to both repeat and parameterize a JUnit 5 test + @ParameterizedTest + @ValueSource(strings = {"INT", "TINYINT", "SMALLINT", "MEDIUMINT", "BIGINT"}) + public void should_sort_insert_statements_following_an_integer_primary_key(String intType) { + + TestTable table = + buildUniqueTable( + DATA_SOURCE, + "table_with_int_pk", + "col_id " + + intType + + "," + + "colA varchar(20), " + + "colB varchar(20), " + + "constraint int_pk" + + generateRandomPositiveInt() + + " primary key (col_id)") + .create() + .insertValues("2, 'A', 'B'") + .insertValues("10, 'C', 'D'") + .insertValues("1, 'E', 'F'"); + + String selectAll = "SELECT * FROM " + table.getTableName(); + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + + // WHEN + List insertStatements = quickSqlTestData.generateInsertListFor(selectAll); + + // THEN + String insertStatementsAsString = insertStatements.toString(); + + String firstQuery = insertStatements.get(0); + assertThat(firstQuery).as(insertStatementsAsString).contains("VALUES(1"); + + String secondQuery = insertStatements.get(1); + assertThat(secondQuery).as(insertStatementsAsString).contains("VALUES(2"); + + String thirdQuery = insertStatements.get(2); + assertThat(thirdQuery).as(insertStatementsAsString).contains("VALUES(10"); + } + + @RepeatedTest(9) + public void + should_sort_insert_statements_following_the_primary_key_values_with_a_composite_composite_primary_key_having_columns_not_in_same_order_as_in_table_declaration() { + + // GIVEN + TestTable table = + buildUniqueTable( + DATA_SOURCE, + "comp_pk", + "col_id1 integer," + + "col_id2 integer, " + + "colA varchar(20), " + + "colB varchar(20), " + + "constraint comp_pk_pk" + + generateRandomPositiveInt() + + " primary key (col_id2, col_id1)") + .create() + .insertValues("1, 2, 'colA_r1_value', 'colB_r1_value'") + .insertValues("1, 1, 'colA_r1_value', 'colB_r1_value'") + .insertValues("2, 2, 'colA_r1_value', 'colB_r1_value'") + .insertValues("2, 1, 'colA_r1_value', 'colB_r1_value'"); + + // WHEN + String selectAll = "SELECT * FROM " + table.getTableName(); + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + List insertStatements = quickSqlTestData.generateInsertListFor(selectAll); + + // THEN + String insertQueriesAsString = insertStatements.toString(); + + String firstInsert = insertStatements.get(0); + assertThat(firstInsert).as(insertQueriesAsString).contains("VALUES(1, 1"); + + String secondInsert = insertStatements.get(1); + assertThat(secondInsert).as(insertQueriesAsString).contains("VALUES(2, 1"); + + String thirdInsert = insertStatements.get(2); + assertThat(thirdInsert).as(insertQueriesAsString).contains("VALUES(1, 2"); + + String fourthInsert = insertStatements.get(3); + assertThat(fourthInsert).as(insertQueriesAsString).contains("VALUES(2, 2"); + } + + // Currently there is no "timestamp with timezone" ( https://jira.mariadb.org/browse/MDEV-10018 ) + + @Test + public void should_generate_an_insert_statement_with_a_date_type() { + + // GIVEN + TestTable playerTable = + buildUniqueTable(DATA_SOURCE, "Table", "date Date").create().insertValues("'2012-09-17'"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable) + .withScript(insertScript) + .hasNumberOfRows(1) + .row(0) + .hasValues("2012-09-17"); + } + + @Test + public void should_generate_an_insert_statement_with_a_timestamp_type() { + + // GIVEN + TestTable playerTable = + buildUniqueTable(DATA_SOURCE, "Table", "timestampCol TIMESTAMP") + .create() + .insertValues("'2012-09-17 19:56:47.32'"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable).withScript(insertScript).hasNumberOfRows(1); + assertThat(insertScript).contains("'2012-09-17 19:56:47.0'"); + } + + @Test + public void should_generate_an_insert_statement_with_a_time_type() { + + // GIVEN + TestTable playerTable = + buildUniqueTable(DATA_SOURCE, "Table", "col TIME").create().insertValues("'23:59:59'"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable) + .withScript(insertScript) + .hasNumberOfRows(1) + .row(0) + .hasValues("23:59:59"); + } +} diff --git a/src/test/java/org/qstd/test/NotFullyManagedDatabaseTest.java b/src/test/java/org/qstd/test/NotFullyManagedDatabaseTest.java index 9675c3d..420dae6 100644 --- a/src/test/java/org/qstd/test/NotFullyManagedDatabaseTest.java +++ b/src/test/java/org/qstd/test/NotFullyManagedDatabaseTest.java @@ -12,49 +12,45 @@ */ package org.qstd.test; +import static org.qstd.dbtype.DatabaseMetadataFinderFactory.createDatabaseMetadataFinderFrom; +import static org.qstd.test.TestTable.*; +import static org.qstd.test.TestTable.TestTableAssert.assertThat; + import org.junit.jupiter.api.Test; import org.qstd.DatabaseMetadataFinder; import org.qstd.QuickSqlTestData; import org.qstd.dbtype.DatabaseType; -import static org.qstd.dbtype.DatabaseMetadataFinderFactory.createDatabaseMetadataFinderFrom; -import static org.qstd.test.TestTable.*; -import static org.qstd.test.TestTable.TestTableAssert.assertThat; - public class NotFullyManagedDatabaseTest extends H2Config { - @Test public void - should_generate_insert_statements_without_necessarily_taking_account_of_database_constraints_if_the_database_is_not_supposed_to_be_fully_managed() { - - // GIVEN - TestTable table = - buildUniqueTable(DATA_SOURCE - , "Table" - , "col1 varchar(25)" - + ", col2 varchar(25)" - + ", col3 varchar(25)" - ) - .create() - .insertValues("'val1', 'val2', 'val3'") - .insertValues("'val3', 'val4', 'val5'"); - - DatabaseMetadataFinder databaseMetadataFinderOfNotFullyManagedDatabase = - createDatabaseMetadataFinderFrom(DATA_SOURCE, DatabaseType.OTHER); - QuickSqlTestData quickSqlTestDataOfNotFullyManagedDatabase = - QuickSqlTestData.buildFrom(DATA_SOURCE, DatabaseType.OTHER - , databaseMetadataFinderOfNotFullyManagedDatabase); - - String select = "SELECT col1, col2 FROM " + table.getTableName(); - - // WHEN - String insertScript = quickSqlTestDataOfNotFullyManagedDatabase.generateInsertScriptFor(select); - - // THEN - table.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(table).withScript(insertScript) - .hasNumberOfRows(2); - - } - + @Test + public void + should_generate_insert_statements_without_necessarily_taking_account_of_database_constraints_if_the_database_is_not_supposed_to_be_fully_managed() { + + // GIVEN + TestTable table = + buildUniqueTable( + DATA_SOURCE, + "Table", + "col1 varchar(25)" + ", col2 varchar(25)" + ", col3 varchar(25)") + .create() + .insertValues("'val1', 'val2', 'val3'") + .insertValues("'val3', 'val4', 'val5'"); + + DatabaseMetadataFinder databaseMetadataFinderOfNotFullyManagedDatabase = + createDatabaseMetadataFinderFrom(DATA_SOURCE, DatabaseType.OTHER); + QuickSqlTestData quickSqlTestDataOfNotFullyManagedDatabase = + QuickSqlTestData.buildFrom( + DATA_SOURCE, DatabaseType.OTHER, databaseMetadataFinderOfNotFullyManagedDatabase); + + String select = "SELECT col1, col2 FROM " + table.getTableName(); + + // WHEN + String insertScript = quickSqlTestDataOfNotFullyManagedDatabase.generateInsertScriptFor(select); + + // THEN + table.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(table).withScript(insertScript).hasNumberOfRows(2); + } } diff --git a/src/test/java/org/qstd/test/OracleTest.java b/src/test/java/org/qstd/test/OracleTest.java index 31672bc..7a3cd05 100644 --- a/src/test/java/org/qstd/test/OracleTest.java +++ b/src/test/java/org/qstd/test/OracleTest.java @@ -12,604 +12,554 @@ */ package org.qstd.test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; -import org.qstd.QuickSqlTestData; -import org.testcontainers.containers.OracleContainer; +import static org.qstd.test.TestTable.TestTableAssert.assertThat; +import static org.qstd.test.TestTable.buildUniqueTable; +import java.util.List; +import java.util.Random; +import javax.sql.DataSource; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.*; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import org.qstd.DatasetRow; - -import javax.sql.DataSource; -import java.util.List; -import java.util.Random; - -import static org.qstd.test.TestTable.TestTableAssert.assertThat; -import static org.qstd.test.TestTable.buildUniqueTable; +import org.qstd.QuickSqlTestData; +import org.testcontainers.containers.OracleContainer; public class OracleTest { - private static DataSource DATA_SOURCE; - - private static final OracleContainer ORACLE_CONTAINER - = new OracleContainer("gvenzl/oracle-xe:18-slim") - .withEnv("ORACLE_PASSWORD", "oracle"); - - private static SqlExecutor SQL_EXECUTOR; - - @BeforeAll - public static void beforeAll() { - ORACLE_CONTAINER.start(); - String jdbcUrl = ORACLE_CONTAINER.getJdbcUrl(); - DATA_SOURCE = DataSourceBuilder.INSTANCE.build(jdbcUrl - , ORACLE_CONTAINER.getUsername() - , ORACLE_CONTAINER.getPassword()); - SQL_EXECUTOR = new SqlExecutor(DATA_SOURCE); - } - - @AfterAll - public static void stopContainer() { - ORACLE_CONTAINER.stop(); - } - - @Test - public void should_generate_working_insert() { - - // GIVEN - TestTable table = - buildUniqueTable(DATA_SOURCE - , "TABLE_NAME" - , "col1 NUMBER" - + ", col2 varchar(25)" - + ", col3 varchar(25)") - .create() - .insertValues("1, 'col2_val', 'col3_val'"); - - String tableName = table.getTableName(); - DatasetRow datasetRow = - DatasetRow.ofTable(tableName) - .addColumnValue("col1", 1) - .addColumnValue("col2", "col2_val") - .addColumnValue("col3", "col3_val"); - - //WHEN - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - - List insertStatements = quickSqlTestData.generateInsertListFor(datasetRow); - - // THEN - table.recreate(); - - SQL_EXECUTOR.execute(insertStatements); - assertThat(table).withGeneratedInserts(insertStatements) - .hasNumberOfRows(1) - .row(0).hasValues(1, "col2_val", "col3_val"); - - } - - @Test public void - should_generate_an_insert_statement_with_columns_declared_in_the_same_order_as_in_the_table() { - - // GIVEN - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "player" - , "id number" - + ", firstName varchar(255)" - + ", lastName varchar(255)") - .create() - .insertValues("1, 'Paul', 'Pogba'"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - List insertStatements = quickSqlTestData.generateInsertListFor(select); - - // THEN - String insertStatement = insertStatements.get(0); - Assertions.assertThat(insertStatement).contains("ID, FIRSTNAME, LASTNAME"); - - playerTable.recreate(); - SQL_EXECUTOR.execute(insertStatements); - assertThat(playerTable).withGeneratedInserts(insertStatements) - .hasNumberOfRows(1); - - } - - @Test public void - should_generate_an_insert_statement_with_not_null_columns() { - - // GIVEN - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Player" - , " id number not null" - + ", firstName varchar(255) not null" - + ", lastName varchar(255) not null" - ) - .create() - .insertValues("1, 'Paul', 'Pogba'"); - - String select = "SELECT id FROM " + playerTable.getTableName() - + " WHERE lastName = 'Pogba'"; - - // WHEN - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - List insertStatements = quickSqlTestData.generateInsertListFor(select); - - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertStatements); - assertThat(playerTable).withGeneratedInserts(insertStatements) - .hasNumberOfRows(1) - .row(0).hasValues(1,"Paul", "Pogba"); - - } - - @RepeatedTest(9) public void - should_sort_insert_statements_following_table_dependencies() { - - // GIVEN - TestTable teamTable = - buildUniqueTable(DATA_SOURCE - , "Team" - ," id number" + - ", name varchar(255)" + - ", primary key (id)" - ) - .create() - .insertValues("1, 'Manchester United'"); - - String playerTableConstraint = "add constraint player_team_fk" + generateRandomPositiveInt() - + " foreign key (team_id)" - + " references " + teamTable.getTableName(); - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Player" - , "id number" - + ", firstName varchar(255)" - + ", lastName varchar(255)" - + ", team_id number" - + ", primary key (id)" - ) - .create() - .alter(playerTableConstraint) - .insertValues("1, 'Paul', 'Pogba', 1"); - - String playerSelect = "SELECT * FROM " + playerTable.getTableName(); - String teamSelect = "SELECT * FROM " + teamTable.getTableName(); - - // WHEN - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - List insertStatements = quickSqlTestData.generateInsertListFor(playerSelect, teamSelect); - - // THEN - playerTable.drop(); - teamTable.drop().create(); - playerTable.create().alter(playerTableConstraint); - SQL_EXECUTOR.execute(insertStatements); - assertThat(playerTable).withGeneratedInserts(insertStatements) - .hasNumberOfRows(1); - assertThat(teamTable).withGeneratedInserts(insertStatements) - .hasNumberOfRows(1); - - } - - @Test public void - should_add_rows_related_to_a_not_null_foreign_key() { - - // GIVEN - TestTable teamTable = - buildUniqueTable(DATA_SOURCE - , "Team" - , " id number not null" + - ", name varchar(255)" + - ", primary key (id)" - ) - .create() - .insertValues("1, 'Manchester United'"); - - String playerTableConstraint = "add constraint player_team_fk" + generateRandomPositiveInt() - + " foreign key (team_id)" - + " references " + teamTable.getTableName(); - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Player" - , "id number not null" - + ", firstName varchar(255)" - + ", lastName varchar(255)" - + ", team_id number not null" - + ", primary key (id)" - ) - .create() - .alter(playerTableConstraint) - .insertValues("1, 'Paul', 'Pogba', 1"); - - // WHEN - String playerSelect = "SELECT * FROM " + playerTable.getTableName(); - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - List insertStatements = quickSqlTestData.generateInsertListFor(playerSelect); - - // THEN - playerTable.drop(); - teamTable.drop().create(); - playerTable.create().alter(playerTableConstraint); - SQL_EXECUTOR.execute(insertStatements); - assertThat(playerTable).withGeneratedInserts(insertStatements) - .hasNumberOfRows(1); - assertThat(teamTable).withGeneratedInserts(insertStatements) - .hasNumberOfRows(1); - } - - @RepeatedTest(9) public void - should_sort_insert_statements_following_primary_keys() { - - // GIVEN - TestTable table = - buildUniqueTable(DATA_SOURCE - , "comp_pk" - , "col_id1 integer," + - "col_id2 integer, " + - "colA varchar(20), " + - "colB varchar(20), " + - "constraint comp_pk_pk" + generateRandomPositiveInt() + " primary key (col_id2, col_id1)" - ) - .create() - .insertValues("1, 2, 'colA_r1_value', 'colB_r1_value'") - .insertValues("1, 1, 'colA_r1_value', 'colB_r1_value'") - .insertValues("2, 2, 'colA_r1_value', 'colB_r1_value'") - .insertValues("2, 1, 'colA_r1_value', 'colB_r1_value'"); - - // WHEN - String selectAll = "SELECT * FROM " + table.getTableName(); - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - List insertStatements = quickSqlTestData.generateInsertListFor(selectAll); - - // THEN - String insertQueriesAsString = insertStatements.toString(); - - String firstInsert = insertStatements.get(0); - Assertions.assertThat(firstInsert).as(insertQueriesAsString).contains("VALUES(1, 1"); - - String secondInsert = insertStatements.get(1); - Assertions.assertThat(secondInsert).as(insertQueriesAsString).contains("VALUES(2, 1"); - - String thirdInsert = insertStatements.get(2); - Assertions.assertThat(thirdInsert).as(insertQueriesAsString).contains("VALUES(1, 2"); - - String fourthInsert = insertStatements.get(3); - Assertions.assertThat(fourthInsert).as(insertQueriesAsString).contains("VALUES(2, 2"); - - } - - // Not possible to both repeat and parameterize a JUnit 5 test - @ParameterizedTest - @ValueSource(strings = {"INTEGER", "SMALLINT"}) - public void - should_sort_insert_statements_following_an_integer_primary_key(String intType) { - - TestTable table = - buildUniqueTable(DATA_SOURCE - , "table_with_int_pk" - , "col_id " + intType + "," + - "colA varchar(20), " + - "colB varchar(20), " + - "constraint int_pk" + generateRandomPositiveInt() + " primary key (col_id)" - ) - .create() - .insertValues("2, 'A', 'B'") - .insertValues("10, 'C', 'D'") - .insertValues("1, 'E', 'F'"); - - String selectAll = "SELECT * FROM " + table.getTableName(); - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - - // WHEN - List insertStatements = quickSqlTestData.generateInsertListFor(selectAll); - - // THEN - String insertStatementsAsString = insertStatements.toString(); - - String firstQuery = insertStatements.get(0); - Assertions.assertThat(firstQuery).as(insertStatementsAsString).contains("VALUES(1"); - - String secondQuery = insertStatements.get(1); - Assertions.assertThat(secondQuery).as(insertStatementsAsString).contains("VALUES(2"); - - String thirdQuery = insertStatements.get(2); - Assertions.assertThat(thirdQuery).as(insertStatementsAsString).contains("VALUES(10"); - - } - - @Test public void - should_generate_an_insert_statement_with_a_date_type() { - - // GIVEN - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Table" - , "dateCol Date" - ) - .create() - .insertValues("TO_DATE('2012-09-17', 'yyyy-mm-dd')"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - List insertStatements = quickSqlTestData.generateInsertListFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertStatements); - assertThat(playerTable).withGeneratedInserts(insertStatements) - .hasNumberOfRows(1) - .row(0).hasValues("2012-09-17"); - - } - - @Test public void - should_generate_an_insert_statement_with_a_date_type_with_day_number_less_than_10() { - - // GIVEN - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Table" - , "dateCol Date" - ) - .create() - .insertValues("TO_DATE('2012-09-05', 'yyyy-mm-dd')"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - List insertStatements = quickSqlTestData.generateInsertListFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertStatements); - assertThat(playerTable).withGeneratedInserts(insertStatements) - .hasNumberOfRows(1) - .row(0).hasValues("2012-09-05"); - - } - - @Test public void - should_generate_an_insert_statement_with_a_date_type_with_hour_less_than_10() { - - // GIVEN - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Table" - , "dateCol Date" - ) - .create() - .insertValues("TO_DATE('2012-09-05 08', 'yyyy-mm-dd HH24')"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - List insertStatements = quickSqlTestData.generateInsertListFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertStatements); - assertThat(playerTable).withGeneratedInserts(insertStatements) - .hasNumberOfRows(1); - - String insertStatement = insertStatements.get(0); - Assertions.assertThat(insertStatement).contains("8"); - - } - - @Test public void - should_generate_an_insert_statement_with_a_date_type_with_hour_greater_than_10() { - - // GIVEN - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Table" - , "dateCol Date" - ) - .create() - .insertValues("TO_DATE('2012-09-05 13', 'yyyy-mm-dd HH24')"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - List insertStatements = quickSqlTestData.generateInsertListFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertStatements); - assertThat(playerTable).withGeneratedInserts(insertStatements) - .hasNumberOfRows(1); - - String insertStatement = insertStatements.get(0); - Assertions.assertThat(insertStatement).contains("13"); - - } - - @Test public void - should_generate_an_insert_statement_with_a_date_type_and_a_month_after_september() { - - // GIVEN - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Table" - , "dateCol Date" - ) - .create() - .insertValues("TO_DATE('2012-10-17', 'yyyy-mm-dd')"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - List insertStatements = quickSqlTestData.generateInsertListFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertStatements); - assertThat(playerTable).withGeneratedInserts(insertStatements) - .hasNumberOfRows(1) - .row(0).hasValues("2012-10-17"); - - } - - @Test public void - should_generate_an_insert_statement_with_a_date_type_and_minutes_less_than_10() { - - // GIVEN - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Table" - , "dateCol Date" - ) - .create() - .insertValues("TO_DATE('2012-09-17 16:09', 'yyyy-mm-dd HH24:MI')"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - List insertStatements = quickSqlTestData.generateInsertListFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertStatements); - assertThat(playerTable).withGeneratedInserts(insertStatements) - .hasNumberOfRows(1); - - String insertStatement = insertStatements.get(0); - Assertions.assertThat(insertStatement) - .as("Generated INSERT: " + insertStatement) - .contains("9"); - - } - - @Test public void - should_generate_an_insert_statement_with_a_date_type_and_minutes_greater_than_10() { - - // GIVEN - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Table" - , "dateCol Date" - ) - .create() - .insertValues("TO_DATE('2012-09-17 16:28', 'yyyy-mm-dd HH24:MI')"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - List insertStatements = quickSqlTestData.generateInsertListFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertStatements); - assertThat(playerTable).withGeneratedInserts(insertStatements) - .hasNumberOfRows(1); - - String insertStatement = insertStatements.get(0); - Assertions.assertThat(insertStatement) - .as("Generated INSERT: " + insertStatement) - .contains("28"); - - } - - @Test public void - should_generate_an_insert_statement_with_a_date_type_and_seconds_greater_than_nine() { - - // GIVEN - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Table" - , "dateCol Date" - ) - .create() - .insertValues("TO_DATE('2012-10-17 17:22:33', 'yyyy-mm-dd HH24:MI:SS')"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - List insertStatements = quickSqlTestData.generateInsertListFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertStatements); - assertThat(playerTable).withGeneratedInserts(insertStatements) - .hasNumberOfRows(1); - - } - - @Test public void - should_generate_an_insert_statement_with_a_timestamp_type_and_ms_less_than_100() { - - // GIVEN - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Table" - , "timestampCol TIMESTAMP" - ) - .create() - .insertValues("TO_TIMESTAMP('2012-09-17 19:56:47.21', 'YYYY-MM-DD HH24:MI:SS.FF')"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - List insertStatements = quickSqlTestData.generateInsertListFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertStatements); - assertThat(playerTable).withGeneratedInserts(insertStatements) - .hasNumberOfRows(1); - String insertStatement = insertStatements.get(0); - Assertions.assertThat(insertStatement).contains("'2012-09-17 19:56:47.210'"); - - } - - @Test public void - should_generate_an_insert_statement_with_a_timestamp_type_and_milliseconds_greater_than_100() { - - // GIVEN - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Table" - , "timestampCol TIMESTAMP" - ) - .create() - .insertValues("TO_TIMESTAMP('2012-09-17 19:56:47.104', 'YYYY-MM-DD HH24:MI:SS.FF')"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - List insertStatements = quickSqlTestData.generateInsertListFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertStatements); - assertThat(playerTable).withGeneratedInserts(insertStatements) - .hasNumberOfRows(1); - String insertStatement = insertStatements.get(0); - Assertions.assertThat(insertStatement).contains("'2012-09-17 19:56:47.104'"); - - } - - private int generateRandomPositiveInt() { - Random random = new Random(); - return Math.abs(random.nextInt()); - } - + private static DataSource DATA_SOURCE; + + private static final OracleContainer ORACLE_CONTAINER = + new OracleContainer("gvenzl/oracle-xe:18-slim").withEnv("ORACLE_PASSWORD", "oracle"); + + private static SqlExecutor SQL_EXECUTOR; + + @BeforeAll + public static void beforeAll() { + ORACLE_CONTAINER.start(); + String jdbcUrl = ORACLE_CONTAINER.getJdbcUrl(); + DATA_SOURCE = + DataSourceBuilder.INSTANCE.build( + jdbcUrl, ORACLE_CONTAINER.getUsername(), ORACLE_CONTAINER.getPassword()); + SQL_EXECUTOR = new SqlExecutor(DATA_SOURCE); + } + + @AfterAll + public static void stopContainer() { + ORACLE_CONTAINER.stop(); + } + + @Test + public void should_generate_working_insert() { + + // GIVEN + TestTable table = + buildUniqueTable( + DATA_SOURCE, + "TABLE_NAME", + "col1 NUMBER" + ", col2 varchar(25)" + ", col3 varchar(25)") + .create() + .insertValues("1, 'col2_val', 'col3_val'"); + + String tableName = table.getTableName(); + DatasetRow datasetRow = + DatasetRow.ofTable(tableName) + .addColumnValue("col1", 1) + .addColumnValue("col2", "col2_val") + .addColumnValue("col3", "col3_val"); + + // WHEN + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + + List insertStatements = quickSqlTestData.generateInsertListFor(datasetRow); + + // THEN + table.recreate(); + + SQL_EXECUTOR.execute(insertStatements); + assertThat(table) + .withGeneratedInserts(insertStatements) + .hasNumberOfRows(1) + .row(0) + .hasValues(1, "col2_val", "col3_val"); + } + + @Test + public void + should_generate_an_insert_statement_with_columns_declared_in_the_same_order_as_in_the_table() { + + // GIVEN + TestTable playerTable = + buildUniqueTable( + DATA_SOURCE, + "player", + "id number" + ", firstName varchar(255)" + ", lastName varchar(255)") + .create() + .insertValues("1, 'Paul', 'Pogba'"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + List insertStatements = quickSqlTestData.generateInsertListFor(select); + + // THEN + String insertStatement = insertStatements.get(0); + Assertions.assertThat(insertStatement).contains("ID, FIRSTNAME, LASTNAME"); + + playerTable.recreate(); + SQL_EXECUTOR.execute(insertStatements); + assertThat(playerTable).withGeneratedInserts(insertStatements).hasNumberOfRows(1); + } + + @Test + public void should_generate_an_insert_statement_with_not_null_columns() { + + // GIVEN + TestTable playerTable = + buildUniqueTable( + DATA_SOURCE, + "Player", + " id number not null" + + ", firstName varchar(255) not null" + + ", lastName varchar(255) not null") + .create() + .insertValues("1, 'Paul', 'Pogba'"); + + String select = "SELECT id FROM " + playerTable.getTableName() + " WHERE lastName = 'Pogba'"; + + // WHEN + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + List insertStatements = quickSqlTestData.generateInsertListFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertStatements); + assertThat(playerTable) + .withGeneratedInserts(insertStatements) + .hasNumberOfRows(1) + .row(0) + .hasValues(1, "Paul", "Pogba"); + } + + @RepeatedTest(9) + public void should_sort_insert_statements_following_table_dependencies() { + + // GIVEN + TestTable teamTable = + buildUniqueTable( + DATA_SOURCE, "Team", " id number" + ", name varchar(255)" + ", primary key (id)") + .create() + .insertValues("1, 'Manchester United'"); + + String playerTableConstraint = + "add constraint player_team_fk" + + generateRandomPositiveInt() + + " foreign key (team_id)" + + " references " + + teamTable.getTableName(); + TestTable playerTable = + buildUniqueTable( + DATA_SOURCE, + "Player", + "id number" + + ", firstName varchar(255)" + + ", lastName varchar(255)" + + ", team_id number" + + ", primary key (id)") + .create() + .alter(playerTableConstraint) + .insertValues("1, 'Paul', 'Pogba', 1"); + + String playerSelect = "SELECT * FROM " + playerTable.getTableName(); + String teamSelect = "SELECT * FROM " + teamTable.getTableName(); + + // WHEN + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + List insertStatements = + quickSqlTestData.generateInsertListFor(playerSelect, teamSelect); + + // THEN + playerTable.drop(); + teamTable.drop().create(); + playerTable.create().alter(playerTableConstraint); + SQL_EXECUTOR.execute(insertStatements); + assertThat(playerTable).withGeneratedInserts(insertStatements).hasNumberOfRows(1); + assertThat(teamTable).withGeneratedInserts(insertStatements).hasNumberOfRows(1); + } + + @Test + public void should_add_rows_related_to_a_not_null_foreign_key() { + + // GIVEN + TestTable teamTable = + buildUniqueTable( + DATA_SOURCE, + "Team", + " id number not null" + ", name varchar(255)" + ", primary key (id)") + .create() + .insertValues("1, 'Manchester United'"); + + String playerTableConstraint = + "add constraint player_team_fk" + + generateRandomPositiveInt() + + " foreign key (team_id)" + + " references " + + teamTable.getTableName(); + TestTable playerTable = + buildUniqueTable( + DATA_SOURCE, + "Player", + "id number not null" + + ", firstName varchar(255)" + + ", lastName varchar(255)" + + ", team_id number not null" + + ", primary key (id)") + .create() + .alter(playerTableConstraint) + .insertValues("1, 'Paul', 'Pogba', 1"); + + // WHEN + String playerSelect = "SELECT * FROM " + playerTable.getTableName(); + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + List insertStatements = quickSqlTestData.generateInsertListFor(playerSelect); + + // THEN + playerTable.drop(); + teamTable.drop().create(); + playerTable.create().alter(playerTableConstraint); + SQL_EXECUTOR.execute(insertStatements); + assertThat(playerTable).withGeneratedInserts(insertStatements).hasNumberOfRows(1); + assertThat(teamTable).withGeneratedInserts(insertStatements).hasNumberOfRows(1); + } + + @RepeatedTest(9) + public void should_sort_insert_statements_following_primary_keys() { + + // GIVEN + TestTable table = + buildUniqueTable( + DATA_SOURCE, + "comp_pk", + "col_id1 integer," + + "col_id2 integer, " + + "colA varchar(20), " + + "colB varchar(20), " + + "constraint comp_pk_pk" + + generateRandomPositiveInt() + + " primary key (col_id2, col_id1)") + .create() + .insertValues("1, 2, 'colA_r1_value', 'colB_r1_value'") + .insertValues("1, 1, 'colA_r1_value', 'colB_r1_value'") + .insertValues("2, 2, 'colA_r1_value', 'colB_r1_value'") + .insertValues("2, 1, 'colA_r1_value', 'colB_r1_value'"); + + // WHEN + String selectAll = "SELECT * FROM " + table.getTableName(); + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + List insertStatements = quickSqlTestData.generateInsertListFor(selectAll); + + // THEN + String insertQueriesAsString = insertStatements.toString(); + + String firstInsert = insertStatements.get(0); + Assertions.assertThat(firstInsert).as(insertQueriesAsString).contains("VALUES(1, 1"); + + String secondInsert = insertStatements.get(1); + Assertions.assertThat(secondInsert).as(insertQueriesAsString).contains("VALUES(2, 1"); + + String thirdInsert = insertStatements.get(2); + Assertions.assertThat(thirdInsert).as(insertQueriesAsString).contains("VALUES(1, 2"); + + String fourthInsert = insertStatements.get(3); + Assertions.assertThat(fourthInsert).as(insertQueriesAsString).contains("VALUES(2, 2"); + } + + // Not possible to both repeat and parameterize a JUnit 5 test + @ParameterizedTest + @ValueSource(strings = {"INTEGER", "SMALLINT"}) + public void should_sort_insert_statements_following_an_integer_primary_key(String intType) { + + TestTable table = + buildUniqueTable( + DATA_SOURCE, + "table_with_int_pk", + "col_id " + + intType + + "," + + "colA varchar(20), " + + "colB varchar(20), " + + "constraint int_pk" + + generateRandomPositiveInt() + + " primary key (col_id)") + .create() + .insertValues("2, 'A', 'B'") + .insertValues("10, 'C', 'D'") + .insertValues("1, 'E', 'F'"); + + String selectAll = "SELECT * FROM " + table.getTableName(); + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + + // WHEN + List insertStatements = quickSqlTestData.generateInsertListFor(selectAll); + + // THEN + String insertStatementsAsString = insertStatements.toString(); + + String firstQuery = insertStatements.get(0); + Assertions.assertThat(firstQuery).as(insertStatementsAsString).contains("VALUES(1"); + + String secondQuery = insertStatements.get(1); + Assertions.assertThat(secondQuery).as(insertStatementsAsString).contains("VALUES(2"); + + String thirdQuery = insertStatements.get(2); + Assertions.assertThat(thirdQuery).as(insertStatementsAsString).contains("VALUES(10"); + } + + @Test + public void should_generate_an_insert_statement_with_a_date_type() { + + // GIVEN + TestTable playerTable = + buildUniqueTable(DATA_SOURCE, "Table", "dateCol Date") + .create() + .insertValues("TO_DATE('2012-09-17', 'yyyy-mm-dd')"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + List insertStatements = quickSqlTestData.generateInsertListFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertStatements); + assertThat(playerTable) + .withGeneratedInserts(insertStatements) + .hasNumberOfRows(1) + .row(0) + .hasValues("2012-09-17"); + } + + @Test + public void should_generate_an_insert_statement_with_a_date_type_with_day_number_less_than_10() { + + // GIVEN + TestTable playerTable = + buildUniqueTable(DATA_SOURCE, "Table", "dateCol Date") + .create() + .insertValues("TO_DATE('2012-09-05', 'yyyy-mm-dd')"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + List insertStatements = quickSqlTestData.generateInsertListFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertStatements); + assertThat(playerTable) + .withGeneratedInserts(insertStatements) + .hasNumberOfRows(1) + .row(0) + .hasValues("2012-09-05"); + } + + @Test + public void should_generate_an_insert_statement_with_a_date_type_with_hour_less_than_10() { + + // GIVEN + TestTable playerTable = + buildUniqueTable(DATA_SOURCE, "Table", "dateCol Date") + .create() + .insertValues("TO_DATE('2012-09-05 08', 'yyyy-mm-dd HH24')"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + List insertStatements = quickSqlTestData.generateInsertListFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertStatements); + assertThat(playerTable).withGeneratedInserts(insertStatements).hasNumberOfRows(1); + + String insertStatement = insertStatements.get(0); + Assertions.assertThat(insertStatement).contains("8"); + } + + @Test + public void should_generate_an_insert_statement_with_a_date_type_with_hour_greater_than_10() { + + // GIVEN + TestTable playerTable = + buildUniqueTable(DATA_SOURCE, "Table", "dateCol Date") + .create() + .insertValues("TO_DATE('2012-09-05 13', 'yyyy-mm-dd HH24')"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + List insertStatements = quickSqlTestData.generateInsertListFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertStatements); + assertThat(playerTable).withGeneratedInserts(insertStatements).hasNumberOfRows(1); + + String insertStatement = insertStatements.get(0); + Assertions.assertThat(insertStatement).contains("13"); + } + + @Test + public void should_generate_an_insert_statement_with_a_date_type_and_a_month_after_september() { + + // GIVEN + TestTable playerTable = + buildUniqueTable(DATA_SOURCE, "Table", "dateCol Date") + .create() + .insertValues("TO_DATE('2012-10-17', 'yyyy-mm-dd')"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + List insertStatements = quickSqlTestData.generateInsertListFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertStatements); + assertThat(playerTable) + .withGeneratedInserts(insertStatements) + .hasNumberOfRows(1) + .row(0) + .hasValues("2012-10-17"); + } + + @Test + public void should_generate_an_insert_statement_with_a_date_type_and_minutes_less_than_10() { + + // GIVEN + TestTable playerTable = + buildUniqueTable(DATA_SOURCE, "Table", "dateCol Date") + .create() + .insertValues("TO_DATE('2012-09-17 16:09', 'yyyy-mm-dd HH24:MI')"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + List insertStatements = quickSqlTestData.generateInsertListFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertStatements); + assertThat(playerTable).withGeneratedInserts(insertStatements).hasNumberOfRows(1); + + String insertStatement = insertStatements.get(0); + Assertions.assertThat(insertStatement).as("Generated INSERT: " + insertStatement).contains("9"); + } + + @Test + public void should_generate_an_insert_statement_with_a_date_type_and_minutes_greater_than_10() { + + // GIVEN + TestTable playerTable = + buildUniqueTable(DATA_SOURCE, "Table", "dateCol Date") + .create() + .insertValues("TO_DATE('2012-09-17 16:28', 'yyyy-mm-dd HH24:MI')"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + List insertStatements = quickSqlTestData.generateInsertListFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertStatements); + assertThat(playerTable).withGeneratedInserts(insertStatements).hasNumberOfRows(1); + + String insertStatement = insertStatements.get(0); + Assertions.assertThat(insertStatement) + .as("Generated INSERT: " + insertStatement) + .contains("28"); + } + + @Test + public void should_generate_an_insert_statement_with_a_date_type_and_seconds_greater_than_nine() { + + // GIVEN + TestTable playerTable = + buildUniqueTable(DATA_SOURCE, "Table", "dateCol Date") + .create() + .insertValues("TO_DATE('2012-10-17 17:22:33', 'yyyy-mm-dd HH24:MI:SS')"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + List insertStatements = quickSqlTestData.generateInsertListFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertStatements); + assertThat(playerTable).withGeneratedInserts(insertStatements).hasNumberOfRows(1); + } + + @Test + public void should_generate_an_insert_statement_with_a_timestamp_type_and_ms_less_than_100() { + + // GIVEN + TestTable playerTable = + buildUniqueTable(DATA_SOURCE, "Table", "timestampCol TIMESTAMP") + .create() + .insertValues("TO_TIMESTAMP('2012-09-17 19:56:47.21', 'YYYY-MM-DD HH24:MI:SS.FF')"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + List insertStatements = quickSqlTestData.generateInsertListFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertStatements); + assertThat(playerTable).withGeneratedInserts(insertStatements).hasNumberOfRows(1); + String insertStatement = insertStatements.get(0); + Assertions.assertThat(insertStatement).contains("'2012-09-17 19:56:47.210'"); + } + + @Test + public void + should_generate_an_insert_statement_with_a_timestamp_type_and_milliseconds_greater_than_100() { + + // GIVEN + TestTable playerTable = + buildUniqueTable(DATA_SOURCE, "Table", "timestampCol TIMESTAMP") + .create() + .insertValues("TO_TIMESTAMP('2012-09-17 19:56:47.104', 'YYYY-MM-DD HH24:MI:SS.FF')"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + List insertStatements = quickSqlTestData.generateInsertListFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertStatements); + assertThat(playerTable).withGeneratedInserts(insertStatements).hasNumberOfRows(1); + String insertStatement = insertStatements.get(0); + Assertions.assertThat(insertStatement).contains("'2012-09-17 19:56:47.104'"); + } + + private int generateRandomPositiveInt() { + Random random = new Random(); + return Math.abs(random.nextInt()); + } } diff --git a/src/test/java/org/qstd/test/PostgreSqlTest.java b/src/test/java/org/qstd/test/PostgreSqlTest.java index d19d235..1fc9c33 100644 --- a/src/test/java/org/qstd/test/PostgreSqlTest.java +++ b/src/test/java/org/qstd/test/PostgreSqlTest.java @@ -12,6 +12,13 @@ */ package org.qstd.test; +import static org.assertj.core.api.Assertions.assertThat; +import static org.qstd.test.TestTable.TestTableAssert.assertThat; +import static org.qstd.test.TestTable.buildUniqueTable; + +import java.util.List; +import java.util.Random; +import javax.sql.DataSource; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.*; import org.junit.jupiter.params.ParameterizedTest; @@ -19,475 +26,444 @@ import org.qstd.QuickSqlTestData; import org.testcontainers.containers.PostgreSQLContainer; -import javax.sql.DataSource; -import java.util.List; -import java.util.Random; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.qstd.test.TestTable.TestTableAssert.assertThat; -import static org.qstd.test.TestTable.buildUniqueTable; - public class PostgreSqlTest { - private static final String DB_USER_NAME = "user"; - - private static final String DB_PASSWORD = "pwd"; - - private static final PostgreSQLContainer POSTGRESQL_CONTAINER - = new PostgreSQLContainer<>("postgres:12.3") - .withDatabaseName("postgresql") - .withUsername(DB_USER_NAME) - .withPassword(DB_PASSWORD); - - private static DataSource DATA_SOURCE; - - private static SqlExecutor SQL_EXECUTOR; - - @BeforeAll - public static void beforeAll() { - POSTGRESQL_CONTAINER.start(); - String jdbcUrl = POSTGRESQL_CONTAINER.getJdbcUrl(); - DATA_SOURCE = DataSourceBuilder.INSTANCE.build(jdbcUrl, DB_USER_NAME, DB_PASSWORD); - SQL_EXECUTOR = new SqlExecutor(DATA_SOURCE); - } - - @AfterAll - public static void stopContainer() { - POSTGRESQL_CONTAINER.stop(); - } - - @Test public void - should_generate_working_insert_from_a_select_statement() { - - // GIVEN - TestTable playerTable = - TestTable.buildUniqueTable(DATA_SOURCE - , "Player" - , " id bigint" - + ", firstName varchar(255)" - + ", lastName varchar(255)") - .create() - .insertValues("1, 'Paul', 'Pogba'") - .insertValues("2, 'Antoine', 'Griezmann'"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(2) - .row(0).column(0).hasValues(1, 2) - .row(0).column(1).hasValues("Paul", "Antoine") - .row(0).column(2).hasValues("Pogba", "Griezmann"); - - } - - @Test public void - should_generate_an_insert_statement_with_columns_declared_in_the_same_order_as_in_the_table() { - - // GIVEN - TestTable playerTable = - TestTable.buildUniqueTable(DATA_SOURCE - , "player" - , "id bigint" - + ", firstName varchar(255)" - + ", lastName varchar(255)") - .create() - .insertValues("1, 'Paul', 'Pogba'"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - assertThat(insertScript).contains("id, firstname, lastname"); - - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1); - - } - - @Test public void - should_generate_an_insert_with_selected_columns_only() { - - // GIVEN - TestTable playerTable = - TestTable.buildUniqueTable(DATA_SOURCE - , "Player" - , "id bigint" - + ", firstName varchar(255)" - + ", lastName varchar(255)" - ) - .create() - .insertValues("1, 'Paul', 'Pogba'"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT firstName FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1) - .row(0).column(1).hasValues("Paul"); - - } - - @Test public void - should_generate_an_insert_statement_with_not_null_columns() { - - // GIVEN - TestTable playerTable = - TestTable.buildUniqueTable(DATA_SOURCE - , "Player" - , " id bigint not null" - + ", firstName varchar(255) not null" - + ", lastName varchar(255) not null" - ) - .create() - .insertValues("1, 'Paul', 'Pogba'"); - - String select = "SELECT id FROM " + playerTable.getTableName() - + " WHERE lastName = 'Pogba'"; - - // WHEN - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1) - .row(0).hasValues(1,"Paul", "Pogba"); - - } - - @RepeatedTest(9) public void - should_sort_insert_statements_following_table_dependencies() { - - // GIVEN - TestTable teamTable = - TestTable.buildUniqueTable(DATA_SOURCE - , "Team" - ," id bigint not null" + - ", name varchar(255)" + - ", primary key (id)" - ) - .create() - .insertValues("1, 'Manchester United'"); - - String playerTableConstraint = "add constraint player_team_fk" + generateRandomPositiveInt() - + " foreign key (team_id)" - + " references " + teamTable.getTableName(); - TestTable playerTable = - TestTable.buildUniqueTable(DATA_SOURCE - , "Player" - , "id bigint not null" - + ", firstName varchar(255)" - + ", lastName varchar(255)" - + ", team_id bigint" - + ", primary key (id)" - ) - .create() - .alter(playerTableConstraint) - .insertValues("1, 'Paul', 'Pogba', 1"); - - String playerSelect = "SELECT * FROM " + playerTable.getTableName(); - String teamSelect = "SELECT * FROM " + teamTable.getTableName(); - - // WHEN - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData - .generateInsertScriptFor(playerSelect, teamSelect); - - // THEN - playerTable.drop(); - teamTable.drop().create(); - playerTable.create().alter(playerTableConstraint); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1); - assertThat(teamTable).withScript(insertScript) - .hasNumberOfRows(1); - - } - - private int generateRandomPositiveInt() { - Random random = new Random(); - return Math.abs(random.nextInt()); - } - - @Test public void - should_add_rows_related_to_a_not_null_foreign_key() { - - // GIVEN - TestTable teamTable = - TestTable.buildUniqueTable(DATA_SOURCE - , "Team" - ," id bigint not null" + - ", name varchar(255)" + - ", primary key (id)" - ) - .create() - .insertValues("1, 'Manchester United'"); - - String playerTableConstraint = "add constraint player_team_fk" + generateRandomPositiveInt() - + " foreign key (team_id)" - + " references " + teamTable.getTableName(); - TestTable playerTable = - TestTable.buildUniqueTable(DATA_SOURCE - , "Player" - , "id bigint not null" - + ", firstName varchar(255)" - + ", lastName varchar(255)" - + ", team_id bigint not null" - + ", primary key (id)" - ) - .create() - .alter(playerTableConstraint) - .insertValues("1, 'Paul', 'Pogba', 1"); - - // WHEN - String playerSelect = "SELECT * FROM " + playerTable.getTableName(); - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(playerSelect); - - // THEN - playerTable.drop(); - teamTable.drop().create(); - playerTable.create().alter(playerTableConstraint); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1); - assertThat(teamTable).withScript(insertScript) - .hasNumberOfRows(1); - - } - - @RepeatedTest(9) public void - should_sort_insert_statements_following_primary_keys() { - - // GIVEN - TestTable table = - TestTable.buildUniqueTable(DATA_SOURCE - , "comp_pk" - , "col_id1 integer," + - "col_id2 integer, " + - "colA varchar(20), " + - "colB varchar(20), " + - "constraint comp_pk_pk" + generateRandomPositiveInt() + " primary key (col_id2, col_id1)" - ) - .create() - .insertValues("1, 2, 'colA_r1_value', 'colB_r1_value'") - .insertValues("1, 1, 'colA_r1_value', 'colB_r1_value'") - .insertValues("2, 2, 'colA_r1_value', 'colB_r1_value'") - .insertValues("2, 1, 'colA_r1_value', 'colB_r1_value'"); - - // WHEN - String selectAll = "SELECT * FROM " + table.getTableName(); - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - List insertStatements = quickSqlTestData.generateInsertListFor(selectAll); - - // THEN - String insertQueriesAsString = insertStatements.toString(); - - String firstInsert = insertStatements.get(0); - assertThat(firstInsert).as(insertQueriesAsString).contains("VALUES(1, 1"); - - String secondInsert = insertStatements.get(1); - assertThat(secondInsert).as(insertQueriesAsString).contains("VALUES(2, 1"); - - String thirdInsert = insertStatements.get(2); - assertThat(thirdInsert).as(insertQueriesAsString).contains("VALUES(1, 2"); - - String fourthInsert = insertStatements.get(3); - assertThat(fourthInsert).as(insertQueriesAsString).contains("VALUES(2, 2"); - - } - - // Not possible to both repeat and parameterize a JUnit 5 test - @ParameterizedTest - @ValueSource(strings = {"INT", "SMALLINT", "BIGINT"}) - public void - should_sort_insert_statements_following_an_integer_primary_key(String intType) { - - TestTable table = - buildUniqueTable(DATA_SOURCE - , "table_with_int_pk" - , "col_id " + intType + "," + - "colA varchar(20), " + - "colB varchar(20), " + - "constraint int_pk" + generateRandomPositiveInt() + " primary key (col_id)" - ) - .create() - .insertValues("2, 'A', 'B'") - .insertValues("10, 'C', 'D'") - .insertValues("1, 'E', 'F'"); - - String selectAll = "SELECT * FROM " + table.getTableName(); - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - - // WHEN - List insertStatements = quickSqlTestData.generateInsertListFor(selectAll); - - // THEN - String insertStatementsAsString = insertStatements.toString(); - - String firstQuery = insertStatements.get(0); - assertThat(firstQuery).as(insertStatementsAsString).contains("VALUES(1"); - - String secondQuery = insertStatements.get(1); - assertThat(secondQuery).as(insertStatementsAsString).contains("VALUES(2"); - - String thirdQuery = insertStatements.get(2); - assertThat(thirdQuery).as(insertStatementsAsString).contains("VALUES(10"); - - } - - @Test public void - should_generate_an_insert_statement_with_a_date_type() { - - // GIVEN - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Table" - , "date Date" - ) - .create() - .insertValues("'2012-09-17'"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1) - .row(0).hasValues("2012-09-17"); - - } - - @Test public void - should_generate_an_insert_statement_with_a_timestamp_type() { - - // GIVEN - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Table" - , "timestampCol TIMESTAMP" - ) - .create() - .insertValues("'2012-09-17 19:56:47.32'"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1); - Assertions.assertThat(insertScript).contains("'2012-09-17 19:56:47.32'"); - - } - - @Test public void - should_generate_an_insert_statement_with_a_timestamp_with_time_zone_type() { - - // GIVEN - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Table" - , "col TIMESTAMP WITH TIME ZONE" - ) - .create() - .insertValues("'2012-09-17 19:56:47.32 UTC'"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1); - - } - - @Test public void - should_generate_an_insert_statement_with_a_time_type() { - - // GIVEN - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Table" - , "col TIME" - ) - .create() - .insertValues("'23:59:59'"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1) - .row(0).hasValues("23:59:59"); - - } - - @Test public void - should_generate_an_insert_statement_with_a_time_with_timezone_type() { - - // GIVEN - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Table" - , "col TIME WITH TIME ZONE" - ) - .create() - .insertValues("'23:59:59 UTC'"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1); - - } - + private static final String DB_USER_NAME = "user"; + + private static final String DB_PASSWORD = "pwd"; + + private static final PostgreSQLContainer POSTGRESQL_CONTAINER = + new PostgreSQLContainer<>("postgres:12.3") + .withDatabaseName("postgresql") + .withUsername(DB_USER_NAME) + .withPassword(DB_PASSWORD); + + private static DataSource DATA_SOURCE; + + private static SqlExecutor SQL_EXECUTOR; + + @BeforeAll + public static void beforeAll() { + POSTGRESQL_CONTAINER.start(); + String jdbcUrl = POSTGRESQL_CONTAINER.getJdbcUrl(); + DATA_SOURCE = DataSourceBuilder.INSTANCE.build(jdbcUrl, DB_USER_NAME, DB_PASSWORD); + SQL_EXECUTOR = new SqlExecutor(DATA_SOURCE); + } + + @AfterAll + public static void stopContainer() { + POSTGRESQL_CONTAINER.stop(); + } + + @Test + public void should_generate_working_insert_from_a_select_statement() { + + // GIVEN + TestTable playerTable = + TestTable.buildUniqueTable( + DATA_SOURCE, + "Player", + " id bigint" + ", firstName varchar(255)" + ", lastName varchar(255)") + .create() + .insertValues("1, 'Paul', 'Pogba'") + .insertValues("2, 'Antoine', 'Griezmann'"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable) + .withScript(insertScript) + .hasNumberOfRows(2) + .row(0) + .column(0) + .hasValues(1, 2) + .row(0) + .column(1) + .hasValues("Paul", "Antoine") + .row(0) + .column(2) + .hasValues("Pogba", "Griezmann"); + } + + @Test + public void + should_generate_an_insert_statement_with_columns_declared_in_the_same_order_as_in_the_table() { + + // GIVEN + TestTable playerTable = + TestTable.buildUniqueTable( + DATA_SOURCE, + "player", + "id bigint" + ", firstName varchar(255)" + ", lastName varchar(255)") + .create() + .insertValues("1, 'Paul', 'Pogba'"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + assertThat(insertScript).contains("id, firstname, lastname"); + + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable).withScript(insertScript).hasNumberOfRows(1); + } + + @Test + public void should_generate_an_insert_with_selected_columns_only() { + + // GIVEN + TestTable playerTable = + TestTable.buildUniqueTable( + DATA_SOURCE, + "Player", + "id bigint" + ", firstName varchar(255)" + ", lastName varchar(255)") + .create() + .insertValues("1, 'Paul', 'Pogba'"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT firstName FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable) + .withScript(insertScript) + .hasNumberOfRows(1) + .row(0) + .column(1) + .hasValues("Paul"); + } + + @Test + public void should_generate_an_insert_statement_with_not_null_columns() { + + // GIVEN + TestTable playerTable = + TestTable.buildUniqueTable( + DATA_SOURCE, + "Player", + " id bigint not null" + + ", firstName varchar(255) not null" + + ", lastName varchar(255) not null") + .create() + .insertValues("1, 'Paul', 'Pogba'"); + + String select = "SELECT id FROM " + playerTable.getTableName() + " WHERE lastName = 'Pogba'"; + + // WHEN + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable) + .withScript(insertScript) + .hasNumberOfRows(1) + .row(0) + .hasValues(1, "Paul", "Pogba"); + } + + @RepeatedTest(9) + public void should_sort_insert_statements_following_table_dependencies() { + + // GIVEN + TestTable teamTable = + TestTable.buildUniqueTable( + DATA_SOURCE, + "Team", + " id bigint not null" + ", name varchar(255)" + ", primary key (id)") + .create() + .insertValues("1, 'Manchester United'"); + + String playerTableConstraint = + "add constraint player_team_fk" + + generateRandomPositiveInt() + + " foreign key (team_id)" + + " references " + + teamTable.getTableName(); + TestTable playerTable = + TestTable.buildUniqueTable( + DATA_SOURCE, + "Player", + "id bigint not null" + + ", firstName varchar(255)" + + ", lastName varchar(255)" + + ", team_id bigint" + + ", primary key (id)") + .create() + .alter(playerTableConstraint) + .insertValues("1, 'Paul', 'Pogba', 1"); + + String playerSelect = "SELECT * FROM " + playerTable.getTableName(); + String teamSelect = "SELECT * FROM " + teamTable.getTableName(); + + // WHEN + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(playerSelect, teamSelect); + + // THEN + playerTable.drop(); + teamTable.drop().create(); + playerTable.create().alter(playerTableConstraint); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable).withScript(insertScript).hasNumberOfRows(1); + assertThat(teamTable).withScript(insertScript).hasNumberOfRows(1); + } + + private int generateRandomPositiveInt() { + Random random = new Random(); + return Math.abs(random.nextInt()); + } + + @Test + public void should_add_rows_related_to_a_not_null_foreign_key() { + + // GIVEN + TestTable teamTable = + TestTable.buildUniqueTable( + DATA_SOURCE, + "Team", + " id bigint not null" + ", name varchar(255)" + ", primary key (id)") + .create() + .insertValues("1, 'Manchester United'"); + + String playerTableConstraint = + "add constraint player_team_fk" + + generateRandomPositiveInt() + + " foreign key (team_id)" + + " references " + + teamTable.getTableName(); + TestTable playerTable = + TestTable.buildUniqueTable( + DATA_SOURCE, + "Player", + "id bigint not null" + + ", firstName varchar(255)" + + ", lastName varchar(255)" + + ", team_id bigint not null" + + ", primary key (id)") + .create() + .alter(playerTableConstraint) + .insertValues("1, 'Paul', 'Pogba', 1"); + + // WHEN + String playerSelect = "SELECT * FROM " + playerTable.getTableName(); + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(playerSelect); + + // THEN + playerTable.drop(); + teamTable.drop().create(); + playerTable.create().alter(playerTableConstraint); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable).withScript(insertScript).hasNumberOfRows(1); + assertThat(teamTable).withScript(insertScript).hasNumberOfRows(1); + } + + @RepeatedTest(9) + public void should_sort_insert_statements_following_primary_keys() { + + // GIVEN + TestTable table = + TestTable.buildUniqueTable( + DATA_SOURCE, + "comp_pk", + "col_id1 integer," + + "col_id2 integer, " + + "colA varchar(20), " + + "colB varchar(20), " + + "constraint comp_pk_pk" + + generateRandomPositiveInt() + + " primary key (col_id2, col_id1)") + .create() + .insertValues("1, 2, 'colA_r1_value', 'colB_r1_value'") + .insertValues("1, 1, 'colA_r1_value', 'colB_r1_value'") + .insertValues("2, 2, 'colA_r1_value', 'colB_r1_value'") + .insertValues("2, 1, 'colA_r1_value', 'colB_r1_value'"); + + // WHEN + String selectAll = "SELECT * FROM " + table.getTableName(); + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + List insertStatements = quickSqlTestData.generateInsertListFor(selectAll); + + // THEN + String insertQueriesAsString = insertStatements.toString(); + + String firstInsert = insertStatements.get(0); + assertThat(firstInsert).as(insertQueriesAsString).contains("VALUES(1, 1"); + + String secondInsert = insertStatements.get(1); + assertThat(secondInsert).as(insertQueriesAsString).contains("VALUES(2, 1"); + + String thirdInsert = insertStatements.get(2); + assertThat(thirdInsert).as(insertQueriesAsString).contains("VALUES(1, 2"); + + String fourthInsert = insertStatements.get(3); + assertThat(fourthInsert).as(insertQueriesAsString).contains("VALUES(2, 2"); + } + + // Not possible to both repeat and parameterize a JUnit 5 test + @ParameterizedTest + @ValueSource(strings = {"INT", "SMALLINT", "BIGINT"}) + public void should_sort_insert_statements_following_an_integer_primary_key(String intType) { + + TestTable table = + buildUniqueTable( + DATA_SOURCE, + "table_with_int_pk", + "col_id " + + intType + + "," + + "colA varchar(20), " + + "colB varchar(20), " + + "constraint int_pk" + + generateRandomPositiveInt() + + " primary key (col_id)") + .create() + .insertValues("2, 'A', 'B'") + .insertValues("10, 'C', 'D'") + .insertValues("1, 'E', 'F'"); + + String selectAll = "SELECT * FROM " + table.getTableName(); + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + + // WHEN + List insertStatements = quickSqlTestData.generateInsertListFor(selectAll); + + // THEN + String insertStatementsAsString = insertStatements.toString(); + + String firstQuery = insertStatements.get(0); + assertThat(firstQuery).as(insertStatementsAsString).contains("VALUES(1"); + + String secondQuery = insertStatements.get(1); + assertThat(secondQuery).as(insertStatementsAsString).contains("VALUES(2"); + + String thirdQuery = insertStatements.get(2); + assertThat(thirdQuery).as(insertStatementsAsString).contains("VALUES(10"); + } + + @Test + public void should_generate_an_insert_statement_with_a_date_type() { + + // GIVEN + TestTable playerTable = + buildUniqueTable(DATA_SOURCE, "Table", "date Date").create().insertValues("'2012-09-17'"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable) + .withScript(insertScript) + .hasNumberOfRows(1) + .row(0) + .hasValues("2012-09-17"); + } + + @Test + public void should_generate_an_insert_statement_with_a_timestamp_type() { + + // GIVEN + TestTable playerTable = + buildUniqueTable(DATA_SOURCE, "Table", "timestampCol TIMESTAMP") + .create() + .insertValues("'2012-09-17 19:56:47.32'"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable).withScript(insertScript).hasNumberOfRows(1); + Assertions.assertThat(insertScript).contains("'2012-09-17 19:56:47.32'"); + } + + @Test + public void should_generate_an_insert_statement_with_a_timestamp_with_time_zone_type() { + + // GIVEN + TestTable playerTable = + buildUniqueTable(DATA_SOURCE, "Table", "col TIMESTAMP WITH TIME ZONE") + .create() + .insertValues("'2012-09-17 19:56:47.32 UTC'"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable).withScript(insertScript).hasNumberOfRows(1); + } + + @Test + public void should_generate_an_insert_statement_with_a_time_type() { + + // GIVEN + TestTable playerTable = + buildUniqueTable(DATA_SOURCE, "Table", "col TIME").create().insertValues("'23:59:59'"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable) + .withScript(insertScript) + .hasNumberOfRows(1) + .row(0) + .hasValues("23:59:59"); + } + + @Test + public void should_generate_an_insert_statement_with_a_time_with_timezone_type() { + + // GIVEN + TestTable playerTable = + buildUniqueTable(DATA_SOURCE, "Table", "col TIME WITH TIME ZONE") + .create() + .insertValues("'23:59:59 UTC'"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable).withScript(insertScript).hasNumberOfRows(1); + } } diff --git a/src/test/java/org/qstd/test/SelectTest.java b/src/test/java/org/qstd/test/SelectTest.java index 800470c..8c3efb4 100644 --- a/src/test/java/org/qstd/test/SelectTest.java +++ b/src/test/java/org/qstd/test/SelectTest.java @@ -12,79 +12,75 @@ */ package org.qstd.test; -import org.junit.jupiter.api.Test; -import org.qstd.QuickSqlTestData; +import static org.qstd.test.TestTable.*; +import static org.qstd.test.TestTable.TestTableAssert.*; import java.util.Arrays; import java.util.List; - -import static org.qstd.test.TestTable.*; -import static org.qstd.test.TestTable.TestTableAssert.*; +import org.junit.jupiter.api.Test; +import org.qstd.QuickSqlTestData; public class SelectTest extends H2Config { - @Test public void - should_generate_working_insert_from_a_select_statement() { - - // GIVEN - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Player" - , " id bigint" - + ", firstName varchar(255)" - + ", lastName varchar(255)" - ) - .create() - .insertValues("1, 'Paul', 'Pogba'") - .insertValues("2, 'Antoine', 'Griezmann'"); - - // WHEN - String playerTableName = playerTable.getTableName(); - String select = "SELECT * FROM " + playerTableName; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select); - - // THEN - playerTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(2) - .row(0).hasValues(1, "Paul", "Pogba") - .row(1).hasValues(2, "Antoine", "Griezmann"); - - } - - @Test public void - should_generate_an_insert_statement_from_a_select_containing_bind_parameters() { - - // GIVEN - TestTable table = - buildUniqueTable(DATA_SOURCE - , "Table" - , "col1 varchar(25)" - + ", col2 varchar(25)" - + ", col3 varchar(25)" - ) - .create() - .insertValues("'val1', 'val2', 'val3'"); - - String tableName = table.getTableName(); - String select = " SELECT col1, col2, col3 FROM " + tableName - + " WHERE col2=? AND col3=?"; - - List parameterValues = Arrays.asList("val2", "val3"); - - // WHEN - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(select, parameterValues); - - // THEN - table.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(table).withScript(insertScript) - .hasNumberOfRows(1) - .row(0).hasValues("val1", "val2", "val3"); - - } - + @Test + public void should_generate_working_insert_from_a_select_statement() { + + // GIVEN + TestTable playerTable = + buildUniqueTable( + DATA_SOURCE, + "Player", + " id bigint" + ", firstName varchar(255)" + ", lastName varchar(255)") + .create() + .insertValues("1, 'Paul', 'Pogba'") + .insertValues("2, 'Antoine', 'Griezmann'"); + + // WHEN + String playerTableName = playerTable.getTableName(); + String select = "SELECT * FROM " + playerTableName; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select); + + // THEN + playerTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable) + .withScript(insertScript) + .hasNumberOfRows(2) + .row(0) + .hasValues(1, "Paul", "Pogba") + .row(1) + .hasValues(2, "Antoine", "Griezmann"); + } + + @Test + public void should_generate_an_insert_statement_from_a_select_containing_bind_parameters() { + + // GIVEN + TestTable table = + buildUniqueTable( + DATA_SOURCE, + "Table", + "col1 varchar(25)" + ", col2 varchar(25)" + ", col3 varchar(25)") + .create() + .insertValues("'val1', 'val2', 'val3'"); + + String tableName = table.getTableName(); + String select = " SELECT col1, col2, col3 FROM " + tableName + " WHERE col2=? AND col3=?"; + + List parameterValues = Arrays.asList("val2", "val3"); + + // WHEN + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(select, parameterValues); + + // THEN + table.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(table) + .withScript(insertScript) + .hasNumberOfRows(1) + .row(0) + .hasValues("val1", "val2", "val3"); + } } diff --git a/src/test/java/org/qstd/test/SortInsertStatementsTest.java b/src/test/java/org/qstd/test/SortInsertStatementsTest.java index 89da449..6ee6a38 100644 --- a/src/test/java/org/qstd/test/SortInsertStatementsTest.java +++ b/src/test/java/org/qstd/test/SortInsertStatementsTest.java @@ -12,100 +12,89 @@ */ package org.qstd.test; -import org.junit.jupiter.api.RepeatedTest; -import org.qstd.QuickSqlTestData; - -import java.util.List; -import java.util.Random; - import static org.assertj.core.api.Assertions.assertThat; import static org.qstd.test.TestTable.TestTableAssert.assertThat; import static org.qstd.test.TestTable.buildUniqueTable; -public class SortInsertStatementsTest extends H2Config { +import java.util.List; +import java.util.Random; +import org.junit.jupiter.api.RepeatedTest; +import org.qstd.QuickSqlTestData; - @RepeatedTest(9) public void - should_sort_insert_statements_following_table_dependencies() { - - // GIVEN - TestTable teamTable = - buildUniqueTable(DATA_SOURCE - , "Team" - ," id bigint not null" + - ", name varchar(255)" + - ", primary key (id)" - ) - .create() - .insertValues("1, 'Manchester United'"); - - String playerTableConstraint = "add constraint player_team_fk" + generateRandomPositiveInt() - + " foreign key (team_id)" - + " references " + teamTable.getTableName(); - TestTable playerTable = - buildUniqueTable(DATA_SOURCE - , "Player" - , "id bigint not null" - + ", firstName varchar(255)" - + ", lastName varchar(255)" - + ", team_id bigint" - + ", primary key (id)" - ) - .create() - .alter(playerTableConstraint) - .insertValues("1, 'Paul', 'Pogba', 1"); - - String playerSelect = "SELECT * FROM " + playerTable.getTableName(); - String teamSelect = "SELECT * FROM " + teamTable.getTableName(); - - // WHEN - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(playerSelect, teamSelect); - - // THEN - playerTable.drop(); - teamTable.drop().create(); - playerTable.create().alter(playerTableConstraint); - SQL_EXECUTOR.execute(insertScript); - assertThat(playerTable).withScript(insertScript) - .hasNumberOfRows(1); - assertThat(teamTable).withScript(insertScript) - .hasNumberOfRows(1); - - } - - private int generateRandomPositiveInt() { - Random random = new Random(); - return Math.abs(random.nextInt()); - } - - @RepeatedTest(9) public void - should_sort_insert_statements_following_table_names_if_independent_tables() { - - TestTable testTable1 = - buildUniqueTable(DATA_SOURCE - , "TABLE_1" - , "col varchar(20)" - ) - .create() - .insertValues("'value_col_tab1'"); - - TestTable testTable2 = - buildUniqueTable(DATA_SOURCE - , "TABLE_2" - , "col varchar(20)" - ) - .create() - .insertValues("'value_col_tab2'"); - - String tab1Select = "SELECT * FROM " + testTable1.getTableName(); - String tab2Select = "SELECT * FROM " + testTable2.getTableName(); - - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - List insertStatements = quickSqlTestData.generateInsertListFor(tab2Select, tab1Select); - - assertThat(insertStatements.get(0)).contains(testTable1.getTableName()); - assertThat(insertStatements.get(1)).contains(testTable2.getTableName()); - - } +public class SortInsertStatementsTest extends H2Config { + @RepeatedTest(9) + public void should_sort_insert_statements_following_table_dependencies() { + + // GIVEN + TestTable teamTable = + buildUniqueTable( + DATA_SOURCE, + "Team", + " id bigint not null" + ", name varchar(255)" + ", primary key (id)") + .create() + .insertValues("1, 'Manchester United'"); + + String playerTableConstraint = + "add constraint player_team_fk" + + generateRandomPositiveInt() + + " foreign key (team_id)" + + " references " + + teamTable.getTableName(); + TestTable playerTable = + buildUniqueTable( + DATA_SOURCE, + "Player", + "id bigint not null" + + ", firstName varchar(255)" + + ", lastName varchar(255)" + + ", team_id bigint" + + ", primary key (id)") + .create() + .alter(playerTableConstraint) + .insertValues("1, 'Paul', 'Pogba', 1"); + + String playerSelect = "SELECT * FROM " + playerTable.getTableName(); + String teamSelect = "SELECT * FROM " + teamTable.getTableName(); + + // WHEN + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(playerSelect, teamSelect); + + // THEN + playerTable.drop(); + teamTable.drop().create(); + playerTable.create().alter(playerTableConstraint); + SQL_EXECUTOR.execute(insertScript); + assertThat(playerTable).withScript(insertScript).hasNumberOfRows(1); + assertThat(teamTable).withScript(insertScript).hasNumberOfRows(1); + } + + private int generateRandomPositiveInt() { + Random random = new Random(); + return Math.abs(random.nextInt()); + } + + @RepeatedTest(9) + public void should_sort_insert_statements_following_table_names_if_independent_tables() { + + TestTable testTable1 = + buildUniqueTable(DATA_SOURCE, "TABLE_1", "col varchar(20)") + .create() + .insertValues("'value_col_tab1'"); + + TestTable testTable2 = + buildUniqueTable(DATA_SOURCE, "TABLE_2", "col varchar(20)") + .create() + .insertValues("'value_col_tab2'"); + + String tab1Select = "SELECT * FROM " + testTable1.getTableName(); + String tab2Select = "SELECT * FROM " + testTable2.getTableName(); + + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + List insertStatements = quickSqlTestData.generateInsertListFor(tab2Select, tab1Select); + + assertThat(insertStatements.get(0)).contains(testTable1.getTableName()); + assertThat(insertStatements.get(1)).contains(testTable2.getTableName()); + } } diff --git a/src/test/java/org/qstd/test/SortInsertStatementsWithPkTest.java b/src/test/java/org/qstd/test/SortInsertStatementsWithPkTest.java index ae6fb10..757f327 100644 --- a/src/test/java/org/qstd/test/SortInsertStatementsWithPkTest.java +++ b/src/test/java/org/qstd/test/SortInsertStatementsWithPkTest.java @@ -12,172 +12,183 @@ */ package org.qstd.test; +import static org.assertj.core.api.Assertions.assertThat; +import static org.qstd.test.TestTable.buildUniqueTable; + +import java.util.List; +import java.util.Random; import org.junit.jupiter.api.RepeatedTest; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; import org.qstd.QuickSqlTestData; -import java.util.List; -import java.util.Random; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.qstd.test.TestTable.buildUniqueTable; - public class SortInsertStatementsWithPkTest extends H2Config { - @RepeatedTest(9) public void - should_sort_insert_statements_following_a_primary_key() { - - TestTable table = - buildUniqueTable(DATA_SOURCE - , "table_with_int_pk" - , "col_id integer," + - "colA varchar(20), " + - "colB varchar(20), " + - "constraint int_pk" + generateRandomPositiveInt() + " primary key (col_id)" - ) - .create() - .insertValues("2, 'A', 'B'") - .insertValues("10, 'C', 'D'") - .insertValues("1, 'E', 'F'"); - - String selectAll = "SELECT * FROM " + table.getTableName(); - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - - // WHEN - List insertStatements = quickSqlTestData.generateInsertListFor(selectAll); - - // THEN - String insertStatementsAsString = insertStatements.toString(); - - String firstQuery = insertStatements.get(0); - assertThat(firstQuery).as(insertStatementsAsString).contains("VALUES(1"); - - String secondQuery = insertStatements.get(1); - assertThat(secondQuery).as(insertStatementsAsString).contains("VALUES(2"); - - String thirdQuery = insertStatements.get(2); - assertThat(thirdQuery).as(insertStatementsAsString).contains("VALUES(10"); - - } - - // Not possible to both repeat and parameterize a JUnit 5 test - @ParameterizedTest - @ValueSource(strings = {"INT", "TINYINT", "SMALLINT", "BIGINT"}) // http://www.h2database.com/html/datatypes.html - public void - should_sort_insert_statements_following_an_integer_primary_key(String intType) { - - TestTable table = - buildUniqueTable(DATA_SOURCE - , "table_with_int_pk" - , "col_id " + intType + "," + - "colA varchar(20), " + - "colB varchar(20), " + - "constraint int_pk" + generateRandomPositiveInt() + " primary key (col_id)" - ) - .create() - .insertValues("2, 'A', 'B'") - .insertValues("10, 'C', 'D'") - .insertValues("1, 'E', 'F'"); - - String selectAll = "SELECT * FROM " + table.getTableName(); - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - - // WHEN - List insertStatements = quickSqlTestData.generateInsertListFor(selectAll); - - // THEN - String insertStatementsAsString = insertStatements.toString(); - - String firstQuery = insertStatements.get(0); - assertThat(firstQuery).as(insertStatementsAsString).contains("VALUES(1"); - - String secondQuery = insertStatements.get(1); - assertThat(secondQuery).as(insertStatementsAsString).contains("VALUES(2"); - - String thirdQuery = insertStatements.get(2); - assertThat(thirdQuery).as(insertStatementsAsString).contains("VALUES(10"); - - } - - @RepeatedTest(9) public void - should_sort_insert_statements_following_a_composite_primary_key() { - - // GIVEN - TestTable table = - buildUniqueTable(DATA_SOURCE - , "comp_pk" - , "col_id1 integer," + - "col_id2 integer, " + - "colA varchar(20), " + - "colB varchar(20), " + - "constraint comp_pk_pk" + generateRandomPositiveInt() + " primary key (col_id2, col_id1)" - ) - .create() - .insertValues("1, 2, 'A', 'B'") - .insertValues("1, 1, 'C', 'D'") - .insertValues("2, 2, 'E', 'F'") - .insertValues("2, 1, 'G', 'H'"); - - String selectAll = "SELECT * FROM " + table.getTableName(); - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - - // WHEN - List insertStatements = quickSqlTestData.generateInsertListFor(selectAll); - - // THEN - String insertStatementsAsString = insertStatements.toString(); - - String firstQuery = insertStatements.get(0); - assertThat(firstQuery).as(insertStatementsAsString).contains("VALUES(1, 1"); - - String secondQuery = insertStatements.get(1); - assertThat(secondQuery).as(insertStatementsAsString).contains("VALUES(2, 1"); - - String thirdQuery = insertStatements.get(2); - assertThat(thirdQuery).as(insertStatementsAsString).contains("VALUES(1, 2"); - - String fourthQuery = insertStatements.get(3); - assertThat(fourthQuery).as(insertStatementsAsString).contains("VALUES(2, 2"); - - } - - @RepeatedTest(9) public void - should_not_sort_insert_statements_if_the_primary_is_not_of_int_type() { - - // GIVEN - TestTable table = - buildUniqueTable(DATA_SOURCE - , "table_with_boolean_pk" - , "col_id " + "BOOLEAN" + "," + - "colA varchar(20), " + - "colB varchar(20), " + - "constraint int_pk" + generateRandomPositiveInt() + " primary key (col_id)" - ) - .create() - .insertValues("FALSE, 'A', 'B'") - .insertValues("TRUE, 'C', 'D'"); - - String selectAll = "SELECT * FROM " + table.getTableName(); - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - - // WHEN - List insertStatements = quickSqlTestData.generateInsertListFor(selectAll); - - // THEN - String insertStatementsAsString = insertStatements.toString(); - - String firstQuery = insertStatements.get(0); - assertThat(firstQuery).as(insertStatementsAsString).contains("VALUES(false"); - - String secondQuery = insertStatements.get(1); - assertThat(secondQuery).as(insertStatementsAsString).contains("VALUES(true"); - - } - - private int generateRandomPositiveInt() { - Random random = new Random(); - return Math.abs(random.nextInt()); - } - + @RepeatedTest(9) + public void should_sort_insert_statements_following_a_primary_key() { + + TestTable table = + buildUniqueTable( + DATA_SOURCE, + "table_with_int_pk", + "col_id integer," + + "colA varchar(20), " + + "colB varchar(20), " + + "constraint int_pk" + + generateRandomPositiveInt() + + " primary key (col_id)") + .create() + .insertValues("2, 'A', 'B'") + .insertValues("10, 'C', 'D'") + .insertValues("1, 'E', 'F'"); + + String selectAll = "SELECT * FROM " + table.getTableName(); + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + + // WHEN + List insertStatements = quickSqlTestData.generateInsertListFor(selectAll); + + // THEN + String insertStatementsAsString = insertStatements.toString(); + + String firstQuery = insertStatements.get(0); + assertThat(firstQuery).as(insertStatementsAsString).contains("VALUES(1"); + + String secondQuery = insertStatements.get(1); + assertThat(secondQuery).as(insertStatementsAsString).contains("VALUES(2"); + + String thirdQuery = insertStatements.get(2); + assertThat(thirdQuery).as(insertStatementsAsString).contains("VALUES(10"); + } + + // Not possible to both repeat and parameterize a JUnit 5 test + @ParameterizedTest + @ValueSource( + strings = { + "INT", + "TINYINT", + "SMALLINT", + "BIGINT" + }) // http://www.h2database.com/html/datatypes.html + public void should_sort_insert_statements_following_an_integer_primary_key(String intType) { + + TestTable table = + buildUniqueTable( + DATA_SOURCE, + "table_with_int_pk", + "col_id " + + intType + + "," + + "colA varchar(20), " + + "colB varchar(20), " + + "constraint int_pk" + + generateRandomPositiveInt() + + " primary key (col_id)") + .create() + .insertValues("2, 'A', 'B'") + .insertValues("10, 'C', 'D'") + .insertValues("1, 'E', 'F'"); + + String selectAll = "SELECT * FROM " + table.getTableName(); + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + + // WHEN + List insertStatements = quickSqlTestData.generateInsertListFor(selectAll); + + // THEN + String insertStatementsAsString = insertStatements.toString(); + + String firstQuery = insertStatements.get(0); + assertThat(firstQuery).as(insertStatementsAsString).contains("VALUES(1"); + + String secondQuery = insertStatements.get(1); + assertThat(secondQuery).as(insertStatementsAsString).contains("VALUES(2"); + + String thirdQuery = insertStatements.get(2); + assertThat(thirdQuery).as(insertStatementsAsString).contains("VALUES(10"); + } + + @RepeatedTest(9) + public void should_sort_insert_statements_following_a_composite_primary_key() { + + // GIVEN + TestTable table = + buildUniqueTable( + DATA_SOURCE, + "comp_pk", + "col_id1 integer," + + "col_id2 integer, " + + "colA varchar(20), " + + "colB varchar(20), " + + "constraint comp_pk_pk" + + generateRandomPositiveInt() + + " primary key (col_id2, col_id1)") + .create() + .insertValues("1, 2, 'A', 'B'") + .insertValues("1, 1, 'C', 'D'") + .insertValues("2, 2, 'E', 'F'") + .insertValues("2, 1, 'G', 'H'"); + + String selectAll = "SELECT * FROM " + table.getTableName(); + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + + // WHEN + List insertStatements = quickSqlTestData.generateInsertListFor(selectAll); + + // THEN + String insertStatementsAsString = insertStatements.toString(); + + String firstQuery = insertStatements.get(0); + assertThat(firstQuery).as(insertStatementsAsString).contains("VALUES(1, 1"); + + String secondQuery = insertStatements.get(1); + assertThat(secondQuery).as(insertStatementsAsString).contains("VALUES(2, 1"); + + String thirdQuery = insertStatements.get(2); + assertThat(thirdQuery).as(insertStatementsAsString).contains("VALUES(1, 2"); + + String fourthQuery = insertStatements.get(3); + assertThat(fourthQuery).as(insertStatementsAsString).contains("VALUES(2, 2"); + } + + @RepeatedTest(9) + public void should_not_sort_insert_statements_if_the_primary_is_not_of_int_type() { + + // GIVEN + TestTable table = + buildUniqueTable( + DATA_SOURCE, + "table_with_boolean_pk", + "col_id " + + "BOOLEAN" + + "," + + "colA varchar(20), " + + "colB varchar(20), " + + "constraint int_pk" + + generateRandomPositiveInt() + + " primary key (col_id)") + .create() + .insertValues("FALSE, 'A', 'B'") + .insertValues("TRUE, 'C', 'D'"); + + String selectAll = "SELECT * FROM " + table.getTableName(); + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + + // WHEN + List insertStatements = quickSqlTestData.generateInsertListFor(selectAll); + + // THEN + String insertStatementsAsString = insertStatements.toString(); + + String firstQuery = insertStatements.get(0); + assertThat(firstQuery).as(insertStatementsAsString).contains("VALUES(false"); + + String secondQuery = insertStatements.get(1); + assertThat(secondQuery).as(insertStatementsAsString).contains("VALUES(true"); + } + + private int generateRandomPositiveInt() { + Random random = new Random(); + return Math.abs(random.nextInt()); + } } diff --git a/src/test/java/org/qstd/test/SqlExecutor.java b/src/test/java/org/qstd/test/SqlExecutor.java index b729528..8e50bd1 100644 --- a/src/test/java/org/qstd/test/SqlExecutor.java +++ b/src/test/java/org/qstd/test/SqlExecutor.java @@ -12,33 +12,32 @@ */ package org.qstd.test; -import javax.sql.DataSource; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.List; +import javax.sql.DataSource; public class SqlExecutor { - private final DataSource dataSource; + private final DataSource dataSource; - SqlExecutor(DataSource dataSource) { - this.dataSource = dataSource; - } + SqlExecutor(DataSource dataSource) { + this.dataSource = dataSource; + } - void execute(List queries) { - for (String query : queries) { - execute(query); - } + void execute(List queries) { + for (String query : queries) { + execute(query); } + } - void execute(String sql) { - try (Connection connection = dataSource.getConnection(); - PreparedStatement statement = connection.prepareStatement(sql)) { - statement.execute(); - } catch (SQLException e) { - throw new IllegalStateException("Unable to execute " + System.lineSeparator() + sql, e); - } + void execute(String sql) { + try (Connection connection = dataSource.getConnection(); + PreparedStatement statement = connection.prepareStatement(sql)) { + statement.execute(); + } catch (SQLException e) { + throw new IllegalStateException("Unable to execute " + System.lineSeparator() + sql, e); } - + } } diff --git a/src/test/java/org/qstd/test/TestTable.java b/src/test/java/org/qstd/test/TestTable.java index 2d3debf..bf589d5 100644 --- a/src/test/java/org/qstd/test/TestTable.java +++ b/src/test/java/org/qstd/test/TestTable.java @@ -12,121 +12,115 @@ */ package org.qstd.test; +import java.util.List; +import java.util.Random; +import javax.sql.DataSource; import org.assertj.core.api.AbstractAssert; import org.assertj.db.api.Assertions; import org.assertj.db.api.TableAssert; import org.assertj.db.api.TableRowAssert; import org.assertj.db.type.Table; -import javax.sql.DataSource; -import java.util.List; -import java.util.Random; - class TestTable { - private final String tableName; + private final String tableName; - private final String creationScript; + private final String creationScript; - private final DataSource dataSource; + private final DataSource dataSource; - private final SqlExecutor sqlExecutor; + private final SqlExecutor sqlExecutor; - TestTable(DataSource dataSource, String tableName, String creationScript) { - this.tableName = tableName; - this.creationScript = creationScript; - this.dataSource = dataSource; - this.sqlExecutor = new SqlExecutor(dataSource); - } + TestTable(DataSource dataSource, String tableName, String creationScript) { + this.tableName = tableName; + this.creationScript = creationScript; + this.dataSource = dataSource; + this.sqlExecutor = new SqlExecutor(dataSource); + } - static TestTable buildUniqueTable(DataSource dataSource - , String baseTableName - , String colDescsAndConstraints) { - String tableName = buildUniqueTableName(baseTableName); - String creationScript = "create table " + tableName - + "(" + colDescsAndConstraints + ")"; - return new TestTable(dataSource, tableName, creationScript); - } + static TestTable buildUniqueTable( + DataSource dataSource, String baseTableName, String colDescsAndConstraints) { + String tableName = buildUniqueTableName(baseTableName); + String creationScript = "create table " + tableName + "(" + colDescsAndConstraints + ")"; + return new TestTable(dataSource, tableName, creationScript); + } - private static String buildUniqueTableName(String baseTableName) { - return baseTableName + "_" + generateRandomPositiveInt(); - } + private static String buildUniqueTableName(String baseTableName) { + return baseTableName + "_" + generateRandomPositiveInt(); + } - private static int generateRandomPositiveInt() { - Random random = new Random(); - return Math.abs(random.nextInt()); - } + private static int generateRandomPositiveInt() { + Random random = new Random(); + return Math.abs(random.nextInt()); + } - TestTable recreate() { - drop(); - create(); - return this; - } + TestTable recreate() { + drop(); + create(); + return this; + } - TestTable drop() { - sqlExecutor.execute("drop table " + tableName); - return this; - } + TestTable drop() { + sqlExecutor.execute("drop table " + tableName); + return this; + } + + TestTable create() { + sqlExecutor.execute(creationScript); + return this; + } + + TestTable insertValues(String valuesSeparatedWithCommas) { + String insert = "INSERT INTO " + tableName + " VALUES (" + valuesSeparatedWithCommas + ")"; + sqlExecutor.execute(insert); + return this; + } - TestTable create() { - sqlExecutor.execute(creationScript); - return this; + String getTableName() { + return tableName; + } + + TestTable alter(String alterCode) { + sqlExecutor.execute("alter table " + tableName + " " + alterCode); + return this; + } + + static class TestTableAssert extends AbstractAssert { + + private static final String LINE_SEPARATOR = System.lineSeparator(); + private Table assertJDbTable; + + TestTableAssert(TestTable testTable, Class selfType) { + super(testTable, TestTableAssert.class); } - TestTable insertValues(String valuesSeparatedWithCommas) { - String insert = "INSERT INTO " + tableName + " VALUES (" +valuesSeparatedWithCommas + ")"; - sqlExecutor.execute(insert); - return this; + static TestTableAssert assertThat(TestTable testTable) { + TestTableAssert testTableAssert = new TestTableAssert(testTable, TestTableAssert.class); + testTableAssert.assertJDbTable = new Table(testTable.dataSource, testTable.tableName); + return testTableAssert; } - String getTableName() { - return tableName; + TableAssert hasNumberOfRows(int expected) { + return Assertions.assertThat(assertJDbTable).hasNumberOfRows(expected); } - TestTable alter(String alterCode) { - sqlExecutor.execute("alter table " + tableName + " " + alterCode); - return this; + TableAssert withScript(String sqlScript) { + String description = + LINE_SEPARATOR + "SQL script: " + LINE_SEPARATOR + sqlScript + LINE_SEPARATOR; + return Assertions.assertThat(assertJDbTable).as(description); } - static class TestTableAssert extends AbstractAssert { - - private static final String LINE_SEPARATOR = System.lineSeparator(); - private Table assertJDbTable; - - TestTableAssert(TestTable testTable, Class selfType) { - super(testTable, TestTableAssert.class); - } - - static TestTableAssert assertThat(TestTable testTable) { - TestTableAssert testTableAssert = new TestTableAssert(testTable, TestTableAssert.class); - testTableAssert.assertJDbTable = new Table(testTable.dataSource, testTable.tableName); - return testTableAssert; - } - - TableAssert hasNumberOfRows(int expected) { - return Assertions.assertThat(assertJDbTable).hasNumberOfRows(expected); - } - - TableAssert withScript(String sqlScript) { - String description = LINE_SEPARATOR - + "SQL script: " - + LINE_SEPARATOR - + sqlScript - + LINE_SEPARATOR; - return Assertions.assertThat(assertJDbTable).as(description); - } - - TableRowAssert row(int index) { - return Assertions.assertThat(assertJDbTable).row(index); - } - - TableAssert withGeneratedInserts(List generatedInsertStatements) { - String description = LINE_SEPARATOR - + "Queries: " - + LINE_SEPARATOR - + String.join(LINE_SEPARATOR, generatedInsertStatements); - return Assertions.assertThat(assertJDbTable).as(description); - } + TableRowAssert row(int index) { + return Assertions.assertThat(assertJDbTable).row(index); } + TableAssert withGeneratedInserts(List generatedInsertStatements) { + String description = + LINE_SEPARATOR + + "Queries: " + + LINE_SEPARATOR + + String.join(LINE_SEPARATOR, generatedInsertStatements); + return Assertions.assertThat(assertJDbTable).as(description); + } + } } diff --git a/src/test/java/org/qstd/test/UpdateTest.java b/src/test/java/org/qstd/test/UpdateTest.java index 7764fe4..c67c356 100644 --- a/src/test/java/org/qstd/test/UpdateTest.java +++ b/src/test/java/org/qstd/test/UpdateTest.java @@ -12,147 +12,168 @@ */ package org.qstd.test; -import org.junit.jupiter.api.Test; -import org.qstd.QuickSqlTestData; - import static org.qstd.test.TestTable.TestTableAssert.assertThat; import static org.qstd.test.TestTable.buildUniqueTable; -public class UpdateTest extends H2Config { +import org.junit.jupiter.api.Test; +import org.qstd.QuickSqlTestData; - @Test public void - should_generate_one_insert_if_all_rows_are_updated_and_no_mandatory_columns() { - - // GIVEN - TestTable foodTable = - buildUniqueTable(DATA_SOURCE - , "Food" - , " id bigint" - + ", Dishname varchar(255)" - + ", Allergy varchar(255)" - + ", Price decimal") - .create() - .insertValues("1, 'Spaghetti Bolognese', 'cheese', 6.80") - .insertValues("2, 'Pizza Margherita', 'pasta', 7.99"); - - // WHEN - String foodTableName = foodTable.getTableName(); - String updateQuery = "UPDATE " + foodTableName - + " SET Price = 7.00, Allergy = 'none'"; - - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(updateQuery); - - // THEN - foodTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(foodTable).withScript(insertScript) - .hasNumberOfRows(2) - .row(0).hasValues(null, null, "cheese", 6.80); - - } - - @Test public void - should_generate_insert_statements_from_update_containing_where_or_like() { - - // GIVEN - TestTable foodTable = - buildUniqueTable(DATA_SOURCE - , "Food" - , " id bigint" - + ", Dishname varchar(255)" - + ", Allergy varchar(255)" - + ", Price decimal") - .create() - .insertValues("1, 'Spaghetti Bolognese', 'cheese', 6.80") - .insertValues("2, 'Pizza', 'pasta', 10.99"); - - // WHEN - String foodTableName = foodTable.getTableName(); - String updateQuery = "UPDATE " + foodTableName + " SET Price = 7.00" - + " WHERE Allergy LIKE 'past%' OR Allergy = 'cheese'" - + " OR Dishname = 'Pizza'"; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(updateQuery); - - // THEN - foodTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(foodTable).withScript(insertScript) - .hasNumberOfRows(2) - .column(0).hasOnlyNullValues() - .column(1).containsValues("Spaghetti Bolognese", "Pizza") - .column(2).containsValues("cheese", "pasta") - .column(3).containsValues(6.80, 10.99); - - } - - - @Test public void - should_generate_insert_statements_from_update_containing_where_columnnames_values_positions_are_swapped() { - - // GIVEN - TestTable foodTable = - buildUniqueTable(DATA_SOURCE - , "Food" - , " id bigint" - + ", Dishname varchar(255)" - + ", Allergy varchar(255)" - + ", Price decimal") - .create() - .insertValues("1, 'Spaghetti Bolognese', 'cheese', 6.80") - .insertValues("2, 'Pizza', 'pasta', 10.99"); - - // WHEN - String foodTableName = foodTable.getTableName(); - String updateQuery = "UPDATE " + foodTableName + " SET Price = 7.00" - + " WHERE Allergy LIKE 'past%' OR 'cheese' = Allergy" - + " OR 'Pizza' = Dishname"; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(updateQuery); - - // THEN - foodTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(foodTable).withScript(insertScript) - .hasNumberOfRows(2) - .column(0).hasOnlyNullValues() - .column(1).containsValues("Spaghetti Bolognese", "Pizza") - .column(2).containsValues("cheese", "pasta") - .column(3).containsValues(6.80, 10.99); - - } - - @Test public void - should_generate_insert_statement_from_update_containing_where_like_and() { - - // GIVEN - TestTable foodTable = - buildUniqueTable(DATA_SOURCE - , "Food" - , " id bigint" - + ", Dishname varchar(255)" - + ", Allergy varchar(255)" - + ", Price decimal") - .create() - .insertValues("1, 'Spaghetti Bolognese', 'cheese', 6.80") - .insertValues("2, 'Pizza', 'pasta', 10.99"); - - // WHEN - String foodTableName = foodTable.getTableName(); - String updateQuery = "UPDATE " + foodTableName + " SET Price = 7.00" - + " WHERE Allergy LIKE 'past%'" - + " AND Dishname = 'Pizza'"; - QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); - String insertScript = quickSqlTestData.generateInsertScriptFor(updateQuery); - - // THEN - foodTable.recreate(); - SQL_EXECUTOR.execute(insertScript); - assertThat(foodTable).withScript(insertScript) - .hasNumberOfRows(1) - .row(0).hasValues(null, "Pizza", "pasta", 10.99); - - } +public class UpdateTest extends H2Config { + @Test + public void should_generate_one_insert_if_all_rows_are_updated_and_no_mandatory_columns() { + + // GIVEN + TestTable foodTable = + buildUniqueTable( + DATA_SOURCE, + "Food", + " id bigint" + + ", Dishname varchar(255)" + + ", Allergy varchar(255)" + + ", Price decimal") + .create() + .insertValues("1, 'Spaghetti Bolognese', 'cheese', 6.80") + .insertValues("2, 'Pizza Margherita', 'pasta', 7.99"); + + // WHEN + String foodTableName = foodTable.getTableName(); + String updateQuery = "UPDATE " + foodTableName + " SET Price = 7.00, Allergy = 'none'"; + + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(updateQuery); + + // THEN + foodTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(foodTable) + .withScript(insertScript) + .hasNumberOfRows(2) + .row(0) + .hasValues(null, null, "cheese", 6.80); + } + + @Test + public void should_generate_insert_statements_from_update_containing_where_or_like() { + + // GIVEN + TestTable foodTable = + buildUniqueTable( + DATA_SOURCE, + "Food", + " id bigint" + + ", Dishname varchar(255)" + + ", Allergy varchar(255)" + + ", Price decimal") + .create() + .insertValues("1, 'Spaghetti Bolognese', 'cheese', 6.80") + .insertValues("2, 'Pizza', 'pasta', 10.99"); + + // WHEN + String foodTableName = foodTable.getTableName(); + String updateQuery = + "UPDATE " + + foodTableName + + " SET Price = 7.00" + + " WHERE Allergy LIKE 'past%' OR Allergy = 'cheese'" + + " OR Dishname = 'Pizza'"; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(updateQuery); + + // THEN + foodTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(foodTable) + .withScript(insertScript) + .hasNumberOfRows(2) + .column(0) + .hasOnlyNullValues() + .column(1) + .containsValues("Spaghetti Bolognese", "Pizza") + .column(2) + .containsValues("cheese", "pasta") + .column(3) + .containsValues(6.80, 10.99); + } + + @Test + public void + should_generate_insert_statements_from_update_containing_where_columnnames_values_positions_are_swapped() { + + // GIVEN + TestTable foodTable = + buildUniqueTable( + DATA_SOURCE, + "Food", + " id bigint" + + ", Dishname varchar(255)" + + ", Allergy varchar(255)" + + ", Price decimal") + .create() + .insertValues("1, 'Spaghetti Bolognese', 'cheese', 6.80") + .insertValues("2, 'Pizza', 'pasta', 10.99"); + + // WHEN + String foodTableName = foodTable.getTableName(); + String updateQuery = + "UPDATE " + + foodTableName + + " SET Price = 7.00" + + " WHERE Allergy LIKE 'past%' OR 'cheese' = Allergy" + + " OR 'Pizza' = Dishname"; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(updateQuery); + + // THEN + foodTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(foodTable) + .withScript(insertScript) + .hasNumberOfRows(2) + .column(0) + .hasOnlyNullValues() + .column(1) + .containsValues("Spaghetti Bolognese", "Pizza") + .column(2) + .containsValues("cheese", "pasta") + .column(3) + .containsValues(6.80, 10.99); + } + + @Test + public void should_generate_insert_statement_from_update_containing_where_like_and() { + + // GIVEN + TestTable foodTable = + buildUniqueTable( + DATA_SOURCE, + "Food", + " id bigint" + + ", Dishname varchar(255)" + + ", Allergy varchar(255)" + + ", Price decimal") + .create() + .insertValues("1, 'Spaghetti Bolognese', 'cheese', 6.80") + .insertValues("2, 'Pizza', 'pasta', 10.99"); + + // WHEN + String foodTableName = foodTable.getTableName(); + String updateQuery = + "UPDATE " + + foodTableName + + " SET Price = 7.00" + + " WHERE Allergy LIKE 'past%'" + + " AND Dishname = 'Pizza'"; + QuickSqlTestData quickSqlTestData = QuickSqlTestData.buildFrom(DATA_SOURCE); + String insertScript = quickSqlTestData.generateInsertScriptFor(updateQuery); + + // THEN + foodTable.recreate(); + SQL_EXECUTOR.execute(insertScript); + assertThat(foodTable) + .withScript(insertScript) + .hasNumberOfRows(1) + .row(0) + .hasValues(null, "Pizza", "pasta", 10.99); + } } From 7f16adaff31680d028f25526248d1639bd2a5108 Mon Sep 17 00:00:00 2001 From: Jean Bisutti Date: Tue, 17 Mar 2026 17:01:28 +0100 Subject: [PATCH 2/2] Restrict spotless profile to Java 17 only --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e660fb3..aac6153 100644 --- a/pom.xml +++ b/pom.xml @@ -302,7 +302,7 @@ - [17,) + 17