]>
Commit | Line | Data |
---|---|---|
78d3013c MT |
1 | #!/usr/bin/python |
2 | ############################################################################### | |
3 | # # | |
4 | # Cappie # | |
5 | # Copyright (C) 2010 Michael Tremer # | |
6 | # # | |
7 | # This program is free software: you can redistribute it and/or modify # | |
8 | # it under the terms of the GNU General Public License as published by # | |
9 | # the Free Software Foundation, either version 3 of the License, or # | |
10 | # (at your option) any later version. # | |
11 | # # | |
12 | # This program is distributed in the hope that it will be useful, # | |
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # | |
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # | |
15 | # GNU General Public License for more details. # | |
16 | # # | |
17 | # You should have received a copy of the GNU General Public License # | |
18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. # | |
19 | # # | |
20 | ############################################################################### | |
21 | ||
22 | import itertools | |
23 | import sqlite3 | |
24 | ||
25 | class Database(object): | |
26 | KEYS = ("EVENTS", "ADDRESSES") | |
27 | _CREATE = ["CREATE TABLE IF NOT EXISTS addresses(mac, address, lastseen);", | |
28 | "CREATE TABLE IF NOT EXISTS changes(address, lastchange);"] | |
29 | ||
30 | counter = 0 | |
31 | ||
32 | def __init__(self, log): | |
33 | self.log = log | |
34 | ||
35 | self.__connection = None | |
36 | ||
37 | def __del__(self): | |
38 | self.close() | |
39 | ||
40 | def open(self): | |
41 | self.log.debug("Opening database") | |
42 | if self.__connection: | |
43 | self.close() | |
44 | self.__connection = sqlite3.connect("test.db") | |
45 | for statement in self._CREATE: | |
46 | self.execute(statement) | |
47 | ||
48 | def close(self): | |
49 | self.log.debug("Closing database") | |
50 | self.commit() | |
51 | self.__connection.close() | |
52 | self.__connection = None | |
53 | ||
54 | def commit(self): | |
55 | self.log.debug("Committing data to database") | |
56 | self.__connection.commit() | |
57 | ||
58 | def query(self, query, *parameters): | |
59 | """Returns a row list for the given query and parameters.""" | |
60 | cursor = self._cursor() | |
61 | self._execute(cursor, query, parameters) | |
62 | column_names = [d[0] for d in cursor.description] | |
63 | return [Row(itertools.izip(column_names, row)) for row in cursor] | |
64 | ||
65 | def get(self, query, *parameters): | |
66 | """Returns the first row returned for the given query.""" | |
67 | rows = self.query(query, *parameters) | |
68 | if not rows: | |
69 | return None | |
70 | elif len(rows) > 1: | |
71 | raise Exception("Multiple rows returned for Database.get() query") | |
72 | else: | |
73 | return rows[0] | |
74 | ||
75 | def _cursor(self): | |
76 | if not self.__connection: | |
77 | self.open() | |
78 | return self.__connection.cursor() | |
79 | ||
80 | def execute(self, query, *parameters): | |
81 | """Executes the given query, returning the lastrowid from the query.""" | |
82 | cursor = self._cursor() | |
83 | self._execute(cursor, query, parameters) | |
84 | return cursor.lastrowid | |
85 | ||
86 | def _execute(self, cursor, query, parameters): | |
fdf8fd04 | 87 | self.log.debug("Executing query: %s" % query) |
78d3013c MT |
88 | try: |
89 | return cursor.execute(query, parameters) | |
90 | except sqlite3.OperationalError: | |
91 | self.log.error("Error connecting to database") | |
92 | self.close() | |
93 | raise | |
94 | ||
95 | ||
96 | class Row(dict): | |
97 | """A dict that allows for object-like property access syntax.""" | |
98 | def __getattr__(self, name): | |
99 | try: | |
100 | return self[name] | |
101 | except KeyError: | |
102 | raise AttributeError(name) |