@balena/pinejs 16.0.3-build-renovate-major-commander-fdfadc781eb734f1b4326f8bc7c5d1f163092b02-1 → 16.1.0-build-partial-unique-index-constraints-c664148d85c67b645954adc929c778a7ce81115f-2
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/.pinejs-cache.json +1 -1
- package/.versionbot/CHANGELOG.yml +143 -9
- package/CHANGELOG.md +56 -2
- package/VERSION +1 -1
- package/out/sbvr-api/sbvr-utils.js +36 -18
- package/out/sbvr-api/sbvr-utils.js.map +1 -1
- package/package.json +4 -4
- package/src/sbvr-api/sbvr-utils.ts +53 -23
@@ -242,11 +242,17 @@ const prettifyConstraintError = (
|
|
242
242
|
request: uriParser.ODataRequest,
|
243
243
|
) => {
|
244
244
|
if (err instanceof db.ConstraintError) {
|
245
|
-
let
|
245
|
+
let keyMatches: RegExpExecArray | null = null;
|
246
|
+
let violatedConstraintInfo:
|
247
|
+
| {
|
248
|
+
table: AbstractSQLCompiler.AbstractSqlTable;
|
249
|
+
name: string;
|
250
|
+
}
|
251
|
+
| undefined;
|
246
252
|
if (err instanceof db.UniqueConstraintError) {
|
247
253
|
switch (db.engine) {
|
248
254
|
case 'mysql':
|
249
|
-
|
255
|
+
keyMatches =
|
250
256
|
/ER_DUP_ENTRY: Duplicate entry '.*?[^\\]' for key '(.*?[^\\])'/.exec(
|
251
257
|
err.message,
|
252
258
|
);
|
@@ -254,22 +260,46 @@ const prettifyConstraintError = (
|
|
254
260
|
case 'postgres': {
|
255
261
|
const resourceName = resolveSynonym(request);
|
256
262
|
const abstractSqlModel = getFinalAbstractSqlModel(request);
|
257
|
-
|
258
|
-
|
259
|
-
|
263
|
+
const table = abstractSqlModel.tables[resourceName];
|
264
|
+
keyMatches = new RegExp('"' + table.name + '_(.*?)_key"').exec(
|
265
|
+
err.message,
|
266
|
+
);
|
267
|
+
// no need to run the regex if a `_key` error was already matched, or if there are
|
268
|
+
// no indexes on the table (since those are the only supported uniqueness errors atm)
|
269
|
+
if (keyMatches == null && table.indexes.length > 0) {
|
270
|
+
const indexConstraintName =
|
271
|
+
/duplicate key value violates unique constraint "(.*)"/.exec(
|
272
|
+
err.message,
|
273
|
+
)?.[1];
|
274
|
+
if (indexConstraintName != null) {
|
275
|
+
violatedConstraintInfo = {
|
276
|
+
table,
|
277
|
+
name: indexConstraintName,
|
278
|
+
};
|
279
|
+
}
|
280
|
+
}
|
260
281
|
break;
|
261
282
|
}
|
262
283
|
}
|
263
|
-
|
264
|
-
|
265
|
-
throw new db.UniqueConstraintError(
|
284
|
+
if (keyMatches != null) {
|
285
|
+
const columns = keyMatches[1].split('_');
|
286
|
+
throw new db.UniqueConstraintError(
|
287
|
+
'"' +
|
288
|
+
columns.map(sqlNameToODataName).join('" and "') +
|
289
|
+
'" must be unique.',
|
290
|
+
);
|
266
291
|
}
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
292
|
+
if (violatedConstraintInfo != null) {
|
293
|
+
const { table, name: violatedConstraintName } = violatedConstraintInfo;
|
294
|
+
const violatedUniqueIndex = table.indexes.find(
|
295
|
+
(idx) => idx.name === violatedConstraintName,
|
296
|
+
);
|
297
|
+
if (violatedUniqueIndex?.description != null) {
|
298
|
+
throw new BadRequestError(violatedUniqueIndex.description);
|
299
|
+
}
|
300
|
+
}
|
301
|
+
// We know it's the right error type, so if matches exists just throw a generic error message, since we have failed to get the info for a more specific one.
|
302
|
+
throw new db.UniqueConstraintError('Unique key constraint violated');
|
273
303
|
}
|
274
304
|
|
275
305
|
if (err instanceof db.ExclusionConstraintError) {
|
@@ -280,7 +310,7 @@ const prettifyConstraintError = (
|
|
280
310
|
if (err instanceof db.ForeignKeyConstraintError) {
|
281
311
|
switch (db.engine) {
|
282
312
|
case 'mysql':
|
283
|
-
|
313
|
+
keyMatches =
|
284
314
|
/ER_ROW_IS_REFERENCED_: Cannot delete or update a parent row: a foreign key constraint fails \(".*?"\.(".*?").*/.exec(
|
285
315
|
err.message,
|
286
316
|
);
|
@@ -289,13 +319,13 @@ const prettifyConstraintError = (
|
|
289
319
|
const resourceName = resolveSynonym(request);
|
290
320
|
const abstractSqlModel = getFinalAbstractSqlModel(request);
|
291
321
|
const tableName = abstractSqlModel.tables[resourceName].name;
|
292
|
-
|
322
|
+
keyMatches = new RegExp(
|
293
323
|
'"' +
|
294
324
|
tableName +
|
295
325
|
'" violates foreign key constraint ".*?" on table "(.*?)"',
|
296
326
|
).exec(err.message);
|
297
|
-
if (
|
298
|
-
|
327
|
+
if (keyMatches == null) {
|
328
|
+
keyMatches = new RegExp(
|
299
329
|
'"' +
|
300
330
|
tableName +
|
301
331
|
'" violates foreign key constraint "' +
|
@@ -308,13 +338,13 @@ const prettifyConstraintError = (
|
|
308
338
|
}
|
309
339
|
// We know it's the right error type, so if no matches exists just throw a generic error message,
|
310
340
|
// since we have failed to get the info for a more specific one.
|
311
|
-
if (
|
341
|
+
if (keyMatches == null) {
|
312
342
|
throw new db.ForeignKeyConstraintError(
|
313
343
|
'Foreign key constraint violated',
|
314
344
|
);
|
315
345
|
}
|
316
346
|
throw new db.ForeignKeyConstraintError(
|
317
|
-
'Data is referenced by ' + sqlNameToODataName(
|
347
|
+
'Data is referenced by ' + sqlNameToODataName(keyMatches[1]) + '.',
|
318
348
|
);
|
319
349
|
}
|
320
350
|
|
@@ -325,7 +355,7 @@ const prettifyConstraintError = (
|
|
325
355
|
if (table.checks) {
|
326
356
|
switch (db.engine) {
|
327
357
|
case 'postgres':
|
328
|
-
|
358
|
+
keyMatches = new RegExp(
|
329
359
|
'new row for relation "' +
|
330
360
|
table.name +
|
331
361
|
'" violates check constraint "(.*?)"',
|
@@ -333,8 +363,8 @@ const prettifyConstraintError = (
|
|
333
363
|
break;
|
334
364
|
}
|
335
365
|
}
|
336
|
-
if (
|
337
|
-
const checkName =
|
366
|
+
if (keyMatches != null) {
|
367
|
+
const checkName = keyMatches[1];
|
338
368
|
const check = table.checks!.find((c) => c.name === checkName);
|
339
369
|
if (check?.description != null) {
|
340
370
|
throw new BadRequestError(check.description);
|