@juit/pgproxy-pool 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,8 @@
1
+ # PostgreSQL Proxy Connection Pool
2
+
3
+ This package provides low-level connectivity and a connection pool
4
+ implementation to connect to PosgreSQL databases using `libpq`.
5
+
6
+ * [PGProxy](https://github.com/juitnow/juit-pgproxy/blob/main/README.md)
7
+ * [Copyright Notice](https://github.com/juitnow/juit-pgproxy/blob/main/NOTICE.md)
8
+ * [License](https://github.com/juitnow/juit-pgproxy/blob/main/NOTICE.md)
@@ -0,0 +1,309 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // connection.ts
31
+ var connection_exports = {};
32
+ __export(connection_exports, {
33
+ Connection: () => Connection,
34
+ convertOptions: () => convertOptions
35
+ });
36
+ module.exports = __toCommonJS(connection_exports);
37
+ var import_node_assert = __toESM(require("node:assert"));
38
+ var import_node_crypto = require("node:crypto");
39
+ var import_events = require("./events.cjs");
40
+ var import_libpq = require("./libpq.cjs");
41
+ var import_queue = require("./queue.cjs");
42
+ var optionKeys = {
43
+ address: "hostaddr",
44
+ applicationName: "application_name",
45
+ connectTimeout: "connect_timeout",
46
+ database: "dbname",
47
+ gssLibrary: "gsslib",
48
+ host: "host",
49
+ keepalives: "keepalives",
50
+ keepalivesCount: "keepalives_count",
51
+ keepalivesIdle: "keepalives_idle",
52
+ keepalivesInterval: "keepalives_interval",
53
+ kerberosServiceName: "krbsrvname",
54
+ password: "password",
55
+ port: "port",
56
+ sslCertFile: "sslcert",
57
+ sslCompression: "sslcompression",
58
+ sslCrlFile: "sslcrl",
59
+ sslKeyFile: "sslkey",
60
+ sslMode: "sslmode",
61
+ sslRootCertFile: "sslrootcert",
62
+ user: "user"
63
+ };
64
+ function quoteParamValue(value) {
65
+ value = value.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
66
+ return `'${value}'`;
67
+ }
68
+ var finalizer = new FinalizationRegistry(
69
+ /* coverage ignore next */
70
+ (pq) => {
71
+ pq.finish();
72
+ }
73
+ );
74
+ function convertOptions(options) {
75
+ const params = [];
76
+ for (const [option, value] of Object.entries(options)) {
77
+ if (value == null)
78
+ continue;
79
+ const key = optionKeys[option];
80
+ if (!key)
81
+ continue;
82
+ const string = typeof value === "boolean" ? value ? "1" : "0" : typeof value === "number" ? value.toString() : typeof value === "string" ? value : (
83
+ /* coverage ignore next */
84
+ import_node_assert.default.fail(`Invalid type for option ${option}`)
85
+ );
86
+ if (string.length === 0)
87
+ continue;
88
+ params.push(`${key}=${quoteParamValue(string)}`);
89
+ }
90
+ return params.join(" ");
91
+ }
92
+ var Connection = class extends import_events.Emitter {
93
+ /** The unique ID of this connection */
94
+ id;
95
+ /** Queue for serializing queries to the database */
96
+ _queue = new import_queue.Queue();
97
+ /** Option string to use when calling `connect` */
98
+ _options;
99
+ /** Current instance of `libpq` */
100
+ _pq;
101
+ /** A flag indicating that `destroy()` has been invoked... */
102
+ _destroyed = false;
103
+ /* Overloaded constructor */
104
+ constructor(logger, options = {}) {
105
+ super(logger);
106
+ this.id = (0, import_node_crypto.randomUUID)();
107
+ this._logger = logger;
108
+ const params = typeof options === "string" ? options : convertOptions(options);
109
+ this._options = `fallback_application_name='pool:${this.id}' ${params}`;
110
+ this._pq = new import_libpq.LibPQ();
111
+ finalizer.register(this, this._pq, this._pq);
112
+ this.on("error", () => {
113
+ finalizer.unregister(this._pq);
114
+ this._pq.finish();
115
+ this._destroyed = true;
116
+ });
117
+ logger.debug(`Connection "${this.id}" created`);
118
+ }
119
+ /* ===== GETTERS ========================================================== */
120
+ /** Check whether this {@link Connection} is connected or not */
121
+ get connected() {
122
+ return !!this._pq.connected;
123
+ }
124
+ /** Check whether this {@link Connection} is destroyed or not */
125
+ get destroyed() {
126
+ return this._destroyed;
127
+ }
128
+ /** Return the version of the server we're connected to */
129
+ get serverVersion() {
130
+ (0, import_node_assert.default)(this._pq.connected, "Not connected");
131
+ const version = this._pq.serverVersion();
132
+ return `${Math.floor(version / 1e4)}.${version % 1e4}`;
133
+ }
134
+ /* ===== PUBLIC =========================================================== */
135
+ /** Connect this {@link Connection} (fails if connected already) */
136
+ async connect() {
137
+ (0, import_node_assert.default)(!this._pq.connected, `Connection "${this.id}" already connected`);
138
+ (0, import_node_assert.default)(!this._destroyed, `Connection "${this.id}" already destroyed`);
139
+ this._logger.debug(`Connection "${this.id}" connecting`);
140
+ const promise = new Promise((resolve, reject) => {
141
+ this._pq.connect(this._options, (error) => {
142
+ if (error) {
143
+ return reject(new Error(error.message.trim() || "Unknown connection error"));
144
+ }
145
+ if (!this._pq.setNonBlocking(true)) {
146
+ return reject(new Error(`Unable to set connection "${this.id}" as non-blocking`));
147
+ }
148
+ return resolve(this._pq.connected);
149
+ });
150
+ });
151
+ try {
152
+ const connected = await promise;
153
+ if (this._destroyed)
154
+ throw new Error(`Connection "${this.id}" aborted`);
155
+ if (!connected)
156
+ throw new Error(`Connection "${this.id}" not connected`);
157
+ this._logger.info(`Connection "${this.id}" connected (server version ${this.serverVersion})`);
158
+ this._emit("connected");
159
+ return this;
160
+ } catch (error) {
161
+ if (error instanceof Error)
162
+ Error.captureStackTrace(error);
163
+ finalizer.unregister(this._pq);
164
+ this._pq.finish();
165
+ this._destroyed = true;
166
+ this._emit("error", error);
167
+ throw error;
168
+ }
169
+ }
170
+ /** Destroy this {@link Connection} releasing all related resources */
171
+ destroy() {
172
+ if (this._destroyed)
173
+ return;
174
+ finalizer.unregister(this._pq);
175
+ this._pq.finish();
176
+ this._destroyed = true;
177
+ this._emit("destroyed");
178
+ }
179
+ /** ===== QUERY INTERFACE ================================================= */
180
+ /** Execute a (possibly parameterised) query with this {@link Connection} */
181
+ async query(text, params) {
182
+ const promise = this._queue.enqueue(() => {
183
+ (0, import_node_assert.default)(this._pq.connected, `Connection "${this.id}" not connected`);
184
+ return new Query(this._pq, this._logger).on("error", (error) => this._emit("error", error)).run(text, params);
185
+ });
186
+ try {
187
+ return await promise;
188
+ } catch (error) {
189
+ if (error instanceof Error)
190
+ Error.captureStackTrace(error);
191
+ throw error;
192
+ } finally {
193
+ if (!this._pq.connected)
194
+ this.destroy();
195
+ }
196
+ }
197
+ /** Cancel (if possible) the currently running query */
198
+ cancel() {
199
+ (0, import_node_assert.default)(this._pq.connected, `Connection "${this.id}" not connected`);
200
+ const cancel = this._pq.cancel();
201
+ if (cancel === true)
202
+ return;
203
+ throw new Error(cancel || "Unknown error canceling");
204
+ }
205
+ };
206
+ var Query = class extends import_events.Emitter {
207
+ constructor(_pq, logger) {
208
+ super(logger);
209
+ this._pq = _pq;
210
+ }
211
+ /** Run a query, sending it and flushing it, then reading results */
212
+ run(text, params = []) {
213
+ return new Promise((resolve, reject) => {
214
+ const sent = params.length > 0 ? this._pq.sendQueryParams(text, params) : this._pq.sendQuery(text);
215
+ if (!sent)
216
+ throw this._fail("sendQuery", "Unable to send query");
217
+ this._flushQuery((error) => {
218
+ if (error)
219
+ return reject(error);
220
+ const readableCallback = () => this._read(onResult);
221
+ const onResult = (error2) => {
222
+ this._pq.stopReader();
223
+ this._pq.off("readable", readableCallback);
224
+ if (error2) {
225
+ this._pq.clear();
226
+ return reject(error2);
227
+ }
228
+ const result = this._createResult();
229
+ this._pq.clear();
230
+ resolve(result);
231
+ };
232
+ this._pq.on("readable", readableCallback);
233
+ this._pq.startReader();
234
+ });
235
+ });
236
+ }
237
+ /* === ERRORS ============================================================= */
238
+ _fail(syscall, message) {
239
+ const text = (this._pq.errorMessage() || "").trim() || message;
240
+ const error = Object.assign(new Error(`${text} (${syscall})`), { syscall });
241
+ this._pq.finish();
242
+ this._emit("error", error);
243
+ return error;
244
+ }
245
+ /* === INTERNALS ========================================================== */
246
+ _error;
247
+ _flushQuery(cb) {
248
+ const result = this._pq.flush();
249
+ if (result === 0)
250
+ return cb();
251
+ if (result === -1)
252
+ cb(this._fail("flush", "Unable to flush query"));
253
+ this._pq.writable(
254
+ /* coverage ignore next */
255
+ () => this._flushQuery(cb)
256
+ );
257
+ }
258
+ _read(onResult) {
259
+ if (!this._pq.consumeInput()) {
260
+ return onResult(this._fail("consumeInput", "Unable to consume input"));
261
+ }
262
+ if (this._pq.isBusy())
263
+ return;
264
+ while (this._pq.getResult()) {
265
+ const status = this._pq.resultStatus();
266
+ switch (status) {
267
+ case "PGRES_FATAL_ERROR":
268
+ this._error = new Error(`SQL Fatal Error: ${this._pq.resultErrorMessage().trim()}`);
269
+ break;
270
+ case "PGRES_TUPLES_OK":
271
+ case "PGRES_COMMAND_OK":
272
+ case "PGRES_EMPTY_QUERY":
273
+ break;
274
+ default:
275
+ return onResult(this._fail("resultStatus", `Unrecognized status ${status}`));
276
+ }
277
+ if (this._pq.isBusy())
278
+ return;
279
+ }
280
+ onResult(this._error);
281
+ }
282
+ /* === RESULT ============================================================= */
283
+ /** Create a {@link ConnectionQueryResult} from the data currently held by `libpq` */
284
+ _createResult() {
285
+ const command = this._pq.cmdStatus().split(" ")[0];
286
+ const rowCount = parseInt(this._pq.cmdTuples() || "0");
287
+ const nfields = this._pq.nfields();
288
+ const ntuples = this._pq.ntuples();
289
+ const fields = new Array(nfields);
290
+ const rows = new Array(ntuples);
291
+ for (let i = 0; i < nfields; i++) {
292
+ fields[i] = [this._pq.fname(i), this._pq.ftype(i)];
293
+ }
294
+ for (let i = 0; i < ntuples; i++) {
295
+ const row = rows[i] = new Array(nfields);
296
+ for (let j = 0; j < nfields; j++) {
297
+ const value = this._pq.getvalue(i, j);
298
+ row[j] = value === "" && this._pq.getisnull(i, j) ? null : value;
299
+ }
300
+ }
301
+ return { command, rowCount, fields, rows };
302
+ }
303
+ };
304
+ // Annotate the CommonJS export names for ESM import in node:
305
+ 0 && (module.exports = {
306
+ Connection,
307
+ convertOptions
308
+ });
309
+ //# sourceMappingURL=connection.cjs.map
@@ -0,0 +1,6 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/connection.ts"],
4
+ "mappings": "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",
5
+ "names": ["assert", "error"]
6
+ }
@@ -0,0 +1,112 @@
1
+ import { Emitter } from './events';
2
+ import type { Logger } from './index';
3
+ /**
4
+ * Connection options
5
+ *
6
+ * See https://www.postgresql.org/docs/9.3/libpq-connect.html#LIBPQ-PARAMKEYWORDS
7
+ */
8
+ export interface ConnectionOptions {
9
+ /** The database name. */
10
+ database?: string;
11
+ /** Name of host to connect to. */
12
+ host?: string;
13
+ /** IPv4 or IPv6 numeric IP address of host to connect to. */
14
+ address?: string;
15
+ /** Port number to connect to at the server host. */
16
+ port?: number;
17
+ /** PostgreSQL user name to connect as. */
18
+ user?: string;
19
+ /** Password to be used if the server demands password authentication. */
20
+ password?: string;
21
+ /** Maximum wait for connection, in seconds. */
22
+ connectTimeout?: number;
23
+ /** The `application_name` as it will appear in `pg_stat_activity`. */
24
+ applicationName?: string;
25
+ /** Controls whether client-side TCP keepalives are used. */
26
+ keepalives?: boolean;
27
+ /** The number of seconds of inactivity after which TCP should send a keepalive message to the server. */
28
+ keepalivesIdle?: number;
29
+ /** The number of seconds after which a TCP keepalive message that is not acknowledged by the server should be retransmitted. */
30
+ keepalivesInterval?: number;
31
+ /** The number of TCP keepalives that can be lost before the client's connection to the server is considered dead. */
32
+ keepalivesCount?: number;
33
+ /**
34
+ * This option determines whether or with what priority a secure SSL TCP/IP
35
+ * connection will be negotiated with the server. There are six modes:
36
+ * * `disable`: only try a non-SSL connection
37
+ * * `allow`: first try a non-SSL connection; if that fails, try an SSL connection
38
+ * * `prefer` _(default)_: first try an SSL connection; if that fails, try a non-SSL connection
39
+ * * `require`: only try an SSL connection. If a root CA file is present, verify the certificate in the same way as if verify-ca was specified
40
+ * * `verify-ca`: only try an SSL connection, and verify that the server certificate is issued by a trusted certificate authority (CA)
41
+ * * `verify-full`: only try an SSL connection, verify that the server certificate is issued by a trusted CA and that the server host name matches that in the certificate
42
+ */
43
+ sslMode?: 'disable' | 'allow' | 'prefer' | 'require' | 'verify-ca' | 'verify-full';
44
+ /** If set to `true` (default), data sent over SSL connections will be compressed */
45
+ sslCompression?: boolean;
46
+ /** The file name of the client SSL certificate */
47
+ sslCertFile?: string;
48
+ /** The location for the secret key used for the client certificate. */
49
+ sslKeyFile?: string;
50
+ /** The name of a file containing SSL certificate authority (CA) certificate(s). */
51
+ sslRootCertFile?: string;
52
+ /** The file name of the SSL certificate revocation list (CRL). */
53
+ sslCrlFile?: string;
54
+ /** Kerberos service name to use when authenticating with Kerberos 5 or GSSAPI. */
55
+ kerberosServiceName?: string;
56
+ /** GSS library to use for GSSAPI authentication. Only used on Windows. */
57
+ gssLibrary?: 'gssapi';
58
+ }
59
+ /** Describes the result of a PostgreSQL query */
60
+ export interface ConnectionQueryResult {
61
+ /** Command executed (normally `SELECT`, or `INSERT`, ...) */
62
+ command: string;
63
+ /** Number of rows affected by this query (e.g. added rows in `INSERT`) */
64
+ rowCount: number;
65
+ /** Fields description with `name` (column name) and `oid` (type) */
66
+ fields: [name: string, oid: number][];
67
+ /** Result rows, as an array of unparsed `string` results from `libpq` */
68
+ rows: (string | null)[][];
69
+ }
70
+ /** The type identifying */
71
+ export type ConnectionQueryParams = (string | number | bigint | null)[];
72
+ /** Events generated by our {@link Connection} */
73
+ interface ConnectionEvents {
74
+ error: (error: Error) => unknown;
75
+ connected: () => unknown;
76
+ destroyed: () => unknown;
77
+ }
78
+ /** Convert our options into a string suitable for LibPQ */
79
+ export declare function convertOptions(options: ConnectionOptions): string;
80
+ /** Our *minimalistic* PostgreSQL connection wrapping `libpq`. */
81
+ export declare class Connection extends Emitter<ConnectionEvents> {
82
+ /** The unique ID of this connection */
83
+ id: string;
84
+ /** Queue for serializing queries to the database */
85
+ private readonly _queue;
86
+ /** Option string to use when calling `connect` */
87
+ private readonly _options;
88
+ /** Current instance of `libpq` */
89
+ private _pq;
90
+ /** A flag indicating that `destroy()` has been invoked... */
91
+ private _destroyed;
92
+ /** Create a connection with the specified `LibPQ` parameters string */
93
+ constructor(logger: Logger, params?: string);
94
+ /** Create a connection with the specified configuration options */
95
+ constructor(logger: Logger, options?: ConnectionOptions);
96
+ /** Check whether this {@link Connection} is connected or not */
97
+ get connected(): boolean;
98
+ /** Check whether this {@link Connection} is destroyed or not */
99
+ get destroyed(): boolean;
100
+ /** Return the version of the server we're connected to */
101
+ get serverVersion(): string;
102
+ /** Connect this {@link Connection} (fails if connected already) */
103
+ connect(): Promise<Connection>;
104
+ /** Destroy this {@link Connection} releasing all related resources */
105
+ destroy(): void;
106
+ /** ===== QUERY INTERFACE ================================================= */
107
+ /** Execute a (possibly parameterised) query with this {@link Connection} */
108
+ query(text: string, params?: ConnectionQueryParams): Promise<ConnectionQueryResult>;
109
+ /** Cancel (if possible) the currently running query */
110
+ cancel(): void;
111
+ }
112
+ export {};