Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
2059034
fix(database): Attach tear-down failures as suppressed, not primary
jeffjensen Jul 23, 2026
e11a798
test(ant): Rewrite obsolete queryset id/refid BuildException test
jeffjensen Jul 23, 2026
d871763
test(operation,database): Delete two dead commented-out test fragments
jeffjensen Jul 23, 2026
9d4b1e9
test(postgresql): Stop swallowing failures in xtest*-prefixed methods
jeffjensen Jul 23, 2026
332f545
docs(changes): Finalize 3.3.1-SNAPSHOT release summary description
jeffjensen Jul 23, 2026
5cb4ce4
feat(database): Add CachingConnectionProvider for cross-test connecti…
jeffjensen Jul 23, 2026
f91a8bf
perf(database): Reduce connection churn in DefaultPrepAndExpectedTest…
jeffjensen Jul 23, 2026
3be43ec
build(pom): Set version to 3.4.0-SNAPSHOT
jeffjensen Jul 23, 2026
7a54fb1
fix(dataset): Use Locale.ENGLISH for expected-column name matching
jeffjensen Jul 23, 2026
e68f3dd
refactor(database): Harmonize null-databaseTester handling on Illegal…
jeffjensen Jul 23, 2026
82b9673
fix(dataset): Pin identifier case folding to Locale.ENGLISH
jeffjensen Jul 24, 2026
0366f0b
fix(dataset): Skip NO_VALUE cells in FlatXmlWriter and YamlWriter
jeffjensen Jul 24, 2026
bb299c7
fix(log): Log at info level in SQLHelper.logInfoIfValueChanged
jeffjensen Jul 24, 2026
d810fe0
fix(dataset): Close input streams and read in chunks in BytesDataType
jeffjensen Jul 24, 2026
4b0d8e2
fix(dataset): Fail fast on invalid [text]/[base64] values in BytesDat…
jeffjensen Jul 24, 2026
72a824d
fix(util): Escape single-character schema segments in QualifiedTableName
jeffjensen Jul 24, 2026
bc6d10a
fix(ant): Dispatch CSV exports case-insensitively and validate format…
jeffjensen Jul 25, 2026
197f65c
fix(database): Attach shadowed verify failure as suppressed in postTest
jeffjensen Jul 25, 2026
f1be34a
fix(operation): Regenerate insert statement when a defaulted NOT NULL…
jeffjensen Jul 25, 2026
4e1e318
fix(dataset): Emit well-formed XML for supplementary and control char…
jeffjensen Jul 25, 2026
aa6cfaa
fix(dataset): Use floor semantics for pre-epoch timestamps in timezon…
jeffjensen Jul 25, 2026
05be724
fix(operation): Roll back on Error in TransactionOperation
jeffjensen Jul 25, 2026
95795f0
fix(dataset): Handle empty sheets and missing rows in XlsTable
jeffjensen Jul 25, 2026
3527e8e
fix(dataset): Write YAML and DTD exports in UTF-8 to match their readers
jeffjensen Jul 25, 2026
1c8b87b
build(pom): Enable japicmp 3.3.0-to-snapshot report for 3.4.0-SNAPSHOT
jeffjensen Jul 25, 2026
ee918ff
perf(database): Skip redundant table-existence query in DatabaseDataS…
jeffjensen Jul 25, 2026
4b6e503
perf(log): Guard per-cell debug logging in the datatype package
jeffjensen Jul 25, 2026
c475f79
fix(dataset): Make StreamingIterator's async exception visible across…
jeffjensen Jul 25, 2026
c9e512b
fix(dataset): Stop duplicating the continuation line on short CSV parses
jeffjensen Jul 25, 2026
b3b5009
refactor(database): Use getFeature for the qualified-table-names check
jeffjensen Jul 25, 2026
b0b842f
fix(util): Close channels safely in FileHelper.copyFile
jeffjensen Jul 25, 2026
745a3bd
perf(database): Keep the configureTest connection open for the test l…
jeffjensen Jul 25, 2026
855db1a
refactor(operation): Remove dead field and harden close path in Refre…
jeffjensen Jul 25, 2026
6442dc4
refactor(log): Route Base64 diagnostics through slf4j
jeffjensen Jul 25, 2026
fba74ab
refactor(dataset): Remove dead encoding-name mapping in XmlWriter
jeffjensen Jul 25, 2026
0603a36
fix(dataset): Parse CSV table names from the final .csv suffix
jeffjensen Jul 25, 2026
9f20426
build(pom): Remove unused duplicate dependency-version properties
jeffjensen Jul 25, 2026
ff17c3a
fix(log): Reindent SQLHelper.logDebugIfValueChanged's closing braces
jeffjensen Jul 27, 2026
0fc3b73
test: Centralize Turkish-locale test setup in a shared JUnit 5 extension
jeffjensen Jul 27, 2026
b7be25f
fix(ant): Include csv in Export.setFormat's unsupported-format message
jeffjensen Jul 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ Integration tests use `DatabaseEnvironment` to bootstrap the target database fro
- Adhere strictly to de facto standard Git commit message formatting.
- Use Conventional Commits format.
- **Commit Types:** `feat:`, `fix:`, `docs:`, `refactor:`, `test:`, `build:`, `ci:`, `perf:`
- **Scopes:** any of the database names, `assertion`, `pom`, `log`, `docker`, `database`, `dataset`, `metadata`, `resultset`, `scripts`, `site`, `statement`, `search`
- **Scopes:** any of the database names, `assertion`, `pom`, `log`, `docker`, `database`, `dataset`, `metadata`, `resultset`, `scripts`, `site`, `statement`, `search`, `util`, `ant`, `operation`
- Capitalize the first word after the type and scope.
- You may suggest additional CC commit types and scopes when encountering situations where the changes do not fit into the approved lists above.
- Reference GitHub issues in the commit footer with `Refs: <issue-number>` (e.g. `Refs: 123`). Do not use a # before the number.
Expand Down
7 changes: 1 addition & 6 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<groupId>org.dbunit</groupId>
<artifactId>dbunit</artifactId>
<version>3.3.1-SNAPSHOT</version>
<version>3.4.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>dbUnit Extension</name>
<url>https://github.com/dbunit/dbunit-extension</url>
Expand Down Expand Up @@ -47,8 +47,6 @@
<logbackClassicVersion>1.5.38</logbackClassicVersion>
<mockitoVersion>5.23.0</mockitoVersion>
<poiVersion>5.2.5</poiVersion>
<slf4jVersion>1.7.25</slf4jVersion>
<snakeYamlVersion>2.2</snakeYamlVersion>
<xmlparserv2Version>23.26.2.0.0</xmlparserv2Version>

