diff options
author | Victor Shyba <victor1984@riseup.net> | 2017-11-11 00:37:01 -0300 |
---|---|---|
committer | Victor Shyba <victor1984@riseup.net> | 2017-11-13 18:17:15 -0300 |
commit | 8f3fdc2f9c3d4360669c2c7fd89dbd95e0f8dd22 (patch) | |
tree | 7d711a51d896811fe6309eb5a368ed468276a6d8 | |
parent | 914579325d242e2643a964bbf1b271435b5c66cc (diff) |
[feature] apply deletions from server
Sync method to propagate deletions in batch locally.
-- Resolves: #8961
-rw-r--r-- | src/leap/soledad/client/_db/blobs/sql.py | 7 | ||||
-rw-r--r-- | src/leap/soledad/client/_db/blobs/sync.py | 7 | ||||
-rw-r--r-- | tests/server/test_blobs_server.py | 19 |
3 files changed, 33 insertions, 0 deletions
diff --git a/src/leap/soledad/client/_db/blobs/sql.py b/src/leap/soledad/client/_db/blobs/sql.py index c5b0b64b..5337ab87 100644 --- a/src/leap/soledad/client/_db/blobs/sql.py +++ b/src/leap/soledad/client/_db/blobs/sql.py @@ -190,6 +190,13 @@ class SQLiteBlobBackend(object): query = 'DELETE FROM blobs WHERE blob_id = ? AND namespace = ?' return self.dbpool.runQuery(query, (blob_id, namespace,)) + def batch_delete(self, blob_id_list, namespace=''): + query = 'DELETE FROM blobs WHERE blob_id IN ' + size = len(blob_id_list) + query += ('(%s)' % ', '.join(['?' for _ in range(size)])) + values = tuple(blob_id_list) + return self.dbpool.runQuery(query, values) + def _init_tables(conn): # unified init for running under the same lock diff --git a/src/leap/soledad/client/_db/blobs/sync.py b/src/leap/soledad/client/_db/blobs/sync.py index bfdc5fbe..bdfbb983 100644 --- a/src/leap/soledad/client/_db/blobs/sync.py +++ b/src/leap/soledad/client/_db/blobs/sync.py @@ -73,6 +73,12 @@ class BlobsSynchronizer(object): namespace=namespace) @defer.inlineCallbacks + def _apply_deletions_from_server(self, namespace=''): + remote_deletions = self.remote_list(namespace=namespace, deleted=True) + remote_deletions = yield remote_deletions + yield self.local.batch_delete(remote_deletions) + + @defer.inlineCallbacks def send_missing(self, namespace=''): """ Compare local and remote blobs and send what's missing in server. @@ -131,6 +137,7 @@ class BlobsSynchronizer(object): @defer.inlineCallbacks def sync(self, namespace=''): try: + yield self._apply_deletions_from_server(namespace) yield self.refresh_sync_status_from_server(namespace) yield self.fetch_missing(namespace) yield self.send_missing(namespace) diff --git a/tests/server/test_blobs_server.py b/tests/server/test_blobs_server.py index ba4a03d7..4e7b4a3b 100644 --- a/tests/server/test_blobs_server.py +++ b/tests/server/test_blobs_server.py @@ -37,6 +37,7 @@ from leap.soledad.client._db.blobs import SyncStatus from leap.soledad.client._db.blobs import RetriableTransferError from leap.soledad.client._db.blobs import MaximumRetriesError from leap.soledad.client._db import blobs as client_blobs +from leap.soledad.client._document import BlobDoc def sleep(x): @@ -324,6 +325,24 @@ class BlobServerTestCase(unittest.TestCase): @defer.inlineCallbacks @pytest.mark.usefixtures("method_tmpdir") + def test_refresh_deletions_from_server(self): + manager = BlobManager(self.tempdir, self.uri, self.secret, + self.secret, uuid4().hex) + self.addCleanup(manager.close) + blob_id, content = 'delete_me', 'content' + blob_id2 = 'dont_delete_me' + doc1 = BlobDoc(BytesIO(content), blob_id) + doc2 = BlobDoc(BytesIO(content), blob_id2) + yield manager.put(doc1, len(content)) + yield manager.put(doc2, len(content)) + yield manager._delete_from_remote(blob_id) # remote only deletion + self.assertTrue((yield manager.local.exists(blob_id))) + yield manager.sync() + self.assertFalse((yield manager.local.exists(blob_id))) + self.assertTrue((yield manager.local.exists(blob_id2))) + + @defer.inlineCallbacks + @pytest.mark.usefixtures("method_tmpdir") def test_download_corrupted_tag_marks_blob_as_failed(self): user_id = uuid4().hex manager = BlobManager(self.tempdir, self.uri, self.secret, |