From 3c270707ae824f26e8f2e76c5b6df1d1185acd28 Mon Sep 17 00:00:00 2001 From: Greg Bowler Date: Sat, 10 Feb 2024 18:09:59 +0000 Subject: [PATCH] feature: improve error handling of special binding including infiles --- src/Connection/Driver.php | 3 ++- src/Query/SqlQuery.php | 54 +++++++++++++++++++++++---------------- 2 files changed, 34 insertions(+), 23 deletions(-) diff --git a/src/Connection/Driver.php b/src/Connection/Driver.php index d59f00a..e7665ec 100644 --- a/src/Connection/Driver.php +++ b/src/Connection/Driver.php @@ -45,11 +45,12 @@ protected function connect():void { Connection::ATTR_ERRMODE => Connection::ERRMODE_EXCEPTION, ]; - if($this->settings->getSchema() === Settings::DRIVER_MYSQL) { + if($this->settings->getDriver() === Settings::DRIVER_MYSQL) { $options[Connection::MYSQL_ATTR_INIT_COMMAND] = "SET SESSION collation_connection='" . $this->settings->getCollation() . "'"; + $options[Connection::MYSQL_ATTR_LOCAL_INFILE] = true; } $this->connection = new Connection( diff --git a/src/Query/SqlQuery.php b/src/Query/SqlQuery.php index f407f1e..573416b 100644 --- a/src/Query/SqlQuery.php +++ b/src/Query/SqlQuery.php @@ -12,10 +12,9 @@ /** @SuppressWarnings(PHPMD.ExcessiveClassComplexity) */ class SqlQuery extends Query { const SPECIAL_BINDINGS = [ - "limit", - "offset", - "groupBy", - "orderBy", + "field" => ["groupBy", "orderBy"], + "int" => ["limit", "offset"], + "string" => ["infileName"], ]; /** @param array|array $bindings */ @@ -71,10 +70,10 @@ public function execute(array $bindings = []):ResultSet { $lastInsertId = $pdo->lastInsertId(); } catch(PDOException $exception) { - $code = $exception->getCode(); throw new PreparedStatementException( - $exception->getMessage() . " (Code $code)", - previous: $exception + $exception->getMessage() . " (" . $exception->getCode(), + 0, + $exception ); } } @@ -108,24 +107,35 @@ public function injectSpecialBindings( string $sql, array $bindings ):string { - foreach(self::SPECIAL_BINDINGS as $special) { - $specialPlaceholder = ":" . $special; + foreach(self::SPECIAL_BINDINGS as $type => $specialList) { + foreach($specialList as $special) { + $specialPlaceholder = ":" . $special; - if(!array_key_exists($special, $bindings)) { - continue; - } + if(!array_key_exists($special, $bindings)) { + continue; + } - $replacement = $this->escapeSpecialBinding( - $bindings[$special], - $special - ); + if($type !== "string") { + $replacement = $this->escapeSpecialBinding( + $bindings[$special], + $special + ); + } - $sql = str_replace( - $specialPlaceholder, - $replacement, - $sql - ); - unset($bindings[$special]); + if($type === "field") { + $replacement = "`" . $bindings[$special] . "`"; + } + elseif($type === "string") { + $replacement = "'" . $bindings[$special] . "'"; + } + + $sql = str_replace( + $specialPlaceholder, + $replacement, + $sql + ); + unset($bindings[$special]); + } } foreach($bindings as $key => $value) {