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);
 

Reply via email to