Skip to content

Commit 19a3ab2

Browse files
authored
Merge pull request #717 from utopia-php/1.x
1.x
2 parents daf0276 + c141d87 commit 19a3ab2

14 files changed

Lines changed: 262 additions & 19 deletions

File tree

‎src/Database/Adapter.php‎

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -388,19 +388,6 @@ public function withTransaction(callable $callback): mixed
388388
} catch (\Throwable $action) {
389389
try {
390390
$this->rollbackTransaction();
391-
392-
if (
393-
$action instanceof DuplicateException ||
394-
$action instanceof RestrictedException ||
395-
$action instanceof AuthorizationException ||
396-
$action instanceof RelationshipException ||
397-
$action instanceof ConflictException ||
398-
$action instanceof LimitException
399-
) {
400-
$this->inTransaction = 0;
401-
throw $action;
402-
}
403-
404391
} catch (\Throwable $rollback) {
405392
if ($attempts < $retries) {
406393
\usleep($sleep * ($attempts + 1));
@@ -411,6 +398,18 @@ public function withTransaction(callable $callback): mixed
411398
throw $rollback;
412399
}
413400

401+
if (
402+
$action instanceof DuplicateException ||
403+
$action instanceof RestrictedException ||
404+
$action instanceof AuthorizationException ||
405+
$action instanceof RelationshipException ||
406+
$action instanceof ConflictException ||
407+
$action instanceof LimitException
408+
) {
409+
$this->inTransaction = 0;
410+
throw $action;
411+
}
412+
414413
if ($attempts < $retries) {
415414
\usleep($sleep * ($attempts + 1));
416415
continue;
@@ -1064,6 +1063,13 @@ abstract public function getSupportForSpatialAttributes(): bool;
10641063
*/
10651064
abstract public function getSupportForSpatialIndexNull(): bool;
10661065

1066+
/**
1067+
* Adapter supports optional spatial attributes with existing rows.
1068+
*
1069+
* @return bool
1070+
*/
1071+
abstract public function getSupportForOptionalSpatialAttributeWithExistingRows(): bool;
1072+
10671073
/**
10681074
* Does the adapter support order attribute in spatial indexes?
10691075
*

‎src/Database/Adapter/MariaDB.php‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1664,6 +1664,16 @@ protected function getPDOType(mixed $value): int
16641664
};
16651665
}
16661666

1667+
/**
1668+
* Get the SQL function for random ordering
1669+
*
1670+
* @return string
1671+
*/
1672+
protected function getRandomOrder(): string
1673+
{
1674+
return 'RAND()';
1675+
}
1676+
16671677
/**
16681678
* Size of POINT spatial type
16691679
*
@@ -1917,4 +1927,14 @@ public function getSupportForSpatialAxisOrder(): bool
19171927
{
19181928
return false;
19191929
}
1930+
1931+
/**
1932+
* Adapter supports optional spatial attributes with existing rows.
1933+
*
1934+
* @return bool
1935+
*/
1936+
public function getSupportForOptionalSpatialAttributeWithExistingRows(): bool
1937+
{
1938+
return true;
1939+
}
19201940
}

‎src/Database/Adapter/MySQL.php‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Utopia\Database\Database;
77
use Utopia\Database\Exception as DatabaseException;
88
use Utopia\Database\Exception\Dependency as DependencyException;
9+
use Utopia\Database\Exception\Structure as StructureException;
910
use Utopia\Database\Exception\Timeout as TimeoutException;
1011
use Utopia\Database\Query;
1112

@@ -155,6 +156,10 @@ protected function processException(PDOException $e): \Exception
155156
return new DependencyException('Attribute cannot be deleted because it is used in an index', $e->getCode(), $e);
156157
}
157158

159+
if ($e->getCode() === '22004' && isset($e->errorInfo[1]) && $e->errorInfo[1] === 1138) {
160+
return new StructureException('Attribute does not allow null values', $e->getCode(), $e);
161+
}
162+
158163
return parent::processException($e);
159164
}
160165
/**
@@ -249,4 +254,14 @@ protected function getSpatialAxisOrderSpec(): string
249254
{
250255
return "'axis-order=long-lat'";
251256
}
257+
258+
/**
259+
* Adapter supports optional spatial attributes with existing rows.
260+
*
261+
* @return bool
262+
*/
263+
public function getSupportForOptionalSpatialAttributeWithExistingRows(): bool
264+
{
265+
return false;
266+
}
252267
}

