📄 oracle.c
字号:
/* +----------------------------------------------------------------------+ | PHP Version 4 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | 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. | +----------------------------------------------------------------------+ | Authors: Stig S鎡her Bakken <ssb@fast.no> | | Mitch Golden <mgolden@interport.net> | | Rasmus Lerdorf <rasmus@php.net> | | Andreas Karajannis <Andreas.Karajannis@gmd.de> | | Thies C. Arntzen <thies@thieso.net> | +----------------------------------------------------------------------+ *//* $Id: oracle.c,v 1.80.2.2.8.2 2007/01/01 09:46:45 sebastian Exp $ *//* comment out the next line if you're on Oracle 7.x and don't have the olog call. */ #define HAS_OLOG 1#ifdef HAVE_CONFIG_H#include "config.h"#endif#include "php.h"#include "zend_globals.h"#if HAVE_ORACLE#include "php_oracle.h"#define HASH_DTOR (void (*)(void *))#include "ext/standard/info.h"#ifndef min#define min(a, b) ((a) > (b) ? (b) : (a))#endif#ifdef PHP_WIN32#define PHP_ORA_API __declspec(dllexport)#else#define PHP_ORA_API#endif #ifdef ZTSint ora_globals_id;#elsePHP_ORA_API php_ora_globals ora_globals;#endif#define DB_SIZE 65536#define ORA_FETCHINTO_ASSOC (1<<0)#define ORA_FETCHINTO_NULLS (1<<1)static oraCursor *ora_get_cursor(HashTable *, pval ** TSRMLS_DC);static char *ora_error(Cda_Def *);static int ora_describe_define(oraCursor *);static void _close_oraconn(zend_rsrc_list_entry *rsrc TSRMLS_DC);static int _close_oracur(oraCursor *cur TSRMLS_DC);static int _ora_ping(oraConnection *conn);int ora_set_param_values(oraCursor *cursor, int isout TSRMLS_DC);void ora_do_logon(INTERNAL_FUNCTION_PARAMETERS, int persistent);static int le_conn, le_pconn, le_cursor; /* {{{ prototypes */PHP_FUNCTION(ora_bind);PHP_FUNCTION(ora_close);PHP_FUNCTION(ora_commit);PHP_FUNCTION(ora_commitoff);PHP_FUNCTION(ora_commiton);PHP_FUNCTION(ora_do);PHP_FUNCTION(ora_error);PHP_FUNCTION(ora_errorcode);PHP_FUNCTION(ora_exec);PHP_FUNCTION(ora_fetch);PHP_FUNCTION(ora_fetch_into);PHP_FUNCTION(ora_columntype);PHP_FUNCTION(ora_columnname);PHP_FUNCTION(ora_columnsize);PHP_FUNCTION(ora_getcolumn);PHP_FUNCTION(ora_numcols);PHP_FUNCTION(ora_numrows);PHP_FUNCTION(ora_logoff);PHP_FUNCTION(ora_logon);PHP_FUNCTION(ora_plogon);PHP_FUNCTION(ora_open);PHP_FUNCTION(ora_parse);PHP_FUNCTION(ora_rollback);PHP_MINIT_FUNCTION(oracle);PHP_RINIT_FUNCTION(oracle);PHP_MSHUTDOWN_FUNCTION(oracle);PHP_RSHUTDOWN_FUNCTION(oracle);PHP_MINFO_FUNCTION(oracle);/* }}} */static unsigned char second_args_force_ref[] = { 2, BYREF_NONE, BYREF_FORCE };/* {{{ oracle_functions[] */function_entry oracle_functions[] = { PHP_FE(ora_bind, NULL) PHP_FE(ora_close, NULL) PHP_FE(ora_commit, NULL) PHP_FE(ora_commitoff, NULL) PHP_FE(ora_commiton, NULL) PHP_FE(ora_do, NULL) PHP_FE(ora_error, NULL) PHP_FE(ora_errorcode, NULL) PHP_FE(ora_exec, NULL) PHP_FE(ora_fetch, NULL) PHP_FE(ora_fetch_into, second_args_force_ref) PHP_FE(ora_columntype, NULL) PHP_FE(ora_columnname, NULL) PHP_FE(ora_columnsize, NULL) PHP_FE(ora_getcolumn, NULL) PHP_FE(ora_numcols, NULL) PHP_FE(ora_numrows, NULL) PHP_FE(ora_logoff, NULL) PHP_FE(ora_logon, NULL) PHP_FE(ora_plogon, NULL) PHP_FE(ora_open, NULL) PHP_FE(ora_parse, NULL) PHP_FE(ora_rollback, NULL) {NULL, NULL, NULL}};/* }}} *//* {{{ oracle_module_entry */zend_module_entry oracle_module_entry = { STANDARD_MODULE_HEADER, "oracle", oracle_functions, PHP_MINIT(oracle), /* extension-wide startup function */ PHP_MSHUTDOWN(oracle), /* extension-wide shutdown function */ PHP_RINIT(oracle), /* per-request startup function */ PHP_RSHUTDOWN(oracle), /* per-request shutdown function */ PHP_MINFO(oracle), NO_VERSION_YET, STANDARD_MODULE_PROPERTIES};/* }}} *//* {{{ ora_func_tab[] */static const text *ora_func_tab[] ={(text *) "unused",/* 1, 2 */ (text *) "unused", (text *) "OSQL",/* 3, 4 */ (text *) "unused", (text *) "OEXEC/OEXN",/* 5, 6 */ (text *) "unused", (text *) "OBIND",/* 7, 8 */ (text *) "unused", (text *) "ODEFIN",/* 9, 10 */ (text *) "unused", (text *) "ODSRBN",/* 11, 12 */ (text *) "unused", (text *) "OFETCH/OFEN",/* 13, 14 */ (text *) "unused", (text *) "OOPEN",/* 15, 16 */ (text *) "unused", (text *) "OCLOSE",/* 17, 18 */ (text *) "unused", (text *) "unused",/* 19, 20 */ (text *) "unused", (text *) "unused",/* 21, 22 */ (text *) "unused", (text *) "ODSC",/* 23, 24 */ (text *) "unused", (text *) "ONAME",/* 25, 26 */ (text *) "unused", (text *) "OSQL3",/* 27, 28 */ (text *) "unused", (text *) "OBNDRV",/* 29, 30 */ (text *) "unused", (text *) "OBNDRN",/* 31, 32 */ (text *) "unused", (text *) "unused",/* 33, 34 */ (text *) "unused", (text *) "OOPT",/* 35, 36 */ (text *) "unused", (text *) "unused",/* 37, 38 */ (text *) "unused", (text *) "unused",/* 39, 40 */ (text *) "unused", (text *) "unused",/* 41, 42 */ (text *) "unused", (text *) "unused",/* 43, 44 */ (text *) "unused", (text *) "unused",/* 45, 46 */ (text *) "unused", (text *) "unused",/* 47, 48 */ (text *) "unused", (text *) "unused",/* 49, 50 */ (text *) "unused", (text *) "unused",/* 51, 52 */ (text *) "unused", (text *) "OCAN",/* 53, 54 */ (text *) "unused", (text *) "OPARSE",/* 55, 56 */ (text *) "unused", (text *) "OEXFET",/* 57, 58 */ (text *) "unused", (text *) "OFLNG",/* 59, 60 */ (text *) "unused", (text *) "ODESCR",/* 61, 62 */ (text *) "unused", (text *) "OBNDRA"};/* }}} */#ifdef COMPILE_DL_ORACLEZEND_GET_MODULE(oracle)#endif/* {{{ _close_oraconn */static void _close_oraconn(zend_rsrc_list_entry *rsrc TSRMLS_DC){ oraConnection *conn = (oraConnection *)rsrc->ptr; conn->open = 0; ologof(&conn->lda); ORA(num_links)--; zend_hash_del(ORA(conns),(void*)&conn,sizeof(void*)); if (conn->persistent) { ORA(num_persistent)--; free(conn); } else { efree(conn); }}/* }}} *//* {{{ pval_ora_param_destructor */static voidpval_ora_param_destructor(oraParam *param){ if (param->progv) { efree(param->progv); }}/* }}} *//* {{{ _close_oracur */static int _close_oracur(oraCursor *cur TSRMLS_DC){ int i; if (cur){ if (cur->query){ efree(cur->query); } if (cur->params){ zend_hash_destroy(cur->params); efree(cur->params); cur->params = NULL; } if (cur->columns){ for(i = 0; i < cur->ncols; i++){ if (cur->columns[i].buf) efree(cur->columns[i].buf); } efree(cur->columns); cur->columns = NULL; } if (cur->open){ oraConnection *db_conn; if (zend_hash_find(ORA(conns),(void*)&(cur->conn_ptr),sizeof(void*),(void **)&db_conn) == SUCCESS) { oclose(&cur->cda); } } efree(cur); } return 1;}/* }}} *//* {{{ php_close_ora_cursor */static void php_close_ora_cursor(zend_rsrc_list_entry *rsrc TSRMLS_DC){ oraCursor *cur = (oraCursor *)rsrc->ptr; _close_oracur(cur TSRMLS_CC);}/* }}} *//* {{{ php_ora_init_globals */static void php_ora_init_globals(php_ora_globals *ora_globals_p TSRMLS_DC){ if (cfg_get_long("oracle.allow_persistent", &ORA(allow_persistent)) == FAILURE) { ORA(allow_persistent) = -1; } if (cfg_get_long("oracle.max_persistent", &ORA(max_persistent)) == FAILURE) { ORA(max_persistent) = -1; } if (cfg_get_long("oracle.max_links", &ORA(max_links)) == FAILURE) { ORA(max_links) = -1; } ORA(num_persistent) = 0; ORA(conns) = malloc(sizeof(HashTable)); zend_hash_init(ORA(conns), 13, NULL, NULL, 1); memset((void*) &ORA(db_err_conn),0,sizeof(ORA(db_err_conn)));}/* }}} *//* {{{ PHP_MINIT_FUNCTION */PHP_MINIT_FUNCTION(oracle){#ifdef ZTS ts_allocate_id(&ora_globals_id, sizeof(php_ora_globals), (ts_allocate_ctor) php_ora_init_globals, NULL);#else php_ora_init_globals(&ora_globals TSRMLS_CC);#endif le_cursor = zend_register_list_destructors_ex(php_close_ora_cursor, NULL, "oracle cursor", module_number); le_conn = zend_register_list_destructors_ex(_close_oraconn, NULL, "oracle link", module_number); le_pconn = zend_register_list_destructors_ex(NULL, _close_oraconn, "oracle link persistent", module_number); REGISTER_LONG_CONSTANT("ORA_BIND_INOUT", 0, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("ORA_BIND_IN", 1, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("ORA_BIND_OUT", 2, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("ORA_FETCHINTO_ASSOC",ORA_FETCHINTO_ASSOC, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("ORA_FETCHINTO_NULLS",ORA_FETCHINTO_NULLS, CONST_CS | CONST_PERSISTENT);#ifdef ZTS opinit(OCI_EV_TSF); #endif return SUCCESS;}/* }}} *//* {{{ PHP_RINIT_FUNCTION */PHP_RINIT_FUNCTION(oracle){ ORA(num_links) = ORA(num_persistent); /* ORA(defaultlrl) = 0; ORA(defaultbinmode) = 0; ORA(defaultconn) = 0; */ return SUCCESS;}/* }}} *//* {{{ PHP_MSHUTDOWN_FUNCTION */PHP_MSHUTDOWN_FUNCTION(oracle){ zend_hash_destroy(ORA(conns)); free(ORA(conns)); return SUCCESS;}/* }}} *//* {{{ PHP_RSHUTDOWN_FUNCTION */PHP_RSHUTDOWN_FUNCTION(oracle){ return SUCCESS;}/* }}} *//* {{{ _ora_ping */static int _ora_ping(oraConnection *conn){ Cda_Def cda; if (oopen(&cda, &conn->lda, (text *) 0, -1, -1, (text *) 0, -1)) { return 0; } if (oparse(&cda, "select sysdate from dual", (sb4) - 1, 0, VERSION_7)) { oclose(&cda); return 0; } oclose(&cda); return 1;}/* }}} *//* ** PHP functions*//* {{{ proto int ora_logon(string user, string password) Open an Oracle connection */PHP_FUNCTION(ora_logon){ ora_do_logon(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);}/* }}} *//* {{{ proto int ora_plogon(string user, string password) Open a persistent Oracle connection */PHP_FUNCTION(ora_plogon){ ora_do_logon(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);}/* }}} *//* {{{ ora_do_logon */void ora_do_logon(INTERNAL_FUNCTION_PARAMETERS, int persistent){ char *user,*passwd; pval **arg1, **arg2; char *hashed_details; int hashed_details_length; oraConnection *db_conn; if (zend_get_parameters_ex(2, &arg1, &arg2) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(arg1); convert_to_string_ex(arg2); user = Z_STRVAL_PP(arg1); passwd = Z_STRVAL_PP(arg2); hashed_details_length = sizeof("oracle__")-1+strlen(user)+strlen(passwd); hashed_details = (char *) emalloc(hashed_details_length+1); sprintf(hashed_details,"oracle_%s_%s",user,passwd); if (!ORA(allow_persistent)) { persistent=0; } if (persistent) { list_entry *le; /* try to find if we already have this link in our persistent list */ if (zend_hash_find(&EG(persistent_list), hashed_details, hashed_details_length+1, (void **) &le)==FAILURE) { /* we don't */ list_entry new_le; if (ORA(max_links)!=-1 && ORA(num_links)>=ORA(max_links)) { php_error(E_WARNING,"Oracle: Too many open links (%d)",ORA(num_links)); efree(hashed_details); RETURN_FALSE; } if (ORA(max_persistent)!=-1 && ORA(num_persistent)>=ORA(max_persistent)) { php_error(E_WARNING,"Oracle: Too many open persistent links (%d)",ORA(num_persistent)); efree(hashed_details); RETURN_FALSE; } /* create the link */ db_conn = (oraConnection *)malloc(sizeof(oraConnection)); memset((void *) db_conn,0,sizeof(oraConnection)); db_conn->persistent = 1; if (#if HAS_OLOG olog(&db_conn->lda, db_conn->hda, user,strlen(user), passwd, strlen(passwd), 0, -1, OCI_LM_DEF)#else orlon(&db_conn->lda, db_conn->hda, user,strlen(user), passwd, strlen(passwd), 0)#endif ) { ORA(db_err_conn) = *db_conn; php_error(E_WARNING, "Unable to connect to ORACLE (%s)",ora_error(&db_conn->lda)); if (persistent) { free(db_conn); } else { efree(db_conn); } efree(hashed_details); RETURN_FALSE; } /* hash it up */ Z_TYPE(new_le) = le_pconn; new_le.ptr = db_conn; if (zend_hash_update(&EG(persistent_list), hashed_details, hashed_details_length+1, (void *) &new_le, sizeof(list_entry), NULL)==FAILURE) { free(db_conn); efree(hashed_details); RETURN_FALSE; } ORA(num_persistent)++; ORA(num_links)++; zend_hash_add(ORA(conns),(void*)&db_conn,sizeof(void*),(void*)&db_conn,sizeof(void*),NULL); } else { /* we do */ if (Z_TYPE_P(le) != le_pconn) { RETURN_FALSE; } db_conn = (oraConnection *) le->ptr; /* ensure that the link did not die */ if (!_ora_ping(db_conn)) { if (#if HAS_OLOG olog(&db_conn->lda, db_conn->hda, user,strlen(user), passwd, strlen(passwd), 0, -1, OCI_LM_DEF)#else orlon(&db_conn->lda, db_conn->hda, user,strlen(user), passwd, strlen(passwd), 0)#endif ) { ORA(db_err_conn) = *db_conn; php_error(E_WARNING, "Oracle: Link to server lost, unable to reconnect",ora_error(&db_conn->lda)); zend_hash_del(&EG(persistent_list), hashed_details, hashed_details_length+1); efree(hashed_details); RETURN_FALSE; } } } ZEND_REGISTER_RESOURCE(return_value, db_conn, le_pconn); } else { /* non persistent */ list_entry *index_ptr,new_index_ptr; /* first we check the hash for the hashed_details key. if it exists, * it should point us to the right offset where the actual Oracle link sits. * if it doesn't, open a new Oracle link, add it to the resource list, * and add a pointer to it with hashed_details as the key. */ if (zend_hash_find(&EG(regular_list),hashed_details,hashed_details_length+1,(void **) &index_ptr)==SUCCESS) { int type,link; void *ptr; if (Z_TYPE_P(index_ptr) != le_index_ptr) { RETURN_FALSE; } link = (int) index_ptr->ptr; ptr = zend_list_find(link,&type); /* check if the link is still there */ if (ptr && (type==le_conn || type==le_pconn)) { zend_list_addref(link); Z_LVAL_P(return_value) = link; Z_TYPE_P(return_value) = IS_RESOURCE; efree(hashed_details); return; } else { zend_hash_del(&EG(regular_list),hashed_details,hashed_details_length+1); } } if (ORA(max_links)!=-1 && ORA(num_links)>=ORA(max_links)) { php_error(E_WARNING,"Oracle: Too many open links (%d)",ORA(num_links)); efree(hashed_details); RETURN_FALSE; } db_conn = (oraConnection *) emalloc(sizeof(oraConnection)); memset((void *) db_conn,0,sizeof(oraConnection)); db_conn->persistent = 0; if (#if HAS_OLOG olog(&db_conn->lda, db_conn->hda, user,strlen(user), passwd, strlen(passwd), 0, -1, OCI_LM_DEF)#else orlon(&db_conn->lda, db_conn->hda, user,strlen(user), passwd, strlen(passwd), 0)#endif ) { ORA(db_err_conn) = *db_conn; php_error(E_WARNING,"Oracle: Connection Failed: %s\n",ora_error(&db_conn->lda)); efree(hashed_details); efree(db_conn); RETURN_FALSE; } /* add it to the list */ ZEND_REGISTER_RESOURCE(return_value, db_conn, le_conn); /* add it to the hash */ new_index_ptr.ptr = (void *) Z_LVAL_P(return_value); Z_TYPE(new_index_ptr) = le_index_ptr; if (zend_hash_update(&EG(regular_list),hashed_details,hashed_details_length+1,(void *) &new_index_ptr, sizeof(list_entry), NULL)==FAILURE) { efree(hashed_details); RETURN_FALSE; } zend_hash_add(ORA(conns),(void*)&db_conn,sizeof(void*),(void*)&db_conn,sizeof(void*),NULL); ORA(num_links)++; } efree(hashed_details);}/* }}} *//* {{{ proto int ora_logoff(int connection) Close an Oracle connection */PHP_FUNCTION(ora_logoff){ /* conn_index */ oraConnection *conn; pval **arg;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -