Compare commits

...

1034 Commits

Author SHA1 Message Date
Nigro Simone
8d493f3b55
feat: add Node.js version 25 to CI workflow (#3556)
* feat: add Node.js version 25 to CI workflow

https://nodejs.org/en/blog/release/v25.0.0

* chore: update CI workflow to exclude Node.js version '23'

Remove Node.js version '23' from CI workflow.
2025-10-22 16:20:07 +02:00
Charmander
917478397b
test: Replace dead row length check with similar shape check (#3532)
These object-mode rows don’t include a `length`. Dead code since 721cf56eb331bd35243c1425095b98cf09adf814 (“Rows are now associative arrays rather than straight arrays.”)?
2025-08-22 01:42:17 +00:00
Prasad
f5c90a5484
docs: fix typo in pool docs (#3530) 2025-08-20 06:48:50 -05:00
dependabot[bot]
65bc3d4884
build(deps-dev): bump node-gyp from 11.2.0 to 11.3.0 (#3526)
Bumps [node-gyp](https://github.com/nodejs/node-gyp) from 11.2.0 to 11.3.0.
- [Release notes](https://github.com/nodejs/node-gyp/releases)
- [Changelog](https://github.com/nodejs/node-gyp/blob/main/CHANGELOG.md)
- [Commits](https://github.com/nodejs/node-gyp/compare/v11.2.0...v11.3.0)

---
updated-dependencies:
- dependency-name: node-gyp
  dependency-version: 11.3.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-08 15:04:02 -05:00
James Vaughan
a6c1084db1
Update bugs and homepage links for pg-pool (#3528) 2025-08-05 13:32:06 -05:00
Mathias Bockwoldt
1b2bedc9c8
feat(pg-connection-string): throw correct error when URL parsing fails
Fixes #3513
2025-07-28 08:48:29 -04:00
Brian C
27a2754787
Deprecations (#3510)
* Make active query a private prop

* Make client.queryQueue private (with deprecation)

* Deprecate some legacy features

* Update packages/pg/lib/client.js

Co-authored-by: Charmander <~@charmander.me>

---------

Co-authored-by: Brian Carlson <brian.carlson@getcruise.com>
Co-authored-by: Charmander <~@charmander.me>
2025-07-16 21:52:00 -05:00
Barry Hagan
01fadd93d7
fix #3508 - recheck min client count during idle callback (#3509) 2025-07-10 14:30:48 -05:00
Brian C
43b8692019
Add tests for export (#3507)
* Add tests for export

* Fix
2025-07-08 22:40:13 -05:00
Tommy D. Rossi
fab87b28af
Add package.json export to pg-cloudflare (#3506)
* Update package.json

* Update package.json

* Update package.json
2025-07-08 18:08:40 -05:00
Herman J. Radtke III
c8fb1e9261
feat(pg-connection-string): warn if non-standard ssl options are used (#3473)
* feat(pg-connection-string): warn if non-standard ssl options are used

In preparation for v3.0.0, we start warning users to be explicit about
the sslmode they want.

* Update index.js
2025-07-07 17:33:22 -05:00
dependabot[bot]
54e0424991
build(deps-dev): bump eslint-plugin-prettier from 5.2.6 to 5.5.1 (#3502)
Bumps [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier) from 5.2.6 to 5.5.1.
- [Release notes](https://github.com/prettier/eslint-plugin-prettier/releases)
- [Changelog](https://github.com/prettier/eslint-plugin-prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/eslint-plugin-prettier/compare/v5.2.6...v5.5.1)

---
updated-dependencies:
- dependency-name: eslint-plugin-prettier
  dependency-version: 5.5.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-02 11:57:38 -05:00
dependabot[bot]
235d7ad5e2
build(deps-dev): bump node-gyp from 10.2.0 to 11.2.0 (#3501)
Bumps [node-gyp](https://github.com/nodejs/node-gyp) from 10.2.0 to 11.2.0.
- [Release notes](https://github.com/nodejs/node-gyp/releases)
- [Changelog](https://github.com/nodejs/node-gyp/blob/main/CHANGELOG.md)
- [Commits](https://github.com/nodejs/node-gyp/compare/v10.2.0...v11.2.0)

---
updated-dependencies:
- dependency-name: node-gyp
  dependency-version: 11.2.0
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-02 11:57:28 -05:00
Brian Carlson
8f8e7315e8 Publish
- pg-bundler-test@0.0.2
 - pg-cloudflare@1.2.7
 - pg-cursor@2.15.3
 - pg-esm-test@1.2.3
 - pg-native@3.5.2
 - pg-protocol@1.10.3
 - pg-query-stream@4.10.3
 - pg@8.16.3
2025-06-27 09:51:27 -05:00
Brian C
f0d1c4868a
Update package exports to support more formats (#3500) 2025-06-27 09:51:01 -05:00
Nigro Simone
0ad6c9b71e
fix: typos (#3499)
* fix: typos

* fix: typo
2025-06-26 17:28:43 -05:00
James Opstad
54964ecff7
Replace cloudflare export condition in pg-cloudflare with workerd (#3498)
* Replace cloudflare export condition with workerd

* Add note about Cloudflare Vite plugin
2025-06-26 16:42:08 -05:00
Brian Carlson
1a25d12817 Publish
- pg-cursor@2.15.2
 - pg-esm-test@1.2.2
 - pg-protocol@1.10.2
 - pg-query-stream@4.10.2
 - pg@8.16.2
2025-06-19 16:15:21 -05:00
Herman J. Radtke III
e00aac1398
Fixes for binary protocol array handling (#3494)
* fix(pg-protocol): specify number of result column format codes

Fixes a bug when binary format. We must specify both:

- the number of result column format codes
- the result column format codes

The text format case was working by accident. When using text format, the
intention was to set the format code to 0. Instead, we set the number
of result column format codes was set to 0. This is valid because it indicates
that all result columns should use the default format (text).

When using binary format, the intention was to set the format code to 1.
Instead, we set the number of result column format codes to 1.
Importantly, we never set a result column format code. This caused an
error: 'insufficient data left in message'. 

We now always set the number of result column format codes to '1'. The
value of '1' has special meaning:

> or one, in which case the specified format code is applied to all result columns (if any)

We then set a single column format code based on whether the connection
(or query) is set to binary.


Fixes #3487

* fix(pg): use a Buffer when parsing binary

The call to parseArray was not working as expected because the value was
being sent as a string instead of a Buffer. The binary parsers in
pg-types all assume the incoming value is a Buffer.
2025-06-19 15:37:04 -05:00
Brian Carlson
cd877a5761 Publish
- pg-bundler-test@0.0.1
 - pg-cloudflare@1.2.6
 - pg-connection-string@2.9.1
 - pg-cursor@2.15.1
 - pg-esm-test@1.2.1
 - pg-native@3.5.1
 - pg-pool@3.10.1
 - pg-protocol@1.10.1
 - pg-query-stream@4.10.1
 - pg@8.16.1
2025-06-18 10:46:26 -05:00
Brian C
607efc1b6e
Bump engines since we do not test lower than 16 anymore (#3490) 2025-06-16 22:07:55 -05:00
Joan Miquel Torres
14dc8dd100
Use performance.now() instead of Date.now()... (#3483)
* Use performance.now() instead of Date.now()...

  * Wherever applicable (measuring performance, not time).
  * Failback to support node < 16.0.0 (perf_hook not globally exposed)
  * Failback to Date.now() for node < 8.5.0

  ✔ Tests passed with node > 16.0.0 (22.12.0)
  ✕ Couldn't pass with node prior 16.0.0 but not due to this changes.

https://nodejs.org/docs/latest-v8.x/api/perf_hooks.html#perf_hooks_performance_now
https://w3c.github.io/hr-time/

* Yarn prettier

* More lint fixes.

* Removed polyfill code for node <16

They are no longer supported:

https://github.com/brianc/node-postgres/pull/3483#issuecomment-2967119692
2025-06-14 16:38:51 -05:00
Brian C
8608fb84c8
fix: do not concatenate an array if passed to escapeLiteral. (#3489) 2025-06-14 16:36:32 -05:00
Tommy D. Rossi
114a03e887
Add package.json in exports (#3488) 2025-06-14 16:32:26 -05:00
Brian C
7ab5923fad
Redact input URL string to prevent console printing (#3486) 2025-06-13 22:59:32 -05:00
Henry Cai
6b016b37d4
fix(pg-cloudflare): use conditional export to support bundlers that don't know about cloudflare:sockets (#3482) 2025-06-12 09:31:57 -05:00
Johan Fagerberg
0ada72e608
docs: add maxLifetimeSeconds to Pool docs (#3484)
Wording taken from https://github.com/brianc/node-postgres/issues/3298#issuecomment-2305207256
2025-06-12 09:24:03 -05:00
dependabot[bot]
03642abec1
build(deps-dev): bump semver from 4.3.6 to 7.7.2 (#3477)
Bumps [semver](https://github.com/npm/node-semver) from 4.3.6 to 7.7.2.
- [Release notes](https://github.com/npm/node-semver/releases)
- [Changelog](https://github.com/npm/node-semver/blob/main/CHANGELOG.md)
- [Commits](https://github.com/npm/node-semver/compare/v4.3.6...v7.7.2)

---
updated-dependencies:
- dependency-name: semver
  dependency-version: 7.7.2
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-05 12:40:05 -05:00
dependabot[bot]
a4888ee028
build(deps-dev): bump eslint-plugin-promise from 6.2.0 to 7.2.1 (#3479)
Bumps [eslint-plugin-promise](https://github.com/eslint-community/eslint-plugin-promise) from 6.2.0 to 7.2.1.
- [Release notes](https://github.com/eslint-community/eslint-plugin-promise/releases)
- [Changelog](https://github.com/eslint-community/eslint-plugin-promise/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint-community/eslint-plugin-promise/compare/v6.2.0...v7.2.1)

---
updated-dependencies:
- dependency-name: eslint-plugin-promise
  dependency-version: 7.2.1
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-05 12:39:52 -05:00
Herman J. Radtke III
411869df65
pool.end() resolves before the last pool.query() (#3461)
* Pass callback to client.end

* Add test for pool.end method

* fix: remove excessive _pulseQueue call

* fix: context problem

* fix: test resolve should be called when the last client is removed

* fix: wait for pool.end()

Because when you don't pass a callback to .end() it always returns a promise

* fix: handle idle timeout test data race

---------

Co-authored-by: Asadbek Raimov <asadbekraimov642@gmail.com>
2025-05-29 17:12:24 -05:00
Herman J. Radtke III
26ace0ac8f fix(pg-connection-string): remove .nyc_output 2025-05-27 09:32:54 -04:00
Ryan Staples
3e7bd2f681
Change instanceof(Date) to util.types.isDate(Date) (#2862)
* change instanceof to isDate

* use both methods to check for valid Date

* add test for PR 2862

* use only isDate(date) in place of instanceof Date

* Extend compatibility of `isDate` use back to Node 8

* Clean up test

---------

Co-authored-by: Charmander <~@charmander.me>
Reviewed-by: Charmander <~@charmander.me>
2025-05-26 22:37:13 +00:00
Noritaka Kobayashi
9cf2184d09
refactor: remove unused import & fix typos in docs (#3471) 2025-05-25 11:30:11 -05:00
Noritaka Kobayashi
c9353acbc0
chore: fix typos in README (#3470) 2025-05-25 09:56:54 -05:00
Brian C
26fa32c133
Update theme.config.js (#3468) 2025-05-15 19:40:03 -05:00
Lorentz Lasson
a47c480055 fix sslcompat remains 2025-05-14 13:50:38 -04:00
Brian Carlson
abff18d6f9 Publish
- pg-connection-string@2.9.0
 - pg-cursor@2.15.0
 - pg-esm-test@1.2.0
 - pg-native@3.5.0
 - pg-pool@3.10.0
 - pg-protocol@1.10.0
 - pg-query-stream@4.10.0
 - pg@8.16.0
2025-05-12 11:49:59 -05:00
Brian Carlson
e43d4b7eb6 Update changelog 2025-05-12 11:49:41 -05:00
Herman J. Radtke III
e8fde07227
chore: document keepAliveInitialDelayMillis option (#3460) 2025-05-12 01:15:55 -05:00
Brian C
27f34c6aee
Bump libpq & nan version dep for node24 compat (#3462) 2025-05-12 01:07:01 -05:00
maltewirz
e30b41d481
Update connecting.mdx (#3266)
Changes tested myself and inspired by documention on aws rds signer https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/Package/-aws-sdk-rds-signer/
2025-05-10 22:23:27 -05:00
Herman J. Radtke III
6be857e9d3 chore(pg-connection-string): use tsx for tests 2025-05-06 06:49:24 -04:00
dependabot[bot]
9bfc967e91
build(deps-dev): bump eslint-config-prettier from 9.1.0 to 10.1.2 (#3453)
Bumps [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) from 9.1.0 to 10.1.2.
- [Release notes](https://github.com/prettier/eslint-config-prettier/releases)
- [Changelog](https://github.com/prettier/eslint-config-prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/eslint-config-prettier/compare/v9.1.0...v10.1.2)

---
updated-dependencies:
- dependency-name: eslint-config-prettier
  dependency-version: 10.1.2
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-01 12:33:50 -05:00
dependabot[bot]
79351af32e
build(deps-dev): bump eslint-plugin-prettier from 5.2.5 to 5.2.6 (#3455)
Bumps [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier) from 5.2.5 to 5.2.6.
- [Release notes](https://github.com/prettier/eslint-plugin-prettier/releases)
- [Changelog](https://github.com/prettier/eslint-plugin-prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/eslint-plugin-prettier/compare/v5.2.5...v5.2.6)

---
updated-dependencies:
- dependency-name: eslint-plugin-prettier
  dependency-version: 5.2.6
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-01 12:33:37 -05:00
dependabot[bot]
52ec1293f2
build(deps-dev): bump @cloudflare/vitest-pool-workers (#3456)
Bumps [@cloudflare/vitest-pool-workers](https://github.com/cloudflare/workers-sdk/tree/HEAD/packages/vitest-pool-workers) from 0.8.12 to 0.8.23.
- [Release notes](https://github.com/cloudflare/workers-sdk/releases)
- [Changelog](https://github.com/cloudflare/workers-sdk/blob/main/packages/vitest-pool-workers/CHANGELOG.md)
- [Commits](https://github.com/cloudflare/workers-sdk/commits/@cloudflare/vitest-pool-workers@0.8.23/packages/vitest-pool-workers)

---
updated-dependencies:
- dependency-name: "@cloudflare/vitest-pool-workers"
  dependency-version: 0.8.23
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-01 12:33:24 -05:00
Brian C
2647f7ecaf
Create README.md (#3451) 2025-04-30 20:20:35 -05:00
Brian C
980752ce00
Hard-pin 3rd party dependencies (#3450)
Co-authored-by: Brian Carlson <brian.carlson@getcruise.com>
2025-04-29 13:34:14 -05:00
francesco
264e30f424
docs: require to import (#3448) 2025-04-29 11:06:32 -05:00
Davide Violante
f528433e9d
chore: minor eslint fixes, reenable no-unused vars (#3445) 2025-04-28 11:59:26 -05:00
Davide Violante
93aa1ba2f1
chore: replace var with const in md files (#3446) 2025-04-28 09:54:46 +00:00
Brian C
9e7a5d97cf
Replace all usages of var with let / const - eslint auto applied (#3444) 2025-04-27 11:50:33 -05:00
Brian C
7a009381e6
Update pool docs (#3442)
* Update docs for pool

* Letting my robot overlords proofread for me

---------

Co-authored-by: Brian Carlson <brian.carlson@getcruise.com>
2025-04-25 15:21:44 -05:00
Harish T
ff40638868
Support Min connection pool parameter #3009 (#3438)
* Support Min connection pool parameter #3009

* Remove extraneous change

* streamline code
2025-04-25 14:41:02 -05:00
Brian C
229de3006b
Remove circluar dep for test dependency - I think this is managed w learna and not needed (#3441)
Co-authored-by: Brian Carlson <brian.carlson@getcruise.com>
2025-04-25 14:34:31 -05:00
Brian Carlson
81d875fe09 Publish
- pg-cursor@2.14.6
 - pg-esm-test@1.1.6
 - pg-pool@3.9.6
 - pg-query-stream@4.9.6
 - pg@8.15.6
2025-04-25 14:09:08 -05:00
Brian C
39e134d0b5
Make pg-cursor compatible with older versions of pg (#3440)
Co-authored-by: Brian Carlson <brian.carlson@getcruise.com>
2025-04-24 15:12:48 -05:00
Brian C
0c1629bea2
Update docs - add ESM info
* Update docs - start

* Add logo & discord

* Start updating docs for esm style imports

* Update docs with logo & info on pooling

* Update more import statements

---------

Co-authored-by: Brian Carlson <brian.carlson@getcruise.com>
2025-04-23 16:46:21 -05:00
Brian Carlson
56e2862577 Publish
- pg-cloudflare@1.2.5
 - pg-connection-string@2.8.5
 - pg-cursor@2.14.5
 - pg-esm-test@1.1.5
 - pg-native@3.4.5
 - pg-pool@3.9.5
 - pg-protocol@1.9.5
 - pg-query-stream@4.9.5
 - pg@8.15.5
2025-04-23 13:48:25 -05:00
Brian Carlson
2919f28d31 Manually advance patch versions to re-align with lerna 2025-04-23 13:48:13 -05:00
Brian Carlson
36fd0a61db Only allow publish from master 2025-04-23 13:46:01 -05:00
Brian C
6ab0c4608c
More tests & exports from pg-protocol (#3436) 2025-04-23 13:22:31 -05:00
Brian C
ad3e6035f4
Expose TypeOverrides in esm & cjs from root of package (#3433) 2025-04-23 12:37:52 -05:00
Brian C
e8280d58f6
Add tests for issues fixed in #3428 (#3432) 2025-04-23 11:53:54 -05:00
Breno A.
2da196cc1f
fix(exports): resolve issues with module imports and requires (#3428)
* fix(exports): resolve issues with module imports and requires

* fix(pg-native): add support for lib module resolution in package.json
2025-04-23 11:39:35 -05:00
Meghan Denny
bbc84b2690 pg-connection-string: fix 'parse' type signature 2025-04-23 10:43:34 -04:00
Brian Carlson
fb25f7bdb3 Publish
- pg-connection-string@2.8.1
 - pg-cursor@2.14.1
 - pg-esm-test@1.1.1
 - pg-pool@3.9.1
 - pg-query-stream@4.9.1
 - pg@8.15.1
2025-04-22 15:27:31 -05:00
Herman J. Radtke III
557716d1fa
fix(pg-connection-string): export default from esm wrapper (#3425)
Prior to v2.8.0, the parse function was the default when using import.
When esm compatibility was introduced in v2.8.0, there was not default
specified. This broke existing code that relied on that default.

Fixes #3424
2025-04-22 15:24:48 -05:00
Herman J. Radtke III
9cc7d8eb94
docs: add missing parameters on pg.Client Config (#3422)
- client_encoding
- fallback_application_name
- options
2025-04-22 11:04:17 -05:00
Brian Carlson
9ec9e5f58d Publish
- pg-cloudflare@1.2.0
 - pg-connection-string@2.8.0
 - pg-cursor@2.14.0
 - pg-esm-test@1.1.0
 - pg-native@3.4.0
 - pg-pool@3.9.0
 - pg-protocol@1.9.0
 - pg-query-stream@4.9.0
 - pg@8.15.0
2025-04-22 10:55:24 -05:00
Brian Carlson
60817cd914 Update changelog 2025-04-22 10:55:10 -05:00
Brian C
940479bc4b
Add esm exports (#3423)
* build: add esm exports

* fix: add defaults as per arethetypeswrong report

* fix: add missing types

* lint

* Fix broken tests

* Add (failing) test for esm compat

* Begin moving files to proper extension and adding tests

* Add tests for connection-string and fix cloudflare module type and esm compat

* Add query-stream and cursor as esm exports

* Update PR copilot review

* Publish

 - pg-cloudflare@1.1.2-alpha.0
 - pg-connection-string@2.7.1-alpha.0
 - pg-cursor@2.13.2-alpha.0
 - pg-esm-test@1.0.1-alpha.0
 - pg-native@3.3.1-alpha.0
 - pg-pool@3.8.1-alpha.0
 - pg-protocol@1.8.1-alpha.0
 - pg-query-stream@4.8.2-alpha.0
 - pg@8.14.2-alpha.0

* More cf compat work

* Publish

 - pg-cloudflare@1.1.2-alpha.1
 - pg-cursor@2.13.2-alpha.1
 - pg-esm-test@1.0.1-alpha.1
 - pg-pool@3.8.1-alpha.1
 - pg-query-stream@4.8.2-alpha.1
 - pg@8.14.2-alpha.1

* Add more cf compat and update tests

* Make tests pass - update exports for esm

* Use env vars for test connection in cf tests

* Fix lint

* Fit vitest into existing legacy framework

* Skip worker tests on node below 18

* Revert doc changes for now

* Remove legacy worker test in favor of vitest

---------

Co-authored-by: Luca Ban <mesqueeb@users.noreply.github.com>
2025-04-22 10:53:22 -05:00
Patrick Malouin
81ec0635fc
feat(pg-connection-string): get closer to libpq semantics for sslmode
Allows user to change the semantics of `sslmode` to be as close as possible to libpq semantics. The opt in can be enabled using `useLibpqCompat` parsing option or the non-standard `uselibpqcompat` query string parameter.

---------

Co-authored-by: Charmander <~@charmander.me>
Co-authored-by: Herman J. Radtke III <herman@hermanradtke.com>
2025-04-20 08:13:33 -04:00
Charmander
d8fb2f9c35
test: Avoid silencing errors from idle timeout test’s child process (#3419)
This hid the error fixed in #3263, for example.
2025-04-13 07:18:33 +00:00
Alex Anderson
9b510373a6
eslint: enable recommended ruleset (#3263) 2025-04-12 08:17:33 +00:00
Herman J. Radtke III
5a8b1a7d24 feat(pg-connection-string): ClientConfig helper functions
Two new functions are introduced to make it easy for TypeScript
users to use a PostgresSQL connection string with pg Client.

Fixes #2280
2025-04-08 20:06:28 -04:00
Charmander
a9fd34fb42
Revert "docs: fix bug in transaction example (#3414)"
This reverts commit dcb4257898d1d8d37110a4364922206dad33f9fe.

The change doesn’t fix the bug it claims to (`finally` always runs) and introduces a resource leak if the `ROLLBACK` query fails. The related bug that a broken client can be returned to the pool remains unaffected either way.
2025-04-03 15:10:49 -07:00
dependabot[bot]
a5d03a0774
build(deps-dev): bump eslint-plugin-prettier from 5.1.2 to 5.2.5 (#3412)
Bumps [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier) from 5.1.2 to 5.2.5.
- [Release notes](https://github.com/prettier/eslint-plugin-prettier/releases)
- [Changelog](https://github.com/prettier/eslint-plugin-prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/eslint-plugin-prettier/compare/v5.1.2...v5.2.5)

---
updated-dependencies:
- dependency-name: eslint-plugin-prettier
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-01 15:38:44 -05:00
lucaesposto
dcb4257898
docs: fix bug in transaction example (#3414)
Throwing error will not allow "finally" execution, so client.release() must be invoked before it.
2025-04-01 15:38:14 -05:00
Brian Carlson
a3fefe3183 Update sponsorship info 2025-03-22 10:58:51 -05:00
Brian Carlson
477f812984 Publish
- pg-cursor@2.13.1
 - pg-query-stream@4.8.1
 - pg@8.14.1
2025-03-17 10:37:54 -05:00
Brian C
c53a472a60
Batch network packets in prepared statements (#3402)
* Batch network packets in prepared statements

Fixes #3340
Fixes #3325
Fixes #3098

* Fix type-o but mostly retrigger build for CF pages preview
2025-03-17 10:28:46 -05:00
Brian Carlson
f7c92e487c Publish
- pg-cursor@2.13.0
 - pg-native@3.3.0
 - pg-pool@3.8.0
 - pg-protocol@1.8.0
 - pg-query-stream@4.8.0
 - pg@8.14.0
2025-03-11 10:25:26 -05:00
Brian Carlson
1c45dd2828 Update changelog 2025-03-11 10:25:12 -05:00
Alex Anderson
b823a23f67
simple-query-tests: remove no-op test (#3390)
Originally skipped in daa370a61

Co-authored-by: alxndrsn <alxndrsn>
2025-03-10 13:14:01 -05:00
George MacKerron
b4022aa5c0
Add support for SCRAM-SHA-256-PLUS i.e. channel binding (#3356)
* Added support for SCRAM-SHA-256-PLUS i.e. channel binding

* Requested tweaks to channel binding

* Additional tweaks to channel binding

* Fixed lint complaints

* Update packages/pg/lib/crypto/sasl.js

Co-authored-by: Charmander <~@charmander.me>

* Update packages/pg/lib/crypto/sasl.js

Co-authored-by: Charmander <~@charmander.me>

* Update packages/pg/lib/client.js

Co-authored-by: Charmander <~@charmander.me>

* Tweaks to channel binding

* Now using homegrown certificate signature algorithm identification

* Update ssl.mdx with channel binding changes

* Allow for config object being undefined when assigning enableChannelBinding

* Fixed a test failing on an updated error message

* Removed - from hash names like SHA-256 for legacy crypto (Node 14 and below)

* Removed packageManager key from package.json

* Added some SASL/channel binding unit tests

* Added a unit test for continueSession to check expected SASL session data

* Modify tests: don't require channel binding (which cannot then work) if not using SSL

---------

Co-authored-by: Charmander <~@charmander.me>
2025-03-10 13:13:32 -05:00
francesco
1876f2000a
Add "unref" to timers (#3396)
* chore: add unref to timer

see https://nodejs.org/api/timers.html#timeoutunref

* chore: add unref to timer

see https://nodejs.org/api/timers.html#timeoutunref

* fix: lint

* fix: lint

* fix: lint

* fix: lint
2025-03-10 12:16:57 -05:00
Alex Anderson
88311c17a5
test-helper: re-add missing function spit() (#3248)
It looks like this was removed in d615ebee177ed57c7a7df861b1db675c9e0ebb0f while it still had references to it.

Reviewed-by: Charmander <~@charmander.me>
2025-02-20 01:34:23 +00:00
Nigro Simone
5a6734429c
fix(devcontainer): upgrade node to version 20 (#3385)
* fix(devcontainer): upgrade node to version 20

* chore: since Windows and Linux use different default line endings, Git may report a large number of modified files that have no differences aside from their line endings.
2025-02-13 17:22:50 -06:00
dependabot[bot]
79ee1ad15f
build(deps-dev): bump workerd from 1.20240529.0 to 1.20250129.0 (#3366)
Bumps [workerd](https://github.com/cloudflare/workerd) from 1.20240529.0 to 1.20250129.0.
- [Release notes](https://github.com/cloudflare/workerd/releases)
- [Changelog](https://github.com/cloudflare/workerd/blob/main/RELEASE.md)
- [Commits](https://github.com/cloudflare/workerd/compare/v1.20240529.0...v1.20250129.0)

---
updated-dependencies:
- dependency-name: workerd
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-13 09:46:54 -06:00
dependabot[bot]
1230c86ba9
build(deps-dev): bump lodash from 2.4.2 to 4.17.21 (#3367)
Bumps [lodash](https://github.com/lodash/lodash) from 2.4.2 to 4.17.21.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/2.4.2...4.17.21)

---
updated-dependencies:
- dependency-name: lodash
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-13 09:42:45 -06:00
Charmander
582cdaf919
Assorted test fixes and cleanup (#3383)
* test: Actually test split messages in split message parsing test

* cleanup: Fix spelling in tests

* test: Wait on asynchronous tests

* cleanup: Remove unused parameter from test method `BufferList#getByteLength`

If someone did want this functionality, it would be better to use addition separate from the method anyway.

* cleanup: Remove unused test function `BufferList.concat`
2025-02-13 09:42:33 -06:00
Brian Carlson
5755b78386 Publish
- pg-cursor@2.12.3
 - pg-native@3.2.2
 - pg-query-stream@4.7.3
 - pg@8.13.3
2025-02-12 18:29:56 -06:00
francesco
f6e829c564
fix: revert PR #3379 (avoid useless spread) (#3382)
* Update result.js

* Update build-result.js

* fix: lint

* fix: lint
2025-02-12 18:28:05 -06:00
Brian Carlson
732580782f Publish
- pg-cursor@2.12.2
 - pg-native@3.2.1
 - pg-pool@3.7.1
 - pg-protocol@1.7.1
 - pg-query-stream@4.7.2
 - pg@8.13.2
2025-02-11 10:19:52 -06:00
Brian Carlson
2dc9e7f2fd Update lockfile 2025-02-11 10:19:26 -06:00
francesco
5f6a6e6596
perf(pg): avoid useless spread (#3379)
* perf(pg): avoid useless spread

* fix: missing initialization
2025-02-11 10:13:15 -06:00
francesco
f1586932fd
perf(pg-native): pre-shaped result rows (#3369)
* perf(pg-native): pre-shaped result rows

Porting on pg-native https://github.com/brianc/node-postgres/issues/3042

* fix: lint

* perf(pg-native): avoid useless spread
2025-02-11 10:12:10 -06:00
francesco
0792f0904a
Update libpq to 1.8.14 and fix #3332 (#3364)
* Update libpq to 1.8.14 and fix #3332

Update libpq to 1.8.14 and fix #3332

* Add node 23
2025-02-11 10:11:25 -06:00
Andy Young
95bec690b3
fix(pg-pool): don't throw on readonly .message e.g. ErrorEvent, preserve original exception (#3374)
* fix(pg-pool): preserve original error on connection timeout, don't throw on readonly .message e.g. ErrorEvent

Fixes https://github.com/brianc/node-postgres/issues/3373

* Fix lint
2025-02-10 16:27:55 -06:00
francesco
751e7410d9
perf(utils): fast prepareValue (#3370)
* perf(utils): fast prepareValue

This PR add a performance improvements at prepare Value for non-object by skipping useless condition

* fix: lint

* fix: case of undefined

* fix: review
2025-02-10 16:26:33 -06:00
francesco
f10f569a8a
perf(utils): replace pad with String.padStart (#3371) 2025-02-07 23:59:58 +00:00
Nigro Simone
3c48f22b22
perf: pre allocate array instead of push item (#3250)
* fix: typo

* perf: pre allocate array instead of push item

* perf: refractoring missing push

* perf: avoid useless varible declaration

* perf: short control flow

* fix: lint

* more precise bench

* fix: lint
2025-01-17 15:27:35 -06:00
Arya
2de02f0a63
updated pg-native github url in package.json (#3320) 2025-01-13 13:32:45 -06:00
francesco
f12e555b73
chore: align pg-types to vanilla (#3336) 2025-01-13 13:31:25 -06:00
Davide Violante
39e5ef8370
chore: update README.md, add how to install (#3339)
Fix #3314
2025-01-13 13:30:28 -06:00
Alexandre Weinberger
9fbcf17908
read dataTypeID and tableID as unsigned uint (#3347)
* read dataTypeID and tableID as unsigned uint

this is causing issues in other projects, like https://github.com/sequelize/sequelize/issues/15466

* added tests for oids larger than 2^31
2025-01-13 13:28:25 -06:00
Islam
373093d176
docs: fix pg-pool readme grammar (#3350)
[skip ci]
2024-12-08 08:14:53 +00:00
Brian Carlson
95d7e620ef Publish
- pg-cursor@2.12.1
 - pg-query-stream@4.7.1
 - pg@8.13.1
2024-10-24 10:40:28 -05:00
Brian Carlson
072015ac0f Update changelog 2024-10-24 10:40:05 -05:00
Antariksh Mahajan
1af6321219
fix: use existing Result types for new Result (#3310)
* fix: use existing Result types for new Result

* test: add test for multiple results with custom type parser

* chore: empty commit to trigger tests
2024-10-23 17:05:33 -05:00
dependabot[bot]
8b2768f91d
Bump node-gyp from 10.1.0 to 10.2.0 (#3324)
Bumps [node-gyp](https://github.com/nodejs/node-gyp) from 10.1.0 to 10.2.0.
- [Release notes](https://github.com/nodejs/node-gyp/releases)
- [Changelog](https://github.com/nodejs/node-gyp/blob/main/CHANGELOG.md)
- [Commits](https://github.com/nodejs/node-gyp/compare/v10.1.0...v10.2.0)

---
updated-dependencies:
- dependency-name: node-gyp
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-08 17:49:54 +00:00
Brian Carlson
92cb640fd3 Publish
- pg-connection-string@2.7.0
 - pg-cursor@2.12.0
 - pg-native@3.2.0
 - pg-pool@3.7.0
 - pg-protocol@1.7.0
 - pg-query-stream@4.7.0
 - pg@8.13.0
2024-09-17 10:08:42 -05:00
Brian C
f73b22f96e
Handle bad message ordering - make it catchable. Fixes 3174 (#3289)
* Handle bad message ordering - make it catchable. Fixes 3174

* Close client in test

* Mess w/ github action settings

* update ci config

* Remove redundant tests

* Update code to use handle error event

* Add tests for commandComplete message being out of order

* Lint fix

* Fix native tests

* Fix lint again...airport computer not my friend

* Not a native issue
2024-09-17 09:50:17 -05:00
Joan Miquel Torres
92bb9a24b7
Little improvement README's to dev-setup section. (#3297)
Inserted a reminder to install libpq-dev before running `yarn lerna
bootstrap`.

It's pretty straightforward in light of the error messages, but I cloned
the repo twice and failed both times.
2024-09-17 09:31:55 -05:00
dependabot[bot]
fb12280340
Bump bluebird from 3.4.1 to 3.7.2 (#3303)
Bumps [bluebird](https://github.com/petkaantonov/bluebird) from 3.4.1 to 3.7.2.
- [Release notes](https://github.com/petkaantonov/bluebird/releases)
- [Commits](https://github.com/petkaantonov/bluebird/compare/v3.4.1...v3.7.2)

---
updated-dependencies:
- dependency-name: bluebird
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-17 09:31:21 -05:00
dependabot[bot]
54eb0fa216
Bump mocha and @types/mocha (#3273)
Bumps [mocha](https://github.com/mochajs/mocha) and [@types/mocha](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/mocha). These dependencies needed to be updated together.

Updates `mocha` from 3.4.2 to 10.5.2
- [Release notes](https://github.com/mochajs/mocha/releases)
- [Changelog](https://github.com/mochajs/mocha/blob/main/CHANGELOG.md)
- [Commits](https://github.com/mochajs/mocha/compare/v3.4.2...v10.5.2)

Updates `@types/mocha` from 5.2.7 to 10.0.7
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/mocha)

---
updated-dependencies:
- dependency-name: mocha
  dependency-type: direct:development
  update-type: version-update:semver-major
- dependency-name: "@types/mocha"
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-25 12:20:59 -05:00
Nigro Simone
b5281f5b0a
fix devcontainer (#3251)
* fix devcontainer

* fix scam autentication required

* fix connection

* install pg native lib

* fix: host

* Update devcontainer.json

* Update docker-compose.yml

* Update index.js
2024-06-24 15:16:15 -05:00
Brian C
50c06f9bc6
Remove test globals (#3264)
* Remove assert from globals

* Remove Client from globals

* Remove global test function

* Remove MemoryStream from globals

* Require assert in SASL integration tests

* Attempt to use a postgres with ssl?

* Use latest image

* Remove connection tests - they test internals that are better covered by testint the client
2024-06-19 13:46:16 -05:00
Pete Bacon Darwin
f7e484ed61
refactor: tighten up cloudflare detection (#3170)
* refactor: tighten up cloudflare detection

The previous approach to detecting whether to use Cloudflare's sockets was to check for missing polyfills.
But as we improve the polyfills that Wrangler can provide these checks are no longer valid.

Now we just try to use the Cloudflare API first and fallback to Node.js if those are not available.

* fixup! refactor: tighten up cloudflare detection
2024-06-19 13:28:01 -05:00
Brian C
3e4d545c20
Fix lint (#3262) 2024-06-19 09:45:52 -05:00
srieding
9baa56eaa2
feat: allow specifying a timeout on a per query base (#3074) 2024-06-19 09:36:35 -05:00
Herman J. Radtke III
b7d5b3b667
chore: add codeowners file (#3129)
This makes it clear who is maintaining which package. This will also
allow commit privileges for a specific package instead of the entire
repo.
2024-06-19 09:35:09 -05:00
Alex Anderson
4f457e12e0
Remove unused file: list-db-types (#3249)
Co-authored-by: alxndrsn <alxndrsn>
2024-06-19 09:32:52 -05:00
Brian C
53dc4e6cb3
Add test for date type (#3261) 2024-06-19 09:32:16 -05:00
Alex Anderson
83a0e3e90e
eslint: enable rule: @typescript-eslint/no-unused-vars (#3247)
When enabling this rule, it's recommended to also *disable* the standard `no-unused-vars` rule.  Although `no-unused-vars` is not currently enabled, it seems helpful to explicitly disable it here.

See: https://typescript-eslint.io/rules/no-unused-vars/

Co-authored-by: alxndrsn <alxndrsn>
2024-06-18 15:55:17 -05:00
Alex Anderson
a24a24dea1
test/connection/inbound-parser: remove unused vars (#3245)
Co-authored-by: alxndrsn <alxndrsn>
2024-06-05 11:00:26 -05:00
Alex Anderson
d650741eea
lib/client: remove no-op statement (#3240)
This looks like it was a refactoring of

  var connectionTimeoutHandle;

Co-authored-by: alxndrsn <alxndrsn>
2024-06-05 11:00:04 -05:00
Alex Anderson
d1548d6e77
docs/apis.result: fix typo (#3238)
Co-authored-by: alxndrsn <alxndrsn>
2024-06-05 10:59:45 -05:00
Alex Anderson
cc419341e8
CHANGELOG: fix typo (#3239)
Co-authored-by: alxndrsn <alxndrsn>
2024-06-05 10:59:25 -05:00
Alex Anderson
e4cb1cdc38
client/escape-tests: remove unused function (#3244)
Co-authored-by: alxndrsn <alxndrsn>
2024-06-05 10:51:56 -05:00
Alex Anderson
cd73e9bf86
pg-native/test: remove unused "done" arg from describe() calls (#3242)
Co-authored-by: alxndrsn <alxndrsn>
2024-06-05 10:51:34 -05:00
Alex Anderson
f2279f3529
pg-connection-string/test: remove unused var (#3243)
Co-authored-by: alxndrsn <alxndrsn>
2024-06-05 10:51:13 -05:00
Alex Anderson
1625861981
Remove unused imports (#3241)
* Remove unused imports

* reinstate test helper

---------

Co-authored-by: alxndrsn <alxndrsn>
2024-06-05 10:50:52 -05:00
Alex Anderson
6e96e45bae
test/type-coercion: fix typo in test title (#3237)
`timestamptz` was written `timestampz`

Co-authored-by: alxndrsn <alxndrsn>
2024-06-05 10:50:16 -05:00
Alex Anderson
ba07d19459
docs: fix typos in announcements (#3236)
Co-authored-by: alxndrsn <alxndrsn>
2024-06-05 10:49:28 -05:00
Brian C
f41afdafe6
Add pg-native link to monorepo readme (#3235)
Should add it here, I suppose, for consistency.
2024-06-04 12:46:17 -05:00
Brendan Irvine-Broque
5c846ca06e
Clarify usage and update readme (#3114)
refs https://github.com/Ethan-Arrowood/socket/pull/17

@petebacondarwin @brianc — publishing `pg-cloudflare` as a separate package seems to be really helpful to people. Ex:

https://github.com/sidorares/node-mysql2/pull/2289/files#diff-e56fabfb5e90fd8f6265cfbe84f3701a85261d884e198bf61de34958cee4864aR12

Added some docs to clarify usage, and cross link to the Node.js implementation of the Socket API.

Co-authored-by: Brian Carlson <brian.m.carlson@gmail.com>
2024-06-04 11:49:30 -05:00
Brian C
7fcf941a33
Improve race condition in pg-native cancel test (#3234) 2024-06-04 11:39:52 -05:00
Brian Carlson
b3f0dddbcf Update changelog 2024-06-04 11:21:07 -05:00
Brian Carlson
0f42880861 Publish
- pg-cursor@2.11.0
 - pg-native@3.1.0
 - pg-query-stream@4.6.0
 - pg@8.12.0
2024-06-04 11:19:08 -05:00
Alex Anderson
ff47a97f28
Add option to force use of Extended Queries (#3214)
This feature can be used as follows:

```
client.query({ text: 'SELECT 1', queryMode: 'extended' })
```

This will force the query to be sent with parse/bind/execute even when it has no parameters and disallows multiple statements being executed.  This can be useful in scenarios where you want to enforce more security & help prevent sql injection attacks...particularly by library authors.

---------

Co-authored-by: alxndrsn <alxndrsn>
Co-authored-by: Brian Carlson <brian.m.carlson@gmail.com>
2024-06-04 11:14:04 -05:00
Brian C
fe88e825e5
Add pg-native to monorepo (#3225)
I didn't do much to "modernize" the pg-native codebase other than running it through the standard eslint --fix that is applied to the rest of the code. There's some easy opportunities there to update it to es6 and so on...it still uses some pretty antiquated coding styles in places.  This PR re-introduces the native tests on node v20, and updates test matrix to drop unsupported versions of node & add in node v22.
2024-06-04 10:26:11 -05:00
dependabot[bot]
46156956e2
Bump workerd from 1.20240329.0 to 1.20240529.0 (#3227)
Bumps [workerd](https://github.com/cloudflare/workerd) from 1.20240329.0 to 1.20240529.0.
- [Release notes](https://github.com/cloudflare/workerd/releases)
- [Changelog](https://github.com/cloudflare/workerd/blob/main/RELEASE.md)
- [Commits](https://github.com/cloudflare/workerd/compare/v1.20240329.0...v1.20240529.0)

---
updated-dependencies:
- dependency-name: workerd
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-04 09:36:29 -05:00
dependabot[bot]
988314ae00
Bump eslint-plugin-promise from 6.0.1 to 6.2.0 (#3229)
Bumps [eslint-plugin-promise](https://github.com/eslint-community/eslint-plugin-promise) from 6.0.1 to 6.2.0.
- [Release notes](https://github.com/eslint-community/eslint-plugin-promise/releases)
- [Changelog](https://github.com/eslint-community/eslint-plugin-promise/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint-community/eslint-plugin-promise/compare/v6.0.1...v6.2.0)

---
updated-dependencies:
- dependency-name: eslint-plugin-promise
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-01 22:45:16 -05:00
Alex Anderson
e25428c8dc
eslint: use cache (#3218)
This significantly speeds up eslint after first run.

Co-authored-by: alxndrsn <alxndrsn>
2024-05-16 11:32:41 -05:00
Wes Lord
81e2ff0524
Update reference in docs from done to release (#3211) 2024-05-15 17:04:16 -05:00
Brian C
0cebc513e3
Add tea contract (#3216) 2024-05-15 17:00:11 -05:00
Juan GP
0096856e2e
reorder user-password-host-port-database appearences (#3207) 2024-05-10 12:03:11 -05:00
dependabot[bot]
13ec7d106e
Bump @typescript-eslint/eslint-plugin from 6.17.0 to 7.0.0 (#3205)
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.17.0 to 7.0.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.0.0/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-02 12:20:50 -05:00
Joan Miquel Torres
c3bd279953
Documented lock_timeout in client.mdx (#3199)
Added 'lock_timeout' option in Config object documentation since it's explicitly declared in node-postgres (packages/pg/lib/connection-parameters.js)

I also checked it works as documented in PostgreSQL Docs:

https://www.postgresql.org/docs/current/runtime-config-client.html#GUC-LOCK-TIMEOUT
2024-04-30 09:49:39 -05:00
Italo A
3cde785e38
Update queries.mdx link to markdown (#3192)
If we use `<a>` here, the template does not visually identify it as a link, so I have switched to the markdown link format.
2024-04-05 18:07:31 -07:00
Brian C
408bebd990
Fix import syntax for commonJS in documentation (#3191) 2024-04-05 16:48:44 -05:00
dependabot[bot]
68171dd00f
Bump eslint-config-prettier from 8.5.0 to 9.1.0 (#3185)
Bumps [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) from 8.5.0 to 9.1.0.
- [Changelog](https://github.com/prettier/eslint-config-prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/eslint-config-prettier/compare/v8.5.0...v9.1.0)

---
updated-dependencies:
- dependency-name: eslint-config-prettier
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-02 18:00:26 -05:00
Brian Carlson
a37a93bf79 Publish
- pg-connection-string@2.6.4
 - pg-cursor@2.10.5
 - pg-query-stream@4.5.5
 - pg@8.11.5
2024-04-02 15:26:02 -05:00
Brian C
95655fea0b
Revert "fix: conflict between browser URL object and Node URL object (#3061)" (#3188)
This reverts commit d21cc09556899b8038ec23613a801c19228637ca.
2024-04-02 15:23:53 -05:00
dependabot[bot]
ef24134a5a
Bump workerd from 1.20231030.0 to 1.20240329.0 (#3182)
Bumps [workerd](https://github.com/cloudflare/workerd) from 1.20231030.0 to 1.20240329.0.
- [Release notes](https://github.com/cloudflare/workerd/releases)
- [Changelog](https://github.com/cloudflare/workerd/blob/main/RELEASE.md)
- [Commits](https://github.com/cloudflare/workerd/compare/v1.20231030.0...v1.20240329.0)

---
updated-dependencies:
- dependency-name: workerd
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-01 11:19:30 -05:00
dependabot[bot]
50dbcd2453
Bump eslint from 8.56.0 to 8.57.0 (#3183)
Bumps [eslint](https://github.com/eslint/eslint) from 8.56.0 to 8.57.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v8.56.0...v8.57.0)

---
updated-dependencies:
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-01 11:17:21 -05:00
Brian Carlson
b03c071d2d Publish
- pg-connection-string@2.6.3
 - pg-cursor@2.10.4
 - pg-pool@3.6.2
 - pg-protocol@1.6.1
 - pg-query-stream@4.5.4
 - pg@8.11.4
2024-03-30 15:40:05 -05:00
Charmander
5807a00d93
Remove unused protocol-related dependencies from pg (#3181)
buffer-writer was replaced with pg-protocol in 3ff91eaa3222657fd51ea463b8086d134a505404, and packet-reader in 520bd3531990f32c3e00b20020c67f6ac6c70261.
2024-03-29 21:35:50 -05:00
Alex Anderson
2ab6f367c0
query: remove unused prop: isPreparedStatement (#3177)
Use of this property was removed in 2020 (dd3ce616d0fbdb92a7e146ecf4171bf3c1b3ea97).

Co-authored-by: alxndrsn <alxndrsn>
2024-03-28 10:28:30 -05:00
Alex Anderson
b400d33c33
query: remove unused prop: _promise (#3178)
Use of this prop was probably removed in 2017 (a0eb36d81938e488b3bc5369faee74fe22f36949).

Co-authored-by: alxndrsn <alxndrsn>
2024-03-28 10:26:00 -05:00
Alex Anderson
91de4b9453
Cursor: avoid closing connection twice if error received after destroy() (#2836)
* Cursor: avoid closing connection twice if error received after destroy()

Includes test case from @nathanjcochran

* Resolve lint violations

* revert fix to check tests fail without it

* Re-introdce fix

This reverts commit 5f5d42a071e40f8851035dba182642937dd35664.

---------

Co-authored-by: alxndrsn <alxndrsn>
2024-03-15 12:26:25 -05:00
Alex Anderson
ebba3d812f
ci: don't fail fast (#3173)
This allows all matrix builds to run, making it easier to understand if a given
failure is specific to nodejs version(s), or more general.

Co-authored-by: alxndrsn <alxndrsn>
2024-03-15 12:08:03 -05:00
Alex Anderson
a717c00b7b
chore (ci): add node v20 to build matrix (#3148)
* chore (ci): add node v20 to build matrix

* skip pg-native tests on node 20

---------

Co-authored-by: alxndrsn <alxndrsn>
2024-03-15 12:05:15 -05:00
Jakob Runge
aedae81c75
Fix broken link in docs (#3155)
* Fix broken link to /apis/types in docs

* Adjust slugs in docs pages
2024-03-14 22:54:57 -07:00
Alex Anderson
641ab436a0
ci: add build timeouts (#3172)
This should prevent runaway builds.

I noticed this issue when working on a fork of https://github.com/brianc/node-postgres/pull/2836.  Example builds with/without these timeouts:

1. 6 hours: https://github.com/alxndrsn/node-postgres/actions/runs/8277192701
2. 10 minutes: https://github.com/alxndrsn/node-postgres/actions/runs/8277388503

These timeouts are 4-5x what a current healthy build takes.
2024-03-14 22:53:08 -07:00
Alex Anderson
1481f8d1f4
ci: yarn: freeze lockfile (#3171)
This should highlight when the yarn.lock file is out of sync with package.json.

From the docs:

> If you need reproducible dependencies, which is usually the case with the continuous integration systems, you should pass --frozen-lockfile flag.
> - https://classic.yarnpkg.com/lang/en/docs/cli/install/
2024-03-14 22:49:33 -07:00
Alex Anderson
119078230e
chore (ci): upgrade github actions to use node 20 (#3149)
Fixes:

> Node.js 16 actions are deprecated. Please update the following actions to use Node.js 20: actions/checkout@v3, actions/setup-node@v3. For more information see: https://github.blog/changelog/2023-09-22-github-actions-transitioning-from-node-16-to-node-20/.

Co-authored-by: alxndrsn <alxndrsn>
2024-03-13 12:45:42 -05:00
Matthew Richmond
0ee010e5a0
Update project-structure.md (#3166)
Small path update
2024-03-13 12:42:59 -05:00
Sehrope Sarkuni
b4bfd63f63
CI clean up to fix lint task and remove Windows / MacOS from matrix (#3122)
* Remove unused travis CI config

* Bump eslint and friends

* Fix lint errors after eslint upgrade

* Remove windows and macos from CI workflow as they are actually running linux

Removes the windows and macos matrix from the CI workflow as they were never actually setting
the OS. Both were running against the "ubuntu-latest" OS. Trying to actually use them would
not work either as neither windows or macos is supported for service containers. A different
means will be needed to test on those platforms. Until that's done, this removes those from
the matrix as we were simply running the same thing 3x for the same node versions.
2024-03-05 14:08:44 -06:00
Akash
2a8efbee09
Minor typo correction (#3135) 2024-02-09 21:27:50 -08:00
Shane da Silva
81c287a49b
Serialize arrays of Uint8Array objects as hex escape sequences (#2930)
Previously, if you attempted to pass an array of `Uint8Array` objects to
a prepared statement, it would render each literal numeric value of that
array.

Since `Uint8Array` (and `TypedArray` types) represent views over raw
bytes, ensure these are serialized to Postgres as a byte representation.
2024-02-09 21:25:41 -08:00
Tunçer Damat
df0f4d19fb
Correction of the "e" variable to "err" in snippet (#3123) 2024-01-10 08:22:00 -08:00
FB
6cd0aeb212
Uppercase LTS in docs home page (#3103)
Changed 'lts' to 'LTS' for better readability, so people get it stands for Long-Term-Support
2023-11-29 22:52:36 -08:00
dependabot[bot]
9c3ecdca69
Bump prettier from 2.8.8 to 3.0.3 (#3054)
Bumps [prettier](https://github.com/prettier/prettier) from 2.8.8 to 3.0.3.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/2.8.8...3.0.3)

---
updated-dependencies:
- dependency-name: prettier
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-19 17:06:13 -06:00
dependabot[bot]
5164959d20
Bump workerd from 1.20230724.0 to 1.20231030.0 (#3088)
Bumps [workerd](https://github.com/cloudflare/workerd) from 1.20230724.0 to 1.20231030.0.
- [Release notes](https://github.com/cloudflare/workerd/releases)
- [Changelog](https://github.com/cloudflare/workerd/blob/main/RELEASE.md)
- [Commits](https://github.com/cloudflare/workerd/compare/v1.20230724.0...v1.20231030.0)

---
updated-dependencies:
- dependency-name: workerd
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-19 17:06:04 -06:00
Kyle Gray
a733b40f99
docs: Link to current PostgreSQL data types page (#3097)
The data types link pointed at PostgreSQL 9.5. Update the link to always point to the latest version of PostgreSQL.
2023-11-19 17:05:44 -06:00
Alex Anderson
e8259e04fc
ci: add lint job (#3079)
* ci: add lint job

* rebuild

* Revert "rebuild"

This reverts commit d330184140b64661027b634511bc5a8eb874a5ce.

* mad debugging

* wtf

* add eslintignore

* remove git status

---------

Co-authored-by: alxndrsn <alxndrsn>
2023-10-19 14:24:22 -05:00
Alex Anderson
16322c2d50
Fix eslint violations (#3078)
Co-authored-by: alxndrsn <alxndrsn>
2023-10-19 10:27:25 -05:00
Alex Anderson
b9a528cb3b
eslintrc: update prettier base config (#3077)
Co-authored-by: alxndrsn <alxndrsn>
2023-10-19 10:27:11 -05:00
Romain Gilliotte
b1a8947738
Fail gracefully when connecting to other database (#3026)
* Fail gracefully when connecting to other SGDB vendor

* Make test more flexible. Adjust error wording to match native better.

---------

Co-authored-by: Brian Carlson <brian.m.carlson@gmail.com>
2023-09-15 16:23:05 -05:00
Sebastien Stettler
d21cc09556
fix: conflict between browser URL object and Node URL object (#3061)
I am running this package using electron, what i noticed was that due to
the fact that the lines between node and browser environments become a
bit blurred, the URL class that was being used was the one defined by
the browser and not node. By making an explicit require it ensures the
correct Class is used.

While creating a test for this would be difficuilt i think adding an
eslint rule to stop using globally defined objects and require imports
instead would resolve issues like this in the future
2023-09-15 16:22:18 -05:00
Brian C
da0f5c5eb2
Remove 1 loop on rowDescription event (#3056)
* Remove 1 loop on rowDescription event

* Update packages/pg/lib/result.js

Co-authored-by: Charmander <~@charmander.me>

---------

Co-authored-by: Charmander <~@charmander.me>
2023-09-15 16:21:45 -05:00
Sehrope Sarkuni
106ca8a178
Fix get value of last column with same name in result rows (#3063)
* Add failing test for result rows with the same column names

* Fix handling of duplicate column names in results to ensure last value is populated

Fixes handling of result rows that have the same column name duplicated in the results to ensure
that the last value is the one returned to the user. This was the old behavior but unintentionally
broken when the pre-built object optimization was added.
2023-09-14 14:43:14 -05:00
Brian Carlson
a84ebb3fe8 Publish
- pg-cursor@2.10.3
 - pg-query-stream@4.5.3
 - pg@8.11.3
2023-08-16 16:50:05 -07:00
Koen
b5c5e52aa0
Option to use pre-shaped result rows; fixes #3042 (#3043)
* Add property usePrebuiltEmptyResultObjects to Query constructor which generates pre-shaped result rows

* Remove option and test for prebuiltEmptyResultObject

* Remove errorneously added newline

* Move all logic for prebuilding objects to Result

* Move prebuilding to addFields

* Use a clone as clone-base

---------

Co-authored-by: HZ111 / Dev2 <hz111@wielick.nl>
2023-08-15 08:42:54 -07:00
dependabot[bot]
58865b2c04
Bump workerd from 1.20230518.0 to 1.20230724.0 (#3036)
Bumps [workerd](https://github.com/cloudflare/workerd) from 1.20230518.0 to 1.20230724.0.
- [Release notes](https://github.com/cloudflare/workerd/releases)
- [Changelog](https://github.com/cloudflare/workerd/blob/main/RELEASE.md)
- [Commits](https://github.com/cloudflare/workerd/compare/v1.20230518.0...v1.20230724.0)

---
updated-dependencies:
- dependency-name: workerd
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-12 08:52:37 -07:00
Brian Carlson
a2a355a680 Publish
- pg-connection-string@2.6.2
 - pg-cursor@2.10.2
 - pg-query-stream@4.5.2
 - pg@8.11.2
2023-07-31 22:36:33 -05:00
Rafi Shamim
cf24ef28ee
pg-connection-string: avoid clobbering port from queryparams (#2833)
If the connection string is something like:
    postgresql://demo:password@/postgres?host=localhost&port=26258

Then the port from the query parameters should be used. Previously, the
parsing function would end up with a null port, and the default port
would end up being used by the connecetion package.
2023-07-21 11:57:02 -05:00
Ben Reinhart
3644730d2b
Remove early return for non commonjs environments (#3033) 2023-07-18 19:01:07 -05:00
Riku Rauhala
970804b6c1
Update pg-connection-string url in connecting.mdx (#3005) 2023-07-07 17:47:35 -05:00
dependabot[bot]
8d211e2be8
Bump workerd from 1.20230419.0 to 1.20230518.0 (#3023)
Bumps [workerd](https://github.com/cloudflare/workerd) from 1.20230419.0 to 1.20230518.0.
- [Release notes](https://github.com/cloudflare/workerd/releases)
- [Changelog](https://github.com/cloudflare/workerd/blob/main/RELEASE.md)
- [Commits](https://github.com/cloudflare/workerd/compare/v1.20230419.0...v1.20230518.0)

---
updated-dependencies:
- dependency-name: workerd
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-07 17:47:09 -05:00
dependabot[bot]
d17da9e1d9
Bump prettier from 2.7.1 to 2.8.8 (#3024)
Bumps [prettier](https://github.com/prettier/prettier) from 2.7.1 to 2.8.8.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/2.7.1...2.8.8)

---
updated-dependencies:
- dependency-name: prettier
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-07 17:47:00 -05:00
Brian Carlson
eaafac36dc Publish
- pg-cloudflare@1.1.1
 - pg-connection-string@2.6.1
 - pg-cursor@2.10.1
 - pg-pool@3.6.1
 - pg-query-stream@4.5.1
 - pg@8.11.1
2023-06-26 11:36:32 -05:00
Arian Mirahmadi
735683c5cb
Fix typo in project-structure.md (#3008) 2023-06-13 14:22:04 -07:00
Filipe Correa
46cfb25baf
Remove await from client release (#3006)
Co-authored-by: Filipe Correa <f.avelino-correa@klarna.com>
2023-06-12 12:50:40 -07:00
Riku Rauhala
e2d8fa2dc2
Fix a typo in README.md (#3002)
Change finanical to financial
2023-06-05 21:01:47 +00:00
Jason Ford
4dbf1af069
Add note about case sensitivity of result of pg.escapeIdentifier (#2993) 2023-06-01 01:03:50 -05:00
phiresky
d59cd15ed2
fix stack traces of query() to include the async context (#1762) (#2983)
* fix stack traces of query() to include the async context (#1762)

* rename tests so they are actually run

* conditionally only run async stack trace tests on node 16+

* add stack trace to pg-native

---------

Co-authored-by: Charmander <~@charmander.me>
2023-05-31 11:28:53 -05:00
Pete Bacon Darwin
0dfd955be5
fix: ensure that pg-cloudflare can be used with bundlers that don't know about Cloudflare sockets (#2978)
By implementing package.json `exports` we can avoid processing the Cloudflare
specific code, which contains `import ... from "cloudflare:sockets"`, in bundlers such
as Webpack.

If you are bundling for a Worker environment using Webpack then you need to add the
`workerd` condition and ignore `cloudflare:sockets` imports:

**webpack.config.js**
```js
resolve: { conditionNames: ["require", "node", "workerd"] },
  plugins: [
    new webpack.IgnorePlugin({
      resourceRegExp: /^cloudflare:sockets$/,
    }),
  ],
```
2023-05-31 11:25:56 -05:00
Rijk van Zanten
20d2c08027
Make async/await the primary examples in the docs (#2932)
* Correctly capitalize GitHub

* Add note on callbacks to index

* Add note on error handling

* Update client examples to use promises

* Update pooling examples

* Fix readme link

* Update cursor docs

* Update connecting examples

* Update Queries

* Update examples in pooling

* Update trx examples

* Update SSL example

* Update example

* Use ESM instead of CJS

* Update docs/pages/apis/cursor.mdx

Co-authored-by: Charmander <~@charmander.me>

* Update docs/pages/apis/cursor.mdx

Co-authored-by: Charmander <~@charmander.me>

* Update docs/pages/apis/pool.mdx

Co-authored-by: Charmander <~@charmander.me>

* Update docs/pages/apis/pool.mdx

Co-authored-by: Charmander <~@charmander.me>

* Update docs/pages/apis/pool.mdx

Co-authored-by: Charmander <~@charmander.me>

* Update docs/pages/features/connecting.mdx

Co-authored-by: Charmander <~@charmander.me>

* Update docs/pages/features/connecting.mdx

Co-authored-by: Charmander <~@charmander.me>

* Update docs/pages/features/ssl.mdx

Co-authored-by: Charmander <~@charmander.me>

---------

Co-authored-by: Charmander <~@charmander.me>
2023-05-31 11:25:24 -05:00
Novikov Evgeniy
dee3ae5cd6
feat: add connection parameter nativeConnectionString (#2941)
Co-authored-by: Evgeniy Novikov <e.p.novikov@tinkoff.ru>
2023-05-31 11:16:36 -05:00
Adam Jones
c38ecf3405
Fix connection string parsing for overriden hosts (#2977)
* Add failing test

* Fix test

This corresponds to what was line 48 previously, see https://github.com/brianc/node-postgres/pull/2971/files#diff-08a5e82487ebd9b43751630019753901fae0a111f8d009ad2e9d194445e96922L48

* Update packages/pg-connection-string/index.js

Co-authored-by: Pete Bacon Darwin <pete@bacondarwin.com>

---------

Co-authored-by: Brian C <brian.m.carlson@gmail.com>
Co-authored-by: Pete Bacon Darwin <pete@bacondarwin.com>
2023-05-31 10:24:08 -05:00
Shane
65406985b9
Fix typo in types.mdx (#2989) 2023-05-29 12:07:05 -07:00
Charmander
3039f1da77 Revert "Update utils.js (#2981)"
This reverts commit 522e2dcb76f92d0096177b10204bdc385375020d.
2023-05-23 08:42:54 +00:00
sudarshanvn
522e2dcb76
Update utils.js (#2981)
Fixed following error

    ReferenceError: TextEncoder is not defined
2023-05-19 16:53:52 -05:00
Brian Carlson
14b840e96e Publish
- pg-cloudflare@1.1.0
 - pg-connection-string@2.6.0
 - pg-cursor@2.10.0
 - pg-query-stream@4.5.0
 - pg@8.11.0
2023-05-15 10:36:31 -05:00
Pete Bacon Darwin
f2062936b9 Clean up pg-native in Makefile better 2023-05-15 07:29:07 +01:00
Pete Bacon Darwin
7152d4db5d Add example Cloudflare Worker and test 2023-05-15 07:29:07 +01:00
Pete Bacon Darwin
07553428e9 Add Cloudflare Worker compatible socket 2023-05-15 07:29:07 +01:00
Pete Bacon Darwin
5532ca51db Use WebCrypto APIs where possible
The only place we are stuck with node's original crypto API
is for generating md5 hashes, which are not supported by WebCrypto.
2023-05-15 07:29:07 +01:00
Pete Bacon Darwin
2b469d01da avoid accessing Node specific requires when not needed 2023-05-15 07:29:07 +01:00
Pete Bacon Darwin
f305419676 Use URL rather than url.parse() in pg-connection-string
Swapping the deprecated Node.js API for the modern cross
environment API.
2023-05-15 07:29:07 +01:00
Pete Bacon Darwin
26f7504531 fix invalid connection string test
The : and @ were the wrong way round
2023-05-15 07:29:07 +01:00
Pete Bacon Darwin
18b8ceae17 Add local development helper doc 2023-05-15 07:29:07 +01:00
Conner
249182ea9f
Document client.escapeIdentifier and client.escapeLiteral (#2954)
* Document client.escapeIdentifier and client.escapeLiteral

Per #1978 it seems that these client APIs are undocumented. Added documentation for these functions along with some examples and relevant links.

* Fix typos in new docs

* Migrate escapeIdentifier and escapeLiteral from Client to PG

These are standalone utility functions, they do not need a client instance to function.

Changes made:
- Refactored escapeIdentifer and escapeLiteral from client class to functions in utils
- Update PG to export  escapeIdentifier and escapeLiteral
- Migrated tests for Client.escapeIdentifier and Client.escapeLiteral to tests for utils
- Updated documentation, added a "utilities" page where these helpers are discussed

**note** this is a breaking change. Users who used these functions (previously undocumented) on instances of Client, or via Client.prototype.

* Export escapeIdentifier and escapeLiteral from PG

These are standalone utility functions, they should not depend on a client instance.

Changes made:
- Refactored escapeIdentifer and escapeLiteral from client class to functions in utils
- Re-exported functions on client for backwards compatibility
- Update PG to export  escapeIdentifier and escapeLiteral
- Updated tests to validate the newly exported functions from both entry points
- Updated documentation, added a "utilities" page where these helpers are discussed

* Ensure escape functions work via Client.prototype

Updated changes such that escapeIdentifier and escapeLiteral are usable via the client prototype
Updated tests to check for both entry points in client
2023-05-02 07:55:59 -05:00
Felix Rath
d63c761be8
docs(api/result): clarify that result.rowCount can be null (#2967)
`result.rowCount` is initialized to `null`, but only set to an `int`-value if the returned command tag consists of more than one word, which is not the case in general.

For example, the `LOCK` command will return a command tag of simply the form `LOCK`, and thus `result.rowCount` will stay `null`.
2023-05-01 09:15:55 -05:00
Brian C
0870442776
Fix race condition in release event test for pool (#2969) 2023-05-01 09:15:20 -05:00
Jan Piotrowski
b357e1884a
fix(theme.config.js): Replace default meta description and social title (#2952)
Currently still nextra default.

Those are shown in Slack and other social apps when sharing the website.
2023-04-20 16:03:59 +02:00
Brian C
48f4398fa7
Update README.md (#2944)
Update href to docs
2023-03-30 11:25:35 -05:00
Samuel Durante
92351b5f3e
docs(client): improve the Client instance example (#2935) 2023-03-30 10:49:28 -05:00
Ryan B. Harvey
65ca2458fd
Add release event to Pool API docs (#2928) 2023-03-16 11:34:50 -05:00
Brian C
0f76fb3bb7
Update path to documentation in readme (#2925) 2023-03-07 13:55:22 -06:00
Brian Carlson
661f870e1c Update changelog 2023-03-06 15:48:08 -06:00
Brian Carlson
ee302cbcf1 Publish
- pg-cursor@2.9.0
 - pg-pool@3.6.0
 - pg-query-stream@4.4.0
 - pg@8.10.0
2023-03-06 14:18:02 -06:00
Ryan B. Harvey
810b125581
Emit a 'release' event when a connection is released back to the pool (#2845) 2023-03-06 12:32:13 -06:00
Aram Zegerius
8804e5caaf
Fix typo in URL (#2913) 2023-03-06 12:30:37 -06:00
Cody Greene
5703791640
fix: double client.end() hang (#2717)
* fix: double client.end() hang

fixes https://github.com/brianc/node-postgres/issues/2716

`client.end()` will resolve early if the connection is already dead,
rather than waiting for an "end" event that will never arrive.

* fix: client.end() resolves when socket is fully closed
2023-03-06 12:10:07 -06:00
Brian Carlson
adbe86d4a0 Update changelog 2023-01-27 09:15:30 -06:00
Brian Carlson
20a243e8b3 Publish
- pg-cursor@2.8.0
 - pg-protocol@1.6.0
 - pg-query-stream@4.3.0
 - pg@8.9.0
2023-01-27 09:12:49 -06:00
Brian Carlson
5bdc61a33d Remove expired sponsors 2023-01-27 09:11:05 -06:00
Brian C
47afe5cded
Attempt to fix timing test flake on older versions of node in CI (#2902) 2023-01-23 13:55:38 -08:00
Sehrope Sarkuni
bb8745b215
Fix SASL to bubble up errors, enable SASL tests in CI, and add informative empty SASL password message (#2901)
* Enable SASL tests in GitHub actions CI

* Add SASL test to ensure that client password is a string

* Fix SASL error handling to emit and bubble up errors

* Add informative error when SASL password is empty string
2023-01-23 10:03:51 -08:00
Ruy Adorno
f82f39c20c
Add support to stream factory (#2898)
This changeset enables declaring the `stream` config value as a factory
method. Providing a much more flexible control of the socket connection.

Defining a custom `stream` config value allows the postgres driver to
support a larger variety of environments/setups such as proxy servers
and secure socket connections that are used by cloud providers such as
GCP.

Currently, usage of the `stream` config value is only viable for single
connections given that it's only possible to define a single socket
stream instance per new Client/Pool instance. By adding support to a
factory function, it becomes possible to enable usage of custom socket
streams for connection pools.

For reference, see the `mysql2` driver for MySQL (linked below) for
prior art example of this pattern.

Refs: ba15fe2570/lib/connection.js (L63-L65)
Refs: https://cloud.google.com/sql/docs/postgres/connect-overview
Signed-off-by: Ruy Adorno <ruyadorno@google.com>

Signed-off-by: Ruy Adorno <ruyadorno@google.com>
2023-01-23 10:02:39 -08:00
Meron Ogbai
3e34816f6f
Update title (#2886)
This will change the title of the docs from Next.js Static Site Generator to node-postgres
2022-12-30 22:45:42 -06:00
dependabot[bot]
c6c05f823c
Bump JSONStream from 0.7.4 to 1.3.5 (#2874)
Bumps [JSONStream](https://github.com/dominictarr/JSONStream) from 0.7.4 to 1.3.5.
- [Release notes](https://github.com/dominictarr/JSONStream/releases)
- [Commits](https://github.com/dominictarr/JSONStream/commits)

---
updated-dependencies:
- dependency-name: JSONStream
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-30 22:02:45 -06:00
dependabot[bot]
16118cecdd
Bump eslint-config-prettier from 6.12.0 to 8.5.0 (#2875)
Bumps [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) from 6.12.0 to 8.5.0.
- [Release notes](https://github.com/prettier/eslint-config-prettier/releases)
- [Changelog](https://github.com/prettier/eslint-config-prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/eslint-config-prettier/compare/v6.12.0...v8.5.0)

---
updated-dependencies:
- dependency-name: eslint-config-prettier
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-30 22:02:31 -06:00
Brian C
27d612a2ac
Update docs (#2867)
- fix config warnings
- add search bar
- add google analytics
2022-11-23 21:50:36 -06:00
Brian C
12b9a69776
update docs - clean up interface (#2863)
* update docs - clean up interface

* Remove node v8.x from test matrix
2022-11-23 15:08:09 -06:00
Charmander
c7dc621d3f
pg-cursor: Fix errors only being sent to half the queue (#2831)
* pg-cursor: Add failing test for errors on queued reads

* pg-cursor: Fix errors being sent to only half the queue
2022-11-21 11:57:30 -06:00
Frazer Smith
c7133eb67f
ci: remove git credentials after checkout (#2858) 2022-11-08 13:24:39 -06:00
Frazer Smith
15b502d4c1
refactor(pg): remove unused imports (#2854) 2022-11-05 18:26:42 -07:00
dependabot[bot]
c253eb6696
Bump chai from 4.2.0 to 4.3.6 (#2851)
Bumps [chai](https://github.com/chaijs/chai) from 4.2.0 to 4.3.6.
- [Release notes](https://github.com/chaijs/chai/releases)
- [Changelog](https://github.com/chaijs/chai/blob/4.x.x/History.md)
- [Commits](https://github.com/chaijs/chai/compare/4.2.0...v4.3.6)

---
updated-dependencies:
- dependency-name: chai
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-04 00:30:19 -05:00
dependabot[bot]
0965531cda
Bump typescript from 4.0.3 to 4.8.4 (#2850)
Bumps [typescript](https://github.com/Microsoft/TypeScript) from 4.0.3 to 4.8.4.
- [Release notes](https://github.com/Microsoft/TypeScript/releases)
- [Commits](https://github.com/Microsoft/TypeScript/compare/v4.0.3...v4.8.4)

---
updated-dependencies:
- dependency-name: typescript
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-04 00:29:25 -05:00
Ryan B. Harvey
89b4e7f2a2
Fix devcontainer build failure due to env var being interpreted as non-string (#2844) 2022-10-28 00:56:53 -05:00
dependabot[bot]
5538df6b44
Bump @typescript-eslint/eslint-plugin from 4.4.0 to 4.33.0 (#2826)
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 4.4.0 to 4.33.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v4.33.0/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-15 12:57:41 -05:00
Knut Olav Løite
406f141a1a
perf: remove superfluous flush message (#2842) 2022-10-15 12:57:16 -05:00
dependabot[bot]
c7dc7fd93a
Bump pgpass from 1.0.2 to 1.0.5 (#2827)
Bumps [pgpass](https://github.com/hoegaarden/pgpass) from 1.0.2 to 1.0.5.
- [Release notes](https://github.com/hoegaarden/pgpass/releases)
- [Commits](https://github.com/hoegaarden/pgpass/compare/v1.0.2...v1.0.5)

---
updated-dependencies:
- dependency-name: pgpass
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-15 12:55:47 -05:00
Brian C
1aa08274a5
Migrate docs repo into monorepo (#2823)
* Move files over

* Finish initial port of content
2022-10-10 12:20:46 -05:00
Alex Anderson
5bcc05d1e9
pg-protocol: fix link to message format docs (#2835) 2022-10-06 09:59:11 -07:00
David Matějka
9dfb3dccbf
perf(pg): use native crypto.pbkdf2Sync in sasl auth (#2815) 2022-09-27 05:38:28 -05:00
Yue Dai
9e2d7c4ad5
Update pg.connect with pool.connect (#2822)
pg.connect() has been deprecated.
2022-09-27 05:31:07 -05:00
Matthieu
9a95ee719b
pg-query-stream: Add missing peer dependency on pg (#2813)
pg-query-stream depends on pg-cursor, which has a peer dependency on pg.
2022-09-19 10:29:53 -07:00
dependabot[bot]
34d173d9e3
Bump coveralls from 3.1.0 to 3.1.1 (#2801)
Bumps [coveralls](https://github.com/nickmerwin/node-coveralls) from 3.1.0 to 3.1.1.
- [Release notes](https://github.com/nickmerwin/node-coveralls/releases)
- [Commits](https://github.com/nickmerwin/node-coveralls/compare/v3.1.0...3.1.1)

---
updated-dependencies:
- dependency-name: coveralls
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-17 20:59:43 +02:00
dependabot[bot]
659ac37ba3
Bump eslint-plugin-promise from 3.8.0 to 6.0.1 (#2802)
Bumps [eslint-plugin-promise](https://github.com/xjamundx/eslint-plugin-promise) from 3.8.0 to 6.0.1.
- [Release notes](https://github.com/xjamundx/eslint-plugin-promise/releases)
- [Changelog](https://github.com/xjamundx/eslint-plugin-promise/blob/development/CHANGELOG.md)
- [Commits](https://github.com/xjamundx/eslint-plugin-promise/commits)

---
updated-dependencies:
- dependency-name: eslint-plugin-promise
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-08 06:31:37 +02:00
Alex
8250af4aed
Minimize GitHub Workflows permissions (#2798)
Signed-off-by: sashashura <93376818+sashashura@users.noreply.github.com>
2022-08-29 12:55:10 -07:00
Brian C
ad6c4a4693
Update README.md (#2799)
Build status icon was still pointing at travis. We don't use travis anymore: we use github actions.
2022-08-29 13:32:48 -05:00
Brian Carlson
c99fb2c127 Publish
- pg-cursor@2.7.4
 - pg-pool@3.5.2
 - pg-query-stream@4.2.4
 - pg@8.8.0
2022-08-23 11:36:18 -05:00
Brian Carlson
8d498959c3 Update changelog 2022-08-23 11:29:35 -05:00
dependabot[bot]
6e386eb294
Bump prettier from 2.1.2 to 2.7.1 (#2792)
Bumps [prettier](https://github.com/prettier/prettier) from 2.1.2 to 2.7.1.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/2.1.2...2.7.1)

---
updated-dependencies:
- dependency-name: prettier
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-22 21:35:18 -05:00
Marcin K
ff85ac2459
chore(): added dependabot (#2374) 2022-08-22 19:06:43 -05:00
Brian C
a4ef6ce38c
Fix error handling test (#2789)
* Fix error handling test

#2569 introduced a bug in the test. The test never passed but because travis-ci lovingly broke the integration we had a long time ago the tests weren't run in CI until I merged.  So, this fixes the tests & does a better job cleaning up the query in an errored state.

* Update sponsors
2022-08-22 19:05:59 -05:00
Brian C
747485d342
Bump min version of pg-native (#2787)
Fixes 2786
2022-08-22 15:34:07 -05:00
Alex Zlotnik
8032fbad43
Catch errors client throws in pool (#2569)
* Catch errors client throws in pool

* Add a test

This test _should be_ right
2022-08-22 15:33:51 -05:00
Martin Kubliniak
3e53d06cd8
Support lock_timeout (#2779) 2022-08-10 16:15:06 -05:00
Peter Rust
68160a29bd
Fix #2556 by keeping callback errors from interfering with cleanup (#2753)
* Fix #2556 (handleRowDescription of null) by keeping callback errors from interfering with cleanup

* Added regression test for #2556
2022-06-20 08:25:12 -05:00
Brian C
28ac2a17bc
Add test for how to set search path (#2700)
Also refactor a few tests a bit to slowly clean up some of the old style.
2022-05-12 22:00:00 -05:00
ChrisWritable
3ca56027d3
Immediately unref() maxLifetimeSeconds Timeout object to prevent blocking allowExitOnIdle (#2721) 2022-05-12 19:05:02 -05:00
Brian Carlson
c7743646cd Update sponsors 2022-05-12 19:04:21 -05:00
dependabot[bot]
ec06473c16
Bump minimist from 1.2.5 to 1.2.6 (#2727)
Bumps [minimist](https://github.com/substack/minimist) from 1.2.5 to 1.2.6.
- [Release notes](https://github.com/substack/minimist/releases)
- [Commits](https://github.com/substack/minimist/compare/1.2.5...1.2.6)

---
updated-dependencies:
- dependency-name: minimist
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-05-11 23:41:19 -05:00
dependabot[bot]
b812ec1e65
Bump async from 0.9.0 to 2.6.4 (#2736)
Bumps [async](https://github.com/caolan/async) from 0.9.0 to 2.6.4.
- [Release notes](https://github.com/caolan/async/releases)
- [Changelog](https://github.com/caolan/async/blob/v2.6.4/CHANGELOG.md)
- [Commits](https://github.com/caolan/async/compare/0.9.0...v2.6.4)

---
updated-dependencies:
- dependency-name: async
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-05-11 23:41:05 -05:00
Brian C
4b4d97b8f3
Remove stream-tester (#2743)
* Remove stream-tester

* Use random port for network-partition tests

* Use random port for connection timeout test

* Bump CI version
2022-05-10 14:49:22 -05:00
Lars Hvam
f5e87ac0b1
pg: update README, remove dead badge (#2719) 2022-04-01 11:31:45 -05:00
dependabot[bot]
21ccd4f1b6
Bump pathval from 1.1.0 to 1.1.1 (#2702)
Bumps [pathval](https://github.com/chaijs/pathval) from 1.1.0 to 1.1.1.
- [Release notes](https://github.com/chaijs/pathval/releases)
- [Changelog](https://github.com/chaijs/pathval/blob/master/CHANGELOG.md)
- [Commits](https://github.com/chaijs/pathval/compare/v1.1.0...v1.1.1)

---
updated-dependencies:
- dependency-name: pathval
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-15 14:52:06 -06:00
Brian Carlson
4fa7ee891a Publish
- pg-cursor@2.7.3
 - pg-pool@3.5.1
 - pg-query-stream@4.2.3
 - pg@8.7.3
2022-02-04 10:28:01 -06:00
Brian Carlson
9a61e9ac58 Format with prettier 2022-02-04 10:27:51 -06:00
Brian Carlson
edf1a864d6 Fix changelog 2022-02-04 10:22:23 -06:00
Brian Carlson
6849cc6868 Publish
- pg-cursor@2.7.2
 - pg-pool@3.5.0
 - pg-query-stream@4.2.2
 - pg@8.7.2
2022-02-04 10:21:57 -06:00
Brian Carlson
e4115854cb Update changelog 2022-02-04 10:20:51 -06:00
ChrisWritable
8392918d7b
Add connection lifetime limit option and tests (#2698)
Co-authored-by: ChrisG0x20 <position0x45@hotmail.com>
2022-01-28 17:17:48 -06:00
Matthieu
5508c0ee6b
fix: Prevent closing the portal twice (#2609)
Fixes brianc/node-postgres#2119
2022-01-28 12:59:45 -06:00
dependabot[bot]
998f573244
Bump trim-off-newlines from 1.0.1 to 1.0.3 (#2695)
Bumps [trim-off-newlines](https://github.com/stevemao/trim-off-newlines) from 1.0.1 to 1.0.3.
- [Release notes](https://github.com/stevemao/trim-off-newlines/releases)
- [Commits](https://github.com/stevemao/trim-off-newlines/compare/v1.0.1...v1.0.3)

---
updated-dependencies:
- dependency-name: trim-off-newlines
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-26 17:34:36 -06:00
dependabot[bot]
f3ff3e2d1f
Bump node-fetch from 2.6.1 to 2.6.7 (#2694)
Bumps [node-fetch](https://github.com/node-fetch/node-fetch) from 2.6.1 to 2.6.7.
- [Release notes](https://github.com/node-fetch/node-fetch/releases)
- [Commits](https://github.com/node-fetch/node-fetch/compare/v2.6.1...v2.6.7)

---
updated-dependencies:
- dependency-name: node-fetch
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-26 17:34:10 -06:00
darkgl0w
a09412c603
chore (ci): trigger a CI run on PR events (#2681) 2022-01-26 17:20:11 -06:00
Andrew Lam
1f7b8cb6fa
Fix markdown for n8n.io sponsor link (#2685) 2022-01-16 14:40:34 -06:00
darkgl0w
392a7f4a66
chore (ci): add macOS and Windows to the CI OS matrix (#2657)
* chore (ci): add macOS and Windows to the CI OS matrix

* chore (ci): fix macOS runner name
2021-12-17 00:21:35 -06:00
Steffen Weidenhaus
2c3adf25f9
Update README.md (#2671)
Change `name` to `now` for time column
2021-12-17 00:15:26 -06:00
dependabot[bot]
97eea2d7a4
Bump path-parse from 1.0.6 to 1.0.7 (#2595)
Bumps [path-parse](https://github.com/jbgutierrez/path-parse) from 1.0.6 to 1.0.7.
- [Release notes](https://github.com/jbgutierrez/path-parse/releases)
- [Commits](https://github.com/jbgutierrez/path-parse/commits/v1.0.7)

---
updated-dependencies:
- dependency-name: path-parse
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-11-19 09:38:43 -06:00
dependabot[bot]
b0bd1c32f1
Bump tar from 4.4.15 to 4.4.19 (#2604)
Bumps [tar](https://github.com/npm/node-tar) from 4.4.15 to 4.4.19.
- [Release notes](https://github.com/npm/node-tar/releases)
- [Changelog](https://github.com/npm/node-tar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/npm/node-tar/compare/v4.4.15...v4.4.19)

---
updated-dependencies:
- dependency-name: tar
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-11-17 11:02:04 -06:00
Brian C
3aba3794cf
Use github actions for CI (#2654)
This is the initial port to github actions.  Still pending are the SSL and client SSL cert tests which are currently being skipped. But perfect is the enemy of the good here, and having no CI because travis-ci keeps not working is unacceptable.
2021-11-17 10:02:22 -06:00
dependabot[bot]
947ccee346
Bump tar from 4.4.13 to 4.4.15 (#2592)
Bumps [tar](https://github.com/npm/node-tar) from 4.4.13 to 4.4.15.
- [Release notes](https://github.com/npm/node-tar/releases)
- [Changelog](https://github.com/npm/node-tar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/npm/node-tar/compare/v4.4.13...v4.4.15)

---
updated-dependencies:
- dependency-name: tar
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-08-05 00:59:44 +00:00
Brian C
98cd59e3e7
Return promise on cursor end (#2589)
* Return promise on cursor end

* Remove redudant if
2021-07-29 17:17:15 -05:00
Brian M. Carlson
92b4d37926 Publish
- pg-cursor@2.7.1
 - pg-pool@3.4.1
 - pg-query-stream@4.2.1
 - pg@8.7.1
2021-07-27 17:33:19 -05:00
Brian C
86d31a6fad
Only call client.ref if it exists
* Only call client.ref if it exists. Fixes #2582

* Make test requiring port less flakey

* Bump port range

Fixes #2582
Fixes #2584
2021-07-27 17:27:05 -05:00
Brian M. Carlson
f3b0ee4c09 Publish
- pg-cursor@2.7.0
 - pg-pool@3.4.0
 - pg-query-stream@4.2.0
 - pg@8.7.0
2021-07-27 12:41:17 -05:00
Brian C
779803fbce
Add ref/unref noop to native client (#2581)
* Add ref/unref noop to native client

* Use promise.catch in test

* Make partition test not flake on old node

* Fix test flake on old node
2021-07-27 12:23:30 -05:00
dependabot[bot]
0da7882f45
Bump y18n from 4.0.0 to 4.0.1 (#2506)
Bumps [y18n](https://github.com/yargs/y18n) from 4.0.0 to 4.0.1.
- [Release notes](https://github.com/yargs/y18n/releases)
- [Changelog](https://github.com/yargs/y18n/blob/master/CHANGELOG.md)
- [Commits](https://github.com/yargs/y18n/commits)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-07-27 11:42:04 -05:00
dependabot[bot]
83aae778e8
Bump ssri from 6.0.1 to 6.0.2 (#2531)
Bumps [ssri](https://github.com/npm/ssri) from 6.0.1 to 6.0.2.
- [Release notes](https://github.com/npm/ssri/releases)
- [Changelog](https://github.com/npm/ssri/blob/v6.0.2/CHANGELOG.md)
- [Commits](https://github.com/npm/ssri/compare/v6.0.1...v6.0.2)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-07-27 11:37:10 -05:00
dependabot[bot]
d8ce457e83
Bump handlebars from 4.7.6 to 4.7.7 (#2538)
Bumps [handlebars](https://github.com/wycats/handlebars.js) from 4.7.6 to 4.7.7.
- [Release notes](https://github.com/wycats/handlebars.js/releases)
- [Changelog](https://github.com/handlebars-lang/handlebars.js/blob/master/release-notes.md)
- [Commits](https://github.com/wycats/handlebars.js/compare/v4.7.6...v4.7.7)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-07-27 11:36:35 -05:00
Brian M. Carlson
f824d74afe Update changelog 2021-07-27 11:35:55 -05:00
Brian Crowell
684cd09bce
Allow Node to exit if the pool is idle (#2568)
Based on the suggestion from #2078. This adds ref/unref methods to the
Connection and Client classes and then uses them to allow the process to
exit if all of the connections in the pool are idle. This behavior is
controlled by the allowExitOnIdle flag to the Pool constructor; it defaults
to the old behavior.
2021-07-27 11:29:07 -05:00
Bluenix
aedaa59afe
Add support for using promises in Cursor methods (#2554)
* Add similar promise variables to read() and close() as seen in query()

* Add testing for promise specific usage

* Simplify tests as no real callbacks are involved

Removes usage of `done()` since we can end the test when we exit the function

Co-Authored-By: Charmander <~@charmander.me>

* Switch to let over var

Co-authored-by: Charmander <~@charmander.me>
2021-07-27 09:40:32 -05:00
Greg Brown
9d2c977ce9
Use _isFull instead of duplicating clients check (#2539)
Noticed that options.max is compared against client count directly, but there's a method wrapping it. I can't see any reason to duplicate it? And using _isFull means I can override that for the adaptive pooling idea I'm exploring :)
2021-06-22 09:55:21 -05:00
Bluenix
a04003164b
Turn Cursor into an ES6 class (#2553)
* Turn Cursor into an ES6 class

* Fix incorrect syntax in Cursor.end()

* Remove extraneous empty line

* Revert es6 change for end()

* Revert back to defining the end() method inside the class

* Use hanging indent to satisfy Prettier
2021-06-22 09:52:10 -05:00
dependabot[bot]
d6ed9e756e
Bump lodash from 4.17.20 to 4.17.21 (#2540)
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.20 to 4.17.21.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.20...4.17.21)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-06-15 11:27:01 -05:00
Charmander
7667e7c9e7
Fix and enable pool verify option test (#2528)
by not double-releasing.

Reviewed-by: Sehrope Sarkuni <sehrope@jackdb.com>
2021-05-27 23:37:07 +00:00
Charmander
8f0db306d9
Remove broken test (#2529)
It’s missing `co.wrap`, so it doesn’t actually run (Mocha does nothing with the paused generator). The test group that follows it, “using an ended pool”, covers the same thing anyway.
2021-04-27 15:34:08 -05:00
Brian M. Carlson
d459479382 Publish
- pg-connection-string@2.5.0
 - pg-cursor@2.6.0
 - pg-pool@3.3.0
 - pg-protocol@1.5.0
 - pg-query-stream@4.1.0
 - pg@8.6.0
2021-04-13 11:02:40 -05:00
Brian M. Carlson
3115be6890 Update changelog 2021-04-13 11:02:10 -05:00
Erona
8faf8a0937
fix(pg-cursor): EventEmitter memory leak (#2501) 2021-04-13 10:57:37 -05:00
Felix Pusch
d99b5741f8
pg-query-stream: remove through dependency (#2518) 2021-04-13 10:56:37 -05:00
Sven Over
6121bd3bb0
Add ParameterDescription message to pg-protocol (#2464) 2021-04-06 09:01:04 -05:00
Juan M Martínez
3dc79b605c
util in connection not used (#2507) 2021-04-02 22:37:39 +00:00
Kannan Goundan
4b229275cf
pg: Re-export DatabaseError from 'pg-protocol' (#2445)
* pg: Re-export DatabaseError from 'pg-protocol'

Before, users would have to import DatabaseError from 'pg-protocol'.  If
there are multiple versions of 'pg-protocol', you might end up using the
wrong one.

Closes #2378

* Update error-handling-tests.js

* Update query-error-handling-tests.js

Co-authored-by: Brian C <brian.m.carlson@gmail.com>
2021-03-22 13:07:05 -05:00
Emily Marigold Klassen
45fa27ea4a
[pg-protocol] use literals instead of const enum (#2490)
Co-authored-by: Emily Marigold Klassen <forivall@users.noreply.github.com>
2021-03-12 11:01:51 -06:00
Brian C
69af1cc934
Remove dead badge from readme 2021-03-12 08:41:13 -06:00
Brian C
61dfda7439
Update SPONSORS.md 2021-03-12 08:40:22 -06:00
Edward O'Reilly
2a7c614583
Adding pg to peerDependencies (#2471)
* Adding pg to peerDependencies

Yarn2 requires strict imports, I.E. all project dependencies need to exist in that project's package.json.

* pg version should be locked on the major version

Co-authored-by: Charmander <~@charmander.me>

Co-authored-by: Charmander <~@charmander.me>
2021-03-12 08:24:07 -06:00
Emily Marigold Klassen
5a41a56862
Add missing metadata to package.jsons (#2487)
Co-authored-by: Emily Marigold Klassen <forivall@users.noreply.github.com>
2021-03-12 08:23:13 -06:00
Sehrope Sarkuni
25f658f227
Fix README to separate sponsors onto separate lines (#2459)
Splits sponsor listings onto multiple lines by putting them in list elements.

Also removes hidden inline png that does not render on the README.
2021-01-29 10:55:05 -06:00
dependabot[bot]
4cb73ebc2c
Bump ini from 1.3.5 to 1.3.8 (#2430)
Bumps [ini](https://github.com/isaacs/ini) from 1.3.5 to 1.3.8.
- [Release notes](https://github.com/isaacs/ini/releases)
- [Commits](https://github.com/isaacs/ini/compare/v1.3.5...v1.3.8)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-26 21:37:23 -06:00
kaue
b4f61ad4c0
update license copyright year (#2450)
updates license copyright year to 2021
2021-01-26 21:36:51 -06:00
Jakob Krigovsky
4bc55834b9
Fix typo (#2442)
6be3b9022f83efc721596cc41165afaa07bfceb0 added support for the `sslmode` parameter, not `ssl-mode`.
2021-01-23 21:53:46 +00:00
Jumpaku
fae2c98870
Fix typo (#2444) 2021-01-19 23:24:44 +00:00
Andy Edwards
3f3f1a77c3
docs(README.md): add link to documentation repo (#2434)
since it's currently the only way to look up documentation for old versions
2020-12-30 04:20:46 -06:00
Brian C
daeafe82b4
Make tests pass in github codespaces (#2437)
* Make tests pass in github codespaces

There were a few tests which didn't specify a host or port which wasn't working well inside the codespaces docker environment.  Added host & port where required.  Also noticed one test wasn't actually _testing_, it was just `console.log`-ing its output, so I added proper assertions there.  Finally set `PGTESTNOSSL: true` in the codespaces environment until I can get the postgres docker container configured w/ SSL...which I will do l8r.

* lint
2020-12-30 04:20:20 -06:00
Sehrope Sarkuni
a109e8c6d2
Add more SASL validation and fix tests (#2436)
* Add sha256 SASL helper

* Rename internal createHMAC(...) to hmacSha256(...)

* Add parseAttributePairs(...) helper for SASL

* Tighten arg checks in SASL xorBuffers(...)

* Add SASL nonce check for printable chars

* Add SASL server salt and server signature base64 validation

* Add check for non-empty SASL server nonce

* Rename SASL helper to parseServerFirstMessage(...)

* Add parameter validation to SASL continueSession(...)

* Split out SASL final message parsing into parseServerFinalMessage(...)

* Fix SCRAM tests

Removes custom assert.throws(...) so that the real one from the assert package is used and
fixes the SCRAM tests to reflect the updated error messages and actual checking of errors.

Previously the custom assert.throws(...) was ignoring the error signature validation.
2020-12-30 04:19:27 -06:00
Jakob Krigovsky
afb3bf3d43
Document sslmode connection string parameter (#2421) 2020-12-03 09:44:28 -06:00
Brian M. Carlson
54b87523e2 Update changelog for pg-query-stream
Document the conversion to typescript as a semver major change. Closes #2412.
2020-11-30 11:01:54 -06:00
Brian M. Carlson
fa4549af4f Publish
- pg-cursor@2.5.2
 - pg-query-stream@4.0.0
2020-11-30 10:58:10 -06:00
Brian M. Carlson
5de36c7f7f Update sponsors & readme 2020-11-30 10:57:40 -06:00
Brian C
4fde8b78f1
Fix double readyForQuery (#2420)
This is fixing a double readyForQuery message being sent from the backend (because we were calling sync after an error, which I already fixed in the main driver).  Also closes #2333
2020-11-30 09:25:01 -06:00
Jakob Krigovsky
c6aa29ade9
Fix typo (#2422)
Co-authored-by: Wolfgang Walther <wolfgangwalther@users.noreply.github.com>
2020-11-27 21:44:37 +00:00
Brian M. Carlson
0b9bb349dc Publish
- pg-cursor@2.5.1
 - pg-query-stream@3.4.2
 - pg@8.5.1
2020-11-13 08:59:48 -06:00
Brian C
ebe412cf24
Support "true" as string for ssl (#2407)
Fixes 2406
2020-11-11 10:41:20 -06:00
Brian M. Carlson
4d203aedee Publish
- pg-query-stream@3.4.1
2020-11-10 16:04:19 -06:00
Brian M. Carlson
3d0f68aa7b Update keyword to force patch apply 2020-11-10 16:04:12 -06:00
Brian C
897d774509
Run build before publish (#2409) 2020-11-10 16:01:44 -06:00
Brian M. Carlson
ec1dcab966 Publish
- pg-cursor@2.5.0
 - pg-protocol@1.4.0
 - pg-query-stream@3.4.0
 - pg@8.5.0
2020-11-10 11:01:03 -06:00
Brian M. Carlson
dce02e8d77 Update sponsors & changelog 2020-11-10 11:00:41 -06:00
Charmander
0012a43d95
Forward options’ ssl.key even when non-enumerable (#2394)
* Test client certificate authentication

* Forward options’ ssl.key even when non-enumerable
2020-11-09 11:30:40 -06:00
Charmander
8bed670aee Add more error handling to error handling tests 2020-11-05 23:19:59 -08:00
Brian C
07988f985a
Speed up bind functionality (#2286)
Move from 3 loops (prepareValue, check for buffers, write param types, write param values) to a single loop. This speeds up the insert benchmark by around 100 queries per second. Performance improvement depends on number of parameters being bound.
2020-11-04 08:27:40 -06:00
Marcin K
78a14a164d
feat(): pg-query-stream typescript (#2376)
* feat(): start converting pg-query stream

* feat(): solution project, initial version of typescript-pg-query stream

* chore(): mocha with typescript

* fix(): eslint ignore query stream dist

* refactor(pg-query-stream): convert test to ts

* chore(): fixed type errors

* chore(): fix helper usage

* chore(): use ts-node compatibile with node v8

* fix(): addd es extension

* chore(): remove emitClose and added compilation for async iterators

* chore(): condition for asyc iteration test

* chore(): rename class to match ts-defs

* chore(): tests to import from src instead of dist

* chore(): remove prettier from peer deps:

* chore(): update lock file
2020-11-03 11:17:49 -06:00
chyzwar
52dfca493c chore(): remove postgres from lint travis task 2020-11-02 10:39:51 -06:00
chyzwar
c22c2f0ebd chore(): update eslint, run lint only on latest lts 2020-11-02 10:39:51 -06:00
Casey Foster
415bf09041 Remove console.error on pg-native module not found 2020-11-02 10:33:55 -06:00
Brian M. Carlson
b6d69d5bc2 Publish
- pg-cursor@2.4.2
 - pg-pool@3.2.2
 - pg-query-stream@3.3.2
 - pg@8.4.2
2020-10-26 12:19:03 -05:00
Lewis Cowles
80c500ffbf Update packages/pg-pool/index.js
Co-authored-by: Charmander <~@charmander.me>
2020-10-20 12:53:25 -05:00
Lewis Cowles
e82137e6d3 Tests 2020-10-20 12:53:25 -05:00
Lewis Cowles
fd2c3563a5 Security: simplify defineProperty non-enumerables
* `password` already has this set, but was a little long considering we only want to override default of one property
* `ssl.key` was showing up in tracebacks
2020-10-20 12:53:25 -05:00
Brian M. Carlson
36342c9a84 Publish
- pg-cursor@2.4.1
 - pg-query-stream@3.3.1
 - pg@8.4.1
2020-10-08 15:53:16 -05:00
Brian M. Carlson
d8681fc2cd Comments & cleanup 2020-10-08 15:17:34 -05:00
Brian M. Carlson
dd3ce616d0 Fixes based on postgres maintainer advice 2020-10-08 15:17:34 -05:00
Brian M. Carlson
d31486fb7c Change when sync is sent during pipelining 2020-10-08 15:17:34 -05:00
Brian M. Carlson
b45051d72a Update comments 2020-10-08 15:17:34 -05:00
Brian M. Carlson
f55d879c52 Apply fix 2020-10-08 15:17:34 -05:00
Brian M. Carlson
17e7e9ed3d Remove fix to fail tests 2020-10-08 15:17:34 -05:00
Brian M. Carlson
9c678e108c Fix double-sync crash on postgres 9.x 2020-10-08 15:17:34 -05:00
Brian M. Carlson
7ffe68eba0 Publish
- pg-connection-string@2.4.0
 - pg-cursor@2.4.0
 - pg-protocol@1.3.0
 - pg-query-stream@3.3.0
 - pg@8.4.0
2020-10-04 14:26:29 -05:00
Brian M. Carlson
125a2686e8 Update changelog 2020-10-04 14:26:04 -05:00
dependabot[bot]
da2bb85987 Bump node-fetch from 2.6.0 to 2.6.1
Bumps [node-fetch](https://github.com/bitinn/node-fetch) from 2.6.0 to 2.6.1.
- [Release notes](https://github.com/bitinn/node-fetch/releases)
- [Changelog](https://github.com/node-fetch/node-fetch/blob/master/docs/CHANGELOG.md)
- [Commits](https://github.com/bitinn/node-fetch/compare/v2.6.0...v2.6.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-04 14:15:19 -05:00
Brian C
7649890bfa Update SPONSORS.md 2020-10-04 14:14:58 -05:00
Benjie Gillam
c5445f0288 Fix metadata for pg-connection-string 2020-10-04 13:36:55 -05:00
Bogdan Chadkin
a02dfac5ad Replace semver with optional peer dependencies
See example bb74168c95/package.json (L42-L49)

This feature is supported by both npm and yarn.
2020-10-04 13:35:16 -05:00
Tom Carrio
58258430d5 Public export of DatabaseError
- Updated root exports of 'pg-protocol' to include DatabaseError

Ref: #2340
2020-10-04 13:33:49 -05:00
Benjie Gillam
e421167d46 Add ssl=true into the test 2020-10-04 13:33:21 -05:00
Benjie Gillam
9cbea21587 Solve issues caused by config.ssl = true 2020-10-04 13:33:21 -05:00
Benjie Gillam
6be3b9022f Add support for ?sslmode connection string param 2020-10-04 13:33:21 -05:00
John
f0fc470d88
Update README.md (#2330) 2020-09-03 22:10:50 +00:00
Brian M. Carlson
95b5daadaa Publish
- pg-cursor@2.3.3
 - pg-query-stream@3.2.3
 - pg@8.3.3
2020-08-26 15:59:37 -05:00
Brian M. Carlson
1f0d3d567f Add test for pgpass check function scope 2020-08-26 15:58:37 -05:00
Pimm "de Chinchilla" Hogeling
0758b766aa Fix context (this) in _checkPgPass. 2020-08-26 15:58:37 -05:00
Brian M. Carlson
acfbafac82 Publish
- pg-cursor@2.3.2
 - pg-query-stream@3.2.2
 - pg@8.3.2
2020-08-18 09:38:12 -05:00
Brian M. Carlson
07ee1bad37 Bump version 2020-08-18 09:37:35 -05:00
Brian M. Carlson
65156e7d24 Small readme updates & auto-formatting 2020-08-18 09:22:05 -05:00
Brian C
61e4b7f03b
Merge pull request #2309 from chris--young/ssl-err
Prevents bad ssl credentials from causing a crash
2020-08-18 08:23:55 -05:00
Christopher Young
f4d123b09e Prevents bad ssl credentials from causing a crash
Fixes: https://github.com/brianc/node-postgres/issues/2307
Fixes: https://github.com/brianc/node-postgres/issues/2004
2020-08-12 07:22:34 -07:00
Brian C
316bec3b43
Merge pull request #2294 from charmander/test-fixes
Fix most SSL negotiation packet tests being ignored
2020-08-05 09:45:10 -05:00
Charmander
3edcbb784f Fix most SSL negotiation packet tests being ignored
`tc` was only one variable and the tests are asynchronous, so every test was writing 'E'.
2020-07-26 20:54:43 -07:00
Charmander
1b022f8c5f Remove accidentally duplicated methods
Fixes #2293.
2020-07-26 10:30:01 -07:00
Brian C
b8773ce236
Merge pull request #2289 from brianc/dependabot/npm_and_yarn/lodash-4.17.19
Bump lodash from 4.17.15 to 4.17.19
2020-07-21 20:36:41 -05:00
Michael Chris Lopez
692e418e0f
Fix documenation typo in README (#2291) 2020-07-21 07:02:21 +00:00
dependabot[bot]
7b74392ce3
Bump lodash from 4.17.15 to 4.17.19
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.15 to 4.17.19.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.15...4.17.19)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-19 02:56:21 +00:00
Brian C
8291b233b8
Merge pull request #2277 from brianc/bmc/remove-comments
Remove out of date unneeded copyright / license comments
2020-07-16 09:58:20 -05:00
Brian C
2793ca74dc
Merge pull request #2278 from brianc/bmc/refactor-to-classes
Refactor to es6 classes
2020-07-16 09:58:04 -05:00
Brian M. Carlson
9ba4ebb803 Fix SASL again 2020-07-15 13:53:12 -05:00
Brian M. Carlson
66d32c6f3f Fix more SASL. Thank God for tests. 2020-07-15 13:38:34 -05:00
Brian M. Carlson
fdf13bac34 Fix msg not being passed for SASL 2020-07-15 13:30:25 -05:00
Brian M. Carlson
5425bc15d2 Fix untested pgpass code 2020-07-15 13:19:45 -05:00
Brian C
3c176bdf86
Merge pull request #2271 from aravindanve/master
Fix: use types configured on pg client in pg-query-stream
2020-07-15 13:01:39 -05:00
Brian M. Carlson
966278a5cc Instance bound methods are not supported in node 8 2020-07-15 12:59:10 -05:00
Brian M. Carlson
9bf31060e1 Cleanup some dead code 2020-07-15 12:22:13 -05:00
Brian M. Carlson
5ba7e3fb48 Refactor connection to class 2020-07-15 11:49:54 -05:00
Brian M. Carlson
9d1dce9c5d Mark handler methods as 'private' 2020-07-15 11:42:33 -05:00
Brian M. Carlson
63e15d15fa Refactor 2020-07-15 11:31:16 -05:00
Brian M. Carlson
0b424cfff1 Move more functionality to methods 2020-07-15 11:16:46 -05:00
Brian M. Carlson
66e1e76c9b More refactoring 2020-07-15 11:05:31 -05:00
Brian M. Carlson
04e5297d2e Convert more things to ES6 classes 2020-07-15 10:33:33 -05:00
Brian M. Carlson
80d07c489f Remove out of date unneeded copyright / license comments 2020-07-15 10:01:26 -05:00
Charmander
d7b22b390d Fix dependency badges for monorepo 2020-07-10 08:55:31 -07:00
Aravindan Ve
54048235c5
fix: use types configured on pg client in pg-query-stream 2020-07-10 11:43:32 +05:30
Brian M. Carlson
f0bf3cda7b Update changelog 2020-07-09 10:37:32 -05:00
Brian M. Carlson
cf203431d6 Publish
- pg-connection-string@2.3.0
 - pg-cursor@2.3.0
 - pg-query-stream@3.2.0
 - pg@8.3.0
2020-07-09 10:35:06 -05:00
Brian C
c22cc33a10
Merge pull request #2269 from brianc/bmc/add-integration-test
Add integration test for #2216
2020-07-08 13:37:59 -05:00
Brian M. Carlson
3360697bbd Add integration test for #2216 2020-07-08 12:17:20 -05:00
Brian C
da5d4efef4
Merge pull request #2216 from rafiss/pgoptions
Support options connection parameter
2020-07-08 12:16:03 -05:00
Brian M. Carlson
dec892ed01 Publish
- pg-cursor@2.2.2
 - pg-protocol@1.2.5
 - pg-query-stream@3.1.2
 - pg@8.2.2
2020-07-07 08:58:57 -05:00
Brian C
9ba49b73c7
Merge pull request #2241 from PruvoNet/#2240
fix: major performance issues with bytea performance #2240
2020-07-07 08:33:26 -05:00
regevbr
1d3f155d4f
fix: major performance issues with bytea performance #2240 2020-07-03 17:57:07 +03:00
regevbr
69af2672ed
fix: major performance issues with bytea performance #2240 2020-07-03 17:56:13 +03:00
regevbr
410a6ab248
fix: major performance issues with bytea performance #2240 2020-07-03 17:54:29 +03:00
regevbr
bf53552a15
fix: major performance issues with bytea performance #2240 2020-07-03 17:53:22 +03:00
regevbr
64c78b0b0e
fix: major performance issues with bytea performance #2240 2020-07-03 17:52:26 +03:00
Charmander
344731959e
Merge pull request #2260 from liamaharon/patch-1
Fix typo in README.md
2020-06-30 21:54:12 +00:00
Liam Aharon
f49db313c1
Fix typo in README.md 2020-06-30 17:13:41 +10:00
Charmander
6d18f6104f
Merge pull request #2254 from mriedem/patch-1
Fix rejectUnauthorize typo in CHANGELOG
2020-06-24 17:20:45 +00:00
Matt Riedemann
27029ba7c7
Fix rejectUnauthorize typo in CHANGELOG 2020-06-24 11:31:35 -05:00
regevbr
5e0d684446
fix: major performance issues with bytea performance #2240 2020-06-20 10:51:29 +03:00
regevbr
89758cee2f
fix: major performance issues with bytea performance #2240 2020-06-19 03:39:06 +03:00
regevbr
316b119e63
fix: major performance issues with bytea performance #2240 2020-06-19 03:27:39 +03:00
regevbr
13ff0e11ed
fix: major performance issues with bytea performance #2240 2020-06-19 02:53:17 +03:00
regevbr
c31205f437
fix: major performance issues with bytea performance #2240 2020-06-19 02:32:00 +03:00
regevbr
0455504e22
fix: major performance issues with bytea performance #2240 2020-06-18 14:49:50 +03:00
Charmander
ea6ac2ad23 Remove the last __dirnames in requires
Follow-up to eeb62ba40da27941dad144635ee84b283950d411.
2020-05-18 18:30:21 -07:00
Charmander
ff302b10ce
Merge pull request #2221 from sehrope/misc-test-cleanup
Test require clean up and refactoring to remove BufferList global
2020-05-17 18:12:07 +00:00
Sehrope Sarkuni
96e2f20a1d test: Replace global BufferList with local require
Removes assigning BufferList to a global in top level test-helper and adds explicit
require in the tests that need to access it.
2020-05-16 08:43:38 -04:00
Sehrope Sarkuni
02c4fc5b95 test: Remove unused imports in test-helpers 2020-05-16 08:28:57 -04:00
Sehrope Sarkuni
87559bdbfa test: Remove unused count variable
Removes unused count var. Sink function below it shadows the variable within
its add(...) function so file level count variable is never used.
2020-05-16 08:28:57 -04:00
Sehrope Sarkuni
bd28c0f15c test: Remove unused getMode() function 2020-05-16 08:28:57 -04:00
Sehrope Sarkuni
eeb62ba40d test: Replace __dirname concatenations in require(...) with relative paths
Replaces __dirname concatentation in pg test scripts so that editors like
VS Code can automatically generate typings and support code navigation (F12).
2020-05-16 07:41:15 -04:00
Brian M. Carlson
f3136a7d5d Publish
- pg-connection-string@2.2.3
 - pg-cursor@2.2.1
 - pg-pool@3.2.1
 - pg-protocol@1.2.4
 - pg-query-stream@3.1.1
 - pg@8.2.1
2020-05-15 18:33:34 -05:00
Brian C
59cbf03e1b
Merge pull request #2220 from brianc/bmc/fix-loop
Send sync after flush
2020-05-15 18:20:04 -05:00
Brian M. Carlson
a79c8e7992 Send sync after flush 2020-05-15 17:51:09 -05:00
Brian C
d5b615e98e
Merge pull request #2217 from charmander/normal-encoding-parameter
Send the `client_encoding` startup parameter value with more typical formatting
2020-05-15 12:54:44 -05:00
Rafi Shamim
06cdf3e9f0 Support options connection parameter
This supports the connection parameter documented here:
https://www.postgresql.org/docs/9.1/libpq-connect.html#LIBPQ-CONNECT-OPTIONS
2020-05-14 10:07:35 -04:00
Charmander
d8422552d1 Merge branch 'master' into normal-encoding-parameter 2020-05-13 23:59:39 -07:00
Charmander
bf40f03788 Send the client_encoding startup parameter value with more typical formatting
All non-alphanumerics are ignored, but `'utf-8'` is weird. `UTF8` is the canonical name, and is what libpq sends.
2020-05-13 23:56:20 -07:00
Brian C
bf469399b8
Merge pull request #2213 from brianc/bmc/upgrade-mocha
Upgrade mocha
2020-05-13 14:52:39 -05:00
Brian M. Carlson
8404434279 Upgrade mocha 2020-05-13 11:49:37 -05:00
Brian M. Carlson
70c8e5f451 Update changelog 2020-05-13 09:17:08 -05:00
Brian M. Carlson
9e55a7073b Publish
- pg-cursor@2.2.0
 - pg-protocol@1.2.3
 - pg-query-stream@3.1.0
 - pg@8.2.0
2020-05-13 09:10:34 -05:00
Brian C
5930e4fa38
Merge pull request #2210 from brianc/bmc/switch-to-fast-connection
Switch internals to use faster connection
2020-05-13 08:54:16 -05:00
Brian M. Carlson
72b5f6d669 Add test & fix packed packet parsing error for SASL authentication messages 2020-05-12 17:20:17 -05:00
Brian M. Carlson
08afb12dcc Set noDelay to true 2020-05-12 16:32:40 -05:00
Brian M. Carlson
520bd35319 Switch internals to use faster connection
This switches the internals to use faster protocol parsing & serializing.  This results in a significant (30% - 50%) speed up in some common query patterns.  There is quite a bit more performance work I need to do, but this takes care of some initial stuff & removes a big fork in the code.
2020-05-12 10:56:14 -05:00
Brian C
1c441d2378
Merge pull request #2208 from sehrope/add-scram-tests
Add some SCRAM tests and enable them on travis
2020-05-12 10:06:14 -05:00
Sehrope Sarkuni
c25e88916a test: Enable scram tests on travis 2020-05-10 09:07:36 -04:00
Sehrope Sarkuni
4a80468a8a test: Add sasl-scram-tests.js
Adds tests for SCRAM if SCRAM_TEST_PGUSER and SCRAM_TEST_PGPASSWORD
are defined. If not the tests are skipped (default).
2020-05-10 09:07:36 -04:00
Brian M. Carlson
c55758fca0 Update changelog 2020-05-08 10:51:13 -05:00
Brian M. Carlson
bd7caf5742 Remove sponsor logo 2020-05-08 10:51:08 -05:00
Brian M. Carlson
3f5bc58a86 Publish
- pg-connection-string@2.2.2
 - pg-cursor@2.1.11
 - pg-pool@3.2.0
 - pg-query-stream@3.0.8
 - pg@8.1.0
2020-05-08 10:42:57 -05:00
Brian C
70cf4dc6ed
Merge pull request #2198 from brianc/benhjames-bhsj/noverify
Add no-verify ssl option
2020-05-07 14:56:05 -05:00
Brian M. Carlson
7929f6ae44 Make change less invasive and fully backwards compatible for native binding config 2020-05-07 11:36:39 -05:00
Brian C
2b7e4b9399
Merge pull request #2200 from revolunet/patch-2
doc: add pg-connection-string in readme packages
2020-05-06 12:47:10 -05:00
Julien Bouquillon
a7aa1bbb1d
doc: add pg-connection-string in readme packages 2020-05-06 18:56:16 +02:00
Brian C
8d1b200a3a
Update SPONSORS.md 2020-05-06 11:54:39 -05:00
Brian M. Carlson
1864910778 Add test for no-verify string config option 2020-05-05 11:08:05 -05:00
Brian M. Carlson
e9073f5a00 Cleanup & comments 2020-05-05 11:03:29 -05:00
Brian M. Carlson
b89eb0f81d Write tests & unify treatment of no-verify 2020-05-05 10:58:34 -05:00
Brian M. Carlson
d8c7005115 Merge branch 'bhsj/noverify' of https://github.com/benhjames/node-postgres into benhjames-bhsj/noverify 2020-05-05 10:35:46 -05:00
Brian C
88da148b18
Merge pull request #2196 from brianc/bmc/use-monorepo-connection-string
Use monorepo connection string
2020-05-05 10:31:04 -05:00
Brian C
db6a023bec
Merge pull request #2197 from brianc/bmc/fix-bad-require
Fix relative  path import
2020-05-05 10:30:32 -05:00
Brian M. Carlson
9e11004e8a No need to import from dist 2020-05-05 09:53:56 -05:00
Brian M. Carlson
3a2af0f52c Fix relative path import
Closes #2188
2020-05-05 09:50:53 -05:00
Brian M. Carlson
698993ec6d Use monorepo connection string 2020-05-05 09:43:31 -05:00
Brian C
77e45c989f
Merge pull request #2194 from papandreou/fix/monorepoRepoLinks
Fix repository field in package.json files after packages were moved into monorepo
2020-05-05 09:37:03 -05:00
Ben Salili-James
6937a2428b Add PGSSLMODE=noverify support to opt-out of rejecting self-signed certs 2020-05-05 13:24:11 +01:00
Andreas Lind
abb1f34020 Fix repository field in package.json 2020-05-05 09:26:42 +02:00
Brian M. Carlson
afd14cb5f9 Publish
- pg-connection-string@2.2.1
2020-04-28 21:56:25 -05:00
Brian C
e93ecacbac
Merge pull request #2184 from brianc/bmc/pg-connection-string
Include pg-connection-string into monorepo
2020-04-28 21:55:06 -05:00
Brian M. Carlson
ddf81128ab Check for the correct binary 2020-04-28 10:20:22 -05:00
Brian M. Carlson
16344cbfcd Update test command for travis
I think the new syntax I'm using here is compatible with `sh`...let's see.
2020-04-28 10:07:12 -05:00
Brian M. Carlson
3a831fc77c Run lint --fix 2020-04-28 10:02:38 -05:00
Brian M. Carlson
4aff01ef8f Add 'packages/pg-connection-string/' from commit '5233b3e77e396a368130709e762fca836290a528'
git-subtree-dir: packages/pg-connection-string
git-subtree-mainline: 35328807e3612cb267bee86dccb2551ad186624a
git-subtree-split: 5233b3e77e396a368130709e762fca836290a528
2020-04-28 09:50:40 -05:00
Brian M. Carlson
35328807e3 Publish
- pg-cursor@2.1.10
 - pg-pool@3.1.1
 - pg-protocol@1.2.2
 - pg-query-stream@3.0.7
 - pg@8.0.3
2020-04-22 11:04:51 -05:00
Brian M. Carlson
a86cb90043 lockfile 2020-04-22 11:04:14 -05:00
Brian C
932c89ded7
Merge pull request #2171 from charmander/no-readystate
Replace uses of private/undocumented `readyState` API
2020-04-22 10:58:46 -05:00
Charmander
c8fb4168d4 Add Node 14 to CI 2020-04-21 23:23:52 -07:00
Charmander
149f482324 Replace uses of private/undocumented readyState API
The `readyState` of a newly-created `net.Socket` changed from `'closed'` to `'open'` in Node 14.0.0, so this makes the JS driver work on Node 14.

`Connection` now always calls `connect` on its `stream` when `connect` is called on it.
2020-04-21 23:20:48 -07:00
Brian C
0729130c57
Merge pull request #2164 from johan13/mem-leak
Refactor pg-pool to avoid potential memory leak
2020-04-21 17:10:50 -05:00
Johan Levin
7de8b49ad7 Refactor pg-pool to avoid potential memory leak
Reduce the closure scope captured by the "release once" lambda function
in _acquireClient so that it does not retain the pendingItem promise.
2020-04-15 11:46:15 +02:00
Brian C
2ef5550373
Merge pull request #2161 from brianc/bmc/lint
Prettier the codebase
2020-04-10 12:32:17 -05:00
Brian M. Carlson
3d9678e2e9 Remove packages from linting themselves in ci as its done at the 'top level' 2020-04-10 12:09:16 -05:00
Brian M. Carlson
12049b7dbc Actually run lint in ci 2020-04-10 11:33:46 -05:00
Brian M. Carlson
8591d94fcc Re-upgrade to prettier@2.x 2020-04-10 11:31:03 -05:00
Brian M. Carlson
6353affeca Downgrade to prettier@1.x to support node@8.x 2020-04-10 11:15:42 -05:00
Brian M. Carlson
c13cf81ee8 Lint pg & turn off semicolons 2020-04-10 10:47:57 -05:00
Brian M. Carlson
6adbcabf50 lint pg-protcol 2020-04-10 10:43:54 -05:00
Brian M. Carlson
cb928ded2a Prettier pg-query-stream 2020-04-10 10:34:34 -05:00
Brian M. Carlson
3002d5cbdd Auto-fix pg-cursor 2020-04-10 10:29:54 -05:00
Brian M. Carlson
a8471aa54b Set up prettier in workspace dir 2020-04-10 10:29:13 -05:00
Brian M. Carlson
41c899c5a2 Update changelog 2020-04-09 15:19:53 -05:00
Brian M. Carlson
da03b3f905 Publish
- pg-cursor@2.1.9
 - pg-pool@3.1.0
 - pg-protocol@1.2.1
 - pg-query-stream@3.0.6
 - pg@8.0.2
2020-04-09 15:17:54 -05:00
Brian C
0399fe5f83
Merge pull request #2157 from chriskchew/ckc/maxuses2
Add maxUses config option to Pool
2020-04-09 14:59:48 -05:00
Brian C
ae5dae4fa4
Make several small speed tweaks for binary reading & writing (#2158) 2020-04-09 14:58:48 -05:00
Chris Chew
de81f71417 Added maxUses config option to Pool; Dev setup instructions in main README 2020-04-09 14:08:11 -05:00
Brian M. Carlson
0a90e018cd Publish
- pg-cursor@2.1.8
 - pg-protocol@1.2.0
 - pg-query-stream@3.0.5
 - pg@8.0.1
2020-04-09 13:22:14 -05:00
Brian C
3ff91eaa32
Decouple serializing messages w/ writing them to socket (#2155)
* Move message writing to typescript lib

* Write more tests, cleanup code to some extent

* Rename package to something more representing its name

* Remove unused code

* Small tweaks based on microbenchmarks

* Rename w/o underscore
2020-04-09 12:28:19 -05:00
Brian C
2013d77b28
Parser speed improvements (#2151)
* Change from transform stream

* Yeah a thing

* Make tests pass, add new code to travis

* Update 'best' benchmarks and include tsc in pretest script

* Need to add build early so we can create test tables

* logging
2020-04-02 16:48:22 -05:00
Brian M. Carlson
90c6d1390e Update changelog
closes #2150
2020-04-01 09:15:54 -05:00
Brian M. Carlson
a227d3e8d4 Publish
- pg-cursor@2.1.7
 - pg-pool@3.0.0
 - pg-query-stream@3.0.4
 - pg@8.0.0
2020-03-30 10:45:12 -05:00
Brian C
aafd8ac64e
8.0 Release (#2117)
* Drop support for EOL versions of node (#2062)

* Drop support for EOL versions of node

* Re-add testing for node@8.x

* Revert changes to .travis.yml

* Update packages/pg-pool/package.json

Co-Authored-By: Charmander <~@charmander.me>

Co-authored-by: Charmander <~@charmander.me>

* Remove password from stringified outputs (#2066)

* Remove password from stringified outputs

Theres a security concern where if you're not careful and you include your client or pool instance in console.log or stack traces it might include the database password.  To widen the pit of success I'm making that field non-enumerable.  You can still get at it...it just wont show up "by accident" when you're logging things now.

The backwards compatiblity impact of this is very small, but it is still technically somewhat an API change so...8.0.

* Implement feedback

* Fix more whitespace the autoformatter changed

* Simplify code a bit

* Remove password from stringified outputs (#2070)

* Keep ConnectionParameters’s password property writable

`Client` writes to it when `password` is a function.

* Avoid creating password property on pool options

when it didn’t exist previously.

* Allow password option to be non-enumerable

to avoid breaking uses like `new Pool(existingPool.options)`.

* Make password property definitions consistent

in formatting and configurability.

Co-authored-by: Charmander <~@charmander.me>

* Make `native` non-enumerable (#2065)

* Make `native` non-enumerable

Making it non-enumerable means less spurious "Cannot find module"
errors in your logs when iterating over `pg` objects.

`Object.defineProperty` has been available since Node 0.12.

See https://github.com/brianc/node-postgres/issues/1894#issuecomment-543300178

* Add test for `native` enumeration

Co-authored-by: Gabe Gorelick <gabegorelick@gmail.com>

* Use class-extends to wrap Pool (#1541)

* Use class-extends to wrap Pool

* Minimize diff

* Test `BoundPool` inheritance

Co-authored-by: Charmander <~@charmander.me>
Co-authored-by: Brian C <brian.m.carlson@gmail.com>

* Continue support for creating a pg.Pool from another instance’s options (#2076)

* Add failing test for creating a `BoundPool` from another instance’s settings

* Continue support for creating a pg.Pool from another instance’s options

by dropping the requirement for the `password` property to be enumerable.

* Use user name as default database when user is non-default (#1679)

Not entirely backwards-compatible.

* Make native client password property consistent with others

i.e. configurable.

* Make notice messages not an instance of Error (#2090)

* Make notice messages not an instance of Error

Slight API cleanup to make a notice instance the same shape as it was, but not be an instance of error.  This is a backwards incompatible change though I expect the impact to be minimal.

Closes #1982

* skip notice test in travis

* Pin node@13.6 for regression in async iterators

* Check and see if node 13.8 is still borked on async iterator

* Yeah, node still has changed edge case behavior on stream

* Emit notice messages on travis

* Revert "Revert "Support additional tls.connect() options (#1996)" (#2010)" (#2113)

This reverts commit 510a273ce45fb73d0355cf384e97ea695c8a5bcc.

* Fix ssl tests (#2116)

* Convert Query to an ES6 class (#2126)

The last missing `new` deprecation warning for pg 8.

Co-authored-by: Charmander <~@charmander.me>
Co-authored-by: Gabe Gorelick <gabegorelick@gmail.com>
Co-authored-by: Natalie Wolfe <natalie@lifewanted.com>
2020-03-30 10:31:35 -05:00
dependabot[bot]
c036779d9c
Bump acorn from 7.1.0 to 7.1.1 (#2136)
Bumps [acorn](https://github.com/acornjs/acorn) from 7.1.0 to 7.1.1.
- [Release notes](https://github.com/acornjs/acorn/releases)
- [Commits](https://github.com/acornjs/acorn/compare/7.1.0...7.1.1)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-03-30 10:31:04 -05:00
Herman J. Radtke III
5233b3e77e Release v2.2.0 2020-03-19 21:57:19 -07:00
Sam :D
11d7c591fa
typo fix (#2118) 2020-02-26 10:49:41 -06:00
Brian C
1c8b6b93cf
Call callback when end called on unconnected client (#2109)
* Call callback when end called on unconnected client

Closes #2108

* Revert a bit of the change

* Use readyState because pending doesn't exist in node 8.x

* Update packages/pg/lib/client.js

use bring your own promise

Co-Authored-By: Charmander <~@charmander.me>

Co-authored-by: Charmander <~@charmander.me>
2020-02-25 08:48:58 -06:00
Brian M. Carlson
29877530c6 Publish
- pg-cursor@2.1.6
 - pg-query-stream@3.0.3
 - pg@7.18.2
2020-02-20 10:33:37 -06:00
Brian M. Carlson
069c2e4ba7 Update sponsors 2020-02-20 10:32:38 -06:00
Kyle Lilly
c2f4b284b1
Implement handleEmptyQuery for pg-query-stream. (#2106) 2020-02-19 12:12:46 -06:00
Herman J. Radtke III
4356679356
Merge pull request #36 from djmitche/format-docs
Include documentation on the URL format in the README
2020-02-17 09:34:43 -08:00
Dustin J. Mitchell
b4e0ba329a Include documentation on the URL format in the README
This summarizes the common forms, but omits some of the more particular,
and unnecessary forms, such as specifying UNIX domain sockets with
`pg://` URLs.
2020-02-16 12:30:46 -05:00
Michal Brašna
823153138f
Destroy socket when there was an error on it (#1975)
When error happens on socket, potentially dead socket is kept open indefinitely by calling "connection.end()".
Similar issue is that it keeps socket open until long-running query is finished even though the connection was ended.
2020-02-14 08:23:41 -08:00
Karl Becker
e404dd517e
Little typo fix, and add GitHub Sponsors (#2104)
Since I believe GitHub Sponsors is your preferred way to donate now, maybe you want to totally get rid of the mention of Patreon, or mention that GitHub Sponsors is preferred?
2020-02-13 11:13:46 -08:00
Herman J. Radtke III
9b89828fac
Merge pull request #34 from danielrozenberg/support-other-socket-modes
Support more modes to set the host as a socket
2020-02-01 08:33:42 -08:00
Brian M. Carlson
b3f0728a11 Publish
- pg-cursor@2.1.5
 - pg-query-stream@3.0.2
 - pg@7.18.1
2020-01-29 18:20:42 -06:00
Brian C
5be3d95f62
Remove double-send of ssl request packet (#2086)
* Remove double-send of ssl request packet

I missed the fact that we are already sending this.  Since I don't have good test coverage for ssl [which I am planning on fixing next](https://github.com/brianc/node-postgres/issues/2009) this got missed.

I'm forcing an SSL test on travis.  This will break for me locally as I don't have SSL enabled on my local test DB. Something I will also remedy.
2020-01-29 18:10:23 -06:00
Brian M. Carlson
c0df3b3e95 Update changelog 2020-01-29 10:53:59 -06:00
Brian M. Carlson
d9fcda8cf7 Publish
- pg-cursor@2.1.4
 - pg-pool@2.0.10
 - pg-query-stream@3.0.1
 - pg@7.18.0
2020-01-29 10:48:38 -06:00
Brian M. Carlson
717ffd0e70 Update ignores 2020-01-29 10:46:03 -06:00
Brian C
11ab1daadd
Close connection on SSL connection errors (#2082)
* Close connection on SSL connection errors

Fixes #2079

* Fix test

* Remove console.log

* Fix tests, implement same behavior for native client

* Fix tests
2020-01-29 10:18:20 -06:00
Daniel Rozenberg
7ec9b70180 Use regex instead of startsWith which is unsupported in node 0.10 2020-01-28 19:40:51 -05:00
Daniel Rozenberg
b309db074f Support URL-encoded socket names 2020-01-28 19:29:38 -05:00
Daniel Rozenberg
0ff40e733b host= query param takes precedence 2020-01-28 19:28:45 -05:00
Brian C
727f1a0ee3
Do not return broken clients to the pool (#2083)
* Prevent requeuing a broken client

If a client is not queryable, the pool should prevent requeuing instead
of strictly enforcing errors to be propagated back to it.

* Write tests for change

* Use node 13.6 in travis

Some weird behavior changed w/ async iteration in node 13.7...I'm not sure if this was an unintentional break or not but it definitely diverges in behavior from node 12 and earlier versions in node 13...so for now going to run tests on 13.6 to unblock the tests from running while I track this down.

* Update packages/pg-pool/test/releasing-clients.js

Co-Authored-By: Charmander <~@charmander.me>

* Update .travis.yml

Co-authored-by: Johannes Würbach <johannes.wuerbach@googlemail.com>
Co-authored-by: Charmander <~@charmander.me>
2020-01-28 10:53:29 -06:00
Charmander
3f6760c62e Update copyright years
because someone will make a PR otherwise. No, this isn’t actually necessary.
2020-01-15 15:44:08 -08:00
Charmander
ee8d32f97c Deprecate implicit TLS rejectUnauthorized: false (#2075)
Yes, it treats `undefined` as `false`. Discussion in #2009. Introduced unintentionally in pg 0.8.7.
2020-01-15 14:59:26 -06:00
Daniel Hritzkiv
d456f1cda0 Update package.json (#2074)
Change the homepage URL's scheme to https
2020-01-14 08:00:55 -08:00
Charmander
ae3f13fad6 Fix tests skipped because of missing suffixes (#2071)
* Fix tests skipped because of missing suffixes

Mocha will happen eventually!

* Skip password tests when they can’t work

Will be made more visible when tests are ported to Mocha.

* Add testing with a user with a password to CI

Should reveal a bug in the password enumerability work, I think.

* Explain new CI matrix entry for password authentication

[ci skip]
2020-01-13 13:00:01 -06:00
Brian M. Carlson
5cf8f5f8d7 Publish
- pg-cursor@2.1.3
 - pg-query-stream@3.0.0
 - pg@7.17.1
2020-01-10 09:22:00 -06:00
Charmander
a046a5a4a5 Fix typo in changelog 2020-01-09 22:40:22 -08:00
Brian C
0895460046
pg-query-stream@3.0 release (#2059)
* Fix one unintentional possible breaking change & update readme

* Update changelog more

* Update CHANGELOG.md

Co-Authored-By: Charmander <~@charmander.me>

Co-authored-by: Charmander <~@charmander.me>
2020-01-09 23:33:40 -06:00
Brian C
19308f9ceb
Result.fields should always be an array (#2060)
This fixes a subtle backwards incompatible change.  Added a test to prevent further regressions.  Closes #2056
2020-01-09 21:30:53 -06:00
Brian C
8eca181d20
Fix pg-query-stream implementation (#2051)
* Fix pg-query-stream

There were some subtle behaviors with the stream being implemented incorrectly & not working as expected with async iteration.  I've modified the code based on #2050 and comments in #2035 to have better test coverage of async iterables and update the internals significantly to more closely match the readable stream interface.

Note: this is a __breaking__ (semver major) change to this package as the close event behavior is changed slightly, and `highWaterMark` is no longer supported.  It shouldn't impact most usage, but breaking regardless.

* Remove a bunch of additional code

* Add test for destroy + error propagation

* Add failing test for destroying unsubmitted stream

* Do not throw an uncatchable error when closing an unused cursor
2019-12-29 23:08:09 -06:00
Brian M. Carlson
6d93951783 Publish
- pg-cursor@2.1.2
 - pg-query-stream@2.1.2
 - pg@7.17.0
2019-12-29 17:50:24 +00:00
Brian M. Carlson
c8b9488d7c Update changelog 2019-12-29 17:45:50 +00:00
Brian C
6b39253a54
Merge pull request #2049 from aheuermann/idle_in_transaction_session_timeout
Adding ability to pass through idle_in_transaction_session_tim…
2019-12-29 11:38:30 -06:00
Brian M. Carlson
af4d05445d Publish
- pg-cursor@2.1.1
 - pg-pool@2.0.9
 - pg-query-stream@2.1.1
 - pg@7.16.1
2019-12-28 17:16:42 +00:00
Brian C
0b87d494ad
Merge pull request #2048 from brianc/bmc/add-pg-pool
Add pg-pool to monorepo
2019-12-28 10:28:26 -06:00
Andrew Heuermann
6ddbe6ab60
Close connection after version check 2019-12-28 09:24:45 -06:00
Andrew Heuermann
839043206d
Only run tests on >= v10 2019-12-28 09:02:04 -06:00
Andrew Heuermann
6363778675
Fixing test 2019-12-27 16:04:45 -06:00
Andrew Heuermann
bb8e806bc5
Adding ability to pass through idle_in_transaction_session_timeout 2019-12-27 15:31:19 -06:00
Brian M. Carlson
637bcf355c Cleanup things a bit 2019-12-27 17:52:28 +00:00
Brian M. Carlson
4c27ad294f Add 'packages/pg-pool/' from commit 'cb96ae2d6e37b1414df405d80258e0e2bafeaba0'
git-subtree-dir: packages/pg-pool
git-subtree-mainline: 69345eb96aa2552b288247960aa7126d41210eb6
git-subtree-split: cb96ae2d6e37b1414df405d80258e0e2bafeaba0
2019-12-27 04:01:42 +00:00
Brian M. Carlson
69345eb96a Publish
- pg-cursor@2.1.0
 - pg-packet-stream@1.1.0
 - pg-query-stream@2.1.0
 - pg@7.16.0
2019-12-27 03:56:07 +00:00
Brian M. Carlson
1cf64444ad Update changelog 2019-12-27 03:55:24 +00:00
Brian C
cc3b09301b
Merge pull request #2045 from brianc/bmc/add-pretest-and-prepublish
Add pretest and prepublish script
2019-12-26 21:52:35 -06:00
Brian M. Carlson
01e0644b99 Add pretest and prepublish script 2019-12-27 03:39:56 +00:00
Brian C
3278dced6e
Merge pull request #2044 from brianc/bmc/packet-stream-parser
Add packet stream parser
2019-12-26 21:36:26 -06:00
Brian C
2431a63853
Merge pull request #2042 from brianc/bmc/callback-on-ready
Fire close callback when ready for next query
2019-12-26 21:30:06 -06:00
Brian M. Carlson
6168f2ee0d Disable lint on missing module since the file is not included 2019-12-27 03:22:30 +00:00
Brian M. Carlson
89b451e934 Properly merge dockerfile 2019-12-27 03:15:51 +00:00
Brian M. Carlson
68e063e30c Merge origin/master 2019-12-27 02:59:42 +00:00
Brian M. Carlson
766e48f34a Update types & move some configs around 2019-12-27 02:55:18 +00:00
Brian M. Carlson
47af4e810f Don't modify path
vscode remote docker does some crazy path overriding...I think this messed it up somehow.  Anyways, no need to do this.
2019-12-26 19:20:43 +00:00
Brian M. Carlson
5a6166d0ae Fire close callback when ready for next query
Working on fixing some timing issues in pg-query-stream it uncovered an issue where the cursor is firing its 'close' callback before it's actually entirely ready to dispatch another query.  This change makes the close callback trigger when the connection re-enters `readyForQuery` state.
2019-12-26 18:36:29 +00:00
Brian M. Carlson
d28d826857 Ignore markdown changes in lerna updated 2019-12-26 18:03:06 +00:00
Brian M. Carlson
5c5dcc5b34 Add node_modules to dockerfile path 2019-12-26 17:50:11 +00:00
Brian M. Carlson
75c94dc7fd Update readme
Add links to pg module and pg-query-stream module
2019-12-26 17:48:15 +00:00
Brian M. Carlson
dfae78e383 Publish
- pg-cursor@2.0.3
 - pg-query-stream@2.0.2
 - pg@7.15.2
2019-12-26 17:42:55 +00:00
Brian M. Carlson
30fb8fbec4 Improve dockerfile prompt 2019-12-26 17:40:03 +00:00
Brian C
b5d584743a
Merge pull request #2041 from brianc/bmc/add-remote-conatiner
Add devcontainer for working on windows
2019-12-26 11:05:51 -06:00
Brian M. Carlson
0167a4177c Add devcontainer for working on windows 2019-12-26 16:56:30 +00:00
Brian M. Carlson
e034010811 Add docker devcontainer stuff 2019-12-26 16:45:37 +00:00
Brian C
582b56d701
Merge pull request #2036 from brianc/bmc/update-readme
Update readme
2019-12-23 10:50:12 -06:00
Brian C
bd3efaac02
Merge pull request #2035 from brianc/bmc/add-pg-query-stream
Add pg-query-stream module
2019-12-23 10:49:09 -06:00
Brian M. Carlson
c090e4fdaf Actually update the right file in the right place... 2019-12-20 17:53:26 -06:00
Brian M. Carlson
8b7e874a37 Update readme 2019-12-20 17:48:26 -06:00
Brian M. Carlson
fdae8516e6 Delete files which are no longer needed as they exist in the monorepo 2019-12-20 15:10:26 -06:00
Brian M. Carlson
6b7b8d19f5 Do not run tests in parallel 2019-12-20 15:03:43 -06:00
Brian M. Carlson
ef2f2d264d Unify lint
Delete accidental addition
2019-12-20 13:46:51 -06:00
Brian M. Carlson
86073026ee Run gitsubtree merge 2019-12-20 12:09:22 -06:00
Brian M. Carlson
db1b95e5f3 Add 'packages/pg-query-stream/' from commit '9ced05e8aab65f3fdf1a67add87bfc9035e487e8'
git-subtree-dir: packages/pg-query-stream
git-subtree-mainline: cccf84e14b3281b753e1baab7bc194aaac5024a8
git-subtree-split: 9ced05e8aab65f3fdf1a67add87bfc9035e487e8
2019-12-20 12:00:58 -06:00
Brian M. Carlson
b0be9da986 Cleanup 2019-12-19 18:57:48 -06:00
Brian M. Carlson
a7c70a9acf All tests passing 2019-12-19 17:44:00 -06:00
Brian C
0189c958f6
Create FUNDING.yml 2019-12-19 16:49:38 -06:00
Brian M. Carlson
e500479382 Add streaming parser 2019-12-19 14:41:05 -06:00
Brian M. Carlson
fa44905b30 port over some tests 2019-12-19 14:33:37 -06:00
Brian M. Carlson
cb96ae2d6e Drop node 4.0 from test matrix 2019-12-19 08:16:52 -06:00
Brian M. Carlson
e302c4c6ff Bump version 2019-12-19 08:13:27 -06:00
Brian M. Carlson
5edcfcb68d Add yarn.lock file 2019-12-19 08:13:17 -06:00
Brian M. Carlson
d2cad38452 Dont use experimental parser yet 2019-12-19 07:39:04 -06:00
Brian M. Carlson
e5d46749c0 Work in progress...convert to more efficient reader 2019-12-18 23:44:43 -06:00
Brian M. Carlson
cccf84e14b Publish
- pg-cursor@2.0.2
 - pg@7.15.1
2019-12-18 15:59:06 -06:00
Brian C
69f30df541
Merge pull request #2030 from brianc/bmc/add-pg-cursor
Add pg cursor
2019-12-18 15:36:00 -06:00
Brian M. Carlson
b14cf678cc Remove postgres 9.1 from test matrix - json is not supported 2019-12-18 14:08:23 -06:00
Brian M. Carlson
57177d749e Use public npm - accidentally had my work npm configured 2019-12-18 13:53:57 -06:00
Brian M. Carlson
5c0c93ce1d Remove nested travis file 2019-12-18 13:47:56 -06:00
Brian M. Carlson
423baa644a Update lint rules for pg-cursor 2019-12-18 13:42:47 -06:00
Brian M. Carlson
37d15740ed Add 'packages/pg-cursor/' from commit '492fbdbb65f6f33396d1017fa4cdbbb247dd3895'
git-subtree-dir: packages/pg-cursor
git-subtree-mainline: ebb81dbfa635eca73d16d54b501f04c8d843bac5
git-subtree-split: 492fbdbb65f6f33396d1017fa4cdbbb247dd3895
2019-12-18 13:20:51 -06:00
Brian M. Carlson
492fbdbb65 Merge branch 'juneidysoo-master' 2019-12-18 13:17:49 -06:00
Brian M. Carlson
e20d0128fc Merge branch 'master' of https://github.com/juneidysoo/node-pg-cursor into juneidysoo-master 2019-12-18 13:16:55 -06:00
Brian C
e34c6021ef
Merge pull request #32 from hetul/fix-closing-finished-connections
Fix closing a finished cursor without supplying a callback
2019-12-18 12:38:30 -06:00
dependabot[bot]
8f819a0e8d Bump js-yaml from 3.12.0 to 3.13.1 (#137)
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 3.12.0 to 3.13.1.
- [Release notes](https://github.com/nodeca/js-yaml/releases)
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/3.12.0...3.13.1)

Signed-off-by: dependabot[bot] <support@github.com>
2019-12-18 10:08:42 -06:00
Johannes Würbach
236db3813d Handle client errors in pool.query (#131)
If an error not related to the query occurs, the client is emitting an
error event.

Forward this event to the callback.
2019-12-18 10:08:30 -06:00
Brian M. Carlson
ebb81dbfa6 Publish
- pg@7.15.0
2019-12-17 10:35:38 -06:00
Brian M. Carlson
7feaafd771 Update changelog 2019-12-17 10:34:09 -06:00
Brian C
1b5f3e33c4
Monorepo (#2014)
* First crack at monorepo

* Update test command

* Update path to script

* Remove node 6 from CI
2019-12-17 08:32:08 -08:00
Charmander
2b59209cf3 Warn when functions intended as constructors are called without new (#2021)
* Warn when pg.Pool() isn’t called as a constructor

in preparation for #1541. `eval` is a bit awkward, but it’s more accurate than an `instanceof` check and will work on platforms new enough to support pg 8 (i.e. only not Node 4).

* Warn when Query() isn’t called as a constructor
2019-12-17 08:02:38 -08:00
Hetul Patel
124c89b173 fix lint issues 2019-12-13 15:30:40 -08:00
Charmander
c1f954b7a6 Remove unreachable branch in parseE (#2020)
The message is created with a fixed name.

56b7c4168d5aa084b2821279ee88d437a2b7636d, released in pg 2.4.0, was when this became applicable and the type of a `notice` event’s argument changed to an Error.
2019-12-12 08:15:53 -08:00
Adam Nielsen
b03a3bd76d Clear connection timeout on error (#2015)
Cancel the connection timeout upon stream error, to avoid getting a stream error followed later by a connection error.
2019-12-12 08:15:19 -08:00
Charmander
8f56b8c2fd Add PostgreSQL 10 to CI (#1947)
* Exit with error code when create-test-tables fails

* Add PostgreSQL 10 to CI

and change to Ubuntu 18.04 so building OpenSSL isn’t necessary, and move old PostgreSQL version tests to the latest Node LTS.

* Add Node 13 to CI

* Preserve create-test-tables’s compatibility with PostgreSQL <9.4
2019-11-20 17:38:40 -06:00
Brian M. Carlson
30f67bb246 Bump version 2019-11-20 10:14:48 -06:00
Brian M. Carlson
b05ea526b8 Update changelog 2019-11-20 10:14:04 -06:00
Brian C
510a273ce4
Revert "Support additional tls.connect() options (#1996)" (#2010)
This reverts commit bf029c827049ca16add0a862d40f4e60dfd9e602.
2019-11-20 10:12:02 -06:00
Brian M. Carlson
c10a96c54d Bump version 2019-11-19 10:44:31 -06:00
Brian M. Carlson
eac3e4dcaf Update changelog 2019-11-19 10:44:23 -06:00
Jim Geurts
bf029c8270 Support additional tls.connect() options (#1996)
* Support additional tls.connect() options

* Pass-through all ssl options to tls.connect()

* Fix lint error

* Remove tls.checkServerIdentity explicit option
2019-11-19 10:10:19 -06:00
Brian C
ced31dd911
Update SPONSORS.md 2019-11-19 10:10:09 -06:00
dependabot[bot]
c8c41c5b65 Bump lodash from 4.17.11 to 4.17.13 (#136)
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.11 to 4.17.13.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.11...4.17.13)

Signed-off-by: dependabot[bot] <support@github.com>
2019-11-19 10:02:08 -06:00
Justin Merz
06fbe19923 Skip TLS SNI if host is IP address (#1890)
* skip TLS SNI if host is IP address (do not set servername option in tls.connect)

* Format code
2019-11-11 15:18:52 -03:00
Sehrope Sarkuni
cd66c0b261 Add explicit files list to package.json (#1951) 2019-11-11 15:11:24 -03:00
Charmander
caa6517999 Fix disconnection tests for pg-pool 2.0.7 (#1946)
* Require latest pg-pool ^2.0.7

to limit variability of next pg’s installations.

* Ignore EPIPE when writing termination message

I don’t know why this wasn’t necessary for tests to pass before…

* Fix disconnection tests for pg-pool 2.0.7

In pg-pool 2.0.7, checked-out clients became responsible for their own 'error' events.

brianc/node-pg-pool#123
2019-11-11 15:10:18 -03:00
Brian M. Carlson
9ced05e8aa Bump version 2019-10-30 14:08:45 -05:00
Brian C
08072a90b8
Pass options to cursor (#65)
* Bump version of pg-cursor

This includes fixes in pg-cursor@2.0.1.  I've relaxed semver a touch so I don't have to release a new version here just for patch changes to pg-cursor.

* Pass options to pg-cursor

fixes #55
2019-10-30 14:08:11 -05:00
dependabot[bot]
05b4c573d2 Bump eslint from 4.4.0 to 4.18.2 (#63)
Bumps [eslint](https://github.com/eslint/eslint) from 4.4.0 to 4.18.2.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v4.4.0...v4.18.2)

Signed-off-by: dependabot[bot] <support@github.com>
2019-10-30 13:03:26 -05:00
Brian C
3e59f28df4
Bump version of pg-cursor (#64)
This includes fixes in pg-cursor@2.0.1.  I've relaxed semver a touch so I don't have to release a new version here just for patch changes to pg-cursor.
2019-10-30 13:03:09 -05:00
Brian M. Carlson
37906091e1 Bump version 2019-10-30 12:55:38 -05:00
Brian C
5055b3a244
Merge pull request #58 from brianc/bmc/add-test-and-deprecate-method
Add additional pool test & deprecate .end
2019-10-30 12:55:02 -05:00
Brian M. Carlson
cedce4bded Fix lint & enable all tests 2019-10-30 12:52:06 -05:00
Brian M. Carlson
507c7eaca4 Merge branch 'master' into bmc/add-test-and-deprecate-method 2019-10-30 12:47:14 -05:00
Brian C
d0e67a93ff
Merge pull request #59 from brianc/bmc/fix-named-portal
Fix named portal not closing
2019-10-30 12:46:13 -05:00
Brian M. Carlson
bd86514c72 Add another test 2019-10-30 11:43:17 -05:00
Brian M. Carlson
389d5d8c14 Fix named portal being left open
When code was added to use a random named portal instead of the empty portal to support redshift we didn't update the close messages approprately.  This could result in postgres keeping locks on tables for modification if streaming and table modification was both done within a transaction.  This update fixes the issue by always issuing a close command on the named portal when query is finished.

fixes #56
2019-10-30 11:33:52 -05:00
Brian C
a84db5ffd7
Add async iterator tests (#62) 2019-10-28 12:46:49 -05:00
dependabot[bot]
a756ee30e4 Bump debug from 2.6.8 to 2.6.9 (#61)
Bumps [debug](https://github.com/visionmedia/debug) from 2.6.8 to 2.6.9.
- [Release notes](https://github.com/visionmedia/debug/releases)
- [Changelog](https://github.com/visionmedia/debug/blob/2.6.9/CHANGELOG.md)
- [Commits](https://github.com/visionmedia/debug/compare/2.6.8...2.6.9)

Signed-off-by: dependabot[bot] <support@github.com>
2019-10-28 12:10:49 -05:00
dependabot[bot]
fb52c52304 Bump js-yaml from 3.9.1 to 3.13.1 (#60)
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 3.9.1 to 3.13.1.
- [Release notes](https://github.com/nodeca/js-yaml/releases)
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/3.9.1...3.13.1)

Signed-off-by: dependabot[bot] <support@github.com>
2019-10-28 12:02:44 -05:00
Mandy Real
e153e3f5fd fixed typo cumbersom (#49) 2019-10-28 12:00:09 -05:00
Brian C
c95a650a73
Upgrade dependencies (#59)
* Upgrade dependencies

- There was a security vuln with mocha, so upgraded mocha.
- Upgraded versions of node we're going to check in travis
- Switched to yarn from npm
- Removed --no-exit as that's standard mocha behavior now

* Enable postgres on newer version of travis
2019-10-28 11:58:35 -05:00
Brian M. Carlson
d3aee3dfc8 Add additional pool test & deprecate .end
There are no tests covering cursor.end().  It's also a weird method to have on the cursor as it terminates the connection to postgres internally.  I don't recall why I added this method in the first place but its not correct to close a connection to postgres by calling .end on a cursor...seems like a pretty big footgun.  If you have a pooled client and you call `cursor.end` it'll close the client internally and likely confuse the pool.  Plus it's just weird to be able to close a connection by calling .end on a query or cursor.  So...I'm deprecating that method.
2019-10-28 11:45:20 -05:00
Brian C
ff09b3f21d
Merge branch 'master' into fix-closing-finished-connections 2019-10-25 18:19:19 -05:00
Brian C
6d47026083
Merge pull request #57 from brianc/bmc/lint-changes
Fix for pg@7.x
2019-10-25 18:17:44 -05:00
Brian M. Carlson
be0321299b Update lint, fix for pg@7.x 2019-10-25 18:11:53 -05:00
Brian M. Carlson
4164686c4b meh 2019-10-25 18:03:07 -05:00
Brian M. Carlson
414fac6a05 Apply prettier to code, change lint rules 2019-10-25 12:14:27 -05:00
Ravi van Rooijen
fde5ec586e Use arrow character in readme 2019-10-13 19:53:56 -07:00
Yuri Astrakhan
2d2a87392c Minor cleanup - inline throwOnRelease() (#129)
The throwOnRelease() function does not appear to be exposed anywhere,
and it does not appear to make any sense to have it as a standalone func,
as it ovecomplicates things and makes function call as non-returning.  Inlined it.
2019-09-03 22:45:45 -07:00
Brian M. Carlson
60d8df659c Bump version 2019-08-09 16:02:25 -05:00
Vitaly Tomilov
05d20a6a6d Update package.json (#1937)
Fixes #1936
2019-08-09 16:00:47 -05:00
Brian M. Carlson
e4578d2c7b Bump version 2019-07-25 13:07:00 -05:00
Brian M. Carlson
d44376ad06 Update sponsors file 2019-07-25 13:06:51 -05:00
Brian M. Carlson
94ad322eb9 Update changelog 2019-07-25 13:06:23 -05:00
Sehrope Sarkuni
3ead900349 Fix eslint and add back standard (#1928)
* lint: Enable standard rules again

* lint: Replace hasOwnProperty(...) call

* lint: Remove trailing spaces

* lint: Remove spaces within array brackets

* lint: Disable quote-props to silence linter

* lint: Skip linting on older node versions
2019-07-25 13:00:14 -05:00
Sehrope Sarkuni
0894a3ce07 feat: Add dynamic retrieval for client password (#1926)
* feat: Add dynamic retrieval for client password

Adds option to specify a function for a client password. When the client
is connected, if the value of password is a function then it is invoked
to get the password to use for that connection.

The function must return either a string or a Promise that resolves to
a string. If the function throws or rejects with an error then it will
be bubbled up to the client.

* test: Add testAsync() helper to Suite

Add testAsync() helper function to Suite to simplify running tests that
return a Promise. The test action is executed and if a syncronous error
is thrown then it is immediately considered failed. If the Promise resolves
successfully then the test is considered successful. If the Promise
rejects with an Error then the test is considered failed.

* test: Add tests for dynamic password

* test: Simplify testAsync error handling

* fix: Clean up dynamic password error handling and misc style

* test: Remove extra semicolons

* test: Change testAsync(...) calls to use arrow functions

* fix: Wrap self.password() invocation in an arrow function

* test: Add a comment to testAsync(...)
2019-07-25 12:48:48 -05:00
Jonathan Baudanza
70d5c09958 Remove reference to "min" config option (#126)
Because it no longer exists.
2019-07-25 12:41:28 -05:00
Brian M. Carlson
e59a7667ff Bump version 2019-07-25 12:39:44 -05:00
Johannes Würbach
f9fc232db3 Remove idleListener when client is in-use (#123)
* Prevent double release with callback

When using the callback instead of client.release, double releasing
a client was possible causing clients to be re-added multiple times.

* Remove idleListener when client is in-use

When a client is in-use, the error handling should be done by the
consumer and not by the pool itself as this otherwise might cause
errors to be handled multiple times.

* Handle verify failures
2019-07-25 12:38:21 -05:00
Brian C
0acaf9d8ff
Fix compare (#1923)
* Fix deepEqual compare

In node 12 assert.deepEqual against a buffer & array no longer passes if the values are the same.  This makes sense.  Updated the test to not use deepEqual in this case.
2019-07-16 18:41:54 -05:00
darkgl0w
d8a0e1e950 Update CI to allow tests to pass on Node.js >= 10.16.0 (#1912)
* Add CI build environment scripts

* Update Travis configuration

* Don't publish CI scripts to npm

* Add Node.js 12 to CI matrix
2019-07-16 14:14:41 -05:00
Juneidy
b0f7958299 Fix hanging listener when error occured 2019-06-27 11:55:38 +08:00
Luis Montes
a483bdf5d9
Merge pull request #31 from iceddev/fix-coverall-badge
fix readme newline typo
2019-06-18 20:56:05 -07:00
Andrew Bowerman
e4c1002e2e
actually include coveralls 2019-06-18 20:49:39 -07:00
Andrew Bowerman
c75c392965
fix readme newline typo 2019-06-18 20:41:10 -07:00
Luis Montes
0f72f29a73
Merge pull request #30 from iceddev/fix-coverall-badge
Update coveralls badge
2019-06-18 20:30:33 -07:00
Andrew Bowerman
c9ee9cd199
Update coveralls badge
Closes #15
2019-06-18 20:25:32 -07:00
Andrew Bowerman
06c46ac12b
2.1.0 2019-06-18 20:12:03 -07:00
Vitaly Tomilov
2c7be86104 minor text improvement in defaults (#1893) 2019-06-17 16:51:16 -05:00
Herman J. Radtke III
4db1a7e9ab
Merge pull request #18 from benny-medflyt/patch-1
Fix typings
2019-06-11 15:37:06 -07:00
benny-medflyt
726f6202fa
Update index.d.ts 2019-05-27 08:30:21 -04:00
Herman J. Radtke III
d7b96e6f44
Merge pull request #28 from hjr3/ssl-parsing
ssl=0 is now parses to false
2019-05-23 14:29:22 -07:00
Herman J. Radtke III
7b62226d57 ssl=0 is now parses to false
Fixes #20
2019-05-23 14:27:46 -07:00
Herman J. Radtke III
43114f4c99
Merge pull request #17 from ywkim/master
Add supporting username and password for socket connections
2019-05-23 13:20:33 -07:00
Herman J. Radtke III
b53c2bd224
Merge pull request #24 from benjie/patch-1
Only publish the required files
2019-05-23 13:17:32 -07:00
Herman J. Radtke III
ac63695b60
Merge pull request #26 from hjr3/ssl-support
Add support for TLS parameters in URI
2019-05-23 13:16:41 -07:00
Herman J. Radtke III
e9270e89af Add support for TLS parameters in URI
The connection string now supports the following parameters:

- sslcert
- sslkey
- sslrootcert

Fixes #25.
2019-05-17 07:58:09 -07:00
Sehrope Sarkuni
8ba1d2c572 Enable eslint:recommended and plugin/node/recommended (#1856)
* Fix typo

* Enable eslint:recommended and remove unused eslint plugins

Enables eslint:recommended by disabling the options that would not pass. Also removes
dependencies for included but unused eslint plugins.

* Convert console.error(...) calls to use %s placeholders

* Enable eslint no-console rule

* Add and enable eslint-node-plugin

* Correct typo

* Enable eslint no-unused-vars
2019-05-10 12:23:49 -05:00
Brian M. Carlson
61cc3d26e2 Bump version 2019-05-10 12:12:16 -05:00
Brian M. Carlson
697bdae507 Update changelog 2019-05-10 12:12:02 -05:00
Peter Boromissza
0993e4b61a Added the missing connect_timeout and keepalives_idle config parameters (#1847)
* Added the missing connect_timeout and keepalives_idle config parameters

* Implementation and tests for keepAliveInitialDelayMillis and connectionTimeoutMillis [squashed 4]
2019-05-10 11:48:38 -05:00
Benjie Gillam
c11dbb1c2b
Only publish the required files
Details: https://docs.npmjs.com/files/package.json#files
2019-04-18 14:46:36 +01:00
Brian M. Carlson
4b530a9e0f Bump version 2019-04-16 17:35:20 -05:00
Brian M. Carlson
0f50d92ea6 Update changelog 2019-04-16 17:35:08 -05:00
Sehrope Sarkuni
13c14f1de0 fix: Catch and emit query parameter prepareValue(...) errors (#1855)
Adds a try/catch block around the prepareValue(...) invocations in query.prepare(...)
to ensure that any that throw an error are caught and bubbled up to the caller.
2019-04-16 17:29:40 -05:00
Tony Wooster
566058de17 Add support for per per-query types (#1825)
The documentation states that you can pass custom type processors to
query objects. See:

https://node-postgres.com/features/queries#types

This didn't actually work. This commit adds an initial implementation
of per-query type-parsing. Caveats:

* It does not work with pg-native. That would require a separate pull
  request to pg-native, and a rather significant change to how that
  library handles query results.

* Per-query types do not "inherit" from types assigned to the Client,
  ala TypeOverrides.
2019-04-16 17:27:39 -05:00
Malcolm
43ebcfb6bc Fix input preparation for date objects with a BC year (#1864)
* test: BC date input preparation

* Fix input preparation for BC dates
2019-04-15 18:38:20 -05:00
Malcolm
4d84909cbd Fix integration test for v1.0.4 of postgres-date sub-dependency (#1867) 2019-04-15 18:37:33 -05:00
Brian M. Carlson
6b8176e841 Bump version 2019-03-15 13:42:56 -05:00
Brian M. Carlson
b12881209b Update CHANGELOG.md 2019-03-15 13:42:24 -05:00
Brian M. Carlson
9cf3d32467 Update SPONSORS.md 2019-03-15 13:42:04 -05:00
andreme
5a92ba3701 sasl/scram authentication (#1835) 2019-03-07 11:02:21 -06:00
Rhys Arkins
41706e64d4 chore: don't publish Travis to npm (#1851) 2019-03-07 10:37:14 -06:00
Brian M. Carlson
bae9fd734a Bump version 2019-03-07 08:58:13 -06:00
Rich Harris
e6a878cbb5 compare prepared statement text with previous to prevent incorrect queries (#1814)
* compare prepared statement text with previous to prevent incorrect queries - fixes #1813

* make suggested changes to error message
2019-03-06 09:35:30 -06:00
Ben Holden-Crowther
4c6c0e9b77 Update license date in readme (#1823) 2019-03-06 09:34:06 -06:00
Brian M. Carlson
e0ebdeff88 Bump version 2019-02-20 14:36:50 -06:00
Brian C
bf84db7c22
Bump packet-reader version (#1840)
* Bump packet-reader version

This should fix the deprecation warning from using `new Buffer`.

* Remove node 11 tests - its a non-stable (odd) version
2019-02-20 14:36:27 -06:00
Brian M. Carlson
fcd0f02210 Bump version 2019-01-11 08:32:29 -06:00
Brian M. Carlson
00123861fb Update changelog 2019-01-11 08:32:23 -06:00
Brian M. Carlson
896faa56f7 Update SPONSORS.md 2019-01-11 08:30:37 -06:00
Ben Holden-Crowther
c8f2f23845 Update license date (#1800)
From 2018 to 2019
2019-01-11 08:16:54 -06:00
Ben Drucker
0e11b5c781 deps: update pg-types to 2 (#1806)
drops node < 4 support but pg previously did so (not major)
2019-01-11 08:16:29 -06:00
Gregory Lepsky
ccbccc9716 Issue #1769 - Inability to restrict communication protocols to set in ssl configuration (#1804)
- Propagate client's ssl.secureOptions config to TLS.
2019-01-08 09:08:43 -06:00
Brian M. Carlson
7d27bd2086 Bump version. Drop version of pg.js via pg-cursor. 2019-01-08 09:00:19 -06:00
Brian M. Carlson
5b2816a6f5 Bump version of pg-cursor 2019-01-08 09:00:04 -06:00
Amila Welihinda
28e43b8b73 Create LICENSE (#34) 2019-01-08 08:57:47 -06:00
Amila Welihinda
d822fc8e7a Added --save flags to installation steps (#35) 2019-01-08 08:57:35 -06:00
Amila Welihinda
c999aae6af Updated readme examples to es6 (#36) 2019-01-08 08:55:35 -06:00
Brian M. Carlson
1cdad4d8d2 Bump version. Drop support for pg.js 2019-01-08 08:53:58 -06:00
Brian M. Carlson
71dde045ea Merge branch 'master' of github.com:brianc/node-pg-cursor 2019-01-08 08:52:25 -06:00
Brian C
67b880a4bd
Merge pull request #35 from jakobrun/master
return rowCount on insert
2019-01-08 08:52:20 -06:00
Brian M. Carlson
1200da5c74 Fix test 2019-01-08 08:52:05 -06:00
Brian C
0a1052516f
Merge pull request #44 from jafl/redshift-requires-portal-name
fix: AWS Redshift requires a portal name to honor fetchSize
2019-01-08 08:28:39 -06:00
Brian C
73506d36b9
Merge pull request #47 from pistor/remove-pg.js-support
Remove support for deprecated pg.js package
2019-01-08 08:27:07 -06:00
Brian M. Carlson
d7f6ed0c7c Bump version 2019-01-02 12:14:50 -06:00
Brian C
4d2ad36951
Upgrade to test on node 10 (#114)
* Upgrade to test on node 10

* Use errno instead of code

* Only check errno if it exists
2019-01-02 12:11:21 -06:00
Bryan Clement
f91769538d idleListener no longer grabs references to things it doesn't need (#83) 2019-01-02 12:10:42 -06:00
Johannes Würbach
35a285c9a7 Fix two timeout races (#109) 2018-12-14 14:15:35 -06:00
Brian M. Carlson
140f9a1242 Bump version 2018-12-11 12:53:22 -06:00
Charmander
7ef3f4aa4a Fix queued checkout after a connection failure (#111)
* Test queued checkout after a connection failure

Co-authored-by: Johannes Würbach <johannes.wuerbach@googlemail.com>

* Fix queued checkout after a connection failure

Co-authored-by: Johannes Würbach <johannes.wuerbach@googlemail.com>
2018-12-11 12:53:00 -06:00
Mikkel Hoegh
6fc07b4a63
fix: remove support for deprecated pg.js package
BREAKING CHANGE: pg.js is long dead and no longer supported.

Use [pg](https://www.npmjs.com/package/pg) instead.
2018-12-05 00:06:10 +01:00
Brian M. Carlson
060a35faeb Bump version 2018-11-29 09:37:03 -06:00
Brian M. Carlson
93df471d98 Bump min version of pg-pool 2018-11-29 09:36:57 -06:00
Brian M. Carlson
f52a0fe8f7 Bump version 2018-11-29 09:16:05 -06:00
Brian M. Carlson
77866d0264 Update changelog 2018-11-29 09:15:50 -06:00
André Cruz
eb076db5d4 Add configurable query timeout (#1760)
* Add read_timeout to connection settings

* Fix uncaught error issue

* Fix lint

* Fix "queryCallback is not a function"

* Added test and fixed error returning

* Added query timeout to native client

* Added test for timeout not reached

* Ensure error is the correct one
Correct test name

* Removed dubious check

* Added new test

* Improved test
2018-11-29 09:11:47 -06:00
Brian M. Carlson
4b9669eaa7 Bump version 2018-11-12 12:32:19 -06:00
Brian M. Carlson
3620e23899 Bump version 2018-11-07 09:32:45 -06:00
Brian C
daddd4ffd6
Bump buffer-writer version (#1764)
Fixes the deprecation warning for using `new Buffer`.

The change is semver major in buffer-writer since we dropped support for node < 4.x, but otherwise it's a non-breaking change.  Since node-postgres already requires node >= 4.x it's fine.
2018-11-07 09:31:59 -06:00
Brian M. Carlson
a3295b4355 Bump version 2018-10-26 09:03:19 -05:00
Brian M. Carlson
034eb34f3c Update changelog 2018-10-26 09:02:53 -05:00
Brian C
d468b6a1f1
Update SPONSORS.md 2018-10-26 08:59:00 -05:00
Igor Savin
badf0a1c65 Update ESLint (#1753)
* Update ESLint

* Downgrade ESLint version to restore Node 4 support

* Downgrade more dependencies

* Keep downgrading
2018-10-26 08:55:31 -05:00
Charmander
1cf1e05ab9 Allow a custom type to be used for Client promises (#1518)
Matches the Pool API.
2018-10-24 10:40:23 -05:00
Igor Savin
ff6fe1e01e Execute tests on Node 11 in CI (#1752) 2018-10-23 13:02:49 -07:00
John Lindal
37997fed76 fix formatting issues 2018-10-23 09:59:50 -07:00
John Lindal
19c68c753e fix: AWS Redshift requires a portal name to honor fetchSize 2018-10-17 14:30:56 -07:00
Brian M. Carlson
6177ff95a6 Bump version 2018-10-08 12:51:13 -05:00
Brian C
2446fdb8d0
Fix for pg@7.5 (#47)
* Fix for pg@7.5

Don't return anything from `stream.submit`

* Add node@10 to travis version

* Relax version of node@4.x
2018-10-08 12:50:11 -05:00
Brian M. Carlson
04a0ec71b4 Bump version 2018-10-03 10:46:12 -05:00
Brian M. Carlson
8cf5a84539 Update changelog 2018-10-03 10:45:53 -05:00
Charmander
3828aa8608 Queued query errors (#1503)
* Add tests for query callbacks after connection-level errors

* Ensure callbacks are executed for all queued queries after connection-level errors

Separates socket errors from error messages, sends socket errors to all queries in the queue, marks clients as unusable after socket errors.

This is not very pleasant but should maintain backwards compatibility…?

* Always call `handleError` asynchronously

This doesn’t match the original behaviour of the type errors, but it’s correct.

* Fix return value of `Client.prototype.query` in immediate error cases

* Mark clients with closed connections as unusable consistently

* Add tests for error event when connecting Client

* Ensure the promise and callback versions of Client#connect always have the same behaviour

* Give same error to queued queries as to active query when ending

and do so in the native Client as well.

* Restore original ordering between queued query callbacks and 'end' event
2018-10-03 10:37:15 -05:00
Thomas Hunter II
fed6375e0a remove query.stream references
* This hasn't been supported since 0b2344b6b5afbb68e89eff1ef2b57ecf0726d80b
* `node-pg-copy-streams` relies on overriding the `handleCopyInResponse` method:
  * https://github.com/brianc/node-pg-copy-streams/blob/e15feb19/index.js#L53
2018-10-03 10:16:42 -05:00
Pat Gaffney
11a4793452 Add error handling for null params to Client.prototype.query() 2018-10-03 10:15:04 -05:00
Charmander
e7602bc678
Merge pull request #1701 from gajus/issue-1699
refactor: simplify the escapeIdentifier logic
2018-07-30 02:46:22 +00:00
Gajus Kuizinas
00d749cdfa refactor: simplify the escapeIdentifier logic 2018-07-29 21:29:27 +01:00
Charmander
6c840aabb0
Merge pull request #1692 from askmike/patch-1
typo in test: g/provded/provided
2018-07-17 01:29:30 +00:00
Mike van Rossum
9bfd4bff40
[test] g/provded/provided 2018-07-17 01:07:00 +08:00
Charmander
a9b3ef7cd3
Merge pull request #1684 from dominicletz/patch-1
Replace poolSize by max in error test
2018-07-09 16:00:55 +00:00
Dominic Letz
28e66ccd4b
Use pool constructor to pass pool size 2018-07-09 14:19:55 +08:00
Dominic Letz
2ea5f91f4a
Replace poolSize by max in error test 2018-07-09 11:46:56 +08:00
Charmander
1cbd507b8c
Merge pull request #1677 from sehrope/fix-network-partition-test-race
Fix network partition test race
2018-06-25 00:33:34 +00:00
Brian C
91bdbbd3d7
Merge pull request #40 from savvymas/patch-1
Add repo to package.json
2018-06-21 14:13:11 -07:00
Savannah Mastrangelo
7eabfbe0ba
Add repo to package.json
Without this pages like https://www.npmjs.com/package/pg-cursor don't link back correctly.
2018-06-20 12:29:41 -04:00
Sehrope Sarkuni
2dc5c6864b Change network partition test to wait for client socket creation prior to destroy 2018-06-17 11:58:37 -04:00
Brian M. Carlson
3ac356a812 Bump version 2018-05-07 10:07:10 -05:00
Matt Keas
7de137f9f8 tls.connect({checkServerIdentity}) option cannot be a null - must be a method or not exist.
Defaults to built-in `tls.checkServerIdentity` method in the event one is not passed into `pgConfig.ssl`

Found breaking in v9.4.2 vs v9.4.1 a la 49054717b4ec0c6d477f04c2becd1f9680b2d13a

cc @tobio @brianc
2018-05-07 10:05:56 -05:00
Brian M. Carlson
83ede28e18 Bump version 2018-05-04 14:01:26 -05:00
Yuval Greenfield
277dc508da Clarifying pool connect logging (#73)
Existing log code was outputting 'connecting new client' twice and saying 'new client connected', creating a false impression when an error (like a timeout) was present.
2018-05-04 13:06:49 -05:00
Yuval Greenfield
6b2883d290 terminiated -> terminated (#78) 2018-05-04 13:06:32 -05:00
Charmander
1871d0f9e1 Remove timed-out checkouts from queue correctly (#86)
* Add failing test for correct removal from checkout queue on timeout

* Remove timed-out checkouts from queue correctly

Fixes #85.
2018-05-04 13:04:42 -05:00
Charmander
fabf39c606 Count only test query itself (#87)
* Count only test query itself

This breaks more obviously in PostgreSQL 10 (https://wiki.postgresql.org/wiki/New_in_postgres_10#Significant_Expansion_of_Wait_Events_in_pg_stat_activity).

* Fix query counting for PostgreSQL 9.1
2018-05-04 12:59:39 -05:00
contra
72db7902fa dont use dynamic functions to parse rows, closes #1417 2018-05-04 12:34:46 -05:00
Toby Brain
49054717b4 Add ability to specify checkServerIdentity callback 2018-05-04 12:33:48 -05:00
Justin Jaffray
831dfb1b4c Pass through portal properly
This happened to work before because `Query.portalName` was undefined,
but in order to be able to set the portal explicitly it should be using
`Query.portal`.
2018-05-04 12:30:17 -05:00
Matthew Blewitt
9389527609 Add comments to case branches, explaining code meanings 2018-05-04 12:20:42 -05:00
Matthew Blewitt
3eb73751f5 Expand test to check for expected and unexpected errors 2018-05-04 12:20:42 -05:00
Matthew Blewitt
7dd3b50e41 Add guard to test to not check errors for empty error messages 2018-05-04 12:20:42 -05:00
Matthew Blewitt
5d32be4a90 Handle SSL negotiation errors more robustly
This commit adds some finer grained detail to handling the postmaster's
response to SSL negotiation packets, by accounting for the possibility
of an 'E' byte being sent back, and emitting an appropriate error.

In the naive case, the postmaster will respond with either 'S' (proceed
with an SSL connection) or 'N' (SSL is not supported). However, the
current if statement doesn't account for an 'E' byte being returned
by the postmaster, where an error is encountered (perhaps unable to
fork due to being out of memory).

By adding this case, we can prevent confusing error messages when SSL is
enforced and the postmaster returns an error after successful SSL
connections.

This also brings the connection handling further in line with
libpq, where 'E' is handled similarly as of this commit:

a49fbaaf8d

Given that there are no longer pre-7.0 databases out in the wild, I
believe this is a safe change to make, and should not break backwards
compatibility (unless matching on error message content).

* Replace if statement with switch, to catch 'S', 'E' and 'N' bytes
  returned by the postmaster
* Return an Error for non 'S' or 'N' cases
* Expand and restructure unit tests for SSL negotiation packets
2018-05-04 12:20:42 -05:00
Vratislav Kalenda
0902d145f4 fix: end stream connection 2018-05-04 12:19:53 -05:00
Sehrope Sarkuni
860928e2d5 Change test to use Buffer.from(...) 2018-05-04 12:18:31 -05:00
Sehrope Sarkuni
272e9a5998 Change network partition test to use socket.destroy() 2018-05-04 12:18:31 -05:00
Sehrope Sarkuni
b0c60cf288 Add node v10 to travis matrix 2018-05-04 12:18:31 -05:00
Charmander
2f14cb1a0f Update CI versions (#88)
* Update CI versions

PostgreSQL 9.1 is no longer available on 14.04.

* Add Node 9 to CI
2018-04-06 11:28:03 -05:00
Elexy
8fb641ee91 upgrade testing node versions 2018-04-04 14:40:25 -07:00
Charmander
87dd65fda5
Merge pull request #1592 from chentsulin/patch-1
use net.Socket instead of net.Stream
2018-03-14 23:33:27 +00:00
C. T. Lin
875236fc0b
use net.Socket instead of net.Stream
`net.Stream` is a undocumented legacy naming from node 0.x
4ae320f2b3/lib/net.js (L1762)
2018-03-14 22:43:52 +08:00
Charmander
50b1221e11
Merge pull request #1585 from BridgeAR/master
Remove `noAssert` argument
2018-03-10 21:15:42 +00:00
Ruben Bridgewater
3f1d7b9bc6
Remove noAssert argument
The support for the `noAssert` argument dropped in the upcoming
Node.js v.10.x. All input is then validated no matter if this
is set to true or not. Just remove the argument because of that.
2018-03-10 22:09:23 +01:00
Charmander
94d38f941e Capitalize some parts of the README 2018-01-09 21:39:40 -08:00
Ben Holden-Crowther
be57714f16 spelling corrections 2018-01-10 05:28:14 +00:00
Brian M. Carlson
a664983cbb Bump version 2018-01-05 13:41:36 -06:00
Pasi Eronen
9825e7c733 Use Buffer.from instead of deprecated Buffer constructor 2018-01-05 13:40:25 -06:00
Pasi Eronen
70a8ee1334 Don't repeat logic for reporting stream errors 2018-01-05 13:40:25 -06:00
Pasi Eronen
4cf67b23d4 Ignore socket hangup when ending connection also with ssl (#1344). 2018-01-05 13:40:25 -06:00
Ben Holden-Crowther
c9ca1dad69 License date in README 2018-01-03 21:09:12 +00:00
Ben Holden-Crowther
1e48733b20 Update license date 2018-01-02 20:15:15 +00:00
jakob
2398e992a8 return rowCount on insert 2018-01-01 18:43:18 +00:00
benny-medflyt
ece7645187
typings: turns out "host" can actually be null 2017-12-13 11:23:28 +02:00
benny-medflyt
929fcb73c3
Fix typings 2017-12-13 11:20:29 +02:00
Brian C
6c723b2f14
Update SPONSORS.md 2017-12-06 10:11:49 -06:00
Brian C
56633a5989
Update SPONSORS.md 2017-12-06 10:06:13 -06:00
Youngwook Kim
279fdeae2f Add supporting username and password for socket connections
This fix adds the ability to use username and password even when using
a socket.
2017-11-22 10:17:22 +09:00
Charmander
9870c86fde Make tests compatible with PostgreSQL 10
PostgreSQL 10 reports its version as only `major.minor`, so it can’t be parsed with semver. The `server_version_num` setting is a major version followed by a four-digit minor version since version 10, and was a three-digit major version followed by a two-digit minor version before that.
2017-11-17 14:16:03 -06:00
Charmander
0b80abacaf Specify collation when relied on in tests
Fixes #189.
2017-11-17 14:12:16 -06:00
Brian M. Carlson
9da3a85cbc Bump version 2017-11-04 14:21:36 -05:00
Brian M. Carlson
fccf8e818c Update changelog 2017-11-04 14:21:28 -05:00
Jan Schär
894e2f2f1e Support Uint8Array values 2017-11-04 14:18:36 -05:00
Robert Treat
32537d5345 Fix minor type in recent changelog entry 2017-11-04 14:17:26 -05:00
Sehrope Sarkuni
19bfb2f9b8 Add postgresql to package.json keywords 2017-11-04 14:17:10 -05:00
Sehrope Sarkuni
c2da0ed978 Sort keywords in package.json 2017-11-04 14:17:10 -05:00
Charmander
74aaced74a Avoid modifying package.json or creating package-lock when running tests with npm 5
Should save some confusion in future pull requests (#1465, #1436, #1363).
2017-11-04 14:16:34 -05:00
Hetul Patel
24e485e81e Fix closing a finished cursor without supplying a callback 2017-10-03 18:13:40 -07:00
Brian C
e087305f31 Update SPONSORS.md 2017-09-06 10:41:25 -05:00
Brian M. Carlson
f66379f5fe Bump version 2017-09-03 14:41:16 -05:00
Brian M. Carlson
dfc7214d14 Update changelog 2017-09-03 14:41:03 -05:00
Sehrope Sarkuni
f1336fcb00 Change Makefile to use local eslint
Changes the Makefile lint target to use the local copy of
eslint that would be installed in node_modules rather than
a global copy that may not be installed.
2017-09-03 14:28:32 -05:00
Josh
ecab41c3f3 restore newline at end of file 2017-09-03 14:14:28 -05:00
Josh
64eb77e94c new test for actual statement timeout 2017-09-03 14:14:28 -05:00
Josh
175b688b90 remove pg-native from dependencies
`npm run test` seems to be adding this
2017-09-03 14:14:28 -05:00
Josh
689bb25e86 fixes 2017-09-03 14:14:28 -05:00
Josh
78fc90366d remove .idea from gitignore 2017-09-03 14:14:28 -05:00
Josh
8839d42547 fixed test failure message 2017-09-03 14:14:28 -05:00
Josh
ad36063ca5 support statement_timeout 2017-09-03 14:14:28 -05:00
Arnaud Benhamdine
4936033adf Check more default properties in configuration teset 2017-09-03 14:01:34 -05:00
Arnaud Benhamdine
d6e7dfee83 Replace poolSize by max in configuration test 2017-09-03 14:01:34 -05:00
Arnaud Benhamdine
3b3e52cdc2 Prefer max over poolSize : max is the only property documented in node-pg-pool 2017-09-03 14:01:34 -05:00
Arnaud Benhamdine
27492efc11 Remove properties no more used in node-pg-pool 2017-09-03 14:01:34 -05:00
Charmander
c961888ceb Revert "Update Grammatical person"
This reverts commit ffc7653b9ebf1572620a1db16f9121e33e0995bc.
2017-09-03 13:58:51 -05:00
Kauê Gimenes
ffc7653b9e Update Grammatical person
Update Grammatical person from First Person to Third Person.
2017-09-01 13:09:49 -05:00
Luis Montes
eafb7acd95 2.0.0 2017-08-30 14:25:59 -07:00
Luis Montes
13687353c9 Use mocha, istanbul, and coveralls (#16)
* some tests

* coveralls and mocha

* coveralls post test hook

* remove done calls
2017-08-30 13:58:52 -07:00
Sehrope Sarkuni
ef3379a480 Normalize export in utils to use short form 2017-08-30 15:30:36 -05:00
Sehrope Sarkuni
e74c13ddad Centralize password md5 hashing logic
Centralize logic for md5 hashing of passwords for authentication. Adds
a new function postgresMd5PasswordHash(user, password, salt) to utils
and updates client.js and tests to use it.
2017-08-30 15:30:36 -05:00
Sehrope Sarkuni
3ad0680e8d Fix reference to md5 helper in test
Fixes reference to md5 helper and removes reference to js client
as the md5 function is now provided by utils.
2017-08-30 15:30:36 -05:00
Luis Montes
cf107b00da Merge pull request #11 from caub/max
thanks, @caub !
2017-08-30 10:26:03 -07:00
Brian C
beba66f2f1 Update SPONSORS.md 2017-08-28 10:57:38 -05:00
Ben Holden-Crowther
80d22da975 Minor improvements
full stop, capitalized Twitter
2017-08-28 10:56:37 -05:00
Jessica Evans
1b55c7bb7b capital letters
minor beautification
2017-08-27 12:46:57 -05:00
Tobias Gurtzick
7d1342e03b verify that sslrootcert is added to libpqConnectionString 2017-08-26 12:26:08 -05:00
Tobias Gurtzick
03c2270d0e add missing sslrootcert for native bindings 2017-08-26 12:26:08 -05:00
Sehrope Sarkuni
884e21e1ca Refactor addCommandComplete
Refactors addCommandComplete to tighten parsing regex start anchor and
handle edge case where no row count is specified (pre 8.2 COPY).
2017-08-26 12:24:59 -05:00
Brian Carlson
4d7734a711 Bump version 2017-08-10 09:01:31 -05:00
Charmander
4e35226340 Fix client remove clearing unrelated idle timers (#71)
* Add failing test for idle timer continuation after removal

* Clear idle timeout only for removed client

* Copy list of idle clients for modification during iteration
2017-08-10 09:00:49 -05:00
Brian Carlson
c3417e95eb Bump version 2017-08-10 00:21:10 -05:00
Brian C
53584b704a Add connection & query timeout if all clients are checked out (#70)
* Add connection & query timeout if all clients are checked out

This addresses [pg#1390](https://github.com/brianc/node-postgres/issues/1390).

Ensure connection timeout applies both for new connections and on an exhuasted pool.  I also made the library return an error when passing a function as the first param to `pool.query` - previosuly this threw a sync type error.

* Add pg-cursor to dev deps
2017-08-10 00:20:56 -05:00
Brian M. Carlson
e762b48e48 Bump version 2017-08-09 10:35:22 -05:00
Brian C
090b759e9f Merge pull request #33 from brianc/eslint-deps
Move eslint to dev dependencies
2017-08-09 10:08:18 -05:00
Brian M. Carlson
17e19e55a0 Move eslint to dev dependencies 2017-08-09 09:53:42 -05:00
Brian C
c0f5518341 Update README.md
Add link to updated documentation
2017-08-08 11:24:06 -05:00
Brian M. Carlson
465ac5caf3 Bump version 2017-08-06 12:42:19 -05:00
Brian C
57f62df315 Merge pull request #29 from brianc/upgrade-pg-cursor
Upgrade to newest version of pg-cursor
2017-08-06 12:41:34 -05:00
Brian M. Carlson
b1f8f8d60d Eslint 2017-08-06 11:59:47 -05:00
Brian M. Carlson
796d141386 Bump version 2017-08-06 11:28:37 -05:00
Brian C
b97a442f07 Merge pull request #30 from brianc/suport-query-config
Add support for rowMode & custom types
2017-08-06 11:28:22 -05:00
Brian Carlson
e517b8ce14 WIP 2017-08-05 18:27:29 -05:00
Brian M. Carlson
e0b2e41e57 Fix lint 2017-08-05 18:25:09 -05:00
Brian M. Carlson
4ff97f54bf Add support for rowMode & custom types 2017-08-05 18:22:54 -05:00
Brian M. Carlson
5b4bb7b615 Bump version 2017-08-05 17:29:58 -05:00
Brian C
71f30faeda Merge pull request #29 from brianc/no-sync-callbacks
Cleanup
2017-08-05 17:28:48 -05:00
Brian M. Carlson
bbefeb8670 Remove unused file 2017-08-05 17:25:13 -05:00
Brian M. Carlson
2ced8f1f2b Integrate eslint 2017-08-05 17:24:49 -05:00
Brian M. Carlson
3675d2b041 Fix to support node@4 LTS 2017-08-05 17:17:24 -05:00
Brian Carlson
a720dc774b Some cleanup 2017-08-05 16:59:20 -05:00
Brian M. Carlson
5a0af8cdd1 Bump version 2017-08-05 15:56:56 -05:00
Brian C
25d978e593 Merge pull request #28 from brianc/rickbergfalk-master
Do not send close after readyForQuery
2017-08-05 15:55:54 -05:00
Brian M. Carlson
620ddc0ded Do not send close after readyForQuery
Close is used to release a named portal (which isn't used by pg-cursor) or when you're early-terminating a cursor on the unnamed portal. Sending 'close' on an connection which has already sent 'readyForQuery' results in the connection responding with a _second_ 'readyForQuery' which causes a lot of issues within node-postgres as 'readyForQuery' is the signal to indicate the client has gone back into the idle state.
2017-08-04 17:40:52 -05:00
Rick Bergfalk
6072bcea8e Merge remote-tracking branch 'brianc/master' 2017-08-04 16:58:34 -04:00
Rick Bergfalk
9c7d2c853e Test cursor with pg-pool 2017-08-04 16:58:32 -04:00
caub
9ab62ff9f3 allow min/max params for pg-pool 2017-08-04 08:58:44 +02:00
Brian Carlson
a446537377 Bump version 2017-07-14 14:07:19 -05:00
Brian C
40f5126b6e Fix idle client teardown on error (#68)
- Re-add default idleTimeoutMillis = 10000 by default
- Fix idle timeout clearing on shutdown
- Ensure idleTimeoutMillis is used in timeout
2017-07-14 14:07:07 -05:00
Brian C
2421a769cb Update README.md 2017-07-13 22:40:26 -05:00
Brian Carlson
139cbdea16 Bump version 2017-07-13 22:37:45 -05:00
Brian C
a0eb36d819 2.0 (#67)
* Initial work

* Make progress on custom pool

* Make all original tests pass

* Fix test race

* Fix test when DNS is missing

* Test more error conditions

* Add test for byop

* Add BYOP tests for errors

* Add test for idle client error expunging

* Fix typo

* Replace var with const/let

* Remove var usage

* Fix linting

* Work on connection timeout

* Work on error condition tests

* Remove logging

* Add connection timeout

* Add idle timeout

* Test for returning to client to pool after error

fixes #48

* Add idleTimeout support to native client

* Add pg as peer dependency

fixes #45

* Rename properties

* Fix lint

* use strict

* Add draining to pool.end

* Ensure ending pools drain properly

* Remove yarn.lock

* Remove object-assign

* Remove node 8

* Remove closure for waiter construction

* Ensure client.connect is never sync

* Fix lint

* Change to es6 class

* Code cleanup & lint fixes
2017-07-13 22:37:08 -05:00
Luis Montes
45d82320b7 Merge pull request #10 from NoNameProvided/patch-1
Add support for Typescript typings

thanks @NoNameProvided  !
2017-06-27 10:09:14 -07:00
Luis Montes
e6643e4cb4 Merge pull request #7 from motiz88/extra-keys
Copy all but special-cased params from URL query string to config
2017-06-27 09:56:42 -07:00
Brian M. Carlson
0c32c57e0e Bump version 2017-06-18 14:09:54 -05:00
Brian C
f7b1edc7bb Add client to error event emitter (#65)
When the pool emits an error pass the client as the 2nd parameter to the `on('error')` handler.
2017-06-18 14:09:18 -05:00
Brian M. Carlson
5061068b04 Fix test 2017-06-08 18:18:49 -05:00
brianc
959d89e043 Add test for connectionString property delegation 2017-06-07 22:35:55 -05:00
Brian C
f93385284d Update .travis.yml 2017-06-02 13:00:42 -05:00
Brian C
a51fe56bc1 Update .travis.yml
Drop node@0.10 and node@0.12 from the test matrix.
2017-06-02 09:40:11 -05:00
Amila Welihinda
52c96a4b2e Create LICENSE (#54)
* Create LICENSE

* Update LICENSE
2017-05-29 10:48:58 -05:00
Brian M. Carlson
6e462ffae6 Bump version 2017-05-15 23:16:55 -05:00
Brian C
bbc2b416ed Merge pull request #25 from sberan/cursor-result
Emit Query Events
2017-05-15 23:15:59 -05:00
Sam Beran
4427e31661 fix travis build env 2017-05-09 10:13:57 -05:00
Sam Beran
2f480217cb fix: only dispatch error events if we have a listener 2017-05-09 10:13:57 -05:00
Sam Beran
acae15de53 Emit Query Events
This change adds events to the `Cursor` object
as per the [Query API](https://github.com/brianc/node-postgres/wiki/Query).
2017-05-09 10:13:57 -05:00
Brian Carlson
42af014483 Update travis.yml 2017-05-08 16:49:24 -05:00
Brian Carlson
4bf66e65de Bump version 2017-04-27 14:37:58 -05:00
Brian C
3cad54e061 Merge pull request #23 from sberan/cursor-result
Return result accumulator in callback
2017-04-27 14:37:49 -05:00
Sam Beran
557e5f879d Return result accumulator in callback
fixes issue: https://github.com/brianc/node-pg-cursor/issues/22
2017-04-27 14:26:11 -05:00
Brian Carlson
a3204168b7 Bump version 2017-04-27 11:42:19 -05:00
Brian C
24d85f5e17 Merge pull request #19 from crisvergara/master
Fix require for webpack compatibility
2017-04-27 11:41:53 -05:00
Attila Olah
54c2044416 feat: add basic typings
To make this app consumable by Typescript apps a typings file must be present.
2017-04-27 12:41:30 +02:00
Brian C
c9e21f4161 Merge pull request #22 from abenhamdine/master
Add node LTS and current versions to travis matrix
2017-04-24 11:25:08 -05:00
brianc
659a448fab Bump version 2017-04-13 10:50:00 -05:00
Russ Tyndall
c89b74bb5d Make a test case and fix for errors drainging the pool (#49)
* this bug leaves the pool empty even if there is work
   to be done, if there are enough consecutive errors to
   empty the pool

re brianc/node-pg-pool#48
2017-04-13 08:26:53 -05:00
Brian M. Carlson
5918a9e105 Bump version 2017-04-01 18:43:04 -05:00
Lewis J Ellis
0b3d68ef31 Bump generic-pool dep to 2.4.3 (#35) 2017-04-01 11:31:33 -05:00
Raul Ochoa
0f323999fc Access Promise through global (#39)
This matches the proposed way in "bring your own promise".
2017-04-01 11:28:27 -05:00
Shakeel Mohamed
2aed8bf7b3 Add syntax highlighting to code block in README (#42) 2017-03-06 11:47:30 -06:00
Arnaud Benhamdine
2a46c8a3d4 Add node LTS and current versions to travis matrix 2017-03-01 15:11:40 +01:00
Cris Vergara
af84d5cd4b Fix require for webpack compatibility 2016-12-05 17:18:25 -05:00
Brian Carlson
ab70f57923 Bump version 2016-12-04 17:27:10 -06:00
Charmander
fd802a385c Don’t create promises when callbacks are provided (#31)
* Revert "When connection fail, emit the error. (#28)"

This reverts commit 6a7edabc22e36db7386c97ee93f08f957364f37d.

The callback passed to `Pool.prototype.connect` should be responsible for handling connection errors. The `error` event is documented to be:

> Emitted whenever an idle client in the pool encounters an error.

This isn’t the case of an idle client in the pool; it never makes it into the pool.

It also breaks tests on pg’s master because of nonspecific dependencies.

* Don’t create promises when callbacks are provided

It’s incorrect to do so. One consequence is that a rejected promise will be unhandled, which is currently annoying, but also dangerous in the future:

> DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

The way callbacks are used currently also causes #24 (hiding of errors thrown synchronously from the callback). One fix for that would be to call them asynchronously from inside the `new Promise()` executor:

    process.nextTick(cb, error);

I don’t think it’s worth implementing, though, since it would still be backwards-incompatible – just less obvious about it.

Also fixes a bug where the `Pool.prototype.connect` callback would be called twice if there was an error.

* Use Node-0.10-compatible `process.nextTick`
2016-12-04 17:20:24 -06:00
Brian M. Carlson
fbdfc15b89 Bump version 2016-09-13 21:29:56 -05:00
Yanlong Wang
6a7edabc22 When connection fail, emit the error. (#28)
* When connection fail, emit the error.

If client connect failed, emit the connection error  rather than swallowing it.

* Add test for connection error.
2016-09-13 21:26:03 -05:00
Brian M. Carlson
cf28f9357f Bump version 2016-08-26 09:11:18 -05:00
jphaas
b091cc0d05 Bug fix: Pool.query now calls cb if connect() fails (#25)
* Pool.query calls cb if connect() fails

Old behavior was that if connect called back with an error, the promise would get rejected but the cb function would never get called.

* Test that Pool.query passes connection errors to callback

* Fixes to standardjs compliance
2016-08-26 09:08:15 -05:00
Brian M. Carlson
f2221a4040 Bump version 2016-08-26 09:07:54 -05:00
Brian M. Carlson
afce7ed6e3 Bump version 2016-08-26 09:05:46 -05:00
brianc
9964208fe8 Bump version 2016-08-05 16:23:05 -05:00
Cody Greene
eca2ea0ede emit "connect" event only on success and avoid double callback (#22)
* fail: "connect" event only on success

Double callback invocation will also cause this to fail.

* avoid double callback: _create

If `client.connect` returns an error, then the callback for `Pool#_create` is only invoked once. Also the `connect` event is only emitted on a successful connection, the client is otherwise rather useless.

* legacy compat; don't use Object.assign

* legacy compat; events.EventEmitter
2016-08-05 16:22:50 -05:00
Cody Greene
51fb7db8fa Support function-like construction (plus test) (#23)
* Support function-like construction

Remove the necessity of using `new` in front of the `Pool`, i.e. allow it to be used as a regular function. This is following https://github.com/brianc/node-postgres/issues/1077

* add Pool factory test
2016-08-05 16:21:51 -05:00
Risto Novik
1d89029ba7 Added missing new keyword to Heroku example. (#21) 2016-07-26 10:18:14 -05:00
Timothy Haley
e2d77719e7 Url parsing example (#19)
* Added URL parsing example

* Typos and cleanup

* Last typo
2016-07-18 15:54:57 -05:00
brianc
8c42c4172b Bump version 2016-07-03 16:17:55 -07:00
Brian C
9ab7aff029 Update code to run on >=0.10.0 (#17)
* Replace const with var

* Update code to run on 0.10.x +

* Lint
2016-07-03 18:17:34 -05:00
Brian C
ef1b15e13a Update README.md
Add note on "bring your own promise"
2016-06-30 15:22:49 -07:00
brianc
4f6208521b Bump version 2016-06-28 17:44:02 -07:00
Brian C
02dc31f925 Merge pull request #17 from rickbergfalk/master
handle empty query
2016-06-28 17:42:44 -07:00
Rick Bergfalk
74b6891b20 handle empty query 2016-06-28 16:47:50 -05:00
brianc
22a76ddd1d Bump version 2016-06-26 22:05:46 -07:00
brianc
d1c70ec9c1 Update documentation 2016-06-26 22:02:49 -07:00
Brian C
d653234a0c Add acquire event (#16)
* Add acquire event

Add acquire event which fires every time a client is acquired from the pool.

* Update README.md
2016-06-26 22:00:16 -07:00
Peter W
ce173f8c28 Fix error event doc in README (#15)
- making error event example code start by acquiring `pool` in
  the same way it is done in the example at the top for `create`
2016-06-26 21:39:36 -07:00
Peter W
d316ef5524 Fix example code for connect event (#14) 2016-06-25 11:21:40 -07:00
brianc
baa5800a70 Bump version 2016-06-24 09:53:46 -07:00
Brian C
aa1f10b0c0 Add support for pool#query without params (#12) 2016-06-24 11:52:32 -05:00
brianc
2d446d4953 Bump version 2016-06-24 11:36:36 -05:00
brianc
f47bc5f23b Update documentation 2016-06-24 11:35:33 -05:00
Brian C
ce59164ba1 Add callback interface to pool#query (#11)
* Add callback interface to pool#query

* Fix linting errors
2016-06-24 11:35:16 -05:00
Brian C
8b45ea1e7d Update README.md
Add a section with instructions on where to instantiate your pool
2016-06-24 10:48:23 -05:00
brianc
4758ea660e Update documentation 2016-06-23 14:34:41 -05:00
Brian C
cc40403de9 Update README.md 2016-06-23 00:22:07 -05:00
brianc
955d6ba797 Bump version 2016-06-23 00:21:16 -05:00
Brian C
c95036c362 Update README.md
Add travis badge
2016-06-23 00:21:01 -05:00
Brian C
8c058a300a Update README.md 2016-06-23 00:09:50 -05:00
Brian C
d2775fc023 Add travis.yml file (#9)
* Add travis.yml file

* Remove test on pg@9.5 since travis does not support it
2016-06-22 23:55:17 -05:00
Brian C
63caf7cd4c Add 'connect' event to pool (#7)
* Have pool emit 'connect' callback with client

* Ensure pool emits client on connect event
2016-06-22 23:29:35 -05:00
Brian C
7ef08fd861 Remove dependency on debug (#6)
Accept a `log: (message, other...) => { }` parameter as a config option, but by default use a no-op function instead of debug.
2016-06-22 23:29:09 -05:00
brianc
276b50d69f Bump version 2016-06-22 17:17:11 -05:00
ikokostya
cc20f8b747 Clone options in Pool constructor (fixes #4) (#5) 2016-06-22 16:34:17 -05:00
Brian C
d21ed42fc6 Update README.md 2016-06-22 10:03:14 -05:00
Brian C
ef8530aeb7 Update README.md 2016-06-21 22:38:31 -05:00
brianc
d09cf3b9c3 Bump version 2016-06-20 19:57:44 -05:00
Lee Symes
a6f641eb2c Only release client once on an error. (#3)
Prevent `generic-pool` error when releasing a client with an error.

Fixes #2
2016-06-20 19:56:12 -05:00
brianc
e38cfe078c Bump version 2016-06-10 22:52:21 -05:00
brianc
cb21c2a2e7 Better compatibility with pg 2016-06-10 22:52:07 -05:00
Brian C
36d50eceee Merge pull request #1 from jrf0110/patch-1
Demonstrate that pg-pool exports Pool constructor
2016-06-10 21:52:43 -05:00
John Fawcett
d42770ae2c Demonstrate that pg-pool exports Pool constructor 2016-06-10 21:25:56 -05:00
Brian C
d73538550c Update README.md 2016-06-10 17:44:48 -05:00
brianc
5c88bd6965 Update readme 2016-06-10 17:40:42 -05:00
Brian C
da6a2b0b0c Update README.md 2016-06-10 17:17:35 -05:00
Brian C
1decf9693a Create README.md 2016-06-10 17:16:14 -05:00
brianc
2aa207eea6 Update test semantics 2016-06-10 16:58:23 -05:00
brianc
ad73407aad Initial commit 2016-06-08 18:40:32 -05:00
brianc
c0d39055f2 Initial commit 2016-06-07 19:16:19 -05:00
Moti Zilberman
cdf06edd14 Copy all but special-cased params from URL query string to config 2015-12-30 15:16:38 +02:00
Brian C
802616b028 Update README.md
Remove outdated information about pg.js
2015-11-13 10:53:02 -06:00
Brian C
aa72d9b16a Merge pull request #17 from brianc/more-travis-versions
Add more versions of node to the travis matrix
2015-11-13 10:43:50 -06:00
brianc
df8acf0aaa Bump version 2015-11-13 10:40:12 -06:00
brianc
9aca077f3e Add more versions of node to the travis matrix 2015-11-13 10:39:28 -06:00
Brian C
ca21462f1b Merge pull request #15 from slickmb/bug/close_race
Avoid race when stream closed while fetching
2015-11-13 10:38:18 -06:00
Brian C
edfe1aa9a3 Merge pull request #16 from brianc/conform-to-readable-stream-spec
Conform to readable stream spec
2015-11-13 10:38:09 -06:00
brianc
27bba8de04 Conform to readable stream spec
One of the tests was failing because it was testing that when a stream became readable it never returned a `null` datum on call to `stream.read()`.

In fact, when a readable stream drains it should & does return `null` for calls to `stream.read()` as described [here](https://nodejs.org/api/stream.html#stream_event_readable)

I updated the test to account for this, and they pass now.
2015-11-13 10:33:39 -06:00
matthew.blasius
d1ac31c105 Support a close callback when closing the stream 2015-11-05 16:54:12 -05:00
matthew.blasius
68819dffda Avoid race when stream closed while fetching 2015-11-05 14:09:50 -05:00
Blaine Bublitz
07a7143fc9 Merge pull request #6 from misaxi/master
Update README.md
2015-10-12 15:21:52 -07:00
Mike He
c612dfabd5 Update README.md 2015-10-13 09:19:26 +11:00
Brian C
a01a555ad6 Merge pull request #12 from dmnd/patch-1
Fix typo: itterate -> iterate
2015-03-19 08:57:07 -04:00
Desmond Brand
56ebc6a656 Fix typo: itterate -> iterate 2015-03-18 00:40:22 -07:00
Brian M. Carlson
e9d1872c70 Test new travis config 2014-11-03 12:52:04 -05:00
Brian M. Carlson
52f5c709ba Merge branch 'master' of github.com:brianc/node-pg-query-stream 2014-11-03 12:34:24 -05:00
Brian M. Carlson
b38d092fa6 Update travis file 2014-11-03 12:34:16 -05:00
Brian C
aa61055029 Update README.md
Add travis badge
2014-11-03 10:46:25 -05:00
Brian M. Carlson
02ff00a374 Bump version 2014-11-03 10:44:26 -05:00
Brian M. Carlson
1dd2d3a938 Add infrastructure files 2014-11-03 10:44:19 -05:00
Brian C
0b45eda5a3 Merge pull request #7 from brianc/add-close-method
Is it possible to destroy the stream?
2014-11-03 10:42:59 -05:00
Brian M. Carlson
6ab80d3995 Add close method & supporting tests 2014-10-30 18:38:44 -04:00
Blaine Bublitz
4c151b9403 0.1.3 2014-09-26 14:22:46 -07:00
Blaine Bublitz
0a07e3d415 Merge pull request #2 from asynxis/master
Add supporting password with colon
2014-09-26 17:22:15 -04:00
Ivan Sorokin
fbdd033d6c Add supporting password with colon 2014-09-26 23:20:53 +03:00
Brian M. Carlson
8d395ff8c0 Bump version 2014-09-24 23:43:25 -04:00
Brian M. Carlson
40f361fd8e Add boilerplate files 2014-09-24 23:43:15 -04:00
Brian M. Carlson
19a2d26fc1 Add client#close
Closes #6
2014-09-24 23:42:51 -04:00
Blaine Bublitz
245abd6daf 0.1.2 2014-09-13 09:20:28 -07:00
Blaine Bublitz
c502985c60 Merge pull request #1 from slickmb/task/relative_url
Support usage of relative urls to set database on the default host
2014-09-13 12:15:22 -04:00
matthew.blasius
ba511f7803 Support usage of relative urls to set database on the default host 2014-09-12 11:42:53 -04:00
Blaine Bublitz
cb9bee1bc9 0.1.1 2014-07-06 16:34:14 -07:00
Blaine Bublitz
df2a24c555 attach port always - ref brianc/node-postgres#604 2014-07-06 16:33:53 -07:00
Blaine Bublitz
92c1fede8e initial commit 2014-07-05 16:43:58 -07:00
Blaine Bublitz
88aafd73fa Initial commit 2014-07-05 16:22:20 -07:00
Brian M. Carlson
df63cbbab7 Bump version 2014-05-22 16:59:23 -04:00
Brian C
7fb1f50023 Merge pull request #5 from calvinmetcalf/fixes
fix tests, clean up a few things
2014-05-22 16:54:14 -04:00
Calvin Metcalf
adf86b89f6 deps 2014-05-22 12:54:14 -04:00
Calvin Metcalf
6763e09cb2 merge it 2014-05-22 12:51:39 -04:00
Brian M. Carlson
99fe666956 Bump version 2014-05-22 11:22:31 -04:00
Brian M. Carlson
e242b94e6c Update version of pg-cursor 2014-05-22 11:20:53 -04:00
Brian M. Carlson
b9fd38df15 Bump version 2014-05-22 11:17:03 -04:00
Brian C
8bfd3a5bde Merge pull request #5 from grncdr/no-row-description
Work with queries that don't have row descriptions
2014-05-22 11:16:23 -04:00
Stephen Sugden
8283fd9b22 add support for queries that don't return a row description 2014-05-21 22:44:51 +02:00
Stephen Sugden
5084624e8d fix test command in package.json 2014-05-21 22:42:54 +02:00
Stephen Sugden
9cc3e527da add failing test for noData queries 2014-05-21 22:42:35 +02:00
Stephen Sugden
f7b6572399 fix typo 2014-05-21 21:54:27 +02:00
Calvin Metcalf
fec090972b clean ups 2014-05-14 10:41:10 -04:00
Calvin Metcalf
41b7d7d4de fix up tests 2014-05-14 09:51:56 -04:00
Brian M. Carlson
7593a44f79 Bump version 2014-04-11 11:01:43 -05:00
Brian C
d82386e1ac Merge pull request #4 from tbuchok/master
maxListeners on timestamp queries
2014-04-11 11:00:30 -05:00
Tom Buchok
cab956ba50 passes stream-tester-timestamp
- moves 'end' event listener to constructor, only listen once
- ensures all existing tests still green
2014-04-09 23:58:18 -04:00
Tom Buchok
87b52f9e51 adds failing test
- appears that timestamp queries emit a lot of `rows` with length == 0
- `self.once('end')` is added each of these times
- assertion on listener count shows that more than 10 listeners are applied
2014-04-09 23:56:21 -04:00
Brian M. Carlson
0f13c8068f Bump version 2014-03-21 11:47:40 -05:00
Brian M. Carlson
1961125476 Update pg-cursor
pg-cursor no longer returns the empty array 'done' signal to the callback
until the cursor recieves a readyForQuery message.  This means pg-query-stream
will not emit 'close' or 'end' events until the server is __truly__ ready for
the next query.  This fixes some race-conditions where some queries
are triggered off of the `end` event of the query-stream

closes #3
2014-03-21 11:47:32 -05:00
Brian M. Carlson
37de20e826 Bump version 2014-03-21 11:44:59 -05:00
Brian M. Carlson
1a9fd7ff76 Do not callback with final empty array until readyForQuery is received
Closes https://github.com/brianc/node-pg-query-stream/issues/3
2014-03-21 11:44:46 -05:00
Brian M. Carlson
0a7da37ab7 Bump version 2014-02-26 09:38:25 -06:00
Brian M. Carlson
37de9c2ab0 Rebase code on top of pg-cursor 2014-02-26 09:38:16 -06:00
Brian M. Carlson
b1b39bbd4f Bump version 2014-02-26 09:30:09 -06:00
Brian M. Carlson
f1dbe7884c Normalize parameter values 2014-02-26 09:30:00 -06:00
Brian M. Carlson
122bcfb27b Bump version 2014-02-26 07:16:00 -06:00
Brian M. Carlson
b66be5e934 Add test for stream close & satisfy stream contract 2014-02-26 07:15:01 -06:00
Brian M. Carlson
f8f2a92897 Remove Makefile 2014-02-26 07:11:16 -06:00
Brian M. Carlson
290906294d Port tests to use mocha 2014-02-26 07:11:16 -06:00
Brian C
0ed940cbfc Merge pull request #1 from grncdr/patch-1
Emit 'close' events when query completes
2014-02-26 07:11:07 -06:00
Brian M. Carlson
cc9f08a042 Bump version 2014-02-26 06:48:35 -06:00
Brian M. Carlson
4925172530 Fix require problem for pg module
Closes #3
2014-02-26 06:48:05 -06:00
Brian M. Carlson
a3074e9d54 Bump mocha version 2014-02-26 06:43:22 -06:00
Brian M. Carlson
87c3cf5e5e Bump version 2014-02-26 06:42:36 -06:00
Brian C
0df516c549 Add cleanup to the example
closes #2
2014-01-30 23:07:03 -06:00
Stephen Sugden
e1117155ae Emit 'close' events when query completes
Consider a system where one component is scheduling tasks that yield
streams, and passing them to (unknown) clients for consumption.

It would be useful for the scheduler to know that the query
underlying the stream is completed (so it can continue on to it's
next task) without having to wait for the consumer to finish reading
all results.
2013-12-25 13:33:34 -08:00
Brian C
dc92b1220e Update README.md 2013-11-20 22:53:19 -06:00
Brian C
a275adae52 Create README.md 2013-11-20 22:49:08 -06:00
Brian M. Carlson
9af987fa63 Pass all tests 2013-11-20 22:30:52 -06:00
Brian M. Carlson
31b2b1da6f All tests passing in isolation
Still have weird race conditions & shutdown/error/resume conditions to tackle
2013-11-11 23:20:04 -06:00
Brian M. Carlson
2e33d4acc0 Add default mocha options 2013-11-08 17:08:55 -06:00
Brian M. Carlson
9e2f622403 Port tests to use mocha 2013-11-08 17:07:54 -06:00
Brian Carlson
40af7c2f4a Update package.jsn 2013-11-08 16:50:17 -06:00
Brian M. Carlson
0ebd4c3bbb Bump version 2013-10-23 17:11:49 -05:00
Brian M. Carlson
33be525dbb Add ability to configure highWaterMark and batchSize 2013-10-23 17:11:43 -05:00
Brian M. Carlson
278c5ceb87 Update npm test command 2013-10-22 13:20:46 -05:00
Brian M. Carlson
58881357a2 Bump version 2013-10-22 13:19:48 -05:00
Brian M. Carlson
1b249e9ceb Add in proper error handling 2013-10-22 13:19:28 -05:00
Brian M. Carlson
aec85ce0d6 Bump version 2013-10-22 11:36:11 -05:00
Brian M. Carlson
48687fc182 Fix relative load path for pg.js 2013-10-22 11:36:05 -05:00
Brian M. Carlson
cc20d98cb0 Bump version 2013-10-22 11:24:41 -05:00
Brian M. Carlson
5400dfeffd Remove bad code 2013-10-22 11:24:30 -05:00
Brian M. Carlson
722296f8d2 Initial commit 2013-10-21 23:57:50 -05:00
Brian Carlson
8a3b3d4167 Bump version 2013-10-07 14:29:28 -05:00
Brian Carlson
31fd30d329 Fix test 2013-10-07 11:54:58 -05:00
Brian Carlson
fc875b0c1d Rename method 2013-10-07 11:54:23 -05:00
Brian Carlson
5d27cf24e2 Initial commit 2013-10-07 11:52:36 -05:00
435 changed files with 35198 additions and 6977 deletions

75
.devcontainer/Dockerfile Normal file
View File

@ -0,0 +1,75 @@
#-------------------------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
#-------------------------------------------------------------------------------------------------------------
FROM node:20
# Avoid warnings by switching to noninteractive
ENV DEBIAN_FRONTEND=noninteractive
# The node image includes a non-root user with sudo access. Use the
# "remoteUser" property in devcontainer.json to use it. On Linux, update
# these values to ensure the container user's UID/GID matches your local values.
# See https://aka.ms/vscode-remote/containers/non-root-user for details.
ARG USERNAME=node
ARG USER_UID=1000
ARG USER_GID=$USER_UID
RUN echo "deb http://archive.debian.org/debian stretch main" > /etc/apt/sources.list
# Configure apt and install packages
RUN apt-get update \
&& apt-get -y install --no-install-recommends dialog 2>&1 \
#
# Verify git and needed tools are installed
&& apt-get -y install git iproute2 procps \
#
# Remove outdated yarn from /opt and install via package
# so it can be easily updated via apt-get upgrade yarn
&& rm -rf /opt/yarn-* \
&& rm -f /usr/local/bin/yarn \
&& rm -f /usr/local/bin/yarnpkg \
&& apt-get install -y curl apt-transport-https lsb-release \
&& curl -sS https://dl.yarnpkg.com/$(lsb_release -is | tr '[:upper:]' '[:lower:]')/pubkey.gpg | apt-key add - 2>/dev/null \
&& echo "deb https://dl.yarnpkg.com/$(lsb_release -is | tr '[:upper:]' '[:lower:]')/ stable main" | tee /etc/apt/sources.list.d/yarn.list \
&& apt-get update \
&& apt-get -y install --no-install-recommends yarn tmux locales postgresql \
&& apt-get install libpq-dev g++ make \
#
# Install eslint globally
&& npm install -g eslint \
#
# [Optional] Update a non-root user to UID/GID if needed.
&& if [ "$USER_GID" != "1000" ] || [ "$USER_UID" != "1000" ]; then \
groupmod --gid $USER_GID $USERNAME \
&& usermod --uid $USER_UID --gid $USER_GID $USERNAME \
&& chown -R $USER_UID:$USER_GID /home/$USERNAME; \
fi \
# [Optional] Add add sudo support for non-root user
&& apt-get install -y sudo \
&& echo node ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \
&& chmod 0440 /etc/sudoers.d/$USERNAME \
# Clean up
&& apt-get autoremove -y \
&& apt-get clean -y \
&& rm -rf /var/lib/apt/lists/*
RUN curl https://raw.githubusercontent.com/brianc/dotfiles/master/.tmux.conf > ~/.tmux.conf
# install nvm
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.2/install.sh | bash
# set up a nicer prompt
RUN git clone https://github.com/magicmonty/bash-git-prompt.git ~/.bash-git-prompt --depth=1
RUN echo "source $HOME/.bash-git-prompt/gitprompt.sh" >> ~/.bashrc
# Set the locale
RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && locale-gen
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8
# Switch back to dialog for any ad-hoc use of apt-get
ENV DEBIAN_FRONTEND=dialog

View File

@ -0,0 +1,16 @@
// If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml.
{
"name": "Node.js 20 & Postgres",
"dockerComposeFile": "docker-compose.yml",
"service": "web",
"workspaceFolder": "/workspace",
// Add the IDs of extensions you want installed when the container is created in the array below.
"customizations":{
"vscode": {
"extensions": ["dbaeumer.vscode-eslint"],
"settings": {
"terminal.integrated.shell.linux": "/bin/bash"
}
}
}
}

View File

@ -0,0 +1,52 @@
#-------------------------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
#-------------------------------------------------------------------------------------------------------------
version: '3.9'
services:
web:
# Uncomment the next line to use a non-root user for all processes. You can also
# simply use the "remoteUser" property in devcontainer.json if you just want VS Code
# and its sub-processes (terminals, tasks, debugging) to execute as the user. On Linux,
# you may need to update USER_UID and USER_GID in .devcontainer/Dockerfile to match your
# user if not 1000. See https://aka.ms/vscode-remote/containers/non-root for details.
# user: node
build:
context: .
dockerfile: Dockerfile
volumes:
- ..:/workspace:cached
environment:
PGPASSWORD: pass
PGUSER: user
PGDATABASE: data
PGHOST: db
# set this to true in the development environment until I can get SSL setup on the
# docker postgres instance
PGTESTNOSSL: 'true'
# Overrides default command so things don't shut down after the process ends.
command: sleep infinity
depends_on:
- db
links:
- db:db
db:
image: postgres:14-alpine
restart: unless-stopped
ports:
- 5432:5432
command: postgres -c password_encryption=md5
environment:
POSTGRES_HOST_AUTH_METHOD: trust
POSTGRES_INITDB_ARGS: "--auth-local=md5"
POSTGRES_PASSWORD: pass
POSTGRES_USER: user
POSTGRES_DB: data

1
.eslintignore Normal file
View File

@ -0,0 +1 @@
/packages/*/dist/

View File

@ -1,6 +1,35 @@
{ {
"extends": "standard", "plugins": ["@typescript-eslint", "prettier"],
"parser": "@typescript-eslint/parser",
"extends": ["eslint:recommended", "plugin:prettier/recommended", "prettier"],
"ignorePatterns": ["node_modules", "coverage", "packages/pg-protocol/dist/**/*", "packages/pg-query-stream/dist/**/*"],
"parserOptions": {
"ecmaVersion": 2017,
"sourceType": "module"
},
"env": {
"node": true,
"es6": true,
"mocha": true
},
"rules": { "rules": {
"no-new-func": "off" "@typescript-eslint/no-unused-vars": ["error", {
} "args": "none",
"varsIgnorePattern": "^_$"
}],
"no-unused-vars": ["error", {
"args": "none",
"varsIgnorePattern": "^_$"
}],
"no-var": "error",
"prefer-const": "error"
},
"overrides": [
{
"files": ["*.ts", "*.mts", "*.cts", "*.tsx"],
"rules": {
"no-undef": "off"
}
}
]
} }

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
* text=auto eol=lf

1
.github/CODEOWNERS vendored Normal file
View File

@ -0,0 +1 @@
/packages/pg-connection-string @hjr3

3
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,3 @@
# These are supported funding model platforms
github: [brianc]

7
.github/dependabot.yaml vendored Normal file
View File

@ -0,0 +1,7 @@
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "monthly"

76
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,76 @@
name: CI
on: [push, pull_request]
permissions:
contents: read
jobs:
lint:
timeout-minutes: 5
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- name: Setup node
uses: actions/setup-node@v4
with:
node-version: 18
cache: yarn
- run: yarn install --frozen-lockfile
- run: yarn lint
build:
timeout-minutes: 15
needs: lint
services:
postgres:
image: ghcr.io/railwayapp-templates/postgres-ssl
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_HOST_AUTH_METHOD: 'md5'
POSTGRES_DB: ci_db_test
ports:
- 5432:5432
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
strategy:
fail-fast: false
matrix:
node:
- '16'
- '18'
- '20'
- '22'
- '24'
- '25'
os:
- ubuntu-latest
name: Node.js ${{ matrix.node }}
runs-on: ubuntu-latest
env:
PGUSER: postgres
PGPASSWORD: postgres
PGHOST: localhost
PGDATABASE: ci_db_test
PGTESTNOSSL: 'true'
SCRAM_TEST_PGUSER: scram_test
SCRAM_TEST_PGPASSWORD: test4scram
steps:
- name: Show OS
run: |
uname -a
- run: |
psql \
-c "SET password_encryption = 'scram-sha-256'" \
-c "CREATE ROLE scram_test LOGIN PASSWORD 'test4scram'"
- uses: actions/checkout@v4
with:
persist-credentials: false
- name: Setup node
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
cache: yarn
- run: yarn install --frozen-lockfile
- run: yarn test

5
.gitignore vendored
View File

@ -5,3 +5,8 @@ build/
node_modules/ node_modules/
package-lock.json package-lock.json
*.swp *.swp
dist
.DS_Store
/.eslintcache
.vscode/
manually-test-on-heroku.js

View File

@ -1,8 +0,0 @@
*~
build/
.lock-wscript
*.log
node_modules/
script/
*.swp
test/

View File

@ -1,35 +0,0 @@
language: node_js
sudo: false
dist: trusty
before_script:
- node script/create-test-tables.js pg://postgres@127.0.0.1:5432/postgres
env:
- CC=clang CXX=clang++ npm_config_clang=1 PGUSER=postgres PGDATABASE=postgres
matrix:
include:
- node_js: "lts/argon"
addons:
postgresql: "9.6"
- node_js: "lts/boron"
addons:
postgresql: "9.1"
dist: precise
- node_js: "lts/boron"
addons:
postgresql: "9.2"
- node_js: "lts/boron"
addons:
postgresql: "9.3"
- node_js: "lts/boron"
addons:
postgresql: "9.4"
- node_js: "lts/boron"
addons:
postgresql: "9.5"
- node_js: "lts/boron"
addons:
postgresql: "9.6"
- node_js: "8"
addons:
postgresql: "9.6"

1
.yarnrc Normal file
View File

@ -0,0 +1 @@
--install.ignore-engines true

View File

@ -4,9 +4,198 @@ For richer information consult the commit log on github with referenced pull req
We do not include break-fix version release in this file. We do not include break-fix version release in this file.
## pg@8.16.0
- Add support for [min connection pool size](https://github.com/brianc/node-postgres/pull/3438).
## pg@8.15.0
- Add support for [esm](https://github.com/brianc/node-postgres/pull/3423) importing. CommonJS importing is still also supported.
## pg@8.14.0
- Add support from SCRAM-SAH-256-PLUS i.e. [channel binding](https://github.com/brianc/node-postgres/pull/3356).
## pg@8.13.0
- Add ability to specify query timeout on [per-query basis](https://github.com/brianc/node-postgres/pull/3074).
## pg@8.12.0
- Add `queryMode` config option to [force use of the extended query protocol](https://github.com/brianc/node-postgres/pull/3214) on queries without any parameters.
## pg-pool@8.10.0
- Emit `release` event when client is returned to [the pool](https://github.com/brianc/node-postgres/pull/2845).
## pg@8.9.0
- Add support for [stream factory](https://github.com/brianc/node-postgres/pull/2898).
- [Better errors](https://github.com/brianc/node-postgres/pull/2901) for SASL authentication.
- [Use native crypto module](https://github.com/brianc/node-postgres/pull/2815) for SASL authentication.
## pg@8.8.0
- Bump minimum required version of [native bindings](https://github.com/brianc/node-postgres/pull/2787).
- Catch previously uncatchable errors thrown in [`pool.query`](https://github.com/brianc/node-postgres/pull/2569).
- Prevent the pool from blocking the event loop if all clients are [idle](https://github.com/brianc/node-postgres/pull/2721) (and `allowExitOnIdle` is enabled).
- Support `lock_timeout` in [client config](https://github.com/brianc/node-postgres/pull/2779).
- Fix errors thrown in callbacks from [interfering with cleanup](https://github.com/brianc/node-postgres/pull/2753).
### pg-pool@3.5.0
- Add connection [lifetime limit](https://github.com/brianc/node-postgres/pull/2698) config option.
### pg@8.7.0
- Add optional config to [pool](https://github.com/brianc/node-postgres/pull/2568) to allow process to exit if pool is idle.
### pg-cursor@2.7.0
- Convert to [es6 class](https://github.com/brianc/node-postgres/pull/2553)
- Add support for promises [to cursor methods](https://github.com/brianc/node-postgres/pull/2554)
### pg@8.6.0
- Better [SASL](https://github.com/brianc/node-postgres/pull/2436) error messages & more validation on bad configuration.
- Export [DatabaseError](https://github.com/brianc/node-postgres/pull/2445).
- Add [ParameterDescription](https://github.com/brianc/node-postgres/pull/2464) support to protocol parsing.
- Fix typescript [typedefs](https://github.com/brianc/node-postgres/pull/2490) with `--isolatedModules`.
### pg-query-stream@4.0.0
- Library has been [converted](https://github.com/brianc/node-postgres/pull/2376) to Typescript. The behavior is identical, but there could be subtle breaking changes due to class names changing or other small inconsistencies introduced by the conversion.
### pg@8.5.0
- Fix bug forwarding [ssl key](https://github.com/brianc/node-postgres/pull/2394).
- Convert pg-query-stream internals to [typescript](https://github.com/brianc/node-postgres/pull/2376).
- Performance [improvements](https://github.com/brianc/node-postgres/pull/2286).
### pg@8.4.0
- Switch to optional peer dependencies & remove [semver](https://github.com/brianc/node-postgres/commit/a02dfac5ad2e2abf0dc3a9817f953938acdc19b1) package which has been a small thorn in the side of a few users.
- Export `DatabaseError` from [pg-protocol](https://github.com/brianc/node-postgres/commit/58258430d52ee446721cc3e6611e26f8bcaa67f5).
- Add support for `sslmode` in the [connection string](https://github.com/brianc/node-postgres/commit/6be3b9022f83efc721596cc41165afaa07bfceb0).
### pg@8.3.0
- Support passing a [string of command line options flags](https://github.com/brianc/node-postgres/pull/2216) via the `{ options: string }` field on client/pool config.
### pg@8.2.0
- Switch internal protocol parser & serializer to [pg-protocol](https://github.com/brianc/node-postgres/tree/master/packages/pg-protocol). The change is backwards compatible but results in a significant performance improvement across the board, with some queries as much as 50% faster. This is the first work to land in an on-going performance improvement initiative I'm working on. Stay tuned as things are set to get much faster still! :rocket:
### pg-cursor@2.2.0
- Switch internal protocol parser & serializer to [pg-protocol](https://github.com/brianc/node-postgres/tree/master/packages/pg-protocol). The change is backwards compatible but results in a significant performance improvement across the board, with some queries as much as 50% faster.
### pg-query-stream@3.1.0
- Switch internal protocol parser & serializer to [pg-protocol](https://github.com/brianc/node-postgres/tree/master/packages/pg-protocol). The change is backwards compatible but results in a significant performance improvement across the board, with some queries as much as 50% faster.
### pg@8.1.0
- Switch to using [monorepo](https://github.com/brianc/node-postgres/tree/master/packages/pg-connection-string) version of `pg-connection-string`. This includes better support for SSL argument parsing from connection strings and ensures continuity of support.
- Add `&ssl=no-verify` option to connection string and `PGSSLMODE=no-verify` environment variable support for the pure JS driver. This is equivalent of passing `{ ssl: { rejectUnauthorized: false } }` to the client/pool constructor. The advantage of having support in connection strings and environment variables is it can be "externally" configured via environment variables and CLI arguments much more easily, and should remove the need to directly edit any application code for [the SSL default changes in 8.0](https://node-postgres.com/announcements#2020-02-25). This should make using `pg@8.x` significantly less difficult on environments like Heroku for example.
### pg-pool@3.2.0
- Same changes to `pg` impact `pg-pool` as they both use the same connection parameter and connection string parsing code for configuring SSL.
### pg-pool@3.1.0
- Add [maxUses](https://github.com/brianc/node-postgres/pull/2157) config option.
### pg@8.0.0
#### note: for detailed release notes please [check here](https://node-postgres.com/announcements#2020-02-25)
- Remove versions of node older than `6 lts` from the test matrix. `pg>=8.0` may still work on older versions but it is no longer officially supported.
- Change default behavior when not specifying `rejectUnauthorized` with the SSL connection parameters. Previously we defaulted to `rejectUnauthorized: false` when it was not specifically included. We now default to `rejectUnauthorized: true.` Manually specify `{ ssl: { rejectUnauthorized: false } }` for old behavior.
- Change [default database](https://github.com/brianc/node-postgres/pull/1679) when not specified to use the `user` config option if available. Previously `process.env.USER` was used.
- Change `pg.Pool` and `pg.Query` to [be](https://github.com/brianc/node-postgres/pull/2126) an [es6 class](https://github.com/brianc/node-postgres/pull/2063).
- Make `pg.native` non enumerable.
- `notice` messages are [no longer instances](https://github.com/brianc/node-postgres/pull/2090) of `Error`.
- Passwords no longer [show up](https://github.com/brianc/node-postgres/pull/2070) when instances of clients or pools are logged.
### pg@7.18.0
- This will likely be the last minor release before pg@8.0.
- This version contains a few bug fixes and adds a deprecation warning for [a pending change in 8.0](https://github.com/brianc/node-postgres/issues/2009#issuecomment-579371651) which will flip the default behavior over SSL from `rejectUnauthorized` from `false` to `true` making things more secure in the general use case.
### pg-query-stream@3.0.0
- [Rewrote stream internals](https://github.com/brianc/node-postgres/pull/2051) to better conform to node stream semantics. This should make pg-query-stream much better at respecting [highWaterMark](https://nodejs.org/api/stream.html#stream_new_stream_readable_options) and getting rid of some edge case bugs when using pg-query-stream as an async iterator. Due to the size and nature of this change (effectively a full re-write) it's safest to bump the semver major here, though almost all tests remain untouched and still passing, which brings us to a breaking change to the API....
- Changed `stream.close` to `stream.destroy` which is the [official](https://nodejs.org/api/stream.html#stream_readable_destroy_error) way to terminate a readable stream. This is a **breaking change** if you rely on the `stream.close` method on pg-query-stream...though should be just a find/replace type operation to upgrade as the semantics remain very similar (not exactly the same, since internals are rewritten, but more in line with how streams are "supposed" to behave).
- Unified the `config.batchSize` and `config.highWaterMark` to both do the same thing: control how many rows are buffered in memory. The `ReadableStream` will manage exactly how many rows are requested from the cursor at a time. This should give better out of the box performance and help with efficient async iteration.
### pg@7.17.0
- Add support for `idle_in_transaction_session_timeout` [option](https://github.com/brianc/node-postgres/pull/2049).
### 7.16.0
- Add optional, opt-in behavior to test new, [faster query pipeline](https://github.com/brianc/node-postgres/pull/2044). This is experimental, and not documented yet. The pipeline changes will grow significantly after the 8.0 release.
### 7.15.0
- Change repository structure to support lerna & future monorepo [development](https://github.com/brianc/node-postgres/pull/2014).
- [Warn about deprecation](https://github.com/brianc/node-postgres/pull/2021) for calling constructors without `new`.
### 7.14.0
- Reverts 7.13.0 as it contained [an accidental breaking change](https://github.com/brianc/node-postgres/pull/2010) for self-signed SSL cert verification. 7.14.0 is identical to 7.12.1.
### 7.13.0
- Add support for [all tls.connect()](https://github.com/brianc/node-postgres/pull/1996) options.
### 7.12.0
- Add support for [async password lookup](https://github.com/brianc/node-postgres/pull/1926).
### 7.11.0
- Add support for [connection_timeout](https://github.com/brianc/node-postgres/pull/1847/files#diff-5391bde944956870128be1136e7bc176R63) and [keepalives_idle](https://github.com/brianc/node-postgres/pull/1847).
### 7.10.0
- Add support for [per-query types](https://github.com/brianc/node-postgres/pull/1825).
### 7.9.0
- Add support for [sasl/scram authentication](https://github.com/brianc/node-postgres/pull/1835).
### 7.8.0
- Add support for passing [secureOptions](https://github.com/brianc/node-postgres/pull/1804) SSL config.
- Upgrade [pg-types](https://github.com/brianc/node-postgres/pull/1806) to 2.0.
### 7.7.0
- Add support for configurable [query timeout](https://github.com/brianc/node-postgres/pull/1760) on a client level.
### 7.6.0
- Add support for ["bring your own promise"](https://github.com/brianc/node-postgres/pull/1518)
### 7.5.0
- Better [error message](https://github.com/brianc/node-postgres/commit/11a4793452d618c53e019416cc886ad38deb1aa7) when passing `null` or `undefined` to `client.query`.
- Better [error handling](https://github.com/brianc/node-postgres/pull/1503) on queued queries.
### 7.4.0
- Add support for [Uint8Array](https://github.com/brianc/node-postgres/pull/1448) values.
### 7.3.0
- Add support for [statement timeout](https://github.com/brianc/node-postgres/pull/1436).
### 7.2.0 ### 7.2.0
- Pinned pg-pool and pg-types to a tighter semver range. This is likely not a noticable change for you unless you were specifically installing older versions of those libraries for some reason, but making it a minor bump here just in case it could cause any confusion. - Pinned pg-pool and pg-types to a tighter semver range. This is likely not a noticeable change for you unless you were specifically installing older versions of those libraries for some reason, but making it a minor bump here just in case it could cause any confusion.
### 7.1.0 ### 7.1.0
@ -40,16 +229,17 @@ We do not include break-fix version release in this file.
### v6.1.0 ### v6.1.0
- Add optional callback parameter to the pure JavaScript `client.end` method. The native client already supported this. - Add optional callback parameter to the pure JavaScript `client.end` method. The native client already supported this.
### v6.0.0 ### v6.0.0
#### Breaking Changes #### Breaking Changes
- Remove `pg.pools`. There is still a reference kept to the pools created & tracked by `pg.connect` but it has been renamed, is considered private, and should not be used. Accessing this API directly was uncommon and was _supposed_ to be private but was incorrectly documented on the wiki. Therefore, it is a breaking change of an (unintentionally) public interface to remove it by renaming it & making it private. Eventually `pg.connect` itself will be deprecated in favor of instantiating pools directly via `new pg.Pool()` so this property should become completely moot at some point. In the mean time...check out the new features...
- Remove `pg.pools`. There is still a reference kept to the pools created & tracked by `pg.connect` but it has been renamed, is considered private, and should not be used. Accessing this API directly was uncommon and was _supposed_ to be private but was incorrectly documented on the wiki. Therefore, it is a breaking change of an (unintentionally) public interface to remove it by renaming it & making it private. Eventually `pg.connect` itself will be deprecated in favor of instantiating pools directly via `new pg.Pool()` so this property should become completely moot at some point. In the mean time...check out the new features...
#### New features #### New features
- Replace internal pooling code with [pg-pool](https://github.com/brianc/node-pg-pool). This is the first step in eventually deprecating and removing the singleton `pg.connect`. The pg-pool constructor is exported from node-postgres at `require('pg').Pool`. It provides a backwards compatible interface with `pg.connect` as well as a promise based interface & additional niceties. - Replace internal pooling code with [pg-pool](https://github.com/brianc/node-pg-pool). This is the first step in eventually deprecating and removing the singleton `pg.connect`. The pg-pool constructor is exported from node-postgres at `require('pg').Pool`. It provides a backwards compatible interface with `pg.connect` as well as a promise based interface & additional niceties.
You can now create an instance of a pool and don't have to rely on the `pg` singleton for anything: You can now create an instance of a pool and don't have to rely on the `pg` singleton for anything:
@ -58,7 +248,7 @@ var pg = require('pg')
var pool = new pg.Pool() var pool = new pg.Pool()
// your friendly neighboorhood pool interface, without the singleton // your friendly neighborhood pool interface, without the singleton
pool.connect(function(err, client, done) { pool.connect(function(err, client, done) {
// ... // ...
}) })
@ -66,9 +256,9 @@ pool.connect(function(err, client, done) {
Promise support & other goodness lives now in [pg-pool](https://github.com/brianc/node-pg-pool). Promise support & other goodness lives now in [pg-pool](https://github.com/brianc/node-pg-pool).
__Please__ read the readme at [pg-pool](https://github.com/brianc/node-pg-pool) for the full api. **Please** read the readme at [pg-pool](https://github.com/brianc/node-pg-pool) for the full api.
- Included support for tcp keep alive. Enable it as follows: - Included support for tcp keep alive. Enable it as follows:
```js ```js
var client = new Client({ keepAlive: true }) var client = new Client({ keepAlive: true })
@ -76,58 +266,69 @@ var client = new Client({ keepAlive: true })
This should help with backends incorrectly considering idle clients to be dead and prematurely disconnecting them. This should help with backends incorrectly considering idle clients to be dead and prematurely disconnecting them.
### v5.1.0 ### v5.1.0
- Make the query object returned from `client.query` implement the promise interface. This is the first step towards promisifying more of the node-postgres api. - Make the query object returned from `client.query` implement the promise interface. This is the first step towards promisifying more of the node-postgres api.
Example: Example:
```js ```js
var client = new Client() var client = new Client()
client.connect() client.connect()
client.query('SELECT $1::text as name', ['brianc']) client.query('SELECT $1::text as name', ['brianc']).then(function (res) {
.then(function(res) { console.log('hello from', res.rows[0])
console.log('hello from', res.rows[0]) client.end()
client.end() })
})
``` ```
### v5.0.0 ### v5.0.0
#### Breaking Changes #### Breaking Changes
- `require('pg').native` now returns null if the native bindings cannot be found; previously, this threw an exception. - `require('pg').native` now returns null if the native bindings cannot be found; previously, this threw an exception.
#### New Features #### New Features
- better error message when passing `undefined` as a query parameter - better error message when passing `undefined` as a query parameter
- support for `defaults.connectionString` - support for `defaults.connectionString`
- support for `returnToHead` being passed to [generic pool](https://github.com/coopernurse/node-pool) - support for `returnToHead` being passed to [generic pool](https://github.com/coopernurse/node-pool)
### v4.5.0 ### v4.5.0
- Add option to parse JS date objects in query parameters as [UTC](https://github.com/brianc/node-postgres/pull/943) - Add option to parse JS date objects in query parameters as [UTC](https://github.com/brianc/node-postgres/pull/943)
### v4.4.0 ### v4.4.0
- Warn to `stderr` if a named query exceeds 63 characters which is the max lenght supported by postgres.
- Warn to `stderr` if a named query exceeds 63 characters which is the max length supported by postgres.
### v4.3.0 ### v4.3.0
- Unpin `pg-types` semver. Allow it to float against `pg-types@1.x`. - Unpin `pg-types` semver. Allow it to float against `pg-types@1.x`.
### v4.2.0 ### v4.2.0
- Support for additional error fields in postgres >= 9.3 if available. - Support for additional error fields in postgres >= 9.3 if available.
### v4.1.0 ### v4.1.0
- Allow type parser overrides on a [per-client basis](https://github.com/brianc/node-postgres/pull/679) - Allow type parser overrides on a [per-client basis](https://github.com/brianc/node-postgres/pull/679)
### v4.0.0 ### v4.0.0
- Make [native bindings](https://github.com/brianc/node-pg-native.git) an optional install with `npm install pg-native` - Make [native bindings](https://github.com/brianc/node-pg-native.git) an optional install with `npm install pg-native`
- No longer surround query result callback with `try/catch` block. - No longer surround query result callback with `try/catch` block.
- Remove built in COPY IN / COPY OUT support - better implementations provided by [pg-copy-streams](https://github.com/brianc/node-pg-copy-streams.git) and [pg-native](https://github.com/brianc/node-pg-native.git) - Remove built in COPY IN / COPY OUT support - better implementations provided by [pg-copy-streams](https://github.com/brianc/node-pg-copy-streams.git) and [pg-native](https://github.com/brianc/node-pg-native.git)
### v3.6.0 ### v3.6.0
- Include support for (parsing JSONB)[https://github.com/brianc/node-pg-types/pull/13] (supported in postgres 9.4) - Include support for (parsing JSONB)[https://github.com/brianc/node-pg-types/pull/13] (supported in postgres 9.4)
### v3.5.0 ### v3.5.0
- Include support for parsing boolean arrays - Include support for parsing boolean arrays
### v3.4.0 ### v3.4.0
- Include port as connection parameter to [unix sockets](https://github.com/brianc/node-postgres/pull/604) - Include port as connection parameter to [unix sockets](https://github.com/brianc/node-postgres/pull/604)
- Better support for odd [date parsing](https://github.com/brianc/node-pg-types/pull/8) - Better support for odd [date parsing](https://github.com/brianc/node-pg-types/pull/8)
@ -137,7 +338,6 @@ client.query('SELECT $1::text as name', ['brianc'])
- Expose array parsers on [pg.types](https://github.com/brianc/node-pg-types/pull/2) - Expose array parsers on [pg.types](https://github.com/brianc/node-pg-types/pull/2)
- Allow [pool](https://github.com/brianc/node-postgres/pull/591) to be configured - Allow [pool](https://github.com/brianc/node-postgres/pull/591) to be configured
### v3.1.0 ### v3.1.0
- Add [count of the number of times a client has been checked out from the pool](https://github.com/brianc/node-postgres/pull/556) - Add [count of the number of times a client has been checked out from the pool](https://github.com/brianc/node-postgres/pull/556)
@ -146,27 +346,29 @@ client.query('SELECT $1::text as name', ['brianc'])
### v3.0.0 ### v3.0.0
#### Breaking changes #### Breaking changes
- [Parse the DATE PostgreSQL type as local time](https://github.com/brianc/node-postgres/pull/514) - [Parse the DATE PostgreSQL type as local time](https://github.com/brianc/node-postgres/pull/514)
After [some discussion](https://github.com/brianc/node-postgres/issues/510) it was decided node-postgres was non-compliant in how it was handling DATE results. They were being converted to UTC, but the PostgreSQL documentation specifies they should be returned in the client timezone. This is a breaking change, and if you use the `date` type you might want to examine your code and make sure nothing is impacted. After [some discussion](https://github.com/brianc/node-postgres/issues/510) it was decided node-postgres was non-compliant in how it was handling DATE results. They were being converted to UTC, but the PostgreSQL documentation specifies they should be returned in the client timezone. This is a breaking change, and if you use the `date` type you might want to examine your code and make sure nothing is impacted.
- [Fix possible numeric precision loss on numeric & int8 arrays](https://github.com/brianc/node-postgres/pull/501) - [Fix possible numeric precision loss on numeric & int8 arrays](https://github.com/brianc/node-postgres/pull/501)
pg@v2.0 included changes to not convert large integers into their JavaScript number representation because of possibility for numeric precision loss. The same types in arrays were not taken into account. This fix applies the same type of type-coercion rules to arrays of those types, so there will be no more possible numeric loss on an array of very large int8s for example. This is a breaking change because now a return type from a query of `int8[]` will contain _string_ representations pg@v2.0 included changes to not convert large integers into their JavaScript number representation because of possibility for numeric precision loss. The same types in arrays were not taken into account. This fix applies the same type of type-coercion rules to arrays of those types, so there will be no more possible numeric loss on an array of very large int8s for example. This is a breaking change because now a return type from a query of `int8[]` will contain _string_ representations
of the integers. Use your favorite JavaScript bignum module to represent them without precision loss, or punch over the type converter to return the old style arrays again. of the integers. Use your favorite JavaScript bignum module to represent them without precision loss, or punch over the type converter to return the old style arrays again.
- [Fix to input array of dates being improperly converted to utc](https://github.com/benesch/node-postgres/commit/c41eedc3e01e5527a3d5c242fa1896f02ef0b261#diff-7172adb1fec2457a2700ed29008a8e0aR108) - [Fix to input array of dates being improperly converted to utc](https://github.com/benesch/node-postgres/commit/c41eedc3e01e5527a3d5c242fa1896f02ef0b261#diff-7172adb1fec2457a2700ed29008a8e0aR108)
Single `date` parameters were properly sent to the PostgreSQL server properly in local time, but an input array of dates was being changed into utc dates. This is a violation of what PostgreSQL expects. Small breaking change, but none-the-less something you should check out if you are inserting an array of dates. Single `date` parameters were properly sent to the PostgreSQL server properly in local time, but an input array of dates was being changed into utc dates. This is a violation of what PostgreSQL expects. Small breaking change, but none-the-less something you should check out if you are inserting an array of dates.
- [Query no longer emits `end` event if it ends due to an error](https://github.com/brianc/node-postgres/commit/357b64d70431ec5ca721eb45a63b082c18e6ffa3) - [Query no longer emits `end` event if it ends due to an error](https://github.com/brianc/node-postgres/commit/357b64d70431ec5ca721eb45a63b082c18e6ffa3)
This is a small change to bring the semantics of query more in line with other EventEmitters. The tests all passed after this change, but I suppose it could still be a breaking change in certain use cases. If you are doing clever things with the `end` and `error` events of a query object you might want to check to make sure its still behaving normally, though it is most likely not an issue. This is a small change to bring the semantics of query more in line with other EventEmitters. The tests all passed after this change, but I suppose it could still be a breaking change in certain use cases. If you are doing clever things with the `end` and `error` events of a query object you might want to check to make sure its still behaving normally, though it is most likely not an issue.
#### New features #### New features
- [Supercharge `prepareValue`](https://github.com/brianc/node-postgres/pull/555) - [Supercharge `prepareValue`](https://github.com/brianc/node-postgres/pull/555)
The long & short of it is now any object you supply in the list of query values will be inspected for a `.toPostgres` method. If the method is present it will be called and its result used as the raw text value sent to PostgreSQL for that value. This allows the same type of custom type coercion on query parameters as was previously afforded to query result values. The long & short of it is now any object you supply in the list of query values will be inspected for a `.toPostgres` method. If the method is present it will be called and its result used as the raw text value sent to PostgreSQL for that value. This allows the same type of custom type coercion on query parameters as was previously afforded to query result values.
- [Domain aware connection pool](https://github.com/brianc/node-postgres/pull/531) - [Domain aware connection pool](https://github.com/brianc/node-postgres/pull/531)
@ -181,41 +383,52 @@ Avoids a scenario where your pool could fill up with disconnected & unusable cli
To provide better documentation and a clearer explanation of how to override the query result parsing system we broke the type converters [into their own module](https://github.com/brianc/node-pg-types). There is still work around removing the 'global-ness' of the type converters so each query or connection can return types differently, but this is a good first step and allow a lot more obvious way to return int8 results as JavaScript numbers, for example To provide better documentation and a clearer explanation of how to override the query result parsing system we broke the type converters [into their own module](https://github.com/brianc/node-pg-types). There is still work around removing the 'global-ness' of the type converters so each query or connection can return types differently, but this is a good first step and allow a lot more obvious way to return int8 results as JavaScript numbers, for example
### v2.11.0 ### v2.11.0
- Add support for [application_name](https://github.com/brianc/node-postgres/pull/497) - Add support for [application_name](https://github.com/brianc/node-postgres/pull/497)
### v2.10.0 ### v2.10.0
- Add support for [the password file](http://www.postgresql.org/docs/9.3/static/libpq-pgpass.html) - Add support for [the password file](http://www.postgresql.org/docs/9.3/static/libpq-pgpass.html)
### v2.9.0 ### v2.9.0
- Add better support for [unix domain socket](https://github.com/brianc/node-postgres/pull/487) connections - Add better support for [unix domain socket](https://github.com/brianc/node-postgres/pull/487) connections
### v2.8.0 ### v2.8.0
- Add support for parsing JSON[] and UUID[] result types - Add support for parsing JSON[] and UUID[] result types
### v2.7.0 ### v2.7.0
- Use single row mode in native bindings when available [@rpedela] - Use single row mode in native bindings when available [@rpedela]
- reduces memory consumption when handling row values in 'row' event - reduces memory consumption when handling row values in 'row' event
- Automatically bind buffer type parameters as binary [@eugeneware] - Automatically bind buffer type parameters as binary [@eugeneware]
### v2.6.0 ### v2.6.0
- Respect PGSSLMODE environment variable - Respect PGSSLMODE environment variable
### v2.5.0 ### v2.5.0
- Ability to opt-in to int8 parsing via `pg.defaults.parseInt8 = true` - Ability to opt-in to int8 parsing via `pg.defaults.parseInt8 = true`
### v2.4.0 ### v2.4.0
- Use eval in the result set parser to increase performance - Use eval in the result set parser to increase performance
### v2.3.0 ### v2.3.0
- Remove built-in support for binary Int64 parsing. - Remove built-in support for binary Int64 parsing.
_Due to the low usage & required compiled dependency this will be pushed into a 3rd party add-on_ _Due to the low usage & required compiled dependency this will be pushed into a 3rd party add-on_
### v2.2.0 ### v2.2.0
- [Add support for excapeLiteral and escapeIdentifier in both JavaScript and the native bindings](https://github.com/brianc/node-postgres/pull/396) - [Add support for excapeLiteral and escapeIdentifier in both JavaScript and the native bindings](https://github.com/brianc/node-postgres/pull/396)
### v2.1.0 ### v2.1.0
- Add support for SSL connections in JavaScript driver - Add support for SSL connections in JavaScript driver
- this means you can connect to heroku postgres from your local machine without the native bindings! - this means you can connect to heroku postgres from your local machine without the native bindings!
- [Add field metadata to result object](https://github.com/brianc/node-postgres/blob/master/test/integration/client/row-description-on-results-tests.js) - [Add field metadata to result object](https://github.com/brianc/node-postgres/blob/master/test/integration/client/row-description-on-results-tests.js)
- [Add ability for rows to be returned as arrays instead of objects](https://github.com/brianc/node-postgres/blob/master/test/integration/client/results-as-array-tests.js) - [Add ability for rows to be returned as arrays instead of objects](https://github.com/brianc/node-postgres/blob/master/test/integration/client/results-as-array-tests.js)
@ -251,7 +464,7 @@ If you are unhappy with these changes you can always [override the built in type
### v1.0.0 ### v1.0.0
- remove deprecated functionality - remove deprecated functionality
- Callback function passed to `pg.connect` now __requires__ 3 arguments - Callback function passed to `pg.connect` now **requires** 3 arguments
- Client#pauseDrain() / Client#resumeDrain removed - Client#pauseDrain() / Client#resumeDrain removed
- numeric, decimal, and float data types no longer parsed into float before being returned. Will be returned from query results as `String` - numeric, decimal, and float data types no longer parsed into float before being returned. Will be returned from query results as `String`

View File

@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2010 - 2017 Brian Carlson Copyright (c) 2010 - 2021 Brian Carlson
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

43
LOCAL_DEV.md Normal file
View File

@ -0,0 +1,43 @@
# Local development
Steps to install and configure Postgres on Mac for developing against locally
1. Install homebrew
2. Install postgres
```sh
brew install postgresql
```
3. Create a database
```sh
createdb test
```
4. Create SSL certificates
```sh
cd /opt/homebrew/var/postgresql@14
openssl genrsa -aes128 2048 > server.key
openssl rsa -in server.key -out server.key
chmod 400 server.key
openssl req -new -key server.key -days 365 -out server.crt -x509
cp server.crt root.crt
```
5. Update config in `/opt/homebrew/var/postgresql@14/postgresql.conf`
```conf
listen_addresses = '*'
password_encryption = md5
ssl = on
ssl_ca_file = 'root.crt'
ssl_cert_file = 'server.crt'
ssl_crl_file = ''
ssl_crl_dir = ''
ssl_key_file = 'server.key'
ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL' # allowed SSL ciphers
ssl_prefer_server_ciphers = on
```
6. Start Postgres server
```sh
/opt/homebrew/opt/postgresql@14/bin/postgres -D /opt/homebrew/var/postgresql@14
```

122
README.md
View File

@ -1,88 +1,120 @@
# node-postgres # node-postgres
[![Build Status](https://secure.travis-ci.org/brianc/node-postgres.svg?branch=master)](http://travis-ci.org/brianc/node-postgres) ![Build Status](https://github.com/brianc/node-postgres/actions/workflows/ci.yml/badge.svg)
[![Dependency Status](https://david-dm.org/brianc/node-postgres.svg)](https://david-dm.org/brianc/node-postgres)
<span class="badge-npmversion"><a href="https://npmjs.org/package/pg" title="View this project on NPM"><img src="https://img.shields.io/npm/v/pg.svg" alt="NPM version" /></a></span> <span class="badge-npmversion"><a href="https://npmjs.org/package/pg" title="View this project on NPM"><img src="https://img.shields.io/npm/v/pg.svg" alt="NPM version" /></a></span>
<span class="badge-npmdownloads"><a href="https://npmjs.org/package/pg" title="View this project on NPM"><img src="https://img.shields.io/npm/dm/pg.svg" alt="NPM downloads" /></a></span> <span class="badge-npmdownloads"><a href="https://npmjs.org/package/pg" title="View this project on NPM"><img src="https://img.shields.io/npm/dm/pg.svg" alt="NPM downloads" /></a></span>
Non-blocking PostgreSQL client for node.js. Pure JavaScript and optional native libpq bindings. Non-blocking PostgreSQL client for Node.js. Pure JavaScript and optional native libpq bindings.
## Monorepo
This repo is a monorepo which contains the core [pg](https://github.com/brianc/node-postgres/tree/master/packages/pg) module as well as a handful of related modules.
- [pg](https://github.com/brianc/node-postgres/tree/master/packages/pg)
- [pg-pool](https://github.com/brianc/node-postgres/tree/master/packages/pg-pool)
- [pg-native](https://github.com/brianc/node-postgres/tree/master/packages/pg-native)
- [pg-cursor](https://github.com/brianc/node-postgres/tree/master/packages/pg-cursor)
- [pg-query-stream](https://github.com/brianc/node-postgres/tree/master/packages/pg-query-stream)
- [pg-connection-string](https://github.com/brianc/node-postgres/tree/master/packages/pg-connection-string)
- [pg-protocol](https://github.com/brianc/node-postgres/tree/master/packages/pg-protocol)
## Install ## Install
```sh ```
$ npm install pg npm install pg
``` ```
--- ## Documentation
## :star: [Documentation](https://node-postgres.com) :star:
Each package in this repo should have its own readme more focused on how to develop/contribute. For overall documentation on the project and the related modules managed by this repo please see:
### :star: [Documentation](https://node-postgres.com) :star:
The source repo for the documentation is available for contribution [here](https://github.com/brianc/node-postgres/tree/master/docs).
### Features ### Features
* pure JavaScript client and native libpq bindings share _the same api_ - Pure JavaScript client and native libpq bindings share _the same API_
* connection pooling - Connection pooling
* extensible js<->postgresql data-type coercion - Extensible JS ↔ PostgreSQL data-type coercion
* supported PostgreSQL features - Supported PostgreSQL features
* parameterized queries - Parameterized queries
* named statements with query plan caching - Named statements with query plan caching
* async notifications with `LISTEN/NOTIFY` - Async notifications with `LISTEN/NOTIFY`
* bulk import & export with `COPY TO/COPY FROM` - Bulk import & export with `COPY TO/COPY FROM`
### Extras ### Extras
node-postgres is by design pretty light on abstractions. These are some handy modules we've been using over the years to complete the picture. node-postgres is by design pretty light on abstractions. These are some handy modules we've been using over the years to complete the picture.
Entire list can be found on [wiki](https://github.com/brianc/node-postgres/wiki/Extras) The entire list can be found on our [wiki](https://github.com/brianc/node-postgres/wiki/Extras).
## Support ## Support
node-postgres is free software. If you encounter a bug with the library please open an issue on the [github repo](https://github.com/brianc/node-postgres). If you have questions unanswered by the documentation please open an issue pointing out how the documentation was unclear & I will do my best to make it better! node-postgres is free software. If you encounter a bug with the library please open an issue on the [GitHub repo](https://github.com/brianc/node-postgres). If you have questions unanswered by the documentation please open an issue pointing out how the documentation was unclear & I will do my best to make it better!
When you open an issue please provide: When you open an issue please provide:
- version of node
- version of postgres - version of Node
- version of Postgres
- smallest possible snippet of code to reproduce the problem - smallest possible snippet of code to reproduce the problem
You can also follow me [@briancarlson](https://twitter.com/briancarlson) if that's your thing. I try to always announce noteworthy changes & developments with node-postgres on twitter. You can also follow me [@briancarlson](https://twitter.com/briancarlson) if that's your thing. I try to always announce noteworthy changes & developments with node-postgres on Twitter.
### Professional Support ## Sponsorship :two_hearts:
I offer professional support for node-postgres. I provide implementation, training, and many years of expertise on how to build applications with node, express, PostgreSQL, and react/redux. Please contact me at [brian.m.carlson@gmail.com](mailto:brian.m.carlson@gmail.com) to discuss how I can help your company be more successful! node-postgres's continued development has been made possible in part by generous financial support from [the community](https://github.com/brianc/node-postgres/blob/master/SPONSORS.md).
### Sponsorship :star: If you or your company are benefiting from node-postgres and would like to help keep the project financially sustainable [please consider supporting](https://github.com/sponsors/brianc) its development.
If you are benefiting from node-postgres and would like to help keep the project financially sustainable please visit Brian Carlson's [Patreon page](https://www.patreon.com/node_postgres). ### Featured sponsor
Special thanks to [medplum](https://medplum.com) for their generous and thoughtful support of node-postgres!
![medplum](https://raw.githubusercontent.com/medplum/medplum-logo/refs/heads/main/medplum-logo.png)
## Contributing ## Contributing
__:heart: contributions!__ **:heart: contributions!**
I will __happily__ accept your pull request if it: I will **happily** accept your pull request if it:
- __has tests__
- **has tests**
- looks reasonable - looks reasonable
- does not break backwards compatibility - does not break backwards compatibility
If your change involves breaking backwards compatibility please please point that out in the pull request & we can discuss & plan when and how to release it and what type of documentation or communication it will require.
### Setting up for local development
1. Clone the repo
2. Ensure you have installed libpq-dev in your system.
3. From your workspace root run `yarn` and then `yarn lerna bootstrap`
4. Ensure you have a PostgreSQL instance running with SSL enabled and an empty database for tests
5. Ensure you have the proper environment variables configured for connecting to the instance
6. Run `yarn test` to run all the tests
## Troubleshooting and FAQ ## Troubleshooting and FAQ
The causes and solutions to common errors can be found among the [Frequently Asked Questions(FAQ)](https://github.com/brianc/node-postgres/wiki/FAQ) The causes and solutions to common errors can be found among the [Frequently Asked Questions (FAQ)](https://github.com/brianc/node-postgres/wiki/FAQ)
## License ## License
Copyright (c) 2010-2017 Brian Carlson (brian.m.carlson@gmail.com) Copyright (c) 2010-2020 Brian Carlson (brian.m.carlson@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.

View File

@ -1,11 +1,56 @@
node-postgres is made possible by the helpful contributors from the community well as the following generous supporters on [Patreon](https://www.patreon.com/node_postgres). node-postgres is made possible by the helpful contributors from the community as well as the following generous supporters on [GitHub Sponsors](https://github.com/sponsors/brianc) and [Patreon](https://www.patreon.com/node_postgres).
# Leaders # Leaders
- [MadKudu](https://www.madkudu.com) - [@madkudu](https://twitter.com/madkudu) - [MadKudu](https://www.madkudu.com) - [@madkudu](https://twitter.com/madkudu)
- [Third Iron](https://thirdiron.com/)
- [Timescale](https://timescale.com)
- [Nafundi](https://nafundi.com)
- [CrateDB](https://crate.io/)
- [BitMEX](https://www.bitmex.com/app/trade/XBTUSD)
- [Dataform](https://dataform.co/)
- [Eaze](https://www.eaze.com/)
- [simpleanalytics](https://simpleanalytics.com/)
- [n8n.io](https://n8n.io/)
- [mpirik](https://github.com/mpirik)
- [@BLUE-DEVIL1134](https://github.com/BLUE-DEVIL1134)
- [bubble.io](https://bubble.io/)
- [GitHub](https://github.com/github)
- [n8n](https://n8n.io/)
- [loveland](https://github.com/loveland)
- [gajus](https://github.com/gajus)
- [thirdiron](https://github.com/thirdiron)
# Supporters # Supporters
- John Fawcett - John Fawcett
- Lalit Kapoor [@lalitkapoor](https://twitter.com/lalitkapoor) - Lalit Kapoor [@lalitkapoor](https://twitter.com/lalitkapoor)
- Paul Frazee [@pfrazee](https://twitter.com/pfrazee) - Paul Frazee [@pfrazee](https://twitter.com/pfrazee)
- Rein Petersen - Rein Petersen
- Arnaud Benhamdine - Arnaud Benhamdine [@abenhamdine](https://twitter.com/abenhamdine)
- Matthew Welke
- Matthew Weber
- Andrea De Simon
- Todd Kennedy
- Alexander Robson
- Benjie Gillam
- David Hanson
- Franklin Davenport
- [Eventbot](https://geteventbot.com/)
- Chuck T
- Paul Cothenet
- Pelle Wessman
- Raul Murray
- Simple Analytics
- Trevor Linton
- Ian Walter
- @Guido4000
- [Martti Laine](https://github.com/codeclown)
- [Tim Nolet](https://github.com/tnolet)
- [Ideal Postcodes](https://github.com/ideal-postcodes)
- [checkly](https://github.com/checkly)
- [Scout APM](https://github.com/scoutapm-sponsorships)
- [Sideline Sports](https://github.com/SidelineSports)
- [Gadget](https://github.com/gadget-inc)
- [Sentry](https://sentry.io/welcome/)
- [devlikeapro](https://github.com/devlikepro)

2
docs/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
.next
out

20
docs/README.md Normal file
View File

@ -0,0 +1,20 @@
# node-postgres docs website
This is the documentation for node-postgres which is currently hosted at [https://node-postgres.com](https://node-postgres.com).
## Development
To run the documentation locally, you need to have [Node.js](https://nodejs.org) installed. Then, you can clone the repository and install the dependencies:
```bash
cd docs
yarn
```
Once you've installed the deps, you can run the development server:
```bash
yarn dev
```
This will start a local server at [http://localhost:3000](http://localhost:3000) where you can view the documentation and see your changes.

View File

@ -0,0 +1,9 @@
import { Callout } from 'nextra-theme-docs'
export const Alert = ({ children }) => {
return (
<Callout type="warning" emoji="⚠️">
{children}
</Callout>
)
}

5
docs/components/info.tsx Normal file
View File

@ -0,0 +1,5 @@
import { Callout } from 'nextra-theme-docs'
export const Info = ({ children }) => {
return <Callout emoji="">{children}</Callout>
}

9
docs/components/logo.tsx Normal file
View File

@ -0,0 +1,9 @@
type Props = {
src: string
alt?: string
}
export function Logo(props: Props) {
const alt = props.alt || 'Logo'
return <img src={props.src} alt={alt} width={100} height={100} style={{ width: 400, height: 'auto' }} />
}

8
docs/next.config.js Normal file
View File

@ -0,0 +1,8 @@
// next.config.js
const withNextra = require('nextra')({
theme: 'nextra-theme-docs',
themeConfig: './theme.config.js',
// optional: add `unstable_staticImage: true` to enable Nextra's auto image import
})
module.exports = withNextra()

20
docs/package.json Normal file
View File

@ -0,0 +1,20 @@
{
"name": "docs",
"version": "1.0.0",
"description": "",
"main": "next.config.js",
"scripts": {
"start": "next dev",
"build": "next build && next export"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"next": "^12.3.1",
"nextra": "2.0.0-beta.29",
"nextra-theme-docs": "2.0.0-beta.29",
"react": "^17.0.1",
"react-dom": "^17.0.1"
}
}

5
docs/pages/_app.js Normal file
View File

@ -0,0 +1,5 @@
import 'nextra-theme-docs/style.css'
export default function Nextra({ Component, pageProps }) {
return <Component {...pageProps} />
}

5
docs/pages/_meta.json Normal file
View File

@ -0,0 +1,5 @@
{
"index": "Welcome",
"announcements": "Announcements",
"apis": "API"
}

View File

@ -0,0 +1,146 @@
import { Alert } from '/components/alert.tsx'
## 2020-02-25
### pg@8.0 release
`pg@8.0` is [being released](https://github.com/brianc/node-postgres/pull/2117) which contains a handful of breaking changes.
I will outline each breaking change here and try to give some historical context on them. Most of them are small and subtle and likely wont impact you; **however**, there is one larger breaking change you will likely run into:
---
- Support all `tls.connect` [options](https://nodejs.org/api/tls.html#tls_tls_connect_options_callback) being passed to the client/pool constructor under the `ssl` option.
Previously we white listed the parameters passed here and did slight massaging of some of them. The main **breaking** change here is that now if you do this:
```js
const client = new Client({ ssl: true })
```
<Alert>
Now we will use the default ssl options to tls.connect which includes rejectUnauthorized being enabled. This means
your connection attempt may fail if you are using a self-signed cert. To use the old behavior you should do this:
</Alert>
```js
const client = new Client({ ssl: { rejectUnauthorized: false } })
```
This makes pg a bit more secure "out of the box" while still enabling you to opt in to the old behavior.
---
The rest of the changes are relatively minor & you likely wont need to do anything, but good to be aware none the less!
- change default database name
If a database name is not specified, available in the environment at `PGDATABASE`, or available at `pg.defaults`, we used to use the username of the process user as the name of the database. Now we will use the `user` property supplied to the client as the database name, if it exists. What this means is this:
```jsx
new Client({
user: 'foo',
})
```
`pg@7.x` will default the database name to the _process_ user. `pg@8.x` will use the `user` property supplied to the client. If you have not supplied `user` to the client, and it isn't available through any of its existing lookup mechanisms (environment variables, pg.defaults) then it will still use the process user for the database name.
- drop support for versions of node older than 8.0
Node@6.0 has been out of LTS for quite some time now, and I've removed it from our test matrix. `pg@8.0` _may_ still work on older versions of node, but it isn't a goal of the project anymore. Node@8.0 is actually no longer in the LTS support line, but pg will continue to test against and support 8.0 until there is a compelling reason to drop support for it. Any security vulnerability issues which come up I will back-port fixes to the `pg@7.x` line and do a release, but any other fixes or improvements will not be back ported.
- prevent password from being logged accidentally
`pg@8.0` makes the password field on the pool and client non-enumerable. This means when you do `console.log(client)` you wont have your database password printed out unintentionally. You can still do `console.log(client.password)` if you really want to see it!
- make `pg.native` non-enumerable
You can use `pg.native.Client` to access the native client. The first time you access the `pg.native` getter it imports the native bindings...which must be installed. In some cases (such as webpacking the pg code for lambda deployment) the `.native` property would be traversed and trigger an import of the native bindings as a side-effect. Making this property non-enumerable will fix this issue. An easy fix, but its technically a breaking change in cases where people _are_ relying on this side effect for any reason.
- make `pg.Pool` an es6 class
This makes extending `pg.Pool` possible. Previously it was not a "proper" es6 class and `class MyPool extends pg.Pool` wouldn't work.
- make `Notice` messages _not_ an instance of a JavaScript error
The code path for parsing `notice` and `error` messages from the postgres backend is the same. Previously created a JavaScript `Error` instance for _both_ of these message types. Now, only actual `errors` from the postgres backend will be an instance of an `Error`. The _shape_ and _properties_ of the two messages did not change outside of this.
- monorepo
While not technically a breaking change for the module itself, I have begun the process of [consolidating](https://github.com/brianc/node-pg-query-stream) [separate](https://github.com/brianc/node-pg-cursor/) [repos](https://github.com/brianc/node-pg-pool) into the main [repo](https://github.com/brianc/node-postgres) and converted it into a monorepo managed by lerna. This will help me stay on top of issues better (it was hard to bounce between 3-4 separate repos) and coordinate bug fixes and changes between dependant modules.
Thanks for reading that! pg tries to be super pedantic about not breaking backwards-compatibility in non semver major releases....even for seemingly small things. If you ever notice a breaking change on a semver minor/patch release please stop by the [repo](https://github.com/brianc/node-postgres) and open an issue!
_If you find `pg` valuable to you or your business please consider [supporting](http://github.com/sponsors/brianc) it's continued development! Big performance improvements, typescript, better docs, query pipelining and more are all in the works!_
## 2019-07-18
### New documentation
After a _very_ long time on my todo list I've ported the docs from my old hand-rolled webapp running on route53 + elb + ec2 + dokku (I know, I went overboard!) to [gatsby](https://www.gatsbyjs.org/) hosted on [netlify](https://www.netlify.com/) which is _so_ much easier to manage. I've released the code at [https://github.com/brianc/node-postgres-docs](https://github.com/brianc/node-postgres-docs) and invite your contributions! Let's make this documentation better together. Any time changes are merged to master on the documentation repo it will automatically deploy.
If you see an error in the docs, big or small, use the "edit on GitHub" button to edit the page & submit a pull request right there. I'll get a new version out ASAP with your changes! If you want to add new pages of documentation open an issue if you need guidance, and I'll help you get started.
I want to extend a special **thank you** to all the [supporters](https://github.com/brianc/node-postgres/blob/master/SPONSORS.md) and [contributors](https://github.com/brianc/node-postgres/graphs/contributors) to the project that have helped keep me going through times of burnout or life "getting in the way." ❤️
It's been quite a journey, and I look forward continuing it for as long as I can provide value to all y'all. 🤠
## 2017-08-12
### code execution vulnerability
Today [@sehrope](https://github.com/sehrope) found and reported a code execution vulnerability in node-postgres. This affects all versions from `pg@2.x` through `pg@7.1.0`.
I have published a fix on the tip of each major version branch of all affected versions as well as a fix on each minor version branch of `pg@6.x` and `pg@7.x`:
### Fixes
The following versions have been published to npm & contain a patch to fix the vulnerability:
```
pg@2.11.2
pg@3.6.4
pg@4.5.7
pg@5.2.1
pg@6.0.5
pg@6.1.6
pg@6.2.5
pg@6.3.3
pg@6.4.2
pg@7.0.3
pg@7.1.2
```
### Example
To demonstrate the issue & see if you are vulnerable execute the following in node:
```js
import pg from 'pg'
const { Client } = pg
const client = new Client()
client.connect()
const sql = `SELECT 1 AS "\\'/*", 2 AS "\\'*/\n + console.log(process.env)] = null;\n//"`
client.query(sql, (err, res) => {
client.end()
})
```
You will see your environment variables printed to your console. An attacker can use this exploit to execute any arbitrary node code within your process.
### Impact
This vulnerability _likely_ does not impact you if you are connecting to a database you control and not executing user-supplied sql. Still, you should **absolutely** upgrade to the most recent patch version as soon as possible to be safe.
Two attack vectors we quickly thought of:
- 1 - executing unsafe, user-supplied sql which contains a malicious column name like the one above.
- 2 - connecting to an untrusted database and executing a query which returns results where any of the column names are malicious.
### Support
I have created [an issue](https://github.com/brianc/node-postgres/issues/1408) you can use to discuss the vulnerability with me or ask questions, and I have reported this issue [on twitter](https://twitter.com/briancarlson) and directly to Heroku and [nodesecurity.io](https://nodesecurity.io/).
I take security very seriously. If you or your company benefit from node-postgres **[please sponsor my work](https://www.patreon.com/node_postgres)**: this type of issue is one of the many things I am responsible for, and I want to be able to continue to tirelessly provide a world-class PostgreSQL experience in node for years to come.

View File

@ -0,0 +1,8 @@
{
"client": "pg.Client",
"pool": "pg.Pool",
"result": "pg.Result",
"types": "pg.Types",
"cursor": "Cursor",
"utilities": "Utilities"
}

243
docs/pages/apis/client.mdx Normal file
View File

@ -0,0 +1,243 @@
---
title: pg.Client
---
## new Client
`new Client(config: Config)`
Every field of the `config` object is entirely optional. A `Client` instance will use [environment variables](/features/connecting#environment-variables) for all missing values.
```ts
type Config = {
user?: string, // default process.env.PGUSER || process.env.USER
password?: string or function, //default process.env.PGPASSWORD
host?: string, // default process.env.PGHOST
port?: number, // default process.env.PGPORT
database?: string, // default process.env.PGDATABASE || user
connectionString?: string, // e.g. postgres://user:password@host:5432/database
ssl?: any, // passed directly to node.TLSSocket, supports all tls.connect options
types?: any, // custom type parsers
statement_timeout?: number, // number of milliseconds before a statement in query will time out, default is no timeout
query_timeout?: number, // number of milliseconds before a query call will timeout, default is no timeout
lock_timeout?: number, // number of milliseconds a query is allowed to be en lock state before it's cancelled due to lock timeout
application_name?: string, // The name of the application that created this Client instance
connectionTimeoutMillis?: number, // number of milliseconds to wait for connection, default is no timeout
keepAliveInitialDelayMillis?: number, // set the initial delay before the first keepalive probe is sent on an idle socket
idle_in_transaction_session_timeout?: number, // number of milliseconds before terminating any session with an open idle transaction, default is no timeout
client_encoding?: string, // specifies the character set encoding that the database uses for sending data to the client
fallback_application_name?: string, // provide an application name to use if application_name is not set
options?: string // command-line options to be sent to the server
}
```
example to create a client with specific connection information:
```js
import { Client } from 'pg'
const client = new Client({
user: 'database-user',
password: 'secretpassword!!',
host: 'my.database-server.com',
port: 5334,
database: 'database-name',
})
```
## client.connect
```js
import { Client } from 'pg'
const client = new Client()
await client.connect()
```
## client.query
### QueryConfig
You can pass an object to `client.query` with the signature of:
```ts
type QueryConfig {
// the raw query text
text: string;
// an array of query parameters
values?: Array<any>;
// name of the query - used for prepared statements
name?: string;
// by default rows come out as a key/value pair for each row
// pass the string 'array' here to receive rows as an array of values
rowMode?: string;
// custom type parsers just for this query result
types?: Types;
// TODO: document
queryMode?: string;
}
```
```ts
client.query(text: string, values?: any[]) => Promise<Result>
```
**Plain text query**
```js
import { Client } from 'pg'
const client = new Client()
await client.connect()
const result = await client.query('SELECT NOW()')
console.log(result)
await client.end()
```
**Parameterized query**
```js
import { Client } from 'pg'
const client = new Client()
await client.connect()
const result = await client.query('SELECT $1::text as name', ['brianc'])
console.log(result)
await client.end()
```
```ts
client.query(config: QueryConfig) => Promise<Result>
```
**client.query with a QueryConfig**
If you pass a `name` parameter to the `client.query` method, the client will create a [prepared statement](/features/queries#prepared-statements).
```js
const query = {
name: 'get-name',
text: 'SELECT $1::text',
values: ['brianc'],
rowMode: 'array',
}
const result = await client.query(query)
console.log(result.rows) // ['brianc']
await client.end()
```
**client.query with a `Submittable`**
If you pass an object to `client.query` and the object has a `.submit` function on it, the client will pass it's PostgreSQL server connection to the object and delegate query dispatching to the supplied object. This is an advanced feature mostly intended for library authors. It is incidentally also currently how the callback and promise based queries above are handled internally, but this is subject to change. It is also how [pg-cursor](https://github.com/brianc/node-pg-cursor) and [pg-query-stream](https://github.com/brianc/node-pg-query-stream) work.
```js
import { Query } from 'pg'
const query = new Query('select $1::text as name', ['brianc'])
const result = client.query(query)
assert(query === result) // true
query.on('row', (row) => {
console.log('row!', row) // { name: 'brianc' }
})
query.on('end', () => {
console.log('query done')
})
query.on('error', (err) => {
console.error(err.stack)
})
```
---
## client.end
Disconnects the client from the PostgreSQL server.
```js
await client.end()
console.log('client has disconnected')
```
## events
### error
```ts
client.on('error', (err: Error) => void) => void
```
When the client is in the process of connecting, dispatching a query, or disconnecting it will catch and forward errors from the PostgreSQL server to the respective `client.connect` `client.query` or `client.end` promise; however, the client maintains a long-lived connection to the PostgreSQL back-end and due to network partitions, back-end crashes, fail-overs, etc the client can (and over a long enough time period _will_) eventually be disconnected while it is idle. To handle this you may want to attach an error listener to a client to catch errors. Here's a contrived example:
```js
const client = new pg.Client()
client.connect()
client.on('error', (err) => {
console.error('something bad has happened!', err.stack)
})
// walk over to server, unplug network cable
// process output: 'something bad has happened!' followed by stacktrace :P
```
### end
```ts
client.on('end') => void
```
When the client disconnects from the PostgreSQL server it will emit an end event once.
### notification
Used for `listen/notify` events:
```ts
type Notification {
processId: number,
channel: string,
payload?: string
}
```
```js
const client = new pg.Client()
await client.connect()
client.query('LISTEN foo')
client.on('notification', (msg) => {
console.log(msg.channel) // foo
console.log(msg.payload) // bar!
})
client.query(`NOTIFY foo, 'bar!'`)
```
### notice
```ts
client.on('notice', (notice: Error) => void) => void
```
Used to log out [notice messages](https://www.postgresql.org/docs/9.6/static/plpgsql-errors-and-messages.html) from the PostgreSQL server.
```js
client.on('notice', (msg) => console.warn('notice:', msg))
```

View File

@ -0,0 +1,76 @@
---
title: pg.Cursor
slug: /apis/cursor
---
A cursor can be used to efficiently read through large result sets without loading the entire result-set into memory ahead of time. It's useful to simulate a 'streaming' style read of data, or exit early from a large result set. The cursor is passed to `client.query` and is dispatched internally in a way very similar to how normal queries are sent, but the API it presents for consuming the result set is different.
## install
```
$ npm install pg pg-cursor
```
## constructor
### `new Cursor(text: String, values: Any[][, config: CursorQueryConfig])`
Instantiates a new Cursor. A cursor is an instance of `Submittable` and should be passed directly to the `client.query` method.
```js
import { Pool } from 'pg'
import Cursor from 'pg-cursor'
const pool = new Pool()
const client = await pool.connect()
const text = 'SELECT * FROM my_large_table WHERE something > $1'
const values = [10]
const cursor = client.query(new Cursor(text, values))
const { rows } = await cursor.read(100)
console.log(rows.length) // 100 (unless the table has fewer than 100 rows)
client.release()
```
```ts
type CursorQueryConfig {
// by default rows come out as a key/value pair for each row
// pass the string 'array' here to receive rows as an array of values
rowMode?: string;
// custom type parsers just for this query result
types?: Types;
}
```
## read
### `cursor.read(rowCount: Number) => Promise<pg.Result>`
Read `rowCount` rows from the cursor instance. The callback will be called when the rows are available, loaded into memory, parsed, and converted to JavaScript types.
If the cursor has read to the end of the result sets all subsequent calls to cursor#read will return a 0 length array of rows. Calling `read` on a cursor that has read to the end.
Here is an example of reading to the end of a cursor:
```js
import { Pool } from 'pg'
import Cursor from 'pg-cursor'
const pool = new Pool()
const client = await pool.connect()
const cursor = client.query(new Cursor('select * from generate_series(0, 5)'))
let rows = await cursor.read(100)
assert(rows.length == 6)
rows = await cursor.read(100)
assert(rows.length == 0)
```
## close
### `cursor.close() => Promise<void>`
Used to close the cursor early. If you want to stop reading from the cursor before you get all of the rows returned, call this.

251
docs/pages/apis/pool.mdx Normal file
View File

@ -0,0 +1,251 @@
---
title: pg.Pool
---
import { Alert } from '/components/alert.tsx'
## new Pool
```ts
new Pool(config: Config)
```
Constructs a new pool instance.
The pool is initially created empty and will create new clients lazily as they are needed. Every field of the `config` object is entirely optional. The config passed to the pool is also passed to every client instance within the pool when the pool creates that client.
```ts
type Config = {
// all valid client config options are also valid here
// in addition here are the pool specific configuration parameters:
// number of milliseconds to wait before timing out when connecting a new client
// by default this is 0 which means no timeout
connectionTimeoutMillis?: number
// number of milliseconds a client must sit idle in the pool and not be checked out
// before it is disconnected from the backend and discarded
// default is 10000 (10 seconds) - set to 0 to disable auto-disconnection of idle clients
idleTimeoutMillis?: number
// maximum number of clients the pool should contain
// by default this is set to 10. There is some nuance to setting the maximum size of your pool.
// see https://node-postgres.com/guides/pool-sizing for more information
max?: number
// minimum number of clients the pool should hold on to and _not_ destroy with the idleTimeoutMillis
// this can be useful if you get very bursty traffic and want to keep a few clients around.
// note: current the pool will not automatically create and connect new clients up to the min, it will
// only not evict and close clients except those which exceed the min count.
// the default is 0 which disables this behavior.
min?: number
// Default behavior is the pool will keep clients open & connected to the backend
// until idleTimeoutMillis expire for each client and node will maintain a ref
// to the socket on the client, keeping the event loop alive until all clients are closed
// after being idle or the pool is manually shutdown with `pool.end()`.
//
// Setting `allowExitOnIdle: true` in the config will allow the node event loop to exit
// as soon as all clients in the pool are idle, even if their socket is still open
// to the postgres server. This can be handy in scripts & tests
// where you don't want to wait for your clients to go idle before your process exits.
allowExitOnIdle?: boolean
// Sets a max overall life for the connection.
// A value of 60 would evict connections that have been around for over 60 seconds,
// regardless of whether they are idle. It's useful to force rotation of connection pools through
// middleware so that you can rotate the underlying servers. The default is disabled (value of zero)
maxLifetimeSeconds?: number
}
```
example to create a new pool with configuration:
```js
import { Pool } from 'pg'
const pool = new Pool({
host: 'localhost',
user: 'database-user',
max: 20,
idleTimeoutMillis: 30000,
connectionTimeoutMillis: 2000,
maxLifetimeSeconds: 60
})
```
## pool.query
Often we only need to run a single query on the database, so as convenience the pool has a method to run a query on the first available idle client and return its result.
```ts
pool.query(text: string, values?: any[]) => Promise<pg.Result>
```
```js
import { Pool } from 'pg'
const pool = new Pool()
const result = await pool.query('SELECT $1::text as name', ['brianc'])
console.log(result.rows[0].name) // brianc
```
Notice in the example above there is no need to check out or release a client. The pool is doing the acquiring and releasing internally. I find `pool.query` to be a handy shortcut in many situations and I use it exclusively unless I need a transaction.
<Alert>
<div>
Do <strong>not</strong> use <code>pool.query</code> if you are using a transaction.
</div>
The pool will dispatch every query passed to pool.query on the first available idle client. Transactions within PostgreSQL
are scoped to a single client and so dispatching individual queries within a single transaction across multiple, random
clients will cause big problems in your app and not work. For more info please read <a href="/features/transactions">
transactions
</a>.
</Alert>
## pool.connect
`pool.connect() => Promise<pg.Client>`
Acquires a client from the pool.
- If there are idle clients in the pool one will be returned to the callback on `process.nextTick`.
- If the pool is not full but all current clients are checked out a new client will be created & returned to this callback.
- If the pool is 'full' and all clients are currently checked out, requests will wait in a FIFO queue until a client becomes available by being released back to the pool.
```js
import { Pool } from 'pg'
const pool = new Pool()
const client = await pool.connect()
await client.query('SELECT NOW()')
client.release()
```
### releasing clients
`client.release(destroy?: boolean) => void`
Client instances returned from `pool.connect` will have a `release` method which will release them from the pool.
The `release` method on an acquired client returns it back to the pool. If you pass a truthy value in the `destroy` parameter, instead of releasing the client to the pool, the pool will be instructed to disconnect and destroy this client, leaving a space within itself for a new client.
```js
import { Pool } from 'pg'
const pool = new Pool()
// check out a single client
const client = await pool.connect()
// release the client
client.release()
```
```js
import { Pool } from 'pg'
const pool = new Pool()
assert(pool.totalCount === 0)
assert(pool.idleCount === 0)
const client = await pool.connect()
await client.query('SELECT NOW()')
assert(pool.totalCount === 1)
assert(pool.idleCount === 0)
// tell the pool to destroy this client
await client.release(true)
assert(pool.idleCount === 0)
assert(pool.totalCount === 0)
```
<Alert>
<div>
You <strong>must</strong> release a client when you are finished with it.
</div>
If you forget to release the client then your application will quickly exhaust available, idle clients in the pool and
all further calls to <code>pool.connect</code> will timeout with an error or hang indefinitely if you have <code>
connectionTimeoutMillis
</code> configured to 0.
</Alert>
## pool.end
Calling `pool.end` will drain the pool of all active clients, disconnect them, and shut down any internal timers in the pool. It is common to call this at the end of a script using the pool or when your process is attempting to shut down cleanly.
```js
// again both promises and callbacks are supported:
import { Pool } from 'pg'
const pool = new Pool()
await pool.end()
```
## properties
`pool.totalCount: number`
The total number of clients existing within the pool.
`pool.idleCount: number`
The number of clients which are not checked out but are currently idle in the pool.
`pool.waitingCount: number`
The number of queued requests waiting on a client when all clients are checked out. It can be helpful to monitor this number to see if you need to adjust the size of the pool.
## events
`Pool` instances are also instances of [`EventEmitter`](https://nodejs.org/api/events.html).
### connect
`pool.on('connect', (client: Client) => void) => void`
Whenever the pool establishes a new client connection to the PostgreSQL backend it will emit the `connect` event with the newly connected client. This presents an opportunity for you to run setup commands on a client.
```js
const pool = new Pool()
pool.on('connect', (client) => {
client.query('SET DATESTYLE = iso, mdy')
})
```
### acquire
`pool.on('acquire', (client: Client) => void) => void`
Whenever a client is checked out from the pool the pool will emit the `acquire` event with the client that was acquired.
### error
`pool.on('error', (err: Error, client: Client) => void) => void`
When a client is sitting idly in the pool it can still emit errors because it is connected to a live backend.
If the backend goes down or a network partition is encountered all the idle, connected clients in your application will emit an error _through_ the pool's error event emitter.
The error listener is passed the error as the first argument and the client upon which the error occurred as the 2nd argument. The client will be automatically terminated and removed from the pool, it is only passed to the error handler in case you want to inspect it.
<Alert>
<div>You probably want to add an event listener to the pool to catch background errors!</div>
Just like other event emitters, if a pool emits an <code>error</code> event and no listeners are added node will emit an
uncaught error and potentially crash your node process.
</Alert>
### release
`pool.on('release', (err: Error, client: Client) => void) => void`
Whenever a client is released back into the pool, the pool will emit the `release` event.
### remove
`pool.on('remove', (client: Client) => void) => void`
Whenever a client is closed & removed from the pool the pool will emit the `remove` event.

View File

@ -0,0 +1,53 @@
---
title: pg.Result
slug: /apis/result
---
The `pg.Result` shape is returned for every successful query.
<div className="alert alert-info">note: you cannot instantiate this directly</div>
## properties
### `result.rows: Array<any>`
Every result will have a rows array. If no rows are returned the array will be empty. Otherwise the array will contain one item for each row returned from the query. By default node-postgres creates a map from the name to value of each column, giving you a json-like object back for each row.
### `result.fields: Array<FieldInfo>`
Every result will have a fields array. This array contains the `name` and `dataTypeID` of each field in the result. These fields are ordered in the same order as the columns if you are using `arrayMode` for the query:
```js
import pg from 'pg'
const { Pool } = pg
const pool = new Pool()
const client = await pool.connect()
const result = await client.query({
rowMode: 'array',
text: 'SELECT 1 as one, 2 as two;',
})
console.log(result.fields[0].name) // one
console.log(result.fields[1].name) // two
console.log(result.rows) // [ [ 1, 2 ] ]
await client.end()
```
### `result.command: string`
The command type last executed: `INSERT` `UPDATE` `CREATE` `SELECT` etc.
### `result.rowCount: int | null`
The number of rows processed by the last command. Can be `null` for commands that never affect rows, such as the `LOCK`-command. More specifically, some commands, including `LOCK`, only return a command tag of the form `COMMAND`, without any `[ROWS]`-field to parse. For such commands `rowCount` will be `null`.
_note: this does not reflect the number of rows __returned__ from a query. e.g. an update statement could update many rows (so high `result.rowCount` value) but `result.rows.length` would be zero. To check for an empty query response on a `SELECT` query use `result.rows.length === 0`_.
[@sehrope](https://github.com/brianc/node-postgres/issues/2182#issuecomment-620553915) has a good explanation:
The `rowCount` is populated from the command tag supplied by the PostgreSQL server. It's generally of the form: `COMMAND [OID] [ROWS]`
For DML commands (INSERT, UPDATE, etc), it reflects how many rows the server modified to process the command. For SELECT or COPY commands it reflects how many rows were retrieved or copied. More info on the specifics here: https://www.postgresql.org/docs/current/protocol-message-formats.html (search for CommandComplete for the message type)
The note in the docs about the difference is because that value is controlled by the server. It's possible for a non-standard server (ex: PostgreSQL fork) or a server version in the future to provide different information in some situations so it'd be best not to rely on it to assume that the rows array length matches the `rowCount`. It's fine to use it for DML counts though.

View File

@ -0,0 +1,6 @@
---
title: Types
slug: /apis/types
---
These docs are incomplete, for now please reference [pg-types docs](https://github.com/brianc/node-pg-types).

View File

@ -0,0 +1,33 @@
---
title: Utilities
---
import { Alert } from '/components/alert.tsx'
## Utility Functions
### pg.escapeIdentifier
Escapes a string as a [SQL identifier](https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS).
```js
import { escapeIdentifier } from 'pg';
const escapedIdentifier = escapeIdentifier('FooIdentifier')
console.log(escapedIdentifier) // '"FooIdentifier"'
```
<Alert>
**Note**: When using an identifier that is the result of this function in an operation like `CREATE TABLE ${escapedIdentifier(identifier)}`, the table that is created will be CASE SENSITIVE. If you use any capital letters in the escaped identifier, you must always refer to the created table like `SELECT * from "MyCaseSensitiveTable"`; queries like `SELECT * FROM MyCaseSensitiveTable` will result in a "Non-existent table" error since case information is stripped from the query.
</Alert>
### pg.escapeLiteral
<Alert>
**Note**: Instead of manually escaping SQL literals, it is recommended to use parameterized queries. Refer to [parameterized queries](/features/queries#parameterized-query) and the [client.query](/apis/client#clientquery) API for more information.
</Alert>
Escapes a string as a [SQL literal](https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-CONSTANTS).
```js
import { escapeLiteral } from 'pg';
const escapedLiteral = escapeLiteral("hello 'world'")
console.log(escapedLiteral) // "'hello ''world'''"
```

View File

@ -0,0 +1,11 @@
{
"connecting": "Connecting",
"queries": "Queries",
"pooling": "Pooling",
"transactions": "Transactions",
"types": "Data Types",
"ssl": "SSL",
"native": "Native",
"esm": "ESM",
"callbacks": "Callbacks"
}

View File

@ -0,0 +1,39 @@
---
title: Callbacks
---
## Callback Support
`async` / `await` is the preferred way to write async code these days with node, but callbacks are supported in the `pg` module and the `pg-pool` module. To use them, pass a callback function as the last argument to the following methods & it will be called and a promise will not be returned:
```js
const { Pool, Client } = require('pg')
// pool
const pool = new Pool()
// run a query on an available client
pool.query('SELECT NOW()', (err, res) => {
console.log(err, res)
})
// check out a client to do something more complex like a transaction
pool.connect((err, client, release) => {
client.query('SELECT NOW()', (err, res) => {
release()
console.log(err, res)
pool.end()
})
})
// single client
const client = new Client()
client.connect((err) => {
if (err) throw err
client.query('SELECT NOW()', (err, res) => {
console.log(err, res)
client.end()
})
})
```

View File

@ -0,0 +1,157 @@
---
title: Connecting
---
## Environment variables
node-postgres uses the same [environment variables](https://www.postgresql.org/docs/9.1/static/libpq-envars.html) as libpq and psql to connect to a PostgreSQL server. Both individual clients & pools will use these environment variables. Here's a tiny program connecting node.js to the PostgreSQL server:
```js
import pg from 'pg'
const { Pool, Client } = pg
// pools will use environment variables
// for connection information
const pool = new Pool()
// you can also use async/await
const res = await pool.query('SELECT NOW()')
await pool.end()
// clients will also use environment variables
// for connection information
const client = new Client()
await client.connect()
const res = await client.query('SELECT NOW()')
await client.end()
```
To run the above program and specify which database to connect to we can invoke it like so:
```sh
$ PGUSER=dbuser \
PGPASSWORD=secretpassword \
PGHOST=database.server.com \
PGPORT=3211 \
PGDATABASE=mydb \
node script.js
```
This allows us to write our programs without having to specify connection information in the program and lets us reuse them to connect to different databases without having to modify the code.
The default values for the environment variables used are:
```
PGUSER=process.env.USER
PGPASSWORD=null
PGHOST=localhost
PGPORT=5432
PGDATABASE=process.env.USER
```
## Programmatic
node-postgres also supports configuring a pool or client programmatically with connection information. Here's our same script from above modified to use programmatic (hard-coded in this case) values. This can be useful if your application already has a way to manage config values or you don't want to use environment variables.
```js
import pg from 'pg'
const { Pool, Client } = pg
const pool = new Pool({
user: 'dbuser',
password: 'secretpassword',
host: 'database.server.com',
port: 3211,
database: 'mydb',
})
console.log(await pool.query('SELECT NOW()'))
const client = new Client({
user: 'dbuser',
password: 'secretpassword',
host: 'database.server.com',
port: 3211,
database: 'mydb',
})
await client.connect()
console.log(await client.query('SELECT NOW()'))
await client.end()
```
Many cloud providers include alternative methods for connecting to database instances using short-lived authentication tokens. node-postgres supports dynamic passwords via a callback function, either synchronous or asynchronous. The callback function must resolve to a string.
```js
import pg from 'pg'
const { Pool } = pg
import { RDS } from 'aws-sdk'
const signerOptions = {
credentials: {
accessKeyId: 'YOUR-ACCESS-KEY',
secretAccessKey: 'YOUR-SECRET-ACCESS-KEY',
},
region: 'us-east-1',
hostname: 'example.aslfdewrlk.us-east-1.rds.amazonaws.com',
port: 5432,
username: 'api-user',
}
const signer = new RDS.Signer(signerOptions)
const getPassword = () => signer.getAuthToken()
const pool = new Pool({
user: signerOptions.username,
password: getPassword,
host: signerOptions.hostname,
port: signerOptions.port,
database: 'my-db',
})
```
### Unix Domain Sockets
Connections to unix sockets can also be made. This can be useful on distros like Ubuntu, where authentication is managed via the socket connection instead of a password.
```js
import pg from 'pg'
const { Client } = pg
client = new Client({
user: 'username',
password: 'password',
host: '/cloudsql/myproject:zone:mydb',
database: 'database_name',
})
```
## Connection URI
You can initialize both a pool and a client with a connection string URI as well. This is common in environments like Heroku where the database connection string is supplied to your application dyno through an environment variable. Connection string parsing brought to you by [pg-connection-string](https://github.com/brianc/node-postgres/tree/master/packages/pg-connection-string).
```js
import pg from 'pg'
const { Pool, Client } = pg
const connectionString = 'postgresql://dbuser:secretpassword@database.server.com:3211/mydb'
const pool = new Pool({
connectionString,
})
await pool.query('SELECT NOW()')
await pool.end()
const client = new Client({
connectionString,
})
await client.connect()
await client.query('SELECT NOW()')
await client.end()
```

View File

@ -0,0 +1,37 @@
---
title: ESM
---
## ESM Support
As of v8.15.x node-postgres supporters the __ECMAScript Module__ (ESM) format. This means you can use `import` statements instead of `require` or `import pg from 'pg'`.
CommonJS modules are still supported. The ESM format is an opt-in feature and will not affect existing codebases that use CommonJS.
The docs have been changed to show ESM usage, but in a CommonJS context you can still use the same code, you just need to change the import format.
If you're using CommonJS, you can use the following code to import the `pg` module:
```js
const pg = require('pg')
const { Client } = pg
// etc...
```
### ESM Usage
If you're using ESM, you can use the following code to import the `pg` module:
```js
import { Client } from 'pg'
// etc...
```
Previously if you were using ESM you would have to use the following code:
```js
import pg from 'pg'
const { Client } = pg
// etc...
```

View File

@ -0,0 +1,29 @@
---
title: Native Bindings
slug: /features/native
metaTitle: bar
---
Native bindings between node.js & [libpq](https://www.postgresql.org/docs/9.5/static/libpq.html) are provided by the [node-pg-native](https://github.com/brianc/node-pg-native) package. node-postgres can consume this package & use the native bindings to access the PostgreSQL server while giving you the same interface that is used with the JavaScript version of the library.
To use the native bindings first you'll need to install them:
```sh
$ npm install pg pg-native
```
Once `pg-native` is installed instead of requiring a `Client` or `Pool` constructor from `pg` you do the following:
```js
import pg from 'pg'
const { native } = pg
const { Client, Pool } = native
```
When you access the `.native` property on `'pg'` it will automatically require the `pg-native` package and wrap it in the same API.
<div class='alert alert-warning'>
Care has been taken to normalize between the two, but there might still be edge cases where things behave subtly differently due to the nature of using libpq over handling the binary protocol directly in JavaScript, so it's recommended you chose to either use the JavaScript driver or the native bindings both in development and production. For what its worth: I use the pure JavaScript driver because the JavaScript driver is more portable (doesn't need a compiler), and the pure JavaScript driver is <em>plenty</em> fast.
</div>
Some of the modules using advanced features of PostgreSQL such as [pg-query-stream](https://github.com/brianc/node-pg-query-stream), [pg-cursor](https://github.com/brianc/node-pg-cursor),and [pg-copy-streams](https://github.com/brianc/node-pg-copy-streams) need to operate directly on the binary stream and therefore are incompatible with the native bindings.

View File

@ -0,0 +1,109 @@
---
title: Pooling
---
import { Alert } from '/components/alert.tsx'
import { Info } from '/components/info.tsx'
If you're working on a web application or other software which makes frequent queries you'll want to use a connection pool.
The easiest and by far most common way to use node-postgres is through a connection pool.
## Why?
- Connecting a new client to the PostgreSQL server requires a handshake which can take 20-30 milliseconds. During this time passwords are negotiated, SSL may be established, and configuration information is shared with the client & server. Incurring this cost _every time_ we want to execute a query would substantially slow down our application.
- The PostgreSQL server can only handle a [limited number of clients at a time](https://wiki.postgresql.org/wiki/Number_Of_Database_Connections). Depending on the available memory of your PostgreSQL server you may even crash the server if you connect an unbounded number of clients. _note: I have crashed a large production PostgreSQL server instance in RDS by opening new clients and never disconnecting them in a python application long ago. It was not fun._
- PostgreSQL can only process one query at a time on a single connected client in a first-in first-out manner. If your multi-tenant web application is using only a single connected client all queries among all simultaneous requests will be pipelined and executed serially, one after the other. No good!
### Good news
node-postgres ships with built-in connection pooling via the [pg-pool](/apis/pool) module.
## Examples
The client pool allows you to have a reusable pool of clients you can check out, use, and return. You generally want a limited number of these in your application and usually just 1. Creating an unbounded number of pools defeats the purpose of pooling at all.
### Checkout, use, and return
```js
import pg from 'pg'
const { Pool } = pg
const pool = new Pool()
// the pool will emit an error on behalf of any idle clients
// it contains if a backend error or network partition happens
pool.on('error', (err, client) => {
console.error('Unexpected error on idle client', err)
process.exit(-1)
})
const client = await pool.connect()
const res = await client.query('SELECT * FROM users WHERE id = $1', [1])
console.log(res.rows[0])
client.release()
```
<Alert>
<div>
You must <b>always</b> return the client to the pool if you successfully check it out, regardless of whether or not
there was an error with the queries you ran on the client.
</div>
If you don't release the client your application will leak them and eventually your pool will be empty forever and all
future requests to check out a client from the pool will wait forever.
</Alert>
### Single query
If you don't need a transaction or you just need to run a single query, the pool has a convenience method to run a query on any available client in the pool. This is the preferred way to query with node-postgres if you can as it removes the risk of leaking a client.
```js
import pg from 'pg'
const { Pool } = pg
const pool = new Pool()
const res = await pool.query('SELECT * FROM users WHERE id = $1', [1])
console.log('user:', res.rows[0])
```
### Shutdown
To shut down a pool call `pool.end()` on the pool. This will wait for all checked-out clients to be returned and then shut down all the clients and the pool timers.
```js
import pg from 'pg'
const { Pool } = pg
const pool = new Pool()
console.log('starting async query')
const result = await pool.query('SELECT NOW()')
console.log('async query finished')
console.log('starting callback query')
pool.query('SELECT NOW()', (err, res) => {
console.log('callback query finished')
})
console.log('calling end')
await pool.end()
console.log('pool has drained')
```
The output of the above will be:
```
starting async query
async query finished
starting callback query
calling end
callback query finished
pool has drained
```
<Info>
The pool will return errors when attempting to check out a client after you've called pool.end() on the pool.
</Info>

View File

@ -0,0 +1,135 @@
---
title: Queries
slug: /features/queries
---
For the sake of brevity I am using the `client.query` method instead of the `pool.query` method - both methods support the same API. In fact, `pool.query` delegates directly to `client.query` internally.
## Text only
If your query has no parameters you do not need to include them to the query method:
```js
await client.query('SELECT NOW() as now')
```
## Parameterized query
If you are passing parameters to your queries you will want to avoid string concatenating parameters into the query text directly. This can (and often does) lead to sql injection vulnerabilities. node-postgres supports parameterized queries, passing your query text _unaltered_ as well as your parameters to the PostgreSQL server where the parameters are safely substituted into the query with battle-tested parameter substitution code within the server itself.
```js
const text = 'INSERT INTO users(name, email) VALUES($1, $2) RETURNING *'
const values = ['brianc', 'brian.m.carlson@gmail.com']
const res = await client.query(text, values)
console.log(res.rows[0])
// { name: 'brianc', email: 'brian.m.carlson@gmail.com' }
```
<div class="alert alert-warning">
PostgreSQL does not support parameters for identifiers. If you need to have dynamic database, schema, table, or column names (e.g. in DDL statements) use [pg-format](https://www.npmjs.com/package/pg-format) package for handling escaping these values to ensure you do not have SQL injection!
</div>
Parameters passed as the second argument to `query()` will be converted to raw data types using the following rules:
**null and undefined**
If parameterizing `null` and `undefined` then both will be converted to `null`.
**Date**
Custom conversion to a UTC date string.
**Buffer**
Buffer instances are unchanged.
**Array**
Converted to a string that describes a Postgres array. Each array item is recursively converted using the rules described here.
**Object**
If a parameterized value has the method `toPostgres` then it will be called and its return value will be used in the query.
The signature of `toPostgres` is the following:
```
toPostgres (prepareValue: (value) => any): any
```
The `prepareValue` function provided can be used to convert nested types to raw data types suitable for the database.
Otherwise if no `toPostgres` method is defined then `JSON.stringify` is called on the parameterized value.
**Everything else**
All other parameterized values will be converted by calling `value.toString` on the value.
## Query config object
`pool.query` and `client.query` both support taking a config object as an argument instead of taking a string and optional array of parameters. The same example above could also be performed like so:
```js
const query = {
text: 'INSERT INTO users(name, email) VALUES($1, $2)',
values: ['brianc', 'brian.m.carlson@gmail.com'],
}
const res = await client.query(query)
console.log(res.rows[0])
```
The query config object allows for a few more advanced scenarios:
### Prepared statements
PostgreSQL has the concept of a [prepared statement](https://www.postgresql.org/docs/9.3/static/sql-prepare.html). node-postgres supports this by supplying a `name` parameter to the query config object. If you supply a `name` parameter the query execution plan will be cached on the PostgreSQL server on a **per connection basis**. This means if you use two different connections each will have to parse & plan the query once. node-postgres handles this transparently for you: a client only requests a query to be parsed the first time that particular client has seen that query name:
```js
const query = {
// give the query a unique name
name: 'fetch-user',
text: 'SELECT * FROM user WHERE id = $1',
values: [1],
}
const res = await client.query(query)
console.log(res.rows[0])
```
In the above example the first time the client sees a query with the name `'fetch-user'` it will send a 'parse' request to the PostgreSQL server & execute the query as normal. The second time, it will skip the 'parse' request and send the _name_ of the query to the PostgreSQL server.
<div class='message is-warning'>
<div class='message-body'>
Be careful not to fall into the trap of premature optimization. Most of your queries will likely not benefit much, if at all, from using prepared statements. This is a somewhat "power user" feature of PostgreSQL that is best used when you know how to use it - namely with very complex queries with lots of joins and advanced operations like union and switch statements. I rarely use this feature in my own apps unless writing complex aggregate queries for reports and I know the reports are going to be executed very frequently.
</div>
</div>
### Row mode
By default node-postgres reads rows and collects them into JavaScript objects with the keys matching the column names and the values matching the corresponding row value for each column. If you do not need or do not want this behavior you can pass `rowMode: 'array'` to a query object. This will inform the result parser to bypass collecting rows into a JavaScript object, and instead will return each row as an array of values.
```js
const query = {
text: 'SELECT $1::text as first_name, $2::text as last_name',
values: ['Brian', 'Carlson'],
rowMode: 'array',
}
const res = await client.query(query)
console.log(res.fields.map(field => field.name)) // ['first_name', 'last_name']
console.log(res.rows[0]) // ['Brian', 'Carlson']
```
### Types
You can pass in a custom set of type parsers to use when parsing the results of a particular query. The `types` property must conform to the [Types](/apis/types) API. Here is an example in which every value is returned as a string:
```js
const query = {
text: 'SELECT * from some_table',
types: {
getTypeParser: () => val => val,
},
}
```

View File

@ -0,0 +1,66 @@
---
title: SSL
slug: /features/ssl
---
node-postgres supports TLS/SSL connections to your PostgreSQL server as long as the server is configured to support it. When instantiating a pool or a client you can provide an `ssl` property on the config object and it will be passed to the constructor for the [node TLSSocket](https://nodejs.org/api/tls.html#tls_class_tls_tlssocket).
## Self-signed cert
Here's an example of a configuration you can use to connect a client or a pool to a PostgreSQL server.
```js
const config = {
database: 'database-name',
host: 'host-or-ip',
// this object will be passed to the TLSSocket constructor
ssl: {
rejectUnauthorized: false,
ca: fs.readFileSync('/path/to/server-certificates/root.crt').toString(),
key: fs.readFileSync('/path/to/client-key/postgresql.key').toString(),
cert: fs.readFileSync('/path/to/client-certificates/postgresql.crt').toString(),
},
}
import { Client, Pool } from 'pg'
const client = new Client(config)
await client.connect()
console.log('connected')
await client.end()
const pool = new Pool(config)
const pooledClient = await pool.connect()
console.log('connected')
pooledClient.release()
await pool.end()
```
## Usage with `connectionString`
If you plan to use a combination of a database connection string from the environment and SSL settings in the config object directly, then you must avoid including any of `sslcert`, `sslkey`, `sslrootcert`, or `sslmode` in the connection string. If any of these options are used then the `ssl` object is replaced and any additional options provided there will be lost.
```js
const config = {
connectionString: 'postgres://user:password@host:port/db?sslmode=require',
// Beware! The ssl object is overwritten when parsing the connectionString
ssl: {
rejectUnauthorized: false,
ca: fs.readFileSync('/path/to/server-certificates/root.crt').toString(),
},
}
```
## Channel binding
If the PostgreSQL server offers SCRAM-SHA-256-PLUS (i.e. channel binding) for TLS/SSL connections, you can enable this as follows:
```js
const client = new Client({ ...config, enableChannelBinding: true})
```
or
```js
const pool = new Pool({ ...config, enableChannelBinding: true})
```

View File

@ -0,0 +1,39 @@
---
title: Transactions
---
import { Alert } from '/components/alert.tsx'
To execute a transaction with node-postgres you simply execute `BEGIN / COMMIT / ROLLBACK` queries yourself through a client. Because node-postgres strives to be low level and un-opinionated, it doesn't provide any higher level abstractions specifically around transactions.
<Alert>
You <strong>must</strong> use the <em>same</em> client instance for all statements within a transaction. PostgreSQL
isolates a transaction to individual clients. This means if you initialize or use transactions with the{' '}
<span className="code">pool.query</span> method you <strong>will</strong> have problems. Do not use transactions with
the <span className="code">pool.query</span> method.
</Alert>
## Examples
```js
import { Pool } from 'pg'
const pool = new Pool()
const client = await pool.connect()
try {
await client.query('BEGIN')
const queryText = 'INSERT INTO users(name) VALUES($1) RETURNING id'
const res = await client.query(queryText, ['brianc'])
const insertPhotoText = 'INSERT INTO photos(user_id, photo_url) VALUES ($1, $2)'
const insertPhotoValues = [res.rows[0].id, 's3.bucket.foo']
await client.query(insertPhotoText, insertPhotoValues)
await client.query('COMMIT')
} catch (e) {
await client.query('ROLLBACK')
throw e
} finally {
client.release()
}
```

View File

@ -0,0 +1,106 @@
---
title: Data Types
---
import { Alert } from '/components/alert.tsx'
PostgreSQL has a rich system of supported [data types](https://www.postgresql.org/docs/current/datatype.html). node-postgres does its best to support the most common data types out of the box and supplies an extensible type parser to allow for custom type serialization and parsing.
## strings by default
node-postgres will convert a database type to a JavaScript string if it doesn't have a registered type parser for the database type. Furthermore, you can send any type to the PostgreSQL server as a string and node-postgres will pass it through without modifying it in any way. To circumvent the type parsing completely do something like the following.
```js
const queryText = 'SELECT int_col::text, date_col::text, json_col::text FROM my_table'
const result = await client.query(queryText)
console.log(result.rows[0]) // will contain the unparsed string value of each column
```
## type parsing examples
### uuid + json / jsonb
There is no data type in JavaScript for a uuid/guid so node-postgres converts a uuid to a string. JavaScript has great support for JSON and node-postgres converts json/jsonb objects directly into their JavaScript object via [`JSON.parse`](https://github.com/brianc/node-pg-types/blob/master/lib/textParsers.js#L193). Likewise sending an object to the PostgreSQL server via a query from node-postgres, node-postgres will call [`JSON.stringify`](https://github.com/brianc/node-postgres/blob/e5f0e5d36a91a72dda93c74388ac890fa42b3be0/lib/utils.js#L47) on your outbound value, automatically converting it to json for the server.
```js
const createTableText = `
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
CREATE TEMP TABLE IF NOT EXISTS users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
data JSONB
);
`
// create our temp table
await client.query(createTableText)
const newUser = { email: 'brian.m.carlson@gmail.com' }
// create a new user
await client.query('INSERT INTO users(data) VALUES($1)', [newUser])
const { rows } = await client.query('SELECT * FROM users')
console.log(rows)
/*
output:
[{
id: 'd70195fd-608e-42dc-b0f5-eee975a621e9',
data: { email: 'brian.m.carlson@gmail.com' }
}]
*/
```
### date / timestamp / timestamptz
node-postgres will convert instances of JavaScript date objects into the expected input value for your PostgreSQL server. Likewise, when reading a `date`, `timestamp`, or `timestamptz` column value back into JavaScript, node-postgres will parse the value into an instance of a JavaScript `Date` object.
```js
const createTableText = `
CREATE TEMP TABLE dates(
date_col DATE,
timestamp_col TIMESTAMP,
timestamptz_col TIMESTAMPTZ
);
`
// create our temp table
await client.query(createTableText)
// insert the current time into it
const now = new Date()
const insertText = 'INSERT INTO dates(date_col, timestamp_col, timestamptz_col) VALUES ($1, $2, $3)'
await client.query(insertText, [now, now, now])
// read the row back out
const result = await client.query('SELECT * FROM dates')
console.log(result.rows)
// {
// date_col: 2017-05-29T05:00:00.000Z,
// timestamp_col: 2017-05-29T23:18:13.263Z,
// timestamptz_col: 2017-05-29T23:18:13.263Z
// }
```
psql output:
```
bmc=# select * from dates;
date_col | timestamp_col | timestamptz_col
------------+-------------------------+----------------------------
2017-05-29 | 2017-05-29 18:18:13.263 | 2017-05-29 18:18:13.263-05
(1 row)
```
node-postgres converts `DATE` and `TIMESTAMP` columns into the **local** time of the node process set at `process.env.TZ`.
_note: I generally use `TIMESTAMPTZ` when storing dates; otherwise, inserting a time from a process in one timezone and reading it out in a process in another timezone can cause unexpected differences in the time._
<Alert>
<div class="message-body">
Although PostgreSQL supports microseconds in dates, JavaScript only supports dates to the millisecond precision.
Keep this in mind when you send dates to and from PostgreSQL from node: your microseconds will be truncated when
converting to a JavaScript date object even if they exist in the database. If you need to preserve them, I recommend
using a custom type parser.
</div>
</Alert>

View File

@ -0,0 +1,6 @@
{
"project-structure": "Suggested Code Structure",
"async-express": "Express with Async/Await",
"pool-sizing": "Pool Sizing",
"upgrading": "Upgrading"
}

View File

@ -0,0 +1,82 @@
---
title: Express with async/await
---
My preferred way to use node-postgres (and all async code in node.js) is with `async/await`. I find it makes reasoning about control-flow easier and allows me to write more concise and maintainable code.
This is how I typically structure express web-applications with node-postgres to use `async/await`:
```
- app.js
- index.js
- routes/
- index.js
- photos.js
- user.js
- db/
- index.js <--- this is where I put data access code
```
That's the same structure I used in the [project structure](/guides/project-structure) example.
My `db/index.js` file usually starts out like this:
```js
import { Pool } from 'pg'
const pool = new Pool()
export const query = (text, params) => pool.query(text, params)
```
Then I will install [express-promise-router](https://www.npmjs.com/package/express-promise-router) and use it to define my routes. Here is my `routes/user.js` file:
```js
import Router from 'express-promise-router'
import db from '../db.js'
// create a new express-promise-router
// this has the same API as the normal express router except
// it allows you to use async functions as route handlers
const router = new Router()
// export our router to be mounted by the parent application
export default router
router.get('/:id', async (req, res) => {
const { id } = req.params
const { rows } = await db.query('SELECT * FROM users WHERE id = $1', [id])
res.send(rows[0])
})
```
Then in my `routes/index.js` file I'll have something like this which mounts each individual router into the main application:
```js
// ./routes/index.js
import users from './user.js'
import photos from './photos.js'
const mountRoutes = (app) => {
app.use('/users', users)
app.use('/photos', photos)
// etc..
}
export default mountRoutes
```
And finally in my `app.js` file where I bootstrap express I will have my `routes/index.js` file mount all my routes. The routes know they're using async functions but because of express-promise-router the main express app doesn't know and doesn't care!
```js
// ./app.js
import express from 'express'
import mountRoutes from './routes.js'
const app = express()
mountRoutes(app)
// ... more express setup stuff can follow
```
Now you've got `async/await`, node-postgres, and express all working together!

View File

@ -0,0 +1,25 @@
---
title: Pool Sizing
---
If you're using a [pool](/apis/pool) in an application with multiple instances of your service running (common in most cloud/container environments currently), you'll need to think a bit about the `max` parameter of your pool across all services and all _instances_ of all services which are connecting to your Postgres server.
This can get pretty complex depending on your cloud environment. Further nuance is introduced with things like pg-bouncer, RDS connection proxies, etc., which will do some forms of connection pooling and connection multiplexing. So, it's definitely worth thinking about. Let's run through a few setups. While certainly not exhaustive, these examples hopefully prompt you into thinking about what's right for your setup.
## Simple apps, dev mode, fixed instance counts, etc.
If your app isn't running in a k8s style env with containers scaling automatically or lambdas or cloud functions etc., you can do some "napkin math" for the `max` pool config you can use. Let's assume your Postgres instance is configured to have a maximum of 200 connections at any one time. You know your service is going to run on 4 instances. You can set the `max` pool size to 50, but if all your services are saturated waiting on database connections, you won't be able to connect to the database from any mgmt tools or scale up your services without changing config/code to adjust the max size.
In this situation, I'd probably set the `max` to 20 or 25. This lets you have plenty of headroom for scaling more instances and realistically, if your app is starved for db connections, you probably want to take a look at your queries and make them execute faster, or cache, or something else to reduce the load on the database. I worked on a more reporting-heavy application with limited users, but each running 5-6 queries at a time which all took 100-200 milliseconds to run. In that situation, I upped the `max` to 50. Typically, though, I don't bother setting it to anything other than the default of `10` as that's usually _fine_.
## Auto-scaling, cloud-functions, multi-tenancy, etc.
If the number of instances of your services which connect to your database is more dynamic and based on things like load, auto-scaling containers, or running in cloud-functions, you need to be a bit more thoughtful about what your max might be. Often in these environments, there will be another database pooling proxy in front of the database like pg-bouncer or the RDS-proxy, etc. I'm not sure how all these function exactly, and they all have some trade-offs, but let's assume you're not using a proxy. Then I'd be pretty cautious about how large you set any individual pool. If you're running an application under pretty serious load where you need dynamic scaling or lots of lambdas spinning up and sending queries, your queries are likely fast and you should be fine setting the `max` to a low value like 10 -- or just leave it alone, since `10` is the default.
## pg-bouncer, RDS-proxy, etc.
I'm not sure of all the pooling services for Postgres. I haven't used any myself. Throughout the years of working on `pg`, I've addressed issues caused by various proxies behaving differently than an actual Postgres backend. There are also gotchas with things like transactions. On the other hand, plenty of people run these with much success. In this situation, I would just recommend using some small but reasonable `max` value like the default value of `10` as it can still be helpful to keep a few TCP sockets from your services to the Postgres proxy open.
## Conclusion, tl;dr
It's a bit of a complicated topic and doesn't have much impact on things until you need to start scaling. At that point, your number of connections _still_ probably won't be your scaling bottleneck. It's worth thinking about a bit, but mostly I'd just leave the pool size to the default of `10` until you run into troubles: hopefully you never do!

View File

@ -0,0 +1,131 @@
---
title: Suggested Project Structure
---
Whenever I am writing a project & using node-postgres I like to create a file within it and make all interactions with the database go through this file. This serves a few purposes:
- Allows my project to adjust to any changes to the node-postgres API without having to trace down all the places I directly use node-postgres in my application.
- Allows me to have a single place to put logging and diagnostics around my database.
- Allows me to make custom extensions to my database access code & share it throughout the project.
- Allows a single place to bootstrap & configure the database.
## example
The location doesn't really matter - I've found it usually ends up being somewhat app specific and in line with whatever folder structure conventions you're using. For this example I'll use an express app structured like so:
```
- app.js
- index.js
- routes/
- index.js
- photos.js
- user.js
- db/
- index.js <--- this is where I put data access code
```
Typically I'll start out my `db/index.js` file like so:
```js
import { Pool } from 'pg'
const pool = new Pool()
export const query = (text, params) => {
return pool.query(text, params)
}
```
That's it. But now everywhere else in my application instead of requiring `pg` directly, I'll require this file. Here's an example of a route within `routes/user.js`:
```js
// notice here I'm requiring my database adapter file
// and not requiring node-postgres directly
import * as db from '../db/index.js'
app.get('/:id', async (req, res, next) => {
const result = await db.query('SELECT * FROM users WHERE id = $1', [req.params.id])
res.send(result.rows[0])
})
// ... many other routes in this file
```
Imagine we have lots of routes scattered throughout many files under our `routes/` directory. We now want to go back and log every single query that's executed, how long it took, and the number of rows it returned. If we had required node-postgres directly in every route file we'd have to go edit every single route - that would take forever & be really error prone! But thankfully we put our data access into `db/index.js`. Let's go add some logging:
```js
import { Pool } from 'pg'
const pool = new Pool()
export const query = async (text, params) => {
const start = Date.now()
const res = await pool.query(text, params)
const duration = Date.now() - start
console.log('executed query', { text, duration, rows: res.rowCount })
return res
}
```
That was pretty quick! And now all of our queries everywhere in our application are being logged.
_note: I didn't log the query parameters. Depending on your application you might be storing encrypted passwords or other sensitive information in your database. If you log your query parameters you might accidentally log sensitive information. Every app is different though so do what suits you best!_
Now what if we need to check out a client from the pool to run several queries in a row in a transaction? We can add another method to our `db/index.js` file when we need to do this:
```js
import { Pool } from 'pg'
const pool = new Pool()
export const query = async (text, params) => {
const start = Date.now()
const res = await pool.query(text, params)
const duration = Date.now() - start
console.log('executed query', { text, duration, rows: res.rowCount })
return res
}
export const getClient = () => {
return pool.connect()
}
```
Okay. Great - the simplest thing that could possibly work. It seems like one of our routes that checks out a client to run a transaction is forgetting to call `release` in some situation! Oh no! We are leaking a client & have hundreds of these routes to go audit. Good thing we have all our client access going through this single file. Lets add some deeper diagnostic information here to help us track down where the client leak is happening.
```js
export const query = async (text, params) => {
const start = Date.now()
const res = await pool.query(text, params)
const duration = Date.now() - start
console.log('executed query', { text, duration, rows: res.rowCount })
return res
}
export const getClient = async () => {
const client = await pool.connect()
const query = client.query
const release = client.release
// set a timeout of 5 seconds, after which we will log this client's last query
const timeout = setTimeout(() => {
console.error('A client has been checked out for more than 5 seconds!')
console.error(`The last executed query on this client was: ${client.lastQuery}`)
}, 5000)
// monkey patch the query method to keep track of the last query executed
client.query = (...args) => {
client.lastQuery = args
return query.apply(client, args)
}
client.release = () => {
// clear our timeout
clearTimeout(timeout)
// set the methods back to their old un-monkey-patched version
client.query = query
client.release = release
return release.apply(client)
}
return client
}
```
That should hopefully give us enough diagnostic information to track down any leaks.

View File

@ -0,0 +1,115 @@
---
title: Upgrading
slug: /guides/upgrading
---
# Upgrading to 8.0
node-postgres at 8.0 introduces a breaking change to ssl-verified connections. If you connect with ssl and use
```
const client = new Client({ ssl: true })
```
and the server's SSL certificate is self-signed, connections will fail as of node-postgres 8.0. To keep the existing behavior, modify the invocation to
```
const client = new Client({ ssl: { rejectUnauthorized: false } })
```
The rest of the changes are relatively minor and unlikely to cause issues; see [the announcement](/announcements#2020-02-25) for full details.
# Upgrading to 7.0
node-postgres at 7.0 introduces somewhat significant breaking changes to the public API.
## node version support
Starting with `pg@7.0` the earliest version of node supported will be `node@4.x LTS`. Support for `node@0.12.x` and `node@.10.x` is dropped, and the module wont work as it relies on new es6 features not available in older versions of node.
## pg singleton
In the past there was a singleton pool manager attached to the root `pg` object in the package. This singleton could be used to provision connection pools automatically by calling `pg.connect`. This API caused a lot of confusion for users. It also introduced a opaque module-managed singleton which was difficult to reason about, debug, error-prone, and inflexible. Starting in pg@6.0 the methods' documentation was removed, and starting in pg@6.3 the methods were deprecated with a warning message.
If your application still relies on these they will be _gone_ in `pg@7.0`. In order to migrate you can do the following:
```js
// old way, deprecated in 6.3.0:
// connection using global singleton
pg.connect(function (err, client, done) {
client.query(/* etc, etc */)
done()
})
// singleton pool shutdown
pg.end()
// ------------------
// new way, available since 6.0.0:
// create a pool
const pool = new pg.Pool()
// connection using created pool
pool.connect(function (err, client, done) {
client.query(/* etc, etc */)
done()
})
// pool shutdown
pool.end()
```
node-postgres ships with a built-in pool object provided by [pg-pool](https://github.com/brianc/node-pg-pool) which is already used internally by the `pg.connect` and `pg.end` methods. Migrating to a user-managed pool (or set of pools) allows you to more directly control their set up their life-cycle.
## client.query(...).on
Before `pg@7.0` the `client.query` method would _always_ return an instance of a query. The query instance was an event emitter, accepted a callback, and was also a promise. A few problems...
- too many flow control options on a single object was confusing
- event emitter `.on('error')` does not mix well with promise `.catch`
- the `row` event was a common source of errors: it looks like a stream but has no support for back-pressure, misleading users into trying to pipe results or handling them in the event emitter for a desired performance gain.
- error handling with a `.done` and `.error` emitter pair for every query is cumbersome and returning the emitter from `client.query` indicated this sort of pattern may be encouraged: it is not.
Starting with `pg@7.0` the return value `client.query` will be dependent on what you pass to the method: I think this aligns more with how most node libraries handle the callback/promise combo, and I hope it will make the "just works" :tm: feeling better while reducing surface area and surprises around event emitter / callback combos.
### client.query with a callback
```js
const query = client.query('SELECT NOW()', (err, res) => {
/* etc, etc */
})
assert(query === undefined) // true
```
If you pass a callback to the method `client.query` will return `undefined`. This limits flow control to the callback which is in-line with almost all of node's core APIs.
### client.query without a callback
```js
const query = client.query('SELECT NOW()')
assert(query instanceof Promise) // true
assert(query.on === undefined) // true
query.then((res) => /* etc, etc */)
```
If you do **not** pass a callback `client.query` will return an instance of a `Promise`. This will **not** be a query instance and will not be an event emitter. This is in line with how most promise-based APIs work in node.
### client.query(Submittable)
`client.query` has always accepted any object that has a `.submit` method on it. In this scenario the client calls `.submit` on the object, delegating execution responsibility to it. In this situation the client also **returns the instance it was passed**. This is how [pg-cursor](https://github.com/brianc/node-pg-cursor) and [pg-query-stream](https://github.com/brianc/node-pg-query-stream) work. So, if you need the event emitter functionality on your queries for some reason, it is still possible because `Query` is an instance of `Submittable`:
```js
import pg from 'pg'
const { Client, Query } = pg
const query = client.query(new Query('SELECT NOW()'))
query.on('row', (row) => {})
query.on('end', (res) => {})
query.on('error', (res) => {})
```
`Query` is considered a public, documented part of the API of node-postgres and this form will be supported indefinitely.
_note: I have been building apps with node-postgres for almost 7 years. In that time I have never used the event emitter API as the primary way to execute queries. I used to use callbacks and now I use async/await. If you need to stream results I highly recommend you use [pg-cursor](https://github.com/brianc/node-pg-cursor) or [pg-query-stream](https://github.com/brianc/node-pg-query-stream) and **not** the query object as an event emitter._

87
docs/pages/index.mdx Normal file
View File

@ -0,0 +1,87 @@
---
title: Welcome
slug: /
---
import { Logo } from '/components/logo.tsx'
node-postgres is a collection of node.js modules for interfacing with your PostgreSQL database. It has support for callbacks, promises, async/await, connection pooling, prepared statements, cursors, streaming results, C/C++ bindings, rich type parsing, and more! Just like PostgreSQL itself there are a lot of features: this documentation aims to get you up and running quickly and in the right direction. It also tries to provide guides for more advanced & edge-case topics allowing you to tap into the full power of PostgreSQL from node.js.
## Install
```bash
$ npm install pg
```
## Supporters
node-postgres continued development and support is made possible by the many [supporters](https://github.com/brianc/node-postgres/blob/master/SPONSORS.md).
Special thanks to [Medplum](https://www.medplum.com/) for sponsoring node-postgres for a whole year!
<a href="https://www.medplum.com/">
<img
alt="Medplum"
src="https://raw.githubusercontent.com/medplum/medplum-logo/refs/heads/main/medplum-logo.png"
style={{
width: '300px',
height: 'auto',
margin: '0 auto',
display: 'block',
}}
/>
</a>
If you or your company would like to sponsor node-postgres stop by [GitHub Sponsors](https://github.com/sponsors/brianc) and sign up or feel free to [email me](mailto:brian@pecanware.com) if you want to add your logo to the documentation or discuss higher tiers of sponsorship!
# Version compatibility
node-postgres strives to be compatible with all recent LTS versions of node & the most recent "stable" version. At the time of this writing node-postgres is compatible with node 18.x, 20.x, 22.x, and 24.x.
## Getting started
The simplest possible way to connect, query, and disconnect is with async/await:
```js
import { Client } from 'pg'
const client = new Client()
await client.connect()
const res = await client.query('SELECT $1::text as message', ['Hello world!'])
console.log(res.rows[0].message) // Hello world!
await client.end()
```
### Error Handling
For the sake of simplicity, these docs will assume that the methods are successful. In real life use, make sure to properly handle errors thrown in the methods. A `try/catch` block is a great way to do so:
```ts
import { Client } from 'pg'
const client = new Client()
await client.connect()
try {
const res = await client.query('SELECT $1::text as message', ['Hello world!'])
console.log(res.rows[0].message) // Hello world!
} catch (err) {
console.error(err);
} finally {
await client.end()
}
```
### Pooling
In most applications you'll want to use a [connection pool](/features/pooling) to manage your connections. This is a more advanced topic, but here's a simple example of how to use it:
```js
import { Pool } from 'pg'
const pool = new Pool()
const res = await pool.query('SELECT $1::text as message', ['Hello world!'])
console.log(res.rows[0].message) // Hello world!
```
Our real-world apps are almost always more complicated than that, and I urge you to read on!

BIN
docs/public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

83
docs/theme.config.js Normal file
View File

@ -0,0 +1,83 @@
// theme.config.js
export default {
project: {
link: 'https://github.com/brianc/node-postgres',
},
twitter: {
cardType: 'summary_large_image',
site: 'https://node-postgres.com',
},
docsRepositoryBase: 'https://github.com/brianc/node-postgres/blob/master/docs', // base URL for the docs repository
titleSuffix: ' node-postgres',
darkMode: true,
navigation: {
prev: true,
next: true,
},
footer: {
text: `MIT ${new Date().getFullYear()} © Brian Carlson.`,
},
editLink: {
text: 'Edit this page on GitHub',
},
logo: (
<>
<svg
version="1.0"
xmlns="http://www.w3.org/2000/svg"
height={48}
width={48}
viewBox="0 0 1024.000000 1024.000000"
preserveAspectRatio="xMidYMid meet"
>
<g transform="translate(0.000000,1024.000000) scale(0.100000,-0.100000)" fill="#3c873a" stroke="none">
<path
d="M4990 7316 c-391 -87 -703 -397 -1003 -996 -285 -568 -477 -1260
-503 -1811 l-7 -142 -112 7 c-103 5 -207 27 -382 78 -37 11 -44 10 -63 -7 -61
-55 17 -180 177 -285 91 -60 194 -103 327 -137 l104 -26 17 -71 c44 -183 152
-441 256 -613 125 -207 322 -424 493 -541 331 -229 774 -291 1113 -156 112 45
182 94 209 147 13 24 13 35 -1 90 -22 87 -88 219 -134 267 -46 49 -79 52 -153
14 -168 -85 -360 -54 -508 83 -170 157 -244 440 -195 743 50 304 231 601 430
706 168 89 332 60 463 -81 66 -71 110 -140 197 -315 83 -166 116 -194 203
-170 88 23 370 258 637 531 411 420 685 806 808 1139 54 145 71 243 71 410 1
128 -3 157 -27 243 -86 310 -243 543 -467 690 -207 137 -440 157 -966 85
l-161 -22 -94 41 c-201 87 -327 113 -533 112 -77 -1 -166 -7 -196 -13z m-89
-1357 c15 -10 34 -38 43 -61 23 -56 13 -111 -28 -156 -59 -64 -171 -54 -216
21 -35 57 -22 145 28 190 44 40 122 43 173 6z m-234 -1361 c-46 -74 -156 -188
-249 -258 -211 -159 -459 -219 -734 -179 l-76 12 89 28 c187 60 485 229 683
388 l75 60 122 0 122 1 -32 -52z"
/>
</g>
</svg>
<span style={{ fontWeight: 800 }}>node-postgres</span>
</>
),
chat: {
link: 'https://discord.gg/2afXp5vUWm',
},
head: (
<>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="shortcut icon" href="/favicon.ico" />
<meta
name="description"
content="node-postgres is a collection of node.js modules for interfacing with your PostgreSQL database."
/>
<meta name="og:title" content="node-postgres" />
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-100138145-1"></script>
<script
dangerouslySetInnerHTML={{
__html: `
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-100138145-1');
`,
}}
></script>
</>
),
}

1892
docs/yarn.lock Normal file

File diff suppressed because it is too large Load Diff

12
lerna.json Normal file
View File

@ -0,0 +1,12 @@
{
"packages": ["packages/*"],
"npmClient": "yarn",
"useWorkspaces": true,
"version": "independent",
"command": {
"version": {
"allowBranch": "master"
}
},
"ignoreChanges": ["**/*.md", "**/test/**"]
}

View File

@ -1,419 +0,0 @@
'use strict'
/**
* Copyright (c) 2010-2017 Brian Carlson (brian.m.carlson@gmail.com)
* All rights reserved.
*
* This source code is licensed under the MIT license found in the
* README.md file in the root directory of this source tree.
*/
var EventEmitter = require('events').EventEmitter
var util = require('util')
var utils = require('./utils')
var pgPass = require('pgpass')
var TypeOverrides = require('./type-overrides')
var ConnectionParameters = require('./connection-parameters')
var Query = require('./query')
var defaults = require('./defaults')
var Connection = require('./connection')
var Client = function (config) {
EventEmitter.call(this)
this.connectionParameters = new ConnectionParameters(config)
this.user = this.connectionParameters.user
this.database = this.connectionParameters.database
this.port = this.connectionParameters.port
this.host = this.connectionParameters.host
this.password = this.connectionParameters.password
this.replication = this.connectionParameters.replication
var c = config || {}
this._types = new TypeOverrides(c.types)
this._ending = false
this._connecting = false
this._connected = false
this._connectionError = false
this.connection = c.connection || new Connection({
stream: c.stream,
ssl: this.connectionParameters.ssl,
keepAlive: c.keepAlive || false,
encoding: this.connectionParameters.client_encoding || 'utf8'
})
this.queryQueue = []
this.binary = c.binary || defaults.binary
this.processID = null
this.secretKey = null
this.ssl = this.connectionParameters.ssl || false
}
util.inherits(Client, EventEmitter)
Client.prototype.connect = function (callback) {
var self = this
var con = this.connection
if (this._connecting || this._connected) {
const err = new Error('Client has already been connected. You cannot reuse a client.')
if (callback) {
callback(err)
return undefined
}
return Promise.reject(err)
}
this._connecting = true
if (this.host && this.host.indexOf('/') === 0) {
con.connect(this.host + '/.s.PGSQL.' + this.port)
} else {
con.connect(this.port, this.host)
}
// once connection is established send startup message
con.on('connect', function () {
if (self.ssl) {
con.requestSsl()
} else {
con.startup(self.getStartupConf())
}
})
con.on('sslconnect', function () {
con.startup(self.getStartupConf())
})
function checkPgPass (cb) {
return function (msg) {
if (self.password !== null) {
cb(msg)
} else {
pgPass(self.connectionParameters, function (pass) {
if (undefined !== pass) {
self.connectionParameters.password = self.password = pass
}
cb(msg)
})
}
}
}
// password request handling
con.on('authenticationCleartextPassword', checkPgPass(function () {
con.password(self.password)
}))
// password request handling
con.on('authenticationMD5Password', checkPgPass(function (msg) {
var inner = utils.md5(self.password + self.user)
var outer = utils.md5(Buffer.concat([Buffer.from(inner), msg.salt]))
var md5password = 'md5' + outer
con.password(md5password)
}))
con.once('backendKeyData', function (msg) {
self.processID = msg.processID
self.secretKey = msg.secretKey
})
const connectingErrorHandler = (err) => {
if (this._connectionError) {
return
}
this._connectionError = true
if (callback) {
return callback(err)
}
this.emit('error', err)
}
const connectedErrorHandler = (err) => {
if (this.activeQuery) {
var activeQuery = self.activeQuery
this.activeQuery = null
return activeQuery.handleError(err, con)
}
this.emit('error', err)
}
con.on('error', connectingErrorHandler)
// hook up query handling events to connection
// after the connection initially becomes ready for queries
con.once('readyForQuery', function () {
self._connecting = false
self._connected = true
self._attachListeners(con)
con.removeListener('error', connectingErrorHandler)
con.on('error', connectedErrorHandler)
// process possible callback argument to Client#connect
if (callback) {
callback(null, self)
// remove callback for proper error handling
// after the connect event
callback = null
}
self.emit('connect')
})
con.on('readyForQuery', function () {
var activeQuery = self.activeQuery
self.activeQuery = null
self.readyForQuery = true
if (activeQuery) {
activeQuery.handleReadyForQuery(con)
}
self._pulseQueryQueue()
})
con.once('end', () => {
if (this.activeQuery) {
var disconnectError = new Error('Connection terminated')
this.activeQuery.handleError(disconnectError, con)
this.activeQuery = null
}
if (!this._ending) {
// if the connection is ended without us calling .end()
// on this client then we have an unexpected disconnection
// treat this as an error unless we've already emitted an error
// during connection.
const error = new Error('Connection terminated unexpectedly')
if (this._connecting && !this._connectionError) {
if (callback) {
callback(error)
} else {
this.emit('error', error)
}
} else if (!this._connectionError) {
this.emit('error', error)
}
}
this.emit('end')
})
con.on('notice', function (msg) {
self.emit('notice', msg)
})
if (!callback) {
return new global.Promise((resolve, reject) => {
this.once('error', reject)
this.once('connect', () => {
this.removeListener('error', reject)
resolve()
})
})
}
}
Client.prototype._attachListeners = function (con) {
const self = this
// delegate rowDescription to active query
con.on('rowDescription', function (msg) {
self.activeQuery.handleRowDescription(msg)
})
// delegate dataRow to active query
con.on('dataRow', function (msg) {
self.activeQuery.handleDataRow(msg)
})
// delegate portalSuspended to active query
con.on('portalSuspended', function (msg) {
self.activeQuery.handlePortalSuspended(con)
})
// deletagate emptyQuery to active query
con.on('emptyQuery', function (msg) {
self.activeQuery.handleEmptyQuery(con)
})
// delegate commandComplete to active query
con.on('commandComplete', function (msg) {
self.activeQuery.handleCommandComplete(msg, con)
})
// if a prepared statement has a name and properly parses
// we track that its already been executed so we don't parse
// it again on the same client
con.on('parseComplete', function (msg) {
if (self.activeQuery.name) {
con.parsedStatements[self.activeQuery.name] = true
}
})
con.on('copyInResponse', function (msg) {
self.activeQuery.handleCopyInResponse(self.connection)
})
con.on('copyData', function (msg) {
self.activeQuery.handleCopyData(msg, self.connection)
})
con.on('notification', function (msg) {
self.emit('notification', msg)
})
}
Client.prototype.getStartupConf = function () {
var params = this.connectionParameters
var data = {
user: params.user,
database: params.database
}
var appName = params.application_name || params.fallback_application_name
if (appName) {
data.application_name = appName
}
if (params.replication) {
data.replication = '' + params.replication
}
return data
}
Client.prototype.cancel = function (client, query) {
if (client.activeQuery === query) {
var con = this.connection
if (this.host && this.host.indexOf('/') === 0) {
con.connect(this.host + '/.s.PGSQL.' + this.port)
} else {
con.connect(this.port, this.host)
}
// once connection is established send cancel message
con.on('connect', function () {
con.cancel(client.processID, client.secretKey)
})
} else if (client.queryQueue.indexOf(query) !== -1) {
client.queryQueue.splice(client.queryQueue.indexOf(query), 1)
}
}
Client.prototype.setTypeParser = function (oid, format, parseFn) {
return this._types.setTypeParser(oid, format, parseFn)
}
Client.prototype.getTypeParser = function (oid, format) {
return this._types.getTypeParser(oid, format)
}
// Ported from PostgreSQL 9.2.4 source code in src/interfaces/libpq/fe-exec.c
Client.prototype.escapeIdentifier = function (str) {
var escaped = '"'
for (var i = 0; i < str.length; i++) {
var c = str[i]
if (c === '"') {
escaped += c + c
} else {
escaped += c
}
}
escaped += '"'
return escaped
}
// Ported from PostgreSQL 9.2.4 source code in src/interfaces/libpq/fe-exec.c
Client.prototype.escapeLiteral = function (str) {
var hasBackslash = false
var escaped = '\''
for (var i = 0; i < str.length; i++) {
var c = str[i]
if (c === '\'') {
escaped += c + c
} else if (c === '\\') {
escaped += c + c
hasBackslash = true
} else {
escaped += c
}
}
escaped += '\''
if (hasBackslash === true) {
escaped = ' E' + escaped
}
return escaped
}
Client.prototype._pulseQueryQueue = function () {
if (this.readyForQuery === true) {
this.activeQuery = this.queryQueue.shift()
if (this.activeQuery) {
this.readyForQuery = false
this.hasExecuted = true
this.activeQuery.submit(this.connection)
} else if (this.hasExecuted) {
this.activeQuery = null
this.emit('drain')
}
}
}
Client.prototype.query = function (config, values, callback) {
// can take in strings, config object or query object
var query
var result
if (typeof config.submit === 'function') {
result = query = config
if (typeof values === 'function') {
query.callback = query.callback || values
}
} else {
query = new Query(config, values, callback)
if (!query.callback) {
let resolveOut, rejectOut
result = new Promise((resolve, reject) => {
resolveOut = resolve
rejectOut = reject
})
query.callback = (err, res) => err ? rejectOut(err) : resolveOut(res)
}
}
if (this.binary && !query.binary) {
query.binary = true
}
if (query._result) {
query._result._getTypeParser = this._types.getTypeParser.bind(this._types)
}
this.queryQueue.push(query)
this._pulseQueryQueue()
return result
}
Client.prototype.end = function (cb) {
this._ending = true
if (this.activeQuery) {
// if we have an active query we need to force a disconnect
// on the socket - otherwise a hung query could block end forever
this.connection.stream.destroy(new Error('Connection terminated by user'))
return cb ? cb() : Promise.resolve()
}
if (cb) {
this.connection.end()
this.connection.once('end', cb)
} else {
return new global.Promise((resolve, reject) => {
this.connection.end()
this.connection.once('end', resolve)
})
}
}
// expose a Query constructor
Client.Query = Query
module.exports = Client

View File

@ -1,117 +0,0 @@
'use strict'
/**
* Copyright (c) 2010-2017 Brian Carlson (brian.m.carlson@gmail.com)
* All rights reserved.
*
* This source code is licensed under the MIT license found in the
* README.md file in the root directory of this source tree.
*/
var dns = require('dns')
var defaults = require('./defaults')
var parse = require('pg-connection-string').parse // parses a connection string
var val = function (key, config, envVar) {
if (envVar === undefined) {
envVar = process.env[ 'PG' + key.toUpperCase() ]
} else if (envVar === false) {
// do nothing ... use false
} else {
envVar = process.env[ envVar ]
}
return config[key] ||
envVar ||
defaults[key]
}
var useSsl = function () {
switch (process.env.PGSSLMODE) {
case 'disable':
return false
case 'prefer':
case 'require':
case 'verify-ca':
case 'verify-full':
return true
}
return defaults.ssl
}
var ConnectionParameters = function (config) {
// if a string is passed, it is a raw connection string so we parse it into a config
config = typeof config === 'string' ? parse(config) : config || {}
// if the config has a connectionString defined, parse IT into the config we use
// this will override other default values with what is stored in connectionString
if (config.connectionString) {
config = Object.assign({}, config, parse(config.connectionString))
}
this.user = val('user', config)
this.database = val('database', config)
this.port = parseInt(val('port', config), 10)
this.host = val('host', config)
this.password = val('password', config)
this.binary = val('binary', config)
this.ssl = typeof config.ssl === 'undefined' ? useSsl() : config.ssl
this.client_encoding = val('client_encoding', config)
this.replication = val('replication', config)
// a domain socket begins with '/'
this.isDomainSocket = (!(this.host || '').indexOf('/'))
this.application_name = val('application_name', config, 'PGAPPNAME')
this.fallback_application_name = val('fallback_application_name', config, false)
}
// Convert arg to a string, surround in single quotes, and escape single quotes and backslashes
var quoteParamValue = function (value) {
return "'" + ('' + value).replace(/\\/g, '\\\\').replace(/'/g, "\\'") + "'"
}
var add = function (params, config, paramName) {
var value = config[paramName]
if (value) {
params.push(paramName + '=' + quoteParamValue(value))
}
}
ConnectionParameters.prototype.getLibpqConnectionString = function (cb) {
var params = []
add(params, this, 'user')
add(params, this, 'password')
add(params, this, 'port')
add(params, this, 'application_name')
add(params, this, 'fallback_application_name')
var ssl = typeof this.ssl === 'object' ? this.ssl : {sslmode: this.ssl}
add(params, ssl, 'sslmode')
add(params, ssl, 'sslca')
add(params, ssl, 'sslkey')
add(params, ssl, 'sslcert')
if (this.database) {
params.push('dbname=' + quoteParamValue(this.database))
}
if (this.replication) {
params.push('replication=' + quoteParamValue(this.replication))
}
if (this.host) {
params.push('host=' + quoteParamValue(this.host))
}
if (this.isDomainSocket) {
return cb(null, params.join(' '))
}
if (this.client_encoding) {
params.push('client_encoding=' + quoteParamValue(this.client_encoding))
}
dns.lookup(this.host, function (err, address) {
if (err) return cb(err, null)
params.push('hostaddr=' + quoteParamValue(address))
return cb(null, params.join(' '))
})
}
module.exports = ConnectionParameters

View File

@ -1,647 +0,0 @@
'use strict'
/**
* Copyright (c) 2010-2017 Brian Carlson (brian.m.carlson@gmail.com)
* All rights reserved.
*
* This source code is licensed under the MIT license found in the
* README.md file in the root directory of this source tree.
*/
var net = require('net')
var EventEmitter = require('events').EventEmitter
var util = require('util')
var Writer = require('buffer-writer')
var Reader = require('packet-reader')
var TEXT_MODE = 0
var BINARY_MODE = 1
var Connection = function (config) {
EventEmitter.call(this)
config = config || {}
this.stream = config.stream || new net.Stream()
this._keepAlive = config.keepAlive
this.lastBuffer = false
this.lastOffset = 0
this.buffer = null
this.offset = null
this.encoding = config.encoding || 'utf8'
this.parsedStatements = {}
this.writer = new Writer()
this.ssl = config.ssl || false
this._ending = false
this._mode = TEXT_MODE
this._emitMessage = false
this._reader = new Reader({
headerSize: 1,
lengthPadding: -4
})
var self = this
this.on('newListener', function (eventName) {
if (eventName === 'message') {
self._emitMessage = true
}
})
}
util.inherits(Connection, EventEmitter)
Connection.prototype.connect = function (port, host) {
if (this.stream.readyState === 'closed') {
this.stream.connect(port, host)
} else if (this.stream.readyState === 'open') {
this.emit('connect')
}
var self = this
this.stream.on('connect', function () {
if (self._keepAlive) {
self.stream.setKeepAlive(true)
}
self.emit('connect')
})
this.stream.on('error', function (error) {
// don't raise ECONNRESET errors - they can & should be ignored
// during disconnect
if (self._ending && error.code === 'ECONNRESET') {
return
}
self.emit('error', error)
})
this.stream.on('close', function () {
self.emit('end')
})
if (!this.ssl) {
return this.attachListeners(this.stream)
}
this.stream.once('data', function (buffer) {
var responseCode = buffer.toString('utf8')
if (responseCode !== 'S') {
return self.emit('error', new Error('The server does not support SSL connections'))
}
var tls = require('tls')
self.stream = tls.connect({
socket: self.stream,
servername: host,
rejectUnauthorized: self.ssl.rejectUnauthorized,
ca: self.ssl.ca,
pfx: self.ssl.pfx,
key: self.ssl.key,
passphrase: self.ssl.passphrase,
cert: self.ssl.cert,
NPNProtocols: self.ssl.NPNProtocols
})
self.attachListeners(self.stream)
self.emit('sslconnect')
self.stream.on('error', function (error) {
self.emit('error', error)
})
})
}
Connection.prototype.attachListeners = function (stream) {
var self = this
stream.on('data', function (buff) {
self._reader.addChunk(buff)
var packet = self._reader.read()
while (packet) {
var msg = self.parseMessage(packet)
if (self._emitMessage) {
self.emit('message', msg)
}
self.emit(msg.name, msg)
packet = self._reader.read()
}
})
stream.on('end', function () {
self.emit('end')
})
}
Connection.prototype.requestSsl = function () {
var bodyBuffer = this.writer
.addInt16(0x04D2)
.addInt16(0x162F).flush()
var length = bodyBuffer.length + 4
var buffer = new Writer()
.addInt32(length)
.add(bodyBuffer)
.join()
this.stream.write(buffer)
}
Connection.prototype.startup = function (config) {
var writer = this.writer
.addInt16(3)
.addInt16(0)
Object.keys(config).forEach(function (key) {
var val = config[key]
writer.addCString(key).addCString(val)
})
writer.addCString('client_encoding').addCString("'utf-8'")
var bodyBuffer = writer.addCString('').flush()
// this message is sent without a code
var length = bodyBuffer.length + 4
var buffer = new Writer()
.addInt32(length)
.add(bodyBuffer)
.join()
this.stream.write(buffer)
}
Connection.prototype.cancel = function (processID, secretKey) {
var bodyBuffer = this.writer
.addInt16(1234)
.addInt16(5678)
.addInt32(processID)
.addInt32(secretKey)
.flush()
var length = bodyBuffer.length + 4
var buffer = new Writer()
.addInt32(length)
.add(bodyBuffer)
.join()
this.stream.write(buffer)
}
Connection.prototype.password = function (password) {
// 0x70 = 'p'
this._send(0x70, this.writer.addCString(password))
}
Connection.prototype._send = function (code, more) {
if (!this.stream.writable) {
return false
}
if (more === true) {
this.writer.addHeader(code)
} else {
return this.stream.write(this.writer.flush(code))
}
}
Connection.prototype.query = function (text) {
// 0x51 = Q
this.stream.write(this.writer.addCString(text).flush(0x51))
}
// send parse message
// "more" === true to buffer the message until flush() is called
Connection.prototype.parse = function (query, more) {
// expect something like this:
// { name: 'queryName',
// text: 'select * from blah',
// types: ['int8', 'bool'] }
// normalize missing query names to allow for null
query.name = query.name || ''
if (query.name.length > 63) {
console.error('Warning! Postgres only supports 63 characters for query names.')
console.error('You supplied', query.name, '(', query.name.length, ')')
console.error('This can cause conflicts and silent errors executing queries')
}
// normalize null type array
query.types = query.types || []
var len = query.types.length
var buffer = this.writer
.addCString(query.name) // name of query
.addCString(query.text) // actual query text
.addInt16(len)
for (var i = 0; i < len; i++) {
buffer.addInt32(query.types[i])
}
var code = 0x50
this._send(code, more)
}
// send bind message
// "more" === true to buffer the message until flush() is called
Connection.prototype.bind = function (config, more) {
// normalize config
config = config || {}
config.portal = config.portal || ''
config.statement = config.statement || ''
config.binary = config.binary || false
var values = config.values || []
var len = values.length
var useBinary = false
for (var j = 0; j < len; j++) { useBinary |= values[j] instanceof Buffer }
var buffer = this.writer
.addCString(config.portal)
.addCString(config.statement)
if (!useBinary) { buffer.addInt16(0) } else {
buffer.addInt16(len)
for (j = 0; j < len; j++) { buffer.addInt16(values[j] instanceof Buffer) }
}
buffer.addInt16(len)
for (var i = 0; i < len; i++) {
var val = values[i]
if (val === null || typeof val === 'undefined') {
buffer.addInt32(-1)
} else if (val instanceof Buffer) {
buffer.addInt32(val.length)
buffer.add(val)
} else {
buffer.addInt32(Buffer.byteLength(val))
buffer.addString(val)
}
}
if (config.binary) {
buffer.addInt16(1) // format codes to use binary
buffer.addInt16(1)
} else {
buffer.addInt16(0) // format codes to use text
}
// 0x42 = 'B'
this._send(0x42, more)
}
// send execute message
// "more" === true to buffer the message until flush() is called
Connection.prototype.execute = function (config, more) {
config = config || {}
config.portal = config.portal || ''
config.rows = config.rows || ''
this.writer
.addCString(config.portal)
.addInt32(config.rows)
// 0x45 = 'E'
this._send(0x45, more)
}
var emptyBuffer = Buffer.alloc(0)
Connection.prototype.flush = function () {
// 0x48 = 'H'
this.writer.add(emptyBuffer)
this._send(0x48)
}
Connection.prototype.sync = function () {
// clear out any pending data in the writer
this.writer.flush(0)
this.writer.add(emptyBuffer)
this._ending = true
this._send(0x53)
}
const END_BUFFER = Buffer.from([0x58, 0x00, 0x00, 0x00, 0x04])
Connection.prototype.end = function () {
// 0x58 = 'X'
this.writer.add(emptyBuffer)
this._ending = true
return this.stream.write(END_BUFFER)
}
Connection.prototype.close = function (msg, more) {
this.writer.addCString(msg.type + (msg.name || ''))
this._send(0x43, more)
}
Connection.prototype.describe = function (msg, more) {
this.writer.addCString(msg.type + (msg.name || ''))
this._send(0x44, more)
}
Connection.prototype.sendCopyFromChunk = function (chunk) {
this.stream.write(this.writer.add(chunk).flush(0x64))
}
Connection.prototype.endCopyFrom = function () {
this.stream.write(this.writer.add(emptyBuffer).flush(0x63))
}
Connection.prototype.sendCopyFail = function (msg) {
// this.stream.write(this.writer.add(emptyBuffer).flush(0x66));
this.writer.addCString(msg)
this._send(0x66)
}
var Message = function (name, length) {
this.name = name
this.length = length
}
Connection.prototype.parseMessage = function (buffer) {
this.offset = 0
var length = buffer.length + 4
switch (this._reader.header) {
case 0x52: // R
return this.parseR(buffer, length)
case 0x53: // S
return this.parseS(buffer, length)
case 0x4b: // K
return this.parseK(buffer, length)
case 0x43: // C
return this.parseC(buffer, length)
case 0x5a: // Z
return this.parseZ(buffer, length)
case 0x54: // T
return this.parseT(buffer, length)
case 0x44: // D
return this.parseD(buffer, length)
case 0x45: // E
return this.parseE(buffer, length)
case 0x4e: // N
return this.parseN(buffer, length)
case 0x31: // 1
return new Message('parseComplete', length)
case 0x32: // 2
return new Message('bindComplete', length)
case 0x33: // 3
return new Message('closeComplete', length)
case 0x41: // A
return this.parseA(buffer, length)
case 0x6e: // n
return new Message('noData', length)
case 0x49: // I
return new Message('emptyQuery', length)
case 0x73: // s
return new Message('portalSuspended', length)
case 0x47: // G
return this.parseG(buffer, length)
case 0x48: // H
return this.parseH(buffer, length)
case 0x57: // W
return new Message('replicationStart', length)
case 0x63: // c
return new Message('copyDone', length)
case 0x64: // d
return this.parsed(buffer, length)
}
}
Connection.prototype.parseR = function (buffer, length) {
var code = 0
var msg = new Message('authenticationOk', length)
if (msg.length === 8) {
code = this.parseInt32(buffer)
if (code === 3) {
msg.name = 'authenticationCleartextPassword'
}
return msg
}
if (msg.length === 12) {
code = this.parseInt32(buffer)
if (code === 5) { // md5 required
msg.name = 'authenticationMD5Password'
msg.salt = Buffer.alloc(4)
buffer.copy(msg.salt, 0, this.offset, this.offset + 4)
this.offset += 4
return msg
}
}
throw new Error('Unknown authenticationOk message type' + util.inspect(msg))
}
Connection.prototype.parseS = function (buffer, length) {
var msg = new Message('parameterStatus', length)
msg.parameterName = this.parseCString(buffer)
msg.parameterValue = this.parseCString(buffer)
return msg
}
Connection.prototype.parseK = function (buffer, length) {
var msg = new Message('backendKeyData', length)
msg.processID = this.parseInt32(buffer)
msg.secretKey = this.parseInt32(buffer)
return msg
}
Connection.prototype.parseC = function (buffer, length) {
var msg = new Message('commandComplete', length)
msg.text = this.parseCString(buffer)
return msg
}
Connection.prototype.parseZ = function (buffer, length) {
var msg = new Message('readyForQuery', length)
msg.name = 'readyForQuery'
msg.status = this.readString(buffer, 1)
return msg
}
var ROW_DESCRIPTION = 'rowDescription'
Connection.prototype.parseT = function (buffer, length) {
var msg = new Message(ROW_DESCRIPTION, length)
msg.fieldCount = this.parseInt16(buffer)
var fields = []
for (var i = 0; i < msg.fieldCount; i++) {
fields.push(this.parseField(buffer))
}
msg.fields = fields
return msg
}
var Field = function () {
this.name = null
this.tableID = null
this.columnID = null
this.dataTypeID = null
this.dataTypeSize = null
this.dataTypeModifier = null
this.format = null
}
var FORMAT_TEXT = 'text'
var FORMAT_BINARY = 'binary'
Connection.prototype.parseField = function (buffer) {
var field = new Field()
field.name = this.parseCString(buffer)
field.tableID = this.parseInt32(buffer)
field.columnID = this.parseInt16(buffer)
field.dataTypeID = this.parseInt32(buffer)
field.dataTypeSize = this.parseInt16(buffer)
field.dataTypeModifier = this.parseInt32(buffer)
if (this.parseInt16(buffer) === TEXT_MODE) {
this._mode = TEXT_MODE
field.format = FORMAT_TEXT
} else {
this._mode = BINARY_MODE
field.format = FORMAT_BINARY
}
return field
}
var DATA_ROW = 'dataRow'
var DataRowMessage = function (length, fieldCount) {
this.name = DATA_ROW
this.length = length
this.fieldCount = fieldCount
this.fields = []
}
// extremely hot-path code
Connection.prototype.parseD = function (buffer, length) {
var fieldCount = this.parseInt16(buffer)
var msg = new DataRowMessage(length, fieldCount)
for (var i = 0; i < fieldCount; i++) {
msg.fields.push(this._readValue(buffer))
}
return msg
}
// extremely hot-path code
Connection.prototype._readValue = function (buffer) {
var length = this.parseInt32(buffer)
if (length === -1) return null
if (this._mode === TEXT_MODE) {
return this.readString(buffer, length)
}
return this.readBytes(buffer, length)
}
// parses error
Connection.prototype.parseE = function (buffer, length) {
var fields = {}
var msg, item
var input = new Message('error', length)
var fieldType = this.readString(buffer, 1)
while (fieldType !== '\0') {
fields[fieldType] = this.parseCString(buffer)
fieldType = this.readString(buffer, 1)
}
if (input.name === 'error') {
// the msg is an Error instance
msg = new Error(fields.M)
for (item in input) {
// copy input properties to the error
if (input.hasOwnProperty(item)) {
msg[item] = input[item]
}
}
} else {
// the msg is an object literal
msg = input
msg.message = fields.M
}
msg.severity = fields.S
msg.code = fields.C
msg.detail = fields.D
msg.hint = fields.H
msg.position = fields.P
msg.internalPosition = fields.p
msg.internalQuery = fields.q
msg.where = fields.W
msg.schema = fields.s
msg.table = fields.t
msg.column = fields.c
msg.dataType = fields.d
msg.constraint = fields.n
msg.file = fields.F
msg.line = fields.L
msg.routine = fields.R
return msg
}
// same thing, different name
Connection.prototype.parseN = function (buffer, length) {
var msg = this.parseE(buffer, length)
msg.name = 'notice'
return msg
}
Connection.prototype.parseA = function (buffer, length) {
var msg = new Message('notification', length)
msg.processId = this.parseInt32(buffer)
msg.channel = this.parseCString(buffer)
msg.payload = this.parseCString(buffer)
return msg
}
Connection.prototype.parseG = function (buffer, length) {
var msg = new Message('copyInResponse', length)
return this.parseGH(buffer, msg)
}
Connection.prototype.parseH = function (buffer, length) {
var msg = new Message('copyOutResponse', length)
return this.parseGH(buffer, msg)
}
Connection.prototype.parseGH = function (buffer, msg) {
var isBinary = buffer[this.offset] !== 0
this.offset++
msg.binary = isBinary
var columnCount = this.parseInt16(buffer)
msg.columnTypes = []
for (var i = 0; i < columnCount; i++) {
msg.columnTypes.push(this.parseInt16(buffer))
}
return msg
}
Connection.prototype.parsed = function (buffer, length) {
var msg = new Message('copyData', length)
msg.chunk = this.readBytes(buffer, msg.length - 4)
return msg
}
Connection.prototype.parseInt32 = function (buffer) {
var value = buffer.readInt32BE(this.offset, true)
this.offset += 4
return value
}
Connection.prototype.parseInt16 = function (buffer) {
var value = buffer.readInt16BE(this.offset, true)
this.offset += 2
return value
}
Connection.prototype.readString = function (buffer, length) {
return buffer.toString(this.encoding, this.offset, (this.offset += length))
}
Connection.prototype.readBytes = function (buffer, length) {
return buffer.slice(this.offset, (this.offset += length))
}
Connection.prototype.parseCString = function (buffer) {
var start = this.offset
var end = buffer.indexOf(0, start)
this.offset = end + 1
return buffer.toString(this.encoding, start, end)
}
// end parsing methods
module.exports = Connection

View File

@ -1,57 +0,0 @@
'use strict'
/**
* Copyright (c) 2010-2017 Brian Carlson (brian.m.carlson@gmail.com)
* All rights reserved.
*
* This source code is licensed under the MIT license found in the
* README.md file in the root directory of this source tree.
*/
var util = require('util')
var Client = require('./client')
var defaults = require('./defaults')
var Connection = require('./connection')
var Pool = require('pg-pool')
const poolFactory = (Client) => {
var BoundPool = function (options) {
var config = Object.assign({ Client: Client }, options)
return new Pool(config)
}
util.inherits(BoundPool, Pool)
return BoundPool
}
var PG = function (clientConstructor) {
this.defaults = defaults
this.Client = clientConstructor
this.Query = this.Client.Query
this.Pool = poolFactory(this.Client)
this._pools = []
this.Connection = Connection
this.types = require('pg-types')
}
if (typeof process.env.NODE_PG_FORCE_NATIVE !== 'undefined') {
module.exports = new PG(require('./native'))
} else {
module.exports = new PG(Client)
// lazy require native module...the native module may not have installed
module.exports.__defineGetter__('native', function () {
delete module.exports.native
var native = null
try {
native = new PG(require('./native'))
} catch (err) {
if (err.code !== 'MODULE_NOT_FOUND') {
throw err
}
console.error(err.message)
}
module.exports.native = native
return native
})
}

View File

@ -1,226 +0,0 @@
'use strict'
/**
* Copyright (c) 2010-2017 Brian Carlson (brian.m.carlson@gmail.com)
* All rights reserved.
*
* This source code is licensed under the MIT license found in the
* README.md file in the root directory of this source tree.
*/
var Native = require('pg-native')
var TypeOverrides = require('../type-overrides')
var semver = require('semver')
var pkg = require('../../package.json')
var assert = require('assert')
var EventEmitter = require('events').EventEmitter
var util = require('util')
var ConnectionParameters = require('../connection-parameters')
var msg = 'Version >= ' + pkg.minNativeVersion + ' of pg-native required.'
assert(semver.gte(Native.version, pkg.minNativeVersion), msg)
var NativeQuery = require('./query')
var Client = module.exports = function (config) {
EventEmitter.call(this)
config = config || {}
this._types = new TypeOverrides(config.types)
this.native = new Native({
types: this._types
})
this._queryQueue = []
this._connected = false
this._connecting = false
// keep these on the object for legacy reasons
// for the time being. TODO: deprecate all this jazz
var cp = this.connectionParameters = new ConnectionParameters(config)
this.user = cp.user
this.password = cp.password
this.database = cp.database
this.host = cp.host
this.port = cp.port
// a hash to hold named queries
this.namedQueries = {}
}
Client.Query = NativeQuery
util.inherits(Client, EventEmitter)
// connect to the backend
// pass an optional callback to be called once connected
// or with an error if there was a connection error
// if no callback is passed and there is a connection error
// the client will emit an error event.
Client.prototype.connect = function (cb) {
var self = this
var onError = function (err) {
if (cb) return cb(err)
return self.emit('error', err)
}
var result
if (!cb) {
var resolveOut, rejectOut
cb = (err) => err ? rejectOut(err) : resolveOut()
result = new global.Promise(function (resolve, reject) {
resolveOut = resolve
rejectOut = reject
})
}
if (this._connecting) {
process.nextTick(() => cb(new Error('Client has already been connected. You cannot reuse a client.')))
return result
}
this._connecting = true
this.connectionParameters.getLibpqConnectionString(function (err, conString) {
if (err) return onError(err)
self.native.connect(conString, function (err) {
if (err) return onError(err)
// set internal states to connected
self._connected = true
// handle connection errors from the native layer
self.native.on('error', function (err) {
// error will be handled by active query
if (self._activeQuery && self._activeQuery.state !== 'end') {
return
}
self.emit('error', err)
})
self.native.on('notification', function (msg) {
self.emit('notification', {
channel: msg.relname,
payload: msg.extra
})
})
// signal we are connected now
self.emit('connect')
self._pulseQueryQueue(true)
// possibly call the optional callback
if (cb) cb()
})
})
return result
}
// send a query to the server
// this method is highly overloaded to take
// 1) string query, optional array of parameters, optional function callback
// 2) object query with {
// string query
// optional array values,
// optional function callback instead of as a separate parameter
// optional string name to name & cache the query plan
// optional string rowMode = 'array' for an array of results
// }
Client.prototype.query = function (config, values, callback) {
if (typeof config.submit === 'function') {
// accept query(new Query(...), (err, res) => { }) style
if (typeof values === 'function') {
config.callback = values
}
this._queryQueue.push(config)
this._pulseQueryQueue()
return config
}
var query = new NativeQuery(config, values, callback)
var result
if (!query.callback) {
let resolveOut, rejectOut
result = new Promise((resolve, reject) => {
resolveOut = resolve
rejectOut = reject
})
query.callback = (err, res) => err ? rejectOut(err) : resolveOut(res)
}
this._queryQueue.push(query)
this._pulseQueryQueue()
return result
}
// disconnect from the backend server
Client.prototype.end = function (cb) {
var self = this
if (!this._connected) {
this.once('connect', this.end.bind(this, cb))
}
var result
if (!cb) {
var resolve, reject
cb = (err) => err ? reject(err) : resolve()
result = new global.Promise(function (res, rej) {
resolve = res
reject = rej
})
}
this.native.end(function () {
// send an error to the active query
if (self._hasActiveQuery()) {
var msg = 'Connection terminated'
self._queryQueue.length = 0
self._activeQuery.handleError(new Error(msg))
}
self.emit('end')
if (cb) cb()
})
return result
}
Client.prototype._hasActiveQuery = function () {
return this._activeQuery && this._activeQuery.state !== 'error' && this._activeQuery.state !== 'end'
}
Client.prototype._pulseQueryQueue = function (initialConnection) {
if (!this._connected) {
return
}
if (this._hasActiveQuery()) {
return
}
var query = this._queryQueue.shift()
if (!query) {
if (!initialConnection) {
this.emit('drain')
}
return
}
this._activeQuery = query
query.submit(this)
var self = this
query.once('_done', function () {
self._pulseQueryQueue()
})
}
// attempt to cancel an in-progress query
Client.prototype.cancel = function (query) {
if (this._activeQuery === query) {
this.native.cancel(function () {})
} else if (this._queryQueue.indexOf(query) !== -1) {
this._queryQueue.splice(this._queryQueue.indexOf(query), 1)
}
}
Client.prototype.setTypeParser = function (oid, format, parseFn) {
return this._types.setTypeParser(oid, format, parseFn)
}
Client.prototype.getTypeParser = function (oid, format) {
return this._types.getTypeParser(oid, format)
}

View File

@ -1,232 +0,0 @@
'use strict'
/**
* Copyright (c) 2010-2017 Brian Carlson (brian.m.carlson@gmail.com)
* All rights reserved.
*
* This source code is licensed under the MIT license found in the
* README.md file in the root directory of this source tree.
*/
var EventEmitter = require('events').EventEmitter
var util = require('util')
var Result = require('./result')
var utils = require('./utils')
var Query = function (config, values, callback) {
// use of "new" optional
if (!(this instanceof Query)) { return new Query(config, values, callback) }
config = utils.normalizeQueryConfig(config, values, callback)
this.text = config.text
this.values = config.values
this.rows = config.rows
this.types = config.types
this.name = config.name
this.binary = config.binary
this.stream = config.stream
// use unique portal name each time
this.portal = config.portal || ''
this.callback = config.callback
this._rowMode = config.rowMode
if (process.domain && config.callback) {
this.callback = process.domain.bind(config.callback)
}
this._result = new Result(this._rowMode, this.types)
// potential for multiple results
this._results = this._result
this.isPreparedStatement = false
this._canceledDueToError = false
this._promise = null
EventEmitter.call(this)
}
util.inherits(Query, EventEmitter)
Query.prototype.requiresPreparation = function () {
// named queries must always be prepared
if (this.name) { return true }
// always prepare if there are max number of rows expected per
// portal execution
if (this.rows) { return true }
// don't prepare empty text queries
if (!this.text) { return false }
// prepare if there are values
if (!this.values) { return false }
return this.values.length > 0
}
Query.prototype._checkForMultirow = function () {
// if we already have a result with a command property
// then we've already executed one query in a multi-statement simple query
// turn our results into an array of results
if (this._result.command) {
if (!Array.isArray(this._results)) {
this._results = [this._result]
}
this._result = new Result(this._rowMode, this.types)
this._results.push(this._result)
}
}
// associates row metadata from the supplied
// message with this query object
// metadata used when parsing row results
Query.prototype.handleRowDescription = function (msg) {
this._checkForMultirow()
this._result.addFields(msg.fields)
this._accumulateRows = this.callback || !this.listeners('row').length
}
Query.prototype.handleDataRow = function (msg) {
var row
if (this._canceledDueToError) {
return
}
try {
row = this._result.parseRow(msg.fields)
} catch (err) {
this._canceledDueToError = err
return
}
this.emit('row', row, this._result)
if (this._accumulateRows) {
this._result.addRow(row)
}
}
Query.prototype.handleCommandComplete = function (msg, con) {
this._checkForMultirow()
this._result.addCommandComplete(msg)
// need to sync after each command complete of a prepared statement
if (this.isPreparedStatement) {
con.sync()
}
}
// if a named prepared statement is created with empty query text
// the backend will send an emptyQuery message but *not* a command complete message
// execution on the connection will hang until the backend receives a sync message
Query.prototype.handleEmptyQuery = function (con) {
if (this.isPreparedStatement) {
con.sync()
}
}
Query.prototype.handleReadyForQuery = function (con) {
if (this._canceledDueToError) {
return this.handleError(this._canceledDueToError, con)
}
if (this.callback) {
this.callback(null, this._results)
}
this.emit('end', this._results)
}
Query.prototype.handleError = function (err, connection) {
// need to sync after error during a prepared statement
if (this.isPreparedStatement) {
connection.sync()
}
if (this._canceledDueToError) {
err = this._canceledDueToError
this._canceledDueToError = false
}
// if callback supplied do not emit error event as uncaught error
// events will bubble up to node process
if (this.callback) {
return this.callback(err)
}
this.emit('error', err)
}
Query.prototype.submit = function (connection) {
if (typeof this.text !== 'string' && typeof this.name !== 'string') {
const err = new Error('A query must have either text or a name. Supplying neither is unsupported.')
connection.emit('error', err)
connection.emit('readyForQuery')
return
}
if (this.values && !Array.isArray(this.values)) {
const err = new Error('Query values must be an array')
connection.emit('error', err)
connection.emit('readyForQuery')
return
}
if (this.requiresPreparation()) {
this.prepare(connection)
} else {
connection.query(this.text)
}
}
Query.prototype.hasBeenParsed = function (connection) {
return this.name && connection.parsedStatements[this.name]
}
Query.prototype.handlePortalSuspended = function (connection) {
this._getRows(connection, this.rows)
}
Query.prototype._getRows = function (connection, rows) {
connection.execute({
portal: this.portalName,
rows: rows
}, true)
connection.flush()
}
Query.prototype.prepare = function (connection) {
var self = this
// prepared statements need sync to be called after each command
// complete or when an error is encountered
this.isPreparedStatement = true
// TODO refactor this poor encapsulation
if (!this.hasBeenParsed(connection)) {
connection.parse({
text: self.text,
name: self.name,
types: self.types
}, true)
}
if (self.values) {
self.values = self.values.map(utils.prepareValue)
}
// http://developer.postgresql.org/pgdocs/postgres/protocol-flow.html#PROTOCOL-FLOW-EXT-QUERY
connection.bind({
portal: self.portalName,
statement: self.name,
values: self.values,
binary: self.binary
}, true)
connection.describe({
type: 'P',
name: self.portalName || ''
}, true)
this._getRows(connection, this.rows)
}
Query.prototype.handleCopyInResponse = function (connection) {
if (this.stream) this.stream.startStreamingToConnection(connection)
else connection.sendCopyFail('No source stream defined')
}
Query.prototype.handleCopyData = function (msg, connection) {
var chunk = msg.chunk
if (this.stream) {
this.stream.handleChunk(chunk)
}
// if there are no stream (for example when copy to query was sent by
// query method instead of copyTo) error will be handled
// on copyOutResponse event, so silently ignore this error here
}
module.exports = Query

View File

@ -1,117 +0,0 @@
'use strict'
/**
* Copyright (c) 2010-2017 Brian Carlson (brian.m.carlson@gmail.com)
* All rights reserved.
*
* This source code is licensed under the MIT license found in the
* README.md file in the root directory of this source tree.
*/
var types = require('pg-types')
var escape = require('js-string-escape')
// result object returned from query
// in the 'end' event and also
// passed as second argument to provided callback
var Result = function (rowMode) {
this.command = null
this.rowCount = null
this.oid = null
this.rows = []
this.fields = []
this._parsers = []
this.RowCtor = null
this.rowAsArray = rowMode === 'array'
if (this.rowAsArray) {
this.parseRow = this._parseRowAsArray
}
}
var matchRegexp = /([A-Za-z]+) ?(\d+ )?(\d+)?/
// adds a command complete message
Result.prototype.addCommandComplete = function (msg) {
var match
if (msg.text) {
// pure javascript
match = matchRegexp.exec(msg.text)
} else {
// native bindings
match = matchRegexp.exec(msg.command)
}
if (match) {
this.command = match[1]
// match 3 will only be existing on insert commands
if (match[3]) {
// msg.value is from native bindings
this.rowCount = parseInt(match[3] || msg.value, 10)
this.oid = parseInt(match[2], 10)
} else {
this.rowCount = parseInt(match[2], 10)
}
}
}
Result.prototype._parseRowAsArray = function (rowData) {
var row = []
for (var i = 0, len = rowData.length; i < len; i++) {
var rawValue = rowData[i]
if (rawValue !== null) {
row.push(this._parsers[i](rawValue))
} else {
row.push(null)
}
}
return row
}
// rowData is an array of text or binary values
// this turns the row into a JavaScript object
Result.prototype.parseRow = function (rowData) {
return new this.RowCtor(this._parsers, rowData)
}
Result.prototype.addRow = function (row) {
this.rows.push(row)
}
var inlineParser = function (fieldName, i) {
return "\nthis['" +
// fields containing single quotes will break
// the evaluated javascript unless they are escaped
// see https://github.com/brianc/node-postgres/issues/507
// Addendum: However, we need to make sure to replace all
// occurences of apostrophes, not just the first one.
// See https://github.com/brianc/node-postgres/issues/934
escape(fieldName) +
"'] = " +
'rowData[' + i + '] == null ? null : parsers[' + i + '](rowData[' + i + ']);'
}
Result.prototype.addFields = function (fieldDescriptions) {
// clears field definitions
// multiple query statements in 1 action can result in multiple sets
// of rowDescriptions...eg: 'select NOW(); select 1::int;'
// you need to reset the fields
if (this.fields.length) {
this.fields = []
this._parsers = []
}
var ctorBody = ''
for (var i = 0; i < fieldDescriptions.length; i++) {
var desc = fieldDescriptions[i]
this.fields.push(desc)
var parser = this._getTypeParser(desc.dataTypeID, desc.format || 'text')
this._parsers.push(parser)
// this is some craziness to compile the row result parsing
// results in ~60% speedup on large query result sets
ctorBody += inlineParser(desc.name, i)
}
if (!this.rowAsArray) {
this.RowCtor = Function('parsers', 'rowData', ctorBody)
}
}
Result.prototype._getTypeParser = types.getTypeParser
module.exports = Result

View File

@ -1,149 +0,0 @@
'use strict'
/**
* Copyright (c) 2010-2017 Brian Carlson (brian.m.carlson@gmail.com)
* All rights reserved.
*
* This source code is licensed under the MIT license found in the
* README.md file in the root directory of this source tree.
*/
const crypto = require('crypto')
const defaults = require('./defaults')
function escapeElement (elementRepresentation) {
var escaped = elementRepresentation
.replace(/\\/g, '\\\\')
.replace(/"/g, '\\"')
return '"' + escaped + '"'
}
// convert a JS array to a postgres array literal
// uses comma separator so won't work for types like box that use
// a different array separator.
function arrayString (val) {
var result = '{'
for (var i = 0; i < val.length; i++) {
if (i > 0) {
result = result + ','
}
if (val[i] === null || typeof val[i] === 'undefined') {
result = result + 'NULL'
} else if (Array.isArray(val[i])) {
result = result + arrayString(val[i])
} else if (val[i] instanceof Buffer) {
result += '\\\\x' + val[i].toString('hex')
} else {
result += escapeElement(prepareValue(val[i]))
}
}
result = result + '}'
return result
}
// converts values from javascript types
// to their 'raw' counterparts for use as a postgres parameter
// note: you can override this function to provide your own conversion mechanism
// for complex types, etc...
var prepareValue = function (val, seen) {
if (val instanceof Buffer) {
return val
}
if (val instanceof Date) {
if (defaults.parseInputDatesAsUTC) {
return dateToStringUTC(val)
} else {
return dateToString(val)
}
}
if (Array.isArray(val)) {
return arrayString(val)
}
if (val === null || typeof val === 'undefined') {
return null
}
if (typeof val === 'object') {
return prepareObject(val, seen)
}
return val.toString()
}
function prepareObject (val, seen) {
if (val && typeof val.toPostgres === 'function') {
seen = seen || []
if (seen.indexOf(val) !== -1) {
throw new Error('circular reference detected while preparing "' + val + '" for query')
}
seen.push(val)
return prepareValue(val.toPostgres(prepareValue), seen)
}
return JSON.stringify(val)
}
function pad (number, digits) {
number = '' + number
while (number.length < digits) { number = '0' + number }
return number
}
function dateToString (date) {
var offset = -date.getTimezoneOffset()
var ret = pad(date.getFullYear(), 4) + '-' +
pad(date.getMonth() + 1, 2) + '-' +
pad(date.getDate(), 2) + 'T' +
pad(date.getHours(), 2) + ':' +
pad(date.getMinutes(), 2) + ':' +
pad(date.getSeconds(), 2) + '.' +
pad(date.getMilliseconds(), 3)
if (offset < 0) {
ret += '-'
offset *= -1
} else { ret += '+' }
return ret + pad(Math.floor(offset / 60), 2) + ':' + pad(offset % 60, 2)
}
function dateToStringUTC (date) {
var ret = pad(date.getUTCFullYear(), 4) + '-' +
pad(date.getUTCMonth() + 1, 2) + '-' +
pad(date.getUTCDate(), 2) + 'T' +
pad(date.getUTCHours(), 2) + ':' +
pad(date.getUTCMinutes(), 2) + ':' +
pad(date.getUTCSeconds(), 2) + '.' +
pad(date.getUTCMilliseconds(), 3)
return ret + '+00:00'
}
function normalizeQueryConfig (config, values, callback) {
// can take in strings or config objects
config = (typeof (config) === 'string') ? { text: config } : config
if (values) {
if (typeof values === 'function') {
config.callback = values
} else {
config.values = values
}
}
if (callback) {
config.callback = callback
}
return config
}
const md5 = function (string) {
return crypto.createHash('md5').update(string, 'utf-8').digest('hex')
}
module.exports = {
prepareValue: function prepareValueWrapper (value) {
// this ensures that extra arguments do not get passed into prepareValue
// by accident, eg: from calling values.map(utils.prepareValue)
return prepareValue(value)
},
normalizeQueryConfig: normalizeQueryConfig,
md5: md5
}

View File

@ -1,49 +1,40 @@
{ {
"name": "pg", "name": "node-postgres",
"version": "7.2.0", "description": "node postgres monorepo",
"description": "PostgreSQL client - pure javascript & libpq with the same API", "main": "index.js",
"keywords": [ "private": true,
"postgres", "repository": "git@github.com:brianc/node-postgres.git",
"pg", "author": "Brian M. Carlson <brian.m.carlson@gmail.com>",
"libpq", "license": "MIT",
"postgre", "workspaces": [
"database", "packages/*"
"rdbms"
], ],
"homepage": "http://github.com/brianc/node-postgres", "scripts": {
"repository": { "test": "yarn lerna exec --concurrency 1 yarn test",
"type": "git", "build": "tsc --build",
"url": "git://github.com/brianc/node-postgres.git" "build:watch": "tsc --build --watch",
}, "docs:build": "cd docs && yarn build",
"author": "Brian Carlson <brian.m.carlson@gmail.com>", "docs:start": "cd docs && yarn start",
"main": "./lib", "pretest": "yarn build",
"dependencies": { "prepublish": "yarn build",
"buffer-writer": "1.0.1", "lint": "eslint --cache 'packages/**/*.{js,ts,tsx}'"
"packet-reader": "0.3.1",
"js-string-escape": "1.0.1",
"pg-connection-string": "0.1.3",
"pg-pool": "~2.0.3",
"pg-types": "~1.12.1",
"pgpass": "1.x",
"semver": "4.3.2"
}, },
"devDependencies": { "devDependencies": {
"async": "0.9.0", "@typescript-eslint/eslint-plugin": "^7.0.0",
"co": "4.6.0", "@typescript-eslint/parser": "^6.17.0",
"eslint": "4.2.0", "eslint": "^8.56.0",
"eslint-config-standard": "10.2.1", "eslint-config-prettier": "^10.1.2",
"eslint-plugin-import": "2.7.0", "eslint-plugin-node": "^11.1.0",
"eslint-plugin-node": "5.1.0", "eslint-plugin-prettier": "^5.1.2",
"eslint-plugin-promise": "3.5.0", "lerna": "^3.19.0",
"eslint-plugin-standard": "3.0.1", "prettier": "3.0.3",
"pg-copy-streams": "0.3.0" "typescript": "^4.0.3"
}, },
"minNativeVersion": "2.0.0", "prettier": {
"scripts": { "semi": false,
"test": "make test-all" "printWidth": 120,
}, "arrowParens": "always",
"license": "MIT", "trailingComma": "es5",
"engines": { "singleQuote": true
"node": ">= 4.5.0"
} }
} }

View File

@ -0,0 +1,8 @@
import * as esbuild from 'esbuild'
await esbuild.build({
entryPoints: ['./src/index.mjs'],
bundle: true,
outfile: './dist/esbuild-cloudflare.js',
conditions: ['import', 'workerd'],
})

View File

@ -0,0 +1,7 @@
import * as esbuild from 'esbuild'
await esbuild.build({
entryPoints: ['./src/index.mjs'],
bundle: true,
outfile: './dist/esbuild-empty.js',
})

View File

@ -0,0 +1,25 @@
{
"name": "pg-bundler-test",
"version": "0.0.2",
"description": "Test bundlers with pg-cloudflare, https://github.com/brianc/node-postgres/issues/3452",
"license": "MIT",
"private": true,
"type": "module",
"devDependencies": {
"@rollup/plugin-commonjs": "^28.0.3",
"@rollup/plugin-node-resolve": "^16.0.1",
"esbuild": "^0.25.5",
"pg-cloudflare": "^1.2.7",
"rollup": "^4.41.1",
"vite": "^6.3.5",
"webpack": "^5.99.9",
"webpack-cli": "^6.0.1"
},
"scripts": {
"test": "yarn webpack && yarn rollup && yarn vite && yarn esbuild",
"webpack": "webpack --config webpack-empty.config.mjs && webpack --config webpack-cloudflare.config.mjs",
"rollup": "rollup --config rollup-empty.config.mjs --failAfterWarnings && rollup --config rollup-cloudflare.config.mjs --failAfterWarnings",
"vite": "[ $(node --version | sed 's/v//' | cut -d'.' -f1) -ge 18 ] && vite build --config vite-empty.config.mjs && vite build --config vite-cloudflare.config.mjs || echo 'Skip Vite test'",
"esbuild": "node esbuild-empty.config.mjs && node esbuild-cloudflare.config.mjs"
}
}

View File

@ -0,0 +1,13 @@
import { defineConfig } from 'rollup'
import { nodeResolve } from '@rollup/plugin-node-resolve'
import commonjs from '@rollup/plugin-commonjs'
export default defineConfig({
input: './src/index.mjs',
output: {
file: 'dist/rollup-cloudflare.js',
format: 'es',
},
plugins: [nodeResolve({ exportConditions: ['import', 'workerd'], preferBuiltins: true }), commonjs()],
external: ['cloudflare:sockets'],
})

View File

@ -0,0 +1,12 @@
import { defineConfig } from 'rollup'
import { nodeResolve } from '@rollup/plugin-node-resolve'
import commonjs from '@rollup/plugin-commonjs'
export default defineConfig({
input: './src/index.mjs',
output: {
file: 'dist/rollup-empty.js',
format: 'es',
},
plugins: [nodeResolve(), commonjs()],
})

View File

@ -0,0 +1 @@
import 'pg-cloudflare'

View File

@ -0,0 +1,20 @@
import { defineConfig } from 'vite'
import commonjs from '@rollup/plugin-commonjs'
export default defineConfig({
build: {
emptyOutDir: false,
lib: {
entry: './src/index.mjs',
fileName: 'vite-cloudflare',
formats: ['es'],
},
rollupOptions: {
external: ['cloudflare:sockets'],
},
},
resolve: {
conditions: ['import', 'workerd'],
},
plugins: [commonjs()],
})

View File

@ -0,0 +1,12 @@
import { defineConfig } from 'vite'
export default defineConfig({
build: {
emptyOutDir: false,
lib: {
entry: './src/index.mjs',
fileName: 'vite-empty',
formats: ['es'],
},
},
})

View File

@ -0,0 +1,16 @@
import webpack from 'webpack'
export default {
mode: 'production',
entry: './src/index.mjs',
output: {
filename: 'webpack-cloudflare.js',
},
resolve: { conditionNames: ['import', 'workerd'] },
plugins: [
// ignore cloudflare:sockets imports
new webpack.IgnorePlugin({
resourceRegExp: /^cloudflare:sockets$/,
}),
],
}

View File

@ -0,0 +1,7 @@
export default {
mode: 'production',
entry: './src/index.mjs',
output: {
filename: 'webpack-empty.js',
},
}

View File

@ -0,0 +1,112 @@
# pg-cloudflare
`pg-cloudflare` makes it easier to take an existing package that relies on `tls` and `net`, and make it work in environments where only `connect()` is supported, such as Cloudflare Workers.
`pg-cloudflare` wraps `connect()`, the [TCP Socket API](https://github.com/wintercg/proposal-sockets-api) proposed within WinterCG, and implemented in [Cloudflare Workers](https://developers.cloudflare.com/workers/runtime-apis/tcp-sockets/), and exposes an interface with methods similar to what the `net` and `tls` modules in Node.js expose. (ex: `net.connect(path[, options][, callback])`). This minimizes the number of changes needed in order to make an existing package work across JavaScript runtimes.
## Installation
```
npm i --save-dev pg-cloudflare
```
The package uses conditional exports to support bundlers that don't know about
`cloudflare:sockets`, so the consumer code by default imports an empty file. To
enable the package, resolve to the `cloudflare` condition in your bundler's
config. For example:
- `webpack.config.js`
```js
export default {
...,
resolve: { conditionNames: [..., "workerd"] },
plugins: [
// ignore cloudflare:sockets imports
new webpack.IgnorePlugin({
resourceRegExp: /^cloudflare:sockets$/,
}),
],
}
```
- `vite.config.js`
> [!NOTE]
> If you are using the [Cloudflare Vite plugin](https://www.npmjs.com/package/@cloudflare/vite-plugin) then the following configuration is not necessary.
```js
export default defineConfig({
...,
resolve: {
conditions: [..., "workerd"],
},
build: {
...,
// don't try to bundle cloudflare:sockets
rollupOptions: {
external: [..., 'cloudflare:sockets'],
},
},
})
```
- `rollup.config.js`
```js
export default defineConfig({
...,
plugins: [..., nodeResolve({ exportConditions: [..., 'workerd'] })],
// don't try to bundle cloudflare:sockets
external: [..., 'cloudflare:sockets'],
})
```
- `esbuild.config.js`
```js
await esbuild.build({
...,
conditions: [..., 'workerd'],
})
```
The concrete examples can be found in `packages/pg-bundler-test`.
## How to use conditionally, in non-Node.js environments
As implemented in `pg` [here](https://github.com/brianc/node-postgres/commit/07553428e9c0eacf761a5d4541a3300ff7859578#diff-34588ad868ebcb232660aba7ee6a99d1e02f4bc93f73497d2688c3f074e60533R5-R13), a typical use case might look as follows, where in a Node.js environment the `net` module is used, while in a non-Node.js environment, where `net` is unavailable, `pg-cloudflare` is used instead, providing an equivalent interface:
```js
module.exports.getStream = function getStream(ssl = false) {
const net = require('net')
if (typeof net.Socket === 'function') {
return net.Socket()
}
const { CloudflareSocket } = require('pg-cloudflare')
return new CloudflareSocket(ssl)
}
```
## Node.js implementation of the Socket API proposal
If you're looking for a way to rely on `connect()` as the interface you use to interact with raw sockets, but need this interface to be available in a Node.js environment, [`@arrowood.dev/socket`](https://github.com/Ethan-Arrowood/socket) provides a Node.js implementation of the Socket API.
### license
The MIT License (MIT)
Copyright (c) 2023 Brian M. Carlson
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -0,0 +1,3 @@
import cf from '../dist/index.js'
export const CloudflareSocket = cf.CloudflareSocket

View File

@ -0,0 +1,38 @@
{
"name": "pg-cloudflare",
"version": "1.2.7",
"description": "A socket implementation that can run on Cloudflare Workers using native TCP connections.",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"license": "MIT",
"devDependencies": {
"ts-node": "^8.5.4",
"typescript": "^4.0.3"
},
"exports": {
".": {
"workerd": {
"import": "./esm/index.mjs",
"require": "./dist/index.js"
},
"default": "./dist/empty.js"
},
"./package.json": "./package.json"
},
"scripts": {
"build": "tsc",
"build:watch": "tsc --watch",
"prepublish": "yarn build",
"test": "echo e2e test in pg package"
},
"repository": {
"type": "git",
"url": "git://github.com/brianc/node-postgres.git",
"directory": "packages/pg-cloudflare"
},
"files": [
"/dist/*{js,ts,map}",
"/src",
"/esm"
]
}

View File

@ -0,0 +1,3 @@
// This is an empty module that is served up when outside of a workerd environment
// See the `exports` field in package.json
export default {}

View File

@ -0,0 +1,166 @@
import { SocketOptions, Socket, TlsOptions } from 'cloudflare:sockets'
import { EventEmitter } from 'events'
/**
* Wrapper around the Cloudflare built-in socket that can be used by the `Connection`.
*/
export class CloudflareSocket extends EventEmitter {
writable = false
destroyed = false
private _upgrading = false
private _upgraded = false
private _cfSocket: Socket | null = null
private _cfWriter: WritableStreamDefaultWriter | null = null
private _cfReader: ReadableStreamDefaultReader | null = null
constructor(readonly ssl: boolean) {
super()
}
setNoDelay() {
return this
}
setKeepAlive() {
return this
}
ref() {
return this
}
unref() {
return this
}
async connect(port: number, host: string, connectListener?: (...args: unknown[]) => void) {
try {
log('connecting')
if (connectListener) this.once('connect', connectListener)
const options: SocketOptions = this.ssl ? { secureTransport: 'starttls' } : {}
const mod = await import('cloudflare:sockets')
const connect = mod.connect
this._cfSocket = connect(`${host}:${port}`, options)
this._cfWriter = this._cfSocket.writable.getWriter()
this._addClosedHandler()
this._cfReader = this._cfSocket.readable.getReader()
if (this.ssl) {
this._listenOnce().catch((e) => this.emit('error', e))
} else {
this._listen().catch((e) => this.emit('error', e))
}
await this._cfWriter!.ready
log('socket ready')
this.writable = true
this.emit('connect')
return this
} catch (e) {
this.emit('error', e)
}
}
async _listen() {
// eslint-disable-next-line no-constant-condition
while (true) {
log('awaiting receive from CF socket')
const { done, value } = await this._cfReader!.read()
log('CF socket received:', done, value)
if (done) {
log('done')
break
}
this.emit('data', Buffer.from(value))
}
}
async _listenOnce() {
log('awaiting first receive from CF socket')
const { done, value } = await this._cfReader!.read()
log('First CF socket received:', done, value)
this.emit('data', Buffer.from(value))
}
write(
data: Uint8Array | string,
encoding: BufferEncoding = 'utf8',
callback: (...args: unknown[]) => void = () => {}
) {
if (data.length === 0) return callback()
if (typeof data === 'string') data = Buffer.from(data, encoding)
log('sending data direct:', data)
this._cfWriter!.write(data).then(
() => {
log('data sent')
callback()
},
(err) => {
log('send error', err)
callback(err)
}
)
return true
}
end(data = Buffer.alloc(0), encoding: BufferEncoding = 'utf8', callback: (...args: unknown[]) => void = () => {}) {
log('ending CF socket')
this.write(data, encoding, (err) => {
this._cfSocket!.close()
if (callback) callback(err)
})
return this
}
destroy(reason: string) {
log('destroying CF socket', reason)
this.destroyed = true
return this.end()
}
startTls(options: TlsOptions) {
if (this._upgraded) {
// Don't try to upgrade again.
this.emit('error', 'Cannot call `startTls()` more than once on a socket')
return
}
this._cfWriter!.releaseLock()
this._cfReader!.releaseLock()
this._upgrading = true
this._cfSocket = this._cfSocket!.startTls(options)
this._cfWriter = this._cfSocket.writable.getWriter()
this._cfReader = this._cfSocket.readable.getReader()
this._addClosedHandler()
this._listen().catch((e) => this.emit('error', e))
}
_addClosedHandler() {
this._cfSocket!.closed.then(() => {
if (!this._upgrading) {
log('CF socket closed')
this._cfSocket = null
this.emit('close')
} else {
this._upgrading = false
this._upgraded = true
}
}).catch((e) => this.emit('error', e))
}
}
const debug = false
function dump(data: unknown) {
if (data instanceof Uint8Array || data instanceof ArrayBuffer) {
const hex = Buffer.from(data).toString('hex')
const str = new TextDecoder().decode(data)
return `\n>>> STR: "${str.replace(/\n/g, '\\n')}"\n>>> HEX: ${hex}\n`
} else {
return data
}
}
function log(...args: unknown[]) {
debug && console.log(...args.map(dump))
}

25
packages/pg-cloudflare/src/types.d.ts vendored Normal file
View File

@ -0,0 +1,25 @@
declare module 'cloudflare:sockets' {
export class Socket {
public readonly readable: any
public readonly writable: any
public readonly closed: Promise<void>
public close(): Promise<void>
public startTls(options: TlsOptions): Socket
}
export type TlsOptions = {
expectedServerHostname?: string
}
export type SocketAddress = {
hostname: string
port: number
}
export type SocketOptions = {
secureTransport?: 'off' | 'on' | 'starttls'
allowHalfOpen?: boolean
}
export function connect(address: string | SocketAddress, options?: SocketOptions): Socket
}

View File

@ -0,0 +1,25 @@
{
"compilerOptions": {
"module": "node16",
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"target": "es2020",
"noImplicitAny": true,
"moduleResolution": "node16",
"sourceMap": true,
"outDir": "dist",
"incremental": true,
"baseUrl": ".",
"declaration": true,
"paths": {
"*": [
"node_modules/*",
"src/types/*"
]
}
},
"include": [
"src/**/*"
]
}

View File

@ -0,0 +1,2 @@
service_name: travis-pro
repo_token: 5F6dODinz9L9uFR6HatKmtsYDoV1A5S2N

View File

@ -0,0 +1,30 @@
# Logs
logs
*.log
# Runtime data
pids
*.pid
*.seed
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directory
# Deployed apps should consider commenting this line out:
# see https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git
node_modules
package-lock.json
# TypeScript output directory
dist

View File

@ -0,0 +1,4 @@
{
"extension": ["js", "ts"],
"require": "tsx"
}

View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014 Iced Development
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,105 @@
pg-connection-string
====================
[![NPM](https://nodei.co/npm/pg-connection-string.png?compact=true)](https://nodei.co/npm/pg-connection-string/)
Functions for dealing with a PostgresSQL connection string
`parse` method taken from [node-postgres](https://github.com/brianc/node-postgres.git)
Copyright (c) 2010-2014 Brian Carlson (brian.m.carlson@gmail.com)
MIT License
## Usage
```js
const parse = require('pg-connection-string').parse;
const config = parse('postgres://someuser:somepassword@somehost:381/somedatabase')
```
The resulting config contains a subset of the following properties:
* `user` - User with which to authenticate to the server
* `password` - Corresponding password
* `host` - Postgres server hostname or, for UNIX domain sockets, the socket filename
* `port` - port on which to connect
* `database` - Database name within the server
* `client_encoding` - string encoding the client will use
* `ssl`, either a boolean or an object with properties
* `rejectUnauthorized`
* `cert`
* `key`
* `ca`
* any other query parameters (for example, `application_name`) are preserved intact.
### ClientConfig Compatibility for TypeScript
The pg-connection-string `ConnectionOptions` interface is not compatible with the `ClientConfig` interface that [pg.Client](https://node-postgres.com/apis/client) expects. To remedy this, use the `parseIntoClientConfig` function instead of `parse`:
```ts
import { ClientConfig } from 'pg';
import { parseIntoClientConfig } from 'pg-connection-string';
const config: ClientConfig = parseIntoClientConfig('postgres://someuser:somepassword@somehost:381/somedatabase')
```
You can also use `toClientConfig` to convert an existing `ConnectionOptions` interface into a `ClientConfig` interface:
```ts
import { ClientConfig } from 'pg';
import { parse, toClientConfig } from 'pg-connection-string';
const config = parse('postgres://someuser:somepassword@somehost:381/somedatabase')
const clientConfig: ClientConfig = toClientConfig(config)
```
## Connection Strings
The short summary of acceptable URLs is:
* `socket:<path>?<query>` - UNIX domain socket
* `postgres://<user>:<password>@<host>:<port>/<database>?<query>` - TCP connection
But see below for more details.
### UNIX Domain Sockets
When user and password are not given, the socket path follows `socket:`, as in `socket:/var/run/pgsql`.
This form can be shortened to just a path: `/var/run/pgsql`.
When user and password are given, they are included in the typical URL positions, with an empty `host`, as in `socket://user:pass@/var/run/pgsql`.
Query parameters follow a `?` character, including the following special query parameters:
* `db=<database>` - sets the database name (urlencoded)
* `encoding=<encoding>` - sets the `client_encoding` property
### TCP Connections
TCP connections to the Postgres server are indicated with `pg:` or `postgres:` schemes (in fact, any scheme but `socket:` is accepted).
If username and password are included, they should be urlencoded.
The database name, however, should *not* be urlencoded.
Query parameters follow a `?` character, including the following special query parameters:
* `host=<host>` - sets `host` property, overriding the URL's host
* `encoding=<encoding>` - sets the `client_encoding` property
* `ssl=1`, `ssl=true`, `ssl=0`, `ssl=false` - sets `ssl` to true or false, accordingly
* `uselibpqcompat=true` - use libpq semantics
* `sslmode=<sslmode>` when `uselibpqcompat=true` is not set
* `sslmode=disable` - sets `ssl` to false
* `sslmode=no-verify` - sets `ssl` to `{ rejectUnauthorized: false }`
* `sslmode=prefer`, `sslmode=require`, `sslmode=verify-ca`, `sslmode=verify-full` - sets `ssl` to true
* `sslmode=<sslmode>` when `uselibpqcompat=true`
* `sslmode=disable` - sets `ssl` to false
* `sslmode=prefer` - sets `ssl` to `{ rejectUnauthorized: false }`
* `sslmode=require` - sets `ssl` to `{ rejectUnauthorized: false }` unless `sslrootcert` is specified, in which case it behaves like `verify-ca`
* `sslmode=verify-ca` - sets `ssl` to `{ checkServerIdentity: no-op }` (verify CA, but not server identity). This verifies the presented certificate against the effective CA specified in sslrootcert.
* `sslmode=verify-full` - sets `ssl` to `{}` (verify CA and server identity)
* `sslcert=<filename>` - reads data from the given file and includes the result as `ssl.cert`
* `sslkey=<filename>` - reads data from the given file and includes the result as `ssl.key`
* `sslrootcert=<filename>` - reads data from the given file and includes the result as `ssl.ca`
A bare relative URL, such as `salesdata`, will indicate a database name while leaving other properties empty.
> [!CAUTION]
> Choosing an sslmode other than verify-full has serious security implications. Please read https://www.postgresql.org/docs/current/libpq-ssl.html#LIBPQ-SSL-SSLMODE-STATEMENTS to understand the trade-offs.

View File

@ -0,0 +1,8 @@
// ESM wrapper for pg-connection-string
import connectionString from '../index.js'
// Re-export the parse function
export default connectionString.parse
export const parse = connectionString.parse
export const toClientConfig = connectionString.toClientConfig
export const parseIntoClientConfig = connectionString.parseIntoClientConfig

View File

@ -0,0 +1,36 @@
import { ClientConfig } from 'pg'
export function parse(connectionString: string, options?: Options): ConnectionOptions
export interface Options {
// Use libpq semantics when interpreting the connection string
useLibpqCompat?: boolean
}
interface SSLConfig {
ca?: string
cert?: string | null
key?: string
rejectUnauthorized?: boolean
}
export interface ConnectionOptions {
host: string | null
password?: string
user?: string
port?: string | null
database: string | null | undefined
client_encoding?: string
ssl?: boolean | string | SSLConfig
application_name?: string
fallback_application_name?: string
options?: string
keepalives?: number
// We allow any other options to be passed through
[key: string]: unknown
}
export function toClientConfig(config: ConnectionOptions): ClientConfig
export function parseIntoClientConfig(connectionString: string): ClientConfig

View File

@ -0,0 +1,233 @@
'use strict'
const { emitWarning } = require('node:process')
//Parse method copied from https://github.com/brianc/node-postgres
//Copyright (c) 2010-2014 Brian Carlson (brian.m.carlson@gmail.com)
//MIT License
//parses a connection string
function parse(str, options = {}) {
//unix socket
if (str.charAt(0) === '/') {
const config = str.split(' ')
return { host: config[0], database: config[1] }
}
// Check for empty host in URL
const config = {}
let result
let dummyHost = false
if (/ |%[^a-f0-9]|%[a-f0-9][^a-f0-9]/i.test(str)) {
// Ensure spaces are encoded as %20
str = encodeURI(str).replace(/%25(\d\d)/g, '%$1')
}
try {
try {
result = new URL(str, 'postgres://base')
} catch (e) {
// The URL is invalid so try again with a dummy host
result = new URL(str.replace('@/', '@___DUMMY___/'), 'postgres://base')
dummyHost = true
}
} catch (err) {
// Remove the input from the error message to avoid leaking sensitive information
err.input && (err.input = '*****REDACTED*****')
throw err
}
// We'd like to use Object.fromEntries() here but Node.js 10 does not support it
for (const entry of result.searchParams.entries()) {
config[entry[0]] = entry[1]
}
config.user = config.user || decodeURIComponent(result.username)
config.password = config.password || decodeURIComponent(result.password)
if (result.protocol == 'socket:') {
config.host = decodeURI(result.pathname)
config.database = result.searchParams.get('db')
config.client_encoding = result.searchParams.get('encoding')
return config
}
const hostname = dummyHost ? '' : result.hostname
if (!config.host) {
// Only set the host if there is no equivalent query param.
config.host = decodeURIComponent(hostname)
} else if (hostname && /^%2f/i.test(hostname)) {
// Only prepend the hostname to the pathname if it is not a URL encoded Unix socket host.
result.pathname = hostname + result.pathname
}
if (!config.port) {
// Only set the port if there is no equivalent query param.
config.port = result.port
}
const pathname = result.pathname.slice(1) || null
config.database = pathname ? decodeURI(pathname) : null
if (config.ssl === 'true' || config.ssl === '1') {
config.ssl = true
}
if (config.ssl === '0') {
config.ssl = false
}
if (config.sslcert || config.sslkey || config.sslrootcert || config.sslmode) {
config.ssl = {}
}
// Only try to load fs if we expect to read from the disk
const fs = config.sslcert || config.sslkey || config.sslrootcert ? require('fs') : null
if (config.sslcert) {
config.ssl.cert = fs.readFileSync(config.sslcert).toString()
}
if (config.sslkey) {
config.ssl.key = fs.readFileSync(config.sslkey).toString()
}
if (config.sslrootcert) {
config.ssl.ca = fs.readFileSync(config.sslrootcert).toString()
}
if (options.useLibpqCompat && config.uselibpqcompat) {
throw new Error('Both useLibpqCompat and uselibpqcompat are set. Please use only one of them.')
}
if (config.uselibpqcompat === 'true' || options.useLibpqCompat) {
switch (config.sslmode) {
case 'disable': {
config.ssl = false
break
}
case 'prefer': {
config.ssl.rejectUnauthorized = false
break
}
case 'require': {
if (config.sslrootcert) {
// If a root CA is specified, behavior of `sslmode=require` will be the same as that of `verify-ca`
config.ssl.checkServerIdentity = function () {}
} else {
config.ssl.rejectUnauthorized = false
}
break
}
case 'verify-ca': {
if (!config.ssl.ca) {
throw new Error(
'SECURITY WARNING: Using sslmode=verify-ca requires specifying a CA with sslrootcert. If a public CA is used, verify-ca allows connections to a server that somebody else may have registered with the CA, making you vulnerable to Man-in-the-Middle attacks. Either specify a custom CA certificate with sslrootcert parameter or use sslmode=verify-full for proper security.'
)
}
config.ssl.checkServerIdentity = function () {}
break
}
case 'verify-full': {
break
}
}
} else {
switch (config.sslmode) {
case 'disable': {
config.ssl = false
break
}
case 'prefer':
case 'require':
case 'verify-ca':
case 'verify-full': {
if (config.sslmode !== 'verify-full') {
deprecatedSslModeWarning(config.sslmode)
}
break
}
case 'no-verify': {
config.ssl.rejectUnauthorized = false
break
}
}
}
return config
}
// convert pg-connection-string ssl config to a ClientConfig.ConnectionOptions
function toConnectionOptions(sslConfig) {
const connectionOptions = Object.entries(sslConfig).reduce((c, [key, value]) => {
// we explicitly check for undefined and null instead of `if (value)` because some
// options accept falsy values. Example: `ssl.rejectUnauthorized = false`
if (value !== undefined && value !== null) {
c[key] = value
}
return c
}, {})
return connectionOptions
}
// convert pg-connection-string config to a ClientConfig
function toClientConfig(config) {
const poolConfig = Object.entries(config).reduce((c, [key, value]) => {
if (key === 'ssl') {
const sslConfig = value
if (typeof sslConfig === 'boolean') {
c[key] = sslConfig
}
if (typeof sslConfig === 'object') {
c[key] = toConnectionOptions(sslConfig)
}
} else if (value !== undefined && value !== null) {
if (key === 'port') {
// when port is not specified, it is converted into an empty string
// we want to avoid NaN or empty string as a values in ClientConfig
if (value !== '') {
const v = parseInt(value, 10)
if (isNaN(v)) {
throw new Error(`Invalid ${key}: ${value}`)
}
c[key] = v
}
} else {
c[key] = value
}
}
return c
}, {})
return poolConfig
}
// parses a connection string into ClientConfig
function parseIntoClientConfig(str) {
return toClientConfig(parse(str))
}
function deprecatedSslModeWarning(sslmode) {
if (!deprecatedSslModeWarning.warned) {
deprecatedSslModeWarning.warned = true
emitWarning(`SECURITY WARNING: The SSL modes 'prefer', 'require', and 'verify-ca' are treated as aliases for 'verify-full'.
In the next major version (pg-connection-string v3.0.0 and pg v9.0.0), these modes will adopt standard libpq semantics, which have weaker security guarantees.
To prepare for this change:
- If you want the current behavior, explicitly use 'sslmode=verify-full'
- If you want libpq compatibility now, use 'uselibpqcompat=true&sslmode=${sslmode}'
See https://www.postgresql.org/docs/current/libpq-ssl.html for libpq SSL mode definitions.`)
}
}
module.exports = parse
parse.parse = parse
parse.toClientConfig = toClientConfig
parse.parseIntoClientConfig = parseIntoClientConfig

View File

@ -0,0 +1,51 @@
{
"name": "pg-connection-string",
"version": "2.9.1",
"description": "Functions for dealing with a PostgresSQL connection string",
"main": "./index.js",
"types": "./index.d.ts",
"exports": {
".": {
"types": "./index.d.ts",
"import": "./esm/index.mjs",
"require": "./index.js",
"default": "./index.js"
}
},
"scripts": {
"test": "nyc --reporter=lcov mocha && npm run check-coverage",
"check-coverage": "nyc check-coverage --statements 100 --branches 100 --lines 100 --functions 100"
},
"repository": {
"type": "git",
"url": "git://github.com/brianc/node-postgres.git",
"directory": "packages/pg-connection-string"
},
"keywords": [
"pg",
"connection",
"string",
"parse"
],
"author": "Blaine Bublitz <blaine@iceddev.com> (http://iceddev.com/)",
"license": "MIT",
"bugs": {
"url": "https://github.com/brianc/node-postgres/issues"
},
"homepage": "https://github.com/brianc/node-postgres/tree/master/packages/pg-connection-string",
"devDependencies": {
"@types/pg": "^8.12.0",
"chai": "^4.1.1",
"coveralls": "^3.0.4",
"istanbul": "^0.4.5",
"mocha": "^10.5.2",
"nyc": "^15",
"tsx": "^4.19.4",
"typescript": "^4.0.3"
},
"files": [
"index.js",
"index.d.ts",
"esm"
]
}

View File

@ -0,0 +1,125 @@
import chai from 'chai'
const expect = chai.expect
chai.should()
import { parse, toClientConfig, parseIntoClientConfig } from '../'
describe('toClientConfig', function () {
it('converts connection info', function () {
const config = parse('postgres://brian:pw@boom:381/lala')
const clientConfig = toClientConfig(config)
clientConfig.user?.should.equal('brian')
clientConfig.password?.should.equal('pw')
clientConfig.host?.should.equal('boom')
clientConfig.port?.should.equal(381)
clientConfig.database?.should.equal('lala')
})
it('converts query params', function () {
const config = parse(
'postgres:///?application_name=TheApp&fallback_application_name=TheAppFallback&client_encoding=utf8&options=-c geqo=off'
)
const clientConfig = toClientConfig(config)
clientConfig.application_name?.should.equal('TheApp')
clientConfig.fallback_application_name?.should.equal('TheAppFallback')
clientConfig.client_encoding?.should.equal('utf8')
clientConfig.options?.should.equal('-c geqo=off')
})
it('converts SSL boolean', function () {
const config = parse('pg:///?ssl=true')
const clientConfig = toClientConfig(config)
clientConfig.ssl?.should.equal(true)
})
it('converts sslmode=disable', function () {
const config = parse('pg:///?sslmode=disable')
const clientConfig = toClientConfig(config)
clientConfig.ssl?.should.equal(false)
})
it('converts sslmode=noverify', function () {
const config = parse('pg:///?sslmode=no-verify')
const clientConfig = toClientConfig(config)
clientConfig.ssl?.should.deep.equal({
rejectUnauthorized: false,
})
})
it('converts other sslmode options', function () {
const config = parse('pg:///?sslmode=verify-ca')
const clientConfig = toClientConfig(config)
clientConfig.ssl?.should.deep.equal({})
})
it('converts other sslmode options', function () {
const config = parse('pg:///?sslmode=verify-ca')
const clientConfig = toClientConfig(config)
clientConfig.ssl?.should.deep.equal({})
})
it('converts ssl cert options', function () {
const connectionString =
'pg:///?sslcert=' +
__dirname +
'/example.cert&sslkey=' +
__dirname +
'/example.key&sslrootcert=' +
__dirname +
'/example.ca'
const config = parse(connectionString)
const clientConfig = toClientConfig(config)
clientConfig.ssl?.should.deep.equal({
ca: 'example ca\n',
cert: 'example cert\n',
key: 'example key\n',
})
})
it('converts unix domain sockets', function () {
const config = parse('socket:/some path/?db=my[db]&encoding=utf8&client_encoding=bogus')
const clientConfig = toClientConfig(config)
clientConfig.host?.should.equal('/some path/')
clientConfig.database?.should.equal('my[db]', 'must to be escaped and unescaped through "my%5Bdb%5D"')
clientConfig.client_encoding?.should.equal('utf8')
})
it('handles invalid port', function () {
const config = parse('postgres://@boom:381/lala')
config.port = 'bogus'
expect(() => toClientConfig(config)).to.throw()
})
it('handles invalid sslconfig values', function () {
const config = parse('postgres://@boom/lala')
config.ssl = {}
config.ssl.cert = null
config.ssl.key = undefined
const clientConfig = toClientConfig(config)
clientConfig.host?.should.equal('boom')
clientConfig.database?.should.equal('lala')
clientConfig.ssl?.should.deep.equal({})
})
})
describe('parseIntoClientConfig', function () {
it('converts url', function () {
const clientConfig = parseIntoClientConfig('postgres://brian:pw@boom:381/lala')
clientConfig.user?.should.equal('brian')
clientConfig.password?.should.equal('pw')
clientConfig.host?.should.equal('boom')
clientConfig.port?.should.equal(381)
clientConfig.database?.should.equal('lala')
})
})

View File

@ -0,0 +1 @@
example ca

View File

@ -0,0 +1 @@
example cert

View File

@ -0,0 +1 @@
example key

View File

@ -0,0 +1,470 @@
import chai from 'chai'
const expect = chai.expect
chai.should()
import { parse } from '../'
describe('parse', function () {
it('using connection string in client constructor', function () {
const subject = parse('postgres://brian:pw@boom:381/lala')
subject.user?.should.equal('brian')
subject.password?.should.equal('pw')
subject.host?.should.equal('boom')
subject.port?.should.equal('381')
subject.database?.should.equal('lala')
})
it('escape spaces if present', function () {
const subject = parse('postgres://localhost/post gres')
subject.database?.should.equal('post gres')
})
it('do not double escape spaces', function () {
const subject = parse('postgres://localhost/post%20gres')
subject.database?.should.equal('post gres')
})
it('initializing with unix domain socket', function () {
const subject = parse('/const/run/')
subject.host?.should.equal('/const/run/')
})
it('initializing with unix domain socket and a specific database, the simple way', function () {
const subject = parse('/const/run/ mydb')
subject.host?.should.equal('/const/run/')
subject.database?.should.equal('mydb')
})
it('initializing with unix domain socket, the health way', function () {
const subject = parse('socket:/some path/?db=my[db]&encoding=utf8')
subject.host?.should.equal('/some path/')
subject.database?.should.equal('my[db]', 'must to be escaped and unescaped trough "my%5Bdb%5D"')
subject.client_encoding?.should.equal('utf8')
})
it('initializing with unix domain socket, the escaped health way', function () {
const subject = parse('socket:/some%20path/?db=my%2Bdb&encoding=utf8')
subject.host?.should.equal('/some path/')
subject.database?.should.equal('my+db')
subject.client_encoding?.should.equal('utf8')
})
it('initializing with unix domain socket, username and password', function () {
const subject = parse('socket://brian:pw@/const/run/?db=mydb')
subject.user?.should.equal('brian')
subject.password?.should.equal('pw')
subject.host?.should.equal('/const/run/')
subject.database?.should.equal('mydb')
})
it('password contains < and/or > characters', function () {
const sourceConfig = {
user: 'brian',
password: 'hello<ther>e',
host: 'localhost',
port: 5432,
database: 'postgres',
}
const connectionString =
'postgres://' +
sourceConfig.user +
':' +
sourceConfig.password +
'@' +
sourceConfig.host +
':' +
sourceConfig.port +
'/' +
sourceConfig.database
const subject = parse(connectionString)
subject.password?.should.equal(sourceConfig.password)
})
it('password contains colons', function () {
const sourceConfig = {
user: 'brian',
password: 'hello:pass:world',
host: 'localhost',
port: 5432,
database: 'postgres',
}
const connectionString =
'postgres://' +
sourceConfig.user +
':' +
sourceConfig.password +
'@' +
sourceConfig.host +
':' +
sourceConfig.port +
'/' +
sourceConfig.database
const subject = parse(connectionString)
subject.password?.should.equal(sourceConfig.password)
})
it('username or password contains weird characters', function () {
const strang = 'pg://my f%irst name:is&%awesome!@localhost:9000'
const subject = parse(strang)
subject.user?.should.equal('my f%irst name')
subject.password?.should.equal('is&%awesome!')
subject.host?.should.equal('localhost')
})
it('url is properly encoded', function () {
const encoded = 'pg://bi%25na%25%25ry%20:s%40f%23@localhost/%20u%2520rl'
const subject = parse(encoded)
subject.user?.should.equal('bi%na%%ry ')
subject.password?.should.equal('s@f#')
subject.host?.should.equal('localhost')
subject.database?.should.equal(' u%20rl')
})
it('relative url sets database', function () {
const relative = 'different_db_on_default_host'
const subject = parse(relative)
subject.database?.should.equal('different_db_on_default_host')
})
it('no pathname returns null database', function () {
const subject = parse('pg://myhost')
;(subject.database === null).should.equal(true)
})
it('pathname of "/" returns null database', function () {
const subject = parse('pg://myhost/')
subject.host?.should.equal('myhost')
;(subject.database === null).should.equal(true)
})
it('configuration parameter host', function () {
const subject = parse('pg://user:pass@/dbname?host=/unix/socket')
subject.user?.should.equal('user')
subject.password?.should.equal('pass')
subject.host?.should.equal('/unix/socket')
subject.database?.should.equal('dbname')
})
it('configuration parameter host overrides url host', function () {
const subject = parse('pg://user:pass@localhost/dbname?host=/unix/socket')
subject.database?.should.equal('dbname')
subject.host?.should.equal('/unix/socket')
})
it('url with encoded socket', function () {
const subject = parse('pg://user:pass@%2Funix%2Fsocket/dbname')
subject.user?.should.equal('user')
subject.password?.should.equal('pass')
subject.host?.should.equal('/unix/socket')
subject.database?.should.equal('dbname')
})
it('url with real host and an encoded db name', function () {
const subject = parse('pg://user:pass@localhost/%2Fdbname')
subject.user?.should.equal('user')
subject.password?.should.equal('pass')
subject.host?.should.equal('localhost')
subject.database?.should.equal('%2Fdbname')
})
it('configuration parameter host treats encoded host as part of the db name', function () {
const subject = parse('pg://user:pass@%2Funix%2Fsocket/dbname?host=localhost')
subject.user?.should.equal('user')
subject.password?.should.equal('pass')
subject.host?.should.equal('localhost')
subject.database?.should.equal('%2Funix%2Fsocket/dbname')
})
it('configuration parameter application_name', function () {
const connectionString = 'pg:///?application_name=TheApp'
const subject = parse(connectionString)
subject.application_name?.should.equal('TheApp')
})
it('configuration parameter fallback_application_name', function () {
const connectionString = 'pg:///?fallback_application_name=TheAppFallback'
const subject = parse(connectionString)
subject.fallback_application_name?.should.equal('TheAppFallback')
})
it('configuration parameter options', function () {
const connectionString = 'pg:///?options=-c geqo=off'
const subject = parse(connectionString)
subject.options?.should.equal('-c geqo=off')
})
it('configuration parameter ssl=true', function () {
const connectionString = 'pg:///?ssl=true'
const subject = parse(connectionString)
subject.ssl?.should.equal(true)
})
it('configuration parameter ssl=1', function () {
const connectionString = 'pg:///?ssl=1'
const subject = parse(connectionString)
subject.ssl?.should.equal(true)
})
it('configuration parameter ssl=0', function () {
const connectionString = 'pg:///?ssl=0'
const subject = parse(connectionString)
subject.ssl?.should.equal(false)
})
it('set ssl', function () {
const subject = parse('pg://myhost/db?ssl=1')
subject.ssl?.should.equal(true)
})
it('configuration parameter sslcert=/path/to/cert', function () {
const connectionString = 'pg:///?sslcert=' + __dirname + '/example.cert'
const subject = parse(connectionString)
subject.ssl?.should.eql({
cert: 'example cert\n',
})
})
it('configuration parameter sslkey=/path/to/key', function () {
const connectionString = 'pg:///?sslkey=' + __dirname + '/example.key'
const subject = parse(connectionString)
subject.ssl?.should.eql({
key: 'example key\n',
})
})
it('configuration parameter sslrootcert=/path/to/ca', function () {
const connectionString = 'pg:///?sslrootcert=' + __dirname + '/example.ca'
const subject = parse(connectionString)
subject.ssl?.should.eql({
ca: 'example ca\n',
})
})
it('configuration parameter sslmode=no-verify', function () {
const connectionString = 'pg:///?sslmode=no-verify'
const subject = parse(connectionString)
subject.ssl?.should.eql({
rejectUnauthorized: false,
})
})
it('configuration parameter sslmode=disable', function () {
const connectionString = 'pg:///?sslmode=disable'
const subject = parse(connectionString)
subject.ssl?.should.eql(false)
})
it('configuration parameter sslmode=prefer', function () {
const connectionString = 'pg:///?sslmode=prefer'
const subject = parse(connectionString)
subject.ssl?.should.eql({})
})
it('configuration parameter sslmode=require', function () {
const connectionString = 'pg:///?sslmode=require'
const subject = parse(connectionString)
subject.ssl?.should.eql({})
})
it('configuration parameter sslmode=verify-ca', function () {
const connectionString = 'pg:///?sslmode=verify-ca'
const subject = parse(connectionString)
subject.ssl?.should.eql({})
})
it('configuration parameter sslmode=verify-full', function () {
const connectionString = 'pg:///?sslmode=verify-full'
const subject = parse(connectionString)
subject.ssl?.should.eql({})
})
it('configuration parameter ssl=true and sslmode=require still work with sslrootcert=/path/to/ca', function () {
const connectionString = 'pg:///?ssl=true&sslrootcert=' + __dirname + '/example.ca&sslmode=require'
const subject = parse(connectionString)
subject.ssl?.should.eql({
ca: 'example ca\n',
})
})
it('configuration parameter sslmode=disable with uselibpqcompat query param', function () {
const connectionString = 'pg:///?sslmode=disable&uselibpqcompat=true'
const subject = parse(connectionString)
subject.ssl?.should.eql(false)
})
it('configuration parameter sslmode=prefer with uselibpqcompat query param', function () {
const connectionString = 'pg:///?sslmode=prefer&uselibpqcompat=true'
const subject = parse(connectionString)
subject.ssl?.should.eql({
rejectUnauthorized: false,
})
})
it('configuration parameter sslmode=require with uselibpqcompat query param', function () {
const connectionString = 'pg:///?sslmode=require&uselibpqcompat=true'
const subject = parse(connectionString)
subject.ssl?.should.eql({
rejectUnauthorized: false,
})
})
it('configuration parameter sslmode=verify-ca with uselibpqcompat query param', function () {
const connectionString = 'pg:///?sslmode=verify-ca&uselibpqcompat=true'
expect(function () {
parse(connectionString)
}).to.throw()
})
it('when throwing on invalid url does not print out the password in the error message', function () {
const host = 'localhost'
const port = 5432
const user = 'user'
const password = 'g#4624$@F$#v`'
const database = 'db'
const connectionString = `postgres://${user}:${password}@${host}:${port}/${database}`
expect(function () {
parse(connectionString)
}).to.throw()
try {
parse(connectionString)
} catch (err: unknown) {
expect(JSON.stringify(err)).to.not.include(password, 'Password should not be in the error message')
expect(JSON.stringify(err)).to.include('REDACTED', 'The thrown error should contain the redacted URL')
return
}
throw new Error('Expected an error to be thrown')
})
it('configuration parameter sslmode=verify-ca and sslrootcert with uselibpqcompat query param', function () {
const connectionString = 'pg:///?sslmode=verify-ca&uselibpqcompat=true&sslrootcert=' + __dirname + '/example.ca'
const subject = parse(connectionString)
subject.ssl?.should.have.property('checkServerIdentity').that.is.a('function')
// We prove above that the checkServerIdentity function is defined
//
// FIXME: remove this if we upgrade to TypeScript 5
// @ts-ignore
expect(subject.ssl.checkServerIdentity()).be.undefined
})
it('configuration parameter sslmode=verify-full with uselibpqcompat query param', function () {
const connectionString = 'pg:///?sslmode=verify-full&uselibpqcompat=true'
const subject = parse(connectionString)
subject.ssl?.should.eql({})
})
it('configuration parameter ssl=true and sslmode=require still work with sslrootcert=/path/to/ca with uselibpqcompat query param', function () {
const connectionString =
'pg:///?ssl=true&sslrootcert=' + __dirname + '/example.ca&sslmode=require&uselibpqcompat=true'
const subject = parse(connectionString)
subject.ssl?.should.have.property('ca', 'example ca\n')
subject.ssl?.should.have.property('checkServerIdentity').that.is.a('function')
// We prove above that the checkServerIdentity function is defined
//
// FIXME: remove this if we upgrade to TypeScript 5
// @ts-ignore
expect(subject.ssl?.checkServerIdentity()).be.undefined
})
it('configuration parameter sslmode=disable with useLibpqCompat option', function () {
const connectionString = 'pg:///?sslmode=disable'
const subject = parse(connectionString, { useLibpqCompat: true })
subject.ssl?.should.eql(false)
})
it('configuration parameter sslmode=prefer with useLibpqCompat option', function () {
const connectionString = 'pg:///?sslmode=prefer'
const subject = parse(connectionString, { useLibpqCompat: true })
subject.ssl?.should.eql({
rejectUnauthorized: false,
})
})
it('configuration parameter sslmode=require with useLibpqCompat option', function () {
const connectionString = 'pg:///?sslmode=require'
const subject = parse(connectionString, { useLibpqCompat: true })
subject.ssl?.should.eql({
rejectUnauthorized: false,
})
})
it('configuration parameter sslmode=verify-ca with useLibpqCompat option', function () {
const connectionString = 'pg:///?sslmode=verify-ca'
expect(function () {
parse(connectionString, { useLibpqCompat: true })
}).to.throw()
})
it('configuration parameter sslmode=verify-ca and sslrootcert with useLibpqCompat option', function () {
const connectionString = 'pg:///?sslmode=verify-ca&sslrootcert=' + __dirname + '/example.ca'
const subject = parse(connectionString, { useLibpqCompat: true })
subject.ssl?.should.have.property('checkServerIdentity').that.is.a('function')
// We prove above that the checkServerIdentity function is defined
//
// FIXME: remove this if we upgrade to TypeScript 5
// @ts-ignore
expect(subject.ssl?.checkServerIdentity()).be.undefined
})
it('configuration parameter sslmode=verify-full with useLibpqCompat option', function () {
const connectionString = 'pg:///?sslmode=verify-full'
const subject = parse(connectionString, { useLibpqCompat: true })
subject.ssl?.should.eql({})
})
it('configuration parameter ssl=true and sslmode=require still work with sslrootcert=/path/to/ca with useLibpqCompat option', function () {
const connectionString = 'pg:///?ssl=true&sslrootcert=' + __dirname + '/example.ca&sslmode=require'
const subject = parse(connectionString, { useLibpqCompat: true })
subject.ssl?.should.have.property('ca', 'example ca\n')
subject.ssl?.should.have.property('checkServerIdentity').that.is.a('function')
// We prove above that the checkServerIdentity function is defined
//
// FIXME: remove this if we upgrade to TypeScript 5
// @ts-ignore
expect(subject.ssl?.checkServerIdentity()).be.undefined
})
it('does not allow uselibpqcompat query parameter and useLibpqCompat option at the same time', function () {
const connectionString = 'pg:///?uselibpqcompat=true'
expect(function () {
parse(connectionString, { useLibpqCompat: true })
}).to.throw()
})
it('allow other params like max, ...', function () {
const subject = parse('pg://myhost/db?max=18&min=4')
subject.max?.should.equal('18')
subject.min?.should.equal('4')
})
it('configuration parameter keepalives', function () {
const connectionString = 'pg:///?keepalives=1'
const subject = parse(connectionString)
subject.keepalives?.should.equal('1')
})
it('unknown configuration parameter is passed into client', function () {
const connectionString = 'pg:///?ThereIsNoSuchPostgresParameter=1234'
const subject = parse(connectionString)
subject.ThereIsNoSuchPostgresParameter?.should.equal('1234')
})
it('do not override a config field with value from query string', function () {
const subject = parse('socket:/some path/?db=my[db]&encoding=utf8&client_encoding=bogus')
subject.host?.should.equal('/some path/')
subject.database?.should.equal('my[db]', 'must to be escaped and unescaped through "my%5Bdb%5D"')
subject.client_encoding?.should.equal('utf8')
})
it('return last value of repeated parameter', function () {
const connectionString = 'pg:///?keepalives=1&keepalives=0'
const subject = parse(connectionString)
subject.keepalives?.should.equal('0')
})
it('use the port specified in the query parameters', function () {
const connectionString = 'postgres:///?host=localhost&port=1234'
const subject = parse(connectionString)
subject.port?.should.equal('1234')
})
})

View File

@ -0,0 +1,19 @@
{
"compilerOptions": {
"module": "commonjs",
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"target": "es6",
"noImplicitAny": true,
"moduleResolution": "node",
"sourceMap": true,
"outDir": "dist",
"incremental": true,
"baseUrl": ".",
"declaration": true
},
"include": [
"test/**/*"
]
}

View File

@ -0,0 +1,37 @@
node-pg-cursor
==============
Use a PostgreSQL result cursor from node with an easy to use API.
### install
```sh
$ npm install pg-cursor
```
___note___: this depends on _either_ `npm install pg` or `npm install pg.js`, but you __must__ be using the pure JavaScript client. This will __not work__ with the native bindings.
### :star: [Documentation](https://node-postgres.com/apis/cursor) :star:
### license
The MIT License (MIT)
Copyright (c) 2013 Brian M. Carlson
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -0,0 +1,5 @@
// ESM wrapper for pg-cursor
import Cursor from '../index.js'
// Export as default only to match CJS module
export default Cursor

265
packages/pg-cursor/index.js Normal file
View File

@ -0,0 +1,265 @@
'use strict'
// note: can remove these deep requires when we bump min version of pg to 9.x
const Result = require('pg/lib/result.js')
const prepare = require('pg/lib/utils.js').prepareValue
const EventEmitter = require('events').EventEmitter
const util = require('util')
let nextUniqueID = 1 // concept borrowed from org.postgresql.core.v3.QueryExecutorImpl
class Cursor extends EventEmitter {
constructor(text, values, config) {
super()
this._conf = config || {}
this.text = text
this.values = values ? values.map(prepare) : null
this.connection = null
this._queue = []
this.state = 'initialized'
this._result = new Result(this._conf.rowMode, this._conf.types)
this._Promise = this._conf.Promise || global.Promise
this._cb = null
this._rows = null
this._portal = null
this._ifNoData = this._ifNoData.bind(this)
this._rowDescription = this._rowDescription.bind(this)
}
_ifNoData() {
this.state = 'idle'
this._shiftQueue()
if (this.connection) {
this.connection.removeListener('rowDescription', this._rowDescription)
}
}
_rowDescription() {
if (this.connection) {
this.connection.removeListener('noData', this._ifNoData)
}
}
submit(connection) {
this.state = 'submitted'
this.connection = connection
this._portal = 'C_' + nextUniqueID++
const con = connection
con.parse(
{
text: this.text,
},
true
)
con.bind(
{
portal: this._portal,
values: this.values,
},
true
)
con.describe(
{
type: 'P',
name: this._portal, // AWS Redshift requires a portal name
},
true
)
con.flush()
if (this._conf.types) {
this._result._getTypeParser = this._conf.types.getTypeParser
}
con.once('noData', this._ifNoData)
con.once('rowDescription', this._rowDescription)
}
_shiftQueue() {
if (this._queue.length) {
this._getRows.apply(this, this._queue.shift())
}
}
_closePortal() {
if (this.state === 'done') return
// because we opened a named portal to stream results
// we need to close the same named portal. Leaving a named portal
// open can lock tables for modification if inside a transaction.
// see https://github.com/brianc/node-pg-cursor/issues/56
this.connection.close({ type: 'P', name: this._portal })
// If we've received an error we already sent a sync message.
// do not send another sync as it triggers another readyForQuery message.
if (this.state !== 'error') {
this.connection.sync()
}
this.state = 'done'
}
handleRowDescription(msg) {
this._result.addFields(msg.fields)
this.state = 'idle'
this._shiftQueue()
}
handleDataRow(msg) {
const row = this._result.parseRow(msg.fields)
this.emit('row', row, this._result)
this._rows.push(row)
}
_sendRows() {
this.state = 'idle'
setImmediate(() => {
const cb = this._cb
// remove callback before calling it
// because likely a new one will be added
// within the call to this callback
this._cb = null
if (cb) {
this._result.rows = this._rows
cb(null, this._rows, this._result)
}
this._rows = []
})
}
handleCommandComplete(msg) {
this._result.addCommandComplete(msg)
this._closePortal()
}
handlePortalSuspended() {
this._sendRows()
}
handleReadyForQuery() {
this._sendRows()
this.state = 'done'
this.emit('end', this._result)
}
handleEmptyQuery() {
this.connection.sync()
}
handleError(msg) {
// If this cursor has already closed, don't try to handle the error.
if (this.state === 'done') return
// If we're in an initialized state we've never been submitted
// and don't have a connection instance reference yet.
// This can happen if you queue a stream and close the client before
// the client has submitted the stream. In this scenario we don't have
// a connection so there's nothing to unsubscribe from.
if (this.state !== 'initialized') {
this.connection.removeListener('noData', this._ifNoData)
this.connection.removeListener('rowDescription', this._rowDescription)
// call sync to trigger a readyForQuery
this.connection.sync()
}
this.state = 'error'
this._error = msg
// satisfy any waiting callback
if (this._cb) {
this._cb(msg)
}
// dispatch error to all waiting callbacks
for (let i = 0; i < this._queue.length; i++) {
const queuedCallback = this._queue[i][1]
queuedCallback.call(this, msg)
}
this._queue.length = 0
if (this.listenerCount('error') > 0) {
// only dispatch error events if we have a listener
this.emit('error', msg)
}
}
_getRows(rows, cb) {
this.state = 'busy'
this._cb = cb
this._rows = []
const msg = {
portal: this._portal,
rows: rows,
}
this.connection.execute(msg, true)
this.connection.flush()
}
// users really shouldn't be calling 'end' here and terminating a connection to postgres
// via the low level connection.end api
end(cb) {
if (this.state !== 'initialized') {
this.connection.sync()
}
this.connection.once('end', cb)
this.connection.end()
}
close(cb) {
let promise
if (!cb) {
promise = new this._Promise((resolve, reject) => {
cb = (err) => (err ? reject(err) : resolve())
})
}
if (!this.connection || this.state === 'done') {
setImmediate(cb)
return promise
}
this._closePortal()
this.connection.once('readyForQuery', function () {
cb()
})
// Return the promise (or undefined)
return promise
}
read(rows, cb) {
let promise
if (!cb) {
promise = new this._Promise((resolve, reject) => {
cb = (err, rows) => (err ? reject(err) : resolve(rows))
})
}
if (this.state === 'idle' || this.state === 'submitted') {
this._getRows(rows, cb)
} else if (this.state === 'busy' || this.state === 'initialized') {
this._queue.push([rows, cb])
} else if (this.state === 'error') {
setImmediate(() => cb(this._error))
} else if (this.state === 'done') {
setImmediate(() => cb(null, []))
} else {
throw new Error('Unknown state: ' + this.state)
}
// Return the promise (or undefined)
return promise
}
}
Cursor.prototype.end = util.deprecate(
Cursor.prototype.end,
'Cursor.end is deprecated. Call end on the client itself to end a connection to the database.'
)
module.exports = Cursor

Some files were not shown because too many files have changed in this diff Show More