UNPKG

lupdo

Version:

Database Abstraction Layer for Node js

168 lines (167 loc) 5.04 kB
import PdoError from '../errors/pdo-error'; export class PdoRawConnection { constructor(pool) { this.pool = pool; this.attributes = {}; this.connection = null; this.inTransaction = false; this.statements = new Map(); } async beginTransaction() { try { await this.doBeginTransaction(await this.generateConnection()); this.inTransaction = true; } catch (error) { await this.release(); throw new PdoError(error); } } async commit() { try { await this.doCommit(this.connection); } catch (error) { throw new PdoError(error); } finally { await this.release(); } } async rollback() { try { await this.doRollback(this.connection); } catch (error) { throw new PdoError(error); } finally { await this.release(); } } async prepare(sql) { try { return await this.generateStatement(sql); } catch (error) { if (!this.inTransaction) { await this.release(); } throw new PdoError(error); } } bindValue(value) { if (Array.isArray(value)) { const values = []; for (const val of value) { values.push(this.adaptBindValue(val)); } return values; } return this.adaptBindValue(value); } async execute(sql, params) { try { const connection = await this.generateOrReuseConnection(); const [sqlProcessed, affectingResults, selectResults, columns] = await this.executeStatement(this.statements.get(sql), params === null ? [] : params, connection); if (connection.__lupdo_killed) { throw new Error('Data are compromised'); } return [sqlProcessed, affectingResults, selectResults, columns]; } catch (error) { throw new PdoError(error); } } async exec(sql) { try { const connection = await this.generateOrReuseConnection(); const affecting = await this.doExec(connection, sql); if (connection.__lupdo_killed) { throw new Error('Data are compromised'); } if (!this.inTransaction) { await this.release(); } return affecting.affectedRows ?? 0; } catch (error) { throw new PdoError(error); } finally { if (!this.inTransaction) { await this.release(); } } } async query(sql) { try { const connection = await this.generateOrReuseConnection(); const [affectingResults, selectResults, columns] = await this.doQuery(connection, sql); if (connection.__lupdo_killed) { throw new Error('Data are compromised'); } if (!this.inTransaction) { await this.release(); } return [affectingResults, selectResults, columns]; } catch (error) { throw new PdoError(error); } finally { if (!this.inTransaction) { await this.release(); } } } async lastInsertId({ affectingResults, }) { if (typeof affectingResults.lastInsertRowid === 'undefined') { return null; } return affectingResults.lastInsertRowid; } async close() { await this.release(); } getAttribute(attribute) { return this.attributes[attribute]; } setAttribute(attribute, value) { if (attribute in this.attributes) { this.attributes[attribute] = value; return true; } return false; } setAttributes(attributes) { this.attributes = { ...attributes }; } async release() { if (this.connection !== null) { for (const statement of this.statements.values()) { await this.closeStatement(statement, this.connection); } this.statements.clear(); this.pool.release(this.connection); this.connection = null; } } async generateStatement(sql) { if (!this.statements.has(sql)) { this.statements.set(sql, await this.getStatement(sql, await this.generateOrReuseConnection())); } return this.statements.get(sql); } async generateOrReuseConnection() { if (this.connection === null) { return await this.generateConnection(); } return this.connection; } async generateConnection() { this.connection = await this.pool.acquire().promise; return this.connection; } } export default PdoRawConnection;