Skip to content

Commit a4cfd7f

Browse files
authored
Merge pull request #13 from softinio/softinio-push-uykmmomoonyp
update dependencies and add cats-effect integration
2 parents 960b688 + c6f3b86 commit a4cfd7f

File tree

17 files changed

+943
-74
lines changed

17 files changed

+943
-74
lines changed

.github/workflows/ci.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
runs-on: ubuntu-latest
1212
strategy:
1313
matrix:
14-
scala-version: ["3.3.6", "3.7.0"]
14+
scala-version: ["3.3.6", "3.8.2"]
1515
steps:
1616
- uses: actions/checkout@v4
1717

@@ -21,7 +21,7 @@ jobs:
2121

2222
# Run nix checks
2323
- name: Run nix flake check
24-
if: matrix.scala-version == '3.7.0'
24+
if: matrix.scala-version == '3.8.2'
2525
run: |
2626
nix flake check
2727
@@ -44,15 +44,15 @@ jobs:
4444
4545
# Check code formatting
4646
- name: Check code formatting
47-
if: matrix.scala-version == '3.7.0'
47+
if: matrix.scala-version == '3.8.2'
4848
run: |
4949
nix develop --command mill mill.scalalib.scalafmt.ScalafmtModule/checkFormatAll __.sources
5050
5151
# Build documentation
5252
- name: Generate documentation
53-
if: matrix.scala-version == '3.7.0'
53+
if: matrix.scala-version == '3.8.2'
5454
run: |
55-
nix develop --command mill "duck4s[3.7.0].docJar"
55+
nix develop --command mill "duck4s[3.8.2].docJar"
5656
5757
# Upload test results
5858
- name: Upload test results

