Skip to content

Commit d0b8ab0

Browse files
authored
feat: update postgres client (#9)
1 parent 6b54e03 commit d0b8ab0

15 files changed

Lines changed: 214 additions & 251 deletions

README.md

Lines changed: 11 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,28 @@
44
[![Latest version](https://deno.land/badge/kysely_deno_postgres_dialect/version)](https://deno.land/x/kysely_deno_postgres_dialect)
55

66
[Kysely](https://github.com/kysely-org/kysely) dialect for PostgreSQL using the
7-
[deno-postgres](https://github.com/denodrivers/postgres) client.
7+
[postgresjs](https://github.com/porsager/postgres) client.
88

99
## 🚀 Getting started
1010

1111
```typescript
1212
import {
13-
KyselyDenoPostgresDialect,
13+
PostgresJSDialect,
1414
setup,
15-
} from "https://deno.land/x/kysely_deno_postgres_dialect/mod.ts";
15+
} from "https://deno.land/x/kysely_postgrs_js_dialect/mod.ts";
16+
import postgres from "https://deno.land/x/postgresjs@v3.4.4/mod.js";
1617

1718
setup(() => {
18-
const dialect = new KyselyDenoPostgresDialect({
19-
pool: new Pool(
19+
const dialect = new PostgresJSDialect({
20+
postgres: postgres(
2021
{
2122
database: "postgres",
2223
hostname: "localhost",
2324
password: "postgres",
2425
port: 5432,
2526
user: "postgres",
27+
max: 10,
2628
},
27-
10,
28-
true,
2929
),
3030
});
3131

@@ -47,44 +47,31 @@ See detail at `./tests/testing/utils_test.ts`.
4747
4848
```typescript
4949
import {
50-
KyselyDenoPostgresDialect,
51-
PostgresConnection,
50+
PostgresJSDialect,
5251
setup,
5352
wrapTransaction,
5453
} from "https://deno.land/x/kysely_deno_postgres_dialect/mod.ts";
5554
import { setupTesting } from "https://deno.land/x/kysely_deno_postgres_dialect/testing.ts";
5655

57-
const connections: PostgresConnection[] = [];
58-
5956
setup(() => {
60-
const dialect = new KyselyDenoPostgresDialect({
61-
pool: new Pool(
57+
const dialect = new PostgresJSDialect({
58+
postgres: postgres(
6259
{
6360
database: "postgres",
6461
hostname: "localhost",
6562
password: "postgres",
6663
port: 5432,
6764
user: "postgres",
65+
max: 10,
6866
},
69-
10,
70-
true,
7167
),
72-
onCreateConnection: (connection: DatabaseConnection) => {
73-
connections.push(connection as PostgresConnection);
74-
},
7568
});
7669

7770
return new Kysely<Database>({
7871
dialect,
7972
});
8073
});
8174

82-
async function endConnections() {
83-
for (const connection of connections) {
84-
await connection.end();
85-
}
86-
}
87-
8875
// test files
8976

9077
const {
@@ -106,7 +93,6 @@ describe("tests", () => {
10693
});
10794
afterEach(async () => {
10895
// note: fix Leaking resources error
109-
await endConnections();
11096
await afterEachFn();
11197
});
11298

deps.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
export type {
2+
ReservedSql,
3+
Sql,
4+
} from "https://deno.land/x/postgresjs@v3.4.4/types/index.d.ts";
15
export {
26
CompiledQuery,
37
type DatabaseConnection,
@@ -13,8 +17,7 @@ export {
1317
type QueryResult,
1418
Transaction,
1519
type TransactionSettings,
16-
} from "https://esm.sh/kysely@0.27.0";
17-
export { Pool, PoolClient } from "https://deno.land/x/postgres@v0.17.0/mod.ts";
20+
} from "https://cdn.jsdelivr.net/npm/kysely@0.27.3/dist/esm/index.js";
1821

19-
export * as kysely from "https://esm.sh/kysely@0.27.0";
20-
export * as postgres from "https://deno.land/x/postgres@v0.17.0/mod.ts";
22+
export * as kysely from "https://cdn.jsdelivr.net/npm/kysely@0.27.3/dist/esm/index.js";
23+
export { default as postgres } from "https://deno.land/x/postgresjs@v3.4.4/mod.js";

mod.ts

Lines changed: 6 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,8 @@
1-
import {
2-
DatabaseIntrospector,
3-
Dialect,
4-
DialectAdapter,
5-
Driver,
6-
Kysely,
7-
PostgresAdapter,
8-
PostgresIntrospector,
9-
PostgresQueryCompiler,
10-
QueryCompiler,
11-
} from "./deps.ts";
12-
13-
import { PostgresDriver } from "./src/postgres-driver.ts";
14-
import { PostgresDialectConfig } from "./src/postgres-dialect-config.ts";
15-
16-
export { type DatabaseConnection, kysely, Pool, postgres } from "./deps.ts";
17-
export { type PostgresConnection } from "./src/postgres-connection.ts";
18-
19-
export class KyselyDenoPostgresDialect implements Dialect {
20-
readonly #config: PostgresDialectConfig;
21-
22-
constructor(config: PostgresDialectConfig) {
23-
this.#config = config;
24-
}
25-
26-
createDriver(): Driver {
27-
return new PostgresDriver(this.#config);
28-
}
29-
30-
createQueryCompiler(): QueryCompiler {
31-
return new PostgresQueryCompiler();
32-
}
33-
34-
createAdapter(): DialectAdapter {
35-
return new PostgresAdapter();
36-
}
37-
38-
// deno-lint-ignore no-explicit-any
39-
createIntrospector(db: Kysely<any>): DatabaseIntrospector {
40-
return new PostgresIntrospector(db);
41-
}
42-
}
1+
export { type DatabaseConnection, kysely, postgres } from "./deps.ts";
2+
export {
3+
PostgresJSConnection,
4+
PostgresJSDialect,
5+
PostgresJSDialectError,
6+
} from "./src/mod.ts";
437

448
export { getDB, setup, wrapTransaction } from "./src/utils.ts";

src/connection.ts

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import {
2+
CompiledQuery,
3+
DatabaseConnection,
4+
QueryResult,
5+
ReservedSql,
6+
TransactionSettings,
7+
} from "../deps.ts";
8+
import { PostgresJSDialectError } from "./errors.ts";
9+
10+
export class PostgresJSConnection implements DatabaseConnection {
11+
#reservedConnection: ReservedSql;
12+
13+
constructor(reservedConnection: ReservedSql) {
14+
this.#reservedConnection = reservedConnection;
15+
}
16+
17+
async beginTransaction(settings: TransactionSettings): Promise<void> {
18+
const { isolationLevel } = settings;
19+
20+
const compiledQuery = CompiledQuery.raw(
21+
isolationLevel
22+
? `start transaction isolation level ${isolationLevel}`
23+
: "begin",
24+
);
25+
26+
await this.executeQuery(compiledQuery);
27+
}
28+
29+
async commitTransaction(): Promise<void> {
30+
await this.executeQuery(CompiledQuery.raw("commit"));
31+
}
32+
33+
async executeQuery<R>(
34+
compiledQuery: CompiledQuery<unknown>,
35+
): Promise<QueryResult<R>> {
36+
const result = await this.#reservedConnection.unsafe<R[]>(
37+
compiledQuery.sql,
38+
// deno-lint-ignore no-explicit-any
39+
compiledQuery.parameters.slice() as any,
40+
);
41+
42+
const rows = Array.from(result.values());
43+
44+
if (["INSERT", "UPDATE", "DELETE"].includes(result.command)) {
45+
const numAffectedRows = BigInt(result.count);
46+
47+
return { numAffectedRows, rows };
48+
}
49+
50+
return { rows };
51+
}
52+
53+
releaseConnection(): void {
54+
this.#reservedConnection.release();
55+
56+
this.#reservedConnection = null!;
57+
}
58+
59+
async rollbackTransaction(): Promise<void> {
60+
await this.executeQuery(CompiledQuery.raw("rollback"));
61+
}
62+
63+
async *streamQuery<R>(
64+
compiledQuery: CompiledQuery<unknown>,
65+
chunkSize: number,
66+
): AsyncIterableIterator<QueryResult<R>> {
67+
if (!Number.isInteger(chunkSize) || chunkSize <= 0) {
68+
throw new PostgresJSDialectError("chunkSize must be a positive integer");
69+
}
70+
71+
const cursor = this.#reservedConnection
72+
// deno-lint-ignore no-explicit-any
73+
.unsafe<R[]>(compiledQuery.sql, compiledQuery.parameters.slice() as any)
74+
.cursor(chunkSize);
75+
76+
for await (const rows of cursor) {
77+
yield { rows };
78+
}
79+
}
80+
}

src/dialect.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import {
2+
type DatabaseIntrospector,
3+
type Dialect,
4+
type DialectAdapter,
5+
type Driver,
6+
type Kysely,
7+
PostgresAdapter,
8+
PostgresIntrospector,
9+
PostgresQueryCompiler,
10+
type QueryCompiler,
11+
} from "../deps.ts";
12+
import { PostgresJSDriver } from "./driver.ts";
13+
import type { PostgresJSDialectConfig } from "./types.ts";
14+
import { freeze } from "./postgres-utils.ts";
15+
16+
export class PostgresJSDialect implements Dialect {
17+
readonly #config: PostgresJSDialectConfig;
18+
19+
constructor(config: PostgresJSDialectConfig) {
20+
this.#config = freeze({ ...config });
21+
}
22+
23+
createAdapter(): DialectAdapter {
24+
return new PostgresAdapter();
25+
}
26+
27+
createDriver(): Driver {
28+
return new PostgresJSDriver(this.#config);
29+
}
30+
31+
// deno-lint-ignore no-explicit-any
32+
createIntrospector(db: Kysely<any>): DatabaseIntrospector {
33+
return new PostgresIntrospector(db);
34+
}
35+
36+
createQueryCompiler(): QueryCompiler {
37+
return new PostgresQueryCompiler();
38+
}
39+
}

src/driver.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import type { Driver, TransactionSettings } from "../deps.ts";
2+
import { PostgresJSConnection } from "./connection.ts";
3+
import type { PostgresJSDialectConfig } from "./types.ts";
4+
import { freeze } from "./postgres-utils.ts";
5+
6+
export class PostgresJSDriver implements Driver {
7+
readonly #config: PostgresJSDialectConfig;
8+
9+
constructor(config: PostgresJSDialectConfig) {
10+
this.#config = freeze({ ...config });
11+
}
12+
13+
async init(): Promise<void> {
14+
// noop
15+
}
16+
17+
async acquireConnection(): Promise<PostgresJSConnection> {
18+
const reservedConnection = await this.#config.postgres.reserve();
19+
20+
return new PostgresJSConnection(reservedConnection);
21+
}
22+
23+
async beginTransaction(
24+
connection: PostgresJSConnection,
25+
settings: TransactionSettings,
26+
): Promise<void> {
27+
await connection.beginTransaction(settings);
28+
}
29+
30+
async commitTransaction(connection: PostgresJSConnection): Promise<void> {
31+
await connection.commitTransaction();
32+
}
33+
34+
async rollbackTransaction(connection: PostgresJSConnection): Promise<void> {
35+
await connection.rollbackTransaction();
36+
}
37+
38+
// deno-lint-ignore require-await
39+
async releaseConnection(connection: PostgresJSConnection): Promise<void> {
40+
connection.releaseConnection();
41+
}
42+
43+
async destroy(): Promise<void> {
44+
await this.#config.postgres.end();
45+
}
46+
}

src/errors.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export class PostgresJSDialectError extends Error {
2+
constructor(message: string) {
3+
super(message);
4+
this.name = "PostgresJSDialectError";
5+
}
6+
}

src/mod.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export * from "./connection.ts";
2+
export * from "./dialect.ts";
3+
export * from "./driver.ts";
4+
export * from "./errors.ts";
5+
export type * from "./types.ts";

0 commit comments

Comments
 (0)