You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
At the moment it's difficult to create test assertions of the db results given the fact that one needs to extract fields from the QueryResultRow object. I propose to enhance capabilities of the library to allow for automatic instance creation for product types.
Feature
Balta will be able to create instances of product types from QueryResultRow
Example
classGetActorByIdTestextendsDBTestSuite {
test("Get actor by id - actor with given id exists EXISTING") {
valexpectedActor=Actor(actorId =1, firstName ="Malin", lastName ="Akerman")
function("runs.get_actor_by_id")
.setParam("i_actor_id", 1)
.execute { queryResult =>
assert(queryResult.hasNext)
valrow= queryResult.next()
assert(row.getInt("actor_id").get == expectedActor.actorId)
assert(row.getString("first_name").get == expectedActor.firstName)
assert(row.getString("last_name").get == expectedActor.lastName)
assert(!queryResult.hasNext)
}
}
importza.co.absa.balta.classes.DefaultColumnNameMappers.SnakeCaseForCamelCaseMapper
test("Get actor by id - actor with given id exists PROPOSAL") {
valexpectedActor=Actor(actorId =1, firstName ="Malin", lastName ="Akerman")
function("runs.get_actor_by_id")
.setParam("i_actor_id", 1)
.execute { queryResult =>
assert(queryResult.hasNext)
valrow= queryResult.next()
valactualActor= row.toProductType[Actor]
assert(expectedActor == actualActor)
assert(!queryResult.hasNext)
}
}
}
Proposed Solution for Discussion
An example of possible solution (needs to be tested for various scenarios, only tested on the test example above)
packageza.co.absa.balta.classesimportorg.postgresql.util.PGobjectimportjava.sql.{Date, ResultSet, Time}
importjava.time.{Instant, OffsetDateTime}
importjava.util.UUIDimportscala.reflect.runtime.universe._importscala.reflect.runtime.currentMirrorclassQueryResultRowprivate[classes](valresultSet:ResultSet) extendsAnyVal {
// existing code not includeddeftoProductType[T<:Product:TypeTag](implicitmapper: ColumnNameMapper):T= {
valtpe= typeOf[T]
valclassSymbol= tpe.typeSymbol.asClass
valclassMirror= currentMirror.reflectClass(classSymbol)
valconstructorSymbol= tpe.decl(termNames.CONSTRUCTOR)
valdefaultConstructor=if (constructorSymbol.isMethod) constructorSymbol.asMethod
else {
valctors= constructorSymbol.asTerm.alternatives
ctors.map(_.asMethod).find(_.isPrimaryConstructor).get
}
valconstructorMirror= classMirror.reflectConstructor(defaultConstructor)
valparams= defaultConstructor.paramLists.flatten.map { param =>valname= param.name.decodedName.toString
valcolumnName= mapper.map(name)
valvalue= resultSet.getObject(columnName)
if (resultSet.wasNull()) nullelse value
}
constructorMirror(params: _*).asInstanceOf[T]
}
}
traitColumnNameMapper {
defmap(name: String):String
}
objectDefaultColumnNameMappers {
// when database columns use the same names as product typeimplicitobjectIdentityMapperextendsColumnNameMapper {
defmap(name: String):String= name
}
// when database columns use upper case and product type uses lower caseimplicitobjectUpperCaseForLowerCaseMapperextendsColumnNameMapper {
defmap(name: String):String= name.toUpperCase
}
// when database columns use lower case and product type uses upper caseimplicitobjectLowerCaseForUpperCaseMapperextendsColumnNameMapper {
defmap(name: String):String= name.toLowerCase
}
// when database columns use snake_case and product type uses camelCaseimplicitobjectSnakeCaseForCamelCaseMapperextendsColumnNameMapper {
defmap(name: String):String= {
valregex="([a-z])([A-Z]+)".r
valreplacement="$1_$2"
regex.replaceAllIn(name, replacement).toLowerCase
}
}
// when database columns use kebab-case and product type uses camelCaseimplicitobjectKebabCaseForCamelCaseMapperextendsColumnNameMapper {
defmap(name: String):String= {
valregex="([a-z])([A-Z]+)".r
valreplacement="$1-$2"
regex.replaceAllIn(name, replacement).toLowerCase
}
}
}
The text was updated successfully, but these errors were encountered:
* implicit class that adds the ability to convert `QueryResultRow` to a product type
* implicit classes that add `getOrThrow` methods to `Option` and `Map`
* copied `NamingConvention` classes from Fa-DB
* added `sbt testAll` alias
* enhanced the README.md to include some basic classes of the library used for DB testing
* implicit class that adds the ability to convert `QueryResultRow` to a product type
* implicit classes that add `getOrThrow` methods to `Option` and `Map`
* copied `NamingConvention` classes from Fa-DB
* added `sbt testAll` alias
* enhanced the README.md to include some basic classes of the library used for DB testing
---------
Co-authored-by: miroslavpojer <miroslav.pojer@absa.africa>
Co-authored-by: Ladislav Sulak <laco.sulak@gmail.com>
Background
At the moment it's difficult to create test assertions of the db results given the fact that one needs to extract fields from the QueryResultRow object. I propose to enhance capabilities of the library to allow for automatic instance creation for product types.
Feature
Balta will be able to create instances of product types from QueryResultRow
Example
Proposed Solution for Discussion
An example of possible solution (needs to be tested for various scenarios, only tested on the test example above)
The text was updated successfully, but these errors were encountered: