Skip to main content

Notice: This Wiki is now read only and edits are no longer possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "EclipseLink/Development/DBWS/CustomSQLDesignTimeSchema"

(New page: == tbd ==)
 
 
(105 intermediate revisions by the same user not shown)
Line 1: Line 1:
== tbd ==
+
<css>
 +
  .source-plsql {padding:4px;border:1px solid black; background-color: white;}
 +
  .source-sql {padding:4px;border:1px solid black; background-color: white;}
 +
  .source-java5 {padding:4px;border:1px solid black; background-color: white;}
 +
  .source-xml {padding:4px;border:1px solid black; background-color: white;}
 +
  .source-text {padding:4px;border:1px solid black; background-color: white;}
 +
</css>
 +
__NOTOC__
 +
 
 +
<font color="red"><i>{NB - this capability is available starting in version 2.2 of DBWS}</i></font>
 +
 
 +
== Custom SQL Design-time Schema ==
 +
 
 +
=== Overview ===
 +
The use-case is the creation of a Web service that exposes the results of executing some custom SQL <tt>SELECT</tt> statement, without exposing the actual SQL. Currently, DBWS determines the 'shape' of the returned result at the time the <tt>SELECT</tt> statement is executed (i.e. at runtime, not design-time). For example, the  following <tt>DBWSBuilder</tt> file produces a SXF (Simplified XML Format) document where the element tag names are direct copies of column names:
 +
<source lang="xml">
 +
<?xml version="1.0" encoding="UTF-8"?>
 +
<dbws-builder xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 +
    <properties>
 +
        <property name="projectName">Semployees</property>
 +
        ...
 +
    </properties>
 +
    <sql
 +
        name="Semployees"
 +
        isCollection="false"
 +
        >
 +
        <text><![CDATA[select * from EMP where ENAME like 'S%']]></text>
 +
    </sql>
 +
</dbws-builder>
 +
</source>
 +
<source lang="xml">
 +
<?xml version = '1.0' encoding = 'UTF-8'?>
 +
<simple-xml-format>
 +
  <simple-xml>
 +
    <EMPNO>7788</EMPNO>
 +
    <ENAME>SCOTT</ENAME>
 +
    <JOB>ANALYST</JOB>
 +
    <MGR>7566</MGR>
 +
    <HIREDATE>1987-04-19</HIREDATE>
 +
    <SAL>3000</SAL>
 +
    <DEPTNO>20</DEPTNO>
 +
  </simple-xml>
 +
  <simple-xml>
 +
    <EMPNO>7369</EMPNO>
 +
    <ENAME>SMITH</ENAME>
 +
    <JOB>CLERK</JOB>
 +
    <MGR>7902</MGR>
 +
    <HIREDATE>1980-12-17</HIREDATE>
 +
    <SAL>800</SAL>
 +
    <DEPTNO>20</DEPTNO>
 +
  </simple-xml>
 +
</simple-xml-format>
 +
</source>
 +
 
 +
=== New Capability: generate schema at design-time===
 +
The custom SQL <tt>SELECT</tt> statement is executed at design-time and the returned <code>java.sql.ResultSet</code> examined via the <code>java.sql.ResultSetMetaData</code> APIs - <code>getColumnCount(), getColumnLabel(), getColumnType(int column)</code>, etc. From this information, an <tt>eclipselink-dbws-schema.xsd</tt> file is created along with all the other required DBWS meta files (eclipselink-dbws.xml, eclipselink-dbws.wsdl, eclipselink-dbws-ox.xml, etc.)
 +
 
 +
The resulting schema for the above example would be:
 +
<source lang="xml">
 +
<?xml version="1.0" encoding="UTF-8"?>
 +
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:emp" xmlns="urn:emp" elementFormDefault="qualified">
 +
  <xsd:complexType name="empType">
 +
      <xsd:sequence>
 +
        <xsd:element name="empno" type="xsd:decimal"/>
 +
        <xsd:element name="ename" type="xsd:string" minOccurs="0" nillable="true"/>
 +
        <xsd:element name="job" type="xsd:string" minOccurs="0" nillable="true"/>
 +
        <xsd:element name="mgr" type="xsd:decimal" minOccurs="0" nillable="true"/>
 +
        <xsd:element name="hiredate" type="xsd:date" minOccurs="0" nillable="true"/>
 +
        <xsd:element name="sal" type="xsd:decimal" minOccurs="0" nillable="true"/>
 +
        <xsd:element name="comm" type="xsd:decimal" minOccurs="0" nillable="true"/>
 +
        <xsd:element name="deptno" type="xsd:decimal" minOccurs="0" nillable="true"/>
 +
      </xsd:sequence>
 +
  </xsd:complexType>
 +
  <xsd:element name="empType" type="empType"/>
 +
</xsd:schema>
 +
</source>
 +
 
 +
=== Strategy ===
 +
The key to this feature is the execution of the <tt>SELECT</tt> statement at design-time. The user must provide a primary and secondary <tt>SELECT</tt> statement. The secondary statement is optimized with a 'nonsense' <tt>WHERE</tt> clause (<tt>WHERE 0=1</tt>) (or optimized using platform-specific hints i.e.g <tt>SELECT TOP</tt> 1) to reduce the cost of preparing and executing the query. Even if no rows are returned, the ResultSet metadata will still have information about the number, name and type of columns involved in the query.
 +
 
 +
=== Work items ===
 +
 
 +
==== Changes to DBWS builder file ====
 +
A new field <tt>build-statement</tt> is added to the <tt>sql</tt> Query operation:
 +
<source lang="xml">
 +
<?xml version="1.0" encoding="UTF-8"?>
 +
<dbws-builder xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 +
    <properties>
 +
        <property name="projectName">emp</property>
 +
        ...
 +
    </properties>
 +
    <sql
 +
        name="Semployees"
 +
        isCollection="false"
 +
        returnType="empType"
 +
        >
 +
        <statement><![CDATA[select * from EMP where ENAME like 'S%']]></statement>
 +
        <build-statement><![CDATA[select * from EMP where 0=1]]></build-statement>
 +
    </sql>
 +
</dbws-builder>
 +
</source>
 +
The <tt>build-statement</tt> is executed and metadata from the resultSet analyzed to create an XSD schema. The top-level name for the schema type is specified by the <tt>returnType</tt> element. If the <tt>build-statement</tt> element is missing, then a SXF document will be built at runtime.
 +
 
 +
Done
 +
 
 +
==== Changes to JDBCHelper ====
 +
Once the <tt>build-statement</tt> has been executed, the <code>ResultSetMetaData</code> is examined to extract:
 +
#columnLabel - name of the column as specified in SQL statement; or, if a column alias used (e.g. <tt>SELECT COUNT(*) as 'employeeCount' from emp</tt>), the column alias.
 +
#columnType - integer code corresponding to <code>java.sql.Types</code> (NB - some JDBC drivers and/or database use non-standard code numbers)
 +
#columnTypeName - the symbolic name for the integer <tt>columnType</tt>
 +
#precision, scale - for numeric data, precision is the total number of digits, scale the number of digits to the right of the decimal point.
 +
#isNullable - can the column contain <tt>null</tt> values
 +
 
 +
Done
 +
 
 +
==== Changes to DBWSBuilder processing ====
 +
Once the set of <code>DbColumn</code>'s is built, OR and OX projects are created (very similar to the tables use-case). In addition to generating the <tt>eclipselink-dbws-or.xml</tt> and <tt>eclipselink-dbws-ox.xml</tt>, the <tt>eclipselink-dbws-schema.xsd</tt> file is auto-generated from the OX project (re-using <code>SchemaModelGenerator</code>)
 +
 
 +
Done
 +
 
 +
<b>Limitation 1 - repeated labels:</b> above it says 'set' - this points out a limitation with this feature. It is perfectly valid to have a SQL statement with multiple identical columns:
 +
<source lang="sql">
 +
SELECT ENAME, ENAME from EMP WHERE 0=1
 +
