diff options
author | Thies C. Arntzen <thies@php.net> | 2000-08-07 11:34:48 +0000 |
---|---|---|
committer | Thies C. Arntzen <thies@php.net> | 2000-08-07 11:34:48 +0000 |
commit | 8289c85438c21aa3658a9998825ced758d6d00d6 (patch) | |
tree | aca1fda99752990165943e8536d8beb21805693a /ext/oci8 | |
parent | 635532053e1e60a3a7c8fe81f3bde7cf8296d1aa (diff) | |
download | php-git-8289c85438c21aa3658a9998825ced758d6d00d6.tar.gz |
@- Fixed CLOB handling in OCI8 driver when using variable-width
@ character sets. (Thies)
Diffstat (limited to 'ext/oci8')
-rw-r--r-- | ext/oci8/oci8.c | 114 |
1 files changed, 64 insertions, 50 deletions
diff --git a/ext/oci8/oci8.c b/ext/oci8/oci8.c index f550fc94ab..507acd718d 100644 --- a/ext/oci8/oci8.c +++ b/ext/oci8/oci8.c @@ -129,7 +129,7 @@ static int _oci_make_zval(zval *, oci_statement *, oci_out_column *, char *, int 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 *); -static ub4 oci_loadlob(oci_connection *, oci_descriptor *, char **); +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); @@ -487,6 +487,7 @@ PHP_MINFO_FUNCTION(oci) php_info_print_table_start(); php_info_print_table_row(2, "OCI8 Support", "enabled"); + php_info_print_table_row(2, "Revision", "$Revision$"); #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 ); @@ -992,12 +993,12 @@ _oci_make_zval(zval *value,oci_statement *statement,oci_out_column *column, char return -1; } - loblen = oci_loadlob(statement->conn,descr,&buffer); + oci_loadlob(statement->conn,descr,&buffer,&loblen); if (loblen >= 0) { ZVAL_STRINGL(value,buffer,loblen,0); } else { - /*ÜXXX is this an error? */ + /* XXX is this an error? */ ZVAL_BOOL(value,0); } } else { @@ -1544,33 +1545,18 @@ oci_fetch(oci_statement *statement, ub4 nrows, char *func) /* }}} */ /* {{{ oci_loadlob() */ -static ub4 -oci_loadlob(oci_connection *connection, oci_descriptor *mydescr, char **buffer) -{ - ub4 loblen; - - connection->error = - OCILobGetLength(connection->pServiceContext, - connection->pError, - mydescr->ocidescr, - &loblen); - if (connection->error) { - oci_error(connection->pError, "OCILobGetLength", connection->error); - return -1; - } - - *buffer = emalloc(loblen + 1); +#define LOBREADSIZE 1048576l /* 1MB */ - if (! buffer) { - return -1; - } - - if (loblen == 0) { - (*buffer)[ 0 ] = 0; - return 0; - } +static int +oci_loadlob(oci_connection *connection, oci_descriptor *mydescr, char **buffer,ub4 *loblen) +{ + ub4 siz = 0; + ub4 readlen; + char *buf; + *loblen = 0; + if (mydescr->type == OCI_DTYPE_FILE) { connection->error = OCILobFileOpen(connection->pServiceContext, @@ -1579,27 +1565,52 @@ oci_loadlob(oci_connection *connection, oci_descriptor *mydescr, char **buffer) OCI_FILE_READONLY); if (connection->error) { oci_error(connection->pError, "OCILobFileOpen",connection->error); - efree(buffer); return -1; } } - - connection->error = - OCILobRead(connection->pServiceContext, - connection->pError, - mydescr->ocidescr, - &loblen, /* IN/OUT bytes toread/read */ - 1, /* offset (starts with 1) */ - (dvoid *) *buffer, - loblen, /* size of buffer */ - (dvoid *)0, - (OCICallbackLobRead) 0, /* callback... */ - (ub2) 0, /* The character set ID of the buffer data. */ - (ub1) SQLCS_IMPLICIT); /* The character set form of the buffer data. */ - + + + connection->error = + OCILobGetLength(connection->pServiceContext, + connection->pError, + mydescr->ocidescr, + &readlen); + + if (connection->error) { + oci_error(connection->pError, "OCILobFileOpen",connection->error); + return -1; + } + + buf = emalloc(readlen + 1); + + do { + connection->error = + OCILobRead(connection->pServiceContext, + connection->pError, + mydescr->ocidescr, + &readlen, /* IN/OUT bytes toread/read */ + siz + 1, /* offset (starts with 1) */ + (dvoid *) buf + siz, + readlen, /* size of buffer */ + (dvoid *)0, + (OCICallbackLobRead) 0, /* callback... */ + (ub2) 0, /* The character set ID of the buffer data. */ + (ub1) SQLCS_IMPLICIT); /* The character set form of the buffer data. */ + + siz += readlen; + readlen = LOBREADSIZE; + + if (connection->error == OCI_NEED_DATA) { + buf = erealloc(buf,siz + LOBREADSIZE + 1); + continue; + } else { + break; + } + } while (1); + if (connection->error) { oci_error(connection->pError, "OCILobRead", connection->error); - efree(buffer); + efree(buf); return -1; } @@ -1610,18 +1621,21 @@ oci_loadlob(oci_connection *connection, oci_descriptor *mydescr, char **buffer) mydescr->ocidescr); if (connection->error) { oci_error(connection->pError, "OCILobFileClose", connection->error); - efree(buffer); + efree(buf); return -1; } } - - (*buffer)[ loblen ] = 0; - oci_debug("OCIloadlob: size=%d",loblen); + buf = erealloc(buf,siz+1); + buf[ siz ] = 0; - return loblen; -} + *buffer = buf; + *loblen = siz; + + oci_debug("OCIloadlob: size=%d",siz); + return 0; +} /* }}} */ /* {{{ oci_failover_callback() */ #if 0 /* not needed yet ! */ @@ -2743,7 +2757,7 @@ PHP_FUNCTION(ociloadlob) connection = descr->conn; - loblen = oci_loadlob(connection,descr,&buffer); + oci_loadlob(connection,descr,&buffer,&loblen); if (loblen >= 0) { RETURN_STRINGL(buffer,loblen,0); |