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 sqlite3
import logging import logging
import operator
import os.path import os.path
from collections import defaultdict
logger = logging.getLogger("isso") logger = logging.getLogger("isso")
from isso.db.comments import Comments from isso.db.comments import Comments
@ -19,7 +22,7 @@ class SQLite3:
a trigger for automated orphan removal. a trigger for automated orphan removal.
""" """
MAX_VERSION = 2 MAX_VERSION = 3
def __init__(self, path, conf): def __init__(self, path, conf):
@ -89,3 +92,25 @@ class SQLite3:
con.execute('PRAGMA user_version = 2') con.execute('PRAGMA user_version = 2')
logger.info("%i rows changed", con.total_changes) 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 import tempfile
from isso.db import SQLite3 from isso.db import SQLite3
from isso.db.comments import Comments
from isso.core import Config from isso.core import Config
from isso.compat import iteritems
class TestDBMigration(unittest.TestCase): class TestDBMigration(unittest.TestCase):
@ -49,3 +52,56 @@ class TestDBMigration(unittest.TestCase):
self.assertEqual(db.version, SQLite3.MAX_VERSION) self.assertEqual(db.version, SQLite3.MAX_VERSION)
self.assertEqual(db.preferences.get("session-key"), self.assertEqual(db.preferences.get("session-key"),
"supersecretkey") "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)