[merge] stable
authorAurelien Campeas <aurelien.campeas@logilab.fr>
Thu, 08 Apr 2010 19:37:00 +0200
branchstable
changeset 5192 e9dd56699097
parent 5191 6d182c7d4392 (diff)
parent 5187 5f9a2b32c9e1 (current diff)
child 5193 c9671feff5e2
[merge]
--- a/doc/book/en/.static/sphinx-default.css	Thu Apr 08 14:40:18 2010 +0200
+++ b/doc/book/en/.static/sphinx-default.css	Thu Apr 08 19:37:00 2010 +0200
@@ -3,7 +3,7 @@
  */
 
 html, body {
-    background: white;	
+    background: white;
 }
 
 body {
@@ -115,7 +115,7 @@
 }
 
 div.sphinxsidebar h3 {
-    font-family: 'Verdanda', sans-serif;
+    font-family: Verdana, sans-serif;
     color: black;
     font-size: 1.2em;
     font-weight: normal;
@@ -126,7 +126,7 @@
 }
 
 div.sphinxsidebar h4 {
-    font-family: 'Verdana', sans-serif;
+    font-family: Verdana, sans-serif;
     color: black;
     font-size: 1.1em;
     font-weight: normal;
--- a/doc/book/en/annexes/rql/intro.rst	Thu Apr 08 14:40:18 2010 +0200
+++ b/doc/book/en/annexes/rql/intro.rst	Thu Apr 08 19:37:00 2010 +0200
@@ -5,10 +5,10 @@
 Goals of RQL
 ~~~~~~~~~~~~
 
-The goal is to have a language emphasizing the way of browsing relations. As
-such, attributes will be regarded as cases of special relations (in terms of
-implementation, the user should see no difference between an attribute and a
-relation).
+The goal is to have a language making relations browsing easy. As
+such, attributes will be regarded as cases of special relations (in
+terms of usage, the user should see no syntactic difference between an
+attribute and a relation).
 
 Comparison with existing languages
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -32,10 +32,10 @@
 
 We should look in more detail, but here are already some ideas for the moment
 ... Versa_ is the language most similar to what we wanted to do, but the model
-underlying data being RDF, there is some number of things such as namespaces or
+underlying data being RDF, there are some things such as namespaces or
 handling of the RDF types which does not interest us. On the functionality
 level, Versa_ is very comprehensive including through many functions of
-conversion and basic types manipulation, which may need to be guided at one time
+conversion and basic types manipulation, which we may want to look at one time
 or another.  Finally, the syntax is a little esoteric.
 
 
--- a/doc/book/en/development/devcore/dbapi.rst	Thu Apr 08 14:40:18 2010 +0200
+++ b/doc/book/en/development/devcore/dbapi.rst	Thu Apr 08 19:37:00 2010 +0200
@@ -5,9 +5,10 @@
 
 The Python API developped to interface with RQL is inspired from the standard db-api,
 with a Connection object having the methods cursor, rollback and commit essentially.
-The most important method is the `execute` method of a cursor :
+The most important method is the `execute` method of a cursor.
 
-`execute(rqlstring, args=None, cachekey=None, build_descr=True)`
+.. sourcecode:: python
+  execute(rqlstring, args=None, cachekey=None, build_descr=True)
 
 :rqlstring: the RQL query to execute (unicode)
 :args: if the query contains substitutions, a dictionary containing the values to use
@@ -18,10 +19,11 @@
    through this argument
 
 
-The `Connection` object owns the methods `commit` and `rollback`. You *should
-never need to use them* during the development of the web interface based on
-the *CubicWeb* framework as it determines the end of the transaction depending
-on the query execution success.
+The `Connection` object owns the methods `commit` and `rollback`. You
+*should never need to use them* during the development of the web
+interface based on the *CubicWeb* framework as it determines the end
+of the transaction depending on the query execution success. They are
+however useful in other contexts such as tests.
 
 .. note::
   While executing update queries (SET, INSERT, DELETE), if a query generates
@@ -30,6 +32,7 @@
 
 Executing RQL queries from a view or a hook
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
 When you're within code of the web interface, the db-api like connexion is
 handled by the request object. You should not have to access it directly, but
 use the `execute` method directly available on the request, eg:
@@ -50,33 +53,30 @@
 
    self._cw.execute('Any T WHERE T in_conf C, C eid %s' % entity.eid)
 
-But it can also be written in a syntax that will benefit from the use
+But it must be written in a syntax that will benefit from the use
 of a cache on the RQL server side:
 
 .. sourcecode:: python
 
-   self._cw.execute('Any T WHERE T in_conf C, C eid %(x)s', {'x': entity.eid}, 'x')
+   self._cw.execute('Any T WHERE T in_conf C, C eid %(x)s', {'x': entity.eid})
 
-Beside proper usage of the `args` argument, notice the latest argument: this is what's called
-the cache key. The cache key should be either a string or a tuple containing the names of keys
-in args which are referencing eids. *YOU MUST SET THIS PROPERLY* if you don't want weird result
-on queries which have ambigous solutions deambiguified by specifing an eid. So the good habit is:
-*always put in the cache key all eid keys*.
+The syntax tree is built once for the "generic" RQL and can be re-used
+with a number of different eids. There rql IN operator is an exception
+to this rule.
 
-The syntax tree is build once for the "generic" RQL and can be re-used
-with a number of different eid.
+.. sourcecode:: python
+
+   self._cw.execute('Any T WHERE T in_conf C, C name IN (%s)' % ','.join(['foo', 'bar']))
 
-Alternativelly, some of the common data related to an entity can be obtained from
-the top-level `entity.related()` method (which is used under the hood by the orm
-when you use attribute access notation on an entity to get a relation. The above
-would then be translated to:
+Alternativelly, some of the common data related to an entity can be
+obtained from the `entity.related()` method (which is used under the
+hood by the orm when you use attribute access notation on an entity to
+get a relation. The initial request would then be translated to:
 
 .. sourcecode:: python
 
    entity.related('in_conf', 'object')
 
-The `related()` method, as more generally others orm methods, makes extensive use
-of the cache mechanisms so you don't have to worry about them. Additionnaly this
-use will get you commonly used attributes that you will be able to use in your
-view generation without having to ask the data backend.
-
+Additionnaly this benefits from the fetch_attrs policy eventually
+defined on the class element, which says which attributes must be also
+loaded when the entity is loaded through the orm.
--- a/doc/book/en/development/devrepo/hooks.rst	Thu Apr 08 14:40:18 2010 +0200
+++ b/doc/book/en/development/devrepo/hooks.rst	Thu Apr 08 19:37:00 2010 +0200
@@ -2,31 +2,103 @@
 
 .. _hooks:
 
-Hooks
-=====
+Hooks and Operations
+====================
+
+Principles
+----------
 
-XXX FILLME
+Paraphrasing the `emacs`_ documentation, let us say that hooks are an
+important mechanism for customizing an application. A hook is
+basically a list of functions to be called on some well-defined
+occasion (This is called `running the hook`).
+
+.. _`emacs`: http://www.gnu.org/software/emacs/manual/html_node/emacs/Hooks.html
+
+In CubicWeb, hooks are classes subclassing the Hook class in
+`server/hook.py`, implementing their own `call` method, and defined
+over pre-defined `events`.
+
+There are two families of events: data events and server events. In a
+typical application, most of the Hooks are defined over data
+events. There can be a lot of them.
 
-*Hooks* are executed before or after updating an entity or a relation in the
-repository.
+The purpose of data hooks is to complement the data model as defined
+in the schema.py, which is static by nature, with dynamic or value
+driven behaviours. It is functionally equivalent to a `database
+trigger`_, except that database triggers definitions languages are not
+standardized, hence not portable (for instance, PL/SQL works with
+Oracle and PostgreSQL but not SqlServer nor Sqlite).
+
+.. _`database trigger`: http://en.wikipedia.org/wiki/Database_trigger
+
+Data hooks can serve the following purposes:
+
+* enforcing constraints that the static schema cannot express
+  (spanning several entities/relations, exotic cardinalities, etc.)
 
-Their prototypes are as follows:
+* implement computed attributes (an example could be the maintenance
+  of a relation representing the transitive closure of another relation)
+
+Operations are Hook-like objects that are created by Hooks and
+scheduled to happen just before (or after) the `commit` event. Hooks
+being fired immediately on data operations, it is sometime necessary
+to delay the actual work down to a time where all other Hooks have run
+and the application state converges towards consistency. Also while
+the order of execution of Hooks is data dependant (and thus hard to
+predict), it is possible to force an order on Operations.
+
+Events
+------
 
-    * after_add_entity     (session, entity)
-    * after_update_entity  (session, entity)
-    * after_delete_entity  (session, eid)
-    * before_add_entity    (session, entity)
-    * before_update_entity (session, entity)
-    * before_delete_entity (session, eid)
+Hooks are mostly defined and used to handle `dataflow`_ operations. It
+means as data gets in (mostly), specific events are issued and the
+Hooks matching these events are called.
+
+.. _`dataflow`: http://en.wikipedia.org/wiki/Dataflow
+
+Below comes a list of the dataflow events related to entities operations:
+
+* before_add_entity
+
+* before_update_entity
+
+* before_delete_entity
+
+* after_add_entity
+
+* after_update_entity
+
+* after_delete_entity
+
+These define ENTTIES HOOKS. RELATIONS HOOKS are defined
+over the following events:
+
+* after_add_relation
 
-    * after_add_relation     (session, fromeid, rtype, toeid)
-    * after_delete_relation  (session, fromeid, rtype, toeid)
-    * before_add_relation    (session, fromeid, rtype, toeid)
-    * before_delete_relation (session, fromeid, rtype, toeid)
+* after_delete_relation
+
+* before_add_relation
+
+* before_delete_relation
+
+This is an occasion to remind us that relations support the add/delete
+operation, but no delete.
+
+Non data events also exist. These are called SYSTEM HOOKS.
+
+* server_startup
 
-    * server_startup
-    * server_shutdown
+* server_shutdown
+
+* server_maintenance
+
+* server_backup
 
-    * session_open
-    * session_close
+* server_restore
+
+* session_open
 
+* session_close
+
+
--- a/doc/book/en/intro/concepts.rst	Thu Apr 08 14:40:18 2010 +0200
+++ b/doc/book/en/intro/concepts.rst	Thu Apr 08 19:37:00 2010 +0200
@@ -339,5 +339,5 @@
 .. Note:
    RQL queries executed in hooks and operations are *unsafe* by default, e.g. the
    read and write security is deactivated unless explicitly asked.
-  
+
 .. |cubicweb| replace:: *CubicWeb*
--- a/server/hook.py	Thu Apr 08 14:40:18 2010 +0200
+++ b/server/hook.py	Thu Apr 08 19:37:00 2010 +0200
@@ -30,7 +30,6 @@
 
 Session hooks (eg session_open, session_close) have no special attribute.
 
-
 :organization: Logilab
 :copyright: 2001-2010 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr