diff options
Diffstat (limited to 'lib/sqlalchemy/processors.py')
-rw-r--r-- | lib/sqlalchemy/processors.py | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/lib/sqlalchemy/processors.py b/lib/sqlalchemy/processors.py new file mode 100644 index 000000000..cb4b72545 --- /dev/null +++ b/lib/sqlalchemy/processors.py @@ -0,0 +1,90 @@ +# processors.py +# Copyright (C) 2010 Gaetan de Menten gdementen@gmail.com +# +# This module is part of SQLAlchemy and is released under +# the MIT License: http://www.opensource.org/licenses/mit-license.php + +"""defines generic type conversion functions, as used in result processors. + +They all share one common characteristic: None is passed through unchanged. + +""" + +import codecs +import re +import datetime + +def str_to_datetime_processor_factory(regexp, type_): + rmatch = regexp.match + # Even on python2.6 datetime.strptime is both slower than this code + # and it does not support microseconds. + def process(value): + if value is None: + return None + else: + return type_(*map(int, rmatch(value).groups(0))) + return process + +try: + from sqlalchemy.cprocessors import UnicodeResultProcessor, \ + DecimalResultProcessor, \ + to_float, to_str, int_to_boolean, \ + str_to_datetime, str_to_time, \ + str_to_date + + def to_unicode_processor_factory(encoding): + return UnicodeResultProcessor(encoding).process + + def to_decimal_processor_factory(target_class): + return DecimalResultProcessor(target_class).process + +except ImportError: + def to_unicode_processor_factory(encoding): + decoder = codecs.getdecoder(encoding) + + def process(value): + if value is None: + return None + else: + # decoder returns a tuple: (value, len). Simply dropping the + # len part is safe: it is done that way in the normal + # 'xx'.decode(encoding) code path. + # cfr python-source/Python/codecs.c:PyCodec_Decode + return decoder(value)[0] + return process + + def to_decimal_processor_factory(target_class): + def process(value): + if value is None: + return None + else: + return target_class(str(value)) + return process + + def to_float(value): + if value is None: + return None + else: + return float(value) + + def to_str(value): + if value is None: + return None + else: + return str(value) + + def int_to_boolean(value): + if value is None: + return None + else: + return value and True or False + + DATETIME_RE = re.compile("(\d+)-(\d+)-(\d+) (\d+):(\d+):(\d+)(?:\.(\d+))?") + TIME_RE = re.compile("(\d+):(\d+):(\d+)(?:\.(\d+))?") + DATE_RE = re.compile("(\d+)-(\d+)-(\d+)") + + str_to_datetime = str_to_datetime_processor_factory(DATETIME_RE, + datetime.datetime) + str_to_time = str_to_datetime_processor_factory(TIME_RE, datetime.time) + str_to_date = str_to_datetime_processor_factory(DATE_RE, datetime.date) + |