summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorAntony Dovgal <tony2001@php.net>2006-04-05 14:06:00 +0000
committerAntony Dovgal <tony2001@php.net>2006-04-05 14:06:00 +0000
commit569ce842f16f7b064f51146be616fad349d0a7a3 (patch)
treeb73714307917c2980a9075ffed560ff2fd3c0b74 /ext
parentc0592d17e9542e2cea0088c133a58cc11d4edf08 (diff)
downloadphp-git-569ce842f16f7b064f51146be616fad349d0a7a3.tar.gz
fix #36934 (OCILob->read() doesn't move internal pointer when reading 0's)
Diffstat (limited to 'ext')
-rw-r--r--ext/oci8/config.m49
-rw-r--r--ext/oci8/oci8_lob.c73
-rw-r--r--ext/oci8/php_oci8_int.h2
3 files changed, 75 insertions, 9 deletions
diff --git a/ext/oci8/config.m4 b/ext/oci8/config.m4
index 52d3a871de..00af24fd58 100644
--- a/ext/oci8/config.m4
+++ b/ext/oci8/config.m4
@@ -232,6 +232,13 @@ if test "$PHP_OCI8" != "no" && test "$PHP_OCI8_INSTANT_CLIENT" = "no"; then
], [], [
-L$OCI8_DIR/$OCI8_LIB_DIR $OCI8_SHARED_LIBADD
])
+
+ PHP_CHECK_LIBRARY(clntsh, OCILobRead2,
+ [
+ AC_DEFINE(HAVE_OCI_LOB_READ2,1,[ ])
+ ], [], [
+ -L$OCI8_DIR/$OCI8_LIB_DIR $OCI8_SHARED_LIBADD
+ ])
;;
@@ -242,6 +249,7 @@ if test "$PHP_OCI8" != "no" && test "$PHP_OCI8_INSTANT_CLIENT" = "no"; then
AC_DEFINE(HAVE_OCI_ENV_NLS_CREATE,1,[ ])
AC_DEFINE(HAVE_OCI_ENV_CREATE,1,[ ])
AC_DEFINE(HAVE_OCI_STMT_PREPARE2,1,[ ])
+ AC_DEFINE(HAVE_OCI_LOB_READ2,1,[ ])
AC_DEFINE(HAVE_OCI8_TEMP_LOB,1,[ ])
AC_DEFINE(PHP_OCI8_HAVE_COLLECTIONS,1,[ ])
;;
@@ -354,6 +362,7 @@ dnl Header directory for manual installation
AC_DEFINE(HAVE_OCI_ENV_NLS_CREATE,1,[ ])
AC_DEFINE(HAVE_OCI_ENV_CREATE,1,[ ])
AC_DEFINE(HAVE_OCI_STMT_PREPARE2,1,[ ])
+ AC_DEFINE(HAVE_OCI_LOB_READ2,1,[ ])
AC_DEFINE(HAVE_OCI8_TEMP_LOB,1,[ ])
AC_DEFINE(PHP_OCI8_HAVE_COLLECTIONS,1,[ ])
diff --git a/ext/oci8/oci8_lob.c b/ext/oci8/oci8_lob.c
index c64d06a51c..af9de8341a 100644
--- a/ext/oci8/oci8_lob.c
+++ b/ext/oci8/oci8_lob.c
@@ -150,8 +150,11 @@ int php_oci_lob_read (php_oci_descriptor *descriptor, long read_length, long ini
{
php_oci_connection *connection = descriptor->connection;
ub4 length = 0;
- int bytes_read, bytes_total = 0, offset = 0, data_len_chars = 0;
+ int bytes_read, bytes_total = 0, offset = 0;
int requested_len = read_length; /* this is by default */
+#if defined(HAVE_OCI_LOB_READ2)
+ int chars_read = 0, is_clob = 0;
+#endif
*data_len = 0;
*data = NULL;
@@ -190,6 +193,23 @@ int php_oci_lob_read (php_oci_descriptor *descriptor, long read_length, long ini
return 1;
}
}
+#ifdef HAVE_OCI_LOB_READ2
+ else {
+ ub2 charset_id = 0;
+
+ connection->errcode = PHP_OCI_CALL(OCILobCharSetId, (connection->env, connection->err, descriptor->descriptor, &charset_id));
+
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
+ return 1;
+ }
+
+ if (charset_id > 0) { /* charset_id is always > 0 for [N]CLOBs */
+ is_clob = 1;
+ }
+ }
+#endif
*data = (char *)emalloc(requested_len + 1);
bytes_read = requested_len;
@@ -198,7 +218,46 @@ int php_oci_lob_read (php_oci_descriptor *descriptor, long read_length, long ini
/* TODO
* We need to make sure this function works with Unicode LOBs
* */
-
+
+#if defined(HAVE_OCI_LOB_READ2)
+
+ do {
+ chars_read = 0;
+ connection->errcode = PHP_OCI_CALL(OCILobRead2,
+ (
+ connection->svc,
+ connection->err,
+ descriptor->descriptor,
+ (oraub8 *)&bytes_read, /* IN/OUT bytes toread/read */
+ (oraub8 *)&chars_read,
+ (oraub8) offset + 1, /* offset (starts with 1) */
+ (dvoid *) ((char *) *data + *data_len),
+ (oraub8) requested_len, /* size of buffer */
+ 0,
+ NULL,
+ (OCICallbackLobRead2) 0, /* callback... */
+ (ub2) connection->charset, /* The character set ID of the buffer data. */
+ (ub1) SQLCS_IMPLICIT /* The character set form of the buffer data. */
+ )
+ );
+
+ bytes_total += bytes_read;
+ if (is_clob) {
+ offset += chars_read;
+ } else {
+ offset += bytes_read;
+ }
+
+ *data_len += bytes_read;
+
+ if (connection->errcode != OCI_NEED_DATA) {
+ break;
+ }
+ *data = erealloc(*data, *data_len + PHP_OCI_LOB_BUFFER_SIZE + 1);
+ } while (connection->errcode == OCI_NEED_DATA);
+
+#else
+
do {
connection->errcode = PHP_OCI_CALL(OCILobRead,
(
@@ -217,11 +276,7 @@ int php_oci_lob_read (php_oci_descriptor *descriptor, long read_length, long ini
);
bytes_total += bytes_read;
- /*
- * Oracle doesn't tell use how many CHARS were read,
- * so we have to count them to get the correct offset for CLOBS */
- data_len_chars = OCIMultiByteStrnDisplayLength(connection->env, *data, bytes_total);
- offset = initial_offset + data_len_chars;
+ offset += bytes_read;
*data_len += bytes_read;
@@ -231,6 +286,8 @@ int php_oci_lob_read (php_oci_descriptor *descriptor, long read_length, long ini
*data = erealloc(*data, *data_len + PHP_OCI_LOB_BUFFER_SIZE + 1);
} while (connection->errcode == OCI_NEED_DATA);
+#endif
+
if (connection->errcode != OCI_SUCCESS) {
php_oci_error(connection->err, connection->errcode TSRMLS_CC);
PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
@@ -239,7 +296,7 @@ int php_oci_lob_read (php_oci_descriptor *descriptor, long read_length, long ini
return 1;
}
- descriptor->lob_current_position += data_len_chars;
+ descriptor->lob_current_position = offset;
if (descriptor->type == OCI_DTYPE_FILE) {
connection->errcode = PHP_OCI_CALL(OCILobFileClose, (connection->svc, connection->err, descriptor->descriptor));
diff --git a/ext/oci8/php_oci8_int.h b/ext/oci8/php_oci8_int.h
index 0553bc70b9..94da6eed2a 100644
--- a/ext/oci8/php_oci8_int.h
+++ b/ext/oci8/php_oci8_int.h
@@ -78,7 +78,7 @@ extern zend_class_entry *oci_coll_class_entry_ptr;
#define PHP_OCI_MAX_NAME_LEN 64
#define PHP_OCI_MAX_DATA_SIZE INT_MAX
#define PHP_OCI_PIECE_SIZE (64*1024)-1
-#define PHP_OCI_LOB_BUFFER_SIZE 1048576l
+#define PHP_OCI_LOB_BUFFER_SIZE 32768
#define PHP_OCI_ASSOC 1<<0
#define PHP_OCI_NUM 1<<1