📄 oci8.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> | | Thies C. Arntzen <thies@thieso.net> | | Maxim Maletsky <maxim@maxim.cx> | | | | Collection support by Andy Sautins <asautins@veripost.net> | | Temporary LOB support by David Benson <dbenson@mancala.com> | +----------------------------------------------------------------------+ *//* $Id: oci8.c,v 1.183.2.18.2.4 2007/01/01 09:46:45 sebastian Exp $ *//* TODO list: * * - php.ini flags * especialliy important for things like oci_ping * - Change return-value for OCIFetch*() (1-row read, 0-Normal end, false-error) * - Error mode (print or shut up?) * - binding of arrays * - Character sets for NCLOBS * - split the module into an upper (php-callable) and lower (c-callable) layer! * - remove all XXXs * - clean up and documentation * - make OCIInternalDebug accept a mask of flags.... * - add some flags to OCIFetchStatement (maxrows etc...) * - have one ocifree() call. * - make it possible to have persistent statements? * - implement connection pooling in ZTS mode. * - failover * - change all the lob stuff to work without classes (optional)! * - make sure that the callbacks terminate the strings with \0 * - cleanup the ociexecute semantics for refcursors * - make $lob->savefile use O_BINARY * - line 2728: ub4 length = -1; needs fixing * - delay OCIInitialize() as far as we can. * - add PHP Array <-> OCICollection conversion * - add Collection iterator object for INDEX BY tables * - make auto-rollback only happen if we have an outstanding transaction * - implement ocidisconnect *//* {{{ includes & stuff */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include "php.h"#include "ext/standard/info.h"/* #define HAVE_OCI8_TEMP_LOB 1 */#define WITH_COLLECTIONS 1#if HAVE_OCI8#include "php_oci8.h"/* True globals, no need for thread safety */static int le_conn;static int le_stmt;static int le_desc;#ifdef WITH_COLLECTIONS static int le_coll;#endifstatic int le_server;static int le_session;static zend_class_entry *oci_lob_class_entry_ptr;#ifdef WITH_COLLECTIONSstatic zend_class_entry *oci_coll_class_entry_ptr;#endif#ifndef SQLT_BFILEE#define SQLT_BFILEE 114#endif#ifndef SQLT_CFILEE#define SQLT_CFILEE 115#endif#define SAFE_STRING(s) ((s)?(s):"")/* dirty marcos to make sure we _never_ call oracle-functions recursivly * * i'm well aware that we should _never_ call exit directly - this core is for * pure testing and commented out - as you can see;-) * thies@thieso.net 20010723 */#define CALL_OCI(call) \{ \ if (OCI(in_call)) { \ php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI8 Recursive call!\n"); \ exit(-1); \ } else { \ OCI(in_call)=1; \ call; \ OCI(in_call)=0; \ } \}#define CALL_OCI_RETURN(retcode,call) \{ \ if (OCI(in_call)) { \ retcode=-1; \ php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI8 Recursive call!\n"); \ exit(-1); \ } else { \ OCI(in_call)=1; \ retcode=call; \ OCI(in_call)=0; \ } \}#include <fcntl.h>#ifndef O_BINARY#define O_BINARY 0#endif/* }}} *//* {{{ thread safety stuff */#ifdef ZTSint oci_globals_id;#elsePHP_OCI_API php_oci_globals oci_globals;#endif/* }}} *//* {{{ dynamically loadable module stuff */#ifdef COMPILE_DL_OCI8ZEND_GET_MODULE(oci8)#endif /* COMPILE_DL *//* }}} *//* {{{ startup/shutdown/info/internal function prototypes */PHP_MINIT_FUNCTION(oci);PHP_RINIT_FUNCTION(oci);PHP_MSHUTDOWN_FUNCTION(oci);PHP_RSHUTDOWN_FUNCTION(oci);PHP_MINFO_FUNCTION(oci);static ub4 oci_handle_error(oci_connection *connection, ub4 errcode);static ub4 oci_error(OCIError *err_p, char *what, sword status);static int oci_ping(oci_server *server);static void oci_debug(const char *format, ...);static void _oci_conn_list_dtor(oci_connection *connection TSRMLS_DC);static void _oci_stmt_list_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC);static void _oci_descriptor_list_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC);#ifdef WITH_COLLECTIONSstatic void _oci_coll_list_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC);#endifstatic void _oci_server_list_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC);static void _oci_session_list_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC);static void php_oci_free_conn_list(zend_rsrc_list_entry *rsrc TSRMLS_DC);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 ** TSRMLS_DC);static oci_statement *oci_get_stmt(zval ** TSRMLS_DC);static oci_descriptor *oci_get_desc(int TSRMLS_DC);#ifdef WITH_COLLECTIONS/* Questionable name. Very close to oci_get_col */static oci_collection *oci_get_coll(int TSRMLS_DC);#endifstatic oci_out_column *oci_get_col(oci_statement *, int, zval **);static int _oci_make_zval(zval *, oci_statement *, oci_out_column *, char *, int mode TSRMLS_DC);static oci_statement *oci_parse(oci_connection *, char *, int);static int oci_execute(oci_statement *, char *, ub4 mode);static int oci_fetch(oci_statement *, ub4, char * TSRMLS_DC);static int oci_loadlob(oci_connection *, oci_descriptor *, char **, ub4 *length);static int oci_setprefetch(oci_statement *statement, int size);static void oci_do_connect(INTERNAL_FUNCTION_PARAMETERS,int persistent,int exclusive);static oci_server *_oci_open_server(char *dbname,int persistent);static void _oci_close_server(oci_server *server);static oci_session *_oci_open_session(oci_server* server,char *username,char *password,int persistent,int exclusive, char *charset);static void _oci_close_session(oci_session *session);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 0static sb4 oci_failover_callback(dvoid *svchp,dvoid* envhp,dvoid *fo_ctx,ub4 fo_type, ub4 fo_event);#endif/* }}} *//* {{{ extension function prototypes */PHP_FUNCTION(ocibindbyname);PHP_FUNCTION(ocidefinebyname);PHP_FUNCTION(ocicolumnisnull);PHP_FUNCTION(ocicolumnname);PHP_FUNCTION(ocicolumnsize);PHP_FUNCTION(ocicolumnscale);PHP_FUNCTION(ocicolumnprecision);PHP_FUNCTION(ocicolumntype);PHP_FUNCTION(ocicolumntyperaw);PHP_FUNCTION(ociexecute);PHP_FUNCTION(ocifetch);PHP_FUNCTION(ocicancel);PHP_FUNCTION(ocifetchinto);PHP_FUNCTION(ocifetchstatement);PHP_FUNCTION(ocifreestatement);PHP_FUNCTION(ociinternaldebug);PHP_FUNCTION(ocilogoff);PHP_FUNCTION(ocilogon);PHP_FUNCTION(ocinlogon);PHP_FUNCTION(ociplogon);PHP_FUNCTION(ocierror);PHP_FUNCTION(ocifreedesc);PHP_FUNCTION(ocisavelob);PHP_FUNCTION(ocisavelobfile);PHP_FUNCTION(ociloadlob);PHP_FUNCTION(ociwritelobtofile);PHP_FUNCTION(ocicommit);PHP_FUNCTION(ocirollback);PHP_FUNCTION(ocinewdescriptor);PHP_FUNCTION(ocinumcols);PHP_FUNCTION(ociparse);PHP_FUNCTION(ocinewcursor);PHP_FUNCTION(ociresult);PHP_FUNCTION(ociserverversion);PHP_FUNCTION(ocistatementtype);PHP_FUNCTION(ocirowcount);PHP_FUNCTION(ocisetprefetch);PHP_FUNCTION(ocipasswordchange);#ifdef HAVE_OCI8_TEMP_LOBPHP_FUNCTION(ociwritetemporarylob);PHP_FUNCTION(ocicloselob);#endif#ifdef WITH_COLLECTIONSPHP_FUNCTION(ocinewcollection);PHP_FUNCTION(ocifreecollection);PHP_FUNCTION(ocicollappend);PHP_FUNCTION(ocicollgetelem);PHP_FUNCTION(ocicollassignelem);PHP_FUNCTION(ocicollassign);PHP_FUNCTION(ocicollsize);PHP_FUNCTION(ocicollmax);PHP_FUNCTION(ocicolltrim);#endif#define OCI_GET_STMT(statement,value) \ statement = oci_get_stmt(value TSRMLS_CC); \ if (statement == NULL) { \ RETURN_FALSE; \ }#define OCI_GET_CONN(connection,value) \ connection = oci_get_conn(value TSRMLS_CC); \ if (connection == NULL) { \ RETURN_FALSE; \ }#define OCI_GET_DESC(descriptor,index) \ descriptor = oci_get_desc(index TSRMLS_CC); \ if (descriptor == NULL) { \ RETURN_FALSE; \ }#ifdef WITH_COLLECTIONS#define OCI_GET_COLL(collection,index) \ collection = oci_get_coll(index TSRMLS_CC); \ if (collection == NULL) { \ RETURN_FALSE; \ }#endif/* }}} *//* {{{ extension definition structures */#define OCI_ASSOC 1<<0#define OCI_NUM 1<<1#define OCI_BOTH (OCI_ASSOC|OCI_NUM)#define OCI_RETURN_NULLS 1<<2#define OCI_RETURN_LOBS 1<<3#define OCI_FETCHSTATEMENT_BY_COLUMN 1<<4#define OCI_FETCHSTATEMENT_BY_ROW 1<<5#define OCI_FETCHSTATEMENT_BY (OCI_FETCHSTATEMENT_BY_COLUMN | OCI_FETCHSTATEMENT_BY_ROW)static unsigned char a3_arg_force_ref[] = { 3, BYREF_NONE, BYREF_NONE, BYREF_FORCE };static unsigned char a2_arg_force_ref[] = { 2, BYREF_NONE, BYREF_FORCE };static zend_function_entry php_oci_functions[] = { PHP_FE(ocidefinebyname, a3_arg_force_ref) PHP_FE(ocibindbyname, a3_arg_force_ref) PHP_FE(ocicolumnisnull, NULL) PHP_FE(ocicolumnname, NULL) PHP_FE(ocicolumnsize, NULL) PHP_FE(ocicolumnscale, NULL) PHP_FE(ocicolumnprecision, NULL) PHP_FE(ocicolumntype, NULL) PHP_FE(ocicolumntyperaw, NULL) PHP_FE(ociexecute, NULL) PHP_FE(ocicancel, NULL) PHP_FE(ocifetch, NULL) PHP_FE(ocifetchinto, a2_arg_force_ref) PHP_FE(ocifetchstatement, a2_arg_force_ref) PHP_FE(ocifreestatement, NULL) PHP_FE(ociinternaldebug, NULL) PHP_FE(ocinumcols, NULL) PHP_FE(ociparse, NULL) PHP_FE(ocinewcursor, NULL) PHP_FE(ociresult, NULL) PHP_FE(ociserverversion, NULL) PHP_FE(ocistatementtype, NULL) PHP_FE(ocirowcount, NULL) PHP_FE(ocilogoff, NULL) PHP_FE(ocilogon, NULL) PHP_FE(ocinlogon, NULL) PHP_FE(ociplogon, NULL) PHP_FE(ocierror, NULL) PHP_FE(ocifreedesc, NULL) PHP_FE(ocisavelob, NULL) PHP_FE(ocisavelobfile, NULL) PHP_FE(ociloadlob, NULL) PHP_FE(ociwritelobtofile, NULL) PHP_FE(ocicommit, NULL) PHP_FE(ocirollback, NULL) PHP_FE(ocinewdescriptor, NULL) PHP_FE(ocisetprefetch, NULL) PHP_FE(ocipasswordchange, NULL)#ifdef WITH_COLLECTIONS PHP_FE(ocifreecollection, NULL) PHP_FE(ocicollappend, NULL) PHP_FE(ocicollgetelem, NULL) PHP_FE(ocicollassignelem, NULL) PHP_FE(ocicollassign, NULL) PHP_FE(ocicollsize, NULL) PHP_FE(ocicollmax, NULL) PHP_FE(ocicolltrim, NULL) PHP_FE(ocinewcollection, NULL)#endif PHP_FALIAS(ocifreecursor,ocifreestatement,NULL) {NULL,NULL,NULL}};static zend_function_entry php_oci_lob_class_functions[] = { PHP_FALIAS(load, ociloadlob, NULL) PHP_FALIAS(writetofile, ociwritelobtofile, NULL)#ifdef HAVE_OCI8_TEMP_LOB PHP_FALIAS(writetemporary, ociwritetemporarylob,NULL) PHP_FALIAS(close, ocicloselob, NULL)#endif PHP_FALIAS(save, ocisavelob, NULL) PHP_FALIAS(savefile, ocisavelobfile, NULL) PHP_FALIAS(free, ocifreedesc, NULL) {NULL,NULL,NULL}};#ifdef WITH_COLLECTIONSstatic zend_function_entry php_oci_coll_class_functions[] = { PHP_FALIAS(append, ocicollappend, NULL) PHP_FALIAS(getelem, ocicollgetelem, NULL) PHP_FALIAS(assignelem, ocicollassignelem, NULL) PHP_FALIAS(assign, ocicollassign, NULL) PHP_FALIAS(size, ocicollsize, NULL) PHP_FALIAS(max, ocicollmax, NULL) PHP_FALIAS(trim, ocicolltrim, NULL) PHP_FALIAS(free, ocifreecollection, NULL) {NULL,NULL,NULL}};#endifzend_module_entry oci8_module_entry = { STANDARD_MODULE_HEADER, "oci8", /* extension name */ php_oci_functions, /* extension function list */ PHP_MINIT(oci), /* extension-wide startup function */ PHP_MSHUTDOWN(oci), /* extension-wide shutdown function */ PHP_RINIT(oci), /* per-request startup function */ PHP_RSHUTDOWN(oci), /* per-request shutdown function */ PHP_MINFO(oci), /* information function */ NO_VERSION_YET, STANDARD_MODULE_PROPERTIES};/* }}} *//* {{{ debug malloc/realloc/free */#define OCI_USE_EMALLOC 0 /* set this to 1 if you want to use the php memory manager! */#if OCI_USE_EMALLOCCONST dvoid *ocimalloc(dvoid *ctx, size_t size){ dvoid *ret; ret = (dvoid *)malloc(size); oci_debug("ocimalloc(%d) = %08x", size,ret); return ret;}CONST dvoid *ocirealloc(dvoid *ctx, dvoid *ptr, size_t size){ dvoid *ret; oci_debug("ocirealloc(%08x, %d)", ptr, size); ret = (dvoid *)realloc(ptr, size); return ptr;}CONST void ocifree(dvoid *ctx, dvoid *ptr){ oci_debug("ocifree(%08x)", ptr); free(ptr);}#endif/* }}} *//* {{{ startup, shutdown and info functions */static void php_oci_init_globals(php_oci_globals *oci_globals_p TSRMLS_DC){ OCI(shutdown) = 0; OCI(in_call) = 0; OCI(user) = malloc(sizeof(HashTable)); zend_hash_init(OCI(user), 13, NULL, NULL, 1); OCI(server) = malloc(sizeof(HashTable)); zend_hash_init(OCI(server), 13, NULL, NULL, 1); CALL_OCI(OCIEnvInit( &OCI(pEnv), OCI_DEFAULT, 0, NULL)); CALL_OCI(OCIHandleAlloc( OCI(pEnv), (dvoid **)&OCI(pError), OCI_HTYPE_ERROR, 0, NULL));}PHP_MINIT_FUNCTION(oci){ zend_class_entry oci_lob_class_entry;#ifdef WITH_COLLECTIONS zend_class_entry oci_coll_class_entry;#endif#ifdef HAVE_OCI8_SHARED_MODE#ifdef WITH_COLLECTIONS#define PHP_OCI_INIT_MODE OCI_SHARED | OCI_OBJECT#else#define PHP_OCI_INIT_MODE OCI_SHARED#endif#else#ifdef WITH_COLLECTIONS#define PHP_OCI_INIT_MODE OCI_DEFAULT | OCI_OBJECT#else#define PHP_OCI_INIT_MODE OCI_DEFAULT#endif#endif#if OCI_USE_EMALLOC OCIInitialize(PHP_OCI_INIT_MODE, NULL, ocimalloc, ocirealloc, ocifree);#else OCIInitialize(PHP_OCI_INIT_MODE, NULL, NULL, NULL, NULL);#endif#ifdef ZTS ts_allocate_id(&oci_globals_id, sizeof(php_oci_globals), (ts_allocate_ctor) php_oci_init_globals, NULL);#else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -