ldbc (Lepus Database Connectivity)
========================================================================================
ldbc (Lepus Database Connectivity) is Pure functional JDBC layer with Cats Effect 3 and Scala 3.
ldbc is a Typelevel project. This means we embrace pure, typeful, functional programming, and provide a safe and friendly environment for teaching, learning, and contributing as described in the Scala Code of Conduct.
Note that ldbc is pre-1.0 software and is still undergoing active development. New versions are not binary compatible with prior versions, although in most cases user code will be source compatible.
Modules availability
ldbc is available on the JVM, Scala.js, and ScalaNative
Module / Platform | JVM | Scala Native | Scala.js |
---|---|---|---|
ldbc-core |
✅ | ✅ | ✅ |
ldbc-sql |
✅ | ✅ | ✅ |
ldbc-connector |
✅ | ✅ | ✅ |
jdbc-connector |
✅ | ❌ | ❌ |
ldbc-dsl |
✅ | ✅ | ✅ |
ldbc-query-builder |
✅ | ✅ | ✅ |
ldbc-schema |
✅ | ✅ | ✅ |
ldbc-schemaSpy |
✅ | ❌ | ❌ |
ldbc-codegen |
✅ | ✅ | ✅ |
ldbc-hikari |
✅ | ❌ | ❌ |
ldbc-plugin |
✅ | ❌ | ❌ |
Quick Start
For people that want to skip the explanations and see it action, this is the place to start!
Dependency Configuration
libraryDependencies += "io.github.takapi327" %% "ldbc-dsl" % "0.3.0-beta8"
For Cross-Platform projects (JVM, JS, and/or Native):
libraryDependencies += "io.github.takapi327" %%% "ldbc-dsl" % "0.3.0-beta8"
The dependency package used depends on whether the database connection is made via a connector using the Java API or a connector provided by ldbc.
Use jdbc connector
libraryDependencies += "io.github.takapi327" %% "jdbc-connector" % "0.3.0-beta8"
Use ldbc connector
libraryDependencies += "io.github.takapi327" %% "ldbc-connector" % "0.3.0-beta8"
For Cross-Platform projects (JVM, JS, and/or Native)
libraryDependencies += "io.github.takapi327" %%% "ldbc-connector" % "0.3.0-beta8"
Usage
The difference in usage is that there are differences in the way connections are built between jdbc and ldbc.
ldbc is currently under active development. Please note that current functionality may therefore be deprecated or changed in the future.
jdbc connector
val ds = new com.mysql.cj.jdbc.MysqlDataSource()
ds.setServerName("127.0.0.1")
ds.setPortNumber(3306)
ds.setDatabaseName("world")
ds.setUser("ldbc")
ds.setPassword("password")
val datasource = jdbc.connector.MysqlDataSource[IO](ds)
val connection: Resource[IO, Connection[IO]] =
Resource.make(datasource.getConnection)(_.close())
ldbc connector
val connection: Resource[IO, Connection[IO]] =
ldbc.connector.Connection[IO](
host = "127.0.0.1",
port = 3306,
user = "ldbc",
password = Some("password"),
database = Some("ldbc"),
ssl = SSL.Trusted
)
The connection process to the database can be carried out using the connections established by each of these methods.
val result: IO[(List[Int], Option[Int], Int)] = connection.use { conn =>
(for
result1 <- sql"SELECT 1".toList[Int]
result2 <- sql"SELECT 2".headOption[Int]
result3 <- sql"SELECT 3".unsafe[Int]
yield (result1, result2, result3)).readOnly(conn)
}
Using the query builder
ldbc provides not only plain queries but also type-safe database connections using the query builder.
The first step is to set up dependencies.
libraryDependencies += "io.github.takapi327" %% "ldbc-query-builder" % "${version}"
For Cross-Platform projects (JVM, JS, and/or Native):
libraryDependencies += "io.github.takapi327" %%% "ldbc-query-builder" % "${version}"
ldbc uses classes to construct queries.
import ldbc.query.builder.Table
case class User(
id: Long,
name: String,
age: Option[Int],
) derives Table
The next step is to create a Table using the classes you have created.
import ldbc.query.builder.Table
val userTable = Table[User]
Finally, you can use the query builder to create a query.
val result: IO[List[User]] = connection.use { conn =>
userTable.selectAll.query.to[List].readOnly(conn)
// "SELECT `id`, `name`, `age` FROM user"
}
Using the schema
ldbc also allows type-safe construction of schema information for tables.
The first step is to set up dependencies.
libraryDependencies += "io.github.takapi327" %% "ldbc-schema" % "0.3.0-beta8"
For Cross-Platform projects (JVM, JS, and/or Native):
libraryDependencies += "io.github.takapi327" %%% "ldbc-schema" % "0.3.0-beta8"
The next step is to create a schema for use by the query builder.
ldbc maintains a one-to-one mapping between Scala models and database table definitions. The mapping between the properties held by the model and the columns held by the table is done in definition order. Table definitions are very similar to the structure of Create statements. This makes the construction of table definitions intuitive for the user.
import ldbc.schema.*
case class User(
id: Long,
name: String,
age: Option[Int],
)
val userTable = Table[User]("user")( // CREATE TABLE `user` (
column("id", BIGINT, AUTO_INCREMENT, PRIMARY_KEY), // `id` BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
column("name", VARCHAR(255)), // `name` VARCHAR(255) NOT NULL,
column("age", INT.UNSIGNED.DEFAULT(None)), // `age` INT unsigned DEFAULT NULL
) // )
Finally, you can use the query builder to create a query.
val result: IO[List[User]] = connection.use { conn =>
userTable.selectAll.query.to[List].readOnly(conn)
// "SELECT `id`, `name`, `age` FROM user"
}
Documentation
Full documentation can be found at Currently available in English and Japanese.
Contributing
All suggestions welcome :)!
If you’d like to contribute, see the list of issues and pick one! Or report your own. If you have an idea you’d like to discuss, that’s always a good option.
If you have any questions about why or how it works, feel free to ask on github. This probably means that the documentation, scaladocs, and code are unclear and can be improved for the benefit of all.
Testing locally
If you want to build and run the tests for yourself, you'll need a local MySQL database. The easiest way to do this is to run docker-compose up
from the project root.