@effect/sql-pg 0.50.3 → 4.0.0-beta.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/dist/{dts/PgClient.d.ts → PgClient.d.ts} +20 -25
- package/dist/PgClient.d.ts.map +1 -0
- package/dist/{esm/PgClient.js → PgClient.js} +118 -144
- package/dist/PgClient.js.map +1 -0
- package/dist/PgMigrator.d.ts +23 -0
- package/dist/PgMigrator.d.ts.map +1 -0
- package/dist/PgMigrator.js +74 -0
- package/dist/PgMigrator.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/{esm/index.js → index.js} +4 -0
- package/dist/index.js.map +1 -0
- package/package.json +56 -54
- package/src/PgClient.ts +332 -377
- package/src/PgMigrator.ts +63 -74
- package/src/index.ts +8 -2
- package/PgClient/package.json +0 -6
- package/PgMigrator/package.json +0 -6
- package/dist/cjs/PgClient.js +0 -434
- package/dist/cjs/PgClient.js.map +0 -1
- package/dist/cjs/PgMigrator.js +0 -104
- package/dist/cjs/PgMigrator.js.map +0 -1
- package/dist/cjs/index.js +0 -12
- package/dist/cjs/index.js.map +0 -1
- package/dist/dts/PgClient.d.ts.map +0 -1
- package/dist/dts/PgMigrator.d.ts +0 -28
- package/dist/dts/PgMigrator.d.ts.map +0 -1
- package/dist/dts/index.d.ts +0 -9
- package/dist/dts/index.d.ts.map +0 -1
- package/dist/esm/PgClient.js.map +0 -1
- package/dist/esm/PgMigrator.js +0 -68
- package/dist/esm/PgMigrator.js.map +0 -1
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/package.json +0 -4
- package/index/package.json +0 -6
package/src/PgMigrator.ts
CHANGED
|
@@ -1,28 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @since 1.0.0
|
|
3
3
|
*/
|
|
4
|
-
import * as
|
|
5
|
-
import type { CommandExecutor } from "@effect/platform/CommandExecutor"
|
|
6
|
-
import { FileSystem } from "@effect/platform/FileSystem"
|
|
7
|
-
import { Path } from "@effect/platform/Path"
|
|
8
|
-
import * as Migrator from "@effect/sql/Migrator"
|
|
9
|
-
import type * as Client from "@effect/sql/SqlClient"
|
|
10
|
-
import type { SqlError } from "@effect/sql/SqlError"
|
|
11
|
-
import * as Effect from "effect/Effect"
|
|
12
|
-
import { pipe } from "effect/Function"
|
|
4
|
+
import type * as Effect from "effect/Effect"
|
|
13
5
|
import * as Layer from "effect/Layer"
|
|
14
|
-
import * as
|
|
15
|
-
import
|
|
6
|
+
import * as Migrator from "effect/unstable/sql/Migrator"
|
|
7
|
+
import type * as Client from "effect/unstable/sql/SqlClient"
|
|
8
|
+
import type { SqlError } from "effect/unstable/sql/SqlError"
|
|
16
9
|
|
|
17
10
|
/**
|
|
18
11
|
* @since 1.0.0
|
|
19
12
|
*/
|
|
20
|
-
export * from "
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* @since 1.0.0
|
|
24
|
-
*/
|
|
25
|
-
export * from "@effect/sql/Migrator/FileSystem"
|
|
13
|
+
export * from "effect/unstable/sql/Migrator"
|
|
26
14
|
|
|
27
15
|
/**
|
|
28
16
|
* @category constructor
|
|
@@ -33,63 +21,64 @@ export const run: <R2 = never>(
|
|
|
33
21
|
) => Effect.Effect<
|
|
34
22
|
ReadonlyArray<readonly [id: number, name: string]>,
|
|
35
23
|
Migrator.MigrationError | SqlError,
|
|
36
|
-
|
|
24
|
+
Client.SqlClient | R2
|
|
37
25
|
> = Migrator.make({
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
26
|
+
// TODO: Wait for Command module
|
|
27
|
+
// dumpSchema(path, table) {
|
|
28
|
+
// const pgDump = (args: Array<string>) =>
|
|
29
|
+
// Effect.gen(function*() {
|
|
30
|
+
// const sql = yield* PgClient
|
|
31
|
+
// const dump = yield* pipe(
|
|
32
|
+
// Command.make("pg_dump", ...args, "--no-owner", "--no-privileges"),
|
|
33
|
+
// Command.env({
|
|
34
|
+
// PATH: (globalThis as any).process?.env.PATH,
|
|
35
|
+
// PGHOST: sql.config.host,
|
|
36
|
+
// PGPORT: sql.config.port?.toString(),
|
|
37
|
+
// PGUSER: sql.config.username,
|
|
38
|
+
// PGPASSWORD: sql.config.password
|
|
39
|
+
// ? Redacted.value(sql.config.password)
|
|
40
|
+
// : undefined,
|
|
41
|
+
// PGDATABASE: sql.config.database,
|
|
42
|
+
// PGSSLMODE: sql.config.ssl ? "require" : "prefer"
|
|
43
|
+
// }),
|
|
44
|
+
// Command.string
|
|
45
|
+
// )
|
|
46
|
+
//
|
|
47
|
+
// return dump.replace(/^--.*$/gm, "")
|
|
48
|
+
// .replace(/^SET .*$/gm, "")
|
|
49
|
+
// .replace(/^SELECT pg_catalog\..*$/gm, "")
|
|
50
|
+
// .replace(/\n{2,}/gm, "\n\n")
|
|
51
|
+
// .trim()
|
|
52
|
+
// }).pipe(
|
|
53
|
+
// Effect.mapError((error) => new Migrator.MigrationError({ kind: "Failed", message: error.message }))
|
|
54
|
+
// )
|
|
55
|
+
//
|
|
56
|
+
// const pgDumpSchema = pgDump(["--schema-only"])
|
|
57
|
+
//
|
|
58
|
+
// const pgDumpMigrations = pgDump([
|
|
59
|
+
// "--column-inserts",
|
|
60
|
+
// "--data-only",
|
|
61
|
+
// `--table=${table}`
|
|
62
|
+
// ])
|
|
63
|
+
//
|
|
64
|
+
// const pgDumpAll = Effect.map(
|
|
65
|
+
// Effect.all([pgDumpSchema, pgDumpMigrations], { concurrency: 2 }),
|
|
66
|
+
// ([schema, migrations]) => schema + "\n\n" + migrations
|
|
67
|
+
// )
|
|
68
|
+
//
|
|
69
|
+
// const pgDumpFile = (path: string) =>
|
|
70
|
+
// Effect.gen(function*() {
|
|
71
|
+
// const fs = yield* FileSystem
|
|
72
|
+
// const path_ = yield* Path
|
|
73
|
+
// const dump = yield* pgDumpAll
|
|
74
|
+
// yield* fs.makeDirectory(path_.dirname(path), { recursive: true })
|
|
75
|
+
// yield* fs.writeFileString(path, dump)
|
|
76
|
+
// }).pipe(
|
|
77
|
+
// Effect.mapError((error) => new Migrator.MigrationError({ kind: "Failed", message: error.message }))
|
|
78
|
+
// )
|
|
79
|
+
//
|
|
80
|
+
// return pgDumpFile(path)
|
|
81
|
+
// }
|
|
93
82
|
})
|
|
94
83
|
|
|
95
84
|
/**
|
|
@@ -101,5 +90,5 @@ export const layer = <R>(
|
|
|
101
90
|
): Layer.Layer<
|
|
102
91
|
never,
|
|
103
92
|
Migrator.MigrationError | SqlError,
|
|
104
|
-
|
|
93
|
+
Client.SqlClient | R
|
|
105
94
|
> => Layer.effectDiscard(run(options))
|
package/src/index.ts
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @since 1.0.0
|
|
3
3
|
*/
|
|
4
|
-
|
|
4
|
+
|
|
5
|
+
// @barrel: Auto-generated exports. Do not edit manually.
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @since 1.0.0
|
|
9
|
+
*/
|
|
10
|
+
export * as PgClient from "./PgClient.ts"
|
|
5
11
|
|
|
6
12
|
/**
|
|
7
13
|
* @since 1.0.0
|
|
8
14
|
*/
|
|
9
|
-
export * as PgMigrator from "./PgMigrator.
|
|
15
|
+
export * as PgMigrator from "./PgMigrator.ts"
|
package/PgClient/package.json
DELETED
package/PgMigrator/package.json
DELETED
package/dist/cjs/PgClient.js
DELETED
|
@@ -1,434 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.makeCompiler = exports.make = exports.layerFromPool = exports.layerConfig = exports.layer = exports.fromPool = exports.TypeId = exports.PgClient = void 0;
|
|
7
|
-
var Reactivity = _interopRequireWildcard(require("@effect/experimental/Reactivity"));
|
|
8
|
-
var Client = _interopRequireWildcard(require("@effect/sql/SqlClient"));
|
|
9
|
-
var _SqlError = require("@effect/sql/SqlError");
|
|
10
|
-
var Statement = _interopRequireWildcard(require("@effect/sql/Statement"));
|
|
11
|
-
var Arr = _interopRequireWildcard(require("effect/Array"));
|
|
12
|
-
var Chunk = _interopRequireWildcard(require("effect/Chunk"));
|
|
13
|
-
var Config = _interopRequireWildcard(require("effect/Config"));
|
|
14
|
-
var Context = _interopRequireWildcard(require("effect/Context"));
|
|
15
|
-
var Duration = _interopRequireWildcard(require("effect/Duration"));
|
|
16
|
-
var Effect = _interopRequireWildcard(require("effect/Effect"));
|
|
17
|
-
var Fiber = _interopRequireWildcard(require("effect/Fiber"));
|
|
18
|
-
var Layer = _interopRequireWildcard(require("effect/Layer"));
|
|
19
|
-
var Number = _interopRequireWildcard(require("effect/Number"));
|
|
20
|
-
var Option = _interopRequireWildcard(require("effect/Option"));
|
|
21
|
-
var RcRef = _interopRequireWildcard(require("effect/RcRef"));
|
|
22
|
-
var Redacted = _interopRequireWildcard(require("effect/Redacted"));
|
|
23
|
-
var Scope = _interopRequireWildcard(require("effect/Scope"));
|
|
24
|
-
var Stream = _interopRequireWildcard(require("effect/Stream"));
|
|
25
|
-
var Pg = _interopRequireWildcard(require("pg"));
|
|
26
|
-
var PgConnString = _interopRequireWildcard(require("pg-connection-string"));
|
|
27
|
-
var _pgCursor = _interopRequireDefault(require("pg-cursor"));
|
|
28
|
-
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
29
|
-
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
30
|
-
/**
|
|
31
|
-
* @since 1.0.0
|
|
32
|
-
*/
|
|
33
|
-
|
|
34
|
-
const ATTR_DB_SYSTEM_NAME = "db.system.name";
|
|
35
|
-
const ATTR_DB_NAMESPACE = "db.namespace";
|
|
36
|
-
const ATTR_SERVER_ADDRESS = "server.address";
|
|
37
|
-
const ATTR_SERVER_PORT = "server.port";
|
|
38
|
-
/**
|
|
39
|
-
* @category type ids
|
|
40
|
-
* @since 1.0.0
|
|
41
|
-
*/
|
|
42
|
-
const TypeId = exports.TypeId = "~@effect/sql-pg/PgClient";
|
|
43
|
-
/**
|
|
44
|
-
* @category tags
|
|
45
|
-
* @since 1.0.0
|
|
46
|
-
*/
|
|
47
|
-
const PgClient = exports.PgClient = /*#__PURE__*/Context.GenericTag("@effect/sql-pg/PgClient");
|
|
48
|
-
const makeClient = (pool, config, options) => Effect.gen(function* () {
|
|
49
|
-
const compiler = makeCompiler(options.transformQueryNames, options.transformJson);
|
|
50
|
-
const transformRows = options.transformResultNames ? Statement.defaultTransforms(options.transformResultNames, options.transformJson).array : undefined;
|
|
51
|
-
class ConnectionImpl {
|
|
52
|
-
pg;
|
|
53
|
-
constructor(pg) {
|
|
54
|
-
this.pg = pg;
|
|
55
|
-
}
|
|
56
|
-
runWithClient(f) {
|
|
57
|
-
if (this.pg !== undefined) {
|
|
58
|
-
return Effect.async(resume => {
|
|
59
|
-
f(this.pg, resume);
|
|
60
|
-
return makeCancel(pool, this.pg);
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
return Effect.async(resume => {
|
|
64
|
-
let done = false;
|
|
65
|
-
let cancel = undefined;
|
|
66
|
-
let client = undefined;
|
|
67
|
-
function onError(cause) {
|
|
68
|
-
cleanup(cause);
|
|
69
|
-
resume(Effect.fail(new _SqlError.SqlError({
|
|
70
|
-
cause,
|
|
71
|
-
message: "Connection error"
|
|
72
|
-
})));
|
|
73
|
-
}
|
|
74
|
-
function cleanup(cause) {
|
|
75
|
-
if (!done) client?.release(cause);
|
|
76
|
-
done = true;
|
|
77
|
-
client?.off("error", onError);
|
|
78
|
-
}
|
|
79
|
-
pool.connect((cause, client_) => {
|
|
80
|
-
if (cause) {
|
|
81
|
-
return resume(Effect.fail(new _SqlError.SqlError({
|
|
82
|
-
cause,
|
|
83
|
-
message: "Failed to acquire connection"
|
|
84
|
-
})));
|
|
85
|
-
} else if (!client_) {
|
|
86
|
-
return resume(Effect.fail(new _SqlError.SqlError({
|
|
87
|
-
message: "Failed to acquire connection",
|
|
88
|
-
cause: new Error("No client returned")
|
|
89
|
-
})));
|
|
90
|
-
} else if (done) {
|
|
91
|
-
client_.release();
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
client = client_;
|
|
95
|
-
client.once("error", onError);
|
|
96
|
-
cancel = makeCancel(pool, client);
|
|
97
|
-
f(client, eff => {
|
|
98
|
-
cleanup();
|
|
99
|
-
resume(eff);
|
|
100
|
-
});
|
|
101
|
-
});
|
|
102
|
-
return Effect.suspend(() => {
|
|
103
|
-
if (!cancel) {
|
|
104
|
-
cleanup();
|
|
105
|
-
return Effect.void;
|
|
106
|
-
}
|
|
107
|
-
return Effect.ensuring(cancel, Effect.sync(cleanup));
|
|
108
|
-
});
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
run(query, params) {
|
|
112
|
-
return this.runWithClient((client, resume) => {
|
|
113
|
-
client.query(query, params, (err, result) => {
|
|
114
|
-
if (err) {
|
|
115
|
-
resume(Effect.fail(new _SqlError.SqlError({
|
|
116
|
-
cause: err,
|
|
117
|
-
message: "Failed to execute statement"
|
|
118
|
-
})));
|
|
119
|
-
} else {
|
|
120
|
-
// Multi-statement queries return an array of results
|
|
121
|
-
resume(Effect.succeed(Array.isArray(result) ? result.map(r => r.rows ?? []) : result.rows ?? []));
|
|
122
|
-
}
|
|
123
|
-
});
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
execute(sql, params, transformRows) {
|
|
127
|
-
return transformRows ? Effect.map(this.run(sql, params), transformRows) : this.run(sql, params);
|
|
128
|
-
}
|
|
129
|
-
executeRaw(sql, params) {
|
|
130
|
-
return this.runWithClient((client, resume) => {
|
|
131
|
-
client.query(sql, params, (err, result) => {
|
|
132
|
-
if (err) {
|
|
133
|
-
resume(Effect.fail(new _SqlError.SqlError({
|
|
134
|
-
cause: err,
|
|
135
|
-
message: "Failed to execute statement"
|
|
136
|
-
})));
|
|
137
|
-
} else {
|
|
138
|
-
resume(Effect.succeed(result));
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
executeWithoutTransform(sql, params) {
|
|
144
|
-
return this.run(sql, params);
|
|
145
|
-
}
|
|
146
|
-
executeValues(sql, params) {
|
|
147
|
-
return this.runWithClient((client, resume) => {
|
|
148
|
-
client.query({
|
|
149
|
-
text: sql,
|
|
150
|
-
rowMode: "array",
|
|
151
|
-
values: params
|
|
152
|
-
}, (err, result) => {
|
|
153
|
-
if (err) {
|
|
154
|
-
resume(Effect.fail(new _SqlError.SqlError({
|
|
155
|
-
cause: err,
|
|
156
|
-
message: "Failed to execute statement"
|
|
157
|
-
})));
|
|
158
|
-
} else {
|
|
159
|
-
resume(Effect.succeed(result.rows));
|
|
160
|
-
}
|
|
161
|
-
});
|
|
162
|
-
});
|
|
163
|
-
}
|
|
164
|
-
executeUnprepared(sql, params, transformRows) {
|
|
165
|
-
return this.execute(sql, params, transformRows);
|
|
166
|
-
}
|
|
167
|
-
executeStream(sql, params, transformRows) {
|
|
168
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
169
|
-
const self = this;
|
|
170
|
-
return Effect.gen(function* () {
|
|
171
|
-
const scope = yield* Effect.scope;
|
|
172
|
-
const client = self.pg ?? (yield* reserveRaw);
|
|
173
|
-
yield* Scope.addFinalizer(scope, Effect.promise(() => cursor.close()));
|
|
174
|
-
const cursor = client.query(new _pgCursor.default(sql, params));
|
|
175
|
-
const pull = Effect.async(resume => {
|
|
176
|
-
cursor.read(128, (err, rows) => {
|
|
177
|
-
if (err) {
|
|
178
|
-
resume(Effect.fail(Option.some(new _SqlError.SqlError({
|
|
179
|
-
cause: err,
|
|
180
|
-
message: "Failed to execute statement"
|
|
181
|
-
}))));
|
|
182
|
-
} else if (Arr.isNonEmptyArray(rows)) {
|
|
183
|
-
resume(Effect.succeed(Chunk.unsafeFromArray(transformRows ? transformRows(rows) : rows)));
|
|
184
|
-
} else {
|
|
185
|
-
resume(Effect.fail(Option.none()));
|
|
186
|
-
}
|
|
187
|
-
});
|
|
188
|
-
});
|
|
189
|
-
return Stream.repeatEffectChunkOption(pull);
|
|
190
|
-
}).pipe(Stream.unwrapScoped);
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
const reserveRaw = Effect.async(resume => {
|
|
194
|
-
const fiber = Option.getOrThrow(Fiber.getCurrentFiber());
|
|
195
|
-
const scope = Context.unsafeGet(fiber.currentContext, Scope.Scope);
|
|
196
|
-
let cause = undefined;
|
|
197
|
-
function onError(cause_) {
|
|
198
|
-
cause = cause_;
|
|
199
|
-
}
|
|
200
|
-
pool.connect((err, client, release) => {
|
|
201
|
-
if (err) {
|
|
202
|
-
resume(Effect.fail(new _SqlError.SqlError({
|
|
203
|
-
cause: err,
|
|
204
|
-
message: "Failed to acquire connection for transaction"
|
|
205
|
-
})));
|
|
206
|
-
return;
|
|
207
|
-
} else if (!client) {
|
|
208
|
-
resume(Effect.fail(new _SqlError.SqlError({
|
|
209
|
-
message: "Failed to acquire connection for transaction",
|
|
210
|
-
cause: new Error("No client returned")
|
|
211
|
-
})));
|
|
212
|
-
return;
|
|
213
|
-
}
|
|
214
|
-
// Else we know we have client defined, so we can proceed with the connection
|
|
215
|
-
client.on("error", onError);
|
|
216
|
-
resume(Effect.as(Scope.addFinalizer(scope, Effect.sync(() => {
|
|
217
|
-
client.off("error", onError);
|
|
218
|
-
release(cause);
|
|
219
|
-
})), client));
|
|
220
|
-
});
|
|
221
|
-
});
|
|
222
|
-
const reserve = Effect.map(reserveRaw, client => new ConnectionImpl(client));
|
|
223
|
-
const listenClient = yield* RcRef.make({
|
|
224
|
-
acquire: reserveRaw
|
|
225
|
-
});
|
|
226
|
-
return Object.assign(yield* Client.make({
|
|
227
|
-
acquirer: Effect.succeed(new ConnectionImpl()),
|
|
228
|
-
transactionAcquirer: reserve,
|
|
229
|
-
compiler,
|
|
230
|
-
spanAttributes: [...(options.spanAttributes ? Object.entries(options.spanAttributes) : []), [ATTR_DB_SYSTEM_NAME, "postgresql"], [ATTR_DB_NAMESPACE, config.database ?? config.username ?? "postgres"], [ATTR_SERVER_ADDRESS, config.host ?? "localhost"], [ATTR_SERVER_PORT, config.port ?? 5432]],
|
|
231
|
-
transformRows
|
|
232
|
-
}), {
|
|
233
|
-
[TypeId]: TypeId,
|
|
234
|
-
config,
|
|
235
|
-
json: _ => PgJson(_),
|
|
236
|
-
listen: channel => Stream.asyncPush(Effect.fnUntraced(function* (emit) {
|
|
237
|
-
const client = yield* RcRef.get(listenClient);
|
|
238
|
-
function onNotification(msg) {
|
|
239
|
-
if (msg.channel === channel && msg.payload) {
|
|
240
|
-
emit.single(msg.payload);
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
yield* Effect.addFinalizer(() => Effect.promise(() => {
|
|
244
|
-
client.off("notification", onNotification);
|
|
245
|
-
return client.query(`UNLISTEN ${Pg.escapeIdentifier(channel)}`);
|
|
246
|
-
}));
|
|
247
|
-
yield* Effect.tryPromise({
|
|
248
|
-
try: () => client.query(`LISTEN ${Pg.escapeIdentifier(channel)}`),
|
|
249
|
-
catch: cause => new _SqlError.SqlError({
|
|
250
|
-
cause,
|
|
251
|
-
message: "Failed to listen"
|
|
252
|
-
})
|
|
253
|
-
});
|
|
254
|
-
client.on("notification", onNotification);
|
|
255
|
-
})),
|
|
256
|
-
notify: (channel, payload) => Effect.async(resume => {
|
|
257
|
-
pool.query(`NOTIFY ${Pg.escapeIdentifier(channel)}, $1`, [payload], err => {
|
|
258
|
-
if (err) {
|
|
259
|
-
resume(Effect.fail(new _SqlError.SqlError({
|
|
260
|
-
cause: err,
|
|
261
|
-
message: "Failed to notify"
|
|
262
|
-
})));
|
|
263
|
-
} else {
|
|
264
|
-
resume(Effect.void);
|
|
265
|
-
}
|
|
266
|
-
});
|
|
267
|
-
})
|
|
268
|
-
});
|
|
269
|
-
});
|
|
270
|
-
/**
|
|
271
|
-
* @category constructors
|
|
272
|
-
* @since 1.0.0
|
|
273
|
-
*/
|
|
274
|
-
const make = options => Effect.gen(function* () {
|
|
275
|
-
const pool = new Pg.Pool({
|
|
276
|
-
connectionString: options.url ? Redacted.value(options.url) : undefined,
|
|
277
|
-
user: options.username,
|
|
278
|
-
host: options.host,
|
|
279
|
-
database: options.database,
|
|
280
|
-
password: options.password ? Redacted.value(options.password) : undefined,
|
|
281
|
-
ssl: options.ssl,
|
|
282
|
-
port: options.port,
|
|
283
|
-
...(options.stream ? {
|
|
284
|
-
stream: options.stream
|
|
285
|
-
} : {}),
|
|
286
|
-
connectionTimeoutMillis: options.connectTimeout ? Duration.toMillis(options.connectTimeout) : undefined,
|
|
287
|
-
idleTimeoutMillis: options.idleTimeout ? Duration.toMillis(options.idleTimeout) : undefined,
|
|
288
|
-
max: options.maxConnections,
|
|
289
|
-
min: options.minConnections,
|
|
290
|
-
maxLifetimeSeconds: options.connectionTTL ? Duration.toSeconds(options.connectionTTL) : undefined,
|
|
291
|
-
application_name: options.applicationName ?? "@effect/sql-pg",
|
|
292
|
-
types: options.types
|
|
293
|
-
});
|
|
294
|
-
pool.on("error", _err => {});
|
|
295
|
-
yield* Effect.acquireRelease(Effect.tryPromise({
|
|
296
|
-
try: () => pool.query("SELECT 1"),
|
|
297
|
-
catch: cause => new _SqlError.SqlError({
|
|
298
|
-
cause,
|
|
299
|
-
message: "PgClient: Failed to connect"
|
|
300
|
-
})
|
|
301
|
-
}), () => Effect.promise(() => pool.end()).pipe(Effect.interruptible, Effect.timeoutOption(1000))).pipe(Effect.timeoutFail({
|
|
302
|
-
duration: options.connectTimeout ?? Duration.seconds(5),
|
|
303
|
-
onTimeout: () => new _SqlError.SqlError({
|
|
304
|
-
cause: new Error("Connection timed out"),
|
|
305
|
-
message: "PgClient: Connection timed out"
|
|
306
|
-
})
|
|
307
|
-
}));
|
|
308
|
-
let config = options;
|
|
309
|
-
if (pool.options.connectionString) {
|
|
310
|
-
try {
|
|
311
|
-
const parsed = PgConnString.parse(pool.options.connectionString);
|
|
312
|
-
config = {
|
|
313
|
-
...config,
|
|
314
|
-
host: config.host ?? parsed.host ?? undefined,
|
|
315
|
-
port: config.port ?? (parsed.port ? Option.getOrUndefined(Number.parse(parsed.port)) : undefined),
|
|
316
|
-
username: config.username ?? parsed.user ?? undefined,
|
|
317
|
-
password: config.password ?? (parsed.password ? Redacted.make(parsed.password) : undefined),
|
|
318
|
-
database: config.database ?? parsed.database ?? undefined
|
|
319
|
-
};
|
|
320
|
-
} catch {
|
|
321
|
-
//
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
return yield* makeClient(pool, config, options);
|
|
325
|
-
});
|
|
326
|
-
/**
|
|
327
|
-
* Create a `PgClient` from an existing `pg` pool.
|
|
328
|
-
*
|
|
329
|
-
* You control the pool lifecycle via `acquire` (typically `Effect.acquireRelease`).
|
|
330
|
-
*
|
|
331
|
-
* @category constructors
|
|
332
|
-
* @since 1.0.0
|
|
333
|
-
*/
|
|
334
|
-
exports.make = make;
|
|
335
|
-
const fromPool = exports.fromPool = /*#__PURE__*/Effect.fnUntraced(function* (options) {
|
|
336
|
-
const pool = yield* options.acquire;
|
|
337
|
-
let config = {
|
|
338
|
-
url: pool.options.connectionString ? Redacted.make(pool.options.connectionString) : undefined,
|
|
339
|
-
host: pool.options.host,
|
|
340
|
-
port: pool.options.port,
|
|
341
|
-
database: pool.options.database,
|
|
342
|
-
username: pool.options.user,
|
|
343
|
-
password: typeof pool.options.password === "string" ? Redacted.make(pool.options.password) : undefined,
|
|
344
|
-
ssl: pool.options.ssl,
|
|
345
|
-
applicationName: pool.options.application_name,
|
|
346
|
-
types: pool.options.types
|
|
347
|
-
};
|
|
348
|
-
if (pool.options.connectionString) {
|
|
349
|
-
try {
|
|
350
|
-
const parsed = PgConnString.parse(pool.options.connectionString);
|
|
351
|
-
config = {
|
|
352
|
-
...config,
|
|
353
|
-
host: config.host ?? parsed.host ?? undefined,
|
|
354
|
-
port: config.port ?? (parsed.port ? Option.getOrUndefined(Number.parse(parsed.port)) : undefined),
|
|
355
|
-
username: config.username ?? parsed.user ?? undefined,
|
|
356
|
-
password: config.password ?? (parsed.password ? Redacted.make(parsed.password) : undefined),
|
|
357
|
-
database: config.database ?? parsed.database ?? undefined
|
|
358
|
-
};
|
|
359
|
-
} catch {
|
|
360
|
-
//
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
return yield* makeClient(pool, config, options);
|
|
364
|
-
});
|
|
365
|
-
const cancelEffects = /*#__PURE__*/new WeakMap();
|
|
366
|
-
const makeCancel = (pool, client) => {
|
|
367
|
-
if (cancelEffects.has(client)) {
|
|
368
|
-
return cancelEffects.get(client);
|
|
369
|
-
}
|
|
370
|
-
const processId = client.processID;
|
|
371
|
-
const eff = processId !== undefined
|
|
372
|
-
// query cancelation is best-effort, so we don't fail if it doesn't work
|
|
373
|
-
? Effect.async(resume => {
|
|
374
|
-
if (pool.ending) return resume(Effect.void);
|
|
375
|
-
pool.query(`SELECT pg_cancel_backend(${processId})`, () => {
|
|
376
|
-
resume(Effect.void);
|
|
377
|
-
});
|
|
378
|
-
}).pipe(Effect.interruptible, Effect.timeoutOption(5000)) : undefined;
|
|
379
|
-
cancelEffects.set(client, eff);
|
|
380
|
-
return eff;
|
|
381
|
-
};
|
|
382
|
-
/**
|
|
383
|
-
* @category layers
|
|
384
|
-
* @since 1.0.0
|
|
385
|
-
*/
|
|
386
|
-
const layerConfig = config => Layer.scopedContext(Config.unwrap(config).pipe(Effect.flatMap(make), Effect.map(client => Context.make(PgClient, client).pipe(Context.add(Client.SqlClient, client))))).pipe(Layer.provide(Reactivity.layer));
|
|
387
|
-
/**
|
|
388
|
-
* @category layers
|
|
389
|
-
* @since 1.0.0
|
|
390
|
-
*/
|
|
391
|
-
exports.layerConfig = layerConfig;
|
|
392
|
-
const layer = config => Layer.scopedContext(Effect.map(make(config), client => Context.make(PgClient, client).pipe(Context.add(Client.SqlClient, client)))).pipe(Layer.provide(Reactivity.layer));
|
|
393
|
-
/**
|
|
394
|
-
* @category layers
|
|
395
|
-
* @since 1.0.0
|
|
396
|
-
*/
|
|
397
|
-
exports.layer = layer;
|
|
398
|
-
const layerFromPool = options => Layer.scopedContext(Effect.map(fromPool(options), client => Context.make(PgClient, client).pipe(Context.add(Client.SqlClient, client)))).pipe(Layer.provide(Reactivity.layer));
|
|
399
|
-
/**
|
|
400
|
-
* @category constructor
|
|
401
|
-
* @since 1.0.0
|
|
402
|
-
*/
|
|
403
|
-
exports.layerFromPool = layerFromPool;
|
|
404
|
-
const makeCompiler = (transform, transformJson = true) => {
|
|
405
|
-
const transformValue = transformJson && transform ? Statement.defaultTransforms(transform).value : undefined;
|
|
406
|
-
return Statement.makeCompiler({
|
|
407
|
-
dialect: "pg",
|
|
408
|
-
placeholder(_) {
|
|
409
|
-
return `$${_}`;
|
|
410
|
-
},
|
|
411
|
-
onIdentifier: transform ? function (value, withoutTransform) {
|
|
412
|
-
return withoutTransform ? escape(value) : escape(transform(value));
|
|
413
|
-
} : escape,
|
|
414
|
-
onRecordUpdate(placeholders, valueAlias, valueColumns, values, returning) {
|
|
415
|
-
return [`(values ${placeholders}) AS ${valueAlias}${valueColumns}${returning ? ` RETURNING ${returning[0]}` : ""}`, returning ? values.flat().concat(returning[1]) : values.flat()];
|
|
416
|
-
},
|
|
417
|
-
onCustom(type, placeholder, withoutTransform) {
|
|
418
|
-
switch (type.kind) {
|
|
419
|
-
case "PgJson":
|
|
420
|
-
{
|
|
421
|
-
return [placeholder(undefined), [withoutTransform || transformValue === undefined ? type.i0 : transformValue(type.i0)]];
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
});
|
|
426
|
-
};
|
|
427
|
-
exports.makeCompiler = makeCompiler;
|
|
428
|
-
const escape = /*#__PURE__*/Statement.defaultEscape("\"");
|
|
429
|
-
/**
|
|
430
|
-
* @category custom types
|
|
431
|
-
* @since 1.0.0
|
|
432
|
-
*/
|
|
433
|
-
const PgJson = /*#__PURE__*/Statement.custom("PgJson");
|
|
434
|
-
//# sourceMappingURL=PgClient.js.map
|