/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
1196 by Martin Pool
- [WIP] retrieve historical texts from weaves
1
# Copyright (C) 2005 Canonical Ltd
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 2 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, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
1393.1.19 by Martin Pool
- add WeaveStore.__iter__, __contains__ and copy_multi()
17
# XXX: Some consideration of the problems that might occur if there are
18
# files whose id differs only in case.  That should probably be forbidden.
19
20
1471 by Robert Collins
Bugfix to previous url escaping patch - include weave stores
21
import errno
22
import os
1393.1.19 by Martin Pool
- add WeaveStore.__iter__, __contains__ and copy_multi()
23
from cStringIO import StringIO
1471 by Robert Collins
Bugfix to previous url escaping patch - include weave stores
24
import urllib
1223 by Martin Pool
- store inventories in weave
25
26
from bzrlib.weavefile import read_weave, write_weave_v5
1563.2.14 by Robert Collins
Prepare weave store to delegate copy details to the versioned file.
27
from bzrlib.weave import WeaveFile
1430 by Robert Collins
touchup the prefixed-store patch
28
from bzrlib.store import TransportStore, hash_prefix
1223 by Martin Pool
- store inventories in weave
29
from bzrlib.atomicfile import AtomicFile
1429 by Robert Collins
merge in niemeyers prefixed-store patch
30
from bzrlib.errors import NoSuchFile, FileExists
1563.2.10 by Robert Collins
Change weave store to be a versioned store, using WeaveFiles which maintain integrity without needing explicit 'put' operations.
31
from bzrlib.symbol_versioning import *
1393.1.19 by Martin Pool
- add WeaveStore.__iter__, __contains__ and copy_multi()
32
from bzrlib.trace import mutter
1393.2.2 by John Arbash Meinel
Updated stores to use Transport
33
34
1563.2.16 by Robert Collins
Change WeaveStore into VersionedFileStore and make its versoined file class parameterisable.
35
class VersionedFileStore(TransportStore):
36
    """Collection of many versioned files in a transport."""
1393.1.19 by Martin Pool
- add WeaveStore.__iter__, __contains__ and copy_multi()
37
1185.58.4 by John Arbash Meinel
Added permission checking to Branch, and propogated that change into the stores.
38
    def __init__(self, transport, prefixed=False, precious=False,
1563.2.16 by Robert Collins
Change WeaveStore into VersionedFileStore and make its versoined file class parameterisable.
39
                 dir_mode=None, file_mode=None,
40
                 versionedfile_class=WeaveFile):
1185.58.4 by John Arbash Meinel
Added permission checking to Branch, and propogated that change into the stores.
41
        super(WeaveStore, self).__init__(transport,
42
                dir_mode=dir_mode, file_mode=file_mode,
43
                prefixed=prefixed, compressed=False)
1417.1.10 by Robert Collins
add a cache bound to Transactions, and a precious facility, so that we keep inventory.weave in memory, but can discard weaves for other such files.
44
        self._precious = precious
1563.2.16 by Robert Collins
Change WeaveStore into VersionedFileStore and make its versoined file class parameterisable.
45
        self._versionedfile_class = versionedfile_class
1196 by Martin Pool
- [WIP] retrieve historical texts from weaves
46
1563.2.25 by Robert Collins
Merge in upstream.
47
    def _clear_cache_id(self, file_id, transaction):
48
        """WARNING may lead to inconsistent object references for file_id.
49
50
        Remove file_id from the transaction map. 
51
52
        NOT in the transaction api because theres no reliable way to clear
53
        callers. So its here for very specialised use rather than having an
54
        'api' that isn't.
55
        """
56
        weave = transaction.map.find_weave(file_id)
1563.2.34 by Robert Collins
Remove the commit and rollback transaction methods as misleading, and implement a WriteTransaction
57
        if weave is not None:
1563.2.25 by Robert Collins
Merge in upstream.
58
            mutter("old data in transaction in %s for %s", self, file_id)
1563.2.34 by Robert Collins
Remove the commit and rollback transaction methods as misleading, and implement a WriteTransaction
59
            # FIXME abstraction violation - transaction now has stale data.
60
            transaction.map.remove_object(weave)
1196 by Martin Pool
- [WIP] retrieve historical texts from weaves
61
1223 by Martin Pool
- store inventories in weave
62
    def filename(self, file_id):
