doc/book/en/intro/concepts.rst
branchstable
changeset 5150 7a9e71ee5671
parent 5146 fe56baf63ecb
child 5189 84d4587a92bc
equal deleted inserted replaced
5149:a6bcb3c264fe 5150:7a9e71ee5671
       
     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 (:file:`schema`), its logic (:file:`entities`) and its user interface
       
    20 (:file:`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 The command :command:`cubicweb-ctl list` displays the list of cubes installed on
       
    31 your system.
       
    32 
       
    33 On a Unix system, the available cubes are usually stored in the directory
       
    34 :file:`/usr/share/cubicweb/cubes`. If you're using the cubicweb forest
       
    35 (:ref:SourceInstallation), the cubes are searched in the directory
       
    36 :file:`/path/to/cubicweb_forest/cubes`. The environment variable
       
    37 :envvar:`CW_CUBES_PATH` gives additionnal locations where to search for cubes.
       
    38 
       
    39 .. _`CubicWeb.org Forge`: http://www.cubicweb.org/project/
       
    40 .. _`cubicweb-blog`: http://www.cubicweb.org/project/cubicweb-blog
       
    41 .. _`cubicweb-comment`: http://www.cubicweb.org/project/cubicweb-comment
       
    42 
       
    43 
       
    44 .. _Instance:
       
    45 
       
    46 Instances
       
    47 ---------
       
    48 
       
    49 An instance is a runnable application installed on a computer and based on a
       
    50 cube.
       
    51 
       
    52 The instance directory contains the configuration files. Several instances can be
       
    53 created and based on the same cube. For exemple, several software forges can be
       
    54 set up on one computer system based on the `cubicweb-forge`_ cube.
       
    55 
       
    56 .. _`cubicweb-forge`: http://www.cubicweb.org/project/cubicweb-forge
       
    57 
       
    58 Instances can be of three different types: all-in-one, web engine or data
       
    59 repository. For applications that support high traffic, several web (front-end)
       
    60 and data (back-end) instances can be set-up to share the load.
       
    61 
       
    62 .. image:: ../../images/archi_globale.en.png
       
    63 
       
    64 The command :command:`cubicweb-ctl list` also displays the list of instances
       
    65 installed on your system.
       
    66 
       
    67 On a Unix system, the instances are usually stored in the directory
       
    68 :file:`/etc/cubicweb.d/`. During development, the :file:`~/etc/cubicweb.d/`
       
    69 directory is looked up, as well as the paths in :envvar:`CW_INSTANCES_DIR`
       
    70 environment variable.
       
    71 
       
    72 
       
    73 .. Note::
       
    74 
       
    75   The term application is used to refer to "something that should do something as
       
    76   a whole", eg more like a project and so can refer to an instance or to a cube,
       
    77   depending on the context. This book will try to use *application*, *cube* and
       
    78   *instance* as appropriate.
       
    79 
       
    80 
       
    81 .. _RepositoryIntro:
       
    82 
       
    83 Data Repository
       
    84 ---------------
       
    85 
       
    86 The data repository [1]_ provides access to one or more data sources (including
       
    87 SQL databases, LDAP repositories, other |cubicweb| instance repositories, GAE's
       
    88 DataStore, etc).
       
    89 
       
    90 All interactions with the repository are done using the Relation Query Language
       
    91 (:ref:`RQL`). The repository federates the data sources and hides them from the
       
    92 querier, which does not realize when a query spans accross several data sources
       
    93 and requires running sub-queries and merges to complete.
       
    94 
       
    95 It is common to run the web engine and the repository in the same process (see
       
    96 instances of type all-in-one above), but this is not a requirement. A repository
       
    97 can be set up to be accessed remotely using Pyro (`Python Remote Objects`_) and
       
    98 act as a server. However, it's important to know if code you're writing is
       
    99 executed on the repository side, on our client side (the web engine being a
       
   100 client for instance): you don't have the same abilities on both side. On the
       
   101 repository side, you can for instance by-pass security checks, which isn't
       
   102 possible from client code.
       
   103 
       
   104 Some logic can be attached to events that happen in the repository, like
       
   105 creation of entities, deletion of relations, etc. This is used for example to
       
   106 send email notifications when the state of an object changes. See :ref:`HookIntro` below.
       
   107 
       
   108 .. [1] not to be confused with a Mercurial repository or a Debian repository.
       
   109 .. _`Python Remote Objects`: http://pyro.sourceforge.net/
       
   110 
       
   111 
       
   112 .. _WebEngineIntro:
       
   113 
       
   114 Web Engine
       
   115 ----------
       
   116 
       
   117 The web engine replies to http requests and runs the user interface
       
   118 and most of the application logic.
       
   119 
       
   120 By default the web engine provides a `CRUD`_ user interface based on
       
   121 the data model of the instance. Entities can be created, displayed,
       
   122 updated and deleted. As the default user interface is not very fancy,
       
   123 it is usually necessary to develop your own.
       
   124 
       
   125 .. _`CRUD`: http://en.wikipedia.org/wiki/Create,_read,_update_and_delete
       
   126 
       
   127 .. _SchemaIntro:
       
   128 
       
   129 Schema (Data Model)
       
   130 -------------------
       
   131 
       
   132 The data model of a cube is described as an entity-relationship schema using a
       
   133 comprehensive language made of Python classes imported from the yams_ library.
       
   134 
       
   135 .. _yams: http://www.logilab.org/project/yams/
       
   136 
       
   137 An `entity type` defines a set of attributes and is used in some relations.
       
   138 Attributes may be of the following types: `String`, `Int`, `Float`, `Boolean`,
       
   139 `Date`, `Time`, `Datetime`, `Interval`, `Password`, `Bytes`, `RichString`.
       
   140 
       
   141 A `relation type` is used to define an oriented binary relation between two
       
   142 entity types.  The left-hand part of a relation is named the `subject` and the
       
   143 right-hand part is named the `object`.
       
   144 
       
   145 A `relation definition` is a triple (*subject entity type*, *relation type*, *object
       
   146 entity type*) associated with a set of properties such as cardinality,
       
   147 constraints, etc.
       
   148 
       
   149 Permissions can be set on entity types and relation definition to control who
       
   150 will be able to create, read, update or delete entities and relations. Permissions
       
   151 are granted to groups (to which users may belong) or using rql expression (if the
       
   152 rql expression returns some results, the permission is granted).
       
   153 
       
   154 Some meta-data necessary to the system is added to the data model. That includes
       
   155 entities like users and groups, the entities used to store the data model
       
   156 itself and attributes like unique identifier, creation date, creator, etc.
       
   157 
       
   158 When you create a new |cubicweb| instance, the schema is stored in the database.
       
   159 When the cubes the instance is based on evolve, they may change their data model
       
   160 and provide migration scripts that will be executed when the administrator will
       
   161 run the upgrade process for the instance.
       
   162 
       
   163 
       
   164 .. _VRegistryIntro:
       
   165 
       
   166 Registries and application objects
       
   167 ----------------------------------
       
   168 
       
   169 Application objects
       
   170 ~~~~~~~~~~~~~~~~~~~
       
   171 
       
   172 Beside a few core functionalities, almost every feature of the framework is
       
   173 achieved by dynamic objects (`application objects` or `appobjects`) stored in a
       
   174 two-levels registry (the `vregistry`). Each object is affected to a registry with
       
   175 an identifier in this registry. You may have more than one object sharing an
       
   176 identifier in the same registry, At runtime, appobjects are selected in a
       
   177 registry according to the context. Selection is done by comparing *score*
       
   178 returned by each appobject's *selector*.
       
   179 
       
   180 Application objects are stored in the vregistry using a two-level hierarchy :
       
   181 
       
   182   object's `__registry__` : object's `__regid__` : [list of app objects]
       
   183 
       
   184 E.g. The `vregistry` contains several registries which hold a list of
       
   185 appobjects associated to an identifier.
       
   186 
       
   187 The base class of appobjects is :class:`cubicweb.appobject.AppObject`.
       
   188 
       
   189 Selectors
       
   190 ~~~~~~~~~
       
   191 
       
   192 Each appobject has a selector, that is used to compute how well the object fits a
       
   193 given context. The better the object fits the context, the higher the score. They
       
   194 are the glue that tie appobjects to the data model. Using them appropriately is
       
   195 an essential part of the construction of well behaved cubes.
       
   196 
       
   197 |cubicweb| provides a set of basic selectors that may be parametrized.  Also,
       
   198 selectors can be combined with the `~` unary operator (negation) and the binary
       
   199 operators `&` and `|` (respectivly 'and' and 'or') to build more complex
       
   200 selector. Of course complex selector may be combined too. Last but not least, you
       
   201 can write your own selectors.
       
   202 
       
   203 The `vregistry`
       
   204 ~~~~~~~~~~~~~~~
       
   205 
       
   206 At startup, the `vregistry` inspects a number of directories looking for
       
   207 compatible classes definition. After a recording process, the objects are
       
   208 assigned to registries so that they can be selected dynamically while the
       
   209 instance is running.
       
   210 
       
   211 In a cube, application object classes are looked in the following modules or
       
   212 packages:
       
   213 
       
   214 - `entities`
       
   215 - `views`
       
   216 - `sobjects`
       
   217 - `hooks`
       
   218 
       
   219 
       
   220 Once initialized, there are three common ways to retrieve some application object
       
   221 from a registry:
       
   222 
       
   223 * get the most appropriate object by specifying an identifier. In that case, the
       
   224   object with the greatest score is selected. There should always be a single
       
   225   appobject with a greater score than others for a particular context.
       
   226 
       
   227 * get all objects applying to a context by specifying a registry. In that case, a
       
   228   list of objects will be returned containing the object with the highest score
       
   229   (> 0) for each identifier in that registry.
       
   230 
       
   231 * get the object within a particular registry/identifier. In that case no
       
   232   selection process is involved, the vregistry will expect to find a single
       
   233   object in that cell.
       
   234 
       
   235 
       
   236 .. _RQLIntro:
       
   237 
       
   238 The RQL query language
       
   239 ----------------------
       
   240 
       
   241 **No need for a complicated ORM when you have a powerful query language**
       
   242 
       
   243 All the persistent data in a |cubicweb| instance is retrieved and modified by
       
   244 using the Relation Query Language.
       
   245 
       
   246 This query language is inspired by SQL but is on a higher level in order to
       
   247 emphasize browsing relations.
       
   248 
       
   249 
       
   250 db-api
       
   251 ~~~~~~
       
   252 
       
   253 The repository exposes a `db-api`_ like api but using the RQL instead of SQL.
       
   254 
       
   255 You basically get a connection using :func:`cubicweb.dbapi.connect` , then
       
   256 get a cursor to call its `execute` method which will return result set for the
       
   257 given rql query.
       
   258 
       
   259 You can also get additional information through the connection, such as the
       
   260 repository'schema, version configuration, etc.
       
   261 
       
   262 
       
   263 Result set
       
   264 ~~~~~~~~~~
       
   265 
       
   266 Every request made (using RQL) to the data repository returns an object we call a
       
   267 Result Set. It enables easy use of the retrieved data, providing a translation
       
   268 layer between the backend's native datatypes and |cubicweb| schema's EntityTypes.
       
   269 
       
   270 Result sets provide access to the raw data, yielding either basic Python data
       
   271 types, or schema-defined high-level entities, in a straightforward way.
       
   272 
       
   273 
       
   274 .. _ViewIntro:
       
   275 
       
   276 Views
       
   277 -----
       
   278 
       
   279 **CubicWeb is data driven**
       
   280 
       
   281 The view system is loosely coupled to data through the selection system explained
       
   282 above. Views are application objects with a dedicated interface to 'render'
       
   283 something, eg producing some html, text, xml, pdf, or whatsover that can be
       
   284 displayed to a user.
       
   285 
       
   286 The two main entry points of a view are:
       
   287 
       
   288 * `call()`, used to render a view on a context with no result set, or on a whole
       
   289   result set
       
   290 
       
   291 * `cell_call(row, col)`, used to render a view on a the cell with index `row` and
       
   292   `col` of the context's result set (remember result set may be seen as a two
       
   293   dimensions array).
       
   294 
       
   295 Then view may gets refined into different kind of objects such as `template`,
       
   296 `boxes`, `components`, which are more high-level abstraction useful to build
       
   297 the user interface in an object oriented way.
       
   298 
       
   299 
       
   300 .. _HookIntro:
       
   301 
       
   302 Hooks and operations
       
   303 --------------------
       
   304 
       
   305 **CubicWeb provides an extensible data repository**
       
   306 
       
   307 The data model defined using Yams types allows to express the data
       
   308 model in a comfortable way. However several aspects of the data model
       
   309 can not be expressed there. For instance:
       
   310 
       
   311 * managing computed attributes
       
   312 
       
   313 * enforcing complicated structural invariants
       
   314 
       
   315 * real-world side-effects linked to data events (email notification
       
   316   being a prime example)
       
   317 
       
   318 The hook system is much like the triggers of an SQL database engine,
       
   319 except that:
       
   320 
       
   321 * it is not limited to one specific SQL backend (every one of them
       
   322   having an idiomatic way to encode triggers), nor to SQL backends at
       
   323   all (think about LDAP or a Subversion repository)
       
   324 
       
   325 * it is well-coupled to the rest of the framework
       
   326 
       
   327 Hooks are also application objects registered on events such as after/before
       
   328 add/update/delete on entities/relations, server startup or shutdown, etc. As all
       
   329 application objects, they have a selector defining when they should be called or
       
   330 not.
       
   331 
       
   332 `Operations` may be instantiated by hooks to do further processing at different
       
   333 steps of the transaction's commit / rollback, which usually can not be done
       
   334 safely at the hook execution time.
       
   335 
       
   336 Hooks and operation are an essential building block of any moderately complicated
       
   337 cubicweb application.
       
   338 
       
   339 .. Note:
       
   340    RQL queries executed in hooks and operations are *unsafe* by default, e.g. the
       
   341    read and write security is deactivated unless explicitly asked.
       
   342   
       
   343 .. |cubicweb| replace:: *CubicWeb*