</source>
 +
 
 +
{| border="1" cellpadding="5" cellspacing="1"
 +
! style="border-width: 1px;border-style: solid;border-color: #ccc;padding: 5px;background-color: #e9e9f2;text-align: right;vertical-align: top;color: #003366;"|ENAME
 +
! style="border-width: 1px;border-style: solid;border-color: #ccc;padding: 5px;background-color: #e9e9f2;text-align: left;vertical-align: top;color: #003366;"|ENAME
 +
|-
 +
|SMITH
 +
|SMITH
 +
|-
 +
|...
 +
|...
 +
|-
 +
|SCOTT
 +
|SCOTT
 +
|}
 +
 
 +
The above is admittedly nonsensical, but a <tt>SELECT</tt> statement that uses <tt>UNION</tt> could return a set of column labels where a label is repeated.
 +
<br/>
 +
DBWSBuilder will keep track of 'already processed columns' and throw an exception when it detects a duplicate.<br/>
 +
<br/>
 +
<b>Limitation 2 - compatible column label sets:</b> the <u>primary</u> and <u>secondary</u> SQL statements <b>must</b> return compatible column label sets. At this time, no pre-processing is done to ensure that the column sets are the same; the error will be detected at runtime when the service is invoked.
 +
 
 +
==== Changes to WSDLGenerator ====
 +
Integrate newly-generated <tt>eclipselink-dbws-schema.xsd</tt> (previously, Custom SQL produced Simplified XML Format docs whose schema was 'faked' to be <code><xsd:sequence> <xsd:any minOccurs="0"/> </xsd:sequence></code>)
 +
 
 +
Done
 +
 
 +
==== End-to-end SOAPMessage testing ====
 +
Built <code>dbws.testing.secondarysql.SecondarySQLTestSuite</code>
 +
 
 +
Done

Latest revision as of 13:54, 13 June 2011


{NB - this capability is available starting in version 2.2 of DBWS}

Custom SQL Design-time Schema

Overview

The use-case is the creation of a Web service that exposes the results of executing some custom SQL SELECT statement, without exposing the actual SQL. Currently, DBWS determines the 'shape' of the returned result at the time the SELECT statement is executed (i.e. at runtime, not design-time). For example, the following DBWSBuilder file produces a SXF (Simplified XML Format) document where the element tag names are direct copies of column names:

<?xml version="1.0" encoding="UTF-8"?>
<dbws-builder xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    <properties>
        <property name="projectName">Semployees</property>
        ...
    </properties>
    <sql
        name="Semployees"
        isCollection="false"
        >
        <text><![CDATA[select * from EMP where ENAME like 'S%']]></text>
    </sql>
</dbws-builder>
<?xml version = '1.0' encoding = 'UTF-8'?>
<simple-xml-format>
  <simple-xml>
    <EMPNO>7788</EMPNO>
    <ENAME>SCOTT</ENAME>
    <JOB>ANALYST</JOB>
    <MGR>7566</MGR>
    <HIREDATE>1987-04-19</HIREDATE>
    <SAL>3000</SAL>
    <DEPTNO>20</DEPTNO>
  </simple-xml>
  <simple-xml>
    <EMPNO>7369</EMPNO>
    <ENAME>SMITH</ENAME>
    <JOB>CLERK</JOB>
    <MGR>7902</MGR>
    <HIREDATE>1980-12-17</HIREDATE>
    <SAL>800</SAL>
    <DEPTNO>20</DEPTNO>
  </simple-xml>
</simple-xml-format>

New Capability: generate schema at design-time

The custom SQL SELECT statement is executed at design-time and the returned java.sql.ResultSet examined via the java.sql.ResultSetMetaData APIs - getColumnCount(), getColumnLabel(), getColumnType(int column), etc. From this information, an eclipselink-dbws-schema.xsd file is created along with all the other required DBWS meta files (eclipselink-dbws.xml, eclipselink-dbws.wsdl, eclipselink-dbws-ox.xml, etc.)

