1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 7 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2017 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
pdo_sqlite_stmt_execute(pdo_stmt_t * stmt)46 static int pdo_sqlite_stmt_execute(pdo_stmt_t *stmt)
47 {
48 pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
49
50 if (stmt->executed && !S->done) {
51 sqlite3_reset(S->stmt);
52 }
53
54 S->done = 0;
55 switch (sqlite3_step(S->stmt)) {
56 case SQLITE_ROW:
57 S->pre_fetched = 1;
58 stmt->column_count = sqlite3_data_count(S->stmt);
59 return 1;
60
61 case SQLITE_DONE:
62 stmt->column_count = sqlite3_column_count(S->stmt);
63 stmt->row_count = sqlite3_changes(S->H->db);
64 sqlite3_reset(S->stmt);
65 S->done = 1;
66 return 1;
67
68 case SQLITE_ERROR:
69 sqlite3_reset(S->stmt);
70 case SQLITE_MISUSE:
71 case SQLITE_BUSY:
72 default:
73 pdo_sqlite_error_stmt(stmt);
74 return 0;
75 }
76 }
77
pdo_sqlite_stmt_param_hook(pdo_stmt_t * stmt,struct pdo_bound_param_data * param,enum pdo_param_event event_type)78 static int pdo_sqlite_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param,
79 enum pdo_param_event event_type)
80 {
81 pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
82 zval *parameter;
83
84 switch (event_type) {
85 case PDO_PARAM_EVT_EXEC_PRE:
86 if (stmt->executed && !S->done) {
87 sqlite3_reset(S->stmt);
88 S->done = 1;
89 }
90
91 if (param->is_param) {
92
93 if (param->paramno == -1) {
94 param->paramno = sqlite3_bind_parameter_index(S->stmt, ZSTR_VAL(param->name)) - 1;
95 }
96
97 switch (PDO_PARAM_TYPE(param->param_type)) {
98 case PDO_PARAM_STMT:
99 return 0;
100
101 case PDO_PARAM_NULL:
102 if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
103 return 1;
104 }
105 pdo_sqlite_error_stmt(stmt);
106 return 0;
107
108 case PDO_PARAM_INT:
109 case PDO_PARAM_BOOL:
110 if (Z_ISREF(param->parameter)) {
111 parameter = Z_REFVAL(param->parameter);
112 } else {
113 parameter = ¶m->parameter;
114 }
115 if (Z_TYPE_P(parameter) == IS_NULL) {
116 if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
117 return 1;
118 }
119 } else {
120 convert_to_long(parameter);
121 #if ZEND_LONG_MAX > 2147483647
122 if (SQLITE_OK == sqlite3_bind_int64(S->stmt, param->paramno + 1, Z_LVAL_P(parameter))) {
123 return 1;
124 }
125 #else
126 if (SQLITE_OK == sqlite3_bind_int(S->stmt, param->paramno + 1, Z_LVAL_P(parameter))) {
127 return 1;
128 }
129 #endif
130 }
131 pdo_sqlite_error_stmt(stmt);
132 return 0;
133
134 case PDO_PARAM_LOB:
135 if (Z_ISREF(param->parameter)) {
136 parameter = Z_REFVAL(param->parameter);
137 } else {
138 parameter = ¶m->parameter;
139 }
140 if (Z_TYPE_P(parameter) == IS_RESOURCE) {
141 php_stream *stm = NULL;
142 php_stream_from_zval_no_verify(stm, parameter);
143 if (stm) {
144 zend_string *mem = php_stream_copy_to_mem(stm, PHP_STREAM_COPY_ALL, 0);
145 zval_ptr_dtor(parameter);
146 ZVAL_STR(parameter, mem ? mem : ZSTR_EMPTY_ALLOC());
147 } else {
148 pdo_raise_impl_error(stmt->dbh, stmt, "HY105", "Expected a stream resource");
149 return 0;
150 }
151 } else if (Z_TYPE_P(parameter) == IS_NULL) {
152 if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
153 return 1;
154 }
155 pdo_sqlite_error_stmt(stmt);
156 return 0;
157 } else {
158 convert_to_string(parameter);
159 }
160
161 if (SQLITE_OK == sqlite3_bind_blob(S->stmt, param->paramno + 1,
162 Z_STRVAL_P(parameter),
163 Z_STRLEN_P(parameter),
164 SQLITE_STATIC)) {
165 return 1;
166 }
167 return 0;
168
169 case PDO_PARAM_STR:
170 default:
171 if (Z_ISREF(param->parameter)) {
172 parameter = Z_REFVAL(param->parameter);
173 } else {
174 parameter = ¶m->parameter;
175 }
176 if (Z_TYPE_P(parameter) == IS_NULL) {
177 if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
178 return 1;
179 }
180 } else {
181 convert_to_string(parameter);
182 if (SQLITE_OK == sqlite3_bind_text(S->stmt, param->paramno + 1,
183 Z_STRVAL_P(parameter),
184 Z_STRLEN_P(parameter),
185 SQLITE_STATIC)) {
186 return 1;
187 }
188 }
189 pdo_sqlite_error_stmt(stmt);
190 return 0;
191 }
192 }
193 break;
194
195 default:
196 ;
197 }
198 return 1;
199 }
200
pdo_sqlite_stmt_fetch(pdo_stmt_t * stmt,enum pdo_fetch_orientation ori,zend_long offset)201 static int pdo_sqlite_stmt_fetch(pdo_stmt_t *stmt,
202 enum pdo_fetch_orientation ori, zend_long offset)
203 {
204 pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
205 int i;
206 if (!S->stmt) {
207 return 0;
208 }
209 if (S->pre_fetched) {
210 S->pre_fetched = 0;
211 return 1;
212 }
213 if (S->done) {
214 return 0;
215 }
216 i = sqlite3_step(S->stmt);
217 switch (i) {
218 case SQLITE_ROW:
219 return 1;
220
221 case SQLITE_DONE:
222 S->done = 1;
223 sqlite3_reset(S->stmt);
224 return 0;
225
226 case SQLITE_ERROR:
227 sqlite3_reset(S->stmt);
228 default:
229 pdo_sqlite_error_stmt(stmt);
230 return 0;
231 }
232 }
233
pdo_sqlite_stmt_describe(pdo_stmt_t * stmt,int colno)234 static int pdo_sqlite_stmt_describe(pdo_stmt_t *stmt, int colno)
235 {
236 pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
237 const char *str;
238
239 if(colno >= sqlite3_column_count(S->stmt)) {
240 /* error invalid column */
241 pdo_sqlite_error_stmt(stmt);
242 return 0;
243 }
244
245 str = sqlite3_column_name(S->stmt, colno);
246 stmt->columns[colno].name = zend_string_init(str, strlen(str), 0);
247 stmt->columns[colno].maxlen = 0xffffffff;
248 stmt->columns[colno].precision = 0;
249
250 switch (sqlite3_column_type(S->stmt, colno)) {
251 case SQLITE_INTEGER:
252 case SQLITE_FLOAT:
253 case SQLITE3_TEXT:
254 case SQLITE_BLOB:
255 case SQLITE_NULL:
256 default:
257 stmt->columns[colno].param_type = PDO_PARAM_STR;
258 break;
259 }
260
261 return 1;
262 }
263
pdo_sqlite_stmt_get_col(pdo_stmt_t * stmt,int colno,char ** ptr,zend_ulong * len,int * caller_frees)264 static int pdo_sqlite_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, zend_ulong *len, int *caller_frees)
265 {
266 pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
267 if (!S->stmt) {
268 return 0;
269 }
270 if(colno >= sqlite3_data_count(S->stmt)) {
271 /* error invalid column */
272 pdo_sqlite_error_stmt(stmt);
273 return 0;
274 }
275 switch (sqlite3_column_type(S->stmt, colno)) {
276 case SQLITE_NULL:
277 *ptr = NULL;
278 *len = 0;
279 return 1;
280
281 case SQLITE_BLOB:
282 *ptr = (char*)sqlite3_column_blob(S->stmt, colno);
283 *len = sqlite3_column_bytes(S->stmt, colno);
284 return 1;
285
286 default:
287 *ptr = (char*)sqlite3_column_text(S->stmt, colno);
288 *len = sqlite3_column_bytes(S->stmt, colno);
289 return 1;
290 }
291 }
292
pdo_sqlite_stmt_col_meta(pdo_stmt_t * stmt,zend_long colno,zval * return_value)293 static int pdo_sqlite_stmt_col_meta(pdo_stmt_t *stmt, zend_long colno, zval *return_value)
294 {
295 pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
296 const char *str;
297 zval flags;
298
299 if (!S->stmt) {
300 return FAILURE;
301 }
302 if(colno >= sqlite3_data_count(S->stmt)) {
303 /* error invalid column */
304 pdo_sqlite_error_stmt(stmt);
305 return FAILURE;
306 }
307
308 array_init(return_value);
309 array_init(&flags);
310
311 switch (sqlite3_column_type(S->stmt, colno)) {
312 case SQLITE_NULL:
313 add_assoc_string(return_value, "native_type", "null");
314 break;
315
316 case SQLITE_FLOAT:
317 add_assoc_string(return_value, "native_type", "double");
318 break;
319
320 case SQLITE_BLOB:
321 add_next_index_string(&flags, "blob");
322 case SQLITE_TEXT:
323 add_assoc_string(return_value, "native_type", "string");
324 break;
325
326 case SQLITE_INTEGER:
327 add_assoc_string(return_value, "native_type", "integer");
328 break;
329 }
330
331 str = sqlite3_column_decltype(S->stmt, colno);
332 if (str) {
333 add_assoc_string(return_value, "sqlite:decl_type", (char *)str);
334 }
335
336 #ifdef SQLITE_ENABLE_COLUMN_METADATA
337 str = sqlite3_column_table_name(S->stmt, colno);
338 if (str) {
339 add_assoc_string(return_value, "table", (char *)str);
340 }
341 #endif
342
343 add_assoc_zval(return_value, "flags", &flags);
344
345 return SUCCESS;
346 }
347
pdo_sqlite_stmt_cursor_closer(pdo_stmt_t * stmt)348 static int pdo_sqlite_stmt_cursor_closer(pdo_stmt_t *stmt)
349 {
350 pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
351 sqlite3_reset(S->stmt);
352 return 1;
353 }
354
355 struct pdo_stmt_methods sqlite_stmt_methods = {
356 pdo_sqlite_stmt_dtor,
357 pdo_sqlite_stmt_execute,
358 pdo_sqlite_stmt_fetch,
359 pdo_sqlite_stmt_describe,
360 pdo_sqlite_stmt_get_col,
361 pdo_sqlite_stmt_param_hook,
362 NULL, /* set_attr */
363 NULL, /* get_attr */
364 pdo_sqlite_stmt_col_meta,
365 NULL, /* next_rowset */
366 pdo_sqlite_stmt_cursor_closer
367 };
368
369 /*
370 * Local variables:
371 * tab-width: 4
372 * c-basic-offset: 4
373 * End:
374 * vim600: noet sw=4 ts=4 fdm=marker
375 * vim<600: noet sw=4 ts=4
376 */
377