@m2k-5f/pgtx 2.5.2 → 2.6.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.
Files changed (39) hide show
  1. package/dist/batch.d.ts +14 -0
  2. package/dist/batch.d.ts.map +1 -0
  3. package/dist/batch.js +35 -0
  4. package/dist/clauses/array.clause.js +2 -2
  5. package/dist/clauses/exclude.clause.d.ts.map +1 -1
  6. package/dist/clauses/exclude.clause.js +2 -2
  7. package/dist/clauses/fragment.clause.d.ts.map +1 -1
  8. package/dist/clauses/fragment.clause.js +2 -5
  9. package/dist/clauses/iden.caluse.js +1 -1
  10. package/dist/clauses/insert.clause.d.ts.map +1 -1
  11. package/dist/clauses/insert.clause.js +10 -9
  12. package/dist/clauses/literal.clause.js +1 -1
  13. package/dist/clauses/update.clause.js +2 -2
  14. package/dist/clauses/where.clause.js +2 -2
  15. package/dist/connection.d.ts +14 -14
  16. package/dist/connection.d.ts.map +1 -1
  17. package/dist/connection.js +151 -204
  18. package/dist/error.d.ts +3 -0
  19. package/dist/error.d.ts.map +1 -1
  20. package/dist/error.js +3 -0
  21. package/dist/pool.d.ts.map +1 -1
  22. package/dist/pool.js +2 -2
  23. package/dist/protocol/connection-request-writer.d.ts.map +1 -1
  24. package/dist/protocol/connection-request-writer.js +1 -0
  25. package/dist/query.d.ts +29 -22
  26. package/dist/query.d.ts.map +1 -1
  27. package/dist/query.js +41 -32
  28. package/dist/queue.d.ts +17 -0
  29. package/dist/queue.d.ts.map +1 -1
  30. package/dist/queue.js +44 -4
  31. package/dist/transaction.d.ts +3 -3
  32. package/dist/transaction.d.ts.map +1 -1
  33. package/dist/transaction.js +2 -4
  34. package/dist/types.d.ts +1 -1
  35. package/dist/types.d.ts.map +1 -1
  36. package/dist/utils/template-compiler.d.ts +2 -2
  37. package/dist/utils/template-compiler.d.ts.map +1 -1
  38. package/dist/utils/template-compiler.js +14 -9
  39. package/package.json +8 -6
@@ -5,12 +5,11 @@ import { compileSqlTemplate } from "./utils/template-compiler";
5
5
  import { Transaction } from "./transaction";
6
6
  import { SocketConnector } from "./protocol/socket-connector";
7
7
  import { Queue } from "./queue";
8
- import { Query, QueryState, StreamQuery } from "./query";
8
+ import { ParseQuery, SimpleQuery, StreamQuery } from "./query";
9
9
  import { sql } from ".";
10
10
  import { Begin, Future, Ok } from 'fluent-future';
11
- import { PostgresError } from "./error";
12
- const ErrConnectionClosed = new PostgresError("Connection is closed", 'connection_closed', "", "ERROR");
13
- const ErrConnectionReconnecring = new PostgresError("Connection are reconnecting", "connection_reconnecting", "", "ERROR");
11
+ import { ErrConnectionClosed, ErrConnectionReconnecting } from "./error";
12
+ import { Batch } from "./batch";
14
13
  /**
15
14
  * Represents a single dedicated connection to the PostgreSQL database.
16
15
  *
@@ -45,28 +44,19 @@ export class Connection {
45
44
  _nextStatement() {
46
45
  return `s-${this._stmtCounter++}`;
47
46
  }
48
- _checkOpened() {
49
- if (!this.isOpened)
50
- throw ErrConnectionClosed;
51
- }
52
- constructor(socket, writer, logLevel, params) {
53
- this._isFlushing = false;
47
+ constructor(socket, logLevel, params) {
48
+ this._activeBatch = null;
54
49
  this._isOpened = true;
55
50
  this._isReconnecting = false;
56
- this._pipelinesQueue = new Queue();
57
- this._described = new Map();
58
- this._describingPending = new Set();
51
+ this._cachedBuffer = ConnectionRequestWriter.new();
52
+ this._batchQueue = new Queue();
59
53
  this._parsed = new Map();
60
- this._parsingPending = new Map();
54
+ this._parsing = new Map();
61
55
  this._listeningCallbacks = new Map();
62
56
  this._stmtCounter = 0;
63
57
  this.params = params;
64
58
  this._logLevel = logLevel;
65
- this._socket = new SocketConnector(socket, (type, _, reader) => this._handlePacket(type, reader), (err) => {
66
- // console.log(err)
67
- this._registerReconnect();
68
- });
69
- this._writer = writer;
59
+ this._socket = new SocketConnector(socket, (type, _, reader) => this._handlePacket(type, reader), () => this._registerReconnect());
70
60
  }
71
61
  /**
72
62
  * Creates a new database connection.
@@ -89,7 +79,39 @@ export class Connection {
89
79
  static new(params) {
90
80
  const writer = ConnectionRequestWriter.new();
91
81
  return createAuthorizedSocket(writer, params)
92
- .andThen(socket => Ok(new Connection(socket, writer, params.logLevel || 'error', params)));
82
+ .andThen(socket => Ok(new Connection(socket, params.logLevel || 'error', params)));
83
+ }
84
+ _registerBatch() {
85
+ if (!this._activeBatch) {
86
+ const batch = new Batch(this._cachedBuffer.clear());
87
+ this._activeBatch = batch;
88
+ setImmediate(() => {
89
+ this._sync(batch);
90
+ });
91
+ return batch;
92
+ }
93
+ return this._activeBatch;
94
+ }
95
+ _sync(batch) {
96
+ if (!this._isOpened) {
97
+ batch.reject(ErrConnectionClosed);
98
+ return;
99
+ }
100
+ if (this._isReconnecting) {
101
+ this._reconnect()
102
+ .then(() => {
103
+ this._activeBatch = null;
104
+ void this._restoreSubscriptions();
105
+ this._socket.write(this._registerBatch().end());
106
+ this._batchQueue.push(this._registerBatch());
107
+ })
108
+ .then(() => {
109
+ this._isReconnecting = false;
110
+ });
111
+ }
112
+ this._socket.write(batch.end());
113
+ this._activeBatch = null;
114
+ this._batchQueue.push(batch);
93
115
  }
94
116
  /**
95
117
  * Executes a query using tagged template literals.
@@ -116,16 +138,32 @@ export class Connection {
116
138
  * ```
117
139
  */
