Created
February 17, 2025 01:49
-
-
Save aboisvert/c716c9e08f6d91c2b427fd855e3b4645 to your computer and use it in GitHub Desktop.
Illustration of using Scala macro to statically prevent nested transactions using the scalasql library
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// See https://github.com/com-lihaoyi/scalasql | |
import scalasql.* | |
/** Shorthand for delimited transaction: | |
* | |
* ``` | |
* db.txn: | |
* val data = runSomeQuery() | |
* doSomeUpdate(...) | |
* ``` | |
*/ | |
extension (db: DbClient) | |
/** Runs `f` as part of a database transaction */ | |
inline def txn[T](f: DbApi.Txn ?=> T): T = | |
TxnMacros.txnImpl(db, f) | |
object TxnMacros: | |
import scala.quoted.* | |
import scala.compiletime.{error, summonFrom} | |
def txnImpl[T](db: Expr[DbClient], f: Expr[DbApi.Txn ?=> T])(using _quotes: Quotes, _typeT: Type[T]): Expr[T] = | |
'{ | |
checkNoNestedTransaction() | |
$db.transaction(txn => $f(using txn)) | |
} | |
inline def checkNoNestedTransaction(): Unit = | |
summonFrom[DbApi.Txn]: | |
case _: DbApi.Txn => error("Nested transactions not supported") | |
case _ => () |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment