haul 2002/08/09 01:28:14 Modified: src/java/org/apache/cocoon/components/language/markup/xsp EsqlQuery.java src/java/org/apache/cocoon/components/language/markup/xsp/java esql.xsl Log: <action dev="CH" type="update"> ESQL: Allow arbitrary types for prepared and callable statements via dynamically loading classes like the SQLTransformer does. Is-null now uses dynamic colum specification. Fixed skip-row feature, which was off by one. Added tag to get connection meta data. </action> Revision Changes Path 1.21 +58 -10 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.20 retrieving revision 1.21 diff -u -r1.20 -r1.21 --- EsqlQuery.java 25 Jul 2002 19:55:35 -0000 1.20 +++ EsqlQuery.java 9 Aug 2002 08:28:14 -0000 1.21 @@ -58,7 +58,7 @@ import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.ArrayList; - +import java.lang.reflect.Field; /** * This helper class takes care of contstructing queries * and cursor positioning (paging) for all different kinds @@ -183,12 +183,33 @@ public PreparedStatement prepareStatement() throws SQLException { switch(limitMethod) { - case EsqlConnection.LIMIT_METHOD_JDBC: - preparedStatement = connection.prepareStatement( getQueryString(), ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); + case EsqlConnection.LIMIT_METHOD_POSTGRESQL: + case EsqlConnection.LIMIT_METHOD_MYSQL: + preparedStatement = connection.prepareStatement(getQueryString() ); break; - default: - preparedStatement = connection.prepareStatement( getQueryString() ); - }; + case EsqlConnection.LIMIT_METHOD_JDBC: + // Produce scrollable ResultSet and skip rows with ResultSet.absolute(skipRows). + // With SQL Server, statement.getResultSet() throws + // java.sql.SQLException: [Microsoft][SQLServer 2000 Driver for JDBC]Error setting up static cursor cache. + // Same error with TYPE_SCROLL_SENSITIVE. + preparedStatement = connection.prepareStatement( getQueryString(), + ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); + if (maxRows > -1) { + // if all JDBC driver's honoured this the code to quit after maxRows could be removed + preparedStatement.setMaxRows(skipRows + maxRows +1); // need this to determine if there's more + } + break; + case EsqlConnection.LIMIT_METHOD_NOLIMIT: + default: + // maxRows can be set without the limit method being set - it defaults to LIMIT_METHOD_NOLIMIT + // which is not such a good name as its really another way of limiting using JDBC. + // Produce non-scrollable ResultSet and skip rows with multiple ResultSet.next(). + preparedStatement = connection.prepareStatement(getQueryString() ); + if (maxRows > -1) { + preparedStatement.setMaxRows(skipRows + maxRows +1); // need this to determine if there's more + } + break; + } statement = preparedStatement; return(preparedStatement); } @@ -196,11 +217,22 @@ public CallableStatement prepareCall() throws SQLException { switch(limitMethod) { - case EsqlConnection.LIMIT_METHOD_JDBC: + case EsqlConnection.LIMIT_METHOD_POSTGRESQL: + case EsqlConnection.LIMIT_METHOD_MYSQL: + preparedStatement = connection.prepareCall( getQueryString() ); + break; + case EsqlConnection.LIMIT_METHOD_JDBC: preparedStatement = connection.prepareCall( getQueryString(), ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); + if (maxRows > -1) { + preparedStatement.setMaxRows(skipRows + maxRows +1); // need this to determine if there's more + } break; - default: + case EsqlConnection.LIMIT_METHOD_NOLIMIT: + default: preparedStatement = connection.prepareCall( getQueryString() ); + if (maxRows > -1) { + preparedStatement.setMaxRows(skipRows + maxRows +1); // need this to determine if there's more + } }; statement = preparedStatement; return((CallableStatement)preparedStatement); @@ -338,7 +370,7 @@ public boolean execute( int resultSetFromObject ) throws SQLException { hasResultSet = this.execute(false); - resultSet = (ResultSet) ((CallableStatement) preparedStatement).getObject(1); + resultSet = (ResultSet) ((CallableStatement) preparedStatement).getObject(resultSetFromObject); resultSetValid = true; return hasResultSet; } @@ -428,4 +460,20 @@ }; } } + + /** + * Get the integer value for a JDBC type. + */ + public static int getType(String typeName) + throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException { + + int index = typeName.lastIndexOf("."); + String className = typeName.substring(0, index); + String fieldName = typeName.substring(index + 1); + Class clss = Class.forName( className ); + Field fld = clss.getField( fieldName ); + return fld.getInt( fieldName ); + } + + } 1.31 +33 -26 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.30 retrieving revision 1.31 diff -u -r1.30 -r1.31 --- esql.xsl 2 Jul 2002 13:38:02 -0000 1.30 +++ esql.xsl 9 Aug 2002 08:28:14 -0000 1.31 @@ -1,4 +1,4 @@ -<?xml version="1.0"?> +<?xml version="1.0"?><!-- -*- xsl -*- --> <!-- $Id$--> <!-- @@ -203,8 +203,7 @@ <xsl:if test=".//esql:connection/esql:pool"> private static ComponentSelector _esql_selector = null; - public void compose(ComponentManager manager) throws org.apache.avalon.framework.component.ComponentException { - super.compose(manager); + protected ComponentSelector _esql_get_selector() throws org.apache.avalon.framework.component.ComponentException { if (_esql_selector == null) { try { _esql_selector = (ComponentSelector) manager.lookup(DataSourceComponent.ROLE + "Selector"); @@ -212,6 +211,7 @@ getLogger().error("Could not look up the datasource component", cme); } } + return _esql_selector; } </xsl:if> @@ -286,7 +286,7 @@ <xsl:choose> <xsl:when test="esql:pool"> try { - _esql_connection.datasource = (DataSourceComponent) _esql_selector.select(String.valueOf(<xsl:copy-of select="$pool"/>)); + _esql_connection.datasource = (DataSourceComponent) _esql_get_selector().select(String.valueOf(<xsl:copy-of select="$pool"/>)); _esql_connection.connection = _esql_connection.datasource.getConnection(); <xsl:if test="esql:allow-multiple-results"> _esql_connection.setMultipleResults(String.valueOf(<xsl:copy-of select="$allow-multiple-results"/>)); @@ -362,10 +362,19 @@ <xsl:template match="esql:connection/esql:username"/> <xsl:template match="esql:connection/esql:password"/> <xsl:template match="esql:connection/esql:pool"/> +<xsl:template match="esql:connection/esql:allow-multiple-results"/> <xsl:template match="esql:connection/esql:autocommit"/> <xsl:template match="esql:connection/esql:use-limit-clause"/> <xsl:template match="esql:connection/esql:property"/> +<xspdoc:desc>Returns the connection's meta data.</xspdoc:desc> +<xsl:template match="esql:get-connection-metadata"> + <xsp:expr>_esql_connection.getMetaData()</xsp:expr> +</xsl:template> + +<xsl:template match="esql:connection/esql:get-connection"> + <xsp:expr>_esql_connection</xsp:expr> +</xsl:template> <!-- set one parameter of a prepared or callable statement and use correct method for type --> <xsl:template name="set-query-parameter"> @@ -386,7 +395,7 @@ <xsl:template name="set-call-parameter"> <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>); + registerOutParameter(<xsl:value-of select="position()"/>, <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> @@ -554,9 +563,6 @@ </xsl:template> <xsl:template match="esql:execute-query//esql:call-results"> - <xsp:logic> - // call results2 - </xsp:logic> <xsp:content> <xsl:apply-templates/> </xsp:content> @@ -954,13 +960,13 @@ </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|esql:call-results//esql:get-column-type" name="get-column-type"> +<xsl:template match="esql:row-results//esql:get-column-type" name="get-column-type"> <xsp:expr><xsl:call-template name="get-resultset"/>.getMetaData().getColumnType(<xsl:call-template name="get-column"/>)</xsp:expr> </xsl:template> <xspdoc:desc>allows null-column testing. Evaluates to a Java expression, which is true when the referred column contains a null-value for the current resultset row</xspdoc:desc> -<xsl:template match="esql:row-results//esql:is-null|esql:call-results//esql:is-null"> - <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 match="esql:row-results//esql:is-null"> + <xsp:expr>((<xsl:call-template name="get-resultset"/>.getObject(<xsl:call-template name="get-column"/>) == null) || <xsl:call-template name="get-resultset"/>.wasNull())</xsp:expr> </xsl:template> <xsl:template match="esql:result"/> @@ -1080,19 +1086,20 @@ <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:when test="$type='Byte'">Types.TINYINT</xsl:when> + <xsl:when test="$type='Short'">Types.SMALLINT</xsl:when> + <xsl:when test="$type='Int'">Types.INTEGER</xsl:when> + <xsl:when test="$type='Long'">Types.BIGINT</xsl:when> + <xsl:when test="$type='Float'">Types.REAL</xsl:when> + <xsl:when test="$type='BigDecimal'">Types.DECIMAL</xsl:when> + <xsl:when test="$type='Boolean'">Types.BIT</xsl:when> + <xsl:when test="$type='String'">Types.VARCHAR</xsl:when> + <xsl:when test="$type='Bytes'">Types.BINARY</xsl:when> + <xsl:when test="$type='AsciiStream'">Types.LONGVARCHAR</xsl:when> + <xsl:when test="$type='UnicodeStream'">Types.LONGVARCHAR</xsl:when> + <xsl:when test="$type='BinaryStream'">Types.VARBINARY</xsl:when> + <xsl:when test="contains($type,'.')">EsqlQuery.getType("<xsl:value-of select="$type"/>")</xsl:when> + <xsl:otherwise>Types.<xsl:value-of select="translate(@type,'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/></xsl:otherwise> </xsl:choose> </xsl:template>
---------------------------------------------------------------------- In case of troubles, e-mail: [EMAIL PROTECTED] To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]