From 713c7bc6ec8439c3e6b1bf3f335cfdd2858a924b Mon Sep 17 00:00:00 2001 From: Yummy-Yums <77977520+Yummy-Yums@users.noreply.github.com> Date: Fri, 27 Sep 2024 18:52:42 +0000 Subject: [PATCH] initial push --- README.md | 1 + build.sbt | 4 +- zio-quickstart-zquery/build.sbt | 22 +++++ .../src/test/resources/init.sql | 53 +++++++++++ .../scala/dev/zio/quickstart/Commons.scala | 95 +++++++++++++++++++ .../dev/zio/quickstart/JdbcRunnableSpec.scala | 74 +++++++++++++++ .../test/scala/dev/zio/quickstart/Pg.scala | 26 +++++ .../scala/dev/zio/quickstart/QuerySpec.scala | 80 ++++++++++++++++ 8 files changed, 354 insertions(+), 1 deletion(-) create mode 100644 zio-quickstart-zquery/build.sbt create mode 100644 zio-quickstart-zquery/src/test/resources/init.sql create mode 100644 zio-quickstart-zquery/src/test/scala/dev/zio/quickstart/Commons.scala create mode 100644 zio-quickstart-zquery/src/test/scala/dev/zio/quickstart/JdbcRunnableSpec.scala create mode 100644 zio-quickstart-zquery/src/test/scala/dev/zio/quickstart/Pg.scala create mode 100644 zio-quickstart-zquery/src/test/scala/dev/zio/quickstart/QuerySpec.scala diff --git a/README.md b/README.md index 2990290..e462d15 100644 --- a/README.md +++ b/README.md @@ -39,3 +39,4 @@ $ sbt run - [ZIO SQL](zio-quickstart-sql) - [ZIO Streams](zio-quickstart-streams) - [ZIO Schema](zio-quickstart-schema) +- [ZIO Zquery](zio-quickstart-zquery) diff --git a/build.sbt b/build.sbt index 55f0d18..0d2e163 100644 --- a/build.sbt +++ b/build.sbt @@ -40,7 +40,8 @@ lazy val root = `zio-quickstart-prelude`, `zio-quickstart-stm`, `zio-quickstart-sql`, - `zio-quickstart-schema` + `zio-quickstart-schema`, + `zio-quickstart-zquery` ) .settings( testFrameworks += new TestFramework("zio.test.sbt.ZTestFramework") @@ -64,3 +65,4 @@ lazy val `zio-quickstart-prelude` = project lazy val `zio-quickstart-stm` = project lazy val `zio-quickstart-sql` = project lazy val `zio-quickstart-schema` = project +lazy val `zio-quickstart-zquery` = project diff --git a/zio-quickstart-zquery/build.sbt b/zio-quickstart-zquery/build.sbt new file mode 100644 index 0000000..801cf7e --- /dev/null +++ b/zio-quickstart-zquery/build.sbt @@ -0,0 +1,22 @@ +scalaVersion := "2.13.12" +organization := "dev.zio" +name := "zio-quickstart-zquery" + +libraryDependencies ++= Seq( + "org.slf4j" % "slf4j-simple" % "2.0.13", + "dev.zio" %% "zio-sql" % "0.1.2", + "dev.zio" %% "zio-sql-postgres" % "0.1.2", + "dev.zio" %% "zio-query" % "0.7.6", + "org.postgresql" % "postgresql" % "42.7.3" % Compile, + "dev.zio" %% "zio-test" % "2.0.22" % Test, + "dev.zio" %% "zio-test-sbt" % "2.0.22" % Test, + "dev.zio" %% "zio-test-junit" % "2.0.22" % Test, + "org.testcontainers" % "testcontainers" % "1.19.7" % Test, + "org.testcontainers" % "database-commons" % "1.19.7" % Test, + "org.testcontainers" % "postgresql" % "1.19.7" % Test, + "org.testcontainers" % "jdbc" % "1.19.7" % Test, + "com.dimafeng" %% "testcontainers-scala-postgresql" % "0.41.3" % Test, + +) + +resolvers ++= Resolver.sonatypeOssRepos("snapshots") \ No newline at end of file diff --git a/zio-quickstart-zquery/src/test/resources/init.sql b/zio-quickstart-zquery/src/test/resources/init.sql new file mode 100644 index 0000000..dddb6b9 --- /dev/null +++ b/zio-quickstart-zquery/src/test/resources/init.sql @@ -0,0 +1,53 @@ +create table customers +( + id uuid not null primary key, + first_name varchar not null, + last_name varchar not null, + verified boolean not null, + dob date not null +); + +create table orders +( + id uuid not null primary key, + customer_id uuid not null, + order_date date not null +); + +insert into customers + (id, first_name, last_name, verified, dob) +values + ('60b01fc9-c902-4468-8d49-3c0f989def37', 'Ronald', 'Russell', true, '1983-01-05'), + ('f76c9ace-be07-4bf3-bd4c-4a9c62882e64', 'Terrence', 'Noel', true, '1999-11-02'), + ('784426a5-b90a-4759-afbb-571b7a0ba35e', 'Mila', 'Paterso', true, '1990-11-16'), + ('df8215a2-d5fd-4c6c-9984-801a1b3a2a0b', 'Alana', 'Murray', true, '1995-11-12'), + ('636ae137-5b1a-4c8c-b11f-c47c624d9cdc', 'Jose', 'Wiggins', false, '1987-03-23'); + +insert into orders + (id, customer_id, order_date) +values + ('04912093-cc2e-46ac-b64c-1bd7bb7758c3', '60b01fc9-c902-4468-8d49-3c0f989def37', '2019-03-25'), + ('a243fa42-817a-44ec-8b67-22193d212d82', '60b01fc9-c902-4468-8d49-3c0f989def37', '2018-06-04'), + ('9022dd0d-06d6-4a43-9121-2993fc7712a1', 'df8215a2-d5fd-4c6c-9984-801a1b3a2a0b', '2019-08-19'), + ('38d66d44-3cfa-488a-ac77-30277751418f', '636ae137-5b1a-4c8c-b11f-c47c624d9cdc', '2019-08-30'), + ('7b2627d5-0150-44df-9171-3462e20797ee', '636ae137-5b1a-4c8c-b11f-c47c624d9cdc', '2019-03-07'), + ('62cd4109-3e5d-40cc-8188-3899fc1f8bdf', '60b01fc9-c902-4468-8d49-3c0f989def37', '2020-03-19'), + ('9473a0bc-396a-4936-96b0-3eea922af36b', 'df8215a2-d5fd-4c6c-9984-801a1b3a2a0b', '2020-05-11'), + ('b8bac18d-769f-48ed-809d-4b6c0e4d1795', 'df8215a2-d5fd-4c6c-9984-801a1b3a2a0b', '2019-02-21'), + ('852e2dc9-4ec3-4225-a6f7-4f42f8ff728e', '60b01fc9-c902-4468-8d49-3c0f989def37', '2018-05-06'), + ('bebbfe4d-4ec3-4389-bdc2-50e9eac2b15b', '784426a5-b90a-4759-afbb-571b7a0ba35e', '2019-02-11'), + ('742d45a0-e81a-41ce-95ad-55b4cabba258', 'f76c9ace-be07-4bf3-bd4c-4a9c62882e64', '2019-10-12'), + ('618aa21f-700b-4ca7-933c-67066cf4cd97', '60b01fc9-c902-4468-8d49-3c0f989def37', '2019-01-29'), + ('606da090-dd33-4a77-8746-6ed0e8443ab2', 'f76c9ace-be07-4bf3-bd4c-4a9c62882e64', '2019-02-10'), + ('4914028d-2e28-4033-a5f2-8f4fcdee8206', '60b01fc9-c902-4468-8d49-3c0f989def37', '2019-09-27'), + ('d4e77298-d829-4e36-a6a0-902403f4b7d3', 'df8215a2-d5fd-4c6c-9984-801a1b3a2a0b', '2018-11-13'), + ('fd0fa8d4-e1a0-4369-be07-945450db5d36', '636ae137-5b1a-4c8c-b11f-c47c624d9cdc', '2020-01-15'), + ('d6d8dddc-4b0b-4d74-8edc-a54e9b7f35f7', 'f76c9ace-be07-4bf3-bd4c-4a9c62882e64', '2018-07-10'), + ('876b6034-b33c-4497-81ee-b4e8742164c2', '784426a5-b90a-4759-afbb-571b7a0ba35e', '2019-08-01'), + ('91caa28a-a5fe-40d7-979c-bd6a128d0418', 'df8215a2-d5fd-4c6c-9984-801a1b3a2a0b', '2019-12-08'), + ('401c7ab1-41cf-4756-8af5-be25cf2ae67b', '784426a5-b90a-4759-afbb-571b7a0ba35e', '2019-11-04'), + ('2c3fc180-d0df-4d7b-a271-e6ccd2440393', '784426a5-b90a-4759-afbb-571b7a0ba35e', '2018-10-14'), + ('763a7c39-833f-4ee8-9939-e80dfdbfc0fc', 'f76c9ace-be07-4bf3-bd4c-4a9c62882e64', '2020-04-05'), + ('5011d206-8eff-42c4-868e-f1a625e1f186', '636ae137-5b1a-4c8c-b11f-c47c624d9cdc', '2019-01-23'), + ('0a48ffb0-ec61-4147-af56-fc4dbca8de0a', 'f76c9ace-be07-4bf3-bd4c-4a9c62882e64', '2019-05-14'), + ('5883cb62-d792-4ee3-acbc-fe85b6baa998', '784426a5-b90a-4759-afbb-571b7a0ba35e', '2020-04-30'); \ No newline at end of file diff --git a/zio-quickstart-zquery/src/test/scala/dev/zio/quickstart/Commons.scala b/zio-quickstart-zquery/src/test/scala/dev/zio/quickstart/Commons.scala new file mode 100644 index 0000000..d9018f4 --- /dev/null +++ b/zio-quickstart-zquery/src/test/scala/dev/zio/quickstart/Commons.scala @@ -0,0 +1,95 @@ +package dev.zio.quickstart + +import Pg._ +import zio._ +import zio.schema.DeriveSchema + +import java.time.LocalDate +import java.util.UUID + +object DatabaseQueriesActor { + + object Customerr{ + + case class Customer( + id: UUID, + firstName: String, + lastName: String, + verified: Boolean, + dob: LocalDate) + + implicit val customerschema= DeriveSchema.gen[Customer] + val customers = defineTableSmart[Customer] + + val (customerid, firstName, lastName, verified, dob) = customers.columns + + val all: List[Any] = customerid :: firstName :: lastName :: verified :: dob :: Nil + + } + + object Order{ + case class Order( + id: UUID, + customerId: UUID, + order_date: LocalDate, + ) + implicit val orderDetailsSchema = DeriveSchema.gen[Order] + val orderDetails = defineTableSmart[Order] + val (id, customerId, order_date) = orderDetails.columns + } + + import Customerr._ + + val getFirstCustomerIdDbQuery: ZIO[SqlDriver, Exception, UUID] = { + val query = + select(customerid, firstName, lastName, verified, dob) + .from(customers) + .to { case (id, firstName, lastName, verified, dob) => + Customer(id, firstName, lastName, verified, dob) + } + + execute(query).runHead.map(_.get.id) + } + + val getAllCustomerIdsDbQuery: ZIO[SqlDriver, Exception, List[UUID]] = { + + val query = + select(customerid, firstName, lastName, verified, dob) + .from(customers) + .to { case (id, firstName, lastName, verified, dob) => + Customer(id, firstName, lastName, verified, dob) + } + + execute(query).runFold(List.empty[UUID]){ + case (list, customer) => list :+ customer.id + } + } + + val id = UUID.fromString("60b01fc9-c902-4468-8d49-3c0f989def37") + + + def getSingleOrderbyCustomerIdDbQuery(customerId: UUID): ZIO[SqlDriver, Exception, Order.Order] = { + val getSingleOrder = + select(Order.id, Order.customerId, Order.order_date) + .from(Order.orderDetails) + .where(Order.customerId === customerId) + .to { case (id, customerId, order_date) => + Order.Order(id, customerId, order_date) + } + execute(getSingleOrder).runCollect.map(_.toList.head) + } + + def getOrdersByCustomerIdDbQuery(customerIds: List[UUID]) = { + val getallOrders = + select(Order.id, Order.customerId, Order.order_date) + .from(Order.orderDetails) + .where(Order.customerId in customerIds) + .to { case (id, customerId, order_date) => + Order.Order(id, customerId, order_date) + } + execute(getallOrders).runCollect.map(_.toList) + + } + + +} \ No newline at end of file diff --git a/zio-quickstart-zquery/src/test/scala/dev/zio/quickstart/JdbcRunnableSpec.scala b/zio-quickstart-zquery/src/test/scala/dev/zio/quickstart/JdbcRunnableSpec.scala new file mode 100644 index 0000000..da790f0 --- /dev/null +++ b/zio-quickstart-zquery/src/test/scala/dev/zio/quickstart/JdbcRunnableSpec.scala @@ -0,0 +1,74 @@ +package dev.zio.quickstart + +import com.dimafeng.testcontainers.{JdbcDatabaseContainer, PostgreSQLContainer, SingleContainer} +import org.testcontainers.utility.DockerImageName +import zio.sql.{ConnectionPool, ConnectionPoolConfig} +import zio.{Scope, ZIO, ZLayer} +import zio.sql.postgresql.PostgresJdbcModule +import zio.test.{Spec, TestEnvironment, ZIOSpecDefault} + + +import java.util.Properties + +trait JdbcRunnableSpec extends ZIOSpecDefault with PostgresJdbcModule { + + type JdbcEnvironment = TestEnvironment with SqlDriver + + protected def specLayered: Spec[JdbcEnvironment, Object] + + def spec: Spec[TestEnvironment, Any] = + specLayered.provideCustomShared(jdbcLayer) + + def getContainer: SingleContainer[_] with JdbcDatabaseContainer = + new PostgreSQLContainer( + dockerImageNameOverride = Option("postgres").map(DockerImageName.parse) + ).configure { a => + a.withInitScript("init.sql") + () + } + + protected val autoCommit = false + + private[this] def connProperties( + user: String, + password: String + ): Properties = { + val props = new Properties + props.setProperty("user", user) + props.setProperty("password", password) + props + } + + private[this] val poolConfigLayer = + ZLayer.scoped { + testContainer + .map(a => + ConnectionPoolConfig( + url = a.jdbcUrl, + properties = connProperties(a.username, a.password) + ) + ) + } + + private[this] final lazy val jdbcLayer: ZLayer[Any, Any, SqlDriver] = + ZLayer.make[SqlDriver]( + connectionPool.orDie, + SqlDriver.live + ) + + val connectionPool: ZLayer[Any, Throwable, ConnectionPool] = + poolConfigLayer >>> ConnectionPool.live + + private[this] val testContainer: ZIO[Any with Scope, Throwable, SingleContainer[_] with JdbcDatabaseContainer] = + ZIO.acquireRelease { + ZIO.attemptBlocking { + val container = getContainer + container.start() + container + } + }{ container => + ZIO.attemptBlocking(container.stop()).orDie + } + + +} diff --git a/zio-quickstart-zquery/src/test/scala/dev/zio/quickstart/Pg.scala b/zio-quickstart-zquery/src/test/scala/dev/zio/quickstart/Pg.scala new file mode 100644 index 0000000..357f288 --- /dev/null +++ b/zio-quickstart-zquery/src/test/scala/dev/zio/quickstart/Pg.scala @@ -0,0 +1,26 @@ +package dev.zio.quickstart + +import com.dimafeng.testcontainers.PostgreSQLContainer +import zio._ +import zio.schema.{DeriveSchema, Schema} +import zio.test.{Spec, assertTrue} + +import java.time.LocalDate +import java.util.UUID + +import org.testcontainers.utility.DockerImageName + +import java.sql.DriverManager + +object Pg extends JdbcRunnableSpec { + + def specLayered: Spec[Pg.JdbcEnvironment, Object] = + suite("Checking"){ + test("er"){ + for{ + url <- ZIO.succeed(getContainer.username) + _ <- ZIO.succeed("") + } yield assertTrue(url == "ew") + } + } +} diff --git a/zio-quickstart-zquery/src/test/scala/dev/zio/quickstart/QuerySpec.scala b/zio-quickstart-zquery/src/test/scala/dev/zio/quickstart/QuerySpec.scala new file mode 100644 index 0000000..fa838c2 --- /dev/null +++ b/zio-quickstart-zquery/src/test/scala/dev/zio/quickstart/QuerySpec.scala @@ -0,0 +1,80 @@ +package dev.zio.quickstart + +import DatabaseQueriesActor.Order +import zio.test._ + +import java.time.LocalDate + + +object QueryingSpec extends JdbcRunnableSpec { + + import zio._ + import zio.query._ + + import java.util.UUID + + case object GetAllUserIds extends Request[Throwable, List[UUID]] + + + object CustomerIdDataSource extends DataSource.Batched[Any, GetAllUserIds.type] { + val identifier: String = "UserIdDataSource" + + def run(requests: Chunk[GetAllUserIds.type])(implicit trace: Trace): ZIO[Any, Nothing, CompletedRequestMap] = + (ZIO.succeed { + val result = Queriess.getAllCustomerIds + result.foldZIO( + err => ZIO.succeed(CompletedRequestMap.empty.insert(GetAllUserIds, Exit.fail(err))), + ids => ZIO.succeed(CompletedRequestMap.empty.insert(GetAllUserIds, Exit.succeed(ids))) + ) + }.flatten).provideLayer(jdbcLayer) + + object Queriess { + def getAllCustomerIds: ZIO[Any, Throwable, List[UUID]] = + DatabaseQueriesActor.getAllCustomerIdsDbQuery.provideLayer(jdbcLayer) + + def getUserNameById(id: UUID): ZIO[Any, Exception, Order.Order] = { + DatabaseQueriesActor.getSingleOrderbyCustomerIdDbQuery(id).provideLayer(jdbcLayer) + } + } + + } + + + object UserQueries { + val getAllUserIds: ZQuery[Any, Throwable, List[UUID]] = + ZQuery.fromRequest(GetAllUserIds)(CustomerIdDataSource) + + val provisionalResults = List( + UUID.fromString("60b01fc9-c902-4468-8d49-3c0f989def37"), + UUID.fromString("f76c9ace-be07-4bf3-bd4c-4a9c62882e64"), + UUID.fromString("784426a5-b90a-4759-afbb-571b7a0ba35e"), + UUID.fromString("df8215a2-d5fd-4c6c-9984-801a1b3a2a0b"), + UUID.fromString("636ae137-5b1a-4c8c-b11f-c47c624d9cdc") + ) + } + + lazy val jdbcLayer: ZLayer[Any, Nothing, Pg.SqlDriver] = + ZLayer.make[Pg.SqlDriver]( + connectionPool.orDie, + Pg.SqlDriver.live + ) + + def specLayered: Spec[QueryingSpec.SqlDriver, Object] = suite("QueryingSpec")( + test("fetching all user IDs") { + val allIds = for { + ids <- UserQueries.getAllUserIds.run + + } yield ids + + for { + _ <- Console.printLine("Starting something") + currTime = java.lang.System.nanoTime() + res <- allIds + doneTime = java.lang.System.nanoTime() - currTime + _ <- Console.printLine("with zquery => " + (doneTime / 1000000)) + // _ <- Console.printLine(res) + } yield assertCompletes && assertTrue(res.size == 5) && assertTrue(res == UserQueries.provisionalResults) + } + ) + +}