1393.2.2 by John Arbash Meinel
Updated stores to use Transport
63
        """Return the path relative to the transport root."""
1429 by Robert Collins
merge in niemeyers prefixed-store patch
64
        if self._prefixed:
1563.2.15 by Robert Collins
remove the weavestore assumptions about the number and nature of files it manages.
65
            return hash_prefix(file_id) + urllib.quote(file_id)
1429 by Robert Collins
merge in niemeyers prefixed-store patch
66
        else:
1563.2.15 by Robert Collins
remove the weavestore assumptions about the number and nature of files it manages.
67
            return urllib.quote(file_id)
1429 by Robert Collins
merge in niemeyers prefixed-store patch
68
1393.1.19 by Martin Pool
- add WeaveStore.__iter__, __contains__ and copy_multi()
69
    def __iter__(self):
1563.2.16 by Robert Collins
Change WeaveStore into VersionedFileStore and make its versoined file class parameterisable.
70
        suffixes = self._versionedfile_class.get_suffixes()
1563.2.15 by Robert Collins
remove the weavestore assumptions about the number and nature of files it manages.
71
        ids = set()
1479 by Robert Collins
More quoting at the transport layer bugfixes.
72
        for relpath in self._iter_files_recursive():
1563.2.15 by Robert Collins
remove the weavestore assumptions about the number and nature of files it manages.
73
            for suffix in suffixes:
74
                if relpath.endswith(suffix):
75
                    id = os.path.basename(relpath[:-len(suffix)])
76
                    if not id in ids:
77
                        yield id
78
                        ids.add(id)
1393.1.19 by Martin Pool
- add WeaveStore.__iter__, __contains__ and copy_multi()
79
1442.1.45 by Robert Collins
replace __contains__ calls in stores with has_id
80
    def has_id(self, fileid):
1563.2.16 by Robert Collins
Change WeaveStore into VersionedFileStore and make its versoined file class parameterisable.
81
        suffixes = self._versionedfile_class.get_suffixes()
1563.2.15 by Robert Collins
remove the weavestore assumptions about the number and nature of files it manages.
82
        filename = self.filename(fileid)
83
        for suffix in suffixes:
84
            if not self._transport.has(filename + suffix):
85
                return False
86
        return True
1223 by Martin Pool
- store inventories in weave
87
1563.2.25 by Robert Collins
Merge in upstream.
88
    def get_empty(self, file_id, transaction):
89
        """Get an empty weave, which implies deleting the existing one first."""
90
        if self.has_id(file_id):
91
            self.delete(file_id, transaction)
92
        return self.get_weave_or_empty(file_id, transaction)
93
94
    def delete(self, file_id, transaction):
95
        """Remove file_id from the store."""
96
        suffixes = self._versionedfile_class.get_suffixes()
97
        filename = self.filename(file_id)
98
        for suffix in suffixes:
99
            self._transport.delete(filename + suffix)
100
        self._clear_cache_id(file_id, transaction)
1223 by Martin Pool
- store inventories in weave
101
1417.1.8 by Robert Collins
use transactions in the weave store interface, which enables caching for log
102
    def get_weave(self, file_id, transaction):
103
        weave = transaction.map.find_weave(file_id)
1563.2.34 by Robert Collins
Remove the commit and rollback transaction methods as misleading, and implement a WriteTransaction
104
        if weave is not None:
1594.3.2 by Robert Collins
make trivial ranges work for HTTP really.
105
            #mutter("cache hit in %s for %s", self, file_id)
1417.1.8 by Robert Collins
use transactions in the weave store interface, which enables caching for log
106
            return weave
1594.2.23 by Robert Collins
Test versioned file storage handling of clean/dirty status for accessed versioned files.
107
        if transaction.writeable():
108
            w = self._versionedfile_class(self.filename(file_id), self._transport, self._file_mode)
109
            transaction.map.add_weave(file_id, w)
110
            transaction.register_dirty(w)
111
        else:
112
            w = self._versionedfile_class(self.filename(file_id),
113
                                          self._transport,
114
                                          self._file_mode,
115
                                          create=False,
116
                                          access_mode='r')
117
            transaction.map.add_weave(file_id, w)
118
            transaction.register_clean(w, precious=self._precious)
1363 by Martin Pool
- add quick-and-dirty cache for weaves to speed check command
119
        return w
1262 by Martin Pool
- fetch should also copy ancestry records
120
1563.2.18 by Robert Collins
get knit repositories really using knits for text storage.
121
    @deprecated_method(zero_eight)
1417.1.8 by Robert Collins
use transactions in the weave store interface, which enables caching for log
122
    def get_lines(self, file_id, rev_id, transaction):
1262 by Martin Pool
- fetch should also copy ancestry records
123
        """Return text from a particular version of a weave.
124
1563.2.35 by Robert Collins
cleanup deprecation warnings and finish conversion so the inventory is knit based too.
125
        Returned as a list of lines.
126
        """
127
        assert 0
1417.1.8 by Robert Collins
use transactions in the weave store interface, which enables caching for log
128
        w = self.get_weave(file_id, transaction)
1563.2.18 by Robert Collins
get knit repositories really using knits for text storage.
129
        return w.get_lines(rev_id)
1196 by Martin Pool
- [WIP] retrieve historical texts from weaves
130
    
1563.2.10 by Robert Collins
Change weave store to be a versioned store, using WeaveFiles which maintain integrity without needing explicit 'put' operations.
131
    def _new_weave(self, file_id, transaction):
132
        """Make a new weave for file_id and return it."""
1563.2.34 by Robert Collins
Remove the commit and rollback transaction methods as misleading, and implement a WriteTransaction
133
        weave = self._make_new_versionedfile(file_id, transaction)
1563.2.10 by Robert Collins
Change weave store to be a versioned store, using WeaveFiles which maintain integrity without needing explicit 'put' operations.
134
        transaction.map.add_weave(file_id, weave)
1594.2.23 by Robert Collins
Test versioned file storage handling of clean/dirty status for accessed versioned files.
135
        # has to be dirty - its able to mutate on its own.
136
        transaction.register_dirty(weave)
1563.2.10 by Robert Collins
Change weave store to be a versioned store, using WeaveFiles which maintain integrity without needing explicit 'put' operations.
137
        return weave
1185.33.88 by Martin Pool
[patch] read only the table-of-contents of weaves to speed up commit
138
1563.2.34 by Robert Collins
Remove the commit and rollback transaction methods as misleading, and implement a WriteTransaction
139
    def _make_new_versionedfile(self, file_id, transaction):
140
        if self.has_id(file_id):
141
            self.delete(file_id, transaction)
1563.2.14 by Robert Collins
Prepare weave store to delegate copy details to the versioned file.
142
        try:
1563.2.25 by Robert Collins
Merge in upstream.
143
            weave = self._versionedfile_class(self.filename(file_id), self._transport, self._file_mode, create=True)
1563.2.14 by Robert Collins
Prepare weave store to delegate copy details to the versioned file.
144
        except NoSuchFile:
145
            if not self._prefixed:
1563.2.16 by Robert Collins
Change WeaveStore into VersionedFileStore and make its versoined file class parameterisable.
146
                # unexpected error - NoSuchFile is raised on a missing dir only and that
147
                # only occurs when we are prefixed.
1563.2.14 by Robert Collins
Prepare weave store to delegate copy details to the versioned file.
148
                raise
149
            self._transport.mkdir(hash_prefix(file_id), mode=self._dir_mode)
1563.2.25 by Robert Collins
Merge in upstream.
150
            weave = self._versionedfile_class(self.filename(file_id), self._transport, self._file_mode, create=True)
1563.2.14 by Robert Collins
Prepare weave store to delegate copy details to the versioned file.
151
        return weave
152
1417.1.8 by Robert Collins
use transactions in the weave store interface, which enables caching for log
153
    def get_weave_or_empty(self, file_id, transaction):
1224 by Martin Pool
- new method WeaveStore.get_weave_or_empty
154
        """Return a weave, or an empty one if it doesn't exist.""" 
155
        try:
1417.1.8 by Robert Collins
use transactions in the weave store interface, which enables caching for log
156
            return self.get_weave(file_id, transaction)
1393.2.2 by John Arbash Meinel
Updated stores to use Transport
157
        except NoSuchFile:
1563.2.10 by Robert Collins
Change weave store to be a versioned store, using WeaveFiles which maintain integrity without needing explicit 'put' operations.
158
            return self._new_weave(file_id, transaction)
1224 by Martin Pool
- new method WeaveStore.get_weave_or_empty
159
1563.2.10 by Robert Collins
Change weave store to be a versioned store, using WeaveFiles which maintain integrity without needing explicit 'put' operations.
160
    @deprecated_method(zero_eight)
