Changeset 706


Ignore:
Timestamp:
Jan 9, 2016, 5:53:44 PM (4 years ago)
Author:
cito
Message:

Make sure DB methods respect the new bool option

Two DB methods assumed that booleans are always returned as strings,
which is no longer true when the set_bool() option is activated.
Added a test run with different global options to make sure that
no DB methods make such tacit assumptions about these options.

Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/4.x/module/pg.py

    r690 r706  
    339339                print(s)
    340340
     341    def _make_bool(d):
     342        """Get boolean value corresponding to d."""
     343        if get_bool():
     344            return bool(d)
     345        return d and 't' or 'f'
     346    _make_bool = staticmethod(_make_bool)
     347
    341348    def _quote_text(self, d):
    342349        """Quote text value."""
     
    353360                return 'NULL'
    354361            d = d.lower() in self._bool_true
    355         else:
    356             d = bool(d)
    357         return ("'f'", "'t'")[d]
     362        return d and "'t'" or "'f'"
    358363
    359364    _date_literals = frozenset('current_date current_time'
     
    717722        except KeyError:
    718723            q = "SELECT has_table_privilege('%s', '%s')" % (qcl, privilege)
    719             ret = self.db.query(q).getresult()[0][0] == 't'
     724            ret = self.db.query(q).getresult()[0][0] == self._make_bool(True)
    720725            self._privileges[(qcl, privilege)] = ret
    721726            return ret
     
    896901        """Clear all the attributes to values determined by the types.
    897902
    898         Numeric types are set to 0, Booleans are set to 'f', and everything
     903        Numeric types are set to 0, Booleans are set to false, and everything
    899904        else is set to the empty string.  If the array argument is present,
    900905        it is used as the array and any entries matching attribute names are
     
    915920                a[n] = 0
    916921            elif t in ('bool', 'boolean'):
    917                 a[n] = 'f'
     922                a[n] = self._make_bool(False)
    918923            else:
    919924                a[n] = ''
  • trunk/module/pg.py

    r705 r706  
    341341                print(s)
    342342
     343    @staticmethod
     344    def _make_bool(d):
     345        """Get boolean value corresponding to d."""
     346        return bool(d) if get_bool() else ('t' if d else 'f')
     347
    343348    def _quote_text(self, d):
    344349        """Quote text value."""
     
    355360                return 'NULL'
    356361            d = d.lower() in self._bool_true
    357         else:
    358             d = bool(d)
    359         return ("'f'", "'t'")[d]
     362        return "'t'" if d else "'f'"
    360363
    361364    _date_literals = frozenset('current_date current_time'
     
    723726        except KeyError:
    724727            q = "SELECT has_table_privilege('%s', '%s')" % (qcl, privilege)
    725             ret = self.db.query(q).getresult()[0][0] == 't'
     728            ret = self.db.query(q).getresult()[0][0] == self._make_bool(True)
    726729            self._privileges[(qcl, privilege)] = ret
    727730            return ret
     
    914917        """Clear all the attributes to values determined by the types.
    915918
    916         Numeric types are set to 0, Booleans are set to 'f', and everything
     919        Numeric types are set to 0, Booleans are set to false, and everything
    917920        else is set to the empty string.  If the array argument is present,
    918921        it is used as the array and any entries matching attribute names are
     
    933936                a[n] = 0
    934937            elif t in ('bool', 'boolean'):
    935                 a[n] = 'f'
     938                a[n] = self._make_bool(False)
    936939            else:
    937940                a[n] = ''
  • trunk/module/tests/test_classic_dbwrapper.py

    r690 r706  
    671671        self.assertEqual(can('test', 'update'), True)
    672672        self.assertEqual(can('test', 'delete'), True)
     673        self.assertEqual(can('pg_views', 'select'), True)
     674        self.assertEqual(can('pg_views', 'delete'), False)
    673675        self.assertRaises(pg.ProgrammingError, can, 'test', 'foobar')
    674676        self.assertRaises(pg.ProgrammingError, can, 'table_does_not_exist')
     
    758760        query = self.db.query
    759761        server_version = self.db.server_version
     762        bool_on = pg.get_bool()
     763        decimal = pg.get_decimal()
    760764        for table in ('insert_test_table', 'test table for insert'):
    761765            query('drop table if exists "%s"' % table)
     
    820824                expect = data.copy()
    821825                expect.update(change)
     826                if bool_on:
     827                    b = expect.get('b')
     828                    if b is not None:
     829                        expect['b'] = b == 't'
     830                if decimal is not Decimal:
     831                    d = expect.get('d')
     832                    if d is not None:
     833                        expect['d'] = decimal(d)
     834                    m = expect.get('m')
     835                    if m is not None:
     836                        expect['m'] = decimal(m)
    822837                if data.get('m') and server_version < 910000:
    823838                    # PostgreSQL < 9.1 cannot directly convert numbers to money
     
    910925        clear = self.db.clear
    911926        query = self.db.query
     927        f = False if pg.get_bool() else 'f'
    912928        for table in ('clear_test_table', 'test table for clear'):
    913929            query('drop table if exists "%s"' % table)
     
    915931                "n integer, b boolean, d date, t text)" % table)
    916932            r = clear(table)
    917             result = {'n': 0, 'b': 'f', 'd': '', 't': ''}
     933            result = {'n': 0, 'b': f, 'd': '', 't': ''}
    918934            self.assertEqual(r, result)
    919935            r['a'] = r['n'] = 1
     
    922938            r['oid'] = long(1)
    923939            r = clear(table, r)
    924             result = {'a': 1, 'n': 0, 'b': 'f', 'd': '', 't': '',
     940            result = {'a': 1, 'n': 0, 'b': f, 'd': '', 't': '',
    925941                'oid': long(1)}
    926942            self.assertEqual(r, result)
     
    11441160
    11451161
     1162class TestDBClassNonStdOpts(TestDBClass):
     1163    """Test the methods of the DB class with non-standard global options."""
     1164
     1165    @classmethod
     1166    def setUpClass(cls):
     1167        cls.saved_options = {}
     1168        cls.set_option('decimal', float)
     1169        not_bool = not pg.get_bool()
     1170        cls.set_option('bool', not_bool)
     1171        unnamed_result = lambda q: q.getresult()
     1172        cls.set_option('namedresult', unnamed_result)
     1173        super(TestDBClassNonStdOpts, cls).setUpClass()
     1174
     1175    @classmethod
     1176    def tearDownClass(cls):
     1177        super(TestDBClassNonStdOpts, cls).tearDownClass()
     1178        cls.reset_option('namedresult')
     1179        cls.reset_option('bool')
     1180        cls.reset_option('decimal')
     1181
     1182    @classmethod
     1183    def set_option(cls, option, value):
     1184        cls.saved_options[option] = getattr(pg, 'get_' + option)()
     1185        return getattr(pg, 'set_' + option)(value)
     1186
     1187    @classmethod
     1188    def reset_option(cls, option):
     1189        return getattr(pg, 'set_' + option)(cls.saved_options[option])
     1190
     1191
    11461192class TestSchemas(unittest.TestCase):
    11471193    """Test correct handling of schemas (namespaces)."""
Note: See TracChangeset for help on using the changeset viewer.