Always downgrade the database before sync

This prevents the missing collation unicase error on the client
This commit is contained in:
Karsten Lehmann 2020-08-28 00:34:07 +02:00
parent e18e86e809
commit 7eff3815a4
No known key found for this signature in database
GPG Key ID: 6C34E8199743C270

View File

@ -1,13 +1,36 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import logging
import os import os
from sqlite3 import dbapi2 as sqlite from sqlite3 import dbapi2 as sqlite
import shutil
import sys import sys
from webob.exc import HTTPBadRequest
import anki.db from anki.db import DB
from anki.collection import Collection
class FullSyncManager: logger = logging.getLogger("ankisyncd.media")
def upload(self, col, data, session): logger.setLevel(1)
class FullSyncManager(object):
def test_db(self, db: DB):
"""
:param anki.db.DB db: the database uploaded from the client.
"""
if db.scalar("pragma integrity_check") != "ok":
raise HTTPBadRequest(
"Integrity check failed for uploaded collection database file."
)
def upload(self, col: Collection, data: bytes, session) -> str:
"""
Uploads a sqlite database from the client to the sync server.
:param anki.collection.Collectio col:
:param bytes data: The binary sqlite database from the client.
:param .sync_app.SyncUserSession session: The current session.
"""
# Verify integrity of the received database file before replacing our # Verify integrity of the received database file before replacing our
# existing db. # existing db.
temp_db_path = session.get_collection_path() + ".tmp" temp_db_path = session.get_collection_path() + ".tmp"
@ -15,10 +38,8 @@ class FullSyncManager:
f.write(data) f.write(data)
try: try:
with anki.db.DB(temp_db_path) as test_db: with DB(temp_db_path) as test_db:
if test_db.scalar("pragma integrity_check") != "ok": self.test_db(test_db)
raise HTTPBadRequest("Integrity check failed for uploaded "
"collection database file.")
except sqlite.Error as e: except sqlite.Error as e:
raise HTTPBadRequest("Uploaded collection database file is " raise HTTPBadRequest("Uploaded collection database file is "
"corrupt.") "corrupt.")
@ -26,7 +47,7 @@ class FullSyncManager:
# Overwrite existing db. # Overwrite existing db.
col.close() col.close()
try: try:
os.replace(temp_db_path, session.get_collection_path()) shutil.copyfile(temp_db_path, session.get_collection_path())
finally: finally:
col.reopen() col.reopen()
# Reopen the media database # Reopen the media database
@ -34,13 +55,27 @@ class FullSyncManager:
return "OK" return "OK"
def download(self, col: Collection, session) -> bytes:
"""Download the binary database.
def download(self, col, session): Performs a downgrade to database schema 11 before sending the database
col.close() to the client.
:param anki.collection.Collection col:
:param .sync_app.SyncUserSession session:
:return bytes: the binary sqlite3 database
"""
col.close(downgrade=True)
db_path = session.get_collection_path()
try: try:
data = open(session.get_collection_path(), 'rb').read() with open(db_path, 'rb') as tmp:
data = tmp.read()
finally: finally:
col.reopen() col.reopen()
# Reopen the media database
col.media.connect()
return data return data