SQL Component

The X:Forge SQL component is an automated component that can be used when the document content has to be pulled out from SQL databases. It provides a convenient method to configure system-wide the database properties and the connection pooling, and it allows to embed SQL queries directly in the document's body. Because of XML syntax rules the < and & characters have to be escaped in SQL queries with &lt; and &amp; respectively.

Configuration

Declaration

The component has to be declared in the configuration file in order to use it in the system. To declare the SQL component just configure associate an alias to the org.bibop.xml.xforge.components.sql.XForgeSQLComponent and specify the configuration by setting the connection parameters (url, user, password, driver) and the connection pool settings (initial connections, connections increment). It's also possible to configure the exceptions handling specifying the "handle-errors-internally" attribute: its default value is true. When "handle-errors-internally" is set to false an occurring exception is thrown: changing it to true means that the exception is formatted in XML and sent to the framework as an ordinary XML data flow.


<component role="process" class="org.apache.avalon.excalibur.component.DefaultComponentSelector">
	<component-instance name="sql" class="org.bibop.xml.xforge.components.sql.SQLComponent"
			    logger="mylogger">
		<dbparameters handle-errors-internally="true">
			<url>Your URL</url>
			<user>Your USER</user>
			<password>Your PASSWORD</password>
			<driver>Your DRIVER</driver>
			<connection-pool>
				<initial-connections>Initial connections</initial-connections>
				<connections-increment>Connection increment</connections-increment>
			</connection-pool>
		</dbparameters>
	</component-instance>
</component>

Usage

Invocation

Once declared and configured the component can be used straight away in XML documents by invoking it through the configured namespace prefix (sql in this case) and passing to it a "query" parameter that contains the actual query. Here follows a query example:


<students>
	<sql:execute>
		<xf:parameter name="query">
			SELECT name,address,email FROM tbAuthors
		</xf:parameter>
	</sql:execute>
</students>

Of course it is also possible to nest other X:Forge components in order to dynamically create the query like this (you might want to format on a single line if your parser does not like the output):


<students>
	<sql:execute>
		<xf:parameter name="query">
			SELECT name,address,email FROM tbAuthors WHERE email=
			<xf:process using="Request">
				<xf:parameter name="getparameter">
					userid
				</xf:parameter>
			</xf:process>
		</xf:parameter>
	</sql:execute>
</students>

Resulting XML

This is the output generated by the previous query:


<students>
  <record>
    <name>Alberto</name>
    <lastname>Garoffolo</lastname>
    <email>a.garoffolo@bibop.it</email>
  </record>
  <record>
    <name>Gianugo</name>
    <lastname>Rabellino</lastname>
    <email>g.rabellino@bibop.it</email>
  </record>
</students>

As you can see the field names are used as the tag names for the output. At this moment there is no check of XML compliance in field names: it's important to be sure that the database schema contains only XMLI compliant field names. Alternatively it's alway possible to use the SQL syntax "SELECT uncompliant AS compliant" to achieve the result.

Errors

Error Handling

If the component is configured to handle exceptions internally, when an exception occurs, the resulting XML is the exception formatted. Here follows an example:


<students>
    <error>ERROR:  Relation 'tbWhatever' does not exist
    <stack-trace>
      java.sql.SQLException: ERROR:  Relation
      'tbStrudel' does not exist    at
      org.postgresql.Connection.ExecSQL(Connection.java:393)   at
      org.postgresql.jdbc2.Statement.execute(Statement.java:273)
      at
      org.postgresql.jdbc2.Statement.executeQuery(Statement.java:54)
      at
      org.bibop.xml.xforge.components.sql.XForgeSQLComponent.toSax
        (XForgeSQLComponent.java:157)
      at
      org.bibop.xml.xforge.XForgeProcessElement.toSax
        (XForgeProcessElement.java:152)
      at
      org.bibop.xml.xforge.XForgeProcessor.endElement(XForgeProcessor.java:328)
      at
      org.apache.xerces.parsers.SAXParser.endElement(SAXParser.java:1403)
      at
      org.apache.xerces.validators.common.XMLValidator.callEndElement
        (XMLValidator.java:1456)
      at
      org.apache.xerces.framework.XMLDocumentScanner$ContentDispatcher.dispatch
        (XMLDocumentScanner.java:1205)
      at
      org.apache.xerces.framework.XMLDocumentScanner.parseSome
        (XMLDocumentScanner.java:381)
      at
      org.apache.xerces.framework.XMLParser.parse(XMLParser.java:1081)
      at org.bibop.xml.xforge.TestXForge.test(TestXForge.java:159)
      at org.bibop.xml.xforge.TestXForge.main(TestXForge.java:91)
    </stack-trace>
  </error>
</students>

Otherwise, if the component is configured not to handle exceptions, the error is just re-thrown to the caller.