doc/book/en/devrepo/entityclasses/application-logic.rst
author Alexandre Fayolle <alexandre.fayolle@logilab.fr>
Thu, 16 Sep 2010 16:42:58 +0200
branchstable
changeset 6268 05a855ffb65d
parent 6152 6824f8b61098
child 7827 9bbf83f68bcc
permissions -rw-r--r--
force debug mode to false in service mode
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
5879
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
     1
How to use entities objects and adapters
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
     2
----------------------------------------
5144
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
     3
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
     4
The previous chapters detailed the classes and methods available to
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
     5
the developper at the so-called `ORM`_ level. However they say little
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
     6
about the common patterns of usage of these objects.
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
     7
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
     8
.. _`ORM`: http://en.wikipedia.org/wiki/Object-relational_mapping
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
     9
5879
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
    10
Entities objects (and their adapters) are used in the repository and
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
    11
web sides of CubicWeb. On the repository side of things, one should
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
    12
manipulate them in Hooks and Operations.
5144
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    13
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    14
Hooks and Operations provide support for the implementation of rules
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    15
such as computed attributes, coherency invariants, etc (they play the
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    16
same role as database triggers, but in a way that is independant of
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    17
the actual data sources).
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    18
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    19
So a lot of an application's business rules will be written in Hooks
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    20
(or Operations).
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    21
5157
1202e6565aff [doc/book] talk about reloadComponent, misc tweaks and notes
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5152
diff changeset
    22
On the web side, views also typically operate using entity
5144
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    23
objects. Obvious entity methods for use in views are the dublin code
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    24
method like dc_title, etc. For separation of concerns reasons, one
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    25
should ensure no ui logic pervades the entities level, and also no
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    26
business logic should creep into the views.
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    27
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    28
In the duration of a transaction, entities objects can be instantiated
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    29
many times, in views and hooks, even for the same database entity. For
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    30
instance, in a classic CubicWeb deployment setup, the repository and
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    31
the web frontend are separated process communicating over the
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    32
wire. There is no way state can be shared between these processes
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    33
(there is a specific API for that). Hence, it is not possible to use
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    34
entity objects as messengers between these components of an
5879
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
    35
application. It means that an attribute set as in ``obj.x = 42``,
5144
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    36
whether or not x is actually an entity schema attribute, has a short
5152
35e6878e2fd0 [doc/book] adjust a bit
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5144
diff changeset
    37
life span, limited to the hook, operation or view within which the
35e6878e2fd0 [doc/book] adjust a bit
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5144
diff changeset
    38
object was built.
5144
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    39
5152
35e6878e2fd0 [doc/book] adjust a bit
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5144
diff changeset
    40
Setting an attribute or relation value can be done in the context of a
5879
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
    41
Hook/Operation, using the obj.set_relations(x=42) notation or a plain
5144
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    42
RQL SET expression.
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    43
5152
35e6878e2fd0 [doc/book] adjust a bit
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5144
diff changeset
    44
In views, it would be preferable to encapsulate the necessary logic in
5879
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
    45
a method of an adapter for the concerned entity class(es). But of
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
    46
course, this advice is also reasonnable for Hooks/Operations, though
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
    47
the separation of concerns here is less stringent than in the case of
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
    48
views.
5152
35e6878e2fd0 [doc/book] adjust a bit
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5144
diff changeset
    49
5879
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
    50
This leads to the practical role of objects adapters: it's where an
5144
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    51
important part of the application logic lie (the other part being
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    52
located in the Hook/Operations).
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    53
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    54
Anatomy of an entity class
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    55
--------------------------
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    56
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    57
We can look now at a real life example coming from the `tracker`_
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    58
cube. Let us begin to study the entities/project.py content.
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    59
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    60
.. sourcecode:: python
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    61
5879
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
    62
    from cubicweb.entities.adapters import ITreeAdapter
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
    63
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
    64
    class ProjectAdapter(ITreeAdapter):
6152
6824f8b61098 use is_instance in a number of places (esp. documentation) rather than the deprecated implements
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5879
diff changeset
    65
        __select__ = is_instance('Project')
5879
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
    66
        tree_relation = 'subproject_of'
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
    67
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
    68
    class Project(AnyEntity):
5144
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    69
        __regid__ = 'Project'
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    70
        fetch_attrs, fetch_order = fetch_config(('name', 'description',
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    71
                                                 'description_format', 'summary'))
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    72
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    73
        TICKET_DEFAULT_STATE_RESTR = 'S name IN ("created","identified","released","scheduled")'
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    74
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    75
        def dc_title(self):
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    76
            return self.name
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    77
5879
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
    78
The fact that the `Project` entity type implements an ``ITree``
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
    79
interface is materialized by the ``ProjectAdapter`` class (inheriting
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
    80
the pre-defined ``ITreeAdapter`` whose __regid__ is of course
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
    81
``ITree``), which will be selected on `Project` entity types because
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
    82
of its selector. On this adapter, we redefine the ``tree_relation``
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
    83
attribute of the ITreeAdapter class.
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
    84
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
    85