<!-- Database driver versions -->
Expand Down Expand Up @@ -1039,8 +1037,6 @@
</parameter>
</configuration>
<reportSets>
<!--
enable when new snapshot version set
<reportSet>
<id>3.3.0-to-snapshot</id>
<reports>
Expand All @@ -1065,7 +1061,6 @@ enable when new snapshot version set
</newVersion>
</configuration>
</reportSet>
-->
<reportSet>
<id>3.2.0-to-3.3.0</id>
<reports>
Expand Down
119 changes: 118 additions & 1 deletion src/changes/changes.xml

Large diffs are not rendered by default.

46 changes: 37 additions & 9 deletions src/main/java/org/dbunit/DataSourceDatabaseTester.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

import javax.sql.DataSource;

import org.dbunit.database.CachingConnectionProvider;
import org.dbunit.database.DatabaseConnection;
import org.dbunit.database.IDatabaseConnection;

Expand All @@ -45,6 +46,7 @@ public class DataSourceDatabaseTester extends AbstractDatabaseTester
*/
private static final Logger logger = LoggerFactory.getLogger(DataSourceDatabaseTester.class);

private final CachingConnectionProvider connectionProvider;
private DataSource dataSource;

/**
Expand All @@ -54,13 +56,7 @@ public class DataSourceDatabaseTester extends AbstractDatabaseTester
*/
public DataSourceDatabaseTester( DataSource dataSource )
{
super();

if (dataSource == null) {
throw new NullPointerException(
"The parameter 'dataSource' must not be null");
}
this.dataSource = dataSource;
this(dataSource, null, null);
}

