Skip to content
This repository has been archived by the owner on Feb 13, 2020. It is now read-only.

Commit

Permalink
Make sure we serialize fractional seconds in Oracle queries.
Browse files Browse the repository at this point in the history
  • Loading branch information
cyrusdaboo committed Jul 1, 2016
1 parent df056fc commit 07c6d45
Showing 1 changed file with 25 additions and 3 deletions.
28 changes: 25 additions & 3 deletions txdav/base/datastore/dbapiclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@

from txdav.common.icommondatastore import InternalDataStoreError

import datetime

import pg8000 as postgres

try:
Expand Down Expand Up @@ -124,7 +126,7 @@ def var(self, *args):
return self.realCursor.var(*args)


def execute(self, sql, args=()):
def mapArgs(self, args):
realArgs = []
for arg in args:
if isinstance(arg, str):
Expand All @@ -133,6 +135,7 @@ def execute(self, sql, args=()):
# application layer as they consume less memory, so do the
# conversion here.
arg = arg.decode('utf-8')

if isinstance(arg, unicode) and len(arg) > 1024:
# This *may* cause a type mismatch, but none of the non-CLOB
# strings that we're passing would allow a value this large
Expand All @@ -143,18 +146,37 @@ def execute(self, sql, args=()):
# it is:
v = self.var(cx_Oracle.NCLOB, len(arg) + 1)
v.setvalue(0, arg)

elif isinstance(arg, datetime.datetime):
# By default when cx_Oracle is passed a datetime object it maps it to a
# cx_Oracle.DATETIME variable which does not serialize fraction seconds
# into the query, or call, arguments. However, for high volume systems,
# we really want sub-second resolution for things like the job queue,
# so we want to serialize datetime as cx_Oracle.TIMESTAMP.
v = self.var(cx_Oracle.TIMESTAMP)
v.setvalue(0, arg)

else:
v = arg

realArgs.append(v)

return realArgs


def execute(self, sql, args=()):
realArgs = self.mapArgs(args)
return super(OracleCursorWrapper, self).execute(sql, realArgs)


def callproc(self, name, args=()):
return self.realCursor.callproc(name, args)
realArgs = self.mapArgs(args)
return self.realCursor.callproc(name, realArgs)


def callfunc(self, name, returnType, args=()):
return self.realCursor.callfunc(name, returnType, args)
realArgs = self.mapArgs(args)
return self.realCursor.callfunc(name, returnType, realArgs)



Expand Down

0 comments on commit 07c6d45

Please sign in to comment.