|
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