This is typically used in views concerned with the representation of
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
    86
tree-like structures (CubicWeb provides several such views).
5152
35e6878e2fd0 [doc/book] adjust a bit
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5144
diff changeset
    87
35e6878e2fd0 [doc/book] adjust a bit
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5144
diff changeset
    88
It is important that the views themselves try not to implement this
35e6878e2fd0 [doc/book] adjust a bit
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5144
diff changeset
    89
logic, not only because such views would be hardly applyable to other
35e6878e2fd0 [doc/book] adjust a bit
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5144
diff changeset
    90
tree-like relations, but also because it is perfectly fine and useful
35e6878e2fd0 [doc/book] adjust a bit
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5144
diff changeset
    91
to use such an interface in Hooks.
35e6878e2fd0 [doc/book] adjust a bit
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5144
diff changeset
    92
35e6878e2fd0 [doc/book] adjust a bit
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5144
diff changeset
    93
In fact, Tree nature is a property of the data model that cannot be
35e6878e2fd0 [doc/book] adjust a bit
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5144
diff changeset
    94
fully and portably expressed at the level of database entities (think
35e6878e2fd0 [doc/book] adjust a bit
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5144
diff changeset
    95
about the transitive closure of the child relation). This is a further
35e6878e2fd0 [doc/book] adjust a bit
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5144
diff changeset
    96
argument to implement it at entity class level.
5144
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    97
5879
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
    98
The fetch_attrs, fetch_order class attributes are parameters of the
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
    99
`ORM`_ layer. They tell which attributes should be loaded at once on
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
   100
entity object instantiation (by default, only the eid is known, other
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
   101
attributes are loaded on demand), and which attribute is to be used to
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
   102
order the .related() and .unrelated() methods output.
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
   103
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
   104
We can observe the big TICKET_DEFAULT_STATE_RESTR is a pure
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
   105
application domain piece of data. There is, of course, no limitation
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
   106
to the amount of class attributes of this kind.
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
   107
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
   108
The ``dc_title`` method provides a (unicode string) value likely to be
5144
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   109
consummed by views, but note that here we do not care about output
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   110
encodings. We care about providing data in the most universal format
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   111
possible, because the data could be used by a web view (which would be
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   112
responsible of ensuring XHTML compliance), or a console or file
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   113
oriented output (which would have the necessary context about the
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   114
needed byte stream encoding).
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   115
5879
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
   116
.. note::
5144
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   117
5879
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
   118
  The dublin code `dc_xxx` methods are not moved to an adapter as they
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
   119
  are extremely prevalent in cubicweb and assorted cubes and should be
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
   120
  available for all entity types.
5144
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   121
5879
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
   122
Let us now dig into more substantial pieces of code, continuing the
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
   123
Project class.
5144
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   124
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   125
.. sourcecode:: python
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   126
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   127
    def latest_version(self, states=('published',), reverse=None):
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   128
        """returns the latest version(s) for the project in one of the given
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   129
        states.
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   130
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   131
        when no states specified, returns the latest published version.
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   132
        """
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   133
        order = 'DESC'
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   134
        if reverse is not None:
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   135
            warn('reverse argument is deprecated',
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   136
                 DeprecationWarning, stacklevel=1)
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   137
            if reverse:
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   138
                order = 'ASC'
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   139
        rset = self.versions_in_state(states, order, True)
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   140
        if rset:
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   141
            return rset.get_entity(0, 0)
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   142
        return None
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   143
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   144
    def versions_in_state(self, states, order='ASC', limit=False):
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   145
        """returns version(s) for the project in one of the given states, sorted
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   146
        by version number.
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   147
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   148
        If limit is true, limit result to one version.
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   149
        If reverse, versions are returned from the smallest to the greatest.
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   150
        """
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   151
        if limit:
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   152
            order += ' LIMIT 1'
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   153
        rql = 'Any V,N ORDERBY version_sort_value(N) %s ' \
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   154
              'WHERE V num N, V in_state S, S name IN (%s), ' \
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   155
              'V version_of P, P eid %%(p)s' % (order, ','.join(repr(s) for s in states))
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   156
        return self._cw.execute(rql, {'p': self.eid})
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   157
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   158
.. _`tracker`: http://www.cubicweb.org/project/cubicweb-tracker/
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   159
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   160
These few lines exhibit the important properties we want to outline:
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   161
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   162
* entity code is concerned with the application domain
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   163
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   164
* it is NOT concerned with database coherency (this is the realm of
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   165
  Hooks/Operations); in other words, it assumes a coherent world
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   166
5879
7d3044271a29 [doc] update book for adapters
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
   167
* it is NOT (directly) concerned with end-user interfaces
5144
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   168
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   169
* however it can be used in both contexts
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   170
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   171
* it does not create or manipulate the internal object's state
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   172
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   173
* it plays freely with RQL expression as needed
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   174
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   175
* it is not concerned with internationalization
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   176
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   177
* it does not raise exceptions
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   178
5a09bea07302 [doc/book] a new chapter on how to use the ORM
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   179