1 .. -*- coding: utf-8 -*- |
|
2 |
|
3 .. _Concepts: |
|
4 |
|
5 The Core Concepts of |cubicweb| |
|
6 =============================== |
|
7 |
|
8 This section defines some terms and core concepts of the |cubicweb| framework. To |
|
9 avoid confusion while reading this book, take time to go through the following |
|
10 definitions and use this section as a reference during your reading. |
|
11 |
|
12 |
|
13 .. _Cube: |
|
14 |
|
15 Cubes |
|
16 ----- |
|
17 |
|
18 A cube is a software component made of three parts: its data model |
|
19 (:mod:`schema`), its logic (:mod:`entities`) and its user interface |
|
20 (:mod:`views`). |
|
21 |
|
22 A cube can use other cubes as building blocks and assemble them to provide a |
|
23 whole with richer functionnalities than its parts. The cubes `cubicweb-blog`_ and |
|
24 `cubicweb-comment`_ could be used to make a cube named *myblog* with commentable |
|
25 blog entries. |
|
26 |
|
27 The `CubicWeb.org Forge`_ offers a large number of cubes developed by the community |
|
28 and available under a free software license. |
|
29 |
|
30 .. note:: |
|
31 |
|
32 The command :command:`cubicweb-ctl list` displays the list of available cubes. |
|
33 |
|
34 .. _`CubicWeb.org Forge`: http://www.cubicweb.org/project/ |
|
35 .. _`cubicweb-blog`: http://www.cubicweb.org/project/cubicweb-blog |
|
36 .. _`cubicweb-comment`: http://www.cubicweb.org/project/cubicweb-comment |
|
37 |
|
38 |
|
39 .. _Instance: |
|
40 |
|
41 Instances |
|
42 --------- |
|
43 |
|
44 An instance is a runnable application installed on a computer and based on a |
|
45 cube. |
|
46 |
|
47 The instance directory contains the configuration files. Several instances can be |
|
48 created and based on the same cube. For exemple, several software forges can be |
|
49 set up on one computer system based on the `cubicweb-forge`_ cube. |
|
50 |
|
51 .. _`cubicweb-forge`: http://www.cubicweb.org/project/cubicweb-forge |
|
52 |
|
53 Instances can be of three different types: all-in-one, web engine or data |
|
54 repository. For applications that support high traffic, several web (front-end) |
|
55 and data (back-end) instances can be set-up to share the load. |
|
56 |
|
57 .. image:: ../images/archi_globale_en.png |
|
58 |
|
59 The command :command:`cubicweb-ctl list` also displays the list of instances |
|
60 installed on your system. |
|
61 |
|
62 .. note:: |
|
63 |
|
64 The term application is used to refer to "something that should do something as |
|
65 a whole", eg more like a project and so can refer to an instance or to a cube, |
|
66 depending on the context. This book will try to use *application*, *cube* and |
|
67 *instance* as appropriate. |
|
68 |
|
69 |
|
70 .. _RepositoryIntro: |
|
71 |
|
72 Data Repository |
|
73 --------------- |
|
74 |
|
75 The data repository [1]_ encapsulates and groups an access to one or |
|
76 more data sources (including SQL databases, LDAP repositories, other |
|
77 |cubicweb| instance repositories, filesystems, Google AppEngine's |
|
78 DataStore, etc). |
|
79 |
|
80 All interactions with the repository are done using the `Relation Query Language` |
|
81 (:ref:`RQL`). The repository federates the data sources and hides them from the |
|
82 querier, which does not realize when a query spans several data sources |
|
83 and requires running sub-queries and merges to complete. |
|
84 |
|
85 Application logic can be mapped to data events happenning within the |
|
86 repository, like creation of entities, deletion of relations, |
|
87 etc. This is used for example to send email notifications when the |
|
88 state of an object changes. See :ref:`HookIntro` below. |
|
89 |
|
90 .. [1] not to be confused with a Mercurial repository or a Debian repository. |
|
91 .. _`Python Remote Objects`: http://pythonhosted.org/Pyro4/ |
|
92 |
|
93 .. _WebEngineIntro: |
|
94 |
|
95 Web Engine |
|
96 ---------- |
|
97 |
|
98 The web engine replies to http requests and runs the user interface. |
|
99 |
|
100 By default the web engine provides a `CRUD`_ user interface based on |
|
101 the data model of the instance. Entities can be created, displayed, |
|
102 updated and deleted. As the default user interface is not very fancy, |
|
103 it is usually necessary to develop your own. |
|
104 |
|
105 It is common to run the web engine and the repository in the same |
|
106 process (see instances of type all-in-one above), but this is not a |
|
107 requirement. A repository can be set up to be accessed remotely using |
|
108 Pyro (`Python Remote Objects`_) and act as a standalone server, which |
|
109 can be directly accessed or also through a standalone web engine. |
|
110 |
|
111 .. _`CRUD`: http://en.wikipedia.org/wiki/Create,_read,_update_and_delete |
|
112 |
|
113 .. _SchemaIntro: |
|
114 |
|
115 Schema (Data Model) |
|
116 ------------------- |
|
117 |
|
118 The data model of a cube is described as an entity-relationship schema using a |
|
119 comprehensive language made of Python classes imported from the yams_ library. |
|
120 |
|
121 .. _yams: http://www.logilab.org/project/yams/ |
|
122 |
|
123 An `entity type` defines a sequence of attributes. Attributes may be |
|
124 of the following types: `String`, `Int`, `Float`, `Boolean`, `Date`, |
|
125 `Time`, `Datetime`, `Interval`, `Password`, `Bytes`, `RichString`. |
|
126 |
|
127 A `relation type` is used to define an oriented binary relation |
|
128 between entity types. The left-hand part of a relation is named the |
|
129 `subject` and the right-hand part is named the `object`. |
|
130 |
|
131 A `relation definition` is a triple (*subject entity type*, *relation type*, *object |
|
132 entity type*) associated with a set of properties such as cardinality, |
|
133 constraints, etc. |
|
134 |
|
135 Permissions can be set on entity types or relation definition to control who |
|
136 will be able to create, read, update or delete entities and relations. Permissions |
|
137 are granted to groups (to which users may belong) or using rql expressions (if the |
|
138 rql expression returns some results, the permission is granted). |
|
139 |
|
140 Some meta-data necessary to the system are added to the data model. That includes |
|
141 entities like users and groups, the entities used to store the data model |
|
142 itself and attributes like unique identifier, creation date, creator, etc. |
|
143 |
|
144 When you create a new |cubicweb| instance, the schema is stored in the database. |
|
145 When the cubes the instance is based on evolve, they may change their data model |
|
146 and provide migration scripts that will be executed when the administrator will |
|
147 run the upgrade process for the instance. |
|
148 |
|
149 |
|
150 .. _VRegistryIntro: |
|
151 |
|
152 Registries and application objects |
|
153 ---------------------------------- |
|
154 |
|
155 Application objects |
|
156 ~~~~~~~~~~~~~~~~~~~ |
|
157 |
|
158 Besides a few core functionalities, almost every feature of the framework is |
|
159 achieved by dynamic objects (`application objects` or `appobjects`) stored in a |
|
160 two-levels registry. Each object is affected to a registry with |
|
161 an identifier in this registry. You may have more than one object sharing an |
|
162 identifier in the same registry: |
|
163 |
|
164 object's `__registry__` : object's `__regid__` : [list of app objects] |
|
165 |
|
166 In other words, the `registry` contains several (sub-)registries which hold a |
|
167 list of appobjects associated to an identifier. |
|
168 |
|
169 The base class of appobjects is :class:`cubicweb.appobject.AppObject`. |
|
170 |
|
171 Selectors |
|
172 ~~~~~~~~~ |
|
173 |
|
174 At runtime, appobjects can be selected in a registry according to some |
|
175 contextual information. Selection is done by comparing the *score* |
|
176 returned by each appobject's *selector*. |
|
177 |
|
178 The better the object fits the context, the higher the score. Scores |
|
179 are the glue that ties appobjects to the data model. Using them |
|
180 appropriately is an essential part of the construction of well behaved |
|
181 cubes. |
|
182 |
|
183 |cubicweb| provides a set of basic selectors that may be parametrized. Also, |
|
184 selectors can be combined with the `~` unary operator (negation) and the binary |
|
185 operators `&` and `|` (respectivly 'and' and 'or') to build more complex |
|
186 selectors. Of course complex selectors may be combined too. Last but not least, you |
|
187 can write your own selectors. |
|
188 |
|
189 The `registry` |
|
190 ~~~~~~~~~~~~~~~ |
|
191 |
|
192 At startup, the `registry` inspects a number of directories looking |
|
193 for compatible class definitions. After a recording process, the |
|
194 objects are assigned to registries and become available through the |
|
195 selection process. |
|
196 |
|
197 In a cube, application object classes are looked in the following modules or |
|
198 packages: |
|
199 |
|
200 - `entities` |
|
201 - `views` |
|
202 - `hooks` |
|
203 - `sobjects` |
|
204 |
|
205 There are three common ways to look up some application object from a |
|
206 registry: |
|
207 |
|
208 * get the most appropriate object by specifying an identifier and |
|
209 context objects. The object with the greatest score is |
|
210 selected. There should always be a single appobject with a greater |
|
211 score than others for a particular context. |
|
212 |
|
213 * get all objects applying to a context by specifying a registry. A |
|
214 list of objects will be returned containing the object with the |
|
215 highest score (> 0) for each identifier in that registry. |
|
216 |
|
217 * get the object within a particular registry/identifier. No selection |
|
218 process is involved: the registry will expect to find a single |
|
219 object in that cell. |
|
220 |
|
221 |
|
222 .. _RQLIntro: |
|
223 |
|
224 The RQL query language |
|
225 ---------------------- |
|
226 |
|
227 No need for a complicated ORM when you have a powerful data |
|
228 manipulation language. |
|
229 |
|
230 All the persistent data in a |cubicweb| instance is retrieved and |
|
231 modified using RQL (see :ref:`rql_intro`). |
|
232 |
|
233 This query language is inspired by SQL but is on a higher level in order to |
|
234 emphasize browsing relations. |
|
235 |
|
236 |
|
237 Result set |
|
238 ~~~~~~~~~~ |
|
239 |
|
240 Every request made (using RQL) to the data repository returns an object we call a |
|
241 Result Set. It enables easy use of the retrieved data, providing a translation |
|
242 layer between the backend's native datatypes and |cubicweb| schema's EntityTypes. |
|
243 |
|
244 Result sets provide access to the raw data, yielding either basic Python data |
|
245 types, or schema-defined high-level entities, in a straightforward way. |
|
246 |
|
247 |
|
248 .. _ViewIntro: |
|
249 |
|
250 Views |
|
251 ----- |
|
252 |
|
253 **CubicWeb is data driven** |
|
254 |
|
255 The view system is loosely coupled to data through the selection system explained |
|
256 above. Views are application objects with a dedicated interface to 'render' |
|
257 something, eg producing some html, text, xml, pdf, or whatsover that can be |
|
258 displayed to a user. |
|
259 |
|
260 Views actually are partitioned into different kind of objects such as |
|
261 `templates`, `boxes`, `components` and proper `views`, which are more |
|
262 high-level abstraction useful to build the user interface in an object |
|
263 oriented way. |
|
264 |
|
265 |
|
266 .. _HookIntro: |
|
267 |
|
268 Hooks and operations |
|
269 -------------------- |
|
270 |
|
271 **CubicWeb provides an extensible data repository** |
|
272 |
|
273 The data model defined using Yams types allows to express the data |
|
274 model in a comfortable way. However several aspects of the data model |
|
275 can not be expressed there. For instance: |
|
276 |
|
277 * managing computed attributes |
|
278 |
|
279 * enforcing complicated business rules |
|
280 |
|
281 * real-world side-effects linked to data events (email notification |
|
282 being a prime example) |
|
283 |
|
284 The hook system is much like the triggers of an SQL database engine, |
|
285 except that: |
|
286 |
|
287 * it is not limited to one specific SQL backend (every one of them |
|
288 having an idiomatic way to encode triggers), nor to SQL backends at |
|
289 all (think about LDAP or a Subversion repository) |
|
290 |
|
291 * it is well-coupled to the rest of the framework |
|
292 |
|
293 Hooks are also application objects (in the `hooks` registry) and |
|
294 selected on events such as after/before add/update/delete on |
|
295 entities/relations, server startup or shutdown, etc. |
|
296 |
|
297 `Operations` may be instantiated by hooks to do further processing at different |
|
298 steps of the transaction's commit / rollback, which usually can not be done |
|
299 safely at the hook execution time. |
|
300 |
|
301 Hooks and operation are an essential building block of any moderately complicated |
|
302 cubicweb application. |
|
303 |
|
304 .. note:: |
|
305 RQL queries executed in hooks and operations are *unsafe* by default, i.e. the |
|
306 read and write security is deactivated unless explicitly asked. |
|