55 DeepPartial ,
66 EntityManager ,
77 getRepository ,
8+ QueryBuilder ,
9+ ReplicationMode ,
810 Repository ,
911 SelectQueryBuilder
1012} from 'typeorm' ;
@@ -34,6 +36,10 @@ export interface BaseOptions {
3436 manager ?: EntityManager ; // Allows consumers to pass in a TransactionManager
3537}
3638
39+ export interface AdvancedFindOptions {
40+ replicationMode ?: ReplicationMode ;
41+ }
42+
3743interface WhereFilterAttributes {
3844 [ key : string ] : string | number | null ;
3945}
@@ -114,12 +120,13 @@ export class BaseService<E extends BaseModel> {
114120 orderBy ?: string ,
115121 limit ?: number ,
116122 offset ?: number ,
117- fields ?: string [ ]
123+ fields ?: string [ ] ,
124+ options : AdvancedFindOptions = { }
118125 ) : Promise < E [ ] > {
119126 // TODO: FEATURE - make the default limit configurable
120127 limit = limit ?? 20 ;
121128 debugStatement ( 'find:buildQuery' ) ;
122- const qb = this . buildFindQuery < W > ( where , orderBy , { limit, offset } , fields ) ;
129+ const qb = this . buildFindQuery < W > ( where , orderBy , { limit, offset } , fields , options ) ;
123130 try {
124131 debugStatement ( 'find:gettingMany' ) ;
125132 const records = await qb . getMany ( ) ;
@@ -129,6 +136,8 @@ export class BaseService<E extends BaseModel> {
129136 debugStatement ( 'find:error' ) ;
130137 logger . error ( 'failed on getMany' , e ) ;
131138 throw e ;
139+ } finally {
140+ this . cleanUpQueryBuilder ( qb ) ;
132141 }
133142 }
134143
@@ -137,7 +146,8 @@ export class BaseService<E extends BaseModel> {
137146 whereUserInput : any = { } , // V3: WhereExpression = {},
138147 orderBy ?: string | string [ ] ,
139148 _pageOptions : RelayPageOptionsInput = { } ,
140- fields ?: ConnectionInputFields
149+ fields ?: ConnectionInputFields ,
150+ options : AdvancedFindOptions = { }
141151 ) : Promise < ConnectionResult < E > > {
142152 // TODO: if the orderby items aren't included in `fields`, should we automatically include?
143153
@@ -176,7 +186,8 @@ export class BaseService<E extends BaseModel> {
176186 whereCombined ,
177187 this . relayService . effectiveOrderStrings ( sorts , relayPageOptions ) ,
178188 { limit : limit + 1 } , // We ask for 1 too many so that we know if there is an additional page
179- requestedFields . selectFields
189+ requestedFields . selectFields ,
190+ options
180191 ) ;
181192
182193 let rawData ;
@@ -189,6 +200,8 @@ export class BaseService<E extends BaseModel> {
189200 rawData = await qb . getMany ( ) ;
190201 }
191202
203+ this . cleanUpQueryBuilder ( qb ) ;
204+
192205 // If we got the n+1 that we requested, pluck the last item off
193206 const returnData = rawData . length > limit ? rawData . slice ( 0 , limit ) : rawData ;
194207
@@ -209,13 +222,19 @@ export class BaseService<E extends BaseModel> {
209222 where : WhereExpression = { } ,
210223 orderBy ?: string | string [ ] ,
211224 pageOptions ?: LimitOffset ,
212- fields ?: string [ ]
225+ fields ?: string [ ] ,
226+ options : AdvancedFindOptions = { }
213227 ) : SelectQueryBuilder < E > {
214228 try {
215229 const DEFAULT_LIMIT = 50 ;
216- let qb = this . manager . connection
217- . createQueryBuilder < E > ( this . entityClass , this . klass )
218- . setQueryRunner ( this . manager . connection . createQueryRunner ( 'slave' ) ) ;
230+ let qb = this . manager . connection . createQueryBuilder < E > ( this . entityClass , this . klass ) ;
231+ if ( options . replicationMode ) {
232+ const queryRunner = this . manager . connection . createQueryRunner ( options . replicationMode ) ;
233+ qb . setQueryRunner ( queryRunner ) ;
234+ ( qb as any ) . warthogQueryRunnerOverride = queryRunner ;
235+ }
236+
237+ //
219238 if ( ! pageOptions ) {
220239 pageOptions = {
221240 limit : DEFAULT_LIMIT
@@ -476,6 +495,15 @@ export class BaseService<E extends BaseModel> {
476495 return { id : found . id } ;
477496 }
478497
498+ // This is really ugly. Shouldn't be attaching to the querybuilder, but need to keep track of whether this
499+ // instance of the queryBuilder was created with a custom query runner so that it can be cleaned up
500+ cleanUpQueryBuilder ( qb : QueryBuilder < E > ) {
501+ // console.log(qb);
502+ if ( ( qb as any ) . warthogQueryRunnerOverride ) {
503+ ( qb as any ) . warthogQueryRunnerOverride . release ( ) ;
504+ }
505+ }
506+
479507 attrsToDBColumns = ( attrs : string [ ] ) : string [ ] => {
480508 return attrs . map ( this . attrToDBColumn ) ;
481509 } ;
0 commit comments