Ensure that use of an sqlite DB is done with a thread-local instance.
authorNeal H. Walfield <neal@walfield.org>
Sun, 17 Jul 2011 21:21:48 +0000 (23:21 +0200)
committerYves Marcoz <yves@marcoz.org>
Fri, 5 Aug 2011 02:55:17 +0000 (19:55 -0700)
src/rss_sqlite.py

index 5b44369..64aef0a 100644 (file)
@@ -2,6 +2,7 @@
 
 # 
 # Copyright (c) 2007-2008 INdT.
+# Copyright (c) 2011 Neal H. Walfield
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU Lesser General Public License as published by
 # the Free Software Foundation, either version 3 of the License, or
@@ -34,24 +35,33 @@ import urllib2
 from BeautifulSoup import BeautifulSoup
 from urlparse import urljoin
 from calendar import timegm
+import threading
 
 def getId(string):
     return md5.new(string).hexdigest()
 
 class Feed:
+    def _getdb(self):
+        try:
+            db = self.tls.db
+        except AttributeError:
+            db = sqlite3.connect("%s/%s.db" % (self.dir, self.key), timeout=120)
+            self.tls.db = db
+        return db
+    db = property(_getdb)
+
     def __init__(self, configdir, key):
         self.key = key
         self.configdir = configdir
         self.dir = "%s/%s.d" %(self.configdir, self.key)
+        self.tls = threading.local ()
+
         if not isdir(self.dir):
             mkdir(self.dir)
         if not isfile("%s/%s.db" %(self.dir, self.key)):
-            self.db = sqlite3.connect("%s/%s.db" %(self.dir, self.key) )
             self.db.execute("CREATE TABLE feed (id text, title text, contentLink text, date float, updated float, link text, read int);")
             self.db.execute("CREATE TABLE images (id text, imagePath text);")
             self.db.commit()
-        else:
-            self.db = sqlite3.connect("%s/%s.db" %(self.dir, self.key) )
 
     def addImage(self, configdir, key, baseurl, url):
         filename = configdir+key+".d/"+getId(url)
@@ -402,11 +412,20 @@ class ArchivedArticles(Feed):
         self.removeEntry(id)
 
 class Listing:
+    def _getdb(self):
+        try:
+            db = self.tls.db
+        except AttributeError:
+            db = sqlite3.connect("%s/feeds.db" % self.configdir, timeout=120)
+            self.tls.db = db
+        return db
+    db = property(_getdb)
+
     # Lists all the feeds in a dictionary, and expose the data
     def __init__(self, configdir):
         self.configdir = configdir
-        
-        self.db = sqlite3.connect("%s/feeds.db" % self.configdir)
+
+        self.tls = threading.local ()
         
         try:
             table = self.db.execute("SELECT sql FROM sqlite_master").fetchone()
@@ -490,8 +509,7 @@ class Listing:
         
     def updateFeed(self, key, expiryTime=24, proxy=None, imageCache=False):
         feed = self.getFeed(key)
-        db = sqlite3.connect("%s/feeds.db" % self.configdir)
-        (url, etag, modified) = db.execute("SELECT url, etag, modified FROM feeds WHERE id=?;", (key,) ).fetchone()
+        (url, etag, modified) = self.db.execute("SELECT url, etag, modified FROM feeds WHERE id=?;", (key,) ).fetchone()
         try:
             modified = time.struct_time(eval(modified))
         except:
@@ -502,11 +520,11 @@ class Listing:
         else:
             modified=str(tuple(modified))
         if updateTime > 0:
-            db.execute("UPDATE feeds SET updateTime=?, etag=?, modified=? WHERE id=?;", (updateTime, etag, modified, key) )
+            self.db.execute("UPDATE feeds SET updateTime=?, etag=?, modified=? WHERE id=?;", (updateTime, etag, modified, key) )
         else:
-            db.execute("UPDATE feeds SET etag=?, modified=? WHERE id=?;", (etag, modified, key) )
-        db.commit()
-        self.updateUnread(key, db=db)
+            self.db.execute("UPDATE feeds SET etag=?, modified=? WHERE id=?;", (etag, modified, key) )
+        self.db.commit()
+        self.updateUnread(key)
         
     def getFeed(self, key):
         if key == "ArchivedArticles":
@@ -592,12 +610,10 @@ class Listing:
         else:
             return False
         
-    def updateUnread(self, key, db=None):
-        if db == None:
-            db = self.db
+    def updateUnread(self, key):
         feed = self.getFeed(key)
-        db.execute("UPDATE feeds SET unread=? WHERE id=?;", (feed.getNumberOfUnreadItems(), key))
-        db.commit()
+        self.db.execute("UPDATE feeds SET unread=? WHERE id=?;", (feed.getNumberOfUnreadItems(), key))
+        self.db.commit()
 
     def addFeed(self, title, url, id=None, category=1):
         if not id: