]> git.ipfire.org Git - oddments/cappie.git/blame - cappie/database.py
Log every database query when in debug mode.
[oddments/cappie.git] / cappie / database.py
CommitLineData
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
22import itertools
23import sqlite3
24
25class 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
96class 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)