‎src/Database/Adapter/Pool.php‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,16 @@ public function getSupportForSpatialAxisOrder(): bool
544544
return $this->delegate(__FUNCTION__, \func_get_args());
545545
}
546546

547+
/**
548+
* Adapter supports optional spatial attributes with existing rows.
549+
*
550+
* @return bool
551+
*/
552+
public function getSupportForOptionalSpatialAttributeWithExistingRows(): bool
553+
{
554+
return $this->delegate(__FUNCTION__, \func_get_args());
555+
}
556+
547557
public function decodePoint(string $wkb): array
548558
{
549559
return $this->delegate(__FUNCTION__, \func_get_args());

‎src/Database/Adapter/Postgres.php‎

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1790,6 +1790,16 @@ protected function getPDOType(mixed $value): int
17901790
};
17911791
}
17921792

1793+
/**
1794+
* Get the SQL function for random ordering
1795+
*
1796+
* @return string
1797+
*/
1798+
protected function getRandomOrder(): string
1799+
{
1800+
return 'RANDOM()';
1801+
}
1802+
17931803
/**
17941804
* Size of POINT spatial type
17951805
*
@@ -2001,6 +2011,16 @@ public function getSupportForSpatialAxisOrder(): bool
20012011
return false;
20022012
}
20032013

2014+
/**
2015+
* Adapter supports optional spatial attributes with existing rows.
2016+
*
2017+
* @return bool
2018+
*/
2019+
public function getSupportForOptionalSpatialAttributeWithExistingRows(): bool
2020+
{
2021+
return false;
2022+
}
2023+
20042024
public function decodePoint(string $wkb): array
20052025
{
20062026
if (str_starts_with(strtoupper($wkb), 'POINT(')) {
@@ -2238,5 +2258,4 @@ public function decodePolygon(string $wkb): array
22382258

22392259
return $rings; // array of rings, each ring is array of [x,y]
22402260
}
2241-
22422261
}

‎src/Database/Adapter/SQL.php‎

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1724,6 +1724,13 @@ protected function getPDO(): mixed
17241724
*/
17251725
abstract protected function getPDOType(mixed $value): int;
17261726

1727+
/**
1728+
* Get the SQL function for random ordering
1729+
*
1730+
* @return string
1731+
*/
1732+
abstract protected function getRandomOrder(): string;
1733+
17271734
/**
17281735
* Returns default PDO configuration
17291736
*
@@ -2363,10 +2370,18 @@ public function find(Document $collection, array $queries = [], ?int $limit = 25
23632370
$cursorWhere = [];
23642371

23652372
foreach ($orderAttributes as $i => $originalAttribute) {
2373+
$orderType = $orderTypes[$i] ?? Database::ORDER_ASC;
2374+
2375+
// Handle random ordering specially
2376+
if ($orderType === Database::ORDER_RANDOM) {
2377+
$orders[] = $this->getRandomOrder();
2378+
continue;
2379+
}
2380+
23662381
$attribute = $this->getInternalKeyForAttribute($originalAttribute);
23672382
$attribute = $this->filter($attribute);
23682383

2369-
$orderType = $this->filter($orderTypes[$i] ?? Database::ORDER_ASC);
2384+
$orderType = $this->filter($orderType);
23702385
$direction = $orderType;
23712386

23722387
if ($cursorDirection === Database::CURSOR_BEFORE) {

‎src/Database/Adapter/SQLite.php‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1284,4 +1284,24 @@ public function getSupportForSpatialAxisOrder(): bool
12841284
{
12851285
return false;
12861286
}
1287+
1288+
/**
1289+
* Adapter supports optionalspatial attributes with existing rows.
1290+
*
1291+
* @return bool
1292+
*/
1293+
public function getSupportForOptionalSpatialAttributeWithExistingRows(): bool
1294+
{
1295+
return true;
1296+
}
1297+
1298+
/**
1299+
* Get the SQL function for random ordering
1300+
*
1301+
* @return string
1302+
*/
1303+
protected function getRandomOrder(): string
1304+
{
1305+
return 'RANDOM()';
1306+
}
12871307
}

