Skip to content

Commit 630b42f

Browse files
oyvindbergclaude
andauthored
Improve connection API and test infrastructure (#181)
* Add ConnectionSource interface and unify pooled/non-pooled data sources - Add ConnectionSource interface unifying pooled and non-pooled connection sources - Add SimpleDataSource for non-pooled connections (wraps DriverManager) - Add ConnectionSettings for connection behavior (isolation, autoCommit, readOnly, etc.) - Move connection settings from PoolConfig to ConnectionSettings - Add transactor() shortcuts to DatabaseConfig for common use cases - Update PooledDataSource to implement ConnectionSource - Remove config::connect from Transactor (use ConnectionSource instead) This provides a clean, unified API: - config.transactor() for quick non-pooled access - config.transactor(settings, strategy) for customized non-pooled - HikariDataSourceFactory.create(config, settings, pool).transactor() for pooled 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Bump PostgreSQL version from 14 to 16 in deploy-docs workflow 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Add test-utils with file locking for parallel snapshot tests When tests run in parallel across multiple JVMs, git operations can conflict. This adds proper file-based locking to ensure exclusive access to git add. - Add test-utils project with SnapshotTestUtils (Java) - withGitLock() uses FileChannel.lock() for cross-JVM file locking - Update all SnapshotTest files to use shared utility - Update WithConnection files to use new Transactor API - Add .snapshot-test.lock to .gitignore 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Update tester withConnection files to use new Transactor API Migrate from `new Transactor(config, strategy)` to `config.transactor(strategy)` for all database testers. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Parallelize type tests for faster execution Use parallel streams and unique table names per test case to enable concurrent execution across PgTypeTest, MariaTypeTest, DuckDbTypeTest, OracleTypeTest, SqlServerTypeTest, and Db2TypeTest. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Fix remaining Kotlin and Java test helpers to use new Transactor API - Update DuckDB Kotlin to use DriverManager.getConnection - Update DB2 Java to use Transactor pattern - Update all Kotlin test helpers to use CONFIG.transactor() method 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 642837d commit 630b42f

46 files changed

Lines changed: 1214 additions & 1047 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/deploy-docs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jobs:
2323
runs-on: ubuntu-latest
2424
if: "!contains(github.event.head_commit.message, 'ci skip')"
2525
env:
26-
PG_MAJOR: 14
26+
PG_MAJOR: 16
2727
steps:
2828
- uses: actions/checkout@v4
2929
- uses: bleep-build/bleep-setup-action@0.0.1

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,5 @@ __pycache__/
2323
/testdb.wal
2424
db/duckdb/test.db
2525
db/duckdb/test.db.wal
26-
duckdb-test/
26+
duckdb-test/
27+
.snapshot-test.lock

bleep.yaml

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,11 @@ projects:
8787
options: -proc:none
8888
platform:
8989
name: jvm
90+
test-utils:
91+
java:
92+
options: -proc:none
93+
platform:
94+
name: jvm
9095
testers/db2/java:
9196
dependencies:
9297
- com.fasterxml.jackson.core:jackson-annotations:2.17.2
@@ -346,7 +351,9 @@ projects:
346351
- com.typesafe.play::play-json:2.10.6
347352
- org.postgresql:postgresql:42.7.3
348353
- org.scalatest::scalatest:3.2.18
349-
dependsOn: typr-dsl-anorm
354+
dependsOn:
355+
- typr-dsl-anorm
356+
- test-utils
350357
extends: template-cross
351358
isTestProject: true
352359
testers/pg/scala/doobie:
@@ -359,7 +366,9 @@ projects:
359366
- io.circe::circe-core:0.14.7
360367
- org.postgresql:postgresql:42.7.3
361368
- org.scalatest::scalatest:3.2.18
362-
dependsOn: typr-dsl-doobie
369+
dependsOn:
370+
- typr-dsl-doobie
371+
- test-utils
363372
extends: template-cross
364373
isTestProject: true
365374
sources: ./generated-and-checked-in
@@ -373,7 +382,9 @@ projects:
373382
- junit:junit:4.13.2
374383
- org.postgresql:postgresql:42.7.3
375384
- org.scalatest::scalatest:3.2.18
376-
dependsOn: foundations-jdbc-dsl
385+
dependsOn:
386+
- foundations-jdbc-dsl
387+
- test-utils
377388
extends: template-scala-3
378389
isTestProject: true
379390
sources: ./generated-and-checked-in
@@ -387,7 +398,9 @@ projects:
387398
- junit:junit:4.13.2
388399
- org.postgresql:postgresql:42.7.3
389400
- org.scalatest::scalatest:3.2.18
390-
dependsOn: foundations-jdbc-dsl-scala
401+
dependsOn:
402+
- foundations-jdbc-dsl-scala
403+
- test-utils
391404
extends: template-scala-3
392405
isTestProject: true
393406
sources: ./generated-and-checked-in
@@ -401,7 +414,9 @@ projects:
401414
- dev.zio::zio-json:0.7.0
402415
- org.postgresql:postgresql:42.7.3
403416
- org.scalatest::scalatest:3.2.18
404-
dependsOn: typr-dsl-zio-jdbc
417+
dependsOn:
418+
- typr-dsl-zio-jdbc
419+
- test-utils
405420
extends: template-cross
406421
isTestProject: true
407422
testers/sqlserver/java:

foundations-jdbc-hikari/src/java/dev/typr/foundations/hikari/HikariDataSourceFactory.java

Lines changed: 63 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2,55 +2,43 @@
22

33
import com.zaxxer.hikari.HikariConfig;
44
import com.zaxxer.hikari.HikariDataSource;
5+
import dev.typr.foundations.connect.ConnectionSettings;
56
import dev.typr.foundations.connect.DatabaseConfig;
67

78
/**
8-
* Factory for creating PooledDataSource instances from DatabaseConfig and PoolConfig.
9+
* Factory for creating PooledDataSource instances.
910
*
1011
* <p>Example usage:
1112
*
1213
* <pre>{@code
13-
* // Minimal - all defaults
14+
* // With connection settings
1415
* var ds = HikariDataSourceFactory.create(
15-
* PostgresConfig.builder("localhost", 5432, "mydb", "user", "pass").build());
16-
*
17-
* // Use the transactor
18-
* var tx = ds.transactor();
19-
* tx.execute(conn -> repo.selectAll(conn));
20-
*
21-
* // With pool configuration
22-
* var ds = HikariDataSourceFactory.create(
23-
* PostgresConfig.builder("localhost", 5432, "mydb", "user", "pass")
24-
* .sslmode(PgSslMode.REQUIRE)
16+
* PostgresConfig.builder("localhost", 5432, "mydb", "user", "pass").build(),
17+
* ConnectionSettings.builder()
18+
* .transactionIsolation(TransactionIsolation.READ_UNCOMMITTED)
2519
* .build(),
2620
* PoolConfig.builder()
2721
* .maximumPoolSize(20)
28-
* .connectionTimeout(Duration.ofSeconds(10))
2922
* .build());
23+
*
24+
* var tx = ds.transactor();
25+
* tx.execute(conn -> repo.selectAll(conn));
3026
* }</pre>
3127
*/
3228
public final class HikariDataSourceFactory {
3329

3430
private HikariDataSourceFactory() {}
3531

3632
/**
37-
* Create a PooledDataSource from DatabaseConfig with default pool settings.
38-
*
39-
* @param config database configuration
40-
* @return configured PooledDataSource with transactor() method
41-
*/
42-
public static PooledDataSource create(DatabaseConfig config) {
43-
return create(config, PoolConfig.defaults());
44-
}
45-
46-
/**
47-
* Create a PooledDataSource from DatabaseConfig and PoolConfig.
33+
* Create a PooledDataSource with connection settings and pool configuration.
4834
*
49-
* @param config database configuration
50-
* @param pool pool configuration
51-
* @return configured PooledDataSource with transactor() method
35+
* @param config database configuration (URL, credentials, driver properties)
36+
* @param settings connection settings (isolation, autoCommit, readOnly, etc.)
37+
* @param pool pool configuration (sizing, timeouts, etc.)
38+
* @return configured PooledDataSource
5239
*/
53-
public static PooledDataSource create(DatabaseConfig config, PoolConfig pool) {
40+
public static PooledDataSource create(
41+
DatabaseConfig config, ConnectionSettings settings, PoolConfig pool) {
5442
HikariConfig hikari = new HikariConfig();
5543

5644
// Connection settings from DatabaseConfig
@@ -73,25 +61,27 @@ public static PooledDataSource create(DatabaseConfig config, PoolConfig pool) {
7361
hikari.setKeepaliveTime(pool.keepaliveTime().toMillis());
7462
hikari.setLeakDetectionThreshold(pool.leakDetectionThreshold().toMillis());
7563

76-
// Connection defaults
77-
if (pool.transactionIsolation() != null) {
78-
hikari.setTransactionIsolation(pool.transactionIsolation().jdbcName());
64+
// Connection settings
65+
if (settings.transactionIsolation() != null) {
66+
hikari.setTransactionIsolation(settings.transactionIsolation().jdbcName());
7967
}
80-
if (pool.autoCommit() != null) {
81-
hikari.setAutoCommit(pool.autoCommit());
68+
if (settings.autoCommit() != null) {
69+
hikari.setAutoCommit(settings.autoCommit());
8270
}
83-
if (pool.readOnly() != null) {
84-
hikari.setReadOnly(pool.readOnly());
71+
if (settings.readOnly() != null) {
72+
hikari.setReadOnly(settings.readOnly());
8573
}
86-
if (pool.catalog() != null) {
87-
hikari.setCatalog(pool.catalog());
74+
if (settings.catalog() != null) {
75+
hikari.setCatalog(settings.catalog());
8876
}
89-
if (pool.schema() != null) {
90-
hikari.setSchema(pool.schema());
77+
if (settings.schema() != null) {
78+
hikari.setSchema(settings.schema());
9179
}
92-
if (pool.connectionInitSql() != null) {
93-
hikari.setConnectionInitSql(pool.connectionInitSql());
80+
if (settings.connectionInitSql() != null) {
81+
hikari.setConnectionInitSql(settings.connectionInitSql());
9482
}
83+
84+
// Pool-specific: connection test query
9585
if (pool.connectionTestQuery() != null) {
9686
hikari.setConnectionTestQuery(pool.connectionTestQuery());
9787
}
@@ -117,4 +107,36 @@ public static PooledDataSource create(DatabaseConfig config, PoolConfig pool) {
117107

118108
return new PooledDataSource(new HikariDataSource(hikari));
119109
}
110+
111+
/**
112+
* Create a PooledDataSource with connection settings and default pool configuration.
113+
*
114+
* @param config database configuration
115+
* @param settings connection settings
116+
* @return configured PooledDataSource
117+
*/
118+
public static PooledDataSource create(DatabaseConfig config, ConnectionSettings settings) {
119+
return create(config, settings, PoolConfig.defaults());
120+
}
121+
122+
/**
123+
* Create a PooledDataSource with default settings.
124+
*
125+
* @param config database configuration
126+
* @return configured PooledDataSource with driver defaults
127+
*/
128+
public static PooledDataSource create(DatabaseConfig config) {
129+
return create(config, ConnectionSettings.EMPTY, PoolConfig.defaults());
130+
}
131+
132+
/**
133+
* Create a PooledDataSource with pool configuration but default connection settings.
134+
*
135+
* @param config database configuration
136+
* @param pool pool configuration
137+
* @return configured PooledDataSource
138+
*/
139+
public static PooledDataSource create(DatabaseConfig config, PoolConfig pool) {
140+
return create(config, ConnectionSettings.EMPTY, pool);
141+
}
120142
}

0 commit comments

Comments
 (0)