.github/workflows/docs.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ jobs:
4646
# Generate documentation
4747
- name: Generate documentation
4848
run: |
49-
nix develop --command mill 'duck4s[3.7.0].docJar'
49+
nix develop --command mill 'duck4s[3.8.2].docJar'
5050
5151
# Deploy to gh-pages branch
5252
- name: Deploy to GitHub Pages
@@ -57,7 +57,7 @@ jobs:
5757
5858
# Create temporary directory
5959
TEMP_DIR=$(mktemp -d)
60-
cp -r out/duck4s/3.7.0/docJar.dest/javadoc/* "$TEMP_DIR/"
60+
cp -r out/duck4s/3.8.2/docJar.dest/javadoc/* "$TEMP_DIR/"
6161
6262
# Check if gh-pages branch exists
6363
if git ls-remote --heads origin gh-pages | grep -q gh-pages; then

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@
55
/.metals/
66
/out/
77
mill.*
8+
.mcp.json

.mill-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.12.14
1+
1.1.2

CLAUDE.md

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,18 @@ This is a Scala 3 project using Mill build tool (version 0.12.14).
1414

1515
### Common Commands
1616

17-
This project supports multiple Scala versions: **3.3.6** and **3.7.0**
17+
This project supports multiple Scala versions: **3.3.6** and **3.8.2**
1818

1919
#### Cross-Version Commands
2020
- **Build for all Scala versions**: `mill __.compile`
21-
- **Build for specific Scala version**: `mill 'duck4s[3.3.6].compile'` or `mill 'duck4s[3.7.0].compile'`
21+
- **Build for specific Scala version**: `mill 'duck4s[3.3.6].compile'` or `mill 'duck4s[3.8.2].compile'`
2222
- **Run tests for all Scala versions**: `mill __.test`
23-
- **Run tests for specific Scala version**: `mill 'duck4s[3.3.6].test'` or `mill 'duck4s[3.7.0].test'`
24-
- **Run specific test**: `mill 'duck4s[3.7.0].test' com.softinio.duck4s.MySuite`
23+
- **Run tests for specific Scala version**: `mill 'duck4s[3.3.6].test'` or `mill 'duck4s[3.8.2].test'`
24+
- **Run specific test**: `mill 'duck4s[3.8.2].test' com.softinio.duck4s.MySuite`
2525

2626
#### Documentation Commands
27-
- **Generate API documentation with static site**: `mill 'duck4s[3.7.0].docJar'`
28-
- **Generated site location**: `out/duck4s/3.7.0/docJar.dest/javadoc/index.html`
27+
- **Generate API documentation with static site**: `mill 'duck4s[3.8.2].docJar'`
28+
- **Generated site location**: `out/duck4s/3.8.2/docJar.dest/javadoc/index.html`
2929

3030
#### Development Commands
3131
- **Format code**: `mill mill.scalalib.scalafmt.ScalafmtModule/reformatAll __.sources`
@@ -34,8 +34,8 @@ This project supports multiple Scala versions: **3.3.6** and **3.7.0**
3434

3535
#### Publishing Commands
3636
- **Publish locally for all Scala versions**: `mill __.publishLocal`
37-
- **Publish locally for specific Scala version**: `mill 'duck4s[3.3.6].publishLocal'` or `mill 'duck4s[3.7.0].publishLocal'`
38-
- **Published artifacts location**: `~/.ivy2/local/com.softinio/duck4s_3.3.6/` and `~/.ivy2/local/com.softinio/duck4s_3.7.0/`
37+
- **Publish locally for specific Scala version**: `mill 'duck4s[3.3.6].publishLocal'` or `mill 'duck4s[3.8.2].publishLocal'`
38+
- **Published artifacts location**: `~/.ivy2/local/com.softinio/duck4s_3.3.6/` and `~/.ivy2/local/com.softinio/duck4s_3.8.2/`
3939

4040
### Development Environment
4141
The project uses Nix flake for reproducible development environments. To enter the dev shell:
@@ -55,13 +55,18 @@ This is a Scala 3 wrapper library for DuckDB with the following structure:
5555
- `PreparedStatement.scala` - Prepared statement wrapper
5656
- `ResultSet.scala` - Result set wrapper
5757
- **Tests**: `duck4s/test/src/` - Tests using MUnit framework
58+
- **Cats-effect module**: `duck4s-cats-effect/src/` - Optional cats-effect / fs2 integration
59+
- `DuckDBIO.scala` - `DuckDBIO` object (`connect`, `stream`) and `IO`-based extension methods on `DuckDBConnection` (`executeQueryIO`, `executeUpdateIO`, `withPreparedStatementIO`, `withBatchIO`, `withTransactionIO`)
60+
- `DuckDBException.scala` - `Throwable` wrapper for `DuckDBError` used to raise errors into `IO`
61+
- **Cats-effect tests**: `duck4s-cats-effect/test/src/` - Integration tests using `munit-cats-effect`
5862
- **Build definition**: `build.mill` - Mill build configuration defining the project as a ScalaModule
5963

6064
The project uses:
61-
- **Scala 3.3.6 and 3.7.0** with modern syntax features (optional braces, colon syntax)
62-
- **MUnit 1.1.1** for testing
65+
- **Scala 3.3.6 and 3.8.2** with modern syntax features (optional braces, colon syntax)
66+
- **MUnit 1.2.2** for testing (plus **munit-cats-effect 2.1.0** for the cats-effect module)
6367
- **Scalafmt 3.9.7** configured for Scala 3 dialect
64-
- **DuckDB JDBC Driver 1.1.3** for database connectivity
68+
- **DuckDB JDBC Driver 1.4.4.0** for database connectivity
69+
- **cats-effect 3.6.3** and **fs2 3.11.0** for the `duck4s-cats-effect` integration module
6570
- **Scala 3 Scaladoc** for comprehensive API documentation generation with:
6671
- Snippet compiler for validating code examples
6772
- External mappings for Scala and Java standard library documentation
@@ -82,6 +87,7 @@ The project includes comprehensive scaladoc documentation with a static website:
8287
- **_docs/**: Markdown content files
8388
- `index.md` - Main homepage with logo
8489
- `getting-started.md` - Getting started guide
90+
- `cats-effect.md` - Cats-effect integration guide
8591
- **_assets/**: Static assets
8692
- **images/**: Logo and other images
8793
- `duck4s_logo.jpeg` - Project logo
@@ -96,7 +102,7 @@ The project includes comprehensive scaladoc documentation with a static website:
96102
- **Examples**: Practical usage examples throughout the API
97103
- **Static site integration**: Homepage, getting started guide, and direct links to API docs
98104

99-
Generate the complete documentation website with `mill 'duck4s[3.7.0].docJar'`.
105+
Generate the complete documentation website with `mill 'duck4s[3.8.2].docJar'`.
100106

101107
## Publishing and Release Process
102108

@@ -167,5 +173,5 @@ This is useful for:
167173
- Mill builds are defined in `build.mill` using Scala syntax
168174
- The `.scalafmt.conf` is configured to use modern Scala 3 syntax features
169175
- All public APIs include comprehensive scaladoc documentation for generated documentation websites
170-
- The build includes conditional scalac options (e.g., `-Xkind-projector:underscores` for Scala 3.7)
176+
- The build includes conditional scalac options (e.g., `-Xkind-projector:underscores` for Scala 3.8)
171177
- Documentation links use the `[[algebra.TypeName]]` format for cross-references to types in the algebra package

README.md

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ Duck4s makes working with DuckDB in Scala applications a pleasant experience by:
2525
- 📊 **Modern Scala 3** - Utilizes Scala 3 features like extension methods, given instances, and braceless syntax
2626
- 🔄 **Batch Operations** - Efficient type-safe batch processing with type classes
2727
- 💼 **Transaction Support** - First-class transaction management with automatic rollback
28-
- 📱 **LTS and Latest Scala Version Support** - Supports Scala 3.3.6 (LTS) and 3.7.0
28+
- 🐱 **Cats-Effect Integration** - Optional `duck4s-cats-effect` module with `Resource`-based connection management, `IO`-wrapped operations, and `fs2.Stream` result set streaming
29+
- 📱 **LTS and Latest Scala Version Support** - Supports Scala 3.3.6 (LTS) and 3.8.2
2930

3031
## Getting Started
3132

@@ -36,22 +37,33 @@ Duck4s makes working with DuckDB in Scala applications a pleasant experience by:
3637
Add duck4s to your `build.sbt`:
3738

3839
```scala
40+
// Core library
3941
libraryDependencies += "com.softinio" %% "duck4s" % "0.1.1"
42+
43+
// Optional: cats-effect integration (includes fs2)
44+
libraryDependencies += "com.softinio" %% "duck4s-cats-effect" % "0.1.1"
4045
```
4146

4247
#### Mill
4348

4449
Add duck4s to your `build.mill`:
4550

4651
```scala
52+
// Core library
4753
def ivyDeps = Agg(
4854
ivy"com.softinio::duck4s::0.1.1"
4955
)
56+
57+
// Optional: cats-effect integration (includes fs2)
58+
def ivyDeps = Agg(
59+
ivy"com.softinio::duck4s::0.1.1",
60+
ivy"com.softinio::duck4s-cats-effect::0.1.1"
61+
)
5062
```
5163

5264
### Prerequisites
5365

54-
- Scala 3.3.6 or 3.7.0
66+
- Scala 3.3.6 or 3.8.2
5567
- Java 17 or higher
5668
- Mill build tool (or use the provided Nix development environment)
5769

@@ -67,13 +79,13 @@ nix develop
6779
mill __.compile
6880

6981
# Build for specific Scala version
70-
mill 'duck4s[3.7.0].compile'
82+
mill 'duck4s[3.8.2].compile'
7183

7284
# Run tests
7385
mill __.test
7486

7587
# Generate documentation
76-
mill 'duck4s[3.7.0].docJar'
88+
mill 'duck4s[3.8.2].docJar'
7789

7890
# Format code
7991
mill mill.scalalib.scalafmt.ScalafmtModule/reformatAll __.sources
@@ -119,6 +131,7 @@ result match
119131
## Documentation
120132

121133
- [Getting Started Guide](https://softinio.github.io/duck4s/docs/getting-started.html) - Learn the basics of duck4s
134+
- [Cats-Effect Integration](https://softinio.github.io/duck4s/docs/cats-effect.html) - Effectful IO and streaming with cats-effect and fs2
122135
- [API Documentation](https://softinio.github.io/duck4s/) - Complete API reference
123136

124137
## Contributing

build.mill

Lines changed: 84 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
//| mvnDeps:
2+
//| - com.goyeau::mill-git::0.3.2
3+
14
/*
25
* Copyright 2025 Salar Rahmanian
36
*
@@ -14,58 +17,60 @@
1417
* limitations under the License.
1518
*/
1619

