[pypy-svn] r69641 - in pypy/trunk/pypy/module/oracle: . test

afa at codespeak.net afa at codespeak.net
Wed Nov 25 19:20:02 CET 2009


Author: afa
Date: Wed Nov 25 19:20:01 2009
New Revision: 69641

Modified:
   pypy/trunk/pypy/module/oracle/__init__.py
   pypy/trunk/pypy/module/oracle/interp_object.py
   pypy/trunk/pypy/module/oracle/roci.py
   pypy/trunk/pypy/module/oracle/test/test_objectvar.py
Log:
Implement attribute access on OBJECT data


Modified: pypy/trunk/pypy/module/oracle/__init__.py
==============================================================================
--- pypy/trunk/pypy/module/oracle/__init__.py	(original)
+++ pypy/trunk/pypy/module/oracle/__init__.py	Wed Nov 25 19:20:01 2009
@@ -19,6 +19,7 @@
         'CURSOR': 'interp_variable.VT_Cursor',
         'BLOB': 'interp_variable.VT_BLOB',
         'CLOB': 'interp_variable.VT_CLOB',
+        'OBJECT': 'interp_variable.VT_Object',
         'Variable': 'interp_variable.W_Variable',
         'Timestamp': 'interp_error.get(space).w_DateTimeType',
         'Date': 'interp_error.get(space).w_DateType',

Modified: pypy/trunk/pypy/module/oracle/interp_object.py
==============================================================================
--- pypy/trunk/pypy/module/oracle/interp_object.py	(original)
+++ pypy/trunk/pypy/module/oracle/interp_object.py	Wed Nov 25 19:20:01 2009
@@ -1,9 +1,12 @@
 from pypy.interpreter.baseobjspace import Wrappable
 from pypy.interpreter.typedef import TypeDef, GetSetProperty
 from pypy.interpreter.typedef import interp_attrproperty
+from pypy.interpreter.gateway import ObjSpace
+from pypy.interpreter.gateway import interp2app
+from pypy.interpreter.error import OperationError
 from pypy.rpython.lltypesystem import rffi, lltype
 
-from pypy.module.oracle import roci, transform
+from pypy.module.oracle import roci, config, transform
 
 class W_ObjectType(Wrappable):
     def __init__(self, connection, param):
@@ -323,6 +326,8 @@
         if self.typeCode in (roci.OCI_TYPECODE_NAMEDCOLLECTION,
                              roci.OCI_TYPECODE_OBJECT):
             self.subType = W_ObjectType(connection, param)
+        else:
+            self.subType = None
 
 W_ObjectAttribute.typedef = TypeDef(
     'ObjectAttribute',
@@ -330,15 +335,79 @@
     )
 
 class W_ExternalObject(Wrappable):
-    def __init__(self, ref, type, instance, indicator, isIndependent=True):
+    def __init__(self, ref, objectType, instance, indicator, isIndependent=True):
         self.ref = ref
-        self.type = type
+        self.objectType = objectType
         self.instance = instance
         self.indicator = indicator
         self.isIndependent = isIndependent
