Connection support for Blobs tests
==================================

Connections handle Blobs specially. To demonstrate that, we first need a Blob
with some data:

    >>> from ZODB.interfaces import IBlob
    >>> from ZODB.blob import Blob
    >>> import transaction
    >>> blob = Blob()
    >>> data = blob.open("w")
    >>> data.write("I'm a happy Blob.")
    >>> data.close()

We also need a database with a blob supporting storage.  (We're going to use
FileStorage rather than MappingStorage here because we will want ``loadBefore``
for one of our examples.)

    >>> blob_storage = create_storage()
    >>> from ZODB.DB import DB
    >>> database = DB(blob_storage)

Putting a Blob into a Connection works like every other object:

    >>> connection = database.open()
    >>> root = connection.root()
    >>> root['myblob'] = blob
    >>> transaction.commit()

We can also commit a transaction that seats a blob into place without
calling the blob's open method:

    >>> nothing = transaction.begin()
    >>> anotherblob = Blob()
    >>> root['anotherblob'] = anotherblob
    >>> nothing = transaction.commit()

Getting stuff out of there works similarly:

    >>> transaction2 = transaction.TransactionManager()
    >>> connection2 = database.open(transaction_manager=transaction2)
    >>> root = connection2.root()
    >>> blob2 = root['myblob']
    >>> IBlob.providedBy(blob2)
    True
    >>> blob2.open("r").read()
    "I'm a happy Blob."
    >>> transaction2.abort()

MVCC also works.

    >>> transaction3 = transaction.TransactionManager()
    >>> connection3 = database.open(transaction_manager=transaction3)
    >>> f = connection.root()['myblob'].open('w')
    >>> f.write('I am an ecstatic Blob.')
    >>> f.close()
    >>> transaction.commit()
    >>> connection3.root()['myblob'].open('r').read()
    "I'm a happy Blob."
 >>> transaction2.abort()

MVCborted as we use
        the transaction context manager.

        >>> db = ZODB.tests.util.DB()
        >>> conn = db.open()
        >>> conn.root()['x'] = conn.root().__class__()
        >>> transaction.commit()
        >>> conn.root()['x']['x'] = 1

        >>> with db.transaction() as conn2:
        ...     conn2.root()['y'] = 1

        >>> conn2.opened

    Now, we'll open a 3rd connection a verify that

        >>> conn3 = db.open()
        >>> conn3.root()['x']
        {}
        >>> conn3.root()['y']
        1
        >>> conn3.close()

    Let's try again, but this time, we'll have an exception:

        >>> with db.transaction() as conn2:
        ...     conn2.root()['y'] = 2
        ...     XXX
        Traceback (most recent call last):
        ...
        NameError: name 'XXX' is not defined

        >>> conn2.opened

        >>> conn3 = db.open()
        >>> conn3.root()['x']
        {}
        >>> 