@wearesage/schema
Version:
A flexible schema definition and validation system for TypeScript with multi-database support
94 lines (82 loc) • 3.21 kB
text/typescript
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);
}
}