Ok, I've attached a pretty ok version. I had to update the config.m4 to inculde a HAVE_OCI9 define, but since I'm not really good in this kind of thing, buildconf now reports a warning
autoheader: No template for symbol `HAVE_OCI9' don't know what to do about it. otherwise everything compiles and runs smoothly, so I hope you'll enjoy :-). Abdul Maxim Maletsky <[EMAIL PROTECTED]> schrieb am 17.10.02 12:45:57: > OK, then. > > > -- > Maxim Maletsky > [EMAIL PROTECTED] > > > > <[EMAIL PROTECTED]> wrote... : > > > > > Thies, Maxim, if you could hang on for a few hours I'll be back with a few ideas >and a cleaned up version of the patches + a switch for oracle 9+ to enable the new >nls functions. > > > > Abdul > > >
--- oci8.c Wed Oct 9 16:55:16 2002 +++ oci8.c Thu Oct 17 13:32:09 2002 @@ -20,7 +20,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: oci8.c,v 1.176 2002/09/12 09:48:02 thies Exp $ */ +/* $Id: oci8.c,v 1.175 2002/08/20 07:26:50 edink Exp $ */ /* TODO list: * @@ -199,7 +199,7 @@ 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); +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 **); @@ -451,7 +451,7 @@ OCI_DEFAULT, 0, NULL)); - + CALL_OCI(OCIHandleAlloc( OCI(pEnv), (dvoid **)&OCI(pError), @@ -631,7 +631,7 @@ php_info_print_table_start(); php_info_print_table_row(2, "OCI8 Support", "enabled"); - php_info_print_table_row(2, "Revision", "$Revision: 1.176 $"); + php_info_print_table_row(2, "Revision", "$Revision: 1.175 $"); #ifndef PHP_WIN32 php_info_print_table_row(2, "Oracle Version", PHP_OCI8_VERSION ); php_info_print_table_row(2, "Compile-time ORACLE_HOME", PHP_OCI8_DIR ); @@ -1158,9 +1158,9 @@ php_error(E_WARNING, "Unknown descriptor type %d.",Z_TYPE_P(descr)); return 0; } - + CALL_OCI_RETURN(OCI(error), OCIDescriptorAlloc( - OCI(pEnv), + connection->session->pEnv, (dvoid*)&(descr->ocidescr), Z_TYPE_P(descr), (size_t) 0, @@ -1244,7 +1244,7 @@ oci_debug("_oci_make_zval: %16s,retlen = %4d,retlen4 = %d,storage_size4 = %4d,indicator %4d, retcode = %4d", column->name,column->retlen,column->retlen4,column->storage_size4,column->indicator,column->retcode); - if ((! statement->has_data) || (column->indicator == -1)) { /* column is NULL or statment has no current data */ + if (column->indicator == -1) { /* column is NULL */ ZVAL_NULL(value); return 0; } @@ -1351,14 +1351,14 @@ statement = ecalloc(1,sizeof(oci_statement)); CALL_OCI(OCIHandleAlloc( - OCI(pEnv), + connection->session->pEnv, (dvoid **)&statement->pStmt, OCI_HTYPE_STMT, 0, NULL)); CALL_OCI(OCIHandleAlloc( - OCI(pEnv), + connection->session->pEnv, (dvoid **)&statement->pError, OCI_HTYPE_ERROR, 0, @@ -1392,9 +1392,7 @@ if (query) { statement->last_query = estrdup(query); } - statement->conn = connection; - statement->has_data = 0; statement->id = zend_list_insert(statement,le_stmt); @@ -1771,7 +1769,6 @@ } statement->error = 0; /* OCI_NO_DATA is NO error for us!!! */ - statement->has_data = 0; return 0; } @@ -1831,16 +1828,12 @@ _oci_make_zval(column->define->zval,statement,column,"OCIFetch",0 TSRMLS_CC); } - statement->has_data = 1; - return 1; } oci_error(statement->pError, func, statement->error); oci_handle_error(statement->conn, statement->error); - statement->has_data = 0; - return 0; } @@ -1855,8 +1848,8 @@ ub4 siz = 0; ub4 readlen = 0; char *buf; + TSRMLS_FETCH(); - *loblen = 0; if (Z_TYPE_P(mydescr) == OCI_DTYPE_FILE) { @@ -1888,17 +1881,17 @@ buf = emalloc(readlen + 1); while (readlen > 0) { /* thies loop should not be entered on readlen == 0 */ - CALL_OCI_RETURN(connection->error, OCILobRead( + CALL_OCI_RETURN(connection->error, OCILobRead( connection->pServiceContext, connection->pError, mydescr->ocidescr, - &readlen, /* IN/OUT bytes toread/read */ + &readlen, + /* IN/OUT bytes toread/read */ siz + 1, /* offset (starts with 1) */ (dvoid *) ((char *) buf + siz), readlen, /* size of buffer */ (dvoid *)0, (OCICallbackLobRead) 0, /* callback... */ - (ub2) 0, /* The character set ID of the buffer data. */ + (ub2) connection->session->charsetId, + /* The character set ID of the buffer data. */ (ub1) SQLCS_IMPLICIT)); /* The character set form of the buffer data. */ siz += readlen; @@ -1911,7 +1904,7 @@ break; } } - + if (connection->error) { oci_error(connection->pError, "OCILobRead", connection->error); oci_handle_error(connection, connection->error); @@ -1936,11 +1929,11 @@ buf = erealloc(buf,siz+1); buf[ siz ] = 0; + oci_debug("OCIloadlob: size=%d",siz); + *buffer = buf; *loblen = siz; - oci_debug("OCIloadlob: size=%d",siz); - return 0; } /* }}} */ @@ -2119,11 +2112,12 @@ */ -static oci_session *_oci_open_session(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,char *charset) { oci_session *session = 0, *psession = 0; OCISvcCtx *svchp = 0; char *hashed_details; + ub2 charsetid; TSRMLS_FETCH(); /* @@ -2172,22 +2166,56 @@ session->server = server; session->exclusive = exclusive; + #ifdef HAVE_OCI9 + //following chunk is Oracle 9i+ ONLY + if (charset != "\0") { + //get ub2 charset id based on charset + //this is pretty secure, since if we don't have a valid character set +name, + //0 comes back and we can still use the 0 in all further statements -> +OCI uses NLS_LANG + //setting in that case + CALL_OCI_RETURN(charsetid, OCINlsCharSetNameToId( + OCI(pEnv), + charset)); + + session->charsetId = charsetid; + oci_debug("oci_do_connect: using charset id=%d",charsetid); + } + + //create an environment using the character set id, Oracle 9i+ ONLY + CALL_OCI(OCIEnvNlsCreate( + &session->pEnv, + OCI_DEFAULT, + 0, + NULL, + NULL, + NULL, + 0, + NULL, + charsetid, + charsetid)); + + #else + //fallback solution (simply use global env and charset) + session->pEnv = OCI(pEnv); + session->charsetId = 0; + + #endif /*HAVE_OCI9*/ + /* allocate temporary Service Context */ CALL_OCI_RETURN(OCI(error), OCIHandleAlloc( - OCI(pEnv), + session->pEnv, (dvoid **)&svchp, OCI_HTYPE_SVCCTX, 0, - NULL)); + NULL)); if (OCI(error) != OCI_SUCCESS) { oci_error(OCI(pError), "_oci_open_session: OCIHandleAlloc OCI_HTYPE_SVCCTX", OCI(error)); goto CLEANUP; } - /* allocate private session-handle */ CALL_OCI_RETURN(OCI(error), OCIHandleAlloc( - OCI(pEnv), + session->pEnv, (dvoid **)&session->pSession, OCI_HTYPE_SESSION, 0, @@ -2305,7 +2333,7 @@ if (session->is_open) { /* Temporary Service Context */ CALL_OCI_RETURN(OCI(error), OCIHandleAlloc( - OCI(pEnv), + session->pEnv, (dvoid **) &svchp, (ub4) OCI_HTYPE_SVCCTX, (size_t) 0, @@ -2365,6 +2393,10 @@ (ub4) OCI_HTYPE_SESSION)); } + CALL_OCI(OCIHandleFree( + (dvoid *)session->pEnv, + OCI_HTYPE_ENV)); + hashed_details = session->hashed_details; if (! OCI(shutdown)) { @@ -2551,13 +2583,26 @@ */ static void oci_do_connect(INTERNAL_FUNCTION_PARAMETERS,int persistent,int exclusive) { - char *username, *password, *dbname; - zval **userParam, **passParam, **dbParam; + char *username, *password, *dbname, *charset; + zval **userParam, **passParam, **dbParam, **charParam; oci_server *server = 0; oci_session *session = 0; oci_connection *connection = 0; - - if (zend_get_parameters_ex(3, &userParam, &passParam, &dbParam) == SUCCESS) { + + charset = "\0"; + //if a forth parameter is handed over, it is the charset identifier (but is only +used in Oracle 9i+) + if (zend_get_parameters_ex(4, &userParam, &passParam, &dbParam, &charParam) == +SUCCESS) { + convert_to_string_ex(userParam); + convert_to_string_ex(passParam); + convert_to_string_ex(dbParam); + convert_to_string_ex(charParam); + + username = Z_STRVAL_PP(userParam); + password = Z_STRVAL_PP(passParam); + dbname = Z_STRVAL_PP(dbParam); + charset = Z_STRVAL_PP(charParam); + oci_debug("oci_do_connect: using charset=%s",charset); + } else if (zend_get_parameters_ex(3, &userParam, &passParam, &dbParam) == +SUCCESS) { convert_to_string_ex(userParam); convert_to_string_ex(passParam); convert_to_string_ex(dbParam); @@ -2577,7 +2622,7 @@ } connection = (oci_connection *) ecalloc(1,sizeof(oci_connection)); - + if (! connection) { goto CLEANUP; } @@ -2596,7 +2641,8 @@ persistent = server->persistent; } - session = _oci_open_session(server,username,password,persistent,exclusive); + session = +_oci_open_session(server,username,password,persistent,exclusive,charset); + if (! session) { goto CLEANUP; @@ -3476,7 +3522,7 @@ } connection->error = - OCILobIsTemporary(OCI(pEnv), + OCILobIsTemporary(connection->session->pEnv, connection->pError, mylob, &is_temporary); @@ -4601,7 +4647,7 @@ oci_debug("OCIfreecollection: coll=%d",inx); CALL_OCI_RETURN(connection->error, OCIObjectFree( - OCI(pEnv), + connection->session->pEnv, connection->pError, (dvoid *)coll->coll, (ub2)(OCI_OBJECTFREE_FORCE))); @@ -4653,7 +4699,7 @@ convert_to_string_ex(arg); if(Z_STRLEN_PP(arg) == 0) { CALL_OCI_RETURN(connection->error, OCICollAppend( - OCI(pEnv), + connection->session->pEnv, connection->pError, (dword *)0, &null_ind, @@ -4686,7 +4732,7 @@ } CALL_OCI_RETURN(connection->error, OCICollAppend( - OCI(pEnv), + connection->session->pEnv, connection->pError, (dvoid *) &dt, (dvoid *) &new_ind, @@ -4702,7 +4748,7 @@ convert_to_string_ex(arg); CALL_OCI_RETURN(connection->error, OCIStringAssignText( - OCI(pEnv), + connection->session->pEnv, connection->pError, Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), @@ -4714,7 +4760,7 @@ } CALL_OCI_RETURN(connection->error, OCICollAppend( - OCI(pEnv), + connection->session->pEnv, connection->pError, (dvoid *) ocistr, (dvoid *) &new_ind, @@ -4751,7 +4797,7 @@ } CALL_OCI_RETURN(connection->error, OCICollAppend( - OCI(pEnv), + connection->session->pEnv, connection->pError, (dvoid *) &num, (dvoid *) &new_ind, @@ -4799,7 +4845,7 @@ connection = coll->conn; CALL_OCI_RETURN(connection->error, OCICollGetElem( - OCI(pEnv), + connection->session->pEnv, connection->pError, coll->coll, ndx, @@ -4839,7 +4885,7 @@ RETURN_STRINGL(buff,len,1); case OCI_TYPECODE_VARCHAR2 : ocistr = *(OCIString **)elem; - str = OCIStringPtr(OCI(pEnv),ocistr); /* XXX not protected against recursion! */ + str = OCIStringPtr(connection->session->pEnv,ocistr); /* +XXX not protected against recursion! */ RETURN_STRINGL(str,strlen(str),1); break; case OCI_TYPECODE_UNSIGNED16 : /* UNSIGNED SHORT */ @@ -4898,7 +4944,7 @@ connection = coll->conn; CALL_OCI_RETURN(connection->error, OCICollAssign( - OCI(pEnv), + connection->session->pEnv, connection->pError, from_coll->coll, coll->coll)); @@ -4958,7 +5004,7 @@ if(Z_STRLEN_PP(val) == 0) { CALL_OCI_RETURN(connection->error, OCICollAssignElem( - OCI(pEnv), + connection->session->pEnv, connection->pError, ndx, (dword *)0, @@ -4991,7 +5037,7 @@ } CALL_OCI_RETURN(connection->error, OCICollAssignElem( - OCI(pEnv), + connection->session->pEnv, connection->pError, ndx, (dword *)&dt, @@ -5007,7 +5053,7 @@ convert_to_string_ex(val); CALL_OCI_RETURN(connection->error, OCIStringAssignText( - OCI(pEnv), + connection->session->pEnv, connection->pError, Z_STRVAL_PP(val), Z_STRLEN_PP(val), @@ -5019,7 +5065,7 @@ } CALL_OCI_RETURN(connection->error, OCICollAssignElem( - OCI(pEnv), + connection->session->pEnv, connection->pError, ndx, (dword *)ocistr, @@ -5058,7 +5104,7 @@ } CALL_OCI_RETURN(connection->error, OCICollAssignElem( - OCI(pEnv), + connection->session->pEnv, connection->pError, ndx, (dword *)&num, @@ -5095,7 +5141,7 @@ connection = coll->conn; CALL_OCI_RETURN(connection->error, OCICollSize( - OCI(pEnv), + connection->session->pEnv, coll->conn->pError, coll->coll, &sz)); @@ -5198,7 +5244,7 @@ zend_list_addref(connection->id); CALL_OCI_RETURN(connection->error, OCITypeByName( - OCI(pEnv), + connection->session->pEnv, connection->pError, connection->pServiceContext, ac==3?(text *)Z_STRVAL_PP(schema):(text *)0, @@ -5217,7 +5263,7 @@ } CALL_OCI_RETURN(connection->error, OCIHandleAlloc( - OCI(pEnv), + connection->session->pEnv, (dvoid **) &dschp1, (ub4) OCI_HTYPE_DESCRIBE, (size_t) 0, @@ -5301,7 +5347,7 @@ } CALL_OCI_RETURN(connection->error, OCITypeByRef( - OCI(pEnv), + connection->session->pEnv, connection->pError, coll->elem_ref, OCI_DURATION_SESSION, @@ -5333,7 +5379,7 @@ /* Create object to hold return table */ CALL_OCI_RETURN(connection->error, OCIObjectNew( - OCI(pEnv), + connection->session->pEnv, connection->pError, connection->pServiceContext, OCI_TYPECODE_TABLE,
--- php_oci8.h Thu Sep 12 11:48:03 2002 +++ php_oci8.h Thu Oct 17 13:46:52 2002 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_oci8.h,v 1.24 2002/09/12 09:48:03 thies Exp $ */ +/* $Id: php_oci8.h,v 1.23 2002/02/10 12:41:52 thies Exp $ */ #if HAVE_OCI8 # ifndef PHP_OCI8_H @@ -69,7 +69,9 @@ int exclusive; char *hashed_details; oci_server *server; - OCISession *pSession; + OCIEnv *pEnv; //sessions own environment + OCISession *pSession; + ub2 charsetId; //sessions used character set (mostly +this will be 0, so NLS_LANG will be used. } oci_session; typedef struct {
--- config.m4.orig Thu Oct 17 13:27:52 2002 +++ config.m4 Thu Oct 17 13:28:02 2002 @@ -66,7 +66,7 @@ PHP_ADD_LIBRARY_WITH_PATH(clntsh, $OCI8_DIR/lib, OCI8_SHARED_LIBADD) ;; - 8.1|9.0) + 8.1) PHP_ADD_LIBRARY(clntsh, 1, OCI8_SHARED_LIBADD) if test -f $OCI8_DIR/lib/libocijdbc8.so ; then PHP_ADD_LIBRARY(ocijdbc8, 1, OCI8_SHARED_LIBADD) @@ -75,6 +75,18 @@ AC_DEFINE(HAVE_OCI8_TEMP_LOB,1,[ ]) AC_DEFINE(HAVE_OCI8_ATTR_STATEMENT,1,[ ]) ;; + + 9.0) + PHP_ADD_LIBRARY(clntsh, 1, OCI8_SHARED_LIBADD) + if test -f $OCI8_DIR/lib/libocijdbc8.so ; then + PHP_ADD_LIBRARY(ocijdbc8, 1, OCI8_SHARED_LIBADD) + fi + PHP_ADD_LIBPATH($OCI8_DIR/lib, OCI8_SHARED_LIBADD) + AC_DEFINE(HAVE_OCI8_TEMP_LOB,1,[ ]) + AC_DEFINE(HAVE_OCI8_ATTR_STATEMENT,1,[ ]) + AC_DEFINE(HAVE_OCI9,1,[]) + ;; + *) AC_MSG_ERROR(Unsupported Oracle version!)
-- PHP Development Mailing List <http://www.php.net/> To unsubscribe, visit: http://www.php.net/unsub.php