Skip to content

Commit 796310b

Browse files
spatial types filter
1 parent 0d4f2ec commit 796310b

2 files changed

Lines changed: 170 additions & 11 deletions

File tree

src/Database/Database.php

Lines changed: 102 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,91 @@ function (?string $value) {
477477
return DateTime::formatTz($value);
478478
}
479479
);
480+
481+
self::addFilter(
482+
Database::VAR_POINT,
483+
/**
484+
* @param mixed $value
485+
* @return mixed
486+
*/
487+
function (mixed $value) {
488+
if (is_null($value)) {
489+
return;
490+
}
491+
try {
492+
return self::encodeSpatialData($value, Database::VAR_POINT);
493+
} catch (\Throwable) {
494+
return $value;
495+
}
496+
},
497+
/**
498+
* @param string|null $value
499+
* @return string|null
500+
*/
501+
function (?string $value) {
502+
if (is_null($value)) {
503+
return $value;
504+
}
505+
return self::decodeSpatialData($value);
506+
}
507+
);
508+
self::addFilter(
509+
Database::VAR_LINESTRING,
510+
/**
511+
* @param mixed $value
512+
* @return mixed
513+
*/
514+
function (mixed $value) {
515+
if (is_null($value)) {
516+
return;
517+
}
518+
try {
519+
return self::encodeSpatialData($value, Database::VAR_LINESTRING);
520+
} catch (\Throwable) {
521+
if (is_null($value)) {
522+
return $value;
523+
}
524+
return $value;
525+
}
526+
},
527+
/**
528+
* @param string|null $value
529+
* @return string|null
530+
*/
531+
function (?string $value) {
532+
if (is_null($value)) {
533+
return $value;
534+
}
535+
return self::decodeSpatialData($value);
536+
}
537+
);
538+
self::addFilter(
539+
Database::VAR_POLYGON,
540+
/**
541+
* @param mixed $value
542+
* @return mixed
543+
*/
544+
function (mixed $value) {
545+
if (is_null($value)) {
546+
return;
547+
}
548+
try {
549+
return self::encodeSpatialData($value, Database::VAR_POLYGON);
550+
} catch (\Throwable) {
551+
return $value;
552+
}
553+
},
554+
/**
555+
* @param string|null $value
556+
* @return string|null
557+
*/
558+
function (?string $value) {
559+
if (is_null($value)) {
560+
return $value;
561+
}
562+
return self::decodeSpatialData($value);
563+
}
564+
);
480565
}
481566

