summaryrefslogtreecommitdiff
path: root/backends
diff options
context:
space:
mode:
Diffstat (limited to 'backends')
-rw-r--r--backends/__init__.py4
-rw-r--r--backends/couch.py31
-rw-r--r--backends/leap_backend.py14
-rw-r--r--backends/objectstore.py13
-rw-r--r--backends/sqlcipher.py3
5 files changed, 56 insertions, 9 deletions
diff --git a/backends/__init__.py b/backends/__init__.py
index 72907f37..61438e8a 100644
--- a/backends/__init__.py
+++ b/backends/__init__.py
@@ -1,3 +1,7 @@
+"""
+Backends that extend U1DB functionality.
+"""
+
import objectstore
diff --git a/backends/couch.py b/backends/couch.py
index 30fd449c..7c884aee 100644
--- a/backends/couch.py
+++ b/backends/couch.py
@@ -1,3 +1,5 @@
+"""A U1DB backend that uses CouchDB as its persistence layer."""
+
# general imports
import uuid
from base64 import b64encode, b64decode
@@ -22,14 +24,16 @@ except ImportError:
class InvalidURLError(Exception):
+ """Exception raised when Soledad encounters a malformed URL."""
pass
class CouchDatabase(ObjectStore):
- """A U1DB implementation that uses Couch as its persistence layer."""
+ """A U1DB backend that uses Couch as its persistence layer."""
@classmethod
def open_database(cls, url, create):
+ """Open a U1DB database using CouchDB as backend."""
# get database from url
m = re.match('(^https?://[^/]+)/(.+)$', url)
if not m:
@@ -69,9 +73,7 @@ class CouchDatabase(ObjectStore):
#-------------------------------------------------------------------------
def _get_doc(self, doc_id, check_for_conflicts=False):
- """
- Get just the document content, without fancy handling.
- """
+ """Get just the document content, without fancy handling."""
cdoc = self._database.get(doc_id)
if cdoc is None:
return None
@@ -90,7 +92,7 @@ class CouchDatabase(ObjectStore):
return doc
def get_all_docs(self, include_deleted=False):
- """Get all documents from the database."""
+ """Get the JSON content for all documents in the database."""
generation = self._get_generation()
results = []
for doc_id in self._database:
@@ -103,6 +105,7 @@ class CouchDatabase(ObjectStore):
return (generation, results)
def _put_doc(self, doc):
+ """Store document in database."""
# prepare couch's Document
cdoc = CouchDocument()
cdoc['_id'] = doc.doc_id
@@ -122,9 +125,15 @@ class CouchDatabase(ObjectStore):
self._database.delete_attachment(cdoc, 'u1db_json')
def get_sync_target(self):
+ """
+ Return a SyncTarget object, for another u1db to synchronize with.
+ """
return CouchSyncTarget(self)
def create_index(self, index_name, *index_expressions):
+ """
+ Create a named index, which can then be queried for future lookups.
+ """
if index_name in self._indexes:
if self._indexes[index_name]._definition == list(
index_expressions):
@@ -142,6 +151,7 @@ class CouchDatabase(ObjectStore):
self._store_u1db_data()
def close(self):
+ """Release any resources associated with this database."""
# TODO: fix this method so the connection is properly closed and
# test_close (+tearDown, which deletes the db) works without problems.
self._url = None
@@ -152,6 +162,7 @@ class CouchDatabase(ObjectStore):
return True
def sync(self, url, creds=None, autocreate=True):
+ """Synchronize documents with remote replica exposed at url."""
from u1db.sync import Synchronizer
return Synchronizer(self, CouchSyncTarget(url, creds=creds)).sync(
autocreate=autocreate)
@@ -206,6 +217,7 @@ class CouchDatabase(ObjectStore):
#-------------------------------------------------------------------------
def delete_database(self):
+ """Delete a U1DB CouchDB database."""
del(self._server[self._dbname])
def _dump_indexes_as_json(self):
@@ -228,6 +240,7 @@ class CouchDatabase(ObjectStore):
class CouchSyncTarget(LocalSyncTarget):
def get_sync_info(self, source_replica_uid):
+ """Return information about known state."""
source_gen, source_trans_id = self._db._get_replica_gen_and_trans_id(
source_replica_uid)
my_gen, my_trans_id = self._db._get_generation_info()
@@ -237,6 +250,7 @@ class CouchSyncTarget(LocalSyncTarget):
def record_sync_info(self, source_replica_uid, source_replica_generation,
source_replica_transaction_id):
+ """Record tip information for another replica."""
if self._trace_hook:
self._trace_hook('record_sync_info')
self._db._set_replica_gen_and_trans_id(
@@ -245,25 +259,26 @@ class CouchSyncTarget(LocalSyncTarget):
class CouchServerState(ServerState):
- """
- Inteface of the WSGI server with the CouchDB backend.
- """
+ """Inteface of the WSGI server with the CouchDB backend."""
def __init__(self, couch_url):
self.couch_url = couch_url
def open_database(self, dbname):
+ """Open a database at the given location."""
# TODO: open couch
from leap.soledad.backends.couch import CouchDatabase
return CouchDatabase.open_database(self.couch_url + '/' + dbname,
create=False)
def ensure_database(self, dbname):
+ """Ensure database at the given location."""
from leap.soledad.backends.couch import CouchDatabase
db = CouchDatabase.open_database(self.couch_url + '/' + dbname,
create=True)
return db, db._replica_uid
def delete_database(self, dbname):
+ """Delete database at the given location."""
from leap.soledad.backends.couch import CouchDatabase
CouchDatabase.delete_database(self.couch_url + '/' + dbname)
diff --git a/backends/leap_backend.py b/backends/leap_backend.py
index c3c52ee6..571cd8ca 100644
--- a/backends/leap_backend.py
+++ b/backends/leap_backend.py
@@ -1,3 +1,8 @@
+"""
+A U1DB backend that encrypts data before sending to server and decrypts after
+receiving.
+"""
+
try:
import simplejson as json
except ImportError:
@@ -13,14 +18,23 @@ import uuid
class NoDefaultKey(Exception):
+ """
+ Exception to signal that there's no default OpenPGP key configured.
+ """
pass
class NoSoledadInstance(Exception):
+ """
+ Exception to signal that no Soledad instance was found.
+ """
pass
class DocumentEncryptionFailed(Exception):
+ """
+ Exception to signal the failure of document encryption.
+ """
pass
diff --git a/backends/objectstore.py b/backends/objectstore.py
index d7aa3049..1ac03df4 100644
--- a/backends/objectstore.py
+++ b/backends/objectstore.py
@@ -1,3 +1,11 @@
+"""
+Abstract U1DB backend to handle storage using object stores (like CouchDB, for
+example.
+
+Right now, this is only used by CouchDatabase backend, but can also be
+extended to implement OpenStack or Amazon S3 storage, for example.
+"""
+
from u1db.backends.inmemory import InMemoryDatabase
from u1db import errors
@@ -37,6 +45,7 @@ class ObjectStore(InMemoryDatabase):
raise NotImplementedError(self.get_all_docs)
def delete_doc(self, doc):
+ """Mark a document as deleted."""
old_doc = self._get_doc(doc.doc_id, check_for_conflicts=True)
if old_doc is None:
raise errors.DocumentDoesNotExist
@@ -55,9 +64,13 @@ class ObjectStore(InMemoryDatabase):
# index-related methods
def create_index(self, index_name, *index_expressions):
+ """
+ Create an named index, which can then be queried for future lookups.
+ """
raise NotImplementedError(self.create_index)
def delete_index(self, index_name):
+ """Remove a named index."""
super(ObjectStore, self).delete_index(index_name)
self._store_u1db_data()
diff --git a/backends/sqlcipher.py b/backends/sqlcipher.py
index c902b466..9a508dc2 100644
--- a/backends/sqlcipher.py
+++ b/backends/sqlcipher.py
@@ -14,7 +14,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with u1db. If not, see <http://www.gnu.org/licenses/>.
-"""A U1DB implementation that uses SQLCipher as its persistence layer."""
+"""A U1DB backend that uses SQLCipher as its persistence layer."""
import os
from pysqlcipher import dbapi2
@@ -125,6 +125,7 @@ class SQLCipherDatabase(SQLitePartialExpandDatabase):
@classmethod
def open_database(cls, sqlite_file, password, create, backend_cls=None,
document_factory=None, soledad=None):
+ """Open U1DB database using SQLCipher as backend."""
try:
return cls._open_database(sqlite_file, password,
document_factory=document_factory,