Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refacor/2024 06 parameter redesign #227

Merged
merged 19 commits into from
Jun 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ The next step is to build a TableQuery using the schema you have created.
```scala
import ldbc.query.builder.TableQuery

val userQuery = TableQuery[IO, User](table)
val userQuery = TableQuery[User](table)
```

Finally, you can use the query builder to create a query.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class CompileCreateQuery:
|val table = Table[Model$size](\"model$size\")(
| $columns
|)
|val tableQuery = TableQuery[IO, Model$size](table)
|val tableQuery = TableQuery[Model$size](table)
|
|val query = tableQuery.select(v => (${ (1 to size).map(i => s"v.c$i").mkString(", ") }))
| .limit(5000)
Expand Down
4 changes: 2 additions & 2 deletions benchmark/src/main/scala/benchmark/ldbc/Insert.scala
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class Insert:
var noLog: LogHandler[IO] = uninitialized

@volatile
var query: TableQuery[IO, Test] = uninitialized
var query: TableQuery[Test] = uninitialized

@volatile
var records: List[(Int, String)] = List.empty
Expand All @@ -54,7 +54,7 @@ class Insert:

noLog = _ => IO.unit

query = TableQuery[IO, Test](Test.table)
query = TableQuery[Test](Test.table)

@Param(Array("10", "100", "1000", "2000", "4000"))
var len: Int = uninitialized
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ import java.util.concurrent.TimeUnit

import org.openjdk.jmh.annotations.*

import cats.effect.IO

import ldbc.core.*
import ldbc.query.builder.TableQuery

Expand All @@ -29,7 +27,7 @@ class RuntimeCreateQuery:
val table = Table[Model1]("model1")(
column("c1", INT)
)
TableQuery[IO, Model1](table).select(_.c1)
TableQuery[Model1](table).select(_.c1)

@Benchmark
def createM5 =
Expand All @@ -40,7 +38,7 @@ class RuntimeCreateQuery:
column("c4", INT),
column("c5", INT)
)
TableQuery[IO, Model5](table).select(v => (v.c1, v.c2, v.c3, v.c4, v.c5))
TableQuery[Model5](table).select(v => (v.c1, v.c2, v.c3, v.c4, v.c5))

@Benchmark
def createM10 =
Expand All @@ -56,7 +54,7 @@ class RuntimeCreateQuery:
column("c9", INT),
column("c10", INT)
)
TableQuery[IO, Model10](table).select(v => (v.c1, v.c2, v.c3, v.c4, v.c5, v.c6, v.c7, v.c8, v.c9, v.c10))
TableQuery[Model10](table).select(v => (v.c1, v.c2, v.c3, v.c4, v.c5, v.c6, v.c7, v.c8, v.c9, v.c10))

