~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/smart/repository.py

  • Committer: John Arbash Meinel
  • Date: 2009-07-29 21:35:05 UTC
  • mfrom: (4576 +trunk)
  • mto: This revision was merged to the branch mainline in revision 4577.
  • Revision ID: john@arbash-meinel.com-20090729213505-tkqsvy1zfpocu75w
Merge bzr.dev 4576 in prep for NEWS

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
    graph,
31
31
    osutils,
32
32
    pack,
33
 
    versionedfile,
34
33
    )
35
34
from bzrlib.bzrdir import BzrDir
36
35
from bzrlib.smart.request import (
40
39
    )
41
40
from bzrlib.repository import _strip_NULL_ghosts, network_format_registry
42
41
from bzrlib import revision as _mod_revision
43
 
from bzrlib.versionedfile import (
44
 
    NetworkRecordStream,
45
 
    record_to_fulltext_bytes,
46
 
    )
 
42
from bzrlib.versionedfile import NetworkRecordStream, record_to_fulltext_bytes
47
43
 
48
44
 
49
45
class SmartServerRepositoryRequest(SmartServerRequest):
418
414
            repository.
419
415
        """
420
416
        self._to_format = network_format_registry.get(to_network_name)
421
 
        if self._should_fake_unknown():
422
 
            return FailedSmartServerResponse(
423
 
                ('UnknownMethod', 'Repository.get_stream'))
424
417
        return None # Signal that we want a body.
425
418
 
426
 
    def _should_fake_unknown(self):
427
 
        """Return True if we should return UnknownMethod to the client.
428
 
        
429
 
        This is a workaround for bugs in pre-1.19 clients that claim to
430
 
        support receiving streams of CHK repositories.  The pre-1.19 client
431
 
        expects inventory records to be serialized in the format defined by
432
 
        to_network_name, but in pre-1.19 (at least) that format definition
433
 
        tries to use the xml5 serializer, which does not correctly handle
434
 
        rich-roots.  After 1.19 the client can also accept inventory-deltas
435
 
        (which avoids this issue), and those clients will use the
436
 
        Repository.get_stream_1.19 verb instead of this one.
437
 
        So: if this repository is CHK, and the to_format doesn't match,
438
 
        we should just fake an UnknownSmartMethod error so that the client
439
 
        will fallback to VFS, rather than sending it a stream we know it
440
 
        cannot handle.
441
 
        """
442
 
        from_format = self._repository._format
443
 
        to_format = self._to_format
444
 
        if not from_format.supports_chks:
445
 
            # Source not CHK: that's ok
446
 
            return False
447
 
        if (to_format.supports_chks and
448
 
            from_format.repository_class is to_format.repository_class and
449
 
            from_format._serializer == to_format._serializer):
450
 
            # Source is CHK, but target matches: that's ok
451
 
            # (e.g. 2a->2a, or CHK2->2a)
452
 
            return False
453
 
        # Source is CHK, and target is not CHK or incompatible CHK.  We can't
454
 
        # generate a compatible stream.
455
 
        return True
456
 
 
457
419
    def do_body(self, body_bytes):
458
420
        repository = self._repository
459
421
        repository.lock_read()
489
451
            repository.unlock()
490
452
 
491
453
 
492
 
class SmartServerRepositoryGetStream_1_19(SmartServerRepositoryGetStream):
493
 
 
494
 
    def _should_fake_unknown(self):
495
 
        """Returns False; we don't need to workaround bugs in 1.19+ clients."""
496
 
        return False
497
 
 
498
 
 
499
454
def _stream_to_byte_stream(stream, src_format):
500
455
    """Convert a record stream to a self delimited byte stream."""
501
456
    pack_writer = pack.ContainerSerialiser()
505
460
        for record in substream:
506
461
            if record.storage_kind in ('chunked', 'fulltext'):
507
462
                serialised = record_to_fulltext_bytes(record)
508
 
            elif record.storage_kind == 'inventory-delta':
509
 
                serialised = record_to_inventory_delta_bytes(record)
510
463
            elif record.storage_kind == 'absent':
511
464
                raise ValueError("Absent factory for %s" % (record.key,))
512
465
            else:
697
650
            return SuccessfulSmartServerResponse(('ok', ))
698
651
 
699
652
 
700
 
class SmartServerRepositoryInsertStream_1_19(SmartServerRepositoryInsertStreamLocked):
701
 
    """Insert a record stream from a RemoteSink into a repository.
702
 
 
703
 
    Same as SmartServerRepositoryInsertStreamLocked, except:
704
 
     - the lock token argument is optional
705
 
     - servers that implement this verb accept 'inventory-delta' records in the
706
 
       stream.
707
 
 
708
 
    New in 1.19.
709
 
    """
710
 
 
711
 
    def do_repository_request(self, repository, resume_tokens, lock_token=None):
712
 
        """StreamSink.insert_stream for a remote repository."""
713
 
        SmartServerRepositoryInsertStreamLocked.do_repository_request(
714
 
            self, repository, resume_tokens, lock_token)
715
 
 
716
 
 
717
653
class SmartServerRepositoryInsertStream(SmartServerRepositoryInsertStreamLocked):
718
654
    """Insert a record stream from a RemoteSink into an unlocked repository.
719
655