thies Fri Apr 13 07:43:40 2001 EDT
Modified files:
/php4/ext/oci8 oci8.c php_oci8.h
Log:
@ - OCI8 now supports binding of collections
@ (Patch by Andy Sautins <[EMAIL PROTECTED]>)
Index: php4/ext/oci8/oci8.c
diff -u php4/ext/oci8/oci8.c:1.114 php4/ext/oci8/oci8.c:1.115
--- php4/ext/oci8/oci8.c:1.114 Wed Apr 11 08:46:03 2001
+++ php4/ext/oci8/oci8.c Fri Apr 13 07:43:39 2001
@@ -14,10 +14,12 @@
+----------------------------------------------------------------------+
| Authors: Stig S�ther Bakken <[EMAIL PROTECTED]> |
| Thies C. Arntzen <[EMAIL PROTECTED]>
|
+ |
+ |
+ | Collection support by Andy Sautins <[EMAIL PROTECTED]> |
+----------------------------------------------------------------------+
*/
-/* $Id: oci8.c,v 1.114 2001/04/11 15:46:03 thies Exp $ */
+/* $Id: oci8.c,v 1.115 2001/04/13 14:43:39 thies Exp $ */
/* TODO list:
*
@@ -53,6 +55,8 @@
#include "ext/standard/head.h"
#include "ext/standard/info.h"
+#define WITH_COLLECTIONS 1
+
#if HAVE_OCI8
#include "php_oci8.h"
@@ -61,9 +65,15 @@
static int le_conn;
static int le_stmt;
static int le_desc;
+#ifdef WITH_COLLECTIONS
+static int le_coll;
+#endif
static int le_server;
static int le_session;
static zend_class_entry *oci_lob_class_entry_ptr;
+#ifdef WITH_COLLECTIONS
+static zend_class_entry *oci_coll_class_entry_ptr;
+#endif
#ifndef SQLT_BFILEE
#define SQLT_BFILEE 114
@@ -117,6 +127,9 @@
static void _oci_conn_list_dtor(oci_connection *connection);
static void _oci_stmt_list_dtor(zend_rsrc_list_entry *rsrc);
static void _oci_descriptor_list_dtor(zend_rsrc_list_entry *rsrc);
+#ifdef WITH_COLLECTIONS
+static void _oci_coll_list_dtor(zend_rsrc_list_entry *rsrc);
+#endif
static void _oci_server_list_dtor(zend_rsrc_list_entry *rsrc);
static void _oci_session_list_dtor(zend_rsrc_list_entry *rsrc);
static void php_oci_free_conn_list(zend_rsrc_list_entry *rsrc);
@@ -128,6 +141,10 @@
static oci_connection *oci_get_conn(zval **);
static oci_statement *oci_get_stmt(zval **);
static oci_descriptor *oci_get_desc(int);
+#ifdef WITH_COLLECTIONS
+/* Questionable name. Very close to oci_get_col */
+static oci_collection *oci_get_coll(int);
+#endif
static oci_out_column *oci_get_col(oci_statement *, int, zval **);
static int _oci_make_zval(zval *, oci_statement *, oci_out_column *, char *, int
mode);
@@ -192,6 +209,20 @@
PHP_FUNCTION(ocistatementtype);
PHP_FUNCTION(ocirowcount);
PHP_FUNCTION(ocisetprefetch);
+#ifdef WITH_COLLECTIONS
+PHP_FUNCTION(ocinewcollection);
+PHP_FUNCTION(ocifreecoll);
+PHP_FUNCTION(ocicollappend);
+PHP_FUNCTION(ocicollgetelem);
+PHP_FUNCTION(ocicollassignelem);
+PHP_FUNCTION(ocicollassign);
+PHP_FUNCTION(ocicollsize);
+PHP_FUNCTION(ocicollmax);
+PHP_FUNCTION(ocicolltrim);
+PHP_FUNCTION(ocicolldategetelem);
+PHP_FUNCTION(ocicolldateassignelem);
+PHP_FUNCTION(ocicolldateappendelem);
+#endif
#define OCI_GET_STMT(statement,value) \
statement = oci_get_stmt(value); \
@@ -211,6 +242,14 @@
RETURN_FALSE; \
}
+#ifdef WITH_COLLECTIONS
+#define OCI_GET_COLL(collection,index) \
+ collection = oci_get_coll(index); \
+ if (collection == NULL) { \
+ RETURN_FALSE; \
+ }
+#endif
+
/* }}} */
/* {{{ extension definition structures */
@@ -262,6 +301,20 @@
PHP_FE(ocirollback, NULL)
PHP_FE(ocinewdescriptor, NULL)
PHP_FE(ocisetprefetch, NULL)
+#ifdef WITH_COLLECTIONS
+ PHP_FE(ocifreecoll, NULL)
+ PHP_FE(ocicollappend, NULL)
+ PHP_FE(ocicollgetelem, NULL)
+ PHP_FE(ocicolldategetelem,NULL)
+ PHP_FE(ocicolldateassignelem,NULL)
+ PHP_FE(ocicolldateappendelem,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)
@@ -277,6 +330,23 @@
{NULL,NULL,NULL}
};
+#ifdef WITH_COLLECTIONS
+static zend_function_entry php_oci_coll_class_functions[] = {
+ PHP_FALIAS(append, ocicollappend, NULL)
+ PHP_FALIAS(getelem, ocicollgetelem, NULL)
+ PHP_FALIAS(dategetelem, ocicolldategetelem, NULL)
+ PHP_FALIAS(dateassignelem, ocicolldateassignelem, NULL)
+ PHP_FALIAS(dateappendelem, ocicolldateappendelem, 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, ocifreecoll, NULL)
+ {NULL,NULL,NULL}
+};
+#endif
+
zend_module_entry oci8_module_entry = {
"oci8", /* extension name */
php_oci_functions, /* extension function list */
@@ -341,17 +411,15 @@
PHP_MINIT_FUNCTION(oci)
{
zend_class_entry oci_lob_class_entry;
+#ifdef WITH_COLLECTIONS
+ zend_class_entry oci_coll_class_entry;
+#endif
-/* XXX Joe Brown says OCI_THREADED breaks windows, assuming the same is true for unix
- tc
-#ifdef ZTS
-#define PHP_OCI_INIT_MODE OCI_THREADED
+#ifdef WITH_COLLECTIONS
+#define PHP_OCI_INIT_MODE OCI_DEFAULT | OCI_OBJECT
#else
-*/
#define PHP_OCI_INIT_MODE OCI_DEFAULT
-
-/*
#endif
-*/
#if OCI_USE_EMALLOC
OCIInitialize(PHP_OCI_INIT_MODE, NULL, ocimalloc, ocirealloc, ocifree);
@@ -368,12 +436,21 @@
le_stmt = zend_register_list_destructors_ex(_oci_stmt_list_dtor, NULL, "oci8
statement", module_number);
le_conn = zend_register_list_destructors_ex(php_oci_free_conn_list, NULL,
"oci8 connection", module_number);
le_desc = zend_register_list_destructors_ex(_oci_descriptor_list_dtor, NULL,
"oci8 descriptor", module_number);
+#ifdef WITH_COLLECTIONS
+ le_coll = zend_register_list_destructors_ex(_oci_coll_list_dtor, NULL, "oci8
+collection", module_number);
+#endif
le_server = zend_register_list_destructors_ex(_oci_server_list_dtor, NULL,
"oci8 server", module_number);
le_session = zend_register_list_destructors_ex(_oci_session_list_dtor, NULL,
"oci8 session", module_number);
INIT_CLASS_ENTRY(oci_lob_class_entry, "OCI-Lob", php_oci_lob_class_functions);
+#ifdef WITH_COLLECTIONS
+ INIT_CLASS_ENTRY(oci_coll_class_entry, "OCI-Collection",
+php_oci_coll_class_functions);
+#endif
oci_lob_class_entry_ptr = zend_register_internal_class(&oci_lob_class_entry);
+#ifdef WITH_COLLECTIONS
+ oci_coll_class_entry_ptr = zend_register_internal_class(&oci_coll_class_entry);
+#endif
/* [EMAIL PROTECTED] 990203 i do not think that we will need all of them - just in
here for completeness for now! */
REGISTER_LONG_CONSTANT("OCI_DEFAULT",OCI_DEFAULT, CONST_CS | CONST_PERSISTENT);
@@ -388,6 +465,11 @@
REGISTER_LONG_CONSTANT("SQLT_BLOB",SQLT_BLOB, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("SQLT_RDD",SQLT_RDD, CONST_CS | CONST_PERSISTENT);
+#ifdef WITH_COLLECTIONS
+ REGISTER_LONG_CONSTANT("OCI_B_SQLT_NTY",SQLT_NTY, CONST_CS | CONST_PERSISTENT);
+ REGISTER_STRING_CONSTANT("OCI_SYSDATE","SYSDATE",CONST_PERSISTENT);
+#endif
+
REGISTER_LONG_CONSTANT("OCI_B_BFILE",SQLT_BFILEE, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("OCI_B_CFILEE",SQLT_CFILEE, CONST_CS |
CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("OCI_B_CLOB",SQLT_CLOB, CONST_CS | CONST_PERSISTENT);
@@ -494,7 +576,7 @@
php_info_print_table_start();
php_info_print_table_row(2, "OCI8 Support", "enabled");
- php_info_print_table_row(2, "Revision", "$Revision: 1.114 $");
+ php_info_print_table_row(2, "Revision", "$Revision: 1.115 $");
#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 );
@@ -689,6 +771,29 @@
_oci_conn_list_dtor(conn);
}
+#ifdef WITH_COLLECTIONS
+
+/* {{{ _oci_coll_list_dtor()
+ */
+
+static void
+_oci_coll_list_dtor(zend_rsrc_list_entry *rsrc)
+{
+ oci_collection *coll = (oci_collection *)rsrc->ptr;
+ oci_debug("START _oci_coll_list_dtor: %d",coll->id);
+
+ zend_list_delete(coll->conn->id);
+ // Note sure if we need to free the object. Have an
+ // oracle TAR out on this one.
+ // OCIDescriptorFree(descr->ocidescr, descr->type);
+
+ oci_debug("END _oci_coll_list_dtor: %d",coll->id);
+
+ efree(coll);
+}
+
+#endif
+
/* {{{ _oci_descriptor_list_dtor()
*/
@@ -973,7 +1078,32 @@
return descr;
}
+#ifdef WITH_COLLECTIONS
+
+/* {{{ _oci_get_ocicoll() */
+
+static int
+_oci_get_ocicoll(zval *id,oci_collection **collection)
+{
+ zval **coll;
+
+ if (zend_hash_find(id->value.obj.properties, "collection", sizeof("collection"),
+(void **)&coll) == FAILURE) {
+ php_error(E_WARNING, "cannot find collection");
+ return 0;
+ }
+ if ((*collection = oci_get_coll((*coll)->value.lval)) == NULL) {
+ php_error(E_WARNING, "collection not found");
+ return 0;
+ }
+
+ return (*coll)->value.lval;
+}
+
/* }}} */
+
+#endif
+
+/* }}} */
/* {{{ _oci_get_ocidesc() */
static int
@@ -2471,6 +2601,11 @@
oci_statement *bindstmt;
oci_bind bind, *bindp;
oci_descriptor *descr;
+#ifdef WITH_COLLECTIONS
+ oci_collection *coll;
+ int mode = OCI_DATA_AT_EXEC;
+ dvoid *mycoll = 0;
+#endif
ub2 ocitype = SQLT_CHR; /* unterminated string */
OCIStmt *mystmt = 0;
dvoid *mydescr = 0;
@@ -2495,6 +2630,24 @@
OCI_GET_STMT(statement,stmt);
switch (ocitype) {
+#ifdef WITH_COLLECTIONS
+ case SQLT_NTY:
+ if((*var)->type != IS_OBJECT) {
+ php_error(E_WARNING,"Variable must be allocated using
+OCINewCollection()");
+ RETURN_FALSE;
+ }
+ if ((inx = _oci_get_ocicoll(*var,&coll)) == 0) {
+ php_error(E_WARNING,"Variable must be allocated using
+OCINewCollection()");
+ RETURN_FALSE;
+ }
+ if (! (mycoll = (dvoid *) coll->coll)) {
+ php_error(E_WARNING,"Collection empty");
+ RETURN_FALSE;
+ }
+ value_sz = sizeof(void*);
+ mode = OCI_DEFAULT;
+ break;
+#endif
case SQLT_BFILEE:
case SQLT_CFILEE:
case SQLT_CLOB:
@@ -2565,7 +2718,11 @@
(ub2 *)&bindp->retcode, /* return
code (ignored) */
(ub4)0, /*
maxarr_len (PL/SQL only?) */
(ub4 *)0, /* actual
array size (PL/SQL only?) */
+#ifdef WITH_COLLECTIONS
+ mode /* mode */);
+#else
OCI_DATA_AT_EXEC /* mode */);
+#endif
if (statement->error != OCI_SUCCESS) {
oci_error(statement->pError, "OCIBindByName", statement->error);
@@ -2573,6 +2730,9 @@
RETURN_FALSE;
}
+#ifdef WITH_COLLECTIONS
+ if(mode == OCI_DATA_AT_EXEC) {
+#endif
statement->error =
OCIBindDynamic(bindp->pBind,
statement->pError,
@@ -2586,6 +2746,24 @@
oci_handle_error(statement->conn, statement->error);
RETURN_FALSE;
}
+#ifdef WITH_COLLECTIONS
+ }
+#endif
+
+#ifdef WITH_COLLECTIONS
+ if(ocitype == SQLT_NTY) {
+ /* Bind object */
+ statement->error = OCIBindObject(bindp->pBind,
+
+statement->pError,
+
+coll->tdo,
+
+(dvoid **) &(coll->coll),
+ (ub4
+*) 0, (dvoid **) 0, (ub4 *) 0);
+ if (statement->error) {
+ oci_error(statement->pError, "OCIBindObject",
+statement->error);
+ RETURN_FALSE;
+ }
+ }
+#endif
RETURN_TRUE;
}
@@ -3942,6 +4120,905 @@
}
/* }}} */
+
+#ifdef WITH_COLLECTIONS
+/* {{{ oci_get_coll() */
+
+static oci_collection *oci_get_coll(int ind)
+{
+ oci_collection *collection;
+ int actual_resource_type;
+
+ collection = (oci_collection *) zend_list_find(ind, &actual_resource_type);
+
+ if (collection && (actual_resource_type == le_coll)) {
+ return collection;
+ } else {
+ return (oci_collection *) NULL;
+ }
+}
+
+
+
+/* {{{ proto string ocifreecoll(object lob)
+ Deletes collection */
+
+PHP_FUNCTION(ocifreecoll)
+{
+ zval *id;
+ int inx;
+ oci_collection *coll;
+ oci_connection *connection;
+
+ if ((id = getThis()) != 0) {
+ inx = _oci_get_ocicoll(id,&coll);
+ if (inx) {
+ /*
+ * Do we need to free the object?
+ */
+ connection = coll->conn;
+ oci_debug("OCIfreecoll: coll=%d",inx);
+ zend_list_delete(inx);
+ RETURN_TRUE;
+ }
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto string ocicollappend(object collection,value)
+ Append an object to the collection */
+
+PHP_FUNCTION(ocicollappend)
+{
+ zval *id, **arg;
+ oci_connection *connection;
+ oci_collection *coll;
+ OCINumber num;
+ OCIString *ocistr = (OCIString *)0;
+ OCIInd new_ind = OCI_IND_NOTNULL;
+ OCIDate dt;
+ char *buffer;
+ int inx;
+ double ndx;
+ ub4 loblen;
+
+ if ((id = getThis()) != 0) {
+ if ((inx = _oci_get_ocicoll(id,&coll)) == 0) {
+ RETURN_FALSE;
+ }
+
+ connection = coll->conn;
+ if (zend_get_parameters_ex(1, &arg) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ switch(coll->element_typecode) {
+ case OCI_TYPECODE_DATE:
+ convert_to_string_ex(arg);
+ connection->error = OCIDateFromText(connection->pError,
+
+ (*arg)->value.str.val,
+
+ (*arg)->value.str.len,
+
+ 0,0,0,0,&dt);
+ if (connection->error) {
+ oci_error(connection->pError, "OCIDateFromText",
+connection->error);
+ }
+ connection->error = OCICollAppend(OCI(pEnv),
+
+ connection->pError,
+
+ (dvoid *) &dt,
+
+ (dvoid *) &new_ind,
+
+ (OCIColl *) coll->coll);
+ if (connection->error) {
+ oci_error(connection->pError, "OCICollAppend",
+connection->error);
+ }
+ break;
+ case OCI_TYPECODE_VARCHAR2 :
+ convert_to_string_ex(arg);
+ connection->error = OCIStringAssignText(OCI(pEnv),
+ connection->pError,
+
+(*arg)->value.str.val,
+
+(*arg)->value.str.len,
+ &ocistr);
+ if (connection->error) {
+ oci_error(connection->pError,
+"OCIStringAssignText", connection->error);
+ }
+ connection->error = OCICollAppend(OCI(pEnv),
+
+ connection->pError,
+
+ (dvoid *) ocistr,
+
+ (dvoid *) &new_ind,
+
+ (OCIColl *) coll->coll);
+ if (connection->error) {
+ oci_error(connection->pError, "OCICollAppend",
+connection->error);
+ }
+ break;
+ case OCI_TYPECODE_UNSIGNED16 : /* UNSIGNED
+SHORT */
+ case OCI_TYPECODE_UNSIGNED32 : /* UNSIGNED
+LONG */
+ case OCI_TYPECODE_REAL : /*
+REAL */
+ case OCI_TYPECODE_DOUBLE : /*
+DOUBLE */
+ case OCI_TYPECODE_INTEGER : /*
+INT */
+ case OCI_TYPECODE_SIGNED16 : /*
+SHORT */
+ case OCI_TYPECODE_SIGNED32 : /*
+LONG */
+ case OCI_TYPECODE_DECIMAL : /*
+DECIMAL */
+ case OCI_TYPECODE_FLOAT : /*
+FLOAT */
+ case OCI_TYPECODE_NUMBER : /*
+NUMBER */
+ case OCI_TYPECODE_SMALLINT : /*
+SMALLINT */
+ convert_to_double_ex(arg);
+ ndx = (double)(*arg)->value.dval;
+ connection->error =
+OCINumberFromReal(connection->pError,&ndx,
+
+ sizeof(double),&num);
+ if (connection->error) {
+ oci_error(connection->pError, "OCINumberFromReal",
+connection->error);
+ }
+
+ connection->error = OCICollAppend(OCI(pEnv),
+
+ connection->pError,
+
+ (dvoid *) &num,
+
+ (dvoid *) &new_ind,
+
+ (OCIColl *) coll->coll);
+ break;
+ }
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto string ocicolldategetelem(object collection,ndx,[format],[lang])
+ Retrieve the value at collection index ndx */
+
+PHP_FUNCTION(ocicolldategetelem)
+{
+ zval *id,**arg,**fmt,**lang;
+ oci_connection *connection;
+ oci_collection *coll;
+ OCINumber num;
+ OCIInd new_ind = OCI_IND_NOTNULL;
+ char *buffer;
+ ub4 ndx;
+ ub4 loblen;
+ int i;
+ dvoid *elem;
+ dvoid *elemind;
+ boolean exists;
+ OCIString *ocistr = (OCIString *)0;
+ text *str;
+ char buff[1024];
+ int len;
+ double dnum;
+ int ac = ZEND_NUM_ARGS(), inx;
+ char *ocifmt;
+ int ocifmt_len;
+ char *ocilang;
+ int ocilang_len;
+
+ if ((id = getThis()) != 0) {
+ if ((inx = _oci_get_ocicoll(id,&coll)) == 0) {
+ RETURN_FALSE;
+ }
+
+ if(coll->element_typecode != OCI_TYPECODE_DATE) {
+ php_error(E_WARNING, "Collection is not of date datatype");
+ RETURN_FALSE;
+ }
+
+ if (ac < 1 || ac > 3 || zend_get_parameters_ex(ac, &arg, &fmt, &lang)
+== FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ convert_to_long_ex(arg);
+ if(ac > 1) {
+ convert_to_string_ex(fmt);
+ ocifmt = (*fmt)->value.str.val;
+ ocifmt_len = (*fmt)->value.str.len;
+ } else {
+ ocifmt = 0;
+ ocifmt_len = 0;
+ }
+
+ if(ac > 2) {
+ convert_to_string_ex(lang);
+ ocilang = (*lang)->value.str.val;
+ ocilang_len = (*lang)->value.str.len;
+ } else {
+ ocilang = 0;
+ ocilang_len = 0;
+ }
+ ndx = (*arg)->value.lval;
+
+ connection = coll->conn;
+
+ connection->error = OCICollGetElem(OCI(pEnv),
+
+connection->pError,
+
+coll->coll,
+ ndx,
+
+&exists,
+
+&elem,
+
+&elemind);
+ if (connection->error) {
+ oci_error(connection->pError, "OCICollGetElem",
+connection->error);
+ }
+ len = 1024;
+ connection->error = OCIDateToText(connection->pError,
+ elem,
+
+ocifmt, /* fmt */
+
+ocifmt_len, /* fmt_length */
+
+ocilang, /* lang_name */
+
+ocilang_len, /* lang_length */
+
+&len,buff);
+ if (connection->error) {
+ oci_error(connection->pError, "OCIDateToText",
+connection->error);
+ }
+ RETURN_STRINGL(buff,len,1);
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto string ocicolldateassignelem(object collection,ndx,val,[format],[lang])
+ assign value at collection index ndx */
+
+PHP_FUNCTION(ocicolldateassignelem)
+{
+ zval *id,**arg,**val,**fmt,**lang;
+ oci_connection *connection;
+ oci_collection *coll;
+ OCINumber num;
+ OCIInd new_ind = OCI_IND_NOTNULL;
+ char *buffer;
+ ub4 ndx;
+ ub4 loblen;
+ int i;
+ dvoid *elem;
+ dvoid *elemind;
+ boolean exists;
+ OCIString *ocistr = (OCIString *)0;
+ OCIDate dt;
+ text *str;
+ char buff[1024];
+ int len;
+ double dnum;
+ int ac = ZEND_NUM_ARGS(), inx;
+ char *ocifmt;
+ int ocifmt_len;
+ char *ocilang;
+ int ocilang_len;
+
+ if ((id = getThis()) != 0) {
+ if ((inx = _oci_get_ocicoll(id,&coll)) == 0) {
+ RETURN_FALSE;
+ }
+
+ if(coll->element_typecode != OCI_TYPECODE_DATE) {
+ php_error(E_WARNING, "Collection is not of date datatype");
+ RETURN_FALSE;
+ }
+
+ if (ac < 2 || ac > 5 || zend_get_parameters_ex(ac, &arg, &val,&fmt,
+&lang) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ convert_to_long_ex(arg);
+ convert_to_string_ex(val);
+ if(ac > 2) {
+ convert_to_string_ex(fmt);
+ ocifmt = (*fmt)->value.str.val;
+ ocifmt_len = (*fmt)->value.str.len;
+ } else {
+ ocifmt = 0;
+ ocifmt_len = 0;
+ }
+
+ if(ac > 3) {
+ convert_to_string_ex(lang);
+ ocilang = (*lang)->value.str.val;
+ ocilang_len = (*lang)->value.str.len;
+ } else {
+ ocilang = 0;
+ ocilang_len = 0;
+ }
+ ndx = (*arg)->value.lval;
+
+ connection = coll->conn;
+ convert_to_string_ex(val);
+
+ if((*val)->value.str.len == 7 &&
+!strncmp((*val)->value.str.val,"SYSDATE",7)) {
+ connection->error = OCIDateSysDate(connection->pError,&dt);
+ if (connection->error) {
+ oci_error(connection->pError, "OCIDateSysDate",
+connection->error);
+ }
+ } else {
+ connection->error = OCIDateFromText(connection->pError,
+
+ (*val)->value.str.val,
+
+ (*val)->value.str.len,
+
+ ocifmt,ocifmt_len,ocilang,ocilang_len,&dt);
+ if (connection->error) {
+ oci_error(connection->pError, "OCIDateFromText",
+connection->error);
+ }
+ }
+
+ connection->error = OCICollAssignElem(OCI(pEnv),
+
+ connection->pError,
+
+ ndx,
+
+ (dword *)&dt,
+
+ &new_ind,
+
+ coll->coll);
+ if (connection->error) {
+ oci_error(connection->pError, "OCIAssignElem",
+connection->error);
+ }
+
+ RETURN_TRUE;
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto string ocicolldateappendelem(object collection,val,[format],[lang])
+ assign value at collection index ndx */
+
+PHP_FUNCTION(ocicolldateappendelem)
+{
+ zval *id,**arg,**fmt,**lang;
+ oci_connection *connection;
+ oci_collection *coll;
+ OCINumber num;
+ OCIInd new_ind = OCI_IND_NOTNULL;
+ char *buffer;
+ ub4 ndx;
+ ub4 loblen;
+ int i;
+ dvoid *elem;
+ dvoid *elemind;
+ boolean exists;
+ OCIString *ocistr = (OCIString *)0;
+ OCIDate dt;
+ text *str;
+ char buff[1024];
+ int len;
+ double dnum;
+ int ac = ZEND_NUM_ARGS(), inx;
+ char *ocifmt;
+ int ocifmt_len;
+ char *ocilang;
+ int ocilang_len;
+
+ if ((id = getThis()) != 0) {
+ if ((inx = _oci_get_ocicoll(id,&coll)) == 0) {
+ RETURN_FALSE;
+ }
+
+ if(coll->element_typecode != OCI_TYPECODE_DATE) {
+ php_error(E_WARNING, "Collection is not of date datatype");
+ RETURN_FALSE;
+ }
+
+ if (ac < 1 || ac > 3 || zend_get_parameters_ex(ac, &arg, &fmt, &lang)
+== FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ if(ac > 1) {
+ convert_to_string_ex(fmt);
+ ocifmt = (*fmt)->value.str.val;
+ ocifmt_len = (*fmt)->value.str.len;
+ } else {
+ ocifmt = 0;
+ ocifmt_len = 0;
+ }
+
+ if(ac > 2) {
+ convert_to_string_ex(lang);
+ ocilang = (*lang)->value.str.val;
+ ocilang_len = (*lang)->value.str.len;
+ } else {
+ ocilang = 0;
+ ocilang_len = 0;
+ }
+ connection = coll->conn;
+
+ convert_to_string_ex(arg);
+ if((*arg)->value.str.len == 7 &&
+!strncmp((*arg)->value.str.val,"SYSDATE",7)) {
+ connection->error = OCIDateSysDate(connection->pError,&dt);
+ if (connection->error) {
+ oci_error(connection->pError, "OCIDateSysDate",
+connection->error);
+ }
+ } else {
+ connection->error = OCIDateFromText(connection->pError,
+
+ (*arg)->value.str.val,
+
+ (*arg)->value.str.len,
+
+ ocifmt,ocifmt_len,ocilang,ocilang_len,&dt);
+ if (connection->error) {
+ oci_error(connection->pError, "OCIDateFromText",
+connection->error);
+ }
+ }
+ connection->error = OCICollAppend(OCI(pEnv),
+
+connection->pError,
+ &dt,
+
+&new_ind,
+
+coll->coll);
+ if (connection->error) {
+ oci_error(connection->pError, "OCICollAppend",
+connection->error);
+ }
+ RETURN_TRUE;
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto string ocicollgetelem(object collection,ndx,[format],[lang])
+ Retrieve the value at collection index ndx */
+
+PHP_FUNCTION(ocicollgetelem)
+{
+ zval *id,**arg,**dt_format,**lang;
+ oci_connection *connection;
+ oci_collection *coll;
+ OCINumber num;
+ OCIInd new_ind = OCI_IND_NOTNULL;
+ char *buffer;
+ ub4 ndx;
+ int inx;
+ ub4 loblen;
+ int i;
+ dvoid *elem;
+ dvoid *elemind;
+ boolean exists;
+ OCIString *ocistr = (OCIString *)0;
+ text *str;
+ char buff[1024];
+ int len;
+ double dnum;
+
+ if ((id = getThis()) != 0) {
+ if ((inx = _oci_get_ocicoll(id,&coll)) == 0) {
+ RETURN_FALSE;
+ }
+ if (zend_get_parameters_ex(1, &arg) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ convert_to_long_ex(arg);
+ ndx = (*arg)->value.lval;
+
+ connection = coll->conn;
+
+ connection->error = OCICollGetElem(OCI(pEnv),
+
+connection->pError,
+
+coll->coll,
+ ndx,
+
+&exists,
+
+&elem,
+
+&elemind);
+ if (connection->error) {
+ oci_error(connection->pError, "OCICollGetElem",
+connection->error);
+ }
+ switch(coll->element_typecode) {
+ case OCI_TYPECODE_DATE:
+ len = 1024;
+ OCIDateToText(connection->pError,
+ elem,
+ 0, /* fmt */
+ 0, /* fmt_length */
+ 0, /* lang_name */
+ 0, /* lang_length */
+ &len,buff);
+ RETURN_STRINGL(buff,len,1);
+ case OCI_TYPECODE_VARCHAR2 :
+ ocistr = *(OCIString **)elem;
+ str = OCIStringPtr(OCI(pEnv),ocistr);
+ RETURN_STRINGL(str,strlen(str),1);
+ break;
+ case OCI_TYPECODE_UNSIGNED16 : /* UNSIGNED
+SHORT */
+ case OCI_TYPECODE_UNSIGNED32 : /* UNSIGNED
+LONG */
+ case OCI_TYPECODE_REAL : /*
+REAL */
+ case OCI_TYPECODE_DOUBLE : /*
+DOUBLE */
+ case OCI_TYPECODE_INTEGER : /*
+INT */
+ case OCI_TYPECODE_SIGNED16 : /*
+SHORT */
+ case OCI_TYPECODE_SIGNED32 : /*
+LONG */
+ case OCI_TYPECODE_DECIMAL : /*
+DECIMAL */
+ case OCI_TYPECODE_FLOAT : /*
+FLOAT */
+ case OCI_TYPECODE_NUMBER : /*
+NUMBER */
+ case OCI_TYPECODE_SMALLINT : /*
+SMALLINT */
+ connection->error = OCINumberToReal(connection->pError,
+
+ (CONST OCINumber *) elem,
+ (uword)
+sizeof(dnum), (dvoid *) &dnum);
+ if (connection->error) {
+ oci_error(connection->pError, "OCINumberToReal",
+connection->error);
+ }
+ RETURN_DOUBLE(dnum);
+ break;
+ }
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+/* {{{ proto string ocicollassign(object collection,object)
+ Assign a collection from another existing collection */
+
+PHP_FUNCTION(ocicollassign)
+{
+ zval *id,**from;
+ oci_connection *connection;
+ oci_collection *coll,*from_coll;
+ OCINumber num;
+ OCIInd new_ind = OCI_IND_NOTNULL;
+ char *buffer;
+ ub4 ndx;
+ int inx;
+ ub4 loblen;
+ int i;
+ boolean exists;
+ OCIString *ocistr = (OCIString *)0;
+ text *str;
+ char buff[1024];
+ double dnum;
+
+ if ((id = getThis()) != 0) {
+ if ((inx = _oci_get_ocicoll(id,&coll)) == 0) {
+ RETURN_FALSE;
+ }
+
+ if (zend_get_parameters_ex(1, &from) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ if ((inx = _oci_get_ocicoll(*from,&from_coll)) == 0) {
+ RETURN_FALSE;
+ }
+
+ connection = coll->conn;
+
+ connection->error = OCICollAssign(OCI(pEnv),connection->pError,
+
+from_coll->coll,coll->coll);
+ if (connection->error) {
+ oci_error(connection->pError, "OCICollAssignElem",
+connection->error);
+ }
+ RETURN_TRUE;
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto string ocicollassignelem(object collection,ndx,val)
+ Assign element val to collection at index ndx */
+
+PHP_FUNCTION(ocicollassignelem)
+{
+ zval *id,**index,**val;
+ oci_connection *connection;
+ oci_collection *coll;
+ OCINumber num;
+ OCIInd new_ind = OCI_IND_NOTNULL;
+ char *buffer;
+ ub4 ndx;
+ int inx;
+ ub4 loblen;
+ int i;
+ boolean exists;
+ OCIString *ocistr = (OCIString *)0;
+ OCIDate dt;
+ text *str;
+ char buff[1024];
+ double dnum;
+
+ if ((id = getThis()) != 0) {
+ if ((inx = _oci_get_ocicoll(id,&coll)) == 0) {
+ RETURN_FALSE;
+ }
+
+ if (zend_get_parameters_ex(2, &index,&val) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ convert_to_long_ex(index);
+ ndx = (*index)->value.lval;
+
+ connection = coll->conn;
+
+
+ if (connection->error) {
+ oci_error(connection->pError, "OCICollAssignElem",
+connection->error);
+ }
+ switch(coll->element_typecode) {
+ case OCI_TYPECODE_DATE:
+ convert_to_string_ex(val);
+ connection->error = OCIDateFromText(connection->pError,
+
+ (*val)->value.str.val,
+
+ (*val)->value.str.len,
+
+ 0,0,0,0,&dt);
+ if (connection->error) {
+ oci_error(connection->pError, "OCIDateFromText",
+connection->error);
+ }
+ connection->error = OCICollAssignElem(OCI(pEnv),
+
+ connection->pError,
+
+ ndx,
+
+ (dword *)&dt,
+
+ &new_ind,
+
+ coll->coll);
+ if (connection->error) {
+ oci_error(connection->pError, "OCIAssignElem",
+connection->error);
+ }
+ break;
+ case OCI_TYPECODE_VARCHAR2 :
+ convert_to_string_ex(val);
+ connection->error = OCIStringAssignText(OCI(pEnv),
+ connection->pError,
+
+(*val)->value.str.val,
+
+(*val)->value.str.len,
+ &ocistr);
+ if (connection->error) {
+ oci_error(connection->pError,
+"OCIStringAssignText", connection->error);
+ }
+ connection->error = OCICollAssignElem(OCI(pEnv),
+
+ connection->pError,
+
+ ndx,
+
+ (dword *)ocistr,
+
+ &new_ind,
+
+ coll->coll);
+ if (connection->error) {
+ oci_error(connection->pError, "OCIAssignElem",
+connection->error);
+ }
+ RETURN_TRUE;
+ break;
+ case OCI_TYPECODE_UNSIGNED16 : /* UNSIGNED
+SHORT */
+ case OCI_TYPECODE_UNSIGNED32 : /* UNSIGNED
+LONG */
+ case OCI_TYPECODE_REAL : /*
+REAL */
+ case OCI_TYPECODE_DOUBLE : /*
+DOUBLE */
+ case OCI_TYPECODE_INTEGER : /*
+INT */
+ case OCI_TYPECODE_SIGNED16 : /*
+SHORT */
+ case OCI_TYPECODE_SIGNED32 : /*
+LONG */
+ case OCI_TYPECODE_DECIMAL : /*
+DECIMAL */
+ case OCI_TYPECODE_FLOAT : /*
+FLOAT */
+ case OCI_TYPECODE_NUMBER : /*
+NUMBER */
+ case OCI_TYPECODE_SMALLINT : /*
+SMALLINT */
+ convert_to_double_ex(val);
+ dnum = (double)(*val)->value.dval;
+ connection->error =
+OCINumberFromReal(connection->pError,&dnum,
+
+ sizeof(double),&num);
+ if (connection->error) {
+ oci_error(connection->pError, "OCINumberFromReal",
+connection->error);
+ }
+ connection->error = OCICollAssignElem(OCI(pEnv),
+
+ connection->pError,
+
+ ndx,
+
+ (dword *)&num,
+
+ &new_ind,
+
+ coll->coll);
+ if (connection->error) {
+ oci_error(connection->pError, "OCIAssignElem",
+connection->error);
+ }
+ RETURN_TRUE;
+ break;
+ }
+
+
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto string ocicollsize(object collection)
+ Return the size of a collection */
+
+PHP_FUNCTION(ocicollsize)
+{
+ zval *id,**arg;
+ oci_collection *coll;
+ sb4 sz;
+ int inx;
+
+ if ((id = getThis()) != 0) {
+ if ((inx = _oci_get_ocicoll(id,&coll)) == 0) {
+ RETURN_FALSE;
+ }
+ OCICollSize(OCI(pEnv),coll->conn->pError,coll->coll,&sz);
+ RETURN_LONG(sz);
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+/* {{{ proto string ocicollmax(object collection)
+ Return the max value of a collection. For a
+ varray this is the maximum length of the array */
+
+PHP_FUNCTION(ocicollmax)
+{
+ zval *id,**arg;
+ oci_collection *coll;
+ sb4 sz;
+ int inx;
+
+ if ((id = getThis()) != 0) {
+ if ((inx = _oci_get_ocicoll(id,&coll)) == 0) {
+ RETURN_FALSE;
+ }
+ sz = OCICollMax(OCI(pEnv),coll->coll);
+ RETURN_LONG(sz);
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto string ocicolltrim(object collection,num)
+ Trim num elements from the end of a collection */
+
+PHP_FUNCTION(ocicolltrim)
+{
+ zval *id,**arg;
+ oci_collection *coll;
+ sb4 sz;
+ int inx;
+
+ if ((id = getThis()) != 0) {
+ if ((inx = _oci_get_ocicoll(id,&coll)) == 0) {
+ RETURN_FALSE;
+ }
+ if (zend_get_parameters_ex(1, &arg) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long_ex(arg);
+ coll->conn->error =
+OCICollTrim(OCI(pEnv),coll->conn->pError,(*arg)->value.lval,coll->coll);
+ if (coll->conn->error) {
+ oci_error(coll->conn->pError, "OCICollTrim",
+coll->conn->error);
+ }
+
+ RETURN_TRUE;
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto string ocinewcollection(int connection, string tdo)
+ Initialize a new collection */
+
+PHP_FUNCTION(ocinewcollection)
+{
+ dvoid *dschp1;
+ dvoid *parmp1;
+ dvoid *parmp2;
+ zval **conn, **tdo;
+ oci_connection *connection;
+ oci_collection *coll;
+ OCISvcCtx *svchp = 0;
+
+ int dtype;
+
+ dtype = OCI_DTYPE_LOB;
+
+ if (zend_get_parameters_ex(2, &conn, &tdo) != SUCCESS) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_string_ex(tdo);
+
+ coll = emalloc(sizeof(oci_collection));
+
+ OCI_GET_CONN(connection,conn);
+
+ coll->conn = connection;
+ coll->id = zend_list_insert(coll,le_coll);
+ zend_list_addref(connection->id);
+
+ connection->error = OCITypeByName(OCI(pEnv),
+ connection->pError,
+ connection->pServiceContext,
+ (text *) 0,
+ (ub4) 0,
+ (text *) (*tdo)->value.str.val,
+ (ub4) (*tdo)->value.str.len,
+ (CONST text *) 0, (ub4) 0,
+ OCI_DURATION_SESSION,
+ OCI_TYPEGET_ALL,
+ &(coll->tdo));
+ if (connection->error) {
+ oci_error(connection->pError, "OCITypeByName", connection->error);
+ RETURN_FALSE;
+ }
+
+ connection->error = OCIHandleAlloc(OCI(pEnv), (dvoid **) &dschp1,
+ (ub4) OCI_HTYPE_DESCRIBE,
+ (size_t) 0, (dvoid **) 0);
+
+ if (connection->error) {
+ oci_error(connection->pError, "OCI_HTYPE_DESCRIBE", connection->error);
+ RETURN_FALSE;
+ }
+ connection->error = OCIDescribeAny(connection->pServiceContext,
+connection->pError, (dvoid *) coll->tdo,
+ (ub4) 0, OCI_OTYPE_PTR, (ub1)1,
+ (ub1) OCI_PTYPE_TYPE, dschp1);
+ if (connection->error) {
+ oci_error(connection->pError, "OCI_OTYPE_PTR", connection->error);
+ RETURN_FALSE;
+ }
+
+ connection->error = OCIAttrGet((dvoid *) dschp1,
+ (ub4) OCI_HTYPE_DESCRIBE,
+ (dvoid *)&parmp1, (ub4 *)0,
+(ub4)OCI_ATTR_PARAM,connection->pError);
+ if (connection->error) {
+ oci_error(connection->pError, "OCI_ATTR_PARAM", connection->error);
+ RETURN_FALSE;
+ }
+
+ // get the collection type code of the attribute
+ connection->error = OCIAttrGet((dvoid*) parmp1, (ub4) OCI_DTYPE_PARAM,
+ (dvoid*) &(coll->coll_typecode), (ub4 *) 0,
+ (ub4) OCI_ATTR_COLLECTION_TYPECODE,
+ connection->pError);
+ if (connection->error) {
+ oci_error(connection->pError, "OCI_ATTR_COLLECTION_TYPECODE",
+connection->error);
+ RETURN_FALSE;
+ }
+
+ switch(coll->coll_typecode) {
+ case OCI_TYPECODE_VARRAY:
+ connection->error = OCIAttrGet((dvoid*) parmp1,
+ (ub4) OCI_DTYPE_PARAM,
+ (dvoid*) &parmp2, (ub4 *) 0,
+ (ub4) OCI_ATTR_COLLECTION_ELEMENT,
+ connection->pError);
+ if (connection->error) {
+ oci_error(connection->pError, "OCI_ATTR_COLLECTION_ELEMENT",
+connection->error);
+ RETURN_FALSE;
+ }
+ connection->error = OCIAttrGet((dvoid*) parmp2,
+ (ub4) OCI_DTYPE_PARAM,
+ (dvoid*) &(coll->elem_ref), (ub4 *) 0,
+ (ub4) OCI_ATTR_REF_TDO,
+ connection->pError);
+ if (connection->error) {
+ oci_error(connection->pError, "OCI_ATTR_REF_TDO", connection->error);
+ RETURN_FALSE;
+ }
+ connection->error = OCITypeByRef(OCI(pEnv), connection->pError,
+coll->elem_ref,
+ OCI_DURATION_SESSION,
+ OCI_TYPEGET_HEADER, &(coll->element_type));
+ if (connection->error) {
+ oci_error(connection->pError, "OCI_TYPEGET_HEADER", connection->error);
+ RETURN_FALSE;
+ }
+
+ connection->error = OCIAttrGet((dvoid*) parmp2,
+ (ub4) OCI_DTYPE_PARAM,
+ (dvoid*) &(coll->element_typecode), (ub4 *) 0,
+ (ub4) OCI_ATTR_TYPECODE,
+ connection->pError);
+ if (connection->error) {
+ oci_error(connection->pError, "OCI_ATTR_TYPECODE", connection->error);
+ RETURN_FALSE;
+ }
+ break;
+ default:
+ printf("Unknown Type\n");
+ }
+
+ /* Create object to hold return table */
+ connection->error = OCIObjectNew(OCI(pEnv),
+ connection->pError,
+ connection->pServiceContext,
+ OCI_TYPECODE_TABLE,
+ coll->tdo,
+ (dvoid *)0,
+ OCI_DURATION_DEFAULT,
+ TRUE,
+ (dvoid **) &(coll->coll));
+ if (connection->error) {
+ oci_error(connection->pError, "OCIObjectNew", connection->error);
+ RETURN_FALSE;
+ }
+
+ object_init_ex(return_value, oci_coll_class_entry_ptr);
+ add_property_resource(return_value, "collection",coll->id);
+}
+
+/* }}} */
+
+#endif
#endif /* HAVE_OCI8 */
Index: php4/ext/oci8/php_oci8.h
diff -u php4/ext/oci8/php_oci8.h:1.13 php4/ext/oci8/php_oci8.h:1.14
--- php4/ext/oci8/php_oci8.h:1.13 Sun Feb 25 22:07:09 2001
+++ php4/ext/oci8/php_oci8.h Fri Apr 13 07:43:39 2001
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: php_oci8.h,v 1.13 2001/02/26 06:07:09 andi Exp $ */
+/* $Id: php_oci8.h,v 1.14 2001/04/13 14:43:39 thies Exp $ */
#if HAVE_OCI8
# ifndef PHP_OCI8_H
@@ -80,6 +80,22 @@
dvoid *ocidescr;
ub4 type;
} oci_descriptor;
+
+typedef struct {
+ int id;
+ int open;
+ oci_connection *conn;
+ oci_session *session;
+ OCISvcCtx *pServiceContext;
+ OCIType *tdo;
+ OCITypeCode coll_typecode;
+ OCIRef *elem_ref;
+ OCIType *element_type;
+ OCITypeCode element_typecode;
+ OCIColl *coll;
+ sword error;
+ OCIError *pError;
+} oci_collection;
typedef struct {
zval *zval;
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
To contact the list administrators, e-mail: [EMAIL PROTECTED]