1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 7 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 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 if (!try_convert_to_string(parameter)) {
197 return 0;
198 }
199 }
200
201 if (SQLITE_OK == sqlite3_bind_blob(S->stmt, param->paramno + 1,
202 Z_STRVAL_P(parameter),
203 Z_STRLEN_P(parameter),
204 SQLITE_STATIC)) {
205 return 1;
206 }
207 return 0;
208
209 case PDO_PARAM_STR:
210 default:
211 if (Z_ISREF(param->parameter)) {
212 parameter = Z_REFVAL(param->parameter);
213 } else {
214 parameter = ¶m->parameter;
215 }
216 if (Z_TYPE_P(parameter) == IS_NULL) {
217 if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
218 return 1;
219 }
220 } else {
221 if (!try_convert_to_string(parameter)) {
222 return 0;
223 }
224 if (SQLITE_OK == sqlite3_bind_text(S->stmt, param->paramno + 1,
225 Z_STRVAL_P(parameter),
226 Z_STRLEN_P(parameter),
227 SQLITE_STATIC)) {
228 return 1;
229 }
230 }
231 pdo_sqlite_error_stmt(stmt);
232 return 0;
233 }
234 }
235 break;
236
237 default:
238 ;
239 }
240 return 1;
241 }
242
pdo_sqlite_stmt_fetch(pdo_stmt_t * stmt,enum pdo_fetch_orientation ori,zend_long offset)243 static int pdo_sqlite_stmt_fetch(pdo_stmt_t *stmt,
244 enum pdo_fetch_orientation ori, zend_long offset)
245 {
246 pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
247 int i;
248 if (!S->stmt) {
249 return 0;
250 }
251 if (S->pre_fetched) {
252 S->pre_fetched = 0;
253 return 1;
254 }
255 if (S->done) {
256 return 0;
257 }
258 i = sqlite3_step(S->stmt);
259 switch (i) {
260 case SQLITE_ROW:
261 return 1;
262
263 case SQLITE_DONE:
264 S->done = 1;
265 sqlite3_reset(S->stmt);
266 return 0;
267
268 case SQLITE_ERROR:
269 sqlite3_reset(S->stmt);
270 default:
271 pdo_sqlite_error_stmt(stmt);
272 return 0;
273 }
274 }
275
pdo_sqlite_stmt_describe(pdo_stmt_t * stmt,int colno)276 static int pdo_sqlite_stmt_describe(pdo_stmt_t *stmt, int colno)
277 {
278 pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
279 const char *str;
280
281 if(colno >= sqlite3_column_count(S->stmt)) {
282 /* error invalid column */
283 pdo_sqlite_error_stmt(stmt);
284 return 0;
285 }
286
287 str = sqlite3_column_name(S->stmt, colno);
288 stmt->columns[colno].name = zend_string_init(str, strlen(str), 0);
289 stmt->columns[colno].maxlen = SIZE_MAX;
290 stmt->columns[colno].precision = 0;
291
292 switch (sqlite3_column_type(S->stmt, colno)) {
293 case SQLITE_INTEGER:
294 case SQLITE_FLOAT:
295 case SQLITE3_TEXT:
296 case SQLITE_BLOB:
297 case SQLITE_NULL:
298 default:
299 stmt->columns[colno].param_type = PDO_PARAM_STR;
300 break;
301 }
302
303 return 1;
304 }
305
pdo_sqlite_stmt_get_col(pdo_stmt_t * stmt,int colno,char ** ptr,size_t * len,int * caller_frees)306 static int pdo_sqlite_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, size_t *len, int *caller_frees)
307 {
308 pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
309 if (!S->stmt) {
310 return 0;
311 }
312 if(colno >= sqlite3_data_count(S->stmt)) {
313 /* error invalid column */
314 pdo_sqlite_error_stmt(stmt);
315 return 0;
316 }
317 switch (sqlite3_column_type(S->stmt, colno)) {
318 case SQLITE_NULL:
319 *ptr = NULL;
320 *len = 0;
321 return 1;
322
323 case SQLITE_BLOB:
324 *ptr = (char*)sqlite3_column_blob(S->stmt, colno);
325 *len = sqlite3_column_bytes(S->stmt, colno);
326 return 1;
327
328 default:
329 *ptr = (char*)sqlite3_column_text(S->stmt, colno);
330 *len = sqlite3_column_bytes(S->stmt, colno);
331 return 1;
332 }
333 }
334
pdo_sqlite_stmt_col_meta(pdo_stmt_t * stmt,zend_long colno,zval * return_value)335 static int pdo_sqlite_stmt_col_meta(pdo_stmt_t *stmt, zend_long colno, zval *return_value)
336 {
337 pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
338 const char *str;
339 zval flags;
340
341 if (!S->stmt) {
342 return FAILURE;
343 }
344 if(colno >= sqlite3_column_count(S->stmt)) {
345 /* error invalid column */
346 pdo_sqlite_error_stmt(stmt);
347 return FAILURE;
348 }
349
350 array_init(return_value);
351 array_init(&flags);
352
353 switch (sqlite3_column_type(S->stmt, colno)) {
354 case SQLITE_NULL:
355 add_assoc_string(return_value, "native_type", "null");
356 break;
357
358 case SQLITE_FLOAT:
359 add_assoc_string(return_value, "native_type", "double");
360 break;
361
362 case SQLITE_BLOB:
363 add_next_index_string(&flags, "blob");
364 case SQLITE_TEXT:
365 add_assoc_string(return_value, "native_type", "string");
366 break;
367
368 case SQLITE_INTEGER:
369 add_assoc_string(return_value, "native_type", "integer");
370 break;
371 }
372
373 str = sqlite3_column_decltype(S->stmt, colno);
374 if (str) {
375 add_assoc_string(return_value, "sqlite:decl_type", (char *)str);
376 }
377
378 #ifdef HAVE_SQLITE3_COLUMN_TABLE_NAME
379 str = sqlite3_column_table_name(S->stmt, colno);
380 if (str) {
381 add_assoc_string(return_value, "table", (char *)str);
382 }
383 #endif
384
385 add_assoc_zval(return_value, "flags", &flags);
386
387 return SUCCESS;
388 }
389
pdo_sqlite_stmt_cursor_closer(pdo_stmt_t * stmt)390 static int pdo_sqlite_stmt_cursor_closer(pdo_stmt_t *stmt)
391 {
392 pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
393 sqlite3_reset(S->stmt);
394 return 1;
395 }
396
pdo_sqlite_stmt_get_attribute(pdo_stmt_t * stmt,zend_long attr,zval * val)397 static int pdo_sqlite_stmt_get_attribute(pdo_stmt_t *stmt, zend_long attr, zval *val)
398 {
399 pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
400
401 switch (attr) {
402 case PDO_SQLITE_ATTR_READONLY_STATEMENT:
403 ZVAL_FALSE(val);
404
405 #if SQLITE_VERSION_NUMBER >= 3007004
406 if (sqlite3_stmt_readonly(S->stmt)) {
407 ZVAL_TRUE(val);
408 }
409 #endif
410 break;
411
412 default:
413 return 0;
414 }
415
416 return 1;
417 }
418
419 const struct pdo_stmt_methods sqlite_stmt_methods = {
420 pdo_sqlite_stmt_dtor,
421 pdo_sqlite_stmt_execute,
422 pdo_sqlite_stmt_fetch,
423 pdo_sqlite_stmt_describe,
424 pdo_sqlite_stmt_get_col,
425 pdo_sqlite_stmt_param_hook,
426 NULL, /* set_attr */
427 pdo_sqlite_stmt_get_attribute, /* get_attr */
428 pdo_sqlite_stmt_col_meta,
429 NULL, /* next_rowset */
430 pdo_sqlite_stmt_cursor_closer
431 };
432