1417.1.8 by Robert Collins
use transactions in the weave store interface, which enables caching for log
161
    def put_weave(self, file_id, weave, transaction):
1563.2.10 by Robert Collins
Change weave store to be a versioned store, using WeaveFiles which maintain integrity without needing explicit 'put' operations.
162
        """This is a deprecated API: It writes an entire collection of ids out.
163
        
164
        This became inappropriate when we made a versioned file api which
165
        tracks the state of the collection of versions for a single id.
166
        
167
        Its maintained for backwards compatability but will only work on
168
        weave stores - pre 0.8 repositories.
169
        """
170
        self._put_weave(self, file_id, weave, transaction)
171
172
    def _put_weave(self, file_id, weave, transaction):
173
        """Preserved here for upgrades-to-weaves to use."""
1563.2.34 by Robert Collins
Remove the commit and rollback transaction methods as misleading, and implement a WriteTransaction
174
        myweave = self._make_new_versionedfile(file_id, transaction)
1563.2.15 by Robert Collins
remove the weavestore assumptions about the number and nature of files it manages.
175
        myweave.join(weave)
1223 by Martin Pool
- store inventories in weave
176
1563.2.10 by Robert Collins
Change weave store to be a versioned store, using WeaveFiles which maintain integrity without needing explicit 'put' operations.
177
    @deprecated_method(zero_eight)
1417.1.8 by Robert Collins
use transactions in the weave store interface, which enables caching for log
178
    def add_text(self, file_id, rev_id, new_lines, parents, transaction):
1563.2.10 by Robert Collins
Change weave store to be a versioned store, using WeaveFiles which maintain integrity without needing explicit 'put' operations.
179
        """This method was a shorthand for 
180
181
        vfile = self.get_weave_or_empty(file_id, transaction)
182
        vfile.add_lines(rev_id, parents, new_lines)
183
        """
184
        vfile = self.get_weave_or_empty(file_id, transaction)
185
        vfile.add_lines(rev_id, parents, new_lines)
1223 by Martin Pool
- store inventories in weave
186
        
1563.2.10 by Robert Collins
Change weave store to be a versioned store, using WeaveFiles which maintain integrity without needing explicit 'put' operations.
187
    @deprecated_method(zero_eight)
1417.1.8 by Robert Collins
use transactions in the weave store interface, which enables caching for log
188
    def add_identical_text(self, file_id, old_rev_id, new_rev_id, parents,
189
                           transaction):
1563.2.10 by Robert Collins
Change weave store to be a versioned store, using WeaveFiles which maintain integrity without needing explicit 'put' operations.
190
        """This method was a shorthand for
191
192
        vfile = self.get_weave_or_empty(file_id, transaction)
193
        vfile.clone_text(new_rev_id, old_rev_id, parents)
194
        """
195
        vfile = self.get_weave_or_empty(file_id, transaction)
196
        vfile.clone_text(new_rev_id, old_rev_id, parents)
1563.2.25 by Robert Collins
Merge in upstream.
197
 
198
    def copy(self, source, result_id, transaction):
199
        """Copy the source versioned file to result_id in this store."""
200
        self._clear_cache_id(result_id, transaction)
201
        source.copy_to(self.filename(result_id), self._transport)
202
 
1563.2.34 by Robert Collins
Remove the commit and rollback transaction methods as misleading, and implement a WriteTransaction
203
    def copy_all_ids(self, store_from, pb=None, from_transaction=None,
204
                     to_transaction=None):
1563.2.14 by Robert Collins
Prepare weave store to delegate copy details to the versioned file.
205
        """Copy all the file ids from store_from into self."""
206
        if from_transaction is None:
1563.2.34 by Robert Collins
Remove the commit and rollback transaction methods as misleading, and implement a WriteTransaction
207
            warn("Please pass from_transaction into "
208
                 "versioned_store.copy_all_ids.", stacklevel=2)
209
        if to_transaction is None:
210
            warn("Please pass to_transaction into "
1563.2.14 by Robert Collins
Prepare weave store to delegate copy details to the versioned file.
211
                 "versioned_store.copy_all_ids.", stacklevel=2)
212
        if not store_from.listable():
213
            raise UnlistableStore(store_from)
214
        ids = []
215
        for count, file_id in enumerate(store_from):
216
            if pb:
