/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.py

  • Committer: Robert Collins
  • Date: 2005-09-27 07:24:40 UTC
  • mfrom: (1185.1.41)
  • Revision ID: robertc@robertcollins.net-20050927072440-1bf4d99c3e1db5b3
pair programming worx... merge integration and weave

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
 
17
20
"""
18
21
Stores are the main data-storage mechanism for Bazaar-NG.
19
22
 
21
24
unique ID.
22
25
"""
23
26
 
24
 
import os, tempfile, types, osutils, gzip, errno
 
27
import errno
 
28
import gzip
 
29
import os
 
30
import tempfile
 
31
import types
25
32
from stat import ST_SIZE
26
33
from StringIO import StringIO
27
 
from trace import mutter
 
34
 
 
35
from bzrlib.errors import BzrError
 
36
from bzrlib.trace import mutter
 
37
import bzrlib.ui
 
38
import bzrlib.osutils as osutils
 
39
 
28
40
 
29
41
######################################################################
30
42
# stores
66
78
    def __init__(self, basedir):
67
79
        self._basedir = basedir
68
80
 
69
 
    def _path(self, id):
70
 
        if '\\' in id or '/' in id:
71
 
            raise ValueError("invalid store id %r" % id)
72
 
        return os.path.join(self._basedir, id)
 
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)
73
87
 
74
88
    def __repr__(self):
75
89
        return "%s(%r)" % (self.__class__.__name__, self._basedir)
90
104
            
91
105
        p = self._path(fileid)
92
106
        if os.access(p, os.F_OK) or os.access(p + '.gz', os.F_OK):
93
 
            from bzrlib.errors import bailout
94
107
            raise BzrError("store %r already contains id %r" % (self._basedir, fileid))
95
108
 
96
109
        fn = p
110
123
            af.close()
111
124
 
112
125
 
113
 
    def copy_multi(self, other, ids):
 
126
    def copy_multi(self, other, ids, permit_failure=False):
114
127
        """Copy texts for ids from other into self.
115
128
 
116
 
        If an id is present in self, it is skipped.  A count of copied
117
 
        ids is returned, which may be less than len(ids).
 
129
        If an id is present in self, it is skipped.
 
130
 
 
131
        Returns (count_copied, failed), where failed is a collection of ids
 
132
        that could not be copied.
118
133
        """
119
 
        from bzrlib.progress import ProgressBar
120
 
        pb = ProgressBar()
 
134
        pb = bzrlib.ui.ui_factory.progress_bar()
 
135
        
121
136
        pb.update('preparing to copy')
122
137
        to_copy = [id for id in ids if id not in self]
123
138
        if isinstance(other, ImmutableStore):
124
 
            return self.copy_multi_immutable(other, to_copy, pb)
 
139
            return self.copy_multi_immutable(other, to_copy, pb, 
 
140
                                             permit_failure=permit_failure)
125
141
        count = 0
 
142
        failed = set()
126
143
        for id in to_copy:
127
144
            count += 1
128
145
            pb.update('copy', count, len(to_copy))
129
 
            self.add(other[id], id)
130
 
        assert count == len(to_copy)
 
146
            if not permit_failure:
 
147
                self.add(other[id], id)
 
148
            else:
 
149
                try:
 
150
                    entry = other[id]
 
151
                except KeyError:
 
152
                    failed.add(id)
 
153
                    continue
 
154
                self.add(entry, id)
 
155
                
 
156
        if not permit_failure:
 
157
            assert count == len(to_copy)
131
158
        pb.clear()
132
 
        return count
133
 
 
134
 
 
135
 
    def copy_multi_immutable(self, other, to_copy, pb):
 
159
        return count, failed
 
160
 
 
161
    def copy_multi_immutable(self, other, to_copy, pb, permit_failure=False):
136
162
        from shutil import copyfile
137
163
        count = 0
 
164
        failed = set()
138
165
        for id in to_copy:
139
166
            p = self._path(id)
140
167
            other_p = other._path(id)
142
169
                copyfile(other_p, p)
143
170
            except IOError, e:
144
171
                if e.errno == errno.ENOENT:
145
 
                    copyfile(other_p+".gz", p+".gz")
 
172
                    if not permit_failure:
 
173
                        copyfile(other_p+".gz", p+".gz")
 
174
                    else:
 
175
                        try:
 
176
                            copyfile(other_p+".gz", p+".gz")
 
177
                        except IOError, e:
 
178
                            if e.errno == errno.ENOENT:
 
179
                                failed.add(id)
 
180
                            else:
 
181
                                raise
146
182
                else:
147
183
                    raise
148
184
            
150
186
            pb.update('copy', count, len(to_copy))
151
187
        assert count == len(to_copy)
152
188
        pb.clear()
153
 
        return count
 
189
        return count, failed
154
190
    
155
191
 
156
192
    def __contains__(self, fileid):
159
195
        return (os.access(p, os.R_OK)
160
196
                or os.access(p + '.gz', os.R_OK))
161
197
 
162
 
    # TODO: Guard against the same thing being stored twice, compressed and uncompresse
 
198
    # TODO: Guard against the same thing being stored twice,
 
199
    # compressed and uncompressed
163
200
 
164
201
    def __iter__(self):
165
202
        for f in os.listdir(self._basedir):
188
225
            if e.errno != errno.ENOENT:
189
226
                raise
190
227
 
191
 
        raise IndexError(fileid)
 
228
        raise KeyError(fileid)
192
229
 
193
230
 
194
231
    def total_size(self):