Пример #1
0
 def _parse_sync_stream(self, data, return_doc_cb, ensure_callback=None):
     parts = data.splitlines()  # one at a time
     if not parts or parts[0] != '[':
         raise BrokenSyncStream
     data = parts[1:-1]
     comma = False
     if data:
         line, comma = utils.check_and_strip_comma(data[0])
         res = json.loads(line)
         if ensure_callback and 'replica_uid' in res:
             ensure_callback(res['replica_uid'])
         for entry in data[1:]:
             if not comma:  # missing in between comma
                 raise BrokenSyncStream
             line, comma = utils.check_and_strip_comma(entry)
             entry = json.loads(line)
             doc = Document(entry['id'], entry['rev'], entry['content'])
             return_doc_cb(doc, entry['gen'], entry['trans_id'])
     if parts[-1] != ']':
         try:
             partdic = json.loads(parts[-1])
         except ValueError:
             pass
         else:
             if isinstance(partdic, dict):
                 self._error(partdic)
         raise BrokenSyncStream
     if not data or comma:  # no entries or bad extra comma
         raise BrokenSyncStream
     return res
Пример #2
0
    def post_put(self, id, rev, content, gen, trans_id, number_of_docs,
                 doc_idx):
        """
        Put one incoming document into the server replica.

        :param id: The id of the incoming document.
        :type id: str
        :param rev: The revision of the incoming document.
        :type rev: str
        :param content: The content of the incoming document.
        :type content: dict
        :param gen: The source replica generation corresponding to the
                    revision of the incoming document.
        :type gen: int
        :param trans_id: The source replica transaction id corresponding to
                         the revision of the incoming document.
        :type trans_id: str
        :param number_of_docs: The total amount of documents sent on this sync
                               session.
        :type number_of_docs: int
        :param doc_idx: The index of the current document.
        :type doc_idx: int
        """
        doc = Document(id, rev, content)
        self._staging.append((doc, gen, trans_id, number_of_docs, doc_idx))
Пример #3
0
    def test_put_doc(self):
        self.response_val = {'rev': 'doc-rev'}, {}
        doc = Document('doc-id', None, '{"v": 1}')
        res = self.db.put_doc(doc)
        self.assertEqual('doc-rev', res)
        self.assertEqual('doc-rev', doc.rev)
        self.assertEqual(('PUT', ['doc', 'doc-id'], {},
                          '{"v": 1}', 'application/json'), self.got)

        self.response_val = {'rev': 'doc-rev-2'}, {}
        doc.content = {"v": 2}
        res = self.db.put_doc(doc)
        self.assertEqual('doc-rev-2', res)
        self.assertEqual('doc-rev-2', doc.rev)
        self.assertEqual(('PUT', ['doc', 'doc-id'], {'old_rev': 'doc-rev'},
                          '{"v": 2}', 'application/json'), self.got)
Пример #4
0
 def put(self, content, old_rev=None):
     doc = Document(self.id, old_rev, content)
     doc_rev = self.db.put_doc(doc)
     if old_rev is None:
         status = 201  # created
     else:
         status = 200
     self.responder.send_response_json(status, rev=doc_rev)
 def test_doc_ids_needing_quoting(self):
     db0 = self.request_state._create_database('db0')
     db = http_database.HTTPDatabase.open_database(self.getURL('db0'),
                                                   create=False)
     doc = Document('%fff', None, '{}')
     db.put_doc(doc)
     self.assertGetDoc(db0, '%fff', doc.rev, '{}', False)
     self.assertGetDoc(db, '%fff', doc.rev, '{}', False)
 def test_delete_doc(self):
     self.response_val = {'rev': 'doc-rev-gone'}, {}
     doc = Document('doc-id', 'doc-rev', None)
     self.db.delete_doc(doc)
     self.assertEqual('doc-rev-gone', doc.rev)
     self.assertEqual(('DELETE', ['doc', 'doc-id'], {
         'old_rev': 'doc-rev'
     }, None, None), self.got)
    def test_put_doc(self):
        self.response_val = {'rev': 'doc-rev'}, {}
        doc = Document('doc-id', None, '{"v": 1}')
        res = self.db.put_doc(doc)
        self.assertEqual('doc-rev', res)
        self.assertEqual('doc-rev', doc.rev)
        self.assertEqual(
            ('PUT', ['doc', 'doc-id'], {}, '{"v": 1}', 'application/json'),
            self.got)

        self.response_val = {'rev': 'doc-rev-2'}, {}
        doc.content = {"v": 2}
        res = self.db.put_doc(doc)
        self.assertEqual('doc-rev-2', res)
        self.assertEqual('doc-rev-2', doc.rev)
        self.assertEqual(('PUT', ['doc', 'doc-id'], {
            'old_rev': 'doc-rev'
        }, '{"v": 2}', 'application/json'), self.got)
Пример #8
0
 def _prune_conflicts(self, doc, doc_vcr):
     if self._has_conflicts(doc.doc_id):
         autoresolved = False
         remaining_conflicts = []
         cur_conflicts = self._conflicts[doc.doc_id]
         for c_rev, c_doc in cur_conflicts:
             c_vcr = vectorclock.VectorClockRev(c_rev)
             if doc_vcr.is_newer(c_vcr):
                 continue
             if doc.same_content_as(Document(doc.doc_id, c_rev, c_doc)):
                 doc_vcr.maximize(c_vcr)
                 autoresolved = True
                 continue
             remaining_conflicts.append((c_rev, c_doc))
         if autoresolved:
             doc_vcr.increment(self._replica_uid)
             doc.rev = doc_vcr.as_str()
         self._replace_conflicts(doc, remaining_conflicts)
Пример #9
0
def make_document_for_test(test, doc_id, rev, content, has_conflicts=False):
    return Document(doc_id, rev, content, has_conflicts=has_conflicts)
Пример #10
0
 def post_stream_entry(self, id, rev, content, gen, trans_id):
     doc = Document(id, rev, content)
     self.sync_exch.insert_doc_from_source(doc, gen, trans_id)
Пример #11
0
 def delete(self, old_rev=None):
     doc = Document(self.id, old_rev, None)
     self.db.delete_doc(doc)
     self.responder.send_response_json(200, rev=doc.rev)