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
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2007-12-31 07:17:19 +00:00
| Copyright ( c ) 1997 - 2008 The PHP Group |
1999-04-22 02:48:28 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2006-01-01 12:51:34 +00:00
| This source file is subject to version 3.01 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 : |
2006-01-01 12:51:34 +00:00
| http : //www.php.net/license/3_01.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
2006-06-15 18:33:09 +00:00
ZEND_DECLARE_MODULE_GLOBALS ( sybase )
static PHP_GINIT_FUNCTION ( sybase ) ;
static PHP_GSHUTDOWN_FUNCTION ( sybase ) ;
2008-07-01 17:24:10 +00:00
/* {{{ arginfo */
ZEND_BEGIN_ARG_INFO_EX ( arginfo_sybase_connect , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , host )
ZEND_ARG_INFO ( 0 , user )
ZEND_ARG_INFO ( 0 , password )
ZEND_ARG_INFO ( 0 , charset )
ZEND_ARG_INFO ( 0 , appname )
2008-11-10 10:59:44 +00:00
ZEND_ARG_INFO ( 0 , new )
2008-07-01 17:24:10 +00:00
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_sybase_pconnect , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , host )
ZEND_ARG_INFO ( 0 , user )
ZEND_ARG_INFO ( 0 , password )
ZEND_ARG_INFO ( 0 , charset )
ZEND_ARG_INFO ( 0 , appname )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_sybase_close , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , link_id )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_sybase_select_db , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , database )
ZEND_ARG_INFO ( 0 , link_id )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_sybase_query , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , query )
ZEND_ARG_INFO ( 0 , link_id )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_sybase_unbuffered_query , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , query )
ZEND_ARG_INFO ( 0 , link_id )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_sybase_free_result , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , result )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_sybase_get_last_message , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , d )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_sybase_num_rows , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , result )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_sybase_num_fields , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , result )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_sybase_fetch_row , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , result )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_sybase_fetch_object , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , result )
ZEND_ARG_INFO ( 0 , object )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_sybase_fetch_array , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , result )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_sybase_fetch_assoc , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , result )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_sybase_data_seek , 0 , 0 , 2 )
ZEND_ARG_INFO ( 0 , result )
ZEND_ARG_INFO ( 0 , offset )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_sybase_fetch_field , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , result )
ZEND_ARG_INFO ( 0 , offset )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_sybase_field_seek , 0 , 0 , 2 )
ZEND_ARG_INFO ( 0 , result )
ZEND_ARG_INFO ( 0 , offset )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_sybase_result , 0 , 0 , 3 )
ZEND_ARG_INFO ( 0 , result )
ZEND_ARG_INFO ( 0 , row )
ZEND_ARG_INFO ( 0 , field )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_sybase_affected_rows , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , link_id )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_sybase_min_client_severity , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , severity )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_sybase_min_server_severity , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , severity )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_sybase_deadlock_retry_count , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , retry_count )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_sybase_set_message_handler , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , error_func )
ZEND_ARG_INFO ( 0 , connection )
ZEND_END_ARG_INFO ( )
/* }}} */
2007-09-27 18:00:48 +00:00
const zend_function_entry sybase_functions [ ] = {
2008-07-01 17:24:10 +00:00
PHP_FE ( sybase_connect , arginfo_sybase_connect )
PHP_FE ( sybase_pconnect , arginfo_sybase_pconnect )
PHP_FE ( sybase_close , arginfo_sybase_close )
PHP_FE ( sybase_select_db , arginfo_sybase_select_db )
PHP_FE ( sybase_query , arginfo_sybase_query )
PHP_FE ( sybase_unbuffered_query , arginfo_sybase_unbuffered_query )
PHP_FE ( sybase_free_result , arginfo_sybase_free_result )
PHP_FE ( sybase_get_last_message , arginfo_sybase_get_last_message )
PHP_FE ( sybase_num_rows , arginfo_sybase_num_rows )
PHP_FE ( sybase_num_fields , arginfo_sybase_num_fields )
PHP_FE ( sybase_fetch_row , arginfo_sybase_fetch_row )
PHP_FE ( sybase_fetch_array , arginfo_sybase_fetch_array )
PHP_FE ( sybase_fetch_assoc , arginfo_sybase_fetch_assoc )
PHP_FE ( sybase_fetch_object , arginfo_sybase_fetch_object )
PHP_FE ( sybase_data_seek , arginfo_sybase_data_seek )
PHP_FE ( sybase_fetch_field , arginfo_sybase_fetch_field )
PHP_FE ( sybase_field_seek , arginfo_sybase_field_seek )
PHP_FE ( sybase_result , arginfo_sybase_result )
PHP_FE ( sybase_affected_rows , arginfo_sybase_affected_rows )
PHP_FE ( sybase_min_client_severity , arginfo_sybase_min_client_severity )
PHP_FE ( sybase_min_server_severity , arginfo_sybase_min_server_severity )
PHP_FE ( sybase_set_message_handler , arginfo_sybase_set_message_handler )
PHP_FE ( sybase_deadlock_retry_count , arginfo_sybase_deadlock_retry_count )
2004-01-25 20:03:10 +00:00
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 ,
2006-06-15 18:33:09 +00:00
" sybase_ct " ,
sybase_functions ,
PHP_MINIT ( sybase ) ,
PHP_MSHUTDOWN ( sybase ) ,
PHP_RINIT ( sybase ) ,
PHP_RSHUTDOWN ( sybase ) ,
PHP_MINFO ( sybase ) ,
NO_VERSION_YET ,
PHP_MODULE_GLOBALS ( sybase ) ,
PHP_GINIT ( sybase ) ,
PHP_GSHUTDOWN ( sybase ) ,
NULL ,
STANDARD_MODULE_PROPERTIES_EX
1999-04-22 02:48:28 +00:00
} ;
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
2005-12-05 23:38:04 +00:00
static int _clean_invalid_results ( zend_rsrc_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 ;
}
2007-04-10 15:50:34 +00:00
# define efree_n(x) { efree(x); x = NULL; }
# define efree_if(x) if (x) efree_n(x)
2008-11-08 13:22:14 +00:00
# ifdef PHP_SYBASE_DEBUG
# define FREE_SYBASE_RESULT(result) \
if ( result ) { \
fprintf ( stderr , " _free_sybase_result(%p) called from line #%d \n " , result , __LINE__ ) ; \
fflush ( stderr ) ; \
_free_sybase_result ( result ) ; \
result = NULL ; \
}
# else
# define FREE_SYBASE_RESULT(result) \
if ( result ) { \
_free_sybase_result ( result ) ; \
result = NULL ; \
}
# endif
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 ) ;
}
2007-04-10 15:56:31 +00:00
if ( result - > tmp_buffer ) {
for ( i = 0 ; i < result - > num_fields ; i + + ) {
efree ( result - > tmp_buffer [ i ] ) ;
}
efree ( result - > tmp_buffer ) ;
}
2007-04-10 15:50:34 +00:00
efree_if ( result - > lengths ) ;
efree_if ( result - > indicators ) ;
efree_if ( result - > datafmt ) ;
efree_if ( result - > numerics ) ;
efree_if ( result - > types ) ;
1999-04-22 02:48:28 +00:00
efree ( result ) ;
}
2004-07-29 19:32:46 +00:00
/* Forward declaration */
2006-07-25 09:20:32 +00:00
static int php_sybase_finish_results ( sybase_result * result TSRMLS_DC ) ;
2004-07-29 19:32:46 +00:00
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 ) ;
}
2006-07-25 09:20:32 +00:00
php_sybase_finish_results ( result TSRMLS_CC ) ;
2004-07-29 19:32:46 +00:00
}
2008-11-08 13:22:14 +00:00
FREE_SYBASE_RESULT ( result ) ;
2000-10-20 18:25:16 +00:00
}
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 ;
}
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 ) ) {
2008-07-01 17:24:10 +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 ;
2008-06-24 16:33:17 +00:00
zval * msgnumber , * severity , * state , * line , * text , * retval = NULL ;
zval * * args [ 5 ] ;
2004-01-25 20:03:10 +00:00
2008-06-24 16:33:17 +00:00
/* Border case - empty fcall */
if ( NULL = = callback_name ) return 0 ;
2004-02-15 10:37:09 +00:00
2008-06-24 16:33:17 +00:00
/* Build arguments */
MAKE_STD_ZVAL ( msgnumber ) ;
ZVAL_LONG ( msgnumber , srvmsg - > msgnumber ) ;
args [ 0 ] = & msgnumber ;
2004-02-15 10:37:09 +00:00
2008-06-24 16:33:17 +00:00
MAKE_STD_ZVAL ( severity ) ;
ZVAL_LONG ( severity , srvmsg - > severity ) ;
args [ 1 ] = & severity ;
2004-02-15 10:37:09 +00:00
2008-06-24 16:33:17 +00:00
MAKE_STD_ZVAL ( state ) ;
ZVAL_LONG ( state , srvmsg - > state ) ;
args [ 2 ] = & state ;
2004-02-15 10:37:09 +00:00
2008-06-24 16:33:17 +00:00
MAKE_STD_ZVAL ( line ) ;
ZVAL_LONG ( line , srvmsg - > line ) ;
args [ 3 ] = & line ;
2004-02-15 10:37:09 +00:00
2008-06-24 16:33:17 +00:00
MAKE_STD_ZVAL ( text ) ;
ZVAL_STRING ( text , srvmsg - > text , 1 ) ;
args [ 4 ] = & text ;
2004-02-15 10:37:09 +00:00
2008-06-24 16:33:17 +00:00
if ( call_user_function_ex ( EG ( function_table ) , NULL , callback_name , & retval , 5 , args , 0 , NULL TSRMLS_CC ) = = FAILURE ) {
zval expr_copy ;
int use_copy ;
zend_make_printable_zval ( callback_name , & expr_copy , & use_copy ) ;
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: Cannot call the messagehandler %s " , Z_STRVAL ( expr_copy ) ) ;
zval_dtor ( & expr_copy ) ;
}
2004-02-15 10:37:09 +00:00
2008-06-24 16:33:17 +00:00
if ( retval ) {
handled = ( ( Z_TYPE_P ( retval ) ! = IS_BOOL ) | | ( Z_BVAL_P ( retval ) ! = 0 ) ) ;
zval_ptr_dtor ( & retval ) ;
} else {
handled = 0 ;
1999-04-22 02:48:28 +00:00
}
2004-01-25 20:03:10 +00:00
2008-06-24 16:33:17 +00:00
zval_ptr_dtor ( & msgnumber ) ;
zval_ptr_dtor ( & severity ) ;
zval_ptr_dtor ( & state ) ;
zval_ptr_dtor ( & line ) ;
zval_ptr_dtor ( & text ) ;
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 ) {
2007-04-10 15:50:34 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: Server message: %s (severity %ld, procedure %s) " ,
srvmsg - > text , ( long ) 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 ( )
2006-06-15 18:33:09 +00:00
static PHP_GINIT_FUNCTION ( sybase )
1999-04-22 02:48:28 +00:00
{
2004-01-25 20:03:10 +00:00
long opt ;
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
}
}
2006-07-25 09:19:38 +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
2004-01-25 20:03:10 +00:00
* requested . The default is CS_NO_LIMIT .
2006-07-25 09:19:38 +00:00
*
2004-01-25 20:03:10 +00:00
* 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
2006-06-15 18:33:09 +00:00
static PHP_GSHUTDOWN_FUNCTION ( sybase )
2000-09-12 20:54:36 +00:00
{
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 )
{
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 ;
}
2006-07-23 23:50:43 +00:00
static int php_sybase_do_connect_internal ( sybase_link * sybase , char * host , char * user , char * passwd , char * charset , char * appname TSRMLS_DC )
1999-04-22 02:48:28 +00:00
{
2001-06-26 20:56:03 +00:00
CS_LOCALE * tmp_locale ;
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 ) ;
2006-07-25 09:19:38 +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 ) {
2007-04-10 15:56:31 +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 ) {
2007-04-10 15:56:31 +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 ) {
2007-04-10 15:56:31 +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 ) {
2007-04-10 15:56:31 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: Unable to update connection properties " ) ;
2001-06-26 20:56:03 +00:00
}
}
}
}
}
2006-07-25 09:19:38 +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 ) {
2007-04-10 15:56:31 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: Unable to update connection packetsize " ) ;
2004-08-21 17:54:11 +00:00
}
}
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
2006-07-25 09:19:38 +00:00
* and not per connection , but we will update the context here to
2004-01-25 20:03:10 +00:00
* allow for code such as the following :
2006-07-25 09:19:38 +00:00
*
2004-01-25 20:03:10 +00:00
* ini_set ( ' sybct . login_timeout ' , $ timeout ) ;
* sybase_connect ( . . . )
2006-07-25 09:19:38 +00:00
*
* Note that preceding calls to sybase_connect ( ) will now use the
2004-01-25 20:03:10 +00:00
* updated value and not the default one !
2006-07-25 09:19:38 +00:00
*
2004-01-25 20:03:10 +00:00
* 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 ;
2008-11-10 10:59:44 +00:00
int hashed_details_length , len ;
zend_bool new = 0 ;
1999-09-04 13:03:09 +00:00
sybase_link * sybase_ptr ;
1999-04-22 02:48:28 +00:00
2008-06-24 16:33:17 +00:00
host = user = passwd = charset = appname = NULL ;
2008-11-10 10:59:44 +00:00
if ( persistent ) {
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " |s!s!s!s!s! " , & host , & len , & user , & len , & passwd , & len , & charset , & len , & appname , & len ) = = FAILURE ) {
return ;
}
} else {
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " |s!s!s!s!s!b " , & host , & len , & user , & len , & passwd , & len , & charset , & len , & appname , & len , & new ) = = FAILURE ) {
return ;
}
1999-04-22 02:48:28 +00:00
}
2008-06-22 10:11:14 +00:00
hashed_details_length = spprintf (
& hashed_details ,
0 ,
" sybase_%s_%s_%s_%s_%s " ,
host ? host : " " ,
user ? user : " " ,
passwd ? passwd : " " ,
charset ? charset : " " ,
appname ? appname : " "
) ;
1999-04-22 02:48:28 +00:00
2000-09-12 20:54:36 +00:00
if ( ! SybCtG ( allow_persistent ) ) {
1999-04-22 02:48:28 +00:00
persistent = 0 ;
}
if ( persistent ) {
2005-12-05 23:38:04 +00:00
zend_rsrc_list_entry * le ;
1999-04-22 02:48:28 +00:00
/* 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 */
2005-12-05 23:38:04 +00:00
zend_rsrc_list_entry new_le ;
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 ;
}
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 ) ) ;
2006-07-23 23:50:43 +00:00
if ( ! php_sybase_do_connect_internal ( sybase_ptr , host , user , passwd , charset , appname TSRMLS_CC ) ) {
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 ;
2005-12-05 23:38:04 +00:00
if ( zend_hash_update ( & EG ( persistent_list ) , hashed_details , hashed_details_length + 1 , ( void * ) & new_le , sizeof ( zend_rsrc_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 ) ) ;
2006-07-23 23:50:43 +00:00
if ( ! php_sybase_do_connect_internal ( sybase_ptr , host , user , passwd , charset , appname TSRMLS_CC ) ) {
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 */
2005-12-05 23:38:04 +00:00
zend_rsrc_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 .
*/
2008-11-10 10:59:44 +00:00
if ( ! new & & 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 ) ) ;
2006-07-23 23:50:43 +00:00
if ( ! php_sybase_do_connect_internal ( sybase_ptr , host , user , passwd , charset , appname TSRMLS_CC ) ) {
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 ;
2005-12-05 23:38:04 +00:00
if ( zend_hash_update ( & EG ( regular_list ) , hashed_details , hashed_details_length + 1 , ( void * ) & new_index_ptr , sizeof ( zend_rsrc_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
}
2008-11-10 10:59:44 +00:00
/* {{{ proto int sybase_connect([string host [, string user [, string password [, string charset [, string appname [, bool new]]]]]])
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
/* }}} */
2008-06-24 16:33:17 +00:00
inline static int php_sybase_connection_id ( zval * sybase_link_index , int * id TSRMLS_DC )
{
if ( NULL = = sybase_link_index ) {
if ( - 1 = = SybCtG ( default_link ) ) {
return FAILURE ;
}
* id = SybCtG ( default_link ) ;
} else {
* id = - 1 ; /* explicit resource number */
}
return SUCCESS ;
}
1999-04-22 02:48:28 +00:00
2008-06-24 16:33:17 +00:00
/* {{{ proto bool sybase_close([resource 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
{
2008-06-24 16:33:17 +00:00
zval * sybase_link_index = NULL ;
1999-09-04 13:03:09 +00:00
sybase_link * sybase_ptr ;
2008-06-24 16:33:17 +00:00
int id ;
2001-08-13 19:45:26 +00:00
2008-06-24 16:33:17 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " |r " , & sybase_link_index ) = = FAILURE ) {
return ;
1999-04-22 02:48:28 +00:00
}
2001-08-13 19:45:26 +00:00
2008-06-24 16:33:17 +00:00
if ( php_sybase_connection_id ( sybase_link_index , & id TSRMLS_CC ) = = FAILURE ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: No connection to close " ) ;
RETURN_FALSE ;
2000-11-03 02:46:49 +00:00
}
2008-06-24 16:33:17 +00:00
ZEND_FETCH_RESOURCE2 ( sybase_ptr , sybase_link * , & sybase_link_index , id , " Sybase-Link " , le_link , le_plink ) ;
2008-11-09 11:39:14 +00:00
if ( id = = - 1 ) {
zend_list_delete ( Z_RESVAL_P ( sybase_link_index ) ) ;
}
if ( id ! = - 1 | | ( sybase_link_index & & Z_RESVAL_P ( sybase_link_index ) = = SybCtG ( default_link ) ) ) {
zend_list_delete ( SybCtG ( default_link ) ) ;
2000-11-03 02:46:49 +00:00
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 ;
}
}
2008-06-24 16:33:17 +00:00
/* {{{ proto bool sybase_select_db(string database [, resource 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
{
2008-06-24 16:33:17 +00:00
zval * sybase_link_index = NULL ;
char * db , * cmdbuf ;
int id , len ;
sybase_link * sybase_ptr ;
2001-08-13 19:45:26 +00:00
2008-06-24 16:33:17 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " s|r " , & db , & len , & sybase_link_index ) = = FAILURE ) {
return ;
1999-04-22 02:48:28 +00:00
}
2001-08-13 19:45:26 +00:00
2008-06-24 16:33:17 +00:00
if ( php_sybase_connection_id ( sybase_link_index , & id TSRMLS_CC ) = = FAILURE ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: No connection " ) ;
RETURN_FALSE ;
}
2001-08-13 19:45:26 +00:00
2008-06-24 16:33:17 +00:00
ZEND_FETCH_RESOURCE2 ( sybase_ptr , sybase_link * , & sybase_link_index , id , " Sybase-Link " , le_link , le_plink ) ;
1999-04-22 02:48:28 +00:00
2008-06-24 16:33:17 +00:00
spprintf ( & cmdbuf , 4 + len + 1 , " use %s " , db ) ;
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
/* }}} */
2006-07-25 09:19:38 +00:00
static int php_sybase_finish_results ( sybase_result * result TSRMLS_DC )
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 ;
2006-07-25 09:19:38 +00:00
2007-04-10 15:50:34 +00:00
efree_n ( result - > datafmt ) ;
efree_n ( result - > lengths ) ;
efree_n ( result - > indicators ) ;
efree_n ( result - > numerics ) ;
efree_n ( result - > types ) ;
2002-11-05 08:29:57 +00:00
for ( i = 0 ; i < result - > num_fields ; i + + ) {
efree ( result - > tmp_buffer [ i ] ) ;
}
2007-04-10 15:50:34 +00:00
efree_n ( result - > tmp_buffer ) ;
2002-11-05 08:29:57 +00:00
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 ;
2006-07-25 09:19:38 +00:00
2002-11-05 08:29:57 +00:00
case CS_CANCELED :
default :
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 ; \
2007-04-10 15:50:34 +00:00
Z_DVAL ( result ) = zend_strtod ( buf , NULL ) ; \
2004-07-29 19:32:46 +00:00
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 ( ) ;
2006-07-25 09:19:38 +00:00
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
}
2006-07-25 09:19:38 +00:00
2002-11-05 08:29:57 +00:00
if ( numrows ! = - 1 ) numrows + = result - > num_rows ;
2008-11-08 12:05:46 +00:00
while ( ( retcode = ct_fetch ( result - > sybase_ptr - > cmd , CS_UNUSED , CS_UNUSED , CS_UNUSED , NULL ) ) = = CS_SUCCEED | | retcode = = CS_ROW_FAIL ) {
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 ) {
2007-03-06 02:10:25 +00:00
result - > data = ( zval * * ) safe_erealloc ( result - > data , SYBASE_ROWS_BLOCK * ( + + result - > blocks_initialized ) , sizeof ( zval * ) , 0 ) ;
2002-11-05 08:29:57 +00:00
}
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
}
2006-07-25 09:19:38 +00:00
2004-07-29 19:32:46 +00:00
case 2 : {
/* This indicates a float */
2006-07-25 09:19:38 +00:00
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 ) {
2006-07-25 09:19:38 +00:00
2004-07-29 19:32:46 +00:00
/* An overflow occurred, so try to fit it into a double */
2006-07-25 09:19:38 +00:00
RETURN_DOUBLE_VAL ( result - > data [ i ] [ j ] , result - > tmp_buffer [ j ] , result - > lengths [ j ] ) ;
2004-07-29 19:32:46 +00:00
break ;
}
Z_TYPE ( result - > data [ i ] [ j ] ) = IS_LONG ;
break ;
}
2006-07-25 09:19:38 +00:00
2004-07-29 19:32:46 +00:00
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 ;
2008-06-24 16:33:17 +00:00
}
2002-11-05 08:29:57 +00:00
}
}
}
if ( numrows ! = - 1 & & result - > num_rows > = numrows ) break ;
}
2007-04-10 15:50:34 +00:00
if ( retcode = = CS_ROW_FAIL ) {
2007-04-10 15:56:31 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: Error reading row %d " , result - > num_rows ) ;
2007-04-10 15:50:34 +00:00
return retcode ;
}
2002-11-05 08:29:57 +00:00
result - > last_retcode = retcode ;
switch ( retcode ) {
case CS_END_DATA :
2006-07-23 23:50:43 +00:00
retcode = php_sybase_finish_results ( result TSRMLS_CC ) ;
2002-11-05 08:29:57 +00:00
break ;
2006-07-25 09:19:38 +00:00
2002-11-05 08:29:57 +00:00
case CS_ROW_FAIL :
case CS_SUCCEED :
break ;
2006-07-25 09:19:38 +00:00
2002-11-05 08:29:57 +00:00
default :
2008-11-08 13:22:14 +00:00
FREE_SYBASE_RESULT ( result ) ;
2002-11-05 08:29:57 +00:00
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 ;
}
2006-07-25 09:19:38 +00:00
2002-11-05 08:29:57 +00:00
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 ;
}
2006-07-25 09:19:38 +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 ) ;
2006-07-25 09:19:38 +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
}
2006-07-25 09:19:38 +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
{
2008-06-24 16:33:17 +00:00
zval * sybase_link_index = NULL ;
zend_bool store = 1 ;
char * query ;
int len , id , deadlock_count ;
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
2008-06-24 16:33:17 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " s|rb " , & query , & len , & sybase_link_index , & store ) = = FAILURE ) {
return ;
1999-04-22 02:48:28 +00:00
}
2001-08-13 19:45:26 +00:00
2008-06-24 16:33:17 +00:00
if ( ! store & & ! buffered ) {
2008-11-08 12:24:52 +00:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Sybase: Cannot use non-storing mode with buffered queries " ) ;
2008-06-24 16:33:17 +00:00
store = 1 ;
}
2001-08-13 19:45:26 +00:00
2008-06-24 16:33:17 +00:00
if ( php_sybase_connection_id ( sybase_link_index , & id TSRMLS_CC ) = = FAILURE ) {
2008-11-08 12:24:52 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: No connection " ) ;
2008-06-24 16:33:17 +00:00
RETURN_FALSE ;
}
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
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 ;
}
2006-07-25 09:19:38 +00:00
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 ;
2006-07-25 09:19:38 +00:00
2008-11-08 12:24:52 +00:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Sybase: 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 ) ;
}
2006-07-25 09:19:38 +00:00
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 ) ;
2006-07-25 09:19:38 +00:00
2002-11-12 13:13:12 +00:00
if ( result ) {
2006-07-23 23:50:43 +00:00
php_sybase_finish_results ( result TSRMLS_CC ) ;
2002-11-12 13:13:12 +00:00
}
2006-07-25 09:19:38 +00:00
2002-12-07 19:49:31 +00:00
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 .
*/
2008-06-24 16:33:17 +00:00
if ( ct_command ( sybase_ptr - > cmd , CS_LANG_CMD , 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 ;
}
2006-07-25 09:19:38 +00:00
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 ;
2006-07-25 09:19:38 +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
2006-07-25 09:19:38 +00:00
/* Retry deadlocks up until deadlock_retry_count times */
2002-11-05 08:29:57 +00:00
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 ) ) ;
2008-11-08 13:22:14 +00:00
FREE_SYBASE_RESULT ( result ) ;
2002-11-05 08:29:57 +00:00
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 .
*/
2008-11-08 13:22:14 +00:00
FREE_SYBASE_RESULT ( result ) ;
1999-04-22 02:48:28 +00:00
}
if ( status = = Q_SUCCESS ) {
RETURN_TRUE ;
}
if ( status = = Q_FAILURE ) {
2008-11-08 13:22:14 +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
}
2008-06-24 16:33:17 +00:00
/* {{{ proto int sybase_query(string query [, resource link_id])
2002-11-05 08:29:57 +00:00
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
2008-06-24 16:33:17 +00:00
/* {{{ proto int sybase_unbuffered_query(string query [, resource link_id])
2002-11-05 08:29:57 +00:00
Send Sybase query */
PHP_FUNCTION ( sybase_unbuffered_query )
{
php_sybase_query ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 1 ) ;
}
2008-06-24 16:33:17 +00:00
/* {{{ proto bool sybase_free_result(resource 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
{
2008-06-24 16:33:17 +00:00
zval * sybase_result_index = NULL ;
1999-09-04 13:03:09 +00:00
sybase_result * result ;
2001-08-13 19:45:26 +00:00
2008-06-24 16:33:17 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " r " , & sybase_result_index ) = = FAILURE ) {
return ;
1999-04-22 02:48:28 +00:00
}
2008-06-24 16:33:17 +00:00
ZEND_FETCH_RESOURCE ( result , sybase_result * , & sybase_result_index , - 1 , " Sybase result " , le_result ) ;
2006-07-25 09:19:38 +00:00
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 ) ;
2006-07-23 23:50:43 +00:00
php_sybase_finish_results ( result TSRMLS_CC ) ;
2002-11-05 08:29:57 +00:00
}
2006-07-25 09:19:38 +00:00
2008-06-24 16:33:17 +00:00
zend_list_delete ( Z_LVAL_P ( 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
}
/* }}} */
2008-06-24 16:33:17 +00:00
/* {{{ proto int sybase_num_rows(resource 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
{
2008-06-24 16:33:17 +00:00
zval * sybase_result_index = NULL ;
1999-09-04 13:03:09 +00:00
sybase_result * result ;
2001-08-13 19:45:26 +00:00
2008-06-24 16:33:17 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " r " , & sybase_result_index ) = = FAILURE ) {
return ;
1999-04-22 02:48:28 +00:00
}
2008-06-24 16:33: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
2008-06-24 16:33:17 +00:00
/* {{{ proto int sybase_num_fields(resource 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
{
2008-06-24 16:33:17 +00:00
zval * sybase_result_index = NULL ;
1999-09-04 13:03:09 +00:00
sybase_result * result ;
2001-08-13 19:45:26 +00:00
2008-06-24 16:33:17 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " r " , & sybase_result_index ) = = FAILURE ) {
return ;
1999-04-22 02:48:28 +00:00
}
2008-06-24 16:33: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
2008-06-24 16:33:17 +00:00
/* {{{ proto array sybase_fetch_row(resource 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
{
2008-06-24 16:33:17 +00:00
zval * sybase_result_index = NULL ;
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
2008-06-24 16:33:17 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " r " , & sybase_result_index ) = = FAILURE ) {
return ;
1999-04-22 02:48:28 +00:00
}
2008-06-24 16:33: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 ) ;
}
2006-07-25 09:19:38 +00:00
2002-11-05 08:29:57 +00:00
/* 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
{
2008-06-24 16:33:17 +00:00
zval * sybase_result_index = NULL ;
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
2008-06-24 16:33:17 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " r " , & sybase_result_index ) = = FAILURE ) {
return ;
1999-04-22 02:48:28 +00:00
}
2008-06-24 16:33: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 ) ;
2006-07-25 09:19:38 +00:00
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 ) ;
2007-10-23 15:21:20 +00:00
Z_ADDREF_P ( tmp ) ;
1999-04-22 02:48:28 +00:00
}
2006-07-25 09:19:38 +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 + + ;
}
2008-06-24 16:33:17 +00:00
/* {{{ proto object sybase_fetch_object(resource 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
{
2008-06-24 16:33:17 +00:00
zval * object = NULL ;
zval * sybase_result_index = NULL ;
zend_class_entry * ce = NULL ;
sybase_result * result ;
2006-07-25 09:19:38 +00:00
2002-11-12 13:13:12 +00:00
/* Was a second parameter given? */
2008-06-24 16:33:17 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " r|z " , & sybase_result_index , & object ) = = FAILURE ) {
return ;
}
ZEND_FETCH_RESOURCE ( result , sybase_result * , & sybase_result_index , - 1 , " Sybase result " , le_result ) ;
ce = ZEND_STANDARD_CLASS_DEF_PTR ;
if ( NULL ! = object ) {
switch ( Z_TYPE_P ( object ) ) {
case IS_OBJECT : {
ce = Z_OBJCE_P ( object ) ;
2002-11-12 13:13:12 +00:00
break ;
2008-06-24 16:33:17 +00:00
}
case IS_NULL : {
/* Use default (ZEND_STANDARD_CLASS_DEF_PTR) */
2004-07-29 19:32:46 +00:00
break ;
2008-06-24 16:33:17 +00:00
}
2004-07-29 19:32:46 +00:00
default : {
zend_class_entry * * pce = NULL ;
2008-06-24 16:33:17 +00:00
convert_to_string ( object ) ;
2002-11-12 13:13:12 +00:00
2008-06-24 16:33:17 +00:00
if ( zend_lookup_class ( Z_STRVAL_P ( object ) , Z_STRLEN_P ( object ) , & pce TSRMLS_CC ) = = FAILURE ) {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Sybase: Class %s has not been declared " , Z_STRVAL_P ( object ) ) ;
/* Use default (ZEND_STANDARD_CLASS_DEF_PTR) */
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
}
}
2008-06-24 16:33:17 +00:00
/* Reset no. of arguments to 1 so that we can use INTERNAL_FUNCTION_PARAM_PASSTHRU */
ht = 1 ;
2002-11-05 08:29:57 +00:00
php_sybase_fetch_hash ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 0 ) ;
2008-06-24 16:33:17 +00:00
if ( Z_TYPE_P ( return_value ) = = IS_ARRAY ) {
object_and_properties_init ( return_value , ce , 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
2008-06-24 16:33:17 +00:00
/* {{{ proto array sybase_fetch_array(resource 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 ) ;
}
/* }}} */
2008-06-24 16:33:17 +00:00
/* {{{ proto array sybase_fetch_assoc(resource result)
2002-11-05 08:29:57 +00:00
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
/* }}} */
2008-06-24 16:33:17 +00:00
/* {{{ proto bool sybase_data_seek(resource 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
{
2008-06-24 16:33:17 +00:00
zval * sybase_result_index = NULL ;
long offset ;
1999-09-04 13:03:09 +00:00
sybase_result * result ;
1999-04-22 02:48:28 +00:00
2008-06-24 16:33:17 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " rl " , & sybase_result_index , & offset ) = = FAILURE ) {
return ;
1999-04-22 02:48:28 +00:00
}
2008-06-24 16:33: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
/* Unbuffered ? */
2008-06-24 16:33:17 +00:00
if ( result - > last_retcode ! = CS_END_DATA & & result - > last_retcode ! = CS_END_RESULTS & & offset > = result - > num_rows ) {
php_sybase_fetch_result_row ( result , offset + 1 ) ;
2002-11-05 08:29:57 +00:00
}
2006-07-25 09:19:38 +00:00
2008-06-24 16:33:17 +00:00
if ( offset < 0 | | offset > = result - > num_rows ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: Bad row offset %ld, must be betweem 0 and %d " , offset , result - > num_rows - 1 ) ;
1999-04-22 02:48:28 +00:00
RETURN_FALSE ;
}
2001-08-13 19:45:26 +00:00
2008-06-24 16:33:17 +00:00
result - > cur_row = 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 ;
}
}
2008-06-24 16:33:17 +00:00
/* {{{ proto object sybase_fetch_field(resource 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
{
2008-06-24 16:33:17 +00:00
zval * sybase_result_index = NULL ;
long field_offset = - 1 ;
1999-09-04 13:03:09 +00:00
sybase_result * result ;
1999-04-22 02:48:28 +00:00
2008-06-24 16:33:17 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " r|l " , & sybase_result_index , & field_offset ) = = FAILURE ) {
return ;
1999-04-22 02:48:28 +00:00
}
2008-06-24 16:33: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
2008-06-24 16:33:17 +00:00
if ( field_offset = = - 1 ) {
1999-04-22 02:48:28 +00:00
field_offset = result - > cur_field ;
result - > cur_field + + ;
}
2001-08-13 19:45:26 +00:00
2008-06-24 16:33:17 +00:00
if ( field_offset < 0 | | field_offset > = result - > num_fields ) {
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
2008-06-24 16:33:17 +00:00
/* {{{ proto bool sybase_field_seek(resource 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
{
2008-06-24 16:33:17 +00:00
zval * sybase_result_index = NULL ;
long field_offset ;
1999-09-04 13:03:09 +00:00
sybase_result * result ;
1999-04-22 02:48:28 +00:00
2008-06-24 16:33:17 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " rl " , & sybase_result_index , & field_offset ) = = FAILURE ) {
return ;
1999-04-22 02:48:28 +00:00
}
2008-06-24 16:33: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
2008-06-24 16:33:17 +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
2008-06-24 16:33:17 +00:00
/* {{{ proto string sybase_result(resource 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
{
2008-06-24 16:33:17 +00:00
zval * field ;
zval * sybase_result_index = NULL ;
long row ;
int field_offset = 0 ;
1999-09-04 13:03:09 +00:00
sybase_result * result ;
1999-04-22 02:48:28 +00:00
2008-06-24 16:33:17 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " rlz " , & sybase_result_index , & row , & field ) = = FAILURE ) {
return ;
1999-04-22 02:48:28 +00:00
}
2008-06-24 16:33:17 +00:00
ZEND_FETCH_RESOURCE ( result , sybase_result * , & sybase_result_index , - 1 , " Sybase result " , le_result ) ;
2006-07-25 09:19:38 +00:00
2002-11-12 13:13:12 +00:00
/* Unbuffered ? */
2008-06-24 16:33:17 +00:00
if ( result - > last_retcode ! = CS_END_DATA & & result - > last_retcode ! = CS_END_RESULTS & & row > = result - > num_rows ) {
php_sybase_fetch_result_row ( result , row ) ;
2002-11-12 13:13:12 +00:00
}
2002-11-05 08:29:57 +00:00
2008-06-24 16:33:17 +00:00
if ( row < 0 | | row > = result - > num_rows ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: Bad row offset (%ld) " , row ) ;
1999-04-22 02:48:28 +00:00
RETURN_FALSE ;
}
2008-06-24 16:33:17 +00:00
switch ( Z_TYPE_P ( field ) ) {
1999-04-22 02:48:28 +00:00
case IS_STRING : {
int i ;
2008-06-24 16:33:17 +00:00
for ( i = 0 ; i < result - > num_fields ; i + + ) {
if ( strcasecmp ( result - > fields [ i ] . name , Z_STRVAL_P ( field ) ) = = 0 ) {
1999-04-22 02:48:28 +00:00
field_offset = i ;
break ;
}
}
2008-06-24 16:33:17 +00:00
if ( i > = result - > num_fields ) { /* no match found */
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: %s field not found in result " , Z_STRVAL_P ( field ) ) ;
1999-04-22 02:48:28 +00:00
RETURN_FALSE ;
}
break ;
}
default :
2008-06-24 16:33:17 +00:00
convert_to_long ( field ) ;
field_offset = Z_LVAL_P ( field ) ;
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 ;
}
2008-06-24 16:33:17 +00:00
* return_value = result - > data [ 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
2008-06-24 16:33:17 +00:00
/* {{{ proto int sybase_affected_rows([resource 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
{
2008-06-24 16:33:17 +00:00
zval * sybase_link_index = NULL ;
1999-09-04 13:03:09 +00:00
sybase_link * sybase_ptr ;
int id ;
2001-08-13 19:45:26 +00:00
2008-06-24 16:33:17 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " |r " , & sybase_link_index ) = = FAILURE ) {
return ;
}
if ( php_sybase_connection_id ( sybase_link_index , & id TSRMLS_CC ) = = FAILURE ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Sybase: No connection " ) ;
RETURN_FALSE ;
1999-04-22 02:48:28 +00:00
}
2001-08-13 19:45:26 +00:00
2008-06-24 16:33:17 +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 " ) ;
2007-02-24 02:17:47 +00:00
snprintf ( buf , sizeof ( buf ) , " %ld " , SybCtG ( num_persistent ) ) ;
2000-09-12 20:54:36 +00:00
php_info_print_table_row ( 2 , " Active Persistent Links " , buf ) ;
2007-02-24 02:17:47 +00:00
snprintf ( buf , sizeof ( buf ) , " %ld " , SybCtG ( num_links ) ) ;
2000-09-12 20:54:36 +00:00
php_info_print_table_row ( 2 , " Active Links " , buf ) ;
2007-02-24 02:17:47 +00:00
snprintf ( buf , sizeof ( buf ) , " %ld " , SybCtG ( min_server_severity ) ) ;
2002-11-05 08:29:57 +00:00
php_info_print_table_row ( 2 , " Min server severity " , buf ) ;
2007-02-24 02:17:47 +00:00
snprintf ( buf , sizeof ( buf ) , " %ld " , SybCtG ( min_client_severity ) ) ;
2006-07-25 09:19:38 +00:00
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 ) ) ;
2007-02-24 02:17:47 +00:00
snprintf ( buf , sizeof ( buf ) , " %ld " , SybCtG ( deadlock_retry_count ) ) ;
2002-11-05 08:29:57 +00:00
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
{
2008-06-24 16:33:17 +00:00
long severity ;
2001-08-13 19:45:26 +00:00
2008-06-24 16:33:17 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " l " , & severity ) = = FAILURE ) {
return ;
1999-04-22 02:48:28 +00:00
}
2008-06-24 16:33:17 +00:00
SybCtG ( min_client_severity ) = 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
{
2008-06-24 16:33:17 +00:00
long severity ;
2001-08-13 19:45:26 +00:00
2008-06-24 16:33:17 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " l " , & severity ) = = FAILURE ) {
return ;
1999-04-22 02:48:28 +00:00
}
2008-06-24 16:33:17 +00:00
SybCtG ( min_server_severity ) = 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 )
{
2008-06-24 16:33:17 +00:00
long retry_count ;
2002-11-05 08:29:57 +00:00
2008-06-24 16:33:17 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " l " , & retry_count ) = = FAILURE ) {
return ;
2002-11-05 08:29:57 +00:00
}
2008-06-24 16:33:17 +00:00
SybCtG ( deadlock_retry_count ) = 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])
2006-07-25 09:19:38 +00:00
Set the error handler , to be called when a server message is raised .
2002-11-05 08:29:57 +00:00
If error_func is NULL the handler will be deleted */
PHP_FUNCTION ( sybase_set_message_handler )
{
2008-06-24 16:33:17 +00:00
zend_fcall_info fci = empty_fcall_info ;
zend_fcall_info_cache cache = empty_fcall_info_cache ;
zval * sybase_link_index = NULL ;
2004-01-25 20:03:10 +00:00
sybase_link * sybase_ptr ;
2008-06-24 16:33:17 +00:00
zval * * callback ;
int id ;
2002-11-05 08:29:57 +00:00
2008-06-24 16:33:17 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " f!|r " , & fci , & cache , & sybase_link_index ) = = FAILURE ) {
return ;
}
2002-11-05 08:29:57 +00:00
2008-06-24 16:33:17 +00:00
if ( php_sybase_connection_id ( sybase_link_index , & id TSRMLS_CC ) = = FAILURE ) {
2002-11-05 08:29:57 +00:00
2008-06-24 16:33:17 +00:00
/* Doesn't matter if we're not connected yet, use default */
callback = & SybCtG ( callback_name ) ;
} else if ( - 1 = = id ) {
/* Connection-based message handler */
ZEND_FETCH_RESOURCE2 ( sybase_ptr , sybase_link * , & sybase_link_index , id , " Sybase-Link " , le_link , le_plink ) ;
callback = & sybase_ptr - > callback_name ;
} else {
/* Default message handler */
callback = & SybCtG ( callback_name ) ;
2002-11-05 08:29:57 +00:00
}
2008-06-24 16:33:17 +00:00
/* Clean old callback */
2004-01-25 20:03:10 +00:00
if ( * callback ) {
zval_ptr_dtor ( callback ) ;
* callback = NULL ;
2002-11-05 08:29:57 +00:00
}
2008-06-24 16:33:17 +00:00
if ( ZEND_FCI_INITIALIZED ( fci ) ) {
ALLOC_ZVAL ( * callback ) ;
* * callback = * fci . function_name ;
INIT_PZVAL ( * callback ) ;
zval_copy_ctor ( * callback ) ;
} else {
callback = NULL ;
2002-11-05 08:29:57 +00:00
}
2008-06-24 16:33:17 +00:00
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 :
*/