summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/databases/sqlite.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2008-09-19 22:59:28 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2008-09-19 22:59:28 +0000
commit8d2fd5f87aaf837042d2dc5e692f84deb7dd1710 (patch)
tree75b308c71a3a4d2d0b0b63cf964b3c3ebbd4dfae /lib/sqlalchemy/databases/sqlite.py
parente395c05b9ac6ec5da8329c29c3b8939e3d642e2c (diff)
downloadsqlalchemy-8d2fd5f87aaf837042d2dc5e692f84deb7dd1710.tar.gz
- Overhauled SQLite date/time bind/result processing
to use regular expressions and format strings, rather than strptime/strftime, to generically support pre-1900 dates, dates with microseconds. [ticket:968]
Diffstat (limited to 'lib/sqlalchemy/databases/sqlite.py')
-rw-r--r--lib/sqlalchemy/databases/sqlite.py76
1 files changed, 34 insertions, 42 deletions
diff --git a/lib/sqlalchemy/databases/sqlite.py b/lib/sqlalchemy/databases/sqlite.py
index 3840cb64c..1486c9f36 100644
--- a/lib/sqlalchemy/databases/sqlite.py
+++ b/lib/sqlalchemy/databases/sqlite.py
@@ -54,76 +54,68 @@ class SLSmallInteger(sqltypes.Smallinteger):
return "SMALLINT"
class DateTimeMixin(object):
- __format__ = "%Y-%m-%d %H:%M:%S"
- __legacy_microseconds__ = False
-
- def bind_processor(self, dialect):
+ def _bind_processor(self, format, element_range):
+ elem = ("year", "month", "day", "hour",
+ "minute", "second", "microsecond")[element_range[0]:element_range[1]]
def process(value):
if not isinstance(value, (NoneType, datetime.date, datetime.datetime, datetime.time)):
- raise TypeError("SQLite Date, Time, and DateTime types only accept Python datetime objects as input.r")
+ raise TypeError("SQLite Date, Time, and DateTime types only accept Python datetime objects as input.")
elif value is not None:
- if self.__microsecond__ and getattr(value, 'microsecond', None) is not None:
- if self.__legacy_microseconds__:
- return value.strftime(self.__format__ + '.' + str(value.microsecond))
- else:
- return value.strftime(self.__format__ + ('.%06d' % value.microsecond))
- else:
- return value.strftime(self.__format__)
+ return format % tuple([getattr(value, attr, 0) for attr in elem])
else:
return None
return process
- def _cvt(self, value, dialect):
- if value is None:
- return None
- try:
- (value, microsecond) = value.split('.')
- if self.__legacy_microseconds__:
- microsecond = int(microsecond)
+ def _result_processor(self, fn, regexp):
+ def process(value):
+ if value is not None:
+ return fn(*[int(x or 0) for x in regexp.match(value).groups()])
else:
- microsecond = int((microsecond + '000000')[0:6])
- except ValueError:
- microsecond = 0
- return time.strptime(value, self.__format__)[0:6] + (microsecond,)
+ return None
+ return process
class SLDateTime(DateTimeMixin, sqltypes.DateTime):
- __format__ = "%Y-%m-%d %H:%M:%S"
- __microsecond__ = True
+ __legacy_microseconds__ = False
def get_col_spec(self):
return "TIMESTAMP"
+ def bind_processor(self, dialect):
+ if self.__legacy_microseconds__:
+ return self._bind_processor("%4.4d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d.%s", (0, 7))
+ else:
+ return self._bind_processor("%4.4d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d.%06d", (0, 7))
+
+ _reg = re.compile(r"(\d+)-(\d+)-(\d+)(?: (\d+):(\d+):(\d+)(?:\.(\d+))?)?")
def result_processor(self, dialect):
- def process(value):
- tup = self._cvt(value, dialect)
- return tup and datetime.datetime(*tup)
- return process
+ return self._result_processor(datetime.datetime, self._reg)
class SLDate(DateTimeMixin, sqltypes.Date):
- __format__ = "%Y-%m-%d"
- __microsecond__ = False
-
def get_col_spec(self):
return "DATE"
+ def bind_processor(self, dialect):
+ return self._bind_processor("%4.4d-%2.2d-%2.2d", (0, 3))
+
+ _reg = re.compile(r"(\d+)-(\d+)-(\d+)")
def result_processor(self, dialect):
- def process(value):
- tup = self._cvt(value, dialect)
- return tup and datetime.date(*tup[0:3])
- return process
+ return self._result_processor(datetime.date, self._reg)
class SLTime(DateTimeMixin, sqltypes.Time):
- __format__ = "%H:%M:%S"
- __microsecond__ = True
+ __legacy_microseconds__ = False
def get_col_spec(self):
return "TIME"
+ def bind_processor(self, dialect):
+ if self.__legacy_microseconds__:
+ return self._bind_processor("%2.2d:%2.2d:%2.2d.%s", (3, 7))
+ else:
+ return self._bind_processor("%2.2d:%2.2d:%2.2d.%06d", (3, 7))
+
+ _reg = re.compile(r"(\d+):(\d+):(\d+)(?:\.(\d+))?")
def result_processor(self, dialect):
- def process(value):
- tup = self._cvt(value, dialect)
- return tup and datetime.time(*tup[3:7])
- return process
+ return self._result_processor(datetime.time, self._reg)
class SLText(sqltypes.Text):
def get_col_spec(self):