@kwaeri/postgresql-database-driver
Version:
The @kwaeri/postgresql-database-driver component of the @kwaer/node-kit application platform.
162 lines • 6.49 kB
JavaScript
/**
* SPDX-PackageName: kwaeri/postgresql-database-driver
* SPDX-PackageVersion: 0.5.0
* SPDX-FileCopyrightText: © 2014 - 2022 Richard Winters <kirvedx@gmail.com> and contributors
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception OR MIT
*/
;
// INCLUDES
//import * as postgresql from 'pg';
import Postgres from 'pg';
import { DatabaseDriver } from '@kwaeri/database-driver'; // You'll need this line and the method definitions below
// to create a new driver type...like for postgresql
import debug from 'debug';
// DEFINES
const DEBUG = debug('nodekit:postgresql-database-driver');
/**
* The PostgreSQLDriver implements the PostgreSQL database provider
*/
export class PostgreSQLDriver extends DatabaseDriver {
/**
* @var { Postgres./Pool } pool
*/
pool;
/**
* Class constructor
*/
constructor(config) {
// Prepare a default port value for postgresql
if (!config.port)
config.port = 5432;
// Do the same for type
if (!config.type)
config.type = 'postgres';
super(config);
DEBUG(`Create connection pool`);
this.pool = new Postgres.Pool({
host: this.connection.host,
port: this.connection.port,
database: this.connection.database,
user: this.connection.user,
password: this.connection.password
});
}
/**
* Executes a transaction [checkout, use, return] query on a pooled client, using the postgres
* database driver.
*
* @param { string } query The query string to be executed, with optional placeholders (i.e. $1, $2, $3 ... )
* @param { any[] } bits An array of parameter placeholders (i.e. [1, "Richard"].)
*
* @return { Promise<QueryResult> } A promise for a {@link QueryResult} object.
*
* **Example**:
*
* ```typescript
* const { rows, fields } = await query( 'select * from people where first_name=$1;', ["Richard"]);
* ```
*
* Though, if you're not using parameters, the bits argument is entirely optional and can be left out.
*
* See the [official documentation](https://node-postgres.com/features/pooling)
*/
async clientQuery(query, bits) {
try {
let results;
DEBUG(`Get client from connection pool`);
const pooledClient = await this.pool.connect();
try {
if (bits && bits.length)
DEBUG(`New PostgreSQL 'query' with query string: '${query}', and bits: '${bits.join(`', '`)}'`);
else
DEBUG(`New PostgreSQL 'query' with query string: '${query}'`);
// Execute the query:
const { command, rowCount, oid, rowAsArray, rows, fields } = (bits && bits.length) ?
await pooledClient.query(query, bits) :
await pooledClient.query(query);
// Monkey punch some stuff into the rows object, so it mocks the mysql implementation:
rows.command = (command) ? command : null;
rows.affectedRows = (rowCount) ? rowCount : null;
rows.oid = (oid) ? oid : null;
rows.rowAsArray = (rowAsArray) ? rowAsArray : false;
DEBUG(`Query returned 'fields' with:`);
DEBUG(`'${fields}'`);
DEBUG(`Query returned 'rows' with:`);
DEBUG(`'${rows}'`);
results = { rows, fields };
}
finally {
DEBUG(`Return client to connection pool`);
pooledClient.release();
// Return a promise resolution:
return Promise.resolve({ ...results });
}
}
catch (error) {
return Promise.reject(error);
}
}
/**
* Executes a standard [the preferred way to] query on any available client in the pool, using the postgres
* database driver.
*
* @param { string } query The query string to be executed, with optional placeholders (i.e. $1, $2, $3 ... )
* @param { any[] } bits An array of parameter placeholders (i.e. [1, "Richard"].)
*
* @return { Promise<QueryResult> } A promise for a {@link QueryResult} object.
*
* **Example**:
*
* ```typescript
* const { rows, fields } = await query( 'select * from people where first_name=$1;', ["Richard"]);
* ```
*
* Though, if you're not using parameters, the bits argument is entirely optional and can be left out.
*
* See the [official documentation](https://node-postgres.com/features/pooling)
*/
async query(query, bits) {
try {
if (bits && bits.length)
DEBUG(`New PostgreSQL 'query' with query string: '${query}', and bits: '${bits.join(`', '`)}'`);
else
DEBUG(`New PostgreSQL 'query' with query string: '${query}'`);
// Execute the query:
const { command, rowCount, oid, rowAsArray, rows, fields } = (bits && bits.length) ?
await this.pool.query(query, bits) :
await this.pool.query(query);
// Monkey punch some stuff into the rows object, so it mocks the mysql implementation:
rows.command = (command) ? command : null;
rows.affectedRows = (rowCount) ? rowCount : null;
rows.oid = (oid) ? oid : null;
rows.rowAsArray = (rowAsArray) ? rowAsArray : false;
DEBUG(`Query returned 'fields' with:`);
DEBUG(`'${fields}'`);
DEBUG(`Query returned 'rows' with:`);
DEBUG(`'${rows}'`);
// Return a promise resolution:
return Promise.resolve({ rows, fields });
}
catch (error) {
return Promise.reject(error);
}
}
/**
* When using the PostgreSQL database driver, one should call end on the connection pool
* after the pool has been used.
*
* @returns { undefined } `undefined` on success
*/
async destroyPool() {
try {
DEBUG(`Calling end on client connetion pool`);
const finished = await this.pool.end();
}
catch (error) {
DEBUG(`Error: ${error}`);
return Promise.reject(`${error}`);
}
return Promise.resolve(undefined);
}
}
//# sourceMappingURL=postgresql-database-driver.mjs.map