import { IEntity } from '@antjs/ant-js/src/model/IEntity'; import * as Knex from 'knex'; import { IAntSqlModel } from '../../model/IAntSqlModel'; import { ISqlSecondaryEntityManager } from './ISqlSecondaryEntityManager'; import { SecondaryEntityManagerHelper } from './SecondayEntityManagerHelper'; export class AntSqlSecondaryEntityManager implements ISqlSecondaryEntityManager { /** * Secondary entity manager helper. */ protected _helper: SecondaryEntityManagerHelper; /** * Model to manage. */ protected _model: IAntSqlModel; /** * Query Builder. */ protected _dbConnection: Knex; /** * Creates a new SQL secondary manager. * @param model Model to manage. * @param dbConnection SQL knex connection. */ public constructor( model: IAntSqlModel, dbConnection: Knex, ) { this._dbConnection = dbConnection; this._helper = new SecondaryEntityManagerHelper(model, dbConnection); this._model = model; } /** * Model to manage. */ public get model(): IAntSqlModel { return this._model; } /** * Deletes an entity from its id. * @param id Id of the entity to delete. * @returns Promise of entity deleted. */ public delete(id: string | number): Promise { return this ._dbConnection .from(this.model.tableName) .where(this.model.id, id) .del(); } /** * Gets an entity by its id. * @param id Id of the entity. * @returns Entity found */ public getById(id: string | number): Promise { return new Promise((resolve, reject) => { this ._dbConnection .from(this.model.tableName) .where(this.model.id, id) .then((results: any[]) => { if (0 === results.length) { resolve(null); } else { resolve(results[0]); } }).catch(reject); }); } /** * Finds a collection of entities by its ids. * @param ids Ids of the entities to find. * @returns Entities found. */ public getByIds(ids: number[] | string[]): Promise { return new Promise((resolve, reject) => { this ._dbConnection .from(this.model.tableName) .whereIn(this.model.id, ids) .then(resolve) .catch(reject); }); } /** * Gets a collection of models by its ids ordered by id asc. * @param ids Model ids. * @returns Models found. */ public getByIdsOrderedAsc(ids: number[]| string[]): Promise { const ascOrder = 'ASC'; return new Promise((resolve, reject) => { this ._dbConnection .from(this.model.tableName) .whereIn(this.model.id, ids) .orderBy(this.model.id, ascOrder) .then(resolve) .catch(reject); }); } /** * Inserts an entity. * @param entity Entity to be inserted. * @returns Promise of entity inserted. */ public insert(entity: TEntity): Promise { let insertionPromise: Promise = this ._dbConnection .insert([this._helper.buildKnexObject(this.model, entity)]) .into(this.model.tableName); const autoGeneratedColumn = this.model.getAutoGeneratedColumn(); if (null !== autoGeneratedColumn) { insertionPromise = (insertionPromise as Knex.QueryBuilder) .returning(autoGeneratedColumn.sqlName) .then((value: any[]) => { (entity as IEntity)[autoGeneratedColumn.entityAlias] = value[0]; }); } return insertionPromise; } /** * Deletes entitis from their ids. * @param ids Id of the entity to delete. * @returns Promise of entities deleted. */ public mDelete(ids: string[] | number[]): Promise { if (0 === ids.length) { return new Promise((resolve) => resolve()); } return this ._dbConnection .from(this.model.tableName) .whereIn(this.model.id, ids) .del(); } /** * Inserts multiple entities. * @param entities Entities to be inserted. * @returns Promise of entities inserted. */ public mInsert(entities: TEntity[]): Promise { if (0 === entities.length) { return new Promise((resolve) => resolve()); } let insertionPromise: Promise = this ._dbConnection .insert(entities.map( (entity) => this._helper.buildKnexObject(this.model, entity), )) .into((this.model.tableName)); const autoGeneratedColumn = this.model.getAutoGeneratedColumn(); if (null != autoGeneratedColumn) { insertionPromise = (insertionPromise as Knex.QueryBuilder) .returning(autoGeneratedColumn.sqlName) .then((values: any[]) => { for (let i = 0; i < entities.length; ++i) { if (null != values[i]) { (entities[i] as IEntity)[autoGeneratedColumn.entityAlias] = values[i]; } } }); } return insertionPromise; } /** * Updates multiple entities. * @param entities Entities to be updated. * @returns Promise of entities updated. */ public mUpdate(entities: TEntity[]): Promise { if (0 === entities.length) { return new Promise((resolve) => resolve()); } return this ._dbConnection .transaction((transaction) => { const queries = new Array>(); for (const entity of entities) { queries.push( this ._dbConnection(this.model.tableName) .where(this.model.id, entity[this.model.id]) .update(this._helper.buildKnexObject(this.model, entity)) .transacting(transaction), ); } Promise.all(queries) .then(() => transaction.commit()) .catch(transaction.rollback); }); } /** * Updates an entity. * @param entity Entity to be updated. * @returns Promise of entity deleted. */ public update(entity: TEntity): Promise { return this ._dbConnection(this.model.tableName) .where(this.model.id, entity[this.model.id]) .update(this._helper.buildKnexObject(this.model, entity)); } }