From 70ff49dfc4fe16e0008dd953d862af525909e284 Mon Sep 17 00:00:00 2001 From: Ryan Cramer Date: Fri, 10 Sep 2021 08:57:09 -0400 Subject: [PATCH] Update WireDatabasePDO::pdoType() to fix issue in reader/writer detection when query had leading whitespace or newlines in unexpected locations --- wire/core/WireDatabasePDO.php | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/wire/core/WireDatabasePDO.php b/wire/core/WireDatabasePDO.php index c400d759..d8d53dbf 100644 --- a/wire/core/WireDatabasePDO.php +++ b/wire/core/WireDatabasePDO.php @@ -526,31 +526,36 @@ class WireDatabasePDO extends Wire implements WireDatabase { /** * Return correct PDO instance type (reader or writer) based on given statement * - * @param string|\PDOStatement $statement + * @param string|\PDOStatement $query * @param bool $getName Get name of PDO type rather than instance? (default=false) * @return \PDO|string * */ - protected function pdoType(&$statement, $getName = false) { + protected function pdoType(&$query, $getName = false) { $reader = 'reader'; $writer = 'writer'; - if(!$this->reader['has']) return $getName ? $writer : $this->pdoWriter(); + if(!$this->reader['has'] || !is_string($query)) { + // no reader available or query is PDOStatement, or other: always return writer + // todo support for inspecting PDOStatement? + return $getName ? $writer : $this->pdoWriter(); + } + + // statement is just first 40 characters of query + $statement = trim(str_replace(array("\n", "\t", "\r"), " ", substr($query, 0, 40))); if($statement === $writer || $statement === $reader) { + // reader or writer requested by name $type = $statement; - } else if(!$this->reader['has']) { - $type = $writer; - } else if(!is_string($statement)) { - // PDOStatement or other, always return write - // @todo add support for inspection of PDOStatement - $type = $writer; } else if(stripos($statement, 'select') === 0) { + // select query is always reader $type = $reader; } else if(stripos($statement, 'insert') === 0) { + // insert query is always writer $type = $writer; } else { + // other query to inspect further $pos = strpos($statement, ' '); $word = strtolower(($pos ? substr($statement, 0, $pos) : $statement)); if($word === 'set') {