From e7330d792e0faed17cf9e02981c519324e71a15a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20Mat=C4=9Bj=C4=8Dek?= Date: Thu, 29 Jun 2017 16:14:37 +0200 Subject: [PATCH] SqlPreprocessor: throw exception if mode does not respond values --- src/Database/SqlPreprocessor.php | 8 +++++++- tests/Database/SqlPreprocessor.phpt | 7 +++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/Database/SqlPreprocessor.php b/src/Database/SqlPreprocessor.php index 7156cd322..616c9452d 100644 --- a/src/Database/SqlPreprocessor.php +++ b/src/Database/SqlPreprocessor.php @@ -19,6 +19,9 @@ class SqlPreprocessor { use Nette\SmartObject; + /** @var array */ + private const MODE_LIST = ['and', 'or', 'set', 'values', 'order']; + /** @var Connection */ private $connection; @@ -162,6 +165,9 @@ private function formatValue($value, $mode = NULL) if ($mode === 'values') { // (key, key, ...) VALUES (value, value, ...) if (array_key_exists(0, $value)) { // multi-insert + if (!is_array($value[0])) { + throw new Nette\InvalidArgumentException('Automaticaly detected multi-insert, but values aren\'t array. If you need try to change mode like "?[' . implode('|', self::MODE_LIST) . ']". Mode "' . $mode . '" was used.'); + } foreach ($value[0] as $k => $v) { $kx[] = $this->delimite($k); } @@ -228,7 +234,7 @@ private function formatValue($value, $mode = NULL) throw new Nette\InvalidArgumentException("Unknown placeholder ?$mode."); } - } elseif (in_array($mode, ['and', 'or', 'set', 'values', 'order'], TRUE)) { + } elseif (in_array($mode, self::MODE_LIST, TRUE)) { $type = gettype($value); throw new Nette\InvalidArgumentException("Placeholder ?$mode expects array or Traversable object, $type given."); diff --git a/tests/Database/SqlPreprocessor.phpt b/tests/Database/SqlPreprocessor.phpt index 747e8d268..263fe54be 100644 --- a/tests/Database/SqlPreprocessor.phpt +++ b/tests/Database/SqlPreprocessor.phpt @@ -324,6 +324,13 @@ test(function () use ($preprocessor) { // ?values }); +test(function () use ($preprocessor) { // automatic detection faild + Assert::exception(function () use ($preprocessor) { + $preprocessor->process(['INSERT INTO author (name) SELECT name FROM user WHERE id IN (?)', [11, 12]]); + }, Nette\InvalidArgumentException::class, 'Automaticaly detected multi-insert, but values aren\'t array. If you need try to change mode like "?[and|or|set|values|order]". Mode "values" was used.'); +}); + + test(function () use ($preprocessor) { // multi insert [$sql, $params] = $preprocessor->process(['INSERT INTO author', [ ['name' => 'Catelyn Stark', 'born' => new DateTime('2011-11-11')],