Skip to content

Commit 16f96e5

Browse files
authored
Merge pull request #693 from utopia-php/spatial-attribute-update-fix
updated spatial update attribute
2 parents f06a57a + 2df73ea commit 16f96e5

7 files changed

Lines changed: 67 additions & 12 deletions

File tree

src/Database/Adapter.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -578,10 +578,11 @@ abstract public function createAttributes(string $collection, array $attributes)
578578
* @param bool $signed
579579
* @param bool $array
580580
* @param string|null $newKey
581+
* @param bool $required
581582
*
582583
* @return bool
583584
*/
584-
abstract public function updateAttribute(string $collection, string $id, string $type, int $size, bool $signed = true, bool $array = false, ?string $newKey = null): bool;
585+
abstract public function updateAttribute(string $collection, string $id, string $type, int $size, bool $signed = true, bool $array = false, ?string $newKey = null, bool $required = false): bool;
585586

586587
/**
587588
* Delete Attribute

src/Database/Adapter/MariaDB.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Utopia\Database\Exception as DatabaseException;
1010
use Utopia\Database\Exception\Duplicate as DuplicateException;
1111
use Utopia\Database\Exception\NotFound as NotFoundException;
12+
use Utopia\Database\Exception\Query as QueryException;
1213
use Utopia\Database\Exception\Timeout as TimeoutException;
1314
use Utopia\Database\Exception\Truncate as TruncateException;
1415
use Utopia\Database\Helpers\ID;
@@ -409,16 +410,16 @@ public function getSchemaAttributes(string $collection): array
409410
* @param bool $signed
410411
* @param bool $array
411412
* @param string|null $newKey
413+
* @param bool $required
412414
* @return bool
413415
* @throws DatabaseException
414416
*/
415-
public function updateAttribute(string $collection, string $id, string $type, int $size, bool $signed = true, bool $array = false, ?string $newKey = null): bool
417+
public function updateAttribute(string $collection, string $id, string $type, int $size, bool $signed = true, bool $array = false, ?string $newKey = null, bool $required = false): bool
416418
{
417419
$name = $this->filter($collection);
418420
$id = $this->filter($id);
419421
$newKey = empty($newKey) ? null : $this->filter($newKey);
420-
$type = $this->getSQLType($type, $size, $signed, $array, false);
421-
422+
$type = $this->getSQLType($type, $size, $signed, $array, $required);
422423
if (!empty($newKey)) {
423424
$sql = "ALTER TABLE {$this->getSQLTable($name)} CHANGE COLUMN `{$id}` `{$newKey}` {$type};";
424425
} else {
@@ -1393,7 +1394,7 @@ protected function handleDistanceSpatialQueries(Query $query, array &$binds, str
13931394
$wktType = $this->getSpatialTypeFromWKT($wkt);
13941395
$attrType = strtolower($type);
13951396
if ($wktType != Database::VAR_POINT || $attrType != Database::VAR_POINT) {
1396-
throw new DatabaseException('Distance in meters is not supported between '.$attrType . ' and '. $wktType);
1397+
throw new QueryException('Distance in meters is not supported between '.$attrType . ' and '. $wktType);
13971398
}
13981399
return "ST_DISTANCE_SPHERE({$alias}.{$attribute}, ST_GeomFromText(:{$placeholder}_0), 6371000) {$operator} :{$placeholder}_1";
13991400
}

src/Database/Adapter/Pool.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ public function createAttributes(string $collection, array $attributes): bool
175175
return $this->delegate(__FUNCTION__, \func_get_args());
176176
}
177177

178-
public function updateAttribute(string $collection, string $id, string $type, int $size, bool $signed = true, bool $array = false, ?string $newKey = null): bool
178+
public function updateAttribute(string $collection, string $id, string $type, int $size, bool $signed = true, bool $array = false, ?string $newKey = null, bool $required = false): bool
179179
{
180180
return $this->delegate(__FUNCTION__, \func_get_args());
181181
}

src/Database/Adapter/Postgres.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -535,16 +535,17 @@ public function renameAttribute(string $collection, string $old, string $new): b
535535
* @param bool $signed
536536
* @param bool $array
537537
* @param string|null $newKey
538+
* @param bool $required
538539
* @return bool
539540
* @throws Exception
540541
* @throws PDOException
541542
*/
542-
public function updateAttribute(string $collection, string $id, string $type, int $size, bool $signed = true, bool $array = false, ?string $newKey = null): bool
543+
public function updateAttribute(string $collection, string $id, string $type, int $size, bool $signed = true, bool $array = false, ?string $newKey = null, bool $required = false): bool
543544
{
544545
$name = $this->filter($collection);
545546
$id = $this->filter($id);
546547
$newKey = empty($newKey) ? null : $this->filter($newKey);
547-
$type = $this->getSQLType($type, $size, $signed, $array, false);
548+
$type = $this->getSQLType($type, $size, $signed, $array, $required);
548549

549550
if ($type == 'TIMESTAMP(3)') {
550551
$type = "TIMESTAMP(3) without time zone USING TO_TIMESTAMP(\"$id\", 'YYYY-MM-DD HH24:MI:SS.MS')";

src/Database/Adapter/SQLite.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,11 +327,12 @@ public function analyzeCollection(string $collection): bool
327327
* @param bool $signed
328328
* @param bool $array
329329
* @param string|null $newKey
330+
* @param bool $required
330331
* @return bool
331332
* @throws Exception
332333
* @throws PDOException
333334
*/
334-
public function updateAttribute(string $collection, string $id, string $type, int $size, bool $signed = true, bool $array = false, ?string $newKey = null): bool
335+
public function updateAttribute(string $collection, string $id, string $type, int $size, bool $signed = true, bool $array = false, ?string $newKey = null, bool $required = false): bool
335336
{
336337
if (!empty($newKey) && $newKey !== $id) {
337338
return $this->renameAttribute($collection, $id, $newKey);

src/Database/Database.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2161,6 +2161,10 @@ public function updateAttribute(string $collection, string $id, ?string $type =
21612161
$default = null;
21622162
}
21632163

2164+
if ($required === true && in_array($type, Database::SPATIAL_TYPES)) {
2165+
$altering = true;
2166+
}
2167+
21642168
switch ($type) {
21652169
case self::VAR_STRING:
21662170
if (empty($size)) {
@@ -2322,7 +2326,7 @@ public function updateAttribute(string $collection, string $id, ?string $type =
23222326
}
23232327
}
23242328

2325-
$updated = $this->adapter->updateAttribute($collection, $id, $type, $size, $signed, $array, $newKey);
2329+
$updated = $this->adapter->updateAttribute($collection, $id, $type, $size, $signed, $array, $newKey, $required);
23262330

23272331
if (!$updated) {
23282332
throw new DatabaseException('Failed to update attribute');

tests/e2e/Adapter/Scopes/SpatialTests.php

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Utopia\Database\Database;
66
use Utopia\Database\Document;
77
use Utopia\Database\Exception;
8+
use Utopia\Database\Exception\Query as QueryException;
89
use Utopia\Database\Exception\Structure as StructureException;
910
use Utopia\Database\Helpers\ID;
1011
use Utopia\Database\Helpers\Permission;
@@ -840,6 +841,53 @@ public function testSpatialIndex(): void
840841
} finally {
841842
$database->deleteCollection($collNullIndex);
842843
}
844+
845+
$collUpdateNull = 'spatial_idx_req';
846+
try {
847+
$database->createCollection($collUpdateNull);
848+
849+
$database->createAttribute($collUpdateNull, 'loc', Database::VAR_POINT, 0, false);
850+
if (!$nullSupported) {
851+
try {
852+
$database->createIndex($collUpdateNull, 'idx_loc_required', Database::INDEX_SPATIAL, ['loc']);
853+
$this->fail('Expected exception when creating spatial index on NULL-able attribute');
854+
} catch (\Throwable $e) {
855+
$this->assertInstanceOf(Exception::class, $e);
856+
}
857+
} else {
858+
$this->assertTrue($database->createIndex($collUpdateNull, 'idx_loc', Database::INDEX_SPATIAL, ['loc']));
859+
}
860+
861+
$database->updateAttribute($collUpdateNull, 'loc', required: true);
862+
863+
$this->assertTrue($database->createIndex($collUpdateNull, 'idx_loc_req', Database::INDEX_SPATIAL, ['loc']));
864+
} finally {
865+
$database->deleteCollection($collUpdateNull);
866+
}
867+
868+
869+
$collUpdateNull = 'spatial_idx_index_null_required_true';
870+
try {
871+
$database->createCollection($collUpdateNull);
872+
873+
$database->createAttribute($collUpdateNull, 'loc', Database::VAR_POINT, 0, false);
874+
if (!$nullSupported) {
875+
try {
876+
$database->createIndex($collUpdateNull, 'idx_loc', Database::INDEX_SPATIAL, ['loc']);
877+
$this->fail('Expected exception when creating spatial index on NULL-able attribute');
878+
} catch (\Throwable $e) {
879+
$this->assertInstanceOf(Exception::class, $e);
880+
}
881+
} else {
882+
$this->assertTrue($database->createIndex($collUpdateNull, 'idx_loc', Database::INDEX_SPATIAL, ['loc']));
883+
}
884+
885+
$database->updateAttribute($collUpdateNull, 'loc', required: true);
886+
887+
$this->assertTrue($database->createIndex($collUpdateNull, 'new index', Database::INDEX_SPATIAL, ['loc']));
888+
} finally {
889+
$database->deleteCollection($collUpdateNull);
890+
}
843891
}
844892

845893
public function testComplexGeometricShapes(): void
@@ -2335,11 +2383,10 @@ public function testSpatialDistanceInMeterError(): void
23352383
]);
23362384
$this->fail('Expected Exception not thrown for ' . implode(' vs ', $case['expected']));
23372385
} catch (\Exception $e) {
2338-
$this->assertInstanceOf(\Exception::class, $e);
2386+
$this->assertInstanceOf(QueryException::class, $e);
23392387

23402388
// Validate exception message contains correct type names
23412389
$msg = strtolower($e->getMessage());
2342-
var_dump($msg);
23432390
$this->assertStringContainsString($case['expected'][0], $msg, 'Attr type missing in exception');
23442391
$this->assertStringContainsString($case['expected'][1], $msg, 'Geom type missing in exception');
23452392
}

0 commit comments

Comments
 (0)