==================================
Keyreferences for zalchemy objects
==================================

In order to index zalchemy objects with the standard zope catalog we
have to provide an adapter to IKeyReference.

  >>> from zope import component, interface
  >>> from z3c.zalchemy.intid.keyreference import RefToSQLAlchemyObject
  >>> component.provideAdapter(RefToSQLAlchemyObject)


Let's create a simple mapper and an according class.

  >>> import sqlalchemy
  >>> import z3c.zalchemy
  >>> aTable = sqlalchemy.Table(
  ...     'aTable',z3c.zalchemy.metadata(),
  ...     sqlalchemy.Column('id', sqlalchemy.Integer, primary_key=True),
  ...     sqlalchemy.Column('value', sqlalchemy.Integer),
  ...     )

Add it to the engine utility (which is already created for this test)
and attach our mapper to the class.

  >>> from z3c.zalchemy.interfaces import ISQLAlchemyObject
  >>> class A(object):
  ...     interface.implements(ISQLAlchemyObject)
  ...     pass
  >>> sqlalchemy.mapper(A, aTable) is not None
  True
  
  >>> z3c.zalchemy.createTable('aTable', '')

Start a transaction.

  >>> import transaction
  >>> txn = transaction.begin()
  >>> session = z3c.zalchemy.getSession()


  >>> a = A()
  >>> session.save(a)
  >>> a.id = 1
  >>> a.value = 1


Now let us create a reference to the object

  >>> from zope.app.keyreference.interfaces import IKeyReference
  >>> ref1 = IKeyReference(a)

A keyreference must be hashable and comparable.

  >>> type(hash(ref1)) is type(1)
  True

  >>> ref2 = IKeyReference(a)
  >>> ref1 == ref2
  True

We have not commited, our transaction therefore the ref returns None
because it is not in the database.

  >>> ref1() is None
  True

  >>> transaction.commit()
  >>> txn = transaction.begin()

  >>> a2 = ref1()
  >>> a2
  <A object at ...>

  >>> a2.value
  1
  
  >>> ref3 = IKeyReference(a2)
  >>> ref3 == ref2 == ref1
  True

