get_main_database() returned wrong results during test run
[mygpo.git] / mygpo / db / couchdb / __init__.py
blobf72b23a349ddf6b60185aba78df24dc774452d49
1 from operator import itemgetter
2 from collections import namedtuple
4 from couchdbkit.ext.django import loading
6 from couchdbkit import *
9 def get_main_database():
10 return loading.get_db('core')
13 def get_database(user=None):
14 return get_main_database()
17 class BulkException(Exception):
19 def __init__(self, errors):
20 self.errors = errors
23 BulkError = namedtuple('BulkError', 'doc error reason')
26 def __default_reload(db, obj):
27 _id = obj._id
29 if isinstance(obj, Document):
30 return obj.__class__.get(_id)
31 else:
32 return db[_id]
35 __get_obj = itemgetter(0)
37 def bulk_save_retry(obj_funs, db=None, reload_f=__default_reload):
38 """ Saves multiple documents and retries failed ones
40 Objects to be saved are passed as (obj, mod_f), where obj is the CouchDB
41 and mod_f is the modification function that should be applied to it.
43 If saving a document fails, it is again fetched from the database, the
44 modification function is applied again and saving is retried. """
46 db = db or get_main_database()
47 errors = []
49 while True:
51 # apply modification function (and keep funs)
52 obj_funs = [(f(o), f) for (o, f) in obj_funs]
54 # filter those with obj None
55 obj_funs = filter(lambda of: __get_obj(of) is not None, obj_funs)
57 # extract objects
58 objs = map(__get_obj, obj_funs)
60 if not objs:
61 return
63 try:
64 db.save_docs(objs)
65 return
67 except BulkSaveError as ex:
69 new_obj_funs = []
70 for res, (obj, f) in zip(ex.results, obj_funs):
71 if res.get('error', False) == 'conflict':
73 # reload conflicted object
74 obj = reload_f(db, obj)
75 new_obj_funs.append( (obj, f) )
77 elif res.get('error', False):
78 # don't retry other errors
79 err = BulkError(obj, res['error'], res.get('reason', None))
80 errors.append(err)
82 obj_funs = new_obj_funs
84 if errors:
85 raise BulkException(errors)