From ea1903089a1511ff3f6b0baec544f51633f5a1cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C4=9Bj=20Km=C3=ADnek?= Date: Thu, 4 Jun 2026 13:09:18 +0200 Subject: [PATCH 1/3] Properly return number of inserted rows during performing multi-insert instead of ActiveRow instance --- src/Database/Table/Selection.php | 2 +- .../Database/Explorer/Selection.insert().multi.phpt | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/Database/Table/Selection.php b/src/Database/Table/Selection.php index 05bdb49c4..27340c829 100644 --- a/src/Database/Table/Selection.php +++ b/src/Database/Table/Selection.php @@ -791,7 +791,7 @@ public function insert(iterable $data): ActiveRow|array|int $this->loadRefCache(); - if ($data instanceof self || $this->primary === null) { + if ($data instanceof self || $this->primary === null || (is_array($data) && array_key_exists(0, $data))) { unset($this->refCache['referencing'][$this->getGeneralCacheKey()][$this->getSpecificCacheKey()]); return $return->getRowCount() ?? throw new Nette\InvalidStateException('Cannot determine the number of affected rows.'); diff --git a/tests/Database/Explorer/Selection.insert().multi.phpt b/tests/Database/Explorer/Selection.insert().multi.phpt index 638783318..656609e13 100644 --- a/tests/Database/Explorer/Selection.insert().multi.phpt +++ b/tests/Database/Explorer/Selection.insert().multi.phpt @@ -14,9 +14,9 @@ $explorer = connectToDB(); Nette\Database\Helpers::loadFromFile($explorer, __DIR__ . "/../files/{$driverName}-nette_test1.sql"); -test('', function () use ($explorer) { +test('multi-insert on autoincrement table returns int row count', function () use ($explorer) { Assert::same(3, $explorer->table('author')->count()); - $explorer->table('author')->insert([ + $result = $explorer->table('author')->insert([ [ 'name' => 'Catelyn Stark', 'web' => 'http://example.com', @@ -28,15 +28,21 @@ test('', function () use ($explorer) { 'born' => new DateTime('2021-11-11'), ], ]); // INSERT INTO `author` (`name`, `web`, `born`) VALUES ('Catelyn Stark', 'http://example.com', '2011-11-11 00:00:00'), ('Sansa Stark', 'http://example.com', '2021-11-11 00:00:00') + Assert::type('int', $result); + Assert::same(2, $result); Assert::same(5, $explorer->table('author')->count()); +}); +test('multi-insert on composite primary key table returns int row count', function () use ($explorer) { $explorer->table('book_tag')->where('book_id', 1)->delete(); // DELETE FROM `book_tag` WHERE (`book_id` = ?) Assert::same(4, $explorer->table('book_tag')->count()); - $explorer->table('book')->get(1)->related('book_tag')->insert([ // SELECT * FROM `book` WHERE (`id` = ?) + $result = $explorer->table('book')->get(1)->related('book_tag')->insert([ // SELECT * FROM `book` WHERE (`id` = ?) ['tag_id' => 21], ['tag_id' => 22], ['tag_id' => 23], ]); // INSERT INTO `book_tag` (`tag_id`, `book_id`) VALUES (21, 1), (22, 1), (23, 1) + Assert::type('int', $result); + Assert::same(3, $result); Assert::same(7, $explorer->table('book_tag')->count()); }); From 7efd43e31a535d140b086c1c2af39c19f6d1b449 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C4=9Bj=20Km=C3=ADnek?= Date: Thu, 4 Jun 2026 13:16:42 +0200 Subject: [PATCH 2/3] Use array_is_list instead of old style approach as that is way sexier --- src/Database/Table/Selection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Database/Table/Selection.php b/src/Database/Table/Selection.php index 27340c829..bf2cba446 100644 --- a/src/Database/Table/Selection.php +++ b/src/Database/Table/Selection.php @@ -791,7 +791,7 @@ public function insert(iterable $data): ActiveRow|array|int $this->loadRefCache(); - if ($data instanceof self || $this->primary === null || (is_array($data) && array_key_exists(0, $data))) { + if ($data instanceof self || $this->primary === null || array_is_list($data)) { unset($this->refCache['referencing'][$this->getGeneralCacheKey()][$this->getSpecificCacheKey()]); return $return->getRowCount() ?? throw new Nette\InvalidStateException('Cannot determine the number of affected rows.'); From c826700e87d7f16c1049f4a0d85e8d2808fcc7c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C4=9Bj=20Km=C3=ADnek?= Date: Thu, 4 Jun 2026 13:27:02 +0200 Subject: [PATCH 3/3] Avoid separation of test into two tests - keep only one just original does --- tests/Database/Explorer/Selection.insert().multi.phpt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/Database/Explorer/Selection.insert().multi.phpt b/tests/Database/Explorer/Selection.insert().multi.phpt index 656609e13..f868eac4a 100644 --- a/tests/Database/Explorer/Selection.insert().multi.phpt +++ b/tests/Database/Explorer/Selection.insert().multi.phpt @@ -14,7 +14,7 @@ $explorer = connectToDB(); Nette\Database\Helpers::loadFromFile($explorer, __DIR__ . "/../files/{$driverName}-nette_test1.sql"); -test('multi-insert on autoincrement table returns int row count', function () use ($explorer) { +test('', function () use ($explorer) { Assert::same(3, $explorer->table('author')->count()); $result = $explorer->table('author')->insert([ [ @@ -31,9 +31,7 @@ test('multi-insert on autoincrement table returns int row count', function () us Assert::type('int', $result); Assert::same(2, $result); Assert::same(5, $explorer->table('author')->count()); -}); -test('multi-insert on composite primary key table returns int row count', function () use ($explorer) { $explorer->table('book_tag')->where('book_id', 1)->delete(); // DELETE FROM `book_tag` WHERE (`book_id` = ?) Assert::same(4, $explorer->table('book_tag')->count());