All files / adapters repository.ts

100% Statements 21/21
100% Branches 11/11
100% Functions 7/7
100% Lines 21/21

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94  10x 10x         10x                 62x 62x 62x 62x                     8x 8x   8x                   2x 2x   2x                   1x 1x   1x                 4x                   1x 1x   1x                   1x    
import { Type } from '../core/types';
import { DatabaseAdapter, DatabaseAdapterRegistry } from './interface';
import { MetadataRegistry } from '../core/MetadataRegistry';
 
/**
 * Generic Repository implementation that works with any database adapter
 */
export class Repository<T extends object> {
  /**
   * Create a new repository for an entity type
   * @param entityType The entity class
   * @param adapter The database adapter to use
   * @param registry The metadata registry to use
   * @param adapterRegistry The database adapter registry to use
   */
  constructor(
    private entityType: Type<T>,
    private adapter: DatabaseAdapter,
    private registry: MetadataRegistry = new MetadataRegistry(),
    private adapterRegistry = DatabaseAdapterRegistry.getInstance()
  ) {}
  
  
  /**
   * Find an entity by its ID
   * @param id The entity ID
   * @returns Promise resolving to entity or null
   */
  async findById(id: string | number): Promise<T | null> {
    // Get the database-specific entity if it exists
    const dbType = this.adapter.type;
    const dbEntityType = this.adapterRegistry.getAdapterEntity(dbType, this.entityType) as Type<T> || this.entityType;
    
    return this.adapter.query<T>(dbEntityType, { id });
  }
  
  /**
   * Find entities matching criteria
   * @param criteria Query criteria
   * @returns Promise resolving to array of entities
   */
  async find(criteria: object = {}): Promise<T[]> {
    // Get the database-specific entity if it exists
    const dbType = this.adapter.type;
    const dbEntityType = this.adapterRegistry.getAdapterEntity(dbType, this.entityType) as Type<T> || this.entityType;
    
    return this.adapter.queryMany<T>(dbEntityType, criteria);
  }
  
  /**
   * Find a single entity matching criteria
   * @param criteria Query criteria
   * @returns Promise resolving to entity or null
   */
  async findOne(criteria: object): Promise<T | null> {
    // Get the database-specific entity if it exists
    const dbType = this.adapter.type;
    const dbEntityType = this.adapterRegistry.getAdapterEntity(dbType, this.entityType) as Type<T> || this.entityType;
    
    return this.adapter.query<T>(dbEntityType, criteria);
  }
  
  /**
   * Save an entity
   * @param entity The entity to save
   * @returns Promise resolving when save is complete
   */
  async save(entity: T): Promise<void> {
    return this.adapter.save<T>(entity);
  }
  
  /**
   * Delete an entity by its ID
   * @param id The entity ID
   * @returns Promise resolving when delete is complete
   */
  async delete(id: string | number): Promise<void> {
    // Get the database-specific entity if it exists
    const dbType = this.adapter.type;
    const dbEntityType = this.adapterRegistry.getAdapterEntity(dbType, this.entityType) as Type<T> || this.entityType;
    
    return this.adapter.delete<T>(dbEntityType, id);
  }
  
  /**
   * Execute a native query specific to the current database
   * @param query The native query string
   * @param params Parameters for the query
   * @returns Promise resolving to query results
   */
  async runNativeQuery<R>(query: string, params?: any): Promise<R> {
    return this.adapter.runNativeQuery<R>(query, params);
  }
}