X-Git-Url: https://git.mxchange.org/?p=quix0rs-apt-p2p.git;a=blobdiff_plain;f=apt_dht_Khashmir%2Fdb.py;h=47e974cf62122bab33cd4b4a4868a92e873bf822;hp=7d40176a4ffb012fe0b64ec5ae663bda6350c3e7;hb=f47aeeba7f705a40bbfe947f5eb374018f57ab37;hpb=92bb708a6485b52682fafc1aedc302e9a48cdaec diff --git a/apt_dht_Khashmir/db.py b/apt_dht_Khashmir/db.py index 7d40176..47e974c 100644 --- a/apt_dht_Khashmir/db.py +++ b/apt_dht_Khashmir/db.py @@ -1,4 +1,6 @@ +"""An sqlite database for storing nodes and key/value pairs.""" + from datetime import datetime, timedelta from pysqlite2 import dbapi2 as sqlite from binascii import a2b_base64, b2a_base64 @@ -15,18 +17,32 @@ class khash(str): class dht_value(str): """Dummy class to convert all DHT values to base64 for storing in the DB.""" - + +# Initialize the database to work with 'khash' objects (binary strings) sqlite.register_adapter(khash, b2a_base64) sqlite.register_converter("KHASH", a2b_base64) sqlite.register_converter("khash", a2b_base64) + +# Initialize the database to work with DHT values (binary strings) sqlite.register_adapter(dht_value, b2a_base64) sqlite.register_converter("DHT_VALUE", a2b_base64) sqlite.register_converter("dht_value", a2b_base64) class DB: - """Database access for storing persistent data.""" + """An sqlite database for storing persistent node info and key/value pairs. + + @type db: C{string} + @ivar db: the database file to use + @type conn: L{pysqlite2.dbapi2.Connection} + @ivar conn: an open connection to the sqlite database + """ def __init__(self, db): + """Load or create the database file. + + @type db: C{string} + @param db: the database file to use + """ self.db = db try: os.stat(db) @@ -39,8 +55,10 @@ class DB: sqlite.register_converter("text", str) else: self.conn.text_factory = str - + + #{ Loading the DB def _loadDB(self, db): + """Open a new connection to the existing database file""" try: self.conn = sqlite.connect(database=db, detect_types=sqlite.PARSE_DECLTYPES) except: @@ -48,16 +66,23 @@ class DB: raise DBExcept, "Couldn't open DB", traceback.format_exc() def _createNewDB(self, db): + """Open a connection to a new database and create the necessary tables.""" self.conn = sqlite.connect(database=db, detect_types=sqlite.PARSE_DECLTYPES) c = self.conn.cursor() - c.execute("CREATE TABLE kv (key KHASH, value DHT_VALUE, last_refresh TIMESTAMP, PRIMARY KEY (key, value))") + c.execute("CREATE TABLE kv (key KHASH, value DHT_VALUE, last_refresh TIMESTAMP, "+ + "PRIMARY KEY (key, value))") c.execute("CREATE INDEX kv_key ON kv(key)") c.execute("CREATE INDEX kv_last_refresh ON kv(last_refresh)") c.execute("CREATE TABLE nodes (id KHASH PRIMARY KEY, host TEXT, port NUMBER)") c.execute("CREATE TABLE self (num NUMBER PRIMARY KEY, id KHASH)") self.conn.commit() + def close(self): + self.conn.close() + + #{ This node's ID def getSelfNode(self): + """Retrieve this node's ID from a previous run of the program.""" c = self.conn.cursor() c.execute('SELECT id FROM self WHERE num = 0') id = c.fetchone() @@ -67,14 +92,14 @@ class DB: return None def saveSelfNode(self, id): + """Store this node's ID for a subsequent run of the program.""" c = self.conn.cursor() c.execute("INSERT OR REPLACE INTO self VALUES (0, ?)", (khash(id),)) self.conn.commit() + #{ Routing table def dumpRoutingTable(self, buckets): - """ - save routing table nodes to the database - """ + """Save routing table nodes to the database.""" c = self.conn.cursor() c.execute("DELETE FROM nodes WHERE id NOT NULL") for bucket in buckets: @@ -83,14 +108,12 @@ class DB: self.conn.commit() def getRoutingTable(self): - """ - load routing table nodes from database - it's usually a good idea to call refreshTable(force=1) after loading the table - """ + """Load routing table nodes from database.""" c = self.conn.cursor() c.execute("SELECT * FROM nodes") return c.fetchall() - + + #{ Key/value pairs def retrieveValues(self, key): """Retrieve values from the database.""" c = self.conn.cursor() @@ -125,9 +148,6 @@ class DB: c.execute("DELETE FROM kv WHERE last_refresh < ?", (t, )) self.conn.commit() - def close(self): - self.conn.close() - class TestDB(unittest.TestCase): """Tests for the khashmir database."""