~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/store/versioned/__init__.py

  • Committer: Martin Pool
  • Date: 2006-04-12 04:45:32 UTC
  • mfrom: (1608.2.13 bzr.mbp.escape-stores)
  • mto: This revision was merged to the branch mainline in revision 1657.
  • Revision ID: mbp@sourcefrog.net-20060412044532-fc8c5c9408aae88b
[merge][wip] Storage escaping

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005 Canonical Ltd
 
1
# Copyright (C) 2005, 2006 Canonical Ltd
2
2
 
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
24
24
import urllib
25
25
 
26
26
from bzrlib.weavefile import read_weave, write_weave_v5
27
 
from bzrlib.weave import WeaveFile
28
 
from bzrlib.store import TransportStore, hash_prefix
 
27
from bzrlib.weave import WeaveFile, Weave
 
28
from bzrlib.store import TransportStore
29
29
from bzrlib.atomicfile import AtomicFile
30
30
from bzrlib.errors import NoSuchFile, FileExists
31
31
from bzrlib.symbol_versioning import *
32
32
from bzrlib.trace import mutter
 
33
import bzrlib.ui
33
34
 
34
35
 
35
36
class VersionedFileStore(TransportStore):
36
37
    """Collection of many versioned files in a transport."""
37
38
 
 
39
    # TODO: Rather than passing versionedfile_kwargs, perhaps pass in a
 
40
    # transport factory callable?
38
41
    def __init__(self, transport, prefixed=False, precious=False,
39
42
                 dir_mode=None, file_mode=None,
40
43
                 versionedfile_class=WeaveFile,
41
 
                 versionedfile_kwargs={}):
42
 
        super(WeaveStore, self).__init__(transport,
 
44
                 versionedfile_kwargs={},
 
45
                 escaped=False):
 
46
        super(VersionedFileStore, self).__init__(transport,
43
47
                dir_mode=dir_mode, file_mode=file_mode,
44
 
                prefixed=prefixed, compressed=False)
 
48
                prefixed=prefixed, compressed=False, escaped=escaped)
45
49
        self._precious = precious
46
50
        self._versionedfile_class = versionedfile_class
47
51
        self._versionedfile_kwargs = versionedfile_kwargs
63
67
 
64
68
    def filename(self, file_id):
65
69
        """Return the path relative to the transport root."""
66
 
        if self._prefixed:
67
 
            return hash_prefix(file_id) + urllib.quote(file_id)
68
 
        else:
69
 
            return urllib.quote(file_id)
 
70
        return self._relpath(file_id)
70
71
 
71
72
    def __iter__(self):
72
73
        suffixes = self._versionedfile_class.get_suffixes()
74
75
        for relpath in self._iter_files_recursive():
75
76
            for suffix in suffixes:
76
77
                if relpath.endswith(suffix):
77
 
                    id = os.path.basename(relpath[:-len(suffix)])
78
 
                    if not id in ids:
79
 
                        yield id
80
 
                        ids.add(id)
 
78
                    # TODO: use standard remove_suffix function
 
79
                    escaped_id = os.path.basename(relpath[:-len(suffix)])
 
80
                    file_id = self._unescape(escaped_id)
 
81
                    if file_id not in ids:
 
82
                        ids.add(file_id)
 
83
                        yield file_id
 
84
                    break # only one suffix can match
81
85
 
82
86
    def has_id(self, fileid):
83
87
        suffixes = self._versionedfile_class.get_suffixes()
101
105
            self._transport.delete(filename + suffix)
102
106
        self._clear_cache_id(file_id, transaction)
103
107
 
 
108
    def _get(self, file_id):
 
109
        return self._transport.get(self.filename(file_id))
 
110
 
 
111
    def _put(self, file_id, f):
 
112
        fn = self.filename(file_id)
 
113
        try:
 
114
            return self._transport.put(fn, f, mode=self._file_mode)
 
115
        except NoSuchFile:
 
116
            if not self._prefixed:
 
117
                raise
 
118
            self._transport.mkdir(os.path.dirname(fn), mode=self._dir_mode)
 
119
            return self._transport.put(fn, f, mode=self._file_mode)
 
120
 
104
121
    def get_weave(self, file_id, transaction):
105
122
        weave = transaction.map.find_weave(file_id)
106
123
        if weave is not None:
128
145
 
129
146
        Returned as a list of lines.
130
147
        """
131
 
        assert 0
132
148
        w = self.get_weave(file_id, transaction)
133
149
        return w.get_lines(rev_id)
134
150
    
151
167
                # unexpected error - NoSuchFile is raised on a missing dir only and that
152
168
                # only occurs when we are prefixed.
153
169
                raise
154
 
            self._transport.mkdir(hash_prefix(file_id), mode=self._dir_mode)
155
 
            weave = self._versionedfile_class(self.filename(file_id), self._transport, self._file_mode, create=True,
 
170
            self._transport.mkdir(self.hash_prefix(file_id), mode=self._dir_mode)
 
171
            weave = self._versionedfile_class(self.filename(file_id), self._transport, 
 
172
                                              self._file_mode, create=True,
156
173
                                              **self._versionedfile_kwargs)
157
174
        return weave
158
175
 
252
269
            # we are copying single objects, and there may be open tranasactions
253
270
            # so again with the passthrough
254
271
            to_transaction = PassThroughTransaction()
 
272
        pb = bzrlib.ui.ui_factory.nested_progress_bar()
255
273
        for count, f in enumerate(file_ids):
256
274
            mutter("copy weave {%s} into %s", f, self)
257
 
            if pb:
258
 
                pb.update('copy', count, len(file_ids))
 
275
            pb.update('copy', count, len(file_ids))
259
276
            # if we have it in cache, its faster.
260
277
            # joining is fast with knits, and bearable for weaves -
261
278
            # indeed the new case can be optimised if needed.
262
279
            target = self._make_new_versionedfile(f, to_transaction)
263
280
            target.join(from_store.get_weave(f, from_transaction))
264
 
        if pb:
265
 
            pb.clear()
 
281
        pb.finished()
266
282
 
267
283
    def total_size(self):
268
284
        count, bytes =  super(VersionedFileStore, self).total_size()