=======================
: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.workflow_timestamp
 
      The last time this version was taken through workflow (published,
      archived, edited, etc). A datetime object.

    .. attribute:: clio.Model.creation_timestamp

      The time this version was created. A datetime object.

    .. 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:: is_editable()

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

    .. 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.

:const:`clio.NEW`
-----------------

The object is newly created.

:const:`clio.PUBLISHED`
-----------------------

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`
----------------------

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

:const:`clio.UPDATABLE`
-----------------------

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`
---------------------

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`
------------------------------

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`
-------------------------------

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.DELETED`
---------------------

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.PUBLISHED_UNDER_EDIT`
----------------------------------

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

:const:`clio.PUBLISHED_UNDER_UPDATE`
------------------------------------

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

:const:`clio.PUBLISHED_UNDER_DELETE`
------------------------------------

The object is published and is pending deletion.

:const:`clio.ARCHIVED`
----------------------

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.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.
