2008-07-25 10:44:59 +08:00
/*
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| PHP Version 5 |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2014-01-03 11:06:16 +08:00
| Copyright ( c ) 1997 - 2014 The PHP Group |
2008-07-25 10:44:59 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| This source file is subject to version 3.01 of the PHP license , |
| that is bundled with this package in the file LICENSE , and is |
| available through the world - wide - web at the following url : |
| http : //www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world - wide - web , please send a note to |
| license @ php . net so we can mail you a copy immediately . |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Authors : Scott MacVicar < scottmac @ php . net > |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
*/
2008-07-27 07:42:53 +08:00
/* $Id$ */
2008-07-25 10:44:59 +08:00
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
# include "php.h"
# include "php_ini.h"
# include "ext/standard/info.h"
# include "php_sqlite3.h"
2008-07-27 07:58:06 +08:00
# include "php_sqlite3_structs.h"
2009-05-08 06:42:46 +08:00
# include "main/SAPI.h"
2008-07-25 10:44:59 +08:00
# include <sqlite3.h>
# include "zend_exceptions.h"
# include "zend_interfaces.h"
2009-05-08 15:58:19 +08:00
# include "SAPI.h"
2008-07-25 10:44:59 +08:00
ZEND_DECLARE_MODULE_GLOBALS ( sqlite3 )
2008-07-27 07:42:53 +08:00
2008-07-25 10:44:59 +08:00
static PHP_GINIT_FUNCTION ( sqlite3 ) ;
2008-07-27 07:42:53 +08:00
static int php_sqlite3_authorizer ( void * autharg , int access_type , const char * arg3 , const char * arg4 , const char * arg5 , const char * arg6 ) ;
2008-07-25 10:44:59 +08:00
static void sqlite3_param_dtor ( void * data ) ;
2011-01-04 03:15:36 +08:00
static int php_sqlite3_compare_stmt_zval_free ( php_sqlite3_free_list * * free_list , zval * statement ) ;
2008-07-25 10:44:59 +08:00
2009-04-28 02:16:46 +08:00
/* {{{ Error Handler
*/
static void php_sqlite3_error ( php_sqlite3_db_object * db_obj , char * format , . . . )
{
va_list arg ;
char * message ;
TSRMLS_FETCH ( ) ;
va_start ( arg , format ) ;
vspprintf ( & message , 0 , format , arg ) ;
va_end ( arg ) ;
if ( db_obj - > exception ) {
zend_throw_exception ( zend_exception_get_default ( TSRMLS_C ) , message , 0 TSRMLS_CC ) ;
} else {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " %s " , message ) ;
}
if ( message ) {
efree ( message ) ;
}
}
/* }}} */
# define SQLITE3_CHECK_INITIALIZED(db_obj, member, class_name) \
2008-07-25 10:44:59 +08:00
if ( ! ( member ) ) { \
2009-04-28 02:16:46 +08:00
php_sqlite3_error ( db_obj , " The " # class_name " object has not been correctly initialised " ) ; \
2008-07-25 10:44:59 +08:00
RETURN_FALSE ; \
}
/* {{{ PHP_INI
2008-07-27 07:42:53 +08:00
*/
2008-07-25 10:44:59 +08:00
PHP_INI_BEGIN ( )
STD_PHP_INI_ENTRY ( " sqlite3.extension_dir " , NULL , PHP_INI_SYSTEM , OnUpdateString , extension_dir , zend_sqlite3_globals , sqlite3_globals )
PHP_INI_END ( )
/* }}} */
/* Handlers */
static zend_object_handlers sqlite3_object_handlers ;
static zend_object_handlers sqlite3_stmt_object_handlers ;
static zend_object_handlers sqlite3_result_object_handlers ;
/* Class entries */
zend_class_entry * php_sqlite3_sc_entry ;
zend_class_entry * php_sqlite3_stmt_entry ;
zend_class_entry * php_sqlite3_result_entry ;
2011-05-10 16:14:55 +08:00
/* {{{ proto void SQLite3::open(String filename [, int Flags [, string Encryption Key]])
2008-07-27 07:42:53 +08:00
Opens a SQLite 3 Database , if the build includes encryption then it will attempt to use the key . */
2008-07-25 10:44:59 +08:00
PHP_METHOD ( sqlite3 , open )
{
php_sqlite3_db_object * db_obj ;
zval * object = getThis ( ) ;
char * filename , * encryption_key , * fullpath ;
2009-01-05 00:31:12 +08:00
int filename_len , encryption_key_len = 0 ;
2008-08-01 16:27:56 +08:00
long flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE ;
2009-02-10 08:24:33 +08:00
zend_error_handling error_handling ;
2008-07-25 10:44:59 +08:00
db_obj = ( php_sqlite3_db_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
2009-02-10 08:24:33 +08:00
zend_replace_error_handling ( EH_THROW , NULL , & error_handling TSRMLS_CC ) ;
2008-07-25 10:44:59 +08:00
2011-06-07 05:28:16 +08:00
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " p|ls " , & filename , & filename_len , & flags , & encryption_key , & encryption_key_len ) ) {
2009-02-10 08:24:33 +08:00
zend_restore_error_handling ( & error_handling TSRMLS_CC ) ;
2008-07-25 10:44:59 +08:00
return ;
}
2009-02-10 08:24:33 +08:00
zend_restore_error_handling ( & error_handling TSRMLS_CC ) ;
2008-07-25 10:44:59 +08:00
if ( db_obj - > initialised ) {
2009-02-10 08:24:33 +08:00
zend_throw_exception ( zend_exception_get_default ( TSRMLS_C ) , " Already initialised DB Object " , 0 TSRMLS_CC ) ;
2008-07-25 10:44:59 +08:00
}
2010-11-18 23:22:22 +08:00
if ( strlen ( filename ) ! = filename_len ) {
return ;
}
2012-06-22 18:48:39 +08:00
if ( memcmp ( filename , " :memory: " , sizeof ( " :memory: " ) ) ! = 0 ) {
2008-07-25 10:44:59 +08:00
if ( ! ( fullpath = expand_filepath ( filename , NULL TSRMLS_CC ) ) ) {
2009-02-10 08:24:33 +08:00
zend_throw_exception ( zend_exception_get_default ( TSRMLS_C ) , " Unable to expand filepath " , 0 TSRMLS_CC ) ;
return ;
2008-07-25 10:44:59 +08:00
}
2010-04-27 07:53:30 +08:00
# if PHP_API_VERSION < 20100412
2008-07-25 10:44:59 +08:00
if ( PG ( safe_mode ) & & ( ! php_checkuid ( fullpath , NULL , CHECKUID_CHECK_FILE_AND_DIR ) ) ) {
2009-02-10 08:24:33 +08:00
zend_throw_exception_ex ( zend_exception_get_default ( TSRMLS_C ) , 0 TSRMLS_CC , " safe_mode prohibits opening %s " , fullpath ) ;
2008-07-25 10:44:59 +08:00
efree ( fullpath ) ;
2009-02-10 08:24:33 +08:00
return ;
2008-07-25 10:44:59 +08:00
}
2010-04-27 07:53:30 +08:00
# endif
2008-07-25 10:44:59 +08:00
if ( php_check_open_basedir ( fullpath TSRMLS_CC ) ) {
2009-02-10 08:24:33 +08:00
zend_throw_exception_ex ( zend_exception_get_default ( TSRMLS_C ) , 0 TSRMLS_CC , " open_basedir prohibits opening %s " , fullpath ) ;
2008-07-25 10:44:59 +08:00
efree ( fullpath ) ;
2009-02-10 08:24:33 +08:00
return ;
2008-07-25 10:44:59 +08:00
}
} else {
fullpath = estrdup ( filename ) ;
}
# if SQLITE_VERSION_NUMBER >= 3005000
if ( sqlite3_open_v2 ( fullpath , & ( db_obj - > db ) , flags , NULL ) ! = SQLITE_OK ) {
# else
if ( sqlite3_open ( fullpath , & ( db_obj - > db ) ) ! = SQLITE_OK ) {
# endif
2009-02-10 08:24:33 +08:00
zend_throw_exception_ex ( zend_exception_get_default ( TSRMLS_C ) , 0 TSRMLS_CC , " Unable to open database: %s " , sqlite3_errmsg ( db_obj - > db ) ) ;
2008-07-25 10:44:59 +08:00
if ( fullpath ) {
efree ( fullpath ) ;
}
return ;
}
# if SQLITE_HAS_CODEC
if ( encryption_key_len > 0 ) {
if ( sqlite3_key ( db_obj - > db , encryption_key , encryption_key_len ) ! = SQLITE_OK ) {
2009-02-10 08:24:33 +08:00
zend_throw_exception_ex ( zend_exception_get_default ( TSRMLS_C ) , 0 TSRMLS_CC , " Unable to open database: %s " , sqlite3_errmsg ( db_obj - > db ) ) ;
2008-07-25 10:44:59 +08:00
return ;
}
}
# endif
2011-01-04 03:15:36 +08:00
db_obj - > initialised = 1 ;
2010-04-27 07:53:30 +08:00
# if PHP_API_VERSION < 20100412
2008-07-27 07:42:53 +08:00
if ( PG ( safe_mode ) | | ( PG ( open_basedir ) & & * PG ( open_basedir ) ) ) {
2010-04-27 07:53:30 +08:00
# else
if ( PG ( open_basedir ) & & * PG ( open_basedir ) ) {
# endif
2008-07-25 10:44:59 +08:00
sqlite3_set_authorizer ( db_obj - > db , php_sqlite3_authorizer , NULL ) ;
}
if ( fullpath ) {
efree ( fullpath ) ;
}
}
/* }}} */
/* {{{ proto bool SQLite3::close()
2008-07-27 07:42:53 +08:00
Close a SQLite 3 Database . */
2008-07-25 10:44:59 +08:00
PHP_METHOD ( sqlite3 , close )
{
php_sqlite3_db_object * db_obj ;
zval * object = getThis ( ) ;
int errcode ;
db_obj = ( php_sqlite3_db_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
}
if ( db_obj - > initialised ) {
2008-07-29 08:56:53 +08:00
zend_llist_clean ( & ( db_obj - > free_list ) ) ;
2008-07-25 10:44:59 +08:00
errcode = sqlite3_close ( db_obj - > db ) ;
if ( errcode ! = SQLITE_OK ) {
2009-04-28 02:16:46 +08:00
php_sqlite3_error ( db_obj , " Unable to close database: %d, %s " , errcode , sqlite3_errmsg ( db_obj - > db ) ) ;
2008-07-25 10:44:59 +08:00
RETURN_FALSE ;
}
db_obj - > initialised = 0 ;
}
RETURN_TRUE ;
}
/* }}} */
/* {{{ proto bool SQLite3::exec(String Query)
2008-07-27 07:42:53 +08:00
Executes a result - less query against a given database . */
2008-07-25 10:44:59 +08:00
PHP_METHOD ( sqlite3 , exec )
{
php_sqlite3_db_object * db_obj ;
zval * object = getThis ( ) ;
char * sql , * errtext = NULL ;
int sql_len ;
db_obj = ( php_sqlite3_db_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
2009-04-28 02:16:46 +08:00
SQLITE3_CHECK_INITIALIZED ( db_obj , db_obj - > initialised , SQLite3 )
2008-07-25 10:44:59 +08:00
2008-07-27 07:42:53 +08:00
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " s " , & sql , & sql_len ) ) {
2008-07-25 10:44:59 +08:00
return ;
}
if ( sqlite3_exec ( db_obj - > db , sql , NULL , NULL , & errtext ) ! = SQLITE_OK ) {
2009-04-28 02:16:46 +08:00
php_sqlite3_error ( db_obj , " %s " , errtext ) ;
2008-07-25 10:44:59 +08:00
sqlite3_free ( errtext ) ;
RETURN_FALSE ;
}
RETURN_TRUE ;
}
/* }}} */
/* {{{ proto Array SQLite3::version()
2008-07-27 07:42:53 +08:00
Returns the SQLite3 Library version as a string constant and as a number . */
2008-07-25 10:44:59 +08:00
PHP_METHOD ( sqlite3 , version )
{
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
}
array_init ( return_value ) ;
add_assoc_string ( return_value , " versionString " , ( char * ) sqlite3_libversion ( ) , 1 ) ;
add_assoc_long ( return_value , " versionNumber " , sqlite3_libversion_number ( ) ) ;
return ;
}
/* }}} */
/* {{{ proto int SQLite3::lastInsertRowID()
2008-07-27 07:42:53 +08:00
Returns the rowid of the most recent INSERT into the database from the database connection . */
2008-07-25 10:44:59 +08:00
PHP_METHOD ( sqlite3 , lastInsertRowID )
{
php_sqlite3_db_object * db_obj ;
zval * object = getThis ( ) ;
db_obj = ( php_sqlite3_db_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
2009-04-28 02:16:46 +08:00
SQLITE3_CHECK_INITIALIZED ( db_obj , db_obj - > initialised , SQLite3 )
2008-07-25 10:44:59 +08:00
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
}
RETURN_LONG ( sqlite3_last_insert_rowid ( db_obj - > db ) ) ;
}
/* }}} */
/* {{{ proto int SQLite3::lastErrorCode()
2008-07-27 07:42:53 +08:00
Returns the numeric result code of the most recent failed sqlite API call for the database connection . */
2008-07-25 10:44:59 +08:00
PHP_METHOD ( sqlite3 , lastErrorCode )
{
php_sqlite3_db_object * db_obj ;
zval * object = getThis ( ) ;
db_obj = ( php_sqlite3_db_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
2009-04-28 02:16:46 +08:00
SQLITE3_CHECK_INITIALIZED ( db_obj , db_obj - > db , SQLite3 )
2008-07-25 10:44:59 +08:00
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
}
RETURN_LONG ( sqlite3_errcode ( db_obj - > db ) ) ;
}
/* }}} */
/* {{{ proto string SQLite3::lastErrorMsg()
2008-07-27 07:42:53 +08:00
Returns english text describing the most recent failed sqlite API call for the database connection . */
2008-07-25 10:44:59 +08:00
PHP_METHOD ( sqlite3 , lastErrorMsg )
{
php_sqlite3_db_object * db_obj ;
zval * object = getThis ( ) ;
db_obj = ( php_sqlite3_db_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
2009-04-28 02:16:46 +08:00
SQLITE3_CHECK_INITIALIZED ( db_obj , db_obj - > db , SQLite3 )
2008-07-25 10:44:59 +08:00
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
}
RETVAL_STRING ( ( char * ) sqlite3_errmsg ( db_obj - > db ) , 1 ) ;
}
/* }}} */
2010-06-20 23:30:49 +08:00
/* {{{ proto bool SQLite3::busyTimeout(int msecs)
Sets a busy handler that will sleep until database is not locked or timeout is reached . Passing a value less than or equal to zero turns off all busy handlers . */
PHP_METHOD ( sqlite3 , busyTimeout )
{
php_sqlite3_db_object * db_obj ;
zval * object = getThis ( ) ;
long ms ;
int return_code ;
db_obj = ( php_sqlite3_db_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
SQLITE3_CHECK_INITIALIZED ( db_obj , db_obj - > initialised , SQLite3 )
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " l " , & ms ) ) {
return ;
}
return_code = sqlite3_busy_timeout ( db_obj - > db , ms ) ;
if ( return_code ! = SQLITE_OK ) {
php_sqlite3_error ( db_obj , " Unable to set busy timeout: %d, %s " , return_code , sqlite3_errmsg ( db_obj - > db ) ) ;
RETURN_FALSE ;
}
RETURN_TRUE ;
}
/* }}} */
2009-03-17 10:45:12 +08:00
# ifndef SQLITE_OMIT_LOAD_EXTENSION
2008-07-25 10:44:59 +08:00
/* {{{ proto bool SQLite3::loadExtension(String Shared Library)
2008-07-27 07:42:53 +08:00
Attempts to load an SQLite extension library . */
2008-07-25 10:44:59 +08:00
PHP_METHOD ( sqlite3 , loadExtension )
{
php_sqlite3_db_object * db_obj ;
zval * object = getThis ( ) ;
char * extension , * lib_path , * extension_dir , * errtext = NULL ;
char fullpath [ MAXPATHLEN ] ;
int extension_len , extension_dir_len ;
db_obj = ( php_sqlite3_db_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
2009-04-28 02:16:46 +08:00
SQLITE3_CHECK_INITIALIZED ( db_obj , db_obj - > initialised , SQLite3 )
2008-07-25 10:44:59 +08:00
2008-07-27 07:42:53 +08:00
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " s " , & extension , & extension_len ) ) {
2008-07-25 10:44:59 +08:00
return ;
}
2009-05-08 00:49:26 +08:00
# ifdef ZTS
if ( ( strncmp ( sapi_module . name , " cgi " , 3 ) ! = 0 ) & &
( strcmp ( sapi_module . name , " cli " ) ! = 0 ) & &
( strncmp ( sapi_module . name , " embed " , 5 ) ! = 0 )
) { php_sqlite3_error ( db_obj , " Not supported in multithreaded Web servers " ) ;
RETURN_FALSE ;
}
# endif
2008-07-25 10:44:59 +08:00
if ( ! SQLITE3G ( extension_dir ) ) {
2009-04-28 02:16:46 +08:00
php_sqlite3_error ( db_obj , " SQLite Extension are disabled " ) ;
2008-07-25 10:44:59 +08:00
RETURN_FALSE ;
}
if ( extension_len = = 0 ) {
2009-04-28 02:16:46 +08:00
php_sqlite3_error ( db_obj , " Empty string as an extension " ) ;
2008-07-25 10:44:59 +08:00
RETURN_FALSE ;
}
extension_dir = SQLITE3G ( extension_dir ) ;
extension_dir_len = strlen ( SQLITE3G ( extension_dir ) ) ;
if ( IS_SLASH ( extension_dir [ extension_dir_len - 1 ] ) ) {
spprintf ( & lib_path , 0 , " %s%s " , extension_dir , extension ) ;
} else {
spprintf ( & lib_path , 0 , " %s%c%s " , extension_dir , DEFAULT_SLASH , extension ) ;
}
if ( ! VCWD_REALPATH ( lib_path , fullpath ) ) {
2009-04-28 02:16:46 +08:00
php_sqlite3_error ( db_obj , " Unable to load extension at '%s' " , lib_path ) ;
2008-07-25 10:44:59 +08:00
efree ( lib_path ) ;
RETURN_FALSE ;
}
efree ( lib_path ) ;
if ( strncmp ( fullpath , extension_dir , extension_dir_len ) ! = 0 ) {
2009-04-28 02:16:46 +08:00
php_sqlite3_error ( db_obj , " Unable to open extensions outside the defined directory " ) ;
2008-07-25 10:44:59 +08:00
RETURN_FALSE ;
}
/* Extension loading should only be enabled for when we attempt to load */
sqlite3_enable_load_extension ( db_obj - > db , 1 ) ;
if ( sqlite3_load_extension ( db_obj - > db , fullpath , 0 , & errtext ) ! = SQLITE_OK ) {
2009-04-28 02:16:46 +08:00
php_sqlite3_error ( db_obj , " %s " , errtext ) ;
2008-07-25 10:44:59 +08:00
sqlite3_free ( errtext ) ;
sqlite3_enable_load_extension ( db_obj - > db , 0 ) ;
RETURN_FALSE ;
}
sqlite3_enable_load_extension ( db_obj - > db , 0 ) ;
RETURN_TRUE ;
}
/* }}} */
2009-03-17 10:45:12 +08:00
# endif
2008-07-25 10:44:59 +08:00
/* {{{ proto int SQLite3::changes()
2008-07-27 07:42:53 +08:00
Returns the number of database rows that were changed ( or inserted or deleted ) by the most recent SQL statement . */
2008-07-25 10:44:59 +08:00
PHP_METHOD ( sqlite3 , changes )
{
php_sqlite3_db_object * db_obj ;
zval * object = getThis ( ) ;
db_obj = ( php_sqlite3_db_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
2009-04-28 02:16:46 +08:00
SQLITE3_CHECK_INITIALIZED ( db_obj , db_obj - > initialised , SQLite3 )
2008-07-25 10:44:59 +08:00
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
}
RETURN_LONG ( sqlite3_changes ( db_obj - > db ) ) ;
}
/* }}} */
/* {{{ proto String SQLite3::escapeString(String value)
2008-07-27 07:42:53 +08:00
Returns a string that has been properly escaped . */
2008-07-25 10:44:59 +08:00
PHP_METHOD ( sqlite3 , escapeString )
{
char * sql , * ret ;
int sql_len ;
2008-07-27 07:42:53 +08:00
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " s " , & sql , & sql_len ) ) {
2008-07-25 10:44:59 +08:00
return ;
}
if ( sql_len ) {
ret = sqlite3_mprintf ( " %q " , sql ) ;
if ( ret ) {
RETVAL_STRING ( ret , 1 ) ;
sqlite3_free ( ret ) ;
}
} else {
RETURN_EMPTY_STRING ( ) ;
}
}
/* }}} */
2008-08-01 06:30:26 +08:00
/* {{{ proto SQLite3Stmt SQLite3::prepare(String Query)
2008-07-27 07:42:53 +08:00
Returns a prepared SQL statement for execution . */
2008-07-25 10:44:59 +08:00
PHP_METHOD ( sqlite3 , prepare )
{
php_sqlite3_db_object * db_obj ;
php_sqlite3_stmt * stmt_obj ;
zval * object = getThis ( ) ;
char * sql ;
int sql_len , errcode ;
2009-01-20 17:57:34 +08:00
php_sqlite3_free_list * free_item ;
2008-07-25 10:44:59 +08:00
db_obj = ( php_sqlite3_db_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
2009-04-28 02:16:46 +08:00
SQLITE3_CHECK_INITIALIZED ( db_obj , db_obj - > initialised , SQLite3 )
2008-07-25 10:44:59 +08:00
2008-07-27 07:42:53 +08:00
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " s " , & sql , & sql_len ) ) {
2008-07-25 10:44:59 +08:00
return ;
}
if ( ! sql_len ) {
RETURN_FALSE ;
}
object_init_ex ( return_value , php_sqlite3_stmt_entry ) ;
stmt_obj = ( php_sqlite3_stmt * ) zend_object_store_get_object ( return_value TSRMLS_CC ) ;
stmt_obj - > db_obj = db_obj ;
stmt_obj - > db_obj_zval = getThis ( ) ;
Z_ADDREF_P ( object ) ;
2009-01-20 17:57:34 +08:00
2008-07-25 10:44:59 +08:00
errcode = sqlite3_prepare_v2 ( db_obj - > db , sql , sql_len , & ( stmt_obj - > stmt ) , NULL ) ;
if ( errcode ! = SQLITE_OK ) {
2009-04-28 02:16:46 +08:00
php_sqlite3_error ( db_obj , " Unable to prepare statement: %d, %s " , errcode , sqlite3_errmsg ( db_obj - > db ) ) ;
2008-07-25 10:44:59 +08:00
zval_dtor ( return_value ) ;
RETURN_FALSE ;
}
2009-01-20 17:57:34 +08:00
2008-07-29 08:56:53 +08:00
stmt_obj - > initialised = 1 ;
2009-01-20 17:57:34 +08:00
free_item = emalloc ( sizeof ( php_sqlite3_free_list ) ) ;
free_item - > stmt_obj = stmt_obj ;
free_item - > stmt_obj_zval = return_value ;
zend_llist_add_element ( & ( db_obj - > free_list ) , & free_item ) ;
2008-07-25 10:44:59 +08:00
}
/* }}} */
2008-08-01 06:30:26 +08:00
/* {{{ proto SQLite3Result SQLite3::query(String Query)
Returns true or false , for queries that return data it will return a SQLite3Result object . */
2008-07-25 10:44:59 +08:00
PHP_METHOD ( sqlite3 , query )
{
php_sqlite3_db_object * db_obj ;
php_sqlite3_result * result ;
php_sqlite3_stmt * stmt_obj ;
zval * object = getThis ( ) ;
zval * stmt = NULL ;
char * sql , * errtext = NULL ;
int sql_len , return_code ;
db_obj = ( php_sqlite3_db_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
2009-04-28 02:16:46 +08:00
SQLITE3_CHECK_INITIALIZED ( db_obj , db_obj - > initialised , SQLite3 )
2008-07-25 10:44:59 +08:00
2008-07-27 07:42:53 +08:00
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " s " , & sql , & sql_len ) ) {
2008-07-25 10:44:59 +08:00
return ;
}
if ( ! sql_len ) {
RETURN_FALSE ;
}
/* If there was no return value then just execute the query */
if ( ! return_value_used ) {
if ( sqlite3_exec ( db_obj - > db , sql , NULL , NULL , & errtext ) ! = SQLITE_OK ) {
2009-04-28 02:16:46 +08:00
php_sqlite3_error ( db_obj , " %s " , errtext ) ;
2008-07-25 10:44:59 +08:00
sqlite3_free ( errtext ) ;
}
return ;
}
MAKE_STD_ZVAL ( stmt ) ;
object_init_ex ( stmt , php_sqlite3_stmt_entry ) ;
stmt_obj = ( php_sqlite3_stmt * ) zend_object_store_get_object ( stmt TSRMLS_CC ) ;
stmt_obj - > db_obj = db_obj ;
stmt_obj - > db_obj_zval = getThis ( ) ;
Z_ADDREF_P ( object ) ;
return_code = sqlite3_prepare_v2 ( db_obj - > db , sql , sql_len , & ( stmt_obj - > stmt ) , NULL ) ;
if ( return_code ! = SQLITE_OK ) {
2009-04-28 02:16:46 +08:00
php_sqlite3_error ( db_obj , " Unable to prepare statement: %d, %s " , return_code , sqlite3_errmsg ( db_obj - > db ) ) ;
2008-07-25 10:44:59 +08:00
zval_ptr_dtor ( & stmt ) ;
RETURN_FALSE ;
}
2008-07-29 08:56:53 +08:00
stmt_obj - > initialised = 1 ;
2008-07-25 10:44:59 +08:00
object_init_ex ( return_value , php_sqlite3_result_entry ) ;
result = ( php_sqlite3_result * ) zend_object_store_get_object ( return_value TSRMLS_CC ) ;
result - > db_obj = db_obj ;
result - > stmt_obj = stmt_obj ;
result - > stmt_obj_zval = stmt ;
return_code = sqlite3_step ( result - > stmt_obj - > stmt ) ;
switch ( return_code ) {
case SQLITE_ROW : /* Valid Row */
case SQLITE_DONE : /* Valid but no results */
{
2008-07-29 08:56:53 +08:00
php_sqlite3_free_list * free_item ;
free_item = emalloc ( sizeof ( php_sqlite3_free_list ) ) ;
free_item - > stmt_obj = stmt_obj ;
free_item - > stmt_obj_zval = stmt ;
zend_llist_add_element ( & ( db_obj - > free_list ) , & free_item ) ;
2008-07-25 10:44:59 +08:00
sqlite3_reset ( result - > stmt_obj - > stmt ) ;
break ;
}
default :
2009-04-28 02:16:46 +08:00
php_sqlite3_error ( db_obj , " Unable to execute statement: %s " , sqlite3_errmsg ( db_obj - > db ) ) ;
2008-07-29 08:56:53 +08:00
sqlite3_finalize ( stmt_obj - > stmt ) ;
stmt_obj - > initialised = 0 ;
2008-07-25 10:44:59 +08:00
zval_dtor ( return_value ) ;
RETURN_FALSE ;
}
}
/* }}} */
2008-07-27 07:42:53 +08:00
static zval * sqlite_value_to_zval ( sqlite3_stmt * stmt , int column ) /* { { { */
2008-07-25 10:44:59 +08:00
{
zval * data ;
MAKE_STD_ZVAL ( data ) ;
switch ( sqlite3_column_type ( stmt , column ) ) {
case SQLITE_INTEGER :
if ( ( sqlite3_column_int64 ( stmt , column ) ) > = INT_MAX | | sqlite3_column_int64 ( stmt , column ) < = INT_MIN ) {
ZVAL_STRINGL ( data , ( char * ) sqlite3_column_text ( stmt , column ) , sqlite3_column_bytes ( stmt , column ) , 1 ) ;
} else {
ZVAL_LONG ( data , sqlite3_column_int64 ( stmt , column ) ) ;
}
break ;
case SQLITE_FLOAT :
ZVAL_DOUBLE ( data , sqlite3_column_double ( stmt , column ) ) ;
break ;
case SQLITE_NULL :
ZVAL_NULL ( data ) ;
break ;
case SQLITE3_TEXT :
ZVAL_STRING ( data , ( char * ) sqlite3_column_text ( stmt , column ) , 1 ) ;
break ;
case SQLITE_BLOB :
default :
ZVAL_STRINGL ( data , ( char * ) sqlite3_column_blob ( stmt , column ) , sqlite3_column_bytes ( stmt , column ) , 1 ) ;
}
return data ;
}
2008-07-27 07:42:53 +08:00
/* }}} */
2008-07-25 10:44:59 +08:00
2008-11-18 03:34:03 +08:00
/* {{{ proto SQLite3Result SQLite3::querySingle(String Query [, bool entire_row = false])
2008-07-27 07:42:53 +08:00
Returns a string of the first column , or an array of the entire row . */
2008-07-25 10:44:59 +08:00
PHP_METHOD ( sqlite3 , querySingle )
{
php_sqlite3_db_object * db_obj ;
zval * object = getThis ( ) ;
char * sql , * errtext = NULL ;
2008-08-01 16:27:56 +08:00
int sql_len , return_code ;
zend_bool entire_row = 0 ;
2008-07-25 10:44:59 +08:00
sqlite3_stmt * stmt ;
db_obj = ( php_sqlite3_db_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
2009-04-28 02:16:46 +08:00
SQLITE3_CHECK_INITIALIZED ( db_obj , db_obj - > initialised , SQLite3 )
2008-07-25 10:44:59 +08:00
2008-07-27 07:42:53 +08:00
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " s|b " , & sql , & sql_len , & entire_row ) ) {
2008-07-25 10:44:59 +08:00
return ;
}
if ( ! sql_len ) {
RETURN_FALSE ;
}
/* If there was no return value then just execute the query */
if ( ! return_value_used ) {
if ( sqlite3_exec ( db_obj - > db , sql , NULL , NULL , & errtext ) ! = SQLITE_OK ) {
2009-04-28 02:16:46 +08:00
php_sqlite3_error ( db_obj , " %s " , errtext ) ;
2008-07-25 10:44:59 +08:00
sqlite3_free ( errtext ) ;
}
return ;
}
return_code = sqlite3_prepare_v2 ( db_obj - > db , sql , sql_len , & stmt , NULL ) ;
if ( return_code ! = SQLITE_OK ) {
2009-04-28 02:16:46 +08:00
php_sqlite3_error ( db_obj , " Unable to prepare statement: %d, %s " , return_code , sqlite3_errmsg ( db_obj - > db ) ) ;
2008-07-25 10:44:59 +08:00
RETURN_FALSE ;
}
return_code = sqlite3_step ( stmt ) ;
switch ( return_code ) {
case SQLITE_ROW : /* Valid Row */
{
if ( ! entire_row ) {
zval * data ;
data = sqlite_value_to_zval ( stmt , 0 ) ;
* return_value = * data ;
zval_copy_ctor ( return_value ) ;
zval_dtor ( data ) ;
FREE_ZVAL ( data ) ;
} else {
int i = 0 ;
array_init ( return_value ) ;
for ( i = 0 ; i < sqlite3_data_count ( stmt ) ; i + + ) {
zval * data ;
data = sqlite_value_to_zval ( stmt , i ) ;
add_assoc_zval ( return_value , ( char * ) sqlite3_column_name ( stmt , i ) , data ) ;
}
}
break ;
}
case SQLITE_DONE : /* Valid but no results */
{
if ( ! entire_row ) {
RETVAL_NULL ( ) ;
} else {
array_init ( return_value ) ;
}
break ;
}
default :
2009-04-28 02:16:46 +08:00
php_sqlite3_error ( db_obj , " Unable to execute statement: %s " , sqlite3_errmsg ( db_obj - > db ) ) ;
2008-07-25 10:44:59 +08:00
RETVAL_FALSE ;
}
sqlite3_finalize ( stmt ) ;
}
/* }}} */
2008-07-27 07:42:53 +08:00
static int sqlite3_do_callback ( struct php_sqlite3_fci * fc , zval * cb , int argc , sqlite3_value * * argv , sqlite3_context * context , int is_agg TSRMLS_DC ) /* { { { */
2008-07-25 10:44:59 +08:00
{
zval * * * zargs = NULL ;
zval * retval = NULL ;
int i ;
int ret ;
int fake_argc ;
2008-12-25 03:22:16 +08:00
php_sqlite3_agg_context * agg_context = NULL ;
2008-07-25 10:44:59 +08:00
if ( is_agg ) {
is_agg = 2 ;
}
fake_argc = argc + is_agg ;
fc - > fci . size = sizeof ( fc - > fci ) ;
fc - > fci . function_table = EG ( function_table ) ;
fc - > fci . function_name = cb ;
fc - > fci . symbol_table = NULL ;
2008-11-28 03:01:23 +08:00
fc - > fci . object_ptr = NULL ;
2008-07-25 10:44:59 +08:00
fc - > fci . retval_ptr_ptr = & retval ;
fc - > fci . param_count = fake_argc ;
/* build up the params */
if ( fake_argc ) {
zargs = ( zval * * * ) safe_emalloc ( fake_argc , sizeof ( zval * * ) , 0 ) ;
}
if ( is_agg ) {
/* summon the aggregation context */
2008-12-25 03:22:16 +08:00
agg_context = ( php_sqlite3_agg_context * ) sqlite3_aggregate_context ( context , sizeof ( php_sqlite3_agg_context ) ) ;
if ( ! agg_context - > zval_context ) {
MAKE_STD_ZVAL ( agg_context - > zval_context ) ;
ZVAL_NULL ( agg_context - > zval_context ) ;
2008-07-25 10:44:59 +08:00
}
2008-12-25 03:22:16 +08:00
zargs [ 0 ] = & agg_context - > zval_context ;
2008-07-25 10:44:59 +08:00
zargs [ 1 ] = emalloc ( sizeof ( zval * ) ) ;
MAKE_STD_ZVAL ( * zargs [ 1 ] ) ;
2008-12-25 03:22:16 +08:00
ZVAL_LONG ( * zargs [ 1 ] , agg_context - > row_count ) ;
2008-07-25 10:44:59 +08:00
}
for ( i = 0 ; i < argc ; i + + ) {
zargs [ i + is_agg ] = emalloc ( sizeof ( zval * ) ) ;
MAKE_STD_ZVAL ( * zargs [ i + is_agg ] ) ;
switch ( sqlite3_value_type ( argv [ i ] ) ) {
case SQLITE_INTEGER :
2013-01-15 00:35:07 +08:00
# if LONG_MAX > 2147483647
ZVAL_LONG ( * zargs [ i + is_agg ] , sqlite3_value_int64 ( argv [ i ] ) ) ;
# else
2008-07-25 10:44:59 +08:00
ZVAL_LONG ( * zargs [ i + is_agg ] , sqlite3_value_int ( argv [ i ] ) ) ;
2013-01-15 00:35:07 +08:00
# endif
2008-07-25 10:44:59 +08:00
break ;
case SQLITE_FLOAT :
ZVAL_DOUBLE ( * zargs [ i + is_agg ] , sqlite3_value_double ( argv [ i ] ) ) ;
break ;
case SQLITE_NULL :
ZVAL_NULL ( * zargs [ i + is_agg ] ) ;
break ;
case SQLITE_BLOB :
case SQLITE3_TEXT :
default :
2008-07-27 07:42:53 +08:00
ZVAL_STRINGL ( * zargs [ i + is_agg ] , ( char * ) sqlite3_value_text ( argv [ i ] ) , sqlite3_value_bytes ( argv [ i ] ) , 1 ) ;
2008-07-25 10:44:59 +08:00
break ;
}
}
fc - > fci . params = zargs ;
if ( ( ret = zend_call_function ( & fc - > fci , & fc - > fcc TSRMLS_CC ) ) = = FAILURE ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " An error occurred while invoking the callback " ) ;
}
/* clean up the params */
if ( fake_argc ) {
for ( i = is_agg ; i < argc + is_agg ; i + + ) {
zval_ptr_dtor ( zargs [ i ] ) ;
efree ( zargs [ i ] ) ;
}
if ( is_agg ) {
zval_ptr_dtor ( zargs [ 1 ] ) ;
efree ( zargs [ 1 ] ) ;
}
efree ( zargs ) ;
}
if ( ! is_agg | | ! argv ) {
/* only set the sqlite return value if we are a scalar function,
* or if we are finalizing an aggregate */
if ( retval ) {
switch ( Z_TYPE_P ( retval ) ) {
case IS_LONG :
2013-01-15 00:35:07 +08:00
# if LONG_MAX > 2147483647
sqlite3_result_int64 ( context , Z_LVAL_P ( retval ) ) ;
# else
2008-07-25 10:44:59 +08:00
sqlite3_result_int ( context , Z_LVAL_P ( retval ) ) ;
2013-01-15 00:35:07 +08:00
# endif
2008-07-25 10:44:59 +08:00
break ;
case IS_NULL :
sqlite3_result_null ( context ) ;
break ;
case IS_DOUBLE :
sqlite3_result_double ( context , Z_DVAL_P ( retval ) ) ;
break ;
default :
convert_to_string_ex ( & retval ) ;
2008-07-27 07:42:53 +08:00
sqlite3_result_text ( context , Z_STRVAL_P ( retval ) , Z_STRLEN_P ( retval ) , SQLITE_TRANSIENT ) ;
2008-07-25 10:44:59 +08:00
break ;
}
} else {
sqlite3_result_error ( context , " failed to invoke callback " , 0 ) ;
}
2008-12-25 03:22:16 +08:00
if ( agg_context & & agg_context - > zval_context ) {
zval_ptr_dtor ( & agg_context - > zval_context ) ;
2008-07-25 10:44:59 +08:00
}
} else {
/* we're stepping in an aggregate; the return value goes into
* the context */
2008-12-25 03:22:16 +08:00
if ( agg_context & & agg_context - > zval_context ) {
zval_ptr_dtor ( & agg_context - > zval_context ) ;
2008-07-25 10:44:59 +08:00
}
if ( retval ) {
2008-12-25 03:22:16 +08:00
agg_context - > zval_context = retval ;
2008-07-25 10:44:59 +08:00
retval = NULL ;
} else {
2008-12-25 03:22:16 +08:00
agg_context - > zval_context = NULL ;
2008-07-25 10:44:59 +08:00
}
}
if ( retval ) {
zval_ptr_dtor ( & retval ) ;
}
return ret ;
}
2008-07-27 07:42:53 +08:00
/* }}}*/
2008-07-25 10:44:59 +08:00
2008-07-27 07:42:53 +08:00
static void php_sqlite3_callback_func ( sqlite3_context * context , int argc , sqlite3_value * * argv ) /* { { { */
2008-07-25 10:44:59 +08:00
{
php_sqlite3_func * func = ( php_sqlite3_func * ) sqlite3_user_data ( context ) ;
TSRMLS_FETCH ( ) ;
sqlite3_do_callback ( & func - > afunc , func - > func , argc , argv , context , 0 TSRMLS_CC ) ;
}
2008-07-27 07:42:53 +08:00
/* }}}*/
2008-07-25 10:44:59 +08:00
2008-07-27 07:42:53 +08:00
static void php_sqlite3_callback_step ( sqlite3_context * context , int argc , sqlite3_value * * argv ) /* { { { */
2008-07-25 10:44:59 +08:00
{
php_sqlite3_func * func = ( php_sqlite3_func * ) sqlite3_user_data ( context ) ;
2008-12-25 03:22:16 +08:00
php_sqlite3_agg_context * agg_context = ( php_sqlite3_agg_context * ) sqlite3_aggregate_context ( context , sizeof ( php_sqlite3_agg_context ) ) ;
2008-07-25 10:44:59 +08:00
TSRMLS_FETCH ( ) ;
2008-12-25 03:22:16 +08:00
agg_context - > row_count + + ;
2008-07-25 10:44:59 +08:00
sqlite3_do_callback ( & func - > astep , func - > step , argc , argv , context , 1 TSRMLS_CC ) ;
}
2008-07-27 07:42:53 +08:00
/* }}} */
2008-07-25 10:44:59 +08:00
2008-07-27 07:42:53 +08:00
static void php_sqlite3_callback_final ( sqlite3_context * context ) /* { { { */
2008-07-25 10:44:59 +08:00
{
php_sqlite3_func * func = ( php_sqlite3_func * ) sqlite3_user_data ( context ) ;
2008-12-25 03:22:16 +08:00
php_sqlite3_agg_context * agg_context = ( php_sqlite3_agg_context * ) sqlite3_aggregate_context ( context , sizeof ( php_sqlite3_agg_context ) ) ;
2008-07-25 10:44:59 +08:00
TSRMLS_FETCH ( ) ;
2008-12-25 03:22:16 +08:00
agg_context - > row_count = 0 ;
2008-07-25 10:44:59 +08:00
sqlite3_do_callback ( & func - > afini , func - > fini , 0 , NULL , context , 1 TSRMLS_CC ) ;
}
2008-07-27 07:42:53 +08:00
/* }}} */
2008-07-25 10:44:59 +08:00
2012-01-29 11:57:29 +08:00
static int php_sqlite3_callback_compare ( void * coll , int a_len , const void * a , int b_len , const void * b ) /* { { { */
{
php_sqlite3_collation * collation = ( php_sqlite3_collation * ) coll ;
zval * * * zargs = NULL ;
zval * retval = NULL ;
int ret ;
TSRMLS_FETCH ( ) ;
collation - > fci . fci . size = ( sizeof ( collation - > fci . fci ) ) ;
collation - > fci . fci . function_table = EG ( function_table ) ;
collation - > fci . fci . function_name = collation - > cmp_func ;
collation - > fci . fci . symbol_table = NULL ;
collation - > fci . fci . object_ptr = NULL ;
collation - > fci . fci . retval_ptr_ptr = & retval ;
collation - > fci . fci . param_count = 2 ;
zargs = ( zval * * * ) safe_emalloc ( 2 , sizeof ( zval * * ) , 0 ) ;
zargs [ 0 ] = emalloc ( sizeof ( zval * ) ) ;
zargs [ 1 ] = emalloc ( sizeof ( zval * ) ) ;
MAKE_STD_ZVAL ( * zargs [ 0 ] ) ;
ZVAL_STRINGL ( * zargs [ 0 ] , a , a_len , 1 ) ;
MAKE_STD_ZVAL ( * zargs [ 1 ] ) ;
ZVAL_STRINGL ( * zargs [ 1 ] , b , b_len , 1 ) ;
collation - > fci . fci . params = zargs ;
if ( ( ret = zend_call_function ( & collation - > fci . fci , & collation - > fci . fcc TSRMLS_CC ) ) = = FAILURE ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " An error occurred while invoking the compare callback " ) ;
}
zval_ptr_dtor ( zargs [ 0 ] ) ;
zval_ptr_dtor ( zargs [ 1 ] ) ;
efree ( zargs [ 0 ] ) ;
efree ( zargs [ 1 ] ) ;
efree ( zargs ) ;
//retval ought to contain a ZVAL_LONG by now
// (the result of a comparison, i.e. most likely -1, 0, or 1)
//I suppose we could accept any scalar return type, though.
if ( Z_TYPE_P ( retval ) ! = IS_LONG ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " An error occurred while invoking the compare callback (invalid return type). Collation behaviour is undefined. " ) ;
} else {
ret = Z_LVAL_P ( retval ) ;
}
zval_ptr_dtor ( & retval ) ;
return ret ;
}
/* }}} */
2009-01-24 20:17:47 +08:00
/* {{{ proto bool SQLite3::createFunction(string name, mixed callback [, int argcount])
2008-07-27 07:42:53 +08:00
Allows registration of a PHP function as a SQLite UDF that can be called within SQL statements . */
2008-07-25 10:44:59 +08:00
PHP_METHOD ( sqlite3 , createFunction )
{
php_sqlite3_db_object * db_obj ;
zval * object = getThis ( ) ;
php_sqlite3_func * func ;
char * sql_func , * callback_name ;
int sql_func_len ;
zval * callback_func ;
long sql_func_num_args = - 1 ;
db_obj = ( php_sqlite3_db_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
2009-04-28 02:16:46 +08:00
SQLITE3_CHECK_INITIALIZED ( db_obj , db_obj - > initialised , SQLite3 )
2008-07-25 10:44:59 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " sz|l " , & sql_func , & sql_func_len , & callback_func , & sql_func_num_args ) = = FAILURE ) {
return ;
}
if ( ! sql_func_len ) {
RETURN_FALSE ;
}
2008-08-02 12:46:07 +08:00
if ( ! zend_is_callable ( callback_func , 0 , & callback_name TSRMLS_CC ) ) {
2009-04-28 02:16:46 +08:00
php_sqlite3_error ( db_obj , " Not a valid callback function %s " , callback_name ) ;
2008-07-25 10:44:59 +08:00
efree ( callback_name ) ;
RETURN_FALSE ;
}
efree ( callback_name ) ;
func = ( php_sqlite3_func * ) ecalloc ( 1 , sizeof ( * func ) ) ;
if ( sqlite3_create_function ( db_obj - > db , sql_func , sql_func_num_args , SQLITE_UTF8 , func , php_sqlite3_callback_func , NULL , NULL ) = = SQLITE_OK ) {
func - > func_name = estrdup ( sql_func ) ;
MAKE_STD_ZVAL ( func - > func ) ;
2009-12-08 09:57:37 +08:00
MAKE_COPY_ZVAL ( & callback_func , func - > func ) ;
2008-07-25 10:44:59 +08:00
func - > argc = sql_func_num_args ;
func - > next = db_obj - > funcs ;
db_obj - > funcs = func ;
RETURN_TRUE ;
}
efree ( func ) ;
RETURN_FALSE ;
}
/* }}} */
2009-01-24 20:17:47 +08:00
/* {{{ proto bool SQLite3::createAggregate(string name, mixed step, mixed final [, int argcount])
2008-07-27 07:42:53 +08:00
Allows registration of a PHP function for use as an aggregate . */
2008-07-25 10:44:59 +08:00
PHP_METHOD ( sqlite3 , createAggregate )
{
php_sqlite3_db_object * db_obj ;
zval * object = getThis ( ) ;
php_sqlite3_func * func ;
char * sql_func , * callback_name ;
int sql_func_len ;
zval * step_callback , * fini_callback ;
long sql_func_num_args = - 1 ;
db_obj = ( php_sqlite3_db_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
2009-04-28 02:16:46 +08:00
SQLITE3_CHECK_INITIALIZED ( db_obj , db_obj - > initialised , SQLite3 )
2008-07-25 10:44:59 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " szz|l " , & sql_func , & sql_func_len , & step_callback , & fini_callback , & sql_func_num_args ) = = FAILURE ) {
return ;
}
if ( ! sql_func_len ) {
RETURN_FALSE ;
}
2008-08-02 12:46:07 +08:00
if ( ! zend_is_callable ( step_callback , 0 , & callback_name TSRMLS_CC ) ) {
2009-04-28 02:16:46 +08:00
php_sqlite3_error ( db_obj , " Not a valid callback function %s " , callback_name ) ;
2008-07-25 10:44:59 +08:00
efree ( callback_name ) ;
RETURN_FALSE ;
}
efree ( callback_name ) ;
2008-08-02 12:46:07 +08:00
if ( ! zend_is_callable ( fini_callback , 0 , & callback_name TSRMLS_CC ) ) {
2009-04-28 02:16:46 +08:00
php_sqlite3_error ( db_obj , " Not a valid callback function %s " , callback_name ) ;
2008-07-25 10:44:59 +08:00
efree ( callback_name ) ;
RETURN_FALSE ;
}
efree ( callback_name ) ;
func = ( php_sqlite3_func * ) ecalloc ( 1 , sizeof ( * func ) ) ;
if ( sqlite3_create_function ( db_obj - > db , sql_func , sql_func_num_args , SQLITE_UTF8 , func , NULL , php_sqlite3_callback_step , php_sqlite3_callback_final ) = = SQLITE_OK ) {
func - > func_name = estrdup ( sql_func ) ;
MAKE_STD_ZVAL ( func - > step ) ;
2009-12-08 09:57:37 +08:00
MAKE_COPY_ZVAL ( & step_callback , func - > step ) ;
2008-07-25 10:44:59 +08:00
MAKE_STD_ZVAL ( func - > fini ) ;
2009-12-08 09:57:37 +08:00
MAKE_COPY_ZVAL ( & fini_callback , func - > fini ) ;
2008-07-25 10:44:59 +08:00
func - > argc = sql_func_num_args ;
func - > next = db_obj - > funcs ;
db_obj - > funcs = func ;
RETURN_TRUE ;
}
efree ( func ) ;
RETURN_FALSE ;
}
/* }}} */
2012-01-29 11:57:29 +08:00
/* {{{ proto bool SQLite3::createCollation(string name, mixed callback)
Registers a PHP function as a comparator that can be used with the SQL COLLATE operator . Callback must accept two strings and return an integer ( as strcmp ( ) ) . */
PHP_METHOD ( sqlite3 , createCollation )
{
php_sqlite3_db_object * db_obj ;
zval * object = getThis ( ) ;
php_sqlite3_collation * collation ;
char * collation_name , * callback_name ;
int collation_name_len ;
zval * callback_func ;
db_obj = ( php_sqlite3_db_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
SQLITE3_CHECK_INITIALIZED ( db_obj , db_obj - > initialised , SQLite3 )
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " sz " , & collation_name , & collation_name_len , & callback_func ) = = FAILURE ) {
RETURN_FALSE ;
}
if ( ! collation_name_len ) {
RETURN_FALSE ;
}
if ( ! zend_is_callable ( callback_func , 0 , & callback_name TSRMLS_CC ) ) {
php_sqlite3_error ( db_obj , " Not a valid callback function %s " , callback_name ) ;
efree ( callback_name ) ;
RETURN_FALSE ;
}
efree ( callback_name ) ;
collation = ( php_sqlite3_collation * ) ecalloc ( 1 , sizeof ( * collation ) ) ;
if ( sqlite3_create_collation ( db_obj - > db , collation_name , SQLITE_UTF8 , collation , php_sqlite3_callback_compare ) = = SQLITE_OK ) {
collation - > collation_name = estrdup ( collation_name ) ;
MAKE_STD_ZVAL ( collation - > cmp_func ) ;
MAKE_COPY_ZVAL ( & callback_func , collation - > cmp_func ) ;
collation - > next = db_obj - > collations ;
db_obj - > collations = collation ;
RETURN_TRUE ;
}
efree ( collation ) ;
RETURN_FALSE ;
}
/* }}} */
2009-01-24 20:17:47 +08:00
typedef struct {
sqlite3_blob * blob ;
size_t position ;
size_t size ;
} php_stream_sqlite3_data ;
static size_t php_sqlite3_stream_write ( php_stream * stream , const char * buf , size_t count TSRMLS_DC )
{
2009-02-19 04:07:40 +08:00
/* php_stream_sqlite3_data *sqlite3_stream = (php_stream_sqlite3_data *) stream->abstract; */
2009-01-24 20:17:47 +08:00
return 0 ;
}
static size_t php_sqlite3_stream_read ( php_stream * stream , char * buf , size_t count TSRMLS_DC )
{
php_stream_sqlite3_data * sqlite3_stream = ( php_stream_sqlite3_data * ) stream - > abstract ;
if ( sqlite3_stream - > position + count > = sqlite3_stream - > size ) {
count = sqlite3_stream - > size - sqlite3_stream - > position ;
stream - > eof = 1 ;
}
if ( count ) {
if ( sqlite3_blob_read ( sqlite3_stream - > blob , buf , count , sqlite3_stream - > position ) ! = SQLITE_OK ) {
return 0 ;
}
sqlite3_stream - > position + = count ;
}
return count ;
}
static int php_sqlite3_stream_close ( php_stream * stream , int close_handle TSRMLS_DC )
{
php_stream_sqlite3_data * sqlite3_stream = ( php_stream_sqlite3_data * ) stream - > abstract ;
if ( sqlite3_blob_close ( sqlite3_stream - > blob ) ! = SQLITE_OK ) {
2012-06-12 04:47:40 +08:00
/* Error occurred, but it still closed */
2009-01-24 20:17:47 +08:00
}
efree ( sqlite3_stream ) ;
return 0 ;
}
static int php_sqlite3_stream_flush ( php_stream * stream TSRMLS_DC )
{
/* do nothing */
return 0 ;
}
/* {{{ */
static int php_sqlite3_stream_seek ( php_stream * stream , off_t offset , int whence , off_t * newoffs TSRMLS_DC )
{
php_stream_sqlite3_data * sqlite3_stream = ( php_stream_sqlite3_data * ) stream - > abstract ;
switch ( whence ) {
case SEEK_CUR :
if ( offset < 0 ) {
if ( sqlite3_stream - > position < ( size_t ) ( - offset ) ) {
sqlite3_stream - > position = 0 ;
* newoffs = - 1 ;
return - 1 ;
} else {
sqlite3_stream - > position = sqlite3_stream - > position + offset ;
* newoffs = sqlite3_stream - > position ;
stream - > eof = 0 ;
return 0 ;
}
} else {
if ( sqlite3_stream - > position + ( size_t ) ( offset ) > sqlite3_stream - > size ) {
sqlite3_stream - > position = sqlite3_stream - > size ;
* newoffs = - 1 ;
return - 1 ;
} else {
sqlite3_stream - > position = sqlite3_stream - > position + offset ;
* newoffs = sqlite3_stream - > position ;
stream - > eof = 0 ;
return 0 ;
}
}
case SEEK_SET :
if ( sqlite3_stream - > size < ( size_t ) ( offset ) ) {
sqlite3_stream - > position = sqlite3_stream - > size ;
* newoffs = - 1 ;
return - 1 ;
} else {
sqlite3_stream - > position = offset ;
* newoffs = sqlite3_stream - > position ;
stream - > eof = 0 ;
return 0 ;
}
case SEEK_END :
if ( offset > 0 ) {
sqlite3_stream - > position = sqlite3_stream - > size ;
* newoffs = - 1 ;
return - 1 ;
} else if ( sqlite3_stream - > size < ( size_t ) ( - offset ) ) {
sqlite3_stream - > position = 0 ;
* newoffs = - 1 ;
return - 1 ;
} else {
sqlite3_stream - > position = sqlite3_stream - > size + offset ;
* newoffs = sqlite3_stream - > position ;
stream - > eof = 0 ;
return 0 ;
}
default :
* newoffs = sqlite3_stream - > position ;
return - 1 ;
}
}
/* }}} */
static int php_sqlite3_stream_cast ( php_stream * stream , int castas , void * * ret TSRMLS_DC )
{
return FAILURE ;
}
static int php_sqlite3_stream_stat ( php_stream * stream , php_stream_statbuf * ssb TSRMLS_DC )
{
2011-01-01 00:37:12 +08:00
php_stream_sqlite3_data * sqlite3_stream = ( php_stream_sqlite3_data * ) stream - > abstract ;
ssb - > sb . st_size = sqlite3_stream - > size ;
return 0 ;
2009-01-24 20:17:47 +08:00
}
2009-01-29 07:58:09 +08:00
static php_stream_ops php_stream_sqlite3_ops = {
2009-01-24 20:17:47 +08:00
php_sqlite3_stream_write ,
php_sqlite3_stream_read ,
php_sqlite3_stream_close ,
php_sqlite3_stream_flush ,
" SQLite3 " ,
php_sqlite3_stream_seek ,
php_sqlite3_stream_cast ,
php_sqlite3_stream_stat
} ;
/* {{{ proto resource SQLite3::openBlob(string table, string column, int rowid [, string dbname])
Open a blob as a stream which we can read / write to . */
PHP_METHOD ( sqlite3 , openBlob )
{
php_sqlite3_db_object * db_obj ;
zval * object = getThis ( ) ;
char * table , * column , * dbname = " main " ;
int table_len , column_len , dbname_len ;
long rowid , flags = 0 ;
sqlite3_blob * blob = NULL ;
php_stream_sqlite3_data * sqlite3_stream ;
php_stream * stream ;
db_obj = ( php_sqlite3_db_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
2009-04-28 02:16:46 +08:00
SQLITE3_CHECK_INITIALIZED ( db_obj , db_obj - > initialised , SQLite3 )
2009-01-24 20:17:47 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " ssl|s " , & table , & table_len , & column , & column_len , & rowid , & dbname , & dbname_len ) = = FAILURE ) {
return ;
}
if ( sqlite3_blob_open ( db_obj - > db , dbname , table , column , rowid , flags , & blob ) ! = SQLITE_OK ) {
2009-04-28 02:16:46 +08:00
php_sqlite3_error ( db_obj , " Unable to open blob: %s " , sqlite3_errmsg ( db_obj - > db ) ) ;
2009-01-24 20:17:47 +08:00
RETURN_FALSE ;
}
sqlite3_stream = emalloc ( sizeof ( php_stream_sqlite3_data ) ) ;
sqlite3_stream - > blob = blob ;
sqlite3_stream - > position = 0 ;
sqlite3_stream - > size = sqlite3_blob_bytes ( blob ) ;
2009-01-24 21:08:04 +08:00
stream = php_stream_alloc ( & php_stream_sqlite3_ops , sqlite3_stream , 0 , " rb " ) ;
2009-01-24 20:17:47 +08:00
if ( stream ) {
php_stream_to_zval ( stream , return_value ) ;
} else {
RETURN_FALSE ;
}
}
/* }}} */
2009-06-08 10:15:54 +08:00
/* {{{ proto bool SQLite3::enableExceptions([bool enableExceptions = false])
Enables an exception error mode . */
2009-04-28 02:16:46 +08:00
PHP_METHOD ( sqlite3 , enableExceptions )
{
php_sqlite3_db_object * db_obj ;
zval * object = getThis ( ) ;
zend_bool enableExceptions = 0 ;
db_obj = ( php_sqlite3_db_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " |b " , & enableExceptions ) = = FAILURE ) {
return ;
}
2009-06-08 10:15:54 +08:00
RETVAL_BOOL ( db_obj - > exception ) ;
2009-04-28 02:16:46 +08:00
db_obj - > exception = enableExceptions ;
}
/* }}} */
2008-08-01 06:30:26 +08:00
/* {{{ proto int SQLite3Stmt::paramCount()
2008-07-27 07:42:53 +08:00
Returns the number of parameters within the prepared statement . */
2008-08-01 06:30:26 +08:00
PHP_METHOD ( sqlite3stmt , paramCount )
2008-07-25 10:44:59 +08:00
{
php_sqlite3_stmt * stmt_obj ;
zval * object = getThis ( ) ;
stmt_obj = ( php_sqlite3_stmt * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
}
RETURN_LONG ( sqlite3_bind_parameter_count ( stmt_obj - > stmt ) ) ;
}
/* }}} */
2008-08-01 06:30:26 +08:00
/* {{{ proto bool SQLite3Stmt::close()
2008-07-27 07:42:53 +08:00
Closes the prepared statement . */
2008-08-01 06:30:26 +08:00
PHP_METHOD ( sqlite3stmt , close )
2008-07-25 10:44:59 +08:00
{
php_sqlite3_stmt * stmt_obj ;
zval * object = getThis ( ) ;
stmt_obj = ( php_sqlite3_stmt * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
}
2008-07-29 08:56:53 +08:00
zend_llist_del_element ( & ( stmt_obj - > db_obj - > free_list ) , object , ( int ( * ) ( void * , void * ) ) php_sqlite3_compare_stmt_zval_free ) ;
2008-07-25 10:44:59 +08:00
RETURN_TRUE ;
}
/* }}} */
2008-08-01 06:30:26 +08:00
/* {{{ proto bool SQLite3Stmt::reset()
2008-07-27 07:42:53 +08:00
Reset the prepared statement to the state before it was executed , bindings still remain . */
2008-08-01 06:30:26 +08:00
PHP_METHOD ( sqlite3stmt , reset )
2008-07-25 10:44:59 +08:00
{
php_sqlite3_stmt * stmt_obj ;
zval * object = getThis ( ) ;
stmt_obj = ( php_sqlite3_stmt * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
}
if ( sqlite3_reset ( stmt_obj - > stmt ) ! = SQLITE_OK ) {
2009-04-28 02:16:46 +08:00
php_sqlite3_error ( stmt_obj - > db_obj , " Unable to reset statement: %s " , sqlite3_errmsg ( sqlite3_db_handle ( stmt_obj - > stmt ) ) ) ;
2008-07-25 10:44:59 +08:00
RETURN_FALSE ;
}
RETURN_TRUE ;
}
/* }}} */
2008-08-01 06:30:26 +08:00
/* {{{ proto bool SQLite3Stmt::clear()
2008-07-27 07:42:53 +08:00
Clear all current bound parameters . */
2008-08-01 06:30:26 +08:00
PHP_METHOD ( sqlite3stmt , clear )
2008-07-25 10:44:59 +08:00
{
php_sqlite3_stmt * stmt_obj ;
zval * object = getThis ( ) ;
stmt_obj = ( php_sqlite3_stmt * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
}
if ( sqlite3_clear_bindings ( stmt_obj - > stmt ) ! = SQLITE_OK ) {
2009-04-28 02:16:46 +08:00
php_sqlite3_error ( stmt_obj - > db_obj , " Unable to clear statement: %s " , sqlite3_errmsg ( sqlite3_db_handle ( stmt_obj - > stmt ) ) ) ;
2008-07-25 10:44:59 +08:00
RETURN_FALSE ;
}
RETURN_TRUE ;
}
/* }}} */
2011-01-01 00:37:12 +08:00
/* {{{ proto bool SQLite3Stmt::readOnly()
Returns true if a statement is definitely read only */
PHP_METHOD ( sqlite3stmt , readOnly )
{
php_sqlite3_stmt * stmt_obj ;
zval * object = getThis ( ) ;
stmt_obj = ( php_sqlite3_stmt * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
}
# if SQLITE_VERSION_NUMBER >= 3007004
if ( sqlite3_stmt_readonly ( stmt_obj - > stmt ) ) {
RETURN_TRUE ;
}
# endif
RETURN_FALSE ;
}
/* }}} */
2008-07-25 10:44:59 +08:00
static int register_bound_parameter_to_sqlite ( struct php_sqlite3_bound_param * param , php_sqlite3_stmt * stmt TSRMLS_DC ) /* { { { */
{
HashTable * hash ;
hash = stmt - > bound_params ;
if ( ! hash ) {
ALLOC_HASHTABLE ( hash ) ;
zend_hash_init ( hash , 13 , NULL , sqlite3_param_dtor , 0 ) ;
stmt - > bound_params = hash ;
}
/* We need a : prefix to resolve a name to a parameter number */
if ( param - > name ) {
if ( param - > name [ 0 ] ! = ' : ' ) {
/* pre-increment for character + 1 for null */
char * temp = emalloc ( + + param - > name_len + 1 ) ;
temp [ 0 ] = ' : ' ;
memmove ( temp + 1 , param - > name , param - > name_len ) ;
param - > name = temp ;
} else {
param - > name = estrndup ( param - > name , param - > name_len ) ;
}
/* do lookup*/
param - > param_number = sqlite3_bind_parameter_index ( stmt - > stmt , param - > name ) ;
}
if ( param - > param_number < 1 ) {
efree ( param - > name ) ;
return 0 ;
}
if ( param - > param_number > = 1 ) {
zend_hash_index_del ( hash , param - > param_number ) ;
}
if ( param - > name ) {
zend_hash_update ( hash , param - > name , param - > name_len , param , sizeof ( * param ) , NULL ) ;
} else {
zend_hash_index_update ( hash , param - > param_number , param , sizeof ( * param ) , NULL ) ;
}
return 1 ;
}
/* }}} */
2008-08-01 06:30:26 +08:00
/* {{{ proto bool SQLite3Stmt::bindParam(int parameter_number, mixed parameter [, int type])
2013-04-22 20:41:27 +08:00
Bind Parameter to a stmt variable . */
2008-08-01 06:30:26 +08:00
PHP_METHOD ( sqlite3stmt , bindParam )
2008-07-25 10:44:59 +08:00
{
php_sqlite3_stmt * stmt_obj ;
zval * object = getThis ( ) ;
struct php_sqlite3_bound_param param = { 0 } ;
stmt_obj = ( php_sqlite3_stmt * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
param . param_number = - 1 ;
param . type = SQLITE3_TEXT ;
2008-07-27 07:42:53 +08:00
if ( zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET , ZEND_NUM_ARGS ( ) TSRMLS_CC , " lz|l " , & param . param_number , & param . parameter , & param . type ) = = FAILURE ) {
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " sz|l " , & param . name , & param . name_len , & param . parameter , & param . type ) = = FAILURE ) {
2008-07-25 10:44:59 +08:00
return ;
}
}
Z_ADDREF_P ( param . parameter ) ;
if ( ! register_bound_parameter_to_sqlite ( & param , stmt_obj TSRMLS_CC ) ) {
if ( param . parameter ) {
zval_ptr_dtor ( & ( param . parameter ) ) ;
param . parameter = NULL ;
}
RETURN_FALSE ;
}
RETURN_TRUE ;
}
/* }}} */
2008-08-01 06:30:26 +08:00
/* {{{ proto bool SQLite3Stmt::bindValue(int parameter_number, mixed parameter [, int type])
2008-07-27 07:42:53 +08:00
Bind Value of a parameter to a stmt variable . */
2008-08-01 06:30:26 +08:00
PHP_METHOD ( sqlite3stmt , bindValue )
2008-07-25 10:44:59 +08:00
{
php_sqlite3_stmt * stmt_obj ;
zval * object = getThis ( ) ;
struct php_sqlite3_bound_param param = { 0 } ;
stmt_obj = ( php_sqlite3_stmt * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
param . param_number = - 1 ;
param . type = SQLITE3_TEXT ;
2008-07-27 07:42:53 +08:00
if ( zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET , ZEND_NUM_ARGS ( ) TSRMLS_CC , " lz/|l " , & param . param_number , & param . parameter , & param . type ) = = FAILURE ) {
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " sz/|l " , & param . name , & param . name_len , & param . parameter , & param . type ) = = FAILURE ) {
2008-07-25 10:44:59 +08:00
return ;
}
}
Z_ADDREF_P ( param . parameter ) ;
if ( ! register_bound_parameter_to_sqlite ( & param , stmt_obj TSRMLS_CC ) ) {
if ( param . parameter ) {
zval_ptr_dtor ( & ( param . parameter ) ) ;
param . parameter = NULL ;
}
RETURN_FALSE ;
}
RETURN_TRUE ;
}
/* }}} */
2008-08-01 06:30:26 +08:00
/* {{{ proto SQLite3Result SQLite3Stmt::execute()
2008-07-27 07:42:53 +08:00
Executes a prepared statement and returns a result set object . */
2008-08-01 06:30:26 +08:00
PHP_METHOD ( sqlite3stmt , execute )
2008-07-25 10:44:59 +08:00
{
php_sqlite3_stmt * stmt_obj ;
php_sqlite3_result * result ;
zval * object = getThis ( ) ;
int return_code = 0 ;
struct php_sqlite3_bound_param * param ;
2009-01-20 08:24:13 +08:00
2008-07-25 10:44:59 +08:00
stmt_obj = ( php_sqlite3_stmt * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
}
2009-04-28 02:16:46 +08:00
SQLITE3_CHECK_INITIALIZED ( stmt_obj - > db_obj , stmt_obj - > initialised , SQLite3 )
2008-11-18 03:34:03 +08:00
2008-07-25 10:44:59 +08:00
if ( stmt_obj - > bound_params ) {
zend_hash_internal_pointer_reset ( stmt_obj - > bound_params ) ;
while ( zend_hash_get_current_data ( stmt_obj - > bound_params , ( void * * ) & param ) = = SUCCESS ) {
/* If the ZVAL is null then it should be bound as that */
if ( Z_TYPE_P ( param - > parameter ) = = IS_NULL ) {
sqlite3_bind_null ( stmt_obj - > stmt , param - > param_number ) ;
2008-08-12 21:37:32 +08:00
zend_hash_move_forward ( stmt_obj - > bound_params ) ;
2008-07-25 10:44:59 +08:00
continue ;
}
switch ( param - > type ) {
case SQLITE_INTEGER :
convert_to_long ( param - > parameter ) ;
2013-01-15 00:35:07 +08:00
# if LONG_MAX > 2147483647
sqlite3_bind_int64 ( stmt_obj - > stmt , param - > param_number , Z_LVAL_P ( param - > parameter ) ) ;
# else
2008-07-25 10:44:59 +08:00
sqlite3_bind_int ( stmt_obj - > stmt , param - > param_number , Z_LVAL_P ( param - > parameter ) ) ;
2013-01-15 00:35:07 +08:00
# endif
2008-07-25 10:44:59 +08:00
break ;
case SQLITE_FLOAT :
/* convert_to_double(param->parameter);*/
sqlite3_bind_double ( stmt_obj - > stmt , param - > param_number , Z_DVAL_P ( param - > parameter ) ) ;
break ;
case SQLITE_BLOB :
{
php_stream * stream = NULL ;
int blength ;
char * buffer = NULL ;
if ( Z_TYPE_P ( param - > parameter ) = = IS_RESOURCE ) {
php_stream_from_zval_no_verify ( stream , & param - > parameter ) ;
if ( stream = = NULL ) {
2009-04-28 02:16:46 +08:00
php_sqlite3_error ( stmt_obj - > db_obj , " Unable to read stream for parameter %ld " , param - > param_number ) ;
2008-07-25 10:44:59 +08:00
RETURN_FALSE ;
}
2008-07-27 07:42:53 +08:00
blength = php_stream_copy_to_mem ( stream , ( void * ) & buffer , PHP_STREAM_COPY_ALL , 0 ) ;
2008-07-25 10:44:59 +08:00
} else {
convert_to_string ( param - > parameter ) ;
blength = Z_STRLEN_P ( param - > parameter ) ;
buffer = Z_STRVAL_P ( param - > parameter ) ;
}
sqlite3_bind_blob ( stmt_obj - > stmt , param - > param_number , buffer , blength , SQLITE_TRANSIENT ) ;
if ( stream ) {
pefree ( buffer , 0 ) ;
}
break ;
}
case SQLITE3_TEXT :
convert_to_string ( param - > parameter ) ;
sqlite3_bind_text ( stmt_obj - > stmt , param - > param_number , Z_STRVAL_P ( param - > parameter ) , Z_STRLEN_P ( param - > parameter ) , SQLITE_STATIC ) ;
break ;
case SQLITE_NULL :
sqlite3_bind_null ( stmt_obj - > stmt , param - > param_number ) ;
break ;
default :
2009-04-28 02:16:46 +08:00
php_sqlite3_error ( stmt_obj - > db_obj , " Unknown parameter type: %ld for parameter %ld " , param - > type , param - > param_number ) ;
2008-07-25 10:44:59 +08:00
RETURN_FALSE ;
}
zend_hash_move_forward ( stmt_obj - > bound_params ) ;
}
}
return_code = sqlite3_step ( stmt_obj - > stmt ) ;
switch ( return_code ) {
case SQLITE_ROW : /* Valid Row */
case SQLITE_DONE : /* Valid but no results */
{
sqlite3_reset ( stmt_obj - > stmt ) ;
object_init_ex ( return_value , php_sqlite3_result_entry ) ;
result = ( php_sqlite3_result * ) zend_object_store_get_object ( return_value TSRMLS_CC ) ;
Z_ADDREF_P ( object ) ;
result - > is_prepared_statement = 1 ;
result - > db_obj = stmt_obj - > db_obj ;
result - > stmt_obj = stmt_obj ;
result - > stmt_obj_zval = getThis ( ) ;
break ;
}
case SQLITE_ERROR :
sqlite3_reset ( stmt_obj - > stmt ) ;
default :
2009-04-28 02:16:46 +08:00
php_sqlite3_error ( stmt_obj - > db_obj , " Unable to execute statement: %s " , sqlite3_errmsg ( sqlite3_db_handle ( stmt_obj - > stmt ) ) ) ;
2008-07-25 10:44:59 +08:00
zval_dtor ( return_value ) ;
RETURN_FALSE ;
}
return ;
}
/* }}} */
2008-11-18 03:34:03 +08:00
/* {{{ proto int SQLite3Stmt::__construct(SQLite3 dbobject, String Statement)
__constructor for SQLite3Stmt . */
PHP_METHOD ( sqlite3stmt , __construct )
{
php_sqlite3_stmt * stmt_obj ;
php_sqlite3_db_object * db_obj ;
zval * object = getThis ( ) ;
zval * db_zval ;
char * sql ;
int sql_len , errcode ;
2008-11-19 10:00:53 +08:00
zend_error_handling error_handling ;
2009-01-20 17:57:34 +08:00
php_sqlite3_free_list * free_item ;
2008-11-18 03:34:03 +08:00
2008-11-18 22:27:09 +08:00
stmt_obj = ( php_sqlite3_stmt * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
2008-11-19 10:00:53 +08:00
zend_replace_error_handling ( EH_THROW , NULL , & error_handling TSRMLS_CC ) ;
2008-11-18 03:34:03 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " Os " , & db_zval , php_sqlite3_sc_entry , & sql , & sql_len ) = = FAILURE ) {
2008-11-19 10:00:53 +08:00
zend_restore_error_handling ( & error_handling TSRMLS_CC ) ;
2008-11-18 03:34:03 +08:00
return ;
}
db_obj = ( php_sqlite3_db_object * ) zend_object_store_get_object ( db_zval TSRMLS_CC ) ;
2009-04-28 02:16:46 +08:00
SQLITE3_CHECK_INITIALIZED ( db_obj , db_obj - > initialised , SQLite3 )
2008-11-18 03:34:03 +08:00
2008-11-19 10:00:53 +08:00
zend_restore_error_handling ( & error_handling TSRMLS_CC ) ;
2008-11-18 03:34:03 +08:00
if ( ! sql_len ) {
RETURN_FALSE ;
}
stmt_obj - > db_obj = db_obj ;
stmt_obj - > db_obj_zval = db_zval ;
Z_ADDREF_P ( db_zval ) ;
errcode = sqlite3_prepare_v2 ( db_obj - > db , sql , sql_len , & ( stmt_obj - > stmt ) , NULL ) ;
if ( errcode ! = SQLITE_OK ) {
2009-04-28 02:16:46 +08:00
php_sqlite3_error ( db_obj , " Unable to prepare statement: %d, %s " , errcode , sqlite3_errmsg ( db_obj - > db ) ) ;
2008-11-18 03:34:03 +08:00
zval_dtor ( return_value ) ;
RETURN_FALSE ;
}
stmt_obj - > initialised = 1 ;
2009-01-20 17:57:34 +08:00
free_item = emalloc ( sizeof ( php_sqlite3_free_list ) ) ;
free_item - > stmt_obj = stmt_obj ;
free_item - > stmt_obj_zval = getThis ( ) ;
zend_llist_add_element ( & ( db_obj - > free_list ) , & free_item ) ;
2008-11-18 03:34:03 +08:00
}
/* }}} */
2008-08-01 06:30:26 +08:00
/* {{{ proto int SQLite3Result::numColumns()
2008-07-27 07:42:53 +08:00
Number of columns in the result set . */
2008-08-01 06:30:26 +08:00
PHP_METHOD ( sqlite3result , numColumns )
2008-07-25 10:44:59 +08:00
{
php_sqlite3_result * result_obj ;
zval * object = getThis ( ) ;
result_obj = ( php_sqlite3_result * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
2009-04-28 02:16:46 +08:00
SQLITE3_CHECK_INITIALIZED ( result_obj - > db_obj , result_obj - > stmt_obj - > initialised , SQLite3Result )
2008-07-25 10:44:59 +08:00
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
}
RETURN_LONG ( sqlite3_column_count ( result_obj - > stmt_obj - > stmt ) ) ;
}
/* }}} */
2008-08-01 06:30:26 +08:00
/* {{{ proto string SQLite3Result::columnName(int column)
2008-07-27 07:42:53 +08:00
Returns the name of the nth column . */
2008-08-01 06:30:26 +08:00
PHP_METHOD ( sqlite3result , columnName )
2008-07-25 10:44:59 +08:00
{
php_sqlite3_result * result_obj ;
zval * object = getThis ( ) ;
2008-08-01 16:27:56 +08:00
long column = 0 ;
2010-12-04 05:05:44 +08:00
char * column_name ;
2008-07-25 10:44:59 +08:00
result_obj = ( php_sqlite3_result * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
2009-04-28 02:16:46 +08:00
SQLITE3_CHECK_INITIALIZED ( result_obj - > db_obj , result_obj - > stmt_obj - > initialised , SQLite3Result )
2008-07-25 10:44:59 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " l " , & column ) = = FAILURE ) {
return ;
}
2010-12-04 05:05:44 +08:00
column_name = ( char * ) sqlite3_column_name ( result_obj - > stmt_obj - > stmt , column ) ;
2008-07-25 10:44:59 +08:00
2010-12-04 05:05:44 +08:00
if ( column_name = = NULL ) {
RETURN_FALSE ;
}
RETVAL_STRING ( column_name , 1 ) ;
2008-07-25 10:44:59 +08:00
}
/* }}} */
2008-08-01 06:30:26 +08:00
/* {{{ proto int SQLite3Result::columnType(int column)
2008-07-27 07:42:53 +08:00
Returns the type of the nth column . */
2008-08-01 06:30:26 +08:00
PHP_METHOD ( sqlite3result , columnType )
2008-07-25 10:44:59 +08:00
{
php_sqlite3_result * result_obj ;
zval * object = getThis ( ) ;
2008-08-01 16:27:56 +08:00
long column = 0 ;
2008-07-25 10:44:59 +08:00
result_obj = ( php_sqlite3_result * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
2009-04-28 02:16:46 +08:00
SQLITE3_CHECK_INITIALIZED ( result_obj - > db_obj , result_obj - > stmt_obj - > initialised , SQLite3Result )
2008-07-25 10:44:59 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " l " , & column ) = = FAILURE ) {
return ;
}
2011-01-06 08:08:59 +08:00
if ( result_obj - > complete ) {
RETURN_FALSE ;
}
2008-07-25 10:44:59 +08:00
RETURN_LONG ( sqlite3_column_type ( result_obj - > stmt_obj - > stmt , column ) ) ;
}
/* }}} */
2008-08-01 06:30:26 +08:00
/* {{{ proto array SQLite3Result::fetchArray([int mode])
2008-07-27 07:42:53 +08:00
Fetch a result row as both an associative or numerically indexed array or both . */
2008-08-01 06:30:26 +08:00
PHP_METHOD ( sqlite3result , fetchArray )
2008-07-25 10:44:59 +08:00
{
php_sqlite3_result * result_obj ;
zval * object = getThis ( ) ;
2008-08-01 16:27:56 +08:00
int i , ret ;
long mode = PHP_SQLITE3_BOTH ;
2008-07-25 10:44:59 +08:00
result_obj = ( php_sqlite3_result * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
2009-04-28 02:16:46 +08:00
SQLITE3_CHECK_INITIALIZED ( result_obj - > db_obj , result_obj - > stmt_obj - > initialised , SQLite3Result )
2008-07-25 10:44:59 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " |l " , & mode ) = = FAILURE ) {
return ;
}
ret = sqlite3_step ( result_obj - > stmt_obj - > stmt ) ;
switch ( ret ) {
case SQLITE_ROW :
/* If there was no return value then just skip fetching */
if ( ! return_value_used ) {
return ;
}
array_init ( return_value ) ;
for ( i = 0 ; i < sqlite3_data_count ( result_obj - > stmt_obj - > stmt ) ; i + + ) {
zval * data ;
data = sqlite_value_to_zval ( result_obj - > stmt_obj - > stmt , i ) ;
if ( mode & PHP_SQLITE3_NUM ) {
add_index_zval ( return_value , i , data ) ;
}
if ( mode & PHP_SQLITE3_ASSOC ) {
if ( mode & PHP_SQLITE3_NUM ) {
Z_ADDREF_P ( data ) ;
}
add_assoc_zval ( return_value , ( char * ) sqlite3_column_name ( result_obj - > stmt_obj - > stmt , i ) , data ) ;
}
}
2008-07-29 07:01:02 +08:00
break ;
2008-07-25 10:44:59 +08:00
case SQLITE_DONE :
2011-01-06 08:08:59 +08:00
result_obj - > complete = 1 ;
2008-07-25 10:44:59 +08:00
RETURN_FALSE ;
2008-07-29 07:01:02 +08:00
break ;
2008-07-25 10:44:59 +08:00
default :
2009-04-28 02:16:46 +08:00
php_sqlite3_error ( result_obj - > db_obj , " Unable to execute statement: %s " , sqlite3_errmsg ( sqlite3_db_handle ( result_obj - > stmt_obj - > stmt ) ) ) ;
2008-07-25 10:44:59 +08:00
}
}
/* }}} */
2008-08-01 06:30:26 +08:00
/* {{{ proto bool SQLite3Result::reset()
2008-07-27 07:42:53 +08:00
Resets the result set back to the first row . */
2008-08-01 06:30:26 +08:00
PHP_METHOD ( sqlite3result , reset )
2008-07-25 10:44:59 +08:00
{
php_sqlite3_result * result_obj ;
zval * object = getThis ( ) ;
result_obj = ( php_sqlite3_result * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
2009-04-28 02:16:46 +08:00
SQLITE3_CHECK_INITIALIZED ( result_obj - > db_obj , result_obj - > stmt_obj - > initialised , SQLite3Result )
2008-07-25 10:44:59 +08:00
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
}
if ( sqlite3_reset ( result_obj - > stmt_obj - > stmt ) ! = SQLITE_OK ) {
RETURN_FALSE ;
}
result_obj - > complete = 0 ;
RETURN_TRUE ;
}
/* }}} */
2008-08-01 06:30:26 +08:00
/* {{{ proto bool SQLite3Result::finalize()
2008-07-27 07:42:53 +08:00
Closes the result set . */
2008-08-01 06:30:26 +08:00
PHP_METHOD ( sqlite3result , finalize )
2008-07-25 10:44:59 +08:00
{
php_sqlite3_result * result_obj ;
zval * object = getThis ( ) ;
result_obj = ( php_sqlite3_result * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
2009-04-28 02:16:46 +08:00
SQLITE3_CHECK_INITIALIZED ( result_obj - > db_obj , result_obj - > stmt_obj - > initialised , SQLite3Result )
2008-07-25 10:44:59 +08:00
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
}
/* We need to finalize an internal statement */
if ( result_obj - > is_prepared_statement = = 0 ) {
2008-07-29 08:56:53 +08:00
zend_llist_del_element ( & ( result_obj - > db_obj - > free_list ) , result_obj - > stmt_obj_zval ,
( int ( * ) ( void * , void * ) ) php_sqlite3_compare_stmt_zval_free ) ;
2008-07-25 10:44:59 +08:00
} else {
sqlite3_reset ( result_obj - > stmt_obj - > stmt ) ;
}
RETURN_TRUE ;
}
/* }}} */
2008-11-18 03:34:03 +08:00
/* {{{ proto int SQLite3Result::__construct()
__constructor for SQLite3Result . */
PHP_METHOD ( sqlite3result , __construct )
{
2009-04-28 02:16:46 +08:00
zend_throw_exception ( zend_exception_get_default ( TSRMLS_C ) , " SQLite3Result cannot be directly instantiated " , 0 TSRMLS_CC ) ;
2008-11-18 03:34:03 +08:00
}
/* }}} */
2008-07-25 10:44:59 +08:00
/* {{{ arginfo */
ZEND_BEGIN_ARG_INFO ( arginfo_sqlite3_open , 0 )
ZEND_ARG_INFO ( 0 , filename )
ZEND_ARG_INFO ( 0 , flags )
ZEND_ARG_INFO ( 0 , encryption_key )
ZEND_END_ARG_INFO ( )
2010-06-20 23:30:49 +08:00
ZEND_BEGIN_ARG_INFO ( arginfo_sqlite3_busytimeout , 0 )
ZEND_ARG_INFO ( 0 , ms )
ZEND_END_ARG_INFO ( )
2009-03-17 10:45:12 +08:00
# ifndef SQLITE_OMIT_LOAD_EXTENSION
2008-07-25 10:44:59 +08:00
ZEND_BEGIN_ARG_INFO ( arginfo_sqlite3_loadextension , 0 )
ZEND_ARG_INFO ( 0 , shared_library )
ZEND_END_ARG_INFO ( )
2009-03-17 10:45:12 +08:00
# endif
2008-07-25 10:44:59 +08:00
ZEND_BEGIN_ARG_INFO_EX ( arginfo_sqlite3_escapestring , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , value )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_sqlite3_query , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , query )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_sqlite3_querysingle , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , query )
ZEND_ARG_INFO ( 0 , entire_row )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_sqlite3_createfunction , 0 , 0 , 2 )
ZEND_ARG_INFO ( 0 , name )
ZEND_ARG_INFO ( 0 , callback )
ZEND_ARG_INFO ( 0 , argument_count )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_sqlite3_createaggregate , 0 , 0 , 3 )
ZEND_ARG_INFO ( 0 , name )
ZEND_ARG_INFO ( 0 , step_callback )
ZEND_ARG_INFO ( 0 , final_callback )
ZEND_ARG_INFO ( 0 , argument_count )
ZEND_END_ARG_INFO ( )
2012-01-29 11:57:29 +08:00
ZEND_BEGIN_ARG_INFO_EX ( arginfo_sqlite3_createcollation , 0 , 0 , 2 )
ZEND_ARG_INFO ( 0 , name )
ZEND_ARG_INFO ( 0 , callback )
ZEND_END_ARG_INFO ( )
2009-01-24 20:17:47 +08:00
ZEND_BEGIN_ARG_INFO_EX ( argingo_sqlite3_openblob , 0 , 0 , 3 )
ZEND_ARG_INFO ( 0 , table )
ZEND_ARG_INFO ( 0 , column )
ZEND_ARG_INFO ( 0 , rowid )
ZEND_ARG_INFO ( 0 , dbname )
ZEND_END_ARG_INFO ( )
2009-04-28 02:16:46 +08:00
ZEND_BEGIN_ARG_INFO_EX ( argingo_sqlite3_enableexceptions , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , enableExceptions )
ZEND_END_ARG_INFO ( )
2008-08-01 06:30:26 +08:00
ZEND_BEGIN_ARG_INFO_EX ( arginfo_sqlite3stmt_bindparam , 0 , 0 , 2 )
2008-07-25 10:44:59 +08:00
ZEND_ARG_INFO ( 0 , param_number )
ZEND_ARG_INFO ( 1 , param )
ZEND_ARG_INFO ( 0 , type )
ZEND_END_ARG_INFO ( )
2008-08-01 06:30:26 +08:00
ZEND_BEGIN_ARG_INFO_EX ( arginfo_sqlite3stmt_bindvalue , 0 , 0 , 2 )
2008-07-25 10:44:59 +08:00
ZEND_ARG_INFO ( 0 , param_number )
ZEND_ARG_INFO ( 0 , param )
ZEND_ARG_INFO ( 0 , type )
ZEND_END_ARG_INFO ( )
2008-11-18 03:34:03 +08:00
ZEND_BEGIN_ARG_INFO ( arginfo_sqlite3stmt_construct , 1 )
ZEND_ARG_INFO ( 0 , sqlite3 )
ZEND_END_ARG_INFO ( )
2008-08-01 06:30:26 +08:00
ZEND_BEGIN_ARG_INFO_EX ( arginfo_sqlite3result_columnname , 0 , 0 , 1 )
2008-07-25 10:44:59 +08:00
ZEND_ARG_INFO ( 0 , column_number )
ZEND_END_ARG_INFO ( )
2008-08-01 06:30:26 +08:00
ZEND_BEGIN_ARG_INFO_EX ( arginfo_sqlite3result_columntype , 0 , 0 , 1 )
2008-07-25 10:44:59 +08:00
ZEND_ARG_INFO ( 0 , column_number )
ZEND_END_ARG_INFO ( )
2008-08-01 06:30:26 +08:00
ZEND_BEGIN_ARG_INFO_EX ( arginfo_sqlite3result_fetcharray , 0 , 0 , 1 )
2008-07-25 10:44:59 +08:00
ZEND_ARG_INFO ( 0 , mode )
ZEND_END_ARG_INFO ( )
2009-01-04 06:08:38 +08:00
ZEND_BEGIN_ARG_INFO ( arginfo_sqlite3_void , 0 )
2008-11-18 03:34:03 +08:00
ZEND_END_ARG_INFO ( )
2008-07-25 10:44:59 +08:00
/* }}} */
/* {{{ php_sqlite3_class_methods */
static zend_function_entry php_sqlite3_class_methods [ ] = {
PHP_ME ( sqlite3 , open , arginfo_sqlite3_open , ZEND_ACC_PUBLIC )
2009-01-04 06:08:38 +08:00
PHP_ME ( sqlite3 , close , arginfo_sqlite3_void , ZEND_ACC_PUBLIC )
PHP_ME ( sqlite3 , exec , arginfo_sqlite3_query , ZEND_ACC_PUBLIC )
PHP_ME ( sqlite3 , version , arginfo_sqlite3_void , ZEND_ACC_PUBLIC | ZEND_ACC_STATIC )
PHP_ME ( sqlite3 , lastInsertRowID , arginfo_sqlite3_void , ZEND_ACC_PUBLIC )
PHP_ME ( sqlite3 , lastErrorCode , arginfo_sqlite3_void , ZEND_ACC_PUBLIC )
PHP_ME ( sqlite3 , lastErrorMsg , arginfo_sqlite3_void , ZEND_ACC_PUBLIC )
2010-06-20 23:30:49 +08:00
PHP_ME ( sqlite3 , busyTimeout , arginfo_sqlite3_busytimeout , ZEND_ACC_PUBLIC )
2009-03-17 10:45:12 +08:00
# ifndef SQLITE_OMIT_LOAD_EXTENSION
2008-07-25 10:44:59 +08:00
PHP_ME ( sqlite3 , loadExtension , arginfo_sqlite3_loadextension , ZEND_ACC_PUBLIC )
2009-03-17 10:45:12 +08:00
# endif
2009-01-04 06:08:38 +08:00
PHP_ME ( sqlite3 , changes , arginfo_sqlite3_void , ZEND_ACC_PUBLIC )
2008-09-30 19:14:48 +08:00
PHP_ME ( sqlite3 , escapeString , arginfo_sqlite3_escapestring , ZEND_ACC_PUBLIC | ZEND_ACC_STATIC )
2009-01-04 06:08:38 +08:00
PHP_ME ( sqlite3 , prepare , arginfo_sqlite3_query , ZEND_ACC_PUBLIC )
2008-07-25 10:44:59 +08:00
PHP_ME ( sqlite3 , query , arginfo_sqlite3_query , ZEND_ACC_PUBLIC )
PHP_ME ( sqlite3 , querySingle , arginfo_sqlite3_querysingle , ZEND_ACC_PUBLIC )
PHP_ME ( sqlite3 , createFunction , arginfo_sqlite3_createfunction , ZEND_ACC_PUBLIC )
PHP_ME ( sqlite3 , createAggregate , arginfo_sqlite3_createaggregate , ZEND_ACC_PUBLIC )
2012-01-29 11:57:29 +08:00
PHP_ME ( sqlite3 , createCollation , arginfo_sqlite3_createcollation , ZEND_ACC_PUBLIC )
2009-01-24 20:17:47 +08:00
PHP_ME ( sqlite3 , openBlob , argingo_sqlite3_openblob , ZEND_ACC_PUBLIC )
2009-04-28 02:16:46 +08:00
PHP_ME ( sqlite3 , enableExceptions , argingo_sqlite3_enableexceptions , ZEND_ACC_PUBLIC )
2008-07-25 10:44:59 +08:00
/* Aliases */
2008-11-18 03:34:03 +08:00
PHP_MALIAS ( sqlite3 , __construct , open , arginfo_sqlite3_open , ZEND_ACC_PUBLIC | ZEND_ACC_CTOR )
2011-07-25 19:35:02 +08:00
PHP_FE_END
2008-07-25 10:44:59 +08:00
} ;
/* }}} */
/* {{{ php_sqlite3_stmt_class_methods */
static zend_function_entry php_sqlite3_stmt_class_methods [ ] = {
2009-01-04 06:08:38 +08:00
PHP_ME ( sqlite3stmt , paramCount , arginfo_sqlite3_void , ZEND_ACC_PUBLIC )
PHP_ME ( sqlite3stmt , close , arginfo_sqlite3_void , ZEND_ACC_PUBLIC )
PHP_ME ( sqlite3stmt , reset , arginfo_sqlite3_void , ZEND_ACC_PUBLIC )
PHP_ME ( sqlite3stmt , clear , arginfo_sqlite3_void , ZEND_ACC_PUBLIC )
PHP_ME ( sqlite3stmt , execute , arginfo_sqlite3_void , ZEND_ACC_PUBLIC )
2008-08-01 06:30:26 +08:00
PHP_ME ( sqlite3stmt , bindParam , arginfo_sqlite3stmt_bindparam , ZEND_ACC_PUBLIC )
PHP_ME ( sqlite3stmt , bindValue , arginfo_sqlite3stmt_bindvalue , ZEND_ACC_PUBLIC )
2011-01-01 00:37:12 +08:00
PHP_ME ( sqlite3stmt , readOnly , arginfo_sqlite3_void , ZEND_ACC_PUBLIC )
2009-01-04 06:08:38 +08:00
PHP_ME ( sqlite3stmt , __construct , arginfo_sqlite3stmt_construct , ZEND_ACC_PRIVATE | ZEND_ACC_CTOR )
2011-07-25 19:35:02 +08:00
PHP_FE_END
2008-07-25 10:44:59 +08:00
} ;
/* }}} */
/* {{{ php_sqlite3_result_class_methods */
static zend_function_entry php_sqlite3_result_class_methods [ ] = {
2009-01-04 06:08:38 +08:00
PHP_ME ( sqlite3result , numColumns , arginfo_sqlite3_void , ZEND_ACC_PUBLIC )
2008-08-01 06:30:26 +08:00
PHP_ME ( sqlite3result , columnName , arginfo_sqlite3result_columnname , ZEND_ACC_PUBLIC )
PHP_ME ( sqlite3result , columnType , arginfo_sqlite3result_columntype , ZEND_ACC_PUBLIC )
PHP_ME ( sqlite3result , fetchArray , arginfo_sqlite3result_fetcharray , ZEND_ACC_PUBLIC )
2009-01-04 06:08:38 +08:00
PHP_ME ( sqlite3result , reset , arginfo_sqlite3_void , ZEND_ACC_PUBLIC )
PHP_ME ( sqlite3result , finalize , arginfo_sqlite3_void , ZEND_ACC_PUBLIC )
PHP_ME ( sqlite3result , __construct , arginfo_sqlite3_void , ZEND_ACC_PRIVATE | ZEND_ACC_CTOR )
2011-07-25 19:35:02 +08:00
PHP_FE_END
2008-07-25 10:44:59 +08:00
} ;
/* }}} */
2008-07-27 07:42:53 +08:00
/* {{{ Authorization Callback
*/
static int php_sqlite3_authorizer ( void * autharg , int access_type , const char * arg3 , const char * arg4 , const char * arg5 , const char * arg6 )
2008-07-25 10:44:59 +08:00
{
switch ( access_type ) {
case SQLITE_ATTACH :
{
2012-06-22 18:48:39 +08:00
if ( memcmp ( arg3 , " :memory: " , sizeof ( " :memory: " ) ) & & * arg3 ) {
2010-04-27 07:53:30 +08:00
TSRMLS_FETCH ( ) ;
# if PHP_API_VERSION < 20100412
2008-07-25 10:44:59 +08:00
if ( PG ( safe_mode ) & & ( ! php_checkuid ( arg3 , NULL , CHECKUID_CHECK_FILE_AND_DIR ) ) ) {
return SQLITE_DENY ;
}
2010-04-27 07:53:30 +08:00
# endif
2008-07-25 10:44:59 +08:00
if ( php_check_open_basedir ( arg3 TSRMLS_CC ) ) {
return SQLITE_DENY ;
}
}
return SQLITE_OK ;
}
default :
/* access allowed */
return SQLITE_OK ;
}
}
/* }}} */
2008-07-29 08:56:53 +08:00
/* {{{ php_sqlite3_free_list_dtor
2008-07-27 07:42:53 +08:00
*/
2008-07-29 08:56:53 +08:00
static void php_sqlite3_free_list_dtor ( void * * item )
2008-07-25 10:44:59 +08:00
{
2008-07-29 08:56:53 +08:00
php_sqlite3_free_list * free_item = ( php_sqlite3_free_list * ) * item ;
2008-07-25 10:44:59 +08:00
2008-07-29 08:56:53 +08:00
if ( free_item - > stmt_obj & & free_item - > stmt_obj - > initialised ) {
sqlite3_finalize ( free_item - > stmt_obj - > stmt ) ;
free_item - > stmt_obj - > initialised = 0 ;
2008-07-25 10:44:59 +08:00
}
efree ( * item ) ;
}
/* }}} */
2008-07-29 08:56:53 +08:00
static int php_sqlite3_compare_stmt_zval_free ( php_sqlite3_free_list * * free_list , zval * statement ) /* { { { */
2008-07-25 10:44:59 +08:00
{
2008-07-29 08:56:53 +08:00
return ( ( * free_list ) - > stmt_obj - > initialised & & statement = = ( * free_list ) - > stmt_obj_zval ) ;
}
/* }}} */
static int php_sqlite3_compare_stmt_free ( php_sqlite3_free_list * * free_list , sqlite3_stmt * statement ) /* { { { */
{
return ( ( * free_list ) - > stmt_obj - > initialised & & statement = = ( * free_list ) - > stmt_obj - > stmt ) ;
2008-07-25 10:44:59 +08:00
}
2008-07-27 07:42:53 +08:00
/* }}} */
2008-07-25 10:44:59 +08:00
2008-07-27 07:42:53 +08:00
static void php_sqlite3_object_free_storage ( void * object TSRMLS_DC ) /* { { { */
2008-07-25 10:44:59 +08:00
{
php_sqlite3_db_object * intern = ( php_sqlite3_db_object * ) object ;
php_sqlite3_func * func ;
2012-01-29 11:57:29 +08:00
php_sqlite3_collation * collation ;
2008-07-25 10:44:59 +08:00
if ( ! intern ) {
return ;
}
while ( intern - > funcs ) {
func = intern - > funcs ;
intern - > funcs = func - > next ;
if ( intern - > initialised & & intern - > db ) {
sqlite3_create_function ( intern - > db , func - > func_name , func - > argc , SQLITE_UTF8 , func , NULL , NULL , NULL ) ;
}
efree ( ( char * ) func - > func_name ) ;
if ( func - > func ) {
zval_ptr_dtor ( & func - > func ) ;
}
if ( func - > step ) {
zval_ptr_dtor ( & func - > step ) ;
}
if ( func - > fini ) {
zval_ptr_dtor ( & func - > fini ) ;
}
efree ( func ) ;
}
2012-01-29 11:57:29 +08:00
while ( intern - > collations ) {
collation = intern - > collations ;
intern - > collations = collation - > next ;
if ( intern - > initialised & & intern - > db ) {
sqlite3_create_collation ( intern - > db , collation - > collation_name , SQLITE_UTF8 , NULL , NULL ) ;
}
efree ( ( char * ) collation - > collation_name ) ;
if ( collation - > cmp_func ) {
zval_ptr_dtor ( & collation - > cmp_func ) ;
}
efree ( collation ) ;
}
2008-07-25 10:44:59 +08:00
if ( intern - > initialised & & intern - > db ) {
sqlite3_close ( intern - > db ) ;
intern - > initialised = 0 ;
}
zend_object_std_dtor ( & intern - > zo TSRMLS_CC ) ;
efree ( intern ) ;
}
2008-07-27 07:42:53 +08:00
/* }}} */
2008-07-25 10:44:59 +08:00
2008-07-27 07:42:53 +08:00
static void php_sqlite3_stmt_object_free_storage ( void * object TSRMLS_DC ) /* { { { */
2008-07-25 10:44:59 +08:00
{
php_sqlite3_stmt * intern = ( php_sqlite3_stmt * ) object ;
if ( ! intern ) {
return ;
}
if ( intern - > bound_params ) {
zend_hash_destroy ( intern - > bound_params ) ;
FREE_HASHTABLE ( intern - > bound_params ) ;
intern - > bound_params = NULL ;
}
if ( intern - > initialised ) {
2008-07-29 08:56:53 +08:00
zend_llist_del_element ( & ( intern - > db_obj - > free_list ) , intern - > stmt ,
( int ( * ) ( void * , void * ) ) php_sqlite3_compare_stmt_free ) ;
2008-07-25 10:44:59 +08:00
}
2008-09-15 08:55:37 +08:00
if ( intern - > db_obj_zval ) {
2011-01-07 09:11:16 +08:00
zval_ptr_dtor ( & intern - > db_obj_zval ) ;
2008-09-15 08:55:37 +08:00
}
2008-07-25 10:44:59 +08:00
zend_object_std_dtor ( & intern - > zo TSRMLS_CC ) ;
efree ( intern ) ;
}
2008-07-27 07:42:53 +08:00
/* }}} */
2008-07-25 10:44:59 +08:00
2008-07-27 07:42:53 +08:00
static void php_sqlite3_result_object_free_storage ( void * object TSRMLS_DC ) /* { { { */
2008-07-25 10:44:59 +08:00
{
php_sqlite3_result * intern = ( php_sqlite3_result * ) object ;
if ( ! intern ) {
return ;
}
2008-09-15 08:55:37 +08:00
if ( intern - > stmt_obj_zval ) {
if ( intern - > stmt_obj - > initialised ) {
sqlite3_reset ( intern - > stmt_obj - > stmt ) ;
}
2008-07-25 10:44:59 +08:00
2008-09-15 08:55:37 +08:00
if ( intern - > is_prepared_statement = = 0 ) {
zval_dtor ( intern - > stmt_obj_zval ) ;
FREE_ZVAL ( intern - > stmt_obj_zval ) ;
} else {
zval_ptr_dtor ( & intern - > stmt_obj_zval ) ;
}
2008-07-25 10:44:59 +08:00
}
zend_object_std_dtor ( & intern - > zo TSRMLS_CC ) ;
efree ( intern ) ;
}
2008-07-27 07:42:53 +08:00
/* }}} */
2008-07-25 10:44:59 +08:00
2008-07-27 07:42:53 +08:00
static zend_object_value php_sqlite3_object_new ( zend_class_entry * class_type TSRMLS_DC ) /* { { { */
2008-07-25 10:44:59 +08:00
{
zend_object_value retval ;
php_sqlite3_db_object * intern ;
/* Allocate memory for it */
intern = emalloc ( sizeof ( php_sqlite3_db_object ) ) ;
2011-08-10 23:30:07 +08:00
memset ( intern , 0 , sizeof ( php_sqlite3_db_object ) ) ;
2009-04-28 02:16:46 +08:00
intern - > exception = 0 ;
2008-07-25 10:44:59 +08:00
2008-07-29 08:56:53 +08:00
/* Need to keep track of things to free */
zend_llist_init ( & ( intern - > free_list ) , sizeof ( php_sqlite3_free_list * ) , ( llist_dtor_func_t ) php_sqlite3_free_list_dtor , 0 ) ;
2008-07-25 10:44:59 +08:00
zend_object_std_init ( & intern - > zo , class_type TSRMLS_CC ) ;
2010-05-24 22:11:39 +08:00
object_properties_init ( & intern - > zo , class_type ) ;
2008-07-25 10:44:59 +08:00
retval . handle = zend_objects_store_put ( intern , NULL , ( zend_objects_free_object_storage_t ) php_sqlite3_object_free_storage , NULL TSRMLS_CC ) ;
retval . handlers = ( zend_object_handlers * ) & sqlite3_object_handlers ;
return retval ;
}
2008-07-27 07:42:53 +08:00
/* }}} */
2008-07-25 10:44:59 +08:00
2008-07-27 07:42:53 +08:00
static zend_object_value php_sqlite3_stmt_object_new ( zend_class_entry * class_type TSRMLS_DC ) /* { { { */
2008-07-25 10:44:59 +08:00
{
zend_object_value retval ;
php_sqlite3_stmt * intern ;
/* Allocate memory for it */
intern = emalloc ( sizeof ( php_sqlite3_stmt ) ) ;
2011-08-10 23:30:07 +08:00
memset ( intern , 0 , sizeof ( php_sqlite3_stmt ) ) ;
2008-07-25 10:44:59 +08:00
2008-09-15 08:55:37 +08:00
intern - > db_obj_zval = NULL ;
2008-07-25 10:44:59 +08:00
zend_object_std_init ( & intern - > zo , class_type TSRMLS_CC ) ;
2010-05-24 22:11:39 +08:00
object_properties_init ( & intern - > zo , class_type ) ;
2008-07-25 10:44:59 +08:00
retval . handle = zend_objects_store_put ( intern , NULL , ( zend_objects_free_object_storage_t ) php_sqlite3_stmt_object_free_storage , NULL TSRMLS_CC ) ;
retval . handlers = ( zend_object_handlers * ) & sqlite3_stmt_object_handlers ;
return retval ;
}
2008-07-27 07:42:53 +08:00
/* }}} */
2008-07-25 10:44:59 +08:00
2008-07-27 07:42:53 +08:00
static zend_object_value php_sqlite3_result_object_new ( zend_class_entry * class_type TSRMLS_DC ) /* { { { */
2008-07-25 10:44:59 +08:00
{
zend_object_value retval ;
php_sqlite3_result * intern ;
/* Allocate memory for it */
intern = emalloc ( sizeof ( php_sqlite3_result ) ) ;
2011-08-10 23:30:07 +08:00
memset ( intern , 0 , sizeof ( php_sqlite3_result ) ) ;
2008-07-25 10:44:59 +08:00
intern - > complete = 0 ;
intern - > is_prepared_statement = 0 ;
2008-09-15 08:55:37 +08:00
intern - > stmt_obj_zval = NULL ;
2008-07-25 10:44:59 +08:00
zend_object_std_init ( & intern - > zo , class_type TSRMLS_CC ) ;
2010-05-24 22:11:39 +08:00
object_properties_init ( & intern - > zo , class_type ) ;
2008-07-25 10:44:59 +08:00
retval . handle = zend_objects_store_put ( intern , NULL , ( zend_objects_free_object_storage_t ) php_sqlite3_result_object_free_storage , NULL TSRMLS_CC ) ;
retval . handlers = ( zend_object_handlers * ) & sqlite3_result_object_handlers ;
return retval ;
}
2008-07-27 07:42:53 +08:00
/* }}} */
2008-07-25 10:44:59 +08:00
2008-07-27 07:42:53 +08:00
static void sqlite3_param_dtor ( void * data ) /* { { { */
2008-07-25 10:44:59 +08:00
{
struct php_sqlite3_bound_param * param = ( struct php_sqlite3_bound_param * ) data ;
if ( param - > name ) {
efree ( param - > name ) ;
}
if ( param - > parameter ) {
zval_ptr_dtor ( & ( param - > parameter ) ) ;
param - > parameter = NULL ;
}
}
2008-07-27 07:42:53 +08:00
/* }}} */
2008-07-25 10:44:59 +08:00
/* {{{ PHP_MINIT_FUNCTION
2008-07-27 07:42:53 +08:00
*/
2008-07-25 10:44:59 +08:00
PHP_MINIT_FUNCTION ( sqlite3 )
{
zend_class_entry ce ;
# if defined(ZTS)
/* Refuse to load if this wasn't a threasafe library loaded */
if ( ! sqlite3_threadsafe ( ) ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " A thread safe version of SQLite is required when using a thread safe version of PHP. " ) ;
return FAILURE ;
}
# endif
memcpy ( & sqlite3_object_handlers , zend_get_std_object_handlers ( ) , sizeof ( zend_object_handlers ) ) ;
memcpy ( & sqlite3_stmt_object_handlers , zend_get_std_object_handlers ( ) , sizeof ( zend_object_handlers ) ) ;
memcpy ( & sqlite3_result_object_handlers , zend_get_std_object_handlers ( ) , sizeof ( zend_object_handlers ) ) ;
/* Register SQLite 3 Class */
INIT_CLASS_ENTRY ( ce , " SQLite3 " , php_sqlite3_class_methods ) ;
ce . create_object = php_sqlite3_object_new ;
sqlite3_object_handlers . clone_obj = NULL ;
php_sqlite3_sc_entry = zend_register_internal_class ( & ce TSRMLS_CC ) ;
/* Register SQLite 3 Prepared Statement Class */
2008-08-01 06:30:26 +08:00
INIT_CLASS_ENTRY ( ce , " SQLite3Stmt " , php_sqlite3_stmt_class_methods ) ;
2008-07-25 10:44:59 +08:00
ce . create_object = php_sqlite3_stmt_object_new ;
sqlite3_stmt_object_handlers . clone_obj = NULL ;
php_sqlite3_stmt_entry = zend_register_internal_class ( & ce TSRMLS_CC ) ;
/* Register SQLite 3 Result Class */
2008-08-01 06:30:26 +08:00
INIT_CLASS_ENTRY ( ce , " SQLite3Result " , php_sqlite3_result_class_methods ) ;
2008-07-25 10:44:59 +08:00
ce . create_object = php_sqlite3_result_object_new ;
sqlite3_result_object_handlers . clone_obj = NULL ;
php_sqlite3_result_entry = zend_register_internal_class ( & ce TSRMLS_CC ) ;
REGISTER_INI_ENTRIES ( ) ;
REGISTER_LONG_CONSTANT ( " SQLITE3_ASSOC " , PHP_SQLITE3_ASSOC , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SQLITE3_NUM " , PHP_SQLITE3_NUM , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SQLITE3_BOTH " , PHP_SQLITE3_BOTH , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SQLITE3_INTEGER " , SQLITE_INTEGER , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SQLITE3_FLOAT " , SQLITE_FLOAT , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SQLITE3_TEXT " , SQLITE3_TEXT , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SQLITE3_BLOB " , SQLITE_BLOB , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SQLITE3_NULL " , SQLITE_NULL , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SQLITE3_OPEN_READONLY " , SQLITE_OPEN_READONLY , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SQLITE3_OPEN_READWRITE " , SQLITE_OPEN_READWRITE , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SQLITE3_OPEN_CREATE " , SQLITE_OPEN_CREATE , CONST_CS | CONST_PERSISTENT ) ;
return SUCCESS ;
}
/* }}} */
/* {{{ PHP_MSHUTDOWN_FUNCTION
2008-07-27 07:42:53 +08:00
*/
2008-07-25 10:44:59 +08:00
PHP_MSHUTDOWN_FUNCTION ( sqlite3 )
{
UNREGISTER_INI_ENTRIES ( ) ;
return SUCCESS ;
}
/* }}} */
/* {{{ PHP_MINFO_FUNCTION
2008-07-27 07:42:53 +08:00
*/
2008-07-25 10:44:59 +08:00
PHP_MINFO_FUNCTION ( sqlite3 )
{
php_info_print_table_start ( ) ;
php_info_print_table_header ( 2 , " SQLite3 support " , " enabled " ) ;
php_info_print_table_row ( 2 , " SQLite3 module version " , PHP_SQLITE3_VERSION ) ;
php_info_print_table_row ( 2 , " SQLite Library " , sqlite3_libversion ( ) ) ;
php_info_print_table_end ( ) ;
DISPLAY_INI_ENTRIES ( ) ;
}
2008-07-27 07:42:53 +08:00
/* }}} */
2008-07-25 10:44:59 +08:00
/* {{{ PHP_GINIT_FUNCTION
2008-07-27 07:42:53 +08:00
*/
2008-07-25 10:44:59 +08:00
static PHP_GINIT_FUNCTION ( sqlite3 )
{
memset ( sqlite3_globals , 0 , sizeof ( * sqlite3_globals ) ) ;
}
/* }}} */
/* {{{ sqlite3_module_entry
2008-07-27 07:42:53 +08:00
*/
2008-07-25 10:44:59 +08:00
zend_module_entry sqlite3_module_entry = {
STANDARD_MODULE_HEADER ,
" sqlite3 " ,
NULL ,
PHP_MINIT ( sqlite3 ) ,
PHP_MSHUTDOWN ( sqlite3 ) ,
NULL ,
NULL ,
PHP_MINFO ( sqlite3 ) ,
PHP_SQLITE3_VERSION ,
PHP_MODULE_GLOBALS ( sqlite3 ) ,
PHP_GINIT ( sqlite3 ) ,
NULL ,
NULL ,
STANDARD_MODULE_PROPERTIES_EX
} ;
/* }}} */
# ifdef COMPILE_DL_SQLITE3
ZEND_GET_MODULE ( sqlite3 )
# endif
/*
* Local variables :
* tab - width : 4
* c - basic - offset : 4
* End :
* vim600 : sw = 4 ts = 4 fdm = marker
* vim < 600 : sw = 4 ts = 4
*/