482567
/**
@@ -1242,6 +1327,19 @@ public function delete(?string $database = null): bool
12421327
*/
12431328
public function createCollection(string $id, array $attributes = [], array $indexes = [], ?array $permissions = null, bool $documentSecurity = true): Document
12441329
{
1330+
foreach ($attributes as &$attribute) {
1331+
if (in_array($attribute['type'], Database::SPATIAL_TYPES)) {
1332+
$existingFilters = $attribute['filters'] ?? [];
1333+
if (!is_array($existingFilters)) {
1334+
$existingFilters = [$existingFilters];
1335+
}
1336+
$attribute['filters'] = array_values(
1337+
array_unique(array_merge($existingFilters, [$attribute['type']]))
1338+
);
1339+
}
1340+
}
1341+
unset($attribute);
1342+
12451343
$permissions ??= [
12461344
Permission::create(Role::any()),
12471345
];
@@ -1598,6 +1696,10 @@ public function createAttribute(string $collection, string $id, string $type, in
15981696
if ($collection->isEmpty()) {
15991697
throw new NotFoundException('Collection not found');
16001698
}
1699+
if (in_array($type, Database::SPATIAL_TYPES)) {
1700+
$filters[] = $type;
1701+
$filters = array_unique($filters);
1702+
}
16011703

16021704
$attribute = $this->validateAttribute(
16031705
$collection,
@@ -6561,14 +6663,6 @@ public function encode(Document $collection, Document $document): Document
65616663

65626664
foreach ($value as $index => $node) {
65636665
if ($node !== null) {
6564-
// Handle spatial data encoding
6565-
$attributeType = $attribute['type'] ?? '';
6566-
if (in_array($attributeType, Database::SPATIAL_TYPES)) {
6567-
if (is_array($node)) {
6568-
$node = $this->encodeSpatialData($node, $attributeType);
6569-
}
6570-
}
6571-
65726666
foreach ($filters as $filter) {
65736667
$node = $this->encodeAttribute($filter, $node, $document);
65746668
}
@@ -6647,9 +6741,6 @@ public function decode(Document $collection, Document $document, array $selectio
66476741
$value = (is_null($value)) ? [] : $value;
66486742

66496743
foreach ($value as $index => $node) {
6650-
if (is_string($node) && in_array($type, Database::SPATIAL_TYPES)) {
6651-
$node = $this->decodeSpatialData($node);
6652-
}
66536744

66546745
foreach (array_reverse($filters) as $filter) {
66556746
$node = $this->decodeAttribute($filter, $node, $document, $key);

tests/e2e/Adapter/Scopes/SpatialTests.php

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2392,4 +2392,72 @@ public function testSpatialDistanceInMeterError(): void
23922392
}
23932393
}
23942394
}
2395+
public function testSpatialEncodeDecode(): void
2396+
{
2397+
$collection = new Document([
2398+
'$collection' => ID::custom(Database::METADATA),
2399+
'$id' => ID::custom('users'),
2400+
'name' => 'Users',
2401+
'attributes' => [
2402+
[
2403+
'$id' => ID::custom('point'),
2404+
'type' => Database::VAR_POINT,
2405+
'required' => false,
2406+
'filters' => [Database::VAR_POINT],
2407+
],
2408+
[
2409+
'$id' => ID::custom('line'),
2410+
'type' => Database::VAR_LINESTRING,
2411+
'format' => '',
2412+
'required' => false,
2413+
'filters' => [Database::VAR_LINESTRING],
2414+
],
2415+
[
2416+
'$id' => ID::custom('poly'),
2417+
'type' => Database::VAR_POLYGON,
2418+
'format' => '',
2419+
'required' => false,
2420+
'filters' => [Database::VAR_POLYGON],
2421+
]
2422+
]
2423+
]);
2424+
2425+
/** @var Database $database */
2426+
$database = static::getDatabase();
2427+
if (!$database->getAdapter()->getSupportForSpatialAttributes()) {
2428+
$this->markTestSkipped('Adapter does not support spatial attributes');
2429+
}
2430+
$point = "POINT(1 2)";
2431+
$line = "LINESTRING(1 2, 1 2)";
2432+
$poly = "POLYGON((0 0, 0 10, 10 10, 0 0))";
2433+
2434+
$pointArr = [1,2];
2435+
$lineArr = [[1,2],[1,2]];
2436+
$polyArr = [[[0.0, 0.0], [0.0, 10.0], [10.0, 10.0], [0.0, 0.0]]];
2437+
$doc = new Document(['point' => $pointArr ,'line' => $lineArr, 'poly' => $polyArr]);
2438+
2439+
$result = $database->encode($collection, $doc);
2440+
2441+
$this->assertEquals($result->getAttribute('point'), $point);
2442+
$this->assertEquals($result->getAttribute('line'), $line);
2443+
$this->assertEquals($result->getAttribute('poly'), $poly);
2444+
2445+
2446+
$result = $database->decode($collection, $doc);
2447+
$this->assertEquals($result->getAttribute('point'), $pointArr);
2448+
$this->assertEquals($result->getAttribute('line'), $lineArr);
2449+
$this->assertEquals($result->getAttribute('poly'), $polyArr);
2450+
2451+
$stringDoc = new Document(['point' => $point,'line' => $line, 'poly' => $poly]);
2452+
$result = $database->decode($collection, $stringDoc);
2453+
$this->assertEquals($result->getAttribute('point'), $pointArr);
2454+
$this->assertEquals($result->getAttribute('line'), $lineArr);
2455+
$this->assertEquals($result->getAttribute('poly'), $polyArr);
2456+
2457+
$nullDoc = new Document(['point' => null,'line' => null, 'poly' => null]);
2458+
$result = $database->decode($collection, $nullDoc);
2459+
$this->assertEquals($result->getAttribute('point'), null);
2460+
$this->assertEquals($result->getAttribute('line'), null);
2461+
$this->assertEquals($result->getAttribute('poly'), null);
2462+
}
23952463
}

0 commit comments

Comments
 (0)