@voltro/sql-mssql 0.85.0 → 0.87.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/CHANGELOG.md +5987 -0
- package/THIRD-PARTY-NOTICES.md +6 -258
- package/dist/binaryParameter.js +9 -0
- package/dist/cdcOffsetsTable.js +1 -0
- package/dist/changeTrackingCdc.js +111 -0
- package/dist/index.d.ts +9 -1
- package/dist/index.js +12 -820
- package/dist/numberParameter.js +19 -0
- package/dist/replicationAdapter.js +35 -0
- package/dist/retry.js +20 -0
- package/dist/rowResultProjection.js +16 -0
- package/dist/sqlLayer.js +78 -0
- package/dist/store.js +576 -0
- package/dist/writeOutput.js +18 -0
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,824 +1,16 @@
|
|
|
1
|
-
import { MssqlClient as e } from "
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
//#region src/numberParameter.ts
|
|
10
|
-
var L = (e) => typeof e == "bigint" ? t.BigInt : typeof e == "number" && Number.isSafeInteger(e) ? e >= -2147483648 && e <= 2147483647 ? t.Int : t.BigInt : t.Float, _e = {
|
|
11
|
-
...t.Int,
|
|
12
|
-
declaration: (e) => L(e.value).declaration(e),
|
|
13
|
-
resolve: (e, t, n) => l({
|
|
14
|
-
...e,
|
|
15
|
-
type: L(e.value)
|
|
16
|
-
}, t, n).data,
|
|
17
|
-
writeTypeInfo: (e, t, n) => L(t.value).writeTypeInfo(e, t, n),
|
|
18
|
-
writeValue: (e, t, n) => L(t.value).writeValue(e, t, n),
|
|
19
|
-
validate: (e, t, n) => {
|
|
20
|
-
if (typeof e == "number" && !Number.isFinite(e)) throw TypeError("SQL Server numeric parameters must be finite.");
|
|
21
|
-
return L(e).validate(e, t, n);
|
|
22
|
-
}
|
|
23
|
-
}, ve = {
|
|
24
|
-
...t.VarBinary,
|
|
25
|
-
resolveLength: (e) => Math.max(1, t.VarBinary.resolveLength(e)),
|
|
26
|
-
validate: (e, n, r) => t.VarBinary.validate(e instanceof Uint8Array && !Buffer.isBuffer(e) ? Buffer.from(e.buffer, e.byteOffset, e.byteLength) : e, n, r)
|
|
27
|
-
}, ye = {
|
|
28
|
-
...e.defaultParameterTypes,
|
|
29
|
-
null: t.NVarChar,
|
|
30
|
-
Date: t.DateTime2,
|
|
31
|
-
string: t.NVarChar,
|
|
32
|
-
number: _e,
|
|
33
|
-
Uint8Array: ve
|
|
34
|
-
}, be = (e) => {
|
|
35
|
-
let t = e.acquireTimeoutMs ?? d;
|
|
36
|
-
return t > 0 ? t : void 0;
|
|
37
|
-
}, R = (t) => {
|
|
38
|
-
let i = be(t);
|
|
39
|
-
return e.layerConfig({
|
|
40
|
-
transactionService: n.succeed(m),
|
|
41
|
-
server: n.succeed(t.server),
|
|
42
|
-
parameterTypes: n.succeed(ye),
|
|
43
|
-
...i === void 0 ? {} : { connectTimeout: n.succeed(r.millis(i)) },
|
|
44
|
-
...t.port === void 0 ? {} : { port: n.succeed(t.port) },
|
|
45
|
-
...t.database === void 0 ? {} : { database: n.succeed(t.database) },
|
|
46
|
-
...t.username === void 0 ? {} : { username: n.succeed(t.username) },
|
|
47
|
-
...t.password === void 0 ? {} : { password: n.succeed(c.make(t.password)) },
|
|
48
|
-
encrypt: n.succeed(t.encrypt ?? !1),
|
|
49
|
-
...t.trustServer === void 0 ? {} : { trustServer: n.succeed(t.trustServer) },
|
|
50
|
-
...t.maxConnections === void 0 ? {} : { maxConnections: n.succeed(t.maxConnections) }
|
|
51
|
-
});
|
|
52
|
-
}, xe = (e) => {
|
|
53
|
-
let t = e.get("sslmode");
|
|
54
|
-
if (t !== null) {
|
|
55
|
-
if (t === "require") return !0;
|
|
56
|
-
if (t === "disable") return !1;
|
|
57
|
-
throw Error(`DB_URL '?sslmode=${t}' is not supported by the mssql dialect — use 'require' (TLS without certificate verification) or 'disable' (plaintext).`);
|
|
58
|
-
}
|
|
59
|
-
for (let t of ["ssl", "encrypt"]) {
|
|
60
|
-
let n = e.get(t);
|
|
61
|
-
if (n !== null) {
|
|
62
|
-
if (n === "true" || n === "1") return !0;
|
|
63
|
-
if (n === "false" || n === "0") return !1;
|
|
64
|
-
throw Error(`DB_URL '?${t}=${n}' is not supported by the mssql dialect — use 'true'/'1' or 'false'/'0'.`);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}, z = (e) => {
|
|
68
|
-
let t = e.acquireTimeoutMs === void 0 ? {} : { acquireTimeoutMs: e.acquireTimeoutMs }, n = (e) => e === void 0 ? {} : {
|
|
69
|
-
encrypt: e,
|
|
70
|
-
...e ? { trustServer: !0 } : {}
|
|
71
|
-
};
|
|
72
|
-
if (e.url) {
|
|
73
|
-
let r = new URL(e.url);
|
|
74
|
-
return {
|
|
75
|
-
server: r.hostname || "localhost",
|
|
76
|
-
port: r.port ? Number(r.port) : 1433,
|
|
77
|
-
username: decodeURIComponent(r.username || "sa"),
|
|
78
|
-
password: decodeURIComponent(r.password || ""),
|
|
79
|
-
database: r.pathname.replace(/^\//, "") || "master",
|
|
80
|
-
...n(e.ssl ?? xe(r.searchParams)),
|
|
81
|
-
...e.maxConnections === void 0 ? {} : { maxConnections: e.maxConnections },
|
|
82
|
-
...t
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
return {
|
|
86
|
-
server: e.host ?? "localhost",
|
|
87
|
-
port: e.port ?? 1433,
|
|
88
|
-
username: e.username ?? "sa",
|
|
89
|
-
password: e.password ?? "",
|
|
90
|
-
database: e.database ?? "master",
|
|
91
|
-
...n(e.ssl),
|
|
92
|
-
...e.maxConnections === void 0 ? {} : { maxConnections: e.maxConnections },
|
|
93
|
-
...t
|
|
94
|
-
};
|
|
95
|
-
}, B = (e) => R(z(e)), V = (e, t) => i.gen(function* () {
|
|
96
|
-
let n = yield* e`
|
|
97
|
-
SELECT name, system_type_id FROM sys.columns
|
|
98
|
-
WHERE object_id = OBJECT_ID(${e`${e(t)}`.compile()[0]}, 'U')
|
|
99
|
-
ORDER BY column_id
|
|
100
|
-
`.withoutTransform;
|
|
101
|
-
return n.length === 0 ? yield* pe(`Cannot inspect result columns for ${t}`) : n;
|
|
102
|
-
}), H = (e, t, n) => e.join(", ", !1)(t.map((t) => {
|
|
103
|
-
let r = e.literal(`[${t.name.replaceAll("]", "]]")}]`), i = n ? e`${e(n)}.${r}` : r;
|
|
104
|
-
return t.system_type_id === 106 || t.system_type_id === 108 ? e`CONVERT(varchar(80), ${i}) AS ${r}` : i;
|
|
105
|
-
})), U = (e, t, n, r = !1) => i.uninterruptible(i.gen(function* () {
|
|
106
|
-
let i = e.literal("[#voltro_write_output]"), a = yield* V(e, t), o = e.join(", ", !1)(a.map((t) => {
|
|
107
|
-
let n = e.literal(`[${t.name.replaceAll("]", "]]")}]`);
|
|
108
|
-
return t.system_type_id === 189 ? e`CONVERT(binary(8), ${n}) AS ${n}` : n;
|
|
109
|
-
})), s = H(e, a);
|
|
110
|
-
return yield* e`
|
|
111
|
-
SELECT TOP (0) ${r ? e.literal("CAST(NULL AS nvarchar(10)) AS [__action],") : e.literal("")} source.* INTO ${i}
|
|
112
|
-
FROM (SELECT ${o} FROM ${e(t)} UNION ALL SELECT ${o} FROM ${e(t)}) AS source;
|
|
113
|
-
${n(i)};
|
|
114
|
-
SELECT ${r ? e.literal("[__action],") : e.literal("")}${s} FROM ${i};
|
|
115
|
-
DROP TABLE ${i};
|
|
116
|
-
`;
|
|
117
|
-
})), Se = p, W = (e) => {
|
|
118
|
-
let t = e;
|
|
119
|
-
for (let e = 0; e < 5 && typeof t == "object" && t; e++) {
|
|
120
|
-
let e = t.number;
|
|
121
|
-
if (typeof e == "number") return String(e);
|
|
122
|
-
let n = t.code;
|
|
123
|
-
if (typeof n == "string") return n;
|
|
124
|
-
t = t.cause;
|
|
125
|
-
}
|
|
126
|
-
}, G = (e) => y(e).some((e) => {
|
|
127
|
-
let t = W(e);
|
|
128
|
-
return t !== void 0 && Se.has(t);
|
|
129
|
-
}), Ce = /* @__PURE__ */ new Set(["2601", "2627"]), K = (e) => y(e).some((e) => {
|
|
130
|
-
let t = W(e);
|
|
131
|
-
return t !== void 0 && Ce.has(t);
|
|
132
|
-
}), q = (e) => G(e) ? "retry" : "noRetry", we = {
|
|
133
|
-
I: "insert",
|
|
134
|
-
U: "update",
|
|
135
|
-
D: "delete"
|
|
136
|
-
}, J = (e, t) => e(i.gen(function* () {
|
|
137
|
-
let e = yield* I;
|
|
138
|
-
if (((yield* e`
|
|
139
|
-
SELECT COUNT(*) AS ${e("on")}
|
|
140
|
-
FROM sys.change_tracking_databases
|
|
141
|
-
WHERE database_id = DB_ID()`)[0]?.on ?? 0) === 0) return yield* i.fail(/* @__PURE__ */ Error("mssql Change Tracking CDC requires CT enabled on the database. Run `ALTER DATABASE <db> SET CHANGE_TRACKING = ON (CHANGE_RETENTION = 2 DAYS, AUTO_CLEANUP = ON)`, or set CDC=0 for inline emit."));
|
|
142
|
-
let n = [];
|
|
143
|
-
for (let r of t) {
|
|
144
|
-
if (((yield* e`
|
|
145
|
-
SELECT CASE WHEN OBJECT_ID(${r}, 'U') IS NULL THEN 0 ELSE 1 END AS ${e("present")}`)[0]?.present ?? 0) === 0) {
|
|
146
|
-
n.push(r);
|
|
147
|
-
continue;
|
|
148
|
-
}
|
|
149
|
-
yield* e.unsafe(`IF NOT EXISTS (
|
|
150
|
-
SELECT 1 FROM sys.change_tracking_tables
|
|
151
|
-
WHERE object_id = OBJECT_ID(${Y(r)})
|
|
152
|
-
)
|
|
153
|
-
ALTER TABLE ${X(r)} ENABLE CHANGE_TRACKING WITH (TRACK_COLUMNS_UPDATED = OFF)`);
|
|
154
|
-
}
|
|
155
|
-
return n;
|
|
156
|
-
})), Y = (e) => `'${e.replace(/'/g, "''")}'`, X = (e) => `[${e.replace(/\]/g, "]]")}]`, Z = async (e) => {
|
|
157
|
-
let t = F({ scope: "voltro:mssql:cdc" }), n = e.pollIntervalMs ?? 500, r = await J(e.run, e.tables), a = /* @__PURE__ */ new Set(), o = async () => (await e.run(i.gen(function* () {
|
|
158
|
-
return yield* (yield* I)`SELECT CONVERT(VARCHAR(40), CHANGE_TRACKING_CURRENT_VERSION()) AS v`;
|
|
159
|
-
})))[0]?.v ?? "0", s = e.startVersion ?? await o(), c = !1, l = null, u = !1, d = (e, t) => BigInt(e) > BigInt(t), f = async (n, r) => {
|
|
160
|
-
let c = await e.run(i.gen(function* () {
|
|
161
|
-
let e = yield* I, t = e.unsafe(X(n)), i = (yield* e`
|
|
162
|
-
SELECT CONVERT(VARCHAR(40), CHANGE_TRACKING_MIN_VALID_VERSION(OBJECT_ID(${e.unsafe(Y(n))}))) AS floor`)[0]?.floor, o = r;
|
|
163
|
-
if (i != null && BigInt(r) < BigInt(i)) {
|
|
164
|
-
if (!a.has(n)) return {
|
|
165
|
-
resync: !0,
|
|
166
|
-
rows: []
|
|
167
|
-
};
|
|
168
|
-
o = i;
|
|
169
|
-
}
|
|
170
|
-
return {
|
|
171
|
-
resync: !1,
|
|
172
|
-
rows: yield* e`
|
|
173
|
-
SELECT ct.SYS_CHANGE_OPERATION AS __ct_op, ct.id AS __ct_id, ${H(e, yield* V(e, n), "t")}
|
|
174
|
-
FROM CHANGETABLE(CHANGES ${t}, ${BigInt(o)}) AS ct
|
|
175
|
-
LEFT JOIN ${t} AS t ON t.id = ct.id
|
|
176
|
-
ORDER BY ct.SYS_CHANGE_VERSION`.unprepared
|
|
177
|
-
};
|
|
178
|
-
}));
|
|
179
|
-
if (c.resync) {
|
|
180
|
-
t.warn("cdc: CT retention floor passed our cursor — resyncing to current version", { table: n }), s = await o(), e.onResync?.(), e.onVersion?.(s);
|
|
181
|
-
return;
|
|
182
|
-
}
|
|
183
|
-
for (let t of c.rows) {
|
|
184
|
-
let r = we[t.__ct_op];
|
|
185
|
-
if (!r) continue;
|
|
186
|
-
let { __ct_op: i, __ct_id: a, ...o } = t;
|
|
187
|
-
if (r === "delete") e.onChange({
|
|
188
|
-
table: n,
|
|
189
|
-
op: "delete",
|
|
190
|
-
old: { id: a },
|
|
191
|
-
new: null,
|
|
192
|
-
netChange: !0
|
|
193
|
-
});
|
|
194
|
-
else {
|
|
195
|
-
let t = E([o], n, "mssql")[0];
|
|
196
|
-
e.onChange({
|
|
197
|
-
table: n,
|
|
198
|
-
op: r,
|
|
199
|
-
old: null,
|
|
200
|
-
new: t,
|
|
201
|
-
netChange: !0
|
|
202
|
-
});
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
}, p = async () => {
|
|
206
|
-
if (!(c || u)) {
|
|
207
|
-
u = !0;
|
|
208
|
-
try {
|
|
209
|
-
if (r.length > 0) {
|
|
210
|
-
let t = r;
|
|
211
|
-
r = await J(e.run, t);
|
|
212
|
-
for (let e of t) r.includes(e) || a.add(e);
|
|
213
|
-
}
|
|
214
|
-
let t = await o();
|
|
215
|
-
if (d(t, s)) {
|
|
216
|
-
for (let t of e.tables) {
|
|
217
|
-
if (c) break;
|
|
218
|
-
r.includes(t) || (await f(t, s), a.delete(t));
|
|
219
|
-
}
|
|
220
|
-
s = d(t, s) ? t : s, e.onVersion?.(s);
|
|
221
|
-
}
|
|
222
|
-
} catch (n) {
|
|
223
|
-
c || (t.warn("cdc: poll cycle failed — retrying next tick", {}, n), e.onError?.(n));
|
|
224
|
-
} finally {
|
|
225
|
-
u = !1, c || (l = setTimeout(() => {
|
|
226
|
-
p();
|
|
227
|
-
}, n));
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
};
|
|
231
|
-
return l = setTimeout(() => {
|
|
232
|
-
p();
|
|
233
|
-
}, n), l.unref && l.unref(), t.info("cdc: Change Tracking reader attached", {
|
|
234
|
-
tables: e.tables.length,
|
|
235
|
-
from: e.startVersion ?? s
|
|
236
|
-
}), {
|
|
237
|
-
stop: async () => {
|
|
238
|
-
c = !0, l &&= (clearTimeout(l), null);
|
|
239
|
-
},
|
|
240
|
-
currentVersion: () => s
|
|
241
|
-
};
|
|
242
|
-
}, Q = F({ scope: "voltro:mssql" }), $ = async (e) => {
|
|
243
|
-
let t = e.changeStrategy ?? "inline", n = t;
|
|
244
|
-
t === "cdc" && !e.cdcConfig && (Q.warn("changeStrategy='cdc' requires cdcConfig (replicaId + includeTables); falling back to 'inline'."), n = "inline");
|
|
245
|
-
let r = e.tracerLayer ? a.mergeAll(e.sqlLayer, e.tracerLayer) : e.sqlLayer, i = o.make(r), s = new Te(await i.runPromise(I), i, n);
|
|
246
|
-
return n === "cdc" && e.cdcConfig && await s.startCdcConsumer(e.cdcConfig), s;
|
|
247
|
-
}, Te = class e {
|
|
248
|
-
sql;
|
|
249
|
-
runtime;
|
|
250
|
-
changeStrategy;
|
|
251
|
-
namespace;
|
|
252
|
-
emitter;
|
|
253
|
-
inflightTxns = 0;
|
|
254
|
-
reportEagerFallback = re(Q);
|
|
255
|
-
cdcHandle = null;
|
|
256
|
-
cdcCheckpointTimer = null;
|
|
257
|
-
cdcPendingVersion = null;
|
|
258
|
-
cdcReplicaId = "";
|
|
259
|
-
cdcStreamName = "default";
|
|
260
|
-
constructor(e, t, n = "inline", r = null, i) {
|
|
261
|
-
this.sql = e, this.runtime = t, this.changeStrategy = n, this.namespace = r, this.emitter = i ?? new ge(), ce(this.emitter);
|
|
262
|
-
}
|
|
263
|
-
get inlineEmit() {
|
|
264
|
-
return this.changeStrategy === "inline";
|
|
265
|
-
}
|
|
266
|
-
withNamespace(t) {
|
|
267
|
-
return t === this.namespace ? this : new e(this.sql, this.runtime, this.changeStrategy, t, this.emitter);
|
|
268
|
-
}
|
|
269
|
-
nsT(e) {
|
|
270
|
-
return oe(this.namespace, e);
|
|
271
|
-
}
|
|
272
|
-
__mssqlReplicationFriend = { runEffect: (e) => this.runtime.runPromise(e) };
|
|
273
|
-
async executeQuery(e, t) {
|
|
274
|
-
let n = T(e, this.sql, this.namespace), r = t ? i.provideService(n, this.sql.transactionService, t) : n, a = await k("mssql", "select", () => this.runtime.runPromise(r));
|
|
275
|
-
return E(a, e.table, "mssql");
|
|
276
|
-
}
|
|
277
|
-
decodeWritten(e, t) {
|
|
278
|
-
return E([t], e, "mssql")[0] ?? t;
|
|
279
|
-
}
|
|
280
|
-
async executeInsert(e, t, n, r, a) {
|
|
281
|
-
t = M(e, t);
|
|
282
|
-
let o = this.sql, s = U(o, this.nsT(e), (n) => o`INSERT INTO ${o(this.nsT(e))} ${o.insert(D(t, e)).returning(o`INSERTED.* INTO ${n}`)}`), c = n ? i.provideService(s, this.sql.transactionService, n) : s, l = (await this.runtime.runPromise(c))[0];
|
|
283
|
-
if (!l) throw Error(`MssqlStore.insert: row not returned post-insert in '${e}'`);
|
|
284
|
-
let u = this.decodeWritten(e, l);
|
|
285
|
-
return await this.routeEvent({
|
|
286
|
-
table: e,
|
|
287
|
-
op: "insert",
|
|
288
|
-
old: null,
|
|
289
|
-
new: u
|
|
290
|
-
}, r, n, a), u;
|
|
291
|
-
}
|
|
292
|
-
async executeUpdate(e, t, n, r, a, o) {
|
|
293
|
-
let s = this.sql, c = U(s, this.nsT(e), (r) => s`UPDATE ${s(this.nsT(e))} SET ${s.update(D(n, e)).returning(s`INSERTED.* INTO ${r}`)} WHERE ${s.and(j(t).map(([e, t]) => s`${s(e)} = ${t}`))}`), l = r ? i.provideService(c, this.sql.transactionService, r) : c, u = (await this.runtime.runPromise(l))[0];
|
|
294
|
-
if (!u) return null;
|
|
295
|
-
let d = this.decodeWritten(e, u);
|
|
296
|
-
return await this.routeEvent({
|
|
297
|
-
table: e,
|
|
298
|
-
op: "update",
|
|
299
|
-
old: null,
|
|
300
|
-
new: d
|
|
301
|
-
}, a, r, o), d;
|
|
302
|
-
}
|
|
303
|
-
async executeInsertMany(e, t, n, r, a) {
|
|
304
|
-
if (t = me(e, t), t.length === 0) return [];
|
|
305
|
-
let o = this.sql, s = b(t, v("mssql")), c = (t) => U(o, this.nsT(e), (n) => o`INSERT INTO ${o(this.nsT(e))} ${o.insert(t.map((t) => D(t, e))).returning(o`INSERTED.* INTO ${n}`)}`), l;
|
|
306
|
-
if (s.length === 1) {
|
|
307
|
-
let e = c(s[0]), t = n ? i.provideService(e, this.sql.transactionService, n) : e;
|
|
308
|
-
l = await this.runtime.runPromise(t);
|
|
309
|
-
} else if (n) {
|
|
310
|
-
let e = [];
|
|
311
|
-
for (let t of s) e.push(...await this.runtime.runPromise(i.provideService(c(t), this.sql.transactionService, n)));
|
|
312
|
-
l = e;
|
|
313
|
-
} else l = await this.runtime.runPromise(o.withTransaction(i.map(i.forEach(s, c, { concurrency: 1 }), (e) => e.flat())));
|
|
314
|
-
let u = t.map((e) => e.id), d = E(l, e, "mssql"), f = new Map(d.map((e) => [e.id, e])), p = u.map((e) => f.get(e)).filter((e) => e !== void 0), m = p.length === l.length ? p : d;
|
|
315
|
-
for (let t of m) await this.routeEvent({
|
|
316
|
-
table: e,
|
|
317
|
-
op: "insert",
|
|
318
|
-
old: null,
|
|
319
|
-
new: t
|
|
320
|
-
}, r, n, a);
|
|
321
|
-
return m;
|
|
322
|
-
}
|
|
323
|
-
async executePatchJson(e, t, n, r, a, o, s, c) {
|
|
324
|
-
let l = this.sql, u = D(ne(t, n, c), e), d = l.csv([S(l, "mssql", n, r), ...Object.entries(u).map(([e, t]) => l`${l(e)} = ${t}`)]), f = U(l, this.nsT(e), (n) => l`UPDATE ${l(this.nsT(e))} SET ${d} OUTPUT INSERTED.* INTO ${n} WHERE ${l.and(j(t).map(([e, t]) => l`${l(e)} = ${t}`))}`), p = a ? i.provideService(f, this.sql.transactionService, a) : f, m = (await this.runtime.runPromise(p))[0];
|
|
325
|
-
if (!m) return null;
|
|
326
|
-
let h = this.decodeWritten(e, m);
|
|
327
|
-
return await this.routeEvent({
|
|
328
|
-
table: e,
|
|
329
|
-
op: "update",
|
|
330
|
-
old: null,
|
|
331
|
-
new: h
|
|
332
|
-
}, o, a, s), h;
|
|
333
|
-
}
|
|
334
|
-
async executeDelete(e, t, n, r, a) {
|
|
335
|
-
let o = this.sql, s = U(o, this.nsT(e), (n) => o`DELETE FROM ${o(this.nsT(e))} OUTPUT DELETED.* INTO ${n} WHERE ${o.and(j(t).map(([e, t]) => o`${o(e)} = ${t}`))}`), c = n ? i.provideService(s, this.sql.transactionService, n) : s, l = (await this.runtime.runPromise(c))[0];
|
|
336
|
-
if (!l) return !1;
|
|
337
|
-
let u = this.decodeWritten(e, l);
|
|
338
|
-
return await this.routeEvent({
|
|
339
|
-
table: e,
|
|
340
|
-
op: "delete",
|
|
341
|
-
old: u,
|
|
342
|
-
new: null
|
|
343
|
-
}, r, n, a), !0;
|
|
344
|
-
}
|
|
345
|
-
async appendInTxn(e, t, n) {
|
|
346
|
-
let r = this.sql, a = r`INSERT INTO ${r(this.nsT(e))} ${r.insert(D(t, e))}`;
|
|
347
|
-
await this.runtime.runPromise(n ? i.provideService(a, this.sql.transactionService, n) : a);
|
|
348
|
-
}
|
|
349
|
-
async maxInTxn(e, t, n, r) {
|
|
350
|
-
let a = this.sql, o = Object.entries(n).map(([e, t]) => a`${a(e)} = ${t}`), s = a`SELECT MAX(${a(t)}) AS ${a("m")} FROM ${a(this.nsT(e))} WHERE ${a.and(o)}`, c = (await this.runtime.runPromise(r ? i.provideService(s, this.sql.transactionService, r) : s))[0]?.m;
|
|
351
|
-
return c == null ? null : Number(c);
|
|
352
|
-
}
|
|
353
|
-
async routeEvent(e, t, n = null, r) {
|
|
354
|
-
e = {
|
|
355
|
-
..._(r),
|
|
356
|
-
...e
|
|
357
|
-
}, A(e.table) && await fe({
|
|
358
|
-
append: (e, t) => this.appendInTxn(e, t, n),
|
|
359
|
-
maxOf: (e, t, r) => this.maxInTxn(e, t, r, n)
|
|
360
|
-
}, {
|
|
361
|
-
table: e.table,
|
|
362
|
-
op: e.op,
|
|
363
|
-
next: e.new,
|
|
364
|
-
prev: e.old,
|
|
365
|
-
traceId: e.traceId,
|
|
366
|
-
subjectId: e.subjectId
|
|
367
|
-
}), O(e.table) && (t === null ? this.inlineEmit && this.emitter.emit("change", e) : t.push(e));
|
|
368
|
-
}
|
|
369
|
-
query(e) {
|
|
370
|
-
return this.runWithEager(e, null);
|
|
371
|
-
}
|
|
372
|
-
raw(e, t) {
|
|
373
|
-
return this.rawOn(e, null);
|
|
374
|
-
}
|
|
375
|
-
rawOn(e, t) {
|
|
376
|
-
let n = w(e, this.sql), r = t ? i.provideService(n, this.sql.transactionService, t) : n;
|
|
377
|
-
return k("mssql", "raw", () => this.runtime.runPromise(r));
|
|
378
|
-
}
|
|
379
|
-
async runWithEager(e, t) {
|
|
380
|
-
if (!te(e)) return this.executeQuery(e, t);
|
|
381
|
-
let n = this.namespace === null ? x(e, this.sql, "mssql") : null;
|
|
382
|
-
if (n !== null) try {
|
|
383
|
-
let e = t ? i.provideService(n.fragment, this.sql.transactionService, t) : n.fragment, r = await k("mssql", "select", () => this.runtime.runPromise(e));
|
|
384
|
-
return n.decode(r);
|
|
385
|
-
} catch (t) {
|
|
386
|
-
if (t instanceof f) throw t;
|
|
387
|
-
this.reportEagerFallback({
|
|
388
|
-
dialect: "mssql",
|
|
389
|
-
table: e.table,
|
|
390
|
-
reason: "execute-failed",
|
|
391
|
-
error: t
|
|
392
|
-
});
|
|
393
|
-
}
|
|
394
|
-
else this.reportEagerFallback({
|
|
395
|
-
dialect: "mssql",
|
|
396
|
-
table: e.table,
|
|
397
|
-
reason: "not-compilable"
|
|
398
|
-
});
|
|
399
|
-
let r = await this.executeQuery(e, t);
|
|
400
|
-
return g(r, e.eager, e.sourceTable ?? le(e.table), (e) => this.executeQuery(e, t));
|
|
401
|
-
}
|
|
402
|
-
getInternalRunWithEager() {
|
|
403
|
-
return this.runWithEager.bind(this);
|
|
404
|
-
}
|
|
405
|
-
localWrite(e, t, n) {
|
|
406
|
-
let r = (e) => A(t) ? this.writeWithRecorders(n, e) : n(e, null, null);
|
|
407
|
-
return k("mssql", e, () => he(r));
|
|
408
|
-
}
|
|
409
|
-
async writeWithRecorders(e, t) {
|
|
410
|
-
let n = [], r = this.sql, a = await this.runtime.runPromise(r.withTransaction(i.flatMap(i.serviceOption(this.sql.transactionService), (r) => s.isNone(r) ? i.fail(/* @__PURE__ */ Error("MssqlStore.write: TransactionConnection missing.")) : i.tryPromise({
|
|
411
|
-
try: () => e(t, r.value, n),
|
|
412
|
-
catch: (e) => e
|
|
413
|
-
}))));
|
|
414
|
-
for (let e of n) this.emitChange(e);
|
|
415
|
-
return a;
|
|
416
|
-
}
|
|
417
|
-
insert(e, t) {
|
|
418
|
-
return this.localWrite("insert", e, (n, r, i) => this.executeInsert(e, t, r, i, n));
|
|
419
|
-
}
|
|
420
|
-
insertMany(e, t) {
|
|
421
|
-
return this.localWrite("insert", e, (n, r, i) => this.executeInsertMany(e, t, r, i, n));
|
|
422
|
-
}
|
|
423
|
-
patchJson(e, t, n, r, i) {
|
|
424
|
-
return this.localWrite("update", e, (a, o, s) => this.executePatchJson(e, t, n, r, o, s, a, i));
|
|
425
|
-
}
|
|
426
|
-
update(e, t, n) {
|
|
427
|
-
return this.localWrite("update", e, (r, i, a) => this.executeUpdate(e, t, n, i, a, r));
|
|
428
|
-
}
|
|
429
|
-
delete(e, t) {
|
|
430
|
-
return this.localWrite("delete", e, (n, r, i) => this.executeDelete(e, t, r, i, n));
|
|
431
|
-
}
|
|
432
|
-
updateMany(e, t, n) {
|
|
433
|
-
return this.executeUpdateMany(e, t, n, null, null);
|
|
434
|
-
}
|
|
435
|
-
deleteMany(e, t) {
|
|
436
|
-
return this.executeDeleteMany(e, t, null, null);
|
|
437
|
-
}
|
|
438
|
-
async executeUpdateMany(e, t, n, r, a, o) {
|
|
439
|
-
let s = this.sql, c = C(n.where, s, this.namespace), l = U(s, this.nsT(e), (n) => s`UPDATE ${s(this.nsT(e))} SET ${s.update(D(t, e))} OUTPUT INSERTED.* INTO ${n} WHERE ${c}`), u = r ? i.provideService(l, this.sql.transactionService, r) : l, d = await k("mssql", "update", () => this.runtime.runPromise(u));
|
|
440
|
-
for (let t of E(d, e, "mssql")) await this.routeEvent({
|
|
441
|
-
table: e,
|
|
442
|
-
op: "update",
|
|
443
|
-
old: null,
|
|
444
|
-
new: t
|
|
445
|
-
}, a, r, o);
|
|
446
|
-
return d.length;
|
|
447
|
-
}
|
|
448
|
-
async executeDeleteMany(e, t, n, r, a) {
|
|
449
|
-
let o = this.sql, s = C(t.where, o, this.namespace), c = U(o, this.nsT(e), (t) => o`DELETE FROM ${o(this.nsT(e))} OUTPUT DELETED.* INTO ${t} WHERE ${s}`), l = n ? i.provideService(c, this.sql.transactionService, n) : c, u = await k("mssql", "delete", () => this.runtime.runPromise(l));
|
|
450
|
-
for (let t of E(u, e, "mssql")) await this.routeEvent({
|
|
451
|
-
table: e,
|
|
452
|
-
op: "delete",
|
|
453
|
-
old: t,
|
|
454
|
-
new: null
|
|
455
|
-
}, r, n, a);
|
|
456
|
-
return u.length;
|
|
457
|
-
}
|
|
458
|
-
upsert(e, t, n) {
|
|
459
|
-
return this.localWrite("upsert", e, (r, i, a) => this.executeUpsert(e, t, n, i, a, r));
|
|
460
|
-
}
|
|
461
|
-
insertIgnore(e, t, n) {
|
|
462
|
-
return this.insertIgnoreWithOutcome(e, t, n).then((e) => e.row);
|
|
463
|
-
}
|
|
464
|
-
insertIgnoreWithOutcome(e, t, n) {
|
|
465
|
-
return this.localWrite("upsert", e, (r, i, a) => this.executeInsertIgnore(e, t, n, i, a, r));
|
|
466
|
-
}
|
|
467
|
-
async executeUpsert(e, t, n, r, i, a) {
|
|
468
|
-
if (P(n), t = M(e, t), typeof n.update != "function" && n.conflictColumns.length > 0) return this.mergeUpsert(e, t, {
|
|
469
|
-
conflictColumns: n.conflictColumns,
|
|
470
|
-
...n.update === void 0 ? {} : { update: n.update },
|
|
471
|
-
...n.updateValues === void 0 ? {} : { updateValues: n.updateValues }
|
|
472
|
-
}, r, i, a);
|
|
473
|
-
let o = await this.findByConflict(e, t, n.conflictColumns, r);
|
|
474
|
-
if (o) return await this.executeUpdate(e, Object.fromEntries(n.conflictColumns.map((e) => [e, o[e]])), N(t, o, n), r, i, a) ?? o;
|
|
475
|
-
try {
|
|
476
|
-
return await this.executeInsert(e, t, r, i, a);
|
|
477
|
-
} catch (o) {
|
|
478
|
-
if (!K(o)) throw o;
|
|
479
|
-
let s = await this.findByConflict(e, t, n.conflictColumns, r);
|
|
480
|
-
if (!s) throw o;
|
|
481
|
-
return await this.executeUpdate(e, Object.fromEntries(n.conflictColumns.map((e) => [e, s[e]])), N(t, s, n), r, i, a) ?? s;
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
async mergeUpsert(e, t, n, r, a, o) {
|
|
485
|
-
let s = this.sql, c = Object.keys(t), l = Array.isArray(n.update) ? n.update.filter((e) => c.includes(e)) : c.filter((e) => e !== "id" && !n.conflictColumns.includes(e)), u = D(t, e), d = c.map((e) => s`${u[e]}`), f = c.map((e) => s`${s(e)}`), p = n.conflictColumns.map((e) => s`tgt.${s(e)} = src.${s(e)}`), m = c.map((e) => s`${s(e)}`), h = c.map((e) => s`src.${s(e)}`), g = P(n), _ = D(g, e), v = [...l.filter((e) => !Object.hasOwn(g, e)).map((e) => s`tgt.${s(e)} = src.${s(e)}`), ...Object.entries(_).map(([e, t]) => s`tgt.${s(e)} = ${t}`)];
|
|
486
|
-
v.length === 0 && v.push(s`tgt.${s(n.conflictColumns[0])} = src.${s(n.conflictColumns[0])}`);
|
|
487
|
-
let y = U(s, this.nsT(e), (t) => s`
|
|
488
|
-
MERGE ${s(this.nsT(e))} WITH (HOLDLOCK) AS tgt
|
|
489
|
-
USING (VALUES (${s.csv(d)})) AS src (${s.csv(f)})
|
|
490
|
-
ON ${s.and(p)}
|
|
491
|
-
WHEN MATCHED THEN UPDATE SET ${s.csv(v)}
|
|
492
|
-
WHEN NOT MATCHED THEN INSERT (${s.csv(m)}) VALUES (${s.csv(h)})
|
|
493
|
-
OUTPUT $action AS ${s("__action")}, INSERTED.* INTO ${t};`, !0), b = r ? i.provideService(y, this.sql.transactionService, r) : y, x = (await this.runtime.runPromise(b))[0];
|
|
494
|
-
if (!x) throw Error(`MssqlStore.upsert: MERGE returned no row for '${e}'`);
|
|
495
|
-
let S = x.__action, { __action: C, ...w } = x, T = this.decodeWritten(e, w);
|
|
496
|
-
return await this.routeEvent({
|
|
497
|
-
table: e,
|
|
498
|
-
op: S === "INSERT" ? "insert" : "update",
|
|
499
|
-
old: null,
|
|
500
|
-
new: T
|
|
501
|
-
}, a, r, o), T;
|
|
502
|
-
}
|
|
503
|
-
async executeInsertIgnore(e, t, n, r, i, a) {
|
|
504
|
-
t = M(e, t);
|
|
505
|
-
let o = await this.findByConflict(e, t, n.conflictColumns, r);
|
|
506
|
-
if (o) return {
|
|
507
|
-
row: o,
|
|
508
|
-
outcome: "ignored"
|
|
509
|
-
};
|
|
510
|
-
try {
|
|
511
|
-
return {
|
|
512
|
-
row: await this.executeInsert(e, t, r, i, a),
|
|
513
|
-
outcome: "inserted"
|
|
514
|
-
};
|
|
515
|
-
} catch (i) {
|
|
516
|
-
if (!K(i)) throw i;
|
|
517
|
-
let a = await this.findByConflict(e, t, n.conflictColumns, r);
|
|
518
|
-
if (!a) throw i;
|
|
519
|
-
return {
|
|
520
|
-
row: a,
|
|
521
|
-
outcome: "ignored"
|
|
522
|
-
};
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
async findByConflict(e, t, n, r) {
|
|
526
|
-
if (n.length === 0) return;
|
|
527
|
-
let a = this.sql, o = n.map((e) => a`${a(e)} = ${t[e]}`), s = a`SELECT TOP 1 * FROM ${a(this.nsT(e))} WHERE ${a.and(o)}`, c = r ? i.provideService(s, this.sql.transactionService, r) : s, l = (await this.runtime.runPromise(c))[0];
|
|
528
|
-
return l ? this.decodeWritten(e, l) : void 0;
|
|
529
|
-
}
|
|
530
|
-
emitChange(e) {
|
|
531
|
-
this.emitter.emit("change", e);
|
|
532
|
-
}
|
|
533
|
-
async startCdcConsumer(e) {
|
|
534
|
-
if (this.cdcHandle) return;
|
|
535
|
-
this.cdcReplicaId = e.replicaId;
|
|
536
|
-
let t = e.includeTables ?? [];
|
|
537
|
-
t.length === 0 && Q.warn("cdc: no reactive tables to tail; Change Tracking reader idle. Set includeTables to enable.");
|
|
538
|
-
let n = await this.readCdcOffset(e.replicaId);
|
|
539
|
-
this.cdcHandle = await Z({
|
|
540
|
-
run: this.__mssqlReplicationFriend.runEffect,
|
|
541
|
-
tables: t,
|
|
542
|
-
startVersion: n,
|
|
543
|
-
onChange: (e) => this.injectExternalChange(e),
|
|
544
|
-
onVersion: (e) => {
|
|
545
|
-
this.cdcPendingVersion = e;
|
|
546
|
-
},
|
|
547
|
-
onError: (e) => Q.warn("cdc: consumer error", {}, e),
|
|
548
|
-
onResync: () => {
|
|
549
|
-
Q.warn("cdc: resynced to current CT version after retention gap — subscriptions self-heal on the next change");
|
|
550
|
-
}
|
|
551
|
-
}), this.cdcCheckpointTimer = setInterval(() => {
|
|
552
|
-
this.flushCdcOffset();
|
|
553
|
-
}, 1e3), this.cdcCheckpointTimer.unref && this.cdcCheckpointTimer.unref();
|
|
554
|
-
}
|
|
555
|
-
async readCdcOffset(e) {
|
|
556
|
-
try {
|
|
557
|
-
let t = this.sql, n = (await this.runtime.runPromise(t`
|
|
558
|
-
SELECT TOP 1 ${t("ctVersion")} FROM ${t(u)}
|
|
559
|
-
WHERE ${t("id")} = ${e}`))[0]?.ctVersion;
|
|
560
|
-
return n ? (Q.info("cdc: resuming from persisted CT version", {
|
|
561
|
-
replicaId: e,
|
|
562
|
-
version: n
|
|
563
|
-
}), n) : null;
|
|
564
|
-
} catch (t) {
|
|
565
|
-
return Q.warn("cdc: no readable offset; starting at current CT version", { replicaId: e }, t), null;
|
|
566
|
-
}
|
|
567
|
-
}
|
|
568
|
-
async flushCdcOffset() {
|
|
569
|
-
let e = this.cdcPendingVersion;
|
|
570
|
-
if (e !== null) {
|
|
571
|
-
this.cdcPendingVersion = null;
|
|
572
|
-
try {
|
|
573
|
-
let t = this.cdcReplicaId;
|
|
574
|
-
await this.executeUpsert(u, {
|
|
575
|
-
id: t,
|
|
576
|
-
replicaId: t,
|
|
577
|
-
streamName: this.cdcStreamName,
|
|
578
|
-
ctVersion: e,
|
|
579
|
-
updatedAt: /* @__PURE__ */ new Date()
|
|
580
|
-
}, {
|
|
581
|
-
conflictColumns: ["id"],
|
|
582
|
-
update: ["ctVersion", "updatedAt"]
|
|
583
|
-
}, null, null);
|
|
584
|
-
} catch (t) {
|
|
585
|
-
this.cdcPendingVersion = e, Q.warn("cdc: checkpoint write failed", {}, t);
|
|
586
|
-
}
|
|
587
|
-
}
|
|
588
|
-
}
|
|
589
|
-
getInternalExecuteQuery() {
|
|
590
|
-
return this.executeQuery.bind(this);
|
|
591
|
-
}
|
|
592
|
-
getInternalExecuteInsert() {
|
|
593
|
-
return this.executeInsert.bind(this);
|
|
594
|
-
}
|
|
595
|
-
getInternalExecuteInsertMany() {
|
|
596
|
-
return this.executeInsertMany.bind(this);
|
|
597
|
-
}
|
|
598
|
-
getInternalExecutePatchJson() {
|
|
599
|
-
return this.executePatchJson.bind(this);
|
|
600
|
-
}
|
|
601
|
-
getInternalExecuteUpdate() {
|
|
602
|
-
return this.executeUpdate.bind(this);
|
|
603
|
-
}
|
|
604
|
-
getInternalExecuteUpdateMany() {
|
|
605
|
-
return this.executeUpdateMany.bind(this);
|
|
606
|
-
}
|
|
607
|
-
getInternalExecuteDeleteMany() {
|
|
608
|
-
return this.executeDeleteMany.bind(this);
|
|
609
|
-
}
|
|
610
|
-
getInternalExecuteDelete() {
|
|
611
|
-
return this.executeDelete.bind(this);
|
|
612
|
-
}
|
|
613
|
-
getInternalExecuteUpsert() {
|
|
614
|
-
return this.executeUpsert.bind(this);
|
|
615
|
-
}
|
|
616
|
-
getInternalExecuteInsertIgnore() {
|
|
617
|
-
return this.executeInsertIgnore.bind(this);
|
|
618
|
-
}
|
|
619
|
-
async emptyTables(e) {
|
|
620
|
-
await this.emptyTablesOn(e, null);
|
|
621
|
-
}
|
|
622
|
-
async incomingForeignKeys(e) {
|
|
623
|
-
if (e.length === 0) return [];
|
|
624
|
-
let t = this.sql;
|
|
625
|
-
return (await this.runtime.runPromise(t`
|
|
626
|
-
SELECT child.name AS fromTable, col.name AS columnName, parent.name AS toTable
|
|
627
|
-
FROM sys.foreign_key_columns fkc
|
|
628
|
-
JOIN sys.tables child ON child.object_id = fkc.parent_object_id
|
|
629
|
-
JOIN sys.tables parent ON parent.object_id = fkc.referenced_object_id
|
|
630
|
-
JOIN sys.columns col ON col.object_id = fkc.parent_object_id AND col.column_id = fkc.parent_column_id
|
|
631
|
-
WHERE parent.name IN ${t.in(e)}
|
|
632
|
-
AND child.name NOT IN ${t.in(e)}`)).map((e) => ({
|
|
633
|
-
from: e.fromTable,
|
|
634
|
-
column: e.columnName,
|
|
635
|
-
to: e.toTable
|
|
636
|
-
}));
|
|
637
|
-
}
|
|
638
|
-
async emptyTablesOn(e, t) {
|
|
639
|
-
if (e.length === 0) return;
|
|
640
|
-
let n = this.sql, r = (e) => this.nsT(e), a = (e, t) => n.unsafe(`ALTER TABLE ${se(r(e), "mssql")} ${t ? "WITH CHECK CHECK" : "NOCHECK"} CONSTRAINT ALL`), o = i.acquireUseRelease(i.forEach(e, (e) => a(e, !1), { discard: !0 }), () => i.forEach(e, (e) => n`DELETE FROM ${n(r(e))}`, { discard: !0 }), () => i.orDie(i.ignore(i.forEach(e, (e) => a(e, !0), { discard: !0 })))), s = t === null ? n.withTransaction(o) : i.provideService(o, this.sql.transactionService, t);
|
|
641
|
-
await this.runtime.runPromise(s);
|
|
642
|
-
}
|
|
643
|
-
async transactional(e) {
|
|
644
|
-
this.inflightTxns++;
|
|
645
|
-
try {
|
|
646
|
-
return await de({
|
|
647
|
-
...this.txnSpec("MssqlStore.transactional"),
|
|
648
|
-
work: e,
|
|
649
|
-
makeView: (e, t) => new Ee(this, e, t)
|
|
650
|
-
});
|
|
651
|
-
} finally {
|
|
652
|
-
this.inflightTxns--;
|
|
653
|
-
}
|
|
654
|
-
}
|
|
655
|
-
get transactionService() {
|
|
656
|
-
return this.sql.transactionService;
|
|
657
|
-
}
|
|
658
|
-
txnSpec(e) {
|
|
659
|
-
return {
|
|
660
|
-
label: e,
|
|
661
|
-
dialect: "mssql",
|
|
662
|
-
withTransaction: (e) => this.sql.withTransaction(e),
|
|
663
|
-
transactionService: this.sql.transactionService,
|
|
664
|
-
runPromiseExit: (e) => this.runtime.runPromiseExit(e),
|
|
665
|
-
isRetryable: G,
|
|
666
|
-
span: {
|
|
667
|
-
name: "store.transactional",
|
|
668
|
-
attributes: {
|
|
669
|
-
"db.system": "mssql",
|
|
670
|
-
"db.operation": "transaction"
|
|
671
|
-
}
|
|
672
|
-
}
|
|
673
|
-
};
|
|
674
|
-
}
|
|
675
|
-
onChange(e) {
|
|
676
|
-
return this.emitter.on("change", e), () => {
|
|
677
|
-
this.emitter.off("change", e);
|
|
678
|
-
};
|
|
679
|
-
}
|
|
680
|
-
get changeScope() {
|
|
681
|
-
return this.changeStrategy === "cdc" ? "fleet" : "local";
|
|
682
|
-
}
|
|
683
|
-
injectExternalChange(e) {
|
|
684
|
-
O(e.table) && this.emitter.emit("change", ee(e));
|
|
685
|
-
}
|
|
686
|
-
run(e) {
|
|
687
|
-
return this.runtime.runPromise(e);
|
|
688
|
-
}
|
|
689
|
-
async close(e = 5e3) {
|
|
690
|
-
if (this.cdcCheckpointTimer &&= (clearInterval(this.cdcCheckpointTimer), null), this.cdcHandle) {
|
|
691
|
-
let e = this.cdcHandle.currentVersion();
|
|
692
|
-
e !== null && (this.cdcPendingVersion = e), await this.flushCdcOffset(), await this.cdcHandle.stop(), this.cdcHandle = null;
|
|
693
|
-
}
|
|
694
|
-
if (this.inflightTxns > 0) {
|
|
695
|
-
let t = Date.now() + e;
|
|
696
|
-
for (; this.inflightTxns > 0 && Date.now() < t;) await new Promise((e) => setTimeout(e, 25));
|
|
697
|
-
this.inflightTxns > 0 && Q.warn("close: grace period expired with in-flight transactions", {
|
|
698
|
-
gracePeriodMs: e,
|
|
699
|
-
inflight: this.inflightTxns
|
|
700
|
-
});
|
|
701
|
-
}
|
|
702
|
-
await this.runtime.dispose();
|
|
703
|
-
}
|
|
704
|
-
async ping() {
|
|
705
|
-
await this.runtime.runPromise(this.sql`SELECT 1`);
|
|
706
|
-
}
|
|
707
|
-
}, Ee = class {
|
|
708
|
-
parent;
|
|
709
|
-
txn;
|
|
710
|
-
attr;
|
|
711
|
-
events = [];
|
|
712
|
-
aborts = ie((e) => G(e));
|
|
713
|
-
committed = !1;
|
|
714
|
-
constructor(e, t, n = void 0) {
|
|
715
|
-
this.parent = e, this.txn = t, this.attr = n;
|
|
716
|
-
}
|
|
717
|
-
savepoint(e) {
|
|
718
|
-
return ue({
|
|
719
|
-
tracker: this.aborts,
|
|
720
|
-
name: `voltro_sp_${++this.savepointCounter}`,
|
|
721
|
-
spelling: "mssql",
|
|
722
|
-
exec: (e) => this.parent.run(i.provideService(I.pipe(i.flatMap((t) => t.unsafe(e))), this.parent.transactionService, this.txn))
|
|
723
|
-
}, e);
|
|
724
|
-
}
|
|
725
|
-
savepointCounter = 0;
|
|
726
|
-
run(e) {
|
|
727
|
-
return this.aborts.track(() => this.parent.run(ae(e, this.parent.transactionService, this.txn)));
|
|
728
|
-
}
|
|
729
|
-
abortedBy() {
|
|
730
|
-
return this.aborts.abortedBy();
|
|
731
|
-
}
|
|
732
|
-
raw(e, t) {
|
|
733
|
-
return this.aborts.track(() => this.parent.rawOn(e, this.txn));
|
|
734
|
-
}
|
|
735
|
-
query(e) {
|
|
736
|
-
return this.aborts.track(() => this.parent.getInternalRunWithEager()(e, this.txn));
|
|
737
|
-
}
|
|
738
|
-
emptyTables(e) {
|
|
739
|
-
return this.aborts.track(() => this.parent.emptyTablesOn(e, this.txn));
|
|
740
|
-
}
|
|
741
|
-
insert(e, t) {
|
|
742
|
-
return this.aborts.track(() => this.parent.getInternalExecuteInsert()(e, t, this.txn, this.events, this.attr));
|
|
743
|
-
}
|
|
744
|
-
insertMany(e, t) {
|
|
745
|
-
return this.aborts.track(() => this.parent.getInternalExecuteInsertMany()(e, t, this.txn, this.events, this.attr));
|
|
746
|
-
}
|
|
747
|
-
patchJson(e, t, n, r, i) {
|
|
748
|
-
return this.aborts.track(() => this.parent.getInternalExecutePatchJson()(e, t, n, r, this.txn, this.events, this.attr, i));
|
|
749
|
-
}
|
|
750
|
-
update(e, t, n) {
|
|
751
|
-
return this.aborts.track(() => this.parent.getInternalExecuteUpdate()(e, t, n, this.txn, this.events, this.attr));
|
|
752
|
-
}
|
|
753
|
-
delete(e, t) {
|
|
754
|
-
return this.aborts.track(() => this.parent.getInternalExecuteDelete()(e, t, this.txn, this.events, this.attr));
|
|
755
|
-
}
|
|
756
|
-
updateMany(e, t, n) {
|
|
757
|
-
return this.aborts.track(() => this.parent.getInternalExecuteUpdateMany()(e, t, n, this.txn, this.events, this.attr));
|
|
758
|
-
}
|
|
759
|
-
deleteMany(e, t) {
|
|
760
|
-
return this.aborts.track(() => this.parent.getInternalExecuteDeleteMany()(e, t, this.txn, this.events, this.attr));
|
|
761
|
-
}
|
|
762
|
-
upsert(e, t, n) {
|
|
763
|
-
return this.aborts.track(() => this.parent.getInternalExecuteUpsert()(e, t, n, this.txn, this.events, this.attr));
|
|
764
|
-
}
|
|
765
|
-
insertIgnore(e, t, n) {
|
|
766
|
-
return this.insertIgnoreWithOutcome(e, t, n).then((e) => e.row);
|
|
767
|
-
}
|
|
768
|
-
insertIgnoreWithOutcome(e, t, n) {
|
|
769
|
-
return this.aborts.track(() => this.parent.getInternalExecuteInsertIgnore()(e, t, n, this.txn, this.events, this.attr));
|
|
770
|
-
}
|
|
771
|
-
transactional(e) {
|
|
772
|
-
return Promise.reject(/* @__PURE__ */ Error("MssqlStore.transactional: nested transactions are not supported."));
|
|
773
|
-
}
|
|
774
|
-
onChange(e) {
|
|
775
|
-
throw Error("MssqlTransactionalView.onChange: not supported inside a transaction.");
|
|
776
|
-
}
|
|
777
|
-
injectExternalChange(e) {
|
|
778
|
-
throw Error("MssqlTransactionalView.injectExternalChange: not supported inside a transaction.");
|
|
779
|
-
}
|
|
780
|
-
commitEvents() {
|
|
781
|
-
if (!this.committed) {
|
|
782
|
-
this.committed = !0;
|
|
783
|
-
for (let e of this.events) this.parent.emitChange(e);
|
|
784
|
-
this.events.length = 0;
|
|
785
|
-
}
|
|
786
|
-
}
|
|
787
|
-
}, De = (e) => e.__mssqlReplicationFriend ?? null, Oe = (e, t) => e === t ? 0 : e < t ? -1 : 1, ke = () => ({
|
|
788
|
-
async capturePrimaryPosition(e) {
|
|
789
|
-
let t = De(e);
|
|
790
|
-
if (t === null) throw Error("mssqlReplicationAdapter: primary is not an MssqlStore (missing __mssqlReplicationFriend).");
|
|
791
|
-
return t.runEffect(i.gen(function* () {
|
|
792
|
-
return (yield* (yield* I)`
|
|
793
|
-
SELECT CONVERT(VARCHAR(40), end_of_log_lsn) AS lsn
|
|
794
|
-
FROM sys.dm_hadr_database_replica_states
|
|
795
|
-
WHERE database_id = DB_ID()
|
|
796
|
-
AND is_local = 1
|
|
797
|
-
AND is_primary_replica = 1
|
|
798
|
-
`)[0]?.lsn ?? "00000000:00000000:0000";
|
|
799
|
-
}));
|
|
800
|
-
},
|
|
801
|
-
async probeReplicaPosition(e) {
|
|
802
|
-
let t = De(e);
|
|
803
|
-
if (t === null) throw Error("mssqlReplicationAdapter: replica is not an MssqlStore.");
|
|
804
|
-
return t.runEffect(i.gen(function* () {
|
|
805
|
-
return (yield* (yield* I)`
|
|
806
|
-
SELECT CONVERT(VARCHAR(40), last_hardened_lsn) AS lsn
|
|
807
|
-
FROM sys.dm_hadr_database_replica_states
|
|
808
|
-
WHERE database_id = DB_ID()
|
|
809
|
-
AND is_local = 1
|
|
810
|
-
`)[0]?.lsn ?? "00000000:00000000:0000";
|
|
811
|
-
}));
|
|
812
|
-
},
|
|
813
|
-
compare(e, t) {
|
|
814
|
-
return Oe(t, e) >= 0 ? "caught-up" : "behind";
|
|
815
|
-
}
|
|
816
|
-
}), Ae = {
|
|
1
|
+
import { MssqlClient as e, connectionFromConfig as t, makeMssqlSqlLayer as n, makeMssqlSqlLayerFromConfig as r } from "./sqlLayer.js";
|
|
2
|
+
import { mssqlRetryFilter as i } from "./retry.js";
|
|
3
|
+
import { ensureChangeTracking as a, startChangeTrackingCdc as o } from "./changeTrackingCdc.js";
|
|
4
|
+
import { CDC_OFFSETS_TABLE as s, _voltroMssqlCdcOffsetsTable as c } from "./cdcOffsetsTable.js";
|
|
5
|
+
import { makeMssqlStore as l } from "./store.js";
|
|
6
|
+
import { mssqlReplicationAdapter as u } from "./replicationAdapter.js";
|
|
7
|
+
//#region src/index.ts
|
|
8
|
+
var d = {
|
|
817
9
|
id: "mssql",
|
|
818
|
-
makeSqlLayer: (e) =>
|
|
819
|
-
makeStore: (e) =>
|
|
10
|
+
makeSqlLayer: (e) => r(e),
|
|
11
|
+
makeStore: (e) => l(e),
|
|
820
12
|
compileContains: (e, t, n) => n`${e} LIKE ${`%${t.replace(/[\\%_[\]]/g, (e) => `\\${e}`)}%`} ESCAPE '\\'`,
|
|
821
|
-
retryFilter:
|
|
13
|
+
retryFilter: i
|
|
822
14
|
};
|
|
823
15
|
//#endregion
|
|
824
|
-
export {
|
|
16
|
+
export { s as CDC_OFFSETS_TABLE, e as MssqlClient, c as _voltroMssqlCdcOffsetsTable, t as connectionFromConfig, a as ensureChangeTracking, n as makeMssqlSqlLayer, r as makeMssqlSqlLayerFromConfig, l as makeMssqlStore, d as mssqlDialect, u as mssqlReplicationAdapter, i as mssqlRetryFilter, o as startChangeTrackingCdc };
|