@remix-run/data-table-postgres 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -16
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/lib/database.d.ts +35 -0
- package/dist/lib/database.d.ts.map +1 -0
- package/dist/lib/database.js +31 -0
- package/dist/lib/{adapter.d.ts → driver.d.ts} +40 -38
- package/dist/lib/driver.d.ts.map +1 -0
- package/dist/lib/driver.js +577 -0
- package/dist/lib/sql-compiler.d.ts +2 -1
- package/dist/lib/sql-compiler.d.ts.map +1 -1
- package/dist/lib/sql-compiler.js +6 -6
- package/package.json +12 -12
- package/src/index.ts +3 -1
- package/src/lib/database.ts +45 -0
- package/src/lib/driver.ts +760 -0
- package/src/lib/sql-compiler.ts +8 -7
- package/dist/lib/adapter.d.ts.map +0 -1
- package/dist/lib/adapter.js +0 -343
- package/src/lib/adapter.ts +0 -454
package/README.md
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
# data-table-postgres
|
|
2
2
|
|
|
3
|
-
PostgreSQL
|
|
4
|
-
Use this package when you want `data-table` APIs backed by `pg`.
|
|
3
|
+
PostgreSQL database driver for [`remix/data-table`](https://github.com/remix-run/remix/tree/main/packages/data-table), backed by `pg`.
|
|
5
4
|
|
|
6
5
|
## Features
|
|
7
6
|
|
|
8
|
-
- **Native `pg` Integration**:
|
|
7
|
+
- **Native `pg` Integration**: Creates a pool from `pg` configuration or uses an existing pool or client
|
|
9
8
|
- **Full `data-table` API Support**: Queries, relations, writes, and transactions
|
|
10
|
-
- **
|
|
9
|
+
- **PostgreSQL Compiler**: SQL compilation is handled automatically for PostgreSQL
|
|
11
10
|
- **Multi-Statement Migrations**: `executeScript()` runs `up.sql` / `down.sql` files natively via `pg`
|
|
12
11
|
- **Postgres Capabilities Enabled By Default**:
|
|
13
12
|
- `returning: true`
|
|
@@ -25,21 +24,20 @@ npm i remix pg
|
|
|
25
24
|
## Usage
|
|
26
25
|
|
|
27
26
|
```ts
|
|
28
|
-
import {
|
|
29
|
-
import { createDatabase } from 'remix/data-table'
|
|
30
|
-
import { createPostgresDatabaseAdapter } from 'remix/data-table/postgres'
|
|
27
|
+
import { createPostgresDatabase } from 'remix/data-table/postgres'
|
|
31
28
|
|
|
32
|
-
let
|
|
29
|
+
let db = createPostgresDatabase({
|
|
33
30
|
connectionString: process.env.DATABASE_URL,
|
|
34
31
|
})
|
|
35
|
-
|
|
36
|
-
let db = createDatabase(createPostgresDatabaseAdapter(pool))
|
|
37
32
|
```
|
|
38
33
|
|
|
39
|
-
Use `db.query(...)`, relation loading, and transactions from `remix/data-table`.
|
|
40
|
-
|
|
34
|
+
Use `db.query(...)`, relation loading, and transactions from `remix/data-table`. Import any driver-specific types you need directly from `pg`.
|
|
35
|
+
|
|
36
|
+
Config-backed databases support `db.wipe()` and `db.reset()`. Call `await db.close()` during application shutdown to close the internally created pool. You may pass an existing `pg` pool or client when your application owns the driver lifecycle; `db.close()` leaves supplied clients alone, and destructive lifecycle methods are unavailable in that mode. `db.wipe()` requires a database name resolvable from the connection config (`database`, the path of `connectionString`, or the `PGDATABASE` environment variable) and throws when none is present.
|
|
41
37
|
|
|
42
|
-
|
|
38
|
+
Migration runs reserve one connection for the PostgreSQL advisory lock, migration SQL, and journal updates. Lock acquisition waits up to 60 seconds (via `lock_timeout`) and fails with an error instead of blocking forever. After a successful run the connection is unlocked and returned to the pool; if the migration or unlock fails, the reserved connection is destroyed instead of being reused, so a dirty session can never leak back into the pool. Nested migration lock acquisition throws instead of deadlocking.
|
|
39
|
+
|
|
40
|
+
## Database Capabilities
|
|
43
41
|
|
|
44
42
|
`data-table-postgres` reports this capability set by default:
|
|
45
43
|
|
|
@@ -53,7 +51,7 @@ Import any driver-specific types you need directly from `pg`.
|
|
|
53
51
|
|
|
54
52
|
### Transaction Options
|
|
55
53
|
|
|
56
|
-
Transaction options are passed through to
|
|
54
|
+
Transaction options are passed through to PostgreSQL as hints.
|
|
57
55
|
|
|
58
56
|
```ts
|
|
59
57
|
await db.transaction(async (txDb) => txDb.exec('select 1'), {
|
|
@@ -62,12 +60,38 @@ await db.transaction(async (txDb) => txDb.exec('select 1'), {
|
|
|
62
60
|
})
|
|
63
61
|
```
|
|
64
62
|
|
|
63
|
+
## Running integration tests locally
|
|
64
|
+
|
|
65
|
+
To start a local Postgres container matching CI:
|
|
66
|
+
|
|
67
|
+
```sh
|
|
68
|
+
podman run --name postgres \
|
|
69
|
+
-e POSTGRES_USER=postgres \
|
|
70
|
+
-e POSTGRES_PASSWORD=postgres \
|
|
71
|
+
-e POSTGRES_DB=remix \
|
|
72
|
+
-p 5432:5432 \
|
|
73
|
+
-d postgres:16
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Then run:
|
|
77
|
+
|
|
78
|
+
```sh
|
|
79
|
+
REMIX_DATA_TABLE_POSTGRES_TEST_URL=postgres://postgres:postgres@127.0.0.1:5432/remix \
|
|
80
|
+
pnpm test src/lib/driver.integration.test.ts
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Remove the container when you are done:
|
|
84
|
+
|
|
85
|
+
```sh
|
|
86
|
+
podman rm -f postgres
|
|
87
|
+
```
|
|
88
|
+
|
|
65
89
|
## Related Packages
|
|
66
90
|
|
|
67
91
|
- [`data-table`](https://github.com/remix-run/remix/tree/main/packages/data-table) - Core query/relations API
|
|
68
92
|
- [`data-schema`](https://github.com/remix-run/remix/tree/main/packages/data-schema) - Schema parsing and validation
|
|
69
|
-
- [`data-table-mysql`](https://github.com/remix-run/remix/tree/main/packages/data-table-mysql) - MySQL
|
|
70
|
-
- [`data-table-sqlite`](https://github.com/remix-run/remix/tree/main/packages/data-table-sqlite) - SQLite
|
|
93
|
+
- [`data-table-mysql`](https://github.com/remix-run/remix/tree/main/packages/data-table-mysql) - MySQL database driver
|
|
94
|
+
- [`data-table-sqlite`](https://github.com/remix-run/remix/tree/main/packages/data-table-sqlite) - SQLite database driver
|
|
71
95
|
|
|
72
96
|
## License
|
|
73
97
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,4 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { createPostgresDatabase, PostgresDatabase } from './lib/database.ts';
|
|
2
|
+
export type { PostgresDatabaseOptions } from './lib/database.ts';
|
|
3
|
+
export type { PostgresDatabaseInput } from './lib/driver.ts';
|
|
2
4
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAC5E,YAAY,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAA;AAChE,YAAY,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { createPostgresDatabase, PostgresDatabase } from './lib/database.js';
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Database, type DatabaseOptions } from '@remix-run/data-table';
|
|
2
|
+
import { type PostgresDatabaseInput } from './driver.ts';
|
|
3
|
+
/** Options for creating a PostgreSQL database. */
|
|
4
|
+
export interface PostgresDatabaseOptions extends DatabaseOptions {
|
|
5
|
+
/** Database used while dropping and recreating the configured database (`postgres` by default). */
|
|
6
|
+
maintenanceDatabase?: string;
|
|
7
|
+
/** Template used to recreate the configured database (`template0` by default). */
|
|
8
|
+
template?: string;
|
|
9
|
+
}
|
|
10
|
+
/** A {@link Database} backed by PostgreSQL. */
|
|
11
|
+
export declare class PostgresDatabase extends Database<'postgres'> {
|
|
12
|
+
/**
|
|
13
|
+
* Creates a PostgreSQL-backed database.
|
|
14
|
+
* @param input PostgreSQL pool configuration, pool, or client.
|
|
15
|
+
* @param options Database runtime and recreation options.
|
|
16
|
+
*/
|
|
17
|
+
constructor(input: PostgresDatabaseInput, options?: PostgresDatabaseOptions);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Creates a PostgreSQL-backed database.
|
|
21
|
+
*
|
|
22
|
+
* @param input PostgreSQL pool configuration, pool, or client.
|
|
23
|
+
* @param options Database runtime and recreation options.
|
|
24
|
+
* @returns A PostgreSQL database.
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* import { createPostgresDatabase } from 'remix/data-table/postgres'
|
|
28
|
+
*
|
|
29
|
+
* let db = createPostgresDatabase({
|
|
30
|
+
* connectionString: process.env.DATABASE_URL,
|
|
31
|
+
* })
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare function createPostgresDatabase(input: PostgresDatabaseInput, options?: PostgresDatabaseOptions): PostgresDatabase;
|
|
35
|
+
//# sourceMappingURL=database.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/lib/database.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAEtE,OAAO,EAA0B,KAAK,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAEhF,kDAAkD;AAClD,MAAM,WAAW,uBAAwB,SAAQ,eAAe;IAC9D,mGAAmG;IACnG,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,kFAAkF;IAClF,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,+CAA+C;AAC/C,qBAAa,gBAAiB,SAAQ,QAAQ,CAAC,UAAU,CAAC;IACxD;;;;OAIG;IACH,YAAY,KAAK,EAAE,qBAAqB,EAAE,OAAO,GAAE,uBAA4B,EAE9E;CACF;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,qBAAqB,EAC5B,OAAO,GAAE,uBAA4B,GACpC,gBAAgB,CAElB"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Database } from '@remix-run/data-table';
|
|
2
|
+
import { PostgresDatabaseDriver } from './driver.js';
|
|
3
|
+
/** A {@link Database} backed by PostgreSQL. */
|
|
4
|
+
export class PostgresDatabase extends Database {
|
|
5
|
+
/**
|
|
6
|
+
* Creates a PostgreSQL-backed database.
|
|
7
|
+
* @param input PostgreSQL pool configuration, pool, or client.
|
|
8
|
+
* @param options Database runtime and recreation options.
|
|
9
|
+
*/
|
|
10
|
+
constructor(input, options = {}) {
|
|
11
|
+
super(new PostgresDatabaseDriver(input, options), options);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Creates a PostgreSQL-backed database.
|
|
16
|
+
*
|
|
17
|
+
* @param input PostgreSQL pool configuration, pool, or client.
|
|
18
|
+
* @param options Database runtime and recreation options.
|
|
19
|
+
* @returns A PostgreSQL database.
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* import { createPostgresDatabase } from 'remix/data-table/postgres'
|
|
23
|
+
*
|
|
24
|
+
* let db = createPostgresDatabase({
|
|
25
|
+
* connectionString: process.env.DATABASE_URL,
|
|
26
|
+
* })
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export function createPostgresDatabase(input, options = {}) {
|
|
30
|
+
return new PostgresDatabase(input, options);
|
|
31
|
+
}
|
|
@@ -1,26 +1,36 @@
|
|
|
1
|
-
import type { DataManipulationRequest, DataManipulationResult,
|
|
1
|
+
import type { DataManipulationOperation, DataManipulationRequest, DataManipulationResult, DatabaseDriver, SqlStatement, TableRef, TransactionOptions, TransactionToken } from '@remix-run/data-table';
|
|
2
|
+
import pg from 'pg';
|
|
2
3
|
import type { Client as PostgresClient, Pool as PostgresPool, PoolClient as PostgresPoolClient } from 'pg';
|
|
4
|
+
type PostgresPoolConfig = ConstructorParameters<typeof pg.Pool>[0];
|
|
5
|
+
/** Database recreation options for a config-backed PostgreSQL driver. */
|
|
6
|
+
export interface PostgresDatabaseDriverOptions {
|
|
7
|
+
/** Database used while dropping and recreating the configured database (`postgres` by default). */
|
|
8
|
+
maintenanceDatabase?: string;
|
|
9
|
+
/** Template used to recreate the configured database (`template0` by default). */
|
|
10
|
+
template?: string;
|
|
11
|
+
}
|
|
3
12
|
type PostgresQueryable = PostgresClient | PostgresPool | PostgresPoolClient;
|
|
13
|
+
export type PostgresDatabaseInput = PostgresPoolConfig | PostgresQueryable;
|
|
4
14
|
/**
|
|
5
|
-
*
|
|
15
|
+
* PostgreSQL database driver backed by a postgres-compatible client.
|
|
6
16
|
*/
|
|
7
|
-
export declare class
|
|
17
|
+
export declare class PostgresDatabaseDriver implements DatabaseDriver<'postgres'> {
|
|
8
18
|
#private;
|
|
9
19
|
/**
|
|
10
|
-
* The SQL dialect identifier reported by this
|
|
20
|
+
* The SQL dialect identifier reported by this database.
|
|
11
21
|
*/
|
|
12
|
-
dialect:
|
|
22
|
+
get dialect(): 'postgres';
|
|
13
23
|
/**
|
|
14
|
-
* Feature flags describing the
|
|
24
|
+
* Feature flags describing the PostgreSQL behaviors supported by this database.
|
|
15
25
|
*/
|
|
16
|
-
capabilities: {
|
|
17
|
-
returning:
|
|
18
|
-
savepoints:
|
|
19
|
-
upsert:
|
|
20
|
-
transactionalDdl:
|
|
21
|
-
migrationLock:
|
|
22
|
-
}
|
|
23
|
-
constructor(
|
|
26
|
+
get capabilities(): Readonly<{
|
|
27
|
+
returning: true;
|
|
28
|
+
savepoints: true;
|
|
29
|
+
upsert: true;
|
|
30
|
+
transactionalDdl: true;
|
|
31
|
+
migrationLock: true;
|
|
32
|
+
}>;
|
|
33
|
+
constructor(config: PostgresDatabaseInput, options?: PostgresDatabaseDriverOptions);
|
|
24
34
|
/**
|
|
25
35
|
* Compiles a data-manipulation operation to postgres SQL statements.
|
|
26
36
|
* @param operation Operation to compile.
|
|
@@ -98,32 +108,24 @@ export declare class PostgresDatabaseAdapter implements DatabaseAdapter {
|
|
|
98
108
|
*/
|
|
99
109
|
releaseSavepoint(token: TransactionToken, name: string): Promise<void>;
|
|
100
110
|
/**
|
|
101
|
-
*
|
|
102
|
-
* @returns A promise that resolves when the
|
|
111
|
+
* Destructively recreates the configured PostgreSQL database.
|
|
112
|
+
* @returns A promise that resolves when the database is ready for use.
|
|
103
113
|
*/
|
|
104
|
-
|
|
114
|
+
wipe(): Promise<void>;
|
|
115
|
+
/** Closes a pool created from configuration. Supplied clients and pools remain caller-owned. */
|
|
116
|
+
close(): Promise<void>;
|
|
105
117
|
/**
|
|
106
|
-
*
|
|
107
|
-
*
|
|
118
|
+
* Runs migration work on the postgres connection that owns the advisory lock.
|
|
119
|
+
*
|
|
120
|
+
* Lock acquisition waits up to 60 seconds and throws when the lock cannot
|
|
121
|
+
* be acquired. Re-entering this method from inside `run` throws instead of
|
|
122
|
+
* deadlocking, and a failed run destroys the reserved connection instead of
|
|
123
|
+
* returning it to the pool.
|
|
124
|
+
* @param name Logical migration lock name.
|
|
125
|
+
* @param run Migration work to run with a connection-bound driver.
|
|
126
|
+
* @returns The callback result.
|
|
108
127
|
*/
|
|
109
|
-
|
|
128
|
+
withMigrationLock<result>(name: string, run: (driver: DatabaseDriver<'postgres'>) => Promise<result>): Promise<result>;
|
|
110
129
|
}
|
|
111
|
-
/**
|
|
112
|
-
* Creates a postgres `DatabaseAdapter`.
|
|
113
|
-
* @param client `pg` pool or pool client.
|
|
114
|
-
* @param options Optional adapter capability overrides.
|
|
115
|
-
* @returns A configured postgres adapter.
|
|
116
|
-
* @example
|
|
117
|
-
* ```ts
|
|
118
|
-
* import { Pool } from 'pg'
|
|
119
|
-
* import { createDatabase } from 'remix/data-table'
|
|
120
|
-
* import { createPostgresDatabaseAdapter } from 'remix/data-table/postgres'
|
|
121
|
-
*
|
|
122
|
-
* let pool = new Pool({ connectionString: process.env.DATABASE_URL })
|
|
123
|
-
* let adapter = createPostgresDatabaseAdapter(pool)
|
|
124
|
-
* let db = createDatabase(adapter)
|
|
125
|
-
* ```
|
|
126
|
-
*/
|
|
127
|
-
export declare function createPostgresDatabaseAdapter(client: PostgresQueryable): PostgresDatabaseAdapter;
|
|
128
130
|
export {};
|
|
129
|
-
//# sourceMappingURL=
|
|
131
|
+
//# sourceMappingURL=driver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"driver.d.ts","sourceRoot":"","sources":["../../src/lib/driver.ts"],"names":[],"mappings":"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"}
|