~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/store/text.py

[merge] from robert and newformat

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
import os, tempfile
25
25
 
26
26
import bzrlib.store
 
27
from bzrlib.store import hash_prefix
27
28
from bzrlib.trace import mutter
28
 
from bzrlib.errors import BzrError
 
29
from bzrlib.errors import BzrError, FileExists
29
30
 
30
31
from cStringIO import StringIO
31
32
from stat import ST_SIZE
41
42
    Files are stored uncompressed, with no delta compression.
42
43
    """
43
44
 
44
 
    def __init__(self, transport):
 
45
    def __init__(self, transport, prefixed=False):
45
46
        super(TextStore, self).__init__(transport)
 
47
        self._prefixed = prefixed
46
48
 
47
49
    def _check_fileid(self, fileid):
48
50
        if not isinstance(fileid, basestring):
52
54
 
53
55
    def _relpath(self, fileid):
54
56
        self._check_fileid(fileid)
55
 
        return fileid
 
57
        if self._prefixed:
 
58
            return hash_prefix(fileid) + fileid
 
59
        else:
 
60
            return fileid
56
61
 
57
62
    def add(self, f, fileid):
58
63
        """Add contents of a file into the store.
65
70
        if self._transport.has(fn):
66
71
            raise BzrError("store %r already contains id %r" % (self._transport.base, fileid))
67
72
 
 
73
        if self._prefixed:
 
74
            try:
 
75
                self._transport.mkdir(hash_prefix(fileid))
 
76
            except FileExists:
 
77
                pass
 
78
 
68
79
        self._transport.put(fn, f)
69
80
 
70
 
    def _do_copy(self, other, to_copy, pb, permit_failure=False):
71
 
        if isinstance(other, TextStore):
72
 
            return self._copy_multi_text(other, to_copy, pb,
73
 
                    permit_failure=permit_failure)
74
 
        return super(TextStore, self)._do_copy(other, to_copy,
75
 
                pb, permit_failure=permit_failure)
76
 
 
77
 
    def _copy_multi_text(self, other, to_copy, pb,
78
 
            permit_failure=False):
79
 
        # Because of _transport, we can no longer assume
80
 
        # that they are on the same filesystem, we can, however
81
 
        # assume that we only need to copy the exact bytes,
82
 
        # we don't need to process the files.
83
 
 
84
 
        failed = set()
85
 
        if permit_failure:
86
 
            new_to_copy = set()
87
 
            for fileid, has in zip(to_copy, other.has(to_copy)):
88
 
                if has:
89
 
                    new_to_copy.add(fileid)
90
 
                else:
91
 
                    failed.add(fileid)
92
 
            to_copy = new_to_copy
93
 
            #mutter('_copy_multi_text copying %s, failed %s' % (to_copy, failed))
94
 
 
95
 
        paths = [self._relpath(fileid) for fileid in to_copy]
96
 
        count = other._transport.copy_to(paths, self._transport, pb=pb)
97
 
        assert count == len(to_copy)
98
 
        return count, failed
99
 
 
100
81
    def __contains__(self, fileid):
101
82
        """"""
102
83
        fn = self._relpath(fileid)
157
138
            count += 1
158
139
 
159
140
    def __iter__(self):
160
 
        # TODO: case-insensitive?
161
 
        for f in self._transport.list_dir('.'):
162
 
            yield f
 
141
        for relpath, st in self._iter_relpaths():
 
142
            yield os.path.basename(relpath)
163
143
 
164
144
    def __len__(self):
165
 
        return len([f for f in self._transport.list_dir('.')])
166
 
 
 
145
        return len(list(self._iter_relpath()))
167
146
 
168
147
    def __getitem__(self, fileid):
169
148
        """Returns a file reading from a particular entry."""
184
163
        the content."""
185
164
        total = 0
186
165
        count = 0
187
 
        relpaths = [self._relpath(fid) for fid in self]
188
 
        for st in self._transport.stat_multi(relpaths):
 
166
        for relpath, st in self._iter_relpaths():
189
167
            count += 1
190
168
            total += st[ST_SIZE]
191
169