tspace-mysql
Version:
Tspace MySQL is a promise-based ORM for Node.js, designed with modern TypeScript and providing type safety for schema databases.
212 lines • 6.96 kB
JavaScript
;
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);
});
const configs = {
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 = new pg.Pool(configs);
this.poolTrx = new pg.Pool({
...configs,
connectionLimit: configs.max * 1.5
});
this.pool.connect(async (err) => {
if (err == null || !err)
return;
if (err?.message?.includes(`database "${options.database}" does not exist`)) {
const db = new pg.Client({
host: options.host,
port: options.port,
user: options.user || options.username,
password: options.password,
database: "postgres",
});
await db.connect();
const sql = new PostgresQueryBuilder_1.PostgresQueryBuilder({}).createDatabase(options.database);
await db.query(sql);
await db.end();
return;
}
const message = this._messageError.bind(this);
process.nextTick(() => {
console.log(message(err?.message));
if (this.options.CONNECTION_ERROR)
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));
});
});
}
async _connection() {
const conn = await this.poolTrx.connect();
let started = false;
let closed = false;
let commited = false;
let rollbacked = false;
const query = async (sql) => {
const start = Date.now();
const results = await conn.query(sql);
this._detectEventQuery({ start, sql });
this.meta(results, sql);
return this.returning(results);
};
const startTransaction = async () => {
await conn.query('BEGIN');
started = true;
closed = false;
return;
};
const commit = async () => {
if (closed) {
throw new Error(this.MESSAGE_TRX_CLOSED);
}
if (!started) {
throw new Error(this.MESSAGE_TRX_NOT_STARTED);
}
commited = true;
await conn.query('COMMIT');
await end();
return;
};
const rollback = async () => {
if (closed) {
throw new Error(this.MESSAGE_TRX_CLOSED);
}
if (!started) {
throw new Error(this.MESSAGE_TRX_NOT_STARTED);
}
rollbacked = true;
await conn.query('ROLLBACK');
await end();
return;
};
const end = async () => {
if (closed)
return;
if (!started) {
throw new Error(this.MESSAGE_TRX_NOT_STARTED);
}
if (!commited && !rollbacked) {
await rollback();
return;
}
await conn.release();
started = false;
closed = true;
return;
};
const release = async () => {
if (closed)
return;
await conn.release();
return;
};
return {
on: (event, data) => this.on(event, data),
queryBuilder: PostgresQueryBuilder_1.PostgresQueryBuilder,
query,
startTransaction,
commit,
rollback,
end,
release
};
}
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