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