/**
Expand All @@ -69,22 +65,54 @@ public DataSourceDatabaseTester( DataSource dataSource )
* @param schema The schema name to be used for new dbunit connections
* @since 2.4.5
*/
public DataSourceDatabaseTester(DataSource dataSource, String schema)
public DataSourceDatabaseTester(DataSource dataSource, String schema)
{
this(dataSource, schema, null);
}

/**
* Creates a new DataSourceDatabaseTester with the specified DataSource and schema name,
* reusing one {@link IDatabaseConnection} across calls via the given
* {@link CachingConnectionProvider} instead of creating a new one on every call.<br>
* Share the same <code>connectionProvider</code> instance across the testers created for
* each test to get reuse across test methods; pair it with
* {@link IOperationListener#NO_OP_OPERATION_LISTENER} (or an equivalent non-closing
* listener) so the cached connection is not closed after every {@link #onSetup()}/
* {@link #onTearDown()} call.
*
* @param dataSource the DataSource to pull connections from
* @param schema The schema name to be used for new dbunit connections - can be <code>null</code>
* @param connectionProvider caches and validates the connection across calls - can be
* <code>null</code>, in which case a new connection is created on every call as before
* @since 3.4.0
*/
public DataSourceDatabaseTester(DataSource dataSource, String schema,
CachingConnectionProvider connectionProvider)
{
super(schema);

if (dataSource == null) {
throw new NullPointerException(
"The parameter 'dataSource' must not be null");
}
this.dataSource = dataSource;
this.connectionProvider = connectionProvider;
}

public IDatabaseConnection getConnection() throws Exception
{
logger.debug("getConnection() - start");

assertTrue( "DataSource is not set", dataSource!=null );
if (connectionProvider != null)
{
return connectionProvider.getConnection(this::createConnection);
}
return createConnection();
}

private IDatabaseConnection createConnection() throws Exception
{
return new DatabaseConnection( dataSource.getConnection(), getSchema() );
}
}
57 changes: 51 additions & 6 deletions src/main/java/org/dbunit/DatabaseTestCase.java
Original file line number Diff line number Diff line change
Expand Up @@ -159,17 +159,62 @@ protected void tearDown() throws Exception
logger.debug("tearDown() - start");

try {
final IDatabaseTester databaseTester = getDatabaseTester();
assertNotNull(databaseTester, "DatabaseTester is not set");
databaseTester.setTearDownOperation(getTearDownOperation());
databaseTester.setDataSet(getDataSet());
databaseTester.setOperationListener(getOperationListener());
databaseTester.onTearDown();
runTearDownOperation();
} finally {
tester = null;
}
}

/**
* Runs tear down the same as {@link #tearDown()}, for use when a test
* failure is already in flight (e.g. calling this from a catch/finally
* around the test body). A tear-down failure never replaces the given
* testFailure; it is instead attached via {@link Throwable#addSuppressed}
* so the original failure remains the one reported, with the tear-down
* failure still visible alongside it.
*
* @param testFailure
* The throwable already in flight from the test body, or
* <code>null</code> if there is none, in which case this
* behaves the same as {@link #tearDown()}.
* @throws Throwable
* testFailure, if not <code>null</code>; otherwise a
* tear-down failure, if one occurred.
* @since 3.4.0
*/
protected void tearDown(final Throwable testFailure) throws Throwable
{
logger.debug("tearDown(testFailure={}) - start", testFailure);

if (testFailure == null)
{
tearDown();
return;
}

try {
try {
runTearDownOperation();
} finally {
tester = null;
}
} catch (final Throwable tearDownFailure) {
testFailure.addSuppressed(tearDownFailure);
}

throw testFailure;
}