118
140
  query(templates, ...params) {
119
- this._checkOpened();
120
- this._registerFlush();
121
- const { text, args } = compileSqlTemplate({ templates, args: params });
141
+ if (!this._isOpened)
142
+ return Future.reject(ErrConnectionClosed);
143
+ if (this._isReconnecting)
144
+ return Future.reject(ErrConnectionReconnecting);
145
+ const { text, args } = compileSqlTemplate(templates, params);
122
146
  if (this._logLevel === 'query') {
123
147
  console.log(`\nQUERY: ${text}\n${args.length !== 0 ? `ARGUMENTS: [${args}]\n` : ""}`);
124
148
  }
125
- const query = this._createQuery(text, args);
126
- this._writeQuery(query);
127
- query.startTimeout(this.params.queryTimeout || 30000);
128
- return query.future;
149
+ const batch = this._registerBatch();
150
+ if (this._parsed.has(text)) {
151
+ const meta = this._parsed.get(text);
152
+ const query = new SimpleQuery(meta.statement, text, args, meta.columns);
153
+ batch.registerQuery(query, this.params.queryTimeout || 30000);
154
+ return query.future;
155
+ }
156
+ if (!this._parsing.has(text)) {
157
+ const parseQuery = new ParseQuery(this._nextStatement(), text);
158
+ this._parsing.set(text, parseQuery.future);
159
+ batch.registerQuery(parseQuery, this.params.queryTimeout || 30000);
160
+ }
161
+ const future = this._parsing.get(text);
162
+ return future.andThen(meta => {
163
+ const query = new SimpleQuery(meta.statement, text, args, meta.columns);
164
+ this._registerBatch().registerQuery(query, this.params.queryTimeout || 30000);
165
+ return query.future;
166
+ });
129
167
  }
130
168
  /**
131
169
  * Starts a managed transaction on this connection.
@@ -149,7 +187,10 @@ export class Connection {
149
187
  * ```
150
188
  */
