=======================
:mod:`clio` - reference
=======================

Functions
=========

:func:`clio.Table(name, metadata, *args, **kwargs)`
---------------------------------------------------

Construct a table. This behaves like :func:`sqlalchemy.Table` but
Clio-related fields and constraints are pre-defined. Takes the same
arguments as :func:`sqlalchemy.Table`.

:func:`clio.workflow_properties(class_)`
----------------------------------------

Add workflow properties to ``class_``. These workflow properties are
based on the relation properties that were defined by
:func:`sqlalchemy.orm.mapper`.

Classes
=======

:class:`clio.Model`
-------------------

The Model serves as the base class to all Clio-based objects. It
defines a number of properties and methods to guide an object through
workflow. When subclassing model and overriding ``__init__``, care
should be taken to call the ``__init__`` of the superclass.

.. class:: clio.Model

  Base class to define a model. All models in a Clio-driven
  application should subclass from this. All described attributes are
  database-backed and can therefore be used to construct SQLAlchemy
  queries.

    .. method:: __init__(code)

      Construct a model. The ``code`` parameter is the unique
      identifier of all versions of this model.

    .. attribute:: clio.Model.id

      The unique id of the record underlying this model. An integer
      number. Ids are unique for each version and for each object.
      The id is automatically generated by the database (as primary
      key).

    .. attribute:: clio.Model.code

      The unique code of the object. An integer number. All versions
      of the object share the same code; different objects have a
      different code. The code should be supplied by the developer
      when first constructing the object.

    .. attribute:: clio.Model.status

      The workflow status this version of the object is in. An integer
      number. See the `Status Constants`_ section for more information
      about status.

    .. attribute:: clio.Model.created_timestamp

      The time this version was first created. A datetime object.

    .. attribute:: clio.Model.published_start_timestamp
 
      The time that this version was first published. ``None`` if not
      yet published.

    .. attribute:: clio.Model.published_end_timestamp
 
      The time that this version stopped being published (i.e. was
      archived). ``None`` if not yet archived.
   
    .. attribute:: clio.Model.published_userid

      The userid of the user that published this version. ``None``
      it not yet published. 

      The system automatically maintains this attribute and it should
      not be set by hand.

      Clio retrieves the ``ICurrentUserId`` utility function to 
      determine the current user for this purpose.

    .. attribute:: clio.Model.changed_userid
     
      The userid of the user that last changed this version. ``None``
      if not yet set. The application needs to call ``mark_changed``
      to set this attribute.

      Clio retrieves the ``ICurrentUserId`` utility function to 
      determine the current user for this purpose.

    .. method:: publish()

      Publish the model. This works for models that are new or being
      edited or updated, or for published models that are being
      deleted. It's a no-op on models that are published by
      themselves, without any editable version.

      If the object is new, the object is now published. Any
      one-to-many relations of the object are now also published.

      If the object is editable, the object is now published, and the
      previously published object is now archived. Any one-to-many
      relations of the object are now also published, and the
      one-to-many relations of the previously published object are now
      archived.

      If the object is updatable, the object is now published, and the
      previously published object is now archived. Any one-to-many
      relations of the previously published object are now that of the
      newly published object.

      If the object was previously submitted for deletion, the object
      is now archived.

      Raises a :class:`clio.PublishError` if the publication fails.

      Returns the object itself (now published, or archived if it was
      submitted for deletion). If applied to published version where
      an editable version exists, returns the editable version, now
      published (object itself becomes archived).

    .. method:: edit()
 
      Create a new editable version of the object from the published
      version. All one-to-many relations also have editable versions
      created for them. If applied to a published version where an
      editable version is already available, return this. If applied
      to a version set for deletion, revert deletion and make a new
      editable version.

      The editable object and its relations can now be modified before
      publishing it.

      Raises a :class:`clio.EditError` if editing fails.

      Returns the editable object.

    .. method:: update()

      Create a new updatable version of the object from the published
      version. No one-to-many relations are copied. If applied to a
      published version where an updatable version is already
      available, return this. If applied to a version set for
      deletion, revert deletion and make a new updatable version.

      The updatable version can now be modified before publishing
      it. When publishing the updatable version, any one-to-many
      related objects associated with the previously published version
      will become associated with the newly published version.

      Raises a :class:`clio.UpdateError` if updating fails.

      Returns the updatable object.

    .. method:: delete()
  
      Submit a published version for deletion. When this version is
      published, it will be archived (along with any objects
      associated with it through one-to-many relations). If the
      version is new, the object will be immediately deleted from the
      database. If the version is being edited or updated, that
      operation is reverted and the object is submitted for deletion.

      Raises a :class:`clio.DeleteError` if submission for deletion
      fails.

      Returns the same version, now prepared for deletion.

    .. method:: revert()

      Revert to published version. If there is an editable or
      updatable version, this version is thrown away. If the version
      is new, the version will be deleted. If the version was set for
      deletion, this is reverted as well and the version remains
      normally published. Reverting a published version is a no-op.

    .. method:: mark_changed()

      Notify Clio that this model has been changed by a user. Clio
      updates the ``changed_userid`` attribute with the current user.

      Clio retrieves the ``ICurrentUserId`` utility function to 
      determine the current user for this purpose.

    .. method:: is_editable()

      Returns ``True`` if this version may be edited.

    .. method:: is_actual()
  
      Returns ``True`` if this version is actual.

    .. method:: is_published()
 
      Returns ``True`` if this is a published version.

    .. method:: is_archived()

      Returns ``True`` if this is an archived version.

    .. method:: is_deleted()
  
      Returns ``True`` if this version is submitted for deletion.

