1999-04-22 10:48:28 +08:00
/*
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2001-12-11 23:32:16 +08:00
| PHP Version 4 |
1999-04-22 10:48:28 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2003-01-01 00:08:15 +08:00
| Copyright ( c ) 1997 - 2003 The PHP Group |
1999-04-22 10:48:28 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2003-06-11 04:04:29 +08:00
| This source file is subject to version 3.0 of the PHP license , |
1999-07-16 21:13:16 +08:00
| that is bundled with this package in the file LICENSE , and is |
2003-06-11 04:04:29 +08:00
| available through the world - wide - web at the following url : |
| http : //www.php.net/license/3_0.txt. |
1999-07-16 21:13:16 +08:00
| 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 . |
1999-04-22 10:48:28 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2001-01-04 19:15:35 +08:00
| Authors : Jouni Ahto < jouni . ahto @ exdec . fi > |
2000-05-15 05:55:45 +08:00
| Andrew Avdeev < andy @ rsc . mv . ru > |
2003-08-16 00:13:51 +08:00
| Ard Biesheuvel < a . k . biesheuvel @ its . tudelft . nl > |
1999-04-22 10:48:28 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
*/
/* $Id$ */
2000-03-13 03:44:23 +08:00
/*
Changes :
2003-08-05 21:17:16 +08:00
2003 - 08 - 05 : Ard Biesheuvel < a . k . biesheuvel @ its . tudelft . nl >
- Significant changes to layout of internal data structures
in order to accomodate and carry out the following changes :
* Removal of arbitrary ' transactions - per - link ' limit ,
* Transactions over multiple databases .
- Leak fixes in ibase_query ( ) and ibase_execute ( ) by replacing
emalloc ( ) with do_alloca ( )
- Changes to ibase_query ( ) to enable the use of CREATE DATABASE . . .
- Added ibase_drop_db ( )
2003-08-07 09:00:22 +08:00
- Added ibase_commit_ret ( ) and ibase_rollback_ret ( )
- Added ibase_name_result ( )
2001-09-05 05:47:05 +08:00
2001 - 05 - 31 : Jeremy Bettis < jeremy @ deadbeef . com >
- If a blob handle was expected and something else was
received create a blob and add the value to it .
- If the incoming argument to a bind parameter is NULL
then store a NULL in the database .
- More verbose date errors .
2000-03-13 03:44:23 +08:00
1999 - 09 - 21 : Ivo Panacek < ivop @ regionet . cz >
- added COMPILE_DL section
- more verbose php_info_ibase function
mostly stolen from pgsql . c for now
1999 - 10 - 05 : Ivo Panacek < ivop @ regionet . cz >
- safe rinit / rfinish : check for NULL so
rfinish could be called repeatedly
emalloc & co . replaced with malloc & co .
*/
1999-04-22 10:48:28 +08:00
2001-05-24 18:07:29 +08:00
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
1999-04-22 10:48:28 +08:00
# include "php.h"
2000-03-13 03:44:23 +08:00
# include "php_ini.h"
# include "ext/standard/php_standard.h"
# include "php_globals.h"
1999-12-05 03:19:57 +08:00
# include "php_interbase.h"
1999-04-22 10:48:28 +08:00
# if HAVE_IBASE
# include <ibase.h>
2003-08-12 21:19:36 +08:00
# ifndef SQLDA_CURRENT_VERSION
# define SQLDA_CURRENT_VERSION SQLDA_VERSION1
# endif
1999-04-22 10:48:28 +08:00
# include <time.h>
2000-03-13 03:44:23 +08:00
# include "ext/standard/fsock.h"
2000-04-07 00:57:33 +08:00
# include "ext/standard/info.h"
2000-04-30 13:46:04 +08:00
2000-05-10 04:30:23 +08:00
# ifdef SQL_INT64
# include <math.h>
# endif
2000-05-15 05:55:45 +08:00
# ifndef SQL_DIALECT_CURRENT
# define SQL_DIALECT_CURRENT 1
# endif
2003-08-05 21:17:16 +08:00
# ifdef ZEND_DEBUG
2003-08-13 18:35:14 +08:00
/* #define IBDEBUG(a) php_printf("::: %s (%d)\n", a, __LINE__); */
# define IBDEBUG(a)
2003-08-05 21:17:16 +08:00
# else
2000-07-09 18:30:52 +08:00
# define IBDEBUG(a)
2003-08-05 21:17:16 +08:00
# endif
1999-04-22 10:48:28 +08:00
2000-04-18 10:52:45 +08:00
# define SAFE_STRING(s) ((s)?(s):"")
1999-04-22 10:48:28 +08:00
/* {{{ extension definition structures */
function_entry ibase_functions [ ] = {
2000-03-13 03:44:23 +08:00
PHP_FE ( ibase_connect , NULL )
PHP_FE ( ibase_pconnect , NULL )
PHP_FE ( ibase_close , NULL )
2003-08-05 21:17:16 +08:00
PHP_FE ( ibase_drop_db , NULL )
2000-03-13 03:44:23 +08:00
PHP_FE ( ibase_query , NULL )
PHP_FE ( ibase_fetch_row , NULL )
2002-03-15 23:26:01 +08:00
PHP_FE ( ibase_fetch_assoc , NULL )
2000-03-13 03:44:23 +08:00
PHP_FE ( ibase_fetch_object , NULL )
PHP_FE ( ibase_free_result , NULL )
2003-08-07 01:51:46 +08:00
PHP_FE ( ibase_name_result , NULL )
2000-03-13 03:44:23 +08:00
PHP_FE ( ibase_prepare , NULL )
PHP_FE ( ibase_execute , NULL )
PHP_FE ( ibase_free_query , NULL )
2002-09-12 19:18:47 +08:00
# if HAVE_STRFTIME
2000-03-13 03:44:23 +08:00
PHP_FE ( ibase_timefmt , NULL )
2002-09-12 19:18:47 +08:00
# endif
2000-03-13 03:44:23 +08:00
PHP_FE ( ibase_num_fields , NULL )
2003-08-11 04:53:19 +08:00
PHP_FE ( ibase_num_params , NULL )
2003-08-11 00:21:26 +08:00
PHP_FE ( ibase_num_rows , NULL )
PHP_FE ( ibase_affected_rows , NULL )
2000-03-13 03:44:23 +08:00
PHP_FE ( ibase_field_info , NULL )
2003-08-11 04:53:19 +08:00
PHP_FE ( ibase_param_info , NULL )
2000-03-13 03:44:23 +08:00
PHP_FE ( ibase_trans , NULL )
PHP_FE ( ibase_commit , NULL )
PHP_FE ( ibase_rollback , NULL )
2003-08-07 01:51:46 +08:00
PHP_FE ( ibase_commit_ret , NULL )
PHP_FE ( ibase_rollback_ret , NULL )
2000-03-13 03:44:23 +08:00
PHP_FE ( ibase_blob_info , NULL )
PHP_FE ( ibase_blob_create , NULL )
PHP_FE ( ibase_blob_add , NULL )
PHP_FE ( ibase_blob_cancel , NULL )
PHP_FE ( ibase_blob_close , NULL )
PHP_FE ( ibase_blob_open , NULL )
PHP_FE ( ibase_blob_get , NULL )
PHP_FE ( ibase_blob_echo , NULL )
PHP_FE ( ibase_blob_import , NULL )
PHP_FE ( ibase_errmsg , NULL )
2003-08-08 19:04:12 +08:00
PHP_FE ( ibase_errcode , NULL )
2002-01-27 23:31:15 +08:00
2002-06-07 03:47:28 +08:00
# ifdef SQL_DIALECT_V6
2002-01-27 23:31:15 +08:00
PHP_FE ( ibase_add_user , NULL )
PHP_FE ( ibase_modify_user , NULL )
PHP_FE ( ibase_delete_user , NULL )
2002-06-07 03:47:28 +08:00
# endif
2003-08-14 18:55:02 +08:00
PHP_FE ( ibase_wait_event , NULL )
2003-08-15 08:06:07 +08:00
PHP_FE ( ibase_set_event_handler , NULL )
2003-08-16 00:13:51 +08:00
PHP_FE ( ibase_free_event_handler , NULL )
1999-04-22 10:48:28 +08:00
{ NULL , NULL , NULL }
} ;
2003-03-16 13:00:50 +08:00
zend_module_entry ibase_module_entry = {
2001-10-12 07:33:59 +08:00
STANDARD_MODULE_HEADER ,
2000-03-07 02:44:01 +08:00
" interbase " ,
1999-04-22 10:48:28 +08:00
ibase_functions ,
1999-08-02 23:02:52 +08:00
PHP_MINIT ( ibase ) ,
2000-03-13 03:44:23 +08:00
PHP_MSHUTDOWN ( ibase ) ,
1999-08-02 23:02:52 +08:00
PHP_RINIT ( ibase ) ,
2000-04-18 10:52:45 +08:00
PHP_RSHUTDOWN ( ibase ) ,
1999-08-02 23:02:52 +08:00
PHP_MINFO ( ibase ) ,
2003-03-16 13:00:50 +08:00
NO_VERSION_YET ,
1999-04-22 10:48:28 +08:00
STANDARD_MODULE_PROPERTIES
} ;
2000-05-23 17:33:51 +08:00
# ifdef COMPILE_DL_INTERBASE
2000-05-02 08:30:36 +08:00
ZEND_GET_MODULE ( ibase )
2000-03-13 03:44:23 +08:00
# define DL_MALLOC(size) malloc(size)
# define DL_STRDUP(str) strdup(str)
# define DL_FREE(ptr) free(ptr)
# else
# define DL_MALLOC(size) emalloc(size)
# define DL_STRDUP(str) estrdup(str)
# define DL_FREE(ptr) efree(ptr)
# endif
1999-04-22 10:48:28 +08:00
2000-10-05 20:47:39 +08:00
/* True globals, no need for thread safety */
2003-08-15 08:06:07 +08:00
static int le_blob , le_link , le_plink , le_result , le_query , le_trans , le_event ;
2000-10-05 20:47:39 +08:00
2000-07-05 12:21:00 +08:00
ZEND_DECLARE_MODULE_GLOBALS ( ibase )
2000-03-13 03:44:23 +08:00
/* }}} */
2003-08-05 21:17:16 +08:00
/* error handling ---------------------------- */
2000-03-13 03:44:23 +08:00
# define IB_STATUS (IBG(status))
2003-08-05 21:17:16 +08:00
/* {{{ proto string ibase_errmsg(void)
Return error message */
PHP_FUNCTION ( ibase_errmsg )
{
if ( ZEND_NUM_ARGS ( ) ! = 0 ) {
WRONG_PARAM_COUNT ;
}
2003-08-08 19:04:12 +08:00
if ( IBG ( sql_code ) ! = 0 ) {
2003-08-05 21:17:16 +08:00
RETURN_STRING ( IBG ( errmsg ) , 1 ) ;
}
RETURN_FALSE ;
}
/* }}} */
2003-08-08 19:04:12 +08:00
/* {{{ proto string ibase_errcode(void)
Return error code */
PHP_FUNCTION ( ibase_errcode )
{
if ( ZEND_NUM_ARGS ( ) ! = 0 ) {
WRONG_PARAM_COUNT ;
}
if ( IBG ( sql_code ) ! = 0 ) {
RETURN_LONG ( IBG ( sql_code ) ) ;
}
RETURN_FALSE ;
}
/* }}} */
2003-08-05 21:17:16 +08:00
/* {{{ _php_ibase_error(TSRMLS_D)
print interbase error and save it for ibase_errmsg ( ) */
static void _php_ibase_error ( TSRMLS_D )
{
2003-08-08 19:04:12 +08:00
char * s = IBG ( errmsg ) ;
ISC_STATUS * statusp = IB_STATUS ;
2003-08-05 21:17:16 +08:00
2003-08-08 19:04:12 +08:00
IBG ( sql_code ) = isc_sqlcode ( IB_STATUS ) ;
2003-08-05 21:17:16 +08:00
while ( ( s - IBG ( errmsg ) ) < MAX_ERRMSG - ( IBASE_MSGSIZE + 2 ) & & isc_interprete ( s , & statusp ) ) {
strcat ( IBG ( errmsg ) , " " ) ;
s = IBG ( errmsg ) + strlen ( IBG ( errmsg ) ) ;
}
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " %s " , IBG ( errmsg ) ) ;
}
/* }}} */
/* {{{ _php_ibase_module_error()
print php interbase module error and save it for ibase_errmsg ( ) */
static void _php_ibase_module_error ( char * msg , . . . )
{
va_list ap ;
TSRMLS_FETCH ( ) ;
va_start ( ap , msg ) ;
/* vsnprintf NUL terminates the buf and writes at most n-1 chars+NUL */
vsnprintf ( IBG ( errmsg ) , MAX_ERRMSG , msg , ap ) ;
va_end ( ap ) ;
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " %s " , IBG ( errmsg ) ) ;
}
/* }}} */
/* {{{ internal macros, functions and structures */
typedef struct {
isc_db_handle * db_ptr ;
long tpb_len ;
char * tpb_ptr ;
} ISC_TEB ;
2003-08-08 09:42:09 +08:00
/* Fill ib_link and trans with the correct database link and transaction.
2003-03-16 13:00:50 +08:00
*/
2003-08-05 21:17:16 +08:00
static void _php_ibase_get_link_trans ( INTERNAL_FUNCTION_PARAMETERS , zval * * link_id , ibase_db_link * * ib_link , ibase_trans * * trans )
2003-03-16 13:00:50 +08:00
{
2000-07-07 20:06:05 +08:00
int type ;
IBDEBUG ( " Transaction or database link? " ) ;
2003-08-11 04:53:19 +08:00
if ( zend_list_find ( Z_LVAL_PP ( link_id ) , & type ) ) {
if ( type = = le_trans ) {
/* Transaction resource: make sure it refers to one link only, then
fetch it ; database link is stored in ib_trans - > db_link [ ] . */
IBDEBUG ( " Type is le_trans " ) ;
ZEND_FETCH_RESOURCE ( * trans , ibase_trans * , link_id , - 1 , " InterBase transaction " , le_trans ) ;
if ( ( * trans ) - > link_cnt > 1 ) {
_php_ibase_module_error ( " Link id is ambiguous: transaction spans multiple connections. " ) ;
return ;
}
* ib_link = ( * trans ) - > db_link [ 0 ] ;
2003-08-10 21:20:38 +08:00
return ;
2003-08-11 04:53:19 +08:00
}
}
IBDEBUG ( " Type is le_[p]link or id not found " ) ;
/* Database link resource, use default transaction. */
* trans = NULL ;
ZEND_FETCH_RESOURCE2 ( * ib_link , ibase_db_link * , link_id , - 1 , " InterBase link " , le_link , le_plink ) ;
2000-07-07 20:06:05 +08:00
}
2000-04-18 10:52:45 +08:00
2003-08-08 19:04:12 +08:00
# define RESET_ERRMSG { IBG(errmsg)[0] = '\0'; IBG(sql_code) = 0; }
2000-03-13 03:44:23 +08:00
/* sql variables union
2003-03-16 13:00:50 +08:00
* used for convert and binding input variables
*/
2000-03-13 03:44:23 +08:00
typedef struct {
union {
short sval ;
float fval ;
ISC_QUAD qval ;
2000-05-15 05:55:45 +08:00
# ifdef ISC_TIMESTAMP
2000-05-12 11:02:14 +08:00
ISC_TIMESTAMP tsval ;
ISC_DATE dtval ;
ISC_TIME tmval ;
2000-05-15 05:55:45 +08:00
# endif
2000-03-13 03:44:23 +08:00
} val ;
short sqlind ;
} BIND_BUF ;
/* get blob identifier from argument
2003-03-16 13:00:50 +08:00
* on empty unset argument ib_blob set to NULL
*/
2000-03-13 03:44:23 +08:00
# define GET_BLOB_ID_ARG(blob_arg, ib_blob)\
{ \
2001-09-26 05:58:48 +08:00
if ( Z_TYPE_P ( blob_arg ) = = IS_STRING & & Z_STRLEN_P ( blob_arg ) = = 0 ) { \
2000-03-13 03:44:23 +08:00
ib_blob = NULL ; \
2001-09-26 05:58:48 +08:00
} else if ( Z_TYPE_P ( blob_arg ) ! = IS_STRING \
| | Z_STRLEN_P ( blob_arg ) ! = sizeof ( ibase_blob_handle ) \
2003-03-16 13:00:50 +08:00
| | ( ( ibase_blob_handle * ) ( Z_STRVAL_P ( blob_arg ) ) ) - > bl_handle ! = 0 ) { \
2002-07-19 17:21:29 +08:00
_php_ibase_module_error ( " Invalid blob id " ) ; \
2000-03-13 03:44:23 +08:00
RETURN_FALSE ; \
} else { \
2001-09-26 05:58:48 +08:00
ib_blob = ( ibase_blob_handle * ) Z_STRVAL_P ( blob_arg ) ; \
2000-03-13 03:44:23 +08:00
} \
}
/* get blob handle from argument
2003-03-16 13:00:50 +08:00
* note : blob already open when handle active
*/
2000-03-13 03:44:23 +08:00
# define GET_BLOB_HANDLE_ARG(blob_arg, blob_ptr) \
{ \
int type ; \
2003-01-15 23:36:28 +08:00
convert_to_long_ex ( blob_arg ) ; \
blob_ptr = ( ibase_blob_handle * ) zend_list_find ( Z_LVAL_PP ( blob_arg ) , & type ) ; \
2000-10-05 20:47:39 +08:00
if ( type ! = le_blob ) { \
2003-01-15 23:36:28 +08:00
_php_ibase_module_error ( " %d is not blob handle " , Z_LVAL_PP ( blob_arg ) ) ; \
2000-03-13 03:44:23 +08:00
RETURN_FALSE ; \
} \
}
2003-03-16 13:00:50 +08:00
/* blob information struct
*/
2000-03-13 03:44:23 +08:00
typedef struct {
ISC_LONG max_segment ; /* Length of longest segment */
ISC_LONG num_segments ; /* Total number of segments */
ISC_LONG total_length ; /* Total length of blob */
int bl_stream ; /* blob is stream ? */
} IBASE_BLOBINFO ;
/* }}} */
/* destructors ---------------------- */
2003-03-16 13:00:50 +08:00
/* {{{ _php_ibase_free_xsqlda() (not actual destructor)
*/
2000-03-13 03:44:23 +08:00
static void _php_ibase_free_xsqlda ( XSQLDA * sqlda )
1999-04-22 10:48:28 +08:00
{
2000-03-13 03:44:23 +08:00
int i ;
XSQLVAR * var ;
1999-04-22 10:48:28 +08:00
2000-04-30 13:46:04 +08:00
IBDEBUG ( " Free XSQLDA? " ) ;
2000-04-18 10:52:45 +08:00
if ( sqlda ) {
2000-04-30 13:46:04 +08:00
IBDEBUG ( " Freeing XSQLDA... " ) ;
2000-03-13 03:44:23 +08:00
var = sqlda - > sqlvar ;
for ( i = 0 ; i < sqlda - > sqld ; i + + , var + + ) {
efree ( var - > sqldata ) ;
2003-03-16 13:00:50 +08:00
if ( var - > sqlind ) {
2000-03-13 03:44:23 +08:00
efree ( var - > sqlind ) ;
2003-03-16 13:00:50 +08:00
}
2000-03-13 03:44:23 +08:00
}
efree ( sqlda ) ;
}
1999-04-22 10:48:28 +08:00
}
/* }}} */
2003-03-16 13:00:50 +08:00
/* {{{ _php_ibase_commit_link()
*/
static void _php_ibase_commit_link ( ibase_db_link * link TSRMLS_DC )
1999-04-22 10:48:28 +08:00
{
2003-08-05 21:17:16 +08:00
int i = 0 , j ;
ibase_tr_list * l ;
2000-07-05 12:21:00 +08:00
IBDEBUG ( " Checking transactions to close... " ) ;
2003-08-05 21:17:16 +08:00
2003-08-08 19:04:12 +08:00
for ( l = link - > tr_list ; l ! = NULL ; + + i ) {
2003-08-05 21:17:16 +08:00
ibase_tr_list * p = l ;
if ( p - > trans ! = NULL ) {
if ( i = = 0 ) {
2003-08-06 23:27:16 +08:00
if ( p - > trans - > handle ! = NULL ) {
IBDEBUG ( " Committing default transaction... " ) ;
if ( isc_commit_transaction ( IB_STATUS , & p - > trans - > handle ) ) {
_php_ibase_error ( TSRMLS_C ) ;
}
2003-08-05 21:17:16 +08:00
}
efree ( p - > trans ) ; /* default transaction is not a registered resource: clean up */
}
2003-08-06 23:27:16 +08:00
else {
if ( p - > trans - > handle ! = NULL ) {
/* non-default transaction might have been rolled back by other call of this dtor */
IBDEBUG ( " Rolling back other transactions... " ) ;
if ( isc_rollback_transaction ( IB_STATUS , & p - > trans - > handle ) ) {
_php_ibase_error ( TSRMLS_C ) ;
}
2003-08-05 21:17:16 +08:00
}
/* set this link pointer to NULL in the transaction */
for ( j = 0 ; j < p - > trans - > link_cnt ; + + j ) {
2003-08-08 19:04:12 +08:00
if ( p - > trans - > db_link [ j ] = = link ) {
p - > trans - > db_link [ j ] = NULL ;
2003-08-05 21:17:16 +08:00
break ;
}
}
2000-03-13 03:44:23 +08:00
}
1999-04-22 10:48:28 +08:00
}
2003-08-05 21:17:16 +08:00
l = l - > next ;
efree ( p ) ;
1999-04-22 10:48:28 +08:00
}
2003-08-08 19:04:12 +08:00
link - > tr_list = NULL ;
1999-04-22 10:48:28 +08:00
}
/* }}} */
2001-07-31 13:44:11 +08:00
static void php_ibase_commit_link_rsrc ( zend_rsrc_list_entry * rsrc TSRMLS_DC )
2000-10-21 02:25:16 +08:00
{
2003-03-16 13:00:50 +08:00
ibase_db_link * link = ( ibase_db_link * ) rsrc - > ptr ;
2001-07-31 13:44:11 +08:00
2003-03-16 13:00:50 +08:00
_php_ibase_commit_link ( link TSRMLS_CC ) ;
2000-10-21 02:25:16 +08:00
}
2000-03-13 03:44:23 +08:00
2003-03-16 13:00:50 +08:00
/* {{{ _php_ibase_close_link()
*/
2001-07-31 13:44:11 +08:00
static void _php_ibase_close_link ( zend_rsrc_list_entry * rsrc TSRMLS_DC )
1999-04-22 10:48:28 +08:00
{
2003-03-16 13:00:50 +08:00
ibase_db_link * link = ( ibase_db_link * ) rsrc - > ptr ;
2000-07-05 12:21:00 +08:00
2003-03-16 13:00:50 +08:00
_php_ibase_commit_link ( link TSRMLS_CC ) ;
2003-08-13 02:01:59 +08:00
if ( link - > handle ! = NULL ) {
2003-08-06 23:27:16 +08:00
IBDEBUG ( " Closing normal link... " ) ;
2003-08-13 02:01:59 +08:00
isc_detach_database ( IB_STATUS , & link - > handle ) ;
2003-08-05 21:17:16 +08:00
}
2000-03-13 03:44:23 +08:00
IBG ( num_links ) - - ;
efree ( link ) ;
}
/* }}} */
2003-03-16 13:00:50 +08:00
/* {{{ _php_ibase_close_plink()
*/
2001-07-31 13:44:11 +08:00
static void _php_ibase_close_plink ( zend_rsrc_list_entry * rsrc TSRMLS_DC )
2000-03-13 03:44:23 +08:00
{
2003-03-16 13:00:50 +08:00
ibase_db_link * link = ( ibase_db_link * ) rsrc - > ptr ;
2000-07-05 12:21:00 +08:00
2003-03-16 13:00:50 +08:00
_php_ibase_commit_link ( link TSRMLS_CC ) ;
2000-04-30 13:46:04 +08:00
IBDEBUG ( " Closing permanent link... " ) ;
2003-08-13 02:01:59 +08:00
if ( link - > handle ! = NULL ) {
isc_detach_database ( IB_STATUS , & link - > handle ) ;
2003-08-05 21:17:16 +08:00
}
2000-03-13 03:44:23 +08:00
IBG ( num_persistent ) - - ;
IBG ( num_links ) - - ;
free ( link ) ;
}
/* }}} */
2003-03-16 13:00:50 +08:00
/* {{{ _php_ibase_free_result()
*/
2001-07-31 13:44:11 +08:00
static void _php_ibase_free_result ( zend_rsrc_list_entry * rsrc TSRMLS_DC )
2000-03-13 03:44:23 +08:00
{
2003-03-16 13:00:50 +08:00
ibase_result * ib_result = ( ibase_result * ) rsrc - > ptr ;
2000-07-05 12:21:00 +08:00
2003-05-06 06:25:29 +08:00
IBDEBUG ( " Freeing result by dtor... " ) ;
2003-03-16 13:00:50 +08:00
if ( ib_result ) {
2000-03-13 03:44:23 +08:00
_php_ibase_free_xsqlda ( ib_result - > out_sqlda ) ;
2003-05-06 06:25:29 +08:00
if ( ib_result - > drop_stmt & & ib_result - > stmt ) {
IBDEBUG ( " Dropping statement handle (free_result dtor)... " ) ;
isc_dsql_free_statement ( IB_STATUS , & ib_result - > stmt , DSQL_drop ) ;
2000-03-13 03:44:23 +08:00
} else {
2000-06-25 00:24:29 +08:00
/* Shouldn't be here unless query was select and had parameter
placeholders , in which case ibase_execute handles this ? ? ?
2000-07-07 20:06:05 +08:00
( Testing seems to confirm the decision was a right one . )
2000-06-25 00:24:29 +08:00
*/
2000-04-30 13:46:04 +08:00
IBDEBUG ( " Closing statement handle... " ) ;
2000-06-25 00:24:29 +08:00
/*
2000-04-18 10:52:45 +08:00
if ( isc_dsql_free_statement ( IB_STATUS , & ib_result - > stmt , DSQL_close ) ) {
2000-03-13 03:44:23 +08:00
_php_ibase_error ( ) ;
}
2000-06-25 00:24:29 +08:00
*/
2000-03-13 03:44:23 +08:00
}
if ( ib_result - > out_array ) {
efree ( ib_result - > out_array ) ;
}
efree ( ib_result ) ;
}
}
/* }}} */
/* {{{ _php_ibase_free_query() */
2003-03-16 13:00:50 +08:00
static void _php_ibase_free_query ( ibase_query * ib_query TSRMLS_DC )
2000-03-13 03:44:23 +08:00
{
2000-05-12 16:37:03 +08:00
IBDEBUG ( " Freeing query... " ) ;
2000-04-18 10:52:45 +08:00
if ( ib_query ) {
2000-03-13 03:44:23 +08:00
if ( ib_query - > in_sqlda ) {
efree ( ib_query - > in_sqlda ) ;
}
if ( ib_query - > out_sqlda ) {
efree ( ib_query - > out_sqlda ) ;
}
2003-05-06 06:25:29 +08:00
if ( ib_query - > stmt ) {
2000-04-30 13:46:04 +08:00
IBDEBUG ( " Dropping statement handle (free_query)... " ) ;
2003-03-16 13:00:50 +08:00
if ( isc_dsql_free_statement ( IB_STATUS , & ib_query - > stmt , DSQL_drop ) ) {
2002-07-19 17:21:29 +08:00
_php_ibase_error ( TSRMLS_C ) ;
1999-04-22 10:48:28 +08:00
}
}
2000-03-13 03:44:23 +08:00
if ( ib_query - > in_array ) {
efree ( ib_query - > in_array ) ;
}
if ( ib_query - > out_array ) {
efree ( ib_query - > out_array ) ;
}
2003-08-13 02:01:59 +08:00
if ( ib_query - > query ) {
efree ( ib_query - > query ) ;
}
2000-03-13 03:44:23 +08:00
efree ( ib_query ) ;
}
}
/* }}} */
2003-05-06 06:25:29 +08:00
/* {{{ php_ibase_free_query_rsrc() */
2001-07-31 13:44:11 +08:00
static void php_ibase_free_query_rsrc ( zend_rsrc_list_entry * rsrc TSRMLS_DC )
2000-10-21 02:25:16 +08:00
{
2003-05-06 06:25:29 +08:00
ibase_query * ib_query = ( ibase_query * ) rsrc - > ptr ;
2001-07-31 13:44:11 +08:00
2003-05-06 06:25:29 +08:00
IBDEBUG ( " Freeing query by dtor... " ) ;
if ( ib_query ) {
if ( ib_query - > in_sqlda ) {
efree ( ib_query - > in_sqlda ) ;
}
if ( ib_query - > out_sqlda ) {
efree ( ib_query - > out_sqlda ) ;
}
if ( ib_query - > stmt ) {
IBDEBUG ( " Dropping statement handle (free_query dtor)... " ) ;
isc_dsql_free_statement ( IB_STATUS , & ib_query - > stmt , DSQL_drop ) ;
}
if ( ib_query - > in_array ) {
efree ( ib_query - > in_array ) ;
}
if ( ib_query - > out_array ) {
efree ( ib_query - > out_array ) ;
}
2003-08-13 02:01:59 +08:00
if ( ib_query - > query ) {
efree ( ib_query - > query ) ;
}
2003-05-06 06:25:29 +08:00
efree ( ib_query ) ;
}
2000-10-21 02:25:16 +08:00
}
2003-05-06 06:25:29 +08:00
/* }}} */
2000-03-13 03:44:23 +08:00
/* {{{ _php_ibase_free_blob() */
2001-07-31 13:44:11 +08:00
static void _php_ibase_free_blob ( zend_rsrc_list_entry * rsrc TSRMLS_DC )
2000-03-13 03:44:23 +08:00
{
2000-10-21 02:25:16 +08:00
ibase_blob_handle * ib_blob = ( ibase_blob_handle * ) rsrc - > ptr ;
2000-07-05 12:21:00 +08:00
2000-03-13 03:44:23 +08:00
if ( ib_blob - > bl_handle ! = NULL ) { /* blob open*/
if ( isc_cancel_blob ( IB_STATUS , & ib_blob - > bl_handle ) ) {
2003-01-15 11:01:17 +08:00
php_error_docref ( NULL TSRMLS_CC , E_ERROR , " You can lose data. Close any blob after reading of writing it. Use ibase_blob_close() before calling ibase_close() " ) ;
2000-03-13 03:44:23 +08:00
}
1999-04-22 10:48:28 +08:00
}
2000-03-13 03:44:23 +08:00
efree ( ib_blob ) ;
1999-04-22 10:48:28 +08:00
}
/* }}} */
2000-07-09 15:30:15 +08:00
/* {{{ _php_ibase_free_trans() */
2001-07-31 13:44:11 +08:00
static void _php_ibase_free_trans ( zend_rsrc_list_entry * rsrc TSRMLS_DC )
2000-07-09 15:30:15 +08:00
{
2003-08-07 08:00:19 +08:00
ibase_trans * trans = ( ibase_trans * ) rsrc - > ptr ;
2003-08-05 21:17:16 +08:00
int i ;
2000-07-09 15:30:15 +08:00
2003-08-05 21:17:16 +08:00
IBDEBUG ( " Cleaning up transaction resource... " ) ;
if ( trans - > handle ! = NULL ) {
IBDEBUG ( " Rolling back unhandled transaction... " ) ;
if ( isc_rollback_transaction ( IB_STATUS , & trans - > handle ) ) {
_php_ibase_error ( TSRMLS_C ) ;
}
}
/* now remove this transaction from all the connection-transaction lists */
for ( i = 0 ; i < trans - > link_cnt ; + + i ) {
2003-08-08 19:04:12 +08:00
if ( trans - > db_link [ i ] ! = NULL ) {
2003-08-05 21:17:16 +08:00
ibase_tr_list * * l ;
2003-08-08 19:04:12 +08:00
for ( l = & trans - > db_link [ i ] - > tr_list ; * l ! = NULL ; l = & ( * l ) - > next ) {
2003-08-05 21:17:16 +08:00
if ( ( * l ) - > trans = = trans ) {
ibase_tr_list * p = * l ;
* l = p - > next ;
efree ( p ) ;
break ;
2002-05-10 05:41:20 +08:00
}
2000-07-09 15:30:15 +08:00
}
}
2003-08-05 21:17:16 +08:00
}
efree ( trans ) ;
2000-07-09 15:30:15 +08:00
}
/* }}} */
2003-08-15 08:06:07 +08:00
/* {{{ _php_ibase_event_free() */
static void _php_ibase_event_free ( char * event_buf , char * result_buf )
{
isc_free ( event_buf ) ;
isc_free ( result_buf ) ;
}
/* }}} */
/* {{{ _php_ibase_free_event */
static void _php_ibase_free_event ( zend_rsrc_list_entry * rsrc TSRMLS_DC )
{
ibase_event * event = ( ibase_event * ) rsrc - > ptr ;
IBDEBUG ( " Cleaning up event resource " ) ;
zval_dtor ( event - > callback ) ;
event - > callback = NULL ;
if ( event - > link - > handle ! = NULL ) {
if ( isc_cancel_events ( IB_STATUS , & event - > link - > handle , & event - > event_id ) ) {
_php_ibase_error ( TSRMLS_C ) ;
}
}
_php_ibase_event_free ( event - > event_buffer , event - > result_buffer ) ;
}
/* }}} */
1999-04-22 10:48:28 +08:00
/* {{{ startup, shutdown and info functions */
2000-04-18 10:52:45 +08:00
PHP_INI_BEGIN ( )
2003-03-16 13:00:50 +08:00
STD_PHP_INI_BOOLEAN ( " ibase.allow_persistent " , " 1 " , PHP_INI_SYSTEM , OnUpdateLong , allow_persistent , zend_ibase_globals , ibase_globals )
STD_PHP_INI_ENTRY_EX ( " ibase.max_persistent " , " -1 " , PHP_INI_SYSTEM , OnUpdateLong , max_persistent , zend_ibase_globals , ibase_globals , display_link_numbers )
STD_PHP_INI_ENTRY_EX ( " ibase.max_links " , " -1 " , PHP_INI_SYSTEM , OnUpdateLong , max_links , zend_ibase_globals , ibase_globals , display_link_numbers )
STD_PHP_INI_ENTRY ( " ibase.default_user " , NULL , PHP_INI_ALL , OnUpdateString , default_user , zend_ibase_globals , ibase_globals )
STD_PHP_INI_ENTRY ( " ibase.default_password " , NULL , PHP_INI_ALL , OnUpdateString , default_password , zend_ibase_globals , ibase_globals )
STD_PHP_INI_ENTRY ( " ibase.timestampformat " , " %m/%d/%Y %H:%M:%S " , PHP_INI_ALL , OnUpdateString , cfg_timestampformat , zend_ibase_globals , ibase_globals )
STD_PHP_INI_ENTRY ( " ibase.dateformat " , " %m/%d/%Y " , PHP_INI_ALL , OnUpdateString , cfg_dateformat , zend_ibase_globals , ibase_globals )
STD_PHP_INI_ENTRY ( " ibase.timeformat " , " %H:%M:%S " , PHP_INI_ALL , OnUpdateString , cfg_timeformat , zend_ibase_globals , ibase_globals )
2000-04-18 10:52:45 +08:00
PHP_INI_END ( )
2001-09-05 05:47:05 +08:00
static void php_ibase_init_globals ( zend_ibase_globals * ibase_globals )
1999-04-22 10:48:28 +08:00
{
2001-09-05 05:47:05 +08:00
ibase_globals - > timestampformat = NULL ;
ibase_globals - > dateformat = NULL ;
ibase_globals - > timeformat = NULL ;
ibase_globals - > num_persistent = 0 ;
2003-08-08 19:04:12 +08:00
ibase_globals - > sql_code = 0 ;
2000-07-05 12:21:00 +08:00
}
PHP_MINIT_FUNCTION ( ibase )
{
ZEND_INIT_MODULE_GLOBALS ( ibase , php_ibase_init_globals , NULL ) ;
2000-04-18 10:52:45 +08:00
REGISTER_INI_ENTRIES ( ) ;
2000-10-26 01:44:02 +08:00
le_result = zend_register_list_destructors_ex ( _php_ibase_free_result , NULL , " interbase result " , module_number ) ;
le_query = zend_register_list_destructors_ex ( php_ibase_free_query_rsrc , NULL , " interbase query " , module_number ) ;
le_blob = zend_register_list_destructors_ex ( _php_ibase_free_blob , NULL , " interbase blob " , module_number ) ;
le_link = zend_register_list_destructors_ex ( _php_ibase_close_link , NULL , " interbase link " , module_number ) ;
le_plink = zend_register_list_destructors_ex ( php_ibase_commit_link_rsrc , _php_ibase_close_plink , " interbase link persistent " , module_number ) ;
le_trans = zend_register_list_destructors_ex ( _php_ibase_free_trans , NULL , " interbase transaction " , module_number ) ;
2003-08-15 08:06:07 +08:00
le_event = zend_register_list_destructors_ex ( _php_ibase_free_event , NULL , " interbase event " , module_number ) ;
2000-03-13 03:44:23 +08:00
REGISTER_LONG_CONSTANT ( " IBASE_DEFAULT " , PHP_IBASE_DEFAULT , CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " IBASE_TEXT " , PHP_IBASE_TEXT , CONST_PERSISTENT ) ;
2000-05-12 11:02:14 +08:00
REGISTER_LONG_CONSTANT ( " IBASE_UNIXTIME " , PHP_IBASE_UNIXTIME , CONST_PERSISTENT ) ;
2003-06-15 00:38:10 +08:00
REGISTER_LONG_CONSTANT ( " IBASE_TIMESTAMP " , PHP_IBASE_TIMESTAMP , CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " IBASE_DATE " , PHP_IBASE_DATE , CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " IBASE_TIME " , PHP_IBASE_TIME , CONST_PERSISTENT ) ;
/* transactions */
REGISTER_LONG_CONSTANT ( " IBASE_WRITE " , PHP_IBASE_WRITE , CONST_PERSISTENT ) ;
2000-03-13 03:44:23 +08:00
REGISTER_LONG_CONSTANT ( " IBASE_READ " , PHP_IBASE_READ , CONST_PERSISTENT ) ;
2000-04-18 10:52:45 +08:00
REGISTER_LONG_CONSTANT ( " IBASE_COMMITTED " , PHP_IBASE_COMMITTED , CONST_PERSISTENT ) ;
2000-03-13 03:44:23 +08:00
REGISTER_LONG_CONSTANT ( " IBASE_CONSISTENCY " , PHP_IBASE_CONSISTENCY , CONST_PERSISTENT ) ;
2003-06-15 00:38:10 +08:00
REGISTER_LONG_CONSTANT ( " IBASE_CONCURRENCY " , PHP_IBASE_CONCURRENCY , CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " IBASE_REC_VERSION " , PHP_IBASE_REC_VERSION , CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " IBASE_REC_NO_VERSION " , PHP_IBASE_REC_NO_VERSION , CONST_PERSISTENT ) ;
2000-03-13 03:44:23 +08:00
REGISTER_LONG_CONSTANT ( " IBASE_NOWAIT " , PHP_IBASE_NOWAIT , CONST_PERSISTENT ) ;
2003-06-15 00:38:10 +08:00
REGISTER_LONG_CONSTANT ( " IBASE_WAIT " , PHP_IBASE_WAIT , CONST_PERSISTENT ) ;
2000-03-13 03:44:23 +08:00
1999-04-22 10:48:28 +08:00
return SUCCESS ;
}
1999-08-02 23:02:52 +08:00
PHP_RINIT_FUNCTION ( ibase )
1999-04-22 10:48:28 +08:00
{
2000-04-18 10:52:45 +08:00
IBG ( default_link ) = - 1 ;
2000-03-13 03:44:23 +08:00
IBG ( num_links ) = IBG ( num_persistent ) ;
2003-03-16 13:00:50 +08:00
if ( IBG ( timestampformat ) ) {
DL_FREE ( IBG ( timestampformat ) ) ;
}
2000-05-12 11:02:14 +08:00
IBG ( timestampformat ) = DL_STRDUP ( IBG ( cfg_timestampformat ) ) ;
2003-03-16 13:00:50 +08:00
if ( IBG ( dateformat ) ) {
DL_FREE ( IBG ( dateformat ) ) ;
}
2000-05-12 11:02:14 +08:00
IBG ( dateformat ) = DL_STRDUP ( IBG ( cfg_dateformat ) ) ;
2003-03-16 13:00:50 +08:00
if ( IBG ( timeformat ) ) {
DL_FREE ( IBG ( timeformat ) ) ;
}
2000-03-13 03:44:23 +08:00
IBG ( timeformat ) = DL_STRDUP ( IBG ( cfg_timeformat ) ) ;
2003-08-07 09:00:22 +08:00
RESET_ERRMSG ;
1999-04-22 10:48:28 +08:00
return SUCCESS ;
}
2000-03-13 03:44:23 +08:00
PHP_MSHUTDOWN_FUNCTION ( ibase )
1999-04-22 10:48:28 +08:00
{
2000-04-18 10:52:45 +08:00
UNREGISTER_INI_ENTRIES ( ) ;
2000-03-13 03:44:23 +08:00
return SUCCESS ;
1999-04-22 10:48:28 +08:00
}
2000-03-13 03:44:23 +08:00
PHP_RSHUTDOWN_FUNCTION ( ibase )
1999-04-22 10:48:28 +08:00
{
2003-03-16 13:00:50 +08:00
if ( IBG ( timestampformat ) ) {
DL_FREE ( IBG ( timestampformat ) ) ;
}
2000-05-12 11:02:14 +08:00
IBG ( timestampformat ) = NULL ;
2003-03-16 13:00:50 +08:00
if ( IBG ( dateformat ) ) {
DL_FREE ( IBG ( dateformat ) ) ;
}
2000-05-12 11:02:14 +08:00
IBG ( dateformat ) = NULL ;
2003-03-16 13:00:50 +08:00
if ( IBG ( timeformat ) ) {
DL_FREE ( IBG ( timeformat ) ) ;
}
2000-04-18 10:52:45 +08:00
IBG ( timeformat ) = NULL ;
2003-03-16 13:00:50 +08:00
return SUCCESS ;
2000-03-13 03:44:23 +08:00
}
1999-08-02 23:02:52 +08:00
PHP_MINFO_FUNCTION ( ibase )
1999-04-22 10:48:28 +08:00
{
2000-04-07 05:07:44 +08:00
char tmp [ 32 ] ;
2000-03-13 03:44:23 +08:00
2000-04-07 00:57:33 +08:00
php_info_print_table_start ( ) ;
2003-03-16 13:00:50 +08:00
php_info_print_table_row ( 2 , " Interbase Support " , " enabled " ) ;
2000-04-07 00:57:33 +08:00
php_info_print_table_row ( 2 , " Revision " , " $Revision$ " ) ;
2000-05-23 17:33:51 +08:00
# ifdef COMPILE_DL_INTERBASE
2003-08-06 23:27:16 +08:00
php_info_print_table_row ( 2 , " Dynamic Module " , " Yes " ) ;
2000-03-13 03:44:23 +08:00
# endif
2003-03-16 13:00:50 +08:00
php_info_print_table_row ( 2 , " Allow Persistent Links " , ( IBG ( allow_persistent ) ? " Yes " : " No " ) ) ;
2000-04-07 00:57:33 +08:00
2000-03-13 03:44:23 +08:00
if ( IBG ( max_persistent ) = = - 1 ) {
2000-06-25 00:24:29 +08:00
snprintf ( tmp , 31 , " %ld/unlimited " , IBG ( num_persistent ) ) ;
2000-03-13 03:44:23 +08:00
} else {
2000-06-25 00:24:29 +08:00
snprintf ( tmp , 31 , " %ld/%ld " , IBG ( num_persistent ) , IBG ( max_persistent ) ) ;
2000-03-13 03:44:23 +08:00
}
2003-03-16 13:00:50 +08:00
tmp [ 31 ] = 0 ;
php_info_print_table_row ( 2 , " Persistent Links " , tmp ) ;
2000-04-07 00:57:33 +08:00
2000-03-13 03:44:23 +08:00
if ( IBG ( max_links ) = = - 1 ) {
2000-06-25 00:24:29 +08:00
snprintf ( tmp , 31 , " %ld/unlimited " , IBG ( num_links ) ) ;
2000-03-13 03:44:23 +08:00
} else {
2000-06-25 00:24:29 +08:00
snprintf ( tmp , 31 , " %ld/%ld " , IBG ( num_links ) , IBG ( max_links ) ) ;
2000-03-13 03:44:23 +08:00
}
2003-03-16 13:00:50 +08:00
tmp [ 31 ] = 0 ;
php_info_print_table_row ( 2 , " Total Links " , tmp ) ;
2000-04-07 00:57:33 +08:00
2003-03-16 13:00:50 +08:00
php_info_print_table_row ( 2 , " Timestamp Format " , IBG ( timestampformat ) ) ;
php_info_print_table_row ( 2 , " Date Format " , IBG ( dateformat ) ) ;
php_info_print_table_row ( 2 , " Time Format " , IBG ( timeformat ) ) ;
2000-04-07 00:57:33 +08:00
php_info_print_table_end ( ) ;
1999-04-22 10:48:28 +08:00
}
/* }}} */
/* {{{ _php_ibase_attach_db() */
2003-03-16 13:00:50 +08:00
static int _php_ibase_attach_db ( char * server , char * uname , char * passwd , char * charset , int buffers , char * role , isc_db_handle * db TSRMLS_DC )
1999-04-22 10:48:28 +08:00
{
2000-03-13 03:44:23 +08:00
char dpb_buffer [ 256 ] , * dpb , * p ;
int dpb_length , len ;
dpb = dpb_buffer ;
* dpb + + = isc_dpb_version1 ;
if ( uname ! = NULL & & ( len = strlen ( uname ) ) ) {
* dpb + + = isc_dpb_user_name ;
* dpb + + = len ;
for ( p = uname ; * p ; ) {
* dpb + + = * p + + ;
}
}
1999-04-22 10:48:28 +08:00
2000-03-13 03:44:23 +08:00
if ( passwd ! = NULL & & ( len = strlen ( passwd ) ) ) {
* dpb + + = isc_dpb_password ;
* dpb + + = strlen ( passwd ) ;
for ( p = passwd ; * p ; ) {
* dpb + + = * p + + ;
}
1999-04-22 10:48:28 +08:00
}
2000-03-13 03:44:23 +08:00
if ( charset ! = NULL & & ( len = strlen ( charset ) ) ) {
* dpb + + = isc_dpb_lc_ctype ;
* dpb + + = strlen ( charset ) ;
for ( p = charset ; * p ; ) {
* dpb + + = * p + + ;
}
1999-04-22 10:48:28 +08:00
}
2000-03-13 03:44:23 +08:00
if ( buffers ) {
* dpb + + = isc_dpb_num_buffers ;
* dpb + + = 1 ;
* dpb + + = buffers ;
}
1999-04-22 10:48:28 +08:00
2000-03-13 03:44:23 +08:00
# ifdef isc_dpb_sql_role_name
if ( role ! = NULL & & ( len = strlen ( role ) ) ) {
* dpb + + = isc_dpb_sql_role_name ;
* dpb + + = strlen ( role ) ;
for ( p = role ; * p ; ) {
* dpb + + = * p + + ;
1999-04-22 10:48:28 +08:00
}
}
2000-03-13 03:44:23 +08:00
# endif
1999-04-22 10:48:28 +08:00
2000-03-13 03:44:23 +08:00
dpb_length = dpb - dpb_buffer ;
1999-04-22 10:48:28 +08:00
2000-07-18 04:51:47 +08:00
if ( isc_attach_database ( IB_STATUS , ( short ) strlen ( server ) , server , db , ( short ) dpb_length , dpb_buffer ) ) {
2002-07-19 17:21:29 +08:00
_php_ibase_error ( TSRMLS_C ) ;
2000-03-13 03:44:23 +08:00
return FAILURE ;
1999-04-22 10:48:28 +08:00
}
2000-03-13 03:44:23 +08:00
return SUCCESS ;
1999-04-22 10:48:28 +08:00
}
/* }}} */
2000-03-13 03:44:23 +08:00
/* {{{ _php_ibase_connect() */
static void _php_ibase_connect ( INTERNAL_FUNCTION_PARAMETERS , int persistent )
{
2003-03-16 13:00:50 +08:00
zval * * * args ;
2000-04-30 13:46:04 +08:00
char * ib_server = NULL , * ib_uname , * ib_passwd , * ib_charset = NULL , * ib_buffers = NULL , * ib_dialect = NULL , * ib_role = NULL ;
2003-08-05 21:17:16 +08:00
int ib_uname_len , ib_passwd_len ;
1999-04-22 10:48:28 +08:00
isc_db_handle db_handle = NULL ;
char * hashed_details ;
2000-03-13 03:44:23 +08:00
int hashed_details_length = 0 ;
2000-05-15 05:55:45 +08:00
ibase_db_link * ib_link = NULL ;
2000-03-13 03:44:23 +08:00
RESET_ERRMSG ;
ib_uname = IBG ( default_user ) ;
ib_passwd = IBG ( default_password ) ;
1999-04-22 10:48:28 +08:00
ib_uname_len = ib_uname ? strlen ( ib_uname ) : 0 ;
ib_passwd_len = ib_passwd ? strlen ( ib_passwd ) : 0 ;
2000-03-13 03:44:23 +08:00
2003-03-16 13:00:50 +08:00
if ( ZEND_NUM_ARGS ( ) < 1 | | ZEND_NUM_ARGS ( ) > 7 ) {
1999-04-22 10:48:28 +08:00
WRONG_PARAM_COUNT ;
2000-03-13 03:44:23 +08:00
}
2003-08-12 10:11:41 +08:00
args = ( zval * * * ) safe_emalloc ( sizeof ( zval * * ) , ZEND_NUM_ARGS ( ) , 0 ) ;
2000-06-06 03:47:54 +08:00
if ( zend_get_parameters_array_ex ( ZEND_NUM_ARGS ( ) , args ) = = FAILURE ) {
2000-03-13 03:44:23 +08:00
efree ( args ) ;
RETURN_FALSE ;
1999-04-22 10:48:28 +08:00
}
2003-03-16 13:00:50 +08:00
switch ( ZEND_NUM_ARGS ( ) ) {
2000-04-30 13:46:04 +08:00
case 7 :
convert_to_string_ex ( args [ 6 ] ) ;
2001-09-26 06:49:04 +08:00
ib_role = Z_STRVAL_PP ( args [ 6 ] ) ;
hashed_details_length + = Z_STRLEN_PP ( args [ 6 ] ) ;
2000-04-30 13:46:04 +08:00
/* fallout */
case 6 :
convert_to_string_ex ( args [ 5 ] ) ;
2001-09-26 06:49:04 +08:00
ib_dialect = Z_STRVAL_PP ( args [ 5 ] ) ;
hashed_details_length + = Z_STRLEN_PP ( args [ 5 ] ) ;
2000-04-30 13:46:04 +08:00
/* fallout */
2000-04-18 10:52:45 +08:00
case 5 :
2000-04-30 13:46:04 +08:00
convert_to_string_ex ( args [ 4 ] ) ;
2001-09-26 06:49:04 +08:00
ib_buffers = Z_STRVAL_PP ( args [ 4 ] ) ;
hashed_details_length + = Z_STRLEN_PP ( args [ 4 ] ) ;
2000-04-18 10:52:45 +08:00
/* fallout */
2000-03-13 03:44:23 +08:00
case 4 :
2000-04-30 13:46:04 +08:00
convert_to_string_ex ( args [ 3 ] ) ;
2001-09-26 06:49:04 +08:00
ib_charset = Z_STRVAL_PP ( args [ 3 ] ) ;
hashed_details_length + = Z_STRLEN_PP ( args [ 3 ] ) ;
2000-03-13 03:44:23 +08:00
/* fallout */
case 3 :
2000-04-30 13:46:04 +08:00
convert_to_string_ex ( args [ 2 ] ) ;
2001-09-26 06:49:04 +08:00
ib_passwd = Z_STRVAL_PP ( args [ 2 ] ) ;
hashed_details_length + = Z_STRLEN_PP ( args [ 2 ] ) ;
2000-03-13 03:44:23 +08:00
/* fallout */
case 2 :
2000-04-30 13:46:04 +08:00
convert_to_string_ex ( args [ 1 ] ) ;
2001-09-26 06:49:04 +08:00
ib_uname = Z_STRVAL_PP ( args [ 1 ] ) ;
hashed_details_length + = Z_STRLEN_PP ( args [ 1 ] ) ;
2000-03-13 03:44:23 +08:00
/* fallout */
case 1 :
2000-04-30 13:46:04 +08:00
convert_to_string_ex ( args [ 0 ] ) ;
2001-09-26 06:49:04 +08:00
ib_server = Z_STRVAL_PP ( args [ 0 ] ) ;
hashed_details_length + = Z_STRLEN_PP ( args [ 0 ] ) ;
2000-04-18 10:52:45 +08:00
} /* case */
2000-03-13 03:44:23 +08:00
efree ( args ) ;
2003-03-16 13:00:50 +08:00
hashed_details = ( char * ) emalloc ( hashed_details_length + strlen ( " ibase_%s_%s_%s_%s_%s_%s_%s " ) + 1 ) ;
2000-04-30 13:46:04 +08:00
sprintf ( hashed_details , " ibase_%s_%s_%s_%s_%s_%s_%s " , SAFE_STRING ( ib_server ) , SAFE_STRING ( ib_uname ) , SAFE_STRING ( ib_passwd ) , SAFE_STRING ( ib_charset ) , SAFE_STRING ( ib_buffers ) , SAFE_STRING ( ib_dialect ) , SAFE_STRING ( ib_role ) ) ;
2000-03-13 03:44:23 +08:00
1999-04-22 10:48:28 +08:00
if ( persistent ) {
list_entry * le ;
2000-05-04 20:28:00 +08:00
int open_new_connection = 1 ;
1999-04-22 10:48:28 +08:00
2003-03-16 13:00:50 +08:00
if ( zend_hash_find ( & EG ( persistent_list ) , hashed_details , hashed_details_length + 1 , ( void * * ) & le ) ! = FAILURE ) {
2000-05-04 20:28:00 +08:00
char tmp_1 [ ] = { isc_info_base_level , isc_info_end } ;
char tmp_2 [ 8 ] ; /* Enough? Hope so... */
2001-09-26 05:58:48 +08:00
if ( Z_TYPE_P ( le ) ! = le_plink ) {
2000-05-04 20:28:00 +08:00
RETURN_FALSE ;
}
/* Check if connection has timed out */
ib_link = ( ibase_db_link * ) le - > ptr ;
2003-08-13 02:01:59 +08:00
if ( ! isc_database_info ( IB_STATUS , & ib_link - > handle , sizeof ( tmp_1 ) , tmp_1 , sizeof ( tmp_2 ) , tmp_2 ) ) {
2000-05-04 20:28:00 +08:00
open_new_connection = 0 ;
}
}
/* There was no previous connection to use or it has timed out */
if ( open_new_connection ) {
1999-04-22 10:48:28 +08:00
list_entry new_le ;
2000-04-30 13:46:04 +08:00
if ( ( IBG ( max_links ) ! = - 1 ) & & ( IBG ( num_links ) > = IBG ( max_links ) ) ) {
2000-03-13 03:44:23 +08:00
_php_ibase_module_error ( " Too many open links (%d) " , IBG ( num_links ) ) ;
1999-04-22 10:48:28 +08:00
efree ( hashed_details ) ;
RETURN_FALSE ;
}
2000-04-30 13:46:04 +08:00
if ( ( IBG ( max_persistent ) ! = - 1 ) & & ( IBG ( num_persistent ) > = IBG ( max_persistent ) ) ) {
2000-03-13 03:44:23 +08:00
_php_ibase_module_error ( " Too many open persistent links (%d) " , IBG ( num_persistent ) ) ;
1999-04-22 10:48:28 +08:00
efree ( hashed_details ) ;
RETURN_FALSE ;
}
2000-03-13 03:44:23 +08:00
/* create the ib_link */
1999-04-22 10:48:28 +08:00
2000-04-30 13:46:04 +08:00
if ( _php_ibase_attach_db ( ib_server , ib_uname , ib_passwd , ib_charset ,
( ib_buffers ? strtoul ( ib_buffers , NULL , 0 ) : 0 ) ,
2003-03-16 13:00:50 +08:00
ib_role , & db_handle TSRMLS_CC ) = = FAILURE ) {
1999-04-22 10:48:28 +08:00
efree ( hashed_details ) ;
RETURN_FALSE ;
}
2000-03-13 03:44:23 +08:00
ib_link = ( ibase_db_link * ) malloc ( sizeof ( ibase_db_link ) ) ;
2003-08-13 02:01:59 +08:00
ib_link - > handle = db_handle ;
2000-07-18 04:51:47 +08:00
ib_link - > dialect = ( ib_dialect ? ( unsigned short ) strtoul ( ib_dialect , NULL , 10 ) : SQL_DIALECT_CURRENT ) ;
2003-08-08 19:04:12 +08:00
ib_link - > tr_list = NULL ;
2003-03-16 13:00:50 +08:00
1999-04-22 10:48:28 +08:00
/* hash it up */
2001-09-26 05:58:48 +08:00
Z_TYPE ( new_le ) = le_plink ;
2000-03-13 03:44:23 +08:00
new_le . ptr = ib_link ;
2003-03-16 13:00:50 +08:00
if ( zend_hash_update ( & EG ( persistent_list ) , hashed_details , hashed_details_length + 1 , ( void * ) & new_le , sizeof ( list_entry ) , NULL ) = = FAILURE ) {
1999-04-22 10:48:28 +08:00
efree ( hashed_details ) ;
2000-03-13 03:44:23 +08:00
free ( ib_link ) ;
1999-04-22 10:48:28 +08:00
RETURN_FALSE ;
}
2000-03-13 03:44:23 +08:00
IBG ( num_links ) + + ;
IBG ( num_persistent ) + + ;
1999-04-22 10:48:28 +08:00
}
2000-07-07 20:06:05 +08:00
2000-10-05 20:47:39 +08:00
ZEND_REGISTER_RESOURCE ( return_value , ib_link , le_plink ) ;
2000-07-07 20:06:05 +08:00
1999-04-22 10:48:28 +08:00
} else {
list_entry * index_ptr , new_index_ptr ;
2000-03-13 03:44:23 +08:00
/* first we check the hash for the hashed_details key. if it exists,
* it should point us to the right offset where the actual ib_link sits .
* if it doesn ' t , open a new ib_link , add it to the resource list ,
1999-04-22 10:48:28 +08:00
* and add a pointer to it with hashed_details as the key .
*/
2003-03-16 13:00:50 +08:00
if ( zend_hash_find ( & EG ( regular_list ) , hashed_details , hashed_details_length + 1 , ( void * * ) & index_ptr ) = = SUCCESS ) {
2001-08-12 00:39:07 +08:00
int type , xlink ;
1999-04-22 10:48:28 +08:00
void * ptr ;
2001-09-26 05:58:48 +08:00
if ( Z_TYPE_P ( index_ptr ) ! = le_index_ptr ) {
1999-04-22 10:48:28 +08:00
RETURN_FALSE ;
}
2000-03-13 03:44:23 +08:00
xlink = ( int ) index_ptr - > ptr ;
ptr = zend_list_find ( xlink , & type ) ; /* check if the xlink is still there */
2003-08-06 23:27:16 +08:00
if ( ptr & & ( type = = le_link | | type = = le_plink ) ) {
2000-04-18 10:52:45 +08:00
zend_list_addref ( xlink ) ;
2001-09-26 05:58:48 +08:00
Z_LVAL_P ( return_value ) = xlink ;
Z_TYPE_P ( return_value ) = IS_RESOURCE ;
IBG ( default_link ) = Z_LVAL_P ( return_value ) ;
1999-04-22 10:48:28 +08:00
efree ( hashed_details ) ;
return ;
} else {
2003-03-16 13:00:50 +08:00
zend_hash_del ( & EG ( regular_list ) , hashed_details , hashed_details_length + 1 ) ;
1999-04-22 10:48:28 +08:00
}
}
2000-04-30 13:46:04 +08:00
if ( ( IBG ( max_links ) ! = - 1 ) & & ( IBG ( num_links ) > = IBG ( max_links ) ) ) {
2000-03-13 03:44:23 +08:00
_php_ibase_module_error ( " Too many open links (%d) " , IBG ( num_links ) ) ;
1999-04-22 10:48:28 +08:00
efree ( hashed_details ) ;
RETURN_FALSE ;
}
2000-03-13 03:44:23 +08:00
/* create the ib_link */
1999-04-22 10:48:28 +08:00
2000-04-30 13:46:04 +08:00
if ( _php_ibase_attach_db ( ib_server , ib_uname , ib_passwd , ib_charset ,
( ib_buffers ? strtoul ( ib_buffers , NULL , 0 ) : 0 ) ,
2003-03-16 13:00:50 +08:00
ib_role , & db_handle TSRMLS_CC ) = = FAILURE ) {
1999-04-22 10:48:28 +08:00
efree ( hashed_details ) ;
RETURN_FALSE ;
}
2000-03-13 03:44:23 +08:00
ib_link = ( ibase_db_link * ) emalloc ( sizeof ( ibase_db_link ) ) ;
2003-08-13 02:01:59 +08:00
ib_link - > handle = db_handle ;
2000-07-18 04:51:47 +08:00
ib_link - > dialect = ( ib_dialect ? ( unsigned short ) strtoul ( ib_dialect , NULL , 10 ) : SQL_DIALECT_CURRENT ) ;
2003-08-08 19:04:12 +08:00
ib_link - > tr_list = NULL ;
2003-03-16 13:00:50 +08:00
2000-10-05 20:47:39 +08:00
ZEND_REGISTER_RESOURCE ( return_value , ib_link , le_link ) ;
2000-07-07 20:06:05 +08:00
1999-04-22 10:48:28 +08:00
/* add it to the hash */
2001-09-26 05:58:48 +08:00
new_index_ptr . ptr = ( void * ) Z_LVAL_P ( return_value ) ;
Z_TYPE ( new_index_ptr ) = le_index_ptr ;
2003-03-16 13:00:50 +08:00
if ( zend_hash_update ( & EG ( regular_list ) , hashed_details , hashed_details_length + 1 , ( void * ) & new_index_ptr , sizeof ( list_entry ) , NULL ) = = FAILURE ) {
1999-04-22 10:48:28 +08:00
efree ( hashed_details ) ;
RETURN_FALSE ;
}
2000-03-13 03:44:23 +08:00
IBG ( num_links ) + + ;
1999-04-22 10:48:28 +08:00
}
efree ( hashed_details ) ;
2001-09-26 05:58:48 +08:00
zend_list_addref ( Z_LVAL_P ( return_value ) ) ;
IBG ( default_link ) = Z_LVAL_P ( return_value ) ;
1999-04-22 10:48:28 +08:00
}
/* }}} */
2003-06-12 19:24:24 +08:00
/* {{{ proto resource ibase_connect(string database [, string username [, string password [, string charset [, int buffers [, int dialect [, string role]]]]]])
1999-04-22 10:48:28 +08:00
Open a connection to an InterBase database */
1999-05-21 18:06:25 +08:00
PHP_FUNCTION ( ibase_connect )
1999-04-22 10:48:28 +08:00
{
2000-03-13 03:44:23 +08:00
_php_ibase_connect ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 0 ) ;
1999-04-22 10:48:28 +08:00
}
/* }}} */
2003-06-12 19:24:24 +08:00
/* {{{ proto resource ibase_pconnect(string database [, string username [, string password [, string charset [, int buffers [, int dialect [, string role]]]]]])
1999-04-22 10:48:28 +08:00
Open a persistent connection to an InterBase database */
1999-05-21 18:06:25 +08:00
PHP_FUNCTION ( ibase_pconnect )
1999-04-22 10:48:28 +08:00
{
2000-03-13 03:44:23 +08:00
_php_ibase_connect ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 1 ) ;
1999-04-22 10:48:28 +08:00
}
/* }}} */
2003-06-12 19:24:24 +08:00
/* {{{ proto bool ibase_close([resource link_identifier])
1999-04-22 10:48:28 +08:00
Close an InterBase connection */
1999-05-21 18:06:25 +08:00
PHP_FUNCTION ( ibase_close )
1999-04-22 10:48:28 +08:00
{
2003-08-06 07:40:30 +08:00
zval * * link_arg = NULL ;
2000-03-13 03:44:23 +08:00
ibase_db_link * ib_link ;
2000-07-07 20:06:05 +08:00
int link_id ;
2000-03-13 03:44:23 +08:00
RESET_ERRMSG ;
1999-04-22 10:48:28 +08:00
2000-06-06 03:47:54 +08:00
switch ( ZEND_NUM_ARGS ( ) ) {
1999-04-22 10:48:28 +08:00
case 0 :
2000-03-13 03:44:23 +08:00
link_id = IBG ( default_link ) ;
2003-08-06 23:27:16 +08:00
IBG ( default_link ) = - 1 ;
1999-04-22 10:48:28 +08:00
break ;
case 1 :
2000-04-30 13:46:04 +08:00
if ( zend_get_parameters_ex ( 1 , & link_arg ) = = FAILURE ) {
1999-04-22 10:48:28 +08:00
RETURN_FALSE ;
}
2000-04-30 13:46:04 +08:00
convert_to_long_ex ( link_arg ) ;
2001-09-26 05:58:48 +08:00
link_id = Z_LVAL_PP ( link_arg ) ;
1999-04-22 10:48:28 +08:00
break ;
default :
WRONG_PARAM_COUNT ;
break ;
}
2000-04-18 10:52:45 +08:00
2000-10-05 20:47:39 +08:00
ZEND_FETCH_RESOURCE2 ( ib_link , ibase_db_link * , link_arg , link_id , " InterBase link " , le_link , le_plink ) ;
2000-03-13 03:44:23 +08:00
zend_list_delete ( link_id ) ;
1999-04-22 10:48:28 +08:00
RETURN_TRUE ;
}
/* }}} */
2003-08-05 21:17:16 +08:00
/* {{{ proto bool ibase_drop_db([resource link_identifier])
Drop an InterBase database */
PHP_FUNCTION ( ibase_drop_db )
{
2003-08-06 07:40:30 +08:00
zval * * link_arg = NULL ;
2003-08-05 21:17:16 +08:00
ibase_db_link * ib_link ;
2003-08-06 23:27:16 +08:00
ibase_tr_list * l ;
2003-08-05 21:17:16 +08:00
int link_id ;
RESET_ERRMSG ;
switch ( ZEND_NUM_ARGS ( ) ) {
case 0 :
link_id = IBG ( default_link ) ;
2003-08-06 23:27:16 +08:00
IBG ( default_link ) = - 1 ;
2003-08-05 21:17:16 +08:00
break ;
case 1 :
if ( zend_get_parameters_ex ( 1 , & link_arg ) = = FAILURE ) {
RETURN_FALSE ;
}
convert_to_long_ex ( link_arg ) ;
link_id = Z_LVAL_PP ( link_arg ) ;
break ;
default :
WRONG_PARAM_COUNT ;
break ;
}
2003-08-06 23:27:16 +08:00
2003-08-05 21:17:16 +08:00
ZEND_FETCH_RESOURCE2 ( ib_link , ibase_db_link * , link_arg , link_id , " InterBase link " , le_link , le_plink ) ;
2003-08-13 02:01:59 +08:00
if ( isc_drop_database ( IB_STATUS , & ib_link - > handle ) ) {
2003-08-05 21:17:16 +08:00
_php_ibase_error ( TSRMLS_C ) ;
RETURN_FALSE ;
}
2003-08-06 23:27:16 +08:00
/* isc_drop_database() doesn't invalidate the transaction handles */
2003-08-08 19:04:12 +08:00
for ( l = ib_link - > tr_list ; l ! = NULL ; l = l - > next ) {
2003-08-06 23:27:16 +08:00
if ( l - > trans ! = NULL ) l - > trans - > handle = NULL ;
}
2003-08-05 21:17:16 +08:00
zend_list_delete ( link_id ) ;
RETURN_TRUE ;
}
/* }}} */
2000-03-13 03:44:23 +08:00
/* {{{ _php_ibase_alloc_array() */
2003-03-16 13:00:50 +08:00
static int _php_ibase_alloc_array ( ibase_array * * ib_arrayp , int * array_cntp , XSQLDA * sqlda , isc_db_handle link , isc_tr_handle trans TSRMLS_DC )
1999-04-22 10:48:28 +08:00
{
2000-03-13 03:44:23 +08:00
# define IB_ARRAY (*ib_arrayp)
2003-03-16 13:00:50 +08:00
2000-03-13 03:44:23 +08:00
int i , dim , ar_cnt , ar_length ;
XSQLVAR * var ;
1999-04-22 10:48:28 +08:00
2000-03-13 03:44:23 +08:00
IB_ARRAY = NULL ;
1999-04-22 10:48:28 +08:00
2000-03-13 03:44:23 +08:00
ar_cnt = 0 ; /* find arrays */
var = sqlda - > sqlvar ;
2000-04-18 10:52:45 +08:00
for ( i = 0 ; i < sqlda - > sqld ; i + + , var + + ) {
2003-03-16 13:00:50 +08:00
if ( ( var - > sqltype & ~ 1 ) = = SQL_ARRAY ) {
2000-03-13 03:44:23 +08:00
ar_cnt + + ;
2003-03-16 13:00:50 +08:00
}
2000-03-13 03:44:23 +08:00
}
1999-04-22 10:48:28 +08:00
2000-04-18 10:52:45 +08:00
if ( ar_cnt ) { /* have arrays ? */
2000-03-13 03:44:23 +08:00
* array_cntp = ar_cnt ;
2003-08-12 08:58:52 +08:00
IB_ARRAY = safe_emalloc ( sizeof ( ibase_array ) , ar_cnt , 0 ) ;
2000-03-13 03:44:23 +08:00
ar_cnt = 0 ;
var = sqlda - > sqlvar ;
2000-04-18 10:52:45 +08:00
for ( i = 0 ; i < sqlda - > sqld ; i + + , var + + ) {
if ( ( var - > sqltype & ~ 1 ) = = SQL_ARRAY ) {
2003-03-16 13:00:50 +08:00
2000-03-13 03:44:23 +08:00
ISC_ARRAY_DESC * ar_desc = & IB_ARRAY [ ar_cnt ] . ar_desc ;
2003-03-16 13:00:50 +08:00
if ( isc_array_lookup_bounds ( IB_STATUS , & link , & trans , var - > relname , var - > sqlname , ar_desc ) ) {
2002-07-19 17:21:29 +08:00
_php_ibase_error ( TSRMLS_C ) ;
2000-03-13 03:44:23 +08:00
efree ( IB_ARRAY ) ;
IB_ARRAY = NULL ;
return FAILURE ;
}
1999-04-22 10:48:28 +08:00
2000-03-13 03:44:23 +08:00
switch ( ar_desc - > array_desc_dtype ) {
case blr_text :
case blr_text2 :
IB_ARRAY [ ar_cnt ] . el_type = SQL_TEXT ;
2003-03-16 13:00:50 +08:00
IB_ARRAY [ ar_cnt ] . el_size = ar_desc - > array_desc_length + 1 ;
2000-03-13 03:44:23 +08:00
break ;
case blr_short :
IB_ARRAY [ ar_cnt ] . el_type = SQL_SHORT ;
IB_ARRAY [ ar_cnt ] . el_size = sizeof ( short ) ;
break ;
case blr_long :
IB_ARRAY [ ar_cnt ] . el_type = SQL_LONG ;
IB_ARRAY [ ar_cnt ] . el_size = sizeof ( long ) ;
break ;
case blr_float :
IB_ARRAY [ ar_cnt ] . el_type = SQL_FLOAT ;
IB_ARRAY [ ar_cnt ] . el_size = sizeof ( float ) ;
break ;
case blr_double :
IB_ARRAY [ ar_cnt ] . el_type = SQL_DOUBLE ;
IB_ARRAY [ ar_cnt ] . el_size = sizeof ( double ) ;
break ;
case blr_date :
IB_ARRAY [ ar_cnt ] . el_type = SQL_DATE ;
IB_ARRAY [ ar_cnt ] . el_size = sizeof ( ISC_QUAD ) ;
break ;
case blr_varying :
case blr_varying2 : /* changed to SQL_TEXT ? */
/* sql_type = SQL_VARYING; Why? FIXME: ??? */
IB_ARRAY [ ar_cnt ] . el_type = SQL_TEXT ;
2003-03-16 13:00:50 +08:00
IB_ARRAY [ ar_cnt ] . el_size = ar_desc - > array_desc_length + sizeof ( short ) ;
2000-03-13 03:44:23 +08:00
break ;
default :
2003-03-16 13:00:50 +08:00
_php_ibase_module_error ( " Unexpected array type %d in relation '%s' column '%s' " , ar_desc - > array_desc_dtype , var - > relname , var - > sqlname ) ;
2000-03-13 03:44:23 +08:00
efree ( IB_ARRAY ) ;
IB_ARRAY = NULL ;
return FAILURE ;
2000-04-18 10:52:45 +08:00
} /* switch array_desc_type */
2000-03-13 03:44:23 +08:00
ar_length = 0 ; /* calculate elements count */
for ( dim = 0 ; dim < ar_desc - > array_desc_dimensions ; dim + + ) {
2003-03-16 13:00:50 +08:00
ar_length + = 1 + ar_desc - > array_desc_bounds [ dim ] . array_bound_upper - ar_desc - > array_desc_bounds [ dim ] . array_bound_lower ;
2000-03-13 03:44:23 +08:00
}
IB_ARRAY [ ar_cnt ] . ar_size = IB_ARRAY [ ar_cnt ] . el_size * ar_length ;
ar_cnt + + ;
2000-04-18 10:52:45 +08:00
} /* if SQL_ARRAY */
} /* for column */
} /* if array_cnt */
1999-04-22 10:48:28 +08:00
2000-03-13 03:44:23 +08:00
return SUCCESS ;
# undef IB_ARRAY
1999-04-22 10:48:28 +08:00
}
/* }}} */
2000-03-13 03:44:23 +08:00
/* {{{ _php_ibase_alloc_query() */
/* allocate and prepare query */
2003-08-13 02:01:59 +08:00
static int _php_ibase_alloc_query ( ibase_query * * ib_queryp , ibase_db_link * link , ibase_trans * trans , char * query , unsigned short dialect , int trans_res_id TSRMLS_DC )
2000-03-13 03:44:23 +08:00
{
# define IB_QUERY (*ib_queryp)
2003-08-13 02:01:59 +08:00
char info_type [ ] = { isc_info_sql_stmt_type } , result [ 8 ] ;
1999-04-22 10:48:28 +08:00
2000-03-13 03:44:23 +08:00
IB_QUERY = emalloc ( sizeof ( ibase_query ) ) ;
IB_QUERY - > link = link ;
IB_QUERY - > trans = trans ;
IB_QUERY - > stmt = NULL ;
IB_QUERY - > out_sqlda = NULL ;
IB_QUERY - > in_sqlda = NULL ;
IB_QUERY - > in_array = NULL ;
IB_QUERY - > in_array_cnt = 0 ;
IB_QUERY - > out_array = NULL ;
IB_QUERY - > out_array_cnt = 0 ;
2000-05-10 04:30:23 +08:00
IB_QUERY - > dialect = dialect ;
2003-08-13 02:01:59 +08:00
IB_QUERY - > statement_type = ' \0 ' ;
IB_QUERY - > query = estrdup ( query ) ;
IB_QUERY - > trans_res_id = trans_res_id ;
2000-03-13 03:44:23 +08:00
2003-08-13 02:01:59 +08:00
if ( isc_dsql_allocate_statement ( IB_STATUS , & link - > handle , & IB_QUERY - > stmt ) ) {
2002-07-19 17:21:29 +08:00
_php_ibase_error ( TSRMLS_C ) ;
2000-03-13 03:44:23 +08:00
goto _php_ibase_alloc_query_error ;
1999-04-22 10:48:28 +08:00
}
2003-08-06 20:09:30 +08:00
IB_QUERY - > out_sqlda = ( XSQLDA * ) emalloc ( XSQLDA_LENGTH ( 1 ) ) ;
IB_QUERY - > out_sqlda - > sqln = 1 ;
2003-08-12 21:19:36 +08:00
IB_QUERY - > out_sqlda - > version = SQLDA_CURRENT_VERSION ;
1999-04-22 10:48:28 +08:00
2003-08-13 02:01:59 +08:00
if ( isc_dsql_prepare ( IB_STATUS , & IB_QUERY - > trans - > handle , & IB_QUERY - > stmt , 0 , query , dialect , IB_QUERY - > out_sqlda ) ) {
_php_ibase_error ( TSRMLS_C ) ;
goto _php_ibase_alloc_query_error ;
}
/* find out what kind of statement was prepared */
if ( isc_dsql_sql_info ( IB_STATUS , & IB_QUERY - > stmt , sizeof ( info_type ) , info_type , sizeof ( result ) , result ) ) {
2002-07-19 17:21:29 +08:00
_php_ibase_error ( TSRMLS_C ) ;
2000-03-13 03:44:23 +08:00
goto _php_ibase_alloc_query_error ;
}
2003-08-13 02:01:59 +08:00
IB_QUERY - > statement_type = result [ 3 ] ;
2000-03-13 03:44:23 +08:00
/* not enough output variables ? */
if ( IB_QUERY - > out_sqlda - > sqld > IB_QUERY - > out_sqlda - > sqln ) {
2001-08-12 00:39:07 +08:00
IB_QUERY - > out_sqlda = erealloc ( IB_QUERY - > out_sqlda , XSQLDA_LENGTH ( IB_QUERY - > out_sqlda - > sqld ) ) ;
2000-03-13 03:44:23 +08:00
IB_QUERY - > out_sqlda - > sqln = IB_QUERY - > out_sqlda - > sqld ;
2003-08-12 21:19:36 +08:00
IB_QUERY - > out_sqlda - > version = SQLDA_CURRENT_VERSION ;
if ( isc_dsql_describe ( IB_STATUS , & IB_QUERY - > stmt , SQLDA_CURRENT_VERSION , IB_QUERY - > out_sqlda ) ) {
2002-07-19 17:21:29 +08:00
_php_ibase_error ( TSRMLS_C ) ;
2000-03-13 03:44:23 +08:00
goto _php_ibase_alloc_query_error ;
1999-04-22 10:48:28 +08:00
}
2000-03-13 03:44:23 +08:00
}
1999-04-22 10:48:28 +08:00
2000-03-13 03:44:23 +08:00
/* maybe have input placeholders? */
2003-08-06 20:09:30 +08:00
IB_QUERY - > in_sqlda = emalloc ( XSQLDA_LENGTH ( 1 ) ) ;
IB_QUERY - > in_sqlda - > sqln = 1 ;
2003-08-12 21:19:36 +08:00
IB_QUERY - > in_sqlda - > version = SQLDA_CURRENT_VERSION ;
if ( isc_dsql_describe_bind ( IB_STATUS , & IB_QUERY - > stmt , SQLDA_CURRENT_VERSION , IB_QUERY - > in_sqlda ) ) {
2002-07-19 17:21:29 +08:00
_php_ibase_error ( TSRMLS_C ) ;
2000-03-13 03:44:23 +08:00
goto _php_ibase_alloc_query_error ;
}
/* not enough input variables ? */
if ( IB_QUERY - > in_sqlda - > sqln < IB_QUERY - > in_sqlda - > sqld ) {
2001-08-12 00:39:07 +08:00
IB_QUERY - > in_sqlda = erealloc ( IB_QUERY - > in_sqlda , XSQLDA_LENGTH ( IB_QUERY - > in_sqlda - > sqld ) ) ;
2000-03-13 03:44:23 +08:00
IB_QUERY - > in_sqlda - > sqln = IB_QUERY - > in_sqlda - > sqld ;
2003-08-12 21:19:36 +08:00
IB_QUERY - > in_sqlda - > version = SQLDA_CURRENT_VERSION ;
if ( isc_dsql_describe_bind ( IB_STATUS , & IB_QUERY - > stmt , SQLDA_CURRENT_VERSION , IB_QUERY - > in_sqlda ) ) {
2002-07-19 17:21:29 +08:00
_php_ibase_error ( TSRMLS_C ) ;
2000-03-13 03:44:23 +08:00
goto _php_ibase_alloc_query_error ;
1999-04-22 10:48:28 +08:00
}
2000-03-13 03:44:23 +08:00
}
1999-04-22 10:48:28 +08:00
2000-03-13 03:44:23 +08:00
/* allocate arrays... */
2003-03-16 13:00:50 +08:00
if ( _php_ibase_alloc_array ( & IB_QUERY - > in_array , & IB_QUERY - > in_array_cnt , IB_QUERY - > in_sqlda , link , trans TSRMLS_CC ) = = FAILURE ) {
2000-03-13 03:44:23 +08:00
goto _php_ibase_alloc_query_error ; /* error report already done */
}
1999-04-22 10:48:28 +08:00
2003-03-16 13:00:50 +08:00
if ( _php_ibase_alloc_array ( & IB_QUERY - > out_array , & IB_QUERY - > out_array_cnt , IB_QUERY - > out_sqlda , link , trans TSRMLS_CC ) = = FAILURE ) {
2000-03-13 03:44:23 +08:00
goto _php_ibase_alloc_query_error ;
}
/* no, haven't placeholders at all */
2000-04-18 10:52:45 +08:00
if ( IB_QUERY - > in_sqlda - > sqld = = 0 ) {
2000-03-13 03:44:23 +08:00
efree ( IB_QUERY - > in_sqlda ) ;
IB_QUERY - > in_sqlda = NULL ;
1999-04-22 10:48:28 +08:00
}
2000-04-18 10:52:45 +08:00
if ( IB_QUERY - > out_sqlda - > sqld = = 0 ) {
2000-03-13 03:44:23 +08:00
efree ( IB_QUERY - > out_sqlda ) ;
IB_QUERY - > out_sqlda = NULL ;
}
return SUCCESS ;
_php_ibase_alloc_query_error :
2003-03-16 13:00:50 +08:00
if ( IB_QUERY - > out_sqlda ) {
2000-03-13 03:44:23 +08:00
efree ( IB_QUERY - > out_sqlda ) ;
2003-03-16 13:00:50 +08:00
}
if ( IB_QUERY - > in_sqlda ) {
2000-03-13 03:44:23 +08:00
efree ( IB_QUERY - > in_sqlda ) ;
2003-03-16 13:00:50 +08:00
}
if ( IB_QUERY - > out_array ) {
2000-03-13 03:44:23 +08:00
efree ( IB_QUERY - > out_array ) ;
2003-03-16 13:00:50 +08:00
}
2003-08-13 02:01:59 +08:00
if ( IB_QUERY - > query ) {
efree ( IB_QUERY - > query ) ;
}
2000-03-13 03:44:23 +08:00
efree ( IB_QUERY ) ;
IB_QUERY = NULL ;
return FAILURE ;
# undef IB_QUERY
1999-04-22 10:48:28 +08:00
}
/* }}} */
2000-05-10 04:30:23 +08:00
/* {{{ _php_ibase_bind()
2000-03-13 03:44:23 +08:00
Bind parameter placeholders in a previously prepared query */
2003-03-16 13:00:50 +08:00
static int _php_ibase_bind ( XSQLDA * sqlda , zval * * b_vars , BIND_BUF * buf , ibase_query * ib_query TSRMLS_DC )
1999-04-22 10:48:28 +08:00
{
2000-03-13 03:44:23 +08:00
XSQLVAR * var ;
2003-03-16 13:00:50 +08:00
zval * b_var ;
2000-03-13 03:44:23 +08:00
int i ;
1999-04-22 10:48:28 +08:00
2000-03-13 03:44:23 +08:00
var = sqlda - > sqlvar ;
2003-08-13 02:01:59 +08:00
for ( i = 0 ; i < sqlda - > sqld ; var + + , i + + ) { /* bound vars */
2000-03-13 03:44:23 +08:00
buf [ i ] . sqlind = 0 ;
2003-03-16 13:00:50 +08:00
var - > sqlind = & buf [ i ] . sqlind ;
2000-03-13 03:44:23 +08:00
b_var = b_vars [ i ] ;
2001-09-26 05:58:48 +08:00
if ( Z_TYPE_P ( b_var ) = = IS_NULL ) {
2001-09-05 05:47:05 +08:00
static char nothing [ 64 ] ;
static short null_flag = - 1 ;
var - > sqldata = nothing ;
var - > sqltype | = 1 ;
var - > sqlind = & null_flag ;
2003-03-16 13:00:50 +08:00
if ( var - > sqllen > 64 ) {
2001-09-05 05:47:05 +08:00
var - > sqllen = 64 ;
2003-03-16 13:00:50 +08:00
}
2001-09-05 05:47:05 +08:00
} else
2003-03-16 13:00:50 +08:00
switch ( var - > sqltype & ~ 1 ) {
2000-03-13 03:44:23 +08:00
case SQL_TEXT : /* direct to variable */
case SQL_VARYING :
convert_to_string ( b_var ) ;
2003-03-16 13:00:50 +08:00
var - > sqldata = ( void ISC_FAR * ) Z_STRVAL_P ( b_var ) ;
2001-09-26 05:58:48 +08:00
var - > sqllen = Z_STRLEN_P ( b_var ) ;
2000-03-13 03:44:23 +08:00
var - > sqltype = SQL_TEXT + ( var - > sqltype & 1 ) ;
break ;
case SQL_SHORT :
convert_to_long ( b_var ) ;
2001-09-26 05:58:48 +08:00
if ( Z_LVAL_P ( b_var ) > SHRT_MAX | | Z_LVAL_P ( b_var ) < SHRT_MIN ) {
2002-07-19 17:21:29 +08:00
_php_ibase_module_error ( " Field %*s overflow " , var - > aliasname_length , var - > aliasname ) ;
2000-03-13 03:44:23 +08:00
return FAILURE ;
}
2003-03-16 13:00:50 +08:00
buf [ i ] . val . sval = ( short ) Z_LVAL_P ( b_var ) ;
var - > sqldata = ( void ISC_FAR * ) ( & buf [ i ] . val . sval ) ;
2000-03-13 03:44:23 +08:00
break ;
2000-05-12 03:38:02 +08:00
case SQL_LONG :
if ( var - > sqlscale < 0 ) {
/*
DECIMAL or NUMERIC field stored internally as scaled integer .
Coerce it to string and let InterBase ' s internal routines
handle it .
*/
convert_to_string ( b_var ) ;
2003-03-16 13:00:50 +08:00
var - > sqldata = ( void ISC_FAR * ) Z_STRVAL_P ( b_var ) ;
2001-09-26 05:58:48 +08:00
var - > sqllen = Z_STRLEN_P ( b_var ) ;
2000-05-12 03:38:02 +08:00
var - > sqltype = SQL_TEXT ;
} else {
convert_to_long ( b_var ) ;
2003-03-16 13:00:50 +08:00
var - > sqldata = ( void ISC_FAR * ) ( & Z_LVAL_P ( b_var ) ) ;
2000-05-12 03:38:02 +08:00
}
2000-03-13 03:44:23 +08:00
break ;
case SQL_FLOAT :
convert_to_double ( b_var ) ;
2003-03-16 13:00:50 +08:00
buf [ i ] . val . fval = ( float ) Z_DVAL_P ( b_var ) ;
var - > sqldata = ( void ISC_FAR * ) ( & buf [ i ] . val . fval ) ;
2000-03-13 03:44:23 +08:00
break ;
case SQL_DOUBLE : /* direct to variable */
convert_to_double ( b_var ) ;
2003-03-16 13:00:50 +08:00
var - > sqldata = ( void ISC_FAR * ) ( & Z_DVAL_P ( b_var ) ) ;
2000-03-13 03:44:23 +08:00
break ;
2000-05-15 05:55:45 +08:00
# ifdef SQL_INT64
2000-05-10 04:30:23 +08:00
case SQL_INT64 :
2000-05-12 03:38:02 +08:00
/*
Just let InterBase ' s internal routines handle it .
Besides , it might even have originally been a string
to avoid rounding errors . . .
*/
convert_to_string ( b_var ) ;
2003-03-16 13:00:50 +08:00
var - > sqldata = ( void ISC_FAR * ) Z_STRVAL_P ( b_var ) ;
2001-09-26 05:58:48 +08:00
var - > sqllen = Z_STRLEN_P ( b_var ) ;
2000-05-12 03:38:02 +08:00
var - > sqltype = SQL_TEXT ;
break ;
2000-05-15 05:55:45 +08:00
# endif
2000-05-12 11:02:14 +08:00
# ifndef SQL_TIMESTAMP
case SQL_DATE :
# else
2000-05-10 04:30:23 +08:00
case SQL_TIMESTAMP :
case SQL_TYPE_DATE :
case SQL_TYPE_TIME :
2000-05-15 05:55:45 +08:00
# endif
2000-05-12 11:02:14 +08:00
# ifndef HAVE_STRPTIME
2000-05-15 05:55:45 +08:00
# ifndef SQL_TIMESTAMP
/* Parsing doesn't seem to happen with older versions... */
{
struct tm t ;
int n ;
2003-03-16 13:00:50 +08:00
t . tm_year = t . tm_mon = t . tm_mday = t . tm_hour = t . tm_min = t . tm_sec = 0 ;
2000-05-15 05:55:45 +08:00
convert_to_string ( b_var ) ;
2003-03-16 13:00:50 +08:00
n = sscanf ( Z_STRVAL_P ( b_var ) , " %d%*[/]%d%*[/]%d %d%*[:]%d%*[:]%d " , & t . tm_mon , & t . tm_mday , & t . tm_year , & t . tm_hour , & t . tm_min , & t . tm_sec ) ;
if ( n ! = 3 & & n ! = 6 ) {
2002-07-19 17:21:29 +08:00
_php_ibase_module_error ( " Invalid date/time format: Expected 3 or 6 fields, got %d. Use format m/d/Y H:i:s. You gave '%s' " , n , Z_STRVAL_P ( b_var ) ) ;
2000-05-15 05:55:45 +08:00
return FAILURE ;
}
t . tm_year - = 1900 ;
t . tm_mon - - ;
isc_encode_date ( & t , & buf [ i ] . val . qval ) ;
2003-03-16 13:00:50 +08:00
var - > sqldata = ( void ISC_FAR * ) ( & buf [ i ] . val . qval ) ;
2000-05-15 05:55:45 +08:00
}
# else
2000-05-12 11:02:14 +08:00
/*
Once again , InterBase ' s internal parsing routines
2000-07-07 20:06:05 +08:00
seems to be a good solution . . . Might change this on
2000-05-12 11:02:14 +08:00
platforms that have strptime ( ) ? Code is there and works ,
but the functions existence is not yet tested . . .
ask Sascha ?
2000-05-10 04:30:23 +08:00
*/
2000-05-12 11:02:14 +08:00
convert_to_string ( b_var ) ;
2003-03-16 13:00:50 +08:00
var - > sqldata = ( void ISC_FAR * ) Z_STRVAL_P ( b_var ) ;
2001-09-26 05:58:48 +08:00
var - > sqllen = Z_STRLEN_P ( b_var ) ;
2000-05-12 11:02:14 +08:00
var - > sqltype = SQL_TEXT ;
2000-05-15 05:55:45 +08:00
# endif
2000-05-12 11:02:14 +08:00
# else
2000-03-13 03:44:23 +08:00
{
struct tm t ;
2000-05-12 11:02:14 +08:00
2000-03-13 03:44:23 +08:00
convert_to_string ( b_var ) ;
2000-05-15 05:55:45 +08:00
# ifndef SQL_TIMESTAMP
2001-09-26 05:58:48 +08:00
strptime ( Z_STRVAL_P ( b_var ) , IBG ( timestampformat ) , & t ) ;
2000-05-15 05:55:45 +08:00
isc_encode_date ( & t , & buf [ i ] . val . qval ) ;
2003-03-16 13:00:50 +08:00
var - > sqldata = ( void ISC_FAR * ) ( & buf [ i ] . val . qval ) ;
2000-05-15 05:55:45 +08:00
# else
2000-05-12 11:02:14 +08:00
switch ( var - > sqltype & ~ 1 ) {
case SQL_TIMESTAMP :
2001-09-26 05:58:48 +08:00
strptime ( Z_STRVAL_P ( b_var ) , IBG ( timestampformat ) , & t ) ;
2000-05-12 11:02:14 +08:00
isc_encode_timestamp ( & t , & buf [ i ] . val . tsval ) ;
2003-03-16 13:00:50 +08:00
var - > sqldata = ( void ISC_FAR * ) ( & buf [ i ] . val . tsval ) ;
2000-05-12 11:02:14 +08:00
break ;
case SQL_TYPE_DATE :
2001-09-26 05:58:48 +08:00
strptime ( Z_STRVAL_P ( b_var ) , IBG ( dateformat ) , & t ) ;
2000-05-12 11:02:14 +08:00
isc_encode_sql_date ( & t , & buf [ i ] . val . dtval ) ;
2003-03-16 13:00:50 +08:00
var - > sqldata = ( void ISC_FAR * ) ( & buf [ i ] . val . dtval ) ;
2000-05-12 11:02:14 +08:00
break ;
case SQL_TYPE_TIME :
2001-09-26 05:58:48 +08:00
strptime ( Z_STRVAL_P ( b_var ) , IBG ( timeformat ) , & t ) ;
2000-05-12 11:02:14 +08:00
isc_encode_sql_time ( & t , & buf [ i ] . val . tmval ) ;
2003-03-16 13:00:50 +08:00
var - > sqldata = ( void ISC_FAR * ) ( & buf [ i ] . val . tmval ) ;
2000-05-12 11:02:14 +08:00
break ;
2000-03-13 03:44:23 +08:00
}
2000-05-15 05:55:45 +08:00
# endif
2000-03-13 03:44:23 +08:00
}
2000-05-12 11:02:14 +08:00
# endif
2000-03-13 03:44:23 +08:00
break ;
case SQL_BLOB :
{
ibase_blob_handle * ib_blob_id ;
2003-03-16 13:00:50 +08:00
if ( Z_TYPE_P ( b_var ) ! = IS_STRING | | Z_STRLEN_P ( b_var ) ! = sizeof ( ibase_blob_handle ) | |
( ( ibase_blob_handle * ) ( Z_STRVAL_P ( b_var ) ) ) - > bl_handle ! = 0 ) {
2001-09-05 05:47:05 +08:00
ibase_blob_handle * ib_blob ;
ib_blob = ( ibase_blob_handle * ) emalloc ( sizeof ( ibase_blob_handle ) ) ;
ib_blob - > trans_handle = ib_query - > trans ;
ib_blob - > link = ib_query - > link ;
ib_blob - > bl_handle = NULL ;
if ( isc_create_blob ( IB_STATUS , & ib_blob - > link , & ib_blob - > trans_handle , & ib_blob - > bl_handle , & ib_blob - > bl_qd ) ) {
efree ( ib_blob ) ;
2002-07-19 17:21:29 +08:00
_php_ibase_error ( TSRMLS_C ) ;
2001-09-05 05:47:05 +08:00
return FAILURE ;
}
convert_to_string ( b_var ) ;
2001-09-26 05:58:48 +08:00
if ( isc_put_segment ( IB_STATUS , & ib_blob - > bl_handle , ( unsigned short ) Z_STRLEN_P ( b_var ) , Z_STRVAL_P ( b_var ) ) ) {
2002-07-19 17:21:29 +08:00
_php_ibase_error ( TSRMLS_C ) ;
2001-09-05 05:47:05 +08:00
return FAILURE ;
}
if ( isc_close_blob ( IB_STATUS , & ib_blob - > bl_handle ) ) {
2002-07-19 17:21:29 +08:00
_php_ibase_error ( TSRMLS_C ) ;
2001-09-05 05:47:05 +08:00
return FAILURE ;
}
ib_blob_id = ib_blob ;
2003-03-16 13:00:50 +08:00
var - > sqldata = ( void ISC_FAR * ) & ib_blob_id - > bl_qd ;
2001-09-05 05:47:05 +08:00
/*
2002-07-19 17:21:29 +08:00
_php_ibase_module_error ( " Invalid blob id string " ) ;
2000-03-13 03:44:23 +08:00
return FAILURE ;
2001-09-05 05:47:05 +08:00
*/
} else {
2003-03-16 13:00:50 +08:00
ib_blob_id = ( ibase_blob_handle * ) Z_STRVAL_P ( b_var ) ;
2000-03-13 03:44:23 +08:00
2003-03-16 13:00:50 +08:00
var - > sqldata = ( void ISC_FAR * ) & ib_blob_id - > bl_qd ;
2001-09-05 05:47:05 +08:00
}
2000-03-13 03:44:23 +08:00
}
1999-04-22 10:48:28 +08:00
break ;
2000-03-13 03:44:23 +08:00
case SQL_ARRAY :
2002-07-19 17:21:29 +08:00
_php_ibase_module_error ( " Binding arrays not supported yet " ) ;
2000-03-13 03:44:23 +08:00
return FAILURE ;
break ;
2003-03-16 13:00:50 +08:00
} /* switch */
} /* for */
2000-03-13 03:44:23 +08:00
return SUCCESS ;
}
/* }}} */
/* {{{ _php_ibase_alloc_xsqlda() */
static void _php_ibase_alloc_xsqlda ( XSQLDA * sqlda )
{
int i ;
XSQLVAR * var = sqlda - > sqlvar ;
2003-03-16 13:00:50 +08:00
2000-03-13 03:44:23 +08:00
for ( i = 0 ; i < sqlda - > sqld ; i + + , var + + ) {
2003-03-16 13:00:50 +08:00
switch ( var - > sqltype & ~ 1 ) {
2000-03-13 03:44:23 +08:00
case SQL_TEXT :
2003-08-12 08:58:52 +08:00
var - > sqldata = safe_emalloc ( sizeof ( char ) , ( var - > sqllen ) , 0 ) ;
2000-03-13 03:44:23 +08:00
break ;
case SQL_VARYING :
2003-08-12 08:58:52 +08:00
var - > sqldata = safe_emalloc ( sizeof ( char ) , ( var - > sqllen + sizeof ( short ) ) , 0 ) ;
2000-03-13 03:44:23 +08:00
break ;
case SQL_SHORT :
var - > sqldata = emalloc ( sizeof ( short ) ) ;
break ;
case SQL_LONG :
var - > sqldata = emalloc ( sizeof ( long ) ) ;
break ;
case SQL_FLOAT :
var - > sqldata = emalloc ( sizeof ( float ) ) ;
break ;
case SQL_DOUBLE :
var - > sqldata = emalloc ( sizeof ( double ) ) ;
break ;
2000-05-10 04:30:23 +08:00
# ifdef SQL_INT64
case SQL_INT64 :
var - > sqldata = emalloc ( sizeof ( ISC_INT64 ) ) ;
break ;
# endif
# ifdef SQL_TIMESTAMP
case SQL_TIMESTAMP :
var - > sqldata = emalloc ( sizeof ( ISC_TIMESTAMP ) ) ;
break ;
case SQL_TYPE_DATE :
var - > sqldata = emalloc ( sizeof ( ISC_DATE ) ) ;
break ;
case SQL_TYPE_TIME :
var - > sqldata = emalloc ( sizeof ( ISC_TIME ) ) ;
break ;
# else
2000-03-13 03:44:23 +08:00
case SQL_DATE :
2000-05-10 04:30:23 +08:00
# endif
2000-03-13 03:44:23 +08:00
case SQL_BLOB :
case SQL_ARRAY :
var - > sqldata = emalloc ( sizeof ( ISC_QUAD ) ) ;
break ;
2003-03-16 13:00:50 +08:00
} /* switch */
if ( var - > sqltype & 1 ) { /* sql NULL flag */
2000-03-13 03:44:23 +08:00
var - > sqlind = emalloc ( sizeof ( short ) ) ;
2003-03-16 13:00:50 +08:00
} else {
2000-03-13 03:44:23 +08:00
var - > sqlind = NULL ;
2003-03-16 13:00:50 +08:00
}
} /* for */
2000-03-13 03:44:23 +08:00
}
/* }}} */
/* {{{ _php_ibase_exec() */
2003-08-13 02:01:59 +08:00
static int _php_ibase_exec ( INTERNAL_FUNCTION_PARAMETERS , ibase_result * * ib_resultp , ibase_query * ib_query , int argc , zval * * args )
2000-03-13 03:44:23 +08:00
{
# define IB_RESULT (*ib_resultp)
XSQLDA * in_sqlda = NULL , * out_sqlda = NULL ;
BIND_BUF * bind_buf = NULL ;
int rv = FAILURE ;
2003-08-13 02:01:59 +08:00
char info_count [ ] = { isc_info_sql_records } , result [ 64 ] ;
2003-08-13 10:19:14 +08:00
ISC_STATUS isc_result ;
2003-08-13 02:01:59 +08:00
RESET_ERRMSG ;
2003-07-10 08:17:09 +08:00
if ( argc > 0 & & args ! = NULL ) {
SEPARATE_ZVAL ( args ) ;
}
2000-03-13 03:44:23 +08:00
2003-08-13 02:01:59 +08:00
switch ( ib_query - > statement_type ) {
isc_tr_handle tr ;
ibase_tr_list * * l ;
ibase_trans * trans ;
case isc_info_sql_stmt_start_trans :
/* a SET TRANSACTION statement should be executed with a NULL trans handle */
tr = NULL ;
if ( isc_dsql_execute_immediate ( IB_STATUS , & ib_query - > link - > handle , & tr , 0 , ib_query - > query , ib_query - > dialect , NULL ) ) {
_php_ibase_error ( TSRMLS_C ) ;
goto _php_ibase_exec_error ;
}
trans = ( ibase_trans * ) emalloc ( sizeof ( ibase_trans ) ) ;
trans - > handle = tr ;
trans - > link_cnt = 1 ;
trans - > affected_rows = 0 ;
trans - > db_link [ 0 ] = ib_query - > link ;
if ( ib_query - > link - > tr_list = = NULL ) {
ib_query - > link - > tr_list = ( ibase_tr_list * ) emalloc ( sizeof ( ibase_tr_list ) ) ;
ib_query - > link - > tr_list - > trans = NULL ;
ib_query - > link - > tr_list - > next = NULL ;
}
/* link the transaction into the connection-transaction list */
for ( l = & ib_query - > link - > tr_list ; * l ! = NULL ; l = & ( * l ) - > next ) ;
* l = ( ibase_tr_list * ) emalloc ( sizeof ( ibase_tr_list ) ) ;
( * l ) - > trans = trans ;
( * l ) - > next = NULL ;
ZEND_REGISTER_RESOURCE ( return_value , trans , le_trans ) ;
return SUCCESS ;
case isc_info_sql_stmt_commit :
case isc_info_sql_stmt_rollback :
if ( isc_dsql_execute_immediate ( IB_STATUS , & ib_query - > link - > handle , & ib_query - > trans - > handle , 0 , ib_query - > query , ib_query - > dialect , NULL ) ) {
_php_ibase_error ( TSRMLS_C ) ;
goto _php_ibase_exec_error ;
}
if ( ib_query - > trans - > handle = = NULL & & ib_query - > trans_res_id ! = 0 ) {
/* transaction was released by the query and was a registered resource,
so we have to release it */
zend_list_delete ( ib_query - > trans_res_id ) ;
}
return SUCCESS ;
default :
Z_BVAL_P ( return_value ) = 1 ;
Z_TYPE_P ( return_value ) = IS_BOOL ;
}
2000-03-13 03:44:23 +08:00
/* allocate sqlda and output buffers */
if ( ib_query - > out_sqlda ) { /* output variables in select, select for update */
2000-07-09 18:27:41 +08:00
IBDEBUG ( " Query wants XSQLDA for output " ) ;
2000-03-13 03:44:23 +08:00
IB_RESULT = emalloc ( sizeof ( ibase_result ) ) ;
2003-08-13 02:01:59 +08:00
IB_RESULT - > link = ib_query - > link - > handle ;
IB_RESULT - > trans = ib_query - > trans - > handle ;
2000-03-13 03:44:23 +08:00
IB_RESULT - > stmt = ib_query - > stmt ;
2003-08-13 10:19:14 +08:00
IB_RESULT - > statement_type = ib_query - > statement_type ;
2000-03-13 03:44:23 +08:00
IB_RESULT - > drop_stmt = 0 ; /* when free result close but not drop!*/
2000-07-09 18:27:41 +08:00
2000-03-13 03:44:23 +08:00
out_sqlda = IB_RESULT - > out_sqlda = emalloc ( XSQLDA_LENGTH ( ib_query - > out_sqlda - > sqld ) ) ;
2001-08-12 00:39:07 +08:00
memcpy ( out_sqlda , ib_query - > out_sqlda , XSQLDA_LENGTH ( ib_query - > out_sqlda - > sqld ) ) ;
2000-03-13 03:44:23 +08:00
_php_ibase_alloc_xsqlda ( out_sqlda ) ;
if ( ib_query - > out_array ) {
2003-08-12 08:58:52 +08:00
IB_RESULT - > out_array = safe_emalloc ( sizeof ( ibase_array ) , ib_query - > out_array_cnt , 0 ) ;
2003-03-16 13:00:50 +08:00
memcpy ( IB_RESULT - > out_array , ib_query - > out_array , sizeof ( ibase_array ) * ib_query - > out_array_cnt ) ;
2000-03-13 03:44:23 +08:00
} else {
IB_RESULT - > out_array = NULL ;
}
}
if ( ib_query - > in_sqlda ) { /* has placeholders */
2000-07-09 18:27:41 +08:00
IBDEBUG ( " Query wants XSQLDA for input " ) ;
2000-03-13 03:44:23 +08:00
if ( ib_query - > in_sqlda - > sqld ! = argc ) {
2002-07-19 17:21:29 +08:00
_php_ibase_module_error ( " Placeholders (%d) and variables (%d) mismatch " , ib_query - > in_sqlda - > sqld , argc ) ;
2000-03-13 03:44:23 +08:00
goto _php_ibase_exec_error ; /* yes mommy, goto! */
}
in_sqlda = emalloc ( XSQLDA_LENGTH ( ib_query - > in_sqlda - > sqld ) ) ;
2000-04-18 10:52:45 +08:00
memcpy ( in_sqlda , ib_query - > in_sqlda , XSQLDA_LENGTH ( ib_query - > in_sqlda - > sqld ) ) ;
2003-08-12 08:58:52 +08:00
bind_buf = safe_emalloc ( sizeof ( BIND_BUF ) , ib_query - > in_sqlda - > sqld , 0 ) ;
2003-03-16 13:00:50 +08:00
if ( _php_ibase_bind ( in_sqlda , args , bind_buf , ib_query TSRMLS_CC ) = = FAILURE ) {
2002-07-19 17:21:29 +08:00
IBDEBUG ( " Could not bind input XSQLDA " ) ;
2000-03-13 03:44:23 +08:00
goto _php_ibase_exec_error ;
}
}
2003-08-13 10:19:14 +08:00
if ( ib_query - > statement_type = = isc_info_sql_stmt_exec_procedure ) {
isc_result = isc_dsql_execute2 ( IB_STATUS , & ib_query - > trans - > handle , & ib_query - > stmt , SQLDA_CURRENT_VERSION , in_sqlda , out_sqlda ) ;
} else {
isc_result = isc_dsql_execute ( IB_STATUS , & ib_query - > trans - > handle , & ib_query - > stmt , SQLDA_CURRENT_VERSION , in_sqlda ) ;
}
if ( isc_result ) {
2002-07-19 17:21:29 +08:00
IBDEBUG ( " Could not execute query " ) ;
_php_ibase_error ( TSRMLS_C ) ;
2000-03-13 03:44:23 +08:00
goto _php_ibase_exec_error ;
}
2003-08-13 02:01:59 +08:00
ib_query - > trans - > affected_rows = 0 ;
switch ( ib_query - > statement_type ) {
case isc_info_sql_stmt_insert :
case isc_info_sql_stmt_update :
case isc_info_sql_stmt_delete :
case isc_info_sql_stmt_exec_procedure :
if ( isc_dsql_sql_info ( IB_STATUS , & ib_query - > stmt , sizeof ( info_count ) , info_count , sizeof ( result ) , result ) ) {
_php_ibase_error ( TSRMLS_C ) ;
goto _php_ibase_exec_error ;
}
if ( result [ 0 ] = = isc_info_sql_records ) {
unsigned i = 3 , result_size = isc_vax_integer ( & result [ 1 ] , 2 ) ;
while ( result [ i ] ! = isc_info_end & & i < result_size ) {
short len = ( short ) isc_vax_integer ( & result [ i + 1 ] , 2 ) ;
if ( result [ i ] ! = isc_info_req_select_count ) {
ib_query - > trans - > affected_rows + = isc_vax_integer ( & result [ i + 3 ] , len ) ;
}
i + = len + 3 ;
}
}
}
2000-03-13 03:44:23 +08:00
rv = SUCCESS ;
_php_ibase_exec_error : /* I'm a bad boy... */
2003-03-16 13:00:50 +08:00
if ( in_sqlda ) {
2000-10-18 01:46:14 +08:00
efree ( in_sqlda ) ;
}
2000-03-13 03:44:23 +08:00
if ( bind_buf )
efree ( bind_buf ) ;
if ( rv = = FAILURE ) {
if ( IB_RESULT ) {
efree ( IB_RESULT ) ;
IB_RESULT = NULL ;
}
2003-03-16 13:00:50 +08:00
if ( out_sqlda ) {
2000-07-09 18:27:41 +08:00
_php_ibase_free_xsqlda ( out_sqlda ) ;
2003-03-16 13:00:50 +08:00
}
2000-03-13 03:44:23 +08:00
}
return rv ;
# undef IB_RESULT
}
/* }}} */
2003-08-06 07:40:30 +08:00
/* {{{ proto resource ibase_trans([int trans_args [, resource link_identifier [, ... ], int trans_args [, resource link_identifier [, ... ]] [, ...]]])
Start a transaction over one or several databases */
# define TPB_MAX_SIZE (8*sizeof(char))
2000-03-13 03:44:23 +08:00
PHP_FUNCTION ( ibase_trans )
{
2003-08-06 20:09:30 +08:00
unsigned short i , argn , link_cnt = 0 , tpb_len = 0 ;
2003-08-06 07:40:30 +08:00
char last_tpb [ TPB_MAX_SIZE ] ;
ibase_db_link * * ib_link = NULL ;
2003-08-05 21:17:16 +08:00
ibase_trans * ib_trans ;
2003-08-06 00:30:47 +08:00
isc_tr_handle tr_handle = NULL ;
2003-08-06 07:40:30 +08:00
ISC_STATUS result ;
2000-03-13 03:44:23 +08:00
RESET_ERRMSG ;
2000-06-06 03:47:54 +08:00
argn = ZEND_NUM_ARGS ( ) ;
2000-03-13 03:44:23 +08:00
2003-08-06 07:40:30 +08:00
/* (1+argn) is an upper bound for the number of links this trans connects to */
2003-08-07 08:00:19 +08:00
ib_link = ( ibase_db_link * * ) do_alloca ( sizeof ( ibase_db_link * ) * ( 1 + argn ) ) ;
2003-08-06 07:40:30 +08:00
if ( argn > 0 ) {
long trans_argl = 0 ;
char * tpb ;
ISC_TEB * teb ;
2003-08-07 08:00:19 +08:00
zval * * * args = ( zval * * * ) do_alloca ( sizeof ( zval * * ) * argn ) ;
2003-08-05 21:17:16 +08:00
2000-04-30 13:46:04 +08:00
if ( zend_get_parameters_array_ex ( argn , args ) = = FAILURE ) {
2003-08-06 07:40:30 +08:00
free_alloca ( args ) ;
free_alloca ( ib_link ) ;
2000-03-13 03:44:23 +08:00
RETURN_FALSE ;
}
2003-08-07 08:00:19 +08:00
teb = ( ISC_TEB * ) do_alloca ( sizeof ( ISC_TEB ) * argn ) ;
tpb = ( char * ) do_alloca ( TPB_MAX_SIZE * argn ) ;
2000-03-13 03:44:23 +08:00
2003-08-06 07:40:30 +08:00
/* enumerate all the arguments: assume every non-resource argument
specifies modifiers for the link ids that follow it */
for ( i = 0 ; i < argn ; + + i ) {
if ( Z_TYPE_PP ( args [ i ] ) = = IS_RESOURCE ) {
ZEND_FETCH_RESOURCE2 ( ib_link [ link_cnt ] , ibase_db_link * , args [ i ] , - 1 , " InterBase link " , le_link , le_plink ) ;
/* copy the most recent modifier string into tbp[] */
memcpy ( & tpb [ TPB_MAX_SIZE * link_cnt ] , last_tpb , TPB_MAX_SIZE ) ;
2000-03-13 03:44:23 +08:00
2003-08-06 07:40:30 +08:00
/* add a database handle to the TEB with the most recently specified set of modifiers */
2003-08-13 02:01:59 +08:00
teb [ link_cnt ] . db_ptr = & ib_link [ link_cnt ] - > handle ;
2003-08-06 07:40:30 +08:00
teb [ link_cnt ] . tpb_len = tpb_len ;
teb [ link_cnt ] . tpb_ptr = & tpb [ TPB_MAX_SIZE * link_cnt ] ;
+ + link_cnt ;
} else {
tpb_len = 0 ;
2000-03-13 03:44:23 +08:00
2003-08-06 07:40:30 +08:00
convert_to_long_ex ( args [ i ] ) ;
trans_argl = Z_LVAL_PP ( args [ i ] ) ;
2000-07-07 20:06:05 +08:00
2003-08-06 07:40:30 +08:00
if ( trans_argl ) {
last_tpb [ tpb_len + + ] = isc_tpb_version3 ;
/* access mode */
if ( trans_argl & PHP_IBASE_READ ) { /* READ ONLY TRANSACTION */
last_tpb [ tpb_len + + ] = isc_tpb_read ;
} else {
last_tpb [ tpb_len + + ] = isc_tpb_write ; /* default access mode */
}
/* isolation level */
if ( trans_argl & PHP_IBASE_COMMITTED ) {
last_tpb [ tpb_len + + ] = isc_tpb_read_committed ;
if ( trans_argl & PHP_IBASE_REC_VERSION ) {
last_tpb [ tpb_len + + ] = isc_tpb_rec_version ;
} else {
last_tpb [ tpb_len + + ] = isc_tpb_no_rec_version ; /* default in read_committed */
}
} else if ( trans_argl & PHP_IBASE_CONSISTENCY ) {
last_tpb [ tpb_len + + ] = isc_tpb_consistency ;
} else {
last_tpb [ tpb_len + + ] = isc_tpb_concurrency ; /* default isolation level */
}
/* lock resolution */
if ( trans_argl & PHP_IBASE_NOWAIT ) {
last_tpb [ tpb_len + + ] = isc_tpb_nowait ;
} else {
last_tpb [ tpb_len + + ] = isc_tpb_wait ; /* default lock resolution */
}
}
}
}
if ( link_cnt > 0 ) {
result = isc_start_multiple ( IB_STATUS , & tr_handle , link_cnt , teb ) ;
2003-03-16 13:00:50 +08:00
}
2003-08-06 07:40:30 +08:00
free_alloca ( args ) ;
free_alloca ( tpb ) ;
free_alloca ( teb ) ;
2000-03-13 03:44:23 +08:00
}
2003-08-06 07:40:30 +08:00
if ( link_cnt = = 0 ) {
link_cnt = 1 ;
ZEND_FETCH_RESOURCE2 ( ib_link [ 0 ] , ibase_db_link * , NULL , IBG ( default_link ) , " InterBase link " , le_link , le_plink ) ;
2003-08-13 02:01:59 +08:00
result = isc_start_transaction ( IB_STATUS , & tr_handle , 1 , & ib_link [ 0 ] - > handle , tpb_len , last_tpb ) ;
2000-03-13 03:44:23 +08:00
}
2003-08-05 21:17:16 +08:00
/* start the transaction */
2003-08-06 07:40:30 +08:00
if ( result ) {
2002-07-19 17:21:29 +08:00
_php_ibase_error ( TSRMLS_C ) ;
2003-08-06 07:40:30 +08:00
free_alloca ( ib_link ) ;
2000-03-13 03:44:23 +08:00
RETURN_FALSE ;
}
2000-07-07 20:06:05 +08:00
2003-08-05 21:17:16 +08:00
/* register the transaction in our own data structures */
2003-08-12 08:58:52 +08:00
ib_trans = ( ibase_trans * ) safe_emalloc ( ( link_cnt - 1 ) , sizeof ( ibase_db_link * ) , sizeof ( ibase_trans ) ) ;
2003-08-05 21:17:16 +08:00
ib_trans - > handle = tr_handle ;
ib_trans - > link_cnt = link_cnt ;
2003-08-11 00:21:26 +08:00
ib_trans - > affected_rows = 0 ;
2003-08-05 21:17:16 +08:00
for ( i = 0 ; i < link_cnt ; + + i ) {
ibase_tr_list * * l ;
2003-08-08 19:04:12 +08:00
ib_trans - > db_link [ i ] = ib_link [ i ] ;
2003-08-05 21:17:16 +08:00
2003-08-06 00:30:47 +08:00
/* the first item in the connection-transaction list is reserved for the default transaction */
2003-08-08 19:04:12 +08:00
if ( ib_link [ i ] - > tr_list = = NULL ) {
ib_link [ i ] - > tr_list = ( ibase_tr_list * ) emalloc ( sizeof ( ibase_tr_list ) ) ;
ib_link [ i ] - > tr_list - > trans = NULL ;
ib_link [ i ] - > tr_list - > next = NULL ;
2003-08-05 21:17:16 +08:00
}
2003-08-06 00:30:47 +08:00
2003-08-05 21:17:16 +08:00
/* link the transaction into the connection-transaction list */
2003-08-08 19:04:12 +08:00
for ( l = & ib_link [ i ] - > tr_list ; * l ! = NULL ; l = & ( * l ) - > next ) ;
2003-08-07 08:00:19 +08:00
* l = ( ibase_tr_list * ) emalloc ( sizeof ( ibase_tr_list ) ) ;
2003-08-05 21:17:16 +08:00
( * l ) - > trans = ib_trans ;
( * l ) - > next = NULL ;
}
2003-08-06 07:40:30 +08:00
free_alloca ( ib_link ) ;
2000-10-05 20:47:39 +08:00
ZEND_REGISTER_RESOURCE ( return_value , ib_trans , le_trans ) ;
2000-03-13 03:44:23 +08:00
}
/* }}} */
/* {{{ _php_ibase_def_trans() */
/* open default transaction */
2003-08-05 21:17:16 +08:00
static int _php_ibase_def_trans ( ibase_db_link * ib_link , ibase_trans * * trans TSRMLS_DC )
2000-03-13 03:44:23 +08:00
{
2003-03-16 08:37:01 +08:00
if ( ib_link = = NULL ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Invalid database link " ) ;
return FAILURE ;
}
2003-08-06 00:30:47 +08:00
/* the first item in the connection-transaction list is reserved for the default transaction */
2003-08-08 19:04:12 +08:00
if ( ib_link - > tr_list = = NULL ) {
ib_link - > tr_list = ( ibase_tr_list * ) emalloc ( sizeof ( ibase_tr_list ) ) ;
ib_link - > tr_list - > trans = NULL ;
ib_link - > tr_list - > next = NULL ;
2003-08-05 21:17:16 +08:00
}
2003-08-06 00:30:47 +08:00
2003-08-05 21:17:16 +08:00
if ( * trans = = NULL ) {
2003-08-08 19:04:12 +08:00
ibase_trans * tr = ib_link - > tr_list - > trans ;
if ( tr = = NULL ) {
tr = ( ibase_trans * ) emalloc ( sizeof ( ibase_trans ) ) ;
2003-08-05 21:17:16 +08:00
tr - > handle = NULL ;
2003-08-08 19:04:12 +08:00
tr - > link_cnt = 1 ;
2003-08-11 00:21:26 +08:00
tr - > affected_rows = 0 ;
2003-08-08 19:04:12 +08:00
tr - > db_link [ 0 ] = ib_link ;
ib_link - > tr_list - > trans = tr ;
}
if ( tr - > handle = = NULL ) {
2003-08-13 02:01:59 +08:00
if ( isc_start_transaction ( IB_STATUS , & tr - > handle , 1 , & ib_link - > handle , 0 , NULL ) ) {
2003-08-05 21:17:16 +08:00
_php_ibase_error ( TSRMLS_C ) ;
return FAILURE ;
}
2000-03-13 03:44:23 +08:00
}
2003-08-08 19:04:12 +08:00
* trans = tr ;
2000-03-13 03:44:23 +08:00
}
return SUCCESS ;
}
2003-08-06 00:30:47 +08:00
/* }}} */
2000-03-13 03:44:23 +08:00
/* {{{ _php_ibase_trans_end() */
2003-08-07 01:51:46 +08:00
# define RETAIN 2
2000-03-13 03:44:23 +08:00
# define COMMIT 1
# define ROLLBACK 0
2003-08-07 01:51:46 +08:00
2000-03-13 03:44:23 +08:00
static void _php_ibase_trans_end ( INTERNAL_FUNCTION_PARAMETERS , int commit )
{
2003-08-05 21:17:16 +08:00
ibase_trans * trans = NULL ;
int res_id = 0 ;
2003-08-15 08:06:07 +08:00
ISC_STATUS result = 0 ;
2000-03-13 03:44:23 +08:00
RESET_ERRMSG ;
2000-06-06 03:47:54 +08:00
switch ( ZEND_NUM_ARGS ( ) ) {
2003-08-05 21:17:16 +08:00
ibase_db_link * ib_link ;
2003-08-08 09:42:09 +08:00
zval * * arg ;
2003-08-05 21:17:16 +08:00
2000-03-13 03:44:23 +08:00
case 0 :
2003-08-05 21:17:16 +08:00
ZEND_FETCH_RESOURCE2 ( ib_link , ibase_db_link * , NULL , IBG ( default_link ) , " InterBase link " , le_link , le_plink ) ;
2003-08-08 21:47:20 +08:00
if ( ib_link - > tr_list = = NULL | | ib_link - > tr_list - > trans = = NULL ) {
2003-08-08 09:42:09 +08:00
/* this link doesn't have a default transaction */
_php_ibase_module_error ( " Default link has no default transaction " ) ;
RETURN_FALSE ;
}
2003-08-08 19:04:12 +08:00
trans = ib_link - > tr_list - > trans ;
2000-03-13 03:44:23 +08:00
break ;
2003-08-05 21:17:16 +08:00
2000-03-13 03:44:23 +08:00
case 1 :
2003-08-08 09:42:09 +08:00
if ( zend_get_parameters_ex ( 1 , & arg ) = = FAILURE ) {
1999-04-22 10:48:28 +08:00
RETURN_FALSE ;
}
2003-08-08 09:42:09 +08:00
/* one id was passed, could be db or trans id */
_php_ibase_get_link_trans ( INTERNAL_FUNCTION_PARAM_PASSTHRU , arg , & ib_link , & trans ) ;
if ( trans ! = NULL ) {
convert_to_long_ex ( arg ) ;
res_id = Z_LVAL_PP ( arg ) ;
2003-08-05 21:17:16 +08:00
2003-08-08 09:42:09 +08:00
} else {
2003-08-08 19:04:12 +08:00
ZEND_FETCH_RESOURCE2 ( ib_link , ibase_db_link * , arg , - 1 , " InterBase link " , le_link , le_plink ) ;
2003-08-05 21:17:16 +08:00
2003-08-08 19:04:12 +08:00
if ( ib_link - > tr_list = = NULL | | ib_link - > tr_list - > trans = = NULL ) {
2003-08-08 09:42:09 +08:00
/* this link doesn't have a default transaction */
_php_ibase_module_error ( " Link has no default transaction " ) ;
RETURN_FALSE ;
}
2003-08-08 19:04:12 +08:00
trans = ib_link - > tr_list - > trans ;
2003-08-08 09:42:09 +08:00
}
1999-04-22 10:48:28 +08:00
break ;
2003-08-05 21:17:16 +08:00
1999-04-22 10:48:28 +08:00
default :
WRONG_PARAM_COUNT ;
break ;
}
2000-03-13 03:44:23 +08:00
2003-08-07 01:51:46 +08:00
switch ( commit ) {
case ROLLBACK :
result = isc_rollback_transaction ( IB_STATUS , & trans - > handle ) ;
break ;
case COMMIT :
result = isc_commit_transaction ( IB_STATUS , & trans - > handle ) ;
break ;
case ( ROLLBACK | RETAIN ) :
result = isc_rollback_retaining ( IB_STATUS , & trans - > handle ) ;
break ;
case ( COMMIT | RETAIN ) :
result = isc_commit_retaining ( IB_STATUS , & trans - > handle ) ;
break ;
2000-03-13 03:44:23 +08:00
}
1999-04-22 10:48:28 +08:00
2003-08-07 01:51:46 +08:00
if ( result ) {
_php_ibase_error ( TSRMLS_C ) ;
RETURN_FALSE ;
}
2003-08-05 21:17:16 +08:00
/* Don't try to destroy implicitly opened transaction from list... */
2003-08-07 01:51:46 +08:00
if ( ( commit & RETAIN ) = = 0 & & res_id ! = 0 ) {
2003-08-05 21:17:16 +08:00
zend_list_delete ( res_id ) ;
}
2000-03-13 03:44:23 +08:00
RETURN_TRUE ;
}
/* }}} */
2003-06-16 18:41:42 +08:00
/* {{{ proto bool ibase_commit( resource link_identifier )
2000-03-13 03:44:23 +08:00
Commit transaction */
PHP_FUNCTION ( ibase_commit )
{
_php_ibase_trans_end ( INTERNAL_FUNCTION_PARAM_PASSTHRU , COMMIT ) ;
}
/* }}} */
2003-06-16 18:41:42 +08:00
/* {{{ proto bool ibase_rollback( resource link_identifier )
Rollback transaction */
2000-03-13 03:44:23 +08:00
PHP_FUNCTION ( ibase_rollback )
{
_php_ibase_trans_end ( INTERNAL_FUNCTION_PARAM_PASSTHRU , ROLLBACK ) ;
}
/* }}} */
2003-08-07 01:51:46 +08:00
/* {{{ proto bool ibase_commit_ret( resource link_identifier )
Commit transaction and retain the transaction context */
PHP_FUNCTION ( ibase_commit_ret )
{
_php_ibase_trans_end ( INTERNAL_FUNCTION_PARAM_PASSTHRU , COMMIT | RETAIN ) ;
}
/* }}} */
/* {{{ proto bool ibase_rollback_ret( resource link_identifier )
Rollback transaction and retain the transaction context */
PHP_FUNCTION ( ibase_rollback_ret )
{
_php_ibase_trans_end ( INTERNAL_FUNCTION_PARAM_PASSTHRU , ROLLBACK | RETAIN ) ;
}
/* }}} */
2003-08-10 21:20:38 +08:00
/* {{{ proto resource ibase_query([resource link_identifier [, resource link_identifier ] ,] string query [, int bind_args])
2000-03-13 03:44:23 +08:00
Execute a query */
PHP_FUNCTION ( ibase_query )
{
2003-08-05 21:17:16 +08:00
zval * * * args , * * bind_args = NULL ;
2003-08-13 02:01:59 +08:00
int i , bind_n = 0 , trans_res_id = 0 ;
2003-08-05 21:17:16 +08:00
ibase_db_link * ib_link = NULL ;
ibase_trans * trans = NULL ;
2000-03-13 03:44:23 +08:00
ibase_query * ib_query ;
2003-08-10 21:20:38 +08:00
ibase_result * ib_result = NULL ;
2003-08-13 02:01:59 +08:00
char * query ;
2000-03-13 03:44:23 +08:00
RESET_ERRMSG ;
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) < 1 ) {
2000-03-13 03:44:23 +08:00
WRONG_PARAM_COUNT ;
}
2003-08-05 21:17:16 +08:00
/* use stack to avoid leaks */
args = ( zval * * * ) do_alloca ( sizeof ( zval * * ) * ZEND_NUM_ARGS ( ) ) ;
2000-06-06 03:47:54 +08:00
if ( zend_get_parameters_array_ex ( ZEND_NUM_ARGS ( ) , args ) = = FAILURE ) {
2003-08-06 07:40:30 +08:00
free_alloca ( args ) ;
1999-04-22 10:48:28 +08:00
RETURN_FALSE ;
}
2003-08-05 21:17:16 +08:00
2000-03-13 03:44:23 +08:00
i = 0 ;
2003-08-05 21:17:16 +08:00
while ( Z_TYPE_PP ( args [ i + + ] ) ! = IS_STRING ) {
2003-08-06 23:27:16 +08:00
if ( i > = ZEND_NUM_ARGS ( ) ) {
2003-08-05 21:17:16 +08:00
_php_ibase_module_error ( " Query argument missing " ) ;
2003-08-06 23:27:16 +08:00
free_alloca ( args ) ;
2003-08-05 21:17:16 +08:00
RETURN_FALSE ;
}
2000-03-13 03:44:23 +08:00
}
2003-08-05 21:17:16 +08:00
convert_to_string_ex ( args [ i - 1 ] ) ;
query = Z_STRVAL_PP ( args [ i - 1 ] ) ;
/* find out if the first one or two arguments refer to either a link id,
a trans id or both */
switch ( i ) {
case 1 :
/* no link ids were passed: if there's no default link, use exec_immediate() with
a NULL handle ; this will enable the use of CREATE DATABASE statements . */
2003-08-07 08:00:19 +08:00
if ( IBG ( default_link ) = = - 1 ) {
2003-08-05 21:17:16 +08:00
isc_db_handle db = NULL ;
isc_tr_handle trans = NULL ;
2000-03-13 03:44:23 +08:00
2003-08-05 21:17:16 +08:00
if ( isc_dsql_execute_immediate ( IB_STATUS , & db , & trans , 0 , query , SQL_DIALECT_CURRENT , NULL ) ) {
_php_ibase_error ( TSRMLS_C ) ;
2003-08-06 23:27:16 +08:00
free_alloca ( args ) ;
2003-08-05 21:17:16 +08:00
RETURN_FALSE ;
}
2003-08-06 23:27:16 +08:00
/* has a new database been created ? */
if ( db ! = NULL ) {
if ( ( IBG ( max_links ) ! = - 1 ) & & ( IBG ( num_links ) > = IBG ( max_links ) ) ) {
/* too many links already ? => close it up immediately */
if ( isc_detach_database ( IB_STATUS , & db ) ) {
_php_ibase_error ( TSRMLS_C ) ;
free_alloca ( args ) ;
RETURN_FALSE ;
}
} else {
/* register the link as a resource; unfortunately, we cannot register
it in the hash table , because we don ' t know the connection params */
2003-08-07 08:00:19 +08:00
ib_link = ( ibase_db_link * ) emalloc ( sizeof ( ibase_db_link ) ) ;
2003-08-13 02:01:59 +08:00
ib_link - > handle = db ;
2003-08-06 23:27:16 +08:00
ib_link - > dialect = SQL_DIALECT_CURRENT ;
2003-08-08 19:04:12 +08:00
ib_link - > tr_list = NULL ;
2003-08-06 23:27:16 +08:00
ZEND_REGISTER_RESOURCE ( return_value , ib_link , le_link ) ;
zend_list_addref ( Z_LVAL_P ( return_value ) ) ;
IBG ( default_link ) = Z_LVAL_P ( return_value ) ;
IBG ( num_links ) + + ;
free_alloca ( args ) ;
return ;
}
2003-08-05 21:17:16 +08:00
}
RETURN_TRUE ;
}
ZEND_FETCH_RESOURCE2 ( ib_link , ibase_db_link * , NULL , IBG ( default_link ) , " InterBase link " , le_link , le_plink ) ;
break ;
case 2 :
/* one id was passed, could be db or trans id */
_php_ibase_get_link_trans ( INTERNAL_FUNCTION_PARAM_PASSTHRU , args [ 0 ] , & ib_link , & trans ) ;
2003-08-10 21:20:38 +08:00
if ( trans ! = NULL ) {
/* argument was a trans id */
convert_to_long_ex ( args [ 0 ] ) ;
2003-08-13 02:01:59 +08:00
trans_res_id = Z_LVAL_PP ( args [ 0 ] ) ;
2003-08-10 21:20:38 +08:00
}
2003-08-05 21:17:16 +08:00
break ;
case 3 :
2003-08-08 09:42:09 +08:00
/* two ids were passed, first should be link and second should be trans; */
2003-08-05 21:17:16 +08:00
ZEND_FETCH_RESOURCE2 ( ib_link , ibase_db_link * , args [ 0 ] , - 1 , " InterBase link " , le_link , le_plink ) ;
ZEND_FETCH_RESOURCE ( trans , ibase_trans * , args [ 1 ] , - 1 , " InterBase transaction " , le_trans ) ;
2003-08-10 21:20:38 +08:00
convert_to_long_ex ( args [ 1 ] ) ;
2003-08-13 02:01:59 +08:00
trans_res_id = Z_LVAL_PP ( args [ 1 ] ) ;
2003-08-10 21:20:38 +08:00
2003-08-05 21:17:16 +08:00
break ;
default :
/* more than two arguments preceed the SQL string */
_php_ibase_module_error ( " Invalid arguments " ) ;
2003-08-06 23:27:16 +08:00
free_alloca ( args ) ;
2003-08-05 21:17:16 +08:00
RETURN_FALSE ;
}
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) > i ) { /* have variables to bind */
2003-08-05 21:17:16 +08:00
/* Using variables in a query without preparing it can be
useful , because it allows you to use ( among other things )
SQL - queries as consts and the passing of string arguments
without the horror of [ un ] slashing them . */
2000-06-06 03:47:54 +08:00
bind_n = ZEND_NUM_ARGS ( ) - i ;
2000-04-30 13:46:04 +08:00
bind_args = args [ i ] ;
2000-03-13 03:44:23 +08:00
}
/* open default transaction */
2003-08-10 21:20:38 +08:00
if ( ib_link = = NULL | | _php_ibase_def_trans ( ib_link , & trans TSRMLS_CC ) = = FAILURE ) {
2003-08-06 23:27:16 +08:00
free_alloca ( args ) ;
2000-03-13 03:44:23 +08:00
RETURN_FALSE ;
}
2003-08-13 02:01:59 +08:00
if ( _php_ibase_alloc_query ( & ib_query , ib_link , trans , query , ib_link - > dialect , trans_res_id TSRMLS_CC ) = = FAILURE ) {
2003-08-06 23:27:16 +08:00
free_alloca ( args ) ;
2000-03-13 03:44:23 +08:00
RETURN_FALSE ;
2003-08-10 21:20:38 +08:00
}
2003-08-13 02:01:59 +08:00
if ( _php_ibase_exec ( INTERNAL_FUNCTION_PARAM_PASSTHRU , & ib_result , ib_query , bind_n , bind_args ) = = FAILURE ) {
_php_ibase_free_query ( ib_query TSRMLS_CC ) ;
2003-08-11 00:21:26 +08:00
free_alloca ( args ) ;
2003-08-10 21:20:38 +08:00
RETURN_FALSE ;
}
2003-08-08 21:47:20 +08:00
2003-08-06 23:27:16 +08:00
free_alloca ( args ) ;
2003-08-11 00:21:26 +08:00
2000-03-13 03:44:23 +08:00
if ( ib_result ) { /* select statement */
ib_result - > drop_stmt = 1 ; /* drop stmt when free result */
ib_query - > stmt = NULL ; /* keep stmt when free query */
2003-03-16 13:00:50 +08:00
_php_ibase_free_query ( ib_query TSRMLS_CC ) ;
2003-08-11 00:21:26 +08:00
ib_result - > has_more_rows = 1 ;
2000-10-05 20:47:39 +08:00
ZEND_REGISTER_RESOURCE ( return_value , ib_result , le_result ) ;
2000-03-13 03:44:23 +08:00
} else {
2003-03-16 13:00:50 +08:00
_php_ibase_free_query ( ib_query TSRMLS_CC ) ;
2000-03-13 03:44:23 +08:00
}
}
/* }}} */
2003-08-11 00:21:26 +08:00
/* {{{ proto ibase_affected_rows( [ resource link_identifier ] )
Returns the number of rows affected by the previous INSERT , UPDATE or DELETE statement */
PHP_FUNCTION ( ibase_affected_rows )
{
ibase_trans * trans = NULL ;
RESET_ERRMSG ;
switch ( ZEND_NUM_ARGS ( ) ) {
ibase_db_link * ib_link ;
zval * * arg ;
case 0 :
ZEND_FETCH_RESOURCE2 ( ib_link , ibase_db_link * , NULL , IBG ( default_link ) , " InterBase link " , le_link , le_plink ) ;
if ( ib_link - > tr_list = = NULL | | ib_link - > tr_list - > trans = = NULL ) {
RETURN_FALSE ;
}
trans = ib_link - > tr_list - > trans ;
break ;
case 1 :
if ( zend_get_parameters_ex ( 1 , & arg ) = = FAILURE ) {
RETURN_FALSE ;
}
/* one id was passed, could be db or trans id */
_php_ibase_get_link_trans ( INTERNAL_FUNCTION_PARAM_PASSTHRU , arg , & ib_link , & trans ) ;
if ( trans = = NULL ) {
ZEND_FETCH_RESOURCE2 ( ib_link , ibase_db_link * , arg , - 1 , " InterBase link " , le_link , le_plink ) ;
if ( ib_link - > tr_list = = NULL | | ib_link - > tr_list - > trans = = NULL ) {
RETURN_FALSE ;
}
trans = ib_link - > tr_list - > trans ;
}
break ;
default :
WRONG_PARAM_COUNT ;
break ;
}
RETURN_LONG ( trans - > affected_rows ) ;
}
/* }}} */
2003-08-16 08:58:24 +08:00
/* {{{ ibase_num_rows( resource result_identifier ) */
2003-08-11 00:21:26 +08:00
PHP_FUNCTION ( ibase_num_rows )
{
2003-08-12 19:35:26 +08:00
/**
2003-08-16 08:58:24 +08:00
* PLEASE READ THIS FIRST before adding this function to the main PHP
* documentation :
*
* As this function relies on the InterBase API function isc_dsql_sql_info ( )
* which has a couple of limitations ( which I hope will be fixed in future
* releases of Firebird ) , this function is fairly useless . I ' m leaving it
* in place for people who can live with the limitations , which I only
* found out about after I had implemented it anyway .
*
* Currently , there ' s no way to determine how many rows can be fetched from
* a cursor . The only number that _can_ be determined is the number of rows
* that have already been pre - fetched by the client library .
* This implies the following :
* - num_rows ( ) always returns zero before the first fetch ;
* - num_rows ( ) for SELECT . . . FOR UPDATE is broken - > never returns a
* higher number than the number of records fetched so far ( no pre - fetch ) ;
* - the result of num_rows ( ) for other statements is merely a lower bound
* on the number of records = > calling ibase_num_rows ( ) again after a couple
* of fetches will most likely return a new ( higher ) figure for large result
* sets .
2003-08-12 19:35:26 +08:00
*
* 12 - aug - 2003 Ard Biesheuvel
*/
2003-08-11 00:21:26 +08:00
zval * * result_arg ;
ibase_result * ib_result ;
char info_count [ ] = { isc_info_sql_records } , result [ 64 ] ;
RESET_ERRMSG ;
if ( ZEND_NUM_ARGS ( ) ! = 1 | | zend_get_parameters_ex ( 1 , & result_arg ) = = FAILURE ) {
WRONG_PARAM_COUNT ;
}
ZEND_FETCH_RESOURCE ( ib_result , ibase_result * , result_arg , - 1 , " InterBase result " , le_result ) ;
if ( isc_dsql_sql_info ( IB_STATUS , & ib_result - > stmt , sizeof ( info_count ) , info_count , sizeof ( result ) , result ) ) {
_php_ibase_error ( TSRMLS_C ) ;
RETURN_FALSE ;
}
if ( result [ 0 ] = = isc_info_sql_records ) {
unsigned i = 3 , result_size = isc_vax_integer ( & result [ 1 ] , 2 ) ;
while ( result [ i ] ! = isc_info_end & & i < result_size ) {
2003-08-11 01:24:51 +08:00
short len = ( short ) isc_vax_integer ( & result [ i + 1 ] , 2 ) ;
2003-08-11 00:21:26 +08:00
if ( result [ i ] = = isc_info_req_select_count ) {
RETURN_LONG ( isc_vax_integer ( & result [ i + 3 ] , len ) ) ;
}
i + = len + 3 ;
}
}
}
2003-08-11 01:24:51 +08:00
/* }}} */
2003-08-11 00:21:26 +08:00
2003-03-16 13:00:50 +08:00
/* {{{ _php_ibase_var_zval() */
static int _php_ibase_var_zval ( zval * val , void * data , int type , int len , int scale , int flag TSRMLS_DC )
2000-03-13 03:44:23 +08:00
{
char string_data [ 255 ] ;
2003-03-16 13:00:50 +08:00
switch ( type & ~ 1 ) {
2000-03-13 03:44:23 +08:00
case SQL_VARYING :
len = ( ( IBASE_VCHAR * ) data ) - > var_len ;
data = ( ( IBASE_VCHAR * ) data ) - > var_str ;
/* fallout */
case SQL_TEXT :
2003-08-12 08:58:52 +08:00
Z_STRVAL_P ( val ) = ( char * ) safe_emalloc ( sizeof ( char ) , ( len + 1 ) , 0 ) ;
2001-09-26 05:58:48 +08:00
memcpy ( Z_STRVAL_P ( val ) , data , len ) ;
Z_STRVAL_P ( val ) [ len ] = ' \0 ' ;
2000-03-13 03:44:23 +08:00
if ( PG ( magic_quotes_runtime ) ) {
2001-09-26 05:58:48 +08:00
Z_STRVAL_P ( val ) = php_addslashes ( Z_STRVAL_P ( val ) , len , & len , 1 TSRMLS_CC ) ;
2003-03-16 13:00:50 +08:00
}
2001-09-26 05:58:48 +08:00
Z_TYPE_P ( val ) = IS_STRING ;
Z_STRLEN_P ( val ) = len ;
2000-03-13 03:44:23 +08:00
break ;
case SQL_LONG :
2003-06-02 20:37:16 +08:00
case SQL_SHORT :
2000-03-13 03:44:23 +08:00
if ( scale ) {
2003-06-02 20:37:16 +08:00
short j ;
long n , f = 1 ;
if ( ( type & ~ 1 ) = = SQL_SHORT ) {
n = ( long ) * ( short * ) ( data ) ;
2003-08-07 08:00:19 +08:00
} else {
2003-06-02 20:37:16 +08:00
n = ( long ) * ( long * ) ( data ) ;
}
2001-05-03 06:31:19 +08:00
for ( j = 0 ; j < - scale ; j + + ) {
2000-03-13 03:44:23 +08:00
f * = 10 ;
2001-05-03 06:31:19 +08:00
}
2003-08-07 08:00:19 +08:00
if ( n > = 0 ) {
Z_STRLEN_P ( val ) = sprintf ( string_data , " %ld.%0*ld " , n / f , - scale , n % f ) ;
} else if ( ( n / f ) ! = 0 ) {
Z_STRLEN_P ( val ) = sprintf ( string_data , " %ld.%0*ld " , n / f , - scale , - ( n % f ) ) ;
} else {
Z_STRLEN_P ( val ) = sprintf ( string_data , " %s.%0*ld " , " -0 " , - scale , - ( n % f ) ) ;
2003-06-02 20:37:16 +08:00
}
2001-09-26 05:58:48 +08:00
Z_TYPE_P ( val ) = IS_STRING ;
Z_STRVAL_P ( val ) = estrdup ( string_data ) ;
2000-04-18 10:52:45 +08:00
} else {
2001-09-26 05:58:48 +08:00
Z_TYPE_P ( val ) = IS_LONG ;
2003-06-02 20:37:16 +08:00
if ( ( type & ~ 1 ) = = SQL_SHORT ) {
Z_LVAL_P ( val ) = * ( short * ) ( data ) ;
2003-08-07 08:00:19 +08:00
} else {
2003-06-02 20:37:16 +08:00
Z_LVAL_P ( val ) = * ( long * ) ( data ) ;
}
2000-03-13 03:44:23 +08:00
}
break ;
case SQL_FLOAT :
2001-09-26 05:58:48 +08:00
Z_TYPE_P ( val ) = IS_DOUBLE ;
2003-03-16 13:00:50 +08:00
Z_DVAL_P ( val ) = * ( float * ) ( data ) ;
2000-03-13 03:44:23 +08:00
break ;
case SQL_DOUBLE :
if ( scale ) {
2001-09-26 05:58:48 +08:00
Z_TYPE_P ( val ) = IS_STRING ;
2003-03-16 13:00:50 +08:00
Z_STRLEN_P ( val ) = sprintf ( string_data , " %.*f " , - scale , * ( double * ) data ) ;
2001-09-26 05:58:48 +08:00
Z_STRVAL_P ( val ) = estrdup ( string_data ) ;
2000-04-18 10:52:45 +08:00
} else {
2001-09-26 05:58:48 +08:00
Z_TYPE_P ( val ) = IS_DOUBLE ;
2003-03-16 13:00:50 +08:00
Z_DVAL_P ( val ) = * ( double * ) data ;
2000-03-13 03:44:23 +08:00
}
break ;
2000-05-10 04:30:23 +08:00
# ifdef SQL_INT64
case SQL_INT64 :
2003-03-16 13:00:50 +08:00
Z_TYPE_P ( val ) = IS_STRING ;
2003-08-07 08:00:19 +08:00
if ( scale < 0 ) {
2003-06-02 20:37:16 +08:00
short j = 0 ;
ISC_INT64 n , f = 1 ;
n = ( ISC_INT64 ) * ( ISC_INT64 * ) data ;
2002-03-19 23:29:17 +08:00
for ( j = 0 ; j < - scale ; j + + ) {
f * = 10 ;
}
2003-08-07 08:00:19 +08:00
if ( n > = 0 ) {
Z_STRLEN_P ( val ) = sprintf ( string_data , " % " ISC_INT64_FORMAT " d.%0* " ISC_INT64_FORMAT " d " ,
2003-06-02 20:37:16 +08:00
( ISC_INT64 ) n / f , - scale , ( ISC_INT64 ) n % f ) ;
2003-08-07 08:00:19 +08:00
} else if ( ( n / f ) ! = 0 ) {
Z_STRLEN_P ( val ) = sprintf ( string_data , " % " ISC_INT64_FORMAT " d.%0* " ISC_INT64_FORMAT " d " ,
2003-06-02 20:37:16 +08:00
( ISC_INT64 ) n / f , - scale , ( ISC_INT64 ) - ( n % f ) ) ;
2003-08-07 08:00:19 +08:00
} else {
Z_STRLEN_P ( val ) = sprintf ( string_data , " %s.%0* " ISC_INT64_FORMAT " d " ,
2003-06-02 20:37:16 +08:00
" -0 " , - scale , ( ISC_INT64 ) - ( n % f ) ) ;
}
2002-03-07 03:54:47 +08:00
} else {
2003-08-07 08:00:19 +08:00
Z_STRLEN_P ( val ) = sprintf ( string_data , " %.0 " ISC_INT64_FORMAT " d " ,
2003-08-10 21:20:38 +08:00
* ( ISC_INT64 * ) data ) ;
2002-03-07 03:54:47 +08:00
}
2003-03-16 13:00:50 +08:00
Z_STRVAL_P ( val ) = estrdup ( string_data ) ;
2000-05-10 04:30:23 +08:00
break ;
# endif
# ifndef SQL_TIMESTAMP
case SQL_DATE :
# else
case SQL_TIMESTAMP :
case SQL_TYPE_DATE :
case SQL_TYPE_TIME :
# endif
{
2000-03-13 03:44:23 +08:00
struct tm t ;
2000-05-12 11:02:14 +08:00
char * format = NULL ;
2000-03-13 03:44:23 +08:00
long timestamp = - 1 ;
2000-05-12 11:02:14 +08:00
# ifndef SQL_TIMESTAMP
2000-03-13 03:44:23 +08:00
isc_decode_date ( ( ISC_QUAD * ) data , & t ) ;
2000-05-12 11:02:14 +08:00
format = IBG ( timestampformat ) ;
2000-05-10 04:30:23 +08:00
# else
switch ( type & ~ 1 ) {
case SQL_TIMESTAMP :
isc_decode_timestamp ( ( ISC_TIMESTAMP * ) data , & t ) ;
2000-05-12 11:02:14 +08:00
format = IBG ( timestampformat ) ;
2000-05-10 04:30:23 +08:00
break ;
case SQL_TYPE_DATE :
isc_decode_sql_date ( ( ISC_DATE * ) data , & t ) ;
2000-05-12 11:02:14 +08:00
format = IBG ( dateformat ) ;
2000-05-10 04:30:23 +08:00
break ;
case SQL_TYPE_TIME :
isc_decode_sql_time ( ( ISC_TIME * ) data , & t ) ;
2000-05-12 11:02:14 +08:00
format = IBG ( timeformat ) ;
2000-05-10 04:30:23 +08:00
break ;
}
# endif
2000-05-04 21:43:06 +08:00
/*
XXX - Might have to remove this later - seems that isc_decode_date ( )
always sets tm_isdst to 0 , sometimes incorrectly ( InterBase 6 bug ? )
*/
t . tm_isdst = - 1 ;
2000-03-13 03:44:23 +08:00
timestamp = mktime ( & t ) ;
# if HAVE_TM_ZONE
t . tm_zone = tzname [ 0 ] ;
# endif
2000-05-12 11:02:14 +08:00
if ( flag & PHP_IBASE_UNIXTIME ) {
2001-09-26 05:58:48 +08:00
Z_TYPE_P ( val ) = IS_LONG ;
Z_LVAL_P ( val ) = timestamp ;
2000-03-13 03:44:23 +08:00
} else {
2001-09-26 05:58:48 +08:00
Z_TYPE_P ( val ) = IS_STRING ;
2000-03-13 03:44:23 +08:00
# if HAVE_STRFTIME
2001-09-26 05:58:48 +08:00
Z_STRLEN_P ( val ) = strftime ( string_data , sizeof ( string_data ) , format , & t ) ;
2000-03-13 03:44:23 +08:00
# else
2000-05-12 11:02:14 +08:00
/* FIXME */
2003-03-16 13:00:50 +08:00
if ( ! t . tm_hour & & ! t . tm_min & & ! t . tm_sec ) {
Z_STRLEN_P ( val ) = sprintf ( string_data , " %02d/%02d/%4d " , t . tm_mon + 1 , t . tm_mday , t . tm_year + 1900 ) ;
} else {
Z_STRLEN_P ( val ) = sprintf ( string_data , " %02d/%02d/%4d %02d:%02d:%02d " , t . tm_mon + 1 , t . tm_mday , t . tm_year + 1900 , t . tm_hour , t . tm_min , t . tm_sec ) ;
}
2000-03-13 03:44:23 +08:00
# endif
2001-09-26 05:58:48 +08:00
Z_STRVAL_P ( val ) = estrdup ( string_data ) ;
2000-03-13 03:44:23 +08:00
break ;
}
}
default :
return FAILURE ;
2000-04-18 10:52:45 +08:00
} /* switch (type) */
2000-03-13 03:44:23 +08:00
return SUCCESS ;
}
/* }}} */
2003-03-16 13:00:50 +08:00
/* {{{ _php_ibase_arr_zval() */
2003-08-06 23:27:16 +08:00
/* create multidimension array - recursion function
2003-03-16 13:00:50 +08:00
* ( * datap ) argument changed
*/
static int _php_ibase_arr_zval ( zval * ar_zval , char * * datap , ibase_array * ib_array , int dim , int flag TSRMLS_DC )
2000-03-13 03:44:23 +08:00
{
2003-03-16 13:00:50 +08:00
zval tmp ;
2000-03-13 03:44:23 +08:00
int i , dim_len , l_bound , u_bound ;
1999-04-22 10:48:28 +08:00
2000-04-18 10:52:45 +08:00
if ( dim > 16 ) { /* InterBase limit */
2002-07-19 17:21:29 +08:00
_php_ibase_module_error ( " Too many dimensions " ) ;
2000-03-13 03:44:23 +08:00
return FAILURE ;
}
u_bound = ib_array - > ar_desc . array_desc_bounds [ dim ] . array_bound_upper ;
l_bound = ib_array - > ar_desc . array_desc_bounds [ dim ] . array_bound_lower ;
dim_len = 1 + u_bound - l_bound ;
if ( dim < ib_array - > ar_desc . array_desc_dimensions - 1 ) { /* array again */
for ( i = 0 ; i < dim_len ; i + + ) {
/* recursion here */
2003-03-16 13:00:50 +08:00
if ( _php_ibase_arr_zval ( ar_zval , datap , ib_array , dim + 1 , flag TSRMLS_CC ) = = FAILURE ) {
2000-03-13 03:44:23 +08:00
return FAILURE ;
}
}
2000-04-18 10:52:45 +08:00
} else { /* data at last */
2000-03-13 03:44:23 +08:00
2003-03-16 13:00:50 +08:00
array_init ( ar_zval ) ;
2000-03-13 03:44:23 +08:00
for ( i = 0 ; i < dim_len ; i + + ) {
2003-03-16 13:00:50 +08:00
if ( _php_ibase_var_zval ( & tmp , * datap ,
ib_array - > el_type ,
2000-03-13 03:44:23 +08:00
ib_array - > ar_desc . array_desc_length ,
ib_array - > ar_desc . array_desc_scale ,
2003-03-16 13:00:50 +08:00
flag TSRMLS_CC ) = = FAILURE ) {
2000-03-13 03:44:23 +08:00
return FAILURE ;
}
2000-05-15 05:55:45 +08:00
/* FIXME ??? */
2003-03-16 13:00:50 +08:00
zend_hash_index_update ( Z_ARRVAL_P ( ar_zval ) , l_bound + i , ( void * ) & tmp , sizeof ( zval ) , NULL ) ;
2000-03-13 03:44:23 +08:00
* datap + = ib_array - > el_size ;
}
}
return SUCCESS ;
}
2001-06-06 21:06:12 +08:00
/* }}} */
2000-03-13 03:44:23 +08:00
/* {{{ _php_ibase_fetch_hash() */
2002-03-15 23:26:01 +08:00
# define FETCH_ROW 2
# define FETCH_ARRAY 4
2000-03-13 03:44:23 +08:00
static void _php_ibase_fetch_hash ( INTERNAL_FUNCTION_PARAMETERS , int fetch_type )
{
2000-04-18 10:52:45 +08:00
zval * * result_arg , * * flag_arg ;
2000-03-13 03:44:23 +08:00
long flag = 0 ;
int i , arr_cnt ;
ibase_result * ib_result ;
XSQLVAR * var ;
2003-08-12 19:27:03 +08:00
RESET_ERRMSG ;
2003-03-16 13:00:50 +08:00
switch ( ZEND_NUM_ARGS ( ) ) {
2000-03-13 03:44:23 +08:00
case 1 :
2003-03-16 13:00:50 +08:00
if ( ZEND_NUM_ARGS ( ) = = 1 & & zend_get_parameters_ex ( 1 , & result_arg ) = = FAILURE ) {
2000-03-13 03:44:23 +08:00
RETURN_FALSE ;
}
break ;
case 2 :
2003-03-16 13:00:50 +08:00
if ( ZEND_NUM_ARGS ( ) = = 2 & & zend_get_parameters_ex ( 2 , & result_arg , & flag_arg ) = = FAILURE ) {
2000-03-13 03:44:23 +08:00
RETURN_FALSE ;
}
2000-04-18 10:52:45 +08:00
convert_to_long_ex ( flag_arg ) ;
2001-09-26 05:58:48 +08:00
flag = Z_LVAL_PP ( flag_arg ) ;
2000-03-13 03:44:23 +08:00
break ;
default :
WRONG_PARAM_COUNT ;
break ;
}
2000-04-18 10:52:45 +08:00
2000-10-05 20:47:39 +08:00
ZEND_FETCH_RESOURCE ( ib_result , ibase_result * , result_arg , - 1 , " InterBase result " , le_result ) ;
2000-04-18 10:52:45 +08:00
2003-08-12 18:02:25 +08:00
if ( ib_result - > out_sqlda = = NULL | | ! ib_result - > has_more_rows ) {
2000-03-13 03:44:23 +08:00
RETURN_FALSE ;
2003-08-12 19:27:03 +08:00
}
2003-08-13 10:19:14 +08:00
if ( ib_result - > statement_type ! = isc_info_sql_stmt_exec_procedure ) {
2003-08-12 19:27:03 +08:00
2003-08-13 10:19:14 +08:00
if ( isc_dsql_fetch ( IB_STATUS , & ib_result - > stmt , 1 , ib_result - > out_sqlda ) ) {
ib_result - > has_more_rows = 0 ;
if ( IB_STATUS [ 0 ] & & IB_STATUS [ 1 ] ) { /* error in fetch */
_php_ibase_error ( TSRMLS_C ) ;
}
RETURN_FALSE ;
2003-08-12 19:27:03 +08:00
}
2003-08-13 10:19:14 +08:00
} else {
ib_result - > has_more_rows = 0 ;
}
2003-03-16 13:00:50 +08:00
array_init ( return_value ) ;
2000-03-13 03:44:23 +08:00
arr_cnt = 0 ;
var = ib_result - > out_sqlda - > sqlvar ;
for ( i = 0 ; i < ib_result - > out_sqlda - > sqld ; i + + , var + + ) {
2000-04-18 10:52:45 +08:00
if ( ( ( var - > sqltype & 1 ) = = 0 ) | | * var - > sqlind ! = - 1 ) {
2003-03-16 13:00:50 +08:00
zval * tmp ;
tmp = emalloc ( sizeof ( zval ) ) ;
switch ( var - > sqltype & ~ 1 ) {
2000-03-13 03:44:23 +08:00
case SQL_VARYING :
case SQL_TEXT :
case SQL_SHORT :
case SQL_LONG :
case SQL_FLOAT :
case SQL_DOUBLE :
2000-05-10 04:30:23 +08:00
# ifdef SQL_INT64
case SQL_INT64 :
# endif
2000-05-12 11:02:14 +08:00
# ifndef SQL_TIMESTAMP
2000-03-13 03:44:23 +08:00
case SQL_DATE :
2000-05-12 11:02:14 +08:00
# else
case SQL_TIMESTAMP :
case SQL_TYPE_DATE :
case SQL_TYPE_TIME :
# endif
2003-03-16 13:00:50 +08:00
_php_ibase_var_zval ( tmp , var - > sqldata , var - > sqltype , var - > sqllen , var - > sqlscale , flag TSRMLS_CC ) ;
2000-03-13 03:44:23 +08:00
break ;
case SQL_BLOB :
if ( flag & PHP_IBASE_TEXT ) { /* text ? */
int stat ;
isc_blob_handle bl_handle = NULL ;
ISC_LONG max_len = 0 , cur_len = 0 ;
char bl_items [ 1 ] , * bl_data , bl_info [ 20 ] , * p ;
if ( isc_open_blob ( IB_STATUS , & ib_result - > link , & ib_result - > trans , & bl_handle , ( ISC_QUAD ISC_FAR * ) var - > sqldata ) ) {
2002-07-19 17:21:29 +08:00
_php_ibase_error ( TSRMLS_C ) ;
2003-08-12 19:27:03 +08:00
RETURN_FALSE ;
2000-03-13 03:44:23 +08:00
}
bl_items [ 0 ] = isc_info_blob_total_length ;
2001-08-12 00:39:07 +08:00
if ( isc_blob_info ( IB_STATUS , & bl_handle , sizeof ( bl_items ) , bl_items , sizeof ( bl_info ) , bl_info ) ) {
2002-07-19 17:21:29 +08:00
_php_ibase_error ( TSRMLS_C ) ;
2003-08-12 19:27:03 +08:00
RETURN_FALSE ;
2000-03-13 03:44:23 +08:00
}
/* find total length of blob's data */
2003-03-16 13:00:50 +08:00
for ( p = bl_info ; * p ! = isc_info_end & & p < bl_info + sizeof ( bl_info ) ; ) {
2000-07-18 04:51:47 +08:00
unsigned short item_len , item = * p + + ;
item_len = ( short ) isc_vax_integer ( p , 2 ) ;
2000-03-13 03:44:23 +08:00
p + = 2 ;
2003-03-16 13:00:50 +08:00
if ( item = = isc_info_blob_total_length ) {
2000-03-13 03:44:23 +08:00
max_len = isc_vax_integer ( p , item_len ) ;
2003-03-16 13:00:50 +08:00
}
2000-03-13 03:44:23 +08:00
p + = item_len ;
}
bl_data = emalloc ( max_len + 1 ) ;
2003-03-16 13:00:50 +08:00
for ( cur_len = stat = 0 ; stat = = 0 & & cur_len < max_len ; ) {
2000-07-18 04:51:47 +08:00
unsigned short seg_len ;
unsigned short max_seg = ( unsigned short ) ( max_len - cur_len > USHRT_MAX ? USHRT_MAX : max_len - cur_len ) ;
2003-03-16 13:00:50 +08:00
2000-03-13 03:44:23 +08:00
stat = isc_get_segment ( IB_STATUS , & bl_handle , & seg_len , max_seg , & bl_data [ cur_len ] ) ;
cur_len + = seg_len ;
2003-03-16 13:00:50 +08:00
if ( cur_len > max_len ) { /* never! */
2000-03-13 03:44:23 +08:00
efree ( bl_data ) ;
2002-07-19 17:21:29 +08:00
_php_ibase_module_error ( " PHP module internal error " ) ;
2003-08-12 19:27:03 +08:00
RETURN_FALSE ;
2000-03-13 03:44:23 +08:00
}
}
if ( IB_STATUS [ 0 ] & & IB_STATUS [ 1 ] & & ( IB_STATUS [ 1 ] ! = isc_segstr_eof ) ) {
efree ( bl_data ) ;
2002-07-19 17:21:29 +08:00
_php_ibase_error ( TSRMLS_C ) ;
2003-08-12 19:27:03 +08:00
RETURN_FALSE ;
2000-03-13 03:44:23 +08:00
}
bl_data [ cur_len ] = ' \0 ' ;
if ( isc_close_blob ( IB_STATUS , & bl_handle ) ) {
efree ( bl_data ) ;
2002-07-19 17:21:29 +08:00
_php_ibase_error ( TSRMLS_C ) ;
2000-03-13 03:44:23 +08:00
RETURN_FALSE ;
}
2001-09-26 05:58:48 +08:00
Z_TYPE_P ( tmp ) = IS_STRING ;
Z_STRLEN_P ( tmp ) = cur_len ;
Z_STRVAL_P ( tmp ) = estrndup ( bl_data , cur_len ) ;
2000-04-18 10:52:45 +08:00
efree ( bl_data ) ;
2003-03-16 13:00:50 +08:00
2000-03-13 03:44:23 +08:00
} else { /* blob id only */
ISC_QUAD * bl_qd = ( ISC_QUAD ISC_FAR * ) var - > sqldata ;
ibase_blob_handle * ib_blob_id ;
ib_blob_id = ( ibase_blob_handle * ) emalloc ( sizeof ( ibase_blob_handle ) ) ;
ib_blob_id - > link = ib_result - > link ;
ib_blob_id - > trans_handle = ib_result - > trans ;
ib_blob_id - > bl_qd . gds_quad_high = bl_qd - > gds_quad_high ;
ib_blob_id - > bl_qd . gds_quad_low = bl_qd - > gds_quad_low ;
ib_blob_id - > bl_handle = NULL ;
2001-09-26 05:58:48 +08:00
Z_TYPE_P ( tmp ) = IS_STRING ;
Z_STRLEN_P ( tmp ) = sizeof ( ibase_blob_handle ) ;
2003-03-16 13:00:50 +08:00
Z_STRVAL_P ( tmp ) = estrndup ( ( char * ) ib_blob_id , sizeof ( ibase_blob_handle ) ) ;
2000-04-18 10:52:45 +08:00
efree ( ib_blob_id ) ;
2000-03-13 03:44:23 +08:00
}
break ;
2003-03-16 13:00:50 +08:00
case SQL_ARRAY : {
2000-03-13 03:44:23 +08:00
ISC_QUAD ar_qd = * ( ISC_QUAD ISC_FAR * ) var - > sqldata ;
ibase_array * ib_array = & ib_result - > out_array [ arr_cnt ] ;
void * ar_data ;
char * tmp_ptr ;
ar_data = emalloc ( ib_array - > ar_size ) ;
2003-03-16 13:00:50 +08:00
if ( isc_array_get_slice ( IB_STATUS , & ib_result - > link , & ib_result - > trans , & ar_qd , & ib_array - > ar_desc , ar_data , & ib_array - > ar_size ) ) {
2002-07-19 17:21:29 +08:00
_php_ibase_error ( TSRMLS_C ) ;
2003-08-05 21:17:16 +08:00
efree ( ar_data ) ;
2003-08-12 19:27:03 +08:00
RETURN_FALSE ;
2000-03-13 03:44:23 +08:00
}
2003-03-16 13:00:50 +08:00
tmp_ptr = ar_data ; /* avoid changes in _arr_zval */
if ( _php_ibase_arr_zval ( tmp , & tmp_ptr , ib_array , 0 , flag TSRMLS_CC ) = = FAILURE ) {
2003-08-05 21:17:16 +08:00
efree ( ar_data ) ;
2003-08-12 19:27:03 +08:00
RETURN_FALSE ;
2000-03-13 03:44:23 +08:00
}
efree ( ar_data ) ;
}
break ;
default :
break ;
2003-03-16 13:00:50 +08:00
} /* switch */
2002-03-15 23:26:01 +08:00
if ( fetch_type & FETCH_ROW ) {
2001-09-26 05:58:48 +08:00
switch ( Z_TYPE_P ( tmp ) ) {
2003-03-16 13:00:50 +08:00
case IS_STRING :
add_index_stringl ( return_value , i , Z_STRVAL_P ( tmp ) , Z_STRLEN_P ( tmp ) , 0 ) ;
break ;
case IS_LONG :
add_index_long ( return_value , i , Z_LVAL_P ( tmp ) ) ;
break ;
case IS_DOUBLE :
add_index_double ( return_value , i , Z_DVAL_P ( tmp ) ) ;
break ;
2000-04-18 10:52:45 +08:00
}
2000-03-13 03:44:23 +08:00
} else {
2001-09-26 05:58:48 +08:00
switch ( Z_TYPE_P ( tmp ) ) {
2003-03-16 13:00:50 +08:00
case IS_STRING :
add_assoc_stringl ( return_value , var - > aliasname , Z_STRVAL_P ( tmp ) , Z_STRLEN_P ( tmp ) , 0 ) ;
break ;
case IS_LONG :
add_assoc_long ( return_value , var - > aliasname , Z_LVAL_P ( tmp ) ) ;
break ;
case IS_DOUBLE :
add_assoc_double ( return_value , var - > aliasname , Z_DVAL_P ( tmp ) ) ;
break ;
2000-04-18 10:52:45 +08:00
}
2000-03-13 03:44:23 +08:00
}
2000-04-18 10:52:45 +08:00
efree ( tmp ) ;
2002-03-01 22:03:10 +08:00
} else {
2002-03-15 23:26:01 +08:00
if ( fetch_type & FETCH_ROW ) {
2002-03-01 22:03:10 +08:00
add_index_null ( return_value , i ) ;
} else {
2002-03-15 23:26:01 +08:00
add_assoc_null ( return_value , var - > aliasname ) ;
2002-03-01 22:03:10 +08:00
}
}
2000-03-13 03:44:23 +08:00
if ( ( var - > sqltype & ~ 1 ) = = SQL_ARRAY ) {
arr_cnt + + ;
}
2003-03-16 13:00:50 +08:00
} /* for field */
2000-03-13 03:44:23 +08:00
}
/* }}} */
2003-06-12 19:24:24 +08:00
/* {{{ proto array ibase_fetch_row(resource result [, int blob_flag])
2000-03-13 03:44:23 +08:00
Fetch a row from the results of a query */
PHP_FUNCTION ( ibase_fetch_row )
2002-03-15 23:26:01 +08:00
{
_php_ibase_fetch_hash ( INTERNAL_FUNCTION_PARAM_PASSTHRU , FETCH_ROW ) ;
}
/* }}} */
2003-06-12 19:24:24 +08:00
/* {{{ proto array ibase_fetch_assoc(resource result [, int blob_flag])
2002-03-15 23:26:01 +08:00
Fetch a row from the results of a query */
PHP_FUNCTION ( ibase_fetch_assoc )
2000-03-13 03:44:23 +08:00
{
_php_ibase_fetch_hash ( INTERNAL_FUNCTION_PARAM_PASSTHRU , FETCH_ARRAY ) ;
}
/* }}} */
2003-06-12 19:24:24 +08:00
/* {{{ proto object ibase_fetch_object(resource result [, int blob_flag])
2000-03-13 03:44:23 +08:00
Fetch a object from the results of a query */
PHP_FUNCTION ( ibase_fetch_object )
{
2002-03-15 23:26:01 +08:00
_php_ibase_fetch_hash ( INTERNAL_FUNCTION_PARAM_PASSTHRU , FETCH_ARRAY ) ;
2003-03-16 13:00:50 +08:00
2002-03-15 23:26:01 +08:00
if ( Z_TYPE_P ( return_value ) = = IS_ARRAY ) {
2003-01-15 11:37:11 +08:00
object_and_properties_init ( return_value , ZEND_STANDARD_CLASS_DEF_PTR , Z_ARRVAL_P ( return_value ) ) ;
2002-03-15 23:26:01 +08:00
}
2000-03-13 03:44:23 +08:00
}
/* }}} */
1999-04-22 10:48:28 +08:00
2003-08-07 01:51:46 +08:00
/* {{{ proto bool ibase_name_result(resource result, string name)
Assign a name to a result for use with . . . WHERE CURRENT OF < name > statements */
PHP_FUNCTION ( ibase_name_result )
{
zval * * result_arg , * * name_arg ;
ibase_result * ib_result ;
RESET_ERRMSG ;
if ( ZEND_NUM_ARGS ( ) ! = 2 | | zend_get_parameters_ex ( 2 , & result_arg , & name_arg ) = = FAILURE ) {
WRONG_PARAM_COUNT ;
}
ZEND_FETCH_RESOURCE ( ib_result , ibase_result * , result_arg , - 1 , " InterBase result " , le_result ) ;
convert_to_string_ex ( name_arg ) ;
if ( isc_dsql_set_cursor_name ( IB_STATUS , & ib_result - > stmt , Z_STRVAL_PP ( name_arg ) , 0 ) ) {
_php_ibase_error ( TSRMLS_C ) ;
RETURN_FALSE ;
}
RETURN_TRUE ;
}
/* }}} */
2003-06-12 19:24:24 +08:00
/* {{{ proto bool ibase_free_result(resource result)
2000-03-13 03:44:23 +08:00
Free the memory used by a result */
PHP_FUNCTION ( ibase_free_result )
{
2000-04-18 10:52:45 +08:00
zval * * result_arg ;
2000-03-13 03:44:23 +08:00
ibase_result * ib_result ;
RESET_ERRMSG ;
2003-03-16 13:00:50 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 1 | | zend_get_parameters_ex ( 1 , & result_arg ) = = FAILURE ) {
2000-03-13 03:44:23 +08:00
WRONG_PARAM_COUNT ;
}
2000-04-30 13:46:04 +08:00
2000-10-05 20:47:39 +08:00
ZEND_FETCH_RESOURCE ( ib_result , ibase_result * , result_arg , - 1 , " InterBase result " , le_result ) ;
2001-09-26 05:58:48 +08:00
zend_list_delete ( Z_LVAL_PP ( result_arg ) ) ;
2000-03-13 03:44:23 +08:00
RETURN_TRUE ;
}
/* }}} */
1999-04-22 10:48:28 +08:00
2003-06-12 19:24:24 +08:00
/* {{{ proto resource ibase_prepare([resource link_identifier, ] string query)
2000-03-13 03:44:23 +08:00
Prepare a query for later execution */
PHP_FUNCTION ( ibase_prepare )
{
2003-08-05 21:17:16 +08:00
zval * * link_arg , * * trans_arg , * * query_arg ;
2000-03-13 03:44:23 +08:00
ibase_db_link * ib_link ;
2003-08-05 21:17:16 +08:00
ibase_trans * trans = NULL ;
2003-08-13 02:01:59 +08:00
int trans_res_id = 0 ;
2000-03-13 03:44:23 +08:00
ibase_query * ib_query ;
char * query ;
RESET_ERRMSG ;
2000-06-06 03:47:54 +08:00
switch ( ZEND_NUM_ARGS ( ) ) {
2000-03-13 03:44:23 +08:00
case 1 :
2000-04-30 13:46:04 +08:00
if ( zend_get_parameters_ex ( 1 , & query_arg ) = = FAILURE ) {
1999-04-22 10:48:28 +08:00
RETURN_FALSE ;
}
2003-08-05 21:17:16 +08:00
ZEND_FETCH_RESOURCE2 ( ib_link , ibase_db_link * , NULL , IBG ( default_link ) , " InterBase link " , le_link , le_plink ) ;
2000-03-13 03:44:23 +08:00
break ;
case 2 :
2000-04-30 13:46:04 +08:00
if ( zend_get_parameters_ex ( 2 , & link_arg , & query_arg ) = = FAILURE ) {
2000-03-13 03:44:23 +08:00
RETURN_FALSE ;
}
2003-08-05 21:17:16 +08:00
_php_ibase_get_link_trans ( INTERNAL_FUNCTION_PARAM_PASSTHRU , link_arg , & ib_link , & trans ) ;
2003-08-13 02:01:59 +08:00
if ( trans ! = NULL ) {
convert_to_long_ex ( link_arg ) ;
trans_res_id = Z_LVAL_PP ( link_arg ) ;
}
2000-03-13 03:44:23 +08:00
break ;
2003-08-05 21:17:16 +08:00
case 3 :
if ( zend_get_parameters_ex ( 3 , & link_arg , & trans_arg , & query_arg ) = = FAILURE ) {
RETURN_FALSE ;
}
ZEND_FETCH_RESOURCE2 ( ib_link , ibase_db_link * , link_arg , - 1 , " InterBase link " , le_link , le_plink ) ;
ZEND_FETCH_RESOURCE ( trans , ibase_trans * , trans_arg , - 1 , " InterBase transaction " , le_trans ) ;
2003-08-13 02:01:59 +08:00
convert_to_long_ex ( trans_arg ) ;
trans_res_id = Z_LVAL_PP ( trans_arg ) ;
2003-08-05 21:17:16 +08:00
break ;
2000-03-13 03:44:23 +08:00
default :
WRONG_PARAM_COUNT ;
break ;
}
2000-04-30 13:46:04 +08:00
convert_to_string_ex ( query_arg ) ;
2001-09-26 05:58:48 +08:00
query = Z_STRVAL_PP ( query_arg ) ;
2000-03-13 03:44:23 +08:00
/* open default transaction */
2003-08-05 21:17:16 +08:00
if ( _php_ibase_def_trans ( ib_link , & trans TSRMLS_CC ) = = FAILURE ) {
2000-03-13 03:44:23 +08:00
RETURN_FALSE ;
}
2003-08-13 02:01:59 +08:00
if ( _php_ibase_alloc_query ( & ib_query , ib_link , trans , query , ib_link - > dialect , trans_res_id TSRMLS_CC ) = = FAILURE ) {
2000-03-13 03:44:23 +08:00
RETURN_FALSE ;
}
2000-06-25 00:24:29 +08:00
ib_query - > cursor_open = 0 ;
2000-04-30 13:46:04 +08:00
2000-10-05 20:47:39 +08:00
ZEND_REGISTER_RESOURCE ( return_value , ib_query , le_query ) ;
2000-03-13 03:44:23 +08:00
}
/* }}} */
2003-06-12 19:24:24 +08:00
/* {{{ proto resource ibase_execute(resource query [, int bind_args [, int ...]])
2000-03-13 03:44:23 +08:00
Execute a previously prepared query */
PHP_FUNCTION ( ibase_execute )
{
2003-03-16 13:00:50 +08:00
zval * * * args , * * bind_args = NULL ;
2000-03-13 03:44:23 +08:00
ibase_query * ib_query ;
2003-08-13 02:01:59 +08:00
ibase_result * ib_result = NULL ;
2000-03-13 03:44:23 +08:00
RESET_ERRMSG ;
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) < 1 ) {
2000-03-13 03:44:23 +08:00
WRONG_PARAM_COUNT ;
}
2003-08-05 21:17:16 +08:00
/* use stack to avoid leaks */
args = ( zval * * * ) do_alloca ( ZEND_NUM_ARGS ( ) * sizeof ( zval * * ) ) ;
2000-06-06 03:47:54 +08:00
if ( zend_get_parameters_array_ex ( ZEND_NUM_ARGS ( ) , args ) = = FAILURE ) {
2003-08-06 07:40:30 +08:00
free_alloca ( args ) ;
2000-03-13 03:44:23 +08:00
RETURN_FALSE ;
}
2000-10-05 20:47:39 +08:00
ZEND_FETCH_RESOURCE ( ib_query , ibase_query * , args [ 0 ] , - 1 , " InterBase query " , le_query ) ;
2000-04-30 13:46:04 +08:00
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) > 1 ) { /* have variables to bind */
2000-04-30 13:46:04 +08:00
bind_args = args [ 1 ] ;
2000-03-13 03:44:23 +08:00
}
2000-06-25 00:24:29 +08:00
/* Have we used this cursor before and it's still open? */
if ( ib_query - > cursor_open ) {
IBDEBUG ( " Implicitly closing a cursor " ) ;
2003-03-16 13:00:50 +08:00
if ( isc_dsql_free_statement ( IB_STATUS , & ib_query - > stmt , DSQL_close ) ) {
2002-07-19 17:21:29 +08:00
_php_ibase_error ( TSRMLS_C ) ;
2000-06-25 00:24:29 +08:00
}
}
2003-08-13 02:01:59 +08:00
if ( _php_ibase_exec ( INTERNAL_FUNCTION_PARAM_PASSTHRU , & ib_result , ib_query , ZEND_NUM_ARGS ( ) - 1 , bind_args ) = = FAILURE ) {
2003-08-07 01:51:46 +08:00
free_alloca ( args ) ;
2000-03-13 03:44:23 +08:00
RETURN_FALSE ;
}
2003-08-13 02:01:59 +08:00
/* free the query if trans handle was released */
if ( ib_query - > trans - > handle = = NULL ) {
zend_list_delete ( Z_LVAL_PP ( args [ 0 ] ) ) ;
}
2003-08-07 01:51:46 +08:00
free_alloca ( args ) ;
2000-03-13 03:44:23 +08:00
if ( ib_result ) { /* select statement */
2000-06-25 00:24:29 +08:00
ib_query - > cursor_open = 1 ;
2003-08-11 00:21:26 +08:00
ib_result - > has_more_rows = 1 ;
2000-10-05 20:47:39 +08:00
ZEND_REGISTER_RESOURCE ( return_value , ib_result , le_result ) ;
2000-04-30 13:46:04 +08:00
} else {
2000-06-25 00:24:29 +08:00
ib_query - > cursor_open = 0 ;
2000-03-13 03:44:23 +08:00
}
}
/* }}} */
2003-06-12 19:24:24 +08:00
/* {{{ proto bool ibase_free_query(resource query)
2000-03-13 03:44:23 +08:00
Free memory used by a query */
PHP_FUNCTION ( ibase_free_query )
{
2003-03-16 13:00:50 +08:00
zval * * query_arg ;
2000-03-13 03:44:23 +08:00
ibase_query * ib_query ;
RESET_ERRMSG ;
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 1 | | zend_get_parameters_ex ( 1 , & query_arg ) = = FAILURE ) {
2000-03-13 03:44:23 +08:00
WRONG_PARAM_COUNT ;
}
2000-10-05 20:47:39 +08:00
ZEND_FETCH_RESOURCE ( ib_query , ibase_query * , query_arg , - 1 , " InterBase query " , le_query ) ;
2001-09-26 05:58:48 +08:00
zend_list_delete ( Z_LVAL_PP ( query_arg ) ) ;
2000-03-13 03:44:23 +08:00
RETURN_TRUE ;
}
/* }}} */
2002-07-19 17:21:29 +08:00
# if HAVE_STRFTIME
2000-03-13 03:44:23 +08:00
/* {{{ proto int ibase_timefmt(string format)
2000-05-12 11:02:14 +08:00
Sets the format of timestamp , date and time columns returned from queries */
2000-03-13 03:44:23 +08:00
PHP_FUNCTION ( ibase_timefmt )
{
2003-03-16 13:00:50 +08:00
zval * * * args ;
2000-05-12 11:02:14 +08:00
char * fmt = NULL ;
int type = PHP_IBASE_TIMESTAMP ;
2000-03-13 03:44:23 +08:00
2000-05-12 11:02:14 +08:00
RESET_ERRMSG ; /* ??? */
2000-03-13 03:44:23 +08:00
2003-03-16 13:00:50 +08:00
if ( ZEND_NUM_ARGS ( ) < 1 | | ZEND_NUM_ARGS ( ) > 2 ) {
2000-03-13 03:44:23 +08:00
WRONG_PARAM_COUNT ;
}
2000-05-12 11:02:14 +08:00
2003-08-12 08:58:52 +08:00
args = ( zval * * * ) safe_emalloc ( sizeof ( zval * * ) , ZEND_NUM_ARGS ( ) , 0 ) ;
2000-06-06 03:47:54 +08:00
if ( zend_get_parameters_array_ex ( ZEND_NUM_ARGS ( ) , args ) = = FAILURE ) {
2000-05-12 11:02:14 +08:00
efree ( args ) ;
RETURN_FALSE ;
}
2000-06-06 03:47:54 +08:00
switch ( ZEND_NUM_ARGS ( ) ) {
2000-05-12 11:02:14 +08:00
case 2 :
convert_to_long_ex ( args [ 1 ] ) ;
2001-09-26 06:49:04 +08:00
type = Z_LVAL_PP ( args [ 1 ] ) ;
2000-05-12 11:02:14 +08:00
case 1 :
convert_to_string_ex ( args [ 0 ] ) ;
2001-09-26 06:49:04 +08:00
fmt = Z_STRVAL_PP ( args [ 0 ] ) ;
2000-05-12 11:02:14 +08:00
}
switch ( type ) {
case PHP_IBASE_TIMESTAMP :
2003-03-16 13:00:50 +08:00
if ( IBG ( timestampformat ) ) {
2000-05-12 11:02:14 +08:00
DL_FREE ( IBG ( timestampformat ) ) ;
2003-03-16 13:00:50 +08:00
}
2000-05-12 11:02:14 +08:00
IBG ( timestampformat ) = DL_STRDUP ( fmt ) ;
break ;
case PHP_IBASE_DATE :
2003-03-16 13:00:50 +08:00
if ( IBG ( dateformat ) ) {
2000-05-12 11:02:14 +08:00
DL_FREE ( IBG ( dateformat ) ) ;
2003-03-16 13:00:50 +08:00
}
2000-05-12 11:02:14 +08:00
IBG ( dateformat ) = DL_STRDUP ( fmt ) ;
break ;
case PHP_IBASE_TIME :
2003-03-16 13:00:50 +08:00
if ( IBG ( timeformat ) ) {
2000-05-12 11:02:14 +08:00
DL_FREE ( IBG ( timeformat ) ) ;
2003-03-16 13:00:50 +08:00
}
2000-05-12 11:02:14 +08:00
IBG ( timeformat ) = DL_STRDUP ( fmt ) ;
break ;
}
2003-03-16 13:00:50 +08:00
2000-05-12 11:02:14 +08:00
efree ( args ) ;
2000-03-13 03:44:23 +08:00
RETURN_TRUE ;
}
/* }}} */
2002-07-19 17:21:29 +08:00
# endif
2000-03-13 03:44:23 +08:00
2003-08-11 04:53:19 +08:00
/* {{{ proto int ibase_num_fields(resource {query|result})
2000-03-13 03:44:23 +08:00
Get the number of fields in result */
PHP_FUNCTION ( ibase_num_fields )
{
2003-03-16 13:00:50 +08:00
zval * * result ;
2003-08-11 04:53:19 +08:00
int type ;
XSQLDA * sqlda ;
2000-03-13 03:44:23 +08:00
RESET_ERRMSG ;
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 1 | | zend_get_parameters_ex ( 1 , & result ) = = FAILURE ) {
2000-03-13 03:44:23 +08:00
WRONG_PARAM_COUNT ;
}
2003-08-11 04:53:19 +08:00
zend_list_find ( Z_LVAL_PP ( result ) , & type ) ;
if ( type = = le_query ) {
ibase_query * ib_query ;
2000-03-13 03:44:23 +08:00
2003-08-11 04:53:19 +08:00
ZEND_FETCH_RESOURCE ( ib_query , ibase_query * , result , - 1 , " InterBase query " , le_query ) ;
sqlda = ib_query - > out_sqlda ;
} else {
ibase_result * ib_result ;
ZEND_FETCH_RESOURCE ( ib_result , ibase_result * , result , - 1 , " InterBase result " , le_result ) ;
sqlda = ib_result - > out_sqlda ;
}
2000-03-13 03:44:23 +08:00
2003-08-11 04:53:19 +08:00
if ( sqlda = = NULL ) {
RETURN_LONG ( 0 ) ;
} else {
RETURN_LONG ( sqlda - > sqld ) ;
}
2000-03-13 03:44:23 +08:00
}
/* }}} */
2003-06-12 19:24:24 +08:00
/* {{{ proto array ibase_field_info(resource result, int field_number)
2000-03-13 03:44:23 +08:00
Get information about a field */
PHP_FUNCTION ( ibase_field_info )
{
2003-03-16 13:00:50 +08:00
zval * ret_val ;
2000-04-18 10:52:45 +08:00
zval * * result_arg , * * field_arg ;
2000-03-13 03:44:23 +08:00
ibase_result * ib_result ;
char buf [ 30 ] , * s ;
int len ;
XSQLVAR * var ;
RESET_ERRMSG ;
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 2 | | zend_get_parameters_ex ( 2 , & result_arg , & field_arg ) = = FAILURE ) {
2000-03-13 03:44:23 +08:00
WRONG_PARAM_COUNT ;
}
2000-10-05 20:47:39 +08:00
ZEND_FETCH_RESOURCE ( ib_result , ibase_result * , result_arg , - 1 , " InterBase result " , le_result ) ;
2000-04-18 10:52:45 +08:00
2000-03-13 03:44:23 +08:00
if ( ib_result - > out_sqlda = = NULL ) {
2002-07-19 17:21:29 +08:00
_php_ibase_module_error ( " Trying to get field info from a non-select query " ) ;
2000-03-13 03:44:23 +08:00
RETURN_FALSE ;
}
2000-04-18 10:52:45 +08:00
convert_to_long_ex ( field_arg ) ;
2000-03-13 03:44:23 +08:00
2003-03-16 13:00:50 +08:00
if ( Z_LVAL_PP ( field_arg ) < 0 | | Z_LVAL_PP ( field_arg ) > = ib_result - > out_sqlda - > sqld ) {
2000-03-13 03:44:23 +08:00
RETURN_FALSE ;
2003-03-16 13:00:50 +08:00
}
2003-01-19 03:41:56 +08:00
array_init ( return_value ) ;
2000-03-13 03:44:23 +08:00
2001-09-26 05:58:48 +08:00
var = ib_result - > out_sqlda - > sqlvar + Z_LVAL_PP ( field_arg ) ;
2000-03-13 03:44:23 +08:00
add_get_index_stringl ( return_value , 0 , var - > sqlname , var - > sqlname_length , ( void * * ) & ret_val , 1 ) ;
2000-05-15 05:55:45 +08:00
add_assoc_stringl ( return_value , " name " , var - > sqlname , var - > sqlname_length , 1 ) ;
2000-03-13 03:44:23 +08:00
add_get_index_stringl ( return_value , 1 , var - > aliasname , var - > aliasname_length , ( void * * ) & ret_val , 1 ) ;
2000-05-15 05:55:45 +08:00
add_assoc_stringl ( return_value , " alias " , var - > aliasname , var - > aliasname_length , 1 ) ;
2000-03-13 03:44:23 +08:00
add_get_index_stringl ( return_value , 2 , var - > relname , var - > relname_length , ( void * * ) & ret_val , 1 ) ;
2000-05-15 05:55:45 +08:00
add_assoc_stringl ( return_value , " relation " , var - > relname , var - > relname_length , 1 ) ;
2000-03-13 03:44:23 +08:00
len = sprintf ( buf , " %d " , var - > sqllen ) ;
add_get_index_stringl ( return_value , 3 , buf , len , ( void * * ) & ret_val , 1 ) ;
2000-05-15 05:55:45 +08:00
add_assoc_stringl ( return_value , " length " , buf , len , 1 ) ;
2000-03-13 03:44:23 +08:00
2000-04-18 10:52:45 +08:00
switch ( var - > sqltype & ~ 1 ) {
2000-05-12 11:02:14 +08:00
case SQL_TEXT : s = " TEXT " ; break ;
case SQL_VARYING : s = " VARYING " ; break ;
case SQL_SHORT : s = " SHORT " ; break ;
case SQL_LONG : s = " LONG " ; break ;
case SQL_FLOAT : s = " FLOAT " ; break ;
case SQL_DOUBLE : s = " DOUBLE " ; break ;
case SQL_D_FLOAT : s = " D_FLOAT " ; break ;
# ifdef SQL_INT64
case SQL_INT64 : s = " INT64 " ; break ;
# endif
# ifdef SQL_TIMESTAMP
case SQL_TIMESTAMP : s = " TIMESTAMP " ; break ;
case SQL_TYPE_DATE : s = " DATE " ; break ;
case SQL_TYPE_TIME : s = " TIME " ; break ;
# else
case SQL_DATE : s = " DATE " ; break ;
# endif
case SQL_BLOB : s = " BLOB " ; break ;
case SQL_ARRAY : s = " ARRAY " ; break ;
case SQL_QUAD : s = " QUAD " ; break ;
2000-03-13 03:44:23 +08:00
default :
2001-08-12 00:39:07 +08:00
sprintf ( buf , " unknown (%d) " , var - > sqltype & ~ 1 ) ;
2000-03-13 03:44:23 +08:00
s = buf ;
break ;
}
add_get_index_stringl ( return_value , 4 , s , strlen ( s ) , ( void * * ) & ret_val , 1 ) ;
2000-05-15 05:55:45 +08:00
add_assoc_stringl ( return_value , " type " , s , strlen ( s ) , 1 ) ;
2003-08-11 04:53:19 +08:00
}
/* }}} */
/* {{{ proto int ibase_num_params(resource query)
Get the number of params in a prepared query */
PHP_FUNCTION ( ibase_num_params )
{
zval * * result ;
ibase_query * ib_query ;
RESET_ERRMSG ;
if ( ZEND_NUM_ARGS ( ) ! = 1 | | zend_get_parameters_ex ( 1 , & result ) = = FAILURE ) {
WRONG_PARAM_COUNT ;
}
ZEND_FETCH_RESOURCE ( ib_query , ibase_query * , result , - 1 , " InterBase query " , le_query ) ;
if ( ib_query - > in_sqlda = = NULL ) {
RETURN_LONG ( 0 ) ;
} else {
RETURN_LONG ( ib_query - > in_sqlda - > sqld ) ;
}
}
/* }}} */
/* {{{ proto array ibase_param_info(resource query, int field_number)
Get information about a parameter */
PHP_FUNCTION ( ibase_param_info )
{
zval * ret_val ;
zval * * result_arg , * * field_arg ;
ibase_query * ib_query ;
char buf [ 30 ] , * s ;
int len ;
XSQLVAR * var ;
RESET_ERRMSG ;
if ( ZEND_NUM_ARGS ( ) ! = 2 | | zend_get_parameters_ex ( 2 , & result_arg , & field_arg ) = = FAILURE ) {
WRONG_PARAM_COUNT ;
}
ZEND_FETCH_RESOURCE ( ib_query , ibase_query * , result_arg , - 1 , " InterBase query " , le_query ) ;
if ( ib_query - > in_sqlda = = NULL ) {
RETURN_FALSE ;
}
convert_to_long_ex ( field_arg ) ;
if ( Z_LVAL_PP ( field_arg ) < 0 | | Z_LVAL_PP ( field_arg ) > = ib_query - > in_sqlda - > sqld ) {
RETURN_FALSE ;
}
array_init ( return_value ) ;
var = ib_query - > in_sqlda - > sqlvar + Z_LVAL_PP ( field_arg ) ;
len = sprintf ( buf , " %d " , var - > sqllen ) ;
add_get_index_stringl ( return_value , 0 , buf , len , ( void * * ) & ret_val , 1 ) ;
add_assoc_stringl ( return_value , " length " , buf , len , 1 ) ;
switch ( var - > sqltype & ~ 1 ) {
case SQL_TEXT : s = " TEXT " ; break ;
case SQL_VARYING : s = " VARYING " ; break ;
case SQL_SHORT : s = " SHORT " ; break ;
case SQL_LONG : s = " LONG " ; break ;
case SQL_FLOAT : s = " FLOAT " ; break ;
case SQL_DOUBLE : s = " DOUBLE " ; break ;
case SQL_D_FLOAT : s = " D_FLOAT " ; break ;
# ifdef SQL_INT64
case SQL_INT64 : s = " INT64 " ; break ;
# endif
# ifdef SQL_TIMESTAMP
case SQL_TIMESTAMP : s = " TIMESTAMP " ; break ;
case SQL_TYPE_DATE : s = " DATE " ; break ;
case SQL_TYPE_TIME : s = " TIME " ; break ;
# else
case SQL_DATE : s = " DATE " ; break ;
# endif
case SQL_BLOB : s = " BLOB " ; break ;
case SQL_ARRAY : s = " ARRAY " ; break ;
case SQL_QUAD : s = " QUAD " ; break ;
default :
sprintf ( buf , " unknown (%d) " , var - > sqltype & ~ 1 ) ;
s = buf ;
break ;
}
add_get_index_stringl ( return_value , 1 , s , strlen ( s ) , ( void * * ) & ret_val , 1 ) ;
add_assoc_stringl ( return_value , " type " , s , strlen ( s ) , 1 ) ;
2000-03-13 03:44:23 +08:00
}
/* }}} */
/* blobs ----------------------------------- */
2001-08-12 00:39:07 +08:00
/* {{{ _php_ibase_blob_info(isc_blob_handle bl_handle, IBASE_BLOBINFO *bl_info) */
2003-03-16 13:00:50 +08:00
static int _php_ibase_blob_info ( isc_blob_handle bl_handle , IBASE_BLOBINFO * bl_info TSRMLS_DC )
2000-03-13 03:44:23 +08:00
{
static char bl_items [ ] = {
isc_info_blob_num_segments ,
isc_info_blob_max_segment ,
isc_info_blob_total_length ,
isc_info_blob_type
} ;
char bl_inf [ sizeof ( long ) * 8 ] , * p ;
bl_info - > max_segment = 0 ;
bl_info - > num_segments = 0 ;
bl_info - > total_length = 0 ;
bl_info - > bl_stream = 0 ;
2001-08-12 00:39:07 +08:00
if ( isc_blob_info ( IB_STATUS , & bl_handle , sizeof ( bl_items ) , bl_items , sizeof ( bl_inf ) , bl_inf ) ) {
2002-07-19 17:21:29 +08:00
_php_ibase_error ( TSRMLS_C ) ;
2000-03-13 03:44:23 +08:00
return FAILURE ;
}
2003-03-16 13:00:50 +08:00
for ( p = bl_inf ; * p ! = isc_info_end & & p < bl_inf + sizeof ( bl_inf ) ; ) {
2000-07-18 04:51:47 +08:00
unsigned short item_len ;
int item = * p + + ;
2003-03-16 13:00:50 +08:00
item_len = ( short ) isc_vax_integer ( p , 2 ) ;
2000-03-13 03:44:23 +08:00
p + = 2 ;
2000-04-18 10:52:45 +08:00
switch ( item ) {
2000-03-13 03:44:23 +08:00
case isc_info_blob_num_segments :
bl_info - > num_segments = isc_vax_integer ( p , item_len ) ;
break ;
case isc_info_blob_max_segment :
bl_info - > max_segment = isc_vax_integer ( p , item_len ) ;
break ;
case isc_info_blob_total_length :
bl_info - > total_length = isc_vax_integer ( p , item_len ) ;
break ;
case isc_info_blob_type :
bl_info - > bl_stream = isc_vax_integer ( p , item_len ) ;
break ;
case isc_info_end :
break ;
case isc_info_truncated :
case isc_info_error : /* hmm. don't think so...*/
2002-07-19 17:21:29 +08:00
_php_ibase_module_error ( " PHP module internal error " ) ;
2000-03-13 03:44:23 +08:00
return FAILURE ;
2003-03-16 13:00:50 +08:00
} /* switch */
2000-03-13 03:44:23 +08:00
p + = item_len ;
2003-03-16 13:00:50 +08:00
} /* for */
2000-03-13 03:44:23 +08:00
return SUCCESS ;
}
/* }}} */
2003-06-12 19:24:24 +08:00
/* {{{ proto int ibase_blob_create([resource link_identifier])
2000-03-13 03:44:23 +08:00
Create blob for adding data */
PHP_FUNCTION ( ibase_blob_create )
{
2000-07-07 20:06:05 +08:00
zval * * link_arg ;
2000-03-13 03:44:23 +08:00
ibase_db_link * ib_link ;
2003-08-05 21:17:16 +08:00
ibase_trans * trans = NULL ;
2000-03-13 03:44:23 +08:00
ibase_blob_handle * ib_blob ;
RESET_ERRMSG ;
2000-06-06 03:47:54 +08:00
switch ( ZEND_NUM_ARGS ( ) ) {
2000-03-13 03:44:23 +08:00
case 0 :
2003-08-05 21:17:16 +08:00
ZEND_FETCH_RESOURCE2 ( ib_link , ibase_db_link * , NULL , IBG ( default_link ) , " InterBase link " , le_link , le_plink ) ;
2000-03-13 03:44:23 +08:00
break ;
case 1 :
2000-07-07 20:06:05 +08:00
if ( zend_get_parameters_ex ( 1 , & link_arg ) = = FAILURE ) {
1999-04-22 10:48:28 +08:00
RETURN_FALSE ;
}
2003-08-05 21:17:16 +08:00
_php_ibase_get_link_trans ( INTERNAL_FUNCTION_PARAM_PASSTHRU , link_arg , & ib_link , & trans ) ;
2000-03-13 03:44:23 +08:00
break ;
default :
WRONG_PARAM_COUNT ;
break ;
1999-04-22 10:48:28 +08:00
}
2000-03-13 03:44:23 +08:00
/* open default transaction */
2003-08-05 21:17:16 +08:00
if ( _php_ibase_def_trans ( ib_link , & trans TSRMLS_CC ) = = FAILURE ) {
2000-03-13 03:44:23 +08:00
RETURN_FALSE ;
1999-04-22 10:48:28 +08:00
}
2000-03-13 03:44:23 +08:00
ib_blob = ( ibase_blob_handle * ) emalloc ( sizeof ( ibase_blob_handle ) ) ;
2003-08-05 21:17:16 +08:00
ib_blob - > trans_handle = trans - > handle ;
2003-08-13 02:01:59 +08:00
ib_blob - > link = ib_link - > handle ;
2000-03-13 03:44:23 +08:00
ib_blob - > bl_handle = NULL ;
1999-04-22 10:48:28 +08:00
2001-08-12 00:39:07 +08:00
if ( isc_create_blob ( IB_STATUS , & ib_blob - > link , & ib_blob - > trans_handle , & ib_blob - > bl_handle , & ib_blob - > bl_qd ) ) {
2000-03-13 03:44:23 +08:00
efree ( ib_blob ) ;
2002-07-19 17:21:29 +08:00
_php_ibase_error ( TSRMLS_C ) ;
1999-04-22 10:48:28 +08:00
RETURN_FALSE ;
}
2000-03-13 03:44:23 +08:00
2000-10-05 20:47:39 +08:00
RETURN_LONG ( zend_list_insert ( ib_blob , le_blob ) ) ;
2000-03-13 03:44:23 +08:00
}
/* }}} */
1999-04-22 10:48:28 +08:00
2000-03-13 03:44:23 +08:00
/* {{{ proto int ibase_blob_open(string blob_id)
2003-08-13 02:01:59 +08:00
Open blob for retrieving data parts */
2000-03-13 03:44:23 +08:00
PHP_FUNCTION ( ibase_blob_open )
{
2003-01-15 11:01:17 +08:00
zval * * blob_arg ;
2000-03-13 03:44:23 +08:00
ibase_blob_handle * ib_blob , * ib_blob_id ;
1999-04-22 10:48:28 +08:00
2000-03-13 03:44:23 +08:00
RESET_ERRMSG ;
1999-04-22 10:48:28 +08:00
2003-03-16 13:00:50 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 1 | | zend_get_parameters_ex ( 1 , & blob_arg ) = = FAILURE ) {
2000-03-13 03:44:23 +08:00
WRONG_PARAM_COUNT ;
}
1999-04-22 10:48:28 +08:00
2000-03-13 03:44:23 +08:00
ib_blob = ( ibase_blob_handle * ) emalloc ( sizeof ( ibase_blob_handle ) ) ;
2003-01-15 11:01:17 +08:00
GET_BLOB_ID_ARG ( * blob_arg , ib_blob_id ) ;
2000-03-13 03:44:23 +08:00
2000-04-18 10:52:45 +08:00
if ( ib_blob_id = = NULL ) { /* blob IS NULL or argument unset */
2000-03-13 03:44:23 +08:00
RETURN_FALSE ;
}
ib_blob - > link = ib_blob_id - > link ;
ib_blob - > trans_handle = ib_blob_id - > trans_handle ;
ib_blob - > bl_qd . gds_quad_high = ib_blob_id - > bl_qd . gds_quad_high ;
ib_blob - > bl_qd . gds_quad_low = ib_blob_id - > bl_qd . gds_quad_low ;
ib_blob - > bl_handle = NULL ;
2000-04-18 10:52:45 +08:00
if ( isc_open_blob ( IB_STATUS , & ib_blob - > link , & ib_blob - > trans_handle , & ib_blob - > bl_handle , & ib_blob - > bl_qd ) ) {
2000-03-13 03:44:23 +08:00
efree ( ib_blob ) ;
2002-07-19 17:21:29 +08:00
_php_ibase_error ( TSRMLS_C ) ;
1999-04-22 10:48:28 +08:00
RETURN_FALSE ;
}
2000-03-13 03:44:23 +08:00
2000-10-05 20:47:39 +08:00
RETURN_LONG ( zend_list_insert ( ib_blob , le_blob ) ) ;
1999-04-22 10:48:28 +08:00
}
/* }}} */
2003-06-12 19:24:24 +08:00
/* {{{ proto bool ibase_blob_add(int blob_id, string data)
2000-03-13 03:44:23 +08:00
Add data into created blob */
PHP_FUNCTION ( ibase_blob_add )
1999-04-22 10:48:28 +08:00
{
2003-01-15 11:01:17 +08:00
zval * * blob_arg , * * string_arg ;
2000-03-13 03:44:23 +08:00
ibase_blob_handle * ib_blob ;
1999-04-22 10:48:28 +08:00
2000-03-13 03:44:23 +08:00
RESET_ERRMSG ;
2003-03-16 13:00:50 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 2 | | zend_get_parameters_ex ( 2 , & blob_arg , & string_arg ) = = FAILURE ) {
1999-04-22 10:48:28 +08:00
WRONG_PARAM_COUNT ;
}
2000-03-13 03:44:23 +08:00
2003-01-15 23:36:28 +08:00
GET_BLOB_HANDLE_ARG ( blob_arg , ib_blob ) ;
1999-04-22 10:48:28 +08:00
2003-01-15 11:01:17 +08:00
convert_to_string_ex ( string_arg ) ;
2000-03-13 03:44:23 +08:00
2003-01-15 11:01:17 +08:00
if ( isc_put_segment ( IB_STATUS , & ib_blob - > bl_handle , ( unsigned short ) Z_STRLEN_PP ( string_arg ) , Z_STRVAL_PP ( string_arg ) ) ) {
2002-07-19 17:21:29 +08:00
_php_ibase_error ( TSRMLS_C ) ;
1999-04-22 10:48:28 +08:00
RETURN_FALSE ;
}
RETURN_TRUE ;
}
/* }}} */
2000-03-13 03:44:23 +08:00
/* {{{ proto string ibase_blob_get(int blob_id, int len)
Get len bytes data from open blob */
PHP_FUNCTION ( ibase_blob_get )
1999-04-22 10:48:28 +08:00
{
2003-01-15 11:01:17 +08:00
zval * * blob_arg , * * len_arg ;
2000-03-13 03:44:23 +08:00
int stat ;
char * bl_data ;
unsigned short max_len = 0 , cur_len , seg_len ;
ibase_blob_handle * ib_blob ;
1999-04-22 10:48:28 +08:00
2000-03-13 03:44:23 +08:00
RESET_ERRMSG ;
2003-01-15 11:01:17 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 2 | | zend_get_parameters_ex ( 2 , & blob_arg , & len_arg ) = = FAILURE ) {
2000-03-13 03:44:23 +08:00
WRONG_PARAM_COUNT ;
}
2003-01-15 11:01:17 +08:00
convert_to_long_ex ( len_arg ) ;
max_len = ( unsigned short ) Z_LVAL_PP ( len_arg ) ;
2000-03-13 03:44:23 +08:00
2003-01-15 23:36:28 +08:00
GET_BLOB_HANDLE_ARG ( blob_arg , ib_blob ) ;
2000-03-13 03:44:23 +08:00
2000-04-18 10:52:45 +08:00
if ( ib_blob - > bl_qd . gds_quad_high | | ib_blob - > bl_qd . gds_quad_low ) { /*not null ?*/
2000-03-13 03:44:23 +08:00
2003-03-16 13:00:50 +08:00
bl_data = emalloc ( max_len + 1 ) ;
2000-03-13 03:44:23 +08:00
2003-03-16 13:00:50 +08:00
for ( cur_len = stat = 0 ; stat = = 0 ; ) {
2000-07-18 04:51:47 +08:00
stat = isc_get_segment ( IB_STATUS , & ib_blob - > bl_handle , & seg_len , ( unsigned short ) ( max_len - cur_len ) , & bl_data [ cur_len ] ) ;
2000-03-13 03:44:23 +08:00
cur_len + = seg_len ;
2000-04-18 10:52:45 +08:00
if ( cur_len > max_len ) { /* never!*/
2000-03-13 03:44:23 +08:00
efree ( bl_data ) ;
2002-07-19 17:21:29 +08:00
_php_ibase_module_error ( " PHP module internal error " ) ;
1999-04-22 10:48:28 +08:00
RETURN_FALSE ;
}
2000-03-13 03:44:23 +08:00
}
bl_data [ cur_len ] = ' \0 ' ;
2000-04-18 10:52:45 +08:00
if ( IB_STATUS [ 0 ] & & ( IB_STATUS [ 1 ] ! = isc_segstr_eof & & IB_STATUS [ 1 ] ! = isc_segment ) ) {
2000-03-13 03:44:23 +08:00
efree ( bl_data ) ;
2002-07-19 17:21:29 +08:00
_php_ibase_error ( TSRMLS_C ) ;
2000-03-13 03:44:23 +08:00
RETURN_FALSE ;
}
2001-08-12 00:39:07 +08:00
RETURN_STRINGL ( bl_data , cur_len , 0 ) ;
2000-04-18 10:52:45 +08:00
} else { /* null blob */
2001-08-12 00:39:07 +08:00
RETURN_STRING ( " " , 1 ) ; /* empty string */
1999-04-22 10:48:28 +08:00
}
2000-03-13 03:44:23 +08:00
}
/* }}} */
# define BLOB_CLOSE 1
# define BLOB_CANCEL 2
/* {{{ _php_ibase_blob_end() */
/* Close or Cancel created or Close open blob */
static void _php_ibase_blob_end ( INTERNAL_FUNCTION_PARAMETERS , int bl_end )
{
2003-01-15 21:50:54 +08:00
zval * * blob_arg ;
2000-03-13 03:44:23 +08:00
ibase_blob_handle * ib_blob ;
RESET_ERRMSG ;
1999-04-22 10:48:28 +08:00
2003-03-16 13:00:50 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 1 | | zend_get_parameters_ex ( 1 , & blob_arg ) = = FAILURE ) {
2000-03-13 03:44:23 +08:00
WRONG_PARAM_COUNT ;
1999-04-22 10:48:28 +08:00
}
2003-01-15 23:36:28 +08:00
GET_BLOB_HANDLE_ARG ( blob_arg , ib_blob ) ;
2000-03-13 03:44:23 +08:00
2000-04-18 10:52:45 +08:00
if ( bl_end = = BLOB_CLOSE ) { /* return id here */
if ( ib_blob - > bl_qd . gds_quad_high | | ib_blob - > bl_qd . gds_quad_low ) { /*not null ?*/
if ( isc_close_blob ( IB_STATUS , & ib_blob - > bl_handle ) ) {
2002-07-19 17:21:29 +08:00
_php_ibase_error ( TSRMLS_C ) ;
2000-03-13 03:44:23 +08:00
RETURN_FALSE ;
}
}
ib_blob - > bl_handle = NULL ;
2003-03-16 13:00:50 +08:00
RETVAL_STRINGL ( ( char * ) ib_blob , sizeof ( ibase_blob_handle ) , 1 ) ;
2003-01-16 03:36:13 +08:00
zend_list_delete ( Z_LVAL_PP ( blob_arg ) ) ;
2000-03-13 03:44:23 +08:00
} else { /* discard created blob */
2000-04-18 10:52:45 +08:00
if ( isc_cancel_blob ( IB_STATUS , & ib_blob - > bl_handle ) ) {
2002-07-19 17:21:29 +08:00
_php_ibase_error ( TSRMLS_C ) ;
1999-04-22 10:48:28 +08:00
RETURN_FALSE ;
}
2000-03-13 03:44:23 +08:00
ib_blob - > bl_handle = NULL ;
2003-01-16 03:36:13 +08:00
zend_list_delete ( Z_LVAL_PP ( blob_arg ) ) ;
2000-03-13 03:44:23 +08:00
RETURN_TRUE ;
1999-04-22 10:48:28 +08:00
}
2000-03-13 03:44:23 +08:00
}
/* }}} */
1999-04-22 10:48:28 +08:00
2003-06-12 19:24:24 +08:00
/* {{{ proto bool ibase_blob_close(int blob_id)
2000-03-13 03:44:23 +08:00
Close blob */
PHP_FUNCTION ( ibase_blob_close )
{
2001-08-12 00:39:07 +08:00
_php_ibase_blob_end ( INTERNAL_FUNCTION_PARAM_PASSTHRU , BLOB_CLOSE ) ;
1999-04-22 10:48:28 +08:00
}
/* }}} */
2003-06-12 19:24:24 +08:00
/* {{{ proto bool ibase_blob_cancel(int blob_id)
2000-03-13 03:44:23 +08:00
Cancel creating blob */
PHP_FUNCTION ( ibase_blob_cancel )
1999-04-22 10:48:28 +08:00
{
2001-08-12 00:39:07 +08:00
_php_ibase_blob_end ( INTERNAL_FUNCTION_PARAM_PASSTHRU , BLOB_CANCEL ) ;
2000-03-13 03:44:23 +08:00
}
/* }}} */
/* {{{ proto object ibase_blob_info(string blob_id_str)
Return blob length and other useful info */
PHP_FUNCTION ( ibase_blob_info )
{
2003-01-15 11:01:17 +08:00
zval * * blob_arg , * * result_var ;
2000-03-13 03:44:23 +08:00
ibase_blob_handle * ib_blob_id ;
IBASE_BLOBINFO bl_info ;
1999-04-22 10:48:28 +08:00
2000-03-13 03:44:23 +08:00
RESET_ERRMSG ;
2003-01-15 11:01:17 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 1 | | zend_get_parameters_ex ( 1 , & blob_arg ) = = FAILURE ) {
1999-04-22 10:48:28 +08:00
WRONG_PARAM_COUNT ;
}
2003-01-15 11:01:17 +08:00
GET_BLOB_ID_ARG ( * blob_arg , ib_blob_id ) ;
2000-03-13 03:44:23 +08:00
2003-01-19 03:41:56 +08:00
array_init ( return_value ) ;
1999-04-22 10:48:28 +08:00
2003-03-16 13:00:50 +08:00
if ( ib_blob_id - > bl_qd . gds_quad_high | | ib_blob_id - > bl_qd . gds_quad_low ) { /* not null ? */
if ( isc_open_blob ( IB_STATUS , & ib_blob_id - > link , & ib_blob_id - > trans_handle , & ib_blob_id - > bl_handle , & ib_blob_id - > bl_qd ) ) {
2002-07-19 17:21:29 +08:00
_php_ibase_error ( TSRMLS_C ) ;
2000-03-13 03:44:23 +08:00
RETURN_FALSE ;
}
1999-04-22 10:48:28 +08:00
2003-06-15 20:10:28 +08:00
if ( _php_ibase_blob_info ( ib_blob_id - > bl_handle , & bl_info TSRMLS_CC ) ) {
2000-03-13 03:44:23 +08:00
RETURN_FALSE ;
}
2000-04-18 10:52:45 +08:00
if ( isc_close_blob ( IB_STATUS , & ib_blob_id - > bl_handle ) ) {
2002-07-19 17:21:29 +08:00
_php_ibase_error ( TSRMLS_C ) ;
2000-03-13 03:44:23 +08:00
RETURN_FALSE ;
}
ib_blob_id - > bl_handle = NULL ;
2003-03-16 13:00:50 +08:00
} else { /* null blob, all values to zero */
2000-03-13 03:44:23 +08:00
bl_info . max_segment = 0 ;
bl_info . num_segments = 0 ;
bl_info . total_length = 0 ;
bl_info . bl_stream = 0 ;
1999-04-22 10:48:28 +08:00
}
2000-03-13 03:44:23 +08:00
/* FIXME */
2003-03-16 13:00:50 +08:00
add_get_index_long ( return_value , 0 , bl_info . total_length , ( void * * ) & result_var ) ;
2000-03-13 03:44:23 +08:00
/*
2001-09-26 05:58:48 +08:00
zend_hash_pointer_update ( Z_ARRVAL_P ( return_value ) , " length " , sizeof ( " length " ) , result_var ) ;
2000-03-13 03:44:23 +08:00
*/
2003-03-16 13:00:50 +08:00
add_get_index_long ( return_value , 1 , bl_info . num_segments , ( void * * ) & result_var ) ;
2000-03-13 03:44:23 +08:00
/*
2001-09-26 05:58:48 +08:00
zend_hash_pointer_update ( Z_ARRVAL_P ( return_value ) , " numseg " , sizeof ( " numseg " ) , result_var ) ;
2000-03-13 03:44:23 +08:00
*/
2003-03-16 13:00:50 +08:00
add_get_index_long ( return_value , 2 , bl_info . max_segment , ( void * * ) & result_var ) ;
2000-03-13 03:44:23 +08:00
/*
2001-09-26 05:58:48 +08:00
zend_hash_pointer_update ( Z_ARRVAL_P ( return_value ) , " maxseg " , sizeof ( " maxseg " ) , result_var ) ;
2000-03-13 03:44:23 +08:00
*/
2003-03-16 13:00:50 +08:00
add_get_index_long ( return_value , 3 , bl_info . bl_stream , ( void * * ) & result_var ) ;
2000-03-13 03:44:23 +08:00
/*
2001-09-26 05:58:48 +08:00
zend_hash_pointer_update ( Z_ARRVAL_P ( return_value ) , " stream " , sizeof ( " stream " ) , result_var ) ;
2000-03-13 03:44:23 +08:00
*/
2003-03-16 13:00:50 +08:00
add_get_index_long ( return_value , 4 , ( ! ib_blob_id - > bl_qd . gds_quad_high & & ! ib_blob_id - > bl_qd . gds_quad_low ) , ( void * * ) & result_var ) ;
2000-03-13 03:44:23 +08:00
/*
2001-09-26 05:58:48 +08:00
zend_hash_pointer_update ( Z_ARRVAL_P ( return_value ) , " isnull " , sizeof ( " isnull " ) , result_var ) ;
1999-04-22 10:48:28 +08:00
*/
}
/* }}} */
2003-06-12 19:24:24 +08:00
/* {{{ proto bool ibase_blob_echo(string blob_id_str)
2000-03-13 03:44:23 +08:00
Output blob contents to browser */
PHP_FUNCTION ( ibase_blob_echo )
1999-04-22 10:48:28 +08:00
{
2003-01-15 21:50:54 +08:00
zval * * blob_arg ;
2000-03-13 03:44:23 +08:00
char bl_data [ IBASE_BLOB_SEG ] ;
unsigned short seg_len ;
ibase_blob_handle * ib_blob_id ;
RESET_ERRMSG ;
1999-04-22 10:48:28 +08:00
2003-03-16 13:00:50 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 1 | | zend_get_parameters_ex ( 1 , & blob_arg ) = = FAILURE ) {
1999-04-22 10:48:28 +08:00
WRONG_PARAM_COUNT ;
}
2000-03-13 03:44:23 +08:00
2003-01-15 11:01:17 +08:00
GET_BLOB_ID_ARG ( * blob_arg , ib_blob_id ) ;
1999-04-22 10:48:28 +08:00
2003-03-16 13:00:50 +08:00
if ( ib_blob_id ) { /* not null? */
2000-03-13 03:44:23 +08:00
2003-03-16 13:00:50 +08:00
if ( isc_open_blob ( IB_STATUS , & ib_blob_id - > link , & ib_blob_id - > trans_handle , & ib_blob_id - > bl_handle , & ib_blob_id - > bl_qd ) ) {
2002-07-19 17:21:29 +08:00
_php_ibase_error ( TSRMLS_C ) ;
2000-03-13 03:44:23 +08:00
RETURN_FALSE ;
}
2003-03-16 13:00:50 +08:00
while ( ! isc_get_segment ( IB_STATUS , & ib_blob_id - > bl_handle , & seg_len , sizeof ( bl_data ) , bl_data ) | | IB_STATUS [ 1 ] = = isc_segment ) {
2001-08-12 00:39:07 +08:00
PHPWRITE ( bl_data , seg_len ) ;
2000-03-13 03:44:23 +08:00
}
1999-04-22 10:48:28 +08:00
2000-04-18 10:52:45 +08:00
if ( IB_STATUS [ 0 ] & & ( IB_STATUS [ 1 ] ! = isc_segstr_eof ) ) {
2002-07-19 17:21:29 +08:00
_php_ibase_error ( TSRMLS_C ) ;
2000-03-13 03:44:23 +08:00
RETURN_FALSE ;
}
1999-04-22 10:48:28 +08:00
2000-04-18 10:52:45 +08:00
if ( isc_close_blob ( IB_STATUS , & ib_blob_id - > bl_handle ) ) {
2002-07-19 17:21:29 +08:00
_php_ibase_error ( TSRMLS_C ) ;
2000-03-13 03:44:23 +08:00
RETURN_FALSE ;
}
ib_blob_id - > bl_handle = NULL ;
2000-04-18 10:52:45 +08:00
} /* not null ? */
2000-03-13 03:44:23 +08:00
RETURN_TRUE ;
1999-04-22 10:48:28 +08:00
}
/* }}} */
2003-06-12 19:24:24 +08:00
/* {{{ proto string ibase_blob_import([resource link_identifier, ] int file_id)
2000-03-13 03:44:23 +08:00
Create blob , copy file in it , and close it */
PHP_FUNCTION ( ibase_blob_import )
1999-04-22 10:48:28 +08:00
{
2000-04-18 10:52:45 +08:00
zval * * link_arg , * * file_arg ;
2003-08-05 21:17:16 +08:00
int link_id = 0 , size ;
2000-07-18 04:51:47 +08:00
unsigned short b ;
2000-03-13 03:44:23 +08:00
ibase_blob_handle ib_blob ;
ibase_db_link * ib_link ;
2003-08-12 10:16:40 +08:00
ibase_trans * trans = NULL ;
2000-03-13 03:44:23 +08:00
char bl_data [ IBASE_BLOB_SEG ] ; /* FIXME? blob_seg_size parameter? */
2002-10-03 07:05:06 +08:00
php_stream * stream ;
1999-04-22 10:48:28 +08:00
2000-03-13 03:44:23 +08:00
RESET_ERRMSG ;
2000-06-06 03:47:54 +08:00
switch ( ZEND_NUM_ARGS ( ) ) {
2000-03-13 03:44:23 +08:00
case 1 :
2000-04-18 10:52:45 +08:00
if ( zend_get_parameters_ex ( 1 , & file_arg ) = = FAILURE ) {
2000-03-13 03:44:23 +08:00
RETURN_FALSE ;
}
link_id = IBG ( default_link ) ;
2000-10-05 20:47:39 +08:00
ZEND_FETCH_RESOURCE2 ( ib_link , ibase_db_link * , NULL , link_id , " InterBase link " , le_link , le_plink ) ;
2000-03-13 03:44:23 +08:00
break ;
case 2 :
2000-04-18 10:52:45 +08:00
if ( zend_get_parameters_ex ( 2 , & link_arg , & file_arg ) = = FAILURE ) {
2000-03-13 03:44:23 +08:00
RETURN_FALSE ;
}
2003-08-05 21:17:16 +08:00
_php_ibase_get_link_trans ( INTERNAL_FUNCTION_PARAM_PASSTHRU , link_arg , & ib_link , & trans ) ;
2000-03-13 03:44:23 +08:00
break ;
default :
WRONG_PARAM_COUNT ;
break ;
1999-04-22 10:48:28 +08:00
}
2000-03-13 03:44:23 +08:00
/* open default transaction */
2003-08-05 21:17:16 +08:00
if ( _php_ibase_def_trans ( ib_link , & trans TSRMLS_CC ) = = FAILURE ) {
1999-04-22 10:48:28 +08:00
RETURN_FALSE ;
}
2000-03-13 03:44:23 +08:00
2002-09-25 23:46:47 +08:00
php_stream_from_zval ( stream , file_arg ) ;
2001-05-29 02:30:57 +08:00
2003-08-13 02:01:59 +08:00
ib_blob . link = ib_link - > handle ;
2003-08-05 21:17:16 +08:00
ib_blob . trans_handle = trans - > handle ;
2000-03-13 03:44:23 +08:00
ib_blob . bl_handle = NULL ;
ib_blob . bl_qd . gds_quad_high = 0 ;
ib_blob . bl_qd . gds_quad_low = 0 ;
1999-04-22 10:48:28 +08:00
2001-08-12 00:39:07 +08:00
if ( isc_create_blob ( IB_STATUS , & ib_blob . link , & ib_blob . trans_handle , & ib_blob . bl_handle , & ib_blob . bl_qd ) ) {
2002-07-19 17:21:29 +08:00
_php_ibase_error ( TSRMLS_C ) ;
1999-04-22 10:48:28 +08:00
RETURN_FALSE ;
}
2000-03-13 03:44:23 +08:00
size = 0 ;
2001-05-29 02:30:57 +08:00
2003-03-16 13:00:50 +08:00
while ( ( b = php_stream_read ( stream , bl_data , sizeof ( bl_data ) ) ) > 0 ) {
2000-03-13 03:44:23 +08:00
if ( isc_put_segment ( IB_STATUS , & ib_blob . bl_handle , b , bl_data ) ) {
2002-07-19 17:21:29 +08:00
_php_ibase_error ( TSRMLS_C ) ;
2000-03-13 03:44:23 +08:00
RETURN_FALSE ;
}
size + = b ;
}
2000-04-18 10:52:45 +08:00
if ( isc_close_blob ( IB_STATUS , & ib_blob . bl_handle ) ) {
2002-07-19 17:21:29 +08:00
_php_ibase_error ( TSRMLS_C ) ;
2000-03-13 03:44:23 +08:00
RETURN_FALSE ;
1999-04-22 10:48:28 +08:00
}
2000-03-13 03:44:23 +08:00
ib_blob . bl_handle = NULL ;
2003-03-16 13:00:50 +08:00
RETVAL_STRINGL ( ( char * ) & ib_blob , sizeof ( ibase_blob_handle ) , 1 ) ;
1999-04-22 10:48:28 +08:00
}
/* }}} */
2003-03-16 13:00:50 +08:00
2002-06-07 03:47:28 +08:00
# ifdef SQL_DIALECT_V6
2002-01-27 23:31:15 +08:00
/* {{{ _php_ibase_user() */
static void _php_ibase_user ( INTERNAL_FUNCTION_PARAMETERS , int operation )
{
2003-03-16 13:00:50 +08:00
zval * * args [ 8 ] ;
char * ib_server , * dba_user_name , * dba_password , * user_name , * user_password = NULL ;
char * first_name = NULL , * middle_name = NULL , * last_name = NULL ;
2002-01-27 23:31:15 +08:00
char service_name_buffer [ 128 ] , * service_name = service_name_buffer ;
char spb_buffer [ 128 ] , * spb = spb_buffer ;
unsigned short spb_length ;
isc_svc_handle service_handle = NULL ;
RESET_ERRMSG ;
switch ( operation ) {
2003-03-16 13:00:50 +08:00
case isc_action_svc_add_user :
case isc_action_svc_modify_user :
/* 5 to 8 parameters for ADD or MODIFY operation */
if ( ZEND_NUM_ARGS ( ) < 5 | | ZEND_NUM_ARGS ( ) > 8 ) {
WRONG_PARAM_COUNT ;
}
break ;
2002-01-27 23:31:15 +08:00
2003-03-16 13:00:50 +08:00
case isc_action_svc_delete_user :
/* 4 parameters for DELETE operation */
if ( ZEND_NUM_ARGS ( ) ! = 4 ) {
WRONG_PARAM_COUNT ;
}
2002-01-27 23:31:15 +08:00
}
2003-03-16 13:00:50 +08:00
2002-01-27 23:31:15 +08:00
if ( zend_get_parameters_array_ex ( ZEND_NUM_ARGS ( ) , args ) = = FAILURE ) {
RETURN_FALSE ;
}
2003-03-16 13:00:50 +08:00
switch ( ZEND_NUM_ARGS ( ) ) {
2002-01-27 23:31:15 +08:00
case 8 :
convert_to_string_ex ( args [ 7 ] ) ;
2003-03-16 13:00:50 +08:00
last_name = Z_STRVAL_PP ( args [ 7 ] ) ;
2002-01-27 23:31:15 +08:00
/* fallout */
case 7 :
convert_to_string_ex ( args [ 6 ] ) ;
2003-03-16 13:00:50 +08:00
middle_name = Z_STRVAL_PP ( args [ 6 ] ) ;
2002-01-27 23:31:15 +08:00
/* fallout */
case 6 :
convert_to_string_ex ( args [ 5 ] ) ;
2003-03-16 13:00:50 +08:00
first_name = Z_STRVAL_PP ( args [ 5 ] ) ;
2002-01-27 23:31:15 +08:00
/* fallout */
}
if ( operation ! = isc_action_svc_delete_user ) {
2003-03-15 01:37:44 +08:00
/* Parameter not available for DELETE operation */
2002-01-27 23:31:15 +08:00
convert_to_string_ex ( args [ 4 ] ) ;
2003-03-16 13:00:50 +08:00
user_password = Z_STRVAL_PP ( args [ 4 ] ) ;
2002-01-27 23:31:15 +08:00
}
convert_to_string_ex ( args [ 3 ] ) ;
2003-03-16 13:00:50 +08:00
user_name = Z_STRVAL_PP ( args [ 3 ] ) ;
2002-01-27 23:31:15 +08:00
convert_to_string_ex ( args [ 2 ] ) ;
2003-03-16 13:00:50 +08:00
dba_password = Z_STRVAL_PP ( args [ 2 ] ) ;
2002-01-27 23:31:15 +08:00
convert_to_string_ex ( args [ 1 ] ) ;
2003-03-16 13:00:50 +08:00
dba_user_name = Z_STRVAL_PP ( args [ 1 ] ) ;
2002-01-27 23:31:15 +08:00
convert_to_string_ex ( args [ 0 ] ) ;
2003-03-16 13:00:50 +08:00
ib_server = Z_STRVAL_PP ( args [ 0 ] ) ;
2002-01-27 23:31:15 +08:00
/*
zend_printf ( " server : %s<br> " , ib_server ) ;
zend_printf ( " admin : %s<br> " , dba_user_name ) ;
zend_printf ( " admin pwd: %s<br> " , dba_password ) ;
zend_printf ( " user : %s<br> " , user_name ) ;
zend_printf ( " user pwd : %s<br> " , user_password ) ;
zend_printf ( " fname : %s<br> " , first_name ) ;
zend_printf ( " mname : %s<br> " , middle_name ) ;
zend_printf ( " lname : %s<br> " , last_name ) ;
*/
2003-03-15 01:37:44 +08:00
/* Build buffer for isc_service_attach() */
2002-01-27 23:31:15 +08:00
* spb + + = isc_spb_version ;
* spb + + = isc_spb_current_version ;
* spb + + = isc_spb_user_name ;
* spb + + = strlen ( dba_user_name ) ;
strcpy ( spb , dba_user_name ) ;
spb + = strlen ( dba_user_name ) ;
* spb + + = isc_spb_password ;
* spb + + = strlen ( dba_password ) ;
strcpy ( spb , dba_password ) ;
spb + = strlen ( dba_password ) ;
spb_length = spb - spb_buffer ;
2003-03-15 01:37:44 +08:00
/* Attach to the Service Manager */
2002-01-27 23:31:15 +08:00
sprintf ( service_name , " %s:service_mgr " , ib_server ) ;
2003-03-16 13:00:50 +08:00
if ( isc_service_attach ( IB_STATUS , 0 , service_name , & service_handle , spb_length , spb_buffer ) ) {
2002-07-19 17:21:29 +08:00
_php_ibase_error ( TSRMLS_C ) ;
2002-01-27 23:31:15 +08:00
RETURN_FALSE ;
2003-03-16 13:00:50 +08:00
} else {
2002-01-27 23:31:15 +08:00
char request [ 128 ] , * x , * p = request ;
2003-03-15 01:37:44 +08:00
/* Identify cluster (here, isc_action_svc_*_user) */
2002-01-27 23:31:15 +08:00
* p + + = operation ;
2003-03-15 01:37:44 +08:00
/* Argument for username */
2002-01-27 23:31:15 +08:00
* p + + = isc_spb_sec_username ;
ADD_SPB_LENGTH ( p , strlen ( user_name ) ) ;
2003-03-16 13:00:50 +08:00
for ( x = user_name ; * x ; ) * p + + = * x + + ;
2002-01-27 23:31:15 +08:00
2003-03-15 01:37:44 +08:00
/* Argument for password */
2002-01-27 23:31:15 +08:00
if ( user_password ) {
* p + + = isc_spb_sec_password ;
ADD_SPB_LENGTH ( p , strlen ( user_password ) ) ;
2003-03-16 13:00:50 +08:00
for ( x = user_password ; * x ; ) * p + + = * x + + ;
2002-01-27 23:31:15 +08:00
}
2003-03-15 01:37:44 +08:00
/* Argument for first name */
2002-01-27 23:31:15 +08:00
if ( first_name ) {
* p + + = isc_spb_sec_firstname ;
ADD_SPB_LENGTH ( p , strlen ( first_name ) ) ;
2003-03-16 13:00:50 +08:00
for ( x = first_name ; * x ; ) * p + + = * x + + ;
2002-01-27 23:31:15 +08:00
}
2003-03-15 01:37:44 +08:00
/* Argument for middle name */
2002-01-27 23:31:15 +08:00
if ( middle_name ) {
* p + + = isc_spb_sec_middlename ;
ADD_SPB_LENGTH ( p , strlen ( middle_name ) ) ;
2003-03-16 13:00:50 +08:00
for ( x = middle_name ; * x ; ) * p + + = * x + + ;
2002-01-27 23:31:15 +08:00
}
2003-03-15 01:37:44 +08:00
/* Argument for last name */
2002-01-27 23:31:15 +08:00
if ( last_name ) {
* p + + = isc_spb_sec_lastname ;
ADD_SPB_LENGTH ( p , strlen ( last_name ) ) ;
2003-03-16 13:00:50 +08:00
for ( x = last_name ; * x ; ) * p + + = * x + + ;
2002-01-27 23:31:15 +08:00
}
2003-03-15 01:37:44 +08:00
/* Let's go update: start Service Manager */
2003-03-16 13:00:50 +08:00
if ( isc_service_start ( IB_STATUS , & service_handle , NULL , ( unsigned short ) ( p - request ) , request ) ) {
2002-07-19 17:21:29 +08:00
_php_ibase_error ( TSRMLS_C ) ;
2002-01-27 23:31:15 +08:00
isc_service_detach ( IB_STATUS , & service_handle ) ;
RETURN_FALSE ;
2003-03-16 13:00:50 +08:00
} else {
2003-03-15 01:37:44 +08:00
/* Detach from Service Manager */
2002-01-27 23:31:15 +08:00
isc_service_detach ( IB_STATUS , & service_handle ) ;
}
}
RETURN_TRUE ;
}
2002-06-07 03:47:28 +08:00
/* }}} */
2002-01-27 23:31:15 +08:00
2003-06-12 19:24:24 +08:00
/* {{{ proto bool ibase_add_user(string server, string dba_user_name, string dba_password, string user_name, string password [, string first_name [, string middle_name [, string last_name]]])
2002-06-07 03:47:28 +08:00
Add an user to security database ( only for IB6 or later ) */
2002-01-27 23:31:15 +08:00
PHP_FUNCTION ( ibase_add_user )
{
_php_ibase_user ( INTERNAL_FUNCTION_PARAM_PASSTHRU , isc_action_svc_add_user ) ;
}
/* }}} */
2003-06-12 19:24:24 +08:00
/* {{{ proto bool ibase_modify_user(string server, string dba_user_name, string dba_password, string user_name, string password [, string first_name [, string middle_name [, string last_name]]])
2002-06-07 03:47:28 +08:00
Modify an user in security database ( only for IB6 or later ) */
2002-01-27 23:31:15 +08:00
PHP_FUNCTION ( ibase_modify_user )
{
_php_ibase_user ( INTERNAL_FUNCTION_PARAM_PASSTHRU , isc_action_svc_modify_user ) ;
}
2002-06-07 03:47:28 +08:00
/* }}} */
2002-01-27 23:31:15 +08:00
2003-06-12 19:24:24 +08:00
/* {{{ proto bool ibase_delete_user(string server, string dba_user_name, string dba_password, string username)
2002-06-07 03:47:28 +08:00
Delete an user from security database ( only for IB6 or later ) */
2002-01-27 23:31:15 +08:00
PHP_FUNCTION ( ibase_delete_user )
{
_php_ibase_user ( INTERNAL_FUNCTION_PARAM_PASSTHRU , isc_action_svc_delete_user ) ;
}
2002-06-07 03:47:28 +08:00
/* }}} */
# endif /* SQL_DIALECT_V6 */
2002-01-27 23:31:15 +08:00
2003-08-14 18:55:02 +08:00
/* {{{ _php_ibase_event_block() */
static void _php_ibase_event_block ( ibase_db_link * ib_link , unsigned short count , char * * events ,
unsigned short * l , char * * event_buf , char * * result_buf )
{
ISC_STATUS dummy_result [ 20 ] ;
/**
* Unfortunately , there ' s no clean and portable way in C to pass arguments to
* a variadic function if you don ' t know the number of arguments at compile time .
* ( And even if there were a way , the Interbase API doesn ' t provide a version of
* this function that takes a va_list as an argument )
*
* In this case , the number of arguments is limited to 18 by the underlying API ,
* so we can work around it .
*/
* l = ( unsigned short ) isc_event_block ( event_buf , result_buf , count , events [ 0 ] ,
events [ 1 ] , events [ 2 ] , events [ 3 ] , events [ 4 ] , events [ 5 ] , events [ 6 ] , events [ 7 ] ,
events [ 8 ] , events [ 9 ] , events [ 10 ] , events [ 11 ] , events [ 12 ] , events [ 13 ] , events [ 14 ] ) ;
/**
* Currently , this is the only way to correctly initialize an event buffer .
* This is clearly something that should be fixed , cause the semantics of
* isc_wait_for_event ( ) indicate that it blocks until an event occurs .
* If the Firebird people ever fix this , these lines should be removed ,
* otherwise , events will have to fire twice before ibase_wait_event ( ) returns .
*/
isc_wait_for_event ( dummy_result , & ib_link - > handle , * l , * event_buf , * result_buf ) ;
isc_event_counts ( dummy_result , * l , * event_buf , * result_buf ) ;
}
/* }}} */
/* {{{ proto string ibase_wait_event([resource link,] string event [, string event [, ...]])
Waits for any one of the passed Interbase events to be posted by the database , and returns its name */
PHP_FUNCTION ( ibase_wait_event )
{
zval * * * args ;
ibase_db_link * ib_link ;
char * event_buffer , * result_buffer , * events [ 15 ] ;
unsigned short i = 0 , event_count = 0 , buffer_size ;
ISC_STATUS occurred_event [ 15 ] ;
RESET_ERRMSG ;
/* no more than 15 events */
if ( ZEND_NUM_ARGS ( ) < 1 | | ZEND_NUM_ARGS ( ) > 16 ) {
WRONG_PARAM_COUNT ;
}
args = ( zval * * * ) safe_emalloc ( sizeof ( zval * * ) , ZEND_NUM_ARGS ( ) , 0 ) ;
if ( zend_get_parameters_array_ex ( ZEND_NUM_ARGS ( ) , args ) = = FAILURE ) {
efree ( args ) ;
RETURN_FALSE ;
}
if ( Z_TYPE_PP ( args [ 0 ] ) = = IS_RESOURCE ) {
ZEND_FETCH_RESOURCE2 ( ib_link , ibase_db_link * , args [ 0 ] , - 1 , " InterBase link " , le_link , le_plink ) ;
i = 1 ;
2003-08-15 08:06:07 +08:00
} else {
if ( ZEND_NUM_ARGS ( ) > 15 ) {
efree ( args ) ;
WRONG_PARAM_COUNT ;
}
2003-08-14 18:55:02 +08:00
2003-08-15 08:06:07 +08:00
ZEND_FETCH_RESOURCE2 ( ib_link , ibase_db_link * , NULL , IBG ( default_link ) , " InterBase link " , le_link , le_plink ) ;
}
2003-08-14 18:55:02 +08:00
for ( ; i < ZEND_NUM_ARGS ( ) ; + + i ) {
convert_to_string_ex ( args [ i ] ) ;
events [ event_count + + ] = Z_STRVAL_PP ( args [ i ] ) ;
}
/* fills the required data structure with information about the events */
_php_ibase_event_block ( ib_link , event_count , events , & buffer_size , & event_buffer , & result_buffer ) ;
/* now block until an event occurs */
if ( isc_wait_for_event ( IB_STATUS , & ib_link - > handle , buffer_size , event_buffer , result_buffer ) ) {
_php_ibase_error ( TSRMLS_C ) ;
_php_ibase_event_free ( event_buffer , result_buffer ) ;
efree ( args ) ;
RETURN_FALSE ;
}
/* find out which event occurred */
isc_event_counts ( occurred_event , buffer_size , event_buffer , result_buffer ) ;
for ( i = 0 ; i < event_count ; + + i ) {
if ( occurred_event [ i ] ) {
char * result = estrdup ( events [ i ] ) ;
_php_ibase_event_free ( event_buffer , result_buffer ) ;
efree ( args ) ;
RETURN_STRING ( result , 0 ) ;
}
}
/* If we reach this line, isc_wait_for_event() did return, but we don't know
which event fired . */
_php_ibase_event_free ( event_buffer , result_buffer ) ;
efree ( args ) ;
RETURN_FALSE ;
}
/* }}} */
2003-08-15 08:06:07 +08:00
/* {{{ _php_ibase_callback() */
static isc_callback _php_ibase_callback ( ibase_event * event , unsigned short buffer_size , char * result_buf )
{
2003-08-15 08:16:58 +08:00
/* this function is called asynchronously by the Interbase client library. */
TSRMLS_FETCH_FROM_CTX ( event - > thread_ctx ) ;
2003-08-15 08:06:07 +08:00
/**
* The callback function is called when the event is first registered and when the event
* is cancelled . I consider this is a bug . By clearing event - > callback , we make sure
* nothing happens if no event was actually posted .
*/
if ( event - > callback ! = NULL ) {
unsigned short i ;
ISC_STATUS occurred_event [ 15 ] ;
zval event_name , link_id , return_value , * args [ 2 ] = { & event_name , & link_id } ;
/* copy the updated results into the result buffer */
memcpy ( event - > result_buffer , result_buf , buffer_size ) ;
INIT_ZVAL ( event_name ) ;
INIT_ZVAL ( link_id ) ;
ZVAL_RESOURCE ( & link_id , event - > link_res_id ) ;
/* find out which event occurred */
isc_event_counts ( occurred_event , buffer_size , event - > event_buffer , event - > result_buffer ) ;
for ( i = 0 ; i < event - > event_count ; + + i ) {
if ( occurred_event [ i ] ) {
ZVAL_STRING ( & event_name , event - > events [ i ] , 0 ) ;
break ;
}
}
/* call the callback provided by the user */
if ( SUCCESS ! = call_user_function ( EG ( function_table ) , NULL , event - > callback , & return_value , 2 , args TSRMLS_CC ) ) {
_php_ibase_module_error ( " Error calling callback %s " , Z_STRVAL_P ( event - > callback ) ) ;
return 0 ;
}
2003-08-16 00:13:51 +08:00
if ( Z_TYPE ( return_value ) = = IS_BOOL & & ! Z_BVAL ( return_value ) ) {
2003-08-15 08:06:07 +08:00
return 0 ;
}
}
/* re-register the event */
if ( isc_que_events ( IB_STATUS , & event - > link - > handle , & event - > event_id , buffer_size ,
event - > event_buffer , ( isc_callback ) _php_ibase_callback , ( void * ) event ) ) {
_php_ibase_error ( TSRMLS_C ) ;
}
return 0 ;
}
/* }}} */
/* {{{ proto resource ibase_set_event_handler([resource link,] callback handler, string event [, string event [, ...]])
Register the callback for handling each of the named events */
PHP_FUNCTION ( ibase_set_event_handler )
{
/**
* The callback passed to this function should take an event name ( string ) and a
* link resource id ( int ) as arguments . The value returned from the function is
* used to determine if the event handler should remain set .
*/
zval * * * args , * * cb_arg ;
ibase_db_link * ib_link ;
ibase_event * event ;
char * callback_name ;
unsigned short i = 1 , buffer_size ;
int link_res_id ;
RESET_ERRMSG ;
/* no more than 15 events */
if ( ZEND_NUM_ARGS ( ) < 1 | | ZEND_NUM_ARGS ( ) > 17 ) {
WRONG_PARAM_COUNT ;
}
args = ( zval * * * ) safe_emalloc ( sizeof ( zval * * ) , ZEND_NUM_ARGS ( ) , 0 ) ;
if ( zend_get_parameters_array_ex ( ZEND_NUM_ARGS ( ) , args ) = = FAILURE ) {
efree ( args ) ;
RETURN_FALSE ;
}
/* get a working link */
if ( Z_TYPE_PP ( args [ 0 ] ) = = IS_RESOURCE ) {
ZEND_FETCH_RESOURCE2 ( ib_link , ibase_db_link * , args [ 0 ] , - 1 , " InterBase link " , le_link , le_plink ) ;
i = 2 ;
convert_to_long_ex ( args [ 0 ] ) ;
link_res_id = Z_LVAL_PP ( args [ 0 ] ) ;
cb_arg = args [ 1 ] ;
} else {
if ( ZEND_NUM_ARGS ( ) > 16 ) {
efree ( args ) ;
WRONG_PARAM_COUNT ;
}
ZEND_FETCH_RESOURCE2 ( ib_link , ibase_db_link * , NULL , IBG ( default_link ) , " InterBase link " , le_link , le_plink ) ;
link_res_id = IBG ( default_link ) ;
cb_arg = args [ 0 ] ;
}
/* get the callback */
2003-08-16 00:13:51 +08:00
if ( ! zend_is_callable ( * cb_arg , 0 , & callback_name ) ) {
2003-08-15 08:06:07 +08:00
_php_ibase_module_error ( " Callback argument %s is not a callable function " , callback_name ) ;
efree ( callback_name ) ;
efree ( args ) ;
RETURN_FALSE ;
}
efree ( callback_name ) ;
/* allocate the event resource */
event = ( ibase_event * ) safe_emalloc ( sizeof ( ibase_event ) , 1 , 0 ) ;
TSRMLS_SET_CTX ( event - > thread_ctx ) ;
event - > link_res_id = link_res_id ;
event - > link = ib_link ;
event - > event_count = 0 ;
event - > callback = NULL ;
event - > events = ( char * * ) safe_emalloc ( sizeof ( char * ) , ZEND_NUM_ARGS ( ) - i , 0 ) ;
for ( ; i < ZEND_NUM_ARGS ( ) ; + + i ) {
convert_to_string_ex ( args [ i ] ) ;
event - > events [ event - > event_count + + ] = estrdup ( Z_STRVAL_PP ( args [ i ] ) ) ;
}
/* fills the required data structure with information about the events */
_php_ibase_event_block ( ib_link , event - > event_count , event - > events ,
& buffer_size , & event - > event_buffer , & event - > result_buffer ) ;
/* now register the events with the Interbase API */
if ( isc_que_events ( IB_STATUS , & ib_link - > handle , & event - > event_id , buffer_size ,
event - > event_buffer , ( isc_callback ) _php_ibase_callback , ( void * ) event ) ) {
_php_ibase_error ( TSRMLS_C ) ;
efree ( args ) ;
efree ( event ) ;
RETURN_FALSE ;
}
ALLOC_ZVAL ( event - > callback ) ;
* event - > callback = * * cb_arg ;
INIT_PZVAL ( event - > callback ) ;
zval_copy_ctor ( event - > callback ) ;
efree ( args ) ;
ZEND_REGISTER_RESOURCE ( return_value , event , le_event ) ;
2003-08-15 08:16:58 +08:00
zend_list_addref ( Z_LVAL_P ( return_value ) ) ;
2003-08-15 08:06:07 +08:00
}
2003-08-16 00:13:51 +08:00
2003-08-16 08:58:24 +08:00
/* {{{ proto bool ibase_free_event_handler(resource event)
2003-08-16 00:13:51 +08:00
Frees the event handler set by ibase_set_event_handler ( ) */
PHP_FUNCTION ( ibase_free_event_handler )
{
zval * * event_arg ;
ibase_event * event ;
RESET_ERRMSG ;
if ( ZEND_NUM_ARGS ( ) ! = 1 | | zend_get_parameters_ex ( 1 , & event_arg ) = = FAILURE ) {
WRONG_PARAM_COUNT ;
}
ZEND_FETCH_RESOURCE ( event , ibase_event * , event_arg , - 1 , " Interbase event " , le_event ) ;
zend_list_delete ( Z_LVAL_PP ( event_arg ) ) ;
RETURN_TRUE ;
}
2003-08-15 08:06:07 +08:00
/* }}} */
2002-01-27 23:31:15 +08:00
# endif /* HAVE_IBASE */
1999-04-22 10:48:28 +08:00
/*
* Local variables :
* tab - width : 4
* c - basic - offset : 4
* End :
2001-09-09 21:29:31 +08:00
* vim600 : sw = 4 ts = 4 fdm = marker
* vim < 600 : sw = 4 ts = 4
1999-04-22 10:48:28 +08:00
*/