Skip to content

Commit f2c738c

Browse files
authored
Merge pull request #20 from clue-labs/query-insert
Fix selecting empty result sets and avoid implicitly executing twice
2 parents f569fe3 + 39ca1c9 commit f2c738c

File tree

2 files changed

+43
-8
lines changed

2 files changed

+43
-8
lines changed

res/sqlite-worker.php

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -174,16 +174,21 @@
174174
}
175175

176176
$rows = array();
177-
while (($row = $result->fetchArray(\SQLITE3_ASSOC)) !== false) {
178-
// base64-encode any string that is not valid UTF-8 without control characters (BLOB)
179-
foreach ($row as &$value) {
180-
if (\is_string($value) && \preg_match('/[\x00-\x08\x11\x12\x14-\x1f\x7f]/u', $value) !== 0) {
181-
$value = ['base64' => \base64_encode($value)];
182-
} elseif (\is_float($value)) {
183-
$value = ['float' => $value];
177+
if ($result->numColumns() !== 0) {
178+
// Fetch all rows only if this result set has any columns.
179+
// INSERT/UPDATE/DELETE etc. do not return any columns, trying
180+
// to fetch the results here will issue the same query again.
181+
while (($row = $result->fetchArray(\SQLITE3_ASSOC)) !== false) {
182+
// base64-encode any string that is not valid UTF-8 without control characters (BLOB)
183+
foreach ($row as &$value) {
184+
if (\is_string($value) && \preg_match('/[\x00-\x08\x11\x12\x14-\x1f\x7f]/u', $value) !== 0) {
185+
$value = ['base64' => \base64_encode($value)];
186+
} elseif (\is_float($value)) {
187+
$value = ['float' => $value];
188+
}
184189
}
190+
$rows[] = $row;
185191
}
186-
$rows[] = $row;
187192
}
188193
$result->finalize();
189194

tests/FunctionalDatabaseTest.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,36 @@ public function testExecRejectsWhenAlreadyClosed($flag)
596596
$loop->run();
597597
}
598598

599+
/**
600+
* @dataProvider provideSocketFlags
601+
* @param bool $flag
602+
*/
603+
public function testQueryInsertResolvesWithResultWithLastInsertIdAndRunsUntilQuit($flag)
604+
{
605+
$loop = React\EventLoop\Factory::create();
606+
$factory = new Factory($loop);
607+
608+
$ref = new ReflectionProperty($factory, 'useSocket');
609+
$ref->setAccessible(true);
610+
$ref->setValue($factory, $flag);
611+
612+
$promise = $factory->open(':memory:');
613+
614+
$data = null;
615+
$promise->then(function (DatabaseInterface $db) use (&$data){
616+
$db->exec('CREATE TABLE foo (id INTEGER PRIMARY KEY AUTOINCREMENT, bar STRING)');
617+
$db->query('INSERT INTO foo (bar) VALUES (?)', ['test'])->then(function (Result $result) use (&$data) {
618+
$data = $result->insertId;
619+
});
620+
621+
$db->quit();
622+
});
623+
624+
$loop->run();
625+
626+
$this->assertSame(1, $data);
627+
}
628+
599629
protected function expectCallableNever()
600630
{
601631
$mock = $this->createCallableMock();

0 commit comments

Comments
 (0)