Skip to content

Commit 80e5d7e

Browse files
committed
Refactor to use BlockingDatabase adapter internally for child process
1 parent a855ad7 commit 80e5d7e

File tree

2 files changed

+38
-103
lines changed

2 files changed

+38
-103
lines changed

res/sqlite-worker.php

Lines changed: 36 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313

1414
use Clue\React\NDJson\Decoder;
1515
use Clue\React\NDJson\Encoder;
16+
use Clue\React\SQLite\Io\BlockingDatabase;
17+
use Clue\React\SQLite\Result;
1618
use React\EventLoop\Factory;
1719
use React\Stream\DuplexResourceStream;
1820
use React\Stream\ReadableResourceStream;
@@ -74,35 +76,10 @@
7476
return;
7577
}
7678

77-
if ($data->method === 'open' && \count($data->params) === 1 && \is_string($data->params[0])) {
78-
// open database with one parameter: $filename
79-
try {
80-
$db = new SQLite3(
81-
$data->params[0]
82-
);
83-
84-
$out->write(array(
85-
'id' => $data->id,
86-
'result' => true
87-
));
88-
} catch (Exception $e) {
89-
$out->write(array(
90-
'id' => $data->id,
91-
'error' => array('message' => $e->getMessage())
92-
));
93-
} catch (Error $e) {
94-
$out->write(array(
95-
'id' => $data->id,
96-
'error' => array('message' => $e->getMessage())
97-
));
98-
}
99-
} elseif ($data->method === 'open' && \count($data->params) === 2 && \is_string($data->params[0]) && \is_int($data->params[1])) {
79+
if ($data->method === 'open' && \count($data->params) === 2 && \is_string($data->params[0]) && ($data->params[1] === null || \is_int($data->params[1]))) {
10080
// open database with two parameters: $filename, $flags
10181
try {
102-
$db = new SQLite3(
103-
$data->params[0],
104-
$data->params[1]
105-
);
82+
$db = new BlockingDatabase($data->params[0], $data->params[1]);
10683

10784
$out->write(array(
10885
'id' => $data->id,
@@ -120,78 +97,40 @@
12097
));
12198
}
12299
} elseif ($data->method === 'exec' && $db !== null && \count($data->params) === 1 && \is_string($data->params[0])) {
123-
// execute statement and suppress PHP warnings
124-
$ret = @$db->exec($data->params[0]);
125-
126-
if ($ret === false) {
100+
// execute statement: $db->exec($sql)
101+
$db->exec($data->params[0])->then(function (Result $result) use ($data, $out) {
127102
$out->write(array(
128103
'id' => $data->id,
129-
'error' => array('message' => $db->lastErrorMsg())
104+
'result' => array(
105+
'insertId' => $result->insertId,
106+
'changed' => $result->changed
107+
)
130108
));
131-
} else {
109+
}, function (Exception $e) use ($data, $out) {
132110
$out->write(array(
133111
'id' => $data->id,
134-
'result' => array(
135-
'insertId' => $db->lastInsertRowID(),
136-
'changed' => $db->changes()
137-
)
112+
'error' => array('message' => $e->getMessage())
138113
));
139-
}
114+
});
140115
} elseif ($data->method === 'query' && $db !== null && \count($data->params) === 2 && \is_string($data->params[0]) && (\is_array($data->params[1]) || \is_object($data->params[1]))) {
141-
// execute statement and suppress PHP warnings
142-
if ($data->params[1] === []) {
143-
$result = @$db->query($data->params[0]);
144-
} else {
145-
$statement = @$db->prepare($data->params[0]);
146-
if ($statement === false) {
147-
$result = false;
116+
// execute statement: $db->query($sql, $params)
117+
$params = [];
118+
foreach ($data->params[1] as $index => $value) {
119+
if (isset($value->float)) {
120+
$params[$index] = (float)$value->float;
121+
} elseif (isset($value->base64)) {
122+
// base64-decode string parameters as BLOB
123+
$params[$index] = \base64_decode($value->base64);
148124
} else {
149-
foreach ($data->params[1] as $index => $value) {
150-
if ($value === null) {
151-
$type = \SQLITE3_NULL;
152-
} elseif ($value === true || $value === false) {
153-
// explicitly cast bool to int because SQLite does not have a native boolean
154-
$type = \SQLITE3_INTEGER;
155-
$value = (int)$value;
156-
} elseif (\is_int($value)) {
157-
$type = \SQLITE3_INTEGER;
158-
} elseif (isset($value->float)) {
159-
$type = \SQLITE3_FLOAT;
160-
$value = (float)$value->float;
161-
} elseif (isset($value->base64)) {
162-
// base64-decode string parameters as BLOB
163-
$type = \SQLITE3_BLOB;
164-
$value = \base64_decode($value->base64);
165-
} else {
166-
$type = \SQLITE3_TEXT;
167-
}
168-
169-
$statement->bindValue(
170-
\is_int($index) ? $index + 1 : $index,
171-
$value,
172-
$type
173-
);
174-
}
175-
$result = @$statement->execute();
125+
$params[$index] = $value;
176126
}
177127
}
178128

179-
if ($result === false) {
180-
$out->write(array(
181-
'id' => $data->id,
182-
'error' => array('message' => $db->lastErrorMsg())
183-
));
184-
} else {
185-
if ($result->numColumns() !== 0) {
186-
// Fetch all rows only if this result set has any columns.
187-
// INSERT/UPDATE/DELETE etc. do not return any columns, trying
188-
// to fetch the results here will issue the same query again.
189-
$rows = $columns = [];
190-
for ($i = 0, $n = $result->numColumns(); $i < $n; ++$i) {
191-
$columns[] = $result->columnName($i);
192-
}
193-
194-
while (($row = $result->fetchArray(\SQLITE3_ASSOC)) !== false) {
129+
$db->query($data->params[0], $params)->then(function (Result $result) use ($data, $out) {
130+
$rows = null;
131+
if ($result->rows !== null) {
132+
$rows = [];
133+
foreach ($result->rows as $row) {
195134
// base64-encode any string that is not valid UTF-8 without control characters (BLOB)
196135
foreach ($row as &$value) {
197136
if (\is_string($value) && \preg_match('/[\x00-\x08\x11\x12\x14-\x1f\x7f]/u', $value) !== 0) {
@@ -202,21 +141,23 @@
202141
}
203142
$rows[] = $row;
204143
}
205-
} else {
206-
$rows = $columns = null;
207144
}
208-
$result->finalize();
209145

210146
$out->write(array(
211147
'id' => $data->id,
212148
'result' => array(
213-
'columns' => $columns,
149+
'columns' => $result->columns,
214150
'rows' => $rows,
215-
'insertId' => $db->lastInsertRowID(),
216-
'changed' => $db->changes()
151+
'insertId' => $result->insertId,
152+
'changed' => $result->changed
217153
)
218154
));
219-
}
155+
}, function (Exception $e) use ($data, $out) {
156+
$out->write(array(
157+
'id' => $data->id,
158+
'error' => array('message' => $e->getMessage())
159+
));
160+
});
220161
} elseif ($data->method === 'close' && $db !== null && \count($data->params) === 0) {
221162
// close database and remove reference
222163
$db->close();

src/Factory.php

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -248,10 +248,7 @@ private function openProcessIo($filename, $flags = null)
248248
$process->start($this->loop);
249249

250250
$db = new ProcessIoDatabase($process);
251-
$args = array($filename);
252-
if ($flags !== null) {
253-
$args[] = $flags;
254-
}
251+
$args = array($filename, $flags);
255252

256253
return $db->send('open', $args)->then(function () use ($db) {
257254
return $db;
@@ -333,10 +330,7 @@ private function openSocketIo($filename, $flags = null)
333330
});
334331

335332
$db = new ProcessIoDatabase($process);
336-
$args = array($filename);
337-
if ($flags !== null) {
338-
$args[] = $flags;
339-
}
333+
$args = array($filename, $flags);
340334

341335
$db->send('open', $args)->then(function () use ($deferred, $db) {
342336
$deferred->resolve($db);

0 commit comments

Comments
 (0)