/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: Martin Pool
  • Date: 2005-09-29 12:49:59 UTC
  • mto: (1185.14.2)
  • mto: This revision was merged to the branch mainline in revision 1396.
  • Revision ID: mbp@sourcefrog.net-20050929124959-df3f175844fc90ed
- remove redundant import

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, UnlistableStore
 
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):
136
 
        from shutil import copyfile
 
159
        return count, failed
 
160
 
 
161
    def copy_multi_immutable(self, other, to_copy, pb, permit_failure=False):
137
162
        count = 0
 
163
        failed = set()
138
164
        for id in to_copy:
139
165
            p = self._path(id)
140
166
            other_p = other._path(id)
141
167
            try:
142
 
                copyfile(other_p, p)
143
 
            except IOError, e:
 
168
                osutils.link_or_copy(other_p, p)
 
169
            except (IOError, OSError), e:
144
170
                if e.errno == errno.ENOENT:
145
 
                    copyfile(other_p+".gz", p+".gz")
 
171
                    if not permit_failure:
 
172
                        osutils.link_or_copy(other_p+".gz", p+".gz")
 
173
                    else:
 
174
                        try:
 
175
                            osutils.link_or_copy(other_p+".gz", p+".gz")
 
176
                        except IOError, e:
 
177
                            if e.errno == errno.ENOENT:
 
178
                                failed.add(id)
 
179
                            else:
 
180
                                raise
146
181
                else:
147
182
                    raise
148
183
            
150
185
            pb.update('copy', count, len(to_copy))
151
186
        assert count == len(to_copy)
152
187
        pb.clear()
153
 
        return count
 
188
        return count, failed
154
189
    
155
190
 
156
191
    def __contains__(self, fileid):
159
194
        return (os.access(p, os.R_OK)
160
195
                or os.access(p + '.gz', os.R_OK))
161
196
 
162
 
    # TODO: Guard against the same thing being stored twice, compressed and uncompresse
 
197
    # TODO: Guard against the same thing being stored twice,
 
198
    # compressed and uncompressed
163
199
 
164
200
    def __iter__(self):
165
201
        for f in os.listdir(self._basedir):
188
224
            if e.errno != errno.ENOENT:
189
225
                raise
190
226
 
191
 
        raise IndexError(fileid)
 
227
        raise KeyError(fileid)
192
228
 
193
229
 
194
230
    def total_size(self):
228
264
            os.remove(fpath)
229
265
        os.rmdir(self._basedir)
230
266
        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)