/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/store/__init__.py

 * New ``versionedfile.KeyMapper`` interface to abstract out the access to
   underyling .knit/.kndx etc files in repositories with partitioned
   storage. (Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
35
35
    osutils,
36
36
    symbol_versioning,
37
37
    urlutils,
 
38
    versionedfile,
38
39
    )
39
40
from bzrlib.errors import BzrError, UnlistableStore, TransportNotPossible
40
41
from bzrlib.symbol_versioning import (
189
190
        raise NotImplementedError('children need to implement this function.')
190
191
 
191
192
    def _check_fileid(self, fileid):
192
 
        if not isinstance(fileid, basestring):
193
 
            raise TypeError('Fileids should be a string type: %s %r' % (type(fileid), fileid))
 
193
        if type(fileid) != str:
 
194
            raise TypeError('Fileids should be bytestrings: %s %r' % (
 
195
                type(fileid), fileid))
194
196
        if '\\' in fileid or '/' in fileid:
195
197
            raise ValueError("invalid store id %r" % fileid)
196
198
 
257
259
        # will just use the filesystem defaults
258
260
        self._dir_mode = dir_mode
259
261
        self._file_mode = file_mode
260
 
 
261
 
    def _unescape(self, file_id):
262
 
        """If filename escaping is enabled for this store, unescape and return the filename."""
263
 
        if self._escaped:
264
 
            return urllib.unquote(file_id)
 
262
        # Create a key mapper to use
 
263
        if escaped and prefixed:
 
264
            self._mapper = versionedfile.HashEscapedPrefixMapper()
 
265
        elif not escaped and prefixed:
 
266
            self._mapper = versionedfile.HashPrefixMapper()
 
267
        elif self._escaped:
 
268
            import pdb;pdb.set_trace()
 
269
            raise ValueError("escaped unprefixed stores are not permitted.")
265
270
        else:
266
 
            return file_id
 
271
            self._mapper = versionedfile.PrefixMapper()
267
272
 
268
273
    def _iter_files_recursive(self):
269
274
        """Iterate through the files in the transport."""
284
289
                    if name.endswith('.' + suffix):
285
290
                        skip = True
286
291
            if not skip:
287
 
                yield self._unescape(name)
 
292
                yield self._mapper.unmap(name)[0]
288
293
 
289
294
    def __len__(self):
290
295
        return len(list(self.__iter__()))
298
303
                self._check_fileid(suffix)
299
304
        else:
300
305
            suffixes = []
301
 
        fileid = self._escape_file_id(fileid)
302
 
        if self._prefixed:
303
 
            # hash_prefix adds the '/' separator
304
 
            prefix = self.hash_prefix(fileid, escaped=True)
305
 
        else:
306
 
            prefix = ''
307
 
        path = prefix + fileid
 
306
        path = self._mapper.map((fileid,))
308
307
        full_path = u'.'.join([path] + suffixes)
309
308
        return urlutils.escape(full_path)
310
309
 
311
 
    def _escape_file_id(self, file_id):
312
 
        """Turn a file id into a filesystem safe string.
313
 
 
314
 
        This is similar to a plain urllib.quote, except
315
 
        it uses specific safe characters, so that it doesn't
316
 
        have to translate a lot of valid file ids.
317
 
        """
318
 
        if not self._escaped:
319
 
            return file_id
320
 
        if isinstance(file_id, unicode):
321
 
            file_id = file_id.encode('utf-8')
322
 
        # @ does not get escaped. This is because it is a valid
323
 
        # filesystem character we use all the time, and it looks
324
 
        # a lot better than seeing %40 all the time.
325
 
        safe = "abcdefghijklmnopqrstuvwxyz0123456789-_@,."
326
 
        r = [((c in safe) and c or ('%%%02x' % ord(c)))
327
 
             for c in file_id]
328
 
        return ''.join(r)
329
 
 
330
 
    def hash_prefix(self, fileid, escaped=False):
331
 
        # fileid should be unescaped
332
 
        if not escaped and self._escaped:
333
 
            fileid = self._escape_file_id(fileid)
334
 
        return "%02x/" % (adler32(fileid) & 0xff)
335
 
 
336
310
    def __repr__(self):
337
311
        if self._transport is None:
338
312
            return "%s(None)" % (self.__class__.__name__)