Hide the media managers db

This commit is contained in:
Karsten Lehmann 2020-08-26 21:06:57 +02:00
parent b566e32597
commit 8358b092a3
No known key found for this signature in database
GPG Key ID: 6C34E8199743C270
4 changed files with 29 additions and 21 deletions

View File

@ -29,6 +29,8 @@ class FullSyncManager:
os.replace(temp_db_path, session.get_collection_path()) os.replace(temp_db_path, session.get_collection_path())
finally: finally:
col.reopen() col.reopen()
# Reopen the media database
col.media.connect()
return "OK" return "OK"

View File

@ -11,18 +11,27 @@ import anki.db
logger = logging.getLogger("ankisyncd.media") logger = logging.getLogger("ankisyncd.media")
class ServerMediaManager(object):
class ServerMediaManager:
def __init__(self, col): def __init__(self, col):
self._dir = re.sub(r"(?i)\.(anki2)$", ".media", col.path) self._dir = re.sub(r"(?i)\.(anki2)$", ".media", col.path)
self.connect() self.connect()
def addMedia(self, media_to_add):
self._db.executemany(
"INSERT OR REPLACE INTO media VALUES (?,?,?)",
media_to_add
)
self._db.commit()
def changes(self, lastUsn):
return self._db.execute("select fname,usn,csum from media order by usn desc limit ?", self.lastUsn() - lastUsn)
def connect(self): def connect(self):
path = self.dir() + ".server.db" path = self.dir() + ".server.db"
create = not os.path.exists(path) create = not os.path.exists(path)
self.db = anki.db.DB(path) self._db = anki.db.DB(path)
if create: if create:
self.db.executescript( self._db.executescript(
"""CREATE TABLE media ( """CREATE TABLE media (
fname TEXT NOT NULL PRIMARY KEY, fname TEXT NOT NULL PRIMARY KEY,
usn INT NOT NULL, usn INT NOT NULL,
@ -33,35 +42,36 @@ class ServerMediaManager:
oldpath = self.dir() + ".db2" oldpath = self.dir() + ".db2"
if os.path.exists(oldpath): if os.path.exists(oldpath):
logger.info("Found client media database, migrating contents") logger.info("Found client media database, migrating contents")
self.db.execute("ATTACH ? AS old", oldpath) self._db.execute("ATTACH ? AS old", oldpath)
self.db.execute( self._db.execute(
"INSERT INTO media SELECT fname, lastUsn, csum FROM old.media, old.meta" "INSERT INTO media SELECT fname, lastUsn, csum FROM old.media, old.meta"
) )
self.db.commit() self._db.commit()
self.db.execute("DETACH old") self._db.execute("DETACH old")
def close(self): def close(self):
self.db.close() self._db.close()
def dir(self): def dir(self):
return self._dir return self._dir
def lastUsn(self): def lastUsn(self):
return self.db.scalar("SELECT max(usn) FROM media") or 0 return self._db.scalar("SELECT max(usn) FROM media") or 0
def mediaCount(self): def mediaCount(self):
return self.db.scalar("SELECT count() FROM media WHERE csum IS NOT NULL") return self._db.scalar("SELECT count() FROM media WHERE csum IS NOT NULL")
# used only in unit tests # used only in unit tests
def syncInfo(self, fname): def syncInfo(self, fname):
return self.db.first("SELECT csum, 0 FROM media WHERE fname=?", fname) return self._db.first("SELECT csum, 0 FROM media WHERE fname=?", fname)
def syncDelete(self, fname): def syncDelete(self, fname):
fpath = os.path.join(self.dir(), fname) fpath = os.path.join(self.dir(), fname)
if os.path.exists(fpath): if os.path.exists(fpath):
os.remove(fpath) os.remove(fpath)
self.db.execute( self._db.execute(
"UPDATE media SET csum = NULL, usn = ? WHERE fname = ?", "UPDATE media SET csum = NULL, usn = ? WHERE fname = ?",
self.lastUsn() + 1, self.lastUsn() + 1,
fname, fname,
) )
self._db.commit()

View File

@ -32,7 +32,7 @@ class SqliteSessionManager(SimpleSessionManager):
everytime the SyncApp is restarted.""" everytime the SyncApp is restarted."""
def __init__(self, session_db_path): def __init__(self, session_db_path):
SimpleSessionManager.__init__(self) super().__init__()
self.session_db_path = os.path.realpath(session_db_path) self.session_db_path = os.path.realpath(session_db_path)
self._ensure_schema_up_to_date() self._ensure_schema_up_to_date()

View File

@ -93,8 +93,7 @@ class SyncCollectionHandler(Syncer):
return {"cont": False, "msg": "Your client doesn't support the v{} scheduler.".format(self.col.schedVer())} return {"cont": False, "msg": "Your client doesn't support the v{} scheduler.".format(self.col.schedVer())}
# Make sure the media database is open! # Make sure the media database is open!
if self.col.media.db is None: self.col.media.connect()
self.col.media.connect()
return { return {
'mod': self.col.mod, 'mod': self.col.mod,
@ -267,9 +266,7 @@ class SyncMediaHandler:
self._remove_media_files(media_to_remove) self._remove_media_files(media_to_remove)
if media_to_add: if media_to_add:
self.col.media.db.executemany( self.col.media.addMedia(media_to_add)
"INSERT OR REPLACE INTO media VALUES (?,?,?)", media_to_add)
self.col.media.db.commit()
assert self.col.media.lastUsn() == oldUsn + processed_count # TODO: move to some unit test assert self.col.media.lastUsn() == oldUsn + processed_count # TODO: move to some unit test
return processed_count return processed_count
@ -325,10 +322,9 @@ class SyncMediaHandler:
def mediaChanges(self, lastUsn): def mediaChanges(self, lastUsn):
result = [] result = []
server_lastUsn = self.col.media.lastUsn() server_lastUsn = self.col.media.lastUsn()
fname = csum = None
if lastUsn < server_lastUsn or lastUsn == 0: if lastUsn < server_lastUsn or lastUsn == 0:
for fname,usn,csum, in self.col.media.db.execute("select fname,usn,csum from media order by usn desc limit ?", server_lastUsn - lastUsn): for fname,usn,csum, in self.col.media.changes(lastUsn):
result.append([fname, usn, csum]) result.append([fname, usn, csum])
# anki assumes server_lastUsn == result[-1][1] # anki assumes server_lastUsn == result[-1][1]