diff --git a/src/Database/Adapter/MariaDB.php b/src/Database/Adapter/MariaDB.php index 599da878e..37c230f60 100644 --- a/src/Database/Adapter/MariaDB.php +++ b/src/Database/Adapter/MariaDB.php @@ -10,6 +10,7 @@ use Utopia\Database\Exception\Character as CharacterException; use Utopia\Database\Exception\Duplicate as DuplicateException; use Utopia\Database\Exception\Limit as LimitException; +use Utopia\Database\Exception\Unique as UniqueException; use Utopia\Database\Exception\NotFound as NotFoundException; use Utopia\Database\Exception\Operator as OperatorException; use Utopia\Database\Exception\Query as QueryException; @@ -1995,7 +1996,7 @@ protected function processException(PDOException $e): \Exception return new DuplicateException('Duplicate permissions for document', $e->getCode(), $e); } if (!\str_contains($message, '_uid')) { - return new DuplicateException('Document with the requested unique attributes already exists', $e->getCode(), $e); + return new UniqueException('Unique index violation', $e->getCode(), $e); } return new DuplicateException('Document already exists', $e->getCode(), $e); } diff --git a/src/Database/Adapter/Postgres.php b/src/Database/Adapter/Postgres.php index d81cdec0b..85cdfcf1a 100644 --- a/src/Database/Adapter/Postgres.php +++ b/src/Database/Adapter/Postgres.php @@ -11,6 +11,7 @@ use Utopia\Database\Exception as DatabaseException; use Utopia\Database\Exception\Duplicate as DuplicateException; use Utopia\Database\Exception\Limit as LimitException; +use Utopia\Database\Exception\Unique as UniqueException; use Utopia\Database\Exception\NotFound as NotFoundException; use Utopia\Database\Exception\Operator as OperatorException; use Utopia\Database\Exception\Timeout as TimeoutException; @@ -2224,9 +2225,13 @@ protected function processException(PDOException $e): \Exception // Duplicate row if ($e->getCode() === '23505' && isset($e->errorInfo[1]) && $e->errorInfo[1] === 7) { - $message = $e->getMessage(); - if (!\str_contains($message, '_uid')) { - return new DuplicateException('Document with the requested unique attributes already exists', $e->getCode(), $e); + if (preg_match('/Key \(([^)]+)\)=\(.+\) already exists/', $e->getMessage(), $matches)) { + $columns = array_map('trim', explode(',', $matches[1])); + sort($columns); + $target = $this->sharedTables ? ['_tenant', '_uid'] : ['_uid']; + if ($columns !== $target) { + return new UniqueException('Unique index violation', $e->getCode(), $e); + } } return new DuplicateException('Document already exists', $e->getCode(), $e); } diff --git a/src/Database/Adapter/SQLite.php b/src/Database/Adapter/SQLite.php index 5b07ce3b7..952d2858f 100644 --- a/src/Database/Adapter/SQLite.php +++ b/src/Database/Adapter/SQLite.php @@ -11,6 +11,7 @@ use Utopia\Database\Exception as DatabaseException; use Utopia\Database\Exception\Duplicate as DuplicateException; use Utopia\Database\Exception\Limit as LimitException; +use Utopia\Database\Exception\Unique as UniqueException; use Utopia\Database\Exception\NotFound as NotFoundException; use Utopia\Database\Exception\Operator as OperatorException; use Utopia\Database\Exception\Timeout as TimeoutException; @@ -1994,7 +1995,7 @@ protected function processException(PDOException $e): \Exception stripos($message, 'duplicate') !== false ) { if (!\str_contains($message, '_uid')) { - return new DuplicateException('Document with the requested unique attributes already exists', $e->getCode(), $e); + return new UniqueException('Unique index violation', $e->getCode(), $e); } return new DuplicateException('Document already exists', $e->getCode(), $e); } diff --git a/src/Database/Exception/Unique.php b/src/Database/Exception/Unique.php new file mode 100644 index 000000000..57a4dc961 --- /dev/null +++ b/src/Database/Exception/Unique.php @@ -0,0 +1,9 @@ +