php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
sqlite_statement.c
Go to the documentation of this file.
1/*
2 +----------------------------------------------------------------------+
3 | Copyright (c) The PHP Group |
4 +----------------------------------------------------------------------+
5 | This source file is subject to version 3.01 of the PHP license, |
6 | that is bundled with this package in the file LICENSE, and is |
7 | available through the world-wide-web at the following url: |
8 | https://www.php.net/license/3_01.txt |
9 | If you did not receive a copy of the PHP license and are unable to |
10 | obtain it through the world-wide-web, please send a note to |
11 | license@php.net so we can mail you a copy immediately. |
12 +----------------------------------------------------------------------+
13 | Author: Wez Furlong <wez@php.net> |
14 +----------------------------------------------------------------------+
15*/
16
17#ifdef HAVE_CONFIG_H
18#include <config.h>
19#endif
20
21#include "php.h"
22#include "php_ini.h"
23#include "ext/standard/info.h"
24#include "ext/pdo/php_pdo.h"
26#include "php_pdo_sqlite.h"
27#include "php_pdo_sqlite_int.h"
28
29
30static int pdo_sqlite_stmt_dtor(pdo_stmt_t *stmt)
31{
33
34 if (S->stmt) {
35 sqlite3_finalize(S->stmt);
36 S->stmt = NULL;
37 }
38 efree(S);
39 return 1;
40}
41
42static int pdo_sqlite_stmt_execute(pdo_stmt_t *stmt)
43{
45
46 if (stmt->executed && !S->done) {
47 sqlite3_reset(S->stmt);
48 }
49
50 S->done = 0;
51 switch (sqlite3_step(S->stmt)) {
52 case SQLITE_ROW:
53 S->pre_fetched = 1;
54 php_pdo_stmt_set_column_count(stmt, sqlite3_data_count(S->stmt));
55 return 1;
56
57 case SQLITE_DONE:
58 php_pdo_stmt_set_column_count(stmt, sqlite3_column_count(S->stmt));
59 stmt->row_count = sqlite3_changes(S->H->db);
60 sqlite3_reset(S->stmt);
61 S->done = 1;
62 return 1;
63
64 case SQLITE_ERROR:
65 sqlite3_reset(S->stmt);
67 case SQLITE_MISUSE:
68 case SQLITE_BUSY:
69 default:
71 return 0;
72 }
73}
74
75static int pdo_sqlite_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param,
76 enum pdo_param_event event_type)
77{
79 zval *parameter;
80
81 switch (event_type) {
83 if (stmt->executed && !S->done) {
84 sqlite3_reset(S->stmt);
85 S->done = 1;
86 }
87
88 if (param->is_param) {
89
90 if (param->paramno == -1) {
91 param->paramno = sqlite3_bind_parameter_index(S->stmt, ZSTR_VAL(param->name)) - 1;
92 }
93
94 switch (PDO_PARAM_TYPE(param->param_type)) {
95 case PDO_PARAM_STMT:
96 return 0;
97
98 case PDO_PARAM_NULL:
99 if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
100 return 1;
101 }
103 return 0;
104
105 case PDO_PARAM_INT:
106 case PDO_PARAM_BOOL:
107 if (Z_ISREF(param->parameter)) {
108 parameter = Z_REFVAL(param->parameter);
109 } else {
110 parameter = &param->parameter;
111 }
112 if (Z_TYPE_P(parameter) == IS_NULL) {
113 if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
114 return 1;
115 }
116 } else {
117 convert_to_long(parameter);
118#if ZEND_LONG_MAX > 2147483647
119 if (SQLITE_OK == sqlite3_bind_int64(S->stmt, param->paramno + 1, Z_LVAL_P(parameter))) {
120 return 1;
121 }
122#else
123 if (SQLITE_OK == sqlite3_bind_int(S->stmt, param->paramno + 1, Z_LVAL_P(parameter))) {
124 return 1;
125 }
126#endif
127 }
129 return 0;
130
131 case PDO_PARAM_LOB:
132 if (Z_ISREF(param->parameter)) {
133 parameter = Z_REFVAL(param->parameter);
134 } else {
135 parameter = &param->parameter;
136 }
137 if (Z_TYPE_P(parameter) == IS_RESOURCE) {
138 php_stream *stm = NULL;
139 php_stream_from_zval_no_verify(stm, parameter);
140 if (stm) {
142 zval_ptr_dtor(parameter);
143 ZVAL_STR(parameter, mem ? mem : ZSTR_EMPTY_ALLOC());
144 } else {
145 pdo_raise_impl_error(stmt->dbh, stmt, "HY105", "Expected a stream resource");
146 return 0;
147 }
148 } else if (Z_TYPE_P(parameter) == IS_NULL) {
149 if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
150 return 1;
151 }
153 return 0;
154 } else {
155 if (!try_convert_to_string(parameter)) {
156 return 0;
157 }
158 }
159
160 if (SQLITE_OK == sqlite3_bind_blob(S->stmt, param->paramno + 1,
161 Z_STRVAL_P(parameter),
162 Z_STRLEN_P(parameter),
163 SQLITE_STATIC)) {
164 return 1;
165 }
166 return 0;
167
168 case PDO_PARAM_STR:
169 default:
170 if (Z_ISREF(param->parameter)) {
171 parameter = Z_REFVAL(param->parameter);
172 } else {
173 parameter = &param->parameter;
174 }
175 if (Z_TYPE_P(parameter) == IS_NULL) {
176 if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
177 return 1;
178 }
179 } else {
180 if (!try_convert_to_string(parameter)) {
181 return 0;
182 }
183 if (SQLITE_OK == sqlite3_bind_text(S->stmt, param->paramno + 1,
184 Z_STRVAL_P(parameter),
185 Z_STRLEN_P(parameter),
186 SQLITE_STATIC)) {
187 return 1;
188 }
189 }
191 return 0;
192 }
193 }
194 break;
195
196 default:
197 ;
198 }
199 return 1;
200}
201
202static int pdo_sqlite_stmt_fetch(pdo_stmt_t *stmt,
204{
206 int i;
207 if (!S->stmt) {
208 return 0;
209 }
210 if (S->pre_fetched) {
211 S->pre_fetched = 0;
212 return 1;
213 }
214 if (S->done) {
215 return 0;
216 }
217 i = sqlite3_step(S->stmt);
218 switch (i) {
219 case SQLITE_ROW:
220 return 1;
221
222 case SQLITE_DONE:
223 S->done = 1;
224 sqlite3_reset(S->stmt);
225 return 0;
226
227 case SQLITE_ERROR:
228 sqlite3_reset(S->stmt);
230 default:
232 return 0;
233 }
234}
235
236static int pdo_sqlite_stmt_describe(pdo_stmt_t *stmt, int colno)
237{
239 const char *str;
240
241 if(colno >= sqlite3_column_count(S->stmt)) {
242 /* error invalid column */
244 return 0;
245 }
246
247 str = sqlite3_column_name(S->stmt, colno);
248 stmt->columns[colno].name = zend_string_init(str, strlen(str), 0);
249 stmt->columns[colno].maxlen = SIZE_MAX;
250 stmt->columns[colno].precision = 0;
251
252 return 1;
253}
254
255static int pdo_sqlite_stmt_get_col(
256 pdo_stmt_t *stmt, int colno, zval *result, enum pdo_param_type *type)
257{
259 if (!S->stmt) {
260 return 0;
261 }
262 if(colno >= sqlite3_data_count(S->stmt)) {
263 /* error invalid column */
265 return 0;
266 }
267 switch (sqlite3_column_type(S->stmt, colno)) {
268 case SQLITE_NULL:
270 return 1;
271
272 case SQLITE_INTEGER: {
273 int64_t i = sqlite3_column_int64(S->stmt, colno);
274#if SIZEOF_ZEND_LONG < 8
275 if (i > ZEND_LONG_MAX || i < ZEND_LONG_MIN) {
277 (char *) sqlite3_column_text(S->stmt, colno),
278 sqlite3_column_bytes(S->stmt, colno));
279 return 1;
280 }
281#endif
282 ZVAL_LONG(result, i);
283 return 1;
284 }
285
286 case SQLITE_FLOAT:
287 ZVAL_DOUBLE(result, sqlite3_column_double(S->stmt, colno));
288 return 1;
289
290 case SQLITE_BLOB:
292 sqlite3_column_blob(S->stmt, colno), sqlite3_column_bytes(S->stmt, colno));
293 return 1;
294
295 default:
297 (char *) sqlite3_column_text(S->stmt, colno), sqlite3_column_bytes(S->stmt, colno));
298 return 1;
299 }
300}
301
302static int pdo_sqlite_stmt_col_meta(pdo_stmt_t *stmt, zend_long colno, zval *return_value)
303{
305 const char *str;
306 zval flags;
307
308 if (!S->stmt || !stmt->executed) {
309 return FAILURE;
310 }
311 if(colno >= sqlite3_column_count(S->stmt)) {
312 /* error invalid column */
314 return FAILURE;
315 }
316
319
320 switch (sqlite3_column_type(S->stmt, colno)) {
321 case SQLITE_NULL:
322 add_assoc_str(return_value, "native_type", ZSTR_KNOWN(ZEND_STR_NULL_LOWERCASE));
323 add_assoc_long(return_value, "pdo_type", PDO_PARAM_NULL);
324 break;
325
326 case SQLITE_FLOAT:
327 add_assoc_str(return_value, "native_type", ZSTR_KNOWN(ZEND_STR_DOUBLE));
328 add_assoc_long(return_value, "pdo_type", PDO_PARAM_STR);
329 break;
330
331 case SQLITE_BLOB:
333 /* TODO Check this is correct */
335 case SQLITE_TEXT:
336 add_assoc_str(return_value, "native_type", ZSTR_KNOWN(ZEND_STR_STRING));
337 add_assoc_long(return_value, "pdo_type", PDO_PARAM_STR);
338 break;
339
340 case SQLITE_INTEGER:
341 add_assoc_str(return_value, "native_type", ZSTR_KNOWN(ZEND_STR_INTEGER));
342 add_assoc_long(return_value, "pdo_type", PDO_PARAM_INT);
343 break;
344 }
345
346 str = sqlite3_column_decltype(S->stmt, colno);
347 if (str) {
348 add_assoc_string(return_value, "sqlite:decl_type", (char *)str);
349 }
350
351#ifdef HAVE_SQLITE3_COLUMN_TABLE_NAME
352 str = sqlite3_column_table_name(S->stmt, colno);
353 if (str) {
354 add_assoc_string(return_value, "table", (char *)str);
355 }
356#endif
357
358 add_assoc_zval(return_value, "flags", &flags);
359
360 return SUCCESS;
361}
362
363static int pdo_sqlite_stmt_cursor_closer(pdo_stmt_t *stmt)
364{
366 sqlite3_reset(S->stmt);
367 return 1;
368}
369
370static int pdo_sqlite_stmt_get_attribute(pdo_stmt_t *stmt, zend_long attr, zval *val)
371{
373
374 switch (attr) {
377
378#if SQLITE_VERSION_NUMBER >= 3007004
379 if (sqlite3_stmt_readonly(S->stmt)) {
380 ZVAL_TRUE(val);
381 }
382#endif
383 break;
384
385 default:
386 return 0;
387 }
388
389 return 1;
390}
391
393 pdo_sqlite_stmt_dtor,
394 pdo_sqlite_stmt_execute,
395 pdo_sqlite_stmt_fetch,
396 pdo_sqlite_stmt_describe,
397 pdo_sqlite_stmt_get_col,
398 pdo_sqlite_stmt_param_hook,
399 NULL, /* set_attr */
400 pdo_sqlite_stmt_get_attribute, /* get_attr */
401 pdo_sqlite_stmt_col_meta,
402 NULL, /* next_rowset */
403 pdo_sqlite_stmt_cursor_closer
404};
zend_ffi_type * type
Definition ffi.c:3812
new_type attr
Definition ffi.c:4364
zval * val
Definition ffi.c:4262
zend_long offset
#define SIZE_MAX
Definition funcs.c:51
#define NULL
Definition gdcache.h:45
#define S(s, l, r)
Definition hash_gost.c:121
#define SUCCESS
Definition hash_sha3.c:261
void pdo_raise_impl_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, pdo_error_type sqlstate, const char *supp)
Definition pdo_dbh.c:68
PDO_API void php_pdo_stmt_set_column_count(pdo_stmt_t *stmt, int new_count)
Definition pdo_stmt.c:195
struct _pdo_stmt_t pdo_stmt_t
pdo_param_type
@ PDO_PARAM_LOB
@ PDO_PARAM_BOOL
@ PDO_PARAM_INT
@ PDO_PARAM_STMT
@ PDO_PARAM_NULL
@ PDO_PARAM_STR
pdo_param_event
@ PDO_PARAM_EVT_EXEC_PRE
pdo_fetch_orientation
#define PDO_PARAM_TYPE(x)
#define pdo_sqlite_error_stmt(s)
@ PDO_SQLITE_ATTR_READONLY_STATEMENT
const struct pdo_stmt_methods sqlite_stmt_methods
struct _php_stream php_stream
Definition php_streams.h:96
#define PHP_STREAM_COPY_ALL
#define php_stream_copy_to_mem(src, maxlen, persistent)
#define php_stream_from_zval_no_verify(xstr, pzval)
ZEND_API zend_result add_next_index_string(zval *arg, const char *str)
Definition zend_API.c:2186
#define ZVAL_STRINGL(z, s, l)
Definition zend_API.h:952
#define ZVAL_STRINGL_FAST(z, s, l)
Definition zend_API.h:983
#define array_init(arg)
Definition zend_API.h:537
#define efree(ptr)
Definition zend_alloc.h:155
struct _zval_struct zval
strlen(string $string)
int32_t zend_long
Definition zend_long.h:42
#define ZEND_LONG_MIN
Definition zend_long.h:46
#define ZEND_LONG_MAX
Definition zend_long.h:45
struct _zend_string zend_string
ZEND_API void ZEND_FASTCALL convert_to_long(zval *op)
#define ZEND_FALLTHROUGH
#define ZSTR_VAL(zstr)
Definition zend_string.h:68
#define ZSTR_KNOWN(idx)
#define ZSTR_EMPTY_ALLOC()
#define Z_TYPE_P(zval_p)
Definition zend_types.h:660
#define ZVAL_STR(z, s)
#define ZVAL_FALSE(z)
#define Z_STRVAL_P(zval_p)
Definition zend_types.h:975
#define ZVAL_TRUE(z)
#define ZVAL_NULL(z)
#define ZVAL_LONG(z, l)
#define IS_RESOURCE
Definition zend_types.h:609
#define Z_REFVAL(zval)
#define Z_STRLEN_P(zval_p)
Definition zend_types.h:978
#define IS_NULL
Definition zend_types.h:601
@ FAILURE
Definition zend_types.h:61
#define ZVAL_DOUBLE(z, d)
#define Z_ISREF(zval)
Definition zend_types.h:953
#define Z_LVAL_P(zval_p)
Definition zend_types.h:966
ZEND_API void zval_ptr_dtor(zval *zval_ptr)
zval * return_value
bool result