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 -*-
import logging
import os
from sqlite3 import dbapi2 as sqlite
import shutil
import sys
from webob.exc import HTTPBadRequest
import anki.db
from anki.db import DB
from anki.collection import Collection
class FullSyncManager:
def upload(self, col, data, session):
logger = logging.getLogger("ankisyncd.media")
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
# existing db.
temp_db_path = session.get_collection_path() + ".tmp"
@ -15,10 +38,8 @@ class FullSyncManager:
f.write(data)
try:
with anki.db.DB(temp_db_path) as test_db:
if test_db.scalar("pragma integrity_check") != "ok":
raise HTTPBadRequest("Integrity check failed for uploaded "
"collection database file.")
with DB(temp_db_path) as test_db:
self.test_db(test_db)
except sqlite.Error as e:
raise HTTPBadRequest("Uploaded collection database file is "
"corrupt.")
@ -26,7 +47,7 @@ class FullSyncManager:
# Overwrite existing db.
col.close()
try:
os.replace(temp_db_path, session.get_collection_path())
shutil.copyfile(temp_db_path, session.get_collection_path())
finally:
col.reopen()
# Reopen the media database
@ -34,13 +55,27 @@ class FullSyncManager:
return "OK"
def download(self, col: Collection, session) -> bytes:
"""Download the binary database.
def download(self, col, session):
col.close()
Performs a downgrade to database schema 11 before sending the database
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:
data = open(session.get_collection_path(), 'rb').read()
with open(db_path, 'rb') as tmp:
data = tmp.read()
finally:
col.reopen()
# Reopen the media database
col.media.connect()
return data