# HG changeset patch # User sylvain.thenault@logilab.fr # Date 1238089903 -3600 # Node ID 60efe4a18692d1ccef37bfdc3ea488705aaea624 # Parent a7c0894051851db18e3c5f3e0e3a9f3608e26312# Parent ebf7328c251e307a33546ad519a0c1c8598b0789 merge diff -r a7c089405185 -r 60efe4a18692 doc/book/en/B0010-define-schema.en.txt --- a/doc/book/en/B0010-define-schema.en.txt Thu Mar 26 18:51:29 2009 +0100 +++ b/doc/book/en/B0010-define-schema.en.txt Thu Mar 26 18:51:43 2009 +0100 @@ -4,14 +4,15 @@ ================================ The schema is the core piece of a `CubicWeb` application as it defines -the data model handled. It is based on entities types already defined -in the `CubicWeb` standard library and others, more specific, we would -expect to find in one or more Python files under the `schema` directory. +the data model handled. It is based on entity types that are either already +defined in the `CubicWeb` standard library; or more specific types, that +`CubicWeb` expects to find in one or more Python files under the directory +`schema`. At this point, it is important to make clear the difference between -relation type and relation definition: a relation type is only a relation +*relation type* and *relation definition*: a *relation type* is only a relation name with potentially other additionnal properties (see XXXX), whereas a -relation definition is a complete triplet +*relation definition* is a complete triplet " ". A relation type could have been implied if none is related to a relation definition of the schema. diff -r a7c089405185 -r 60efe4a18692 doc/book/en/B0011-schema-stdlib.en.txt --- a/doc/book/en/B0011-schema-stdlib.en.txt Thu Mar 26 18:51:29 2009 +0100 +++ b/doc/book/en/B0011-schema-stdlib.en.txt Thu Mar 26 18:51:43 2009 +0100 @@ -3,14 +3,14 @@ Pre-defined schemas in the library ---------------------------------- -The library defines a set of entities schemas that are required by the system +The library defines a set of entity schemas that are required by the system or commonly used in `CubicWeb` applications. Of course, you can extend those schemas if necessary. System schemas `````````````` -The system entities available are : +The system entities available are: * `EUser`, system users * `EGroup`, users groups @@ -31,8 +31,11 @@ * `Bookmark`, an entity type used to allow a user to customize his links within the application -Cubes available -``````````````` +(The first 'E' in some of the names is the first letter of 'Erudi', +`CubicWeb`'s old name; it might be changed/removed some day.) + + Cubes available + ``````````````` An application is based on several basic cubes. In the set of available basic cubes we can find for example : diff -r a7c089405185 -r 60efe4a18692 doc/book/en/B0012-schema-definition.en.txt --- a/doc/book/en/B0012-schema-definition.en.txt Thu Mar 26 18:51:29 2009 +0100 +++ b/doc/book/en/B0012-schema-definition.en.txt Thu Mar 26 18:51:43 2009 +0100 @@ -3,10 +3,12 @@ Entity type definition ---------------------- -An entity type is defined by a Python class which inherits `EntityType`. The -class name correponds to the type name. Then the content of the class contains -the description of attributes and relations for the defined entity type, -for example :: +An entity type is defined by a Python class which inherits from `EntityType`. +The class definition contains the description of attributes and relations +for the defined entity type. +The class name corresponds to the entity type name. + +For example :: class Person(EntityType): """A person with the properties and the relations necessary for my @@ -14,15 +16,17 @@ last_name = String(required=True, fulltextindexed=True) first_name = String(required=True, fulltextindexed=True) - title = String(vocabulary=('M', 'Mme', 'Mlle')) + title = String(vocabulary=('Mr', 'Mrs', 'Miss')) date_of_birth = Date() works_for = SubjectRelation('Company', cardinality='?*') + * the name of the Python attribute corresponds to the name of the attribute or the relation in `CubicWeb` application. -* all built-in types are available : `String`, `Int`, `Float`, - `Boolean`, `Date`, `Datetime`, `Time`, `Byte`. +* all `CubicWeb` built-in types are available : `String`, `Int`, `Float`, + `Boolean`, `Date`, `Datetime`, `Time`, `Byte`; they are and implicitely + imported (as well as the special the function "_"). * each entity type has at least the following meta-relations : @@ -34,21 +38,19 @@ - `created_by` (`EUser`) (which user created the entity) - - `owned_by` (`EUser`) (who does the entity belongs to, by default the - creator but not necessary and it could have multiple owners) + - `owned_by` (`EUser`) (to whom the entity belongs; by default the + creator but not necessary, and it could have multiple owners) - `is` (`EEType`) - -* it is also possible to define relations of type object by using `ObjectRelation` - instead of `SubjectRelation` -* the first argument of `SubjectRelation` and `ObjectRelation` gives respectively +* relations can be defined by using `ObjectRelation` or `SubjectRelation`. + The first argument of `SubjectRelation` or `ObjectRelation` gives respectively the object/subject entity type of the relation. This could be : * a string corresponding to an entity type - * a tuple of string correponding to multiple entities types + * a tuple of string corresponding to multiple entity types * special string such as follows : @@ -62,20 +64,20 @@ * optional properties for attributes and relations : - - `description` : string describing an attribute or a relation. By default + - `description` : a string describing an attribute or a relation. By default this string will be used in the editing form of the entity, which means that it is supposed to help the end-user and should be flagged by the function `_` to be properly internationalized. - - `constraints` : list of conditions/constraints that the relation needs to + - `constraints` : a list of conditions/constraints that the relation has to satisfy (c.f. `Contraints`_) - - `cardinality` : two characters string which specify the cardinality of the + - `cardinality` : a two character string which specify the cardinality of the relation. The first character defines the cardinality of the relation on - the subject, the second on the object of the relation. When a relation - has multiple possible subjects or objects, the cardinality applies to all - and not on a one to one basis (so it must be consistent...). The possible - values are inspired from regular expressions syntax : + the subject, and the second on the object. When a relation can have + multiple subjects or objects, the cardinality applies to all, + not on a one-to-one basis (so it must be consistent...). The possible + values are inspired from regular expression syntax : * `1`: 1..1 * `?`: 0..1 @@ -85,7 +87,7 @@ - `meta` : boolean indicating that the relation is a meta-relation (false by default) -* optionnal properties for attributes : +* optional properties for attributes : - `required` : boolean indicating if the attribute is required (false by default) @@ -98,11 +100,11 @@ attribute. - `default` : default value of the attribute. In case of date types, the values - which could be used correpond to the RQL keywords `TODAY` and `NOW`. + which could be used correspond to the RQL keywords `TODAY` and `NOW`. - `vocabulary` : specify static possible values of an attribute -* optionnal properties of type `String` : +* optional properties of type `String` : - `fulltextindexed` : boolean indicating if the attribute is part of the full text index (false by default) (*applicable on the type `Byte` @@ -113,17 +115,17 @@ - `maxsize` : integer providing the maximum size of the string (no limit by default) -* optionnal properties for relations : +* optional properties for relations : - `composite` : string indicating that the subject (composite == 'subject') is composed of the objects of the relations. For the opposite case (when - the object is composed of the subjects of the relation), we just need - to set 'object' as the value. The composition implies that when the relation + the object is composed of the subjects of the relation), we just set + 'object' as value. The composition implies that when the relation is deleted (so when the composite is deleted), the composed are also deleted. Contraints `````````` -By default, the available constraints types are : +By default, the available constraint types are : * `SizeConstraint` : allows to specify a minimum and/or maximum size on string (generic case of `maxsize`) @@ -135,7 +137,7 @@ * `StaticVocabularyConstraint` : identical to "vocabulary=(...)" -* `RQLConstraint` : allows to specify a RQL query that needs to be satisfied +* `RQLConstraint` : allows to specify a RQL query that has to be satisfied by the subject and/or the object of the relation. In this query the variables `S` and `O` are reserved for the entities subject and object of the relation. @@ -143,7 +145,7 @@ * `RQLVocabularyConstraint` : similar to the previous type of constraint except that it does not express a "strong" constraint, which means it is only used to restrict the values listed in the drop-down menu of editing form, but it does - not prevent another entity to be selected + not prevent another entity to be selected. Relation definition @@ -154,7 +156,7 @@ A relation is defined by a Python class heriting `RelationType`. The name of the class corresponds to the name of the type. The class then contains a description of the properties of this type of relation, and could as well -contains a string for the subject and a string for the object. This allows to create +contain a string for the subject and a string for the object. This allows to create new definition of associated relations, (so that the class can have the definition properties from the relation) for example :: @@ -174,14 +176,14 @@ table for the relation. This applies to the relation when the cardinality of subject->relation->object is 0..1 (`?`) or 1..1 (`1`) -* `symetric` : boolean indication that the relation is symetrical, which +* `symmetric` : boolean indicating that the relation is symmetrical, which means `X relation Y` implies `Y relation X` In the case of simultaneous relations definitions, `subject` and `object` can both be equal to the value of the first argument of `SubjectRelation` and `ObjectRelation`. -When a relation is not inlined and not symetrical, and it does not require +When a relation is not inlined and not symmetrical, and it does not require specific permissions, its definition (by using `SubjectRelation` and `ObjectRelation`) is all we need. @@ -375,7 +377,11 @@ Updating your application with your new schema `````````````````````````````````````````````` -You have to get a shell on your application :: +If you modified your schema, the update is not automatic; this is +indeed in general not a good idea. +Instead, we call a shell on your application, which is a +an interactive python shell, with an appropriate +cubicweb environment :: cubicweb-ctl shell myinstance diff -r a7c089405185 -r 60efe4a18692 doc/book/en/B0040-migration.en.txt --- a/doc/book/en/B0040-migration.en.txt Thu Mar 26 18:51:29 2009 +0100 +++ b/doc/book/en/B0040-migration.en.txt Thu Mar 26 18:51:43 2009 +0100 @@ -5,10 +5,10 @@ Migration ========= -One of the main concept in `CubicWeb` is to create incremental applications -and for this purpose multiple actions are provided to facilitate the improvement -of an application and in particular changes applied to the data model -without loosing existing data. +One of the main concept in `CubicWeb` is to create incremental applications. +For this purpose, multiple actions are provided to facilitate the improvement +of an application, and in particular to handle the changes to be applied +to the data model, without loosing existing data. The current version of an application model is provided in the file `__pkginfo__.py` as a tuple of 3 integers. @@ -16,8 +16,8 @@ Migration scripts management ---------------------------- -Migration scripts needs to be located in the directory `migration` of your -application and nammed accordingly: +Migration scripts has to be located in the directory `migration` of your +application and named accordingly: :: @@ -25,26 +25,27 @@ in which : -* X.Y.Z is the model version number to which the script enable to migrate +* X.Y.Z is the model version number to which the script enables to migrate. -* *mode* (between the last "_" and the extension ".py") indicates which part - of the application (RQL server, web server) the script applies to in case - of distributed installation. Its value could be : +* *mode* (between the last "_" and the extension ".py") is used for + distributed installation. It indicates to which part + of the application (RQL server, web server) the script applies. + Its value could be : * `common`, applies to the RQL server as well as the web server and updates files on the hard drive (configuration files migration for example). - * `web`, applies only to the web server and updates files on the hard drive + * `web`, applies only to the web server and updates files on the hard drive. * `repository`, applies only to the RQL server and updates files on the - hard drive + hard drive. * `Any`, applies only to the RQL server and updates data in the database - (schema and data migration for example) + (schema and data migration for example). Again in the directory `migration`, the file `depends.map` allows to indicate that to migrate to a particular model version, you always have to first migrate -to a particular `CubicWeb` version. This file can contains comments (lines +to a particular `CubicWeb` version. This file can contain comments (lines starting by `#`) and a dependancy is listed as follows: :: : @@ -53,7 +54,7 @@ 0.12.0: 2.26.0 0.13.0: 2.27.0 - # 0.14 works with 2.27 <= erudi <= 2.28 at least + # 0.14 works with 2.27 <= cubicweb <= 2.28 at least 0.15.0: 2.28.0 Base context @@ -68,18 +69,16 @@ * `appltemplversion`, application model version of the instance -* `applerudiversion`, cubicweb instance version - * `templversion`, installed application model version -* `erudiversion`, installed cubicweb version +* `cubicwebversion`, installed cubicweb version * `confirm(question)`, function interrogating the user and returning true - if the user answers yes, false otherwise (always returns true when in a + if the user answers yes, false otherwise (always returns true in non-interactive mode) -* `_`, function fonction equivalent to `unicode` allowing to flag the strings - to internationalize in the migration scripts +* the function `_`, it is equivalent to `unicode` allowing to flag the strings + to internationalize in the migration scripts. In the `repository` scripts, the following identifiers are also defined: @@ -89,7 +88,7 @@ current migration) * `newschema`, installed schema on the file system (e.g. schema of - the updated model and erudi) + the updated model and cubicweb) * `sqlcursor`, SQL cursor for very rare cases where it is really necessary or beneficial to go through the sql @@ -109,7 +108,7 @@ * `drop_attribute(etype, attrname, commit=True)`, removes an attribute from an existing entity type. -* `rename_attribute(etype, oldname, newname, commit=True)`, rename an attribute +* `rename_attribute(etype, oldname, newname, commit=True)`, renames an attribute * `add_entity_type(etype, auto=True, commit=True)`, adds a new entity type. If `auto` is True, all the relations using this entity type and having a known diff -r a7c089405185 -r 60efe4a18692 doc/book/en/C040-rql.en.txt --- a/doc/book/en/C040-rql.en.txt Thu Mar 26 18:51:29 2009 +0100 +++ b/doc/book/en/C040-rql.en.txt Thu Mar 26 18:51:43 2009 +0100 @@ -9,13 +9,13 @@ Introduction ============ -Goals RQL ---------- +Goals of RQL +------------ The goal is to have a language emphasizing the way of browsing relations. As such, attributes will be regarded as cases of -special relations (in terms of implementation, the user -language not to see virtually no difference between an attribute and a +special relations (in terms of implementation, the language +user should see virtually no difference between an attribute and a relation). RQL is inspired by SQL but is the highest level. A knowledge of the @@ -34,7 +34,7 @@ Versa ````` -Should I look in more detail, but here is already some ideas for +We should look in more detail, but here are already some ideas for the moment ... Versa_ is the language most similar to what we wanted to do, but the model underlying data being RDF, there is some number of things such as namespaces or handling of the RDF types which @@ -54,19 +54,18 @@ ------------------------------ Search (`Any`) - This type of query can extract entities and attributes of entities. + Extract entities and attributes of entities. -Inserting entities (`INSERT`) - This type of query is used to insert new entities in the database. It - will also create direct relationships entities newly created. +Insert entities (`INSERT`) + Insert new entities or relations in the database. + It can also directly create relationships for the newly created entities. -Update entities, relations creation (`SET`) - This type of query updates existing entities in the database, +Update entities, create relations (`SET`) + Update existing entities in the database, or create relations between existing entities. -Deletion of entities or relationship (`DELETE`) - This type of query allows for the removal of entities and relations existing - in the database. +Delete entities or relationship (`DELETE`) + Remove entities or relations existing in the database. Search Query ------------ @@ -80,7 +79,7 @@ Type of selected variables. The special type `Any` is equivalent to not specify a type. :restriction: - list of relations to go through whic follow the pattern + list of conditions to test successively `V1 relation V2 | ` :orderterms: Definition of the selection order: variable or column number followed by @@ -92,13 +91,13 @@ - *Search for the object of identifier 53* - :: + :: Any WHERE X X eid 53 - *Search material such as comics, owned by syt and available* - :: + :: WHERE X Document X occurence_of F, F class C, C name 'Comics' @@ -106,36 +105,36 @@ X available true - *Looking for people working for eurocopter interested in training* - :: + :: Any P WHERE - P is Person, P work_for P, S name 'Eurocopter' + P is Person, P work_for S, S name 'Eurocopter' P interested_by T, T name 'training' - *Search note less than 10 days old written by jphc or ocy* - :: + :: Any N WHERE N is Note, N written_on D, D day> (today -10), N written_by P, P name 'jphc' or P name 'ocy' - *Looking for people interested in training or living in Paris* - :: + :: Any P WHERE P is Person, (P interested_by T, T name 'training') OR (P city 'Paris') - *The name and surname of all people* - :: + :: Any N, P WHERE X is Person, X name N, X first_name P - Note that the selection of several entities generally force - the use of "Any" because the type specification applies otherwise - to all the selected variables. We could write here - :: + Note that the selection of several entities generally force + the use of "Any" because the type specification applies otherwise + to all the selected variables. We could write here + :: String N, P WHERE X is Person, X name N, X first_name P @@ -147,16 +146,16 @@ `INSERT` V1 (, V2) \ * `:` [ `WHERE` ] -: assignments: +:assignments: list of relations to assign in the form `V1 relationship V2 | ` The restriction can define variables used in assignments. Caution, if a restriction is specified, the insertion is done for -*each line results returned by the restriction*. +*each line result returned by the restriction*. - *Insert a new person named 'foo'* - :: + :: INSERT Person X: X name 'foo' @@ -178,12 +177,12 @@ [ `WHERE` ] Caution, if a restriction is specified, the update is done *for -each line results returned by the restriction*. +each result line returned by the restriction*. - *Renaming of the person named 'foo' to 'bar' with the first name changed* :: - SET X name 'bar', X first_name 'original' where X is Person X name 'foo' + SET X name 'bar', X first_name 'original' WHERE X is Person, X name 'foo' - *Insert a relation of type 'know' between objects linked by the relation of type 'friend'* @@ -198,7 +197,7 @@ [ `WHERE` ] Caution, if a restriction is specified, the deletion is made *for -each line results returned by the restriction*. +each line result returned by the restriction*. - *Deletion of the person named 'foo'* :: @@ -211,8 +210,8 @@ DELETE X friend Y WHERE X is Person, X name 'foo' -Undocumented (yet) type of queries ----------------------------------- +(yet) Undocumented types of queries +----------------------------------- **Limit / offset** :: @@ -302,14 +301,14 @@ `````````````` The base types supported are string (between double or single quotes), -integers or floats (the separator is the'.'), dates and +integers or floats (the separator is '.'), dates and boolean. We expect to receive a schema in which types String, Int, Float, Date and Boolean are defined. * `String` (literal: between double or single quotes). * `Int`, `Float` (separator being'.'). * `Date`, `Datetime`, `Time` (literal: string YYYY/MM/DD [hh:mm] or keywords - `TODAY` and `NOW`). + `TODAY` and `NOW`). * `Boolean` (keywords `TRUE` and `FALSE`). * `Keyword` NULL. @@ -318,10 +317,10 @@ --------- Logical Operators -``````````````````` +````````````````` :: - AND, OR, ',' + AND, OR, NOT, ',' ',' is equivalent to 'AND' but with the smallest among the priority of logical operators (see :ref:`PriorityOperators`). @@ -336,7 +335,7 @@ ```````````````````` :: - =, <, <=, >=, > = ~, IN, LIKE + =, <, <=, >=, >, ~=, IN, LIKE * The operator `=` is the default operator. @@ -345,7 +344,7 @@ must start or finish by a prefix/suffix: :: - Any X WHERE X name =~ 'Th%' + Any X WHERE X name ~= 'Th%' Any X WHERE X name LIKE '%lt' * The operator `IN` provides a list of possible values: @@ -354,30 +353,32 @@ Any X WHERE X name IN ( 'chauvat', 'fayolle', 'di mascio', 'thenault') -XXX nico: A trick <> 'bar' would not it be more convenient than NOT A -trick 'bar'? +XXX nico: "A trick <> 'bar'" wouldn't it be more convenient than +"NOT A trick 'bar'" ? .. _PriorityOperators: -Operators priority -`````````````````` +Operator priority +````````````````` 1. '*', '/' 2. '+', '-' -3. 'and' +3. 'not' + +4 'and' -4. 'or' +5 'or' -5. ',' +6 ',' Advanced Features ----------------- -Functions aggregates -```````````````````` +Aggregate Functions +``````````````````` :: COUNT, MIN, MAX, AVG, SUM @@ -468,11 +469,11 @@ constant ::= KEYWORD | STRING | FLOAT | INT # tokens - LOGIC_OP ::= ',' | 'GOLD' | 'AND' + LOGIC_OP ::= ',' | 'OR' | 'AND' MATH_OP ::= '+' | '-' | '/' | '*' COMP_OP ::= '>' | '>=' | '=' | '<=' | '<' | '~=' | 'LIKE' - FUNCTION ::= 'MIN' | 'MAX' | 'SUM' | 'AVG' | 'COUNT' | 'upper' | 'LOWER' + FUNCTION ::= 'MIN' | 'MAX' | 'SUM' | 'AVG' | 'COUNT' | 'UPPER' | 'LOWER' VARIABLE ::= '[A-Z][A-Z0-9]*' E_TYPE ::= '[A-Z]\w*' @@ -541,13 +542,13 @@ :: - Select ((Relationship | And | Gold)?, Group?, Sort?) - Insert (Relations | And | Gold)? - Delete (Relationship | And | Gold)? - Update (Relations | And | Gold)? + Select ((Relationship | And | Or)?, Group?, Sort?) + Insert (Relations | And | Or)? + Delete (Relationship | And | Or)? + Update (Relations | And | Or)? - And ((Relationship | And | Gold), (Relationship | And | Gold)) - Or ((Relationship | And | Gold), (Relationship | And | Gold)) + And ((Relationship | And | Or), (Relationship | And | Or)) + Or ((Relationship | And | Or), (Relationship | And | Or)) Relationship ((VariableRef, Comparison)) @@ -578,20 +579,20 @@ Point P where P abs X, P ord Y, P value X+Y - is valid, but:: + is valid, but:: Point P where P abs X, P value X+Y, P ord Y - is not. + is not. RQL logs -------- -You can configure the `CubicWeb` application so that you keep a log -of the queries executed against your database. To do so, you want to +You can configure the `CubicWeb` application to keep a log +of the queries executed against your database. To do so, edit the configuration file of your application ``.../etc/cubicweb.d/myapp/all-in-one.conf`` and uncomment the -variable ``query-log-file``: :: +variable ``query-log-file``:: # web application query log file query-log-file=/tmp/rql-myapp.log diff -r a7c089405185 -r 60efe4a18692 web/views/editcontroller.py --- a/web/views/editcontroller.py Thu Mar 26 18:51:29 2009 +0100 +++ b/web/views/editcontroller.py Thu Mar 26 18:51:43 2009 +0100 @@ -166,13 +166,13 @@ self.delete_entities(self.req.edited_eids(withtype=True)) return self.reset() - def _needs_edition(self, rtype, formparams): + def _needs_edition(self, rtype, formparams, entity): """returns True and and the new value if `rtype` was edited""" editkey = 'edits-%s' % rtype if not editkey in formparams: return False, None # not edited value = formparams.get(rtype) or None - if (formparams.get(editkey) or None) == value: + if entity.has_eid() and (formparams.get(editkey) or None) == value: return False, None # not modified if value == INTERNAL_FIELD_VALUE: value = None @@ -183,7 +183,7 @@ attribute described by the given schema if necessary """ attr = rschema.type - edition_needed, value = self._needs_edition(attr, formparams) + edition_needed, value = self._needs_edition(attr, formparams, entity) if not edition_needed: return # test if entity class defines a special handler for this attribute