[pypy-svn] r69596 - pypy/trunk/pypy/module/oracle
afa at codespeak.net
afa at codespeak.net
Tue Nov 24 18:30:44 CET 2009
Author: afa
Date: Tue Nov 24 18:30:43 2009
New Revision: 69596
Modified:
pypy/trunk/pypy/module/oracle/__init__.py
pypy/trunk/pypy/module/oracle/interp_environ.py
pypy/trunk/pypy/module/oracle/interp_error.py
pypy/trunk/pypy/module/oracle/interp_variable.py
pypy/trunk/pypy/module/oracle/roci.py
pypy/trunk/pypy/module/oracle/transform.py
Log:
Add the TIMESTAMP datatype
Modified: pypy/trunk/pypy/module/oracle/__init__.py
==============================================================================
--- pypy/trunk/pypy/module/oracle/__init__.py (original)
+++ pypy/trunk/pypy/module/oracle/__init__.py Tue Nov 24 18:30:43 2009
@@ -10,6 +10,7 @@
'STRING': 'interp_variable.VT_String',
'DATETIME': 'interp_variable.VT_DateTime',
'DATE': 'interp_variable.VT_Date',
+ 'TIMESTAMP': 'interp_variable.VT_Timestamp',
'BINARY': 'interp_variable.VT_Binary',
'LONG_STRING': 'interp_variable.VT_LongString',
'LONG_BINARY': 'interp_variable.VT_LongBinary',
Modified: pypy/trunk/pypy/module/oracle/interp_environ.py
==============================================================================
--- pypy/trunk/pypy/module/oracle/interp_environ.py (original)
+++ pypy/trunk/pypy/module/oracle/interp_environ.py Tue Nov 24 18:30:43 2009
@@ -82,6 +82,6 @@
error = W_Error(self.space, self, context, 0)
error.code = 0
- error.message = self.space.wrap("Invalid handle!")
+ error.w_message = self.space.wrap("Invalid handle!")
raise OperationError(get(self.space).w_DatabaseError,
self.space.wrap(error))
Modified: pypy/trunk/pypy/module/oracle/interp_error.py
==============================================================================
--- pypy/trunk/pypy/module/oracle/interp_error.py (original)
+++ pypy/trunk/pypy/module/oracle/interp_error.py Tue Nov 24 18:30:43 2009
@@ -20,6 +20,7 @@
self.w_NotSupportedError = get('NotSupportedError')
self.w_IntegrityError = get('IntegrityError')
self.w_InternalError = get('InternalError')
+ self.w_DataError = get('DataError')
self.w_Variable = get('Variable')
w_import = space.builtin.get('__import__')
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 Tue Nov 24 18:30:43 2009
@@ -799,7 +799,85 @@
return transform.OracleDateToPythonDate(self.environment, dataptr)
class VT_Timestamp(W_Variable):
- pass
+ oracleType = roci.SQLT_TIMESTAMP
+ size = rffi.sizeof(roci.OCIDateTime_p)
+
+ def initialize(self, space, cursor):
+ # initialize the Timestamp descriptors
+ for i in range(self.allocatedElements):
+ dataptr = rffi.ptradd(
+ rffi.cast(roci.Ptr(roci.OCIDateTime_p), self.data),
+ i)
+ status = roci.OCIDescriptorAlloc(
+ self.environment.handle,
+ dataptr,
+ roci.OCI_DTYPE_TIMESTAMP,
+ 0, None)
+ self.environment.checkForError(
+ status, "TimestampVar_Initialize()")
+
+ def finalize(self):
+ dataptr = rffi.cast(roci.Ptr(roci.OCIDateTime_p), self.data)
+ for i in range(self.allocatedElements):
+ if dataptr[i]:
+ roci.OCIDescriptorFree(
+ dataptr[i], roci.OCI_DTYPE_TIMESTAMP)
+
+ def getValueProc(self, space, pos):
+ dataptr = rffi.ptradd(
+ rffi.cast(roci.Ptr(roci.OCIDateTime_p), self.data),
+ pos)
+
+ return transform.OracleTimestampToPythonDate(
+ self.environment, dataptr)
+
+ def setValueProc(self, space, pos, w_value):
+ dataptr = rffi.ptradd(
+ rffi.cast(roci.Ptr(roci.OCIDateTime_p), self.data),
+ pos)
+
+ # make sure a timestamp is being bound
+ if not space.is_true(space.isinstance(w_value, get(space).w_DateTimeType)):
+ raise OperationError(
+ space.w_TypeError,
+ space.wrap("expecting timestamp data"))
+
+ year = space.int_w(space.getattr(w_value, space.wrap('year')))
+ month = space.int_w(space.getattr(w_value, space.wrap('month')))
+ day = space.int_w(space.getattr(w_value, space.wrap('day')))
+ hour = space.int_w(space.getattr(w_value, space.wrap('hour')))
+ minute = space.int_w(space.getattr(w_value, space.wrap('minute')))
+ second = space.int_w(space.getattr(w_value, space.wrap('second')))
+ microsecond = space.int_w(space.getattr(w_value, space.wrap('microsecond')))
+
+ status = roci.OCIDateTimeConstruct(
+ self.environment.handle,
+ self.environment.errorHandle,
+ dataptr[0],
+ year, month, day, hour, minute, second, microsecond * 1000,
+ None, 0)
+
+ self.environment.checkForError(
+ status, "TimestampVar_SetValue(): create structure")
+
+ validptr = lltype.malloc(rffi.CArrayPtr(roci.ub4).TO, 1, flavor='raw')
+ try:
+ status = roci.OCIDateTimeCheck(
+ self.environment.handle,
+ self.environment.errorHandle,
+ dataptr[0],
+ validptr);
+ self.environment.checkForError(
+ status,
+ "TimestampVar_SetValue()")
+ valid = rffi.cast(lltype.Signed, validptr[0])
+ finally:
+ lltype.free(validptr, flavor='raw')
+
+ if valid != 0:
+ raise OperationError(
+ get(space).w_DataError,
+ space.wrap("invalid date"))
class VT_Interval(W_Variable):
pass
Modified: pypy/trunk/pypy/module/oracle/roci.py
==============================================================================
--- pypy/trunk/pypy/module/oracle/roci.py (original)
+++ pypy/trunk/pypy/module/oracle/roci.py Tue Nov 24 18:30:43 2009
@@ -45,12 +45,14 @@
('OCIDateTime', OCITime),
])
+ OCIDateTime_p = platform.SimpleType('OCIDateTime*', rffi.VOIDP)
+
constants = '''
OCI_DEFAULT OCI_OBJECT OCI_THREADED OCI_EVENTS
OCI_SUCCESS OCI_SUCCESS_WITH_INFO OCI_INVALID_HANDLE OCI_NO_DATA
OCI_HTYPE_ERROR OCI_HTYPE_SVCCTX OCI_HTYPE_SERVER OCI_HTYPE_SESSION
OCI_HTYPE_STMT OCI_HTYPE_DESCRIBE OCI_HTYPE_ENV
- OCI_DTYPE_PARAM
+ OCI_DTYPE_PARAM OCI_DTYPE_TIMESTAMP
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
@@ -165,6 +167,15 @@
OCIError], # errhp
sword)
+OCIDescriptorAlloc = external(
+ 'OCIDescriptorAlloc',
+ [dvoidp, # parenth
+ dvoidpp, # descpp
+ ub4, # type
+ size_t, # xtramem_sz
+ dvoidp], # usrmempp
+ sword)
+
OCIDescriptorFree = external(
'OCIDescriptorFree',
[dvoidp, # descp
@@ -336,6 +347,53 @@
ub4], # type
sword)
+# OCI Date, Datetime, and Interval Functions
+
+OCIDateTimeCheck = external(
+ 'OCIDateTimeCheck',
+ [dvoidp, # hndl
+ OCIError, # err
+ OCIDateTime_p, # date
+ Ptr(ub4)], # valid
+ sword)
+
+OCIDateTimeConstruct = external(
+ 'OCIDateTimeConstruct',
+ [dvoidp, # hndl
+ OCIError, # errhp
+ OCIDateTime_p, # datetime
+ sb2, # year
+ ub1, # month
+ ub1, # day
+ ub1, # hour
+ ub1, # min
+ ub1, # src
+ ub4, # fsec
+ oratext, # timezone
+ size_t], # timezone_length
+ sword)
+
+OCIDateTimeGetDate = external(
+ 'OCIDateTimeGetDate',
+ [dvoidp, # hndl
+ OCIError, # errhp
+ OCIDateTime_p, # datetime
+ Ptr(sb2), # year
+ Ptr(ub1), # month
+ Ptr(ub1)], # day
+ sword)
+
+OCIDateTimeGetTime = external(
+ 'OCIDateTimeGetTime',
+ [dvoidp, # hndl
+ OCIError, # errhp
+ OCIDateTime_p, # datetime
+ Ptr(ub1), # hour
+ Ptr(ub1), # minute
+ Ptr(ub1), # second
+ Ptr(ub4)], # fsec
+ sword)
+
# OCI Number Functions
OCINumberFromInt = external(
Modified: pypy/trunk/pypy/module/oracle/transform.py
==============================================================================
--- pypy/trunk/pypy/module/oracle/transform.py (original)
+++ pypy/trunk/pypy/module/oracle/transform.py Tue Nov 24 18:30:43 2009
@@ -53,6 +53,52 @@
w(time.c_OCITimeMI),
w(time.c_OCITimeSS))
+def OracleTimestampToPythonDate(environment, valueptr):
+ yearptr = lltype.malloc(roci.Ptr(roci.sb2).TO, 1, flavor='raw')
+ monthptr = lltype.malloc(roci.Ptr(roci.ub1).TO, 1, flavor='raw')
+ dayptr = lltype.malloc(roci.Ptr(roci.ub1).TO, 1, flavor='raw')
+ hourptr = lltype.malloc(roci.Ptr(roci.ub1).TO, 1, flavor='raw')
+ minuteptr = lltype.malloc(roci.Ptr(roci.ub1).TO, 1, flavor='raw')
+ secondptr = lltype.malloc(roci.Ptr(roci.ub1).TO, 1, flavor='raw')
+ fsecondptr = lltype.malloc(roci.Ptr(roci.ub4).TO, 1, flavor='raw')
+
+ try:
+ status = roci.OCIDateTimeGetDate(
+ environment.handle, environment.errorHandle,
+ valueptr[0],
+ yearptr, monthptr, dayptr)
+
+ environment.checkForError(
+ status, "OracleTimestampToPythonDate(): date portion")
+
+ status = roci.OCIDateTimeGetTime(
+ environment.handle, environment.errorHandle,
+ valueptr[0],
+ hourptr, minuteptr, secondptr, fsecondptr)
+
+ environment.checkForError(
+ status, "OracleTimestampToPythonDate(): time portion")
+
+ space = environment.space
+ w = space.wrap
+ w_datetime = space.getattr(
+ space.getbuiltinmodule('datetime'),
+ w('datetime'))
+
+ return space.call_function(
+ w_datetime,
+ w(yearptr[0]), w(monthptr[0]), w(dayptr[0]),
+ w(hourptr[0]), w(minuteptr[0]), w(secondptr[0]),
+ w(fsecondptr[0] / 1000))
+ finally:
+ lltype.free(yearptr, flavor='raw')
+ lltype.free(monthptr, flavor='raw')
+ lltype.free(dayptr, flavor='raw')
+ lltype.free(hourptr, flavor='raw')
+ lltype.free(minuteptr, flavor='raw')
+ lltype.free(secondptr, flavor='raw')
+ lltype.free(fsecondptr, flavor='raw')
+
def DecimalToFormatAndText(environment, w_value):
space = environment.space
w_tuple_value = space.call_method(w_value, "as_tuple")
More information about the Pypy-commit
mailing list