~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

  • Committer: Martin Pool
  • Date: 2006-11-03 01:52:12 UTC
  • mto: This revision was merged to the branch mainline in revision 2119.
  • Revision ID: mbp@sourcefrog.net-20061103015212-1e5f881c2152d79f
Review comments

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2006 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 as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
 
 
17
"""TextStore based revision store.
 
18
 
 
19
This stores revisions as individual text entries in a TextStore and 
 
20
requires access to a inventory weave to produce object graphs.
 
21
"""
 
22
 
 
23
 
 
24
from cStringIO import StringIO
 
25
 
 
26
 
 
27
import bzrlib
 
28
import bzrlib.errors as errors
 
29
from bzrlib.store.revision import RevisionStore
 
30
from bzrlib.store.text import TextStore
 
31
from bzrlib.store.versioned import VersionedFileStore
 
32
from bzrlib.transport import get_transport
 
33
from bzrlib.tsort import topo_sort
 
34
 
 
35
 
 
36
class TextRevisionStoreTestFactory(object):
 
37
    """Factory to create a TextRevisionStore for testing.
 
38
 
 
39
    This creates a inventory weave and hooks it into the revision store
 
40
    """
 
41
 
 
42
    def create(self, url):
 
43
        """Create a revision store at url."""
 
44
        t = get_transport(url)
 
45
        t.mkdir('revstore')
 
46
        text_store = TextStore(t.clone('revstore'))
 
47
        return TextRevisionStore(text_store)
 
48
 
 
49
    def __str__(self):
 
50
        return "TextRevisionStore"
 
51
 
 
52
 
 
53
class TextRevisionStore(RevisionStore):
 
54
    """A RevisionStore layering on a TextStore and Inventory weave store."""
 
55
 
 
56
    def __init__(self, text_store, serializer=None):
 
57
        """Create a TextRevisionStore object.
 
58
 
 
59
        :param text_store: the text store to put serialised revisions into.
 
60
        """
 
61
        super(TextRevisionStore, self).__init__(serializer)
 
62
        self.text_store = text_store
 
63
        self.text_store.register_suffix('sig')
 
64
 
 
65
    def _add_revision(self, revision, revision_as_file, transaction):
 
66
        """Template method helper to store revision in this store."""
 
67
        self.text_store.add(revision_as_file, revision.revision_id)
 
68
 
 
69
    def add_revision_signature_text(self, revision_id, signature_text, transaction):
 
70
        """See RevisionStore.add_revision_signature_text()."""
 
71
        self.text_store.add(StringIO(signature_text), revision_id, "sig")
 
72
 
 
73
    def all_revision_ids(self, transaction):
 
74
        """See RevisionStore.all_revision_ids()."""
 
75
        # for TextRevisionStores, this is only functional
 
76
        # on listable transports.
 
77
        assert self.text_store.listable()
 
78
        result_graph = {}
 
79
        for rev_id in self.text_store:
 
80
            rev = self.get_revision(rev_id, transaction)
 
81
            result_graph[rev_id] = rev.parent_ids
 
82
        # remove ghosts
 
83
        for rev_id, parents in result_graph.items():
 
84
            for parent in list(parents):
 
85
                if not parent in result_graph:
 
86
                    del parents[parents.index(parent)]
 
87
        return topo_sort(result_graph.items())
 
88
 
 
89
    def get_revisions(self, revision_ids, transaction):
 
90
        """See RevisionStore.get_revisions()."""
 
91
        revisions = []
 
92
        for revision_id in revision_ids:
 
93
            xml_file = self._get_revision_xml_file(revision_id)
 
94
            try:
 
95
                r = self._serializer.read_revision(xml_file)
 
96
            except SyntaxError, e:
 
97
                raise errors.BzrError('failed to unpack revision_xml',
 
98
                                   [revision_id,
 
99
                                   str(e)])
 
100
            xml_file.close()
 
101
            assert r.revision_id == revision_id
 
102
            revisions.append(r)
 
103
        return revisions 
 
104
 
 
105
    def _get_revision_xml_file(self, revision_id):
 
106
        try:
 
107
            return self.text_store.get(revision_id)
 
108
        except (IndexError, KeyError):
 
109
            raise bzrlib.errors.NoSuchRevision(self, revision_id)
 
110
 
 
111
    def _get_signature_text(self, revision_id, transaction):
 
112
        """See RevisionStore._get_signature_text()."""
 
113
        try:
 
114
            return self.text_store.get(revision_id, suffix='sig').read()
 
115
        except (IndexError, KeyError):
 
116
            raise errors.NoSuchRevision(self, revision_id)
 
117
 
 
118
    def has_revision_id(self, revision_id, transaction):
 
119
        """True if the store contains revision_id."""
 
120
        return (revision_id is None
 
121
                or self.text_store.has_id(revision_id))
 
122
 
 
123
    def _has_signature(self, revision_id, transaction):
 
124
        """See RevisionStore._has_signature()."""
 
125
        return self.text_store.has_id(revision_id, suffix='sig')
 
126
 
 
127
    def total_size(self, transaction):
 
128
        """ See RevisionStore.total_size()."""
 
129
        return self.text_store.total_size()