Setup environment
::

    >>> import ZODB.tests.util
    >>> db = ZODB.tests.util.DB()
    >>> conn = db.open()
    >>> root = conn.root()
    
    >>> from zodbcode.module import ManagedRegistry
    >>> from zope.component.persistentregistry import PersistentComponents
    >>> registry = root['registry'] = ManagedRegistry()
    >>> manager = root['manager'] = PersistentComponents()

Register soup
::

    >>> from cornerstone.soup.interfaces import ISoup
    >>> from cornerstone.soup.tests.env import MySoup
    >>> soup = MySoup()
    >>> manager.registerUtility(soup, ISoup, name=u'mysoup')
    
Close DB connection
::
    
    >>> from transaction import commit
    >>> commit()
    >>> conn.close()

Re-open DB connection and lookup utility from persistent components
::

    >>> conn = db.open()
    >>> root = conn.root()
    >>> manager = root['manager']
    >>> manager.getUtility(ISoup, name=u'mysoup')
    <MySoup at mysoup>

Our catalog factory
::

    >>> from zope.component import getUtility
    >>> from cornerstone.soup.interfaces import ICatalogFactory
    >>> catalogfactory = getUtility(ICatalogFactory, name='mysoup')
    >>> catalogfactory
    <cornerstone.soup.tests.env.MyCatalogFactory object at ...>

    >>> catalogfactory()
    <zope.catalog.catalog.Catalog object at ...>
    
Create a Record and add it to soup
::

    >>> from cornerstone.soup import Record
    >>> record = Record(user='user1')
    >>> id = soup.add(record)

Check querying
::

    >>> [r for r in soup.query(user='user1')]
    [<Record at ...>]
    
    >>> [r for r in soup.query(user='nonexist')]
    []
    
Add some more Records
::

    >>> id = soup.add(Record(user='user1'))
    >>> id = soup.add(Record(user='user2'))
    >>> u1records = [r for r in soup.query(user='user1')]
    >>> u1records
    [<Record at ...>, 
    <Record at ...>]

Change user attribute of one record
::

    >>> u1records[0].data['user'] = 'user2'

The query still returns the old result. The Record must be reindexed
::

    >>> [r for r in soup.query(user='user1')]
    [<Record at ...>, 
    <Record at ...>]
    
    >>> soup.reindex([u1records[0]])
    
    >>> u1 = [r for r in soup.query(user='user1')]
    >>> u1
    [<Record at ...>]
    
    >>> u2 = [r for r in soup.query(user='user2')]
    >>> u2
    [<Record at ...>, 
    <Record at ...>]

You can reindex all records in soup at once
::

    >>> all = [r for r in soup.data.values()]
    >>> all = sorted(all, key=lambda x: x.user)
    >>> all
    [<Record at ...>, 
    <Record at ...>, 
    <Record at ...>]
    
    >>> all[-1].data['user'] = 'user3'
    >>> soup.reindex()
    >>> [r for r in soup.query(user='user3')]
    [<Record at ...>]

You can also rebuild the catalog. In this case the catalog factory is called
again and the new catalog is used. Lets modify catalog of catalog factory
::

    >>> from zope.catalog.field import FieldIndex
    >>> catalogfactory = getUtility(ICatalogFactory, name='mysoup')
    >>> catalogfactory.catalog[u'name'] = FieldIndex(field_name='name',
    ...                                   field_callable=False)
    >>> catalogfactory()[u'name']
    <zope.catalog.field.FieldIndex object at ...>

Set name attribute on some record data, rebuild soup and check results
::

    >>> all[0].data['name'] = 'name'
    >>> all[1].data['name'] = 'name'
    >>> all[2].data['name'] = 'name'
    >>> soup.rebuild()
    >>> [r for r in soup.query(name='name')]
    [<Record at ...>, 
    <Record at ...>, 
    <Record at ...>]
    

We can delete items as well *hurrey*
::

    >>> del soup[all[0]]
    >>> [r for r in soup.query(name='name')]
    [<Record at ...>, 
    <Record at ...>]

For huge expected results we can query LazyRecords. They return the real record
on call
::

    >>> lazy = [l for l in soup.lazy(name='name')]
    >>> lazy
    [<cornerstone.soup.soup.LazyRecord object at ...>, 
    <cornerstone.soup.soup.LazyRecord object at ...>]
    
    >>> lazy[0]()
    <Record at ...>

Commit transaction, close DB connection, reopen and check if soup is still in
sane state
::

    >>> commit()
    >>> conn.close()    
    >>> conn = db.open()
    >>> root = conn.root()
    >>> manager = root['manager']
    >>> soup = manager.getUtility(ISoup, name=u'mysoup')
    >>> [r for r in soup.query(name='name')]
    [<Record at ...>, 
    <Record at ...>]

Cleanup
::

    >>> conn.close()    
    >>> db.close()