isso/isso/db.py

125 lines
4.1 KiB
Python
Raw Normal View History

2012-10-16 17:11:59 +00:00
import abc
2012-10-16 19:04:20 +00:00
import time
2012-10-16 17:11:59 +00:00
import sqlite3
from os.path import join
2012-10-16 19:07:29 +00:00
from isso.models import Comment
2012-10-16 17:11:59 +00:00
class Abstract:
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def initialize(self, conf):
return
@abc.abstractmethod
def shutdown(self):
return
@abc.abstractmethod
def add(path, comment):
return
@abc.abstractmethod
def update(self, path, id, comment):
2012-10-16 17:11:59 +00:00
return
@abc.abstractmethod
def delete(self, path):
2012-10-16 17:11:59 +00:00
return
@abc.abstractmethod
def retrieve(self, path, limit):
2012-10-16 17:11:59 +00:00
return
class SQLite(Abstract):
2012-10-16 17:32:55 +00:00
"""A basic :class:`Abstract` implementation using SQLite3. All comments
share a single database. The tuple (id, path) acts as unique identifier
for a comment. Multiple comments per path (= that is the URI to your blog
post) are ordered by that id."""
2012-10-16 17:11:59 +00:00
fields = [
'id', 'path', 'created', 'modified',
'text', 'author', 'email', 'website', 'parent', 'mode'
2012-10-16 17:11:59 +00:00
]
def initialize(self, conf):
2012-10-16 17:32:55 +00:00
self.dbpath = conf['SQLITE']
self.mode = 1 if conf.get('MODERATION') else 0
2012-10-16 17:11:59 +00:00
with sqlite3.connect(self.dbpath) as con:
sql = ('main.comments (id INTEGER NOT NULL, path VARCHAR(255) NOT NULL,'
'created FLOAT NOT NULL, modified FLOAT, text VARCHAR,'
'author VARCHAR(64), email VARCHAR(64), website VARCHAR(64),'
'parent INTEGER, mode INTEGER, PRIMARY KEY (id, path))')
2012-10-16 17:11:59 +00:00
con.execute("CREATE TABLE IF NOT EXISTS %s;" % sql)
# increment id if (id, path) is no longer unique
con.execute("""\
CREATE TRIGGER IF NOT EXISTS increment AFTER INSERT ON comments
BEGIN
UPDATE comments SET
id=(SELECT MAX(id)+1 FROM comments WHERE path=NEW.path)
WHERE rowid=NEW.rowid;
END;""")
def shutdown(self):
return
def query2comment(self, query):
return Comment(
text=query[4], author=query[5], email=query[6], website=query[7],
parent=query[8], mode=query[9], id=query[0], created=query[2], modified=query[3]
2012-10-16 17:11:59 +00:00
)
def add(self, path, c):
with sqlite3.connect(self.dbpath) as con:
keys = ','.join(self.fields)
values = ','.join('?'*len(self.fields))
x = con.execute('INSERT INTO comments (%s) VALUES (%s);' % (keys, values), (
0, path, c.created, c.modified, c.text, c.author, c.email, c.website,
c.parent, self.mode)
)
2012-10-16 17:11:59 +00:00
with sqlite3.connect(self.dbpath) as con:
return con.execute('SELECT path, MAX(id) FROM comments;').fetchone()
def update(self, path, id, comment):
with sqlite3.connect(self.dbpath) as con:
for field, value in comment.iteritems():
con.execute('UPDATE comments SET %s=? WHERE path=? AND id=?;' % field,
(value, id, path))
2012-10-16 19:04:20 +00:00
with sqlite3.connect(self.dbpath) as con:
con.execute('UPDATE comments SET modified=? WHERE path=? AND id=?',
(time.time(), path, id))
return path, id
def get(self, path, id):
with sqlite3.connect(self.dbpath) as con:
return self.query2comment(con.execute(
'SELECT * FROM comments WHERE path=? AND id=?;', (path, id)).fetchone())
2012-10-16 17:11:59 +00:00
def delete(self, path, id):
with sqlite3.connect(self.dbpath) as con:
con.execute('UPDATE comments SET text=? WHERE path=? AND id=?', ('', path, id))
for field in Comment.fields:
if field == 'text': continue
con.execute('UPDATE comments SET %s=? WHERE path=? AND id=?' % field,
(None, path, id))
return path, id
2012-10-16 17:11:59 +00:00
def retrieve(self, path, limit=20):
with sqlite3.connect(self.dbpath) as con:
2012-10-16 17:32:55 +00:00
rv = con.execute("SELECT * FROM comments WHERE path = ?" \
+ " ORDER BY id DESC LIMIT ?;", (path, limit)).fetchall()
2012-10-16 17:11:59 +00:00
for item in rv:
yield self.query2comment(item)