[Cubicweb] ORMHelper registry

Adrien Di Mascio adrien.dimascio at logilab.fr
Wed Mar 9 08:30:30 CET 2011


Hi,

On 08/03/2011 20:38, aurélien campéas wrote:
>     - use RQL functions to change fetch_order
> this is not (yet) very palatable to me
> any example ?

RQL functions is actually a not-so-good example since this is already 
achievable with a custom fetch_order method as in:

    @classmethod
    def fetch_order(cls, attr, var):
        if attr == 'firstname':
            return 'LOWER(firstname)'
        return None

but then what if the RQL function takes 2 parameters ? One being the 
corresponding attribute, the other being another attribute or worse an 
attribute fetched on a linked entity (typically a linked by a composite 
relation).


>     - sort according to "composed entities" (e.g. if schema defines "A
>     rel1 B", "B rel2 (composite) C", I might want A.related('rel1') to
>     sort according to C)
>
>     - fetch other relations and other attributes that CubicWeb has no
>     chance to guess
>
> examples ?


In one of my cubes, some content needs to be localized. Here's
a simplified example of the schema::

   class Language(EntityType):
     iso_code = String(maxsize=2)
     label = String(maxsize=64, internationalizable=True)

   class LocalizedValue(EntityType):
     value = String()
     lang = SubjectRelation('Language', '1*')

   class SectionDefinition(EntityType):
     section_id = String(maxsize=64)
     l10n_title = SubjectRelation('LocalizedValue', cardinality='+?')
     l10n_descr = SubjectRelation('LocalizedValue', cardinality='+?')

In the above schema, I want SectionDefinition's title and description to 
be localized (hence ``l10n_title`` and ``l10n_descr``).

Now, assuming that ``sect_def`` is a ``SectionDefinition`` entity 
object, I'd like ``sect_def.l10n_xxx`` to fetch corresponding ``xxx`` 
values sorted by a custom RQL function applied on langs. (In this 
application, languages are ordered, say english > french > spanish).

To fulfill that case, I have overloaded ``cw_related_rql``::

   class SectionDefinition(AnyEntity):
     __regid__ = 'SectionDefinition'
     def cw_related_rql(self, rtype, role='subject',
                        targettypes=None):
       if str(rtype).startswith('l10n'):
         return ('Any X, XT, XL, XLC ORDERBY LANG_SORT_VALUE(XLC) '
                 'WHERE E eid %%(x)s, E %s X, '
                 'X value XT, X in_lang XL, XL iso_code XLC') % rtype
       return super(EcoverNavigationMixIn, self).cw_related_rql(rtype,
                                                 role, targettypes)


Actually, while pasting this code, I can't remember why this was done at 
``SectionDefinition`` level rather than at ``LocalizedValue`` level :-/. 
The problem would have been the same, though. If I want to sort 
according to a linked entity attribute (here: LocalizedValue objects 
must be sorted according to a lang.iso_code), current ``fetch_order()`` 
API is not flexible enough to let me do this.


We could simply extend ``fetch_order()`` (and ``fetch_attrs()``) API and 
expose the rql syntax tree there, but I think a more general approach is 
to consider that we can't foresee every cases and the ``ORMHelper`` (or 
DatabaseHelper or whatever it would be called) would solve this case.

Another benefit I can see is that it will unclutter a bit the Entity 
class and provide a better dispatch of responsibilities, and I really 
think there are cases where fetch_attrs should be context-dependant.

-- 
Adrien Di Mascio - LOGILAB, Paris (France).
Tél: 01.45.32.03.12
Formations - http://www.logilab.fr/formations
Développements - http://www.logilab.fr/services
Gestion de connaissances - http://www.cubicweb.org/



More information about the Cubicweb mailing list