2003-04-17 09:29:45 +08:00
/*
2003-06-15 02:16:47 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2004-01-08 16:18:22 +08:00
| PHP Version 5 |
2003-06-15 02:16:47 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2004-01-08 16:18:22 +08:00
| Copyright ( c ) 1997 - 2004 The PHP Group |
2003-06-15 02:16:47 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| This source file is subject to version 3.0 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_0.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 : Wez Furlong < wez @ thebrainroom . com > |
| Tal Peer < tal @ php . net > |
| Marcus Boerger < helly @ php . net > |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
$ Id $
2003-04-17 09:29:45 +08:00
*/
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
2003-06-23 01:19:46 +08:00
# define PHP_SQLITE_MODULE_VERSION "1.1-dev"
2003-04-18 03:13:21 +08:00
2003-04-17 09:29:45 +08:00
# include "php.h"
# include "php_ini.h"
# include "ext/standard/info.h"
2003-07-01 21:07:37 +08:00
# include "ext/session/php_session.h"
2003-04-17 09:29:45 +08:00
# include "php_sqlite.h"
2003-04-18 20:22:43 +08:00
# if HAVE_TIME_H
# include <time.h>
# endif
2003-06-27 22:30:26 +08:00
# if HAVE_UNISTD_H
2003-04-18 20:22:43 +08:00
# include <unistd.h>
2003-06-27 22:30:26 +08:00
# endif
2003-04-18 20:22:43 +08:00
2003-04-17 09:29:45 +08:00
# include <sqlite.h>
2004-02-12 18:43:27 +08:00
# include "zend_exceptions.h"
2003-07-06 04:02:40 +08:00
2003-04-27 21:46:07 +08:00
# ifndef safe_emalloc
2003-06-20 04:57:11 +08:00
# define safe_emalloc(a,b,c) emalloc((a)*(b)+(c))
2003-04-27 21:46:07 +08:00
# endif
2003-04-22 08:08:48 +08:00
ZEND_DECLARE_MODULE_GLOBALS ( sqlite )
2003-07-02 01:55:32 +08:00
# if HAVE_PHP_SESSION
2003-07-01 21:07:37 +08:00
extern ps_module ps_mod_sqlite ;
# define ps_sqlite_ptr &ps_mod_sqlite
2003-07-02 01:55:32 +08:00
# endif
2003-07-01 21:07:37 +08:00
2003-04-19 20:54:17 +08:00
extern int sqlite_encode_binary ( const unsigned char * in , int n , unsigned char * out ) ;
extern int sqlite_decode_binary ( const unsigned char * in , unsigned char * out ) ;
2003-08-17 23:43:41 +08:00
# define php_sqlite_encode_binary(in, n, out) sqlite_encode_binary((const unsigned char *)in, n, (unsigned char *)out)
# define php_sqlite_decode_binary(in, out) sqlite_decode_binary((const unsigned char *)in, (unsigned char *)out)
2003-04-19 00:30:16 +08:00
static int le_sqlite_db , le_sqlite_result , le_sqlite_pdb ;
2003-04-22 08:08:48 +08:00
static inline void php_sqlite_strtoupper ( char * s )
{
2003-04-27 21:32:43 +08:00
while ( * s ! = ' \0 ' ) {
* s = toupper ( * s ) ;
s + + ;
}
2003-04-22 08:08:48 +08:00
}
static inline void php_sqlite_strtolower ( char * s )
{
2003-04-27 21:32:43 +08:00
while ( * s ! = ' \0 ' ) {
* s = tolower ( * s ) ;
s + + ;
}
2003-04-22 08:08:48 +08:00
}
/* {{{ PHP_INI
*/
PHP_INI_BEGIN ( )
2003-06-05 06:40:00 +08:00
STD_PHP_INI_ENTRY_EX ( " sqlite.assoc_case " , " 0 " , PHP_INI_ALL , OnUpdateLong , assoc_case , zend_sqlite_globals , sqlite_globals , display_link_numbers )
2003-04-22 08:08:48 +08:00
PHP_INI_END ( )
/* }}} */
2003-04-19 00:30:16 +08:00
# define DB_FROM_ZVAL(db, zv) ZEND_FETCH_RESOURCE2(db, struct php_sqlite_db *, zv, -1, "sqlite database", le_sqlite_db, le_sqlite_pdb)
2003-04-17 09:29:45 +08:00
2003-06-23 01:19:46 +08:00
# define DB_FROM_OBJECT(db, object) \
{ \
sqlite_object * obj = ( sqlite_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ; \
db = obj - > u . db ; \
if ( ! db ) { \
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " The database wasn't opened " ) ; \
RETURN_NULL ( ) ; \
} \
}
# define RES_FROM_OBJECT(res, object) \
{ \
sqlite_object * obj = ( sqlite_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ; \
res = obj - > u . res ; \
if ( ! res ) { \
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " No result set available " ) ; \
RETURN_NULL ( ) ; \
} \
}
# define SQLITE_THROW(message) \
PG ( suppress_errors ) = 0 ; \
2003-08-26 04:55:14 +08:00
EG ( exception ) = zend_throw_exception ( sqlite_ce_exception , message , 0 TSRMLS_CC ) ;
2003-06-23 01:19:46 +08:00
2003-04-17 09:29:45 +08:00
struct php_sqlite_result {
2003-05-03 06:09:54 +08:00
struct php_sqlite_db * db ;
2003-04-18 20:22:43 +08:00
sqlite_vm * vm ;
int buffered ;
2003-04-17 09:29:45 +08:00
int ncolumns ;
2003-04-18 20:22:43 +08:00
int nrows ;
2003-04-17 09:29:45 +08:00
int curr_row ;
2003-04-18 20:22:43 +08:00
char * * col_names ;
int alloc_rows ;
2003-04-30 23:18:59 +08:00
int mode ;
2004-02-24 23:47:38 +08:00
char * * table ;
2003-04-17 09:29:45 +08:00
} ;
2003-04-18 04:08:00 +08:00
struct php_sqlite_db {
sqlite * db ;
int last_err_code ;
2003-07-01 21:26:49 +08:00
zend_bool is_persistent ;
2004-02-24 23:47:38 +08:00
long rsrc_id ;
2003-04-20 23:13:04 +08:00
HashTable callbacks ;
2003-04-18 04:08:00 +08:00
} ;
2003-04-20 21:08:22 +08:00
struct php_sqlite_agg_functions {
2003-04-20 23:13:04 +08:00
struct php_sqlite_db * db ;
int is_valid ;
2003-04-20 21:08:22 +08:00
zval * step ;
2003-04-20 23:13:04 +08:00
zval * fini ;
2003-04-20 21:08:22 +08:00
} ;
2003-10-18 01:21:56 +08:00
static void php_sqlite_fetch_array ( struct php_sqlite_result * res , int mode , zend_bool decode_binary , int move_next , zval * return_value TSRMLS_DC ) ;
static int php_sqlite_fetch ( struct php_sqlite_result * rres TSRMLS_DC ) ;
2003-04-20 21:08:22 +08:00
2003-04-17 09:29:45 +08:00
enum { PHPSQLITE_ASSOC = 1 , PHPSQLITE_NUM = 2 , PHPSQLITE_BOTH = PHPSQLITE_ASSOC | PHPSQLITE_NUM } ;
function_entry sqlite_functions [ ] = {
2003-08-04 01:44:39 +08:00
PHP_FE ( sqlite_open , third_arg_force_ref )
PHP_FE ( sqlite_popen , third_arg_force_ref )
2003-04-17 09:29:45 +08:00
PHP_FE ( sqlite_close , NULL )
PHP_FE ( sqlite_query , NULL )
2003-06-10 07:14:25 +08:00
PHP_FE ( sqlite_array_query , NULL )
2003-06-26 00:59:24 +08:00
PHP_FE ( sqlite_single_query , NULL )
2003-04-17 09:29:45 +08:00
PHP_FE ( sqlite_fetch_array , NULL )
2003-08-29 07:19:51 +08:00
PHP_FE ( sqlite_fetch_object , NULL )
2003-06-27 03:26:26 +08:00
PHP_FE ( sqlite_fetch_single , NULL )
PHP_FALIAS ( sqlite_fetch_string , sqlite_fetch_single , NULL )
2003-06-07 03:00:16 +08:00
PHP_FE ( sqlite_fetch_all , NULL )
2003-05-03 06:09:54 +08:00
PHP_FE ( sqlite_current , NULL )
2003-05-03 20:51:13 +08:00
PHP_FE ( sqlite_column , NULL )
2003-04-17 09:29:45 +08:00
PHP_FE ( sqlite_libversion , NULL )
PHP_FE ( sqlite_libencoding , NULL )
PHP_FE ( sqlite_changes , NULL )
PHP_FE ( sqlite_last_insert_rowid , NULL )
PHP_FE ( sqlite_num_rows , NULL )
PHP_FE ( sqlite_num_fields , NULL )
PHP_FE ( sqlite_field_name , NULL )
PHP_FE ( sqlite_seek , NULL )
2003-05-03 06:09:54 +08:00
PHP_FE ( sqlite_rewind , NULL )
PHP_FE ( sqlite_next , NULL )
2003-07-13 17:38:33 +08:00
PHP_FE ( sqlite_prev , NULL )
2003-05-03 06:09:54 +08:00
PHP_FE ( sqlite_has_more , NULL )
2003-07-13 17:38:33 +08:00
PHP_FE ( sqlite_has_prev , NULL )
2003-04-17 10:20:26 +08:00
PHP_FE ( sqlite_escape_string , NULL )
2003-04-18 00:57:46 +08:00
PHP_FE ( sqlite_busy_timeout , NULL )
2003-04-18 04:08:00 +08:00
PHP_FE ( sqlite_last_error , NULL )
PHP_FE ( sqlite_error_string , NULL )
2003-04-18 20:22:43 +08:00
PHP_FE ( sqlite_unbuffered_query , NULL )
2003-04-20 21:08:22 +08:00
PHP_FE ( sqlite_create_aggregate , NULL )
2003-04-20 21:31:36 +08:00
PHP_FE ( sqlite_create_function , NULL )
2003-08-04 01:44:39 +08:00
PHP_FE ( sqlite_factory , third_arg_force_ref )
2003-06-21 20:29:32 +08:00
PHP_FE ( sqlite_udf_encode_binary , NULL )
PHP_FE ( sqlite_udf_decode_binary , NULL )
2003-12-19 05:28:00 +08:00
PHP_FE ( sqlite_fetch_column_types , NULL )
2003-04-17 09:29:45 +08:00
{ NULL , NULL , NULL }
} ;
2003-06-23 01:19:46 +08:00
function_entry sqlite_funcs_db [ ] = {
PHP_ME_MAPPING ( sqlite_db , sqlite_open , NULL )
2003-06-23 03:00:44 +08:00
/* PHP_ME_MAPPING(close, sqlite_close, NULL)*/
2003-06-23 01:19:46 +08:00
PHP_ME_MAPPING ( query , sqlite_query , NULL )
PHP_ME_MAPPING ( array_query , sqlite_array_query , NULL )
2003-06-26 00:59:24 +08:00
PHP_ME_MAPPING ( single_query , sqlite_single_query , NULL )
2003-06-23 01:19:46 +08:00
PHP_ME_MAPPING ( unbuffered_query , sqlite_unbuffered_query , NULL )
PHP_ME_MAPPING ( last_insert_rowid , sqlite_last_insert_rowid , NULL )
2003-12-11 02:56:05 +08:00
PHP_ME_MAPPING ( changes , sqlite_changes , NULL )
2003-06-23 01:19:46 +08:00
PHP_ME_MAPPING ( create_aggregate , sqlite_create_aggregate , NULL )
PHP_ME_MAPPING ( create_function , sqlite_create_function , NULL )
PHP_ME_MAPPING ( busy_timeout , sqlite_busy_timeout , NULL )
PHP_ME_MAPPING ( last_error , sqlite_last_error , NULL )
2003-12-19 05:28:00 +08:00
PHP_ME_MAPPING ( fetch_column_types , sqlite_fetch_column_types , NULL )
2003-06-23 01:19:46 +08:00
/* PHP_ME_MAPPING(error_string, sqlite_error_string, NULL) static */
/* PHP_ME_MAPPING(escape_string, sqlite_escape_string, NULL) static */
{ NULL , NULL , NULL }
} ;
function_entry sqlite_funcs_query [ ] = {
PHP_ME_MAPPING ( fetch_array , sqlite_fetch_array , NULL )
2003-08-29 07:19:51 +08:00
PHP_ME_MAPPING ( fetch_object , sqlite_fetch_object , NULL )
2003-06-27 03:26:26 +08:00
PHP_ME_MAPPING ( fetch_single , sqlite_fetch_single , NULL )
2003-06-23 01:19:46 +08:00
PHP_ME_MAPPING ( fetch_all , sqlite_fetch_all , NULL )
PHP_ME_MAPPING ( column , sqlite_column , NULL )
PHP_ME_MAPPING ( num_fields , sqlite_num_fields , NULL )
PHP_ME_MAPPING ( field_name , sqlite_field_name , NULL )
/* spl_forward */
PHP_ME_MAPPING ( current , sqlite_current , NULL )
PHP_ME_MAPPING ( next , sqlite_next , NULL )
2003-09-04 22:54:53 +08:00
PHP_ME_MAPPING ( hasmore , sqlite_has_more , NULL )
2003-06-23 01:19:46 +08:00
/* spl_sequence */
PHP_ME_MAPPING ( rewind , sqlite_rewind , NULL )
/* additional */
2003-10-17 16:01:49 +08:00
PHP_ME_MAPPING ( prev , sqlite_prev , NULL )
PHP_ME_MAPPING ( hasprev , sqlite_has_prev , NULL )
2003-06-23 01:19:46 +08:00
PHP_ME_MAPPING ( num_rows , sqlite_num_rows , NULL )
PHP_ME_MAPPING ( seek , sqlite_seek , NULL )
{ NULL , NULL , NULL }
} ;
function_entry sqlite_funcs_ub_query [ ] = {
PHP_ME_MAPPING ( fetch_array , sqlite_fetch_array , NULL )
2003-08-29 07:19:51 +08:00
PHP_ME_MAPPING ( fetch_object , sqlite_fetch_object , NULL )
2003-06-27 03:26:26 +08:00
PHP_ME_MAPPING ( fetch_single , sqlite_fetch_single , NULL )
2003-06-23 01:19:46 +08:00
PHP_ME_MAPPING ( fetch_all , sqlite_fetch_all , NULL )
PHP_ME_MAPPING ( column , sqlite_column , NULL )
PHP_ME_MAPPING ( num_fields , sqlite_num_fields , NULL )
PHP_ME_MAPPING ( field_name , sqlite_field_name , NULL )
/* spl_forward */
PHP_ME_MAPPING ( current , sqlite_current , NULL )
PHP_ME_MAPPING ( next , sqlite_next , NULL )
2003-09-04 22:54:53 +08:00
PHP_ME_MAPPING ( hasmore , sqlite_has_more , NULL )
2003-06-23 01:19:46 +08:00
{ NULL , NULL , NULL }
} ;
function_entry sqlite_funcs_exception [ ] = {
{ NULL , NULL , NULL }
} ;
2003-04-17 09:29:45 +08:00
zend_module_entry sqlite_module_entry = {
# if ZEND_MODULE_API_NO >= 20010901
STANDARD_MODULE_HEADER ,
# endif
" sqlite " ,
sqlite_functions ,
PHP_MINIT ( sqlite ) ,
NULL ,
2003-06-23 01:19:46 +08:00
PHP_RINIT ( sqlite ) ,
2003-04-19 00:30:16 +08:00
PHP_RSHUTDOWN ( sqlite ) ,
2003-04-17 09:29:45 +08:00
PHP_MINFO ( sqlite ) ,
# if ZEND_MODULE_API_NO >= 20010901
2003-04-18 03:13:21 +08:00
PHP_SQLITE_MODULE_VERSION ,
2003-04-17 09:29:45 +08:00
# endif
STANDARD_MODULE_PROPERTIES
} ;
# ifdef COMPILE_DL_SQLITE
ZEND_GET_MODULE ( sqlite )
2003-08-31 20:41:53 +08:00
# ifdef PHP_WIN32
# include "zend_arg_defs.c"
# endif
2003-04-17 09:29:45 +08:00
# endif
2003-04-20 23:13:04 +08:00
static int php_sqlite_callback_invalidator ( struct php_sqlite_agg_functions * funcs TSRMLS_DC )
{
if ( ! funcs - > is_valid ) {
return 0 ;
}
if ( funcs - > step ) {
zval_ptr_dtor ( & funcs - > step ) ;
funcs - > step = NULL ;
}
if ( funcs - > fini ) {
zval_ptr_dtor ( & funcs - > fini ) ;
funcs - > fini = NULL ;
}
funcs - > is_valid = 0 ;
return 0 ;
}
static void php_sqlite_callback_dtor ( void * pDest )
{
struct php_sqlite_agg_functions * funcs = ( struct php_sqlite_agg_functions * ) pDest ;
if ( funcs - > is_valid ) {
TSRMLS_FETCH ( ) ;
php_sqlite_callback_invalidator ( funcs TSRMLS_CC ) ;
}
}
2003-07-13 16:48:43 +08:00
2003-04-17 09:29:45 +08:00
static ZEND_RSRC_DTOR_FUNC ( php_sqlite_db_dtor )
{
2003-04-19 00:30:16 +08:00
if ( rsrc - > ptr ) {
struct php_sqlite_db * db = ( struct php_sqlite_db * ) rsrc - > ptr ;
2003-07-13 17:20:40 +08:00
2003-04-19 00:30:16 +08:00
sqlite_close ( db - > db ) ;
2003-04-20 23:13:04 +08:00
zend_hash_destroy ( & db - > callbacks ) ;
2003-04-19 00:30:16 +08:00
pefree ( db , db - > is_persistent ) ;
2003-04-18 04:08:00 +08:00
2003-04-19 00:30:16 +08:00
rsrc - > ptr = NULL ;
}
2003-04-17 09:29:45 +08:00
}
2003-05-03 06:09:54 +08:00
static void real_result_dtor ( struct php_sqlite_result * res TSRMLS_DC )
2003-04-17 09:29:45 +08:00
{
2003-04-18 20:22:43 +08:00
int i , j , base ;
if ( res - > vm ) {
sqlite_finalize ( res - > vm , NULL ) ;
}
2003-04-27 21:25:10 +08:00
2003-05-03 06:09:54 +08:00
if ( res - > table ) {
if ( ! res - > buffered & & res - > nrows ) {
2003-05-03 06:22:16 +08:00
res - > nrows = 1 ; /* only one row is stored */
}
2003-05-03 06:17:01 +08:00
for ( i = 0 ; i < res - > nrows ; i + + ) {
base = i * res - > ncolumns ;
for ( j = 0 ; j < res - > ncolumns ; j + + ) {
if ( res - > table [ base + j ] ! = NULL ) {
efree ( res - > table [ base + j ] ) ;
}
2003-04-19 18:28:45 +08:00
}
2003-04-18 20:22:43 +08:00
}
efree ( res - > table ) ;
}
if ( res - > col_names ) {
for ( j = 0 ; j < res - > ncolumns ; j + + ) {
efree ( res - > col_names [ j ] ) ;
}
efree ( res - > col_names ) ;
}
2003-04-17 09:29:45 +08:00
2003-05-03 06:09:54 +08:00
zend_list_delete ( res - > db - > rsrc_id ) ;
2003-04-17 09:29:45 +08:00
efree ( res ) ;
}
2003-04-18 20:22:43 +08:00
static ZEND_RSRC_DTOR_FUNC ( php_sqlite_result_dtor )
{
struct php_sqlite_result * res = ( struct php_sqlite_result * ) rsrc - > ptr ;
2003-05-03 06:09:54 +08:00
real_result_dtor ( res TSRMLS_CC ) ;
2003-04-18 20:22:43 +08:00
}
2003-04-19 00:30:16 +08:00
static int php_sqlite_forget_persistent_id_numbers ( zend_rsrc_list_entry * rsrc TSRMLS_DC )
{
2003-12-28 06:16:13 +08:00
struct php_sqlite_db * db = ( struct php_sqlite_db * ) rsrc - > ptr ;
2003-04-19 00:30:16 +08:00
if ( Z_TYPE_P ( rsrc ) ! = le_sqlite_pdb ) {
return 0 ;
}
2004-01-16 05:30:31 +08:00
/* prevent bad mojo if someone tries to use a previously registered function in the next request */
zend_hash_apply ( & db - > callbacks , ( apply_func_t ) php_sqlite_callback_invalidator TSRMLS_CC ) ;
2003-04-19 00:30:16 +08:00
db - > rsrc_id = FAILURE ;
/* don't leave pending commits hanging around */
sqlite_exec ( db - > db , " ROLLBACK " , NULL , NULL , NULL ) ;
return 0 ;
}
PHP_RSHUTDOWN_FUNCTION ( sqlite )
{
zend_hash_apply ( & EG ( persistent_list ) , ( apply_func_t ) php_sqlite_forget_persistent_id_numbers TSRMLS_CC ) ;
return SUCCESS ;
}
2003-04-18 04:09:45 +08:00
/* {{{ PHP Function interface */
2003-04-20 21:31:36 +08:00
static void php_sqlite_generic_function_callback ( sqlite_func * func , int argc , const char * * argv )
2003-04-17 11:14:14 +08:00
{
zval * retval = NULL ;
2003-04-27 21:25:10 +08:00
zval * * * zargs = NULL ;
2003-04-17 11:14:14 +08:00
zval funcname ;
int i , res ;
2003-04-17 11:38:20 +08:00
char * callable = NULL , * errbuf = NULL ;
2003-04-19 03:43:38 +08:00
TSRMLS_FETCH ( ) ;
2003-04-17 11:14:14 +08:00
/* sanity check the args */
if ( argc = = 0 ) {
sqlite_set_result_error ( func , " not enough parameters " , - 1 ) ;
return ;
}
2003-10-26 07:17:15 +08:00
ZVAL_STRING ( & funcname , ( char * ) argv [ 0 ] , 1 ) ;
2003-04-17 11:14:14 +08:00
2003-10-26 07:17:15 +08:00
if ( ! zend_make_callable ( & funcname , & callable TSRMLS_CC ) ) {
2003-12-29 00:26:04 +08:00
spprintf ( & errbuf , 0 , " function `%s' is not a function name " , callable ) ;
2003-04-17 11:38:20 +08:00
sqlite_set_result_error ( func , errbuf , - 1 ) ;
efree ( errbuf ) ;
efree ( callable ) ;
2003-10-26 07:17:15 +08:00
zval_dtor ( & funcname ) ;
2003-04-17 11:14:14 +08:00
return ;
}
if ( argc > 1 ) {
2003-04-27 21:46:07 +08:00
zargs = ( zval * * * ) safe_emalloc ( ( argc - 1 ) , sizeof ( zval * * ) , 0 ) ;
2003-04-17 11:14:14 +08:00
for ( i = 0 ; i < argc - 1 ; i + + ) {
zargs [ i ] = emalloc ( sizeof ( zval * ) ) ;
MAKE_STD_ZVAL ( * zargs [ i ] ) ;
2003-04-18 00:36:59 +08:00
ZVAL_STRING ( * zargs [ i ] , ( char * ) argv [ i + 1 ] , 1 ) ;
2003-04-17 11:14:14 +08:00
}
}
res = call_user_function_ex ( EG ( function_table ) ,
NULL ,
& funcname ,
& retval ,
argc - 1 ,
zargs ,
0 , NULL TSRMLS_CC ) ;
2003-12-29 00:26:04 +08:00
2003-10-26 07:17:15 +08:00
zval_dtor ( & funcname ) ;
2003-04-17 11:14:14 +08:00
if ( res = = SUCCESS ) {
if ( retval = = NULL ) {
sqlite_set_result_string ( func , NULL , 0 ) ;
} else {
switch ( Z_TYPE_P ( retval ) ) {
case IS_STRING :
sqlite_set_result_string ( func , Z_STRVAL_P ( retval ) , Z_STRLEN_P ( retval ) ) ;
break ;
case IS_LONG :
case IS_BOOL :
sqlite_set_result_int ( func , Z_LVAL_P ( retval ) ) ;
break ;
case IS_DOUBLE :
sqlite_set_result_double ( func , Z_DVAL_P ( retval ) ) ;
break ;
case IS_NULL :
default :
sqlite_set_result_string ( func , NULL , 0 ) ;
}
}
} else {
2003-12-29 00:26:04 +08:00
char * errbuf ;
spprintf ( & errbuf , 0 , " call_user_function_ex failed for function %s() " , callable ) ;
sqlite_set_result_error ( func , errbuf , - 1 ) ;
efree ( errbuf ) ;
2003-04-17 11:14:14 +08:00
}
2003-12-29 00:26:04 +08:00
efree ( callable ) ;
2003-04-17 11:14:14 +08:00
if ( retval ) {
zval_ptr_dtor ( & retval ) ;
}
if ( zargs ) {
for ( i = 0 ; i < argc - 1 ; i + + ) {
2003-04-18 00:36:59 +08:00
zval_ptr_dtor ( zargs [ i ] ) ;
2003-04-17 11:14:14 +08:00
efree ( zargs [ i ] ) ;
}
efree ( zargs ) ;
}
}
2003-04-18 04:09:45 +08:00
/* }}} */
2003-04-18 00:36:59 +08:00
2003-04-20 23:13:04 +08:00
/* {{{ callback for sqlite_create_function */
2003-04-20 21:31:36 +08:00
static void php_sqlite_function_callback ( sqlite_func * func , int argc , const char * * argv )
{
zval * retval = NULL ;
2003-04-27 21:25:10 +08:00
zval * * * zargs = NULL ;
2003-04-20 21:31:36 +08:00
int i , res ;
struct php_sqlite_agg_functions * funcs = sqlite_user_data ( func ) ;
TSRMLS_FETCH ( ) ;
2003-04-20 23:13:04 +08:00
if ( ! funcs - > is_valid ) {
sqlite_set_result_error ( func , " this function has not been correctly defined for this request " , - 1 ) ;
return ;
}
2003-04-20 21:31:36 +08:00
if ( argc > 0 ) {
2003-04-27 21:46:07 +08:00
zargs = ( zval * * * ) safe_emalloc ( argc , sizeof ( zval * * ) , 0 ) ;
2003-04-20 21:31:36 +08:00
for ( i = 0 ; i < argc ; i + + ) {
zargs [ i ] = emalloc ( sizeof ( zval * ) ) ;
MAKE_STD_ZVAL ( * zargs [ i ] ) ;
2003-06-20 04:57:11 +08:00
if ( argv [ i ] = = NULL ) {
ZVAL_NULL ( * zargs [ i ] ) ;
} else {
ZVAL_STRING ( * zargs [ i ] , ( char * ) argv [ i ] , 1 ) ;
}
2003-04-20 21:31:36 +08:00
}
}
res = call_user_function_ex ( EG ( function_table ) ,
NULL ,
funcs - > step ,
& retval ,
argc ,
zargs ,
0 , NULL TSRMLS_CC ) ;
if ( res = = SUCCESS ) {
if ( retval = = NULL ) {
sqlite_set_result_string ( func , NULL , 0 ) ;
} else {
switch ( Z_TYPE_P ( retval ) ) {
case IS_STRING :
2003-06-20 04:57:11 +08:00
/* TODO: for binary results, need to encode the string */
2003-04-20 21:31:36 +08:00
sqlite_set_result_string ( func , Z_STRVAL_P ( retval ) , Z_STRLEN_P ( retval ) ) ;
break ;
case IS_LONG :
case IS_BOOL :
sqlite_set_result_int ( func , Z_LVAL_P ( retval ) ) ;
break ;
case IS_DOUBLE :
sqlite_set_result_double ( func , Z_DVAL_P ( retval ) ) ;
break ;
case IS_NULL :
default :
sqlite_set_result_string ( func , NULL , 0 ) ;
}
}
} else {
sqlite_set_result_error ( func , " call_user_function_ex failed " , - 1 ) ;
}
if ( retval ) {
zval_ptr_dtor ( & retval ) ;
}
if ( zargs ) {
for ( i = 0 ; i < argc ; i + + ) {
zval_ptr_dtor ( zargs [ i ] ) ;
efree ( zargs [ i ] ) ;
}
efree ( zargs ) ;
}
}
2003-04-20 23:13:04 +08:00
/* }}} */
2003-04-20 21:31:36 +08:00
2003-04-20 23:13:04 +08:00
/* {{{ callback for sqlite_create_aggregate: step function */
2003-04-20 21:08:22 +08:00
static void php_sqlite_agg_step_function_callback ( sqlite_func * func , int argc , const char * * argv )
{
zval * retval = NULL ;
zval * * * zargs ;
zval * * context_p ;
int i , res , zargc ;
struct php_sqlite_agg_functions * funcs = sqlite_user_data ( func ) ;
TSRMLS_FETCH ( ) ;
2003-04-20 23:13:04 +08:00
if ( ! funcs - > is_valid ) {
sqlite_set_result_error ( func , " this function has not been correctly defined for this request " , - 1 ) ;
return ;
}
2003-04-20 21:08:22 +08:00
/* sanity check the args */
if ( argc < 1 ) {
return ;
}
zargc = argc + 1 ;
2003-04-27 21:46:07 +08:00
zargs = ( zval * * * ) safe_emalloc ( zargc , sizeof ( zval * * ) , 0 ) ;
2003-04-20 21:08:22 +08:00
/* first arg is always the context zval */
context_p = ( zval * * ) sqlite_aggregate_context ( func , sizeof ( * context_p ) ) ;
2003-04-20 23:13:04 +08:00
2003-04-20 21:08:22 +08:00
if ( * context_p = = NULL ) {
MAKE_STD_ZVAL ( * context_p ) ;
2003-04-20 23:13:04 +08:00
( * context_p ) - > is_ref = 1 ;
Z_TYPE_PP ( context_p ) = IS_NULL ;
2003-04-20 21:08:22 +08:00
}
zargs [ 0 ] = context_p ;
/* copy the other args */
for ( i = 0 ; i < argc ; i + + ) {
zargs [ i + 1 ] = emalloc ( sizeof ( zval * ) ) ;
MAKE_STD_ZVAL ( * zargs [ i + 1 ] ) ;
2003-06-20 04:57:11 +08:00
if ( argv [ i ] = = NULL ) {
ZVAL_NULL ( * zargs [ i + 1 ] ) ;
} else {
ZVAL_STRING ( * zargs [ i + 1 ] , ( char * ) argv [ i ] , 1 ) ;
}
2003-04-20 21:08:22 +08:00
}
res = call_user_function_ex ( EG ( function_table ) ,
NULL ,
funcs - > step ,
& retval ,
zargc ,
zargs ,
0 , NULL TSRMLS_CC ) ;
if ( res ! = SUCCESS ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " call_user_function_ex failed " ) ;
}
if ( retval ) {
zval_ptr_dtor ( & retval ) ;
}
if ( zargs ) {
for ( i = 1 ; i < zargc ; i + + ) {
zval_ptr_dtor ( zargs [ i ] ) ;
efree ( zargs [ i ] ) ;
}
efree ( zargs ) ;
}
}
2003-04-20 23:13:04 +08:00
/* }}} */
2003-04-20 21:08:22 +08:00
2003-04-20 23:13:04 +08:00
/* {{{ callback for sqlite_create_aggregate: finalize function */
2003-04-20 21:08:22 +08:00
static void php_sqlite_agg_fini_function_callback ( sqlite_func * func )
{
zval * retval = NULL ;
2003-04-20 23:13:04 +08:00
int res ;
2003-04-20 21:08:22 +08:00
struct php_sqlite_agg_functions * funcs = sqlite_user_data ( func ) ;
zval * * context_p ;
TSRMLS_FETCH ( ) ;
2003-04-20 23:13:04 +08:00
if ( ! funcs - > is_valid ) {
sqlite_set_result_error ( func , " this function has not been correctly defined for this request " , - 1 ) ;
return ;
}
2003-04-20 21:08:22 +08:00
context_p = ( zval * * ) sqlite_aggregate_context ( func , sizeof ( * context_p ) ) ;
res = call_user_function_ex ( EG ( function_table ) ,
NULL ,
2003-04-20 23:13:04 +08:00
funcs - > fini ,
2003-04-20 21:08:22 +08:00
& retval ,
1 ,
& context_p ,
0 , NULL TSRMLS_CC ) ;
if ( res = = SUCCESS ) {
if ( retval = = NULL ) {
sqlite_set_result_string ( func , NULL , 0 ) ;
} else {
switch ( Z_TYPE_P ( retval ) ) {
case IS_STRING :
/* TODO: for binary results, need to encode the string */
sqlite_set_result_string ( func , Z_STRVAL_P ( retval ) , Z_STRLEN_P ( retval ) ) ;
break ;
case IS_LONG :
case IS_BOOL :
sqlite_set_result_int ( func , Z_LVAL_P ( retval ) ) ;
break ;
case IS_DOUBLE :
sqlite_set_result_double ( func , Z_DVAL_P ( retval ) ) ;
break ;
case IS_NULL :
default :
sqlite_set_result_string ( func , NULL , 0 ) ;
}
}
} else {
sqlite_set_result_error ( func , " call_user_function_ex failed " , - 1 ) ;
}
if ( retval ) {
zval_ptr_dtor ( & retval ) ;
}
zval_ptr_dtor ( context_p ) ;
}
2003-04-20 23:13:04 +08:00
/* }}} */
2003-04-20 21:08:22 +08:00
2003-04-18 04:09:45 +08:00
/* {{{ Authorization Callback */
2003-06-05 06:40:00 +08:00
static int php_sqlite_authorizer ( void * autharg , int access_type , const char * arg3 , const char * arg4 ,
const char * arg5 , const char * arg6 )
2003-04-18 02:54:40 +08:00
{
switch ( access_type ) {
case SQLITE_COPY :
{
TSRMLS_FETCH ( ) ;
if ( PG ( safe_mode ) & & ( ! php_checkuid ( arg4 , NULL , CHECKUID_CHECK_FILE_AND_DIR ) ) ) {
return SQLITE_DENY ;
}
if ( php_check_open_basedir ( arg4 TSRMLS_CC ) ) {
return SQLITE_DENY ;
}
}
return SQLITE_OK ;
2003-06-07 06:44:57 +08:00
# ifdef SQLITE_ATTACH
case SQLITE_ATTACH :
{
TSRMLS_FETCH ( ) ;
if ( PG ( safe_mode ) & & ( ! php_checkuid ( arg3 , NULL , CHECKUID_CHECK_FILE_AND_DIR ) ) ) {
return SQLITE_DENY ;
}
if ( php_check_open_basedir ( arg3 TSRMLS_CC ) ) {
return SQLITE_DENY ;
}
}
return SQLITE_OK ;
# endif
2003-04-18 02:54:40 +08:00
default :
/* access allowed */
return SQLITE_OK ;
}
}
2003-04-18 04:09:45 +08:00
/* }}} */
2003-04-18 00:36:59 +08:00
2003-06-23 01:19:46 +08:00
/* {{{ OO init/structure stuff */
# define REGISTER_SQLITE_CLASS(name, parent) \
{ \
zend_class_entry ce ; \
INIT_CLASS_ENTRY ( ce , " sqlite_ " # name , sqlite_funcs_ # # name ) ; \
ce . create_object = sqlite_object_new_ # # name ; \
sqlite_ce_ # # name = zend_register_internal_class_ex ( & ce , parent , NULL TSRMLS_CC ) ; \
memcpy ( & sqlite_object_handlers_ # # name , zend_get_std_object_handlers ( ) , sizeof ( zend_object_handlers ) ) ; \
2003-07-21 02:00:54 +08:00
sqlite_object_handlers_ # # name . clone_obj = NULL ; \
2003-10-17 16:17:09 +08:00
sqlite_ce_ # # name - > ce_flags | = ZEND_ACC_FINAL_CLASS ; \
2003-06-23 01:19:46 +08:00
}
zend_class_entry * sqlite_ce_db , * sqlite_ce_exception ;
zend_class_entry * sqlite_ce_query , * sqlite_ce_ub_query ;
static zend_object_handlers sqlite_object_handlers_db ;
static zend_object_handlers sqlite_object_handlers_query ;
static zend_object_handlers sqlite_object_handlers_ub_query ;
static zend_object_handlers sqlite_object_handlers_exception ;
typedef enum {
is_db ,
is_result
} sqlite_obj_type ;
typedef struct _sqlite_object {
zend_object std ;
sqlite_obj_type type ;
union {
struct php_sqlite_db * db ;
struct php_sqlite_result * res ;
void * ptr ;
} u ;
} sqlite_object ;
static int sqlite_free_persistent ( list_entry * le , void * ptr TSRMLS_DC )
{
2003-09-22 03:36:40 +08:00
return le - > ptr = = ptr ? ZEND_HASH_APPLY_REMOVE : ZEND_HASH_APPLY_KEEP ;
2003-06-23 01:19:46 +08:00
}
2004-02-04 19:14:47 +08:00
static void sqlite_object_free_storage ( void * object TSRMLS_DC )
2003-06-23 01:19:46 +08:00
{
sqlite_object * intern = ( sqlite_object * ) object ;
zend_hash_destroy ( intern - > std . properties ) ;
FREE_HASHTABLE ( intern - > std . properties ) ;
if ( intern - > u . ptr ) {
if ( intern - > type = = is_db ) {
if ( intern - > u . db - > rsrc_id ) {
zend_list_delete ( intern - > u . db - > rsrc_id ) ;
zend_hash_apply_with_argument ( & EG ( persistent_list ) , ( apply_func_arg_t ) sqlite_free_persistent , & intern - > u . ptr TSRMLS_CC ) ;
}
} else {
real_result_dtor ( intern - > u . res TSRMLS_CC ) ;
}
}
efree ( object ) ;
}
static void sqlite_object_new ( zend_class_entry * class_type , zend_object_handlers * handlers , zend_object_value * retval TSRMLS_DC )
{
sqlite_object * intern ;
zval * tmp ;
intern = emalloc ( sizeof ( sqlite_object ) ) ;
memset ( intern , 0 , sizeof ( sqlite_object ) ) ;
intern - > std . ce = class_type ;
ALLOC_HASHTABLE ( intern - > std . properties ) ;
zend_hash_init ( intern - > std . properties , 0 , NULL , ZVAL_PTR_DTOR , 0 ) ;
zend_hash_copy ( intern - > std . properties , & class_type - > default_properties , ( copy_ctor_func_t ) zval_add_ref , ( void * ) & tmp , sizeof ( zval * ) ) ;
2004-02-04 20:45:56 +08:00
retval - > handle = zend_objects_store_put ( intern , NULL , ( zend_objects_free_object_storage_t ) sqlite_object_free_storage , NULL TSRMLS_CC ) ;
2003-06-23 01:19:46 +08:00
retval - > handlers = handlers ;
}
static zend_object_value sqlite_object_new_db ( zend_class_entry * class_type TSRMLS_DC )
{
zend_object_value retval ;
sqlite_object_new ( class_type , & sqlite_object_handlers_db , & retval TSRMLS_CC ) ;
return retval ;
}
static zend_object_value sqlite_object_new_query ( zend_class_entry * class_type TSRMLS_DC )
{
zend_object_value retval ;
sqlite_object_new ( class_type , & sqlite_object_handlers_query , & retval TSRMLS_CC ) ;
return retval ;
}
static zend_object_value sqlite_object_new_ub_query ( zend_class_entry * class_type TSRMLS_DC )
{
zend_object_value retval ;
sqlite_object_new ( class_type , & sqlite_object_handlers_ub_query , & retval TSRMLS_CC ) ;
return retval ;
}
static zend_object_value sqlite_object_new_exception ( zend_class_entry * class_type TSRMLS_DC )
{
zend_object_value retval ;
sqlite_object_new ( class_type , & sqlite_object_handlers_exception , & retval TSRMLS_CC ) ;
return retval ;
}
# define SQLITE_REGISTER_OBJECT(_type, _object, _ptr) \
{ \
sqlite_object * obj ; \
obj = ( sqlite_object * ) zend_object_store_get_object ( _object TSRMLS_CC ) ; \
obj - > type = is_ # # _type ; \
obj - > u . _type = _ptr ; \
}
static zend_class_entry * sqlite_get_ce_query ( zval * object TSRMLS_DC )
{
return sqlite_ce_query ;
}
static zend_class_entry * sqlite_get_ce_ub_query ( zval * object TSRMLS_DC )
{
return sqlite_ce_ub_query ;
}
static zval * sqlite_instanciate ( zend_class_entry * pce , zval * object TSRMLS_DC )
{
if ( ! object ) {
ALLOC_ZVAL ( object ) ;
}
Z_TYPE_P ( object ) = IS_OBJECT ;
object_init_ex ( object , pce ) ;
object - > refcount = 1 ;
object - > is_ref = 1 ;
return object ;
}
2003-10-18 01:21:56 +08:00
typedef struct _sqlite_object_iterator {
zend_object_iterator it ;
struct php_sqlite_result * res ;
zval * value ;
} sqlite_object_iterator ;
void sqlite_iterator_dtor ( zend_object_iterator * iter TSRMLS_DC )
{
zval * object = ( zval * ) ( ( sqlite_object_iterator * ) iter ) - > it . data ;
if ( ( ( sqlite_object_iterator * ) iter ) - > value ) {
zval_ptr_dtor ( & ( ( sqlite_object_iterator * ) iter ) - > value ) ;
( ( sqlite_object_iterator * ) iter ) - > value = NULL ;
}
zval_ptr_dtor ( & object ) ;
efree ( iter ) ;
}
void sqlite_iterator_rewind ( zend_object_iterator * iter TSRMLS_DC )
{
struct php_sqlite_result * res = ( ( sqlite_object_iterator * ) iter ) - > res ;
if ( ( ( sqlite_object_iterator * ) iter ) - > value ) {
zval_ptr_dtor ( & ( ( sqlite_object_iterator * ) iter ) - > value ) ;
( ( sqlite_object_iterator * ) iter ) - > value = NULL ;
}
if ( res ) {
res - > curr_row = 0 ;
}
}
int sqlite_iterator_has_more ( zend_object_iterator * iter TSRMLS_DC )
{
struct php_sqlite_result * res = ( ( sqlite_object_iterator * ) iter ) - > res ;
if ( res & & res - > curr_row < res - > nrows & & res - > nrows ) { /* curr_row may be -1 */
return SUCCESS ;
} else {
return FAILURE ;
}
}
void sqlite_iterator_get_current_data ( zend_object_iterator * iter , zval * * * data TSRMLS_DC )
{
struct php_sqlite_result * res = ( ( sqlite_object_iterator * ) iter ) - > res ;
* data = & ( ( sqlite_object_iterator * ) iter ) - > value ;
if ( res & & ! * * data ) {
MAKE_STD_ZVAL ( * * data ) ;
2004-02-16 04:42:58 +08:00
php_sqlite_fetch_array ( res , res - > mode , 1 , 0 , * * data TSRMLS_CC ) ;
2003-10-18 01:21:56 +08:00
}
}
int sqlite_iterator_get_current_key ( zend_object_iterator * iter , char * * str_key , uint * str_key_len , ulong * int_key TSRMLS_DC )
{
struct php_sqlite_result * res = ( ( sqlite_object_iterator * ) iter ) - > res ;
* str_key = NULL ;
* str_key_len = 0 ;
* int_key = res ? res - > curr_row : 0 ;
return HASH_KEY_IS_LONG ;
}
void sqlite_iterator_move_forward ( zend_object_iterator * iter TSRMLS_DC )
{
struct php_sqlite_result * res = ( ( sqlite_object_iterator * ) iter ) - > res ;
if ( ( ( sqlite_object_iterator * ) iter ) - > value ) {
zval_ptr_dtor ( & ( ( sqlite_object_iterator * ) iter ) - > value ) ;
( ( sqlite_object_iterator * ) iter ) - > value = NULL ;
}
if ( res ) {
if ( ! res - > buffered & & res - > vm ) {
php_sqlite_fetch ( res TSRMLS_CC ) ;
}
if ( res - > curr_row > = res - > nrows ) {
/* php_error_docref(NULL TSRMLS_CC, E_WARNING, "no more rows available"); */
return ;
}
res - > curr_row + + ;
}
}
2003-10-19 02:43:31 +08:00
zend_object_iterator_funcs sqlite_ub_query_iterator_funcs = {
sqlite_iterator_dtor ,
sqlite_iterator_has_more ,
sqlite_iterator_get_current_data ,
sqlite_iterator_get_current_key ,
sqlite_iterator_move_forward ,
NULL
} ;
2003-10-18 01:21:56 +08:00
2003-10-19 02:43:31 +08:00
zend_object_iterator_funcs sqlite_query_iterator_funcs = {
sqlite_iterator_dtor ,
sqlite_iterator_has_more ,
sqlite_iterator_get_current_data ,
sqlite_iterator_get_current_key ,
sqlite_iterator_move_forward ,
sqlite_iterator_rewind
} ;
2003-10-18 01:21:56 +08:00
2003-10-19 02:43:31 +08:00
zend_object_iterator * sqlite_get_iterator ( zend_class_entry * ce , zval * object TSRMLS_DC )
2003-10-18 01:21:56 +08:00
{
sqlite_object_iterator * iterator = emalloc ( sizeof ( sqlite_object_iterator ) ) ;
sqlite_object * obj = ( sqlite_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
object - > refcount + + ;
iterator - > it . data = ( void * ) object ;
2003-10-19 02:43:31 +08:00
iterator - > it . funcs = ce - > iterator_funcs . funcs ;
2003-10-18 01:21:56 +08:00
iterator - > res = obj - > u . res ;
iterator - > value = NULL ;
return ( zend_object_iterator * ) iterator ;
}
2003-06-23 01:19:46 +08:00
/* }}} */
2003-04-23 07:24:44 +08:00
static int init_sqlite_globals ( zend_sqlite_globals * g )
{
g - > assoc_case = 0 ;
return SUCCESS ;
}
2003-04-17 09:29:45 +08:00
PHP_MINIT_FUNCTION ( sqlite )
{
2003-06-23 01:19:46 +08:00
REGISTER_SQLITE_CLASS ( db , NULL ) ;
REGISTER_SQLITE_CLASS ( query , NULL ) ;
REGISTER_SQLITE_CLASS ( ub_query , NULL ) ;
REGISTER_SQLITE_CLASS ( exception , zend_exception_get_default ( ) ) ;
sqlite_object_handlers_query . get_class_entry = sqlite_get_ce_query ;
sqlite_object_handlers_ub_query . get_class_entry = sqlite_get_ce_ub_query ;
2003-10-18 01:21:56 +08:00
2003-10-19 02:43:31 +08:00
sqlite_ce_ub_query - > get_iterator = sqlite_get_iterator ;
sqlite_ce_ub_query - > iterator_funcs . funcs = & sqlite_ub_query_iterator_funcs ;
sqlite_ce_query - > get_iterator = sqlite_get_iterator ;
sqlite_ce_query - > iterator_funcs . funcs = & sqlite_query_iterator_funcs ;
2003-06-23 01:19:46 +08:00
2003-04-23 07:24:44 +08:00
ZEND_INIT_MODULE_GLOBALS ( sqlite , init_sqlite_globals , NULL ) ;
2003-06-23 01:19:46 +08:00
2003-04-22 08:08:48 +08:00
REGISTER_INI_ENTRIES ( ) ;
2003-04-23 07:24:44 +08:00
2003-07-02 01:55:32 +08:00
# if HAVE_PHP_SESSION
2003-07-01 21:07:37 +08:00
php_session_register_module ( ps_sqlite_ptr ) ;
2003-07-02 01:55:32 +08:00
# endif
2003-07-01 21:07:37 +08:00
2003-04-17 09:29:45 +08:00
le_sqlite_db = zend_register_list_destructors_ex ( php_sqlite_db_dtor , NULL , " sqlite database " , module_number ) ;
2003-07-13 17:20:40 +08:00
le_sqlite_pdb = zend_register_list_destructors_ex ( NULL , php_sqlite_db_dtor , " sqlite database (persistent) " , module_number ) ;
2003-04-17 09:29:45 +08:00
le_sqlite_result = zend_register_list_destructors_ex ( php_sqlite_result_dtor , NULL , " sqlite result " , module_number ) ;
REGISTER_LONG_CONSTANT ( " SQLITE_BOTH " , PHPSQLITE_BOTH , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SQLITE_NUM " , PHPSQLITE_NUM , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SQLITE_ASSOC " , PHPSQLITE_ASSOC , CONST_CS | CONST_PERSISTENT ) ;
2003-04-18 04:17:54 +08:00
REGISTER_LONG_CONSTANT ( " SQLITE_OK " , SQLITE_OK , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SQLITE_ERROR " , SQLITE_ERROR , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SQLITE_INTERNAL " , SQLITE_INTERNAL , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SQLITE_PERM " , SQLITE_PERM , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SQLITE_ABORT " , SQLITE_ABORT , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SQLITE_BUSY " , SQLITE_BUSY , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SQLITE_LOCKED " , SQLITE_LOCKED , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SQLITE_NOMEM " , SQLITE_NOMEM , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SQLITE_READONLY " , SQLITE_READONLY , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SQLITE_INTERRUPT " , SQLITE_INTERRUPT , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SQLITE_IOERR " , SQLITE_IOERR , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SQLITE_CORRUPT " , SQLITE_CORRUPT , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SQLITE_NOTFOUND " , SQLITE_NOTFOUND , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SQLITE_FULL " , SQLITE_FULL , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SQLITE_CANTOPEN " , SQLITE_CANTOPEN , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SQLITE_PROTOCOL " , SQLITE_PROTOCOL , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SQLITE_EMPTY " , SQLITE_EMPTY , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SQLITE_SCHEMA " , SQLITE_SCHEMA , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SQLITE_TOOBIG " , SQLITE_TOOBIG , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SQLITE_CONSTRAINT " , SQLITE_CONSTRAINT , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SQLITE_MISMATCH " , SQLITE_MISMATCH , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SQLITE_MISUSE " , SQLITE_MISUSE , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SQLITE_NOLFS " , SQLITE_NOLFS , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SQLITE_AUTH " , SQLITE_AUTH , CONST_CS | CONST_PERSISTENT ) ;
2003-06-20 04:57:11 +08:00
# ifdef SQLITE_FORMAT
REGISTER_LONG_CONSTANT ( " SQLITE_FORMAT " , SQLITE_FORMAT , CONST_CS | CONST_PERSISTENT ) ;
# endif
2003-04-18 04:17:54 +08:00
REGISTER_LONG_CONSTANT ( " SQLITE_ROW " , SQLITE_ROW , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SQLITE_DONE " , SQLITE_DONE , CONST_CS | CONST_PERSISTENT ) ;
2003-04-17 09:29:45 +08:00
return SUCCESS ;
}
2003-06-23 01:19:46 +08:00
PHP_RINIT_FUNCTION ( sqlite )
{
return SUCCESS ;
}
2003-04-17 09:29:45 +08:00
PHP_MINFO_FUNCTION ( sqlite )
{
php_info_print_table_start ( ) ;
php_info_print_table_header ( 2 , " SQLite support " , " enabled " ) ;
2003-04-18 03:13:21 +08:00
php_info_print_table_row ( 2 , " PECL Module version " , PHP_SQLITE_MODULE_VERSION " $Id$ " ) ;
2003-04-17 09:29:45 +08:00
php_info_print_table_row ( 2 , " SQLite Library " , sqlite_libversion ( ) ) ;
php_info_print_table_row ( 2 , " SQLite Encoding " , sqlite_libencoding ( ) ) ;
php_info_print_table_end ( ) ;
2003-04-22 08:08:48 +08:00
DISPLAY_INI_ENTRIES ( ) ;
2003-04-17 09:29:45 +08:00
}
2003-06-23 01:19:46 +08:00
static struct php_sqlite_db * php_sqlite_open ( char * filename , int mode , char * persistent_id , zval * return_value , zval * errmsg , zval * object TSRMLS_DC )
2003-04-17 09:29:45 +08:00
{
char * errtext = NULL ;
2003-04-18 04:08:00 +08:00
sqlite * sdb = NULL ;
2003-04-19 00:30:16 +08:00
struct php_sqlite_db * db = NULL ;
2003-04-17 09:29:45 +08:00
2003-04-18 04:08:00 +08:00
sdb = sqlite_open ( filename , mode , & errtext ) ;
2003-04-17 09:29:45 +08:00
2003-04-18 04:08:00 +08:00
if ( sdb = = NULL ) {
2003-04-19 03:43:38 +08:00
2003-04-17 09:29:45 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " %s " , errtext ) ;
if ( errmsg ) {
ZVAL_STRING ( errmsg , errtext , 1 ) ;
}
sqlite_freemem ( errtext ) ;
2003-06-23 01:19:46 +08:00
/* if object is not an object then we're called from the factory() function */
if ( object & & Z_TYPE_P ( object ) ! = IS_OBJECT ) {
RETVAL_NULL ( ) ;
} else {
RETVAL_FALSE ;
}
2003-04-19 00:30:16 +08:00
return NULL ;
2003-04-17 09:29:45 +08:00
}
2003-04-19 00:30:16 +08:00
db = ( struct php_sqlite_db * ) pemalloc ( sizeof ( struct php_sqlite_db ) , persistent_id ? 1 : 0 ) ;
db - > is_persistent = persistent_id ? 1 : 0 ;
2003-04-18 04:17:54 +08:00
db - > last_err_code = SQLITE_OK ;
2003-04-18 04:08:00 +08:00
db - > db = sdb ;
2003-04-20 23:13:04 +08:00
zend_hash_init ( & db - > callbacks , 0 , NULL , php_sqlite_callback_dtor , db - > is_persistent ) ;
2003-04-18 04:08:00 +08:00
2003-04-17 11:14:14 +08:00
/* register the PHP functions */
2003-04-20 21:31:36 +08:00
sqlite_create_function ( sdb , " php " , - 1 , php_sqlite_generic_function_callback , 0 ) ;
2003-04-18 00:57:46 +08:00
2003-06-20 04:57:11 +08:00
/* set default busy handler; keep retrying up until 1 minute has passed,
2003-04-18 00:57:46 +08:00
* then fail with a busy status code */
2003-06-20 04:57:11 +08:00
sqlite_busy_timeout ( sdb , 60000 ) ;
2003-04-18 02:54:40 +08:00
2003-06-07 19:38:03 +08:00
/* authorizer hook so we can enforce safe mode
* Note : the declaration of php_sqlite_authorizer is correct for 2.8 .2 of libsqlite ,
* and IS backwards binary compatible with earlier versions */
2003-04-18 04:08:00 +08:00
sqlite_set_authorizer ( sdb , php_sqlite_authorizer , NULL ) ;
2003-04-17 11:14:14 +08:00
2003-06-23 01:19:46 +08:00
db - > rsrc_id = ZEND_REGISTER_RESOURCE ( object ? NULL : return_value , db , persistent_id ? le_sqlite_pdb : le_sqlite_db ) ;
if ( object ) {
/* if object is not an object then we're called from the factory() function */
if ( Z_TYPE_P ( object ) ! = IS_OBJECT ) {
sqlite_instanciate ( sqlite_ce_db , object TSRMLS_CC ) ;
}
/* and now register the object */
SQLITE_REGISTER_OBJECT ( db , object , db )
}
2003-04-19 00:30:16 +08:00
if ( persistent_id ) {
list_entry le ;
Z_TYPE ( le ) = le_sqlite_pdb ;
le . ptr = db ;
if ( FAILURE = = zend_hash_update ( & EG ( persistent_list ) , persistent_id ,
strlen ( persistent_id ) + 1 ,
( void * ) & le , sizeof ( le ) , NULL ) ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Failed to register persistent resource " ) ;
}
}
return db ;
}
2003-07-06 04:02:40 +08:00
/* {{{ proto resource sqlite_popen(string filename [, int mode [, string &error_message]])
Opens a persistent handle to a SQLite database . Will create the database if it does not exist . */
2003-04-19 00:30:16 +08:00
PHP_FUNCTION ( sqlite_popen )
{
2004-02-24 23:47:38 +08:00
long mode = 0666 ;
2003-04-19 00:30:16 +08:00
char * filename , * fullpath , * hashkey ;
long filename_len , hashkeylen ;
zval * errmsg = NULL ;
struct php_sqlite_db * db = NULL ;
list_entry * le ;
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " s|lz/ " ,
& filename , & filename_len , & mode , & errmsg ) ) {
return ;
}
2003-06-27 03:07:17 +08:00
if ( errmsg ) {
zval_dtor ( errmsg ) ;
}
2003-04-19 00:30:16 +08:00
2003-06-10 04:36:55 +08:00
if ( strncmp ( filename , " :memory: " , sizeof ( " :memory: " ) - 1 ) ) {
/* resolve the fully-qualified path name to use as the hash key */
fullpath = expand_filepath ( filename , NULL TSRMLS_CC ) ;
2003-04-19 00:30:16 +08:00
2003-06-10 04:36:55 +08:00
if ( PG ( safe_mode ) & & ( ! php_checkuid ( fullpath , NULL , CHECKUID_CHECK_FILE_AND_DIR ) ) ) {
RETURN_FALSE ;
}
2003-04-19 00:30:16 +08:00
2003-06-10 04:36:55 +08:00
if ( php_check_open_basedir ( fullpath TSRMLS_CC ) ) {
RETURN_FALSE ;
}
} else {
fullpath = estrndup ( filename , filename_len ) ;
2003-04-19 00:30:16 +08:00
}
2004-02-24 23:47:38 +08:00
hashkeylen = spprintf ( & hashkey , 0 , " sqlite_pdb_%s:%ld " , fullpath , mode ) ;
2003-04-17 09:29:45 +08:00
2003-04-19 00:30:16 +08:00
/* do we have an existing persistent connection ? */
if ( SUCCESS = = zend_hash_find ( & EG ( persistent_list ) , hashkey , hashkeylen + 1 , ( void * ) & le ) ) {
if ( Z_TYPE_P ( le ) = = le_sqlite_pdb ) {
db = ( struct php_sqlite_db * ) le - > ptr ;
if ( db - > rsrc_id = = FAILURE ) {
/* give it a valid resource id for this request */
db - > rsrc_id = ZEND_REGISTER_RESOURCE ( return_value , db , le_sqlite_pdb ) ;
} else {
2003-07-13 17:20:40 +08:00
int type ;
/* sanity check to ensure that the resource is still a valid regular resource
* number */
2003-07-19 19:00:17 +08:00
if ( zend_list_find ( db - > rsrc_id , & type ) = = db ) {
2003-07-13 17:20:40 +08:00
/* already accessed this request; map it */
zend_list_addref ( db - > rsrc_id ) ;
ZVAL_RESOURCE ( return_value , db - > rsrc_id ) ;
} else {
db - > rsrc_id = ZEND_REGISTER_RESOURCE ( return_value , db , le_sqlite_pdb ) ;
}
2003-04-19 00:30:16 +08:00
}
/* all set */
efree ( fullpath ) ;
efree ( hashkey ) ;
return ;
}
2003-06-15 02:16:47 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Some other type of persistent resource is using this hash key!? " ) ;
2003-04-19 00:30:16 +08:00
RETURN_FALSE ;
}
/* now we need to open the database */
2003-06-23 01:19:46 +08:00
php_sqlite_open ( fullpath , mode , hashkey , return_value , errmsg , NULL TSRMLS_CC ) ;
2003-04-19 00:30:16 +08:00
efree ( fullpath ) ;
efree ( hashkey ) ;
}
/* }}} */
2003-07-06 04:02:40 +08:00
/* {{{ proto resource sqlite_open(string filename [, int mode [, string &error_message]])
Opens a SQLite database . Will create the database if it does not exist . */
2003-04-19 00:30:16 +08:00
PHP_FUNCTION ( sqlite_open )
{
2004-02-24 23:47:38 +08:00
long mode = 0666 ;
2003-08-13 05:15:16 +08:00
char * filename , * fullpath = NULL ;
2003-04-19 00:30:16 +08:00
long filename_len ;
zval * errmsg = NULL ;
2003-06-23 01:19:46 +08:00
zval * object = getThis ( ) ;
2003-04-19 00:30:16 +08:00
2003-08-26 04:55:14 +08:00
php_set_error_handling ( object ? EH_THROW : EH_NORMAL , sqlite_ce_exception TSRMLS_CC ) ;
2003-04-19 00:30:16 +08:00
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " s|lz/ " ,
& filename , & filename_len , & mode , & errmsg ) ) {
2003-09-13 18:31:06 +08:00
php_std_error_handling ( ) ;
2003-04-19 00:30:16 +08:00
return ;
}
2003-06-27 03:07:17 +08:00
if ( errmsg ) {
zval_dtor ( errmsg ) ;
}
2003-04-19 00:30:16 +08:00
2003-06-10 04:36:55 +08:00
if ( strncmp ( filename , " :memory: " , sizeof ( " :memory: " ) - 1 ) ) {
2003-08-13 05:15:16 +08:00
/* resolve the fully-qualified path name to use as the hash key */
fullpath = expand_filepath ( filename , NULL TSRMLS_CC ) ;
if ( PG ( safe_mode ) & & ( ! php_checkuid ( fullpath , NULL , CHECKUID_CHECK_FILE_AND_DIR ) ) ) {
2003-09-13 18:31:06 +08:00
php_std_error_handling ( ) ;
2003-08-13 05:15:16 +08:00
efree ( fullpath ) ;
2003-06-23 01:19:46 +08:00
if ( object ) {
RETURN_NULL ( ) ;
} else {
RETURN_FALSE ;
}
2003-06-10 04:36:55 +08:00
}
2003-08-13 05:15:16 +08:00
if ( php_check_open_basedir ( fullpath TSRMLS_CC ) ) {
2003-09-13 18:31:06 +08:00
php_std_error_handling ( ) ;
2003-08-13 05:15:16 +08:00
efree ( fullpath ) ;
2003-06-23 01:19:46 +08:00
if ( object ) {
RETURN_NULL ( ) ;
} else {
RETURN_FALSE ;
}
2003-06-10 04:36:55 +08:00
}
2003-04-19 00:30:16 +08:00
}
2003-06-23 01:19:46 +08:00
2003-08-13 05:29:28 +08:00
php_sqlite_open ( fullpath ? fullpath : filename , mode , NULL , return_value , errmsg , object TSRMLS_CC ) ;
2003-06-23 01:19:46 +08:00
2003-08-13 05:15:16 +08:00
if ( fullpath ) {
efree ( fullpath ) ;
}
2003-09-13 18:31:06 +08:00
php_std_error_handling ( ) ;
2003-06-23 01:19:46 +08:00
}
/* }}} */
2003-07-06 04:02:40 +08:00
/* {{{ proto object sqlite_factory(string filename [, int mode [, string &error_message]])
Opens a SQLite database and creates an object for it . Will create the database if it does not exist . */
2003-06-23 01:19:46 +08:00
PHP_FUNCTION ( sqlite_factory )
{
2004-02-24 23:47:38 +08:00
long mode = 0666 ;
2003-06-23 01:19:46 +08:00
char * filename ;
long filename_len ;
zval * errmsg = NULL ;
php_set_error_handling ( EH_THROW , sqlite_ce_exception TSRMLS_CC ) ;
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " s|lz/ " ,
& filename , & filename_len , & mode , & errmsg ) ) {
2003-08-29 07:19:51 +08:00
php_std_error_handling ( ) ;
2003-06-23 01:19:46 +08:00
RETURN_NULL ( ) ;
}
2003-06-27 03:07:17 +08:00
if ( errmsg ) {
zval_dtor ( errmsg ) ;
}
2003-06-23 01:19:46 +08:00
2003-09-22 03:36:40 +08:00
if ( strncmp ( filename , " :memory: " , sizeof ( " :memory: " ) - 1 ) ) {
if ( PG ( safe_mode ) & & ( ! php_checkuid ( filename , NULL , CHECKUID_CHECK_FILE_AND_DIR ) ) ) {
php_std_error_handling ( ) ;
RETURN_NULL ( ) ;
}
if ( php_check_open_basedir ( filename TSRMLS_CC ) ) {
php_std_error_handling ( ) ;
RETURN_NULL ( ) ;
}
2003-06-23 01:19:46 +08:00
}
php_sqlite_open ( filename , mode , NULL , return_value , errmsg , return_value TSRMLS_CC ) ;
2003-08-29 07:19:51 +08:00
php_std_error_handling ( ) ;
2003-04-17 09:29:45 +08:00
}
/* }}} */
2003-04-18 00:57:46 +08:00
/* {{{ proto void sqlite_busy_timeout(resource db, int ms)
2003-07-06 04:02:40 +08:00
Set busy timeout duration . If ms < = 0 , all busy handlers are disabled . */
2003-04-18 00:57:46 +08:00
PHP_FUNCTION ( sqlite_busy_timeout )
{
zval * zdb ;
2003-04-18 04:08:00 +08:00
struct php_sqlite_db * db ;
2003-04-18 00:57:46 +08:00
long ms ;
2003-06-23 01:19:46 +08:00
zval * object = getThis ( ) ;
2003-04-18 00:57:46 +08:00
2003-06-23 01:19:46 +08:00
if ( object ) {
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " l " , & ms ) ) {
return ;
}
DB_FROM_OBJECT ( db , object ) ;
} else {
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " rl " , & zdb , & ms ) ) {
return ;
}
DB_FROM_ZVAL ( db , & zdb ) ;
2003-04-18 00:57:46 +08:00
}
2003-04-18 04:08:00 +08:00
sqlite_busy_timeout ( db - > db , ms ) ;
2003-04-18 00:57:46 +08:00
}
/* }}} */
2003-04-17 09:29:45 +08:00
/* {{{ proto void sqlite_close(resource db)
2003-07-06 04:02:40 +08:00
Closes an open sqlite database . */
2003-04-17 09:29:45 +08:00
PHP_FUNCTION ( sqlite_close )
{
zval * zdb ;
2003-04-18 04:08:00 +08:00
struct php_sqlite_db * db ;
2003-06-23 01:19:46 +08:00
zval * object = getThis ( ) ;
2003-04-17 09:29:45 +08:00
2003-06-23 01:19:46 +08:00
if ( object ) {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Ignored, you must destruct the object instead " ) ;
} else {
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " r " , & zdb ) ) {
return ;
}
DB_FROM_ZVAL ( db , & zdb ) ;
2003-06-05 05:11:45 +08:00
}
2003-04-17 09:29:45 +08:00
zend_list_delete ( Z_RESVAL_P ( zdb ) ) ;
}
/* }}} */
2003-04-27 21:32:43 +08:00
/* {{{ php_sqlite_fetch */
2003-10-18 01:21:56 +08:00
static int php_sqlite_fetch ( struct php_sqlite_result * rres TSRMLS_DC )
2003-04-27 21:25:10 +08:00
{
const char * * rowdata , * * colnames ;
int ret , i , base ;
2003-05-01 21:20:22 +08:00
char * errtext = NULL , * colname ;
2003-04-27 21:25:10 +08:00
next_row :
ret = sqlite_step ( rres - > vm , & rres - > ncolumns , & rowdata , & colnames ) ;
if ( ! rres - > nrows ) {
/* first row - lets copy the column names */
rres - > col_names = safe_emalloc ( rres - > ncolumns , sizeof ( char * ) , 0 ) ;
for ( i = 0 ; i < rres - > ncolumns ; i + + ) {
2003-12-15 02:45:37 +08:00
colname = ( char * ) colnames [ i ] ;
2003-05-01 21:20:22 +08:00
if ( SQLITE_G ( assoc_case ) = = 1 ) {
php_sqlite_strtoupper ( colname ) ;
} else if ( SQLITE_G ( assoc_case ) = = 2 ) {
php_sqlite_strtolower ( colname ) ;
}
rres - > col_names [ i ] = estrdup ( colname ) ;
2003-04-27 21:25:10 +08:00
}
if ( ! rres - > buffered ) {
/* non buffered mode - also fetch memory for on single row */
rres - > table = safe_emalloc ( rres - > ncolumns , sizeof ( char * ) , 0 ) ;
}
}
switch ( ret ) {
case SQLITE_ROW :
if ( rres - > buffered ) {
/* add the row to our collection */
if ( rres - > nrows + 1 > = rres - > alloc_rows ) {
rres - > alloc_rows = rres - > alloc_rows ? rres - > alloc_rows * 2 : 16 ;
rres - > table = erealloc ( rres - > table , rres - > alloc_rows * rres - > ncolumns * sizeof ( char * ) ) ;
}
base = rres - > nrows * rres - > ncolumns ;
for ( i = 0 ; i < rres - > ncolumns ; i + + ) {
if ( rowdata [ i ] ) {
rres - > table [ base + i ] = estrdup ( rowdata [ i ] ) ;
} else {
rres - > table [ base + i ] = NULL ;
}
}
rres - > nrows + + ;
goto next_row ;
} else {
/* non buffered: only fetch one row but first free data if not first row */
if ( rres - > nrows + + ) {
for ( i = 0 ; i < rres - > ncolumns ; i + + ) {
if ( rres - > table [ i ] ) {
efree ( rres - > table [ i ] ) ;
}
}
}
for ( i = 0 ; i < rres - > ncolumns ; i + + ) {
if ( rowdata [ i ] ) {
rres - > table [ i ] = estrdup ( rowdata [ i ] ) ;
} else {
rres - > table [ i ] = NULL ;
}
}
}
ret = SQLITE_OK ;
break ;
2003-04-27 22:01:09 +08:00
case SQLITE_BUSY :
case SQLITE_ERROR :
case SQLITE_MISUSE :
2003-04-27 21:25:10 +08:00
case SQLITE_DONE :
2003-04-27 22:01:09 +08:00
default :
2003-04-27 21:25:10 +08:00
if ( rres - > vm ) {
ret = sqlite_finalize ( rres - > vm , & errtext ) ;
}
rres - > vm = NULL ;
if ( ret ! = SQLITE_OK ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " %s " , errtext ) ;
sqlite_freemem ( errtext ) ;
}
break ;
}
2003-05-03 06:09:54 +08:00
rres - > db - > last_err_code = ret ;
2003-04-27 21:25:10 +08:00
return ret ;
}
/* }}} */
2003-05-03 06:09:54 +08:00
/* {{{ sqlite_query */
2004-02-24 23:47:38 +08:00
void sqlite_query ( zval * object , struct php_sqlite_db * db , char * sql , long sql_len , long mode , int buffered , zval * return_value , struct php_sqlite_result * * prres TSRMLS_DC )
2003-04-18 20:22:43 +08:00
{
2003-12-29 00:26:04 +08:00
struct php_sqlite_result res , * rres ;
2003-04-20 23:13:04 +08:00
int ret ;
2003-04-18 20:22:43 +08:00
char * errtext = NULL ;
const char * tail ;
memset ( & res , 0 , sizeof ( res ) ) ;
2003-05-03 06:09:54 +08:00
res . buffered = buffered ;
2003-04-30 23:18:59 +08:00
res . mode = mode ;
2003-04-18 20:22:43 +08:00
ret = sqlite_compile ( db - > db , sql , & tail , & res . vm , & errtext ) ;
db - > last_err_code = ret ;
if ( ret ! = SQLITE_OK ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " %s " , errtext ) ;
sqlite_freemem ( errtext ) ;
2004-01-15 05:17:09 +08:00
goto terminate ;
} else if ( ! res . vm ) { /* empty query */
terminate :
2003-06-24 03:37:48 +08:00
if ( return_value ) {
RETURN_FALSE ;
} else {
return ;
}
2003-04-18 20:22:43 +08:00
}
2003-12-29 00:26:04 +08:00
if ( ! prres ) {
rres = NULL ;
prres = & rres ;
2003-06-10 07:14:25 +08:00
}
2003-12-29 00:26:04 +08:00
if ( ! * prres ) {
* prres = ( struct php_sqlite_result * ) emalloc ( sizeof ( * * prres ) ) ;
}
memcpy ( * prres , & res , sizeof ( * * prres ) ) ;
( * prres ) - > db = db ;
2003-05-03 06:09:54 +08:00
zend_list_addref ( db - > rsrc_id ) ;
2003-04-18 20:22:43 +08:00
2003-04-27 21:25:10 +08:00
/* now the result set is ready for stepping: get first row */
2003-12-29 00:26:04 +08:00
if ( php_sqlite_fetch ( ( * prres ) TSRMLS_CC ) ! = SQLITE_OK ) {
real_result_dtor ( ( * prres ) TSRMLS_CC ) ;
* prres = NULL ;
2003-06-24 03:37:48 +08:00
if ( return_value ) {
RETURN_FALSE ;
} else {
return ;
}
2003-04-27 21:25:10 +08:00
}
2003-12-29 00:26:04 +08:00
( * prres ) - > curr_row = 0 ;
2003-04-18 20:22:43 +08:00
2003-06-23 01:19:46 +08:00
if ( object ) {
sqlite_object * obj ;
if ( buffered ) {
sqlite_instanciate ( sqlite_ce_query , return_value TSRMLS_CC ) ;
} else {
sqlite_instanciate ( sqlite_ce_ub_query , return_value TSRMLS_CC ) ;
}
obj = ( sqlite_object * ) zend_object_store_get_object ( return_value TSRMLS_CC ) ;
obj - > type = is_result ;
2003-12-29 00:26:04 +08:00
obj - > u . res = ( * prres ) ;
2003-06-23 01:19:46 +08:00
} else if ( return_value ) {
2003-12-29 00:26:04 +08:00
ZEND_REGISTER_RESOURCE ( object ? NULL : return_value , ( * prres ) , le_sqlite_result ) ;
2003-06-10 07:14:25 +08:00
}
2003-04-18 20:22:43 +08:00
}
/* }}} */
2003-05-03 06:09:54 +08:00
/* {{{ proto resource sqlite_unbuffered_query(string query, resource db [ , int result_type ])
2003-07-06 04:02:40 +08:00
Executes a query that does not prefetch and buffer all data . */
2003-05-03 06:09:54 +08:00
PHP_FUNCTION ( sqlite_unbuffered_query )
2003-04-17 09:29:45 +08:00
{
zval * zdb ;
2003-04-18 04:08:00 +08:00
struct php_sqlite_db * db ;
2003-04-17 09:29:45 +08:00
char * sql ;
long sql_len ;
2004-02-24 23:47:38 +08:00
long mode = PHPSQLITE_BOTH ;
2003-05-03 06:09:54 +08:00
char * errtext = NULL ;
2003-06-23 01:19:46 +08:00
zval * object = getThis ( ) ;
2003-04-17 09:29:45 +08:00
2003-06-23 01:19:46 +08:00
if ( object ) {
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " s|l " , & sql , & sql_len , & mode ) ) {
return ;
}
DB_FROM_OBJECT ( db , object ) ;
} else {
if ( FAILURE = = zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET ,
2003-04-30 23:18:59 +08:00
ZEND_NUM_ARGS ( ) TSRMLS_CC , " sr|l " , & sql , & sql_len , & zdb , & mode ) & &
FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " rs|l " , & zdb , & sql , & sql_len , & mode ) ) {
2003-06-23 01:19:46 +08:00
return ;
}
DB_FROM_ZVAL ( db , & zdb ) ;
2003-04-17 09:29:45 +08:00
}
2003-04-19 00:30:16 +08:00
/* avoid doing work if we can */
if ( ! return_value_used ) {
db - > last_err_code = sqlite_exec ( db - > db , sql , NULL , NULL , & errtext ) ;
if ( db - > last_err_code ! = SQLITE_OK ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " %s " , errtext ) ;
sqlite_freemem ( errtext ) ;
}
return ;
}
2003-06-23 01:19:46 +08:00
sqlite_query ( object , db , sql , sql_len , mode , 0 , return_value , NULL TSRMLS_CC ) ;
2003-05-03 06:09:54 +08:00
}
/* }}} */
2003-04-17 09:29:45 +08:00
2003-12-19 05:28:00 +08:00
/* {{{ proto resource sqlite_fetch_column_types(string table_name, resource db)
Return an array of column types from a particular table . */
PHP_FUNCTION ( sqlite_fetch_column_types )
{
zval * zdb ;
struct php_sqlite_db * db ;
char * tbl , * sql ;
long tbl_len ;
char * errtext = NULL ;
zval * object = getThis ( ) ;
struct php_sqlite_result res ;
const char * * rowdata , * * colnames , * tail ;
int i , ncols ;
if ( object ) {
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " s " , & tbl , & tbl_len ) ) {
return ;
}
DB_FROM_OBJECT ( db , object ) ;
} else {
if ( FAILURE = = zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET ,
ZEND_NUM_ARGS ( ) TSRMLS_CC , " sr " , & tbl , & tbl_len , & zdb ) & &
FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " rs " , & zdb , & tbl , & tbl_len ) ) {
return ;
}
DB_FROM_ZVAL ( db , & zdb ) ;
}
if ( ! ( sql = sqlite_mprintf ( " SELECT * FROM %q LIMIT 1 " , tbl ) ) ) {
RETURN_FALSE ;
}
sqlite_exec ( db - > db , " PRAGMA show_datatypes = ON " , NULL , NULL , & errtext ) ;
db - > last_err_code = sqlite_compile ( db - > db , sql , & tail , & res . vm , & errtext ) ;
sqlite_freemem ( sql ) ;
if ( db - > last_err_code ! = SQLITE_OK ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " %s " , errtext ) ;
sqlite_freemem ( errtext ) ;
RETVAL_FALSE ;
goto done ;
}
sqlite_step ( res . vm , & ncols , & rowdata , & colnames ) ;
array_init ( return_value ) ;
for ( i = 0 ; i < ncols ; i + + ) {
char * colname = ( char * ) colnames [ i ] ;
if ( SQLITE_G ( assoc_case ) = = 1 ) {
php_sqlite_strtoupper ( colname ) ;
} else if ( SQLITE_G ( assoc_case ) = = 2 ) {
php_sqlite_strtolower ( colname ) ;
}
add_assoc_string ( return_value , colname , colnames [ ncols + i ] ? ( char * ) colnames [ ncols + i ] : " " , 1 ) ;
}
done :
sqlite_exec ( db - > db , " PRAGMA show_datatypes = OFF " , NULL , NULL , & errtext ) ;
}
/* }}} */
2003-07-06 04:02:40 +08:00
/* {{{ proto resource sqlite_query(string query, resource db [, int result_type ])
Executes a query against a given database and returns a result handle . */
2003-05-03 06:09:54 +08:00
PHP_FUNCTION ( sqlite_query )
{
zval * zdb ;
struct php_sqlite_db * db ;
char * sql ;
long sql_len ;
2004-02-24 23:47:38 +08:00
long mode = PHPSQLITE_BOTH ;
2003-05-03 06:09:54 +08:00
char * errtext = NULL ;
2003-06-23 01:19:46 +08:00
zval * object = getThis ( ) ;
2003-04-17 09:29:45 +08:00
2003-06-23 01:19:46 +08:00
if ( object ) {
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " s|l " , & sql , & sql_len , & mode ) ) {
return ;
}
DB_FROM_OBJECT ( db , object ) ;
} else {
if ( FAILURE = = zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET ,
ZEND_NUM_ARGS ( ) TSRMLS_CC , " sr|l " , & sql , & sql_len , & zdb , & mode ) & &
FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " rs|l " , & zdb , & sql , & sql_len , & mode ) ) {
return ;
}
DB_FROM_ZVAL ( db , & zdb ) ;
2003-04-17 09:29:45 +08:00
}
2003-05-03 06:09:54 +08:00
/* avoid doing work if we can */
if ( ! return_value_used ) {
db - > last_err_code = sqlite_exec ( db - > db , sql , NULL , NULL , & errtext ) ;
2003-04-18 20:22:43 +08:00
2003-05-03 06:09:54 +08:00
if ( db - > last_err_code ! = SQLITE_OK ) {
2003-06-07 19:38:03 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " %s " , errtext ) ;
sqlite_freemem ( errtext ) ;
}
2003-05-03 06:09:54 +08:00
return ;
2003-04-18 20:22:43 +08:00
}
2003-06-23 01:19:46 +08:00
sqlite_query ( object , db , sql , sql_len , mode , 1 , return_value , NULL TSRMLS_CC ) ;
2003-04-17 09:29:45 +08:00
}
/* }}} */
2003-05-03 06:09:54 +08:00
/* {{{ php_sqlite_fetch_array */
static void php_sqlite_fetch_array ( struct php_sqlite_result * res , int mode , zend_bool decode_binary , int move_next , zval * return_value TSRMLS_DC )
2003-04-17 09:29:45 +08:00
{
2003-06-23 01:19:46 +08:00
int j , n = res - > ncolumns , buffered = res - > buffered ;
2003-04-18 20:22:43 +08:00
const char * * rowdata , * * colnames ;
2003-06-23 01:19:46 +08:00
2003-04-27 21:25:10 +08:00
/* check range of the row */
if ( res - > curr_row > = res - > nrows ) {
/* no more */
RETURN_FALSE ;
}
colnames = ( const char * * ) res - > col_names ;
2003-04-18 20:22:43 +08:00
if ( res - > buffered ) {
rowdata = ( const char * * ) & res - > table [ res - > curr_row * res - > ncolumns ] ;
} else {
2003-04-27 21:25:10 +08:00
rowdata = ( const char * * ) res - > table ;
2003-04-17 09:29:45 +08:00
}
2003-04-18 20:22:43 +08:00
/* now populate the result */
2003-04-17 09:29:45 +08:00
array_init ( return_value ) ;
2003-06-23 01:19:46 +08:00
for ( j = 0 ; j < n ; j + + ) {
2003-06-07 03:00:16 +08:00
zval * decoded ;
MAKE_STD_ZVAL ( decoded ) ;
2003-04-19 20:54:17 +08:00
2003-06-10 07:14:25 +08:00
if ( rowdata [ j ] = = NULL ) {
ZVAL_NULL ( decoded ) ;
} else if ( decode_binary & & rowdata [ j ] [ 0 ] = = ' \x01 ' ) {
2003-06-15 02:16:47 +08:00
Z_STRVAL_P ( decoded ) = emalloc ( strlen ( rowdata [ j ] ) ) ;
2003-08-17 23:43:41 +08:00
Z_STRLEN_P ( decoded ) = php_sqlite_decode_binary ( rowdata [ j ] + 1 , Z_STRVAL_P ( decoded ) ) ;
2003-06-15 02:16:47 +08:00
Z_STRVAL_P ( decoded ) [ Z_STRLEN_P ( decoded ) ] = ' \0 ' ;
2003-06-07 03:00:16 +08:00
Z_TYPE_P ( decoded ) = IS_STRING ;
2003-06-10 07:14:25 +08:00
if ( ! buffered ) {
efree ( ( char * ) rowdata [ j ] ) ;
rowdata [ j ] = NULL ;
}
2003-04-19 20:54:17 +08:00
} else {
2003-06-10 07:14:25 +08:00
ZVAL_STRING ( decoded , ( char * ) rowdata [ j ] , buffered ) ;
if ( ! buffered ) {
rowdata [ j ] = NULL ;
2003-04-19 20:54:17 +08:00
}
}
2003-06-07 03:00:16 +08:00
2003-04-17 09:29:45 +08:00
if ( mode & PHPSQLITE_NUM ) {
2003-06-07 03:00:16 +08:00
if ( mode & PHPSQLITE_ASSOC ) {
2003-06-15 02:16:47 +08:00
add_index_zval ( return_value , j , decoded ) ;
2003-06-07 03:00:16 +08:00
ZVAL_ADDREF ( decoded ) ;
add_assoc_zval ( return_value , ( char * ) colnames [ j ] , decoded ) ;
2003-06-15 02:16:47 +08:00
} else {
add_next_index_zval ( return_value , decoded ) ;
2003-04-18 01:09:59 +08:00
}
2003-06-07 03:00:16 +08:00
} else {
add_assoc_zval ( return_value , ( char * ) colnames [ j ] , decoded ) ;
2003-04-19 20:54:17 +08:00
}
2003-04-17 09:29:45 +08:00
}
2003-05-03 06:09:54 +08:00
if ( move_next ) {
2003-05-03 20:51:13 +08:00
if ( ! res - > buffered ) {
/* non buffered: fetch next row */
php_sqlite_fetch ( res TSRMLS_CC ) ;
}
/* advance the row pointer */
res - > curr_row + + ;
2003-04-27 21:25:10 +08:00
}
2003-04-17 09:29:45 +08:00
}
2003-05-03 20:51:13 +08:00
/* }}} */
/* {{{ php_sqlite_fetch_column */
static void php_sqlite_fetch_column ( struct php_sqlite_result * res , zval * which , zend_bool decode_binary , zval * return_value TSRMLS_DC )
{
int j ;
const char * * rowdata , * * colnames ;
/* check range of the row */
if ( res - > curr_row > = res - > nrows ) {
/* no more */
RETURN_FALSE ;
}
colnames = ( const char * * ) res - > col_names ;
if ( Z_TYPE_P ( which ) = = IS_LONG ) {
j = Z_LVAL_P ( which ) ;
} else {
convert_to_string_ex ( & which ) ;
for ( j = 0 ; j < res - > ncolumns ; j + + ) {
if ( ! strcasecmp ( ( char * ) colnames [ j ] , Z_STRVAL_P ( which ) ) ) {
break ;
}
}
}
if ( j < 0 | | j > = res - > ncolumns ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " No such column %d " , j ) ;
RETURN_FALSE ;
}
2003-06-10 07:14:25 +08:00
if ( res - > buffered ) {
rowdata = ( const char * * ) & res - > table [ res - > curr_row * res - > ncolumns ] ;
2003-05-03 20:51:13 +08:00
} else {
2003-06-10 07:14:25 +08:00
rowdata = ( const char * * ) res - > table ;
2003-05-03 20:51:13 +08:00
}
2003-06-10 07:14:25 +08:00
if ( rowdata [ j ] = = NULL ) {
2003-05-03 20:51:13 +08:00
RETURN_NULL ( ) ;
2003-06-23 01:19:46 +08:00
} else if ( decode_binary & & rowdata [ j ] ! = NULL & & rowdata [ j ] [ 0 ] = = ' \x01 ' ) {
2003-06-10 07:14:25 +08:00
int l = strlen ( rowdata [ j ] ) ;
char * decoded = emalloc ( l ) ;
2003-08-17 23:43:41 +08:00
l = php_sqlite_decode_binary ( rowdata [ j ] + 1 , decoded ) ;
2003-06-10 07:14:25 +08:00
decoded [ l ] = ' \0 ' ;
RETVAL_STRINGL ( decoded , l , 0 ) ;
if ( ! res - > buffered ) {
efree ( ( char * ) rowdata [ j ] ) ;
rowdata [ j ] = NULL ;
2003-06-23 01:19:46 +08:00
}
2003-05-03 20:51:13 +08:00
} else {
2003-06-10 07:14:25 +08:00
RETVAL_STRING ( ( char * ) rowdata [ j ] , res - > buffered ) ;
if ( ! res - > buffered ) {
rowdata [ j ] = NULL ;
2003-06-23 01:19:46 +08:00
}
2003-05-03 20:51:13 +08:00
}
2003-05-03 06:09:54 +08:00
}
/* }}} */
2003-07-06 04:02:40 +08:00
/* {{{ proto array sqlite_fetch_all(resource result [, int result_type [, bool decode_binary]])
Fetches all rows from a result set as an array of arrays . */
2003-06-07 03:00:16 +08:00
PHP_FUNCTION ( sqlite_fetch_all )
{
zval * zres , * ent ;
2004-02-24 23:47:38 +08:00
long mode = PHPSQLITE_BOTH ;
2003-06-07 03:00:16 +08:00
zend_bool decode_binary = 1 ;
struct php_sqlite_result * res ;
2003-06-23 01:19:46 +08:00
zval * object = getThis ( ) ;
2003-06-07 03:00:16 +08:00
2003-06-23 01:19:46 +08:00
if ( object ) {
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " |lb " , & mode , & decode_binary ) ) {
return ;
}
RES_FROM_OBJECT ( res , object ) ;
if ( ! ZEND_NUM_ARGS ( ) ) {
mode = res - > mode ;
}
} else {
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " r|lb " , & zres , & mode , & decode_binary ) ) {
return ;
}
ZEND_FETCH_RESOURCE ( res , struct php_sqlite_result * , & zres , - 1 , " sqlite result " , le_sqlite_result ) ;
if ( ZEND_NUM_ARGS ( ) < 2 ) {
mode = res - > mode ;
}
2003-06-07 03:00:16 +08:00
}
if ( res - > curr_row > = res - > nrows & & res - > nrows ) {
if ( ! res - > buffered ) {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " One or more rowsets were already returned " ) ;
} else {
res - > curr_row = 0 ;
}
}
array_init ( return_value ) ;
while ( res - > curr_row < res - > nrows ) {
MAKE_STD_ZVAL ( ent ) ;
php_sqlite_fetch_array ( res , mode , decode_binary , 1 , ent TSRMLS_CC ) ;
add_next_index_zval ( return_value , ent ) ;
}
}
/* }}} */
2003-07-06 04:02:40 +08:00
/* {{{ proto array sqlite_fetch_array(resource result [, int result_type [, bool decode_binary]])
Fetches the next row from a result set as an array . */
2003-05-03 06:09:54 +08:00
PHP_FUNCTION ( sqlite_fetch_array )
{
zval * zres ;
2004-02-24 00:26:34 +08:00
long mode = PHPSQLITE_BOTH ;
2003-05-03 06:09:54 +08:00
zend_bool decode_binary = 1 ;
struct php_sqlite_result * res ;
2003-06-23 01:19:46 +08:00
zval * object = getThis ( ) ;
2003-05-03 06:09:54 +08:00
2003-06-23 01:19:46 +08:00
if ( object ) {
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " |lb " , & mode , & decode_binary ) ) {
return ;
}
RES_FROM_OBJECT ( res , object ) ;
if ( ! ZEND_NUM_ARGS ( ) ) {
mode = res - > mode ;
}
} else {
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " r|lb " , & zres , & mode , & decode_binary ) ) {
return ;
}
ZEND_FETCH_RESOURCE ( res , struct php_sqlite_result * , & zres , - 1 , " sqlite result " , le_sqlite_result ) ;
if ( ZEND_NUM_ARGS ( ) < 2 ) {
mode = res - > mode ;
}
2003-05-03 06:09:54 +08:00
}
php_sqlite_fetch_array ( res , mode , decode_binary , 1 , return_value TSRMLS_CC ) ;
}
/* }}} */
2003-08-30 05:32:25 +08:00
/* {{{ proto object sqlite_fetch_object(resource result [, string class_name [, NULL|array ctor_params [, bool decode_binary]]])
2003-08-29 07:19:51 +08:00
Fetches the next row from a result set as an object . */
2003-08-30 05:13:50 +08:00
/* note that you can do array(&$val) for param ctor_params */
2003-08-29 07:19:51 +08:00
PHP_FUNCTION ( sqlite_fetch_object )
{
zval * zres ;
zend_bool decode_binary = 1 ;
struct php_sqlite_result * res ;
zval * object = getThis ( ) ;
char * class_name ;
int class_name_len ;
zend_class_entry * ce ;
zval dataset ;
zend_fcall_info fci ;
zend_fcall_info_cache fcc ;
2003-08-30 05:13:50 +08:00
zval * retval_ptr ;
zval * ctor_params = NULL ;
2003-08-29 07:19:51 +08:00
php_set_error_handling ( object ? EH_THROW : EH_NORMAL , sqlite_ce_exception TSRMLS_CC ) ;
if ( object ) {
2003-08-30 05:13:50 +08:00
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " |szb " , & class_name , & class_name_len , & ctor_params , & decode_binary ) ) {
2003-08-29 07:19:51 +08:00
php_std_error_handling ( ) ;
return ;
}
RES_FROM_OBJECT ( res , object ) ;
if ( ! ZEND_NUM_ARGS ( ) ) {
ce = zend_standard_class_def ;
} else {
ce = zend_fetch_class ( class_name , class_name_len , ZEND_FETCH_CLASS_AUTO TSRMLS_CC ) ;
}
} else {
2003-08-30 05:13:50 +08:00
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " r|szb " , & zres , & class_name , & class_name_len , & ctor_params , & decode_binary ) ) {
2003-08-29 07:19:51 +08:00
php_std_error_handling ( ) ;
return ;
}
ZEND_FETCH_RESOURCE ( res , struct php_sqlite_result * , & zres , - 1 , " sqlite result " , le_sqlite_result ) ;
if ( ZEND_NUM_ARGS ( ) < 2 ) {
ce = zend_standard_class_def ;
} else {
ce = zend_fetch_class ( class_name , class_name_len , ZEND_FETCH_CLASS_AUTO TSRMLS_CC ) ;
}
}
if ( ! ce ) {
zend_throw_exception_ex ( sqlite_ce_exception , 0 TSRMLS_CC , " Could not find class '%s' " , class_name ) ;
php_std_error_handling ( ) ;
return ;
}
2003-12-10 09:02:20 +08:00
if ( res - > curr_row < res - > nrows ) {
php_sqlite_fetch_array ( res , PHPSQLITE_ASSOC , decode_binary , 1 , & dataset TSRMLS_CC ) ;
} else {
RETURN_FALSE ;
}
2003-08-29 07:19:51 +08:00
2003-08-30 07:30:03 +08:00
object_and_properties_init ( return_value , ce , NULL ) ;
zend_merge_properties ( return_value , Z_ARRVAL ( dataset ) , 1 TSRMLS_CC ) ;
2003-08-29 07:19:51 +08:00
php_std_error_handling ( ) ; /* before calling the ctor */
if ( ce - > constructor ) {
fci . size = sizeof ( fci ) ;
fci . function_table = & ce - > function_table ;
fci . function_name = NULL ;
fci . symbol_table = NULL ;
fci . object_pp = & return_value ;
fci . retval_ptr_ptr = & retval_ptr ;
2003-08-30 05:33:24 +08:00
if ( ctor_params & & Z_TYPE_P ( ctor_params ) ! = IS_NULL ) {
2003-08-30 05:13:50 +08:00
if ( Z_TYPE_P ( ctor_params ) = = IS_ARRAY ) {
HashTable * ht = Z_ARRVAL_P ( ctor_params ) ;
Bucket * p ;
fci . param_count = 0 ;
2004-01-01 03:45:46 +08:00
fci . params = safe_emalloc ( sizeof ( zval * ) , ht - > nNumOfElements , 0 ) ;
2003-08-30 05:13:50 +08:00
p = ht - > pListHead ;
while ( p ! = NULL ) {
fci . params [ fci . param_count + + ] = ( zval * * ) p - > pData ;
p = p - > pListNext ;
}
} else {
/* Two problems why we throw exceptions here: PHP is typeless
* and hence passing one argument that ' s not an array could be
* by mistake and the other way round is possible , too . The
* single value is an array . Also we ' d have to make that one
* argument passed by reference .
*/
zend_throw_exception ( sqlite_ce_exception , " Parameter ctor_params must be an array " , 0 TSRMLS_CC ) ;
return ;
}
} else {
fci . param_count = 0 ;
fci . params = NULL ;
}
2003-08-29 07:19:51 +08:00
fci . no_separation = 1 ;
2003-08-31 20:41:53 +08:00
2003-08-29 07:19:51 +08:00
fcc . initialized = 1 ;
fcc . function_handler = ce - > constructor ;
fcc . calling_scope = EG ( scope ) ;
fcc . object_pp = & return_value ;
2003-08-31 20:41:53 +08:00
2003-08-29 07:19:51 +08:00
if ( zend_call_function ( & fci , & fcc TSRMLS_CC ) = = FAILURE ) {
zend_throw_exception_ex ( sqlite_ce_exception , 0 TSRMLS_CC , " Could not execute %s::%s() " , class_name , ce - > constructor - > common . function_name ) ;
} else {
2003-08-29 07:36:46 +08:00
if ( retval_ptr ) {
zval_ptr_dtor ( & retval_ptr ) ;
}
2003-08-29 07:19:51 +08:00
}
2003-08-30 05:13:50 +08:00
if ( fci . params ) {
efree ( fci . params ) ;
}
2003-08-30 05:32:25 +08:00
} else if ( ctor_params & & Z_TYPE_P ( ctor_params ) ! = IS_NULL ) {
2003-09-06 04:09:19 +08:00
zend_throw_exception_ex ( sqlite_ce_exception , 0 TSRMLS_CC , " Class %s does not have a constructor, use NULL for parameter ctor_params or omit it " , class_name ) ;
2003-08-29 07:19:51 +08:00
}
}
/* }}} */
2003-07-06 04:02:40 +08:00
/* {{{ proto array sqlite_array_query(resource db, string query [ , int result_type [, bool decode_binary]])
Executes a query against a given database and returns an array of arrays . */
2003-06-10 07:14:25 +08:00
PHP_FUNCTION ( sqlite_array_query )
{
zval * zdb , * ent ;
struct php_sqlite_db * db ;
struct php_sqlite_result * rres ;
char * sql ;
long sql_len ;
2004-02-24 23:47:38 +08:00
long mode = PHPSQLITE_BOTH ;
2003-06-10 07:14:25 +08:00
char * errtext = NULL ;
zend_bool decode_binary = 1 ;
2003-06-23 01:19:46 +08:00
zval * object = getThis ( ) ;
2003-06-10 07:14:25 +08:00
2003-06-23 01:19:46 +08:00
if ( object ) {
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " s|lb " , & sql , & sql_len , & mode , & decode_binary ) ) {
return ;
}
DB_FROM_OBJECT ( db , object ) ;
} else {
if ( FAILURE = = zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET ,
ZEND_NUM_ARGS ( ) TSRMLS_CC , " sr|lb " , & sql , & sql_len , & zdb , & mode , & decode_binary ) & &
FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " rs|lb " , & zdb , & sql , & sql_len , & mode , & decode_binary ) ) {
return ;
}
DB_FROM_ZVAL ( db , & zdb ) ;
2003-06-10 07:14:25 +08:00
}
/* avoid doing work if we can */
if ( ! return_value_used ) {
db - > last_err_code = sqlite_exec ( db - > db , sql , NULL , NULL , & errtext ) ;
if ( db - > last_err_code ! = SQLITE_OK ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " %s " , errtext ) ;
sqlite_freemem ( errtext ) ;
}
return ;
}
2003-06-23 01:19:46 +08:00
2003-06-10 07:14:25 +08:00
rres = ( struct php_sqlite_result * ) emalloc ( sizeof ( * rres ) ) ;
2003-12-29 00:26:04 +08:00
sqlite_query ( NULL , db , sql , sql_len , mode , 0 , NULL , & rres TSRMLS_CC ) ;
2003-06-24 03:37:48 +08:00
if ( db - > last_err_code ! = SQLITE_OK ) {
2003-12-29 00:26:04 +08:00
if ( rres ) {
efree ( rres ) ;
}
2003-06-24 03:37:48 +08:00
RETURN_FALSE ;
}
2003-06-10 07:14:25 +08:00
array_init ( return_value ) ;
while ( rres - > curr_row < rres - > nrows ) {
MAKE_STD_ZVAL ( ent ) ;
php_sqlite_fetch_array ( rres , mode , decode_binary , 1 , ent TSRMLS_CC ) ;
add_next_index_zval ( return_value , ent ) ;
}
real_result_dtor ( rres TSRMLS_CC ) ;
}
/* }}} */
2003-06-27 03:26:26 +08:00
/* {{{ php_sqlite_fetch_single */
static void php_sqlite_fetch_single ( struct php_sqlite_result * res , zend_bool decode_binary , zval * return_value TSRMLS_DC )
2003-05-14 07:51:25 +08:00
{
2003-06-26 00:59:24 +08:00
const char * * rowdata ;
2003-06-26 07:21:10 +08:00
char * decoded ;
2003-05-14 07:51:25 +08:00
int decoded_len ;
2003-06-26 00:59:24 +08:00
/* check range of the row */
2003-05-14 07:51:25 +08:00
if ( res - > curr_row > = res - > nrows ) {
2003-06-26 00:59:24 +08:00
/* no more */
2003-05-14 07:51:25 +08:00
RETURN_FALSE ;
}
2003-06-26 00:59:24 +08:00
2003-05-14 07:51:25 +08:00
if ( res - > buffered ) {
rowdata = ( const char * * ) & res - > table [ res - > curr_row * res - > ncolumns ] ;
} else {
rowdata = ( const char * * ) res - > table ;
}
if ( decode_binary & & rowdata [ 0 ] ! = NULL & & rowdata [ 0 ] [ 0 ] = = ' \x01 ' ) {
2003-06-15 02:16:47 +08:00
decoded = emalloc ( strlen ( rowdata [ 0 ] ) ) ;
2003-08-17 23:43:41 +08:00
decoded_len = php_sqlite_decode_binary ( rowdata [ 0 ] + 1 , decoded ) ;
2003-06-15 02:16:47 +08:00
if ( ! res - > buffered ) {
efree ( ( char * ) rowdata [ 0 ] ) ;
rowdata [ 0 ] = NULL ;
}
2003-06-26 00:59:24 +08:00
} else if ( rowdata [ 0 ] ) {
decoded_len = strlen ( ( char * ) rowdata [ 0 ] ) ;
if ( res - > buffered ) {
decoded = estrndup ( ( char * ) rowdata [ 0 ] , decoded_len ) ;
2003-06-15 02:16:47 +08:00
} else {
2003-06-26 00:59:24 +08:00
decoded = ( char * ) rowdata [ 0 ] ;
rowdata [ 0 ] = NULL ;
2003-06-15 02:16:47 +08:00
}
2003-06-26 07:21:10 +08:00
} else {
decoded = NULL ;
decoded_len = 0 ;
2003-05-14 07:51:25 +08:00
}
if ( ! res - > buffered ) {
/* non buffered: fetch next row */
php_sqlite_fetch ( res TSRMLS_CC ) ;
}
/* advance the row pointer */
res - > curr_row + + ;
if ( decoded = = NULL ) {
RETURN_NULL ( ) ;
} else {
2003-06-15 02:16:47 +08:00
RETURN_STRINGL ( decoded , decoded_len , 0 ) ;
2003-05-14 07:51:25 +08:00
}
}
/* }}} */
2003-06-26 00:59:24 +08:00
2003-07-06 04:02:40 +08:00
/* {{{ proto array sqlite_single_query(resource db, string query [, bool first_row_only [, bool decode_binary]])
Executes a query and returns either an array for one single column or the value of the first row . */
2003-06-26 00:59:24 +08:00
PHP_FUNCTION ( sqlite_single_query )
{
zval * zdb , * ent ;
struct php_sqlite_db * db ;
struct php_sqlite_result * rres ;
char * sql ;
long sql_len ;
char * errtext = NULL ;
zend_bool decode_binary = 1 ;
zend_bool srow = 1 ;
zval * object = getThis ( ) ;
if ( object ) {
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " s|bb " , & sql , & sql_len , & srow , & decode_binary ) ) {
return ;
}
RES_FROM_OBJECT ( db , object ) ;
} else {
if ( FAILURE = = zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET ,
ZEND_NUM_ARGS ( ) TSRMLS_CC , " sr|bb " , & sql , & sql_len , & zdb , & srow , & decode_binary ) & &
FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " rs|bb " , & zdb , & sql , & sql_len , & srow , & decode_binary ) ) {
return ;
}
DB_FROM_ZVAL ( db , & zdb ) ;
}
/* avoid doing work if we can */
if ( ! return_value_used ) {
db - > last_err_code = sqlite_exec ( db - > db , sql , NULL , NULL , & errtext ) ;
if ( db - > last_err_code ! = SQLITE_OK ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " %s " , errtext ) ;
sqlite_freemem ( errtext ) ;
}
return ;
}
rres = ( struct php_sqlite_result * ) emalloc ( sizeof ( * rres ) ) ;
2003-12-29 00:26:04 +08:00
sqlite_query ( NULL , db , sql , sql_len , PHPSQLITE_NUM , 0 , NULL , & rres TSRMLS_CC ) ;
2003-06-26 00:59:24 +08:00
if ( db - > last_err_code ! = SQLITE_OK ) {
2003-12-29 00:26:04 +08:00
if ( rres ) {
efree ( rres ) ;
}
2003-06-26 00:59:24 +08:00
RETURN_FALSE ;
}
if ( ! srow ) {
array_init ( return_value ) ;
}
while ( rres - > curr_row < rres - > nrows ) {
MAKE_STD_ZVAL ( ent ) ;
2003-06-27 03:26:26 +08:00
php_sqlite_fetch_single ( rres , decode_binary , ent TSRMLS_CC ) ;
2003-06-26 00:59:24 +08:00
/* if set and we only have 1 row in the result set, return the result as a string. */
if ( srow ) {
if ( rres - > curr_row = = 1 & & rres - > curr_row > = rres - > nrows ) {
* return_value = * ent ;
zval_copy_ctor ( return_value ) ;
zval_dtor ( ent ) ;
FREE_ZVAL ( ent ) ;
break ;
} else {
srow = 0 ;
array_init ( return_value ) ;
}
}
add_next_index_zval ( return_value , ent ) ;
}
real_result_dtor ( rres TSRMLS_CC ) ;
}
/* }}} */
2003-07-06 04:02:40 +08:00
/* {{{ proto string sqlite_fetch_single(resource result [, bool decode_binary])
Fetches the first column of a result set as a string . */
2003-06-27 03:26:26 +08:00
PHP_FUNCTION ( sqlite_fetch_single )
2003-06-26 00:59:24 +08:00
{
zval * zres ;
zend_bool decode_binary = 1 ;
struct php_sqlite_result * res ;
zval * object = getThis ( ) ;
if ( object ) {
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " |b " , & decode_binary ) ) {
return ;
}
RES_FROM_OBJECT ( res , object ) ;
} else {
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " r|b " , & zres , & decode_binary ) ) {
return ;
}
ZEND_FETCH_RESOURCE ( res , struct php_sqlite_result * , & zres , - 1 , " sqlite result " , le_sqlite_result ) ;
}
2003-06-27 03:26:26 +08:00
php_sqlite_fetch_single ( res , decode_binary , return_value TSRMLS_CC ) ;
2003-06-26 00:59:24 +08:00
}
/* }}} */
2003-07-06 04:02:40 +08:00
/* {{{ proto array sqlite_current(resource result [, int result_type [, bool decode_binary]])
Fetches the current row from a result set as an array . */
2003-05-03 06:09:54 +08:00
PHP_FUNCTION ( sqlite_current )
{
zval * zres ;
2004-02-24 23:47:38 +08:00
long mode = PHPSQLITE_BOTH ;
2003-05-03 06:09:54 +08:00
zend_bool decode_binary = 1 ;
struct php_sqlite_result * res ;
2003-06-23 01:19:46 +08:00
zval * object = getThis ( ) ;
2003-05-03 06:09:54 +08:00
2003-06-23 01:19:46 +08:00
if ( object ) {
if ( ZEND_NUM_ARGS ( ) & & FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " |lb " , & mode , & decode_binary ) ) {
return ;
}
RES_FROM_OBJECT ( res , object ) ;
if ( ! ZEND_NUM_ARGS ( ) ) {
mode = res - > mode ;
}
} else {
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " r|lb " , & zres , & mode , & decode_binary ) ) {
return ;
}
ZEND_FETCH_RESOURCE ( res , struct php_sqlite_result * , & zres , - 1 , " sqlite result " , le_sqlite_result ) ;
if ( ZEND_NUM_ARGS ( ) < 2 ) {
mode = res - > mode ;
}
2003-05-03 06:09:54 +08:00
}
php_sqlite_fetch_array ( res , mode , decode_binary , 0 , return_value TSRMLS_CC ) ;
}
2003-04-17 09:29:45 +08:00
/* }}} */
2003-06-21 20:29:32 +08:00
/* {{{ proto mixed sqlite_column(resource result, mixed index_or_name [, bool decode_binary])
2003-07-06 04:02:40 +08:00
Fetches a column from the current row of a result set . */
2003-05-03 20:51:13 +08:00
PHP_FUNCTION ( sqlite_column )
{
zval * zres ;
zval * which ;
zend_bool decode_binary = 1 ;
struct php_sqlite_result * res ;
2003-06-23 01:19:46 +08:00
zval * object = getThis ( ) ;
2003-05-03 20:51:13 +08:00
2003-06-23 01:19:46 +08:00
if ( object ) {
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " z|b " , & which , & decode_binary ) ) {
return ;
}
RES_FROM_OBJECT ( res , object ) ;
} else {
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " rz|b " , & zres , & which , & decode_binary ) ) {
return ;
}
ZEND_FETCH_RESOURCE ( res , struct php_sqlite_result * , & zres , - 1 , " sqlite result " , le_sqlite_result ) ;
2003-05-03 20:51:13 +08:00
}
php_sqlite_fetch_column ( res , which , decode_binary , return_value TSRMLS_CC ) ;
}
/* }}} */
2003-04-17 09:29:45 +08:00
/* {{{ proto string sqlite_libversion()
2003-07-06 04:02:40 +08:00
Returns the version of the linked SQLite library . */
2003-04-17 09:29:45 +08:00
PHP_FUNCTION ( sqlite_libversion )
{
if ( ZEND_NUM_ARGS ( ) ! = 0 ) {
WRONG_PARAM_COUNT ;
}
RETURN_STRING ( ( char * ) sqlite_libversion ( ) , 1 ) ;
}
/* }}} */
/* {{{ proto string sqlite_libencoding()
2003-07-06 04:02:40 +08:00
Returns the encoding ( iso8859 or UTF - 8 ) of the linked SQLite library . */
2003-04-17 09:29:45 +08:00
PHP_FUNCTION ( sqlite_libencoding )
{
if ( ZEND_NUM_ARGS ( ) ! = 0 ) {
WRONG_PARAM_COUNT ;
}
RETURN_STRING ( ( char * ) sqlite_libencoding ( ) , 1 ) ;
}
/* }}} */
/* {{{ proto int sqlite_changes(resource db)
2003-07-06 04:02:40 +08:00
Returns the number of rows that were changed by the most recent SQL statement . */
2003-04-17 09:29:45 +08:00
PHP_FUNCTION ( sqlite_changes )
{
zval * zdb ;
2003-04-18 04:08:00 +08:00
struct php_sqlite_db * db ;
2003-06-23 01:19:46 +08:00
zval * object = getThis ( ) ;
2003-04-17 09:29:45 +08:00
2003-06-23 01:19:46 +08:00
if ( object ) {
if ( ZEND_NUM_ARGS ( ) ! = 0 ) {
WRONG_PARAM_COUNT
}
DB_FROM_OBJECT ( db , object ) ;
} else {
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " r " , & zdb ) ) {
return ;
}
DB_FROM_ZVAL ( db , & zdb ) ;
2003-04-17 09:29:45 +08:00
}
2003-04-18 04:08:00 +08:00
RETURN_LONG ( sqlite_changes ( db - > db ) ) ;
2003-04-17 09:29:45 +08:00
}
/* }}} */
/* {{{ proto int sqlite_last_insert_rowid(resource db)
2003-07-06 04:02:40 +08:00
Returns the rowid of the most recently inserted row . */
2003-04-17 09:29:45 +08:00
PHP_FUNCTION ( sqlite_last_insert_rowid )
{
zval * zdb ;
2003-04-18 04:08:00 +08:00
struct php_sqlite_db * db ;
2003-06-23 01:19:46 +08:00
zval * object = getThis ( ) ;
2003-04-17 09:29:45 +08:00
2003-06-23 01:19:46 +08:00
if ( object ) {
if ( ZEND_NUM_ARGS ( ) ! = 0 ) {
WRONG_PARAM_COUNT
}
DB_FROM_OBJECT ( db , object ) ;
} else {
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " r " , & zdb ) ) {
return ;
}
DB_FROM_ZVAL ( db , & zdb ) ;
2003-04-17 09:29:45 +08:00
}
2003-04-18 04:08:00 +08:00
RETURN_LONG ( sqlite_last_insert_rowid ( db - > db ) ) ;
2003-04-17 09:29:45 +08:00
}
/* }}} */
/* {{{ proto int sqlite_num_rows(resource result)
2003-07-06 04:02:40 +08:00
Returns the number of rows in a buffered result set . */
2003-04-17 09:29:45 +08:00
PHP_FUNCTION ( sqlite_num_rows )
{
zval * zres ;
struct php_sqlite_result * res ;
2003-06-23 01:19:46 +08:00
zval * object = getThis ( ) ;
2003-04-17 09:29:45 +08:00
2003-06-23 01:19:46 +08:00
if ( object ) {
if ( ZEND_NUM_ARGS ( ) ! = 0 ) {
WRONG_PARAM_COUNT
}
RES_FROM_OBJECT ( res , object ) ;
} else {
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " r " , & zres ) ) {
return ;
}
ZEND_FETCH_RESOURCE ( res , struct php_sqlite_result * , & zres , - 1 , " sqlite result " , le_sqlite_result ) ;
2003-04-17 09:29:45 +08:00
}
2003-04-18 20:22:43 +08:00
if ( res - > buffered ) {
RETURN_LONG ( res - > nrows ) ;
} else {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Row count is not available for unbuffered queries " ) ;
RETURN_FALSE ;
}
2003-04-17 09:29:45 +08:00
}
/* }}} */
2003-05-03 06:09:54 +08:00
/* {{{ proto bool sqlite_has_more(resource result)
2003-07-06 04:02:40 +08:00
Returns whether more rows are available . */
2003-05-03 06:09:54 +08:00
PHP_FUNCTION ( sqlite_has_more )
{
zval * zres ;
struct php_sqlite_result * res ;
2003-06-23 01:19:46 +08:00
zval * object = getThis ( ) ;
2003-05-03 06:09:54 +08:00
2003-06-23 01:19:46 +08:00
if ( object ) {
if ( ZEND_NUM_ARGS ( ) ! = 0 ) {
WRONG_PARAM_COUNT
}
RES_FROM_OBJECT ( res , object ) ;
} else {
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " r " , & zres ) ) {
return ;
}
ZEND_FETCH_RESOURCE ( res , struct php_sqlite_result * , & zres , - 1 , " sqlite result " , le_sqlite_result ) ;
2003-05-03 06:09:54 +08:00
}
2003-06-23 01:19:46 +08:00
RETURN_BOOL ( res - > curr_row < res - > nrows & & res - > nrows ) ; /* curr_row may be -1 */
2003-05-03 06:09:54 +08:00
}
/* }}} */
2003-07-13 17:38:33 +08:00
/* {{{ proto bool sqlite_has_prev(resource result)
* Returns whether a previous row is available . */
PHP_FUNCTION ( sqlite_has_prev )
{
zval * zres ;
struct php_sqlite_result * res ;
zval * object = getThis ( ) ;
if ( object ) {
if ( ZEND_NUM_ARGS ( ) ! = 0 ) {
WRONG_PARAM_COUNT
}
RES_FROM_OBJECT ( res , object ) ;
} else {
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " r " , & zres ) ) {
return ;
}
ZEND_FETCH_RESOURCE ( res , struct php_sqlite_result * , & zres , - 1 , " sqlite result " , le_sqlite_result ) ;
}
if ( ! res - > buffered ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " you cannot use sqlite_has_prev on unbuffered querys " ) ;
RETURN_FALSE ;
}
RETURN_BOOL ( res - > curr_row ) ;
}
/* }}} */
2003-04-17 09:29:45 +08:00
/* {{{ proto int sqlite_num_fields(resource result)
2003-07-06 04:02:40 +08:00
Returns the number of fields in a result set . */
2003-04-17 09:29:45 +08:00
PHP_FUNCTION ( sqlite_num_fields )
{
zval * zres ;
struct php_sqlite_result * res ;
2003-06-23 01:19:46 +08:00
zval * object = getThis ( ) ;
2003-04-17 09:29:45 +08:00
2003-06-23 01:19:46 +08:00
if ( object ) {
if ( ZEND_NUM_ARGS ( ) ! = 0 ) {
WRONG_PARAM_COUNT
}
RES_FROM_OBJECT ( res , object ) ;
} else {
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " r " , & zres ) ) {
return ;
}
ZEND_FETCH_RESOURCE ( res , struct php_sqlite_result * , & zres , - 1 , " sqlite result " , le_sqlite_result ) ;
2003-04-17 09:29:45 +08:00
}
2003-04-27 21:25:10 +08:00
RETURN_LONG ( res - > ncolumns ) ;
2003-04-17 09:29:45 +08:00
}
/* }}} */
2003-07-06 04:02:40 +08:00
/* {{{ proto string sqlite_field_name(resource result, int field_index)
Returns the name of a particular field of a result set . */
2003-04-17 09:29:45 +08:00
PHP_FUNCTION ( sqlite_field_name )
{
zval * zres ;
struct php_sqlite_result * res ;
2004-02-24 23:47:38 +08:00
long field ;
2003-06-23 01:19:46 +08:00
zval * object = getThis ( ) ;
2003-04-17 09:29:45 +08:00
2003-06-23 01:19:46 +08:00
if ( object ) {
2003-07-06 04:02:40 +08:00
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " l " , & field ) ) {
2003-06-23 01:19:46 +08:00
return ;
}
RES_FROM_OBJECT ( res , object ) ;
} else {
2003-07-06 04:02:40 +08:00
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " rl " , & zres , & field ) ) {
2003-06-23 01:19:46 +08:00
return ;
}
ZEND_FETCH_RESOURCE ( res , struct php_sqlite_result * , & zres , - 1 , " sqlite result " , le_sqlite_result ) ;
2003-04-17 09:29:45 +08:00
}
2003-04-27 21:25:10 +08:00
if ( field < 0 | | field > = res - > ncolumns ) {
2004-02-24 23:47:38 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " field %ld out of range " , field ) ;
2003-04-17 09:29:45 +08:00
RETURN_FALSE ;
}
2003-04-27 21:25:10 +08:00
RETURN_STRING ( res - > col_names [ field ] , 1 ) ;
2003-04-17 09:29:45 +08:00
}
/* }}} */
/* {{{ proto bool sqlite_seek(resource result, int row)
2003-07-06 04:02:40 +08:00
Seek to a particular row number of a buffered result set . */
2003-04-17 09:29:45 +08:00
PHP_FUNCTION ( sqlite_seek )
{
zval * zres ;
struct php_sqlite_result * res ;
2004-02-24 23:47:38 +08:00
long row ;
2003-06-23 01:19:46 +08:00
zval * object = getThis ( ) ;
2003-04-17 09:29:45 +08:00
2003-06-23 01:19:46 +08:00
if ( object ) {
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " l " , & row ) ) {
return ;
}
RES_FROM_OBJECT ( res , object ) ;
} else {
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " rl " , & zres , & row ) ) {
return ;
}
ZEND_FETCH_RESOURCE ( res , struct php_sqlite_result * , & zres , - 1 , " sqlite result " , le_sqlite_result ) ;
2003-04-17 09:29:45 +08:00
}
2003-04-18 20:22:43 +08:00
if ( ! res - > buffered ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Cannot seek an unbuffered result set " ) ;
RETURN_FALSE ;
}
2003-07-09 02:57:28 +08:00
if ( row < 0 | | row > = res - > nrows ) {
2004-02-24 23:47:38 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " row %ld out of range " , row ) ;
2003-04-17 09:29:45 +08:00
RETURN_FALSE ;
}
2003-05-03 06:09:54 +08:00
res - > curr_row = row ;
RETURN_TRUE ;
}
/* }}} */
/* {{{ proto bool sqlite_rewind(resource result)
2003-07-06 04:02:40 +08:00
Seek to the first row number of a buffered result set . */
2003-05-03 06:09:54 +08:00
PHP_FUNCTION ( sqlite_rewind )
{
zval * zres ;
struct php_sqlite_result * res ;
2003-06-23 01:19:46 +08:00
zval * object = getThis ( ) ;
2003-05-03 06:09:54 +08:00
2003-06-23 01:19:46 +08:00
if ( object ) {
if ( ZEND_NUM_ARGS ( ) ! = 0 ) {
WRONG_PARAM_COUNT
}
RES_FROM_OBJECT ( res , object ) ;
} else {
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " r " , & zres ) ) {
return ;
}
ZEND_FETCH_RESOURCE ( res , struct php_sqlite_result * , & zres , - 1 , " sqlite result " , le_sqlite_result ) ;
2003-05-03 06:09:54 +08:00
}
if ( ! res - > buffered ) {
2003-07-13 17:38:33 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Cannot rewind an unbuffered result set " ) ;
2003-05-03 06:09:54 +08:00
RETURN_FALSE ;
}
if ( ! res - > nrows ) {
2003-06-07 03:00:16 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " no rows received " ) ;
2003-05-03 06:09:54 +08:00
RETURN_FALSE ;
}
res - > curr_row = 0 ;
RETURN_TRUE ;
}
/* }}} */
/* {{{ proto bool sqlite_next(resource result)
2003-07-06 04:02:40 +08:00
Seek to the next row number of a result set . */
2003-05-03 06:09:54 +08:00
PHP_FUNCTION ( sqlite_next )
{
zval * zres ;
struct php_sqlite_result * res ;
2003-06-23 01:19:46 +08:00
zval * object = getThis ( ) ;
2003-05-03 06:09:54 +08:00
2003-06-23 01:19:46 +08:00
if ( object ) {
if ( ZEND_NUM_ARGS ( ) ! = 0 ) {
WRONG_PARAM_COUNT
}
RES_FROM_OBJECT ( res , object ) ;
} else {
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " r " , & zres ) ) {
return ;
}
ZEND_FETCH_RESOURCE ( res , struct php_sqlite_result * , & zres , - 1 , " sqlite result " , le_sqlite_result ) ;
2003-05-03 06:09:54 +08:00
}
if ( ! res - > buffered & & res - > vm ) {
php_sqlite_fetch ( res TSRMLS_CC ) ;
}
if ( res - > curr_row > = res - > nrows ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " no more rows available " ) ;
RETURN_FALSE ;
}
res - > curr_row + + ;
2003-04-17 09:29:45 +08:00
RETURN_TRUE ;
}
/* }}} */
2003-07-13 17:38:33 +08:00
/* {{{ proto bool sqlite_prev(resource result)
* Seek to the previous row number of a result set . */
PHP_FUNCTION ( sqlite_prev )
{
zval * zres ;
struct php_sqlite_result * res ;
zval * object = getThis ( ) ;
if ( object ) {
if ( ZEND_NUM_ARGS ( ) ! = 0 ) {
WRONG_PARAM_COUNT
}
RES_FROM_OBJECT ( res , object ) ;
} else {
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " r " , & zres ) ) {
return ;
}
ZEND_FETCH_RESOURCE ( res , struct php_sqlite_result * , & zres , - 1 , " sqlite result " , le_sqlite_result ) ;
}
if ( ! res - > buffered ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " you cannot use sqlite_prev on unbuffered querys " ) ;
RETURN_FALSE ;
}
if ( res - > curr_row < = 0 ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " no previous row available " ) ;
RETURN_FALSE ;
}
res - > curr_row - - ;
RETURN_TRUE ;
}
/* }}} */
2003-04-17 10:20:26 +08:00
/* {{{ proto string sqlite_escape_string(string item)
2003-07-06 04:02:40 +08:00
Escapes a string for use as a query parameter . */
2003-04-17 10:20:26 +08:00
PHP_FUNCTION ( sqlite_escape_string )
{
2003-04-19 20:54:17 +08:00
char * string = NULL ;
2004-02-22 20:10:00 +08:00
int stringlen ;
2003-04-17 10:20:26 +08:00
char * ret ;
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " s " , & string , & stringlen ) ) {
return ;
}
2003-04-19 20:54:17 +08:00
if ( stringlen & & ( string [ 0 ] = = ' \x01 ' | | memchr ( string , ' \0 ' , stringlen ) ! = NULL ) ) {
/* binary string */
int enclen ;
ret = emalloc ( 1 + ( ( 256 * stringlen + 1262 ) / 253 ) ) ;
ret [ 0 ] = ' \x01 ' ;
2003-08-17 23:43:41 +08:00
enclen = php_sqlite_encode_binary ( string , stringlen , ret + 1 ) ;
2003-04-19 20:54:17 +08:00
RETVAL_STRINGL ( ret , enclen + 1 , 0 ) ;
} else {
ret = sqlite_mprintf ( " %q " , string ) ;
if ( ret ) {
RETVAL_STRING ( ret , 1 ) ;
sqlite_freemem ( ret ) ;
}
2003-04-17 10:20:26 +08:00
}
}
/* }}} */
2003-04-18 04:08:00 +08:00
/* {{{ proto int sqlite_last_error(resource db)
2003-07-06 04:02:40 +08:00
Returns the error code of the last error for a database . */
2003-04-18 04:08:00 +08:00
PHP_FUNCTION ( sqlite_last_error )
{
zval * zdb ;
struct php_sqlite_db * db ;
2003-06-23 01:19:46 +08:00
zval * object = getThis ( ) ;
2003-04-17 10:20:26 +08:00
2003-06-23 01:19:46 +08:00
if ( object ) {
if ( ZEND_NUM_ARGS ( ) ! = 0 ) {
WRONG_PARAM_COUNT
}
DB_FROM_OBJECT ( db , object ) ;
} else {
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " r " , & zdb ) ) {
return ;
}
DB_FROM_ZVAL ( db , & zdb ) ;
2003-04-18 04:08:00 +08:00
}
RETURN_LONG ( db - > last_err_code ) ;
}
/* }}} */
/* {{{ proto string sqlite_error_string(int error_code)
2003-07-06 04:02:40 +08:00
Returns the textual description of an error code . */
2003-04-18 04:08:00 +08:00
PHP_FUNCTION ( sqlite_error_string )
{
long code ;
const char * msg ;
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " l " , & code ) ) {
return ;
}
msg = sqlite_error_string ( code ) ;
if ( msg ) {
RETURN_STRING ( ( char * ) msg , 1 ) ;
} else {
RETURN_NULL ( ) ;
}
}
/* }}} */
2003-04-20 21:08:22 +08:00
2003-04-20 23:13:04 +08:00
/* manages duplicate registrations of a particular function, and
* also handles the case where the db is using a persistent connection */
enum callback_prep_t { DO_REG , SKIP_REG , ERR } ;
static enum callback_prep_t prep_callback_struct ( struct php_sqlite_db * db , int is_agg ,
char * funcname ,
zval * step , zval * fini , struct php_sqlite_agg_functions * * funcs )
{
struct php_sqlite_agg_functions * alloc_funcs , func_tmp ;
char * hashkey ;
int hashkeylen ;
enum callback_prep_t ret ;
hashkeylen = spprintf ( & hashkey , 0 , " %s-%s " , is_agg ? " agg " : " reg " , funcname ) ;
/* is it already registered ? */
if ( SUCCESS = = zend_hash_find ( & db - > callbacks , hashkey , hashkeylen + 1 , ( void * ) & alloc_funcs ) ) {
/* override the previous definition */
if ( alloc_funcs - > is_valid ) {
/* release these */
if ( alloc_funcs - > step ) {
zval_ptr_dtor ( & alloc_funcs - > step ) ;
alloc_funcs - > step = NULL ;
}
if ( alloc_funcs - > fini ) {
zval_ptr_dtor ( & alloc_funcs - > fini ) ;
alloc_funcs - > fini = NULL ;
}
}
ret = SKIP_REG ;
} else {
/* add a new one */
func_tmp . db = db ;
ret = SUCCESS = = zend_hash_update ( & db - > callbacks , hashkey , hashkeylen + 1 ,
( void * ) & func_tmp , sizeof ( func_tmp ) , ( void * * ) & alloc_funcs ) ? DO_REG : ERR ;
}
efree ( hashkey ) ;
MAKE_STD_ZVAL ( alloc_funcs - > step ) ;
* ( alloc_funcs - > step ) = * step ;
zval_copy_ctor ( alloc_funcs - > step ) ;
if ( is_agg ) {
MAKE_STD_ZVAL ( alloc_funcs - > fini ) ;
* ( alloc_funcs - > fini ) = * fini ;
zval_copy_ctor ( alloc_funcs - > fini ) ;
} else {
alloc_funcs - > fini = NULL ;
}
alloc_funcs - > is_valid = 1 ;
* funcs = alloc_funcs ;
return ret ;
}
2003-04-20 21:31:36 +08:00
/* {{{ proto bool sqlite_create_aggregate(resource db, string funcname, mixed step_func, mixed finalize_func[, long num_args])
2003-07-06 04:02:40 +08:00
Registers an aggregate function for queries . */
2003-04-20 21:08:22 +08:00
PHP_FUNCTION ( sqlite_create_aggregate )
{
char * funcname = NULL ;
long funcname_len ;
zval * zstep , * zfinal , * zdb ;
struct php_sqlite_db * db ;
struct php_sqlite_agg_functions * funcs ;
char * callable = NULL ;
long num_args = - 1 ;
2003-06-23 01:19:46 +08:00
zval * object = getThis ( ) ;
if ( object ) {
2004-02-16 04:15:34 +08:00
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " szz|l " , & funcname , & funcname_len , & zstep , & zfinal , & num_args ) ) {
2003-06-23 01:19:46 +08:00
return ;
}
DB_FROM_OBJECT ( db , object ) ;
} else {
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " rszz|l " , & zdb , & funcname , & funcname_len , & zstep , & zfinal , & num_args ) ) {
return ;
}
DB_FROM_ZVAL ( db , & zdb ) ;
2003-04-20 21:08:22 +08:00
}
if ( ! zend_is_callable ( zstep , 0 , & callable ) ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " step function `%s' is not callable " , callable ) ;
efree ( callable ) ;
return ;
}
efree ( callable ) ;
if ( ! zend_is_callable ( zfinal , 0 , & callable ) ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " finalize function `%s' is not callable " , callable ) ;
efree ( callable ) ;
return ;
}
efree ( callable ) ;
2003-06-23 01:19:46 +08:00
2003-04-20 23:13:04 +08:00
if ( prep_callback_struct ( db , 1 , funcname , zstep , zfinal , & funcs ) = = DO_REG ) {
sqlite_create_aggregate ( db - > db , funcname , num_args ,
php_sqlite_agg_step_function_callback ,
php_sqlite_agg_fini_function_callback , funcs ) ;
}
2003-04-20 21:08:22 +08:00
2003-04-20 23:13:04 +08:00
2003-04-20 21:08:22 +08:00
}
/* }}} */
2003-04-20 21:31:36 +08:00
/* {{{ proto bool sqlite_create_function(resource db, string funcname, mixed callback[, long num_args])
2003-07-06 04:02:40 +08:00
Registers a " regular " function for queries . */
2003-04-20 21:31:36 +08:00
PHP_FUNCTION ( sqlite_create_function )
{
char * funcname = NULL ;
long funcname_len ;
zval * zcall , * zdb ;
struct php_sqlite_db * db ;
struct php_sqlite_agg_functions * funcs ;
char * callable = NULL ;
long num_args = - 1 ;
2003-06-23 01:19:46 +08:00
zval * object = getThis ( ) ;
if ( object ) {
2003-06-26 01:22:31 +08:00
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " sz|l " , & funcname , & funcname_len , & zcall , & num_args ) ) {
2003-06-23 01:19:46 +08:00
return ;
}
DB_FROM_OBJECT ( db , object ) ;
} else {
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " rsz|l " , & zdb , & funcname , & funcname_len , & zcall , & num_args ) ) {
return ;
}
DB_FROM_ZVAL ( db , & zdb ) ;
2003-04-20 21:31:36 +08:00
}
if ( ! zend_is_callable ( zcall , 0 , & callable ) ) {
2003-04-20 23:13:04 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " function `%s' is not callable " , callable ) ;
2003-04-20 21:31:36 +08:00
efree ( callable ) ;
return ;
}
efree ( callable ) ;
2003-04-20 23:13:04 +08:00
if ( prep_callback_struct ( db , 0 , funcname , zcall , NULL , & funcs ) = = DO_REG ) {
sqlite_create_function ( db - > db , funcname , num_args , php_sqlite_function_callback , funcs ) ;
}
2003-04-20 21:31:36 +08:00
}
/* }}} */
2003-04-22 08:08:48 +08:00
2003-06-21 20:29:32 +08:00
/* {{{ proto string sqlite_udf_encode_binary(string data)
2003-07-06 04:02:40 +08:00
Apply binary encoding ( if required ) to a string to return from an UDF . */
2003-06-21 20:29:32 +08:00
PHP_FUNCTION ( sqlite_udf_encode_binary )
{
char * data = NULL ;
2004-02-23 09:21:16 +08:00
int datalen ;
2003-06-21 20:29:32 +08:00
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " s! " , & data , & datalen ) ) {
return ;
}
if ( data = = NULL ) {
RETURN_NULL ( ) ;
}
if ( datalen & & ( data [ 0 ] = = ' \x01 ' | | memchr ( data , ' \0 ' , datalen ) ! = NULL ) ) {
/* binary string */
int enclen ;
char * ret ;
ret = emalloc ( 1 + ( ( 256 * datalen + 1262 ) / 253 ) ) ;
ret [ 0 ] = ' \x01 ' ;
2003-08-17 23:43:41 +08:00
enclen = php_sqlite_encode_binary ( data , datalen , ret + 1 ) ;
2003-06-21 20:29:32 +08:00
RETVAL_STRINGL ( ret , enclen + 1 , 0 ) ;
} else {
RETVAL_STRINGL ( data , datalen , 1 ) ;
}
}
/* }}} */
/* {{{ proto string sqlite_udf_decode_binary(string data)
2003-07-06 04:02:40 +08:00
Decode binary encoding on a string parameter passed to an UDF . */
2003-06-21 20:29:32 +08:00
PHP_FUNCTION ( sqlite_udf_decode_binary )
{
char * data = NULL ;
long datalen ;
if ( FAILURE = = zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " s! " , & data , & datalen ) ) {
return ;
}
if ( data = = NULL ) {
RETURN_NULL ( ) ;
}
if ( datalen & & data [ 0 ] = = ' \x01 ' ) {
/* encoded string */
int enclen ;
char * ret ;
ret = emalloc ( datalen ) ;
2003-08-17 23:43:41 +08:00
enclen = php_sqlite_decode_binary ( data + 1 , ret ) ;
2003-06-21 20:29:32 +08:00
ret [ enclen ] = ' \0 ' ;
RETVAL_STRINGL ( ret , enclen , 0 ) ;
} else {
RETVAL_STRINGL ( data , datalen , 1 ) ;
}
}
/* }}} */
2003-04-22 08:08:48 +08:00
/*
* Local variables :
* tab - width : 4
* c - basic - offset : 4
* End :
* vim600 : sw = 4 ts = 4 fdm = marker
* vim < 600 : sw = 4 ts = 4
*/