From 794f489cabc32bac71b68626f4cb9a067b19f364 Mon Sep 17 00:00:00 2001 From: Anthony Berg Date: Thu, 2 May 2024 15:16:54 +0100 Subject: [PATCH] feat(connector): add database transaction for testing --- .../connector/shared/TestTransaction.kt | 89 +++++++++++++++++++ .../shared/database/ActionResultDatabase.kt | 38 ++++++++ .../connector/shared/database/TestDatabase.kt | 30 +++++++ .../connector/shared/entity/ActionResult.kt | 31 +++++++ .../connector/shared/entity/Test.kt | 25 ++++++ .../connector/shared/database/ActionResult.sq | 3 + .../connector/shared/database/Test.sq | 3 + 7 files changed, 219 insertions(+) create mode 100644 connector/shared/src/commonMain/kotlin/io/anthonyberg/connector/shared/TestTransaction.kt create mode 100644 connector/shared/src/commonMain/kotlin/io/anthonyberg/connector/shared/database/ActionResultDatabase.kt create mode 100644 connector/shared/src/commonMain/kotlin/io/anthonyberg/connector/shared/database/TestDatabase.kt create mode 100644 connector/shared/src/commonMain/kotlin/io/anthonyberg/connector/shared/entity/ActionResult.kt create mode 100644 connector/shared/src/commonMain/kotlin/io/anthonyberg/connector/shared/entity/Test.kt diff --git a/connector/shared/src/commonMain/kotlin/io/anthonyberg/connector/shared/TestTransaction.kt b/connector/shared/src/commonMain/kotlin/io/anthonyberg/connector/shared/TestTransaction.kt new file mode 100644 index 0000000..e9e6078 --- /dev/null +++ b/connector/shared/src/commonMain/kotlin/io/anthonyberg/connector/shared/TestTransaction.kt @@ -0,0 +1,89 @@ +package io.anthonyberg.connector.shared + +import io.anthonyberg.connector.shared.database.ActionResultDatabase +import io.anthonyberg.connector.shared.database.DriverFactory +import io.anthonyberg.connector.shared.database.TestDatabase +import kotlinx.datetime.Clock +import kotlinx.datetime.Instant + +/** + * Database transactions for testing procedures + */ +class TestTransaction (driverFactory: DriverFactory) { + private val testDb = TestDatabase(driverFactory) + private val actionResultDb = ActionResultDatabase(driverFactory) + + /** + * Starts the test on the database + * + * @param procedureId ID of the Procedure that is being tested + * + * @return ID of the Test that was started + */ + fun startTest(procedureId: Int): Int { + val currentTime = Clock.System.now().toString() + + val id = testDb.startTest( + procedureId = procedureId.toLong(), + startUTC = currentTime, + ) + + return id.toInt() + } + + /** + * Tells the database that the test has ended + * + * @param id ID of the Test + * + * @return The final time for when the test ended + */ + fun endTest(id: Int): Instant { + val currentTime = Clock.System.now() + + testDb.endTest(testId = id.toLong(), endUTC = currentTime.toString()) + + return currentTime + } + + /** + * Starts the test for a specific action on the database + * + * @param testId ID of the current test that is running + * @param actionId ID of the current action that is being tested + * @param initState The initial state of the action in the simulator + * + * @return ID of the Action created on the database + */ + fun startAction(testId: Int, actionId: Int, initState: String): Int { + val currentTime = Clock.System.now().toString() + + val id = actionResultDb.startResult( + testId = testId.toLong(), + actionId = actionId.toLong(), + initState = initState, + startUTC = currentTime, + ) + + return id.toInt() + } + + /** + * Tells the database that the test has ended and adds the final state + * + * @param id ID of the ActionResult + * + * @return The time for when the test for the specific action finished + */ + fun finishAction(id: Int, endState: String): Instant { + val currentTime = Clock.System.now() + + actionResultDb.finishResult( + id = id.toLong(), + endState = endState, + endUTC = currentTime.toString() + ) + + return currentTime + } +} diff --git a/connector/shared/src/commonMain/kotlin/io/anthonyberg/connector/shared/database/ActionResultDatabase.kt b/connector/shared/src/commonMain/kotlin/io/anthonyberg/connector/shared/database/ActionResultDatabase.kt new file mode 100644 index 0000000..d4386e2 --- /dev/null +++ b/connector/shared/src/commonMain/kotlin/io/anthonyberg/connector/shared/database/ActionResultDatabase.kt @@ -0,0 +1,38 @@ +package io.anthonyberg.connector.shared.database + +internal class ActionResultDatabase (driverFactory: DriverFactory) { + private val database = Database(driverFactory.createDriver()) + private val dbQuery = database.actionResultQueries + + /** + * Adds the start of a test for an action to the database + * + * @return ID of the ActionResult created + */ + internal fun startResult( + testId: Long, + actionId: Long, + initState: String, + startUTC: String + ): Long { + dbQuery.startResult( + testId = testId, + actionId = actionId, + initState = initState, + startUTC = startUTC + ) + + return dbQuery.lastInsertedRowId().executeAsOne() + } + + /** + * Updates the final results of the test for the action in the database + */ + internal fun finishResult(id: Long, endState: String, endUTC: String) { + dbQuery.finishResult( + id = id, + endState = endState, + endUTC = endUTC, + ) + } +} diff --git a/connector/shared/src/commonMain/kotlin/io/anthonyberg/connector/shared/database/TestDatabase.kt b/connector/shared/src/commonMain/kotlin/io/anthonyberg/connector/shared/database/TestDatabase.kt new file mode 100644 index 0000000..a23e4a2 --- /dev/null +++ b/connector/shared/src/commonMain/kotlin/io/anthonyberg/connector/shared/database/TestDatabase.kt @@ -0,0 +1,30 @@ +package io.anthonyberg.connector.shared.database + +internal class TestDatabase (driverFactory: DriverFactory) { + private val database = Database(driverFactory.createDriver()) + private val dbQuery = database.testQueries + + /** + * Creates a Test record on the database + * + * @return ID of the Test created + */ + internal fun startTest(procedureId: Long, startUTC: String) : Long { + dbQuery.startTest( + procedureId = procedureId, + startUTC = startUTC, + ) + + return dbQuery.lastInsertedRowId().executeAsOne() + } + + /** + * Updates Test record to include the end time + */ + internal fun endTest(testId: Long, endUTC: String) { + dbQuery.endTest( + id = testId, + endUTC = endUTC, + ) + } +} diff --git a/connector/shared/src/commonMain/kotlin/io/anthonyberg/connector/shared/entity/ActionResult.kt b/connector/shared/src/commonMain/kotlin/io/anthonyberg/connector/shared/entity/ActionResult.kt new file mode 100644 index 0000000..05016cb --- /dev/null +++ b/connector/shared/src/commonMain/kotlin/io/anthonyberg/connector/shared/entity/ActionResult.kt @@ -0,0 +1,31 @@ +package io.anthonyberg.connector.shared.entity + +import kotlinx.datetime.TimeZone +import kotlinx.datetime.toInstant +import kotlinx.datetime.toLocalDateTime +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class ActionResult( + @SerialName("id") + val id: Int, + @SerialName("test_id") + val testId: Int, + @SerialName("action_id") + val actionId: Int, + @SerialName("init_state") + val initState: String, + @SerialName("end_state") + val endState: String?, + @SerialName("description") + val description: String, + @SerialName("start_utc") + val startUTC: String, + @SerialName("end_utc") + val endUTC: String?, +) { + // Convert String time to LocalDateTime variable + var start = startUTC.toInstant().toLocalDateTime(TimeZone.UTC) + var end = endUTC?.toInstant()?.toLocalDateTime(TimeZone.UTC) +} diff --git a/connector/shared/src/commonMain/kotlin/io/anthonyberg/connector/shared/entity/Test.kt b/connector/shared/src/commonMain/kotlin/io/anthonyberg/connector/shared/entity/Test.kt new file mode 100644 index 0000000..44946e2 --- /dev/null +++ b/connector/shared/src/commonMain/kotlin/io/anthonyberg/connector/shared/entity/Test.kt @@ -0,0 +1,25 @@ +package io.anthonyberg.connector.shared.entity + +import kotlinx.datetime.TimeZone +import kotlinx.datetime.toInstant +import kotlinx.datetime.toLocalDateTime +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class Test( + @SerialName("id") + val id: Int, + @SerialName("procedure_id") + val procedureId: Int, + @SerialName("actions") + val actions: List?, + @SerialName("start_utc") + val startUTC: String, + @SerialName("end_utc") + val endUTC: String?, +) { + // Convert String time to LocalDateTime variable + var start = startUTC.toInstant().toLocalDateTime(TimeZone.UTC) + var end = endUTC?.toInstant()?.toLocalDateTime(TimeZone.UTC) +} diff --git a/connector/shared/src/commonMain/sqldelight/io/anthonyberg/connector/shared/database/ActionResult.sq b/connector/shared/src/commonMain/sqldelight/io/anthonyberg/connector/shared/database/ActionResult.sq index 1c95442..5af5fa7 100644 --- a/connector/shared/src/commonMain/sqldelight/io/anthonyberg/connector/shared/database/ActionResult.sq +++ b/connector/shared/src/commonMain/sqldelight/io/anthonyberg/connector/shared/database/ActionResult.sq @@ -18,3 +18,6 @@ finishResult: UPDATE ActionResult SET endState = ?, endUTC = ? WHERE id = ?; + +lastInsertedRowId: +SELECT last_insert_rowid(); diff --git a/connector/shared/src/commonMain/sqldelight/io/anthonyberg/connector/shared/database/Test.sq b/connector/shared/src/commonMain/sqldelight/io/anthonyberg/connector/shared/database/Test.sq index 8a7bfff..2bc6b6d 100644 --- a/connector/shared/src/commonMain/sqldelight/io/anthonyberg/connector/shared/database/Test.sq +++ b/connector/shared/src/commonMain/sqldelight/io/anthonyberg/connector/shared/database/Test.sq @@ -14,3 +14,6 @@ endTest: UPDATE Test SET endUTC = ? WHERE id = ?; + +lastInsertedRowId: +SELECT last_insert_rowid();