Skip to content

Commit 75c376d

Browse files
committed
Reorder and readd toc
1 parent 4e95748 commit 75c376d

File tree

1 file changed

+104
-89
lines changed

1 file changed

+104
-89
lines changed

README.md

Lines changed: 104 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,23 @@ async function insertUser({ name, age }) {
6363

6464
```
6565

66+
## Table of Contents
67+
68+
* [Connection](#connection)
69+
* [Queries](#queries)
70+
* [Building queries](#building-queries)
71+
* [Advanced query methods](#advanced-query-methods)
72+
* [Transactions](#transactions)
73+
* [Listen & notify](#listen--notify)
74+
* [Realtime subscribe](#realtime-subscribe)
75+
* [Numbers, bigint, numeric](#numbers-bigint-numeric)
76+
* [Connection details](#connection-details)
77+
* [Custom Types](#custom-types)
78+
* [Teardown / Cleanup](#teardown--cleanup)
79+
* [Error handling](#error-handling)
80+
* [TypeScript support](#typescript-support)
81+
82+
6683
## Connection
6784

6885
### `postgres([url], [options])`
@@ -80,7 +97,7 @@ const sql = postgres('postgres://username:password@host:port/database', {
8097
})
8198
```
8299

83-
More options can be found in the [Advanced Connection Options section](#connection-options).
100+
More options can be found in the [Connection details section](#connection-details).
84101

85102
## Queries
86103

@@ -406,7 +423,7 @@ const result = await sql.file('query.sql', ['Murray', 68])
406423

407424
```
408425
409-
## Canceling Queries in Progress
426+
### Canceling Queries in Progress
410427
411428
Postgres.js supports, [canceling queries in progress](https://www.postgresql.org/docs/7.1/protocol-protocol.html#AEN39000). It works by opening a new connection with a protocol level startup message to cancel the current query running on a specific connection. That means there is no guarantee that the query will be canceled, and due to the possible race conditions it might even result in canceling another query. This is fine for long running queries, but in the case of high load and fast queries it might be better to simply ignore results instead of canceling.
412429
@@ -418,6 +435,22 @@ const result = await query
418435

419436
```
420437
438+
### Unsafe raw string queries
439+
440+
<details>
441+
<summary>Advanced unsafe use cases</summary>
442+
443+
### `await sql.unsafe(query, [args], [options]) -> Result[]`
444+
445+
If you know what you're doing, you can use `unsafe` to pass any string you'd like to postgres. Please note that this can lead to sql injection if you're not careful.
446+
447+
```js
448+
449+
sql.unsafe('select ' + danger + ' from users where id = ' + dragons)
450+
451+
```
452+
</details>
453+
421454
## Transactions
422455
423456
#### BEGIN / COMMIT `await sql.begin([options = ''], fn) -> fn()`
@@ -500,66 +533,7 @@ sql.begin('read write', async sql => {
500533
501534
Do note that you can often achieve the same result using [`WITH` queries (Common Table Expressions)](https://www.postgresql.org/docs/current/queries-with.html) instead of using transactions.
502535
503-
## Unsafe raw string queries
504-
505-
<details>
506-
<summary>Advanced unsafe use cases</summary>
507-
508-
### `await sql.unsafe(query, [args], [options]) -> Result[]`
509-
510-
If you know what you're doing, you can use `unsafe` to pass any string you'd like to postgres. Please note that this can lead to sql injection if you're not careful.
511-
512-
```js
513-
514-
sql.unsafe('select ' + danger + ' from users where id = ' + dragons)
515-
516-
```
517-
</details>
518-
519-
## Custom Types
520-
521-
You can add ergonomic support for custom types, or simply use `sql.typed(value, type)` inline, where type is the PostgreSQL `oid` for the type and the correctly serialized string. _(`oid` values for types can be found in the `pg_catalog.pg_types` table.)_
522-
523-
Adding Query helpers is the cleanest approach which can be done like this:
524-
525-
```js
526-
const sql = postgres({
527-
types: {
528-
rect: {
529-
// The pg_types oid to pass to the db along with the serialized value.
530-
to : 1337,
531-
532-
// An array of pg_types oids to handle when parsing values coming from the db.
533-
from : [1337],
534-
535-
//Function that transform values before sending them to the db.
536-
serialize : ({ x, y, width, height }) => [x, y, width, height],
537-
538-
// Function that transforms values coming from the db.
539-
parse : ([x, y, width, height]) => { x, y, width, height }
540-
}
541-
}
542-
})
543-
544-
// Now you can use sql.typed.rect() as specified above
545-
const [custom] = sql`
546-
insert into rectangles (
547-
name,
548-
rect
549-
) values (
550-
'wat',
551-
${ sql.typed.rect({ x: 13, y: 37, width: 42, height: 80 }) }
552-
)
553-
returning *
554-
`
555-
556-
// custom = { name: 'wat', rect: { x: 13, y: 37, width: 42, height: 80 } }
557-
558-
```
559-
560-
## Advanced communication
561-
562-
### Listen and notify
536+
## Listen & notify
563537
564538
When you call `.listen`, a dedicated connection will be created to ensure that you receive notifications in real-time. This connection will be used for any further calls to `.listen`.
565539
@@ -581,20 +555,20 @@ sql.notify('news', JSON.stringify({ no: 'this', is: 'news' }))
581555

582556
```
583557
584-
### Subscribe / Realtime
558+
## Realtime subscribe
585559
586560
Postgres.js implements the logical replication protocol of PostgreSQL to support subscription to real-time updates of `insert`, `update` and `delete` operations.
587561
588562
> **NOTE** To make this work you must [create the proper publications in your database](https://www.postgresql.org/docs/current/sql-createpublication.html), enable logical replication by setting `wal_level = logical` in `postgresql.conf` and connect using either a replication or superuser.
589563
590-
#### Quick start
564+
### Quick start
591565
592-
##### Create a publication (eg. in migration)
566+
#### Create a publication (eg. in migration)
593567
```sql
594568
CREATE PUBLICATION alltables FOR ALL TABLES
595569
```
596570
597-
##### Subscribe to updates
571+
#### Subscribe to updates
598572
```js
599573
const sql = postgres({ publications: 'alltables' })
600574

@@ -603,11 +577,11 @@ const { unsubscribe } = await sql.subscribe('insert:events', (row, { command, re
603577
)
604578
```
605579
606-
#### Subscribe pattern
580+
### Subscribe pattern
607581
608582
You can subscribe to specific operations, tables, or even rows with primary keys.
609583
610-
##### `operation` `:` `schema` `.` `table` `=` `primary_key`
584+
#### `operation` `:` `schema` `.` `table` `=` `primary_key`
611585
612586
**`operation`** is one of ``` * | insert | update | delete ``` and defaults to `*`
613587
@@ -617,7 +591,7 @@ You can subscribe to specific operations, tables, or even rows with primary keys
617591
618592
**`primary_key`** can be used to only subscribe to specific rows
619593
620-
#### Examples
594+
### Examples
621595
622596
```js
623597
sql.subscribe('*', () => /* everything */ )
@@ -627,25 +601,6 @@ sql.subscribe('delete:users', () => /* all deletes on the public.users table
627601
sql.subscribe('update:users=1', () => /* all updates on the users row with a primary key = 1 */ )
628602
```
629603
630-
## Teardown / Cleanup
631-
632-
To ensure proper teardown and cleanup on server restarts use `await sql.end()` before `process.exit()`.
633-
634-
Calling `sql.end()` will reject new queries and return a Promise which resolves when all queries are finished and the underlying connections are closed. If a `{ timeout }` option is provided any pending queries will be rejected once the timeout (in seconds) is reached and the connections will be destroyed.
635-
636-
#### Sample shutdown using [Prexit](https://github.com/porsager/prexit)
637-
638-
```js
639-
640-
import prexit from 'prexit'
641-
642-
prexit(async () => {
643-
await sql.end({ timeout: 5 })
644-
await new Promise(r => server.close(r))
645-
})
646-
647-
```
648-
649604
## Numbers, bigint, numeric
650605
651606
`Number` in javascript is only able to represent 2<sup>53</sup>-1 safely which means that types in PostgreSQLs like `bigint` and `numeric` won't fit into `Number`.
@@ -665,7 +620,7 @@ const sql = postgres({
665620
There is currently no guaranteed way to handle `numeric / decimal` types in native Javascript. **These [and similar] types will be returned as a `string`**. The best way in this case is to use [custom types](#custom-types).
666621
667622
668-
## Connection options
623+
## Connection details
669624
670625
### All Postgres options
671626
@@ -792,6 +747,66 @@ const sql = postgres()
792747
793748
Prepared statements will automatically be created for any queries where it can be inferred that the query is static. This can be disabled by using the `no_prepare` option. For instance — this is useful when [using PGBouncer in `transaction mode`](https://github.com/porsager/postgres/issues/93).
794749
750+
## Custom Types
751+
752+
You can add ergonomic support for custom types, or simply use `sql.typed(value, type)` inline, where type is the PostgreSQL `oid` for the type and the correctly serialized string. _(`oid` values for types can be found in the `pg_catalog.pg_types` table.)_
753+
754+
Adding Query helpers is the cleanest approach which can be done like this:
755+
756+
```js
757+
const sql = postgres({
758+
types: {
759+
rect: {
760+
// The pg_types oid to pass to the db along with the serialized value.
761+
to : 1337,
762+
763+
// An array of pg_types oids to handle when parsing values coming from the db.
764+
from : [1337],
765+
766+
//Function that transform values before sending them to the db.
767+
serialize : ({ x, y, width, height }) => [x, y, width, height],
768+
769+
// Function that transforms values coming from the db.
770+
parse : ([x, y, width, height]) => { x, y, width, height }
771+
}
772+
}
773+
})
774+
775+
// Now you can use sql.typed.rect() as specified above
776+
const [custom] = sql`
777+
insert into rectangles (
778+
name,
779+
rect
780+
) values (
781+
'wat',
782+
${ sql.typed.rect({ x: 13, y: 37, width: 42, height: 80 }) }
783+
)
784+
returning *
785+
`
786+
787+
// custom = { name: 'wat', rect: { x: 13, y: 37, width: 42, height: 80 } }
788+
789+
```
790+
791+
## Teardown / Cleanup
792+
793+
To ensure proper teardown and cleanup on server restarts use `await sql.end()` before `process.exit()`.
794+
795+
Calling `sql.end()` will reject new queries and return a Promise which resolves when all queries are finished and the underlying connections are closed. If a `{ timeout }` option is provided any pending queries will be rejected once the timeout (in seconds) is reached and the connections will be destroyed.
796+
797+
#### Sample shutdown using [Prexit](https://github.com/porsager/prexit)
798+
799+
```js
800+
801+
import prexit from 'prexit'
802+
803+
prexit(async () => {
804+
await sql.end({ timeout: 5 })
805+
await new Promise(r => server.close(r))
806+
})
807+
808+
```
809+
795810
## Error handling
796811
797812
Errors are all thrown to related queries and never globally. Errors coming from database itself are always in the [native Postgres format](https://www.postgresql.org/docs/current/errcodes-appendix.html), and the same goes for any [Node.js errors](https://nodejs.org/api/errors.html#errors_common_system_errors) eg. coming from the underlying connection.

0 commit comments

Comments
 (0)