schema.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Thu, 02 Jul 2009 10:35:03 +0200
changeset 2234 1fbcf202882d
parent 2185 09d0445641e2
parent 2222 81130047390d
child 2293 7ded2a1416e4
permissions -rw-r--r--
backport stable
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     1
"""classes to define schemas for CubicWeb
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     2
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     3
:organization: Logilab
1977
606923dff11b big bunch of copyright / docstring update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1498
diff changeset
     4
:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     5
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
1977
606923dff11b big bunch of copyright / docstring update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1498
diff changeset
     6
:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     7
"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     8
__docformat__ = "restructuredtext en"
2142
098aa2075903 include_schema_files is useless
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
     9
_ = unicode
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    10
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    11
import re
2147
476a75ede2cc merge and add missing import in schema.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2142
diff changeset
    12
from os.path import join
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    13
from logging import getLogger
1133
8a409ea0c9ec more linting
sylvain.thenault@logilab.fr
parents: 1132
diff changeset
    14
from warnings import warn
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    15
624
258e5692ae06 provide a new RichString attribute type
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 479
diff changeset
    16
from logilab.common.decorators import cached, clear_cache, monkeypatch
2201
ddc1f58c8e8b deprecate display_name from builtin, ask for explicit import
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2157
diff changeset
    17
from logilab.common.deprecation import obsolete
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    18
from logilab.common.compat import any
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    19
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    20
from yams import BadSchemaDefinition, buildobjs as ybo
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    21
from yams.schema import Schema, ERSchema, EntitySchema, RelationSchema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    22
from yams.constraints import BaseConstraint, StaticVocabularyConstraint
2183
9dfa88ac9f49 RelationFileReader is dead
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2181
diff changeset
    23
from yams.reader import CONSTRAINTS, PyFileReader, SchemaLoader
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    24
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    25
from rql import parse, nodes, RQLSyntaxError, TypeResolverException
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    26
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    27
from cubicweb import ETYPE_NAME_MAP, ValidationError, Unauthorized
1138
22f634977c95 make pylint happy, fix some bugs on the way
sylvain.thenault@logilab.fr
parents: 1133
diff changeset
    28
from cubicweb import set_log_methods
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    29
1016
26387b836099 use datetime instead of mx.DateTime
sylvain.thenault@logilab.fr
parents: 745
diff changeset
    30
# XXX <3.2 bw compat
26387b836099 use datetime instead of mx.DateTime
sylvain.thenault@logilab.fr
parents: 745
diff changeset
    31
from yams import schema
26387b836099 use datetime instead of mx.DateTime
sylvain.thenault@logilab.fr
parents: 745
diff changeset
    32
schema.use_py_datetime()
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
    33
nodes.use_py_datetime()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    34
2126
a25859917ccc stop using meta attribute from yams schema. Use instead sets defining meta relations and another defining schema types. Refactor various schema view based on this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    35
#  set of meta-relations available for every entity types
a25859917ccc stop using meta attribute from yams schema. Use instead sets defining meta relations and another defining schema types. Refactor various schema view based on this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    36
META_RELATIONS_TYPES = set((
a25859917ccc stop using meta attribute from yams schema. Use instead sets defining meta relations and another defining schema types. Refactor various schema view based on this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    37
    'owned_by', 'created_by', 'is', 'is_instance_of', 'identity',
a25859917ccc stop using meta attribute from yams schema. Use instead sets defining meta relations and another defining schema types. Refactor various schema view based on this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    38
    'eid', 'creation_date', 'modification_date', 'has_text',
2184
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 2181
diff changeset
    39
    ))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    40
2126
a25859917ccc stop using meta attribute from yams schema. Use instead sets defining meta relations and another defining schema types. Refactor various schema view based on this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    41
#  set of entity and relation types used to build the schema
a25859917ccc stop using meta attribute from yams schema. Use instead sets defining meta relations and another defining schema types. Refactor various schema view based on this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    42
SCHEMA_TYPES = set((
a25859917ccc stop using meta attribute from yams schema. Use instead sets defining meta relations and another defining schema types. Refactor various schema view based on this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    43
    'CWEType', 'CWRType', 'CWAttribute', 'CWRelation',
a25859917ccc stop using meta attribute from yams schema. Use instead sets defining meta relations and another defining schema types. Refactor various schema view based on this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    44
    'CWConstraint', 'CWConstraintType', 'RQLExpression',
a25859917ccc stop using meta attribute from yams schema. Use instead sets defining meta relations and another defining schema types. Refactor various schema view based on this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    45
    'relation_type', 'from_entity', 'to_entity',
a25859917ccc stop using meta attribute from yams schema. Use instead sets defining meta relations and another defining schema types. Refactor various schema view based on this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    46
    'constrained_by', 'cstrtype',
a25859917ccc stop using meta attribute from yams schema. Use instead sets defining meta relations and another defining schema types. Refactor various schema view based on this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    47
    # XXX those are not really "schema" entity types
a25859917ccc stop using meta attribute from yams schema. Use instead sets defining meta relations and another defining schema types. Refactor various schema view based on this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    48
    #     but we usually don't want them as @* targets
a25859917ccc stop using meta attribute from yams schema. Use instead sets defining meta relations and another defining schema types. Refactor various schema view based on this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    49
    'CWProperty', 'CWPermission', 'State', 'Transition',
a25859917ccc stop using meta attribute from yams schema. Use instead sets defining meta relations and another defining schema types. Refactor various schema view based on this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    50
    ))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    51
2142
098aa2075903 include_schema_files is useless
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    52
_LOGGER = getLogger('cubicweb.schemaloader')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    53
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    54
# schema entities created from serialized schema have an eid rproperty
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    55
ybo.ETYPE_PROPERTIES += ('eid',)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    56
ybo.RTYPE_PROPERTIES += ('eid',)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    57
ybo.RDEF_PROPERTIES += ('eid',)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    58
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    59
def bw_normalize_etype(etype):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    60
    if etype in ETYPE_NAME_MAP:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    61
        msg = '%s has been renamed to %s, please update your code' % (
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
    62
            etype, ETYPE_NAME_MAP[etype])
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    63
        warn(msg, DeprecationWarning, stacklevel=4)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    64
        etype = ETYPE_NAME_MAP[etype]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    65
    return etype
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    66
624
258e5692ae06 provide a new RichString attribute type
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 479
diff changeset
    67
258e5692ae06 provide a new RichString attribute type
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 479
diff changeset
    68
## cubicweb provides a RichString class for convenience
258e5692ae06 provide a new RichString attribute type
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 479
diff changeset
    69
class RichString(ybo.String):
258e5692ae06 provide a new RichString attribute type
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 479
diff changeset
    70
    """Convenience RichString attribute type
1498
2c6eec0b46b9 fix imports, cleanup, repair some ajax calls
sylvain.thenault@logilab.fr
parents: 1477
diff changeset
    71
    The following declaration::
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
    72
624
258e5692ae06 provide a new RichString attribute type
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 479
diff changeset
    73
      class Card(EntityType):
258e5692ae06 provide a new RichString attribute type
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 479
diff changeset
    74
          content = RichString(fulltextindexed=True, default_format='text/rest')
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
    75
624
258e5692ae06 provide a new RichString attribute type
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 479
diff changeset
    76
    is equivalent to::
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
    77
