UNPKG

slim-ef

Version:

An implementation of basic entity framework functionnalities in typescript

226 lines 8.46 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DbSet = exports.UnderlyingType = void 0; const base_specification_1 = require("../specification/base.specification"); const specification_interface_1 = require("../specification/specification.interface"); const utilis_1 = require("./utilis"); const repository_decorator_1 = require("./repository.decorator"); const exception_1 = require("./exception"); exports.UnderlyingType = Symbol('__UnderlyingType'); class DbSet { constructor(context) { this.context = context; this._queryTypeToExecute = specification_interface_1.QueryType.ALL; this._baseSpec = new base_specification_1.BaseSpecification(); } get [exports.UnderlyingType]() { if (!this._underlyingType) { this._underlyingType = repository_decorator_1.getEntitySchema(this); } return this._underlyingType; } set [exports.UnderlyingType](value) { if (value) { this._underlyingType = value; } } add(...entities) { return this.context.add(...utilis_1.patchM(this[exports.UnderlyingType])(...entities)); } update(...entities) { return this.context.update(...utilis_1.patchM(this[exports.UnderlyingType])(...entities)); } unTrack(...entities) { return this.context.unTrack(...utilis_1.patchM(this[exports.UnderlyingType])(...entities)); } remove(...entities) { return this.context.remove(...utilis_1.patchM(this[exports.UnderlyingType])(...entities)); } async find(id) { return await this.context.find(this[exports.UnderlyingType], id); } async exists(id) { return !!(await this.find(id)); } loadRelatedData(entity) { return this.context.loadRelatedData(this._underlyingType, entity); } async firstOrDefault(predicate, context) { this._baseSpec.applyPaging(0, 1); this.where(predicate, context); return await this.execute(specification_interface_1.QueryType.ONE); } async first(func, context) { const elt = await this.firstOrDefault(func, context); if (!elt) throw new exception_1.EmptySetException(); return elt; } include(navigationPropertyPath) { this._lastInclude = navigationPropertyPath; this._baseSpec.addInclude(navigationPropertyPath); return this; } thenInclude(navigationPropertyPath) { this._baseSpec.addChainedInclude(this._lastInclude, navigationPropertyPath); return this; } where(predicate, context) { this._baseSpec.addCriteria(predicate, context); return this; } take(count) { this._baseSpec.applyPaging(this._currentSkip, count); this._currentTake = count; return this; } skip(count) { this._baseSpec.applyPaging(count, this._currentTake); this._currentSkip = count; return this; } select(selector) { const thisType = this[exports.UnderlyingType]; const includePaths = this._getIncludePaths(); this._onGoingPromise = this.context .getMetadata(thisType, includePaths) .then(proxyInstance => { const res = selector(proxyInstance); const fieldsToSelect = this._extractKeyFields(res); const s = { builder: selector, fieldsToSelect }; this._baseSpec.applySelector(s); return true; }) .catch(rej => { if (rej.message && rej.message.includes('Cannot read property') && rej.message.includes('of undefined')) { throw new Error('Select proxy cannot be build. You may have forget to include some properties using `.include` or `.thenInclude` or may be the selected property is not part of the entity schema. Internal Error: ' + rej.message); } else { throw new Error(rej); } }); return this; } _getIncludePaths() { const spec = this.asSpecification(); return spec.getIncludePaths(); } _extractKeyFields(res) { const fieldsToSelect = []; for (const k in res) { if (k !== '$$propertyName' && Object.prototype.hasOwnProperty.call(res, k)) { const element = res[k]; if (!element) continue; if (!Array.isArray(element)) { const canGrind = !(element instanceof String) && !(element instanceof Number) && !(element instanceof Boolean) && element instanceof Object; if (canGrind) { fieldsToSelect.push(...this._extractKeyFields(element).map(e => ({ field: `${e.field}` }))); } else if (element.$$propertyName) { fieldsToSelect.push({ field: element.$$propertyName }); } } else { const arrElt = element[0]; fieldsToSelect.push(...this._extractKeyFields(arrElt).map(e => ({ field: `${e.field}` }))); } } } return fieldsToSelect; } async count(predicate) { this._baseSpec.addCriteria(predicate); this._baseSpec.applyFunction('COUNT', null); return Number.parseFloat((await this.execute(specification_interface_1.QueryType.RAW_ONE)).COUNT); } async sum(selector) { this._baseSpec.applyFunction('SUM', selector); return Number.parseFloat((await this.execute(specification_interface_1.QueryType.RAW_ONE)).SUM); } async average(selector) { this._baseSpec.applyFunction('AVG', selector); return Number.parseFloat((await this.execute(specification_interface_1.QueryType.RAW_ONE)).AVG); } async max(selector) { this._baseSpec.applyFunction('MAX', selector); return (await this.execute(specification_interface_1.QueryType.RAW_ONE)).MAX; } async min(selector) { this._baseSpec.applyFunction('MIN', selector); return (await this.execute(specification_interface_1.QueryType.RAW_ONE)).MIN; } orderBy(keySelector) { this._baseSpec.applyOrderBy(keySelector); return this; } thenOrderBy(keySelector) { this._baseSpec.applyThenOrderBy(keySelector); return this; } groupBy(keySelector) { this._baseSpec.applyGroupBy(keySelector); return this; } thenGroupBy(keySelector) { this._baseSpec.applyThenGroupBy(keySelector); return this; } orderByDescending(keySelector) { this._baseSpec.applyOrderByDescending(keySelector); return this; } asSpecification() { return this._baseSpec; } ignoreQueryFilters() { this._ignoreFilters = true; return this; } distinct() { this._baseSpec.applyDistinct(); return this; } fromSpecification(spec) { this._baseSpec.extend(spec); this._baseSpec.applySelector(spec.getSelector()); this._baseSpec.applyOrderBy(spec.getOrderBy()); this._baseSpec.applyOrderByDescending(spec.getOrderByDescending()); return this; } toList() { return this.execute(this._queryTypeToExecute); } async execute(type) { try { if (!this._onGoingPromise || (await this._onGoingPromise)) { const res = await this.context.execute(this, type, this._ignoreFilters); this._baseSpec.clearSpecs(); return res; } } catch (err) { // wrapping this in finally, to clear specs on failure or success this._baseSpec.clearSpecs(); throw err; } } } exports.DbSet = DbSet; //# sourceMappingURL=db-set.js.map