diff --git a/res/sqlite-worker.php b/res/sqlite-worker.php index bc585b5..68c3827 100644 --- a/res/sqlite-worker.php +++ b/res/sqlite-worker.php @@ -174,16 +174,21 @@ } $rows = array(); - while (($row = $result->fetchArray(\SQLITE3_ASSOC)) !== false) { - // base64-encode any string that is not valid UTF-8 without control characters (BLOB) - foreach ($row as &$value) { - if (\is_string($value) && \preg_match('/[\x00-\x08\x11\x12\x14-\x1f\x7f]/u', $value) !== 0) { - $value = ['base64' => \base64_encode($value)]; - } elseif (\is_float($value)) { - $value = ['float' => $value]; + if ($result->numColumns() !== 0) { + // Fetch all rows only if this result set has any columns. + // INSERT/UPDATE/DELETE etc. do not return any columns, trying + // to fetch the results here will issue the same query again. + while (($row = $result->fetchArray(\SQLITE3_ASSOC)) !== false) { + // base64-encode any string that is not valid UTF-8 without control characters (BLOB) + foreach ($row as &$value) { + if (\is_string($value) && \preg_match('/[\x00-\x08\x11\x12\x14-\x1f\x7f]/u', $value) !== 0) { + $value = ['base64' => \base64_encode($value)]; + } elseif (\is_float($value)) { + $value = ['float' => $value]; + } } + $rows[] = $row; } - $rows[] = $row; } $result->finalize(); diff --git a/tests/FunctionalDatabaseTest.php b/tests/FunctionalDatabaseTest.php index 451a670..95a4ad4 100644 --- a/tests/FunctionalDatabaseTest.php +++ b/tests/FunctionalDatabaseTest.php @@ -596,6 +596,36 @@ public function testExecRejectsWhenAlreadyClosed($flag) $loop->run(); } + /** + * @dataProvider provideSocketFlags + * @param bool $flag + */ + public function testQueryInsertResolvesWithResultWithLastInsertIdAndRunsUntilQuit($flag) + { + $loop = React\EventLoop\Factory::create(); + $factory = new Factory($loop); + + $ref = new ReflectionProperty($factory, 'useSocket'); + $ref->setAccessible(true); + $ref->setValue($factory, $flag); + + $promise = $factory->open(':memory:'); + + $data = null; + $promise->then(function (DatabaseInterface $db) use (&$data){ + $db->exec('CREATE TABLE foo (id INTEGER PRIMARY KEY AUTOINCREMENT, bar STRING)'); + $db->query('INSERT INTO foo (bar) VALUES (?)', ['test'])->then(function (Result $result) use (&$data) { + $data = $result->insertId; + }); + + $db->quit(); + }); + + $loop->run(); + + $this->assertSame(1, $data); + } + protected function expectCallableNever() { $mock = $this->createCallableMock();