624
258e5692ae06 provide a new RichString attribute type
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 479
diff changeset
    78
      class Card(EntityType):
258e5692ae06 provide a new RichString attribute type
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 479
diff changeset
    79
          content_format = String(meta=True, internationalizable=True,
258e5692ae06 provide a new RichString attribute type
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 479
diff changeset
    80
                                 default='text/rest', constraints=[format_constraint])
258e5692ae06 provide a new RichString attribute type
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 479
diff changeset
    81
          content  = String(fulltextindexed=True)
258e5692ae06 provide a new RichString attribute type
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 479
diff changeset
    82
    """
258e5692ae06 provide a new RichString attribute type
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 479
diff changeset
    83
    def __init__(self, default_format='text/plain', format_constraints=None, **kwargs):
258e5692ae06 provide a new RichString attribute type
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 479
diff changeset
    84
        self.default_format = default_format
258e5692ae06 provide a new RichString attribute type
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 479
diff changeset
    85
        self.format_constraints = format_constraints or [format_constraint]
258e5692ae06 provide a new RichString attribute type
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 479
diff changeset
    86
        super(RichString, self).__init__(**kwargs)
258e5692ae06 provide a new RichString attribute type
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 479
diff changeset
    87
258e5692ae06 provide a new RichString attribute type
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 479
diff changeset
    88
PyFileReader.context['RichString'] = RichString
258e5692ae06 provide a new RichString attribute type
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 479
diff changeset
    89
258e5692ae06 provide a new RichString attribute type
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 479
diff changeset
    90
## need to monkeypatch yams' _add_relation function to handle RichString
258e5692ae06 provide a new RichString attribute type
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 479
diff changeset
    91
yams_add_relation = ybo._add_relation
258e5692ae06 provide a new RichString attribute type
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 479
diff changeset
    92
@monkeypatch(ybo)
258e5692ae06 provide a new RichString attribute type
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 479
diff changeset
    93
def _add_relation(relations, rdef, name=None, insertidx=None):
258e5692ae06 provide a new RichString attribute type
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 479
diff changeset
    94
    if isinstance(rdef, RichString):
258e5692ae06 provide a new RichString attribute type
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 479
diff changeset
    95
        format_attrdef = ybo.String(meta=True, internationalizable=True,
258e5692ae06 provide a new RichString attribute type
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 479
diff changeset
    96
                                    default=rdef.default_format, maxsize=50,
258e5692ae06 provide a new RichString attribute type
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 479
diff changeset
    97
                                    constraints=rdef.format_constraints)
258e5692ae06 provide a new RichString attribute type
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 479
diff changeset
    98
        yams_add_relation(relations, format_attrdef, name+'_format', insertidx)
258e5692ae06 provide a new RichString attribute type
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 479
diff changeset
    99
    yams_add_relation(relations, rdef, name, insertidx)
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   100
2222
81130047390d [schema] fix Entity.add_relation(RichString(...)...)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 2201
diff changeset
   101
81130047390d [schema] fix Entity.add_relation(RichString(...)...)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 2201
diff changeset
   102
yams_EntityType_add_relation = ybo.EntityType.add_relation
81130047390d [schema] fix Entity.add_relation(RichString(...)...)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 2201
diff changeset
   103
@monkeypatch(ybo.EntityType)
81130047390d [schema] fix Entity.add_relation(RichString(...)...)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 2201
diff changeset
   104
def add_relation(self, rdef, name=None):
81130047390d [schema] fix Entity.add_relation(RichString(...)...)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 2201
diff changeset
   105
    yams_EntityType_add_relation(self, rdef, name)
81130047390d [schema] fix Entity.add_relation(RichString(...)...)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 2201
diff changeset
   106
    if isinstance(rdef, RichString) and not rdef in self._defined:
81130047390d [schema] fix Entity.add_relation(RichString(...)...)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 2201
diff changeset
   107
        format_attr_name = (name or rdef.name) + '_format'
81130047390d [schema] fix Entity.add_relation(RichString(...)...)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 2201
diff changeset
   108
        rdef = self.get_relations(format_attr_name).next()
81130047390d [schema] fix Entity.add_relation(RichString(...)...)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 2201
diff changeset
   109
        self._ensure_relation_type(rdef)
81130047390d [schema] fix Entity.add_relation(RichString(...)...)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 2201
diff changeset
   110
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   111
def display_name(req, key, form=''):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   112
    """return a internationalized string for the key (schema entity or relation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   113
    name) in a given form
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   114
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   115
    assert form in ('', 'plural', 'subject', 'object')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   116
    if form == 'subject':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   117
        form = ''
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   118
    if form:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   119
        key = key + '_' + form
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   120
    # ensure unicode
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   121
    # added .lower() in case no translation are available
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   122
    return unicode(req._(key)).lower()
2201
ddc1f58c8e8b deprecate display_name from builtin, ask for explicit import
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2157
diff changeset
   123
__builtins__['display_name'] = obsolete('display_name should be imported from cubicweb.schema')(display_name)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   124
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   125
def ERSchema_display_name(self, req, form=''):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   126
    """return a internationalized string for the entity/relation type name in
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   127
    a given form
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   128
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   129
    return display_name(req, self.type, form)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   130
ERSchema.display_name = ERSchema_display_name
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   131
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   132
@cached
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   133
def ERSchema_get_groups(self, action):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   134
    """return the groups authorized to perform <action> on entities of
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   135
    this type
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   136
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   137
    :type action: str
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   138
    :param action: the name of a permission
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   139
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   140
    :rtype: tuple
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   141
    :return: names of the groups with the given permission
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   142
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   143
    assert action in self.ACTIONS, action
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   144
    #assert action in self._groups, '%s %s' % (self, action)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   145
    try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   146
        return frozenset(g for g in self._groups[action] if isinstance(g, basestring))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   147
    except KeyError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   148
        return ()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   149
ERSchema.get_groups = ERSchema_get_groups
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   150
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   151
def ERSchema_set_groups(self, action, groups):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   152
    """set the groups allowed to perform <action> on entities of this type. Don't
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   153
    change rql expressions for the same action.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   154
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   155
    :type action: str
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   156
    :param action: the name of a permission
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   157
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   158
    :type groups: list or tuple
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   159
    :param groups: names of the groups granted to do the given action
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   160
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   161
    assert action in self.ACTIONS, action
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   162
    clear_cache(self, 'ERSchema_get_groups')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   163
    self._groups[action] = tuple(groups) + self.get_rqlexprs(action)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   164
ERSchema.set_groups = ERSchema_set_groups
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   165
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   166
@cached
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   167
def ERSchema_get_rqlexprs(self, action):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   168
    """return the rql expressions representing queries to check the user is allowed
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   169
    to perform <action> on entities of this type
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   170
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   171
    :type action: str
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   172
    :param action: the name of a permission
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   173
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   174
    :rtype: tuple
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   175
    :return: the rql expressions with the given permission
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   176
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   177
    assert action in self.ACTIONS, action
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   178
    #assert action in self._rqlexprs, '%s %s' % (self, action)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   179
    try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   180
        return tuple(g for g in self._groups[action] if not isinstance(g, basestring))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   181
    except KeyError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   182
        return ()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   183
