Changeset 792 for trunk/pgdb.py


Ignore:
Timestamp:
Jan 28, 2016, 2:54:34 PM (4 years ago)
Author:
cito
Message:

Using ARRAY and ROW constructor in pgdb again

Using the special input syntax for quoting arrays and rows had some
advantages, but one big disadvantage, namely the missing type information.
Therefore, this change has been reverted, we now use ARRAY and ROW
constructor syntax again to quote lists and tuples. See comments.

The code has become simpler again and doesn't need the re module any more.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/pgdb.py

    r791 r792  
    7373from math import isnan, isinf
    7474from collections import namedtuple
    75 from re import compile as regex
    7675from json import loads as jsondecode, dumps as jsonencode
    7776
     
    265264
    266265
    267 _re_array_quote = regex(r'[{},"\\\s]|^[Nn][Uu][Ll][Ll]$')
    268 _re_record_quote = regex(r'[(,"\\]')
    269 _re_array_escape = _re_record_escape = regex(r'(["\\])')
    270 
    271 
    272266class _quotedict(dict):
    273267    """Dictionary with auto quoting of its items.
     
    337331            return val
    338332        if isinstance(val, list):
    339             return "'%s'" % self._quote_array(val)
     333            # Quote value as an ARRAY constructor. This is better than using
     334            # an array literal because it carries the information that this is
     335            # an array and not a string.  One issue with this syntax is that
     336            # you need to add an explicit type cast when passing empty arrays.
     337            # The ARRAY keyword is actually only necessary at the top level.
     338            q = self._quote
     339            return 'ARRAY[%s]' % ','.join(str(q(v)) for v in val)
    340340        if isinstance(val, tuple):
    341             return "'%s'" % self._quote_record(val)
     341            # Quote as a ROW constructor.  This is better than using a record
     342            # literal because it carries the information that this is a record
     343            # and not a string.  We don't use the keyword ROW in order to make
     344            # this usable with the IN synntax as well.  It is only necessary
     345            # when the records has a single column which is not really useful.
     346            q = self._quote
     347            return '(%s)' % ','.join(str(q(v)) for v in val)
    342348        try:
    343349            return val.__pg_repr__()
     
    346352                'do not know how to handle type %s' % type(val))
    347353
    348     def _quote_array(self, val):
    349         """Quote value as a literal constant for an array."""
    350         q = self._quote_array_element
    351         return '{%s}' % ','.join(q(v) for v in val)
    352 
    353     def _quote_array_element(self, val):
    354         """Quote value using the output syntax for arrays."""
    355         if isinstance(val, list):
    356             return self._quote_array(val)
    357         if val is None:
    358             return 'null'
    359         if isinstance(val, (int, long, float)):
    360             return str(val)
    361         if isinstance(val, bool):
    362             return 't' if val else 'f'
    363         if isinstance(val, tuple):
    364             val = self._quote_record(val)
    365         if isinstance(val, basestring):
    366             if not val:
    367                 return '""'
    368             if _re_array_quote.search(val):
    369                 return '"%s"' % _re_array_escape.sub(r'\\\1', val)
    370             return val
    371         raise InterfaceError(
    372             'do not know how to handle base type %s' % type(val))
    373 
    374     def _quote_record(self, val):
    375         """Quote value as a literal constant for a record."""
    376         q = self._quote_record_element
    377         return '(%s)' % ','.join(q(v) for v in val)
    378 
    379     def _quote_record_element(self, val):
    380         """Quote value using the output syntax for records."""
    381         if val is None:
    382             return ''
    383         if isinstance(val, (int, long, float)):
    384             return str(val)
    385         if isinstance(val, bool):
    386             return 't' if val else 'f'
    387         if isinstance(val, list):
    388             val = self._quote_array(val)
    389         if isinstance(val, basestring):
    390             if not val:
    391                 return '""'
    392             if _re_record_quote.search(val):
    393                 return '"%s"' % _re_record_escape.sub(r'\\\1', val)
    394             return val
    395         raise InterfaceError(
    396             'do not know how to handle component type %s' % type(val))
    397354
    398355    def _quoteparams(self, string, parameters):
Note: See TracChangeset for help on using the changeset viewer.