import { FilterQuery, ObjectID } from 'mongodb'; import { DatabaseDriver } from './DatabaseDriver'; import { MongoConnection } from '../connections/MongoConnection'; import { EntityData, IEntityType, IPrimaryKey } from '../decorators'; import { QueryOrder } from '../query'; import { Utils } from '../utils'; import { MongoPlatform } from '../platforms/MongoPlatform'; import { QueryResult } from '../connections'; export class MongoDriver extends DatabaseDriver { protected readonly connection = new MongoConnection(this.config); protected readonly platform = new MongoPlatform(); async find>(entityName: string, where: FilterQuery, populate: string[], orderBy: Record, limit: number, offset: number): Promise { where = this.renameFields(entityName, where); const res = await this.connection.find(this.getCollectionName(entityName), where, orderBy, limit, offset); return res.map((r: T) => this.mapResult(r, this.metadata[entityName])); } async findOne>(entityName: string, where: FilterQuery | IPrimaryKey, populate: string[] = [], orderBy: Record = {}): Promise { if (Utils.isPrimaryKey(where)) { where = { _id: new ObjectID(where as string) }; } where = this.renameFields(entityName, where) as FilterQuery; const res = await this.connection.find(this.getCollectionName(entityName), where, orderBy, 1); return this.mapResult(res[0], this.metadata[entityName]); } async count>(entityName: string, where: FilterQuery): Promise { where = this.renameFields(entityName, where); return this.connection.countDocuments(this.getCollectionName(entityName), where); } async nativeInsert>(entityName: string, data: EntityData): Promise { data = this.renameFields(entityName, data); return this.connection.insertOne>(this.getCollectionName(entityName), data); } async nativeUpdate>(entityName: string, where: FilterQuery | IPrimaryKey, data: EntityData): Promise { if (Utils.isPrimaryKey(where)) { where = { _id: new ObjectID(where as string) }; } where = this.renameFields(entityName, where) as FilterQuery; data = this.renameFields(entityName, data); return this.connection.updateMany(this.getCollectionName(entityName), where, data); } async nativeDelete>(entityName: string, where: FilterQuery | IPrimaryKey): Promise { if (Utils.isPrimaryKey(where)) { where = { _id: new ObjectID(where as string) }; } where = this.renameFields(entityName, where) as FilterQuery; return this.connection.deleteMany(this.getCollectionName(entityName), where); } async aggregate(entityName: string, pipeline: any[]): Promise { return this.connection.aggregate(this.getCollectionName(entityName), pipeline); } private renameFields(entityName: string, data: any): any { data = Object.assign({}, data); // copy first Utils.renameKey(data, 'id', '_id'); const meta = this.metadata[entityName]; Object.keys(data).forEach(k => { if (meta && meta.properties[k]) { const prop = meta.properties[k]; if (prop.fieldName) { Utils.renameKey(data, k, prop.fieldName); } } }); return data; } private getCollectionName(entityName: string): string { return this.metadata[entityName] ? this.metadata[entityName].collection : entityName; } }