|
13 | 13 |
|
14 | 14 | use Clue\React\NDJson\Decoder;
|
15 | 15 | use Clue\React\NDJson\Encoder;
|
| 16 | +use Clue\React\SQLite\Io\BlockingDatabase; |
| 17 | +use Clue\React\SQLite\Result; |
16 | 18 | use React\EventLoop\Factory;
|
17 | 19 | use React\Stream\DuplexResourceStream;
|
18 | 20 | use React\Stream\ReadableResourceStream;
|
|
74 | 76 | return;
|
75 | 77 | }
|
76 | 78 |
|
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]))) { |
100 | 80 | // open database with two parameters: $filename, $flags
|
101 | 81 | try {
|
102 |
| - $db = new SQLite3( |
103 |
| - $data->params[0], |
104 |
| - $data->params[1] |
105 |
| - ); |
| 82 | + $db = new BlockingDatabase($data->params[0], $data->params[1]); |
106 | 83 |
|
107 | 84 | $out->write(array(
|
108 | 85 | 'id' => $data->id,
|
|
120 | 97 | ));
|
121 | 98 | }
|
122 | 99 | } 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) { |
127 | 102 | $out->write(array(
|
128 | 103 | 'id' => $data->id,
|
129 |
| - 'error' => array('message' => $db->lastErrorMsg()) |
| 104 | + 'result' => array( |
| 105 | + 'insertId' => $result->insertId, |
| 106 | + 'changed' => $result->changed |
| 107 | + ) |
130 | 108 | ));
|
131 |
| - } else { |
| 109 | + }, function (Exception $e) use ($data, $out) { |
132 | 110 | $out->write(array(
|
133 | 111 | 'id' => $data->id,
|
134 |
| - 'result' => array( |
135 |
| - 'insertId' => $db->lastInsertRowID(), |
136 |
| - 'changed' => $db->changes() |
137 |
| - ) |
| 112 | + 'error' => array('message' => $e->getMessage()) |
138 | 113 | ));
|
139 |
| - } |
| 114 | + }); |
140 | 115 | } 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); |
148 | 124 | } 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; |
176 | 126 | }
|
177 | 127 | }
|
178 | 128 |
|
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) { |
195 | 134 | // base64-encode any string that is not valid UTF-8 without control characters (BLOB)
|
196 | 135 | foreach ($row as &$value) {
|
197 | 136 | if (\is_string($value) && \preg_match('/[\x00-\x08\x11\x12\x14-\x1f\x7f]/u', $value) !== 0) {
|
|
202 | 141 | }
|
203 | 142 | $rows[] = $row;
|
204 | 143 | }
|
205 |
| - } else { |
206 |
| - $rows = $columns = null; |
207 | 144 | }
|
208 |
| - $result->finalize(); |
209 | 145 |
|
210 | 146 | $out->write(array(
|
211 | 147 | 'id' => $data->id,
|
212 | 148 | 'result' => array(
|
213 |
| - 'columns' => $columns, |
| 149 | + 'columns' => $result->columns, |
214 | 150 | 'rows' => $rows,
|
215 |
| - 'insertId' => $db->lastInsertRowID(), |
216 |
| - 'changed' => $db->changes() |
| 151 | + 'insertId' => $result->insertId, |
| 152 | + 'changed' => $result->changed |
217 | 153 | )
|
218 | 154 | ));
|
219 |
| - } |
| 155 | + }, function (Exception $e) use ($data, $out) { |
| 156 | + $out->write(array( |
| 157 | + 'id' => $data->id, |
| 158 | + 'error' => array('message' => $e->getMessage()) |
| 159 | + )); |
| 160 | + }); |
220 | 161 | } elseif ($data->method === 'close' && $db !== null && \count($data->params) === 0) {
|
221 | 162 | // close database and remove reference
|
222 | 163 | $db->close();
|
|
0 commit comments