~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/bundle/serializer/v4.py

  • Committer: Aaron Bentley
  • Date: 2007-07-04 03:08:46 UTC
  • mto: This revision was merged to the branch mainline in revision 2631.
  • Revision ID: aaron.bentley@utoronto.ca-20070704030846-jazbwllok1798atc
Cleanup of bundle code

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
 
34
34
 
35
35
class BundleWriter(object):
36
 
 
37
36
    """Writer for bundle-format files.
38
37
 
39
38
    This serves roughly the same purpose as ContainerReader, but acts as a
40
39
    layer on top of it.
41
40
 
42
 
    Provides ways of writing the spcific record types supported this bundle
 
41
    Provides ways of writing the specific record types supported this bundle
43
42
    format.
44
43
    """
 
44
 
45
45
    def __init__(self, fileobj):
46
46
        self._container = pack.ContainerWriter(self._write_encoded)
47
47
        self._fileobj = fileobj
53
53
 
54
54
    def begin(self):
55
55
        """Start writing the bundle"""
56
 
        self._fileobj.write(serializer._get_bundle_header('4alpha'))
 
56
        self._fileobj.write(serializer._get_bundle_header(
 
57
            serializer.v4_string))
57
58
        self._fileobj.write('#\n')
58
59
        self._container.begin()
59
60
 
67
68
        """Add a record for a multi-parent diff
68
69
 
69
70
        :mp_bytes: A multi-parent diff, as a bytestring
 
71
        :sha1: The sha1 hash of the fulltext
70
72
        :parents: a list of revision-ids of the parents
71
73
        :repo_kind: The kind of object in the repository.  May be 'file' or
72
74
            'inventory'
78
80
                    'sha1': sha1}
79
81
        self._add_record(mp_bytes, metadata, repo_kind, revision_id, file_id)
80
82
 
81
 
    def add_fulltext_record(self, bytes, parents, repo_kind, revision_id,
82
 
                            file_id):
 
83
    def add_fulltext_record(self, bytes, parents, repo_kind, revision_id):
83
84
        """Add a record for a fulltext
84
85
 
85
86
        :bytes: The fulltext, as a bytestring
87
88
        :repo_kind: The kind of object in the repository.  May be 'revision' or
88
89
            'signature'
89
90
        :revision_id: The revision id of the fulltext being added.
90
 
        :file_id: must be None
91
91
        """
92
92
        metadata = {'parents': parents,
93
93
                    'storage_kind': 'mpdiff'}
94
94
        self._add_record(bytes, {'parents': parents,
95
 
            'storage_kind': 'fulltext'}, repo_kind, revision_id, file_id)
 
95
            'storage_kind': 'fulltext'}, repo_kind, revision_id, None)
96
96
 
97
97
    def add_info_record(self, **kwargs):
98
98
        """Add an info record to the bundle
139
139
 
140
140
 
141
141
class BundleReader(object):
142
 
 
143
142
    """Reader for bundle-format files.
144
143
 
145
144
    This serves roughly the same purpose as ContainerReader, but acts as a
146
145
    layer on top of it, providing metadata, a semantic name, and a record
147
146
    body
148
147
    """
 
148
 
149
149
    def __init__(self, fileobj):
150
150
        line = fileobj.readline()
151
151
        if line != '\n':
195
195
 
196
196
 
197
197
class BundleSerializerV4(serializer.BundleSerializer):
198
 
 
199
198
    """Implement the high-level bundle interface"""
 
199
 
200
200
    def write(self, repository, revision_ids, forced_bases, fileobj):
201
201
        """Write a bundle to a file-like object
202
202
 
230
230
 
231
231
 
232
232
class BundleWriteOperation(object):
233
 
 
234
233
    """Perform the operation of writing revisions to a bundle"""
 
234
 
235
235
    @classmethod
236
236
    def from_old_args(cls, repository, revision_ids, forced_bases, fileobj):
 
237
        """Create a BundleWriteOperation from old-style arguments"""
237
238
        base, target = cls.get_base_target(revision_ids, forced_bases,
238
239
                                           repository)
239
240
        return BundleWriteOperation(base, target, repository, fileobj,
325
326
        for parents, revision_id in zip(parents_list, revision_order):
326
327
            revision_text = self.repository.get_revision_xml(revision_id)
327
328
            self.bundle.add_fulltext_record(revision_text, parents,
328
 
                                       'revision', revision_id, None)
 
329
                                       'revision', revision_id)
329
330
            try:
330
331
                self.bundle.add_fulltext_record(
331
332
                    self.repository.get_signature_text(
332
 
                    revision_id), parents, 'signature', revision_id, None)
 
333
                    revision_id), parents, 'signature', revision_id)
333
334
            except errors.NoSuchRevision:
334
335
                pass
335
336
 
336
337
    @staticmethod
337
338
    def get_base_target(revision_ids, forced_bases, repository):
 
339
        """Determine the base and target from old-style revision ids"""
338
340
        if len(revision_ids) == 0:
339
341
            return None, None
340
342
        target = revision_ids[0]
372
374
        return self.install_revisions(repository)
373
375
 
374
376
    def install_revisions(self, repository):
 
377
        """Install this bundle's revisions into the specified repository"""
375
378
        repository.lock_write()
376
379
        try:
377
380
            ri = RevisionInstaller(self.get_bundle_reader(),
387
390
        """
388
391
        return None, self.target, 'inapplicable'
389
392
 
390
 
 
391
393
    def get_bundle_reader(self):
392
394
        self._fileobj.seek(0)
393
395
        return BundleReader(self._fileobj)
424
426
 
425
427
 
426
428
class RevisionInstaller(object):
 
429
    """Installs revisions into a repository"""
427
430
 
428
431
    def __init__(self, container, serializer, repository):
429
432
        self._container = container
431
434
        self._repository = repository
432
435
        self._info = None
433
436
 
434
 
    def handle_info(self, info):
435
 
        self._info = info
436
 
        self._source_serializer = self._serializer.get_source_serializer(info)
437
 
        if (info['supports_rich_root'] == 0 and
438
 
            self._repository.supports_rich_root()):
439
 
            self.update_root = True
440
 
        else:
441
 
            self.update_root = False
442
 
 
443
437
    def install(self):
 
438
        """Perform the installation"""
444
439
        current_file = None
445
440
        current_versionedfile = None
446
441
        pending_file_records = []
450
445
            self._container.iter_records():
451
446
            if repo_kind == 'info':
452
447
                assert self._info is None
453
 
                self.handle_info(metadata)
 
448
                self._handle_info(metadata)
454
449
            if repo_kind != 'file':
455
450
                self._install_mp_records(current_versionedfile,
456
451
                    pending_file_records)
479
474
        self._install_mp_records(current_versionedfile, pending_file_records)
480
475
        return target_revision
481
476
 
 
477
    def _handle_info(self, info):
 
478
        """Extract data from an info record"""
 
479
        self._info = info
 
480
        self._source_serializer = self._serializer.get_source_serializer(info)
 
481
        if (info['supports_rich_root'] == 0 and
 
482
            self._repository.supports_rich_root()):
 
483
            self.update_root = True
 
484
        else:
 
485
            self.update_root = False
 
486
 
482
487
    def _install_mp_records(self, versionedfile, records):
483
488
        if len(records) == 0:
484
489
            return