1
# Copyright (C) 2006 Canonical Ltd
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.
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.
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
17
"""TextStore based revision store.
19
This stores revisions as individual text entries in a TextStore and
20
requires access to a inventory weave to produce object graphs.
24
from cStringIO import StringIO
31
revision as _mod_revision,
33
from bzrlib.store.revision import RevisionStore
34
from bzrlib.store.text import TextStore
35
from bzrlib.store.versioned import VersionedFileStore
36
from bzrlib.transport import get_transport
37
from bzrlib.tsort import topo_sort
40
class TextRevisionStoreTestFactory(object):
41
"""Factory to create a TextRevisionStore for testing.
43
This creates a inventory weave and hooks it into the revision store
46
def create(self, url):
47
"""Create a revision store at url."""
48
t = get_transport(url)
50
text_store = TextStore(t.clone('revstore'))
51
return TextRevisionStore(text_store)
54
return "TextRevisionStore"
57
class TextRevisionStore(RevisionStore):
58
"""A RevisionStore layering on a TextStore and Inventory weave store."""
60
def __init__(self, text_store, serializer=None):
61
"""Create a TextRevisionStore object.
63
:param text_store: the text store to put serialised revisions into.
65
super(TextRevisionStore, self).__init__(serializer)
66
self.text_store = text_store
67
self.text_store.register_suffix('sig')
69
def _add_revision(self, revision, revision_as_file, transaction):
70
"""Template method helper to store revision in this store."""
71
self.text_store.add(revision_as_file, revision.revision_id)
73
def add_revision_signature_text(self, revision_id, signature_text, transaction):
74
"""See RevisionStore.add_revision_signature_text()."""
75
self.text_store.add(StringIO(signature_text), revision_id, "sig")
77
def all_revision_ids(self, transaction):
78
"""See RevisionStore.all_revision_ids()."""
79
# for TextRevisionStores, this is only functional
80
# on listable transports.
81
assert self.text_store.listable()
83
for rev_id in self.text_store:
84
rev = self.get_revision(rev_id, transaction)
85
result_graph[rev_id] = rev.parent_ids
87
for rev_id, parents in result_graph.items():
88
for parent in list(parents):
89
if not parent in result_graph:
90
del parents[parents.index(parent)]
91
return topo_sort(result_graph.items())
93
def get_revisions(self, revision_ids, transaction):
94
"""See RevisionStore.get_revisions()."""
96
for revision_id in revision_ids:
97
xml_file = self._get_revision_xml_file(revision_id)
99
r = self._serializer.read_revision(xml_file)
100
except SyntaxError, e:
101
raise errors.BzrError('failed to unpack revision_xml',
105
assert r.revision_id == revision_id
109
def _get_revision_xml_file(self, revision_id):
110
_mod_revision.check_not_reserved_id(revision_id)
112
return self.text_store.get(revision_id)
113
except (IndexError, KeyError):
114
raise errors.NoSuchRevision(self, revision_id)
116
def _get_signature_text(self, revision_id, transaction):
117
"""See RevisionStore._get_signature_text()."""
119
return self.text_store.get(revision_id, suffix='sig').read()
120
except (IndexError, KeyError):
121
raise errors.NoSuchRevision(self, revision_id)
123
def has_revision_id(self, revision_id, transaction):
124
"""True if the store contains revision_id."""
125
return (_mod_revision.is_null(revision_id)
126
or self.text_store.has_id(revision_id))
128
def _has_signature(self, revision_id, transaction):
129
"""See RevisionStore._has_signature()."""
130
return self.text_store.has_id(revision_id, suffix='sig')
132
def total_size(self, transaction):
133
""" See RevisionStore.total_size()."""
134
return self.text_store.total_size()