private void runTearDownOperation() throws Exception
{
final IDatabaseTester databaseTester = getDatabaseTester();
assertNotNull(databaseTester, "DatabaseTester is not set");
databaseTester.setTearDownOperation(getTearDownOperation());
databaseTester.setDataSet(getDataSet());
databaseTester.setOperationListener(getOperationListener());
databaseTester.onTearDown();
}

/**
* @return The {@link IOperationListener} to be used by the {@link IDatabaseTester}.
* @since 2.4.4
Expand Down
78 changes: 65 additions & 13 deletions src/main/java/org/dbunit/DefaultDatabaseTester.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
*/
package org.dbunit;

import java.util.concurrent.Callable;

import org.dbunit.database.CachingConnectionProvider;
import org.dbunit.database.IDatabaseConnection;

/**
Expand All @@ -30,20 +33,69 @@
* @version $Revision$
* @since 2.2
*/
public class DefaultDatabaseTester extends AbstractDatabaseTester
{
private final IDatabaseConnection connection;
private final CachingConnectionProvider connectionProvider;
private final Callable<IDatabaseConnection> connectionFactory;

public class DefaultDatabaseTester extends AbstractDatabaseTester {

final IDatabaseConnection connection;

/**
* Creates a new DefaultDatabaseTester with the supplied connection.
*/
public DefaultDatabaseTester( final IDatabaseConnection connection ) {
this.connection = connection;
}
/**
* Creates a new DefaultDatabaseTester with the supplied connection.<br>
* The same connection instance is returned by every {@link #getConnection()}
* call, with no liveness check. Pair this with a non-closing
* {@link IOperationListener} (e.g. {@link IOperationListener#NO_OP_OPERATION_LISTENER})
* to keep it open across test methods.
*
* @param connection the connection to return from every {@link #getConnection()} call
*/
public DefaultDatabaseTester(final IDatabaseConnection connection)
{
this.connection = connection;
this.connectionProvider = null;
this.connectionFactory = null;
}

public IDatabaseConnection getConnection() throws Exception {
return this.connection;
}
/**
* Creates a new DefaultDatabaseTester that reuses one connection - created
* with the given factory - across calls via the given
* {@link CachingConnectionProvider}, transparently replacing it if it is no
* longer alive.<br>
* Share the same <code>connectionProvider</code> instance across the testers
* created for each test to get reuse across test methods; pair it with
* {@link IOperationListener#NO_OP_OPERATION_LISTENER} (or an equivalent
* non-closing listener) so the cached connection is not closed after every
* {@link #onSetup()}/{@link #onTearDown()} call.
*
* @param connectionProvider caches and validates the connection across calls
* @param connectionFactory creates a new connection; only invoked by
* <code>connectionProvider</code> when there is no live cached
* connection to reuse
* @since 3.4.0
*/
public DefaultDatabaseTester(final CachingConnectionProvider connectionProvider,
final Callable<IDatabaseConnection> connectionFactory)
{
if (connectionProvider == null)
{
throw new NullPointerException(
"The parameter 'connectionProvider' must not be null");
}
if (connectionFactory == null)
{
throw new NullPointerException(
"The parameter 'connectionFactory' must not be null");
}
this.connection = null;
this.connectionProvider = connectionProvider;
this.connectionFactory = connectionFactory;
}

public IDatabaseConnection getConnection() throws Exception
{
if (connectionProvider != null)
{
return connectionProvider.getConnection(connectionFactory);
}
return this.connection;
}
}
Loading
Loading