Skip to content

Commit da8accb

Browse files
updated attribute size and precision point
1 parent f5e713b commit da8accb

7 files changed

Lines changed: 73 additions & 219 deletions

File tree

src/Database/Adapter/MariaDB.php

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1494,7 +1494,11 @@ public function find(Document $collection, array $queries = [], ?int $limit = 25
14941494
$stmt = $this->getPDO()->prepare($sql);
14951495

14961496
foreach ($binds as $key => $value) {
1497-
$stmt->bindValue($key, $value, $this->getPDOType($value));
1497+
if (gettype($value) === 'double') {
1498+
$stmt->bindValue($key, $this->getFloatPrecision($value), PDO::PARAM_STR);
1499+
} else {
1500+
$stmt->bindValue($key, $value, $this->getPDOType($value));
1501+
}
14981502
}
14991503

15001504
$stmt->execute();
@@ -1711,13 +1715,13 @@ protected function handleSpatialQueries(Query $query, array &$binds, string $att
17111715
$distanceParams = $query->getValues()[0];
17121716
$binds[":{$placeholder}_0"] = $this->convertArrayToWKT($distanceParams[0]);
17131717
$binds[":{$placeholder}_1"] = $distanceParams[1];
1714-
return "ST_Distance({$alias}.{$attribute}, ST_GeomFromText(:{$placeholder}_0)) <= :{$placeholder}_1";
1718+
return "ST_Distance({$alias}.{$attribute}, ST_GeomFromText(:{$placeholder}_0)) = :{$placeholder}_1";
17151719

17161720
case Query::TYPE_NOT_DISTANCE:
17171721
$distanceParams = $query->getValues()[0];
17181722
$binds[":{$placeholder}_0"] = $this->convertArrayToWKT($distanceParams[0]);
17191723
$binds[":{$placeholder}_1"] = $distanceParams[1];
1720-
return "ST_Distance({$alias}.{$attribute}, ST_GeomFromText(:{$placeholder}_0)) > :{$placeholder}_1";
1724+
return "ST_Distance({$alias}.{$attribute}, ST_GeomFromText(:{$placeholder}_0)) != :{$placeholder}_1";
17211725

17221726
case Query::TYPE_DISTANCE_GREATER_THAN:
17231727
$distanceParams = $query->getValues()[0];
@@ -1731,18 +1735,6 @@ protected function handleSpatialQueries(Query $query, array &$binds, string $att
17311735
$binds[":{$placeholder}_1"] = $distanceParams[1];
17321736
return "ST_Distance({$alias}.{$attribute}, ST_GeomFromText(:{$placeholder}_0)) < :{$placeholder}_1";
17331737

1734-
case Query::TYPE_NOT_DISTANCE_GREATER_THAN:
1735-
$distanceParams = $query->getValues()[0];
1736-
$binds[":{$placeholder}_0"] = $this->convertArrayToWKT($distanceParams[0]);
1737-
$binds[":{$placeholder}_1"] = $distanceParams[1];
1738-
return "NOT (ST_Distance({$alias}.{$attribute}, ST_GeomFromText(:{$placeholder}_0)) > :{$placeholder}_1)";
1739-
1740-
case Query::TYPE_NOT_DISTANCE_LESS_THAN:
1741-
$distanceParams = $query->getValues()[0];
1742-
$binds[":{$placeholder}_0"] = $this->convertArrayToWKT($distanceParams[0]);
1743-
$binds[":{$placeholder}_1"] = $distanceParams[1];
1744-
return "NOT (ST_Distance({$alias}.{$attribute}, ST_GeomFromText(:{$placeholder}_0)) < :{$placeholder}_1)";
1745-
17461738
case Query::TYPE_INTERSECTS:
17471739
$binds[":{$placeholder}_0"] = $this->convertArrayToWKT($query->getValues()[0]);
17481740
return "ST_Intersects({$alias}.{$attribute}, ST_GeomFromText(:{$placeholder}_0))";
@@ -1978,13 +1970,24 @@ protected function getSQLType(string $type, int $size, bool $signed = true, bool
19781970
protected function getPDOType(mixed $value): int
19791971
{
19801972
return match (gettype($value)) {
1981-
'double', 'string' => PDO::PARAM_STR,
1973+
'string' => PDO::PARAM_STR,
19821974
'integer', 'boolean' => PDO::PARAM_INT,
19831975
'NULL' => PDO::PARAM_NULL,
19841976
default => throw new DatabaseException('Unknown PDO Type for ' . \gettype($value)),
19851977
};
19861978
}
19871979

1980+
/**
1981+
* Size of POINT spatial type
1982+
*
1983+
* @return int
1984+
*/
1985+
protected function getMaxPointSize(): int
1986+
{
1987+
// https://dev.mysql.com/doc/refman/8.4/en/gis-data-formats.html#gis-internal-format
1988+
return 25;
1989+
}
1990+
19881991
public function getMinDateTime(): \DateTime
19891992
{
19901993
return new \DateTime('1000-01-01 00:00:00');

src/Database/Adapter/Postgres.php

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1580,11 +1580,15 @@ public function find(Document $collection, array $queries = [], ?int $limit = 25
15801580

15811581
try {
15821582
$stmt = $this->getPDO()->prepare($sql);
1583+
15831584
foreach ($binds as $key => $value) {
1584-
$stmt->bindValue($key, $value, $this->getPDOType($value));
1585+
if (gettype($value) === 'double') {
1586+
$stmt->bindValue($key, $this->getFloatPrecision($value), PDO::PARAM_STR);
1587+
} else {
1588+
$stmt->bindValue($key, $value, $this->getPDOType($value));
1589+
}
15851590
}
1586-
1587-
$this->execute($stmt);
1591+
$stmt->execute();
15881592
} catch (PDOException $e) {
15891593
throw $this->processException($e);
15901594
}
@@ -1828,18 +1832,6 @@ protected function handleSpatialQueries(Query $query, array &$binds, string $att
18281832
$binds[":{$placeholder}_1"] = $distanceParams[1];
18291833
return "ST_Distance({$alias}.{$attribute}, ST_GeomFromText(:{$placeholder}_0)) < :{$placeholder}_1";
18301834

1831-
case Query::TYPE_NOT_DISTANCE_GREATER_THAN:
1832-
$distanceParams = $query->getValues()[0];
1833-
$binds[":{$placeholder}_0"] = $this->convertArrayToWKT($distanceParams[0]);
1834-
$binds[":{$placeholder}_1"] = $distanceParams[1];
1835-
return "NOT (ST_Distance({$alias}.{$attribute}, ST_GeomFromText(:{$placeholder}_0)) > :{$placeholder}_1)";
1836-
1837-
case Query::TYPE_NOT_DISTANCE_LESS_THAN:
1838-
$distanceParams = $query->getValues()[0];
1839-
$binds[":{$placeholder}_0"] = $this->convertArrayToWKT($distanceParams[0]);
1840-
$binds[":{$placeholder}_1"] = $distanceParams[1];
1841-
return "NOT (ST_Distance({$alias}.{$attribute}, ST_GeomFromText(:{$placeholder}_0)) < :{$placeholder}_1)";
1842-
18431835
case Query::TYPE_EQUAL:
18441836
$binds[":{$placeholder}_0"] = $this->convertArrayToWKT($query->getValues()[0]);
18451837
return "ST_Equals({$alias}.{$attribute}, ST_GeomFromText(:{$placeholder}_0))";
@@ -2099,14 +2091,26 @@ protected function getSQLSchema(): string
20992091
protected function getPDOType(mixed $value): int
21002092
{
21012093
return match (\gettype($value)) {
2102-
'string', 'double' => PDO::PARAM_STR,
2094+
'string' => PDO::PARAM_STR,
21032095
'boolean' => PDO::PARAM_BOOL,
21042096
'integer' => PDO::PARAM_INT,
21052097
'NULL' => PDO::PARAM_NULL,
21062098
default => throw new DatabaseException('Unknown PDO Type for ' . \gettype($value)),
21072099
};
21082100
}
21092101

2102+
/**
2103+
* Size of POINT spatial type
2104+
*
2105+
* @return int
2106+
*/
2107+
protected function getMaxPointSize(): int
2108+
{
2109+
// https://stackoverflow.com/questions/30455025/size-of-data-type-geographypoint-4326-in-postgis
2110+
return 32;
2111+
}
2112+
2113+
21102114
/**
21112115
* Encode array
21122116
*

src/Database/Adapter/SQL.php

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,27 @@ abstract class SQL extends Adapter
1919
{
2020
protected mixed $pdo;
2121

22+
/**
23+
* Controls how many fractional digits are used when binding float parameters.
24+
*/
25+
protected int $floatPrecision = 17;
26+
27+
/**
28+
* Configure float precision for parameter binding/logging.
29+
*/
30+
public function setFloatPrecision(int $precision): void
31+
{
32+
$this->floatPrecision = $precision;
33+
}
34+
35+
/**
36+
* Helper to format a float value according to configured precision for binding/logging.
37+
*/
38+
protected function getFloatPrecision(float $value): string
39+
{
40+
return sprintf('%.'. $this->floatPrecision . 'F', $value);
41+
}
42+
2243
/**
2344
* Constructor.
2445
*
@@ -58,7 +79,7 @@ public function startTransaction(): bool
5879
}
5980

6081
$this->inTransaction++;
61-
return $result;
82+
return true;
6283
}
6384

6485
/**
@@ -1108,11 +1129,11 @@ public function getAttributeWidth(Document $collection): int
11081129
break;
11091130

11101131
case Database::VAR_POINT:
1111-
$total += 25;
1132+
$total += $this->getMaxPointSize();
11121133
break;
11131134
case Database::VAR_LINESTRING:
11141135
case Database::VAR_POLYGON:
1115-
$total += 50;
1136+
$total += 20;
11161137
break;
11171138

11181139
default:
@@ -1702,6 +1723,12 @@ public function getMaxVarcharLength(): int
17021723
return 16381; // Floor value for Postgres:16383 | MySQL:16381 | MariaDB:16382
17031724
}
17041725

1726+
/**
1727+
* Size of POINT spatial type
1728+
*
1729+
* @return int
1730+
*/
1731+
abstract protected function getMaxPointSize(): int;
17051732
/**
17061733
* @return string
17071734
*/

src/Database/Query.php

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,6 @@ class Query
3434
public const TYPE_NOT_DISTANCE = 'notDistance';
3535
public const TYPE_DISTANCE_GREATER_THAN = 'distanceGreaterThan';
3636
public const TYPE_DISTANCE_LESS_THAN = 'distanceLessThan';
37-
public const TYPE_NOT_DISTANCE_GREATER_THAN = 'notDistanceGreaterThan';
38-
public const TYPE_NOT_DISTANCE_LESS_THAN = 'notDistanceLessThan';
3937
public const TYPE_INTERSECTS = 'intersects';
4038
public const TYPE_NOT_INTERSECTS = 'notIntersects';
4139
public const TYPE_OVERLAPS = 'overlaps';
@@ -86,8 +84,6 @@ class Query
8684
self::TYPE_NOT_DISTANCE,
8785
self::TYPE_DISTANCE_GREATER_THAN,
8886
self::TYPE_DISTANCE_LESS_THAN,
89-
self::TYPE_NOT_DISTANCE_GREATER_THAN,
90-
self::TYPE_NOT_DISTANCE_LESS_THAN,
9187
self::TYPE_INTERSECTS,
9288
self::TYPE_NOT_INTERSECTS,
9389
self::TYPE_OVERLAPS,
@@ -293,8 +289,6 @@ public function isSpatialQuery(): bool
293289
self::TYPE_NOT_DISTANCE,
294290
self::TYPE_DISTANCE_GREATER_THAN,
295291
self::TYPE_DISTANCE_LESS_THAN,
296-
self::TYPE_NOT_DISTANCE_GREATER_THAN,
297-
self::TYPE_NOT_DISTANCE_LESS_THAN,
298292
self::TYPE_INTERSECTS,
299293
self::TYPE_NOT_INTERSECTS,
300294
self::TYPE_OVERLAPS,
@@ -949,30 +943,6 @@ public static function distanceLessThan(string $attribute, array $values): self
949943
return new self(self::TYPE_DISTANCE_LESS_THAN, $attribute, $values);
950944
}
951945

952-
/**
953-
* Helper method to create Query with notDistanceGreaterThan method
954-
*
955-
* @param string $attribute
956-
* @param array<mixed> $values
957-
* @return Query
958-
*/
959-
public static function notDistanceGreaterThan(string $attribute, array $values): self
960-
{
961-
return new self(self::TYPE_NOT_DISTANCE_GREATER_THAN, $attribute, $values);
962-
}
963-
964-
/**
965-
* Helper method to create Query with notDistanceLessThan method
966-
*
967-
* @param string $attribute
968-
* @param array<mixed> $values
969-
* @return Query
970-
*/
971-
public static function notDistanceLessThan(string $attribute, array $values): self
972-
{
973-
return new self(self::TYPE_NOT_DISTANCE_LESS_THAN, $attribute, $values);
974-
}
975-
976946
/**
977947
* Helper method to create Query with intersects method
978948
*

src/Database/Validator/Queries.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,6 @@ public function isValid($value): bool
112112
Query::TYPE_NOT_DISTANCE,
113113
Query::TYPE_DISTANCE_GREATER_THAN,
114114
Query::TYPE_DISTANCE_LESS_THAN,
115-
Query::TYPE_NOT_DISTANCE_GREATER_THAN,
116-
Query::TYPE_NOT_DISTANCE_LESS_THAN,
117115
Query::TYPE_INTERSECTS,
118116
Query::TYPE_NOT_INTERSECTS,
119117
Query::TYPE_OVERLAPS,

src/Database/Validator/Query/Filter.php

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -263,8 +263,6 @@ public function isValid($value): bool
263263
case Query::TYPE_NOT_DISTANCE:
264264
case Query::TYPE_DISTANCE_GREATER_THAN:
265265
case Query::TYPE_DISTANCE_LESS_THAN:
266-
case Query::TYPE_NOT_DISTANCE_GREATER_THAN:
267-
case Query::TYPE_NOT_DISTANCE_LESS_THAN:
268266
if (count($value->getValues()) !== 1 || !is_array($value->getValues()[0]) || count($value->getValues()[0]) !== 2) {
269267
$this->message = 'Distance query requires [[geometry, distance]] parameters';
270268
return false;
@@ -320,8 +318,7 @@ public function isValid($value): bool
320318

321319
default:
322320
// Handle spatial query types and any other query types
323-
$query = new Query($method);
324-
if ($query->isSpatialQuery()) {
321+
if ($value->isSpatialQuery()) {
325322
if ($this->isEmpty($value->getValues())) {
326323
$this->message = \ucfirst($method) . ' queries require at least one value.';
327324
return false;

0 commit comments

Comments
 (0)