@pi-r/postgres 0.7.2 → 0.8.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/client/index.js CHANGED
@@ -1,50 +1,18 @@
1
1
  "use strict";
2
- exports.DB_SOURCE_TYPE = exports.DB_SOURCE_CLIENT = exports.checkTimeout = exports.executeBatchQuery = exports.executeQuery = exports.setCredential = exports.setAuthentication = void 0;
2
+ exports.DB_SOURCE_TYPE = exports.DB_SOURCE_CLIENT = void 0;
3
+ exports.setAuthentication = setAuthentication;
4
+ exports.setCredential = setCredential;
5
+ exports.executeQuery = executeQuery;
6
+ exports.executeBatchQuery = executeBatchQuery;
7
+ exports.checkTimeout = checkTimeout;
3
8
  const postgres = require("pg");
4
9
  const connectionString = require("pg-connection-string");
10
+ const QueryStream = require("pg-query-stream");
11
+ const Db = require("@e-mc/db");
5
12
  const util_1 = require("@e-mc/db/util");
6
13
  const types_1 = require("@e-mc/types");
7
- const Db = require("@e-mc/db");
8
- const QueryStream = require("pg-query-stream");
9
- const DbPool = require('@e-mc/db/pool');
10
- class PostgresPool extends DbPool {
11
- async getConnection() {
12
- return this.client.connect();
13
- }
14
- async close() {
15
- return this.client.end();
16
- }
17
- isEmpty() {
18
- return this.closed || this.client.totalCount === 0 && this.client.waitingCount === 0;
19
- }
20
- get closed() {
21
- return this.client.ended;
22
- }
23
- }
14
+ const DbPool = require("@pi-r/postgres/client/pool");
24
15
  const POOL_STATE = {};
