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