@prisma/adapter-mssql 6.15.0-dev.3 → 6.15.0-dev.30
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/index.d.mts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +282 -73
- package/dist/index.mjs +271 -59
- package/package.json +4 -7
package/dist/index.d.mts
CHANGED
|
@@ -26,11 +26,10 @@ declare class MssqlQueryable implements SqlQueryable {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
export declare class PrismaMssql implements SqlDriverAdapterFactory {
|
|
29
|
-
private
|
|
30
|
-
private readonly options?;
|
|
29
|
+
#private;
|
|
31
30
|
readonly provider = "sqlserver";
|
|
32
31
|
readonly adapterName: string;
|
|
33
|
-
constructor(
|
|
32
|
+
constructor(configOrString: sql.config | string, options?: PrismaMssqlOptions);
|
|
34
33
|
connect(): Promise<PrismaMssqlAdapter>;
|
|
35
34
|
}
|
|
36
35
|
|
|
@@ -47,6 +46,8 @@ declare class PrismaMssqlAdapter extends MssqlQueryable implements SqlDriverAdap
|
|
|
47
46
|
|
|
48
47
|
declare type PrismaMssqlOptions = {
|
|
49
48
|
schema?: string;
|
|
49
|
+
onPoolError?: (err: unknown) => void;
|
|
50
|
+
onConnectionError?: (err: unknown) => void;
|
|
50
51
|
};
|
|
51
52
|
|
|
52
53
|
export { }
|
package/dist/index.d.ts
CHANGED
|
@@ -26,11 +26,10 @@ declare class MssqlQueryable implements SqlQueryable {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
export declare class PrismaMssql implements SqlDriverAdapterFactory {
|
|
29
|
-
private
|
|
30
|
-
private readonly options?;
|
|
29
|
+
#private;
|
|
31
30
|
readonly provider = "sqlserver";
|
|
32
31
|
readonly adapterName: string;
|
|
33
|
-
constructor(
|
|
32
|
+
constructor(configOrString: sql.config | string, options?: PrismaMssqlOptions);
|
|
34
33
|
connect(): Promise<PrismaMssqlAdapter>;
|
|
35
34
|
}
|
|
36
35
|
|
|
@@ -47,6 +46,8 @@ declare class PrismaMssqlAdapter extends MssqlQueryable implements SqlDriverAdap
|
|
|
47
46
|
|
|
48
47
|
declare type PrismaMssqlOptions = {
|
|
49
48
|
schema?: string;
|
|
49
|
+
onPoolError?: (err: unknown) => void;
|
|
50
|
+
onConnectionError?: (err: unknown) => void;
|
|
50
51
|
};
|
|
51
52
|
|
|
52
53
|
export { }
|
package/dist/index.js
CHANGED
|
@@ -35,60 +35,201 @@ __export(index_exports, {
|
|
|
35
35
|
module.exports = __toCommonJS(index_exports);
|
|
36
36
|
|
|
37
37
|
// src/mssql.ts
|
|
38
|
-
var
|
|
38
|
+
var import_driver_adapter_utils3 = require("@prisma/driver-adapter-utils");
|
|
39
39
|
var import_async_mutex = require("async-mutex");
|
|
40
|
-
var
|
|
40
|
+
var import_mssql3 = __toESM(require("mssql"));
|
|
41
41
|
|
|
42
42
|
// package.json
|
|
43
43
|
var name = "@prisma/adapter-mssql";
|
|
44
44
|
|
|
45
|
-
// src/
|
|
45
|
+
// src/connection-string.ts
|
|
46
46
|
var import_driver_adapter_utils = require("@prisma/driver-adapter-utils");
|
|
47
47
|
var import_mssql = __toESM(require("mssql"));
|
|
48
|
+
function mapIsolationLevelFromString(level) {
|
|
49
|
+
const normalizedLevel = level.toUpperCase().replace(/\s+/g, "");
|
|
50
|
+
switch (normalizedLevel) {
|
|
51
|
+
case "READCOMMITTED":
|
|
52
|
+
return import_mssql.default.ISOLATION_LEVEL.READ_COMMITTED;
|
|
53
|
+
case "READUNCOMMITTED":
|
|
54
|
+
return import_mssql.default.ISOLATION_LEVEL.READ_UNCOMMITTED;
|
|
55
|
+
case "REPEATABLEREAD":
|
|
56
|
+
return import_mssql.default.ISOLATION_LEVEL.REPEATABLE_READ;
|
|
57
|
+
case "SERIALIZABLE":
|
|
58
|
+
return import_mssql.default.ISOLATION_LEVEL.SERIALIZABLE;
|
|
59
|
+
case "SNAPSHOT":
|
|
60
|
+
return import_mssql.default.ISOLATION_LEVEL.SNAPSHOT;
|
|
61
|
+
default:
|
|
62
|
+
throw new Error(`Invalid isolation level: ${level}`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
var debug = (0, import_driver_adapter_utils.Debug)("prisma:driver-adapter:mssql:connection-string");
|
|
66
|
+
function extractSchemaFromConnectionString(connectionString) {
|
|
67
|
+
const withoutProtocol = connectionString.replace(/^sqlserver:\/\//, "");
|
|
68
|
+
const parts = withoutProtocol.split(";");
|
|
69
|
+
for (const part of parts) {
|
|
70
|
+
const [key, value] = part.split("=", 2);
|
|
71
|
+
if (key?.trim() === "schema") {
|
|
72
|
+
return value?.trim();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return void 0;
|
|
76
|
+
}
|
|
77
|
+
function parseConnectionString(connectionString) {
|
|
78
|
+
const withoutProtocol = connectionString.replace(/^sqlserver:\/\//, "");
|
|
79
|
+
const [hostPart, ...paramParts] = withoutProtocol.split(";");
|
|
80
|
+
const config = {
|
|
81
|
+
server: "",
|
|
82
|
+
options: {},
|
|
83
|
+
pool: {}
|
|
84
|
+
};
|
|
85
|
+
const [host, portStr] = hostPart.split(":");
|
|
86
|
+
config.server = host.trim();
|
|
87
|
+
if (portStr) {
|
|
88
|
+
const port = parseInt(portStr, 10);
|
|
89
|
+
if (isNaN(port)) {
|
|
90
|
+
throw new Error(`Invalid port number: ${portStr}`);
|
|
91
|
+
}
|
|
92
|
+
config.port = port;
|
|
93
|
+
}
|
|
94
|
+
for (const part of paramParts) {
|
|
95
|
+
const [key, value] = part.split("=", 2);
|
|
96
|
+
if (!key) continue;
|
|
97
|
+
const trimmedKey = key.trim();
|
|
98
|
+
const trimmedValue = value.trim();
|
|
99
|
+
switch (trimmedKey) {
|
|
100
|
+
case "database":
|
|
101
|
+
case "initial catalog":
|
|
102
|
+
config.database = trimmedValue;
|
|
103
|
+
break;
|
|
104
|
+
case "user":
|
|
105
|
+
case "username":
|
|
106
|
+
case "uid":
|
|
107
|
+
case "userid":
|
|
108
|
+
config.user = trimmedValue;
|
|
109
|
+
break;
|
|
110
|
+
case "password":
|
|
111
|
+
case "pwd":
|
|
112
|
+
config.password = trimmedValue;
|
|
113
|
+
break;
|
|
114
|
+
case "encrypt":
|
|
115
|
+
config.options = config.options || {};
|
|
116
|
+
config.options.encrypt = trimmedValue.toLowerCase() === "true";
|
|
117
|
+
break;
|
|
118
|
+
case "trustServerCertificate":
|
|
119
|
+
config.options = config.options || {};
|
|
120
|
+
config.options.trustServerCertificate = trimmedValue.toLowerCase() === "true";
|
|
121
|
+
break;
|
|
122
|
+
case "connectionLimit": {
|
|
123
|
+
config.pool = config.pool || {};
|
|
124
|
+
const limit = parseInt(trimmedValue, 10);
|
|
125
|
+
if (isNaN(limit)) {
|
|
126
|
+
throw new Error(`Invalid connection limit: ${trimmedValue}`);
|
|
127
|
+
}
|
|
128
|
+
config.pool.max = limit;
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
case "connectTimeout":
|
|
132
|
+
case "connectionTimeout": {
|
|
133
|
+
const connectTimeout = parseInt(trimmedValue, 10);
|
|
134
|
+
if (isNaN(connectTimeout)) {
|
|
135
|
+
throw new Error(`Invalid connection timeout: ${trimmedValue}`);
|
|
136
|
+
}
|
|
137
|
+
config.connectionTimeout = connectTimeout;
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
case "loginTimeout": {
|
|
141
|
+
const loginTimeout = parseInt(trimmedValue, 10);
|
|
142
|
+
if (isNaN(loginTimeout)) {
|
|
143
|
+
throw new Error(`Invalid login timeout: ${trimmedValue}`);
|
|
144
|
+
}
|
|
145
|
+
config.connectionTimeout = loginTimeout;
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
148
|
+
case "socketTimeout": {
|
|
149
|
+
const socketTimeout = parseInt(trimmedValue, 10);
|
|
150
|
+
if (isNaN(socketTimeout)) {
|
|
151
|
+
throw new Error(`Invalid socket timeout: ${trimmedValue}`);
|
|
152
|
+
}
|
|
153
|
+
config.requestTimeout = socketTimeout;
|
|
154
|
+
break;
|
|
155
|
+
}
|
|
156
|
+
case "poolTimeout": {
|
|
157
|
+
const poolTimeout = parseInt(trimmedValue, 10);
|
|
158
|
+
if (isNaN(poolTimeout)) {
|
|
159
|
+
throw new Error(`Invalid pool timeout: ${trimmedValue}`);
|
|
160
|
+
}
|
|
161
|
+
config.pool = config.pool || {};
|
|
162
|
+
config.pool.acquireTimeoutMillis = poolTimeout * 1e3;
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
165
|
+
case "applicationName":
|
|
166
|
+
case "application name":
|
|
167
|
+
config.options = config.options || {};
|
|
168
|
+
config.options.appName = trimmedValue;
|
|
169
|
+
break;
|
|
170
|
+
case "isolationLevel":
|
|
171
|
+
config.options = config.options || {};
|
|
172
|
+
config.options.isolationLevel = mapIsolationLevelFromString(trimmedValue);
|
|
173
|
+
break;
|
|
174
|
+
case "schema":
|
|
175
|
+
break;
|
|
176
|
+
default:
|
|
177
|
+
debug(`Unknown connection string parameter: ${trimmedKey}`);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
if (!config.server || config.server.trim() === "") {
|
|
181
|
+
throw new Error("Server host is required in connection string");
|
|
182
|
+
}
|
|
183
|
+
return config;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// src/conversion.ts
|
|
187
|
+
var import_driver_adapter_utils2 = require("@prisma/driver-adapter-utils");
|
|
188
|
+
var import_mssql2 = __toESM(require("mssql"));
|
|
48
189
|
function mapColumnType(col) {
|
|
49
190
|
switch (col.type) {
|
|
50
|
-
case
|
|
51
|
-
case
|
|
52
|
-
case
|
|
53
|
-
case
|
|
54
|
-
case
|
|
55
|
-
case
|
|
56
|
-
case
|
|
57
|
-
return
|
|
58
|
-
case
|
|
59
|
-
return
|
|
60
|
-
case
|
|
61
|
-
case
|
|
62
|
-
case
|
|
63
|
-
return
|
|
64
|
-
case
|
|
65
|
-
return
|
|
66
|
-
case
|
|
67
|
-
case
|
|
68
|
-
case
|
|
69
|
-
case
|
|
70
|
-
return
|
|
71
|
-
case
|
|
72
|
-
return
|
|
73
|
-
case
|
|
74
|
-
case
|
|
75
|
-
case
|
|
76
|
-
return
|
|
77
|
-
case
|
|
78
|
-
return
|
|
79
|
-
case
|
|
80
|
-
case
|
|
81
|
-
return
|
|
82
|
-
case
|
|
83
|
-
return
|
|
84
|
-
case
|
|
85
|
-
return
|
|
86
|
-
case
|
|
87
|
-
case
|
|
88
|
-
case
|
|
89
|
-
return
|
|
191
|
+
case import_mssql2.default.VarChar:
|
|
192
|
+
case import_mssql2.default.Char:
|
|
193
|
+
case import_mssql2.default.NVarChar:
|
|
194
|
+
case import_mssql2.default.NChar:
|
|
195
|
+
case import_mssql2.default.Text:
|
|
196
|
+
case import_mssql2.default.NText:
|
|
197
|
+
case import_mssql2.default.Xml:
|
|
198
|
+
return import_driver_adapter_utils2.ColumnTypeEnum.Text;
|
|
199
|
+
case import_mssql2.default.Bit:
|
|
200
|
+
return import_driver_adapter_utils2.ColumnTypeEnum.Boolean;
|
|
201
|
+
case import_mssql2.default.TinyInt:
|
|
202
|
+
case import_mssql2.default.SmallInt:
|
|
203
|
+
case import_mssql2.default.Int:
|
|
204
|
+
return import_driver_adapter_utils2.ColumnTypeEnum.Int32;
|
|
205
|
+
case import_mssql2.default.BigInt:
|
|
206
|
+
return import_driver_adapter_utils2.ColumnTypeEnum.Int64;
|
|
207
|
+
case import_mssql2.default.DateTime2:
|
|
208
|
+
case import_mssql2.default.SmallDateTime:
|
|
209
|
+
case import_mssql2.default.DateTime:
|
|
210
|
+
case import_mssql2.default.DateTimeOffset:
|
|
211
|
+
return import_driver_adapter_utils2.ColumnTypeEnum.DateTime;
|
|
212
|
+
case import_mssql2.default.Real:
|
|
213
|
+
return import_driver_adapter_utils2.ColumnTypeEnum.Float;
|
|
214
|
+
case import_mssql2.default.Float:
|
|
215
|
+
case import_mssql2.default.Money:
|
|
216
|
+
case import_mssql2.default.SmallMoney:
|
|
217
|
+
return import_driver_adapter_utils2.ColumnTypeEnum.Double;
|
|
218
|
+
case import_mssql2.default.UniqueIdentifier:
|
|
219
|
+
return import_driver_adapter_utils2.ColumnTypeEnum.Uuid;
|
|
220
|
+
case import_mssql2.default.Decimal:
|
|
221
|
+
case import_mssql2.default.Numeric:
|
|
222
|
+
return import_driver_adapter_utils2.ColumnTypeEnum.Numeric;
|
|
223
|
+
case import_mssql2.default.Date:
|
|
224
|
+
return import_driver_adapter_utils2.ColumnTypeEnum.Date;
|
|
225
|
+
case import_mssql2.default.Time:
|
|
226
|
+
return import_driver_adapter_utils2.ColumnTypeEnum.Time;
|
|
227
|
+
case import_mssql2.default.VarBinary:
|
|
228
|
+
case import_mssql2.default.Binary:
|
|
229
|
+
case import_mssql2.default.Image:
|
|
230
|
+
return import_driver_adapter_utils2.ColumnTypeEnum.Bytes;
|
|
90
231
|
default:
|
|
91
|
-
throw new
|
|
232
|
+
throw new import_driver_adapter_utils2.DriverAdapterError({
|
|
92
233
|
kind: "UnsupportedNativeDataType",
|
|
93
234
|
type: col["udt"]?.name ?? "N/A"
|
|
94
235
|
});
|
|
@@ -97,25 +238,28 @@ function mapColumnType(col) {
|
|
|
97
238
|
function mapIsolationLevel(level) {
|
|
98
239
|
switch (level) {
|
|
99
240
|
case "READ COMMITTED":
|
|
100
|
-
return
|
|
241
|
+
return import_mssql2.default.ISOLATION_LEVEL.READ_COMMITTED;
|
|
101
242
|
case "READ UNCOMMITTED":
|
|
102
|
-
return
|
|
243
|
+
return import_mssql2.default.ISOLATION_LEVEL.READ_UNCOMMITTED;
|
|
103
244
|
case "REPEATABLE READ":
|
|
104
|
-
return
|
|
245
|
+
return import_mssql2.default.ISOLATION_LEVEL.REPEATABLE_READ;
|
|
105
246
|
case "SERIALIZABLE":
|
|
106
|
-
return
|
|
247
|
+
return import_mssql2.default.ISOLATION_LEVEL.SERIALIZABLE;
|
|
107
248
|
case "SNAPSHOT":
|
|
108
|
-
return
|
|
249
|
+
return import_mssql2.default.ISOLATION_LEVEL.SNAPSHOT;
|
|
109
250
|
default:
|
|
110
|
-
throw new
|
|
251
|
+
throw new import_driver_adapter_utils2.DriverAdapterError({
|
|
111
252
|
kind: "InvalidIsolationLevel",
|
|
112
253
|
level
|
|
113
254
|
});
|
|
114
255
|
}
|
|
115
256
|
}
|
|
116
|
-
function mapArg(arg) {
|
|
117
|
-
if (arg
|
|
118
|
-
return
|
|
257
|
+
function mapArg(arg, argType) {
|
|
258
|
+
if (arg === null) {
|
|
259
|
+
return null;
|
|
260
|
+
}
|
|
261
|
+
if (typeof arg === "string" && argType.scalarType === "bigint") {
|
|
262
|
+
arg = BigInt(arg);
|
|
119
263
|
}
|
|
120
264
|
if (typeof arg === "bigint") {
|
|
121
265
|
if (arg >= BigInt(Number.MIN_SAFE_INTEGER) && arg <= BigInt(Number.MAX_SAFE_INTEGER)) {
|
|
@@ -123,28 +267,74 @@ function mapArg(arg) {
|
|
|
123
267
|
}
|
|
124
268
|
return arg.toString();
|
|
125
269
|
}
|
|
270
|
+
if (typeof arg === "string" && argType.scalarType === "datetime") {
|
|
271
|
+
arg = new Date(arg);
|
|
272
|
+
}
|
|
273
|
+
if (arg instanceof Date) {
|
|
274
|
+
switch (argType.dbType) {
|
|
275
|
+
case "TIME":
|
|
276
|
+
return formatTime(arg);
|
|
277
|
+
case "DATE":
|
|
278
|
+
return formatDate(arg);
|
|
279
|
+
default:
|
|
280
|
+
return formatDateTime(arg);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
if (typeof arg === "string" && argType.scalarType === "bytes") {
|
|
284
|
+
return Buffer.from(arg, "base64");
|
|
285
|
+
}
|
|
286
|
+
if (Array.isArray(arg) && argType.scalarType === "bytes") {
|
|
287
|
+
return Buffer.from(arg);
|
|
288
|
+
}
|
|
289
|
+
if (ArrayBuffer.isView(arg)) {
|
|
290
|
+
return Buffer.from(arg.buffer, arg.byteOffset, arg.byteLength);
|
|
291
|
+
}
|
|
126
292
|
return arg;
|
|
127
293
|
}
|
|
128
294
|
function mapRow(row, columns) {
|
|
129
295
|
return row.map((value, i) => {
|
|
296
|
+
const type = columns?.[i]?.type;
|
|
130
297
|
if (value instanceof Date) {
|
|
131
|
-
if (
|
|
132
|
-
return value.toISOString().split("T").
|
|
298
|
+
if (type === import_mssql2.default.Time) {
|
|
299
|
+
return value.toISOString().split("T")[1].replace("Z", "");
|
|
133
300
|
}
|
|
134
301
|
return value.toISOString();
|
|
135
302
|
}
|
|
303
|
+
if (typeof value === "number" && type === import_mssql2.default.Real) {
|
|
304
|
+
for (let digits = 7; digits <= 9; digits++) {
|
|
305
|
+
const parsed = Number.parseFloat(value.toPrecision(digits));
|
|
306
|
+
if (value === new Float32Array([parsed])[0]) {
|
|
307
|
+
return parsed;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
return value;
|
|
311
|
+
}
|
|
136
312
|
if (Buffer.isBuffer(value)) {
|
|
137
313
|
return Array.from(value);
|
|
138
314
|
}
|
|
139
|
-
if (typeof value === "string" &&
|
|
315
|
+
if (typeof value === "string" && type === import_mssql2.default.UniqueIdentifier) {
|
|
140
316
|
return value.toLowerCase();
|
|
141
317
|
}
|
|
142
|
-
if (typeof value === "boolean" &&
|
|
318
|
+
if (typeof value === "boolean" && type === import_mssql2.default.Bit) {
|
|
143
319
|
return value ? 1 : 0;
|
|
144
320
|
}
|
|
145
321
|
return value;
|
|
146
322
|
});
|
|
147
323
|
}
|
|
324
|
+
function formatDateTime(date) {
|
|
325
|
+
const pad = (n, z = 2) => String(n).padStart(z, "0");
|
|
326
|
+
const ms = date.getUTCMilliseconds();
|
|
327
|
+
return date.getUTCFullYear() + "-" + pad(date.getUTCMonth() + 1) + "-" + pad(date.getUTCDate()) + " " + pad(date.getUTCHours()) + ":" + pad(date.getUTCMinutes()) + ":" + pad(date.getUTCSeconds()) + (ms ? "." + String(ms).padStart(3, "0") : "");
|
|
328
|
+
}
|
|
329
|
+
function formatDate(date) {
|
|
330
|
+
const pad = (n, z = 2) => String(n).padStart(z, "0");
|
|
331
|
+
return date.getUTCFullYear() + "-" + pad(date.getUTCMonth() + 1) + "-" + pad(date.getUTCDate());
|
|
332
|
+
}
|
|
333
|
+
function formatTime(date) {
|
|
334
|
+
const pad = (n, z = 2) => String(n).padStart(z, "0");
|
|
335
|
+
const ms = date.getUTCMilliseconds();
|
|
336
|
+
return pad(date.getUTCHours()) + ":" + pad(date.getUTCMinutes()) + ":" + pad(date.getUTCSeconds()) + (ms ? "." + String(ms).padStart(3, "0") : "");
|
|
337
|
+
}
|
|
148
338
|
|
|
149
339
|
// src/errors.ts
|
|
150
340
|
function convertDriverError(error) {
|
|
@@ -331,7 +521,7 @@ function isDriverError(error) {
|
|
|
331
521
|
}
|
|
332
522
|
|
|
333
523
|
// src/mssql.ts
|
|
334
|
-
var
|
|
524
|
+
var debug2 = (0, import_driver_adapter_utils3.Debug)("prisma:driver-adapter:mssql");
|
|
335
525
|
var MssqlQueryable = class {
|
|
336
526
|
constructor(conn) {
|
|
337
527
|
this.conn = conn;
|
|
@@ -340,7 +530,7 @@ var MssqlQueryable = class {
|
|
|
340
530
|
adapterName = name;
|
|
341
531
|
async queryRaw(query) {
|
|
342
532
|
const tag = "[js::query_raw]";
|
|
343
|
-
|
|
533
|
+
debug2(`${tag} %O`, query);
|
|
344
534
|
const { recordset, columns: columnsList } = await this.performIO(query);
|
|
345
535
|
const columns = columnsList?.[0];
|
|
346
536
|
return {
|
|
@@ -351,7 +541,7 @@ var MssqlQueryable = class {
|
|
|
351
541
|
}
|
|
352
542
|
async executeRaw(query) {
|
|
353
543
|
const tag = "[js::execute_raw]";
|
|
354
|
-
|
|
544
|
+
debug2(`${tag} %O`, query);
|
|
355
545
|
return (await this.performIO(query)).rowsAffected?.[0] ?? 0;
|
|
356
546
|
}
|
|
357
547
|
async performIO(query) {
|
|
@@ -359,7 +549,7 @@ var MssqlQueryable = class {
|
|
|
359
549
|
const req = this.conn.request();
|
|
360
550
|
req.arrayRowMode = true;
|
|
361
551
|
for (let i = 0; i < query.args.length; i++) {
|
|
362
|
-
req.input(`P${i + 1}`, mapArg(query.args[i]));
|
|
552
|
+
req.input(`P${i + 1}`, mapArg(query.args[i], query.argTypes[i]));
|
|
363
553
|
}
|
|
364
554
|
const res = await req.query(query.sql);
|
|
365
555
|
return res;
|
|
@@ -368,8 +558,8 @@ var MssqlQueryable = class {
|
|
|
368
558
|
}
|
|
369
559
|
}
|
|
370
560
|
onError(error) {
|
|
371
|
-
|
|
372
|
-
throw new
|
|
561
|
+
debug2("Error in performIO: %O", error);
|
|
562
|
+
throw new import_driver_adapter_utils3.DriverAdapterError(convertDriverError(error));
|
|
373
563
|
}
|
|
374
564
|
};
|
|
375
565
|
var MssqlTransaction = class extends MssqlQueryable {
|
|
@@ -390,14 +580,14 @@ var MssqlTransaction = class extends MssqlQueryable {
|
|
|
390
580
|
}
|
|
391
581
|
}
|
|
392
582
|
async commit() {
|
|
393
|
-
|
|
583
|
+
debug2(`[js::commit]`);
|
|
394
584
|
await this.transaction.commit();
|
|
395
585
|
}
|
|
396
586
|
async rollback() {
|
|
397
|
-
|
|
587
|
+
debug2(`[js::rollback]`);
|
|
398
588
|
await this.transaction.rollback().catch((e) => {
|
|
399
589
|
if (e.code === "EABORT") {
|
|
400
|
-
|
|
590
|
+
debug2(`[js::rollback] Transaction already aborted`);
|
|
401
591
|
return;
|
|
402
592
|
}
|
|
403
593
|
throw e;
|
|
@@ -418,8 +608,12 @@ var PrismaMssqlAdapter = class extends MssqlQueryable {
|
|
|
418
608
|
usePhantomQuery: true
|
|
419
609
|
};
|
|
420
610
|
const tag = "[js::startTransaction]";
|
|
421
|
-
|
|
611
|
+
debug2("%s options: %O", tag, options);
|
|
422
612
|
const tx = this.pool.transaction();
|
|
613
|
+
tx.on("error", (err) => {
|
|
614
|
+
debug2("Error from pool connection: %O", err);
|
|
615
|
+
this.options?.onConnectionError?.(err);
|
|
616
|
+
});
|
|
423
617
|
try {
|
|
424
618
|
await tx.begin(isolationLevel !== void 0 ? mapIsolationLevel(isolationLevel) : void 0);
|
|
425
619
|
return new MssqlTransaction(tx, options);
|
|
@@ -442,16 +636,31 @@ var PrismaMssqlAdapter = class extends MssqlQueryable {
|
|
|
442
636
|
}
|
|
443
637
|
};
|
|
444
638
|
var PrismaMssqlAdapterFactory = class {
|
|
445
|
-
constructor(config, options) {
|
|
446
|
-
this.config = config;
|
|
447
|
-
this.options = options;
|
|
448
|
-
}
|
|
449
639
|
provider = "sqlserver";
|
|
450
640
|
adapterName = name;
|
|
641
|
+
#config;
|
|
642
|
+
#options;
|
|
643
|
+
constructor(configOrString, options) {
|
|
644
|
+
if (typeof configOrString === "string") {
|
|
645
|
+
this.#config = parseConnectionString(configOrString);
|
|
646
|
+
const extractedSchema = extractSchemaFromConnectionString(configOrString);
|
|
647
|
+
this.#options = {
|
|
648
|
+
...options,
|
|
649
|
+
schema: options?.schema ?? extractedSchema
|
|
650
|
+
};
|
|
651
|
+
} else {
|
|
652
|
+
this.#config = configOrString;
|
|
653
|
+
this.#options = options ?? {};
|
|
654
|
+
}
|
|
655
|
+
}
|
|
451
656
|
async connect() {
|
|
452
|
-
const pool = new
|
|
657
|
+
const pool = new import_mssql3.default.ConnectionPool(this.#config);
|
|
658
|
+
pool.on("error", (err) => {
|
|
659
|
+
debug2("Error from pool client: %O", err);
|
|
660
|
+
this.#options?.onPoolError?.(err);
|
|
661
|
+
});
|
|
453
662
|
await pool.connect();
|
|
454
|
-
return new PrismaMssqlAdapter(pool, this
|
|
663
|
+
return new PrismaMssqlAdapter(pool, this.#options);
|
|
455
664
|
}
|
|
456
665
|
};
|
|
457
666
|
// Annotate the CommonJS export names for ESM import in node:
|
package/dist/index.mjs
CHANGED
|
@@ -1,58 +1,202 @@
|
|
|
1
1
|
// src/mssql.ts
|
|
2
2
|
import {
|
|
3
|
-
Debug,
|
|
3
|
+
Debug as Debug2,
|
|
4
4
|
DriverAdapterError as DriverAdapterError2
|
|
5
5
|
} from "@prisma/driver-adapter-utils";
|
|
6
6
|
import { Mutex } from "async-mutex";
|
|
7
|
-
import
|
|
7
|
+
import sql3 from "mssql";
|
|
8
8
|
|
|
9
9
|
// package.json
|
|
10
10
|
var name = "@prisma/adapter-mssql";
|
|
11
11
|
|
|
12
|
-
// src/
|
|
13
|
-
import {
|
|
12
|
+
// src/connection-string.ts
|
|
13
|
+
import { Debug } from "@prisma/driver-adapter-utils";
|
|
14
14
|
import sql from "mssql";
|
|
15
|
+
function mapIsolationLevelFromString(level) {
|
|
16
|
+
const normalizedLevel = level.toUpperCase().replace(/\s+/g, "");
|
|
17
|
+
switch (normalizedLevel) {
|
|
18
|
+
case "READCOMMITTED":
|
|
19
|
+
return sql.ISOLATION_LEVEL.READ_COMMITTED;
|
|
20
|
+
case "READUNCOMMITTED":
|
|
21
|
+
return sql.ISOLATION_LEVEL.READ_UNCOMMITTED;
|
|
22
|
+
case "REPEATABLEREAD":
|
|
23
|
+
return sql.ISOLATION_LEVEL.REPEATABLE_READ;
|
|
24
|
+
case "SERIALIZABLE":
|
|
25
|
+
return sql.ISOLATION_LEVEL.SERIALIZABLE;
|
|
26
|
+
case "SNAPSHOT":
|
|
27
|
+
return sql.ISOLATION_LEVEL.SNAPSHOT;
|
|
28
|
+
default:
|
|
29
|
+
throw new Error(`Invalid isolation level: ${level}`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
var debug = Debug("prisma:driver-adapter:mssql:connection-string");
|
|
33
|
+
function extractSchemaFromConnectionString(connectionString) {
|
|
34
|
+
const withoutProtocol = connectionString.replace(/^sqlserver:\/\//, "");
|
|
35
|
+
const parts = withoutProtocol.split(";");
|
|
36
|
+
for (const part of parts) {
|
|
37
|
+
const [key, value] = part.split("=", 2);
|
|
38
|
+
if (key?.trim() === "schema") {
|
|
39
|
+
return value?.trim();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return void 0;
|
|
43
|
+
}
|
|
44
|
+
function parseConnectionString(connectionString) {
|
|
45
|
+
const withoutProtocol = connectionString.replace(/^sqlserver:\/\//, "");
|
|
46
|
+
const [hostPart, ...paramParts] = withoutProtocol.split(";");
|
|
47
|
+
const config = {
|
|
48
|
+
server: "",
|
|
49
|
+
options: {},
|
|
50
|
+
pool: {}
|
|
51
|
+
};
|
|
52
|
+
const [host, portStr] = hostPart.split(":");
|
|
53
|
+
config.server = host.trim();
|
|
54
|
+
if (portStr) {
|
|
55
|
+
const port = parseInt(portStr, 10);
|
|
56
|
+
if (isNaN(port)) {
|
|
57
|
+
throw new Error(`Invalid port number: ${portStr}`);
|
|
58
|
+
}
|
|
59
|
+
config.port = port;
|
|
60
|
+
}
|
|
61
|
+
for (const part of paramParts) {
|
|
62
|
+
const [key, value] = part.split("=", 2);
|
|
63
|
+
if (!key) continue;
|
|
64
|
+
const trimmedKey = key.trim();
|
|
65
|
+
const trimmedValue = value.trim();
|
|
66
|
+
switch (trimmedKey) {
|
|
67
|
+
case "database":
|
|
68
|
+
case "initial catalog":
|
|
69
|
+
config.database = trimmedValue;
|
|
70
|
+
break;
|
|
71
|
+
case "user":
|
|
72
|
+
case "username":
|
|
73
|
+
case "uid":
|
|
74
|
+
case "userid":
|
|
75
|
+
config.user = trimmedValue;
|
|
76
|
+
break;
|
|
77
|
+
case "password":
|
|
78
|
+
case "pwd":
|
|
79
|
+
config.password = trimmedValue;
|
|
80
|
+
break;
|
|
81
|
+
case "encrypt":
|
|
82
|
+
config.options = config.options || {};
|
|
83
|
+
config.options.encrypt = trimmedValue.toLowerCase() === "true";
|
|
84
|
+
break;
|
|
85
|
+
case "trustServerCertificate":
|
|
86
|
+
config.options = config.options || {};
|
|
87
|
+
config.options.trustServerCertificate = trimmedValue.toLowerCase() === "true";
|
|
88
|
+
break;
|
|
89
|
+
case "connectionLimit": {
|
|
90
|
+
config.pool = config.pool || {};
|
|
91
|
+
const limit = parseInt(trimmedValue, 10);
|
|
92
|
+
if (isNaN(limit)) {
|
|
93
|
+
throw new Error(`Invalid connection limit: ${trimmedValue}`);
|
|
94
|
+
}
|
|
95
|
+
config.pool.max = limit;
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
case "connectTimeout":
|
|
99
|
+
case "connectionTimeout": {
|
|
100
|
+
const connectTimeout = parseInt(trimmedValue, 10);
|
|
101
|
+
if (isNaN(connectTimeout)) {
|
|
102
|
+
throw new Error(`Invalid connection timeout: ${trimmedValue}`);
|
|
103
|
+
}
|
|
104
|
+
config.connectionTimeout = connectTimeout;
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
case "loginTimeout": {
|
|
108
|
+
const loginTimeout = parseInt(trimmedValue, 10);
|
|
109
|
+
if (isNaN(loginTimeout)) {
|
|
110
|
+
throw new Error(`Invalid login timeout: ${trimmedValue}`);
|
|
111
|
+
}
|
|
112
|
+
config.connectionTimeout = loginTimeout;
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
case "socketTimeout": {
|
|
116
|
+
const socketTimeout = parseInt(trimmedValue, 10);
|
|
117
|
+
if (isNaN(socketTimeout)) {
|
|
118
|
+
throw new Error(`Invalid socket timeout: ${trimmedValue}`);
|
|
119
|
+
}
|
|
120
|
+
config.requestTimeout = socketTimeout;
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
case "poolTimeout": {
|
|
124
|
+
const poolTimeout = parseInt(trimmedValue, 10);
|
|
125
|
+
if (isNaN(poolTimeout)) {
|
|
126
|
+
throw new Error(`Invalid pool timeout: ${trimmedValue}`);
|
|
127
|
+
}
|
|
128
|
+
config.pool = config.pool || {};
|
|
129
|
+
config.pool.acquireTimeoutMillis = poolTimeout * 1e3;
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
case "applicationName":
|
|
133
|
+
case "application name":
|
|
134
|
+
config.options = config.options || {};
|
|
135
|
+
config.options.appName = trimmedValue;
|
|
136
|
+
break;
|
|
137
|
+
case "isolationLevel":
|
|
138
|
+
config.options = config.options || {};
|
|
139
|
+
config.options.isolationLevel = mapIsolationLevelFromString(trimmedValue);
|
|
140
|
+
break;
|
|
141
|
+
case "schema":
|
|
142
|
+
break;
|
|
143
|
+
default:
|
|
144
|
+
debug(`Unknown connection string parameter: ${trimmedKey}`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
if (!config.server || config.server.trim() === "") {
|
|
148
|
+
throw new Error("Server host is required in connection string");
|
|
149
|
+
}
|
|
150
|
+
return config;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// src/conversion.ts
|
|
154
|
+
import {
|
|
155
|
+
ColumnTypeEnum,
|
|
156
|
+
DriverAdapterError
|
|
157
|
+
} from "@prisma/driver-adapter-utils";
|
|
158
|
+
import sql2 from "mssql";
|
|
15
159
|
function mapColumnType(col) {
|
|
16
160
|
switch (col.type) {
|
|
17
|
-
case
|
|
18
|
-
case
|
|
19
|
-
case
|
|
20
|
-
case
|
|
21
|
-
case
|
|
22
|
-
case
|
|
23
|
-
case
|
|
161
|
+
case sql2.VarChar:
|
|
162
|
+
case sql2.Char:
|
|
163
|
+
case sql2.NVarChar:
|
|
164
|
+
case sql2.NChar:
|
|
165
|
+
case sql2.Text:
|
|
166
|
+
case sql2.NText:
|
|
167
|
+
case sql2.Xml:
|
|
24
168
|
return ColumnTypeEnum.Text;
|
|
25
|
-
case
|
|
169
|
+
case sql2.Bit:
|
|
26
170
|
return ColumnTypeEnum.Boolean;
|
|
27
|
-
case
|
|
28
|
-
case
|
|
29
|
-
case
|
|
171
|
+
case sql2.TinyInt:
|
|
172
|
+
case sql2.SmallInt:
|
|
173
|
+
case sql2.Int:
|
|
30
174
|
return ColumnTypeEnum.Int32;
|
|
31
|
-
case
|
|
175
|
+
case sql2.BigInt:
|
|
32
176
|
return ColumnTypeEnum.Int64;
|
|
33
|
-
case
|
|
34
|
-
case
|
|
35
|
-
case
|
|
36
|
-
case
|
|
177
|
+
case sql2.DateTime2:
|
|
178
|
+
case sql2.SmallDateTime:
|
|
179
|
+
case sql2.DateTime:
|
|
180
|
+
case sql2.DateTimeOffset:
|
|
37
181
|
return ColumnTypeEnum.DateTime;
|
|
38
|
-
case
|
|
182
|
+
case sql2.Real:
|
|
39
183
|
return ColumnTypeEnum.Float;
|
|
40
|
-
case
|
|
41
|
-
case
|
|
42
|
-
case
|
|
184
|
+
case sql2.Float:
|
|
185
|
+
case sql2.Money:
|
|
186
|
+
case sql2.SmallMoney:
|
|
43
187
|
return ColumnTypeEnum.Double;
|
|
44
|
-
case
|
|
188
|
+
case sql2.UniqueIdentifier:
|
|
45
189
|
return ColumnTypeEnum.Uuid;
|
|
46
|
-
case
|
|
47
|
-
case
|
|
190
|
+
case sql2.Decimal:
|
|
191
|
+
case sql2.Numeric:
|
|
48
192
|
return ColumnTypeEnum.Numeric;
|
|
49
|
-
case
|
|
193
|
+
case sql2.Date:
|
|
50
194
|
return ColumnTypeEnum.Date;
|
|
51
|
-
case
|
|
195
|
+
case sql2.Time:
|
|
52
196
|
return ColumnTypeEnum.Time;
|
|
53
|
-
case
|
|
54
|
-
case
|
|
55
|
-
case
|
|
197
|
+
case sql2.VarBinary:
|
|
198
|
+
case sql2.Binary:
|
|
199
|
+
case sql2.Image:
|
|
56
200
|
return ColumnTypeEnum.Bytes;
|
|
57
201
|
default:
|
|
58
202
|
throw new DriverAdapterError({
|
|
@@ -64,15 +208,15 @@ function mapColumnType(col) {
|
|
|
64
208
|
function mapIsolationLevel(level) {
|
|
65
209
|
switch (level) {
|
|
66
210
|
case "READ COMMITTED":
|
|
67
|
-
return
|
|
211
|
+
return sql2.ISOLATION_LEVEL.READ_COMMITTED;
|
|
68
212
|
case "READ UNCOMMITTED":
|
|
69
|
-
return
|
|
213
|
+
return sql2.ISOLATION_LEVEL.READ_UNCOMMITTED;
|
|
70
214
|
case "REPEATABLE READ":
|
|
71
|
-
return
|
|
215
|
+
return sql2.ISOLATION_LEVEL.REPEATABLE_READ;
|
|
72
216
|
case "SERIALIZABLE":
|
|
73
|
-
return
|
|
217
|
+
return sql2.ISOLATION_LEVEL.SERIALIZABLE;
|
|
74
218
|
case "SNAPSHOT":
|
|
75
|
-
return
|
|
219
|
+
return sql2.ISOLATION_LEVEL.SNAPSHOT;
|
|
76
220
|
default:
|
|
77
221
|
throw new DriverAdapterError({
|
|
78
222
|
kind: "InvalidIsolationLevel",
|
|
@@ -80,9 +224,12 @@ function mapIsolationLevel(level) {
|
|
|
80
224
|
});
|
|
81
225
|
}
|
|
82
226
|
}
|
|
83
|
-
function mapArg(arg) {
|
|
84
|
-
if (arg
|
|
85
|
-
return
|
|
227
|
+
function mapArg(arg, argType) {
|
|
228
|
+
if (arg === null) {
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
if (typeof arg === "string" && argType.scalarType === "bigint") {
|
|
232
|
+
arg = BigInt(arg);
|
|
86
233
|
}
|
|
87
234
|
if (typeof arg === "bigint") {
|
|
88
235
|
if (arg >= BigInt(Number.MIN_SAFE_INTEGER) && arg <= BigInt(Number.MAX_SAFE_INTEGER)) {
|
|
@@ -90,28 +237,74 @@ function mapArg(arg) {
|
|
|
90
237
|
}
|
|
91
238
|
return arg.toString();
|
|
92
239
|
}
|
|
240
|
+
if (typeof arg === "string" && argType.scalarType === "datetime") {
|
|
241
|
+
arg = new Date(arg);
|
|
242
|
+
}
|
|
243
|
+
if (arg instanceof Date) {
|
|
244
|
+
switch (argType.dbType) {
|
|
245
|
+
case "TIME":
|
|
246
|
+
return formatTime(arg);
|
|
247
|
+
case "DATE":
|
|
248
|
+
return formatDate(arg);
|
|
249
|
+
default:
|
|
250
|
+
return formatDateTime(arg);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
if (typeof arg === "string" && argType.scalarType === "bytes") {
|
|
254
|
+
return Buffer.from(arg, "base64");
|
|
255
|
+
}
|
|
256
|
+
if (Array.isArray(arg) && argType.scalarType === "bytes") {
|
|
257
|
+
return Buffer.from(arg);
|
|
258
|
+
}
|
|
259
|
+
if (ArrayBuffer.isView(arg)) {
|
|
260
|
+
return Buffer.from(arg.buffer, arg.byteOffset, arg.byteLength);
|
|
261
|
+
}
|
|
93
262
|
return arg;
|
|
94
263
|
}
|
|
95
264
|
function mapRow(row, columns) {
|
|
96
265
|
return row.map((value, i) => {
|
|
266
|
+
const type = columns?.[i]?.type;
|
|
97
267
|
if (value instanceof Date) {
|
|
98
|
-
if (
|
|
99
|
-
return value.toISOString().split("T").
|
|
268
|
+
if (type === sql2.Time) {
|
|
269
|
+
return value.toISOString().split("T")[1].replace("Z", "");
|
|
100
270
|
}
|
|
101
271
|
return value.toISOString();
|
|
102
272
|
}
|
|
273
|
+
if (typeof value === "number" && type === sql2.Real) {
|
|
274
|
+
for (let digits = 7; digits <= 9; digits++) {
|
|
275
|
+
const parsed = Number.parseFloat(value.toPrecision(digits));
|
|
276
|
+
if (value === new Float32Array([parsed])[0]) {
|
|
277
|
+
return parsed;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
return value;
|
|
281
|
+
}
|
|
103
282
|
if (Buffer.isBuffer(value)) {
|
|
104
283
|
return Array.from(value);
|
|
105
284
|
}
|
|
106
|
-
if (typeof value === "string" &&
|
|
285
|
+
if (typeof value === "string" && type === sql2.UniqueIdentifier) {
|
|
107
286
|
return value.toLowerCase();
|
|
108
287
|
}
|
|
109
|
-
if (typeof value === "boolean" &&
|
|
288
|
+
if (typeof value === "boolean" && type === sql2.Bit) {
|
|
110
289
|
return value ? 1 : 0;
|
|
111
290
|
}
|
|
112
291
|
return value;
|
|
113
292
|
});
|
|
114
293
|
}
|
|
294
|
+
function formatDateTime(date) {
|
|
295
|
+
const pad = (n, z = 2) => String(n).padStart(z, "0");
|
|
296
|
+
const ms = date.getUTCMilliseconds();
|
|
297
|
+
return date.getUTCFullYear() + "-" + pad(date.getUTCMonth() + 1) + "-" + pad(date.getUTCDate()) + " " + pad(date.getUTCHours()) + ":" + pad(date.getUTCMinutes()) + ":" + pad(date.getUTCSeconds()) + (ms ? "." + String(ms).padStart(3, "0") : "");
|
|
298
|
+
}
|
|
299
|
+
function formatDate(date) {
|
|
300
|
+
const pad = (n, z = 2) => String(n).padStart(z, "0");
|
|
301
|
+
return date.getUTCFullYear() + "-" + pad(date.getUTCMonth() + 1) + "-" + pad(date.getUTCDate());
|
|
302
|
+
}
|
|
303
|
+
function formatTime(date) {
|
|
304
|
+
const pad = (n, z = 2) => String(n).padStart(z, "0");
|
|
305
|
+
const ms = date.getUTCMilliseconds();
|
|
306
|
+
return pad(date.getUTCHours()) + ":" + pad(date.getUTCMinutes()) + ":" + pad(date.getUTCSeconds()) + (ms ? "." + String(ms).padStart(3, "0") : "");
|
|
307
|
+
}
|
|
115
308
|
|
|
116
309
|
// src/errors.ts
|
|
117
310
|
function convertDriverError(error) {
|
|
@@ -298,7 +491,7 @@ function isDriverError(error) {
|
|
|
298
491
|
}
|
|
299
492
|
|
|
300
493
|
// src/mssql.ts
|
|
301
|
-
var
|
|
494
|
+
var debug2 = Debug2("prisma:driver-adapter:mssql");
|
|
302
495
|
var MssqlQueryable = class {
|
|
303
496
|
constructor(conn) {
|
|
304
497
|
this.conn = conn;
|
|
@@ -307,7 +500,7 @@ var MssqlQueryable = class {
|
|
|
307
500
|
adapterName = name;
|
|
308
501
|
async queryRaw(query) {
|
|
309
502
|
const tag = "[js::query_raw]";
|
|
310
|
-
|
|
503
|
+
debug2(`${tag} %O`, query);
|
|
311
504
|
const { recordset, columns: columnsList } = await this.performIO(query);
|
|
312
505
|
const columns = columnsList?.[0];
|
|
313
506
|
return {
|
|
@@ -318,7 +511,7 @@ var MssqlQueryable = class {
|
|
|
318
511
|
}
|
|
319
512
|
async executeRaw(query) {
|
|
320
513
|
const tag = "[js::execute_raw]";
|
|
321
|
-
|
|
514
|
+
debug2(`${tag} %O`, query);
|
|
322
515
|
return (await this.performIO(query)).rowsAffected?.[0] ?? 0;
|
|
323
516
|
}
|
|
324
517
|
async performIO(query) {
|
|
@@ -326,7 +519,7 @@ var MssqlQueryable = class {
|
|
|
326
519
|
const req = this.conn.request();
|
|
327
520
|
req.arrayRowMode = true;
|
|
328
521
|
for (let i = 0; i < query.args.length; i++) {
|
|
329
|
-
req.input(`P${i + 1}`, mapArg(query.args[i]));
|
|
522
|
+
req.input(`P${i + 1}`, mapArg(query.args[i], query.argTypes[i]));
|
|
330
523
|
}
|
|
331
524
|
const res = await req.query(query.sql);
|
|
332
525
|
return res;
|
|
@@ -335,7 +528,7 @@ var MssqlQueryable = class {
|
|
|
335
528
|
}
|
|
336
529
|
}
|
|
337
530
|
onError(error) {
|
|
338
|
-
|
|
531
|
+
debug2("Error in performIO: %O", error);
|
|
339
532
|
throw new DriverAdapterError2(convertDriverError(error));
|
|
340
533
|
}
|
|
341
534
|
};
|
|
@@ -357,14 +550,14 @@ var MssqlTransaction = class extends MssqlQueryable {
|
|
|
357
550
|
}
|
|
358
551
|
}
|
|
359
552
|
async commit() {
|
|
360
|
-
|
|
553
|
+
debug2(`[js::commit]`);
|
|
361
554
|
await this.transaction.commit();
|
|
362
555
|
}
|
|
363
556
|
async rollback() {
|
|
364
|
-
|
|
557
|
+
debug2(`[js::rollback]`);
|
|
365
558
|
await this.transaction.rollback().catch((e) => {
|
|
366
559
|
if (e.code === "EABORT") {
|
|
367
|
-
|
|
560
|
+
debug2(`[js::rollback] Transaction already aborted`);
|
|
368
561
|
return;
|
|
369
562
|
}
|
|
370
563
|
throw e;
|
|
@@ -385,8 +578,12 @@ var PrismaMssqlAdapter = class extends MssqlQueryable {
|
|
|
385
578
|
usePhantomQuery: true
|
|
386
579
|
};
|
|
387
580
|
const tag = "[js::startTransaction]";
|
|
388
|
-
|
|
581
|
+
debug2("%s options: %O", tag, options);
|
|
389
582
|
const tx = this.pool.transaction();
|
|
583
|
+
tx.on("error", (err) => {
|
|
584
|
+
debug2("Error from pool connection: %O", err);
|
|
585
|
+
this.options?.onConnectionError?.(err);
|
|
586
|
+
});
|
|
390
587
|
try {
|
|
391
588
|
await tx.begin(isolationLevel !== void 0 ? mapIsolationLevel(isolationLevel) : void 0);
|
|
392
589
|
return new MssqlTransaction(tx, options);
|
|
@@ -409,16 +606,31 @@ var PrismaMssqlAdapter = class extends MssqlQueryable {
|
|
|
409
606
|
}
|
|
410
607
|
};
|
|
411
608
|
var PrismaMssqlAdapterFactory = class {
|
|
412
|
-
constructor(config, options) {
|
|
413
|
-
this.config = config;
|
|
414
|
-
this.options = options;
|
|
415
|
-
}
|
|
416
609
|
provider = "sqlserver";
|
|
417
610
|
adapterName = name;
|
|
611
|
+
#config;
|
|
612
|
+
#options;
|
|
613
|
+
constructor(configOrString, options) {
|
|
614
|
+
if (typeof configOrString === "string") {
|
|
615
|
+
this.#config = parseConnectionString(configOrString);
|
|
616
|
+
const extractedSchema = extractSchemaFromConnectionString(configOrString);
|
|
617
|
+
this.#options = {
|
|
618
|
+
...options,
|
|
619
|
+
schema: options?.schema ?? extractedSchema
|
|
620
|
+
};
|
|
621
|
+
} else {
|
|
622
|
+
this.#config = configOrString;
|
|
623
|
+
this.#options = options ?? {};
|
|
624
|
+
}
|
|
625
|
+
}
|
|
418
626
|
async connect() {
|
|
419
|
-
const pool = new
|
|
627
|
+
const pool = new sql3.ConnectionPool(this.#config);
|
|
628
|
+
pool.on("error", (err) => {
|
|
629
|
+
debug2("Error from pool client: %O", err);
|
|
630
|
+
this.#options?.onPoolError?.(err);
|
|
631
|
+
});
|
|
420
632
|
await pool.connect();
|
|
421
|
-
return new PrismaMssqlAdapter(pool, this
|
|
633
|
+
return new PrismaMssqlAdapter(pool, this.#options);
|
|
422
634
|
}
|
|
423
635
|
};
|
|
424
636
|
export {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma/adapter-mssql",
|
|
3
|
-
"version": "6.15.0-dev.
|
|
3
|
+
"version": "6.15.0-dev.30",
|
|
4
4
|
"description": "Prisma's driver adapter for \"mssql\"",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -33,18 +33,15 @@
|
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"mssql": "^11.0.1",
|
|
35
35
|
"async-mutex": "0.5.0",
|
|
36
|
-
"@prisma/driver-adapter-utils": "6.15.0-dev.
|
|
36
|
+
"@prisma/driver-adapter-utils": "6.15.0-dev.30"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@types/mssql": "9.1.7",
|
|
40
|
-
"
|
|
41
|
-
"@swc/jest": "0.2.37",
|
|
42
|
-
"jest": "29.7.0",
|
|
43
|
-
"jest-junit": "16.0.0"
|
|
40
|
+
"vitest": "3.0.9"
|
|
44
41
|
},
|
|
45
42
|
"scripts": {
|
|
46
43
|
"dev": "DEV=true tsx helpers/build.ts",
|
|
47
44
|
"build": "tsx helpers/build.ts",
|
|
48
|
-
"test": "
|
|
45
|
+
"test": "vitest run"
|
|
49
46
|
}
|
|
50
47
|
}
|