Showing preview only (312K chars total). Download the full file or copy to clipboard to get everything.
Repository: Ninja-Squad/DbSetup
Branch: master
Commit: e520dc610ecd
Files: 67
Total size: 287.8 KB
Directory structure:
gitextract_dbqecuzp/
├── .circleci/
│ └── config.yml
├── .gitignore
├── DbSetup-core/
│ ├── build.gradle.kts
│ └── src/
│ ├── main/
│ │ └── java/
│ │ └── com/
│ │ └── ninja_squad/
│ │ └── dbsetup/
│ │ ├── DbSetup.java
│ │ ├── DbSetupRuntimeException.java
│ │ ├── DbSetupTracker.java
│ │ ├── Operations.java
│ │ ├── bind/
│ │ │ ├── Binder.java
│ │ │ ├── BinderConfiguration.java
│ │ │ ├── Binders.java
│ │ │ └── DefaultBinderConfiguration.java
│ │ ├── destination/
│ │ │ ├── DataSourceDestination.java
│ │ │ ├── Destination.java
│ │ │ └── DriverManagerDestination.java
│ │ ├── generator/
│ │ │ ├── DateSequenceValueGenerator.java
│ │ │ ├── SequenceValueGenerator.java
│ │ │ ├── StringSequenceValueGenerator.java
│ │ │ ├── ValueGenerator.java
│ │ │ └── ValueGenerators.java
│ │ ├── operation/
│ │ │ ├── CompositeOperation.java
│ │ │ ├── DeleteAll.java
│ │ │ ├── Insert.java
│ │ │ ├── Operation.java
│ │ │ ├── SqlOperation.java
│ │ │ └── Truncate.java
│ │ ├── overview.html
│ │ └── util/
│ │ └── Preconditions.java
│ └── test/
│ └── java/
│ └── com/
│ └── ninja_squad/
│ └── dbsetup/
│ ├── DbSetupTest.java
│ ├── DbSetupTrackerTest.java
│ ├── bind/
│ │ ├── BindersTest.java
│ │ └── DefaultBinderConfigurationTest.java
│ ├── destination/
│ │ ├── DataSourceDestinationTest.java
│ │ └── DriverManagerDestinationTest.java
│ ├── generator/
│ │ ├── DateSequenceValueGeneratorTest.java
│ │ ├── SequenceValueGeneratorTest.java
│ │ ├── StringSequenceValueGeneratorTest.java
│ │ └── ValueGeneratorsTest.java
│ ├── integration/
│ │ ├── CommonOperations.java
│ │ ├── Database.java
│ │ ├── DeleteAllIntegrationTest.java
│ │ ├── InsertIntegrationTest.java
│ │ ├── RollbackIntegrationTest.java
│ │ └── TruncateIntegrationTest.java
│ └── operation/
│ ├── CompositeOperationTest.java
│ ├── DeleteAllTest.java
│ ├── InsertTest.java
│ ├── SqlOperationTest.java
│ └── TruncateTest.java
├── DbSetup-kotlin/
│ ├── build.gradle.kts
│ └── src/
│ ├── main/
│ │ └── kotlin/
│ │ └── com/
│ │ └── ninja_squad/
│ │ └── dbsetup_kotlin/
│ │ ├── DbSetup.kt
│ │ ├── DbSetupBuilder.kt
│ │ ├── Functions.kt
│ │ └── Insert.Builder.kt
│ └── test/
│ └── kotlin/
│ └── com/
│ └── ninja_squad/
│ └── dbsetup_kotlin/
│ ├── DbSetupBuilderTest.kt
│ ├── InsertBuilderTest.kt
│ └── MockitoExtensions.kt
├── README.md
├── build.gradle.kts
├── buildSrc/
│ ├── build.gradle.kts
│ ├── settings.grade.kts
│ └── src/
│ └── main/
│ └── kotlin/
│ └── java-library-convention.gradle.kts
├── gradle/
│ └── wrapper/
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
└── settings.gradle.kts
================================================
FILE CONTENTS
================================================
================================================
FILE: .circleci/config.yml
================================================
version: 2
jobs:
build:
working_directory: ~/DbSetup
docker:
- image: circleci/openjdk:8-jdk
steps:
- checkout
- run: ./gradlew build
- store_test_results:
path: DbSetup-core/build/test-results/test
- store_test_results:
path: DbSetup-kotlin/build/test-results/test
================================================
FILE: .gitignore
================================================
/.project
.gradle
/.settings
/bin
build/
/.classpath
/.classpath.idea/
/.java-version
*.iml
.idea
out
classes
.sdkmanrc
================================================
FILE: DbSetup-core/build.gradle.kts
================================================
plugins {
`java-library-convention`
}
project.description = "Helps you setup your database with test data"
java {
withJavadocJar()
}
dependencies {
compileOnly("com.google.code.findbugs:jsr305:2.0.0")
compileOnly("net.sourceforge.findbugs:annotations:1.3.2")
testImplementation("junit:junit:4.+")
testImplementation("org.mockito:mockito-all:1.9.0")
testImplementation("org.hsqldb:hsqldb:2.3.3")
}
tasks {
javadoc {
(options as StandardJavadocDocletOptions).apply {
overview(file("src/main/java/com/ninja_squad/dbsetup/overview.html").path)
noTimestamp(true)
linkSource(true)
addBooleanOption("Xdoclint:all,-missing", true)
}
}
}
================================================
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/DbSetup.java
================================================
/*
* The MIT License
*
* Copyright (c) 2012, Ninja Squad
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.ninja_squad.dbsetup;
import java.sql.Connection;
import java.sql.SQLException;
import javax.annotation.Nonnull;
import com.ninja_squad.dbsetup.bind.BinderConfiguration;
import com.ninja_squad.dbsetup.bind.DefaultBinderConfiguration;
import com.ninja_squad.dbsetup.destination.Destination;
import com.ninja_squad.dbsetup.operation.Operation;
import com.ninja_squad.dbsetup.util.Preconditions;
/**
* Allows executing a sequence of database operations. This object is reusable, and can thus be used several times
* to launch the same sequence of database operations. Here's a typical usage scenario in a unit test:
* <pre>
* @Before
* public void setUp() throws Exception {
* Operation operation =
* Operations.sequenceOf(
* CommonOperations.DELETE_ALL,
* CommonOperations.INSERT_REFERENCE_DATA,
* Operations.insertInto("CLIENT")
* .columns("CLIENT_ID", "FIRST_NAME", "LAST_NAME", "DATE_OF_BIRTH", "COUNTRY_ID")
* .values(1L, "John", "Doe", "1975-07-19", 1L)
* .values(2L, "Jack", "Smith", "1969-08-22", 2L)
* .build());
* DbSetup dbSetup = new DbSetup(new DataSourceDestination(dataSource), operation);
* dbSetup.launch();
* }
* </pre>
* In the above code, <code>CommonOperations.DELETE_ALL</code> and <code>CommonOperations.INSERT_REFERENCE_DATA</code>
* are operations shared by multiple test classes.
* <p>
* Note that, to speed up test executions, a {@link DbSetupTracker} can be used, at the price of a slightly
* bigger complexity.
* @author JB Nizet
*/
public final class DbSetup {
private final Destination destination;
private final Operation operation;
private final BinderConfiguration binderConfiguration;
/**
* Constructor which uses the {@link DefaultBinderConfiguration#INSTANCE default binder configuration}.
* @param destination the destination of the sequence of database operations
* @param operation the operation to execute (most of the time, an instance of
* {@link com.ninja_squad.dbsetup.operation.CompositeOperation}
*/
public DbSetup(@Nonnull Destination destination, @Nonnull Operation operation) {
this(destination, operation, DefaultBinderConfiguration.INSTANCE);
}
/**
* Constructor allowing to use a custom {@link BinderConfiguration}.
* @param destination the destination of the sequence of database operations
* @param operation the operation to execute (most of the time, an instance of
* {@link com.ninja_squad.dbsetup.operation.CompositeOperation}
* @param binderConfiguration the binder configuration to use.
*/
public DbSetup(@Nonnull Destination destination,
@Nonnull Operation operation,
@Nonnull BinderConfiguration binderConfiguration) {
Preconditions.checkNotNull(destination, "destination may not be null");
Preconditions.checkNotNull(operation, "operation may not be null");
Preconditions.checkNotNull(binderConfiguration, "binderConfiguration may not be null");
this.destination = destination;
this.operation = operation;
this.binderConfiguration = binderConfiguration;
}
/**
* Executes the sequence of operations. All the operations use the same connection, and are grouped
* in a single transaction. The transaction is rolled back if any exception occurs.
*/
public void launch() {
try {
Connection connection = destination.getConnection();
try {
connection.setAutoCommit(false);
operation.execute(connection, binderConfiguration);
connection.commit();
}
catch (SQLException e) {
connection.rollback();
throw e;
}
catch (RuntimeException e) {
connection.rollback();
throw e;
}
finally {
connection.close();
}
}
catch (SQLException e) {
throw new DbSetupRuntimeException(e);
}
}
@Override
public String toString() {
return "DbSetup [destination="
+ destination
+ ", operation="
+ operation
+ ", binderConfiguration="
+ binderConfiguration
+ "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + binderConfiguration.hashCode();
result = prime * result + destination.hashCode();
result = prime * result + operation.hashCode();
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
DbSetup other = (DbSetup) obj;
return binderConfiguration.equals(other.binderConfiguration)
&& destination.equals(other.destination)
&& operation.equals(other.operation);
}
}
================================================
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/DbSetupRuntimeException.java
================================================
/*
* The MIT License
*
* Copyright (c) 2012, Ninja Squad
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.ninja_squad.dbsetup;
/**
* A runtime exception indicating that a DbSetup failed.
* @author JB Nizet
*/
public class DbSetupRuntimeException extends RuntimeException {
public DbSetupRuntimeException() {
super();
}
public DbSetupRuntimeException(String message, Throwable cause) {
super(message, cause);
}
public DbSetupRuntimeException(String message) {
super(message);
}
public DbSetupRuntimeException(Throwable cause) {
super(cause);
}
}
================================================
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/DbSetupTracker.java
================================================
/*
* The MIT License
*
* Copyright (c) 2012, Ninja Squad
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.ninja_squad.dbsetup;
import javax.annotation.Nonnull;
/**
* <p>
* This class allows speeding up test execution, by avoiding re-executing the same sequence of database operations
* before each test method even if each of these test methods leaves the database as it is (and only performs read-only
* operations, which is the most frequent case).
* </p>
* <p>Example usage:</p>
* <pre>
* // the tracker is static because JUnit uses a separate Test instance for every test method.
* private static DbSetupTracker dbSetupTracker = new DbSetupTracker();
*
* @Before
* public void setUp() throws Exception {
* Operation operation =
* Operations.sequenceOf(
* CommonOperations.DELETE_ALL,
* CommonOperations.INSERT_REFERENCE_DATA,
* Operations.insertInto("CLIENT")
* .columns("CLIENT_ID", "FIRST_NAME", "LAST_NAME", "DATE_OF_BIRTH", "COUNTRY_ID")
* .values(1L, "John", "Doe", "1975-07-19", 1L)
* .values(2L, "Jack", "Smith", "1969-08-22", 2L)
* .build());
* DbSetup dbSetup = new DbSetup(new DataSourceDestination(dataSource), operation);
* dbSetupTracker.launchIfNecessary(dbSetup);
* }
*
* @Test
* public void readOnlyTest1() {
* dbSetupTracker.skipNextLaunch();
* ...
* }
*
* @Test
* public void readOnlyTest2() {
* dbSetupTracker.skipNextLaunch();
* ...
* }
*
* @Test
* public void readOnlyTest3() {
* dbSetupTracker.skipNextLaunch();
* ...
* }
*
* @Test
* public void readWriteTest1() {
* // No call to dbSetupTracker.skipNextLaunch();
* ...
* }
* </pre>
* @author JB Nizet
*/
public final class DbSetupTracker {
private DbSetup lastSetupLaunched;
private boolean nextLaunchSkipped;
/**
* Executes the given DbSetup unless all the following conditions are <code>true</code>:
* <ul>
* <li>{@link #skipNextLaunch()} has been called since the last call to this method;</li>
* <li>the given <code>dbSetup</code> is equal to the last DbSetup launched by this method</li>
* </ul>
* This method resets the <code>skipNextLaunch</code> flag to <code>false</code>.
* @param dbSetup the DbSetup to execute (or skip)
*/
public void launchIfNecessary(@Nonnull DbSetup dbSetup) {
boolean skipLaunch = nextLaunchSkipped && dbSetup.equals(lastSetupLaunched);
nextLaunchSkipped = false;
if (skipLaunch) {
return;
}
dbSetup.launch();
lastSetupLaunched = dbSetup;
}
/**
* Marks the current test method as read-only, and thus the need for the next test method to re-execute the same
* sequence of database setup operations.
*/
public void skipNextLaunch() {
this.nextLaunchSkipped = true;
}
@Override
public String toString() {
return "DbSetupTracker [lastSetupLaunched="
+ lastSetupLaunched
+ ", nextLaunchSkipped="
+ nextLaunchSkipped
+ "]";
}
}
================================================
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/Operations.java
================================================
/*
* The MIT License
*
* Copyright (c) 2012, Ninja Squad
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.ninja_squad.dbsetup;
import java.util.List;
import javax.annotation.Nonnull;
import com.ninja_squad.dbsetup.operation.CompositeOperation;
import com.ninja_squad.dbsetup.operation.DeleteAll;
import com.ninja_squad.dbsetup.operation.Insert;
import com.ninja_squad.dbsetup.operation.Operation;
import com.ninja_squad.dbsetup.operation.SqlOperation;
import com.ninja_squad.dbsetup.operation.Truncate;
/**
* A static factory class for operations. Static import of this class can help make the code more readable.
* @author JB Nizet
*/
public final class Operations {
private Operations() {
}
/**
* Creates a <code>delete from table</code> operation.
* @param table the table to delete all from
* @see DeleteAll
*/
public static DeleteAll deleteAllFrom(@Nonnull String table) {
return DeleteAll.from(table);
}
/**
* Creates a sequence of <code>delete from table</code> operations.
* @param tables the tables to delete all from
* @see DeleteAll
*/
public static Operation deleteAllFrom(@Nonnull String... tables) {
return DeleteAll.from(tables);
}
/**
* Creates a sequence of <code>delete from ...</code> operations.
* @param tables the tables to delete all from
* @see DeleteAll
*/
public static Operation deleteAllFrom(@Nonnull List<String> tables) {
return DeleteAll.from(tables);
}
/**
* Creates a <code>truncate table ...</code> operation.
* @param table the table to truncate
* @see Truncate
*/
public static Truncate truncate(@Nonnull String table) {
return Truncate.table(table);
}
/**
* Creates a sequence of <code>truncate table ...</code> operations.
* @param tables the tables to truncate
* @see Truncate
*/
public static Operation truncate(@Nonnull String... tables) {
return Truncate.tables(tables);
}
/**
* Creates a sequence of <code>truncate table ...</code> operations.
* @param tables the tables to truncate
* @see Truncate
*/
public static Operation truncate(@Nonnull List<String> tables) {
return Truncate.tables(tables);
}
/**
* Creates a SQL operation.
* @param sqlStatement the SQL statement to execute (using {@link java.sql.Statement#executeUpdate(String)})
* @see SqlOperation
*/
public static SqlOperation sql(@Nonnull String sqlStatement) {
return SqlOperation.of(sqlStatement);
}
/**
* Creates a sequence of SQL operations.
* @param sqlStatements the SQL statements to execute (using {@link java.sql.Statement#executeUpdate(String)})
* @see SqlOperation
*/
public static Operation sql(@Nonnull String... sqlStatements) {
return SqlOperation.of(sqlStatements);
}
/**
* Creates a sequence of SQL operations.
* @param sqlStatements the SQL statements to execute (using {@link java.sql.Statement#executeUpdate(String)})
* @see SqlOperation
*/
public static Operation sql(@Nonnull List<String> sqlStatements) {
return SqlOperation.of(sqlStatements);
}
/**
* Creates a builder for a sequence of insert operations.
* @param table the table to insert into
* @see Insert
*/
public static Insert.Builder insertInto(@Nonnull String table) {
return Insert.into(table);
}
/**
* Creates a sequence of operations.
* @param operations the operations to put in a sequence
* @see CompositeOperation
*/
public static Operation sequenceOf(@Nonnull Operation... operations) {
return CompositeOperation.sequenceOf(operations);
}
/**
* Creates a sequence of operations.
* @param operations the operations to put in a sequence
* @see CompositeOperation
*/
public static Operation sequenceOf(@Nonnull List<? extends Operation> operations) {
return CompositeOperation.sequenceOf(operations);
}
}
================================================
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/bind/Binder.java
================================================
/*
* The MIT License
*
* Copyright (c) 2012, Ninja Squad
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.ninja_squad.dbsetup.bind;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import com.ninja_squad.dbsetup.DbSetupTracker;
/**
* An object which binds a value to a prepared statement parameter. It's advised to make implementations of this
* interface immutable, and to make them implement equals and hashCode in order for {@link DbSetupTracker} to function
* properly, or to make them singletons.
* @author JB Nizet
*/
public interface Binder {
/**
* Binds the given value to the given parameter in the given prepared statement.
* @param statement the statement to bind the parameter to
* @param param The index of the parameter to bind in the statement
* @param value The value to bind (may be <code>null</code>)
* @throws SQLException if the binding throws a {@link SQLException}
*/
void bind(PreparedStatement statement, int param, Object value) throws SQLException;
}
================================================
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/bind/BinderConfiguration.java
================================================
/*
* The MIT License
*
* Copyright (c) 2012, Ninja Squad
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.ninja_squad.dbsetup.bind;
import com.ninja_squad.dbsetup.DbSetup;
import com.ninja_squad.dbsetup.DbSetupTracker;
import javax.annotation.Nullable;
import java.sql.ParameterMetaData;
import java.sql.SQLException;
/**
* An object which returns the appropriate {@link Binder} based on the metadata of the prepared statement.
* The default instance of this interface is {@link DefaultBinderConfiguration}. If the binders returned by this
* default configuration don't fit for the particular database you're using, or if you would like the binders
* returned by the configuration to support additional data types, you might want to provide a different implementation
* of this interface to the {@link DbSetup}.
* <p>
* It's advised to make implementations of this interface immutable, and to make them implement equals and hashCode
* in order for {@link DbSetupTracker} to function properly, or to make them singletons.
* @author JB Nizet
*/
public interface BinderConfiguration {
/**
* Returns the appropriate {@link Binder} for the given parameter, based on the given metadata.
* @param metadata the metadata allowing to decide which Binder to return. <code>null</code> if the Insert has been
* configured to not use metadata, or if the JDBC driver returned null metadata, or the JDBC driver threw a
* SQLException when asked for the metadata
* @param param the param for which a binder is requested
* @return the binder for the given param and its metadata
* @throws SQLException if a SQLException occurs while using the metadata
*/
Binder getBinder(@Nullable ParameterMetaData metadata, int param) throws SQLException;
}
================================================
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/bind/Binders.java
================================================
/*
* The MIT License
*
* Copyright (c) 2012-2016, Ninja Squad
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.ninja_squad.dbsetup.bind;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.sql.Types;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.OffsetTime;
import java.time.ZonedDateTime;
import java.util.Calendar;
import java.util.TimeZone;
/**
* Utility class allowing to get various kinds of binders. The {@link DefaultBinderConfiguration} uses binders
* returned by this class, based on the type of the parameter.
* @author JB Nizet
*/
public final class Binders {
private static final Binder DEFAULT_BINDER = new DefaultBinder();
private static final Binder DATE_BINDER = new DateBinder();
private static final Binder TIMESTAMP_BINDER = new TimestampBinder();
private static final Binder DECIMAL_BINDER = new DecimalBinder();
private static final Binder INTEGER_BINDER = new IntegerBinder();
private static final Binder TIME_BINDER = new TimeBinder();
private static final Binder STRING_BINDER = new StringBinder();
private Binders() {
}
/**
* Returns the default binder. This binder is normally used for columns of a type that is not handled by the other
* binders. It is also used when the metadata are not used and the Insert thus doesn't know the type of the column.
* It simply uses <code>stmt.setObject()</code> to bind the parameter, except if the value being bound is of some
* some well-known type not handled by JDBC:
* <ul>
* <li><code>enum</code>: the name of the enum is bound</li>
* <li><code>java.util.Date</code>: the date is transformed to a <code>java.sql.Timestamp</code></li>
* <li><code>java.util.Calendar</code>: the calendar is transformed to a <code>java.sql.Timestamp</code>,
* and is passed as third argument of
* <code>PreparedStatement.setTimestamp()</code> to pass the timezone</li>
* <li><code>java.time.LocalDate</code>: transformed to a <code>java.sql.Date</code></li>
* <li><code>java.time.LocalTime</code>: transformed to a <code>java.sql.Time</code></li>
* <li><code>java.time.LocalDateTime</code>: transformed to a <code>java.sql.Timestamp</code></li>
* <li><code>java.time.Instant</code>: transformed to a <code>java.sql.Timestamp</code></li>
* <li><code>java.time.ZonedDateTime</code> and <code>OffsetDateTime</code>: transformed to a
* <code>java.sql.Timestamp</code>. The time zone is also used to create a <code>Calendar</code> passed as
* third argument of <code>PreparedStatement.setTimestamp()</code> to pass the timezone</li>
* <li><code>java.time.OffsetTime</code>: transformed to a
* <code>java.sql.Time</code>. The time zone is also used to create a <code>Calendar</code> passed as third
* argument of <code>PreparedStatement.setTime()</code> to pass the timezone</li>
* </ul>
*/
public static Binder defaultBinder() {
return DEFAULT_BINDER;
}
/**
* Returns a binder suitable for columns of type CHAR and VARCHAR. The returned binder supports values of type
* <ul>
* <li><code>String</code></li>
* <li><code>enum</code>: the name of the enum is used as bound value</li>
* <li><code>Object</code>: the <code>toString()</code> of the object is used as bound value</li>
* </ul>
*/
public static Binder stringBinder() {
return STRING_BINDER;
}
/**
* Returns a binder suitable for columns of type DATE. The returned binder supports values of type
* <ul>
* <li><code>java.sql.Date</code></li>
* <li><code>java.util.Date</code>: the milliseconds of the date are used to construct a
* <code>java.sql.Date</code>.</li>
* <li><code>java.util.Calendar</code>: the milliseconds of the calendar are used to construct a
* <code>java.sql.Date</code>, and the calendar is passed as third argument of
* <code>PreparedStatement.setDate()</code> to pass the timezone
* </li>
* <li><code>String</code>: the string is transformed to a java.sql.Date using the <code>Date.valueOf()</code>
* method</li>
* <li><code>java.time.LocalDate</code>: transformed to a <code>java.sql.Date</code> using
* <code>Date.valueOf()</code></li>
* <li><code>java.time.LocalDateTime</code>: transformed to a LocalDate (and thus ignoring the time),
* and then transformed to a <code>java.sql.Date</code> using <code>Date.valueOf()</code></li>
* <li><code>java.time.Instant</code>the milliseconds of the instant are used to construct a
* <code>java.sql.Date</code>.</li>
* <li><code>java.time.ZonedDateTime</code> and <code>java.time.OffsetDateTime</code>: transformed to an Instant
* and then to a <code>java.sql.Date</code>. The time zone is also used to create a <code>Calendar</code>
* passed as third argument of <code>PreparedStatement.setDate()</code> to pass the timezone</li>
* </ul>
* If the value is none of these types, <code>stmt.setObject()</code> is used to bind the value.
*/
public static Binder dateBinder() {
return DATE_BINDER;
}
/**
* Returns a binder suitable for columns of type TIMESTAMP and TIMESTAMP_WITH_TIMEZONE. The returned binder
* supports values of type
* <ul>
* <li><code>java.sql.Timestamp</code></li>
* <li><code>java.util.Date</code>: the milliseconds of the date are used to construct a
* <code>java.sql.Timestamp</code></li>
* <li><code>java.util.Calendar</code>: the milliseconds of the calendar are used to construct a
* <code>java.sql.Timestamp</code>, and the calendar is passed as third argument of
* <code>PreparedStatement.setTimestamp()</code> to pass the timezone</li>
* <li><code>String</code>: the string is transformed to a <code>java.sql.Timestamp</code> using the
* <code>Timestamp.valueOf()</code> method, or using the <code>java.sql.Date.valueOf()</code> method if the
* string has less than 19 characters</li>
* <li><code>java.time.LocalDateTime</code>: transformed to a <code>java.sql.Timestamp</code> using
* <code>Timestamp.valueOf()</code></li>
* <li><code>java.time.LocalDate</code>: transformed to a LocalDateTime with the time at start of day,
* and then transformed to a <code>java.sql.Timestamp</code> using <code>Timestamp.valueOf()</code></li>
* <li><code>java.time.Instant</code>: transformed to a <code>java.sql.Timestamp</code> using
* <code>Timestamp.from()</code></li>
* <li><code>java.time.ZonedDateTime</code> and <code>java.time.OffsetDateTime</code>: transformed to an Instant
* and then to a <code>java.sql.Timestamp</code> using <code>Timestamp.from()</code>. The time zone is also
* used to create a <code>Calendar</code> passed as third argument of
* <code>PreparedStatement.setTimestamp()</code> to pass the timezone</li>
* </ul>
* If the value is none of these types, <code>stmt.setObject()</code> is used to bind the value.
*/
public static Binder timestampBinder() {
return TIMESTAMP_BINDER;
}
/**
* Returns a binder suitable for columns of type TIME or TIME_WITH_TIMEZONE. The returned binder supports values
* of type
* <ul>
* <li><code>java.sql.Time</code></li>
* <li><code>java.util.Date</code>: the milliseconds of the date are used to construct a
* <code>java.sql.Time</code></li>
* <li><code>java.util.Calendar</code>: the milliseconds of the calendar are used to construct a
* <code>java.sql.Time</code>, and the calendar is passed as third argument of
* <code>PreparedStatement.setTimestamp()</code> to pass the timezone
* </li>
* <li><code>String</code>: the string is transformed to a java.sql.Time using the
* <code>Time.valueOf()</code> method</li>
* <li><code>java.time.LocalTime</code>: transformed to a <code>java.sql.Time</code> using
* <code>Time.valueOf()</code></li>
* <li><code>java.time.OffsetTime</code>: transformed to a <code>LocalTime</code> and then to a
* <code>java.sql.Time</code> using <code>Time.valueOf()</code>. The time zone is also
* used to create a <code>Calendar</code> passed as third argument of
* <code>PreparedStatement.setTime()</code> to pass the timezone</li>
* </ul>
* If the value is none of these types, <code>stmt.setObject()</code> is used to bind the value.
*/
public static Binder timeBinder() {
return TIME_BINDER;
}
/**
* Returns a binder suitable for numeric, decimal columns. The returned binder supports values of type
* <ul>
* <li><code>String</code>: the string is transformed to a java.math.BigDecimal using its constructor</li>
* </ul>
* If the value is none of these types, <code>stmt.setObject()</code> is used to bind the value.
*/
public static Binder decimalBinder() {
return DECIMAL_BINDER;
}
/**
* Returns a binder suitable for numeric, integer columns. The returned binder supports values of type
* <ul>
* <li><code>BigInteger</code>: the object is transformed to a String and bound using
* <code>stmt.setObject()</code>, with <code>BIGINT</code> as target type.
* </li>
* <li><code>enum</code>: the enum is transformed into an integer by taking its ordinal</li>
* <li><code>String</code>: the string is bound using <code>stmt.setObject()</code>, with <code>BIGINT</code> as
* target type.
* </li>
* </ul>
* If the value is none of these types, <code>stmt.setObject()</code> is used to bind the value.
*/
public static Binder integerBinder() {
return INTEGER_BINDER;
}
/**
* The implementation for {@link Binders#stringBinder()}
* @author JB Nizet
*/
private static final class StringBinder implements Binder {
@Override
public void bind(java.sql.PreparedStatement stmt, int param, Object value) throws java.sql.SQLException {
if (value instanceof String) {
stmt.setString(param, (String) value);
}
else if (value instanceof Enum<?>) {
stmt.setString(param, ((Enum<?>) value).name());
}
else if (value == null) {
stmt.setObject(param, null);
}
else {
stmt.setString(param, value.toString());
}
}
@Override
public String toString() {
return "Binders.stringBinder";
}
}
/**
* The implementation for {@link Binders#timeBinder()}
* @author JB Nizet
*/
private static final class TimeBinder implements Binder {
@Override
public void bind(java.sql.PreparedStatement stmt, int param, Object value) throws java.sql.SQLException {
if (value instanceof Time) {
stmt.setTime(param, (Time) value);
}
else if (value instanceof java.util.Date) {
stmt.setTime(param, new Time(((java.util.Date) value).getTime()));
}
else if (value instanceof Calendar) {
Calendar calendar = (Calendar) value;
stmt.setTime(param, new Time(calendar.getTimeInMillis()), calendar);
}
else if (value instanceof String) {
stmt.setTime(param, Time.valueOf((String) value));
}
else if (value instanceof LocalTime) {
stmt.setTime(param, Time.valueOf((LocalTime) value));
}
else if (value instanceof OffsetTime) {
OffsetTime offsetTime = (OffsetTime) value;
stmt.setTime(param,
Time.valueOf(offsetTime.toLocalTime()),
Calendar.getInstance(TimeZone.getTimeZone(offsetTime.getOffset())));
}
else {
stmt.setObject(param, value);
}
}
@Override
public String toString() {
return "Binders.timeBinder";
}
}
/**
* The implementation for {@link Binders#integerBinder()}
* @author JB Nizet
*/
private static final class IntegerBinder implements Binder {
@Override
public void bind(java.sql.PreparedStatement stmt, int param, Object value) throws java.sql.SQLException {
if (value instanceof BigInteger) {
stmt.setObject(param, value.toString(), Types.BIGINT);
}
else if (value instanceof Enum<?>) {
stmt.setInt(param, ((Enum<?>) value).ordinal());
}
else if (value instanceof String) {
stmt.setObject(param, value, Types.BIGINT);
}
else {
stmt.setObject(param, value);
}
}
@Override
public String toString() {
return "Binders.integerBinder";
}
}
/**
* The implementation for {@link Binders#decimalBinder()}
* @author JB Nizet
*/
private static final class DecimalBinder implements Binder {
@Override
public void bind(java.sql.PreparedStatement stmt, int param, Object value) throws java.sql.SQLException {
if (value instanceof String) {
stmt.setBigDecimal(param, new BigDecimal((String) value));
}
else {
stmt.setObject(param, value);
}
}
@Override
public String toString() {
return "Binders.decimalBinder";
}
}
/**
* The implementation for {@link Binders#timestampBinder()}
* @author JB Nizet
*/
private static final class TimestampBinder implements Binder {
// the number of chars in yyyy-mm-dd hh:mm:ss
private static final int MIN_NUMBER_OF_CHARS_FOR_TIMESTAMP = 19;
@Override
public void bind(java.sql.PreparedStatement stmt, int param, Object value) throws java.sql.SQLException {
if (value instanceof Timestamp) {
stmt.setTimestamp(param, (Timestamp) value);
}
else if (value instanceof java.util.Date) {
stmt.setTimestamp(param, new Timestamp(((java.util.Date) value).getTime()));
}
else if (value instanceof Calendar) {
stmt.setTimestamp(param, new Timestamp(((Calendar) value).getTimeInMillis()), (Calendar) value);
}
else if (value instanceof String) {
String valueAsString = (String) value;
if (valueAsString.length() >= MIN_NUMBER_OF_CHARS_FOR_TIMESTAMP) {
stmt.setTimestamp(param, Timestamp.valueOf(valueAsString));
}
else {
Date valueAsDate = Date.valueOf(valueAsString);
stmt.setTimestamp(param, new Timestamp(valueAsDate.getTime()));
}
}
else if (value instanceof LocalDateTime) {
LocalDateTime localDateTime = (LocalDateTime) value;
stmt.setTimestamp(param, Timestamp.valueOf(localDateTime));
}
else if (value instanceof Instant) {
Instant instant = (Instant) value;
stmt.setTimestamp(param, Timestamp.from(instant));
}
else if (value instanceof ZonedDateTime) {
ZonedDateTime zonedDateTime = (ZonedDateTime) value;
stmt.setTimestamp(param,
Timestamp.from(zonedDateTime.toInstant()),
Calendar.getInstance(TimeZone.getTimeZone(zonedDateTime.getZone())));
}
else if (value instanceof OffsetDateTime) {
OffsetDateTime offsetDateTime = (OffsetDateTime) value;
stmt.setTimestamp(param,
Timestamp.from(offsetDateTime.toInstant()),
Calendar.getInstance(TimeZone.getTimeZone(offsetDateTime.getOffset())));
}
else if (value instanceof LocalDate) {
LocalDate localDate = (LocalDate) value;
stmt.setTimestamp(param, Timestamp.valueOf(localDate.atStartOfDay()));
}
else {
stmt.setObject(param, value);
}
}
@Override
public String toString() {
return "Binders.timestampBinder";
}
}
/**
* The implementation for {@link Binders#dateBinder()}
* @author JB Nizet
*/
private static final class DateBinder implements Binder {
@Override
public void bind(java.sql.PreparedStatement stmt, int param, Object value) throws java.sql.SQLException {
if (value instanceof Date) {
stmt.setDate(param, (Date) value);
}
else if (value instanceof java.util.Date) {
stmt.setDate(param, new Date(((java.util.Date) value).getTime()));
}
else if (value instanceof Calendar) {
Calendar calendar = (Calendar) value;
stmt.setDate(param, new Date(calendar.getTimeInMillis()), calendar);
}
else if (value instanceof String) {
stmt.setDate(param, Date.valueOf((String) value));
}
else if (value instanceof LocalDate) {
LocalDate localDate = (LocalDate) value;
stmt.setDate(param, Date.valueOf(localDate));
}
else if (value instanceof LocalDateTime) {
LocalDateTime localDateTime = (LocalDateTime) value;
stmt.setDate(param, Date.valueOf(localDateTime.toLocalDate()));
}
else if (value instanceof Instant) {
Instant instant = (Instant) value;
stmt.setDate(param, new Date(instant.toEpochMilli()));
}
else if (value instanceof ZonedDateTime) {
ZonedDateTime zonedDateTime = (ZonedDateTime) value;
stmt.setDate(param,
new Date(zonedDateTime.toInstant().toEpochMilli()),
Calendar.getInstance(TimeZone.getTimeZone(zonedDateTime.getZone())));
}
else if (value instanceof OffsetDateTime) {
OffsetDateTime offsetDateTime = (OffsetDateTime) value;
stmt.setDate(param,
new Date(offsetDateTime.toInstant().toEpochMilli()),
Calendar.getInstance(TimeZone.getTimeZone(offsetDateTime.getOffset())));
}
else {
stmt.setObject(param, value);
}
}
@Override
public String toString() {
return "Binders.dateBinder";
}
}
/**
* The implementation for {@link Binders#defaultBinder()}
* @author JB Nizet
*/
private static final class DefaultBinder implements Binder {
@Override
public void bind(java.sql.PreparedStatement stmt, int param, Object value) throws java.sql.SQLException {
if (value instanceof Enum) {
stmt.setString(param, ((Enum) value).name());
}
else if (value instanceof java.util.Date) {
stmt.setTimestamp(param, new Timestamp(((java.util.Date) value).getTime()));
}
else if (value instanceof Calendar) {
Calendar calendar = (Calendar) value;
stmt.setTimestamp(param, new Timestamp(calendar.getTime().getTime()), calendar);
}
else if (value instanceof LocalDate) {
stmt.setDate(param, Date.valueOf((LocalDate) value));
}
else if (value instanceof LocalTime) {
stmt.setTime(param, Time.valueOf((LocalTime) value));
}
else if (value instanceof LocalDateTime) {
stmt.setTimestamp(param, Timestamp.valueOf((LocalDateTime) value));
}
else if (value instanceof Instant) {
stmt.setTimestamp(param, Timestamp.from((Instant) value));
}
else if (value instanceof ZonedDateTime) {
ZonedDateTime zonedDateTime = (ZonedDateTime) value;
stmt.setTimestamp(param,
Timestamp.from(zonedDateTime.toInstant()),
Calendar.getInstance(TimeZone.getTimeZone(zonedDateTime.getZone())));
}
else if (value instanceof OffsetDateTime) {
OffsetDateTime offsetDateTime = (OffsetDateTime) value;
stmt.setTimestamp(param,
Timestamp.from(offsetDateTime.toInstant()),
Calendar.getInstance(TimeZone.getTimeZone(offsetDateTime.getOffset())));
}
else if (value instanceof OffsetTime) {
OffsetTime offsetTime = (OffsetTime) value;
stmt.setTime(param,
Time.valueOf(offsetTime.toLocalTime()),
Calendar.getInstance(TimeZone.getTimeZone(offsetTime.getOffset())));
}
else {
stmt.setObject(param, value);
}
}
@Override
public String toString() {
return "Binders.defaultBinder";
}
}
}
================================================
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/bind/DefaultBinderConfiguration.java
================================================
/*
* The MIT License
*
* Copyright (c) 2012-2016, Ninja Squad
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.ninja_squad.dbsetup.bind;
import java.sql.ParameterMetaData;
import java.sql.SQLException;
import java.sql.Types;
import com.ninja_squad.dbsetup.DbSetup;
/**
* Default implementation of {@link BinderConfiguration}, used by default by {@link DbSetup}.
* @author JB Nizet
*/
public class DefaultBinderConfiguration implements BinderConfiguration {
/**
* A shareable, reusable instance of this class.
*/
public static final DefaultBinderConfiguration INSTANCE = new DefaultBinderConfiguration();
/**
* Constructor. Protected because it doesn't make much sense to instantiate this class,
* but extending it can be useful.
*/
protected DefaultBinderConfiguration() {
}
/**
* Uses the parameter type of the given parameter and returns the following Binders depending on the type
* got from the metadata.
* <ul>
* <li>null metadata (i.e. metadata not used or not returned): {@link Binders#defaultBinder()}</li>
* <li>VARCHAR, CHAR, LONGNVARCHAR, LONGVARCHAR, NCHAR, NVARCHAR :
* {@link Binders#stringBinder()}</li>
* <li>DATE : {@link Binders#dateBinder()}</li>
* <li>TIME : {@link Binders#timeBinder()}</li>
* <li>TIMESTAMP : {@link Binders#timestampBinder()}</li>
* <li>INTEGER, BIGINT, SMALLINT, TINYINT : {@link Binders#integerBinder()}</li>
* <li>DECIMAL, DOUBLE, FLOAT, NUMERIC, REAL : {@link Binders#decimalBinder()}</li>
* <li>other : {@link Binders#defaultBinder()}</li>
* </ul>
*
* If the parameter type can't be obtained from the metadata, the default binder is returned.
*/
@Override
public Binder getBinder(ParameterMetaData metadata, int param) throws SQLException {
if (metadata == null) {
return Binders.defaultBinder();
}
try {
int sqlType = metadata.getParameterType(param);
if (sqlType == Types.DATE) {
return Binders.dateBinder();
}
if (sqlType == Types.TIME || sqlType == Types.TIME_WITH_TIMEZONE) {
return Binders.timeBinder();
}
if (sqlType == Types.TIMESTAMP || sqlType == Types.TIMESTAMP_WITH_TIMEZONE) {
return Binders.timestampBinder();
}
if (sqlType == Types.BIGINT
|| sqlType == Types.INTEGER
|| sqlType == Types.SMALLINT
|| sqlType == Types.TINYINT) {
return Binders.integerBinder();
}
if (sqlType == Types.DECIMAL
|| sqlType == Types.DOUBLE
|| sqlType == Types.FLOAT
|| sqlType == Types.NUMERIC
|| sqlType == Types.REAL) {
return Binders.decimalBinder();
}
if (sqlType == Types.VARCHAR
|| sqlType == Types.CHAR
|| sqlType == Types.LONGNVARCHAR
|| sqlType == Types.LONGVARCHAR
|| sqlType == Types.NCHAR
|| sqlType == Types.NVARCHAR) {
return Binders.stringBinder();
}
return Binders.defaultBinder();
}
catch (SQLException e) {
// the database can't return types from parameters. Fall back to default binder.
return Binders.defaultBinder();
}
}
@Override
public String toString() {
return "DefaultBinderConfiguration";
}
}
================================================
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/destination/DataSourceDestination.java
================================================
/*
* The MIT License
*
* Copyright (c) 2012, Ninja Squad
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.ninja_squad.dbsetup.destination;
import com.ninja_squad.dbsetup.util.Preconditions;
import javax.annotation.Nonnull;
import javax.annotation.concurrent.Immutable;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
/**
* A destination which wraps a DataSource and gets its connection from the wrapped DataSource
* @author JB Nizet
*/
@Immutable
public final class DataSourceDestination implements Destination {
private final DataSource dataSource;
/**
* Constructor
* @param dataSource the wrapped DataSource
*/
public DataSourceDestination(@Nonnull DataSource dataSource) {
Preconditions.checkNotNull(dataSource, "dataSource may not be null");
this.dataSource = dataSource;
}
/**
* Factory method creating a new DataSourceDestination. This allows a more readable style than using the
* constructor:
*
* <pre>
* DbSetup dbSetup = new DbSetup(DataSourceDestination.with(dataSource), operation);
* </pre>
*
* or, if this method is statically imported:
*
* <pre>
* DbSetup dbSetup = new DbSetup(with(dataSource), operation);
* </pre>
*
* instead of
*
* <pre>
* DbSetup dbSetup = new DbSetup(new DataSourceDestination(dataSource), operation);
* </pre>
*
* @param dataSource the wrapped DataSource
*/
public static DataSourceDestination with(@Nonnull DataSource dataSource) {
return new DataSourceDestination(dataSource);
}
@Override
public Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
@Override
public String toString() {
return "DataSourceDestination [dataSource=" + dataSource + "]";
}
@Override
public int hashCode() {
return dataSource.hashCode();
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
DataSourceDestination other = (DataSourceDestination) obj;
return dataSource.equals(other.dataSource);
}
}
================================================
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/destination/Destination.java
================================================
/*
* The MIT License
*
* Copyright (c) 2012, Ninja Squad
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.ninja_squad.dbsetup.destination;
import java.sql.Connection;
import java.sql.SQLException;
import com.ninja_squad.dbsetup.DbSetupTracker;
/**
* The destination of a database setup. It's advised to make implementations of this
* interface immutable, and to make them implement equals and hashCode in order for {@link DbSetupTracker} to function
* properly, or to make them singletons.
* @author JB Nizet
*/
public interface Destination {
/**
* Returns a connection to the destination database
* @return a connection to the destination database
* @throws SQLException if a connection can't be returned
*/
Connection getConnection() throws SQLException;
}
================================================
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/destination/DriverManagerDestination.java
================================================
/*
* The MIT License
*
* Copyright (c) 2012, Ninja Squad
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.ninja_squad.dbsetup.destination;
import com.ninja_squad.dbsetup.util.Preconditions;
import javax.annotation.Nonnull;
import javax.annotation.concurrent.Immutable;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
/**
* A destination which uses the {@link DriverManager} to get a connection
* @author JB Nizet
*/
@Immutable
public final class DriverManagerDestination implements Destination {
private final String url;
private final String user;
private final String password;
/**
* Constructor
* @param url the URL of the database
* @param user the user used to get a connection
* @param password the password used to get a connection
*/
public DriverManagerDestination(@Nonnull String url, String user, String password) {
Preconditions.checkNotNull(url, "url may not be null");
this.url = url;
this.user = user;
this.password = password;
}
/**
* Factory method creating a new DriverManagerDestination. This allows a more readable style than using the
* constructor:
*
* <pre>
* DbSetup dbSetup = new DbSetup(DriverManagerDestination.with(url, user, password), operation);
* </pre>
*
* or, if this method is statically imported:
*
* <pre>
* DbSetup dbSetup = new DbSetup(with(url, user, password), operation);
* </pre>
*
* instead of
*
* <pre>
* DbSetup dbSetup = new DbSetup(new DriverManagerDestination(url, user, password), operation);
* </pre>
*
* @param url the URL of the database
* @param user the user used to get a connection
* @param password the password used to get a connection
*/
public static DriverManagerDestination with(@Nonnull String url, String user, String password) {
return new DriverManagerDestination(url, user, password);
}
@Override
public Connection getConnection() throws SQLException {
return DriverManager.getConnection(url, user, password);
}
@Override
public String toString() {
return "DriverManagerDestination [url="
+ url
+ ", user="
+ user
+ ", password="
+ password
+ "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + url.hashCode();
result = prime * result + ((password == null) ? 0 : password.hashCode());
result = prime * result + ((user == null) ? 0 : user.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
DriverManagerDestination other = (DriverManagerDestination) obj;
if (password == null) {
if (other.password != null) {
return false;
}
}
else if (!password.equals(other.password)) {
return false;
}
if (!url.equals(other.url)) {
return false;
}
if (user == null) {
if (other.user != null) {
return false;
}
}
else if (!user.equals(other.user)) {
return false;
}
return true;
}
}
================================================
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/generator/DateSequenceValueGenerator.java
================================================
/*
* The MIT License
*
* Copyright (c) 2013-2016, Ninja Squad
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.ninja_squad.dbsetup.generator;
import javax.annotation.Nonnull;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalUnit;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
import com.ninja_squad.dbsetup.util.Preconditions;
/**
* A {@link ValueGenerator} that returns a sequence of dates, starting at a given zoned date time and incremented by a
* given time, specified as an increment and a temporal unit.
* @author JB
*/
public final class DateSequenceValueGenerator implements ValueGenerator<ZonedDateTime> {
// the number of chars in yyyy-mm-dd hh:mm:ss
private static final int MIN_NUMBER_OF_CHARS_FOR_TIMESTAMP = 19;
/**
* The available units for the increment of this sequence
* @deprecated use ChronoField instead. This enum is only kept to maintain backward compatibility
*/
@Deprecated
public enum CalendarField {
YEAR(ChronoUnit.YEARS),
MONTH(ChronoUnit.MONTHS),
DAY(ChronoUnit.DAYS),
HOUR(ChronoUnit.HOURS),
MINUTE(ChronoUnit.MINUTES),
SECOND(ChronoUnit.SECONDS),
MILLISECOND(ChronoUnit.MILLIS);
private TemporalUnit unit;
CalendarField(TemporalUnit unit) {
this.unit = unit;
}
private TemporalUnit toTemporalUnit() {
return unit;
}
}
private ZonedDateTime next;
private int increment;
private TemporalUnit unit;
DateSequenceValueGenerator() {
this(LocalDate.now().atStartOfDay().atZone(ZoneId.systemDefault()), 1, ChronoUnit.DAYS);
}
private DateSequenceValueGenerator(ZonedDateTime next, int increment, TemporalUnit unit) {
this.next = next;
this.increment = increment;
this.unit = unit;
}
/**
* Restarts the sequence at the given date, in the given time zone
* @return this instance, for chaining
* @deprecated use one of the other <code>startingAt()</code> methods taking java.time types as argument
*/
@Deprecated
public DateSequenceValueGenerator startingAt(@Nonnull Date startDate, @Nonnull TimeZone timeZone) {
Preconditions.checkNotNull(startDate, "startDate may not be null");
Preconditions.checkNotNull(timeZone, "timeZone may not be null");
next = startDate.toInstant().atZone(timeZone.toZoneId());
return this;
}
/**
* Restarts the sequence at the given date, in the default time zone
* @return this instance, for chaining
* @deprecated use one of the other <code>startingAt()</code> methods taking java.time types as argument
*/
@Deprecated
public DateSequenceValueGenerator startingAt(@Nonnull Date startDate) {
return startingAt(startDate, TimeZone.getDefault());
}
/**
* Restarts the sequence at the given date
* @return this instance, for chaining
* @deprecated use one of the other <code>startingAt()</code> methods taking java.time types as argument
*/
@Deprecated
public DateSequenceValueGenerator startingAt(@Nonnull Calendar startDate) {
Preconditions.checkNotNull(startDate, "startDate may not be null");
next = startDate.toInstant().atZone(startDate.getTimeZone().toZoneId());
return this;
}
/**
* Restarts the sequence at the given date, in the default time zone
* @param startDate the starting date, as a String. The supported formats are the same as the ones supported by
* {@link com.ninja_squad.dbsetup.bind.Binders#timestampBinder()}, i.e. the formats supported by
* <code>java.sql.Timestamp.valueOf()</code> and <code>java.sql.Date.valueOf()</code>
* @return this instance, for chaining
*/
public DateSequenceValueGenerator startingAt(@Nonnull String startDate) {
Preconditions.checkNotNull(startDate, "startDate may not be null");
if (startDate.length() >= MIN_NUMBER_OF_CHARS_FOR_TIMESTAMP) {
return startingAt(new Date(Timestamp.valueOf(startDate).getTime()));
}
else {
return startingAt(new Date(java.sql.Date.valueOf(startDate).getTime()));
}
}
/**
* Restarts the sequence at the given local date, in the default time zone
* @return this instance, for chaining
*/
public DateSequenceValueGenerator startingAt(@Nonnull LocalDate startDate) {
return startingAt(startDate.atStartOfDay());
}
/**
* Restarts the sequence at the given local date time, in the default time zone
* @return this instance, for chaining
*/
public DateSequenceValueGenerator startingAt(@Nonnull LocalDateTime startDate) {
return startingAt(startDate.atZone(ZoneId.systemDefault()));
}
/**
* Restarts the sequence at the given zoned date time
* @return this instance, for chaining
*/
public DateSequenceValueGenerator startingAt(@Nonnull ZonedDateTime startDate) {
next = startDate;
return this;
}
/**
* Increments the date by the given increment of the given unit.
* @return this instance, for chaining
* @deprecated use the other {@link #incrementingBy(int, TemporalUnit)} method
*/
@Deprecated
public DateSequenceValueGenerator incrementingBy(int increment, @Nonnull CalendarField unit) {
Preconditions.checkNotNull(unit, "unit may not be null");
return incrementingBy(increment, unit.toTemporalUnit());
}
/**
* Increments the date by the given increment of the given unit. One of the constants of ChronoField is typically
* used for the unit.
* @return this instance, for chaining
*/
public DateSequenceValueGenerator incrementingBy(int increment, @Nonnull TemporalUnit unit) {
Preconditions.checkNotNull(unit, "unit may not be null");
this.increment = increment;
this.unit = unit;
return this;
}
@Override
public ZonedDateTime nextValue() {
ZonedDateTime result = next;
next = next.plus(increment, unit);
return result;
}
@Override
public String toString() {
return "DateSequenceValueGenerator["
+ "next=" + next
+ ", increment=" + increment
+ ", unit=" + unit
+ "]";
}
}
================================================
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/generator/SequenceValueGenerator.java
================================================
/*
* The MIT License
*
* Copyright (c) 2013, Ninja Squad
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.ninja_squad.dbsetup.generator;
/**
* A {@link ValueGenerator} which generates a sequence of long values. By default, the sequence starts at 1 and
* increments by 1, but this can be customized. Instances of this class are created using
* {@link ValueGenerators#sequence()}.
* @author JB Nizet
*/
public final class SequenceValueGenerator implements ValueGenerator<Long> {
private long next = 1L;
private int increment = 1;
SequenceValueGenerator() {
this(1, 1);
}
private SequenceValueGenerator(long start, int increment) {
this.next = start;
this.increment = increment;
}
/**
* Restarts the sequence at the given value
* @param start the starting value of the created generator
* @return this instance, for chaining
*/
public SequenceValueGenerator startingAt(long start) {
this.next = start;
return this;
}
/**
* Increments the value by the given increment.
* @return this instance, for chaining
*/
public SequenceValueGenerator incrementingBy(int increment) {
this.increment = increment;
return this;
}
@Override
public Long nextValue() {
long result = next;
next += increment;
return result;
}
@Override
public String toString() {
return "SequenceValueGenerator["
+ "next="
+ next
+ ", increment="
+ increment
+ "]";
}
}
================================================
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/generator/StringSequenceValueGenerator.java
================================================
/*
* The MIT License
*
* Copyright (c) 2013-2016, Ninja Squad
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.ninja_squad.dbsetup.generator;
import com.ninja_squad.dbsetup.util.Preconditions;
/**
* A {@link ValueGenerator} that returns a string prefix followed by a sequence number, optionally left-padded
* with 0 to ensure a correct ordering (for example: CODE_001, CODE_002, etc.). Instances of this generator
* are created by {@link ValueGenerators#stringSequence(String)}.
* @author JB
*/
public final class StringSequenceValueGenerator implements ValueGenerator<String> {
private String prefix;
private long next;
private int increment;
/**
* The length of the number once padded. 0 if no padding must be applied
*/
private int paddedNumberLength;
StringSequenceValueGenerator(String prefix) {
this(prefix, 1L, 1, 0);
}
private StringSequenceValueGenerator(String prefix, long next, int increment, int paddedNumberLength) {
this.prefix = prefix;
this.next = next;
this.increment = increment;
this.paddedNumberLength = paddedNumberLength;
}
/**
* Tells the generator to left-pad the number it generates with 0 until the length of the number is the given
* length. For example, passing 3 to this method will generate numbers 001, 002, 003, 004, etc. If the generated
* number, before padding, has a length already equal or larger that the given length, the number is not padded.
* @param paddedNumberLength the length of the number once padded. Must be > 0.
* @return this instance, for chaining
*/
public StringSequenceValueGenerator withLeftPadding(int paddedNumberLength) {
Preconditions.checkArgument(paddedNumberLength > 0, "paddedNumberLength must be > 0");
this.paddedNumberLength = paddedNumberLength;
return this;
}
/**
* Tells the generator to avoid left-padding the number it generates with 0
* @return this instance, for chaining
*/
public StringSequenceValueGenerator withoutLeftPadding() {
this.paddedNumberLength = 0;
return this;
}
/**
* Restarts the sequence at the given value
* @param start the new starting value of the sequence
* @return this instance, for chaining
*/
public StringSequenceValueGenerator startingAt(long start) {
this.next = start;
return this;
}
/**
* Increments the number by the given increment.
* @return this instance, for chaining
*/
public StringSequenceValueGenerator incrementingBy(int increment) {
this.increment = increment;
return this;
}
@Override
public String nextValue() {
long number = next;
next += increment;
return prefix + leftPadIfNecessary(number);
}
private String leftPadIfNecessary(long number) {
String numberAsString = Long.toString(number);
if (numberAsString.length() >= paddedNumberLength) {
return numberAsString;
}
StringBuilder builder = new StringBuilder(paddedNumberLength);
for (int i = 0; i < paddedNumberLength - numberAsString.length(); i++) {
builder.append('0');
}
return builder.append(numberAsString).toString();
}
@Override
public String toString() {
return "StringSequenceValueGenerator["
+ "prefix='" + prefix + '\''
+ ", next=" + next
+ ", increment=" + increment
+ ", paddedNumberLength=" + paddedNumberLength
+ "]";
}
}
================================================
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/generator/ValueGenerator.java
================================================
/*
* The MIT License
*
* Copyright (c) 2013, Ninja Squad
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.ninja_squad.dbsetup.generator;
/**
* A value generator allows generating values for a specific column in a sequence of inserts. This is useful when you
* don't want to specify a value for each of the inserted rows in a table, and when a default value is not an option
* either because, for example, the column has a unique constraint.
* @param <T> the type of value that this generator generates
*
* @see ValueGenerators for useful implementations of this interface
* @author JB Nizet
*/
public interface ValueGenerator<T> {
/**
* Called each time a new row is inserted, to get the value to insert in the column using this value generator.
* @return the value to insert in the column associated with this generator.
*/
T nextValue();
}
================================================
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/generator/ValueGenerators.java
================================================
/*
* The MIT License
*
* Copyright (c) 2013, Ninja Squad
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.ninja_squad.dbsetup.generator;
import com.ninja_squad.dbsetup.util.Preconditions;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* Utility class containing factory methods for {@link ValueGenerator}
* @author JB Nizet
*/
public final class ValueGenerators {
private ValueGenerators() {
}
/**
* Returns a value generator which generates a sequence of long values starting with 1, with an increment of 1.
* The starting value and increment can be customized using
* <pre>
* ValueGenerators.increment().startingAt(1000).incrementingBy(5)
* </pre>
*/
public static SequenceValueGenerator sequence() {
return new SequenceValueGenerator();
}
/**
* Returns a value generator which always returns the same, given value.
*/
public static <T> ValueGenerator<T> constant(@Nullable final T constant) {
return new ValueGenerator<T>() {
@Override
public T nextValue() {
return constant;
}
@Override
public String toString() {
return "ValueGenerators.constant(" + constant + ")";
}
};
}
/**
* Returns a value generator that returns a string prefix followed by a sequence number, optionally left-padded
* with 0 to ensure a correct ordering (for example: CODE_001, CODE_002, etc.). The returned generator starts the
* sequence at 1 and increments by 1, and doesn't pad the numbers.
* @param prefix the prefix before the generated number (for example: <code>"CODE_"</code>).
*/
public static StringSequenceValueGenerator stringSequence(@Nonnull String prefix) {
Preconditions.checkNotNull(prefix, "prefix may not be null");
return new StringSequenceValueGenerator(prefix);
}
/**
* Returns a value generator that returns a sequence of dates, starting at a given date and incremented by a given
* time, specified as an increment and a calendar field. The returned generator starts today at 00:00:00
* and increments by 1 day by default.
*/
public static DateSequenceValueGenerator dateSequence() {
return new DateSequenceValueGenerator();
}
}
================================================
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/operation/CompositeOperation.java
================================================
/*
* The MIT License
*
* Copyright (c) 2012, Ninja Squad
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.ninja_squad.dbsetup.operation;
import javax.annotation.Nonnull;
import javax.annotation.concurrent.Immutable;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import com.ninja_squad.dbsetup.bind.BinderConfiguration;
/**
* A composite operation or, in other words, an operation which consists in executing a sequence of other operations.
* @author JB Nizet
*/
@Immutable
public final class CompositeOperation implements Operation {
private static final Operation NOP = new Operation() {
@Override
public void execute(Connection connection, BinderConfiguration configuration) {
// does nothing since it's a NOP
}
@Override
public String toString() {
return "NOP";
}
};
private final List<Operation> operations;
private CompositeOperation(List<? extends Operation> operations) {
this.operations = new ArrayList<Operation>(operations);
}
/**
* Creates a new Operation containing all the given operations
* @param operations the sequence of operations
*/
public static Operation sequenceOf(@Nonnull Operation... operations) {
return sequenceOf(Arrays.asList(operations));
}
/**
* Creates a new Operation containing all the given operations
* @param operations the sequence of operations
*/
public static Operation sequenceOf(@Nonnull List<? extends Operation> operations) {
if (operations.isEmpty()) {
return NOP;
}
else if (operations.size() == 1) {
return operations.get(0);
}
return new CompositeOperation(operations);
}
/**
* Executes the sequence of operations
* @throws SQLException as soon as one of the operations in the sequence throws a SQLException
*/
@Override
public void execute(Connection connection, BinderConfiguration configuration) throws SQLException {
for (Operation operation : operations) {
operation.execute(connection, configuration);
}
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
boolean first = true;
for (Operation operation : operations) {
if (!first) {
builder.append('\n');
}
else {
first = false;
}
builder.append(operation);
}
return builder.toString();
}
@Override
public int hashCode() {
return operations.hashCode();
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null) {
return false;
}
if (getClass() != o.getClass()) {
return false;
}
CompositeOperation other = (CompositeOperation) o;
return this.operations.equals(other.operations);
}
}
================================================
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/operation/DeleteAll.java
================================================
/*
* The MIT License
*
* Copyright (c) 2012, Ninja Squad
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.ninja_squad.dbsetup.operation;
import com.ninja_squad.dbsetup.bind.BinderConfiguration;
import com.ninja_squad.dbsetup.util.Preconditions;
import javax.annotation.Nonnull;
import javax.annotation.concurrent.Immutable;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* An operation which deletes everything from a given database table.
* @author JB Nizet
*/
@Immutable
public final class DeleteAll implements Operation {
private final String table;
private DeleteAll(String table) {
Preconditions.checkNotNull(table, "table may not be null");
this.table = table;
}
@Override
public void execute(Connection connection, BinderConfiguration configuration) throws SQLException {
Statement stmt = connection.createStatement();
try {
stmt.executeUpdate("delete from " + table);
}
finally {
stmt.close();
}
}
/**
* Returns an operation which deletes all the rows from the given table.
* @param table the table to delete everything from.
*/
public static DeleteAll from(@Nonnull String table) {
return new DeleteAll(table);
}
/**
* Returns a composite operation which deletes all the rows from the given tables, in the same order as the
* tables. If A has a foreign key to B, which has a foreign key to C, tables should be listed in the following
* order: A, B, C. Otherwise, referential constraint will break. If there is a cycle in the dependencies, you might
* want to use a sequence of {@link SqlOperation} to disable the foreign key constraints, then delete everything
* from the tables, then use another sequence of {@link SqlOperation} to re-enable the foreign key constraints.
* @param tables the tables to delete everything from.
*/
public static Operation from(@Nonnull String... tables) {
return from(Arrays.asList(tables));
}
/**
* Returns a composite operation which deletes all the rows from the given tables, in the same order as the
* tables. If A has a foreign key to B, which has a foreign key to C, tables should be listed in the following
* order: A, B, C. Otherwise, referential constraint will break. If there is a cycle in the dependencies, you might
* want to use a sequence of {@link SqlOperation} to disable the foreign key constraints, then delete everything
* from the tables, then use another sequence of {@link SqlOperation} to re-enable the foreign key constraints.
* @param tables the tables to delete everything from.
*/
public static Operation from(@Nonnull List<String> tables) {
List<DeleteAll> operations = new ArrayList<DeleteAll>(tables.size());
for (String table : tables) {
operations.add(new DeleteAll(table));
}
return CompositeOperation.sequenceOf(operations);
}
@Override
public String toString() {
return "delete from " + table;
}
@Override
public int hashCode() {
return table.hashCode();
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
DeleteAll other = (DeleteAll) obj;
return this.table.equals(other.table);
}
}
================================================
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/operation/Insert.java
================================================
/*
* The MIT License
*
* Copyright (c) 2012-2016, Ninja Squad
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.ninja_squad.dbsetup.operation;
import javax.annotation.Nonnull;
import javax.annotation.concurrent.Immutable;
import java.sql.Connection;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.ninja_squad.dbsetup.bind.Binder;
import com.ninja_squad.dbsetup.bind.BinderConfiguration;
import com.ninja_squad.dbsetup.bind.Binders;
import com.ninja_squad.dbsetup.generator.ValueGenerator;
import com.ninja_squad.dbsetup.generator.ValueGenerators;
import com.ninja_squad.dbsetup.util.Preconditions;
/**
* Operation which inserts one or several rows into a table. Example usage:
* <pre>
* Insert insert =
* Insert.into("CLIENT")
* .columns("CLIENT_ID", "FIRST_NAME", "LAST_NAME", "DATE_OF_BIRTH", "CLIENT_TYPE")
* .values(1L, "John", "Doe", "1975-07-19", ClientType.NORMAL)
* .values(2L, "Jack", "Smith", "1969-08-22", ClientType.HIGH_PRIORITY)
* .withDefaultValue("DELETED", false)
* .withDefaultValue("VERSION", 1)
* .withBinder(new ClientTypeBinder(), "CLIENT_TYPE")
* .build();
* </pre>
*
* The above operation will insert two rows inside the CLIENT table. For each row, the column DELETED will be set to
* <code>false</code> and the column VERSION will be set to 1. For the column CLIENT_TYPE, instead of using the
* {@link Binder} associated to the type of the column found in the metadata of the table, a custom binder will be used.
* <p>
* Instead of specifying values as an ordered sequence which must match the sequence of column names, some might prefer
* passing a map of column/value associations. This makes things more verbose, but can be more readable in some cases,
* when the number of columns is high. This also allows not specifying any value for columns that must stay null.
* The map can be constructed like any other map and passed to the builder, or it can be added using a fluent builder.
* The following snippet:
*
* <pre>
* Insert insert =
* Insert.into("CLIENT")
* .columns("CLIENT_ID", "FIRST_NAME", "LAST_NAME", "DATE_OF_BIRTH", "CLIENT_TYPE")
* .row().column("CLIENT_ID", 1L)
* .column("FIRST_NAME", "John")
* .column("LAST_NAME", "Doe")
* .column("DATE_OF_BIRTH", "1975-07-19")
* .end()
* .row().column("CLIENT_ID", 2L)
* .column("FIRST_NAME", "Jack")
* .column("LAST_NAME", "Smith")
* .end() // null date of birth, because it's not in the row
* .build();
* </pre>
*
* is thus equivalent to:
*
* <pre>
* Map<String, Object> johnDoe = new HashMap<String, Object>();
* johnDoe.put("CLIENT_ID", 1L);
* johnDoe.put("FIRST_NAME", "John");
* johnDoe.put("LAST_NAME", "Doe");
* johnDoe.put("DATE_OF_BIRTH", "1975-07-19");
*
* Map<String, Object> jackSmith = new HashMap<String, Object>();
* jackSmith.put("CLIENT_ID", 2L);
* jackSmith.put("FIRST_NAME", "Jack");
* jackSmith.put("LAST_NAME", "Smith");
*
* Insert insert =
* Insert.into("CLIENT")
* .columns("CLIENT_ID", "FIRST_NAME", "LAST_NAME", "DATE_OF_BIRTH", "CLIENT_TYPE")
* .values(johnDoe)
* .values(jackSmith)
* .build();
* </pre>
*
* When building the Insert using column/value associations, it might seem redundant to specify the set of column names
* before inserting the rows. Remember, though, that all the rows of an Insert are inserted using the same
* parameterized SQL query. We thus need a robust and easy way to know all the columns to insert for every row of the
* insert. To be able to spot errors easily and early, and to avoid complex rules, the rule is thus simple: the set of
* columns (excluding the generated ones) is specified either by columns(), or by the columns of the first row. All the
* subsequent rows may not have additional columns. And <code>null</code> is inserted for all the absent columns of the
* subsequent rows. The above example can thus be written as
*
* <pre>
* Insert insert =
* Insert.into("CLIENT")
* .row().column("CLIENT_ID", 1L)
* .column("FIRST_NAME", "John")
* .column("LAST_NAME", "Doe")
* .column("DATE_OF_BIRTH", "1975-07-19")
* .end()
* .row().column("CLIENT_ID", 2L)
* .column("FIRST_NAME", "Jack")
* .column("LAST_NAME", "Smith")
* .end() // null date of birth, because it's not in the row
* .build();
* </pre>
*
* but the following will throw an exception, because the DATE_OF_BIRTH column is not part of the first row:
*
* <pre>
* Insert insert =
* Insert.into("CLIENT")
* .row().column("CLIENT_ID", 2L)
* .column("FIRST_NAME", "Jack")
* .column("LAST_NAME", "Smith")
* .column("CLIENT_TYPE", ClientType.HIGH_PRIORITY)
* .end()
* .row().column("CLIENT_ID", 1L)
* .column("FIRST_NAME", "John")
* .column("LAST_NAME", "Doe")
* .column("DATE_OF_BIRTH", "1975-07-19")
* .column("CLIENT_TYPE", ClientType.NORMAL)
* .end()
* .build();
* </pre>
*
* @author JB Nizet
*/
@Immutable
public final class Insert implements Operation {
private final String table;
private final List<String> columnNames;
private final Map<String, List<Object>> generatedValues;
private final List<List<?>> rows;
private final boolean metadataUsed;
private final Map<String, Binder> binders;
private Insert(Builder builder) {
this.table = builder.table;
this.columnNames = builder.columnNames;
this.rows = builder.rows;
this.generatedValues = generateValues(builder.valueGenerators, rows.size());
this.binders = builder.binders;
this.metadataUsed = builder.metadataUsed;
}
private Map<String, List<Object>> generateValues(Map<String, ValueGenerator<?>> valueGenerators,
int count) {
Map<String, List<Object>> result = new LinkedHashMap<String, List<Object>>();
for (Map.Entry<String, ValueGenerator<?>> entry : valueGenerators.entrySet()) {
result.put(entry.getKey(), generateValues(entry.getValue(), count));
}
return result;
}
private List<Object> generateValues(ValueGenerator<?> valueGenerator, int count) {
List<Object> result = new ArrayList<Object>(count);
for (int i = 0; i < count; i++) {
result.add(valueGenerator.nextValue());
}
return result;
}
/**
* Inserts the values and generated values in the table. Unless <code>useMetadata</code> has been set to
* <code>false</code>, the given configuration is used to get the appropriate binder. Nevertheless, if a binder
* has explicitly been associated to a given column, this binder will always be used for this column.
*/
@edu.umd.cs.findbugs.annotations.SuppressWarnings(
value = "SQL_PREPARED_STATEMENT_GENERATED_FROM_NONCONSTANT_STRING",
justification = "The point here is precisely to compose a SQL String from column names coming from the user")
@Override
public void execute(Connection connection, BinderConfiguration configuration) throws SQLException {
List<String> allColumnNames = new ArrayList<String>(columnNames);
allColumnNames.addAll(generatedValues.keySet());
String query = generateSqlQuery(allColumnNames);
PreparedStatement stmt = connection.prepareStatement(query);
try {
Map<String, Binder> usedBinders = initializeBinders(stmt, allColumnNames, configuration);
int rowIndex = 0;
for (List<?> row : rows) {
int i = 0;
for (Object value : row) {
String columnName = columnNames.get(i);
Binder binder = usedBinders.get(columnName);
binder.bind(stmt, i + 1, value);
i++;
}
for (Map.Entry<String, List<Object>> entry : generatedValues.entrySet()) {
String columnName = entry.getKey();
List<Object> rowValues = entry.getValue();
Binder binder = usedBinders.get(columnName);
binder.bind(stmt, i + 1, rowValues.get(rowIndex));
i++;
}
stmt.executeUpdate();
rowIndex++;
}
}
finally {
stmt.close();
}
}
/**
* Gets the number of rows that are inserted in the database table when this insert operation is executed.
*/
public int getRowCount() {
return rows.size();
}
private String generateSqlQuery(List<String> allColumnNames) {
StringBuilder sql = new StringBuilder("insert into ").append(table).append(" (");
for (Iterator<String> it = allColumnNames.iterator(); it.hasNext(); ) {
String columnName = it.next();
sql.append(columnName);
if (it.hasNext()) {
sql.append(", ");
}
}
sql.append(") values (");
for (Iterator<String> it = allColumnNames.iterator(); it.hasNext(); ) {
it.next();
sql.append('?');
if (it.hasNext()) {
sql.append(", ");
}
}
sql.append(')');
return sql.toString();
}
private Map<String, Binder> initializeBinders(PreparedStatement stmt,
List<String> allColumnNames,
BinderConfiguration configuration) throws SQLException {
Map<String, Binder> result = new HashMap<String, Binder>();
ParameterMetaData metadata = null;
if (metadataUsed) {
try {
metadata = stmt.getParameterMetaData();
}
catch (SQLException e) {
metadata = null;
// the parameter metadata are probably not supported by the database. Pass null to the configuration.
// The default configuration will return the default binder, just as if useMetadata(false) had been used
}
}
int i = 1;
for (String columnName : allColumnNames) {
Binder binder = this.binders.get(columnName);
if (binder == null) {
binder = configuration.getBinder(metadata, i);
if (binder == null) {
throw new IllegalStateException("null binder returned from configuration "
+ configuration.getClass());
}
}
result.put(columnName, binder);
i++;
}
return result;
}
@Override
public String toString() {
return "insert into "
+ table
+ " [columns="
+ columnNames
+ ", generatedValues="
+ generatedValues
+ ", rows="
+ rows
+ ", metadataUsed="
+ metadataUsed
+ ", binders="
+ binders
+ "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + binders.hashCode();
result = prime * result + columnNames.hashCode();
result = prime * result + generatedValues.hashCode();
result = prime * result + Boolean.valueOf(metadataUsed).hashCode();
result = prime * result + rows.hashCode();
result = prime * result + table.hashCode();
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Insert other = (Insert) obj;
return binders.equals(other.binders)
&& columnNames.equals(other.columnNames)
&& generatedValues.equals(other.generatedValues)
&& metadataUsed == other.metadataUsed
&& rows.equals(other.rows)
&& table.equals(other.table);
}
/**
* Creates a new Builder instance, in order to build an Insert operation into the given table
* @param table the name of the table to insert into
* @return the created Builder
*/
public static Builder into(@Nonnull String table) {
Preconditions.checkNotNull(table, "table may not be null");
return new Builder(table);
}
/**
* A builder used to create an Insert operation. Such a builder may only be used once. Once it has built its Insert
* operation, all its methods throw an {@link IllegalStateException}.
* @see Insert
* @see Insert#into(String)
* @author JB Nizet
*/
public static final class Builder {
private final String table;
private final List<String> columnNames = new ArrayList<String>();
private final Map<String, ValueGenerator<?>> valueGenerators = new LinkedHashMap<String, ValueGenerator<?>>();
private final List<List<?>> rows = new ArrayList<List<?>>();
private boolean metadataUsed = true;
private final Map<String, Binder> binders = new HashMap<String, Binder>();
private boolean built;
private Builder(String table) {
this.table = table;
}
/**
* Specifies the list of columns into which values will be inserted. The values must the be specified, after,
* using the {@link #values(Object...)} method, or with the {@link #values(java.util.Map)} method, or by adding
* a row with named columns fluently using {@link #row()}.
* @param columns the names of the columns to insert into.
* @return this Builder instance, for chaining.
* @throws IllegalStateException if the Insert has already been built, or if this method has already been
* called, or if one of the given columns is also specified as one of the generated value columns, or if the
* set of columns has already been defined by adding a first row to the builder.
*/
public Builder columns(@Nonnull String... columns) {
Preconditions.checkState(!built, "The insert has already been built");
Preconditions.checkState(columnNames.isEmpty(), "columns have already been specified");
for (String column : columns) {
Preconditions.checkNotNull(column, "column may not be null");
Preconditions.checkState(!valueGenerators.containsKey(column),
"column "
+ column
+ " has already been specified as generated value column");
}
columnNames.addAll(Arrays.asList(columns));
return this;
}
/**
* Adds a row of values to insert.
* @param values the values to insert.
* @return this Builder instance, for chaining.
* @throws IllegalStateException if the Insert has already been built, or if the number of values doesn't match
* the number of columns.
*/
public Builder values(@Nonnull Object... values) {
return addRepeatingValues(Arrays.asList(values), 1);
}
/**
* Allows adding many rows with the same non-generated values to insert.
* @param values the values to insert.
* @return A RowRepeater, allowing to choose how many similar rows to add.
* @throws IllegalStateException if the Insert has already been built, or if the number of values doesn't match
* the number of columns.
*/
public RowRepeater repeatingValues(@Nonnull Object... values) {
Preconditions.checkState(!built, "The insert has already been built");
Preconditions.checkArgument(values.length == columnNames.size(),
"The number of values doesn't match the number of columns");
return new ListRowRepeater(this, Arrays.asList(values));
}
/**
* Starts building a new row with named columns to insert. If the row is the first one being added and the
* columns haven't been set yet by calling <code>columns()</code>, then the columns of this row constitute the
* column names (excluding the generated ones) of the Insert being built
* @return a {@link RowBuilder} instance, which, when built, will add a row (or several ones) to this insert
* builder.
* @throws IllegalStateException if the Insert has already been built.
* @see RowBuilder
*/
public RowBuilder row() {
Preconditions.checkState(!built, "The insert has already been built");
return new RowBuilder(this);
}
/**
* Adds a row to this builder. If no row has been added yet and the columns haven't been set yet by calling
* <code>columns()</code>, then the keys of this map constitute the column names (excluding the generated ones)
* of the Insert being built, in the order of the keys in the map (which is arbitrary unless an ordered or
* sorted map is used).
* @param row the row to add. The keys of the map are the column names, which must match with
* the column names specified in the call to {@link #columns(String...)}, or with the column names of the first
* added row. If a column name is not present in the map, null is inserted for this column.
* @return this Builder instance, for chaining.
* @throws IllegalStateException if the Insert has already been built.
* @throws IllegalArgumentException if a column name of the map doesn't match with any of the column names
* specified with {@link #columns(String...)}
*/
public Builder values(@Nonnull Map<String, ?> row) {
return addRepeatingValues(row, 1);
}
/**
* Allows adding many rows with the same non-generated values to insert.
* @return A RowRepeater, allowing to choose how many similar rows to add.
* @throws IllegalStateException if the Insert has already been built.
* @see #values(Map)
*/
public RowRepeater repeatingValues(@Nonnull Map<String, ?> row) {
Preconditions.checkState(!built, "The insert has already been built");
Preconditions.checkNotNull(row, "The row may not be null");
return new MapRowRepeater(this, row);
}
/**
* Associates a Binder to one or several columns.
* @param binder the binder to use, regardless of the metadata, for the given columns
* @param columns the name of the columns to associate with the given Binder
* @return this Builder instance, for chaining.
* @throws IllegalStateException if the Insert has already been built,
* @throws IllegalArgumentException if any of the given columns is not
* part of the columns or "generated value" columns.
*/
public Builder withBinder(@Nonnull Binder binder, @Nonnull String... columns) {
Preconditions.checkState(!built, "The insert has already been built");
Preconditions.checkNotNull(binder, "binder may not be null");
for (String columnName : columns) {
Preconditions.checkArgument(this.columnNames.contains(columnName)
|| this.valueGenerators.containsKey(columnName),
"column "
+ columnName
+ " is not one of the registered column names");
binders.put(columnName, binder);
}
return this;
}
/**
* Specifies a default value to be inserted in a column for all the rows inserted by the Insert operation.
* Calling this method is equivalent to calling
* <code>withGeneratedValue(column, ValueGenerators.constant(value))</code>
* @param column the name of the column
* @param value the default value to insert into the column
* @return this Builder instance, for chaining.
* @throws IllegalStateException if the Insert has already been built, or if the given column is part
* of the columns to insert.
*/
public Builder withDefaultValue(@Nonnull String column, Object value) {
return withGeneratedValue(column, ValueGenerators.constant(value));
}
/**
* Allows the given column to be populated by a value generator, which will be called for every row of the
* Insert operation being built.
* @param column the name of the column
* @param valueGenerator the generator generating values for the given column of every row
* @return this Builder instance, for chaining.
* @throws IllegalStateException if the Insert has already been built, or if the given column is part
* of the columns to insert.
*/
public Builder withGeneratedValue(@Nonnull String column, @Nonnull ValueGenerator<?> valueGenerator) {
Preconditions.checkState(!built, "The insert has already been built");
Preconditions.checkNotNull(column, "column may not be null");
Preconditions.checkNotNull(valueGenerator, "valueGenerator may not be null");
Preconditions.checkArgument(!columnNames.contains(column),
"column "
+ column
+ " is already listed in the list of column names");
valueGenerators.put(column, valueGenerator);
return this;
}
/**
* Determines if the metadata must be used to get the appropriate binder for each inserted column (except
* the ones which have been associated explicitly with a Binder). The default is <code>true</code>. The insert
* can be faster if set to <code>false</code>, but in this case, the binder used will be the one returned
* by the {@link BinderConfiguration} for a null metadata (which is, by default, the
* {@link Binders#defaultBinder() default binder}), except the ones which have been associated explicitly with
* a Binder.<br>
* Before version 1.3.0, a SQLException was thrown if the database doesn't support parameter metadata and
* <code>useMetadata(false)</code> wasn't called. Since version 1.3.0, if <code>useMetadata</code> is true
* (the default) but the database doesn't support metadata, then the default binder configuration returns the
* default binder. Using this method is thus normally unnecessary as of 1.3.0.
* @return this Builder instance, for chaining.
* @throws IllegalStateException if the Insert has already been built.
*/
public Builder useMetadata(boolean useMetadata) {
Preconditions.checkState(!built, "The insert has already been built");
this.metadataUsed = useMetadata;
return this;
}
/**
* Builds the Insert operation.
* @return the created Insert operation.
* @throws IllegalStateException if the Insert has already been built, or if no column and no generated value
* column has been specified.
*/
public Insert build() {
Preconditions.checkState(!built, "The insert has already been built");
Preconditions.checkState(!this.columnNames.isEmpty() || !this.valueGenerators.isEmpty(),
"no column and no generated value column has been specified");
built = true;
return new Insert(this);
}
@Override
public String toString() {
return "insert into "
+ table
+ " [columns="
+ columnNames
+ ", rows="
+ rows
+ ", valueGenerators="
+ valueGenerators
+ ", metadataUsed="
+ metadataUsed
+ ", binders="
+ binders
+ ", built="
+ built
+ "]";
}
private Builder addRepeatingValues(List<?> values, int times) {
Preconditions.checkState(!built, "The insert has already been built");
Preconditions.checkArgument(values.size() == columnNames.size(),
"The number of values doesn't match the number of columns");
List<Object> row = new ArrayList<Object>(values);
for (int i = 0; i < times; i++) {
rows.add(row);
}
return this;
}
private Builder addRepeatingValues(@Nonnull Map<String, ?> row, int times) {
Preconditions.checkState(!built, "The insert has already been built");
Preconditions.checkNotNull(row, "The row may not be null");
List<Object> values = mapToRow(row);
for (int i = 0; i < times; i++) {
rows.add(values);
}
return this;
}
private List<Object> mapToRow(@Nonnull Map<String, ?> row) {
boolean setColumns = rows.isEmpty() && columnNames.isEmpty();
if (setColumns) {
columns(row.keySet().toArray(new String[row.size()]));
}
else {
Set<String> rowColumnNames = new HashSet<String>(row.keySet());
rowColumnNames.removeAll(columnNames);
if (!rowColumnNames.isEmpty()) {
throw new IllegalArgumentException(
"The following columns of the row don't match with any column name: " + rowColumnNames);
}
}
List<Object> values = new ArrayList<Object>(columnNames.size());
for (String columnName : columnNames) {
values.add(row.get(columnName));
}
return values;
}
}
/**
* A row builder, constructed with {@link com.ninja_squad.dbsetup.operation.Insert.Builder#row()}. This builder
* allows adding a row with named columns to an Insert:
*
* <pre>
* Insert insert =
* Insert.into("CLIENT")
* .columns("CLIENT_ID", "FIRST_NAME", "LAST_NAME", "DATE_OF_BIRTH", "CLIENT_TYPE")
* .row().column("CLIENT_ID", 1L)
* .column("FIRST_NAME", "John")
* .column("LAST_NAME", "Doe")
* .column("DATE_OF_BIRTH", "1975-07-19")
* .column("CLIENT_TYPE", ClientType.NORMAL)
* .end()
* .row().column("CLIENT_ID", 2L)
* .column("FIRST_NAME", "Jack")
* .column("LAST_NAME", "Smith")
* .column("DATE_OF_BIRTH", "1969-08-22")
* .column("CLIENT_TYPE", ClientType.HIGH_PRIORITY)
* .end()
* .build();
* </pre>
*
* You may omit the call to <code>columns()</code>. In that case, the columns of the Insert will be the columns
* specified in the first added row.
*/
public static final class RowBuilder {
private final Builder builder;
private final Map<String, Object> row;
private boolean ended;
private RowBuilder(Builder builder) {
this.builder = builder;
// note: very important to use a LinkedHashMap here, to guarantee the ordering of the columns.
this.row = new LinkedHashMap<String, Object>();
}
/**
* Adds a new named column to the row. If a previous value has already been added for the same column, it's
* replaced by this new value.
* @param name the name of the column, which must match with a column name defined in the Insert Builder
* @param value the value of the column for the constructed row
* @return this builder, for chaining
* @throws IllegalArgumentException if the given name is not the name of one of the columns to insert
*/
public RowBuilder column(@Nonnull String name, Object value) {
Preconditions.checkState(!ended, "The row has already been ended and added to the Insert Builder");
if (!builder.columnNames.isEmpty()) {
Preconditions.checkNotNull(name, "the column name may not be null");
Preconditions.checkArgument(builder.columnNames.contains(name),
"column " + name + " is not one of the registered column names");
}
row.put(name, value);
return this;
}
/**
* Ends the row, adds it to the Insert Builder and returns it, for chaining.
* @return the Insert Builder
*/
public Builder end() {
Preconditions.checkState(!ended, "The row has already been ended and added to the Insert Builder");
ended = true;
return builder.values(row);
}
/**
* Ends the row, adds it to the Insert Builder the given amount of times, and returns it, for chaining.
* @param times the number of rows to add. Must be >= 0. If zero, no row is added.
* @return the Insert Builder
*/
public Builder times(int times) {
Preconditions.checkArgument(times >= 0, "the number of repeating values must be >= 0");
Preconditions.checkState(!ended, "The row has already been ended and added to the Insert Builder");
ended = true;
return builder.addRepeatingValues(row, times);
}
}
/**
* Allows inserting the same list of non-generated values several times.
*/
public interface RowRepeater {
/**
* Adds several rows with the same non-generated values to the insert. This method can only be called once.
* @param times the number of rows to add. Must be >= 0. If zero, no row is added.
* @return the Insert Builder, for chaining
* @throws IllegalStateException if the rows have already been added
*/
Builder times(int times);
}
/**
* Base abstract class for row repeaters.
*/
private abstract static class AbstractRowRepeater implements RowRepeater {
protected final Builder builder;
private boolean ended;
public AbstractRowRepeater(Builder builder) {
this.builder = builder;
}
protected abstract Builder doTimes(int times);
@Override
public Builder times(int times) {
Preconditions.checkArgument(times >= 0, "the number of repeating values must be >= 0");
Preconditions.checkState(!ended, "The rows have already been ended and added to the Insert Builder");
ended = true;
return doTimes(times);
}
}
/**
* Allows inserting the same list of non-generated values as list several times.
*/
private static final class ListRowRepeater extends AbstractRowRepeater {
private final List<Object> values;
private ListRowRepeater(Builder builder, List<Object> values) {
super(builder);
this.values = values;
}
@Override
public Builder doTimes(int times) {
return builder.addRepeatingValues(values, times);
}
}
/**
* Allows inserting the same list of non-generated values as map several times.
*/
private static final class MapRowRepeater extends AbstractRowRepeater {
private final Map<String, ?> values;
private MapRowRepeater(Builder builder, Map<String, ?> values) {
super(builder);
this.values = values;
}
@Override
public Builder doTimes(int times) {
return builder.addRepeatingValues(values, times);
}
}
}
================================================
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/operation/Operation.java
================================================
/*
* The MIT License
*
* Copyright (c) 2012, Ninja Squad
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.ninja_squad.dbsetup.operation;
import java.sql.Connection;
import java.sql.SQLException;
import com.ninja_squad.dbsetup.DbSetupTracker;
import com.ninja_squad.dbsetup.bind.BinderConfiguration;
/**
* An operation that the database setup executes. It's advised to make implementations of this interface
* immutable, and to make them implement equals and hashCode in order for {@link DbSetupTracker} to function
* properly.
* @author JB Nizet
*/
public interface Operation {
/**
* Executes the operation
* @param connection the connection used to execute the operation
* @param configuration the binder configuration, used to get appropriate binders based on the metadata of
* the prepared statements
* @throws SQLException if the execution throws a SQLException
*/
void execute(Connection connection, BinderConfiguration configuration) throws SQLException;
}
================================================
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/operation/SqlOperation.java
================================================
/*
* The MIT License
*
* Copyright (c) 2012, Ninja Squad
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.ninja_squad.dbsetup.operation;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.annotation.Nonnull;
import javax.annotation.concurrent.Immutable;
import com.ninja_squad.dbsetup.bind.BinderConfiguration;
import com.ninja_squad.dbsetup.util.Preconditions;
/**
* An operation which simply executes a SQL statement (using {@link Statement#executeUpdate(String)}). It can be useful,
* for example, to disable or re-enable constraints before/after deleting everything from tables, or inserting into
* tables having cross references.
* @author JB Nizet
*/
@Immutable
public final class SqlOperation implements Operation {
private final String sql;
/**
* Constructor
* @param sql the SQL query to execute
*/
private SqlOperation(String sql) {
Preconditions.checkNotNull(sql, "sql may not be null");
this.sql = sql;
}
@Override
public void execute(Connection connection, BinderConfiguration configuration) throws SQLException {
Statement stmt = connection.createStatement();
try {
stmt.executeUpdate(sql);
}
finally {
stmt.close();
}
}
/**
* Creates a SqlOperation for the given SQL statement
* @param sqlStatement the SQL statement to execute
* @return the created SqlOperation
*/
public static SqlOperation of(@Nonnull String sqlStatement) {
return new SqlOperation(sqlStatement);
}
/**
* Creates a sequence of SqlOperation for the given SQL statements.
* @param sqlStatements the SQL statements to execute
* @return the created sequence of operations
*/
public static Operation of(@Nonnull String... sqlStatements) {
return of(Arrays.asList(sqlStatements));
}
/**
* Creates a sequence of SqlOperation for the given SQL statements.
* @param sqlStatements the SQL statements to execute
* @return the created sequence of operations
*/
public static Operation of(@Nonnull List<String> sqlStatements) {
List<SqlOperation> operations = new ArrayList<SqlOperation>(sqlStatements.size());
for (String sql : sqlStatements) {
operations.add(new SqlOperation(sql));
}
return CompositeOperation.sequenceOf(operations);
}
@Override
public String toString() {
return sql;
}
@Override
public int hashCode() {
return sql.hashCode();
}
@Override
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (o == null) {
return false;
}
if (o.getClass() != this.getClass()) {
return false;
}
SqlOperation other = (SqlOperation) o;
return this.sql.equals(other.sql);
}
}
================================================
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/operation/Truncate.java
================================================
/*
* The MIT License
*
* Copyright (c) 2012, Ninja Squad
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.ninja_squad.dbsetup.operation;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.annotation.Nonnull;
import javax.annotation.concurrent.Immutable;
import com.ninja_squad.dbsetup.bind.BinderConfiguration;
/**
* An operation which deletes everything from a given database table using a TRUNCATE statement., which is sometimes
* faster that using a DELETE statement.
* @author JB Nizet
*/
@Immutable
public final class Truncate implements Operation {
private final String tableToTruncate;
private Truncate(String table) {
this.tableToTruncate = table;
}
@Override
public void execute(Connection connection, BinderConfiguration configuration) throws SQLException {
Statement stmt = connection.createStatement();
try {
stmt.executeUpdate("truncate table " + tableToTruncate);
}
finally {
stmt.close();
}
}
/**
* Returns an operation which truncates the given table.
* @param table the table to delete everything from.
*/
public static Truncate table(@Nonnull String table) {
return new Truncate(table);
}
/**
* Returns a composite operation which truncates the given tables, in the same order as the
* tables. If A has a foreign key to B, which has a foreign key to C, tables should be listed in the following
* order: A, B, C. Otherwise, referential constraint will break. If there is a cycle in the dependencies, you might
* want to use a sequence of {@link SqlOperation} to disable the foreign key constraints, then truncate the tables,
* then use another sequence of {@link SqlOperation} to re-enable the foreign key constraints.
* @param tables the tables to truncate.
*/
public static Operation tables(String... tables) {
return tables(Arrays.asList(tables));
}
/**
* Returns a composite operation which truncates the given tables, in the same order as the
* tables. If A has a foreign key to B, which has a foreign key to C, tables should be listed in the following
* order: A, B, C. Otherwise, referential constraint will break. If there is a cycle in the dependencies, you might
* want to use a sequence of {@link SqlOperation} to disable the foreign key constraints, then truncate the tables,
* then use another sequence of {@link SqlOperation} to re-enable the foreign key constraints.
* @param tables the tables to truncate.
*/
public static Operation tables(List<String> tables) {
List<Truncate> operations = new ArrayList<Truncate>(tables.size());
for (String table : tables) {
operations.add(new Truncate(table));
}
return CompositeOperation.sequenceOf(operations);
}
@Override
public String toString() {
return "truncate table " + tableToTruncate;
}
@Override
public int hashCode() {
return tableToTruncate.hashCode();
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Truncate other = (Truncate) obj;
return this.tableToTruncate.equals(other.tableToTruncate);
}
}
================================================
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/overview.html
================================================
<html>
<body>
DbSetup allows populating a database before executing automated integration tests
(typically, DAO/Repository automated tests). Although DBUnit, which is a great project, allows doing the same thing
and much more, it's also harder to use and setup. And in our experience, in 98% of the cases, DBUnit is only used
to pre-populate a database before executing every test method. This is the task on which DbSetup concentrates.
<p>
The philosophy of DbSetup is that DAO tests should not have to setup the database, execute tests, and then
remove everything from the database. Instead, a single setup method should be used to delete everything from the
database (whatever the previous test put in it, or the initial state of the database tables), and then populate it
with the data necessary to execute the test.
<p>
Another design choice of DbSetup is to provide an easy to use and simple Java API to populate the database, rather than
loading data from external XML files. Using a Java API has several advantages:
<ul>
<li>It allows using real Java types as data (longs, enums, etc.)</li>
<li>It allows defining default values, looping to generate several similar rows, storing data sets in variables
or factorizing their creation using reusable methods
<li>It allows viewing the data sets easily, without having to open external files, by storing the data set
directly into the test class, or by navigating through classes and methods using the IDE shortcuts.</li>
<li>For more complex situations, like cyclic referential integrity constraints between rows, the Java API
allows easily integrating SQL statements into the sequence of operations to execute to pre-populate the
database. These SQL statements can, for example, disable constraints and re-enable them, or update rows
after their insertion.</li>
</ul>
The {@link com.ninja_squad.dbsetup.DbSetup} class and the {@link com.ninja_squad.dbsetup.DbSetupTracker} classes
are the main entry points to the API that an automated test will use. Look at their javadoc below for example usage.
</body>
</html>
================================================
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/util/Preconditions.java
================================================
/*
* The MIT License
*
* Copyright (c) 2012, Ninja Squad
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.ninja_squad.dbsetup.util;
/**
* Utility class to help verifying preconditions
* @author JB Nizet
*/
public final class Preconditions {
private Preconditions() {
}
/**
* Throws a NullPointerException with the given message if the given argument is <code>null</code>.
* @param argument the argument to check for <code>null</code>
* @param message the message of the thrown NullPointerException
* @throws NullPointerException if argument is <code>null</code>.
*/
public static void checkNotNull(Object argument, String message) throws NullPointerException {
if (argument == null) {
throw new NullPointerException(message);
}
}
/**
* Throws an IllegalStateException with the given message if the given condition is <code>false</code>.
* @param condition the condition to check
* @param message the message of the thrown IllegalStateException
* @throws IllegalStateException if the condition is <code>false</code>.
*/
public static void checkState(boolean condition, String message) throws IllegalStateException {
if (!condition) {
throw new IllegalStateException(message);
}
}
/**
* Throws an IllegalARgumentException with the given message if the given condition is <code>false</code>.
* @param condition the condition to check
* @param message the message of the thrown IllegalArgumentException
* @throws IllegalArgumentException if the condition is <code>false</code>.
*/
public static void checkArgument(boolean condition, String message) throws IllegalStateException {
if (!condition) {
throw new IllegalArgumentException(message);
}
}
}
================================================
FILE: DbSetup-core/src/test/java/com/ninja_squad/dbsetup/DbSetupTest.java
================================================
/*
* The MIT License
*
* Copyright (c) 2012, Ninja Squad
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.ninja_squad.dbsetup;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import java.sql.Connection;
import java.sql.SQLException;
import org.junit.Test;
import org.mockito.InOrder;
import com.ninja_squad.dbsetup.bind.BinderConfiguration;
import com.ninja_squad.dbsetup.bind.DefaultBinderConfiguration;
import com.ninja_squad.dbsetup.destination.Destination;
import com.ninja_squad.dbsetup.operation.Operation;
/**
* @author JB Nizet
*/
public class DbSetupTest {
@Test
public void launchWorks() throws SQLException {
Destination destination = mock(Destination.class);
Connection connection = mock(Connection.class);
when(destination.getConnection()).thenReturn(connection);
Operation operation = mock(Operation.class);
DbSetup setup = new DbSetup(destination, operation);
setup.launch();
InOrder inOrder = inOrder(destination, connection, operation);
inOrder.verify(destination).getConnection();
inOrder.verify(operation).execute(connection, DefaultBinderConfiguration.INSTANCE);
inOrder.verify(connection).commit();
}
@Test
public void launchWorksWithCustomConfiguration() throws SQLException {
Destination destination = mock(Destination.class);
Connection connection = mock(Connection.class);
when(destination.getConnection()).thenReturn(connection);
Operation operation = mock(Operation.class);
BinderConfiguration config = mock(BinderConfiguration.class);
DbSetup setup = new DbSetup(destination, operation, config);
setup.launch();
InOrder inOrder = inOrder(destination, connection, operation);
inOrder.verify(destination).getConnection();
inOrder.verify(operation).execute(connection, config);
inOrder.verify(connection).commit();
}
@Test
public void launchRollbacksIfSQLException() throws SQLException {
Destination destination = mock(Destination.class);
Connection connection = mock(Connection.class);
when(destination.getConnection()).thenReturn(connection);
Operation operation = mock(Operation.class);
doThrow(new SQLException()).when(operation).execute(connection, DefaultBinderConfiguration.INSTANCE);
DbSetup setup = new DbSetup(destination, operation);
try {
setup.launch();
fail("Expected a DbSetupRuntimeException");
}
catch (DbSetupRuntimeException e) {
// expected
}
InOrder inOrder = inOrder(destination, connection, operation);
inOrder.verify(destination).getConnection();
inOrder.verify(operation).execute(connection, DefaultBinderConfiguration.INSTANCE);
inOrder.verify(connection).rollback();
}
@Test
public void launchRollbacksIfOtherException() throws SQLException {
Destination destination = mock(Destination.class);
Connection connection = mock(Connection.class);
when(destination.getConnection()).thenReturn(connection);
Operation operation = mock(Operation.class);
doThrow(new NullPointerException()).when(operation).execute(connection, DefaultBinderConfiguration.INSTANCE);
DbSetup setup = new DbSetup(destination, operation);
try {
setup.launch();
fail("Expected a DbSetupRuntimeException");
}
catch (NullPointerException e) {
// expected
}
InOrder inOrder = inOrder(destination, connection, operation);
inOrder.verify(destination).getConnection();
inOrder.verify(operation).execute(connection, DefaultBinderConfiguration.INSTANCE);
inOrder.verify(connection).rollback();
}
@Test
public void equalsAndHashCodeWork() throws SQLException {
Destination destination1 = mock(Destination.class);
Operation operation1 = mock(Operation.class);
BinderConfiguration config1 = DefaultBinderConfiguration.INSTANCE;
Destination destination2 = mock(Destination.class);
Operation operation2 = mock(Operation.class);
BinderConfiguration config2 = mock(BinderConfiguration.class);
DbSetup setup1 = new DbSetup(destination1, operation1, config1);
assertEquals(setup1, setup1);
assertEquals(setup1, new DbSetup(destination1, operation1, config1));
assertEquals(setup1.hashCode(), new DbSetup(destination1, operation1, config1).hashCode());
assertFalse(setup1.equals(null));
assertFalse(setup1.equals("hello"));
assertFalse(setup1.equals(new DbSetup(destination2, operation1, config1)));
assertFalse(setup1.equals(new DbSetup(destination1, operation2, config1)));
assertFalse(setup1.equals(new DbSetup(destination1, operation1, config2)));
}
@Test
public void toStringWorks() throws SQLException {
Destination destination1 = mock(Destination.class);
when(destination1.toString()).thenReturn("destination1");
Operation operation1 = mock(Operation.class);
when(operation1.toString()).thenReturn("operation1");
BinderConfiguration config1 = mock(BinderConfiguration.class);
when(config1.toString()).thenReturn("config1");
DbSetup setup1 = new DbSetup(destination1, operation1, config1);
assertEquals("DbSetup [destination=destination1, operation=operation1, binderConfiguration=config1]",
setup1.toString());
}
}
================================================
FILE: DbSetup-core/src/test/java/com/ninja_squad/dbsetup/DbSetupTrackerTest.java
================================================
/*
* The MIT License
*
* Copyright (c) 2012, Ninja Squad
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.ninja_squad.dbsetup;
import static org.junit.Assert.*;
import static org.mockito.Matchers.*;
import static org.mockito.Mockito.*;
import java.sql.Connection;
import java.sql.SQLException;
import org.junit.Before;
import org.junit.Test;
import com.ninja_squad.dbsetup.bind.BinderConfiguration;
import com.ninja_squad.dbsetup.destination.Destination;
import com.ninja_squad.dbsetup.operation.Operation;
/**
* @author JB Nizet
*/
public class DbSetupTrackerTest {
private Operation operation1;
private DbSetup dbSetup1;
private Operation operation2;
private DbSetup dbSetup2;
@Before
public void prepare() throws SQLException {
Destination destination = mock(Destination.class);
Connection connection = mock(Connection.class);
when(destination.getConnection()).thenReturn(connection);
operation1 = mock(Operation.class);
operation2 = mock(Operation.class);
dbSetup1 = new DbSetup(destination, operation1);
dbSetup2 = new DbSetup(destination, operation2);
}
@Test
public void launchIfNecessaryLaunchesTheFirstTime() throws SQLException {
DbSetupTracker tracker = new DbSetupTracker();
tracker.launchIfNecessary(dbSetup1);
verify(operation1).execute(any(Connection.class), any(BinderConfiguration.class));
}
@Test
public void launchIfNecessaryLaunchesIfNotSkipped() throws SQLException {
DbSetupTracker tracker = new DbSetupTracker();
tracker.launchIfNecessary(dbSetup1);
tracker.launchIfNecessary(dbSetup1);
verify(operation1, times(2)).execute(any(Connection.class), any(BinderConfiguration.class));
}
@Test
public void launchIfNecessaryDoesntLaunchIfSkipped() throws SQLException {
DbSetupTracker tracker = new DbSetupTracker();
tracker.launchIfNecessary(dbSetup1);
tracker.skipNextLaunch();
tracker.launchIfNecessary(dbSetup1);
verify(operation1, times(1)).execute(any(Connection.class), any(BinderConfiguration.class));
}
@Test
public void launchIfNecessaryResetsTheSkipFlag() throws SQLException {
DbSetupTracker tracker = new DbSetupTracker();
tracker.launchIfNecessary(dbSetup1);
tracker.skipNextLaunch();
tracker.launchIfNecessary(dbSetup1);
tracker.launchIfNecessary(dbSetup1);
verify(operation1, times(2)).execute(any(Connection.class), any(BinderConfiguration.class));
}
@Test
public void launchIfNecessaryDoesntLaunchIfDifferentSetup() throws SQLException {
DbSetupTracker tracker = new DbSetupTracker();
tracker.launchIfNecessary(dbSetup1);
tracker.skipNextLaunch();
tracker.launchIfNecessary(dbSetup2);
verify(operation1, times(1)).execute(any(Connection.class), any(BinderConfiguration.class));
verify(operation2, times(1)).execute(any(Connection.class), any(BinderConfiguration.class));
}
@Test
public void toStringWorks() {
DbSetupTracker tracker = new DbSetupTracker();
assertEquals("DbSetupTracker [lastSetupLaunched=null, nextLaunchSkipped=false]", tracker.toString());
}
}
================================================
FILE: DbSetup-core/src/test/java/com/ninja_squad/dbsetup/bind/BindersTest.java
================================================
/*
* The MIT License
*
* Copyright (c) 2012-2016, Ninja Squad
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.ninja_squad.dbsetup.bind;
import static org.mockito.Matchers.argThat;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Time;
import java.sql.Timestamp;
import java.sql.Types;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.OffsetTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.util.Calendar;
import java.util.TimeZone;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.junit.Before;
import org.junit.Test;
public class BindersTest {
private PreparedStatement stmt;
@Before
public void prepare() {
stmt = mock(PreparedStatement.class);
}
@Test
public void defaultBinderBindsObject() throws SQLException {
Binder binder = Binders.defaultBinder();
binder.bind(stmt, 1, Boolean.TRUE);
verify(stmt).setObject(1, Boolean.TRUE);
}
@Test
public void defaultBinderBindsNull() throws SQLException {
Binder binder = Binders.defaultBinder();
binder.bind(stmt, 1, null);
verify(stmt).setObject(1, null);
}
@Test
public void defaultBinderBindsEnum() throws SQLException {
Binder binder = Binders.defaultBinder();
binder.bind(stmt, 1, TestEnum.BAR);
verify(stmt).setString(1, TestEnum.BAR.name());
}
@Test
public void defaultBinderBindsUtilDate() throws SQLException {
java.util.Date date = new java.util.Date(Date.valueOf("1975-07-19").getTime());
Binder binder = Binders.defaultBinder();
binder.bind(stmt, 1, date);
verify(stmt).setTimestamp(1, new Timestamp(date.getTime()));
}
@Test
public void defaultBinderBindsCalendar() throws SQLException {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(Date.valueOf("1975-07-19").getTime());
Binder binder = Binders.defaultBinder();
binder.bind(stmt, 1, calendar);
verify(stmt).setTimestamp(1, new Timestamp(calendar.getTime().getTime()), calendar);
}
@Test
public void defaultBinderBindsLocalDate() throws SQLException {
LocalDate localDate = LocalDate.parse("1975-07-19");
Binder binder = Binders.defaultBinder();
binder.bind(stmt, 1, localDate);
verify(stmt).setDate(1, Date.valueOf(localDate));
}
@Test
public void defaultBinderBindsLocalTime() throws SQLException {
LocalTime localTime = LocalTime.parse("01:02:03.000");
Binder binder = Binders.defaultBinder();
binder.bind(stmt, 1, localTime);
verify(stmt).setTime(1, Time.valueOf("01:02:03"));
}
@Test
public void defaultBinderBindsLocalDateTime() throws SQLException {
LocalDateTime localDateTime = LocalDateTime.parse("1975-07-19T01:02:03.000");
Binder binder = Binders.defaultBinder();
binder.bind(stmt, 1, localDateTime);
verify(stmt).setTimestamp(1, Timestamp.valueOf("1975-07-19 01:02:03"));
}
@Test
public void defaultBinderBindsInstant() throws SQLException {
Instant instant = LocalDateTime.parse("1975-07-19T01:02:03.000").atZone(ZoneId.systemDefault()).toInstant();
Binder binder = Binders.defaultBinder();
binder.bind(stmt, 1, instant);
verify(stmt).setTimestamp(1, Timestamp.valueOf("1975-07-19 01:02:03"));
}
@Test
public void defaultBinderBindsZonedDateTime() throws SQLException {
ZonedDateTime zonedDateTime = LocalDateTime.parse("1975-07-19T01:02:03.000").atZone(ZoneOffset.UTC);
Binder binder = Binders.defaultBinder();
binder.bind(stmt, 1, zonedDateTime);
verify(stmt).setTimestamp(eq(1),
eq(Timestamp.from(zonedDateTime.toInstant())),
calendarWithTimeZone(TimeZone.getTimeZone(ZoneOffset.UTC)));
}
@Test
public void defaultBinderBindsOffsetDateTime() throws SQLException {
OffsetDateTime offsetDateTime = LocalDateTime.parse("1975-07-19T01:02:03.000").atOffset(ZoneOffset.UTC);
Binder binder = Binders.defaultBinder();
binder.bind(stmt, 1, offsetDateTime);
verify(stmt).setTimestamp(eq(1),
eq(Timestamp.from(offsetDateTime.toInstant())),
calendarWithTimeZone(TimeZone.getTimeZone(ZoneOffset.UTC)));
}
@Test
public void defaultBinderBindsOffsetTime() throws SQLException {
OffsetTime offsetTime = LocalTime.parse("01:02:03.000").atOffset(ZoneOffset.UTC);
Binder binder = Binders.defaultBinder();
binder.bind(stmt, 1, offsetTime);
verify(stmt).setTime(eq(1),
eq(Time.valueOf(offsetTime.toLocalTime())),
calendarWithTimeZone(TimeZone.getTimeZone(ZoneOffset.UTC)));
}
@Test
public void stringBinderBindsString() throws SQLException {
Binder binder = Binders.stringBinder();
binder.bind(stmt, 1, "hello");
verify(stmt).setString(1, "hello");
}
@Test
public void stringBinderBindsEnum() throws SQLException {
Binder binder = Binders.stringBinder();
binder.bind(stmt, 1, TestEnum.BAR);
verify(stmt).setString(1, "BAR");
}
@Test
public void stringBinderBindsObject() throws SQLException {
Binder binder = Binders.stringBinder();
binder.bind(stmt, 1, new Foo());
verify(stmt).setString(1, "foo");
}
@Test
public void stringBinderBindsNull() throws SQLException {
Binder binder = Binders.stringBinder();
binder.bind(stmt, 1, null);
verify(stmt).setObject(1, null);
}
@Test
public void dateBinderBindsSqlDate() throws SQLException {
Date date = Date.valueOf("1975-07-19");
Binder binder = Binders.dateBinder();
binder.bind(stmt, 1, date);
verify(stmt).setDate(1, date);
}
@Test
public void dateBinderBindsUtilDate() throws SQLException {
java.util.Date date = new java.util.Date(Date.valueOf("1975-07-19").getTime());
Binder binder = Binders.dateBinder();
binder.bind(stmt, 1, date);
verify(stmt).setDate(1, Date.valueOf("1975-07-19"));
}
@Test
public void dateBinderBindsCalendar() throws SQLException {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(Date.valueOf("1975-07-19").getTime());
Binder binder = Binders.dateBinder();
binder.bind(stmt, 1, calendar);
verify(stmt).setDate(1, Date.valueOf("1975-07-19"), calendar);
}
@Test
public void dateBinderBindsString() throws SQLException {
Binder binder = Binders.dateBinder();
binder.bind(stmt, 1, "1975-07-19");
verify(stmt).setDate(1, Date.valueOf("1975-07-19"));
}
@Test
public void dateBinderBindsLocalDate() throws SQLException {
Binder binder = Binders.dateBinder();
binder.bind(stmt, 1, LocalDate.parse("1975-07-19"));
verify(stmt).setDate(1, Date.valueOf("1975-07-19"));
}
@Test
public void dateBinderBindsLocalDateTime() throws SQLException {
Binder binder = Binders.dateBinder();
binder.bind(stmt, 1, LocalDateTime.parse("1975-07-19T01:02:03.000"));
verify(stmt).setDate(1, Date.valueOf("1975-07-19"));
}
@Test
public void dateBinderBindsInstant() throws SQLException {
Binder binder = Binders.dateBinder();
Instant value = LocalDateTime.parse("1975-07-19T01:02:03.000").atZone(ZoneId.systemDefault()).toInstant();
binder.bind(stmt, 1, value);
verify(stmt).setDate(1, new Date(value.toEpochMilli()));
}
@Test
public void dateBinderBindsZonedDateTime() throws SQLException {
Binder binder = Binders.dateBinder();
ZonedDateTime value = LocalDateTime.parse("1975-07-19T01:02:03.000").atZone(ZoneOffset.UTC);
binder.bind(stmt, 1, value);
verify(stmt).setDate(eq(1),
eq(new Date(value.toInstant().toEpochMilli())),
calendarWithTimeZone(TimeZone.getTimeZone(ZoneOffset.UTC)));
}
@Test
public void dateBinderBindsOffsetDateTime() throws SQLException {
Binder binder = Binders.dateBinder();
OffsetDateTime value = LocalDateTime.parse("1975-07-19T01:02:03.000").atOffset(ZoneOffset.UTC);
binder.bind(stmt, 1, value);
verify(stmt).setDate(eq(1),
eq(new Date(value.toInstant().toEpochMilli())),
calendarWithTimeZone(TimeZone.getTimeZone(ZoneOffset.UTC)));
}
@Test
public void dateBinderBindsNull() throws SQLException {
Binder binder = Binders.dateBinder();
binder.bind(stmt, 1, null);
verify(stmt).setObject(1, null);
}
@Test
public void dateBinderBindsObject() throws SQLException {
Binder binder = Binders.dateBinder();
binder.bind(stmt, 1, Boolean.TRUE);
verify(stmt).setObject(1, Boolean.TRUE);
}
@Test
public void timestampBinderBindsTimestamp() throws SQLException {
Timestamp ts = Timestamp.valueOf("1975-07-19 13:14:15");
Binder binder = Binders.timestampBinder();
binder.bind(stmt, 1, ts);
verify(stmt).setTimestamp(1, ts);
}
@Test
public void timestampBinderBindsUtilDate() throws SQLException {
Timestamp ts = Timestamp.valueOf("1975-07-19 13:14:15");
Binder binder = Binders.timestampBinder();
binder.bind(stmt, 1, new java.util.Date(ts.getTime()));
verify(stmt).setTimestamp(1, ts);
}
@Test
public void timestampBinderBindsCalendar() throws SQLException {
Timestamp ts = Timestamp.valueOf("1975-07-19 13:14:15");
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(ts.getTime());
Binder binder = Binders.timestampBinder();
binder.bind(stmt, 1, calendar);
verify(stmt).setTimestamp(1, ts, calendar);
}
@Test
public void timestampBinderBindsStringWithTimestampFormat() throws SQLException {
Binder binder = Binders.timestampBinder();
binder.bind(stmt, 1, "1975-07-19 13:14:15");
verify(stmt).setTimestamp(1, Timestamp.valueOf("1975-07-19 13:14:15"));
}
@Test
public void timestampBinderBindsStringWithDateFormat() throws SQLException {
Binder binder = Binders.timestampBinder();
binder.bind(stmt, 1, "1975-07-19");
verify(stmt).setTimestamp(1, Timestamp.valueOf("1975-07-19 00:00:00"));
}
@Test
public void timestampBinderBindsLocalDateTime() throws SQLException {
Binder binder = Binders.timestampBinder();
binder.bind(stmt, 1, LocalDateTime.parse("1975-07-19T01:02:03.000"));
verify(stmt).setTimestamp(1, Timestamp.valueOf("1975-07-19 01:02:03"));
}
@Test
public void timestampBinderBindsLocalDate() throws SQLException {
Binder binder = Binders.timestampBinder();
binder.bind(stmt, 1, LocalDate.parse("1975-07-19"));
verify(stmt).setTimestamp(1, Timestamp.valueOf("1975-07-19 00:00:00"));
}
@Test
public void timestampBinderBindsInstant() throws SQLException {
Binder binder = Binders.timestampBinder();
binder.bind(stmt, 1, LocalDateTime.parse("1975-07-19T01:02:03.000").atZone(ZoneId.systemDefault()).toInstant());
verify(stmt).setTimestamp(1, Timestamp.valueOf("1975-07-19 01:02:03"));
}
@Test
public void timestampBinderBindsZonedDateTime() throws SQLException {
Binder binder = Binders.timestampBinder();
ZonedDateTime value = LocalDateTime.parse("1975-07-19T01:02:03.000").atZone(ZoneOffset.UTC);
binder.bind(stmt, 1, value);
verify(stmt).setTimestamp(eq(1),
eq(Timestamp.from(value.toInstant())),
calendarWithTimeZone(TimeZone.getTimeZone(ZoneOffset.UTC)));
}
@Test
public void timestampBinderBindsOffsetDateTime() throws SQLException {
Binder binder = Binders.timestampBinder();
OffsetDateTime value = LocalDateTime.parse("1975-07-19T01:02:03.000").atOffset(ZoneOffset.UTC);
binder.bind(stmt, 1, value);
verify(stmt).setTimestamp(eq(1),
eq(Timestamp.from(value.toInstant())),
calendarWithTimeZone(TimeZone.getTimeZone(ZoneOffset.UTC)));
}
@Test
public void timestampBinderBindsNull() throws SQLException {
Binder binder = Binders.timestampBinder();
binder.bind(stmt, 1, null);
verify(stmt).setObject(1, null);
}
@Test
public void timestampBinderBindsObject() throws SQLException {
Binder binder = Binders.timestampBinder();
binder.bind(stmt, 1, Boolean.TRUE);
verify(stmt).setObject(1, Boolean.TRUE);
}
@Test
public void timeBinderBindsTime() throws SQLException {
Time time = Time.valueOf("13:14:15");
Binder binder = Binders.timeBinder();
binder.bind(stmt, 1, time);
verify(stmt).setTime(1, time);
}
@Test
public void timeBinderBindsUtilDate() throws SQLException {
Time time = Time.valueOf("13:14:15");
Binder binder = Binders.timeBinder();
binder.bind(stmt, 1, new java.util.Date(time.getTime()));
verify(stmt).setTime(1, time);
}
@Test
public void timeBinderBindsCalendar() throws SQLException {
Time time = Time.valueOf("13:14:15");
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(time.getTime());
Binder binder = Binders.timeBinder();
binder.bind(stmt, 1, calendar);
verify(stmt).setTime(1, time, calendar);
}
@Test
public void timeBinderBindsString() throws SQLException {
Binder binder = Binders.timeBinder();
binder.bind(stmt, 1, "13:14:15");
verify(stmt).setTime(1, Time.valueOf("13:14:15"));
}
@Test
public void timeBinderBindsLocalTime() throws SQLException {
Binder binder = Binders.timeBinder();
binder.bind(stmt, 1, LocalTime.parse("01:02:03.000"));
verify(stmt).setTime(1, Time.valueOf("01:02:03"));
}
@Test
public void timeBinderBindsOffsetTime() throws SQLException {
Binder binder = Binders.timeBinder();
binder.bind(stmt, 1, OffsetTime.of(LocalTime.parse("01:02:03.000"), ZoneOffset.UTC));
verify(stmt).setTime(eq(1),
eq(Time.valueOf("01:02:03")),
calendarWithTimeZone(TimeZone.getTimeZone(ZoneOffset.UTC)));
}
@Test
public void timeBinderBindsNull() throws SQLException {
Binder binder = Binders.timeBinder();
binder.bind(stmt, 1, null);
verify(stmt).setObject(1, null);
}
@Test
public void timeBinderBindsObject() throws SQLException {
Binder binder = Binders.timeBinder();
binder.bind(stmt, 1, Boolean.TRUE);
verify(stmt).setObject(1, Boolean.TRUE);
}
@Test
public void decimalBinderBindsString() throws SQLException {
Binder binder = Binders.decimalBinder();
binder.bind(stmt, 1, "12.45");
verify(stmt).setBigDecimal(1, new BigDecimal("12.45"));
}
@Test
public void decimalBinderBindsObject() throws SQLException {
Binder binder = Binders.decimalBinder();
binder.bind(stmt, 1, 12.45);
verify(stmt).setObject(1, 12.45);
}
@Test
public void decimalBinderBindsNull() throws SQLException {
Binder binder = Binders.decimalBinder();
binder.bind(stmt, 1, null);
verify(stmt).setObject(1, null);
}
@Test
public void integerBinderBindsBigInteger() throws SQLException {
Binder binder = Binders.integerBinder();
binder.bind(stmt, 1, new BigInteger("12"));
verify(stmt).setObject(1, "12", Types.BIGINT);
}
@Test
public void integerBinderBindsString() throws SQLException {
Binder binder = Binders.integerBinder();
binder.bind(stmt, 1, "12");
verify(stmt).setObject(1, "12", Types.BIGINT);
}
@Test
public void integerBinderBindsEnum() throws SQLException {
Binder binder = Binders.integerBinder();
binder.bind(stmt, 1, TestEnum.FOO);
verify(stmt).setInt(1, 0);
}
@Test
public void integerBinderBindsObject() throws SQLException {
Binder binder = Binders.integerBinder();
binder.bind(stmt, 1, 27);
verify(stmt).setObject(1, 27);
}
@Test
public void integerBinderBindsNull() throws SQLException {
Binder binder = Binders.integerBinder();
binder.bind(stmt, 1, null);
verify(stmt).setObject(1, null);
}
private enum TestEnum {
FOO, BAR;
}
private static class Foo {
@Override
public String toString() {
return "foo";
}
}
private static Calendar calendarWithTimeZone(TimeZone timeZone) {
return argThat(new BaseMatcher<Calendar>() {
@Override
public boolean matches(Object item) {
return (item instanceof Calendar) && ((Calendar) item).getTimeZone().equals(timeZone);
}
@Override
public void describeTo(Description description) {
description.appendText("a calendar with timezone " + timeZone);
}
});
}
}
================================================
FILE: DbSetup-core/src/test/java/com/ninja_squad/dbsetup/bind/DefaultBinderConfigurationTest.java
================================================
package com.ninja_squad.dbsetup.bind;
import org.junit.Test;
import java.sql.ParameterMetaData;
import java.sql.SQLException;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.*;
public class DefaultBinderConfigurationTest {
@Test
public void shouldReturnDefaultBinderIfNoParameterMetadata() throws SQLException {
assertEquals(Binders.defaultBinder(), DefaultBinderConfiguration.INSTANCE.getBinder(null, 1));
}
@Test
public void shouldReturnDefaultBinderIfParameterTypeCantBeObtained() throws SQLException {
ParameterMetaData mockMetaData = mock(ParameterMetaData.class);
when(mockMetaData.getParameterType(1)).thenThrow(new SQLException());
assertEquals(Binders.defaultBinder(), DefaultBinderConfiguration.INSTANCE.getBinder(mockMetaData, 1));
}
}
================================================
FILE: DbSetup-core/src/test/java/com/ninja_squad/dbsetup/destination/DataSourceDestinationTest.java
================================================
/*
* The MIT License
*
* Copyright (c) 2012, Ninja Squad
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.ninja_squad.dbsetup.destination;
import org.junit.Test;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
/**
* @author JB Nizet
*/
public class DataSourceDestinationTest {
@Test
public void getConnectionWorks() throws SQLException {
DataSource dataSource = mock(DataSource.class);
Connection connection = mock(Connection.class);
when(dataSource.getConnection()).thenReturn(connection);
assertSame(connection, new DataSourceDestination(dataSource).getConnection());
}
@Test
public void equalsAndHashCodeWork() throws SQLException {
DataSource dataSource1 = mock(DataSource.class);
DataSource dataSource2 = mock(DataSource.class);
Destination dest1 = new DataSourceDestination(dataSource1);
Destination dest1bis = DataSourceDestination.with(dataSource1);
Destination dest2 = new DataSourceDestination(dataSource2);
assertEquals(dest1, dest1);
assertEquals(dest1, dest1bis);
assertEquals(dest1.hashCode(), dest1bis.hashCode());
assertFalse(dest1.equals(dest2));
assertFalse(dest1.equals(null));
assertFalse(dest1.equals("hello"));
}
@Test
public void toStringWorks() {
DataSource dataSource1 = mock(DataSource.class);
when(dataSource1.toString()).thenReturn("dataSource1");
assertEquals("DataSourceDestination [dataSource=dataSource1]",
new DataSourceDestination(dataSource1).toString());
}
}
================================================
FILE: DbSetup-core/src/test/java/com/ninja_squad/dbsetup/destination/DriverManagerDestinationTest.java
================================================
/*
* The MIT License
*
* Copyright (c) 2012, Ninja Squad
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.ninja_squad.dbsetup.destination;
import static org.junit.Assert.*;
import org.junit.Test;
/**
* @author JB Nizet
*/
public class DriverManagerDestinationTest {
@Test
public void equalsAndHashCodeWork() {
Destination dest1 = new DriverManagerDestination("url", "user", "password");
Destination dest1bis = DriverManagerDestination.with("url", "user", "password");
assertEquals(dest1, dest1);
assertEquals(dest1, dest1bis);
assertEquals(dest1.hashCode(), dest1bis.hashCode());
assertFalse(dest1.equals(new DriverManagerDestination("url2", "user", "password")));
assertFalse(dest1.equals(new DriverManagerDestination("url", "user2", "password")));
assertFalse(dest1.equals(new DriverManagerDestination("url", "user", "password2")));
assertFalse(dest1.equals(new DriverManagerDestination("url", null, "password")));
assertFalse(dest1.equals(new DriverManagerDestination("url", "user", null)));
assertFalse(new DriverManagerDestination("url", null, "password").equals(dest1));
assertFalse(new DriverManagerDestination("url", "user", null).equals(dest1));
assertFalse(dest1.equals(null));
assertFalse(dest1.equals("hello"));
assertEquals(new DriverManagerDestination("url", null, null), new DriverManagerDestination("url", null, null));
assertEquals(new DriverManagerDestination("url", null, null).hashCode(),
new DriverManagerDestination("url", null, null).hashCode());
}
@Test
public void toStringWorks() {
assertEquals("DriverManagerDestination [url=theUrl, user=theUser, password=thePassword]",
new DriverManagerDestination("theUrl", "theUser", "thePassword").toString());
assertEquals("DriverManagerDestination [url=theUrl, user=null, password=null]",
new DriverManagerDestination("theUrl", null, null).toString());
}
}
================================================
FILE: DbSetup-core/src/test/java/com/ninja_squad/dbsetup/generator/DateSequenceValueGeneratorTest.java
================================================
/*
* The MIT License
*
* Copyright (c) 2013-2016, Ninja Squad
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.ninja_squad.dbsetup.generator;
import static org.junit.Assert.assertEquals;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
import org.junit.Test;
/**
* @author JB
*/
public class DateSequenceValueGeneratorTest {
@Test
public void startsAtToday() {
ZonedDateTime date = ValueGenerators.dateSequence().nextValue();
assertEquals(LocalDate.now().atStartOfDay(ZoneId.systemDefault()), date);
}
@Test
@SuppressWarnings("deprecation")
public void incrementsByOneDay() throws ParseException {
DateSequenceValueGenerator sequence = ValueGenerators.dateSequence().startingAt(july19Of2013AtMidnight());
sequence.nextValue();
ZonedDateTime date = sequence.nextValue();
assertEquals(LocalDateTime.parse("2013-07-20T00:00:00.000").atZone(ZoneId.systemDefault()), date);
}
@Test
@SuppressWarnings("deprecation")
public void allowsSettingNewStartAsDate() throws ParseException {
DateSequenceValueGenerator sequence = ValueGenerators.dateSequence().startingAt(july19Of2013AtMidnight());
assertEquals("2013-07-19T00:00:00.000", toLongString(sequence.nextValue()));
sequence.startingAt(july19Of1975AtMidnight());
assertEquals("1975-07-19T00:00:00.000", toLongString(sequence.nextValue()));
}
@Test
@SuppressWarnings("deprecation")
public void allowsSettingNewStartAsDateWithTimeZone() throws ParseException {
DateSequenceValueGenerator sequence =
ValueGenerators.dateSequence()
.startingAt(july19Of2013AtMidnightInParisTimeZone(), TimeZone.getTimeZone("UTC"));
assertEquals("2013-07-18T22:00:00.000", toLongStringInUTC(sequence.nextValue()));
}
@Test
public void allowsSettingNewStartAsString() throws ParseException {
DateSequenceValueGenerator sequence =
ValueGenerators.dateSequence()
.startingAt("2013-07-19");
assertEquals("2013-07-19T00:00:00.000", toLongString(sequence.nextValue()));
}
@Test
@SuppressWarnings("deprecation")
public void allowsSettingNewStartAsCalendar() throws ParseException {
Calendar start = Calendar.getInstance();
DateSequenceValueGenerator sequence =
ValueGenerators.dateSequence().startingAt(start);
assertEquals(start.getTime().getTime(), sequence.nextValue().toInstant().toEpochMilli());
}
@Test
public void allowsSettingNewStartAsLocalDate() throws ParseException {
LocalDate start = LocalDate.parse("2000-01-01");
DateSequenceValueGenerator sequence =
ValueGenerators.dateSequence().startingAt(start);
assertEquals(start.atStartOfDay(ZoneId.systemDefault()), sequence.nextValue());
}
@Test
public void allowsSettingNewStartAsLocalDateTime() throws ParseException {
LocalDateTime start = LocalDateTime.parse("2000-01-01T01:02:03.000");
DateSequenceValueGenerator sequence =
ValueGenerators.dateSequence().startingAt(start);
assertEquals(start.atZone(ZoneId.systemDefault()), sequence.nextValue());
}
@Test
public void allowsSettingNewStartAsZonedDateTime() throws ParseException {
ZonedDateTime start = ZonedDateTime.parse("2000-01-01T01:02:03.000Z");
DateSequenceValueGenerator sequence =
ValueGenerators.dateSequence().startingAt(start);
assertEquals(start, sequence.nextValue());
}
@Test
@SuppressWarnings("deprecation")
public void allowsSettingNewIncrement() throws ParseException {
DateSequenceValueGenerator sequence =
ValueGenerators.dateSequence()
.startingAt(july19Of2013AtMidnight())
.incrementingBy(2, DateSequenceValueGenerator.CalendarField.DAY);
assertEquals("2013-07-19T00:00:00.000", toLongString(sequence.nextValue()));
assertEquals("2013-07-21T00:00:00.000", toLongString(sequence.nextValue()));
}
@Test
@SuppressWarnings("deprecation")
public void allowsSettingNewIncrementInYears() throws ParseException {
DateSequenceValueGenerator sequence =
ValueGenerators.dateSequence()
.startingAt(july19Of2013AtMidnight())
.incrementingBy(1, DateSequenceValueGenerator.CalendarField.YEAR);
assertEquals("2013-07-19T00:00:00.000", toLongString(sequence.nextValue()));
assertEquals("2014-07-19T00:00:00.000", toLongString(sequence.nextValue()));
}
@Test
@SuppressWarnings("deprecation")
public void allowsSettingNewIncrementInMonths() throws ParseException {
DateSequenceValueGenerator sequence =
ValueGenerators.dateSequence()
.startingAt(july19Of2013AtMidnight())
.incrementingBy(1, DateSequenceValueGenerator.CalendarField.MONTH);
assertEquals("2013-07-19T00:00:00.000", toLongString(sequence.nextValue()));
assertEquals("2013-08-19T00:00:00.000", toLongString(sequence.nextValue()));
}
@Test
@SuppressWarnings("deprecation")
public void allowsSettingNewIncrementInHours() throws ParseException {
DateSequenceValueGenerator sequence =
ValueGenerators.dateSequence()
.startingAt(july19Of2013AtMidnight())
.incrementingBy(1, DateSequenceValueGenerator.CalendarField.HOUR);
assertEquals("2013-07-19T00:00:00.000", toLongString(sequence.nextValue()));
assertEquals("2013-07-19T01:00:00.000", toLongString(sequence.nextValue()));
}
@Test
@SuppressWarnings("deprecation")
public void allowsSettingNewIncrementInMinutes() throws ParseException {
DateSequenceValueGenerator sequence =
ValueGenerators.dateSequence()
.startingAt(july19Of2013AtMidnight())
.incrementingBy(1, DateSequenceValueGenerator.CalendarField.MINUTE);
assertEquals("2013-07-19T00:00:00.000", toLongString(sequence.nextValue()));
assertEquals("2013-07-19T00:01:00.000", toLongString(sequence.nextValue()));
}
@Test
@SuppressWarnings("deprecation")
public void allowsSettingNewIncrementInSeconds() throws ParseException {
DateSequenceValueGenerator sequence =
ValueGenerators.dateSequence()
.startingAt(july19Of2013AtMidnight())
.incrementingBy(1, DateSequenceValueGenerator.CalendarField.SECOND);
assertEquals("2013-07-19T00:00:00.000", toLongString(sequence.nextValue()));
assertEquals("2013-07-19T00:00:01.000", toLongString(sequence.nextValue()));
}
@Test
@SuppressWarnings("deprecation")
public void allowsSettingNewIncrementInMilliseconds() throws ParseException {
DateSequenceValueGenerator sequence =
ValueGenerators.dateSequence()
.startingAt(july19Of2013AtMidnight())
.incrementingBy(1, DateSequenceValueGenerator.CalendarField.MILLISECOND);
assertEquals("2013-07-19T00:00:00.000", toLongString(sequence.nextValue()));
assertEquals("2013-07-19T00:00:00.001", toLongString(sequence.nextValue()));
}
private String toLongString(ZonedDateTime date) {
return DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS").format(date);
}
private String toLongStringInUTC(ZonedDateTime date) {
return toLongString(date.withZoneSameInstant(ZoneOffset.UTC));
}
private Date july19Of2013AtMidnight() throws ParseException {
return new SimpleDateFormat("yyyy-MM-dd").parse("2013-07-19");
}
private Date july19Of1975AtMidnight() throws ParseException {
return new SimpleDateFormat("yyyy-MM-dd").parse("1975-07-19");
}
// offset is +02:00 in Paris at this date
private Date july19Of2013AtMidnightInParisTimeZone() throws ParseException {
TimeZone zone = TimeZone.getTimeZone("Europe/Paris");
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
simpleDateFormat.setTimeZone(zone);
return simpleDateFormat.parse("2013-07-19");
}
}
================================================
FILE: DbSetup-core/src/test/java/com/ninja_squad/dbsetup/generator/SequenceValueGeneratorTest.java
================================================
/*
* The MIT License
*
* Copyright (c) 2013, Ninja Squad
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.ninja_squad.dbsetup.generator;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* @author JB
*/
public class SequenceValueGeneratorTest {
@Test
public void startsAtOne() {
assertEquals(1L, ValueGenerators.sequence().nextValue().longValue());
}
@Test
public void incrementsByOne() {
SequenceValueGenerator sequence = ValueGenerators.sequence();
sequence.nextValue();
assertEquals(2L, sequence.nextValue().longValue());
}
@Test
public void allowsSettingNewStart() {
SequenceValueGenerator sequence = ValueGenerators.sequence().startingAt(12L);
assertEquals(12L, sequence.nextValue().longValue());
sequence.startingAt(5L);
assertEquals(5L, sequence.nextValue().longValue());
}
@Test
public void allowsSettingNewIncrement() {
SequenceValueGenerator sequence = ValueGenerators.sequence().incrementingBy(10);
assertEquals(1L, sequence.nextValue().longValue());
assertEquals(11L, sequence.nextValue().longValue());
}
}
================================================
FILE: DbSetup-core/src/test/java/com/ninja_squad/dbsetup/generator/StringSequenceValueGeneratorTest.java
================================================
/*
* The MIT License
*
* Copyright (c) 2013, Ninja Squad
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.ninja_squad.dbsetup.generator;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
/**
* @author JB
*/
public class StringSequenceValueGeneratorTest {
@Test
public void startsAtOne() {
assertEquals("CODE_1", ValueGenerators.stringSequence("CODE_").nextValue());
}
@Test
public void incrementsByOne() {
StringSequenceValueGenerator sequence = ValueGenerators.stringSequence("CODE_");
sequence.nextValue();
assertEquals("CODE_2", sequence.nextValue());
}
@Test
public void allowsSettingNewStart() {
StringSequenceValueGenerator sequence = ValueGenerators.stringSequence("CODE_").startingAt(12L);
assertEquals("CODE_12", sequence.nextValue());
sequence.startingAt(5L);
assertEquals("CODE_5", sequence.nextValue());
}
@Test
public void allowsSettingNewIncrement() {
StringSequenceValueGenerator sequence = ValueGenerators.stringSequence("CODE_").incrementingBy(10);
assertEquals("CODE_1", sequence.nextValue());
assertEquals("CODE_11", sequence.nextValue());
}
@Test
public void allowsSettingLeftPadding() {
StringSequenceValueGenerator sequence =
ValueGenerators.stringSequence("CODE_").withLeftPadding(2);
assertEquals("CODE_01", sequence.nextValue());
assertEquals("CODE_02", sequence.nextValue());
sequence.startingAt(10L);
assertEquals("CODE_10", sequence.nextValue());
assertEquals("CODE_11", sequence.nextValue());
sequence.startingAt(100L);
assertEquals("CODE_100", sequence.nextValue());
assertEquals("CODE_101", sequence.nextValue());
}
@Test
public void allowsUnsettingLeftPadding() {
StringSequenceValueGenerator sequence =
ValueGenerators.stringSequence("CODE_").withLeftPadding(2);
sequence.withoutLeftPadding();
assertEquals("CODE_1", sequence.nextValue());
assertEquals("CODE_2", sequence.nextValue());
}
}
================================================
FILE: DbSetup-core/src/test/java/com/ninja_squad/dbsetup/generator/ValueGeneratorsTest.java
================================================
package com.ninja_squad.dbsetup.generator;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* @author JB
*/
public class ValueGeneratorsTest {
@Test
public void contantShouldReturnGeneratorWhichGeneratesAConstantValue() {
ValueGenerator<String> constantGenerator = ValueGenerators.constant("hello");
for (int i = 0; i < 3; i++) {
assertEquals("hello", constantGenerator.nextValue());
}
}
// other methods are tested by the test for the class returned by the method
}
================================================
FILE: DbSetup-core/src/test/java/com/ninja_squad/dbsetup/integration/CommonOperations.java
================================================
/*
* The MIT License
*
gitextract_dbqecuzp/ ├── .circleci/ │ └── config.yml ├── .gitignore ├── DbSetup-core/ │ ├── build.gradle.kts │ └── src/ │ ├── main/ │ │ └── java/ │ │ └── com/ │ │ └── ninja_squad/ │ │ └── dbsetup/ │ │ ├── DbSetup.java │ │ ├── DbSetupRuntimeException.java │ │ ├── DbSetupTracker.java │ │ ├── Operations.java │ │ ├── bind/ │ │ │ ├── Binder.java │ │ │ ├── BinderConfiguration.java │ │ │ ├── Binders.java │ │ │ └── DefaultBinderConfiguration.java │ │ ├── destination/ │ │ │ ├── DataSourceDestination.java │ │ │ ├── Destination.java │ │ │ └── DriverManagerDestination.java │ │ ├── generator/ │ │ │ ├── DateSequenceValueGenerator.java │ │ │ ├── SequenceValueGenerator.java │ │ │ ├── StringSequenceValueGenerator.java │ │ │ ├── ValueGenerator.java │ │ │ └── ValueGenerators.java │ │ ├── operation/ │ │ │ ├── CompositeOperation.java │ │ │ ├── DeleteAll.java │ │ │ ├── Insert.java │ │ │ ├── Operation.java │ │ │ ├── SqlOperation.java │ │ │ └── Truncate.java │ │ ├── overview.html │ │ └── util/ │ │ └── Preconditions.java │ └── test/ │ └── java/ │ └── com/ │ └── ninja_squad/ │ └── dbsetup/ │ ├── DbSetupTest.java │ ├── DbSetupTrackerTest.java │ ├── bind/ │ │ ├── BindersTest.java │ │ └── DefaultBinderConfigurationTest.java │ ├── destination/ │ │ ├── DataSourceDestinationTest.java │ │ └── DriverManagerDestinationTest.java │ ├── generator/ │ │ ├── DateSequenceValueGeneratorTest.java │ │ ├── SequenceValueGeneratorTest.java │ │ ├── StringSequenceValueGeneratorTest.java │ │ └── ValueGeneratorsTest.java │ ├── integration/ │ │ ├── CommonOperations.java │ │ ├── Database.java │ │ ├── DeleteAllIntegrationTest.java │ │ ├── InsertIntegrationTest.java │ │ ├── RollbackIntegrationTest.java │ │ └── TruncateIntegrationTest.java │ └── operation/ │ ├── CompositeOperationTest.java │ ├── DeleteAllTest.java │ ├── InsertTest.java │ ├── SqlOperationTest.java │ └── TruncateTest.java ├── DbSetup-kotlin/ │ ├── build.gradle.kts │ └── src/ │ ├── main/ │ │ └── kotlin/ │ │ └── com/ │ │ └── ninja_squad/ │ │ └── dbsetup_kotlin/ │ │ ├── DbSetup.kt │ │ ├── DbSetupBuilder.kt │ │ ├── Functions.kt │ │ └── Insert.Builder.kt │ └── test/ │ └── kotlin/ │ └── com/ │ └── ninja_squad/ │ └── dbsetup_kotlin/ │ ├── DbSetupBuilderTest.kt │ ├── InsertBuilderTest.kt │ └── MockitoExtensions.kt ├── README.md ├── build.gradle.kts ├── buildSrc/ │ ├── build.gradle.kts │ ├── settings.grade.kts │ └── src/ │ └── main/ │ └── kotlin/ │ └── java-library-convention.gradle.kts ├── gradle/ │ └── wrapper/ │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── gradlew ├── gradlew.bat └── settings.gradle.kts
SYMBOL INDEX (416 symbols across 44 files)
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/DbSetup.java
class DbSetup (line 64) | public final class DbSetup {
method DbSetup (line 75) | public DbSetup(@Nonnull Destination destination, @Nonnull Operation op...
method DbSetup (line 86) | public DbSetup(@Nonnull Destination destination,
method launch (line 102) | public void launch() {
method toString (line 127) | @Override
method hashCode (line 138) | @Override
method equals (line 148) | @Override
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/DbSetupRuntimeException.java
class DbSetupRuntimeException (line 31) | public class DbSetupRuntimeException extends RuntimeException {
method DbSetupRuntimeException (line 33) | public DbSetupRuntimeException() {
method DbSetupRuntimeException (line 37) | public DbSetupRuntimeException(String message, Throwable cause) {
method DbSetupRuntimeException (line 41) | public DbSetupRuntimeException(String message) {
method DbSetupRuntimeException (line 45) | public DbSetupRuntimeException(Throwable cause) {
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/DbSetupTracker.java
class DbSetupTracker (line 82) | public final class DbSetupTracker {
method launchIfNecessary (line 95) | public void launchIfNecessary(@Nonnull DbSetup dbSetup) {
method skipNextLaunch (line 109) | public void skipNextLaunch() {
method toString (line 113) | @Override
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/Operations.java
class Operations (line 42) | public final class Operations {
method Operations (line 43) | private Operations() {
method deleteAllFrom (line 51) | public static DeleteAll deleteAllFrom(@Nonnull String table) {
method deleteAllFrom (line 60) | public static Operation deleteAllFrom(@Nonnull String... tables) {
method deleteAllFrom (line 69) | public static Operation deleteAllFrom(@Nonnull List<String> tables) {
method truncate (line 78) | public static Truncate truncate(@Nonnull String table) {
method truncate (line 87) | public static Operation truncate(@Nonnull String... tables) {
method truncate (line 96) | public static Operation truncate(@Nonnull List<String> tables) {
method sql (line 105) | public static SqlOperation sql(@Nonnull String sqlStatement) {
method sql (line 114) | public static Operation sql(@Nonnull String... sqlStatements) {
method sql (line 123) | public static Operation sql(@Nonnull List<String> sqlStatements) {
method insertInto (line 132) | public static Insert.Builder insertInto(@Nonnull String table) {
method sequenceOf (line 141) | public static Operation sequenceOf(@Nonnull Operation... operations) {
method sequenceOf (line 150) | public static Operation sequenceOf(@Nonnull List<? extends Operation> ...
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/bind/Binder.java
type Binder (line 38) | public interface Binder {
method bind (line 46) | void bind(PreparedStatement statement, int param, Object value) throws...
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/bind/BinderConfiguration.java
type BinderConfiguration (line 45) | public interface BinderConfiguration {
method getBinder (line 56) | Binder getBinder(@Nullable ParameterMetaData metadata, int param) thro...
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/bind/Binders.java
class Binders (line 48) | public final class Binders {
method Binders (line 58) | private Binders() {
method defaultBinder (line 84) | public static Binder defaultBinder() {
method stringBinder (line 96) | public static Binder stringBinder() {
method dateBinder (line 124) | public static Binder dateBinder() {
method timestampBinder (line 154) | public static Binder timestampBinder() {
method timeBinder (line 180) | public static Binder timeBinder() {
method decimalBinder (line 191) | public static Binder decimalBinder() {
method integerBinder (line 208) | public static Binder integerBinder() {
class StringBinder (line 216) | private static final class StringBinder implements Binder {
method bind (line 217) | @Override
method toString (line 233) | @Override
class TimeBinder (line 243) | private static final class TimeBinder implements Binder {
method bind (line 244) | @Override
method toString (line 273) | @Override
class IntegerBinder (line 283) | private static final class IntegerBinder implements Binder {
method bind (line 284) | @Override
method toString (line 300) | @Override
class DecimalBinder (line 310) | private static final class DecimalBinder implements Binder {
method bind (line 311) | @Override
method toString (line 321) | @Override
class TimestampBinder (line 331) | private static final class TimestampBinder implements Binder {
method bind (line 335) | @Override
method toString (line 385) | @Override
class DateBinder (line 395) | private static final class DateBinder implements Binder {
method bind (line 396) | @Override
method toString (line 440) | @Override
class DefaultBinder (line 450) | private static final class DefaultBinder implements Binder {
method bind (line 451) | @Override
method toString (line 498) | @Override
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/bind/DefaultBinderConfiguration.java
class DefaultBinderConfiguration (line 37) | public class DefaultBinderConfiguration implements BinderConfiguration {
method DefaultBinderConfiguration (line 48) | protected DefaultBinderConfiguration() {
method getBinder (line 68) | @Override
method toString (line 113) | @Override
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/destination/DataSourceDestination.java
class DataSourceDestination (line 39) | @Immutable
method DataSourceDestination (line 47) | public DataSourceDestination(@Nonnull DataSource dataSource) {
method with (line 74) | public static DataSourceDestination with(@Nonnull DataSource dataSourc...
method getConnection (line 78) | @Override
method toString (line 83) | @Override
method hashCode (line 88) | @Override
method equals (line 93) | @Override
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/destination/Destination.java
type Destination (line 38) | public interface Destination {
method getConnection (line 44) | Connection getConnection() throws SQLException;
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/destination/DriverManagerDestination.java
class DriverManagerDestination (line 39) | @Immutable
method DriverManagerDestination (line 52) | public DriverManagerDestination(@Nonnull String url, String user, Stri...
method with (line 83) | public static DriverManagerDestination with(@Nonnull String url, Strin...
method getConnection (line 87) | @Override
method toString (line 92) | @Override
method hashCode (line 103) | @Override
method equals (line 113) | @Override
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/generator/DateSequenceValueGenerator.java
class DateSequenceValueGenerator (line 46) | public final class DateSequenceValueGenerator implements ValueGenerator<...
type CalendarField (line 55) | @Deprecated
method CalendarField (line 67) | CalendarField(TemporalUnit unit) {
method toTemporalUnit (line 71) | private TemporalUnit toTemporalUnit() {
method DateSequenceValueGenerator (line 80) | DateSequenceValueGenerator() {
method DateSequenceValueGenerator (line 84) | private DateSequenceValueGenerator(ZonedDateTime next, int increment, ...
method startingAt (line 95) | @Deprecated
method startingAt (line 108) | @Deprecated
method startingAt (line 118) | @Deprecated
method startingAt (line 132) | public DateSequenceValueGenerator startingAt(@Nonnull String startDate) {
method startingAt (line 146) | public DateSequenceValueGenerator startingAt(@Nonnull LocalDate startD...
method startingAt (line 154) | public DateSequenceValueGenerator startingAt(@Nonnull LocalDateTime st...
method startingAt (line 162) | public DateSequenceValueGenerator startingAt(@Nonnull ZonedDateTime st...
method incrementingBy (line 172) | @Deprecated
method incrementingBy (line 183) | public DateSequenceValueGenerator incrementingBy(int increment, @Nonnu...
method nextValue (line 190) | @Override
method toString (line 197) | @Override
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/generator/SequenceValueGenerator.java
class SequenceValueGenerator (line 33) | public final class SequenceValueGenerator implements ValueGenerator<Long> {
method SequenceValueGenerator (line 38) | SequenceValueGenerator() {
method SequenceValueGenerator (line 42) | private SequenceValueGenerator(long start, int increment) {
method startingAt (line 52) | public SequenceValueGenerator startingAt(long start) {
method incrementingBy (line 61) | public SequenceValueGenerator incrementingBy(int increment) {
method nextValue (line 66) | @Override
method toString (line 73) | @Override
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/generator/StringSequenceValueGenerator.java
class StringSequenceValueGenerator (line 35) | public final class StringSequenceValueGenerator implements ValueGenerato...
method StringSequenceValueGenerator (line 45) | StringSequenceValueGenerator(String prefix) {
method StringSequenceValueGenerator (line 49) | private StringSequenceValueGenerator(String prefix, long next, int inc...
method withLeftPadding (line 63) | public StringSequenceValueGenerator withLeftPadding(int paddedNumberLe...
method withoutLeftPadding (line 73) | public StringSequenceValueGenerator withoutLeftPadding() {
method startingAt (line 83) | public StringSequenceValueGenerator startingAt(long start) {
method incrementingBy (line 92) | public StringSequenceValueGenerator incrementingBy(int increment) {
method nextValue (line 97) | @Override
method leftPadIfNecessary (line 104) | private String leftPadIfNecessary(long number) {
method toString (line 116) | @Override
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/generator/ValueGenerator.java
type ValueGenerator (line 36) | public interface ValueGenerator<T> {
method nextValue (line 41) | T nextValue();
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/generator/ValueGenerators.java
class ValueGenerators (line 36) | public final class ValueGenerators {
method ValueGenerators (line 37) | private ValueGenerators() {
method sequence (line 47) | public static SequenceValueGenerator sequence() {
method constant (line 54) | public static <T> ValueGenerator<T> constant(@Nullable final T constan...
method stringSequence (line 74) | public static StringSequenceValueGenerator stringSequence(@Nonnull Str...
method dateSequence (line 84) | public static DateSequenceValueGenerator dateSequence() {
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/operation/CompositeOperation.java
class CompositeOperation (line 41) | @Immutable
method execute (line 46) | @Override
method toString (line 51) | @Override
method CompositeOperation (line 59) | private CompositeOperation(List<? extends Operation> operations) {
method sequenceOf (line 67) | public static Operation sequenceOf(@Nonnull Operation... operations) {
method sequenceOf (line 75) | public static Operation sequenceOf(@Nonnull List<? extends Operation> ...
method execute (line 89) | @Override
method toString (line 96) | @Override
method hashCode (line 112) | @Override
method equals (line 117) | @Override
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/operation/DeleteAll.java
class DeleteAll (line 43) | @Immutable
method DeleteAll (line 48) | private DeleteAll(String table) {
method execute (line 53) | @Override
method from (line 68) | public static DeleteAll from(@Nonnull String table) {
method from (line 80) | public static Operation from(@Nonnull String... tables) {
method from (line 92) | public static Operation from(@Nonnull List<String> tables) {
method toString (line 100) | @Override
method hashCode (line 105) | @Override
method equals (line 110) | @Override
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/operation/Insert.java
class Insert (line 156) | @Immutable
method Insert (line 166) | private Insert(Builder builder) {
method generateValues (line 175) | private Map<String, List<Object>> generateValues(Map<String, ValueGene...
method generateValues (line 184) | private List<Object> generateValues(ValueGenerator<?> valueGenerator, ...
method execute (line 197) | @edu.umd.cs.findbugs.annotations.SuppressWarnings(
method getRowCount (line 241) | public int getRowCount() {
method generateSqlQuery (line 245) | private String generateSqlQuery(List<String> allColumnNames) {
method initializeBinders (line 267) | private Map<String, Binder> initializeBinders(PreparedStatement stmt,
method toString (line 298) | @Override
method hashCode (line 316) | @Override
method equals (line 329) | @Override
method into (line 355) | public static Builder into(@Nonnull String table) {
class Builder (line 367) | public static final class Builder {
method Builder (line 378) | private Builder(String table) {
method columns (line 392) | public Builder columns(@Nonnull String... columns) {
method values (line 413) | public Builder values(@Nonnull Object... values) {
method repeatingValues (line 424) | public RowRepeater repeatingValues(@Nonnull Object... values) {
method row (line 440) | public RowBuilder row() {
method values (line 458) | public Builder values(@Nonnull Map<String, ?> row) {
method repeatingValues (line 468) | public RowRepeater repeatingValues(@Nonnull Map<String, ?> row) {
method withBinder (line 483) | public Builder withBinder(@Nonnull Binder binder, @Nonnull String......
method withDefaultValue (line 507) | public Builder withDefaultValue(@Nonnull String column, Object value) {
method withGeneratedValue (line 520) | public Builder withGeneratedValue(@Nonnull String column, @Nonnull V...
method useMetadata (line 546) | public Builder useMetadata(boolean useMetadata) {
method build (line 558) | public Insert build() {
method toString (line 566) | @Override
method addRepeatingValues (line 585) | private Builder addRepeatingValues(List<?> values, int times) {
method addRepeatingValues (line 597) | private Builder addRepeatingValues(@Nonnull Map<String, ?> row, int ...
method mapToRow (line 608) | private List<Object> mapToRow(@Nonnull Map<String, ?> row) {
class RowBuilder (line 656) | public static final class RowBuilder {
method RowBuilder (line 661) | private RowBuilder(Builder builder) {
method column (line 675) | public RowBuilder column(@Nonnull String name, Object value) {
method end (line 690) | public Builder end() {
method times (line 701) | public Builder times(int times) {
type RowRepeater (line 712) | public interface RowRepeater {
method times (line 719) | Builder times(int times);
class AbstractRowRepeater (line 725) | private abstract static class AbstractRowRepeater implements RowRepeat...
method AbstractRowRepeater (line 729) | public AbstractRowRepeater(Builder builder) {
method doTimes (line 733) | protected abstract Builder doTimes(int times);
method times (line 735) | @Override
class ListRowRepeater (line 747) | private static final class ListRowRepeater extends AbstractRowRepeater {
method ListRowRepeater (line 750) | private ListRowRepeater(Builder builder, List<Object> values) {
method doTimes (line 755) | @Override
class MapRowRepeater (line 764) | private static final class MapRowRepeater extends AbstractRowRepeater {
method MapRowRepeater (line 767) | private MapRowRepeater(Builder builder, Map<String, ?> values) {
method doTimes (line 772) | @Override
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/operation/Operation.java
type Operation (line 39) | public interface Operation {
method execute (line 48) | void execute(Connection connection, BinderConfiguration configuration)...
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/operation/SqlOperation.java
class SqlOperation (line 46) | @Immutable
method SqlOperation (line 55) | private SqlOperation(String sql) {
method execute (line 60) | @Override
method of (line 76) | public static SqlOperation of(@Nonnull String sqlStatement) {
method of (line 85) | public static Operation of(@Nonnull String... sqlStatements) {
method of (line 94) | public static Operation of(@Nonnull List<String> sqlStatements) {
method toString (line 102) | @Override
method hashCode (line 107) | @Override
method equals (line 112) | @Override
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/operation/Truncate.java
class Truncate (line 44) | @Immutable
method Truncate (line 49) | private Truncate(String table) {
method execute (line 53) | @Override
method table (line 68) | public static Truncate table(@Nonnull String table) {
method tables (line 80) | public static Operation tables(String... tables) {
method tables (line 92) | public static Operation tables(List<String> tables) {
method toString (line 100) | @Override
method hashCode (line 105) | @Override
method equals (line 110) | @Override
FILE: DbSetup-core/src/main/java/com/ninja_squad/dbsetup/util/Preconditions.java
class Preconditions (line 31) | public final class Preconditions {
method Preconditions (line 32) | private Preconditions() {
method checkNotNull (line 41) | public static void checkNotNull(Object argument, String message) throw...
method checkState (line 53) | public static void checkState(boolean condition, String message) throw...
method checkArgument (line 65) | public static void checkArgument(boolean condition, String message) th...
FILE: DbSetup-core/src/test/java/com/ninja_squad/dbsetup/DbSetupTest.java
class DbSetupTest (line 44) | public class DbSetupTest {
method launchWorks (line 46) | @Test
method launchWorksWithCustomConfiguration (line 61) | @Test
method launchRollbacksIfSQLException (line 77) | @Test
method launchRollbacksIfOtherException (line 99) | @Test
method equalsAndHashCodeWork (line 121) | @Test
method toStringWorks (line 143) | @Test
FILE: DbSetup-core/src/test/java/com/ninja_squad/dbsetup/DbSetupTrackerTest.java
class DbSetupTrackerTest (line 44) | public class DbSetupTrackerTest {
method prepare (line 52) | @Before
method launchIfNecessaryLaunchesTheFirstTime (line 64) | @Test
method launchIfNecessaryLaunchesIfNotSkipped (line 71) | @Test
method launchIfNecessaryDoesntLaunchIfSkipped (line 79) | @Test
method launchIfNecessaryResetsTheSkipFlag (line 88) | @Test
method launchIfNecessaryDoesntLaunchIfDifferentSetup (line 98) | @Test
method toStringWorks (line 108) | @Test
FILE: DbSetup-core/src/test/java/com/ninja_squad/dbsetup/bind/BindersTest.java
class BindersTest (line 57) | public class BindersTest {
method prepare (line 61) | @Before
method defaultBinderBindsObject (line 66) | @Test
method defaultBinderBindsNull (line 73) | @Test
method defaultBinderBindsEnum (line 80) | @Test
method defaultBinderBindsUtilDate (line 87) | @Test
method defaultBinderBindsCalendar (line 95) | @Test
method defaultBinderBindsLocalDate (line 104) | @Test
method defaultBinderBindsLocalTime (line 112) | @Test
method defaultBinderBindsLocalDateTime (line 120) | @Test
method defaultBinderBindsInstant (line 128) | @Test
method defaultBinderBindsZonedDateTime (line 136) | @Test
method defaultBinderBindsOffsetDateTime (line 146) | @Test
method defaultBinderBindsOffsetTime (line 156) | @Test
method stringBinderBindsString (line 166) | @Test
method stringBinderBindsEnum (line 173) | @Test
method stringBinderBindsObject (line 180) | @Test
method stringBinderBindsNull (line 187) | @Test
method dateBinderBindsSqlDate (line 194) | @Test
method dateBinderBindsUtilDate (line 202) | @Test
method dateBinderBindsCalendar (line 210) | @Test
method dateBinderBindsString (line 219) | @Test
method dateBinderBindsLocalDate (line 226) | @Test
method dateBinderBindsLocalDateTime (line 233) | @Test
method dateBinderBindsInstant (line 240) | @Test
method dateBinderBindsZonedDateTime (line 248) | @Test
method dateBinderBindsOffsetDateTime (line 258) | @Test
method dateBinderBindsNull (line 268) | @Test
method dateBinderBindsObject (line 275) | @Test
method timestampBinderBindsTimestamp (line 282) | @Test
method timestampBinderBindsUtilDate (line 290) | @Test
method timestampBinderBindsCalendar (line 298) | @Test
method timestampBinderBindsStringWithTimestampFormat (line 308) | @Test
method timestampBinderBindsStringWithDateFormat (line 315) | @Test
method timestampBinderBindsLocalDateTime (line 322) | @Test
method timestampBinderBindsLocalDate (line 329) | @Test
method timestampBinderBindsInstant (line 336) | @Test
method timestampBinderBindsZonedDateTime (line 343) | @Test
method timestampBinderBindsOffsetDateTime (line 353) | @Test
method timestampBinderBindsNull (line 363) | @Test
method timestampBinderBindsObject (line 370) | @Test
method timeBinderBindsTime (line 377) | @Test
method timeBinderBindsUtilDate (line 385) | @Test
method timeBinderBindsCalendar (line 393) | @Test
method timeBinderBindsString (line 403) | @Test
method timeBinderBindsLocalTime (line 410) | @Test
method timeBinderBindsOffsetTime (line 417) | @Test
method timeBinderBindsNull (line 426) | @Test
method timeBinderBindsObject (line 433) | @Test
method decimalBinderBindsString (line 440) | @Test
method decimalBinderBindsObject (line 447) | @Test
method decimalBinderBindsNull (line 454) | @Test
method integerBinderBindsBigInteger (line 461) | @Test
method integerBinderBindsString (line 468) | @Test
method integerBinderBindsEnum (line 475) | @Test
method integerBinderBindsObject (line 482) | @Test
method integerBinderBindsNull (line 489) | @Test
type TestEnum (line 496) | private enum TestEnum {
class Foo (line 500) | private static class Foo {
method toString (line 501) | @Override
method calendarWithTimeZone (line 507) | private static Calendar calendarWithTimeZone(TimeZone timeZone) {
FILE: DbSetup-core/src/test/java/com/ninja_squad/dbsetup/bind/DefaultBinderConfigurationTest.java
class DefaultBinderConfigurationTest (line 11) | public class DefaultBinderConfigurationTest {
method shouldReturnDefaultBinderIfNoParameterMetadata (line 13) | @Test
method shouldReturnDefaultBinderIfParameterTypeCantBeObtained (line 18) | @Test
FILE: DbSetup-core/src/test/java/com/ninja_squad/dbsetup/destination/DataSourceDestinationTest.java
class DataSourceDestinationTest (line 39) | public class DataSourceDestinationTest {
method getConnectionWorks (line 40) | @Test
method equalsAndHashCodeWork (line 48) | @Test
method toStringWorks (line 64) | @Test
FILE: DbSetup-core/src/test/java/com/ninja_squad/dbsetup/destination/DriverManagerDestinationTest.java
class DriverManagerDestinationTest (line 34) | public class DriverManagerDestinationTest {
method equalsAndHashCodeWork (line 35) | @Test
method toStringWorks (line 58) | @Test
FILE: DbSetup-core/src/test/java/com/ninja_squad/dbsetup/generator/DateSequenceValueGeneratorTest.java
class DateSequenceValueGeneratorTest (line 46) | public class DateSequenceValueGeneratorTest {
method startsAtToday (line 47) | @Test
method incrementsByOneDay (line 53) | @Test
method allowsSettingNewStartAsDate (line 62) | @Test
method allowsSettingNewStartAsDateWithTimeZone (line 71) | @Test
method allowsSettingNewStartAsString (line 80) | @Test
method allowsSettingNewStartAsCalendar (line 88) | @Test
method allowsSettingNewStartAsLocalDate (line 97) | @Test
method allowsSettingNewStartAsLocalDateTime (line 105) | @Test
method allowsSettingNewStartAsZonedDateTime (line 113) | @Test
method allowsSettingNewIncrement (line 121) | @Test
method allowsSettingNewIncrementInYears (line 132) | @Test
method allowsSettingNewIncrementInMonths (line 143) | @Test
method allowsSettingNewIncrementInHours (line 154) | @Test
method allowsSettingNewIncrementInMinutes (line 165) | @Test
method allowsSettingNewIncrementInSeconds (line 176) | @Test
method allowsSettingNewIncrementInMilliseconds (line 187) | @Test
method toLongString (line 198) | private String toLongString(ZonedDateTime date) {
method toLongStringInUTC (line 202) | private String toLongStringInUTC(ZonedDateTime date) {
method july19Of2013AtMidnight (line 206) | private Date july19Of2013AtMidnight() throws ParseException {
method july19Of1975AtMidnight (line 210) | private Date july19Of1975AtMidnight() throws ParseException {
method july19Of2013AtMidnightInParisTimeZone (line 215) | private Date july19Of2013AtMidnightInParisTimeZone() throws ParseExcep...
FILE: DbSetup-core/src/test/java/com/ninja_squad/dbsetup/generator/SequenceValueGeneratorTest.java
class SequenceValueGeneratorTest (line 34) | public class SequenceValueGeneratorTest {
method startsAtOne (line 35) | @Test
method incrementsByOne (line 40) | @Test
method allowsSettingNewStart (line 47) | @Test
method allowsSettingNewIncrement (line 55) | @Test
FILE: DbSetup-core/src/test/java/com/ninja_squad/dbsetup/generator/StringSequenceValueGeneratorTest.java
class StringSequenceValueGeneratorTest (line 34) | public class StringSequenceValueGeneratorTest {
method startsAtOne (line 35) | @Test
method incrementsByOne (line 40) | @Test
method allowsSettingNewStart (line 47) | @Test
method allowsSettingNewIncrement (line 55) | @Test
method allowsSettingLeftPadding (line 62) | @Test
method allowsUnsettingLeftPadding (line 76) | @Test
FILE: DbSetup-core/src/test/java/com/ninja_squad/dbsetup/generator/ValueGeneratorsTest.java
class ValueGeneratorsTest (line 10) | public class ValueGeneratorsTest {
method contantShouldReturnGeneratorWhichGeneratesAConstantValue (line 12) | @Test
FILE: DbSetup-core/src/test/java/com/ninja_squad/dbsetup/integration/CommonOperations.java
class CommonOperations (line 34) | public class CommonOperations {
FILE: DbSetup-core/src/test/java/com/ninja_squad/dbsetup/integration/Database.java
class Database (line 36) | public class Database {
method getConnection (line 52) | public static Connection getConnection() throws SQLException {
FILE: DbSetup-core/src/test/java/com/ninja_squad/dbsetup/integration/DeleteAllIntegrationTest.java
class DeleteAllIntegrationTest (line 44) | public class DeleteAllIntegrationTest {
method prepare (line 48) | @Before
method cleanup (line 56) | @After
method testDeleteAll (line 61) | @Test
FILE: DbSetup-core/src/test/java/com/ninja_squad/dbsetup/integration/InsertIntegrationTest.java
class InsertIntegrationTest (line 61) | public class InsertIntegrationTest {
method prepare (line 64) | @Before
method cleanup (line 71) | @After
method testInsert (line 76) | @Test
method testWithoutMetadata (line 132) | @Test
method insertEnumToVarcharColumnWithoutMetadataShouldWork (line 174) | @Test
method insertJavaUtilDateToDateColumnWithoutMetadataShouldWork (line 185) | @Test
method insertJavaUtilCalendarToDateColumnWithoutMetadataShouldWork (line 196) | @Test
method insertJavaUtilDateToTimestampColumnWithoutMetadataShouldWork (line 207) | @Test
method insertJavaUtilCalendarToTimestampColumnWithoutMetadataShouldWork (line 218) | @Test
method insertLocalDateTimeToTimestampColumnWithoutMetadataShouldWork (line 229) | @Test
method insertLocalDateToDateColumnWithoutMetadataShouldWork (line 240) | @Test
method insertLocalTimeToTimeColumnWithoutMetadataShouldWork (line 251) | @Test
method insertInstantToTimestampColumnWithoutMetadataShouldWork (line 262) | @Test
method insertZonedDateTimeToTimestampColumnWithoutMetadataShouldWork (line 273) | @Test
method insertOffsetDateTimeToTimestampColumnWithoutMetadataShouldWork (line 284) | @Test
method insertOffsetTimeToTimeColumnWithoutMetadataShouldWork (line 295) | @Test
class Foo (line 306) | private static class Foo {
method Foo (line 309) | public Foo(String label) {
method getLabel (line 313) | public String getLabel() {
class FooBinder (line 318) | private static class FooBinder implements Binder {
method bind (line 320) | @Override
type TestEnum (line 327) | private enum TestEnum {
FILE: DbSetup-core/src/test/java/com/ninja_squad/dbsetup/integration/RollbackIntegrationTest.java
class RollbackIntegrationTest (line 46) | public class RollbackIntegrationTest {
method prepare (line 49) | @Before
method cleanup (line 56) | @After
method testRollbackIfSQLException (line 61) | @Test
method testRollbackIfOtherException (line 85) | @Test
FILE: DbSetup-core/src/test/java/com/ninja_squad/dbsetup/integration/TruncateIntegrationTest.java
class TruncateIntegrationTest (line 44) | public class TruncateIntegrationTest {
method prepare (line 48) | @Before
method cleanup (line 56) | @After
method testDeleteAll (line 61) | @Test
FILE: DbSetup-core/src/test/java/com/ninja_squad/dbsetup/operation/CompositeOperationTest.java
class CompositeOperationTest (line 44) | public class CompositeOperationTest {
method sequenceOfWorksWhenNop (line 45) | @Test
method testNoArgOpWorks (line 53) | private void testNoArgOpWorks(Operation nop) throws SQLException {
method sequenceOfWorksWhenSingleArg (line 59) | @Test
method sequenceOfWorksWhenSeveralArgs (line 69) | @Test
method testSequenceOfWorksWhenMultipleArgs (line 80) | private void testSequenceOfWorksWhenMultipleArgs(Operation composite, ...
method equalsAndHashCodeWork (line 88) | @Test
method toStringWorks (line 103) | @Test
FILE: DbSetup-core/src/test/java/com/ninja_squad/dbsetup/operation/DeleteAllTest.java
class DeleteAllTest (line 44) | public class DeleteAllTest {
method fromWorks (line 46) | @Test
method toStringWorks (line 54) | @Test
method equalsAndHashCodeWork (line 59) | @Test
method testFrom (line 70) | private void testFrom(Operation deleteAllFromAandB) throws SQLException {
FILE: DbSetup-core/src/test/java/com/ninja_squad/dbsetup/operation/InsertTest.java
class InsertTest (line 48) | public class InsertTest {
method insertWorks (line 50) | @Test
method insertWorksWithoutMetadata (line 106) | @Test
method insertWorksWhenMetadataNotSupported (line 145) | @Test
method insertWorksWhenColumnsSpecifiedByFirstRow (line 170) | @Test
method insertWorksWhenColumnsSpecifiedByFirstRepeatedRow (line 220) | @Test
method rowBuilderColumnFailsWhenMapContainsUnknownColumnName (line 257) | @Test(expected = IllegalArgumentException.class)
method valuesFailsWhenMapContainsUnknownColumnName (line 264) | @Test(expected = IllegalArgumentException.class)
method endRowFailsWhenItContainsUnknownColumnNameAndColumnNamesSpecifiedByFirstRow (line 273) | @Test(expected = IllegalArgumentException.class)
method repeatingValuesWork (line 280) | @Test
method rowAsMapCanBeAddedSeveralTimes (line 311) | @Test
method dynamicRowCanBeAddedSeveralTimes (line 350) | @Test
method toStringWorks (line 388) | @Test
method builderToStringWorks (line 403) | @Test
method equalsAndHashCodeWork (line 437) | @Test
method getRowCountWorks (line 530) | @Test
FILE: DbSetup-core/src/test/java/com/ninja_squad/dbsetup/operation/SqlOperationTest.java
class SqlOperationTest (line 44) | public class SqlOperationTest {
method ofWorks (line 46) | @Test
method toStringWorks (line 54) | @Test
method equalsAndHashCodeWork (line 59) | @Test
method testOf (line 70) | private void testOf(Operation aAndB) throws SQLException {
FILE: DbSetup-core/src/test/java/com/ninja_squad/dbsetup/operation/TruncateTest.java
class TruncateTest (line 44) | public class TruncateTest {
method tablesWorks (line 46) | @Test
method toStringWorks (line 54) | @Test
method equalsAndHashCodeWork (line 59) | @Test
method testFrom (line 70) | private void testFrom(Operation truncateAandB) throws SQLException {
Condensed preview — 67 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (312K chars).
[
{
"path": ".circleci/config.yml",
"chars": 334,
"preview": "version: 2\njobs:\n build:\n\n working_directory: ~/DbSetup\n\n docker:\n - image: circleci/openjdk:8-jdk\n\n step"
},
{
"path": ".gitignore",
"chars": 120,
"preview": "/.project\n.gradle\n/.settings\n/bin\nbuild/\n/.classpath\n/.classpath.idea/\n/.java-version\n*.iml\n.idea\nout\nclasses\n.sdkmanrc\n"
},
{
"path": "DbSetup-core/build.gradle.kts",
"chars": 734,
"preview": "plugins {\n `java-library-convention`\n}\n\nproject.description = \"Helps you setup your database with test data\"\n\njava {\n"
},
{
"path": "DbSetup-core/src/main/java/com/ninja_squad/dbsetup/DbSetup.java",
"chars": 6421,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2012, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to any p"
},
{
"path": "DbSetup-core/src/main/java/com/ninja_squad/dbsetup/DbSetupRuntimeException.java",
"chars": 1663,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2012, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to any p"
},
{
"path": "DbSetup-core/src/main/java/com/ninja_squad/dbsetup/DbSetupTracker.java",
"chars": 4279,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2012, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to any p"
},
{
"path": "DbSetup-core/src/main/java/com/ninja_squad/dbsetup/Operations.java",
"chars": 5152,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2012, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to any p"
},
{
"path": "DbSetup-core/src/main/java/com/ninja_squad/dbsetup/bind/Binder.java",
"chars": 2085,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2012, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to any p"
},
{
"path": "DbSetup-core/src/main/java/com/ninja_squad/dbsetup/bind/BinderConfiguration.java",
"chars": 2834,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2012, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to any p"
},
{
"path": "DbSetup-core/src/main/java/com/ninja_squad/dbsetup/bind/Binders.java",
"chars": 23129,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2012-2016, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to "
},
{
"path": "DbSetup-core/src/main/java/com/ninja_squad/dbsetup/bind/DefaultBinderConfiguration.java",
"chars": 4635,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2012-2016, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to "
},
{
"path": "DbSetup-core/src/main/java/com/ninja_squad/dbsetup/destination/DataSourceDestination.java",
"chars": 3417,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2012, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to any p"
},
{
"path": "DbSetup-core/src/main/java/com/ninja_squad/dbsetup/destination/Destination.java",
"chars": 1841,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2012, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to any p"
},
{
"path": "DbSetup-core/src/main/java/com/ninja_squad/dbsetup/destination/DriverManagerDestination.java",
"chars": 4657,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2012, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to any p"
},
{
"path": "DbSetup-core/src/main/java/com/ninja_squad/dbsetup/generator/DateSequenceValueGenerator.java",
"chars": 7611,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2013-2016, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to "
},
{
"path": "DbSetup-core/src/main/java/com/ninja_squad/dbsetup/generator/SequenceValueGenerator.java",
"chars": 2659,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2013, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to any p"
},
{
"path": "DbSetup-core/src/main/java/com/ninja_squad/dbsetup/generator/StringSequenceValueGenerator.java",
"chars": 4684,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2013-2016, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to "
},
{
"path": "DbSetup-core/src/main/java/com/ninja_squad/dbsetup/generator/ValueGenerator.java",
"chars": 1920,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2013, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to any p"
},
{
"path": "DbSetup-core/src/main/java/com/ninja_squad/dbsetup/generator/ValueGenerators.java",
"chars": 3408,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2013, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to any p"
},
{
"path": "DbSetup-core/src/main/java/com/ninja_squad/dbsetup/operation/CompositeOperation.java",
"chars": 4168,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2012, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to any p"
},
{
"path": "DbSetup-core/src/main/java/com/ninja_squad/dbsetup/operation/DeleteAll.java",
"chars": 4695,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2012, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to any p"
},
{
"path": "DbSetup-core/src/main/java/com/ninja_squad/dbsetup/operation/Insert.java",
"chars": 34405,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2012-2016, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to "
},
{
"path": "DbSetup-core/src/main/java/com/ninja_squad/dbsetup/operation/Operation.java",
"chars": 2056,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2012, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to any p"
},
{
"path": "DbSetup-core/src/main/java/com/ninja_squad/dbsetup/operation/SqlOperation.java",
"chars": 4082,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2012, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to any p"
},
{
"path": "DbSetup-core/src/main/java/com/ninja_squad/dbsetup/operation/Truncate.java",
"chars": 4617,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2012, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to any p"
},
{
"path": "DbSetup-core/src/main/java/com/ninja_squad/dbsetup/overview.html",
"chars": 2141,
"preview": "<html>\n <body>\n DbSetup allows populating a database before executing automated integration tests\n (typically, DAO/Re"
},
{
"path": "DbSetup-core/src/main/java/com/ninja_squad/dbsetup/util/Preconditions.java",
"chars": 2901,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2012, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to any p"
},
{
"path": "DbSetup-core/src/test/java/com/ninja_squad/dbsetup/DbSetupTest.java",
"chars": 6656,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2012, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to any p"
},
{
"path": "DbSetup-core/src/test/java/com/ninja_squad/dbsetup/DbSetupTrackerTest.java",
"chars": 4323,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2012, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to any p"
},
{
"path": "DbSetup-core/src/test/java/com/ninja_squad/dbsetup/bind/BindersTest.java",
"chars": 19045,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2012-2016, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to "
},
{
"path": "DbSetup-core/src/test/java/com/ninja_squad/dbsetup/bind/DefaultBinderConfigurationTest.java",
"chars": 840,
"preview": "package com.ninja_squad.dbsetup.bind;\n\nimport org.junit.Test;\n\nimport java.sql.ParameterMetaData;\nimport java.sql.SQLExc"
},
{
"path": "DbSetup-core/src/test/java/com/ninja_squad/dbsetup/destination/DataSourceDestinationTest.java",
"chars": 2761,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2012, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to any p"
},
{
"path": "DbSetup-core/src/test/java/com/ninja_squad/dbsetup/destination/DriverManagerDestinationTest.java",
"chars": 3109,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2012, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to any p"
},
{
"path": "DbSetup-core/src/test/java/com/ninja_squad/dbsetup/generator/DateSequenceValueGeneratorTest.java",
"chars": 9709,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2013-2016, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to "
},
{
"path": "DbSetup-core/src/test/java/com/ninja_squad/dbsetup/generator/SequenceValueGeneratorTest.java",
"chars": 2220,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2013, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to any p"
},
{
"path": "DbSetup-core/src/test/java/com/ninja_squad/dbsetup/generator/StringSequenceValueGeneratorTest.java",
"chars": 3185,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2013, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to any p"
},
{
"path": "DbSetup-core/src/test/java/com/ninja_squad/dbsetup/generator/ValueGeneratorsTest.java",
"chars": 538,
"preview": "package com.ninja_squad.dbsetup.generator;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * @author JB"
},
{
"path": "DbSetup-core/src/test/java/com/ninja_squad/dbsetup/integration/CommonOperations.java",
"chars": 2081,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2012, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to any p"
},
{
"path": "DbSetup-core/src/test/java/com/ninja_squad/dbsetup/integration/Database.java",
"chars": 1983,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2012, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to any p"
},
{
"path": "DbSetup-core/src/test/java/com/ninja_squad/dbsetup/integration/DeleteAllIntegrationTest.java",
"chars": 2815,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2012, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to any p"
},
{
"path": "DbSetup-core/src/test/java/com/ninja_squad/dbsetup/integration/InsertIntegrationTest.java",
"chars": 12474,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2012-2016, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to "
},
{
"path": "DbSetup-core/src/test/java/com/ninja_squad/dbsetup/integration/RollbackIntegrationTest.java",
"chars": 3761,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2012, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to any p"
},
{
"path": "DbSetup-core/src/test/java/com/ninja_squad/dbsetup/integration/TruncateIntegrationTest.java",
"chars": 2809,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2012, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to any p"
},
{
"path": "DbSetup-core/src/test/java/com/ninja_squad/dbsetup/operation/CompositeOperationTest.java",
"chars": 4400,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2012, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to any p"
},
{
"path": "DbSetup-core/src/test/java/com/ninja_squad/dbsetup/operation/DeleteAllTest.java",
"chars": 3048,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2012, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to any p"
},
{
"path": "DbSetup-core/src/test/java/com/ninja_squad/dbsetup/operation/InsertTest.java",
"chars": 23806,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2012-2015, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to "
},
{
"path": "DbSetup-core/src/test/java/com/ninja_squad/dbsetup/operation/SqlOperationTest.java",
"chars": 2961,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2012, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to any p"
},
{
"path": "DbSetup-core/src/test/java/com/ninja_squad/dbsetup/operation/TruncateTest.java",
"chars": 3035,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2012, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to any p"
},
{
"path": "DbSetup-kotlin/build.gradle.kts",
"chars": 911,
"preview": "import java.time.Duration\n\nplugins {\n `java-library-convention`\n kotlin(\"jvm\") version \"1.4.20\"\n id(\"org.jetbra"
},
{
"path": "DbSetup-kotlin/src/main/kotlin/com/ninja_squad/dbsetup_kotlin/DbSetup.kt",
"chars": 1787,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2016, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to any p"
},
{
"path": "DbSetup-kotlin/src/main/kotlin/com/ninja_squad/dbsetup_kotlin/DbSetupBuilder.kt",
"chars": 4927,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2016, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to any p"
},
{
"path": "DbSetup-kotlin/src/main/kotlin/com/ninja_squad/dbsetup_kotlin/Functions.kt",
"chars": 4096,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2016, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to any p"
},
{
"path": "DbSetup-kotlin/src/main/kotlin/com/ninja_squad/dbsetup_kotlin/Insert.Builder.kt",
"chars": 3627,
"preview": "/*\n * The MIT License\n *\n * Copyright (c) 2016, Ninja Squad\n *\n * Permission is hereby granted, free of charge, to any p"
},
{
"path": "DbSetup-kotlin/src/test/kotlin/com/ninja_squad/dbsetup_kotlin/DbSetupBuilderTest.kt",
"chars": 5752,
"preview": "package com.ninja_squad.dbsetup_kotlin;\n\nimport com.ninja_squad.dbsetup.bind.BinderConfiguration\nimport com.ninja_squad."
},
{
"path": "DbSetup-kotlin/src/test/kotlin/com/ninja_squad/dbsetup_kotlin/InsertBuilderTest.kt",
"chars": 1038,
"preview": "package com.ninja_squad.dbsetup_kotlin\n\nimport com.ninja_squad.dbsetup.generator.ValueGenerators\nimport org.junit.Assert"
},
{
"path": "DbSetup-kotlin/src/test/kotlin/com/ninja_squad/dbsetup_kotlin/MockitoExtensions.kt",
"chars": 290,
"preview": "package com.ninja_squad.dbsetup_kotlin\n\nimport org.mockito.Mockito\nimport org.mockito.stubbing.OngoingStubbing\n\n/**\n * @"
},
{
"path": "README.md",
"chars": 4866,
"preview": "[](https://circleci.com/gh/Ninja-Squad/DbSetup)\n\n#"
},
{
"path": "build.gradle.kts",
"chars": 466,
"preview": "import java.time.Duration\n\nplugins {\n id(\"io.github.gradle-nexus.publish-plugin\") version \"1.0.0\"\n}\n\ngroup = \"com.nin"
},
{
"path": "buildSrc/build.gradle.kts",
"chars": 92,
"preview": "plugins {\n `kotlin-dsl`\n}\n\nrepositories {\n mavenCentral()\n gradlePluginPortal()\n}\n\n"
},
{
"path": "buildSrc/settings.grade.kts",
"chars": 0,
"preview": ""
},
{
"path": "buildSrc/src/main/kotlin/java-library-convention.gradle.kts",
"chars": 2825,
"preview": "import org.gradle.api.tasks.testing.logging.TestExceptionFormat\n\nplugins {\n `java-library`\n signing\n `maven-pub"
},
{
"path": "gradle/wrapper/gradle-wrapper.properties",
"chars": 232,
"preview": "#Sun Feb 07 17:02:40 CET 2021\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_"
},
{
"path": "gradle.properties",
"chars": 16,
"preview": "version = 2.1.1\n"
},
{
"path": "gradlew",
"chars": 5046,
"preview": "#!/usr/bin/env bash\n\n##############################################################################\n##\n## Gradle start "
},
{
"path": "gradlew.bat",
"chars": 2404,
"preview": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@r"
},
{
"path": "settings.gradle.kts",
"chars": 121,
"preview": "rootProject.name = \"DbSetupParent\"\n\ninclude(\"DbSetup-core\", \"DbSetup-kotlin\")\n\nproject(\":DbSetup-core\").name = \"DbSetup\""
}
]
// ... and 1 more files (download for full content)
About this extraction
This page contains the full source code of the Ninja-Squad/DbSetup GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 67 files (287.8 KB), approximately 66.7k tokens, and a symbol index with 416 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.