151
189
  begin(txCallback) {
152
- this._checkOpened();
190
+ if (!this._isOpened)
191
+ return Future.reject(ErrConnectionClosed);
192
+ if (this._isReconnecting)
193
+ return Future.reject(ErrConnectionReconnecting);
153
194
  const tx = new Transaction(this);
154
195
  return Begin()
155
196
  .andThen(() => tx.query `BEGIN`)
@@ -175,7 +216,10 @@ export class Connection {
175
216
  * ```
176
217
  */
177
218
  notify(channelName, payload = "") {
178
- this._checkOpened();
219
+ if (!this._isOpened)
220
+ return Future.reject(ErrConnectionClosed);
221
+ if (this._isReconnecting)
222
+ return Future.reject(ErrConnectionReconnecting);
179
223
  return this.query `select pg_notify(${channelName}, ${payload})`;
180
224
  }
181
225
  /**
@@ -190,7 +234,10 @@ export class Connection {
190
234
  * ```
191
235
  */
192
236
  listen(channelName, callback) {
193
- this._checkOpened();
237
+ if (!this._isOpened)
238
+ return Future.reject(ErrConnectionClosed);
239
+ if (this._isReconnecting)
240
+ return Future.reject(ErrConnectionReconnecting);
194
241
  if (!this._listeningCallbacks.has(channelName)) {
195
242
  this._listeningCallbacks.set(channelName, new Set());
196
243
  }
@@ -210,7 +257,10 @@ export class Connection {
210
257
  * ```
211
258
  */
212
259
  unlisten(channelName, callback) {
213
- this._checkOpened();
260
+ if (!this._isOpened)
261
+ return Future.reject(ErrConnectionClosed);
262
+ if (this._isReconnecting)
263
+ return Future.reject(ErrConnectionReconnecting);
214
264
  if (!this._listeningCallbacks.has(channelName)) {
215
265
  return Ok();
216
266
  }
@@ -248,9 +298,11 @@ export class Connection {
248
298
  * }
249
299
  */
250
300
  stream(templates, ...params) {
251
- this._checkOpened();
252
- this._registerFlush();
253
- const { text, args } = compileSqlTemplate({ templates, args: params });
301
+ if (!this._isOpened)
302
+ throw ErrConnectionClosed;
303
+ if (this._isReconnecting)
304
+ throw ErrConnectionReconnecting;
305
+ const { text, args } = compileSqlTemplate(templates, params);
254
306
  if (this._logLevel === 'query') {
255
307
  console.log(`\nQUERY: ${text}\n${args.length !== 0 ? `ARGUMENTS: [${args}]\n` : ""}`);
256
308
  }
@@ -260,148 +312,71 @@ export class Connection {
260
312
  controller = c;
261
313
  }
262
314
  });
263
- const query = this._createStream(text, args, controller);
264
- this._writeQuery(query);
265
- query.startTimeout(this.params.queryTimeout || 30000);
315
+ const batch = this._registerBatch();
316
+ if (this._parsed.has(text)) {
317
+ const meta = this._parsed.get(text);
318
+ const query = new StreamQuery(meta.statement, text, args, controller, meta.columns);
319
+ batch.registerQuery(query, this.params.queryTimeout || 30000);
320
+ return stream;
321
+ }
322
+ if (!this._parsing.has(text)) {
323
+ const parseQuery = new ParseQuery(this._nextStatement(), text);
324
+ this._parsing.set(text, parseQuery.future);
325
+ batch.registerQuery(parseQuery, this.params.queryTimeout || 30000);
326
+ }
327
+ const future = this._parsing.get(text);
328
+ future
329
+ .tap(meta => {
330
+ const query = new StreamQuery(meta.statement, text, args, controller, meta.columns);
331
+ this._registerBatch().registerQuery(query, this.params.queryTimeout || 30000);
332
+ })
333
+ .catch(err => controller.error(err));
266
334
  return stream;
267
335
  }
268
336
  _streamWithController(templates, params, controller) {
269
- this._checkOpened();
270
- this._registerFlush();
271
- const { text, args } = compileSqlTemplate({ templates, args: params });
337
+ if (!this._isOpened)
338
+ throw ErrConnectionClosed;
339
+ if (this._isReconnecting)
340
+ throw ErrConnectionReconnecting;
341
+ const { text, args } = compileSqlTemplate(templates, params);
272
342
  if (this._logLevel === 'query') {
273
343
  console.log(`\nQUERY: ${text}\n${args.length !== 0 ? `ARGUMENTS: [${args}]\n` : ""}`);
274
344
  }
275
- const query = this._createStream(text, args, controller);
276
- this._writeQuery(query);
277
- query.startTimeout(this.params.queryTimeout || 30000);
278
- return query;
279
- }
280
- _createQuery(text, args) {
345
+ const batch = this._registerBatch();
281
346
  if (this._parsed.has(text)) {
282
- const statementName = this._parsed.get(text);
283
- if (this._described.has(statementName)) {
284
- const columns = this._described.get(statementName);
285
- return new Query(text, args, QueryState.Executing, statementName, columns);
286
- }
287
- else {
288
- if (this._describingPending.has(statementName)) {
289
- return new Query(text, args, QueryState.Executing, statementName);
290
- }
291
- else {
292
- this._describingPending.add(statementName);
293
- return new Query(text, args, QueryState.Describing, statementName);
294
- }
295
- }
347
+ const meta = this._parsed.get(text);
348
+ const query = new StreamQuery(meta.statement, text, args, controller, meta.columns);
349
+ batch.registerQuery(query, this.params.queryTimeout || 30000);
296
350
  }
297
- else {
298
- if (this._parsingPending.has(text)) {
299
- const statementName = this._parsingPending.get(text);
300
- return new Query(text, args, QueryState.Describing, statementName);
301
- }
302
- else {
303
- const statementName = this._nextStatement();
304
- this._parsingPending.set(text, statementName);
305
- return new Query(text, args, QueryState.Parsing, statementName);
306
- }
307
- }
308
- }
309
- _createStream(text, args, controller) {
310
- if (this._parsed.has(text)) {
311
- const statementName = this._parsed.get(text);
312
- if (this._described.has(statementName)) {
313
- const columns = this._described.get(statementName);
314
- return new StreamQuery(text, args, QueryState.Executing, statementName, controller, columns);
315
- }
316
- else {
317
- if (this._describingPending.has(statementName)) {
318
- return new StreamQuery(text, args, QueryState.Executing, statementName, controller);
319
- }
320
- else {
321
- this._describingPending.add(statementName);
322
- return new StreamQuery(text, args, QueryState.Describing, statementName, controller);
323
- }
324
- }
325
- }
326
- else {
327
- if (this._parsingPending.has(text)) {
328
- const statementName = this._parsingPending.get(text);
329
- return new StreamQuery(text, args, QueryState.Describing, statementName, controller);
330
- }
331
- else {
332
- const statementName = this._nextStatement();
333
- this._parsingPending.set(text, statementName);
334
- return new StreamQuery(text, args, QueryState.Parsing, statementName, controller);
335
- }
336
- }
337
- }
338
- _writeQuery(query) {
339
- if (query.state === QueryState.Parsing) {
340
- this._writer
341
- .writeParse(query.statementName, query.text)
342
- .writeDescribe(query.statementName)
343
- .writeBind("", query.statementName, query.args)
344
- .writeExecute("");
345
- }
346
- if (query.state === QueryState.Describing) {
347
- this._writer
348
- .writeDescribe(query.statementName)
349
- .writeBind("", query.statementName, query.args)
350
- .writeExecute("");
351
- }
352
- if (query.state === QueryState.Executing) {
353
- this._writer
354
- .writeBind("", query.statementName, query.args)
355
- .writeExecute("");
356
- }
357
- this._pipelinesQueue.last.push(query);
358
- }
359
- _registerFlush() {
360
- if (!this._isFlushing) {
361
- this._isFlushing = true;
362
- this._pipelinesQueue.push(new Queue());
363
- setImmediate(() => {
364
- this._flush();
365
- });
366
- }
367
- }
368
- _flush() {
369
- if (!this._isOpened) {
370
- this._rejectPipeline(ErrConnectionClosed);
371
- return;
372
- }
373
- if (this._isReconnecting) {
374
- this._reconnect().then(() => {
375
- this._isFlushing = false;
376
- this._socket.write(this._writer.writeSync());
377
- this._writer.clear();
378
- });
379
- }
380
- else {
381
- this._isFlushing = false;
382
- this._socket.write(this._writer.writeSync());
383
- this._writer.clear();
351
+ if (!this._parsing.has(text)) {
352
+ const parseQuery = new ParseQuery(this._nextStatement(), text);
353
+ this._parsing.set(text, parseQuery.future);
354
+ batch.registerQuery(parseQuery, this.params.queryTimeout || 30000);
384
355
  }
356
+ const future = this._parsing.get(text);
357
+ future
358
+ .tap(meta => {
359
+ const query = new StreamQuery(meta.statement, text, args, controller, meta.columns);
360
+ this._registerBatch().registerQuery(query, this.params.queryTimeout || 30000);
361
+ })
362
+ .catch(err => controller.error(err));
385
363
  }
386
364
  _registerReconnect() {
365
+ if (this._isReconnecting)
366
+ return;
387
367
  this._isReconnecting = true;
388
- this._rejectPipeline(ErrConnectionReconnecring);
389
368
  }
390
369
  _resetConnectionState(cause) {
391
370
  this._parsed.clear();
392
- this._described.clear();
393
- this._describingPending.clear();
394
- this._parsingPending.clear();
395
- this._writer.clear();
396
- this._rejectPipeline(cause);
371
+ this._parsing.clear();
372
+ this._activeBatch = null;
373
+ this._rejectAllBatches(cause);
397
374
  }
398
375
  async _reconnect() {
399
- this._resetConnectionState(ErrConnectionReconnecring);
400
376
  const socket = await createAuthorizedSocket(ConnectionRequestWriter.new(), this.params);
401
377
  const connector = new SocketConnector(socket, (type, _, reader) => this._handlePacket(type, reader), (err) => this._registerReconnect());
402
378
  this._socket = connector;
403
- void this._restoreSubscriptions();
404
- this._isReconnecting = false;
379
+ this._resetConnectionState(ErrConnectionReconnecting);
405
380
  }
406
381
  _restoreSubscriptions() {
407
382
  if (this._listeningCallbacks.size === 0)
@@ -412,14 +387,11 @@ export class Connection {
412
387
  return Promise.all(promises);
413
388
  }
414
389
  _getCurrentQuery() {
415
- return this._pipelinesQueue.current.current;
390
+ return this._batchQueue.current.current;
416
391
  }
417
- _rejectPipeline(error) {
418
- if (this._pipelinesQueue.isFree)
419
- return;
420
- const queue = this._pipelinesQueue.current;
421
- while (queue.hasMore) {
422
- queue.shift.reject(error);
392
+ _rejectAllBatches(cause) {
393
+ while (this._batchQueue.hasMore) {
394
+ this._batchQueue.shift.reject(cause);
423
395
  }
424
396
  }
425
397
  _handlePacket(type, reader) {
@@ -427,10 +399,6 @@ export class Connection {
427
399
  case ResponseTypes.ParseComplete:
428
400
  {
429
401
  reader.readParseComplete();
430
- const query = this._getCurrentQuery();
431
- this._parsingPending.delete(query.text);
432
- this._parsed.set(query.text, query.statementName);
433
- query.state = QueryState.Describing;
434
402
  }
435
403
  break;
436
404
  case ResponseTypes.BindComplete:
@@ -452,46 +420,36 @@ export class Connection {
452
420
  {
453
421
  reader.readNoData();
454
422
  const query = this._getCurrentQuery();
455
- this._describingPending.delete(query.statementName);
456
- this._described.set(query.statementName, []);
457
- query.state = QueryState.Executing;
458
- query.columns = [];
423
+ const meta = { statement: query.statement, columns: [] };
424
+ this._parsing.delete(query.text);
425
+ query.resolve(meta);
426
+ this._parsed.set(query.text, meta);
427
+ this._batchQueue.current.next();
459
428
  }
460
429
  break;
461
430
  case ResponseTypes.RowDescription:
462
431
  {
463
432
  const columns = reader.readRowDescription();
464
433
  const query = this._getCurrentQuery();
465
- this._describingPending.delete(query.statementName);
466
- this._described.set(query.statementName, columns);
467
- query.state = QueryState.Executing;
468
- query.columns = columns;
434
+ const meta = { statement: query.statement, columns };
435
+ this._parsing.delete(query.text);
436
+ query.resolve(meta);
437
+ this._parsed.set(query.text, meta);
438
+ this._batchQueue.current.next();
469
439
  }
470
440
  break;
471
441
  case ResponseTypes.DataRow:
472
442
  {
473
443
  let query = this._getCurrentQuery();
474
- if (!query.columns) {
475
- query.columns = this._described.get(query.statementName);
476
- }
477
444
  query.push(reader.readDataRow(query.columns, this.params.int8toBigint));
478
445
  }
479
446
  break;
480
447
  case ResponseTypes.ComandComplete:
481
448
  {
482
449
  reader.readCommandComplete();
483
- if (this._pipelinesQueue.isFree) {
484
- this.close();
485
- break;
486
- }
487
450
  const query = this._getCurrentQuery();
488
- if (!query) {
489
- this.close();
490
- break;
491
- }
492
- query.state = QueryState.Completed;
493
- this._pipelinesQueue.current.next();
494
451
  query.resolve();
452
+ this._batchQueue.current.next();
495
453
  }
496
454
  break;
497
455
  case ResponseTypes.ErrorResponse:
@@ -501,22 +459,14 @@ export class Connection {
501
459
  console.log(`\nError: ${error}\n`);
502
460
  }
503
461
  const query = this._getCurrentQuery();
504
- switch (query.state) {
505
- case QueryState.Parsing:
506
- this._parsingPending.delete(query.text);
507
- break;
508
- case QueryState.Describing:
509
- this._describingPending.delete(query.statementName);
510
- break;
511
- }
512
- query.state = QueryState.Failed;
513
- this._rejectPipeline(error);
462
+ this._parsing.delete(query.text);
463
+ this._batchQueue.current.reject(error);
514
464
  }
515
465
  break;
516
466
  case ResponseTypes.ReadyForQuery:
517
467
  {
518
468
  reader.readReadyForQuery();
519
- this._pipelinesQueue.next();
469
+ this._batchQueue.next();
520
470
  }
521
471
  break;
522
472
  case ResponseTypes.Notice:
@@ -536,7 +486,7 @@ export class Connection {
536
486
  callbackSet.forEach(cb => cb(payload));
537
487
  }
538
488
  break;
539
- default: console.warn('Undeclared response type: ', type);
489
+ default: console.log('Undeclared response type: ', type);
540
490
  }
541
491
  }
542
492
  /**
@@ -559,9 +509,6 @@ export class Connection {
559
509
  close() {
560
510
  this._isOpened = false;
561
511
  this._socket.destroy();
562
- while (this._pipelinesQueue.hasMore) {
563
- this._rejectPipeline(ErrConnectionClosed);
564
- this._pipelinesQueue.next();
565
- }
512
+ this._rejectAllBatches(ErrConnectionClosed);
566
513
  }
567
514
  }
package/dist/error.d.ts CHANGED
@@ -15,4 +15,7 @@ export declare class PostgresError extends Error {
15
15
  get isTimeout(): boolean;
16
16
  get isConnectionFailure(): boolean;
17
17
  }
18
+ export declare const ErrQueryTimeout: PostgresError;
19
+ export declare const ErrConnectionClosed: PostgresError;
20
+ export declare const ErrConnectionReconnecting: PostgresError;
18
21
  //# sourceMappingURL=error.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAAA,qBAAa,aAAc,SAAQ,KAAK;IAEhB,OAAO,EAAE,MAAM;IACxB,IAAI,EAAE,MAAM;IACZ,MAAM,EAAE,MAAM;IACd,QAAQ,EAAE,MAAM;IAChB,KAAK,EAAE,MAAM;IACb,IAAI,EAAE,MAAM;IACZ,QAAQ,EAAE,MAAM;IAChB,QAAQ,EAAE,MAAM;IAChB,UAAU,EAAE,MAAM;gBART,OAAO,EAAE,MAAM,EACxB,IAAI,GAAE,MAAqB,EAC3B,MAAM,GAAE,MAAW,EACnB,QAAQ,GAAE,MAAW,EACrB,KAAK,GAAE,MAAW,EAClB,IAAI,GAAE,MAAW,EACjB,QAAQ,GAAE,MAAW,EACrB,QAAQ,GAAE,MAAW,EACrB,UAAU,GAAE,MAAW;IAQlC,IAAI,YAAY,IAAI,OAAO,CAE1B;IAID,IAAI,UAAU,IAAI,OAAO,CAExB;IAID,IAAI,qBAAqB,IAAI,OAAO,CAEnC;IAGD,IAAI,SAAS,IAAI,OAAO,CAEvB;IAGD,IAAI,mBAAmB,IAAI,OAAO,CAEjC;CACJ"}
1
+ {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAAA,qBAAa,aAAc,SAAQ,KAAK;IAEhB,OAAO,EAAE,MAAM;IACxB,IAAI,EAAE,MAAM;IACZ,MAAM,EAAE,MAAM;IACd,QAAQ,EAAE,MAAM;IAChB,KAAK,EAAE,MAAM;IACb,IAAI,EAAE,MAAM;IACZ,QAAQ,EAAE,MAAM;IAChB,QAAQ,EAAE,MAAM;IAChB,UAAU,EAAE,MAAM;gBART,OAAO,EAAE,MAAM,EACxB,IAAI,GAAE,MAAqB,EAC3B,MAAM,GAAE,MAAW,EACnB,QAAQ,GAAE,MAAW,EACrB,KAAK,GAAE,MAAW,EAClB,IAAI,GAAE,MAAW,EACjB,QAAQ,GAAE,MAAW,EACrB,QAAQ,GAAE,MAAW,EACrB,UAAU,GAAE,MAAW;IAQlC,IAAI,YAAY,IAAI,OAAO,CAE1B;IAID,IAAI,UAAU,IAAI,OAAO,CAExB;IAID,IAAI,qBAAqB,IAAI,OAAO,CAEnC;IAGD,IAAI,SAAS,IAAI,OAAO,CAEvB;IAGD,IAAI,mBAAmB,IAAI,OAAO,CAEjC;CACJ;AAED,eAAO,MAAM,eAAe,eAA8C,CAAA;AAE1E,eAAO,MAAM,mBAAmB,eAA8E,CAAA;AAC9G,eAAO,MAAM,yBAAyB,eAA2F,CAAA"}
package/dist/error.js CHANGED
@@ -31,3 +31,6 @@ export class PostgresError extends Error {
31
31
  return this.code.startsWith('08') || this.code.startsWith('57') && this.code !== '57014';
32
32
  }
33
33
  }
34
+ export const ErrQueryTimeout = new PostgresError('Query timeout', '57014');
35
+ export const ErrConnectionClosed = new PostgresError("Connection is closed", 'connection_closed', "", "ERROR");
36
+ export const ErrConnectionReconnecting = new PostgresError("Connection are reconnecting", "connection_reconnecting", "", "ERROR");
@@ -1 +1 @@
1
- {"version":3,"file":"pool.d.ts","sourceRoot":"","sources":["../src/pool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAG3C,OAAO,EAAS,MAAM,EAAM,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAGxC,KAAK,UAAU,GAAG,gBAAgB,GAAG;IACjC,GAAG,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAWD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,qBAAa,IAAI;IACb,OAAO,CAAC,UAAU,CAA0B;IAC5C,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,IAAI,CAAQ;IACpB,OAAO,CAAC,MAAM,CAAI;IAClB,OAAO,CAAC,QAAQ,CAAsB;IACtC,OAAO,CAAC,SAAS,CAAQ;IAEzB,OAAO,CAAC,YAAY;gBAIR,MAAM,EAAE,UAAU;IAM9B;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO;IA2BP;;;;;;;;;;;;;;;;;OAiBG;IACH,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC;IAUnD;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,CAAC,IAAI,EAAE,UAAU;IAiBxB;;;;;;;;;;;;;;;;;OAiBG;IACH,KAAK,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,WAAW,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC;IAY7D;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,SAAS,EAAE,oBAAoB,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE;IAuBpF;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,MAAM,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,SAAS,EAAE,oBAAoB,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,cAAc,CAAC,CAAC,CAAC;IAoCzG;;;;;;;;;;OAUG;IACH,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,GAAE,MAAW,GACuB,MAAM,CAAC,EAAE,EAAE,aAAa,CAAC;IAIhG;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI;IAY3D;;OAEG;IACH,IAAI,IAAI,WAEP;IAGD;;;OAGG;IACH,IAAI,KAAK,WAER;IAGD;;;;;;;;;;OAUG;IACH,KAAK;CAWR"}
1
+ {"version":3,"file":"pool.d.ts","sourceRoot":"","sources":["../src/pool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAG3C,OAAO,EAAS,MAAM,EAAM,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAGxC,KAAK,UAAU,GAAG,gBAAgB,GAAG;IACjC,GAAG,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAWD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,qBAAa,IAAI;IACb,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,IAAI,CAAQ;IACpB,OAAO,CAAC,MAAM,CAAI;IAClB,OAAO,CAAC,QAAQ,CAAsB;IACtC,OAAO,CAAC,SAAS,CAAQ;IAEzB,OAAO,CAAC,YAAY;gBAIR,MAAM,EAAE,UAAU;IAO9B;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO;IA2BP;;;;;;;;;;;;;;;;;OAiBG;IACH,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC;IAUnD;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,CAAC,IAAI,EAAE,UAAU;IAiBxB;;;;;;;;;;;;;;;;;OAiBG;IACH,KAAK,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,WAAW,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC;IAY7D;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,SAAS,EAAE,oBAAoB,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE;IAuBpF;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,MAAM,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,SAAS,EAAE,oBAAoB,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,cAAc,CAAC,CAAC,CAAC;IAoCzG;;;;;;;;;;OAUG;IACH,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,GAAE,MAAW,GACuB,MAAM,CAAC,EAAE,EAAE,aAAa,CAAC;IAIhG;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI;IAY3D;;OAEG;IACH,IAAI,IAAI,WAEP;IAGD;;;OAGG;IACH,IAAI,KAAK,WAER;IAGD;;;;;;;;;;OAUG;IACH,KAAK;CAWR"}
package/dist/pool.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Connection } from "./connection";
2
- import { Queue } from "./queue";
2
+ import { Queue, RingQueue } from "./queue";
3
3
  import { Begin, Future, Ok } from "fluent-future";
4
4
  import { PostgresError } from "./error";
5
5
  const ErrPoolClosed = new PostgresError('Pool closed');
@@ -44,12 +44,12 @@ export class Pool {
44
44
  throw new Error('Pool closed');
45
45
  }
46
46
  constructor(params) {
47
- this._available = new Queue();
48
47
  this._total = 0;
49
48
  this._waiting = new Queue();
50
49
  this._isClosed = false;
51
50
  this._config = params;
52
51
  this._max = params.max || 20;
52
+ this._available = new RingQueue(this._max);
53
53
  }
54
54
  /**
55
55
  * Acquires a dedicated connection from the pool.
@@ -1 +1 @@
1
- {"version":3,"file":"connection-request-writer.d.ts","sourceRoot":"","sources":["../../src/protocol/connection-request-writer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAgB,MAAM,aAAa,CAAA;AAGvD,qBAAa,uBAAuB;IAE5B,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,wBAAwB;IAHpC,OAAO;IAOP,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM;IAK3B,OAAO,CAAC,cAAc;IAmBtB,YAAY,CAAC,MAAM,EAAE,MAAM;IAY3B,WAAW,CAAC,MAAM,EAAE,MAAM;IAS1B,UAAU,CAAC,MAAM,EAAE,MAAM;IAUzB,UAAU,CAAC,MAAM,EAAE,MAAM;IAUzB,SAAS,CAAC,IAAI,EAAE,MAAM;IAStB,YAAY,CAAC,WAAW,EAAE,WAAW;IAQrC,YAAY;IAMZ,UAAU;IAUV,QAAQ;IAKR,KAAK;CAIR;AAGD,qBAAa,uBAAuB;IAE5B,OAAO,CAAC,MAAM;IADlB,OAAO;IAIP,MAAM,CAAC,GAAG;IAMV,UAAU,CAAC,IAAI,EAAE,MAAM;IASvB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,EAAE,EAAE,IAAI,EAAE,MAAM;IAW1C,aAAa,CAAC,aAAa,EAAE,MAAM,GAAG,EAAE;IAUxC,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,EAAE,EAAE,aAAa,EAAE,MAAM,GAAG,EAAE,EAAE,MAAM,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE;IAmBtF,UAAU,CAAC,IAAI,EAAE,MAAM;IAUvB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IAY3C,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,EAAE;IAUlC,SAAS;IAOT,aAAa,CAAC,QAAQ,EAAE,MAAM;IAS9B,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM;IAW9D,iBAAiB,CAAC,kBAAkB,EAAE,MAAM;IAS5C,QAAQ;IAKR,KAAK;CAKR"}
1
+ {"version":3,"file":"connection-request-writer.d.ts","sourceRoot":"","sources":["../../src/protocol/connection-request-writer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAgB,MAAM,aAAa,CAAA;AAGvD,qBAAa,uBAAuB;IAE5B,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,wBAAwB;IAHpC,OAAO;IAOP,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM;IAK3B,OAAO,CAAC,cAAc;IAoBtB,YAAY,CAAC,MAAM,EAAE,MAAM;IAY3B,WAAW,CAAC,MAAM,EAAE,MAAM;IAS1B,UAAU,CAAC,MAAM,EAAE,MAAM;IAUzB,UAAU,CAAC,MAAM,EAAE,MAAM;IAUzB,SAAS,CAAC,IAAI,EAAE,MAAM;IAStB,YAAY,CAAC,WAAW,EAAE,WAAW;IAQrC,YAAY;IAMZ,UAAU;IAYV,QAAQ;IAKR,KAAK;CAIR;AAGD,qBAAa,uBAAuB;IAE5B,OAAO,CAAC,MAAM;IADlB,OAAO;IAIP,MAAM,CAAC,GAAG;IAMV,UAAU,CAAC,IAAI,EAAE,MAAM;IASvB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,EAAE,EAAE,IAAI,EAAE,MAAM;IAW1C,aAAa,CAAC,aAAa,EAAE,MAAM,GAAG,EAAE;IAUxC,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,EAAE,EAAE,aAAa,EAAE,MAAM,GAAG,EAAE,EAAE,MAAM,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE;IAmBtF,UAAU,CAAC,IAAI,EAAE,MAAM;IAUvB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IAY3C,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,EAAE;IAUlC,SAAS;IAOT,aAAa,CAAC,QAAQ,EAAE,MAAM;IAS9B,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM;IAW9D,iBAAiB,CAAC,kBAAkB,EAAE,MAAM;IAS5C,QAAQ;IAKR,KAAK;CAKR"}
@@ -61,6 +61,7 @@ export class ConnectionRequestBuffer {
61
61
  return this.writeInt32(0);
62
62
  }
63
63
  endRequest() {
64
+ this.ensureCapacity(4);
64
65
  this.buffer.writeInt32BE(this.offset - (this.lastRequestLenByteOffset), this.lastRequestLenByteOffset);
65
66
  return this;
66
67
  }
package/dist/query.d.ts CHANGED
@@ -1,46 +1,53 @@
1
1
  import { Future } from "fluent-future";
2
- import { QueryText, StatementName } from "./connection";
2
+ import { QueryMeta, QueryText, StatementName } from "./connection";
3
3
  import { ColumnDescription, ValueOF } from "./types";
4
4
  import { PostgresError } from "./error";
5
5
  export declare const QueryState: {
6
6
  readonly Parsing: 0;
7
- readonly Describing: 1;
8
- readonly Executing: 2;
9
- readonly Completed: 3;
10
- readonly Failed: 4;
7
+ readonly Executing: 1;
8
+ readonly Completed: 2;
9
+ readonly Failed: 3;
11
10
  };
12
11
  export type State = ValueOF<typeof QueryState>;
13
- export declare class Query<T> {
12
+ export declare abstract class Query {
13
+ statement: StatementName;
14
+ protected _timer?: NodeJS.Timeout;
15
+ constructor(statement: StatementName);
16
+ startTimeout(timeout: number): void;
17
+ abstract reject(cause: PostgresError): void;
18
+ abstract resolve(...args: any[]): void;
19
+ }
20
+ export declare class SimpleQuery<T> extends Query {
14
21
  text: QueryText;
15
22
  args: (string | null)[];
16
- state: State;
17
- statementName: StatementName;
18
- columns?: ColumnDescription[] | undefined;
23
+ columns: ColumnDescription[];
19
24
  future: Future<T[], PostgresError>;
20
25
  private _resolve;
21
26
  private _reject;
22
27
  private _rows;
23
- private _timer?;
24
- constructor(text: QueryText, args: (string | null)[], state: State, statementName: StatementName, columns?: ColumnDescription[] | undefined);
25
- startTimeout(timeout: number): void;
26
- setState(state: State): void;
28
+ constructor(statement: StatementName, text: QueryText, args: (string | null)[], columns: ColumnDescription[]);
27
29
  push(value: T): void;
28
30
  reject(cause: PostgresError): void;
29
31
  resolve(): void;
30
32
  }
31
- export declare class StreamQuery<T> {
33
+ export declare class ParseQuery extends Query {
34
+ text: QueryText;
35
+ future: Future<QueryMeta, PostgresError>;
36
+ private _resolve;
37
+ private _reject;
38
+ constructor(statement: StatementName, text: QueryText);
39
+ reject(cause: PostgresError): void;
40
+ resolve(meta: QueryMeta): void;
41
+ }
42
+ export declare class StreamQuery<T> extends Query {
32
43
  text: QueryText;
33
44
  args: (string | null)[];
34
- state: State;
35
- statementName: StatementName;
36
- private _controller;
37
- columns?: ColumnDescription[] | undefined;
38
- private _timer?;
39
- constructor(text: QueryText, args: (string | null)[], state: State, statementName: StatementName, _controller: ReadableStreamDefaultController<T>, columns?: ColumnDescription[] | undefined);
40
- setState(state: State): void;
41
- startTimeout(timeout: number): void;
45
+ controller: ReadableStreamDefaultController<T>;
46
+ columns: ColumnDescription[];
47
+ constructor(statement: StatementName, text: QueryText, args: (string | null)[], controller: ReadableStreamDefaultController<T>, columns: ColumnDescription[]);
42
48
  push(value: T): void;
43
49
  reject(cause: PostgresError): void;
44
50
  resolve(): void;
45
51
  }
52
+ export type PostgresQuery = SimpleQuery<any> | ParseQuery | StreamQuery<any>;
46
53
  //# sourceMappingURL=query.d.ts.map