FedericoCeratto/bottle-cork

SQLiteBackend.Table.iteritems() yields wrong data

Closed this issue · 2 comments

The iteritems() function currently yields the first column name, instead of the first column data, in the yielded tuple.

Here's the current code:

    def iteritems(self):
        """Iterate over table rows"""
        query = "SELECT * FROM %s" % self._table_name
        result = self._backend.run_query(query)
        for row in result:
            d = dict(zip(self._column_names, row))
            d.pop(self._key_col)

            yield (self._key_col, d)

The problem is with d.pop(self._key_col) and yield (self._key_col, d).

You are popping of the first data element in the row (for example, a user name) with d.pop(self._key_col), and discarding it. Then, the column name is returned as the first item in the tuple (for example username).

That makes this script:

from cork import Cork
from cork.backends import SQLiteBackend

cork = Cork(backend=SQLiteBackend('example.db'))

for data in cork._store.users.iteritems():
    print data

print something like this:

('username', {'hash': u'cHtcFZCkr0dg++G1hxOY5x8NQdNG3oA6QZQrmW9Z9ZwwKIll7dKcln9NAN3YPwlzgXM7JHdR0MzYmU5uasEJq28=', 'email_addr': None, 'creation_date': u'2016-03-23 18:49:40.136047', 'role': u'user', 'last_login': u'2016-03-23 18:49:40.136047', 'desc': None})
('username', {'hash': u'cF5tr7q61ACnWSFfD19cydYxxlow+ky9jHEn9uNqbltvjncqiI7JV5XzTY3+LfVVO2vGl1JVcHnn/CEUk3vR5xY=', 'email_addr': None, 'creation_date': u'2016-03-23 18:49:57.529329', 'role': u'admin', 'last_login': u'2016-03-23 18:49:57.529329', 'desc': None})

(Notice that username is listed instead of the actual user's name)

The fix is pretty simple, and follows the other backends. Store off the data, and yield the result:

    def iteritems(self):
        """Iterate over table rows"""
        query = "SELECT * FROM %s" % self._table_name
        result = self._backend.run_query(query)
        for row in result:
            d = dict(zip(self._column_names, row))
            value = d.pop(self._key_col)

            yield (value, d)

Which now yields the following:

(u'user', {'hash': u'cHtcFZCkr0dg++G1hxOY5x8NQdNG3oA6QZQrmW9Z9ZwwKIll7dKcln9NAN3YPwlzgXM7JHdR0MzYmU5uasEJq28=', 'email_addr': None, 'creation_date': u'2016-03-23 18:49:40.136047', 'role': u'user', 'last_login': u'2016-03-23 18:49:40.136047', 'desc': None})
(u'user2', {'hash': u'cF5tr7q61ACnWSFfD19cydYxxlow+ky9jHEn9uNqbltvjncqiI7JV5XzTY3+LfVVO2vGl1JVcHnn/CEUk3vR5xY=', 'email_addr': None, 'creation_date': u'2016-03-23 18:49:57.529329', 'role': u'admin', 'last_login': u'2016-03-23 18:49:57.529329', 'desc': None})

Thank you for the bug report and the patch!

It was an easy fix :)