# HG changeset patch # User Sylvain Thénault # Date 1265221595 -3600 # Node ID 550cf406dbc6d0a2e8f1f620f7185dddccc1b633 # Parent 2eb6112ba4f07258e5a38220e2c33825de9b07c3 moved content to the dbapi section diff -r 2eb6112ba4f0 -r 550cf406dbc6 doc/book/en/development/devcore/dbapi.rst --- a/doc/book/en/development/devcore/dbapi.rst Wed Feb 03 18:45:20 2010 +0100 +++ b/doc/book/en/development/devcore/dbapi.rst Wed Feb 03 19:26:35 2010 +0100 @@ -7,11 +7,11 @@ with a Connection object having the methods cursor, rollback and commit essentially. The most important method is the `execute` method of a cursor : -`execute(rqlstring, args=None, eid_key=None, build_descr=True)` +`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 -:eid_key: +:cachekey: an implementation detail of the RQL cache implies that if a substitution is used to introduce an eid *susceptible to raise the ambiguities in the query type resolution*, then we have to specify the corresponding key in the dictionary @@ -27,3 +27,56 @@ While executing update queries (SET, INSERT, DELETE), if a query generates an error related to security, a rollback is automatically done on the current transaction. + +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: + + rset = self._cw.execute(rqlstring, kwargs) + +Similarly, on the server side (eg in hooks), there is no db-api connexion (since +you're directly inside the data-server), so you'll have to use the execute method +of the session object. + + +Important note about proper usage of .execute +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Let's say you want to get T which is in configuration C, this translates to: + +.. sourcecode:: python + + 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 +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') + +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 build once for the "generic" RQL and can be re-used +with a number of different eid. + +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: + +.. 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. + diff -r 2eb6112ba4f0 -r 550cf406dbc6 doc/book/en/development/devweb/gettingdata.rst --- a/doc/book/en/development/devweb/gettingdata.rst Wed Feb 03 18:45:20 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ - -.. _Getting Data: - -Getting Data ------------- - -You might have spotted this in the explanations about the views, to -get data, when not using a toplevel method, you will execute an RQL -query over the._cwuest. For more details about RQL, head out to the -`RQL chapter` - -Basic cases -``````````` -In a similiar way that you might be used to in SQL, to obtain data -from the RQL backend, you will execute an RQL command and obtain a -resultset :: - - rset = self._cw.execute(rql_command) - -Then, you can use the data from the rset. - -XXX complete section with examples - -Use of the cache for RQL execution -`````````````````````````````````` -Let's say you want to get T which is in configuration C, this translates to :: - - 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 -of a cache on the RQL server side. :: - - self._cw.execute('Any T WHERE T in_conf C, C eid %(x)s', {'x': entity.eid}, 'x') - -The syntax tree is build once for the "generic" RQL and can be re-used -with a number of different eid. Alternativelly, some of the common -data related to an entity can be obtained from the top-level -`entity.related()` method. The above would then be translated to :: - - entity.related('in_conf', 'object') - -The `related()` method 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. -