[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