[pypy-svn] r69637 - in pypy/trunk/pypy/module/oracle: . test
afa at codespeak.net
afa at codespeak.net
Wed Nov 25 17:12:35 CET 2009
Author: afa
Date: Wed Nov 25 17:12:33 2009
New Revision: 69637
Modified:
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:
Add ability to describe OBJECT types.
(Still incomplete)
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 17:12:33 2009
@@ -1,5 +1,6 @@
from pypy.interpreter.baseobjspace import Wrappable
-from pypy.interpreter.typedef import TypeDef, interp_attrproperty
+from pypy.interpreter.typedef import TypeDef, GetSetProperty
+from pypy.interpreter.typedef import interp_attrproperty
from pypy.rpython.lltypesystem import rffi, lltype
from pypy.module.oracle import roci
@@ -92,14 +93,188 @@
# describe the type
try:
- pass
- #self.describe(connection, describeHandle)
+ self.describe(connection, describeHandle)
finally:
roci.OCIHandleFree(describeHandle, roci.OCI_HTYPE_DESCRIBE)
+
+ def describe(self, connection, describeHandle):
+ "Describe the type and store information about it as needed"
+
+ # describe the type
+ status = roci.OCIDescribeAny(
+ connection.handle,
+ self.environment.errorHandle,
+ self.tdo, 0,
+ roci.OCI_OTYPE_PTR,
+ roci.OCI_DEFAULT,
+ roci.OCI_PTYPE_TYPE,
+ describeHandle)
+ self.environment.checkForError(
+ status, "ObjectType_Describe(): describe type")
+
+ # get top level parameter descriptor
+ paramptr = lltype.malloc(roci.Ptr(roci.OCIParam).TO,
+ 1, flavor='raw')
+ try:
+ status = roci.OCIAttrGet(
+ describeHandle, roci.OCI_HTYPE_DESCRIBE,
+ rffi.cast(roci.dvoidp, paramptr),
+ lltype.nullptr(roci.Ptr(roci.ub4).TO),
+ roci.OCI_ATTR_PARAM,
+ self.environment.errorHandle)
+ self.environment.checkForError(
+ status,
+ "ObjectType_Describe(): get top level parameter descriptor")
+ toplevelParam = paramptr[0]
+ finally:
+ lltype.free(paramptr, flavor='raw')
+
+ # determine type of type
+ typecodeptr = lltype.malloc(roci.Ptr(roci.OCITypeCode).TO,
+ 1, flavor='raw')
+ try:
+ status = roci.OCIAttrGet(
+ toplevelParam, roci.OCI_DTYPE_PARAM,
+ rffi.cast(roci.dvoidp, typecodeptr),
+ lltype.nullptr(roci.Ptr(roci.ub4).TO),
+ roci.OCI_ATTR_TYPECODE,
+ self.environment.errorHandle)
+ self.environment.checkForError(
+ status, "ObjectType_Describe(): get type code")
+ typeCode = typecodeptr[0]
+ finally:
+ lltype.free(typecodeptr, flavor='raw')
+
+ # if a collection, need to determine the sub type
+ if typeCode == roci.OCI_TYPECODE_NAMEDCOLLECTION:
+ self.isCollection = 1
+
+ # determine type of collection
+ XXX
+
+ # acquire collection parameter descriptor
+ XXX
+
+ # determine type of element
+ XXX
+
+ # if element type is an object type get its type
+ XXX
+
+ # determine the number of attributes
+ numptr = lltype.malloc(roci.Ptr(roci.ub2).TO,
+ 1, flavor='raw')
+ try:
+ status = roci.OCIAttrGet(
+ toplevelParam, roci.OCI_DTYPE_PARAM,
+ rffi.cast(roci.dvoidp, numptr),
+ lltype.nullptr(roci.Ptr(roci.ub4).TO),
+ roci.OCI_ATTR_NUM_TYPE_ATTRS,
+ self.environment.errorHandle)
+ self.environment.checkForError(
+ status, "ObjectType_Describe(): get number of attributes")
+ numAttributes = numptr[0]
+ finally:
+ lltype.free(numptr, flavor='raw')
+
+ # allocate the attribute list and dictionary
+ self.attributes = []
+ self.attributesByName = {}
+
+ # acquire the list parameter descriptor
+ listptr = lltype.malloc(roci.Ptr(roci.OCIParam).TO,
+ 1, flavor='raw')
+ try:
+ status = roci.OCIAttrGet(
+ toplevelParam, roci.OCI_DTYPE_PARAM,
+ rffi.cast(roci.dvoidp, listptr),
+ lltype.nullptr(roci.Ptr(roci.ub4).TO),
+ roci.OCI_ATTR_LIST_TYPE_ATTRS,
+ self.environment.errorHandle)
+ self.environment.checkForError(
+ status, "ObjectType_Describe(): get list parameter descriptor")
+ attributeListParam = listptr[0]
+ finally:
+ lltype.free(listptr, flavor='raw')
+
+ # create attribute information for each attribute
+ for i in range(numAttributes):
+ paramptr = lltype.malloc(roci.Ptr(roci.OCIParam).TO,
+ 1, flavor='raw')
+ try:
+ status = roci.OCIParamGet(
+ attributeListParam, roci.OCI_DTYPE_PARAM,
+ self.environment.errorHandle,
+ paramptr, i + 1)
+ self.environment.checkForError(
+ status,
+ "ObjectType_Describe(): get attribute param descriptor")
+ attribute = W_ObjectAttribute(connection, paramptr[0])
+ finally:
+ lltype.free(paramptr, flavor='raw')
+
+ self.attributes.append(attribute)
+ self.attributesByName[attribute.name] = attribute
+
+ def get_attributes(space, self):
+ return space.newlist([space.wrap(attr) for attr in self.attributes])
+
W_ObjectType.typedef = TypeDef(
'ObjectType',
schema = interp_attrproperty('schema', W_ObjectType),
name = interp_attrproperty('name', W_ObjectType),
+ attributes = GetSetProperty(W_ObjectType.get_attributes),
+ )
+
+class W_ObjectAttribute(Wrappable):
+ def __init__(self, connection, param):
+ self.initialize(connection, param)
+
+ def initialize(self, connection, param):
+ # determine the name of the attribute
+ nameptr = lltype.malloc(rffi.CArrayPtr(roci.oratext).TO, 1,
+ flavor='raw')
+ lenptr = lltype.malloc(rffi.CArrayPtr(roci.ub4).TO, 1,
+ flavor='raw')
+ try:
+ status = roci.OCIAttrGet(
+ param, roci.OCI_DTYPE_PARAM,
+ rffi.cast(roci.dvoidp, nameptr),
+ lenptr,
+ roci.OCI_ATTR_NAME,
+ connection.environment.errorHandle)
+ connection.environment.checkForError(
+ status,
+ "ObjectAttribute_Initialize(): get name")
+ self.name = rffi.charpsize2str(nameptr[0], lenptr[0])
+ finally:
+ lltype.free(nameptr, flavor='raw')
+ lltype.free(lenptr, flavor='raw')
+
+ # determine the type of the attribute
+ typecodeptr = lltype.malloc(roci.Ptr(roci.OCITypeCode).TO,
+ 1, flavor='raw')
+ try:
+ status = roci.OCIAttrGet(
+ param, roci.OCI_DTYPE_PARAM,
+ rffi.cast(roci.dvoidp, typecodeptr),
+ lltype.nullptr(roci.Ptr(roci.ub4).TO),
+ roci.OCI_ATTR_TYPECODE,
+ connection.environment.errorHandle)
+ connection.environment.checkForError(
+ status, "ObjectType_Describe(): get type code")
+ self.typeCode = typecodeptr[0]
+ finally:
+ lltype.free(typecodeptr, flavor='raw')
+
+ # if the type of the attribute is object, recurse
+ if self.typeCode in (roci.OCI_TYPECODE_NAMEDCOLLECTION,
+ roci.OCI_TYPECODE_OBJECT):
+ self.subType = W_ObjectType(connection, param)
+
+W_ObjectAttribute.typedef = TypeDef(
+ 'ObjectAttribute',
+ name = interp_attrproperty('name', W_ObjectAttribute),
)
class W_ExternalObject(Wrappable):
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 17:12:33 2009
@@ -36,6 +36,7 @@
OCIInd = platform.SimpleType('OCIInd', rffi.INT)
OCIPinOpt = platform.SimpleType('OCIPinOpt', rffi.INT)
OCILockOpt = platform.SimpleType('OCILockOpt', rffi.INT)
+ OCITypeCode = platform.SimpleType('OCITypeCode', rffi.UINT)
OCINumber = platform.Struct('OCINumber', [])
OCITime = platform.Struct('OCITime',
@@ -58,16 +59,18 @@
OCI_DTYPE_PARAM OCI_DTYPE_TIMESTAMP OCI_DTYPE_INTERVAL_DS OCI_DTYPE_LOB
OCI_CRED_RDBMS OCI_CRED_EXT OCI_SPOOL_ATTRVAL_NOWAIT
OCI_ATTR_SERVER OCI_ATTR_SESSION OCI_ATTR_USERNAME OCI_ATTR_PASSWORD
- OCI_ATTR_STMT_TYPE OCI_ATTR_PARAM_COUNT OCI_ATTR_ROW_COUNT
+ OCI_ATTR_STMT_TYPE OCI_ATTR_PARAM OCI_ATTR_PARAM_COUNT OCI_ATTR_ROW_COUNT
OCI_ATTR_NAME OCI_ATTR_SCALE OCI_ATTR_PRECISION OCI_ATTR_IS_NULL
OCI_ATTR_DATA_SIZE OCI_ATTR_DATA_TYPE OCI_ATTR_REF_TDO
- OCI_ATTR_SCHEMA_NAME OCI_ATTR_TYPE_NAME
+ OCI_ATTR_SCHEMA_NAME OCI_ATTR_TYPE_NAME OCI_ATTR_TYPECODE
+ OCI_ATTR_NUM_TYPE_ATTRS OCI_ATTR_LIST_TYPE_ATTRS
OCI_ATTR_CHARSET_FORM OCI_ATTR_ENV_CHARSET_ID
OCI_ATTR_PARSE_ERROR_OFFSET
OCI_NTV_SYNTAX OCI_COMMIT_ON_SUCCESS
OCI_FETCH_NEXT
OCI_IND_NULL OCI_IND_NOTNULL
OCI_PIN_ANY OCI_LOCK_NONE
+ OCI_OTYPE_PTR OCI_PTYPE_TYPE
OCI_STMT_SELECT OCI_STMT_CREATE OCI_STMT_DROP OCI_STMT_ALTER
OCI_STMT_INSERT OCI_STMT_DELETE OCI_STMT_UPDATE
SQLT_CHR SQLT_LNG SQLT_AFC SQLT_RDD SQLT_BIN SQLT_LBI SQLT_LVC SQLT_LVB
@@ -78,6 +81,7 @@
SQLCS_IMPLICIT SQLCS_NCHAR
OCI_TEMP_CLOB OCI_TEMP_BLOB OCI_DURATION_SESSION OCI_ONE_PIECE
OCI_NUMBER_SIGNED
+ OCI_TYPECODE_NAMEDCOLLECTION OCI_TYPECODE_OBJECT
OCI_NLS_MAXBUFSZ OCI_NLS_CS_ORA_TO_IANA
'''.split()
@@ -283,6 +287,18 @@
ub4], # indszp
sword)
+OCIDescribeAny = external(
+ 'OCIDescribeAny',
+ [OCISvcCtx, # svchp
+ OCIError, # errhp
+ dvoidp, # objptr
+ ub4, # objptr_len
+ ub1, # objptr_typ
+ ub1, # info_level
+ ub1, # objtyp
+ OCIDescribe], # dschp
+ sword)
+
OCIStmtGetBindInfo = external(
'OCIStmtGetBindInfo',
[OCIStmt, # stmtp
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 17:12:33 2009
@@ -31,4 +31,4 @@
objValue, = cur.fetchone()
assert objValue.type.schema == self.cnx.username.upper()
assert objValue.type.name == "PYPY_TEST_OBJTYPE"
- #assert objValue.type.attributes[0].name == "NUMBERVALUE"
+ assert objValue.type.attributes[0].name == "NUMBERCOL"
More information about the Pypy-commit
mailing list