Skip to content

Commit

Permalink
DBFunction and DBSchema refactored
Browse files Browse the repository at this point in the history
  • Loading branch information
salamonpavel committed Dec 1, 2023
1 parent 5045b8a commit 0932546
Show file tree
Hide file tree
Showing 5 changed files with 212 additions and 255 deletions.
170 changes: 64 additions & 106 deletions core/src/main/scala/za/co/absa/fadb/DBFunction.scala
Original file line number Diff line number Diff line change
Expand Up @@ -30,34 +30,24 @@ import scala.concurrent.Future
* @tparam R - the type covering the returned fields from the database function
* @tparam E - the type of the [[DBEngine]] engine
*/
abstract class DBFunction[I, R, E <: DBEngine](functionNameOverride: Option[String] = None)
(implicit val schema: DBSchema, val dBEngine: E) extends DBFunctionFabric {

/* alternative constructors for different availability of input parameters */
def this(functionNameOverride: String)
(implicit schema: DBSchema, dBEngine: E) = {
this(Option(functionNameOverride))(schema, dBEngine)
abstract class DBFunction[I, R, E <: DBEngine](functionNameOverride: Option[String] = None, schema: Option[DBSchema])
(implicit val dBEngine: E, val namingConvention: NamingConvention)
extends DBFunctionFabric {

// Alternative constructors for different availability of input parameters
def this(functionNameOverride: String, schema: DBSchema)
(implicit dBEngine: E, namingConvention: NamingConvention) = {
this(Option(functionNameOverride), Option(schema))
}

def this(schema: DBSchema, functionNameOverride: String)
(implicit dBEngine: E) = {
this(Option(functionNameOverride))(schema, dBEngine)
def this(functionNameOverride: String)
(implicit schema: Option[DBSchema], dBEngine: E, namingConvention: NamingConvention) = {
this(Option(functionNameOverride), schema)
}

/* only one constructor of a class can have default values for parameters*/
def this(schema: DBSchema)
(implicit dBEngine: E) = {
this(None)(schema, dBEngine)
}

def this(dBEngine: E, functionNameOverride: String)
(implicit schema: DBSchema) = {
this(Option(functionNameOverride))(schema, dBEngine)
}

def this(dBEngine: E)
(implicit schema: DBSchema) = {
this(None)(schema, dBEngine)
(implicit dBEngine: E, namingConvention: NamingConvention) = {
this(None, Option(schema))
}

/**
Expand All @@ -71,17 +61,15 @@ abstract class DBFunction[I, R, E <: DBEngine](functionNameOverride: Option[Stri
/**
* 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))
if (schema.schemaName.isEmpty) {
fn
} else {
s"${schema.schemaName}.$fn"
def functionName: String = {
schema match {
case Some(s) if s.schemaName.nonEmpty =>
s"${s.schemaName}.${functionNameOverride.getOrElse(namingConvention.fromClassNamePerConvention(getClass))}"
case _ =>
functionNameOverride.getOrElse(namingConvention.fromClassNamePerConvention(getClass))
}
}

def namingConvention: NamingConvention = schema.namingConvention

/**
* List of fields to select from the DB function. Expected to be based on the return type `R`
* @return - list of fields to select
Expand All @@ -107,34 +95,24 @@ object DBFunction {
* @tparam R - the type covering the returned fields from the database function
* @tparam E - the type of the [[DBEngine]] engine
*/
abstract class DBMultipleResultFunction[I, R, E <: DBEngine](functionNameOverride: Option[String] = None)
(implicit schema: DBSchema, dBEngine: E)
extends DBFunction[I, R, E](functionNameOverride) {

def this(functionNameOverride: String)
(implicit schema: DBSchema, dBEngine: E) = {
this(Option(functionNameOverride))(schema, dBEngine)
}

def this(schema: DBSchema, functionNameOverride: String)
(implicit dBEngine: E) = {
this(Option(functionNameOverride))(schema, dBEngine)
}
abstract class DBMultipleResultFunction[I, R, E <: DBEngine](functionNameOverride: Option[String] = None, schema: Option[DBSchema] = None)
(implicit override val dBEngine: E, override val namingConvention: NamingConvention)
extends DBFunction[I, R, E](functionNameOverride, schema) {

def this(schema: DBSchema)
(implicit dBEngine: E) = {
this(None)(schema, dBEngine)
}
def this(functionNameOverride: String, schema: DBSchema)
(implicit dBEngine: E, namingConvention: NamingConvention) = {
this(Option(functionNameOverride), Option(schema))
}

def this(dBEngine: E, functionNameOverride: String)
(implicit schema: DBSchema) = {
this(Option(functionNameOverride))(schema, dBEngine)
}
def this(functionNameOverride: String)
(implicit schema: Option[DBSchema], dBEngine: E, namingConvention: NamingConvention) = {
this(Option(functionNameOverride), schema)
}

def this(dBEngine: E)
(implicit schema: DBSchema) = {
this(None)(schema, dBEngine)
}
def this(schema: DBSchema)
(implicit dBEngine: E, namingConvention: NamingConvention) = {
this(None, Option(schema))
}

/**
* For easy and convenient execution of the DB function call
Expand All @@ -156,34 +134,24 @@ object DBFunction {
* @tparam R - the type covering the returned fields from the database function
* @tparam E - the type of the [[DBEngine]] engine
*/
abstract class DBSingleResultFunction[I, R, E <: DBEngine](functionNameOverride: Option[String] = None)
(implicit schema: DBSchema, dBEngine: E)
extends DBFunction[I, R, E](functionNameOverride) {

def this(functionNameOverride: String)
(implicit schema: DBSchema, dBEngine: E) = {
this(Option(functionNameOverride))(schema, dBEngine)
}
abstract class DBSingleResultFunction[I, R, E <: DBEngine](functionNameOverride: Option[String] = None, schema: Option[DBSchema] = None)
(implicit override val dBEngine: E, override val namingConvention: NamingConvention)
extends DBFunction[I, R, E](functionNameOverride, schema) {

def this(schema: DBSchema, functionNameOverride: String)
(implicit dBEngine: E) = {
this(Option(functionNameOverride))(schema, dBEngine)
}

def this(schema: DBSchema)
(implicit dBEngine: E) = {
this(None)(schema, dBEngine)
}
def this(functionNameOverride: String, schema: DBSchema)
(implicit dBEngine: E, namingConvention: NamingConvention) = {
this(Option(functionNameOverride), Option(schema))
}

def this(dBEngine: E, functionNameOverride: String)
(implicit schema: DBSchema) = {
this(Option(functionNameOverride))(schema, dBEngine)
}
def this(functionNameOverride: String)
(implicit schema: Option[DBSchema], dBEngine: E, namingConvention: NamingConvention) = {
this(Option(functionNameOverride), schema)
}

def this(dBEngine: E)
(implicit schema: DBSchema) = {
this(None)(schema, dBEngine)
}
def this(schema: DBSchema)
(implicit dBEngine: E, namingConvention: NamingConvention) = {
this(None, Option(schema))
}

/**
* For easy and convenient execution of the DB function call
Expand All @@ -204,34 +172,24 @@ object DBFunction {
* @tparam R - the type covering the returned fields from the database function
* @tparam E - the type of the [[DBEngine]] engine
*/
abstract class DBOptionalResultFunction[I, R, E <: DBEngine](functionNameOverride: Option[String] = None)
(implicit schema: DBSchema, dBEngine: E)
extends DBFunction[I, R, E](functionNameOverride) {

def this(functionNameOverride: String)
(implicit schema: DBSchema, dBEngine: E) = {
this(Option(functionNameOverride))(schema, dBEngine)
}

def this(schema: DBSchema, functionNameOverride: String)
(implicit dBEngine: E) = {
this(Option(functionNameOverride))(schema, dBEngine)
}
abstract class DBOptionalResultFunction[I, R, E <: DBEngine](functionNameOverride: Option[String] = None, schema: Option[DBSchema] = None)
(implicit override val dBEngine: E, override val namingConvention: NamingConvention)
extends DBFunction[I, R, E](functionNameOverride, schema) {

def this(schema: DBSchema)
(implicit dBEngine: E) = {
this(None)(schema, dBEngine)
}
def this(functionNameOverride: String, schema: DBSchema)
(implicit dBEngine: E, namingConvention: NamingConvention) = {
this(Option(functionNameOverride), Option(schema))
}

def this(dBEngine: E, functionNameOverride: String)
(implicit schema: DBSchema) = {
this(Option(functionNameOverride))(schema, dBEngine)
}
def this(functionNameOverride: String)
(implicit schema: Option[DBSchema], dBEngine: E, namingConvention: NamingConvention) = {
this(Option(functionNameOverride), schema)
}

def this(dBEngine: E)
(implicit schema: DBSchema) = {
this(None)(schema, dBEngine)
}
def this(schema: DBSchema)
(implicit dBEngine: E, namingConvention: NamingConvention) = {
this(None, Option(schema))
}

/**
* For easy and convenient execution of the DB function call
Expand Down
31 changes: 10 additions & 21 deletions core/src/main/scala/za/co/absa/fadb/DBSchema.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,39 +25,28 @@ import za.co.absa.fadb.naming.NamingConvention
* @param namingConvention - the [[za.co.absa.fadb.naming.NamingConvention NamingConvention]]
* prescribing how to convert a class name into a db object name
*/
abstract class DBSchema(schemaNameOverride: Option[String] = None)(implicit val namingConvention: NamingConvention)
{
abstract class DBSchema(schemaNameOverride: Option[String] = None)(implicit val namingConvention: NamingConvention) {

def this(schemaNameOverride: String)(implicit namingConvention: NamingConvention) {
this(Option(schemaNameOverride))(namingConvention)
// Alternative constructors for different availability of input parameters
def this(schemaNameOverride: String)(implicit namingConvention: NamingConvention) = {
this(Option(schemaNameOverride))
}

def this()(implicit namingConvention: NamingConvention) {
this(None)(namingConvention)
}

def this(namingConvention: NamingConvention, schemaNameOverride: String) {
this(Option(schemaNameOverride))(namingConvention)
def this()(implicit namingConvention: NamingConvention) = {
this(None)
}

/**
* To easy pass over to [[DBFunction]] members of the schema
*/
protected implicit val schema: DBSchema = this

/**
* Function to convert a class to the associated DB object name, based on the class' name. For transformation from the
* class name to usual db name the schema's [[za.co.absa.fadb.naming.NamingConvention NamingConvention]] is used.
* @param c - class which name to use to get the DB object name
* @return - the db object name
*
* @param c - class which name to use to get the DB object name
* @return - the db object name
*/
def objectNameFromClassName(c: Class[_]): String = {
namingConvention.fromClassNamePerConvention(c)
}

/**
* Name of the schema. Based on the schema's class name or provided override
*/
val schemaName: String = schemaNameOverride.getOrElse(objectNameFromClassName(getClass))
val schemaName: String = schemaNameOverride.getOrElse(objectNameFromClassName(this.getClass))

}
18 changes: 14 additions & 4 deletions core/src/test/scala/za/co/absa/fadb/DBFunctionSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ class DBFunctionSuite extends AnyFunSuite {
private object FooNameless extends DBSchema("")

test("Function name check"){
case class MyFunction(override val schema: DBSchema) extends DBFunction[Unit, Unit, DBEngine](schema) {
override protected def query(values: Unit): dBEngine.QueryType[Unit] = neverHappens
case class MyFunction(schema: DBSchema) extends DBFunction(schema) {
override protected def query(values: Nothing): dBEngine.QueryType[Nothing] = neverHappens
}

val fnc1 = MyFunction(FooNamed)
Expand All @@ -49,8 +49,8 @@ class DBFunctionSuite extends AnyFunSuite {
}

test("Function name override check"){
case class MyFunction(override val schema: DBSchema) extends DBFunction[Unit, Unit, DBEngine](schema, "bar") {
override protected def query(values: Unit): dBEngine.QueryType[Unit] = neverHappens
case class MyFunction(schema: DBSchema) extends DBFunction("bar", schema) {
override protected def query(values: Nothing): dBEngine.QueryType[Nothing] = neverHappens
}

val fnc1 = MyFunction(FooNamed)
Expand All @@ -60,4 +60,14 @@ class DBFunctionSuite extends AnyFunSuite {
assert(fnc2.functionName == "bar")
}

test("Function name check with no schema"){
case class MyFunction() extends DBFunction(None, None) {
override protected def query(values: Nothing): dBEngine.QueryType[Nothing] = neverHappens
}

val fnc = MyFunction()

assert(fnc.functionName == "my_function")
}

}
4 changes: 2 additions & 2 deletions core/src/test/scala/za/co/absa/fadb/DBSchemaSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class DBSchemaSuite extends AnyFunSuite {
object LowerCaseNamingConvention extends NamingConvention {
def stringPerConvention(original: String): String = original.toLowerCase
}
class Bar extends DBSchema(LowerCaseNamingConvention, null)
class Bar extends DBSchema()(LowerCaseNamingConvention)

val schema = new Bar
assert(schema.schemaName == "bar") // Assuming the naming convention converts "Bar" to "bar"
Expand All @@ -49,7 +49,7 @@ class DBSchemaSuite extends AnyFunSuite {
object LowerCaseNamingConvention extends NamingConvention {
def stringPerConvention(original: String): String = original.toLowerCase
}
class Bar extends DBSchema(LowerCaseNamingConvention, "bar")
class Bar extends DBSchema("bar")(LowerCaseNamingConvention)

val schema = new Bar
assert(schema.schemaName == "bar")
Expand Down
Loading

0 comments on commit 0932546

Please sign in to comment.