summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/leap/soledad/backends/objectstore.py183
-rw-r--r--src/leap/soledad/tests/test_logs.py2
-rw-r--r--src/leap/soledad/util.py159
3 files changed, 173 insertions, 171 deletions
diff --git a/src/leap/soledad/backends/objectstore.py b/src/leap/soledad/backends/objectstore.py
index 2ab07675..03694532 100644
--- a/src/leap/soledad/backends/objectstore.py
+++ b/src/leap/soledad/backends/objectstore.py
@@ -1,6 +1,5 @@
from u1db.backends import CommonBackend
from u1db import errors, Document, vectorclock
-from leap.soledad import util as soledadutil
class ObjectStore(CommonBackend):
"""
@@ -12,9 +11,9 @@ class ObjectStore(CommonBackend):
# with the database is established in each implementation, so it can
# ensure that u1db data is configured and up-to-date.
self.set_document_factory(Document)
- self._sync_log = soledadutil.SyncLog()
- self._transaction_log = soledadutil.TransactionLog()
- self._conflict_log = soledadutil.ConflictLog(self._factory)
+ self._sync_log = SyncLog()
+ self._transaction_log = TransactionLog()
+ self._conflict_log = ConflictLog(self._factory)
self._replica_uid = replica_uid
self._ensure_u1db_data()
@@ -139,19 +138,18 @@ class ObjectStore(CommonBackend):
def _set_replica_gen_and_trans_id(self, other_replica_uid,
other_generation, other_transaction_id):
- self._get_u1db_data()
+ return self._do_set_replica_gen_and_trans_id(
+ other_replica_uid,
+ other_generation,
+ other_transaction_id)
+
+ def _do_set_replica_gen_and_trans_id(self, other_replica_uid,
+ other_generation, other_transaction_id):
self._sync_log.set_replica_gen_and_trans_id(other_replica_uid,
other_generation,
other_transaction_id)
self._set_u1db_data()
- def _do_set_replica_gen_and_trans_id(self, other_replica_uid,
- other_generation, other_transaction_id):
- return self._set_replica_gen_and_trans_id(
- other_replica_uid,
- other_generation,
- other_transaction_id)
-
def _get_transaction_log(self):
self._get_u1db_data()
return self._transaction_log.get_transaction_log()
@@ -276,3 +274,164 @@ class ObjectStore(CommonBackend):
self._add_conflict(doc.doc_id, my_doc.rev, my_doc.get_json())
doc.has_conflicts = True
self._put_and_update_indexes(my_doc, doc)
+
+
+#----------------------------------------------------------------------------
+# U1DB's Transaction, Sync, and conflict Logs
+#----------------------------------------------------------------------------
+
+class SimpleList(object):
+ def __init__(self):
+ self._log = []
+
+ def _set_log(self, log):
+ self._log = log
+
+ def _get_log(self):
+ return self._log
+
+ log = property(
+ _get_log, _set_log, doc="Log contents.")
+
+ def append(self, msg):
+ self._log.append(msg)
+
+ def reduce(self, func, initializer=None):
+ return reduce(func, self._log, initializer)
+
+ def map(self, func):
+ return map(func, self._get_log())
+
+ def filter(self, func):
+ return filter(func, self._get_log())
+
+
+class TransactionLog(SimpleList):
+ """
+ An ordered list of (generation, doc_id, transaction_id) tuples.
+ """
+
+ def _set_log(self, log):
+ self._log = log
+
+ def _get_log(self):
+ return sorted(self._log, reverse=True)
+
+ log = property(
+ _get_log, _set_log, doc="Log contents.")
+
+ def get_generation(self):
+ """
+ Return the current generation.
+ """
+ gens = self.map(lambda x: x[0])
+ if not gens:
+ return 0
+ return max(gens)
+
+ def get_generation_info(self):
+ """
+ Return the current generation and transaction id.
+ """
+ if not self._log:
+ return(0, '')
+ info = self.map(lambda x: (x[0], x[2]))
+ return reduce(lambda x, y: x if (x[0] > y[0]) else y, info)
+
+ def get_trans_id_for_gen(self, gen):
+ """
+ Get the transaction id corresponding to a particular generation.
+ """
+ log = self.reduce(lambda x, y: y if y[0] == gen else x)
+ if log is None:
+ return None
+ return log[2]
+
+ def whats_changed(self, old_generation):
+ """
+ Return a list of documents that have changed since old_generation.
+ """
+ results = self.filter(lambda x: x[0] > old_generation)
+ seen = set()
+ changes = []
+ newest_trans_id = ''
+ for generation, doc_id, trans_id in results:
+ if doc_id not in seen:
+ changes.append((doc_id, generation, trans_id))
+ seen.add(doc_id)
+ if changes:
+ cur_gen = changes[0][1] # max generation
+ newest_trans_id = changes[0][2]
+ changes.reverse()
+ else:
+ results = self._get_log()
+ if not results:
+ cur_gen = 0
+ newest_trans_id = ''
+ else:
+ cur_gen, _, newest_trans_id = results[0]
+
+ return cur_gen, newest_trans_id, changes
+
+
+ def get_transaction_log(self):
+ """
+ Return only a list of (doc_id, transaction_id)
+ """
+ return map(lambda x: (x[1], x[2]), sorted(self._log))
+
+
+class SyncLog(SimpleList):
+ """
+ A list of (replica_id, generation, transaction_id) tuples.
+ """
+
+ def find_by_replica_uid(self, replica_uid):
+ if not self._get_log():
+ return ()
+ return self.reduce(lambda x, y: y if y[0] == replica_uid else x)
+
+ def get_replica_gen_and_trans_id(self, other_replica_uid):
+ """
+ Return the last known generation and transaction id for the other db
+ replica.
+ """
+ info = self.find_by_replica_uid(other_replica_uid)
+ if not info:
+ return (0, '')
+ return (info[1], info[2])
+
+ def set_replica_gen_and_trans_id(self, other_replica_uid,
+ other_generation, other_transaction_id):
+ """
+ Set the last-known generation and transaction id for the other
+ database replica.
+ """
+ self._log = self.filter(lambda x: x[0] != other_replica_uid)
+ self.append((other_replica_uid, other_generation,
+ other_transaction_id))
+
+class ConflictLog(SimpleList):
+ """
+ A list of (doc_id, my_doc_rev, my_content) tuples.
+ """
+
+ def __init__(self, factory):
+ super(ConflictLog, self).__init__()
+ self._factory = factory
+
+ def delete_conflicts(self, conflicts):
+ for conflict in conflicts:
+ self._log = self.filter(lambda x:
+ x[0] != conflict[0] or x[1] != conflict[1])
+
+ def get_conflicts(self, doc_id):
+ conflicts = self.filter(lambda x: x[0] == doc_id)
+ if not conflicts:
+ return []
+ return reversed(map(lambda x: self._factory(doc_id, x[1], x[2]),
+ conflicts))
+
+ def has_conflicts(self, doc_id):
+ return bool(self.filter(lambda x: x[0] == doc_id))
+
diff --git a/src/leap/soledad/tests/test_logs.py b/src/leap/soledad/tests/test_logs.py
index 2102b671..a6c6e282 100644
--- a/src/leap/soledad/tests/test_logs.py
+++ b/src/leap/soledad/tests/test_logs.py
@@ -1,5 +1,5 @@
import unittest2 as unittest
-from leap.soledad.util import TransactionLog, SyncLog, ConflictLog
+from leap.soledad.backends.objectstore import TransactionLog, SyncLog, ConflictLog
class LogTestCase(unittest.TestCase):
diff --git a/src/leap/soledad/util.py b/src/leap/soledad/util.py
index 8a8bedfb..a26bff31 100644
--- a/src/leap/soledad/util.py
+++ b/src/leap/soledad/util.py
@@ -53,161 +53,4 @@ class GPGWrapper(gnupg.GPG):
return result
-#----------------------------------------------------------------------------
-# u1db Transaction and Sync logs.
-#----------------------------------------------------------------------------
-
-class SimpleLog(object):
- def __init__(self):
- self._log = []
-
- def _set_log(self, log):
- self._log = log
-
- def _get_log(self):
- return self._log
-
- log = property(
- _get_log, _set_log, doc="Log contents.")
-
- def append(self, msg):
- self._log.append(msg)
-
- def reduce(self, func, initializer=None):
- return reduce(func, self._log, initializer)
-
- def map(self, func):
- return map(func, self._get_log())
-
- def filter(self, func):
- return filter(func, self._get_log())
-
-
-class TransactionLog(SimpleLog):
- """
- An ordered list of (generation, doc_id, transaction_id) tuples.
- """
-
- def _set_log(self, log):
- self._log = log
-
- def _get_log(self):
- return sorted(self._log, reverse=True)
-
- log = property(
- _get_log, _set_log, doc="Log contents.")
-
- def get_generation(self):
- """
- Return the current generation.
- """
- gens = self.map(lambda x: x[0])
- if not gens:
- return 0
- return max(gens)
-
- def get_generation_info(self):
- """
- Return the current generation and transaction id.
- """
- if not self._log:
- return(0, '')
- info = self.map(lambda x: (x[0], x[2]))
- return reduce(lambda x, y: x if (x[0] > y[0]) else y, info)
-
- def get_trans_id_for_gen(self, gen):
- """
- Get the transaction id corresponding to a particular generation.
- """
- log = self.reduce(lambda x, y: y if y[0] == gen else x)
- if log is None:
- return None
- return log[2]
-
- def whats_changed(self, old_generation):
- """
- Return a list of documents that have changed since old_generation.
- """
- results = self.filter(lambda x: x[0] > old_generation)
- seen = set()
- changes = []
- newest_trans_id = ''
- for generation, doc_id, trans_id in results:
- if doc_id not in seen:
- changes.append((doc_id, generation, trans_id))
- seen.add(doc_id)
- if changes:
- cur_gen = changes[0][1] # max generation
- newest_trans_id = changes[0][2]
- changes.reverse()
- else:
- results = self._get_log()
- if not results:
- cur_gen = 0
- newest_trans_id = ''
- else:
- cur_gen, _, newest_trans_id = results[0]
-
- return cur_gen, newest_trans_id, changes
-
-
- def get_transaction_log(self):
- """
- Return only a list of (doc_id, transaction_id)
- """
- return map(lambda x: (x[1], x[2]), sorted(self._log))
-
-
-class SyncLog(SimpleLog):
- """
- A list of (replica_id, generation, transaction_id) tuples.
- """
-
- def find_by_replica_uid(self, replica_uid):
- if not self._get_log():
- return ()
- return self.reduce(lambda x, y: y if y[0] == replica_uid else x)
-
- def get_replica_gen_and_trans_id(self, other_replica_uid):
- """
- Return the last known generation and transaction id for the other db
- replica.
- """
- info = self.find_by_replica_uid(other_replica_uid)
- if not info:
- return (0, '')
- return (info[1], info[2])
-
- def set_replica_gen_and_trans_id(self, other_replica_uid,
- other_generation, other_transaction_id):
- """
- Set the last-known generation and transaction id for the other
- database replica.
- """
- self._log = self.filter(lambda x: x[0] != other_replica_uid)
- self.append((other_replica_uid, other_generation,
- other_transaction_id))
-
-class ConflictLog(SimpleLog):
- """
- A list of (doc_id, my_doc_rev, my_content) tuples.
- """
-
- def __init__(self, factory):
- super(ConflictLog, self).__init__()
- self._factory = factory
-
- def delete_conflicts(self, conflicts):
- for conflict in conflicts:
- self._log = self.filter(lambda x:
- x[0] != conflict[0] or x[1] != conflict[1])
-
- def get_conflicts(self, doc_id):
- conflicts = self.filter(lambda x: x[0] == doc_id)
- if not conflicts:
- return []
- return reversed(map(lambda x: self._factory(doc_id, x[1], x[2]),
- conflicts))
-
- def has_conflicts(self, doc_id):
- return bool(self.filter(lambda x: x[0] == doc_id))
+