php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
pdo_sqlite.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 "SAPI.h"
25#include "ext/pdo/php_pdo.h"
27#include "php_pdo_sqlite.h"
28#include "php_pdo_sqlite_int.h"
29#include "zend_exceptions.h"
30#include "pdo_sqlite_arginfo.h"
31
32static zend_class_entry *pdosqlite_ce;
33
34/* {{{ pdo_sqlite_deps */
35static const zend_module_dep pdo_sqlite_deps[] = {
38};
39/* }}} */
40
41/* {{{ pdo_sqlite_module_entry */
44 pdo_sqlite_deps,
45 "pdo_sqlite",
46 NULL,
47 PHP_MINIT(pdo_sqlite),
48 PHP_MSHUTDOWN(pdo_sqlite),
49 NULL,
50 NULL,
51 PHP_MINFO(pdo_sqlite),
54};
55/* }}} */
56
57#if defined(COMPILE_DL_PDO_SQLITE) || defined(COMPILE_DL_PDO_SQLITE_EXTERNAL)
58ZEND_GET_MODULE(pdo_sqlite)
59#endif
60
61/* proto bool PdoSqlite::createFunction(string $function_name, callable $callback, int $num_args = -1, int $flags = 0)
62 Creates a function that can be used in a query
63*/
68
69#ifndef PDO_SQLITE_OMIT_LOAD_EXTENSION
70/* Attempts to load an SQLite extension library. */
71PHP_METHOD(Pdo_Sqlite, loadExtension)
72{
73 char *extension, *errtext = NULL;
74 char fullpath[MAXPATHLEN];
75 size_t extension_len;
76
77 pdo_dbh_t *dbh;
78 pdo_sqlite_db_handle *db_handle;
79
80 if (zend_parse_parameters(ZEND_NUM_ARGS(), "p", &extension, &extension_len) == FAILURE) {
82 }
83
84 if (extension_len == 0) {
87 }
88
91
92 db_handle = (pdo_sqlite_db_handle *)dbh->driver_data;
93
94#ifdef ZTS
95 if ((strncmp(sapi_module.name, "cgi", 3) != 0) &&
96 (strcmp(sapi_module.name, "cli") != 0) &&
97 (strncmp(sapi_module.name, "embed", 5) != 0)
98 ) {
99 zend_throw_exception_ex(php_pdo_get_exception(), 0, "Not supported in multithreaded Web servers");
101 }
102#endif
103
104 if (!VCWD_REALPATH(extension, fullpath)) {
105 zend_throw_exception_ex(php_pdo_get_exception(), 0, "Unable to load extension \"%s\"", extension);
107 }
108
109 sqlite3 *sqlite_handle;
110 sqlite_handle = db_handle->db;
111
112 /* This only enables extension loading for the C api, not for SQL */
113 sqlite3_db_config(sqlite_handle, SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, 1, NULL);
114
115 if (sqlite3_load_extension(sqlite_handle, fullpath, 0, &errtext) != SQLITE_OK) {
116 zend_throw_exception_ex(php_pdo_get_exception(), 0, "Unable to load extension \"%s\"", errtext);
117 sqlite3_free(errtext);
118 sqlite3_db_config(sqlite_handle, SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, 0, NULL);
120 }
121
122 /* We disable extension loading for a vague feeling of safety. This is probably not necessary
123 as extensions can only be loaded through C code, not through SQL, and if someone can get
124 some C code to run on the server, they can do anything.*/
125 sqlite3_db_config(sqlite_handle, SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, 0, NULL);
126}
127#endif
128
129typedef struct {
130 sqlite3_blob *blob;
131 size_t position;
132 size_t size;
133 int flags;
135
136static ssize_t php_pdosqlite3_stream_write(php_stream *stream, const char *buf, size_t count)
137{
139
140 if (sqlite3_stream->flags & SQLITE_OPEN_READONLY) {
141 php_error_docref(NULL, E_WARNING, "Can't write to blob stream: is open as read only");
142 return -1;
143 }
144
145 if (sqlite3_stream->position + count > sqlite3_stream->size) {
146 php_error_docref(NULL, E_WARNING, "It is not possible to increase the size of a BLOB");
147 return -1;
148 }
149
150 if (sqlite3_blob_write(sqlite3_stream->blob, buf, count, sqlite3_stream->position) != SQLITE_OK) {
151 return -1;
152 }
153
154 if (sqlite3_stream->position + count >= sqlite3_stream->size) {
155 stream->eof = 1;
156 sqlite3_stream->position = sqlite3_stream->size;
157 }
158 else {
159 sqlite3_stream->position += count;
160 }
161
162 return count;
163}
164
165static ssize_t php_pdosqlite3_stream_read(php_stream *stream, char *buf, size_t count)
166{
168
169 if (sqlite3_stream->position + count >= sqlite3_stream->size) {
170 count = sqlite3_stream->size - sqlite3_stream->position;
171 stream->eof = 1;
172 }
173 if (count) {
174 if (sqlite3_blob_read(sqlite3_stream->blob, buf, count, sqlite3_stream->position) != SQLITE_OK) {
175 return -1;
176 }
177 sqlite3_stream->position += count;
178 }
179 return count;
180}
181
182static int php_pdosqlite3_stream_close(php_stream *stream, int close_handle)
183{
185
186 if (sqlite3_blob_close(sqlite3_stream->blob) != SQLITE_OK) {
187 /* Error occurred, but it still closed */
188 }
189
190 efree(sqlite3_stream);
191
192 return 0;
193}
194
195static int php_pdosqlite3_stream_flush(php_stream *stream)
196{
197 /* do nothing */
198 return 0;
199}
200
201static int php_pdosqlite3_stream_seek(php_stream *stream, zend_off_t offset, int whence, zend_off_t *newoffs)
202{
204
205 switch(whence) {
206 case SEEK_CUR:
207 if (offset < 0) {
208 if (sqlite3_stream->position < (size_t)(-offset)) {
209 sqlite3_stream->position = 0;
210 *newoffs = -1;
211 return -1;
212 } else {
213 sqlite3_stream->position = sqlite3_stream->position + offset;
214 *newoffs = sqlite3_stream->position;
215 stream->eof = 0;
216 return 0;
217 }
218 } else {
219 if (sqlite3_stream->position + (size_t)(offset) > sqlite3_stream->size) {
220 sqlite3_stream->position = sqlite3_stream->size;
221 *newoffs = -1;
222 return -1;
223 } else {
224 sqlite3_stream->position = sqlite3_stream->position + offset;
225 *newoffs = sqlite3_stream->position;
226 stream->eof = 0;
227 return 0;
228 }
229 }
230 case SEEK_SET:
231 if (sqlite3_stream->size < (size_t)(offset)) {
232 sqlite3_stream->position = sqlite3_stream->size;
233 *newoffs = -1;
234 return -1;
235 } else {
236 sqlite3_stream->position = offset;
237 *newoffs = sqlite3_stream->position;
238 stream->eof = 0;
239 return 0;
240 }
241 case SEEK_END:
242 if (offset > 0) {
243 sqlite3_stream->position = sqlite3_stream->size;
244 *newoffs = -1;
245 return -1;
246 } else if (sqlite3_stream->size < (size_t)(-offset)) {
247 sqlite3_stream->position = 0;
248 *newoffs = -1;
249 return -1;
250 } else {
251 sqlite3_stream->position = sqlite3_stream->size + offset;
252 *newoffs = sqlite3_stream->position;
253 stream->eof = 0;
254 return 0;
255 }
256 default:
257 *newoffs = sqlite3_stream->position;
258 return -1;
259 }
260}
261
262static int php_pdosqlite3_stream_cast(php_stream *stream, int castas, void **ret)
263{
264 return FAILURE;
265}
266
267static int php_pdosqlite3_stream_stat(php_stream *stream, php_stream_statbuf *ssb)
268{
270 ssb->sb.st_size = sqlite3_stream->size;
271 return 0;
272}
273
274static const php_stream_ops php_stream_pdosqlite3_ops = {
275 php_pdosqlite3_stream_write,
276 php_pdosqlite3_stream_read,
277 php_pdosqlite3_stream_close,
278 php_pdosqlite3_stream_flush,
279 "PDOSQLite",
280 php_pdosqlite3_stream_seek,
281 php_pdosqlite3_stream_cast,
282 php_pdosqlite3_stream_stat,
283 NULL
284};
285
286/* Open a blob as a stream which we can read / write to. */
287PHP_METHOD(Pdo_Sqlite, openBlob)
288{
289 char *table, *column, *dbname = "main", *mode = "rb";
290 size_t table_len, column_len, dbname_len;
291 zend_long rowid, flags = SQLITE_OPEN_READONLY, sqlite_flags = 0;
292 sqlite3_blob *blob = NULL;
293 php_stream_pdosqlite3_data *sqlite3_stream;
294 php_stream *stream;
295
296 pdo_dbh_t *dbh;
297 pdo_sqlite_db_handle *db_handle;
298
299 dbh = Z_PDO_DBH_P(ZEND_THIS);
301 db_handle = (pdo_sqlite_db_handle *)dbh->driver_data;
302
303 if (zend_parse_parameters(ZEND_NUM_ARGS(), "ppl|pl", &table, &table_len, &column, &column_len, &rowid, &dbname, &dbname_len, &flags) == FAILURE) {
305 }
306
307 sqlite3 *sqlite_handle;
308 sqlite_handle = db_handle->db;
309 sqlite_flags = (flags & SQLITE_OPEN_READWRITE) ? 1 : 0;
310
311 if (sqlite3_blob_open(sqlite_handle, dbname, table, column, rowid, sqlite_flags, &blob) != SQLITE_OK) {
312 zend_error(E_WARNING, "Unable to open blob: %s", sqlite3_errmsg(sqlite_handle));
314 }
315
316 sqlite3_stream = emalloc(sizeof(php_stream_pdosqlite3_data));
317 sqlite3_stream->blob = blob;
318 sqlite3_stream->flags = flags;
319 sqlite3_stream->position = 0;
320 sqlite3_stream->size = sqlite3_blob_bytes(blob);
321
322 if (sqlite_flags != 0) {
323 mode = "r+b";
324 }
325
326 stream = php_stream_alloc(&php_stream_pdosqlite3_ops, sqlite3_stream, 0, mode);
327
328 if (stream) {
330 } else {
332 }
333}
334
335static int php_sqlite_collation_callback(void *context, int string1_len, const void *string1,
336 int string2_len, const void *string2)
337{
338 int ret = 0;
339 zval zargs[2];
340 zval retval;
341 struct pdo_sqlite_collation *collation = (struct pdo_sqlite_collation*) context;
342
343 // Prepare the arguments.
344 ZVAL_STRINGL(&zargs[0], (char *) string1, string1_len);
345 ZVAL_STRINGL(&zargs[1], (char *) string2, string2_len);
346
347 zend_call_known_fcc(&collation->callback, &retval, /* argc */ 2, zargs, /* named_params */ NULL);
348
349 if (!Z_ISUNDEF(retval)) {
350 if (Z_TYPE(retval) != IS_LONG) {
352 zend_type_error("%s(): Return value of the callback must be of type int, %s returned",
354 zend_string_release(func_name);
356 return FAILURE;
357 }
358 if (Z_LVAL(retval) > 0) {
359 ret = 1;
360 } else if (Z_LVAL(retval) < 0) {
361 ret = -1;
362 }
363 }
364
365 zval_ptr_dtor(&zargs[0]);
366 zval_ptr_dtor(&zargs[1]);
367
368 return ret;
369}
370
375
376PHP_METHOD(Pdo_Sqlite, createCollation)
377{
379}
380
381/* {{{ PHP_MINIT_FUNCTION */
383{
384#ifdef SQLITE_DETERMINISTIC
385 REGISTER_PDO_CLASS_CONST_LONG("SQLITE_DETERMINISTIC", (zend_long)SQLITE_DETERMINISTIC);
386#endif
387
394
395 pdosqlite_ce = register_class_Pdo_Sqlite(pdo_dbh_ce);
396 pdosqlite_ce->create_object = pdo_dbh_new;
397
399 return FAILURE;
400 }
401
403}
404/* }}} */
405
406/* {{{ PHP_MSHUTDOWN_FUNCTION */
412/* }}} */
413
414/* {{{ PHP_MINFO_FUNCTION */
416{
418 php_info_print_table_row(2, "PDO Driver for SQLite 3.x", "enabled");
419 php_info_print_table_row(2, "SQLite Library", sqlite3_libversion());
421}
422/* }}} */
SAPI_API sapi_module_struct sapi_module
Definition SAPI.c:65
count(Countable|array $value, int $mode=COUNT_NORMAL)
zend_ffi_ctype_name_buf buf
Definition ffi.c:4685
const SEEK_CUR
Definition file.stub.php:16
const SEEK_END
Definition file.stub.php:21
zend_long offset
char * mode
#define SEEK_SET
Definition gd_io_file.c:20
#define NULL
Definition gdcache.h:45
#define SUCCESS
Definition hash_sha3.c:261
PHPAPI ZEND_COLD void php_error_docref(const char *docref, int type, const char *format,...)
Definition main.c:1173
PDO_API void php_pdo_unregister_driver(const pdo_driver_t *driver)
Definition pdo.c:129
PDO_API zend_result php_pdo_register_driver(const pdo_driver_t *driver)
Definition pdo.c:113
PDO_API zend_result php_pdo_register_driver_specific_ce(const pdo_driver_t *driver, zend_class_entry *ce)
Definition pdo.c:140
zend_class_entry * pdo_dbh_ce
Definition pdo.c:34
PDO_API zend_class_entry * php_pdo_get_exception(void)
Definition pdo.c:62
zend_object * pdo_dbh_new(zend_class_entry *ce)
Definition pdo_dbh.c:1533
php_info_print_table_start()
Definition info.c:1064
php_info_print_table_row(2, "PDO Driver for Firebird", "enabled")
php_info_print_table_end()
Definition info.c:1074
zend_module_entry pdo_sqlite_module_entry
Definition pdo_sqlite.c:42
#define PHP_MSHUTDOWN_FUNCTION
Definition php.h:401
#define PHP_MINFO
Definition php.h:396
#define PHP_MINIT_FUNCTION
Definition php.h:400
#define PHP_MSHUTDOWN
Definition php.h:393
#define PHP_MINFO_FUNCTION
Definition php.h:404
#define PHP_MINIT
Definition php.h:392
#define PHP_METHOD
Definition php.h:365
#define PDO_CONSTRUCT_CHECK
Definition php_pdo.h:64
#define REGISTER_PDO_CLASS_CONST_LONG(const_name, value)
Definition php_pdo.h:53
struct _pdo_dbh_t pdo_dbh_t
#define Z_PDO_DBH_P(zv)
#define PHP_PDO_SQLITE_VERSION
@ PDO_SQLITE_ATTR_READONLY_STATEMENT
@ PDO_SQLITE_ATTR_OPEN_FLAGS
@ PDO_SQLITE_ATTR_EXTENDED_RESULT_CODES
void pdo_sqlite_create_function_internal(INTERNAL_FUNCTION_PARAMETERS)
void pdo_sqlite_create_collation_internal(INTERNAL_FUNCTION_PARAMETERS, pdo_sqlite_create_collation_callback callback)
const pdo_driver_t pdo_sqlite_driver
void pdo_sqlite_create_aggregate_internal(INTERNAL_FUNCTION_PARAMETERS)
#define SQLITE_OPEN_CREATE
#define SQLITE_OPEN_READWRITE
#define SQLITE_OPEN_READONLY
struct _php_stream php_stream
Definition php_streams.h:96
#define php_stream_to_zval(stream, zval)
struct _php_stream_ops php_stream_ops
#define php_stream_alloc(ops, thisptr, persistent_id, mode)
struct _php_stream_statbuf php_stream_statbuf
const char * func_name
void * driver_data
uint16_t eof
void * abstract
Definition dce.c:49
zend_fcall_info_cache callback
ZEND_API ZEND_COLD void zend_type_error(const char *format,...)
Definition zend.c:1824
ZEND_API ZEND_COLD void zend_error(int type, const char *format,...)
Definition zend.c:1666
#define INTERNAL_FUNCTION_PARAM_PASSTHRU
Definition zend.h:50
ZEND_API const char * zend_zval_value_name(const zval *arg)
Definition zend_API.c:148
ZEND_API zend_result zend_parse_parameters(uint32_t num_args, const char *type_spec,...)
Definition zend_API.c:1300
ZEND_API ZEND_COLD void zend_argument_must_not_be_empty_error(uint32_t arg_num)
Definition zend_API.c:443
#define ZEND_NUM_ARGS()
Definition zend_API.h:530
#define RETURN_FALSE
Definition zend_API.h:1058
#define ZEND_GET_MODULE(name)
Definition zend_API.h:241
#define RETURN_THROWS()
Definition zend_API.h:1060
#define ZEND_THIS
Definition zend_API.h:523
#define ZVAL_STRINGL(z, s, l)
Definition zend_API.h:952
#define efree(ptr)
Definition zend_alloc.h:155
#define emalloc(size)
Definition zend_alloc.h:151
struct _zval_struct zval
strncmp(string $string1, string $string2, int $length)
strcmp(string $string1, string $string2)
#define E_WARNING
Definition zend_errors.h:24
ZEND_API ZEND_COLD zend_object * zend_throw_exception_ex(zend_class_entry *exception_ce, zend_long code, const char *format,...)
ZEND_API zend_string * get_active_function_or_method_name(void)
int32_t zend_long
Definition zend_long.h:42
int32_t zend_off_t
Definition zend_long.h:44
struct _zend_string zend_string
#define ZEND_MOD_END
struct _zend_module_dep zend_module_dep
struct _zend_module_entry zend_module_entry
#define STANDARD_MODULE_PROPERTIES
#define ZEND_MOD_REQUIRED(name)
#define STANDARD_MODULE_HEADER_EX
struct _zend_class_entry zend_class_entry
#define ZSTR_VAL(zstr)
Definition zend_string.h:68
#define Z_ISUNDEF(zval)
Definition zend_types.h:956
@ FAILURE
Definition zend_types.h:61
#define IS_LONG
Definition zend_types.h:604
#define Z_TYPE(zval)
Definition zend_types.h:659
#define Z_LVAL(zval)
Definition zend_types.h:965
ZEND_API void zval_ptr_dtor(zval *zval_ptr)
#define MAXPATHLEN
#define VCWD_REALPATH(path, real_path)
zval retval
zval * return_value
zval * ret