summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThies C. Arntzen <thies@php.net>1999-10-27 17:51:22 +0000
committerThies C. Arntzen <thies@php.net>1999-10-27 17:51:22 +0000
commitc171eecd7aea11c22a8d7b111fc6b8a34b243216 (patch)
treeabdd90e18bff5d37d8877cdcfa776c866a74a3f0
parent1a2f656816e4f0d2ea302da091f4fb0194408f29 (diff)
downloadphp-git-c171eecd7aea11c22a8d7b111fc6b8a34b243216.tar.gz
@- implemented OCI8 $lob->WriteToFile() function - very useful for streaming
@ large amounts of LOB-Data without to need of a huge buffer. (Thies)
-rw-r--r--ext/oci8/oci8.c202
1 files changed, 198 insertions, 4 deletions
diff --git a/ext/oci8/oci8.c b/ext/oci8/oci8.c
index f68f45b642..83c82edd9f 100644
--- a/ext/oci8/oci8.c
+++ b/ext/oci8/oci8.c
@@ -169,6 +169,7 @@ PHP_FUNCTION(ocifreedesc);
PHP_FUNCTION(ocisavelob);
PHP_FUNCTION(ocisavelobfile);
PHP_FUNCTION(ociloadlob);
+PHP_FUNCTION(ociwritelobtofile);
PHP_FUNCTION(ocicommit);
PHP_FUNCTION(ocirollback);
PHP_FUNCTION(ocinewdescriptor);
@@ -237,6 +238,7 @@ static zend_function_entry php_oci_functions[] = {
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)
@@ -245,10 +247,11 @@ static zend_function_entry php_oci_functions[] = {
};
static zend_function_entry php_oci_lob_class_functions[] = {
- PHP_FALIAS(load, ociloadlob, NULL)
- PHP_FALIAS(save, ocisavelob, NULL)
- PHP_FALIAS(savefile,ocisavelobfile, NULL)
- PHP_FALIAS(free, ocifreedesc, NULL)
+ PHP_FALIAS(load, ociloadlob, NULL)
+ PHP_FALIAS(writetofile, ociwritelobtofile,NULL)
+ PHP_FALIAS(save, ocisavelob, NULL)
+ PHP_FALIAS(savefile, ocisavelobfile, NULL)
+ PHP_FALIAS(free, ocifreedesc, NULL)
{NULL,NULL,NULL}
};
@@ -2616,6 +2619,197 @@ PHP_FUNCTION(ociloadlob)
RETURN_FALSE;
}
/* }}} */
+/* {{{ proto void ociwritelobtofile(object lob [,string filename][,int start][,int length])
+ */
+
+PHP_FUNCTION(ociwritelobtofile)
+{
+ pval *id, **tmp, **conn, **zfilename, **zstart, **zlength;
+ char *filename = NULL;
+ int start = -1;
+ ub4 length = -1;
+ oci_connection *connection;
+ oci_descriptor *descr;
+ char *buffer;
+ ub4 loblen;
+ int ac = ARG_COUNT(ht);
+ int fp = -1;
+ OCILobLocator *mylob;
+ int coffs;
+
+ if ((id = getThis()) != 0) {
+ if (zend_hash_find(id->value.obj.properties, "connection", sizeof("connection"), (void **)&conn) == FAILURE) {
+ php_error(E_WARNING, "unable to find my statement property");
+ RETURN_FALSE;
+ }
+
+ OCI_GET_CONN(connection,conn);
+
+ if (zend_hash_find(id->value.obj.properties, "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
+ php_error(E_WARNING, "unable to find my locator property");
+ RETURN_FALSE;
+ }
+
+ if (zend_hash_index_find(connection->descriptors, (*tmp)->value.lval, (void **)&descr) == FAILURE) {
+ php_error(E_WARNING, "unable to find my descriptor %d",(*tmp)->value.lval);
+ RETURN_FALSE;
+ }
+
+ mylob = (OCILobLocator *) descr->ocidescr;
+
+ if (! mylob) {
+ RETURN_FALSE;
+ }
+
+ if (ac < 0 || ac > 3 || getParametersEx(ac, &zfilename, &zstart, &zlength) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ switch (ac) {
+ case 3:
+ convert_to_long_ex(zlength);
+ length = (*zlength)->value.lval;
+ case 2:
+ convert_to_long_ex(zstart);
+ start = (*zstart)->value.lval;
+ case 1:
+ convert_to_string_ex(zfilename);
+ filename = (*zfilename)->value.str.val;
+ }
+
+ if (filename && *filename) {
+ if (_php3_check_open_basedir(filename)) {
+ goto bail;
+ }
+
+ if ((fp = open(filename,O_CREAT|O_TRUNC|O_WRONLY)) == -1) {
+ php_error(E_WARNING, "Can't create file %s", filename);
+ goto bail;
+ }
+ }
+
+ connection->error =
+ OCILobGetLength(connection->pServiceContext,
+ connection->pError,
+ descr->ocidescr,
+ &loblen);
+
+ if (connection->error) {
+ oci_error(connection->pError, "OCILobGetLength", connection->error);
+ goto bail;
+ }
+
+ if (descr->type == OCI_DTYPE_FILE) {
+ connection->error =
+ OCILobFileOpen(connection->pServiceContext,
+ connection->pError,
+ descr->ocidescr,
+ OCI_FILE_READONLY);
+ if (connection->error) {
+ oci_error(connection->pError, "OCILobFileOpen",connection->error);
+ goto bail;
+ }
+ }
+
+ if (start == -1) {
+ start = 0;
+ }
+
+ if (length == -1) {
+ length = loblen - start;
+ }
+
+ if ((start + length) > loblen) {
+ length = loblen - start;
+ }
+
+#define OCI_LOB_READ_BUFFER 128*1024
+
+ buffer = emalloc(OCI_LOB_READ_BUFFER);
+
+ coffs = start;
+
+ oci_debug("ociwritelobtofile(start = %d, length = %d, loblen = %d",start,length,loblen);
+
+ while (length > 0) {
+ ub4 toread;
+
+ if (length > OCI_LOB_READ_BUFFER) {
+ toread = OCI_LOB_READ_BUFFER;
+ } else {
+ toread = length;
+ }
+
+ oci_debug("OCILobRead(coffs = %d, toread = %d",coffs,toread);
+
+ connection->error =
+ OCILobRead(connection->pServiceContext,
+ connection->pError,
+ descr->ocidescr,
+ &toread, /* IN/OUT bytes toread/read */
+ coffs+1, /* offset (starts with 1) */
+ (dvoid *) buffer,
+ toread, /* 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. */
+
+ oci_debug("OCILobRead(read - %d",toread);
+
+ if (connection->error) {
+ oci_error(connection->pError, "OCILobRead", connection->error);
+ goto bail;
+ }
+
+ if (fp != -1) {
+ if (write(fp,buffer,toread) != toread) {
+ php_error(E_WARNING, "cannot write file!");
+ goto bail;
+ }
+ } else {
+ if (php3_header()) {
+ PHPWRITE(buffer,toread);
+ }
+ }
+
+ length -= toread;
+ coffs += toread;
+ }
+
+ efree(buffer);
+ buffer = 0;
+
+ if (fp != -1) {
+ close(fp);
+ fp = 0;
+ }
+
+ if (descr->type == OCI_DTYPE_FILE) {
+ connection->error =
+ OCILobFileClose(connection->pServiceContext,
+ connection->pError,
+ descr->ocidescr);
+ if (connection->error) {
+ oci_error(connection->pError, "OCILobFileClose", connection->error);
+ goto bail;
+ }
+ }
+ RETURN_TRUE;
+ }
+
+ bail:
+ if (fp != -1) {
+ close(fp);
+ }
+
+ if (buffer) {
+ efree(buffer);
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
/* {{{ proto string OCINewDescriptor(int connection [,int type ])
initialize a new empty descriptor LOB/FILE (LOB is default)
*/