UNPKG

tspace-mysql

Version:

Tspace MySQL is a promise-based ORM for Node.js, designed with modern TypeScript and providing type safety for schema databases.

187 lines 6.85 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.PostgresDriver = void 0; const __1 = require(".."); const PostgresQueryBuilder_1 = require("./PostgresQueryBuilder"); class PostgresDriver extends __1.BaseDriver { constructor(options) { super(); this.options = options; } connect() { const options = this.options; const pg = this.import("pg"); const BIGINT_OID = 20; const NUMERIC_OID = 1700; pg.types.setTypeParser(BIGINT_OID, (val) => parseInt(val, 10)); pg.types.setTypeParser(NUMERIC_OID, (v) => { return v === null ? null : parseFloat(v); }); this.pool = new pg.Pool({ host: options.host, port: options.port, database: options.database, user: options.user || options.username, password: options.password, max: options.connectionLimit ?? 20, min: Math.max(2, Math.floor((options.connectionLimit ?? 20) / 3)), connectionTimeoutMillis: options.connectTimeout ?? 1000 * 60, keepAlive: true, allowExitOnIdle: false, idleTimeoutMillis: 1000 * 60, statement_timeout: 1000 * 60, query_timeout: 1000 * 60, }); this.pool.connect((err) => { if (err == null || !err) return; const message = this._messageError.bind(this); process.nextTick(() => { console.log(message(err?.message)); return process.exit(); }); }); return { database: () => this.options.database, on: (event, data) => this.on(event, data), queryBuilder: PostgresQueryBuilder_1.PostgresQueryBuilder, query: (sql) => this._query(sql), connection: () => this._connection(), end: () => this._end() }; } disconnect(pool) { if (pool == null) return; pool?.end(() => { pool = undefined; }); } _query(sql) { const start = Date.now(); return new Promise((resolve, reject) => { return this.pool.query(sql, (err, results) => { if (err) return reject(err); this._detectEventQuery({ start, sql }); this.meta(results, sql); return resolve(this.returning(results)); }); }); } _connection() { let closeTransaction = false; return new Promise((resolve, reject) => { this.pool.connect((err, connection, release) => { if (err) return reject(err); const query = (sql) => { const start = Date.now(); return new Promise((ok, fail) => { if (closeTransaction) { return fail(new Error(this.MESSAGE_TRX_CLOSED)); } connection.query(sql, (err, results) => { if (err) { return fail(err); } this._detectEventQuery({ start, sql }); this.meta(results, sql); return ok(this.returning(results)); }); }); }; const startTransaction = async () => { if (closeTransaction) { throw new Error(this.MESSAGE_TRX_CLOSED); } await query("BEGIN").catch((err) => reject(err)); return; }; const commit = async () => { if (closeTransaction) { throw new Error(this.MESSAGE_TRX_CLOSED); } await query("COMMIT").catch((err) => reject(err)); await end(); return; }; const rollback = async () => { if (closeTransaction) { throw new Error(this.MESSAGE_TRX_CLOSED); } await query("ROLLBACK").catch((err) => reject(err)); await end(); return; }; const end = async () => { await new Promise((resolve) => setTimeout(() => { if (!closeTransaction) { closeTransaction = true; // After commit the transaction, you can't perform any actions with this transaction. release(); // After destroying the connection, it will be removed from the connection this.pool. this.pool.end(); } return resolve(); }, 500)); return; }; return resolve({ on: (event, data) => this.on(event, data), query, queryBuilder: PostgresQueryBuilder_1.PostgresQueryBuilder, startTransaction, commit, rollback, end, }); }); }); } async _end() { return new Promise((resolve, reject) => { return this.pool.end((err) => { if (err) return reject(err); this.pool = undefined; return resolve(); }); }); } meta(results, sql) { if (Array.isArray(results)) return; if (results.$meta == null) results.$meta = {}; const command = this._detectQueryType(sql); results.$meta = { command }; if (command === "INSERT") { const insertIds = (results.rows ?? []).map((v) => v.id); results.$meta = { ...results.$meta, insertIds, affected: true, }; } if (command === "UPDATE" || command === "DELETE") { results.$meta = { ...results.$meta, insertIds: [], affected: Boolean(results.rowCount), }; } } returning(results) { if (["DELETE", "UPDATE", "INSERT"] .some((v) => results?.$meta?.command === v)) { return results; } const { rows } = results; return rows; } } exports.PostgresDriver = PostgresDriver; //# sourceMappingURL=PostgresDriver.js.map