@@ -14,6 +14,7 @@ import org.intellij.lang.annotations.Language
1414import kotlin.coroutines.AbstractCoroutineContextElement
1515import kotlin.experimental.ExperimentalTypeInference
1616
17+ @TerpalSqlInternal
1718class CoroutineSession <Session >(val session : Session , val sessionKey : CoroutineContext .Key <CoroutineSession <Session >>) : AbstractCoroutineContextElement(sessionKey) {
1819 override fun toString () = " CoroutineSession($sessionKey )"
1920}
@@ -22,7 +23,7 @@ class TerpalException(msg: String, cause: Throwable?): Exception(msg, cause) {
2223 constructor (msg: String ): this (msg, null )
2324}
2425
25- @OptIn( TerpalSqlInternal :: class )
26+ @TerpalSqlInternal
2627interface EncodingConfig <Session , Stmt , ResultRow > {
2728 val additionalEncoders: Set <SqlEncoder <Session , Stmt , out Any >>
2829 val additionalDecoders: Set <SqlDecoder <Session , ResultRow , out Any >>
@@ -33,7 +34,7 @@ interface EncodingConfig<Session, Stmt, ResultRow> {
3334 val debugMode: Boolean
3435}
3536
36- @OptIn( TerpalSqlInternal :: class )
37+ @TerpalSqlInternal
3738interface WithEncoding <Session , Stmt , ResultRow > {
3839 val encodingConfig: EncodingConfig <Session , Stmt , ResultRow >
3940 val startingStatementIndex: StartingIndex get() = StartingIndex .Zero // default for JDBC is 1 so this needs to be overrideable
@@ -85,22 +86,34 @@ interface WithEncoding<Session, Stmt, ResultRow> {
8586 }
8687}
8788
88- @OptIn( TerpalSqlInternal :: class )
89+ @TerpalSqlInternal
8990interface RequiresSession <Session , Stmt , ExecutionOpts > {
9091
9192 // Methods that implementors need to provide
9293 val sessionKey: CoroutineContext .Key <CoroutineSession <Session >>
94+
95+ @TerpalSqlInternal
9396 abstract suspend fun newSession (executionOptions : ExecutionOpts ): Session
97+
98+ @TerpalSqlInternal
9499 abstract suspend fun closeSession (session : Session ): Unit
100+
101+ @TerpalSqlInternal
95102 abstract suspend fun isClosedSession (session : Session ): Boolean
103+
104+ @TerpalSqlInternal
96105 suspend fun <R > accessStmt (sql : String , conn : Session , block : suspend (Stmt ) -> R ): R
106+
107+ @TerpalSqlInternal
97108 suspend fun <R > accessStmtReturning (sql : String , conn : Session , options : ExecutionOpts , returningColumns : List <String >, block : suspend (Stmt ) -> R ): R
98109
110+ @TerpalSqlInternal
99111 suspend fun CoroutineContext.hasOpenConnection (): Boolean {
100112 val session = get(sessionKey)?.session
101113 return session != null && ! isClosedSession(session)
102114 }
103115
116+ @TerpalSqlInternal
104117 suspend fun <T > withConnection (executionOptions : ExecutionOpts , block : suspend CoroutineScope .() -> T ): T {
105118 return if (coroutineContext.hasOpenConnection()) {
106119 withContext(coroutineContext + Dispatchers .IO ) { block() }
@@ -115,7 +128,7 @@ interface RequiresSession<Session, Stmt, ExecutionOpts> {
115128 }
116129 }
117130
118-
131+ @TerpalSqlInternal
119132 suspend fun localConnection () =
120133 coroutineContext.get(sessionKey)?.session ? : error(" No connection detected in withConnection scope. This should be impossible." )
121134
@@ -140,9 +153,11 @@ interface RequiresSession<Session, Stmt, ExecutionOpts> {
140153 }
141154}
142155
156+ @TerpalSqlInternal
143157interface RequiresTransactionality <Session , Stmt , ExecutionOpts >: RequiresSession <Session , Stmt , ExecutionOpts > {
144158 abstract suspend fun <T > runTransactionally (block : suspend CoroutineScope .() -> T ): T
145159
160+ @TerpalSqlInternal
146161 suspend fun <T > withTransactionScope (executionOptions : ExecutionOpts , block : suspend CoroutineScope .() -> T ): T {
147162 val existingTransaction = coroutineContext[CoroutineTransaction ]
148163
@@ -159,48 +174,46 @@ interface RequiresTransactionality<Session, Stmt, ExecutionOpts>: RequiresSessio
159174 }
160175}
161176
162- @OptIn(TerpalSqlInternal ::class )
163177interface ControllerVerbs <ExecutionOpts > {
164178 fun DefaultOpts (): ExecutionOpts
165179
166- suspend fun <T > stream (query : ControllerQuery <T >, options : ExecutionOpts ): Flow <T >
167- suspend fun <T > stream (query : ControllerBatchActionReturning <T >, options : ExecutionOpts ): Flow <T >
168- suspend fun <T > stream (query : ControllerActionReturning <T >, options : ExecutionOpts ): Flow <T >
169- suspend fun <T > run (query : ControllerQuery <T >, options : ExecutionOpts ): List <T >
170- suspend fun run (query : ControllerAction , options : ExecutionOpts ): Long
171- suspend fun run (query : ControllerBatchAction , options : ExecutionOpts ): List <Long >
172- suspend fun <T > run (query : ControllerActionReturning <T >, options : ExecutionOpts ): T
173- suspend fun <T > run (query : ControllerBatchActionReturning <T >, options : ExecutionOpts ): List <T >
174-
175- suspend fun <T > runRaw (query : ControllerQuery <T >, options : ExecutionOpts ): List <List <Pair <String , String ?>>>
176-
177- suspend fun <T > stream (query : ControllerQuery <T >): Flow <T > = stream(query, DefaultOpts ())
178- suspend fun <T > stream (query : ControllerBatchActionReturning <T >): Flow <T > = stream(query, DefaultOpts ())
179- suspend fun <T > stream (query : ControllerActionReturning <T >): Flow <T > = stream(query, DefaultOpts ())
180- suspend fun <T > run (query : ControllerQuery <T >): List <T > = run (query, DefaultOpts ())
181- suspend fun run (query : ControllerAction ): Long = run (query, DefaultOpts ())
182- suspend fun run (query : ControllerBatchAction ): List <Long > = run (query, DefaultOpts ())
183- suspend fun <T > run (query : ControllerActionReturning <T >): T = run (query, DefaultOpts ())
184- suspend fun <T > run (query : ControllerBatchActionReturning <T >): List <T > = run (query, DefaultOpts ())
185-
186- suspend fun <T > runRaw (query : ControllerQuery <T >): List <List <Pair <String , String ?>>> = runRaw(query, DefaultOpts ())
180+ @TerpalSqlInternal suspend fun <T > stream (query : ControllerQuery <T >, options : ExecutionOpts ): Flow <T >
181+ @TerpalSqlInternal suspend fun <T > stream (query : ControllerBatchActionReturning <T >, options : ExecutionOpts ): Flow <T >
182+ @TerpalSqlInternal suspend fun <T > stream (query : ControllerActionReturning <T >, options : ExecutionOpts ): Flow <T >
183+ @TerpalSqlInternal suspend fun <T > run (query : ControllerQuery <T >, options : ExecutionOpts ): List <T >
184+ @TerpalSqlInternal suspend fun run (query : ControllerAction , options : ExecutionOpts ): Long
185+ @TerpalSqlInternal suspend fun run (query : ControllerBatchAction , options : ExecutionOpts ): List <Long >
186+ @TerpalSqlInternal suspend fun <T > run (query : ControllerActionReturning <T >, options : ExecutionOpts ): T
187+ @TerpalSqlInternal suspend fun <T > run (query : ControllerBatchActionReturning <T >, options : ExecutionOpts ): List <T >
188+
189+ @TerpalSqlInternal suspend fun <T > stream (query : ControllerQuery <T >): Flow <T > = stream(query, DefaultOpts ())
190+ @TerpalSqlInternal suspend fun <T > stream (query : ControllerBatchActionReturning <T >): Flow <T > = stream(query, DefaultOpts ())
191+ @TerpalSqlInternal suspend fun <T > stream (query : ControllerActionReturning <T >): Flow <T > = stream(query, DefaultOpts ())
192+ @TerpalSqlInternal suspend fun <T > run (query : ControllerQuery <T >): List <T > = run (query, DefaultOpts ())
193+ @TerpalSqlInternal suspend fun run (query : ControllerAction ): Long = run (query, DefaultOpts ())
194+ @TerpalSqlInternal suspend fun run (query : ControllerBatchAction ): List <Long > = run (query, DefaultOpts ())
195+ @TerpalSqlInternal suspend fun <T > run (query : ControllerActionReturning <T >): T = run (query, DefaultOpts ())
196+ @TerpalSqlInternal suspend fun <T > run (query : ControllerBatchActionReturning <T >): List <T > = run (query, DefaultOpts ())
197+
198+ @TerpalSqlInternal suspend fun <T > runRaw (query : ControllerQuery <T >, options : ExecutionOpts ): List <List <Pair <String , String ?>>>
199+ @TerpalSqlInternal suspend fun <T > runRaw (query : ControllerQuery <T >): List <List <Pair <String , String ?>>> = runRaw(query, DefaultOpts ())
187200}
188201
189202/* *
190203 * This is the base class of all Terpal Drivers (not to be confused with JDBC drivers or similar).
191204 * This is a minimal set of semantics needed to support Sql-interpolated query executions. This makes minimal assumptions
192205 * about how the context functionality is composed. Typically implementations will want to start with ContextBase or ContextCannonical.
193206 */
194- @OptIn(TerpalSqlInternal ::class )
195207interface Controller <ExecutionOpts >: ControllerVerbs <ExecutionOpts > {
196208
197209}
198210
199- @OptIn( TerpalSqlInternal :: class )
200- suspend fun Controller <* >.runActions (@Language(" SQL" ) actions : String ): List < Long > =
211+ @TerpalSqlUnsafe
212+ suspend fun Controller <* >.runActionsUnsafe (@Language(" SQL" ) actions : String ): Unit {
201213 actions.split(" ;" ).map { it.trim() }.filter { it.isNotEmpty() }.map { run (ControllerAction (it, listOf ()), DefaultOpts ()) }
214+ }
215+
202216
203- @OptIn(TerpalSqlInternal ::class )
204217interface ControllerTransactional <Session , Stmt , ExecutionOpts >: Controller <ExecutionOpts >, RequiresSession <Session , Stmt , ExecutionOpts >, RequiresTransactionality <Session , Stmt , ExecutionOpts > {
205218 fun showStats (): String = " "
206219}
@@ -210,14 +223,15 @@ interface ControllerTransactional<Session, Stmt, ExecutionOpts>: Controller<Exec
210223 * and encoders. The assumption here is that the same Session/Row/Result types used in the encoders are used in the session-handling.
211224 * If this is not the case use ContextBase.
212225 */
213- @OptIn( TerpalSqlInternal :: class )
226+ @TerpalSqlInternal
214227interface ControllerCanonical <Session , Stmt , ResultRow , ExecutionOpts >: ControllerTransactional <Session , Stmt , ExecutionOpts >, RequiresSession <Session , Stmt , ExecutionOpts >, RequiresTransactionality <Session , Stmt , ExecutionOpts >, WithEncoding <Session , Stmt , ResultRow >
215228
216229suspend fun <T > ControllerQuery<T>.runOn (ctx : Controller <* >) = ctx.run (this )
217230suspend fun <T > ControllerQuery<T>.streamOn (ctx : Controller <* >) = ctx.stream(this )
218231suspend fun <T > ControllerQuery<T>.runRawOn (ctx : Controller <* >) = ctx.runRaw(this )
219232suspend fun ControllerAction.runOn (ctx : Controller <* >) = ctx.run (this )
220233suspend fun <T > ControllerActionReturning<T>.runOn (ctx : Controller <* >) = ctx.run (this )
234+ suspend fun <T > ControllerActionReturning<T>.streamOn (ctx : Controller <* >) = ctx.stream(this )
221235suspend fun ControllerBatchAction.runOn (ctx : Controller <* >) = ctx.run (this )
222236suspend fun <T > ControllerBatchActionReturning<T>.runOn (ctx : Controller <* >) = ctx.run (this )
223237suspend fun <T > ControllerBatchActionReturning<T>.streamOn (ctx : Controller <* >) = ctx.stream(this )
0 commit comments