haul        02/01/31 08:11:33

  Modified:    .        changes.xml
               src/java/org/apache/cocoon/components/language/markup/xsp
                        EsqlQuery.java
               src/java/org/apache/cocoon/components/language/markup/xsp/java
                        esql.xsl
               src/documentation/xdocs/userdocs/xsp esql.xml
  Log:
  Stored Procedure support for esql
  
  Revision  Changes    Path
  1.86      +4 -3      xml-cocoon2/changes.xml
  
  Index: changes.xml
  ===================================================================
  RCS file: /home/cvs/xml-cocoon2/changes.xml,v
  retrieving revision 1.85
  retrieving revision 1.86
  diff -u -r1.85 -r1.86
  --- changes.xml       31 Jan 2002 13:29:48 -0000      1.85
  +++ changes.xml       31 Jan 2002 16:11:32 -0000      1.86
  @@ -4,7 +4,7 @@
   
   <!--
     History of Cocoon changes
  -  $Id: changes.xml,v 1.85 2002/01/31 13:29:48 cziegeler Exp $
  +  $Id: changes.xml,v 1.86 2002/01/31 16:11:32 haul Exp $
   -->
   
   <changes title="History of Changes">
  @@ -31,8 +31,9 @@
    </devs>
   
    <release version="@version@" date="@date@">
  -  <action dev="dummy" type="fix">
  -    dummy
  +  <action dev="CH" type="add">
  +    Stored Procedure support for esql plus ability to obtain and use a result
  +      set from any column just like a nested query.
     </action>
    </release>
    <release version="2.0.1" date="January 31, 2002">
  
  
  
  1.3       +71 -9     
xml-cocoon2/src/java/org/apache/cocoon/components/language/markup/xsp/EsqlQuery.java
  
  Index: EsqlQuery.java
  ===================================================================
  RCS file: 
