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