‎src/Database/Database.php‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ class Database
9191
public const ORDER_ASC = 'ASC';
9292
public const ORDER_DESC = 'DESC';
9393

94+
public const ORDER_RANDOM = 'RANDOM';
95+
9496
// Permissions
9597
public const PERMISSION_CREATE = 'create';
9698
public const PERMISSION_READ = 'read';

‎src/Database/Query.php‎

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ class Query
4646
// Order methods
4747
public const TYPE_ORDER_DESC = 'orderDesc';
4848
public const TYPE_ORDER_ASC = 'orderAsc';
49+
public const TYPE_ORDER_RANDOM = 'orderRandom';
4950

5051
// Pagination methods
5152
public const TYPE_LIMIT = 'limit';
@@ -93,6 +94,7 @@ class Query
9394
self::TYPE_SELECT,
9495
self::TYPE_ORDER_DESC,
9596
self::TYPE_ORDER_ASC,
97+
self::TYPE_ORDER_RANDOM,
9698
self::TYPE_LIMIT,
9799
self::TYPE_OFFSET,
98100
self::TYPE_CURSOR_AFTER,
@@ -247,6 +249,7 @@ public static function isMethod(string $value): bool
247249
self::TYPE_NOT_SEARCH,
248250
self::TYPE_ORDER_ASC,
249251
self::TYPE_ORDER_DESC,
252+
self::TYPE_ORDER_RANDOM,
250253
self::TYPE_LIMIT,
251254
self::TYPE_OFFSET,
252255
self::TYPE_CURSOR_AFTER,
@@ -600,6 +603,16 @@ public static function orderAsc(string $attribute = ''): self
600603
return new self(self::TYPE_ORDER_ASC, $attribute);
601604
}
602605

606+
/**
607+
* Helper method to create Query with orderRandom method
608+
*
609+
* @return Query
610+
*/
611+
public static function orderRandom(): self
612+
{
613+
return new self(self::TYPE_ORDER_RANDOM);
614+
}
615+
603616
/**
604617
* Helper method to create Query with limit method
605618
*
@@ -830,13 +843,16 @@ public static function groupByType(array $queries): array
830843
switch ($method) {
831844
case Query::TYPE_ORDER_ASC:
832845
case Query::TYPE_ORDER_DESC:
846+
case Query::TYPE_ORDER_RANDOM:
833847
if (!empty($attribute)) {
834848
$orderAttributes[] = $attribute;
835849
}
836850

837-
$orderTypes[] = $method === Query::TYPE_ORDER_ASC
838-
? Database::ORDER_ASC
839-
: Database::ORDER_DESC;
851+
$orderTypes[] = match ($method) {
852+
Query::TYPE_ORDER_ASC => Database::ORDER_ASC,
853+
Query::TYPE_ORDER_DESC => Database::ORDER_DESC,
854+
Query::TYPE_ORDER_RANDOM => Database::ORDER_RANDOM,
855+
};
840856

841857
break;
842858
case Query::TYPE_LIMIT:

‎src/Database/Validator/Queries.php‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ public function isValid($value): bool
8585
Query::TYPE_CURSOR_AFTER,
8686
Query::TYPE_CURSOR_BEFORE => Base::METHOD_TYPE_CURSOR,
8787
Query::TYPE_ORDER_ASC,
88-
Query::TYPE_ORDER_DESC => Base::METHOD_TYPE_ORDER,
88+
Query::TYPE_ORDER_DESC,
89+
Query::TYPE_ORDER_RANDOM => Base::METHOD_TYPE_ORDER,
8990
Query::TYPE_EQUAL,
9091
Query::TYPE_NOT_EQUAL,
9192
Query::TYPE_LESSER,

0 commit comments

Comments
 (0)