24
24
import os, tempfile
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
30
31
from cStringIO import StringIO
31
32
from stat import ST_SIZE
41
42
Files are stored uncompressed, with no delta compression.
44
def __init__(self, transport):
45
def __init__(self, transport, prefixed=False):
45
46
super(TextStore, self).__init__(transport)
47
self._prefixed = prefixed
47
49
def _check_fileid(self, fileid):
48
50
if not isinstance(fileid, basestring):
53
55
def _relpath(self, fileid):
54
56
self._check_fileid(fileid)
58
return hash_prefix(fileid) + fileid
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))
75
self._transport.mkdir(hash_prefix(fileid))
68
79
self._transport.put(fn, f)
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)
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.
87
for fileid, has in zip(to_copy, other.has(to_copy)):
89
new_to_copy.add(fileid)
93
#mutter('_copy_multi_text copying %s, failed %s' % (to_copy, failed))
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)
100
81
def __contains__(self, fileid):
102
83
fn = self._relpath(fileid)
159
140
def __iter__(self):
160
# TODO: case-insensitive?
161
for f in self._transport.list_dir('.'):
141
for relpath, st in self._iter_relpaths():
142
yield os.path.basename(relpath)
164
144
def __len__(self):
165
return len([f for f in self._transport.list_dir('.')])
168
def __getitem__(self, fileid):
169
"""Returns a file reading from a particular entry."""
170
fn = self._relpath(fileid)
171
# This will throw if the file doesn't exist.
173
f = self._transport.get(fn)
175
raise KeyError('This store (%s) does not contain %s' % (self, fileid))
145
return len(list(self._iter_relpath()))
180
147
def total_size(self):
181
148
"""Return (count, bytes)