~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/store.py

  • Committer: Martin Pool
  • Date: 2005-08-30 06:10:39 UTC
  • Revision ID: mbp@sourcefrog.net-20050830061039-1d0347fb236c39ad
- clean up some code in revision.py

- move all exceptions to bzrlib.errors

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
 
# TODO: Could remember a bias towards whether a particular store is typically
18
 
# compressed or not.
19
 
 
20
17
"""
21
18
Stores are the main data-storage mechanism for Bazaar-NG.
22
19
 
24
21
unique ID.
25
22
"""
26
23
 
27
 
import errno
28
 
import gzip
29
 
import os
30
 
import tempfile
31
 
import types
 
24
import os, tempfile, types, osutils, gzip, errno
32
25
from stat import ST_SIZE
33
26
from StringIO import StringIO
34
 
 
35
 
from bzrlib.errors import BzrError, UnlistableStore
36
27
from bzrlib.trace import mutter
37
28
import bzrlib.ui
38
 
import bzrlib.osutils as osutils
39
 
 
40
29
 
41
30
######################################################################
42
31
# stores
78
67
    def __init__(self, basedir):
79
68
        self._basedir = basedir
80
69
 
81
 
    def _path(self, entry_id):
82
 
        if not isinstance(entry_id, basestring):
83
 
            raise TypeError(type(entry_id))
84
 
        if '\\' in entry_id or '/' in entry_id:
85
 
            raise ValueError("invalid store id %r" % entry_id)
86
 
        return os.path.join(self._basedir, entry_id)
 
70
    def _path(self, id):
 
71
        if '\\' in id or '/' in id:
 
72
            raise ValueError("invalid store id %r" % id)
 
73
        return os.path.join(self._basedir, id)
87
74
 
88
75
    def __repr__(self):
89
76
        return "%s(%r)" % (self.__class__.__name__, self._basedir)
136
123
        pb.update('preparing to copy')
137
124
        to_copy = [id for id in ids if id not in self]
138
125
        if isinstance(other, ImmutableStore):
139
 
            return self.copy_multi_immutable(other, to_copy, pb, 
140
 
                                             permit_failure=permit_failure)
 
126
            return self.copy_multi_immutable(other, to_copy, pb)
141
127
        count = 0
142
 
        failed = set()
143
128
        for id in to_copy:
144
129
            count += 1
145
130
            pb.update('copy', count, len(to_copy))
148
133
            else:
149
134
                try:
150
135
                    entry = other[id]
151
 
                except KeyError:
152
 
                    failed.add(id)
 
136
                except IndexError:
 
137
                    failures.add(id)
153
138
                    continue
154
139
                self.add(entry, id)
155
140
                
156
 
        if not permit_failure:
157
 
            assert count == len(to_copy)
 
141
        assert count == len(to_copy)
158
142
        pb.clear()
159
 
        return count, failed
 
143
        return count, []
160
144
 
161
145
    def copy_multi_immutable(self, other, to_copy, pb, permit_failure=False):
 
146
        from shutil import copyfile
162
147
        count = 0
163
148
        failed = set()
164
149
        for id in to_copy:
165
150
            p = self._path(id)
166
151
            other_p = other._path(id)
167
152
            try:
168
 
                osutils.link_or_copy(other_p, p)
169
 
            except (IOError, OSError), e:
 
153
                copyfile(other_p, p)
 
154
            except IOError, e:
170
155
                if e.errno == errno.ENOENT:
171
156
                    if not permit_failure:
172
 
                        osutils.link_or_copy(other_p+".gz", p+".gz")
 
157
                        copyfile(other_p+".gz", p+".gz")
173
158
                    else:
174
159
                        try:
175
 
                            osutils.link_or_copy(other_p+".gz", p+".gz")
 
160
                            copyfile(other_p+".gz", p+".gz")
176
161
                        except IOError, e:
177
162
                            if e.errno == errno.ENOENT:
178
163
                                failed.add(id)
194
179
        return (os.access(p, os.R_OK)
195
180
                or os.access(p + '.gz', os.R_OK))
196
181
 
197
 
    # TODO: Guard against the same thing being stored twice,
198
 
    # compressed and uncompressed
 
182
    # TODO: Guard against the same thing being stored twice, compressed and uncompresse
199
183
 
200
184
    def __iter__(self):
201
185
        for f in os.listdir(self._basedir):
224
208
            if e.errno != errno.ENOENT:
225
209
                raise
226
210
 
227
 
        raise KeyError(fileid)
 
211
        raise IndexError(fileid)
228
212
 
229
213
 
230
214
    def total_size(self):
264
248
            os.remove(fpath)
265
249
        os.rmdir(self._basedir)
266
250
        mutter("%r destroyed" % self)
267
 
 
268
 
def copy_all(store_from, store_to):
269
 
    """Copy all ids from one store to another."""
270
 
    if not hasattr(store_from, "__iter__"):
271
 
        raise UnlistableStore(store_from)
272
 
    ids = [f for f in store_from]
273
 
    store_to.copy_multi(store_from, ids)