UNPKG

firebird-orm

Version:
263 lines (262 loc) 10.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Repository = void 0; const decorators_1 = require("./decorators"); class Repository { constructor(pool, entity) { this.pool = pool; this.entity = entity; this.metadata = Reflect.getMetadata(decorators_1.ENTITY_METADATA_KEY, entity); } getColumnName(propertyKey) { const columns = Reflect.getMetadata(decorators_1.COLUMN_METADATA_KEY, this.entity) || []; const primaryColumns = Reflect.getMetadata(decorators_1.PRIMARY_COLUMN_METADATA_KEY, this.entity) || []; const allColumns = [...columns, ...primaryColumns]; const column = allColumns.find(col => col.propertyKey === propertyKey); return (column === null || column === void 0 ? void 0 : column.name) || propertyKey.toString(); } async getNextId() { return new Promise((resolve, reject) => { const tableName = this.metadata.name; const sql = `SELECT GEN_ID(GEN_${tableName}_ID, 1) AS ID FROM RDB$DATABASE`; this.pool.get((err, db) => { if (err) { reject(err); return; } db.query(sql, [], (err, result) => { db.detach(); if (err) { reject(err); return; } resolve(result[0].ID); }); }); }); } buildWhereClause(where) { const conditions = []; const params = []; Object.entries(where).forEach(([key, value]) => { const columnName = this.getColumnName(key); conditions.push(`${columnName} = ?`); params.push(value); }); return { sql: conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '', params }; } buildOrderByClause(orderBy) { const orders = []; Object.entries(orderBy).forEach(([key, direction]) => { const columnName = this.getColumnName(key); orders.push(`${columnName} ${direction}`); }); return orders.length > 0 ? `ORDER BY ${orders.join(', ')}` : ''; } mapResultToEntity(result) { const entity = new this.entity(); const columns = Reflect.getMetadata(decorators_1.COLUMN_METADATA_KEY, this.entity) || []; const primaryColumns = Reflect.getMetadata(decorators_1.PRIMARY_COLUMN_METADATA_KEY, this.entity) || []; const allColumns = [...columns, ...primaryColumns]; allColumns.forEach(column => { const columnName = column.name.toLowerCase(); const resultKey = Object.keys(result).find(key => key.toLowerCase() === columnName); if (resultKey) { entity[column.propertyKey] = result[resultKey]; } }); return entity; } async findOne(id) { return new Promise((resolve, reject) => { const primaryColumns = Reflect.getMetadata(decorators_1.PRIMARY_COLUMN_METADATA_KEY, this.entity) || []; if (!primaryColumns.length) { reject(new Error('No primary key defined')); return; } const primaryColumn = primaryColumns[0]; const tableName = this.metadata.name; const sql = `SELECT * FROM ${tableName} WHERE ${primaryColumn.name} = ?`; this.pool.get((err, db) => { if (err) { reject(err); return; } db.query(sql, [id], (err, result) => { db.detach(); if (err) { reject(err); return; } if (!result || result.length === 0) { resolve(null); return; } resolve(this.mapResultToEntity(result[0])); }); }); }); } async find(options) { return new Promise((resolve, reject) => { const tableName = this.metadata.name; const whereClause = (options === null || options === void 0 ? void 0 : options.where) ? this.buildWhereClause(options.where) : { sql: '', params: [] }; const orderByClause = (options === null || options === void 0 ? void 0 : options.orderBy) ? this.buildOrderByClause(options.orderBy) : ''; const limitClause = (options === null || options === void 0 ? void 0 : options.limit) ? `ROWS ${options.limit}` : ''; const offsetClause = (options === null || options === void 0 ? void 0 : options.offset) ? `OFFSET ${options.offset}` : ''; const sql = ` SELECT * FROM ${tableName} ${whereClause.sql} ${orderByClause} ${limitClause} ${offsetClause} `.trim().replace(/\s+/g, ' '); this.pool.get((err, db) => { if (err) { reject(err); return; } db.query(sql, whereClause.params, (err, result) => { db.detach(); if (err) { reject(err); return; } if (!result) { resolve([]); return; } resolve(result.map(row => this.mapResultToEntity(row))); }); }); }); } async save(entity) { return new Promise(async (resolve, reject) => { const columns = Reflect.getMetadata(decorators_1.COLUMN_METADATA_KEY, this.entity) || []; const primaryColumns = Reflect.getMetadata(decorators_1.PRIMARY_COLUMN_METADATA_KEY, this.entity) || []; const tableName = this.metadata.name; try { // Se não tem ID e tem coluna primária, gera o próximo ID if (primaryColumns.length) { const primaryColumn = primaryColumns[0]; const id = entity[primaryColumn.propertyKey]; if (!id) { const nextId = await this.getNextId(); entity[primaryColumn.propertyKey] = nextId; } } // Incluir TODAS as colunas (normais + primárias) const allColumns = [...columns, ...primaryColumns]; const columnNames = allColumns.map((col) => col.name).join(', '); const placeholders = allColumns.map(() => '?').join(', '); const values = allColumns.map((col) => entity[col.propertyKey]); const sql = `INSERT INTO ${tableName} (${columnNames}) VALUES (${placeholders})`; this.pool.get((err, db) => { if (err) { reject(err); return; } db.query(sql, values, (err) => { db.detach(); if (err) { reject(err); return; } if (primaryColumns.length) { const primaryColumn = primaryColumns[0]; const id = entity[primaryColumn.propertyKey]; this.findOne(id) .then(savedEntity => { if (!savedEntity) { reject(new Error('Failed to save entity')); return; } resolve(savedEntity); }) .catch(reject); } else { resolve(this.mapResultToEntity(entity)); } }); }); } catch (error) { reject(error); } }); } async update(id, entity) { return new Promise((resolve, reject) => { const columns = Reflect.getMetadata(decorators_1.COLUMN_METADATA_KEY, this.entity) || []; const primaryColumns = Reflect.getMetadata(decorators_1.PRIMARY_COLUMN_METADATA_KEY, this.entity) || []; const tableName = this.metadata.name; if (!primaryColumns.length) { reject(new Error('No primary key defined')); return; } const primaryColumn = primaryColumns[0]; const setClause = columns .map((col) => `${col.name} = ?`) .join(', '); const values = [ ...columns.map((col) => entity[col.propertyKey]), id ]; const sql = `UPDATE ${tableName} SET ${setClause} WHERE ${primaryColumn.name} = ?`; this.pool.get((err, db) => { if (err) { reject(err); return; } db.query(sql, values, (err) => { db.detach(); if (err) { reject(err); return; } this.findOne(id) .then(updatedEntity => { if (!updatedEntity) { reject(new Error('Failed to update entity')); return; } resolve(updatedEntity); }) .catch(reject); }); }); }); } async delete(id) { return new Promise((resolve, reject) => { const primaryColumns = Reflect.getMetadata(decorators_1.PRIMARY_COLUMN_METADATA_KEY, this.entity) || []; const tableName = this.metadata.name; if (!primaryColumns.length) { reject(new Error('No primary key defined')); return; } const primaryColumn = primaryColumns[0]; const sql = `DELETE FROM ${tableName} WHERE ${primaryColumn.name} = ?`; this.pool.get((err, db) => { if (err) { reject(err); return; } db.query(sql, [id], (err) => { db.detach(); if (err) { reject(err); return; } resolve(); }); }); }); } } exports.Repository = Repository;