From 0c1629bea2104aba8366263be78d62ff89aca8e5 Mon Sep 17 00:00:00 2001 From: Brian C Date: Wed, 23 Apr 2025 16:46:21 -0500 Subject: [PATCH] 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 --- docs/README.md | 20 +++++++++++ docs/components/logo.tsx | 11 ++++++ docs/pages/apis/client.mdx | 15 +++----- docs/pages/apis/cursor.mdx | 14 +++----- docs/pages/apis/pool.mdx | 18 ++++------ docs/pages/features/_meta.json | 4 ++- docs/pages/features/callbacks.mdx | 39 +++++++++++++++++++++ docs/pages/features/esm.mdx | 37 ++++++++++++++++++++ docs/pages/features/ssl.mdx | 3 +- docs/pages/features/transactions.mdx | 3 +- docs/pages/guides/async-express.md | 3 +- docs/pages/guides/project-structure.md | 13 +++---- docs/pages/index.mdx | 46 +++++++++++++++---------- docs/public/favicon.ico | Bin 0 -> 15406 bytes docs/theme.config.js | 35 +++++++++++++++++-- 15 files changed, 194 insertions(+), 67 deletions(-) create mode 100644 docs/README.md create mode 100644 docs/components/logo.tsx create mode 100644 docs/pages/features/callbacks.mdx create mode 100644 docs/pages/features/esm.mdx create mode 100644 docs/public/favicon.ico diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 00000000..d19c590b --- /dev/null +++ b/docs/README.md @@ -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. diff --git a/docs/components/logo.tsx b/docs/components/logo.tsx new file mode 100644 index 00000000..5d1175de --- /dev/null +++ b/docs/components/logo.tsx @@ -0,0 +1,11 @@ +import React from 'react' + +type Props = { + src: string + alt?: string +} + +export function Logo(props: Props) { + const alt = props.alt || 'Logo' + return {alt} +} diff --git a/docs/pages/apis/client.mdx b/docs/pages/apis/client.mdx index 8014731f..9ce6b111 100644 --- a/docs/pages/apis/client.mdx +++ b/docs/pages/apis/client.mdx @@ -33,8 +33,7 @@ type Config = { example to create a client with specific connection information: ```js -import pg from 'pg' -const { Client } = pg +import { Client } from 'pg' const client = new Client({ user: 'database-user', @@ -48,8 +47,7 @@ const client = new Client({ ## client.connect ```js -import pg from 'pg' -const { Client } = pg +import { Client } from 'pg' const client = new Client() await client.connect() @@ -91,8 +89,7 @@ client.query(text: string, values?: any[]) => Promise **Plain text query** ```js -import pg from 'pg' -const { Client } = pg +import { Client } from 'pg' const client = new Client() await client.connect() @@ -106,8 +103,7 @@ await client.end() **Parameterized query** ```js -import pg from 'pg' -const { Client } = pg +import { Client } from 'pg' const client = new Client() await client.connect() @@ -145,8 +141,7 @@ await client.end() 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 pg from 'pg' -const { Query } = pg +import { Query } from 'pg' const query = new Query('select $1::text as name', ['brianc']) const result = client.query(query) diff --git a/docs/pages/apis/cursor.mdx b/docs/pages/apis/cursor.mdx index 7728520c..810bccdd 100644 --- a/docs/pages/apis/cursor.mdx +++ b/docs/pages/apis/cursor.mdx @@ -18,8 +18,7 @@ $ npm install pg pg-cursor Instantiates a new Cursor. A cursor is an instance of `Submittable` and should be passed directly to the `client.query` method. ```js -import pg from 'pg' -const { Pool } = pg +import { Pool } from 'pg' import Cursor from 'pg-cursor' const pool = new Pool() @@ -29,11 +28,9 @@ const values = [10] const cursor = client.query(new Cursor(text, values)) -cursor.read(100, (err, rows) => { - cursor.close(() => { - client.release() - }) -}) +const { rows } = await cursor.read(100) +console.log(rows.length) // 100 (unless the table has fewer than 100 rows) +client.release() ``` ```ts @@ -58,8 +55,7 @@ If the cursor has read to the end of the result sets all subsequent calls to cur Here is an example of reading to the end of a cursor: ```js -import pg from 'pg' -const { Pool } = pg +import { Pool } from 'pg' import Cursor from 'pg-cursor' const pool = new Pool() diff --git a/docs/pages/apis/pool.mdx b/docs/pages/apis/pool.mdx index d3975c1d..3cf32b6c 100644 --- a/docs/pages/apis/pool.mdx +++ b/docs/pages/apis/pool.mdx @@ -48,8 +48,7 @@ type Config = { example to create a new pool with configuration: ```js -import pg from 'pg' -const { Pool } = pg +import { Pool } from 'pg' const pool = new Pool({ host: 'localhost', @@ -69,8 +68,7 @@ pool.query(text: string, values?: any[]) => Promise ``` ```js -import pg from 'pg' -const { Pool } = pg +import { Pool } from 'pg' const pool = new Pool() @@ -102,8 +100,7 @@ Acquires a client from the pool. - If the pool is 'full' and all clients are currently checked out will wait in a FIFO queue until a client becomes available by it being released back to the pool. ```js -import pg from 'pg' -const { Pool } = pg +import { Pool } from 'pg' const pool = new Pool() @@ -121,8 +118,7 @@ Client instances returned from `pool.connect` will have a `release` method which 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 pg from 'pg' -const { Pool } = pg +import { Pool } from 'pg' const pool = new Pool() @@ -134,8 +130,7 @@ client.release() ``` ```js -import pg from 'pg' -const { Pool } = pg +import { Pool } from 'pg' const pool = new Pool() assert(pool.totalCount === 0) @@ -168,8 +163,7 @@ Calling `pool.end` will drain the pool of all active clients, disconnect them, a ```js // again both promises and callbacks are supported: -import pg from 'pg' -const { Pool } = pg +import { Pool } from 'pg' const pool = new Pool() diff --git a/docs/pages/features/_meta.json b/docs/pages/features/_meta.json index a2f5e340..1c798049 100644 --- a/docs/pages/features/_meta.json +++ b/docs/pages/features/_meta.json @@ -5,5 +5,7 @@ "transactions": "Transactions", "types": "Data Types", "ssl": "SSL", - "native": "Native" + "native": "Native", + "esm": "ESM", + "callbacks": "Callbacks" } diff --git a/docs/pages/features/callbacks.mdx b/docs/pages/features/callbacks.mdx new file mode 100644 index 00000000..8a6e2a52 --- /dev/null +++ b/docs/pages/features/callbacks.mdx @@ -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() + }) +}) +``` diff --git a/docs/pages/features/esm.mdx b/docs/pages/features/esm.mdx new file mode 100644 index 00000000..7aac546a --- /dev/null +++ b/docs/pages/features/esm.mdx @@ -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... +``` diff --git a/docs/pages/features/ssl.mdx b/docs/pages/features/ssl.mdx index a7609ea0..2c5e7bd9 100644 --- a/docs/pages/features/ssl.mdx +++ b/docs/pages/features/ssl.mdx @@ -22,8 +22,7 @@ const config = { }, } -import pg from 'pg' -const { Client, Pool } = pg +import { Client, Pool } from 'pg' const client = new Client(config) await client.connect() diff --git a/docs/pages/features/transactions.mdx b/docs/pages/features/transactions.mdx index 9280d1f4..4433bd3e 100644 --- a/docs/pages/features/transactions.mdx +++ b/docs/pages/features/transactions.mdx @@ -16,8 +16,7 @@ To execute a transaction with node-postgres you simply execute `BEGIN / COMMIT / ## Examples ```js -import pg from 'pg' -const { Pool } = pg +import { Pool } from 'pg' const pool = new Pool() const client = await pool.connect() diff --git a/docs/pages/guides/async-express.md b/docs/pages/guides/async-express.md index 60116452..a44c1528 100644 --- a/docs/pages/guides/async-express.md +++ b/docs/pages/guides/async-express.md @@ -22,8 +22,7 @@ That's the same structure I used in the [project structure](/guides/project-stru My `db/index.js` file usually starts out like this: ```js -import pg from 'pg' -const { Pool } = pg +import { Pool } from 'pg' const pool = new Pool() diff --git a/docs/pages/guides/project-structure.md b/docs/pages/guides/project-structure.md index 1e360ae4..5f53a418 100644 --- a/docs/pages/guides/project-structure.md +++ b/docs/pages/guides/project-structure.md @@ -27,13 +27,12 @@ The location doesn't really matter - I've found it usually ends up being somewha Typically I'll start out my `db/index.js` file like so: ```js -import pg from 'pg' -const { Pool } = pg +import { Pool } from 'pg' const pool = new Pool() -export const query = (text, params, callback) => { - return pool.query(text, params, callback) +export const query = (text, params) => { + return pool.query(text, params) } ``` @@ -55,8 +54,7 @@ app.get('/:id', async (req, res, next) => { 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 pg from 'pg' -const { Pool } = pg +import { Pool } from 'pg' const pool = new Pool() @@ -76,8 +74,7 @@ _note: I didn't log the query parameters. Depending on your application you migh 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 pg from 'pg' -const { Pool } = pg +import { Pool } from 'pg' const pool = new Pool() diff --git a/docs/pages/index.mdx b/docs/pages/index.mdx index 0330e2c7..5a9011b0 100644 --- a/docs/pages/index.mdx +++ b/docs/pages/index.mdx @@ -3,6 +3,8 @@ 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 @@ -15,19 +17,33 @@ $ npm install pg 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! + + + Medplum + + 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 8.x, 10.x, 12.x and 14.x To use node >= 14.x you will need to install `pg@8.2.x` or later due to some internal stream changes on the node 14 branch. Dropping support for an old node lts version will always be considered a breaking change in node-postgres and will be done on _major_ version number changes only, and we will try to keep support for 8.x for as long as reasonably possible. +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 pg from 'pg' -const { Client } = pg +import { Client } from 'pg' const client = new Client() await client.connect() @@ -41,8 +57,7 @@ await client.end() 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 pg from 'pg' -const { Client } = pg +import { Client } from 'pg' const client = new Client() await client.connect() @@ -56,22 +71,17 @@ try { } ``` -### Callbacks +### Pooling -If you prefer a callback-style approach to asynchronous programming, all async methods support an optional callback parameter as well: +In most applications you'll wannt 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 pg from 'pg' -const { Client } = pg -const client = new Client() - -client.connect((err) => { - client.query('SELECT $1::text as message', ['Hello world!'], (err, res) => { - console.log(err ? err.stack : res.rows[0].message) // Hello World! - client.end() - }) -}) - +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! + + diff --git a/docs/public/favicon.ico b/docs/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..ab485092f262fc43d2b742e8c634bf75489bf519 GIT binary patch literal 15406 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 MN&+bfBvk_c1)24w$^ZZW literal 0 HcmV?d00001 diff --git a/docs/theme.config.js b/docs/theme.config.js index 02e5327c..316ae714 100644 --- a/docs/theme.config.js +++ b/docs/theme.config.js @@ -10,7 +10,6 @@ export default { docsRepositoryBase: 'https://github.com/brianc/node-postgres/blob/master/docs', // base URL for the docs repository titleSuffix: ' – node-postgres', darkMode: true, - footer: true, navigation: { prev: true, next: true, @@ -23,13 +22,43 @@ export default { }, logo: ( <> - ... - node-postgres + + + + + + node-postgres ), + chat: { + link: 'https://discord.gg/4nbb6zJa', + }, head: ( <> +