v0.3.0-beta3
ldbc v0.3.0-beta3 is released.
This release adds enhancements to existing features.
Note
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.
The major version will be the stable version.
Functional modification: support for connector switching
The Scala MySQL connector has added new support for switching connections between JDBC and ldbc.
The modification allows developers to flexibly select database connections using the JDBC or ldbc libraries, depending on the requirements of the project. This allows them to utilise the functionality of the different libraries and increases flexibility in setting up and operating the connection.
How to switch
First, set up common dependencies.
libraryDependencies += "io.github.takapi327" %% "ldbc-dsl" % "0.3.0-beta3"
For Cross-Platform projects (JVM, JS, and/or Native):
libraryDependencies += "io.github.takapi327" %%% "ldbc-dsl" % "0.3.0-beta3"
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-beta3"
Use ldbc connector
libraryDependencies += "io.github.takapi327" %% "ldbc-connector" % "0.3.0-beta3"
For Cross-Platform projects (JVM, JS, and/or Native)
libraryDependencies += "io.github.takapi327" %%% "ldbc-connector" % "0.3.0-beta3"
Usage
The difference in usage is that there are differences in the way connections are built between jdbc and ldbc.
Caution
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(13306)
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 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.
case class User(
id: Long,
name: String,
age: Option[Int],
)
val table = 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
)
The next step is to build a TableQuery using the schema you have created.
import ldbc.query.builder.TableQuery
val userQuery = TableQuery[IO, User](table)
Finally, you can use the query builder to create a query.
val result: IO[List[User]] = connection.use { conn =>
userQuery.selectAll.toList[User].readOnly(conn)
// "SELECT `id`, `name`, `age` FROM user"
}
Functional modification: extension of plain query construction.
A new feature has been added to the MySQL connector in Scala to treat static strings as query strings.
Our Scala-made MySQL connector has extended the plain query construction functionality to increase query flexibility. In particular, a new sc
function has been introduced that allows static strings to be used in string completion. This allows static strings to be incorporated directly as part of the query.
Examples of use and details of functions
Introducing the sc
function: sc
stands for static context, which can be used in string completion to safely incorporate static strings, such as table names, into queries.
Assembling the query
val table = sc("table_name")
sql"SELECT * FROM $table WHERE id = ${1L}"
In the above code, table_name is incorporated into the query as a static string using sc
and "SELECT * FROM table_name WHERE id = ?"
The SQL is generated in the form "SELECT * FROM table_name WHERE id = ?
In this way, the placeholder (?) corresponds to a dynamic parameter (in this case 1L).
This extension makes it easier to create more dynamic and secure queries. This new method is particularly useful when multiple table names or SQL fragments need to be combined dynamically from the programme.
Functional modification: provision of functions to support plain query construction.
The MySQL connector in Scala adds a new feature for building queries using dynamic values.
The enhancements allow developers to build SQL queries more flexibly and simplify the dynamic generation of SQL, especially when dealing with multiple values and conditions. Key new features include utility functions for efficiently building combinations of values
, in
, notIn
, and
, or
and conditional expressions.
Main new functions
values
function: allows multiple values to be incorporated into a VALUES expression, e.g. used for batch insertion.in
andnotIn
functions: generate IN and NOT IN clauses based on a specified list of values.and
andor
functions: combine multiple conditions with AND or OR to form logical conditional expressions.whereAnd
andwhereOr
functions: incorporate multiple conditions into a WHERE clause to enhance query filtering.
examples showing the use (of a word)
val ids = List(1, 2, 3) // Dynamically generated values
val query = sql"SELECT * FROM users WHERE" ++ in(sql"id", ids)
// SELECT * FROM users WHERE id IN (?, ?, ?)
With this retrofit, developers using the MySQL connector from Scala will be able to build programmatically complex queries easily and safely. This will improve the performance and maintainability of applications and allow for more diverse data manipulation.
What's Changed
🚀 Features
- Feature/2024 05 convenience method added for sql construction by @takapi327 in #214
- Feature/2024 05 create jdbc connector package by @takapi327 in #215
- Feature/2024 05 create query helper by @takapi327 in #220
- Feature/2024 06 create static parameter by @takapi327 in #223
💪 Enhancement
- Enhancement/2024 05 add large update by @takapi327 in #219
🪲 Bug Fixes
- Bug/2024 06 fix transaction by @takapi327 in #225
🔧 Refactoring
- Refactor/2024 05 OKPacket decode by @takapi327 in #216
- Refactor/2024 06 sql by @takapi327 in #222
📖 Documentation
- Update README/docs by @takapi327 in #218
⛓️ Dependency update
- Update munit-cats-effect from 2.0.0-RC1 to 2.0.0 by @scala-steward in #213
Full Changelog: v0.3.0-beta2...v0.3.0-beta3