import type { EntityManager , MergeOptions } from '../EntityManager' ; import type { EntityData , EntityName , AnyEntity , Primary , Loaded , New , FilterQuery , EntityDictionary , AutoPath } from '../typings' ; import type { CountOptions , DeleteOptions , FindOneOptions , FindOneOrFailOptions , FindOptions , GetReferenceOptions , UpdateOptions } from '../drivers/IDatabaseDriver' ; import type { IdentifiedReference , Reference } from './Reference' ; import type { EntityLoaderOptions } from './EntityLoader' ; export class EntityRepository < T extends AnyEntity < T > > { constructor ( protected readonly _em , protected readonly entityName ) { } /**
     * Tells the EntityManager to make an instance managed and persistent.
     * The entity will be entered into the database at or before transaction commit or as a result of the flush operation.
     */ persist ( entity ) { return this . em . persist ( entity ) ; } /**
     * Persists your entity immediately, flushing all not yet persisted changes to the database too.
     * Equivalent to `em.persist(e).flush()`.
     */ async persistAndFlush ( entity ) { await this . em . persistAndFlush ( entity ) ; } deprecated persistLater ( entity ) { this . em . persistLater ( entity ) ; } /**
     * Finds first entity matching your `where` query.
     */ async findOne < P extends string = never > ( where , options ? ) { return this . em . findOne < T , P > ( this . entityName , where , options ) ; } /**
     * Finds first entity matching your `where` query. If nothing found, it will throw an error.
     * You can override the factory for creating this method via `options.failHandler` locally
     * or via `Configuration.findOneOrFailHandler` globally.
     */ async findOneOrFail < P extends string = never > ( where , options ? ) { return this . em . findOneOrFail < T , P > ( this . entityName , where , options ) ; } /**
     * Finds all entities matching your `where` query. You can pass additional options via the `options` parameter.
     */ async find < P extends string = never > ( where , options ? ) { return this . em . find < T , P > ( this . entityName , where as FilterQuery < T > , options ) ; } /**
     * Calls `em.find()` and `em.count()` with the same arguments (where applicable) and returns the results as tuple
     * where first element is the array of entities and the second is the count.
     */ async findAndCount < P extends string = never > ( where , options ? ) { return this . em . findAndCount < T , P > ( this . entityName , where , options ) ; } /**
     * Finds all entities of given type. You can pass additional options via the `options` parameter.
     */ async findAll < P extends string = never > ( options ? ) { return this . em . find < T , P > ( this . entityName , { } as FilterQuery < T > , options ) ; } /**
     * Marks entity for removal.
     * A removed entity will be removed from the database at or before transaction commit or as a result of the flush operation.
     *
     * To remove entities by condition, use `em.nativeDelete()`.
     */ remove ( entity ) { return this . em . remove ( entity ) ; } /**
     * Removes an entity instance immediately, flushing all not yet persisted changes to the database too.
     * Equivalent to `em.remove(e).flush()`
     */ async removeAndFlush ( entity ) { await this . em . removeAndFlush ( entity ) ; } deprecated removeLater ( entity ) { this . em . removeLater ( entity ) ; } /**
     * Flushes all changes to objects that have been queued up to now to the database.
     * This effectively synchronizes the in-memory state of managed objects with the database.
     * This method is a shortcut for `em.flush()`, in other words, it will flush the whole UoW,
     * not just entities registered via this particular repository.
     */ async flush ( ) { return this . em . flush ( ) ; } /**
     * Fires native insert query. Calling this has no side effects on the context (identity map).
     */ async nativeInsert ( data ) { return this . em . nativeInsert < T > ( this . entityName , data ) ; } /**
     * Fires native update query. Calling this has no side effects on the context (identity map).
     */ async nativeUpdate ( where , data , options ? ) { return this . em . nativeUpdate ( this . entityName , where , data , options ) ; } /**
     * Fires native delete query. Calling this has no side effects on the context (identity map).
     */ async nativeDelete ( where , options ? ) { return this . em . nativeDelete ( this . entityName , where , options ) ; } /**
     * Maps raw database result to an entity and merges it to this EntityManager.
     */ map ( result , options ? ) { return this . em . map ( this . entityName , result , options ) ; } /**
     * Gets a reference to the entity identified by the given type and identifier without actually loading it, if the entity is not yet loaded
     */ getReference < PK extends keyof T > ( id , options ) ; /**
     * Gets a reference to the entity identified by the given type and identifier without actually loading it, if the entity is not yet loaded
     */ getReference ( id ) ; /**
     * Gets a reference to the entity identified by the given type and identifier without actually loading it, if the entity is not yet loaded
     */ getReference ( id , options ) ; /**
     * Gets a reference to the entity identified by the given type and identifier without actually loading it, if the entity is not yet loaded
     */ getReference < PK extends keyof T = keyof T > ( id , options ? ) { return this . em . getReference < T > ( this . entityName , id , options ) ; } /**
     * Checks whether given property can be populated on the entity.
     */ canPopulate ( property ) { return this . em . canPopulate ( this . entityName , property ) ; } /**
     * Loads specified relations in batch. This will execute one query for each relation, that will populate it on all of the specified entities.
     */ async populate < P extends string = never > ( entities , populate , options ? ) { return this . em . populate ( entities as T , populate , options ) ; } /**
     * Creates new instance of given entity and populates it with given data.
     * The entity constructor will be used unless you provide `{ managed: true }` in the options parameter.
     * The constructor will be given parameters based on the defined constructor of the entity. If the constructor
     * parameter matches a property name, its value will be extracted from `data`. If no matching property exists,
     * the whole `data` parameter will be passed. This means we can also define `constructor(data: Partial<T>)` and
     * `em.create()` will pass the data into it (unless we have a property named `data` too).
     */ create < P extends string = any > ( data ) { return this . em . create < T , P > ( this . entityName , data ) ; } /**
     * Shortcut for `wrap(entity).assign(data, { em })`
     */ assign ( entity , data ) { return this . em . assign ( entity , data ) ; } /**
     * Merges given entity to this EntityManager so it becomes managed. You can force refreshing of existing entities
     * via second parameter. By default it will return already loaded entities without modifying them.
     */ merge ( data , options ? ) { return this . em . merge < T > ( this . entityName , data , options ) ; } /**
     * Returns total number of entities matching your `where` query.
     */ async count < P extends string = never > ( where = { } as FilterQuery < T > , options = { } ) { return this . em . count ( this . entityName , where , options ) ; } protected get em ( ) : EntityManager { return this . _em . getContext ( ) ; } }