1999-04-22 02:48:28 +00:00
/*
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2004-01-08 08:18:22 +00:00
| PHP Version 5 |
1999-04-22 02:48:28 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2005-08-03 14:08:58 +00:00
| Copyright ( c ) 1997 - 2005 The PHP Group |
1999-04-22 02:48:28 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2003-06-10 20:04:29 +00:00
| This source file is subject to version 3.0 of the PHP license , |
1999-07-16 13:13:16 +00:00
| that is bundled with this package in the file LICENSE , and is |
2003-06-10 20:04:29 +00:00
| available through the world - wide - web at the following url : |
| http : //www.php.net/license/3_0.txt. |
1999-07-16 13:13:16 +00: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 02:48:28 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Authors : Zeev Suraski < zeev @ zend . com > |
| Tom May < tom @ go2net . com > |
2002-11-05 08:29:57 +00:00
| Timm Friebe < php_sybase_ct @ thekid . de > |
1999-04-22 02:48:28 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
*/
2001-08-13 19:45:26 +00:00
1999-04-22 02:48:28 +00:00
/* $Id$ */
2001-05-24 10:07:29 +00:00
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
1999-04-22 02:48:28 +00:00
# include "php.h"
1999-08-13 00:14:17 +00:00
# include "php_sybase_ct.h"
1999-12-04 19:19:57 +00:00
# include "ext/standard/php_standard.h"
2000-04-06 21:07:44 +00:00
# include "ext/standard/info.h"
1999-04-22 02:48:28 +00:00
# include "php_globals.h"
2000-09-12 20:54:36 +00:00
# include "php_ini.h"
/* True globals, no need for thread safety */
static int le_link , le_plink , le_result ;
1999-04-22 02:48:28 +00:00
# if HAVE_SYBASE_CT
1999-09-04 13:03:09 +00:00
function_entry sybase_functions [ ] = {
2004-01-25 20:03:10 +00:00
PHP_FE ( sybase_connect , NULL )
PHP_FE ( sybase_pconnect , NULL )
PHP_FE ( sybase_close , NULL )
PHP_FE ( sybase_select_db , NULL )
PHP_FE ( sybase_query , NULL )
PHP_FE ( sybase_unbuffered_query , NULL )
PHP_FE ( sybase_free_result , NULL )
PHP_FE ( sybase_get_last_message , NULL )
PHP_FE ( sybase_num_rows , NULL )
PHP_FE ( sybase_num_fields , NULL )
PHP_FE ( sybase_fetch_row , NULL )
PHP_FE ( sybase_fetch_array , NULL )
PHP_FE ( sybase_fetch_assoc , NULL )
PHP_FE ( sybase_fetch_object , NULL )
PHP_FE ( sybase_data_seek , NULL )
PHP_FE ( sybase_fetch_field , NULL )
PHP_FE ( sybase_field_seek , NULL )
PHP_FE ( sybase_result , NULL )
PHP_FE ( sybase_affected_rows , NULL )
PHP_FE ( sybase_min_client_severity , NULL )
PHP_FE ( sybase_min_server_severity , NULL )
PHP_FE ( sybase_set_message_handler , NULL )
PHP_FE ( sybase_deadlock_retry_count , NULL )
2005-08-06 05:42:51 +00:00
# if !defined(PHP_WIN32) && !defined(HAVE_MSSQL)
2004-01-25 20:03:10 +00:00
PHP_FALIAS ( mssql_connect , sybase_connect , NULL )
PHP_FALIAS ( mssql_pconnect , sybase_pconnect , NULL )
PHP_FALIAS ( mssql_close , sybase_close , NULL )
PHP_FALIAS ( mssql_select_db , sybase_select_db , NULL )
PHP_FALIAS ( mssql_query , sybase_query , NULL )
PHP_FALIAS ( mssql_unbuffered_query , sybase_unbuffered_query , NULL )
PHP_FALIAS ( mssql_free_result , sybase_free_result , NULL )
PHP_FALIAS ( mssql_get_last_message , sybase_get_last_message , NULL )
PHP_FALIAS ( mssql_num_rows , sybase_num_rows , NULL )
PHP_FALIAS ( mssql_num_fields , sybase_num_fields , NULL )
PHP_FALIAS ( mssql_fetch_row , sybase_fetch_row , NULL )
PHP_FALIAS ( mssql_fetch_array , sybase_fetch_array , NULL )
PHP_FALIAS ( mssql_fetch_assoc , sybase_fetch_assoc , NULL )
PHP_FALIAS ( mssql_fetch_object , sybase_fetch_object , NULL )
PHP_FALIAS ( mssql_data_seek , sybase_data_seek , NULL )
PHP_FALIAS ( mssql_fetch_field , sybase_fetch_field , NULL )
PHP_FALIAS ( mssql_field_seek , sybase_field_seek , NULL )
PHP_FALIAS ( mssql_result , sybase_result , NULL )
PHP_FALIAS ( mssql_affected_rows , sybase_affected_rows , NULL )
PHP_FALIAS ( mssql_min_client_severity , sybase_min_client_severity , NULL )
PHP_FALIAS ( mssql_min_server_severity , sybase_min_server_severity , NULL )
PHP_FALIAS ( mssql_set_message_handler , sybase_set_message_handler , NULL )
PHP_FALIAS ( mssql_deadlock_retry_count , sybase_deadlock_retry_count , NULL )
2005-08-06 05:42:51 +00:00
# endif
2004-01-25 20:03:10 +00:00
1999-04-22 02:48:28 +00:00
{ NULL , NULL , NULL }
} ;
1999-09-04 13:03:09 +00:00
zend_module_entry sybase_module_entry = {
2001-10-11 23:33:59 +00:00
STANDARD_MODULE_HEADER ,
" sybase_ct " , sybase_functions , PHP_MINIT ( sybase ) , PHP_MSHUTDOWN ( sybase ) , PHP_RINIT ( sybase ) , PHP_RSHUTDOWN ( sybase ) , PHP_MINFO ( sybase ) , NO_VERSION_YET , STANDARD_MODULE_PROPERTIES
1999-04-22 02:48:28 +00:00
} ;
2000-09-10 05:13:56 +00:00
ZEND_DECLARE_MODULE_GLOBALS ( sybase )
2001-06-26 20:56:03 +00:00
/* static CS_CONTEXT *context; */
2000-09-10 05:13:56 +00:00
2000-05-23 09:33:51 +00:00
# ifdef COMPILE_DL_SYBASE_CT
2000-05-02 00:30:36 +00:00
ZEND_GET_MODULE ( sybase )
1999-04-22 02:48:28 +00:00
# endif
2000-09-12 20:54:36 +00:00
ZEND_DECLARE_MODULE_GLOBALS ( sybase )
2002-11-12 13:13:12 +00:00
# define CHECK_LINK(link) { if (link==-1) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sybase: A link to the server could not be established"); RETURN_FALSE; } }
1999-04-22 02:48:28 +00:00
2001-07-31 04:53:54 +00:00
static int _clean_invalid_results ( list_entry * le TSRMLS_DC )
1999-04-22 02:48:28 +00:00
{
2001-09-25 21:58:48 +00:00
if ( Z_TYPE_P ( le ) = = le_result ) {
1999-09-04 13:03:09 +00:00
sybase_link * sybase_ptr = ( ( sybase_result * ) le - > ptr ) - > sybase_ptr ;
2001-08-13 19:45:26 +00:00
1999-09-04 13:03:09 +00:00
if ( ! sybase_ptr - > valid ) {
1999-04-22 02:48:28 +00:00
return 1 ;
}
}
return 0 ;
}
1999-09-04 13:03:09 +00:00
static void _free_sybase_result ( sybase_result * result )
1999-04-22 02:48:28 +00:00
{
2000-09-12 20:54:36 +00:00
int i , j ;
1999-04-22 02:48:28 +00:00
if ( result - > data ) {
2004-07-29 19:32:46 +00:00
for ( i = 0 ; i < ( result - > store ? result - > num_rows : MIN ( 1 , result - > num_rows ) ) ; i + + ) {
1999-04-22 02:48:28 +00:00
for ( j = 0 ; j < result - > num_fields ; j + + ) {
2002-11-05 08:29:57 +00:00
zval_dtor ( & result - > data [ i ] [ j ] ) ;
1999-04-22 02:48:28 +00:00
}
efree ( result - > data [ i ] ) ;
}
efree ( result - > data ) ;
}
2001-08-13 19:45:26 +00:00
1999-04-22 02:48:28 +00:00
if ( result - > fields ) {
for ( i = 0 ; i < result - > num_fields ; i + + ) {
STR_FREE ( result - > fields [ i ] . name ) ;
STR_FREE ( result - > fields [ i ] . column_source ) ;
}
efree ( result - > fields ) ;
}
efree ( result ) ;
}
2004-07-29 19:32:46 +00:00
/* Forward declaration */
static int php_sybase_finish_results ( sybase_result * result ) ;
2001-07-31 05:44:11 +00:00
static void php_free_sybase_result ( zend_rsrc_list_entry * rsrc TSRMLS_DC )
2000-10-20 18:25:16 +00:00
{
sybase_result * result = ( sybase_result * ) rsrc - > ptr ;
2001-07-31 05:44:11 +00:00
2004-07-29 19:32:46 +00:00
/* Check to see if we've read all rows */
if ( result - > sybase_ptr & & result - > sybase_ptr - > active_result_index ) {
if ( result - > sybase_ptr - > cmd ) {
ct_cancel ( NULL , result - > sybase_ptr - > cmd , CS_CANCEL_ALL ) ;
}
php_sybase_finish_results ( result ) ;
}
2000-10-20 18:25:16 +00:00
_free_sybase_result ( result ) ;
}
1999-04-22 02:48:28 +00:00
2001-07-31 05:44:11 +00:00
static void _close_sybase_link ( zend_rsrc_list_entry * rsrc TSRMLS_DC )
1999-04-22 02:48:28 +00:00
{
2000-10-20 18:25:16 +00:00
sybase_link * sybase_ptr = ( sybase_link * ) rsrc - > ptr ;
1999-04-22 02:48:28 +00:00
CS_INT con_status ;
1999-09-04 13:03:09 +00:00
sybase_ptr - > valid = 0 ;
2004-01-25 20:03:10 +00:00
if ( sybase_ptr - > callback_name ! = NULL ) {
zval_ptr_dtor ( & sybase_ptr - > callback_name ) ;
sybase_ptr - > callback_name = NULL ;
}
2000-01-15 13:39:19 +00:00
2001-07-31 04:53:54 +00:00
zend_hash_apply ( & EG ( regular_list ) , ( apply_func_t ) _clean_invalid_results TSRMLS_CC ) ;
1999-04-22 02:48:28 +00:00
/* Non-persistent connections will always be connected or we wouldn't
* get here , but since we want to check the death status anyway
* we might as well double - check the connect status .
*/
1999-09-04 13:03:09 +00:00
if ( ct_con_props ( sybase_ptr - > connection , CS_GET , CS_CON_STATUS ,
1999-04-22 02:48:28 +00:00
& con_status , CS_UNUSED , NULL ) ! = CS_SUCCEED ) {
2002-11-12 13:13:12 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: Unable to get connection status on close " ) ;
1999-04-22 02:48:28 +00:00
/* Assume the worst. */
con_status = CS_CONSTAT_CONNECTED | CS_CONSTAT_DEAD ;
}
if ( con_status & CS_CONSTAT_CONNECTED ) {
1999-09-04 13:03:09 +00:00
if ( ( con_status & CS_CONSTAT_DEAD ) | | ct_close ( sybase_ptr - > connection , CS_UNUSED ) ! = CS_SUCCEED ) {
ct_close ( sybase_ptr - > connection , CS_FORCE_CLOSE ) ;
1999-04-22 02:48:28 +00:00
}
}
2004-08-21 17:54:11 +00:00
ct_cmd_drop ( sybase_ptr - > cmd ) ;
1999-09-04 13:03:09 +00:00
ct_con_drop ( sybase_ptr - > connection ) ;
efree ( sybase_ptr ) ;
2000-09-12 20:54:36 +00:00
SybCtG ( num_links ) - - ;
1999-04-22 02:48:28 +00:00
}
2001-07-31 05:44:11 +00:00
static void _close_sybase_plink ( zend_rsrc_list_entry * rsrc TSRMLS_DC )
1999-04-22 02:48:28 +00:00
{
2000-10-20 18:25:16 +00:00
sybase_link * sybase_ptr = ( sybase_link * ) rsrc - > ptr ;
1999-04-22 02:48:28 +00:00
CS_INT con_status ;
/* Persistent connections may have been closed before a failed
* reopen attempt .
*/
1999-09-04 13:03:09 +00:00
if ( ct_con_props ( sybase_ptr - > connection , CS_GET , CS_CON_STATUS ,
1999-04-22 02:48:28 +00:00
& con_status , CS_UNUSED , NULL ) ! = CS_SUCCEED ) {
2002-11-12 13:13:12 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: Unable to get connection status on close " ) ;
1999-04-22 02:48:28 +00:00
/* Assume the worst. */
con_status = CS_CONSTAT_CONNECTED | CS_CONSTAT_DEAD ;
}
if ( con_status & CS_CONSTAT_CONNECTED ) {
1999-09-04 13:03:09 +00:00
if ( ( con_status & CS_CONSTAT_DEAD ) | | ct_close ( sybase_ptr - > connection , CS_UNUSED ) ! = CS_SUCCEED ) {
ct_close ( sybase_ptr - > connection , CS_FORCE_CLOSE ) ;
1999-04-22 02:48:28 +00:00
}
}
1999-09-04 13:03:09 +00:00
ct_con_drop ( sybase_ptr - > connection ) ;
free ( sybase_ptr ) ;
2000-09-12 20:54:36 +00:00
SybCtG ( num_persistent ) - - ;
SybCtG ( num_links ) - - ;
1999-04-22 02:48:28 +00:00
}
2001-05-23 04:17:54 +00:00
static CS_RETCODE CS_PUBLIC _client_message_handler ( CS_CONTEXT * context , CS_CONNECTION * connection , CS_CLIENTMSG * errmsg )
1999-04-22 02:48:28 +00:00
{
2001-07-28 11:36:37 +00:00
TSRMLS_FETCH ( ) ;
2000-09-12 20:54:36 +00:00
if ( CS_SEVERITY ( errmsg - > msgnumber ) > = SybCtG ( min_client_severity ) ) {
2002-11-12 13:13:12 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: Client message: %s (severity %d) " , errmsg - > msgstring , CS_SEVERITY ( errmsg - > msgnumber ) ) ;
1999-04-22 02:48:28 +00:00
}
2001-01-13 22:47:44 +00:00
STR_FREE ( SybCtG ( server_message ) ) ;
SybCtG ( server_message ) = estrdup ( errmsg - > msgstring ) ;
1999-04-22 02:48:28 +00:00
/* If this is a timeout message, return CS_FAIL to cancel the
* operation and mark the connection as dead .
*/
if ( CS_SEVERITY ( errmsg - > msgnumber ) = = CS_SV_RETRY_FAIL & &
CS_NUMBER ( errmsg - > msgnumber ) = = 63 & &
CS_ORIGIN ( errmsg - > msgnumber ) = = 2 & &
CS_LAYER ( errmsg - > msgnumber ) = = 1 )
{
return CS_FAIL ;
}
2002-11-05 08:29:57 +00:00
return CS_SUCCEED ;
1999-04-22 02:48:28 +00:00
}
2004-01-25 20:03:10 +00:00
static int _call_message_handler ( zval * callback_name , CS_SERVERMSG * srvmsg TSRMLS_DC )
1999-04-22 02:48:28 +00:00
{
2004-01-25 20:03:10 +00:00
int handled = 0 ;
if ( callback_name ) {
2004-02-15 10:37:09 +00:00
zval * msgnumber , * severity , * state , * line , * text , * retval = NULL ;
zval * * args [ 5 ] ;
MAKE_STD_ZVAL ( msgnumber ) ;
ZVAL_LONG ( msgnumber , srvmsg - > msgnumber ) ;
args [ 0 ] = & msgnumber ;
MAKE_STD_ZVAL ( severity ) ;
ZVAL_LONG ( severity , srvmsg - > severity ) ;
args [ 1 ] = & severity ;
MAKE_STD_ZVAL ( state ) ;
ZVAL_LONG ( state , srvmsg - > state ) ;
args [ 2 ] = & state ;
MAKE_STD_ZVAL ( line ) ;
ZVAL_LONG ( line , srvmsg - > line ) ;
args [ 3 ] = & line ;
MAKE_STD_ZVAL ( text ) ;
ZVAL_STRING ( text , srvmsg - > text , 1 ) ;
args [ 4 ] = & text ;
2002-11-05 08:29:57 +00:00
2004-01-25 20:03:10 +00:00
if ( call_user_function_ex ( EG ( function_table ) , NULL , callback_name , & retval , 5 , args , 0 , NULL TSRMLS_CC ) = = FAILURE ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: Cannot call the messagehandler %s " , Z_STRVAL_P ( callback_name ) ) ;
2002-11-05 08:29:57 +00:00
}
2004-02-15 10:37:09 +00:00
2004-01-25 20:03:10 +00:00
if ( retval ) {
handled = ( ( Z_TYPE_P ( retval ) ! = IS_BOOL ) | | ( Z_BVAL_P ( retval ) ! = 0 ) ) ;
zval_ptr_dtor ( & retval ) ;
2002-11-05 08:29:57 +00:00
}
2004-02-15 10:37:09 +00:00
zval_ptr_dtor ( & msgnumber ) ;
zval_ptr_dtor ( & severity ) ;
zval_ptr_dtor ( & state ) ;
zval_ptr_dtor ( & line ) ;
zval_ptr_dtor ( & text ) ;
1999-04-22 02:48:28 +00:00
}
2004-01-25 20:03:10 +00:00
return handled ;
}
static CS_RETCODE CS_PUBLIC _server_message_handler ( CS_CONTEXT * context , CS_CONNECTION * connection , CS_SERVERMSG * srvmsg )
{
sybase_link * sybase ;
int handled = 0 ;
TSRMLS_FETCH ( ) ;
/* Remember the last server message in any case */
2001-01-13 22:47:44 +00:00
STR_FREE ( SybCtG ( server_message ) ) ;
SybCtG ( server_message ) = estrdup ( srvmsg - > text ) ;
1999-04-22 02:48:28 +00:00
2004-01-25 20:03:10 +00:00
/* Retrieve sybase link */
if ( ct_con_props ( connection , CS_GET , CS_USERDATA , & sybase , CS_SIZEOF ( sybase ) , NULL ) ! = CS_SUCCEED ) {
sybase = NULL ;
}
1999-04-22 02:48:28 +00:00
/* If this is a deadlock message, set the connection's deadlock flag
* so we will retry the request . Sorry about the bare constant here ,
* but it ' s not defined anywhere and it ' s a " well-known " number .
*/
2004-01-25 20:03:10 +00:00
if ( sybase & & ( srvmsg - > msgnumber = = 1205 ) ) {
sybase - > deadlock = 1 ;
}
1999-04-22 02:48:28 +00:00
2004-01-25 20:03:10 +00:00
/* Check mininum server severity level */
if ( srvmsg - > severity < SybCtG ( min_server_severity ) ) {
return CS_SUCCEED ;
}
/* Call global message handler */
handled = handled | _call_message_handler ( SybCtG ( callback_name ) , srvmsg TSRMLS_CC ) ;
/* Call link specific message handler */
if ( sybase ) {
handled = handled | _call_message_handler ( sybase - > callback_name , srvmsg TSRMLS_CC ) ;
}
/* Spit out a warning if neither of them has handled this message */
if ( ! handled ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: Server message: %s (severity %d, procedure %s) " ,
srvmsg - > text , srvmsg - > severity , ( ( srvmsg - > proclen > 0 ) ? srvmsg - > proc : " N/A " ) ) ;
1999-04-22 02:48:28 +00:00
}
2002-11-05 08:29:57 +00:00
return CS_SUCCEED ;
1999-04-22 02:48:28 +00:00
}
2000-09-12 20:54:36 +00:00
PHP_INI_BEGIN ( )
2004-01-25 20:03:10 +00:00
STD_PHP_INI_BOOLEAN ( " sybct.allow_persistent " , " 1 " , PHP_INI_SYSTEM , OnUpdateLong , allow_persistent , zend_sybase_globals , sybase_globals )
STD_PHP_INI_ENTRY_EX ( " sybct.max_persistent " , " -1 " , PHP_INI_SYSTEM , OnUpdateLong , max_persistent , zend_sybase_globals , sybase_globals , display_link_numbers )
STD_PHP_INI_ENTRY_EX ( " sybct.max_links " , " -1 " , PHP_INI_SYSTEM , OnUpdateLong , max_links , zend_sybase_globals , sybase_globals , display_link_numbers )
STD_PHP_INI_ENTRY ( " sybct.min_server_severity " , " 10 " , PHP_INI_ALL , OnUpdateLong , min_server_severity , zend_sybase_globals , sybase_globals )
STD_PHP_INI_ENTRY ( " sybct.min_client_severity " , " 10 " , PHP_INI_ALL , OnUpdateLong , min_client_severity , zend_sybase_globals , sybase_globals )
STD_PHP_INI_ENTRY ( " sybct.login_timeout " , " -1 " , PHP_INI_ALL , OnUpdateLong , login_timeout , zend_sybase_globals , sybase_globals )
STD_PHP_INI_ENTRY ( " sybct.hostname " , NULL , PHP_INI_ALL , OnUpdateString , hostname , zend_sybase_globals , sybase_globals )
2004-09-09 19:17:50 +00:00
STD_PHP_INI_ENTRY_EX ( " sybct.deadlock_retry_count " , " 0 " , PHP_INI_ALL , OnUpdateLong , deadlock_retry_count , zend_sybase_globals , sybase_globals , display_link_numbers )
2000-09-12 20:54:36 +00:00
PHP_INI_END ( )
static void php_sybase_init_globals ( zend_sybase_globals * sybase_globals )
1999-04-22 02:48:28 +00:00
{
2004-01-25 20:03:10 +00:00
long opt ;
2002-11-12 22:59:11 +00:00
TSRMLS_FETCH ( ) ;
1999-04-22 02:48:28 +00:00
2001-08-13 19:58:07 +00:00
if ( cs_ctx_alloc ( CTLIB_VERSION , & sybase_globals - > context ) ! = CS_SUCCEED | | ct_init ( sybase_globals - > context , CTLIB_VERSION ) ! = CS_SUCCEED ) {
2000-09-12 20:54:36 +00:00
return ;
1999-04-22 02:48:28 +00:00
}
2000-09-12 20:54:36 +00:00
1999-04-22 02:48:28 +00:00
/* Initialize message handlers */
2000-09-12 20:54:36 +00:00
if ( ct_callback ( sybase_globals - > context , NULL , CS_SET , CS_SERVERMSG_CB , ( CS_VOID * ) _server_message_handler ) ! = CS_SUCCEED ) {
2002-11-12 13:13:12 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: Unable to set server message handler " ) ;
1999-04-22 02:48:28 +00:00
}
2000-09-12 20:54:36 +00:00
if ( ct_callback ( sybase_globals - > context , NULL , CS_SET , CS_CLIENTMSG_CB , ( CS_VOID * ) _client_message_handler ) ! = CS_SUCCEED ) {
2002-11-12 13:13:12 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: Unable to set client message handler " ) ;
1999-04-22 02:48:28 +00:00
}
2001-08-13 19:45:26 +00:00
1999-04-22 02:48:28 +00:00
/* Set datetime conversion format to "Nov 3 1998 8:06PM".
* This is the default format for the ct - lib that comes with
* Sybase ASE 11.5 .1 for Solaris , but the Linux libraries that
* come with 11.0 .3 .3 default to " 03/11/98 " which is singularly
* useless . This levels the playing field for all platforms .
*/
{
CS_INT dt_convfmt = CS_DATES_SHORT ;
2000-09-12 20:54:36 +00:00
if ( cs_dt_info ( sybase_globals - > context , CS_SET , NULL , CS_DT_CONVFMT , CS_UNUSED , & dt_convfmt , sizeof ( dt_convfmt ) , NULL ) ! = CS_SUCCEED ) {
2002-11-12 13:13:12 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: Unable to set datetime conversion format " ) ;
1999-04-22 02:48:28 +00:00
}
}
2004-01-25 20:03:10 +00:00
/* Set the timeout, which is per context and can't be set with
* ct_con_props ( ) , so set it globally from the config value if
* requested . The default is CS_NO_LIMIT .
*
* Note that despite some noise in the documentation about using
1999-04-22 02:48:28 +00:00
* signals to implement timeouts , they are actually implemented
* by using poll ( ) or select ( ) on Solaris and Linux .
*/
2004-01-25 20:03:10 +00:00
if ( cfg_get_long ( " sybct.timeout " , & opt ) = = SUCCESS ) {
CS_INT cs_timeout = opt ;
if ( ct_config ( sybase_globals - > context , CS_SET , CS_TIMEOUT , & cs_timeout , CS_UNUSED , NULL ) ! = CS_SUCCEED ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: Unable to update the timeout " ) ;
1999-04-22 02:48:28 +00:00
}
}
2004-01-25 20:03:10 +00:00
2000-09-12 20:54:36 +00:00
sybase_globals - > num_persistent = 0 ;
2002-11-05 08:29:57 +00:00
sybase_globals - > callback_name = NULL ;
2000-09-12 20:54:36 +00:00
}
1999-04-22 02:48:28 +00:00
2000-09-12 20:54:36 +00:00
static void php_sybase_destroy_globals ( zend_sybase_globals * sybase_globals )
{
2002-11-05 08:29:57 +00:00
ct_exit ( sybase_globals - > context , CS_UNUSED ) ;
cs_ctx_drop ( sybase_globals - > context ) ;
2000-09-12 20:54:36 +00:00
}
PHP_MINIT_FUNCTION ( sybase )
{
ZEND_INIT_MODULE_GLOBALS ( sybase , php_sybase_init_globals , php_sybase_destroy_globals ) ;
REGISTER_INI_ENTRIES ( ) ;
2000-10-25 17:44:02 +00:00
le_link = zend_register_list_destructors_ex ( _close_sybase_link , NULL , " sybase-ct link " , module_number ) ;
le_plink = zend_register_list_destructors_ex ( NULL , _close_sybase_plink , " sybase-ct link persistent " , module_number ) ;
le_result = zend_register_list_destructors_ex ( php_free_sybase_result , NULL , " sybase-ct result " , module_number ) ;
1999-04-22 02:48:28 +00:00
return SUCCESS ;
}
1999-09-04 13:03:09 +00:00
PHP_RINIT_FUNCTION ( sybase )
1999-04-22 02:48:28 +00:00
{
2000-09-12 20:54:36 +00:00
SybCtG ( default_link ) = - 1 ;
SybCtG ( num_links ) = SybCtG ( num_persistent ) ;
2004-04-16 16:27:19 +00:00
SybCtG ( appname ) = estrndup ( " PHP " PHP_VERSION , sizeof ( " PHP " PHP_VERSION ) ) ;
2004-07-19 07:19:50 +00:00
SybCtG ( server_message ) = STR_EMPTY_ALLOC ( ) ;
1999-04-22 02:48:28 +00:00
return SUCCESS ;
}
1999-09-04 13:03:09 +00:00
PHP_MSHUTDOWN_FUNCTION ( sybase )
1999-04-22 02:48:28 +00:00
{
2000-09-12 20:54:36 +00:00
UNREGISTER_INI_ENTRIES ( ) ;
#if 0
2001-08-13 19:58:07 +00:00
ct_exit ( context , CS_UNUSED ) ;
2000-09-12 20:54:36 +00:00
cs_ctx_drop ( context ) ;
# endif
1999-04-22 02:48:28 +00:00
return SUCCESS ;
}
1999-09-04 13:03:09 +00:00
PHP_RSHUTDOWN_FUNCTION ( sybase )
1999-04-22 02:48:28 +00:00
{
2000-09-12 20:54:36 +00:00
efree ( SybCtG ( appname ) ) ;
2004-07-10 07:46:17 +00:00
SybCtG ( appname ) = NULL ;
2002-11-05 08:29:57 +00:00
if ( SybCtG ( callback_name ) ) {
2002-12-07 19:49:31 +00:00
zval_ptr_dtor ( & SybCtG ( callback_name ) ) ;
2002-11-05 08:29:57 +00:00
SybCtG ( callback_name ) = NULL ;
}
2001-01-13 22:47:44 +00:00
STR_FREE ( SybCtG ( server_message ) ) ;
2004-07-10 07:46:17 +00:00
SybCtG ( server_message ) = NULL ;
1999-04-22 02:48:28 +00:00
return SUCCESS ;
}
2002-03-06 15:59:57 +00:00
static int php_sybase_do_connect_internal ( sybase_link * sybase , char * host , char * user , char * passwd , char * charset , char * appname )
1999-04-22 02:48:28 +00:00
{
2001-06-26 20:56:03 +00:00
CS_LOCALE * tmp_locale ;
2001-07-28 11:36:37 +00:00
TSRMLS_FETCH ( ) ;
2004-08-21 17:54:11 +00:00
long packetsize ;
2000-09-12 20:54:36 +00:00
1999-04-22 02:48:28 +00:00
/* set a CS_CONNECTION record */
2000-09-12 20:54:36 +00:00
if ( ct_con_alloc ( SybCtG ( context ) , & sybase - > connection ) ! = CS_SUCCEED ) {
2002-11-12 13:13:12 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: Unable to allocate connection record " ) ;
1999-04-22 02:48:28 +00:00
return 0 ;
}
2001-08-13 19:45:26 +00:00
1999-09-04 13:03:09 +00:00
/* Note - this saves a copy of sybase, not a pointer to it. */
if ( ct_con_props ( sybase - > connection , CS_SET , CS_USERDATA , & sybase , CS_SIZEOF ( sybase ) , NULL ) ! = CS_SUCCEED ) {
2002-11-12 13:13:12 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: Unable to set userdata " ) ;
1999-09-04 13:03:09 +00:00
ct_con_drop ( sybase - > connection ) ;
1999-04-22 02:48:28 +00:00
return 0 ;
}
if ( user ) {
1999-09-04 13:03:09 +00:00
ct_con_props ( sybase - > connection , CS_SET , CS_USERNAME , user , CS_NULLTERM , NULL ) ;
1999-04-22 02:48:28 +00:00
}
if ( passwd ) {
1999-09-04 13:03:09 +00:00
ct_con_props ( sybase - > connection , CS_SET , CS_PASSWORD , passwd , CS_NULLTERM , NULL ) ;
1999-04-22 02:48:28 +00:00
}
2002-03-06 15:59:57 +00:00
if ( appname ) {
ct_con_props ( sybase - > connection , CS_SET , CS_APPNAME , appname , CS_NULLTERM , NULL ) ;
2002-11-05 08:29:57 +00:00
} else {
2002-03-06 15:59:57 +00:00
ct_con_props ( sybase - > connection , CS_SET , CS_APPNAME , SybCtG ( appname ) , CS_NULLTERM , NULL ) ;
}
1999-04-22 02:48:28 +00:00
2000-09-12 20:54:36 +00:00
if ( SybCtG ( hostname ) ) {
ct_con_props ( sybase - > connection , CS_SET , CS_HOSTNAME , SybCtG ( hostname ) , CS_NULLTERM , NULL ) ;
1999-04-22 02:48:28 +00:00
}
2001-06-26 20:56:03 +00:00
if ( charset ) {
if ( cs_loc_alloc ( SybCtG ( context ) , & tmp_locale ) ! = CS_SUCCEED ) {
2002-11-12 13:13:12 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: Unable to allocate locale information. " ) ;
2001-06-26 20:56:03 +00:00
} else {
if ( cs_locale ( SybCtG ( context ) , CS_SET , tmp_locale , CS_LC_ALL , NULL , CS_NULLTERM , NULL ) ! = CS_SUCCEED ) {
2002-11-12 13:13:12 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: Unable to load default locale data. " ) ;
2001-06-26 20:56:03 +00:00
} else {
if ( cs_locale ( SybCtG ( context ) , CS_SET , tmp_locale , CS_SYB_CHARSET , charset , CS_NULLTERM , NULL ) ! = CS_SUCCEED ) {
2002-11-12 13:13:12 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: Unable to update character set. " ) ;
2001-06-26 20:56:03 +00:00
} else {
if ( ct_con_props ( sybase - > connection , CS_SET , CS_LOC_PROP , tmp_locale , CS_UNUSED , NULL ) ! = CS_SUCCEED ) {
2002-11-12 13:13:12 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: Unable to update connection properties. " ) ;
2001-06-26 20:56:03 +00:00
}
}
}
}
}
2004-08-21 17:54:11 +00:00
if ( cfg_get_long ( " sybct.packet_size " , & packetsize ) = = SUCCESS ) {
if ( ct_con_props ( sybase - > connection , CS_SET , CS_PACKETSIZE , ( CS_VOID * ) & packetsize , CS_UNUSED , NULL ) ! = CS_SUCCEED ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: Unable to update connection packetsize. " ) ;
}
}
2001-06-26 20:56:03 +00:00
2004-01-25 20:03:10 +00:00
/* Set the login timeout. Actually, the login timeout is per context
* and not per connection , but we will update the context here to
* allow for code such as the following :
*
* ini_set ( ' sybct . login_timeout ' , $ timeout ) ;
* sybase_connect ( . . . )
*
* Note that preceding calls to sybase_connect ( ) will now use the
* updated value and not the default one !
*
* The default value for CS_LOGIN_TIMEOUT is 60 ( 1 minute ) .
*/
if ( SybCtG ( login_timeout ) ! = - 1 ) {
CS_INT cs_login_timeout = SybCtG ( login_timeout ) ;
if ( ct_config ( SybCtG ( context ) , CS_SET , CS_LOGIN_TIMEOUT , & cs_login_timeout , CS_UNUSED , NULL ) ! = CS_SUCCEED ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: Unable to update the login timeout " ) ;
}
}
1999-09-04 13:03:09 +00:00
sybase - > valid = 1 ;
sybase - > dead = 0 ;
2002-11-05 08:29:57 +00:00
sybase - > active_result_index = 0 ;
2004-01-25 20:03:10 +00:00
sybase - > callback_name = NULL ;
1999-04-22 02:48:28 +00:00
/* create the link */
1999-09-04 13:03:09 +00:00
if ( ct_connect ( sybase - > connection , host , CS_NULLTERM ) ! = CS_SUCCEED ) {
2002-11-12 13:13:12 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: Unable to connect " ) ;
1999-09-04 13:03:09 +00:00
ct_con_drop ( sybase - > connection ) ;
1999-04-22 02:48:28 +00:00
return 0 ;
}
2000-09-12 20:54:36 +00:00
if ( ct_cmd_alloc ( sybase - > connection , & sybase - > cmd ) ! = CS_SUCCEED ) {
2002-11-12 13:13:12 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: Unable to allocate command record " ) ;
2001-08-13 19:58:07 +00:00
ct_close ( sybase - > connection , CS_UNUSED ) ;
1999-09-04 13:03:09 +00:00
ct_con_drop ( sybase - > connection ) ;
1999-04-22 02:48:28 +00:00
return 0 ;
}
return 1 ;
}
2000-09-12 20:54:36 +00:00
static void php_sybase_do_connect ( INTERNAL_FUNCTION_PARAMETERS , int persistent )
1999-04-22 02:48:28 +00:00
{
2002-03-06 15:59:57 +00:00
char * user , * passwd , * host , * charset , * appname ;
1999-04-22 02:48:28 +00:00
char * hashed_details ;
int hashed_details_length ;
1999-09-04 13:03:09 +00:00
sybase_link * sybase_ptr ;
1999-04-22 02:48:28 +00:00
2000-06-05 19:47:54 +00:00
switch ( ZEND_NUM_ARGS ( ) ) {
1999-04-22 02:48:28 +00:00
case 0 : /* defaults */
2002-03-06 15:59:57 +00:00
host = user = passwd = charset = appname = NULL ;
hashed_details_length = 6 + 5 ;
1999-04-22 02:48:28 +00:00
hashed_details = ( char * ) emalloc ( hashed_details_length + 1 ) ;
2002-03-06 15:59:57 +00:00
strcpy ( hashed_details , " sybase_____ " ) ;
1999-04-22 02:48:28 +00:00
break ;
case 1 : {
2003-01-15 03:01:17 +00:00
zval * * yyhost ;
2001-08-13 19:45:26 +00:00
2003-01-15 03:01:17 +00:00
if ( zend_get_parameters_ex ( 1 , & yyhost ) = = FAILURE ) {
1999-04-22 02:48:28 +00:00
RETURN_FALSE ;
}
2003-01-15 03:01:17 +00:00
convert_to_string_ex ( yyhost ) ;
host = Z_STRVAL_PP ( yyhost ) ;
2002-03-06 15:59:57 +00:00
user = passwd = charset = appname = NULL ;
2003-01-15 03:01:17 +00:00
hashed_details_length = Z_STRLEN_PP ( yyhost ) + 6 + 5 ;
1999-04-22 02:48:28 +00:00
hashed_details = ( char * ) emalloc ( hashed_details_length + 1 ) ;
2003-01-15 03:01:17 +00:00
sprintf ( hashed_details , " sybase_%s____ " , Z_STRVAL_PP ( yyhost ) ) ;
1999-04-22 02:48:28 +00:00
}
break ;
case 2 : {
2003-01-15 03:01:17 +00:00
zval * * yyhost , * * yyuser ;
2001-08-13 19:45:26 +00:00
2003-01-15 03:01:17 +00:00
if ( zend_get_parameters_ex ( 2 , & yyhost , & yyuser ) = = FAILURE ) {
1999-04-22 02:48:28 +00:00
RETURN_FALSE ;
}
2003-01-15 03:01:17 +00:00
convert_to_string_ex ( yyhost ) ;
convert_to_string_ex ( yyuser ) ;
host = Z_STRVAL_PP ( yyhost ) ;
user = Z_STRVAL_PP ( yyuser ) ;
2002-03-06 15:59:57 +00:00
passwd = charset = appname = NULL ;
2003-01-15 03:01:17 +00:00
hashed_details_length = Z_STRLEN_PP ( yyhost ) + Z_STRLEN_PP ( yyuser ) + 6 + 5 ;
1999-04-22 02:48:28 +00:00
hashed_details = ( char * ) emalloc ( hashed_details_length + 1 ) ;
2003-01-15 03:01:17 +00:00
sprintf ( hashed_details , " sybase_%s_%s___ " , Z_STRVAL_PP ( yyhost ) , Z_STRVAL_PP ( yyuser ) ) ;
1999-04-22 02:48:28 +00:00
}
break ;
case 3 : {
2003-01-15 03:01:17 +00:00
zval * * yyhost , * * yyuser , * * yypasswd ;
2001-08-13 19:45:26 +00:00
2003-01-15 03:01:17 +00:00
if ( zend_get_parameters_ex ( 3 , & yyhost , & yyuser , & yypasswd ) = = FAILURE ) {
1999-04-22 02:48:28 +00:00
RETURN_FALSE ;
}
2003-01-15 03:01:17 +00:00
convert_to_string_ex ( yyhost ) ;
convert_to_string_ex ( yyuser ) ;
convert_to_string_ex ( yypasswd ) ;
host = Z_STRVAL_PP ( yyhost ) ;
user = Z_STRVAL_PP ( yyuser ) ;
passwd = Z_STRVAL_PP ( yypasswd ) ;
2002-03-06 15:59:57 +00:00
charset = appname = NULL ;
2003-01-15 03:01:17 +00:00
hashed_details_length = Z_STRLEN_PP ( yyhost ) + Z_STRLEN_PP ( yyuser ) + Z_STRLEN_PP ( yypasswd ) + 6 + 5 ;
2001-06-26 20:56:03 +00:00
hashed_details = ( char * ) emalloc ( hashed_details_length + 1 ) ;
2003-01-15 03:01:17 +00:00
sprintf ( hashed_details , " sybase_%s_%s_%s__ " , Z_STRVAL_PP ( yyhost ) , Z_STRVAL_PP ( yyuser ) , Z_STRVAL_PP ( yypasswd ) ) ;
2001-06-26 20:56:03 +00:00
}
break ;
case 4 : {
2003-01-15 03:01:17 +00:00
zval * * yyhost , * * yyuser , * * yypasswd , * * yycharset ;
2001-06-26 20:56:03 +00:00
2003-01-15 03:01:17 +00:00
if ( zend_get_parameters_ex ( 4 , & yyhost , & yyuser , & yypasswd , & yycharset ) = = FAILURE ) {
2001-06-26 20:56:03 +00:00
RETURN_FALSE ;
}
2003-01-15 03:01:17 +00:00
convert_to_string_ex ( yyhost ) ;
convert_to_string_ex ( yyuser ) ;
convert_to_string_ex ( yypasswd ) ;
convert_to_string_ex ( yycharset ) ;
host = Z_STRVAL_PP ( yyhost ) ;
user = Z_STRVAL_PP ( yyuser ) ;
passwd = Z_STRVAL_PP ( yypasswd ) ;
charset = Z_STRVAL_PP ( yycharset ) ;
2002-03-06 15:59:57 +00:00
appname = NULL ;
2003-01-15 03:01:17 +00:00
hashed_details_length = Z_STRLEN_PP ( yyhost ) + Z_STRLEN_PP ( yyuser ) + Z_STRLEN_PP ( yypasswd ) + Z_STRLEN_PP ( yycharset ) + 6 + 5 ;
2002-03-06 15:59:57 +00:00
hashed_details = ( char * ) emalloc ( hashed_details_length + 1 ) ;
2003-01-15 03:01:17 +00:00
sprintf ( hashed_details , " sybase_%s_%s_%s_%s_ " , Z_STRVAL_PP ( yyhost ) , Z_STRVAL_PP ( yyuser ) , Z_STRVAL_PP ( yypasswd ) , Z_STRVAL_PP ( yycharset ) ) ;
2002-03-06 15:59:57 +00:00
}
break ;
case 5 : {
2003-01-15 03:01:17 +00:00
zval * * yyhost , * * yyuser , * * yypasswd , * * yycharset , * * yyappname ;
2002-03-06 15:59:57 +00:00
2003-01-15 03:01:17 +00:00
if ( zend_get_parameters_ex ( 5 , & yyhost , & yyuser , & yypasswd , & yycharset , & yyappname ) = = FAILURE ) {
2002-03-06 15:59:57 +00:00
RETURN_FALSE ;
}
2003-01-15 03:01:17 +00:00
convert_to_string_ex ( yyhost ) ;
convert_to_string_ex ( yyuser ) ;
convert_to_string_ex ( yypasswd ) ;
convert_to_string_ex ( yycharset ) ;
convert_to_string_ex ( yyappname ) ;
host = Z_STRVAL_PP ( yyhost ) ;
user = Z_STRVAL_PP ( yyuser ) ;
passwd = Z_STRVAL_PP ( yypasswd ) ;
charset = Z_STRVAL_PP ( yycharset ) ;
appname = Z_STRVAL_PP ( yyappname ) ;
hashed_details_length = Z_STRLEN_PP ( yyhost ) + Z_STRLEN_PP ( yyuser ) + Z_STRLEN_PP ( yypasswd ) + Z_STRLEN_PP ( yycharset ) + Z_STRLEN_PP ( yyappname ) + 6 + 5 ;
1999-04-22 02:48:28 +00:00
hashed_details = ( char * ) emalloc ( hashed_details_length + 1 ) ;
2003-01-15 03:01:17 +00:00
sprintf ( hashed_details , " sybase_%s_%s_%s_%s_%s " , Z_STRVAL_PP ( yyhost ) , Z_STRVAL_PP ( yyuser ) , Z_STRVAL_PP ( yypasswd ) , Z_STRVAL_PP ( yycharset ) , Z_STRVAL_PP ( yyappname ) ) ;
1999-04-22 02:48:28 +00:00
}
break ;
default :
WRONG_PARAM_COUNT ;
break ;
}
2000-09-12 20:54:36 +00:00
if ( ! SybCtG ( allow_persistent ) ) {
1999-04-22 02:48:28 +00:00
persistent = 0 ;
}
if ( persistent ) {
list_entry * le ;
/* try to find if we already have this link in our persistent list */
2000-02-05 15:16:12 +00:00
if ( zend_hash_find ( & EG ( persistent_list ) , hashed_details , hashed_details_length + 1 , ( void * * ) & le ) = = FAILURE ) { /* we don't */
1999-04-22 02:48:28 +00:00
list_entry new_le ;
2000-09-12 20:54:36 +00:00
if ( SybCtG ( max_links ) ! = - 1 & & SybCtG ( num_links ) > = SybCtG ( max_links ) ) {
2004-01-18 16:01:02 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: Too many open links (%ld) " , SybCtG ( num_links ) ) ;
1999-04-22 02:48:28 +00:00
efree ( hashed_details ) ;
RETURN_FALSE ;
}
2000-09-12 20:54:36 +00:00
if ( SybCtG ( max_persistent ) ! = - 1 & & SybCtG ( num_persistent ) > = SybCtG ( max_persistent ) ) {
2004-01-18 16:01:02 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: Too many open persistent links (%ld) " , SybCtG ( num_persistent ) ) ;
1999-04-22 02:48:28 +00:00
efree ( hashed_details ) ;
RETURN_FALSE ;
}
1999-09-04 13:03:09 +00:00
sybase_ptr = ( sybase_link * ) malloc ( sizeof ( sybase_link ) ) ;
2002-03-06 15:59:57 +00:00
if ( ! php_sybase_do_connect_internal ( sybase_ptr , host , user , passwd , charset , appname ) ) {
1999-09-04 13:03:09 +00:00
free ( sybase_ptr ) ;
1999-04-22 02:48:28 +00:00
efree ( hashed_details ) ;
RETURN_FALSE ;
}
/* hash it up */
2001-09-25 21:58:48 +00:00
Z_TYPE ( new_le ) = le_plink ;
1999-09-04 13:03:09 +00:00
new_le . ptr = sybase_ptr ;
2001-08-13 19:58:07 +00:00
if ( zend_hash_update ( & EG ( persistent_list ) , hashed_details , hashed_details_length + 1 , ( void * ) & new_le , sizeof ( list_entry ) , NULL ) = = FAILURE ) {
1999-09-04 13:03:09 +00:00
ct_close ( sybase_ptr - > connection , CS_UNUSED ) ;
ct_con_drop ( sybase_ptr - > connection ) ;
free ( sybase_ptr ) ;
1999-04-22 02:48:28 +00:00
efree ( hashed_details ) ;
RETURN_FALSE ;
}
2000-09-12 20:54:36 +00:00
SybCtG ( num_persistent ) + + ;
SybCtG ( num_links ) + + ;
1999-04-22 02:48:28 +00:00
} else { /* we do */
CS_INT con_status ;
2001-09-25 21:58:48 +00:00
if ( Z_TYPE_P ( le ) ! = le_plink ) {
1999-04-22 02:48:28 +00:00
efree ( hashed_details ) ;
RETURN_FALSE ;
}
2001-08-13 19:45:26 +00:00
1999-09-04 13:03:09 +00:00
sybase_ptr = ( sybase_link * ) le - > ptr ;
1999-04-22 02:48:28 +00:00
/* If the link has died, close it and overwrite it with a new one. */
1999-09-04 13:03:09 +00:00
if ( ct_con_props ( sybase_ptr - > connection , CS_GET , CS_CON_STATUS ,
1999-04-22 02:48:28 +00:00
& con_status , CS_UNUSED , NULL ) ! = CS_SUCCEED ) {
2002-11-12 13:13:12 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: Unable to get connection status " ) ;
1999-04-22 02:48:28 +00:00
efree ( hashed_details ) ;
RETURN_FALSE ;
}
1999-09-04 13:03:09 +00:00
if ( ! ( con_status & CS_CONSTAT_CONNECTED ) | | ( con_status & CS_CONSTAT_DEAD ) | | sybase_ptr - > dead ) {
sybase_link sybase ;
1999-04-22 02:48:28 +00:00
if ( con_status & CS_CONSTAT_CONNECTED ) {
1999-09-04 13:03:09 +00:00
ct_close ( sybase_ptr - > connection , CS_FORCE_CLOSE ) ;
1999-04-22 02:48:28 +00:00
}
/* Create a new connection, then replace the old
* connection . If we fail to create a new connection ,
* put the old one back so there will be a connection ,
* even if it is a non - functional one . This is because
* code may still be holding an id for this connection
* so we can ' t free the CS_CONNECTION .
* ( This is actually totally hokey , it would be better
* to just ct_con_drop ( ) the connection and set
1999-09-04 13:03:09 +00:00
* sybase_ptr - > connection to NULL , then test it for
1999-04-22 02:48:28 +00:00
* NULL before trying to use it elsewhere . . . )
*/
2000-09-12 20:54:36 +00:00
memcpy ( & sybase , sybase_ptr , sizeof ( sybase_link ) ) ;
2002-03-06 15:59:57 +00:00
if ( ! php_sybase_do_connect_internal ( sybase_ptr , host , user , passwd , charset , appname ) ) {
2000-09-12 20:54:36 +00:00
memcpy ( sybase_ptr , & sybase , sizeof ( sybase_link ) ) ;
1999-04-22 02:48:28 +00:00
efree ( hashed_details ) ;
RETURN_FALSE ;
}
1999-09-04 13:03:09 +00:00
ct_con_drop ( sybase . connection ) ; /* drop old connection */
1999-04-22 02:48:28 +00:00
}
}
2000-09-12 20:54:36 +00:00
ZEND_REGISTER_RESOURCE ( return_value , sybase_ptr , le_plink ) ;
1999-04-22 02:48:28 +00:00
} else { /* non persistent */
2000-09-12 20:54:36 +00:00
list_entry * index_ptr , new_index_ptr ;
2001-08-13 19:45:26 +00:00
1999-04-22 02:48:28 +00:00
/* first we check the hash for the hashed_details key. if it exists,
1999-09-04 13:03:09 +00:00
* it should point us to the right offset where the actual sybase link sits .
* if it doesn ' t , open a new sybase link , add it to the resource list ,
1999-04-22 02:48:28 +00:00
* and add a pointer to it with hashed_details as the key .
*/
2001-08-13 19:58:07 +00:00
if ( zend_hash_find ( & EG ( regular_list ) , hashed_details , hashed_details_length + 1 , ( void * * ) & index_ptr ) = = SUCCESS ) {
2000-09-12 20:54:36 +00:00
int type , link ;
1999-04-22 02:48:28 +00:00
void * ptr ;
2001-09-25 21:58:48 +00:00
if ( Z_TYPE_P ( index_ptr ) ! = le_index_ptr ) {
1999-04-22 02:48:28 +00:00
efree ( hashed_details ) ;
RETURN_FALSE ;
}
link = ( int ) index_ptr - > ptr ;
2000-09-12 20:54:36 +00:00
ptr = zend_list_find ( link , & type ) ; /* check if the link is still there */
if ( ptr & & ( type = = le_link | | type = = le_plink ) ) {
2001-07-23 16:10:10 +00:00
zend_list_addref ( link ) ;
2001-08-14 01:07:42 +00:00
Z_LVAL_P ( return_value ) = SybCtG ( default_link ) = link ;
2001-09-25 21:58:48 +00:00
Z_TYPE_P ( return_value ) = IS_RESOURCE ;
1999-04-22 02:48:28 +00:00
efree ( hashed_details ) ;
return ;
} else {
2000-09-12 20:54:36 +00:00
zend_hash_del ( & EG ( regular_list ) , hashed_details , hashed_details_length + 1 ) ;
1999-04-22 02:48:28 +00:00
}
}
2000-09-12 20:54:36 +00:00
if ( SybCtG ( max_links ) ! = - 1 & & SybCtG ( num_links ) > = SybCtG ( max_links ) ) {
2004-01-18 16:01:02 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: Too many open links (%ld) " , SybCtG ( num_links ) ) ;
1999-04-22 02:48:28 +00:00
efree ( hashed_details ) ;
RETURN_FALSE ;
}
1999-09-04 13:03:09 +00:00
sybase_ptr = ( sybase_link * ) emalloc ( sizeof ( sybase_link ) ) ;
2002-03-06 15:59:57 +00:00
if ( ! php_sybase_do_connect_internal ( sybase_ptr , host , user , passwd , charset , appname ) ) {
1999-09-04 13:03:09 +00:00
efree ( sybase_ptr ) ;
1999-04-22 02:48:28 +00:00
efree ( hashed_details ) ;
RETURN_FALSE ;
}
/* add it to the list */
2000-09-12 20:54:36 +00:00
ZEND_REGISTER_RESOURCE ( return_value , sybase_ptr , le_link ) ;
2001-08-13 19:45:26 +00:00
1999-04-22 02:48:28 +00:00
/* add it to the hash */
2001-08-14 01:07:42 +00:00
new_index_ptr . ptr = ( void * ) Z_LVAL_P ( return_value ) ;
2001-09-25 21:58:48 +00:00
Z_TYPE ( new_index_ptr ) = le_index_ptr ;
2001-08-13 19:58:07 +00:00
if ( zend_hash_update ( & EG ( regular_list ) , hashed_details , hashed_details_length + 1 , ( void * ) & new_index_ptr , sizeof ( list_entry ) , NULL ) = = FAILURE ) {
1999-09-04 13:03:09 +00:00
ct_close ( sybase_ptr - > connection , CS_UNUSED ) ;
ct_con_drop ( sybase_ptr - > connection ) ;
efree ( sybase_ptr ) ;
1999-04-22 02:48:28 +00:00
efree ( hashed_details ) ;
RETURN_FALSE ;
}
2000-09-12 20:54:36 +00:00
SybCtG ( num_links ) + + ;
1999-04-22 02:48:28 +00:00
}
efree ( hashed_details ) ;
2001-08-14 01:07:42 +00:00
SybCtG ( default_link ) = Z_LVAL_P ( return_value ) ;
2001-07-23 16:10:10 +00:00
zend_list_addref ( SybCtG ( default_link ) ) ;
1999-04-22 02:48:28 +00:00
}
1999-09-04 13:03:09 +00:00
static int php_sybase_get_default_link ( INTERNAL_FUNCTION_PARAMETERS )
1999-04-22 02:48:28 +00:00
{
2000-09-12 20:54:36 +00:00
if ( SybCtG ( default_link ) = = - 1 ) { /* no link opened yet, implicitly open one */
1999-07-22 23:54:54 +00:00
ht = 0 ;
1999-09-04 13:03:09 +00:00
php_sybase_do_connect ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 0 ) ;
1999-04-22 02:48:28 +00:00
}
2000-09-12 20:54:36 +00:00
return SybCtG ( default_link ) ;
1999-04-22 02:48:28 +00:00
}
2002-03-06 15:59:57 +00:00
/* {{{ proto int sybase_connect([string host [, string user [, string password [, string charset [, string appname]]]]])
2001-01-26 21:41:38 +00:00
Open Sybase server connection */
1999-09-04 13:03:09 +00:00
PHP_FUNCTION ( sybase_connect )
1999-04-22 02:48:28 +00:00
{
2000-09-12 20:54:36 +00:00
php_sybase_do_connect ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 0 ) ;
1999-04-22 02:48:28 +00:00
}
2000-09-26 07:38:47 +00:00
/* }}} */
2002-03-06 15:59:57 +00:00
/* {{{ proto int sybase_pconnect([string host [, string user [, string password [, string charset [, string appname]]]]])
2001-01-26 21:41:38 +00:00
Open persistent Sybase connection */
1999-09-04 13:03:09 +00:00
PHP_FUNCTION ( sybase_pconnect )
1999-04-22 02:48:28 +00:00
{
2000-09-12 20:54:36 +00:00
php_sybase_do_connect ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 1 ) ;
1999-04-22 02:48:28 +00:00
}
2000-09-26 07:38:47 +00:00
/* }}} */
1999-04-22 02:48:28 +00:00
2000-09-26 07:38:47 +00:00
/* {{{ proto bool sybase_close([int link_id])
2001-01-26 21:41:38 +00:00
Close Sybase connection */
1999-09-04 13:03:09 +00:00
PHP_FUNCTION ( sybase_close )
1999-04-22 02:48:28 +00:00
{
2003-01-15 03:01:17 +00:00
zval * * sybase_link_index = 0 ;
1999-09-04 13:03:09 +00:00
int id ;
sybase_link * sybase_ptr ;
2001-08-13 19:45:26 +00:00
2000-06-05 19:47:54 +00:00
switch ( ZEND_NUM_ARGS ( ) ) {
1999-04-22 02:48:28 +00:00
case 0 :
2000-09-12 20:54:36 +00:00
id = SybCtG ( default_link ) ;
1999-04-22 02:48:28 +00:00
break ;
case 1 :
2003-01-15 03:01:17 +00:00
if ( zend_get_parameters_ex ( 1 , & sybase_link_index ) = = FAILURE ) {
1999-04-22 02:48:28 +00:00
RETURN_FALSE ;
}
1999-09-04 13:03:09 +00:00
id = - 1 ;
1999-04-22 02:48:28 +00:00
break ;
default :
WRONG_PARAM_COUNT ;
break ;
}
2001-08-13 19:45:26 +00:00
2003-01-15 13:55:34 +00:00
ZEND_FETCH_RESOURCE2 ( sybase_ptr , sybase_link * , sybase_link_index , id , " Sybase-Link " , le_link , le_plink ) ;
2001-08-13 19:45:26 +00:00
2003-01-15 03:01:17 +00:00
if ( id = = - 1 ) { /* explicit resource number */
2003-01-15 13:55:34 +00:00
zend_list_delete ( Z_RESVAL_PP ( sybase_link_index ) ) ;
2000-11-03 02:46:49 +00:00
}
2003-01-15 03:01:17 +00:00
if ( id ! = - 1 | | ( sybase_link_index & & Z_RESVAL_PP ( sybase_link_index ) = = SybCtG ( default_link ) ) ) {
2000-11-03 02:46:49 +00:00
zend_list_delete ( SybCtG ( default_link ) ) ;
SybCtG ( default_link ) = - 1 ;
1999-10-12 15:00:10 +00:00
}
1999-09-04 13:03:09 +00:00
1999-04-22 02:48:28 +00:00
RETURN_TRUE ;
}
2000-09-26 07:38:47 +00:00
/* }}} */
2001-08-13 19:45:26 +00:00
1999-04-22 02:48:28 +00:00
2000-09-12 20:54:36 +00:00
static int exec_cmd ( sybase_link * sybase_ptr , char * cmdbuf )
1999-04-22 02:48:28 +00:00
{
CS_RETCODE retcode ;
CS_INT restype ;
int failure = 0 ;
/* Fail if we already marked this connection dead. */
1999-09-04 13:03:09 +00:00
if ( sybase_ptr - > dead ) {
1999-04-22 02:48:28 +00:00
return FAILURE ;
}
/*
* * Get a command handle , store the command string in it , and
* * send it to the server .
*/
2001-08-13 19:45:26 +00:00
1999-09-04 13:03:09 +00:00
if ( ct_command ( sybase_ptr - > cmd , CS_LANG_CMD , cmdbuf , CS_NULLTERM , CS_UNUSED ) ! = CS_SUCCEED ) {
sybase_ptr - > dead = 1 ;
1999-04-22 02:48:28 +00:00
return FAILURE ;
}
1999-09-04 13:03:09 +00:00
if ( ct_send ( sybase_ptr - > cmd ) ! = CS_SUCCEED ) {
sybase_ptr - > dead = 1 ;
1999-04-22 02:48:28 +00:00
return FAILURE ;
}
2001-08-13 19:45:26 +00:00
1999-09-04 13:03:09 +00:00
while ( ( retcode = ct_results ( sybase_ptr - > cmd , & restype ) ) = = CS_SUCCEED ) {
1999-04-22 02:48:28 +00:00
switch ( ( int ) restype ) {
case CS_CMD_SUCCEED :
case CS_CMD_DONE :
break ;
2001-08-13 19:45:26 +00:00
1999-04-22 02:48:28 +00:00
case CS_CMD_FAIL :
failure = 1 ;
break ;
2001-08-13 19:45:26 +00:00
1999-04-22 02:48:28 +00:00
case CS_STATUS_RESULT :
1999-09-04 13:03:09 +00:00
ct_cancel ( NULL , sybase_ptr - > cmd , CS_CANCEL_CURRENT ) ;
1999-04-22 02:48:28 +00:00
break ;
2001-08-13 19:45:26 +00:00
1999-04-22 02:48:28 +00:00
default :
failure = 1 ;
break ;
}
if ( failure ) {
1999-09-04 13:03:09 +00:00
ct_cancel ( NULL , sybase_ptr - > cmd , CS_CANCEL_ALL ) ;
1999-04-22 02:48:28 +00:00
return FAILURE ;
}
}
switch ( retcode ) {
case CS_END_RESULTS :
return SUCCESS ;
break ;
case CS_FAIL :
/* Hopefully this either cleans up the connection, or the
* connection ends up marked dead so it will be reopened
* if it is persistent . We may want to do
* ct_close ( CS_FORCE_CLOSE ) if ct_cancel ( ) fails ; see the
* doc for ct_results ( ) = = CS_FAIL .
*/
1999-09-04 13:03:09 +00:00
ct_cancel ( NULL , sybase_ptr - > cmd , CS_CANCEL_ALL ) ;
1999-04-22 02:48:28 +00:00
/* Don't take chances with the vagaries of ct-lib. Mark it
* dead ourselves .
*/
1999-09-04 13:03:09 +00:00
sybase_ptr - > dead = 1 ;
1999-04-22 02:48:28 +00:00
return FAILURE ;
default :
return FAILURE ;
}
}
2000-09-26 07:38:47 +00:00
/* {{{ proto bool sybase_select_db(string database [, int link_id])
2001-01-26 21:41:38 +00:00
Select Sybase database */
1999-09-04 13:03:09 +00:00
PHP_FUNCTION ( sybase_select_db )
1999-04-22 02:48:28 +00:00
{
2003-01-15 03:01:17 +00:00
zval * * db , * * sybase_link_index ;
1999-09-04 13:03:09 +00:00
int id ;
1999-04-22 02:48:28 +00:00
char * cmdbuf ;
1999-09-04 13:03:09 +00:00
sybase_link * sybase_ptr ;
2001-08-13 19:45:26 +00:00
2000-06-05 19:47:54 +00:00
switch ( ZEND_NUM_ARGS ( ) ) {
1999-04-22 02:48:28 +00:00
case 1 :
2003-01-15 03:01:17 +00:00
if ( zend_get_parameters_ex ( 1 , & db ) = = FAILURE ) {
1999-04-22 02:48:28 +00:00
RETURN_FALSE ;
}
1999-09-04 13:03:09 +00:00
id = php_sybase_get_default_link ( INTERNAL_FUNCTION_PARAM_PASSTHRU ) ;
CHECK_LINK ( id ) ;
1999-04-22 02:48:28 +00:00
break ;
case 2 :
2003-01-15 03:01:17 +00:00
if ( zend_get_parameters_ex ( 2 , & db , & sybase_link_index ) = = FAILURE ) {
1999-04-22 02:48:28 +00:00
RETURN_FALSE ;
}
1999-09-04 13:03:09 +00:00
id = - 1 ;
1999-04-22 02:48:28 +00:00
break ;
default :
WRONG_PARAM_COUNT ;
break ;
}
2001-08-13 19:45:26 +00:00
2003-01-15 03:01:17 +00:00
ZEND_FETCH_RESOURCE2 ( sybase_ptr , sybase_link * , sybase_link_index , id , " Sybase-Link " , le_link , le_plink ) ;
2001-08-13 19:45:26 +00:00
2003-01-15 03:01:17 +00:00
convert_to_string_ex ( db ) ;
cmdbuf = ( char * ) emalloc ( sizeof ( " use " ) + Z_STRLEN_PP ( db ) + 1 ) ;
sprintf ( cmdbuf , " use %s " , Z_STRVAL_PP ( db ) ) ; /* SAFE */
1999-04-22 02:48:28 +00:00
2000-09-12 20:54:36 +00:00
if ( exec_cmd ( sybase_ptr , cmdbuf ) = = FAILURE ) {
1999-04-22 02:48:28 +00:00
efree ( cmdbuf ) ;
RETURN_FALSE ;
} else {
efree ( cmdbuf ) ;
RETURN_TRUE ;
}
}
2000-09-26 07:38:47 +00:00
/* }}} */
2004-01-24 02:17:42 +00:00
static int php_sybase_finish_results ( sybase_result * result )
2002-11-05 08:29:57 +00:00
{
2004-01-24 02:17:42 +00:00
int i , fail ;
2002-11-05 08:29:57 +00:00
CS_RETCODE retcode ;
CS_INT restype ;
2002-11-12 22:59:11 +00:00
TSRMLS_FETCH ( ) ;
2002-11-05 08:29:57 +00:00
efree ( result - > datafmt ) ;
efree ( result - > lengths ) ;
efree ( result - > indicators ) ;
efree ( result - > numerics ) ;
efree ( result - > types ) ;
for ( i = 0 ; i < result - > num_fields ; i + + ) {
efree ( result - > tmp_buffer [ i ] ) ;
}
efree ( result - > tmp_buffer ) ;
2002-11-12 13:13:12 +00:00
/* Indicate we have read all rows */
result - > sybase_ptr - > active_result_index = 0 ;
2002-11-05 08:29:57 +00:00
/* The only restype we should get now is CS_CMD_DONE, possibly
* followed by a CS_STATUS_RESULT / CS_CMD_SUCCEED / CS_CMD_DONE
* sequence if the command was a stored procedure call . But we
* still need to read and discard unexpected results . We might
* want to return a failure in this case because the application
* won ' t be getting all the results it asked for .
*/
2004-01-24 02:17:42 +00:00
fail = 0 ;
2002-11-05 08:29:57 +00:00
while ( ( retcode = ct_results ( result - > sybase_ptr - > cmd , & restype ) ) = = CS_SUCCEED ) {
switch ( ( int ) restype ) {
case CS_CMD_SUCCEED :
case CS_CMD_DONE :
break ;
case CS_CMD_FAIL :
2004-01-24 02:17:42 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: Command failed, cancelling rest " ) ;
ct_cancel ( NULL , result - > sybase_ptr - > cmd , CS_CANCEL_ALL ) ;
fail = 1 ;
2002-11-05 08:29:57 +00:00
break ;
case CS_COMPUTE_RESULT :
case CS_CURSOR_RESULT :
case CS_PARAM_RESULT :
case CS_ROW_RESULT :
/* Unexpected results, cancel them. */
2002-11-12 13:13:12 +00:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Sybase: Unexpected results, cancelling current " ) ;
2002-11-05 08:29:57 +00:00
ct_cancel ( NULL , result - > sybase_ptr - > cmd , CS_CANCEL_CURRENT ) ;
break ;
2004-07-29 19:32:46 +00:00
case CS_STATUS_RESULT :
/* Status result from a stored procedure, cancel it but do not tell user */
ct_cancel ( NULL , result - > sybase_ptr - > cmd , CS_CANCEL_CURRENT ) ;
break ;
2002-11-05 08:29:57 +00:00
default :
2002-11-12 13:13:12 +00:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Sybase: Unexpected results, cancelling all " ) ;
2002-11-05 08:29:57 +00:00
ct_cancel ( NULL , result - > sybase_ptr - > cmd , CS_CANCEL_ALL ) ;
break ;
}
2004-01-24 02:17:42 +00:00
if ( fail ) {
break ;
}
2002-11-05 08:29:57 +00:00
}
switch ( retcode ) {
case CS_END_RESULTS :
/* Normal. */
break ;
case CS_FAIL :
/* Hopefully this either cleans up the connection, or the
* connection ends up marked dead so it will be reopened
* if it is persistent . We may want to do
* ct_close ( CS_FORCE_CLOSE ) if ct_cancel ( ) fails ; see the
* doc for ct_results ( ) = = CS_FAIL .
*/
ct_cancel ( NULL , result - > sybase_ptr - > cmd , CS_CANCEL_ALL ) ;
/* Don't take chances with the vagaries of ct-lib. Mark it
* dead ourselves .
*/
result - > sybase_ptr - > dead = 1 ;
case CS_CANCELED :
default :
_free_sybase_result ( result ) ;
result = NULL ;
2004-01-24 02:17:42 +00:00
retcode = CS_FAIL ;
2002-11-05 08:29:57 +00:00
break ;
}
2004-01-24 02:17:42 +00:00
return retcode ;
2002-11-05 08:29:57 +00:00
}
2004-07-29 19:32:46 +00:00
# define RETURN_DOUBLE_VAL(result, buf, length) \
if ( ( length - 1 ) < = EG ( precision ) ) { \
errno = 0 ; \
Z_DVAL ( result ) = strtod ( buf , NULL ) ; \
if ( errno ! = ERANGE ) { \
Z_TYPE ( result ) = IS_DOUBLE ; \
} else { \
ZVAL_STRINGL ( & result , buf , length - 1 , 1 ) ; \
} \
} else { \
ZVAL_STRINGL ( & result , buf , length - 1 , 1 ) ; \
}
2004-05-18 10:53:53 +00:00
static int php_sybase_fetch_result_row ( sybase_result * result , int numrows )
2002-11-05 08:29:57 +00:00
{
int i , j ;
CS_INT retcode ;
2004-05-18 10:53:53 +00:00
TSRMLS_FETCH ( ) ;
2002-11-05 08:29:57 +00:00
/* We've already fetched everything */
2004-02-15 10:53:45 +00:00
if ( result - > last_retcode = = CS_END_DATA | | result - > last_retcode = = CS_END_RESULTS ) {
return result - > last_retcode ;
2002-11-05 08:29:57 +00:00
}
if ( numrows ! = - 1 ) numrows + = result - > num_rows ;
while ( ( retcode = ct_fetch ( result - > sybase_ptr - > cmd , CS_UNUSED , CS_UNUSED , CS_UNUSED , NULL ) ) = = CS_SUCCEED
| | retcode = = CS_ROW_FAIL ) {
/*
if ( retcode = = CS_ROW_FAIL ) {
2002-11-12 13:13:12 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: Error reading row %d " , result - > num_rows ) ;
2002-11-05 08:29:57 +00:00
}
*/
result - > num_rows + + ;
i = result - > store ? result - > num_rows - 1 : 0 ;
if ( i > = result - > blocks_initialized * SYBASE_ROWS_BLOCK ) {
result - > data = ( zval * * ) erealloc ( result - > data , sizeof ( zval * ) * SYBASE_ROWS_BLOCK * ( + + result - > blocks_initialized ) ) ;
}
if ( result - > store | | 1 = = result - > num_rows ) {
2003-08-12 00:58:52 +00:00
result - > data [ i ] = ( zval * ) safe_emalloc ( sizeof ( zval ) , result - > num_fields , 0 ) ;
2002-11-05 08:29:57 +00:00
}
1999-04-22 02:48:28 +00:00
2004-07-29 19:32:46 +00:00
for ( j = 0 ; j < result - > num_fields ; j + + ) {
/* If we are in non-storing mode, free the previous result */
if ( ! result - > store & & result - > num_rows > 1 & & Z_TYPE ( result - > data [ i ] [ j ] ) = = IS_STRING ) {
efree ( Z_STRVAL ( result - > data [ i ] [ j ] ) ) ;
}
2002-11-05 08:29:57 +00:00
if ( result - > indicators [ j ] = = - 1 ) { /* null value */
ZVAL_NULL ( & result - > data [ i ] [ j ] ) ;
} else {
switch ( result - > numerics [ j ] ) {
2004-07-29 19:32:46 +00:00
case 1 : {
/* This indicates a long */
ZVAL_LONG ( & result - > data [ i ] [ j ] , strtol ( result - > tmp_buffer [ j ] , NULL , 10 ) ) ;
2002-11-05 08:29:57 +00:00
break ;
2004-07-29 19:32:46 +00:00
}
case 2 : {
/* This indicates a float */
RETURN_DOUBLE_VAL ( result - > data [ i ] [ j ] , result - > tmp_buffer [ j ] , result - > lengths [ j ] ) ;
2002-11-05 08:29:57 +00:00
break ;
2004-07-29 19:32:46 +00:00
}
case 3 : {
/* This indicates either a long or a float, which ever fits */
errno = 0 ;
Z_LVAL ( result - > data [ i ] [ j ] ) = strtol ( result - > tmp_buffer [ j ] , NULL , 10 ) ;
if ( errno = = ERANGE ) {
/* An overflow occurred, so try to fit it into a double */
RETURN_DOUBLE_VAL ( result - > data [ i ] [ j ] , result - > tmp_buffer [ j ] , result - > lengths [ j ] ) ;
break ;
}
Z_TYPE ( result - > data [ i ] [ j ] ) = IS_LONG ;
break ;
}
default : {
/* This indicates anything else, return it as string */
ZVAL_STRINGL ( & result - > data [ i ] [ j ] , result - > tmp_buffer [ j ] , result - > lengths [ j ] - 1 , 1 ) ;
2004-05-16 20:30:35 +00:00
break ;
2004-07-29 19:32:46 +00:00
}
2002-11-05 08:29:57 +00:00
}
}
}
if ( numrows ! = - 1 & & result - > num_rows > = numrows ) break ;
}
result - > last_retcode = retcode ;
switch ( retcode ) {
case CS_END_DATA :
2004-01-24 02:17:42 +00:00
retcode = php_sybase_finish_results ( result ) ;
2002-11-05 08:29:57 +00:00
break ;
case CS_ROW_FAIL :
case CS_SUCCEED :
break ;
default :
_free_sybase_result ( result ) ;
result = NULL ;
2004-01-24 02:17:42 +00:00
retcode = CS_FAIL ; /* Just to be sure */
2002-11-05 08:29:57 +00:00
break ;
}
return retcode ;
}
static sybase_result * php_sybase_fetch_result_set ( sybase_link * sybase_ptr , int buffered , int store )
1999-04-22 02:48:28 +00:00
{
int num_fields ;
1999-09-04 13:03:09 +00:00
sybase_result * result ;
2002-11-05 08:29:57 +00:00
int i , j ;
CS_INT retcode ;
/* The following (if unbuffered) is more or less the equivalent of mysql_store_result().
1999-04-22 02:48:28 +00:00
* fetch all rows from the server into the row buffer , thus :
* 1 ) Being able to fire up another query without explicitly reading all rows
* 2 ) Having numrows accessible
*/
1999-09-04 13:03:09 +00:00
if ( ct_res_info ( sybase_ptr - > cmd , CS_NUMDATA , & num_fields , CS_UNUSED , NULL ) ! = CS_SUCCEED ) {
1999-04-22 02:48:28 +00:00
return NULL ;
}
2002-11-05 08:29:57 +00:00
1999-09-04 13:03:09 +00:00
result = ( sybase_result * ) emalloc ( sizeof ( sybase_result ) ) ;
2003-08-12 00:58:52 +00:00
result - > data = ( zval * * ) safe_emalloc ( sizeof ( zval * ) , SYBASE_ROWS_BLOCK , 0 ) ;
1999-04-22 02:48:28 +00:00
result - > fields = NULL ;
1999-09-04 13:03:09 +00:00
result - > sybase_ptr = sybase_ptr ;
1999-04-22 02:48:28 +00:00
result - > cur_field = result - > cur_row = result - > num_rows = 0 ;
result - > num_fields = num_fields ;
2002-11-05 08:29:57 +00:00
result - > last_retcode = 0 ;
result - > store = store ;
result - > blocks_initialized = 1 ;
2003-08-12 00:58:52 +00:00
result - > tmp_buffer = ( char * * ) safe_emalloc ( sizeof ( char * ) , num_fields , 0 ) ;
result - > lengths = ( CS_INT * ) safe_emalloc ( sizeof ( CS_INT ) , num_fields , 0 ) ;
result - > indicators = ( CS_SMALLINT * ) safe_emalloc ( sizeof ( CS_INT ) , num_fields , 0 ) ;
result - > datafmt = ( CS_DATAFMT * ) safe_emalloc ( sizeof ( CS_DATAFMT ) , num_fields , 0 ) ;
result - > numerics = ( unsigned char * ) safe_emalloc ( sizeof ( unsigned char ) , num_fields , 0 ) ;
result - > types = ( CS_INT * ) safe_emalloc ( sizeof ( CS_INT ) , num_fields , 0 ) ;
2002-11-05 08:29:57 +00:00
1999-04-22 02:48:28 +00:00
for ( i = 0 ; i < num_fields ; i + + ) {
2002-11-05 08:29:57 +00:00
ct_describe ( sybase_ptr - > cmd , i + 1 , & result - > datafmt [ i ] ) ;
result - > types [ i ] = result - > datafmt [ i ] . datatype ;
switch ( result - > datafmt [ i ] . datatype ) {
1999-04-22 02:48:28 +00:00
case CS_CHAR_TYPE :
case CS_VARCHAR_TYPE :
case CS_TEXT_TYPE :
case CS_IMAGE_TYPE :
2002-11-05 08:29:57 +00:00
result - > datafmt [ i ] . maxlength + + ;
result - > numerics [ i ] = 0 ;
1999-04-22 02:48:28 +00:00
break ;
case CS_BINARY_TYPE :
case CS_VARBINARY_TYPE :
2002-11-05 08:29:57 +00:00
result - > datafmt [ i ] . maxlength * = 2 ;
result - > datafmt [ i ] . maxlength + + ;
result - > numerics [ i ] = 0 ;
1999-04-22 02:48:28 +00:00
break ;
case CS_BIT_TYPE :
case CS_TINYINT_TYPE :
2002-11-05 08:29:57 +00:00
result - > datafmt [ i ] . maxlength = 4 ;
result - > numerics [ i ] = 1 ;
1999-04-22 02:48:28 +00:00
break ;
case CS_SMALLINT_TYPE :
2002-11-05 08:29:57 +00:00
result - > datafmt [ i ] . maxlength = 7 ;
result - > numerics [ i ] = 1 ;
1999-04-22 02:48:28 +00:00
break ;
case CS_INT_TYPE :
2002-11-05 08:29:57 +00:00
result - > datafmt [ i ] . maxlength = 12 ;
result - > numerics [ i ] = 1 ;
1999-04-22 02:48:28 +00:00
break ;
case CS_REAL_TYPE :
case CS_FLOAT_TYPE :
2002-11-05 08:29:57 +00:00
result - > datafmt [ i ] . maxlength = 24 ;
result - > numerics [ i ] = 2 ;
1999-04-22 02:48:28 +00:00
break ;
case CS_MONEY_TYPE :
case CS_MONEY4_TYPE :
2002-11-05 08:29:57 +00:00
result - > datafmt [ i ] . maxlength = 24 ;
result - > numerics [ i ] = 2 ;
1999-04-22 02:48:28 +00:00
break ;
case CS_DATETIME_TYPE :
case CS_DATETIME4_TYPE :
2002-11-05 08:29:57 +00:00
result - > datafmt [ i ] . maxlength = 30 ;
result - > numerics [ i ] = 0 ;
1999-04-22 02:48:28 +00:00
break ;
case CS_NUMERIC_TYPE :
case CS_DECIMAL_TYPE :
2002-11-05 08:29:57 +00:00
result - > datafmt [ i ] . maxlength = result - > datafmt [ i ] . precision + 3 ;
/* numeric(10) vs numeric(10, 1) */
2004-05-16 20:30:35 +00:00
result - > numerics [ i ] = ( result - > datafmt [ i ] . scale = = 0 ) ? 3 : 2 ;
1999-04-22 02:48:28 +00:00
break ;
default :
2002-11-05 08:29:57 +00:00
result - > datafmt [ i ] . maxlength + + ;
result - > numerics [ i ] = 0 ;
1999-04-22 02:48:28 +00:00
break ;
}
2002-11-05 08:29:57 +00:00
result - > tmp_buffer [ i ] = ( char * ) emalloc ( result - > datafmt [ i ] . maxlength ) ;
result - > datafmt [ i ] . datatype = CS_CHAR_TYPE ;
result - > datafmt [ i ] . format = CS_FMT_NULLTERM ;
ct_bind ( sybase_ptr - > cmd , i + 1 , & result - > datafmt [ i ] , result - > tmp_buffer [ i ] , & result - > lengths [ i ] , & result - > indicators [ i ] ) ;
1999-04-22 02:48:28 +00:00
}
2003-08-12 00:58:52 +00:00
result - > fields = ( sybase_field * ) safe_emalloc ( sizeof ( sybase_field ) , num_fields , 0 ) ;
2002-11-05 08:29:57 +00:00
j = 0 ;
for ( i = 0 ; i < num_fields ; i + + ) {
char computed_buf [ 16 ] ;
2001-08-13 19:45:26 +00:00
2002-11-05 08:29:57 +00:00
if ( result - > datafmt [ i ] . namelen > 0 ) {
result - > fields [ i ] . name = estrndup ( result - > datafmt [ i ] . name , result - > datafmt [ i ] . namelen ) ;
} else {
if ( j > 0 ) {
snprintf ( computed_buf , 16 , " computed%d " , j ) ;
1999-04-22 02:48:28 +00:00
} else {
2002-11-05 08:29:57 +00:00
strcpy ( computed_buf , " computed " ) ;
1999-04-22 02:48:28 +00:00
}
2002-11-05 08:29:57 +00:00
result - > fields [ i ] . name = estrdup ( computed_buf ) ;
j + + ;
1999-04-22 02:48:28 +00:00
}
2004-07-19 07:19:50 +00:00
result - > fields [ i ] . column_source = STR_EMPTY_ALLOC ( ) ;
2002-11-05 08:29:57 +00:00
result - > fields [ i ] . max_length = result - > datafmt [ i ] . maxlength - 1 ;
result - > fields [ i ] . numeric = result - > numerics [ i ] ;
Z_TYPE ( result - > fields [ i ] ) = result - > types [ i ] ;
1999-04-22 02:48:28 +00:00
}
2004-02-15 10:53:45 +00:00
2004-07-29 19:32:46 +00:00
if ( buffered ) {
retcode = CS_SUCCEED ;
} else {
if ( ( retcode = php_sybase_fetch_result_row ( result , - 1 ) ) = = CS_FAIL ) {
return NULL ;
}
2004-01-24 02:17:42 +00:00
}
1999-04-22 02:48:28 +00:00
2004-02-15 10:53:45 +00:00
result - > last_retcode = retcode ;
1999-04-22 02:48:28 +00:00
return result ;
}
2002-11-05 08:29:57 +00:00
static void php_sybase_query ( INTERNAL_FUNCTION_PARAMETERS , int buffered )
1999-04-22 02:48:28 +00:00
{
2002-11-05 08:29:57 +00:00
zval * * query , * * sybase_link_index = NULL ;
zval * * store_mode = NULL ;
int id , deadlock_count , store ;
1999-09-04 13:03:09 +00:00
sybase_link * sybase_ptr ;
sybase_result * result ;
1999-04-22 02:48:28 +00:00
CS_INT restype ;
CS_RETCODE retcode ;
enum {
Q_RESULT , /* Success with results. */
Q_SUCCESS , /* Success but no results. */
Q_FAILURE , /* Failure, no results. */
} status ;
2001-08-13 19:45:26 +00:00
2002-11-05 08:29:57 +00:00
store = 1 ;
2000-06-05 19:47:54 +00:00
switch ( ZEND_NUM_ARGS ( ) ) {
1999-04-22 02:48:28 +00:00
case 1 :
2000-09-10 05:24:30 +00:00
if ( zend_get_parameters_ex ( 1 , & query ) = = FAILURE ) {
1999-04-22 02:48:28 +00:00
RETURN_FALSE ;
}
2000-09-12 20:54:36 +00:00
id = SybCtG ( default_link ) ;
1999-04-22 02:48:28 +00:00
break ;
case 2 :
2000-09-10 05:24:30 +00:00
if ( zend_get_parameters_ex ( 2 , & query , & sybase_link_index ) = = FAILURE ) {
1999-04-22 02:48:28 +00:00
RETURN_FALSE ;
}
1999-09-04 13:03:09 +00:00
id = - 1 ;
1999-04-22 02:48:28 +00:00
break ;
2002-11-05 08:29:57 +00:00
case 3 :
if ( zend_get_parameters_ex ( 3 , & query , & sybase_link_index , & store_mode ) = = FAILURE ) {
RETURN_FALSE ;
}
2004-07-29 19:32:46 +00:00
if ( ! buffered ) {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " cannot use non-storing mode with buffered queries " ) ;
store = 1 ;
} else {
convert_to_long_ex ( store_mode ) ;
store = ( Z_LVAL_PP ( store_mode ) ! = 0 ) ;
}
2002-11-05 08:29:57 +00:00
id = - 1 ;
break ;
1999-04-22 02:48:28 +00:00
default :
WRONG_PARAM_COUNT ;
break ;
}
2001-08-13 19:45:26 +00:00
2000-09-20 04:12:03 +00:00
ZEND_FETCH_RESOURCE2 ( sybase_ptr , sybase_link * , sybase_link_index , id , " Sybase-Link " , le_link , le_plink ) ;
2001-08-13 19:45:26 +00:00
2000-09-10 05:24:30 +00:00
convert_to_string_ex ( query ) ;
2001-08-13 19:45:26 +00:00
1999-04-22 02:48:28 +00:00
/* Fail if we already marked this connection dead. */
1999-09-04 13:03:09 +00:00
if ( sybase_ptr - > dead ) {
1999-04-22 02:48:28 +00:00
RETURN_FALSE ;
}
2002-11-05 08:29:57 +00:00
/* Check to see if a previous sybase_unbuffered_query has read all rows */
if ( sybase_ptr - > active_result_index ) {
2002-12-07 19:49:31 +00:00
zval * tmp = NULL ;
2002-11-12 13:13:12 +00:00
2003-01-22 22:07:22 +00:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " called without first fetching all rows from a previous unbuffered query " ) ;
2002-11-05 08:29:57 +00:00
if ( sybase_ptr - > cmd ) {
ct_cancel ( NULL , sybase_ptr - > cmd , CS_CANCEL_ALL ) ;
}
2002-11-12 13:13:12 +00:00
/* Get the resultset and free it */
ALLOC_ZVAL ( tmp ) ;
Z_LVAL_P ( tmp ) = sybase_ptr - > active_result_index ;
Z_TYPE_P ( tmp ) = IS_RESOURCE ;
INIT_PZVAL ( tmp ) ;
ZEND_FETCH_RESOURCE ( result , sybase_result * , & tmp , - 1 , " Sybase result " , le_result ) ;
2002-12-07 19:49:31 +00:00
/* Causes the following segfault:
Program received signal SIGSEGV , Segmentation fault .
0x8144380 in _efree ( ptr = 0x81fe024 , __zend_filename = 0x81841a0 " php4/ext/sybase_ct/php_sybase_ct.c " ,
__zend_lineno = 946 , __zend_orig_filename = 0x0 , __zend_orig_lineno = 0 ) at php4 / Zend / zend_alloc . c : 229
php4 / Zend / zend_alloc . c : 229 : 7284 : beg : 0x8144380
*/
# if O_TIMM
2002-11-12 13:13:12 +00:00
if ( result ) {
php_sybase_finish_results ( result ) ;
}
2002-12-07 19:49:31 +00:00
# endif
zval_ptr_dtor ( & tmp ) ;
2002-11-05 08:29:57 +00:00
zend_list_delete ( sybase_ptr - > active_result_index ) ;
sybase_ptr - > active_result_index = 0 ;
}
1999-04-22 02:48:28 +00:00
/* Repeat until we don't deadlock. */
2002-11-05 08:29:57 +00:00
deadlock_count = 0 ;
1999-04-22 02:48:28 +00:00
for ( ; ; ) {
result = NULL ;
1999-09-04 13:03:09 +00:00
sybase_ptr - > deadlock = 0 ;
sybase_ptr - > affected_rows = 0 ;
1999-04-22 02:48:28 +00:00
/* On Solaris 11.5, ct_command() can be moved outside the
* loop , but not on Linux 11.0 .
*/
2001-09-25 21:58:48 +00:00
if ( ct_command ( sybase_ptr - > cmd , CS_LANG_CMD , Z_STRVAL_PP ( query ) , CS_NULLTERM , CS_UNUSED ) ! = CS_SUCCEED ) {
1999-04-22 02:48:28 +00:00
/* If this didn't work, the connection is screwed but
* ct - lib might not set CS_CONSTAT_DEAD . So set our own
* flag . This happens sometimes when the database is restarted
* and / or its machine is rebooted , and ct_command ( ) returns
* CS_BUSY for some reason .
*/
1999-09-04 13:03:09 +00:00
sybase_ptr - > dead = 1 ;
2002-11-12 13:13:12 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: Connection is dead " ) ;
2002-11-05 08:29:57 +00:00
RETURN_FALSE ;
1999-04-22 02:48:28 +00:00
}
1999-09-04 13:03:09 +00:00
if ( ct_send ( sybase_ptr - > cmd ) ! = CS_SUCCEED ) {
ct_cancel ( NULL , sybase_ptr - > cmd , CS_CANCEL_ALL ) ;
sybase_ptr - > dead = 1 ;
2002-11-12 13:13:12 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: Cannot send command " ) ;
1999-04-22 02:48:28 +00:00
RETURN_FALSE ;
}
/* Use the first result set or succeed/fail status and discard the
* others . Applications really shouldn ' t be making calls that
* return multiple result sets , but if they do then we need to
* properly read or cancel them or the connection will become
* unusable .
*/
1999-09-04 13:03:09 +00:00
if ( ct_results ( sybase_ptr - > cmd , & restype ) ! = CS_SUCCEED ) {
ct_cancel ( NULL , sybase_ptr - > cmd , CS_CANCEL_ALL ) ;
sybase_ptr - > dead = 1 ;
2002-11-12 13:13:12 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: Cannot read results " ) ;
1999-04-22 02:48:28 +00:00
RETURN_FALSE ;
}
switch ( ( int ) restype ) {
case CS_CMD_FAIL :
default :
status = Q_FAILURE ;
break ;
case CS_CMD_SUCCEED :
case CS_CMD_DONE : {
CS_INT row_count ;
1999-09-04 13:03:09 +00:00
if ( ct_res_info ( sybase_ptr - > cmd , CS_ROW_COUNT , & row_count , CS_UNUSED , NULL ) = = CS_SUCCEED ) {
sybase_ptr - > affected_rows = ( long ) row_count ;
1999-04-22 02:48:28 +00:00
}
}
/* Fall through */
case CS_COMPUTEFMT_RESULT :
case CS_ROWFMT_RESULT :
case CS_DESCRIBE_RESULT :
case CS_MSG_RESULT :
2002-11-05 08:29:57 +00:00
buffered = 0 ; /* These queries have no need for buffering */
1999-04-22 02:48:28 +00:00
status = Q_SUCCESS ;
break ;
case CS_COMPUTE_RESULT :
case CS_CURSOR_RESULT :
case CS_PARAM_RESULT :
case CS_ROW_RESULT :
case CS_STATUS_RESULT :
2002-11-05 08:29:57 +00:00
result = php_sybase_fetch_result_set ( sybase_ptr , buffered , store ) ;
1999-04-22 02:48:28 +00:00
if ( result = = NULL ) {
1999-09-04 13:03:09 +00:00
ct_cancel ( NULL , sybase_ptr - > cmd , CS_CANCEL_ALL ) ;
1999-04-22 02:48:28 +00:00
RETURN_FALSE ;
}
status = Q_RESULT ;
break ;
}
2002-11-05 08:29:57 +00:00
/* Check for left-over results */
if ( ! buffered & & status ! = Q_RESULT ) {
while ( ( retcode = ct_results ( sybase_ptr - > cmd , & restype ) ) = = CS_SUCCEED ) {
switch ( ( int ) restype ) {
case CS_CMD_SUCCEED :
case CS_CMD_DONE :
break ;
case CS_CMD_FAIL :
status = Q_FAILURE ;
break ;
case CS_COMPUTE_RESULT :
case CS_CURSOR_RESULT :
case CS_PARAM_RESULT :
case CS_ROW_RESULT :
2003-08-28 16:19:08 +00:00
if ( status ! = Q_RESULT ) {
result = php_sybase_fetch_result_set ( sybase_ptr , buffered , store ) ;
if ( result = = NULL ) {
ct_cancel ( NULL , sybase_ptr - > cmd , CS_CANCEL_ALL ) ;
sybase_ptr - > dead = 1 ;
RETURN_FALSE ;
}
status = Q_RESULT ;
2004-02-15 10:53:45 +00:00
retcode = result - > last_retcode ;
2003-08-28 16:19:08 +00:00
} else {
/* Unexpected results, cancel them. */
ct_cancel ( NULL , sybase_ptr - > cmd , CS_CANCEL_CURRENT ) ;
}
break ;
2002-11-05 08:29:57 +00:00
case CS_STATUS_RESULT :
2003-08-28 16:19:08 +00:00
/* Unexpected results, cancel them. */
2002-11-05 08:29:57 +00:00
ct_cancel ( NULL , sybase_ptr - > cmd , CS_CANCEL_CURRENT ) ;
break ;
default :
status = Q_FAILURE ;
break ;
}
if ( status = = Q_FAILURE ) {
ct_cancel ( NULL , sybase_ptr - > cmd , CS_CANCEL_ALL ) ;
}
2004-02-15 10:53:45 +00:00
if ( retcode = = CS_END_RESULTS ) {
break ;
}
2002-11-05 08:29:57 +00:00
}
switch ( retcode ) {
case CS_END_RESULTS :
/* Normal. */
1999-04-22 02:48:28 +00:00
break ;
2001-08-13 19:45:26 +00:00
2002-11-05 08:29:57 +00:00
case CS_FAIL :
/* Hopefully this either cleans up the connection, or the
* connection ends up marked dead so it will be reopened
* if it is persistent . We may want to do
* ct_close ( CS_FORCE_CLOSE ) if ct_cancel ( ) fails ; see the
* doc for ct_results ( ) = = CS_FAIL .
*/
ct_cancel ( NULL , sybase_ptr - > cmd , CS_CANCEL_ALL ) ;
/* Don't take chances with the vagaries of ct-lib. Mark it
* dead ourselves .
*/
sybase_ptr - > dead = 1 ;
case CS_CANCELED :
1999-04-22 02:48:28 +00:00
default :
status = Q_FAILURE ;
break ;
}
}
2004-02-15 10:53:45 +00:00
2002-11-05 08:29:57 +00:00
/* Retry deadlocks up until deadlock_retry_count times */
if ( sybase_ptr - > deadlock & & SybCtG ( deadlock_retry_count ) ! = - 1 & & + + deadlock_count > SybCtG ( deadlock_retry_count ) ) {
2005-08-18 13:34:41 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: Retried deadlock %d times [max: %ld], giving up " , deadlock_count - 1 , SybCtG ( deadlock_retry_count ) ) ;
2002-11-05 08:29:57 +00:00
if ( result ! = NULL ) {
_free_sybase_result ( result ) ;
}
break ;
1999-04-22 02:48:28 +00:00
}
/* If query completed without deadlock, break out of the loop.
* Sometimes deadlock results in failures and sometimes not ,
* it seems to depend on the server flavor . But we want to
* retry all deadlocks .
*/
1999-09-04 13:03:09 +00:00
if ( sybase_ptr - > dead | | sybase_ptr - > deadlock = = 0 ) {
1999-04-22 02:48:28 +00:00
break ;
}
/* Get rid of any results we may have fetched. This happens:
* e . g . , our result set may be a stored procedure status which
* is returned even if the stored procedure deadlocks . As an
* optimization , we could try not to fetch results in known
* deadlock conditions , but deadlock is ( should be ) rare .
*/
if ( result ! = NULL ) {
1999-09-04 13:03:09 +00:00
_free_sybase_result ( result ) ;
1999-04-22 02:48:28 +00:00
}
}
if ( status = = Q_SUCCESS ) {
RETURN_TRUE ;
}
if ( status = = Q_FAILURE ) {
if ( result ! = NULL ) {
1999-09-04 13:03:09 +00:00
_free_sybase_result ( result ) ;
1999-04-22 02:48:28 +00:00
}
RETURN_FALSE ;
}
2002-11-05 08:29:57 +00:00
/* Indicate we have data in case of buffered queries */
2004-01-24 02:17:42 +00:00
id = ZEND_REGISTER_RESOURCE ( return_value , result , le_result ) ;
2002-11-05 08:29:57 +00:00
sybase_ptr - > active_result_index = buffered ? id : 0 ;
1999-04-22 02:48:28 +00:00
}
2002-11-05 08:29:57 +00:00
/* {{{ proto int sybase_query(string query [, int link_id])
Send Sybase query */
PHP_FUNCTION ( sybase_query )
{
php_sybase_query ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 0 ) ;
}
2000-09-26 07:38:47 +00:00
/* }}} */
1999-04-22 02:48:28 +00:00
2002-11-05 08:29:57 +00:00
/* {{{ proto int sybase_unbuffered_query(string query [, int link_id])
Send Sybase query */
PHP_FUNCTION ( sybase_unbuffered_query )
{
php_sybase_query ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 1 ) ;
}
2000-09-26 07:38:47 +00:00
/* {{{ proto bool sybase_free_result(int result)
2001-01-26 21:41:38 +00:00
Free result memory */
1999-09-04 13:03:09 +00:00
PHP_FUNCTION ( sybase_free_result )
1999-04-22 02:48:28 +00:00
{
2003-01-15 03:01:17 +00:00
zval * * sybase_result_index ;
1999-09-04 13:03:09 +00:00
sybase_result * result ;
2001-08-13 19:45:26 +00:00
2003-01-15 03:01:17 +00:00
if ( ZEND_NUM_ARGS ( ) ! = 1 | | zend_get_parameters_ex ( 1 , & sybase_result_index ) = = FAILURE ) {
1999-04-22 02:48:28 +00:00
WRONG_PARAM_COUNT ;
}
2001-08-13 19:45:26 +00:00
2003-01-15 03:01:17 +00:00
if ( Z_TYPE_PP ( sybase_result_index ) = = IS_RESOURCE & & Z_LVAL_PP ( sybase_result_index ) = = 0 ) {
1999-04-22 02:48:28 +00:00
RETURN_FALSE ;
}
1999-09-04 13:03:09 +00:00
2003-01-15 03:01:17 +00:00
ZEND_FETCH_RESOURCE ( result , sybase_result * , sybase_result_index , - 1 , " Sybase result " , le_result ) ;
2002-11-05 08:29:57 +00:00
/* Did we fetch up until the end? */
2004-05-21 20:29:38 +00:00
if ( result - > last_retcode ! = CS_END_DATA & & result - > last_retcode ! = CS_END_RESULTS ) {
2005-08-18 13:34:41 +00:00
/* php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sybase: Cancelling the rest of the results"); */
2002-11-05 08:29:57 +00:00
ct_cancel ( NULL , result - > sybase_ptr - > cmd , CS_CANCEL_ALL ) ;
php_sybase_finish_results ( result ) ;
}
2003-01-15 03:01:17 +00:00
zend_list_delete ( Z_LVAL_PP ( sybase_result_index ) ) ;
1999-04-22 02:48:28 +00:00
RETURN_TRUE ;
}
2000-09-26 07:38:47 +00:00
/* }}} */
1999-04-22 02:48:28 +00:00
2001-01-13 22:47:44 +00:00
/* {{{ proto string sybase_get_last_message(void)
Returns the last message from server ( over min_message_severity ) */
PHP_FUNCTION ( sybase_get_last_message )
2001-08-13 19:58:07 +00:00
{
RETURN_STRING ( SybCtG ( server_message ) , 1 ) ;
2001-01-13 22:47:44 +00:00
}
/* }}} */
2000-09-26 07:38:47 +00:00
/* {{{ proto int sybase_num_rows(int result)
2001-01-26 21:41:38 +00:00
Get number of rows in result */
1999-09-04 13:03:09 +00:00
PHP_FUNCTION ( sybase_num_rows )
1999-04-22 02:48:28 +00:00
{
2003-01-15 03:01:17 +00:00
zval * * sybase_result_index ;
1999-09-04 13:03:09 +00:00
sybase_result * result ;
2001-08-13 19:45:26 +00:00
2003-01-15 03:01:17 +00:00
if ( ZEND_NUM_ARGS ( ) ! = 1 | | zend_get_parameters_ex ( 1 , & sybase_result_index ) = = FAILURE ) {
1999-04-22 02:48:28 +00:00
WRONG_PARAM_COUNT ;
}
2001-08-13 19:45:26 +00:00
2003-01-15 03:01:17 +00:00
ZEND_FETCH_RESOURCE ( result , sybase_result * , sybase_result_index , - 1 , " Sybase result " , le_result ) ;
2001-08-13 19:45:26 +00:00
2001-08-14 01:07:42 +00:00
Z_LVAL_P ( return_value ) = result - > num_rows ;
2001-09-25 21:58:48 +00:00
Z_TYPE_P ( return_value ) = IS_LONG ;
1999-04-22 02:48:28 +00:00
}
2000-09-26 07:38:47 +00:00
/* }}} */
1999-04-22 02:48:28 +00:00
2000-09-26 07:38:47 +00:00
/* {{{ proto int sybase_num_fields(int result)
2001-01-26 21:41:38 +00:00
Get number of fields in result */
1999-09-04 13:03:09 +00:00
PHP_FUNCTION ( sybase_num_fields )
1999-04-22 02:48:28 +00:00
{
2003-01-15 03:01:17 +00:00
zval * * sybase_result_index ;
1999-09-04 13:03:09 +00:00
sybase_result * result ;
2001-08-13 19:45:26 +00:00
2003-01-15 03:01:17 +00:00
if ( ZEND_NUM_ARGS ( ) ! = 1 | | zend_get_parameters_ex ( 1 , & sybase_result_index ) = = FAILURE ) {
1999-04-22 02:48:28 +00:00
WRONG_PARAM_COUNT ;
}
2001-08-13 19:45:26 +00:00
2003-01-15 03:01:17 +00:00
ZEND_FETCH_RESOURCE ( result , sybase_result * , sybase_result_index , - 1 , " Sybase result " , le_result ) ;
2001-08-13 19:45:26 +00:00
2001-08-14 01:07:42 +00:00
Z_LVAL_P ( return_value ) = result - > num_fields ;
2001-09-25 21:58:48 +00:00
Z_TYPE_P ( return_value ) = IS_LONG ;
1999-04-22 02:48:28 +00:00
}
2000-09-26 07:38:47 +00:00
/* }}} */
1999-04-22 02:48:28 +00:00
2000-09-26 07:38:47 +00:00
/* {{{ proto array sybase_fetch_row(int result)
2001-01-26 21:41:38 +00:00
Get row as enumerated array */
1999-09-04 13:03:09 +00:00
PHP_FUNCTION ( sybase_fetch_row )
1999-04-22 02:48:28 +00:00
{
2003-01-15 03:01:17 +00:00
zval * * sybase_result_index ;
1999-09-04 13:03:09 +00:00
int i ;
sybase_result * result ;
2002-11-05 08:29:57 +00:00
zval * field_content ;
1999-04-22 02:48:28 +00:00
2003-01-15 03:01:17 +00:00
if ( ZEND_NUM_ARGS ( ) ! = 1 | | zend_get_parameters_ex ( 1 , & sybase_result_index ) = = FAILURE ) {
1999-04-22 02:48:28 +00:00
WRONG_PARAM_COUNT ;
}
2002-11-05 08:29:57 +00:00
2003-01-15 03:01:17 +00:00
ZEND_FETCH_RESOURCE ( result , sybase_result * , sybase_result_index , - 1 , " Sybase result " , le_result ) ;
2001-08-13 19:45:26 +00:00
2002-11-05 08:29:57 +00:00
/* Unbuffered? */
2004-02-15 10:53:45 +00:00
if ( result - > last_retcode ! = CS_END_DATA & & result - > last_retcode ! = CS_END_RESULTS ) {
2002-11-05 08:29:57 +00:00
php_sybase_fetch_result_row ( result , 1 ) ;
}
/* At the end? */
1999-04-22 02:48:28 +00:00
if ( result - > cur_row > = result - > num_rows ) {
RETURN_FALSE ;
}
2001-08-13 19:45:26 +00:00
1999-04-22 02:48:28 +00:00
array_init ( return_value ) ;
for ( i = 0 ; i < result - > num_fields ; i + + ) {
1999-12-26 21:21:33 +00:00
ALLOC_ZVAL ( field_content ) ;
2002-11-05 08:29:57 +00:00
* field_content = result - > data [ result - > store ? result - > cur_row : 0 ] [ i ] ;
1999-07-16 22:00:53 +00:00
INIT_PZVAL ( field_content ) ;
2002-11-05 08:29:57 +00:00
zval_copy_ctor ( field_content ) ;
zend_hash_index_update ( Z_ARRVAL_P ( return_value ) , i , ( void * ) & field_content , sizeof ( zval * ) , NULL ) ;
1999-04-22 02:48:28 +00:00
}
result - > cur_row + + ;
}
2000-09-26 07:38:47 +00:00
/* }}} */
1999-04-22 02:48:28 +00:00
2002-11-05 08:29:57 +00:00
static void php_sybase_fetch_hash ( INTERNAL_FUNCTION_PARAMETERS , int numerics )
1999-04-22 02:48:28 +00:00
{
2003-01-15 03:01:17 +00:00
zval * * sybase_result_index ;
1999-09-04 13:03:09 +00:00
sybase_result * result ;
2002-11-05 08:29:57 +00:00
int i , j ;
zval * tmp ;
char name [ 32 ] ;
2001-08-13 19:45:26 +00:00
2003-01-15 03:01:17 +00:00
if ( ZEND_NUM_ARGS ( ) ! = 1 | | zend_get_parameters_ex ( 1 , & sybase_result_index ) = = FAILURE ) {
1999-04-22 02:48:28 +00:00
WRONG_PARAM_COUNT ;
}
2001-08-13 19:45:26 +00:00
2003-01-15 03:01:17 +00:00
ZEND_FETCH_RESOURCE ( result , sybase_result * , sybase_result_index , - 1 , " Sybase result " , le_result ) ;
2001-08-13 19:45:26 +00:00
2002-11-05 08:29:57 +00:00
/* Unbuffered ? Fetch next row */
2004-02-15 10:53:45 +00:00
if ( result - > last_retcode ! = CS_END_DATA & & result - > last_retcode ! = CS_END_RESULTS ) {
2002-11-05 08:29:57 +00:00
php_sybase_fetch_result_row ( result , 1 ) ;
}
/* At the end? */
1999-04-22 02:48:28 +00:00
if ( result - > cur_row > = result - > num_rows ) {
RETURN_FALSE ;
}
2001-08-13 19:45:26 +00:00
2003-01-15 03:01:17 +00:00
array_init ( return_value ) ;
2002-11-05 08:29:57 +00:00
j = 1 ;
1999-04-22 02:48:28 +00:00
for ( i = 0 ; i < result - > num_fields ; i + + ) {
1999-12-26 21:21:33 +00:00
ALLOC_ZVAL ( tmp ) ;
2002-11-05 08:29:57 +00:00
* tmp = result - > data [ result - > store ? result - > cur_row : 0 ] [ i ] ;
1999-07-16 22:00:53 +00:00
INIT_PZVAL ( tmp ) ;
2001-09-25 21:58:48 +00:00
if ( PG ( magic_quotes_runtime ) & & Z_TYPE_P ( tmp ) = = IS_STRING ) {
2001-08-14 01:07:42 +00:00
Z_STRVAL_P ( tmp ) = php_addslashes ( Z_STRVAL_P ( tmp ) , Z_STRLEN_P ( tmp ) , & Z_STRLEN_P ( tmp ) , 0 TSRMLS_CC ) ;
1999-11-19 13:06:12 +00:00
} else {
2002-11-05 08:29:57 +00:00
zval_copy_ctor ( tmp ) ;
}
if ( numerics ) {
zend_hash_index_update ( Z_ARRVAL_P ( return_value ) , i , ( void * ) & tmp , sizeof ( zval * ) , NULL ) ;
2002-12-07 19:49:31 +00:00
tmp - > refcount + + ;
1999-04-22 02:48:28 +00:00
}
2002-11-05 08:29:57 +00:00
if ( zend_hash_exists ( Z_ARRVAL_P ( return_value ) , result - > fields [ i ] . name , strlen ( result - > fields [ i ] . name ) + 1 ) ) {
snprintf ( name , 32 , " %s%d " , result - > fields [ i ] . name , j ) ;
result - > fields [ i ] . name = estrdup ( name ) ;
j + + ;
}
zend_hash_update ( Z_ARRVAL_P ( return_value ) , result - > fields [ i ] . name , strlen ( result - > fields [ i ] . name ) + 1 , ( void * ) & tmp , sizeof ( zval * ) , NULL ) ;
1999-04-22 02:48:28 +00:00
}
result - > cur_row + + ;
}
2002-11-12 13:13:12 +00:00
/* {{{ proto object sybase_fetch_object(int result [, mixed object])
2001-01-26 21:41:38 +00:00
Fetch row as object */
1999-09-04 13:03:09 +00:00
PHP_FUNCTION ( sybase_fetch_object )
1999-04-22 02:48:28 +00:00
{
2002-11-12 13:13:12 +00:00
zval * * object = NULL ;
zval * sybase_result_index ;
zend_class_entry * ce = NULL ;
/* Was a second parameter given? */
if ( 2 = = ZEND_NUM_ARGS ( ) ) {
if ( zend_get_parameters_ex ( 2 , & sybase_result_index , & object ) = = FAILURE ) {
WRONG_PARAM_COUNT ;
}
switch ( Z_TYPE_PP ( object ) ) {
case IS_OBJECT :
2004-07-29 19:32:46 +00:00
ce = Z_OBJCE_PP ( object ) ;
2002-11-12 13:13:12 +00:00
break ;
2004-07-29 19:32:46 +00:00
case IS_NULL :
break ;
default : {
zend_class_entry * * pce = NULL ;
2002-11-12 13:13:12 +00:00
2004-07-29 19:32:46 +00:00
convert_to_string_ex ( object ) ;
if ( zend_lookup_class ( Z_STRVAL_PP ( object ) , Z_STRLEN_PP ( object ) , & pce TSRMLS_CC ) = = FAILURE ) {
2002-11-12 13:13:12 +00:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Sybase: Class %s has not been declared " , Z_STRVAL_PP ( object ) ) ;
2004-07-29 19:32:46 +00:00
} else {
ce = * pce ;
2002-11-12 13:13:12 +00:00
}
2004-07-29 19:32:46 +00:00
}
2002-11-12 13:13:12 +00:00
}
2004-07-29 19:32:46 +00:00
/* Reset no. of arguments to 1 so that we can use INTERNAL_FUNCTION_PARAM_PASSTHRU */
2002-11-12 13:13:12 +00:00
ht = 1 ;
}
2002-11-05 08:29:57 +00:00
php_sybase_fetch_hash ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 0 ) ;
2001-09-25 21:58:48 +00:00
if ( Z_TYPE_P ( return_value ) = = IS_ARRAY ) {
2002-11-12 13:13:12 +00:00
object_and_properties_init (
return_value ,
2004-07-29 19:32:46 +00:00
ce ? ce : ZEND_STANDARD_CLASS_DEF_PTR ,
2002-11-12 13:13:12 +00:00
Z_ARRVAL_P ( return_value )
) ;
1999-04-22 02:48:28 +00:00
}
}
2000-09-26 07:38:47 +00:00
/* }}} */
1999-04-22 02:48:28 +00:00
2000-09-26 07:38:47 +00:00
/* {{{ proto array sybase_fetch_array(int result)
2001-01-26 21:41:38 +00:00
Fetch row as array */
1999-09-04 13:03:09 +00:00
PHP_FUNCTION ( sybase_fetch_array )
1999-04-22 02:48:28 +00:00
{
2002-11-05 08:29:57 +00:00
php_sybase_fetch_hash ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 1 ) ;
}
/* }}} */
/* {{{ proto array sybase_fetch_assoc(int result)
Fetch row as array without numberic indices */
PHP_FUNCTION ( sybase_fetch_assoc )
{
php_sybase_fetch_hash ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 0 ) ;
1999-04-22 02:48:28 +00:00
}
2000-09-26 07:38:47 +00:00
/* }}} */
/* {{{ proto bool sybase_data_seek(int result, int offset)
2001-01-26 21:41:38 +00:00
Move internal row pointer */
1999-09-04 13:03:09 +00:00
PHP_FUNCTION ( sybase_data_seek )
1999-04-22 02:48:28 +00:00
{
2003-01-15 03:01:17 +00:00
zval * * sybase_result_index , * * offset ;
1999-09-04 13:03:09 +00:00
sybase_result * result ;
1999-04-22 02:48:28 +00:00
2003-01-15 03:01:17 +00:00
if ( ZEND_NUM_ARGS ( ) ! = 2 | | zend_get_parameters_ex ( 2 , & sybase_result_index , & offset ) = = FAILURE ) {
1999-04-22 02:48:28 +00:00
WRONG_PARAM_COUNT ;
}
2001-08-13 19:45:26 +00:00
1999-09-04 13:03:09 +00:00
2003-01-15 13:55:34 +00:00
ZEND_FETCH_RESOURCE ( result , sybase_result * , sybase_result_index , - 1 , " Sybase result " , le_result ) ;
1999-04-22 02:48:28 +00:00
2003-01-15 03:01:17 +00:00
convert_to_long_ex ( offset ) ;
2002-11-05 08:29:57 +00:00
/* Unbuffered ? */
2004-02-15 10:53:45 +00:00
if ( result - > last_retcode ! = CS_END_DATA & & result - > last_retcode ! = CS_END_RESULTS & & Z_LVAL_PP ( offset ) > = result - > num_rows ) {
2004-07-29 19:32:46 +00:00
php_sybase_fetch_result_row ( result , Z_LVAL_PP ( offset ) + 1 ) ;
2002-11-05 08:29:57 +00:00
}
2003-01-15 03:01:17 +00:00
if ( Z_LVAL_PP ( offset ) < 0 | | Z_LVAL_PP ( offset ) > = result - > num_rows ) {
2004-07-29 19:32:46 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: Bad row offset %ld, must be betweem 0 and %d " , Z_LVAL_PP ( offset ) , result - > num_rows - 1 ) ;
1999-04-22 02:48:28 +00:00
RETURN_FALSE ;
}
2001-08-13 19:45:26 +00:00
2003-01-15 03:01:17 +00:00
result - > cur_row = Z_LVAL_PP ( offset ) ;
1999-04-22 02:48:28 +00:00
RETURN_TRUE ;
}
2000-09-26 07:38:47 +00:00
/* }}} */
1999-04-22 02:48:28 +00:00
1999-09-04 13:03:09 +00:00
static char * php_sybase_get_field_name ( CS_INT type )
1999-04-22 02:48:28 +00:00
{
switch ( type ) {
case CS_CHAR_TYPE :
case CS_VARCHAR_TYPE :
case CS_TEXT_TYPE :
return " string " ;
break ;
case CS_IMAGE_TYPE :
return " image " ;
break ;
case CS_BINARY_TYPE :
case CS_VARBINARY_TYPE :
return " blob " ;
break ;
case CS_BIT_TYPE :
return " bit " ;
break ;
case CS_TINYINT_TYPE :
case CS_SMALLINT_TYPE :
case CS_INT_TYPE :
return " int " ;
break ;
case CS_REAL_TYPE :
case CS_FLOAT_TYPE :
case CS_NUMERIC_TYPE :
case CS_DECIMAL_TYPE :
return " real " ;
break ;
case CS_MONEY_TYPE :
case CS_MONEY4_TYPE :
return " money " ;
break ;
case CS_DATETIME_TYPE :
case CS_DATETIME4_TYPE :
return " datetime " ;
break ;
default :
return " unknown " ;
break ;
}
}
2000-09-26 07:38:47 +00:00
/* {{{ proto object sybase_fetch_field(int result [, int offset])
2001-01-26 21:41:38 +00:00
Get field information */
1999-09-04 13:03:09 +00:00
PHP_FUNCTION ( sybase_fetch_field )
1999-04-22 02:48:28 +00:00
{
2003-01-15 13:55:34 +00:00
zval * * sybase_result_index , * * offset ;
1999-09-04 13:03:09 +00:00
int field_offset ;
sybase_result * result ;
1999-04-22 02:48:28 +00:00
2000-06-05 19:47:54 +00:00
switch ( ZEND_NUM_ARGS ( ) ) {
1999-04-22 02:48:28 +00:00
case 1 :
2003-01-15 03:01:17 +00:00
if ( zend_get_parameters_ex ( 1 , & sybase_result_index ) = = FAILURE ) {
1999-04-22 02:48:28 +00:00
RETURN_FALSE ;
}
field_offset = - 1 ;
break ;
case 2 :
2003-01-15 03:01:17 +00:00
if ( zend_get_parameters_ex ( 2 , & sybase_result_index , & offset ) = = FAILURE ) {
1999-04-22 02:48:28 +00:00
RETURN_FALSE ;
}
2003-01-15 03:01:17 +00:00
convert_to_long_ex ( offset ) ;
field_offset = Z_LVAL_PP ( offset ) ;
1999-04-22 02:48:28 +00:00
break ;
default :
WRONG_PARAM_COUNT ;
break ;
}
2001-08-13 19:45:26 +00:00
2003-01-15 13:55:34 +00:00
ZEND_FETCH_RESOURCE ( result , sybase_result * , sybase_result_index , - 1 , " Sybase result " , le_result ) ;
2001-08-13 19:45:26 +00:00
1999-04-22 02:48:28 +00:00
if ( field_offset = = - 1 ) {
field_offset = result - > cur_field ;
result - > cur_field + + ;
}
2001-08-13 19:45:26 +00:00
1999-04-22 02:48:28 +00:00
if ( field_offset < 0 | | field_offset > = result - > num_fields ) {
2000-06-05 19:47:54 +00:00
if ( ZEND_NUM_ARGS ( ) = = 2 ) { /* field specified explicitly */
2002-11-12 13:13:12 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: Bad column offset " ) ;
1999-04-22 02:48:28 +00:00
}
RETURN_FALSE ;
}
2003-01-30 02:33:16 +00:00
object_init ( return_value ) ;
2000-09-12 20:54:36 +00:00
add_property_string ( return_value , " name " , result - > fields [ field_offset ] . name , 1 ) ;
add_property_long ( return_value , " max_length " , result - > fields [ field_offset ] . max_length ) ;
add_property_string ( return_value , " column_source " , result - > fields [ field_offset ] . column_source , 1 ) ;
1999-04-22 02:48:28 +00:00
add_property_long ( return_value , " numeric " , result - > fields [ field_offset ] . numeric ) ;
2001-09-26 08:35:48 +00:00
add_property_string ( return_value , " type " , php_sybase_get_field_name ( Z_TYPE ( result - > fields [ field_offset ] ) ) , 1 ) ;
1999-04-22 02:48:28 +00:00
}
2000-09-26 07:38:47 +00:00
/* }}} */
1999-04-22 02:48:28 +00:00
2000-09-26 07:38:47 +00:00
/* {{{ proto bool sybase_field_seek(int result, int offset)
2001-01-26 21:41:38 +00:00
Set field offset */
1999-09-04 13:03:09 +00:00
PHP_FUNCTION ( sybase_field_seek )
1999-04-22 02:48:28 +00:00
{
2003-01-15 03:01:17 +00:00
zval * * sybase_result_index , * * offset ;
1999-09-04 13:03:09 +00:00
int field_offset ;
sybase_result * result ;
1999-04-22 02:48:28 +00:00
2003-01-15 03:01:17 +00:00
if ( ZEND_NUM_ARGS ( ) ! = 2 | | zend_get_parameters_ex ( 2 , & sybase_result_index , & offset ) = = FAILURE ) {
1999-04-22 02:48:28 +00:00
WRONG_PARAM_COUNT ;
}
2001-08-13 19:45:26 +00:00
2003-01-15 13:55:34 +00:00
ZEND_FETCH_RESOURCE ( result , sybase_result * , sybase_result_index , - 1 , " Sybase result " , le_result ) ;
2001-08-13 19:45:26 +00:00
2003-01-15 03:01:17 +00:00
convert_to_long_ex ( offset ) ;
field_offset = Z_LVAL_PP ( offset ) ;
2002-11-05 08:29:57 +00:00
1999-04-22 02:48:28 +00:00
if ( field_offset < 0 | | field_offset > = result - > num_fields ) {
2002-11-12 13:13:12 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: Bad column offset " ) ;
1999-04-22 02:48:28 +00:00
RETURN_FALSE ;
}
result - > cur_field = field_offset ;
RETURN_TRUE ;
}
2000-09-26 07:38:47 +00:00
/* }}} */
1999-04-22 02:48:28 +00:00
2000-09-26 07:38:47 +00:00
/* {{{ proto string sybase_result(int result, int row, mixed field)
2001-01-26 21:41:38 +00:00
Get result data */
1999-09-04 13:03:09 +00:00
PHP_FUNCTION ( sybase_result )
1999-04-22 02:48:28 +00:00
{
2003-01-15 03:01:17 +00:00
zval * * row , * * field , * * sybase_result_index ;
1999-09-04 13:03:09 +00:00
int field_offset = 0 ;
sybase_result * result ;
1999-04-22 02:48:28 +00:00
2003-01-15 03:01:17 +00:00
if ( ZEND_NUM_ARGS ( ) ! = 3 | | zend_get_parameters_ex ( 3 , & sybase_result_index , & row , & field ) = = FAILURE ) {
1999-04-22 02:48:28 +00:00
WRONG_PARAM_COUNT ;
}
2001-08-13 19:45:26 +00:00
2003-01-15 13:55:34 +00:00
ZEND_FETCH_RESOURCE ( result , sybase_result * , sybase_result_index , - 1 , " Sybase result " , le_result ) ;
1999-09-04 13:03:09 +00:00
2003-01-15 03:01:17 +00:00
convert_to_long_ex ( row ) ;
2002-11-05 08:29:57 +00:00
2002-11-12 13:13:12 +00:00
/* Unbuffered ? */
2004-02-15 10:53:45 +00:00
if ( result - > last_retcode ! = CS_END_DATA & & result - > last_retcode ! = CS_END_RESULTS & & Z_LVAL_PP ( row ) > = result - > num_rows ) {
2003-01-15 03:01:17 +00:00
php_sybase_fetch_result_row ( result , Z_LVAL_PP ( row ) ) ;
2002-11-12 13:13:12 +00:00
}
2002-11-05 08:29:57 +00:00
2003-01-15 03:01:17 +00:00
if ( Z_LVAL_PP ( row ) < 0 | | Z_LVAL_PP ( row ) > = result - > num_rows ) {
2004-01-18 16:01:02 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: Bad row offset (%ld) " , Z_LVAL_PP ( row ) ) ;
1999-04-22 02:48:28 +00:00
RETURN_FALSE ;
}
2003-01-15 03:01:17 +00:00
switch ( Z_TYPE_PP ( field ) ) {
1999-04-22 02:48:28 +00:00
case IS_STRING : {
int i ;
for ( i = 0 ; i < result - > num_fields ; i + + ) {
2003-01-15 03:01:17 +00:00
if ( ! strcasecmp ( result - > fields [ i ] . name , Z_STRVAL_PP ( field ) ) ) {
1999-04-22 02:48:28 +00:00
field_offset = i ;
break ;
}
}
if ( i > = result - > num_fields ) { /* no match found */
2003-01-15 03:01:17 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: %s field not found in result " , Z_STRVAL_PP ( field ) ) ;
1999-04-22 02:48:28 +00:00
RETURN_FALSE ;
}
break ;
}
default :
2003-01-15 03:01:17 +00:00
convert_to_long_ex ( field ) ;
field_offset = Z_LVAL_PP ( field ) ;
1999-04-22 02:48:28 +00:00
if ( field_offset < 0 | | field_offset > = result - > num_fields ) {
2002-11-12 13:13:12 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: Bad column offset specified " ) ;
1999-04-22 02:48:28 +00:00
RETURN_FALSE ;
}
break ;
}
2003-01-15 03:01:17 +00:00
* return_value = result - > data [ Z_LVAL_PP ( row ) ] [ field_offset ] ;
2002-11-05 08:29:57 +00:00
zval_copy_ctor ( return_value ) ;
1999-04-22 02:48:28 +00:00
}
2000-09-26 07:38:47 +00:00
/* }}} */
1999-04-22 02:48:28 +00:00
2000-10-05 02:40:53 +00:00
/* {{{ proto int sybase_affected_rows([int link_id])
2001-01-26 21:41:38 +00:00
Get number of affected rows in last query */
1999-09-04 13:03:09 +00:00
PHP_FUNCTION ( sybase_affected_rows )
1999-04-22 02:48:28 +00:00
{
2003-01-15 03:01:17 +00:00
zval * * sybase_link_index ;
1999-09-04 13:03:09 +00:00
sybase_link * sybase_ptr ;
int id ;
2001-08-13 19:45:26 +00:00
2000-06-05 19:47:54 +00:00
switch ( ZEND_NUM_ARGS ( ) ) {
1999-04-22 02:48:28 +00:00
case 0 :
1999-09-04 13:03:09 +00:00
id = php_sybase_get_default_link ( INTERNAL_FUNCTION_PARAM_PASSTHRU ) ;
1999-04-22 02:48:28 +00:00
break ;
case 1 :
2003-01-15 03:01:17 +00:00
if ( zend_get_parameters_ex ( 1 , & sybase_link_index ) = = FAILURE ) {
1999-04-22 02:48:28 +00:00
RETURN_FALSE ;
}
1999-09-04 13:03:09 +00:00
id = - 1 ;
1999-04-22 02:48:28 +00:00
break ;
default :
WRONG_PARAM_COUNT ;
break ;
}
2001-08-13 19:45:26 +00:00
2003-01-15 13:55:34 +00:00
ZEND_FETCH_RESOURCE2 ( sybase_ptr , sybase_link * , sybase_link_index , id , " Sybase-Link " , le_link , le_plink ) ;
1999-09-04 13:03:09 +00:00
2001-08-14 01:07:42 +00:00
Z_LVAL_P ( return_value ) = sybase_ptr - > affected_rows ;
2001-09-25 21:58:48 +00:00
Z_TYPE_P ( return_value ) = IS_LONG ;
1999-04-22 02:48:28 +00:00
}
2000-10-05 02:40:53 +00:00
/* }}} */
1999-04-22 02:48:28 +00:00
1999-09-04 13:03:09 +00:00
PHP_MINFO_FUNCTION ( sybase )
1999-04-22 02:48:28 +00:00
{
2000-09-12 20:54:36 +00:00
char buf [ 32 ] ;
2001-08-13 19:45:26 +00:00
2000-04-06 21:07:44 +00:00
php_info_print_table_start ( ) ;
2001-06-26 21:00:13 +00:00
php_info_print_table_header ( 2 , " Sybase_CT Support " , " enabled " ) ;
2000-09-12 20:54:36 +00:00
sprintf ( buf , " %ld " , SybCtG ( num_persistent ) ) ;
php_info_print_table_row ( 2 , " Active Persistent Links " , buf ) ;
sprintf ( buf , " %ld " , SybCtG ( num_links ) ) ;
php_info_print_table_row ( 2 , " Active Links " , buf ) ;
2002-11-05 08:29:57 +00:00
sprintf ( buf , " %ld " , SybCtG ( min_server_severity ) ) ;
php_info_print_table_row ( 2 , " Min server severity " , buf ) ;
sprintf ( buf , " %ld " , SybCtG ( min_client_severity ) ) ;
php_info_print_table_row ( 2 , " Min client severity " , buf ) ;
2000-09-12 20:54:36 +00:00
php_info_print_table_row ( 2 , " Application Name " , SybCtG ( appname ) ) ;
2002-11-05 08:29:57 +00:00
sprintf ( buf , " %ld " , SybCtG ( deadlock_retry_count ) ) ;
php_info_print_table_row ( 2 , " Deadlock retry count " , buf ) ;
2000-04-06 21:07:44 +00:00
php_info_print_table_end ( ) ;
2000-09-12 20:54:36 +00:00
DISPLAY_INI_ENTRIES ( ) ;
1999-04-22 02:48:28 +00:00
}
2000-10-05 02:40:53 +00:00
/* {{{ proto void sybase_min_client_severity(int severity)
Sets minimum client severity */
1999-09-04 13:03:09 +00:00
PHP_FUNCTION ( sybase_min_client_severity )
1999-04-22 02:48:28 +00:00
{
2003-01-15 03:01:17 +00:00
zval * * severity ;
2001-08-13 19:45:26 +00:00
2003-01-15 03:01:17 +00:00
if ( ZEND_NUM_ARGS ( ) ! = 1 | | zend_get_parameters_ex ( 1 , & severity ) = = FAILURE ) {
1999-04-22 02:48:28 +00:00
WRONG_PARAM_COUNT ;
}
2003-01-15 03:01:17 +00:00
convert_to_long_ex ( severity ) ;
SybCtG ( min_client_severity ) = Z_LVAL_PP ( severity ) ;
1999-04-22 02:48:28 +00:00
}
2000-10-05 02:40:53 +00:00
/* }}} */
1999-04-22 02:48:28 +00:00
2000-10-05 02:40:53 +00:00
/* {{{ proto void sybase_min_server_severity(int severity)
2001-01-26 21:41:38 +00:00
Sets minimum server severity */
1999-09-04 13:03:09 +00:00
PHP_FUNCTION ( sybase_min_server_severity )
1999-04-22 02:48:28 +00:00
{
2003-01-15 03:01:17 +00:00
zval * * severity ;
2001-08-13 19:45:26 +00:00
2003-01-15 03:01:17 +00:00
if ( ZEND_NUM_ARGS ( ) ! = 1 | | zend_get_parameters_ex ( 1 , & severity ) = = FAILURE ) {
1999-04-22 02:48:28 +00:00
WRONG_PARAM_COUNT ;
}
2003-01-15 03:01:17 +00:00
convert_to_long_ex ( severity ) ;
SybCtG ( min_server_severity ) = Z_LVAL_PP ( severity ) ;
1999-04-22 02:48:28 +00:00
}
2000-10-05 02:40:53 +00:00
/* }}} */
1999-04-22 02:48:28 +00:00
2002-11-05 08:29:57 +00:00
/* {{{ proto void sybase_deadlock_retry_count(int retry_count)
Sets deadlock retry count */
PHP_FUNCTION ( sybase_deadlock_retry_count )
{
2003-01-15 03:01:17 +00:00
zval * * retry_count ;
2002-11-05 08:29:57 +00:00
2003-01-15 03:01:17 +00:00
if ( ZEND_NUM_ARGS ( ) ! = 1 | | zend_get_parameters_ex ( 1 , & retry_count ) = = FAILURE ) {
2002-11-05 08:29:57 +00:00
WRONG_PARAM_COUNT ;
}
2003-01-15 03:01:17 +00:00
convert_to_long_ex ( retry_count ) ;
SybCtG ( deadlock_retry_count ) = Z_LVAL_PP ( retry_count ) ;
2002-11-05 08:29:57 +00:00
}
/* }}} */
2004-01-25 20:03:10 +00:00
/* {{{ proto bool sybase_set_message_handler(mixed error_func [, resource connection])
2002-11-05 08:29:57 +00:00
Set the error handler , to be called when a server message is raised .
If error_func is NULL the handler will be deleted */
PHP_FUNCTION ( sybase_set_message_handler )
{
2004-01-25 20:03:10 +00:00
zval * * callback , * * param , * * sybase_link_index = NULL ;
2002-11-05 08:29:57 +00:00
char * name ;
2004-01-25 20:03:10 +00:00
sybase_link * sybase_ptr ;
2002-11-05 08:29:57 +00:00
2004-01-25 20:03:10 +00:00
switch ( ZEND_NUM_ARGS ( ) ) {
case 1 : /* Default message handler */
if ( zend_get_parameters_ex ( 1 , & param ) = = FAILURE ) {
RETURN_FALSE ;
}
callback = & SybCtG ( callback_name ) ;
break ;
2002-11-05 08:29:57 +00:00
2004-01-25 20:03:10 +00:00
case 2 : /* Connection-based message handler */
if ( zend_get_parameters_ex ( 2 , & param , & sybase_link_index ) = = FAILURE ) {
RETURN_FALSE ;
}
ZEND_FETCH_RESOURCE2 ( sybase_ptr , sybase_link * , sybase_link_index , - 1 , " Sybase-Link " , le_link , le_plink ) ;
callback = & sybase_ptr - > callback_name ;
break ;
2002-11-05 08:29:57 +00:00
2004-01-25 20:03:10 +00:00
default :
WRONG_PARAM_COUNT ;
2002-11-05 08:29:57 +00:00
}
2004-01-25 20:03:10 +00:00
/* Clean out old callback */
if ( * callback ) {
zval_ptr_dtor ( callback ) ;
* callback = NULL ;
2002-11-05 08:29:57 +00:00
}
2004-01-25 20:03:10 +00:00
switch ( Z_TYPE_PP ( param ) ) {
case IS_NULL :
/* Return TRUE to indicate we deleted the message handler */
RETURN_TRUE ;
break ;
case IS_ARRAY :
case IS_STRING :
/* Either "function", array("class", "function") or array($object, "function") */
if ( ! zend_is_callable ( * param , 0 , & name ) ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " First argumented is expected to be a valid callback, '%s' was given " , name ) ;
efree ( name ) ;
RETURN_FALSE ;
}
efree ( name ) ;
break ;
default :
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " First argumented is expected to be either NULL, an array or string, %s given " , zend_zval_type_name ( * param ) ) ;
RETURN_FALSE ;
2002-11-05 08:29:57 +00:00
}
2004-01-25 20:03:10 +00:00
ALLOC_ZVAL ( * callback ) ;
* * callback = * * param ;
INIT_PZVAL ( * callback ) ;
zval_copy_ctor ( * callback ) ;
2002-11-05 08:29:57 +00:00
RETURN_TRUE ;
}
/* }}} */
1999-04-22 02:48:28 +00:00
# endif
1999-10-12 15:00:10 +00:00
/*
* Local variables :
* tab - width : 4
* c - basic - offset : 4
* End :
*/