1- import { EntityManager , EntityMetadata , FindOptionsOrder , FindOptionsRelations , FindOptionsWhere } from 'typeorm'
1+ import {
2+ EntityManager ,
3+ EntityMetadata ,
4+ EntityNotFoundError ,
5+ FindOptionsOrder ,
6+ FindOptionsRelations ,
7+ FindOptionsWhere ,
8+ } from 'typeorm'
29import { EntityTarget } from 'typeorm/common/EntityTarget'
310import { ChangeWriter } from './utils/changeWriter'
411import { StateManager } from './utils/stateManager'
@@ -237,7 +244,7 @@ export class Store {
237244 private async _delete ( metadata : EntityMetadata , ids : string [ ] ) {
238245 this . logger ?. debug ( `delete ${ metadata . name } ${ ids . length } entities` )
239246 await this . changes ?. writeDelete ( metadata , ids )
240- await this . em . delete ( metadata . target , ids ) // TODO : should be split by chunks too?
247+ await this . em . delete ( metadata . target , ids ) // NOTE : should be split by chunks too?
241248 }
242249
243250 async count < E extends EntityLiteral > ( target : EntityTarget < E > , options ?: FindManyOptions < E > ) : Promise < number > {
@@ -250,16 +257,19 @@ export class Store {
250257 target : EntityTarget < E > ,
251258 where : FindOptionsWhere < E > | FindOptionsWhere < E > [ ]
252259 ) : Promise < number > {
253- return await this . performRead ( async ( ) => {
254- return await this . em . countBy ( target , where )
255- } )
260+ return await this . count ( target , { where} )
256261 }
257262
258263 async find < E extends EntityLiteral > ( target : EntityTarget < E > , options : FindManyOptions < E > ) : Promise < E [ ] > {
259264 return await this . performRead ( async ( ) => {
260265 const { cache, ...opts } = options
261266 const res = await this . em . find ( target , opts )
262- if ( cache ?? this . cacheMode === 'ALL' ) this . persistEntities ( target , res , options ?. relations )
267+ if ( cache ?? this . cacheMode === 'ALL' ) {
268+ const metadata = this . getEntityMetadata ( target )
269+ for ( const e of res ) {
270+ this . cacheEntity ( metadata , e )
271+ }
272+ }
263273 return res
264274 } )
265275 }
@@ -269,11 +279,7 @@ export class Store {
269279 where : FindOptionsWhere < E > | FindOptionsWhere < E > [ ] ,
270280 cache ?: boolean
271281 ) : Promise < E [ ] > {
272- return await this . performRead ( async ( ) => {
273- const res = await this . em . findBy ( target , where )
274- if ( cache ?? this . cacheMode === 'ALL' ) this . persistEntities ( target , res )
275- return res
276- } )
282+ return await this . find ( target , { where, cache} )
277283 }
278284
279285 async findOne < E extends EntityLiteral > (
@@ -283,8 +289,11 @@ export class Store {
283289 return await this . performRead ( async ( ) => {
284290 const { cache, ...opts } = options
285291 const res = await this . em . findOne ( target , opts ) . then ( noNull )
286- if ( res != null && ( cache ?? this . cacheMode === 'ALL' ) )
287- this . persistEntities ( target , res , options ?. relations )
292+ if ( cache ?? this . cacheMode === 'ALL' ) {
293+ const metadata = this . getEntityMetadata ( target )
294+ const idOrEntity = res || getIdFromWhere ( options . where )
295+ this . cacheEntity ( metadata , idOrEntity )
296+ }
288297 return res
289298 } )
290299 }
@@ -294,34 +303,23 @@ export class Store {
294303 where : FindOptionsWhere < E > | FindOptionsWhere < E > [ ] ,
295304 cache ?: boolean
296305 ) : Promise < E | undefined > {
297- return await this . performRead ( async ( ) => {
298- const res = await this . em . findOneBy ( target , where ) . then ( noNull )
299- if ( res != null && ( cache ?? this . cacheMode === 'ALL' ) ) this . persistEntities ( target , res )
300-
301- return res
302- } )
306+ return await this . findOne ( target , { where, cache} )
303307 }
304308
305309 async findOneOrFail < E extends EntityLiteral > ( target : EntityTarget < E > , options : FindOneOptions < E > ) : Promise < E > {
306- return await this . performRead ( async ( ) => {
307- const { cache, ...opts } = options
308- const res = await this . em . findOneOrFail ( target , opts )
309- if ( cache ?? this . cacheMode === 'ALL' ) this . persistEntities ( target , res , options ?. relations )
310-
311- return res
312- } )
310+ const res = await this . findOne ( target , options )
311+ if ( res == null ) throw new EntityNotFoundError ( target , options . where )
312+ return res
313313 }
314314
315315 async findOneByOrFail < E extends EntityLiteral > (
316316 target : EntityTarget < E > ,
317317 where : FindOptionsWhere < E > | FindOptionsWhere < E > [ ] ,
318318 cache ?: boolean
319319 ) : Promise < E > {
320- return await this . performRead ( async ( ) => {
321- const res = await this . em . findOneByOrFail ( target , where )
322- if ( cache || this . cacheMode === 'ALL' ) this . persistEntities ( target , res )
323- return res
324- } )
320+ const res = await this . findOneBy ( target , where , cache )
321+ if ( res == null ) throw new EntityNotFoundError ( target , where )
322+ return res
325323 }
326324
327325 async get < E extends EntityLiteral > ( target : EntityTarget < E > , id : string ) : Promise < E | undefined >
@@ -331,28 +329,18 @@ export class Store {
331329 idOrOptions : string | GetOptions < E >
332330 ) : Promise < E | undefined > {
333331 const { id, relations} = parseGetOptions ( idOrOptions )
334-
335332 const metadata = this . getEntityMetadata ( target )
336333 let entity = this . state . get < E > ( metadata , id , relations )
337334 if ( entity !== undefined ) return noNull ( entity )
338-
339335 return await this . findOne ( target , { where : { id} as any , relations, cache : true } )
340336 }
341337
342- async getOrFail < E extends EntityLiteral > ( entityClass : EntityTarget < E > , id : string ) : Promise < E >
343- async getOrFail < E extends EntityLiteral > ( entityClass : EntityTarget < E > , options : GetOptions < E > ) : Promise < E >
344- async getOrFail < E extends EntityLiteral > (
345- entityClass : EntityTarget < E > ,
346- idOrOptions : string | GetOptions < E >
347- ) : Promise < E > {
338+ async getOrFail < E extends EntityLiteral > ( target : EntityTarget < E > , id : string ) : Promise < E >
339+ async getOrFail < E extends EntityLiteral > ( target : EntityTarget < E > , options : GetOptions < E > ) : Promise < E >
340+ async getOrFail < E extends EntityLiteral > ( target : EntityTarget < E > , idOrOptions : string | GetOptions < E > ) : Promise < E > {
348341 const options = parseGetOptions ( idOrOptions )
349- let e = await this . get ( entityClass , options )
350-
351- if ( e == null ) {
352- const metadata = this . getEntityMetadata ( entityClass )
353- throw new Error ( `Missing entity ${ metadata . name } with id "${ options . id } "` )
354- }
355-
342+ let e = await this . get ( target , options )
343+ if ( e == null ) throw new EntityNotFoundError ( target , options . id )
356344 return e
357345 }
358346
@@ -365,89 +353,66 @@ export class Store {
365353
366354 this . pendingCommit = createFuture ( )
367355 try {
368- const { upserts, inserts, deletes, extraUpserts} = this . state . computeChangeSets ( )
356+ await this . state . performUpdate ( async ( { upserts, inserts, deletes, extraUpserts} ) => {
357+ for ( const { metadata, entities} of upserts ) {
358+ await this . _upsert ( metadata , entities )
359+ }
369360
370- for ( const { metadata, entities} of upserts ) {
371- await this . _upsert ( metadata , entities )
372- }
361+ for ( const { metadata, entities} of inserts ) {
362+ await this . _insert ( metadata , entities )
363+ }
373364
374- for ( const { metadata, entities } of inserts ) {
375- await this . _insert ( metadata , entities )
376- }
365+ for ( const { metadata, ids } of deletes ) {
366+ await this . _delete ( metadata , ids )
367+ }
377368
378- for ( const { metadata, ids} of deletes ) {
379- await this . _delete ( metadata , ids )
380- }
369+ for ( const { metadata, entities} of extraUpserts ) {
370+ await this . _upsert ( metadata , entities )
371+ }
372+ } )
381373
382- for ( const { metadata , entities } of extraUpserts ) {
383- await this . _upsert ( metadata , entities )
374+ if ( this . resetMode === 'FLUSH' || reset ) {
375+ this . reset ( )
384376 }
385-
386- this . state . clear ( )
387377 } finally {
388378 this . pendingCommit . resolve ( )
389379 this . pendingCommit = undefined
390380 }
391-
392- if ( this . resetMode === 'FLUSH' || reset ) {
393- this . reset ( )
394- }
395- }
396-
397- /**
398- * @internal
399- */
400- _close ( ) {
401- this . isClosed = true
402381 }
403382
404383 private async performRead < T > ( cb : ( ) => Promise < T > ) : Promise < T > {
405- this . assetNotClosed ( )
406-
384+ this . assertNotClosed ( )
407385 if ( this . flushMode === 'AUTO' || this . flushMode === 'ALWAYS' ) {
408386 await this . flush ( )
409387 }
410-
411388 return await cb ( )
412389 }
413390
414391 private async performWrite ( cb : ( ) => Promise < void > ) : Promise < void > {
392+ this . assertNotClosed ( )
415393 await this . pendingCommit ?. promise ( )
416-
417- this . assetNotClosed ( )
418-
419394 await cb ( )
420-
421395 if ( this . flushMode === 'ALWAYS' ) {
422396 await this . flush ( )
423397 }
424398 }
425399
426- private assetNotClosed ( ) {
400+ private assertNotClosed ( ) {
427401 assert ( ! this . isClosed , `too late to perform db updates, make sure you haven't forgot to await on db query` )
428402 }
429403
430- private persistEntities < E extends EntityLiteral > (
431- target : EntityTarget < E > ,
432- e : E | E [ ] ,
433- relationMask ?: FindOptionsRelations < any >
434- ) {
435- const metadata = this . getEntityMetadata ( target )
436-
437- e = Array . isArray ( e ) ? e : [ e ]
438- for ( const entity of e ) {
439- traverseEntity ( {
440- metadata,
441- entity,
442- relationMask : relationMask || null ,
443- cb : ( e , md ) => this . state ?. persist ( md , e ) ,
444- } )
404+ private cacheEntity < E extends EntityLiteral > ( metadata : EntityMetadata , entityOrId ?: E | string ) {
405+ if ( entityOrId == null ) {
406+ return
407+ } else if ( typeof entityOrId === 'string' ) {
408+ this . state . settle ( metadata , entityOrId )
409+ } else {
410+ traverseEntity ( metadata , entityOrId , ( e , md ) => this . state . persist ( md , e ) )
445411 }
446412 }
447413
448414 private getEntityMetadata ( target : EntityTarget < any > ) {
449- const em = this . em
450- return em . connection . getMetadata ( target )
415+ return this . em . connection . getMetadata ( target )
451416 }
452417}
453418
@@ -458,3 +423,7 @@ function parseGetOptions<E>(idOrOptions: string | GetOptions<E>): GetOptions<E>
458423 return idOrOptions
459424 }
460425}
426+
427+ function getIdFromWhere ( where ?: FindOptionsWhere < EntityLiteral > ) {
428+ return typeof where ?. id === 'string' ? where . id : undefined
429+ }
0 commit comments