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$ */
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"
2003-08-16 23:30:22 +08:00
2003-09-08 03:59:55 +08:00
# define FILE_REVISION "$Revision$"
2003-09-17 09:25:08 +08:00
# if HAVE_IBASE
2003-08-16 23:30:22 +08:00
2000-03-13 03:44:23 +08:00
# include "php_ini.h"
# include "ext/standard/php_standard.h"
1999-12-05 03:19:57 +08:00
# include "php_interbase.h"
1999-04-22 10:48:28 +08:00
2003-08-16 23:30:22 +08:00
# include <time.h>
2003-08-12 21:19:36 +08:00
# ifndef SQLDA_CURRENT_VERSION
# define SQLDA_CURRENT_VERSION SQLDA_VERSION1
# endif
2000-05-15 05:55:45 +08:00
# ifndef SQL_DIALECT_CURRENT
2003-09-04 22:18:39 +08:00
# define SQL_DIALECT_CURRENT 1 /* == SQL_DIALECT_V5 */
2003-09-12 07:08:48 +08:00
/* IB < 6 doesn't define these */
# ifdef PHP_WIN32
typedef __int64 ISC_INT64 ;
typedef unsigned __int64 ISC_UINT64 ;
# else
typedef long long ISC_INT64 ;
typedef unsigned long long ISC_UINT64 ;
# endif
2000-05-15 05:55:45 +08:00
# endif
2003-08-28 06:55:06 +08:00
# ifdef ZEND_DEBUG_
2003-09-02 21:17:56 +08:00
# define IBDEBUG(a) php_printf("::: %s (%d)\n", a, __LINE__);
2003-08-28 06:55:06 +08:00
# endif
# ifndef IBDEBUG
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):"")
2003-09-04 22:44:34 +08:00
# define ISC_LONG_MIN (-ISC_LONG_MAX - 1)
# define ISC_LONG_MAX 2147483647
2003-08-20 20:22:58 +08:00
# ifdef PHP_WIN32
2003-09-12 07:08:48 +08:00
# define LL_MASK "I64"
# define LL_LIT(lit) lit ## I64
2003-09-17 04:28:27 +08:00
# ifdef FB_SQLDA
# pragma comment(lib, "fbclient_ms.lib")
2003-09-17 09:25:08 +08:00
# else
# pragma comment(lib, "gds32_ms.lib")
2003-09-17 04:28:27 +08:00
# endif
2003-08-20 20:22:58 +08:00
# else
2003-09-12 07:08:48 +08:00
# define LL_MASK "ll"
# define LL_LIT(lit) lit ## ll
2003-08-20 20:22:58 +08:00
# endif
2003-08-28 06:55:06 +08:00
# define QUERY_RESULT 1
# define EXECUTE_RESULT 2
# define ROLLBACK 0
# define COMMIT 1
# define RETAIN 2
2003-08-20 20:22:58 +08:00
2003-08-28 06:55:06 +08:00
# define FETCH_ROW 1
# define FETCH_ARRAY 2
# define BLOB_ID_LEN 18
# define BLOB_ID_MASK "0x%" LL_MASK "x"
# define BLOB_INPUT 1
# define BLOB_OUTPUT 2
# define BLOB_CLOSE 1
# define BLOB_CANCEL 2
2003-08-18 08:14:53 +08:00
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
2003-09-24 04:58:14 +08:00
PHP_FE ( ibase_gen_id , NULL )
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-16 09:58:29 +08:00
# if abies_0
2003-08-11 00:21:26 +08:00
PHP_FE ( ibase_num_rows , NULL )
2003-08-16 09:58:29 +08:00
# endif
2003-08-11 00:21:26 +08:00
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 )
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 )
2003-09-04 22:18:39 +08:00
PHP_FE ( ibase_rollback_ret , 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-29 06:12:06 +08:00
/* {{{ proto int ibase_errcode(void)
2003-08-08 19:04:12 +08:00
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 ( ) */
2003-09-02 20:46:42 +08:00
static void _php_ibase_module_error ( char * TSRMLS_DC , . . . ) PHP_ATTRIBUTE_FORMAT ( printf , 1 , PHP_ATTR_FMT_OFFSET + 2 ) ;
2003-08-28 08:11:16 +08:00
static void _php_ibase_module_error ( char * msg TSRMLS_DC , . . . )
2003-08-05 21:17:16 +08:00
{
va_list ap ;
2003-08-28 08:11:16 +08:00
# ifdef ZTS
va_start ( ap , TSRMLS_C ) ;
# else
2003-08-05 21:17:16 +08:00
va_start ( ap , msg ) ;
2003-08-28 08:11:16 +08:00
# endif
2003-08-05 21:17:16 +08:00
/* vsnprintf NUL terminates the buf and writes at most n-1 chars+NUL */
vsnprintf ( IBG ( errmsg ) , MAX_ERRMSG , msg , ap ) ;
va_end ( ap ) ;
2003-08-16 23:30:22 +08:00
IBG ( sql_code ) = - 999 ; /* no SQL error */
2003-08-05 21:17:16 +08:00
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-28 06:55:06 +08:00
typedef struct {
2003-09-04 22:18:39 +08:00
unsigned short vary_length ;
2003-08-28 06:55:06 +08:00
char vary_string [ 1 ] ;
} IBVARY ;
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 ;
2003-09-02 21:17:56 +08:00
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 ) {
2003-08-28 08:11:16 +08:00
_php_ibase_module_error ( " Link id is ambiguous: transaction spans multiple connections. " TSRMLS_CC ) ;
2003-08-11 04:53:19 +08:00
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 ;
2003-09-04 22:18:39 +08:00
ISC_LONG lval ;
2000-03-13 03:44:23 +08:00
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 ;
2003-08-20 20:22:58 +08:00
static inline int _php_ibase_string_to_quad ( char const * id , ISC_QUAD * qd )
2003-08-16 09:58:29 +08:00
{
2003-08-20 20:22:58 +08:00
/* shortcut for most common case */
2003-09-12 07:08:48 +08:00
if ( sizeof ( ISC_QUAD ) = = sizeof ( ISC_UINT64 ) ) {
return sscanf ( id , BLOB_ID_MASK , ( ISC_UINT64 * ) qd ) ;
2003-08-20 20:22:58 +08:00
} else {
2003-09-12 07:08:48 +08:00
ISC_UINT64 res ;
2003-08-21 00:13:51 +08:00
if ( sscanf ( id , BLOB_ID_MASK , & res ) ) {
qd - > gds_quad_high = ( ISC_LONG ) ( res > > 0x20 ) ;
2003-09-11 16:50:30 +08:00
qd - > gds_quad_low = ( ISC_LONG ) ( res & 0xFFFFFFFF ) ;
2003-08-21 00:13:51 +08:00
return 1 ;
}
return 0 ;
2003-08-16 09:58:29 +08:00
}
2003-08-20 20:22:58 +08:00
}
static inline char * _php_ibase_quad_to_string ( ISC_QUAD const qd )
{
char * result = ( char * ) emalloc ( BLOB_ID_LEN + 1 ) ;
/* shortcut for most common case */
2003-09-12 07:08:48 +08:00
if ( sizeof ( ISC_QUAD ) = = sizeof ( ISC_UINT64 ) ) {
sprintf ( result , BLOB_ID_MASK , * ( ISC_UINT64 * ) ( void * ) & qd ) ;
2003-08-20 20:22:58 +08:00
} else {
2003-09-12 07:08:48 +08:00
ISC_UINT64 res = ( ( ISC_UINT64 ) qd . gds_quad_high < < 0x20 ) | qd . gds_quad_low ;
2003-08-20 20:22:58 +08:00
sprintf ( result , BLOB_ID_MASK , res ) ;
}
result [ BLOB_ID_LEN ] = ' \0 ' ;
return result ;
2003-08-16 09:58:29 +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-28 06:55:06 +08:00
unsigned short i = 0 , j ;
2003-08-05 21:17:16 +08:00
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-08-28 06:55:06 +08:00
if ( ib_result ) {
2000-03-13 03:44:23 +08:00
_php_ibase_free_xsqlda ( ib_result - > out_sqlda ) ;
2003-08-28 06:55:06 +08:00
if ( ib_result - > stmt & & ib_result - > type ! = EXECUTE_RESULT ) {
2003-05-06 06:25:29 +08:00
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
}
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... " ) ;
2003-08-20 20:40:05 +08:00
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)... " ) ;
if ( isc_dsql_free_statement ( IB_STATUS , & ib_query - > stmt , DSQL_drop ) ) {
_php_ibase_error ( TSRMLS_C ) ;
2003-08-13 02:01:59 +08:00
}
2003-08-20 20:40:05 +08:00
}
if ( ib_query - > in_array ) {
efree ( ib_query - > in_array ) ;
}
if ( ib_query - > out_array ) {
efree ( ib_query - > out_array ) ;
}
if ( ib_query - > query ) {
efree ( ib_query - > query ) ;
2000-03-13 03:44:23 +08:00
}
}
/* }}} */
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-08-28 06:55:06 +08:00
ibase_query * ib_query = ( ibase_query * ) rsrc - > ptr ;
if ( ib_query ! = NULL ) {
2003-08-20 20:40:05 +08:00
IBDEBUG ( " Preparing to free query by dtor... " ) ;
2003-08-28 06:55:06 +08:00
_php_ibase_free_query ( ib_query TSRMLS_CC ) ;
if ( ib_query - > statement_type ! = isc_info_sql_stmt_exec_procedure ) {
zend_list_delete ( ib_query - > result_res_id ) ;
}
efree ( ib_query ) ;
2003-05-06 06:25:29 +08:00
}
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
{
2003-08-20 20:22:58 +08:00
ibase_blob * ib_blob = ( ibase_blob * ) 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-08-21 06:59:33 +08:00
_php_ibase_module_error ( " You can lose data. Close any blob after "
2003-08-28 08:11:16 +08:00
" reading from or writing to it. Use ibase_blob_close() before calling ibase_close() " TSRMLS_CC ) ;
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-28 06:55:06 +08:00
unsigned short 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 ) ;
2003-08-16 23:30:22 +08:00
REGISTER_LONG_CONSTANT ( " IBASE_TEXT " , PHP_IBASE_FETCH_BLOBS , CONST_PERSISTENT ) ; /* deprecated, for BC only */
REGISTER_LONG_CONSTANT ( " IBASE_FETCH_BLOBS " , PHP_IBASE_FETCH_BLOBS , CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " IBASE_FETCH_ARRAYS " , PHP_IBASE_FETCH_ARRAYS , 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
{
2003-09-17 04:28:27 +08:00
char tmp [ 64 ] ;
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 " ) ;
2003-09-12 07:08:48 +08:00
2003-09-17 04:28:27 +08:00
# if (SQLDA_CURRENT_VERSION > 1) || defined(FB_SQLDA)
isc_get_client_version ( tmp ) ;
php_info_print_table_row ( 2 , " Client Library " , tmp ) ;
# elif (SQL_DIALECT_CURRENT == 1)
php_info_print_table_row ( 2 , " Client Library " , " Interbase 5.6 or earlier " ) ;
2003-09-12 07:08:48 +08:00
# elif !defined(DSC_null)
2003-09-17 04:28:27 +08:00
php_info_print_table_row ( 2 , " Client Library " , " Interbase 6 " ) ;
2003-09-12 07:08:48 +08:00
# else
2003-09-17 04:28:27 +08:00
php_info_print_table_row ( 2 , " Client Library " , " Firebird 1.0 " ) ;
2003-09-12 07:08:48 +08:00
# endif
2003-09-08 03:59:55 +08:00
php_info_print_table_row ( 2 , " Revision " , FILE_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 ) {
2003-09-12 07:08:48 +08:00
sprintf ( tmp , " %ld/unlimited " , IBG ( num_persistent ) ) ;
2000-03-13 03:44:23 +08:00
} else {
2003-09-12 07:08:48 +08:00
sprintf ( tmp , " %ld/%ld " , IBG ( num_persistent ) , IBG ( max_persistent ) ) ;
2000-03-13 03:44:23 +08:00
}
2003-03-16 13:00:50 +08:00
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 ) {
2003-09-12 07:08:48 +08:00
sprintf ( tmp , " %ld/unlimited " , IBG ( num_links ) ) ;
2000-03-13 03:44:23 +08:00
} else {
2003-09-12 07:08:48 +08:00
sprintf ( tmp , " %ld/%ld " , IBG ( num_links ) , IBG ( max_links ) ) ;
2000-03-13 03:44:23 +08:00
}
2003-03-16 13:00:50 +08:00
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-08-28 08:11:16 +08:00
if ( ( zend_hash_find ( & EG ( persistent_list ) , hashed_details , hashed_details_length + 1 , ( void * ) & le ) ! = FAILURE ) ) {
2003-08-18 08:14:53 +08:00
static char info [ ] = { isc_info_base_level , isc_info_end } ;
char result [ 8 ] ; /* Enough? Hope so... */
2000-05-04 20:28:00 +08:00
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-18 08:14:53 +08:00
if ( ! isc_database_info ( IB_STATUS , & ib_link - > handle , sizeof ( info ) , info , sizeof ( result ) , result ) ) {
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 ) ) ) {
2003-08-29 00:48:22 +08:00
_php_ibase_module_error ( " Too many open links (%ld) " TSRMLS_CC , 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 ) ) ) {
2003-08-29 00:48:22 +08:00
_php_ibase_module_error ( " Too many open persistent links (%ld) " TSRMLS_CC , 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-08-28 08:11:16 +08:00
if ( ( zend_hash_find ( & EG ( regular_list ) , hashed_details , hashed_details_length + 1 , ( void * ) & index_ptr ) = = SUCCESS ) ) {
2003-09-13 05:02:43 +08:00
int type ;
long xlink ;
1999-04-22 10:48:28 +08:00
void * ptr ;
2003-09-13 05:02:43 +08:00
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 ;
}
2003-09-13 05:02:43 +08:00
xlink = ( long ) index_ptr - > ptr ;
2000-03-13 03:44:23 +08:00
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 ) ) ) {
2003-08-29 00:48:22 +08:00
_php_ibase_module_error ( " Too many open links (%ld) " TSRMLS_CC , 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-09-04 19:09:46 +08:00
static int _php_ibase_alloc_array ( ibase_array * * ib_arrayp , 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
2003-09-04 19:09:46 +08:00
unsigned short i ;
XSQLVAR * var = sqlda - > sqlvar ;
1999-04-22 10:48:28 +08:00
2003-09-04 19:09:46 +08:00
IB_ARRAY = safe_emalloc ( sizeof ( ibase_array ) , sqlda - > sqld , 0 ) ;
1999-04-22 10:48:28 +08:00
2000-04-18 10:52:45 +08:00
for ( i = 0 ; i < sqlda - > sqld ; i + + , var + + ) {
2003-09-04 19:09:46 +08:00
unsigned short dim ;
2003-09-05 22:21:25 +08:00
unsigned long ar_size = 1 ;
2003-09-04 19:09:46 +08:00
2003-03-16 13:00:50 +08:00
if ( ( var - > sqltype & ~ 1 ) = = SQL_ARRAY ) {
2003-09-04 19:09:46 +08:00
ISC_ARRAY_DESC * ar_desc = & IB_ARRAY [ i ] . ar_desc ;
2003-03-16 13:00:50 +08:00
2003-09-04 19:09:46 +08:00
if ( isc_array_lookup_bounds ( IB_STATUS , & link , & trans , var - > relname , var - > sqlname , ar_desc ) ) {
_php_ibase_error ( TSRMLS_C ) ;
efree ( IB_ARRAY ) ;
IB_ARRAY = NULL ;
return FAILURE ;
}
1999-04-22 10:48:28 +08:00
2003-09-04 19:09:46 +08:00
switch ( ar_desc - > array_desc_dtype ) {
case blr_text :
case blr_text2 :
IB_ARRAY [ i ] . el_type = SQL_TEXT ;
2003-09-05 22:21:25 +08:00
IB_ARRAY [ i ] . el_size = ar_desc - > array_desc_length ;
2003-09-04 19:09:46 +08:00
break ;
case blr_short :
IB_ARRAY [ i ] . el_type = SQL_SHORT ;
IB_ARRAY [ i ] . el_size = sizeof ( short ) ;
break ;
case blr_long :
IB_ARRAY [ i ] . el_type = SQL_LONG ;
IB_ARRAY [ i ] . el_size = sizeof ( ISC_LONG ) ;
break ;
case blr_float :
IB_ARRAY [ i ] . el_type = SQL_FLOAT ;
IB_ARRAY [ i ] . el_size = sizeof ( float ) ;
break ;
case blr_double :
IB_ARRAY [ i ] . el_type = SQL_DOUBLE ;
IB_ARRAY [ i ] . el_size = sizeof ( double ) ;
break ;
2003-09-04 09:26:36 +08:00
# ifdef blr_int64
2003-09-04 19:09:46 +08:00
case blr_int64 :
IB_ARRAY [ i ] . el_type = SQL_INT64 ;
IB_ARRAY [ i ] . el_size = sizeof ( ISC_INT64 ) ;
break ;
2003-09-04 09:26:36 +08:00
# endif
# ifndef blr_timestamp
2003-09-04 19:09:46 +08:00
case blr_date :
IB_ARRAY [ i ] . el_type = SQL_DATE ;
IB_ARRAY [ i ] . el_size = sizeof ( ISC_QUAD ) ;
break ;
2003-09-04 09:26:36 +08:00
# else
2003-09-04 19:09:46 +08:00
case blr_timestamp :
IB_ARRAY [ i ] . el_type = SQL_TIMESTAMP ;
IB_ARRAY [ i ] . el_size = sizeof ( ISC_TIMESTAMP ) ;
break ;
case blr_sql_date :
IB_ARRAY [ i ] . el_type = SQL_TYPE_DATE ;
IB_ARRAY [ i ] . el_size = sizeof ( ISC_DATE ) ;
break ;
case blr_sql_time :
IB_ARRAY [ i ] . el_type = SQL_TYPE_TIME ;
IB_ARRAY [ i ] . el_size = sizeof ( ISC_TIME ) ;
break ;
2003-09-04 09:26:36 +08:00
# endif
2003-09-04 19:09:46 +08:00
case blr_varying :
2003-09-05 22:21:25 +08:00
case blr_varying2 :
/**
* IB has a strange way of handling VARCHAR arrays . It doesn ' t store
* the length in the first short , as with VARCHAR fields . It does ,
* however , expect the extra short to be allocated for each element .
*/
2003-09-04 19:09:46 +08:00
IB_ARRAY [ i ] . el_type = SQL_TEXT ;
IB_ARRAY [ i ] . el_size = ar_desc - > array_desc_length + sizeof ( short ) ;
break ;
case blr_quad :
case blr_blob_id :
case blr_cstring :
case blr_cstring2 :
2003-09-05 22:21:25 +08:00
/**
* These types are mentioned as array types in the manual , but I
* wouldn ' t know how to create an array field with any of these
* types . I assume these types are not applicable to arrays , and
* were mentioned erroneously .
*/
2003-09-04 19:09:46 +08:00
default :
_php_ibase_module_error ( " Unsupported array type %d in relation '%s' column '%s' " TSRMLS_CC , ar_desc - > array_desc_dtype , var - > relname , var - > sqlname ) ;
efree ( IB_ARRAY ) ;
IB_ARRAY = NULL ;
return FAILURE ;
} /* switch array_desc_type */
2003-09-05 22:21:25 +08:00
/* calculate elements count */
2003-09-04 19:09:46 +08:00
for ( dim = 0 ; dim < ar_desc - > array_desc_dimensions ; dim + + ) {
2003-09-05 06:37:14 +08:00
ar_size * = 1 + ar_desc - > array_desc_bounds [ dim ] . array_bound_upper - ar_desc - > array_desc_bounds [ dim ] . array_bound_lower ;
2003-09-04 19:09:46 +08:00
}
2003-09-05 06:37:14 +08:00
IB_ARRAY [ i ] . ar_size = IB_ARRAY [ i ] . el_size * ar_size ;
2003-09-04 19:09:46 +08:00
} /* if SQL_ARRAY */
} /* for column */
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-20 20:40:05 +08:00
static int _php_ibase_alloc_query ( ibase_query * ib_query , 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
{
2003-08-18 08:14:53 +08:00
static char info_type [ ] = { isc_info_sql_stmt_type } ;
char result [ 8 ] ;
1999-04-22 10:48:28 +08:00
2003-08-20 20:40:05 +08:00
ib_query - > link = link ;
ib_query - > trans = trans ;
2003-08-21 03:47:00 +08:00
ib_query - > result_res_id = 0 ;
2003-08-20 20:40:05 +08:00
ib_query - > stmt = NULL ;
ib_query - > in_array = NULL ;
ib_query - > out_array = NULL ;
ib_query - > dialect = dialect ;
ib_query - > query = estrdup ( query ) ;
ib_query - > trans_res_id = trans_res_id ;
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-20 20:40:05 +08:00
ib_query - > out_sqlda = ( XSQLDA * ) emalloc ( XSQLDA_LENGTH ( 1 ) ) ;
ib_query - > out_sqlda - > sqln = 1 ;
ib_query - > out_sqlda - > version = SQLDA_CURRENT_VERSION ;
1999-04-22 10:48:28 +08:00
2003-08-20 20:40:05 +08:00
if ( isc_dsql_prepare ( IB_STATUS , & ib_query - > trans - > handle , & ib_query - > stmt , 0 , query , dialect , ib_query - > out_sqlda ) ) {
2003-08-13 02:01:59 +08:00
_php_ibase_error ( TSRMLS_C ) ;
goto _php_ibase_alloc_query_error ;
}
/* find out what kind of statement was prepared */
2003-08-20 20:40:05 +08:00
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-20 20:40:05 +08:00
ib_query - > statement_type = result [ 3 ] ;
2000-03-13 03:44:23 +08:00
/* not enough output variables ? */
2003-08-20 20:40:05 +08:00
if ( ib_query - > out_sqlda - > sqld > ib_query - > out_sqlda - > sqln ) {
ib_query - > out_sqlda = erealloc ( ib_query - > out_sqlda , XSQLDA_LENGTH ( ib_query - > out_sqlda - > sqld ) ) ;
ib_query - > out_sqlda - > sqln = ib_query - > out_sqlda - > sqld ;
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-20 20:40:05 +08:00
ib_query - > in_sqlda = emalloc ( XSQLDA_LENGTH ( 1 ) ) ;
ib_query - > in_sqlda - > sqln = 1 ;
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 ? */
2003-08-20 20:40:05 +08:00
if ( ib_query - > in_sqlda - > sqln < ib_query - > in_sqlda - > sqld ) {
ib_query - > in_sqlda = erealloc ( ib_query - > in_sqlda , XSQLDA_LENGTH ( ib_query - > in_sqlda - > sqld ) ) ;
ib_query - > in_sqlda - > sqln = ib_query - > in_sqlda - > sqld ;
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
/* no, haven't placeholders at all */
2003-08-20 20:40:05 +08:00
if ( ib_query - > in_sqlda - > sqld = = 0 ) {
efree ( ib_query - > in_sqlda ) ;
ib_query - > in_sqlda = NULL ;
2003-09-04 19:09:46 +08:00
} else if ( _php_ibase_alloc_array ( & ib_query - > in_array , ib_query - > in_sqlda , link - > handle , trans - > handle TSRMLS_CC ) = = FAILURE ) {
goto _php_ibase_alloc_query_error ;
1999-04-22 10:48:28 +08:00
}
2003-08-20 20:40:05 +08:00
if ( ib_query - > out_sqlda - > sqld = = 0 ) {
efree ( ib_query - > out_sqlda ) ;
ib_query - > out_sqlda = NULL ;
2003-09-04 19:09:46 +08:00
} else if ( _php_ibase_alloc_array ( & ib_query - > out_array , ib_query - > out_sqlda , link - > handle , trans - > handle TSRMLS_CC ) = = FAILURE ) {
goto _php_ibase_alloc_query_error ;
2000-03-13 03:44:23 +08:00
}
return SUCCESS ;
_php_ibase_alloc_query_error :
2003-08-20 20:40:05 +08:00
if ( ib_query - > out_sqlda ) {
efree ( ib_query - > out_sqlda ) ;
2003-03-16 13:00:50 +08:00
}
2003-08-20 20:40:05 +08:00
if ( ib_query - > in_sqlda ) {
efree ( ib_query - > in_sqlda ) ;
2003-03-16 13:00:50 +08:00
}
2003-08-20 20:40:05 +08:00
if ( ib_query - > out_array ) {
efree ( ib_query - > out_array ) ;
2003-03-16 13:00:50 +08:00
}
2003-08-20 20:40:05 +08:00
if ( ib_query - > query ) {
efree ( ib_query - > query ) ;
2003-08-13 02:01:59 +08:00
}
2000-03-13 03:44:23 +08:00
return FAILURE ;
1999-04-22 10:48:28 +08:00
}
/* }}} */
2003-08-17 20:31:55 +08:00
/* ((( _php_ibase_blob_add */
2003-08-20 20:22:58 +08:00
static int _php_ibase_blob_add ( zval * * string_arg , ibase_blob * ib_blob TSRMLS_DC )
2003-08-17 20:31:55 +08:00
{
unsigned long put_cnt = 0 , rem_cnt ;
unsigned short chunk_size ;
convert_to_string_ex ( string_arg ) ;
for ( rem_cnt = Z_STRLEN_PP ( string_arg ) ; rem_cnt > 0 ; rem_cnt - = chunk_size ) {
chunk_size = rem_cnt > USHRT_MAX ? USHRT_MAX : ( unsigned short ) rem_cnt ;
if ( isc_put_segment ( IB_STATUS , & ib_blob - > bl_handle , chunk_size , & Z_STRVAL_PP ( string_arg ) [ put_cnt ] ) ) {
_php_ibase_error ( TSRMLS_C ) ;
return FAILURE ;
}
put_cnt + = chunk_size ;
}
return SUCCESS ;
}
/* }}} */
2003-09-05 06:37:14 +08:00
/* {{{ _php_ibase_bind_array() */
static int _php_ibase_bind_array ( zval * val , char * buf , unsigned long buf_size , ibase_array * array , int dim TSRMLS_DC )
{
2003-09-05 22:21:25 +08:00
zval null_val , * pnull_val = & null_val ;
int u_bound = array - > ar_desc . array_desc_bounds [ dim ] . array_bound_upper ,
2003-09-05 06:37:14 +08:00
l_bound = array - > ar_desc . array_desc_bounds [ dim ] . array_bound_lower ,
dim_len = 1 + u_bound - l_bound ;
2003-09-05 22:21:25 +08:00
ZVAL_NULL ( pnull_val ) ;
2003-09-05 06:37:14 +08:00
if ( dim < array - > ar_desc . array_desc_dimensions ) {
unsigned long slice_size = buf_size / dim_len ;
unsigned short i ;
2003-09-05 22:21:25 +08:00
zval * * subval = & val ;
2003-09-05 06:37:14 +08:00
2003-09-05 22:21:25 +08:00
if ( Z_TYPE_P ( val ) = = IS_ARRAY ) {
zend_hash_internal_pointer_reset ( Z_ARRVAL_P ( val ) ) ;
2003-09-05 06:37:14 +08:00
}
for ( i = 0 ; i < dim_len ; + + i ) {
2003-09-05 22:21:25 +08:00
if ( Z_TYPE_P ( val ) = = IS_ARRAY & &
zend_hash_get_current_data ( Z_ARRVAL_P ( val ) , ( void * ) & subval ) = = FAILURE )
{
subval = & pnull_val ;
}
if ( _php_ibase_bind_array ( * subval , buf , slice_size , array , dim + 1 TSRMLS_CC ) = = FAILURE )
{
2003-09-05 06:37:14 +08:00
return FAILURE ;
}
buf + = slice_size ;
2003-09-05 22:21:25 +08:00
if ( Z_TYPE_P ( val ) = = IS_ARRAY ) {
zend_hash_move_forward ( Z_ARRVAL_P ( val ) ) ;
}
2003-09-05 06:37:14 +08:00
}
2003-09-05 22:21:25 +08:00
if ( Z_TYPE_P ( val ) = = IS_ARRAY ) {
zend_hash_internal_pointer_reset ( Z_ARRVAL_P ( val ) ) ;
}
2003-09-05 06:37:14 +08:00
} else {
/* expect a single value */
2003-09-05 22:21:25 +08:00
if ( Z_TYPE_P ( val ) = = IS_NULL ) {
memset ( buf , 0 , buf_size ) ;
} else if ( array - > ar_desc . array_desc_scale < 0 ) {
2003-09-05 06:37:14 +08:00
/* no coercion for array types */
2003-09-05 22:21:25 +08:00
double l ;
2003-09-05 06:37:14 +08:00
2003-09-05 22:21:25 +08:00
convert_to_double ( val ) ;
if ( Z_DVAL_P ( val ) > 0 ) {
l = Z_DVAL_P ( val ) * pow ( 10 , - array - > ar_desc . array_desc_scale ) + .5 ;
} else {
l = Z_DVAL_P ( val ) * pow ( 10 , - array - > ar_desc . array_desc_scale ) - .5 ;
}
2003-09-05 06:37:14 +08:00
2003-09-05 22:21:25 +08:00
switch ( array - > el_type ) {
2003-09-05 06:37:14 +08:00
case SQL_SHORT :
if ( l > SHRT_MAX | | l < SHRT_MIN ) {
_php_ibase_module_error ( " Array parameter exceeds field width " TSRMLS_CC ) ;
return FAILURE ;
}
* ( short * ) buf = ( short ) l ;
break ;
case SQL_LONG :
if ( l > ISC_LONG_MAX | | l < ISC_LONG_MIN ) {
_php_ibase_module_error ( " Array parameter exceeds field width " TSRMLS_CC ) ;
return FAILURE ;
}
* ( ISC_LONG * ) buf = ( ISC_LONG ) l ;
break ;
# ifdef SQL_INT64
case SQL_INT64 :
{
long double l ;
convert_to_string ( val ) ;
2003-09-05 22:21:25 +08:00
2003-09-05 06:37:14 +08:00
if ( ! sscanf ( Z_STRVAL_P ( val ) , " % " LL_MASK " f " , & l ) ) {
_php_ibase_module_error ( " Cannot convert '%s' to long double " TSRMLS_CC , Z_STRVAL_P ( val ) ) ;
return FAILURE ;
2003-09-05 22:21:25 +08:00
}
if ( l > 0 ) {
* ( ISC_INT64 * ) buf = ( ISC_INT64 ) ( l * pow ( 10 , - array - > ar_desc . array_desc_scale ) + .5 ) ;
2003-09-05 06:37:14 +08:00
} else {
2003-09-05 22:21:25 +08:00
* ( ISC_INT64 * ) buf = ( ISC_INT64 ) ( l * pow ( 10 , - array - > ar_desc . array_desc_scale ) - .5 ) ;
2003-09-05 06:37:14 +08:00
}
}
break ;
# endif
}
} else {
struct tm t = { 0 , 0 , 0 , 0 , 0 , 0 } ;
switch ( array - > el_type ) {
unsigned short n ;
case SQL_SHORT :
convert_to_long ( val ) ;
if ( Z_LVAL_P ( val ) > SHRT_MAX | | Z_LVAL_P ( val ) < SHRT_MIN ) {
_php_ibase_module_error ( " Array parameter exceeds field width " TSRMLS_CC ) ;
return FAILURE ;
}
* ( short * ) buf = ( short ) Z_LVAL_P ( val ) ;
break ;
case SQL_LONG :
convert_to_long ( val ) ;
# if (SIZEOF_LONG > 4)
if ( Z_LVAL_P ( val ) > ISC_LONG_MAX | | Z_LVAL_P ( val ) < ISC_LONG_MIN ) {
_php_ibase_module_error ( " Array parameter exceeds field width " TSRMLS_CC ) ;
return FAILURE ;
}
# endif
* ( ISC_LONG * ) buf = ( ISC_LONG ) Z_LVAL_P ( val ) ;
break ;
# ifdef SQL_INT64
case SQL_INT64 :
# if (SIZEOF_LONG >= 8)
convert_to_long ( val ) ;
* ( long * ) buf = Z_LVAL_P ( val ) ;
# else
{
ISC_INT64 l ;
convert_to_string ( val ) ;
if ( ! sscanf ( Z_STRVAL_P ( val ) , " % " LL_MASK " d " , & l ) ) {
_php_ibase_module_error ( " Cannot convert '%s' to long integer " TSRMLS_CC , Z_STRVAL_P ( val ) ) ;
return FAILURE ;
} else {
* ( ISC_INT64 * ) buf = l ;
}
}
# endif
break ;
# endif
case SQL_FLOAT :
convert_to_double ( val ) ;
* ( float * ) buf = ( float ) Z_DVAL_P ( val ) ;
break ;
case SQL_DOUBLE :
convert_to_double ( val ) ;
* ( double * ) buf = Z_DVAL_P ( val ) ;
break ;
# ifndef SQL_TIMESTAMP
case SQL_DATE :
# else
case SQL_TIMESTAMP :
# endif
convert_to_string ( val ) ;
# ifdef HAVE_STRPTIME
strptime ( Z_STRVAL_P ( val ) , IBG ( timestampformat ) , & t ) ;
# else
n = sscanf ( Z_STRVAL_P ( val ) , " %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 ) {
_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') " TSRMLS_CC , n , Z_STRVAL_P ( val ) ) ;
return FAILURE ;
}
t . tm_year - = 1900 ;
t . tm_mon - - ;
# endif
# ifndef SQL_TIMESTAMP
isc_encode_date ( & t , ( ISC_QUAD * ) buf ) ;
break ;
# else
isc_encode_timestamp ( & t , ( ISC_TIMESTAMP * ) buf ) ;
break ;
case SQL_TYPE_DATE :
convert_to_string ( val ) ;
# ifdef HAVE_STRPTIME
strptime ( Z_STRVAL_P ( val ) , IBG ( dateformat ) , & t ) ;
# else
n = sscanf ( Z_STRVAL_P ( val ) , " %d%*[/]%d%*[/]%d " , & t . tm_mon , & t . tm_mday , & t . tm_year ) ;
if ( n ! = 3 ) {
_php_ibase_module_error ( " Invalid date format (expected 3 fields, got %d. Use format 'm/d/Y' You gave '%s') " TSRMLS_CC , n , Z_STRVAL_P ( val ) ) ;
return FAILURE ;
}
t . tm_year - = 1900 ;
t . tm_mon - - ;
# endif
isc_encode_sql_date ( & t , ( ISC_DATE * ) buf ) ;
break ;
case SQL_TYPE_TIME :
convert_to_string ( val ) ;
# ifdef HAVE_STRPTIME
strptime ( Z_STRVAL_P ( val ) , IBG ( timeformat ) , & t ) ;
# else
n = sscanf ( Z_STRVAL_P ( val ) , " %d%*[:]%d%*[:]%d " , & t . tm_hour , & t . tm_min , & t . tm_sec ) ;
if ( n ! = 3 ) {
_php_ibase_module_error ( " Invalid time format (expected 3 fields, got %d. Use format 'H:i:s'. You gave '%s') " TSRMLS_CC , n , Z_STRVAL_P ( val ) ) ;
return FAILURE ;
}
# endif
isc_encode_sql_time ( & t , ( ISC_TIME * ) buf ) ;
break ;
# endif
default :
convert_to_string ( val ) ;
strncpy ( buf , Z_STRVAL_P ( val ) , array - > el_size ) ;
buf [ array - > el_size - 1 ] = ' \0 ' ;
}
}
}
return SUCCESS ;
}
/* }}} */
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
{
2003-09-05 06:37:14 +08:00
int i , rv = SUCCESS ;
2003-09-03 23:15:30 +08:00
XSQLVAR * var = sqlda - > sqlvar ;
1999-04-22 10:48:28 +08:00
2003-09-03 23:15:30 +08:00
for ( i = 0 ; i < sqlda - > sqld ; + + var , + + i ) { /* bound vars */
2000-03-13 03:44:23 +08:00
2003-09-03 23:15:30 +08:00
zval * b_var = b_vars [ i ] ;
2003-03-16 13:00:50 +08:00
var - > sqlind = & buf [ i ] . sqlind ;
2000-03-13 03:44:23 +08:00
2001-09-26 05:58:48 +08:00
if ( Z_TYPE_P ( b_var ) = = IS_NULL ) {
2003-09-03 23:15:30 +08:00
if ( ( var - > sqltype & 1 ) ! = 1 ) {
_php_ibase_module_error ( " Parameter %d must have a value " TSRMLS_CC , i + 1 ) ;
rv = FAILURE ;
2003-03-16 13:00:50 +08:00
}
2003-09-03 23:15:30 +08:00
buf [ i ] . sqlind = - 1 ;
} else {
buf [ i ] . sqlind = 0 ;
if ( var - > sqlscale < 0 ) {
2000-05-12 03:38:02 +08:00
/*
2003-09-03 23:15:30 +08:00
DECIMAL or NUMERIC field are stored internally as scaled integers .
Coerce it to string and let InterBase ' s internal routines handle it .
2000-05-12 03:38:02 +08:00
*/
var - > sqltype = SQL_TEXT ;
2003-09-03 23:15:30 +08:00
}
switch ( var - > sqltype & ~ 1 ) {
case SQL_SHORT :
convert_to_long ( b_var ) ;
if ( Z_LVAL_P ( b_var ) > SHRT_MAX | | Z_LVAL_P ( b_var ) < SHRT_MIN ) {
_php_ibase_module_error ( " Parameter %d exceeds field width " TSRMLS_CC , i + 1 ) ;
rv = FAILURE ;
}
buf [ i ] . val . sval = ( short ) Z_LVAL_P ( b_var ) ;
var - > sqldata = ( void * ) & buf [ i ] . val . sval ;
break ;
case SQL_LONG :
convert_to_long ( b_var ) ;
2003-09-04 22:18:39 +08:00
# if (SIZEOF_LONG > 4)
/* ISC_LONG is always 32-bit */
2003-09-04 22:44:34 +08:00
if ( Z_LVAL_P ( b_var ) > ISC_LONG_MAX | | Z_LVAL_P ( b_var ) < ISC_LONG_MIN ) {
2003-09-04 22:18:39 +08:00
_php_ibase_module_error ( " Parameter %d exceeds field width " TSRMLS_CC , i + 1 ) ;
rv = FAILURE ;
}
# endif
buf [ i ] . val . lval = ( ISC_LONG ) Z_LVAL_P ( b_var ) ;
var - > sqldata = ( void * ) & buf [ i ] . val . lval ;
break ;
# if defined(SQL_INT64) && (SIZEOF_LONG == 8)
case SQL_INT64 :
convert_to_long ( b_var ) ;
2003-09-03 23:15:30 +08:00
var - > sqldata = ( void * ) & Z_LVAL_P ( b_var ) ;
break ;
2003-09-04 22:18:39 +08:00
# endif
2003-09-03 23:15:30 +08:00
case SQL_FLOAT :
convert_to_double ( b_var ) ;
buf [ i ] . val . fval = ( float ) Z_DVAL_P ( b_var ) ;
var - > sqldata = ( void * ) & buf [ i ] . val . fval ;
break ;
case SQL_DOUBLE :
convert_to_double ( b_var ) ;
var - > sqldata = ( void * ) & Z_DVAL_P ( b_var ) ;
break ;
2000-05-15 05:55:45 +08:00
# ifndef SQL_TIMESTAMP
2003-09-03 23:15:30 +08:00
case SQL_DATE :
2000-05-15 05:55:45 +08:00
convert_to_string ( b_var ) ;
2003-09-03 23:15:30 +08:00
{
struct tm t ;
# ifdef HAVE_STRPTIME
strptime ( Z_STRVAL_P ( b_var ) , IBG ( timestampformat ) , & t ) ;
2000-05-15 05:55:45 +08:00
# else
2003-09-03 23:15:30 +08:00
/* Parsing doesn't seem to happen with older versions... */
int n ;
t . tm_year = t . tm_mon = t . tm_mday = t . tm_hour = t . tm_min = t . tm_sec = 0 ;
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 ) {
_php_ibase_module_error ( " Parameter %d: invalid date/time format (expected 3 or 6 fields, got %d. Use format m/d/Y H:i:s. You gave '%s') " TSRMLS_CC , i + 1 , n , Z_STRVAL_P ( b_var ) ) ;
rv = FAILURE ;
}
t . tm_year - = 1900 ;
t . tm_mon - - ;
2000-05-15 05:55:45 +08:00
# endif
2003-09-03 23:15:30 +08:00
isc_encode_date ( & t , & buf [ i ] . val . qval ) ;
var - > sqldata = ( void * ) ( & buf [ i ] . val . qval ) ;
}
2000-05-12 11:02:14 +08:00
# else
2003-09-03 23:15:30 +08:00
# ifdef HAVE_STRPTIME
case SQL_TIMESTAMP :
case SQL_TYPE_DATE :
case SQL_TYPE_TIME :
{
struct tm t ;
convert_to_string ( b_var ) ;
switch ( var - > sqltype & ~ 1 ) {
case SQL_TIMESTAMP :
strptime ( Z_STRVAL_P ( b_var ) , IBG ( timestampformat ) , & t ) ;
isc_encode_timestamp ( & t , & buf [ i ] . val . tsval ) ;
var - > sqldata = ( void * ) ( & buf [ i ] . val . tsval ) ;
break ;
case SQL_TYPE_DATE :
strptime ( Z_STRVAL_P ( b_var ) , IBG ( dateformat ) , & t ) ;
isc_encode_sql_date ( & t , & buf [ i ] . val . dtval ) ;
var - > sqldata = ( void * ) ( & buf [ i ] . val . dtval ) ;
break ;
case SQL_TYPE_TIME :
strptime ( Z_STRVAL_P ( b_var ) , IBG ( timeformat ) , & t ) ;
isc_encode_sql_time ( & t , & buf [ i ] . val . tmval ) ;
var - > sqldata = ( void * ) ( & buf [ i ] . val . tmval ) ;
break ;
}
2000-03-13 03:44:23 +08:00
}
2000-05-15 05:55:45 +08:00
# endif
2000-05-12 11:02:14 +08:00
# endif
2003-09-03 23:15:30 +08:00
break ;
case SQL_BLOB :
2003-08-18 00:13:52 +08:00
2003-09-03 23:15:30 +08:00
convert_to_string ( b_var ) ;
if ( Z_STRLEN_P ( b_var ) ! = BLOB_ID_LEN | |
! _php_ibase_string_to_quad ( Z_STRVAL_P ( b_var ) , & buf [ i ] . val . qval ) ) {
ibase_blob ib_blob = { NULL , { 0 , 0 } , BLOB_INPUT } ;
if ( isc_create_blob ( IB_STATUS , & ib_query - > link - > handle , & ib_query - > trans - > handle , & ib_blob . bl_handle , & ib_blob . bl_qd ) ) {
_php_ibase_error ( TSRMLS_C ) ;
return FAILURE ;
}
if ( _php_ibase_blob_add ( & b_var , & ib_blob TSRMLS_CC ) ! = SUCCESS ) {
return FAILURE ;
}
if ( isc_close_blob ( IB_STATUS , & ib_blob . bl_handle ) ) {
_php_ibase_error ( TSRMLS_C ) ;
return FAILURE ;
}
buf [ i ] . val . qval = ib_blob . bl_qd ;
2001-09-05 05:47:05 +08:00
}
2003-09-03 23:15:30 +08:00
var - > sqldata = ( void * ) & buf [ i ] . val . qval ;
break ;
case SQL_ARRAY :
2003-09-05 06:37:14 +08:00
if ( Z_TYPE_P ( b_var ) ! = IS_ARRAY ) {
convert_to_string ( b_var ) ;
if ( Z_STRLEN_P ( b_var ) ! = BLOB_ID_LEN | |
! _php_ibase_string_to_quad ( Z_STRVAL_P ( b_var ) , & buf [ i ] . val . qval ) ) {
_php_ibase_module_error ( " Parameter %d: invalid array ID " TSRMLS_CC , i + 1 ) ;
rv = FAILURE ;
}
} else {
/* convert the array data into something IB can understand */
void * array_data = emalloc ( ib_query - > in_array [ i ] . ar_size ) ;
ISC_QUAD array_id = { 0 , 0 } ;
if ( _php_ibase_bind_array ( b_var , array_data , ib_query - > in_array [ i ] . ar_size ,
& ib_query - > in_array [ i ] , 0 TSRMLS_CC ) = = FAILURE )
{
_php_ibase_module_error ( " Parameter %d: failed to bind array argument " TSRMLS_CC , i + 1 ) ;
efree ( array_data ) ;
rv = FAILURE ;
break ;
}
if ( isc_array_put_slice ( IB_STATUS ,
& ib_query - > link - > handle ,
& ib_query - > trans - > handle ,
& array_id ,
& ib_query - > in_array [ i ] . ar_desc ,
array_data ,
& ib_query - > in_array [ i ] . ar_size ) )
{
_php_ibase_error ( TSRMLS_C ) ;
efree ( array_data ) ;
return FAILURE ;
}
buf [ i ] . val . qval = array_id ;
efree ( array_data ) ;
}
var - > sqldata = ( void * ) & buf [ i ] . val . qval ;
2003-09-03 23:15:30 +08:00
break ;
default :
convert_to_string ( b_var ) ;
var - > sqldata = Z_STRVAL_P ( b_var ) ;
var - > sqllen = Z_STRLEN_P ( b_var ) ;
var - > sqltype = SQL_TEXT ;
} /* switch */
} /* if */
2003-03-16 13:00:50 +08:00
} /* for */
2003-09-03 23:15:30 +08:00
return rv ;
2000-03-13 03:44:23 +08:00
}
/* }}} */
/* {{{ _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 :
2003-09-04 09:26:36 +08:00
var - > sqldata = emalloc ( sizeof ( ISC_LONG ) ) ;
2000-03-13 03:44:23 +08:00
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-18 08:14:53 +08:00
static char info_count [ ] = { isc_info_sql_records } ;
char 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 :
2003-08-17 20:31:55 +08:00
RETVAL_BOOL ( 1 ) ;
2003-08-13 02:01:59 +08:00
}
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 */
2003-09-02 21:17:56 +08:00
IBDEBUG ( " Query wants XSQLDA for output " ) ;
2003-09-04 22:18:39 +08:00
IB_RESULT = emalloc ( sizeof ( ibase_result ) + sizeof ( ibase_array ) * ( ib_query - > out_sqlda - > sqld - 1 ) ) ;
2003-08-28 06:55:06 +08:00
IB_RESULT - > link = ib_query - > link ;
IB_RESULT - > trans = ib_query - > trans ;
IB_RESULT - > stmt = ib_query - > stmt ;
IB_RESULT - > statement_type = ib_query - > statement_type ;
IB_RESULT - > out_sqlda = NULL ;
2003-08-21 03:47:00 +08:00
IB_RESULT - > has_more_rows = 1 ;
2003-08-28 06:55:06 +08:00
out_sqlda = IB_RESULT - > out_sqlda = emalloc ( XSQLDA_LENGTH ( ib_query - > out_sqlda - > sqld ) ) ;
memcpy ( out_sqlda , ib_query - > out_sqlda , XSQLDA_LENGTH ( ib_query - > out_sqlda - > sqld ) ) ;
_php_ibase_alloc_xsqlda ( out_sqlda ) ;
if ( ib_query - > out_array ) {
2003-09-04 22:18:39 +08:00
memcpy ( & IB_RESULT - > out_array , ib_query - > out_array , sizeof ( ibase_array ) * out_sqlda - > sqld ) ;
2003-08-28 06:55:06 +08:00
}
2000-03-13 03:44:23 +08:00
}
if ( ib_query - > in_sqlda ) { /* has placeholders */
2003-09-02 21:17:56 +08:00
IBDEBUG ( " Query wants XSQLDA for input " ) ;
2000-03-13 03:44:23 +08:00
if ( ib_query - > in_sqlda - > sqld ! = argc ) {
2003-08-28 08:11:16 +08:00
_php_ibase_module_error ( " Placeholders (%d) and variables (%d) mismatch " TSRMLS_CC , ib_query - > in_sqlda - > sqld , argc ) ;
2003-08-21 03:47:00 +08:00
goto _php_ibase_exec_error ;
2000-03-13 03:44:23 +08:00
}
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 ) {
2003-08-17 20:31:55 +08:00
unsigned long affected_rows ;
2003-08-13 02:01:59 +08:00
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 ;
}
2003-08-17 20:31:55 +08:00
affected_rows = 0 ;
2003-08-13 02:01:59 +08:00
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 ) {
2003-08-17 20:31:55 +08:00
affected_rows + = isc_vax_integer ( & result [ i + 3 ] , len ) ;
2003-08-13 02:01:59 +08:00
}
i + = len + 3 ;
}
2003-08-17 20:31:55 +08:00
}
if ( affected_rows > 0 ) {
ib_query - > trans - > affected_rows = affected_rows ;
RETVAL_LONG ( affected_rows ) ;
}
2003-08-13 02:01:59 +08:00
}
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 ) ;
}
2003-08-18 00:30:15 +08:00
if ( bind_buf )
2000-03-13 03:44:23 +08:00
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 */
2003-08-21 00:13:51 +08:00
if ( PHP_IBASE_READ = = ( trans_argl & PHP_IBASE_READ ) ) {
2003-08-06 07:40:30 +08:00
last_tpb [ tpb_len + + ] = isc_tpb_read ;
2003-08-21 00:13:51 +08:00
} else if ( PHP_IBASE_WRITE = = ( trans_argl & PHP_IBASE_WRITE ) ) {
last_tpb [ tpb_len + + ] = isc_tpb_write ;
2003-08-06 07:40:30 +08:00
}
/* isolation level */
2003-08-21 00:13:51 +08:00
if ( PHP_IBASE_COMMITTED = = ( trans_argl & PHP_IBASE_COMMITTED ) ) {
2003-08-06 07:40:30 +08:00
last_tpb [ tpb_len + + ] = isc_tpb_read_committed ;
2003-08-21 00:13:51 +08:00
if ( PHP_IBASE_REC_VERSION = = ( trans_argl & PHP_IBASE_REC_VERSION ) ) {
2003-08-06 07:40:30 +08:00
last_tpb [ tpb_len + + ] = isc_tpb_rec_version ;
2003-08-21 00:13:51 +08:00
} else if ( PHP_IBASE_REC_NO_VERSION = = ( trans_argl & PHP_IBASE_REC_NO_VERSION ) ) {
last_tpb [ tpb_len + + ] = isc_tpb_no_rec_version ;
2003-08-06 07:40:30 +08:00
}
2003-08-21 00:13:51 +08:00
} else if ( PHP_IBASE_CONSISTENCY = = ( trans_argl & PHP_IBASE_CONSISTENCY ) ) {
2003-08-06 07:40:30 +08:00
last_tpb [ tpb_len + + ] = isc_tpb_consistency ;
2003-08-21 00:13:51 +08:00
} else if ( PHP_IBASE_CONCURRENCY = = ( trans_argl & PHP_IBASE_CONCURRENCY ) ) {
last_tpb [ tpb_len + + ] = isc_tpb_concurrency ;
2003-08-06 07:40:30 +08:00
}
/* lock resolution */
2003-08-21 00:13:51 +08:00
if ( PHP_IBASE_NOWAIT = = ( trans_argl & PHP_IBASE_NOWAIT ) ) {
2003-08-06 07:40:30 +08:00
last_tpb [ tpb_len + + ] = isc_tpb_nowait ;
2003-08-21 00:13:51 +08:00
} else if ( PHP_IBASE_WAIT = = ( trans_argl & PHP_IBASE_WAIT ) ) {
last_tpb [ tpb_len + + ] = isc_tpb_wait ;
2003-08-06 07:40:30 +08:00
}
}
}
}
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() */
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-17 20:31:55 +08:00
ISC_STATUS result ;
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 */
2003-08-28 08:11:16 +08:00
_php_ibase_module_error ( " Default link has no default transaction " TSRMLS_CC ) ;
2003-08-08 09:42:09 +08:00
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 */
2003-08-28 08:11:16 +08:00
_php_ibase_module_error ( " Link has no default transaction " TSRMLS_CC ) ;
2003-08-08 09:42:09 +08:00
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 ) {
2003-08-17 20:31:55 +08:00
default : /* == case ROLLBACK: */
2003-08-07 01:51:46 +08:00
result = isc_rollback_transaction ( IB_STATUS , & trans - > handle ) ;
break ;
case COMMIT :
result = isc_commit_transaction ( IB_STATUS , & trans - > handle ) ;
break ;
2003-09-04 22:18:39 +08:00
# ifdef SQL_DIALECT_V6
2003-08-07 01:51:46 +08:00
case ( ROLLBACK | RETAIN ) :
result = isc_rollback_retaining ( IB_STATUS , & trans - > handle ) ;
break ;
2003-09-04 22:18:39 +08:00
# endif
2003-08-07 01:51:46 +08:00
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 */
2003-09-04 22:18:39 +08:00
# ifdef SQL_DIALECT_V6
2003-08-07 01:51:46 +08:00
PHP_FUNCTION ( ibase_rollback_ret )
{
_php_ibase_trans_end ( INTERNAL_FUNCTION_PARAM_PASSTHRU , ROLLBACK | RETAIN ) ;
}
2003-09-04 22:18:39 +08:00
# endif
2003-08-07 01:51:46 +08:00
/* }}} */
2003-08-29 06:12:06 +08:00
/* {{{ proto mixed ibase_query([resource link_identifier, [ resource link_identifier, ]] string query [, mixed bind_arg [, mixed bind_arg [, ...]]])
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 ;
2003-08-28 06:55:06 +08:00
ibase_query ib_query = { NULL , NULL , 0 , 0 } ;
ibase_result * 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-28 08:11:16 +08:00
_php_ibase_module_error ( " Query argument missing " TSRMLS_CC ) ;
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 */
2003-08-28 08:11:16 +08:00
_php_ibase_module_error ( " Invalid arguments " TSRMLS_CC ) ;
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
2003-08-28 06:55:06 +08:00
if ( _php_ibase_exec ( INTERNAL_FUNCTION_PARAM_PASSTHRU , & result , & ib_query , bind_n , bind_args ) = = FAILURE ) {
2003-08-20 20:40:05 +08:00
_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
2003-08-28 06:55:06 +08:00
if ( result ! = NULL ) { /* statement returns a result */
result - > type = QUERY_RESULT ;
2003-08-20 20:40:05 +08:00
2003-08-28 06:55:06 +08:00
/* EXECUTE PROCEDURE returns only one row => statement can be released immediately */
if ( ib_query . statement_type ! = isc_info_sql_stmt_exec_procedure ) {
ib_query . stmt = NULL ; /* keep stmt when free query */
}
ZEND_REGISTER_RESOURCE ( return_value , result , le_result ) ;
2000-03-13 03:44:23 +08:00
}
2003-08-20 20:40:05 +08:00
_php_ibase_free_query ( & ib_query TSRMLS_CC ) ;
2000-03-13 03:44:23 +08:00
}
/* }}} */
2003-08-29 06:12:06 +08:00
/* {{{ proto int ibase_affected_rows( [ resource link_identifier ] )
2003-08-11 00:21:26 +08:00
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-09-22 14:54:29 +08:00
/* {{{ proto int ibase_num_rows( resource result_identifier )
2003-09-17 03:45:22 +08:00
*/
2003-08-16 09:58:29 +08:00
# if abies_0
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 ;
2003-08-18 08:14:53 +08:00
static char info_count [ ] = { isc_info_sql_records } ;
char result [ 64 ] ;
2003-08-11 00:21:26 +08:00
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-16 09:58:29 +08:00
# endif
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
{
2003-09-04 09:26:36 +08:00
# ifdef SQL_INT64
static ISC_INT64 const scales [ ] = { 1 , 10 , 100 , 1000 , 10000 , 100000 , 1000000 , 100000000 , 1000000000 ,
1000000000 , LL_LIT ( 10000000000 ) , LL_LIT ( 100000000000 ) , LL_LIT ( 10000000000000 ) , LL_LIT ( 100000000000000 ) ,
LL_LIT ( 1000000000000000 ) , LL_LIT ( 1000000000000000 ) , LL_LIT ( 1000000000000000000 ) } ;
# else
static long const scales [ ] = { 1 , 10 , 100 , 1000 , 10000 , 100000 , 1000000 , 100000000 , 1000000000 , 1000000000 } ;
# endif
2003-03-16 13:00:50 +08:00
switch ( type & ~ 1 ) {
2003-09-04 09:26:36 +08:00
unsigned short l ;
long n ;
char string_data [ 255 ] ;
2003-08-20 21:02:26 +08:00
2000-03-13 03:44:23 +08:00
case SQL_VARYING :
2003-08-28 06:55:06 +08:00
len = ( ( IBVARY * ) data ) - > vary_length ;
data = ( ( IBVARY * ) data ) - > vary_string ;
2003-09-04 09:26:36 +08:00
/* no break */
2000-03-13 03:44:23 +08:00
case SQL_TEXT :
if ( PG ( magic_quotes_runtime ) ) {
2003-08-20 20:22:58 +08:00
Z_STRVAL_P ( val ) = php_addslashes ( data , len , & Z_STRLEN_P ( val ) , 0 TSRMLS_CC ) ;
Z_TYPE_P ( val ) = IS_STRING ;
} else {
ZVAL_STRINGL ( val , ( char * ) data , len , 1 ) ;
2003-03-16 13:00:50 +08:00
}
2000-03-13 03:44:23 +08:00
break ;
2003-06-02 20:37:16 +08:00
case SQL_SHORT :
2003-09-04 09:26:36 +08:00
n = * ( short * ) data ;
goto _sql_long ;
2003-09-04 22:18:39 +08:00
# ifdef SQL_INT64
case SQL_INT64 :
# if (SIZEOF_LONG >= 8)
n = * ( long * ) data ;
goto _sql_long ;
# else
if ( scale = = 0 ) {
2003-09-05 22:21:25 +08:00
l = sprintf ( string_data , " % " LL_MASK " d " , * ( ISC_INT64 * ) data ) ;
2003-09-04 22:18:39 +08:00
ZVAL_STRINGL ( val , string_data , l , 1 ) ;
} else {
ISC_INT64 n = * ( ISC_INT64 * ) data , f = scales [ - scale ] ;
if ( n > = 0 ) {
l = sprintf ( string_data , " % " LL_MASK " d.%0* " LL_MASK " d " , n / f , - scale , n % f ) ;
} else if ( n < - f ) {
l = sprintf ( string_data , " % " LL_MASK " d.%0* " LL_MASK " d " , n / f , - scale , - n % f ) ;
} else {
l = sprintf ( string_data , " -0.%0* " LL_MASK " d " , - scale , - n % f ) ;
}
ZVAL_STRINGL ( val , string_data , l , 1 ) ;
}
break ;
# endif
# endif
2003-09-04 09:26:36 +08:00
case SQL_LONG :
2003-09-04 22:18:39 +08:00
n = * ( ISC_LONG * ) data ;
2003-09-04 09:26:36 +08:00
_sql_long :
if ( scale = = 0 ) {
ZVAL_LONG ( val , n ) ;
} else {
2003-09-04 19:09:46 +08:00
long f = ( long ) scales [ - scale ] ;
2003-09-04 09:26:36 +08:00
if ( n > = 0 ) {
l = sprintf ( string_data , " %ld.%0*ld " , n / f , - scale , n % f ) ;
} else if ( n < - f ) {
l = sprintf ( string_data , " %ld.%0*ld " , n / f , - scale , - n % f ) ;
2003-08-07 08:00:19 +08:00
} else {
2003-09-04 09:26:36 +08:00
l = sprintf ( string_data , " -0.%0*ld " , - scale , - n % f ) ;
2003-06-02 20:37:16 +08:00
}
2003-09-04 09:26:36 +08:00
ZVAL_STRINGL ( val , string_data , l , 1 ) ;
2000-03-13 03:44:23 +08:00
}
break ;
case SQL_FLOAT :
2003-08-20 21:02:26 +08:00
ZVAL_DOUBLE ( val , * ( float * ) data ) ;
2000-03-13 03:44:23 +08:00
break ;
case SQL_DOUBLE :
2003-09-04 09:26:36 +08:00
ZVAL_DOUBLE ( val , * ( double * ) data ) ;
2000-03-13 03:44:23 +08:00
break ;
2003-09-04 09:26:36 +08:00
default : /* == any date/time type */
2000-05-10 04:30:23 +08:00
{
2000-03-13 03:44:23 +08:00
struct tm t ;
2000-05-12 11:02:14 +08:00
char * format = NULL ;
# 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 ) {
2003-09-04 09:26:36 +08:00
default : /* == case SQL_TIMESTAMP: */
2000-05-10 04:30:23 +08:00
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
# if HAVE_TM_ZONE
t . tm_zone = tzname [ 0 ] ;
# endif
2000-05-12 11:02:14 +08:00
if ( flag & PHP_IBASE_UNIXTIME ) {
2003-09-04 09:26:36 +08:00
ZVAL_LONG ( val , mktime ( & t ) ) ;
2000-03-13 03:44:23 +08:00
} else {
# if HAVE_STRFTIME
2003-09-04 09:26:36 +08:00
l = strftime ( string_data , sizeof ( string_data ) , format , & t ) ;
2000-03-13 03:44:23 +08:00
# else
2003-09-04 09:26:36 +08:00
switch ( type & ~ 1 ) {
default :
l = 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 ) ;
break ;
# ifdef SQL_TIMESTAMP
case SQL_TYPE_DATE :
l = sprintf ( string_data , " %02d/%02d/%4d " , t . tm_mon + 1 , t . tm_mday , t . tm_year + 1900 ) ;
break ;
case SQL_TYPE_TIME :
l = sprintf ( string_data , " %02d:%02d:%02d " , t . tm_hour , t . tm_min , t . tm_sec ) ;
break ;
# endif
2003-03-16 13:00:50 +08:00
}
2000-03-13 03:44:23 +08:00
# endif
2003-09-04 09:26:36 +08:00
ZVAL_STRINGL ( val , string_data , l , 1 ) ;
2000-03-13 03:44:23 +08:00
break ;
}
}
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
*/
2003-09-04 19:09:46 +08:00
static int _php_ibase_arr_zval ( zval * ar_zval , char * data , unsigned long data_size , ibase_array * ib_array , int dim , int flag TSRMLS_DC )
2000-03-13 03:44:23 +08:00
{
2003-09-04 19:09:46 +08:00
int
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 ;
unsigned short i ;
2000-03-13 03:44:23 +08:00
2003-09-05 06:37:14 +08:00
if ( dim < ib_array - > ar_desc . array_desc_dimensions ) { /* array again */
2003-09-04 19:09:46 +08:00
unsigned long slice_size = data_size / dim_len ;
2003-09-05 06:37:14 +08:00
array_init ( ar_zval ) ;
2003-09-04 19:09:46 +08:00
for ( i = 0 ; i < dim_len ; + + i ) {
zval * slice_zval ;
ALLOC_INIT_ZVAL ( slice_zval ) ;
2000-03-13 03:44:23 +08:00
/* recursion here */
2003-09-04 19:09:46 +08:00
if ( _php_ibase_arr_zval ( slice_zval , data , slice_size , ib_array , dim + 1 , flag TSRMLS_CC ) = = FAILURE ) {
2000-03-13 03:44:23 +08:00
return FAILURE ;
}
2003-09-04 19:09:46 +08:00
data + = slice_size ;
add_index_zval ( ar_zval , l_bound + i , slice_zval ) ;
2000-03-13 03:44:23 +08:00
}
2000-04-18 10:52:45 +08:00
} else { /* data at last */
2000-03-13 03:44:23 +08:00
2003-09-05 06:37:14 +08:00
if ( _php_ibase_var_zval ( ar_zval , data ,
ib_array - > el_type ,
ib_array - > ar_desc . array_desc_length ,
ib_array - > ar_desc . array_desc_scale ,
flag TSRMLS_CC ) = = FAILURE ) {
return FAILURE ;
2000-03-13 03:44:23 +08:00
}
2003-09-05 22:21:25 +08:00
/* fix for peculiar handling of VARCHAR arrays;
truncate the field to the cstring length */
if ( ib_array - > ar_desc . array_desc_dtype = = blr_varying | |
ib_array - > ar_desc . array_desc_dtype = = blr_varying2 ) {
Z_STRLEN_P ( ar_zval ) = strlen ( Z_STRVAL_P ( ar_zval ) ) ;
}
2000-03-13 03:44:23 +08:00
}
return SUCCESS ;
}
2001-06-06 21:06:12 +08:00
/* }}} */
2000-03-13 03:44:23 +08:00
2003-08-17 20:31:55 +08:00
/* {{{ _php_ibase_blob_get */
2003-08-20 20:22:58 +08:00
static int _php_ibase_blob_get ( zval * return_value , ibase_blob * ib_blob , unsigned long max_len TSRMLS_DC )
2003-08-17 20:31:55 +08:00
{
if ( ib_blob - > bl_qd . gds_quad_high | | ib_blob - > bl_qd . gds_quad_low ) { /*not null ?*/
ISC_STATUS stat ;
char * bl_data ;
unsigned long cur_len ;
unsigned short seg_len ;
bl_data = emalloc ( max_len + 1 ) ;
for ( cur_len = stat = 0 ; ( stat = = 0 | | stat = = isc_segment ) & & cur_len < max_len ; cur_len + = seg_len ) {
unsigned short chunk_size = ( max_len - cur_len ) > USHRT_MAX ? USHRT_MAX : ( unsigned short ) ( max_len - cur_len ) ;
stat = isc_get_segment ( IB_STATUS , & ib_blob - > bl_handle , & seg_len , chunk_size , & bl_data [ cur_len ] ) ;
}
bl_data [ cur_len ] = ' \0 ' ;
if ( IB_STATUS [ 0 ] = = 1 & & ( stat ! = 0 & & stat ! = isc_segstr_eof & & stat ! = isc_segment ) ) {
efree ( bl_data ) ;
_php_ibase_error ( TSRMLS_C ) ;
return FAILURE ;
}
RETVAL_STRINGL ( bl_data , cur_len , 0 ) ;
} else { /* null blob */
RETVAL_STRING ( " " , 1 ) ; /* empty string */
}
return SUCCESS ;
}
/* }}} */
2000-03-13 03:44:23 +08:00
/* {{{ _php_ibase_fetch_hash() */
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 ;
2003-09-04 19:09:46 +08:00
long i , flag = 0 ;
2000-03-13 03:44:23 +08:00
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
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-09-04 19:09:46 +08:00
zval * result ;
ALLOC_INIT_ZVAL ( result ) ;
2003-08-17 21:16:54 +08:00
2003-03-16 13:00:50 +08:00
switch ( var - > sqltype & ~ 1 ) {
2003-08-20 20:22:58 +08:00
default :
2003-09-04 19:09:46 +08:00
_php_ibase_var_zval ( result , var - > sqldata , var - > sqltype , var - > sqllen , var - > sqlscale , flag TSRMLS_CC ) ;
2000-03-13 03:44:23 +08:00
break ;
case SQL_BLOB :
2003-08-16 23:30:22 +08:00
if ( flag & PHP_IBASE_FETCH_BLOBS ) { /* fetch blob contents into hash */
2003-08-20 20:22:58 +08:00
ibase_blob blob_handle ;
2003-08-17 20:31:55 +08:00
unsigned long max_len = 0 ;
2003-08-18 08:14:53 +08:00
static char bl_items [ ] = { isc_info_blob_total_length } ;
2003-08-21 06:59:33 +08:00
char bl_info [ 20 ] ;
unsigned short i ;
2003-08-20 20:22:58 +08:00
2003-08-17 20:31:55 +08:00
blob_handle . bl_handle = NULL ;
2003-09-03 06:37:26 +08:00
blob_handle . bl_qd = * ( ISC_QUAD * ) var - > sqldata ;
2003-08-17 20:31:55 +08:00
2003-08-18 08:14:53 +08:00
if ( isc_open_blob ( IB_STATUS , & ib_result - > link - > handle , & ib_result - > trans - > handle , & blob_handle . bl_handle , & blob_handle . bl_qd ) ) {
2002-07-19 17:21:29 +08:00
_php_ibase_error ( TSRMLS_C ) ;
2003-09-04 19:09:46 +08:00
goto _php_ibase_fetch_error ;
2000-03-13 03:44:23 +08:00
}
2003-08-17 20:31:55 +08:00
if ( isc_blob_info ( IB_STATUS , & blob_handle . 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-09-04 19:09:46 +08:00
goto _php_ibase_fetch_error ;
2000-03-13 03:44:23 +08:00
}
/* find total length of blob's data */
2003-08-21 06:59:33 +08:00
for ( i = 0 ; i < sizeof ( bl_info ) ; ) {
2003-08-20 20:22:58 +08:00
unsigned short item_len ;
2003-08-21 06:59:33 +08:00
char item = bl_info [ i + + ] ;
2003-08-20 20:22:58 +08:00
2003-08-21 06:59:33 +08:00
if ( item = = isc_info_end | | item = = isc_info_truncated | |
item = = isc_info_error | | i > = sizeof ( bl_info ) ) {
2003-08-28 08:11:16 +08:00
_php_ibase_module_error ( " Could not determine BLOB size (internal error) " TSRMLS_CC ) ;
2003-09-04 19:09:46 +08:00
goto _php_ibase_fetch_error ;
2003-08-21 06:59:33 +08:00
}
item_len = ( unsigned short ) isc_vax_integer ( & bl_info [ i ] , 2 ) ;
2003-03-16 13:00:50 +08:00
if ( item = = isc_info_blob_total_length ) {
2003-08-21 06:59:33 +08:00
max_len = isc_vax_integer ( & bl_info [ i + 2 ] , item_len ) ;
2003-08-17 20:31:55 +08:00
break ;
2003-03-16 13:00:50 +08:00
}
2003-08-21 06:59:33 +08:00
i + = item_len + 2 ;
2000-03-13 03:44:23 +08:00
}
2003-08-17 20:31:55 +08:00
if ( max_len = = 0 ) {
2003-09-04 19:09:46 +08:00
ZVAL_STRING ( result , " " , 1 ) ;
} else if ( _php_ibase_blob_get ( result , & blob_handle , max_len TSRMLS_CC ) ! = SUCCESS ) {
goto _php_ibase_fetch_error ;
2000-03-13 03:44:23 +08:00
}
2003-08-17 20:31:55 +08:00
if ( isc_close_blob ( IB_STATUS , & blob_handle . bl_handle ) ) {
2002-07-19 17:21:29 +08:00
_php_ibase_error ( TSRMLS_C ) ;
2003-09-04 19:09:46 +08:00
goto _php_ibase_fetch_error ;
2000-03-13 03:44:23 +08:00
}
2003-08-20 20:22:58 +08:00
2000-03-13 03:44:23 +08:00
} else { /* blob id only */
2003-09-03 06:37:26 +08:00
ISC_QUAD bl_qd = * ( ISC_QUAD * ) var - > sqldata ;
2003-09-04 19:09:46 +08:00
ZVAL_STRINGL ( result , _php_ibase_quad_to_string ( bl_qd ) , BLOB_ID_LEN , 0 ) ;
2000-03-13 03:44:23 +08:00
}
break ;
2003-09-04 19:09:46 +08:00
case SQL_ARRAY :
2003-08-20 20:22:58 +08:00
if ( flag & PHP_IBASE_FETCH_ARRAYS ) { /* array can be *huge* so only fetch if asked */
2003-09-03 06:37:26 +08:00
ISC_QUAD ar_qd = * ( ISC_QUAD * ) var - > sqldata ;
2003-09-04 19:09:46 +08:00
ibase_array * ib_array = & ib_result - > out_array [ i ] ;
void * ar_data = emalloc ( ib_array - > ar_size ) ;
2003-08-16 23:30:22 +08:00
2003-08-18 08:14:53 +08:00
if ( isc_array_get_slice ( IB_STATUS , & ib_result - > link - > handle , & ib_result - > trans - > handle , & ar_qd , & ib_array - > ar_desc , ar_data , & ib_array - > ar_size ) ) {
2003-08-16 23:30:22 +08:00
_php_ibase_error ( TSRMLS_C ) ;
efree ( ar_data ) ;
2003-09-04 19:09:46 +08:00
goto _php_ibase_fetch_error ;
2003-08-16 23:30:22 +08:00
}
2003-09-04 19:09:46 +08:00
if ( _php_ibase_arr_zval ( result , ar_data , ib_array - > ar_size , ib_array , 0 , flag TSRMLS_CC ) = = FAILURE ) {
2003-08-16 23:30:22 +08:00
efree ( ar_data ) ;
2003-09-04 19:09:46 +08:00
goto _php_ibase_fetch_error ;
2003-08-16 23:30:22 +08:00
}
2003-08-05 21:17:16 +08:00
efree ( ar_data ) ;
2003-08-20 20:22:58 +08:00
} else { /* blob id only */
2003-09-03 06:37:26 +08:00
ISC_QUAD ar_qd = * ( ISC_QUAD * ) var - > sqldata ;
2003-09-04 19:09:46 +08:00
ZVAL_STRINGL ( result , _php_ibase_quad_to_string ( ar_qd ) , BLOB_ID_LEN , 0 ) ;
2003-08-20 20:22:58 +08:00
}
2003-09-04 19:09:46 +08:00
break ;
_php_ibase_fetch_error :
zval_dtor ( result ) ;
FREE_ZVAL ( result ) ;
RETURN_FALSE ;
2003-03-16 13:00:50 +08:00
} /* switch */
2002-03-15 23:26:01 +08:00
if ( fetch_type & FETCH_ROW ) {
2003-09-04 19:09:46 +08:00
add_index_zval ( return_value , i , result ) ;
2000-03-13 03:44:23 +08:00
} else {
2003-09-04 19:09:46 +08:00
add_assoc_zval ( return_value , var - > aliasname , result ) ;
2000-03-13 03:44:23 +08:00
}
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
}
}
2003-03-16 13:00:50 +08:00
} /* for field */
2000-03-13 03:44:23 +08:00
}
/* }}} */
2003-08-20 20:40:05 +08:00
/* {{{ proto array ibase_fetch_row(resource result [, int fetch_flags])
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-08-20 20:40:05 +08:00
/* {{{ proto array ibase_fetch_assoc(resource result [, int fetch_flags])
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-08-20 20:40:05 +08:00
/* {{{ proto object ibase_fetch_object(resource result [, int fetch_flags])
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-20 21:02:26 +08:00
ib_query = ( ibase_query * ) emalloc ( sizeof ( ibase_query ) ) ;
2003-08-20 20:40:05 +08:00
if ( _php_ibase_alloc_query ( ib_query , ib_link , trans , query , ib_link - > dialect , trans_res_id TSRMLS_CC ) = = FAILURE ) {
efree ( ib_query ) ;
2000-03-13 03:44:23 +08:00
RETURN_FALSE ;
}
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-08-29 06:12:06 +08:00
/* {{{ proto mixed ibase_execute(resource query [, mixed bind_arg [, mixed bind_arg [, ...]]])
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-28 06:55:06 +08:00
ibase_result * 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
}
2003-08-28 06:55:06 +08:00
/* Have we used this cursor before and it's still open (exec proc has no cursor) ? */
if ( ib_query - > result_res_id ! = 0 & & ib_query - > statement_type ! = isc_info_sql_stmt_exec_procedure ) {
2003-09-02 21:17:56 +08:00
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-28 06:55:06 +08:00
/* invalidate previous results returned by this query (not necessary for exec proc) */
zend_list_delete ( ib_query - > result_res_id ) ;
2000-06-25 00:24:29 +08:00
}
2003-08-21 03:47:00 +08:00
2003-08-28 06:55:06 +08:00
if ( _php_ibase_exec ( INTERNAL_FUNCTION_PARAM_PASSTHRU , & 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
2003-08-28 06:55:06 +08:00
if ( result ! = NULL ) {
result - > type = EXECUTE_RESULT ;
if ( ib_query - > statement_type = = isc_info_sql_stmt_exec_procedure ) {
result - > stmt = NULL ;
2003-08-21 03:47:00 +08:00
}
2003-08-28 06:55:06 +08:00
ib_query - > result_res_id = zend_list_insert ( result , le_result ) ;
2003-08-21 03:47:00 +08:00
RETURN_RESOURCE ( ib_query - > result_res_id ) ;
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
2003-08-29 06:12:06 +08:00
/* {{{ proto bool 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-09-03 06:19:18 +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-09-05 06:37:14 +08:00
/* {{{ _php_ibase_field_info() */
static void _php_ibase_field_info ( zval * return_value , XSQLVAR * var )
2003-09-03 03:30:20 +08:00
{
2003-09-05 06:37:14 +08:00
unsigned short len ;
char buf [ 16 ] , * s = buf ;
2003-09-03 03:30:20 +08:00
2003-09-05 06:37:14 +08:00
array_init ( return_value ) ;
add_index_stringl ( return_value , 0 , var - > sqlname , var - > sqlname_length , 1 ) ;
add_assoc_stringl ( return_value , " name " , var - > sqlname , var - > sqlname_length , 1 ) ;
add_index_stringl ( return_value , 1 , var - > aliasname , var - > aliasname_length , 1 ) ;
add_assoc_stringl ( return_value , " alias " , var - > aliasname , var - > aliasname_length , 1 ) ;
add_index_stringl ( return_value , 2 , var - > relname , var - > relname_length , 1 ) ;
add_assoc_stringl ( return_value , " relation " , var - > relname , var - > relname_length , 1 ) ;
len = sprintf ( buf , " %d " , var - > sqllen ) ;
add_index_stringl ( return_value , 3 , buf , len , 1 ) ;
add_assoc_stringl ( return_value , " length " , buf , len , 1 ) ;
2003-09-03 06:19:18 +08:00
if ( var - > sqlscale < 0 ) {
unsigned short precision ;
switch ( var - > sqltype & ~ 1 ) {
case SQL_SHORT :
2003-09-03 03:30:20 +08:00
precision = 4 ;
2003-09-03 06:19:18 +08:00
break ;
case SQL_LONG :
2003-09-03 03:30:20 +08:00
precision = 9 ;
2003-09-03 06:19:18 +08:00
break ;
2003-09-03 03:30:20 +08:00
# ifdef SQL_INT64
2003-09-03 06:19:18 +08:00
case SQL_INT64 :
2003-09-03 03:30:20 +08:00
precision = 18 ;
2003-09-03 06:19:18 +08:00
break ;
# endif
}
2003-09-05 06:37:14 +08:00
len = sprintf ( buf , " NUMERIC(%d,%d) " , precision , - var - > sqlscale ) ;
add_index_stringl ( return_value , 4 , s , len , 1 ) ;
add_assoc_stringl ( return_value , " type " , s , len , 1 ) ;
2003-09-03 06:19:18 +08:00
} else {
switch ( var - > sqltype & ~ 1 ) {
case SQL_TEXT :
s = " CHAR " ;
break ;
case SQL_VARYING :
s = " VARCHAR " ;
break ;
case SQL_SHORT :
s = " SMALLINT " ;
break ;
case SQL_LONG :
s = " INTEGER " ;
break ;
case SQL_FLOAT :
s = " FLOAT " ; break ;
case SQL_DOUBLE :
case SQL_D_FLOAT :
s = " DOUBLE PRECISION " ; break ;
# ifdef SQL_INT64
case SQL_INT64 :
2003-09-03 03:30:20 +08:00
s = " BIGINT " ;
2003-09-03 06:19:18 +08:00
break ;
2003-09-03 03:30:20 +08:00
# endif
# ifdef SQL_TIMESTAMP
2003-09-03 06:19:18 +08:00
case SQL_TIMESTAMP :
s = " TIMESTAMP " ;
break ;
case SQL_TYPE_DATE :
s = " DATE " ;
break ;
case SQL_TYPE_TIME :
s = " TIME " ;
break ;
2003-09-03 03:30:20 +08:00
# else
2003-09-03 06:19:18 +08:00
case SQL_DATE :
s = " DATE " ;
break ;
2003-09-03 03:30:20 +08:00
# endif
2003-09-03 06:19:18 +08:00
case SQL_BLOB :
s = " BLOB " ;
break ;
case SQL_ARRAY :
s = " ARRAY " ;
break ;
/* FIXME: provide more detailed information about the field type, field size
* and array dimensions */
case SQL_QUAD :
s = " QUAD " ;
break ;
}
2003-09-05 06:37:14 +08:00
add_index_string ( return_value , 4 , s , 1 ) ;
add_assoc_string ( return_value , " type " , s , 1 ) ;
2003-09-03 03:30:20 +08:00
}
}
/* }}} */
2003-09-03 06:19:18 +08:00
/* {{{ proto array ibase_field_info(resource query_result, int field_number)
2000-03-13 03:44:23 +08:00
Get information about a field */
PHP_FUNCTION ( ibase_field_info )
{
2000-04-18 10:52:45 +08:00
zval * * result_arg , * * field_arg ;
2003-09-05 06:37:14 +08:00
int type ;
2003-09-03 03:30:20 +08:00
XSQLDA * sqlda ;
2000-03-13 03:44:23 +08:00
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 ;
}
2003-09-03 03:30:20 +08:00
zend_list_find ( Z_LVAL_PP ( result_arg ) , & type ) ;
if ( type = = le_query ) {
ibase_query * ib_query ;
2000-04-18 10:52:45 +08:00
2003-09-03 03:30:20 +08:00
ZEND_FETCH_RESOURCE ( ib_query , ibase_query * , result_arg , - 1 , " InterBase query " , le_query ) ;
sqlda = ib_query - > out_sqlda ;
} else {
ibase_result * ib_result ;
ZEND_FETCH_RESOURCE ( ib_result , ibase_result * , result_arg , - 1 , " InterBase result " , le_result ) ;
sqlda = ib_result - > out_sqlda ;
}
if ( sqlda = = NULL ) {
2003-08-28 08:11:16 +08:00
_php_ibase_module_error ( " Trying to get field info from a non-select query " TSRMLS_CC ) ;
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-09-03 03:30:20 +08:00
if ( Z_LVAL_PP ( field_arg ) < 0 | | Z_LVAL_PP ( field_arg ) > = sqlda - > sqld ) {
2000-03-13 03:44:23 +08:00
RETURN_FALSE ;
2003-03-16 13:00:50 +08:00
}
2003-09-05 06:37:14 +08:00
_php_ibase_field_info ( return_value , sqlda - > sqlvar + Z_LVAL_PP ( field_arg ) ) ;
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 * * result_arg , * * field_arg ;
ibase_query * ib_query ;
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 ;
}
2003-09-05 06:37:14 +08:00
_php_ibase_field_info ( return_value , ib_query - > in_sqlda - > sqlvar + Z_LVAL_PP ( field_arg ) ) ;
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...*/
2003-08-28 08:11:16 +08:00
_php_ibase_module_error ( " PHP module internal error " TSRMLS_CC ) ;
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-08-29 06:12:06 +08:00
/* {{{ proto resource 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 ;
2003-08-20 20:22:58 +08:00
ibase_blob * ib_blob ;
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 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
}
2003-08-20 20:22:58 +08:00
ib_blob = ( ibase_blob * ) emalloc ( sizeof ( ibase_blob ) ) ;
2000-03-13 03:44:23 +08:00
ib_blob - > bl_handle = NULL ;
2003-08-18 08:14:53 +08:00
ib_blob - > type = BLOB_INPUT ;
1999-04-22 10:48:28 +08:00
2003-08-20 20:22:58 +08:00
if ( isc_create_blob ( IB_STATUS , & ib_link - > handle , & trans - > handle , & ib_blob - > bl_handle , & ib_blob - > bl_qd ) ) {
2002-07-19 17:21:29 +08:00
_php_ibase_error ( TSRMLS_C ) ;
2003-08-20 20:22:58 +08:00
efree ( ib_blob ) ;
1999-04-22 10:48:28 +08:00
RETURN_FALSE ;
}
2003-08-20 20:22:58 +08:00
ZEND_REGISTER_RESOURCE ( return_value , ib_blob , le_blob ) ;
2000-03-13 03:44:23 +08:00
}
/* }}} */
1999-04-22 10:48:28 +08:00
2003-08-29 06:12:06 +08:00
/* {{{ proto resource ibase_blob_open([ resource link_identifier, ] 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-08-20 20:22:58 +08:00
zval * * blob_arg , * * link_arg ;
ibase_db_link * link ;
2003-08-18 08:14:53 +08:00
ibase_trans * trans = NULL ;
2003-08-20 20:22:58 +08:00
ibase_blob * ib_blob ;
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-08-20 20:22:58 +08:00
switch ( ZEND_NUM_ARGS ( ) ) {
case 1 :
if ( zend_get_parameters_ex ( 1 , & blob_arg ) ! = SUCCESS ) {
WRONG_PARAM_COUNT ;
}
ZEND_FETCH_RESOURCE2 ( link , ibase_db_link * , NULL , IBG ( default_link ) , " InterBase link " , le_link , le_plink ) ;
break ;
case 2 :
if ( zend_get_parameters_ex ( 2 , & link_arg , & blob_arg ) ! = SUCCESS ) {
WRONG_PARAM_COUNT ;
}
_php_ibase_get_link_trans ( INTERNAL_FUNCTION_PARAM_PASSTHRU , link_arg , & link , & trans ) ;
break ;
default :
WRONG_PARAM_COUNT ;
2000-03-13 03:44:23 +08:00
}
1999-04-22 10:48:28 +08:00
2003-08-18 08:14:53 +08:00
convert_to_string_ex ( blob_arg ) ;
2003-08-20 20:22:58 +08:00
ib_blob = ( ibase_blob * ) emalloc ( sizeof ( ibase_blob ) ) ;
ib_blob - > bl_handle = NULL ;
ib_blob - > type = BLOB_OUTPUT ;
2003-08-18 08:14:53 +08:00
2003-08-20 20:22:58 +08:00
if ( ! _php_ibase_string_to_quad ( Z_STRVAL_PP ( blob_arg ) , & ( ib_blob - > bl_qd ) ) ) {
2003-08-28 08:11:16 +08:00
_php_ibase_module_error ( " String is not a BLOB ID " TSRMLS_CC ) ;
2003-08-16 09:58:29 +08:00
efree ( ib_blob ) ;
2000-03-13 03:44:23 +08:00
RETURN_FALSE ;
}
2003-08-18 08:14:53 +08:00
/* open default transaction */
2003-08-20 20:22:58 +08:00
if ( _php_ibase_def_trans ( link , & trans TSRMLS_CC ) = = FAILURE ) {
efree ( ib_blob ) ;
2003-08-18 08:14:53 +08:00
RETURN_FALSE ;
}
2003-08-18 00:13:52 +08:00
2003-08-20 20:22:58 +08:00
if ( isc_open_blob ( IB_STATUS , & link - > handle , & trans - > handle , & ib_blob - > bl_handle , & ib_blob - > bl_qd ) ) {
2002-07-19 17:21:29 +08:00
_php_ibase_error ( TSRMLS_C ) ;
2003-08-20 20:22:58 +08:00
efree ( ib_blob ) ;
1999-04-22 10:48:28 +08:00
RETURN_FALSE ;
}
2000-03-13 03:44:23 +08:00
2003-08-20 20:22:58 +08:00
ZEND_REGISTER_RESOURCE ( return_value , ib_blob , le_blob ) ;
1999-04-22 10:48:28 +08:00
}
2003-08-18 00:13:52 +08:00
/* }}} */
1999-04-22 10:48:28 +08:00
2003-08-29 06:12:06 +08:00
/* {{{ proto bool ibase_blob_add(resource blob_handle, 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 ;
2003-08-20 20:22:58 +08:00
ibase_blob * 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-08-20 20:22:58 +08:00
ZEND_FETCH_RESOURCE ( ib_blob , ibase_blob * , blob_arg , - 1 , " Interbase blob " , le_blob ) ;
2003-08-18 08:14:53 +08:00
if ( ib_blob - > type ! = BLOB_INPUT ) {
2003-08-28 08:11:16 +08:00
_php_ibase_module_error ( " BLOB is not open for input " TSRMLS_CC ) ;
2003-08-18 08:14:53 +08:00
RETURN_FALSE ;
}
2003-08-20 20:22:58 +08:00
2003-08-17 20:31:55 +08:00
if ( _php_ibase_blob_add ( string_arg , ib_blob TSRMLS_CC ) ! = SUCCESS ) {
RETURN_FALSE ;
1999-04-22 10:48:28 +08:00
}
}
/* }}} */
2003-08-29 06:12:06 +08:00
/* {{{ proto string ibase_blob_get(resource blob_handle, int len)
2000-03-13 03:44:23 +08:00
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 ;
2003-08-20 20:22:58 +08:00
ibase_blob * 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-08-20 20:22:58 +08:00
ZEND_FETCH_RESOURCE ( ib_blob , ibase_blob * , blob_arg , - 1 , " Interbase blob " , le_blob ) ;
2000-03-13 03:44:23 +08:00
2003-08-18 08:14:53 +08:00
if ( ib_blob - > type ! = BLOB_OUTPUT ) {
2003-08-28 08:11:16 +08:00
_php_ibase_module_error ( " BLOB is not open for output " TSRMLS_CC ) ;
2003-08-18 08:14:53 +08:00
RETURN_FALSE ;
}
2003-08-17 20:31:55 +08:00
convert_to_long_ex ( len_arg ) ;
2003-08-18 08:14:53 +08:00
2003-08-17 20:31:55 +08:00
if ( _php_ibase_blob_get ( return_value , ib_blob , Z_LVAL_PP ( len_arg ) TSRMLS_CC ) ! = SUCCESS ) {
RETURN_FALSE ;
1999-04-22 10:48:28 +08:00
}
2000-03-13 03:44:23 +08:00
}
/* }}} */
/* {{{ _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 ;
2003-08-20 20:22:58 +08:00
ibase_blob * ib_blob ;
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
}
2003-08-20 20:22:58 +08:00
ZEND_FETCH_RESOURCE ( ib_blob , ibase_blob * , blob_arg , - 1 , " Interbase blob " , le_blob ) ;
2003-08-16 09:58:29 +08:00
2000-04-18 10:52:45 +08:00
if ( bl_end = = BLOB_CLOSE ) { /* return id here */
2003-08-18 08:14:53 +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 ?*/
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-08-18 08:14:53 +08:00
2003-08-20 20:22:58 +08:00
RETVAL_STRINGL ( _php_ibase_quad_to_string ( ib_blob - > bl_qd ) , BLOB_ID_LEN , 0 ) ;
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-08-18 08:14:53 +08:00
RETVAL_BOOL ( 1 ) ;
1999-04-22 10:48:28 +08:00
}
2003-08-18 08:14:53 +08:00
zend_list_delete ( Z_LVAL_PP ( blob_arg ) ) ;
2000-03-13 03:44:23 +08:00
}
/* }}} */
1999-04-22 10:48:28 +08:00
2003-08-29 06:12:06 +08:00
/* {{{ proto string ibase_blob_close(resource blob_handle)
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-08-29 06:12:06 +08:00
/* {{{ proto bool ibase_blob_cancel(resource blob_handle)
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
}
/* }}} */
2003-08-29 06:12:06 +08:00
/* {{{ proto array ibase_blob_info([ resource link_identifier, ] string blob_id)
2000-03-13 03:44:23 +08:00
Return blob length and other useful info */
PHP_FUNCTION ( ibase_blob_info )
{
2003-08-28 06:55:06 +08:00
zval * * blob_arg , * * link_arg ;
2003-08-20 20:22:58 +08:00
ibase_db_link * link ;
2003-08-18 08:14:53 +08:00
ibase_trans * trans = NULL ;
2003-08-20 20:22:58 +08:00
ibase_blob ib_blob = { NULL , { 0 , 0 } , BLOB_INPUT } ;
2000-03-13 03:44:23 +08:00
IBASE_BLOBINFO bl_info ;
1999-04-22 10:48:28 +08:00
2000-03-13 03:44:23 +08:00
RESET_ERRMSG ;
2003-08-20 20:22:58 +08:00
switch ( ZEND_NUM_ARGS ( ) ) {
case 1 :
if ( zend_get_parameters_ex ( 1 , & blob_arg ) ! = SUCCESS ) {
WRONG_PARAM_COUNT ;
}
ZEND_FETCH_RESOURCE2 ( link , ibase_db_link * , NULL , IBG ( default_link ) , " InterBase link " , le_link , le_plink ) ;
break ;
case 2 :
if ( zend_get_parameters_ex ( 2 , & link_arg , & blob_arg ) ! = SUCCESS ) {
WRONG_PARAM_COUNT ;
}
_php_ibase_get_link_trans ( INTERNAL_FUNCTION_PARAM_PASSTHRU , link_arg , & link , & trans ) ;
break ;
default :
WRONG_PARAM_COUNT ;
1999-04-22 10:48:28 +08:00
}
2003-08-20 20:22:58 +08:00
convert_to_string_ex ( blob_arg ) ;
if ( ! _php_ibase_string_to_quad ( Z_STRVAL_PP ( blob_arg ) , & ( ib_blob . bl_qd ) ) ) {
2003-08-28 08:11:16 +08:00
_php_ibase_module_error ( " Unrecognized BLOB ID " TSRMLS_CC ) ;
2003-08-16 09:58:29 +08:00
RETURN_FALSE ;
}
2003-08-20 20:22:58 +08:00
2003-08-18 08:14:53 +08:00
/* open default transaction */
2003-08-20 20:22:58 +08:00
if ( _php_ibase_def_trans ( link , & trans TSRMLS_CC ) = = FAILURE ) {
2003-08-18 08:14:53 +08:00
RETURN_FALSE ;
}
2003-08-20 20:22:58 +08:00
if ( ib_blob . bl_qd . gds_quad_high | | ib_blob . bl_qd . gds_quad_low ) { /* not null ? */
if ( isc_open_blob ( IB_STATUS , & link - > handle , & trans - > handle , & ib_blob . bl_handle , & ib_blob . 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-08-20 20:22:58 +08:00
if ( _php_ibase_blob_info ( ib_blob . bl_handle , & bl_info TSRMLS_CC ) ) {
2000-03-13 03:44:23 +08:00
RETURN_FALSE ;
}
2003-08-20 20:22:58 +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 ;
}
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
}
2003-08-20 20:22:58 +08:00
array_init ( return_value ) ;
2003-08-28 06:55:06 +08:00
add_index_long ( return_value , 0 , bl_info . total_length ) ;
add_assoc_long ( return_value , " length " , bl_info . total_length ) ;
add_index_long ( return_value , 1 , bl_info . num_segments ) ;
add_assoc_long ( return_value , " numseg " , bl_info . num_segments ) ;
add_index_long ( return_value , 2 , bl_info . max_segment ) ;
add_assoc_long ( return_value , " maxseg " , bl_info . max_segment ) ;
add_index_bool ( return_value , 3 , bl_info . bl_stream ) ;
add_assoc_bool ( return_value , " stream " , bl_info . bl_stream ) ;
add_index_bool ( return_value , 4 , ( ! ib_blob . bl_qd . gds_quad_high & & ! ib_blob . bl_qd . gds_quad_low ) ) ;
add_assoc_bool ( return_value , " isnull " , ( ! ib_blob . bl_qd . gds_quad_high & & ! ib_blob . bl_qd . gds_quad_low ) ) ;
1999-04-22 10:48:28 +08:00
}
/* }}} */
2003-08-29 06:12:06 +08:00
/* {{{ proto bool ibase_blob_echo([ resource link_identifier, ] string blob_id)
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-08-20 20:22:58 +08:00
zval * * blob_arg , * * link_arg ;
ibase_db_link * link ;
2003-08-18 08:14:53 +08:00
ibase_trans * trans = NULL ;
2003-08-21 00:13:51 +08:00
ibase_blob ib_blob_id = { NULL , { 0 , 0 } , BLOB_OUTPUT } ;
2003-08-20 20:22:58 +08:00
char bl_data [ IBASE_BLOB_SEG ] ;
unsigned short seg_len ;
2000-03-13 03:44:23 +08:00
RESET_ERRMSG ;
1999-04-22 10:48:28 +08:00
2003-08-20 20:22:58 +08:00
switch ( ZEND_NUM_ARGS ( ) ) {
case 1 :
if ( zend_get_parameters_ex ( 1 , & blob_arg ) ! = SUCCESS ) {
WRONG_PARAM_COUNT ;
}
ZEND_FETCH_RESOURCE2 ( link , ibase_db_link * , NULL , IBG ( default_link ) , " InterBase link " , le_link , le_plink ) ;
break ;
case 2 :
if ( zend_get_parameters_ex ( 2 , & link_arg , & blob_arg ) ! = SUCCESS ) {
WRONG_PARAM_COUNT ;
}
_php_ibase_get_link_trans ( INTERNAL_FUNCTION_PARAM_PASSTHRU , link_arg , & link , & trans ) ;
break ;
default :
WRONG_PARAM_COUNT ;
1999-04-22 10:48:28 +08:00
}
2000-03-13 03:44:23 +08:00
2003-08-20 20:22:58 +08:00
convert_to_string_ex ( blob_arg ) ;
if ( ! _php_ibase_string_to_quad ( Z_STRVAL_PP ( blob_arg ) , & ( ib_blob_id . bl_qd ) ) ) {
2003-08-28 08:11:16 +08:00
_php_ibase_module_error ( " Unrecognized BLOB ID " TSRMLS_CC ) ;
2003-08-16 09:58:29 +08:00
RETURN_FALSE ;
}
2003-08-20 20:22:58 +08:00
2003-08-18 08:14:53 +08:00
/* open default transaction */
2003-08-20 20:22:58 +08:00
if ( _php_ibase_def_trans ( link , & trans TSRMLS_CC ) = = FAILURE ) {
2003-08-18 08:14:53 +08:00
RETURN_FALSE ;
}
2000-03-13 03:44:23 +08:00
2003-08-20 20:22:58 +08:00
if ( isc_open_blob ( IB_STATUS , & link - > handle , & trans - > handle , & ib_blob_id . bl_handle , & ib_blob_id . bl_qd ) ) {
2003-08-18 08:14:53 +08:00
_php_ibase_error ( TSRMLS_C ) ;
RETURN_FALSE ;
}
1999-04-22 10:48:28 +08:00
2003-08-20 20:22:58 +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 ) {
2003-08-18 08:14:53 +08:00
PHPWRITE ( bl_data , seg_len ) ;
}
if ( IB_STATUS [ 0 ] & & ( IB_STATUS [ 1 ] ! = isc_segstr_eof ) ) {
_php_ibase_error ( TSRMLS_C ) ;
RETURN_FALSE ;
}
2003-08-20 20:22:58 +08:00
if ( isc_close_blob ( IB_STATUS , & ib_blob_id . bl_handle ) ) {
2003-08-18 08:14:53 +08:00
_php_ibase_error ( TSRMLS_C ) ;
RETURN_FALSE ;
}
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 ;
2003-08-20 20:22:58 +08:00
ibase_blob ib_blob = { NULL , { 0 , 0 } , 0 } ;
2000-03-13 03:44:23 +08:00
ibase_db_link * ib_link ;
2003-08-12 10:16:40 +08:00
ibase_trans * trans = NULL ;
2003-08-18 00:13:52 +08:00
char bl_data [ IBASE_BLOB_SEG ] ;
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-20 20:22:58 +08:00
if ( isc_create_blob ( IB_STATUS , & ib_link - > handle , & 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
}
2003-08-20 20:22:58 +08:00
RETURN_STRINGL ( _php_ibase_quad_to_string ( ib_blob . bl_qd ) , BLOB_ID_LEN , 0 ) ;
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 ] ;
2003-08-20 20:22:58 +08:00
unsigned long dummy_count [ 15 ] ;
2003-08-14 18:55:02 +08:00
/**
* 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 ) ;
2003-08-20 20:22:58 +08:00
isc_event_counts ( dummy_count , * l , * event_buf , * result_buf ) ;
2003-08-14 18:55:02 +08:00
}
/* }}} */
2003-08-29 06:12:06 +08:00
/* {{{ proto string ibase_wait_event([resource link_identifier,] string event [, string event [, ...]])
2003-08-14 18:55:02 +08:00
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 ;
2003-08-20 20:22:58 +08:00
unsigned long occurred_event [ 15 ] ;
2003-08-14 18:55:02 +08:00
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 ;
2003-08-20 20:22:58 +08:00
unsigned long occurred_event [ 15 ] ;
2003-08-21 06:59:33 +08:00
zval event_name , link_id , return_value , * args [ 2 ] ;
2003-08-15 08:06:07 +08:00
2003-08-21 06:59:33 +08:00
/* initialize at runtime to satisify picky compilers */
args [ 0 ] = & event_name ;
args [ 1 ] = & link_id ;
2003-08-15 08:06:07 +08:00
/* 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 ) ) {
2003-08-28 08:11:16 +08:00
_php_ibase_module_error ( " Error calling callback %s " TSRMLS_CC , Z_STRVAL_P ( event - > callback ) ) ;
2003-08-15 08:06:07 +08:00
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 ;
}
/* }}} */
2003-08-29 06:12:06 +08:00
/* {{{ proto resource ibase_set_event_handler([resource link_identifier,] callback handler, string event [, string event [, ...]])
2003-08-15 08:06:07 +08:00
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 */
2003-08-16 23:30:22 +08:00
if ( Z_TYPE_PP ( args [ 0 ] ) ! = IS_STRING ) {
2003-08-15 08:06:07 +08:00
2003-08-16 23:30:22 +08:00
cb_arg = args [ 1 ] ;
2003-08-15 08:06:07 +08:00
i = 2 ;
2003-08-16 23:30:22 +08:00
ZEND_FETCH_RESOURCE2 ( ib_link , ibase_db_link * , args [ 0 ] , - 1 , " InterBase link " , le_link , le_plink ) ;
2003-08-15 08:06:07 +08:00
convert_to_long_ex ( args [ 0 ] ) ;
link_res_id = Z_LVAL_PP ( args [ 0 ] ) ;
} else {
if ( ZEND_NUM_ARGS ( ) > 16 ) {
efree ( args ) ;
WRONG_PARAM_COUNT ;
}
2003-08-16 23:30:22 +08:00
cb_arg = args [ 0 ] ;
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 ) ;
link_res_id = IBG ( default_link ) ;
}
/* get the callback */
2003-08-16 00:13:51 +08:00
if ( ! zend_is_callable ( * cb_arg , 0 , & callback_name ) ) {
2003-08-28 08:11:16 +08:00
_php_ibase_module_error ( " Callback argument %s is not a callable function " TSRMLS_CC , callback_name ) ;
2003-08-15 08:06:07 +08:00
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
/* }}} */
2003-09-24 04:58:14 +08:00
/* {{{ proto int ibase_gen_id([ resource link_identifier, ] string generator [, int increment ])
Increments the named generator and returns its new value */
PHP_FUNCTION ( ibase_gen_id )
{
char query [ 128 ] ;
zval * * arg1 , * * arg2 , * * arg3 , * * query_arg ;
ibase_db_link * ib_link ;
ibase_trans * trans = NULL ;
long increment ;
# ifdef SQL_INT64
ISC_INT64 result ;
# else
ISC_LONG result ;
# endif
XSQLDA out_sqlda ;
RESET_ERRMSG ;
switch ( ZEND_NUM_ARGS ( ) ) {
case 1 :
if ( zend_get_parameters_ex ( 1 , & arg1 ) = = FAILURE ) {
RETURN_FALSE ;
}
ZEND_FETCH_RESOURCE2 ( ib_link , ibase_db_link * , NULL , IBG ( default_link ) , " InterBase link " , le_link , le_plink ) ;
query_arg = arg1 ;
increment = 1 ;
break ;
case 2 :
if ( zend_get_parameters_ex ( 2 , & arg1 , & arg2 ) = = FAILURE ) {
RETURN_FALSE ;
}
if ( Z_TYPE_PP ( arg1 ) = = IS_STRING ) /* first param is generator, second is inc */
{
query_arg = arg1 ;
convert_to_long_ex ( arg2 ) ;
increment = Z_LVAL_PP ( arg2 ) ;
ZEND_FETCH_RESOURCE2 ( ib_link , ibase_db_link * , NULL , IBG ( default_link ) , " InterBase link " , le_link , le_plink ) ;
} else {
_php_ibase_get_link_trans ( INTERNAL_FUNCTION_PARAM_PASSTHRU , arg1 , & ib_link , & trans ) ;
query_arg = arg2 ;
increment = 1 ;
}
break ;
case 3 :
if ( zend_get_parameters_ex ( 3 , & arg1 , & arg2 , & arg3 ) = = FAILURE ) {
RETURN_FALSE ;
}
ZEND_FETCH_RESOURCE2 ( ib_link , ibase_db_link * , arg1 , - 1 , " InterBase link " , le_link , le_plink ) ;
query_arg = arg2 ;
convert_to_long_ex ( arg3 ) ;
increment = Z_LVAL_PP ( arg3 ) ;
break ;
default :
WRONG_PARAM_COUNT ;
break ;
}
convert_to_string_ex ( query_arg ) ;
sprintf ( query , " SELECT GEN_ID(%s,%ld) FROM rdb$database " , Z_STRVAL_PP ( query_arg ) , increment ) ;
/* open default transaction */
if ( _php_ibase_def_trans ( ib_link , & trans TSRMLS_CC ) = = FAILURE ) {
RETURN_FALSE ;
}
/* allocate a minimal descriptor area */
out_sqlda . sqln = out_sqlda . sqld = 1 ;
out_sqlda . version = SQLDA_CURRENT_VERSION ;
/* allocate the field for the result */
# ifdef SQL_INT64
out_sqlda . sqlvar [ 0 ] . sqltype = SQL_INT64 ;
# else
out_sqlda . sqlvar [ 0 ] . sqltype = SQL_LONG ;
# endif
out_sqlda . sqlvar [ 0 ] . sqlscale = 0 ;
out_sqlda . sqlvar [ 0 ] . sqllen = sizeof ( result ) ;
out_sqlda . sqlvar [ 0 ] . sqldata = ( void * ) & result ;
/* execute the query */
if ( isc_dsql_exec_immed2 ( IB_STATUS , & ib_link - > handle , & trans - > handle , 0 , query , SQL_DIALECT_CURRENT , NULL , & out_sqlda ) )
{
_php_ibase_error ( TSRMLS_C ) ;
RETURN_FALSE ;
}
/* don't return the generator value as a string unless it doesn't fit in a long */
# ifdef SQL_INT64
if ( result > LONG_MAX )
# endif
{
char res [ 24 ] ;
sprintf ( res , " % " LL_MASK " d " , result ) ;
RETURN_STRING ( res , 1 ) ;
}
RETURN_LONG ( ( long ) result ) ;
}
/* }}} */
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
*/