UNPKG

@dazejs/framework

Version:

Daze.js - A powerful web framework for Node.js

359 lines 12.9 kB
"use strict"; var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Repository = void 0; const builder_1 = require("./builder"); const inspect = Symbol.for('nodejs.util.inspect.custom'); class Repository { constructor(model) { this.exists = false; this.updateAttributeColumns = new Set(); this.withs = new Map(); this.needWithTrashed = false; this.needWithSecret = false; this.needAutoTimestap = true; this.model = model; const entity = this.model.createNewEntity(); for (const column of this.model.getColumns().keys()) { if (entity[column] !== undefined) { this[column] = entity[column]; } } return new Proxy(this, this.proxy()); } getColumns() { return this.model.getColumns().keys(); } proxy() { return { set(target, p, value, receiver) { if (target.isExists()) { target.addUpdateAttributeColumn(p); } return Reflect.set(target, p, value, receiver); }, get(target, p, receiver) { const customs = target.model.getCustomColumns(); if (customs.includes(p)) { return Reflect.get(target.model.getOriginEntity().prototype, p, target); } return Reflect.get(target, p, receiver); } }; } isExists() { return this.exists; } setExists(exists = true) { this.exists = exists; return this; } hasUpdatedAttributes() { return !!this.updateAttributeColumns.size; } addUpdateAttributeColumn(key) { if (this.model.getColumns().has(key)) { this.updateAttributeColumns.add(key); } return this; } getUpdatedAttributes() { const attributes = {}; for (const column of this.updateAttributeColumns) { attributes[column] = this[column]; } return attributes; } createQueryBuilder() { const modelBuilder = (new builder_1.ModelBuilder(this.model, this)); return modelBuilder; } getPrimaryValue() { var _a; return (_a = this[this.model.getPrimaryKey()]) !== null && _a !== void 0 ? _a : null; } fill(data) { if (!data) return this; const keys = this.model.getColumns().keys(); for (const key of keys) { this.setAttribute(key, data[key]); } return this; } getAttributes() { const attributes = {}; const columns = this.model.getColumns(); for (const [column, desc] of columns) { if (!desc.secret) { attributes[column] = this[column]; } else { if (this.needWithSecret) { attributes[column] = this[column]; } } } const relationMap = this.model.getRelationMap(); for (const realtion of relationMap.keys()) { const _realtion = this[realtion]; if (_realtion) { if (Array.isArray(_realtion)) { attributes[realtion] = _realtion.map(item => item === null || item === void 0 ? void 0 : item.getAttributes()); } else { attributes[realtion] = _realtion === null || _realtion === void 0 ? void 0 : _realtion.getAttributes(); } } } return attributes; } setAttribute(key, value) { if (value === undefined) return this; this[key] = value; if (this.isExists()) { this.addUpdateAttributeColumn(key); } return this; } getAttribute(key) { if (!key) return; if (this.model.getColumns().has(key) || this.model.getCustomColumns().includes(key) || this.model.getRelationMap().has(key)) return this[key]; } with(relation, callback) { const relationImp = this.model.getRelationImp(relation); if (relationImp) { this.setWith(relation, relationImp, callback); } return this; } withTrashed() { this.needWithTrashed = true; return this; } withSecret() { this.needWithSecret = true; return this; } getWiths() { return this.withs; } setWiths(withs) { this.withs = withs; return this; } setWith(relation, value, queryCallback) { this.withs.set(relation, { relation: value, queryCallback }); return this; } async eagerly(withs, result) { for (const [relation, relationOption] of withs) { const { relation: relationImp, queryCallback } = relationOption; await relationImp.eagerly(result, relation, queryCallback); } } async eagerlyCollection(withs, results) { for (const [relation, relationOption] of withs) { const { relation: relationImp, queryCallback } = relationOption; await relationImp.eagerlyMap(results, relation, queryCallback); } } async delete() { if (!this.model.getPrimaryKey()) { throw new Error('Primary key not defined'); } if (!this.isExists()) return false; await this.executeDelete(); return true; } async executeDelete() { const query = this.createQueryBuilder(); if (this.model.isForceDelete()) { await query.where(this.model.getPrimaryKey(), '=', this.getPrimaryValue()).delete(); this.setExists(false); return true; } const attributes = {}; attributes[this.model.getSoftDeleteKey()] = this.model.getFormatedDate(this.model.getColumnType(this.model.getSoftDeleteKey())); if (this.needAutoTimestap && this.model.hasUpdateTimestamp()) { const updateTimestampKey = this.model.getUpdateTimestampKey(); attributes[updateTimestampKey] = this.model.getFormatedDate(this.model.getColumnType(updateTimestampKey)); } return query.where(this.model.getPrimaryKey(), '=', this.getPrimaryValue()).update(attributes); } async get(id) { const query = this.createQueryBuilder(); if (!this.model.isForceDelete() && !this.needWithTrashed) { if (this.model.getSoftDeleteDefaultValue() === null) { query.whereNull(this.model.getSoftDeleteKey()); } else { query.where(this.model.getSoftDeleteKey(), this.model.getSoftDeleteDefaultValue()); } } return query.where(this.model.getPrimaryKey(), '=', id).first(); } async save() { const query = this.createQueryBuilder(); if (this.isExists()) { if (!this.hasUpdatedAttributes()) return true; if (this.needAutoTimestap && this.model.hasUpdateTimestamp()) { const key = this.model.getUpdateTimestampKey(); const val = this.model.getFreshDateWithColumnKey(key); this[key] = val; } const updatedAttributes = this.getUpdatedAttributes(); return this.executeUpdate(query, updatedAttributes); } else { if (this.needAutoTimestap && this.model.hasCreateTimestamp()) { const key = this.model.getCreateTimestampKey(); const val = this.model.getFreshDateWithColumnKey(key); this[key] = val; } if (this.needAutoTimestap && this.model.hasUpdateTimestamp()) { const key = this.model.getUpdateTimestampKey(); const val = this.model.getFreshDateWithColumnKey(key); this[key] = val; } if (this.model.isIncrementing()) { await this.executeInsertAndSetId(query); } else { if (!this.model.getColumns().size) return true; await query.insert(this.getIntertAttributes()); } this.setExists(true); } return true; } getIntertAttributes() { const attributes = {}; const columns = this.model.getColumns(); for (const [column] of columns) { attributes[column] = this[column]; } return attributes; } async executeInsertAndSetId(query) { const id = await query.insert(this.getIntertAttributes()); this.setAttribute(this.model.getPrimaryKey(), id); return this; } async executeUpdate(query, attributes) { await query.where(this.model.getPrimaryKey(), '=', this.getPrimaryValue()).update(attributes); return true; } async create(attributes) { const repos = this.model.createRepository().setExists(false).fill(attributes); await repos.save(); return repos; } async destroy(...ids) { let count = 0; if (!ids.length) return count; const key = this.model.getPrimaryKey(); const results = await this.createQueryBuilder().whereIn(key, ids).find(); for (const result of results) { if (await result.delete()) { count++; } } return count; } toJSON() { return this.getAttributes(); } [inspect]() { return this.toJSON(); } withoutAutoTimestamp() { this.needAutoTimestap = false; return this; } async attach(relation, ...idsWithDatas) { var _a; if (!this.isExists()) { throw new Error('model does not exists!'); } const relationMap = this.model.getRelationMap(); if (!relationMap.has(relation) || ((_a = relationMap.get(relation)) === null || _a === void 0 ? void 0 : _a.type) !== 'belongsToMany') { throw new Error(`model does not have many to many relation: [${relation}]!`); } const imp = this.model.getRelationImp(relation); const insertData = []; const repos = imp.pivot.createRepository(); for (const item of idsWithDatas) { let _id; let _data = {}; if (typeof item === 'object' && item.id) { const { id } = item, rest = __rest(item, ["id"]); _id = id; _data = Object.assign({}, rest); } else { _id = item; } const data = Object.assign({ [`${imp.foreignPivotKey}`]: this.getPrimaryValue(), [`${imp.relatedPivotKey}`]: _id }, _data); if (this.needAutoTimestap && repos.model.hasCreateTimestamp()) { const key = repos.model.getCreateTimestampKey(); const val = repos.model.getFreshDateWithColumnKey(key); data[key] = val; } if (this.needAutoTimestap && repos.model.hasUpdateTimestamp()) { const key = repos.model.getUpdateTimestampKey(); const val = repos.model.getFreshDateWithColumnKey(key); data[key] = val; } insertData.push(data); } await repos .createQueryBuilder() .getBuilder() .insertAll(insertData); return repos; } async detach(relation, ...ids) { var _a; if (!this.isExists()) { throw new Error('model does not exists!'); } const relationMap = this.model.getRelationMap(); if (!relationMap.has(relation) || ((_a = relationMap.get(relation)) === null || _a === void 0 ? void 0 : _a.type) !== 'belongsToMany') { throw new Error(`model does not have many to many relation: [${relation}]!`); } const imp = this.model.getRelationImp(relation); const repos = imp.pivot.createRepository(); await repos .createQueryBuilder() .getBuilder() .where(imp.foreignPivotKey, '=', this.getPrimaryValue()) .whereIn(imp.relatedPivotKey, ids) .delete(); return repos; } } exports.Repository = Repository; //# sourceMappingURL=repository.js.map