:class:`clio.Sequence`
----------------------

A MySQL-specific table-based sequence implementation.

Status Constants
================

These are the constants used by the ``status`` property of a clio
model. The constants by which this status appears in the database are
also documented (in parenthesis).

:const:`clio.NEW` (0)
---------------------

The object is newly created.

:const:`clio.PUBLISHED` (6)
---------------------------

The object is published and no new editable or updatable version of
the object exists, and the object is also not pending deletion.

:const:`clio.EDITABLE` (1)
--------------------------

An editable version of a published object. This object may be modified. When
published, all relations will be published as well.

:const:`clio.UPDATABLE` (2)
---------------------------

An updatable version of a published object. This may be be
modified. Similar to editable, except relations have not been taken
into edit. When published, the relations of the published object will
be associated with this object.

:const:`clio.DELETED` (3)
-------------------------

An deleted version of a published object, pending deletion upon
publication. When the version is published, the original version is
archived and the deleted version is destroyed.

:const:`clio.DELETED_EDITABLE` (4)
----------------------------------

An deleted version of an editable object, pending deletion upon
publication. When the version is published, the deleted version is
destroyed and the published version is archived. Can be reverted into
a normal editable version.

:const:`clio.DELETED_UPDATABLE` (5)
-----------------------------------

An deleted version of an updatable object, pending deletion upon
publication. When the version is published, the deleted version is
destroyed and the published version is archived. Can be reverted into
a normal editable version.

:const:`clio.PUBLISHED_UNDER_EDIT` (7)
--------------------------------------

The object is published and an editable version of the object exists.

:const:`clio.PUBLISHED_UNDER_UPDATE` (8)
----------------------------------------

The object is published and an updatable version of the object exists.

:const:`clio.PUBLISHED_UNDER_DELETE` (9)
----------------------------------------

The object is published and is pending deletion.

:const:`clio.ARCHIVED` (1000 and higher)
----------------------------------------

The object is archived.

There are an unlimited amount of archived states. This is the first
archived status available. All archived states have a status greater
than or equal to :const:`clio.ARCHIVED`.

:const:`clio.NEW_VERSION_STATUSES`
-----------------------------------

If the version has a status in this tuple of statuses the user is
allowed to edit the version. These versions are always new versions,
either of existing objects or completely new, or a version pending for
deletions.

:const:`clio.EDITABLE_STATUSES`
-------------------------------

The new version statuses plus the :const:`clio.PUBLISHED`
status. These are all the statuses that should be visible through an
edit UI (inclusion versions pending for deletion).

:const:`clio.ACTUAL_STATUSES`
-----------------------------

The new version statuses without those items deleted or pending
deletion. This will be what the published statuses will be upon
publication - the deleted items that aren't replaced will be
considered archived.

:const:`clio.PUBLISHED_STATUSES`
--------------------------------

If the version has a status in this tuple of statuses the version is
considered published.

:const:`clio.DELETED_STATUSES`
------------------------------

If the version has a status that is deleted.

Exceptions
==========

:class:`clio.ClioError`
-----------------------

Base class of all Clio exceptions. Catch this to handle any Clio-related
exception.

:class:`clio.PublishError`
--------------------------

Error raised when a version be published. This may be because it has a
parent (in a one to many relation) that has never been published, or
because the version is archived.

:class:`clio.EditError`
-----------------------

Error raised when a version cannot be edited. This may be because the
object is being updated (not edited) already, or because the version
is archived.

:class:`clio.UpdateError`
-------------------------

Error raised when a version cannot be updated. This may be because the
object is being edited (not updated) already, or because the version
is archived.

:class:`clio.DeleteError`
-------------------------

Error raised when a version cannot be deleted. This may be because the
version is archived.

:class:`clio.RevertError`
-------------------------

Error raised when a version cannot be reverted. This may be because the
version is archived.