17-
import mill._
18-
import mill.scalalib.api.ZincWorkerUtil
19-
import mill.scalalib._
20-
import publish._
21-
22-
import $ivy.`de.tototec::de.tobiasroeser.mill.vcs.version::0.4.1`
23-
import de.tobiasroeser.mill.vcs.version.VcsVersion
20+
import mill.*
21+
import mill.scalalib.*
22+
import mill.scalalib.publish.*
23+
import com.goyeau.mill.git.GitVersionedPublishModule
2424

25-
val duckdbVersion = "1.1.3"
26-
val munitVersion = "1.1.1"
27-
val scalaVersions = Seq("3.3.6", "3.7.0")
25+
val duckdbVersion = "1.4.4.0"
26+
val munitV = "1.2.2"
27+
val catsEffectVersion = "3.6.3"
28+
val fs2Version = "3.11.0"
29+
val munitCEVersion = "2.1.0"
30+
val scalaVersions = Seq("3.3.6", "3.8.2")
2831

2932
object duck4s extends Cross[Duck4sModule](scalaVersions)
3033

31-
trait Duck4sModule extends ScalaModule with CrossScalaModule with PublishModule {
32-
override def publishVersion: T[String] = VcsVersion.vcsState().format()
33-
34+
trait Duck4sModule
35+
extends ScalaModule
36+
with CrossScalaModule
37+
with GitVersionedPublishModule:
3438
def artifactName = "duck4s"
3539

36-
override def artifactScalaVersion: T[String] = T {
37-
ZincWorkerUtil.scalaBinaryVersion(crossScalaVersion)
40+
override def artifactScalaVersion: T[String] = Task {
41+
val v = crossScalaVersion
42+
if v.startsWith("3.") then "3"
43+
else v.split('.').take(2).mkString(".")
3844
}
3945

40-
def ivyDeps = Agg(
41-
ivy"org.duckdb:duckdb_jdbc:$duckdbVersion"
46+
def mvnDeps = Seq(
47+
mvn"org.duckdb:duckdb_jdbc:$duckdbVersion"
4248
)
4349

4450
// Enforce Java 17 as minimum version
4551
def javacOptions = Seq("-source", "17", "-target", "17")
4652

4753
// Scaladoc configuration for documentation website generation
48-
def scalacOptions = {
54+
def scalacOptions =
4955
val common = Seq("-explain", "-explain-types", "-release", "17")
50-
if (crossScalaVersion.startsWith("3.7")) {
56+
if crossScalaVersion.startsWith("3.8") then
5157
common :+ "-Xkind-projector:underscores"
52-
} else {
53-
common
54-
}
55-
}
58+
else common
5659

57-
def scalaDocOptions = T {
58-
val version = T.env.get("DUCK4S_DOC_VERSION").getOrElse(publishVersion())
60+
def scalaDocOptions = Task {
61+
val version = Task.env.get("DUCK4S_DOC_VERSION").getOrElse(publishVersion())
5962
super.scalaDocOptions() ++ Seq(
60-
"-project", "Duck4s",
61-
"-project-version", version,
63+
"-project",
64+
"Duck4s",
65+
"-project-version",
66+
version,
6267
"-social-links:github::https://github.com/softinio/duck4s",
6368
"-groups",
6469
"-snippet-compiler:compile",
65-
"-external-mappings:" +
66-
".*scala.*::scaladoc3::https://scala-lang.org/api/3.x/," +
67-
".*java.*::javadoc::https://docs.oracle.com/en/java/javase/17/docs/api/"
68-
)
70+
"-external-mappings:" +
71+
".*scala.*::scaladoc3::https://scala-lang.org/api/3.x/," +
72+
".*java.*::javadoc::https://docs.oracle.com/en/java/javase/17/docs/api/"
73+
)
6974
}
7075

7176
def pomSettings = PomSettings(
@@ -83,9 +88,53 @@ trait Duck4sModule extends ScalaModule with CrossScalaModule with PublishModule
8388
)
8489
)
8590

86-
object test extends ScalaTests with TestModule.Munit {
87-
def ivyDeps = Agg(
88-
ivy"org.scalameta::munit::$munitVersion"
91+
object test extends ScalaTests with TestModule.Munit:
92+
def mvnDeps = Seq(
93+
mvn"org.scalameta::munit::$munitV"
8994
)
95+
96+
object `duck4s-cats-effect` extends Cross[Duck4sCatsEffectModule](scalaVersions)
97+
98+
trait Duck4sCatsEffectModule
99+
extends ScalaModule
100+
with CrossScalaModule
101+
with GitVersionedPublishModule:
102+
def artifactName = "duck4s-cats-effect"
103+
104+
def moduleDeps = Seq(duck4s(crossScalaVersion))
105+
106+
override def artifactScalaVersion: T[String] = Task {
107+
val v = crossScalaVersion
108+
if v.startsWith("3.") then "3"
109+
else v.split('.').take(2).mkString(".")
90110
}
91-
}
111+
112+
def mvnDeps = Seq(
113+
mvn"org.typelevel::cats-effect:$catsEffectVersion",
114+
mvn"co.fs2::fs2-core:$fs2Version"
115+
)
116+
117+
def javacOptions = Seq("-source", "17", "-target", "17")
118+
119+
def scalacOptions =
120+
val common = Seq("-explain", "-explain-types", "-release", "17")
121+
if crossScalaVersion.startsWith("3.8") then
122+
common :+ "-Xkind-projector:underscores"
123+
else common
124+
125+
def pomSettings = PomSettings(
126+
description = "Scala 3 cats-effect integration for duck4s DuckDB library",
127+
organization = "com.softinio",
128+
url = "https://www.duck4s.com",
129+
licenses = Seq(License.`Apache-2.0`),
130+
versionControl = VersionControl.github("softinio", "duck4s"),
131+
developers = Seq(
132+
Developer("softinio", "Salar Rahmanian", "https://www.softinio.com")
133+
)
134+
)
135+
136+
object test extends ScalaTests with TestModule.Munit:
137+
def mvnDeps = Seq(
138+
mvn"org.scalameta::munit::$munitV",
139+
mvn"org.typelevel::munit-cats-effect::$munitCEVersion"
140+
)

0 commit comments

Comments
 (0)