~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/store/revision/__init__.py

Merge in knit repository use of knits - still not a stable format, but can be experimented with.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2006 by Canonical Ltd
 
2
#
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License version 2 as published by
 
5
# the Free Software Foundation.
 
6
#
 
7
# This program is distributed in the hope that it will be useful,
 
8
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
# GNU General Public License for more details.
 
11
#
 
12
# You should have received a copy of the GNU General Public License
 
13
# along with this program; if not, write to the Free Software
 
14
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
15
 
 
16
"""Revision stores.
 
17
 
 
18
Revision stores are responsible for storing a group of revisions
 
19
and returning some interesting data about them such as ancestors
 
20
and ghosts information.
 
21
"""
 
22
 
 
23
 
 
24
from copy import deepcopy
 
25
from cStringIO import StringIO
 
26
from unittest import TestSuite
 
27
 
 
28
 
 
29
import bzrlib
 
30
import bzrlib.errors as errors
 
31
from bzrlib.trace import mutter
 
32
 
 
33
 
 
34
class RevisionStoreTestProviderAdapter(object):
 
35
    """A tool to generate a suite testing multiple repository stores.
 
36
 
 
37
    This is done by copying the test once for each repository store
 
38
    and injecting the transport_server, transport_readonly_server,
 
39
    and revision-store-factory into each copy.
 
40
    Each copy is also given a new id() to make it easy to identify.
 
41
    """
 
42
 
 
43
    def __init__(self, transport_server, transport_readonly_server, factories):
 
44
        self._transport_server = transport_server
 
45
        self._transport_readonly_server = transport_readonly_server
 
46
        self._factories = factories
 
47
    
 
48
    def adapt(self, test):
 
49
        result = TestSuite()
 
50
        for factory in self._factories:
 
51
            new_test = deepcopy(test)
 
52
            new_test.transport_server = self._transport_server
 
53
            new_test.transport_readonly_server = self._transport_readonly_server
 
54
            new_test.store_factory = factory
 
55
            def make_new_test_id():
 
56
                new_id = "%s(%s)" % (new_test.id(), factory)
 
57
                return lambda: new_id
 
58
            new_test.id = make_new_test_id()
 
59
            result.addTest(new_test)
 
60
        return result
 
61
 
 
62
    @staticmethod
 
63
    def default_test_list():
 
64
        """Generate the default list of revision store permutations to test."""
 
65
        from bzrlib.store.revision.text import TextRevisionStoreTestFactory
 
66
        from bzrlib.store.revision.knit import KnitRevisionStoreFactory
 
67
        result = []
 
68
        # test the fallback InterVersionedFile from weave to annotated knits
 
69
        result.append(TextRevisionStoreTestFactory())
 
70
        result.append(KnitRevisionStoreFactory())
 
71
        return result
 
72
 
 
73
 
 
74
class RevisionStore(object):
 
75
    """A revision store stores revisions."""
 
76
 
 
77
    def __init__(self, serializer=None):
 
78
        if serializer is None:
 
79
            serializer = bzrlib.xml5.serializer_v5
 
80
        self._serializer = serializer
 
81
 
 
82
    def add_revision(self, revision, transaction):
 
83
        """Add revision to the revision store.
 
84
 
 
85
        :param rev: The revision object.
 
86
        """
 
87
        # serialisation : common to all at the moment.
 
88
        rev_tmp = StringIO()
 
89
        self._serializer.write_revision(revision, rev_tmp)
 
90
        rev_tmp.seek(0)
 
91
        self._add_revision(revision, rev_tmp, transaction)
 
92
        mutter('added revision_id {%s}', revision.revision_id)
 
93
 
 
94
    def _add_revision(self, revision, revision_as_file, transaction):
 
95
        """Template method helper to store revision in this store."""
 
96
        raise NotImplementedError(self._add_revision)
 
97
 
 
98
    def add_revision_signature_text(self, revision_id, signature_text, transaction):
 
99
        """Add signature_text as a signature for revision_id."""
 
100
        raise NotImplementedError(self.add_revision_signature_text)
 
101
 
 
102
    def all_revision_ids(self, transaction):
 
103
        """Returns a list of all the revision ids in the revision store. 
 
104
 
 
105
        :return: list of revision_ids in topological order.
 
106
        """
 
107
        raise NotImplementedError(self.all_revision_ids)
 
108
 
 
109
    def get_revision(self, revision_id, transaction):
 
110
        """Return the Revision object for a named revision."""
 
111
        raise NotImplementedError(self.get_revision)
 
112
 
 
113
    def get_signature_text(self, revision_id, transaction):
 
114
        """Get the signature text for the digital signature of revision_id.
 
115
        
 
116
        :return: a signature text.
 
117
        """
 
118
        self._guard_revision(revision_id, transaction)
 
119
        return self._get_signature_text(revision_id, transaction)
 
120
 
 
121
    def _get_signature_text(self, revision_id, transaction):
 
122
        """Helper method for get_signature_text to return the text itself."""
 
123
        raise NotImplementedError(self.get_signature_text)
 
124
 
 
125
    def _guard_revision(self, revision_id, transaction):
 
126
        """Guard method for testing the presence of a revision."""
 
127
        if not self.has_revision_id(revision_id, transaction):
 
128
            raise errors.NoSuchRevision(self, revision_id)
 
129
 
 
130
    def has_revision_id(self, revision_id, transaction):
 
131
        """True if the store contains revision_id."""
 
132
        raise NotImplementedError(self.has_revision_id)
 
133
 
 
134
    def has_signature(self, revision_id, transaction):
 
135
        """True if the store has a signature for revision_id."""
 
136
        self._guard_revision(revision_id, transaction)
 
137
        return self._has_signature(revision_id, transaction)
 
138
 
 
139
    def _has_signature(self, revision_id, transaction):
 
140
        """Return the presence of a signature for revision_id.
 
141
 
 
142
        A worker memrthod for has_signature, this can assume the
 
143
        revision is present.
 
144
        """
 
145
        return NotImplementedError(self._has_signature)
 
146
        
 
147
    def total_size(self, transaction):
 
148
        """How big is the store?
 
149
 
 
150
        :return: (count, bytes) tuple.
 
151
        """
 
152
        raise NotImplementedError(self.total_size)