ERSchema.get_rqlexprs = ERSchema_get_rqlexprs
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   184
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   185
def ERSchema_set_rqlexprs(self, action, rqlexprs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   186
    """set the rql expression allowing to perform <action> on entities of this type. Don't
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   187
    change groups for the same action.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   188
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   189
    :type action: str
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   190
    :param action: the name of a permission
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   191
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   192
    :type rqlexprs: list or tuple
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   193
    :param rqlexprs: the rql expressions allowing the given action
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   194
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   195
    assert action in self.ACTIONS, action
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   196
    clear_cache(self, 'ERSchema_get_rqlexprs')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   197
    self._groups[action] = tuple(self.get_groups(action)) + tuple(rqlexprs)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   198
ERSchema.set_rqlexprs = ERSchema_set_rqlexprs
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   199
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   200
def ERSchema_set_permissions(self, action, permissions):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   201
    """set the groups and rql expressions allowing to perform <action> on
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   202
    entities of this type
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   203
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   204
    :type action: str
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   205
    :param action: the name of a permission
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   206
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   207
    :type permissions: tuple
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   208
    :param permissions: the groups and rql expressions allowing the given action
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   209
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   210
    assert action in self.ACTIONS, action
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   211
    clear_cache(self, 'ERSchema_get_rqlexprs')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   212
    clear_cache(self, 'ERSchema_get_groups')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   213
    self._groups[action] = tuple(permissions)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   214
ERSchema.set_permissions = ERSchema_set_permissions
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   215
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   216
def ERSchema_has_perm(self, session, action, *args, **kwargs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   217
    """return true if the action is granted globaly or localy"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   218
    try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   219
        self.check_perm(session, action, *args, **kwargs)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   220
        return True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   221
    except Unauthorized:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   222
        return False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   223
ERSchema.has_perm = ERSchema_has_perm
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   224
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   225
def ERSchema_has_local_role(self, action):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   226
    """return true if the action *may* be granted localy (eg either rql
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   227
    expressions or the owners group are used in security definition)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   228
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   229
    XXX this method is only there since we don't know well how to deal with
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   230
    'add' action checking. Also find a better name would be nice.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   231
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   232
    assert action in self.ACTIONS, action
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   233
    if self.get_rqlexprs(action):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   234
        return True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   235
    if action in ('update', 'delete'):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   236
        return self.has_group(action, 'owners')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   237
    return False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   238
ERSchema.has_local_role = ERSchema_has_local_role
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   239
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   240
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   241
def system_etypes(schema):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   242
    """return system entity types only: skip final, schema and application entities
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   243
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   244
    for eschema in schema.entities():
2126
a25859917ccc stop using meta attribute from yams schema. Use instead sets defining meta relations and another defining schema types. Refactor various schema view based on this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   245
        if eschema.is_final() or eschema.schema_entity():
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   246
            continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   247
        yield eschema.type
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   248
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   249
# Schema objects definition ###################################################
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   250
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   251
class CubicWebEntitySchema(EntitySchema):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   252
    """a entity has a type, a set of subject and or object relations
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   253
    the entity schema defines the possible relations for a given type and some
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   254
    constraints on those relations
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   255
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   256
    def __init__(self, schema=None, edef=None, eid=None, **kwargs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   257
        super(CubicWebEntitySchema, self).__init__(schema, edef, **kwargs)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   258
        if eid is None and edef is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   259
            eid = getattr(edef, 'eid', None)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   260
        self.eid = eid
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   261
        # take care: no _groups attribute when deep-copying
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   262
        if getattr(self, '_groups', None):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   263
            for groups in self._groups.itervalues():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   264
                for group_or_rqlexpr in groups:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   265
                    if isinstance(group_or_rqlexpr, RRQLExpression):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   266
                        msg = "can't use RRQLExpression on an entity type, use an ERQLExpression (%s)"
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   267
                        raise BadSchemaDefinition(msg % self.type)
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   268
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   269
    def attribute_definitions(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   270
        """return an iterator on attribute definitions
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   271
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   272
        attribute relations are a subset of subject relations where the
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   273
        object's type is a final entity
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   274
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   275
        an attribute definition is a 2-uple :
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   276
        * name of the relation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   277
        * schema of the destination entity type
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   278
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   279
        iter = super(CubicWebEntitySchema, self).attribute_definitions()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   280
        for rschema, attrschema in iter:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   281
            if rschema.type == 'has_text':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   282
                continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   283
            yield rschema, attrschema
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   284
2128
464edb198faa drop @ wildcard in relation subject/object, override main_attribute for proper behaviour
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2126
diff changeset
   285
    def main_attribute(self):
464edb198faa drop @ wildcard in relation subject/object, override main_attribute for proper behaviour
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2126
diff changeset
   286
        """convenience method that returns the *main* (i.e. the first non meta)
464edb198faa drop @ wildcard in relation subject/object, override main_attribute for proper behaviour
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2126
diff changeset
   287
        attribute defined in the entity schema
464edb198faa drop @ wildcard in relation subject/object, override main_attribute for proper behaviour
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2126
diff changeset
   288
        """
464edb198faa drop @ wildcard in relation subject/object, override main_attribute for proper behaviour
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2126
diff changeset
   289
        for rschema, _ in self.attribute_definitions():
464edb198faa drop @ wildcard in relation subject/object, override main_attribute for proper behaviour
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2126
diff changeset
   290
            if not (rschema in META_RELATIONS_TYPES
464edb198faa drop @ wildcard in relation subject/object, override main_attribute for proper behaviour
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2126
diff changeset
   291
                    or self.is_metadata(rschema)):
464edb198faa drop @ wildcard in relation subject/object, override main_attribute for proper behaviour
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2126
diff changeset
   292
                return rschema
464edb198faa drop @ wildcard in relation subject/object, override main_attribute for proper behaviour
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2126
diff changeset
   293
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   294
    def add_subject_relation(self, rschema):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   295
        """register the relation schema as possible subject relation"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   296
        super(CubicWebEntitySchema, self).add_subject_relation(rschema)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   297
        self._update_has_text()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   298
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   299
    def del_subject_relation(self, rtype):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   300
        super(CubicWebEntitySchema, self).del_subject_relation(rtype)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   301
        self._update_has_text(False)
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   302
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   303
    def _update_has_text(self, need_has_text=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   304
        may_need_has_text, has_has_text = False, False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   305
        for rschema in self.subject_relations():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   306
            if rschema.is_final():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   307
                if rschema == 'has_text':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   308
                    has_has_text = True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   309
                elif self.rproperty(rschema, 'fulltextindexed'):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   310
                    may_need_has_text = True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   311
            elif rschema.fulltext_container:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   312
                if rschema.fulltext_container == 'subject':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   313
                    may_need_has_text = True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   314
                else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   315
                    need_has_text = False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   316
        for rschema in self.object_relations():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   317
            if rschema.fulltext_container:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   318
                if rschema.fulltext_container == 'object':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   319
                    may_need_has_text = True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   320
                else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   321
                    need_has_text = False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   322
                    break
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   323
        if need_has_text is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   324
            need_has_text = may_need_has_text
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   325
        if need_has_text and not has_has_text:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   326
            rdef = ybo.RelationDefinition(self.type, 'has_text', 'String')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   327
            self.schema.add_relation_def(rdef)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   328
        elif not need_has_text and has_has_text:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   329
            self.schema.del_relation_def(self.type, 'has_text', 'String')
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   330
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   331
    def schema_entity(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   332
        """return True if this entity type is used to build the schema"""
2126
a25859917ccc stop using meta attribute from yams schema. Use instead sets defining meta relations and another defining schema types. Refactor various schema view based on this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   333
        return self.type in SCHEMA_TYPES
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   334
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   335
    def check_perm(self, session, action, eid=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   336
        # NB: session may be a server session or a request object
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   337
        user = session.user
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   338
        # check user is in an allowed group, if so that's enough
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   339
        # internal sessions should always stop there
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   340
        if user.matching_groups(self.get_groups(action)):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   341
            return
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   342
        # if 'owners' in allowed groups, check if the user actually owns this
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   343
        # object, if so that's enough
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   344
        if eid is not None and 'owners' in self.get_groups(action) and \
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   345
               user.owns(eid):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   346
            return
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   347
        # else if there is some rql expressions, check them
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   348
        if any(rqlexpr.check(session, eid)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   349
               for rqlexpr in self.get_rqlexprs(action)):
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   350
            return
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   351
        raise Unauthorized(action, str(self))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   352
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   353
    def rql_expression(self, expression, mainvars=None, eid=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   354
        """rql expression factory"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   355
        return ERQLExpression(expression, mainvars, eid)
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   356
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   357
class CubicWebRelationSchema(RelationSchema):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   358
    RelationSchema._RPROPERTIES['eid'] = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   359
    _perms_checked = False
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   360
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   361
    def __init__(self, schema=None, rdef=None, eid=None, **kwargs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   362
        if rdef is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   363
            # if this relation is inlined
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   364
            self.inlined = rdef.inlined
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   365
        super(CubicWebRelationSchema, self).__init__(schema, rdef, **kwargs)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   366
        if eid is None and rdef is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   367
            eid = getattr(rdef, 'eid', None)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   368
        self.eid = eid
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   369
2126
a25859917ccc stop using meta attribute from yams schema. Use instead sets defining meta relations and another defining schema types. Refactor various schema view based on this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   370
    @property
a25859917ccc stop using meta attribute from yams schema. Use instead sets defining meta relations and another defining schema types. Refactor various schema view based on this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   371
    def meta(self):
a25859917ccc stop using meta attribute from yams schema. Use instead sets defining meta relations and another defining schema types. Refactor various schema view based on this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   372
        return self.type in META_RELATIONS_TYPES
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   373
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   374
    def update(self, subjschema, objschema, rdef):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   375
        super(CubicWebRelationSchema, self).update(subjschema, objschema, rdef)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   376
        if not self._perms_checked and self._groups:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   377
            for action, groups in self._groups.iteritems():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   378
                for group_or_rqlexpr in groups:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   379
                    if action == 'read' and \
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   380
                           isinstance(group_or_rqlexpr, RQLExpression):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   381
                        msg = "can't use rql expression for read permission of "\
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   382
                              "a relation type (%s)"
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   383
                        raise BadSchemaDefinition(msg % self.type)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   384
                    elif self.final and isinstance(group_or_rqlexpr, RRQLExpression):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   385
                        if self.schema.reading_from_database:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   386
                            # we didn't have final relation earlier, so turn
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   387
                            # RRQLExpression into ERQLExpression now
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   388
                            rqlexpr = group_or_rqlexpr
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   389
                            newrqlexprs = [x for x in self.get_rqlexprs(action) if not x is rqlexpr]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   390
                            newrqlexprs.append(ERQLExpression(rqlexpr.expression,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   391
                                                              rqlexpr.mainvars,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   392
                                                              rqlexpr.eid))
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   393
                            self.set_rqlexprs(action, newrqlexprs)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   394
                        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   395
                            msg = "can't use RRQLExpression on a final relation "\
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   396
                                  "type (eg attribute relation), use an ERQLExpression (%s)"
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   397
                            raise BadSchemaDefinition(msg % self.type)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   398
                    elif not self.final and \
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   399
                             isinstance(group_or_rqlexpr, ERQLExpression):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   400
                        msg = "can't use ERQLExpression on a relation type, use "\
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   401
                              "a RRQLExpression (%s)"
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   402
                        raise BadSchemaDefinition(msg % self.type)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   403
            self._perms_checked = True
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   404
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   405
    def cardinality(self, subjtype, objtype, target):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   406
        card = self.rproperty(subjtype, objtype, 'cardinality')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   407
        return (target == 'subject' and card[0]) or \
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   408
               (target == 'object' and card[1])
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   409
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   410
    def schema_relation(self):
2126
a25859917ccc stop using meta attribute from yams schema. Use instead sets defining meta relations and another defining schema types. Refactor various schema view based on this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   411
        """return True if this relation type is used to build the schema"""
a25859917ccc stop using meta attribute from yams schema. Use instead sets defining meta relations and another defining schema types. Refactor various schema view based on this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   412
        return self.type in SCHEMA_TYPES
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   413
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   414
    def physical_mode(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   415
        """return an appropriate mode for physical storage of this relation type:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   416
        * 'subjectinline' if every possible subject cardinalities are 1 or ?
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   417
        * 'objectinline' if 'subjectinline' mode is not possible but every
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   418
          possible object cardinalities are 1 or ?
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   419
        * None if neither 'subjectinline' and 'objectinline'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   420
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   421
        assert not self.final
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   422
        return self.inlined and 'subjectinline' or None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   423
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   424
    def check_perm(self, session, action, *args, **kwargs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   425
        # NB: session may be a server session or a request object check user is
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   426
        # in an allowed group, if so that's enough internal sessions should
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   427
        # always stop there
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   428
        if session.user.matching_groups(self.get_groups(action)):
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   429
            return
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   430
        # else if there is some rql expressions, check them
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   431
        if any(rqlexpr.check(session, *args, **kwargs)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   432
               for rqlexpr in self.get_rqlexprs(action)):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   433
            return
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   434
        raise Unauthorized(action, str(self))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   435
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   436
    def rql_expression(self, expression, mainvars=None, eid=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   437
        """rql expression factory"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   438
        if self.is_final():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   439
            return ERQLExpression(expression, mainvars, eid)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   440
        return RRQLExpression(expression, mainvars, eid)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   441
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   442
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   443
class CubicWebSchema(Schema):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   444
    """set of entities and relations schema defining the possible data sets
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   445
    used in an application
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   446
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   447
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   448
    :type name: str
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   449
    :ivar name: name of the schema, usually the application identifier
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   450
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   451
    :type base: str
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   452
    :ivar base: path of the directory where the schema is defined
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   453
    """
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   454
    reading_from_database = False
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   455
    entity_class = CubicWebEntitySchema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   456
    relation_class = CubicWebRelationSchema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   457
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   458
    def __init__(self, *args, **kwargs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   459
        self._eid_index = {}
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   460
        super(CubicWebSchema, self).__init__(*args, **kwargs)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   461
        ybo.register_base_types(self)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   462
        rschema = self.add_relation_type(ybo.RelationType('eid', meta=True))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   463
        rschema.final = True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   464
        rschema.set_default_groups()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   465
        rschema = self.add_relation_type(ybo.RelationType('has_text', meta=True))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   466
        rschema.final = True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   467
        rschema.set_default_groups()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   468
        rschema = self.add_relation_type(ybo.RelationType('identity', meta=True))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   469
        rschema.final = False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   470
        rschema.set_default_groups()
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   471
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   472
    def add_entity_type(self, edef):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   473
        edef.name = edef.name.encode()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   474
        edef.name = bw_normalize_etype(edef.name)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   475
        assert re.match(r'[A-Z][A-Za-z0-9]*[a-z]+[0-9]*$', edef.name), repr(edef.name)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   476
        eschema = super(CubicWebSchema, self).add_entity_type(edef)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   477
        if not eschema.is_final():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   478
            # automatically add the eid relation to non final entity types
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   479
            rdef = ybo.RelationDefinition(eschema.type, 'eid', 'Int',
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   480
                                          cardinality='11', uid=True)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   481
            self.add_relation_def(rdef)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   482
            rdef = ybo.RelationDefinition(eschema.type, 'identity', eschema.type)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   483
            self.add_relation_def(rdef)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   484
        self._eid_index[eschema.eid] = eschema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   485
        return eschema
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   486
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   487
    def add_relation_type(self, rdef):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   488
        rdef.name = rdef.name.lower().encode()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   489
        rschema = super(CubicWebSchema, self).add_relation_type(rdef)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   490
        self._eid_index[rschema.eid] = rschema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   491
        return rschema
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   492
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   493
    def add_relation_def(self, rdef):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   494
        """build a part of a relation schema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   495
        (i.e. add a relation between two specific entity's types)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   496
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   497
        :type subject: str
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   498
        :param subject: entity's type that is subject of the relation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   499
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   500
        :type rtype: str
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   501
        :param rtype: the relation's type (i.e. the name of the relation)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   502
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   503
        :type obj: str
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   504
        :param obj: entity's type that is object of the relation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   505
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   506
        :rtype: RelationSchema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   507
        :param: the newly created or just completed relation schema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   508
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   509
        rdef.name = rdef.name.lower()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   510
        rdef.subject = bw_normalize_etype(rdef.subject)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   511
        rdef.object = bw_normalize_etype(rdef.object)
1034
0356bbfb2f26 fix to pass arguments to base class
sylvain.thenault@logilab.fr
parents: 1016
diff changeset
   512
        if super(CubicWebSchema, self).add_relation_def(rdef):
0356bbfb2f26 fix to pass arguments to base class
sylvain.thenault@logilab.fr
parents: 1016
diff changeset
   513
            try:
0356bbfb2f26 fix to pass arguments to base class
sylvain.thenault@logilab.fr
parents: 1016
diff changeset
   514
                self._eid_index[rdef.eid] = (self.eschema(rdef.subject),
0356bbfb2f26 fix to pass arguments to base class
sylvain.thenault@logilab.fr
parents: 1016
diff changeset
   515
                                             self.rschema(rdef.name),
0356bbfb2f26 fix to pass arguments to base class
sylvain.thenault@logilab.fr
parents: 1016
diff changeset
   516
                                             self.eschema(rdef.object))
0356bbfb2f26 fix to pass arguments to base class
sylvain.thenault@logilab.fr
parents: 1016
diff changeset
   517
            except AttributeError:
0356bbfb2f26 fix to pass arguments to base class
sylvain.thenault@logilab.fr
parents: 1016
diff changeset
   518
                pass # not a serialized schema
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   519
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   520
    def del_relation_type(self, rtype):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   521
        rschema = self.rschema(rtype)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   522
        self._eid_index.pop(rschema.eid, None)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   523
        super(CubicWebSchema, self).del_relation_type(rtype)
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   524
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   525
    def del_relation_def(self, subjtype, rtype, objtype):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   526
        for k, v in self._eid_index.items():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   527
            if v == (subjtype, rtype, objtype):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   528
                del self._eid_index[k]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   529
        super(CubicWebSchema, self).del_relation_def(subjtype, rtype, objtype)
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   530
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   531
    def del_entity_type(self, etype):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   532
        eschema = self.eschema(etype)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   533
        self._eid_index.pop(eschema.eid, None)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   534
        # deal with has_text first, else its automatic deletion (see above)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   535
        # may trigger an error in ancestor's del_entity_type method
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   536
        if 'has_text' in eschema.subject_relations():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   537
            self.del_relation_def(etype, 'has_text', 'String')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   538
        super(CubicWebSchema, self).del_entity_type(etype)
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   539
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   540
    def schema_by_eid(self, eid):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   541
        return self._eid_index[eid]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   542
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   543
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   544
# Possible constraints ########################################################
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   545
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   546
class RQLVocabularyConstraint(BaseConstraint):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   547
    """the rql vocabulary constraint :
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   548
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   549
    limit the proposed values to a set of entities returned by a rql query,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   550
    but this is not enforced at the repository level
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   551
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   552
     restriction is additional rql restriction that will be added to
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   553
     a predefined query, where the S and O variables respectivly represent
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   554
     the subject and the object of the relation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   555
    """
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   556
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   557
    def __init__(self, restriction):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   558
        self.restriction = restriction
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   559
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   560
    def serialize(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   561
        return self.restriction
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   562
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   563
    def deserialize(cls, value):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   564
        return cls(value)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   565
    deserialize = classmethod(deserialize)
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   566
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   567
    def check(self, entity, rtype, value):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   568
        """return true if the value satisfy the constraint, else false"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   569
        # implemented as a hook in the repository
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   570
        return 1
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   571
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   572
    def repo_check(self, session, eidfrom, rtype, eidto):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   573
        """raise ValidationError if the relation doesn't satisfy the constraint
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   574
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   575
        pass # this is a vocabulary constraint, not enforce
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   576
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   577
    def __str__(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   578
        return self.restriction
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   579
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   580
    def __repr__(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   581
        return '<%s : %s>' % (self.__class__.__name__, repr(self.restriction))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   582
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   583
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   584
class RQLConstraint(RQLVocabularyConstraint):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   585
    """the rql constraint is similar to the RQLVocabularyConstraint but
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   586
    are also enforced at the repository level
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   587
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   588
    def exec_query(self, session, eidfrom, eidto):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   589
        rql = 'Any S,O WHERE S eid %(s)s, O eid %(o)s, ' + self.restriction
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   590
        return session.unsafe_execute(rql, {'s': eidfrom, 'o': eidto},
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   591
                                      ('s', 'o'), build_descr=False)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   592
    def error(self, eid, rtype, msg):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   593
        raise ValidationError(eid, {rtype: msg})
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   594
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   595
    def repo_check(self, session, eidfrom, rtype, eidto):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   596
        """raise ValidationError if the relation doesn't satisfy the constraint
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   597
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   598
        if not self.exec_query(session, eidfrom, eidto):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   599
            # XXX at this point dunno if the validation error `occured` on
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   600
            #     eidfrom or eidto (from user interface point of view)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   601
            self.error(eidfrom, rtype, 'constraint %s failed' % self)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   602
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   603
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   604
class RQLUniqueConstraint(RQLConstraint):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   605
    """the unique rql constraint check that the result of the query isn't
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   606
    greater than one
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   607
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   608
    def repo_check(self, session, eidfrom, rtype, eidto):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   609
        """raise ValidationError if the relation doesn't satisfy the constraint
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   610
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   611
        if len(self.exec_query(session, eidfrom, eidto)) > 1:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   612
            # XXX at this point dunno if the validation error `occured` on
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   613
            #     eidfrom or eidto (from user interface point of view)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   614
            self.error(eidfrom, rtype, 'unique constraint %s failed' % self)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   615
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   616
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   617
def split_expression(rqlstring):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   618
    for expr in rqlstring.split(','):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   619
        for word in expr.split():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   620
            yield word
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   621
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   622
def normalize_expression(rqlstring):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   623
    """normalize an rql expression to ease schema synchronization (avoid
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   624
    suppressing and reinserting an expression if only a space has been added/removed
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   625
    for instance)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   626
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   627
    return u', '.join(' '.join(expr.split()) for expr in rqlstring.split(','))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   628
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   629
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   630
class RQLExpression(object):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   631
    def __init__(self, expression, mainvars, eid):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   632
        self.eid = eid # eid of the entity representing this rql expression
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   633
        if not isinstance(mainvars, unicode):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   634
            mainvars = unicode(mainvars)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   635
        self.mainvars = mainvars
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   636
        self.expression = normalize_expression(expression)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   637
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   638
            self.rqlst = parse(self.full_rql, print_errors=False).children[0]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   639
        except RQLSyntaxError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   640
            raise RQLSyntaxError(expression)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   641
        for mainvar in mainvars.split(','):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   642
            if len(self.rqlst.defined_vars[mainvar].references()) <= 2:
2142
098aa2075903 include_schema_files is useless
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   643
                _LOGGER.warn('You did not use the %s variable in your RQL '
098aa2075903 include_schema_files is useless
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   644
                             'expression %s', mainvar, self)
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   645
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   646
    def __str__(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   647
        return self.full_rql
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   648
    def __repr__(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   649
        return '%s(%s)' % (self.__class__.__name__, self.full_rql)
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   650
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   651
    def __deepcopy__(self, memo):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   652
        return self.__class__(self.expression, self.mainvars)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   653
    def __getstate__(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   654
        return (self.expression, self.mainvars)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   655
    def __setstate__(self, state):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   656
        self.__init__(*state)
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   657
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   658
    @cached
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   659
    def transform_has_permission(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   660
        found = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   661
        rqlst = self.rqlst
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   662
        for var in rqlst.defined_vars.itervalues():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   663
            for varref in var.references():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   664
                rel = varref.relation()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   665
                if rel is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   666
                    continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   667
                try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   668
                    prefix, action, suffix = rel.r_type.split('_')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   669
                except ValueError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   670
                    continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   671
                if prefix != 'has' or suffix != 'permission' or \
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   672
                       not action in ('add', 'delete', 'update', 'read'):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   673
                    continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   674
                if found is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   675
                    found = []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   676
                    rqlst.save_state()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   677
                assert rel.children[0].name == 'U'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   678
                objvar = rel.children[1].children[0].variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   679
                rqlst.remove_node(rel)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   680
                selected = [v.name for v in rqlst.get_selected_variables()]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   681
                if objvar.name not in selected:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   682
                    colindex = len(selected)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   683
                    rqlst.add_selected(objvar)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   684
                else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   685
                    colindex = selected.index(objvar.name)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   686
                found.append((action, objvar, colindex))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   687
                # remove U eid %(u)s if U is not used in any other relation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   688
                uvrefs = rqlst.defined_vars['U'].references()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   689
                if len(uvrefs) == 1:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   690
                    rqlst.remove_node(uvrefs[0].relation())
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   691
        if found is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   692
            rql = rqlst.as_string()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   693
            if len(rqlst.selection) == 1 and isinstance(rqlst.where, nodes.Relation):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   694
                # only "Any X WHERE X eid %(x)s" remaining, no need to execute the rql
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   695
                keyarg = rqlst.selection[0].name.lower()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   696
            else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   697
                keyarg = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   698
            rqlst.recover()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   699
            return rql, found, keyarg
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   700
        return rqlst.as_string(), None, None
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   701
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   702
    def _check(self, session, **kwargs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   703
        """return True if the rql expression is matching the given relation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   704
        between fromeid and toeid
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   705
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   706
        session may actually be a request as well
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   707
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   708
        if self.eid is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   709
            key = (self.eid, tuple(sorted(kwargs.iteritems())))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   710
            try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   711
                return session.local_perm_cache[key]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   712
            except KeyError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   713
                pass
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   714
        rql, has_perm_defs, keyarg = self.transform_has_permission()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   715
        if keyarg is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   716
            # on the server side, use unsafe_execute, but this is not available
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   717
            # on the client side (session is actually a request)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   718
            execute = getattr(session, 'unsafe_execute', session.execute)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   719
            # XXX what if 'u' in kwargs
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   720
            cachekey = kwargs.keys()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   721
            kwargs['u'] = session.user.eid
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   722
            try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   723
                rset = execute(rql, kwargs, cachekey, build_descr=True)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   724
            except NotImplementedError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   725
                self.critical('cant check rql expression, unsupported rql %s', rql)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   726
                if self.eid is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   727
                    session.local_perm_cache[key] = False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   728
                return False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   729
            except TypeResolverException, ex:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   730
                # some expression may not be resolvable with current kwargs
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   731
                # (type conflict)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   732
                self.warning('%s: %s', rql, str(ex))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   733
                if self.eid is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   734
                    session.local_perm_cache[key] = False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   735
                return False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   736
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   737
            rset = session.eid_rset(kwargs[keyarg])
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   738
        # if no special has_*_permission relation in the rql expression, just
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   739
        # check the result set contains something
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   740
        if has_perm_defs is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   741
            if rset:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   742
                if self.eid is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   743
                    session.local_perm_cache[key] = True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   744
                return True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   745
        elif rset:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   746
            # check every special has_*_permission relation is satisfied
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   747
            get_eschema = session.vreg.schema.eschema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   748
            try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   749
                for eaction, var, col in has_perm_defs:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   750
                    for i in xrange(len(rset)):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   751
                        eschema = get_eschema(rset.description[i][col])
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   752
                        eschema.check_perm(session, eaction, rset[i][col])
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   753
                if self.eid is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   754
                    session.local_perm_cache[key] = True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   755
                return True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   756
            except Unauthorized:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   757
                pass
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   758
        if self.eid is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   759
            session.local_perm_cache[key] = False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   760
        return False
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   761
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   762
    @property
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   763
    def minimal_rql(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   764
        return 'Any %s WHERE %s' % (self.mainvars, self.expression)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   765
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   766
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   767
class ERQLExpression(RQLExpression):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   768
    def __init__(self, expression, mainvars=None, eid=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   769
        RQLExpression.__init__(self, expression, mainvars or 'X', eid)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   770
        # syntax tree used by read security (inserted in queries when necessary
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   771
        self.snippet_rqlst = parse(self.minimal_rql, print_errors=False).children[0]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   772
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   773
    @property
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   774
    def full_rql(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   775
        rql = self.minimal_rql
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   776
        rqlst = getattr(self, 'rqlst', None) # may be not set yet
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   777
        if rqlst is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   778
            defined = rqlst.defined_vars
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   779
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   780
            defined = set(split_expression(self.expression))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   781
        if 'X' in defined:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   782
            rql += ', X eid %(x)s'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   783
        if 'U' in defined:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   784
            rql += ', U eid %(u)s'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   785
        return rql
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   786
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   787
    def check(self, session, eid=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   788
        if 'X' in self.rqlst.defined_vars:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   789
            if eid is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   790
                return False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   791
            return self._check(session, x=eid)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   792
        return self._check(session)
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   793
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   794
PyFileReader.context['ERQLExpression'] = ERQLExpression
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   795
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   796
class RRQLExpression(RQLExpression):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   797
    def __init__(self, expression, mainvars=None, eid=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   798
        if mainvars is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   799
            defined = set(split_expression(expression))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   800
            mainvars = []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   801
            if 'S' in defined:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   802
                mainvars.append('S')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   803
            if 'O' in defined:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   804
                mainvars.append('O')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   805
            if not mainvars:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   806
                raise Exception('unable to guess selection variables')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   807
            mainvars = ','.join(mainvars)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   808
        RQLExpression.__init__(self, expression, mainvars, eid)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   809
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   810
    @property
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   811
    def full_rql(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   812
        rql = self.minimal_rql
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   813
        rqlst = getattr(self, 'rqlst', None) # may be not set yet
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   814
        if rqlst is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   815
            defined = rqlst.defined_vars
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   816
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   817
            defined = set(split_expression(self.expression))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   818
        if 'S' in defined:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   819
            rql += ', S eid %(s)s'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   820
        if 'O' in defined:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   821
            rql += ', O eid %(o)s'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   822
        if 'U' in defined:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   823
            rql += ', U eid %(u)s'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   824
        return rql
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   825
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   826
    def check(self, session, fromeid=None, toeid=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   827
        kwargs = {}
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   828
        if 'S' in self.rqlst.defined_vars:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   829
            if fromeid is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   830
                return False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   831
            kwargs['s'] = fromeid
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   832
        if 'O' in self.rqlst.defined_vars:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   833
            if toeid is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   834
                return False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   835
            kwargs['o'] = toeid
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   836
        return self._check(session, **kwargs)
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   837
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   838
PyFileReader.context['RRQLExpression'] = RRQLExpression
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   839
629
59b6542f5729 provide a new WorkflowableEntityType base class (will be refactored later, maybe with schema interfaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 628
diff changeset
   840
# workflow extensions #########################################################
59b6542f5729 provide a new WorkflowableEntityType base class (will be refactored later, maybe with schema interfaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 628
diff changeset
   841
59b6542f5729 provide a new WorkflowableEntityType base class (will be refactored later, maybe with schema interfaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 628
diff changeset
   842
class workflowable_definition(ybo.metadefinition):
59b6542f5729 provide a new WorkflowableEntityType base class (will be refactored later, maybe with schema interfaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 628
diff changeset
   843
    """extends default EntityType's metaclass to add workflow relations
59b6542f5729 provide a new WorkflowableEntityType base class (will be refactored later, maybe with schema interfaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 628
diff changeset
   844
    (i.e. in_state and wf_info_for).
59b6542f5729 provide a new WorkflowableEntityType base class (will be refactored later, maybe with schema interfaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 628
diff changeset
   845
    This is the default metaclass for WorkflowableEntityType
59b6542f5729 provide a new WorkflowableEntityType base class (will be refactored later, maybe with schema interfaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 628
diff changeset
   846
    """
59b6542f5729 provide a new WorkflowableEntityType base class (will be refactored later, maybe with schema interfaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 628
diff changeset
   847
    def __new__(mcs, name, bases, classdict):
59b6542f5729 provide a new WorkflowableEntityType base class (will be refactored later, maybe with schema interfaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 628
diff changeset
   848
        abstract = classdict.pop('abstract', False)
59b6542f5729 provide a new WorkflowableEntityType base class (will be refactored later, maybe with schema interfaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 628
diff changeset
   849
        defclass = super(workflowable_definition, mcs).__new__(mcs, name, bases, classdict)
59b6542f5729 provide a new WorkflowableEntityType base class (will be refactored later, maybe with schema interfaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 628
diff changeset
   850
        if not abstract:
59b6542f5729 provide a new WorkflowableEntityType base class (will be refactored later, maybe with schema interfaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 628
diff changeset
   851
            existing_rels = set(rdef.name for rdef in defclass.__relations__)
59b6542f5729 provide a new WorkflowableEntityType base class (will be refactored later, maybe with schema interfaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 628
diff changeset
   852
            if 'in_state' not in existing_rels and 'wf_info_for' not in existing_rels:
59b6542f5729 provide a new WorkflowableEntityType base class (will be refactored later, maybe with schema interfaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 628
diff changeset
   853
                in_state = ybo.SubjectRelation('State', cardinality='1*',
59b6542f5729 provide a new WorkflowableEntityType base class (will be refactored later, maybe with schema interfaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 628
diff changeset
   854
                                               # XXX automatize this
59b6542f5729 provide a new WorkflowableEntityType base class (will be refactored later, maybe with schema interfaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 628
diff changeset
   855
                                               constraints=[RQLConstraint('S is ET, O state_of ET')],
59b6542f5729 provide a new WorkflowableEntityType base class (will be refactored later, maybe with schema interfaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 628
diff changeset
   856
                                               description=_('account state'))
59b6542f5729 provide a new WorkflowableEntityType base class (will be refactored later, maybe with schema interfaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 628
diff changeset
   857
                yams_add_relation(defclass.__relations__, in_state, 'in_state')
59b6542f5729 provide a new WorkflowableEntityType base class (will be refactored later, maybe with schema interfaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 628
diff changeset
   858
                wf_info_for = ybo.ObjectRelation('TrInfo', cardinality='1*', composite='object')
59b6542f5729 provide a new WorkflowableEntityType base class (will be refactored later, maybe with schema interfaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 628
diff changeset
   859
                yams_add_relation(defclass.__relations__, wf_info_for, 'wf_info_for')
59b6542f5729 provide a new WorkflowableEntityType base class (will be refactored later, maybe with schema interfaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 628
diff changeset
   860
        return defclass
59b6542f5729 provide a new WorkflowableEntityType base class (will be refactored later, maybe with schema interfaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 628
diff changeset
   861
59b6542f5729 provide a new WorkflowableEntityType base class (will be refactored later, maybe with schema interfaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 628
diff changeset
   862
class WorkflowableEntityType(ybo.EntityType):
59b6542f5729 provide a new WorkflowableEntityType base class (will be refactored later, maybe with schema interfaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 628
diff changeset
   863
    __metaclass__ = workflowable_definition
59b6542f5729 provide a new WorkflowableEntityType base class (will be refactored later, maybe with schema interfaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 628
diff changeset
   864
    abstract = True
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   865
629
59b6542f5729 provide a new WorkflowableEntityType base class (will be refactored later, maybe with schema interfaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 628
diff changeset
   866
PyFileReader.context['WorkflowableEntityType'] = WorkflowableEntityType
59b6542f5729 provide a new WorkflowableEntityType base class (will be refactored later, maybe with schema interfaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 628
diff changeset
   867
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   868
# schema loading ##############################################################
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   869
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   870
CONSTRAINTS['RQLConstraint'] = RQLConstraint
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   871
CONSTRAINTS['RQLUniqueConstraint'] = RQLUniqueConstraint
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   872
CONSTRAINTS['RQLVocabularyConstraint'] = RQLVocabularyConstraint
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   873
PyFileReader.context.update(CONSTRAINTS)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   874
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   875
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   876
class BootstrapSchemaLoader(SchemaLoader):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   877
    """cubicweb specific schema loader, loading only schema necessary to read
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   878
    the persistent schema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   879
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   880
    schemacls = CubicWebSchema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   881
1034
0356bbfb2f26 fix to pass arguments to base class
sylvain.thenault@logilab.fr
parents: 1016
diff changeset
   882
    def load(self, config, path=(), **kwargs):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   883
        """return a Schema instance from the schema definition read
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   884
        from <directory>
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   885
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   886
        self.lib_directory = config.schemas_lib_dir()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   887
        return super(BootstrapSchemaLoader, self).load(
1034
0356bbfb2f26 fix to pass arguments to base class
sylvain.thenault@logilab.fr
parents: 1016
diff changeset
   888
            path, config.appid, register_base_types=False, **kwargs)
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   889
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   890
    def _load_definition_files(self, cubes=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   891
        # bootstraping, ignore cubes
2142
098aa2075903 include_schema_files is useless
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   892
        filepath = join(self.lib_directory, 'bootstrap.py')
098aa2075903 include_schema_files is useless
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   893
        self.info('loading %s', filepath)
098aa2075903 include_schema_files is useless
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   894
        self.handle_file(filepath)
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   895
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   896
    def unhandled_file(self, filepath):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   897
        """called when a file without handler associated has been found"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   898
        self.warning('ignoring file %r', filepath)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   899
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   900
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   901
class CubicWebSchemaLoader(BootstrapSchemaLoader):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   902
    """cubicweb specific schema loader, automatically adding metadata to the
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   903
    application's schema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   904
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   905
1034
0356bbfb2f26 fix to pass arguments to base class
sylvain.thenault@logilab.fr
parents: 1016
diff changeset
   906
    def load(self, config, **kwargs):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   907
        """return a Schema instance from the schema definition read
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   908
        from <directory>
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   909
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   910
        self.info('loading %s schemas', ', '.join(config.cubes()))
372
a8a975a88368 check apphome is not None
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 0
diff changeset
   911
        if config.apphome:
a8a975a88368 check apphome is not None
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 0
diff changeset
   912
            path = reversed([config.apphome] + config.cubes_path())
a8a975a88368 check apphome is not None
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 0
diff changeset
   913
        else:
a8a975a88368 check apphome is not None
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 0
diff changeset
   914
            path = reversed(config.cubes_path())
1034
0356bbfb2f26 fix to pass arguments to base class
sylvain.thenault@logilab.fr
parents: 1016
diff changeset
   915
        return super(CubicWebSchemaLoader, self).load(config, path=path, **kwargs)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   916
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   917
    def _load_definition_files(self, cubes):
2142
098aa2075903 include_schema_files is useless
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   918
        for filepath in (join(self.lib_directory, 'bootstrap.py'),
098aa2075903 include_schema_files is useless
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   919
                         join(self.lib_directory, 'base.py'),
098aa2075903 include_schema_files is useless
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   920
                         join(self.lib_directory, 'workflow.py'),
098aa2075903 include_schema_files is useless
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   921
                         join(self.lib_directory, 'Bookmark.py')):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   922
            self.info('loading %s', filepath)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   923
            self.handle_file(filepath)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   924
        for cube in cubes:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   925
            for filepath in self.get_schema_files(cube):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   926
                self.info('loading %s', filepath)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   927
                self.handle_file(filepath)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   928
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   929
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   930
# _() is just there to add messages to the catalog, don't care about actual
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   931
# translation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   932
PERM_USE_TEMPLATE_FORMAT = _('use_template_format')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   933
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   934
class FormatConstraint(StaticVocabularyConstraint):
715
83228d379cbe do it the other way
sylvain.thenault@logilab.fr
parents: 705
diff changeset
   935
    need_perm_formats = [_('text/cubicweb-page-template')]
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   936
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   937
    regular_formats = (_('text/rest'),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   938
                       _('text/html'),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   939
                       _('text/plain'),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   940
                       )
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   941
    def __init__(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   942
        pass
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   943
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   944
    def serialize(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   945
        """called to make persistent valuable data of a constraint"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   946
        return None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   947
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   948
    @classmethod
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   949
    def deserialize(cls, value):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   950
        """called to restore serialized data of a constraint. Should return
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   951
        a `cls` instance
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   952
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   953
        return cls()
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   954
1045
5040a5835e4d accept req as parameter for convenience
sylvain.thenault@logilab.fr
parents: 1034
diff changeset
   955
    def vocabulary(self, entity=None, req=None):
5040a5835e4d accept req as parameter for convenience
sylvain.thenault@logilab.fr
parents: 1034
diff changeset
   956
        if req is None and entity is not None:
5040a5835e4d accept req as parameter for convenience
sylvain.thenault@logilab.fr
parents: 1034
diff changeset
   957
            req = entity.req
5040a5835e4d accept req as parameter for convenience
sylvain.thenault@logilab.fr
parents: 1034
diff changeset
   958
        if req is not None and req.user.has_permission(PERM_USE_TEMPLATE_FORMAT):
745
sylvain.thenault@logilab.fr
parents: 715
diff changeset
   959
            return self.regular_formats + tuple(self.need_perm_formats)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   960
        return self.regular_formats
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   961
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   962
    def __str__(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   963
        return 'value in (%s)' % u', '.join(repr(unicode(word)) for word in self.vocabulary())
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   964
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   965
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   966
format_constraint = FormatConstraint()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   967
CONSTRAINTS['FormatConstraint'] = FormatConstraint
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   968
PyFileReader.context['format_constraint'] = format_constraint
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   969
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   970
set_log_methods(CubicWebSchemaLoader, getLogger('cubicweb.schemaloader'))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   971
set_log_methods(BootstrapSchemaLoader, getLogger('cubicweb.bootstrapschemaloader'))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   972
set_log_methods(RQLExpression, getLogger('cubicweb.schema'))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   973
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   974
# XXX monkey patch PyFileReader.import_erschema until bw_normalize_etype is
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   975
# necessary
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   976
orig_import_erschema = PyFileReader.import_erschema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   977
def bw_import_erschema(self, ertype, schemamod=None, instantiate=True):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   978
    return orig_import_erschema(self, bw_normalize_etype(ertype), schemamod, instantiate)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   979
PyFileReader.import_erschema = bw_import_erschema
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   980
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   981
# XXX itou for some Statement methods
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   982
from rql import stmts
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   983
orig_get_etype = stmts.ScopeNode.get_etype
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   984
def bw_get_etype(self, name):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   985
    return orig_get_etype(self, bw_normalize_etype(name))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   986
stmts.ScopeNode.get_etype = bw_get_etype
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   987
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   988
orig_add_main_variable_delete = stmts.Delete.add_main_variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   989
def bw_add_main_variable_delete(self, etype, vref):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   990
    return orig_add_main_variable_delete(self, bw_normalize_etype(etype), vref)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   991
stmts.Delete.add_main_variable = bw_add_main_variable_delete
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   992
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   993
orig_add_main_variable_insert = stmts.Insert.add_main_variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   994
def bw_add_main_variable_insert(self, etype, vref):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   995
    return orig_add_main_variable_insert(self, bw_normalize_etype(etype), vref)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   996
stmts.Insert.add_main_variable = bw_add_main_variable_insert
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   997
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   998
orig_set_statement_type = stmts.Select.set_statement_type
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   999
def bw_set_statement_type(self, etype):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1000
    return orig_set_statement_type(self, bw_normalize_etype(etype))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1001
stmts.Select.set_statement_type = bw_set_statement_type