@keyv/postgres 2.2.3 → 6.0.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +434 -23
- package/dist/index.cjs +572 -101
- package/dist/index.d.cts +275 -15
- package/dist/index.d.ts +275 -15
- package/dist/index.js +572 -101
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
# @keyv/postgres [<img width="100" align="right" src="https://jaredwray.com/images/keyv-symbol.svg" alt="keyv">](https://github.com/
|
|
1
|
+
# @keyv/postgres [<img width="100" align="right" src="https://jaredwray.com/images/keyv-symbol.svg" alt="keyv">](https://github.com/jaredwray/keyv)
|
|
2
2
|
|
|
3
3
|
> PostgreSQL storage adapter for Keyv
|
|
4
4
|
|
|
5
|
-
[](https://github.com/jaredwray/keyv/actions/workflows/
|
|
5
|
+
[](https://github.com/jaredwray/keyv/actions/workflows/tests.yaml)
|
|
6
6
|
[](https://codecov.io/gh/jaredwray/keyv)
|
|
7
7
|
[](https://www.npmjs.com/package/@keyv/postgres)
|
|
8
8
|
[](https://npmjs.com/package/@keyv/postgres)
|
|
@@ -11,55 +11,450 @@ PostgreSQL storage adapter for [Keyv](https://github.com/jaredwray/keyv).
|
|
|
11
11
|
|
|
12
12
|
Requires Postgres 9.5 or newer for `ON CONFLICT` support to allow performant upserts. [Why?](https://stackoverflow.com/questions/17267417/how-to-upsert-merge-insert-on-duplicate-update-in-postgresql/17267423#17267423)
|
|
13
13
|
|
|
14
|
-
##
|
|
14
|
+
## Table of Contents
|
|
15
|
+
|
|
16
|
+
- [Install](#install)
|
|
17
|
+
- [Usage](#usage)
|
|
18
|
+
- [Migrating to v6](#migrating-to-v6)
|
|
19
|
+
- [Constructor Options](#constructor-options)
|
|
20
|
+
- [Properties](#properties)
|
|
21
|
+
- [uri](#uri)
|
|
22
|
+
- [table](#table)
|
|
23
|
+
- [keyLength](#keylength)
|
|
24
|
+
- [namespaceLength](#namespacelength)
|
|
25
|
+
- [schema](#schema)
|
|
26
|
+
- [ssl](#ssl)
|
|
27
|
+
- [iterationLimit](#iterationlimit)
|
|
28
|
+
- [useUnloggedTable](#useunloggedtable)
|
|
29
|
+
- [clearExpiredInterval](#clearexpiredinterval)
|
|
30
|
+
- [namespace](#namespace)
|
|
31
|
+
- [Methods](#methods)
|
|
32
|
+
- [.set(key, value)](#setkey-value)
|
|
33
|
+
- [.setMany(entries)](#setmanyentries)
|
|
34
|
+
- [.get(key)](#getkey)
|
|
35
|
+
- [.getMany(keys)](#getmanykeys)
|
|
36
|
+
- [.has(key)](#haskey)
|
|
37
|
+
- [.hasMany(keys)](#hasmanykeys)
|
|
38
|
+
- [.delete(key)](#deletekey)
|
|
39
|
+
- [.deleteMany(keys)](#deletemanykeys)
|
|
40
|
+
- [.clear()](#clear)
|
|
41
|
+
- [.clearExpired()](#clearexpired)
|
|
42
|
+
- [.iterator(namespace?)](#iteratornamespace)
|
|
43
|
+
- [.disconnect()](#disconnect)
|
|
44
|
+
- [Using an Unlogged Table for Performance](#using-an-unlogged-table-for-performance)
|
|
45
|
+
- [Connection Pooling](#connection-pooling)
|
|
46
|
+
- [SSL/TLS Connections](#ssltls-connections)
|
|
47
|
+
- [Testing](#testing)
|
|
48
|
+
- [License](#license)
|
|
49
|
+
|
|
50
|
+
# Install
|
|
15
51
|
|
|
16
52
|
```shell
|
|
17
53
|
npm install --save keyv @keyv/postgres
|
|
18
54
|
```
|
|
19
55
|
|
|
20
|
-
|
|
56
|
+
# Usage
|
|
21
57
|
|
|
22
58
|
```js
|
|
23
59
|
import Keyv from 'keyv';
|
|
24
60
|
import KeyvPostgres from '@keyv/postgres';
|
|
25
61
|
|
|
26
|
-
const keyv = new Keyv(new KeyvPostgres('postgresql://user:pass@localhost:5432/dbname'));
|
|
62
|
+
const keyv = new Keyv({ store: new KeyvPostgres('postgresql://user:pass@localhost:5432/dbname') });
|
|
27
63
|
keyv.on('error', handleConnectionError);
|
|
28
64
|
```
|
|
29
65
|
|
|
30
|
-
You can specify the `table`
|
|
66
|
+
You can specify the `table` and `schema` options:
|
|
31
67
|
|
|
32
|
-
|
|
68
|
+
```js
|
|
69
|
+
const keyvPostgres = new KeyvPostgres({ uri: 'postgresql://user:pass@localhost:5432/dbname', table: 'cache', schema: 'keyv' });
|
|
70
|
+
const keyv = new Keyv({ store: keyvPostgres });
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
You can also use the `createKeyv` helper function to create `Keyv` with `KeyvPostgres` store:
|
|
33
74
|
|
|
34
75
|
```js
|
|
35
|
-
|
|
36
|
-
|
|
76
|
+
import { createKeyv } from '@keyv/postgres';
|
|
77
|
+
|
|
78
|
+
const keyv = createKeyv({ uri: 'postgresql://user:pass@localhost:5432/dbname', table: 'cache', schema: 'keyv' });
|
|
37
79
|
```
|
|
38
80
|
|
|
39
|
-
|
|
81
|
+
# Migrating to v6
|
|
82
|
+
|
|
83
|
+
## Breaking changes
|
|
40
84
|
|
|
41
|
-
|
|
85
|
+
### Properties instead of opts
|
|
86
|
+
|
|
87
|
+
In v5, configuration was accessed through the `opts` object:
|
|
42
88
|
|
|
43
89
|
```js
|
|
44
|
-
|
|
45
|
-
|
|
90
|
+
// v5
|
|
91
|
+
store.opts.table; // 'keyv'
|
|
92
|
+
store.opts.schema; // 'public'
|
|
46
93
|
```
|
|
47
94
|
|
|
48
|
-
|
|
95
|
+
In v6, all configuration options are exposed as top-level properties with getters and setters:
|
|
49
96
|
|
|
50
97
|
```js
|
|
51
|
-
|
|
98
|
+
// v6
|
|
99
|
+
store.table; // 'keyv'
|
|
100
|
+
store.schema; // 'public'
|
|
101
|
+
store.table = 'cache';
|
|
102
|
+
```
|
|
52
103
|
|
|
53
|
-
|
|
104
|
+
The `opts` getter still exists for backward compatibility but should not be used for new code.
|
|
105
|
+
|
|
106
|
+
### Native namespace support
|
|
107
|
+
|
|
108
|
+
In v5, namespaces were stored as key prefixes in the `key` column (e.g. `key="myns:mykey"` with `namespace=NULL`). In v6, the namespace is stored in a dedicated `namespace` column (e.g. `key="mykey"`, `namespace="myns"`). This enables more efficient queries and proper namespace isolation.
|
|
109
|
+
|
|
110
|
+
The adapter automatically adds the `namespace` column and creates the appropriate index when it connects, so no manual schema changes are needed for new installations.
|
|
111
|
+
|
|
112
|
+
### Hookified integration
|
|
113
|
+
|
|
114
|
+
The adapter now extends [Hookified](https://hookified.org) instead of a custom EventEmitter. Events work the same (`on`, `emit`), but hooks are also available via the standard Hookified API.
|
|
115
|
+
|
|
116
|
+
## New features
|
|
117
|
+
|
|
118
|
+
### Native TTL support with `expires` column
|
|
119
|
+
|
|
120
|
+
v6 adds an `expires BIGINT` column to the table. When values are stored with a TTL via Keyv core, the adapter automatically extracts the `expires` timestamp from the serialized value and stores it in the column. A partial index is created on the `expires` column for efficient cleanup queries.
|
|
121
|
+
|
|
122
|
+
The schema migration is automatic on connect — existing tables get the column added via `ADD COLUMN IF NOT EXISTS`.
|
|
123
|
+
|
|
124
|
+
### `clearExpired()` method
|
|
125
|
+
|
|
126
|
+
A new utility method that deletes all rows where the `expires` column is set and the timestamp is in the past:
|
|
127
|
+
|
|
128
|
+
```js
|
|
129
|
+
await store.clearExpired();
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### `clearExpiredInterval` option
|
|
133
|
+
|
|
134
|
+
Set an interval (in milliseconds) to automatically call `clearExpired()` on a schedule. Disabled by default (`0`). The timer uses `unref()` so it won't keep the Node.js process alive.
|
|
135
|
+
|
|
136
|
+
```js
|
|
137
|
+
const store = new KeyvPostgres({
|
|
138
|
+
uri: 'postgresql://user:pass@localhost:5432/dbname',
|
|
139
|
+
clearExpiredInterval: 60_000, // clean up every 60 seconds
|
|
140
|
+
});
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Bulk operations
|
|
144
|
+
|
|
145
|
+
New methods for efficient multi-key operations:
|
|
146
|
+
|
|
147
|
+
- `.setMany(entries)` — bulk upsert using PostgreSQL `UNNEST`
|
|
148
|
+
- `.getMany(keys)` — bulk retrieve using `ANY`
|
|
149
|
+
- `.deleteMany(keys)` — bulk delete using `ANY`
|
|
150
|
+
- `.hasMany(keys)` — bulk existence check
|
|
151
|
+
|
|
152
|
+
### `createKeyv()` helper
|
|
153
|
+
|
|
154
|
+
A convenience function to create a `Keyv` instance with `KeyvPostgres` as the store in one call:
|
|
155
|
+
|
|
156
|
+
```js
|
|
157
|
+
import { createKeyv } from '@keyv/postgres';
|
|
158
|
+
|
|
159
|
+
const keyv = createKeyv({ uri: 'postgresql://user:pass@localhost:5432/dbname' });
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Improved iterator
|
|
163
|
+
|
|
164
|
+
The iterator now uses cursor-based (keyset) pagination instead of `OFFSET`. This handles concurrent deletions during iteration without skipping entries and is more efficient for large datasets.
|
|
165
|
+
|
|
166
|
+
## Running the migration script
|
|
167
|
+
|
|
168
|
+
If you have existing data from v5, you need to run the migration script to move namespace prefixes from keys into the new `namespace` column. The script is located at `scripts/migrate-v6.ts` in the `@keyv/postgres` package.
|
|
169
|
+
|
|
170
|
+
Preview the changes first with `--dry-run`:
|
|
171
|
+
|
|
172
|
+
```shell
|
|
173
|
+
npx tsx scripts/migrate-v6.ts --uri postgresql://user:pass@localhost:5432/dbname --dry-run
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Run the migration:
|
|
177
|
+
|
|
178
|
+
```shell
|
|
179
|
+
npx tsx scripts/migrate-v6.ts --uri postgresql://user:pass@localhost:5432/dbname
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
You can also specify a custom table, schema, and column lengths:
|
|
183
|
+
|
|
184
|
+
```shell
|
|
185
|
+
npx tsx scripts/migrate-v6.ts --uri postgresql://user:pass@localhost:5432/dbname --table cache --schema keyv
|
|
186
|
+
npx tsx scripts/migrate-v6.ts --uri postgresql://user:pass@localhost:5432/dbname --keyLength 512 --namespaceLength 512
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
The migration runs inside a transaction and will roll back automatically if anything fails.
|
|
190
|
+
|
|
191
|
+
**Important notes:**
|
|
192
|
+
- The script only migrates rows where `namespace IS NULL`. Rows that already have a namespace value (e.g. from a partial earlier migration) are skipped.
|
|
193
|
+
- Keys are split on the first colon — the part before becomes the namespace, the rest becomes the key. Namespaces containing colons are not supported.
|
|
194
|
+
|
|
195
|
+
# Constructor Options
|
|
196
|
+
|
|
197
|
+
`KeyvPostgres` accepts a connection URI string or an options object. The options object accepts the following properties along with any [`PoolConfig`](https://node-postgres.com/apis/pool) properties from the `pg` library (e.g. `max`, `idleTimeoutMillis`, `connectionTimeoutMillis`):
|
|
198
|
+
|
|
199
|
+
| Option | Type | Default | Description |
|
|
200
|
+
| --- | --- | --- | --- |
|
|
201
|
+
| `uri` | `string` | `'postgresql://localhost:5432'` | PostgreSQL connection URI |
|
|
202
|
+
| `table` | `string` | `'keyv'` | Table name for key-value storage |
|
|
203
|
+
| `keyLength` | `number` | `255` | Maximum key column length (VARCHAR length) |
|
|
204
|
+
| `namespaceLength` | `number` | `255` | Maximum namespace column length (VARCHAR length) |
|
|
205
|
+
| `schema` | `string` | `'public'` | PostgreSQL schema name (created automatically if it doesn't exist) |
|
|
206
|
+
| `ssl` | `object` | `undefined` | SSL/TLS configuration passed to the `pg` driver |
|
|
207
|
+
| `iterationLimit` | `number` | `10` | Number of rows fetched per batch during iteration |
|
|
208
|
+
| `useUnloggedTable` | `boolean` | `false` | Use a PostgreSQL UNLOGGED table for better write performance |
|
|
209
|
+
| `clearExpiredInterval` | `number` | `0` | Interval in milliseconds to automatically clear expired entries (0 = disabled) |
|
|
210
|
+
|
|
211
|
+
# Properties
|
|
212
|
+
|
|
213
|
+
All configuration options are exposed as properties with getters and setters on the `KeyvPostgres` instance. You can read or update them after construction.
|
|
214
|
+
|
|
215
|
+
## uri
|
|
216
|
+
|
|
217
|
+
Get or set the PostgreSQL connection URI.
|
|
218
|
+
|
|
219
|
+
- Type: `string`
|
|
220
|
+
- Default: `'postgresql://localhost:5432'`
|
|
221
|
+
|
|
222
|
+
```js
|
|
223
|
+
const store = new KeyvPostgres({ uri: 'postgresql://user:pass@localhost:5432/dbname' });
|
|
224
|
+
console.log(store.uri); // 'postgresql://user:pass@localhost:5432/dbname'
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## table
|
|
228
|
+
|
|
229
|
+
Get or set the table name used for storage.
|
|
230
|
+
|
|
231
|
+
- Type: `string`
|
|
232
|
+
- Default: `'keyv'`
|
|
233
|
+
|
|
234
|
+
```js
|
|
235
|
+
const store = new KeyvPostgres({ uri: 'postgresql://user:pass@localhost:5432/dbname' });
|
|
236
|
+
console.log(store.table); // 'keyv'
|
|
237
|
+
store.table = 'cache';
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## keyLength
|
|
241
|
+
|
|
242
|
+
Get or set the maximum key length (VARCHAR length) for the key column.
|
|
243
|
+
|
|
244
|
+
- Type: `number`
|
|
245
|
+
- Default: `255`
|
|
246
|
+
|
|
247
|
+
```js
|
|
248
|
+
const store = new KeyvPostgres({ uri: 'postgresql://user:pass@localhost:5432/dbname', keyLength: 512 });
|
|
249
|
+
console.log(store.keyLength); // 512
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
## namespaceLength
|
|
253
|
+
|
|
254
|
+
Get or set the maximum namespace length (VARCHAR length) for the namespace column.
|
|
255
|
+
|
|
256
|
+
- Type: `number`
|
|
257
|
+
- Default: `255`
|
|
258
|
+
|
|
259
|
+
```js
|
|
260
|
+
const store = new KeyvPostgres({ uri: 'postgresql://user:pass@localhost:5432/dbname', namespaceLength: 512 });
|
|
261
|
+
console.log(store.namespaceLength); // 512
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
## schema
|
|
265
|
+
|
|
266
|
+
Get or set the PostgreSQL schema name. Non-public schemas are created automatically if they don't exist.
|
|
267
|
+
|
|
268
|
+
- Type: `string`
|
|
269
|
+
- Default: `'public'`
|
|
270
|
+
|
|
271
|
+
```js
|
|
272
|
+
const store = new KeyvPostgres({ uri: 'postgresql://user:pass@localhost:5432/dbname', schema: 'keyv' });
|
|
273
|
+
console.log(store.schema); // 'keyv'
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
## ssl
|
|
277
|
+
|
|
278
|
+
Get or set the SSL configuration for the PostgreSQL connection. Passed directly to the `pg` driver.
|
|
279
|
+
|
|
280
|
+
- Type: `object | undefined`
|
|
281
|
+
- Default: `undefined`
|
|
282
|
+
|
|
283
|
+
```js
|
|
284
|
+
const store = new KeyvPostgres({
|
|
285
|
+
uri: 'postgresql://user:pass@localhost:5432/dbname',
|
|
286
|
+
ssl: { rejectUnauthorized: false },
|
|
287
|
+
});
|
|
288
|
+
console.log(store.ssl); // { rejectUnauthorized: false }
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
## iterationLimit
|
|
292
|
+
|
|
293
|
+
Get or set the number of rows to fetch per iteration batch.
|
|
294
|
+
|
|
295
|
+
- Type: `number`
|
|
296
|
+
- Default: `10`
|
|
297
|
+
|
|
298
|
+
```js
|
|
299
|
+
const store = new KeyvPostgres({ uri: 'postgresql://user:pass@localhost:5432/dbname', iterationLimit: 50 });
|
|
300
|
+
console.log(store.iterationLimit); // 50
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
## useUnloggedTable
|
|
304
|
+
|
|
305
|
+
Get or set whether to use a PostgreSQL unlogged table for better write performance. Unlogged tables are faster but data is lost on crash.
|
|
306
|
+
|
|
307
|
+
- Type: `boolean`
|
|
308
|
+
- Default: `false`
|
|
309
|
+
|
|
310
|
+
```js
|
|
311
|
+
const store = new KeyvPostgres({ uri: 'postgresql://user:pass@localhost:5432/dbname', useUnloggedTable: true });
|
|
312
|
+
console.log(store.useUnloggedTable); // true
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
## clearExpiredInterval
|
|
316
|
+
|
|
317
|
+
Get or set the interval in milliseconds between automatic expired-entry cleanup runs. When set to a value greater than 0, the adapter will automatically call `clearExpired()` at the specified interval. The timer uses `unref()` so it won't keep the Node.js process alive. Setting to 0 disables the automatic cleanup.
|
|
318
|
+
|
|
319
|
+
- Type: `number`
|
|
320
|
+
- Default: `0` (disabled)
|
|
321
|
+
|
|
322
|
+
```js
|
|
323
|
+
// Clean up expired entries every 60 seconds
|
|
324
|
+
const store = new KeyvPostgres({ uri: 'postgresql://user:pass@localhost:5432/dbname', clearExpiredInterval: 60_000 });
|
|
325
|
+
console.log(store.clearExpiredInterval); // 60000
|
|
326
|
+
|
|
327
|
+
// Disable it later
|
|
328
|
+
store.clearExpiredInterval = 0;
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
## namespace
|
|
332
|
+
|
|
333
|
+
Get or set the namespace for the adapter. Used for key prefixing and scoping operations like `clear()`.
|
|
334
|
+
|
|
335
|
+
- Type: `string | undefined`
|
|
336
|
+
- Default: `undefined`
|
|
337
|
+
|
|
338
|
+
```js
|
|
339
|
+
const store = new KeyvPostgres({ uri: 'postgresql://user:pass@localhost:5432/dbname' });
|
|
340
|
+
store.namespace = 'my-namespace';
|
|
341
|
+
console.log(store.namespace); // 'my-namespace'
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
# Methods
|
|
345
|
+
|
|
346
|
+
## .set(key, value)
|
|
347
|
+
|
|
348
|
+
Set a key-value pair.
|
|
349
|
+
|
|
350
|
+
```js
|
|
351
|
+
await keyv.set('foo', 'bar');
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
## .setMany(entries)
|
|
355
|
+
|
|
356
|
+
Set multiple key-value pairs at once using PostgreSQL `UNNEST` for efficient bulk operations.
|
|
357
|
+
|
|
358
|
+
```js
|
|
359
|
+
await keyv.setMany([
|
|
360
|
+
{ key: 'foo', value: 'bar' },
|
|
361
|
+
{ key: 'baz', value: 'qux' },
|
|
362
|
+
]);
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
## .get(key)
|
|
366
|
+
|
|
367
|
+
Get a value by key. Returns `undefined` if the key does not exist.
|
|
368
|
+
|
|
369
|
+
```js
|
|
370
|
+
const value = await keyv.get('foo'); // 'bar'
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
## .getMany(keys)
|
|
374
|
+
|
|
375
|
+
Get multiple values at once. Returns an array of values in the same order as the keys, with `undefined` for missing keys.
|
|
376
|
+
|
|
377
|
+
```js
|
|
378
|
+
const values = await keyv.getMany(['foo', 'baz']); // ['bar', 'qux']
|
|
54
379
|
```
|
|
55
380
|
|
|
56
|
-
##
|
|
381
|
+
## .has(key)
|
|
382
|
+
|
|
383
|
+
Check if a key exists. Returns a boolean.
|
|
384
|
+
|
|
385
|
+
```js
|
|
386
|
+
const exists = await keyv.has('foo'); // true
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
## .hasMany(keys)
|
|
390
|
+
|
|
391
|
+
Check if multiple keys exist. Returns an array of booleans in the same order as the input keys.
|
|
392
|
+
|
|
393
|
+
```js
|
|
394
|
+
await keyv.set('foo', 'bar');
|
|
395
|
+
await keyv.set('baz', 'qux');
|
|
396
|
+
|
|
397
|
+
const results = await keyv.hasMany(['foo', 'baz', 'unknown']); // [true, true, false]
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
## .delete(key)
|
|
401
|
+
|
|
402
|
+
Delete a key. Returns `true` if the key existed, `false` otherwise.
|
|
403
|
+
|
|
404
|
+
```js
|
|
405
|
+
const deleted = await keyv.delete('foo'); // true
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
## .deleteMany(keys)
|
|
409
|
+
|
|
410
|
+
Delete multiple keys at once. Returns `true` if any of the keys existed.
|
|
411
|
+
|
|
412
|
+
```js
|
|
413
|
+
const deleted = await keyv.deleteMany(['foo', 'baz']); // true
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
## .clear()
|
|
417
|
+
|
|
418
|
+
Clear all keys in the current namespace.
|
|
419
|
+
|
|
420
|
+
```js
|
|
421
|
+
await keyv.clear();
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
## .clearExpired()
|
|
425
|
+
|
|
426
|
+
Utility helper method to delete all expired entries from the store. This removes any rows where the `expires` column is set and the timestamp is in the past. This is useful for periodic cleanup of expired data.
|
|
427
|
+
|
|
428
|
+
```js
|
|
429
|
+
await keyv.clearExpired();
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
## .iterator(namespace?)
|
|
433
|
+
|
|
434
|
+
Iterate over all key-value pairs, optionally filtered by namespace. Uses cursor-based pagination controlled by the `iterationLimit` property.
|
|
435
|
+
|
|
436
|
+
```js
|
|
437
|
+
const iterator = keyv.iterator();
|
|
438
|
+
for await (const [key, value] of iterator) {
|
|
439
|
+
console.log(key, value);
|
|
440
|
+
}
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
## .disconnect()
|
|
444
|
+
|
|
445
|
+
Disconnect from the PostgreSQL database and release the connection pool.
|
|
446
|
+
|
|
447
|
+
```js
|
|
448
|
+
await keyv.disconnect();
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
# Using an Unlogged Table for Performance
|
|
57
452
|
|
|
58
453
|
By default, the adapter creates a logged table. If you want to use an unlogged table for performance, you can pass the `useUnloggedTable` option to the constructor.
|
|
59
454
|
|
|
60
455
|
```js
|
|
61
456
|
const keyvPostgres = new KeyvPostgres({ uri: 'postgresql://user:pass@localhost:5432/dbname', useUnloggedTable: true });
|
|
62
|
-
const keyv = new Keyv(keyvPostgres);
|
|
457
|
+
const keyv = new Keyv({ store: keyvPostgres });
|
|
63
458
|
```
|
|
64
459
|
|
|
65
460
|
From the [PostgreSQL documentation](https://www.postgresql.org/docs/current/sql-createtable.html#SQL-CREATETABLE-UNLOGGED):
|
|
@@ -68,15 +463,31 @@ If specified, the table is created as an unlogged table. Data written to unlogge
|
|
|
68
463
|
|
|
69
464
|
If this is specified, any sequences created together with the unlogged table (for identity or serial columns) are also created as unlogged.
|
|
70
465
|
|
|
71
|
-
|
|
466
|
+
# Connection Pooling
|
|
72
467
|
|
|
73
468
|
The adapter automatically uses the default settings on the `pg` package for connection pooling. You can override these settings by passing the options to the constructor such as setting the `max` pool size.
|
|
74
469
|
|
|
75
470
|
```js
|
|
76
|
-
const keyv = new Keyv(new KeyvPostgres({ uri: 'postgresql://user:pass@localhost:5432/dbname', max: 20 }));
|
|
471
|
+
const keyv = new Keyv({ store: new KeyvPostgres({ uri: 'postgresql://user:pass@localhost:5432/dbname', max: 20 }) });
|
|
77
472
|
```
|
|
78
473
|
|
|
79
|
-
|
|
474
|
+
# SSL/TLS Connections
|
|
475
|
+
|
|
476
|
+
You can configure SSL/TLS connections by passing the `ssl` option. This is passed directly to the underlying `pg` driver.
|
|
477
|
+
|
|
478
|
+
```js
|
|
479
|
+
const keyvPostgres = new KeyvPostgres({
|
|
480
|
+
uri: 'postgresql://user:pass@localhost:5432/dbname',
|
|
481
|
+
ssl: {
|
|
482
|
+
rejectUnauthorized: false,
|
|
483
|
+
},
|
|
484
|
+
});
|
|
485
|
+
const keyv = new Keyv({ store: keyvPostgres });
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
For more details on SSL configuration, see the [node-postgres SSL documentation](https://node-postgres.com/features/ssl).
|
|
489
|
+
|
|
490
|
+
# Testing
|
|
80
491
|
|
|
81
492
|
When testing you can use our `docker compose` postgresql instance by having docker installed and running. This will start a postgres server, run the tests, and stop the server:
|
|
82
493
|
|
|
@@ -85,11 +496,11 @@ At the root of the Keyv mono repo:
|
|
|
85
496
|
pnpm test:services:start
|
|
86
497
|
```
|
|
87
498
|
|
|
88
|
-
To just test the postgres adapter go to the postgres directory (
|
|
499
|
+
To just test the postgres adapter go to the postgres directory (storage/postgres) and run:
|
|
89
500
|
```shell
|
|
90
501
|
pnpm test
|
|
91
502
|
```
|
|
92
503
|
|
|
93
|
-
|
|
504
|
+
# License
|
|
94
505
|
|
|
95
506
|
[MIT © Jared Wray](LISCENCE)
|