25
- const POOL_UNUSED = ['ssl', 'keepAlive', 'statement_timeout', 'query_timeout', 'keepAliveInitialDelayMillis', 'idle_in_transaction_session_timeout', 'connectionTimeoutMillis', 'max', 'min', 'idleTimeoutMillis', 'log', 'allowExitOnIdle', 'maxUses'];
26
- const POOL_ACTIVE = new WeakSet();
27
- function removePoolProperties(credential) {
28
- if (!credential.uuidKey && POOL_ACTIVE.has(credential)) {
29
- let result;
30
- for (let i = 0, length = POOL_UNUSED.length; i < length; ++i) {
31
- const attr = POOL_UNUSED[i];
32
- if (attr in credential) {
33
- result ||= { ...credential };
34
- if (attr === 'ssl' && (0, types_1.isObject)(result[attr])) {
35
- result[attr] = true;
36
- }
37
- else {
38
- delete result[attr];
39
- }
40
- }
41
- }
42
- if (result) {
43
- return result;
44
- }
45
- }
46
- return credential;
47
- }
48
16
  function fromConnectionString(credential, uri) {
49
17
  const { user, password, host, port, database, application_name, ssl } = connectionString.parse(uri);
50
18
  if (!credential.user) {
@@ -62,15 +30,6 @@ function fromConnectionString(credential, uri) {
62
30
  }
63
31
  return credential;
64
32
  }
65
- function getPoolKey(credential) {
66
- if (credential.host && credential.user) {
67
- if ('uuidKey' in credential) {
68
- credential = { ...credential };
69
- delete credential.uuidKey;
70
- }
71
- return JSON.stringify(credential);
72
- }
73
- }
74
33
  function setAuthentication(credential) {
75
34
  const auth = (0, util_1.parseServerAuth)(credential);
76
35
  credential.host ||= auth.hostname;
@@ -82,7 +41,6 @@ function setAuthentication(credential) {
82
41
  this.readTLSConfig(credential.ssl);
83
42
  }
84
43
  }
85
- exports.setAuthentication = setAuthentication;
86
44
  function setCredential(item) {
87
45
  let credential = this.getCredential(item);
88
46
  if (credential) {
@@ -90,7 +48,7 @@ function setCredential(item) {
90
48
  }
91
49
  else {
92
50
  credential = {};
93
- if ((0, types_1.isString)(item.uri)) {
51
+ if (item.uri) {
94
52
  item.credential = fromConnectionString(credential, item.uri);
95
53
  }
96
54
  }
@@ -102,10 +60,21 @@ function setCredential(item) {
102
60
  if (!credential.user) {
103
61
  errors.push('user');
104
62
  }
105
- if (errors.length) {
63
+ if (errors.length > 0) {
106
64
  throw (0, types_1.errorMessage)("postgres", 'Not defined - ' + errors.join(' | '));
107
65
  }
108
66
  }
67
+ if (credential.host?.endsWith('.rds.amazonaws.com')) {
68
+ try {
69
+ const ssl = credential.ssl ||= {};
70
+ if ((0, types_1.isPlainObject)(ssl) && !ssl.ca) {
71
+ const bundle = require('aws-ssl-profiles');
72
+ ssl.ca = bundle.ca;
73
+ }
74
+ }
75
+ catch {
76
+ }
77
+ }
109
78
  const usePool = item.usePool;
110
79
  if (!item.usePool || typeof credential.password === 'function') {
111
80
  if ('usePool' in item) {
@@ -143,18 +112,19 @@ function setCredential(item) {
143
112
  credential.connectionTimeoutMillis ??= timeout;
144
113
  }
145
114
  }
146
- const poolKey = getPoolKey(credential);
115
+ const poolKey = DbPool.asString(credential);
147
116
  if ((pool = POOL_STATE[poolKey]) && !pool.closed) {
148
117
  pool.add(item);
149
118
  return;
150
119
  }
151
- new PostgresPool(new postgres.Pool(credential), poolKey, username && password ? { username, password } : undefined).add(item).parent = POOL_STATE;
120
+ const client = new postgres.Pool(credential);
121
+ new DbPool(client, poolKey, username && password ? { username, password } : undefined)
122
+ .add(item)
123
+ .parent = POOL_STATE;
152
124
  }
153
- exports.setCredential = setCredential;
154
125
  async function executeQuery(item, options) {
155
126
  return (await executeBatchQuery.call(this, [item], options))[0] || [];
156
127
  }
157
- exports.executeQuery = executeQuery;
158
128
  async function executeBatchQuery(batch, options = '', outResult) {
159
129
  const length = batch.length;
160
130
  if (length === 0) {
@@ -189,20 +159,18 @@ async function executeBatchQuery(batch, options = '', outResult) {
189
159
  item.transactionState = 64;
190
160
  let client;
191
161
  if (postgresPool) {
192
- pools.push(client = await postgresPool.getConnection());
162
+ pools.push(client = await postgresPool.getConnection(credential));
193
163
  item.transactionState &= ~64;
194
- POOL_ACTIVE.add(credential);
195
164
  return client;
196
165
  }
197
- const pool = item.usePool && DbPool.findKey(POOL_STATE, item.usePool, getPoolKey(credential), ...connectOnce ? [item, batch[0]] : [item]);
166
+ const pool = item.usePool && DbPool.findKey(POOL_STATE, item.usePool, DbPool.asString(credential), ...connectOnce ? [item, batch[0]] : [item]);
198
167
  if (pool) {
199
168
  try {
200
- pools.push(client = await pool.getConnection());
169
+ pools.push(client = await pool.getConnection(credential));
201
170
  if (connectOnce) {
202
171
  postgresPool = pool;
203
172
  }
204
173
  pool.connected = true;
205
- POOL_ACTIVE.add(credential);
206
174
  }
207
175
  catch (err) {
208
176
  let close;
@@ -267,7 +235,7 @@ async function executeBatchQuery(batch, options = '', outResult) {
267
235
  if (caching && ignoreCache !== true) {
268
236
  queryString = Db.asString(query, true) + '_' + Db.asString(params, true);
269
237
  if (ignoreCache !== 1) {
270
- const result = this.getQueryResult(source, removePoolProperties(credential), queryString, cacheValue);
238
+ const result = this.getQueryResult(source, DbPool.sanitize(credential), queryString, cacheValue);
271
239
  if (result) {
272
240
  if (parallel) {
273
241
  tasks[i] = Promise.resolve(result);
@@ -303,7 +271,7 @@ async function executeBatchQuery(batch, options = '', outResult) {
303
271
  commandType = this.commandType.SELECT;
304
272
  if (streamRow && (0, types_1.isString)(query)) {
305
273
  const rows = [];
306
- const processRow = typeof streamRow === 'function' && streamRow;
274
+ const processRow = typeof streamRow === 'function' ? streamRow : null;
307
275
  const stream = client.query(new QueryStream(query, params));
308
276
  stream
309
277
  .on('data', row => {
@@ -326,7 +294,7 @@ async function executeBatchQuery(batch, options = '', outResult) {
326
294
  }
327
295
  else {
328
296
  this.add(item, 4);
329
- resolve(!error ? this.setQueryResult(source, removePoolProperties(credential), queryString, rows, cacheValue) : rows);
297
+ resolve(!error ? this.setQueryResult(source, DbPool.sanitize(credential), queryString, rows, cacheValue) : rows);
330
298
  }
331
299
  })
332
300
  .on('end', () => stream.destroy());
@@ -334,7 +302,7 @@ async function executeBatchQuery(batch, options = '', outResult) {
334
302
  else {
335
303
  const { rows, command } = await client.query(query, params);
336
304
  this.add(item, 4);
337
- resolve(rows.length || command === 'SELECT' ? this.setQueryResult(source, removePoolProperties(credential), queryString, rows, cacheValue) : null);
305
+ resolve(rows.length || command === 'SELECT' ? this.setQueryResult(source, DbPool.sanitize(credential), queryString, rows, cacheValue) : null);
338
306
  }
339
307
  }
340
308
  catch (err) {
@@ -357,25 +325,23 @@ async function executeBatchQuery(batch, options = '', outResult) {
357
325
  }
358
326
  }
359
327
  return this.processRows(batch, tasks, {
328
+ parallel,
360
329
  disconnect: () => {
361
- clients.forEach(item => {
330
+ for (const item of clients) {
362
331
  item.end(err => {
363
332
  if (err) {
364
333
  this.writeFail(["Unable to close connnection", "postgres"], err, { type: 65536, fatal: false });
365
334
  }
366
335
  });
367
- });
368
- pools.forEach(item => {
336
+ }
337
+ for (const item of pools) {
369
338
  item.release();
370
- });
371
- },
372
- parallel
339
+ }
340
+ }
373
341
  }, outResult);
374
342
  }
375
- exports.executeBatchQuery = executeBatchQuery;
376
343
  async function checkTimeout(value, limit = 0) {
377
344
  return DbPool.checkTimeout(POOL_STATE, value, limit);
378
345
  }
379
- exports.checkTimeout = checkTimeout;
380
346
  exports.DB_SOURCE_CLIENT = true;
381
347
  exports.DB_SOURCE_TYPE = types_1.DB_TYPE.SQL;
@@ -0,0 +1,9 @@
1
+ import type { DbPoolConstructor } from '@e-mc/types/lib/db';
2
+
3
+ import type { DbPoolCredential, PostgresDataSource } from '../types';
4
+
5
+ import type { Pool, PoolClient } from 'pg';
6
+
7
+ declare const PostgresPool: DbPoolConstructor<PostgresDataSource, Pool, PoolClient, DbPoolCredential>;
8
+
9
+ export = PostgresPool;
package/client/pool.js ADDED
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ const types_1 = require("@e-mc/types");
3
+ const DbPool = require('@e-mc/db/pool');
4
+ const POOL_ACTIVE = new WeakSet();
5
+ class PostgresPool extends DbPool {
6
+ static CACHE_UNUSED = ['keepAlive', 'statement_timeout', 'query_timeout', 'keepAliveInitialDelayMillis', 'idle_in_transaction_session_timeout', 'connectionTimeoutMillis', 'max', 'min', 'idleTimeoutMillis', 'log', 'allowExitOnIdle', 'maxUses'];
7
+ static asString(credential) {
8
+ if (credential.host && credential.user) {
9
+ return JSON.stringify(this.removeUUIDKey(credential));
10
+ }
11
+ return super.asString(credential);
12
+ }
13
+ static sanitize(credential) {
14
+ if (!POOL_ACTIVE.has(credential) || credential.uuidKey) {
15
+ return credential;
16
+ }
17
+ const ssl = credential.ssl;
18
+ let result = super.sanitize(credential);
19
+ if ((0, types_1.isObject)(ssl)) {
20
+ if (result === credential) {
21
+ result = { ...credential };
22
+ }
23
+ const cert = ssl.cert;
24
+ if ((0, types_1.isString)(cert)) {
25
+ result.ssl = { cert };
26
+ }
27
+ else if (Buffer.isBuffer(cert)) {
28
+ result.ssl = { cert: cert.toString('utf-8') };
29
+ }
30
+ else if ((0, types_1.isArray)(cert)) {
31
+ result.ssl = { cert: cert.reduce((a, b) => a + (Buffer.isBuffer(b) ? b.toString('utf-8') : b), '') };
32
+ }
33
+ else {
34
+ result.ssl = { cert: "Unknown" };
35
+ }
36
+ }
37
+ return result;
38
+ }
39
+ async getConnection(credential) {
40
+ if (credential) {
41
+ POOL_ACTIVE.add(credential);
42
+ }
43
+ return this.client.connect();
44
+ }
45
+ async close() {
46
+ return this.client.end();
47
+ }
48
+ isEmpty() {
49
+ return this.closed || this.client.totalCount === 0 && this.client.waitingCount === 0;
50
+ }
51
+ get closed() {
52
+ return this.client.ended;
53
+ }
54
+ }
55
+ module.exports = PostgresPool;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-r/postgres",
3
- "version": "0.7.2",
3
+ "version": "0.8.0",
4
4
  "description": "PostgreSQL client driver for E-mc.",
5
5
  "main": "client/index.js",
6
6
  "types": "client/index.d.ts",
@@ -21,8 +21,8 @@
21
21
  "license": "MIT",
22
22
  "homepage": "https://github.com/anpham6/pi-r#readme",
23
23
  "dependencies": {
24
- "@e-mc/db": "^0.9.4",
25
- "@e-mc/types": "^0.9.4",
24
+ "@e-mc/db": "^0.10.0",
25
+ "@e-mc/types": "^0.10.0",
26
26
  "pg": "^8.12.0",
27
27
  "pg-connection-string": "^2.6.4",
28
28
  "pg-query-stream": "^4.6.0"
package/types/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type { DbDataSource } from '@e-mc/types/lib/squared';
2
2
 
3
+ import type { IdentifierAction } from '@e-mc/types/lib/core';
3
4
  import type { ExecuteAction, ServerAuth } from '@e-mc/types/lib/db';
4
5
 
5
6
  // @ts-ignore
@@ -9,4 +10,5 @@ export interface PostgresDataSource<T = unknown[]> extends DbDataSource<string |
9
10
  source: "postgres";
10
11
  }
11
12
 
12
- export interface PostgresCredential extends Omit<ServerAuth, "password">, PoolConfig {}
13
+ export interface PostgresCredential extends Omit<ServerAuth, "password">, PoolConfig {}
14
+ export type DbPoolCredential = PoolConfig & IdentifierAction;