diff options
author | Thies C. Arntzen <thies@php.net> | 2000-02-01 14:39:59 +0000 |
---|---|---|
committer | Thies C. Arntzen <thies@php.net> | 2000-02-01 14:39:59 +0000 |
commit | c145f856383d272c68bb7f4dc69c3cb26cd32506 (patch) | |
tree | 07f20cc241e8bf07097c6d671518045cf354351a /ext/oci8 | |
parent | 11f53347c7e7d14c750a0ffe898f3ad22b205570 (diff) | |
download | php-git-c145f856383d272c68bb7f4dc69c3cb26cd32506.tar.gz |
make it work without the zend_hash_pointer*() functions. some work on the shutdown issues (more to follow)
Diffstat (limited to 'ext/oci8')
-rw-r--r-- | ext/oci8/oci8.c | 308 | ||||
-rw-r--r-- | ext/oci8/php_oci8.h | 11 |
2 files changed, 181 insertions, 138 deletions
diff --git a/ext/oci8/oci8.c b/ext/oci8/oci8.c index fed8ff47b8..849e7c1ac1 100644 --- a/ext/oci8/oci8.c +++ b/ext/oci8/oci8.c @@ -16,6 +16,7 @@ | Thies C. Arntzen <thies@digicol.de> | +----------------------------------------------------------------------+ */ + /* $Id$ */ /* TODO list: @@ -60,6 +61,8 @@ static int le_conn; static int le_stmt; static int le_desc; +static int le_server; +static int le_session; static zend_class_entry *oci_lob_class_entry_ptr; #ifndef SQLT_BFILEE @@ -111,10 +114,12 @@ static void oci_debug(const char *format, ...); static void _oci_conn_list_dtor(oci_connection *connection); static void _oci_stmt_list_dtor(oci_statement *statement); static void _oci_descriptor_list_dtor(oci_descriptor *descriptor); +static void _oci_server_list_dtor(oci_server *server); +static void _oci_session_list_dtor(oci_session *session); -static int _oci_column_hash_dtor(void *data); -static int _oci_define_hash_dtor(void *data); -static int _oci_bind_hash_dtor(void *data); +static void _oci_column_hash_dtor(void *data); +static void _oci_define_hash_dtor(void *data); +static void _oci_bind_hash_dtor(void *data); static oci_connection *oci_get_conn(zval **); static oci_statement *oci_get_stmt(zval **); @@ -130,20 +135,16 @@ static int oci_setprefetch(oci_statement *statement, int size); static void oci_do_connect(INTERNAL_FUNCTION_PARAMETERS,int persistent,int exclusive); -/* ServerAttach/Detach */ -static oci_server *oci_open_server(char *dbname,int persistent); +static oci_server *_oci_open_server(char *dbname,int persistent); static void _oci_close_server(oci_server *server); -/* SessionBegin/End */ -static oci_session *oci_open_user(oci_server* server,char *username,char *password,int persistent,int exclusive); -static void _oci_close_user(oci_session *session); +static oci_session *_oci_open_session(oci_server* server,char *username,char *password,int persistent,int exclusive); +static void _oci_close_session(oci_session *session); -/* bind callback functions */ static sb4 oci_bind_in_callback(dvoid *, OCIBind *, ub4, ub4, dvoid **, ub4 *, ub1 *, dvoid **); static sb4 oci_bind_out_callback(dvoid *, OCIBind *, ub4, ub4, dvoid **, ub4 **, ub1 *, dvoid **, ub2 **); #if 0 -/* failover callback function */ static sb4 oci_failover_callback(dvoid *svchp,dvoid* envhp,dvoid *fo_ctx,ub4 fo_type, ub4 fo_event); #endif @@ -333,6 +334,8 @@ PHP_MINIT_FUNCTION(oci) zend_class_entry oci_lob_class_entry; ELS_FETCH(); + OCI(shutdown) = 0; + #ifdef ZTS #define PHP_OCI_INIT_MODE OCI_THREADED #else @@ -354,6 +357,8 @@ PHP_MINIT_FUNCTION(oci) le_stmt = register_list_destructors(_oci_stmt_list_dtor, NULL); le_conn = register_list_destructors(_oci_conn_list_dtor, NULL); le_desc = register_list_destructors(_oci_descriptor_list_dtor, NULL); + le_server = register_list_destructors(_oci_server_list_dtor, NULL); + le_session = register_list_destructors(_oci_session_list_dtor, NULL); INIT_CLASS_ENTRY(oci_lob_class_entry, "OCI-Lob", php_oci_lob_class_functions); @@ -418,9 +423,9 @@ PHP_RINIT_FUNCTION(oci) return SUCCESS; } -static int _user_pcleanup(oci_session *session) +static int _session_pcleanup(oci_session *session) { - _oci_close_user(session); + _oci_close_session(session); return 1; } @@ -436,9 +441,11 @@ PHP_MSHUTDOWN_FUNCTION(oci) { OCILS_FETCH(); + OCI(shutdown) = 1; + oci_debug("START php_mshutdown_oci"); - zend_hash_apply(OCI(user),(int (*)(void *))_user_pcleanup); + zend_hash_apply(OCI(user),(int (*)(void *))_session_pcleanup); zend_hash_apply(OCI(server),(int (*)(void *))_server_pcleanup); zend_hash_destroy(OCI(user)); @@ -454,12 +461,13 @@ PHP_MSHUTDOWN_FUNCTION(oci) return SUCCESS; } -static int _user_cleanup(oci_session *session) +#if 0 +static int _session_cleanup(oci_session *session) { if (session->persistent) return 0; - _oci_close_user(session); + _oci_close_session(session); return 1; } @@ -473,19 +481,20 @@ static int _server_cleanup(oci_server *server) return 1; } +#endif PHP_RSHUTDOWN_FUNCTION(oci) { OCILS_FETCH(); - oci_debug("\n\n##################################################\n\n"); - oci_debug("START php_rshutdown_oci"); +#if 0 /* XXX free all statements, rollback all outstanding transactions */ - zend_hash_apply(OCI(user),(int (*)(void *))_user_cleanup); + zend_hash_apply(OCI(user),(int (*)(void *))_session_cleanup); zend_hash_apply(OCI(server),(int (*)(void *))_server_cleanup); +#endif oci_debug("END php_rshutdown_oci"); @@ -506,7 +515,7 @@ PHP_MINFO_FUNCTION(oci) /* }}} */ /* {{{ _oci_define_hash_dtor() */ -static int +static void _oci_define_hash_dtor(void *data) { oci_define *define = (oci_define *) data; @@ -519,14 +528,12 @@ _oci_define_hash_dtor(void *data) efree(define->name); define->name = 0; } - - return 1; } /* }}} */ /* {{{ _oci_bind_hash_dtor() */ -static int +static void _oci_bind_hash_dtor(void *data) { oci_bind *bind = (oci_bind *) data; @@ -534,8 +541,6 @@ _oci_bind_hash_dtor(void *data) oci_debug("_oci_bind_hash_dtor:"); zval_del_ref(&(bind->zval)); - - return 1; } /* }}} */ @@ -556,7 +561,7 @@ _oci_bind_pre_exec(void *data) /* }}} */ /* {{{ _oci_column_hash_dtor() */ -static int +static void _oci_column_hash_dtor(void *data) { oci_out_column *column = (oci_out_column *) data; @@ -580,8 +585,6 @@ _oci_column_hash_dtor(void *data) if (column->name) { efree(column->name); } - - return 1; } /* }}} */ @@ -679,6 +682,34 @@ _oci_descriptor_list_dtor(oci_descriptor *descr) } /* }}} */ +/* {{{ _oci_server_list_dtor() + */ + +static void +_oci_server_list_dtor(oci_server *server) +{ + ELS_FETCH(); + + if (server->persistent) + return; + + _oci_close_server(server); +} + +/* }}} */ +/* {{{ _oci_session_list_dtor() + */ + +static void +_oci_session_list_dtor(oci_session *session) +{ + if (session->persistent) + return; + + _oci_close_session(session); +} + +/* }}} */ /* {{{ oci_error() */ static ub4 @@ -937,7 +968,6 @@ _oci_make_zval(zval *value,oci_statement *statement,oci_out_column *column, char column->name,column->retlen,column->retlen4,column->storage_size4,column->indicator,column->retcode); if (column->indicator == -1) { /* column is NULL */ - /* XXX we should to make sure that there's no data attached to this yet!!! */ ZVAL_NULL(value); return 0; } @@ -1723,16 +1753,15 @@ oci_bind_out_callback(dvoid *octxp, /* context pointer */ } /* }}} */ -/* {{{ oci_open_user() +/* {{{ _oci_open_session() */ -static oci_session *oci_open_user(oci_server* server,char *username,char *password,int persistent,int exclusive) +static oci_session *_oci_open_session(oci_server* server,char *username,char *password,int persistent,int exclusive) { - oci_session *session = 0; + oci_session *session = 0, *psession = 0; OCISvcCtx *svchp = 0; char *hashed_details; - int hashed_details_length; OCILS_FETCH(); /* @@ -1744,30 +1773,27 @@ static oci_session *oci_open_user(oci_server* server,char *username,char *passwo but only as pesistent requested connections will be kept between requests! */ - hashed_details_length = strlen(SAFE_STRING(username))+ - strlen(SAFE_STRING(password))+ - strlen(SAFE_STRING(server->dbname)); - - hashed_details = (char *) emalloc(hashed_details_length+1); - + hashed_details = (char *) malloc(strlen(SAFE_STRING(username))+ + strlen(SAFE_STRING(password))+ + strlen(SAFE_STRING(server->dbname))+1); + sprintf(hashed_details,"%s%s%s", SAFE_STRING(username), SAFE_STRING(password), SAFE_STRING(server->dbname)); if (! exclusive) { - zend_hash_find(OCI(user), hashed_details, hashed_details_length+1, (void **) &session); + zend_hash_find(OCI(user), hashed_details, strlen(hashed_details)+1, (void **) &session); if (session) { if (session->open) { if (persistent) { session->persistent = 1; } - efree(hashed_details); + free(hashed_details); return session; } else { - _oci_close_user(session); - zend_hash_del(OCI(user), hashed_details, hashed_details_length+1); + _oci_close_session(session); /* breakthru to open */ } } @@ -1780,6 +1806,7 @@ static oci_session *oci_open_user(oci_server* server,char *username,char *passwo } session->persistent = persistent; + session->hashed_details = hashed_details; session->server = server; /* allocate temporary Service Context */ @@ -1790,7 +1817,7 @@ static oci_session *oci_open_user(oci_server* server,char *username,char *passwo 0, NULL); if (OCI(error) != OCI_SUCCESS) { - oci_error(OCI(pError), "oci_open_user: OCIHandleAlloc OCI_HTYPE_SVCCTX", OCI(error)); + oci_error(OCI(pError), "_oci_open_session: OCIHandleAlloc OCI_HTYPE_SVCCTX", OCI(error)); goto CLEANUP; } @@ -1802,7 +1829,7 @@ static oci_session *oci_open_user(oci_server* server,char *username,char *passwo 0, NULL); if (OCI(error) != OCI_SUCCESS) { - oci_error(OCI(pError), "oci_open_user: OCIHandleAlloc OCI_HTYPE_SESSION", OCI(error)); + oci_error(OCI(pError), "_oci_open_session: OCIHandleAlloc OCI_HTYPE_SESSION", OCI(error)); goto CLEANUP; } @@ -1815,7 +1842,7 @@ static oci_session *oci_open_user(oci_server* server,char *username,char *passwo OCI_ATTR_SERVER, OCI(pError)); if (OCI(error) != OCI_SUCCESS) { - oci_error(OCI(pError), "oci_open_user: OCIAttrSet OCI_ATTR_SERVER", OCI(error)); + oci_error(OCI(pError), "_oci_open_session: OCIAttrSet OCI_ATTR_SERVER", OCI(error)); goto CLEANUP; } @@ -1859,53 +1886,56 @@ static oci_session *oci_open_user(oci_server* server,char *username,char *passwo /* Free Temporary Service Context */ OCIHandleFree((dvoid *) svchp, (ub4) OCI_HTYPE_SVCCTX); - session->num = OCI(user_num)++; - - session->open = 1; - - oci_debug("oci_open_user new sess=%d user=%s",session->num,username); if (exclusive) { - zend_hash_next_index_pointer_insert(OCI(user), - (void *) session); + /* + zend_hash_next_index_insert(OCI(user), + (void *)session, + sizeof(oci_session), + (void**)&psession); + */ } else { - zend_hash_pointer_update(OCI(user), - hashed_details, - hashed_details_length+1, - (void *) session); + zend_hash_update(OCI(user), + session->hashed_details, + strlen(session->hashed_details)+1, + (void *)session, + sizeof(oci_session), + (void**)&psession); } - efree(hashed_details); + psession->num = zend_list_insert(psession,le_session); + psession->open = 1; - return session; + oci_debug("_oci_open_session new sess=%d user=%s",psession->num,username); - CLEANUP: - oci_debug("oci_open_user: FAILURE -> CLEANUP called"); + free(session); - if (hashed_details) { - efree(hashed_details); - } + return psession; + + CLEANUP: + oci_debug("_oci_open_session: FAILURE -> CLEANUP called"); - _oci_close_user(session); + _oci_close_session(session); return 0; } /* }}} */ -/* {{{ _oci_close_user() +/* {{{ _oci_close_session() */ static void -_oci_close_user(oci_session *session) +_oci_close_session(oci_session *session) { OCISvcCtx *svchp; + char *hashed_details; OCILS_FETCH(); if (! session) { return; } - oci_debug("_oci_close_user: logging-off sess=%d",session->num); + oci_debug("_oci_close_session: logging-off sess=%d",session->num); if (session->open) { /* Temporary Service Context */ @@ -1917,7 +1947,7 @@ _oci_close_user(oci_session *session) (dvoid **) 0); if (OCI(error) != OCI_SUCCESS) { - oci_error(OCI(pError), "_oci_close_user OCIHandleAlloc OCI_HTYPE_SVCCTX", OCI(error)); + oci_error(OCI(pError), "_oci_close_session OCIHandleAlloc OCI_HTYPE_SVCCTX", OCI(error)); } /* Set the server handle in service handle */ @@ -1929,7 +1959,7 @@ _oci_close_user(oci_session *session) OCI_ATTR_SERVER, OCI(pError)); if (OCI(error) != OCI_SUCCESS) { - oci_error(OCI(pError), "_oci_close_user: OCIAttrSet OCI_ATTR_SERVER", OCI(error)); + oci_error(OCI(pError), "_oci_close_session: OCIAttrSet OCI_ATTR_SERVER", OCI(error)); } /* Set the Authentication handle in the service handle */ @@ -1941,7 +1971,7 @@ _oci_close_user(oci_session *session) OCI_ATTR_SESSION, OCI(pError)); if (OCI(error) != OCI_SUCCESS) { - oci_error(OCI(pError), "_oci_close_user: OCIAttrSet OCI_ATTR_SESSION", OCI(error)); + oci_error(OCI(pError), "_oci_close_session: OCIAttrSet OCI_ATTR_SESSION", OCI(error)); } OCI(error) = @@ -1950,10 +1980,10 @@ _oci_close_user(oci_session *session) session->pSession, (ub4) 0); if (OCI(error) != OCI_SUCCESS) { - oci_error(OCI(pError), "_oci_close_user: OCISessionEnd", OCI(error)); + oci_error(OCI(pError), "_oci_close_session: OCISessionEnd", OCI(error)); } } else { - oci_debug("_oci_close_user: logging-off DEAD session"); + oci_debug("_oci_close_session: logging-off DEAD session"); } OCIHandleFree((dvoid *) svchp, (ub4) OCI_HTYPE_SVCCTX); @@ -1961,65 +1991,59 @@ _oci_close_user(oci_session *session) if (session->pSession) { OCIHandleFree((dvoid *) session->pSession, (ub4) OCI_HTYPE_SESSION); } - - free(session); + + hashed_details = session->hashed_details; + + if (! OCI(shutdown)) { + zend_hash_del(OCI(user), hashed_details, strlen(hashed_details)+1); + } + + free(hashed_details); } /* }}} */ -/* {{{ oci_open_server() +/* {{{ _oci_open_server() */ -static oci_server *oci_open_server(char *dbname,int persistent) + +static oci_server *_oci_open_server(char *dbname,int persistent) { - oci_server *server = 0; - char *hashed_details; - int hashed_details_length; + oci_server *server, *pserver = 0; OCILS_FETCH(); /* check if we already have this server open - + we will reuse servers within a request no matter if the user requested persistent connections or not! but only as pesistent requested connections will be kept between requests! */ - hashed_details_length = strlen(SAFE_STRING((char *)dbname)); - hashed_details = (char *) emalloc(hashed_details_length+1); - sprintf(hashed_details,"%s",SAFE_STRING((char *)dbname)); + zend_hash_find(OCI(server), dbname, strlen(dbname)+1, (void **) &pserver); - zend_hash_find(OCI(server), hashed_details, hashed_details_length+1, (void **) &server); - - if (server) { + if (pserver) { /* XXX ini-flag */ /* - if (! oci_ping(server)) { - server->open = 0; + if (! oci_ping(pserver)) { + pserver->open = 0; } */ - if (server->open) { + if (pserver->open) { /* if our new users uses this connection persistent, we're keeping it! */ if (persistent) { - server->persistent = persistent; + pserver->persistent = persistent; } - efree(hashed_details); - return server; + return pserver; } else { /* server "died" in the meantime - try to reconnect! */ - _oci_close_server(server); - zend_hash_del(OCI(server),hashed_details,hashed_details_length+1); + _oci_close_server(pserver); /* breakthru to open */ } } - + server = calloc(1,sizeof(oci_server)); - if (! server) { - goto CLEANUP; - } - server->persistent = persistent; - server->dbname = strdup(SAFE_STRING(dbname)); OCIHandleAlloc(OCI(pEnv), @@ -2031,19 +2055,38 @@ static oci_server *oci_open_server(char *dbname,int persistent) OCI(error) = OCIServerAttach(server->pServer, OCI(pError), - (text*)dbname, - strlen(dbname), + (text*)server->dbname, + strlen(server->dbname), (ub4) OCI_DEFAULT); if (OCI(error)) { - oci_error(OCI(pError), "oci_open_server", OCI(error)); + oci_error(OCI(pError), "_oci_open_server", OCI(error)); goto CLEANUP; } - server->num = OCI(server_num)++; + zend_hash_update(OCI(server), + server->dbname, + strlen(server->dbname)+1, + (void *)server, + sizeof(oci_server), + (void**)&pserver); + + pserver->num = zend_list_insert(pserver,le_server); + pserver->open = 1; + + oci_debug("_oci_open_server new conn=%d dname=%s",server->num,server->dbname); - server->open = 1; + free(server); + + return pserver; + CLEANUP: + oci_debug("_oci_open_server: FAILURE -> CLEANUP called"); + + _oci_close_server(server); + + return 0; +} #if 0 server->failover.fo_ctx = (dvoid *) server; @@ -2057,48 +2100,41 @@ static oci_server *oci_open_server(char *dbname,int persistent) OCI(pError)); if (error) { - oci_error(OCI(pError), "oci_open_server OCIAttrSet OCI_ATTR_FOCBK", error); + oci_error(OCI(pError), "_oci_open_server OCIAttrSet OCI_ATTR_FOCBK", error); goto CLEANUP; } #endif - oci_debug("oci_open_server new conn=%d dname=%s",server->num,server->dbname); - - zend_hash_pointer_update(OCI(server), - hashed_details, - hashed_details_length+1, - (void *) server); - - efree(hashed_details); - return server; - - CLEANUP: - oci_debug("oci_open_server: FAILURE -> CLEANUP called"); +/* }}} */ +/* {{{ _oci_close_server() + */ - if (hashed_details) { - efree(hashed_details); +static int _oci_session_cleanup(list_entry *le) +{ + if (le->type == le_session) { + oci_server *server = ((oci_session*) le->ptr)->server; + if (server->open == 2) + return 1; } - - _oci_close_server(server); - return 0; } -/* }}} */ -/* {{{ _oci_close_server() - */ static void _oci_close_server(oci_server *server) { + char *dbname; OCILS_FETCH(); + ELS_FETCH(); - if (! server) { - return; + server->open = 2; + + if (! OCI(shutdown)) { + zend_hash_apply(&EG(regular_list),_oci_session_cleanup); } - oci_debug("_oci_close_server: detaching conn=%d dbname=%s",server->num,server->dbname); + oci_debug("START _oci_close_server: detaching conn=%d dbname=%s",server->num,server->dbname); /* XXX close server here */ @@ -2129,11 +2165,13 @@ _oci_close_server(oci_server *server) OCIHandleFree((dvoid *) server->pServer, (ub4) OCI_HTYPE_SERVER); } - if (server->dbname) { - free(server->dbname); + dbname = server->dbname; + + if (! OCI(shutdown)) { + zend_hash_del(OCI(server),dbname,strlen(dbname)+1); } - free(server); + free(dbname); } /* }}} */ @@ -2174,7 +2212,7 @@ static void oci_do_connect(INTERNAL_FUNCTION_PARAMETERS,int persistent,int exclu goto CLEANUP; } - server = oci_open_server(dbname,persistent); + server = _oci_open_server(dbname,persistent); if (! server) { goto CLEANUP; @@ -2182,7 +2220,7 @@ static void oci_do_connect(INTERNAL_FUNCTION_PARAMETERS,int persistent,int exclu persistent = server->persistent; /* if our server-context is not persistent we can't */ - session = oci_open_user(server,username,password,persistent,exclusive); + session = _oci_open_session(server,username,password,persistent,exclusive); if (! session) { goto CLEANUP; @@ -2429,7 +2467,7 @@ PHP_FUNCTION(ocibindbyname) (text*) (*name)->value.str.val, /* placeholder name */ (*name)->value.str.len, /* placeholder length */ (dvoid *)0, /* in/out data */ - value_sz, //OCI_MAX_DATA_SIZE, /* max size of input/output data */ + value_sz, /* OCI_MAX_DATA_SIZE, */ /* max size of input/output data */ (ub2)ocitype, /* in/out data type */ (dvoid *)&bindp->indicator, /* indicator (ignored) */ (ub2 *)0, /* size array (ignored) */ diff --git a/ext/oci8/php_oci8.h b/ext/oci8/php_oci8.h index 29d63f52e9..18bb23ba28 100644 --- a/ext/oci8/php_oci8.h +++ b/ext/oci8/php_oci8.h @@ -25,9 +25,6 @@ +----------------------------------------------------------------------+ | Authors: Stig Sæther Bakken <ssb@fast.no> | | Thies C. Arntzen <thies@digicol.de> | - | | - | Initial work sponsored by Thies Arntzen <thies@digicol.de> of | - | Digital Collections, http://www.digicol.de/ | +----------------------------------------------------------------------+ */ @@ -64,13 +61,16 @@ typedef struct { int open; char *dbname; OCIServer *pServer; +#if 0 OCIFocbkStruct failover; +#endif } oci_server; typedef struct { int num; int persistent; int open; + char *hashed_details; oci_server *server; OCISession *pSession; } oci_session; @@ -148,12 +148,17 @@ typedef struct { typedef struct { sword error; OCIError *pError; + + /* char *default_username; char *default_password; char *default_dbname; + */ long debug_mode; + int shutdown; + /* XXX NYI long allow_persistent; long max_persistent; |