1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 7 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2018 The PHP Group |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
15 | Author: Wez Furlong <wez@php.net> |
16 +----------------------------------------------------------------------+
17 */
18
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22
23 #include "php.h"
24 #include "php_ini.h"
25 #include "ext/standard/info.h"
26 #include "pdo/php_pdo.h"
27 #include "pdo/php_pdo_driver.h"
28 #include "php_pdo_sqlite.h"
29 #include "php_pdo_sqlite_int.h"
30
31
pdo_sqlite_stmt_dtor(pdo_stmt_t * stmt)32 static int pdo_sqlite_stmt_dtor(pdo_stmt_t *stmt)
33 {
34 pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
35
36 if (S->stmt) {
37 sqlite3_finalize(S->stmt);
38 S->stmt = NULL;
39 }
40 efree(S);
41 return 1;
42 }
43
44 /**
45 * Change the column count on the statement.
46 *
47 * Since PHP 7.2 sqlite3_prepare_v2 is used which auto recompile prepared statement on schema change.
48 * Instead of raise an error on schema change, the result set will change, and the statement's columns must be updated.
49 *
50 * See bug #78192
51 */
pdo_sqlite_stmt_set_column_count(pdo_stmt_t * stmt,int new_count)52 static void pdo_sqlite_stmt_set_column_count(pdo_stmt_t *stmt, int new_count)
53 {
54 /* Columns not yet "described" */
55 if (!stmt->columns) {
56 stmt->column_count = new_count;
57
58 return;
59 }
60
61 /*
62 * The column count has not changed : no need to reload columns description
63 * Note: Do not handle attribute name change, without column count change
64 */
65 if (new_count == stmt->column_count) {
66 return;
67 }
68
69 /* Free previous columns to force reload description */
70 int i;
71
72 for (i = 0; i < stmt->column_count; i++) {
73 if (stmt->columns[i].name) {
74 zend_string_release(stmt->columns[i].name);
75 stmt->columns[i].name = NULL;
76 }
77 }
78
79 efree(stmt->columns);
80 stmt->columns = NULL;
81 stmt->column_count = new_count;
82 }
83
pdo_sqlite_stmt_execute(pdo_stmt_t * stmt)84 static int pdo_sqlite_stmt_execute(pdo_stmt_t *stmt)
85 {
86 pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
87
88 if (stmt->executed && !S->done) {
89 sqlite3_reset(S->stmt);
90 }
91
92 S->done = 0;
93 switch (sqlite3_step(S->stmt)) {
94 case SQLITE_ROW:
95 S->pre_fetched = 1;
96 pdo_sqlite_stmt_set_column_count(stmt, sqlite3_data_count(S->stmt));
97 return 1;
98
99 case SQLITE_DONE:
100 pdo_sqlite_stmt_set_column_count(stmt, sqlite3_column_count(S->stmt));
101 stmt->row_count = sqlite3_changes(S->H->db);
102 sqlite3_reset(S->stmt);
103 S->done = 1;
104 return 1;
105
106 case SQLITE_ERROR:
107 sqlite3_reset(S->stmt);
108 case SQLITE_MISUSE:
109 case SQLITE_BUSY:
110 default:
111 pdo_sqlite_error_stmt(stmt);
112 return 0;
113 }
114 }
115
pdo_sqlite_stmt_param_hook(pdo_stmt_t * stmt,struct pdo_bound_param_data * param,enum pdo_param_event event_type)116 static int pdo_sqlite_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param,
117 enum pdo_param_event event_type)
118 {
119 pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
120 zval *parameter;
121
122 switch (event_type) {
123 case PDO_PARAM_EVT_EXEC_PRE:
124 if (stmt->executed && !S->done) {
125 sqlite3_reset(S->stmt);
126 S->done = 1;
127 }
128
129 if (param->is_param) {
130
131 if (param->paramno == -1) {
132 param->paramno = sqlite3_bind_parameter_index(S->stmt, ZSTR_VAL(param->name)) - 1;
133 }
134
135 switch (PDO_PARAM_TYPE(param->param_type)) {
136 case PDO_PARAM_STMT:
137 return 0;
138
139 case PDO_PARAM_NULL:
140 if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
141 return 1;
142 }
143 pdo_sqlite_error_stmt(stmt);
144 return 0;
145
146 case PDO_PARAM_INT:
147 case PDO_PARAM_BOOL:
148 if (Z_ISREF(param->parameter)) {
149 parameter = Z_REFVAL(param->parameter);
150 } else {
151 parameter = ¶m->parameter;
152 }
153 if (Z_TYPE_P(parameter) == IS_NULL) {
154 if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
155 return 1;
156 }
157 } else {
158 convert_to_long(parameter);
159 #if ZEND_LONG_MAX > 2147483647
160 if (SQLITE_OK == sqlite3_bind_int64(S->stmt, param->paramno + 1, Z_LVAL_P(parameter))) {
161 return 1;
162 }
163 #else
164 if (SQLITE_OK == sqlite3_bind_int(S->stmt, param->paramno + 1, Z_LVAL_P(parameter))) {
165 return 1;
166 }
167 #endif
168 }
169 pdo_sqlite_error_stmt(stmt);
170 return 0;
171
172 case PDO_PARAM_LOB:
173 if (Z_ISREF(param->parameter)) {
174 parameter = Z_REFVAL(param->parameter);
175 } else {
176 parameter = ¶m->parameter;
177 }
178 if (Z_TYPE_P(parameter) == IS_RESOURCE) {
179 php_stream *stm = NULL;
180 php_stream_from_zval_no_verify(stm, parameter);
181 if (stm) {
182 zend_string *mem = php_stream_copy_to_mem(stm, PHP_STREAM_COPY_ALL, 0);
183 zval_ptr_dtor(parameter);
184 ZVAL_STR(parameter, mem ? mem : ZSTR_EMPTY_ALLOC());
185 } else {
186 pdo_raise_impl_error(stmt->dbh, stmt, "HY105", "Expected a stream resource");
187 return 0;
188 }
189 } else if (Z_TYPE_P(parameter) == IS_NULL) {
190 if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
191 return 1;
192 }
193 pdo_sqlite_error_stmt(stmt);
194 return 0;
195 } else {
196 convert_to_string(parameter);
197 }
198
199 if (SQLITE_OK == sqlite3_bind_blob(S->stmt, param->paramno + 1,
200 Z_STRVAL_P(parameter),
201 Z_STRLEN_P(parameter),
202 SQLITE_STATIC)) {
203 return 1;
204 }
205 return 0;
206
207 case PDO_PARAM_STR:
208 default:
209 if (Z_ISREF(param->parameter)) {
210 parameter = Z_REFVAL(param->parameter);
211 } else {
212 parameter = ¶m->parameter;
213 }
214 if (Z_TYPE_P(parameter) == IS_NULL) {
215 if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
216 return 1;
217 }
218 } else {
219 convert_to_string(parameter);
220 if (SQLITE_OK == sqlite3_bind_text(S->stmt, param->paramno + 1,
221 Z_STRVAL_P(parameter),
222 Z_STRLEN_P(parameter),
223 SQLITE_STATIC)) {
224 return 1;
225 }
226 }
227 pdo_sqlite_error_stmt(stmt);
228 return 0;
229 }
230 }
231 break;
232
233 default:
234 ;
235 }
236 return 1;
237 }
238
pdo_sqlite_stmt_fetch(pdo_stmt_t * stmt,enum pdo_fetch_orientation ori,zend_long offset)239 static int pdo_sqlite_stmt_fetch(pdo_stmt_t *stmt,
240 enum pdo_fetch_orientation ori, zend_long offset)
241 {
242 pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
243 int i;
244 if (!S->stmt) {
245 return 0;
246 }
247 if (S->pre_fetched) {
248 S->pre_fetched = 0;
249 return 1;
250 }
251 if (S->done) {
252 return 0;
253 }
254 i = sqlite3_step(S->stmt);
255 switch (i) {
256 case SQLITE_ROW:
257 return 1;
258
259 case SQLITE_DONE:
260 S->done = 1;
261 sqlite3_reset(S->stmt);
262 return 0;
263
264 case SQLITE_ERROR:
265 sqlite3_reset(S->stmt);
266 default:
267 pdo_sqlite_error_stmt(stmt);
268 return 0;
269 }
270 }
271
pdo_sqlite_stmt_describe(pdo_stmt_t * stmt,int colno)272 static int pdo_sqlite_stmt_describe(pdo_stmt_t *stmt, int colno)
273 {
274 pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
275 const char *str;
276
277 if(colno >= sqlite3_column_count(S->stmt)) {
278 /* error invalid column */
279 pdo_sqlite_error_stmt(stmt);
280 return 0;
281 }
282
283 str = sqlite3_column_name(S->stmt, colno);
284 stmt->columns[colno].name = zend_string_init(str, strlen(str), 0);
285 stmt->columns[colno].maxlen = SIZE_MAX;
286 stmt->columns[colno].precision = 0;
287
288 switch (sqlite3_column_type(S->stmt, colno)) {
289 case SQLITE_INTEGER:
290 case SQLITE_FLOAT:
291 case SQLITE3_TEXT:
292 case SQLITE_BLOB:
293 case SQLITE_NULL:
294 default:
295 stmt->columns[colno].param_type = PDO_PARAM_STR;
296 break;
297 }
298
299 return 1;
300 }
301
pdo_sqlite_stmt_get_col(pdo_stmt_t * stmt,int colno,char ** ptr,zend_ulong * len,int * caller_frees)302 static int pdo_sqlite_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, zend_ulong *len, int *caller_frees)
303 {
304 pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
305 if (!S->stmt) {
306 return 0;
307 }
308 if(colno >= sqlite3_data_count(S->stmt)) {
309 /* error invalid column */
310 pdo_sqlite_error_stmt(stmt);
311 return 0;
312 }
313 switch (sqlite3_column_type(S->stmt, colno)) {
314 case SQLITE_NULL:
315 *ptr = NULL;
316 *len = 0;
317 return 1;
318
319 case SQLITE_BLOB:
320 *ptr = (char*)sqlite3_column_blob(S->stmt, colno);
321 *len = sqlite3_column_bytes(S->stmt, colno);
322 return 1;
323
324 default:
325 *ptr = (char*)sqlite3_column_text(S->stmt, colno);
326 *len = sqlite3_column_bytes(S->stmt, colno);
327 return 1;
328 }
329 }
330
pdo_sqlite_stmt_col_meta(pdo_stmt_t * stmt,zend_long colno,zval * return_value)331 static int pdo_sqlite_stmt_col_meta(pdo_stmt_t *stmt, zend_long colno, zval *return_value)
332 {
333 pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
334 const char *str;
335 zval flags;
336
337 if (!S->stmt) {
338 return FAILURE;
339 }
340 if(colno >= sqlite3_column_count(S->stmt)) {
341 /* error invalid column */
342 pdo_sqlite_error_stmt(stmt);
343 return FAILURE;
344 }
345
346 array_init(return_value);
347 array_init(&flags);
348
349 switch (sqlite3_column_type(S->stmt, colno)) {
350 case SQLITE_NULL:
351 add_assoc_string(return_value, "native_type", "null");
352 break;
353
354 case SQLITE_FLOAT:
355 add_assoc_string(return_value, "native_type", "double");
356 break;
357
358 case SQLITE_BLOB:
359 add_next_index_string(&flags, "blob");
360 case SQLITE_TEXT:
361 add_assoc_string(return_value, "native_type", "string");
362 break;
363
364 case SQLITE_INTEGER:
365 add_assoc_string(return_value, "native_type", "integer");
366 break;
367 }
368
369 str = sqlite3_column_decltype(S->stmt, colno);
370 if (str) {
371 add_assoc_string(return_value, "sqlite:decl_type", (char *)str);
372 }
373
374 #ifdef SQLITE_ENABLE_COLUMN_METADATA
375 str = sqlite3_column_table_name(S->stmt, colno);
376 if (str) {
377 add_assoc_string(return_value, "table", (char *)str);
378 }
379 #endif
380
381 add_assoc_zval(return_value, "flags", &flags);
382
383 return SUCCESS;
384 }
385
pdo_sqlite_stmt_cursor_closer(pdo_stmt_t * stmt)386 static int pdo_sqlite_stmt_cursor_closer(pdo_stmt_t *stmt)
387 {
388 pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
389 sqlite3_reset(S->stmt);
390 return 1;
391 }
392
393 const struct pdo_stmt_methods sqlite_stmt_methods = {
394 pdo_sqlite_stmt_dtor,
395 pdo_sqlite_stmt_execute,
396 pdo_sqlite_stmt_fetch,
397 pdo_sqlite_stmt_describe,
398 pdo_sqlite_stmt_get_col,
399 pdo_sqlite_stmt_param_hook,
400 NULL, /* set_attr */
401 NULL, /* get_attr */
402 pdo_sqlite_stmt_col_meta,
403 NULL, /* next_rowset */
404 pdo_sqlite_stmt_cursor_closer
405 };
406
407 /*
408 * Local variables:
409 * tab-width: 4
410 * c-basic-offset: 4
411 * End:
412 * vim600: noet sw=4 ts=4 fdm=marker
413 * vim<600: noet sw=4 ts=4
414 */
415