From c41fe96cd896684152cbe626234afef8ed62fd13 Mon Sep 17 00:00:00 2001 From: Michael Calcinai Date: Fri, 9 Aug 2024 15:35:58 +1200 Subject: [PATCH 1/2] Support geometry columns via brick/geo --- composer.json | 3 ++- src/Wave/DB.php | 35 ++++++++++++++++++++++++--- src/Wave/DB/Column.php | 1 + src/Wave/DB/Driver/AbstractDriver.php | 6 +++++ src/Wave/DB/Driver/MySQL.php | 3 +++ src/Wave/DB/Driver/PostgreSQL.php | 3 +++ 6 files changed, 46 insertions(+), 5 deletions(-) diff --git a/composer.json b/composer.json index 8277c40..06b00e7 100644 --- a/composer.json +++ b/composer.json @@ -30,7 +30,8 @@ "php": ">=8.1", "twig/twig": "3.*", "monolog/monolog": "2.*", - "dragonmantank/cron-expression": "^3.3" + "dragonmantank/cron-expression": "^3.3", + "brick/geo": "^0.11.0" }, "require-dev": { diff --git a/src/Wave/DB.php b/src/Wave/DB.php index c1ae673..09ec7cd 100755 --- a/src/Wave/DB.php +++ b/src/Wave/DB.php @@ -468,10 +468,21 @@ public static function insert(Model &$object) { ); try { - $connection->prepare($sql)->execute($params); + $statement = $connection->prepare($sql); + foreach($params as $name => $param){ + if(is_array($param)){ + $statement->bindParam($name+1, ...$param); + } else { + $statement->bindParam($name+1, $param); + } + } + + $statement->execute(); } catch (\PDOException $e){ throw $connection->getDriverClass()::convertException($e); } + + $primary_key = $object::_getPrimaryKey(); if($primary_key !== null && count($primary_key) === 1) { $column = current($primary_key); @@ -518,9 +529,17 @@ public static function update(Model &$object) { implode(',', $updates), implode(' AND ', $criteria) ); - $connection->prepare($sql)->execute($params); - return true; + $statement = $connection->prepare($sql); + foreach($params as $name => $param){ + if(is_array($param)){ + $statement->bindParam($name+1, ...$param); + } else { + $statement->bindParam($name+1, $param); + } + } + + return $statement->execute(); } /** @@ -549,8 +568,16 @@ public static function delete(Model &$object) { $database->escape($object::_getTableName()), implode(' AND ', $criteria) ); - $connection->prepare($sql)->execute($params); + $statement = $connection->prepare($sql); + foreach($params as $name => $param){ + if(is_array($param)){ + $statement->bindParam($name+1, ...$param); + } else { + $statement->bindParam($name+1, $param); + } + } + $statement->execute(); $object->_setLoaded(false); return true; diff --git a/src/Wave/DB/Column.php b/src/Wave/DB/Column.php index f344a31..1cfa159 100644 --- a/src/Wave/DB/Column.php +++ b/src/Wave/DB/Column.php @@ -21,6 +21,7 @@ class Column { const TYPE_FLOAT = 5; const TYPE_DATE = 6; const TYPE_JSON = 7; + const TYPE_GEOMETRY = 8; /** @var Table $table */ private $table; diff --git a/src/Wave/DB/Driver/AbstractDriver.php b/src/Wave/DB/Driver/AbstractDriver.php index 3611eb9..6f213d0 100755 --- a/src/Wave/DB/Driver/AbstractDriver.php +++ b/src/Wave/DB/Driver/AbstractDriver.php @@ -2,6 +2,7 @@ namespace Wave\DB\Driver; +use Brick\Geo\Geometry; use Wave\DB\Column; abstract class AbstractDriver @@ -14,6 +15,8 @@ public static function valueToSQL($value) return $value ? 1 : 0; case $value instanceof \DateTimeInterface: return $value->format('Y-m-d H:i:s'); + case $value instanceof Geometry: + return [$value->asBinary(), \PDO::PARAM_LOB]; case is_object($value) || is_array($value): return json_encode($value); @@ -49,6 +52,9 @@ public static function valueFromSQL($value, array $field_data) case Column::TYPE_JSON: return json_decode($value); + case Column::TYPE_GEOMETRY: + return Geometry::fromBinary($value); + case Column::TYPE_DATE: case Column::TYPE_TIMESTAMP: if ($value == 'CURRENT_TIMESTAMP') { diff --git a/src/Wave/DB/Driver/MySQL.php b/src/Wave/DB/Driver/MySQL.php index eea0320..b3e0fe0 100755 --- a/src/Wave/DB/Driver/MySQL.php +++ b/src/Wave/DB/Driver/MySQL.php @@ -259,6 +259,9 @@ public static function translateSQLDataType($type) case 'json' : return DB\Column::TYPE_JSON; + case 'geometry' : + return DB\Column::TYPE_GEOMETRY; + default: return DB\Column::TYPE_UNKNOWN; } diff --git a/src/Wave/DB/Driver/PostgreSQL.php b/src/Wave/DB/Driver/PostgreSQL.php index 1975b29..5d19213 100644 --- a/src/Wave/DB/Driver/PostgreSQL.php +++ b/src/Wave/DB/Driver/PostgreSQL.php @@ -279,6 +279,9 @@ public static function translateSQLDataType($type) case 'json' : return DB\Column::TYPE_JSON; + case 'geometry' : + return DB\Column::TYPE_GEOMETRY; + default: return DB\Column::TYPE_UNKNOWN; } From 03555f9b6745a1d6ecb90fce0a4f1f3094b44f6b Mon Sep 17 00:00:00 2001 From: Patrick Hindmarsh Date: Mon, 23 Sep 2024 15:49:00 +1200 Subject: [PATCH 2/2] Update DB.php Can't use `bindParam` here because its by reference, and in the context of the loop every bound parameter has the value of whatever the last parameter in the loop was. `bindValue` is not by reference, and still allows the type to be set separately. --- src/Wave/DB.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Wave/DB.php b/src/Wave/DB.php index 09ec7cd..c7c518f 100755 --- a/src/Wave/DB.php +++ b/src/Wave/DB.php @@ -471,9 +471,9 @@ public static function insert(Model &$object) { $statement = $connection->prepare($sql); foreach($params as $name => $param){ if(is_array($param)){ - $statement->bindParam($name+1, ...$param); + $statement->bindValue($name+1, ...$param); } else { - $statement->bindParam($name+1, $param); + $statement->bindValue($name+1, $param); } } @@ -533,9 +533,9 @@ public static function update(Model &$object) { $statement = $connection->prepare($sql); foreach($params as $name => $param){ if(is_array($param)){ - $statement->bindParam($name+1, ...$param); + $statement->bindValue($name+1, ...$param); } else { - $statement->bindParam($name+1, $param); + $statement->bindValue($name+1, $param); } } @@ -572,9 +572,9 @@ public static function delete(Model &$object) { $statement = $connection->prepare($sql); foreach($params as $name => $param){ if(is_array($param)){ - $statement->bindParam($name+1, ...$param); + $statement->bindValue($name+1, ...$param); } else { - $statement->bindParam($name+1, $param); + $statement->bindValue($name+1, $param); } } $statement->execute(); @@ -584,4 +584,4 @@ public static function delete(Model &$object) { } -} \ No newline at end of file +}