[pypy-svn] r69386 - in pypy/trunk/pypy/module/oracle: . test
afa at codespeak.net
afa at codespeak.net
Wed Nov 18 17:59:39 CET 2009
Author: afa
Date: Wed Nov 18 17:59:38 2009
New Revision: 69386
Modified:
pypy/trunk/pypy/module/oracle/interp_variable.py
pypy/trunk/pypy/module/oracle/roci.py
pypy/trunk/pypy/module/oracle/test/test_numbervar.py
Log:
Support for long integer values
Modified: pypy/trunk/pypy/module/oracle/interp_variable.py
==============================================================================
--- pypy/trunk/pypy/module/oracle/interp_variable.py (original)
+++ pypy/trunk/pypy/module/oracle/interp_variable.py Wed Nov 18 17:59:38 2009
@@ -70,6 +70,9 @@
position == cursor.outputSizeColumn):
size = cursor.outputSize
+ # call the procedure to set values prior to define
+ varType = varType.preDefine(param, cursor.environment)
+
# create a variable of the correct type
if cursor.outputTypeHandler:
var = _newByOutputTypeHandler(
@@ -84,9 +87,6 @@
else:
var = varType(cursor, numElements, size)
- # call the procedure to set values prior to define
- var.preDefine(param)
-
# perform the define
handleptr = lltype.malloc(roci.Ptr(roci.OCIDefine).TO, 1, flavor='raw')
try:
@@ -216,8 +216,9 @@
def initialize(self, cursor):
pass
- def preDefine(self, param):
- pass
+ @classmethod
+ def preDefine(cls, param, environment):
+ return cls
def postDefine(self):
pass
@@ -502,6 +503,51 @@
oracleType = roci.SQLT_VNU
size = rffi.sizeof(roci.OCINumber)
+ @classmethod
+ def preDefine(cls, param, environment):
+ # if the return type has not already been specified, check to
+ # see if the number can fit inside an integer by looking at
+ # the precision and scale
+ if cls is VT_Float:
+ attrptr = lltype.malloc(rffi.CArrayPtr(roci.sb1).TO, 1,
+ flavor='raw')
+ try:
+ status = roci.OCIAttrGet(
+ param, roci.OCI_HTYPE_DESCRIBE,
+ rffi.cast(roci.dvoidp, attrptr),
+ lltype.nullptr(roci.Ptr(roci.ub4).TO),
+ roci.OCI_ATTR_SCALE,
+ environment.errorHandle)
+ environment.checkForError(
+ status,
+ "NumberVar_PreDefine(): scale")
+ scale = attrptr[0]
+ finally:
+ lltype.free(attrptr, flavor='raw')
+
+ attrptr = lltype.malloc(rffi.CArrayPtr(roci.ub2).TO, 1,
+ flavor='raw')
+ try:
+ status = roci.OCIAttrGet(
+ param, roci.OCI_HTYPE_DESCRIBE,
+ rffi.cast(roci.dvoidp, attrptr),
+ lltype.nullptr(roci.Ptr(roci.ub4).TO),
+ roci.OCI_ATTR_PRECISION,
+ environment.errorHandle)
+ environment.checkForError(
+ status,
+ "NumberVar_PreDefine(): precision")
+ precision = attrptr[0]
+ finally:
+ lltype.free(attrptr, flavor='raw')
+
+ if scale == 0 or (scale == -127 and precision == 0):
+ return VT_LongInteger
+ elif precision > 0 and precision < 10:
+ return VT_Integer
+
+ return cls
+
def getValueProc(self, space, pos):
dataptr = rffi.ptradd(
rffi.cast(roci.Ptr(roci.OCINumber), self.data),
@@ -525,7 +571,32 @@
finally:
lltype.free(integerValuePtr, flavor='raw')
elif isinstance(self, (VT_NumberAsString, VT_LongInteger)):
- XXX = NumberAsString, LongInteger
+ format_buf = config.StringBuffer()
+ format_buf.fill(space, space.wrap("TM9"))
+ sizeptr = lltype.malloc(rffi.CArray(roci.ub4), 1, flavor='raw')
+ BUFSIZE = 200
+ sizeptr[0] = rffi.cast(lltype.Unsigned, BUFSIZE)
+ textbuf, text = rffi.alloc_buffer(BUFSIZE)
+ try:
+ status = roci.OCINumberToText(
+ self.environment.errorHandle,
+ dataptr,
+ format_buf.ptr, format_buf.size,
+ None, 0,
+ sizeptr, textbuf);
+ self.environment.checkForError(
+ status, "NumberVar_GetValue(): as string")
+ w_strvalue = space.wrap(
+ rffi.str_from_buffer(textbuf, text,
+ BUFSIZE,
+ rffi.cast(lltype.Signed, sizeptr[0])))
+ if isinstance(self, VT_NumberAsString):
+ return w_strvalue
+ else:
+ return space.call_function(space.w_int, w_strvalue)
+ finally:
+ rffi.keep_buffer_alive_until_here(textbuf, text)
+ lltype.free(sizeptr, flavor='raw')
else:
return transform.OracleNumberToPythonFloat(
self.environment, dataptr)
@@ -551,6 +622,22 @@
finally:
lltype.free(integerValuePtr, flavor='raw')
return
+ if space.is_true(space.isinstance(w_value, space.w_long)):
+ text_buf = config.StringBuffer()
+ text_buf.fill(space, space.str(w_value))
+ format_buf = config.StringBuffer()
+ format_buf.fill(space, space.wrap("9" * 63))
+ status = roci.OCINumberFromText(
+ self.environment.errorHandle,
+ text_buf.ptr, text_buf.size,
+ format_buf.ptr, format_buf.size,
+ None, 0,
+ dataptr)
+ self.environment.checkForError(
+ status, "NumberVar_SetValue(): from long")
+ return
+ elif space.is_true(space.isinstance(w_value, space.w_bool)):
+ XXX
elif space.is_true(space.isinstance(w_value, space.w_float)):
doubleValuePtr = lltype.malloc(roci.Ptr(lltype.Float).TO, 1,
flavor='raw')
@@ -789,7 +876,8 @@
if space.is_true(space.isinstance(w_value, space.w_int)):
return VT_Integer, 0, numElements
- # XXX long
+ if space.is_true(space.isinstance(w_value, space.w_long)):
+ return VT_LongInteger, 0, numElements
if space.is_true(space.isinstance(w_value, space.w_float)):
return VT_Float, 0, numElements
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 18 17:59:38 2009
@@ -382,3 +382,15 @@
dvoidp], # rsl
sword)
+OCINumberToText = external(
+ 'OCINumberToText',
+ [OCIError, # err
+ Ptr(OCINumber), # number
+ oratext, # fmt
+ ub4, # fmt_length
+ oratext, # nls_params
+ ub4, # nls_p_length
+ Ptr(ub4), # buf_size
+ oratext], # buf
+ sword)
+
Modified: pypy/trunk/pypy/module/oracle/test/test_numbervar.py
==============================================================================
--- pypy/trunk/pypy/module/oracle/test/test_numbervar.py (original)
+++ pypy/trunk/pypy/module/oracle/test/test_numbervar.py Wed Nov 18 17:59:38 2009
@@ -16,3 +16,18 @@
cur.execute("begin :a := :b*2.5; end;", a=var,
b=decimal.Decimal("0.5"))
assert var.getvalue() == 1.25
+
+ def test_largelong(self):
+ cur = self.cnx.cursor()
+ var = cur.var(oracle.NUMBER)
+ var.setvalue(0, 6088343244)
+ cur.execute("select :x+5 from dual", x=var)
+ value, = cur.fetchone()
+ assert value == 6088343249
+
+ def test_smalllong(self):
+ cur = self.cnx.cursor()
+ cur.execute("select :x from dual", x=3L)
+ value, = cur.fetchone()
+ assert value == 3
+
More information about the Pypy-commit
mailing list