From 9c49c4eb4635173a05029239120bbef0a35b8d13 Mon Sep 17 00:00:00 2001 From: Rijk van Zanten Date: Thu, 3 Jun 2021 23:33:31 -0400 Subject: [PATCH] Fixed unique constraint violation error extraction for MySQL 5.7 (#6059) * Add MySQL 5.7 docker debug instance * Fix unique error constraint extraction in MySQL 5.7 Fixes #5719 --- api/src/exceptions/database/dialects/mysql.ts | 53 +++++++++++++------ docker-compose.yml | 11 +++- 2 files changed, 48 insertions(+), 16 deletions(-) diff --git a/api/src/exceptions/database/dialects/mysql.ts b/api/src/exceptions/database/dialects/mysql.ts index 02a551753b..4309b0cee4 100644 --- a/api/src/exceptions/database/dialects/mysql.ts +++ b/api/src/exceptions/database/dialects/mysql.ts @@ -43,28 +43,51 @@ function uniqueViolation(error: MySQLError) { if (!matches) return error; - const collection = matches[1].slice(1, -1).split('.')[0]; - - let field = null; - /** * MySQL's error doesn't return the field name in the error. In case the field is created through * Directus (/ Knex), the key name will be `__unique` in which case we can pull * the field name from the key name */ - const indexName = matches[1].slice(1, -1).split('.')[1]; - if (indexName?.startsWith(`${collection}_`) && indexName.endsWith('_unique')) { - field = indexName.slice(collection.length + 1, -7); + /** MySQL 8+ style error message */ + if (matches[1].includes('.')) { + const collection = matches[1].slice(1, -1).split('.')[0]; + + let field = null; + + const indexName = matches[1].slice(1, -1).split('.')[1]; + + if (indexName?.startsWith(`${collection}_`) && indexName.endsWith('_unique')) { + field = indexName.slice(collection.length + 1, -7); + } + + const invalid = matches[0].slice(1, -1); + + return new RecordNotUniqueException(field, { + collection, + field, + invalid, + }); + } else { + /** MySQL 5.7 style error message */ + const indexName = matches[1].slice(1, -1); + + const collection = indexName.split('_')[0]; + + let field = null; + + if (indexName?.startsWith(`${collection}_`) && indexName.endsWith('_unique')) { + field = indexName.slice(collection.length + 1, -7); + } + + const invalid = matches[0].slice(1, -1); + + return new RecordNotUniqueException(field, { + collection, + field, + invalid, + }); } - - const invalid = matches[0].slice(1, -1); - - return new RecordNotUniqueException(field, { - collection, - field, - invalid, - }); } function numericValueOutOfRange(error: MySQLError) { diff --git a/docker-compose.yml b/docker-compose.yml index 6ff2543c8d..0fa0559953 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,13 +4,14 @@ # # Ports: # Postgres: 5100 -# MySQL: 5101 +# MySQL (8): 5101 # MariaDB: 5102 # MS SQL: 5103 # Oracle: 5104 # Redis: 5105 # Minio (S3): 5106 # Azure 5107 +# MySQL (5.7): 5108 # # Credentials: # Postgres: @@ -107,3 +108,11 @@ services: image: mcr.microsoft.com/azure-storage/azurite ports: - 5107:10000 + + mysql5: + image: mysql:5 + environment: + MYSQL_ROOT_PASSWORD: secret + MYSQL_DATABASE: directus + ports: + - 5108:3306