@effect/sql-mssql 4.0.0-beta.8 → 4.0.0-beta.80
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/MssqlClient.d.ts +53 -16
- package/dist/MssqlClient.d.ts.map +1 -1
- package/dist/MssqlClient.js +146 -38
- package/dist/MssqlClient.js.map +1 -1
- package/dist/MssqlMigrator.d.ts +17 -5
- package/dist/MssqlMigrator.d.ts.map +1 -1
- package/dist/MssqlMigrator.js +8 -4
- package/dist/MssqlMigrator.js.map +1 -1
- package/dist/Parameter.d.ts +16 -8
- package/dist/Parameter.d.ts.map +1 -1
- package/dist/Parameter.js +19 -5
- package/dist/Parameter.js.map +1 -1
- package/dist/Procedure.d.ts +47 -22
- package/dist/Procedure.d.ts.map +1 -1
- package/dist/Procedure.js +33 -13
- package/dist/Procedure.js.map +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/index.js +6 -6
- package/package.json +4 -4
- package/src/MssqlClient.ts +213 -37
- package/src/MssqlMigrator.ts +17 -5
- package/src/Parameter.ts +27 -9
- package/src/Procedure.ts +57 -24
- package/src/index.ts +6 -6
package/src/MssqlClient.ts
CHANGED
|
@@ -1,7 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Microsoft SQL Server client implementation for Effect SQL, backed by the
|
|
3
|
+
* `tedious` driver.
|
|
4
|
+
*
|
|
5
|
+
* This module provides the `MssqlClient` service, constructors, layers, and SQL
|
|
6
|
+
* Server statement compiler. `make` creates a pooled Tedious client, checks the
|
|
7
|
+
* connection with `SELECT 1`, maps SQL Server failures to `SqlError`, and
|
|
8
|
+
* supports transactions with savepoints. The SQL Server-specific service adds
|
|
9
|
+
* typed Tedious parameters with `param`, stored procedure calls with `call`,
|
|
10
|
+
* direct or config-backed layers, and default parameter type mappings.
|
|
11
|
+
* Streaming queries are not implemented by this driver.
|
|
12
|
+
*
|
|
13
|
+
* @since 4.0.0
|
|
3
14
|
*/
|
|
4
15
|
import * as Config from "effect/Config"
|
|
16
|
+
import * as Context from "effect/Context"
|
|
5
17
|
import * as Duration from "effect/Duration"
|
|
6
18
|
import * as Effect from "effect/Effect"
|
|
7
19
|
import { identity } from "effect/Function"
|
|
@@ -9,12 +21,23 @@ import * as Layer from "effect/Layer"
|
|
|
9
21
|
import * as Pool from "effect/Pool"
|
|
10
22
|
import * as Redacted from "effect/Redacted"
|
|
11
23
|
import * as Scope from "effect/Scope"
|
|
12
|
-
import * as ServiceMap from "effect/ServiceMap"
|
|
13
24
|
import * as Stream from "effect/Stream"
|
|
14
25
|
import * as Reactivity from "effect/unstable/reactivity/Reactivity"
|
|
15
26
|
import * as Client from "effect/unstable/sql/SqlClient"
|
|
16
27
|
import type { Connection } from "effect/unstable/sql/SqlConnection"
|
|
17
|
-
import {
|
|
28
|
+
import {
|
|
29
|
+
AuthenticationError,
|
|
30
|
+
AuthorizationError,
|
|
31
|
+
ConnectionError,
|
|
32
|
+
ConstraintError,
|
|
33
|
+
DeadlockError,
|
|
34
|
+
LockTimeoutError,
|
|
35
|
+
SerializationError,
|
|
36
|
+
SqlError,
|
|
37
|
+
SqlSyntaxError,
|
|
38
|
+
UniqueViolation,
|
|
39
|
+
UnknownError
|
|
40
|
+
} from "effect/unstable/sql/SqlError"
|
|
18
41
|
import * as Statement from "effect/unstable/sql/Statement"
|
|
19
42
|
import * as Tedious from "tedious"
|
|
20
43
|
import type { ConnectionOptions } from "tedious/lib/connection.ts"
|
|
@@ -28,21 +51,116 @@ const ATTR_DB_NAMESPACE = "db.namespace"
|
|
|
28
51
|
const ATTR_SERVER_ADDRESS = "server.address"
|
|
29
52
|
const ATTR_SERVER_PORT = "server.port"
|
|
30
53
|
|
|
54
|
+
const mssqlNumberFromCause = (cause: unknown): number | undefined => {
|
|
55
|
+
if (typeof cause !== "object" || cause === null || !("number" in cause)) {
|
|
56
|
+
return undefined
|
|
57
|
+
}
|
|
58
|
+
const number = cause.number
|
|
59
|
+
return typeof number === "number" ? number : undefined
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const mssqlConnectionErrorCodes = new Set([233, 10054])
|
|
63
|
+
const mssqlAuthenticationErrorCodes = new Set([4060, 18452, 18456])
|
|
64
|
+
const mssqlAuthorizationErrorCodes = new Set([229, 230, 262, 297, 300])
|
|
65
|
+
const mssqlSyntaxErrorCodes = new Set([102, 207, 208, 2714])
|
|
66
|
+
const mssqlConstraintErrorCodes = new Set([515, 547])
|
|
67
|
+
|
|
68
|
+
const UNKNOWN_CONSTRAINT = "unknown"
|
|
69
|
+
|
|
70
|
+
const normalizeConstraintIdentifier = (identifier: unknown): string => {
|
|
71
|
+
if (typeof identifier !== "string") {
|
|
72
|
+
return UNKNOWN_CONSTRAINT
|
|
73
|
+
}
|
|
74
|
+
const trimmed = identifier.trim()
|
|
75
|
+
return trimmed.length === 0 ? UNKNOWN_CONSTRAINT : trimmed
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const mssqlCauseProperty = (cause: unknown, property: "constraint" | "message"): unknown => {
|
|
79
|
+
if (typeof cause !== "object" || cause === null || !(property in cause)) {
|
|
80
|
+
return undefined
|
|
81
|
+
}
|
|
82
|
+
return (cause as Record<string, unknown>)[property]
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const mssqlUniqueViolationConstraintFromMessage = (number: 2601 | 2627, message: unknown): string => {
|
|
86
|
+
if (typeof message !== "string") {
|
|
87
|
+
return UNKNOWN_CONSTRAINT
|
|
88
|
+
}
|
|
89
|
+
const match = number === 2627 ?
|
|
90
|
+
/\bconstraint\s+'([^']*)'/i.exec(message) :
|
|
91
|
+
/\bunique index\s+'([^']*)'/i.exec(message)
|
|
92
|
+
return match === null ? UNKNOWN_CONSTRAINT : normalizeConstraintIdentifier(match[1])
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const mssqlUniqueViolationConstraintFromCause = (number: 2601 | 2627, cause: unknown): string => {
|
|
96
|
+
const constraint = normalizeConstraintIdentifier(mssqlCauseProperty(cause, "constraint"))
|
|
97
|
+
if (constraint !== UNKNOWN_CONSTRAINT) {
|
|
98
|
+
return constraint
|
|
99
|
+
}
|
|
100
|
+
return mssqlUniqueViolationConstraintFromMessage(number, mssqlCauseProperty(cause, "message"))
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const classifyError = (
|
|
104
|
+
cause: unknown,
|
|
105
|
+
message: string,
|
|
106
|
+
operation: string,
|
|
107
|
+
fallback: "connection" | "unknown" = "unknown"
|
|
108
|
+
) => {
|
|
109
|
+
const props = { cause, message, operation }
|
|
110
|
+
const number = mssqlNumberFromCause(cause)
|
|
111
|
+
if (number !== undefined) {
|
|
112
|
+
if (mssqlConnectionErrorCodes.has(number)) {
|
|
113
|
+
return new ConnectionError(props)
|
|
114
|
+
}
|
|
115
|
+
if (mssqlAuthenticationErrorCodes.has(number)) {
|
|
116
|
+
return new AuthenticationError(props)
|
|
117
|
+
}
|
|
118
|
+
if (mssqlAuthorizationErrorCodes.has(number)) {
|
|
119
|
+
return new AuthorizationError(props)
|
|
120
|
+
}
|
|
121
|
+
if (mssqlSyntaxErrorCodes.has(number)) {
|
|
122
|
+
return new SqlSyntaxError(props)
|
|
123
|
+
}
|
|
124
|
+
if (number === 2601 || number === 2627) {
|
|
125
|
+
return new UniqueViolation({ ...props, constraint: mssqlUniqueViolationConstraintFromCause(number, cause) })
|
|
126
|
+
}
|
|
127
|
+
if (mssqlConstraintErrorCodes.has(number)) {
|
|
128
|
+
return new ConstraintError(props)
|
|
129
|
+
}
|
|
130
|
+
if (number === 1205) {
|
|
131
|
+
return new DeadlockError(props)
|
|
132
|
+
}
|
|
133
|
+
if (number === 3960) {
|
|
134
|
+
return new SerializationError(props)
|
|
135
|
+
}
|
|
136
|
+
if (number === 1222) {
|
|
137
|
+
return new LockTimeoutError(props)
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return fallback === "connection" ? new ConnectionError(props) : new UnknownError(props)
|
|
141
|
+
}
|
|
142
|
+
|
|
31
143
|
/**
|
|
32
|
-
*
|
|
33
|
-
*
|
|
144
|
+
* Runtime type identifier used to mark `MssqlClient` values.
|
|
145
|
+
*
|
|
146
|
+
* @category type IDs
|
|
147
|
+
* @since 4.0.0
|
|
34
148
|
*/
|
|
35
149
|
export const TypeId: unique symbol = Symbol.for("@effect/sql-mssql/MssqlClient")
|
|
36
150
|
|
|
37
151
|
/**
|
|
38
|
-
*
|
|
39
|
-
*
|
|
152
|
+
* Type-level identifier used to mark `MssqlClient` values.
|
|
153
|
+
*
|
|
154
|
+
* @category type IDs
|
|
155
|
+
* @since 4.0.0
|
|
40
156
|
*/
|
|
41
157
|
export type TypeId = typeof TypeId
|
|
42
158
|
|
|
43
159
|
/**
|
|
160
|
+
* Microsoft SQL Server client service, extending `SqlClient` with typed parameter fragments and stored procedure calls.
|
|
161
|
+
*
|
|
44
162
|
* @category models
|
|
45
|
-
* @since
|
|
163
|
+
* @since 4.0.0
|
|
46
164
|
*/
|
|
47
165
|
export interface MssqlClient extends Client.SqlClient {
|
|
48
166
|
readonly [TypeId]: TypeId
|
|
@@ -65,14 +183,23 @@ export interface MssqlClient extends Client.SqlClient {
|
|
|
65
183
|
}
|
|
66
184
|
|
|
67
185
|
/**
|
|
68
|
-
*
|
|
69
|
-
*
|
|
186
|
+
* Service tag for the Microsoft SQL Server client service.
|
|
187
|
+
*
|
|
188
|
+
* **When to use**
|
|
189
|
+
*
|
|
190
|
+
* Use to access or provide a Microsoft SQL Server client through the Effect
|
|
191
|
+
* context.
|
|
192
|
+
*
|
|
193
|
+
* @category services
|
|
194
|
+
* @since 4.0.0
|
|
70
195
|
*/
|
|
71
|
-
export const MssqlClient =
|
|
196
|
+
export const MssqlClient = Context.Service<MssqlClient>("@effect/sql-mssql/MssqlClient")
|
|
72
197
|
|
|
73
198
|
/**
|
|
199
|
+
* Configuration for a Microsoft SQL Server client, including connection, authentication, pool, parameter type, span attribute, and query/result name transform options.
|
|
200
|
+
*
|
|
74
201
|
* @category models
|
|
75
|
-
* @since
|
|
202
|
+
* @since 4.0.0
|
|
76
203
|
*/
|
|
77
204
|
export interface MssqlClientConfig {
|
|
78
205
|
readonly domain?: string | undefined
|
|
@@ -111,14 +238,18 @@ interface MssqlConnection extends Connection {
|
|
|
111
238
|
readonly rollback: (name?: string) => Effect.Effect<void, SqlError>
|
|
112
239
|
}
|
|
113
240
|
|
|
114
|
-
const TransactionConnection = Client.TransactionConnection as unknown as
|
|
241
|
+
const TransactionConnection = Client.TransactionConnection as unknown as (clientId: number) => Context.Service<
|
|
115
242
|
readonly [conn: MssqlConnection, counter: number],
|
|
116
243
|
readonly [conn: MssqlConnection, counter: number]
|
|
117
244
|
>
|
|
118
245
|
|
|
246
|
+
let clientIdCounter = 0
|
|
247
|
+
|
|
119
248
|
/**
|
|
249
|
+
* Creates a scoped Microsoft SQL Server client backed by a connection pool, with transaction and stored procedure support. Streaming queries are not implemented.
|
|
250
|
+
*
|
|
120
251
|
* @category constructors
|
|
121
|
-
* @since
|
|
252
|
+
* @since 4.0.0
|
|
122
253
|
*/
|
|
123
254
|
export const make = (
|
|
124
255
|
options: MssqlClientConfig
|
|
@@ -174,7 +305,9 @@ export const make = (
|
|
|
174
305
|
yield* Effect.callback<void, SqlError>((resume) => {
|
|
175
306
|
conn.connect((cause) => {
|
|
176
307
|
if (cause) {
|
|
177
|
-
resume(
|
|
308
|
+
resume(
|
|
309
|
+
Effect.fail(new SqlError({ reason: classifyError(cause, "Failed to connect", "connect", "connection") }))
|
|
310
|
+
)
|
|
178
311
|
} else {
|
|
179
312
|
resume(Effect.void)
|
|
180
313
|
}
|
|
@@ -189,7 +322,9 @@ export const make = (
|
|
|
189
322
|
Effect.callback<any, SqlError>((resume) => {
|
|
190
323
|
const req = new Tedious.Request(sql, (cause, _rowCount, result) => {
|
|
191
324
|
if (cause) {
|
|
192
|
-
resume(
|
|
325
|
+
resume(
|
|
326
|
+
Effect.fail(new SqlError({ reason: classifyError(cause, "Failed to execute statement", "execute") }))
|
|
327
|
+
)
|
|
193
328
|
return
|
|
194
329
|
}
|
|
195
330
|
|
|
@@ -232,7 +367,9 @@ export const make = (
|
|
|
232
367
|
escape(procedure.name),
|
|
233
368
|
(cause, _, rows) => {
|
|
234
369
|
if (cause) {
|
|
235
|
-
resume(
|
|
370
|
+
resume(
|
|
371
|
+
Effect.fail(new SqlError({ reason: classifyError(cause, "Failed to execute statement", "execute") }))
|
|
372
|
+
)
|
|
236
373
|
} else {
|
|
237
374
|
rows = rowsToObjects(rows)
|
|
238
375
|
if (transformRows) {
|
|
@@ -291,7 +428,13 @@ export const make = (
|
|
|
291
428
|
begin: Effect.callback<void, SqlError>((resume) => {
|
|
292
429
|
conn.beginTransaction((cause) => {
|
|
293
430
|
if (cause) {
|
|
294
|
-
resume(
|
|
431
|
+
resume(
|
|
432
|
+
Effect.fail(
|
|
433
|
+
new SqlError({
|
|
434
|
+
reason: classifyError(cause, "Failed to begin transaction", "beginTransaction")
|
|
435
|
+
})
|
|
436
|
+
)
|
|
437
|
+
)
|
|
295
438
|
} else {
|
|
296
439
|
resume(Effect.void)
|
|
297
440
|
}
|
|
@@ -300,7 +443,13 @@ export const make = (
|
|
|
300
443
|
commit: Effect.callback<void, SqlError>((resume) => {
|
|
301
444
|
conn.commitTransaction((cause) => {
|
|
302
445
|
if (cause) {
|
|
303
|
-
resume(
|
|
446
|
+
resume(
|
|
447
|
+
Effect.fail(
|
|
448
|
+
new SqlError({
|
|
449
|
+
reason: classifyError(cause, "Failed to commit transaction", "commitTransaction")
|
|
450
|
+
})
|
|
451
|
+
)
|
|
452
|
+
)
|
|
304
453
|
} else {
|
|
305
454
|
resume(Effect.void)
|
|
306
455
|
}
|
|
@@ -310,7 +459,11 @@ export const make = (
|
|
|
310
459
|
Effect.callback<void, SqlError>((resume) => {
|
|
311
460
|
conn.saveTransaction((cause) => {
|
|
312
461
|
if (cause) {
|
|
313
|
-
resume(
|
|
462
|
+
resume(
|
|
463
|
+
Effect.fail(
|
|
464
|
+
new SqlError({ reason: classifyError(cause, "Failed to create savepoint", "createSavepoint") })
|
|
465
|
+
)
|
|
466
|
+
)
|
|
314
467
|
} else {
|
|
315
468
|
resume(Effect.void)
|
|
316
469
|
}
|
|
@@ -320,7 +473,13 @@ export const make = (
|
|
|
320
473
|
Effect.callback<void, SqlError>((resume) => {
|
|
321
474
|
conn.rollbackTransaction((cause) => {
|
|
322
475
|
if (cause) {
|
|
323
|
-
resume(
|
|
476
|
+
resume(
|
|
477
|
+
Effect.fail(
|
|
478
|
+
new SqlError({
|
|
479
|
+
reason: classifyError(cause, "Failed to rollback transaction", "rollbackTransaction")
|
|
480
|
+
})
|
|
481
|
+
)
|
|
482
|
+
)
|
|
324
483
|
} else {
|
|
325
484
|
resume(Effect.void)
|
|
326
485
|
}
|
|
@@ -349,22 +508,29 @@ export const make = (
|
|
|
349
508
|
|
|
350
509
|
yield* Pool.get(pool).pipe(
|
|
351
510
|
Effect.tap((connection) => connection.executeUnprepared("SELECT 1", [], undefined)),
|
|
352
|
-
Effect.mapError((
|
|
511
|
+
Effect.mapError((cause) =>
|
|
512
|
+
new SqlError({ reason: classifyError(cause, "MssqlClient: Failed to connect", "connect", "connection") })
|
|
513
|
+
),
|
|
353
514
|
Effect.scoped,
|
|
354
515
|
Effect.timeoutOrElse({
|
|
355
516
|
duration: options.connectTimeout ?? Duration.seconds(5),
|
|
356
|
-
|
|
517
|
+
orElse: () =>
|
|
357
518
|
Effect.fail(
|
|
358
519
|
new SqlError({
|
|
359
|
-
|
|
360
|
-
|
|
520
|
+
reason: new ConnectionError({
|
|
521
|
+
message: "MssqlClient: Connection timeout",
|
|
522
|
+
cause: new Error("connection timeout"),
|
|
523
|
+
operation: "connect"
|
|
524
|
+
})
|
|
361
525
|
})
|
|
362
526
|
)
|
|
363
527
|
})
|
|
364
528
|
)
|
|
365
529
|
|
|
530
|
+
const transactionService = TransactionConnection(clientIdCounter++)
|
|
531
|
+
|
|
366
532
|
const withTransaction = Client.makeWithTransaction({
|
|
367
|
-
transactionService
|
|
533
|
+
transactionService,
|
|
368
534
|
spanAttributes,
|
|
369
535
|
acquireConnection: Effect.gen(function*() {
|
|
370
536
|
const scope = Scope.makeUnsafe()
|
|
@@ -382,6 +548,7 @@ export const make = (
|
|
|
382
548
|
yield* Client.make({
|
|
383
549
|
acquirer: Pool.get(pool),
|
|
384
550
|
compiler,
|
|
551
|
+
transactionService: transactionService as any,
|
|
385
552
|
spanAttributes,
|
|
386
553
|
transformRows
|
|
387
554
|
}),
|
|
@@ -426,42 +593,48 @@ export const make = (
|
|
|
426
593
|
})
|
|
427
594
|
|
|
428
595
|
/**
|
|
596
|
+
* Creates a layer from a `Config`-wrapped SQL Server client configuration, providing both `MssqlClient` and `SqlClient`.
|
|
597
|
+
*
|
|
429
598
|
* @category layers
|
|
430
|
-
* @since
|
|
599
|
+
* @since 4.0.0
|
|
431
600
|
*/
|
|
432
601
|
export const layerConfig: (
|
|
433
602
|
config: Config.Wrap<MssqlClientConfig>
|
|
434
603
|
) => Layer.Layer<Client.SqlClient | MssqlClient, Config.ConfigError | SqlError> = (
|
|
435
604
|
config: Config.Wrap<MssqlClientConfig>
|
|
436
605
|
): Layer.Layer<Client.SqlClient | MssqlClient, Config.ConfigError | SqlError> =>
|
|
437
|
-
Layer.
|
|
438
|
-
Config.unwrap(config).
|
|
606
|
+
Layer.effectContext(
|
|
607
|
+
Config.unwrap(config).pipe(
|
|
439
608
|
Effect.flatMap(make),
|
|
440
609
|
Effect.map((client) =>
|
|
441
|
-
|
|
442
|
-
|
|
610
|
+
Context.make(MssqlClient, client).pipe(
|
|
611
|
+
Context.add(Client.SqlClient, client)
|
|
443
612
|
)
|
|
444
613
|
)
|
|
445
614
|
)
|
|
446
615
|
).pipe(Layer.provide(Reactivity.layer))
|
|
447
616
|
|
|
448
617
|
/**
|
|
618
|
+
* Creates a layer from a concrete SQL Server client configuration, providing both `MssqlClient` and `SqlClient`.
|
|
619
|
+
*
|
|
449
620
|
* @category layers
|
|
450
|
-
* @since
|
|
621
|
+
* @since 4.0.0
|
|
451
622
|
*/
|
|
452
623
|
export const layer = (
|
|
453
624
|
config: MssqlClientConfig
|
|
454
625
|
): Layer.Layer<Client.SqlClient | MssqlClient, never | SqlError> =>
|
|
455
|
-
Layer.
|
|
626
|
+
Layer.effectContext(
|
|
456
627
|
Effect.map(make(config), (client) =>
|
|
457
|
-
|
|
458
|
-
|
|
628
|
+
Context.make(MssqlClient, client).pipe(
|
|
629
|
+
Context.add(Client.SqlClient, client)
|
|
459
630
|
))
|
|
460
631
|
).pipe(Layer.provide(Reactivity.layer))
|
|
461
632
|
|
|
462
633
|
/**
|
|
634
|
+
* Creates the SQL Server statement compiler, using `@1`-style placeholders, bracket-escaped identifiers, and SQL Server `OUTPUT INSERTED` returning clauses.
|
|
635
|
+
*
|
|
463
636
|
* @category compiler
|
|
464
|
-
* @since
|
|
637
|
+
* @since 4.0.0
|
|
465
638
|
*/
|
|
466
639
|
export const makeCompiler = (transform?: (_: string) => string) =>
|
|
467
640
|
Statement.makeCompiler<MssqlCustom>({
|
|
@@ -510,7 +683,10 @@ function numberToParamName(n: number) {
|
|
|
510
683
|
}
|
|
511
684
|
|
|
512
685
|
/**
|
|
513
|
-
*
|
|
686
|
+
* Default mapping from Effect SQL primitive value kinds to Tedious SQL Server parameter data types.
|
|
687
|
+
*
|
|
688
|
+
* @category configuration
|
|
689
|
+
* @since 4.0.0
|
|
514
690
|
*/
|
|
515
691
|
export const defaultParameterTypes: Record<Statement.PrimitiveKind, DataType> = {
|
|
516
692
|
string: Tedious.TYPES.VarChar,
|
package/src/MssqlMigrator.ts
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Utilities for applying Effect SQL migrations to Microsoft SQL Server.
|
|
3
|
+
*
|
|
4
|
+
* This module re-exports the shared `Migrator` loaders and error types, then
|
|
5
|
+
* provides `run` and `layer` helpers for applying ordered migrations through
|
|
6
|
+
* the current SQL Server `SqlClient`. `run` returns the applied migration IDs
|
|
7
|
+
* and names, while `layer` runs migrations during layer construction and
|
|
8
|
+
* provides no services.
|
|
9
|
+
*
|
|
10
|
+
* @since 4.0.0
|
|
3
11
|
*/
|
|
4
12
|
import type * as Effect from "effect/Effect"
|
|
5
13
|
import * as Layer from "effect/Layer"
|
|
@@ -8,13 +16,15 @@ import type * as Client from "effect/unstable/sql/SqlClient"
|
|
|
8
16
|
import type { SqlError } from "effect/unstable/sql/SqlError"
|
|
9
17
|
|
|
10
18
|
/**
|
|
11
|
-
* @since
|
|
19
|
+
* @since 4.0.0
|
|
12
20
|
*/
|
|
13
21
|
export * from "effect/unstable/sql/Migrator"
|
|
14
22
|
|
|
15
23
|
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
24
|
+
* Runs SQL migrations using the configured `SqlClient`, returning the migrations that were applied.
|
|
25
|
+
*
|
|
26
|
+
* @category constructors
|
|
27
|
+
* @since 4.0.0
|
|
18
28
|
*/
|
|
19
29
|
export const run: <R>(
|
|
20
30
|
options: Migrator.MigratorOptions<R>
|
|
@@ -25,8 +35,10 @@ export const run: <R>(
|
|
|
25
35
|
> = Migrator.make({})
|
|
26
36
|
|
|
27
37
|
/**
|
|
38
|
+
* Creates a layer that runs the configured SQL migrations during layer construction.
|
|
39
|
+
*
|
|
28
40
|
* @category layers
|
|
29
|
-
* @since
|
|
41
|
+
* @since 4.0.0
|
|
30
42
|
*/
|
|
31
43
|
export const layer = <R>(
|
|
32
44
|
options: Migrator.MigratorOptions<R>
|
package/src/Parameter.ts
CHANGED
|
@@ -1,25 +1,41 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Typed SQL Server stored procedure parameter metadata.
|
|
3
|
+
*
|
|
4
|
+
* This module builds {@link Parameter} values that pair a stored procedure
|
|
5
|
+
* parameter name with a Tedious `DataType`, Tedious `ParameterOptions`, and a
|
|
6
|
+
* phantom TypeScript value type. `Procedure.param` and
|
|
7
|
+
* `Procedure.outputParam` use this metadata, and `MssqlClient.call` forwards it
|
|
8
|
+
* to Tedious when registering input and output parameters.
|
|
9
|
+
*
|
|
10
|
+
* @see {@link make} for constructing parameter metadata directly.
|
|
11
|
+
*
|
|
12
|
+
* @since 4.0.0
|
|
3
13
|
*/
|
|
4
14
|
import { identity } from "effect/Function"
|
|
5
15
|
import type { DataType } from "tedious/lib/data-type.ts"
|
|
6
16
|
import type { ParameterOptions } from "tedious/lib/request.ts"
|
|
7
17
|
|
|
8
18
|
/**
|
|
9
|
-
*
|
|
10
|
-
*
|
|
19
|
+
* Runtime type identifier used to mark SQL Server stored procedure parameter metadata.
|
|
20
|
+
*
|
|
21
|
+
* @category type IDs
|
|
22
|
+
* @since 4.0.0
|
|
11
23
|
*/
|
|
12
24
|
export const TypeId: TypeId = "~@effect/sql-mssql/Parameter"
|
|
13
25
|
|
|
14
26
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
27
|
+
* Type-level identifier used to mark SQL Server stored procedure parameter metadata.
|
|
28
|
+
*
|
|
29
|
+
* @category type IDs
|
|
30
|
+
* @since 4.0.0
|
|
17
31
|
*/
|
|
18
32
|
export type TypeId = "~@effect/sql-mssql/Parameter"
|
|
19
33
|
|
|
20
34
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
35
|
+
* Metadata for a SQL Server stored procedure parameter, including its name, Tedious data type, options, and phantom value type.
|
|
36
|
+
*
|
|
37
|
+
* @category models
|
|
38
|
+
* @since 4.0.0
|
|
23
39
|
*/
|
|
24
40
|
export interface Parameter<out A> {
|
|
25
41
|
readonly [TypeId]: (_: never) => A
|
|
@@ -30,8 +46,10 @@ export interface Parameter<out A> {
|
|
|
30
46
|
}
|
|
31
47
|
|
|
32
48
|
/**
|
|
33
|
-
*
|
|
34
|
-
*
|
|
49
|
+
* Creates typed metadata for a SQL Server stored procedure parameter.
|
|
50
|
+
*
|
|
51
|
+
* @category constructors
|
|
52
|
+
* @since 4.0.0
|
|
35
53
|
*/
|
|
36
54
|
export const make = <A>(
|
|
37
55
|
name: string,
|
package/src/Procedure.ts
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Typed metadata builders for Microsoft SQL Server stored procedure calls.
|
|
3
|
+
*
|
|
4
|
+
* This module defines the `Procedure` values consumed by `MssqlClient.call`.
|
|
5
|
+
* `make` starts a procedure definition, `param` and `outputParam` add typed
|
|
6
|
+
* Tedious parameter metadata, `withRows` sets the expected row type, and
|
|
7
|
+
* `compile` binds input values before execution. The module also defines the
|
|
8
|
+
* typed result shape for output parameters and returned rows.
|
|
9
|
+
*
|
|
10
|
+
* @since 4.0.0
|
|
3
11
|
*/
|
|
4
12
|
import { identity } from "effect/Function"
|
|
5
13
|
import type { Pipeable } from "effect/Pipeable"
|
|
@@ -11,20 +19,26 @@ import type { ParameterOptions } from "tedious/lib/request.ts"
|
|
|
11
19
|
import * as Parameter from "./Parameter.ts"
|
|
12
20
|
|
|
13
21
|
/**
|
|
14
|
-
*
|
|
15
|
-
*
|
|
22
|
+
* Runtime type identifier used to mark SQL Server stored procedure definitions.
|
|
23
|
+
*
|
|
24
|
+
* @category type IDs
|
|
25
|
+
* @since 4.0.0
|
|
16
26
|
*/
|
|
17
27
|
export const TypeId: TypeId = "~@effect/sql-mssql/Procedure"
|
|
18
28
|
|
|
19
29
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
30
|
+
* Type-level identifier used to mark SQL Server stored procedure definitions.
|
|
31
|
+
*
|
|
32
|
+
* @category type IDs
|
|
33
|
+
* @since 4.0.0
|
|
22
34
|
*/
|
|
23
35
|
export type TypeId = "~@effect/sql-mssql/Procedure"
|
|
24
36
|
|
|
25
37
|
/**
|
|
26
|
-
*
|
|
27
|
-
*
|
|
38
|
+
* Pipeable definition of a SQL Server stored procedure, tracking its input parameters, output parameters, and result row type.
|
|
39
|
+
*
|
|
40
|
+
* @category models
|
|
41
|
+
* @since 4.0.0
|
|
28
42
|
*/
|
|
29
43
|
export interface Procedure<
|
|
30
44
|
I extends Record<string, Parameter.Parameter<any>>,
|
|
@@ -41,8 +55,10 @@ export interface Procedure<
|
|
|
41
55
|
}
|
|
42
56
|
|
|
43
57
|
/**
|
|
44
|
-
*
|
|
45
|
-
*
|
|
58
|
+
* Stored procedure definition with concrete input values bound for execution.
|
|
59
|
+
*
|
|
60
|
+
* @category models
|
|
61
|
+
* @since 4.0.0
|
|
46
62
|
*/
|
|
47
63
|
export interface ProcedureWithValues<
|
|
48
64
|
I extends Record<string, Parameter.Parameter<any>>,
|
|
@@ -53,11 +69,16 @@ export interface ProcedureWithValues<
|
|
|
53
69
|
}
|
|
54
70
|
|
|
55
71
|
/**
|
|
56
|
-
*
|
|
72
|
+
* Namespace containing type helpers and result types for SQL Server stored procedures.
|
|
73
|
+
*
|
|
74
|
+
* @since 4.0.0
|
|
57
75
|
*/
|
|
58
|
-
export namespace Procedure {
|
|
76
|
+
export declare namespace Procedure {
|
|
59
77
|
/**
|
|
60
|
-
*
|
|
78
|
+
* Maps a record of `Parameter` metadata to the corresponding record of parameter value types.
|
|
79
|
+
*
|
|
80
|
+
* @category utility types
|
|
81
|
+
* @since 4.0.0
|
|
61
82
|
*/
|
|
62
83
|
export type ParametersRecord<
|
|
63
84
|
A extends Record<string, Parameter.Parameter<any>>
|
|
@@ -69,8 +90,10 @@ export namespace Procedure {
|
|
|
69
90
|
& {}
|
|
70
91
|
|
|
71
92
|
/**
|
|
72
|
-
*
|
|
73
|
-
*
|
|
93
|
+
* Result of a SQL Server stored procedure call, containing typed output parameter values and returned rows.
|
|
94
|
+
*
|
|
95
|
+
* @category models
|
|
96
|
+
* @since 4.0.0
|
|
74
97
|
*/
|
|
75
98
|
export interface Result<
|
|
76
99
|
O extends Record<string, Parameter.Parameter<any>>,
|
|
@@ -94,8 +117,10 @@ const procedureProto = {
|
|
|
94
117
|
}
|
|
95
118
|
|
|
96
119
|
/**
|
|
97
|
-
*
|
|
98
|
-
*
|
|
120
|
+
* Creates an empty SQL Server stored procedure definition for the given procedure name.
|
|
121
|
+
*
|
|
122
|
+
* @category constructors
|
|
123
|
+
* @since 4.0.0
|
|
99
124
|
*/
|
|
100
125
|
export const make = (name: string): Procedure<{}, {}> => {
|
|
101
126
|
const procedure = Object.create(procedureProto)
|
|
@@ -106,8 +131,10 @@ export const make = (name: string): Procedure<{}, {}> => {
|
|
|
106
131
|
}
|
|
107
132
|
|
|
108
133
|
/**
|
|
109
|
-
*
|
|
110
|
-
*
|
|
134
|
+
* Adds a typed input parameter to a SQL Server stored procedure definition.
|
|
135
|
+
*
|
|
136
|
+
* @category combinators
|
|
137
|
+
* @since 4.0.0
|
|
111
138
|
*/
|
|
112
139
|
export const param = <A>() =>
|
|
113
140
|
<N extends string, T extends DataType>(
|
|
@@ -129,8 +156,10 @@ export const param = <A>() =>
|
|
|
129
156
|
})
|
|
130
157
|
|
|
131
158
|
/**
|
|
132
|
-
*
|
|
133
|
-
*
|
|
159
|
+
* Adds a typed output parameter to a SQL Server stored procedure definition.
|
|
160
|
+
*
|
|
161
|
+
* @category combinators
|
|
162
|
+
* @since 4.0.0
|
|
134
163
|
*/
|
|
135
164
|
export const outputParam = <A>() =>
|
|
136
165
|
<N extends string, T extends DataType>(
|
|
@@ -152,8 +181,10 @@ export const outputParam = <A>() =>
|
|
|
152
181
|
})
|
|
153
182
|
|
|
154
183
|
/**
|
|
155
|
-
*
|
|
156
|
-
*
|
|
184
|
+
* Sets the expected row type for a SQL Server stored procedure definition.
|
|
185
|
+
*
|
|
186
|
+
* @category combinators
|
|
187
|
+
* @since 4.0.0
|
|
157
188
|
*/
|
|
158
189
|
export const withRows = <A extends object = Row>() =>
|
|
159
190
|
<
|
|
@@ -164,8 +195,10 @@ export const withRows = <A extends object = Row>() =>
|
|
|
164
195
|
): Procedure<I, O, A> => self as any
|
|
165
196
|
|
|
166
197
|
/**
|
|
167
|
-
*
|
|
168
|
-
*
|
|
198
|
+
* Binds input values to a SQL Server stored procedure definition, producing a value that can be executed with `MssqlClient.call`.
|
|
199
|
+
*
|
|
200
|
+
* @category combinators
|
|
201
|
+
* @since 4.0.0
|
|
169
202
|
*/
|
|
170
203
|
export const compile = <
|
|
171
204
|
I extends Record<string, Parameter.Parameter<any>>,
|