haul 2002/06/04 02:09:11
Modified: src/documentation/xdocs/userdocs/xsp esql.xml
Log:
Improved docs.
Revision Changes Path
1.5 +319 -123 xml-cocoon2/src/documentation/xdocs/userdocs/xsp/esql.xml
Index: esql.xml
===================================================================
RCS file: /home/cvs/xml-cocoon2/src/documentation/xdocs/userdocs/xsp/esql.xml,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- esql.xml 5 Feb 2002 16:59:40 -0000 1.4
+++ esql.xml 4 Jun 2002 09:09:11 -0000 1.5
@@ -7,27 +7,30 @@
<person name="Robin Green" email="[EMAIL PROTECTED]"/>
</authors></header><body>
- <s1 title="Description">
+ <s1 title="Description">
- <p>The ESQL logicsheet is an
-XSP logicsheet that performs sql queries and serializes their
-results as XML. This allows you to work with data from a wide variety of different
sources when using Apache Cocoon.
-</p>
-
- <p>It has a number of important advantages over the old (deprecated) SQL
logicsheet and SQL processor.
- For example, it allows you to mix esql with other logicsheets. It also
- supports prepared statements (which gives you automatic parameter escaping),
multiple encodings
- in a single query and even multiple resultsets on one statement (if supported
from database)!</p>
-
- <p>The name was chosen merely to emphasise the fact that this is an extended
version of the old sql logicsheet -
- esql still uses standard SQL syntax. In fact, it is just a conversion
wrapper around your JDBC database
- driver, so it supports no more and no less SQL syntax than your JDBC driver
supports.
+ <p>The ESQL logicsheet is an XSP logicsheet that performs sql queries and
+ serializes their results as XML. This allows you to work with data from a
+ wide variety of different sources when using Apache Cocoon.
+ </p>
+
+ <p>It has a number of important advantages over the old (deprecated) SQL
+ logicsheet and SQL processor. For example, it allows you to mix esql with
+ other logicsheets. It also supports prepared statements (which gives you
+ automatic parameter escaping), multiple encodings in a single query and
+ even multiple resultsets on one statement (if supported from database)!</p>
+
+ <p>The name was chosen merely to emphasise the fact that this is an
+ extended version of the old sql logicsheet - esql still uses standard SQL
+ syntax. In fact, it is just a conversion wrapper around your JDBC database
+ driver, so it supports no more and no less SQL syntax than your JDBC driver
+ supports.
</p>
- </s1>
+ </s1>
- <s1 title="Installation">
- <p>Check your <code>cocoon.xconf</code> for this line and add it if
it's not already there:</p>
- <source><![CDATA[
+ <s1 title="Installation">
+ <p>Check your <code>cocoon.xconf</code> for this line and add it if it's not
already there:</p>
+ <source><![CDATA[
<builtin-logicsheet>
<parameter name="prefix" value="esql"/>
<parameter name="uri" value="http://apache.org/cocoon/SQL/v2"/>
@@ -35,38 +38,43 @@
value="resource://org/apache/cocoon/components/language/markup/xsp/java/esql.xsl"/>
</builtin-logicsheet>
]]></source>
- </s1>
+ </s1>
- <s1 title="Configuration">
- <p>Map the</p>
- <source>http://apache.org/cocoon/SQL/v2</source>
- <p>namespace to the esql prefix. Elements in the esql taglib namespace
will be interpreted as input to
-the esql taglib and will be stripped from the output.</p>
- <p>This is typically done like this:</p>
- <source><![CDATA[
+ <s1 title="Configuration">
+ <p>Map the</p>
+ <source>http://apache.org/cocoon/SQL/v2</source>
+ <p>namespace to the esql prefix. Elements in the esql taglib namespace will be
interpreted as input to
+ the esql taglib and will be stripped from the output.</p>
+ <p>This is typically done like this:</p>
+ <source><![CDATA[
<xsp:page
language="java"
xmlns:xsp="http://apache.org/xsp"
- xmlns:esql="http://apache.org/cocoon/SQL/v2"
+ xmlns:esql="http://apache.org/cocoon/SQL/v2"
>
. . .
</xsp:page>
]]></source>
- </s1>
- <s1 title="Usage and Examples">
- <p>At the moment documentation on esql is quite thin on the ground -
however, it should be enough to get
- you started.
- In the <code>docs/samples/xsp</code> directory you will find
<code>esql.xsp</code>, which is an example
- of two esql queries, demonstrating "nested" queries and dynamic prepared
statements. However, much more
- comprehensive is the <strong>schema</strong> in <code>esql.xsd</code>
which is a formal specification,
- written in the W3C standard language XML Schema, of every single esql
element and attribute.
- It is fairly human-readable and includes comments for the purpose of each
tag.</p>
-
- <p>A fairly common example is to list a query result in a table. Notice
that esql:results and esql:no-results
- are mutual exclusive. So only one of them will be in your XML tree. This
example takes a connection from a
- datasource defined in <code>cocoon.xconf</code>:</p>
+ </s1>
- <source><![CDATA[
+ <s1 title="Usage and Examples">
+ <p>At the moment documentation on esql is quite thin on the ground -
+ however, it should be enough to get you started. In the
+ <code>docs/samples/xsp</code> directory you will find
+ <code>esql.xsp</code>, which is an example of two esql queries,
+ demonstrating "nested" queries and dynamic prepared statements. However,
+ much more comprehensive is the <strong>schema</strong> in
+ <code>esql.xsd</code> which is a formal specification, written in the W3C
+ standard language XML Schema, of every single esql element and attribute.
+ It is fairly human-readable and includes comments for the purpose of each
+ tag.</p>
+
+ <p>A fairly common example is to list a query result in a table. Notice that
+ esql:results and esql:no-results are mutual exclusive. So only one of them
+ will be in your XML tree. This example takes a connection from a datasource
+ defined in <code>cocoon.xconf</code>:</p>
+
+ <source><![CDATA[
<esql:connection>
<esql:pool>connectionName</esql:pool>
<esql:execute-query>
@@ -88,24 +96,129 @@
</esql:connection>]]>
</source>
- <p>For more complex lists, often nested queries are
- needed. Esql allows arbitrary nesting of queries. However,
- you can do table joins and then insert a header and footer
- whenever a "watched" column value changes using the
- <code><esql:group/></code> and
- <code><esql:member/></code> tags. It follows the
- nesting ideology of <code><xsp:logic>
- ... <xsp:content></></></code>You can
- nest <code><esql:group></code> and
- <code><esql:member></code> indefinately.</p>
+ <s2 title="Refering to results">
+
+ <p>A select query usually returns one ResultSet. This case is handled by
+ the <code>esql:results</code> tag and its content. However, many special
+ cases exist, e.g. an error occurs or an update query is used. Esql
+ provides different tags for these cases.
+ </p>
+
+ <p>If an empty result set is returned, the <code>esql:no-results</code>
+ block is used.</p>
+
+ <s3 title="Errors">
+ <p>In case of an error, usually signalled by an Exception during setup or
+ execution of a query, the <code>esql:error-results</code> block is
+ evaluated. If no such tag exists, the exception is rethrown and
+ processing is stopped. Withing the tag, <code>esql:get-message</code>,
+ <code>esql:get-stacktrace</code>, and <code>esql:to-string</code> allow
+ access to the error message.</p>
+ </s3>
+
+ <s3 title="Limiting the number of rows returned">
+
+ <p>Esql allows to display only a part of the result set using the
+ <code>esql:use-limit-clause</code>. If your DBMS is supported, the DBMS
+ generates only the indicated rows, otherwise a number of rows are skipped
+ and retrieval is stopped after a given number of rows. It works like a
+ fixed-size window to the result set, paging through it.</p>
+
+ <p>These parameters are set for a connection.</p>
+
+ <p>If the <code>esql:use-limit-clause</code> is empty or set to "auto",
+ esql tries to determine automatically which method to use, depending on
+ the connection URL.</p>
+
+ <p><code>esql:skip-rows</code> and <code>esql:max-rows</code> tags specify
+ how many rows should be skipped at the beginning and how many rows should
+ be retrieved at maximum.</p>
+
+ <p>In this context the <code>esql:previous-results</code> and
+ <code>esql:more-results</code> blocks hold code and content that is only
+ used if this sliding window has previous or following windows.</p>
+
+ </s3>
+
+ <source><![CDATA[
+<esql:connection>
+ <esql:pool>connectionName</esql:pool>
+ <esql:execute-query>
+ <esql:query>SELECT mycolumn1,mycolumn2 FROM table</esql:query>
+ <esql:use-limit-clause>auto</esql:use-limit-clause>
+ <esql:skip-rows><xsp:expr>skiprows</xsp:expr></esql:skip-rows>
+ <esql:max-rows>10</esql:max-rows>
+ <esql:results>
+ <table>
+ <esql:row-results>
+ <esql:previous-results>previous rows available</esql:previous-results>
+ <esql:more-results>more rows available</esql:more-results>
+ <tr>
+ <td><esql:get-string column="mycolumn1"/></td>
+ <td><esql:get-string column="mycolumn2"/></td>
+ </tr>
+ </esql:row-results>
+ </table>
+ </esql:results>
+ <esql:error-results>An error occurred</esql:error-results>
+ <esql:no-results>
+ <p>Sorry, no results!</p>
+ </esql:no-results>
+ </esql:execute-query>
+</esql:connection>]]>
+</source>
+
+ <s3 title="Updates">
+ <p>In JDBC, updates, inserts, and deletes are "update queries". For those,
+ no results are available but an update count is returned, indicating,
+ how many rows were affected.</p>
+
+ <p>Code or content that depends on this has to be placed inside the
+ <code>esql:update-results</code> tag. It is used whenever at least one
+ row was affected. The update count can be accessed through the
+ <code>esql:get-update-count</code> tag.
+ </p>
+
+ <p>If no rows where affected, the <code>esql:no-results</code> block is
+ used.</p>
+ </s3>
+
+
+ <source><![CDATA[
+<esql:connection>
+ <esql:pool>connectionName</esql:pool>
+ <esql:execute-query>
+ <esql:query>update table set price=price*1.17</esql:query>
+ <esql:error-results>An error occurred</esql:error-results>
+ <esql:update-results>
+ <esql:get-update-count/> prices adjusted.
+ </esql:update-results>
+ <esql:no-results>
+ <p>Sorry, no prices adjusted!</p>
+ </esql:no-results>
+ </esql:execute-query>
+</esql:connection>]]>
+</source>
+
+ </s2>
- <source><![CDATA[
+ <s2 title="Groups">
+ <p>For more complex lists, often nested queries are needed. Esql allows
+ arbitrary nesting of queries. However, you can do table joins and then
+ insert a header whenever a "watched" column value changes using the
+ <code><esql:group/></code> and <code><esql:member/></code>
+ tags. It follows the nesting ideology of <code><xsp:logic> ...
+ <xsp:content></></></code>You can nest
+ <code><esql:group></code> and <code><esql:member></code>
+ indefinately.</p>
+
+ <source><![CDATA[
<esql:execute-query>
<esql:query>
- select committeeName, title, firstName, middleName, lastName, suffix,
-status from committeeMember left join directoryInformation using(userid)
-left join committee on committee.id=committeeMember.committeeid order by
-committeeName asc
+ select committeeName, title, firstName, middleName, lastName, suffix, status
+ from committeeMember left join directoryInformation using(userid)
+ left join committee on committee.id=committeeMember.committeeid
+ order by committeeName asc
</esql:query>
<esql:results>
<esql:row-results>
@@ -126,97 +239,180 @@
</esql:row-results>
</esql:results>
</esql:execute-query>]]>
- </source>
+ </source>
- <s2 title="Stored Procedure Support">
- <p>In order to use stored procedures replace
- <code><esql:query/></code> with
- <code><esql:call/></code>, use either DBMS specific syntax or
- JDBC escape syntax <code>{? = foo(?)}</code>. If your jdbc driver
- requires to use the <code>executeQuery()</code> method instead of
- the <code>execute()</code> method (like e.g. INFORMIX does), set
- <code>needs-query="true"</code> attribute.</p>
-
- <p>If a result set is returned through the (only) return parameter of
- a stored procedure, e.g. <code>resultset-from-object="1"</code> as attribute
- to <code><esql:call/></code>to automatically use this result
- set. For a more general alternative see further below.</p>
-
- <p>Parameters for a stored procedure call may be of
- <code>direction="in|out|inout"</code> with the usual JDBC meaning. In
- addition a <code>type</code> needs to be supplied as well. This would
- be the same "XXX" as used in a <code>get-XXX</code> JDBC-method
- call.</p>
-
- <p><code><esql:call-results/></code> (child of
- <code><esql:execute-query/></code>) may contain code that will
- always be executed whether the query returned a result or not. For
- example most stored procedures will not return a result set but
- several out parameters.</p>
-
- <p>all <code><esql:get-xxx/></code> tags accept new attribute
- <code>from-call="yes"</code> to indicate that the value is retrieved
- from the CallableStatement rather than the current
- ResultSet. Obviously, this only works after a call to a stored
- procedure.</p>
-
- <p>Retrieve a ResultSet from any column and use it like the result of a
- nested query. Supported child elements are
- <code><esql:row-results/></code> and
- <code><esql:no-results/></code>. Otherwise it behaves
- exactly like nesting queries. Thus the <code>ancestor</code>
- attribute can be used to access e.g. the original query.</p>
+ <p>One important limitation of the grouping feature is, that <em>no access
+ to a column may appear after closing a group.</em> The value will belong
+ to the following row or cause an error if no next row exists. If this is
+ needed, consider swapping columns using XSLT. Hence the following example
+ is illegal:</p>
+ </s2>
+ <source><![CDATA[
+<esql:execute-query>
+ <esql:query>
+ select committeeName, committeeTitle, title, firstName, middleName,
+ lastName, suffix, status
+ from committeeMember left join directoryInformation using(userid)
+ left join committee on committee.id=committeeMember.committeeid
+ order by committeeName asc
+ </esql:query>
+ <esql:results>
+ <esql:row-results>
+ <esql:group group-on="committeeName">
+ <h2><esql:get-string column="committeeName"/></h2>
+ <ul>
+ <esql:member>
+ <li>
+ <esql:get-string column="title"/>
+ <esql:get-string column="firstName"/>
+ <esql:get-string column="middleName"/>
+ <esql:get-string column="lastName"/>
+ <esql:get-string column="suffix"/>
+ </li>
+ </esql:member>
+ </ul>
+ </esql:group>
+ <esql:get-string column="committeeTitle"/><!-- illegal !! -->
+ </esql:row-results>
+ </esql:results>
+</esql:execute-query>]]>
+ </source>
+
+
+ <s2 title="Stored Procedure Support">
+ <p>In order to use stored procedures replace
+ <code><esql:query/></code> with <code><esql:call/></code>, use
+ either DBMS specific syntax or JDBC escape syntax <code>{? =
+ foo(?)}</code>. If your jdbc driver requires to use the
+ <code>executeQuery()</code> method instead of the <code>execute()</code>
+ method (like e.g. INFORMIX does), set <code>needs-query="true"</code>
+ attribute.</p>
+
+ <p>If a result set is returned through the (only) return parameter of a
+ stored procedure, e.g. <code>resultset-from-object="1"</code> as attribute
+ to <code><esql:call/></code>to automatically use this result set.
+ For a more general alternative see further below.</p>
+
+ <p>Parameters for a stored procedure call may be of
+ <code>direction="in|out|inout"</code> with the usual JDBC meaning. In
+ addition a <code>type</code> needs to be supplied as well. This would be
+ the same "XXX" as used in a <code>get-XXX</code> JDBC-method call.</p>
+
+ <p><code><esql:call-results/></code> (child of
+ <code><esql:execute-query/></code>) may contain code that will
+ always be executed whether the query returned a result or not. For example
+ most stored procedures will not return a result set but several out
+ parameters.</p>
+
+ <p>all <code><esql:get-xxx/></code> tags accept new attribute
+ <code>from-call="yes"</code> to indicate that the value is retrieved from
+ the CallableStatement rather than the current ResultSet. Obviously, this
+ only works after a call to a stored procedure.</p>
+
+ <p>Retrieve a ResultSet from any column and use it like the result of a
+ nested query with the <code>esql:use-results</code> tag. It behaves
+ exactly like nesting queries. Thus the <code>ancestor</code> attribute can
+ be used to access e.g. the original query.</p>
- <p>Example:</p>
-<source><![CDATA[
+
+ <p>Example:</p>
+ <source><![CDATA[
<esql:call>{? = foo(<esql:parameter direction="in"
type="Int"><xsp:expr>1</xsp:expr></esql:parameter>)}
</esql:call>
<esql:call-results>
- <esql:results>
+ <esql:use-results>
<esql:result><xsp:expr>(ResultSet)<esql:get-object column="1"
from-call="true"/></xsp:expr></esql:result>
<esql:row-results>
<esql:get-string column="1"/>
</esql:row-results>
- </esql:results>
+ </esql:use-results>
</esql:call-results>
]]></source>
- <p>Example:</p>
-<source><![CDATA[
+
+ <p>Example:</p>
+ <source><![CDATA[
<esql:query>select name, list_of_aliases from table</esql:query>
<esql:results>
<esql:row-results>
<p>
<esql:get-string column="name"/>:
- <esql:results>
+ <esql:use-results>
<esql:result><xsp:expr><esql:get-array
column="list_of_aliases"/>.getResultSet()</xsp:expr></esql:result>
<esql:row-results>
<esql:get-string column="1"/>
</esql:row-results>
- </esql:results>
+ </esql:use-results>
</p>
</esql:row-results>
</esql:results>
]]></source>
- </s2>
-
- <p>The ultimate reference, is of course the source code, which is an XSLT
logicsheet contained in the
- file
<code>src/org/apache/cocoon/components/language/markup/xsp/java/esql.xsl</code></p>
- <p>Of course, we would be very grateful for any improvements on this
documentation
- or further examples - please send them to
- <link
href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</link>!</p>
+ </s2>
- </s1>
+ <s2 title="Multiple Results">
+ <p>If multiple results are returned from a stored procedure or a query, the
+ <code>esql:results</code> block is reused. However, it is supported to
+ have different blocks for each result. Since a result can either be a
+ ResultSet or an UpdateCount, both are counted independently. The nth
+ ResultSet will be handled by the nth <code>esql:results</code> block, or -
+ if there are fewer blocks - the last one.</p>
+
+ <p>The same holds true for <code>esql:update-results</code> and
+ <code>esql:no-results</code> blocks as well.</p>
+
+
+ <p>Example: Suppose stored procedure <code>bar</code> returns an update
+ count, another update count, a result set, an update count, and a
+ last result set.</p>
+
+ <source><![CDATA[
+<esql:call>{? = bar(<esql:parameter direction="in"
+type="Int"><xsp:expr>1</xsp:expr></esql:parameter>)}
+</esql:call>
+<esql:results>
+ <!-- this is used for the first result set -->
+</esql:results>
+<esql:results>
+ <!-- this is used for the second and
+ all following result sets -->
+</esql:results>
+<esql:update-results>
+ <!-- this is used for the first update count -->
+</esql:update-results>
+<esql:no-results>
+ <!-- this is used for the first update count -->
+</esql:no-results>
+<esql:update-results>
+ <!-- this is used for the second and
+ all following update counts -->
+</esql:update-results>
+<esql:no-results>
+ <!-- this is used for the second and
+ all following update counts -->
+</esql:no-results>
+]]></source>
+ </s2>
- <s1 title="Template Descriptions">
- <table>
- <tr>
- <th>Tag</th>
- <th>Description</th>
- </tr>
+ <p>The ultimate reference, is of course the source code, which is an XSLT
+ logicsheet contained in the file
+
<code>src/org/apache/cocoon/components/language/markup/xsp/java/esql.xsl</code></p>
+
+ <p>Of course, we would be very grateful for any improvements on this
+ documentation or further examples - please send them to <link
+
href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</link>!</p>
+
+ </s1>
+
+
+ <s1 title="Template Descriptions">
+ <table>
+ <tr>
+ <th>Tag</th>
+ <th>Description</th>
+ </tr>
<tr><td>esql:row-results//esql:get-columns</td>
<td>results in a set of elements whose names are the names of the
columns. the elements each have one text child, whose value is the value of the column
interpreted as a string. No special formatting is allowed here. If you want to mess
around with the names of the elements or the value of the text field, use the
type-specific get methods and write out the result fragment yourself. For Cocoon 2
only, this outputs structured types as well. Here sql-list or sql-set contains several
sql-list-item or sql-set-item element that again contain the actual data.</td>
</tr>
@@ -258,7 +454,7 @@
</tr>
<tr><td>esql:row-results//esql:get-array</td>
<td>returns the value of the given column as an java.sql.Array. This is
frequently used for collection
- datatypes like lists, sets, bags etc.</td>
+ datatypes like lists, sets, bags etc.</td>
</tr>
<tr><td>esql:row-results//esql:get-struct</td>
<td>returns the value of the given column as a java.sql.Struct. This is
frequently used for row types.</td>
@@ -302,12 +498,12 @@
<tr><td>esql:results/esql:get-resultset</td>
<td>returns the current resultset</td>
</tr>
- <tr><td>esql:group</td>
- <td>Allows header and footer elements around groups of consecutive records
with identical values in column named by @group-on. Facilitates a single query with
joins to be used in lieu of some nested queries.</td>
+ <tr><td>esql:group</td>
+ <td>Allows header elements around groups of consecutive records with
identical values in column named by @group-on. Facilitates a single query with joins
to be used in lieu of some nested queries.</td>
</tr>
- <tr><td>esql:member</td>
- <td>Used in conjunction with and nested inside esql:group. Formatting for
individual records goes within esql:member. Header and footer stuff goes in between
group and member.</td>
- </tr>
+ <tr><td>esql:member</td>
+ <td>Used in conjunction with and nested inside esql:group. Formatting for
individual records goes within esql:member. Header stuff goes in between group and
member.</td>
+ </tr>
<tr><td>@*|node()</td>
<td>used internally to determine which column is the given column. if a
column attribute exists and its value is a number, it is taken to be the column's
position. if the value is not a number, it is taken to be the column's name. if a
column attribute does not exist, an esql:column element is assumed to exist and to
render as a string (after all of the xsp instructions have been evaluated), which is
taken to be the column's name.</td>
</tr>
----------------------------------------------------------------------
In case of troubles, e-mail: [EMAIL PROTECTED]
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]