home *** CD-ROM | disk | FTP | other *** search
- <?xml version="1.0" encoding="UTF-8"?>
- <!--
- Copyright 1999-2004 The Apache Software Foundation
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
- <!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.0//EN" "document-v10.dtd">
-
- <document>
-
- <header>
- <title>Database Actions</title>
- <authors>
- <person name="Christian Haul" email="haul@apache.org"/>
- </authors>
- </header>
-
- <body>
- <s1 title="Introduction">
- <p>
- Two different sets of actions exist, that deal with (object) relational
- database access through JDBC. The original database actions provide a
- relatively simple interface to store, modify, delete and retrieve data.
- They are oriented towards usage of request parameters for input and
- request attributes together with sitemap variables for output and do
- not support auto increment column types. In addition, the description of
- the database structure is split over several files since these actions
- attempt to use all tables in a provided description.
- </p>
- <p>
- The modular database actions provide similar functionality. In contrast
- to the original actions they allow to store the database meta data in a
- single file and to switch input and output flexible through the use of
- modules. Even for auto increment columns specific modules exist that
- cover a wide range of database management systems.
- </p>
- <p>
- For an overview of column types supported by the modular database
- actions, see javadocs for JDBCTypeConversions. The types supported by
- the original actions are documented in AbstractDatabaseAction.
- </p>
- </s1>
-
- <s1 title="Original Database Actions">
- <p>
- The original database actions have evolved quite a bit and at different
- speeds. The add action is certainly the most complete one, providing
- support for multiple tables and rows. However, the interface has become
- a bit inconsistent.
- </p>
- <p>
- If an error occurs, the original database actions will throw an
- exception.
- </p>
- <s2 title="Describing the Structure of your DB - descriptor.xml">
- <p>
- The key to database actions is a file that describes database meta
- data in XML. The original actions will ignore all but the first table
- and act only on one row. Only the add action will try to access all
- tables that are contained in this description. As a consequence, each
- HTML form needs to have a corresponding descriptor file if different
- tables are affected.
- </p>
- <p>
- The file name has no meaning and does not need to be
- <code>descriptor.xml</code> - it can even be a Cocoon pipeline. The
- name of the root element in a descriptor file is ignored. Only
- <code>table</code> elements nested on first level inside the root
- element are parsed by the actions. All unknown elements or attributes
- are ignored.
- </p>
- <p>
- For each table a <code>table</code> element needs to be present.
- </p>
- <source>
- <![CDATA[
- <?xml version="1.0"?>
-
- <employee>
- <connection>personnel</connection>
- <table name="employee">
- <keys>
- <key param="employee" dbcol="id" type="int" mode="manual"/>
- </keys>
- <values>
- <value param="name" dbcol="name" type="string"/>
- <value param="department" dbcol="department_id" type="int"/>
- </values>
- </table>
- </employee>
- ]]>
- </source>
- <p>
- Describes a single table named "employee". In addition a database
- connection is specified. See <link
- href="../../developing/datasources.html">here</link> for more
- information on database connections.
- </p>
-
- <s3 title="Key Columns">
- <p>
- Tables may or may not have key columns. A key column is a column
- that is part of the primary key. Actually, candidate keys should do
- as well.
- </p>
- <p>
- All key columns are contained in a <code>keys</code> child element
- of the <code>table</code> element. Each column has a
- <code>key</code> element to define its properties. The
- <code>dbcol</code> attribute holds the column name,
- <code>type</code> is the JDBC type name for this column (have a
- look at AbstactDatabaseAction source for valid type names),
- <code>param</code> specifies the name of the request parameter to
- use, and <code>mode</code> sets how the value for this column is
- obtained on adding a row.
- </p>
- <p>
- Through the mode attribute the behaviour of the add action can be
- changed.
- </p>
- <p>
- Default mode is "automatic" and to let the database create the key
- value by setting this value to <code>null</code>. The created value
- can not be read back from the database and will not be available as
- request attribute or sitemap variable.
- </p>
- <p>
- A mode of "manual" will query the database for the maximum current
- value, add 1 to it and use that for a value.
- </p>
- <p>
- A mode of "form" will use the corresponding request parameter.
- </p>
- <p>
- A mode of "request-attribute" will use the corresponding request
- attribute. The name specified in the <code>param</code> attribute
- will be automatically prefixed with the class name.
- </p>
- <p>
- Key values will be propagated to sitemap variables and - prefixed
- with the class name - request attributes.
- </p>
- </s3>
- <s3 title="Other Columns">
- <p>
- All other columns are contained in a <code>values</code> child
- element of the <code>table</code> element. Each column has a
- <code>value</code> element to define its properties. Properties are
- similar to those for key columns. A <code>mode</code> attribute
- does not exist for value columns. Instead, request parameters and
- request attributes are tried in this order for the specified
- parameter.
- </p>
- <p>
- Request attribute names are <em>not</em> prefixed with the class
- name. Thus, to insert the value of a key column of the previous row
- or previous table into a value column, it needs to be named
- <code>org.apache.cocoon.acting.AbstractDatabaseAction:key:table:dbcol</code>.
- </p>
- <p>
- Value columns are propagated to request attributes with class name
- prefix. They are not available for the sitemap.
- </p>
- </s3>
- </s2>
- </s1>
- <s1 title="Modular Database Actions">
- <p>
- The modular database actions were mainly created to make auto increment
- columns available, handle input and output flexibly, and have a
- consistent interface. A successful action will return the number of
- rows affected in a sitemap parameter named <code>row-count</code>. The
- added features required to change the descriptor file format in
- incompatible ways.
- </p>
- <p>
- It can be configured if an exception will be thrown when an error
- occurs.
- </p>
- <s2 title="Describing the Structure of your DB - descriptor.xml">
- <p>
- Like the original actions, the modular actions need meta data in an
- XML file. However, that file may contain any number of tables, not
- just the ones needed for a single request. The tables actually used
- are referenced through a <code>table-set</code>. Unknown elements and
- attributes are ignored. This way a descriptor file can be shared with
- other actions like the form validator.
- </p>
- <p>
- For the flexible input and output handling, the modular database
- actions rely on <link href="../concepts/modules.html">modules</link>.
- Have a look at those before proceeding.
- </p>
- <p>
- The following is a snippet from a descriptor file.
- </p>
- <source>
- <![CDATA[
- <root>
- <connection>personnel</connection>
- <table name="user" alias="user">
- <keys>
- <key name="uid" type="int" autoincrement="true">
- <mode name="auto" type="autoincr"/>
- </key>
- </keys>
- <values>
- <value name="name" type="string"></value>
- <value name="firstname" type="string"></value>
- <value name="uname" type="string"></value>
- </values>
- </table>
- ]]>
- </source>
- <p>
- The <code>table</code> element has an additional attribute
- <code>alias</code> which is an alternative name to reference
- the table from a table set. The descriptor file is searched
- top down for tables whose <code>name</code> or
- <code>alias</code> match. The <code>alias</code>n attribute
- is useful if a complex join expression is used as table
- name. In such a case modifications like update, insert,
- delete will likely fail.
- </p>
- <p>
- Another application of aliases if different numbers of columns should
- be affected by an operation. or if a table contains several candidate
- keys that are used alternatively. This way, different views to a
- table can be created.
- </p>
- <s3 title="Key Columns">
- <p>
- The descriptor file resembles the one for the original actions. One
- major difference is the absence of <code>dbcol</code> and
- <code>param</code> attributes. Instead there is a <code>name</code>
- attribute which corresponds to the <code>dbcol</code> attribute and
- specifies the database column name.
- </p>
- <p>
- If a column is an auto increment column, the similar named attribute
- indicates this. Auto increment columns will be handled differently
- on insert operations.
- </p>
- <p>
- Instead of specifying a parameter name, the actions support to use
- different input modules for each operation through the nested
- <code>mode</code> elements. This is described in more detail below.
- </p>
- <p>
- Note here though, that not every column needs a <code>mode</code>
- element: The actions default to the module defined as
- <code>request</code> which is in a default installation to obtain
- the values from request parameters. The name of the parameter
- defaults to table name dot column name.
- </p>
- </s3>
- <s3 title="Other Columns">
- <p>
- Apart from the fact that the auto increment columns are only
- supported for key columns, everything said above applies to value
- columns as well.
- </p>
- </s3>
- <s3 title="Operation Mode Types">
- <p>
- Basically, two different mode types exist:
- <code>autoincrement</code> which is used whenever data shall be
- inserted into a table and this particular key column has the
- auto increment attribute set and <code>others</code> for all other
- requirements.
- </p>
- <p>
- In addition, a table-set can specify different mode types to use
- instead of the predefined type names. Through this, and the fact
- that every mode can specify a different input module, it is easy to
- use different input modules for different tasks and forms.
- </p>
- <p>
- One special mode type name exists that matches all requested ones:
- <code>all</code> This makes it easier to configure only some
- columns differently for each table-set.
- </p>
- </s3>
- <s3 title="How to obtain Values">
- <p>
- As said above, these actions default to reading from request
- parameters with a default parameter name. By specifying
- <code>mode</code> elements, this can be overridden. Any component
- that implements the <code>InputModule</code> interface can be used
- to obtain values. How to make such modules known to Apache Cocoon
- is described <link href="../concepts/modules.html">elsewhere</link>.
- </p>
- <p>
- Beside using different input modules, their parameters can be set
- in place, for example to override parameter names, configure a
- random generator or a message digest algorithm.
- </p>
-
- <source>
- <![CDATA[
- <table name="user_groups">
- <keys>
- <key name="uid" type="int">
- <mode name="request" type="request">
- <parameter>user_groups.uid</parameter>
- </mode>
- <mode name="attribute" type="attrib">
- <parameter>org.apache.cocoon.components.modules.output.OutputModule:user.uid[0]</parameter>
- </mode>
- </key>
- <key name="gid" type="int" set="master">
- <mode name="request" type="all">
- <parameter>user_groups.gid</parameter>
- </mode>
- </key>
- </keys>
- </table>
- ]]>
- </source>
- <p>
- The above example shows just that: the <code>parameter</code>
- element is not read by the database action itself but the
- complete <code>mode</code> configuration object is passed to the
- input module. Both the request attribute and the request parameter
- input modules understand this parameter attribute which takes
- precedence over the default one.
- </p>
- <p>
- Another feature when obtaining values is tied to the
- <code>type</code> attribute: Different modes can be used in
- different situations. The basic setup uses two different mode
- types: <code>autoincrement</code> when inserting in key columns
- that have an indicator that they are indeed auto increment columns
- and <code>others</code> for insert operations on all other columns
- and all other operations on all columns.
- </p>
- <p>
- Table-sets can override the default names for these two mode type
- name categories with arbitrary names except the special name
- <code>all</code>. A mode that carries the type name "all" is used
- with all requested type names. Lookup obeys first match principle
- so that all modes are tested from top to bottom and the first that
- matches is used.
- </p>
- </s3>
- <s3 title="How to store Values e.g. in your Session">
- <p>
- All modular database action can be configured to use any component
- that implements the <code>OutputModule</code> interface to store
- values. The output module is chosen on declaring the action in the
- sitemap or dynamically with a sitemap parameter. If no output
- module is specified, the default it to use the request attribute
- module.
- </p>
- <p>
- The interface does not allow to pass configuration information to
- the output module. This has to be done when the module is declared
- e.g. in cocoon.xconf.
- </p>
- </s3>
- <s3 title="Inserting Multiple Rows - Sets">
- <p>
- Once common task is to work on more than one row. If the rows are
- in different tables, this is catered for by table-sets. Operating
- on multiple rows of one table requires to mark columns that should
- vary and among those one, that determines the number of rows to
- work on.
- </p>
- <p>
- This is done with sets. All columns that cary a <code>set</code>
- attribute can vary, those, that don't, are kept fixed during the
- operation. The column that is used to determine the number of rows
- is required to have a value of <code>master</code> while all others
- need to have a value of <code>slave</code> for the set
- attribute. There may be only one master in a set.
- </p>
- <p>
- Sets can be tagged either on column or on mode level but not both
- for a single column.
- </p>
- </s3>
- <s3 title="Select Your Tables - Table-Sets">
- <p>
- Tables that should be used during an operation can be grouped
- together with a table-set. A table-set references tables by their
- name or their alias.
- </p>
- <p>
- In addition, a table-set can override the mode type names for the
- two categories "autoincrement" and "others".
- </p>
- <p>
- Operations spanning multiple tables in a table-set are done in a
- single transaction. Thus, if one fails, the other is rolled back.
- </p>
- <source>
- <![CDATA[
-
- <table name="groups">
- <keys>
- <key name="gid" type="int" autoincrement="true">
- <mode name="auto" type="autoincr"/>
- </key>
- </keys>
- <values>
- <value name="gname" type="string"/>
- </values>
- </table>
-
- <table-set name="user">
- <table name="user"/>
- </table-set>
-
- <table-set name="groups">
- <table name="groups"/>
- </table-set>
-
- <table-set name="user+groups">
- <table name="user"/>
- <table name="user_groups" others-mode="attrib"/>
- </table-set>
-
- <table-set name="user_groups">
- <table name="user_groups" others-mode="request"/>
- </table-set>
-
- </root>
- ]]>
- </source>
- </s3>
- </s2>
- </s1>
- </body>
- </document>
-