11import { lowerCaseFirst } from '@zenstackhq/common-helpers' ;
2- import type { SqliteDialectConfig } from 'kysely' ;
2+ import type { QueryExecutor , SqliteDialectConfig } from 'kysely' ;
33import {
44 CompiledQuery ,
55 DefaultConnectionProvider ,
@@ -60,6 +60,7 @@ export class ClientImpl<Schema extends SchemaDef> {
6060 private readonly schema : Schema ,
6161 private options : ClientOptions < Schema > ,
6262 baseClient ?: ClientImpl < Schema > ,
63+ executor ?: QueryExecutor ,
6364 ) {
6465 this . $schema = schema ;
6566 this . $options = options ?? ( { } as ClientOptions < Schema > ) ;
@@ -73,22 +74,24 @@ export class ClientImpl<Schema extends SchemaDef> {
7374 if ( baseClient ) {
7475 this . kyselyProps = {
7576 ...baseClient . kyselyProps ,
76- executor : new ZenStackQueryExecutor (
77- this ,
78- baseClient . kyselyProps . driver as ZenStackDriver ,
79- baseClient . kyselyProps . dialect . createQueryCompiler ( ) ,
80- baseClient . kyselyProps . dialect . createAdapter ( ) ,
81- new DefaultConnectionProvider ( baseClient . kyselyProps . driver ) ,
82- ) ,
77+ executor :
78+ executor ??
79+ new ZenStackQueryExecutor (
80+ this ,
81+ baseClient . kyselyProps . driver as ZenStackDriver ,
82+ baseClient . kyselyProps . dialect . createQueryCompiler ( ) ,
83+ baseClient . kyselyProps . dialect . createAdapter ( ) ,
84+ new DefaultConnectionProvider ( baseClient . kyselyProps . driver ) ,
85+ ) ,
8386 } ;
8487 this . kyselyRaw = baseClient . kyselyRaw ;
88+ this . auth = baseClient . auth ;
8589 } else {
8690 const dialect = this . getKyselyDialect ( ) ;
8791 const driver = new ZenStackDriver ( dialect . createDriver ( ) , new Log ( this . $options . log ?? [ ] ) ) ;
8892 const compiler = dialect . createQueryCompiler ( ) ;
8993 const adapter = dialect . createAdapter ( ) ;
9094 const connectionProvider = new DefaultConnectionProvider ( driver ) ;
91- const executor = new ZenStackQueryExecutor ( this , driver , compiler , adapter , connectionProvider ) ;
9295
9396 this . kyselyProps = {
9497 config : {
@@ -97,7 +100,7 @@ export class ClientImpl<Schema extends SchemaDef> {
97100 } ,
98101 dialect,
99102 driver,
100- executor,
103+ executor : executor ?? new ZenStackQueryExecutor ( this , driver , compiler , adapter , connectionProvider ) ,
101104 } ;
102105
103106 // raw kysely instance with default executor
@@ -112,14 +115,21 @@ export class ClientImpl<Schema extends SchemaDef> {
112115 return createClientProxy ( this ) ;
113116 }
114117
115- public get $qb ( ) {
118+ get $qb ( ) {
116119 return this . kysely ;
117120 }
118121
119- public get $qbRaw ( ) {
122+ get $qbRaw ( ) {
120123 return this . kyselyRaw ;
121124 }
122125
126+ /**
127+ * Create a new client with a new query executor.
128+ */
129+ withExecutor ( executor : QueryExecutor ) {
130+ return new ClientImpl ( this . schema , this . $options , this , executor ) ;
131+ }
132+
123133 private getKyselyDialect ( ) {
124134 return match ( this . schema . provider . type )
125135 . with ( 'sqlite' , ( ) => this . makeSqliteKyselyDialect ( ) )
@@ -136,11 +146,17 @@ export class ClientImpl<Schema extends SchemaDef> {
136146 }
137147
138148 async $transaction < T > ( callback : ( tx : ClientContract < Schema > ) => Promise < T > ) : Promise < T > {
139- return this . kysely . transaction ( ) . execute ( ( tx ) => {
140- const txClient = new ClientImpl < Schema > ( this . schema , this . $options ) ;
141- txClient . kysely = tx ;
142- return callback ( txClient as unknown as ClientContract < Schema > ) ;
143- } ) ;
149+ if ( this . kysely . isTransaction ) {
150+ // proceed directly if already in a transaction
151+ return callback ( this as unknown as ClientContract < Schema > ) ;
152+ } else {
153+ // otherwise, create a new transaction, clone the client, and execute the callback
154+ return this . kysely . transaction ( ) . execute ( ( tx ) => {
155+ const txClient = new ClientImpl < Schema > ( this . schema , this . $options ) ;
156+ txClient . kysely = tx ;
157+ return callback ( txClient as unknown as ClientContract < Schema > ) ;
158+ } ) ;
159+ }
144160 }
145161
146162 get $procedures ( ) {
0 commit comments