Skip to content

Commit

Permalink
Merge pull request #348 from takapi327/enhancement/2024-12-Make-Encod…
Browse files Browse the repository at this point in the history
…er-and-Decoder-compatible-with-Twiddles

Enhancement/2024 12 make encoder and decoder compatible with twiddles
  • Loading branch information
takapi327 authored Dec 31, 2024
2 parents 81a1c62 + 9e3d768 commit 485a6aa
Show file tree
Hide file tree
Showing 23 changed files with 246 additions and 402 deletions.
35 changes: 35 additions & 0 deletions benchmark/src/main/scala/benchmark/Model.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

package benchmark

import ldbc.dsl.codec.*
import ldbc.query.builder.Table
import ldbc.query.builder.formatter.Naming

Expand All @@ -15,6 +16,10 @@ case class Model1(
c1: Int
) derives Table

object Model1:
given Encoder[Model1] = Encoder[Int].to[Model1]
given Decoder[Model1] = Decoder[Int].to[Model1]

case class Model5(
c1: Int,
c2: Int,
Expand Down Expand Up @@ -59,6 +64,20 @@ case class Model20(
c20: Int
) derives Table

object Model20:
given Encoder[Model20] = (
Encoder[Int] *: Encoder[Int] *: Encoder[Int] *: Encoder[Int] *: Encoder[Int] *:
Encoder[Int] *: Encoder[Int] *: Encoder[Int] *: Encoder[Int] *: Encoder[Int] *:
Encoder[Int] *: Encoder[Int] *: Encoder[Int] *: Encoder[Int] *: Encoder[Int] *:
Encoder[Int] *: Encoder[Int] *: Encoder[Int] *: Encoder[Int] *: Encoder[Int]
).to[Model20]
given Decoder[Model20] = (
Decoder[Int] *: Decoder[Int] *: Decoder[Int] *: Decoder[Int] *: Decoder[Int] *:
Decoder[Int] *: Decoder[Int] *: Decoder[Int] *: Decoder[Int] *: Decoder[Int] *:
Decoder[Int] *: Decoder[Int] *: Decoder[Int] *: Decoder[Int] *: Decoder[Int] *:
Decoder[Int] *: Decoder[Int] *: Decoder[Int] *: Decoder[Int] *: Decoder[Int]
).to[Model20]

case class Model25(
c1: Int,
c2: Int,
Expand Down Expand Up @@ -87,6 +106,22 @@ case class Model25(
c25: Int
) derives Table

object Model25:
given Encoder[Model25] = (
Encoder[Int] *: Encoder[Int] *: Encoder[Int] *: Encoder[Int] *: Encoder[Int] *:
Encoder[Int] *: Encoder[Int] *: Encoder[Int] *: Encoder[Int] *: Encoder[Int] *:
Encoder[Int] *: Encoder[Int] *: Encoder[Int] *: Encoder[Int] *: Encoder[Int] *:
Encoder[Int] *: Encoder[Int] *: Encoder[Int] *: Encoder[Int] *: Encoder[Int] *:
Encoder[Int] *: Encoder[Int] *: Encoder[Int] *: Encoder[Int] *: Encoder[Int]
).to[Model25]
given Decoder[Model25] = (
Decoder[Int] *: Decoder[Int] *: Decoder[Int] *: Decoder[Int] *: Decoder[Int] *:
Decoder[Int] *: Decoder[Int] *: Decoder[Int] *: Decoder[Int] *: Decoder[Int] *:
Decoder[Int] *: Decoder[Int] *: Decoder[Int] *: Decoder[Int] *: Decoder[Int] *:
Decoder[Int] *: Decoder[Int] *: Decoder[Int] *: Decoder[Int] *: Decoder[Int] *:
Decoder[Int] *: Decoder[Int] *: Decoder[Int] *: Decoder[Int] *: Decoder[Int]
).to[Model25]

case class City(
id: Int,
name: String,
Expand Down
7 changes: 4 additions & 3 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ lazy val dsl = crossProject(JVMPlatform, JSPlatform, NativePlatform)
.module("dsl", "Projects that provide a way to connect to the database")
.settings(
libraryDependencies ++= Seq(
"org.typelevel" %%% "twiddles-core" % "0.8.0",
"org.typelevel" %%% "cats-effect" % "3.5.7",
"org.typelevel" %%% "munit-cats-effect" % "2.0.0" % Test
)
Expand All @@ -83,8 +84,7 @@ lazy val statement = crossProject(JVMPlatform, JSPlatform, NativePlatform)
.module("statement", "Project for building type-safe statements")
.settings(
libraryDependencies ++= Seq(
"org.typelevel" %%% "twiddles-core" % "0.8.0",
"org.scalatest" %%% "scalatest" % "3.2.18" % Test
"org.scalatest" %%% "scalatest" % "3.2.18" % Test
)
)
.dependsOn(dsl)
Expand Down Expand Up @@ -201,7 +201,8 @@ lazy val tests = crossProject(JVMPlatform)
.settings(
name := "tests",
description := "Projects for testing",
Test / fork := true
Test / fork := true,
scalacOptions += "-Ximplicit-search-limit:100000"
)
.defaultSettings
.settings(
Expand Down
2 changes: 1 addition & 1 deletion docs/src/main/scala/05-Program.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import ldbc.dsl.codec.*
val program1: DBIO[Int] =
sql"INSERT INTO user (name, email, status) VALUES (${ "user 1" }, ${ "[email protected]" }, ${ Status.Active })".update

given Decoder.Elem[Status] = Decoder.Elem.mapping[Boolean, Status] {
given Decoder[Status] = Decoder[Boolean].map {
case true => Status.Active
case false => Status.InActive
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,7 @@ private[ldbc] object TableModelGenerator:
Some(s"""enum $enumName extends model.Enum:
| case ${ types.mkString(", ") }
| object $enumName extends model.EnumDataType[$enumName]:
| given ldbc.dsl.codec.Decoder.Elem[$enumName] = new ldbc.dsl.codec.Decoder.Elem[$enumName]:
| override def decode(resultSet: ldbc.sql.ResultSet, columnLabel: String): $enumName = $enumName.fromOrdinal(resultSet.getInt(columnLabel))
| override def decode(resultSet: ldbc.sql.ResultSet, index: Int): $enumName = $enumName.fromOrdinal(resultSet.getInt(index))
| given ldbc.dsl.codec.Decoder[$enumName] = ldbc.dsl.codec.Decoder[Int].map($enumName.fromOrdinal)
| given ldbc.dsl.codec.Encoder[$enumName] = ldbc.dsl.codec.Encoder[Int].contramap(_.ordinal)
|""".stripMargin)
case _ => None
25 changes: 3 additions & 22 deletions module/ldbc-dsl/src/main/scala/ldbc/dsl/Mysql.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
package ldbc.dsl

import scala.annotation.targetName
import scala.deriving.Mirror
import scala.compiletime.erasedValue

import cats.syntax.all.*

Expand Down Expand Up @@ -44,23 +42,8 @@ case class Mysql[F[_]: Temporal](statement: String, params: List[Parameter.Dynam
* @return
* A [[ldbc.dsl.Query]] instance
*/
inline def query[T](using decoder: Decoder.Elem[T]): Query[F, T] =
Query.Impl[F, T](statement, params, Decoder.one[T])

/**
* A method to convert a query to a [[ldbc.dsl.Query]].
*
* {{{
* sql"SELECT `name`, `age` FROM user".query[User]
* }}}
*
* @return
* A [[ldbc.dsl.Query]] instance
*/
inline def query[P <: Product](using mirror: Mirror.ProductOf[P]): Query[F, P] =
inline erasedValue[P] match
case _: Tuple => Query.Impl[F, P](statement, params, Decoder.derivedTuple(mirror))
case _ => Query.Impl[F, P](statement, params, Decoder.derivedProduct(mirror))
def query[T](using decoder: Decoder[T]): Query[F, T] =
Query.Impl[F, T](statement, params, decoder)

/**
* A method to execute an update operation against the MySQL server.
Expand Down Expand Up @@ -95,9 +78,7 @@ case class Mysql[F[_]: Temporal](statement: String, params: List[Parameter.Dynam
* @return
* The primary key value
*/
def returning[T <: String | Int | Long](using decoder: Decoder.Elem[T]): DBIO[F, T] =
given Decoder[T] = Decoder.one[T]

def returning[T <: String | Int | Long](using Decoder[T]): DBIO[F, T] =
DBIO.Impl[F, T](
statement,
params,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,13 @@ object ResultSetConsumer:

given [F[_]: Monad, T](using decoder: Decoder[T]): ResultSetConsumer[F, Option[T]] with
override def consume(resultSet: ResultSet): F[Option[T]] =
if resultSet.next() then Monad[F].pure(decoder.decode(resultSet, None).some) else Monad[F].pure(None)
if resultSet.next() then Monad[F].pure(decoder.decode(resultSet, 1).some) else Monad[F].pure(None)

given [F[_]: Monad, T, G[_]](using
decoder: Decoder[T],
factoryCompat: FactoryCompat[T, G[T]]
): ResultSetConsumer[F, G[T]] with
override def consume(resultSet: ResultSet): F[G[T]] =
val builder = factoryCompat.newBuilder
while resultSet.next() do builder += decoder.decode(resultSet, None)
while resultSet.next() do builder += decoder.decode(resultSet, 1)
Monad[F].pure(builder.result())
Loading

0 comments on commit 485a6aa

Please sign in to comment.