[book] update rql documentation and some erroneous/deprecated examples
authorJulien Jehannet <julien.jehannet@logilab.fr>
Wed, 07 Jul 2010 10:53:03 +0200
changeset 5924 b218df942dd4
parent 5923 d1b374aa5174
child 5926 89e27940df99
[book] update rql documentation and some erroneous/deprecated examples
doc/book/en/annexes/depends.rst
doc/book/en/annexes/faq.rst
doc/book/en/annexes/rql/Graph-ex.gif
doc/book/en/annexes/rql/debugging.rst
doc/book/en/annexes/rql/index.rst
doc/book/en/annexes/rql/intro.rst
doc/book/en/annexes/rql/language.rst
doc/book/en/devrepo/profiling.rst
doc/book/en/tutorials/tools/windmill.rst
req.py
--- a/doc/book/en/annexes/depends.rst	Wed Jul 07 13:50:55 2010 +0200
+++ b/doc/book/en/annexes/depends.rst	Wed Jul 07 10:53:03 2010 +0200
@@ -27,6 +27,9 @@
 * logilab-common - http://www.logilab.org/project/logilab-common -
   http://pypi.python.org/pypi/logilab-common/ - included in the forest
 
+* logilab-database - http://www.logilab.org/project/logilab-database -
+  http://pypi.python.org/pypi/logilab-database/ - included in the forest
+
 * logilab-constraint - http://www.logilab.org/project/logilab-constraint -
   http://pypi.python.org/pypi/constraint/ - included in the forest
 
@@ -44,7 +47,7 @@
 
 To use network communication between cubicweb instances / clients:
 
-* Pyro - http://pyro.sourceforge.net/ - http://pypi.python.org/pypi/Pyro
+* Pyro - http://www.xs4all.nl/~irmen/pyro3/ - http://pypi.python.org/pypi/Pyro
 
 If you're using a Postgres database (recommended):
 
--- a/doc/book/en/annexes/faq.rst	Wed Jul 07 13:50:55 2010 +0200
+++ b/doc/book/en/annexes/faq.rst	Wed Jul 07 10:53:03 2010 +0200
@@ -115,7 +115,7 @@
 
     from cubicweb import dbapi
 
-    cnx = dbapi.connection(database='instance-id', user='admin', password='admin')
+    cnx = dbapi.connect(database='instance-id', user='admin', password='admin')
     cur = cnx.cursor()
     for name in ('Personal', 'Professional', 'Computers'):
         cur.execute('INSERT Blog B: B name %s', name)
@@ -302,10 +302,10 @@
     import pwd
     import sys
 
-    from logilab.common.db import get_connection
+    from logilab.database import get_connection
 
     def getlogin():
