diff --git a/core/src/main/scala/za/co/absa/db/fadb/DBFunction.scala b/core/src/main/scala/za/co/absa/db/fadb/DBFunction.scala index 68c253f2..c1c7a96e 100644 --- a/core/src/main/scala/za/co/absa/db/fadb/DBFunction.scala +++ b/core/src/main/scala/za/co/absa/db/fadb/DBFunction.scala @@ -18,9 +18,10 @@ package za.co.absa.db.fadb import cats.MonadError import cats.implicits.toFlatMapOps +import za.co.absa.db.fadb.exceptions.StatusException import za.co.absa.db.fadb.status.aggregation.StatusAggregator import za.co.absa.db.fadb.status.handling.StatusHandling -import za.co.absa.db.fadb.status.{FailedOrRows, FailedOrRow, Row} +import za.co.absa.db.fadb.status.{FailedOrRow, FailedOrRows, FunctionStatus, Row} import scala.language.higherKinds @@ -111,7 +112,7 @@ abstract class DBFunctionWithStatus[I, R, E <: DBEngine[F], F[_]](functionNameOv * @return - A sequence of results from the database function. */ protected def multipleResults(values: I)(implicit me: MonadError[F, Throwable]): F[Seq[FailedOrRow[R]]] = - query(values).flatMap(q => dBEngine.fetchAllWithStatus(q)) + query(values).flatMap((q: dBEngine.QueryWithStatusType[R]) => dBEngine.fetchAllWithStatus(q)) /** * Executes the database function and returns a single result. @@ -148,7 +149,7 @@ abstract class DBFunctionWithStatus[I, R, E <: DBEngine[F], F[_]](functionNameOv protected def query(values: I)(implicit me: MonadError[F, Throwable]): F[dBEngine.QueryWithStatusType[R]] // To be provided by an implementation of QueryStatusHandling - override def checkStatus[D](statusWithData: Row[D]): FailedOrRow[D] + override def checkStatus(functionStatus: FunctionStatus): Option[StatusException] } object DBFunction { diff --git a/core/src/main/scala/za/co/absa/db/fadb/Query.scala b/core/src/main/scala/za/co/absa/db/fadb/Query.scala index ecb2ab09..84848682 100644 --- a/core/src/main/scala/za/co/absa/db/fadb/Query.scala +++ b/core/src/main/scala/za/co/absa/db/fadb/Query.scala @@ -16,7 +16,8 @@ package za.co.absa.db.fadb -import za.co.absa.db.fadb.status.{FailedOrRow, Row} +import za.co.absa.db.fadb.exceptions.StatusException +import za.co.absa.db.fadb.status.{BlbyJmenoWithLayers, FailedOrRow, FunctionStatus, Row, StatusWithDataOptional} /** * The basis for all query types of [[DBEngine]] implementations @@ -30,21 +31,21 @@ trait Query[R] * @tparam D - the intermediate result type of the query (a row without status columns, i.e. data only) * @tparam R - the final return type of the query (final version of result, depending on the needs, might be the same as D) */ -trait QueryWithStatus[DS, D, R] { +abstract class QueryWithStatus[DS <: BlbyJmenoWithLayers[R], D, R](val processStatus: FunctionStatus => Option[StatusException]) extends Query[R] { /** * Processes the status of the query and returns the status with data * @param initialResult - the initial result of the query * @return data with status */ - def processStatus(initialResult: DS): Row[D] +// def processStatus(initialResult: FunctionStatus): Option[StatusException] /** * Converts the status with data to either a status exception or the data * @param statusWithData - the status with data * @return either a status exception or the data */ - def toStatusExceptionOrData(statusWithData: Row[D]): FailedOrRow[R] +// def toStatusExceptionOrData(statusWithData: StatusWithDataOptional[D]): FailedOrRow[R] /** * Returns the result of the query or a status exception @@ -52,5 +53,5 @@ trait QueryWithStatus[DS, D, R] { * @return the result of the query or a status exception */ def getResultOrException(initialResult: DS): FailedOrRow[R] = - toStatusExceptionOrData(processStatus(initialResult)) + initialResult.toFailedOrRow(processStatus) } diff --git a/core/src/main/scala/za/co/absa/db/fadb/status/handling/StatusHandling.scala b/core/src/main/scala/za/co/absa/db/fadb/status/handling/StatusHandling.scala index bb85da90..c8d7efbd 100644 --- a/core/src/main/scala/za/co/absa/db/fadb/status/handling/StatusHandling.scala +++ b/core/src/main/scala/za/co/absa/db/fadb/status/handling/StatusHandling.scala @@ -16,7 +16,8 @@ package za.co.absa.db.fadb.status.handling -import za.co.absa.db.fadb.status.{FailedOrRow, Row} +import za.co.absa.db.fadb.exceptions.StatusException +import za.co.absa.db.fadb.status.{FailedOrRow, FunctionStatus, Row} /** * `StatusHandling` is a base trait that defines the interface for handling the status of a function invocation. @@ -30,5 +31,5 @@ trait StatusHandling { * @return Either a `StatusException` if the status code indicates an error, or the data (along with the status * information so that it's retrievable) if the status code is successful. */ - def checkStatus[D](statusWithData: Row[D]): FailedOrRow[D] + def checkStatus(functionStatus: FunctionStatus): Option[StatusException] } diff --git a/core/src/main/scala/za/co/absa/db/fadb/status/handling/implementations/StandardStatusHandling.scala b/core/src/main/scala/za/co/absa/db/fadb/status/handling/implementations/StandardStatusHandling.scala index 68c0dfcd..db856dc4 100644 --- a/core/src/main/scala/za/co/absa/db/fadb/status/handling/implementations/StandardStatusHandling.scala +++ b/core/src/main/scala/za/co/absa/db/fadb/status/handling/implementations/StandardStatusHandling.scala @@ -17,7 +17,7 @@ package za.co.absa.db.fadb.status.handling.implementations import za.co.absa.db.fadb.exceptions._ -import za.co.absa.db.fadb.status.{FailedOrRow, Row} +import za.co.absa.db.fadb.status.{FailedOrRow, FunctionStatus, Row} import za.co.absa.db.fadb.status.handling.StatusHandling /** @@ -29,16 +29,15 @@ trait StandardStatusHandling extends StatusHandling { /** * Checks the status of a function invocation. */ - override def checkStatus[D](statusWithData: Row[D]): FailedOrRow[D] = { - val functionStatus = statusWithData.functionStatus + override def checkStatus(functionStatus: FunctionStatus): Option[StatusException] = { functionStatus.statusCode / 10 match { - case 1 => Right(statusWithData) - case 2 => Left(ServerMisconfigurationException(functionStatus)) - case 3 => Left(DataConflictException(functionStatus)) - case 4 => Left(DataNotFoundException(functionStatus)) - case 5 | 6 | 7 | 8 => Left(ErrorInDataException(functionStatus)) - case 9 => Left(OtherStatusException(functionStatus)) - case _ => Left(StatusOutOfRangeException(functionStatus)) + case 1 => None + case 2 => Some(ServerMisconfigurationException(functionStatus)) + case 3 => Some(DataConflictException(functionStatus)) + case 4 => Some(DataNotFoundException(functionStatus)) + case 5 | 6 | 7 | 8 => Some(ErrorInDataException(functionStatus)) + case 9 => Some(OtherStatusException(functionStatus)) + case _ => Some(StatusOutOfRangeException(functionStatus)) } } } diff --git a/core/src/main/scala/za/co/absa/db/fadb/status/handling/implementations/UserDefinedStatusHandling.scala b/core/src/main/scala/za/co/absa/db/fadb/status/handling/implementations/UserDefinedStatusHandling.scala index c1e81953..be5a523e 100644 --- a/core/src/main/scala/za/co/absa/db/fadb/status/handling/implementations/UserDefinedStatusHandling.scala +++ b/core/src/main/scala/za/co/absa/db/fadb/status/handling/implementations/UserDefinedStatusHandling.scala @@ -16,9 +16,9 @@ package za.co.absa.db.fadb.status.handling.implementations -import za.co.absa.db.fadb.exceptions.OtherStatusException +import za.co.absa.db.fadb.exceptions.{OtherStatusException, StatusException} import za.co.absa.db.fadb.status.handling.StatusHandling -import za.co.absa.db.fadb.status.{FailedOrRow, Row} +import za.co.absa.db.fadb.status.{FailedOrRow, FunctionStatus, Row} /** * Trait represents user defined status handling @@ -26,10 +26,10 @@ import za.co.absa.db.fadb.status.{FailedOrRow, Row} trait UserDefinedStatusHandling extends StatusHandling { def OKStatuses: Set[Integer] - override def checkStatus[D](statusWithData: Row[D]): FailedOrRow[D] = - if (OKStatuses.contains(statusWithData.functionStatus.statusCode)) { - Right(statusWithData) + override def checkStatus(functionStatus: FunctionStatus): Option[StatusException] = + if (OKStatuses.contains(functionStatus.statusCode)) { + None } else { - Left(OtherStatusException(statusWithData.functionStatus)) + Some(OtherStatusException(functionStatus)) } } diff --git a/core/src/main/scala/za/co/absa/db/fadb/status/package.scala b/core/src/main/scala/za/co/absa/db/fadb/status/package.scala index eae596b0..c5461d37 100644 --- a/core/src/main/scala/za/co/absa/db/fadb/status/package.scala +++ b/core/src/main/scala/za/co/absa/db/fadb/status/package.scala @@ -17,6 +17,7 @@ package za.co.absa.db.fadb import za.co.absa.db.fadb.exceptions.StatusException +import za.co.absa.db.fadb.status.FailedOrRow package object status { @@ -31,8 +32,26 @@ package object status { * @param data the data of one row (barring the status fields) * @tparam D the type of the data */ + + trait BlbyJmenoWithLayers[R] { + def toFailedOrRow(statusCheck: FunctionStatus => Option[StatusException]): FailedOrRow[R] + } + case class Row[D](functionStatus: FunctionStatus, data: D) + case class StatusWithDataOptional[R](status: Int, statusText: String, data: Option[R]) + extends BlbyJmenoWithLayers[R]{ + + def toFailedOrRow(statusCheck: FunctionStatus => Option[StatusException]): FailedOrRow[R] = { + val functionStatus = FunctionStatus(status, statusText) + val left = statusCheck(functionStatus) + left match { + case Some(e) => Left(e) + case None => Right(Row(functionStatus, data.get)) + } + } + } + /** * This is a representation of a single row returned from a DB function with processed status information. * diff --git a/core/src/test/scala/za/co/absa/db/fadb/status/handling/implementations/StandardStatusHandlingUnitTests.scala b/core/src/test/scala/za/co/absa/db/fadb/status/handling/implementations/StandardStatusHandlingUnitTests.scala index 32a5dda7..aa054503 100644 --- a/core/src/test/scala/za/co/absa/db/fadb/status/handling/implementations/StandardStatusHandlingUnitTests.scala +++ b/core/src/test/scala/za/co/absa/db/fadb/status/handling/implementations/StandardStatusHandlingUnitTests.scala @@ -1,98 +1,98 @@ -/* - * 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.db.fadb.status.handling.implementations - -import org.scalatest.funsuite.AnyFunSuiteLike -import org.scalatest.matchers.should.Matchers.convertToAnyShouldWrapper -import za.co.absa.db.fadb.exceptions._ -import za.co.absa.db.fadb.status.{FunctionStatus, Row} - -class StandardStatusHandlingUnitTests extends AnyFunSuiteLike { - - private val standardQueryStatusHandling = new StandardStatusHandling {} - - test("checkStatus should return Right when status code is in the range 10-19") { - for (statusCode <- 10 to 19) { - val functionStatus = FunctionStatus(statusCode, "Success") - val statusWithData = Row(functionStatus, "Data") - val result = standardQueryStatusHandling.checkStatus(statusWithData) - result shouldBe Right(statusWithData) - } - } - - test("checkStatus should return Left with ServerMisconfigurationException when status code is in the range 20-29") { - for (statusCode <- 20 to 29) { - val functionStatus = FunctionStatus(statusCode, "Server Misconfiguration") - val statusWithData = Row(functionStatus, "Data") - val result = standardQueryStatusHandling.checkStatus(statusWithData) - result shouldBe Left(ServerMisconfigurationException(functionStatus)) - } - } - - test("checkStatus should return Left with DataConflictException when status code is in the range 30-39") { - for (statusCode <- 30 to 39) { - val functionStatus = FunctionStatus(statusCode, "Data Conflict") - val statusWithData = Row(functionStatus, "Data") - val result = standardQueryStatusHandling.checkStatus(statusWithData) - result shouldBe Left(DataConflictException(functionStatus)) - } - } - - test("checkStatus should return Left with DataNotFoundException when status code is in the range 40-49") { - for (statusCode <- 40 to 49) { - val functionStatus = FunctionStatus(statusCode, "Data Not Found") - val statusWithData = Row(functionStatus, "Data") - val result = standardQueryStatusHandling.checkStatus(statusWithData) - result shouldBe Left(DataNotFoundException(functionStatus)) - } - } - - test("checkStatus should return Left with ErrorInDataException when status code is in the range 50-89") { - for (statusCode <- 50 to 89) { - val functionStatus = FunctionStatus(statusCode, "Error in Data") - val statusWithData = Row(functionStatus, "Data") - val result = standardQueryStatusHandling.checkStatus(statusWithData) - result shouldBe Left(ErrorInDataException(functionStatus)) - } - } - - test("checkStatus should return Left with OtherStatusException when status code is in the range 90-99") { - for (statusCode <- 90 to 99) { - val functionStatus = FunctionStatus(statusCode, "Other Status") - val statusWithData = Row(functionStatus, "Data") - val result = standardQueryStatusHandling.checkStatus(statusWithData) - result shouldBe Left(OtherStatusException(functionStatus)) - } - } - - test("checkStatus should return Left with StatusOutOfRangeException when status code is not in any known range") { - for (statusCode <- 0 to 9) { - val functionStatus = FunctionStatus(statusCode, "Out of range") - val statusWithData = Row(functionStatus, "Data") - val result = standardQueryStatusHandling.checkStatus(statusWithData) - result shouldBe Left(StatusOutOfRangeException(functionStatus)) - } - - for (statusCode <- 100 to 110) { - val functionStatus = FunctionStatus(statusCode, "Out of range") - val statusWithData = Row(functionStatus, "Data") - val result = standardQueryStatusHandling.checkStatus(statusWithData) - result shouldBe Left(StatusOutOfRangeException(functionStatus)) - } - } - -} +///* +// * 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.db.fadb.status.handling.implementations +// +//import org.scalatest.funsuite.AnyFunSuiteLike +//import org.scalatest.matchers.should.Matchers.convertToAnyShouldWrapper +//import za.co.absa.db.fadb.exceptions._ +//import za.co.absa.db.fadb.status.{FunctionStatus, Row} +// +//class StandardStatusHandlingUnitTests extends AnyFunSuiteLike { +// +// private val standardQueryStatusHandling = new StandardStatusHandling {} +// +// test("checkStatus should return Right when status code is in the range 10-19") { +// for (statusCode <- 10 to 19) { +// val functionStatus = FunctionStatus(statusCode, "Success") +// val statusWithData = Row(functionStatus, "Data") +// val result = standardQueryStatusHandling.checkStatus(statusWithData) +// result shouldBe Right(statusWithData) +// } +// } +// +// test("checkStatus should return Left with ServerMisconfigurationException when status code is in the range 20-29") { +// for (statusCode <- 20 to 29) { +// val functionStatus = FunctionStatus(statusCode, "Server Misconfiguration") +// val statusWithData = Row(functionStatus, "Data") +// val result = standardQueryStatusHandling.checkStatus(statusWithData) +// result shouldBe Left(ServerMisconfigurationException(functionStatus)) +// } +// } +// +// test("checkStatus should return Left with DataConflictException when status code is in the range 30-39") { +// for (statusCode <- 30 to 39) { +// val functionStatus = FunctionStatus(statusCode, "Data Conflict") +// val statusWithData = Row(functionStatus, "Data") +// val result = standardQueryStatusHandling.checkStatus(statusWithData) +// result shouldBe Left(DataConflictException(functionStatus)) +// } +// } +// +// test("checkStatus should return Left with DataNotFoundException when status code is in the range 40-49") { +// for (statusCode <- 40 to 49) { +// val functionStatus = FunctionStatus(statusCode, "Data Not Found") +// val statusWithData = Row(functionStatus, "Data") +// val result = standardQueryStatusHandling.checkStatus(statusWithData) +// result shouldBe Left(DataNotFoundException(functionStatus)) +// } +// } +// +// test("checkStatus should return Left with ErrorInDataException when status code is in the range 50-89") { +// for (statusCode <- 50 to 89) { +// val functionStatus = FunctionStatus(statusCode, "Error in Data") +// val statusWithData = Row(functionStatus, "Data") +// val result = standardQueryStatusHandling.checkStatus(statusWithData) +// result shouldBe Left(ErrorInDataException(functionStatus)) +// } +// } +// +// test("checkStatus should return Left with OtherStatusException when status code is in the range 90-99") { +// for (statusCode <- 90 to 99) { +// val functionStatus = FunctionStatus(statusCode, "Other Status") +// val statusWithData = Row(functionStatus, "Data") +// val result = standardQueryStatusHandling.checkStatus(statusWithData) +// result shouldBe Left(OtherStatusException(functionStatus)) +// } +// } +// +// test("checkStatus should return Left with StatusOutOfRangeException when status code is not in any known range") { +// for (statusCode <- 0 to 9) { +// val functionStatus = FunctionStatus(statusCode, "Out of range") +// val statusWithData = Row(functionStatus, "Data") +// val result = standardQueryStatusHandling.checkStatus(statusWithData) +// result shouldBe Left(StatusOutOfRangeException(functionStatus)) +// } +// +// for (statusCode <- 100 to 110) { +// val functionStatus = FunctionStatus(statusCode, "Out of range") +// val statusWithData = Row(functionStatus, "Data") +// val result = standardQueryStatusHandling.checkStatus(statusWithData) +// result shouldBe Left(StatusOutOfRangeException(functionStatus)) +// } +// } +// +//} diff --git a/doobie/src/main/scala/za/co/absa/db/fadb/doobie/DoobieEngine.scala b/doobie/src/main/scala/za/co/absa/db/fadb/doobie/DoobieEngine.scala index 1a14bfb5..39400ffd 100644 --- a/doobie/src/main/scala/za/co/absa/db/fadb/doobie/DoobieEngine.scala +++ b/doobie/src/main/scala/za/co/absa/db/fadb/doobie/DoobieEngine.scala @@ -49,13 +49,16 @@ class DoobieEngine[F[_]: Async](val transactor: Transactor[F]) extends DBEngine[ * @return the query result as an `F[Seq[R]]` */ private def executeQuery[R](query: QueryType[R])(implicit readR: Read[R]): F[Seq[R]] = { - query.fragment.query[R].to[Seq].transact(transactor) + val o: Query0[R] = query.fragment.query[R] + val o1: ConnectionIO[Seq[R]] = o.to[Seq] + val o2: F[Seq[R]] = o1.transact(transactor) + o2 } /** * Executes a Doobie query and returns the result. * - * Note: `StatusWithData` is needed here because it is more 'flat' in comparison to `FunctionStatusWithData` + * Note: `StatusWithData` is needed here because it is more 'flat' in comparison to `FunctionStatusWithData` * and Doobie's `Read` wasn't able to work with it. * * @param query the Doobie query to execute @@ -64,8 +67,8 @@ class DoobieEngine[F[_]: Async](val transactor: Transactor[F]) extends DBEngine[ */ private def executeQueryWithStatus[R]( query: QueryWithStatusType[R] - )(implicit readStatusWithDataR: Read[StatusWithData[R]]): F[Seq[FailedOrRow[R]]] = { - query.fragment.query[StatusWithData[R]].to[Seq].transact(transactor).map(_.map(query.getResultOrException)) + )(implicit readStatusWithDataR: Read[StatusWithDataOptional[R]]): F[Seq[FailedOrRow[R]]] = { + query.fragment.query[StatusWithDataOptional[R]].to[Seq].transact(transactor).map(_.map(query.getResultOrException)) } /** diff --git a/doobie/src/main/scala/za/co/absa/db/fadb/doobie/DoobieFunction.scala b/doobie/src/main/scala/za/co/absa/db/fadb/doobie/DoobieFunction.scala index ca7fd5a9..e7232a2b 100644 --- a/doobie/src/main/scala/za/co/absa/db/fadb/doobie/DoobieFunction.scala +++ b/doobie/src/main/scala/za/co/absa/db/fadb/doobie/DoobieFunction.scala @@ -22,6 +22,7 @@ import doobie.util.Read import doobie.util.fragment.Fragment import za.co.absa.db.fadb.DBFunction._ import za.co.absa.db.fadb.DBSchema +import za.co.absa.db.fadb.status.handling.StatusHandling import za.co.absa.db.fadb.status.{FailedOrRow, Row} import scala.language.higherKinds @@ -120,16 +121,27 @@ trait DoobieFunction[I, R, F[_]] extends DoobieFunctionBase[R] { } -trait DoobieFunctionWithStatus[I, R, F[_]] extends DoobieFunctionBase[R] { +trait DoobieFunctionWithStatus[I, R, F[_]] extends DoobieFunctionBase[R] with StatusHandling { /** * The `Read[StatusWithData[R]]` instance used to read the query result with status into `StatusWithData[R]`. */ - implicit def readStatusWithDataR(implicit readR: Read[R]): Read[StatusWithData[R]] = Read[(Int, String, R)].map { - case (status, status_text, data) => StatusWithData(status, status_text, data) - } +// implicit def readStatusWithDataR(implicit readR: Read[R]): Read[StatusWithData[R]] = Read[(Int, String, R)].map { +// case (status, status_text, data) => StatusWithData(status, status_text, data) +// } - /** +// implicit def readStatusWithDataR(implicit readR: Read[R]): Read[StatusWithDataOptional[R]] = Read[(Int, String, Option[R])].map { +// case (status: Int, status_text: String, data: Option[R]) => StatusWithDataOptional(status, status_text, data) +// } + +// def getOption[T](f: Fragment)(implicit read: Read[T]): Option[T] = { +// f.query[T] +// .option +// .transact(xa) +// .unsafeRunSync() + + + /** * Function that generates a sequence of `Fragment`s representing the SQL query from input values for the function. * @return the sequence of `Fragment`s representing the SQL query */ @@ -196,7 +208,8 @@ trait DoobieFunctionWithStatus[I, R, F[_]] extends DoobieFunctionBase[R] { } // This is to be mixed in by an implementation of StatusHandling - def checkStatus[D](statusWithData: Row[D]): FailedOrRow[D] +// def checkStatus[D](statusWithData: Row[D]): FailedOrRow[D] +// def checkStatus[D](statusWithData: Row[D]): FailedOrRow[D] } /** diff --git a/doobie/src/main/scala/za/co/absa/db/fadb/doobie/DoobieQuery.scala b/doobie/src/main/scala/za/co/absa/db/fadb/doobie/DoobieQuery.scala index 66d50eb2..a27de30a 100644 --- a/doobie/src/main/scala/za/co/absa/db/fadb/doobie/DoobieQuery.scala +++ b/doobie/src/main/scala/za/co/absa/db/fadb/doobie/DoobieQuery.scala @@ -18,6 +18,7 @@ package za.co.absa.db.fadb.doobie import doobie.util.Read import doobie.util.fragment.Fragment +import za.co.absa.db.fadb.exceptions.StatusException import za.co.absa.db.fadb.status.{FailedOrRow, FunctionStatus, Row} import za.co.absa.db.fadb.{Query, QueryWithStatus} @@ -40,23 +41,25 @@ class DoobieQuery[R](val fragment: Fragment)(implicit val readR: Read[R]) extend */ class DoobieQueryWithStatus[R]( val fragment: Fragment, - checkStatus: Row[R] => FailedOrRow[R] -)(implicit val readStatusWithDataR: Read[StatusWithData[R]]) - extends QueryWithStatus[StatusWithData[R], R, R] { + checkStatus: FunctionStatus => Option[StatusException], +)(implicit val readStatusWithDataR: Read[StatusWithDataOptional[R]]) + extends QueryWithStatus[StatusWithDataOptional[R], R, R](checkStatus) { /* * Processes the status of the query and returns the status with data * @param initialResult - the initial result of the query * @return data with status */ - override def processStatus(initialResult: StatusWithData[R]): Row[R] = + override def processStatus(initialResult: FunctionStatus): Option[StatusException] = { Row(FunctionStatus(initialResult.status, initialResult.statusText), initialResult.data) + } + /* * Converts the status with data to either a status exception or the data * @param statusWithData - the status with data * @return either a status exception or the data */ - override def toStatusExceptionOrData(statusWithData: Row[R]): FailedOrRow[R] = - checkStatus(statusWithData) +// override def toStatusExceptionOrData(statusWithData: Row[R]): FailedOrRow[R] = +// checkStatus(statusWithData) } diff --git a/doobie/src/main/scala/za/co/absa/db/fadb/doobie/StatusWithData.scala b/doobie/src/main/scala/za/co/absa/db/fadb/doobie/StatusWithData.scala index 5da6b4fa..bc98e9f2 100644 --- a/doobie/src/main/scala/za/co/absa/db/fadb/doobie/StatusWithData.scala +++ b/doobie/src/main/scala/za/co/absa/db/fadb/doobie/StatusWithData.scala @@ -25,3 +25,4 @@ package za.co.absa.db.fadb.doobie * by a user. */ case class StatusWithData[R](status: Int, statusText: String, data: R) +case class StatusWithDataOptional[R](status: Int, statusText: String, data: Option[R]) diff --git a/slick/src/main/scala/za/co/absa/db/fadb/slick/SlickFunction.scala b/slick/src/main/scala/za/co/absa/db/fadb/slick/SlickFunction.scala index 5093c2fc..0bd61cf0 100644 --- a/slick/src/main/scala/za/co/absa/db/fadb/slick/SlickFunction.scala +++ b/slick/src/main/scala/za/co/absa/db/fadb/slick/SlickFunction.scala @@ -20,6 +20,7 @@ import cats.MonadError import slick.jdbc.{GetResult, SQLActionBuilder} import za.co.absa.db.fadb.DBFunction._ import za.co.absa.db.fadb.DBSchema +import za.co.absa.db.fadb.status.handling.StatusHandling import za.co.absa.db.fadb.status.{FailedOrRow, Row} import scala.concurrent.Future @@ -74,7 +75,7 @@ private[slick] trait SlickFunction[I, R] extends SlickFunctionBase[I, R] { } } -private[slick] trait SlickFunctionWithStatus[I, R] extends SlickFunctionBase[I, R] { +private[slick] trait SlickFunctionWithStatus[I, R] extends SlickFunctionBase[I, R] with StatusHandling { /** * Generates a `SlickQueryWithStatus[R]` representing the SQL query for the function with status support. diff --git a/slick/src/main/scala/za/co/absa/db/fadb/slick/SlickQuery.scala b/slick/src/main/scala/za/co/absa/db/fadb/slick/SlickQuery.scala index 2bffc5f4..f346b903 100644 --- a/slick/src/main/scala/za/co/absa/db/fadb/slick/SlickQuery.scala +++ b/slick/src/main/scala/za/co/absa/db/fadb/slick/SlickQuery.scala @@ -17,6 +17,7 @@ package za.co.absa.db.fadb.slick import slick.jdbc.{GetResult, PositionedResult, SQLActionBuilder} +import za.co.absa.db.fadb.exceptions.StatusException import za.co.absa.db.fadb.status.{FailedOrRow, FunctionStatus, Row} import za.co.absa.db.fadb.{Query, QueryWithStatus} @@ -39,26 +40,30 @@ class SlickQuery[R](val sql: SQLActionBuilder, val getResult: GetResult[R]) exte class SlickQueryWithStatus[R]( val sql: SQLActionBuilder, val getResult: GetResult[R], - checkStatus: Row[PositionedResult] => FailedOrRow[PositionedResult] -) extends QueryWithStatus[PositionedResult, PositionedResult, R] { + checkStatus: FunctionStatus => Option[StatusException] +) extends QueryWithStatus[PositionedResult, PositionedResult, R](checkStatus) { /** * Processes the status of the query and returns the status with data * @param initialResult - the initial result of the query * @return data with status */ - override def processStatus(initialResult: PositionedResult): Row[PositionedResult] = { + override def processStatus(initialResult: PositionedResult): Option[StatusException]= { val status: Int = initialResult.<< val statusText: String = initialResult.<< Row(FunctionStatus(status, statusText), initialResult) } +// override def processStatus(initialResult: FunctionStatus): Option[StatusException] = +// Row(FunctionStatus(initialResult.status, initialResult.statusText), initialResult.data) + + /** * Converts the status with data to either a status exception or the data * @param statusWithData - the status with data * @return either a status exception or the data */ - override def toStatusExceptionOrData( +/* override def toStatusExceptionOrData( statusWithData: Row[PositionedResult] ): FailedOrRow[R] = { checkStatus(statusWithData) match { @@ -68,7 +73,7 @@ class SlickQueryWithStatus[R]( val data = getResult(value.data) Right(Row(status, data)) } - } + }*/ /** * Combines the processing of the status and the conversion of the status with data to either a status exception or the data