doc/book/en/development/datamodel/definition.rst
branchstable
changeset 5145 bfa4d775219f
parent 4936 a4b772a0d801
child 5220 42f854b6083d
equal deleted inserted replaced
5144:5a09bea07302 5145:bfa4d775219f
     9 in cubes. The schema for a cube is defined in a :file:schema.py file or in
     9 in cubes. The schema for a cube is defined in a :file:schema.py file or in
    10 one or more Python files under the :file:`schema` directory (python package).
    10 one or more Python files under the :file:`schema` directory (python package).
    11 
    11 
    12 At this point, it is important to make clear the difference between
    12 At this point, it is important to make clear the difference between
    13 *relation type* and *relation definition*: a *relation type* is only a relation
    13 *relation type* and *relation definition*: a *relation type* is only a relation
    14 name with potentially other additionnal properties (see below), whereas a
    14 name with potentially other additional properties (see below), whereas a
    15 *relation definition* is a complete triplet
    15 *relation definition* is a complete triplet
    16 "<subject entity type> <relation type> <object entity type>".
    16 "<subject entity type> <relation type> <object entity type>".
    17 A relation type could have been implied if none is related to a
    17 
    18 relation definition of the schema.
    18 Also, it should be clear that to properly handle data migration, an
    19 
    19 instance's schema
    20 Also, it should be clear that to properly handle data migration, an instance'schema
    20 is stored in the database, so the python schema file used to defined it is only read
    21 is stored in the database, so the python schema file used to defined it are only readen
       
    22 when the instance is created or upgraded.
    21 when the instance is created or upgraded.
    23 
    22 
    24 The following built-in types are available : `String`, `Int`, `Float`,
    23 The following built-in types are available: `String`, `Int`, `Float`,
    25 `Decimal`, `Boolean`, `Date`, `Datetime`, `Time`, `Interval`, `Byte`
    24 `Decimal`, `Boolean`, `Date`, `Datetime`, `Time`, `Interval`, `Byte`
    26 and `Password`.
    25 and `Password`.
    27 
    26 
    28 You'll also have access to :ref:`base cubicweb entity types <CWBaseEntityTypes>`.
    27 You'll also have access to :ref:`base CubicWeb entity types <CWBaseEntityTypes>`.
    29 
    28 
    30 The instance schema is accessible through the .schema attribute of the
    29 The instance schema is accessible through the .schema attribute of the
    31 `vregistry`.  It's an instance of :class:`cubicweb.schema.Schema`, which
    30 `vregistry`.  It's an instance of :class:`cubicweb.schema.Schema`, which
    32 extends :class:`yams.schema.Schema`.
    31 extends :class:`yams.schema.Schema`.
    33 
    32 
    34 :note:
    33 :note:
    35   In previous yams versions, almost all classes where available without
    34   In previous yams versions, almost all classes where available without
    36   any import, but the should now be explicitely imported.
    35   any import, but the should now be explicitly imported.
    37 
    36 
    38 
    37 
    39 Entity type
    38 Entity type
    40 ~~~~~~~~~~~
    39 ~~~~~~~~~~~
    41 It's an instance of :class:`yams.schema.EntitySchema`. Each entity types has
    40 An entity type is an instance of :class:`yams.schema.EntitySchema`. Each entity type has
    42 a set of attributes and relation and some permissions, defining who can add, read,
    41 a set of attributes and relations, and some permissions which define who can add, read,
    43 update or delete entities of this type.
    42 update or delete entities of this type.
    44 
    43 
    45 XXX yams inheritance
    44 XXX yams inheritance
    46 
    45 
    47 Relation type
    46 Relation type
    48 ~~~~~~~~~~~~~
    47 ~~~~~~~~~~~~~
    49 It's an instance of :class:`yams.schema.RelationSchema`. A relation type is simply
    48 A relation type is an instance of :class:`yams.schema.RelationSchema`. A relation type is simply
    50 a semantic definition of a kind of relationship that may occurs in your application.
    49 a semantic definition of a kind of relationship that may occur in an application.
    51 
    50 
    52 It's important to choose a good name, at least to avoid conflicts with some semantically
    51 It is important to choose a good name, at least to avoid conflicts with some semantically
    53 different relation defined in other cubes (since we've no namespace yet).
    52 different relation defined in other cubes (since we've no name space yet).
    54 
    53 
    55 A relation type hold the following properties (which are hence shared between all
    54 A relation type holds the following properties (which are hence shared between all
    56 relation definitions of that type):
    55 relation definitions of that type):
    57 
    56 
    58 * `inlined` : boolean handling the physical optimization for archiving
    57 * `inlined`: boolean handling the physical optimization for archiving
    59   the relation in the subject entity table, instead of creating a specific
    58   the relation in the subject entity table, instead of creating a specific
    60   table for the relation. This applies to relations where cardinality
    59   table for the relation. This applies to relations where cardinality
    61   of subject->relation->object is 0..1 (`?`) or 1..1 (`1`) for *all* its relation
    60   of subject->relation->object is 0..1 (`?`) or 1..1 (`1`) for *all* its relation
    62   definitions.
    61   definitions.
    63 
    62 
    64 * `symmetric` : boolean indicating that the relation is symmetrical, which
    63 * `symmetric`: boolean indicating that the relation is symmetrical, which
    65   means that `X relation Y` implies `Y relation X`.
    64   means that `X relation Y` implies `Y relation X`.
    66 
    65 
    67 
    66 
    68 Relation definition
    67 Relation definition
    69 ~~~~~~~~~~~~~~~~~~~
    68 ~~~~~~~~~~~~~~~~~~~
    70 It's an instance of :class:`yams.schema.RelationDefinition`. It is a complete triplet
    69 A relation definition is an instance of :class:`yams.schema.RelationDefinition`. It is a complete triplet
    71 "<subject entity type> <relation type> <object entity type>".
    70 "<subject entity type> <relation type> <object entity type>".
       
    71 
       
    72 When creating a new instance of that class, the corresponding
       
    73 :class:`RelationType` instance is created on the fly if necessary.
       
    74 
    72 
    75 
    73 Properties
    76 Properties
    74 ``````````
    77 ``````````
    75 
    78 
    76 * Optional properties for attributes and relations :
    79 * Optional properties for attributes and relations:
    77 
    80 
    78   - `description` : a string describing an attribute or a relation. By default
    81   - `description`: a string describing an attribute or a relation. By default
    79     this string will be used in the editing form of the entity, which means
    82     this string will be used in the editing form of the entity, which means
    80     that it is supposed to help the end-user and should be flagged by the
    83     that it is supposed to help the end-user and should be flagged by the
    81     function `_` to be properly internationalized.
    84     function `_` to be properly internationalized.
    82 
    85 
    83   - `constraints` : a list of conditions/constraints that the relation has to
    86   - `constraints`: a list of conditions/constraints that the relation has to
    84     satisfy (c.f. `Constraints`_)
    87     satisfy (c.f. `Constraints`_)
    85 
    88 
    86   - `cardinality` : a two character string which specify the cardinality of the
    89   - `cardinality`: a two character string specifying the cardinality of the
    87     relation. The first character defines the cardinality of the relation on
    90     relation. The first character defines the cardinality of the relation on
    88     the subject, and the second on the object. When a relation can have
    91     the subject, and the second on the object. When a relation can have
    89     multiple subjects or objects, the cardinality applies to all,
    92     multiple subjects or objects, the cardinality applies to all,
    90     not on a one-to-one basis (so it must be consistent...). The possible
    93     not on a one-to-one basis (so it must be consistent...). The possible
    91     values are inspired from regular expression syntax :
    94     values are inspired from regular expression syntax:
    92 
    95 
    93     * `1`: 1..1
    96     * `1`: 1..1
    94     * `?`: 0..1
    97     * `?`: 0..1
    95     * `+`: 1..n
    98     * `+`: 1..n
    96     * `*`: 0..n
    99     * `*`: 0..n
    97 
   100 
    98 * optional properties for attributes :
   101 * optional properties for attributes:
    99 
   102 
   100   - `unique` : boolean indicating if the value of the attribute has to be unique
   103   - `unique`: boolean indicating if the value of the attribute has to be unique
   101     or not within all entities of the same type (false by default)
   104     or not within all entities of the same type (false by default)
   102 
   105 
   103   - `indexed` : boolean indicating if an index needs to be created for this
   106   - `indexed`: boolean indicating if an index needs to be created for this
   104     attribute in the database (false by default). This is useful only if
   107     attribute in the database (false by default). This is useful only if
   105     you know that you will have to run numerous searches on the value of this
   108     you know that you will have to run numerous searches on the value of this
   106     attribute.
   109     attribute.
   107 
   110 
   108   - `default` : default value of the attribute. In case of date types, the values
   111   - `default`: default value of the attribute. In case of date types, the values
   109     which could be used correspond to the RQL keywords `TODAY` and `NOW`.
   112     which could be used correspond to the RQL keywords `TODAY` and `NOW`.
   110 
   113 
   111 * optional properties of type `String` :
   114 * optional properties for type `String` attributes:
   112 
   115 
   113   - `fulltextindexed` : boolean indicating if the attribute is part of
   116   - `fulltextindexed`: boolean indicating if the attribute is part of
   114     the full text index (false by default) (*applicable on the type `Byte`
   117     the full text index (false by default) (*applicable on the type `Byte`
   115     as well*)
   118     as well*)
   116 
   119 
   117   - `internationalizable` : boolean indicating if the value of the attribute
   120   - `internationalizable`: boolean indicating if the value of the attribute
   118     is internationalizable (false by default)
   121     is internationalizable (false by default)
   119 
   122 
   120 * optional properties for relations :
   123 * optional properties for relations:
   121 
   124 
   122   - `composite` : string indicating that the subject (composite == 'subject')
   125   - `composite`: string indicating that the subject (composite == 'subject')
   123     is composed of the objects of the relations. For the opposite case (when
   126     is composed of the objects of the relations. For the opposite case (when
   124     the object is composed of the subjects of the relation), we just set
   127     the object is composed of the subjects of the relation), we just set
   125     'object' as value. The composition implies that when the relation
   128     'object' as value. The composition implies that when the relation
   126     is deleted (so when the composite is deleted, at least), the composed are also deleted.
   129     is deleted (so when the composite is deleted, at least), the composed are also deleted.
   127 
   130 
   128   - `fti_container`: XXX feed me
   131   - `fulltext_container`: string indicating if the value if the full text
       
   132     indexation of the entity on one end of the relation should be used
       
   133     to find the entity on the other end. The possible values are
       
   134     'subject' or 'object'. For instance the use_email relation has
       
   135     that property set to 'subject', since when performing a full text
       
   136     search people want to find the entity using an email address, and not
       
   137     the entity representing the email address.
   129 
   138 
   130 Constraints
   139 Constraints
   131 ```````````
   140 ```````````
   132 
   141 
   133 By default, the available constraint types are :
   142 By default, the available constraint types are:
   134 
   143 
   135 General Constraints
   144 General Constraints
   136 ......................
   145 ......................
   137 
   146 
   138 * `SizeConstraint` : allows to specify a minimum and/or maximum size on
   147 * `SizeConstraint`: allows to specify a minimum and/or maximum size on
   139   string (generic case of `maxsize`)
   148   string (generic case of `maxsize`)
   140 
   149 
   141 * `BoundConstraint` : allows to specify a minimum and/or maximum value on
   150 * `BoundConstraint`: allows to specify a minimum and/or maximum value on
   142   numeric types
   151   numeric types
   143 
   152 
   144 * `UniqueConstraint` : identical to "unique=True"
   153 * `UniqueConstraint`: identical to "unique=True"
   145 
   154 
   146 * `StaticVocabularyConstraint` : identical to "vocabulary=(...)"
   155 * `StaticVocabularyConstraint`: identical to "vocabulary=(...)"
   147 
   156 
   148 XXX Attribute, TODAY, NOW
   157 XXX Attribute, TODAY, NOW
   149 
   158 
   150 RQL Based Constraints
   159 RQL Based Constraints
   151 ......................
   160 ......................
   157 specified using ``mainvars``. The argument expects a single string with all
   166 specified using ``mainvars``. The argument expects a single string with all
   158 variable's name separated by spaces. The last one, ``msg``, is the error message
   167 variable's name separated by spaces. The last one, ``msg``, is the error message
   159 displayed when the constraint fails. As RQLVocabularyConstraint never fails the
   168 displayed when the constraint fails. As RQLVocabularyConstraint never fails the
   160 third argument is not available.
   169 third argument is not available.
   161 
   170 
   162 * `RQLConstraint` : allows to specify a RQL query that has to be satisfied
   171 * `RQLConstraint`: allows to specify a RQL query that has to be satisfied
   163   by the subject and/or the object of relation. In this query the variables
   172   by the subject and/or the object of relation. In this query the variables
   164   `S` and `O` are reserved for the entities subject and object of the
   173   `S` and `O` are reserved for the relation subject and object entities.
   165   relation.
   174 
   166 
   175 * `RQLVocabularyConstraint`: similar to the previous type of constraint except
   167 * `RQLVocabularyConstraint` : similar to the previous type of constraint except
       
   168   that it does not express a "strong" constraint, which means it is only used to
   176   that it does not express a "strong" constraint, which means it is only used to
   169   restrict the values listed in the drop-down menu of editing form, but it does
   177   restrict the values listed in the drop-down menu of editing form, but it does
   170   not prevent another entity to be selected.
   178   not prevent another entity to be selected.
   171 
   179 
   172 * `RQLUniqueConstraint` : allows to the specify a RQL query that ensure that an
   180 * `RQLUniqueConstraint`: allows to the specify a RQL query that ensure that an
   173   attribute is unique in a specific context. The Query must **never** return more
   181   attribute is unique in a specific context. The Query must **never** return more
   174   than a single result to be satisfied. In this query the variables `S` is
   182   than a single result to be satisfied. In this query the variables `S` is
   175   reserved for the entity subject of the relation. The other variable should be
   183   reserved for the relation subject entity. The other variables should be
   176   specified with the second constructor argument (mainvars). This constraints
   184   specified with the second constructor argument (mainvars). This constraints
   177   should be used when UniqueConstraint doesn't fit. Here is a simple example ::
   185   should be used when UniqueConstraint doesn't fit. Here is a simple example ::
   178 
   186 
   179     # Check that in the same Workflow each state's name is unique.  Using
   187     # Check that in the same Workflow each state's name is unique.  Using
   180     # UniqueConstraint (or unique=True) here would prevent states in different
   188     # UniqueConstraint (or unique=True) here would prevent states in different
   186                         mainvars='Y',
   194                         mainvars='Y',
   187                         msg=_('workflow already have a state of that name'))
   195                         msg=_('workflow already have a state of that name'))
   188 
   196 
   189 
   197 
   190 
   198 
   191 * `RQLUniqueConstraint` : allows to the specify a RQL query that ensure that an
       
   192   attribute is unique in a specific context. The Query must **never** return more
       
   193   than a single result to be satisfied. In this query the variables `S` is
       
   194   reserved for the entity subject of the relation. The other variable should be
       
   195   specified with the second constructor argument (mainvars). This constraints
       
   196   should be used when UniqueConstraint doesn't fit. Here is a simple example ::
       
   197 
       
   198     # Check that in the same Workflow each state's name is unique.  Using
       
   199     # UniqueConstraint (or unique=True) here would prevent states in different
       
   200     # workflows to have the same name.
       
   201 
       
   202     # With: State S, Workflow W, String N ; S state_of W, S name N
       
   203 
       
   204     RQLUniqueConstraint('S name N, S state_of WF, Y state_of WF, Y name N',
       
   205                         mainvars='Y',
       
   206                         msg=_('workflow already have a state of that name'))
       
   207 
       
   208 
       
   209 
       
   210 XXX note about how to add new constraint
   199 XXX note about how to add new constraint
   211 
   200 
   212 .. _securitymodel:
   201 .. _securitymodel:
   213 
   202 
   214 
   203 
   215 The security model
   204 The security model
   216 ~~~~~~~~~~~~~~~~~~
   205 ~~~~~~~~~~~~~~~~~~
   217 
   206 
   218 The security model of `cubicWeb` is based on `Access Control List`.
   207 The security model of `CubicWeb` is based on `Access Control List`.
   219 The main principles are:
   208 The main principles are:
   220 
   209 
   221 * users and groups of users
   210 * users and groups of users
   222 * a user belongs to at least one group of user
   211 * a user belongs to at least one group of user
   223 * permissions (read, update, create, delete)
   212 * permissions (read, update, create, delete)
   224 * permissions are assigned to groups (and not to users)
   213 * permissions are assigned to groups (and not to users)
   225 
   214 
   226 For *CubicWeb* in particular:
   215 For *CubicWeb* in particular:
   227 
   216 
   228 * we associate rights at the enttities/relations schema level
   217 * we associate rights at the entities/relations schema level
   229 * for each entity, we distinguish four kind of permissions: read,
   218 * for each entity, we distinguish four kinds of permissions: `read`,
   230   add, update and delete
   219   `add`, `update` and `delete`
   231 * for each relation, we distinguish three kinds of permissions: read,
   220 * for each relation, we distinguish three kinds of permissions: `read`,
   232   add and delete (we can not modify a relation)
   221   `add` and `delete` (it is not possible to `modify` a relation)
   233 * the basic groups are: Administrators, Users and Guests
   222 * the default groups are: `administrators`, `users` and `guests`
   234 * by default, users belong to the group Users
   223 * by default, users belong to the `users` group
   235 * there is a virtual group called `Owners` to which we
   224 * there is a virtual group called `owners` to which we
   236   can associate only deletion and update permissions
   225   can associate only `delete` and `update` permissions
   237 * we can not add users to the `Owners` group, they are
   226 
   238   implicitly added to it according to the context of the objects
   227   * we can not add users to the `Owners` group, they are
   239   they own
   228     implicitly added to it according to the context of the objects
   240 * the permissions of this group are only checked on update/deletion
   229     they own
   241   actions if all the other groups the user belongs to does not provide
   230   * the permissions of this group are only checked on `update`/`delete`
   242   those permissions
   231     actions if all the other groups the user belongs to do not provide
       
   232     those permissions
   243 
   233 
   244 Setting permissions is done with the attribute `__permissions__` of entities and
   234 Setting permissions is done with the attribute `__permissions__` of entities and
   245 relation types. It defines a dictionary where the keys are the access types
   235 relation types. The value of this attribute is a dictionary where the keys are the access types
   246 (action), and the values are the authorized groups or expressions.
   236 (action), and the values are the authorized groups or expressions.
   247 
   237 
   248 For an entity type, the possible actions are `read`, `add`, `update` and
   238 For an entity type, the possible actions are `read`, `add`, `update` and
   249 `delete`.
   239 `delete`.
   250 
   240 
   251 For a relation type, the possible actions are `read`, `add`, and `delete`.
   241 For a relation type, the possible actions are `read`, `add`, and `delete`.
   252 
   242 
   253 For each access type, a tuple indicates the name of the authorized groups and/or
   243 For each access type, a tuple indicates the name of the authorized groups and/or
   254 one or multiple RQL expressions to satisfy to grant access. The access is
   244 one or multiple RQL expressions to satisfy to grant access. The access is
   255 provided if the user is in one of the listed groups or one of if the RQL condition
   245 provided if the user is in one of the listed groups or if one of the RQL condition
   256 is satisfied.
   246 is satisfied.
   257 
   247 
   258 The standard user groups
   248 The standard user groups
   259 ````````````````````````
   249 ````````````````````````
   260 
   250 
   262 
   252 
   263 * `users`
   253 * `users`
   264 
   254 
   265 * `managers`
   255 * `managers`
   266 
   256 
   267 * `owners` : virtual group corresponding to the entity's owner.
   257 * `owners`: virtual group corresponding to the entity's owner.
   268   This can only be used for the actions `update` and `delete` of an entity
   258   This can only be used for the actions `update` and `delete` of an entity
   269   type.
   259   type.
   270 
   260 
   271 It is also possible to use specific groups if they are defined in the
   261 It is also possible to use specific groups if they are defined in the
   272 precreate of the cube (``migration/precreate.py``). Defining groups in
   262 precreate script of the cube (``migration/precreate.py``). Defining groups in
   273 postcreate or even later makes them NOT available for security
   263 postcreate script or later makes them unavailable for security
   274 purposes (in this case, an `sync_schema_props_perms` command have to
   264 purposes (in this case, an `sync_schema_props_perms` command has to
   275 be issued in a CubicWeb shell).
   265 be issued in a CubicWeb shell).
   276 
   266 
   277 
   267 
   278 Use of RQL expression for write permissions
   268 Use of RQL expression for write permissions
   279 ```````````````````````````````````````````
   269 ```````````````````````````````````````````
   280 It is possible to define RQL expression to provide update permission
   270 It is possible to define RQL expression to provide update permission
   281 (`add`, `delete` and `update`) on relation and entity types.
   271 (`add`, `delete` and `update`) on relation and entity types.
   282 
   272 
   283 RQL expression for entity type permission :
   273 RQL expression for entity type permission:
   284 
   274 
   285 * you have to use the class `ERQLExpression`
   275 * you have to use the class `ERQLExpression`
   286 
   276 
   287 * the used expression corresponds to the WHERE statement of an RQL query
   277 * the used expression corresponds to the WHERE statement of an RQL query
   288 
   278 
   289 * in this expression, the variables X and U are pre-defined references
   279 * in this expression, the variables `X` and `U` are pre-defined references
   290   respectively on the current entity (on which the action is verified) and
   280   respectively on the current entity (on which the action is verified) and
   291   on the user who send the request
   281   on the user who send the request
   292 
   282 
   293 * it is possible to use, in this expression, a special relation
   283 * it is possible to use, in this expression, a special relation
   294   "has_<ACTION>_permission" where the subject is the user and the
   284   "has_<ACTION>_permission" where the subject is the user and the
   295   object is any variable, meaning that the user needs to have
   285   object is any variable, meaning that the user needs to have
   296   permission to execute the action <ACTION> on the entities related
   286   permission to execute the action <ACTION> on the entities related
   297   to this variable
   287   to this variable
   298 
   288 
   299 For RQL expressions on a relation type, the principles are the same except
   289 For RQL expressions on a relation type, the principles are the same except
   300 for the following :
   290 for the following:
   301 
   291 
   302 * you have to use the class `RRQLExpression` in the case of a non-final relation
   292 * you have to use the class `RRQLExpression` in the case of a non-final relation
   303 
   293 
   304 * in the expression, the variables S, O and U are pre-defined references
   294 * in the expression, the variables `S`, `O` and `U` are pre-defined references
   305   to respectively the subject and the object of the current relation (on
   295   to respectively the subject and the object of the current relation (on
   306   which the action is being verified) and the user who executed the query
   296   which the action is being verified) and the user who executed the query
   307 
   297 
   308 * we can also define rights over attributes of an entity (non-final relation),
   298 * we can also define rights over attributes of an entity (non-final relation),
   309   knowing that :
   299   knowing that:
   310 
   300 
   311   - to define RQL expression, we have to use the class `ERQLExpression`
   301   - to define RQL expression, we have to use the class `ERQLExpression`
   312     in which X represents the entity the attribute belongs to
   302     in which `X` represents the entity the attribute belongs to
   313 
   303 
   314   - the permissions `add` and `delete` are equivalent. Only `add`/`read`
   304   - the permissions `add` and `delete` are equivalent. Only `add`/`read`
   315     are actually taken in consideration.
   305     are actually taken in consideration.
   316 
   306 
   317 :Note on the use of RQL expression for `add` permission:
   307 :Note on the use of RQL expression for `add` permission:
   331 
   321 
   332 
   322 
   333 Use of RQL expression for reading rights
   323 Use of RQL expression for reading rights
   334 ````````````````````````````````````````
   324 ````````````````````````````````````````
   335 
   325 
   336 The principles are the same but with the following restrictions :
   326 The principles are the same but with the following restrictions:
   337 
   327 
   338 * we can not use `RRQLExpression` on relation types for reading
   328 * we can not use `RRQLExpression` on relation types for reading
   339 
   329 
   340 * special relations "has_<ACTION>_permission" can not be used
   330 * special relations "has_<ACTION>_permission" can not be used
   341 
   331 
   346 -------------------------------
   336 -------------------------------
   347 
   337 
   348 Entity type definition
   338 Entity type definition
   349 ~~~~~~~~~~~~~~~~~~~~~~
   339 ~~~~~~~~~~~~~~~~~~~~~~
   350 
   340 
   351 An entity type is defined by a Python class which inherits from `EntityType`.
   341 An entity type is defined by a Python class which inherits from
   352 The class definition contains the description of attributes and relations
   342 :class:`yams.buildobjs.EntityType`.  The class definition contains the
   353 for the defined entity type.
   343 description of attributes and relations for the defined entity type.
   354 The class name corresponds to the entity type name. It is exepected to be
   344 The class name corresponds to the entity type name. It is expected to
   355 defined in the module ``mycube.schema``.
   345 be defined in the module ``mycube.schema``.
       
   346 
       
   347 :Note on schema definition:
       
   348 
       
   349  The code in ``mycube.schema`` is not meant to be executed. The class
       
   350  EntityType mentioned above is different from the EntitySchema class
       
   351  described in the previous chapter. EntityType is a helper class to
       
   352  make Entity definition easier. Yams will process EntityType classes
       
   353  and create EntitySchema instances from these class definitions. Similar
       
   354  manipulation happen for relations.
   356 
   355 
   357 When defining a schema using python files, you may use the following shortcuts:
   356 When defining a schema using python files, you may use the following shortcuts:
   358 
   357 
   359 - `required` : boolean indicating if the attribute is required, eg subject cardinality is '1'
   358 - `required`: boolean indicating if the attribute is required, ed subject cardinality is '1'
   360 
   359 
   361 - `vocabulary` : specify static possible values of an attribute
   360 - `vocabulary`: specify static possible values of an attribute
   362 
   361 
   363 - `maxsize` : integer providing the maximum size of a string (no limit by default)
   362 - `maxsize`: integer providing the maximum size of a string (no limit by default)
   364 
   363 
   365 For example:
   364 For example:
   366 
   365 
   367 .. sourcecode:: python
   366 .. sourcecode:: python
   368 
   367 
   380 The entity described above defines three attributes of type String,
   379 The entity described above defines three attributes of type String,
   381 last_name, first_name and title, an attribute of type Date for the date of
   380 last_name, first_name and title, an attribute of type Date for the date of
   382 birth and a relation that connects a `Person` to another entity of type
   381 birth and a relation that connects a `Person` to another entity of type
   383 `Company` through the semantic `works_for`.
   382 `Company` through the semantic `works_for`.
   384 
   383 
       
   384 :Naming convention:
       
   385 
       
   386  Entity class names must start with an uppercase letter. The common
       
   387  usage is to use ``CamelCase`` names.
       
   388 
       
   389  Attribute and relation names must start with a lowercase letter. The
       
   390  common usage is to use ``underscore_separated_words``. Attribute and
       
   391  relation names starting with a single underscore are permitted, to
       
   392  denote a somewhat "protected" or "private" attribute.
       
   393 
       
   394  In any case, identifiers starting with "CW" or "cw" are reserved for
       
   395  internal use by the framework.
       
   396 
       
   397 
   385 The name of the Python attribute corresponds to the name of the attribute
   398 The name of the Python attribute corresponds to the name of the attribute
   386 or the relation in *CubicWeb* application.
   399 or the relation in *CubicWeb* application.
   387 
   400 
   388 An attribute is defined in the schema as follows::
   401 An attribute is defined in the schema as follows::
   389 
   402 
   390     attr_name = attr_type(properties)
   403     attr_name = attr_type(properties)
   391 
   404 
   392 where `attr_type` is one of the type listed above and `properties` is
   405 where `attr_type` is one of the type listed above and `properties` is
   393 a list of the attribute needs to statisfy (see `Properties`_
   406 a list of the attribute needs to satisfy (see `Properties`_
   394 for more details).
   407 for more details).
   395 
       
   396 
       
   397 * relations can be defined by using `ObjectRelation` or `SubjectRelation`.
       
   398   The first argument of `SubjectRelation` or `ObjectRelation` gives respectively
       
   399   the object/subject entity type of the relation. This could be :
       
   400 
       
   401   * a string corresponding to an entity type
       
   402 
       
   403   * a tuple of string corresponding to multiple entity types
       
   404 
       
   405   * special string such as follows :
       
   406 
       
   407     - "**" : all types of entities
       
   408     - "*" : all types of non-meta entities
       
   409     - "@" : all types of meta entities but not system entities (e.g. used for
       
   410       the basic schema description)
       
   411 
   408 
   412 * it is possible to use the attribute `meta` to flag an entity type as a `meta`
   409 * it is possible to use the attribute `meta` to flag an entity type as a `meta`
   413   (e.g. used to describe/categorize other entities)
   410   (e.g. used to describe/categorize other entities)
   414 
   411 
   415 *Note* : if you end up with an `if` in the definition of your entity, this probably
   412 .. XXX the paragraph below needs clarification and / or moving out in
       
   413 .. another place
       
   414 
       
   415 *Note*: if you end up with an `if` in the definition of your entity, this probably
   416 means that you need two separate entities that implement the `ITree` interface and
   416 means that you need two separate entities that implement the `ITree` interface and
   417 get the result from `.children()` which ever entity is concerned.
   417 get the result from `.children()` which ever entity is concerned.
   418 
   418 
   419 Inheritance
   419 Inheritance
   420 ```````````
   420 ```````````
   438     inlined = True
   438     inlined = True
   439     cardinality = '?*'
   439     cardinality = '?*'
   440     subject = '*'
   440     subject = '*'
   441     object = 'CWUser'
   441     object = 'CWUser'
   442 
   442 
   443 In the case of simultaneous relations definitions, `subject` and `object`
   443 If provided, the `subject` and `object` attributes denote the subject
   444 can both be equal to the value of the first argument of `SubjectRelation`
   444 and object of the various relation definitions related to the relation
   445 and `ObjectRelation`.
   445 type. Allowed values for these attributes are:
       
   446 
       
   447 * a string corresponding to an entity type
       
   448 * a tuple of string corresponding to multiple entity types
       
   449 * special string such as follows:
       
   450 
       
   451   - "**": all types of entities
       
   452   - "*": all types of non-meta entities
       
   453   - "@": all types of meta entities but not system entities (e.g. used for
       
   454     the basic schema description)
   446 
   455 
   447 When a relation is not inlined and not symmetrical, and it does not require
   456 When a relation is not inlined and not symmetrical, and it does not require
   448 specific permissions, its definition (by using `SubjectRelation` and
   457 specific permissions, it can be defined using a `SubjectRelation`
   449 `ObjectRelation`) is all we need.
   458 attribute in the EntityType class. The first argument of `SubjectRelation` gives
   450 
   459 the entity type for the object of the relation.
       
   460 
       
   461 :Naming convention:
       
   462 
       
   463  Although this way of defining relations uses a Python class, the
       
   464  naming convention defined earlier prevails over the PEP8 conventions
       
   465  used in the framework: relation type class names use
       
   466  ``underscore_separated_words``. 
       
   467 
       
   468 :Historical note:
       
   469 
       
   470    It has been historically possible to use `ObjectRelation` which
       
   471    defines a relation in the opposite direction. This feature is soon to be
       
   472    deprecated and therefore should not be used in newly written code.
       
   473 
       
   474 :Future deprecation note:
       
   475 
       
   476   In an even more remote future, it is quite possible that the
       
   477   SubjectRelation shortcut will become deprecated, in favor of the
       
   478   RelationType declaration which offers some advantages in the context
       
   479   of reusable cubes.
   451 
   480 
   452 Definition of permissions
   481 Definition of permissions
   453 ~~~~~~~~~~~~~~~~~~~~~~~~~~
   482 ~~~~~~~~~~~~~~~~~~~~~~~~~~
   454 The entity type `CWPermission` from the standard library
   483 The entity type `CWPermission` from the standard library
   455 allows to build very complex and dynamic security architectures. The schema of
   484 allows to build very complex and dynamic security architectures. The schema of
   456 this entity type is as follow :
   485 this entity type is as follow:
   457 
   486 
   458 .. sourcecode:: python
   487 .. sourcecode:: python
   459 
   488 
   460     class CWPermission(EntityType):
   489     class CWPermission(EntityType):
   461         """entity type that may be used to construct some advanced security configuration
   490         """entity type that may be used to construct some advanced security configuration
   462         """
   491         """
   463         name = String(required=True, indexed=True, internationalizable=True, maxsize=100)
   492         name = String(required=True, indexed=True, internationalizable=True, maxsize=100)
   464  require_group = SubjectRelation('CWGroup', cardinality='+*',
   493         require_group = SubjectRelation('CWGroup', cardinality='+*',
   465                                         description=_('groups to which the permission is granted'))
   494                                         description=_('groups to which the permission is granted'))
   466  require_state = SubjectRelation('State',
   495         require_state = SubjectRelation('State',
   467                                         description=_("entity's state in which the permission is applicable"))
   496                                         description=_("entity's state in which the permission is applicable"))
   468         # can be used on any entity
   497         # can be used on any entity
   469  require_permission = ObjectRelation('**', cardinality='*1', composite='subject',
   498         require_permission = ObjectRelation('**', cardinality='*1', composite='subject',
   470                                             description=_("link a permission to the entity. This "
   499                                             description=_("link a permission to the entity. This "
   471                                                           "permission should be used in the security "
   500                                                           "permission should be used in the security "
   472                                                           "definition of the entity's type to be useful."))
   501                                                           "definition of the entity's type to be useful."))
   473 
   502 
   474 
   503 
   500         inlined = True
   529         inlined = True
   501 
   530 
   502 
   531 
   503 This configuration indicates that an entity `CWPermission` named
   532 This configuration indicates that an entity `CWPermission` named
   504 "add_version" can be associated to a project and provides rights to create
   533 "add_version" can be associated to a project and provides rights to create
   505 new versions on this project to specific groups. It is important to notice that :
   534 new versions on this project to specific groups. It is important to notice that:
   506 
   535 
   507 * in such case, we have to protect both the entity type "Version" and the relation
   536 * in such case, we have to protect both the entity type "Version" and the relation
   508   associating a version to a project ("version_of")
   537   associating a version to a project ("version_of")
   509 
   538 
   510 * because of the genericity of the entity type `CWPermission`, we have to execute
   539 * because of the genericity of the entity type `CWPermission`, we have to execute