UNPKG

@smallprod/models

Version:
433 lines (432 loc) 22 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const entitymanager_1 = __importDefault(require("./entitymanager")); const create_query_1 = __importDefault(require("./querys/create.query")); const delete_query_1 = __importDefault(require("./querys/delete.query")); const find_query_1 = __importDefault(require("./querys/find.query")); const update_query_1 = __importDefault(require("./querys/update.query")); class Entity { constructor() { this.persisted = false; this.relations = []; this.create = async (dbName = null, context) => { var _a, _b; const base = this; const query = new create_query_1.default(base.constructor.tableName); const nonPersistentColumns = (_a = base.constructor.nonPersistentColumns) !== null && _a !== void 0 ? _a : []; const primaryKeys = (_b = base.constructor.primaryKeys) !== null && _b !== void 0 ? _b : []; let column; for (column of base.constructor.columns) { if (!primaryKeys.includes(column.key) && !(base[column.key] instanceof Array) && typeof base[column.key] !== 'function') { if (typeof base[column.key] !== 'object' || typeof base[column.key] === null) { query.setAttribute(column.fieldName, base[column.key]); } else if (base[column.key] instanceof Date) { const field = base.constructor.columns.find((f) => f.name === column.name); if (field) { const d = base[column.key]; let formattedD = ''; switch (field.type) { case 'date': { formattedD = `${d.getFullYear()}-${d.getMonth() + 1}-${d.getDate()}`; break; } case 'datetime': { formattedD = `${d.getFullYear()}-${d.getMonth() + 1}-${d.getDate()} ${d.getHours()}:${d.getMinutes()}:${d.getSeconds()}`; break; } case 'timestamp': { formattedD = d.getTime().toString(); break; } case 'time': { formattedD = `${d.getHours()}:${d.getMinutes()}:${d.getSeconds()}`; break; } default: { formattedD = ''; } } if (formattedD) { query.setAttribute(column.fieldName, formattedD); } } } } } const manyToManyQueries = []; base.constructor.relations.forEach((relation) => { if (base[relation.fieldName]) { switch (relation.type) { case 'manytomany': const rel = this.relations.find((r) => r.entity === relation.entity); const relData = rel ? rel.data : []; const relationTable = relation.relationTable; if (relationTable) { base[relation.fieldName].forEach((elem) => { if (elem.persisted && !relData.includes(elem[elem.constructor.id.key])) { const manyToManyQuery = new create_query_1.default(relationTable); const tableName = elem.constructor.tableName; manyToManyQuery.setAttribute(`${tableName.endsWith('s') ? tableName.substr(0, tableName.length - 1) : tableName}_id`, elem[elem.constructor.id.key]); manyToManyQueries.push(manyToManyQuery); } }); } break; case 'manytoone': if (base[relation.fieldName].persisted) { query.setAttribute(`${relation.fieldName}_id`, base[relation.fieldName][base[relation.fieldName].constructor.id.key]); } break; case 'onetomany': break; default: } } }); const res = await query.exec(dbName); if (res) { if (base.constructor.id) { this.persisted = true; base[base.constructor.id.key] = res; entitymanager_1.default.addEntity(this, context); await manyToManyQueries.reduce(async (prev, cur) => { await prev; const tableName = base.constructor.tableName; cur.setAttribute(`${tableName.endsWith('s') ? tableName.substr(0, tableName.length - 1) : tableName}_id`, base[base.constructor.id.key]); await cur.exec(dbName); }, Promise.resolve()); } return this; } return null; }; this.update = async (dbName = null) => { var _a, _b; const base = this; const query = new update_query_1.default(base.constructor.tableName); const nonPersistentColumns = (_a = base.constructor.nonPersistentColumns) !== null && _a !== void 0 ? _a : []; const primaryKeys = (_b = base.constructor.primaryKeys) !== null && _b !== void 0 ? _b : []; let column; for (column of base.constructor.columns) { if (!primaryKeys.includes(column.key) && !(base[column.key] instanceof Array) && typeof base[column.key] !== 'function') { if (typeof base[column.key] !== 'object' || typeof base[column.key] === null) { query.setAttribute(column.fieldName, base[column.key]); } else if (base[column.key] instanceof Date) { const field = base.constructor.columns.find((f) => f.key === column.key); if (field) { const d = base[column.key]; let formattedD = ''; switch (field.type) { case 'date': { formattedD = `${d.getFullYear()}-${d.getMonth() + 1}-${d.getDate()}`; break; } case 'datetime': { formattedD = `${d.getFullYear()}-${d.getMonth() + 1}-${d.getDate()} ${d.getHours()}:${d.getMinutes()}:${d.getSeconds()}`; break; } case 'timestamp': { formattedD = d.getTime().toString(); break; } case 'time': { formattedD = `${d.getHours()}:${d.getMinutes()}:${d.getSeconds()}`; break; } default: { formattedD = ''; } } if (formattedD) { query.setAttribute(column.fieldName, formattedD); } } } } } if (base.constructor.id) { query.where(base.constructor.id.fieldName, '=', base[base.constructor.id.key]); } else { throw new Error('No specified id'); } await base.constructor.relations.reduce(async (prev, relation) => { await prev; if (base[relation.fieldName]) { switch (relation.type) { case 'manytomany': { const rel = this.relations.find((r) => r.entity === relation.entity); const relData = rel ? rel.data : []; const relationTable = relation.relationTable; if (relationTable) { const curTableName = base.constructor.tableName; const curTableField = `${curTableName.endsWith('s') ? curTableName.substr(0, curTableName.length - 1) : curTableName}_id`; const removeOldQuery = new delete_query_1.default(relationTable); removeOldQuery.where(curTableField, '=', base[base.constructor.id.key]); await removeOldQuery.exec(dbName); await base[relation.fieldName].reduce(async (previous, elem) => { await previous; if (elem.persisted && !relData.includes(elem[elem.constructor.id.key])) { const tableName = elem.constructor.tableName; const tableField = `${tableName.endsWith('s') ? tableName.substr(0, tableName.length - 1) : tableName}_id`; const manyToManyQuery = new create_query_1.default(relationTable); manyToManyQuery.setAttribute(tableField, elem[elem.constructor.id.key]); manyToManyQuery.setAttribute(curTableField, base[base.constructor.id.key]); await manyToManyQuery.exec(dbName); } }, Promise.resolve()); } break; } case 'manytoone': if (base[relation.fieldName].persisted) { query.setAttribute(`${relation.fieldName}_id`, base[relation.fieldName][base[relation.fieldName].constructor.id.key]); } break; case 'onetomany': break; default: } } }, Promise.resolve()); const res = await query.exec(dbName); if (res) { return this; } return null; }; this.delete = async (dbName = null, context) => { const base = this; const query = new delete_query_1.default(base.constructor.tableName); if (!base.constructor.id) { throw new Error('No id specified'); } await base.constructor.relations.reduce(async (prev, relation) => { await prev; if (relation.type === 'manytomany' && relation.relationTable) { const curTableName = base.constructor.tableName; const curTableField = `${curTableName.endsWith('s') ? curTableName.substr(0, curTableName.length - 1) : curTableName}_id`; const deleteQuery = new delete_query_1.default(relation.relationTable); deleteQuery.where(curTableField, '=', base[base.constructor.id.key]); await deleteQuery.exec(dbName); } }, Promise.resolve()); query.where(base.constructor.id.fieldName, '=', base[base.constructor.id.key]); const res = await query.exec(dbName); if (res) { entitymanager_1.default.removeEntity(this, context); return true; } return false; }; this.fetch = async (field, context, dbName) => { var _a; const base = this; const relation = base.constructor.relations.find((r) => r.fieldName === field); if (relation) { const rel = entitymanager_1.default.entities.find((e) => e.tableName === relation.entity); if (rel) { const ent = rel.entity; switch (relation.type) { case 'manytomany': { const relationTable = relation.relationTable; if (relationTable) { const tableName = base.constructor.tableName; const relations = await new find_query_1.default(relationTable) .where(`${tableName.endsWith('s') ? tableName.substr(0, tableName.length - 1) : tableName}_id`, '=', base[base.constructor.id.key]) .exec(dbName); if (relations && relations.length) { this.relations.push({ entity: relation.entity, data: relations, }); base[relation.fieldName] = await ent .findMany(context, dbName) .where(((_a = ent.id) === null || _a === void 0 ? void 0 : _a.fieldName) || '', 'IN', relations.map((r) => r[`${ent.tableName.endsWith('s') ? ent.tableName.substr(0, ent.tableName.length - 1) : ent.tableName}_id`])) .exec(dbName); } else { base[field] = []; } } break; } case 'manytoone': { if (base[`${relation.entity}_id`]) { base[field] = await ent.findById(base[`${relation.entity}_id`], context, dbName); } break; } case 'onetomany': { base[field] = await ent .findMany(context, dbName) .where(`${base.constructor.tableName}_id`, '=', base[base.constructor.id.key]) .exec(dbName); break; } default: } } } }; } static findOne(context) { const query = new find_query_1.default(this.tableName, async (res) => { if (res.length) { return await this.generateEntity(res[0], context); } return null; }, this.dbName); query.limit(1); return query; } static findMany(context, dbName) { const query = new find_query_1.default(this.tableName, async (res) => { const result = []; await res.reduce(async (prev, r) => { await prev; result.push(await this.generateEntity(r, context, dbName)); }, Promise.resolve()); return result; }, this.dbName); return query; } static async findById(id, context, dbName) { if (!this.id) throw new Error('No id specified'); const entity = entitymanager_1.default.findEntity(this.tableName, id); if (entity) return entity; const query = new find_query_1.default(this.tableName); query.where(this.id.fieldName, '=', id); const res = await query.exec(dbName); if (res.length) { return await this.generateEntity(res[0], context, dbName); } return null; } static async deleteById(id, context, dbName) { const query = new delete_query_1.default(this.tableName); if (!this.id) throw new Error('No id specified'); query.where(this.id.fieldName, '=', id); const res = await query.exec(dbName); if (res) { const entity = entitymanager_1.default.findEntity(this.tableName, id, context); if (entity) entitymanager_1.default.removeEntity(entity, context); } return res; } static async generateEntity(res, context, dbName) { const newObj = this.create(); newObj.persisted = true; for (const [key, value] of Object.entries(res)) { const field = this.columns.find((f) => f.fieldName === key); if (field) { switch (field.type) { case 'date': case 'datetime': case 'timestamp': case 'time': newObj[field.key] = new Date(value); break; default: newObj[field.key] = value; } } else { newObj[key] = value; } } const entity = entitymanager_1.default.findEntity(newObj.constructor.tableName, newObj[newObj.constructor.id.key], context); if (entity) { return entity; } entitymanager_1.default.addEntity(newObj, context); await this.relations.reduce(async (prev, cur) => { var _a, _b, _c; await prev; if (cur.autoFetch) { const relationEntity = entitymanager_1.default.entities.find((e) => e.tableName === cur.entity); if (relationEntity) { const ent = relationEntity.entity; switch (cur.type) { case 'manytomany': { const relationTable = cur.relationTable; if (relationTable) { const relations = await new find_query_1.default(relationTable) .where(`${this.tableName.endsWith('s') ? this.tableName.substr(0, this.tableName.length - 1) : this.tableName}_id`, '=', res[((_a = this.id) === null || _a === void 0 ? void 0 : _a.fieldName) || '']) .exec(dbName); if (relations && relations.length) { newObj.relations.push({ entity: cur.entity, data: relations, }); newObj[cur.fieldName] = await ent .findMany(context, dbName) .where(((_b = ent.id) === null || _b === void 0 ? void 0 : _b.fieldName) || '', 'IN', relations.map((r) => r[`${ent.tableName.endsWith('s') ? ent.tableName.substr(0, ent.tableName.length - 1) : ent.tableName}_id`])) .exec(dbName); } else { newObj[cur.fieldName] = []; } } break; } case 'manytoone': { if (res[`${cur.fieldName}_id`]) { newObj[cur.fieldName] = await ent.findById(res[`${cur.fieldName}_id`], context, dbName); } break; } case 'onetomany': { newObj[cur.fieldName] = await ent .findMany(context) .where(`${this.tableName}_id`, '=', res[((_c = this.id) === null || _c === void 0 ? void 0 : _c.fieldName) || '']) .exec(dbName); break; } default: } } } }, Promise.resolve()); return newObj; } } exports.default = Entity; Entity.initialized = false; Entity.create = () => { };