~isoschiz/endroid/kermit-v2

« back to all changes in this revision

Viewing changes to src/endroid/database.py

  • Committer: Martin Morrison
  • Date: 2014-05-07 15:53:42 UTC
  • Revision ID: martmorr@cisco.com-20140507155342-8qbdu8e0er5y1yo8
Series of minor review markups.

Show diffs side-by-side

added added

removed removed

Lines of Context:
8
8
import os.path
9
9
import logging
10
10
 
 
11
__all__ = (
 
12
    'Value', 'LIKE',
 
13
    'Field',
 
14
    'Database',
 
15
    'EndroidUniqueID', 'EndroidLastModified',
 
16
)
 
17
 
11
18
 
12
19
class TableRow(dict):
13
 
    """A regular dict, plus a system 'id' attribute."""
 
20
    """
 
21
    A dict with special properties for access the magic fields of the row.
 
22
 
 
23
    These should not be instantiated directly, but are instead returned from
 
24
    "fetch" operations on tables.
 
25
 
 
26
    """
14
27
    __slots__ = ()
15
28
 
16
29
    def __init__(self, *args, **kwargs):
18
31
 
19
32
    @property
20
33
    def id(self):
21
 
        logging.warning(self)
22
34
        return self[EndroidUniqueID]
23
35
 
24
36
    @property
25
37
    def last_modified(self):
26
38
        return self[EndroidLastModified]
27
39
 
 
40
 
28
41
class Value(object):
 
42
    """
 
43
    Wrapper for a value to be matched in a condition.
 
44
 
 
45
    'cmp' must be one of the comparison operators supported by SQL.
 
46
 
 
47
    """
29
48
    def __init__(self, val, cmp='='):
30
49
        self.value = str(val)
31
50
        self._cmp = str(cmp)
40
59
        else:
41
60
            return Value.as_condition(Value(obj))
42
61
 
 
62
 
43
63
class LIKE(Value):
 
64
    "Value subclass for handling SQl 'LIKE' comparisons."
44
65
    def __init__(self, val):
45
66
        super(LIKE, self).__init__("%{}%".format(val), "LIKE")
46
67
 
 
68
 
47
69
class Field(object):
 
70
    """
 
71
    Class representing a Field of a Table.
 
72
 
 
73
    These need usually only be instantiated when a table is first being
 
74
    created. Note that raw strings can be used as fields in create calls,
 
75
    and they simply get the default type.
 
76
 
 
77
    """
48
78
    def __init__(self, name, type=None, default=None):
49
79
        self._name = Field.as_str(name)
50
80
        self._type = type
68
98
        else:
69
99
            return Database._sanitize(obj)
70
100
 
 
101
 
71
102
class Table(object):
72
103
    """
73
104
    Wrapper around a table (so that the table name doesn't need to be
109
140
    def name(self):
110
141
        return self._db._tName(self._name)
111
142
 
 
143
 
112
144
class Database(object):
113
145
    """
114
146
    Wrapper round an sqlite3 Database.
158
190
    
159
191
    @staticmethod
160
192
    def _buildConditions(conditions):
161
 
        return " and ".join(Field.as_str(f) + Value.as_condition(v) for f, v in conditions.items()) or "1"
162
 
        #return " and ".join(Field.as_cmp(c) + "?" for c in conditions) or "1"
 
193
        return " and ".join(Field.as_str(f) + Value.as_condition(v)
 
194
                            for f, v in conditions.items()) or "1"
163
195
 
164
196
    def table(self, name):
165
197
        return Table(name, self)
171
203
 
172
204
        """
173
205
        if any(str(f).startswith('_endroid') for f in fields):
174
 
            raise ValueError("An attempt was made to create a table with system-reserved column-name (prefix '_endroid').")
 
206
            raise ValueError("An attempt was made to create a table with "
 
207
                             "system-reserved column-name (prefix '_endroid').")
175
208
        n = Database._sanitize(self._tName(name))
176
209
        fields_string = ', '.join(map(Field.as_create_str,
177
210
                                  [EndroidUniqueID] + list(fields)))
240
273
        return rows
241
274
 
242
275
    def count(self, name, conditions):
243
 
        """Return the number of rows in table 'name' which satisfy conditions."""
 
276
        "Return the number of rows in table 'name' which satisfy conditions."
244
277
        n = Database._sanitize(self._tName(name))
245
278
        query = "SELECT COUNT(*) FROM {0} WHERE ({1});".format(n, Database._buildConditions(conditions))
246
279
        r = Database.raw(query, Database._tupleFromFieldValues(conditions)).fetchall()
279
312
 
280
313
    @staticmethod
281
314
    def raw(command, params=()):
282
 
        logging.info("SQL command {} params {}".format(command, params))
 
315
        logging.debug("SQL command {} params {}".format(command, params))
283
316
        p = Database.cursor.execute(command, params)
284
317
        Database.connection.commit()
285
318
        return p