/home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/language/markup/xsp/EsqlQuery.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- EsqlQuery.java    28 Jan 2002 09:37:16 -0000      1.2
  +++ EsqlQuery.java    31 Jan 2002 16:11:33 -0000      1.3
  @@ -10,6 +10,7 @@
   import java.sql.Connection;
   import java.sql.Statement;
   import java.sql.PreparedStatement;
  +import java.sql.CallableStatement;
   import java.sql.ResultSet;
   import java.sql.ResultSetMetaData;
   import java.sql.SQLException;
  @@ -30,6 +31,7 @@
     private ResultSet resultSet = null;
     private ResultSetMetaData resultSetMetaData = null;
     private boolean hasResultSet = false;
  +  private boolean resultSetValid = false;
     private int position = -1;
     private int maxRows = -1;
     private int skipRows = 0;
  @@ -45,6 +47,14 @@
       this.query = query;
     }
   
  +  public EsqlQuery( ResultSet aResultSet ) {
  +    this.connection = null;
  +    this.statement = null;
  +    this.query = null;
  +    this.resultSetValid = true;
  +    this.hasResultSet = (this.resultSet != null);
  +  }
  +
     public int getSkipRows() {
       return(skipRows);
     }
  @@ -118,10 +128,27 @@
       return(preparedStatement);
     }
   
  +
  +  public CallableStatement prepareCall() throws SQLException {
  +    switch(limitMethod) {
  +      case EsqlConnection.LIMIT_METHOD_JDBC:
  +        preparedStatement = connection.prepareCall( getQueryString(), 
ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
  +        break;
  +      default:
  +        preparedStatement = connection.prepareCall( getQueryString() );
  +    };
  +    statement = preparedStatement; 
  +    return((CallableStatement)preparedStatement);
  +  }
  +
     public PreparedStatement getPreparedStatement() {
       return(preparedStatement);
     }
   
  +  public CallableStatement getCallableStatement() {
  +    return((CallableStatement) preparedStatement);
  +  }
  +
     public ResultSet getResultSet() {
       return(resultSet);
     }
  @@ -171,13 +198,45 @@
     }
   
     public boolean execute() throws SQLException {
  -    if (preparedStatement != null) {
  -      hasResultSet = preparedStatement.execute();
  -    }
  -    else {
  -      hasResultSet = statement.execute( getQueryString() );
  -    }
  -    return(hasResultSet);
  +      return this.execute(false);
  +  }
  +
  +  /**
  +   * some brain dead DBMSs (Oracle) return their result sets for
  +   * callable statements through the some (i.e. the first) returned
  +   * object.  
  +   */
  +  public boolean execute( int resultSetFromObject ) throws SQLException {
  +      hasResultSet = this.execute(false);
  +      resultSet = (ResultSet) ((CallableStatement) preparedStatement).getObject(1);
  +      resultSetValid = true;
  +      return hasResultSet;
  +  }
  +
  +  /**
  +   * some other brain dead DBMSs (Informix) don't like their callable
  +   * statements to be 'execute'd but require 'executeQuery' instead.
  +   */
  +  public boolean execute( boolean needsQuery ) throws SQLException {
  +      if ( needsQuery ) {
  +          if (preparedStatement != null) {
  +              resultSet = preparedStatement.executeQuery();
  +          }
  +          else {
  +              resultSet = statement.executeQuery( getQueryString() );
  +          }
  +          hasResultSet = (resultSet != null);
  +          resultSetValid = true;
  +      } else {
  +          if (preparedStatement != null) {
  +              hasResultSet = preparedStatement.execute();
  +          }
  +          else {
  +              hasResultSet = statement.execute( getQueryString() );
  +          }
  +          resultSetValid = false;
  +      }
  +      return(hasResultSet);
     }
   
     public boolean hasResultSet() {
  @@ -209,8 +268,11 @@
     }
   
     public void getResultRows() throws SQLException {
  -    resultSet = statement.getResultSet();
  -    resultSetMetaData = resultSet.getMetaData();
  +    if ( resultSetValid ) {
  +        resultSetMetaData = resultSet.getMetaData();
  +    } else {
  +        resultSet = statement.getResultSet();
  +    }
      
       if (skipRows > 0) {
         switch(limitMethod) {
  
  
  
  1.5       +137 -23   
xml-cocoon2/src/java/org/apache/cocoon/components/language/markup/xsp/java/esql.xsl
  
  Index: esql.xsl
  ===================================================================
  RCS file: 
/home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/language/markup/xsp/java/esql.xsl,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- esql.xsl  28 Jan 2002 09:37:16 -0000      1.4
  +++ esql.xsl  31 Jan 2002 16:11:33 -0000      1.5
  @@ -1,5 +1,5 @@
   <?xml version="1.0"?>
  -<!-- $Id: esql.xsl,v 1.4 2002/01/28 09:37:16 tcurdt Exp $-->
  +<!-- $Id: esql.xsl,v 1.5 2002/01/31 16:11:33 haul Exp $-->
   <!--
   
    ============================================================================
  @@ -205,6 +205,7 @@
         <xsp:include>java.sql.Connection</xsp:include>
         <xsp:include>java.sql.Statement</xsp:include>
         <xsp:include>java.sql.PreparedStatement</xsp:include>
  +      <xsp:include>java.sql.CallableStatement</xsp:include>
         <xsp:include>java.sql.ResultSet</xsp:include>
         <xsp:include>java.sql.ResultSetMetaData</xsp:include>
         <xsp:include>java.sql.Struct</xsp:include>
  @@ -437,7 +438,9 @@
   <xsl:template match="esql:connection/esql:property"/>
   
   <xsl:template match="esql:connection//esql:execute-query">
  -  <xsl:variable name="query"><xsl:call-template 
name="get-nested-string"><xsl:with-param name="content" 
select="esql:query"/></xsl:call-template></xsl:variable>
  +
  +  <xsl:variable name="query"><xsl:choose><xsl:when 
test="esql:query"><xsl:call-template name="get-nested-string"><xsl:with-param 
name="content" select="esql:query"/></xsl:call-template></xsl:when><xsl:when 
test="esql:call"><xsl:call-template name="get-nested-string"><xsl:with-param 
name="content" 
select="esql:call"/></xsl:call-template></xsl:when></xsl:choose></xsl:variable>
  +
     <xsl:variable name="maxrows"><xsl:call-template 
name="get-nested-string"><xsl:with-param name="content" 
select="esql:max-rows"/></xsl:call-template></xsl:variable>
     <xsl:variable name="skiprows"><xsl:call-template 
name="get-nested-string"><xsl:with-param name="content" 
select="esql:skip-rows"/></xsl:call-template></xsl:variable>
     <xsp:logic>
  @@ -460,6 +463,46 @@
   
       try {
         <xsl:choose>
  +        <xsl:when test="esql:call">
  +          try {
  +            _esql_query.prepareCall();
  +          } catch (SQLException _esql_exception_<xsl:value-of 
select="generate-id(.)"/>) {
  +            throw new RuntimeException("Error preparing statement: " + 
_esql_query.getQueryString() + ": "+_esql_exception_<xsl:value-of 
select="generate-id(.)"/>.getMessage());
  +          }
  +          <xsl:for-each select="esql:call//esql:parameter">
  +            try {
  +            <xsl:if test="@direction='out' or @direction='inout'">
  +              <xsl:text>_esql_query.getCallableStatement().</xsl:text>
  +              registerOutParameter(<xsl:value-of select="position()"/>, 
Types.<xsl:call-template name="get-Sql-Type"><xsl:with-param name="type"><xsl:value-of 
select="@type"/></xsl:with-param></xsl:call-template><xsl:if test="@typename">, 
<xsl:value-of select="@typename"/> </xsl:if>);
  +            </xsl:if>
  +            <xsl:if test="not(@direction) or @direction='inout' or @direction='in'">
  +              <xsl:text>_esql_query.getCallableStatement().</xsl:text>
  +              <xsl:choose>
  +                <xsl:when test="@type">
  +                  <xsl:variable name="type"><xsl:value-of 
select="concat(translate(substring(@type,1,1),'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ'),substring(@type,2))"/></xsl:variable>
  +                  <xsl:text>set</xsl:text><xsl:value-of 
select="$type"/>(<xsl:value-of select="position()"/>,<xsl:call-template 
name="get-nested-content"><xsl:with-param name="content" 
select="."/></xsl:call-template>);<xsl:text>
  +</xsl:text>
  +              </xsl:when>
  +              <xsl:otherwise>
  +                <xsl:text>setString(</xsl:text><xsl:value-of 
select="position()"/>,String.valueOf(<xsl:call-template 
name="get-nested-string"><xsl:with-param name="content" 
select="."/></xsl:call-template>));<xsl:text>
  +</xsl:text>
  +              </xsl:otherwise>
  +            </xsl:choose>
  +          </xsl:if>
  +            } catch (SQLException _esql_exception_<xsl:value-of 
select="generate-id(.)"/>) {
  +              throw new RuntimeException("Error setting parameter on statement: " + 
_esql_query.getQueryString() + ": "+_esql_exception_<xsl:value-of 
select="generate-id(.)"/>);
  +            }
  +          </xsl:for-each>
  +          try {
  +          <xsl:choose>
  +            <xsl:when test="esql:call[@needs-query='true' or 
@needs-query='yes']">_esql_query.execute(true);</xsl:when>
  +            <xsl:when 
test="esql:call[@resultset-from-object]">_esql_query.execute(<xsl:copy-of 
select="esql:call[@resultset-from-object]"/>);</xsl:when>
  +            <xsl:otherwise>_esql_query.execute();</xsl:otherwise>
  +          </xsl:choose>
  +          } catch (SQLException _esql_exception_<xsl:value-of 
select="generate-id(.)"/>) {
  +            throw new RuntimeException("Error executing prepared statement: " + 
_esql_query.getQueryString() + ": "+_esql_exception_<xsl:value-of 
select="generate-id(.)"/>);
  +          }
  +        </xsl:when>
           <xsl:when test="esql:query//esql:parameter">
             try {
               _esql_query.prepareStatement();
  @@ -507,6 +550,12 @@
             getLogger().debug("esql query: " + _esql_query.getQueryString());
           </xsl:otherwise>
         </xsl:choose>
  +      <xsl:if test="esql:call">
  +        // call results
  +        <xsp:content>
  +          <xsl:apply-templates select="esql:call-results"/>
  +        </xsp:content>
  +      </xsl:if>
         if (_esql_query.hasResultSet()) {
           do {
             _esql_query.getResultRows();
  @@ -559,6 +608,7 @@
   </xsl:template>
   
   <xsl:template match="esql:query//esql:parameter">"?"</xsl:template>
  +<xsl:template match="esql:call//esql:parameter">"?"</xsl:template>
   
   <xsl:template match="esql:execute-query//esql:results//esql:row-count">
     <xsp:expr>_esql_query.rowCount()</xsp:expr>
  @@ -570,6 +620,15 @@
     </xsp:content>
   </xsl:template>
   
  +<xsl:template match="esql:execute-query//esql:call-results">
  +  <xsp:logic>
  +  // call results2
  +  </xsp:logic>
  +  <xsp:content>
  +    <xsl:apply-templates/>
  +  </xsp:content>
  +</xsl:template>
  +
   <xsl:template match="esql:execute-query//esql:error-results">
     <xsp:content>
       <xsl:apply-templates/>
  @@ -781,7 +840,7 @@
   </xsl:template>
   
   <xspdoc:desc>returns the value of the given column as a string</xspdoc:desc>
  -<xsl:template match="esql:row-results//esql:get-string" name="get-string">
  +<xsl:template 
match="esql:row-results//esql:get-string|esql:call-results//esql:get-string" 
name="get-string">
     <xsp:expr>
       <xsl:call-template name="get-string-encoded">
         <xsl:with-param name="column-spec"><xsl:call-template 
name="get-column"/></xsl:with-param>
  @@ -791,7 +850,7 @@
   </xsl:template>
   
   <xspdoc:desc>returns the value of the given column as a date. if a format attribute 
exists, its value is taken to be a date format string as defined in 
java.text.SimpleDateFormat, and the result is formatted accordingly.</xspdoc:desc>
  -<xsl:template match="esql:row-results//esql:get-date">
  +<xsl:template 
match="esql:row-results//esql:get-date|esql:call-results//esql:get-date">
     <xsl:choose>
       <xsl:when test="@format">
         <xsp:expr><xsl:call-template 
name="get-resultset"/>.getDate(<xsl:call-template name="get-column"/>) == null ? "" : 
new SimpleDateFormat("<xsl:value-of select="@format"/>").format(<xsl:call-template 
name="get-resultset"/>.getDate(<xsl:call-template name="get-column"/>))</xsp:expr>
  @@ -803,7 +862,7 @@
   </xsl:template>
   
   <xspdoc:desc>returns the value of the given column as a time. if a format attribute 
exists, its value is taken to be a date format string as defined in 
java.text.SimpleDateFormat, and the result is formatted accordingly.</xspdoc:desc>
  -<xsl:template match="esql:row-results//esql:get-time">
  +<xsl:template 
match="esql:row-results//esql:get-time|esql:call-results//esql:get-time">
     <xsl:choose>
       <xsl:when test="@format">
         <xsp:expr><xsl:call-template 
name="get-resultset"/>.getTime(<xsl:call-template name="get-column"/>) == null ? "" : 
new SimpleDateFormat("<xsl:value-of select="@format"/>").format(<xsl:call-template 
name="get-resultset"/>.getTime(<xsl:call-template name="get-column"/>))</xsp:expr>
  @@ -815,7 +874,7 @@
   </xsl:template>
   
   <xspdoc:desc>returns the value of the given column as a timestamp. if a format 
attribute exists, its value is taken to be a date format string as defined in 
java.text.SimpleDateFormat, and the result is formatted accordingly.</xspdoc:desc>
  -<xsl:template match="esql:row-results//esql:get-timestamp">
  +<xsl:template 
match="esql:row-results//esql:get-timestamp|esql:call-results//esql:get-timestamp">
     <xsl:choose>
       <xsl:when test="@format">
         <xsp:expr><xsl:call-template 
name="get-resultset"/>.getTimestamp(<xsl:call-template name="get-column"/>) == null ? 
"" : new SimpleDateFormat("<xsl:value-of 
select="@format"/>").format(<xsl:call-template 
name="get-resultset"/>.getTimestamp(<xsl:call-template name="get-column"/>))</xsp:expr>
  @@ -827,12 +886,12 @@
   </xsl:template>
   
   <xspdoc:desc>returns the value of the given column as true or false</xspdoc:desc>
  -<xsl:template match="esql:row-results//esql:get-boolean">
  +<xsl:template 
match="esql:row-results//esql:get-boolean|esql:call-results//esql:get-boolean">
     <xsp:expr><xsl:call-template name="get-resultset"/>.getBoolean(<xsl:call-template 
name="get-column"/>)</xsp:expr>
   </xsl:template>
   
   <xspdoc:desc>returns the value of the given column as a double. if a format 
attribute exists, its value is taken to be a decimal format string as defined in 
java.text.DecimalFormat, and the result is formatted accordingly.</xspdoc:desc>
  -<xsl:template match="esql:row-results//esql:get-double">
  +<xsl:template 
match="esql:row-results//esql:get-double|esql:call-results//esql:get-double">
     <xsl:choose>
       <xsl:when test="@format">
         <xsp:expr>new DecimalFormat("<xsl:value-of select="@format"/>").format(new 
Double(<xsl:call-template name="get-resultset"/>.getDouble(<xsl:call-template 
name="get-column"/>)))</xsp:expr>
  @@ -844,7 +903,7 @@
   </xsl:template>
   
   <xspdoc:desc>returns the value of the given column as a float. if a format 
attribute exists, its value is taken to be a decimal format string as defined in 
java.text.DecimalFormat, and the result is formatted accordingly.</xspdoc:desc>
  -<xsl:template match="esql:row-results//esql:get-float">
  +<xsl:template 
match="esql:row-results//esql:get-float|esql:call-results//esql:get-float">
     <xsl:choose>
       <xsl:when test="@format">
         <xsp:expr>new DecimalFormat("<xsl:value-of select="@format"/>").format(new 
Float(<xsl:call-template name="get-resultset"/>.getFloat(<xsl:call-template 
name="get-column"/>)))</xsp:expr>
  @@ -861,37 +920,37 @@
   </xsl:template>
   
   <xspdoc:desc>returns the value of the given column as an object</xspdoc:desc>
  -<xsl:template match="esql:row-results//esql:get-object">
  +<xsl:template 
match="esql:row-results//esql:get-object|esql:call-results//esql:get-object">
     <xsp:expr><xsl:call-template name="get-resultset"/>.getObject(<xsl:call-template 
name="get-column"/>)</xsp:expr>
   </xsl:template>
   
   <xspdoc:desc>returns the value of the given column as an array</xspdoc:desc>
  -<xsl:template match="esql:row-results//esql:get-array">
  +<xsl:template 
match="esql:row-results//esql:get-array|esql:call-results//esql:get-array">
     <xsp:expr><xsl:call-template name="get-resultset"/>.getArray(<xsl:call-template 
name="get-column"/>)</xsp:expr>
   </xsl:template>
   
   <xspdoc:desc>returns the value of the given column as a struct</xspdoc:desc>
  -<xsl:template match="esql:row-results//esql:get-struct">
  +<xsl:template 
match="esql:row-results//esql:get-struct|esql:call-results//esql:get-struct">
     <xsp:expr>(Struct) <xsl:call-template 
name="get-resultset"/>.getObject(<xsl:call-template name="get-column"/>)</xsp:expr>
   </xsl:template>
   
   <xspdoc:desc>returns the value of the given column as an integer</xspdoc:desc>
  -<xsl:template match="esql:row-results//esql:get-int">
  +<xsl:template 
match="esql:row-results//esql:get-int|esql:call-results//esql:get-int">
     <xsp:expr><xsl:call-template name="get-resultset"/>.getInt(<xsl:call-template 
name="get-column"/>)</xsp:expr>
   </xsl:template>
   
   <xspdoc:desc>returns the value of the given column as a long</xspdoc:desc>
  -<xsl:template match="esql:row-results//esql:get-long">
  +<xsl:template 
match="esql:row-results//esql:get-long|esql:call-results//esql:get-long">
     <xsp:expr><xsl:call-template name="get-resultset"/>.getLong(<xsl:call-template 
name="get-column"/>)</xsp:expr>
   </xsl:template>
   
   <xspdoc:desc>returns the value of the given column as a short</xspdoc:desc>
  -<xsl:template match="esql:row-results//esql:get-short">
  +<xsl:template 
match="esql:row-results//esql:get-short|esql:call-results//esql:get-short">
     <xsp:expr><xsl:call-template name="get-resultset"/>.getShort(<xsl:call-template 
name="get-column"/>)</xsp:expr>
   </xsl:template>
   
   <xspdoc:desc>returns the value of the given column as a clob</xspdoc:desc>
  -<xsl:template match="esql:row-results//esql:get-ascii">
  +<xsl:template 
match="esql:row-results//esql:get-ascii|esql:call-results//esql:get-ascii">
     <xsp:expr>EsqlHelper.getAscii(<xsl:call-template name="get-resultset"/>, 
<xsl:call-template name="get-column"/>)</xsp:expr>
   </xsl:template>
   
  @@ -899,7 +958,7 @@
    The fragment is parsed by the default xsp parser and the document element is 
returned.
    If a root attribute exists, its value is taken to be the name of an element to 
wrap around the contents of
    the fragment before parsing.</xspdoc:desc>
  -<xsl:template match="esql:row-results//esql:get-xml">
  +<xsl:template 
match="esql:row-results//esql:get-xml|esql:call-results//esql:get-xml">
     <xsl:variable name="content">
       <xsl:choose>
         <xsl:when test="@root">
  @@ -972,27 +1031,27 @@
   </xsl:template>
   
   <xspdoc:desc>returns the position of the current row in the result set</xspdoc:desc>
  -<xsl:template 
match="esql:row-results//esql:get-row-position|esql:results//esql:get-row-position">
  +<xsl:template 
match="esql:row-results//esql:get-row-position|esql:results//esql:get-row-position|esql:call-results//esql:get-row-position">
     <xsp:expr>_esql_query.getCurrentRow()</xsp:expr>
   </xsl:template>
   
   <xspdoc:desc>returns the name of the given column. the column mus tbe specified by 
number, not name.</xspdoc:desc>
  -<xsl:template match="esql:row-results//esql:get-column-name">
  +<xsl:template 
match="esql:row-results//esql:get-column-name|esql:call-results//esql:get-column-name">
     <xsp:expr><xsl:call-template 
name="get-resultset"/>.getMetaData().getColumnName(<xsl:call-template 
name="get-column"/>)</xsp:expr>
   </xsl:template>
   
   <xspdoc:desc>returns the label of the given column. the column mus tbe specified by 
number, not name.</xspdoc:desc>
  -<xsl:template match="esql:row-results//esql:get-column-label">
  +<xsl:template 
match="esql:row-results//esql:get-column-label|esql:call-results//esql:get-column-label">
     <xsp:expr><xsl:call-template 
name="get-resultset"/>.getMetaData().getColumnLabel(<xsl:call-template 
name="get-column"/>)</xsp:expr>
   </xsl:template>
   
   <xspdoc:desc>returns the name of the type of the given column. the column must be 
specified by number, not name.</xspdoc:desc>
  -<xsl:template match="esql:row-results//esql:get-column-type-name">
  +<xsl:template 
match="esql:row-results//esql:get-column-type-name|esql:call-results//esql:get-column-type-name">
     <xsp:expr><xsl:call-template 
name="get-resultset"/>.getMetaData().getColumnTypeName(<xsl:call-template 
name="get-column"/>)</xsp:expr>
   </xsl:template>
   
   <xspdoc:desc>returns the type of the given column as int. the column must be 
specified by number, not name.</xspdoc:desc>
  -<xsl:template match="esql:row-results//esql:get-column-type">
  +<xsl:template 
match="esql:row-results//esql:get-column-type|esql:call-results//esql:get-column-type">
     <xsp:expr><xsl:call-template 
name="get-resultset"/>.getMetaData().getColumnType(<xsl:call-template 
name="get-column"/>)</xsp:expr>
   </xsl:template>
   
  @@ -1001,6 +1060,40 @@
     <xsp:expr>((<xsl:call-template name="get-resultset"/>.getObject("<xsl:value-of 
select="@column"/>") == null) || <xsl:call-template 
name="get-resultset"/>.wasNull())</xsp:expr>
   </xsl:template>
   
  +<xspdoc:desc>creates a nested query like block that uses the result set obtained 
from a column as current result set. Only row-results and no-results are supported as 
nested elements (i.e. more-results is not supported).</xspdoc:desc>
  +<xsl:template 
match="esql:row-results//esql:results[@from-column]|esql:call-results//esql:results[@from-column]"
 priority="2">
  +<xsp:logic>
  +  // nested result set
  +    if (_esql_query != null) {
  +      _esql_queries.push(_esql_query);
  +    }
  +    _esql_query = new EsqlQuery((ResultSet) <xsl:call-template 
name="get-resultset"/>.getObject(<xsl:value-of select="@from-column"/>));
  +    {
  +      if (_esql_query.hasResultSet()) {
  +        do {
  +          _esql_query.getResultRows();
  +
  +          if (_esql_query.nextRow()) {
  +            <xsl:apply-templates select="esql:row-results"/>
  +          }
  +          else {
  +            <xsl:apply-templates select="esql:no-results"/>
  +          }
  +          _esql_query.getResultSet().close();
  +
  +        } while(_esql_query.getMoreResults());
  +      } else {
  +        <xsl:apply-templates select="esql:no-results"/>
  +      }
  +    }
  +    if (_esql_queries.empty()) {
  +      _esql_query = null;
  +    } else {
  +      _esql_query = (EsqlQuery)_esql_queries.pop();
  +    }
  +  </xsp:logic>
  +</xsl:template>
  +
   <xspdoc:desc>returns the message of the current exception</xspdoc:desc>
   <xsl:template match="esql:error-results//esql:get-message">
     <xsp:expr>_esql_exception.getMessage()</xsp:expr>
  @@ -1017,7 +1110,7 @@
   </xsl:template>
   
   <xsl:template name="get-resultset">
  -  <xsl:call-template name="get-query"/><xsl:text>.getResultSet()</xsl:text>
  +  <xsl:call-template name="get-query"/><xsl:choose><xsl:when test="@from-call='yes' 
or 
@from-call='true'"><xsl:text>.getCallableStatement()</xsl:text></xsl:when><xsl:otherwise><xsl:text>.getResultSet()</xsl:text></xsl:otherwise></xsl:choose>
   </xsl:template>
   
   <xsl:template name="get-query">
  @@ -1087,6 +1180,27 @@
       </xsl:otherwise>
     </xsl:choose>
   </xsl:template>
  +
  +<xsl:template name="get-Sql-Type">
  +  <xsl:param name="type"/>
  +  <xsl:choose>
  +    <!-- just do the 'unusual' mappings -->
  +    <xsl:when test="$type='Byte'">TINYINT</xsl:when>
  +    <xsl:when test="$type='Short'">SMALLINT</xsl:when>
  +    <xsl:when test="$type='Int'">INTEGER</xsl:when>
  +    <xsl:when test="$type='Long'">BIGINT</xsl:when>
  +    <xsl:when test="$type='Float'">REAL</xsl:when>
  +    <xsl:when test="$type='BigDecimal'">DECIMAL</xsl:when>
  +    <xsl:when test="$type='Boolean'">BIT</xsl:when>
  +    <xsl:when test="$type='String'">VARCHAR</xsl:when>
  +    <xsl:when test="$type='Bytes'">BINARY</xsl:when>
  +    <xsl:when test="$type='AsciiStream'">LONGVARCHAR</xsl:when>
  +    <xsl:when test="$type='UnicodeStream'">LONGVARCHAR</xsl:when>
  +    <xsl:when test="$type='BinaryStream'">VARBINARY</xsl:when>
  +    <xsl:otherwise><xsl:value-of 
select="translate(@type,'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/></xsl:otherwise>
  +  </xsl:choose>
  +</xsl:template>
  +
   
   <!--
     Break on error.
  
  
  
  1.2       +57 -0     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.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- esql.xml  3 Jan 2002 12:31:06 -0000       1.1
  +++ esql.xml  31 Jan 2002 16:11:33 -0000      1.2
  @@ -128,6 +128,63 @@
   </esql:execute-query>]]>
             </source>
   
  +      <s2 title="Stored Procedure Support">
  +     <p>In order to use stored procedures replace
  +       <code>&lt;esql:query/&gt;</code> with
  +       <code>&lt;esql:call/&gt;</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>&lt;esql:call/&gt;</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>&lt;esql:call-results/&gt;</code> (child of
  +       <code>&lt;esql:execute-query/&gt;</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>&lt;esql:get-xxx/&gt;</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 by e.g. <code>&lt;esql:results
  +         from-column="1"/&gt;</code>. Of course the column needs to return a
  +       result that is castable to ResultSet. Supported child elements are
  +       <code>&lt;esql:row-results/&gt;</code> and
  +       <code>&lt;esql:no-results/&gt;</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>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 from-column="1" from-call="true">
  +                <esql:row-results>
  +                  <esql:get-string column="1"/>
  +                </esql:row-results>
  +       </esql:results>
  +     </esql:call-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>
   
  
  
  

----------------------------------------------------------------------
In case of troubles, e-mail:     [EMAIL PROTECTED]
To unsubscribe, e-mail:          [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to