-        """avoid usinng os.getlogin() because of strange tty / stdin problems
+        """avoid using os.getlogin() because of strange tty/stdin problems
         (man 3 getlogin)
         Another solution would be to use $LOGNAME, $USER or $USERNAME
         """
@@ -402,6 +402,20 @@
     mydb=> update cw_cwuser set cw_upassword='qHO8282QN5Utg' where cw_login='joe';
     UPDATE 1
 
+You can prefer use a migration script similar to this shell invocation instead::
+
+    $ cubicweb-ctl shell <instance>
+    >>> from cubicweb.server.utils import crypt_password
+    >>> crypted = crypt_password('joepass')
+    >>> rset = rql('Any U WHERE U is CWUser, U login "joe"')
+    >>> joe = rset.get_entity(0,0)
+    >>> joe.set_attributes(upassword=crypted)
+
+The more experimented people would use RQL request directly::
+
+    >>> rql('SET X upassword %(a)s WHERE X is CWUser, X login "joe"',
+    ...     {'a': crypted})
+
 I've just created a user in a group and it doesn't work !
 ---------------------------------------------------------
 
Binary file doc/book/en/annexes/rql/Graph-ex.gif has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/annexes/rql/debugging.rst	Wed Jul 07 10:53:03 2010 +0200
@@ -0,0 +1,56 @@
+.. -*- coding: utf-8 -*-
+
+.. _DEBUGGING:
+
+Debugging RQL
+-------------
+
+Available levels
+~~~~~~~~~~~~~~~~
+
+:DBG_NONE:
+    no debug information (current mode)
+
+:DBG_RQL:
+    rql execution information
+
+:DBG_SQL:
+    executed sql
+
+:DBG_REPO:
+    repository events
+
+:DBG_MS:
+    multi-sources
+
+:DBG_MORE:
+    more verbosity
+
+:DBG_ALL:
+    all level enabled
+
+
+Enable verbose output
+~~~~~~~~~~~~~~~~~~~~~
+
+It may be interested to enable a verboser output to debug your RQL statements:
+
+.. sourcecode:: python
+
+    from cubicweb import server
+    server.set_debug(server.DBG_RQL|server.DBG_SQL|server.DBG_ALL)
+
+
+Detect largest RQL queries
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+See `Profiling and performance` chapter (see :ref:`PROFILING`).
+
+
+API
+~~~
+
+.. autofunction:: cubicweb.server.set_debug
+
+.. autoclass:: cubicweb.server.debugged
+
--- a/doc/book/en/annexes/rql/index.rst	Wed Jul 07 13:50:55 2010 +0200
+++ b/doc/book/en/annexes/rql/index.rst	Wed Jul 07 10:53:03 2010 +0200
@@ -4,8 +4,9 @@
 This chapter describes the Relation Query Language syntax and its implementation in CubicWeb.
 
 .. toctree::
-   :maxdepth: 1
+   :maxdepth: 2
 
    intro
    language
+   debugging
    implementation
--- a/doc/book/en/annexes/rql/intro.rst	Wed Jul 07 13:50:55 2010 +0200
+++ b/doc/book/en/annexes/rql/intro.rst	Wed Jul 07 10:53:03 2010 +0200
@@ -7,8 +7,13 @@
 Goals of RQL
 ~~~~~~~~~~~~
 
-The goal is to have a language making relations browsing easy. As
-such, attributes will be regarded as cases of special relations (in
+The goal is to have a semantic language in order to:
+
+- query relations in a clear syntax
+- empowers access to data repository manipulation
+- making attributes/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).
 
@@ -59,7 +64,78 @@
    Remove entities or relations existing in the database.
 
 
+Concepts
+~~~~~~~~
+
+Entity type
+```````````
+
+RQL manipulates variables that are instances of entities.
+Each entity has its own type which are used in backend to improve the query
+execution plan.
+
+Restrictions
+````````````
+
+They are conditions used to limit the perimeter of the result set.
+
+Relations
+`````````
+A relation is a `3-expression` defined as follows:
+
+.. image:: Graph-ex.gif
+    :alt: <subject> <predicate> <object>
+    :align: center
+
+A RQL relation contains three components:
+
+* the subject, which is an entity type
+* the predicate, which is an oriented graph
+* the object, which is either an attribute or a relation to another entity
+
+In cubicweb, the term `relation` is often found without ambiguity instead of `predicate`.
+This predicate is also known as the `property` of the triple in `RDF concepts`_
+
+A relation is always expressed in the order: subject, predicate, object.
+
+It's important to determine if entity type is subject or object to construct a
+valid expression. An inversion subject/object is equivalent to an RQL error
+since the supposed relation cannot be found in schema. If you don't have access
+to the code, you could find the order by looking at the schema image in manager
+views (the subject is located at the beginning of the arrow).
+
+.. _SQL: http://www.firstsql.com/tutor5.htm
+.. _RDF concepts: http://www.w3.org/TR/rdf-concepts/
+
+Cardinality
+```````````
+XXX
+
+Cardinality is an important concept to model your business rules.
+They determine nu./tutorials/advanced/index.rst
+
+Please refer to the `datamodel definitions`_ for a deep understanding.
+
+`Relations`_ are always expressed by cardinality rules (`**` by default)
+
+.. _datamodel definitions: ./devrepo/datamodel/definition.rst
+
+Transaction
+```````````
+
+RQL supports notion of **transactions**; i.e. sequences of RQL statements
+without invoking security hooks of the instance's schema.
+
+When you're ready to make persistent the changes, you have to *commit* the
+modification in calling `commit()`.
+
+If an error is found (typically in raising a ValidationError), you have the
+possibility to roll back the transaction in invoking `rollback()` function; i.e
+to come back to the initial state of the transaction.
+
+Please, refer to the :ref:`Migration` chapter if you want more details.
 
 
-.. _Versa: http://uche.ogbuji.net/tech/rdf/versa/
+
+.. _Versa: http://wiki.xml3k.org/Versa
 .. _SPARQL: http://www.w3.org/TR/rdf-sparql-query/
--- a/doc/book/en/annexes/rql/language.rst	Wed Jul 07 13:50:55 2010 +0200
+++ b/doc/book/en/annexes/rql/language.rst	Wed Jul 07 10:53:03 2010 +0200
@@ -15,6 +15,7 @@
   HAVING, ILIKE, IN, INSERT, LIKE, LIMIT, NOT, NOW, NULL, OFFSET,
   OR, ORDERBY, SET, TODAY, TRUE, UNION, WHERE, WITH
 
+
 Variables and Typing
 ~~~~~~~~~~~~~~~~~~~~
 
@@ -29,10 +30,11 @@
 There is a special type **Any**, referring to a non specific type.
 
 We can restrict the possible types for a variable using the
-special relation **is**.
+special relation **is** in the constraints.
+
 The possible type(s) for each variable is derived from the schema
-according to the constraints expressed above and thanks to the relations between
-each variable.
+according to the constraints expressed above and thanks to the relations
+between each variable.
 
 Built-in types
 ``````````````
@@ -63,7 +65,7 @@
   of logical operators (see :ref:`PriorityOperators`).
 
 Mathematical Operators
-```````````````````````
+``````````````````````
 ::
 
      +, -, *, /
@@ -74,7 +76,13 @@
 
      =, <, <=, >=, >, ~=, IN, LIKE, ILIKE
 
-* The operator `=` is the default operator.
+* Syntax to use comparison operator:
+
+    `VARIABLE relation operator VALUE`
+
+* The operator `=` is the default operator and can be omitted.
+
+* `relation` name is always attended
 
 * The operator `LIKE` equivalent to `~=` can be used with the
   special character `%` in a string to indicate that the chain
@@ -89,7 +97,7 @@
 * The operator `IN` provides a list of possible values:
   ::
 
-    Any X WHERE X name IN ( 'chauvat', 'fayolle', 'di mascio', 'thenault')
+    Any X WHERE X name IN ('chauvat', 'fayolle', 'di mascio', 'thenault')
 
 
 .. XXX nico: "A trick <> 'bar'" wouldn't it be more convenient than "NOT A trick 'bar'" ?
@@ -100,16 +108,11 @@
 ``````````````````
 
 1. '*', '/'
-
 2. '+', '-'
-
-3. 'not'
-
-4 'and'
-
-5 'or'
-
-6 ','
+3. 'NOT'
+4. 'AND'
+5. 'OR'
+6. ','
 
 
 Search Query
@@ -141,16 +144,39 @@
 ``````````````````
 
 - For grouped queries (e.g. with a GROUPBY clause), all
-  selected variables should be grouped.
+  selected variables should be grouped at the right of the keyword.
 
-- To group and/or sort by attributes, we can do: "X,L user U, U
-  login L GROUPBY L, X ORDERBY L"
+- To group and/or sort by attributes, we can do::
+
+  X,L user U, U login L GROUPBY L, X ORDERBY L
 
 - If the sorting method (SORT_METHOD) is not specified, then the sorting is
-  ascendant.
+  ascendant (`ASC`).
 
 - Aggregate Functions: COUNT, MIN, MAX, AVG, SUM
 
+Having
+``````
+
+The HAVING clause, as in SQL, has been originally introduced to restrict a query according to value returned by an aggregate function, e.g.::
+
+    Any X GROUPBY X WHERE X relation Y HAVING COUNT(Y) > 10
+
+It may however be used for something else...
+
+In the WHERE clause, we are limited to 3-expression_, such thing can't be expressed directly as in the SQL's way. But this can be expressed using HAVING comparison expression.
+
+For instance, let's say you want to get people whose uppercased first name equals to another person uppercased first name::
+
+    Person X WHERE X firstname XFN, Y firstname YFN HAVING X > Y, UPPER(XFN) = UPPER(YFN)
+
+This open some new possibilities. Another example::
+
+    Person X WHERE X birthday XB HAVING YEAR(XB) = 2000
+
+That lets you use transformation functions not only in selection but for restriction as well and to by-pass limitation of the WHERE clause, which was the major flaw in the RQL language.
+
+Notice that while we would like this to work without the HAVING clause, this can't be currently be done because it introduces an ambiguity in RQL's grammar that can't be handled by Yapps_, the parser's generator we're using.
 
 Negation
 ````````
@@ -170,9 +196,8 @@
 
    Any A WHERE A comments B, A identity B
 
-return all objects that comment themselves. The relation
-`identity` is especially useful when defining the rules for securities
-with `RQLExpressions`.
+return all objects that comment themselves. The relation `identity` is
+especially useful when defining the rules for securities with `RQLExpressions`.
 
 
 Limit / offset
@@ -181,13 +206,6 @@
 
     Any P ORDERBY N LIMIT 5 OFFSET 10 WHERE P is Person, P firstname N
 
-Function calls
-``````````````
-::
-
-    Any UPPER(N) WHERE P firstname N
-
-Functions on string: UPPER, LOWER
 
 Exists
 ``````
@@ -199,8 +217,14 @@
           OR EXISTS(T tags X, T name "priority")
 
 
-Optional relations (Left outer join)
-````````````````````````````````````
+Optional relations
+``````````````````
+
+It is a similar concept that the `Left outer join`_:
+
+    the result of a left outer join (or simply left join) for table A and B
+    always contains all records of the "left" table (A), even if the
+    join-condition does not find any matching record in the "right" table (B).
 
 * They allow you to select entities related or not to another.
 
@@ -218,12 +242,6 @@
     Any T,P,V WHERE T is Ticket, T concerns P, T done_in V?
 
 
-Having
-``````
-::
-
-    Any X GROUPBY X WHERE X knows Y HAVING COUNT(Y) > 10
-
 Subqueries
 ``````````
 ::
@@ -234,16 +252,29 @@
      DISTINCT Any W, REF
         WITH W, REF BEING
             (
-	      (Any W, REF WHERE W is Workcase, W ref REF,
+              (Any W, REF WHERE W is Workcase, W ref REF,
                                  W concerned_by D, D name "Logilab")
                UNION
               (Any W, REF WHERE W is Workcase, W ref REF, '
                                 W split_into WP, WP name "WP1")
             )
 
+Function calls
+``````````````
+::
+
+    Any UPPER(N) WHERE P firstname N
+    Any LOWER(N) WHERE P firstname N
+
+Functions available on string: `UPPER`, `LOWER`
+
+.. XXX retrieve available function automatically
+
+For a performance issue, you can enrich the RQL dialect by RDMS (Relational database management system) functions.
+
 
 Examples
-````````
+~~~~~~~~
 
 - *Search for the object of identifier 53*
   ::
@@ -280,11 +311,11 @@
         P is Person, (P interested_by T, T name 'training') OR
         (P city 'Paris')
 
-- *The name and surname of all people*
+- *The surname and firstname of all people*
   ::
 
         Any N, P WHERE
-        X is Person, X name N, X first_name P
+        X is Person, X name N, X firstname P
 
   Note that the selection of several entities generally force
   the use of "Any" because the type specification applies otherwise
@@ -304,7 +335,7 @@
 
 
 Insertion query
-~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~
 
     `INSERT` <entity type> V1 (, <entity type> V2) \ * `:` <assignments>
     [ `WHERE` <restriction>]
@@ -336,6 +367,7 @@
 
 Update and relation creation queries
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
     `SET` <assignements>
     [ `WHERE` <restriction>]
 
@@ -345,7 +377,7 @@
 - *Renaming of the person named 'foo' to 'bar' with the first name changed*
   ::
 
-        SET X name 'bar', X first_name 'original' WHERE X is Person, X name 'foo'
+        SET X name 'bar', X firstname 'original' WHERE X is Person, X name 'foo'
 
 - *Insert a relation of type 'know' between objects linked by
   the relation of type 'friend'*
@@ -356,6 +388,7 @@
 
 Deletion query
 ~~~~~~~~~~~~~~
+
     `DELETE` (<entity type> V) | (V1 relation v2 ),...
     [ `WHERE` <restriction>]
 
@@ -372,6 +405,7 @@
 
         DELETE X friend Y WHERE X is Person, X name 'foo'
 
+
 Virtual RQL relations
 ~~~~~~~~~~~~~~~~~~~~~
 
@@ -381,6 +415,13 @@
 * `has_text`: relation to use to query the full text index (only for
   entities having fulltextindexed attributes).
 
-* `identity`: relation to use to tell that a RQL variable should be
+* `identity`: `Identity`_ relation to use to tell that a RQL variable should be
   the same as another (but you've to use two different rql variables
   for querying purpose)
+
+* `is`: relation to enforce possible types for a variable
+
+
+
+.. _Yapps: http://theory.stanford.edu/~amitp/yapps/
+.. _Left outer join: http://en.wikipedia.org/wiki/Join_(SQL)#Left_outer_join
--- a/doc/book/en/devrepo/profiling.rst	Wed Jul 07 13:50:55 2010 +0200
+++ b/doc/book/en/devrepo/profiling.rst	Wed Jul 07 10:53:03 2010 +0200
@@ -1,3 +1,5 @@
+.. _PROFILING:
+
 Profiling and performance
 =========================
 
--- a/doc/book/en/tutorials/tools/windmill.rst	Wed Jul 07 13:50:55 2010 +0200
+++ b/doc/book/en/tutorials/tools/windmill.rst	Wed Jul 07 10:53:03 2010 +0200
@@ -26,7 +26,16 @@
     pip install windmill
     curl -O http://github.com/windmill/windmill/tarball/master
 
-Some install instructions are `available <http://wiki.github.com/windmill/windmill/installing>`_.
+However, the Windmill project doesn't release frequently. Our recommandation is
+to used the last snapshot of the Git repository:
+
+.. sourcecode:: shell
+
+    git clone git://github.com/windmill/windmill.git HEAD
+    cd windmill
+    python setup.py develop
+
+Install instructions are `available <http://wiki.github.com/windmill/windmill/installing>`_.
 
 Be sure to have the windmill module in your PYTHONPATH afterwards::
 
--- a/req.py	Wed Jul 07 13:50:55 2010 +0200
+++ b/req.py	Wed Jul 07 10:53:03 2010 +0200
@@ -133,7 +133,7 @@
         Example (in a shell session):
 
         >>> c = create_entity('Company', name=u'Logilab')
-        >>> create_entity('Person', firstname=u'John', lastname=u'Doe',
+        >>> create_entity('Person', firstname=u'John', surname=u'Doe',
         ...               works_for=c)
 
         """