From 78d3013c1fa8c50586290b07b4af855639100c39 Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Thu, 29 Apr 2010 16:37:32 +0200 Subject: [PATCH] Moved Database class to own file with enhancements. --- cappie/__init__.py | 30 -------------- cappie/database.py | 101 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 30 deletions(-) create mode 100644 cappie/database.py diff --git a/cappie/__init__.py b/cappie/__init__.py index 1cf1e8d..5e5a10a 100644 --- a/cappie/__init__.py +++ b/cappie/__init__.py @@ -194,33 +194,3 @@ class Interface(Thread): def filter(self): return "arp or rarp" - -class Database(object): - def __init__(self, interface): - self.interface = interface - self.dev = self.interface.dev - self.log = self.interface.log - - self.__data = {} - - def open(self): - self.log.debug("Opened database for %s" % self.dev) - - def close(self): - self.log.debug("Closing database for %s" % self.dev) - print self.__data - - def get(self, mac): - if self.has(mac): - return self.__data[mac] - - def has(self, mac): - return self.__data.has_key(mac) - - def put(self, mac, key, val): - if not self.has(mac): - self.__data[mac] = {} - - # TODO Check key for sanity - - self.__data[mac][key] = val diff --git a/cappie/database.py b/cappie/database.py new file mode 100644 index 0000000..df766cb --- /dev/null +++ b/cappie/database.py @@ -0,0 +1,101 @@ +#!/usr/bin/python +############################################################################### +# # +# Cappie # +# Copyright (C) 2010 Michael Tremer # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +############################################################################### + +import itertools +import sqlite3 + +class Database(object): + KEYS = ("EVENTS", "ADDRESSES") + _CREATE = ["CREATE TABLE IF NOT EXISTS addresses(mac, address, lastseen);", + "CREATE TABLE IF NOT EXISTS changes(address, lastchange);"] + + counter = 0 + + def __init__(self, log): + self.log = log + + self.__connection = None + + def __del__(self): + self.close() + + def open(self): + self.log.debug("Opening database") + if self.__connection: + self.close() + self.__connection = sqlite3.connect("test.db") + for statement in self._CREATE: + self.execute(statement) + + def close(self): + self.log.debug("Closing database") + self.commit() + self.__connection.close() + self.__connection = None + + def commit(self): + self.log.debug("Committing data to database") + self.__connection.commit() + + def query(self, query, *parameters): + """Returns a row list for the given query and parameters.""" + cursor = self._cursor() + self._execute(cursor, query, parameters) + column_names = [d[0] for d in cursor.description] + return [Row(itertools.izip(column_names, row)) for row in cursor] + + def get(self, query, *parameters): + """Returns the first row returned for the given query.""" + rows = self.query(query, *parameters) + if not rows: + return None + elif len(rows) > 1: + raise Exception("Multiple rows returned for Database.get() query") + else: + return rows[0] + + def _cursor(self): + if not self.__connection: + self.open() + return self.__connection.cursor() + + def execute(self, query, *parameters): + """Executes the given query, returning the lastrowid from the query.""" + cursor = self._cursor() + self._execute(cursor, query, parameters) + return cursor.lastrowid + + def _execute(self, cursor, query, parameters): + try: + return cursor.execute(query, parameters) + except sqlite3.OperationalError: + self.log.error("Error connecting to database") + self.close() + raise + + +class Row(dict): + """A dict that allows for object-like property access syntax.""" + def __getattr__(self, name): + try: + return self[name] + except KeyError: + raise AttributeError(name) -- 2.39.2