Move VirtualVersionedFiles and FakeControlFiles to bzr-foreign.
[jelmer/subvertpy.git] / versionedfiles.py
1 # Copyright (C) 2005-2007 Jelmer Vernooij <jelmer@samba.org>
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 3 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, see <http://www.gnu.org/licenses/>.
15
16 from bzrlib import osutils, urlutils
17 from bzrlib.versionedfile import FulltextContentFactory, VersionedFiles, VirtualVersionedFiles
18
19 from bzrlib.plugins.svn.core import SubversionException
20 from bzrlib.plugins.svn.errors import ERR_FS_NOT_FILE
21 from bzrlib.plugins.svn.foreign.versionedfiles import VirtualSignatureTexts, VirtualRevisionTexts, VirtualInventoryTexts
22
23 from cStringIO import StringIO
24
25 class SvnTexts(VersionedFiles):
26     """Subversion texts backend."""
27
28     def __init__(self, repository):
29         self.repository = repository
30
31     def check(self, progressbar=None):
32         return True
33
34     def add_mpdiffs(self, records):
35         raise NotImplementedError(self.add_mpdiffs)
36
37     def get_record_stream(self, keys, ordering, include_delta_closure):
38         # TODO: there may be valid text revisions that only exist as 
39         # ghosts in the repository itself. This function will 
40         # not be able to report them.
41         # TODO: Sort keys by file id and issue just one get_file_revs() call 
42         # per file-id ?
43         for (fileid, revid) in list(keys):
44             (branch, revnum, mapping) = self.repository.lookup_revision_id(revid)
45             map = self.repository.get_fileid_map(revnum, branch, mapping)
46             # Unfortunately, the map is the other way around
47             lines = None
48             for k, (v, ck) in map.items():
49                 if v == fileid:
50                     try:
51                         stream = StringIO()
52                         self.repository.transport.get_file(urlutils.join(branch, k), stream, revnum)
53                         stream.seek(0)
54                         lines = stream.readlines()
55                     except SubversionException, (_, num):
56                         if num == ERR_FS_NOT_FILE:
57                             lines = []
58                         else:
59                             raise
60                     break
61             if lines is None:
62                 raise Exception("Inconsistent key specified: (%r,%r)" % (fileid, revid))
63             yield FulltextContentFactory((fileid, revid), None, 
64                         sha1=osutils.sha_strings(lines),
65                         text=''.join(lines))
66
67     def get_parent_map(self, keys):
68         invs = {}
69
70         # First, figure out the revision number/path
71         ret = {}
72         for (fileid, revid) in keys:
73             # FIXME: Evil hack
74             ret[(fileid, revid)] = None
75         return ret
76
77     # TODO: annotate, get_sha1s, iter_lines_added_or_present_in_keys, keys
78
79
80