Skip to content

Instantly share code, notes, and snippets.

@dmcg
Created June 9, 2023 21:56
Show Gist options
  • Save dmcg/bfa6407f4eb09c3171b08a1f4305f0c7 to your computer and use it in GitHub Desktop.
Save dmcg/bfa6407f4eb09c3171b08a1f4305f0c7 to your computer and use it in GitHub Desktop.
package com.gildedrose
import com.gildedrose.domain.StockList
import com.gildedrose.foundation.magic
import com.gildedrose.persistence.*
import dev.forkhandles.result4k.Result
import dev.forkhandles.result4k.Success
import org.jooq.DSLContext
import org.junit.jupiter.api.Test
class JooqContextsTests {
val items = NewItems()
@Test
fun `two transactions`() {
with(Persistence(testDslContext)) {
items.save(initialStockList)
items.load()
}
}
@Test
fun `one transaction`() {
with(Persistence(testDslContext)) {
inNewOrExistingTX {
items.save(initialStockList)
items.load()
}
}
}
@Test
fun `nested transaction with savepoints`() {
with(Persistence(testDslContext)) {
inNewOrExistingTX {
inNewTX {
items.save(initialStockList)
}
items.load()
}
}
}
}
data class Persistence(
val dslContext: DSLContext,
val isInTX: Boolean = false
)
context(Persistence)
fun <R> inNewOrExistingTX(f: context(Persistence)() -> R): R = when {
isInTX -> f(magic())
else -> dslContext.transactionResult { trx ->
f(Persistence(trx.dsl(), isInTX = true))
}
}
context(Persistence)
fun <R> inNewTX(f: context(Persistence)() -> R): R =
dslContext.transactionResult { trx ->
f(Persistence(trx.dsl(), isInTX = true))
}
class NewItems {
context(Persistence)
fun save(stockList: StockList)
: Result<StockList, StockListLoadingError.IOError> = inNewOrExistingTX {
dslContext.save(stockList)
Success(stockList)
}
context(Persistence)
fun load(): Result<StockList, StockListLoadingError> = inNewOrExistingTX {
Success(dslContext.load())
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment