add db migration, part of #79

This commit is contained in:
Martin Zimmermann 2014-04-20 15:39:43 +02:00
parent 1253d40422
commit 5d2daa1244
2 changed files with 82 additions and 1 deletions

View File

@ -2,8 +2,11 @@
import sqlite3
import logging
import operator
import os.path
from collections import defaultdict
logger = logging.getLogger("isso")
from isso.db.comments import Comments
@ -19,7 +22,7 @@ class SQLite3:
a trigger for automated orphan removal.
"""
MAX_VERSION = 2
MAX_VERSION = 3
def __init__(self, path, conf):
@ -89,3 +92,25 @@ class SQLite3:
con.execute('PRAGMA user_version = 2')
logger.info("%i rows changed", con.total_changes)
# limit max. nesting level to 1
if self.version == 2:
first = lambda rv: list(map(operator.itemgetter(0), rv))
with sqlite3.connect(self.path) as con:
top = first(con.execute("SELECT id FROM comments WHERE parent IS NULL").fetchall())
flattened = defaultdict(set)
for id in top:
ids = [id, ]
while ids:
rv = first(con.execute("SELECT id FROM comments WHERE parent=?", (ids.pop(), )))
ids.extend(rv)
flattened[id].update(set(rv))
for id in flattened.keys():
for n in flattened[id]:
con.execute("UPDATE comments SET parent=? WHERE id=?", (id, n))

View File

@ -9,8 +9,11 @@ import sqlite3
import tempfile
from isso.db import SQLite3
from isso.db.comments import Comments
from isso.core import Config
from isso.compat import iteritems
class TestDBMigration(unittest.TestCase):
@ -49,3 +52,56 @@ class TestDBMigration(unittest.TestCase):
self.assertEqual(db.version, SQLite3.MAX_VERSION)
self.assertEqual(db.preferences.get("session-key"),
"supersecretkey")
def test_limit_nested_comments(self):
tree = {
1: None,
2: None,
3: 2,
4: 3,
7: 3,
5: 2,
6: None
}
with sqlite3.connect(self.path) as con:
con.execute("PRAGMA user_version = 2")
con.execute("CREATE TABLE threads ("
" id INTEGER PRIMARY KEY,"
" uri VARCHAR UNIQUE,"
" title VARCHAR)")
con.execute("CREATE TABLE comments ("
" tid REFERENCES threads(id),"
" id INTEGER PRIMARY KEY,"
" parent INTEGER,"
" created FLOAT NOT NULL, modified FLOAT,"
" text VARCHAR, email VARCHAR, website VARCHAR,"
" mode INTEGER,"
" remote_addr VARCHAR,"
" likes INTEGER DEFAULT 0,"
" dislikes INTEGER DEFAULT 0,"
" voters BLOB)")
con.execute("INSERT INTO threads (uri, title) VALUES (?, ?)", ("/", "Test"))
for (id, parent) in iteritems(tree):
con.execute("INSERT INTO comments ("
" tid, parent, created)"
"VALUEs (?, ?, ?)", (id, parent, id))
conf = Config.load(None)
db = SQLite3(self.path, conf)
flattened = [
(1, None),
(2, None),
(3, 2),
(4, 2),
(5, 2),
(6, None),
(7, 2)
]
with sqlite3.connect(self.path) as con:
rv = con.execute("SELECT id, parent FROM comments ORDER BY created").fetchall()
self.assertEqual(flattened, rv)