Various documentation fixes and additions.
[quix0rs-apt-p2p.git] / apt_dht_Khashmir / db.py
index 7d40176a4ffb012fe0b64ec5ae663bda6350c3e7..47e974cf62122bab33cd4b4a4868a92e873bf822 100644 (file)
@@ -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."""