The resulting schema for the above example would be:

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:emp" xmlns="urn:emp" elementFormDefault="qualified">
   <xsd:complexType name="empType">
      <xsd:sequence>
         <xsd:element name="empno" type="xsd:decimal"/>
         <xsd:element name="ename" type="xsd:string" minOccurs="0" nillable="true"/>
         <xsd:element name="job" type="xsd:string" minOccurs="0" nillable="true"/>
         <xsd:element name="mgr" type="xsd:decimal" minOccurs="0" nillable="true"/>
         <xsd:element name="hiredate" type="xsd:date" minOccurs="0" nillable="true"/>
         <xsd:element name="sal" type="xsd:decimal" minOccurs="0" nillable="true"/>
         <xsd:element name="comm" type="xsd:decimal" minOccurs="0" nillable="true"/>
         <xsd:element name="deptno" type="xsd:decimal" minOccurs="0" nillable="true"/>
      </xsd:sequence>
   </xsd:complexType>
   <xsd:element name="empType" type="empType"/>
</xsd:schema>

Strategy

The key to this feature is the execution of the SELECT statement at design-time. The user must provide a primary and secondary SELECT statement. The secondary statement is optimized with a 'nonsense' WHERE clause (WHERE 0=1) (or optimized using platform-specific hints i.e.g SELECT TOP 1) to reduce the cost of preparing and executing the query. Even if no rows are returned, the ResultSet metadata will still have information about the number, name and type of columns involved in the query.

Work items

Changes to DBWS builder file

A new field build-statement is added to the sql Query operation:

<?xml version="1.0" encoding="UTF-8"?>
<dbws-builder xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    <properties>
        <property name="projectName">emp</property>
        ...
    </properties>
    <sql
        name="Semployees"
        isCollection="false"
        returnType="empType"
        >
        <statement><![CDATA[select * from EMP where ENAME like 'S%']]></statement>
        <build-statement><![CDATA[select * from EMP where 0=1]]></build-statement>
    </sql>
</dbws-builder>

The build-statement is executed and metadata from the resultSet analyzed to create an XSD schema. The top-level name for the schema type is specified by the returnType element. If the build-statement element is missing, then a SXF document will be built at runtime.

Done

Changes to JDBCHelper

Once the build-statement has been executed, the ResultSetMetaData is examined to extract:

  1. columnLabel - name of the column as specified in SQL statement; or, if a column alias used (e.g. SELECT COUNT(*) as 'employeeCount' from emp), the column alias.
  2. columnType - integer code corresponding to java.sql.Types (NB - some JDBC drivers and/or database use non-standard code numbers)
  3. columnTypeName - the symbolic name for the integer columnType
  4. precision, scale - for numeric data, precision is the total number of digits, scale the number of digits to the right of the decimal point.
  5. isNullable - can the column contain null values

Done

Changes to DBWSBuilder processing

Once the set of DbColumn's is built, OR and OX projects are created (very similar to the tables use-case). In addition to generating the eclipselink-dbws-or.xml and eclipselink-dbws-ox.xml, the eclipselink-dbws-schema.xsd file is auto-generated from the OX project (re-using SchemaModelGenerator)

Done

Limitation 1 - repeated labels: above it says 'set' - this points out a limitation with this feature. It is perfectly valid to have a SQL statement with multiple identical columns:

SELECT ENAME, ENAME FROM EMP WHERE 0=1
ENAME ENAME
SMITH SMITH
... ...
SCOTT SCOTT

The above is admittedly nonsensical, but a SELECT statement that uses UNION could return a set of column labels where a label is repeated.
DBWSBuilder will keep track of 'already processed columns' and throw an exception when it detects a duplicate.

Limitation 2 - compatible column label sets: the primary and secondary SQL statements must return compatible column label sets. At this time, no pre-processing is done to ensure that the column sets are the same; the error will be detected at runtime when the service is invoked.

Changes to WSDLGenerator

Integrate newly-generated eclipselink-dbws-schema.xsd (previously, Custom SQL produced Simplified XML Format docs whose schema was 'faked' to be <xsd:sequence> <xsd:any minOccurs="0"/> </xsd:sequence>)

Done

End-to-end SOAPMessage testing

Built dbws.testing.secondarysql.SecondarySQLTestSuite

Done

Back to the top