@Benchmark
def createM20 =
Expand All @@ -82,7 +80,7 @@ class RuntimeCreateQuery:
column("c19", INT),
column("c20", INT)
)
TableQuery[IO, Model20](table).select(v =>
TableQuery[Model20](table).select(v =>
(
v.c1,
v.c2,
Expand Down Expand Up @@ -136,7 +134,7 @@ class RuntimeCreateQuery:
column("c24", INT),
column("c25", INT)
)
TableQuery[IO, Model25](table).select(v =>
TableQuery[Model25](table).select(v =>
(
v.c1,
v.c2,
Expand Down
4 changes: 2 additions & 2 deletions benchmark/src/main/scala/benchmark/ldbc/Select.scala
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class Select:
var noLog: LogHandler[IO] = uninitialized

@volatile
var query: TableQuery[IO, City] = uninitialized
var query: TableQuery[City] = uninitialized

@Setup
def setup(): Unit =
Expand All @@ -51,7 +51,7 @@ class Select:

noLog = _ => IO.unit

query = TableQuery[IO, City](City.table)
query = TableQuery[City](City.table)

@Param(Array("10", "100", "1000", "2000", "4000"))
var len: Int = uninitialized
Expand Down
8 changes: 4 additions & 4 deletions docs/src/main/mdoc/en/03-Type-safe-Query-Builder.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ val table = Table[User]("user")(
column("age", INT.UNSIGNED.DEFAULT(None)),
)

val userQuery = TableQuery[IO, User](table)
val userQuery = TableQuery[User](table)
```

## SELECT
Expand Down Expand Up @@ -199,9 +199,9 @@ object CountryLanguage:
column("language", CHAR(30))
)

val countryQuery = TableQuery[IO, Country](Country.table)
val cityQuery = TableQuery[IO, City](City.table)
val countryLanguageQuery = TableQuery[IO, CountryLanguage](CountryLanguage.table)
val countryQuery = TableQuery[Country](Country.table)
val cityQuery = TableQuery[City](City.table)
val countryLanguageQuery = TableQuery[CountryLanguage](CountryLanguage.table)
```

If you want to do a simple Join first, use `join`.
Expand Down
2 changes: 1 addition & 1 deletion docs/src/main/mdoc/en/04-Database-Connection.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ val table = Table[User]("user")(
column("age", INT.UNSIGNED.DEFAULT(None)),
)

val userQuery = TableQuery[IO, User](table)
val userQuery = TableQuery[User](table)
```

## Using DataSource
Expand Down
2 changes: 1 addition & 1 deletion docs/src/main/mdoc/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ The next step is to build a TableQuery using the schema you have created.
```scala
import ldbc.query.builder.TableQuery

val userQuery = TableQuery[IO, User](table)
val userQuery = TableQuery[User](table)
```

Finally, you can use the query builder to create a query.
Expand Down
8 changes: 4 additions & 4 deletions docs/src/main/mdoc/ja/03-Type-safe-Query-Builder.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ val table = Table[User]("user")(
column("age", INT.UNSIGNED.DEFAULT(None)),
)

val userQuery = TableQuery[IO, User](table)
val userQuery = TableQuery[User](table)
```

## SELECT
Expand Down Expand Up @@ -199,9 +199,9 @@ object CountryLanguage:
column("language", CHAR(30))
)

val countryQuery = TableQuery[IO, Country](Country.table)
val cityQuery = TableQuery[IO, City](City.table)
val countryLanguageQuery = TableQuery[IO, CountryLanguage](CountryLanguage.table)
val countryQuery = TableQuery[Country](Country.table)
val cityQuery = TableQuery[City](City.table)
val countryLanguageQuery = TableQuery[CountryLanguage](CountryLanguage.table)
```

まずシンプルなJoinを行いたい場合は、`join`を使用します。
Expand Down
2 changes: 1 addition & 1 deletion docs/src/main/mdoc/ja/04-Database-Connection.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ val table = Table[User]("user")(
column("age", INT.UNSIGNED.DEFAULT(None)),
)

val userQuery = TableQuery[IO, User](table)
val userQuery = TableQuery[User](table)
```

## DataSourceの使用
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ trait ConnectionProvider[F[_]: Sync]:

private def connection[T](
statement: String,
params: Seq[ParameterBinder[F]],
params: Seq[Parameter.DynamicBinder],
consumer: ResultSetConsumer[F, T]
)(using logHandler: LogHandler[F]): Kleisli[F, Connection[F], T] =
Kleisli { connection =>
Expand Down Expand Up @@ -54,7 +54,7 @@ trait ConnectionProvider[F[_]: Sync]:
*/
protected def connectionToList[T](
statement: String,
params: Seq[ParameterBinder[F]]
params: Seq[Parameter.DynamicBinder]
)(using Kleisli[F, ResultSet[F], T], LogHandler[F], FactoryCompat[T, List[T]]): Kleisli[F, Connection[F], List[T]] =
connection[List[T]](statement, params, summon[ResultSetConsumer[F, List[T]]])

Expand All @@ -64,7 +64,7 @@ trait ConnectionProvider[F[_]: Sync]:
*/
protected def connectionToHeadOption[T](
statement: String,
params: Seq[ParameterBinder[F]]
params: Seq[Parameter.DynamicBinder]
)(using Kleisli[F, ResultSet[F], T], LogHandler[F]): Kleisli[F, Connection[F], Option[T]] =
connection[Option[T]](statement, params, summon[ResultSetConsumer[F, Option[T]]])

Expand All @@ -74,6 +74,6 @@ trait ConnectionProvider[F[_]: Sync]:
*/
protected def connectionToUnsafe[T](
statement: String,
params: Seq[ParameterBinder[F]]
params: Seq[Parameter.DynamicBinder]
)(using Kleisli[F, ResultSet[F], T], LogHandler[F]): Kleisli[F, Connection[F], T] =
connection[T](statement, params, summon[ResultSetConsumer[F, T]])
2 changes: 1 addition & 1 deletion module/ldbc-dsl/src/main/scala/ldbc/dsl/Executor.scala
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ object Executor:

private[ldbc] case class Impl[F[_]: Temporal, T](
statement: String,
params: List[ParameterBinder[F]],
params: List[Parameter.DynamicBinder],
run: Connection[F] => F[T]
) extends Executor[F, T]:

Expand Down
8 changes: 4 additions & 4 deletions module/ldbc-dsl/src/main/scala/ldbc/dsl/Mysql.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import ldbc.sql.*
* @tparam F
* The effect type
*/
case class Mysql[F[_]: Temporal](statement: String, params: List[ParameterBinder[F]]) extends SQL[F]:
case class Mysql[F[_]: Temporal](statement: String, params: List[Parameter.DynamicBinder]) extends SQL[F]:

@targetName("combine")
override def ++(sql: SQL[F]): SQL[F] =
Expand All @@ -40,7 +40,7 @@ case class Mysql[F[_]: Temporal](statement: String, params: List[ParameterBinder
for
prepareStatement <- connection.prepareStatement(statement)
resultSet <- params.zipWithIndex.traverse {
case (param, index) => param.bind(prepareStatement, index + 1)
case (param, index) => param.bind[F](prepareStatement, index + 1)
} >> prepareStatement.executeQuery()
result <- consumer.consume(resultSet) <* prepareStatement.close()
yield result
Expand All @@ -54,7 +54,7 @@ case class Mysql[F[_]: Temporal](statement: String, params: List[ParameterBinder
for
prepareStatement <- connection.prepareStatement(statement)
result <- params.zipWithIndex.traverse {
case (param, index) => param.bind(prepareStatement, index + 1)
case (param, index) => param.bind[F](prepareStatement, index + 1)
} >> prepareStatement.executeUpdate() <* prepareStatement.close()
yield result
)
Expand All @@ -69,7 +69,7 @@ case class Mysql[F[_]: Temporal](statement: String, params: List[ParameterBinder
for
prepareStatement <- connection.prepareStatement(statement, Statement.RETURN_GENERATED_KEYS)
resultSet <- params.zipWithIndex.traverse {
case (param, index) => param.bind(prepareStatement, index + 1)
case (param, index) => param.bind[F](prepareStatement, index + 1)
} >> prepareStatement.executeUpdate() >> prepareStatement.getGeneratedKeys()
result <- summon[ResultSetConsumer[F, T]].consume(resultSet) <* prepareStatement.close()
yield result
Expand Down
2 changes: 1 addition & 1 deletion module/ldbc-dsl/src/main/scala/ldbc/dsl/SQL.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ trait SQL[F[_]: Monad]:
/**
* statement has '?' that the statement has.
*/
def params: List[ParameterBinder[F]]
def params: List[Parameter.DynamicBinder]

@targetName("combine")
def ++(sql: SQL[F]): SQL[F]
Expand Down
22 changes: 9 additions & 13 deletions module/ldbc-dsl/src/main/scala/ldbc/dsl/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import cats.syntax.all.*

import cats.effect.*

import ldbc.sql.{ PreparedStatement, Parameter, ParameterBinder }
import ldbc.sql.Parameter

import ldbc.dsl.syntax.*

Expand All @@ -24,10 +24,6 @@ package object dsl:
QuerySyntax[F],
CommandSyntax[F]:

private case class StaticImpl(value: String) extends ParameterBinder.Static[F]:
override def bind(statement: PreparedStatement[F], index: Int): F[Unit] = Sync[F].unit
override def toString: String = value

/**
* Function for setting parameters to be used as static strings.
* {{{
Expand All @@ -36,39 +32,39 @@ package object dsl:
* // SELECT * FROM table WHERE id = ?
* }}}
*/
def sc(value: String): ParameterBinder.Static[F] = StaticImpl(value)
def sc(value: String): Parameter.StaticBinder = Parameter.StaticBinder(value)

// The following helper functions for building SQL models are rewritten from doobie fragments for ldbc SQL models.
// see: https://github.com/tpolecat/doobie/blob/main/modules/core/src/main/scala/doobie/util/fragments.scala

/** Returns `VALUES (v0), (v1), ...`. */
def values[M[_]: Reducible, T](vs: M[T])(using Parameter[F, T]): SQL[F] =
def values[M[_]: Reducible, T](vs: M[T])(using Parameter[T]): SQL[F] =
sql"VALUES" ++ comma(vs.toNonEmptyList.map(v => parentheses(p"$v")))

/** Returns `VALUES (s0, s1, ...)`. */
def values[M[_]: Reducible](vs: M[SQL[F]]): SQL[F] =
sql"VALUES" ++ parentheses(comma(vs.toNonEmptyList))

/** Returns `(sql IN (v0, v1, ...))`. */
def in[T](s: SQL[F], v0: T, v1: T, vs: T*)(using Parameter[F, T]): SQL[F] =
def in[T](s: SQL[F], v0: T, v1: T, vs: T*)(using Parameter[T]): SQL[F] =
in(s, NonEmptyList(v0, v1 :: vs.toList))

/** Returns `(sql IN (s0, s1, ...))`. */
def in[M[_]: Reducible: Functor, T](s: SQL[F], vs: M[T])(using Parameter[F, T]): SQL[F] =
def in[M[_]: Reducible: Functor, T](s: SQL[F], vs: M[T])(using Parameter[T]): SQL[F] =
parentheses(s ++ sql" IN " ++ parentheses(comma(vs.map(v => p"$v"))))

def inOpt[M[_]: Foldable, T](s: SQL[F], vs: M[T])(using Parameter[F, T]): Option[SQL[F]] =
def inOpt[M[_]: Foldable, T](s: SQL[F], vs: M[T])(using Parameter[T]): Option[SQL[F]] =
NonEmptyList.fromFoldable(vs).map(nel => in(s, nel))

/** Returns `(sql NOT IN (v0, v1, ...))`. */
def notIn[T](s: SQL[F], v0: T, v1: T, vs: T*)(using Parameter[F, T]): SQL[F] =
def notIn[T](s: SQL[F], v0: T, v1: T, vs: T*)(using Parameter[T]): SQL[F] =
notIn(s, NonEmptyList(v0, v1 :: vs.toList))

/** Returns `(sql NOT IN (v0, v1, ...))`, or `true` for empty `fs`. */
def notIn[M[_]: Reducible: Functor, T](s: SQL[F], vs: M[T])(using Parameter[F, T]): SQL[F] =
def notIn[M[_]: Reducible: Functor, T](s: SQL[F], vs: M[T])(using Parameter[T]): SQL[F] =
parentheses(s ++ sql" NOT IN " ++ parentheses(comma(vs.map(v => p"$v"))))

def notInOpt[M[_]: Foldable, T](s: SQL[F], vs: M[T])(using Parameter[F, T]): Option[SQL[F]] =
def notInOpt[M[_]: Foldable, T](s: SQL[F], vs: M[T])(using Parameter[T]): Option[SQL[F]] =
NonEmptyList.fromFoldable(vs).map(nel => notIn(s, nel))

/** Returns `(s1 AND s2 AND ... sn)` for a non-empty collection. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import ldbc.dsl.logging.*

trait CommandSyntax[F[_]: Sync]:

extension (command: Command[F])
extension (command: Command)
def update(using logHandler: LogHandler[F]): Kleisli[F, Connection[F], Int] = Kleisli { connection =>
(for
statement <- connection.prepareStatement(command.statement)
Expand All @@ -35,7 +35,7 @@ trait CommandSyntax[F[_]: Sync]:
<* logHandler.run(LogEvent.Success(command.statement, command.params.map(_.parameter).toList))
}

implicit class InsertOps[P <: Product](insert: Insert[F, P]):
implicit class InsertOps[P <: Product](insert: Insert[P]):
def update(using logHandler: LogHandler[F]): Kleisli[F, Connection[F], Int] = Kleisli { connection =>
(for
statement <- connection.prepareStatement(insert.statement)
Expand Down
Loading