~bzr-pqm/bzr/bzr.dev

1563.2.21 by Robert Collins
Smoke test for RevisionStore factories creating revision stores.
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
"""TextStore based revision store.
17
18
This stores revisions as individual text entries in a TextStore and 
19
requires access to a inventory weave to produce object graphs.
20
"""
21
22
1563.2.27 by Robert Collins
Add signature text addition to the revisionstore api.
23
from cStringIO import StringIO
24
25
1563.2.23 by Robert Collins
Add add_revision and get_revision methods to RevisionStore
26
import bzrlib
27
import bzrlib.errors as errors
1563.2.21 by Robert Collins
Smoke test for RevisionStore factories creating revision stores.
28
from bzrlib.store.revision import RevisionStore
1563.2.22 by Robert Collins
Move responsibility for repository.has_revision into RevisionStore
29
from bzrlib.store.text import TextStore
1563.2.23 by Robert Collins
Add add_revision and get_revision methods to RevisionStore
30
from bzrlib.store.versioned import VersionedFileStore
1563.2.21 by Robert Collins
Smoke test for RevisionStore factories creating revision stores.
31
from bzrlib.transport import get_transport
1563.2.29 by Robert Collins
Remove all but fetch references to repository.revision_store.
32
from bzrlib.tsort import topo_sort
1563.2.21 by Robert Collins
Smoke test for RevisionStore factories creating revision stores.
33
34
35
class TextRevisionStoreTestFactory(object):
36
    """Factory to create a TextRevisionStore for testing.
37
38
    This creates a inventory weave and hooks it into the revision store
39
    """
40
41
    def create(self, url):
42
        """Create a revision store at url."""
43
        t = get_transport(url)
1563.2.22 by Robert Collins
Move responsibility for repository.has_revision into RevisionStore
44
        t.mkdir('revstore')
45
        text_store = TextStore(t.clone('revstore'))
46
        return TextRevisionStore(text_store)
1563.2.21 by Robert Collins
Smoke test for RevisionStore factories creating revision stores.
47
48
    def __str__(self):
49
        return "TextRevisionStore"
1563.2.22 by Robert Collins
Move responsibility for repository.has_revision into RevisionStore
50
51
52
class TextRevisionStore(RevisionStore):
53
    """A RevisionStore layering on a TextStore and Inventory weave store."""
54
1563.2.28 by Robert Collins
Add total_size to the revision_store api.
55
    def __init__(self, text_store, serializer=None):
1563.2.22 by Robert Collins
Move responsibility for repository.has_revision into RevisionStore
56
        """Create a TextRevisionStore object.
57
58
        :param text_store: the text store to put serialised revisions into.
59
        """
1563.2.28 by Robert Collins
Add total_size to the revision_store api.
60
        super(TextRevisionStore, self).__init__(serializer)
1563.2.22 by Robert Collins
Move responsibility for repository.has_revision into RevisionStore
61
        self.text_store = text_store
1563.2.27 by Robert Collins
Add signature text addition to the revisionstore api.
62
        self.text_store.register_suffix('sig')
1563.2.22 by Robert Collins
Move responsibility for repository.has_revision into RevisionStore
63
1563.2.23 by Robert Collins
Add add_revision and get_revision methods to RevisionStore
64
    def _add_revision(self, revision, revision_as_file, transaction):
65
        """Template method helper to store revision in this store."""
66
        self.text_store.add(revision_as_file, revision.revision_id)
67
1563.2.30 by Robert Collins
Remove all but fetch references to revision_store, making the repository references that are weave specific use the RevisionTextStore.text_store attribute.
68
    def add_revision_signature_text(self, revision_id, signature_text, transaction):
69
        """See RevisionStore.add_revision_signature_text()."""
1563.2.27 by Robert Collins
Add signature text addition to the revisionstore api.
70
        self.text_store.add(StringIO(signature_text), revision_id, "sig")
71
1563.2.29 by Robert Collins
Remove all but fetch references to repository.revision_store.
72
    def all_revision_ids(self, transaction):
73
        """See RevisionStore.all_revision_ids()."""
74
        # for TextRevisionStores, this is only functional
75
        # on listable transports.
76
        assert self.text_store.listable()
77
        result_graph = {}
78
        for rev_id in self.text_store:
79
            rev = self.get_revision(rev_id, transaction)
80
            result_graph[rev_id] = rev.parent_ids
81
        # remove ghosts
82
        for rev_id, parents in result_graph.items():
1594.2.4 by Robert Collins
Merge in knit repository use of knits - still not a stable format, but can be experimented with.
83
            for parent in list(parents):
1563.2.29 by Robert Collins
Remove all but fetch references to repository.revision_store.
84
                if not parent in result_graph:
85
                    del parents[parents.index(parent)]
86
        return topo_sort(result_graph.items())
87
1756.1.2 by Aaron Bentley
Show logs using get_revisions
88
    def get_revisions(self, revision_ids, transaction):
89
        """See RevisionStore.get_revisions()."""
90
        revisions = []
1756.1.5 by Aaron Bentley
Test get_revisions with all repository types (and fix bug...)
91
        for revision_id in revision_ids:
92
            xml_file = self._get_revision_xml_file(revision_id)
93
            try:
1756.1.2 by Aaron Bentley
Show logs using get_revisions
94
                r = self._serializer.read_revision(xml_file)
1756.1.5 by Aaron Bentley
Test get_revisions with all repository types (and fix bug...)
95
            except SyntaxError, e:
96
                raise errors.BzrError('failed to unpack revision_xml',
97
                                   [revision_id,
98
                                   str(e)])
99
            xml_file.close()
1756.1.2 by Aaron Bentley
Show logs using get_revisions
100
            assert r.revision_id == revision_id
101
            revisions.append(r)
102
        return revisions 
1563.2.23 by Robert Collins
Add add_revision and get_revision methods to RevisionStore
103
104
    def _get_revision_xml_file(self, revision_id):
105
        try:
106
            return self.text_store.get(revision_id)
107
        except (IndexError, KeyError):
108
            raise bzrlib.errors.NoSuchRevision(self, revision_id)
109
1563.2.30 by Robert Collins
Remove all but fetch references to revision_store, making the repository references that are weave specific use the RevisionTextStore.text_store attribute.
110
    def _get_signature_text(self, revision_id, transaction):
111
        """See RevisionStore._get_signature_text()."""
112
        try:
113
            return self.text_store.get(revision_id, suffix='sig').read()
114
        except (IndexError, KeyError):
115
            raise errors.NoSuchRevision(self, revision_id)
116
1563.2.22 by Robert Collins
Move responsibility for repository.has_revision into RevisionStore
117
    def has_revision_id(self, revision_id, transaction):
118
        """True if the store contains revision_id."""
119
        return (revision_id is None
120
                or self.text_store.has_id(revision_id))
1563.2.29 by Robert Collins
Remove all but fetch references to repository.revision_store.
121
 
122
    def _has_signature(self, revision_id, transaction):
123
        """See RevisionStore._has_signature()."""
124
        return self.text_store.has_id(revision_id, suffix='sig')
125
1563.2.28 by Robert Collins
Add total_size to the revision_store api.
126
    def total_size(self, transaction):
127
        """ See RevisionStore.total_size()."""
128
        return self.text_store.total_size()