217
                pb.update('listing files', count, count)
218
            ids.append(file_id)
219
        if pb:
220
            pb.clear()
221
        mutter('copy_all ids: %r', ids)
222
        self.copy_multi(store_from, ids, pb=pb,
1563.2.34 by Robert Collins
Remove the commit and rollback transaction methods as misleading, and implement a WriteTransaction
223
                        from_transaction=from_transaction,
224
                        to_transaction=to_transaction)
1563.2.14 by Robert Collins
Prepare weave store to delegate copy details to the versioned file.
225
1563.2.34 by Robert Collins
Remove the commit and rollback transaction methods as misleading, and implement a WriteTransaction
226
    def copy_multi(self, from_store, file_ids, pb=None, from_transaction=None,
227
                   to_transaction=None):
1563.2.14 by Robert Collins
Prepare weave store to delegate copy details to the versioned file.
228
        """Copy all the versions for multiple file_ids from from_store.
229
        
230
        :param from_transaction: required current transaction in from_store.
231
        """
1563.2.34 by Robert Collins
Remove the commit and rollback transaction methods as misleading, and implement a WriteTransaction
232
        from bzrlib.transactions import PassThroughTransaction
1393.1.19 by Martin Pool
- add WeaveStore.__iter__, __contains__ and copy_multi()
233
        assert isinstance(from_store, WeaveStore)
1563.2.14 by Robert Collins
Prepare weave store to delegate copy details to the versioned file.
234
        if from_transaction is None:
235
            warn("WeaveStore.copy_multi without a from_transaction parameter "
236
                 "is deprecated. Please provide a from_transaction.",
237
                 DeprecationWarning,
238
                 stacklevel=2)
1563.2.34 by Robert Collins
Remove the commit and rollback transaction methods as misleading, and implement a WriteTransaction
239
            # we are reading one object - caching is irrelevant.
240
            from_transaction = PassThroughTransaction()
241
        if to_transaction is None:
242
            warn("WeaveStore.copy_multi without a to_transaction parameter "
243
                 "is deprecated. Please provide a to_transaction.",
244
                 DeprecationWarning,
245
                 stacklevel=2)
246
            # we are copying single objects, and there may be open tranasactions
247
            # so again with the passthrough
248
            to_transaction = PassThroughTransaction()
1185.79.2 by John Arbash Meinel
Adding progress bars to copy_all and copy_multi, fixing ordering of repository.clone() to pull inventories after weaves.
249
        for count, f in enumerate(file_ids):
1393.1.19 by Martin Pool
- add WeaveStore.__iter__, __contains__ and copy_multi()
250
            mutter("copy weave {%s} into %s", f, self)
1185.79.2 by John Arbash Meinel
Adding progress bars to copy_all and copy_multi, fixing ordering of repository.clone() to pull inventories after weaves.
251
            if pb:
252
                pb.update('copy', count, len(file_ids))
1563.2.10 by Robert Collins
Change weave store to be a versioned store, using WeaveFiles which maintain integrity without needing explicit 'put' operations.
253
            # if we have it in cache, its faster.
1563.2.15 by Robert Collins
remove the weavestore assumptions about the number and nature of files it manages.
254
            # joining is fast with knits, and bearable for weaves -
1563.2.34 by Robert Collins
Remove the commit and rollback transaction methods as misleading, and implement a WriteTransaction
255
            # indeed the new case can be optimised if needed.
256
            target = self._make_new_versionedfile(f, to_transaction)
1563.2.15 by Robert Collins
remove the weavestore assumptions about the number and nature of files it manages.
257
            target.join(from_store.get_weave(f, from_transaction))
1185.79.2 by John Arbash Meinel
Adding progress bars to copy_all and copy_multi, fixing ordering of repository.clone() to pull inventories after weaves.
258
        if pb:
259
            pb.clear()
1563.2.16 by Robert Collins
Change WeaveStore into VersionedFileStore and make its versoined file class parameterisable.
260
1563.2.31 by Robert Collins
Convert Knit repositories to use knits.
261
    def total_size(self):
262
        count, bytes =  super(VersionedFileStore, self).total_size()
263
        return (count / len(self._versionedfile_class.get_suffixes())), bytes
1563.2.16 by Robert Collins
Change WeaveStore into VersionedFileStore and make its versoined file class parameterisable.
264
265
WeaveStore = VersionedFileStore