haul        01/11/20 04:33:55

  Modified:    src/org/apache/cocoon/components/language/markup/xsp
                        EsqlQuery.java
               src/org/apache/cocoon/components/language/markup/xsp/java
                        esql.xsl
               documentation/xdocs/userdocs/xsp esql.xml
  Log:
  Patch from Tim Myers:
  Adds esql:group + esql:member tags to provide a simpler
  and (to the DBMS) friendlier alternative to nested queries
  in some cases.
  
  Revision  Changes    Path
  1.4       +18 -0     
xml-cocoon2/src/org/apache/cocoon/components/language/markup/xsp/EsqlQuery.java
  
  Index: EsqlQuery.java
  ===================================================================
  RCS file: 
/home/cvs/xml-cocoon2/src/org/apache/cocoon/components/language/markup/xsp/EsqlQuery.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- EsqlQuery.java    2001/10/26 11:31:33     1.3
  +++ EsqlQuery.java    2001/11/20 12:33:55     1.4
  @@ -33,6 +33,8 @@
     private int position = -1;
     private int maxRows = -1;
     private int skipRows = 0;
  +  private boolean keepgoing = true; 
  +  private java.util.Hashtable groupingVars = new java.util.Hashtable();
   
     private String query;
     private int limitMethod;
  @@ -128,6 +130,22 @@
       position++;
       return(resultSet.next());
     }
  +
  +  public boolean keepGoing() {
  +    return(keepgoing);
  +  }
  +
  +  public void setKeepGoing( boolean still ) {
  +    keepgoing = still;
  +  }
  +
  +  public Object setGroupingVar( String key, Object value) {
  +    return groupingVars.put(key,value);
  +  } 
  + 
  +  public Object getGroupingVar( String key) {
  +    return groupingVars.get(key);
  +  } 
   
     public ResultSetMetaData getResultSetMetaData() {
       return(resultSetMetaData);
  
  
  
  1.24      +73 -7     
xml-cocoon2/src/org/apache/cocoon/components/language/markup/xsp/java/esql.xsl
  
  Index: esql.xsl
  ===================================================================
  RCS file: 
/home/cvs/xml-cocoon2/src/org/apache/cocoon/components/language/markup/xsp/java/esql.xsl,v
  retrieving revision 1.23
  retrieving revision 1.24
  diff -u -r1.23 -r1.24
  --- esql.xsl  2001/11/19 15:23:53     1.23
  +++ esql.xsl  2001/11/20 12:33:55     1.24
  @@ -1,5 +1,5 @@
   <?xml version="1.0"?>
  -<!-- $Id: esql.xsl,v 1.23 2001/11/19 15:23:53 haul Exp $-->
  +<!-- $Id: esql.xsl,v 1.24 2001/11/20 12:33:55 haul Exp $-->
   <!--
   
    ============================================================================
  @@ -583,15 +583,20 @@
   </xsl:template>
   
   <xsl:template match="esql:results//esql:row-results">
  +  <xsl:variable name="group" select=".//esql:group"/>
     <xsp:logic>
  +
  +    //create booleans for group change watches and strings for old values.
  +    <xsl:apply-templates select=".//esql:group" mode="vars"/>
  +
       do {
  -    <xsp:content>
  +      <xsp:content>
         <xsl:apply-templates/>
  -    </xsp:content>
  -      if (_esql_query.getMaxRows() != -1 &amp;&amp; _esql_query.getCurrentRow() - 
_esql_query.getSkipRows() == _esql_query.getMaxRows() - 1 ) {
  -        break;
  -      }
  -    } while (_esql_query.nextRow());
  +      </xsp:content>
  +      <xsl:if test="count($group) &lt; 1">   
  +        <xsl:call-template name="nextRow"/>
  +      </xsl:if>
  +    } while ( _esql_query.keepGoing() );
   
       if (_esql_query.getSkipRows() > 0 ) {
           <xsl:apply-templates select="ancestor::esql:results//esql:previous-results" 
mode="more"/>
  @@ -603,12 +608,73 @@
     </xsp:logic>
   </xsl:template>
   
  +<xsl:template name="nextRow">
  +  //checking out early?
  +    if (_esql_query.getMaxRows() != -1 &amp;&amp; _esql_query.getCurrentRow() - 
_esql_query.getSkipRows() == _esql_query.getMaxRows() - 1 ) {
  +    } else { //if not, advance normally
  +      _esql_query.setKeepGoing( _esql_query.nextRow() );
  +    }
  +</xsl:template>
  +
   <xsl:template match="esql:results//esql:previous-results"/>
   
   <xsl:template match="esql:results//esql:previous-results" mode="more">
     <xsp:content>
       <xsl:apply-templates/>
     </xsp:content>
  +</xsl:template>
  +
  +<xsl:template match="esql:group" mode="vars">
  +  _esql_query.setGroupingVar("<xsl:value-of select="@group-on"/>Changed", new 
Boolean(true));
  +</xsl:template>
  +
  +<xspdoc:desc>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.</xspdoc:desc>
  +<xsl:template match="esql:group|esql:group//esql:group[.//esql:member]" 
priority="3">
  +<xsp:logic>
  +  if (((Boolean)_esql_query.getGroupingVar("<xsl:value-of 
select="@group-on"/>Changed")).booleanValue()){    
  +    //header contents
  +    <xsp:content>
  +      <xsl:apply-templates>
  +        <xsl:with-param name="group-on" select="@group-on"/>
  +      </xsl:apply-templates>
  +    </xsp:content>
  +  }
  +</xsp:logic>
  +</xsl:template>
  +
  +<xsl:template match="esql:group//node()[.//esql:member]">
  +  <xsl:param name="group-on"/>
  +  <xsl:copy>
  +    <xsl:apply-templates select="@*|*|text()">
  +      <xsl:with-param name="group-on" select="$group-on"/>
  +    </xsl:apply-templates>
  +  </xsl:copy>
  +</xsl:template>
  +
  +<xspdoc:desc>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.</xspdoc:desc>
  +<xsl:template match="esql:member|esql:group//esql:member[.//esql:member]">
  +  <xsl:param name="group-on"/>
  +  <xsl:variable name="group" select=".//esql:group"/>
  +  <xsp:logic>
  +  }
  +    _esql_query.setGroupingVar("<xsl:value-of select="$group-on"/>Old", 
_esql_query.getResultSet().getString("<xsl:value-of select="$group-on"/>")); 
  +    <xsp:content>
  +      <xsl:apply-templates>
  +        <xsl:with-param name="group-on" select="$group-on"/>
  +      </xsl:apply-templates>
  +    </xsp:content>
  +
  +    <xsl:if test="count($group) &lt; 1">     
  +      <xsl:call-template name="nextRow"/>
  +    </xsl:if>
  +  if ( _esql_query.keepGoing() ) {
  +    _esql_query.setGroupingVar("<xsl:value-of select="$group-on"/>Changed", new 
Boolean(!((String)_esql_query.getGroupingVar("<xsl:value-of 
select="$group-on"/>Old")).equals(_esql_query.getResultSet().getString("<xsl:value-of 
select="$group-on"/>"))));
  +  } else {
  +    _esql_query.setGroupingVar("<xsl:value-of select="$group-on"/>Changed", new 
Boolean(true));
  +  }
  +  if (((Boolean)_esql_query.getGroupingVar("<xsl:value-of 
select="$group-on"/>Changed")).booleanValue()) {   
  +    //footer contents
  +  </xsp:logic>
   </xsl:template>
   
   <xsl:template match="esql:results//esql:more-results"/>
  
  
  
  1.4       +50 -0     xml-cocoon2/documentation/xdocs/userdocs/xsp/esql.xml
  
  Index: esql.xml
  ===================================================================
  RCS file: /home/cvs/xml-cocoon2/documentation/xdocs/userdocs/xsp/esql.xml,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- esql.xml  2001/11/19 15:23:53     1.3
  +++ esql.xml  2001/11/20 12:33:55     1.4
  @@ -87,13 +87,57 @@
     </esql:execute-query>
   </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>&lt;esql:group/&gt;</code> and
  +        <code>&lt;esql:member/&gt;</code> tags.  It follows the
  +        nesting ideology of <code>&lt;xsp:logic&gt;
  +        ... &lt;xsp:content&gt;&lt;/&gt;&lt;/&gt;</code>You can
  +        nest <code>&lt;esql:group&gt;</code> and
  +        <code>&lt;esql:member&gt;</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
  +  </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:row-results>
  +  </esql:results>
  +</esql:execute-query>]]>
  +          </source>
  +
             <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>
  @@ -185,6 +229,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>
  +       <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>@*|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]

Reply via email to