+
+    def getattr(self, space, attr):
+        try:
+            attribute = self.objectType.attributesByName[attr]
+        except KeyError:
+            msg = "ExternalObject has no attribute '%s'" %(attr,)
+            raise OperationError(space.w_AttributeError, space.wrap(msg))
+
+        environment = self.objectType.environment
+
+        scalarvalueindicatorptr = lltype.malloc(rffi.CArrayPtr(roci.OCIInd).TO,
+                                                1, flavor='raw')
+        valueindicatorptr = lltype.malloc(rffi.CArrayPtr(roci.dvoidp).TO,
+                                          1, flavor='raw')
+        valueptr = lltype.malloc(rffi.CArrayPtr(roci.dvoidp).TO,
+                                 1, flavor='raw')
+        tdoptr = lltype.malloc(rffi.CArrayPtr(roci.OCIType).TO,
+                               1, flavor='raw')
+        nameptr = lltype.malloc(rffi.CArrayPtr(roci.oratext).TO,
+                               1, flavor='raw')
+        nameptr[0] = rffi.str2charp(attr)
+        namelenptr = lltype.malloc(rffi.CArrayPtr(roci.ub4).TO,
+                                   1, flavor='raw')
+        namelenptr[0] = rffi.cast(roci.ub4, len(attr))
+
+        try:
+            status = roci.OCIObjectGetAttr(
+                environment.handle,
+                environment.errorHandle,
+                self.instance,
+                self.indicator,
+                self.objectType.tdo,
+                nameptr, namelenptr, 1,
+                lltype.nullptr(roci.Ptr(roci.ub4).TO), 0,
+                scalarvalueindicatorptr,
+                valueindicatorptr,
+                valueptr,
+                tdoptr)
+            environment.checkForError(
+                status, "ExternalObject_GetAttributeValue(): getting value")
+
+            # determine the proper null indicator
+            valueIndicator = valueindicatorptr[0]
+            if not valueIndicator:
+                valueIndicator = scalarvalueindicatorptr
+            value = valueptr[0]
+
+            return convertToPython(
+                space, environment,
+                attribute.typeCode,
+                value, valueIndicator,
+                self, attribute.subType)
+        finally:
+            lltype.free(scalarvalueindicatorptr, flavor='raw')
+            lltype.free(valueindicatorptr, flavor='raw')
+            lltype.free(valueptr, flavor='raw')
+            lltype.free(tdoptr, flavor='raw')
+            rffi.free_charp(nameptr[0])
+            lltype.free(nameptr, flavor='raw')
+            lltype.free(namelenptr, flavor='raw')
+
+    getattr.unwrap_spec = ['self', ObjSpace, str]
+
 W_ExternalObject.typedef = TypeDef(
     'ExternalObject',
-    type = interp_attrproperty('type', W_ExternalObject),
+    type = interp_attrproperty('objectType', W_ExternalObject),
+    __getattr__ = interp2app(W_ExternalObject.getattr),
     )
 
 def convertToPython(space, environment, typeCode,

Modified: pypy/trunk/pypy/module/oracle/roci.py
==============================================================================
--- pypy/trunk/pypy/module/oracle/roci.py	(original)
+++ pypy/trunk/pypy/module/oracle/roci.py	Wed Nov 25 19:20:01 2009
@@ -464,6 +464,27 @@
      ub4],        # type
     sword)
 
+# OCI Miscellaneous Object Functions
+
+OCIObjectGetAttr = external(
+    'OCIObjectGetAttr',
+    [OCIEnv,             # env
+     OCIError,           # err
+     dvoidp,             # instance
+     dvoidp,             # null_struct
+     OCIType,            # tdo
+     Ptr(oratext),       # names
+     Ptr(ub4),           # lengths
+     ub4,                # name_count
+     Ptr(ub4),           # indexes
+     ub4,                # index_count
+     Ptr(OCIInd),        # attr_null_status
+     dvoidpp,            # attr_null_struct
+     dvoidpp,            # attr_value
+     dvoidpp],           # attr_tdo
+    sword)
+
+
 # OCI Object Pin, Unpin, and Free Functions
 
 OCIObjectFree = external(

Modified: pypy/trunk/pypy/module/oracle/test/test_objectvar.py
==============================================================================
--- pypy/trunk/pypy/module/oracle/test/test_objectvar.py	(original)
+++ pypy/trunk/pypy/module/oracle/test/test_objectvar.py	Wed Nov 25 19:20:01 2009
@@ -43,3 +43,5 @@
         assert objValue.type.attributes[0].name == "NUMBERCOL"
         assert isinstance(arrayValue, list)
         assert arrayValue == [5, 10, None, 20]
+        assert objValue.NUMBERCOL == 1
+        raises(AttributeError, getattr, objValue, 'OTHERCOL')



More information about the Pypy-commit mailing list