doc/book/en/intro/concepts/index.rst
brancholdstable
changeset 5422 0865e1e90674
parent 4985 02b52bf9f5f8
parent 5421 8167de96c523
child 5424 8ecbcbff9777
equal deleted inserted replaced
4985:02b52bf9f5f8 5422:0865e1e90674
     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|
       
     9 framework. To avoid confusion while reading this book, take time to go through
       
    10 the following definitions and use this section as a reference during your
       
    11 reading.
       
    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
       
    23 a whole with richer functionnalities than its parts. The cubes `cubicweb-blog`_
       
    24 and `cubicweb-comment`_ could be used to make a cube named *myblog* with
       
    25 commentable blog entries.
       
    26 
       
    27 The `|cubicweb| 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 your
       
    31 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| 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 Instances
       
    45 ---------
       
    46 
       
    47 An instance is a runnable application installed on a computer and based on a
       
    48 cube.
       
    49 
       
    50 The instance directory contains the configuration files. Several instances can
       
    51 be created and based on the same cube. For exemple, several software forges can
       
    52 be set up on one computer system based on the `cubicweb-forge`_ cube.
       
    53 
       
    54 .. _`cubicweb-forge`: http://www.cubicweb.org/project/cubicweb-forge
       
    55 
       
    56 Instances can be of three different types: all-in-one, web engine or data
       
    57 repository. For applications that support high traffic, several web (front-end)
       
    58 and data (back-end) instances can be set-up to share the load.
       
    59 
       
    60 .. image:: ../../images/archi_globale.en.png
       
    61 
       
    62 The command :command:`cubicweb-ctl list` also displays the list of instances
       
    63 installed on your system.
       
    64 
       
    65 On a Unix system, the instances are usually stored in the directory
       
    66 :file:`/etc/cubicweb.d/`. During development, the :file:`~/etc/cubicweb.d/`
       
    67 directory is looked up, as well as the paths in :envvar:`CW_INSTANCES_DIR`
       
    68 environment variable.
       
    69 
       
    70 The term application is used to refer to "something that should do something as a
       
    71 whole", eg more like a project and so can refer to an instance or to a cube,
       
    72 depending on the context. This book will try to use *application*, *cube* and
       
    73 *instance* as appropriate.
       
    74 
       
    75 Data Repository
       
    76 ---------------
       
    77 
       
    78 The data repository [1]_ provides access to one or more data sources (including
       
    79 SQL databases, LDAP repositories, Mercurial or Subversion version control
       
    80 systems, other |cubicweb| instance repositories, GAE's DataStore, etc).
       
    81 
       
    82 All interactions with the repository are done using the Relation Query Language
       
    83 (RQL). The repository federates the data sources and hides them from the
       
    84 querier, which does not realize when a query spans accross several data sources
       
    85 and requires running sub-queries and merges to complete.
       
    86 
       
    87 It is common to run the web engine and the repository in the same process (see
       
    88 instances of type all-in-one above), but this is not a requirement. A repository
       
    89 can be set up to be accessed remotely using Pyro (`Python Remote Objects`_) and
       
    90 act as a server.
       
    91 
       
    92 Some logic can be attached to events that happen in the repository, like
       
    93 creation of entities, deletion of relations, etc. This is used for example to
       
    94 send email notifications when the state of an object changes. See `Hooks` below.
       
    95 
       
    96 .. [1] not to be confused with a Mercurial repository or a Debian repository.
       
    97 .. _`Python Remote Objects`: http://pyro.sourceforge.net/
       
    98 
       
    99 Web Engine
       
   100 ----------
       
   101 
       
   102 The web engine replies to http requests and runs the user interface
       
   103 and most of the application logic.
       
   104 
       
   105 By default the web engine provides a default user interface based on
       
   106 the data model of the instance. Entities can be created, displayed,
       
   107 updated and deleted. As the default user interface is not very fancy,
       
   108 it is usually necessary to develop your own.
       
   109 
       
   110 Schema (Data Model)
       
   111 -------------------
       
   112 
       
   113 The data model of a cube is described as an entity-relationship schema using a
       
   114 comprehensive language made of Python classes imported from the yams_ library.
       
   115 
       
   116 .. _yams: http://www.logilab.org/project/yams/
       
   117 
       
   118 An `entity type` defines a set of attributes and is used in some relations.
       
   119 Attributes may be of the following types: `String`, `Int`, `Float`, `Boolean`,
       
   120 `Date`, `Time`, `Datetime`, `Interval`, `Password`, `Bytes`, `RichString`. See
       
   121 :ref:`yams.BASE_TYPES` for details.
       
   122 
       
   123 A `relation type` is used to define an oriented binary relation between two
       
   124 entity types.  The left-hand part of a relation is named the `subject` and the
       
   125 right-hand part is named the `object`.
       
   126 
       
   127 A `relation definition` is a triple (*subject entity type*, *relation type*, *object
       
   128 entity type*) associated with a set of properties such as cardinality,
       
   129 constraints, etc.
       
   130 
       
   131 Permissions can be set on entity types and relation types to control who will be
       
   132 able to create, read, update or delete entities and relations.
       
   133 
       
   134 Some meta-data necessary to the system is added to the data model. That includes
       
   135 entities like users and groups, the entities used to store the data model
       
   136 itself and attributes like unique identifier, creation date, creator, etc.
       
   137 
       
   138 When you create a new |cubicweb| instance, the schema is stored in the database.
       
   139 When the cubes the instance is based on evolve, they may change their data model
       
   140 and provide migration scripts that will be executed when the administrator will
       
   141 run the upgrade process for the instance.
       
   142 
       
   143 Registries and Objects
       
   144 ----------------------
       
   145 
       
   146 Application objects
       
   147 ~~~~~~~~~~~~~~~~~~~
       
   148 
       
   149 Beside a few core functionalities, almost every feature of the framework is
       
   150 achieved by dynamic objects (`application objects` or `appobjects`) stored in a
       
   151 two-levels registry (the `vregistry`). Each object is affected to a registry with
       
   152 an identifier in this registry. You may have more than one object sharing an
       
   153 identifier in the same registry, At runtime, appobjects are selected in the
       
   154 vregistry according to the context.
       
   155 
       
   156 Application objects are stored in the registry using a two-level hierarchy :
       
   157 
       
   158   object's `__registry__` : object's `id` : [list of app objects]
       
   159 
       
   160 The base class of appobjects is `AppObject` (module `cubicweb.appobject`).
       
   161 
       
   162 The `vregistry`
       
   163 ~~~~~~~~~~~~~~~
       
   164 
       
   165 At startup, the `registry` inspects a number of directories looking
       
   166 for compatible classes definition. After a recording process, the
       
   167 objects are assigned to registers so that they can be selected
       
   168 dynamically while the instance is running.
       
   169 
       
   170 Selectors
       
   171 ~~~~~~~~~
       
   172 
       
   173 Each appobject has a selector, that is used to compute how well the object fits
       
   174 a given context. The better the object fits the context, the higher the score.
       
   175 
       
   176 |cubicweb| provides a set of basic selectors that may be parametrized. Selectors
       
   177 can be combined with the binary operators `&` and `|` to build more complex
       
   178 selector that can be combined too.
       
   179 
       
   180 There are three common ways to retrieve some appobject from the repository:
       
   181 
       
   182 * get the most appropriate objects by specifying a registry and an identifier. In
       
   183   that case, the object with the greatest score is selected. There should always
       
   184   be a single appobject with a greater score than others.
       
   185 
       
   186 * get all appobjects applying to a context by specifying a registry. In
       
   187   that case, every object with the a postive score is selected.
       
   188 
       
   189 * get the object within a particular registry/identifier. In that case no
       
   190   selection process is involved, the vregistry will expect to find a single
       
   191   object in that cell.
       
   192 
       
   193 Selector sets are the glue that tie views to the data model. Using them
       
   194 appropriately is an essential part of the construction of well behaved cubes.
       
   195 
       
   196 When no score is higher than the others, an exception is raised in development
       
   197 mode to let you know that the engine was not able to identify the view to
       
   198 apply. This error is silenced in production mode and one of the objects with the
       
   199 higher score is picked.
       
   200 
       
   201 If no object has a positive score, ``NoSelectableObject`` exception is raised.
       
   202 
       
   203 If no object is found for a particular registry and identifier,
       
   204 ``ObjectNotFound`` exception is raised.
       
   205 
       
   206 In such cases you would need to review your design and make sure your views are
       
   207 properly defined.
       
   208 
       
   209 
       
   210 
       
   211 The RQL query language
       
   212 ----------------------
       
   213 
       
   214 **No need for a complicated ORM when you have a powerful query language**
       
   215 
       
   216 All the persistent data in a |cubicweb| instance is retrieved and modified by using the
       
   217 Relation Query Language.
       
   218 
       
   219 This query language is inspired by SQL but is on a higher level in order to
       
   220 emphasize browsing relations.
       
   221 
       
   222 db-api
       
   223 ~~~~~~
       
   224 
       
   225 The repository exposes a `db-api`_ like api but using the RQL instead of SQL.
       
   226 XXX feed me
       
   227 
       
   228 Result set
       
   229 ~~~~~~~~~~
       
   230 
       
   231 Every request made (using RQL) to the data repository returns an
       
   232 object we call a Result Set. It enables easy use of the retrieved
       
   233 data, providing a translation layer between the backend's native
       
   234 datatypes and |cubicweb| schema's EntityTypes.
       
   235 
       
   236 Result sets provide access to the raw data, yielding either basic
       
   237 Python data types, or schema-defined high-level entities, in a
       
   238 straightforward way.
       
   239 
       
   240 
       
   241 Views
       
   242 -----
       
   243 
       
   244 **CubicWeb| is data driven**
       
   245 
       
   246 The view system is loosely coupled to data through a selection
       
   247 system. Views are, in essence, defined by an id, a selection predicate
       
   248 and an entry point (generaly producing html).
       
   249 
       
   250 XXX feed me.
       
   251 
       
   252 
       
   253 Hooks
       
   254 -----
       
   255 
       
   256 **CubicWeb provides an extensible data repository**
       
   257 
       
   258 The data model defined using Yams types allows to express the data
       
   259 model in a comfortable way. However several aspects of the data model
       
   260 can not be expressed there. For instance:
       
   261 
       
   262 * managing computed attributes
       
   263 
       
   264 * enforcing complicated structural invariants
       
   265 
       
   266 * real-world side-effects linked to data events (email notification
       
   267   being a prime example)
       
   268 
       
   269 The hook system is much like the triggers of an SQL database engine,
       
   270 except that:
       
   271 
       
   272 * it is not limited to one specific SQL backend (every one of them
       
   273   having an idiomatic way to encode triggers), nor to SQL backends at
       
   274   all (think about LDAP or a Subversion repository)
       
   275 
       
   276 * it is well-coupled to the rest of the framework
       
   277 
       
   278 Hooks are basically functions that dispatch on both:
       
   279 
       
   280 * events : after/before add/update/delete on entities/relations
       
   281 
       
   282 * entity or relation types
       
   283 
       
   284 They are an essential building block of any moderately complicated
       
   285 cubicweb application.
       
   286 
       
   287 
       
   288 .. _RunMode:
       
   289 
       
   290 Running mode
       
   291 ------------
       
   292 
       
   293 A running mode is a predifined set of configuration telling where it should look
       
   294 for various resources, such as cubes, instances, etc. To ease development with
       
   295 the framework, there are two running modes with |cubicweb|:
       
   296 
       
   297 * 'user', resources are searched / created in the user home directory:
       
   298   - instances are stored in :file:`~/etc/cubicweb.d`
       
   299   - temporary files (such as pid file) in :file:`/tmp`
       
   300 
       
   301 * 'system', resources are searched / created in the system directories (eg usually requiring root access):
       
   302   - instances are stored in :file:`/etc/cubicweb.d`
       
   303   - temporary files (such as pid file) in :file:`/var/run/cubicweb`
       
   304 
       
   305 Cubes search path is also affected, see the :ref:Cube section.
       
   306 
       
   307 By default, the mode automatically set to 'user' if a :file:`.hg` directory is found
       
   308 in the cubicweb package, else it's set to 'system'. You can force this by setting
       
   309 the :envvar:`CW_MODE` environment variable to either 'user' or 'system'.
       
   310 
       
   311 If you've a doubt about the mode you're currently running, check the first line
       
   312 outputed by the :command:`cubicweb-ctl list` command.
       
   313 
       
   314 Notice that each resource path may be explicitly set using an environment
       
   315 variable if the default doesn't suit your needs.
       
   316 
       
   317 .. |cubicweb| replace:: *CubicWeb*