Author: byterock
Date: Tue Dec 11 05:48:09 2007
New Revision: 10408
Modified:
dbd-oracle/trunk/dbdimp.h
dbd-oracle/trunk/oci8.c
Log:
rc 4
Modified: dbd-oracle/trunk/dbdimp.h
==============================================================================
--- dbd-oracle/trunk/dbdimp.h (original)
+++ dbd-oracle/trunk/dbdimp.h Tue Dec 11 05:48:09 2007
@@ -165,14 +165,12 @@
OCITypeCode col_typecode; /*if collection this is its
OCI_ATTR_COLLECTION_TYPECODE */
OCITypeCode element_typecode; /*if collection this is its
element's OCI_ATTR_TYPECODE*/
OCIRef *obj_ref; /*if an embeded object
this is ref handle to its TDO*/
-
- OCIComplexObject **obj_instance;
- OCIComplexObject *obj_ind;
+ OCIComplexObject *obj_ind; /*Null indictator for
object */
OCIComplexObject *obj_value; /*the actual value from the DB*/
OCIType *obj_type; /*if an embeded object this is
the OCIType returned by a OCIObjectPin*/
fbh_obj_t *fields; /*one object for each
field/property*/
int field_count; /*The number of fields Not
really needed but nice to have*/
- AV *value; /*The */
+ AV *value; /*The value to
send back to Perl This way there are no memory leaks*/
};
struct imp_fbh_st { /* field buffer EXPERIMENTAL */
Modified: dbd-oracle/trunk/oci8.c
==============================================================================
--- dbd-oracle/trunk/oci8.c (original)
+++ dbd-oracle/trunk/oci8.c Tue Dec 11 05:48:09 2007
@@ -1370,36 +1370,44 @@
get_object (SV *sth, AV *list, imp_fbh_t *fbh,fbh_obj_t *obj,OCIComplexObject
*value){
dTHX;
sword status;
- OCIIter *itr = (OCIIter *) 0;
- dvoid *element = (dvoid *) 0;
- dvoid *null_element = (dvoid *) 0;
- dvoid *attr_value;
+ dvoid *element ;
+ dvoid *attr_value;
boolean eoc;
ub2 pos;
dvoid *attr_null_struct;
- OCIInd attr_null_status = OCI_IND_NULL;
- OCIType *attr_tdo;
- fbh_obj_t *fld;
- OCIInd *names_null = (OCIInd *) -1;
- dvoid *addr_obj = (dvoid *)0;
- dvoid *nind = (dvoid *)0;
- sb4 *size;
+ OCIInd attr_null_status;
+ OCIInd *element_null;
+ OCIType *attr_tdo;
+ OCIIter *itr;
+ fbh_obj_t *fld;
+
if (DBIS->debug >= 5) {
PerlIO_printf(DBILOGFP, " getting attributes of object named
%s with typecode=%d\n",obj->type_name,obj->typecode);
}
-
-
switch (obj->typecode) {
case OCI_TYPECODE_OBJECT : /* embedded ADT */
-
- for (pos = 0; pos < obj->field_count; pos++){
+ for (pos = 0; pos < obj->field_count; pos++){
fld = &obj->fields[pos]; /*get the field */
status=OCIObjectGetInd(fbh->imp_sth->envhp,fbh->imp_sth->errhp,value,&obj->obj_ind);
+/*the little bastard above took me ages to find out
+seems Oracle does not like people to know that it can do this
+the concept is simple really
+ 1. pin the object
+ 2. bind with dty = SQLT_NTY
+ 3. OCIDefineObject using the TDO
+ 4. on fetech get the null indicator of the objcet with OCIObjectGetInd
+ 5. interate over the atributes of the object
+
+The thing to remember is that OCI and C have no way of representing a DB NULLs
so we use the OCIInd find out
+if the object or any of its properties are NULL, This is one little line in a
20 chapter book and even then
+id only shows you examples with the C struct built in. Nowhere does it say you
can do it this way.
+ */
+
if (status != OCI_SUCCESS) {
oci_error(sth, fbh->imp_sth->errhp,
status, "OCIObjectGetInd");
return 0;
@@ -1439,14 +1447,13 @@
croak("panic: OCI_TYPECODE_REF objets () are not
supported ");
break;
- case OCI_TYPECODE_NAMEDCOLLECTION :
+ case OCI_TYPECODE_NAMEDCOLLECTION : /*this works for both as I
am using CONST OCIColl */
switch (obj->col_typecode) {
case OCI_TYPECODE_TABLE :
/* nested table */
case OCI_TYPECODE_VARRAY :
/* variable array */
fld = &obj->fields[0]; /*get the field */
-
OCIIterCreate_log_stat(fbh->imp_sth->envhp,
fbh->imp_sth->errhp,
(CONST OCIColl*) value, &itr,status);
@@ -1460,10 +1467,10 @@
for(eoc =
FALSE;!OCIIterNext(fbh->imp_sth->envhp, fbh->imp_sth->errhp, itr,
(dvoid **) &element,
- (dvoid **) &names_null, &eoc) && !eoc;)
+ (dvoid **) &element_null, &eoc) && !eoc;)
{
- if (*names_null==OCI_IND_NULL){
+ if
(*element_null==OCI_IND_NULL){
av_push(list, &sv_undef);
} else {
if
(obj->element_typecode == OCI_TYPECODE_OBJECT){
@@ -1475,7 +1482,8 @@
}
}
}
-
+ /*nasty surprise here. one has to get rid of
the iterator or you will leak memory
+ not documented in oci or in demos */
OCIIterDelete_log_stat( fbh->imp_sth->envhp,
fbh->imp_sth->errhp, &itr,status );
@@ -1718,19 +1726,11 @@
OCIObjectPin_log_stat(imp_sth->envhp,imp_sth->errhp,
obj->obj_ref,(dvoid **)&obj->obj_type,status);
-
if (status != OCI_SUCCESS) {
oci_error(sth,imp_sth->errhp, status, "OCIObjectPin");
return 0;
}
-
- if (status != OCI_SUCCESS) {
- oci_error(sth,imp_sth->errhp, status, "OCIObjectPin");
- return 0;
- }
-
-
OCIAttrGet_parmdp(imp_sth, obj->parmdp, (dvoid
*)&obj->field_count,(ub4 *) 0, OCI_ATTR_NUM_TYPE_ATTRS, status);
if (status != OCI_SUCCESS) {
@@ -1741,7 +1741,7 @@
/*now get the differnt fields of this object add one field
object for property*/
Newz(1, obj->fields, obj->field_count, fbh_obj_t);
- /*a field is just another instance of an obj not a new type*/
+ /*a field is just another instance of an obj not a new struct*/
OCIAttrGet_parmdp(imp_sth, obj->parmdp, (dvoid
*)&list_attr,(ub4 *) 0, OCI_ATTR_LIST_TYPE_ATTRS, status);