zc.vault

HomePage: http://pypi.python.org/pypi/zc.vault

Author: Zope Project

Download: https://pypi.python.org/packages/source/z/zc.vault/zc.vault-0.11.tar.gz

        *********
zc.vault
*********

The `zc.vault` package provides a low-level versioning support similar
to revision control systems, with an example usage and several example
add-ons.  It's ZODB-friendly.

.. See ``src/zc/vault/README.txt`` for details.


.. contents::

Detailed Documentation
**********************

=====
Vault
=====

Vaults model versioned containers.  A single revision of a vault is
typically viewed and (if not yet frozen) manipulated as an "inventory".
Inventories actually manipulate lower-level objects called manifests
that are only touched on in this document.  Inventories are the primary
API.

Inventories *model* containers, but are not traditional mappings:
containment is external to the actual objects in the inventory.  You
must query the inventory to discover the hierarchy, rather than the
objects themselves.  For instance, if you put an object in an inventory
and want to treat it as a versioned folder, you don't put children in
the object, but in the inventory node that wraps the object.  This will
be demonstrated repeatedly and in-depth below.

Vaults only contain versioned, frozen manifests, accessed as
inventories.  Working inventories can be made from any inventory in a
vault.  They can then be modified, and committed themselves in the
vault. Committing an inventory freezes it and all objects it
"contains".

Let's look at an example.  Vaults store manifests, so when you first
create one it is empty.  Vaults have a basic sequence API, so a `len`
will return `0`.

    >>> from zc.vault.vault import Vault, Inventory
    >>> from zc.vault.core import Manifest
    >>> from zc.vault import interfaces
    >>> from zope.interface.verify import verifyObject
    >>> v = Vault()
    >>> len(v)
    0
    >>> verifyObject(interfaces.IVault, v)
    True

The last inventory--the -1 index--is the current one.  A shorthand to this
inventory is the inventory attribute.

    >>> v.inventory # None

Vaults and inventories must have a database connection in order to store their
data.  We'll assume we have a ZODB folder named "app" in which we can store
our information.  This is set up in tests.py when this file is run as a test.

    >>> app['vault'] = v

Creating an initial working inventory requires us to merely instantiate it.
Usually we pass a versioned inventory on which to base the new inventory, but
without that we at least pass the vault.

    >>> i = Inventory(vault=v)
    >>> verifyObject(interfaces.IInventory, i)
    True

Technically, what we have done is create a manifest--the core API for managing
the contents--and wrapped an inventory API around it.

    >>> verifyObject(interfaces.IManifest, i.manifest)
    True

We could have created the manifest explicitly instead.

    >>> manifest = Manifest(vault=v)
    >>> verifyObject(interfaces.IManifest, manifest)
    True
    >>> i = Inventory(manifest)
    >>> verifyObject(interfaces.IInventory, i)
    True

Inventories--or at least the manifests on which they rely--must be
stored somewhere in the database before being committed. They provide
zope.app.location.interfaces.ILocation so that they can be stored in
standard Zope containers as they are being developed.

    >>> app['inventory'] = i

Inventories have contents that can seem to directly contain objects.  They have
a mapping API, and follow the IInventoryContents interface.

    >>> verifyObject(interfaces.IInventoryContents, i.contents)
    True
    >>> len(i.contents.keys())
    0
    >>> len(i.contents.values())
    0
    >>> len(i.contents.items())
    0
    >>> list(i.contents)
    []
    >>> i.contents.get('mydemo') # None
    >>> 'mydemo' in i
    False
    >>> i.contents['mydemo']
    Traceback (most recent call last):
    ...
    KeyError: 'mydemo'
    >>> del i.contents['mydemo']
    Traceback (most recent call last):
    ...
    KeyError: 'mydemo'

(ADVANCED SIDE NOTE: feel free to ignore)

The contents object is an API convenience to wrap a relationship.
Relationships connect a token to various pieces of information.  The
token for all inventory contents (the top node) is stored on the