diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 10493609c9..6946f8f96e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,7 +27,7 @@ jobs: fail-fast: false matrix: scala: [2.12.x, 2.13.x, 3.3.x] - module: [base, db, async, codegen, bigdata] + module: [base, db, codegen, bigdata] include: - scala: 2.12.x scala_short: 212 @@ -42,8 +42,6 @@ jobs: # For now, only do the `base` build for Scala 3 - scala: 3.3.x module: db - - scala: 3.3.x - module: async - scala: 3.3.x module: codegen - scala: 3.3.x diff --git a/build.sbt b/build.sbt index ac95b5b0d7..9f9a79c1e7 100644 --- a/build.sbt +++ b/build.sbt @@ -46,14 +46,6 @@ lazy val dbModules = Seq[sbt.ClasspathDep[sbt.ProjectReference]]( `quill-jdbc-zio` ) -lazy val jasyncModules = Seq[sbt.ClasspathDep[sbt.ProjectReference]]( - `quill-jasync`, - `quill-jasync-postgres`, - `quill-jasync-mysql`, - `quill-jasync-zio`, - `quill-jasync-zio-postgres` -) - lazy val codegenModules = Seq[sbt.ClasspathDep[sbt.ProjectReference]]( `quill-codegen`, `quill-codegen-jdbc`, @@ -70,10 +62,10 @@ lazy val bigdataModules = Seq[sbt.ClasspathDep[sbt.ProjectReference]]( ) lazy val allModules = - baseModules ++ dbModules ++ jasyncModules ++ codegenModules ++ bigdataModules ++ docsModules + baseModules ++ dbModules ++ codegenModules ++ bigdataModules ++ docsModules lazy val scala213Modules = - baseModules ++ dbModules ++ jasyncModules ++ codegenModules ++ bigdataModules + baseModules ++ dbModules ++ codegenModules ++ bigdataModules lazy val scala3Modules = Seq[sbt.ClasspathDep[sbt.ProjectReference]](`quill-engine`, `quill-util`) @@ -112,15 +104,12 @@ lazy val filteredModules = { case "db" => println("SBT =:> Compiling Database Modules") dbModules - case "async" => - println("SBT =:> Compiling Async Database Modules") - jasyncModules case "codegen" => println("SBT =:> Compiling Code Generator Modules") codegenModules case "nocodegen" => println("Compiling Not-Code Generator Modules") - baseModules ++ dbModules ++ jasyncModules ++ bigdataModules + baseModules ++ dbModules ++ bigdataModules case "bigdata" => println("SBT =:> Compiling Big Data Modules") bigdataModules @@ -421,71 +410,6 @@ lazy val `quill-spark` = .dependsOn(`quill-sql` % "compile->compile;test->test") .enablePlugins(MimaPlugin) -lazy val `quill-jasync` = - (project in file("quill-jasync")) - .settings(commonSettings: _*) - .settings( - Test / fork := true, - libraryDependencies ++= Seq( - "com.github.jasync-sql" % "jasync-common" % "2.2.4", - "org.scala-lang.modules" %% "scala-java8-compat" % "0.9.1" - ) - ) - .dependsOn(`quill-sql` % "compile->compile;test->test") - .enablePlugins(MimaPlugin) - -lazy val `quill-jasync-postgres` = - (project in file("quill-jasync-postgres")) - .settings(commonSettings: _*) - .settings( - Test / fork := true, - libraryDependencies ++= Seq( - "com.github.jasync-sql" % "jasync-postgresql" % "2.2.4" - ) - ) - .dependsOn(`quill-jasync` % "compile->compile;test->test") - .enablePlugins(MimaPlugin) - -lazy val `quill-jasync-mysql` = - (project in file("quill-jasync-mysql")) - .settings(commonSettings: _*) - .settings( - Test / fork := true, - libraryDependencies ++= Seq( - "com.github.jasync-sql" % "jasync-mysql" % "2.2.4" - ) - ) - .dependsOn(`quill-jasync` % "compile->compile;test->test") - .enablePlugins(MimaPlugin) - -lazy val `quill-jasync-zio` = - (project in file("quill-jasync-zio")) - .settings(commonSettings: _*) - .settings( - Test / fork := true, - libraryDependencies ++= Seq( - "com.github.jasync-sql" % "jasync-common" % "2.2.4", - "org.scala-lang.modules" %% "scala-java8-compat" % "0.9.1", - "dev.zio" %% "zio" % Version.zio, - "dev.zio" %% "zio-streams" % Version.zio - ) - ) - .dependsOn(`quill-zio` % "compile->compile;test->test") - .dependsOn(`quill-sql` % "compile->compile;test->test") - .enablePlugins(MimaPlugin) - -lazy val `quill-jasync-zio-postgres` = - (project in file("quill-jasync-zio-postgres")) - .settings(commonSettings: _*) - .settings( - Test / fork := true, - libraryDependencies ++= Seq( - "com.github.jasync-sql" % "jasync-postgresql" % "2.2.4" - ) - ) - .dependsOn(`quill-jasync-zio` % "compile->compile;test->test") - .enablePlugins(MimaPlugin) - lazy val `quill-cassandra` = (project in file("quill-cassandra")) .settings(commonSettings: _*) diff --git a/build/build.sh b/build/build.sh index 994c4b91da..1eea9caf50 100755 --- a/build/build.sh +++ b/build/build.sh @@ -177,13 +177,6 @@ function db_build() { ./build/aware_run.sh "sbt -Dmodules=db $SBT_ARGS test" } -function async_build() { - echo "build.sh =:> Async Build Specified" - wait_for_mysql_postgres - echo "build.sh =:> Starting Async Build Primary" - sbt -Dmodules=async $SBT_ARGS test -} - function codegen_build() { echo "build.sh =:> Codegen Build Specified" wait_for_databases @@ -236,9 +229,6 @@ elif [[ $modules == "js" ]]; then elif [[ $modules == "finagle" ]]; then echo "build.sh =:> Build Script: Doing Finagle Database Build" finagle_build -elif [[ $modules == "async" ]]; then - echo "build.sh =:> Build Script: Doing Async Database Build" - async_build elif [[ $modules == "codegen" ]]; then echo "build.sh =:> Build Script: Doing Code Generator Build" codegen_build diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index f4e868956a..2b5cdaf731 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -68,7 +68,7 @@ docker-compose run --rm sbt sbt "test-only io.getquill.context.sql.SqlQuerySpec" Run all tests in specific sub-project: ```bash -docker-compose run --rm sbt sbt "project quill-async" test +docker-compose run --rm sbt sbt "project quill-jdbc-zio" test ``` Run specific test in specific sub-project: diff --git a/docs/contexts.md b/docs/contexts.md index e31bf2d3f1..20af085421 100644 --- a/docs/contexts.md +++ b/docs/contexts.md @@ -1023,373 +1023,6 @@ ctx.dataSource.portNumber=1521 ctx.dataSource.serverName=host ``` -## NDBC Context - -Async support via [NDBC driver](https://ndbc.io/) is available with Postgres database. - -### quill-ndbc-postgres - -#### transactions - -Transaction support is provided out of the box by NDBC: - -```scala -ctx.transaction { - ctx.run(query[Person].delete) - // other transactional code -} -``` - -The body of transaction can contain calls to other methods and multiple run calls since the transaction is automatically handled. - -#### sbt dependencies - -``` -libraryDependencies ++= Seq( - "io.getquill" %% "quill-ndbc-postgres" % "@VERSION@" -) -``` - -#### context definition -```scala -lazy val ctx = new NdbcPostgresContext(Literal, "ctx") -``` - -#### application.properties -``` -ctx.ndbc.dataSourceSupplierClass=io.trane.ndbc.postgres.netty4.DataSourceSupplier -ctx.ndbc.host=host -ctx.ndbc.port=1234 -ctx.ndbc.user=root -ctx.ndbc.password=root -ctx.ndbc.database=database -``` - -## quill-async - -The `quill-async` module provides simple async support for MySQL and Postgres databases. - -#### transactions - -The async module provides transaction support based on a custom implicit execution context: - -``` -ctx.transaction { implicit ec => - ctx.run(query[Person].delete) - // other transactional code -} -``` - -The body of `transaction` can contain calls to other methods and multiple `run` calls, but the transactional code must be done using the provided implicit execution context. For instance: - -``` -def deletePerson(name: String)(implicit ec: ExecutionContext) = - ctx.run(query[Person].filter(_.name == lift(name)).delete) - -ctx.transaction { implicit ec => - deletePerson("John") -} -``` - -Depending on how the main execution context is imported, it is possible to produce an ambiguous implicit resolution. A way to solve this problem is shadowing the multiple implicits by using the same name: - -``` -import scala.concurrent.ExecutionContext.Implicits.{ global => ec } - -def deletePerson(name: String)(implicit ec: ExecutionContext) = - ctx.run(query[Person].filter(_.name == lift(name)).delete) - -ctx.transaction { implicit ec => - deletePerson("John") -} -``` - -Note that the global execution context is renamed to ec. - -#### application.properties - -##### connection configuration -``` -ctx.host=host -ctx.port=1234 -ctx.user=root -ctx.password=root -ctx.database=database -``` - -or use connection URL with database-specific scheme (see below): - -``` -ctx.url=scheme://host:5432/database?user=root&password=root -``` - -##### connection pool configuration -``` -ctx.poolMaxQueueSize=4 -ctx.poolMaxObjects=4 -ctx.poolMaxIdle=999999999 -ctx.poolValidationInterval=10000 -``` - -Also see [`PoolConfiguration` documentation](https://github.com/mauricio/postgresql-async/blob/master/db-async-common/src/main/scala/com/github/mauricio/async/db/pool/PoolConfiguration.scala). - -##### SSL configuration -``` -ctx.sslmode=disable # optional, one of [disable|prefer|require|verify-ca|verify-full] -ctx.sslrootcert=./path/to/cert/file # optional, required for sslmode=verify-ca or verify-full -``` - -##### other -``` -ctx.charset=UTF-8 -ctx.maximumMessageSize=16777216 -ctx.connectTimeout=5s -ctx.testTimeout=5s -ctx.queryTimeout=10m -``` - -### quill-async-mysql - -#### sbt dependencies - -``` -libraryDependencies ++= Seq( - "io.getquill" %% "quill-async-mysql" % "@VERSION@" -) -``` - -#### context definition -```scala -lazy val ctx = new MysqlAsyncContext(SnakeCase, "ctx") -``` - -#### application.properties - -See [above](#applicationproperties-5) - -For `url` property use `mysql` scheme: - -``` -ctx.url=mysql://host:3306/database?user=root&password=root -``` - -### quill-async-postgres - -#### sbt dependencies - -``` -libraryDependencies ++= Seq( - "io.getquill" %% "quill-async-postgres" % "@VERSION@" -) -``` - -#### context definition -```scala -lazy val ctx = new PostgresAsyncContext(SnakeCase, "ctx") -``` - -#### application.properties - -See [common properties](#applicationproperties-5) - -For `url` property use `postgresql` scheme: - -``` -ctx.url=postgresql://host:5432/database?user=root&password=root -``` - -## quill-jasync - -The `quill-jasync` module provides simple async support for Postgres databases. - -#### transactions - -The async module provides transaction support based on a custom implicit execution context: - -``` -ctx.transaction { implicit ec => - ctx.run(query[Person].delete) - // other transactional code -} -``` - -The body of `transaction` can contain calls to other methods and multiple `run` calls, but the transactional code must be done using the provided implicit execution context. For instance: - -``` -def deletePerson(name: String)(implicit ec: ExecutionContext) = - ctx.run(query[Person].filter(_.name == lift(name)).delete) - -ctx.transaction { implicit ec => - deletePerson("John") -} -``` - -Depending on how the main execution context is imported, it is possible to produce an ambiguous implicit resolution. A way to solve this problem is shadowing the multiple implicits by using the same name: - -``` -import scala.concurrent.ExecutionContext.Implicits.{ global => ec } - -def deletePerson(name: String)(implicit ec: ExecutionContext) = - ctx.run(query[Person].filter(_.name == lift(name)).delete) - -ctx.transaction { implicit ec => - deletePerson("John") -} -``` - -Note that the global execution context is renamed to ec. - -#### application.properties - -##### connection configuration -``` -ctx.host=host -ctx.port=1234 -ctx.username=root -ctx.password=root -ctx.database=database -``` - -or use connection URL with database-specific scheme (see below): - -``` -ctx.url=scheme://host:5432/database?user=root&password=root -``` - -Also see full settings `ConnectionPoolConfiguration` [documentation](https://github.com/jasync-sql/jasync-sql/blob/master/db-async-common/src/main/java/com/github/jasync/sql/db/ConnectionPoolConfiguration.kt). - -##### SSL configuration -``` -ctx.sslmode=disable # optional, one of [disable|prefer|require|verify-ca|verify-full] -ctx.sslrootcert=./path/to/cert/file # optional, required for sslmode=verify-ca or verify-full -``` - -### quill-jasync-mysql - -#### sbt dependencies - -``` -libraryDependencies ++= Seq( - "io.getquill" %% "quill-jasync-mysql" % "@VERSION@" -) -``` - -#### context definition -```scala -lazy val ctx = new MysqlJAsyncContext(SnakeCase, "ctx") -``` - -#### application.properties - -See [above](#applicationproperties-5) - -For `url` property use `mysql` scheme: - -``` -ctx.url=mysql://host:3306/database?user=root&password=root -``` - - -### quill-jasync-postgres - -#### sbt dependencies - -``` -libraryDependencies ++= Seq( - "io.getquill" %% "quill-jasync-postgres" % "@VERSION@" -) -``` - -#### context definition - -```scala -lazy val ctx = new PostgresJAsyncContext(SnakeCase, "ctx") -``` - -#### application.properties - -See [common properties](#applicationproperties-5) - -For `url` property use `postgresql` scheme: - -``` -ctx.url=postgresql://host:5432/database?user=root&password=root -``` - -## quill-jasync-zio - -The `quill-jasync-zio` module provides ZIO async support for Postgres databases. - - -##### connection configuration -``` -ctx.host=host -ctx.port=1234 -ctx.username=root -ctx.password=root -ctx.database=database -``` - -or use connection URL with database-specific scheme (see below): - -``` -ctx.url=scheme://host:5432/database?user=root&password=root -``` - -Also see full settings `ConnectionPoolConfiguration` [documentation](https://github.com/jasync-sql/jasync-sql/blob/master/db-async-common/src/main/java/com/github/jasync/sql/db/ConnectionPoolConfiguration.kt). - -##### SSL configuration -``` -ctx.sslmode=disable # optional, one of [disable|prefer|require|verify-ca|verify-full] -ctx.sslrootcert=./path/to/cert/file # optional, required for sslmode=verify-ca or verify-full -ctx.sslcert=./path/to/cert/file # optional, required to only allow connections from trusted clients -ctx.sslkey=./path/to/key/file # optional, required to only allow connections from trusted clients -``` - -### quill-jasync-zio-postgres - - -#### sbt dependencies - -``` -libraryDependencies ++= Seq( - "io.getquill" %% "quill-jasync-zio-postgres" % "@VERSION@" -) -``` - -#### context definition -```scala -lazy val ctx = new PostgresZioJAsyncContext(SnakeCase) -// Also can be static: -object MyContext extends PostgresZioJAsyncContext(Literal) -``` -In order to run operation in this context we need to provide `ZioJAsyncConnection` instance. - -```scala -object MyApp extends zio.App { - object DBContext extends PostgresZioJAsyncContext(Literal) - import DBContext._ - - val dependencies = - PostgresJAsyncContextConfig.loadConfig("testPostgresDB") >>> - ZioJAsyncConnection.live[PostgreSQLConnection] - - val program = run(query[Person]) - - def run(args: List[String]) = program.provideLayer(dependencies).exitCode -} -``` - -#### application.properties - -See [common properties](#applicationproperties-5) - -For `url` property use `postgresql` scheme: - -``` -ctx.url=postgresql://host:5432/database?user=root&password=root -``` - ## quill-doobie Quill 3.16.5 and above supports Doobie starting 1.0.0-RC1. You can use quill quotes to construct `ConnectionIO` programs. diff --git a/docs/getting-started.md b/docs/getting-started.md index 9de5053589..7901d5e638 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -8,7 +8,7 @@ sidebar_label: "Getting Started" Quill has integrations with many libraries. If you are using a regular RDBMS e.g. PostgreSQL and want to use Quill to query it with an asynchronous, non-blocking, reactive application, the easiest way to get -started is by using an awesome library called ZIO. +started is by using ZIO. A simple ZIO + Quill application looks like this: ```scala @@ -57,6 +57,4 @@ Choose the quill module that works for you! * If you are starting from scratch with a regular RDBMS try using the `quill-jdbc-zio` module as shown above. * If you are developing a legacy Java project and don't want/need reactive, use `quill-jdbc`. * If you are developing a project with Cats and/or Monix, try `quill-jdbc-monix`. -* If you like to "live dangerously" and want to try a socket-level async library, try `quill-jasync-postgres` - or `quill-jasync-mysql`. * If you are using Cassandra, Spark, or OrientDB, try the corresponding modules for each of them. diff --git a/docs/quill-vs-slick.md b/docs/quill-vs-slick.md index 78a32ffdf1..3e7a0eaa47 100644 --- a/docs/quill-vs-slick.md +++ b/docs/quill-vs-slick.md @@ -98,7 +98,7 @@ The feedback cycle using Slick is typically longer. Some factors like normalizat ## Non-blocking IO ## -Slick provides an asynchronous wrapper on top of jdbc's blocking interface, making it harder to scale applications using it. On the other hand, quill provides fully asynchronous non-blocking database access through quill-async and quill-finagle-mysql. +Slick provides an asynchronous wrapper on top of jdbc's blocking interface, making it harder to scale applications using it. On the other hand, quill provides fully asynchronous non-blocking database access through quill-zio. ## Extensibility ## diff --git a/docs/writing-queries.md b/docs/writing-queries.md index ae88e864f1..9f7f6e1add 100644 --- a/docs/writing-queries.md +++ b/docs/writing-queries.md @@ -2039,8 +2039,7 @@ final case class Book(id: Int, notes: List[String], pages: Vector[Int], history: ctx.run(query[Book]) // SELECT x.id, x.notes, x.pages, x.history FROM Book x ``` -Note that not all drivers/databases provides such feature hence only `PostgresJdbcContext` and -`PostgresAsyncContext` support SQL Arrays. +Note that not all drivers/databases provides such feature hence only `PostgresJdbcContext` support SQL Arrays. ## Cassandra-specific encoding diff --git a/quill-jasync-mysql/src/main/scala/io/getquill/MysqlJAsyncContext.scala b/quill-jasync-mysql/src/main/scala/io/getquill/MysqlJAsyncContext.scala deleted file mode 100644 index 23c373ce6c..0000000000 --- a/quill-jasync-mysql/src/main/scala/io/getquill/MysqlJAsyncContext.scala +++ /dev/null @@ -1,38 +0,0 @@ -package io.getquill - -import java.lang.{Long => JavaLong} - -import com.github.jasync.sql.db.{QueryResult => DBQueryResult} -import com.github.jasync.sql.db.mysql.MySQLConnection -import com.github.jasync.sql.db.mysql.MySQLQueryResult -import com.github.jasync.sql.db.pool.ConnectionPool -import com.typesafe.config.Config -import io.getquill.context.jasync.{JAsyncContext, UUIDStringEncoding} -import io.getquill.util.LoadConfig -import io.getquill.util.Messages.fail -import com.github.jasync.sql.db.general.ArrayRowData -import scala.jdk.CollectionConverters._ - -class MysqlJAsyncContext[+N <: NamingStrategy](naming: N, pool: ConnectionPool[MySQLConnection]) - extends JAsyncContext[MySQLDialect, N, MySQLConnection](MySQLDialect, naming, pool) - with UUIDStringEncoding { - - def this(naming: N, config: MysqlJAsyncContextConfig) = this(naming, config.pool) - def this(naming: N, config: Config) = this(naming, MysqlJAsyncContextConfig(config)) - def this(naming: N, configPrefix: String) = this(naming, LoadConfig(configPrefix)) - - override protected def extractActionResult[O](returningAction: ReturnAction, returningExtractor: Extractor[O])( - result: DBQueryResult - ): List[O] = - result match { - case r: MySQLQueryResult => - List( - returningExtractor( - new ArrayRowData(0, Map.empty[String, Integer].asJava, Array(JavaLong.valueOf(r.getLastInsertId))), - () - ) - ) - case _ => - fail("This is a bug. Cannot extract returning value.") - } -} diff --git a/quill-jasync-mysql/src/main/scala/io/getquill/MysqlJAsyncContextConfig.scala b/quill-jasync-mysql/src/main/scala/io/getquill/MysqlJAsyncContextConfig.scala deleted file mode 100644 index d1eea13918..0000000000 --- a/quill-jasync-mysql/src/main/scala/io/getquill/MysqlJAsyncContextConfig.scala +++ /dev/null @@ -1,10 +0,0 @@ -package io.getquill - -import com.github.jasync.sql.db.mysql.MySQLConnection -import com.github.jasync.sql.db.mysql.pool.MySQLConnectionFactory -import com.github.jasync.sql.db.mysql.util.URLParser -import com.typesafe.config.Config -import io.getquill.context.jasync.JAsyncContextConfig - -case class MysqlJAsyncContextConfig(config: Config) - extends JAsyncContextConfig[MySQLConnection](config, new MySQLConnectionFactory(_), URLParser.INSTANCE) diff --git a/quill-jasync-mysql/src/test/resources/application.conf b/quill-jasync-mysql/src/test/resources/application.conf deleted file mode 100644 index 0e0faad738..0000000000 --- a/quill-jasync-mysql/src/test/resources/application.conf +++ /dev/null @@ -1,9 +0,0 @@ -testMysqlDB.host=${?MYSQL_HOST} -testMysqlDB.port=${?MYSQL_PORT} -testMysqlDB.user=root -testMysqlDB.password=${?MYSQL_PASSWORD} -testMysqlDB.database=quill_test -testMysqlDB.poolMaxQueueSize=10 -testMysqlDB.poolMaxObjects=10 -testMysqlDB.poolMaxIdle=999999999 -testMysqlDB.poolValidationInterval=100 \ No newline at end of file diff --git a/quill-jasync-mysql/src/test/scala/io/getquill/TypeParamExtensionTest.scala b/quill-jasync-mysql/src/test/scala/io/getquill/TypeParamExtensionTest.scala deleted file mode 100644 index 62cb105a56..0000000000 --- a/quill-jasync-mysql/src/test/scala/io/getquill/TypeParamExtensionTest.scala +++ /dev/null @@ -1,14 +0,0 @@ -package io.getquill - -import io.getquill.context.Context - -// Testing we are passing type params explicitly into AsyncContext, otherwise -// this file will fail to compile - -trait BaseExtensions { - val context: Context[MySQLDialect, _] -} - -trait AsyncExtensions extends BaseExtensions { - override val context: MysqlJAsyncContext[_] -} diff --git a/quill-jasync-mysql/src/test/scala/io/getquill/context/jasync/mysql/CaseClassQueryJAsyncSpec.scala b/quill-jasync-mysql/src/test/scala/io/getquill/context/jasync/mysql/CaseClassQueryJAsyncSpec.scala deleted file mode 100644 index cd73620d9a..0000000000 --- a/quill-jasync-mysql/src/test/scala/io/getquill/context/jasync/mysql/CaseClassQueryJAsyncSpec.scala +++ /dev/null @@ -1,51 +0,0 @@ -package io.getquill.context.jasync.mysql - -import io.getquill.context.sql.base.CaseClassQuerySpec -import scala.concurrent.ExecutionContext.Implicits.{global => ec} -import org.scalatest.matchers.should.Matchers._ - -class CaseClassQueryJAsyncSpec extends CaseClassQuerySpec { - - val context = testContext - import testContext._ - - override def beforeAll = - await { - testContext.transaction { implicit ec => - for { - _ <- testContext.run(query[Contact].delete) - _ <- testContext.run(query[Address].delete) - _ <- testContext.run(liftQuery(peopleEntries).foreach(e => peopleInsert(e))) - _ <- testContext.run(liftQuery(addressEntries).foreach(e => addressInsert(e))) - } yield {} - } - } - - "Example 1 - Single Case Class Mapping" in { - await( - testContext.run(`Ex 1 CaseClass Record Output`) - ) should contain theSameElementsAs `Ex 1 CaseClass Record Output expected result` - } - "Example 1A - Single Case Class Mapping" in { - await( - testContext.run(`Ex 1A CaseClass Record Output`) - ) should contain theSameElementsAs `Ex 1 CaseClass Record Output expected result` - } - "Example 1B - Single Case Class Mapping" in { - await( - testContext.run(`Ex 1B CaseClass Record Output`) - ) should contain theSameElementsAs `Ex 1 CaseClass Record Output expected result` - } - - "Example 2 - Single Record Mapped Join" in { - await( - testContext.run(`Ex 2 Single-Record Join`) - ) should contain theSameElementsAs `Ex 2 Single-Record Join expected result` - } - - "Example 3 - Inline Record as Filter" in { - await( - testContext.run(`Ex 3 Inline Record Usage`) - ) should contain theSameElementsAs `Ex 3 Inline Record Usage expected result` - } -} diff --git a/quill-jasync-mysql/src/test/scala/io/getquill/context/jasync/mysql/DepartmentsMysqlJAsyncSpec.scala b/quill-jasync-mysql/src/test/scala/io/getquill/context/jasync/mysql/DepartmentsMysqlJAsyncSpec.scala deleted file mode 100644 index b0c1d9e946..0000000000 --- a/quill-jasync-mysql/src/test/scala/io/getquill/context/jasync/mysql/DepartmentsMysqlJAsyncSpec.scala +++ /dev/null @@ -1,34 +0,0 @@ -package io.getquill.context.jasync.mysql - -import io.getquill.context.sql.base.DepartmentsSpec - -import scala.concurrent.ExecutionContext.Implicits.{global => ec} - -class DepartmentsMysqlJAsyncSpec extends DepartmentsSpec { - - val context = testContext - import testContext._ - - override def beforeAll = - await { - testContext.transaction { implicit ec => - for { - _ <- testContext.run(query[Department].delete) - _ <- testContext.run(query[Employee].delete) - _ <- testContext.run(query[Task].delete) - - _ <- testContext.run(liftQuery(departmentEntries).foreach(e => departmentInsert(e))) - _ <- testContext.run(liftQuery(employeeEntries).foreach(e => employeeInsert(e))) - _ <- testContext.run(liftQuery(taskEntries).foreach(e => taskInsert(e))) - } yield {} - } - } - - "Example 8 - nested naive" in { - await(testContext.run(`Example 8 expertise naive`(lift(`Example 8 param`)))) mustEqual `Example 8 expected result` - } - - "Example 9 - nested db" in { - await(testContext.run(`Example 9 expertise`(lift(`Example 9 param`)))) mustEqual `Example 9 expected result` - } -} diff --git a/quill-jasync-mysql/src/test/scala/io/getquill/context/jasync/mysql/MysqlJAsyncContextConfigSpec.scala b/quill-jasync-mysql/src/test/scala/io/getquill/context/jasync/mysql/MysqlJAsyncContextConfigSpec.scala deleted file mode 100644 index e055842e09..0000000000 --- a/quill-jasync-mysql/src/test/scala/io/getquill/context/jasync/mysql/MysqlJAsyncContextConfigSpec.scala +++ /dev/null @@ -1,66 +0,0 @@ -package io.getquill.context.jasync.mysql - -import java.nio.charset.Charset - -import com.typesafe.config.ConfigFactory -import io.getquill.MysqlJAsyncContextConfig -import io.getquill.base.Spec - -import scala.jdk.CollectionConverters._ - -class MysqlJAsyncContextConfigSpec extends Spec { - - "extracts valid data from configs" in { - val c = ConfigFactory.parseMap( - Map( - "url" -> "jdbc:postgresql://github.com:5233/db?user=p", - "pass" -> "pass", - "queryTimeout" -> "123", - "host" -> "github.com", - "port" -> "5233", - "charset" -> "UTF-8", - "username" -> "p", - "password" -> "pass", - "maximumMessageSize" -> "456", - "connectionTestTimeout" -> "789" - ).asJava - ) - val conf = MysqlJAsyncContextConfig(c).connectionPoolConfiguration - - conf.getQueryTimeout mustBe 123L - conf.getConnectionTestTimeout mustBe 789L - conf.getMaximumMessageSize mustBe 456 - conf.getCharset mustBe Charset.forName("UTF-8") - conf.getHost mustBe "github.com" - conf.getPort mustBe 5233 - conf.getUsername mustBe "p" - conf.getPassword mustBe "pass" - } - - "parses url and passes valid data to configuration" in { - val c = ConfigFactory.parseMap( - Map( - "url" -> "jdbc:mysql://host:5233/db?user=p", - "pass" -> "pass", - "queryTimeout" -> "123", - "host" -> "github.com", - "port" -> "5233", - "charset" -> "UTF-8", - "password" -> "pass", - "maximumMessageSize" -> "456", - "connectionTestTimeout" -> "789" - ).asJava - ) - val conf = MysqlJAsyncContextConfig(c).connectionPoolConfiguration - - conf.getQueryTimeout mustBe 123L - conf.getConnectionTestTimeout mustBe 789L - conf.getMaximumMessageSize mustBe 456 - conf.getCharset mustBe Charset.forName("UTF-8") - conf.getHost mustBe "github.com" - conf.getPort mustBe 5233 - conf.getUsername mustBe "p" - conf.getPassword mustBe "pass" - } - -} diff --git a/quill-jasync-mysql/src/test/scala/io/getquill/context/jasync/mysql/MysqlJAsyncContextSpec.scala b/quill-jasync-mysql/src/test/scala/io/getquill/context/jasync/mysql/MysqlJAsyncContextSpec.scala deleted file mode 100644 index 60bef118b6..0000000000 --- a/quill-jasync-mysql/src/test/scala/io/getquill/context/jasync/mysql/MysqlJAsyncContextSpec.scala +++ /dev/null @@ -1,113 +0,0 @@ -package io.getquill.context.jasync.mysql - -import com.github.jasync.sql.db.{QueryResult, ResultSetKt} -import io.getquill.ReturnAction.ReturnColumns -import io.getquill.base.Spec -import io.getquill.{Literal, MysqlJAsyncContext, ReturnAction} - -import scala.concurrent.ExecutionContext.Implicits.global -import scala.concurrent.Future - -class MysqlJAsyncContextSpec extends Spec { - - import testContext._ - - "run non-batched action" in { - val insert = quote { (i: Int) => - qr1.insert(_.i -> i) - } - await(testContext.run(insert(lift(1)))) mustEqual 1 - } - - "Insert with returning with single column table" in { - val inserted: Long = await(testContext.run { - qr4.insertValue(lift(TestEntity4(0))).returningGenerated(_.i) - }) - await(testContext.run(qr4.filter(_.i == lift(inserted)))).head.i mustBe inserted - } - - "performIO" in { - await(performIO(runIO(qr4).transactional)) - } - - "probe" in { - probe("select 1").toOption mustBe defined - } - - "cannot extract" in { - object ctx extends MysqlJAsyncContext(Literal, "testMysqlDB") { - override def handleSingleResult[T](sql: String, list: List[T]) = super.handleSingleResult(sql, list) - - override def extractActionResult[O]( - returningAction: ReturnAction, - returningExtractor: ctx.Extractor[O] - )(result: QueryResult) = - super.extractActionResult(returningAction, returningExtractor)(result) - } - intercept[IllegalStateException] { - val v = ctx.extractActionResult(ReturnColumns(List("w/e")), (row, session) => 1)( - new QueryResult(0, "w/e", ResultSetKt.getEMPTY_RESULT_SET) - ) - ctx.handleSingleResult("", v) - } - ctx.close - } - - "prepare" in { - testContext.prepareParams("", (ps, session) => (Nil, ps ++ List("Sarah", 127))) mustEqual List("'Sarah'", "127") - } - - "provides transaction support" - { - "success" in { - await(for { - _ <- testContext.run(qr4.delete) - _ <- testContext.transaction { implicit ec => - testContext.run(qr4.insert(_.i -> 33)) - } - r <- testContext.run(qr4) - } yield r).map(_.i) mustEqual List(33) - } - "failure" in { - await(for { - _ <- testContext.run(qr4.delete) - e <- testContext.transaction { implicit ec => - Future.sequence( - Seq( - testContext.run(qr4.insert(_.i -> 18)), - Future(throw new IllegalStateException) - ) - ) - }.recoverWith { case e: Exception => - Future(e.getClass.getSimpleName) - } - r <- testContext.run(qr4) - } yield (e, r.isEmpty)) mustEqual (("CompletionException", true)) - } - "nested" in { - await(for { - _ <- testContext.run(qr4.delete) - _ <- testContext.transaction { implicit ec => - testContext.transaction { implicit ec => - testContext.run(qr4.insert(_.i -> 33)) - } - } - r <- testContext.run(qr4) - } yield r).map(_.i) mustEqual List(33) - } - "nested transactions use the same connection" in { - await(for { - e <- testContext.transaction { implicit ec => - val externalConn = ec.conn - testContext.transaction { implicit ec => - Future(externalConn == ec.conn) - } - } - } yield e) mustEqual true - } - } - - override protected def beforeAll(): Unit = { - await(testContext.run(qr1.delete)) - () - } -} diff --git a/quill-jasync-mysql/src/test/scala/io/getquill/context/jasync/mysql/MysqlJAsyncEncodingSpec.scala b/quill-jasync-mysql/src/test/scala/io/getquill/context/jasync/mysql/MysqlJAsyncEncodingSpec.scala deleted file mode 100644 index bc217ec4a9..0000000000 --- a/quill-jasync-mysql/src/test/scala/io/getquill/context/jasync/mysql/MysqlJAsyncEncodingSpec.scala +++ /dev/null @@ -1,160 +0,0 @@ -package io.getquill.context.jasync.mysql - -import java.time.{LocalDate, LocalDateTime} -import io.getquill.context.sql.EncodingSpec - -import scala.concurrent.ExecutionContext.Implicits.global -import scala.concurrent.{Await, Future} -import scala.concurrent.duration.Duration -import java.util.Date -import io.getquill.Query -import io.getquill.context.jasync.mysql - -import java.time.temporal.ChronoUnit - -class MysqlJAsyncEncodingSpec extends EncodingSpec { - - val context = testContext - import testContext._ - - "encodes and decodes types" in { - val r = - for { - _ <- testContext.run(delete) - _ <- testContext.run(liftQuery(insertValues).foreach(e => insert(e))) - result <- testContext.run(query[EncodingTestEntity]) - } yield result - - verify(Await.result(r, Duration.Inf)) - } - - "decode numeric types correctly" - { - "decode byte to" - { - "short" in { - prepareEncodingTestEntity() - case class EncodingTestEntity(v3: Short) - val v3List = Await.result(testContext.run(query[EncodingTestEntity]), Duration.Inf) - v3List.map(_.v3) must contain theSameElementsAs List(1: Byte, 0: Byte) - } - "int" in { - prepareEncodingTestEntity() - case class EncodingTestEntity(v3: Int) - val v3List = Await.result(testContext.run(query[EncodingTestEntity]), Duration.Inf) - v3List.map(_.v3) must contain theSameElementsAs List(1, 0) - } - "long" in { - prepareEncodingTestEntity() - case class EncodingTestEntity(v3: Long) - val v3List = Await.result(testContext.run(query[EncodingTestEntity]), Duration.Inf) - v3List.map(_.v3) must contain theSameElementsAs List(1L, 0L) - } - } - "decode short to" - { - "int" in { - prepareEncodingTestEntity() - case class EncodingTestEntity(v5: Int) - val v5List = Await.result(testContext.run(query[EncodingTestEntity]), Duration.Inf) - v5List.map(_.v5) must contain theSameElementsAs List(23, 0) - } - "long" in { - prepareEncodingTestEntity() - case class EncodingTestEntity(v5: Long) - val v5List = Await.result(testContext.run(query[EncodingTestEntity]), Duration.Inf) - v5List.map(_.v5) must contain theSameElementsAs List(23L, 0L) - } - } - "decode int to long" in { - case class EncodingTestEntity(v6: Long) - val v6List = Await.result(testContext.run(query[EncodingTestEntity]), Duration.Inf) - v6List.map(_.v6) must contain theSameElementsAs List(33L, 0L) - } - - "decode and encode any numeric as boolean" in { - case class EncodingTestEntity(v3: Boolean, v4: Boolean, v6: Boolean, v7: Boolean) - Await.result(testContext.run(query[EncodingTestEntity]), Duration.Inf) - () - } - } - - "decode date types" in { - case class DateEncodingTestEntity(v1: Date, v2: Date, v3: Date) - val entity = DateEncodingTestEntity(new Date, new Date, new Date) - val r = for { - _ <- testContext.run(query[DateEncodingTestEntity].delete) - _ <- testContext.run(query[DateEncodingTestEntity].insertValue(lift(entity))) - result <- testContext.run(query[DateEncodingTestEntity]) - } yield result - Await.result(r, Duration.Inf) - () - } - - "decode LocalDate and LocalDateTime types" in { - case class DateEncodingTestEntity(v1: LocalDate, v2: LocalDateTime, v3: LocalDateTime) - val entity = DateEncodingTestEntity( - LocalDate.now, - LocalDateTime.now.truncatedTo(ChronoUnit.MILLIS), - LocalDateTime.now.truncatedTo(ChronoUnit.MILLIS) - ) - val r = for { - _ <- testContext.run(query[DateEncodingTestEntity].delete) - _ <- testContext.run(query[DateEncodingTestEntity].insertValue(lift(entity))) - result <- testContext.run(query[DateEncodingTestEntity]) - } yield result - Await.result(r, Duration.Inf) must contain(entity) - } - - "fails if the column has the wrong type" - { - "numeric" in { - Await.result(testContext.run(liftQuery(insertValues).foreach(e => insert(e))), Duration.Inf) - case class EncodingTestEntity(v1: Int) - val e = intercept[IllegalStateException] { - Await.result(testContext.run(query[EncodingTestEntity]), Duration.Inf) - } - } - "non-numeric" in { - Await.result(testContext.run(liftQuery(insertValues).foreach(e => insert(e))), Duration.Inf) - case class EncodingTestEntity(v1: Date) - val e = intercept[IllegalStateException] { - Await.result(testContext.run(query[EncodingTestEntity]), Duration.Inf) - } - } - } - - "encodes sets" in { - val q = quote { (set: Query[Int]) => - query[EncodingTestEntity].filter(t => set.contains(t.v6)) - } - val fut = - for { - _ <- testContext.run(query[EncodingTestEntity].delete) - _ <- testContext.run(liftQuery(insertValues).foreach(e => query[EncodingTestEntity].insertValue(e))) - r <- testContext.run(q(liftQuery(insertValues.map(_.v6)))) - } yield { - r - } - verify(Await.result(fut, Duration.Inf)) - } - - "encodes custom type inside singleton object" in { - object Singleton { - def apply()(implicit c: TestContext): Future[Seq[Long]] = { - import c._ - for { - _ <- c.run(query[EncodingTestEntity].delete) - result <- c.run(liftQuery(insertValues).foreach(e => query[EncodingTestEntity].insertValue(e))) - } yield result - } - } - - implicit val c = testContext - Await.result(Singleton(), Duration.Inf) - } - - private def prepareEncodingTestEntity(): Unit = { - val prepare = for { - _ <- testContext.run(delete) - _ <- testContext.run(liftQuery(insertValues).foreach(e => insert(e))) - } yield {} - Await.result(prepare, Duration.Inf) - } -} diff --git a/quill-jasync-mysql/src/test/scala/io/getquill/context/jasync/mysql/OnConflictJAsyncSpec.scala b/quill-jasync-mysql/src/test/scala/io/getquill/context/jasync/mysql/OnConflictJAsyncSpec.scala deleted file mode 100644 index f0c5bf0b6a..0000000000 --- a/quill-jasync-mysql/src/test/scala/io/getquill/context/jasync/mysql/OnConflictJAsyncSpec.scala +++ /dev/null @@ -1,36 +0,0 @@ -package io.getquill.context.jasync.mysql - -import io.getquill.context.sql.base.OnConflictSpec -import scala.concurrent.ExecutionContext.Implicits.global - -class OnConflictJAsyncSpec extends OnConflictSpec { - val ctx = testContext - import ctx._ - - override protected def beforeAll(): Unit = { - await(ctx.run(qr1.delete)) - () - } - - "INSERT IGNORE" in { - import `onConflictIgnore`._ - await(ctx.run(testQuery1)) mustEqual res1 - await(ctx.run(testQuery2)) mustEqual res2 - await(ctx.run(testQuery3)) mustEqual res3 - } - - "ON DUPLICATE KEY UPDATE i=i " in { - import `onConflictIgnore(_.i)`._ - await(ctx.run(testQuery1)) mustEqual res1 - await(ctx.run(testQuery2)) mustEqual res2 - await(ctx.run(testQuery3)) mustEqual res3 - } - - "ON DUPLICATE KEY UPDATE ..." in { - import `onConflictUpdate((t, e) => ...)`._ - await(ctx.run(testQuery(e1))) mustEqual res1 - await(ctx.run(testQuery(e2))) mustEqual res2 + 1 - await(ctx.run(testQuery(e3))) mustEqual res3 + 1 - await(ctx.run(testQuery4)) mustEqual res4 - } -} diff --git a/quill-jasync-mysql/src/test/scala/io/getquill/context/jasync/mysql/PeopleAsyncReturningSpec.scala b/quill-jasync-mysql/src/test/scala/io/getquill/context/jasync/mysql/PeopleAsyncReturningSpec.scala deleted file mode 100644 index 6267831ebb..0000000000 --- a/quill-jasync-mysql/src/test/scala/io/getquill/context/jasync/mysql/PeopleAsyncReturningSpec.scala +++ /dev/null @@ -1,75 +0,0 @@ -package io.getquill.context.jasync.mysql - -import io.getquill.context.sql.base.PeopleReturningSpec -import scala.concurrent.ExecutionContext.Implicits.{global => ec} - -class PeopleAsyncReturningSpec extends PeopleReturningSpec { - - val context: testContext.type = testContext - - import testContext._ - - override def beforeEach(): Unit = { - await { - testContext.transaction { implicit ec => - for { - _ <- testContext.run(query[Contact].delete) - _ <- testContext.run(query[Product].delete) - _ <- testContext.run(liftQuery(people).foreach(p => peopleInsert(p))) - } yield () - } - } - super.beforeEach() - } - - "Ex 0 insert.returning(_.generatedColumn) mod" in { - import `Ex 0 insert.returning(_.generatedColumn) mod`._ - await(for { - id <- testContext.run(op) - output <- testContext.run(get) - } yield (output.toSet mustEqual result(id).toSet)) - } - - "Ex 0.5 insert.returning(wholeRecord) mod" ignore { - import `Ex 0.5 insert.returning(wholeRecord) mod`._ - await(for { - product <- testContext.run(op) - output <- testContext.run(get) - } yield (output mustEqual result(product))) - } - - "Ex 1 insert.returningMany(_.generatedColumn) mod" in { - import `Ex 1 insert.returningMany(_.generatedColumn) mod`._ - await(for { - id <- testContext.run(op) - output <- testContext.run(get) - } yield (output mustEqual result(id.head))) - } - - "Ex 2 update.returningMany(_.singleColumn) mod" ignore { - import `Ex 2 update.returningMany(_.singleColumn) mod`._ - await(for { - opResult <- testContext.run(op) - _ = opResult.toSet mustEqual expect.toSet - output <- testContext.run(get) - } yield (output.toSet mustEqual result.toSet)) - } - - "Ex 3 delete.returningMany(wholeRecord)" ignore { - import `Ex 3 delete.returningMany(wholeRecord)`._ - await(for { - opResult <- testContext.run(op) - _ = opResult.toSet mustEqual expect.toSet - output <- testContext.run(get) - } yield (output.toSet mustEqual result.toSet)) - } - - "Ex 4 update.returningMany(query)" ignore { - import `Ex 4 update.returningMany(query)`._ - await(for { - opResult <- testContext.run(op) - _ = opResult.toSet mustEqual expect.toSet - output <- testContext.run(get) - } yield (output.toSet mustEqual result.toSet)) - } -} diff --git a/quill-jasync-mysql/src/test/scala/io/getquill/context/jasync/mysql/PeopleMysqlJAsyncSpec.scala b/quill-jasync-mysql/src/test/scala/io/getquill/context/jasync/mysql/PeopleMysqlJAsyncSpec.scala deleted file mode 100644 index 4786d758bc..0000000000 --- a/quill-jasync-mysql/src/test/scala/io/getquill/context/jasync/mysql/PeopleMysqlJAsyncSpec.scala +++ /dev/null @@ -1,61 +0,0 @@ -package io.getquill.context.jasync.mysql - -import io.getquill.context.sql.base.PeopleSpec - -import scala.concurrent.ExecutionContext.Implicits.{global => ec} - -class PeopleMysqlJAsyncSpec extends PeopleSpec { - - val context = testContext - import testContext._ - - override def beforeAll = - await { - testContext.transaction { implicit ec => - for { - _ <- testContext.run(query[Couple].delete) - _ <- testContext.run(query[Person].delete) - _ <- testContext.run(liftQuery(peopleEntries).foreach(e => peopleInsert(e))) - _ <- testContext.run(liftQuery(couplesEntries).foreach(e => couplesInsert(e))) - } yield {} - } - } - - "Example 1 - differences" in { - await(testContext.run(`Ex 1 differences`)) mustEqual `Ex 1 expected result` - } - - "Example 2 - range simple" in { - await( - testContext.run(`Ex 2 rangeSimple`(lift(`Ex 2 param 1`), lift(`Ex 2 param 2`))) - ) mustEqual `Ex 2 expected result` - } - - "Examples 3 - satisfies" in { - await(testContext.run(`Ex 3 satisfies`)) mustEqual `Ex 3 expected result` - } - - "Examples 4 - satisfies" in { - await(testContext.run(`Ex 4 satisfies`)) mustEqual `Ex 4 expected result` - } - - "Example 5 - compose" in { - await(testContext.run(`Ex 5 compose`(lift(`Ex 5 param 1`), lift(`Ex 5 param 2`)))) mustEqual `Ex 5 expected result` - } - - "Example 6 - predicate 0" in { - await(testContext.run(satisfies(eval(`Ex 6 predicate`)))) mustEqual `Ex 6 expected result` - } - - "Example 7 - predicate 1" in { - await(testContext.run(satisfies(eval(`Ex 7 predicate`)))) mustEqual `Ex 7 expected result` - } - - "Example 8 - contains empty" in { - await(testContext.run(`Ex 8 and 9 contains`(liftQuery(`Ex 8 param`)))) mustEqual `Ex 8 expected result` - } - - "Example 9 - contains non empty" in { - await(testContext.run(`Ex 8 and 9 contains`(liftQuery(`Ex 9 param`)))) mustEqual `Ex 9 expected result` - } -} diff --git a/quill-jasync-mysql/src/test/scala/io/getquill/context/jasync/mysql/ProductMysqlJAsyncSpec.scala b/quill-jasync-mysql/src/test/scala/io/getquill/context/jasync/mysql/ProductMysqlJAsyncSpec.scala deleted file mode 100644 index 2167b358fd..0000000000 --- a/quill-jasync-mysql/src/test/scala/io/getquill/context/jasync/mysql/ProductMysqlJAsyncSpec.scala +++ /dev/null @@ -1,97 +0,0 @@ -package io.getquill.context.jasync.mysql - -import scala.concurrent.Future -import scala.concurrent.ExecutionContext.Implicits.global - -import io.getquill.context.sql.ProductSpec -import io.getquill.context.sql.Id - -class ProductMysqlJAsyncSpec extends ProductSpec { - - val context = testContext - import testContext._ - - override def beforeAll = { - await(testContext.run(quote(query[Product].delete))) - () - } - - "Product" - { - "Insert multiple products" in { - val inserted = - await(Future.sequence(productEntries.map(product => testContext.run(productInsert(lift(product)))))) - val product = await(testContext.run(productById(lift(inserted(2))))).head - product.description mustEqual productEntries(2).description - product.id mustEqual inserted(2) - } - "Single insert product" in { - val inserted = await(testContext.run(productSingleInsert)) - val product = await(testContext.run(productById(lift(inserted)))).head - product.description mustEqual "Window" - product.id mustEqual inserted - } - - "Single insert with inlined free variable" in { - val prd = Product(0L, "test1", 1L) - val inserted = await { - testContext.run { - product.insert(_.sku -> lift(prd.sku), _.description -> lift(prd.description)).returningGenerated(_.id) - } - } - val returnedProduct = await(testContext.run(productById(lift(inserted)))).head - returnedProduct.description mustEqual "test1" - returnedProduct.sku mustEqual 1L - returnedProduct.id mustEqual inserted - } - - "Single insert with free variable and explicit quotation" in { - val prd = Product(0L, "test2", 2L) - val q1 = quote { - product.insert(_.sku -> lift(prd.sku), _.description -> lift(prd.description)).returningGenerated(_.id) - } - val inserted = await(testContext.run(q1)) - val returnedProduct = await(testContext.run(productById(lift(inserted)))).head - returnedProduct.description mustEqual "test2" - returnedProduct.sku mustEqual 2L - returnedProduct.id mustEqual inserted - } - - "Single insert with value class" in { - case class Product(id: Id, description: String, sku: Long) - val prd = Product(Id(0L), "test2", 2L) - val q1 = quote { - query[Product].insert(_.sku -> lift(prd.sku), _.description -> lift(prd.description)).returningGenerated(_.id) - } - await(testContext.run(q1)) mustBe a[Id] - } - - "Single product insert with a method quotation" in { - val prd = Product(0L, "test3", 3L) - val inserted = await(testContext.run(productInsert(lift(prd)))) - val returnedProduct = await(testContext.run(productById(lift(inserted)))).head - returnedProduct.description mustEqual "test3" - returnedProduct.sku mustEqual 3L - returnedProduct.id mustEqual inserted - } - - "supports casts from string to number" - { - "toInt" in { - case class Product(id: Long, description: String, sku: Int) - val queried = await { - testContext.run { - query[Product].filter(_.sku == lift("1004").toInt) - } - }.head - queried.sku mustEqual 1004L - } - "toLong" in { - val queried = await { - testContext.run { - query[Product].filter(_.sku == lift("1004").toLong) - } - }.head - queried.sku mustEqual 1004L - } - } - } -} diff --git a/quill-jasync-mysql/src/test/scala/io/getquill/context/jasync/mysql/QueryResultTypeMysqlJAsyncSpec.scala b/quill-jasync-mysql/src/test/scala/io/getquill/context/jasync/mysql/QueryResultTypeMysqlJAsyncSpec.scala deleted file mode 100644 index 52e914eb82..0000000000 --- a/quill-jasync-mysql/src/test/scala/io/getquill/context/jasync/mysql/QueryResultTypeMysqlJAsyncSpec.scala +++ /dev/null @@ -1,106 +0,0 @@ -package io.getquill.context.jasync.mysql - -import io.getquill.context.sql.base.QueryResultTypeSpec - -import java.util.concurrent.ConcurrentLinkedQueue -import scala.jdk.CollectionConverters._ -import scala.concurrent.ExecutionContext.Implicits.global -import scala.math.BigDecimal.int2bigDecimal - -class QueryResultTypeMysqlJAsyncSpec extends QueryResultTypeSpec { - - val context = testContext - import testContext._ - - val insertedProducts = new ConcurrentLinkedQueue[Product] - - override def beforeAll = { - await(testContext.run(deleteAll)) - val ids = await(testContext.run(liftQuery(productEntries).foreach(e => productInsert(e)))) - val inserted = (ids zip productEntries).map { case (id, prod) => - prod.copy(id = id) - } - insertedProducts.addAll(inserted.asJava) - () - } - - def products = insertedProducts.asScala.toList - - "return list" - { - "select" in { - await(testContext.run(selectAll)) must contain theSameElementsAs (products) - } - "map" in { - await(testContext.run(map)) must contain theSameElementsAs (products.map(_.id)) - } - "filter" in { - await(testContext.run(filter)) must contain theSameElementsAs (products) - } - "withFilter" in { - await(testContext.run(withFilter)) must contain theSameElementsAs (products) - } - "sortBy" in { - await(testContext.run(sortBy)) must contain theSameElementsInOrderAs (products) - } - "take" in { - await(testContext.run(take)) must contain theSameElementsAs (products) - } - "drop" in { - await(testContext.run(drop)) must contain theSameElementsAs (products.drop(1)) - } - "++" in { - await(testContext.run(`++`)) must contain theSameElementsAs (products ++ products) - } - "unionAll" in { - await(testContext.run(unionAll)) must contain theSameElementsAs (products ++ products) - } - "union" in { - await(testContext.run(union)) must contain theSameElementsAs (products) - } - "join" in { - await(testContext.run(join)) must contain theSameElementsAs (products zip products) - } - "distinct" in { - await(testContext.run(distinct)) must contain theSameElementsAs (products.map(_.id).distinct) - } - } - - "return single result" - { - "min" - { - "some" in { - await(testContext.run(minExists)) mustEqual Some(products.map(_.sku).min) - } - "none" in { - await(testContext.run(minNonExists)) mustBe None - } - } - "max" - { - "some" in { - await(testContext.run(maxExists)) mustBe Some(products.map(_.sku).max) - } - "none" in { - await(testContext.run(maxNonExists)) mustBe None - } - } - "avg" - { - "some" in { - await(testContext.run(avgExists)) mustBe Some(BigDecimal(products.map(_.sku).sum) / products.size) - } - "none" in { - await(testContext.run(avgNonExists)) mustBe None - } - } - "size" in { - await(testContext.run(productSize)) mustEqual products.size - } - "parametrized size" in { - await(testContext.run(parametrizedSize(lift(10000)))) mustEqual 0 - } - "nonEmpty" in { - await(testContext.run(nonEmpty)) mustEqual true - } - "isEmpty" in { - await(testContext.run(isEmpty)) mustEqual false - } - } -} diff --git a/quill-jasync-mysql/src/test/scala/io/getquill/context/jasync/mysql/TestContext.scala b/quill-jasync-mysql/src/test/scala/io/getquill/context/jasync/mysql/TestContext.scala deleted file mode 100644 index 064e1ad059..0000000000 --- a/quill-jasync-mysql/src/test/scala/io/getquill/context/jasync/mysql/TestContext.scala +++ /dev/null @@ -1,10 +0,0 @@ -package io.getquill.context.jasync.mysql - -import io.getquill.{Literal, MysqlJAsyncContext, TestEntities} -import io.getquill.context.sql.{TestDecoders, TestEncoders} - -class TestContext - extends MysqlJAsyncContext(Literal, "testMysqlDB") - with TestEntities - with TestEncoders - with TestDecoders diff --git a/quill-jasync-mysql/src/test/scala/io/getquill/context/jasync/mysql/package.scala b/quill-jasync-mysql/src/test/scala/io/getquill/context/jasync/mysql/package.scala deleted file mode 100644 index e9b2ae6744..0000000000 --- a/quill-jasync-mysql/src/test/scala/io/getquill/context/jasync/mysql/package.scala +++ /dev/null @@ -1,5 +0,0 @@ -package io.getquill.context.jasync - -package object mysql { - object testContext extends TestContext -} diff --git a/quill-jasync-postgres/src/main/scala/io/getquill/PostgresJAsyncContext.scala b/quill-jasync-postgres/src/main/scala/io/getquill/PostgresJAsyncContext.scala deleted file mode 100644 index 91e18e398e..0000000000 --- a/quill-jasync-postgres/src/main/scala/io/getquill/PostgresJAsyncContext.scala +++ /dev/null @@ -1,38 +0,0 @@ -package io.getquill - -import com.github.jasync.sql.db.pool.ConnectionPool -import com.github.jasync.sql.db.postgresql.PostgreSQLConnection -import com.github.jasync.sql.db.{QueryResult => DBQueryResult} -import com.typesafe.config.Config -import io.getquill.ReturnAction.{ReturnColumns, ReturnNothing, ReturnRecord} -import io.getquill.context.jasync.{ArrayDecoders, ArrayEncoders, JAsyncContext, UUIDObjectEncoding} -import io.getquill.util.LoadConfig -import io.getquill.util.Messages.fail -import scala.jdk.CollectionConverters._ - -class PostgresJAsyncContext[+N <: NamingStrategy](naming: N, pool: ConnectionPool[PostgreSQLConnection]) - extends JAsyncContext[PostgresDialect, N, PostgreSQLConnection](PostgresDialect, naming, pool) - with ArrayEncoders - with ArrayDecoders - with UUIDObjectEncoding { - - def this(naming: N, config: PostgresJAsyncContextConfig) = this(naming, config.pool) - def this(naming: N, config: Config) = this(naming, PostgresJAsyncContextConfig(config)) - def this(naming: N, configPrefix: String) = this(naming, LoadConfig(configPrefix)) - - override protected def extractActionResult[O](returningAction: ReturnAction, returningExtractor: Extractor[O])( - result: DBQueryResult - ): List[O] = - result.getRows.asScala.toList.map(row => returningExtractor(row, ())) - - override protected def expandAction(sql: String, returningAction: ReturnAction): String = - returningAction match { - // The Postgres dialect will create SQL that has a 'RETURNING' clause so we don't have to add one. - case ReturnRecord => s"$sql" - // The Postgres dialect will not actually use these below variants but in case we decide to plug - // in some other dialect into this context... - case ReturnColumns(columns) => s"$sql RETURNING ${columns.mkString(", ")}" - case ReturnNothing => s"$sql" - } - -} diff --git a/quill-jasync-postgres/src/main/scala/io/getquill/PostgresJAsyncContextConfig.scala b/quill-jasync-postgres/src/main/scala/io/getquill/PostgresJAsyncContextConfig.scala deleted file mode 100644 index fa6f77a6d2..0000000000 --- a/quill-jasync-postgres/src/main/scala/io/getquill/PostgresJAsyncContextConfig.scala +++ /dev/null @@ -1,10 +0,0 @@ -package io.getquill - -import com.github.jasync.sql.db.postgresql.PostgreSQLConnection -import com.github.jasync.sql.db.postgresql.pool.PostgreSQLConnectionFactory -import com.github.jasync.sql.db.postgresql.util.URLParser -import com.typesafe.config.Config -import io.getquill.context.jasync.JAsyncContextConfig - -case class PostgresJAsyncContextConfig(config: Config) - extends JAsyncContextConfig[PostgreSQLConnection](config, new PostgreSQLConnectionFactory(_), URLParser.INSTANCE) diff --git a/quill-jasync-postgres/src/main/scala/io/getquill/context/jasync/ArrayDecoders.scala b/quill-jasync-postgres/src/main/scala/io/getquill/context/jasync/ArrayDecoders.scala deleted file mode 100644 index 1bc7d2cef1..0000000000 --- a/quill-jasync-postgres/src/main/scala/io/getquill/context/jasync/ArrayDecoders.scala +++ /dev/null @@ -1,65 +0,0 @@ -package io.getquill.context.jasync - -import java.time.{LocalDate, LocalDateTime, ZoneId} -import java.util -import java.util.Date -import io.getquill.PostgresJAsyncContext -import io.getquill.context.sql.encoding.ArrayEncoding -import io.getquill.util.Messages.fail - -import scala.reflect.ClassTag -import scala.collection.compat._ -import scala.jdk.CollectionConverters._ - -trait ArrayDecoders extends ArrayEncoding { - self: PostgresJAsyncContext[_] => - - implicit def arrayStringDecoder[Col <: Seq[String]](implicit bf: CBF[String, Col]): Decoder[Col] = - arrayRawDecoder[String, Col] - implicit def arrayBigDecimalDecoder[Col <: Seq[BigDecimal]](implicit bf: CBF[BigDecimal, Col]): Decoder[Col] = - arrayDecoder[java.math.BigDecimal, BigDecimal, Col](BigDecimal.javaBigDecimal2bigDecimal) - implicit def arrayBooleanDecoder[Col <: Seq[Boolean]](implicit bf: CBF[Boolean, Col]): Decoder[Col] = - arrayRawDecoder[Boolean, Col] - implicit def arrayByteDecoder[Col <: Seq[Byte]](implicit bf: CBF[Byte, Col]): Decoder[Col] = - arrayDecoder[Short, Byte, Col](_.toByte) - implicit def arrayShortDecoder[Col <: Seq[Short]](implicit bf: CBF[Short, Col]): Decoder[Col] = - arrayRawDecoder[Short, Col] - implicit def arrayIntDecoder[Col <: Seq[Index]](implicit bf: CBF[Index, Col]): Decoder[Col] = - arrayRawDecoder[Index, Col] - implicit def arrayLongDecoder[Col <: Seq[Long]](implicit bf: CBF[Long, Col]): Decoder[Col] = - arrayRawDecoder[Long, Col] - implicit def arrayFloatDecoder[Col <: Seq[Float]](implicit bf: CBF[Float, Col]): Decoder[Col] = - arrayDecoder[Double, Float, Col](_.toFloat) - implicit def arrayDoubleDecoder[Col <: Seq[Double]](implicit bf: CBF[Double, Col]): Decoder[Col] = - arrayRawDecoder[Double, Col] - implicit def arrayDateDecoder[Col <: Seq[Date]](implicit bf: CBF[Date, Col]): Decoder[Col] = - arrayDecoder[LocalDateTime, Date, Col](d => Date.from(d.atZone(ZoneId.systemDefault()).toInstant)) - implicit def arrayLocalDateDecoder[Col <: Seq[LocalDate]](implicit bf: CBF[LocalDate, Col]): Decoder[Col] = - arrayRawDecoder[LocalDate, Col] - implicit def arrayLocalDateTimeDecoder[Col <: Seq[LocalDateTime]](implicit - bf: CBF[LocalDateTime, Col] - ): Decoder[Col] = arrayRawDecoder[LocalDateTime, Col] - - def arrayDecoder[I, O, Col <: Seq[O]]( - mapper: I => O - )(implicit bf: CBF[O, Col], iTag: ClassTag[I], oTag: ClassTag[O]): Decoder[Col] = - AsyncDecoder[Col](SqlTypes.ARRAY)(new BaseDecoder[Col] { - def apply(index: Index, row: ResultRow, session: Session): Col = row.get(index) match { - case seq: util.ArrayList[_] => - seq.asScala - .foldLeft(bf.newBuilder) { - case (b, x: I) => b += mapper(x) - case (_, x) => - fail(s"Array at index $index contains element of ${x.getClass.getCanonicalName}, but expected $iTag") - } - .result() - case value => - fail( - s"Value '$value' at index $index is not an array so it cannot be decoded to collection of $oTag" - ) - } - }) - - def arrayRawDecoder[T: ClassTag, Col <: Seq[T]](implicit bf: CBF[T, Col]): Decoder[Col] = - arrayDecoder[T, T, Col](identity) -} diff --git a/quill-jasync-postgres/src/main/scala/io/getquill/context/jasync/ArrayEncoders.scala b/quill-jasync-postgres/src/main/scala/io/getquill/context/jasync/ArrayEncoders.scala deleted file mode 100644 index f05b33898f..0000000000 --- a/quill-jasync-postgres/src/main/scala/io/getquill/context/jasync/ArrayEncoders.scala +++ /dev/null @@ -1,30 +0,0 @@ -package io.getquill.context.jasync - -import java.time.{LocalDate, LocalDateTime, OffsetDateTime} -import java.util.Date -import io.getquill.PostgresJAsyncContext -import io.getquill.context.sql.encoding.ArrayEncoding - -trait ArrayEncoders extends ArrayEncoding { - self: PostgresJAsyncContext[_] => - - implicit def arrayStringEncoder[Col <: Seq[String]]: Encoder[Col] = arrayRawEncoder[String, Col] - implicit def arrayBigDecimalEncoder[Col <: Seq[BigDecimal]]: Encoder[Col] = arrayRawEncoder[BigDecimal, Col] - implicit def arrayBooleanEncoder[Col <: Seq[Boolean]]: Encoder[Col] = arrayRawEncoder[Boolean, Col] - implicit def arrayByteEncoder[Col <: Seq[Byte]]: Encoder[Col] = arrayRawEncoder[Byte, Col] - implicit def arrayShortEncoder[Col <: Seq[Short]]: Encoder[Col] = arrayRawEncoder[Short, Col] - implicit def arrayIntEncoder[Col <: Seq[Index]]: Encoder[Col] = arrayRawEncoder[Index, Col] - implicit def arrayLongEncoder[Col <: Seq[Long]]: Encoder[Col] = arrayRawEncoder[Long, Col] - implicit def arrayFloatEncoder[Col <: Seq[Float]]: Encoder[Col] = arrayRawEncoder[Float, Col] - implicit def arrayDoubleEncoder[Col <: Seq[Double]]: Encoder[Col] = arrayRawEncoder[Double, Col] - implicit def arrayDateEncoder[Col <: Seq[Date]]: Encoder[Col] = - arrayEncoder[Date, Col](date => OffsetDateTime.ofInstant(date.toInstant, dateTimeZone).toLocalDateTime) - implicit def arrayLocalDateEncoder[Col <: Seq[LocalDate]]: Encoder[Col] = arrayRawEncoder[LocalDate, Col] - implicit def arrayLocalDateTimeEncoder[Col <: Seq[LocalDateTime]]: Encoder[Col] = arrayRawEncoder[LocalDateTime, Col] - - def arrayEncoder[T, Col <: Seq[T]](mapper: T => Any): Encoder[Col] = - encoder[Col]((col: Col) => col.toIndexedSeq.map(mapper).mkString("{", ",", "}"), SqlTypes.ARRAY) - - def arrayRawEncoder[T, Col <: Seq[T]]: Encoder[Col] = arrayEncoder[T, Col](identity) - -} diff --git a/quill-jasync-postgres/src/test/resources/application.conf b/quill-jasync-postgres/src/test/resources/application.conf deleted file mode 100644 index 6c63a92b62..0000000000 --- a/quill-jasync-postgres/src/test/resources/application.conf +++ /dev/null @@ -1,5 +0,0 @@ -testPostgresDB.host=${?POSTGRES_HOST} -testPostgresDB.port=${?POSTGRES_PORT} -testPostgresDB.username=postgres -testPostgresDB.password=${?POSTGRES_PASSWORD} -testPostgresDB.database=quill_test \ No newline at end of file diff --git a/quill-jasync-postgres/src/test/scala/io/getquill/PostgresJAsyncContextConfigSpec.scala b/quill-jasync-postgres/src/test/scala/io/getquill/PostgresJAsyncContextConfigSpec.scala deleted file mode 100644 index 1c918db5b6..0000000000 --- a/quill-jasync-postgres/src/test/scala/io/getquill/PostgresJAsyncContextConfigSpec.scala +++ /dev/null @@ -1,33 +0,0 @@ -package io.getquill - -import java.io.File -import com.github.jasync.sql.db.SSLConfiguration -import com.github.jasync.sql.db.SSLConfiguration.Mode -import com.typesafe.config.{ConfigFactory, ConfigValueFactory} -import io.getquill.base.Spec - -class PostgresJAsyncContextConfigSpec extends Spec { - - "parses ssl config" in { - val config = ConfigFactory - .empty() - .withValue("user", ConfigValueFactory.fromAnyRef("user")) - .withValue("port", ConfigValueFactory.fromAnyRef(5432)) - .withValue("host", ConfigValueFactory.fromAnyRef("host")) - .withValue("sslmode", ConfigValueFactory.fromAnyRef("require")) - .withValue( - "sslrootcert", - ConfigValueFactory.fromAnyRef("./server-ca.crt") - ) - .withValue("sslcert", ConfigValueFactory.fromAnyRef("./client-cert.pem")) - .withValue("sslkey", ConfigValueFactory.fromAnyRef("./client-key.pk8")) - - val context = new PostgresJAsyncContextConfig(config) - context.connectionPoolConfiguration.getSsl mustEqual new SSLConfiguration( - Mode.Require, - new File("./server-ca.crt"), - new File("./client-cert.pem"), - new File("./client-key.pk8") - ) - } -} diff --git a/quill-jasync-postgres/src/test/scala/io/getquill/TypeParamExtensionTest.scala b/quill-jasync-postgres/src/test/scala/io/getquill/TypeParamExtensionTest.scala deleted file mode 100644 index b34e82a454..0000000000 --- a/quill-jasync-postgres/src/test/scala/io/getquill/TypeParamExtensionTest.scala +++ /dev/null @@ -1,14 +0,0 @@ -package io.getquill - -import io.getquill.context.Context - -// Testing we are passing type params explicitly into AsyncContext, otherwise -// this file will fail to compile - -trait BaseExtensions { - val context: Context[PostgresDialect, _] -} - -trait AsyncExtensions extends BaseExtensions { - override val context: PostgresJAsyncContext[_] -} diff --git a/quill-jasync-postgres/src/test/scala/io/getquill/context/jasync/postgres/ArrayAsyncEncodingSpec.scala b/quill-jasync-postgres/src/test/scala/io/getquill/context/jasync/postgres/ArrayAsyncEncodingSpec.scala deleted file mode 100644 index faa477bb53..0000000000 --- a/quill-jasync-postgres/src/test/scala/io/getquill/context/jasync/postgres/ArrayAsyncEncodingSpec.scala +++ /dev/null @@ -1,132 +0,0 @@ -package io.getquill.context.jasync.postgres - -import io.getquill.context.sql.EncodingTestType -import io.getquill.context.sql.encoding.ArrayEncodingBaseSpec - -import java.time.temporal.ChronoUnit -import java.time.{LocalDate, LocalDateTime} -import java.util.{Date, UUID} - -class ArrayAsyncEncodingSpec extends ArrayEncodingBaseSpec { - import scala.concurrent.ExecutionContext.Implicits.global - - private val ctx = testContext - import ctx._ - - private val q = quote(query[ArraysTestEntity]) - - "Support all sql base types and `Iterable` implementers" in { - await(ctx.run(q.insertValue(lift(e)))) - val actual = await(ctx.run(q)).head - actual mustEqual e - baseEntityDeepCheck(actual, e) - } - - "Java8 times" in { - case class Java8Times(timestamps: Seq[LocalDateTime], dates: Seq[LocalDate]) - // See https://stackoverflow.com/a/74781779/2431728 - val jE = Java8Times(Seq(LocalDateTime.now().truncatedTo(ChronoUnit.MICROS)), Seq(LocalDate.now())) - val jQ = quote(querySchema[Java8Times]("ArraysTestEntity")) - await(ctx.run(jQ.insertValue(lift(jE)))) - val actual = await(ctx.run(jQ)).head - actual.timestamps mustBe jE.timestamps - actual.dates mustBe jE.dates - } - - "Support Iterable encoding basing on MappedEncoding" in { - val wrapQ = quote(querySchema[WrapEntity]("ArraysTestEntity")) - await(ctx.run(wrapQ.insertValue(lift(wrapE)))) - await(ctx.run(wrapQ)).head mustBe wrapE - } - - "Arrays in where clause" in { - await(ctx.run(q.insertValue(lift(e)))) - val actual1 = await(ctx.run(q.filter(_.texts == lift(List("test"))))) - val actual2 = await(ctx.run(q.filter(_.texts == lift(List("test2"))))) - baseEntityDeepCheck(actual1.head, e) - actual1 mustEqual List(e) - actual2 mustEqual List.empty - } - - // Need to have an actual value in the table in order for the decoder to go off. Previously, - // there was guaranteed to be information there due to ordering of build artifacts but not anymore. - "fail if found not an array" in { - case class RealEncodingTestEntity( - v1: String, - v2: BigDecimal, - v3: Boolean, - v4: Byte, - v5: Short, - v6: Int, - v7: Long, - v8: Float, - v9: Double, - v10: Array[Byte], - v11: Date, - v12: EncodingTestType, - v13: LocalDate, - v14: UUID, - o1: Option[String], - o2: Option[BigDecimal], - o3: Option[Boolean], - o4: Option[Byte], - o5: Option[Short], - o6: Option[Int], - o7: Option[Long], - o8: Option[Float], - o9: Option[Double], - o10: Option[Array[Byte]], - o11: Option[Date], - o12: Option[EncodingTestType], - o13: Option[LocalDate], - o14: Option[UUID], - o15: Option[io.getquill.context.sql.Number] - ) - - val insertValue = - RealEncodingTestEntity( - "s", - BigDecimal(1.1), - true, - 11.toByte, - 23.toShort, - 33, - 431L, - 34.4f, - 42d, - Array(1.toByte, 2.toByte), - new Date(31200000), - EncodingTestType("s"), - LocalDate.of(2013, 11, 23), - UUID.randomUUID(), - Some("s"), - Some(BigDecimal(1.1)), - Some(true), - Some(11.toByte), - Some(23.toShort), - Some(33), - Some(431L), - Some(34.4f), - Some(42d), - Some(Array(1.toByte, 2.toByte)), - Some(new Date(31200000)), - Some(EncodingTestType("s")), - Some(LocalDate.of(2013, 11, 23)), - Some(UUID.randomUUID()), - Some(io.getquill.context.sql.Number("0")) - ) - - val realEntity = quote { - querySchema[RealEncodingTestEntity]("EncodingTestEntity") - } - await(ctx.run(realEntity.insertValue(lift(insertValue)))) - - case class EncodingTestEntity(v1: List[String]) - intercept[IllegalStateException](await(ctx.run(query[EncodingTestEntity]))) - } - - override protected def beforeEach(): Unit = { - await(ctx.run(q.delete)) - () - } -} diff --git a/quill-jasync-postgres/src/test/scala/io/getquill/context/jasync/postgres/ArrayOpsAsyncSpec.scala b/quill-jasync-postgres/src/test/scala/io/getquill/context/jasync/postgres/ArrayOpsAsyncSpec.scala deleted file mode 100644 index e01b92e462..0000000000 --- a/quill-jasync-postgres/src/test/scala/io/getquill/context/jasync/postgres/ArrayOpsAsyncSpec.scala +++ /dev/null @@ -1,24 +0,0 @@ -package io.getquill.context.jasync.postgres - -import io.getquill.context.sql.base.ArrayOpsSpec -import scala.concurrent.ExecutionContext.Implicits.global - -class ArrayOpsAsyncSpec extends ArrayOpsSpec { - val ctx = testContext - - import ctx._ - - "contains" in { - await(ctx.run(`contains`.`Ex 1 return all`)) mustBe `contains`.`Ex 1 expected` - await(ctx.run(`contains`.`Ex 2 return 1`)) mustBe `contains`.`Ex 2 expected` - await(ctx.run(`contains`.`Ex 3 return 2,3`)) mustBe `contains`.`Ex 3 expected` - await(ctx.run(`contains`.`Ex 4 return empty`)) mustBe `contains`.`Ex 4 expected` - } - - override protected def beforeAll(): Unit = { - await(ctx.run(entity.delete)) - await(ctx.run(insertEntries)) - () - } - -} diff --git a/quill-jasync-postgres/src/test/scala/io/getquill/context/jasync/postgres/CaseClassQueryAsyncSpec.scala b/quill-jasync-postgres/src/test/scala/io/getquill/context/jasync/postgres/CaseClassQueryAsyncSpec.scala deleted file mode 100644 index 068b58cd78..0000000000 --- a/quill-jasync-postgres/src/test/scala/io/getquill/context/jasync/postgres/CaseClassQueryAsyncSpec.scala +++ /dev/null @@ -1,51 +0,0 @@ -package io.getquill.context.jasync.postgres - -import io.getquill.context.sql.base.CaseClassQuerySpec -import scala.concurrent.ExecutionContext.Implicits.{global => ec} -import org.scalatest.matchers.should.Matchers._ - -class CaseClassQueryAsyncSpec extends CaseClassQuerySpec { - - val context = testContext - import testContext._ - - override def beforeAll = - await { - testContext.transaction { implicit ec => - for { - _ <- testContext.run(query[Contact].delete) - _ <- testContext.run(query[Address].delete) - _ <- testContext.run(liftQuery(peopleEntries).foreach(e => peopleInsert(e))) - _ <- testContext.run(liftQuery(addressEntries).foreach(e => addressInsert(e))) - } yield {} - } - } - - "Example 1 - Single Case Class Mapping" in { - await( - testContext.run(`Ex 1 CaseClass Record Output`) - ) should contain theSameElementsAs `Ex 1 CaseClass Record Output expected result` - } - "Example 1A - Single Case Class Mapping" in { - await( - testContext.run(`Ex 1A CaseClass Record Output`) - ) should contain theSameElementsAs `Ex 1 CaseClass Record Output expected result` - } - "Example 1B - Single Case Class Mapping" in { - await( - testContext.run(`Ex 1B CaseClass Record Output`) - ) should contain theSameElementsAs `Ex 1 CaseClass Record Output expected result` - } - - "Example 2 - Single Record Mapped Join" in { - await( - testContext.run(`Ex 2 Single-Record Join`) - ) should contain theSameElementsAs `Ex 2 Single-Record Join expected result` - } - - "Example 3 - Inline Record as Filter" in { - await( - testContext.run(`Ex 3 Inline Record Usage`) - ) should contain theSameElementsAs `Ex 3 Inline Record Usage expected result` - } -} diff --git a/quill-jasync-postgres/src/test/scala/io/getquill/context/jasync/postgres/DepartmentsPostgresAsyncSpec.scala b/quill-jasync-postgres/src/test/scala/io/getquill/context/jasync/postgres/DepartmentsPostgresAsyncSpec.scala deleted file mode 100644 index 35c61a8d32..0000000000 --- a/quill-jasync-postgres/src/test/scala/io/getquill/context/jasync/postgres/DepartmentsPostgresAsyncSpec.scala +++ /dev/null @@ -1,38 +0,0 @@ -package io.getquill.context.jasync.postgres - -import io.getquill.context.sql.base.DepartmentsSpec - -import scala.concurrent.ExecutionContext.Implicits.{global => ec} - -class DepartmentsPostgresAsyncSpec extends DepartmentsSpec { - - val context = testContext - import testContext._ - - override def beforeAll = - await { - testContext.transaction { implicit ec => - for { - _ <- testContext.run(query[Department].delete) - _ <- testContext.run(query[Employee].delete) - _ <- testContext.run(query[Task].delete) - - _ <- testContext.run(liftQuery(departmentEntries).foreach(e => departmentInsert(e))) - _ <- testContext.run(liftQuery(employeeEntries).foreach(e => employeeInsert(e))) - _ <- testContext.run(liftQuery(taskEntries).foreach(e => taskInsert(e))) - } yield {} - } - } - - "Example 8 - nested naive" in { - await(testContext.run(`Example 8 expertise naive`(lift(`Example 8 param`)))) mustEqual `Example 8 expected result` - } - - "Example 9 - nested db" in { - await(testContext.run(`Example 9 expertise`(lift(`Example 9 param`)))) mustEqual `Example 9 expected result` - } - - "performIO" in { - await(performIO(runIO(query[Task]).transactional)) - } -} diff --git a/quill-jasync-postgres/src/test/scala/io/getquill/context/jasync/postgres/OnConflictAsyncSpec.scala b/quill-jasync-postgres/src/test/scala/io/getquill/context/jasync/postgres/OnConflictAsyncSpec.scala deleted file mode 100644 index 9d2f0f856a..0000000000 --- a/quill-jasync-postgres/src/test/scala/io/getquill/context/jasync/postgres/OnConflictAsyncSpec.scala +++ /dev/null @@ -1,36 +0,0 @@ -package io.getquill.context.jasync.postgres - -import io.getquill.context.sql.base.OnConflictSpec -import scala.concurrent.ExecutionContext.Implicits.global - -class OnConflictAsyncSpec extends OnConflictSpec { - val ctx = testContext - import ctx._ - - override protected def beforeAll(): Unit = { - await(ctx.run(qr1.delete)) - () - } - - "ON CONFLICT DO NOTHING" in { - import `onConflictIgnore`._ - await(ctx.run(testQuery1)) mustEqual res1 - await(ctx.run(testQuery2)) mustEqual res2 - await(ctx.run(testQuery3)) mustEqual res3 - } - - "ON CONFLICT (i) DO NOTHING" in { - import `onConflictIgnore(_.i)`._ - await(ctx.run(testQuery1)) mustEqual res1 - await(ctx.run(testQuery2)) mustEqual res2 - await(ctx.run(testQuery3)) mustEqual res3 - } - - "ON CONFLICT (i) DO UPDATE ..." in { - import `onConflictUpdate(_.i)((t, e) => ...)`._ - await(ctx.run(testQuery(e1))) mustEqual res1 - await(ctx.run(testQuery(e2))) mustEqual res2 - await(ctx.run(testQuery(e3))) mustEqual res3 - await(ctx.run(testQuery4)) mustEqual res4 - } -} diff --git a/quill-jasync-postgres/src/test/scala/io/getquill/context/jasync/postgres/OptionalNestedAsyncSpec.scala b/quill-jasync-postgres/src/test/scala/io/getquill/context/jasync/postgres/OptionalNestedAsyncSpec.scala deleted file mode 100644 index bae7f18c5b..0000000000 --- a/quill-jasync-postgres/src/test/scala/io/getquill/context/jasync/postgres/OptionalNestedAsyncSpec.scala +++ /dev/null @@ -1,98 +0,0 @@ -package io.getquill.context.jasync.postgres - -import io.getquill.context.encoding.OptionalNestedSpec -import scala.concurrent.ExecutionContext.Implicits.{global => ec} - -class OptionalProductEncodingJasyncSpec extends OptionalNestedSpec { - - val context: testContext.type = testContext - import testContext._ - - override protected def beforeEach() = { - import Setup._ - await(testContext.run(query[Contact].delete)) - () - } - - "1.Optional Inner Product" - { - import `1.Optional Inner Product`._ - "1.Ex1 - Not null inner product" in { - await(context.run(`1.Ex1 - Not null inner product insert`)) - await(context.run(data)) mustEqual List(`1.Ex1 - Not null inner product result`) - } - "1.Ex1 Auto - Not null inner product" in { - val result = `1.Ex1 - Not null inner product result` - await(context.run(data.insertValue(lift(result)))) - await(context.run(data)) mustEqual List(result) - } - - "1.Ex2 - null inner product" in { - await(context.run(`1.Ex2 - null inner product insert`)) - // When doing getInt on a row that is null Jasync will actually throw an NPE. This more like idiomatic JVM behavior. - assertThrows[NullPointerException] { - await(context.run(data)) - } - } - "1.Ex2 Auto - null inner product" in { - val result = `1.Ex2 - null inner product result` - await(context.run(data.insertValue(lift(result)))) - await(context.run(data)) mustEqual List(result) - } - } - - "2.Optional Inner Product" - { - import `2.Optional Inner Product with Optional Leaf`._ - "2.Ex1 - Not null inner product" in { - await(context.run(`2.Ex1 - not-null insert`)) - await(context.run(data)) mustEqual List(`2.Ex1 - not-null result`) - } - "2.Ex1 Auto - Not null inner product" in { - val result = `2.Ex1 - not-null result` - await(context.run(data.insertValue(lift(result)))) - await(context.run(data)) mustEqual List(result) - } - - "2.Ex2 - Not null inner product" in { - await(context.run(`2.Ex2 - Null inner product insert`)) - await(context.run(data)) mustEqual List(`2.Ex2 - Null inner product result`) - } - "2.Ex2 Auto - Not null inner product" in { - val result = `2.Ex2 - Null inner product result` - await(context.run(data.insertValue(lift(result)))) - await(context.run(data)) mustEqual List(result) - } - - "2.Ex3 - Null inner leaf" in { - await(context.run(`2.Ex3 - Null inner leaf insert`)) - await(context.run(data)) mustEqual List(`2.Ex3 - Null inner leaf result`) - } - "2.Ex3 Auto - Null inner leaf" in { - val result = `2.Ex3 - Null inner leaf result` - await(context.run(data.insertValue(lift(result)))) - await(context.run(data)) mustEqual List(result) - } - } - - "3.Optional Nested Inner Product" - { - import `3.Optional Nested Inner Product`._ - "3.Ex1 - Null inner product insert" in { - await(context.run(`3.Ex1 - Null inner product insert`)) - await(context.run(data)) mustEqual List(`3.Ex1 - Null inner product result`) - } - "3.Ex1 Auto - Null inner product insert" in { - val result = `3.Ex1 - Null inner product result` - await(context.run(data.insertValue(lift(result)))) - await(context.run(data)) mustEqual List(result) - } - - "3.Ex2 - Null inner leaf" in { - await(context.run(`3.Ex2 - Null inner leaf insert`)) - await(context.run(data)) mustEqual List(`3.Ex2 - Null inner leaf result`) - } - "3.Ex2 Auto - Null inner leaf" in { - val result = `3.Ex2 - Null inner leaf result` - await(context.run(data.insertValue(lift(result)))) - await(context.run(data)) mustEqual List(result) - } - } -} diff --git a/quill-jasync-postgres/src/test/scala/io/getquill/context/jasync/postgres/PeopleAsyncReturningSpec.scala b/quill-jasync-postgres/src/test/scala/io/getquill/context/jasync/postgres/PeopleAsyncReturningSpec.scala deleted file mode 100644 index 6a4fd28963..0000000000 --- a/quill-jasync-postgres/src/test/scala/io/getquill/context/jasync/postgres/PeopleAsyncReturningSpec.scala +++ /dev/null @@ -1,75 +0,0 @@ -package io.getquill.context.jasync.postgres - -import io.getquill.context.sql.base.PeopleReturningSpec -import scala.concurrent.ExecutionContext.Implicits.{global => ec} - -class PeopleAsyncReturningSpec extends PeopleReturningSpec { - - val context: testContext.type = testContext - - import testContext._ - - override def beforeEach(): Unit = { - await { - testContext.transaction { implicit ec => - for { - _ <- testContext.run(query[Contact].delete) - _ <- testContext.run(query[Product].delete) - _ <- testContext.run(liftQuery(people).foreach(p => peopleInsert(p))) - } yield () - } - } - super.beforeEach() - } - - "Ex 0 insert.returning(_.generatedColumn) mod" in { - import `Ex 0 insert.returning(_.generatedColumn) mod`._ - await(for { - id <- testContext.run(op) - output <- testContext.run(get) - } yield (output.toSet mustEqual result(id).toSet)) - } - - "Ex 0.5 insert.returning(wholeRecord) mod" in { - import `Ex 0.5 insert.returning(wholeRecord) mod`._ - await(for { - product <- testContext.run(op) - output <- testContext.run(get) - } yield (output mustEqual result(product))) - } - - "Ex 1 insert.returningMany(_.generatedColumn) mod" in { - import `Ex 1 insert.returningMany(_.generatedColumn) mod`._ - await(for { - id <- testContext.run(op) - output <- testContext.run(get) - } yield (output mustEqual result(id.head))) - } - - "Ex 2 update.returningMany(_.singleColumn) mod" in { - import `Ex 2 update.returningMany(_.singleColumn) mod`._ - await(for { - opResult <- testContext.run(op) - _ = opResult.toSet mustEqual expect.toSet - output <- testContext.run(get) - } yield (output.toSet mustEqual result.toSet)) - } - - "Ex 3 delete.returningMany(wholeRecord)" in { - import `Ex 3 delete.returningMany(wholeRecord)`._ - await(for { - opResult <- testContext.run(op) - _ = opResult.toSet mustEqual expect.toSet - output <- testContext.run(get) - } yield (output.toSet mustEqual result.toSet)) - } - - "Ex 4 update.returningMany(query)" in { - import `Ex 4 update.returningMany(query)`._ - await(for { - opResult <- testContext.run(op) - _ = opResult.toSet mustEqual expect.toSet - output <- testContext.run(get) - } yield (output.toSet mustEqual result.toSet)) - } -} diff --git a/quill-jasync-postgres/src/test/scala/io/getquill/context/jasync/postgres/PeoplePostgresAsyncSpec.scala b/quill-jasync-postgres/src/test/scala/io/getquill/context/jasync/postgres/PeoplePostgresAsyncSpec.scala deleted file mode 100644 index c8dba02034..0000000000 --- a/quill-jasync-postgres/src/test/scala/io/getquill/context/jasync/postgres/PeoplePostgresAsyncSpec.scala +++ /dev/null @@ -1,61 +0,0 @@ -package io.getquill.context.jasync.postgres - -import io.getquill.context.sql.base.PeopleSpec - -import scala.concurrent.ExecutionContext.Implicits.{global => ec} - -class PeoplePostgresAsyncSpec extends PeopleSpec { - - val context = testContext - import testContext._ - - override def beforeAll = - await { - testContext.transaction { implicit ec => - for { - _ <- testContext.run(query[Couple].delete) - _ <- testContext.run(query[Person].delete) - _ <- testContext.run(liftQuery(peopleEntries).foreach(e => peopleInsert(e))) - _ <- testContext.run(liftQuery(couplesEntries).foreach(e => couplesInsert(e))) - } yield {} - } - } - - "Example 1 - differences" in { - await(testContext.run(`Ex 1 differences`)) mustEqual `Ex 1 expected result` - } - - "Example 2 - range simple" in { - await( - testContext.run(`Ex 2 rangeSimple`(lift(`Ex 2 param 1`), lift(`Ex 2 param 2`))) - ) mustEqual `Ex 2 expected result` - } - - "Examples 3 - satisfies" in { - await(testContext.run(`Ex 3 satisfies`)) mustEqual `Ex 3 expected result` - } - - "Examples 4 - satisfies" in { - await(testContext.run(`Ex 4 satisfies`)) mustEqual `Ex 4 expected result` - } - - "Example 5 - compose" in { - await(testContext.run(`Ex 5 compose`(lift(`Ex 5 param 1`), lift(`Ex 5 param 2`)))) mustEqual `Ex 5 expected result` - } - - "Example 6 - predicate 0" in { - await(testContext.run(satisfies(eval(`Ex 6 predicate`)))) mustEqual `Ex 6 expected result` - } - - "Example 7 - predicate 1" in { - await(testContext.run(satisfies(eval(`Ex 7 predicate`)))) mustEqual `Ex 7 expected result` - } - - "Example 8 - contains empty" in { - await(testContext.run(`Ex 8 and 9 contains`(liftQuery(`Ex 8 param`)))) mustEqual `Ex 8 expected result` - } - - "Example 9 - contains non empty" in { - await(testContext.run(`Ex 8 and 9 contains`(liftQuery(`Ex 9 param`)))) mustEqual `Ex 9 expected result` - } -} diff --git a/quill-jasync-postgres/src/test/scala/io/getquill/context/jasync/postgres/PostgresAsyncEncodingSpec.scala b/quill-jasync-postgres/src/test/scala/io/getquill/context/jasync/postgres/PostgresAsyncEncodingSpec.scala deleted file mode 100644 index 8c2c51f64b..0000000000 --- a/quill-jasync-postgres/src/test/scala/io/getquill/context/jasync/postgres/PostgresAsyncEncodingSpec.scala +++ /dev/null @@ -1,122 +0,0 @@ -package io.getquill.context.jasync.postgres - -import java.time.{LocalDate, LocalDateTime} -import io.getquill.context.sql.EncodingSpec - -import scala.concurrent.ExecutionContext.Implicits.global -import scala.concurrent.Await -import scala.concurrent.duration.Duration -import java.util.Date -import java.util.UUID -import io.getquill.Query - -import java.time.temporal.ChronoUnit - -class PostgresAsyncEncodingSpec extends EncodingSpec { - - val context = testContext - import testContext._ - - "encodes and decodes types" in { - val r = - for { - _ <- testContext.run(delete) - _ <- testContext.run(liftQuery(insertValues).foreach(e => insert(e))) - result <- testContext.run(query[EncodingTestEntity]) - } yield result - - verify(Await.result(r, Duration.Inf)) - } - - "encodes and decodes uuids" in { - case class EncodingUUIDTestEntity(v1: UUID) - val testUUID = UUID.fromString("e5240c08-6ee7-474a-b5e4-91f79c48338f") - - // delete old values - val q0 = quote(query[EncodingUUIDTestEntity].delete) - val rez0 = Await.result(testContext.run(q0), Duration.Inf) - - // insert new uuid - val rez1 = Await.result( - testContext.run(query[EncodingUUIDTestEntity].insertValue(lift(EncodingUUIDTestEntity(testUUID)))), - Duration.Inf - ) - - // verify you can get the uuid back from the db - val q2 = quote(query[EncodingUUIDTestEntity].map(p => p.v1)) - val rez2 = Await.result(testContext.run(q2), Duration.Inf) - - rez2 mustEqual List(testUUID) - } - - "fails if the column has the wrong type" - { - "numeric" in { - Await.result(testContext.run(liftQuery(insertValues).foreach(e => insert(e))), Duration.Inf) - case class EncodingTestEntity(v1: Int) - val e = intercept[IllegalStateException] { - Await.result(testContext.run(query[EncodingTestEntity]), Duration.Inf) - } - } - "non-numeric" in { - Await.result(testContext.run(liftQuery(insertValues).foreach(e => insert(e))), Duration.Inf) - case class EncodingTestEntity(v1: Date) - val e = intercept[IllegalStateException] { - Await.result(testContext.run(query[EncodingTestEntity]), Duration.Inf) - } - } - } - - "encodes sets" in { - val q = quote { (set: Query[Int]) => - query[EncodingTestEntity].filter(t => set.contains(t.v6)) - } - val fut = - for { - _ <- testContext.run(query[EncodingTestEntity].delete) - _ <- testContext.run(liftQuery(insertValues).foreach(e => query[EncodingTestEntity].insertValue(e))) - r <- testContext.run(q(liftQuery(insertValues.map(_.v6)))) - } yield { - r - } - verify(Await.result(fut, Duration.Inf)) - } - - "returning UUID" in { - val success = for { - uuid <- Await.result(testContext.run(insertBarCode(lift(barCodeEntry))), Duration.Inf) - barCode <- Await.result(testContext.run(findBarCodeByUuid(uuid)), Duration.Inf).headOption - } yield { - verifyBarcode(barCode) - } - success must not be empty - } - - "decodes LocalDate and LocalDateTime types" in { - case class DateEncodingTestEntity(v1: LocalDate, v2: LocalDateTime) - val entity = DateEncodingTestEntity( - LocalDate.now, - LocalDateTime.now.truncatedTo(ChronoUnit.MICROS) - ) // https://stackoverflow.com/a/74781779/2431728 - val r = for { - _ <- testContext.run(query[DateEncodingTestEntity].delete) - _ <- testContext.run(query[DateEncodingTestEntity].insertValue(lift(entity))) - result <- testContext.run(query[DateEncodingTestEntity]) - } yield result - Await.result(r, Duration.Inf) mustBe Seq(entity) - } - - "encodes custom type inside singleton object" in { - object Singleton { - def apply()(implicit c: TestContext) = { - import c._ - for { - _ <- c.run(query[EncodingTestEntity].delete) - result <- c.run(liftQuery(insertValues).foreach(e => query[EncodingTestEntity].insertValue(e))) - } yield result - } - } - - implicit val c = testContext - Await.result(Singleton(), Duration.Inf) - } -} diff --git a/quill-jasync-postgres/src/test/scala/io/getquill/context/jasync/postgres/PostgresJAsyncContextSpec.scala b/quill-jasync-postgres/src/test/scala/io/getquill/context/jasync/postgres/PostgresJAsyncContextSpec.scala deleted file mode 100644 index 5a1abec040..0000000000 --- a/quill-jasync-postgres/src/test/scala/io/getquill/context/jasync/postgres/PostgresJAsyncContextSpec.scala +++ /dev/null @@ -1,123 +0,0 @@ -package io.getquill.context.jasync.postgres - -import com.github.jasync.sql.db.{QueryResult, ResultSetKt} -import io.getquill.ReturnAction.ReturnColumns -import io.getquill.base.Spec -import io.getquill.{Literal, PostgresJAsyncContext, ReturnAction} - -import scala.concurrent.ExecutionContext.Implicits.global -import scala.concurrent.Future - -class PostgresJAsyncContextSpec extends Spec { - - import testContext._ - - "run non-batched action" in { - val insert = quote { (i: Int) => - qr1.insert(_.i -> i) - } - await(testContext.run(insert(lift(1)))) mustEqual 1 - } - - "Insert with returning with single column table" in { - val inserted: Long = await(testContext.run { - qr4.insertValue(lift(TestEntity4(0))).returningGenerated(_.i) - }) - await(testContext.run(qr4.filter(_.i == lift(inserted)))).head.i mustBe inserted - } - "Insert with returning with multiple columns" in { - await(testContext.run(qr1.delete)) - val inserted = await(testContext.run { - qr1.insertValue(lift(TestEntity("foo", 1, 18L, Some(123), true))).returning(r => (r.i, r.s, r.o)) - }) - (1, "foo", Some(123)) mustBe inserted - } - - "performIO" in { - await(performIO(runIO(qr4).transactional)) - } - - "probe" in { - probe("select 1").toOption mustBe defined - } - - "cannot extract" in { - object ctx extends PostgresJAsyncContext(Literal, "testPostgresDB") { - override def handleSingleResult[T](sql: String, list: List[T]) = super.handleSingleResult(sql, list) - - override def extractActionResult[O]( - returningAction: ReturnAction, - returningExtractor: ctx.Extractor[O] - )(result: QueryResult) = - super.extractActionResult(returningAction, returningExtractor)(result) - } - intercept[IllegalStateException] { - val v = ctx.extractActionResult(ReturnColumns(List("w/e")), (row, session) => 1)( - new QueryResult(0, "w/e", ResultSetKt.getEMPTY_RESULT_SET) - ) - ctx.handleSingleResult("", v) - } - ctx.close - } - - "prepare" in { - testContext.prepareParams( - "", - (ps, session) => (Nil, ps ++ List("Sarah", 127)) - ) mustEqual List("'Sarah'", "127") - } - - "provides transaction support" - { - "success" in { - await(for { - _ <- testContext.run(qr4.delete) - _ <- testContext.transaction { implicit ec => - testContext.run(qr4.insert(_.i -> 33)) - } - r <- testContext.run(qr4) - } yield r).map(_.i) mustEqual List(33) - } - "failure" in { - await(for { - _ <- testContext.run(qr4.delete) - e <- testContext.transaction { implicit ec => - Future.sequence( - Seq( - testContext.run(qr4.insert(_.i -> 18)), - Future(throw new IllegalStateException) - ) - ) - }.recoverWith { case e: Exception => - Future(e.getClass.getSimpleName) - } - r <- testContext.run(qr4) - } yield (e, r.isEmpty)) mustEqual (("CompletionException", true)) - } - "nested" in { - await(for { - _ <- testContext.run(qr4.delete) - _ <- testContext.transaction { implicit ec => - testContext.transaction { implicit ec => - testContext.run(qr4.insert(_.i -> 33)) - } - } - r <- testContext.run(qr4) - } yield r).map(_.i) mustEqual List(33) - } - "nested transactions use the same connection" in { - await(for { - e <- testContext.transaction { implicit ec => - val externalConn = ec.conn - testContext.transaction { implicit ec => - Future(externalConn == ec.conn) - } - } - } yield e) mustEqual true - } - } - - override protected def beforeAll(): Unit = { - await(testContext.run(qr1.delete)) - () - } -} diff --git a/quill-jasync-postgres/src/test/scala/io/getquill/context/jasync/postgres/ProductPostgresAsyncSpec.scala b/quill-jasync-postgres/src/test/scala/io/getquill/context/jasync/postgres/ProductPostgresAsyncSpec.scala deleted file mode 100644 index 897e5faf93..0000000000 --- a/quill-jasync-postgres/src/test/scala/io/getquill/context/jasync/postgres/ProductPostgresAsyncSpec.scala +++ /dev/null @@ -1,97 +0,0 @@ -package io.getquill.context.jasync.postgres - -import scala.concurrent.Future -import scala.concurrent.ExecutionContext.Implicits.global - -import io.getquill.context.sql.ProductSpec -import io.getquill.context.sql.Id - -class ProductPostgresAsyncSpec extends ProductSpec { - - val context = testContext - import testContext._ - - override def beforeAll = { - await(testContext.run(quote(query[Product].delete))) - () - } - - "Product" - { - "Insert multiple products" in { - val inserted = - await(Future.sequence(productEntries.map(product => testContext.run(productInsert(lift(product)))))) - val product = await(testContext.run(productById(lift(inserted(2))))).head - product.description mustEqual productEntries(2).description - product.id mustEqual inserted(2) - } - "Single insert product" in { - val inserted = await(testContext.run(productSingleInsert)) - val product = await(testContext.run(productById(lift(inserted)))).head - product.description mustEqual "Window" - product.id mustEqual inserted - } - - "Single insert with inlined free variable" in { - val prd = Product(0L, "test1", 1L) - val inserted = await { - testContext.run { - product.insert(_.sku -> lift(prd.sku), _.description -> lift(prd.description)).returning(_.id) - } - } - val returnedProduct = await(testContext.run(productById(lift(inserted)))).head - returnedProduct.description mustEqual "test1" - returnedProduct.sku mustEqual 1L - returnedProduct.id mustEqual inserted - } - - "Single insert with free variable and explicit quotation" in { - val prd = Product(0L, "test2", 2L) - val q1 = quote { - product.insert(_.sku -> lift(prd.sku), _.description -> lift(prd.description)).returning(_.id) - } - val inserted = await(testContext.run(q1)) - val returnedProduct = await(testContext.run(productById(lift(inserted)))).head - returnedProduct.description mustEqual "test2" - returnedProduct.sku mustEqual 2L - returnedProduct.id mustEqual inserted - } - - "Single product insert with a method quotation" in { - val prd = Product(0L, "test3", 3L) - val inserted = await(testContext.run(productInsert(lift(prd)))) - val returnedProduct = await(testContext.run(productById(lift(inserted)))).head - returnedProduct.description mustEqual "test3" - returnedProduct.sku mustEqual 3L - returnedProduct.id mustEqual inserted - } - - "Single insert with value class" in { - case class Product(id: Id, description: String, sku: Long) - val prd = Product(Id(0L), "test2", 2L) - val q1 = quote { - query[Product].insert(_.sku -> lift(prd.sku), _.description -> lift(prd.description)).returning(_.id) - } - await(testContext.run(q1)) mustBe a[Id] - } - - "supports casts from string to number" - { - "toInt" in { - case class Product(id: Long, description: String, sku: Int) - val queried = await { - testContext.run { - query[Product].filter(_.sku == lift("1004").toInt) - } - }.head - queried.sku mustEqual 1004L - } - "toLong" in { - val queried = await { - testContext.run { - query[Product].filter(_.sku == lift("1004").toLong) - } - }.head - queried.sku mustEqual 1004L - } - } - } -} diff --git a/quill-jasync-postgres/src/test/scala/io/getquill/context/jasync/postgres/QueryResultTypePostgresAsyncSpec.scala b/quill-jasync-postgres/src/test/scala/io/getquill/context/jasync/postgres/QueryResultTypePostgresAsyncSpec.scala deleted file mode 100644 index a8e762ca17..0000000000 --- a/quill-jasync-postgres/src/test/scala/io/getquill/context/jasync/postgres/QueryResultTypePostgresAsyncSpec.scala +++ /dev/null @@ -1,106 +0,0 @@ -package io.getquill.context.jasync.postgres - -import io.getquill.context.sql.base.QueryResultTypeSpec - -import java.util.concurrent.ConcurrentLinkedQueue -import scala.jdk.CollectionConverters._ -import scala.concurrent.ExecutionContext.Implicits.global -import scala.math.BigDecimal.int2bigDecimal - -class QueryResultTypePostgresAsyncSpec extends QueryResultTypeSpec { - - val context = testContext - import testContext._ - - val insertedProducts = new ConcurrentLinkedQueue[Product] - - override def beforeAll = { - await(testContext.run(deleteAll)) - val ids = await(testContext.run(liftQuery(productEntries).foreach(e => productInsert(e)))) - val inserted = (ids zip productEntries).map { case (id, prod) => - prod.copy(id = id) - } - insertedProducts.addAll(inserted.asJava) - () - } - - def products = insertedProducts.asScala.toList - - "return list" - { - "select" in { - await(testContext.run(selectAll)) must contain theSameElementsAs (products) - } - "map" in { - await(testContext.run(map)) must contain theSameElementsAs (products.map(_.id)) - } - "filter" in { - await(testContext.run(filter)) must contain theSameElementsAs (products) - } - "withFilter" in { - await(testContext.run(withFilter)) must contain theSameElementsAs (products) - } - "sortBy" in { - await(testContext.run(sortBy)) must contain theSameElementsInOrderAs (products) - } - "take" in { - await(testContext.run(take)) must contain theSameElementsAs (products) - } - "drop" in { - await(testContext.run(drop)) must contain theSameElementsAs (products.drop(1)) - } - "++" in { - await(testContext.run(`++`)) must contain theSameElementsAs (products ++ products) - } - "unionAll" in { - await(testContext.run(unionAll)) must contain theSameElementsAs (products ++ products) - } - "union" in { - await(testContext.run(union)) must contain theSameElementsAs (products) - } - "join" in { - await(testContext.run(join)) must contain theSameElementsAs (products zip products) - } - "distinct" in { - await(testContext.run(distinct)) must contain theSameElementsAs (products.map(_.id).distinct) - } - } - - "return single result" - { - "min" - { - "some" in { - await(testContext.run(minExists)) mustEqual Some(products.map(_.sku).min) - } - "none" in { - await(testContext.run(minNonExists)) mustBe None - } - } - "max" - { - "some" in { - await(testContext.run(maxExists)) mustBe Some(products.map(_.sku).max) - } - "none" in { - await(testContext.run(maxNonExists)) mustBe None - } - } - "avg" - { - "some" in { - await(testContext.run(avgExists)) mustBe Some(BigDecimal(products.map(_.sku).sum) / products.size) - } - "none" in { - await(testContext.run(avgNonExists)) mustBe None - } - } - "size" in { - await(testContext.run(productSize)) mustEqual products.size - } - "parametrized size" in { - await(testContext.run(parametrizedSize(lift(10000)))) mustEqual 0 - } - "nonEmpty" in { - await(testContext.run(nonEmpty)) mustEqual true - } - "isEmpty" in { - await(testContext.run(isEmpty)) mustEqual false - } - } -} diff --git a/quill-jasync-postgres/src/test/scala/io/getquill/context/jasync/postgres/TestContext.scala b/quill-jasync-postgres/src/test/scala/io/getquill/context/jasync/postgres/TestContext.scala deleted file mode 100644 index 4de142bca1..0000000000 --- a/quill-jasync-postgres/src/test/scala/io/getquill/context/jasync/postgres/TestContext.scala +++ /dev/null @@ -1,10 +0,0 @@ -package io.getquill.context.jasync.postgres - -import io.getquill.context.sql.{TestDecoders, TestEncoders} -import io.getquill.{Literal, PostgresJAsyncContext, TestEntities} - -class TestContext - extends PostgresJAsyncContext(Literal, "testPostgresDB") - with TestEntities - with TestEncoders - with TestDecoders diff --git a/quill-jasync-postgres/src/test/scala/io/getquill/context/jasync/postgres/package.scala b/quill-jasync-postgres/src/test/scala/io/getquill/context/jasync/postgres/package.scala deleted file mode 100644 index da6ba04c56..0000000000 --- a/quill-jasync-postgres/src/test/scala/io/getquill/context/jasync/postgres/package.scala +++ /dev/null @@ -1,5 +0,0 @@ -package io.getquill.context.jasync - -package object postgres { - object testContext extends TestContext -} diff --git a/quill-jasync-zio-postgres/src/main/scala/io/getquill/context/qzio/PostgresJAsyncContextConfig.scala b/quill-jasync-zio-postgres/src/main/scala/io/getquill/context/qzio/PostgresJAsyncContextConfig.scala deleted file mode 100644 index 6e88f2b6b9..0000000000 --- a/quill-jasync-zio-postgres/src/main/scala/io/getquill/context/qzio/PostgresJAsyncContextConfig.scala +++ /dev/null @@ -1,9 +0,0 @@ -package io.getquill.context.qzio - -import com.github.jasync.sql.db.postgresql.PostgreSQLConnection -import com.github.jasync.sql.db.postgresql.pool.PostgreSQLConnectionFactory -import com.github.jasync.sql.db.postgresql.util.URLParser -import com.typesafe.config.Config - -case class PostgresJAsyncContextConfig(config: Config) - extends JAsyncContextConfig[PostgreSQLConnection](config, new PostgreSQLConnectionFactory(_), URLParser.INSTANCE) diff --git a/quill-jasync-zio-postgres/src/main/scala/io/getquill/context/qzio/PostgresZioJAsyncContext.scala b/quill-jasync-zio-postgres/src/main/scala/io/getquill/context/qzio/PostgresZioJAsyncContext.scala deleted file mode 100644 index bca502f162..0000000000 --- a/quill-jasync-zio-postgres/src/main/scala/io/getquill/context/qzio/PostgresZioJAsyncContext.scala +++ /dev/null @@ -1,32 +0,0 @@ -package io.getquill.context.qzio - -import com.github.jasync.sql.db.postgresql.PostgreSQLConnection -import com.github.jasync.sql.db.{QueryResult => DBQueryResult} -import io.getquill.ReturnAction.{ReturnColumns, ReturnNothing, ReturnRecord} -import io.getquill.context.qzio.jasync.{ArrayDecoders, ArrayEncoders} -import io.getquill.{NamingStrategy, PostgresDialect, ReturnAction} - -import scala.jdk.CollectionConverters._ - -class PostgresZioJAsyncContext[+N <: NamingStrategy](naming: N) - extends ZioJAsyncContext[PostgresDialect, N, PostgreSQLConnection](PostgresDialect, naming) - with ArrayEncoders - with ArrayDecoders - with UUIDObjectEncoding { - - override protected def extractActionResult[O](returningAction: ReturnAction, returningExtractor: Extractor[O])( - result: DBQueryResult - ): List[O] = - result.getRows.asScala.toList.map(row => returningExtractor(row, ())) - - override protected def expandAction(sql: String, returningAction: ReturnAction): String = - returningAction match { - // The Postgres dialect will create SQL that has a 'RETURNING' clause so we don't have to add one. - case ReturnRecord => s"$sql" - // The Postgres dialect will not actually use these below variants but in case we decide to plug - // in some other dialect into this context... - case ReturnColumns(columns) => s"$sql RETURNING ${columns.mkString(", ")}" - case ReturnNothing => s"$sql" - } - -} diff --git a/quill-jasync-zio-postgres/src/main/scala/io/getquill/context/qzio/jasync/ArrayDecoders.scala b/quill-jasync-zio-postgres/src/main/scala/io/getquill/context/qzio/jasync/ArrayDecoders.scala deleted file mode 100644 index f8c043a0f8..0000000000 --- a/quill-jasync-zio-postgres/src/main/scala/io/getquill/context/qzio/jasync/ArrayDecoders.scala +++ /dev/null @@ -1,65 +0,0 @@ -package io.getquill.context.qzio.jasync - -import io.getquill.context.qzio.{PostgresZioJAsyncContext, SqlTypes} -import io.getquill.context.sql.encoding.ArrayEncoding -import io.getquill.util.Messages.fail - -import java.time.{LocalDate, LocalDateTime, ZoneId} -import java.util -import java.util.Date -import scala.collection.compat._ -import scala.jdk.CollectionConverters._ -import scala.reflect.ClassTag - -trait ArrayDecoders extends ArrayEncoding { - self: PostgresZioJAsyncContext[_] => - - implicit def arrayStringDecoder[Col <: Seq[String]](implicit bf: CBF[String, Col]): Decoder[Col] = - arrayRawDecoder[String, Col] - implicit def arrayBigDecimalDecoder[Col <: Seq[BigDecimal]](implicit bf: CBF[BigDecimal, Col]): Decoder[Col] = - arrayDecoder[java.math.BigDecimal, BigDecimal, Col](BigDecimal.javaBigDecimal2bigDecimal) - implicit def arrayBooleanDecoder[Col <: Seq[Boolean]](implicit bf: CBF[Boolean, Col]): Decoder[Col] = - arrayRawDecoder[Boolean, Col] - implicit def arrayByteDecoder[Col <: Seq[Byte]](implicit bf: CBF[Byte, Col]): Decoder[Col] = - arrayDecoder[Short, Byte, Col](_.toByte) - implicit def arrayShortDecoder[Col <: Seq[Short]](implicit bf: CBF[Short, Col]): Decoder[Col] = - arrayRawDecoder[Short, Col] - implicit def arrayIntDecoder[Col <: Seq[Index]](implicit bf: CBF[Index, Col]): Decoder[Col] = - arrayRawDecoder[Index, Col] - implicit def arrayLongDecoder[Col <: Seq[Long]](implicit bf: CBF[Long, Col]): Decoder[Col] = - arrayRawDecoder[Long, Col] - implicit def arrayFloatDecoder[Col <: Seq[Float]](implicit bf: CBF[Float, Col]): Decoder[Col] = - arrayDecoder[Double, Float, Col](_.toFloat) - implicit def arrayDoubleDecoder[Col <: Seq[Double]](implicit bf: CBF[Double, Col]): Decoder[Col] = - arrayRawDecoder[Double, Col] - implicit def arrayDateDecoder[Col <: Seq[Date]](implicit bf: CBF[Date, Col]): Decoder[Col] = - arrayDecoder[LocalDateTime, Date, Col](d => Date.from(d.atZone(ZoneId.systemDefault()).toInstant)) - implicit def arrayLocalDateDecoder[Col <: Seq[LocalDate]](implicit bf: CBF[LocalDate, Col]): Decoder[Col] = - arrayRawDecoder[LocalDate, Col] - implicit def arrayLocalDateTimeDecoder[Col <: Seq[LocalDateTime]](implicit - bf: CBF[LocalDateTime, Col] - ): Decoder[Col] = arrayRawDecoder[LocalDateTime, Col] - - def arrayDecoder[I, O, Col <: Seq[O]]( - mapper: I => O - )(implicit bf: CBF[O, Col], iTag: ClassTag[I], oTag: ClassTag[O]): Decoder[Col] = - AsyncDecoder[Col](SqlTypes.ARRAY)(new BaseDecoder[Col] { - def apply(index: Index, row: ResultRow, session: Session): Col = row.get(index) match { - case seq: util.ArrayList[_] => - seq.asScala - .foldLeft(bf.newBuilder) { - case (b, x: I) => b += mapper(x) - case (_, x) => - fail(s"Array at index $index contains element of ${x.getClass.getCanonicalName}, but expected $iTag") - } - .result() - case value => - fail( - s"Value '$value' at index $index is not an array so it cannot be decoded to collection of $oTag" - ) - } - }) - - def arrayRawDecoder[T: ClassTag, Col <: Seq[T]](implicit bf: CBF[T, Col]): Decoder[Col] = - arrayDecoder[T, T, Col](identity) -} diff --git a/quill-jasync-zio-postgres/src/main/scala/io/getquill/context/qzio/jasync/ArrayEncoders.scala b/quill-jasync-zio-postgres/src/main/scala/io/getquill/context/qzio/jasync/ArrayEncoders.scala deleted file mode 100644 index 7fea21e84a..0000000000 --- a/quill-jasync-zio-postgres/src/main/scala/io/getquill/context/qzio/jasync/ArrayEncoders.scala +++ /dev/null @@ -1,31 +0,0 @@ -package io.getquill.context.qzio.jasync - -import io.getquill.context.qzio.{PostgresZioJAsyncContext, SqlTypes} - -import java.time.{LocalDate, LocalDateTime, OffsetDateTime} -import java.util.Date -import io.getquill.context.sql.encoding.ArrayEncoding - -trait ArrayEncoders extends ArrayEncoding { - self: PostgresZioJAsyncContext[_] => - - implicit def arrayStringEncoder[Col <: Seq[String]]: Encoder[Col] = arrayRawEncoder[String, Col] - implicit def arrayBigDecimalEncoder[Col <: Seq[BigDecimal]]: Encoder[Col] = arrayRawEncoder[BigDecimal, Col] - implicit def arrayBooleanEncoder[Col <: Seq[Boolean]]: Encoder[Col] = arrayRawEncoder[Boolean, Col] - implicit def arrayByteEncoder[Col <: Seq[Byte]]: Encoder[Col] = arrayRawEncoder[Byte, Col] - implicit def arrayShortEncoder[Col <: Seq[Short]]: Encoder[Col] = arrayRawEncoder[Short, Col] - implicit def arrayIntEncoder[Col <: Seq[Index]]: Encoder[Col] = arrayRawEncoder[Index, Col] - implicit def arrayLongEncoder[Col <: Seq[Long]]: Encoder[Col] = arrayRawEncoder[Long, Col] - implicit def arrayFloatEncoder[Col <: Seq[Float]]: Encoder[Col] = arrayRawEncoder[Float, Col] - implicit def arrayDoubleEncoder[Col <: Seq[Double]]: Encoder[Col] = arrayRawEncoder[Double, Col] - implicit def arrayDateEncoder[Col <: Seq[Date]]: Encoder[Col] = - arrayEncoder[Date, Col](date => OffsetDateTime.ofInstant(date.toInstant, dateTimeZone).toLocalDateTime) - implicit def arrayLocalDateEncoder[Col <: Seq[LocalDate]]: Encoder[Col] = arrayRawEncoder[LocalDate, Col] - implicit def arrayLocalDateTimeEncoder[Col <: Seq[LocalDateTime]]: Encoder[Col] = arrayRawEncoder[LocalDateTime, Col] - - def arrayEncoder[T, Col <: Seq[T]](mapper: T => Any): Encoder[Col] = - encoder[Col]((col: Col) => col.toIndexedSeq.map(mapper).mkString("{", ",", "}"), SqlTypes.ARRAY) - - def arrayRawEncoder[T, Col <: Seq[T]]: Encoder[Col] = arrayEncoder[T, Col](identity) - -} diff --git a/quill-jasync-zio-postgres/src/test/resources/application.conf b/quill-jasync-zio-postgres/src/test/resources/application.conf deleted file mode 100644 index 6c63a92b62..0000000000 --- a/quill-jasync-zio-postgres/src/test/resources/application.conf +++ /dev/null @@ -1,5 +0,0 @@ -testPostgresDB.host=${?POSTGRES_HOST} -testPostgresDB.port=${?POSTGRES_PORT} -testPostgresDB.username=postgres -testPostgresDB.password=${?POSTGRES_PASSWORD} -testPostgresDB.database=quill_test \ No newline at end of file diff --git a/quill-jasync-zio-postgres/src/test/resources/logback.xml b/quill-jasync-zio-postgres/src/test/resources/logback.xml deleted file mode 100644 index 3938c39719..0000000000 --- a/quill-jasync-zio-postgres/src/test/resources/logback.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n%ex - - - - - - - - - - - - diff --git a/quill-jasync-zio-postgres/src/test/scala/io/getquill/PostgresJAsyncContextConfigSpec.scala b/quill-jasync-zio-postgres/src/test/scala/io/getquill/PostgresJAsyncContextConfigSpec.scala deleted file mode 100644 index 6590727867..0000000000 --- a/quill-jasync-zio-postgres/src/test/scala/io/getquill/PostgresJAsyncContextConfigSpec.scala +++ /dev/null @@ -1,34 +0,0 @@ -package io.getquill - -import com.github.jasync.sql.db.SSLConfiguration -import com.github.jasync.sql.db.SSLConfiguration.Mode -import com.typesafe.config.{ConfigFactory, ConfigValueFactory} -import io.getquill.base.Spec -import io.getquill.context.qzio.PostgresJAsyncContextConfig - -import java.io.File - -class PostgresJAsyncContextConfigSpec extends Spec { - "parses ssl config" in { - val config = ConfigFactory - .empty() - .withValue("user", ConfigValueFactory.fromAnyRef("user")) - .withValue("port", ConfigValueFactory.fromAnyRef(5432)) - .withValue("host", ConfigValueFactory.fromAnyRef("host")) - .withValue("sslmode", ConfigValueFactory.fromAnyRef("require")) - .withValue( - "sslrootcert", - ConfigValueFactory.fromAnyRef("./server-ca.crt") - ) - .withValue("sslcert", ConfigValueFactory.fromAnyRef("./client-cert.pem")) - .withValue("sslkey", ConfigValueFactory.fromAnyRef("./client-key.pk8")) - - val context = new PostgresJAsyncContextConfig(config) - context.connectionPoolConfiguration.getSsl mustEqual new SSLConfiguration( - Mode.Require, - new File("./server-ca.crt"), - new File("./client-cert.pem"), - new File("./client-key.pk8") - ) - } -} diff --git a/quill-jasync-zio-postgres/src/test/scala/io/getquill/TypeParamExtensionTest.scala b/quill-jasync-zio-postgres/src/test/scala/io/getquill/TypeParamExtensionTest.scala deleted file mode 100644 index d80d437a65..0000000000 --- a/quill-jasync-zio-postgres/src/test/scala/io/getquill/TypeParamExtensionTest.scala +++ /dev/null @@ -1,15 +0,0 @@ -package io.getquill - -import io.getquill.context.Context -import io.getquill.context.qzio.PostgresZioJAsyncContext - -// Testing we are passing type params explicitly into AsyncContext, otherwise -// this file will fail to compile - -trait BaseExtensions { - val context: Context[PostgresDialect, _] -} - -trait AsyncExtensions extends BaseExtensions { - override val context: PostgresZioJAsyncContext[_] -} diff --git a/quill-jasync-zio-postgres/src/test/scala/io/getquill/context/qzio/jasync/postgres/ArrayOpsAsyncSpec.scala b/quill-jasync-zio-postgres/src/test/scala/io/getquill/context/qzio/jasync/postgres/ArrayOpsAsyncSpec.scala deleted file mode 100644 index 5a139e7c21..0000000000 --- a/quill-jasync-zio-postgres/src/test/scala/io/getquill/context/qzio/jasync/postgres/ArrayOpsAsyncSpec.scala +++ /dev/null @@ -1,21 +0,0 @@ -package io.getquill.context.qzio.jasync.postgres - -import io.getquill.context.sql.base.ArrayOpsSpec - -class ArrayOpsAsyncSpec extends ArrayOpsSpec with ZioSpec { - import context._ - - "contains" in { - runSyncUnsafe(context.run(`contains`.`Ex 1 return all`)) mustBe `contains`.`Ex 1 expected` - runSyncUnsafe(context.run(`contains`.`Ex 2 return 1`)) mustBe `contains`.`Ex 2 expected` - runSyncUnsafe(context.run(`contains`.`Ex 3 return 2,3`)) mustBe `contains`.`Ex 3 expected` - runSyncUnsafe(context.run(`contains`.`Ex 4 return empty`)) mustBe `contains`.`Ex 4 expected` - } - - override protected def beforeAll(): Unit = { - runSyncUnsafe(context.run(entity.delete)) - runSyncUnsafe(context.run(insertEntries)) - () - } - -} diff --git a/quill-jasync-zio-postgres/src/test/scala/io/getquill/context/qzio/jasync/postgres/CaseClassQueryAsyncSpec.scala b/quill-jasync-zio-postgres/src/test/scala/io/getquill/context/qzio/jasync/postgres/CaseClassQueryAsyncSpec.scala deleted file mode 100644 index 4d332cdc2f..0000000000 --- a/quill-jasync-zio-postgres/src/test/scala/io/getquill/context/qzio/jasync/postgres/CaseClassQueryAsyncSpec.scala +++ /dev/null @@ -1,49 +0,0 @@ -package io.getquill.context.qzio.jasync.postgres - -import io.getquill.context.sql.base.CaseClassQuerySpec -import org.scalatest.matchers.should.Matchers._ - -class CaseClassQueryAsyncSpec extends CaseClassQuerySpec with ZioSpec { - - import context._ - - override def beforeAll = - runSyncUnsafe { - context.transaction { - for { - _ <- context.run(query[Contact].delete) - _ <- context.run(query[Address].delete) - _ <- context.run(liftQuery(peopleEntries).foreach(e => peopleInsert(e))) - _ <- context.run(liftQuery(addressEntries).foreach(e => addressInsert(e))) - } yield {} - } - } - - "Example 1 - Single Case Class Mapping" in { - runSyncUnsafe( - context.run(`Ex 1 CaseClass Record Output`) - ) should contain theSameElementsAs `Ex 1 CaseClass Record Output expected result` - } - "Example 1A - Single Case Class Mapping" in { - runSyncUnsafe( - context.run(`Ex 1A CaseClass Record Output`) - ) should contain theSameElementsAs `Ex 1 CaseClass Record Output expected result` - } - "Example 1B - Single Case Class Mapping" in { - runSyncUnsafe( - context.run(`Ex 1B CaseClass Record Output`) - ) should contain theSameElementsAs `Ex 1 CaseClass Record Output expected result` - } - - "Example 2 - Single Record Mapped Join" in { - runSyncUnsafe( - context.run(`Ex 2 Single-Record Join`) - ) should contain theSameElementsAs `Ex 2 Single-Record Join expected result` - } - - "Example 3 - Inline Record as Filter" in { - runSyncUnsafe( - context.run(`Ex 3 Inline Record Usage`) - ) should contain theSameElementsAs `Ex 3 Inline Record Usage expected result` - } -} diff --git a/quill-jasync-zio-postgres/src/test/scala/io/getquill/context/qzio/jasync/postgres/DepartmentsPostgresAsyncSpec.scala b/quill-jasync-zio-postgres/src/test/scala/io/getquill/context/qzio/jasync/postgres/DepartmentsPostgresAsyncSpec.scala deleted file mode 100644 index c84a23438a..0000000000 --- a/quill-jasync-zio-postgres/src/test/scala/io/getquill/context/qzio/jasync/postgres/DepartmentsPostgresAsyncSpec.scala +++ /dev/null @@ -1,37 +0,0 @@ -package io.getquill.context.qzio.jasync.postgres - -import io.getquill.context.sql.base.DepartmentsSpec - -class DepartmentsPostgresAsyncSpec extends DepartmentsSpec with ZioSpec { - - import context._ - - override def beforeAll = - runSyncUnsafe { - context.transaction { - for { - _ <- context.run(query[Department].delete) - _ <- context.run(query[Employee].delete) - _ <- context.run(query[Task].delete) - - _ <- context.run(liftQuery(departmentEntries).foreach(e => departmentInsert(e))) - _ <- context.run(liftQuery(employeeEntries).foreach(e => employeeInsert(e))) - _ <- context.run(liftQuery(taskEntries).foreach(e => taskInsert(e))) - } yield {} - } - } - - "Example 8 - nested naive" in { - runSyncUnsafe( - testContext.run(`Example 8 expertise naive`(lift(`Example 8 param`))) - ) mustEqual `Example 8 expected result` - } - - "Example 9 - nested db" in { - runSyncUnsafe(testContext.run(`Example 9 expertise`(lift(`Example 9 param`)))) mustEqual `Example 9 expected result` - } - - "performIO" in { - runSyncUnsafe(performIO(runIO(query[Task]).transactional)) - } -} diff --git a/quill-jasync-zio-postgres/src/test/scala/io/getquill/context/qzio/jasync/postgres/OnConflictAsyncSpec.scala b/quill-jasync-zio-postgres/src/test/scala/io/getquill/context/qzio/jasync/postgres/OnConflictAsyncSpec.scala deleted file mode 100644 index fb97bec942..0000000000 --- a/quill-jasync-zio-postgres/src/test/scala/io/getquill/context/qzio/jasync/postgres/OnConflictAsyncSpec.scala +++ /dev/null @@ -1,35 +0,0 @@ -package io.getquill.context.qzio.jasync.postgres - -import io.getquill.context.sql.base.OnConflictSpec - -class OnConflictAsyncSpec extends OnConflictSpec with ZioSpec { - - import context._ - - override protected def beforeAll(): Unit = { - runSyncUnsafe(context.run(qr1.delete)) - () - } - - "ON CONFLICT DO NOTHING" in { - import `onConflictIgnore`._ - runSyncUnsafe(context.run(testQuery1)) mustEqual res1 - runSyncUnsafe(context.run(testQuery2)) mustEqual res2 - runSyncUnsafe(context.run(testQuery3)) mustEqual res3 - } - - "ON CONFLICT (i) DO NOTHING" in { - import `onConflictIgnore(_.i)`._ - runSyncUnsafe(context.run(testQuery1)) mustEqual res1 - runSyncUnsafe(context.run(testQuery2)) mustEqual res2 - runSyncUnsafe(context.run(testQuery3)) mustEqual res3 - } - - "ON CONFLICT (i) DO UPDATE ..." in { - import `onConflictUpdate(_.i)((t, e) => ...)`._ - runSyncUnsafe(context.run(testQuery(e1))) mustEqual res1 - runSyncUnsafe(context.run(testQuery(e2))) mustEqual res2 - runSyncUnsafe(context.run(testQuery(e3))) mustEqual res3 - runSyncUnsafe(context.run(testQuery4)) mustEqual res4 - } -} diff --git a/quill-jasync-zio-postgres/src/test/scala/io/getquill/context/qzio/jasync/postgres/PeopleAsyncReturningSpec.scala b/quill-jasync-zio-postgres/src/test/scala/io/getquill/context/qzio/jasync/postgres/PeopleAsyncReturningSpec.scala deleted file mode 100644 index 4d6a424f8a..0000000000 --- a/quill-jasync-zio-postgres/src/test/scala/io/getquill/context/qzio/jasync/postgres/PeopleAsyncReturningSpec.scala +++ /dev/null @@ -1,72 +0,0 @@ -package io.getquill.context.qzio.jasync.postgres - -import io.getquill.context.sql.base.PeopleReturningSpec - -class PeopleAsyncReturningSpec extends PeopleReturningSpec with ZioSpec { - - import context._ - - override def beforeEach(): Unit = { - runSyncUnsafe { - testContext.transaction { - for { - _ <- testContext.run(query[Contact].delete) - _ <- testContext.run(query[Product].delete) - _ <- testContext.run(liftQuery(people).foreach(p => peopleInsert(p))) - } yield () - } - } - super.beforeEach() - } - - "Ex 0 insert.returning(_.generatedColumn) mod" in { - import `Ex 0 insert.returning(_.generatedColumn) mod`._ - runSyncUnsafe(for { - id <- testContext.run(op) - output <- testContext.run(get) - } yield (output.toSet mustEqual result(id).toSet)) - } - - "Ex 0.5 insert.returning(wholeRecord) mod" in { - import `Ex 0.5 insert.returning(wholeRecord) mod`._ - runSyncUnsafe(for { - product <- testContext.run(op) - output <- testContext.run(get) - } yield (output mustEqual result(product))) - } - - "Ex 1 insert.returningMany(_.generatedColumn) mod" in { - import `Ex 1 insert.returningMany(_.generatedColumn) mod`._ - runSyncUnsafe(for { - id <- testContext.run(op) - output <- testContext.run(get) - } yield (output mustEqual result(id.head))) - } - - "Ex 2 update.returningMany(_.singleColumn) mod" in { - import `Ex 2 update.returningMany(_.singleColumn) mod`._ - runSyncUnsafe(for { - opResult <- testContext.run(op) - _ = opResult.toSet mustEqual expect.toSet - output <- testContext.run(get) - } yield (output.toSet mustEqual result.toSet)) - } - - "Ex 3 delete.returningMany(wholeRecord)" in { - import `Ex 3 delete.returningMany(wholeRecord)`._ - runSyncUnsafe(for { - opResult <- testContext.run(op) - _ = opResult.toSet mustEqual expect.toSet - output <- testContext.run(get) - } yield (output.toSet mustEqual result.toSet)) - } - - "Ex 4 update.returningMany(query)" in { - import `Ex 4 update.returningMany(query)`._ - runSyncUnsafe(for { - opResult <- testContext.run(op) - _ = opResult.toSet mustEqual expect.toSet - output <- testContext.run(get) - } yield (output.toSet mustEqual result.toSet)) - } -} diff --git a/quill-jasync-zio-postgres/src/test/scala/io/getquill/context/qzio/jasync/postgres/PeoplePostgresAsyncSpec.scala b/quill-jasync-zio-postgres/src/test/scala/io/getquill/context/qzio/jasync/postgres/PeoplePostgresAsyncSpec.scala deleted file mode 100644 index 38a2f013b4..0000000000 --- a/quill-jasync-zio-postgres/src/test/scala/io/getquill/context/qzio/jasync/postgres/PeoplePostgresAsyncSpec.scala +++ /dev/null @@ -1,60 +0,0 @@ -package io.getquill.context.qzio.jasync.postgres - -import io.getquill.context.sql.base.PeopleSpec - -class PeoplePostgresAsyncSpec extends PeopleSpec with ZioSpec { - - import context._ - - override def beforeAll = - runSyncUnsafe { - testContext.transaction { - for { - _ <- testContext.run(query[Couple].delete) - _ <- testContext.run(query[Person].delete) - _ <- testContext.run(liftQuery(peopleEntries).foreach(e => peopleInsert(e))) - _ <- testContext.run(liftQuery(couplesEntries).foreach(e => couplesInsert(e))) - } yield {} - } - } - - "Example 1 - differences" in { - runSyncUnsafe(testContext.run(`Ex 1 differences`)) mustEqual `Ex 1 expected result` - } - - "Example 2 - range simple" in { - runSyncUnsafe( - testContext.run(`Ex 2 rangeSimple`(lift(`Ex 2 param 1`), lift(`Ex 2 param 2`))) - ) mustEqual `Ex 2 expected result` - } - - "Examples 3 - satisfies" in { - runSyncUnsafe(testContext.run(`Ex 3 satisfies`)) mustEqual `Ex 3 expected result` - } - - "Examples 4 - satisfies" in { - runSyncUnsafe(testContext.run(`Ex 4 satisfies`)) mustEqual `Ex 4 expected result` - } - - "Example 5 - compose" in { - runSyncUnsafe( - testContext.run(`Ex 5 compose`(lift(`Ex 5 param 1`), lift(`Ex 5 param 2`))) - ) mustEqual `Ex 5 expected result` - } - - "Example 6 - predicate 0" in { - runSyncUnsafe(testContext.run(satisfies(eval(`Ex 6 predicate`)))) mustEqual `Ex 6 expected result` - } - - "Example 7 - predicate 1" in { - runSyncUnsafe(testContext.run(satisfies(eval(`Ex 7 predicate`)))) mustEqual `Ex 7 expected result` - } - - "Example 8 - contains empty" in { - runSyncUnsafe(testContext.run(`Ex 8 and 9 contains`(liftQuery(`Ex 8 param`)))) mustEqual `Ex 8 expected result` - } - - "Example 9 - contains non empty" in { - runSyncUnsafe(testContext.run(`Ex 8 and 9 contains`(liftQuery(`Ex 9 param`)))) mustEqual `Ex 9 expected result` - } -} diff --git a/quill-jasync-zio-postgres/src/test/scala/io/getquill/context/qzio/jasync/postgres/PostgresAsyncEncodingSpec.scala b/quill-jasync-zio-postgres/src/test/scala/io/getquill/context/qzio/jasync/postgres/PostgresAsyncEncodingSpec.scala deleted file mode 100644 index c9642d24de..0000000000 --- a/quill-jasync-zio-postgres/src/test/scala/io/getquill/context/qzio/jasync/postgres/PostgresAsyncEncodingSpec.scala +++ /dev/null @@ -1,111 +0,0 @@ -package io.getquill.context.qzio.jasync.postgres - -import java.time.{LocalDate, LocalDateTime} -import io.getquill.context.sql.EncodingSpec - -import java.util.Date -import java.util.UUID -import io.getquill.Query - -import java.time.temporal.ChronoUnit - -class PostgresAsyncEncodingSpec extends EncodingSpec with ZioSpec { - - import context._ - - "encodes and decodes types" in { - val r = - for { - _ <- context.run(delete) - _ <- context.run(liftQuery(insertValues).foreach(e => insert(e))) - result <- context.run(query[EncodingTestEntity]) - } yield result - - verify(runSyncUnsafe(r)) - } - - "encodes and decodes uuids" in { - case class EncodingUUIDTestEntity(v1: UUID) - val testUUID = UUID.fromString("e5240c08-6ee7-474a-b5e4-91f79c48338f") - - // delete old values - val q0 = quote(query[EncodingUUIDTestEntity].delete) - val rez0 = runSyncUnsafe(testContext.run(q0)) - - // insert new uuid - val rez1 = - runSyncUnsafe(testContext.run(query[EncodingUUIDTestEntity].insertValue(lift(EncodingUUIDTestEntity(testUUID))))) - - // verify you can get the uuid back from the db - val q2 = quote(query[EncodingUUIDTestEntity].map(p => p.v1)) - val rez2 = runSyncUnsafe(testContext.run(q2)) - - rez2 mustEqual List(testUUID) - } - - "fails if the column has the wrong type" - { - "numeric" in { - runSyncUnsafe(testContext.run(liftQuery(insertValues).foreach(e => insert(e)))) - case class EncodingTestEntity(v1: Int) - val e = intercept[IllegalStateException] { - runSyncUnsafe(testContext.run(query[EncodingTestEntity])) - } - } - "non-numeric" in { - runSyncUnsafe(testContext.run(liftQuery(insertValues).foreach(e => insert(e)))) - case class EncodingTestEntity(v1: Date) - val e = intercept[IllegalStateException] { - runSyncUnsafe(testContext.run(query[EncodingTestEntity])) - } - } - } - - "encodes sets" in { - val q = quote { (set: Query[Int]) => - query[EncodingTestEntity].filter(t => set.contains(t.v6)) - } - val fut = - for { - _ <- testContext.run(query[EncodingTestEntity].delete) - _ <- testContext.run(liftQuery(insertValues).foreach(e => query[EncodingTestEntity].insertValue(e))) - r <- testContext.run(q(liftQuery(insertValues.map(_.v6)))) - } yield r - verify(runSyncUnsafe(fut)) - } - - "returning UUID" in { - val success = for { - uuid <- runSyncUnsafe(testContext.run(insertBarCode(lift(barCodeEntry)))) - barCode <- runSyncUnsafe(testContext.run(findBarCodeByUuid(uuid))).headOption - } yield { - verifyBarcode(barCode) - } - success must not be empty - } - - "decodes LocalDate and LocalDateTime types" in { - case class DateEncodingTestEntity(v1: LocalDate, v2: LocalDateTime) - val entity = DateEncodingTestEntity(LocalDate.now, LocalDateTime.now.truncatedTo(ChronoUnit.MICROS)) - val r = for { - _ <- testContext.run(query[DateEncodingTestEntity].delete) - _ <- testContext.run(query[DateEncodingTestEntity].insertValue(lift(entity))) - result <- testContext.run(query[DateEncodingTestEntity]) - } yield result - runSyncUnsafe(r) mustBe Seq(entity) - } - - "encodes custom type inside singleton object" in { - object Singleton { - def apply()(implicit c: TestContext) = { - import c._ - for { - _ <- c.run(query[EncodingTestEntity].delete) - result <- c.run(liftQuery(insertValues).foreach(e => query[EncodingTestEntity].insertValue(e))) - } yield result - } - } - - implicit val c = testContext - runSyncUnsafe(Singleton()) - } -} diff --git a/quill-jasync-zio-postgres/src/test/scala/io/getquill/context/qzio/jasync/postgres/PostgresJAsyncContextSpec.scala b/quill-jasync-zio-postgres/src/test/scala/io/getquill/context/qzio/jasync/postgres/PostgresJAsyncContextSpec.scala deleted file mode 100644 index 6fd2ed5b08..0000000000 --- a/quill-jasync-zio-postgres/src/test/scala/io/getquill/context/qzio/jasync/postgres/PostgresJAsyncContextSpec.scala +++ /dev/null @@ -1,73 +0,0 @@ -package io.getquill.context.qzio.jasync.postgres - -import com.github.jasync.sql.db.{QueryResult, ResultSetKt} -import io.getquill.ReturnAction.ReturnColumns -import io.getquill.base.Spec -import io.getquill.context.qzio.PostgresZioJAsyncContext - -import io.getquill.{Literal, ReturnAction} - -class PostgresJAsyncContextSpec extends Spec with ZioSpec { - - import context._ - - "run non-batched action" in { - val insert = quote { (i: Int) => - qr1.insert(_.i -> i) - } - runSyncUnsafe(testContext.run(insert(lift(1)))) mustEqual 1 - } - - "Insert with returning with single column table" in { - val inserted: Long = runSyncUnsafe(testContext.run { - qr4.insertValue(lift(TestEntity4(0))).returningGenerated(_.i) - }) - runSyncUnsafe(testContext.run(qr4.filter(_.i == lift(inserted)))).head.i mustBe inserted - } - "Insert with returning with multiple columns" in { - runSyncUnsafe(testContext.run(qr1.delete)) - val inserted = runSyncUnsafe(testContext.run { - qr1.insertValue(lift(TestEntity("foo", 1, 18L, Some(123), true))).returning(r => (r.i, r.s, r.o)) - }) - (1, "foo", Some(123)) mustBe inserted - } - - "performIO" in { - runSyncUnsafe(performIO(runIO(qr4).transactional)) - } - - "probe" in { - probe("select 1").toOption mustBe defined - } - - "cannot extract" in { - object ctx extends PostgresZioJAsyncContext(Literal) { - override def handleSingleResult[T](sql: String, list: List[T]) = super.handleSingleResult(sql, list) - - override def extractActionResult[O]( - returningAction: ReturnAction, - returningExtractor: ctx.Extractor[O] - )(result: QueryResult) = - super.extractActionResult(returningAction, returningExtractor)(result) - } - intercept[IllegalStateException] { - val v = ctx.extractActionResult(ReturnColumns(List("w/e")), (row, session) => 1)( - new QueryResult(0, "w/e", ResultSetKt.getEMPTY_RESULT_SET) - ) - ctx.handleSingleResult("", v) - } - ctx.close - } - - "prepare" in { - testContext.prepareParams( - "", - (ps, session) => (Nil, ps ++ List("Sarah", 127)) - ) mustEqual List("'Sarah'", "127") - } - - override protected def beforeAll(): Unit = { - runSyncUnsafe(testContext.run(qr1.delete)) - () - } -} diff --git a/quill-jasync-zio-postgres/src/test/scala/io/getquill/context/qzio/jasync/postgres/ProductPostgresAsyncSpec.scala b/quill-jasync-zio-postgres/src/test/scala/io/getquill/context/qzio/jasync/postgres/ProductPostgresAsyncSpec.scala deleted file mode 100644 index 84320c16a5..0000000000 --- a/quill-jasync-zio-postgres/src/test/scala/io/getquill/context/qzio/jasync/postgres/ProductPostgresAsyncSpec.scala +++ /dev/null @@ -1,93 +0,0 @@ -package io.getquill.context.qzio.jasync.postgres - -import io.getquill.context.sql.{Id, ProductSpec} -import zio.ZIO - -class ProductPostgresAsyncSpec extends ProductSpec with ZioSpec { - - import context._ - - override def beforeAll = { - runSyncUnsafe(testContext.run(quote(query[Product].delete))) - () - } - - "Product" - { - "Insert multiple products" in { - val inserted = - runSyncUnsafe(ZIO.foreach(productEntries)(product => testContext.run(productInsert(lift(product))))) - val product = runSyncUnsafe(testContext.run(productById(lift(inserted(2))))).head - product.description mustEqual productEntries(2).description - product.id mustEqual inserted(2) - } - "Single insert product" in { - val inserted = runSyncUnsafe(testContext.run(productSingleInsert)) - val product = runSyncUnsafe(testContext.run(productById(lift(inserted)))).head - product.description mustEqual "Window" - product.id mustEqual inserted - } - - "Single insert with inlined free variable" in { - val prd = Product(0L, "test1", 1L) - val inserted = runSyncUnsafe { - testContext.run { - product.insert(_.sku -> lift(prd.sku), _.description -> lift(prd.description)).returning(_.id) - } - } - val returnedProduct = runSyncUnsafe(testContext.run(productById(lift(inserted)))).head - returnedProduct.description mustEqual "test1" - returnedProduct.sku mustEqual 1L - returnedProduct.id mustEqual inserted - } - - "Single insert with free variable and explicit quotation" in { - val prd = Product(0L, "test2", 2L) - val q1 = quote { - product.insert(_.sku -> lift(prd.sku), _.description -> lift(prd.description)).returning(_.id) - } - val inserted = runSyncUnsafe(testContext.run(q1)) - val returnedProduct = runSyncUnsafe(testContext.run(productById(lift(inserted)))).head - returnedProduct.description mustEqual "test2" - returnedProduct.sku mustEqual 2L - returnedProduct.id mustEqual inserted - } - - "Single product insert with a method quotation" in { - val prd = Product(0L, "test3", 3L) - val inserted = runSyncUnsafe(testContext.run(productInsert(lift(prd)))) - val returnedProduct = runSyncUnsafe(testContext.run(productById(lift(inserted)))).head - returnedProduct.description mustEqual "test3" - returnedProduct.sku mustEqual 3L - returnedProduct.id mustEqual inserted - } - - "Single insert with value class" in { - case class Product(id: Id, description: String, sku: Long) - val prd = Product(Id(0L), "test2", 2L) - val q1 = quote { - query[Product].insert(_.sku -> lift(prd.sku), _.description -> lift(prd.description)).returning(_.id) - } - runSyncUnsafe(testContext.run(q1)) mustBe a[Id] - } - - "supports casts from string to number" - { - "toInt" in { - case class Product(id: Long, description: String, sku: Int) - val queried = runSyncUnsafe { - testContext.run { - query[Product].filter(_.sku == lift("1004").toInt) - } - }.head - queried.sku mustEqual 1004L - } - "toLong" in { - val queried = runSyncUnsafe { - testContext.run { - query[Product].filter(_.sku == lift("1004").toLong) - } - }.head - queried.sku mustEqual 1004L - } - } - } -} diff --git a/quill-jasync-zio-postgres/src/test/scala/io/getquill/context/qzio/jasync/postgres/QueryResultTypePostgresAsyncSpec.scala b/quill-jasync-zio-postgres/src/test/scala/io/getquill/context/qzio/jasync/postgres/QueryResultTypePostgresAsyncSpec.scala deleted file mode 100644 index 805cf2ffe5..0000000000 --- a/quill-jasync-zio-postgres/src/test/scala/io/getquill/context/qzio/jasync/postgres/QueryResultTypePostgresAsyncSpec.scala +++ /dev/null @@ -1,104 +0,0 @@ -package io.getquill.context.qzio.jasync.postgres - -import io.getquill.context.sql.base.QueryResultTypeSpec - -import java.util.concurrent.ConcurrentLinkedQueue -import scala.jdk.CollectionConverters._ -import scala.math.BigDecimal.int2bigDecimal - -class QueryResultTypePostgresAsyncSpec extends QueryResultTypeSpec with ZioSpec { - - import context._ - - val insertedProducts = new ConcurrentLinkedQueue[Product] - - override def beforeAll = { - runSyncUnsafe(testContext.run(deleteAll)) - val ids = runSyncUnsafe(testContext.run(liftQuery(productEntries).foreach(e => productInsert(e)))) - val inserted = (ids zip productEntries).map { case (id, prod) => - prod.copy(id = id) - } - insertedProducts.addAll(inserted.asJava) - () - } - - def products = insertedProducts.asScala.toList - - "return list" - { - "select" in { - runSyncUnsafe(testContext.run(selectAll)) must contain theSameElementsAs (products) - } - "map" in { - runSyncUnsafe(testContext.run(map)) must contain theSameElementsAs (products.map(_.id)) - } - "filter" in { - runSyncUnsafe(testContext.run(filter)) must contain theSameElementsAs (products) - } - "withFilter" in { - runSyncUnsafe(testContext.run(withFilter)) must contain theSameElementsAs (products) - } - "sortBy" in { - runSyncUnsafe(testContext.run(sortBy)) must contain theSameElementsInOrderAs (products) - } - "take" in { - runSyncUnsafe(testContext.run(take)) must contain theSameElementsAs (products) - } - "drop" in { - runSyncUnsafe(testContext.run(drop)) must contain theSameElementsAs (products.drop(1)) - } - "++" in { - runSyncUnsafe(testContext.run(`++`)) must contain theSameElementsAs (products ++ products) - } - "unionAll" in { - runSyncUnsafe(testContext.run(unionAll)) must contain theSameElementsAs (products ++ products) - } - "union" in { - runSyncUnsafe(testContext.run(union)) must contain theSameElementsAs (products) - } - "join" in { - runSyncUnsafe(testContext.run(join)) must contain theSameElementsAs (products zip products) - } - "distinct" in { - runSyncUnsafe(testContext.run(distinct)) must contain theSameElementsAs (products.map(_.id).distinct) - } - } - - "return single result" - { - "min" - { - "some" in { - runSyncUnsafe(testContext.run(minExists)) mustEqual Some(products.map(_.sku).min) - } - "none" in { - runSyncUnsafe(testContext.run(minNonExists)) mustBe None - } - } - "max" - { - "some" in { - runSyncUnsafe(testContext.run(maxExists)) mustBe Some(products.map(_.sku).max) - } - "none" in { - runSyncUnsafe(testContext.run(maxNonExists)) mustBe None - } - } - "avg" - { - "some" in { - runSyncUnsafe(testContext.run(avgExists)) mustBe Some(BigDecimal(products.map(_.sku).sum) / products.size) - } - "none" in { - runSyncUnsafe(testContext.run(avgNonExists)) mustBe None - } - } - "size" in { - runSyncUnsafe(testContext.run(productSize)) mustEqual products.size - } - "parametrized size" in { - runSyncUnsafe(testContext.run(parametrizedSize(lift(10000)))) mustEqual 0 - } - "nonEmpty" in { - runSyncUnsafe(testContext.run(nonEmpty)) mustEqual true - } - "isEmpty" in { - runSyncUnsafe(testContext.run(isEmpty)) mustEqual false - } - } -} diff --git a/quill-jasync-zio-postgres/src/test/scala/io/getquill/context/qzio/jasync/postgres/TestContext.scala b/quill-jasync-zio-postgres/src/test/scala/io/getquill/context/qzio/jasync/postgres/TestContext.scala deleted file mode 100644 index 51a4af396d..0000000000 --- a/quill-jasync-zio-postgres/src/test/scala/io/getquill/context/qzio/jasync/postgres/TestContext.scala +++ /dev/null @@ -1,22 +0,0 @@ -package io.getquill.context.qzio.jasync.postgres - -import com.github.jasync.sql.db.postgresql.PostgreSQLConnection -import io.getquill.context.qzio.{ - JAsyncContextConfig, - PostgresJAsyncContextConfig, - PostgresZioJAsyncContext, - ZioJAsyncConnection -} -import io.getquill.context.sql.{TestDecoders, TestEncoders} -import io.getquill.util.LoadConfig -import io.getquill.{Literal, TestEntities} -import zio._ - -class TestContext extends PostgresZioJAsyncContext(Literal) with TestEntities with TestEncoders with TestDecoders { - - val config: JAsyncContextConfig[PostgreSQLConnection] = PostgresJAsyncContextConfig(LoadConfig("testPostgresDB")) - - val layer: TaskLayer[ZioJAsyncConnection] = - ZLayer.succeed(config) >>> ZioJAsyncConnection.live[PostgreSQLConnection] - -} diff --git a/quill-jasync-zio-postgres/src/test/scala/io/getquill/context/qzio/jasync/postgres/ZioSpec.scala b/quill-jasync-zio-postgres/src/test/scala/io/getquill/context/qzio/jasync/postgres/ZioSpec.scala deleted file mode 100644 index 668335c3f4..0000000000 --- a/quill-jasync-zio-postgres/src/test/scala/io/getquill/context/qzio/jasync/postgres/ZioSpec.scala +++ /dev/null @@ -1,43 +0,0 @@ -package io.getquill.context.qzio.jasync.postgres - -import io.getquill.base.Spec -import io.getquill.context.qzio.ZioJAsyncConnection -import org.scalatest.BeforeAndAfterAll -import zio.stream.{ZSink, ZStream} -import zio.{Runtime, Unsafe, ZIO} - -trait ZioSpec extends Spec with BeforeAndAfterAll { - - lazy val context = testContext - val ctx = context - - def accumulate[T](stream: ZStream[ZioJAsyncConnection, Throwable, T]): ZIO[ZioJAsyncConnection, Throwable, List[T]] = - stream.run(ZSink.collectAll).map(_.toList) - - def collect[T](stream: ZStream[ZioJAsyncConnection, Throwable, T]): List[T] = - Unsafe.unsafe { implicit u => - Runtime.default.unsafe - .run(stream.run(ZSink.collectAll).map(_.toList).provideLayer(testContext.layer)) - .getOrThrow() - } - - def runSyncUnsafe[T](qzio: ZIO[ZioJAsyncConnection, Throwable, T]): T = - Unsafe.unsafe { implicit u => - Runtime.default.unsafe.run(qzio.provideLayer(testContext.layer)).getOrThrow() - } - - implicit class ZioAnyOps[T](qzio: ZIO[Any, Throwable, T]) { - def runSyncUnsafe() = - Unsafe.unsafe { implicit u => - Runtime.default.unsafe.run(qzio).getOrThrow() - } - } - - implicit class ZStreamTestExt[T](stream: ZStream[ZioJAsyncConnection, Throwable, T]) { - def runSyncUnsafe() = collect[T](stream) - } - - implicit class ZioTestExt[T](qzio: ZIO[ZioJAsyncConnection, Throwable, T]) { - def runSyncUnsafe() = ZioSpec.this.runSyncUnsafe[T](qzio) - } -} diff --git a/quill-jasync-zio-postgres/src/test/scala/io/getquill/context/qzio/jasync/postgres/package.scala b/quill-jasync-zio-postgres/src/test/scala/io/getquill/context/qzio/jasync/postgres/package.scala deleted file mode 100644 index b3e77cf9f3..0000000000 --- a/quill-jasync-zio-postgres/src/test/scala/io/getquill/context/qzio/jasync/postgres/package.scala +++ /dev/null @@ -1,5 +0,0 @@ -package io.getquill.context.qzio.jasync - -package object postgres { - object testContext extends TestContext -} diff --git a/quill-jasync-zio/src/main/scala/io/getquill/context/qzio/Decoders.scala b/quill-jasync-zio/src/main/scala/io/getquill/context/qzio/Decoders.scala deleted file mode 100644 index bc5654c0ad..0000000000 --- a/quill-jasync-zio/src/main/scala/io/getquill/context/qzio/Decoders.scala +++ /dev/null @@ -1,147 +0,0 @@ -package io.getquill.context.qzio - -import com.github.jasync.sql.db.RowData -import io.getquill.context.Context -import io.getquill.util.Messages.fail - -import java.math.{BigDecimal => JavaBigDecimal} -import java.time.{LocalDate, LocalDateTime, ZoneId} -import java.util.Date -import scala.reflect.{ClassTag, classTag} - -trait Decoders { - this: ZioJAsyncContext[_, _, _] => - - type Decoder[T] = AsyncDecoder[T] - - type ResultRow = RowData - type Session = Unit - - type DecoderSqlType = SqlTypes.SqlTypes - - case class AsyncDecoder[T](sqlType: DecoderSqlType)(implicit decoder: BaseDecoder[T]) extends BaseDecoder[T] { - override def apply(index: Index, row: ResultRow, session: Session) = - decoder(index, row, session) - } - - def decoder[T: ClassTag]( - f: PartialFunction[Any, T] = PartialFunction.empty, - sqlType: DecoderSqlType - ): Decoder[T] = - AsyncDecoder[T](sqlType)(new BaseDecoder[T] { - def apply(index: Index, row: ResultRow, session: Session) = - row.get(index) match { - case value: T => value - case value if f.isDefinedAt(value) => f(value) - case value => - fail( - s"Value '$value' at index $index can't be decoded to '${classTag[T].runtimeClass}'" - ) - } - }) - - implicit def mappedDecoder[I, O](implicit mapped: MappedEncoding[I, O], decoder: Decoder[I]): Decoder[O] = - AsyncDecoder(decoder.sqlType)(new BaseDecoder[O] { - def apply(index: Index, row: ResultRow, session: Session): O = - mapped.f(decoder.apply(index, row, session)) - }) - - trait NumericDecoder[T] extends BaseDecoder[T] { - - def apply(index: Index, row: ResultRow, session: Session) = - (row.get(index): Any) match { - case v: Byte => decode(v) - case v: Short => decode(v) - case v: Int => decode(v) - case v: Long => decode(v) - case v: Float => decode(v) - case v: Double => decode(v) - case v: JavaBigDecimal => decode(v: BigDecimal) - case other => - fail(s"Value $other is not numeric, type: ${other.getClass.getCanonicalName}") - } - - def decode[U](v: U)(implicit n: Numeric[U]): T - } - - implicit def optionDecoder[T](implicit d: Decoder[T]): Decoder[Option[T]] = - AsyncDecoder(d.sqlType)(new BaseDecoder[Option[T]] { - def apply(index: Index, row: ResultRow, session: Session) = - row.get(index) match { - case null => None - case value => Some(d(index, row, session)) - } - }) - - implicit val stringDecoder: Decoder[String] = decoder[String](PartialFunction.empty, SqlTypes.VARCHAR) - - implicit val bigDecimalDecoder: Decoder[BigDecimal] = - AsyncDecoder(SqlTypes.REAL)(new NumericDecoder[BigDecimal] { - def decode[U](v: U)(implicit n: Numeric[U]) = - BigDecimal(n.toDouble(v)) - }) - - implicit val booleanDecoder: Decoder[Boolean] = - decoder[Boolean]( - { - case v: Byte => v == (1: Byte) - case v: Short => v == (1: Short) - case v: Int => v == 1 - case v: Long => v == 1L - }, - SqlTypes.BOOLEAN - ) - - implicit val byteDecoder: Decoder[Byte] = - decoder[Byte]( - { case v: Short => - v.toByte - }, - SqlTypes.TINYINT - ) - - implicit val shortDecoder: Decoder[Short] = - decoder[Short]( - { case v: Byte => - v.toShort - }, - SqlTypes.SMALLINT - ) - - implicit val intDecoder: Decoder[Int] = - AsyncDecoder(SqlTypes.INTEGER)(new NumericDecoder[Int] { - def decode[U](v: U)(implicit n: Numeric[U]) = - n.toInt(v) - }) - - implicit val longDecoder: Decoder[Long] = - AsyncDecoder(SqlTypes.BIGINT)(new NumericDecoder[Long] { - def decode[U](v: U)(implicit n: Numeric[U]) = - n.toLong(v) - }) - - implicit val floatDecoder: Decoder[Float] = - AsyncDecoder(SqlTypes.FLOAT)(new NumericDecoder[Float] { - def decode[U](v: U)(implicit n: Numeric[U]) = - n.toFloat(v) - }) - - implicit val doubleDecoder: Decoder[Double] = - AsyncDecoder(SqlTypes.DOUBLE)(new NumericDecoder[Double] { - def decode[U](v: U)(implicit n: Numeric[U]) = - n.toDouble(v) - }) - - implicit val byteArrayDecoder: Decoder[Array[Byte]] = decoder[Array[Byte]](PartialFunction.empty, SqlTypes.TINYINT) - - implicit val dateDecoder: Decoder[Date] = decoder[Date]( - { - case date: LocalDateTime => Date.from(date.atZone(ZoneId.systemDefault()).toInstant) - case date: LocalDate => Date.from(date.atStartOfDay.atZone(ZoneId.systemDefault()).toInstant) - }, - SqlTypes.TIMESTAMP - ) - implicit val localDateDecoder: Decoder[LocalDate] = decoder[LocalDate](PartialFunction.empty, SqlTypes.DATE) - implicit val localDateTimeDecoder: Decoder[LocalDateTime] = - decoder[LocalDateTime](PartialFunction.empty, SqlTypes.TIMESTAMP) -} diff --git a/quill-jasync-zio/src/main/scala/io/getquill/context/qzio/Encoders.scala b/quill-jasync-zio/src/main/scala/io/getquill/context/qzio/Encoders.scala deleted file mode 100644 index 52daa2c718..0000000000 --- a/quill-jasync-zio/src/main/scala/io/getquill/context/qzio/Encoders.scala +++ /dev/null @@ -1,71 +0,0 @@ -package io.getquill.context.qzio - -import com.github.jasync.sql.db.RowData -import io.getquill.context.Context - -import java.time._ -import java.util.Date - -trait Encoders { - this: ZioJAsyncContext[_, _, _] => - - type Encoder[T] = AsyncEncoder[T] - - type ResultRow = RowData - type Session = Unit - type PrepareRow = Seq[Any] - - type EncoderSqlType = SqlTypes.SqlTypes - type DecoderSqlType = SqlTypes.SqlTypes - - case class AsyncEncoder[T](sqlType: DecoderSqlType)(implicit encoder: BaseEncoder[T]) extends BaseEncoder[T] { - override def apply(index: Index, value: T, row: PrepareRow, session: Session) = - encoder.apply(index, value, row, session) - } - - def encoder[T](sqlType: DecoderSqlType): Encoder[T] = - encoder(identity[T], sqlType) - - def encoder[T](f: T => Any, sqlType: DecoderSqlType): Encoder[T] = - AsyncEncoder[T](sqlType)(new BaseEncoder[T] { - def apply(index: Index, value: T, row: PrepareRow, session: Session) = - row :+ f(value) - }) - - implicit def mappedEncoder[I, O](implicit mapped: MappedEncoding[I, O], e: Encoder[O]): Encoder[I] = - AsyncEncoder(e.sqlType)(new BaseEncoder[I] { - def apply(index: Index, value: I, row: PrepareRow, session: Session) = - e(index, mapped.f(value), row, session) - }) - - implicit def optionEncoder[T](implicit d: Encoder[T]): Encoder[Option[T]] = - AsyncEncoder(d.sqlType)(new BaseEncoder[Option[T]] { - def apply(index: Index, value: Option[T], row: PrepareRow, session: Session) = - value match { - case None => nullEncoder(index, null, row, session) - case Some(v) => d(index, v, row, session) - } - }) - - private[this] val nullEncoder: Encoder[Null] = encoder[Null](SqlTypes.NULL) - - implicit val stringEncoder: Encoder[String] = encoder[String](SqlTypes.VARCHAR) - implicit val bigDecimalEncoder: Encoder[BigDecimal] = - encoder[BigDecimal]((bd: BigDecimal) => bd.bigDecimal, SqlTypes.REAL) - implicit val booleanEncoder: Encoder[Boolean] = encoder[Boolean](SqlTypes.BOOLEAN) - implicit val byteEncoder: Encoder[Byte] = encoder[Byte](SqlTypes.TINYINT) - implicit val shortEncoder: Encoder[Short] = encoder[Short](SqlTypes.SMALLINT) - implicit val intEncoder: Encoder[Int] = encoder[Int](SqlTypes.INTEGER) - implicit val longEncoder: Encoder[Long] = encoder[Long](SqlTypes.BIGINT) - implicit val floatEncoder: Encoder[Float] = encoder[Float](SqlTypes.FLOAT) - implicit val doubleEncoder: Encoder[Double] = encoder[Double](SqlTypes.DOUBLE) - implicit val byteArrayEncoder: Encoder[Array[Byte]] = encoder[Array[Byte]](SqlTypes.VARBINARY) - implicit val dateEncoder: Encoder[Date] = encoder[Date]( - (date: Date) => { - OffsetDateTime.ofInstant(date.toInstant, dateTimeZone).toLocalDateTime - }, - SqlTypes.DATE - ) - implicit val localDateEncoder: Encoder[LocalDate] = encoder[LocalDate](SqlTypes.DATE) - implicit val localDateTimeEncoder: Encoder[LocalDateTime] = encoder[LocalDateTime](SqlTypes.TIMESTAMP) -} diff --git a/quill-jasync-zio/src/main/scala/io/getquill/context/qzio/JAsyncContextConfig.scala b/quill-jasync-zio/src/main/scala/io/getquill/context/qzio/JAsyncContextConfig.scala deleted file mode 100644 index dbf7d86a47..0000000000 --- a/quill-jasync-zio/src/main/scala/io/getquill/context/qzio/JAsyncContextConfig.scala +++ /dev/null @@ -1,67 +0,0 @@ -package io.getquill.context.qzio - -import com.github.jasync.sql.db._ -import com.github.jasync.sql.db.pool.ObjectFactory -import com.github.jasync.sql.db.util.AbstractURIParser -import com.typesafe.config.Config - -import java.lang.{Long => JavaLong} -import java.nio.charset.Charset -import scala.jdk.CollectionConverters._ -import scala.util.Try - -abstract class JAsyncContextConfig[C <: ConcreteConnection]( - config: Config, - val connectionFactory: Configuration => ObjectFactory[C], - uriParser: AbstractURIParser -) { - - private def getValue[T](path: String, getter: String => T) = Try(getter(path)) - private def getString(path: String) = getValue(path, config.getString).toOption - private def getInt(path: String) = getValue(path, config.getInt).toOption - private def getLong(path: String) = getValue(path, config.getLong).toOption - - private lazy val urlConfiguration: Configuration = getValue("url", config.getString) - .map(uriParser.parseOrDie(_, uriParser.getDEFAULT.getCharset)) - .getOrElse(uriParser.getDEFAULT) - - private lazy val default = new ConnectionPoolConfigurationBuilder().build() - - lazy val connectionPoolConfiguration = new ConnectionPoolConfiguration( - getString("host").getOrElse(urlConfiguration.getHost), - getInt("port").getOrElse(urlConfiguration.getPort), - getString("database").orElse(Option(urlConfiguration.getDatabase)).orNull, - getString("username").getOrElse(urlConfiguration.getUsername), - getString("password").orElse(Option(urlConfiguration.getPassword)).orNull, - getInt("maxActiveConnections").getOrElse(default.getMaxActiveConnections), - getLong("maxIdleTime").getOrElse(default.getMaxIdleTime), - getInt("maxPendingQueries").getOrElse(default.getMaxPendingQueries), - getLong("connectionValidationInterval").getOrElse(default.getConnectionValidationInterval), - getLong("connectionCreateTimeout").getOrElse(default.getConnectionCreateTimeout), - getLong("connectionTestTimeout").getOrElse(default.getConnectionTestTimeout), - getLong("queryTimeout") - .orElse(Option(urlConfiguration.getQueryTimeout).map(_.toMillis)) - .map(JavaLong.valueOf) - .orNull, - urlConfiguration.getEventLoopGroup, - urlConfiguration.getExecutionContext, - default.getCoroutineDispatcher, - new SSLConfiguration( - Map( - "sslmode" -> getString("sslmode"), - "sslrootcert" -> getString("sslrootcert"), - "sslcert" -> getString("sslcert"), - "sslkey" -> getString("sslkey") - ).collect { case (key, Some(value)) => - key -> value - }.asJava - ), - Try(Charset.forName(config.getString("charset"))).getOrElse(urlConfiguration.getCharset), - getInt("maximumMessageSize").getOrElse(urlConfiguration.getMaximumMessageSize), - urlConfiguration.getAllocator, - getString("applicationName").orElse(Option(urlConfiguration.getApplicationName)).orNull, - urlConfiguration.getInterceptors, - getLong("maxConnectionTtl").map(JavaLong.valueOf).orElse(Option(default.getMaxConnectionTtl)).orNull, - getString("currentSchema").orElse(Option(urlConfiguration.getCurrentSchema)).orNull - ) -} diff --git a/quill-jasync-zio/src/main/scala/io/getquill/context/qzio/SqlTypes.scala b/quill-jasync-zio/src/main/scala/io/getquill/context/qzio/SqlTypes.scala deleted file mode 100644 index a8751dc973..0000000000 --- a/quill-jasync-zio/src/main/scala/io/getquill/context/qzio/SqlTypes.scala +++ /dev/null @@ -1,10 +0,0 @@ -package io.getquill.context.qzio - -object SqlTypes extends Enumeration { - type SqlTypes = Value - - val BIT, TINYINT, SMALLINT, INTEGER, BIGINT, FLOAT, REAL, DOUBLE, NUMERIC, DECIMAL, CHAR, VARCHAR, LONGVARCHAR, DATE, - TIME, TIMESTAMP, BINARY, VARBINARY, LONGVARBINARY, NULL, ARRAY, BLOB, BOOLEAN, TIME_WITH_TIMEZONE, - TIMESTAMP_WITH_TIMEZONE, UUID = Value - -} diff --git a/quill-jasync-zio/src/main/scala/io/getquill/context/qzio/UUIDObjectEncoding.scala b/quill-jasync-zio/src/main/scala/io/getquill/context/qzio/UUIDObjectEncoding.scala deleted file mode 100644 index dc1b89c95f..0000000000 --- a/quill-jasync-zio/src/main/scala/io/getquill/context/qzio/UUIDObjectEncoding.scala +++ /dev/null @@ -1,16 +0,0 @@ -package io.getquill.context.qzio - -import java.util.UUID - -trait UUIDObjectEncoding { - this: ZioJAsyncContext[_, _, _] => - - implicit val uuidEncoder: Encoder[UUID] = encoder[UUID](SqlTypes.UUID) - - implicit val uuidDecoder: Decoder[UUID] = - AsyncDecoder(SqlTypes.UUID)((index: Index, row: ResultRow, session: Session) => - row.get(index) match { - case value: UUID => value - } - ) -} diff --git a/quill-jasync-zio/src/main/scala/io/getquill/context/qzio/UUIDStringEncoding.scala b/quill-jasync-zio/src/main/scala/io/getquill/context/qzio/UUIDStringEncoding.scala deleted file mode 100644 index c92bb102c0..0000000000 --- a/quill-jasync-zio/src/main/scala/io/getquill/context/qzio/UUIDStringEncoding.scala +++ /dev/null @@ -1,16 +0,0 @@ -package io.getquill.context.qzio - -import java.util.UUID - -trait UUIDStringEncoding { - this: ZioJAsyncContext[_, _, _] => - - implicit val uuidEncoder: Encoder[UUID] = encoder[UUID]((v: UUID) => v.toString, SqlTypes.UUID) - - implicit val uuidDecoder: Decoder[UUID] = - AsyncDecoder(SqlTypes.UUID)((index: Index, row: ResultRow, session: Session) => - row.get(index) match { - case value: String => UUID.fromString(value) - } - ) -} diff --git a/quill-jasync-zio/src/main/scala/io/getquill/context/qzio/ZIOMonad.scala b/quill-jasync-zio/src/main/scala/io/getquill/context/qzio/ZIOMonad.scala deleted file mode 100644 index 4f8b2f80cf..0000000000 --- a/quill-jasync-zio/src/main/scala/io/getquill/context/qzio/ZIOMonad.scala +++ /dev/null @@ -1,57 +0,0 @@ -package io.getquill.context.qzio - -import io.getquill.context.Context -import io.getquill.monad.{IOMonad, IOMonadMacro} -import io.getquill.{Action, ActionReturning, BatchAction, Query, Quoted} -import zio.{RIO, ZIO} - -import scala.collection.compat._ -import scala.language.experimental.macros -import scala.language.higherKinds -import scala.util.{Failure, Success} - -trait ZIOMonad extends IOMonad { - this: Context[_, _] => - - type Result[T] = RIO[ZioJAsyncConnection, T] - - def runIO[T](quoted: Quoted[T]): IO[RunQuerySingleResult[T], Effect.Read] = macro IOMonadMacro.runIO - def runIO[T](quoted: Quoted[Query[T]]): IO[RunQueryResult[T], Effect.Read] = macro IOMonadMacro.runIO - def runIO(quoted: Quoted[Action[_]]): IO[RunActionResult, Effect.Write] = macro IOMonadMacro.runIO - def runIO[T]( - quoted: Quoted[ActionReturning[_, T]] - ): IO[RunActionReturningResult[T], Effect.Write] = macro IOMonadMacro.runIO - def runIO( - quoted: Quoted[BatchAction[Action[_]]] - ): IO[RunBatchActionResult, Effect.Write] = macro IOMonadMacro.runIO - def runIO[T]( - quoted: Quoted[BatchAction[ActionReturning[_, T]]] - ): IO[RunBatchActionReturningResult[T], Effect.Write] = macro IOMonadMacro.runIO - - case class Run[T, E <: Effect](f: () => Result[T]) extends IO[T, E] - - def flatten[Y, M[X] <: IterableOnce[X]]( - seq: Sequence[Y, M, Effect] - ) = { - val builder = seq.cbfResultToValue.newBuilder - ZIO - .foldLeft(seq.in.iterator.toIterable)(builder) { (r, ioa) => - for { - a <- performIO(ioa) - } yield r += a - } - .map(_.result()) - } - - def performIO[T](io: IO[T, _], transactional: Boolean = false): Result[T] = - io match { - case FromTry(v) => ZIO.fromTry(v) - case Run(f) => f() - case seq @ Sequence(_, _) => - flatten(seq) - case TransformWith(a, fA) => - performIO(a).either.flatMap(valueOrError => performIO(fA(valueOrError.fold(Failure(_), Success(_))))) - case Transactional(io) => - performIO(io, transactional = true) - } -} diff --git a/quill-jasync-zio/src/main/scala/io/getquill/context/qzio/ZioJAsyncConnection.scala b/quill-jasync-zio/src/main/scala/io/getquill/context/qzio/ZioJAsyncConnection.scala deleted file mode 100644 index 5eaac3591a..0000000000 --- a/quill-jasync-zio/src/main/scala/io/getquill/context/qzio/ZioJAsyncConnection.scala +++ /dev/null @@ -1,83 +0,0 @@ -package io.getquill.context.qzio - -import com.github.jasync.sql.db.pool.{ConnectionPool => KConnectionPool} -import com.github.jasync.sql.db.{ConcreteConnection, QueryResult} -import zio.{RIO, Scope, Tag, Task, ZIO, ZLayer} - -import scala.jdk.CollectionConverters._ - -trait ZioJAsyncConnection { - protected def takeConnection: ZIO[Scope, Throwable, ConcreteConnection] - - private[qzio] final def transaction[R <: ZioJAsyncConnection, A](action: RIO[R, A]): ZIO[R, Throwable, A] = - // Taken from ConcreteConnectionBase.kt to avoid usage of pool.inTransaction - ZIO.scoped[R] { - takeConnection.flatMap(conn => - (ZioJAsyncConnection.sendQuery(conn, "BEGIN") *> - action.updateService[ZioJAsyncConnection](_ => ZioJAsyncConnection.make(conn))).tapBoth( - _ => ZioJAsyncConnection.sendQuery(conn, "ROLLBACK"), - _ => ZioJAsyncConnection.sendQuery(conn, "COMMIT") - ) - ) - } - - private[qzio] final def sendQuery(query: String): Task[QueryResult] = - ZIO.scoped { - takeConnection.flatMap(conn => ZIO.fromCompletableFuture(conn.sendQuery(query))) - } - - private[qzio] final def sendPreparedStatement(sql: String, params: Seq[Any]): Task[QueryResult] = - ZIO.scoped { - takeConnection.flatMap(conn => - ZIO.fromCompletableFuture( - conn.sendPreparedStatement(sql, params.asJava) - ) - ) - } - -} - -object ZioJAsyncConnection { - - def sendQuery(query: String): ZIO[ZioJAsyncConnection, Throwable, QueryResult] = - ZIO.environmentWithZIO[ZioJAsyncConnection](_.get.sendQuery(query)) - - def sendPreparedStatement(sql: String, params: Seq[Any]): ZIO[ZioJAsyncConnection, Throwable, QueryResult] = - ZIO.environmentWithZIO[ZioJAsyncConnection](_.get.sendPreparedStatement(sql, params)) - - private def sendQuery[C <: ConcreteConnection](connection: C, query: String): Task[QueryResult] = - ZIO.fromCompletableFuture(connection.sendQuery(query)) - - def make[C <: ConcreteConnection](pool: KConnectionPool[C]): ZioJAsyncConnection = new ZioJAsyncConnection { - - override protected def takeConnection: ZIO[Scope, Throwable, ConcreteConnection] = - ZIO.acquireRelease(ZIO.fromCompletableFuture(pool.take()))(conn => - ZIO.fromCompletableFuture(pool.giveBack(conn)).orDie.unit - ) - - } - - def make[C <: ConcreteConnection](connection: C): ZioJAsyncConnection = new ZioJAsyncConnection { - override protected def takeConnection: ZIO[Scope, Throwable, ConcreteConnection] = - for { - _ <- ZIO.scope - conn <- ZIO.attempt(connection) - } yield conn - } - - def live[C <: ConcreteConnection: Tag]: ZLayer[JAsyncContextConfig[C], Throwable, ZioJAsyncConnection] = - ZLayer.scoped { - for { - env <- ZIO.environment[JAsyncContextConfig[C]] - pool <- ZIO.acquireRelease( - ZIO.attempt( - new KConnectionPool[C]( - env.get.connectionFactory(env.get.connectionPoolConfiguration.getConnectionConfiguration), - env.get.connectionPoolConfiguration - ) - ) - )(pool => ZIO.fromCompletableFuture(pool.disconnect()).orDie) - } yield (ZioJAsyncConnection.make[C](pool)) - } - -} diff --git a/quill-jasync/src/main/scala/io/getquill/context/jasync/Decoders.scala b/quill-jasync/src/main/scala/io/getquill/context/jasync/Decoders.scala deleted file mode 100644 index bbfd1d3e6f..0000000000 --- a/quill-jasync/src/main/scala/io/getquill/context/jasync/Decoders.scala +++ /dev/null @@ -1,143 +0,0 @@ -package io.getquill.context.jasync - -import java.math.{BigDecimal => JavaBigDecimal} -import java.time._ -import java.util.Date - -import io.getquill.util.Messages.fail - -import scala.reflect.{ClassTag, classTag} - -trait Decoders { - this: JAsyncContext[_, _, _] => - - type Decoder[T] = AsyncDecoder[T] - - type DecoderSqlType = SqlTypes.SqlTypes - - case class AsyncDecoder[T](sqlType: DecoderSqlType)(implicit decoder: BaseDecoder[T]) extends BaseDecoder[T] { - override def apply(index: Index, row: ResultRow, session: Session) = - decoder(index, row, session) - } - - def decoder[T: ClassTag]( - f: PartialFunction[Any, T] = PartialFunction.empty, - sqlType: DecoderSqlType - ): Decoder[T] = - AsyncDecoder[T](sqlType)(new BaseDecoder[T] { - def apply(index: Index, row: ResultRow, session: Session) = - row.get(index) match { - case value: T => value - case value if f.isDefinedAt(value) => f(value) - case value => - fail( - s"Value '$value' at index $index can't be decoded to '${classTag[T].runtimeClass}'" - ) - } - }) - - implicit def mappedDecoder[I, O](implicit mapped: MappedEncoding[I, O], decoder: Decoder[I]): Decoder[O] = - AsyncDecoder(decoder.sqlType)(new BaseDecoder[O] { - def apply(index: Index, row: ResultRow, session: Session): O = - mapped.f(decoder.apply(index, row, session)) - }) - - trait NumericDecoder[T] extends BaseDecoder[T] { - - def apply(index: Index, row: ResultRow, session: Session) = - (row.get(index): Any) match { - case v: Byte => decode(v) - case v: Short => decode(v) - case v: Int => decode(v) - case v: Long => decode(v) - case v: Float => decode(v) - case v: Double => decode(v) - case v: JavaBigDecimal => decode(v: BigDecimal) - case other => - fail(s"Value $other is not numeric, type: ${other.getClass.getCanonicalName}") - } - - def decode[U](v: U)(implicit n: Numeric[U]): T - } - - implicit def optionDecoder[T](implicit d: Decoder[T]): Decoder[Option[T]] = - AsyncDecoder(d.sqlType)(new BaseDecoder[Option[T]] { - def apply(index: Index, row: ResultRow, session: Session) = - row.get(index) match { - case null => None - case value => Some(d(index, row, session)) - } - }) - - implicit val stringDecoder: Decoder[String] = decoder[String](PartialFunction.empty, SqlTypes.VARCHAR) - - implicit val bigDecimalDecoder: Decoder[BigDecimal] = - AsyncDecoder(SqlTypes.REAL)(new NumericDecoder[BigDecimal] { - def decode[U](v: U)(implicit n: Numeric[U]) = - BigDecimal(n.toDouble(v)) - }) - - implicit val booleanDecoder: Decoder[Boolean] = - decoder[Boolean]( - { - case v: Byte => v == (1: Byte) - case v: Short => v == (1: Short) - case v: Int => v == 1 - case v: Long => v == 1L - }, - SqlTypes.BOOLEAN - ) - - implicit val byteDecoder: Decoder[Byte] = - decoder[Byte]( - { case v: Short => - v.toByte - }, - SqlTypes.TINYINT - ) - - implicit val shortDecoder: Decoder[Short] = - decoder[Short]( - { case v: Byte => - v.toShort - }, - SqlTypes.SMALLINT - ) - - implicit val intDecoder: Decoder[Int] = - AsyncDecoder(SqlTypes.INTEGER)(new NumericDecoder[Int] { - def decode[U](v: U)(implicit n: Numeric[U]) = - n.toInt(v) - }) - - implicit val longDecoder: Decoder[Long] = - AsyncDecoder(SqlTypes.BIGINT)(new NumericDecoder[Long] { - def decode[U](v: U)(implicit n: Numeric[U]) = - n.toLong(v) - }) - - implicit val floatDecoder: Decoder[Float] = - AsyncDecoder(SqlTypes.FLOAT)(new NumericDecoder[Float] { - def decode[U](v: U)(implicit n: Numeric[U]) = - n.toFloat(v) - }) - - implicit val doubleDecoder: Decoder[Double] = - AsyncDecoder(SqlTypes.DOUBLE)(new NumericDecoder[Double] { - def decode[U](v: U)(implicit n: Numeric[U]) = - n.toDouble(v) - }) - - implicit val byteArrayDecoder: Decoder[Array[Byte]] = decoder[Array[Byte]](PartialFunction.empty, SqlTypes.TINYINT) - - implicit val dateDecoder: Decoder[Date] = decoder[Date]( - { - case date: LocalDateTime => Date.from(date.atZone(dateTimeZone).toInstant) - case date: LocalDate => Date.from(date.atStartOfDay.atZone(dateTimeZone).toInstant) - }, - SqlTypes.TIMESTAMP - ) - implicit val localDateDecoder: Decoder[LocalDate] = decoder[LocalDate](PartialFunction.empty, SqlTypes.DATE) - implicit val localDateTimeDecoder: Decoder[LocalDateTime] = - decoder[LocalDateTime](PartialFunction.empty, SqlTypes.TIMESTAMP) -} diff --git a/quill-jasync/src/main/scala/io/getquill/context/jasync/Encoders.scala b/quill-jasync/src/main/scala/io/getquill/context/jasync/Encoders.scala deleted file mode 100644 index dff73b8494..0000000000 --- a/quill-jasync/src/main/scala/io/getquill/context/jasync/Encoders.scala +++ /dev/null @@ -1,63 +0,0 @@ -package io.getquill.context.jasync - -import java.time.{LocalDate, LocalDateTime, OffsetDateTime} -import java.util.Date - -trait Encoders { - this: JAsyncContext[_, _, _] => - - type Encoder[T] = AsyncEncoder[T] - - type EncoderSqlType = SqlTypes.SqlTypes - - case class AsyncEncoder[T](sqlType: DecoderSqlType)(implicit encoder: BaseEncoder[T]) extends BaseEncoder[T] { - override def apply(index: Index, value: T, row: PrepareRow, session: Session) = - encoder.apply(index, value, row, session) - } - - def encoder[T](sqlType: DecoderSqlType): Encoder[T] = - encoder(identity[T], sqlType) - - def encoder[T](f: T => Any, sqlType: DecoderSqlType): Encoder[T] = - AsyncEncoder[T](sqlType)(new BaseEncoder[T] { - def apply(index: Index, value: T, row: PrepareRow, session: Session) = - row :+ f(value) - }) - - implicit def mappedEncoder[I, O](implicit mapped: MappedEncoding[I, O], e: Encoder[O]): Encoder[I] = - AsyncEncoder(e.sqlType)(new BaseEncoder[I] { - def apply(index: Index, value: I, row: PrepareRow, session: Session) = - e(index, mapped.f(value), row, session) - }) - - implicit def optionEncoder[T](implicit d: Encoder[T]): Encoder[Option[T]] = - AsyncEncoder(d.sqlType)(new BaseEncoder[Option[T]] { - def apply(index: Index, value: Option[T], row: PrepareRow, session: Session) = - value match { - case None => nullEncoder(index, null, row, session) - case Some(v) => d(index, v, row, session) - } - }) - - private[this] val nullEncoder: Encoder[Null] = encoder[Null](SqlTypes.NULL) - - implicit val stringEncoder: Encoder[String] = encoder[String](SqlTypes.VARCHAR) - implicit val bigDecimalEncoder: Encoder[BigDecimal] = - encoder[BigDecimal]((bd: BigDecimal) => bd.bigDecimal, SqlTypes.REAL) - implicit val booleanEncoder: Encoder[Boolean] = encoder[Boolean](SqlTypes.BOOLEAN) - implicit val byteEncoder: Encoder[Byte] = encoder[Byte](SqlTypes.TINYINT) - implicit val shortEncoder: Encoder[Short] = encoder[Short](SqlTypes.SMALLINT) - implicit val intEncoder: Encoder[Int] = encoder[Int](SqlTypes.INTEGER) - implicit val longEncoder: Encoder[Long] = encoder[Long](SqlTypes.BIGINT) - implicit val floatEncoder: Encoder[Float] = encoder[Float](SqlTypes.FLOAT) - implicit val doubleEncoder: Encoder[Double] = encoder[Double](SqlTypes.DOUBLE) - implicit val byteArrayEncoder: Encoder[Array[Byte]] = encoder[Array[Byte]](SqlTypes.VARBINARY) - implicit val dateEncoder: Encoder[Date] = encoder[Date]( - (date: Date) => { - OffsetDateTime.ofInstant(date.toInstant, dateTimeZone).toLocalDateTime - }, - SqlTypes.TIMESTAMP - ) - implicit val localDateEncoder: Encoder[LocalDate] = encoder[LocalDate](SqlTypes.DATE) - implicit val localDateTimeEncoder: Encoder[LocalDateTime] = encoder[LocalDateTime](SqlTypes.TIMESTAMP) -} diff --git a/quill-jasync/src/main/scala/io/getquill/context/jasync/JAsyncContextConfig.scala b/quill-jasync/src/main/scala/io/getquill/context/jasync/JAsyncContextConfig.scala deleted file mode 100644 index 6e6bf8def4..0000000000 --- a/quill-jasync/src/main/scala/io/getquill/context/jasync/JAsyncContextConfig.scala +++ /dev/null @@ -1,78 +0,0 @@ -package io.getquill.context.jasync - -import java.nio.charset.Charset -import java.lang.{Long => JavaLong} - -import scala.jdk.CollectionConverters._ -import scala.util.Try - -import com.github.jasync.sql.db.ConcreteConnection -import com.github.jasync.sql.db.{ConnectionPoolConfiguration, ConnectionPoolConfigurationBuilder} -import com.github.jasync.sql.db.pool.ConnectionPool -import com.github.jasync.sql.db.Configuration -import com.github.jasync.sql.db.SSLConfiguration -import com.github.jasync.sql.db.pool.ObjectFactory -import com.github.jasync.sql.db.util.AbstractURIParser -import com.typesafe.config.Config - -abstract class JAsyncContextConfig[C <: ConcreteConnection]( - config: Config, - connectionFactory: Configuration => ObjectFactory[C], - uriParser: AbstractURIParser -) { - - private def getValue[T](path: String, getter: String => T) = Try(getter(path)) - private def getString(path: String) = getValue(path, config.getString).toOption - private def getInt(path: String) = getValue(path, config.getInt).toOption - private def getLong(path: String) = getValue(path, config.getLong).toOption - - private lazy val urlConfiguration: Configuration = getValue("url", config.getString) - .map(uriParser.parseOrDie(_, uriParser.getDEFAULT.getCharset)) - .getOrElse(uriParser.getDEFAULT) - - private lazy val default = new ConnectionPoolConfigurationBuilder().build() - - lazy val connectionPoolConfiguration = new ConnectionPoolConfiguration( - getString("host").getOrElse(urlConfiguration.getHost), - getInt("port").getOrElse(urlConfiguration.getPort), - getString("database").orElse(Option(urlConfiguration.getDatabase)).orNull, - getString("username").getOrElse(urlConfiguration.getUsername), - getString("password").orElse(Option(urlConfiguration.getPassword)).orNull, - getInt("maxActiveConnections").getOrElse(default.getMaxActiveConnections), - getLong("maxIdleTime").getOrElse(default.getMaxIdleTime), - getInt("maxPendingQueries").getOrElse(default.getMaxPendingQueries), - getLong("connectionValidationInterval").getOrElse(default.getConnectionValidationInterval), - getLong("connectionCreateTimeout").getOrElse(default.getConnectionCreateTimeout), - getLong("connectionTestTimeout").getOrElse(default.getConnectionTestTimeout), - getLong("queryTimeout") - .orElse(Option(urlConfiguration.getQueryTimeout).map(_.toMillis)) - .map(JavaLong.valueOf) - .orNull, - urlConfiguration.getEventLoopGroup, - urlConfiguration.getExecutionContext, - default.getCoroutineDispatcher, - new SSLConfiguration( - Map( - "sslmode" -> getString("sslmode"), - "sslrootcert" -> getString("sslrootcert"), - "sslcert" -> getString("sslcert"), - "sslkey" -> getString("sslkey") - ).collect { case (key, Some(value)) => - key -> value - }.asJava - ), - Try(Charset.forName(config.getString("charset"))).getOrElse(urlConfiguration.getCharset), - getInt("maximumMessageSize").getOrElse(urlConfiguration.getMaximumMessageSize), - urlConfiguration.getAllocator, - getString("applicationName").orElse(Option(urlConfiguration.getApplicationName)).orNull, - urlConfiguration.getInterceptors, - getLong("maxConnectionTtl").map(JavaLong.valueOf).orElse(Option(default.getMaxConnectionTtl)).orNull, - getString("currentSchema").orElse(Option(urlConfiguration.getCurrentSchema)).orNull - ) - - def pool = - new ConnectionPool[C]( - connectionFactory(connectionPoolConfiguration.getConnectionConfiguration), - connectionPoolConfiguration - ) -} diff --git a/quill-jasync/src/main/scala/io/getquill/context/jasync/SqlTypes.scala b/quill-jasync/src/main/scala/io/getquill/context/jasync/SqlTypes.scala deleted file mode 100644 index c4ff2c0f79..0000000000 --- a/quill-jasync/src/main/scala/io/getquill/context/jasync/SqlTypes.scala +++ /dev/null @@ -1,10 +0,0 @@ -package io.getquill.context.jasync - -object SqlTypes extends Enumeration { - type SqlTypes = Value - - val BIT, TINYINT, SMALLINT, INTEGER, BIGINT, FLOAT, REAL, DOUBLE, NUMERIC, DECIMAL, CHAR, VARCHAR, LONGVARCHAR, DATE, - TIME, TIMESTAMP, BINARY, VARBINARY, LONGVARBINARY, NULL, ARRAY, BLOB, BOOLEAN, TIME_WITH_TIMEZONE, - TIMESTAMP_WITH_TIMEZONE, UUID = Value - -} diff --git a/quill-jasync/src/main/scala/io/getquill/context/jasync/TransactionalExecutionContext.scala b/quill-jasync/src/main/scala/io/getquill/context/jasync/TransactionalExecutionContext.scala deleted file mode 100644 index 13e5b44acc..0000000000 --- a/quill-jasync/src/main/scala/io/getquill/context/jasync/TransactionalExecutionContext.scala +++ /dev/null @@ -1,14 +0,0 @@ -package io.getquill.context.jasync - -import com.github.jasync.sql.db.Connection - -import scala.concurrent.ExecutionContext - -case class TransactionalExecutionContext(ec: ExecutionContext, conn: Connection) extends ExecutionContext { - - def execute(runnable: Runnable): Unit = - ec.execute(runnable) - - def reportFailure(cause: Throwable): Unit = - ec.reportFailure(cause) -} diff --git a/quill-jasync/src/main/scala/io/getquill/context/jasync/UUIDObjectEncoding.scala b/quill-jasync/src/main/scala/io/getquill/context/jasync/UUIDObjectEncoding.scala deleted file mode 100644 index 8d066f4509..0000000000 --- a/quill-jasync/src/main/scala/io/getquill/context/jasync/UUIDObjectEncoding.scala +++ /dev/null @@ -1,16 +0,0 @@ -package io.getquill.context.jasync - -import java.util.UUID - -trait UUIDObjectEncoding { - this: JAsyncContext[_, _, _] => - - implicit val uuidEncoder: Encoder[UUID] = encoder[UUID](SqlTypes.UUID) - - implicit val uuidDecoder: Decoder[UUID] = - AsyncDecoder(SqlTypes.UUID)((index: Index, row: ResultRow, session: Session) => - row.get(index) match { - case value: UUID => value - } - ) -} diff --git a/quill-jasync/src/main/scala/io/getquill/context/jasync/UUIDStringEncoding.scala b/quill-jasync/src/main/scala/io/getquill/context/jasync/UUIDStringEncoding.scala deleted file mode 100644 index 5a98aa3f2c..0000000000 --- a/quill-jasync/src/main/scala/io/getquill/context/jasync/UUIDStringEncoding.scala +++ /dev/null @@ -1,16 +0,0 @@ -package io.getquill.context.jasync - -import java.util.UUID - -trait UUIDStringEncoding { - this: JAsyncContext[_, _, _] => - - implicit val uuidEncoder: Encoder[UUID] = encoder[UUID]((v: UUID) => v.toString, SqlTypes.UUID) - - implicit val uuidDecoder: Decoder[UUID] = - AsyncDecoder(SqlTypes.UUID)((index: Index, row: ResultRow, session: Session) => - row.get(index) match { - case value: String => UUID.fromString(value) - } - ) -} diff --git a/quill-jasync/src/test/resources/placeholder b/quill-jasync/src/test/resources/placeholder deleted file mode 100644 index 8b13789179..0000000000 --- a/quill-jasync/src/test/resources/placeholder +++ /dev/null @@ -1 +0,0 @@ - diff --git a/quill-jasync/src/test/scala/io/getquill/context/jasync/TransactionalExecutionContextSpec.scala b/quill-jasync/src/test/scala/io/getquill/context/jasync/TransactionalExecutionContextSpec.scala deleted file mode 100644 index 1302d3b4d6..0000000000 --- a/quill-jasync/src/test/scala/io/getquill/context/jasync/TransactionalExecutionContextSpec.scala +++ /dev/null @@ -1,37 +0,0 @@ -package io.getquill.context.jasync - -import io.getquill.base.Spec -import scala.concurrent.ExecutionContext -import scala.collection.mutable.ListBuffer - -class TransactionalExecutionContextSpec extends Spec { - - "uses the wrapped context to execute runnables" in { - val executed = ListBuffer[Runnable]() - val ec = new ExecutionContext { - def execute(r: Runnable): Unit = { - executed += r - r.run() - } - def reportFailure(t: Throwable): Unit = ??? - } - val runnable = new Runnable { - override def run() = {} - } - TransactionalExecutionContext(ec, null).execute(runnable) - executed.result() mustEqual List(runnable) - } - - "uses the wrapped context to report errors" in { - val reported = ListBuffer[Throwable]() - val ec = new ExecutionContext { - def execute(r: Runnable): Unit = ??? - def reportFailure(t: Throwable): Unit = { - val r = reported += t - } - } - val exception = new IllegalStateException - TransactionalExecutionContext(ec, null).reportFailure(exception) - reported.result() mustEqual List(exception) - } -} diff --git a/quill-jdbc/src/test/resources/logback.xml b/quill-jdbc/src/test/resources/logback.xml index 92853fcd8b..7650bf2b2a 100644 --- a/quill-jdbc/src/test/resources/logback.xml +++ b/quill-jdbc/src/test/resources/logback.xml @@ -9,7 +9,6 @@ -