From 8358b092a3b119585286dfabfcd2ae0195cffa45 Mon Sep 17 00:00:00 2001 From: Karsten Lehmann Date: Wed, 26 Aug 2020 21:06:57 +0200 Subject: [PATCH] Hide the media managers db --- src/ankisyncd/full_sync.py | 2 ++ src/ankisyncd/media.py | 36 +++++++++++++++++++++++------------- src/ankisyncd/sessions.py | 2 +- src/ankisyncd/sync_app.py | 10 +++------- 4 files changed, 29 insertions(+), 21 deletions(-) diff --git a/src/ankisyncd/full_sync.py b/src/ankisyncd/full_sync.py index 5d6a5cc..dd26d68 100644 --- a/src/ankisyncd/full_sync.py +++ b/src/ankisyncd/full_sync.py @@ -29,6 +29,8 @@ class FullSyncManager: os.replace(temp_db_path, session.get_collection_path()) finally: col.reopen() + # Reopen the media database + col.media.connect() return "OK" diff --git a/src/ankisyncd/media.py b/src/ankisyncd/media.py index 9c68c4c..c6627c5 100644 --- a/src/ankisyncd/media.py +++ b/src/ankisyncd/media.py @@ -11,18 +11,27 @@ import anki.db logger = logging.getLogger("ankisyncd.media") - -class ServerMediaManager: +class ServerMediaManager(object): def __init__(self, col): self._dir = re.sub(r"(?i)\.(anki2)$", ".media", col.path) 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): path = self.dir() + ".server.db" create = not os.path.exists(path) - self.db = anki.db.DB(path) + self._db = anki.db.DB(path) if create: - self.db.executescript( + self._db.executescript( """CREATE TABLE media ( fname TEXT NOT NULL PRIMARY KEY, usn INT NOT NULL, @@ -33,35 +42,36 @@ class ServerMediaManager: oldpath = self.dir() + ".db2" if os.path.exists(oldpath): logger.info("Found client media database, migrating contents") - self.db.execute("ATTACH ? AS old", oldpath) - self.db.execute( + self._db.execute("ATTACH ? AS old", oldpath) + self._db.execute( "INSERT INTO media SELECT fname, lastUsn, csum FROM old.media, old.meta" ) - self.db.commit() - self.db.execute("DETACH old") + self._db.commit() + self._db.execute("DETACH old") def close(self): - self.db.close() + self._db.close() def dir(self): return self._dir 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): - 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 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): fpath = os.path.join(self.dir(), fname) if os.path.exists(fpath): os.remove(fpath) - self.db.execute( + self._db.execute( "UPDATE media SET csum = NULL, usn = ? WHERE fname = ?", self.lastUsn() + 1, fname, ) + self._db.commit() diff --git a/src/ankisyncd/sessions.py b/src/ankisyncd/sessions.py index 2e09ab6..7c609db 100644 --- a/src/ankisyncd/sessions.py +++ b/src/ankisyncd/sessions.py @@ -32,7 +32,7 @@ class SqliteSessionManager(SimpleSessionManager): everytime the SyncApp is restarted.""" def __init__(self, session_db_path): - SimpleSessionManager.__init__(self) + super().__init__() self.session_db_path = os.path.realpath(session_db_path) self._ensure_schema_up_to_date() diff --git a/src/ankisyncd/sync_app.py b/src/ankisyncd/sync_app.py index 0baa830..fad24e4 100644 --- a/src/ankisyncd/sync_app.py +++ b/src/ankisyncd/sync_app.py @@ -93,8 +93,7 @@ class SyncCollectionHandler(Syncer): return {"cont": False, "msg": "Your client doesn't support the v{} scheduler.".format(self.col.schedVer())} # Make sure the media database is open! - if self.col.media.db is None: - self.col.media.connect() + self.col.media.connect() return { 'mod': self.col.mod, @@ -267,9 +266,7 @@ class SyncMediaHandler: self._remove_media_files(media_to_remove) if media_to_add: - self.col.media.db.executemany( - "INSERT OR REPLACE INTO media VALUES (?,?,?)", media_to_add) - self.col.media.db.commit() + self.col.media.addMedia(media_to_add) assert self.col.media.lastUsn() == oldUsn + processed_count # TODO: move to some unit test return processed_count @@ -325,10 +322,9 @@ class SyncMediaHandler: def mediaChanges(self, lastUsn): result = [] server_lastUsn = self.col.media.lastUsn() - fname = csum = None 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]) # anki assumes server_lastUsn == result[-1][1]