Skip to content

Commit

Permalink
#118: adding support for MultipleResultFunction with status for Doobie
Browse files Browse the repository at this point in the history
  • Loading branch information
lsulak committed Mar 25, 2024
1 parent f25f70f commit 05f4a21
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ It brings:
* `class DoobieMultipleResultFunction` - abstract class for DB functions returning sequence of results
* `class DoobieOptionalResultFunction` - abstract class for DB functions returning optional result
* `class DoobieSingleResultFunctionWithStatus` - abstract class for DB functions with status handling; it requires an implementation of `StatusHandling` to be mixed-in (`StandardStatusHandling` available out-of-the-box)
* `class DoobieMultipleResultFunctionWithStatus` - as `DoobieSingleResultFunctionWithStatus` but for multiple record retrieval

Since Doobie also interoperates with ZIO, there is an example of how a database connection can be properly established within a ZIO application. Please see [this file](doobie/zio-setup.md) for more details.

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* Copyright 2022 ABSA Group Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package za.co.absa.fadb.doobie

import cats.effect.IO
import cats.effect.unsafe.implicits.global
import doobie.Fragment
import doobie.implicits.toSqlInterpolator
import org.scalatest.funsuite.AnyFunSuite
import za.co.absa.fadb.DBSchema
import za.co.absa.fadb.doobie.DoobieFunction.DoobieMultipleResultFunctionWithStatus
import za.co.absa.fadb.status.handling.implementations.StandardStatusHandling

class DoobieMultipleResultFunctionWithStatusTest extends AnyFunSuite with DoobieTest {

private val getActorsByLastnameQueryFragments: GetActorsByLastnameQueryParameters => Seq[Fragment] = {
values => Seq(fr"${values.lastName}", fr"${values.firstName}")
}

class GetActorsByLastname(implicit schema: DBSchema, dbEngine: DoobieEngine[IO])
extends DoobieMultipleResultFunctionWithStatus[GetActorsByLastnameQueryParameters, Option[Actor], IO](getActorsByLastnameQueryFragments)
with StandardStatusHandling {
override def fieldsToSelect: Seq[String] = super.fieldsToSelect ++ Seq("actor_id", "first_name", "last_name")
}

private val getActorsByLastname = new GetActorsByLastname()(Integration, new DoobieEngine(transactor))

test("Retrieving actor from database, full match") {
val expectedResultElem = Actor(50, "Liza", "Simpson")
val results = getActorsByLastname(GetActorsByLastnameQueryParameters("Simpson", Some("Liza"))).unsafeRunSync()

results match {
case Left(_) => fail("should not be left")
case Right(value) =>
assert(value.contains(expectedResultElem))
}
}

test("Retrieving actor from database, lastname match") {
val expectedResultElem = Actor(50, "Liza", "Simpson")
val results = getActorsByLastname(GetActorsByLastnameQueryParameters("Simpson")).unsafeRunSync()

results match {
case Left(_) => fail("should not be left")
case Right(value) =>
assert(value.contains(expectedResultElem))
}
}

test("Retrieving actor from database, no match") {
val results = getActorsByLastname(GetActorsByLastnameQueryParameters("TotallyNonExisting!")).unsafeRunSync()

results match {
case Left(value) =>
assert(value.status.statusText == "No actor found")
assert(value.status.statusCode == 41)
case Right(_) => fail("should not be right")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import za.co.absa.fadb.DBSchema
trait DoobieTest {
case class Actor(actorId: Int, firstName: String, lastName: String)
case class GetActorsQueryParameters(firstName: Option[String], lastName: Option[String])
case class GetActorsByLastnameQueryParameters(lastName: String, firstName: Option[String] = None)
case class CreateActorRequestBody(firstName: String, lastName: String)

import za.co.absa.fadb.naming.implementations.SnakeCaseNaming.Implicits._
Expand Down
13 changes: 13 additions & 0 deletions doobie/src/main/scala/za/co/absa/fadb/doobie/DoobieFunction.scala
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,19 @@ object DoobieFunction {
) extends DBMultipleResultFunction[I, R, DoobieEngine[F], F](functionNameOverride)
with DoobieFunction[I, R, F]

/**
* `DoobieMultipleResultFunctionWithStatus` represents a db function that returns multiple results with statuses.
*/
abstract class DoobieMultipleResultFunctionWithStatus[I, R, F[_]](
override val toFragmentsSeq: I => Seq[Fragment],
functionNameOverride: Option[String] = None
)(implicit
override val schema: DBSchema,
val dbEngine: DoobieEngine[F],
val readR: Read[R]
) extends DBFunctionWithStatus[I, R, DoobieEngine[F], F](functionNameOverride)
with DoobieFunctionWithStatus[I, R, F]

/**
* `DoobieOptionalResultFunction` represents a db function that returns an optional result.
*/
Expand Down

0 comments on commit 05f4a21

Please sign in to comment.