@prisma/adapter-planetscale 6.10.0-dev.2 → 6.10.0-dev.4
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.js +141 -9
- package/dist/index.mjs +141 -9
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -37,6 +37,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
37
37
|
// src/planetscale.ts
|
|
38
38
|
var planetScale = __toESM(require("@planetscale/database"));
|
|
39
39
|
var import_driver_adapter_utils2 = require("@prisma/driver-adapter-utils");
|
|
40
|
+
var import_async_mutex = require("async-mutex");
|
|
40
41
|
|
|
41
42
|
// package.json
|
|
42
43
|
var name = "@prisma/adapter-planetscale";
|
|
@@ -132,6 +133,117 @@ function createDeferred() {
|
|
|
132
133
|
];
|
|
133
134
|
}
|
|
134
135
|
|
|
136
|
+
// src/errors.ts
|
|
137
|
+
function convertDriverError(error) {
|
|
138
|
+
switch (error.code) {
|
|
139
|
+
case 1062: {
|
|
140
|
+
const index = error.message.split(" ").pop()?.split("'").at(1)?.split(".").pop();
|
|
141
|
+
return {
|
|
142
|
+
kind: "UniqueConstraintViolation",
|
|
143
|
+
constraint: index !== void 0 ? { index } : void 0
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
case 1451:
|
|
147
|
+
case 1452: {
|
|
148
|
+
const field = error.message.split(" ").at(17)?.split("`").at(1);
|
|
149
|
+
return {
|
|
150
|
+
kind: "ForeignKeyConstraintViolation",
|
|
151
|
+
constraint: field !== void 0 ? { fields: [field] } : void 0
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
case 1263: {
|
|
155
|
+
const index = error.message.split(" ").pop()?.split("'").at(1);
|
|
156
|
+
return {
|
|
157
|
+
kind: "NullConstraintViolation",
|
|
158
|
+
constraint: index !== void 0 ? { index } : void 0
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
case 1264:
|
|
162
|
+
return {
|
|
163
|
+
kind: "ValueOutOfRange",
|
|
164
|
+
cause: error.message
|
|
165
|
+
};
|
|
166
|
+
case 1364:
|
|
167
|
+
case 1048: {
|
|
168
|
+
const field = error.message.split(" ").at(1)?.split("'").at(1);
|
|
169
|
+
return {
|
|
170
|
+
kind: "NullConstraintViolation",
|
|
171
|
+
constraint: field !== void 0 ? { fields: [field] } : void 0
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
case 1049: {
|
|
175
|
+
const db = error.message.split(" ").pop()?.split("'").at(1);
|
|
176
|
+
return {
|
|
177
|
+
kind: "DatabaseDoesNotExist",
|
|
178
|
+
db
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
case 1007: {
|
|
182
|
+
const db = error.message.split(" ").at(3)?.split("'").at(1);
|
|
183
|
+
return {
|
|
184
|
+
kind: "DatabaseAlreadyExists",
|
|
185
|
+
db
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
case 1044: {
|
|
189
|
+
const db = error.message.split(" ").pop()?.split("'").at(1);
|
|
190
|
+
return {
|
|
191
|
+
kind: "DatabaseAccessDenied",
|
|
192
|
+
db
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
case 1045: {
|
|
196
|
+
const user = error.message.split(" ").at(4)?.split("@").at(0)?.split("'").at(1);
|
|
197
|
+
return {
|
|
198
|
+
kind: "AuthenticationFailed",
|
|
199
|
+
user
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
case 1146: {
|
|
203
|
+
const table = error.message.split(" ").at(1)?.split("'").at(1)?.split(".").pop();
|
|
204
|
+
return {
|
|
205
|
+
kind: "TableDoesNotExist",
|
|
206
|
+
table
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
case 1054: {
|
|
210
|
+
const column = error.message.split(" ").at(2)?.split("'").at(1);
|
|
211
|
+
return {
|
|
212
|
+
kind: "ColumnNotFound",
|
|
213
|
+
column
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
case 1406: {
|
|
217
|
+
const column = error.message.split(" ").flatMap((part) => part.split("'")).at(6);
|
|
218
|
+
return {
|
|
219
|
+
kind: "LengthMismatch",
|
|
220
|
+
column
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
case 1191:
|
|
224
|
+
return {
|
|
225
|
+
kind: "MissingFullTextSearchIndex"
|
|
226
|
+
};
|
|
227
|
+
case 1213:
|
|
228
|
+
return {
|
|
229
|
+
kind: "TransactionWriteConflict"
|
|
230
|
+
};
|
|
231
|
+
case 1040:
|
|
232
|
+
case 1203:
|
|
233
|
+
return {
|
|
234
|
+
kind: "TooManyConnections",
|
|
235
|
+
cause: error.message
|
|
236
|
+
};
|
|
237
|
+
default:
|
|
238
|
+
return {
|
|
239
|
+
kind: "mysql",
|
|
240
|
+
code: error.code,
|
|
241
|
+
message: error.message,
|
|
242
|
+
state: error.state
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
135
247
|
// src/planetscale.ts
|
|
136
248
|
var debug = (0, import_driver_adapter_utils2.Debug)("prisma:driver-adapter:planetscale");
|
|
137
249
|
var RollbackError = class _RollbackError extends Error {
|
|
@@ -197,23 +309,28 @@ function onError(error) {
|
|
|
197
309
|
if (error.name === "DatabaseError") {
|
|
198
310
|
const parsed = parseErrorMessage(error.message);
|
|
199
311
|
if (parsed) {
|
|
200
|
-
throw new import_driver_adapter_utils2.DriverAdapterError(
|
|
201
|
-
kind: "mysql",
|
|
202
|
-
...parsed
|
|
203
|
-
});
|
|
312
|
+
throw new import_driver_adapter_utils2.DriverAdapterError(convertDriverError(parsed));
|
|
204
313
|
}
|
|
205
314
|
}
|
|
206
315
|
debug("Error in performIO: %O", error);
|
|
207
316
|
throw error;
|
|
208
317
|
}
|
|
209
|
-
function parseErrorMessage(
|
|
318
|
+
function parseErrorMessage(error) {
|
|
210
319
|
const regex = /^(.*) \(errno (\d+)\) \(sqlstate ([A-Z0-9]+)\)/;
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
const
|
|
320
|
+
let match = null;
|
|
321
|
+
while (true) {
|
|
322
|
+
const result = error.match(regex);
|
|
323
|
+
if (result === null) {
|
|
324
|
+
break;
|
|
325
|
+
}
|
|
326
|
+
match = result;
|
|
327
|
+
error = match[1];
|
|
328
|
+
}
|
|
329
|
+
if (match !== null) {
|
|
330
|
+
const [, message, codeAsString, sqlstate] = match;
|
|
214
331
|
const code = Number.parseInt(codeAsString, 10);
|
|
215
332
|
return {
|
|
216
|
-
message
|
|
333
|
+
message,
|
|
217
334
|
code,
|
|
218
335
|
state: sqlstate
|
|
219
336
|
};
|
|
@@ -221,6 +338,7 @@ function parseErrorMessage(message) {
|
|
|
221
338
|
return void 0;
|
|
222
339
|
}
|
|
223
340
|
}
|
|
341
|
+
var LOCK_TAG = Symbol();
|
|
224
342
|
var PlanetScaleTransaction = class extends PlanetScaleQueryable {
|
|
225
343
|
constructor(tx, options, txDeferred, txResultPromise) {
|
|
226
344
|
super(tx);
|
|
@@ -228,6 +346,20 @@ var PlanetScaleTransaction = class extends PlanetScaleQueryable {
|
|
|
228
346
|
this.txDeferred = txDeferred;
|
|
229
347
|
this.txResultPromise = txResultPromise;
|
|
230
348
|
}
|
|
349
|
+
// The PlanetScale connection objects are not meant to be used concurrently,
|
|
350
|
+
// so we override the `performIO` method to synchronize access to it with a mutex.
|
|
351
|
+
// See: https://github.com/mattrobenolt/ps-http-sim/issues/7
|
|
352
|
+
[LOCK_TAG] = new import_async_mutex.Mutex();
|
|
353
|
+
async performIO(query) {
|
|
354
|
+
const release = await this[LOCK_TAG].acquire();
|
|
355
|
+
try {
|
|
356
|
+
return await super.performIO(query);
|
|
357
|
+
} catch (e) {
|
|
358
|
+
onError(e);
|
|
359
|
+
} finally {
|
|
360
|
+
release();
|
|
361
|
+
}
|
|
362
|
+
}
|
|
231
363
|
async commit() {
|
|
232
364
|
debug(`[js::commit]`);
|
|
233
365
|
this.txDeferred.resolve();
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// src/planetscale.ts
|
|
2
2
|
import * as planetScale from "@planetscale/database";
|
|
3
3
|
import { Debug, DriverAdapterError } from "@prisma/driver-adapter-utils";
|
|
4
|
+
import { Mutex } from "async-mutex";
|
|
4
5
|
|
|
5
6
|
// package.json
|
|
6
7
|
var name = "@prisma/adapter-planetscale";
|
|
@@ -96,6 +97,117 @@ function createDeferred() {
|
|
|
96
97
|
];
|
|
97
98
|
}
|
|
98
99
|
|
|
100
|
+
// src/errors.ts
|
|
101
|
+
function convertDriverError(error) {
|
|
102
|
+
switch (error.code) {
|
|
103
|
+
case 1062: {
|
|
104
|
+
const index = error.message.split(" ").pop()?.split("'").at(1)?.split(".").pop();
|
|
105
|
+
return {
|
|
106
|
+
kind: "UniqueConstraintViolation",
|
|
107
|
+
constraint: index !== void 0 ? { index } : void 0
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
case 1451:
|
|
111
|
+
case 1452: {
|
|
112
|
+
const field = error.message.split(" ").at(17)?.split("`").at(1);
|
|
113
|
+
return {
|
|
114
|
+
kind: "ForeignKeyConstraintViolation",
|
|
115
|
+
constraint: field !== void 0 ? { fields: [field] } : void 0
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
case 1263: {
|
|
119
|
+
const index = error.message.split(" ").pop()?.split("'").at(1);
|
|
120
|
+
return {
|
|
121
|
+
kind: "NullConstraintViolation",
|
|
122
|
+
constraint: index !== void 0 ? { index } : void 0
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
case 1264:
|
|
126
|
+
return {
|
|
127
|
+
kind: "ValueOutOfRange",
|
|
128
|
+
cause: error.message
|
|
129
|
+
};
|
|
130
|
+
case 1364:
|
|
131
|
+
case 1048: {
|
|
132
|
+
const field = error.message.split(" ").at(1)?.split("'").at(1);
|
|
133
|
+
return {
|
|
134
|
+
kind: "NullConstraintViolation",
|
|
135
|
+
constraint: field !== void 0 ? { fields: [field] } : void 0
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
case 1049: {
|
|
139
|
+
const db = error.message.split(" ").pop()?.split("'").at(1);
|
|
140
|
+
return {
|
|
141
|
+
kind: "DatabaseDoesNotExist",
|
|
142
|
+
db
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
case 1007: {
|
|
146
|
+
const db = error.message.split(" ").at(3)?.split("'").at(1);
|
|
147
|
+
return {
|
|
148
|
+
kind: "DatabaseAlreadyExists",
|
|
149
|
+
db
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
case 1044: {
|
|
153
|
+
const db = error.message.split(" ").pop()?.split("'").at(1);
|
|
154
|
+
return {
|
|
155
|
+
kind: "DatabaseAccessDenied",
|
|
156
|
+
db
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
case 1045: {
|
|
160
|
+
const user = error.message.split(" ").at(4)?.split("@").at(0)?.split("'").at(1);
|
|
161
|
+
return {
|
|
162
|
+
kind: "AuthenticationFailed",
|
|
163
|
+
user
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
case 1146: {
|
|
167
|
+
const table = error.message.split(" ").at(1)?.split("'").at(1)?.split(".").pop();
|
|
168
|
+
return {
|
|
169
|
+
kind: "TableDoesNotExist",
|
|
170
|
+
table
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
case 1054: {
|
|
174
|
+
const column = error.message.split(" ").at(2)?.split("'").at(1);
|
|
175
|
+
return {
|
|
176
|
+
kind: "ColumnNotFound",
|
|
177
|
+
column
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
case 1406: {
|
|
181
|
+
const column = error.message.split(" ").flatMap((part) => part.split("'")).at(6);
|
|
182
|
+
return {
|
|
183
|
+
kind: "LengthMismatch",
|
|
184
|
+
column
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
case 1191:
|
|
188
|
+
return {
|
|
189
|
+
kind: "MissingFullTextSearchIndex"
|
|
190
|
+
};
|
|
191
|
+
case 1213:
|
|
192
|
+
return {
|
|
193
|
+
kind: "TransactionWriteConflict"
|
|
194
|
+
};
|
|
195
|
+
case 1040:
|
|
196
|
+
case 1203:
|
|
197
|
+
return {
|
|
198
|
+
kind: "TooManyConnections",
|
|
199
|
+
cause: error.message
|
|
200
|
+
};
|
|
201
|
+
default:
|
|
202
|
+
return {
|
|
203
|
+
kind: "mysql",
|
|
204
|
+
code: error.code,
|
|
205
|
+
message: error.message,
|
|
206
|
+
state: error.state
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
99
211
|
// src/planetscale.ts
|
|
100
212
|
var debug = Debug("prisma:driver-adapter:planetscale");
|
|
101
213
|
var RollbackError = class _RollbackError extends Error {
|
|
@@ -161,23 +273,28 @@ function onError(error) {
|
|
|
161
273
|
if (error.name === "DatabaseError") {
|
|
162
274
|
const parsed = parseErrorMessage(error.message);
|
|
163
275
|
if (parsed) {
|
|
164
|
-
throw new DriverAdapterError(
|
|
165
|
-
kind: "mysql",
|
|
166
|
-
...parsed
|
|
167
|
-
});
|
|
276
|
+
throw new DriverAdapterError(convertDriverError(parsed));
|
|
168
277
|
}
|
|
169
278
|
}
|
|
170
279
|
debug("Error in performIO: %O", error);
|
|
171
280
|
throw error;
|
|
172
281
|
}
|
|
173
|
-
function parseErrorMessage(
|
|
282
|
+
function parseErrorMessage(error) {
|
|
174
283
|
const regex = /^(.*) \(errno (\d+)\) \(sqlstate ([A-Z0-9]+)\)/;
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
const
|
|
284
|
+
let match = null;
|
|
285
|
+
while (true) {
|
|
286
|
+
const result = error.match(regex);
|
|
287
|
+
if (result === null) {
|
|
288
|
+
break;
|
|
289
|
+
}
|
|
290
|
+
match = result;
|
|
291
|
+
error = match[1];
|
|
292
|
+
}
|
|
293
|
+
if (match !== null) {
|
|
294
|
+
const [, message, codeAsString, sqlstate] = match;
|
|
178
295
|
const code = Number.parseInt(codeAsString, 10);
|
|
179
296
|
return {
|
|
180
|
-
message
|
|
297
|
+
message,
|
|
181
298
|
code,
|
|
182
299
|
state: sqlstate
|
|
183
300
|
};
|
|
@@ -185,6 +302,7 @@ function parseErrorMessage(message) {
|
|
|
185
302
|
return void 0;
|
|
186
303
|
}
|
|
187
304
|
}
|
|
305
|
+
var LOCK_TAG = Symbol();
|
|
188
306
|
var PlanetScaleTransaction = class extends PlanetScaleQueryable {
|
|
189
307
|
constructor(tx, options, txDeferred, txResultPromise) {
|
|
190
308
|
super(tx);
|
|
@@ -192,6 +310,20 @@ var PlanetScaleTransaction = class extends PlanetScaleQueryable {
|
|
|
192
310
|
this.txDeferred = txDeferred;
|
|
193
311
|
this.txResultPromise = txResultPromise;
|
|
194
312
|
}
|
|
313
|
+
// The PlanetScale connection objects are not meant to be used concurrently,
|
|
314
|
+
// so we override the `performIO` method to synchronize access to it with a mutex.
|
|
315
|
+
// See: https://github.com/mattrobenolt/ps-http-sim/issues/7
|
|
316
|
+
[LOCK_TAG] = new Mutex();
|
|
317
|
+
async performIO(query) {
|
|
318
|
+
const release = await this[LOCK_TAG].acquire();
|
|
319
|
+
try {
|
|
320
|
+
return await super.performIO(query);
|
|
321
|
+
} catch (e) {
|
|
322
|
+
onError(e);
|
|
323
|
+
} finally {
|
|
324
|
+
release();
|
|
325
|
+
}
|
|
326
|
+
}
|
|
195
327
|
async commit() {
|
|
196
328
|
debug(`[js::commit]`);
|
|
197
329
|
this.txDeferred.resolve();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma/adapter-planetscale",
|
|
3
|
-
"version": "6.10.0-dev.
|
|
3
|
+
"version": "6.10.0-dev.4",
|
|
4
4
|
"description": "Prisma's driver adapter for \"@planetscale/database\"",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -31,7 +31,8 @@
|
|
|
31
31
|
"license": "Apache-2.0",
|
|
32
32
|
"sideEffects": false,
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"
|
|
34
|
+
"async-mutex": "0.5.0",
|
|
35
|
+
"@prisma/driver-adapter-utils": "6.10.0-dev.4"
|
|
35
36
|
},
|
|
36
37
|
"devDependencies": {
|
|
37
38
|
"@planetscale/database": "1.19.0",
|