Skip to content

Commit

Permalink
selectEntry available for both Doobie and Slick modules
Browse files Browse the repository at this point in the history
  • Loading branch information
salamonpavel committed Dec 8, 2023
1 parent 5f95411 commit 6cd018d
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 39 deletions.
30 changes: 25 additions & 5 deletions core/src/main/scala/za/co/absa/fadb/DBFunctionFabric.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,13 @@ package za.co.absa.fadb
* that offer certain implementations. This trait should help with the inheritance of all of these
*/
abstract class DBFunctionFabric(functionNameOverride: Option[String])(implicit val schema: DBSchema) {

/**
* List of fields to select from the DB function.
* @return - list of fields to select
* Alias of the function, based on the class name
*/
def fieldsToSelect: Seq[String] = Seq.empty
protected val alias = "FNC"

/**
* Name of the function, based on the class name, unless it is overridden in the constructor
* Name of the function, based on the class name, unless it is overridden in the constructor
*/
val functionName: String = {
val fn = functionNameOverride.getOrElse(schema.objectNameFromClassName(getClass))
Expand All @@ -40,4 +38,26 @@ abstract class DBFunctionFabric(functionNameOverride: Option[String])(implicit v
}
}

/**
* List of fields to select from the DB function.
* @return - list of fields to select
*/
def fieldsToSelect: Seq[String] = Seq.empty

/*
* Generates a list of select columns for the function
*/
protected def selectEntry: String = {
val fieldsSeq = fieldsToSelect
if (fieldsSeq.isEmpty) {
"*"
} else {
val aliasToUse = if (alias.isEmpty) {
""
} else {
s"$alias."
}
fieldsToSelect.map(aliasToUse + _).mkString(",")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,13 @@ class DoobieSingleResultFunctionTest extends AnyFunSuite with DoobieTest {
class CreateActor(implicit schema: DBSchema, dbEngine: DoobieEngine[IO])
extends DoobieSingleResultFunction[CreateActorRequestBody, Int, IO] {

// do not remove the example below
// override def fieldsToSelect: Seq[String] = super.fieldsToSelect ++ Seq("o_actor_id")

override def sql(values: CreateActorRequestBody)(implicit read: Read[Int]): Fragment =
sql"SELECT o_actor_id FROM ${Fragment.const(functionName)}(${values.firstName}, ${values.lastName})"
// do not remove the example below, it has to be used with the override def fieldsToSelect
// sql"SELECT ${Fragment.const(selectEntry)} FROM ${Fragment.const(functionName)}(${values.firstName}, ${values.lastName}) ${Fragment.const(alias)}"
}

private val createActor = new CreateActor()(Runs, new DoobieEngine(transactor))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import za.co.absa.fadb.{DBFunctionWithStatus, DBSchema, FunctionStatusWithData}
import scala.language.higherKinds

trait DoobieFunctionBase[R] {

/**
* The `Read[R]` instance used to read the query result into `R`.
*/
Expand All @@ -41,7 +40,6 @@ trait DoobieFunctionBase[R] {
* @tparam R the result type of the function
*/
private[doobie] trait DoobieFunction[I, R] extends DoobieFunctionBase[R] {

/**
* Generates a Doobie `Fragment` representing the SQL query for the function.
*
Expand All @@ -60,9 +58,6 @@ private[doobie] trait DoobieFunction[I, R] extends DoobieFunctionBase[R] {
}

private[doobie] trait DoobieFunctionWithStatus[I, R] extends DoobieFunctionBase[R] {

def checkStatus[A](statusWithData: FunctionStatusWithData[A]): Either[StatusException, A]

/**
* The `Read[StatusWithData[R]]` instance used to read the query result with status into `StatusWithData[R]`.
*/
Expand All @@ -85,14 +80,16 @@ private[doobie] trait DoobieFunctionWithStatus[I, R] extends DoobieFunctionBase[
* @return the `DoobieQueryWithStatus[R]` representing the SQL query
*/
protected def query(values: I): DoobieQueryWithStatus[R] = new DoobieQueryWithStatus[R](sql(values), checkStatus)

// This is to be mixed in by an implementation of StatusHandling
def checkStatus[A](statusWithData: FunctionStatusWithData[A]): Either[StatusException, A]
}

/**
* `DoobieFunction` is an object that contains several abstract classes extending different types of database functions.
* These classes use Doobie's `Fragment` to represent SQL queries and `DoobieEngine` to execute them.
*/
object DoobieFunction {

/**
* `DoobieSingleResultFunctionWithStatus` is an abstract class that extends `DBSingleResultFunctionWithStatus` with `DoobiePgEngine` as the engine type.
* It represents a database function that returns a single result with status.
Expand Down
28 changes: 0 additions & 28 deletions slick/src/main/scala/za/co/absa/fadb/slick/SlickFunction.scala
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import scala.concurrent.Future
* @tparam R the result type of the function
*/
private[slick] trait SlickFunctionBase[I, R] {

/**
* The `GetResult[R]` instance used to read the query result into `R`.
*/
Expand All @@ -47,34 +46,9 @@ private[slick] trait SlickFunctionBase[I, R] {
protected def sql(values: I): SQLActionBuilder

def fieldsToSelect: Seq[String]

/**
* Alias to use within the SQL query
*/
protected val alias = "FNC"

/**
* Helper function to use in the actual DB function class
*
* @return the SELECT part of the function call SQL query
*/
protected def selectEntry: String = {
val fieldsSeq = fieldsToSelect
if (fieldsSeq.isEmpty) {
"*"
} else {
val aliasToUse = if (alias.isEmpty) {
""
} else {
s"$alias."
}
fieldsToSelect.map(aliasToUse + _).mkString(",")
}
}
}

private[slick] trait SlickFunction[I, R] extends SlickFunctionBase[I, R] {

/**
* Generates a `SlickQuery[R]` representing the SQL query for the function.
*
Expand All @@ -85,7 +59,6 @@ private[slick] trait SlickFunction[I, R] extends SlickFunctionBase[I, R] {
}

private[slick] trait SlickFunctionWithStatus[I, R] extends SlickFunctionBase[I, R] {

/**
* Generates a `SlickQueryWithStatus[R]` representing the SQL query for the function with status support.
*
Expand All @@ -100,7 +73,6 @@ private[slick] trait SlickFunctionWithStatus[I, R] extends SlickFunctionBase[I,
}

object SlickFunction {

/**
* Class for Slick DB functions with status support.
*/
Expand Down

0 comments on commit 6cd018d

Please sign in to comment.