Author: shawkins
Date: 2010-03-22 17:01:44 -0400 (Mon, 22 Mar 2010)
New Revision: 1986
Added:
trunk/build/kit-jboss-container/teiid-examples/simpleclient/JDBCClient.class
trunk/client/src/main/java/org/teiid/adminapi/impl/
trunk/client/src/main/java/org/teiid/client/plan/
trunk/client/src/main/java/org/teiid/jdbc/
trunk/client/src/main/java/org/teiid/jdbc/BaseDataSource.java
trunk/client/src/main/java/org/teiid/jdbc/BatchResults.java
trunk/client/src/main/java/org/teiid/jdbc/CallableStatementImpl.java
trunk/client/src/main/java/org/teiid/jdbc/ConnectionImpl.java
trunk/client/src/main/java/org/teiid/jdbc/ConnectionListener.java
trunk/client/src/main/java/org/teiid/jdbc/DataTypeTransformer.java
trunk/client/src/main/java/org/teiid/jdbc/DatabaseMetaDataImpl.java
trunk/client/src/main/java/org/teiid/jdbc/DeferredMetadataProvider.java
trunk/client/src/main/java/org/teiid/jdbc/EmbeddedProfile.java
trunk/client/src/main/java/org/teiid/jdbc/ExecutionProperties.java
trunk/client/src/main/java/org/teiid/jdbc/FilteredResultsMetadata.java
trunk/client/src/main/java/org/teiid/jdbc/JDBCColumnNames.java
trunk/client/src/main/java/org/teiid/jdbc/JDBCColumnPositions.java
trunk/client/src/main/java/org/teiid/jdbc/JDBCPlugin.java
trunk/client/src/main/java/org/teiid/jdbc/JDBCURL.java
trunk/client/src/main/java/org/teiid/jdbc/MetadataProvider.java
trunk/client/src/main/java/org/teiid/jdbc/ParameterMetaDataImpl.java
trunk/client/src/main/java/org/teiid/jdbc/PartialResultsWarning.java
trunk/client/src/main/java/org/teiid/jdbc/PreparedStatementImpl.java
trunk/client/src/main/java/org/teiid/jdbc/ResultSetImpl.java
trunk/client/src/main/java/org/teiid/jdbc/ResultSetMetaDataImpl.java
trunk/client/src/main/java/org/teiid/jdbc/SQLStates.java
trunk/client/src/main/java/org/teiid/jdbc/SocketProfile.java
trunk/client/src/main/java/org/teiid/jdbc/StatementImpl.java
trunk/client/src/main/java/org/teiid/jdbc/TeiidDataSource.java
trunk/client/src/main/java/org/teiid/jdbc/TeiidDriver.java
trunk/client/src/main/java/org/teiid/jdbc/TeiidSQLException.java
trunk/client/src/main/java/org/teiid/jdbc/TeiidStatement.java
trunk/client/src/main/java/org/teiid/jdbc/WarningUtil.java
trunk/client/src/main/java/org/teiid/jdbc/WrapperImpl.java
trunk/client/src/main/java/org/teiid/jdbc/XAConnectionImpl.java
trunk/client/src/main/java/org/teiid/jdbc/XAResourceImpl.java
trunk/client/src/main/resources/META-INF/
trunk/client/src/main/resources/org/teiid/jdbc/
trunk/client/src/test/java/org/teiid/jdbc/
trunk/client/src/test/java/org/teiid/jdbc/TestAllResultsImpl.java
trunk/client/src/test/java/org/teiid/jdbc/TestBatchResults.java
trunk/client/src/test/java/org/teiid/jdbc/TestDataTypeTransformer.java
trunk/client/src/test/java/org/teiid/jdbc/TestEmbeddedProfile.java
trunk/client/src/test/java/org/teiid/jdbc/TestMMCallableStatement.java
trunk/client/src/test/java/org/teiid/jdbc/TestMMConnection.java
trunk/client/src/test/java/org/teiid/jdbc/TestMMDriver.java
trunk/client/src/test/java/org/teiid/jdbc/TestMMJDBCURL.java
trunk/client/src/test/java/org/teiid/jdbc/TestMMPreparedStatement.java
trunk/client/src/test/java/org/teiid/jdbc/TestMMResultSet.java
trunk/client/src/test/java/org/teiid/jdbc/TestMMSQLException.java
trunk/client/src/test/java/org/teiid/jdbc/TestMMStatement.java
trunk/client/src/test/java/org/teiid/jdbc/TestMMXAConnection.java
trunk/client/src/test/java/org/teiid/jdbc/TestSocketProfile.java
trunk/client/src/test/java/org/teiid/jdbc/TestTeiidDataSource.java
trunk/client/src/test/java/org/teiid/jdbc/TestTeiidDriver.java
trunk/client/src/test/java/org/teiid/jdbc/TestWrapperImpl.java
trunk/client/src/test/java/org/teiid/jdbc/plan/
trunk/client/src/test/java/org/teiid/jdbc/util/
Removed:
trunk/build/kit-jboss-container/teiid-examples/simpleclient/JDBCClient.class
trunk/client-jdbc/
trunk/engine/src/main/java/org/teiid/adminapi/impl/
Modified:
trunk/adminshell/pom.xml
trunk/build/assembly/client-jar.xml
trunk/client/pom.xml
trunk/client/src/main/java/org/teiid/client/plan/Annotation.java
trunk/client/src/main/java/org/teiid/client/plan/DefaultDisplayHelper.java
trunk/client/src/main/java/org/teiid/client/plan/DisplayHelper.java
trunk/client/src/main/java/org/teiid/client/plan/PlanNode.java
trunk/client/src/main/java/org/teiid/client/plan/PlanVisitor.java
trunk/client/src/main/java/org/teiid/client/plan/TextOutputVisitor.java
trunk/client/src/main/java/org/teiid/client/plan/XMLOutputVisitor.java
trunk/client/src/test/java/org/teiid/jdbc/plan/TestTextOutputVisitor.java
trunk/client/src/test/java/org/teiid/jdbc/plan/TestXMLOutputVisitor.java
trunk/console/pom.xml
trunk/engine/src/main/java/org/teiid/dqp/internal/transaction/TransactionServerImpl.java
trunk/jboss-integration/pom.xml
trunk/pom.xml
trunk/runtime/pom.xml
trunk/test-integration/db/pom.xml
trunk/test-integration/pom.xml
Log:
TEIID-918 combining client-jdbc and client
Modified: trunk/adminshell/pom.xml
===================================================================
--- trunk/adminshell/pom.xml 2010-03-22 20:34:29 UTC (rev 1985)
+++ trunk/adminshell/pom.xml 2010-03-22 21:01:44 UTC (rev 1986)
@@ -20,11 +20,6 @@
<artifactId>teiid-client</artifactId>
<scope>provided</scope>
</dependency>
- <dependency>
- <groupId>org.jboss.teiid</groupId>
- <artifactId>teiid-client-jdbc</artifactId>
- <scope>provided</scope>
- </dependency>
<dependency>
<groupId>beanshell</groupId>
Modified: trunk/build/assembly/client-jar.xml
===================================================================
--- trunk/build/assembly/client-jar.xml 2010-03-22 20:34:29 UTC (rev 1985)
+++ trunk/build/assembly/client-jar.xml 2010-03-22 21:01:44 UTC (rev 1986)
@@ -16,7 +16,6 @@
<includes>
<include>org.jboss.teiid:teiid-client</include>
- <include>org.jboss.teiid:teiid-client-jdbc</include>
<include>org.jboss.teiid:teiid-common-core</include>
</includes>
Deleted: trunk/build/kit-jboss-container/teiid-examples/simpleclient/JDBCClient.class
===================================================================
(Binary files differ)
Added: trunk/build/kit-jboss-container/teiid-examples/simpleclient/JDBCClient.class
===================================================================
(Binary files differ)
Property changes on:
trunk/build/kit-jboss-container/teiid-examples/simpleclient/JDBCClient.class
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Modified: trunk/client/pom.xml
===================================================================
--- trunk/client/pom.xml 2010-03-22 20:34:29 UTC (rev 1985)
+++ trunk/client/pom.xml 2010-03-22 21:01:44 UTC (rev 1986)
@@ -1,26 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
-<project
xmlns="http://maven.apache.org/POM/4.0.0"
-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
- <parent>
- <artifactId>teiid</artifactId>
- <groupId>org.jboss.teiid</groupId>
- <version>7.0.0-SNAPSHOT</version>
- </parent>
- <modelVersion>4.0.0</modelVersion>
- <artifactId>teiid-client</artifactId>
- <name>Client</name>
- <description>Contains the packages related to communication, administrative api,
+<project
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <artifactId>teiid</artifactId>
+ <groupId>org.jboss.teiid</groupId>
+ <version>7.0.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>teiid-client</artifactId>
+ <name>Client</name>
+ <description>Contains the packages related to communication, administrative api,
sessioning and transport level messaging.</description>
- <dependencies>
- <dependency>
- <groupId>org.jboss.teiid</groupId>
- <artifactId>teiid-common-core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.jboss.teiid</groupId>
- <artifactId>teiid-common-core</artifactId>
- <type>test-jar</type>
- </dependency>
- </dependencies>
+ <dependencies>
+ <dependency>
+ <groupId>org.jboss.teiid</groupId>
+ <artifactId>teiid-common-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.teiid</groupId>
+ <artifactId>teiid-common-core</artifactId>
+ <type>test-jar</type>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.man</groupId>
+ <artifactId>jboss-managed</artifactId>
+ </dependency>
+ </dependencies>
</project>
\ No newline at end of file
Copied: trunk/client/src/main/java/org/teiid/adminapi/impl (from rev 1983,
trunk/engine/src/main/java/org/teiid/adminapi/impl)
Copied: trunk/client/src/main/java/org/teiid/client/plan (from rev 1983,
trunk/client-jdbc/src/main/java/org/teiid/jdbc/plan)
Modified: trunk/client/src/main/java/org/teiid/client/plan/Annotation.java
===================================================================
--- trunk/client-jdbc/src/main/java/org/teiid/jdbc/plan/Annotation.java 2010-03-22
14:47:51 UTC (rev 1983)
+++ trunk/client/src/main/java/org/teiid/client/plan/Annotation.java 2010-03-22 21:01:44
UTC (rev 1986)
@@ -20,7 +20,7 @@
* 02110-1301 USA.
*/
-package org.teiid.jdbc.plan;
+package org.teiid.client.plan;
/**
Modified: trunk/client/src/main/java/org/teiid/client/plan/DefaultDisplayHelper.java
===================================================================
---
trunk/client-jdbc/src/main/java/org/teiid/jdbc/plan/DefaultDisplayHelper.java 2010-03-22
14:47:51 UTC (rev 1983)
+++ trunk/client/src/main/java/org/teiid/client/plan/DefaultDisplayHelper.java 2010-03-22
21:01:44 UTC (rev 1986)
@@ -20,7 +20,7 @@
* 02110-1301 USA.
*/
-package org.teiid.jdbc.plan;
+package org.teiid.client.plan;
import java.util.ArrayList;
import java.util.List;
Modified: trunk/client/src/main/java/org/teiid/client/plan/DisplayHelper.java
===================================================================
--- trunk/client-jdbc/src/main/java/org/teiid/jdbc/plan/DisplayHelper.java 2010-03-22
14:47:51 UTC (rev 1983)
+++ trunk/client/src/main/java/org/teiid/client/plan/DisplayHelper.java 2010-03-22
21:01:44 UTC (rev 1986)
@@ -20,7 +20,7 @@
* 02110-1301 USA.
*/
-package org.teiid.jdbc.plan;
+package org.teiid.client.plan;
import java.util.List;
Modified: trunk/client/src/main/java/org/teiid/client/plan/PlanNode.java
===================================================================
--- trunk/client-jdbc/src/main/java/org/teiid/jdbc/plan/PlanNode.java 2010-03-22 14:47:51
UTC (rev 1983)
+++ trunk/client/src/main/java/org/teiid/client/plan/PlanNode.java 2010-03-22 21:01:44 UTC
(rev 1986)
@@ -20,7 +20,7 @@
* 02110-1301 USA.
*/
-package org.teiid.jdbc.plan;
+package org.teiid.client.plan;
import java.util.*;
Modified: trunk/client/src/main/java/org/teiid/client/plan/PlanVisitor.java
===================================================================
--- trunk/client-jdbc/src/main/java/org/teiid/jdbc/plan/PlanVisitor.java 2010-03-22
14:47:51 UTC (rev 1983)
+++ trunk/client/src/main/java/org/teiid/client/plan/PlanVisitor.java 2010-03-22 21:01:44
UTC (rev 1986)
@@ -20,7 +20,7 @@
* 02110-1301 USA.
*/
-package org.teiid.jdbc.plan;
+package org.teiid.client.plan;
import java.util.Collection;
import java.util.LinkedList;
Modified: trunk/client/src/main/java/org/teiid/client/plan/TextOutputVisitor.java
===================================================================
--- trunk/client-jdbc/src/main/java/org/teiid/jdbc/plan/TextOutputVisitor.java 2010-03-22
14:47:51 UTC (rev 1983)
+++ trunk/client/src/main/java/org/teiid/client/plan/TextOutputVisitor.java 2010-03-22
21:01:44 UTC (rev 1986)
@@ -20,7 +20,7 @@
* 02110-1301 USA.
*/
-package org.teiid.jdbc.plan;
+package org.teiid.client.plan;
import java.util.Collection;
import java.util.HashMap;
Modified: trunk/client/src/main/java/org/teiid/client/plan/XMLOutputVisitor.java
===================================================================
--- trunk/client-jdbc/src/main/java/org/teiid/jdbc/plan/XMLOutputVisitor.java 2010-03-22
14:47:51 UTC (rev 1983)
+++ trunk/client/src/main/java/org/teiid/client/plan/XMLOutputVisitor.java 2010-03-22
21:01:44 UTC (rev 1986)
@@ -20,7 +20,7 @@
* 02110-1301 USA.
*/
-package org.teiid.jdbc.plan;
+package org.teiid.client.plan;
import java.util.Collection;
import java.util.HashMap;
Copied: trunk/client/src/main/java/org/teiid/jdbc/BaseDataSource.java (from rev 1983,
trunk/client-jdbc/src/main/java/org/teiid/jdbc/BaseDataSource.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/BaseDataSource.java
(rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/BaseDataSource.java 2010-03-22 21:01:44 UTC
(rev 1986)
@@ -0,0 +1,850 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.io.PrintWriter;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Properties;
+
+import javax.sql.ConnectionPoolDataSource;
+import javax.sql.PooledConnection;
+import javax.sql.XAConnection;
+import javax.sql.XADataSource;
+
+import org.teiid.client.RequestMessage;
+import org.teiid.net.TeiidURL;
+
+
+
+
+/**
+ * The Teiid JDBC DataSource implementation class of {@link javax.sql.DataSource} and
+ * {@link javax.sql.XADataSource}.
+ * <p>
+ * The {@link javax.sql.DataSource} interface follows the JavaBean design pattern,
+ * meaning the implementation class has <i>properties</i> that are accessed
with getter methods
+ * and set using setter methods, and where the getter and setter methods follow the
JavaBean
+ * naming convention (e.g.,
<code>get</code><i>PropertyName</i><code>() :
</code><i>PropertyType</i>
+ * and
<code>set</code><i>PropertyName</i><code>(</code><i>PropertyType</i><code>)
: void</code>).
+ * </p>
+ * The {@link javax.sql.XADataSource} interface is almost identical to the {@link
javax.sql.DataSource}
+ * interface, but rather than returning {@link java.sql.Connection} instances, there are
methods that
+ * return {@link javax.sql.XAConnection} instances that can be used with distributed
transactions.
+ * <p>
+ * The following are the properties for this DataSource:
+ * <table cellspacing="0" cellpadding="0" border="1"
width="100%">
+ * <tr><td><b>Property
Name</b></td><td><b>Type</b></td><td><b>Description</b></td></tr>
+ * <tr><td>applicationName
</td><td><code>String</code></td><td>The
<i>optional</i> name of the application using the
DataSource.</td></tr>
+ * <tr><td>clientToken
</td><td><code>Serializable</code></td><td>The
<i>optional</i> client token that will be passed directly
+ * through to the
connectors, which may use it and/or pass it
+ * down to their
underlying data source.
+ * <p>
+ * The form and type of
the client token is up to the client but it <i>must</i> implement the
+ *
<code>Serializable</code> interface. Teiid does nothing with this token
except to make it
+ * available for
authentication/augmentation/replacement upon authentication to the system and to
+ * connectors that may
require it at the data source level.
+ *
</p></td></tr>
+ * <tr><td>databaseName
</td><td><code>String</code></td><td>The name of a
particular virtual database on a
+ * Teiid
Server.</td></tr>
+ * <tr><td>databaseVersion
</td><td><code>String</code></td><td>The
<i>optional</i> version of a particular
+ * virtual database on a
Teiid Server;
+ * if not supplied, then
the latest version is assumed.</td></tr>
+ * <tr><td>dataSourceName
</td><td><code>String</code></td><td>The
<i>optional</i> logical name for the underlying
+ *
<code>XADataSource</code> or
<code>ConnectionPoolDataSource</code>;
+ * used only when pooling
connections or distributed transactions
+ * are
implemented.</td></tr>
+ * <tr><td>description
</td><td><code>String</code></td><td>The
<i>optional</i> description of this data source.</td></tr>
+ * <tr><td>logFile
</td><td><code>String</code></td><td>The
<i>optional</i> path and file name to which JDBC Log Statements
+ * will be written; if
none is specified, then no
+ * Log Statements will be
written.</td></tr>
+ * <tr><td>logLevel </td><td><code>int
</code></td><td>The <i>optional</i> level for logging, which
only applies
+ * if the
<code>logFile</code> property is set. Value must be
+ * one of the following:
+ * <ul>
+ *
<li>"<code>0</code>" - no JDBC log messages will be written to
the file;
+ * this is the
default</li>
+ *
<li>"<code>1</code>" - all JDBC log messages will be written
to the file</li>
+ *
<li>"<code>2</code>" - all JDBC log messages as well as stack
traces
+ * of any
exceptions thrown from this driver will be written
+ * to the
file</li>
+ * </ul>
+ *
<tr><td>password</td><td><code>String</code></td><td>The
user's password.</td></tr>
+ *
<tr><td>user</td><td><code>String</code></td><td>The
user name to use for the connection.</td></tr>
+ *
<tr><td>partialResultsMode</td><td><code>boolean</code></td><td>Support
partial results mode or not. </td></tr>
+ *
<tr><td>fetchSize</td><td><code>int</code></td><td>Set
default fetch size for statements, default=500.</td></tr>
+ *
<tr><td>sqlOptions</td><td><code>String</code></td><td>Set
sql options to use on every command. default=null</td></tr>
+ * <table>
+ * </p>
+ */
+public abstract class BaseDataSource extends WrapperImpl implements javax.sql.DataSource,
XADataSource, ConnectionPoolDataSource, java.io.Serializable {
+ public static final String DEFAULT_APP_NAME = "JDBC"; //$NON-NLS-1$
+
+ // constant indicating Virtual database name
+ public static final String VDB_NAME = TeiidURL.JDBC.VDB_NAME;
+ // constant indicating Virtual database version
+ public static final String VDB_VERSION = TeiidURL.JDBC.VDB_VERSION;
+ // constant for vdb version part of serverURL
+ public static final String VERSION = TeiidURL.JDBC.VERSION;
+ // name of the application which is obtaining connection
+ public static final String APP_NAME = TeiidURL.CONNECTION.APP_NAME;
+ // constant for username part of url
+ public static final String USER_NAME = TeiidURL.CONNECTION.USER_NAME;
+ // constant for password part of url
+ public static final String PASSWORD = TeiidURL.CONNECTION.PASSWORD;
+
+ protected static final int DEFAULT_TIMEOUT = 0;
+ protected static final int DEFAULT_LOG_LEVEL = 0;
+
+ /**
+ * The name of the virtual database on a particular Teiid Server.
+ * This property name is one of the standard property names defined by the JDBC 2.0
specification,
+ * and is <i>required</i>.
+ */
+ private String databaseName;
+
+ /**
+ * The logical name for the underlying <code>XADataSource</code> or
+ * <code>ConnectionPoolDataSource</code>;
+ * used only when pooling connections or distributed transactions are implemented.
+ * This property name is one of the standard property names defined by the JDBC 2.0
specification,
+ * and is <i>optional</i>.
+ */
+ private String dataSourceName;
+
+ /**
+ * The description of this data source.
+ * This property name is one of the standard property names defined by the JDBC 2.0
specification,
+ * and is <i>optional</i>.
+ */
+ private String description;
+
+
+ /**
+ * The user's name.
+ * This property name is one of the standard property names defined by the JDBC 2.0
specification,
+ * and is <i>required</i>.
+ */
+ private String user;
+
+ /**
+ * The user's password.
+ * This property name is one of the standard property names defined by the JDBC 2.0
specification,
+ * and is <i>required</i>.
+ */
+ private String password;
+
+ /**
+ * The version number of the virtual database to which a connection is to be
established.
+ * This property is <i>optional</i>; if not specified, the assumption is
that the latest version
+ * on the Teiid Server is to be used.
+ */
+ private String databaseVersion;
+
+ /**
+ * The name of the application. Supplying this property may allow an administrator
of a
+ * Teiid Server to better identify individual connections and usage patterns.
+ * This property is <i>optional</i>.
+ */
+ private String applicationName;
+
+ /** Support partial results mode or not.*/
+ private String partialResultsMode;
+
+ /** Default fetch size, <= 0 indicates not set. */
+ private int fetchSize = BaseDataSource.DEFAULT_FETCH_SIZE;
+
+ /** Whether to use result set cache if it available **/
+ private String resultSetCacheMode;
+
+ /**
+ * The number of milliseconds before timing out.
+ * This property is <i>optional</i> and defaults to "0"
(meaning no time out).
+ */
+ private int loginTimeout;
+
+ private String sqlOptions;
+
+ private String disableLocalTxn;
+
+ private String transactionAutoWrap;
+
+ private boolean ansiQuotedIdentifiers = true;
+
+ /**
+ * Reference to the logWriter, which is transient and is therefore not serialized
with the DataSource.
+ */
+ private transient PrintWriter logWriter;
+ public static final String JDBC = "jdbc:"; //$NON-NLS-1$
+ // Default execution property constants
+ protected static final int DEFAULT_FETCH_SIZE = RequestMessage.DEFAULT_FETCH_SIZE;
+ protected static final String DEFAULT_PARTIAL_RESULTS_MODE = "FALSE";
//$NON-NLS-1$
+ protected static final String DEFAULT_RESULT_SET_CACHE_MODE = "TRUE";
//$NON-NLS-1$
+
+ /**
+ * Transaction auto wrap constant - never wrap a command execution in a transaction
+ * and allow multi-source updates to occur outside of a transaction.
+ */
+ public static final String TXN_WRAP_OFF = ExecutionProperties.TXN_WRAP_OFF;
+
+ /**
+ * Transaction auto wrap constant - always wrap every non-transactional command
+ * execution in a transaction.
+ */
+ public static final String TXN_WRAP_ON = ExecutionProperties.TXN_WRAP_ON;
+
+ /**
+ * Transaction auto wrap constant - checks if a command
+ * requires a transaction and will be automatically wrap it.
+ */
+ public static final String TXN_WRAP_AUTO = ExecutionProperties.TXN_WRAP_DETECT;
+
+ /**
+ * String to hold additional properties that are not represented with an explicit
getter/setter
+ */
+ private String additionalProperties;
+
+ /**
+ * Constructor for MMDataSource.
+ */
+ public BaseDataSource() {
+ this.loginTimeout = DEFAULT_TIMEOUT;
+ }
+
+ //
--------------------------------------------------------------------------------------------
+ // H E L P E R M E T H O D S
+ //
--------------------------------------------------------------------------------------------
+
+ protected Properties buildProperties(final String userName, final String password) {
+ Properties props = new Properties();
+ props.setProperty(BaseDataSource.VDB_NAME,this.getDatabaseName());
+
+ if ( this.getDatabaseVersion() != null &&
this.getDatabaseVersion().trim().length() != 0 ) {
+ props.setProperty(BaseDataSource.VDB_VERSION,this.getDatabaseVersion());
+ }
+
+ if ( userName != null && userName.trim().length() != 0) {
+ props.setProperty(BaseDataSource.USER_NAME, userName);
+ } else if ( this.getUser() != null && this.getUser().trim().length() !=
0) {
+ props.setProperty(BaseDataSource.USER_NAME, this.getUser());
+ }
+
+ if ( password != null && password.trim().length() != 0) {
+ props.setProperty(BaseDataSource.PASSWORD, password);
+ } else if ( this.getPassword() != null &&
this.getPassword().trim().length() != 0) {
+ props.setProperty(BaseDataSource.PASSWORD, this.getPassword());
+ }
+
+ if ( this.getApplicationName() != null &&
this.getApplicationName().trim().length() != 0 ) {
+ props.setProperty(BaseDataSource.APP_NAME,this.getApplicationName());
+ }
+
+ if (this.getPartialResultsMode() != null &&
this.getPartialResultsMode().trim().length() != 0) {
+ props.setProperty(ExecutionProperties.PROP_PARTIAL_RESULTS_MODE,
this.getPartialResultsMode());
+ }
+
+ if(this.getFetchSize() > 0) {
+ props.setProperty(ExecutionProperties.PROP_FETCH_SIZE, "" +
this.getFetchSize()); //$NON-NLS-1$
+ }
+
+ if (this.getResultSetCacheMode() != null &&
this.getResultSetCacheMode().trim().length() != 0) {
+ props.setProperty(ExecutionProperties.RESULT_SET_CACHE_MODE,
this.getResultSetCacheMode());
+ }
+
+ if (this.getSqlOptions() != null) {
+ props.setProperty(ExecutionProperties.PROP_SQL_OPTIONS,
this.getSqlOptions());
+ }
+
+ if ( this.getTransactionAutoWrap() != null &&
this.getTransactionAutoWrap().trim().length() != 0 ) {
+ props.setProperty(ExecutionProperties.PROP_TXN_AUTO_WRAP,
this.getTransactionAutoWrap());
+ }
+
+ if (this.getDisableLocalTxn() != null) {
+ props.setProperty(ExecutionProperties.DISABLE_LOCAL_TRANSACTIONS,
this.getDisableLocalTxn());
+ }
+
+ if (this.additionalProperties != null) {
+ JDBCURL.parseConnectionProperties(this.additionalProperties, props);
+ }
+
+ return props;
+ }
+
+ protected void validateProperties( final String userName, final String password)
throws java.sql.SQLException {
+ String reason = reasonWhyInvalidApplicationName(this.applicationName);
+ if ( reason != null ) {
+ throw new SQLException(reason);
+ }
+
+ reason = reasonWhyInvalidDatabaseName(this.databaseName);
+ if ( reason != null ) {
+ throw new SQLException(reason);
+ }
+
+ reason = reasonWhyInvalidDatabaseVersion(this.databaseVersion);
+ if ( reason != null ) {
+ throw new SQLException(reason);
+ }
+
+ reason = reasonWhyInvalidDataSourceName(this.dataSourceName);
+ if ( reason != null ) {
+ throw new SQLException(reason);
+ }
+
+ reason = reasonWhyInvalidDescription(this.description);
+ if ( reason != null ) {
+ throw new SQLException(reason);
+ }
+
+ final String pwd = password != null ? password : getPassword();
+ reason = reasonWhyInvalidPassword(pwd);
+ if ( reason != null ) {
+ throw new SQLException(reason);
+ }
+
+ reason = reasonWhyInvalidPartialResultsMode(this.partialResultsMode);
+ if (reason != null) {
+ throw new SQLException(reason);
+ }
+
+ reason = reasonWhyInvalidFetchSize(this.fetchSize);
+ if (reason != null) {
+ throw new SQLException(reason);
+ }
+
+ final String user = userName != null ? userName : getUser();
+ reason = reasonWhyInvalidUser(user);
+ if ( reason != null ) {
+ throw new SQLException(reason);
+ }
+
+ reason = reasonWhyInvalidTransactionAutoWrap(this.transactionAutoWrap);
+ if ( reason != null ) {
+ throw new SQLException(reason);
+ }
+
+
+ }
+
+ //
--------------------------------------------------------------------------------------------
+ // D A T A S O U R C E M E T H O D S
+ //
--------------------------------------------------------------------------------------------
+
+ /**
+ * Attempt to establish a database connection.
+ * @return a Connection to the database
+ * @throws java.sql.SQLException if a database-access error occurs
+ * @see javax.sql.DataSource#getConnection()
+ */
+ public Connection getConnection() throws java.sql.SQLException {
+ return getConnection(null,null);
+ }
+
+ /**
+ * @see javax.sql.XADataSource#getXAConnection()
+ */
+ public XAConnection getXAConnection() throws SQLException {
+ return getXAConnection(null,null);
+ }
+
+ /**
+ * Attempt to establish a database connection that can be used with distributed
transactions.
+ * @param userName the database user on whose behalf the XAConnection is being made
+ * @param password the user's password
+ * @return an XAConnection to the database
+ * @throws java.sql.SQLException if a database-access error occurs
+ * @see javax.sql.XADataSource#getXAConnection(java.lang.String, java.lang.String)
+ */
+ public XAConnection getXAConnection(final String userName, final String password)
throws java.sql.SQLException {
+ return XAConnectionImpl.newInstance(new XAConnectionImpl.ConnectionSource() {
+
+ public ConnectionImpl createConnection() throws SQLException {
+ return (ConnectionImpl)getConnection(userName, password);
+ }});
+ }
+
+ public PooledConnection getPooledConnection() throws SQLException {
+ return getPooledConnection(null, null);
+ }
+
+ public PooledConnection getPooledConnection(final String userName, final String
password)
+ throws SQLException {
+ return getXAConnection(userName, password);
+ }
+
+ //
--------------------------------------------------------------------------------------------
+ // P R O P E R T Y M E T H O D S
+ //
--------------------------------------------------------------------------------------------
+
+ public String getDisableLocalTxn() {
+ return disableLocalTxn;
+ }
+
+ public void setDisableLocalTxn(String disableLocalTxn) {
+ this.disableLocalTxn = disableLocalTxn;
+ }
+
+ /**
+ * Get the log writer for this data source.
+ * <p>
+ * The log writer is a character output stream to which all logging and tracing
+ * messages for this data source object instance will be printed. This includes
+ * messages printed by the methods of this object, messages printed by methods
+ * of other objects manufactured by this object, and so on. Messages printed
+ * to a data source specific log writer are not printed to the log writer
+ * associated with the {@link java.sql.DriverManager} class. When a DataSource object
is
+ * created the log writer is initially null, in other words, logging is disabled.
+ * @return the log writer for this data source, null if disabled
+ * @throws java.sql.SQLException if a database-access error occurs
+ * @see javax.sql.DataSource#getLogWriter()
+ */
+ public PrintWriter getLogWriter() throws java.sql.SQLException{
+ return this.logWriter;
+ }
+
+ /**
+ * Gets the maximum time in seconds that this data source can wait while attempting
+ * to connect to a database. A value of zero means that the timeout is the default
+ * system timeout if there is one; otherwise it means that there is no timeout.
+ * When a DataSource object is created the login timeout is initially zero.
+ * @return the data source login time limit
+ * @throws java.sql.SQLException if a database-access error occurs
+ * @see javax.sql.DataSource#getLoginTimeout()
+ */
+ public int getLoginTimeout() throws java.sql.SQLException {
+ return this.loginTimeout;
+ }
+
+ /**
+ * Set the log writer for this data source.
+ * <p>
+ * The log writer is a character output stream to which all logging and tracing
+ * messages for this data source object instance will be printed. This includes
+ * messages printed by the methods of this object, messages printed by methods
+ * of other objects manufactured by this object, and so on. Messages printed
+ * to a data source specific log writer are not printed to the log writer
+ * associated with the {@link java.sql.DriverManager} class. When a DataSource object
is
+ * created the log writer is initially null, in other words, logging is disabled.
+ * @param writer the log writer for this data source, null if disabled
+ * @throws java.sql.SQLException if a database-access error occurs
+ * @see javax.sql.DataSource#setLogWriter(java.io.PrintWriter)
+ */
+ public void setLogWriter( final PrintWriter writer) throws java.sql.SQLException{
+ this.logWriter = writer;
+ }
+
+ /**
+ * Sets the maximum time in seconds that this data source can wait while attempting
+ * to connect to a database. A value of zero means that the timeout is the default
+ * system timeout if there is one; otherwise it means that there is no timeout.
+ * When a DataSource object is created the login timeout is initially zero.
+ * @param timeOut the data source login time limit
+ * @throws java.sql.SQLException if a database-access error occurs
+ * @see javax.sql.DataSource#setLoginTimeout(int)
+ */
+ public void setLoginTimeout( final int timeOut) throws java.sql.SQLException {
+ this.loginTimeout = timeOut;
+ }
+
+ /**
+ * Returns the name of the application. Supplying this property may allow an
administrator of a
+ * Teiid Server to better identify individual connections and usage patterns.
+ * This property is <i>optional</i>.
+ * @return String the application name; may be null or zero-length
+ */
+ public String getApplicationName() {
+ return applicationName!=null?applicationName:DEFAULT_APP_NAME;
+ }
+
+ /**
+ * Returns the name of the virtual database on a particular Teiid Server.
+ * @return String
+ */
+ public String getDatabaseName() {
+ return databaseName;
+ }
+
+ /**
+ * Returns the databaseVersion.
+ * @return String
+ */
+ public String getDatabaseVersion() {
+ return databaseVersion;
+ }
+
+ /**
+ * Returns the logical name for the underlying <code>XADataSource</code>
or
+ * <code>ConnectionPoolDataSource</code>;
+ * used only when pooling connections or distributed transactions are implemented.
+ * @return the logical name for the underlying data source; may be null
+ */
+ public String getDataSourceName() {
+ return dataSourceName;
+ }
+
+ /**
+ * Returns the description of this data source.
+ * @return the description; may be null
+ */
+ public String getDescription() {
+ return description;
+ }
+
+ /**
+ * Returns the user.
+ * @return the name of the user for this data source
+ */
+ public String getUser() {
+ return user;
+ }
+
+ /**
+ * Returns the password.
+ * @return the password for this data source.
+ */
+ public String getPassword() {
+ return password;
+ }
+
+ /**
+< * Sets the name of the application. Supplying this property may allow an
administrator of a
+ * Teiid Server to better identify individual connections and usage patterns.
+ * This property is <i>optional</i>.
+ * @param applicationName The applicationName to set
+ */
+ public void setApplicationName(final String applicationName) {
+ this.applicationName = applicationName;
+ }
+
+ /**
+ * Sets the name of the virtual database on a particular Teiid Server.
+ * @param databaseName The name of the virtual database
+ */
+ public void setDatabaseName(final String databaseName) {
+ this.databaseName = databaseName;
+ }
+
+ /**
+ * Sets the databaseVersion.
+ * @param databaseVersion The version of the virtual database
+ */
+ public void setDatabaseVersion(final String databaseVersion) {
+ this.databaseVersion = databaseVersion;
+ }
+
+ /**
+ * Sets the logical name for the underlying <code>XADataSource</code> or
+ * <code>ConnectionPoolDataSource</code>;
+ * used only when pooling connections or distributed transactions are implemented.
+ * @param dataSourceName The dataSourceName for this data source; may be null
+ */
+ public void setDataSourceName(final String dataSourceName) {
+ this.dataSourceName = dataSourceName;
+ }
+
+ /**
+ * Sets the user.
+ * @param user The user to set
+ */
+ public void setUser(final String user) {
+ this.user = user;
+ }
+
+ /**
+ * Sets the password.
+ * @param password The password for this data source
+ */
+ public void setPassword(final String password) {
+ this.password = password;
+ }
+
+ /**
+ * Sets the description of this data source.
+ * @param description The description for this data source; may be null
+ */
+ public void setDescription(final String description) {
+ this.description = description;
+ }
+
+ public void setPartialResultsMode(String partialResultsMode) {
+ this.partialResultsMode = partialResultsMode;
+ }
+
+ public String getPartialResultsMode() {
+ return this.partialResultsMode;
+ }
+
+ public void setFetchSize(int fetchSize) {
+ this.fetchSize = fetchSize;
+ }
+
+ public int getFetchSize() {
+ return this.fetchSize;
+ }
+
+ public void setResultSetCacheMode(String resultSetCacheMode) {
+ this.resultSetCacheMode = resultSetCacheMode;
+ }
+
+ public String getResultSetCacheMode() {
+ return this.resultSetCacheMode;
+ }
+
+ /**
+ * Get special sqlOptions string, which can currently be set only to SHOWPLAN
+ * @return Returns sqlOptions string or null if none
+ * @since 4.3
+ */
+ public String getSqlOptions() {
+ return this.sqlOptions;
+ }
+
+ /**
+ * Sets special sqlOptions that should be used with each command.
+ * @param sqlOptions SQL options, only "SHOWPLAN" is currently accepted
+ * @since 4.3
+ */
+ public void setSqlOptions(String sqlOptions) {
+ this.sqlOptions = sqlOptions;
+ }
+
+ /**
+ * @deprecated
+ * @see #getAutoCommitTxn()
+ * @return
+ */
+ public String getTransactionAutoWrap() {
+ return transactionAutoWrap;
+ }
+
+ /**
+ * @deprecated
+ * @see #setAutoCommitTxn(String)
+ * @param transactionAutoWrap
+ */
+ public void setTransactionAutoWrap(String transactionAutoWrap) {
+ this.transactionAutoWrap = transactionAutoWrap;
+ }
+
+ /**
+ * Returns the current setting for how connections are created by this DataSource
manage transactions
+ * for client requests when client applications do not use transactions.
+ * Because a virtual database will likely deal with multiple underlying information
sources,
+ * Teiid will execute all client requests within the contexts of transactions.
+ * This method determines the semantics of creating such transactions when the client
does not
+ * explicitly do so.
+ * @return the current setting, or null if the property has not been set and the
default mode will
+ * be used.
+ */
+ public String getAutoCommitTxn() {
+ return this.transactionAutoWrap;
+ }
+
+ /**
+ * Sets the setting for how connections are created by this DataSource manage
transactions
+ * for client requests with autoCommit = true.
+ * Because a virtual database will likely deal with multiple underlying information
sources,
+ * Teiid will execute all client requests within the contexts of transactions.
+ * This method determines the semantics of creating such transactions when the client
does not
+ * explicitly do so.
+ * <p>
+ * The allowable values for this property are:
+ * <ul>
+ * <li>"<code>OFF</code>" - Nothing is ever wrapped in
a transaction and the server will execute
+ * multi-source updates happily but outside a transaction. This is least safe but
highest performance.
+ * The {@link #TXN_WRAP_OFF} constant value is provided for convenience.</li>
+ * <li>"<code>ON</code>" - Always wrap every command in
a transaction. This is most safe but lowest
+ * performance.
+ * The {@link #TXN_WRAP_ON} constant value is provided for convenience.</li>
+ * <li>"<code>AUTO</code>" - checks if a command
requires a transaction and will be automatically wrap it.
+ * This is the default mode.
+ * The {@link #TXN_WRAP_AUTO} constant value is provided for convenience.</li>
+ * </ul>
+ * </p>
+ * @param transactionAutoWrap The transactionAutoWrap to set
+ */
+ public void setAutoCommitTxn(String transactionAutoWrap) {
+ this.transactionAutoWrap = transactionAutoWrap;
+ }
+
+ //
--------------------------------------------------------------------------------------------
+ // V A L I D A T I O N M E T H O D S
+ //
--------------------------------------------------------------------------------------------
+
+ /**
+ * Return the reason why the supplied application name may be invalid, or null
+ * if it is considered valid.
+ * @param applicationName a possible value for the property
+ * @return the reason why the property is invalid, or null if it is considered valid
+ * @see #setApplicationName(String)
+ */
+ public static String reasonWhyInvalidApplicationName( final String applicationName )
{
+ return null; // anything is valid
+ }
+
+
+
+ /**
+ * Return the reason why the supplied virtual database name may be invalid, or null
+ * if it is considered valid.
+ * @param databaseName a possible value for the property
+ * @return the reason why the property is invalid, or null if it is considered valid
+ * @see #setDatabaseName(String)
+ */
+ public static String reasonWhyInvalidDatabaseName( final String databaseName ) {
+ if ( databaseName == null || databaseName.trim().length() == 0 ) {
+ return
JDBCPlugin.Util.getString("MMDataSource.Virtual_database_name_must_be_specified");
//$NON-NLS-1$
+ }
+ return null;
+ }
+
+ /**
+ * Return the reason why the supplied user name may be invalid, or null
+ * if it is considered valid.
+ * @param userName a possible value for the property
+ * @return the reason why the property is invalid, or null if it is considered valid
+ * @see #setUser(String)
+ */
+ public static String reasonWhyInvalidUser( final String userName ) {
+ return null;
+ }
+
+ /**
+ * Return the reason why the supplied transaction auto wrap value may be invalid, or
null
+ * if it is considered valid.
+ * <p>
+ * This method checks to see that the value is one of the allowable values.
+ * </p>
+ * @param autoWrap a possible value for the auto wrap property.
+ * @return the reason why the property is invalid, or null if it is considered valid
+ * @see #setTransactionAutoWrap(String)
+ */
+ public static String reasonWhyInvalidTransactionAutoWrap( final String autoWrap ) {
+ if ( autoWrap == null || autoWrap.trim().length() == 0 ) {
+ return null; // no longer require an app server name, 'cause will look
on classpath
+ }
+ final String trimmedAutoWrap = autoWrap.trim();
+ if( TXN_WRAP_ON.equals(trimmedAutoWrap) ) {
+ return null;
+ }
+ if( TXN_WRAP_OFF.equals(trimmedAutoWrap) ) {
+ return null;
+ }
+ if( TXN_WRAP_AUTO.equals(trimmedAutoWrap) ) {
+ return null;
+ }
+
+ Object[] params = new Object[] {
+ TXN_WRAP_ON, TXN_WRAP_OFF, TXN_WRAP_AUTO };
+ return
JDBCPlugin.Util.getString("MMDataSource.Invalid_trans_auto_wrap_mode", params);
//$NON-NLS-1$
+ }
+
+ /**
+ * Return the reason why the supplied virtual database version may be invalid, or
null
+ * if it is considered valid.
+ * @param databaseVersion a possible value for the property
+ * @return the reason why the property is invalid, or null if it is considered valid
+ * @see #setDatabaseVersion(String)
+ */
+ public static String reasonWhyInvalidDatabaseVersion( final String databaseVersion )
{
+ return null; // anything is valid (let server validate)
+ }
+
+ /**
+ * Return the reason why the supplied data source name may be invalid, or null
+ * if it is considered valid.
+ * @param dataSourceName a possible value for the property
+ * @return the reason why the property is invalid, or null if it is considered valid
+ * @see #setDataSourceName(String)
+ */
+ public static String reasonWhyInvalidDataSourceName( final String dataSourceName) {
+ return null; // anything is valid
+ }
+
+ /**
+ * Return the reason why the supplied password may be invalid, or null
+ * if it is considered valid.
+ * @param pwd a possible value for the property
+ * @return the reason why the property is invalid, or null if it is considered valid
+ * @see #setPassword(String)
+ */
+ public static String reasonWhyInvalidPassword( final String pwd ) {
+ return null;
+ }
+
+ /**
+ * Return the reason why the supplied description may be invalid, or null
+ * if it is considered valid.
+ * @param description a possible value for the property
+ * @return the reason why the property is invalid, or null if it is considered valid
+ * @see #setDescription(String)
+ */
+ public static String reasonWhyInvalidDescription( final String description ) {
+ return null; // anything is valid
+ }
+
+ /**
+ * The reason why partialResultsMode is invalid.
+ * @param partialMode boolean flag
+ * @return String reason
+ */
+ public static String reasonWhyInvalidPartialResultsMode( final String partialMode) {
+ if ( partialMode != null ) {
+ if (partialMode.equalsIgnoreCase("true") ||
partialMode.equalsIgnoreCase("false")) { //$NON-NLS-1$ //$NON-NLS-2$
+ return null;
+ }
+ return
JDBCPlugin.Util.getString("MMDataSource.The_partial_mode_must_be_boolean._47");
//$NON-NLS-1$
+ }
+ return null;
+ }
+
+ /**
+ * The reason why fetchSize is invalid.
+ * @param fetchSize Number of rows per batch
+ * @return the reason why the property is invalid, or null if it is considered valid
+ */
+ public static String reasonWhyInvalidFetchSize( final int fetchSize) {
+ if ( fetchSize <= 0 ) {
+ return
JDBCPlugin.Util.getString("MMDataSource.The_fetch_size_must_be_greater_than_zero");
//$NON-NLS-1$
+ }
+ return null;
+ }
+
+ public void setAdditionalProperties(String additionalProperties) {
+ this.additionalProperties = additionalProperties;
+ }
+
+ public String getAdditionalProperties() {
+ return additionalProperties;
+ }
+
+ public void setAnsiQuotedIdentifiers(boolean ansiQuotedIdentifiers) {
+ this.ansiQuotedIdentifiers = ansiQuotedIdentifiers;
+ }
+
+ public boolean isAnsiQuotedIdentifiers() {
+ return ansiQuotedIdentifiers;
+ }
+
+}
+
Copied: trunk/client/src/main/java/org/teiid/jdbc/BatchResults.java (from rev 1983,
trunk/client-jdbc/src/main/java/org/teiid/jdbc/BatchResults.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/BatchResults.java
(rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/BatchResults.java 2010-03-22 21:01:44 UTC
(rev 1986)
@@ -0,0 +1,255 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.metamatrix.core.util.Assertion;
+
+/**
+ * @since 4.3
+ */
+public class BatchResults {
+
+ public interface BatchFetcher {
+ Batch requestBatch(int beginRow) throws SQLException;
+ }
+
+ static class Batch{
+ private List[] batch;
+ private int beginRow;
+ private int endRow;
+ private boolean isLast;
+
+ Batch(List[] batch, int beginRow, int endRow, boolean isLast){
+ this.batch = batch;
+ this.beginRow = beginRow;
+ this.endRow = endRow;
+ this.isLast = isLast;
+ }
+
+ int getLength() {
+ return batch.length;
+ }
+
+ List getRow(int index) {
+ return batch[index - beginRow];
+ }
+
+ int getBeginRow() {
+ return beginRow;
+ }
+
+ int getEndRow() {
+ return endRow;
+ }
+
+ boolean isLast() {
+ return isLast;
+ }
+
+ }
+
+ static final int DEFAULT_SAVED_BATCHES = 3;
+
+ private ArrayList<Batch> batches = new ArrayList<Batch>();
+
+ private int currentRowNumber;
+ private List<?> currentRow;
+ private int lastRowNumber = -1;
+ private int highestRowNumber;
+ private BatchFetcher batchFetcher;
+ private int savedBatches = DEFAULT_SAVED_BATCHES;
+
+ public BatchResults(List[] batch, int beginRow, int endRow, boolean isLast) {
+ this.setBatch(new Batch(batch, beginRow, endRow, isLast));
+ }
+
+ public BatchResults(BatchFetcher batchFetcher, Batch batch, int savedBatches) {
+ this.batchFetcher = batchFetcher;
+ this.savedBatches = savedBatches;
+ this.setBatch(batch);
+ }
+
+ /**
+ * Moving forward through the results it's expected that the batches are
arbitrarily size.
+ * Moving backward through the results it's expected that the batches will match
the fetch size.
+ */
+ public List getCurrentRow() throws SQLException {
+ if (currentRow != null) {
+ return currentRow;
+ }
+ if (this.currentRowNumber == 0 || (lastRowNumber != -1 &&
this.currentRowNumber > lastRowNumber)) {
+ return null;
+ }
+ for (int i = 0; i < batches.size(); i++) {
+ Batch batch = batches.get(i);
+ if (this.currentRowNumber < batch.getBeginRow()) {
+ continue;
+ }
+ if (this.currentRowNumber > batch.getEndRow()) {
+ continue;
+ }
+ if (i != 0) {
+ batches.add(0, batches.remove(i));
+ }
+ currentRow = batch.getRow(this.currentRowNumber);
+ return currentRow;
+ }
+ requestBatchAndWait(this.currentRowNumber);
+ Batch batch = batches.get(0);
+ currentRow = batch.getRow(this.currentRowNumber);
+ return currentRow;
+ }
+
+ private void requestNextBatch() throws SQLException {
+ requestBatchAndWait(highestRowNumber + 1);
+ }
+
+ public boolean next() throws SQLException{
+ if (hasNext()) {
+ setCurrentRowNumber(this.currentRowNumber + 1);
+ getCurrentRow();
+ return true;
+ }
+
+ if (this.currentRowNumber == highestRowNumber) {
+ setCurrentRowNumber(this.currentRowNumber + 1);
+ }
+
+ return false;
+ }
+
+ public boolean hasPrevious() {
+ return (this.currentRowNumber != 0 && this.currentRowNumber != 1);
+ }
+
+ public boolean previous() {
+ if (hasPrevious()) {
+ setCurrentRowNumber(this.currentRowNumber - 1);
+ return true;
+ }
+
+ if (this.currentRowNumber == 1) {
+ setCurrentRowNumber(this.currentRowNumber - 1);
+ }
+
+ return false;
+ }
+
+ public void setBatchFetcher(BatchFetcher batchFetcher) {
+ this.batchFetcher = batchFetcher;
+ }
+
+ public boolean absolute(int row) throws SQLException {
+ return absolute(row, 0);
+ }
+
+ public boolean absolute(int row, int offset) throws SQLException {
+ if(row == 0) {
+ setCurrentRowNumber(0);
+ return false;
+ }
+
+ if (row > 0) {
+ //row is greater than highest, but the last row is not known
+ while (row + offset > highestRowNumber && lastRowNumber == -1) {
+ requestNextBatch();
+ }
+
+ if (row + offset <= highestRowNumber) {
+ setCurrentRowNumber(row);
+ return true;
+ }
+
+ setCurrentRowNumber(lastRowNumber + 1 - offset);
+ return false;
+ }
+
+ row -= offset;
+
+ while (lastRowNumber == -1) {
+ requestNextBatch();
+ }
+
+ int positiveRow = lastRowNumber + row + 1;
+
+ if (positiveRow <= 0) {
+ setCurrentRowNumber(0);
+ return false;
+ }
+
+ setCurrentRowNumber(positiveRow);
+ return true;
+ }
+
+ public int getCurrentRowNumber() {
+ return currentRowNumber;
+ }
+
+ private void requestBatchAndWait(int beginRow) throws SQLException{
+ if (batches.size() == savedBatches) {
+ batches.remove(savedBatches - 1);
+ }
+ setBatch(batchFetcher.requestBatch(beginRow));
+ }
+
+ private void setBatch(Batch batch) {
+ Assertion.assertTrue(batch.getLength() != 0 || batch.isLast());
+ if (batch.isLast()) {
+ this.lastRowNumber = batch.getEndRow();
+ }
+ highestRowNumber = Math.max(batch.getEndRow(), highestRowNumber);
+ this.batches.add(0, batch);
+ }
+
+ public boolean hasNext() throws SQLException {
+ return hasNext(1);
+ }
+
+ public boolean hasNext(int next) throws SQLException {
+ while (this.currentRowNumber + next > highestRowNumber && lastRowNumber
== -1) {
+ requestNextBatch();
+ }
+
+ return (this.currentRowNumber + next <= highestRowNumber);
+ }
+
+ public int getFinalRowNumber() {
+ return lastRowNumber;
+ }
+
+ public int getHighestRowNumber() {
+ return highestRowNumber;
+ }
+
+ private void setCurrentRowNumber(int currentRowNumber) {
+ if (currentRowNumber != this.currentRowNumber) {
+ this.currentRow = null;
+ }
+ this.currentRowNumber = currentRowNumber;
+ }
+
+}
Copied: trunk/client/src/main/java/org/teiid/jdbc/CallableStatementImpl.java (from rev
1983, trunk/client-jdbc/src/main/java/org/teiid/jdbc/CallableStatementImpl.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/CallableStatementImpl.java
(rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/CallableStatementImpl.java 2010-03-22
21:01:44 UTC (rev 1986)
@@ -0,0 +1,788 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.CallableStatement;
+import java.sql.Clob;
+import java.sql.Date;
+import java.sql.Ref;
+import java.sql.SQLException;
+//## JDBC4.0-begin ##
+import java.sql.SQLXML;
+import java.sql.NClob;
+import java.sql.RowId;
+//## JDBC4.0-end ##
+
+/*## JDBC3.0-JDK1.5-begin ##
+import com.metamatrix.core.jdbc.SQLXML;
+## JDBC3.0-JDK1.5-end ##*/
+
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Calendar;
+import java.util.Map;
+
+import org.teiid.client.RequestMessage;
+import org.teiid.client.RequestMessage.ResultsMode;
+import org.teiid.client.RequestMessage.StatementType;
+
+import com.metamatrix.common.util.SqlUtil;
+import com.metamatrix.common.util.TimestampWithTimezone;
+
+/**
+ * <p> This class inherits Statement methods, which deal with SQL statements in
+ * general and also inherits PreparedStatement methods, which deal with IN parameters.
+ * This object provides a way to call stored procedures. This call
+ * is written in an escape syntax that may take one of two forms: one form with
+ * result parameter, and the other without one. A result parameter, a kind of OUT
+ * parameter is the return value for the stored procedure. Both forms may have a
+ * variable number of parameters used for input(IN parameters), output(OUT parameters),
+ * or both (INOUT parameters).</p>
+ * <p> The methods in this class can be used to retrieve values of OUT parameters
or
+ * the output aspect of INOUT parameters.</p>
+ */
+public class CallableStatementImpl extends PreparedStatementImpl implements
CallableStatement {
+
+ // object representing parameter value
+ private Object parameterValue;
+
+ /**
+ * Factory Constructor (be sure to cast it to MMCallableStatement)
+ */
+ static CallableStatementImpl newInstance(ConnectionImpl connection, String
procedureCall, int resultSetType, int resultSetConcurrency) throws SQLException {
+ return new CallableStatementImpl(connection, procedureCall, resultSetType,
resultSetConcurrency);
+ }
+
+ /**
+ * <p>MMCallableStatement constructor that sets the procedureName, IN
parameters
+ * and OUT parameters on this object.
+ * @param Driver's connection object which creates this object.
+ * @param procedureCall string
+ * @throws SQLException if there is an error parsing the call
+ */
+ CallableStatementImpl(ConnectionImpl connection, String procedureCall, int
resultSetType, int resultSetConcurrency) throws SQLException {
+ // set the connection on the super class
+ super(connection, procedureCall, resultSetType, resultSetConcurrency);
+ this.prepareSql = procedureCall;
+ }
+
+ @Override
+ protected RequestMessage createRequestMessage(String[] commands,
+ boolean isBatchedCommand, ResultsMode resultsMode) {
+ RequestMessage message = super.createRequestMessage(commands, isBatchedCommand,
resultsMode);
+ message.setStatementType(StatementType.CALLABLE);
+ return message;
+ }
+
+ /**
+ * In many cases, it is desirable to immediately release a Statements's database
+ * and JDBC resources instead of waiting for this to happen when it is automatically
+ * closed; the close method provides this immediate release.
+ * @throws SQLException should never occur.
+ */
+ public void close() throws SQLException {
+ this.prepareSql = null;
+ super.close();
+ }
+
+ /**
+ * <p>Gets the value of a OUTPUT parameter as a java.math.BigDecimal object
with
+ * scale digits to the right of the decimal point.
+ * @param parameterIndex whose value is to be fetched from the result.
+ * @return The parameter at the given index is returned as an BigDecimal object.
+ * @throws SQLException if param datatype is not NUMERIC
+ * @deprecated
+ */
+ public java.math.BigDecimal getBigDecimal(int parameterIndex, int scale) throws
SQLException {
+ BigDecimal bigDecimalParam =
DataTypeTransformer.getBigDecimal(getObject(parameterIndex));
+
+ // set scale on the param value
+ bigDecimalParam.setScale(scale);
+
+ // return param value
+ return bigDecimalParam;
+ }
+
+ /**
+ * <p>Gets the value of a OUTPUT parameter as a java.math.BigDecimal object.
+ * @param parameterIndex whose value is to be fetched from the result.
+ * @return The parameter at the given index is returned as an BigDecimal object.
+ * @throws SQLException if param datatype is not NUMERIC
+ */
+ public java.math.BigDecimal getBigDecimal(int parameterIndex) throws SQLException {
+ return DataTypeTransformer.getBigDecimal(getObject(parameterIndex));
+ }
+
+ /**
+ * <p>Gets the value of a OUTPUT parameter as a java.sql.Blob object.
+ * @param parameterIndex whose value is to be fetched from the result.
+ * @return The parameter at the given index is returned as a Blob object.
+ */
+ public Blob getBlob(int parameterIndex) throws SQLException {
+ return DataTypeTransformer.getBlob(getObject(parameterIndex));
+ }
+
+ /**
+ * <p>Gets the value of a OUTPUT parameter as a boolean.
+ * @param parameterIndex whose value is to be fetched from the result.
+ * @return The parameter at the given index is returned as a boolean value.
+ * @throws SQLException if param datatype is not BIT
+ */
+ public boolean getBoolean(int parameterIndex) throws SQLException {
+ return DataTypeTransformer.getBoolean(getObject(parameterIndex));
+ }
+
+ /**
+ * <p>Gets the value of a OUTPUT parameter as a byte.
+ * @param parameterIndex whose value is to be fetched from the result.
+ * @return The parameter at the given index is returned as a byte value.
+ * @throws SQLException if param datatype is not TINYINT
+ */
+ public byte getByte(int parameterIndex) throws SQLException {
+ return DataTypeTransformer.getByte(getObject(parameterIndex));
+ }
+
+ /**
+ * <p>Gets the value of a OUTPUT parameter as a java.sql.Clob object.
+ * @param parameterIndex whose value is to be fetched from the result.
+ * @return The parameter at the given index is returned as a Clob object.
+ */
+ public Clob getClob(int parameterIndex) throws SQLException {
+ return DataTypeTransformer.getClob(getObject(parameterIndex));
+ }
+
+ /**
+ * <p>Gets the value of a OUTPUT parameter as a java.sql.Date object.
+ * @param parameterIndex whose value is to be fetched from the result.
+ * @return The parameter at the given index is returned as a Date object.
+ * @throws SQLException if param datatype is not DATE
+ */
+ public java.sql.Date getDate(int parameterIndex) throws SQLException {
+ return getDate(parameterIndex, null);
+ }
+
+ /**
+ * <p>Gets the value of a OUTPUT parameter as a java.sql.Date object. Calender
+ * object contains the timezone info for the Date.
+ * @param parameterIndex whose value is to be fetched from the result.
+ * @param Calendar object used to construct the Date object.
+ * @return The parameter at the given index is returned as a Date object.
+ * @throws SQLException if param datatype is not DATE
+ */
+ public java.sql.Date getDate(int parameterIndex, Calendar cal) throws SQLException {
+ Date value = DataTypeTransformer.getDate(getObject(parameterIndex));
+
+ if (value == null) {
+ return null;
+ }
+
+ if (cal != null) {
+ value = TimestampWithTimezone.createDate(value,
getDefaultCalendar().getTimeZone(), cal);
+ }
+
+ return value;
+ }
+
+ /**
+ * <p>Gets the value of a OUTPUT parameter as a double.
+ * @param parameterIndex whose value is to be fetched from the result.
+ * @return The parameter at the given index is returned as a double value.
+ * @throws SQLException if param datatype is not DOUBLE or FLOAT
+ */
+ public double getDouble(int parameterIndex) throws SQLException {
+ return DataTypeTransformer.getDouble(getObject(parameterIndex));
+ }
+
+ /**
+ * <p>Gets the value of a OUTPUT parameter as a float.
+ * @param parameterIndex whose value is to be fetched from the result.
+ * @return The parameter at the given index is returned as a float value.
+ * @throws SQLException if param datatype is not FLOAT
+ */
+ public float getFloat(int parameterIndex) throws SQLException {
+ return DataTypeTransformer.getFloat(getObject(parameterIndex));
+ }
+
+ /**
+ * <p>Gets the value of a OUTPUT parameter as a int.
+ * @param parameterIndex whose value is to be fetched from the result.
+ * @return The parameter at the given index is returned as a int value.
+ * @throws SQLException if param datatype is not INTEGER
+ */
+ public int getInt(int parameterIndex) throws SQLException {
+ return DataTypeTransformer.getInteger(getObject(parameterIndex));
+ }
+
+ /**
+ * <p>Gets the value of a OUTPUT parameter as a long.
+ * @param parameterIndex whose value is to be fetched from the result.
+ * @return The parameter at the given index is returned as a long value.
+ * @throws SQLException if param datatype is not BIGINT
+ */
+ public long getLong(int parameterIndex) throws SQLException {
+ return DataTypeTransformer.getLong(getObject(parameterIndex));
+ }
+
+ /**
+ * <p>Gets the value of a OUTPUT parameter as an object.
+ * @param parameterIndex whose value is to be fetched from the result.
+ * @return The parameter at the given index is returned as an object.
+ * @throws SQLException
+ */
+ public Object getObject(int parameterIndex) throws SQLException {
+ //checkParameter(parameterIndex);
+
+ Object indexInResults = this.outParamIndexMap.get(new Integer(parameterIndex));
+ if(indexInResults == null){
+ throw new
IllegalArgumentException(JDBCPlugin.Util.getString("MMCallableStatement.Param_not_found",
parameterIndex)); //$NON-NLS-1$
+ }
+ checkStatement();
+ parameterValue =
resultSet.getOutputParamValue(((Integer)indexInResults).intValue());
+ return parameterValue;
+ }
+
+ /**
+ * <p>Gets the value of a OUTPUT parameter as a short.
+ * @param parameterIndex whose value is to be fetched from the result.
+ * @return The parameter at the given index is returned as a short value.
+ * @throws SQLException if param datatype is not SMALLINT
+ */
+ public short getShort(int parameterIndex) throws SQLException {
+ return DataTypeTransformer.getShort(getObject(parameterIndex));
+ }
+
+ /**
+ * <p>Gets the value of a OUTPUT parameter as a String.
+ * @param parameterIndex whose value is to be fetched from the result.
+ * @return The parameter at the given index is returned as a String object.
+ * @throws SQLException if param datatype is not CHAR, VARCHAR, LONGVARCHAR
+ */
+ public String getString(int parameterIndex) throws SQLException {
+ // return the parameter value a String object
+ return getObject(parameterIndex).toString();
+ }
+
+ /**
+ * <p>Gets the value of a OUTPUT parameter as a java.sql.Time object.
+ * @param parameterIndex whose value is to be fetched from the result.
+ * @return The parameter at the given index is returned as a Time object.
+ * @throws SQLException if param datatype is not TIME
+ */
+ public Time getTime(int parameterIndex) throws SQLException {
+ return getTime(parameterIndex, null);
+ }
+
+ /**
+ * <p>Gets the value of a OUTPUT parameter as a java.sql.Timestamp object.
Calendar
+ * object contains the timezone information.
+ * @param parameterIndex whose value is to be fetched from the result.
+ * @param Calendar object used to construct the Date object.
+ * @return The parameter at the given index is returned as a Time object.
+ * @throws SQLException if param datatype is not TIME
+ */
+ public Time getTime(int parameterIndex, java.util.Calendar cal) throws SQLException
{
+ Time value = DataTypeTransformer.getTime(getObject(parameterIndex));
+
+ if (value == null) {
+ return null;
+ }
+
+ if (cal != null) {
+ value = TimestampWithTimezone.createTime(value,
getDefaultCalendar().getTimeZone(), cal);
+ }
+
+ return value;
+ }
+
+ /**
+ * <p>Gets the value of a OUTPUT parameter as a java.sql.Timestamp object.
+ * @param parameterIndex whose value is to be fetched from the result.
+ * @return The parameter at the given index is returned as a Timestamp object.
+ * @throws SQLException if param datatype is not TIMESTAMP
+ */
+ public Timestamp getTimestamp(int parameterIndex) throws SQLException {
+ return getTimestamp(parameterIndex, null);
+ }
+
+ /**
+ * <p>Gets the value of a OUTPUT parameter as a java.sql.Timestamp object.
Calendar
+ * object contains the timezone information.
+ * @param parameterIndex whose value is to be fetched from the result.
+ * @param Calendar object used to construct the Date object.
+ * @return The parameter at the given index is returned as a Timestamp object.
+ * @throws SQLException if param datatype is not TIMESTAMP
+ */
+ public Timestamp getTimestamp(int parameterIndex, java.util.Calendar cal) throws
SQLException {
+ Timestamp value = DataTypeTransformer.getTimestamp(getObject(parameterIndex));
+
+ if (value == null) {
+ return null;
+ }
+
+ if (cal != null) {
+ value = TimestampWithTimezone.createTimestamp(value,
getDefaultCalendar().getTimeZone(), cal);
+ }
+
+ return value;
+ }
+
+ /**
+ * <p>Register the OUT parameter in the ordinal position parameterIndex to
jdbcsql
+ * type. Scale is used by setXXX methods to determine number of decimals.
+ * @param parameterIndex. Index of the OUT parameter in the stored procedure.
+ * @param jdbcSqlType. SQL type codes from java.sql.Types
+ * @param SQLException, should never occur
+ */
+ public void registerOutParameter(int parameterIndex, int jdbcSqlType) throws
SQLException {
+ // ignore - we don't care
+ }
+
+ /**
+ * <p>Register the OUT parameter in the ordinal position parameterIndex to
jdbcsql
+ * type. Scale is used by setXXX methods to determine number of decimals.
+ * @param parameterIndex. Index of the OUT parameter in the stored procedure.
+ * @param jdbcSqlType. SQL type codes from java.sql.Types
+ * @param scale. The number of decimal digits on the OUT param.
+ * @param SQLException, should never occur
+ */
+ public void registerOutParameter(int parameterIndex, int jdbcSqlType, int scale)
throws SQLException {
+ // ignore - we don't care
+ }
+
+ /**
+ * <p>Register the OUT parameter in the ordinal position parameterIndex to
jdbcsql
+ * type. The param typename(SQL name for user-named type) is ignored as SQL3
+ * datatypes are not supported.
+ * @param parameterIndex. Index of the OUT parameter in the stored procedure.
+ * @param jdbcSqlType. SQL type codes from java.sql.Types
+ * @param typeName. SQL name of user-named type being used
+ * @param SQLException, should never occur
+ */
+ public void registerOutParameter (int parameterIndex, int jdbcSqlType, String
typeName) throws SQLException {
+ // ignore - we don't care
+ }
+
+ /**
+ * <p>Indicates whether the last OUT parameter read was a return null.
+ * @return true if the last param read was null else false.
+ * @throws SQLException, if the statement is already closed.
+ */
+ public boolean wasNull() throws SQLException {
+ checkStatement();
+
+ return parameterValue == null;
+ }
+
+ public SQLXML getSQLXML(int parameterIndex) throws SQLException {
+ return DataTypeTransformer.getSQLXML(getObject(parameterIndex));
+ }
+
+ public Array getArray(int parameterIndex) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public Array getArray(String parameterName) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public BigDecimal getBigDecimal(String parameterName) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public Blob getBlob(String parameterName) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public boolean getBoolean(String parameterName) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public byte getByte(String parameterName) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public byte[] getBytes(int parameterIndex) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public byte[] getBytes(String parameterName) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public Reader getCharacterStream(int parameterIndex) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public Reader getCharacterStream(String parameterName) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public Clob getClob(String parameterName) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public Date getDate(String parameterName) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public Date getDate(String parameterName, Calendar cal) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public double getDouble(String parameterName) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public float getFloat(String parameterName) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public int getInt(String parameterName) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public long getLong(String parameterName) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public Reader getNCharacterStream(int parameterIndex) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public Reader getNCharacterStream(String parameterName) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ //## JDBC4.0-begin ##
+ public NClob getNClob(int parameterIndex) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+ //## JDBC4.0-end ##
+
+ //## JDBC4.0-begin ##
+ public NClob getNClob(String parameterName) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+ //## JDBC4.0-end ##
+
+ public String getNString(int parameterIndex) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public String getNString(String parameterName) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public Object getObject(String parameterName) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public Object getObject(int parameterIndex, Map<String, Class<?>> map)
throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public Object getObject(String parameterName, Map<String, Class<?>> map)
throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public Ref getRef(int parameterIndex) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public Ref getRef(String parameterName) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ //## JDBC4.0-begin ##
+ public RowId getRowId(int parameterIndex) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+ //## JDBC4.0-end ##
+
+ //## JDBC4.0-begin ##
+ public RowId getRowId(String parameterName) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+ //## JDBC4.0-end ##
+
+ public SQLXML getSQLXML(String parameterName) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public short getShort(String parameterName) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public String getString(String parameterName) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public Time getTime(String parameterName) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public Time getTime(String parameterName, Calendar cal) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public Timestamp getTimestamp(String parameterName) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public Timestamp getTimestamp(String parameterName, Calendar cal) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public URL getURL(int parameterIndex) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public URL getURL(String parameterName) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void registerOutParameter(String parameterName, int sqlType) throws SQLException
{
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void registerOutParameter(String parameterName, int sqlType,int scale) throws
SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void registerOutParameter(String parameterName, int sqlType, String typeName)
throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setAsciiStream(String parameterName, InputStream x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setAsciiStream(String parameterName, InputStream x, int length) throws
SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setAsciiStream(String parameterName, InputStream x, long length) throws
SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setBigDecimal(String parameterName, BigDecimal x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setBinaryStream(String parameterName, InputStream x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setBinaryStream(String parameterName, InputStream x, int length)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setBinaryStream(String parameterName, InputStream x, long length)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setBlob(String parameterName, Blob x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setBlob(String parameterName, InputStream inputStream)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setBlob(String parameterName, InputStream inputStream,
+ long length) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setBoolean(String parameterName, boolean x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setByte(String parameterName, byte x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setBytes(String parameterName, byte[] x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setCharacterStream(String parameterName, Reader reader)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException(); }
+
+ public void setCharacterStream(String parameterName, Reader reader,
+ int length) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setCharacterStream(String parameterName, Reader reader,
+ long length) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setClob(String parameterName, Clob x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setClob(String parameterName, Reader reader)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setClob(String parameterName, Reader reader, long length)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setDate(String parameterName, Date x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setDate(String parameterName, Date x, Calendar cal)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setDouble(String parameterName, double x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setFloat(String parameterName, float x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setInt(String parameterName, int x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setLong(String parameterName, long x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setNCharacterStream(String parameterName, Reader value)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setNCharacterStream(String parameterName, Reader value,
+ long length) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ //## JDBC4.0-begin ##
+ public void setNClob(String parameterName, NClob value) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+ //## JDBC4.0-end ##
+
+ public void setNClob(String parameterName, Reader reader)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setNClob(String parameterName, Reader reader, long length)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setNString(String parameterName, String value)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setNull(String parameterName, int sqlType) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setNull(String parameterName, int sqlType, String typeName)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setObject(String parameterName, Object x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setObject(String parameterName, Object x, int targetSqlType)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setObject(String parameterName, Object x, int targetSqlType,
+ int scale) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ //## JDBC4.0-begin ##
+ public void setRowId(String parameterName, RowId x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+ //## JDBC4.0-end ##
+
+ public void setSQLXML(String parameterName, SQLXML xmlObject)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+
+ public void setShort(String parameterName, short x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setString(String parameterName, String x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setTime(String parameterName, Time x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setTime(String parameterName, Time x, Calendar cal)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setTimestamp(String parameterName, Timestamp x)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setTimestamp(String parameterName, Timestamp x, Calendar cal)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setURL(String parameterName, URL val) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+}
\ No newline at end of file
Copied: trunk/client/src/main/java/org/teiid/jdbc/ConnectionImpl.java (from rev 1983,
trunk/client-jdbc/src/main/java/org/teiid/jdbc/ConnectionImpl.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/ConnectionImpl.java
(rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/ConnectionImpl.java 2010-03-22 21:01:44 UTC
(rev 1986)
@@ -0,0 +1,1000 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.CallableStatement;
+import java.sql.Clob;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+//## JDBC4.0-begin ##
+import java.sql.SQLClientInfoException;
+import java.sql.NClob;
+import java.sql.SQLXML;
+//## JDBC4.0-end ##
+
+/*## JDBC3.0-JDK1.5-begin ##
+import com.metamatrix.core.jdbc.SQLXML;
+## JDBC3.0-JDK1.5-end ##*/
+import java.sql.Savepoint;
+import java.sql.Statement;
+import java.sql.Struct;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.transaction.xa.Xid;
+
+import org.teiid.client.DQP;
+import org.teiid.client.util.ResultsFuture;
+import org.teiid.client.xa.XATransactionException;
+import org.teiid.client.xa.XidImpl;
+import org.teiid.net.CommunicationException;
+import org.teiid.net.TeiidURL;
+import org.teiid.net.ServerConnection;
+import org.teiid.net.socket.SocketServerConnection;
+
+
+
+import com.metamatrix.common.util.SqlUtil;
+
+public class ConnectionImpl extends WrapperImpl implements Connection {
+ private static Logger logger = Logger.getLogger("org.teiid.jdbc");
//$NON-NLS-1$
+
+ // constant value giving product name
+ private final static String SERVER_NAME = "Teiid Server"; //$NON-NLS-1$
+ private final static String EMBEDDED_NAME = "Teiid Embedded";
//$NON-NLS-1$
+
+ // Unique request ID generator
+ private long requestIDGenerator;
+
+ // url used to create the connection
+ private String url;
+
+ // properties object containing the connection properties.
+ protected Properties propInfo;
+
+ // status of connection object
+ private boolean closed = false;
+ // determines if a statement executed should be immediately committed.
+ private boolean autoCommitFlag = true;
+
+ // collection of all open statements on this connection
+ private Collection<StatementImpl> statements = new
ArrayList<StatementImpl>();
+ // cached DatabaseMetadata
+ private DatabaseMetaData dbmm;
+
+ //Xid for participating in TXN
+ private XidImpl transactionXid;
+
+ // Flag to represent if the connection state needs to be readOnly, default value
false.
+ private boolean readOnly = false;
+
+ private boolean disableLocalTransactions = false;
+ private DQP dqp;
+ protected ServerConnection serverConn;
+ private int transactionIsolation = Connection.TRANSACTION_READ_COMMITTED;
+
+ public ConnectionImpl(ServerConnection serverConn, Properties info, String url) {
+ this.serverConn = serverConn;
+ this.url = url;
+ this.dqp = serverConn.getService(DQP.class);
+
+ // set default properties if not overridden
+ String overrideProp = info.getProperty(ExecutionProperties.PROP_TXN_AUTO_WRAP);
+ if ( overrideProp == null || overrideProp.trim().length() == 0 ) {
+ info.put(ExecutionProperties.PROP_TXN_AUTO_WRAP,
ExecutionProperties.TXN_WRAP_DETECT);
+ }
+
+ // Get default fetch size
+ String defaultFetchSize = info.getProperty(ExecutionProperties.PROP_FETCH_SIZE);
+ if (defaultFetchSize != null) {
+ info.put(ExecutionProperties.PROP_FETCH_SIZE, defaultFetchSize);
+ } else {
+ info.put(ExecutionProperties.PROP_FETCH_SIZE,
""+BaseDataSource.DEFAULT_FETCH_SIZE); //$NON-NLS-1$
+ }
+
+ // Get partial results mode
+ String partialResultsMode =
info.getProperty(ExecutionProperties.PROP_PARTIAL_RESULTS_MODE);
+ if (partialResultsMode != null) {
+ info.put(ExecutionProperties.PROP_PARTIAL_RESULTS_MODE, partialResultsMode);
+ } else {
+ info.put(ExecutionProperties.PROP_PARTIAL_RESULTS_MODE,
BaseDataSource.DEFAULT_PARTIAL_RESULTS_MODE);
+ }
+
+ // Get result set cache mode
+ String resultSetCacheMode =
info.getProperty(ExecutionProperties.RESULT_SET_CACHE_MODE);
+ if (resultSetCacheMode != null) {
+ info.put(ExecutionProperties.RESULT_SET_CACHE_MODE, resultSetCacheMode);
+ } else {
+ info.put(ExecutionProperties.RESULT_SET_CACHE_MODE,
BaseDataSource.DEFAULT_RESULT_SET_CACHE_MODE);
+ }
+
+ String ansiQuotes =
info.getProperty(ExecutionProperties.ANSI_QUOTED_IDENTIFIERS);
+ if (ansiQuotes != null) {
+ info.put(ExecutionProperties.ANSI_QUOTED_IDENTIFIERS, ansiQuotes);
+ } else {
+ info.put(ExecutionProperties.ANSI_QUOTED_IDENTIFIERS,
Boolean.TRUE.toString());
+ }
+
+ logger.fine(JDBCPlugin.Util.getString("MMConnection.Session_success"));
//$NON-NLS-1$
+ logConnectionProperties(url, info);
+
+ // properties object used in obtaining connection
+ this.propInfo = info;
+
+ this.disableLocalTransactions =
Boolean.valueOf(this.propInfo.getProperty(ExecutionProperties.DISABLE_LOCAL_TRANSACTIONS)).booleanValue();
+ }
+
+ protected Properties getConnectionProperties() {
+ return this.propInfo;
+ }
+
+ DQP getDQP() {
+ return this.dqp;
+ }
+
+ /**
+ * Remove password & trusted token and log all other properties
+ * @param connUrl - URL used to connect to server
+ * @param info - properties object supplied
+ */
+ private void logConnectionProperties(String connUrl, Properties info) {
+ StringBuffer modifiedUrl = new StringBuffer();
+
+ // If we have valid URL
+ if (connUrl != null) {
+ // We need wipe out the password here, before we write to the log
+ int startIndex = connUrl.indexOf("password="); //$NON-NLS-1$
+ if (startIndex != -1) {
+ modifiedUrl.append(connUrl.substring(0, startIndex));
+ modifiedUrl.append("password=***"); //$NON-NLS-1$
+ int endIndex = connUrl.indexOf(";", startIndex+9); //$NON-NLS-1$
+ if (endIndex != -1) {
+ modifiedUrl.append(";").append(connUrl.substring(endIndex));
//$NON-NLS-1$
+ }
+ }
+ logger.fine("Connection Url="+modifiedUrl); //$NON-NLS-1$
+ }
+
+ // Now clone the properties object and remove password and trusted token
+ if (info != null) {
+ Enumeration enumeration = info.keys();
+ while (enumeration.hasMoreElements()) {
+ String key = (String)enumeration.nextElement();
+ Object anObj = info.get(key);
+ // Log each property except for password and token.
+ if (!TeiidURL.CONNECTION.PASSWORD.equalsIgnoreCase(key)) {
+ logger.fine(key+"="+anObj); //$NON-NLS-1$
+ }
+ }
+ }
+ }
+
+ String getUrl() {
+ return this.url;
+ }
+
+ /**
+ * Connection identifier of this connection
+ * @return identifier
+ * @throws SQLException
+ */
+ public String getConnectionId() {
+ return String.valueOf(this.serverConn.getLogonResult().getSessionID());
+ }
+
+ long currentRequestId() {
+ return requestIDGenerator;
+ }
+
+ /**
+ * Generate the next unique requestID for matching up requests with responses.
+ * These IDs should be unique only in the context of a ServerConnection instance.
+ * @return Request ID
+ */
+ long nextRequestID() {
+ return requestIDGenerator++;
+ }
+
+ public void clearWarnings() throws SQLException {
+ // do nothing
+ }
+
+ public void close() throws SQLException {
+ Throwable firstException = null;
+
+ if(closed) {
+ return;
+ }
+
+ try {
+ // close any statements that were created on this connection
+ try {
+ closeStatements();
+ } catch (SQLException se) {
+ firstException = se;
+ } finally {
+ this.serverConn.close();
+ if ( firstException != null )
+ throw (SQLException)firstException;
+ }
+ } catch (SQLException se) {
+ throw TeiidSQLException.create(se,
JDBCPlugin.Util.getString("MMConnection.Err_connection_close",
se.getMessage())); //$NON-NLS-1$
+ } finally {
+
logger.fine(JDBCPlugin.Util.getString("MMConnection.Connection_close_success"));
//$NON-NLS-1$
+ // set the status of the connection to closed
+ closed = true;
+ }
+ }
+
+ /**
+ * <p>
+ * Close all the statements open on this connection
+ * </p>
+ *
+ * @throws SQLException
+ * server statement object could not be closed.
+ */
+ void closeStatements() throws SQLException {
+ // Closing the statement will cause the
+ // MMConnection.closeStatement() method to be called,
+ // which will modify this.statements. So, we do this iteration
+ // in a separate safe copy of the list
+ List statementsSafe = new ArrayList(this.statements);
+ Iterator statementIter = statementsSafe.iterator();
+ SQLException ex = null;
+ while (statementIter.hasNext ()) {
+ Statement statement = (Statement) statementIter.next();
+ try {
+ statement.close();
+ } catch (SQLException e) {
+ ex = e;
+ }
+ }
+ if (ex != null) {
+ throw TeiidSQLException.create(ex,
JDBCPlugin.Util.getString("MMConnection.Err_closing_stmts")); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Called by MMStatement to notify the connection that the
+ * statement has been closed.
+ * @param statement
+ */
+ void closeStatement(Statement statement) {
+ this.statements.remove(statement);
+ }
+
+ /**
+ * <p>This method makes any changes involved in a transaction permanent and
releases
+ * any locks held by the connection object. This is only used when auto-commit
+ * is set to false.</p>
+ * @throws SQLException if the transaction had been rolled back or marked to roll
back.
+ */
+ public void commit() throws SQLException {
+ checkConnection();
+ if (!autoCommitFlag) {
+ try {
+ directCommit();
+ } finally {
+ beginLocalTxn();
+ }
+ }
+ }
+
+ private void directCommit() throws SQLException {
+ try {
+ ResultsFuture<?> future = this.dqp.commit();
+ future.get();
+ } catch (Exception e) {
+ throw TeiidSQLException.create(e);
+ }
+ logger.fine(JDBCPlugin.Util.getString("MMConnection.Commit_success"));
//$NON-NLS-1$
+ }
+
+ private void beginLocalTxn() throws SQLException {
+ if (this.transactionXid == null) {
+ if (disableLocalTransactions) {
+ this.autoCommitFlag = true;
+ return;
+ }
+ boolean txnStarted = false;
+ try {
+ try {
+ this.dqp.begin();
+ } catch (XATransactionException e) {
+ throw TeiidSQLException.create(e);
+ }
+ txnStarted = true;
+ } finally {
+ if (!txnStarted) {
+ autoCommitFlag = true;
+ }
+ }
+ }
+ }
+
+ /**
+ * <p>This creates a MMStatement object for sending SQL statements to the
MetaMatrix
+ * server. This should be used for statements without parameters. For statements
+ * that are executed many times, use the PreparedStatement object.</p>
+ * @return a Statement object.
+ * @throws a SQLException if a MetaMatrix server access error occurs.
+ */
+ public Statement createStatement() throws SQLException {
+ return createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
+ }
+
+ /**
+ * <p>Creates a Statement object that will produce ResultSet objects of the
type
+ * resultSetType and concurrency level resultSetConcurrency.</p>
+ * @param intvalue indicating the ResultSet's type
+ * @param intValue indicating the ResultSet's concurrency
+ * @return Statement object.
+ */
+ public Statement createStatement(int resultSetType, int resultSetConcurrency) throws
SQLException {
+ //Check to see the connection is open
+ checkConnection();
+
+ validateResultSetType(resultSetType);
+ validateResultSetConcurrency(resultSetConcurrency);
+
+ // add the statement object to the map
+ StatementImpl newStatement = StatementImpl.newInstance(this, resultSetType,
resultSetConcurrency);
+ statements.add(newStatement);
+
+ return newStatement;
+ }
+
+ /**
+ * @param resultSetType
+ * @throws TeiidSQLException
+ * @since 4.3
+ */
+ private void validateResultSetType(int resultSetType) throws TeiidSQLException {
+ if (resultSetType == ResultSet.TYPE_SCROLL_SENSITIVE ) {
+ String msg =
JDBCPlugin.Util.getString("MMConnection.Scrollable_type_not_supported",
"ResultSet.TYPE_SCROLL_SENSITIVE"); //$NON-NLS-1$ //$NON-NLS-2$
+ throw new TeiidSQLException(msg);
+ }
+ }
+
+ /**
+ * @param resultSetConcurrency
+ * @throws TeiidSQLException
+ * @since 4.3
+ */
+ private void validateResultSetConcurrency(int resultSetConcurrency) throws
TeiidSQLException {
+ if (resultSetConcurrency == ResultSet.CONCUR_UPDATABLE) {
+ String msg =
JDBCPlugin.Util.getString("MMConnection.Concurrency_type_not_supported",
"ResultSet.CONCUR_UPDATABLE"); //$NON-NLS-1$ //$NON-NLS-2$
+ throw new TeiidSQLException(msg);
+ }
+ }
+
+ /**
+ * <p>This method returns the current status of the connection in regards to
it's
+ * auto-commit state. By default, the auto-commit is set to true. Meaning that
+ * any transaction that occurs is automatically commited to the MetaMatrix server.
+ * #See corresponding setAutoCommit() method.</p>
+ * @return true if the statements on this connection get committed on execution.
+ * @throws SQLException should never happen
+ */
+ public boolean getAutoCommit() throws SQLException {
+ //Check to see the connection is open
+ checkConnection();
+ return autoCommitFlag;
+ }
+
+ public String getCatalog() throws SQLException {
+ //Check to see the connection is open
+ checkConnection();
+ //catalogs are not supported
+ return this.serverConn.getLogonResult().getVdbName();
+ }
+
+ /**
+ * <p>This method gets the ServerConnection object wrapped by this
object.</p>
+ * @return ServerConnection object
+ */
+ ServerConnection getServerConnection() throws SQLException {
+ //Check to see the connection is open
+ checkConnection();
+ return serverConn;
+ }
+
+ String getVDBName() throws SQLException {
+ //Check to see the connection is open
+ checkConnection();
+ //get the virtual database name to which we are connected.
+
+ return this.serverConn.getLogonResult().getVdbName();
+ }
+
+ public int getVDBVersion() throws SQLException {
+ checkConnection();
+ return this.serverConn.getLogonResult().getVdbVersion();
+ }
+
+ /**
+ * Get's the name of the user who got this connection.
+ * @return Sring object giving the user name
+ * @throws SQLException if the connection is closed
+ */
+ String getUserName() throws SQLException {
+ checkConnection();
+
+ return this.serverConn.getLogonResult().getUserName();
+ }
+
+ public DatabaseMetaData getMetaData() throws SQLException {
+ //Check to see the connection is open
+ checkConnection();
+
+ if (dbmm == null) {
+ dbmm = new DatabaseMetaDataImpl(this);
+ }
+ return dbmm;
+ }
+
+ /**
+ * Get the database name that this connection is representing
+ * @return String name of the database
+ */
+ public String getDatabaseName() {
+ if (this.serverConn instanceof SocketServerConnection) {
+ return SERVER_NAME;
+ }
+ return EMBEDDED_NAME;
+ }
+
+ /**
+ * Retrieves the current holdability of ResultSet objects created using this
Connection object.
+ * @param holdability int indicating the holdability
+ * @return int holdability
+ * @throws SQLException
+ */
+ public int getHoldability() throws SQLException {
+ return ResultSet.HOLD_CURSORS_OVER_COMMIT;
+ }
+
+ public int getTransactionIsolation() throws SQLException {
+ return this.transactionIsolation;
+ }
+
+ /**
+ * Retreives the type map associated with this Connection object. The type map
+ * contains entries for undefined types. This method always returns an empty
+ * map since it is not possible to add entries to this type map
+ * @return map containing undefined types(empty)
+ * @throws SQLException, should never occur
+ */
+ public Map getTypeMap() throws SQLException {
+ //Check to see the connection is open
+ checkConnection();
+ return new HashMap();
+ }
+
+ /**
+ * <p>This method will return the first warning reported by calls on this
connection,
+ * or null if none exist.</p>
+ * @return A SQLWarning object if there are any warnings.
+ * @throws SQLException, should never occur
+ */
+ public SQLWarning getWarnings() throws SQLException {
+ //Check to see the connection is open
+ checkConnection();
+ return null; // we don't have any warnings
+ }
+
+ /**
+ * <p>This method will return whether this connection is closed or
not.</p>
+ * @return booleanvalue indicating if the connection is closed
+ * @throws SQLException, should never occur
+ */
+ public boolean isClosed() throws SQLException {
+ return closed;
+ }
+
+ /**
+ * <p>This method will return whether this connection is read only or not.
+ * It will throw a SQLException if a MetaMatrix server access error occurs.
+ * @return boolean value indication if connection is readonly
+ * @throws SQLException, should never occur
+ */
+ public boolean isReadOnly() throws SQLException {
+ return readOnly;
+ }
+
+ /**
+ * <p>This method will convert the given SQL String into a MetaMatrix SQL
Request.
+ * This will convert any date escape sequences into the appropriate MetaMatrix
+ * type, and any kind of data transformations that the MetaMatrix server would
+ * expect. This method returns the native form of the statement that the driver
+ * would have sent.</p>
+ * @param sql string to be coverted into SQL understood by metamatrix
+ * @return uncoverted sql string(escape parsing takesplace in metamatrix)
+ * @throws SQLException, should never occur
+ */
+ public String nativeSQL(String sql) throws SQLException {
+ // return the string argument without any modifications.
+ // escape syntaxes are directly supported in the server
+ return sql;
+ }
+
+ /**
+ * <p>Creates a CallableStatement object that contains sql and that will
produce
+ * ResultSet objects that are non-scrollable and non-updatable. A SQL stored
+ * procedure call statement is handled by creating a CallableStatement for
it.</p>
+ * @param sql String(escape syntax) for invoking a stored procedure.
+ * @return CallableStatement object that can be used to execute the storedProcedure
+ * @throws SQLException if there is an error creating the callable statement object
+ */
+ public CallableStatement prepareCall(String sql) throws SQLException {
+ //there is a problem setting the result set type to be non-scrollable
+ //See defect 17768
+ return prepareCall(sql, ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
+ }
+
+ /**
+ * <p>Creates a CallableStatement object that contains a sql and that will
produce
+ * ResultSet objects of the type resultSetType and with a concurrency level of
+ * resultSetConcurrency. A SQL stored procedure call statement is handled by
+ * creating a CallableStatement for it.</p>
+ * @param sql String(escape syntax) for invoking a stored procedure.
+ * @param intvalue indicating the ResultSet's type
+ * @param intValue indicating the ResultSet's concurrency
+ * @return CallableStatement object that can be used to execute the storedProcedure
+ */
+ public CallableStatement prepareCall(String sql, int resultSetType, int
resultSetConcurrency) throws SQLException {
+ //Check to see the connection is open
+ checkConnection();
+
+ validateResultSetType(resultSetType);
+ validateResultSetConcurrency(resultSetConcurrency);
+ validateSQL(sql);
+
+ // add the statement object to the map
+ CallableStatementImpl newStatement = CallableStatementImpl.newInstance(this, sql,
resultSetType, resultSetConcurrency);
+ statements.add(newStatement);
+ return newStatement;
+ }
+
+ /**
+ * @param sql
+ * @throws TeiidSQLException
+ * @since 4.3
+ */
+ private void validateSQL(String sql) throws TeiidSQLException {
+ if (sql == null) {
+ String msg =
JDBCPlugin.Util.getString("MMConnection.SQL_cannot_be_null"); //$NON-NLS-1$
+ throw new TeiidSQLException(msg);
+ }
+ }
+
+ /**
+ * <p>This method creates a MMPreparedStatement which is used for sending
parameterized
+ * SQL statements to the MetaMatrix server. A statement with or without IN
parameters
+ * can be pre-compiled and stored in a MMPreparedStatement object. Since the
MetaMatrix
+ * server does not pre-compile statements, a sql statement will be constructed using
the
+ * parameters supplied which would be used for execution of this preparedStatement
object.</p>
+ * @param sql string representing a prepared statement
+ * @return a PreparedStatement object
+ * @throws SQLException if there is an error creating a prepared statement object
+ */
+ public PreparedStatement prepareStatement(String sql) throws SQLException {
+ return prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY);
+ }
+
+ /**
+ * <p>Creates a PreparedStatement object that contains a sql and that will
produce
+ * ResultSet objects of the type resultSetType and with a concurrency level of
+ * resultSetConcurrency.</p>
+ * @param sql string representing a prepared statement
+ * @param intvalue indicating the ResultSet's type
+ * @param intValue indicating the ResultSet's concurrency
+ * @return a PreparedStatement object
+ */
+ public PreparedStatement prepareStatement(String sql, int resultSetType, int
resultSetConcurrency) throws SQLException {
+ //Check to see the connection is open
+ checkConnection();
+
+ validateResultSetType(resultSetType);
+ validateResultSetConcurrency(resultSetConcurrency);
+ validateSQL(sql);
+
+ // add the statement object to the map
+ PreparedStatementImpl newStatement = PreparedStatementImpl.newInstance(this, sql,
resultSetType, resultSetConcurrency);
+ statements.add(newStatement);
+ return newStatement;
+ }
+
+ /**
+ * <p>This method creates a MMPreparedStatement which is used for sending
parameterized
+ * SQL statements to the MetaMatrix server and it has the capability to retrieve
auto-generated keys.</p>
+ * @param sql string representing a prepared statement
+ * @param intValue indicating the result set Type
+ * @param intValue indicating the result set concurrency
+ * @param intValue indicating the result set holdability
+ * @return a PreparedStatement object
+ * @throws SQLException if there is an error creating a prepared statement object
+ */
+ public PreparedStatement prepareStatement(String sql, int resultSetType, int
resultSetConcurrency,
+ int resultSetHoldability ) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ /**
+ * <p>This method will drop all changes made since the beginning of the
transaction
+ * and release any MetaMatrix server locks currently held by this connection. This
+ * method rolls back transactions on all the statements currently open on this
connection.
+ * This is used when then auto-commit has been disabled.</p>
+ * @see setAutoCommit(boolean) method for more information.
+ * @throws SQLException if there is an error rolling back.
+ */
+ public void rollback() throws SQLException {
+ rollback(true);
+ }
+
+ void rollback(boolean startTxn) throws SQLException {
+
+ //Check to see the connection is open
+ checkConnection();
+ if (!autoCommitFlag) {
+ try {
+ try {
+ ResultsFuture<?> future = this.dqp.rollback();
+ future.get();
+ } catch (Exception e) {
+ throw TeiidSQLException.create(e);
+ }
+
logger.fine(JDBCPlugin.Util.getString("MMConnection.Rollback_success"));
//$NON-NLS-1$
+ } finally {
+ if (startTxn) {
+ beginLocalTxn();
+ }
+ else {
+ this.autoCommitFlag = true;
+ }
+ }
+ }
+ }
+
+ /**
+ * <p>This method will set the connection's auto commit mode accordingly.
By
+ * default this is set to true (auto-commit is turned on). An auto-commit
+ * value of true means any statements will automatically be made permanent if
+ * they are successful after the last row of the ReulstSet has been retrieved
+ * or the next execute occurs, whichever comes first. If set to false, changes
+ * can be either be committed (using the commit() method) or rolled back ("undo
+ * the changes" by using the rollback() method).</p>
+ * @param boolean value indicating if autoCommit is turned on
+ * @throws SQLException is metamatrix access error occurs.
+ */
+ public void setAutoCommit(boolean autoCommit) throws SQLException {
+ //Check to see the connection is open
+ checkConnection();
+
+ if (autoCommit == this.autoCommitFlag) {
+ return;
+ }
+
+ this.autoCommitFlag = autoCommit;
+
+ if (autoCommit) {
+ directCommit();
+ } else {
+ beginLocalTxn();
+ }
+ }
+
+ /**
+ * <p>Metamatrix does not allow setting a catalog through a connection. This
+ * method silently ignores the request as per the specification.</p>
+ * @param The string values which sets the catalog name on the connection.
+ * @throws SQLException This should never occur.
+ */
+ public void setCatalog(String catalog) throws SQLException {
+ // do nothing, silently ignore the request
+ }
+
+ /**
+ * @param A boolean value specifying whether the connection is readonly.
+ * @throws throws SQLException.
+ */
+ public void setReadOnly(boolean readOnly) throws SQLException {
+ if (this.readOnly == readOnly) {
+ return;
+ }
+ // During transaction do not allow to change this flag
+ if (!autoCommitFlag || this.transactionXid != null) {
+ throw new
TeiidSQLException(JDBCPlugin.Util.getString("MMStatement.Invalid_During_Transaction",
"setReadOnly(" + readOnly + ")"));//$NON-NLS-1$
//$NON-NLS-2$//$NON-NLS-3$
+ }
+ this.readOnly = readOnly;
+ }
+
+ /**
+ * <p> This utility method checks if the jdbc connection is closed and
+ * throws an exception if it is closed. </p>
+ * @throws SQLException if the connection object is closed.
+ */
+ void checkConnection() throws SQLException{
+ //Check to see the connection is closed and proceed if it is not
+ if (closed) {
+ throw new
TeiidSQLException(JDBCPlugin.Util.getString("MMConnection.Cant_use_closed_connection"));
//$NON-NLS-1$
+ }
+ }
+
+ protected void commitTransaction(XidImpl arg0, boolean arg1) throws SQLException {
+ checkConnection();
+ transactionXid = null;
+ this.autoCommitFlag = true;
+ try {
+ ResultsFuture<?> future = this.dqp.commit(arg0, arg1);
+ future.get();
+ } catch (Exception e) {
+ throw TeiidSQLException.create(e);
+ }
+ }
+
+ protected void endTransaction(XidImpl arg0, int arg1) throws SQLException {
+ checkConnection();
+ this.autoCommitFlag = true;
+ try {
+ ResultsFuture<?> future = this.dqp.end(arg0, arg1);
+ future.get();
+ } catch (Exception e) {
+ throw TeiidSQLException.create(e);
+ }
+ }
+
+ protected void forgetTransaction(XidImpl arg0) throws SQLException {
+ checkConnection();
+ try {
+ ResultsFuture<?> future = this.dqp.forget(arg0);
+ future.get();
+ } catch (Exception e) {
+ throw TeiidSQLException.create(e);
+ }
+ }
+
+ protected int prepareTransaction(XidImpl arg0) throws SQLException {
+ checkConnection();
+ transactionXid = null;
+ try {
+ ResultsFuture<Integer> future = this.dqp.prepare(arg0);
+ return future.get();
+ } catch (Exception e) {
+ throw TeiidSQLException.create(e);
+ }
+ }
+
+ protected Xid[] recoverTransaction(int arg0) throws SQLException {
+ checkConnection();
+ try {
+ ResultsFuture<Xid[]> future = this.dqp.recover(arg0);
+ return future.get();
+ } catch (Exception e) {
+ throw TeiidSQLException.create(e);
+ }
+ }
+
+ protected void rollbackTransaction(XidImpl arg0) throws SQLException {
+ checkConnection();
+ transactionXid = null;
+ this.autoCommitFlag = true;
+ try {
+ ResultsFuture<?> future = this.dqp.rollback(arg0);
+ future.get();
+ } catch (Exception e) {
+ throw TeiidSQLException.create(e);
+ }
+ }
+
+ protected void startTransaction(XidImpl arg0, int arg1, int timeout) throws
SQLException {
+ checkConnection();
+ try {
+ ResultsFuture<?> future = this.dqp.start(arg0, arg1, timeout);
+ future.get();
+ } catch (Exception e) {
+ throw TeiidSQLException.create(e);
+ }
+ transactionXid = arg0;
+ this.autoCommitFlag = false;
+ }
+
+ protected XidImpl getTransactionXid() {
+ return transactionXid;
+ }
+
+ public boolean isValid(int timeout) throws SQLException {
+ Statement statement = null;
+ try {
+ statement = createStatement();
+ statement.setQueryTimeout(timeout);
+ statement.execute("select 1"); //$NON-NLS-1$
+ return true;
+ } catch (SQLException e) {
+ return false;
+ } finally {
+ if (statement != null) {
+ try {
+ statement.close();
+ } catch (SQLException e) {
+ }
+ }
+ }
+ }
+
+ public void recycleConnection() {
+ try {
+ //close all open statements
+ this.closeStatements();
+ } catch (SQLException e) {
+ logger.log(Level.WARNING,
JDBCPlugin.Util.getString("MMXAConnection.rolling_back_error"), e);
//$NON-NLS-1$
+ }
+ try {
+ //rollback if still in a transaction
+ if (!this.getAutoCommit()) {
+
logger.warning(JDBCPlugin.Util.getString("MMXAConnection.rolling_back"));
//$NON-NLS-1$
+
+ if (this.getTransactionXid() == null) {
+ this.rollback(false);
+ } else {
+ this.rollbackTransaction(getTransactionXid());
+ }
+ }
+ } catch (SQLException e) {
+ logger.log(Level.WARNING,
JDBCPlugin.Util.getString("MMXAConnection.rolling_back_error"), e);
//$NON-NLS-1$
+ }
+
+ //perform load balancing
+ if (this.serverConn instanceof SocketServerConnection) {
+ ((SocketServerConnection)this.serverConn).selectNewServerInstance(this.getDQP());
+ }
+ }
+
+ public boolean isSameProcess(ConnectionImpl conn) throws CommunicationException {
+ return this.serverConn.isSameInstance(conn.serverConn);
+ }
+
+ //## JDBC4.0-begin ##
+ public void setClientInfo(Properties properties)
+ throws SQLClientInfoException {
+ }
+
+ public void setClientInfo(String name, String value)
+ throws SQLClientInfoException {
+ }
+ //## JDBC4.0-end ##
+
+ public Properties getClientInfo() throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public String getClientInfo(String name) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public Array createArrayOf(String typeName, Object[] elements)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public Blob createBlob() throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public Clob createClob() throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ //## JDBC4.0-begin ##
+ public NClob createNClob() throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+ //## JDBC4.0-end ##
+
+ public SQLXML createSQLXML() throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public Statement createStatement(int resultSetType,
+ int resultSetConcurrency, int resultSetHoldability)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+
+ }
+
+ public Struct createStruct(String typeName, Object[] attributes)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public CallableStatement prepareCall(String sql, int resultSetType,
+ int resultSetConcurrency, int resultSetHoldability)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+
+ }
+
+ public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+
+ }
+
+ public PreparedStatement prepareStatement(String sql, int[] columnIndexes)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+
+ }
+
+ public PreparedStatement prepareStatement(String sql, String[] columnNames)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+
+ }
+
+ public void releaseSavepoint(Savepoint savepoint) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+
+ }
+
+ public void rollback(Savepoint savepoint) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+
+ }
+
+ public void setHoldability(int holdability) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public Savepoint setSavepoint() throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public Savepoint setSavepoint(String name) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setTransactionIsolation(int level) throws SQLException {
+ this.transactionIsolation = level;
+ }
+
+ public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+}
Copied: trunk/client/src/main/java/org/teiid/jdbc/ConnectionListener.java (from rev 1983,
trunk/client-jdbc/src/main/java/org/teiid/jdbc/ConnectionListener.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/ConnectionListener.java
(rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/ConnectionListener.java 2010-03-22 21:01:44
UTC (rev 1986)
@@ -0,0 +1,41 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.Connection;
+
+/**
+ * A JDBC Connection lifecycle listener
+ */
+public interface ConnectionListener {
+
+ /**
+ * Called when a new connection is created.
+ */
+ void connectionAdded(String id, Connection connection);
+
+ /**
+ * Called when a connection is closed.
+ */
+ void connectionRemoved(String id, Connection connection);
+}
Copied: trunk/client/src/main/java/org/teiid/jdbc/DataTypeTransformer.java (from rev 1983,
trunk/client-jdbc/src/main/java/org/teiid/jdbc/DataTypeTransformer.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/DataTypeTransformer.java
(rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/DataTypeTransformer.java 2010-03-22 21:01:44
UTC (rev 1986)
@@ -0,0 +1,270 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.math.BigDecimal;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Date;
+import java.sql.SQLException;
+//## JDBC4.0-begin ##
+import java.sql.SQLXML;
+//## JDBC4.0-end ##
+/*## JDBC3.0-JDK1.5-begin ##
+import com.metamatrix.core.jdbc.SQLXML;
+## JDBC3.0-JDK1.5-end ##*/
+import java.sql.Time;
+import java.sql.Timestamp;
+
+import com.metamatrix.common.types.DataTypeManager;
+import com.metamatrix.common.types.TransformationException;
+import com.metamatrix.common.types.DataTypeManager.DefaultDataClasses;
+
+/**
+ * <p>This class is used to transform objects into desired data types. The static
+ * method on this class are used by Metadatresults, ResultsWrapper and
+ * MMCallableStatement classes.</p>
+ */
+final class DataTypeTransformer {
+
+ // Prevent instantiation
+ private DataTypeTransformer() {}
+
+ /**
+ * Gets an object value and transforms it into a java.math.BigDecimal object.
+ * @param value, the object to be transformed
+ * @return a BigDecimal object
+ * @throws SQLException if failed to transform to the desired datatype
+ */
+ static final BigDecimal getBigDecimal(Object value) throws SQLException {
+ return transform(value, BigDecimal.class, "BigDecimal"); //$NON-NLS-1$
+ }
+
+ private static final <T> T transform(Object value, Class<T> type, String
typeName) throws SQLException {
+ return transform(value, type, type, typeName);
+ }
+
+ private static final <T> T transform(Object value, Class<T> targetType,
Class<?> runtimeType, String typeName) throws SQLException {
+ if (value == null || targetType.isAssignableFrom(value.getClass())) {
+ return (T)value;
+ }
+ try {
+ return
(T)DataTypeManager.transformValue(DataTypeManager.convertToRuntimeType(value),
runtimeType);
+ } catch (TransformationException e) {
+ String valueStr = value.toString();
+ if (valueStr.length() > 20) {
+ valueStr = valueStr.substring(0, 20) + "..."; //$NON-NLS-1$
+ }
+ String msg =
JDBCPlugin.Util.getString("DataTypeTransformer.Err_converting", valueStr,
typeName); //$NON-NLS-1$
+ throw TeiidSQLException.create(e, msg);
+ }
+ }
+
+ /**
+ * Gets an object value and transforms it into a boolean
+ * @param value, the object to be transformed
+ * @return a Boolean object
+ * @throws SQLException if failed to transform to the desired datatype
+ */
+ static final boolean getBoolean(Object value) throws SQLException {
+ if (value == null) {
+ return false;
+ }
+ return transform(value, Boolean.class, "Boolean"); //$NON-NLS-1$
+ }
+
+ /**
+ * Gets an object value and transforms it into a byte
+ * @param value, the object to be transformed
+ * @return a Byte object
+ * @throws SQLException if failed to transform to the desired datatype
+ */
+ static final byte getByte(Object value) throws SQLException {
+ if (value == null) {
+ return 0;
+ }
+ return transform(value, Byte.class, "Byte"); //$NON-NLS-1$
+ }
+
+ static final byte[] getBytes(Object value) throws SQLException {
+ if (value == null) {
+ return null;
+ } else if (value instanceof byte[]) {
+ return (byte[])value;
+ } else if (value instanceof Blob) {
+ Blob blob = (Blob)value;
+ long length = blob.length();
+ if (length > Integer.MAX_VALUE) {
+ throw new
TeiidSQLException(JDBCPlugin.Util.getString("DataTypeTransformer.blob_too_big"));
//$NON-NLS-1$
+ }
+ return blob.getBytes(1, (int)length);
+ } else if (value instanceof String) {
+ return ((String)value).getBytes();
+ }
+ throw new
TeiidSQLException(JDBCPlugin.Util.getString("DataTypeTransformer.cannot_get_bytes"));
//$NON-NLS-1$
+ }
+
+ static final Character getCharacter(Object value) throws SQLException {
+ return transform(value, Character.class, "Character"); //$NON-NLS-1$
+ }
+
+ /**
+ * Gets an object value and transforms it into a java.sql.Date object.
+ * @param value, the object to be transformed
+ * @param Calendar object to be used to construct the Date object.
+ * @return a Date object
+ * @throws SQLException if failed to transform to the desired datatype
+ */
+ static final Date getDate(Object value) throws SQLException {
+ return transform(value, Date.class, "Date"); //$NON-NLS-1$
+ }
+
+ /**
+ * Gets an object value and transforms it into a double
+ * @param value, the object to be transformed
+ * @return a Double object
+ * @throws SQLException if failed to transform to the desired datatype
+ */
+ static final double getDouble(Object value) throws SQLException {
+ if (value == null) {
+ return 0;
+ }
+ return transform(value, Double.class, "Double"); //$NON-NLS-1$
+ }
+
+ /**
+ * Gets an object value and transforms it into a float
+ * @param value, the object to be transformed
+ * @return a Float object
+ * @throws SQLException if failed to transform to the desired datatype
+ */
+ static final float getFloat(Object value) throws SQLException {
+ if (value == null) {
+ return 0;
+ }
+ return transform(value, Float.class, "Float"); //$NON-NLS-1$
+ }
+
+ /**
+ * Gets an object value and transforms it into a integer
+ * @param value, the object to be transformed
+ * @return a Integer object
+ * @throws SQLException if failed to transform to the desired datatype
+ */
+ static final int getInteger(Object value) throws SQLException {
+ if (value == null) {
+ return 0;
+ }
+ return transform(value, Integer.class, "Integer"); //$NON-NLS-1$
+ }
+
+ /**
+ * Gets an object value and transforms it into a long
+ * @param value, the object to be transformed
+ * @return a Long object
+ * @throws SQLException if failed to transform to the desired datatype
+ */
+ static final long getLong(Object value) throws SQLException {
+ if (value == null) {
+ return 0;
+ }
+ return transform(value, Long.class, "Long"); //$NON-NLS-1$
+ }
+
+ /**
+ * Gets an object value and transforms it into a short
+ * @param value, the object to be transformed
+ * @return a Short object
+ * @throws SQLException if failed to transform to the desired datatype
+ */
+ static final short getShort(Object value) throws SQLException {
+ if (value == null) {
+ return 0;
+ }
+ return transform(value, Short.class, "Short"); //$NON-NLS-1$
+ }
+
+ /**
+ * Gets an object value and transforms it into a java.sql.Time object.
+ * @param value, the object to be transformed
+ * @param Calendar object to be used to construct the Time object.
+ * @return a Time object
+ * @throws SQLException if failed to transform to the desired datatype
+ */
+ static final Time getTime(Object value) throws SQLException {
+ return transform(value, Time.class, "Time"); //$NON-NLS-1$
+ }
+
+ /**
+ * Gets an object value and transforms it into a java.sql.Timestamp object.
+ * @param value, the object to be transformed
+ * @param Calendar object to be used to construct the Timestamp object.
+ * @return a Timestamp object
+ * @throws SQLException if failed to transform to the desired datatype
+ */
+ static final Timestamp getTimestamp(Object value) throws SQLException {
+ return transform(value, Timestamp.class, "Timestamp"); //$NON-NLS-1$
+ }
+
+ static final String getString(Object value) throws SQLException {
+ if (value instanceof SQLXML) {
+ return ((SQLXML)value).getString();
+ } else if (value instanceof Clob) {
+ Clob c = (Clob)value;
+ return c.getSubString(1,
c.length()>Integer.MAX_VALUE?Integer.MAX_VALUE:(int)c.length());
+ }
+ return transform(value, String.class, "String"); //$NON-NLS-1$
+ }
+
+ /**
+ * Gets an object value and transforms it into a java.sql.Timestamp object.
+ * @param value, the object to be transformed
+ * @param Calendar object to be used to construct the Timestamp object.
+ * @return a Timestamp object
+ * @throws SQLException if failed to transform to the desired datatype
+ */
+ static final Blob getBlob(Object value) throws SQLException {
+ return transform(value, Blob.class, DefaultDataClasses.BLOB, "Blob");
//$NON-NLS-1$
+ }
+
+ /**
+ * Gets an object value and transforms it into a java.sql.Timestamp object.
+ * @param value, the object to be transformed
+ * @param Calendar object to be used to construct the Timestamp object.
+ * @return a Timestamp object
+ * @throws SQLException if failed to transform to the desired datatype
+ */
+ static final Clob getClob(Object value) throws SQLException {
+ return transform(value, Clob.class, DefaultDataClasses.CLOB, "Clob");
//$NON-NLS-1$
+ }
+
+ /**
+ * Gets an object value and transforms it into a SQLXML object.
+ * @param value, the object to be transformed
+ * @return a SQLXML object
+ * @throws SQLException if failed to transform to the desired datatype
+ */
+ static final SQLXML getSQLXML(Object value) throws SQLException {
+ return transform(value, SQLXML.class, DefaultDataClasses.XML, "SQLXML");
//$NON-NLS-1$
+ }
+}
\ No newline at end of file
Copied: trunk/client/src/main/java/org/teiid/jdbc/DatabaseMetaDataImpl.java (from rev
1983, trunk/client-jdbc/src/main/java/org/teiid/jdbc/DatabaseMetaDataImpl.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/DatabaseMetaDataImpl.java
(rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/DatabaseMetaDataImpl.java 2010-03-22
21:01:44 UTC (rev 1986)
@@ -0,0 +1,2963 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.RowIdLifetime;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Logger;
+
+import org.teiid.client.ResultsMessage;
+import org.teiid.client.metadata.ResultsMetadataConstants;
+import org.teiid.client.metadata.ResultsMetadataDefaults;
+
+import com.metamatrix.common.types.DataTypeManager;
+import com.metamatrix.common.types.MMJDBCSQLTypeInfo;
+import com.metamatrix.common.util.SqlUtil;
+import com.metamatrix.core.CoreConstants;
+import com.metamatrix.core.MetaMatrixRuntimeException;
+
+public class DatabaseMetaDataImpl extends WrapperImpl implements DatabaseMetaData {
+ private static final String DATA_TYPES = "DataTypes"; //$NON-NLS-1$
+
+ private static Logger logger = Logger.getLogger("org.teiid.jdbc");
//$NON-NLS-1$
+
+ /** CONSTANTS */
+ private static final String PERCENT = "%"; //$NON-NLS-1$
+ // constant value indicating that there is not limit
+ private final static int NO_LIMIT = 0;
+ // constant value giving preferred name for a schema
+ private final static String SCHEMA_TERM = "Schema"; //$NON-NLS-1$
+ // constant value giving an empty string value
+ private final static String EMPTY_STRING = ""; //$NON-NLS-1$
+ // constant value giving a string used to escape search strings
+ private final static String ESCAPE_SEARCH_STRING = "\\"; //$NON-NLS-1$
+ // constant value giving an identifier quoting char
+ //private final static String SINGLE_QUOTE = "\'";
+ // constant value giving an identifier quoting string
+ private final static String DOUBLE_QUOTE = "\""; //$NON-NLS-1$
+ // constant value giving extra name characters used in Identifiers
+ private final static String EXTRA_CHARS = ".@"; //$NON-NLS-1$
+ // constant value giving the key words not in SQL-92
+ private final static String KEY_WORDS = "OPTION, SHOWPLAN, DEBUG";
//$NON-NLS-1$
+ // constant value giving preferred name for a procedure
+ private final static String PROCEDURE_TERM = "StoredProcedure";
//$NON-NLS-1$
+ // constant value giving the names of numeric functions supported
+ final static String NUMERIC_FUNCTIONS =
+ "ABS, ACOS, ASIN, ATAN, ATAN2, BITAND, BITNOT, BITOR, BITXOR, CEILING"
//$NON-NLS-1$
+ + ", COS, COT, DEGREES, EXP, FLOOR, FORMATBIGDECIMAL, FORMATBIGINTEGER"
//$NON-NLS-1$
+ + ", FORMATDOUBLE, FORMATFLOAT, FORMATINTEGER, FORMATLONG, LOG, LOG10"
//$NON-NLS-1$
+ + ", MOD, PARSEBIGDECIMAL, PARSEBIGINTEGER, PARSEDOUBLE, PARSEFLOAT"
//$NON-NLS-1$
+ + ", PARSEINTEGER, PARSELONG, PI, POWER, RADIANS, RAND, ROUND, SIGN, SIN,
SQRT, TAN"; //$NON-NLS-1$
+ // constant value giving the names of string functions supported
+ final static String STRING_FUNCTIONS =
+ "ASCII, CHR, CHAR, CONCAT, CONCAT2, INITCAP, INSERT, LCASE, LEFT, LENGTH,
LOCATE, LOWER, LPAD, LTRIM, " + //$NON-NLS-1$
+ "REPEAT, REPLACE, RIGHT, RPAD, RTRIM, SUBSTRING, TRANSLATE, UCASE,
UPPER"; //$NON-NLS-1$
+ // constant value giving the names of date/time functions supported
+ final static String DATE_FUNCTIONS =
+ "CURDATE, CURTIME, NOW, DAYNAME, DAYOFMONTH, DAYOFWEEK, DAYOFYEAR,
FORMATDATE, " + //$NON-NLS-1$
+ "FORMATTIME, FORMATTIMESTAMP, FROM_UNIXTIME, HOUR, MINUTE, MONTH, MONTHNAME,
PARSEDATE, PARSETIME, " + //$NON-NLS-1$
+ "PARSETIMESTAMP, QUARTER, SECOND, TIMESTAMPADD, TIMESTAMPDIFF, WEEK,
YEAR"; //$NON-NLS-1$
+ // constant value giving the names of system functions supported
+ final static String SYSTEM_FUNCTIONS =
+ "CAST, COALESCE, CONVERT, DECODESTRING, DECODEINTEGER, IFNULL, NULLIF, NVL,
LOOKUP"; //$NON-NLS-1$
+ // constant value giving max length of a catalog name
+ private final static int MAX_CATALOG_NAME_LENGTH = 255;
+ // constant value giving max length of a procedure name
+ private final static int MAX_PROCEDURE_NAME_LENGTH = 255;
+ // constant value giving max length of a table name
+ private final static int MAX_TABLE_NAME_LENGTH = 255;
+ // constant value giving max length of a column name
+ private final static int MAX_COLUMN_NAME_LENGTH = 255;
+ // constant value giving max length of a user name
+ private final static int MAX_USER_NAME_LENGTH = 255;
+ // constant value giving min value of a columns scale
+ //private final static short MIN_SCALE = 0;
+ // constant value giving max value of a columns scale
+ //private final static short MAX_SCALE = 256;
+
+ private final static String LIKE_ESCAPE = " LIKE ? ESCAPE '" +
ESCAPE_SEARCH_STRING + "' ";//$NON-NLS-1$//$NON-NLS-2$
+
+ final private static class RUNTIME_MODEL{
+ public final static String VIRTUAL_MODEL_NAME = CoreConstants.SYSTEM_MODEL;
+ }
+
+ private static final String TYPE_MAPPING;
+
+ private static final String PRECISION_MAPPING;
+
+ static {
+ String[] internalTypes = MMJDBCSQLTypeInfo.getMMTypeNames();
+ StringBuffer typeMapping = new StringBuffer();
+ StringBuffer precisionMapping = new StringBuffer();
+ for (int i = 0; i < internalTypes.length; i++) {
+ if (i != 0) {
+ typeMapping.append(","); //$NON-NLS-1$
+ precisionMapping.append(","); //$NON-NLS-1$
+ }
+
typeMapping.append(internalTypes[i]).append(",").append(MMJDBCSQLTypeInfo.getSQLType(internalTypes[i]));
//$NON-NLS-1$
+
precisionMapping.append(internalTypes[i]).append(",").append(ResultsMetadataDefaults.getDefaultPrecision(internalTypes[i]));
//$NON-NLS-1$
+ }
+ TYPE_MAPPING = typeMapping.toString();
+ PRECISION_MAPPING = precisionMapping.toString();
+ }
+
+ private static final String NULLABILITY_MAPPING =
+ new StringBuffer("No Nulls, ").append(DatabaseMetaData.columnNoNulls)
//$NON-NLS-1$
+ .append( ", Nullable, ").append(DatabaseMetaData.columnNullable)
//$NON-NLS-1$
+ .append( ", Unknown, ")
.append(DatabaseMetaData.columnNullableUnknown) //$NON-NLS-1$
+ .toString();
+
+ private static final String PROC_COLUMN_NULLABILITY_MAPPING =
+ new StringBuffer("No Nulls,
").append(DatabaseMetaData.procedureNoNulls) //$NON-NLS-1$
+ .append( ", Nullable,
").append(DatabaseMetaData.procedureNullable) //$NON-NLS-1$
+ .append( ", Unknown, ")
.append(DatabaseMetaData.procedureNullableUnknown) //$NON-NLS-1$
+ .toString();
+
+ private static final String PARAM_DIRECTION_MAPPING =
+ new StringBuffer("In,")
.append(DatabaseMetaData.procedureColumnIn) //$NON-NLS-1$
+ .append( ", Out,")
.append(DatabaseMetaData.procedureColumnOut) //$NON-NLS-1$
+ .append( ", InOut,")
.append(DatabaseMetaData.procedureColumnInOut) //$NON-NLS-1$
+ .append( ",
ReturnValue,").append(DatabaseMetaData.procedureColumnReturn) //$NON-NLS-1$
+ .append( ", ResultSet,")
.append(DatabaseMetaData.procedureColumnResult) //$NON-NLS-1$
+ .toString();
+
+// private static final String UDT_NAME_MAPPING =
+// new StringBuffer("JAVA_OBJECT, ").append(Types.JAVA_OBJECT)
//$NON-NLS-1$
+// .append( ", DISTINCT, ") .append(Types.DISTINCT) //$NON-NLS-1$
+// .append( ", STRUCT, ") .append(Types.STRUCT) //$NON-NLS-1$
+// .append( ", null, ") .append(Types.JAVA_OBJECT).toString();
//$NON-NLS-1$
+
+ private static final String DATATYPES_WITH_NO_PRECISION =
+ new
StringBuffer("'").append(DataTypeManager.DefaultDataTypes.STRING).append("',
'") //$NON-NLS-1$ //$NON-NLS-2$
+ .append(DataTypeManager.DefaultDataTypes.CHAR).append("', '")
//$NON-NLS-1$
+ .append(DataTypeManager.DefaultDataTypes.CLOB).append("', '")
//$NON-NLS-1$
+ .append(DataTypeManager.DefaultDataTypes.BLOB).append("', '")
//$NON-NLS-1$
+ .append(DataTypeManager.DefaultDataTypes.BOOLEAN).append("',
'") //$NON-NLS-1$
+ .append(DataTypeManager.DefaultDataTypes.DATE).append("', '")
//$NON-NLS-1$
+ .append(DataTypeManager.DefaultDataTypes.TIME).append("', '")
//$NON-NLS-1$
+ .append(DataTypeManager.DefaultDataTypes.TIMESTAMP).append("',
'") //$NON-NLS-1$
+
.append(DataTypeManager.DefaultDataTypes.OBJECT).append("'").toString();
//$NON-NLS-1$
+
+ // Queries
+ private final static String QUERY_REFERENCE_KEYS =
+ new StringBuffer("SELECT PKTABLE_CAT, PKTABLE_SCHEM, PKTABLE_NAME,
PKCOLUMN_NAME, FKTABLE_CAT, FKTABLE_SCHEM") //$NON-NLS-1$
+ .append(", FKTABLE_NAME, FKCOLUMN_NAME, KEY_SEQ, UPDATE_RULE, DELETE_RULE,
FK_NAME, PK_NAME, DEFERRABILITY FROM ") //$NON-NLS-1$
+
.append(RUNTIME_MODEL.VIRTUAL_MODEL_NAME).append(".ReferenceKeyColumns").toString();
//$NON-NLS-1$
+
+ private final static String QUERY_CROSS_REFERENCES = new
StringBuffer(QUERY_REFERENCE_KEYS)
+ .append(" WHERE UCASE(PKTABLE_CAT)").append(LIKE_ESCAPE).append("AND
UCASE(FKTABLE_CAT)").append(LIKE_ESCAPE) //$NON-NLS-1$//$NON-NLS-2$
+ .append(" AND UCASE(PKTABLE_SCHEM)").append(LIKE_ESCAPE).append("AND
UCASE(FKTABLE_SCHEM)").append(LIKE_ESCAPE) //$NON-NLS-1$//$NON-NLS-2$
+ .append(" AND
UCASE(PKTABLE_NAME)").append(LIKE_ESCAPE).append("AND
UCASE(FKTABLE_NAME)").append(LIKE_ESCAPE) //$NON-NLS-1$//$NON-NLS-2$
+ .append("ORDER BY FKTABLE_NAME, KEY_SEQ").toString(); //$NON-NLS-1$
+
+ private final static String QUERY_EXPORTED_KEYS = new
StringBuffer(QUERY_REFERENCE_KEYS)
+ .append(" WHERE UCASE(PKTABLE_CAT)").append(LIKE_ESCAPE) //$NON-NLS-1$
+ .append(" AND UCASE(PKTABLE_SCHEM)").append(LIKE_ESCAPE) //$NON-NLS-1$
+ .append(" AND UCASE(PKTABLE_NAME)").append(LIKE_ESCAPE).append("ORDER
BY FKTABLE_NAME, KEY_SEQ").toString(); //$NON-NLS-1$//$NON-NLS-2$
+
+ private final static String QUERY_IMPORTED_KEYS = new
StringBuffer(QUERY_REFERENCE_KEYS)
+ .append(" WHERE UCASE(FKTABLE_CAT)").append(LIKE_ESCAPE) //$NON-NLS-1$
+ .append(" AND UCASE(FKTABLE_SCHEM)").append(LIKE_ESCAPE) //$NON-NLS-1$
+ .append(" AND
UCASE(FKTABLE_NAME)").append(LIKE_ESCAPE).append("ORDER BY PKTABLE_NAME,
KEY_SEQ").toString(); //$NON-NLS-1$//$NON-NLS-2$
+
+ private final static String QUERY_COLUMNS = new StringBuffer("SELECT VDBName AS
TABLE_CAT") //$NON-NLS-1$
+ .append(", SchemaName AS TABLE_SCHEM, TableName AS TABLE_NAME, Name AS
COLUMN_NAME") //$NON-NLS-1$
+ .append(", convert(decodeString(DataType,
'").append(TYPE_MAPPING).append("', ','), short) AS
DATA_TYPE") //$NON-NLS-1$ //$NON-NLS-2$
+ .append(", DataType AS TYPE_NAME") //$NON-NLS-1$
+ .append(", CASE WHEN (DataType IN
(").append(DATATYPES_WITH_NO_PRECISION) //$NON-NLS-1$
+ .append(")) THEN CASE WHEN ElementLength <= 0 THEN
convert(decodeString(DataType,'").append(PRECISION_MAPPING) //$NON-NLS-1$
+ .append("',','), integer) ELSE ElementLength END ELSE CASE WHEN
Precision <= 0 THEN convert(decodeString(DataType,'") //$NON-NLS-1$
+ .append(PRECISION_MAPPING).append("',','), integer) ELSE
Precision END END AS COLUMN_SIZE") //$NON-NLS-1$
+ .append(", NULL AS BUFFER_LENGTH, Scale AS DECIMAL_DIGITS, Radix AS
NUM_PREC_RADIX") //$NON-NLS-1$
+ .append(", convert(decodeString(NullType,
'").append(NULLABILITY_MAPPING).append("', ','), integer) AS
NULLABLE") //$NON-NLS-1$ //$NON-NLS-2$
+ .append(", Description AS REMARKS, DefaultValue AS COLUMN_DEF, NULL AS
SQL_DATA_TYPE, NULL AS SQL_DATETIME_SUB") //$NON-NLS-1$
+ .append(", CharOctetLength AS CHAR_OCTET_LENGTH, Position AS
ORDINAL_POSITION") //$NON-NLS-1$
+ .append(", decodeString(NullType, 'No Nulls, YES, Nullable, NO, Unknown,
'' ''', ',') AS IS_NULLABLE") //$NON-NLS-1$
+ .append(", NULL AS SCOPE_CATALOG, NULL AS SCOPE_SCHEMA, NULL AS SCOPE_TABLE,
NULL AS SOURCE_DATA_TYPE, CASE WHEN e.IsAutoIncremented = 'true' THEN
'YES' ELSE 'NO' END AS IS_AUTOINCREMENT") //$NON-NLS-1$
+ .append(" FROM ").append(RUNTIME_MODEL.VIRTUAL_MODEL_NAME)
//$NON-NLS-1$
+ .append(".Columns e") //$NON-NLS-1$
+ .append(" WHERE UCASE(SchemaName)").append(LIKE_ESCAPE)//$NON-NLS-1$
+ .append("AND UCASE(TableName)") .append(LIKE_ESCAPE) //$NON-NLS-1$
+ .append("AND UCASE(Name)").append(LIKE_ESCAPE) //$NON-NLS-1$
+ .append("AND UCASE(VDBName)").append(LIKE_ESCAPE) //$NON-NLS-1$
+ .append(" ORDER BY TABLE_NAME, ORDINAL_POSITION").toString();
//$NON-NLS-1$
+
+ private static final String QUERY_INDEX_INFO =
+ new StringBuffer("SELECT VDBName AS TABLE_CAT, SchemaName AS TABLE_SCHEM,
TableName AS TABLE_NAME") //$NON-NLS-1$
+ .append(", case when KeyType = 'Index' then TRUE else FALSE end AS
NON_UNIQUE, NULL AS INDEX_QUALIFIER, KeyName AS INDEX_NAME") //$NON-NLS-1$
+ .append(", 0 AS TYPE, convert(Position, short) AS ORDINAL_POSITION, k.Name
AS COLUMN_NAME") //$NON-NLS-1$
+ .append(", NULL AS ASC_OR_DESC, 0 AS CARDINALITY, 1 AS PAGES, NULL AS
FILTER_CONDITION") //$NON-NLS-1$
+ .append(" FROM
").append(RUNTIME_MODEL.VIRTUAL_MODEL_NAME).append(".KeyColumns k")
//$NON-NLS-1$ //$NON-NLS-2$
+ .append(" WHERE UCASE(VDBName)").append(LIKE_ESCAPE)//$NON-NLS-1$
+ .append(" AND UCASE(SchemaName)").append(LIKE_ESCAPE)//$NON-NLS-1$
+ .append(" AND UCASE(TableName)") .append(LIKE_ESCAPE) //$NON-NLS-1$
+ .append(" AND KeyType IN ('Index', ?)") //$NON-NLS-1$
+ .append(" ORDER BY NON_UNIQUE, TYPE, INDEX_NAME,
ORDINAL_POSITION").toString(); //$NON-NLS-1$
+
+ private static final String QUERY_PRIMARY_KEYS =
+ new StringBuffer("SELECT VDBName as TABLE_CAT, SchemaName AS TABLE_SCHEM,
TableName AS TABLE_NAME") //$NON-NLS-1$
+ .append(", k.Name AS COLUMN_NAME, convert(Position, short) AS KEY_SEQ,
KeyName AS PK_NAME") //$NON-NLS-1$
+ .append(" FROM
").append(RUNTIME_MODEL.VIRTUAL_MODEL_NAME).append(".KeyColumns k")
//$NON-NLS-1$ //$NON-NLS-2$
+ .append(" WHERE UCASE(VDBName)").append(LIKE_ESCAPE)//$NON-NLS-1$
+ .append(" AND UCASE(SchemaName)").append(LIKE_ESCAPE)//$NON-NLS-1$
+ .append(" AND UCASE(TableName)") .append(LIKE_ESCAPE) //$NON-NLS-1$
+ .append(" AND KeyType LIKE 'Primary'") //$NON-NLS-1$
+ .append(" ORDER BY COLUMN_NAME, KEY_SEQ").toString(); //$NON-NLS-1$
+
+ private final static String QUERY_PROCEDURES =
+ new StringBuffer("SELECT VDBName AS PROCEDURE_CAT, SchemaName AS
PROCEDURE_SCHEM") //$NON-NLS-1$
+ .append(", p.Name AS PROCEDURE_NAME, convert(null, string) AS
RESERVED_1") //$NON-NLS-1$
+ .append(", convert(null, string) AS RESERVED_2, convert(null, string) AS
RESERVED_3, p.Description AS REMARKS") //$NON-NLS-1$
+ .append(", convert(decodeString(p.ReturnsResults, 'true,
").append(DatabaseMetaData.procedureReturnsResult) //$NON-NLS-1$
+ .append(", false,
").append(DatabaseMetaData.procedureNoResult).append("'), short) AS
PROCEDURE_TYPE, p.Name AS SPECIFIC_NAME FROM ") //$NON-NLS-1$ //$NON-NLS-2$
+ .append(RUNTIME_MODEL.VIRTUAL_MODEL_NAME).append(".Procedures as p")
//$NON-NLS-1$
+ .append(" WHERE UCASE(VDBName)").append(LIKE_ESCAPE)//$NON-NLS-1$
+ .append(" AND UCASE(SchemaName)").append(LIKE_ESCAPE)//$NON-NLS-1$
+ .append(" AND UCASE(p.Name)").append(LIKE_ESCAPE) //$NON-NLS-1$
+ .append(" ORDER BY PROCEDURE_SCHEM, PROCEDURE_NAME").toString();
//$NON-NLS-1$
+
+ private final static String QUERY_PROCEDURE_COLUMNS =
+ new StringBuffer("SELECT VDBName PROCEDURE_CAT, SchemaName AS
PROCEDURE_SCHEM") //$NON-NLS-1$
+ .append(", ProcedureName AS PROCEDURE_NAME, p.Name AS COLUMN_NAME")
//$NON-NLS-1$
+ .append(", convert(decodeString(TYPE,
'").append(PARAM_DIRECTION_MAPPING).append("', ','), short) AS
COLUMN_TYPE") //$NON-NLS-1$ //$NON-NLS-2$
+ .append(", convert(decodeString(DataType,
'").append(TYPE_MAPPING).append("', ','), integer) AS
DATA_TYPE") //$NON-NLS-1$ //$NON-NLS-2$
+ .append(", DataType AS TYPE_NAME, CASE WHEN Precision <= 0 THEN
convert(decodeString(DataType,'").append(PRECISION_MAPPING) //$NON-NLS-1$
+ .append("',','), integer) ELSE Precision END AS PRECISION, CASE
WHEN TypeLength <= 0 THEN convert(decodeString(DataType,'") //$NON-NLS-1$
+ .append(PRECISION_MAPPING).append("',','), integer) ELSE
TypeLength END AS LENGTH, convert(Scale, short) AS SCALE") //$NON-NLS-1$
+ .append(", Radix AS RADIX, convert(decodeString(NullType, '")
//$NON-NLS-1$
+ .append(PROC_COLUMN_NULLABILITY_MAPPING).append("', ','),
integer) AS NULLABLE") //$NON-NLS-1$
+ .append(", convert(null, string) AS REMARKS, NULL AS COLUMN_DEF")
//$NON-NLS-1$
+ .append(", NULL AS SQL_DATA_TYPE, NULL AS SQL_DATETIME_SUB, NULL AS
CHAR_OCTET_LENGTH, p.Position AS ORDINAL_POSITION") //$NON-NLS-1$
+ .append(", CASE NullType WHEN 'Nullable' THEN 'YES' WHEN
'No Nulls' THEN 'NO' ELSE '' END AS IS_NULLABLE, p.ProcedureName
as SPECIFIC_NAME FROM ") //$NON-NLS-1$
+ .append(RUNTIME_MODEL.VIRTUAL_MODEL_NAME)
+ .append(".ProcedureParams as p") //$NON-NLS-1$
+ .append(" WHERE UCASE(VDBName)").append(LIKE_ESCAPE)//$NON-NLS-1$
+ .append(" AND UCASE(SchemaName)").append(LIKE_ESCAPE)//$NON-NLS-1$
+ .append(" AND UCASE(ProcedureName)") .append(LIKE_ESCAPE)
//$NON-NLS-1$
+ .append(" AND UCASE(p.Name) LIKE ?") //$NON-NLS-1$
+ .append(" ORDER BY PROCEDURE_SCHEM, PROCEDURE_NAME, COLUMN_TYPE,
POSITION").toString(); //$NON-NLS-1$
+
+ private static final String QUERY_SCHEMAS =
+ new StringBuffer("SELECT Name AS TABLE_SCHEM, VDBName AS TABLE_CATALOG")
//$NON-NLS-1$
+ .append(" FROM
").append(RUNTIME_MODEL.VIRTUAL_MODEL_NAME).append(".Schemas")
//$NON-NLS-1$ //$NON-NLS-2$
+ .append(" WHERE UCASE(VDBName)").append(LIKE_ESCAPE)//$NON-NLS-1$
+ .append(" AND UCASE(Name)").append(LIKE_ESCAPE)//$NON-NLS-1$
+ .append(" ORDER BY TABLE_SCHEM").toString(); //$NON-NLS-1$
+
+ private final static String TABLE_TYPE = "CASE WHEN IsSystem = 'true'
and UCASE(Type) = 'TABLE' THEN 'SYSTEM TABLE' ELSE UCASE(Type) END";
//$NON-NLS-1$
+
+ private final static String QUERY_TABLES =
+ new StringBuffer("SELECT VDBName AS TABLE_CAT, SchemaName AS TABLE_SCHEM, Name
AS TABLE_NAME") //$NON-NLS-1$
+ .append(", ").append(TABLE_TYPE).append(" AS TABLE_TYPE,
Description AS REMARKS, NULL AS TYPE_CAT, NULL AS TYPE_SCHEM") //$NON-NLS-1$
//$NON-NLS-2$
+ .append(", NULL AS TYPE_NAME, NULL AS SELF_REFERENCING_COL_NAME, NULL AS
REF_GENERATION, IsPhysical AS ISPHYSICAL") //$NON-NLS-1$
+ .append(" FROM
").append(RUNTIME_MODEL.VIRTUAL_MODEL_NAME).append(".Tables g ")
//$NON-NLS-1$ //$NON-NLS-2$
+ .append(" WHERE UCASE(VDBName)").append(LIKE_ESCAPE)//$NON-NLS-1$
+ .append(" AND UCASE(SchemaName)").append(LIKE_ESCAPE)//$NON-NLS-1$
+ .append(" AND UCASE(Name)") .append(LIKE_ESCAPE).toString();
//$NON-NLS-1$
+
+// private static final String QUERY_UDT =
+// new StringBuffer("SELECT NULL AS TYPE_CAT, v.Name AS TYPE_SCHEM, TypeName AS
TYPE_NAME") //$NON-NLS-1$
+// .append(", JavaClass AS CLASS_NAME, decodeString(JavaClass,
'").append(UDT_NAME_MAPPING).append("', ',') AS DATA_TYPE")
//$NON-NLS-1$ //$NON-NLS-2$
+// .append(", Description AS REMARKS") //$NON-NLS-1$
+// .append(", decodeString(BaseType,
'").append(UDT_NAME_MAPPING).append("', ',') AS BASE_TYPE
") //$NON-NLS-1$ //$NON-NLS-2$
+// .append(" FROM
").append(RUNTIME_MODEL.VIRTUAL_MODEL_NAME).append(".DataTypes CROSS JOIN
") //$NON-NLS-1$ //$NON-NLS-2$
+// .append(RUNTIME_MODEL.VIRTUAL_MODEL_NAME).append(".VirtualDatabases
v") //$NON-NLS-1$
+// .append(" WHERE UCASE(v.Name)").append(LIKE_ESCAPE).append("AND
UCASE(TypeName)").append(LIKE_ESCAPE).append("ORDER BY DATA_TYPE, TYPE_SCHEM,
TYPE_NAME ").toString(); //$NON-NLS-1$
+
+ /** ATTRIBUTES */
+
+ // driver's connection object used in constructin this object.
+ private ConnectionImpl driverConnection;
+
+ /**
+ * <p>Constructor which initializes with the connection object on which
metadata
+ * is sought
+ * @param driver's connection object.
+ * @throws SQLException if the connection is already closed.
+ */
+ DatabaseMetaDataImpl(ConnectionImpl connection) {
+ this.driverConnection = connection;
+ }
+
+ /**
+ * <p>Checks whether the current user has the required security rights to call
+ * all the procedures returned by the method getProcedures.</p>
+ * @return true if the precedures are selectable else return false
+ * @throws SQLException. Should never occur.
+ */
+ public boolean allProceduresAreCallable() throws SQLException {
+ return true;
+ }
+
+ /**
+ * <p>Checks whether the current user can use SELECT statement with all of the
+ * tables returned by the method getTables. Selectability is column level in
+ * metamatrix, hence return true</p>
+ * @return true if tables are selectable else return false
+ * @throws SQLException. Should never occur.
+ */
+ public boolean allTablesAreSelectable() throws SQLException {
+ return true;
+ }
+
+ /**
+ * <p>Checks whether a DDL statement within a transaction forces the
transaction
+ * to commit.</p>
+ * @return if so return true else return false.
+ * @throws SQLException Should never occur.
+ */
+ public boolean dataDefinitionCausesTransactionCommit() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Checks whether a DDL statement within a transaction is
ignored.</p>
+ * @return if so return true, else false
+ * @throw SQLException Should never occur.
+ */
+ public boolean dataDefinitionIgnoredInTransactions() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Indicates whether or not a visible row delete can be detected by
+ * calling ResultSet.rowDeleted(). If deletesAreDetected()
+ * returns false, then deleted rows are removed from the result set.
+ * @param result set type, i.e. ResultSet.TYPE_XXX
+ * @return true if changes are detected by the resultset type
+ * @throws SQLException, should never occur
+ */
+ public boolean deletesAreDetected(int type) throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Did getMaxRowSize() include LONGVARCHAR and LONGVARBINARY
+ * blobs?</p>
+ * @return <code>true</code> if so; <code>false</code>
otherwise
+ * @throws SQLException, should never occur
+ */
+ public boolean doesMaxRowSizeIncludeBlobs() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Gets a description of a table's optimal set of columns that uniquely
identifies a row.</p>
+ * @param name of the catalog from which metadata needs
+ * @param catalog name in which the table is present.
+ * @param schema name in which this table is present.
+ * @param table name whose best row identifier info is sought.
+ * @param int indicating the scope of the result.
+ * @param boolean indicating whether the nullable columns can be included.
+ * @return ResultSet object containing the bestrow indetifier info.
+ */
+ public ResultSet getBestRowIdentifier(String catalog, String schema, String table,
int scope, boolean nullable) throws SQLException {
+
+ // here it always returns a empty result set, when this functionality
+ // is being changed make sure that we check the catelog & schema here
+ // to filter.
+
+ // list containing records/rows in the ResultSet
+ List records = new ArrayList (0);
+
+ /***********************************************************************
+ * Hardcoding JDBC column names for the columns returned in results object
+ ***********************************************************************/
+ Map[] metadataList = new Map[8];
+
+ // HardCoding metadata details for SCOPE column
+ metadataList[0] = getColumnMetadata(null, JDBCColumnNames.BEST_ROW.SCOPE,
+ MMJDBCSQLTypeInfo.SHORT,
ResultsMetadataConstants.NULL_TYPES.NOT_NULL);
+
+ // HardCoding metadata details for COLUMN_NAME column
+ metadataList[1] = getColumnMetadata(null, JDBCColumnNames.BEST_ROW.COLUMN_NAME,
+ MMJDBCSQLTypeInfo.STRING,
ResultsMetadataConstants.NULL_TYPES.NOT_NULL);
+
+ // HardCoding metadata details for DATA_TYPE column
+ metadataList[2] = getColumnMetadata(null, JDBCColumnNames.BEST_ROW.DATA_TYPE,
+ MMJDBCSQLTypeInfo.SHORT,
ResultsMetadataConstants.NULL_TYPES.NOT_NULL);
+
+ // HardCoding metadata details for TYPE_NAME column
+ metadataList[3] = getColumnMetadata(null, JDBCColumnNames.BEST_ROW.TYPE_NAME,
+ MMJDBCSQLTypeInfo.STRING,
ResultsMetadataConstants.NULL_TYPES.NOT_NULL);
+
+ // HardCoding metadata details for COLUMN_SIZE column
+ metadataList[4] = getColumnMetadata(null, JDBCColumnNames.BEST_ROW.COLUMN_SIZE,
+ MMJDBCSQLTypeInfo.INTEGER,
ResultsMetadataConstants.NULL_TYPES.NOT_NULL);
+
+ // HardCoding metadata details for BUFFER_LENGTH column
+ metadataList[5] = getColumnMetadata(null,
JDBCColumnNames.BEST_ROW.BUFFER_LENGTH,
+ MMJDBCSQLTypeInfo.INTEGER,
ResultsMetadataConstants.NULL_TYPES.NULLABLE);
+
+ // HardCoding metadata details for DECIMAL_DIGITS column
+ metadataList[6] = getColumnMetadata(null,
JDBCColumnNames.BEST_ROW.DECIMAL_DIGITS,
+ MMJDBCSQLTypeInfo.SHORT,
ResultsMetadataConstants.NULL_TYPES.NOT_NULL);
+
+ // HardCoding metadata details for PSEUDO_COLUMN column
+ metadataList[7] = getColumnMetadata(null,
JDBCColumnNames.BEST_ROW.PSEUDO_COLUMN,
+ MMJDBCSQLTypeInfo.SHORT,
ResultsMetadataConstants.NULL_TYPES.NOT_NULL);
+
+ // logging
+ String logMsg =
JDBCPlugin.Util.getString("MMDatabaseMetadata.Best_row_sucess", table);
//$NON-NLS-1$
+ logger.fine(logMsg);
+
+ // construct results object from column values and their metadata
+ return createResultSet(records, metadataList);
+ }
+
+ /**
+ * <p>Gets the catalog names available to metamatrix. The results are ordered
by
+ * catalog name. There is no concept of catalogs in a metamatrix driver and this
+ * returns an empty resultSet.
+ * @return ResultSet object containing metadata info of the catalog on this
connection.
+ * @throws SQLException if there is an error obtaining server results
+ */
+ public ResultSet getCatalogs() throws SQLException {
+ // list containing records/rows in the ResultSet
+ List records = new ArrayList (0);
+
+ /***********************************************************************
+ * Hardcoding JDBC column names for the columns returned in results object
+ ***********************************************************************/
+ Map[] metadataList = new Map[1];
+
+ // HardCoding metadata details for TABLE_CAT column
+ metadataList[0] = getColumnMetadata(null, JDBCColumnNames.CATALOGS.TABLE_CAT,
+ MMJDBCSQLTypeInfo.STRING,
ResultsMetadataConstants.NULL_TYPES.NULLABLE);
+
+ // logging
+ String logMsg =
JDBCPlugin.Util.getString("MMDatabaseMetadata.Catalog_success"); //$NON-NLS-1$
+ logger.fine(logMsg);
+
+ // construct results object from column values and their metadata
+ return createResultSet(records, metadataList);
+ }
+
+ private ResultSet createResultSet(List records, Map[] columnMetadata) throws
SQLException {
+ ResultSetMetaData rsmd = new ResultSetMetaDataImpl(new
MetadataProvider(columnMetadata));
+
+ return createResultSet(records, rsmd);
+ }
+
+ private ResultSet createResultSet(List records, ResultSetMetaData rsmd) throws
SQLException {
+ ResultsMessage resultsMsg = createDummyResultsMessage(null, null, records);
+ StatementImpl stmt = StatementImpl.newInstance(this.driverConnection,
ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
+ return new ResultSetImpl(resultsMsg, stmt, rsmd, 0);
+ }
+
+ private ResultSet createEmptyResultSet(String[] columnNames, String[] dataTypes)
throws SQLException {
+ ResultsMessage resultsMsg = createDummyResultsMessage(columnNames, dataTypes,
Collections.EMPTY_LIST);
+ StatementImpl stmt = StatementImpl.newInstance(this.driverConnection,
ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
+ try {
+ stmt.setFetchSize(500);
+ } catch(SQLException e) {
+ // will never happen but throw a runtime if it does
+ throw new MetaMatrixRuntimeException(e);
+ }
+ Map[] metadata = new Map[columnNames.length];
+ for (int i = 0; i < columnNames.length; i++) {
+ metadata[i] = getColumnMetadata(null, columnNames[i], dataTypes[i],
ResultsMetadataConstants.NULL_TYPES.UNKNOWN);
+ }
+ return new ResultSetImpl(resultsMsg, stmt, new ResultSetMetaDataImpl(new
MetadataProvider(metadata)), 0);
+ }
+
+ private ResultsMessage createDummyResultsMessage(String[] columnNames, String[]
dataTypes, List records) {
+ ResultsMessage resultsMsg = new ResultsMessage();
+ resultsMsg.setColumnNames(columnNames);
+ resultsMsg.setDataTypes(dataTypes);
+ resultsMsg.setFirstRow(1);
+ resultsMsg.setLastRow(records.size());
+ resultsMsg.setFinalRow(records.size());
+ resultsMsg.setResults((List[])records.toArray(new List[records.size()]));
+ return resultsMsg;
+ }
+
+ /**
+ * <p>Gets the String object used to separate a catalog name and a table name
+ * @return String delimiter
+ * @throws SQLException, should never occur.
+ */
+ public String getCatalogSeparator() throws SQLException {
+ return EMPTY_STRING;
+ }
+
+ /**
+ * <p>Get the metamatrix term for catalog
+ * @return String representing catalog name
+ * @throws SQLException, should never occur.
+ */
+ public String getCatalogTerm() throws SQLException {
+ return EMPTY_STRING;
+ }
+
+ /**
+ * <p>Gets a description of the access rights for a column of the given name.
+ * Catalog, schema and table names are not used to narrow down the search,
+ * but the schema name should match the virtualdatabasename used to obtain
+ * this driver connection.</p>
+ * @param name of the catalog to which columns belong.
+ * @param name of the schema to which columns belong.
+ * @param name of the table to which columns belong.
+ * @param name pattern to be matched by column names.
+ * @return ResultSet containing column privilage information.
+ * @throws SQLException if there is an error obtaining server results
+ */
+ public ResultSet getColumnPrivileges(String catalog, String schema, String table,
String columnName) throws SQLException {
+
+ List records = new ArrayList (0);
+ /***********************************************************************
+ * Hardcoding JDBC column names for the columns returned in results object
+ ***********************************************************************/
+ Map[] metadataList = new Map[8];
+
+ metadataList[0] = getColumnMetadata(null, JDBCColumnNames.PRIVILEGES.TABLE_CAT,
+ MMJDBCSQLTypeInfo.STRING,
ResultsMetadataConstants.NULL_TYPES.NULLABLE);
+ metadataList[1] = getColumnMetadata(null,
JDBCColumnNames.PRIVILEGES.TABLE_SCHEM,
+ MMJDBCSQLTypeInfo.STRING,
ResultsMetadataConstants.NULL_TYPES.NULLABLE);
+ metadataList[2] = getColumnMetadata(null, JDBCColumnNames.PRIVILEGES.TABLE_NAME,
+ MMJDBCSQLTypeInfo.STRING,
ResultsMetadataConstants.NULL_TYPES.NOT_NULL);
+ metadataList[3] = getColumnMetadata(null,
JDBCColumnNames.PRIVILEGES.COLUMN_NAME,
+ MMJDBCSQLTypeInfo.STRING,
ResultsMetadataConstants.NULL_TYPES.NOT_NULL);
+ metadataList[4] = getColumnMetadata(null, JDBCColumnNames.PRIVILEGES.GRANTOR,
+ MMJDBCSQLTypeInfo.STRING,
ResultsMetadataConstants.NULL_TYPES.NULLABLE);
+ metadataList[5] = getColumnMetadata(null, JDBCColumnNames.PRIVILEGES.GRANTEE,
+ MMJDBCSQLTypeInfo.STRING,
ResultsMetadataConstants.NULL_TYPES.NOT_NULL);
+ metadataList[6] = getColumnMetadata(null, JDBCColumnNames.PRIVILEGES.PRIVILEGE,
+ MMJDBCSQLTypeInfo.STRING,
ResultsMetadataConstants.NULL_TYPES.NOT_NULL);
+ metadataList[7] = getColumnMetadata(null,
JDBCColumnNames.PRIVILEGES.IS_GRANTABLE,
+ MMJDBCSQLTypeInfo.STRING,
ResultsMetadataConstants.NULL_TYPES.NULLABLE);
+
+ return createResultSet(records, metadataList);
+
+ }
+
+ /**
+ * <p>Get's the metadata information about the columns whose names match
the given
+ * columnNamePattern. Catalog, schema and tableNamePattern are not used to
+ * narrow down the search, but Catalog and schema names should match the
+ * virtualdatabasename and version used to obtain this driver connection.</p>
+ * <p> The ResultSet returned by this method contains the following additional
+ * columns that are not specified in the JDBC specification.</p>
+ * <OL>
+ * <LI><B>Format</B> String => format of the column
+ * <LI><B>MinRange</B> String => minimum range value of the
column
+ * <LI><B>MaxRange</B> String => maximum range value of the
column
+ * <OL>
+ * @param catalog name to which the columns belong.
+ * @param schema name to which the columns belong.
+ * @param pattern name to be matched by table name.
+ * @param pattern name to be matched by column name.
+ * @return ResultSet containing column metadata info.
+ * @throws SQLException if there is an error obtaining server results.
+ */
+ public ResultSet getColumns(String catalog, String schema, String tableNamePattern,
String columnNamePattern) throws SQLException {
+
+ if (catalog == null) {
+ catalog = PERCENT;
+ }
+
+ if (schema == null) {
+ schema = PERCENT;
+ }
+ // Get columns in all the tables if tableNamePattern is null
+ if(tableNamePattern == null) {
+ tableNamePattern = PERCENT;
+ }
+ // Get all columns if columnNamePattern is null
+ if(columnNamePattern == null) {
+ columnNamePattern = PERCENT;
+ }
+
+ // list which represent records containing column info
+ List records = new ArrayList ();
+ ResultSetMetaData rmetadata = null;
+ ResultSetImpl results = null;
+ PreparedStatement prepareQuery = null;
+
+ try {
+ prepareQuery = driverConnection.prepareStatement(QUERY_COLUMNS);
+ prepareQuery.setObject(1, schema.toUpperCase());
+ prepareQuery.setObject(2, tableNamePattern.toUpperCase());
+ prepareQuery.setObject(3, columnNamePattern.toUpperCase());
+ prepareQuery.setObject(4, catalog.toUpperCase());
+
+ // make a query against runtimemetadata and get results
+ results = (ResultSetImpl) prepareQuery.executeQuery();
+
+ // build the list of records of column description
+ while (results.next ()) {
+ // list represents a record on the Results object.
+ List currentRow = new
ArrayList(JDBCColumnPositions.COLUMNS.MAX_COLUMNS);
+
+ // add values in the current record on the Results object to the list
+ // number of values to be fetched from each row is MAX_COLUMNS.
+ for(int i=0; i < JDBCColumnPositions.COLUMNS.MAX_COLUMNS; i++) {
+ // get the value at the current index add it to currentRow
+ currentRow.add(results.getObject(i+1));
+ }
+ records.add(currentRow);
+ }// end of while
+
+ // get the metadata for the results
+ rmetadata = results.getMetaData();
+
+ } catch(Exception e) {
+ // logging
+ String logMsg =
JDBCPlugin.Util.getString("MMDatabaseMetadata.getCols_error", columnNamePattern,
tableNamePattern, e.getMessage()); //$NON-NLS-1$
+ throw TeiidSQLException.create(e, logMsg);
+ }
+
+ // logging
+ String logMsg =
JDBCPlugin.Util.getString("MMDatabaseMetadata.getCols_success",
columnNamePattern, tableNamePattern); //$NON-NLS-1$
+ logger.fine(logMsg);
+
+ // construct results object from column values and their metadata
+ return createResultSet(records, rmetadata);
+ }
+
+ /**
+ * <p>Gets the description of the foreign key columns in the table
foreignTable.
+ * These foreign key columns reference primary key columns of primaryTable.
+ * Catalog and schema information is not used to narrow down the search, but
+ * Catalog and schema names(primary and foreign) should match the
+ * virtualdatabasename and version used to obtain this driver connection.
+ * @param name of the catalog containing primary keys.
+ * @param name of the schema containing primary keys.
+ * @param name of the table containing primary keys.
+ * @param name of the catalog containing foreign keys.
+ * @param name of the schema containing foreign keys.
+ * @param name of the table containing foreign keys.
+ * @return ResultSet giving description of foreign key columns.
+ * @throws SQLException if there is an error obtaining server results
+ */
+ public ResultSet getCrossReference(String primaryCatalog, String primarySchema,String
primaryTable,String foreignCatalog,String foreignSchema, String foreignTable) throws
SQLException {
+
+ if (primaryCatalog == null) {
+ primaryCatalog = PERCENT;
+ }
+
+ if (foreignCatalog == null) {
+ foreignCatalog = PERCENT;
+ }
+
+ if (primarySchema == null) {
+ primarySchema = PERCENT;
+ }
+
+ if (foreignSchema == null) {
+ foreignSchema = PERCENT;
+ }
+
+ if (primaryTable == null) {
+ primaryTable = PERCENT;
+ }
+
+ if (foreignTable == null) {
+ foreignTable = PERCENT;
+ }
+
+ ResultSetImpl results = null;
+ try {
+ PreparedStatement prepareQuery =
driverConnection.prepareStatement(QUERY_CROSS_REFERENCES);
+ prepareQuery.setObject(1, primaryCatalog.toUpperCase());
+ prepareQuery.setObject(2, foreignCatalog.toUpperCase());
+ prepareQuery.setObject(3, primarySchema.toUpperCase());
+ prepareQuery.setObject(4, foreignSchema.toUpperCase());
+ prepareQuery.setObject(5, primaryTable.toUpperCase());
+ prepareQuery.setObject(6, foreignTable.toUpperCase());
+
+ // make a query against runtimemetadata and get results
+ results = (ResultSetImpl) prepareQuery.executeQuery();
+ } catch(Exception e) {
+ // logging
+ String logMsg =
JDBCPlugin.Util.getString("MMDatabaseMetadata.getCrossRef_error", primaryTable,
foreignTable, e.getMessage()); //$NON-NLS-1$
+ throw TeiidSQLException.create(e, logMsg);
+ }
+
+ ResultSet resultSet = getReferenceKeys(results);
+
+ // logging
+ String logMsg =
JDBCPlugin.Util.getString("MMDatabaseMetadata.getCrossRef_success",
primaryTable, foreignTable); //$NON-NLS-1$
+ logger.fine(logMsg);
+
+ return resultSet;
+ }
+
+ /**
+ * Retrieves the minor version number of the underlying database.
+ * @return intValue of database's minor version
+ * @throws SQLException if a database access error occurs.
+ */
+ public int getDatabaseMinorVersion() throws SQLException {
+ return TeiidDriver.getInstance().getMinorVersion();
+ }
+
+ /**
+ * Retrieves the major version number of the underlying database.
+ * @return intValue of database's minor version
+ * @throws SQLException if a database access error occurs.
+ */
+ public int getDatabaseMajorVersion() throws SQLException {
+ return TeiidDriver.getInstance().getMajorVersion();
+ }
+
+ /**
+ * Retrieves the major JDBC version number for this driver.
+ * @return intValue JDBC major version number
+ * @throws SQLException should never occur.
+ */
+ public int getJDBCMajorVersion() throws SQLException {
+ return 3;
+ }
+
+ /**
+ * Retrieves the minor JDBC version number for this driver.
+ * @return intValue JDBC major version number
+ * @throws SQLException should never occur.
+ */
+ public int getJDBCMinorVersion() throws SQLException {
+ return 0;
+ }
+
+ /**
+ * <p>Gets the product name for this database
+ * @return String representing the product name
+ * @throws SQLException should never occur.
+ */
+ public String getDatabaseProductName() throws SQLException {
+ return this.driverConnection.getDatabaseName();
+ }
+
+ /**
+ * <p>Gets the version of metamatrix server to which this driver connects
+ * @return String representing the product version
+ * @throws SQLException if there is an error accessing product release info.
+ */
+ public String getDatabaseProductVersion() throws SQLException {
+ return TeiidDriver.getInstance().getMajorVersion() + "." +
TeiidDriver.getInstance().getMinorVersion(); //$NON-NLS-1$
+ }
+
+ /**
+ * <p>Gets metamatrix default transaction isolation level.
+ * @return intvalue giving the transaction isolation level
+ * @throws SQLException never
+ */
+ public int getDefaultTransactionIsolation() throws SQLException {
+ return Connection.TRANSACTION_NONE;
+ }
+
+ /**
+ * <p>Gets this drivers major version number
+ * @return int representing the driver's major version
+ */
+ public int getDriverMajorVersion() {
+ return TeiidDriver.getInstance().getMajorVersion();
+ }
+
+ /**
+ * <p>Gets this drivers minor version number
+ * @return int representing the driver's minor version
+ */
+ public int getDriverMinorVersion() {
+ return TeiidDriver.getInstance().getMinorVersion();
+ }
+
+ /**
+ * <p>Get the name of this JDBC driver
+ * @return String representing the driver's name
+ * @throws SQLException, if the connection is already closed.
+ */
+ public String getDriverName() throws SQLException {
+ return TeiidDriver.getInstance().getDriverName();
+ }
+
+ /**
+ * <p>This method gets the version of this JDBC driver. It combines the major
+ * and minor version numbers
+ * @return String representing the driver's version
+ * @throws SQLException, should never occur.
+ */
+ public String getDriverVersion() throws SQLException {
+ return getDriverMajorVersion()+"."+getDriverMinorVersion ();
//$NON-NLS-1$
+ }
+
+ /**
+ * <p>This method gets a description of the forignkey columns that reference
the
+ * primary key columns in the given table. Catalog and schema names are not
+ * used to narrow down the search, but they should match the virtualdatabasename
+ * and version used to obtain this driver connection.
+ * @param name of the catalog which contains the given table.
+ * @param schema name which contains the given table.
+ * @param table name which contains the primary keys.
+ * @return ResultSet object giving the exported key info.
+ * @throws SQLException if there is an error obtaining server results
+ */
+ public ResultSet getExportedKeys(String catalog, String schema, String table) throws
SQLException {
+ if (catalog == null) {
+ catalog = PERCENT;
+ }
+
+ if (schema == null) {
+ schema = PERCENT;
+ }
+
+ if (table == null) {
+ table = PERCENT;
+ }
+
+ ResultSetImpl results = null;
+ try {
+ PreparedStatement prepareQuery =
driverConnection.prepareStatement(QUERY_EXPORTED_KEYS);
+ prepareQuery.setObject(1, catalog.toUpperCase());
+ prepareQuery.setObject(2, schema.toUpperCase());
+ prepareQuery.setObject(3, table.toUpperCase());
+
+ // make a query against runtimemetadata and get results
+ results = (ResultSetImpl) prepareQuery.executeQuery();
+ } catch(Exception e) {
+ // logging
+ String logMsg =
JDBCPlugin.Util.getString("MMDatabaseMetadata.getExpKey_error", table,
e.getMessage()); //$NON-NLS-1$
+ throw TeiidSQLException.create(e, logMsg);
+ }
+
+ ResultSet resultSet = getReferenceKeys(results);
+
+
logger.fine(JDBCPlugin.Util.getString("MMDatabaseMetadata.getExpKey_success",
table));//$NON-NLS-1$
+
+ return resultSet;
+ }
+
+ /**
+ * <p>Gets the extra characters that can be used in unquoted identifier names
+ * (those beyond a-z, 0-9, and _)
+ * @return String representing extra charachters that can be used in identifier
names.
+ * @throws SQLException, should never occur
+ */
+ public String getExtraNameCharacters() throws SQLException {
+ return EXTRA_CHARS;// ".@" is use in fully qualified identifier names
+ }
+
+ /**
+ * <p>Get's the string used to quote SQL identifiers. This returns a "
" if identifier
+ * quoting is not supported.
+ * @return string used to quote SQL identifiers.
+ * @throws SQLException, should never occur
+ */
+ public String getIdentifierQuoteString() throws SQLException {
+ return DOUBLE_QUOTE;
+ }
+
+ /**
+ * <p>Gets a description of the primary key columns that are referenced by the
+ * foreign key columns in the given table. Catalog and schema names are not
+ * used to narrow down the search, but they should match the virtualdatabasename
+ * and version used to obtain this driver connection.
+ * @param name of the catalog which contains the given table.
+ * @param schema name which contains the given table.
+ * @param table name which contains the foreign keys.
+ * @return ResultSet object giving the imported key info.
+ * @throws SQLException if there is an error obtaining server results
+ */
+ public ResultSet getImportedKeys(String catalog, String schema, String table) throws
SQLException {
+ if (catalog == null) {
+ catalog = PERCENT;
+ }
+
+ if (schema == null) {
+ schema = PERCENT;
+ }
+
+ if (table == null) {
+ table = PERCENT;
+ }
+
+ ResultSetImpl results = null;
+ try {
+ PreparedStatement prepareQuery =
driverConnection.prepareStatement(QUERY_IMPORTED_KEYS);
+ prepareQuery.setObject(1, catalog.toUpperCase());
+ prepareQuery.setObject(2, schema.toUpperCase());
+ prepareQuery.setObject(3, table.toUpperCase());
+
+
+ // make a query against runtimemetadata and get results
+ results = (ResultSetImpl) prepareQuery.executeQuery();
+ } catch(Exception e) {
+ String logMsg =
JDBCPlugin.Util.getString("MMDatabaseMetadata.getImpKey_error", table,
e.getMessage()); //$NON-NLS-1$
+ throw TeiidSQLException.create(e, logMsg);
+ }
+
+ ResultSet resultSet = getReferenceKeys(results);
+
+
logger.fine(JDBCPlugin.Util.getString("MMDatabaseMetadata.getImpKey_success",
table)); //$NON-NLS-1$
+
+ return resultSet;
+ }
+
+ /**
+ * <p>Gets a description of the indexes that are present on a given table.
+ *
+ * @param name of the catalog which contains the given table.
+ * @param schema name which contains the given table.
+ * @param table name which contains the indexes.
+ * @param boolean indicating if unique key info needs to be returned.
+ * @param boolean indicating if approximate value are to be allowed.
+ * @return ResultSet object containing metadata info of index columns.
+ * @throws SQLException if catalog/schema info does not match for this connection.
+ */
+ public ResultSet getIndexInfo(String catalog, String schema, String table, boolean
unique, boolean approximate) throws SQLException {
+ if (catalog == null) {
+ catalog = PERCENT;
+ }
+
+ if (schema == null) {
+ schema = PERCENT;
+ }
+
+ if (table == null) {
+ table = PERCENT;
+ }
+ // list which represent records containing primary key info
+ List records = new ArrayList ();
+ ResultSetMetaData rmetadata = null;
+ ResultSetImpl results = null;
+ PreparedStatement prepareQuery = null;
+
+ try {
+ prepareQuery = driverConnection.prepareStatement(QUERY_INDEX_INFO);
+ prepareQuery.setObject(1, catalog.toUpperCase());
+ prepareQuery.setObject(2, schema.toUpperCase());
+ prepareQuery.setObject(3, table.toUpperCase());
+ prepareQuery.setObject(4, unique?null:"NonUnique"); //$NON-NLS-1$
+
+
+ // make a query against runtimemetadata and get results
+ results = (ResultSetImpl) prepareQuery.executeQuery();
+
+ // build the list of records from server's Results object.
+ while (results.next ()) {
+ // list represents a record on the Results object.
+ List currentRow = new ArrayList (13);
+ // add values in the current record on the Results object to the list
+ // number of values to be fetched from each row is MAX_COLUMNS.
+ for(int i=0; i < JDBCColumnPositions.INDEX_INFO.MAX_COLUMNS; i++) {
+ // get the value at the current index add it to currentRow
+ currentRow.add(results.getObject(i+1));
+ }
+
+ // add the current row to the list of records.
+ records.add(currentRow);
+ }// end of while
+
+ // get the metadata for the results
+ rmetadata = results.getMetaData();
+
+ } catch (Exception e) {
+ throw TeiidSQLException.create(e,
JDBCPlugin.Util.getString("MMDatabaseMetadata.getIndex_error", table,
e.getMessage())); //$NON-NLS-1$
+ }
+
+
logger.fine(JDBCPlugin.Util.getString("MMDatabaseMetadata.getIndex_success",
table)); //$NON-NLS-1$
+
+ // construct results object from column values and their metadata
+ return createResultSet(records, rmetadata);
+ }
+
+ /**
+ * <p>Gets the maximum number of hexadecimal characters allowed in an inline
+ * binary literal
+ * @return int value giving maximum length of a binary literal
+ * @throws SQLException, should never occur
+ */
+ public int getMaxBinaryLiteralLength() throws SQLException {
+ return NO_LIMIT;
+ }
+
+ /**
+ * <p>Gets the maximum number of characters allowed in a catalog name
+ * @return int value giving maximum length of a catalog name
+ * @throws SQLException, should never occur
+ */
+ public int getMaxCatalogNameLength() throws SQLException {
+ return MAX_CATALOG_NAME_LENGTH;
+ }
+
+ /**
+ * <p>Gets the maximum number of characters allowed in a character literal
+ * @return int value giving maximum length of a charachter literal
+ * @throws SQLException, should never occur
+ */
+ public int getMaxCharLiteralLength() throws SQLException {
+ return NO_LIMIT;
+ }
+
+ /**
+ * <p>Gets the maximum number of characters allowed in a column name
+ * @return int value giving maximum length of the column name
+ * @throws SQLException, should never occur
+ */
+ public int getMaxColumnNameLength() throws SQLException {
+ return MAX_COLUMN_NAME_LENGTH;
+ }
+
+ /**
+ * <p>Gets the maximum number of columns allowed in a GROUP BY clause
+ * @return int values giving max columns in GROUP BY
+ * @throws SQLException, should never occur
+ */
+ public int getMaxColumnsInGroupBy() throws SQLException {
+ return NO_LIMIT;
+ }
+
+ /**
+ * <p>Gets the maximum number of columns allowed in an index
+ * @return int gives maximum columns in an index.
+ * @throws SQLException, should never occur
+ */
+ public int getMaxColumnsInIndex() throws SQLException {
+ return NO_LIMIT;
+ }
+
+ /**
+ * <p>Gets the maximum number of columns allowed in a ORDER BY clause
+ * @return int gives maximum columns in an order by.
+ * @throws SQLException, should never occur
+ */
+ public int getMaxColumnsInOrderBy() throws SQLException {
+ return NO_LIMIT;
+ }
+
+ /**
+ * <p>Gets the maximum number of columns allowed in a SELECT clause
+ * @return int gives maximum columns in a select.
+ * @throws SQLException, should never occur
+ */
+ public int getMaxColumnsInSelect() throws SQLException {
+ return NO_LIMIT;
+ }
+
+ /**
+ * <p>Gets the maximum number of columns allowed in a table
+ * @return int gives maximum columns in a table.
+ * @throws SQLException, should never occur
+ */
+ public int getMaxColumnsInTable() throws SQLException {
+ return NO_LIMIT;
+ }
+
+ /**
+ * <p>Gets the maximum number of active connections to metamatrix that can be
+ * maintained through this driver instance
+ * @return int gives maximum connections.
+ * @throws SQLException, should never occur
+ */
+ public int getMaxConnections() throws SQLException {
+ return NO_LIMIT;
+ }
+
+ /**
+ * <p>Gets the maximum number of characters allowed in a cursor name
+ * @return int gives maximum max charachters allowed in a cursor name.
+ * @throws SQLException, should never occur
+ */
+ public int getMaxCursorNameLength() throws SQLException {
+ return NO_LIMIT;
+ }
+
+ /**
+ * <p>Gets the maximum number of bytes allowed in an index
+ * @return int gives maximum bytes.
+ * @throws SQLException, should never occur
+ */
+ public int getMaxIndexLength() throws SQLException {
+ return NO_LIMIT;
+ }
+
+ /**
+ * <p>Gets the maximum number of characters allowed in a procedure name
+ * @return int gives maximum length of procedure name.
+ * @throws SQLException, should never occur
+ */
+ public int getMaxProcedureNameLength() throws SQLException {
+ return MAX_PROCEDURE_NAME_LENGTH;
+ }
+
+ /**
+ * <p>Gets the maximum number of bytes allowed in a single row
+ * @return int max row size in the result set.
+ * @throws SQLException, should never occur
+ */
+ public int getMaxRowSize() throws SQLException {
+ return NO_LIMIT;
+ }
+
+ /**
+ * <p>Gets the maximum number of characters allowed in a schema name
+ * @return int maximum length of a schema.
+ * @throws SQLException, should never occur
+ */
+ public int getMaxSchemaNameLength() throws SQLException {
+ return NO_LIMIT;
+ }
+
+ /**
+ * <p>Gets the maximum number of characters allowed in an SQL statement
+ * @return maximum length of a statement
+ * @throws SQLException, should never occur
+ */
+ public int getMaxStatementLength() throws SQLException {
+ return NO_LIMIT;
+ }
+
+ /**
+ * <p>Gets the maximum number of active statements that may be open on one
+ * connection at any time
+ * @return max number of open statements on a connection.
+ * @throws SQLException, should never occur
+ */
+ public int getMaxStatements() throws SQLException {
+ return NO_LIMIT;
+ }
+
+ /**
+ * <p>Gets the maximum number of characters allowed in a table name
+ * @return max length of table name.
+ * @throws SQLException, should never occur
+ */
+ public int getMaxTableNameLength() throws SQLException {
+ return MAX_TABLE_NAME_LENGTH;
+ }
+
+ /**
+ * <p>Gets the maximum number of tables allowed in a SELECT clause
+ * @return max tables in a select.
+ * @throws SQLException, should never occur
+ */
+ public int getMaxTablesInSelect() throws SQLException {
+ return NO_LIMIT;
+ }
+
+ /**
+ * <p>Gets the maximum number of characters allowed in a user name
+ * @return max length of user name.
+ * @throws SQLException, should never occur
+ */
+ public int getMaxUserNameLength() throws SQLException {
+ return MAX_USER_NAME_LENGTH;
+ }
+
+ /**
+ * <p>Gets the OPEN GROUP CLI names of metamatrix math functions
+ * @return string giving numeric functions supported.
+ * @throws SQLException, should never occur
+ */
+ public String getNumericFunctions() throws SQLException {
+ return NUMERIC_FUNCTIONS;
+ }
+
+ /**
+ * <p>Get's a description of the primary key columns in a table. The
descriptions
+ * are ordered by column name. Catalog and schema names are not used to narrow
+ * down the search, but they should match the virtualdatabasename and version
+ * used to obtain this driver connection.
+ * @param name of the catalog which contains the given table.
+ * @param schema name which contains the given table.
+ * @param table name which contains the primary keys.
+ * @return ResultSet object containing primary keys of the given table.
+ * @throws SQLException if there is an error obtaining metamatrix results.
+ */
+ public ResultSet getPrimaryKeys(String catalog, String schema, String table) throws
SQLException {
+ if (catalog == null) {
+ catalog = PERCENT;
+ }
+
+ if (schema == null) {
+ schema = PERCENT;
+ }
+
+ if (table == null) {
+ table = PERCENT;
+ }
+
+ // list which represent records containing primary key info
+ List records = new ArrayList ();
+ ResultSetMetaData rmetadata = null;
+ ResultSetImpl results = null;
+ PreparedStatement prepareQuery = null;
+ try {
+ prepareQuery = driverConnection.prepareStatement(QUERY_PRIMARY_KEYS);
+
+ prepareQuery.setObject(1, catalog.toUpperCase());
+ prepareQuery.setObject(2, schema.toUpperCase());
+ prepareQuery.setObject(3, table.toUpperCase());
+
+ // make a query against runtimemetadata and get results
+ results = (ResultSetImpl) prepareQuery.executeQuery();
+
+ // build the list of records from server's Results object.
+ while (results.next ()) {
+ // list represents a record on the Results object.
+ List currentRow = new ArrayList (7);
+ // add values in the current record on the Results object to the list
+ // number of values to be fetched from each row is MAX_COLUMNS.
+ for(int i=0; i < JDBCColumnPositions.PRIMARY_KEYS.MAX_COLUMNS; i++) {
+ // get the value at the current index add it to currentRow
+ currentRow.add(results.getObject(i+1));
+ }
+
+ // add the current row to the list of records.
+ records.add(currentRow);
+ }// end of while
+
+ // get the metadata for the results
+ rmetadata = results.getMetaData();
+
+ } catch (Exception e) {
+ throw TeiidSQLException.create(e,
JDBCPlugin.Util.getString("MMDatabaseMetadata.getPrimaryKey_error", table,
e.getMessage())); //$NON-NLS-1$
+ }
+
+
logger.fine(JDBCPlugin.Util.getString("MMDatabaseMetadata.getPrimaryKey_success"));
//$NON-NLS-1$
+
+ // construct results object from column values and their metadata
+ return createResultSet(records, rmetadata);
+ }
+
+ /**
+ * <p>Gets a description of the input, output and results associated with
certain
+ * stored procedures matching the given procedureNamePattern. Catalog and
+ * schema names are not used to narrow down the search, but they should match
+ * the virtualdatabasename and version used to obtain this driver
connection.</p>
+ * @param name of the catalog the procedure is present in.
+ * @param pattern of schama name the procedure is present in.
+ * @param pattern which is to be matched by the procedureNames.
+ * @param pattern to be matched by the column names.
+ * @return ResultSet containing the metadata info for procedure parameters.
+ * @throws SQLException if there is an error obtaining metamatrix results.
+ */
+ public ResultSet getProcedureColumns(String catalog, String schemaPattern, String
procedureNamePattern, String columnNamePattern) throws SQLException {
+ if (catalog == null) {
+ catalog = PERCENT;
+ }
+ if (schemaPattern == null) {
+ schemaPattern = PERCENT;
+ }
+
+ // Get all columns in all procedures if procedureNamePattern is null
+ if(procedureNamePattern == null) {
+ procedureNamePattern = PERCENT;
+ }
+ // Get all columns if columnNamePattern is null
+ if(columnNamePattern == null) {
+ columnNamePattern = PERCENT;
+ }
+
+ // list which represent records containing procedure column info
+ List records = new ArrayList ();
+
+ ResultSetMetaData rmetadata = null;
+ ResultSetImpl results = null;
+ PreparedStatement prepareQuery = null;
+ try {
+ prepareQuery = driverConnection.prepareStatement(QUERY_PROCEDURE_COLUMNS);
+ prepareQuery.setObject(1, catalog.toUpperCase());
+ prepareQuery.setObject(2, schemaPattern.toUpperCase());
+ prepareQuery.setObject(3, procedureNamePattern.toUpperCase());
+ prepareQuery.setObject(4, columnNamePattern.toUpperCase());
+
+ // make a query against runtimemetadata and get results
+ results = (ResultSetImpl) prepareQuery.executeQuery();
+ // build the list of records from server's Results object.
+ while (results.next ()) {
+ // list represents a record on the Results object.
+ List currentRow = new ArrayList (13);
+ // add values in the current record on the Results object to the list
+ // number of values to be fetched from each row is MAX_COLUMNS.
+ for(int i=0; i < JDBCColumnPositions.PROCEDURE_COLUMNS.MAX_COLUMNS;
i++) {
+ // get the value at the current index add it to currentRow
+ currentRow.add(results.getObject(i+1));
+ }
+
+ // add the current row to the list of records.
+ records.add(currentRow);
+ }// end of while
+ rmetadata = results.getMetaData();
+
+ } catch (Exception e) {
+ throw TeiidSQLException.create(e,
JDBCPlugin.Util.getString("MMDatabaseMetadata.getProcCol_error",
columnNamePattern, e.getMessage())); //$NON-NLS-1$
+ }
+
+
logger.fine(JDBCPlugin.Util.getString("MMDatabaseMetadata.getProcCol_success",
columnNamePattern, procedureNamePattern)); //$NON-NLS-1$
+
+ // construct results object from column values and their metadata
+ return createResultSet(records, rmetadata);
+ }
+
+ /**
+ * <p>Gets description of all the available stored procedures whose names
match
+ * the given pattern. Catalog and schemaPattern are not used to narrow down
+ * the search, but they should match the virtualdatabasename and version used
+ * to obtain this driver connection.
+ * @param name of the catalog.
+ * @param name of the schema.
+ * @param pattern which is to be matched by the procedureNames.
+ * @return ResultSet object which gives the metadata information about procedures.
+ * @throws SQLException if there is an error obtaining metamatrix results.
+ */
+ public ResultSet getProcedures(String catalog, String schemaPattern, String
procedureNamePattern) throws SQLException {
+ if (catalog == null) {
+ catalog = PERCENT;
+ }
+
+ if (schemaPattern == null) {
+ schemaPattern = PERCENT;
+ }
+
+ // Get all procedures if procedureNamePattern is null
+ if(procedureNamePattern == null) {
+ procedureNamePattern = PERCENT;
+ }
+
+ // list which represent records containing procedure info
+ List records = new ArrayList ();
+ ResultSetMetaData rmetadata = null;
+ ResultSetImpl results = null;
+ PreparedStatement prepareQuery = null;
+
+ try {
+ prepareQuery = driverConnection.prepareStatement(QUERY_PROCEDURES);
+ prepareQuery.setObject(1, catalog.toUpperCase());
+ prepareQuery.setObject(2, schemaPattern.toUpperCase());
+ prepareQuery.setObject(3, procedureNamePattern.toUpperCase());
+
+ // make a query against runtimemetadata and get results
+ results = (ResultSetImpl) prepareQuery.executeQuery();
+
+ // build the list of records from server's Results object.
+ while (results.next ()) {
+ // list represents a record on the Results object.
+ List currentRow = new ArrayList
(JDBCColumnPositions.PROCEDURES.MAX_COLUMNS);
+ // add values in the current record on the Results object to the list
+ // number of values to be fetched from each row is MAX_COLUMNS.
+ // there are 3 columns are reserved for future use
+ for(int i=0; i < JDBCColumnPositions.PROCEDURES.MAX_COLUMNS; i++) {
+ // get the value at the current index add it to currentRow
+ currentRow.add(results.getObject(i+1));
+ }
+
+ // add the current row to the list of records.
+ records.add(currentRow);
+
+ }// end of while
+ // get the metadata for the results
+ rmetadata = results.getMetaData();
+
+ } catch (Exception e) {
+ throw TeiidSQLException.create(e,
JDBCPlugin.Util.getString("MMDatabaseMetadata.getProc_error",
procedureNamePattern, e.getMessage())); //$NON-NLS-1$
+ }
+
+
logger.fine(JDBCPlugin.Util.getString("MMDatabaseMetadata.getProc_success",
procedureNamePattern)); //$NON-NLS-1$
+
+ // construct results object from column values and their metadata
+ return createResultSet(records, rmetadata);
+ }
+
+ /**
+ * <p>Gets MetaMatrix's preferred term for procedures
+ * @return String representing metamatrix procedure term.
+ * @throws SQLException, should never occur
+ */
+ public String getProcedureTerm() throws SQLException {
+ return PROCEDURE_TERM;
+ }
+
+ /**
+ * <p>Gets the schema names available for this connection. The results are
ordered
+ * by schema name. Schema information retreived only for the schema to which
+ * used in obtaining this driver connection.
+ * @return ResultsSet object containing schema and catalog names.
+ * @throws SQLException if there is an error obtaining metamatrix results.
+ */
+ public ResultSet getSchemas() throws SQLException {
+ return getSchemas(null, null);
+ }
+
+ /**
+ * <p>Gets MetaMatrix's preferred term for schema
+ * @return String object giving schema term
+ * @throws SQLException, should never occur
+ */
+ public String getSchemaTerm() throws SQLException {
+ return SCHEMA_TERM;
+ }
+
+ /**
+ * <p>Gets the string that can be used to escape "_" or "%"
wildcards in the
+ * string search pattern used for search parameters
+ * @return String that is used for escaping wildcards
+ * @throws SQLException, should never occur
+ */
+ public String getSearchStringEscape() throws SQLException {
+ return ESCAPE_SEARCH_STRING;
+ }
+
+ /**
+ * <p>Get metamatrix keywords that are not SQL-92 keyword
+ * @return String object giving non SQL-92 keywords
+ * @throws SQLException, should never occur
+ */
+ public String getSQLKeywords() throws SQLException {
+ return KEY_WORDS;
+ }
+
+ /**
+ * Indicates whether the SQLSTATE returned by SQLException.getSQLState is X/Open
+ * (now known as Open Group) SQL CLI or SQL99.
+ * @return intValue, the type of SQLSTATE; one of: sqlStateXOpen or sqlStateSQL99
+ */
+ public int getSQLStateType() throws SQLException {
+ //return sqlStateSQL99;
+ return 2;
+ }
+
+ /**
+ * <p>Gets the Open Group CLI names for metamatrix string functions
+ * @return String containing string function names
+ * @throws SQLException, should never occur
+ */
+ public String getStringFunctions() throws SQLException {
+ return STRING_FUNCTIONS;
+ }
+
+ /**
+ * Retrieves a description of the table hierarchies defined in a
+ * particular schema in this database.
+ * @param catalog A catalog name; "" retrieves those without a catalog;
+ * null means drop catalog name from the selection criteria.
+ * @param schemaPattern A schema name pattern; "" retrieves those without a
schema.
+ * @param tableNamePattern A table name pattern; may be a fully-qualified name.
+ * @throws SQLException since not supported
+ */
+ public ResultSet getSuperTables(String catalog, String schemaPattern,
+ String tableNamePattern) throws SQLException {
+ List records = new ArrayList (0);
+
+ /***********************************************************************
+ * Hardcoding JDBC column names for the columns returned in results object
+ ***********************************************************************/
+ Map[] metadataList = new Map[4];
+
+ // HardCoding metadata details for TABLE_CAT column
+ metadataList[0] = getColumnMetadata(null,
JDBCColumnNames.SUPER_TABLES.TABLE_CAT,
+ MMJDBCSQLTypeInfo.STRING,
ResultsMetadataConstants.NULL_TYPES.NULLABLE);
+
+ // HardCoding metadata details for TABLE_SCHEM column
+ metadataList[1] = getColumnMetadata(null,
JDBCColumnNames.SUPER_TABLES.TABLE_SCHEM,
+ MMJDBCSQLTypeInfo.STRING,
ResultsMetadataConstants.NULL_TYPES.NULLABLE);
+
+ // HardCoding metadata details for TABLE_NAME column
+ metadataList[2] = getColumnMetadata(null,
JDBCColumnNames.SUPER_TABLES.TABLE_NAME,
+ MMJDBCSQLTypeInfo.STRING,
ResultsMetadataConstants.NULL_TYPES.NOT_NULL);
+
+ // HardCoding metadata details for SUPERTABLE_NAME column
+ metadataList[3] = getColumnMetadata(null,
JDBCColumnNames.SUPER_TABLES.SUPERTABLE_NAME,
+ MMJDBCSQLTypeInfo.STRING,
ResultsMetadataConstants.NULL_TYPES.NOT_NULL);
+
+ // construct results object from column values and their metadata
+ return createResultSet(records, metadataList);
+
+ }
+
+ /**
+ * Retrieves a description of the user-defined type (UDT) hierarchies
+ * defined in a particular schema in this database.
+ * @param catalog A catalog name; "" retrieves those without a catalog;
+ * null means drop catalog name from the selection criteria.
+ * @param schemaPattern A schema name pattern; "" retrieves those without a
schema.
+ * @param tableNamePattern A table name pattern; may be a fully-qualified name.
+ */
+ public ResultSet getSuperTypes(String catalog, String schemaPattern,
+ String tableNamePattern) throws SQLException {
+ List records = new ArrayList (0);
+
+ /***********************************************************************
+ * Hardcoding JDBC column names for the columns returned in results object
+ ***********************************************************************/
+ Map[] metadataList = new Map[6];
+
+ // HardCoding metadata details for TYPE_CAT column
+ metadataList[0] = getColumnMetadata(null, JDBCColumnNames.SUPER_TYPES.TYPE_CAT,
+ MMJDBCSQLTypeInfo.STRING,
ResultsMetadataConstants.NULL_TYPES.NULLABLE);
+
+ // HardCoding metadata details for TYPE_SCHEM column
+ metadataList[1] = getColumnMetadata(null,
JDBCColumnNames.SUPER_TYPES.TYPE_SCHEM,
+ MMJDBCSQLTypeInfo.STRING,
ResultsMetadataConstants.NULL_TYPES.NULLABLE);
+
+ // HardCoding metadata details for TYPE_NAME column
+ metadataList[2] = getColumnMetadata(null, JDBCColumnNames.SUPER_TYPES.TYPE_NAME,
+ MMJDBCSQLTypeInfo.STRING,
ResultsMetadataConstants.NULL_TYPES.NOT_NULL);
+
+ // HardCoding metadata details for SUPERTYPE_CAT column
+ metadataList[3] = getColumnMetadata(null,
JDBCColumnNames.SUPER_TYPES.SUPERTYPE_CAT,
+ MMJDBCSQLTypeInfo.STRING,
ResultsMetadataConstants.NULL_TYPES.NULLABLE);
+
+ // HardCoding metadata details for SUPERTYPE_SCHEM column
+ metadataList[4] = getColumnMetadata(null,
JDBCColumnNames.SUPER_TYPES.SUPERTYPE_SCHEM,
+ MMJDBCSQLTypeInfo.STRING,
ResultsMetadataConstants.NULL_TYPES.NULLABLE);
+
+ // HardCoding metadata details for SUPERTYPE_NAME column
+ metadataList[5] = getColumnMetadata(null,
JDBCColumnNames.SUPER_TYPES.SUPERTYPE_NAME,
+ MMJDBCSQLTypeInfo.STRING,
ResultsMetadataConstants.NULL_TYPES.NOT_NULL);
+
+ // construct results object from column values and their metadata
+ return createResultSet(records, metadataList);
+ }
+
+ /**
+ * <p>Gets the Open Group CLI names for metamatrix system functions
+ * @return String containing system function names
+ * @throws SQLException, should never occur
+ */
+ public String getSystemFunctions() throws SQLException {
+ return SYSTEM_FUNCTIONS; // there are no system functions
+ }
+
+ /**
+ * <p>Gets a description of access rights for the table of the given name.
+ * <p>Catalog and schemaPattern are not used to narrow down the search, but
they
+ * should match the virtualdatabasename and version used to obtain this driver
+ * connection.
+ * @param name of the catalog the table is present in.
+ * @param pattern of schama name the table is present in.
+ * @param pattern of table names whose privilage info is needed.
+ * @return ResultSet containing table privilages info.
+ * @throws SQLException if there is an error obtaining metamatrix results.
+ */
+ public ResultSet getTablePrivileges(String catalog, String schemaPattern, String
tableName) throws SQLException {
+ List records = new ArrayList (0);
+ /***********************************************************************
+ * Hardcoding JDBC column names for the columns returned in results object
+ ***********************************************************************/
+ Map[] metadataList = new Map[7];
+
+ metadataList[0] = getColumnMetadata(null, JDBCColumnNames.PRIVILEGES.TABLE_CAT,
+ MMJDBCSQLTypeInfo.STRING,
ResultsMetadataConstants.NULL_TYPES.NULLABLE);
+ metadataList[1] = getColumnMetadata(null,
JDBCColumnNames.PRIVILEGES.TABLE_SCHEM,
+ MMJDBCSQLTypeInfo.STRING,
ResultsMetadataConstants.NULL_TYPES.NULLABLE);
+ metadataList[2] = getColumnMetadata(null, JDBCColumnNames.PRIVILEGES.TABLE_NAME,
+ MMJDBCSQLTypeInfo.STRING,
ResultsMetadataConstants.NULL_TYPES.NOT_NULL);
+ metadataList[3] = getColumnMetadata(null, JDBCColumnNames.PRIVILEGES.GRANTOR,
+ MMJDBCSQLTypeInfo.STRING,
ResultsMetadataConstants.NULL_TYPES.NULLABLE);
+ metadataList[4] = getColumnMetadata(null, JDBCColumnNames.PRIVILEGES.GRANTEE,
+ MMJDBCSQLTypeInfo.STRING,
ResultsMetadataConstants.NULL_TYPES.NOT_NULL);
+ metadataList[5] = getColumnMetadata(null, JDBCColumnNames.PRIVILEGES.PRIVILEGE,
+ MMJDBCSQLTypeInfo.STRING,
ResultsMetadataConstants.NULL_TYPES.NOT_NULL);
+ metadataList[6] = getColumnMetadata(null,
JDBCColumnNames.PRIVILEGES.IS_GRANTABLE,
+ MMJDBCSQLTypeInfo.STRING,
ResultsMetadataConstants.NULL_TYPES.NULLABLE);
+
+ return createResultSet(records, metadataList);
+
+ }
+
+ /**
+ * <p>Gets a description of tables whose table name matches tableNamePattern.
+ * <p>Catalog, schemaPattern and types[] are not used to narrow down the
search,
+ * but catalog and schemaPattern should match the virtualdatabasename and
+ * version respectively used to obtain this driver connection.
+ * Note:
+ * supports 1.4 API
+ * @param name of the catalog in which tables are present.
+ * @param pattern of schema names which in which the tables are present.
+ * @param pattern of tables names.
+ * @param list of possible table types.
+ * @return ResultSet containing Table metadata information.
+ * @throws SQLException if there is an error obtaining metamatrix results.
+ */
+ public ResultSet getTables(String catalog, String schemaPattern, String
tableNamePattern, String types[]) throws SQLException {
+ if (catalog == null) {
+ catalog = PERCENT;
+ }
+
+ if (schemaPattern == null) {
+ schemaPattern = PERCENT;
+ }
+
+ // Get all tables if tableNamePattern is null
+ if(tableNamePattern == null) {
+ tableNamePattern = PERCENT;
+ }
+
+ // list which represent records containing tables info
+ List records = new ArrayList ();
+
+ // query string to be submitted to get table metadata info
+ StringBuffer sqlQuery = new StringBuffer(QUERY_TABLES);
+
+ StringBuffer typesString = new StringBuffer("("); // criteria string
for different table types //$NON-NLS-1$
+
+ if (types != null) {
+ // construct the criteria string
+ for(int i=0; i < types.length; i++) {
+ if (types[i] != null && types[i].length() > 0) {
+ if (i > 0) {
+ typesString.append(" OR "); //$NON-NLS-1$
+ }
+ typesString.append(TABLE_TYPE).append(LIKE_ESCAPE);
+ }
+ }
+ typesString.append(")"); //$NON-NLS-1$
+ sqlQuery.append(" AND ").append(typesString.toString());
//$NON-NLS-1$
+ }
+
+ sqlQuery.append(" ORDER BY TABLE_TYPE, TABLE_SCHEM, TABLE_NAME");
//$NON-NLS-1$
+
+
+ ResultSetMetaData rmetadata = null;
+ ResultSetImpl results = null;
+ PreparedStatement prepareQuery = null;
+
+ try {
+ prepareQuery = driverConnection.prepareStatement(sqlQuery.toString());
+ int columnIndex = 0;
+ prepareQuery.setObject(++columnIndex, catalog.toUpperCase());
+ prepareQuery.setObject(++columnIndex, schemaPattern.toUpperCase());
+ prepareQuery.setObject(++columnIndex, tableNamePattern.toUpperCase());
+
+ if(types != null) {
+ for(int i=0; i < types.length; i++) {
+ if (types[i] != null && types[i].length() > 0) {
+ prepareQuery.setObject(++columnIndex, types[i].toUpperCase());
+ }
+ }
+ }
+
+ // make a query against runtimemetadata and get results
+ results = (ResultSetImpl) prepareQuery.executeQuery();
+
+ // build the list of records from server's Results object.
+ while (results.next ()) {
+ // list represents a record on the Results object.
+ List currentRow = new ArrayList (11);
+ // add values in the current record on the Results object to the list
+ // number of values to be fetched from each row is MAX_COLUMNS.
+ for(int i=0; i < JDBCColumnPositions.TABLES.MAX_COLUMNS; i++) {
+ // get the value at the current index add it to currentRow
+ currentRow.add(results.getObject(i+1));
+ }
+
+ // add the current row to the list of records.
+ records.add(currentRow);
+ }// end of while
+
+ // get the metadata for the results
+ rmetadata = results.getMetaData();
+ } catch (SQLException e) {
+ throw e;
+ } catch (Exception e) {
+ throw TeiidSQLException.create(e,
JDBCPlugin.Util.getString("MMDatabaseMetadata.getTable_error", tableNamePattern,
e.getMessage())); //$NON-NLS-1$
+ }
+
+ // close the results (need to close case results exceed cursor size)
+ //results.close();
+
+ // close the PreparedStatement, too. Because of the way of closing request in
current framework,
+ // manually send out a close request is very necessary for PreparedStatement.
+ //prepareQuery.close();
+
+
logger.fine(JDBCPlugin.Util.getString("MMDatabaseMetadata.getTable_success",
tableNamePattern)); //$NON-NLS-1$
+
+ // construct results object from column values and their metadata
+ return createResultSet(records, rmetadata);
+ }
+
+ /**
+ * <p>Gets the table types available to metamatrix. The results are ordered by
+ * table type
+ * @return ResultSet object containing hardcoded table type info.
+ * @throws SQLException, should never occur.
+ */
+ public ResultSet getTableTypes() throws SQLException {
+
+ // list which represent records containing Table Type info
+ List records = new ArrayList (5);
+ /********************************
+ * HardCoding JDBC specific values
+ *********************************/
+
+ records.add(Arrays.asList(new String[] {"DOCUMENT"})); //$NON-NLS-1$
+ records.add(Arrays.asList(new String[] {"TABLE"})); //$NON-NLS-1$
+ records.add(Arrays.asList(new String[] {"VIEW"})); //$NON-NLS-1$
+ records.add(Arrays.asList(new String[] {"XMLSTAGINGTABLE"}));
//$NON-NLS-1$
+ records.add(Arrays.asList(new String[] {"SYSTEM TABLE"}));
//$NON-NLS-1$
+
+ /***********************************************************************
+ * Hardcoding JDBC column names for the columns returned in results object
+ ***********************************************************************/
+
+ Map[] metadataList = new Map[1];
+
+ metadataList[0] = getColumnMetadata(null, JDBCColumnNames.TABLE_TYPES.TABLE_TYPE,
+ MMJDBCSQLTypeInfo.STRING,
ResultsMetadataConstants.NULL_TYPES.NOT_NULL);
+
+
logger.fine(JDBCPlugin.Util.getString("MMDatabaseMetadata.getTableType_success"));
//$NON-NLS-1$
+
+ // construct results object from column values and their metadata
+ return createResultSet(records, metadataList);
+ }
+
+ /**
+ * <p>Gets the Open Group CLI names for metamatrix time and date functions
+ * @return String representing time and date functions in MetaMatrix
+ * @throws SQLException, should never occur
+ */
+ public String getTimeDateFunctions() throws SQLException {
+ return DATE_FUNCTIONS;
+ }
+
+ /**
+ * <p>Gets the description of all datatypes supported by metamatrix.
+ * @return ResultSet object containing info about the datatypes supported by
MetaMatrix.
+ * @throws SQLException if there is an error obtaining metamatrix results.
+ */
+ public ResultSet getTypeInfo() throws SQLException {
+
+ // list which represent records containing data type info
+ List records = new ArrayList ();
+
+ records.add(Arrays.asList(createTypeInfoRow("boolean",
"{b'", "}", Boolean.TRUE, Boolean.TRUE, 0))); //$NON-NLS-1$
//$NON-NLS-2$ //$NON-NLS-3$
+ records.add(Arrays.asList(createTypeInfoRow("byte", null, null,
Boolean.TRUE, Boolean.TRUE, 0))); //$NON-NLS-1$
+ records.add(Arrays.asList(createTypeInfoRow("long", null, null,
Boolean.FALSE, Boolean.FALSE, 10))); //$NON-NLS-1$
+ records.add(Arrays.asList(createTypeInfoRow("char", "'",
"'", Boolean.TRUE, Boolean.TRUE, 0))); //$NON-NLS-1$ //$NON-NLS-2$
//$NON-NLS-3$
+ records.add(Arrays.asList(createTypeInfoRow("bigdecimal",null, null,
Boolean.FALSE, Boolean.TRUE, 10))); //$NON-NLS-1$
+ records.add(Arrays.asList(createTypeInfoRow("biginteger", null, null,
Boolean.FALSE, Boolean.FALSE, 10))); //$NON-NLS-1$
+ records.add(Arrays.asList(createTypeInfoRow("integer", null, null,
Boolean.FALSE, Boolean.FALSE, 10))); //$NON-NLS-1$
+ records.add(Arrays.asList(createTypeInfoRow("short", null, null,
Boolean.FALSE, Boolean.FALSE, 10))); //$NON-NLS-1$
+ records.add(Arrays.asList(createTypeInfoRow("float", null, null,
Boolean.FALSE, Boolean.FALSE, 10))); //$NON-NLS-1$
+ records.add(Arrays.asList(createTypeInfoRow("double", null, null,
Boolean.FALSE, Boolean.FALSE, 10))); //$NON-NLS-1$
+ records.add(Arrays.asList(createTypeInfoRow("string",
"'", "'", Boolean.TRUE, Boolean.TRUE, 0))); //$NON-NLS-1$
//$NON-NLS-2$//$NON-NLS-3$
+ records.add(Arrays.asList(createTypeInfoRow("xml", null, null,
Boolean.TRUE, Boolean.TRUE, 0))); //$NON-NLS-1$
+ records.add(Arrays.asList(createTypeInfoRow("date",
"{d'", "}", Boolean.TRUE, Boolean.TRUE, 0))); //$NON-NLS-1$
//$NON-NLS-2$//$NON-NLS-3$
+ records.add(Arrays.asList(createTypeInfoRow("time",
"{t'", "}", Boolean.TRUE, Boolean.TRUE, 0))); //$NON-NLS-1$
//$NON-NLS-2$//$NON-NLS-3$
+ records.add(Arrays.asList(createTypeInfoRow("timestamp",
"{ts'", "}", Boolean.TRUE, Boolean.TRUE, 0))); //$NON-NLS-1$
//$NON-NLS-2$//$NON-NLS-3$
+ records.add(Arrays.asList(createTypeInfoRow("object", null, null,
Boolean.TRUE, Boolean.TRUE, 0))); //$NON-NLS-1$
+ records.add(Arrays.asList(createTypeInfoRow("blob", null, null,
Boolean.TRUE, Boolean.TRUE, 0))); //$NON-NLS-1$
+ records.add(Arrays.asList(createTypeInfoRow("clob", null, null,
Boolean.TRUE, Boolean.TRUE, 0))); //$NON-NLS-1$
+
+ Map[] metadataList = new Map[18];
+
+ metadataList[0] = getColumnMetadata(CoreConstants.SYSTEM_MODEL + "." +
DATA_TYPES, JDBCColumnNames.TYPE_INFO.TYPE_NAME, MMJDBCSQLTypeInfo.STRING,
ResultsMetadataConstants.NULL_TYPES.NOT_NULL,
ResultsMetadataConstants.SEARCH_TYPES.SEARCHABLE, Boolean.FALSE, Boolean.FALSE,
Boolean.FALSE);//$NON-NLS-1$
+ metadataList[1] = getColumnMetadata(CoreConstants.SYSTEM_MODEL + "." +
DATA_TYPES, JDBCColumnNames.TYPE_INFO.DATA_TYPE, MMJDBCSQLTypeInfo.INTEGER,
ResultsMetadataConstants.NULL_TYPES.NULLABLE,
ResultsMetadataConstants.SEARCH_TYPES.SEARCHABLE, Boolean.TRUE, Boolean.TRUE,
Boolean.FALSE);//$NON-NLS-1$
+ metadataList[2] = getColumnMetadata(CoreConstants.SYSTEM_MODEL + "." +
DATA_TYPES, JDBCColumnNames.TYPE_INFO.PRECISION, MMJDBCSQLTypeInfo.INTEGER,
ResultsMetadataConstants.NULL_TYPES.NULLABLE,
ResultsMetadataConstants.SEARCH_TYPES.SEARCHABLE, Boolean.TRUE, Boolean.TRUE,
Boolean.FALSE);//$NON-NLS-1$
+ metadataList[3] = getColumnMetadata(CoreConstants.SYSTEM_MODEL + "." +
DATA_TYPES, JDBCColumnNames.TYPE_INFO.LITERAL_PREFIX, MMJDBCSQLTypeInfo.STRING,
ResultsMetadataConstants.NULL_TYPES.NULLABLE,
ResultsMetadataConstants.SEARCH_TYPES.SEARCHABLE, Boolean.TRUE, Boolean.TRUE,
Boolean.FALSE);//$NON-NLS-1$
+ metadataList[4] = getColumnMetadata(CoreConstants.SYSTEM_MODEL + "." +
DATA_TYPES, JDBCColumnNames.TYPE_INFO.LITERAL_SUFFIX, MMJDBCSQLTypeInfo.STRING,
ResultsMetadataConstants.NULL_TYPES.NULLABLE,
ResultsMetadataConstants.SEARCH_TYPES.SEARCHABLE, Boolean.TRUE, Boolean.TRUE,
Boolean.FALSE);//$NON-NLS-1$
+ metadataList[5] = getColumnMetadata(CoreConstants.SYSTEM_MODEL + "." +
DATA_TYPES, JDBCColumnNames.TYPE_INFO.CREATE_PARAMS, MMJDBCSQLTypeInfo.STRING,
ResultsMetadataConstants.NULL_TYPES.NULLABLE,
ResultsMetadataConstants.SEARCH_TYPES.SEARCHABLE, Boolean.TRUE, Boolean.TRUE,
Boolean.FALSE);//$NON-NLS-1$
+ metadataList[6] = getColumnMetadata(CoreConstants.SYSTEM_MODEL + "." +
DATA_TYPES, JDBCColumnNames.TYPE_INFO.NULLABLE, MMJDBCSQLTypeInfo.SHORT,
ResultsMetadataConstants.NULL_TYPES.NULLABLE,
ResultsMetadataConstants.SEARCH_TYPES.SEARCHABLE, Boolean.TRUE, Boolean.TRUE,
Boolean.FALSE);//$NON-NLS-1$
+ metadataList[7] = getColumnMetadata(CoreConstants.SYSTEM_MODEL + "." +
DATA_TYPES, JDBCColumnNames.TYPE_INFO.CASE_SENSITIVE, MMJDBCSQLTypeInfo.BOOLEAN,
ResultsMetadataConstants.NULL_TYPES.NOT_NULL,
ResultsMetadataConstants.SEARCH_TYPES.SEARCHABLE, Boolean.FALSE, Boolean.FALSE,
Boolean.TRUE);//$NON-NLS-1$
+ metadataList[8] = getColumnMetadata(CoreConstants.SYSTEM_MODEL + "." +
DATA_TYPES, JDBCColumnNames.TYPE_INFO.SEARCHABLE, MMJDBCSQLTypeInfo.SHORT,
ResultsMetadataConstants.NULL_TYPES.NULLABLE,
ResultsMetadataConstants.SEARCH_TYPES.SEARCHABLE, Boolean.TRUE, Boolean.TRUE,
Boolean.FALSE);//$NON-NLS-1$
+ metadataList[9] = getColumnMetadata(CoreConstants.SYSTEM_MODEL + "." +
DATA_TYPES, JDBCColumnNames.TYPE_INFO.UNSIGNED_ATTRIBUTE, MMJDBCSQLTypeInfo.BOOLEAN,
ResultsMetadataConstants.NULL_TYPES.NULLABLE,
ResultsMetadataConstants.SEARCH_TYPES.SEARCHABLE, Boolean.TRUE, Boolean.TRUE,
Boolean.FALSE);//$NON-NLS-1$
+ metadataList[10] = getColumnMetadata(CoreConstants.SYSTEM_MODEL + "." +
DATA_TYPES, JDBCColumnNames.TYPE_INFO.FIXED_PREC_SCALE, MMJDBCSQLTypeInfo.BOOLEAN,
ResultsMetadataConstants.NULL_TYPES.NULLABLE,
ResultsMetadataConstants.SEARCH_TYPES.SEARCHABLE, Boolean.TRUE, Boolean.TRUE,
Boolean.FALSE);//$NON-NLS-1$
+ metadataList[11] = getColumnMetadata(CoreConstants.SYSTEM_MODEL + "." +
DATA_TYPES, JDBCColumnNames.TYPE_INFO.AUTOINCREMENT, MMJDBCSQLTypeInfo.BOOLEAN,
ResultsMetadataConstants.NULL_TYPES.NOT_NULL,
ResultsMetadataConstants.SEARCH_TYPES.SEARCHABLE, Boolean.FALSE, Boolean.TRUE,
Boolean.TRUE);//$NON-NLS-1$
+ metadataList[12] = getColumnMetadata(CoreConstants.SYSTEM_MODEL + "." +
DATA_TYPES, JDBCColumnNames.TYPE_INFO.LOCAL_TYPE_NAME, MMJDBCSQLTypeInfo.STRING,
ResultsMetadataConstants.NULL_TYPES.NOT_NULL,
ResultsMetadataConstants.SEARCH_TYPES.SEARCHABLE, Boolean.FALSE, Boolean.FALSE,
Boolean.FALSE);//$NON-NLS-1$
+ metadataList[13] = getColumnMetadata(CoreConstants.SYSTEM_MODEL + "." +
DATA_TYPES, JDBCColumnNames.TYPE_INFO.MINIMUM_SCALE, MMJDBCSQLTypeInfo.SHORT,
ResultsMetadataConstants.NULL_TYPES.NULLABLE,
ResultsMetadataConstants.SEARCH_TYPES.SEARCHABLE, Boolean.TRUE, Boolean.TRUE,
Boolean.FALSE);//$NON-NLS-1$
+ metadataList[14] = getColumnMetadata(CoreConstants.SYSTEM_MODEL + "." +
DATA_TYPES, JDBCColumnNames.TYPE_INFO.MAXIMUM_SCALE, MMJDBCSQLTypeInfo.SHORT,
ResultsMetadataConstants.NULL_TYPES.NULLABLE,
ResultsMetadataConstants.SEARCH_TYPES.SEARCHABLE, Boolean.TRUE, Boolean.TRUE,
Boolean.FALSE);//$NON-NLS-1$
+ metadataList[15] = getColumnMetadata(CoreConstants.SYSTEM_MODEL + "." +
DATA_TYPES, JDBCColumnNames.TYPE_INFO.SQL_DATA_TYPE, MMJDBCSQLTypeInfo.INTEGER,
ResultsMetadataConstants.NULL_TYPES.NULLABLE,
ResultsMetadataConstants.SEARCH_TYPES.SEARCHABLE, Boolean.TRUE, Boolean.TRUE,
Boolean.FALSE);//$NON-NLS-1$
+ metadataList[16] = getColumnMetadata(CoreConstants.SYSTEM_MODEL + "." +
DATA_TYPES, JDBCColumnNames.TYPE_INFO.SQL_DATETIME_SUB, MMJDBCSQLTypeInfo.INTEGER,
ResultsMetadataConstants.NULL_TYPES.NULLABLE,
ResultsMetadataConstants.SEARCH_TYPES.SEARCHABLE, Boolean.TRUE, Boolean.TRUE,
Boolean.FALSE);//$NON-NLS-1$
+ metadataList[17] = getColumnMetadata(CoreConstants.SYSTEM_MODEL + "." +
DATA_TYPES, JDBCColumnNames.TYPE_INFO.NUM_PREC_RADIX, MMJDBCSQLTypeInfo.INTEGER,
ResultsMetadataConstants.NULL_TYPES.NULLABLE,
ResultsMetadataConstants.SEARCH_TYPES.SEARCHABLE, Boolean.FALSE, Boolean.FALSE,
Boolean.FALSE);//$NON-NLS-1$
+
+ ResultSetMetaData rmetadata = new ResultSetMetaDataImpl(new
MetadataProvider(metadataList));
+
+
logger.fine(JDBCPlugin.Util.getString("MMDatabaseMetadata.getTypes_success"));
//$NON-NLS-1$
+
+ // construct results object from column values and their metadata
+ return createResultSet(records, rmetadata);
+ }
+
+ private Object[] createTypeInfoRow(String typeName, String prefix, String suffix,
Boolean unsigned, Boolean fixedPrecScale, int radix){
+ return new Object[] {typeName, new
Integer(MMJDBCSQLTypeInfo.getSQLType(typeName)),
ResultsMetadataDefaults.getDefaultPrecision(typeName), prefix, suffix, null, new
Short((short)DatabaseMetaData.typeNullable), Boolean.FALSE, new
Short((short)DatabaseMetaData.typeSearchable), unsigned, fixedPrecScale, Boolean.FALSE,
typeName, new Short((short)0), new Short((short)255), null, null, new Integer(radix)};
+ }
+
+ /**
+ * <p>Gets a description of the user-defined types defined in a particular
+ * schema. Schema-specific UDTs may have type JAVA_OBJECT, STRUCT, or DISTINCT.
+ * Supports 1.4
+ * @param catalog a catalog name
+ * @param schemaPattern a schema name pattern
+ * @param typeNamePattern a type name pattern
+ * @param types a list of user-named types to include (JAVA_OBJECT, STRUCT,
+ * or DISTINCT); null returns all types
+ * @return ResultSet. Empty ResultSet object as this method is not supported.
+ * @throws SQLException if catalog/schema info does not match for the given
connection.
+ */
+ public ResultSet getUDTs(String catalog, String schemaPattern,
+ String typeNamePattern, int[] types) throws SQLException {
+ return emptyUDTSResultSet();
+ }
+
+ /**
+ * Return a empty result set for to aid getUDTS() functions.
+ * @return ResultSet.
+ */
+ private ResultSet emptyUDTSResultSet() throws SQLException {
+ String[] columnNames = new String[] {
+ JDBCColumnNames.UDTS.TYPE_CAT,
+ JDBCColumnNames.UDTS.TYPE_SCHEM,
+ JDBCColumnNames.UDTS.TYPE_NAME,
+ JDBCColumnNames.UDTS.CLASS_NAME,
+ JDBCColumnNames.UDTS.DATA_TYPE,
+ JDBCColumnNames.UDTS.REMARKS,
+ JDBCColumnNames.UDTS.BASE_TYPE
+ };
+ String[] dataTypes = new String[] {
+ MMJDBCSQLTypeInfo.STRING,
+ MMJDBCSQLTypeInfo.STRING,
+ MMJDBCSQLTypeInfo.STRING,
+ MMJDBCSQLTypeInfo.STRING,
+ MMJDBCSQLTypeInfo.STRING,
+ MMJDBCSQLTypeInfo.STRING,
+ MMJDBCSQLTypeInfo.SHORT
+ };
+ return createEmptyResultSet(columnNames, dataTypes);
+ }
+
+ /**
+ * <p>Gets the URL used to connect to metamatrix
+ * @return URL used to connect.
+ * @throws SQLException
+ */
+ public String getURL() throws SQLException {
+ return driverConnection.getUrl();
+ }
+
+ /**
+ * <p>Gets the user name as known to metamatrix
+ * @return name if the user.
+ */
+ public String getUserName() throws SQLException {
+ return driverConnection.getUserName();
+ }
+
+ /**
+ * <p>Gets the description of the columns in a table that are automatically
updated
+ * when any value in a row is updated. The column descriptions are not ordered.
+ * @param name of the catalog in which the table is present.
+ * @param name of the schema in which the table is present.
+ * @param name of the table which has the version columns.
+ * @return ResultSet object containing version column information.
+ * @throws SQLException, should never occur
+ */
+ public ResultSet getVersionColumns(String catalog, String schema, String table)
throws SQLException {
+
+ // ResultSet returned has the same columns as best row identifier
+ // Method not supported, retuning empty ResultSet
+ ResultSet resultSet = getBestRowIdentifier(catalog, schema, table, 0, true);
+
+
logger.fine(JDBCPlugin.Util.getString("MMDatabaseMetadata.getVersionCols_success"));
//$NON-NLS-1$
+
+ return resultSet;
+ }
+
+
+ /**
+ * <p>Checks whether a catalog name appears at the start of a fully qualified
table
+ * name. If it is not at the beginning, it appears at the end.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean isCatalogAtStart() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Indicates whether or not a visible row insert can be detected
+ * by calling ResultSet.rowInserted().</p>
+ * @param result set type, i.e. ResultSet.TYPE_XXX
+ * @return true if changes are detected by the resultset type
+ * @throws SQLException, should never occur
+ */
+ public boolean insertsAreDetected(int type) throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Checks whether the databases used by metamatrix are in read-only
mode</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean isReadOnly() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Indicates whether updates made to a LOB are made on a copy or directly to
the LOB. </p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean locatorsUpdateCopy() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Checks whether the concatenation of a NULL vaule and a non-NULL value
results
+ * in a NULL value.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean nullPlusNonNullIsNull() throws SQLException {
+ return true;
+ }
+
+ /**
+ * <p>Checks whether NULL vaules are sorted at the end regardless of sort
order.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean nullsAreSortedAtEnd() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Checks whether NULL vaules are sorted at the start regardless of sort
order.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean nullsAreSortedAtStart() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Checks whether NULL vaules are sorted high.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean nullsAreSortedHigh() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Checks whether NULL vaules are sorted low.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean nullsAreSortedLow() throws SQLException {
+ return true;
+ }
+
+ /**
+ * <p>Indicates whether a result set's own updates are visible.</p>
+ * @param result set type, i.e. ResultSet.TYPE_XXX
+ * @return <code>true</code> if updates are visible for the result set
type;
+ * <code>false</code> otherwise
+ * @throws SQLException, should never occur
+ */
+ public boolean ownUpdatesAreVisible(int type) throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Indicates whether a result set's own deletes are visible.</p>
+ * @param result set type, i.e. ResultSet.TYPE_XXX
+ * @return <code>true</code> if deletes are visible for the result set
type;
+ * <code>false</code> otherwise
+ * @throws SQLException, should never occur
+ */
+ public boolean ownDeletesAreVisible(int type) throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Indicates whether a result set's own inserts are visible.</p>
+ * @param result set type, i.e. ResultSet.TYPE_XXX
+ * @return <code>true</code> if inserts are visible for the result set
type;
+ * <code>false</code> otherwise
+ * @throws SQLException, should never occur
+ */
+ public boolean ownInsertsAreVisible(int type) throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Indicates whether updates made by others are visible.</p>
+ * @param result set type, i.e. ResultSet.TYPE_XXX
+ * @return <code>true</code> if updates made by others
+ * are visible for the result set type;
+ * <code>false</code> otherwise
+ * @throws SQLException, should never occur
+ */
+ public boolean othersUpdatesAreVisible(int type) throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Indicates whether deletes made by others are visible.</p>
+ * @param result set type, i.e. ResultSet.TYPE_XXX
+ * @return <code>true</code> if deletes made by others
+ * are visible for the result set type;
+ * <code>false</code> otherwise
+ * @throws SQLException, should never occur
+ */
+ public boolean othersDeletesAreVisible(int type) throws SQLException {
+ return false;
+ }
+ /**
+ * <p>Indicates whether inserts made by others are visible.</p>
+ * @param result set type, i.e. ResultSet.TYPE_XXX
+ * @return true if updates are visible for the result set type
<code>true</code>
+ * if inserts made by others are visible for the result set type;
+ * <code>false</code> otherwise
+ * @throws SQLException, should never occur
+ */
+ public boolean othersInsertsAreVisible(int type) throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>This method checks whether metamatrix treats mixed-case unquoted SQL
identifiers
+ * used in SQL statements as case-insensitive and stores them as all lowercase
+ * in its metadata tables.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean storesLowerCaseIdentifiers() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>This method checks whether metamatrix treats mixed-case quoted SQL
identifiers
+ * used in SQL statements as case-insensitive and stores them as all lowercase
+ * in its metadata tables.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean storesLowerCaseQuotedIdentifiers() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>This method checks whether metamatrix treats mixed-case unquoted SQL
identifiers
+ * used in SQL statements as case-insensitive and stores them as all mixedcase
+ * in its metadata tables.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean storesMixedCaseIdentifiers() throws SQLException {
+ return true;
+ }
+
+ /**
+ * <p>This method checks whether metamatrix treats mixed-case quoted SQL
identifiers
+ * used in SQL statements as case-insensitive and stores them in mixedcase
+ * in its metadata tables.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean storesMixedCaseQuotedIdentifiers() throws SQLException {
+ return true;
+ }
+
+ /**
+ * <p>This method checks whether metamatrix treats mixed-case unquoted SQL
identifiers
+ * used in SQL statements as case-insensitive and stores them as all uppercase
+ * in its metadata tables.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean storesUpperCaseIdentifiers() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>This method checks whether metamatrix treats mixed-case quoted SQL
identifiers
+ * used in SQL statements as case-insensitive and stores them as all uppercase
+ * in its metadata tables.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean storesUpperCaseQuotedIdentifiers() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports ALTER TABLE with add
column.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsAlterTableWithAddColumn() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports ALTER TABLE with drop
column.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsAlterTableWithDropColumn() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports ANSI-92 entry level SQL
grammer.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsANSI92EntryLevelSQL() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports ANSI-92 full SQL grammer.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsANSI92FullSQL() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports ANSI-92 intermediate SQL
grammer.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsANSI92IntermediateSQL() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Indicates whether the driver supports batch updates.</p>
+ * @return true if the driver supports batch updates; false otherwise
+ * @throws SQLException, should never occur
+ */
+ public boolean supportsBatchUpdates() throws SQLException {
+ return true;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports using a catalog name in a data
manipulation
+ * statement.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsCatalogsInDataManipulation() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports using a catalog name in an index
definition
+ * statement.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsCatalogsInIndexDefinitions() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports using a catalog name in a privilage
+ * definition statement.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports using a catalog name in a procedure
call
+ * statement.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsCatalogsInProcedureCalls() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports using a catalog name in a table
definition
+ * statement.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsCatalogsInTableDefinitions() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports column aliasing. If true the SQL AS
clause
+ * can be used to provide names for alias names for columns.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsColumnAliasing() throws SQLException {
+ return true;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports scalar function CONVERT for the
conversion
+ * of one JDBC type to another.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsConvert() throws SQLException {
+ return true;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports scalar function CONVERT for the
conversion
+ * of fromType to toType.</p>
+ * @param fromType SQL type from which to convert
+ * @param toType SQL type to convert to
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsConvert(int fromType, int toType) throws SQLException {
+ String fromName = MMJDBCSQLTypeInfo.getTypeName(fromType);
+ String toName = MMJDBCSQLTypeInfo.getTypeName(toType);
+
+ if (fromName.equals(toName)) {
+ if (fromName.equals(DataTypeManager.DefaultDataTypes.OBJECT) && fromName !=
toName) {
+ return false;
+ }
+ return true;
+ }
+ return DataTypeManager.isTransformable(fromName, toName);
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports correlated subqueries.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsCorrelatedSubqueries() throws SQLException {
+ return true;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports ODBC Core SQL grammer.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsCoreSQLGrammar() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Checks whether metamatric supports both data definition and data
manipulation
+ * statements within a transaction.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsDataDefinitionAndDataManipulationTransactions() throws
SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Are only data manipulation statements within a transaction
+ * supported?</p>
+ * @return <code>true</code> if so; <code>false</code>
otherwise
+ * @throws SQLException, should never occur
+ */
+ public boolean supportsDataManipulationTransactionsOnly() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Checks whether metamatric supports only data manipulation statements
within
+ * a transaction.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsDifferentTableCorrelationNames() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports expressions in ORDER BY
lists.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsExpressionsInOrderBy() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports ODBC Extended SQL grammer.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsExtendedSQLGrammar() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports full outer joins</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsFullOuterJoins() throws SQLException {
+ return true;
+ }
+
+ /**
+ * Retrieves whether auto-generated keys can be retrieved after a
+ * statement has been executed.
+ * @return boolean true if auto-generated keys can be retrieved
+ * after a statement has executed; false otherwise
+ * @throws SQLException, should never occur
+ */
+ public boolean supportsGetGeneratedKeys() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports GROUP BY</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsGroupBy() throws SQLException {
+ return true;
+ }
+
+ /**
+ * <p>Checks whether a GROUP BY clause can use columns that are not in the
SELECT
+ * clause, provided that it specifies all the columns in the SELECT
clause.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsGroupByBeyondSelect() throws SQLException {
+ return true;
+ }
+
+ /**
+ * <p>Checks whether a GROUP BY clause can use columns that are not in the
SELECT
+ * clause.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsGroupByUnrelated() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports the SQL Integrity Enhancement
Facility.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsIntegrityEnhancementFacility() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports specifying a LIKE escape
clause.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsLikeEscapeClause() throws SQLException {
+ return true;
+ }
+
+ /**
+ * <p>Checks whether metamatrix provides limited support for outer
joins.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsLimitedOuterJoins() throws SQLException {
+ return true;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports the ODBC minimum SQL
grammer.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsMinimumSQLGrammar() throws SQLException {
+ return true;
+ }
+
+ /**
+ * <p>Checks whether mixed-case unquoted SQL identifiers used in SQL statements
are
+ * case sensitive</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsMixedCaseIdentifiers() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Checks whether mixed-case quoted SQL identifiers used in SQL statements
are
+ * case sensitive</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports having cursors open across commits.
+ * @return if so return true, else false.</p>
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsOpenCursorsAcrossCommit() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Are multiple ResultSets from a single execute supported?</p>
+ * @return <code>true</code> if so; <code>false</code>
otherwise
+ * @throws SQLException, should never occur
+ */
+ public boolean supportsMultipleResultSets() throws SQLException {
+ return false;
+ }
+
+ /**
+ * Retrieves whether it is possible to have multiple ResultSet objects
+ * returned from a CallableStatement object simultaneously.
+ * @return <code>true</code> if so; <code>false</code>
otherwise
+ * @throws SQLException, should never occur
+ */
+ public boolean supportsMultipleOpenResults() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Checks whether multiple transactions open at once on different
connectons</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsMultipleTransactions() throws SQLException {
+ return true;
+ }
+
+ /**
+ * Retrieves whether metamatrix supports named parameters to callable statements.
+ * @return boolean true if named parameters are supported; false otherwise.
+ * @throws SQLException, should never occur
+ */
+ public boolean supportsNamedParameters() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports defining columns as
nonnullable.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsNonNullableColumns() throws SQLException {
+ return true;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports having cursors open across
rollbacks.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsOpenCursorsAcrossRollback() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports having cursors open across
commits.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsOpenStatementsAcrossCommit() throws SQLException {
+ return true;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports having cursors open across
rollbacks.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsOpenStatementsAcrossRollback() throws SQLException {
+ return true;
+ }
+
+ /**
+ * <p>Checks whether an ORDER BY clause can use columns that are not in the
SELECT clause.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsOrderByUnrelated() throws SQLException {
+ return true;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports some form of outer joins.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsOuterJoins() throws SQLException {
+ return true;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports positioned DELETEs on
resultsets</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsPositionedDelete() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports positioned UPDATEs on result
sets.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsPositionedUpdate() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Does the database support the concurrency type in combination
+ * with the given result set type?</p>
+ * @param type defined in <code>java.sql.ResultSet</code>
+ * @param concurrency type defined in <code>java.sql.ResultSet</code>
+ * @return <code>true</code> if so; <code>false</code>
otherwise
+ * @throws SQLException, should never occur
+ * @see Connection
+ */
+ public boolean supportsResultSetConcurrency(int type, int concurrency)
+ throws SQLException {
+ if(type == java.sql.ResultSet.TYPE_FORWARD_ONLY || type ==
java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE) {
+ if(concurrency == java.sql.ResultSet.CONCUR_READ_ONLY) {
+ return true;
+ }
+ return false;
+ }
+ return false;
+ }
+
+ /**
+ * Retrieves whether database supports the given result set holdability.
+ * Holdability - one of the following constants:
+ * ResultSet.HOLD_CURSORS_OVER_COMMIT or ResultSet.CLOSE_CURSORS_AT_COMMIT.
+ * @param intValue holdability
+ * @return boolean true if so; false otherwise
+ * @throws SQLException, should never occur
+
+ */
+ public boolean supportsResultSetHoldability(int holdability) throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Does the database support the given result set type?</p>
+ * @param type defined in <code>java.sql.ResultSet</code>
+ * @return <code>true</code> if so; <code>false</code>
otherwise
+ * @throws SQLException, should never occur
+ * @see Connection
+ */
+ public boolean supportsResultSetType(int type) throws SQLException {
+
+ if(type == java.sql.ResultSet.TYPE_FORWARD_ONLY || type ==
java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Retrieves whether metamatrix supports savepoints.
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsSavepoints() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports using a schema name in a data
manipulation
+ * statement</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsSchemasInDataManipulation() throws SQLException {
+ return true;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports using a schema name in an index
definition
+ * statement</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsSchemasInIndexDefinitions() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports using a schema name in a privilage
+ * definition statement</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports using a schema name in an procedure
+ * call statement</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsSchemasInProcedureCalls() throws SQLException {
+ return true;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports using a schema name in an table
+ * definition statement</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsSchemasInTableDefinitions() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports SELECT FOR UPDATE
statements</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsSelectForUpdate() throws SQLException {
+ return false;
+ }
+
+ /**
+ * Retrieves whether this metamatrix supports statement pooling.
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsStatementPooling() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports stored procedure calls using the
stored
+ * procedure escape syntax</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsStoredProcedures() throws SQLException {
+ return true;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports subqueries in comparision
expressions.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsSubqueriesInComparisons() throws SQLException {
+ return true;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports subqueries in EXISTS
expressions.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsSubqueriesInExists() throws SQLException {
+ return true;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports subqueries in IN
statements.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsSubqueriesInIns() throws SQLException {
+ return true;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports subqueries in qualified
expressions.</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsSubqueriesInQuantifieds() throws SQLException {
+ return true;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports table correlation names</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsTableCorrelationNames() throws SQLException {
+ return true;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports the given transaction isolation
level</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsTransactionIsolationLevel(int level) throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports transactions</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsTransactions() throws SQLException {
+ return true;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports SQL UNION</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsUnion() throws SQLException {
+ return true;
+ }
+
+ /**
+ * <p>Checks whether metamatrix supports SQL UNION ALL</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean supportsUnionAll() throws SQLException {
+ return true;
+ }
+
+ /**
+ * <p>Indicates whether or not a visible row update can be detected by
+ * calling the method <code>ResultSet.rowUpdated</code>.</p>
+ * @param result set type, i.e. ResultSet.TYPE_XXX
+ * @return <code>true</code> if changes are detected by the result set
type;
+ * <code>false</code> otherwise
+ * @throws SQLException, should never occur
+ */
+ public boolean updatesAreDetected(int type) throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Checks whether metamatrix uses a separate local file to store each
table</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean usesLocalFilePerTable() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>Checks whether metamatrix stores tables in a local file</p>
+ * @return if so return true, else false.
+ * @throws SQLException, should never occur.
+ */
+ public boolean usesLocalFiles() throws SQLException {
+ return false;
+ }
+
+ /**
+ * <p>This method is used to produce ResultSets from server's Results
objects for
+ * getCrossReference, getExportedKeys and getImportedKeys methods.
+ * @param server's Results object.
+ * @return ResultSet object giving the reference key info.
+ * @throws SQLException if there is an accesing server results
+ */
+ private ResultSet getReferenceKeys(ResultSetImpl results) throws SQLException {
+
+ // list which represent records containing reference key info
+ List records = new ArrayList ();
+ ResultSetMetaData rmetadata = null;
+ try {
+ // build the list of records from Results object.
+ while (results.next()) {
+ // list represents a record on the Results object.
+ List currentRow = new ArrayList (15);
+ // add values in the current record on the Results object to the list
+ // number of values to be fetched from each row is MAX_COLUMNS.
+ for(int i=0; i < JDBCColumnPositions.REFERENCE_KEYS.MAX_COLUMNS; i++)
{
+ // get the value at the current index add it to currentRow
+ currentRow.add(results.getObject(i+1));
+ }
+
+ // add the current row to the list of records.
+ records.add(currentRow);
+ }// end of while
+
+ // get the metadata for the results
+ rmetadata = results.getMetaData();
+
+ } catch (Exception e) {
+ String msg =
JDBCPlugin.Util.getString("MMDatabaseMetadata.Err_getting_primary_keys");
//$NON-NLS-1$
+ throw TeiidSQLException.create(e, msg);
+ }
+
+ // close the resultset and driver connection
+ //results.close();
+
+
logger.fine(JDBCPlugin.Util.getString("MMDatabaseMetadata.getRefKey_success"));
//$NON-NLS-1$
+
+ // construct results object from column values and their metadata
+ return createResultSet(records, rmetadata);
+ }
+
+ /**
+ * <p>This method is used to hardcode metadata details for a given column into
+ * a map object. While some of the details are obtained as parameters, most
+ * are hardcoded.
+ * @param tableName The group/table name in which the column is present
+ * @param columnName The name of the column/element
+ * @param dataType The MetaMatrix datatype of the column
+ * @param nullable An int value indicating nallability of the column
+ * @return a map containing metadata details for any given column
+ * @throws SQLException, should never occur
+ */
+ private Map getColumnMetadata(String tableName, String columnName, String dataType,
Integer nullable) throws SQLException {
+ return getColumnMetadata(tableName, columnName, dataType, nullable,
ResultsMetadataConstants.SEARCH_TYPES.UNSEARCHABLE, Boolean.FALSE, Boolean.FALSE,
Boolean.FALSE);
+ }
+
+ private Map getColumnMetadata(String tableName, String columnName, String dataType,
Integer nullable, Integer searchable, Boolean writable, Boolean signed, Boolean
caseSensitive) throws SQLException {
+
+ // map that would contain metadata details
+ Map metadataMap = new HashMap();
+
+ /*******************************************************
+ HardCoding Column metadata details for the given column
+ ********************************************************/
+
+ metadataMap.put(ResultsMetadataConstants.VIRTUAL_DATABASE_NAME,
driverConnection.getVDBName());
+ metadataMap.put(ResultsMetadataConstants.GROUP_NAME, tableName);
+ metadataMap.put(ResultsMetadataConstants.ELEMENT_NAME, columnName);
+ metadataMap.put(ResultsMetadataConstants.DATA_TYPE, dataType);
+ metadataMap.put(ResultsMetadataConstants.PRECISION,
ResultsMetadataDefaults.getDefaultPrecision(dataType));
+ metadataMap.put(ResultsMetadataConstants.RADIX, new Integer(10));
+ metadataMap.put(ResultsMetadataConstants.SCALE, new Integer(0));
+ metadataMap.put(ResultsMetadataConstants.AUTO_INCREMENTING, Boolean.FALSE);
+ metadataMap.put(ResultsMetadataConstants.CASE_SENSITIVE, caseSensitive);
+ metadataMap.put(ResultsMetadataConstants.NULLABLE, nullable);
+ metadataMap.put(ResultsMetadataConstants.SEARCHABLE, searchable);
+ metadataMap.put(ResultsMetadataConstants.SIGNED, signed);
+ metadataMap.put(ResultsMetadataConstants.WRITABLE, writable);
+ metadataMap.put(ResultsMetadataConstants.CURRENCY, Boolean.FALSE);
+ metadataMap.put(ResultsMetadataConstants.DISPLAY_SIZE,
ResultsMetadataDefaults.getMaxDisplaySize(dataType));
+
+ return metadataMap;
+ }
+
+ public boolean autoCommitFailureClosesAllResultSets() throws SQLException {
+ return false;
+ }
+
+ public int getResultSetHoldability() throws SQLException {
+ return ResultSet.HOLD_CURSORS_OVER_COMMIT;
+ }
+
+ public Connection getConnection() throws SQLException {
+ return driverConnection;
+ }
+
+ public boolean supportsStoredFunctionsUsingCallSyntax() throws SQLException {
+ return false;
+ }
+
+ public ResultSet getAttributes(String catalog, String schemaPattern, String
typeNamePattern, String attributeNamePattern)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public ResultSet getClientInfoProperties() throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public ResultSet getFunctionColumns(String catalog, String schemaPattern,
+ String functionNamePattern, String columnNamePattern)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public ResultSet getFunctions(String catalog, String schemaPattern,
+ String functionNamePattern) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ //## JDBC4.0-begin ##
+ public RowIdLifetime getRowIdLifetime() throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+ //## JDBC4.0-end ##
+
+ public ResultSet getSchemas(String catalog, String schemaPattern)
+ throws SQLException {
+ if (catalog == null) {
+ catalog = PERCENT;
+ }
+
+ if (schemaPattern == null) {
+ schemaPattern = PERCENT;
+ }
+ // list which represent records containing schema info
+ List records = new ArrayList ();
+
+ ResultSetMetaData rmetadata = null;
+ ResultSetImpl results = null;
+ PreparedStatement prepareQuery = null;
+ try {
+ prepareQuery = driverConnection.prepareStatement(QUERY_SCHEMAS);
+ prepareQuery.setObject(1, catalog.toUpperCase());
+ prepareQuery.setObject(2, schemaPattern.toUpperCase());
+ // make a query against runtimemetadata and get results
+ results = (ResultSetImpl) prepareQuery.executeQuery();
+
+ while (results.next ()) {
+ // each row will have only one column(Virtual database name)
+ List currentRow = new ArrayList (2);
+
+ for(int i = 0; i < JDBCColumnPositions.SCHEMAS.MAX_COLUMNS; i++) {
+ // get the value at the current index add it to currentRow
+ currentRow.add(results.getObject(i+1));
+ }
+
+ records.add(currentRow);
+ }
+
+ // Get the metadata for the results
+ rmetadata = results.getMetaData();
+
+ } catch(Exception e) {
+ throw TeiidSQLException.create(e,
JDBCPlugin.Util.getString("MMDatabaseMetadata.getschema_error",
e.getMessage())); //$NON-NLS-1$
+ }
+
+
logger.fine(JDBCPlugin.Util.getString("MMDatabaseMetadata.getschema_success"));
//$NON-NLS-1$
+
+ // construct results object from column values and their metadata
+ return createResultSet(records, rmetadata);
+ }
+}
Copied: trunk/client/src/main/java/org/teiid/jdbc/DeferredMetadataProvider.java (from rev
1983, trunk/client-jdbc/src/main/java/org/teiid/jdbc/DeferredMetadataProvider.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/DeferredMetadataProvider.java
(rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/DeferredMetadataProvider.java 2010-03-22
21:01:44 UTC (rev 1986)
@@ -0,0 +1,90 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.teiid.client.metadata.MetadataResult;
+import org.teiid.client.metadata.ResultsMetadataConstants;
+
+import com.metamatrix.api.exception.MetaMatrixComponentException;
+import com.metamatrix.api.exception.MetaMatrixProcessingException;
+import com.metamatrix.core.util.StringUtil;
+
+/**
+ * This metadata provider starts with just column names and types (provided in the
response)
+ * but must lazily load the rest of the metadata when necessary.
+ */
+public class DeferredMetadataProvider extends MetadataProvider {
+ private StatementImpl statement;
+ private long requestID;
+
+ public DeferredMetadataProvider(String[] columnNames, String[] columnTypes,
StatementImpl statement, long requestID) {
+ super(loadPartialMetadata(columnNames, columnTypes));
+ this.statement = statement;
+ this.requestID = requestID;
+ }
+
+ static Map[] loadPartialMetadata(String[] columnNames, String[] columnTypes) {
+ if(columnNames == null || columnTypes == null || columnNames.length !=
columnTypes.length) {
+ Object[] params = new Object[] {
+ StringUtil.toString(columnNames), StringUtil.toString(columnTypes)
+ };
+ throw new
IllegalArgumentException(JDBCPlugin.Util.getString("DeferredMetadataProvider.Invalid_data",
params)); //$NON-NLS-1$
+ }
+ Map[] columnMetadata = new Map[columnNames.length];
+ for(int i=0; i<columnNames.length; i++) {
+ columnMetadata[i] = new HashMap();
+ columnMetadata[i].put(ResultsMetadataConstants.ELEMENT_NAME,
columnNames[i]);
+ columnMetadata[i].put(ResultsMetadataConstants.DATA_TYPE, columnTypes[i]);
+ }
+ return columnMetadata;
+ }
+
+ private void loadFullMetadata() throws SQLException {
+ MetadataResult results;
+ try {
+ results = this.statement.getDQP().getMetadata(this.requestID);
+ } catch (MetaMatrixComponentException e) {
+ throw TeiidSQLException.create(e);
+ } catch (MetaMatrixProcessingException e) {
+ throw TeiidSQLException.create(e);
+ }
+ this.metadata = results.getColumnMetadata();
+ }
+
+ @Override
+ public Object getValue(int columnIndex, Integer metadataPropertyKey) throws
SQLException {
+ Object value = super.getValue(columnIndex, metadataPropertyKey);
+
+ if(value == null) {
+ loadFullMetadata();
+ value = super.getValue(columnIndex, metadataPropertyKey);
+ }
+
+ return value;
+ }
+
+}
Copied: trunk/client/src/main/java/org/teiid/jdbc/EmbeddedProfile.java (from rev 1983,
trunk/client-jdbc/src/main/java/org/teiid/jdbc/EmbeddedProfile.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/EmbeddedProfile.java
(rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/EmbeddedProfile.java 2010-03-22 21:01:44 UTC
(rev 1986)
@@ -0,0 +1,168 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.Properties;
+import java.util.logging.Logger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.teiid.net.CommunicationException;
+import org.teiid.net.ConnectionException;
+import org.teiid.net.ServerConnection;
+
+import com.metamatrix.common.util.PropertiesUtils;
+import com.metamatrix.core.MetaMatrixCoreException;
+import com.metamatrix.core.MetaMatrixRuntimeException;
+import com.metamatrix.core.util.ReflectionHelper;
+
+final class EmbeddedProfile {
+
+ /**
+ * Match URL like
+ * - jdbc:teiid:BQT
+ * - jdbc:teiid:BQT;verson=1
+ */
+ static final String BASE_PATTERN = "jdbc:teiid:((\\w+)[;]?)(;([^@])+)*";
//$NON-NLS-1$
+
+ private static Logger logger = Logger.getLogger("org.teiid.jdbc");
//$NON-NLS-1$
+
+ static Pattern basePattern = Pattern.compile(BASE_PATTERN);
+
+ /**
+ * This method tries to make a connection to the given URL. This class
+ * will return a null if this is not the right driver to connect to the given URL.
+ * @param The URL used to establish a connection.
+ * @return Connection object created
+ * @throws SQLException if it is unable to establish a connection
+ */
+ public static Connection connect(String url, Properties info)
+ throws SQLException {
+ // create a properties obj if it is null
+ if (info == null) {
+ info = new Properties();
+ } else {
+ info = PropertiesUtils.clone(info);
+ }
+
+ // parse the URL to add it's properties to properties object
+ parseURL(url, info);
+ ConnectionImpl conn = createConnection(url, info);
+ logger.fine(JDBCPlugin.Util.getString("JDBCDriver.Connection_sucess"));
//$NON-NLS-1$
+ return conn;
+ }
+
+ static ConnectionImpl createConnection(String url, Properties info) throws
SQLException{
+
+ // first validate the properties as this may called from the EmbeddedDataSource
+ // and make sure we have all the properties we need.
+ validateProperties(info);
+ try {
+ ServerConnection sc =
(ServerConnection)ReflectionHelper.create("org.teiid.transport.LocalServerConnection",
Arrays.asList(info), Thread.currentThread().getContextClassLoader()); //$NON-NLS-1$
+ return new ConnectionImpl(sc, info, url);
+ } catch (MetaMatrixRuntimeException e) {
+ throw TeiidSQLException.create(e);
+ } catch (ConnectionException e) {
+ throw TeiidSQLException.create(e);
+ } catch (CommunicationException e) {
+ throw TeiidSQLException.create(e);
+ } catch (MetaMatrixCoreException e) {
+ throw TeiidSQLException.create(e);
+ }
+ }
+
+ /**
+ * This method parses the URL and adds properties to the the properties object. These
include required and any optional
+ * properties specified in the URL.
+ * Expected URL format --
+ * jdbc:teiid:VDB;[name=value]*;
+ *
+ * @param The URL needed to be parsed.
+ * @param The properties object which is to be updated with properties in the URL.
+ * @throws SQLException if the URL is not in the expected format.
+ */
+ static void parseURL(String url, Properties info) throws SQLException {
+ if (url == null || url.trim().length() == 0) {
+ String logMsg =
JDBCPlugin.Util.getString("EmbeddedDriver.URL_must_be_specified");
//$NON-NLS-1$
+ throw new SQLException(logMsg);
+ }
+
+ try {
+ JDBCURL jdbcURL = new JDBCURL(url);
+
+ // Set the VDB Name
+ info.setProperty(BaseDataSource.VDB_NAME, jdbcURL.getVDBName());
+
+ Properties optionalParams = jdbcURL.getProperties();
+ JDBCURL.normalizeProperties(info);
+
+ Enumeration keys = optionalParams.keys();
+ while (keys.hasMoreElements()) {
+ String propName = (String)keys.nextElement();
+ // Don't let the URL properties override the passed-in Properties
object.
+ if (!info.containsKey(propName)) {
+ info.setProperty(propName, optionalParams.getProperty(propName));
+ }
+ }
+ // add the property only if it is new because they could have
+ // already been specified either through url or otherwise.
+ if(! info.containsKey(BaseDataSource.VDB_VERSION) &&
jdbcURL.getVDBVersion() != null) {
+ info.setProperty(BaseDataSource.VDB_VERSION, jdbcURL.getVDBVersion());
+ }
+ if(!info.containsKey(BaseDataSource.APP_NAME)) {
+ info.setProperty(BaseDataSource.APP_NAME,
BaseDataSource.DEFAULT_APP_NAME);
+ }
+ } catch (Exception e) {
+ throw new SQLException(e);
+ }
+ }
+
+ /**
+ * validate some required properties
+ * @param info the connection properties to be validated
+ * @throws SQLException
+ * @since 4.3
+ */
+ static void validateProperties(Properties info) throws SQLException {
+ // VDB Name has to be there
+ String value = null;
+ value = info.getProperty(BaseDataSource.VDB_NAME);
+ if (value == null || value.trim().length() == 0) {
+ String logMsg =
JDBCPlugin.Util.getString("MMDataSource.Virtual_database_name_must_be_specified");
//$NON-NLS-1$
+ throw new SQLException(logMsg);
+ }
+
+ }
+
+ public static boolean acceptsURL(String url) {
+ // Check if this can match our default one, then allow it.
+ Matcher m = basePattern.matcher(url);
+ boolean matched = m.matches();
+ return matched;
+ }
+
+}
Property changes on: trunk/client/src/main/java/org/teiid/jdbc/EmbeddedProfile.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Copied: trunk/client/src/main/java/org/teiid/jdbc/ExecutionProperties.java (from rev 1983,
trunk/client-jdbc/src/main/java/org/teiid/jdbc/ExecutionProperties.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/ExecutionProperties.java
(rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/ExecutionProperties.java 2010-03-22 21:01:44
UTC (rev 1986)
@@ -0,0 +1,102 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import org.teiid.client.RequestMessage;
+
+/**
+ * MetaMatrix-specific execution properties. These execution properties can
+ * be set via the {@link com.metamatrix.jdbc.api.Statement#setExecutionProperty(String,
String)}
+ * method. They affect the subsequent execution of all commands on that Statement
+ * instance.
+ */
+public interface ExecutionProperties {
+
+ /** Execution property name for XML format */
+ public static final String PROP_XML_FORMAT = "XMLFormat"; //$NON-NLS-1$
+
+ /** Execution property name for XML validation */
+ public static final String PROP_XML_VALIDATION = "XMLValidation";
//$NON-NLS-1$
+
+ /** Execution property name for transaction auto wrap mode */
+ public static final String PROP_TXN_AUTO_WRAP = "autoCommitTxn";
//$NON-NLS-1$
+
+ /** Execution property name for partial results mode */
+ public static final String PROP_PARTIAL_RESULTS_MODE =
"partialResultsMode"; //$NON-NLS-1$
+
+ /** XML results format: XML results displayed as a formatted tree */
+ public static final String XML_TREE_FORMAT = "Tree"; //$NON-NLS-1$
+
+ /** XML results format: XML results displayed in compact form */
+ public static final String XML_COMPACT_FORMAT = "Compact"; //$NON-NLS-1$
+
+ /** Transaction auto wrap constant - never wrap a command execution in a transaction
*/
+ public static final String TXN_WRAP_OFF = RequestMessage.TXN_WRAP_OFF;
+
+ /** Transaction auto wrap constant - always wrap commands in a transaction. */
+ public static final String TXN_WRAP_ON = RequestMessage.TXN_WRAP_ON;
+
+ /**
+ * Transaction auto wrap constant - checks if a command
+ * requires a transaction and will be automatically wrap it.
+ */
+ public static final String TXN_WRAP_DETECT = RequestMessage.TXN_WRAP_DETECT;
+
+ /**
+ * Whether to use result set cache if it is available
+ * @since 4.2
+ */
+ public static final String RESULT_SET_CACHE_MODE = "resultSetCacheMode";
//$NON-NLS-1$
+
+ /**
+ * Default fetch size to use on Statements if the fetch size is not explicitly set.
+ * The default is 500.
+ * @since 4.2
+ */
+ public static final String PROP_FETCH_SIZE = "fetchSize"; //$NON-NLS-1$
+
+ /**
+ * If true, will ignore autocommit for local transactions.
+ * @since 5.5.2
+ */
+ public static final String DISABLE_LOCAL_TRANSACTIONS = "disableLocalTxn";
//$NON-NLS-1$
+
+ /**
+ * Overrides the handling of double quoted identifiers to allow them to be strings.
+ * @since 4.3
+ */
+ public static final String ANSI_QUOTED_IDENTIFIERS =
"ansiQuotedIdentifiers"; //$NON-NLS-1$
+
+ /**
+ * Additional options/hints for executing the command
+ * @since 4.3
+ */
+ public static final String PROP_SQL_OPTIONS = "sqlOptions"; //$NON-NLS-1$
+
+ /**
+ * Passed as an option to PROP_SQL_OPTIONS
+ */
+ public static final String SQL_OPTION_SHOWPLAN = "SHOWPLAN"; //$NON-NLS-1$
+
+}
+
\ No newline at end of file
Copied: trunk/client/src/main/java/org/teiid/jdbc/FilteredResultsMetadata.java (from rev
1983, trunk/client-jdbc/src/main/java/org/teiid/jdbc/FilteredResultsMetadata.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/FilteredResultsMetadata.java
(rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/FilteredResultsMetadata.java 2010-03-22
21:01:44 UTC (rev 1986)
@@ -0,0 +1,155 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+
+
+/**
+ */
+public class FilteredResultsMetadata extends WrapperImpl implements ResultSetMetaData {
+
+ private ResultSetMetaData delegate;
+ private int actualColumnCount;
+
+ static FilteredResultsMetadata newInstance (ResultSetMetaData rsmd, int
actualColumnCount) {
+ return new FilteredResultsMetadata(rsmd, actualColumnCount);
+ }
+
+ FilteredResultsMetadata(ResultSetMetaData rsmd, int actualColumnCount) {
+ this.delegate = rsmd;
+ this.actualColumnCount = actualColumnCount;
+ }
+
+ public int getColumnCount() throws SQLException {
+ return actualColumnCount;
+ }
+
+ private void verifyColumnIndex(int index) throws SQLException {
+ if(index > actualColumnCount) {
+ throw new
SQLException(JDBCPlugin.Util.getString("FilteredResultsMetadata.Invalid_index",
index)); //$NON-NLS-1$
+ }
+ }
+
+ public boolean isAutoIncrement(int column) throws SQLException {
+ verifyColumnIndex(column);
+ return this.delegate.isAutoIncrement(column);
+ }
+
+ public boolean isCaseSensitive(int column) throws SQLException {
+ verifyColumnIndex(column);
+ return this.delegate.isCaseSensitive(column);
+ }
+
+ public boolean isSearchable(int column) throws SQLException {
+ verifyColumnIndex(column);
+ return this.delegate.isSearchable(column);
+ }
+
+ public boolean isCurrency(int column) throws SQLException {
+ verifyColumnIndex(column);
+ return this.delegate.isCurrency(column);
+ }
+
+ public int isNullable(int column) throws SQLException {
+ verifyColumnIndex(column);
+ return this.delegate.isNullable(column);
+ }
+
+ public boolean isSigned(int column) throws SQLException {
+ verifyColumnIndex(column);
+ return this.delegate.isSigned(column);
+ }
+
+ public int getColumnDisplaySize(int column) throws SQLException {
+ verifyColumnIndex(column);
+ return this.delegate.getColumnDisplaySize(column);
+ }
+
+ public String getColumnLabel(int column) throws SQLException {
+ verifyColumnIndex(column);
+ return this.delegate.getColumnLabel(column);
+ }
+
+ public String getColumnName(int column) throws SQLException {
+ verifyColumnIndex(column);
+ return this.delegate.getColumnName(column);
+ }
+
+ public String getSchemaName(int column) throws SQLException {
+ verifyColumnIndex(column);
+ return this.delegate.getSchemaName(column);
+ }
+
+ public int getPrecision(int column) throws SQLException {
+ verifyColumnIndex(column);
+ return this.delegate.getPrecision(column);
+ }
+
+ public int getScale(int column) throws SQLException {
+ verifyColumnIndex(column);
+ return this.delegate.getScale(column);
+ }
+
+ public String getTableName(int column) throws SQLException {
+ verifyColumnIndex(column);
+ return this.delegate.getTableName(column);
+ }
+
+ public String getCatalogName(int column) throws SQLException {
+ verifyColumnIndex(column);
+ return this.delegate.getCatalogName(column);
+ }
+
+ public int getColumnType(int column) throws SQLException {
+ verifyColumnIndex(column);
+ return this.delegate.getColumnType(column);
+ }
+
+ public String getColumnTypeName(int column) throws SQLException {
+ verifyColumnIndex(column);
+ return this.delegate.getColumnTypeName(column);
+ }
+
+ public boolean isReadOnly(int column) throws SQLException {
+ verifyColumnIndex(column);
+ return this.delegate.isReadOnly(column);
+ }
+
+ public boolean isWritable(int column) throws SQLException {
+ verifyColumnIndex(column);
+ return this.delegate.isWritable(column);
+ }
+
+ public boolean isDefinitelyWritable(int column) throws SQLException {
+ verifyColumnIndex(column);
+ return this.delegate.isDefinitelyWritable(column);
+ }
+
+ public String getColumnClassName(int column) throws SQLException {
+ verifyColumnIndex(column);
+ return this.delegate.getColumnClassName(column);
+ }
+
+}
Copied: trunk/client/src/main/java/org/teiid/jdbc/JDBCColumnNames.java (from rev 1983,
trunk/client-jdbc/src/main/java/org/teiid/jdbc/JDBCColumnNames.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/JDBCColumnNames.java
(rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/JDBCColumnNames.java 2010-03-22 21:01:44 UTC
(rev 1986)
@@ -0,0 +1,596 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+/* <p> This class contains constants indicating names of the columns in the
+ * result sets returned by methods on DatabaseMetaData. Each inner class represents
+ * a particular method and the class attributes give the names of the columns on
+ * methods ResultSet.</p>
+ */
+
+interface JDBCColumnNames {
+
+ /**
+ * This class contains constants representing column names on ResultSet
+ * returned by getCatalogs method on DatabaseMetaData. These constant values
+ * are be used for the column names used in constructing the ResultSet obj.
+ */
+ interface CATALOGS {
+ // name of the column containing catalog or Virtual database name.
+ static final String TABLE_CAT = "TABLE_CAT"; //$NON-NLS-1$
+ }
+
+ /**
+ * This class contains constants representing column names on ResultSet
+ * returned by getColumns method on DatabaseMetaData. These constant values
+ * are be used to hardcode the column names used in constructin the ResultSet obj.
+ */
+ interface COLUMNS {
+
+ // name of the column containing catalog or Virtual database name.
+ static final String TABLE_CAT = "TABLE_CAT"; //$NON-NLS-1$
+
+ // name of the column containing schema or Virtual database version.
+ static final String TABLE_SCHEM = "TABLE_SCHEM"; //$NON-NLS-1$
+
+ // name of the column containing table or group name.
+ static final String TABLE_NAME = "TABLE_NAME"; //$NON-NLS-1$
+
+ // name of the column containing column or element name.
+ static final String COLUMN_NAME = "COLUMN_NAME"; //$NON-NLS-1$
+
+ /** name of column that contains SQL type from java.sql.Types for column's
data type. */
+ static final String DATA_TYPE = "DATA_TYPE"; //$NON-NLS-1$
+
+ /** name of column that contains local type name used by the data source. */
+ static final String TYPE_NAME = "TYPE_NAME"; //$NON-NLS-1$
+
+ // name of the column containing column size.
+ static final String COLUMN_SIZE = "COLUMN_SIZE"; //$NON-NLS-1$
+
+ /** name of column that is not used will contain nulls */
+ static final String BUFFER_LENGTH = "BUFFER_LENGTH"; //$NON-NLS-1$
+
+ // name of the column containing number of digits to right of decimal
+ static final String DECIMAL_DIGITS = "DECIMAL_DIGITS"; //$NON-NLS-1$
+
+ // name of the column containing column's Radix.
+ static final String NUM_PREC_RADIX = "NUM_PREC_RADIX"; //$NON-NLS-1$
+
+ /** name of column that has an String value indicating nullablity */
+ static final String NULLABLE = "NULLABLE"; //$NON-NLS-1$
+
+ /** name of column containing explanatory notes. */
+ static final String REMARKS = "REMARKS"; //$NON-NLS-1$
+
+ /** name of column which contails default value for the column. */
+ static final String COLUMN_DEF = "COLUMN_DEF"; //$NON-NLS-1$
+
+ /** name of column that not used will contain nulls */
+ static final String SQL_DATA_TYPE = "SQL_DATA_TYPE"; //$NON-NLS-1$
+
+ /** name of column that not used will contain nulls */
+ static final String SQL_DATETIME_SUB = "SQL_DATETIME_SUB";
//$NON-NLS-1$
+
+ /** name of column that stores the max number of bytes in the column */
+ static final String CHAR_OCTET_LENGTH = "CHAR_OCTET_LENGTH";
//$NON-NLS-1$
+
+ /** name of column that stores the index of a column in the table */
+ static final String ORDINAL_POSITION = "ORDINAL_POSITION";
//$NON-NLS-1$
+
+ /** name of column that has an String value indicating nullablity */
+ static final String IS_NULLABLE = "IS_NULLABLE"; //$NON-NLS-1$
+
+ /** name of column that is the scope of a reference attribute (null if DATA_TYPE
isn't REF)*/
+ static final String SCOPE_CATLOG = "SCOPE_CATLOG"; //$NON-NLS-1$
+
+ /** name of column that is the scope of a reference attribute (null if the
DATA_TYPE isn't REF) */
+ static final String SCOPE_SCHEMA = "SCOPE_SCHEMA"; //$NON-NLS-1$
+
+ /** name of column that is the scope of a reference attribure (null if the
DATA_TYPE isn't REF) */
+ static final String SCOPE_TABLE = "SCOPE_TABLE"; //$NON-NLS-1$
+
+ /**
+ * name of column that is source type of a distinct type or user-generated Ref
type, SQL type
+ * from java.sql.Types (null if DATA_TYPE isn't DISTINCT or user-generated
REF)
+ */
+ static final String SOURCE_DATA_TYPE = "SOURCE_DATA_TYPE";
//$NON-NLS-1$
+
+ /** name of column that has an String value indicating format */
+ static final String FORMAT = "FORMAT"; //$NON-NLS-1$
+
+ /** name of column that has an String value indicating minimum range */
+ static final String MIN_RANGE = "MIN_RANGE"; //$NON-NLS-1$
+
+ /** name of column that has an String value indicating maximum range */
+ static final String MAX_RANGE = "MAX_RANGE"; //$NON-NLS-1$
+ }
+
+ /**
+ * This class contains constants representing column names on ResultSet
+ * returned by getColumnPrivileges and getTablePrivileges methods on
+ * DatabaseMetaData. These constant values are be used to hardcode the column
+ * names used in constructin the ResultSet obj.
+ */
+ interface PRIVILEGES {
+
+ // name of the column containing catalog or Virtual database name.
+ static final String TABLE_CAT = "TABLE_CAT"; //$NON-NLS-1$
+
+ // name of the column containing schema or Virtual database version.
+ static final String TABLE_SCHEM = "TABLE_SCHEM"; //$NON-NLS-1$
+
+ // name of the column containing table or group name.
+ static final String TABLE_NAME = "TABLE_NAME"; //$NON-NLS-1$
+
+ // name of the column containing column or element name.
+ static final String COLUMN_NAME = "COLUMN_NAME"; //$NON-NLS-1$
+
+ // name of the column containing Grantor name
+ static final String GRANTOR = "GRANTOR"; //$NON-NLS-1$
+
+ // name of the column containing Grantee name
+ static final String GRANTEE = "GRANTEE"; //$NON-NLS-1$
+
+ // name of the column containing privilege name
+ static final String PRIVILEGE = "PRIVILEGE"; //$NON-NLS-1$
+
+ // name of the column containing privilage grantable info
+ static final String IS_GRANTABLE = "IS_GRANTABLE"; //$NON-NLS-1$
+ }
+
+ /**
+ * This class contains constants representing column names on ResultSet
+ * returned by getCrossReference, getExportedKeys, and getImportedKeys methods
+ * on DatabaseMetaData. These constant values are be used to hardcode the
+ * column names used in constructin the ResultSet obj.
+ */
+ interface REFERENCE_KEYS {
+
+ // name of the column containing catalog or Virtual database name for primary
key's table.
+ static final String PKTABLE_CAT = "PKTABLE_CAT"; //$NON-NLS-1$
+
+ // name of the column containing schema or Virtual database version for primary
key's table.
+ static final String PKTABLE_SCHEM = "PKTABLE_SCHEM"; //$NON-NLS-1$
+
+ // name of the column containing table or group name for primary key's
table.
+ static final String PKTABLE_NAME = "PKTABLE_NAME"; //$NON-NLS-1$
+
+ // name of the column containing column or element name of the primary key.
+ static final String PKCOLUMN_NAME = "PKCOLUMN_NAME"; //$NON-NLS-1$
+
+ // name of the column containing catalog or Virtual database name for foreign
key's table.
+ static final String FKTABLE_CAT = "FKTABLE_CAT"; //$NON-NLS-1$
+
+ // name of the column containing schema or Virtual database version for foreign
key's table.
+ static final String FKTABLE_SCHEM = "FKTABLE_SCHEM"; //$NON-NLS-1$
+
+ // name of the column containing table or group name for foreign key's
table.
+ static final String FKTABLE_NAME = "FKTABLE_NAME"; //$NON-NLS-1$
+
+ // name of the column containing column or element name of the foreign key.
+ static final String FKCOLUMN_NAME = "FKCOLUMN_NAME"; //$NON-NLS-1$
+
+ // name of the column containing sequence number within the foreign key
+ static final String KEY_SEQ = "KEY_SEQ"; //$NON-NLS-1$
+
+ // name of the column containing effect on foreign key when PK is updated.
+ static final String UPDATE_RULE = "UPDATE_RULE"; //$NON-NLS-1$
+
+ // name of the column containing effect on foreign key when PK is deleted.
+ static final String DELETE_RULE = "DELETE_RULE"; //$NON-NLS-1$
+
+ // name of the column containing name of the foreign key.
+ static final String FK_NAME = "FK_NAME"; //$NON-NLS-1$
+
+ // name of the column containing name of the primary key.
+ static final String PK_NAME = "PK_NAME"; //$NON-NLS-1$
+
+ // name of the column containing deferability of foreign key constraStrings.
+ static final String DEFERRABILITY = "DEFERRABILITY"; //$NON-NLS-1$
+ static final String FKPOSITION = "FKPOSITION"; //$NON-NLS-1$
+ }
+
+
+ /**
+ * This class contains constants representing column names on ResultSet
+ * returned by getPrimaryKeys method on DatabaseMetaData. These constant values
+ * are be used to hardcode the column names used in constructin the ResultSet obj.
+ */
+ interface PRIMARY_KEYS {
+
+ // name of the column containing catalog or Virtual database name.
+ static final String TABLE_CAT = "TABLE_CAT"; //$NON-NLS-1$
+
+ // name of the column containing schema or Virtual database version.
+ static final String TABLE_SCHEM = "TABLE_SCHEM"; //$NON-NLS-1$
+
+ // name of the column containing table or group name.
+ static final String TABLE_NAME = "TABLE_NAME"; //$NON-NLS-1$
+
+ // name of the column containing column or element name.
+ static final String COLUMN_NAME = "COLUMN_NAME"; //$NON-NLS-1$
+
+ // name of the column containing sequence number within the primary key
+ static final String KEY_SEQ = "KEY_SEQ"; //$NON-NLS-1$
+
+ // name of the column containing name of the primary key.
+ static final String PK_NAME = "PK_NAME"; //$NON-NLS-1$
+ static final String POSITION = "POSITION"; //$NON-NLS-1$
+ }
+
+
+ /**
+ * This class contains constants representing column names on ResultSet
+ * returned by getProcedureColumns method on DatabaseMetaData. These constant
+ * values are be used to hardcode the column names used in constructin the
+ * ResultSet obj.
+ */
+ interface PROCEDURE_COLUMNS {
+
+ // name of the column containing procedure catalog or Virtual database name.
+ static final String PROCEDURE_CAT = "PROCEDURE_CAT"; //$NON-NLS-1$
+
+ // name of the column containing schema or Virtual database version.
+ static final String PROCEDURE_SCHEM = "PROCEDURE_SCHEM"; //$NON-NLS-1$
+
+ // name of the column containing table or group name.
+ static final String PROCEDURE_NAME = "PROCEDURE_NAME"; //$NON-NLS-1$
+
+ // name of the column containing column or element name.
+ static final String COLUMN_NAME = "COLUMN_NAME"; //$NON-NLS-1$
+
+ // name of the column containing column or element type.
+ static final String COLUMN_TYPE = "COLUMN_TYPE"; //$NON-NLS-1$
+
+ /** name of column that contains SQL type from java.sql.Types for column's
data type. */
+ static final String DATA_TYPE = "DATA_TYPE"; //$NON-NLS-1$
+
+ /** name of column that contains local type name used by the data source. */
+ static final String TYPE_NAME = "TYPE_NAME"; //$NON-NLS-1$
+
+ // name of the column containing number of digits to right of decimal
+ static final String PRECISION = "PRECISION"; //$NON-NLS-1$
+
+ /** name of column that that contains length of data in bytes */
+ static final String LENGTH = "LENGTH"; //$NON-NLS-1$
+
+ // constant indiacting column's Radix.
+ static final String SCALE = "SCALE"; //$NON-NLS-1$
+
+ // constant indiacting column's Radix.
+ static final String RADIX = "RADIX"; //$NON-NLS-1$
+
+ /** name of column that has an String value indicating nullablity */
+ static final String NULLABLE = "NULLABLE"; //$NON-NLS-1$
+
+ /** name of column containing explanatory notes. */
+ static final String REMARKS = "REMARKS"; //$NON-NLS-1$
+ static final String POSITION = "POSITION"; //$NON-NLS-1$
+ }
+
+
+ /**
+ * This class contains constants representing column names on ResultSet
+ * returned by getProcedures method on DatabaseMetaData. These constant values
+ * are be used to hardcode the column names used in constructin the ResultSet obj.
+ */
+ interface PROCEDURES {
+
+ // name of the column containing procedure catalog or Virtual database name.
+ static final String PROCEDURE_CAT = "PROCEDURE_CAT"; //$NON-NLS-1$
+
+ // name of the column containing schema or Virtual database version.
+ static final String PROCEDURE_SCHEM = "PROCEDURE_SCHEM"; //$NON-NLS-1$
+
+ // name of the column containing table or group name.
+ static final String PROCEDURE_NAME = "PROCEDURE_NAME"; //$NON-NLS-1$
+
+ // name of the column containing name of the column which is reserved
+ //static final String RESERVED = "RESERVED";
+
+ /** name of column containing explanatory notes. */
+ static final String REMARKS = "REMARKS"; //$NON-NLS-1$
+
+ /** name of column indicating kind of the procedure. */
+ static final String PROCEDURE_TYPE = "PROCEDURE_TYPE"; //$NON-NLS-1$
+
+ static final String RESERVED_1 = "RESERVED_1"; //$NON-NLS-1$
+ static final String RESERVED_2 = "RESERVED_2"; //$NON-NLS-1$
+ static final String RESERVED_3 = "RESERVED_3"; //$NON-NLS-1$
+ }
+
+
+ /**
+ * This class contains constants representing column names on ResultSet
+ * returned by getSchemas method on DatabaseMetaData. These constant values
+ * are be used to hardcode the column names used in constructin the ResultSet obj.
+ */
+ interface SCHEMAS {
+
+ // name of the column containing procedure catalog or Virtual database name.
+ static final String TABLE_SCHEM = "TABLE_SCHEM"; //$NON-NLS-1$
+
+ // name of the column containing schema or Virtual database version.
+ static final String TABLE_CATALOG = "TABLE_CATALOG"; //$NON-NLS-1$
+
+ }
+
+ /**
+ * This class contains constants representing column names on ResultSet
+ * returned by getTables and getTableTypes methods on DatabaseMetaData. These
+ * constant values are be used to hardcode the column names used in construction
+ * the ResultSet obj.
+ */
+ interface TABLES {
+
+ // name of the column containing catalog or Virtual database name.
+ static final String TABLE_CAT = "TABLE_CAT"; //$NON-NLS-1$
+
+ // name of the column containing schema or Virtual database version.
+ static final String TABLE_SCHEM = "TABLE_SCHEM"; //$NON-NLS-1$
+
+ // name of the column containing table or group name.
+ static final String TABLE_NAME = "TABLE_NAME"; //$NON-NLS-1$
+
+ // name of the column containing table or group type.
+ static final String TABLE_TYPE = "TABLE_TYPE"; //$NON-NLS-1$
+
+ /** name of column containing explanatory notes. */
+ static final String REMARKS = "REMARKS"; //$NON-NLS-1$
+ static final String TYPE_CAT = "TYPE_CAT"; //$NON-NLS-1$
+ static final String TYPE_SCHEM = "TYPE_SCHEM"; //$NON-NLS-1$
+ static final String TYPE_NAME = "TYPE_NAME"; //$NON-NLS-1$
+ static final String SELF_REFERENCING_COL_NAME =
"SELF_REFERENCING_COL_NAME"; //$NON-NLS-1$
+ static final String REF_GENERATION = "REF_GENERATION"; //$NON-NLS-1$
+ static final String ISPHYSICAL = "ISPHYSICAL"; //$NON-NLS-1$
+
+ }
+
+ /**
+ * This class contains constants representing column names on ResultSet
+ * returned by getTables and getTableTypes methods on DatabaseMetaData. These
+ * constant values are be used to hardcode the column names used in construction
+ * the ResultSet obj.
+ */
+ interface TABLE_TYPES {
+
+ // name of the column containing table or group type.
+ static final String TABLE_TYPE = "TABLE_TYPE"; //$NON-NLS-1$
+ }
+
+ /**
+ * This class contains constants representing column names on ResultSet
+ * returned by getTypeInfo method on DatabaseMetaData. These constant values
+ * are be used to hardcode the column names used in constructin the ResultSet obj.
+ */
+ interface TYPE_INFO {
+
+ /** name of column that contains local type name used by the data source. */
+ static final String TYPE_NAME = "TYPE_NAME"; //$NON-NLS-1$
+
+ /** name of column that contains SQL type from java.sql.Types for column's
data type. */
+ static final String DATA_TYPE = "DATA_TYPE"; //$NON-NLS-1$
+
+ // name of the column containing number of digits to right of decimal
+ static final String PRECISION = "PRECISION"; //$NON-NLS-1$
+
+ // name of the column containing prefix used to quote a literal
+ static final String LITERAL_PREFIX = "LITERAL_PREFIX"; //$NON-NLS-1$
+
+ // name of the column containing suffix used to quote a literal
+ static final String LITERAL_SUFFIX = "LITERAL_SUFFIX"; //$NON-NLS-1$
+
+ // name of the column containing params used in creating the type
+ static final String CREATE_PARAMS = "CREATE_PARAMS"; //$NON-NLS-1$
+
+ /** name of column that has an String value indicating nullablity */
+ static final String NULLABLE = "NULLABLE"; //$NON-NLS-1$
+
+ /** name of column that has an String value indicating case sensitivity */
+ static final String CASE_SENSITIVE = "CASE_SENSITIVE"; //$NON-NLS-1$
+
+ /** name of column that has an String value indicating searchability */
+ static final String SEARCHABLE = "SEARCHABLE"; //$NON-NLS-1$
+
+ /** name of column that has an String value indicating searchability */
+ static final String UNSIGNED_ATTRIBUTE = "UNSIGNED_ATTRIBUTE";
//$NON-NLS-1$
+
+ /** name of column that contains info if the column is a currency value */
+ static final String FIXED_PREC_SCALE = "FIXED_PREC_SCALE";
//$NON-NLS-1$
+
+ /** name of column that contains info whether the column is autoincrementable */
+ static final String AUTOINCREMENT = "AUTO_INCREMENT"; //$NON-NLS-1$
+
+ /** name of column that localised version of type name */
+ static final String LOCAL_TYPE_NAME = "LOCAL_TYPE_NAME"; //$NON-NLS-1$
+
+ /** name of column that gives the min scale supported */
+ static final String MINIMUM_SCALE = "MINIMUM_SCALE"; //$NON-NLS-1$
+
+ /** name of column that gives the max scale supported */
+ static final String MAXIMUM_SCALE = "MAXIMUM_SCALE"; //$NON-NLS-1$
+
+ /** name of column that not used will contain nulls */
+ static final String SQL_DATA_TYPE = "SQL_DATA_TYPE"; //$NON-NLS-1$
+
+ /** name of column that not used will contain nulls */
+ static final String SQL_DATETIME_SUB = "SQL_DATETIME_SUB";
//$NON-NLS-1$
+
+ // constant indiacting column's Radix.
+ static final String NUM_PREC_RADIX = "NUM_PREC_RADIX"; //$NON-NLS-1$
+ }
+
+
+ /**
+ * This class contains constants representing column names on ResultSet
+ * returned by getUDTS method on DatabaseMetaData. These constant values
+ * are be used to hardcode the column names used in constructin the ResultSet obj.
+ */
+ interface UDTS {
+
+ // name of the column containing table or Groups name in which UDTS are present.
+ static final String TABLE_NAME = "UDTS"; //$NON-NLS-1$
+
+ // name of the column containing catalog or Virtual database name.
+ static final String TYPE_CAT = "TYPE_CAT"; //$NON-NLS-1$
+
+ // name of the column containing schema or Virtual database version.
+ static final String TYPE_SCHEM = "TYPE_SCHEM"; //$NON-NLS-1$
+
+ // name of the column containing name of type name column.
+ static final String TYPE_NAME = "TYPE_NAME"; //$NON-NLS-1$
+
+ // name of the column containing class name column.
+ static final String CLASS_NAME = "CLASS_NAME"; //$NON-NLS-1$
+
+ // name of the column containing name of sql datatype code column
+ static final String DATA_TYPE = "DATA_TYPE"; //$NON-NLS-1$
+
+ // name of the column containing comments column
+ static final String REMARKS = "REMARKS"; //$NON-NLS-1$
+ static final String BASE_TYPE = "BASE_TYPE"; //$NON-NLS-1$
+ }
+
+ /**
+ * This class contains constants representing column names on ResultSet
+ * returned by getIndexInfo method on DatabaseMetaData. These constant values
+ * are be used to hardcode the column names used in constructin the ResultSet obj.
+ */
+ interface INDEX_INFO {
+
+ // name of the column containing tables catalog name on which the index is
present
+ static final String TABLE_CAT = "TABLE_CAT"; //$NON-NLS-1$
+
+ // name of the column containing tables schema name on which the index is
present
+ static final String TABLE_SCHEM = "TABLE_SCHEM"; //$NON-NLS-1$
+
+ // name of the column containing table or group name.
+ static final String TABLE_NAME = "TABLE_NAME"; //$NON-NLS-1$
+
+ // name of the column containing name of column showing if an index in
non-unique
+ static final String NON_UNIQUE = "NON_UNIQUE"; //$NON-NLS-1$
+
+ // name of the column containing name of column containing index_qualifier
string
+ static final String INDEX_QUALIFIER = "INDEX_QUALIFIER"; //$NON-NLS-1$
+
+ // name of the column containing name of column containing index names
+ static final String INDEX_NAME = "INDEX_NAME"; //$NON-NLS-1$
+
+ // name of the column containing name of column containing index types
+ static final String TYPE = "TYPE"; //$NON-NLS-1$
+
+ // name of the column containing name of the column containing column position.
+ static final String ORDINAL_POSITION = "ORDINAL_POSITION";
//$NON-NLS-1$
+
+ // name of the column containing name of the column containing column names.
+ static final String COLUMN_NAME = "COLUMN_NAME"; //$NON-NLS-1$
+
+ // name of the column containing name of column containing info if the index is
asc or desc.
+ static final String ASC_OR_DESC = "ASC_OR_DESC"; //$NON-NLS-1$
+
+ // name of the column containing name of the column containing number of unique
values in index.
+ static final String CARDINALITY = "CARDINALITY"; //$NON-NLS-1$
+
+ // name of the column containing name of the column giving number od pages used
for the current index.
+ static final String PAGES = "PAGES"; //$NON-NLS-1$
+
+ // name of the column containing name of the column giving filter condition.
+ static final String FILTER_CONDITION = "FILTER_CONDITION";
//$NON-NLS-1$
+ }
+
+ /**
+ * This class contains constants representing column names on ResultSet
+ * returned by getBestRowIdentifier method on DatabaseMetaData. These constant
values
+ * are be used to hardcode the column names used in constructin the ResultSet obj.
+ */
+ interface BEST_ROW {
+
+ // name of the column containing SCOPE of the identifier
+ static final String SCOPE = "SCOPE"; //$NON-NLS-1$
+
+ // name of the column containing column name
+ static final String COLUMN_NAME = "COLUMN_NAME"; //$NON-NLS-1$
+
+ // name of the column containing data type code
+ static final String DATA_TYPE = "DATA_TYPE"; //$NON-NLS-1$
+
+ // name of the column containing data type name
+ static final String TYPE_NAME = "TYPE_NAME"; //$NON-NLS-1$
+
+ // name of the column containing size of the column
+ static final String COLUMN_SIZE = "COLUMN_SIZE"; //$NON-NLS-1$
+
+ // name of the column containing buffer length
+ static final String BUFFER_LENGTH = "BUFFER_LENGTH"; //$NON-NLS-1$
+
+ // name of the column containing decimal digits/ scale
+ static final String DECIMAL_DIGITS = "DECIMAL_DIGITS"; //$NON-NLS-1$
+
+ // name of the column containing name of the column containing column position.
+ static final String ORDINAL_POSITION = "ORDINAL_POSITION";
//$NON-NLS-1$
+
+ // name of the column containing pseudo column
+ static final String PSEUDO_COLUMN = "PSEUDO_COLUMN"; //$NON-NLS-1$
+ }
+
+ /**
+ * This class contains constants representing column names on ResultSet
+ * returned by getSuperTables method on DatabaseMetaData. These constant values
+ * are be used to hardcode the column names used in constructin the ResultSet obj.
+ */
+ interface SUPER_TABLES {
+ // name of the column containing catalog or Virtual database name.
+ static final String TABLE_CAT = "TABLE_CAT"; //$NON-NLS-1$
+ // name of the column containing schema or Virtual database version.
+ static final String TABLE_SCHEM = "TABLE_SCHEM"; //$NON-NLS-1$
+ // name of the column containing table or Groups name .
+ static final String TABLE_NAME = "TABLE_NAME"; //$NON-NLS-1$
+ // name of the column containing super table.
+ static final String SUPERTABLE_NAME = "SUPERTABLE_NAME"; //$NON-NLS-1$
+ }
+
+ /**
+ * This class contains constants representing column names on ResultSet
+ * returned by getSuperTypes method on DatabaseMetaData. These constant values
+ * are be used to hardcode the column names used in constructin the ResultSet obj.
+ */
+
+ interface SUPER_TYPES {
+
+ // name of the column containing catalog or Virtual database name.
+ static final String TYPE_CAT = "TYPE_CAT"; //$NON-NLS-1$
+ // name of the column containing schema or Virtual database version.
+ static final String TYPE_SCHEM = "TYPE_SCHEM"; //$NON-NLS-1$
+ // name of the column containing name of type name column.
+ static final String TYPE_NAME = "TYPE_NAME"; //$NON-NLS-1$
+ // name of the column containing super catalog or Virtual database name.
+ static final String SUPERTYPE_CAT = "SUPERTYPE_CAT"; //$NON-NLS-1$
+ // name of the column containing super schema or Virtual database version.
+ static final String SUPERTYPE_SCHEM = "SUPERTYPE_SCHEM"; //$NON-NLS-1$
+ // name of the column containing name of super type name column.
+ static final String SUPERTYPE_NAME = "SUPERTYPE_NAME"; //$NON-NLS-1$
+
+ }
+
+}
Copied: trunk/client/src/main/java/org/teiid/jdbc/JDBCColumnPositions.java (from rev 1983,
trunk/client-jdbc/src/main/java/org/teiid/jdbc/JDBCColumnPositions.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/JDBCColumnPositions.java
(rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/JDBCColumnPositions.java 2010-03-22 21:01:44
UTC (rev 1986)
@@ -0,0 +1,576 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+/**
+ * <p> This class provides constants indicating positions of columns in the
+ * <code>ResultSets</code> returned by methods on
<code>MMDatabaseMetaData</code>
+ * object. The inner classes represent the methods while attributes represent the
+ * column positions. The name of the constant explains the column content.</p>
+ * <p> The constants in the inner classes could include column positions for
columns
+ * that are hardcoded, columns positions of some columns on server's
+ * <code>Results</code> object.</p>
+ * <p> Each of the inner classes have a constant
<code>MAX_COLUMNS</code> that
+ * represents the number of columns to be read from the server's
<code>Results</code>
+ * object.</p>
+ * <p> All the column positions are one based. </code>
+ */
+
+interface JDBCColumnPositions {
+
+ /**
+ * <p>This class contains constants representing column positions on ResultSet
+ * returned by getColumns method on DatabaseMetaData. The class has constants
+ * for columns whose values are to be hardcoded in MMDatabaseMetaData object.
+ * <code>MAX_COLUMNS</code> is the number of columns to be read from
server's
+ * results from getElements method on <code>Metadata object</code>.
+ * <code>JAVA_CLASS</code> is the column position for element data type
on
+ * server's Results object.
+ */
+ interface SCHEMAS {
+ /** Number of columns to be read from results returned getElements method. */
+ static final int MAX_COLUMNS = 2;
+ static final int TABLE_CATALOG = 2;
+ }
+
+ /**
+ * <p>This class contains constants representing column positions on ResultSet
+ * returned by getColumns method on DatabaseMetaData. The class has constants
+ * for columns whose values are to be hardcoded in MMDatabaseMetaData object.
+ * <code>MAX_COLUMNS</code> is the number of columns to be read from
server's
+ * results from getElements method on <code>Metadata object</code>.
+ * <code>JAVA_CLASS</code> is the column position for element data type
on
+ * server's Results object.
+ */
+ interface CATALOGS {
+
+ /** Number of columns to be read from results returned getElements method. */
+ static final int MAX_COLUMNS = 1;
+ }
+
+
+ /**
+ * <p>This class contains constants representing column positions on ResultSet
+ * returned by getColumns method on DatabaseMetaData. The class has constants
+ * for columns whose values are to be hardcoded in MMDatabaseMetaData object.
+ * <code>MAX_COLUMNS</code> is the number of columns to be read from
server's
+ * results from getElements method on <code>Metadata object</code>.
+ * <code>JAVA_CLASS</code> is the column position for element data type
on
+ * server's Results object.
+ */
+ interface COLUMNS {
+
+ /** Number of columns to be read from results returned getElements method. */
+ static final int MAX_COLUMNS = 23;
+
+ /** Position of column that contains catalog name in which the table for the
column is present. */
+ static final int TABLE_CAT = 1;
+
+ static final int TABLE_SCHEM = 2;
+
+ static final int TABLE_NAME = 3;
+
+ static final int COLUMN_NAME = 4;
+
+ /** Position of column that contains SQL type from java.sql.Types for
column's data type. */
+ static final int DATA_TYPE = 5;
+
+ /** Position of column that contains local type name used by the data source. */
+ static final int TYPE_NAME = 6;
+
+ static final int COLUMN_SIZE = 7;
+
+ /** Position of column that is not used will contain nulls */
+ static final int BUFFER_LENGTH = 8;
+
+ static final int DECIMAL_DIGITS = 9;
+
+ static final int NUM_PREC_RADIX = 10;
+
+ /** Position of column that has an int value indicating nullablity */
+ static final int NULLABLE = 11;
+
+ /** Position of column containing explanatory notes. */
+ static final int REMARKS = 12;
+
+ static final int COLUMN_DEF = 13;
+
+ /** Position of column that not used will contain nulls */
+ static final int SQL_DATA_TYPE = 14;
+
+ /** Position of column that not used will contain nulls */
+ static final int SQL_DATETIME_SUB = 15;
+
+ static final int CHAR_OCTET_LENGTH = 16;
+
+ static final int ORDINAL_POSITION = 17;
+
+ /** Position of column that has an String value indicating nullablity */
+ static final int IS_NULLABLE = 18;
+
+ static final int SCOPE_CATALOG = 19;
+
+ static final int SCOPE_SCHEMA = 20;
+
+ static final int SCOPE_TABLE = 21;
+
+ static final int SOURCE_DATA_TYPE = 22;
+
+ static final int IS_AUTOINCREMENT = 23;
+
+ }
+
+ /**
+ * <p>This class contains constants representing column positions on ResultSet
+ * returned by getColumns method on DatabaseMetaData. The class has constants
+ * for columns whose values are to be hardcoded in MMDatabaseMetaData object.
+ * <code>MAX_COLUMNS</code> is the number of columns to be read from
server's
+ * results from getElements method on <code>Metadata object</code>.
+ * <code>JAVA_CLASS</code> is the column position for element data type
on
+ * server's Results object.
+ */
+ interface TABLES {
+
+ /** Number of columns to be read from results returned getTables method. */
+ static final int MAX_COLUMNS = 11;
+
+ /** Position of column that contains catalog name in which the table is present.
*/
+ static final int TABLE_CAT = 1;
+ static final int TYPE_CAT = 6;
+ static final int TYPE_SCHEM = 7;
+ static final int TYPE_NAME = 8;
+ static final int SELF_REFERENCING_COL_NAME = 9;
+ static final int REF_GENERATION = 10;
+ static final int ISPHYSICAL = 11;
+ }
+
+ /**
+ * <p>This class contains constants representing column positions on ResultSet
+ * returned by getColumns method on DatabaseMetaData. The class has constants
+ * for columns whose values are to be hardcoded in MMDatabaseMetaData object.
+ * <code>MAX_COLUMNS</code> is the number of columns to be read from
server's
+ * results from getElements method on <code>Metadata object</code>.
+ * <code>JAVA_CLASS</code> is the column position for element data type
on
+ * server's Results object.
+ */
+ interface TYPE_INFO {
+
+ /** Number of columns to be read from results returned getElements method. */
+ static final int MAX_COLUMNS = 18;
+
+ /** Position of column that contains local type name used by the data source. */
+ static final int TYPE_NAME = 1;
+
+ /** Position of column that contains SQL type from java.sql.Types for
column's data type. */
+ static final int DATA_TYPE = 2;
+
+ static final int PRECISION = 3;
+ /** Position of column that contains prefix used to quote a literal. */
+ static final int LITERAL_PREFIX = 4;
+
+ /** Position of column that contains suffix used to quote a literal. */
+ static final int LITERAL_SUFFIX = 5;
+
+ /** Position of column that contains params used in creating the type. */
+ static final int CREATE_PARAMS = 6;
+
+ /** Position of column that contains the nullable value. */
+ static final int NULLABLE = 7;
+
+ static final int CASE_SENSITIVE = 8;
+
+ /** Position of column that contains the searchable value. */
+ static final int SEARCHABLE = 9;
+
+ /** Position of column that contains the unsigned value. */
+ static final int UNSIGNED_ATTRIBUTE = 10;
+
+ static final int FIXED_PREC_SCALE = 11;
+
+ static final int AUTO_INCREMENT = 12;
+
+ /** Position of column that contains local type name used by the data source. */
+ static final int LOCAL_TYPE_NAME = 13;
+
+ /** Position of column that contains the min scale value. */
+ static final int MINIMUM_SCALE = 14;
+
+ /** Position of column that contains the max scale value. */
+ static final int MAXIMUM_SCALE = 15;
+
+ /** Position of column that not used will contain nulls */
+ static final int SQL_DATA_TYPE = 16;
+
+ /** Position of column that not used will contain nulls */
+ static final int SQL_DATETIME_SUB = 17;
+
+ static final int NUM_PREC_RADIX = 18;
+
+ /** Position of column in server's results containing name of the
datatype.*/
+ static final int NAME = 19;
+
+ /** Position of column in server's results containing isSigned value.*/
+ static final int IS_SIGNED = 20;
+
+ /** Position of column in server's results containing nullType name.*/
+ static final int NULL_TYPE_NAME = 21;
+
+ /** Position of column in server's results containing search type name.*/
+ static final int SEARCH_TYPE_NAME = 22;
+ }
+
+ /**
+ * This class contains constants representing column positions on ResultSet
+ * returned by getUDTS method on DatabaseMetaData. These constant values
+ * are be used to hardcode the column values used in constructin the ResultSet obj.
+ */
+ interface UDTS {
+
+ /** Number of columns to be read from results returned getUserDefinedTypes
method. */
+ static final int MAX_COLUMNS = 7;
+
+ // name of the column containing table or Groups name in which UDTS are present.
+ static final int TABLE_NAME = 3;
+
+ // name of the column containing catalog or Virtual database name.
+ static final int TYPE_CAT = 1;
+
+ // name of the column containing schema or Virtual database version.
+ static final int TYPE_SCHEM = 2;
+
+ // name of the column containing name of type name column.
+ static final int TYPE_NAME = 9;
+
+ // name of the column containing class name column.
+ static final int CLASS_NAME = 4;
+
+ // name of the column containing name of sql datatype code column
+ static final int DATA_TYPE = 5;
+
+ // name of the column containing comments column
+ static final int REMARKS = 6;
+
+ static final int BASE_TYPE = 7;
+ /** Position of column in server's results containing java class name.*/
+ static final int JAVA_CLASS = 8;
+ }
+
+ /**
+ * <p>This class contains constants representing column positions on ResultSet
+ * returned by getIndexInfo method on DatabaseMetaData. The class has constants
+ * for columns whose values are to be hardcoded in MMDatabaseMetaData object.
+ * <code>MAX_COLUMNS</code> is the number of columns to be read from
server's
+ * results from the query against System.KeyElements table.</p>
+ */
+ interface INDEX_INFO {
+
+ /** Number of columns to be read from results returned by server results. */
+ static final int MAX_COLUMNS = 13;
+
+ /** Position of column that contains catalog name of the table. */
+ static final int TABLE_CAT = 1;
+
+ static final int TABLE_SCHEM = 2;
+
+ static final int TABLE_NAME = 3;
+
+ /** Position of column that contains non uniqueness of the index. */
+ static final int NON_UNIQUE = 4;
+
+ /** Position of column that contains qualifier for the index. */
+ static final int INDEX_QUALIFIER = 5;
+
+ static final int INDEX_NAME = 6;
+
+ /** Position of column that contains type of index. */
+ static final int TYPE = 7;
+
+ static final int ORDINAL_POSITION = 8;
+
+ static final int COLUMN_NAME = 9;
+
+ /** Position of column that contains desc if index is ascending or descending.
*/
+ static final int ASC_OR_DESC = 10;
+
+ /** Position of column that contains cardinality of the index. */
+ static final int CARDINALITY = 11;
+
+ /** Position of column that contains pages oocupied by table. */
+ static final int PAGES = 12;
+
+ /** Position of column that contains any filter condition. */
+ static final int FILTER_CONDITION = 13;
+
+ }
+
+ /**
+ * <p>This class contains constants representing column positions on ResultSet
+ * returned by getColumns method on DatabaseMetaData. The class has constants
+ * for columns whose values are to be hardcoded in MMDatabaseMetaData object.
+ * <code>MAX_COLUMNS</code> is the number of columns to be read from
server's
+ * results from getElements method on <code>Metadata object</code>.
+ * <code>JAVA_CLASS</code> is the column position for element data type
on
+ * server's Results object.
+ */
+ interface PRIMARY_KEYS {
+
+ /** Number of columns to be read from results returned by getPrimaryKeys. */
+ static final int MAX_COLUMNS = 6;
+
+ /** Position of column that contains catalog name of the primaryTable. */
+ static final int TABLE_CAT = 1;
+ static final int TABLE_SCHEM = 2;
+ static final int TABLE_NAME = 3;
+ static final int COLUMN_NAME = 4;
+ static final int KEY_SEQ = 5;
+ static final int PK_NAME = 6;
+ }
+
+ /**
+ * <p>This class contains constants representing column positions on ResultSet
+ * returned by getCrossReferences method on DatabaseMetaData. The class has
constants
+ * for columns whose values are to be hardcoded in MMDatabaseMetaData object.
+ * <code>MAX_COLUMNS</code> is the number of columns to be read from
server's
+ * results from getCrossReferences method on server's <code>Metadata
object</code>.
+ */
+ interface REFERENCE_KEYS {
+
+ /** Number of columns to be read from results returned any of the 3 methods. */
+ static final int MAX_COLUMNS = 14;
+
+ /** Position of column that contains catalog name of the primaryTable. */
+ static final int PKTABLE_CAT = 1;
+
+ /** Position of column that contains scheam name of the primaryTable. */
+ static final int PKTABLE_SCHEM = 2;
+
+ static final int PKTABLE_NAME = 3;
+
+ static final int PKCOLUMN_NAME = 4;
+
+ /** Position of column that contains catalog name of the foreignTable. */
+ static final int FKTABLE_CAT = 5;
+
+ /** Position of column that contains schema name of the foreignTable. */
+ static final int FKTABLE_SCHEM = 6;
+
+ static final int FKTABLE_NAME = 7;
+
+ static final int FKCOLUMN_NAME = 8;
+
+ static final int KEY_SEQ = 9;
+
+ /** Position of column that determines how forein key changes if PK is updated.
*/
+ static final int UPDATE_RULE = 10;
+
+ /** Position of column that determines how forein key changes if PK is deleted.
*/
+ static final int DELETE_RULE = 11;
+
+ static final int FK_NAME = 12;
+
+ static final int PK_NAME = 13;
+
+ /** Position of column that determines if forein key constraints can be deffered
until commit. */
+ static final int DEFERRABILITY = 14;
+ }
+
+ /**
+ * <p>This class contains constants representing column positions on ResultSet
+ * returned by getProcedures method on DatabaseMetaData. The class has constants
+ * for columns whose values are to be hardcoded in MMDatabaseMetaData object.
+ * <code>MAX_COLUMNS</code> is the number of columns to be read from
server's
+ * results from getElements method on <code>Metadata object</code>.
+ * <code>JAVA_CLASS</code> is the column position for element data type
on
+ * server's Results object.
+ */
+ interface PROCEDURES {
+
+ /** Number of columns to be read from results returned getCrossReferences method.
*/
+ static final int MAX_COLUMNS = 9;
+
+ /** Position of column that contains catalog name of the procedure. */
+ static final int PROCEDURE_CAT = 1;
+ static final int PROCEDURE_SCHEM = 2;
+ static final int PROCEDURE_NAME = 3;
+
+ /** Position of column the is reserved for future use. */
+ static final int RESERVED_1 = 4;
+
+ /** Position of column the is reserved for future use. */
+ static final int RESERVED_2 = 5;
+
+ /** Position of column the is reserved for future use. */
+ static final int RESERVED_3 = 6;
+
+ static final int REMARKS = 7;
+
+ /** Position of column Procedure type. */
+ static final int PROCEDURE_TYPE = 8;
+
+ static final int SPECIFIC_NAME = 9;
+ }
+
+ /**
+ * <p>This class contains constants representing column positions on ResultSet
+ * returned by getColumns method on DatabaseMetaData. The class has constants
+ * for columns whose values are to be hardcoded in MMDatabaseMetaData object.
+ * <code>MAX_COLUMNS</code> is the number of columns to be read from
server's
+ * results from getElements method on <code>Metadata object</code>.
+ * <code>JAVA_CLASS</code> is the column position for element data type
on
+ * server's Results object.
+ */
+ interface PROCEDURE_COLUMNS {
+
+ /** Number of columns to be read from results returned getProcedureColumns
method. */
+ static final int MAX_COLUMNS = 20;
+
+ /** Position of column that contains catalog name of the procedure. */
+ static final int PROCEDURE_CAT = 1;
+
+ static final int PROCEDURE_SCHEM = 2;
+ static final int PROCEDURE_NAME = 3;
+ static final int COLUMN_NAME = 4;
+
+ /** Position of the column containing column or element type. */
+ static final int COLUMN_TYPE = 5;
+
+ /** Position of column that contains SQL type from java.sql.Types for
column's data type. */
+ static final int DATA_TYPE = 6;
+
+ /** Position of column that contains local type name used by the data source. */
+ static final int TYPE_NAME = 7;
+
+ static final int PRECISION = 8;
+ static final int LENGTH = 9;
+ static final int SCALE = 10;
+ static final int RADIX = 11;
+
+ /** Position of column that contains the nullable value. */
+ static final int NULLABLE = 12;
+
+ /** Position of column that contains comments. */
+ static final int REMARKS = 13;
+ static final int COLUMN_DEF = 14;
+
+ static final int SQL_DATA_TYPE = 15;
+ static final int SQL_DATETIME_SUB = 16;
+ static final int CHAR_OCTET_LENGTH = 17;
+
+ static final int ORDINAL_POSITION = 18;
+
+ static final int IS_NULLABLE = 19;
+
+ static final int SPECIFIC_NAME = 20;
+ }
+
+ /**
+ * <p>This class contains constants representing column positions on ResultSet
+ * returned by getColumns method on DatabaseMetaData. The class also has constants
+ * for columns whose values are to be hardcoded in MMDatabaseMetaData object.
+ * <code>MAX_COLUMNS</code> is the number of columns to be read from
server's
+ * results from getElements method on <code>Metadata object</code>.
+ */
+ interface TABLE_PRIVILEGES {
+
+ /** Number of columns to be read from results returned getGroupEntitlements
method. */
+ static final int MAX_COLUMNS = 6;
+
+ /** Position of VirtualDatabaseName column in server's results object
returned by
+ getGroupEntitlements method in User API */
+ static final int VIRTUAL_DATABASE_NAME = 0;
+
+ /** Position of VirtualDatabaseVersion column in server's results object
returned by
+ getElementEntitlements method in User API */
+ static final int VIRTUAL_DATABASE_VERSION = 1;
+
+ /** Position of GroupName column in server's results object returned by
+ getGroupEntitlements method in User API */
+ static final int GROUP_NAME = 2;
+
+ /** Position of Grantor column in server's results object returned by
+ getGroupEntitlements method in User API */
+ static final int GRANTOR = 3;
+
+ /** Position of Grantee column in server's results object returned by
+ getGroupEntitlements method in User API */
+ static final int GRANTEE = 4;
+
+ /** Position of Permission column in server's results object returned by
+ getGroupEntitlements method in User API */
+ static final int PERMISSION = 5;
+
+ /** Position of the column containing catalog name info. */
+ static final int TABLE_CAT = 0;
+
+ /** Position of the column containing privilage grantable info. */
+ static final int IS_GRANTABLE = 6;
+ }
+
+ /**
+ * <p>This class contains constants representing column positions on ResultSet
+ * returned by getColumns method on DatabaseMetaData. The class also has constants
+ * for columns whose values are to be hardcoded in MMDatabaseMetaData object.
+ * <code>MAX_COLUMNS</code> is the number of columns to be read from
server's
+ * results from getElements method on <code>Metadata object</code>.
+ */
+ interface COLUMN_PRIVILEGES {
+
+ /** Number of columns to be read from results returned getElementEntitlements
method. */
+ static final int MAX_COLUMNS = 7;
+
+ /** Position of VirtualDatabaseName column in server's results object
returned by
+ getElementEntitlements method in User API */
+ static final int VIRTUAL_DATABASE_NAME = 0;
+
+ /** Position of VirtualDatabaseVersion column in server's results object
returned by
+ getElementEntitlements method in User API */
+ static final int VIRTUAL_DATABASE_VERSION = 1;
+
+ /** Position of GroupName column in server's results object returned by
+ getElementEntitlements method in User API */
+ static final int GROUP_NAME = 2;
+
+ /** Position of ElementName column in server's results object returned by
+ getElementEntitlements method in User API */
+ static final int ELEMENT_NAME = 3;
+
+ /** Position of Grantor column in server's results object returned by
+ getElementEntitlements method in User API */
+ static final int GRANTOR = 4;
+
+ /** Position of Grantee column in server's results object returned by
+ getElementEntitlements method in User API */
+ static final int GRANTEE = 5;
+
+ /** Position of Permission column in server's results object returned by
+ getElementEntitlements method in User API */
+ static final int PERMISSION = 6;
+
+ /** Position of the column containing catalog name info. */
+ static final int TABLE_CAT = 0;
+
+ /** Position of the column containing privilage grantable info. */
+ static final int IS_GRANTABLE = 7;
+ }
+
+}
Copied: trunk/client/src/main/java/org/teiid/jdbc/JDBCPlugin.java (from rev 1983,
trunk/client-jdbc/src/main/java/org/teiid/jdbc/JDBCPlugin.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/JDBCPlugin.java (rev
0)
+++ trunk/client/src/main/java/org/teiid/jdbc/JDBCPlugin.java 2010-03-22 21:01:44 UTC (rev
1986)
@@ -0,0 +1,39 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.util.ResourceBundle;
+import com.metamatrix.core.BundleUtil;
+
+/**
+ * JDBCPlugin
+ * <p>Used here in <code>jdbc</code> to have access to the new
+ * logging framework.</p>
+ */
+public class JDBCPlugin { // extends Plugin {
+
+ public static final String PLUGIN_ID = "org.teiid.jdbc" ; //$NON-NLS-1$
+
+ public static final BundleUtil Util = new BundleUtil(PLUGIN_ID,
+ PLUGIN_ID + ".i18n",
ResourceBundle.getBundle(PLUGIN_ID + ".i18n")); //$NON-NLS-1$ //$NON-NLS-2$
+}
Copied: trunk/client/src/main/java/org/teiid/jdbc/JDBCURL.java (from rev 1983,
trunk/client-jdbc/src/main/java/org/teiid/jdbc/JDBCURL.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/JDBCURL.java (rev
0)
+++ trunk/client/src/main/java/org/teiid/jdbc/JDBCURL.java 2010-03-22 21:01:44 UTC (rev
1986)
@@ -0,0 +1,324 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+
+import org.teiid.net.TeiidURL;
+
+
+
+
+
+
+/**
+ * @since 4.3
+ */
+public class JDBCURL {
+ private static final String UTF_8 = "UTF-8"; //$NON-NLS-1$
+ public static final String JDBC_PROTOCOL = "jdbc:teiid:"; //$NON-NLS-1$
+ private static final String OLD_JDBC_PROTOCOL = "jdbc:metamatrix:";
//$NON-NLS-1$
+
+ public static final String[] KNOWN_PROPERTIES = {
+ BaseDataSource.APP_NAME,
+ BaseDataSource.VDB_NAME,
+ BaseDataSource.VERSION,
+ BaseDataSource.VDB_VERSION,
+ BaseDataSource.USER_NAME,
+ BaseDataSource.PASSWORD,
+ ExecutionProperties.PROP_TXN_AUTO_WRAP,
+ ExecutionProperties.PROP_PARTIAL_RESULTS_MODE,
+ ExecutionProperties.RESULT_SET_CACHE_MODE,
+ ExecutionProperties.ANSI_QUOTED_IDENTIFIERS,
+ ExecutionProperties.PROP_SQL_OPTIONS,
+ ExecutionProperties.PROP_FETCH_SIZE,
+ ExecutionProperties.PROP_XML_FORMAT,
+ ExecutionProperties.PROP_XML_VALIDATION,
+ ExecutionProperties.DISABLE_LOCAL_TRANSACTIONS,
+ TeiidURL.CONNECTION.AUTO_FAILOVER,
+ TeiidURL.CONNECTION.DISCOVERY_STRATEGY
+ };
+
+ private String vdbName;
+ private String connectionURL;
+ private Properties properties = new Properties();
+
+ private String urlString;
+
+ public JDBCURL(String jdbcURL) {
+ parseURL(jdbcURL);
+ }
+
+ public JDBCURL(String vdbName, String connectionURL, Properties props) {
+ if (vdbName == null || vdbName.trim().length() == 0) {
+ throw new IllegalArgumentException();
+ }
+ this.vdbName = vdbName;
+ this.connectionURL = connectionURL;
+ if (props != null) {
+ normalizeProperties(props, this.properties);
+ }
+ }
+
+ public String getVDBName() {
+ return vdbName;
+ }
+
+ public String getConnectionURL() {
+ return connectionURL;
+ }
+
+ public Properties getProperties() {
+ // Make a copy of the properties object, including any non-string values that may
be contained in the map.
+ Properties newProps = new Properties();
+ newProps.putAll(this.properties);
+ return newProps;
+ }
+
+ private void parseURL(String jdbcURL) {
+ if (jdbcURL == null) {
+ throw new IllegalArgumentException();
+ }
+ // Trim extra spaces
+ jdbcURL = jdbcURL.trim();
+ if (jdbcURL.length() == 0) {
+ throw new IllegalArgumentException();
+ }
+ int delimiter = jdbcURL.indexOf('@');
+ if (delimiter == -1) {
+ // this is for default connection protocol in embedded driver.
+ // then go by first semi colon
+ int fsc = jdbcURL.indexOf(';');
+ if (fsc == -1) {
+ parseJDBCProtocol(jdbcURL);
+ }
+ else {
+ parseJDBCProtocol(jdbcURL.substring(0, fsc));
+ parseConnectionProperties(jdbcURL.substring(fsc+1), this.properties);
+ }
+ }
+ else {
+ String[] urlParts = jdbcURL.split("@", 2); //$NON-NLS-1$
+ if (urlParts.length != 2) {
+ throw new IllegalArgumentException();
+ }
+ parseJDBCProtocol(urlParts[0]);
+ parseConnectionPart(urlParts[1]);
+ }
+ }
+
+ private void parseJDBCProtocol(String protocol) {
+ if (protocol.startsWith(JDBC_PROTOCOL)) {
+ if (protocol.length() == JDBC_PROTOCOL.length()) {
+ throw new IllegalArgumentException();
+ }
+ vdbName = protocol.substring(JDBC_PROTOCOL.length());
+ }
+ else if (protocol.startsWith(OLD_JDBC_PROTOCOL)) {
+ if (protocol.length() == OLD_JDBC_PROTOCOL.length()) {
+ throw new IllegalArgumentException();
+ }
+ vdbName = protocol.substring(OLD_JDBC_PROTOCOL.length());
+ }
+ else {
+ throw new IllegalArgumentException();
+ }
+
+ }
+
+ private void parseConnectionPart(String connectionInfo) {
+ String[] connectionParts = connectionInfo.split(";"); //$NON-NLS-1$
+ if (connectionParts.length == 0 || connectionParts[0].trim().length() == 0) {
+ throw new IllegalArgumentException();
+ }
+ connectionURL = connectionParts[0].trim();
+ if (connectionParts.length > 1) {
+ // The rest should be connection params
+ for (int i = 1; i < connectionParts.length; i++) {
+ parseConnectionProperty(connectionParts[i], this.properties);
+ }
+ }
+ }
+
+ public static void parseConnectionProperties(String connectionInfo, Properties p) {
+ String[] connectionParts = connectionInfo.split(";"); //$NON-NLS-1$
+ if (connectionParts.length != 0) {
+ // The rest should be connection params
+ for (int i = 0; i < connectionParts.length; i++) {
+ parseConnectionProperty(connectionParts[i], p);
+ }
+ }
+ }
+
+ static void parseConnectionProperty(String connectionProperty, Properties p) {
+ if (connectionProperty.length() == 0) {
+ // Be tolerant of double-semicolons and dangling semicolons
+ return;
+ } else if(connectionProperty.length() < 3) {
+ // key=value must have at least 3 characters
+ throw new IllegalArgumentException();
+ }
+ int firstEquals = connectionProperty.indexOf('=');
+ if(firstEquals < 1) {
+ throw new IllegalArgumentException();
+ }
+ String key = connectionProperty.substring(0, firstEquals).trim();
+ String value = connectionProperty.substring(firstEquals+1).trim();
+ if(value.indexOf('=') >= 0) {
+ throw new IllegalArgumentException();
+ }
+ addNormalizedProperty(key, getValidValue(value), p);
+ }
+
+ public String getJDBCURL() {
+ if (urlString == null) {
+ StringBuffer buf = new StringBuffer(JDBC_PROTOCOL)
+ .append(vdbName);
+ if (this.connectionURL != null) {
+ buf.append('(a)').append(connectionURL);
+ }
+ for (Iterator i = properties.entrySet().iterator(); i.hasNext();) {
+ Map.Entry entry = (Map.Entry)i.next();
+ if (entry.getValue() instanceof String) {
+ // get only the string properties, because a non-string property
could not have been set on the url.
+ buf.append(';')
+ .append(entry.getKey())
+ .append('=')
+ .append(entry.getValue());
+ }
+ }
+ urlString = buf.toString();
+ }
+ return urlString;
+ }
+
+ public String getProperty(String key) {
+ return properties.getProperty(key);
+ }
+
+ public String getUserName() {
+ return properties.getProperty(BaseDataSource.USER_NAME);
+ }
+
+ public String getPassword() {
+ return properties.getProperty(BaseDataSource.PASSWORD);
+ }
+
+ public String getVDBVersion() {
+ if (properties.contains(BaseDataSource.VDB_VERSION)) {
+ return properties.getProperty(BaseDataSource.VDB_VERSION);
+ }
+ return properties.getProperty(BaseDataSource.VERSION);
+ }
+
+ public String getTransactionAutowrapMode() {
+ return properties.getProperty(ExecutionProperties.PROP_TXN_AUTO_WRAP);
+ }
+
+ public String getPartialResultsMode() {
+ return properties.getProperty(ExecutionProperties.PROP_PARTIAL_RESULTS_MODE);
+ }
+
+ public String getResultSetCacheMode() {
+ return properties.getProperty(ExecutionProperties.RESULT_SET_CACHE_MODE);
+ }
+
+ public String getAnsiQuotedIdentifiers() {
+ return properties.getProperty(ExecutionProperties.ANSI_QUOTED_IDENTIFIERS);
+ }
+
+ public String getSQLOptions() {
+ return properties.getProperty(ExecutionProperties.PROP_SQL_OPTIONS);
+ }
+
+ public String getFetchSize() {
+ return properties.getProperty(ExecutionProperties.PROP_FETCH_SIZE);
+ }
+
+ public String getXMLFormat() {
+ return properties.getProperty(ExecutionProperties.PROP_XML_FORMAT);
+ }
+
+ public String getXMLValidation() {
+ return properties.getProperty(ExecutionProperties.PROP_XML_VALIDATION);
+ }
+
+ public String getTransparentFailover() {
+ return properties.getProperty(TeiidURL.CONNECTION.AUTO_FAILOVER);
+ }
+
+ public String getDisableLocalTransactions() {
+ return properties.getProperty(ExecutionProperties.DISABLE_LOCAL_TRANSACTIONS);
+ }
+
+ public String toString() {
+ return getJDBCURL();
+ }
+
+ private static void normalizeProperties(Properties source, Properties target) {
+ for (Enumeration e = source.propertyNames(); e.hasMoreElements();) {
+ String key = (String)e.nextElement();
+ addNormalizedProperty(key, source.get(key), target);
+ }
+ }
+
+ private static void addNormalizedProperty(String key, Object value, Properties
target) {
+ String validKey = getValidKey(key);
+
+ // now add the normalized key and value into the properties object.
+ target.put(validKey, value);
+ }
+
+ private static String getValidKey(String key) {
+ // figure out the valid key based on its case
+ for (int i = 0; i < KNOWN_PROPERTIES.length; i++) {
+ if (key.equalsIgnoreCase(KNOWN_PROPERTIES[i])) {
+ return KNOWN_PROPERTIES[i];
+ }
+ }
+ return key;
+ }
+
+ private static Object getValidValue(Object value) {
+ if (value instanceof String) {
+ try {
+ // Decode the value of the property if incase they were encoded.
+ return URLDecoder.decode((String)value, UTF_8);
+ } catch (UnsupportedEncodingException e) {
+ // use the original value
+ }
+ }
+ return value;
+ }
+
+ public static Properties normalizeProperties(Properties props) {
+ normalizeProperties(props, props);
+ return props;
+ }
+
+}
Copied: trunk/client/src/main/java/org/teiid/jdbc/MetadataProvider.java (from rev 1983,
trunk/client-jdbc/src/main/java/org/teiid/jdbc/MetadataProvider.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/MetadataProvider.java
(rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/MetadataProvider.java 2010-03-22 21:01:44
UTC (rev 1986)
@@ -0,0 +1,65 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.SQLException;
+import java.util.Map;
+
+
+/**
+ */
+public class MetadataProvider {
+
+ // Map of detail maps -- <columnIndex, Map<propertyName,
metadataObject>>
+ protected Map[] metadata;
+
+ public MetadataProvider(Map[] metadata) {
+ this.metadata = metadata;
+ }
+
+ public Object getValue(int columnIndex, Integer metadataPropertyKey) throws
SQLException {
+ if(columnIndex < 0 || columnIndex >= metadata.length) {
+ throw new
SQLException(JDBCPlugin.Util.getString("StaticMetadataProvider.Invalid_column",
columnIndex)); //$NON-NLS-1$
+ }
+
+ Map column = this.metadata[columnIndex];
+ return column.get(metadataPropertyKey);
+ }
+
+ public int getColumnCount() throws SQLException {
+ return metadata.length;
+ }
+
+ public String getStringValue(int columnIndex, Integer metadataPropertyKey) throws
SQLException {
+ return (String) getValue(columnIndex, metadataPropertyKey);
+ }
+
+ public int getIntValue(int columnIndex, Integer metadataPropertyKey) throws
SQLException {
+ return ((Integer) getValue(columnIndex, metadataPropertyKey)).intValue();
+ }
+
+ public boolean getBooleanValue(int columnIndex, Integer metadataPropertyKey) throws
SQLException {
+ return ((Boolean) getValue(columnIndex, metadataPropertyKey)).booleanValue();
+ }
+
+}
Copied: trunk/client/src/main/java/org/teiid/jdbc/ParameterMetaDataImpl.java (from rev
1983, trunk/client-jdbc/src/main/java/org/teiid/jdbc/ParameterMetaDataImpl.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/ParameterMetaDataImpl.java
(rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/ParameterMetaDataImpl.java 2010-03-22
21:01:44 UTC (rev 1986)
@@ -0,0 +1,89 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.CallableStatement;
+import java.sql.ParameterMetaData;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+import com.metamatrix.common.types.MMJDBCSQLTypeInfo;
+
+/**
+ * Note: this is currently only accurate for {@link PreparedStatement}s.
+ * Only the basic type information will be accurate for {@link CallableStatement}s.
+ */
+public class ParameterMetaDataImpl extends WrapperImpl implements ParameterMetaData {
+
+ private ResultSetMetaDataImpl metadata;
+
+ public ParameterMetaDataImpl(ResultSetMetaDataImpl metadata) {
+ this.metadata = metadata;
+ }
+
+ @Override
+ public String getParameterClassName(int param) throws SQLException {
+ return MMJDBCSQLTypeInfo.getJavaClassName(getParameterType(param));
+ }
+
+ @Override
+ public int getParameterCount() throws SQLException {
+ return metadata.getColumnCount();
+ }
+
+ @Override
+ public int getParameterMode(int param) throws SQLException {
+ return parameterModeUnknown;
+ }
+
+ @Override
+ public int getParameterType(int param) throws SQLException {
+ return metadata.getColumnType(param);
+ }
+
+ @Override
+ public String getParameterTypeName(int param) throws SQLException {
+ return metadata.getColumnTypeName(param);
+ }
+
+ @Override
+ public int getPrecision(int param) throws SQLException {
+ return metadata.getPrecision(param);
+ }
+
+ @Override
+ public int getScale(int param) throws SQLException {
+ return metadata.getScale(param);
+ }
+
+ @Override
+ public int isNullable(int param) throws SQLException {
+ return metadata.isNullable(param);
+ }
+
+ @Override
+ public boolean isSigned(int param) throws SQLException {
+ return metadata.isSigned(param);
+ }
+
+}
Property changes on: trunk/client/src/main/java/org/teiid/jdbc/ParameterMetaDataImpl.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Copied: trunk/client/src/main/java/org/teiid/jdbc/PartialResultsWarning.java (from rev
1983, trunk/client-jdbc/src/main/java/org/teiid/jdbc/PartialResultsWarning.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/PartialResultsWarning.java
(rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/PartialResultsWarning.java 2010-03-22
21:01:44 UTC (rev 1986)
@@ -0,0 +1,114 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+
+/**
+ * This warning class is sent when using partial results mode if one or more
+ * sources fails. In this case, results will be returned (with 0 rows sent from
+ * failing source). This warning can be obtained from the ResultSet to determine
+ * which sources failed and provided 0 rows and why they failed.
+ */
+public class PartialResultsWarning extends SQLWarning {
+
+ private static final long serialVersionUID = 5301215068719177369L;
+ private Map failures;
+
+ /**
+ * Construct partial results warning.
+ * @param reason Reason for the exception
+ * @param SQLstate SQL state code
+ * @param vendorCode Vendor code
+ */
+ public PartialResultsWarning(String reason, String SQLstate, int vendorCode) {
+ super(reason, SQLstate, vendorCode);
+ }
+
+ /**
+ * Construct partial results warning.
+ * @param reason Reason for the exception
+ * @param SQLstate SQL state code
+ */
+ public PartialResultsWarning(String reason, String SQLstate) {
+ super(reason, SQLstate);
+ }
+
+ /**
+ * Construct partial results warning.
+ * @param reason Reason for the exception
+ */
+ public PartialResultsWarning(String reason) {
+ super(reason);
+ }
+
+ /**
+ * Construct partial results warning.
+ */
+ public PartialResultsWarning() {
+ super();
+ }
+
+ /**
+ * Add a connector failure to the warning
+ * @param name Connector name
+ * @param exception Connector exception
+ */
+ public void addConnectorFailure(String name, SQLException exception) {
+ if(this.failures == null) {
+ this.failures = new HashMap();
+ }
+ this.failures.put(name, exception);
+ }
+
+ /**
+ * Obtain list of connectors that failed.
+ * @return List of connectors that failed - List contains String names
+ */
+ public Collection getFailedConnectors() {
+ if(this.failures != null) {
+ return new HashSet(this.failures.keySet());
+ }
+ return Collections.EMPTY_SET;
+ }
+
+ /**
+ * Obtain failure for a particular connector.
+ * @param name Connector name
+ * @return Exception that occurred for this connector or null if
+ * the exception was unknown
+ */
+ public SQLException getConnectorException(String connectorName) {
+ if(this.failures != null) {
+ return (SQLException) this.failures.get(connectorName);
+ }
+ return null;
+ }
+
+}
Copied: trunk/client/src/main/java/org/teiid/jdbc/PreparedStatementImpl.java (from rev
1983, trunk/client-jdbc/src/main/java/org/teiid/jdbc/PreparedStatementImpl.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/PreparedStatementImpl.java
(rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/PreparedStatementImpl.java 2010-03-22
21:01:44 UTC (rev 1986)
@@ -0,0 +1,787 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.NClob;
+import java.sql.ParameterMetaData;
+import java.sql.PreparedStatement;
+import java.sql.Ref;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.RowId;
+import java.sql.SQLException;
+import java.sql.SQLXML;
+import java.sql.Types;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.TimeZone;
+import java.util.TreeMap;
+
+import javax.sql.rowset.serial.SerialBlob;
+import javax.sql.rowset.serial.SerialClob;
+
+import org.teiid.client.RequestMessage;
+import org.teiid.client.RequestMessage.ResultsMode;
+import org.teiid.client.RequestMessage.StatementType;
+import org.teiid.client.metadata.MetadataResult;
+
+
+
+import com.metamatrix.api.exception.MetaMatrixComponentException;
+import com.metamatrix.api.exception.MetaMatrixProcessingException;
+import com.metamatrix.common.types.MMJDBCSQLTypeInfo;
+import com.metamatrix.common.util.SqlUtil;
+import com.metamatrix.common.util.TimestampWithTimezone;
+import com.metamatrix.core.util.ArgCheck;
+import com.metamatrix.core.util.ObjectConverterUtil;
+
+/**
+ * <p> Instances of PreparedStatement contain a SQL statement that has already
been
+ * compiled. The SQL statement contained in a PreparedStatement object may have
+ * one or more IN parameters. An IN parameter is a parameter whose value is not
+ * specified when a SQL statement is created. Instead the statement has a placeholder
+ * for each IN parameter.</p>
+ * <p> The MMPreparedStatement object wraps the server's PreparedStatement
object.
+ * The methods in this class are used to set the IN parameters on a server's
+ * preparedstatement object.</p>
+ */
+
+public class PreparedStatementImpl extends StatementImpl implements PreparedStatement {
+ // sql, which this prepared statement is operating on
+ protected String prepareSql;
+
+ //map that holds parameter index to values for prepared statements
+ private Map<Integer, Object> parameterMap;
+
+ //a list of map that holds parameter index to values for prepared statements
+ protected List<List<Object>> batchParameterList;
+
+ // metadata
+ private MetadataResult metadataResults;
+ private ResultSetMetaData metadata;
+ private ParameterMetaData parameterMetaData;
+
+ private Calendar serverCalendar;
+
+ /**
+ * Factory Constructor
+ * @param connection
+ * @param sql
+ * @param resultSetType
+ * @param resultSetConcurrency
+ */
+ static PreparedStatementImpl newInstance(ConnectionImpl connection, String sql, int
resultSetType, int resultSetConcurrency) throws SQLException {
+ return new PreparedStatementImpl(connection, sql, resultSetType,
resultSetConcurrency);
+ }
+
+ /**
+ * <p>MMPreparedStatement constructor.
+ * @param Driver's connection object.
+ * @param String object representing the prepared statement
+ */
+ PreparedStatementImpl(ConnectionImpl connection, String sql, int resultSetType, int
resultSetConcurrency) throws SQLException {
+ super(connection, resultSetType, resultSetConcurrency);
+
+ // this sql is for callable statement, don't check any more
+ ArgCheck.isNotNull(sql,
JDBCPlugin.Util.getString("MMPreparedStatement.Err_prep_sql")); //$NON-NLS-1$
+ this.prepareSql = sql;
+
+ TimeZone timezone =
connection.getServerConnection().getLogonResult().getTimeZone();
+
+ if (timezone != null &&
!timezone.hasSameRules(getDefaultCalendar().getTimeZone())) {
+ this.serverCalendar = Calendar.getInstance(timezone);
+ }
+ }
+
+ /**
+ * <p>Adds a set of parameters to this PreparedStatement object's list of
commands
+ * to be sent to the database for execution as a batch.
+ * @throws SQLException if there is an error
+ */
+ public void addBatch() throws SQLException {
+ checkStatement();
+ if(batchParameterList == null){
+ batchParameterList = new ArrayList<List<Object>>();
+ }
+ batchParameterList.add(getParameterValues());
+ clearParameters();
+ }
+
+ /**
+ * Makes the set of commands in the current batch empty.
+ *
+ * @throws SQLException if a database access error occurs or the
+ * driver does not support batch statements
+ */
+ public void clearBatch() throws SQLException {
+ if (batchParameterList != null ) {
+ batchParameterList.clear();
+ }
+ }
+
+ /**
+ * <p>Clears the values set for the PreparedStatement object's IN
parameters and
+ * releases the resources used by those values. In general, parameter values
+ * remain in force for repeated use of statement.
+ * @throws SQLException if there is an error while clearing params
+ */
+ public void clearParameters() throws SQLException {
+ checkStatement();
+ //clear the parameters list on servers prepared statement object
+ if(parameterMap != null){
+ parameterMap.clear();
+ }
+ }
+
+ @Override
+ public boolean execute(String sql) throws SQLException {
+ String msg = JDBCPlugin.Util.getString("JDBC.Method_not_supported");
//$NON-NLS-1$
+ throw new TeiidSQLException(msg);
+ }
+
+ @Override
+ public ResultSet executeQuery(String sql) throws SQLException {
+ String msg = JDBCPlugin.Util.getString("JDBC.Method_not_supported");
//$NON-NLS-1$
+ throw new TeiidSQLException(msg);
+ }
+
+ @Override
+ public int executeUpdate(String sql) throws SQLException {
+ String msg = JDBCPlugin.Util.getString("JDBC.Method_not_supported");
//$NON-NLS-1$
+ throw new TeiidSQLException(msg);
+ }
+
+ @Override
+ public void addBatch(String sql) throws SQLException {
+ String msg = JDBCPlugin.Util.getString("JDBC.Method_not_supported");
//$NON-NLS-1$
+ throw new TeiidSQLException(msg);
+ }
+
+ //## JDBC4.0-begin ##
+ @Override
+ //## JDBC4.0-end ##
+ public boolean execute() throws SQLException {
+ executeSql(new String[] {this.prepareSql}, false, ResultsMode.EITHER);
+ return hasResultSet();
+ }
+
+ @Override
+ public int[] executeBatch() throws SQLException {
+ if (batchParameterList == null || batchParameterList.isEmpty()) {
+ return new int[0];
+ }
+ try{
+ executeSql(new String[] {this.prepareSql}, true, ResultsMode.UPDATECOUNT);
+ }finally{
+ batchParameterList.clear();
+ }
+ return this.updateCounts;
+ }
+
+ //## JDBC4.0-begin ##
+ @Override
+ //## JDBC4.0-end ##
+ public ResultSet executeQuery() throws SQLException {
+ executeSql(new String[] {this.prepareSql}, false, ResultsMode.RESULTSET);
+ return resultSet;
+ }
+
+ //## JDBC4.0-begin ##
+ @Override
+ //## JDBC4.0-end ##
+ public int executeUpdate() throws SQLException {
+ executeSql(new String[] {this.prepareSql}, false, ResultsMode.UPDATECOUNT);
+ return this.updateCounts[0];
+ }
+
+ @Override
+ protected RequestMessage createRequestMessage(String[] commands,
+ boolean isBatchedCommand, ResultsMode resultsMode) {
+ RequestMessage message = super.createRequestMessage(commands, false, resultsMode);
+ message.setStatementType(StatementType.PREPARED);
+ message.setParameterValues(isBatchedCommand?getParameterValuesList():
getParameterValues());
+ message.setBatchedUpdate(isBatchedCommand);
+ return message;
+ }
+
+ /**
+ * <p>Retreives a ResultSetMetaData object with information about the numbers,
+ * types, and properties of columns in the ResultSet object that will be returned
+ * when this preparedstatement object is executed.
+ * @return ResultSetMetaData object
+ * @throws SQLException, currently there is no means of getting results
+ * metadata before getting results.
+ */
+ public ResultSetMetaData getMetaData() throws SQLException {
+
+ // check if the statement is open
+ checkStatement();
+
+ if(metadata == null) {
+ if (updateCounts != null) {
+ return null;
+ } else if(resultSet != null) {
+ metadata = resultSet.getMetaData();
+ } else {
+ if (getMetadataResults().getColumnMetadata() == null) {
+ return null;
+ }
+ MetadataProvider provider = new
MetadataProvider(getMetadataResults().getColumnMetadata());
+ metadata = new ResultSetMetaDataImpl(provider);
+ }
+ }
+
+ return metadata;
+ }
+
+ private MetadataResult getMetadataResults() throws TeiidSQLException {
+ if (metadataResults == null) {
+ try {
+ metadataResults = this.getDQP().getMetadata(this.currentRequestID, prepareSql,
Boolean.valueOf(getExecutionProperty(ExecutionProperties.ANSI_QUOTED_IDENTIFIERS)).booleanValue());
+ } catch (MetaMatrixComponentException e) {
+ throw TeiidSQLException.create(e);
+ } catch (MetaMatrixProcessingException e) {
+ throw TeiidSQLException.create(e);
+ }
+ }
+ return metadataResults;
+ }
+
+ public void setAsciiStream (int parameterIndex, java.io.InputStream in, int length)
throws SQLException {
+ //create a clob from the ascii stream
+ try {
+ setObject(parameterIndex, new SerialClob(ObjectConverterUtil.convertToCharArray(in,
length, "ASCII"))); //$NON-NLS-1$
+ } catch (IOException e) {
+ throw TeiidSQLException.create(e);
+ }
+ }
+
+ /**
+ * <p>Sets the IN parameter at paramaterIndex to a BigDecimal object. The
parameter
+ * type is set to NUMERIC
+ * @param parameterIndex of the parameter whose value is to be set
+ * @param BigDecimal object to which the parameter value is to be set.
+ * @throws SQLException, should not occur
+ */
+ public void setBigDecimal (int parameterIndex, java.math.BigDecimal value) throws
SQLException {
+ setObject(parameterIndex, value);
+ }
+
+ public void setBinaryStream(int parameterIndex, java.io.InputStream in, int length)
throws SQLException {
+ //create a blob from the ascii stream
+ try {
+ setObject(parameterIndex, new SerialBlob(ObjectConverterUtil.convertToByteArray(in,
length)));
+ } catch (IOException e) {
+ throw TeiidSQLException.create(e);
+ }
+ }
+
+ /**
+ * <p>Sets the parameter in position parameterIndex to a Blob object.
+ * @param parameterIndex of the parameter whose value is to be set
+ * @param Blob object to which the parameter value is to be set.
+ * @throws SQLException if parameter type/datatype do not match
+ */
+ public void setBlob (int parameterIndex, Blob x) throws SQLException {
+ setObject(parameterIndex, x);
+ }
+
+ /**
+ * <p>Sets parameter number parameterIndex to b, a Java boolean value. The
parameter
+ * type is set to BIT
+ * @param parameterIndex of the parameter whose value is to be set
+ * @param boolean value to which the parameter value is to be set.
+ * @throws SQLException, if parameter type/datatype do not match
+ */
+ public void setBoolean (int parameterIndex, boolean value) throws SQLException {
+ setObject(parameterIndex, new Boolean(value));
+ }
+
+ /**
+ * <p>Sets parameter number parameterIndex to x, a Java byte value. The
parameter
+ * type is set to TINYINT
+ * @param parameterIndex of the parameter whose value is to be set
+ * @param byte value to which the parameter value is to be set.
+ * @throws SQLException, if parameter type/datatype do not match
+ */
+ public void setByte(int parameterIndex, byte value) throws SQLException {
+ setObject(parameterIndex, new Byte(value));
+ }
+
+ /**
+ * <p>Sets parameter number parameterIndex to x[], a Java array of bytes.
+ * @param parameterIndex of the parameter whose value is to be set
+ * @param bytes array to which the parameter value is to be set.
+ */
+ public void setBytes(int parameterIndex, byte bytes[]) throws SQLException {
+ //create a blob from the ascii stream
+ setObject(parameterIndex, new SerialBlob(bytes));
+ }
+
+ public void setCharacterStream (int parameterIndex, java.io.Reader reader, int
length) throws SQLException {
+ //create a clob from the ascii stream
+ try {
+ setObject(parameterIndex, new
SerialClob(ObjectConverterUtil.convertToCharArray(reader, length)));
+ } catch (IOException e) {
+ throw TeiidSQLException.create(e);
+ }
+ }
+
+ /**
+ * <p>Sets the parameter in position parameterIndex to a Clob object.
+ * @param parameterIndex of the parameter whose value is to be set
+ * @param Clob object to which the parameter value is to be set.
+ * @throws SQLException if parameter type/datatype do not match.
+ */
+ public void setClob (int parameterIndex, Clob x) throws SQLException {
+ setObject(parameterIndex, x);
+ }
+
+ /**
+ * <p>Sets parameter number parameterIndex to x, a java.sql.Date object. The
parameter
+ * type is set to DATE
+ * @param parameterIndex of the parameter whose value is to be set
+ * @param Date object to which the parameter value is to be set.
+ * @throws SQLException, if parameter type/datatype do not match
+ */
+ public void setDate(int parameterIndex, java.sql.Date value) throws SQLException {
+ setDate(parameterIndex, value, null);
+ }
+
+ /**
+ * <p>Sets parameter number parameterIndex to x, a java.sql.Date object. The
parameter
+ * type is set to DATE
+ * @param parameterIndex of the parameter whose value is to be set
+ * @param Date object to which the parameter value is to be set.
+ * @param Calendar object to constrct date(useful to get include timezone info)
+ * @throws SQLException, if parameter type/datatype do not match
+ */
+ public void setDate(int parameterIndex, java.sql.Date x ,java.util.Calendar cal)
throws SQLException {
+
+ if (cal == null || x == null) {
+ setObject(parameterIndex, x);
+ return;
+ }
+
+ // set the parameter on the stored procedure
+ setObject(parameterIndex, TimestampWithTimezone.createDate(x, cal.getTimeZone(),
getDefaultCalendar()));
+ }
+
+ /**
+ * <p>Sets parameter number parameterIndex to x, a double value. The parameter
+ * type is set to DOUBLE
+ * @param parameterIndex of the parameter whose value is to be set
+ * @param double value to which the parameter value is to be set.
+ * @throws SQLException, if parameter type/datatype do not match
+ */
+ public void setDouble(int parameterIndex, double value) throws SQLException {
+ setObject(parameterIndex, new Double(value));
+ }
+
+ /**
+ * <p>Sets parameter number parameterIndex to value, a float value. The
parameter
+ * type is set to FLOAT
+ * @param parameterIndex of the parameter whose value is to be set
+ * @param float value to which the parameter value is to be set.
+ * @throws SQLException, if parameter type/datatype do not match
+ */
+ public void setFloat(int parameterIndex, float value) throws SQLException {
+ setObject(parameterIndex, new Float(value));
+ }
+
+ /**
+ * <p>Sets parameter number parameterIndex to value, a int value. The
parameter
+ * type is set to INTEGER
+ * @param parameterIndex of the parameter whose value is to be set
+ * @param int value to which the parameter value is to be set.
+ * @throws SQLException, if parameter type/datatype do not match
+ */
+ public void setInt(int parameterIndex, int value) throws SQLException {
+ setObject(parameterIndex, new Integer(value));
+ }
+
+ /**
+ * <p>Sets parameter number parameterIndex to x, a long value. The parameter
+ * type is set to BIGINT
+ * @param parameterIndex of the parameter whose value is to be set
+ * @param long value to which the parameter value is to be set.
+ * @throws SQLException, if parameter type/datatype do not match
+ */
+ public void setLong(int parameterIndex, long value) throws SQLException {
+ setObject(parameterIndex, new Long(value));
+ }
+
+ /**
+ * <p>Sets parameter number parameterIndex to a null value.
+ * @param parameterIndex of the parameter whose value is to be set
+ * @param jdbc type of the parameter whose value is to be set to null
+ * @throws SQLException, if parameter type/datatype do not match
+ */
+ public void setNull(int parameterIndex, int jdbcType) throws SQLException {
+ setObject(parameterIndex, null);
+ }
+
+ /**
+ * <p>Sets parameter number parameterIndex to a null value.
+ * @param parameterIndex of the parameter whose value is to be set
+ * @param jdbc type of the parameter whose value is to be set to null
+ * @param fully qualifies typename of the parameter being set.
+ * @throws SQLException, if parameter type/datatype do not match
+ */
+ public void setNull(int parameterIndex, int jdbcType, String typeName) throws
SQLException {
+ setObject(parameterIndex, null);
+ }
+
+ /**
+ * <p>Sets parameter number parameterIndex to an object value
+ * @param parameterIndex of the parameter whose value is to be set
+ * @param an object value to which the parameter value is to be set.
+ * @param int value giving the JDBC type to conver the object to
+ * @param int value giving the scale to be set if the type is DECIMAL or NUMERIC
+ * @throws SQLException, if there is an error setting the parameter value
+ */
+ public void setObject (int parameterIndex, Object value, int targetJdbcType, int
scale) throws SQLException {
+
+ if(value == null) {
+ setObject(parameterIndex, null);
+ return;
+ }
+
+ if(targetJdbcType != Types.DECIMAL || targetJdbcType != Types.NUMERIC) {
+ setObject(parameterIndex, value, targetJdbcType);
+ // Decimal and NUMERIC types correspong to java.math.BigDecimal
+ } else {
+ // transform the object to a BigDecimal
+ BigDecimal bigDecimalObject = DataTypeTransformer.getBigDecimal(value);
+ // set scale on the BigDecimal
+ bigDecimalObject.setScale(scale);
+
+ setObject(parameterIndex, bigDecimalObject);
+ }
+ }
+
+ public void setObject(int parameterIndex, Object value, int targetJdbcType) throws
SQLException {
+
+ Object targetObject = null;
+
+ if(value == null) {
+ setObject(parameterIndex, null);
+ return;
+ }
+
+ // get the java class name for the given JDBC type
+ String javaClassName = MMJDBCSQLTypeInfo.getJavaClassName(targetJdbcType);
+ // transform the value to the target datatype
+ if(javaClassName.equalsIgnoreCase(MMJDBCSQLTypeInfo.STRING_CLASS)) {
+ targetObject = value.toString();
+ } else if(javaClassName.equalsIgnoreCase(MMJDBCSQLTypeInfo.CHAR_CLASS)) {
+ targetObject = DataTypeTransformer.getCharacter(value);
+ } else if(javaClassName.equalsIgnoreCase(MMJDBCSQLTypeInfo.INTEGER_CLASS)) {
+ targetObject = DataTypeTransformer.getInteger(value);
+ } else if(javaClassName.equalsIgnoreCase(MMJDBCSQLTypeInfo.BYTE_CLASS)) {
+ targetObject = DataTypeTransformer.getByte(value);
+ } else if(javaClassName.equalsIgnoreCase(MMJDBCSQLTypeInfo.SHORT_CLASS)) {
+ targetObject = DataTypeTransformer.getShort(value);
+ } else if(javaClassName.equalsIgnoreCase(MMJDBCSQLTypeInfo.LONG_CLASS)) {
+ targetObject = DataTypeTransformer.getLong(value);
+ } else if(javaClassName.equalsIgnoreCase(MMJDBCSQLTypeInfo.FLOAT_CLASS)) {
+ targetObject = DataTypeTransformer.getFloat(value);
+ } else if(javaClassName.equalsIgnoreCase(MMJDBCSQLTypeInfo.DOUBLE_CLASS)) {
+ targetObject = DataTypeTransformer.getDouble(value);
+ } else if(javaClassName.equalsIgnoreCase(MMJDBCSQLTypeInfo.BOOLEAN_CLASS)) {
+ targetObject = DataTypeTransformer.getBoolean(value);
+ } else if(javaClassName.equalsIgnoreCase(MMJDBCSQLTypeInfo.BIGDECIMAL_CLASS)) {
+ targetObject = DataTypeTransformer.getBigDecimal(value);
+ } else if(javaClassName.equalsIgnoreCase(MMJDBCSQLTypeInfo.TIMESTAMP_CLASS)) {
+ targetObject = DataTypeTransformer.getTimestamp(value);
+ } else if(javaClassName.equalsIgnoreCase(MMJDBCSQLTypeInfo.DATE_CLASS)) {
+ targetObject = DataTypeTransformer.getDate(value);
+ } else if(javaClassName.equalsIgnoreCase(MMJDBCSQLTypeInfo.TIME_CLASS)) {
+ targetObject = DataTypeTransformer.getTime(value);
+ } else if (javaClassName.equalsIgnoreCase(MMJDBCSQLTypeInfo.BLOB_CLASS)) {
+ targetObject = DataTypeTransformer.getBlob(value);
+ } else if (javaClassName.equalsIgnoreCase(MMJDBCSQLTypeInfo.CLOB_CLASS)) {
+ targetObject = DataTypeTransformer.getClob(value);
+ } else {
+ String msg =
JDBCPlugin.Util.getString("MMPreparedStatement.Err_transform_obj");
//$NON-NLS-1$
+ throw new TeiidSQLException(msg);
+ }
+
+ setObject(parameterIndex, targetObject);
+ }
+
+ /**
+ * <p>Sets parameter number parameterIndex to an object value
+ * @param parameterIndex of the parameter whose value is to be set
+ * @param an object value to which the parameter value is to be set.
+ * @throws SQLException, if there is an error setting the parameter value
+ */
+ public void setObject(int parameterIndex, Object value) throws SQLException {
+ ArgCheck.isPositive(parameterIndex,
JDBCPlugin.Util.getString("MMPreparedStatement.Invalid_param_index"));
//$NON-NLS-1$
+
+ if(parameterMap == null){
+ parameterMap = new TreeMap<Integer, Object>();
+ }
+
+ Object val = null;
+ if (serverCalendar != null && value instanceof java.util.Date) {
+ val = TimestampWithTimezone.create((java.util.Date)value,
getDefaultCalendar().getTimeZone(), serverCalendar, value.getClass());
+ } else val = value;
+
+ parameterMap.put(new Integer(parameterIndex), val);
+ }
+
+ /**
+ * <p>Sets parameter number parameterIndex to x, a short value. The parameter
+ * type is set to TINYINT
+ * @param parameterIndex of the parameter whose value is to be set
+ * @param short value to which the parameter value is to be set.
+ * @throws SQLException, if there is an error setting the parameter value
+ */
+ public void setShort(int parameterIndex, short value) throws SQLException {
+ setObject(parameterIndex, new Short(value));
+ }
+
+ /**
+ * <p>Sets parameter number parameterIndex to x, a String value. The parameter
+ * type is set to VARCHAR
+ * @param parameterIndex of the parameter whose value is to be set
+ * @param String object to which the parameter value is to be set.
+ * @throws SQLException
+ */
+ public void setString(int parameterIndex, String value) throws SQLException {
+ setObject(parameterIndex, value);
+ }
+
+ /**
+ * <p>Sets parameter number parameterIndex to x, a java.sql.Time object. The
parameter
+ * type is set to TIME
+ * @param parameterIndex of the parameter whose value is to be set
+ * @param Time object to which the parameter value is to be set.
+ * @throws SQLException, if parameter type/datatype do not match
+ */
+ public void setTime(int parameterIndex, java.sql.Time value) throws SQLException {
+ setTime(parameterIndex, value, null);
+ }
+
+ /**
+ * <p>Sets parameter number parameterIndex to x, a java.sql.Time object. The
parameter
+ * type is set to TIME
+ * @param parameterIndex of the parameter whose value is to be set
+ * @param Time object to which the parameter value is to be set.
+ * @param Calendar object to constrct Time(useful to get include timezone info)
+ * @throws SQLException, if parameter type/datatype do not match
+ */
+ public void setTime(int parameterIndex, java.sql.Time x, java.util.Calendar cal)
throws SQLException {
+
+ if (cal == null || x == null) {
+ setObject(parameterIndex, x);
+ return;
+ }
+
+ // set the parameter on the stored procedure
+ setObject(parameterIndex, TimestampWithTimezone.createTime(x, cal.getTimeZone(),
getDefaultCalendar()));
+ }
+
+ /**
+ * <p>Sets parameter number parameterIndex to x, a java.sql.Timestamp object.
The
+ * parameter type is set to TIMESTAMP
+ * @param parameterIndex of the parameter whose value is to be set
+ * @param Timestamp object to which the parameter value is to be set.
+ * @throws SQLException, if parameter type/datatype do not match
+ */
+ public void setTimestamp(int parameterIndex, java.sql.Timestamp value) throws
SQLException {
+ setTimestamp(parameterIndex, value, null);
+ }
+
+ /**
+ * <p>Sets parameter number parameterIndex to x, a java.sql.Timestamp object.
The
+ * parameter type is set to TIMESTAMP
+ * @param parameterIndex of the parameter whose value is to be set
+ * @param Timestamp object to which the parameter value is to be set.
+ * @param Calendar object to constrct timestamp(useful to get include timezone info)
+ * @throws SQLException, if parameter type/datatype do not match
+ */
+ public void setTimestamp(int parameterIndex, java.sql.Timestamp x, java.util.Calendar
cal) throws SQLException {
+
+ if (cal == null || x == null) {
+ setObject(parameterIndex, x);
+ return;
+ }
+
+ // set the parameter on the stored procedure
+ setObject(parameterIndex, TimestampWithTimezone.createTimestamp(x,
cal.getTimeZone(), getDefaultCalendar()));
+ }
+
+ /**
+ * Sets the designated parameter to the given java.net.URL value. The driver
+ * converts this to an SQL DATALINK value when it sends it to the database.
+ * @param parameter int index
+ * @param x URL to be set
+ * @throws SQLException
+ */
+ public void setURL(int parameterIndex, URL x) throws SQLException {
+ setObject(parameterIndex, x);
+ }
+
+ List<List<Object>> getParameterValuesList() {
+ if(batchParameterList == null || batchParameterList.isEmpty()){
+ return Collections.emptyList();
+ }
+ return new ArrayList<List<Object>>(batchParameterList);
+ }
+
+ List<Object> getParameterValues() {
+ if(parameterMap == null || parameterMap.isEmpty()){
+ return Collections.emptyList();
+ }
+ return new ArrayList<Object>(parameterMap.values());
+ }
+
+ public ParameterMetaData getParameterMetaData() throws SQLException {
+ if (parameterMetaData == null) {
+ //TODO: some of the base implementation of ResultSetMetadata could be on the
MetadataProvider
+ this.parameterMetaData = new ParameterMetaDataImpl(new ResultSetMetaDataImpl(new
MetadataProvider(getMetadataResults().getParameterMetadata())));
+ }
+ return parameterMetaData;
+ }
+
+ /**
+ * Exposed for unit testing
+ */
+ void setServerCalendar(Calendar serverCalendar) {
+ this.serverCalendar = serverCalendar;
+ }
+
+ public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException {
+ setObject(parameterIndex, xmlObject);
+ }
+
+ public void setArray(int parameterIndex, Array x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setAsciiStream(int parameterIndex, InputStream x)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setAsciiStream(int parameterIndex, InputStream x, long length)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setBinaryStream(int parameterIndex, InputStream x)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setBinaryStream(int parameterIndex, InputStream x, long length)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setBlob(int parameterIndex, InputStream inputStream)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setBlob(int parameterIndex, InputStream inputStream, long length) throws
SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setCharacterStream(int parameterIndex, Reader reader)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setCharacterStream(int parameterIndex, Reader reader,
+ long length) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setClob(int parameterIndex, Reader reader) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setClob(int parameterIndex, Reader reader, long length)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setNCharacterStream(int parameterIndex, Reader value)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setNCharacterStream(int parameterIndex, Reader value,
+ long length) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ //## JDBC4.0-begin ##
+ public void setNClob(int parameterIndex, NClob value) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+ //## JDBC4.0-end ##
+
+ public void setNClob(int parameterIndex, Reader reader) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setNClob(int parameterIndex, Reader reader, long length)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setNString(int parameterIndex, String value)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setRef(int parameterIndex, Ref x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ //## JDBC4.0-begin ##
+ public void setRowId(int parameterIndex, RowId x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+ //## JDBC4.0-end ##
+
+ public void setUnicodeStream(int parameterIndex, InputStream x, int length)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+}
Copied: trunk/client/src/main/java/org/teiid/jdbc/ResultSetImpl.java (from rev 1983,
trunk/client-jdbc/src/main/java/org/teiid/jdbc/ResultSetImpl.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/ResultSetImpl.java
(rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/ResultSetImpl.java 2010-03-22 21:01:44 UTC
(rev 1986)
@@ -0,0 +1,1778 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Date;
+import java.sql.NClob;
+import java.sql.Ref;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.RowId;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.SQLXML;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Calendar;
+import java.util.List;
+import java.util.Map;
+import java.util.TimeZone;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.logging.Logger;
+
+import org.teiid.client.ResultsMessage;
+import org.teiid.client.lob.LobChunkInputStream;
+import org.teiid.client.lob.StreamingLobChunckProducer;
+import org.teiid.client.util.ResultsFuture;
+import org.teiid.jdbc.BatchResults.Batch;
+import org.teiid.jdbc.BatchResults.BatchFetcher;
+
+import com.metamatrix.api.exception.MetaMatrixComponentException;
+import com.metamatrix.api.exception.MetaMatrixProcessingException;
+import com.metamatrix.common.types.BlobImpl;
+import com.metamatrix.common.types.BlobType;
+import com.metamatrix.common.types.ClobImpl;
+import com.metamatrix.common.types.ClobType;
+import com.metamatrix.common.types.InputStreamFactory;
+import com.metamatrix.common.types.SQLXMLImpl;
+import com.metamatrix.common.types.Streamable;
+import com.metamatrix.common.types.XMLType;
+import com.metamatrix.common.util.SqlUtil;
+import com.metamatrix.common.util.TimestampWithTimezone;
+
+/**
+ * <p>
+ * The MMResultSet is the way query results are returned to the requesting
+ * client based upon a query given to the server. This abstract class that
+ * implements java.sql.ResultSet. This class represents access to results
+ * produced by any of the classes on the driver.
+ * </p>
+ */
+
+public class ResultSetImpl extends WrapperImpl implements ResultSet, BatchFetcher {
+ private static Logger logger = Logger.getLogger("org.teiid.jdbc");
//$NON-NLS-1$
+
+ private static final int BEFORE_FIRST_ROW = 0;
+
+ // the object which was last read from Results
+ private Object currentValue;
+
+ // This object represents metadata for this result set.
+ private ResultSetMetaData rmetadata;
+ // Statement that causes this results
+ private StatementImpl statement;
+
+ // Cursor related state
+ private int cursorType;
+ private boolean isClosed;
+
+ // reuse the original request's state
+ private long requestID;
+ private BatchResults batchResults;
+ private int columnCount;
+ private int resultColumns;
+ private int parameters;
+ private TimeZone serverTimeZone;
+ private Map updatedPlanDescription;
+ private int maxFieldSize;
+ private int fetchSize;
+
+ /**
+ * Constructor.
+ *
+ * @param resultsMsg
+ * @param statement
+ * @throws SQLException
+ */
+ ResultSetImpl(ResultsMessage resultsMsg, StatementImpl statement) throws SQLException {
+ this(resultsMsg, statement, null, 0);
+ }
+
+ ResultSetImpl(ResultsMessage resultsMsg, StatementImpl statement,
+ ResultSetMetaData metadata, int parameters) throws SQLException {
+ this.statement = statement;
+ this.parameters = parameters;
+ // server latency-related timestamp
+ this.requestID = statement.getCurrentRequestID();
+ this.cursorType = statement.getResultSetType();
+ this.batchResults = new BatchResults(this, getCurrentBatch(resultsMsg),
this.cursorType == ResultSet.TYPE_FORWARD_ONLY ? 1 : BatchResults.DEFAULT_SAVED_BATCHES);
+ accumulateWarnings(resultsMsg);
+ this.serverTimeZone = statement.getServerTimeZone();
+
+ if (metadata == null) {
+ MetadataProvider provider = new DeferredMetadataProvider(resultsMsg.getColumnNames(),
+ resultsMsg.getDataTypes(), statement,
+ statement.getCurrentRequestID());
+ rmetadata = new ResultSetMetaDataImpl(provider);
+ } else {
+ rmetadata = metadata;
+ }
+ // Cache the column count and isLOB values since every call to getObject uses
these.
+ this.columnCount = rmetadata.getColumnCount();
+
+ this.resultColumns = columnCount - parameters;
+ if (this.parameters > 0) {
+ rmetadata = new FilteredResultsMetadata(rmetadata, resultColumns);
+ }
+ this.fetchSize = statement.getFetchSize();
+ }
+
+ public void setMaxFieldSize(int maxFieldSize) {
+ this.maxFieldSize = maxFieldSize;
+ }
+
+ /**
+ * Close this result set.
+ */
+ public void close() throws SQLException{
+ if(!isClosed) {
+ // close the the server's statement object (if necessary)
+ if(this.requestID >= 0){
+ try {
+ this.statement.getDQP().closeRequest(requestID);
+ } catch (MetaMatrixProcessingException e) {
+ throw TeiidSQLException.create(e);
+ } catch (MetaMatrixComponentException e) {
+ throw TeiidSQLException.create(e);
+ }
+ }
+ isClosed = true;
+ }
+ }
+
+ public boolean isClosed() throws SQLException {
+ return isClosed;
+ }
+
+ protected void checkClosed() throws SQLException {
+ if (isClosed) {
+ String msg = JDBCPlugin.Util
+ .getString("MMResultSet.Cant_call_closed_resultset"); //$NON-NLS-1$
+ throw new TeiidSQLException(msg);
+ }
+ }
+
+ /**
+ * Return the value for output/return parameter given the index
+ * of the parameter in the ResultSet
+ * @param index Index of the parameter to be retrieved.
+ */
+ Object getOutputParamValue(int index) throws SQLException {
+ if (index <= resultColumns || index > resultColumns + parameters) {
+ throw new
TeiidSQLException(JDBCPlugin.Util.getString("StoredProcedureResultsImpl.Invalid_parameter_index__{0}_2",
index)); //$NON-NLS-1$
+ }
+ // Mark the row we're on
+ final int originalRow = getAbsoluteRowNumber();
+
+ this.batchResults.absolute(-1);
+ try {
+ return getObjectDirect(index);
+ } finally {
+ this.batchResults.absolute(originalRow);
+ }
+ }
+
+ /**
+ * <p>Get a java object based on the column index for the current
row.</p>
+ * @param The index of the column whose value needs to be fetched.
+ * @return The value of the column as an object.
+ * @throws SQLException if a results access error occurs or transform fails.
+ */
+ public Object getObject(int column) throws SQLException {
+ if (isAfterLast()) {
+ throw new
TeiidSQLException(JDBCPlugin.Util.getString("StoredProcedureResultsImpl.ResultSet_cursor_is_after_the_last_row._1"));
//$NON-NLS-1$
+ }
+ // only get the Object of the result set
+ if(column > resultColumns){
+ throw new
TeiidSQLException(JDBCPlugin.Util.getString("ResultsImpl.Invalid_col_index",
column)); //$NON-NLS-1$
+ }
+ return getObjectDirect(column);
+ }
+
+ /**
+ * Get fetch size that will be used if this result set is backed
+ * by a cursor. This may be the hint fetch size provided by
+ * {@link com.metamatrix.jdbc.ResultsImpl#getFetchSize} or it may
+ * have been reset by the server.
+ */
+ public int getFetchSize() throws SQLException {
+ return this.fetchSize;
+ }
+
+ /**
+ * Move row pointer forward one row. This may cause the cursor
+ * to fetch more rows.
+ * @return True if the current index is on a valid row, false if
+ * the pointer is past the end of the rows
+ * @throws SQLException if this result set has an exception
+ */
+ public boolean next() throws SQLException {
+ checkClosed();
+ if (hasNext()) {
+ return batchResults.next();
+ }
+ batchResults.next();
+ return false;
+ }
+
+ /**
+ * Move row pointer backward one row. This may cause the cursor
+ * to fetch more rows.
+ * @return True if the current index is on a valid row, false if
+ * the pointer is before the beginning of the rows
+ * @throws SQLException if this result set has an exception
+ */
+ public boolean previous() throws SQLException {
+ checkClosed();
+ checkNotForwardOnly();
+ return batchResults.previous();
+ }
+
+ /**
+ * Get current row pointer.
+ * @return Index of current row
+ * @throws SQLException if this result set has an exception
+ */
+ public int getRow() throws SQLException {
+ checkClosed();
+ if (isAfterLast()) {
+ return 0;
+ }
+ return getAbsoluteRowNumber();
+ }
+
+ /**
+ * Get the value of the current row at the column index specified.
+ * @param column Column index
+ * @return Value at column, which may be null
+ * @throws SQLException if this result set has an exception
+ */
+ public Object getObjectDirect(int column) throws SQLException {
+ checkClosed();
+ if(column < 1 || column > columnCount) {
+ throw new
IllegalArgumentException(JDBCPlugin.Util.getString("ResultsImpl.Invalid_col_index",
column)); //$NON-NLS-1$
+ }
+ List cursorRow = batchResults.getCurrentRow();
+
+ if (cursorRow == null) {
+ throw new
TeiidSQLException(JDBCPlugin.Util.getString("ResultsImpl.The_cursor_is_not_on_a_valid_row._1"));
//$NON-NLS-1$
+ }
+
+ // defect 13539 - set the currentValue (defined in MMResultSet) so that wasNull()
accurately returns whether this value was null
+ currentValue = cursorRow.get(column-1);
+
+ if (currentValue instanceof Streamable) {
+ if (Boolean.getBoolean(Streamable.FORCE_STREAMING)) {
+ Object reference = ((Streamable)currentValue).getReference();
+ if (reference != null) {
+ currentValue = reference;
+ return currentValue;
+ }
+ }
+ if(currentValue instanceof ClobType){
+ currentValue = new
ClobImpl(createInputStreamFactory((ClobType)currentValue),
((ClobType)currentValue).getLength());
+ }
+ else if (currentValue instanceof BlobType) {
+ InputStreamFactory isf = createInputStreamFactory((BlobType)currentValue);
+ isf.setLength(((BlobType)currentValue).getLength());
+ currentValue = new BlobImpl(isf);
+ }
+ else if (currentValue instanceof XMLType) {
+ currentValue = new
SQLXMLImpl(createInputStreamFactory((XMLType)currentValue));
+ }
+ }
+ else if (currentValue instanceof java.util.Date) {
+ return TimestampWithTimezone.create((java.util.Date)currentValue,
serverTimeZone, getDefaultCalendar(), currentValue.getClass());
+ }
+ else if (maxFieldSize > 0 && currentValue instanceof String) {
+ String val = (String)currentValue;
+ currentValue = val.substring(0, Math.min(maxFieldSize/2, val.length()));
+ }
+ return currentValue;
+ }
+
+ private InputStreamFactory createInputStreamFactory(Streamable<?> type) {
+ final StreamingLobChunckProducer.Factory factory = new
StreamingLobChunckProducer.Factory(this.statement.getDQP(), this.requestID, type);
+ InputStreamFactory isf = new InputStreamFactory(Streamable.ENCODING) {
+ @Override
+ public InputStream getInputStream() throws IOException {
+ return new LobChunkInputStream(factory.getLobChunkProducer());
+ }
+ };
+ return isf;
+ }
+
+ /**
+ * Get all values in current record in column order
+ * @return List of Object values in current row
+ * @throws SQLException if an access error occurs.
+ */
+ public List getCurrentRecord() throws SQLException {
+ checkClosed();
+ List wholeRecord = batchResults.getCurrentRow();
+ return wholeRecord.subList(0, wholeRecord.size() - getOffset());
+ }
+ /*
+ * @see java.sql.ResultSet#getType()
+ */
+ public int getType() throws SQLException {
+ return this.cursorType;
+ }
+
+ public boolean absolute( int row) throws SQLException {
+ checkClosed();
+ checkNotForwardOnly();
+ return batchResults.absolute(row, getOffset());
+ }
+
+ protected Map getUpdatedPlanDescription() {
+ return updatedPlanDescription;
+ }
+
+ public Batch requestBatch(int beginRow) throws SQLException{
+ logger.fine("CursorResultsImpl.requestBatch] thread name: " +
Thread.currentThread().getName() + " requestID: " + requestID + " beginRow:
" + beginRow ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ checkClosed();
+ try {
+ ResultsFuture<ResultsMessage> results =
statement.getDQP().processCursorRequest(requestID, beginRow, fetchSize);
+ int timeoutSeconds = statement.getQueryTimeout();
+ if (timeoutSeconds == 0) {
+ timeoutSeconds = Integer.MAX_VALUE;
+ }
+ ResultsMessage currentResultMsg = results.get(timeoutSeconds,
TimeUnit.SECONDS);
+ this.accumulateWarnings(currentResultMsg);
+ this.updatedPlanDescription = currentResultMsg.getPlanDescription();
+ return getCurrentBatch(currentResultMsg);
+ } catch (MetaMatrixProcessingException e) {
+ throw TeiidSQLException.create(e);
+ } catch (InterruptedException e) {
+ throw TeiidSQLException.create(e);
+ } catch (ExecutionException e) {
+ throw TeiidSQLException.create(e);
+ } catch (TimeoutException e) {
+ throw TeiidSQLException.create(e);
+ }
+ }
+
+ private Batch getCurrentBatch(ResultsMessage currentResultMsg) {
+ boolean isLast = currentResultMsg.getResults().length == 0 ||
currentResultMsg.getFinalRow() == currentResultMsg.getLastRow();
+ return new Batch(currentResultMsg.getResults(), currentResultMsg.getFirstRow(),
currentResultMsg.getLastRow(), isLast);
+ }
+
+ protected int getFinalRowNumber() {
+ return Math.max(-1, batchResults.getFinalRowNumber() - getOffset());
+ }
+
+ protected boolean hasNext() throws SQLException {
+ return batchResults.hasNext(getOffset() + 1);
+ }
+
+ protected int getOffset() {
+ return parameters > 0 ? 1 : 0;
+ }
+
+ protected int getAbsoluteRowNumber() {
+ return batchResults.getCurrentRowNumber();
+ }
+
+ public void cancelRowUpdates() throws SQLException {
+ // do nothing.
+ checkClosed(); // check to see if the ResultSet is closed
+ }
+
+ //## JDBC4.0-begin ##
+ @Override
+ //## JDBC4.0-end ##
+ public void clearWarnings() throws SQLException {
+ // do nothing
+ checkClosed(); // check to see if the ResultSet is closed
+ }
+
+ public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
+ return DataTypeTransformer.getBigDecimal(getObject(columnIndex));
+ }
+
+ public BigDecimal getBigDecimal(String columnName) throws SQLException {
+ // find the columnIndex for the given column name.
+ return getBigDecimal(findColumn(columnName));
+ }
+
+ public BigDecimal getBigDecimal(int columnIndex, int scale)
+ throws SQLException {
+
+ // do the necessary transformation depending on the datatype of the
+ // object at the given index.
+ BigDecimal bigDecimalObject = DataTypeTransformer
+ .getBigDecimal(getObject(columnIndex));
+
+ if (bigDecimalObject == null) {
+ return null;
+ }
+
+ // set the scale on the bigDecimal
+ return bigDecimalObject.setScale(scale);
+ }
+
+ public BigDecimal getBigDecimal(String columnName, int scale)
+ throws SQLException {
+ // find the columnIndex for the given column name.
+ return getBigDecimal(findColumn(columnName), scale);
+ }
+
+ public java.io.InputStream getBinaryStream(int columnIndex)
+ throws SQLException {
+ Object value = getObject(columnIndex);
+ if (value == null) {
+ return null;
+ }
+
+ if (value instanceof Blob) {
+ return ((Blob) value).getBinaryStream();
+ }
+
+ if (value instanceof SQLXML) {
+ return ((SQLXML)value).getBinaryStream();
+ }
+
+ throw new
TeiidSQLException(JDBCPlugin.Util.getString("MMResultSet.cannot_convert_to_binary_stream"));
//$NON-NLS-1$
+ }
+
+ public java.io.InputStream getBinaryStream(String columnName)
+ throws SQLException {
+ return getBinaryStream(findColumn(columnName));
+ }
+
+ public Blob getBlob(int columnIndex) throws SQLException {
+ return DataTypeTransformer.getBlob(getObject(columnIndex));
+ }
+
+ public Blob getBlob(String columnName) throws SQLException {
+ return getBlob(findColumn(columnName));
+ }
+
+ public boolean getBoolean(int columnIndex) throws SQLException {
+ return DataTypeTransformer.getBoolean(getObject(columnIndex));
+ }
+
+ public boolean getBoolean(String columnName) throws SQLException {
+ // find the columnIndex for the given column name.
+ return getBoolean(findColumn(columnName));
+ }
+
+ public byte getByte(int columnIndex) throws SQLException {
+ return DataTypeTransformer.getByte(getObject(columnIndex));
+ }
+
+ public byte getByte(String columnName) throws SQLException {
+ // find the columnIndex for the given column name.
+ return getByte(findColumn(columnName));
+ }
+
+ /**
+ * This method will return the value in the current row as an array of byte
+ * values
+ *
+ * @param columnIndex
+ * The column position in the current row whose value is to be read.
+ * @return The value of the column at columnIndex as an array of bytes.
+ * @throws SQLException
+ * if there is an error accessing or converting the result value
+ */
+ public byte[] getBytes(int columnIndex) throws SQLException {
+ return DataTypeTransformer.getBytes(getObject(columnIndex));
+ }
+
+ /**
+ * This method will return the value in the current row as an array of byte
+ * values
+ *
+ * @param columnName
+ * The column name in the current row whose value is to be updated.
+ * @return byte[]. The value of the column at columnIndex as an array of
+ * bytes.
+ * @throws SQLException
+ * if there is an error accessing or converting the result value
+ */
+ public byte[] getBytes(String columnName) throws SQLException {
+ return getBytes(findColumn(columnName));
+ }
+
+ /**
+ * Get the concurrency type for this ResultSet object. The concurrency was
+ * set by the Statement object. The possible concurrency types are
+ * CONCUR_READ_ONLY and CONCUR_UPDATABLE.
+ *
+ * @return The resultSets are not updatable, this method returns
+ * CONCUR_READ_ONLY.
+ * @throws SQLException
+ * if the there is an error accesing results
+ */
+ public int getConcurrency() throws SQLException {
+
+ checkClosed(); // check to see if the ResultSet is closed
+ return ResultSet.CONCUR_READ_ONLY;
+ }
+
+ /**
+ * This method will attempt to return the value contained at the index as a
+ * java.io.Reader object.
+ *
+ * @param columnIndex
+ * The column position in the current row whose value is to be read.
+ * @return The value of the column as a java.io.Reader object.
+ */
+ public java.io.Reader getCharacterStream(int columnIndex)
+ throws SQLException {
+ Object value = getObject(columnIndex);
+ if (value == null) {
+ return null;
+ }
+
+ if (value instanceof Clob) {
+ return ((Clob) value).getCharacterStream();
+ }
+
+ if (value instanceof SQLXML) {
+ return ((SQLXML)value).getCharacterStream();
+ }
+
+ return new StringReader(getString(columnIndex));
+ }
+
+ /**
+ * This method will attempt to return the value at the designated column
+ * determined by the columName as a java.io.Reader object.
+ *
+ * @param columnName
+ * The column name in the current row whose value is to be updated.
+ * @return The value of the column as a java.io.Reader object.
+ */
+ public java.io.Reader getCharacterStream(String columnName)
+ throws SQLException {
+ return getCharacterStream(findColumn(columnName));
+ }
+
+ /**
+ * This method will return the value in the current row as a Date object.
+ * This will use the timeZone info of the calendar object.
+ *
+ * @param The
+ * index of the column whose value needs to be fetched.
+ * @param Calender
+ * object used to get the date value.
+ * @return The value of the column as a Date object.
+ * @throws SQLException
+ * if a results access error occurs or transform fails.
+ */
+ public Date getDate(int columnIndex, Calendar cal) throws SQLException {
+ Date value = DataTypeTransformer.getDate(getObject(columnIndex));
+
+ if (value != null && cal != null) {
+ value = TimestampWithTimezone.createDate(value,
+ getDefaultCalendar().getTimeZone(), cal);
+ }
+
+ return value;
+ }
+
+ /**
+ * Get the Date value for the given column.
+ *
+ * @param columnName
+ * . The name of the column whose value needs to be fetched.
+ * @param Calender
+ * object used to get the date value.
+ * @return value of the column as an int.
+ * @throws SQLException
+ * unable to obtain date value for the given column.
+ */
+ public Date getDate(String columnName, Calendar cal) throws SQLException {
+ // find the columnIndex for the given column name.
+ return getDate(findColumn(columnName), cal);
+ }
+
+ /**
+ * This method will return the value in the current row as a Date object.
+ * This will assume the default timeZone.
+ *
+ * @param The
+ * index of the column whose value needs to be fetched.
+ * @return The value of the column as a Date object.
+ * @throws SQLException
+ * if a results access error occurs or transform fails.
+ */
+ public Date getDate(int columnIndex) throws SQLException {
+ return getDate(columnIndex, null);
+ }
+
+ /**
+ * Get the column value as a Date object
+ *
+ * @param name
+ * of the column in the resultset whose value is to be fetched.
+ * @return value of the column as an int.
+ * @throw a SQLException if a resultSet access error occurs.
+ */
+ public Date getDate(String columnName) throws SQLException {
+ // find the columnIndex for the given column name.
+ return getDate(findColumn(columnName));
+ }
+
+ /**
+ * This method will return the value in the current row as a double value.
+ *
+ * @param The
+ * index of the column whose value needs to be fetched.
+ * @return The value of the column as a double value.
+ * @throws SQLException
+ * if a results access error occurs or transform fails.
+ */
+ public double getDouble(int columnIndex) throws SQLException {
+ return DataTypeTransformer.getDouble(getObject(columnIndex));
+ }
+
+ /**
+ * Get a double value based on the column name.
+ *
+ * @param name
+ * of the column in the resultset whose value is to be fetched.
+ * @return value of the column as a double.
+ * @throw a SQLException if a resultSet access error occurs.
+ */
+ public double getDouble(String columnName) throws SQLException {
+ // find the columnIndex for the given column name.
+ return getDouble(findColumn(columnName));
+ }
+
+ /**
+ * Gets the direction suggested to the driver as the direction in which to
+ * fetch rows.
+ *
+ * @return fetch direction for this ResultSet. This cannot be set and is
+ * alwayd FETCH_FORWARD.
+ * @throws SQLException
+ */
+ public int getFetchDirection() throws SQLException {
+ checkClosed(); // check to see if the ResultSet is closed
+ return ResultSet.FETCH_FORWARD;
+ }
+
+ /**
+ * This method will return the value in the current row as a float value.
+ *
+ * @param The
+ * index of the column whose value needs to be fetched.
+ * @return The value of the column as a float value.
+ * @throws SQLException
+ * if a results access error occurs or transform fails.
+ */
+ public float getFloat(int columnIndex) throws SQLException {
+ return DataTypeTransformer.getFloat(getObject(columnIndex));
+ }
+
+ /**
+ * Get a float value based on the column name.
+ *
+ * @param name
+ * of the column in the resultset whose value is to be fetched.
+ * @return value of the column as a float.
+ * @throw a SQLException if a resultSet access error occurs.
+ */
+ public float getFloat(String columnName) throws SQLException {
+ // find the columnIndex for the given column name.
+ return getFloat(findColumn(columnName));
+ }
+
+ /**
+ * This method will return the value in the current row as a int value.
+ *
+ * @param The
+ * index of the column whose value needs to be fetched.
+ * @return The value of the column as a int value.
+ * @throws SQLException
+ * if a results access error occurs or transform fails.
+ */
+ public int getInt(int columnIndex) throws SQLException {
+ return DataTypeTransformer.getInteger(getObject(columnIndex));
+ }
+
+ /**
+ * Get an integer based on the column index.
+ *
+ * @param name
+ * of the column in the resultset whose value is to be fetched.
+ * @return value of the column as an int.
+ * @throw a SQLException if a resultSet access error occurs.
+ */
+ public int getInt(String columnName) throws SQLException {
+ // find the columnIndex for the given column name.
+ return getInt(findColumn(columnName));
+ }
+
+ /**
+ * This method will return the value in the current row as a long value.
+ *
+ * @param The
+ * index of the column whose value needs to be fetched.
+ * @return The value of the column as a long value.
+ * @throws SQLException
+ * if a results access error occurs or transform fails.
+ */
+ public long getLong(int columnIndex) throws SQLException {
+ return DataTypeTransformer.getLong(getObject(columnIndex));
+ }
+
+ /**
+ * Get a long based on the column name.
+ *
+ * @param name
+ * of the column in the resultset whose value is to be fetched.
+ * @return value of the column as a long.
+ * @throw a SQLException if a resultSet access error occurs.
+ */
+ public long getLong(String columnName) throws SQLException {
+ // find the columnIndex for the given column name.
+ return getLong(findColumn(columnName));
+ }
+
+ /**
+ * Get a java object based on the column name.
+ *
+ * @param name
+ * of the column in the resultset whose value is to be fetched.
+ * @return object which gives the column value.
+ * @throw a SQLException if a resultSet access error occurs.
+ */
+ public Object getObject(String columnName) throws SQLException {
+ // find the columnIndex for the given column name.
+ return getObject(findColumn(columnName));
+ }
+
+ /**
+ * Get a primitive short based on the column index.
+ *
+ * @param The
+ * index of the column whose value needs to be fetched.
+ * @return The value of the column as a short value.
+ * @throws SQLException
+ * if a results access error occurs or transform fails.
+ */
+ public short getShort(int columnIndex) throws SQLException {
+ return DataTypeTransformer.getShort(getObject(columnIndex));
+ }
+
+ /**
+ * Get a short based on the column name.
+ *
+ * @param String
+ * representing name of the column.
+ * @return short value of the column.
+ * @throws SQLException
+ * if a results access error occurs.
+ */
+ public short getShort(String columnName) throws SQLException {
+ // find the columnIndex for the given column name.
+ return getShort(findColumn(columnName));
+ }
+
+ /**
+ * Get a String based on the column index.
+ *
+ * @param The
+ * index of the column whose value needs to be fetched.
+ * @return The value of the column as a string value.
+ * @throws SQLException
+ * if a results access error occurs or transform fails.
+ */
+ public String getString(int columnIndex) throws SQLException {
+ return DataTypeTransformer.getString(getObject(columnIndex));
+ }
+
+ /**
+ * Get a string based on the column name.
+ *
+ * @param String
+ * representing name of the column.
+ * @return String value of the column.
+ * @throws SQLException
+ * if a results access error occurs.
+ */
+ public String getString(String columnName) throws SQLException {
+ // find the columnIndex for the given column name.
+ return getString(findColumn(columnName));
+ }
+
+ /**
+ * This method will return the value in the current row as a Time object.
+ * This will assume the default timeZone.
+ *
+ * @param The
+ * index of the column whose value needs to be fetched.
+ * @return The value of the column as a Time object.
+ * @throws SQLException
+ * if a results access error occurs or transform fails.
+ */
+ public Time getTime(int columnIndex) throws SQLException {
+ return getTime(columnIndex, null);
+ }
+
+ /**
+ * Get a java.sql.Time based on the column name.
+ *
+ * @param name
+ * of the column whose value is to be fetched as a timestamp
+ * @return value of the column as a Timestamp object
+ * @throws SQLException
+ * if a results access error occurs.
+ */
+ public Time getTime(String columnName) throws SQLException {
+ // find the columnIndex for the given column name.
+ return getTime(findColumn(columnName));
+ }
+
+ /**
+ * This method will return the value in the current row as a Time object.
+ * This will use the timeZone info of the calendar object.
+ *
+ * @param The
+ * index of the column whose value needs to be fetched.
+ * @param Calendar
+ * object to be used to construct the Time object.
+ * @return The value of the column as a Time object.
+ * @throws SQLException
+ * if a results access error occurs or transform fails.
+ */
+ public Time getTime(int columnIndex, Calendar cal) throws SQLException {
+ Time value = DataTypeTransformer.getTime(getObject(columnIndex));
+
+ if (value != null && cal != null) {
+ value = TimestampWithTimezone.createTime(value,
+ getDefaultCalendar().getTimeZone(), cal);
+ }
+
+ return value;
+ }
+
+ /**
+ * Get a java.sql.Time based on the column name.
+ *
+ * @param name
+ * of the column whose value is to be fetched as a timestamp
+ * @param calender
+ * object to include the timezone info in the object returned
+ * @return value of the column as a Timestamp object
+ * @throws SQLException
+ * if a results access error occurs.
+ */
+ public Time getTime(String columnName, Calendar cal) throws SQLException {
+ // find the columnIndex for the given column name.
+ return getTime((findColumn(columnName)), cal);
+ }
+
+ /**
+ * This method will return the value in the current row as a Timestamp
+ * object. This will assume the default timeZone.
+ *
+ * @param The
+ * index of the column whose value needs to be fetched.
+ * @return The value of the column as a Timestamp object.
+ * @throws SQLException
+ * if a results access error occurs or transform fails.
+ */
+ public Timestamp getTimestamp(int columnIndex) throws SQLException {
+ return getTimestamp(columnIndex, null);
+ }
+
+ /**
+ * Get a java.sql.Timestamp based on the column name.
+ *
+ * @param name
+ * of the column whose value is to be fetched as a timestamp
+ * @return value of the column as a Timestamp object
+ * @throws SQLException
+ * if a results access error occurs.
+ */
+ public Timestamp getTimestamp(String columnName) throws SQLException {
+ // find the columnIndex for the given column name.
+ return getTimestamp(findColumn(columnName));
+ }
+
+ /**
+ * This method will return the value in the current row as a Timestamp
+ * object. This will use the timeZone info of the calendar object.
+ *
+ * @param The
+ * index of the column whose value needs to be fetched.
+ * @param Calendar
+ * object to be used to construct the Timestamp object.
+ * @return The value of the column as a Timestamp object.
+ * @throws SQLException
+ * if a results access error occurs or transform fails.
+ */
+ public Timestamp getTimestamp(int columnIndex, Calendar cal)
+ throws SQLException {
+ Timestamp value = DataTypeTransformer.getTimestamp(getObject(columnIndex));
+
+ if (value != null && cal != null) {
+ value = TimestampWithTimezone.createTimestamp(value,
+ getDefaultCalendar().getTimeZone(), cal);
+ }
+
+ return value;
+ }
+
+ /**
+ * Get a java.sql.Timestamp based on the column name.
+ *
+ * @param name
+ * of the column whose value is to be fetched as a timestamp
+ * @param calender
+ * object to include the timezone info in the object returned
+ * @return value of the column as a Timestamp object
+ * @throws SQLException
+ * if a results access error occurs.
+ */
+ public Timestamp getTimestamp(String columnName, Calendar cal)
+ throws SQLException {
+ // find the columnIndex for the given column name.
+ return getTimestamp(findColumn(columnName), cal);
+ }
+
+ /**
+ * Moves the cursor to the remembered cursor position, usually the current
+ * row. This method does not have any effect if the cursor is not on the
+ * insert row. ResultSet cannot currently be updated.
+ */
+ public void moveToCurrentRow() throws SQLException {
+ // do nothing
+ }
+
+ /**
+ * This will return a boolean value if the last column that was read had a
+ * value equal to null. If the last column read was null return true, else
+ * return false.
+ *
+ * @return A boolean value showing if the lastvalue read in was null or not.
+ * @throws SQLException
+ */
+ public boolean wasNull() throws SQLException {
+
+ checkClosed(); // check to see if the ResultSet is closed
+
+ return currentValue == null;
+ }
+
+ protected void accumulateWarnings(ResultsMessage resultsMsg) {
+ this.statement.accumulateWarnings(resultsMsg.getWarnings());
+ }
+
+ /**
+ * <p>
+ * This method returns the meta data of the result set, such as the number,
+ * types and properties of this resultSets columns.
+ * </p>
+ *
+ * @return ResultSerMetaData object for these results.
+ * @throws SQLException
+ * if results access error occurs
+ */
+ public ResultSetMetaData getMetaData() throws SQLException {
+ checkClosed();
+ return rmetadata;
+ }
+
+ /**
+ * Retrieves the RequestID for the query that created this ResultSet.
+ *
+ * @return The requestID for the query that created these results
+ * @throws SQLException
+ */
+ public String getCursorName() throws SQLException {
+ return null;
+ }
+
+ /**
+ * <p>
+ * Retrieves the Statement object that produced this ResultSet object.
+ *
+ * @return a Statement object.
+ * </p>
+ * @throws SQLException
+ * if the there is an error accesing results
+ */
+ public StatementImpl getStatement() throws SQLException {
+ checkClosed();
+ return statement;
+ }
+
+ public SQLWarning getWarnings() throws SQLException {
+ checkClosed();
+
+ return null;
+ }
+
+ /**
+ * True if current record is the first in the result set.
+ *
+ * @return True if current row is first
+ * @throws QueryResultsException
+ * if this result set has an exception
+ * @throws InvalidatedResultsException
+ * if the results were obtained during a transaction and the
+ * transaction has been rolled back
+ */
+ public boolean isFirst() throws SQLException {
+ return this.getAbsoluteRowNumber() == BEFORE_FIRST_ROW + 1 && hasNext();
+ }
+
+ /**
+ * True if current record is the last in the result set.
+ *
+ * @return True if current row is last
+ * @throws QueryResultsException
+ * if this result set has an exception
+ * @throws InvalidatedResultsException
+ * if the results were obtained during a transaction and the
+ * transaction has been rolled back
+ */
+ public boolean isLast() throws SQLException {
+ return !hasNext() && this.getAbsoluteRowNumber() > BEFORE_FIRST_ROW
&& this.getAbsoluteRowNumber() == getFinalRowNumber();
+ }
+
+ /**
+ * <p>
+ * Determines whether the cursor is after the last row in this ResultSet
+ * object. This method should be called only if the result set is
+ * scrollable.
+ * </p>
+ *
+ * @return true if the cursor is after the last row in the resultSet.
+ * @throws SQLException
+ */
+ public boolean isAfterLast() throws SQLException {
+ // return true if the current row has a next row
+ // it is also not the last
+ return !hasNext() && this.getAbsoluteRowNumber() > BEFORE_FIRST_ROW
&& this.getAbsoluteRowNumber() > getFinalRowNumber();
+ }
+
+ /**
+ * <p>
+ * Determines whether the cursor is before the first row in this ResultSet
+ * object. This method should be called only if the result set is
+ * scrollable.
+ * </p>
+ *
+ * @return true if the cursor is before the last row in the resultSet;false
+ * if the cursor is at any other position or the result set contains no
+ * rows.
+ * @throws SQLException
+ */
+ public boolean isBeforeFirst() throws SQLException {
+ // return true if there are rows and the current row is before first
+ return getAbsoluteRowNumber() == BEFORE_FIRST_ROW && hasNext();
+ }
+
+ /**
+ * <p>
+ * Moves the cursor a number of rows relative to the current row in this
+ * ResultSet object. The number of rows may be positive or negative.
+ * </p>
+ *
+ * @param number
+ * of rows to move relative to the present row.
+ * @return true if the cursor is on a valid row in the resultSet.
+ * @throws SQLException
+ * if the there is an error accessing results
+ */
+ public boolean relative(int rows) throws SQLException {
+ if (isBeforeFirst() || isAfterLast() || getFinalRowNumber() == 0) {
+ throw new TeiidSQLException(
+ JDBCPlugin.Util
+ .getString("ResultsImpl.The_cursor_is_not_on_a_valid_row._1"));
//$NON-NLS-1$
+ }
+
+ checkNotForwardOnly();
+
+ return this.absolute(Math.max(0, getAbsoluteRowNumber() + rows));
+ }
+
+ /**
+ * <p>
+ * Moves the cursor to the last row in the in this ResultSet object. This
+ * method should be called only if the result set is scrollable.
+ * </p>
+ *
+ * @return true if the cursor is on a validRow, false otherwise or if no
+ * rows exist.
+ * @throws SQLException
+ * if the type of the ResultSet is TYPE_FORWARD_ONLY
+ */
+ public boolean last() throws SQLException {
+ checkNotForwardOnly();
+
+ return absolute(-1);
+ }
+
+ protected void checkNotForwardOnly() throws SQLException {
+ if (getType() == ResultSet.TYPE_FORWARD_ONLY) {
+ String msg = JDBCPlugin.Util
+ .getString("ResultsImpl.Op_invalid_fwd_only"); //$NON-NLS-1$
+ throw new TeiidSQLException(msg);
+ }
+ }
+
+ /**
+ * <p>
+ * Moves the cursor to the end of the result set, just after the last row.
+ * Has no effect if the result set contains no rows.
+ * </p>
+ *
+ * @throws SQLException
+ * if a results access error occurs or the result set type is
+ * TYPE_FORWARD_ONLY
+ */
+ public void afterLast() throws SQLException {
+ if (last()) {
+ next();
+ }
+ }
+
+ /**
+ * <p>
+ * Moves the cursor to the front of the result set, just before the first
+ * row. Has no effect if the result set contains no rows.
+ * </p>
+ *
+ * @exception SQLException
+ * if a results can not be accessed or the result set type is
+ * TYPE_FORWARD_ONLY
+ */
+ public void beforeFirst() throws SQLException {
+ if (first()) {
+ previous();
+ }
+ }
+
+ /**
+ * <p>
+ * Moves the cursor to the first row in this ResultSet object.
+ * </p>
+ *
+ * @return true if the cursor is on valid row, false if there are no rows in
+ * the resultset.
+ * @throws SQLException
+ * if the ResulSet is of TYPE_FORWARD_ONLY.
+ */
+ public boolean first() throws SQLException {
+ checkNotForwardOnly();
+ return absolute(1);
+ }
+
+ /**
+ * <p>
+ * This method returns the integer that represents which column represents
+ * the column name parameter.
+ * </p>
+ *
+ * @param Name
+ * of the column whose position is to be returned.
+ * @return Position of column amoung the columns in the ResultSet.
+ * @throws SQLException
+ * if a database access error occurs.
+ */
+ public int findColumn(String columnName) throws SQLException {
+ checkClosed();
+
+ // get the column index using ResultsMetadata object
+ return findColumnIndex(columnName);
+ }
+
+ protected int findColumnIndex(String columnName) throws SQLException {
+ int colCount = getMetaData().getColumnCount();
+ for (int i = 1; i <= colCount; i++) {
+ if (getMetaData().getColumnName(i).equalsIgnoreCase(columnName)) {
+ return i;
+ }
+ }
+
+ String msg = JDBCPlugin.Util.getString(
+ "MMResultsImpl.Col_doesnt_exist", columnName); //$NON-NLS-1$
+ throw new TeiidSQLException(msg);
+ }
+
+ protected Calendar getDefaultCalendar() {
+ return statement.getDefaultCalendar();
+ }
+
+ public void deleteRow() throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public Array getArray(int columnIndex) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public Array getArray(String columnLabel) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public InputStream getAsciiStream(int columnIndex) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public InputStream getAsciiStream(String columnLabel) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public Clob getClob(int columnIndex) throws SQLException {
+ return DataTypeTransformer.getClob(getObject(columnIndex));
+ }
+
+ public SQLXML getSQLXML(int columnIndex) throws SQLException {
+ return DataTypeTransformer.getSQLXML(getObject(columnIndex));
+ }
+
+ public Clob getClob(String columnLabel) throws SQLException {
+ return getClob(findColumn(columnLabel));
+ }
+
+
+ public int getHoldability() throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public Reader getNCharacterStream(int columnIndex) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public Reader getNCharacterStream(String columnLabel) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ //## JDBC4.0-begin ##
+ public NClob getNClob(int columnIndex) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public NClob getNClob(String columnLabel) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+ //## JDBC4.0-end ##
+
+ public String getNString(int columnIndex) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public String getNString(String columnLabel) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public Object getObject(int columnIndex, Map<String, Class<?>> map)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public Object getObject(String columnLabel, Map<String, Class<?>> map)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public Ref getRef(int columnIndex) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public Ref getRef(String columnLabel) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ //## JDBC4.0-begin ##
+ public RowId getRowId(int columnIndex) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+ //## JDBC4.0-end ##
+
+ //## JDBC4.0-begin ##
+ public RowId getRowId(String columnLabel) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+ //## JDBC4.0-end ##
+
+ public SQLXML getSQLXML(String columnLabel) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public InputStream getUnicodeStream(int columnIndex) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public InputStream getUnicodeStream(String columnLabel) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public URL getURL(int columnIndex) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public URL getURL(String columnLabel) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void insertRow() throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void moveToInsertRow() throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void refreshRow() throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public boolean rowDeleted() throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public boolean rowInserted() throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public boolean rowUpdated() throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setFetchDirection(int direction) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setFetchSize(int rows) throws SQLException {
+ checkClosed();
+ if ( rows < 0 ) {
+ throw new
TeiidSQLException(JDBCPlugin.Util.getString("MMStatement.Invalid_fetch_size"));
//$NON-NLS-1$
+ }
+ // sets the fetch size on this statement
+ if (rows == 0) {
+ this.fetchSize = BaseDataSource.DEFAULT_FETCH_SIZE;
+ } else {
+ this.fetchSize = rows;
+ }
+ }
+
+ public void updateArray(int columnIndex, Array x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateArray(String columnLabel, Array x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateAsciiStream(int columnIndex, InputStream x, int length)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateAsciiStream(String columnLabel, InputStream x, int length)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateAsciiStream(int columnIndex, InputStream x, long length)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateAsciiStream(int columnIndex, InputStream x)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateAsciiStream(String columnLabel, InputStream x, long length)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateAsciiStream(String columnLabel, InputStream x)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateBigDecimal(int columnIndex, BigDecimal x)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateBigDecimal(String columnLabel, BigDecimal x)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateBinaryStream(int columnIndex, InputStream x, int length)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateBinaryStream(String columnLabel, InputStream x, int length)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+
+ public void updateBinaryStream(int columnIndex, InputStream x, long length)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateBinaryStream(int columnIndex, InputStream x)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateBinaryStream(String columnLabel, InputStream x,
+ long length) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateBinaryStream(String columnLabel, InputStream x)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateBlob(int columnIndex, Blob x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateBlob(String columnLabel, Blob x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateBlob(int columnIndex, InputStream inputStream, long length)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateBlob(int columnIndex, InputStream inputStream)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateBlob(String columnLabel, InputStream inputStream,
+ long length) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateBlob(String columnLabel, InputStream inputStream)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateBoolean(int columnIndex, boolean x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateBoolean(String columnLabel, boolean x)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateByte(int columnIndex, byte x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateByte(String columnLabel, byte x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateBytes(int columnIndex, byte[] x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateBytes(String columnLabel, byte[] x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+
+ public void updateCharacterStream(int columnIndex, Reader x, int length)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateCharacterStream(String columnLabel, Reader reader,
+ int length) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateCharacterStream(int columnIndex, Reader x, long length)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateCharacterStream(int columnIndex, Reader x)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateCharacterStream(String columnLabel, Reader reader,
+ long length) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateCharacterStream(String columnLabel, Reader reader)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateClob(int columnIndex, Clob x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateClob(String columnLabel, Clob x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateClob(int columnIndex, Reader reader, long length)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateClob(int columnIndex, Reader reader) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateClob(String columnLabel, Reader reader, long length)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateClob(String columnLabel, Reader reader)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateDate(int columnIndex, Date x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateDate(String columnLabel, Date x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateDouble(int columnIndex, double x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateDouble(String columnLabel, double x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateFloat(int columnIndex, float x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateFloat(String columnLabel, float x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateInt(int columnIndex, int x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateInt(String columnLabel, int x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateLong(int columnIndex, long x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateLong(String columnLabel, long x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateNCharacterStream(int columnIndex, Reader x, long length)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+
+ }
+
+ public void updateNCharacterStream(int columnIndex, Reader x)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+
+ }
+
+ public void updateNCharacterStream(String columnLabel, Reader reader,
+ long length) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateNCharacterStream(String columnLabel, Reader reader)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+
+ }
+
+ //## JDBC4.0-begin ##
+ public void updateNClob(int columnIndex, NClob clob) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+ //## JDBC4.0-end ##
+
+ public void updateNClob(int columnIndex, Reader reader, long length)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateNClob(int columnIndex, Reader reader) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ //## JDBC4.0-begin ##
+ public void updateNClob(String columnLabel, NClob clob) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+ //## JDBC4.0-end ##
+
+ public void updateNClob(String columnLabel, Reader reader, long length)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateNClob(String columnLabel, Reader reader)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateNString(int columnIndex, String string)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateNString(String columnLabel, String string)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateNull(int columnIndex) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateNull(String columnLabel) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateObject(int columnIndex, Object x, int scaleOrLength)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateObject(int columnIndex, Object x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateObject(String columnLabel, Object x, int scaleOrLength)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateObject(String columnLabel, Object x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateRef(int columnIndex, Ref x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateRef(String columnLabel, Ref x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateRow() throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ //## JDBC4.0-begin ##
+ public void updateRowId(int columnIndex, RowId x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+ //## JDBC4.0-end ##
+
+ //## JDBC4.0-begin ##
+ public void updateRowId(String columnLabel, RowId x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+ //## JDBC4.0-end ##
+
+ public void updateShort(int columnIndex, short x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateShort(String columnLabel, short x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateSQLXML(int columnIndex, SQLXML xmlObject)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateSQLXML(String columnLabel, SQLXML xmlObject)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateString(int columnIndex, String x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateString(String columnLabel, String x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateTime(int columnIndex, Time x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateTime(String columnLabel, Time x) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateTimestamp(int columnIndex, Timestamp x)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void updateTimestamp(String columnLabel, Timestamp x)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+}
Copied: trunk/client/src/main/java/org/teiid/jdbc/ResultSetMetaDataImpl.java (from rev
1983, trunk/client-jdbc/src/main/java/org/teiid/jdbc/ResultSetMetaDataImpl.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/ResultSetMetaDataImpl.java
(rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/ResultSetMetaDataImpl.java 2010-03-22
21:01:44 UTC (rev 1986)
@@ -0,0 +1,166 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+
+import org.teiid.client.metadata.ResultsMetadataConstants;
+
+import com.metamatrix.common.types.MMJDBCSQLTypeInfo;
+
+/**
+ */
+public class ResultSetMetaDataImpl extends WrapperImpl implements ResultSetMetaData {
+
+ private MetadataProvider provider;
+
+ public ResultSetMetaDataImpl(MetadataProvider provider) {
+ this.provider = provider;
+ }
+
+ /**
+ * Adjust from 1-based to internal 0-based representation
+ * @param index External 1-based representation
+ * @return Internal 0-based representation
+ */
+ private int adjustColumn(int index) {
+ return index-1;
+ }
+
+ public String getVirtualDatabaseName(int index) throws SQLException {
+ return provider.getStringValue(adjustColumn(index),
ResultsMetadataConstants.VIRTUAL_DATABASE_NAME);
+ }
+
+ public String getVirtualDatabaseVersion(int index) throws SQLException {
+ return provider.getStringValue(adjustColumn(index),
ResultsMetadataConstants.VIRTUAL_DATABASE_VERSION);
+ }
+
+ public int getColumnCount() throws SQLException {
+ return provider.getColumnCount();
+ }
+
+ public boolean isAutoIncrement(int index) throws SQLException {
+ return provider.getBooleanValue(adjustColumn(index),
ResultsMetadataConstants.AUTO_INCREMENTING);
+ }
+
+ public boolean isCaseSensitive(int index) throws SQLException {
+ return provider.getBooleanValue(adjustColumn(index),
ResultsMetadataConstants.CASE_SENSITIVE);
+ }
+
+ public boolean isSearchable(int index) throws SQLException {
+ Integer searchable = (Integer) provider.getValue(adjustColumn(index),
ResultsMetadataConstants.SEARCHABLE);
+ return !(ResultsMetadataConstants.SEARCH_TYPES.UNSEARCHABLE.equals(searchable));
+ }
+
+ public boolean isCurrency(int index) throws SQLException {
+ return provider.getBooleanValue(adjustColumn(index),
ResultsMetadataConstants.CURRENCY);
+ }
+
+ public int isNullable(int index) throws SQLException {
+ Object nullable = provider.getValue(adjustColumn(index),
ResultsMetadataConstants.NULLABLE);
+ if(nullable.equals(ResultsMetadataConstants.NULL_TYPES.NULLABLE)) {
+ return columnNullable;
+ } else if(nullable.equals(ResultsMetadataConstants.NULL_TYPES.NOT_NULL)) {
+ return columnNoNulls;
+ } else {
+ return columnNullableUnknown;
+ }
+ }
+
+ public boolean isSigned(int index) throws SQLException {
+ return provider.getBooleanValue(adjustColumn(index),
ResultsMetadataConstants.SIGNED);
+ }
+
+ public int getColumnDisplaySize(int index) throws SQLException {
+ return provider.getIntValue(adjustColumn(index),
ResultsMetadataConstants.DISPLAY_SIZE);
+ }
+
+ public String getColumnLabel(int index) throws SQLException {
+ return provider.getStringValue(adjustColumn(index),
ResultsMetadataConstants.ELEMENT_LABEL);
+ }
+
+ public String getColumnName(int index) throws SQLException {
+ return provider.getStringValue(adjustColumn(index),
ResultsMetadataConstants.ELEMENT_NAME);
+ }
+
+ public String getSchemaName(int index) throws SQLException {
+ String name = provider.getStringValue(adjustColumn(index),
ResultsMetadataConstants.GROUP_NAME);
+ if (name != null) {
+ int dotIndex = name.indexOf('.');
+ if (dotIndex != -1) {
+ return name.substring(0, dotIndex);
+ }
+ }
+ return null;
+ }
+
+ public int getPrecision(int index) throws SQLException {
+ return provider.getIntValue(adjustColumn(index),
ResultsMetadataConstants.PRECISION);
+ }
+
+ public int getScale(int index) throws SQLException {
+ return provider.getIntValue(adjustColumn(index),
ResultsMetadataConstants.SCALE);
+ }
+
+ public String getTableName(int index) throws SQLException {
+ String name = provider.getStringValue(adjustColumn(index),
ResultsMetadataConstants.GROUP_NAME);
+ if (name != null) {
+ int dotIndex = name.indexOf('.');
+ if (dotIndex != -1) {
+ return name.substring(dotIndex + 1);
+ }
+ }
+ return name;
+ }
+
+ public String getCatalogName(int index) throws SQLException {
+ return provider.getStringValue(adjustColumn(index),
ResultsMetadataConstants.VIRTUAL_DATABASE_NAME);
+ }
+
+ public int getColumnType(int index) throws SQLException {
+ String runtimeTypeName = provider.getStringValue(adjustColumn(index),
ResultsMetadataConstants.DATA_TYPE);
+ return MMJDBCSQLTypeInfo.getSQLType(runtimeTypeName);
+ }
+
+ public String getColumnTypeName(int index) throws SQLException {
+ return provider.getStringValue(adjustColumn(index),
ResultsMetadataConstants.DATA_TYPE);
+ }
+
+ public boolean isReadOnly(int index) throws SQLException {
+ return ! provider.getBooleanValue(adjustColumn(index),
ResultsMetadataConstants.WRITABLE);
+ }
+
+ public boolean isWritable(int index) throws SQLException {
+ return provider.getBooleanValue(adjustColumn(index),
ResultsMetadataConstants.WRITABLE);
+ }
+
+ public boolean isDefinitelyWritable(int index) throws SQLException {
+ return provider.getBooleanValue(adjustColumn(index),
ResultsMetadataConstants.WRITABLE);
+ }
+
+ public String getColumnClassName(int index) throws SQLException {
+ return MMJDBCSQLTypeInfo.getJavaClassName(getColumnType(index));
+ }
+
+}
Copied: trunk/client/src/main/java/org/teiid/jdbc/SQLStates.java (from rev 1983,
trunk/client-jdbc/src/main/java/org/teiid/jdbc/SQLStates.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/SQLStates.java (rev
0)
+++ trunk/client/src/main/java/org/teiid/jdbc/SQLStates.java 2010-03-22 21:01:44 UTC (rev
1986)
@@ -0,0 +1,151 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.util.HashSet;
+import java.util.Set;
+
+
+/**
+ * Utility class containing 1) SQL state constants used to represent JDBC error state
code, and
+ * 2) utility methods to check whether a SQL state belongs to a particular class of
exception states.
+ * @since 4.3
+ */
+public class SQLStates {
+ // Class 80 - connection exception
+
+ /**
+ * Identifies the SQLState class Connection Exception (08).
+ */
+ public static final SQLStateClass CLASS_CONNECTION_EXCEPTION = new SQLStateClass(
+ "08"); //$NON-NLS-1$
+
+ /**
+ * Connection Exception with no subclass (SQL-99 08000)
+ */
+ public static final String CONNECTION_EXCEPTION_NO_SUBCLASS = "08000";
//$NON-NLS-1$
+
+ /**
+ * SQL-client unable to establish SQL-connection (SQL-99 08001)
+ */
+ public static final String
CONNECTION_EXCEPTION_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION = "08001";
//$NON-NLS-1$
+
+ /**
+ * Connection name in use (SQL-99 08002)
+ */
+ public static final String CONNECTION_EXCEPTION_CONNECTION_NAME_IN_USE =
"08002"; //$NON-NLS-1$
+
+ /**
+ * Connection does not exist (SQL-99 08003)
+ */
+ public static final String CONNECTION_EXCEPTION_CONNECTION_DOES_NOT_EXIST =
"08003"; //$NON-NLS-1$
+
+ /**
+ * SQL-server rejected establishment of SQL-connection (SQL-99 08004)
+ */
+ public static final String
CONNECTION_EXCEPTION_SQLSERVER_REJECTED_ESTABLISHMENT_OF_SQLCONNECTION =
"08004"; //$NON-NLS-1$
+
+ /**
+ * Connection failure (SQL-99 08006)
+ */
+ public static final String CONNECTION_EXCEPTION_CONNECTION_FAILURE = "08006";
//$NON-NLS-1$
+
+ /**
+ * Transaction resolution unknown (SQL-99 08007)
+ */
+ public static final String CONNECTION_EXCEPTION_TRANSACTION_RESOLUTION_UNKNOWN =
"08007"; //$NON-NLS-1$
+
+ /**
+ * Connection is stale and should no longer be used. (08S01)
+ * <p>
+ * The SQLState subclass S01 is an implementation-specified condition and
+ * conforms to the subclass DataDirect uses for SocketExceptions.
+ */
+ public static final String CONNECTION_EXCEPTION_STALE_CONNECTION = "08S01";
//$NON-NLS-1$
+
+ // Class 28 - invalid authorization specification
+
+ /**
+ * Identifies the SQLState class Invalid Authorization Specification (28).
+ */
+ public static final SQLStateClass CLASS_INVALID_AUTHORIZATION_SPECIFICATION = new
SQLStateClass(
+ "28"); //$NON-NLS-1$
+
+ /**
+ * Invalid authorization specification with no subclass (SQL-99 28000)
+ */
+ public static final String INVALID_AUTHORIZATION_SPECIFICATION_NO_SUBCLASS =
"28000"; //$NON-NLS-1$
+
+
+ // Class 38 - External Routine Exception (as defined by SQL spec):
+ /** External routine exception. This is the default unknown code */
+ public static final String DEFAULT = "38000"; //$NON-NLS-1$
+
+ public static final String SUCESS = "00000"; //$NON-NLS-1$
+
+ // Class 50 - Query execution errors
+ public static final SQLStateClass CLASS_USAGE_ERROR = new
SQLStateClass("50"); //$NON-NLS-1$
+ /** General query execution error*/
+ public static final String USAGE_ERROR = "50000"; //$NON-NLS-1$
+ /** Error raised by ERROR instruction in virtual procedure.*/
+ public static final String VIRTUAL_PROCEDURE_ERROR = "50001";
//$NON-NLS-1$
+
+ private static final SQLStateClass[] stateClasses = {CLASS_USAGE_ERROR};
+ static {
+ CLASS_USAGE_ERROR.stateCodes.add(USAGE_ERROR);
+ CLASS_USAGE_ERROR.stateCodes.add(VIRTUAL_PROCEDURE_ERROR);
+ }
+
+ public static boolean isSystemErrorState(String sqlStateCode) {
+ return !isUsageErrorState(sqlStateCode);
+ }
+
+ public static boolean isUsageErrorState(String sqlStateCode) {
+ return belongsToClass(sqlStateCode, CLASS_USAGE_ERROR);
+ }
+
+ public static boolean belongsToClass(String sqlStateCode, SQLStateClass
sqlStateClass) {
+ return sqlStateCode.startsWith(sqlStateClass.codeBeginsWith);
+ }
+
+ public static SQLStateClass getClass(String sqlStateCode) {
+ for (int i = 0; i < stateClasses.length; i++) {
+ if (stateClasses[i].containsSQLState(sqlStateCode)) {
+ return stateClasses[i];
+ }
+ }
+ return null;
+ }
+
+ public static final class SQLStateClass {
+ private String codeBeginsWith;
+ private Set stateCodes = new HashSet();
+ private SQLStateClass(String beginsWith) {
+ this.codeBeginsWith = beginsWith;
+ }
+
+ public boolean containsSQLState(String sqlState) {
+ return stateCodes.contains(sqlState);
+ }
+ }
+}
Copied: trunk/client/src/main/java/org/teiid/jdbc/SocketProfile.java (from rev 1983,
trunk/client-jdbc/src/main/java/org/teiid/jdbc/SocketProfile.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/SocketProfile.java
(rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/SocketProfile.java 2010-03-22 21:01:44 UTC
(rev 1986)
@@ -0,0 +1,158 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Enumeration;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.teiid.net.CommunicationException;
+import org.teiid.net.ConnectionException;
+import org.teiid.net.TeiidURL;
+import org.teiid.net.ServerConnection;
+import org.teiid.net.socket.SocketServerConnectionFactory;
+
+import com.metamatrix.common.util.PropertiesUtils;
+import com.metamatrix.core.MetaMatrixCoreException;
+
+/**
+ * <p> The java.sql.DriverManager class uses this class to connect to Teiid Server
or Teiid Embedded.
+ * The TeiidDriver class has a static initializer, which
+ * is used to instantiate and register itself with java.sql.DriverManager. The
+ * DriverManager's <code>getConnection</code> method calls
<code>connect</code>
+ * method on available registered drivers. </p>
+ */
+
+final class SocketProfile {
+
+ private static Logger logger = Logger.getLogger("org.teiid.jdbc");
//$NON-NLS-1$
+
+ /**
+ * Suports JDBC URLS of format
+ * - jdbc:teiid:BQT@mm://localhost:####;version=1
+ * - jdbc:teiid:BQT@mms://localhost:####;version=1
+ * - jdbc:teiid:BQT@mm(s)://host1:####,host2:####,host3:####;version=1
+ */
+
+ // This host/port pattern allows just a . or a - to be in the host part.
+ static final String HOST_PORT_PATTERN = "[\\p{Alnum}\\.\\-]+:\\d+";
//$NON-NLS-1$
+ static final String URL_PATTERN =
"jdbc:(metamatrix|teiid):(\\w+)@((mm[s]?://"+HOST_PORT_PATTERN+"(,"+HOST_PORT_PATTERN+")*)[;]?){1}((.*)*)";
//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ static Pattern urlPattern = Pattern.compile(URL_PATTERN);
+
+ /**
+ * This method tries to make a connection to the given URL. This class
+ * will return a null if this is not the right driver to connect to the given URL.
+ * @param The URL used to establish a connection.
+ * @return Connection object created
+ * @throws SQLException if it is unable to establish a connection to the server.
+ */
+ public static Connection connect(String url, Properties info) throws SQLException {
+
+ ConnectionImpl myConnection = null;
+ // create a properties obj if it is null
+ if(info == null) {
+ info = new Properties();
+ } else {
+ info = PropertiesUtils.clone(info);
+ }
+
+ try {
+ // parse the URL to add it's properties to properties object
+ parseURL(url, info);
+
+ myConnection = createConnection(url, info);
+ } catch (MetaMatrixCoreException e) {
+ logger.log(Level.SEVERE, "Could not create connection", e);
//$NON-NLS-1$
+ throw TeiidSQLException.create(e, e.getMessage());
+ }
+
+ // logging
+ String logMsg =
JDBCPlugin.Util.getString("JDBCDriver.Connection_sucess"); //$NON-NLS-1$
+ logger.fine(logMsg);
+
+ return myConnection;
+ }
+
+ static ConnectionImpl createConnection(String url, Properties info)
+ throws ConnectionException, CommunicationException {
+
+ ServerConnection serverConn =
SocketServerConnectionFactory.getInstance().getConnection(info);
+
+ // construct a MMConnection object.
+ ConnectionImpl connection = new ConnectionImpl(serverConn, info, url);
+ return connection;
+ }
+
+ /**
+ * This method parses the URL and adds properties to the the properties object.
+ * These include required and any optional properties specified in the URL.
+ * @param The URL needed to be parsed.
+ * @param The properties object which is to be updated with properties in the URL.
+ * @throws SQLException if the URL is not in the expected format.
+ */
+ protected static void parseURL(String url, Properties info) throws SQLException {
+ if(url == null) {
+ String msg = JDBCPlugin.Util.getString("MMDriver.urlFormat");
//$NON-NLS-1$
+ throw new TeiidSQLException(msg);
+ }
+ try {
+ JDBCURL jdbcURL = new JDBCURL(url);
+ info.setProperty(BaseDataSource.VDB_NAME, jdbcURL.getVDBName());
+ info.setProperty(TeiidURL.CONNECTION.SERVER_URL,
jdbcURL.getConnectionURL());
+ Properties optionalParams = jdbcURL.getProperties();
+ JDBCURL.normalizeProperties(info);
+ Enumeration keys = optionalParams.keys();
+ while (keys.hasMoreElements()) {
+ String propName = (String)keys.nextElement();
+ // Don't let the URL properties override the passed-in Properties
object.
+ if (!info.containsKey(propName)) {
+ info.setProperty(propName, optionalParams.getProperty(propName));
+ }
+ }
+ // add the property only if it is new because they could have
+ // already been specified either through url or otherwise.
+ if(!info.containsKey(BaseDataSource.VDB_VERSION) &&
jdbcURL.getVDBVersion() != null) {
+ info.setProperty(BaseDataSource.VDB_VERSION, jdbcURL.getVDBVersion());
+ }
+ if(!info.containsKey(BaseDataSource.APP_NAME)) {
+ info.setProperty(BaseDataSource.APP_NAME,
BaseDataSource.DEFAULT_APP_NAME);
+ }
+
+ } catch(IllegalArgumentException iae) {
+ throw new
TeiidSQLException(JDBCPlugin.Util.getString("MMDriver.urlFormat"));
//$NON-NLS-1$
+ }
+ }
+
+
+ public static boolean acceptsURL(String url) {
+ Matcher m = urlPattern.matcher(url);
+ return m.matches();
+ }
+}
+
+
Property changes on: trunk/client/src/main/java/org/teiid/jdbc/SocketProfile.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Copied: trunk/client/src/main/java/org/teiid/jdbc/StatementImpl.java (from rev 1983,
trunk/client-jdbc/src/main/java/org/teiid/jdbc/StatementImpl.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/StatementImpl.java
(rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/StatementImpl.java 2010-03-22 21:01:44 UTC
(rev 1986)
@@ -0,0 +1,1042 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Serializable;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.TimeZone;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.teiid.client.DQP;
+import org.teiid.client.RequestMessage;
+import org.teiid.client.ResultsMessage;
+import org.teiid.client.RequestMessage.ResultsMode;
+import org.teiid.client.metadata.ParameterInfo;
+import org.teiid.client.plan.Annotation;
+import org.teiid.client.plan.PlanNode;
+
+import com.metamatrix.api.exception.MetaMatrixComponentException;
+import com.metamatrix.api.exception.MetaMatrixException;
+import com.metamatrix.api.exception.MetaMatrixProcessingException;
+import com.metamatrix.common.util.SqlUtil;
+import com.metamatrix.core.util.ObjectConverterUtil;
+
+public class StatementImpl extends WrapperImpl implements TeiidStatement {
+ private static Logger logger = Logger.getLogger("org.teiid.jdbc");
//$NON-NLS-1$
+
+ // State constants
+ protected static final int TIMED_OUT = 4;
+ protected static final int CANCELLED = 3;
+ protected static final int NO_TIMEOUT = 0;
+
+ // integer indicating no maximum limit - used in some metadata-ish methods.
+ private static final int NO_LIMIT = 0;
+
+ //######## Configuration state #############
+ private ConnectionImpl driverConnection;
+ private Properties execProps = null;
+
+ // the string which is the XSLT style sheet
+ private String styleSheet;
+
+ // fetch size value. This is the default fetch size used by the server
+ private int fetchSize = BaseDataSource.DEFAULT_FETCH_SIZE;
+
+ // the fetch direction
+ private int fetchDirection = ResultSet.FETCH_FORWARD;
+
+ // the result set type
+ private int resultSetType = ResultSet.TYPE_FORWARD_ONLY;
+ private int resultSetConcurrency = ResultSet.CONCUR_READ_ONLY;
+
+ //######## Processing state #############
+
+ // boolean to indicate if this statement object is closed
+ private boolean isClosed = false;
+
+ // Differentiate timeout from cancel in blocking asynch operation
+ protected int commandStatus = -1;
+
+ // number of seconds for the query to timeout.
+ protected int queryTimeout = NO_TIMEOUT;
+
+ //########## Per-execution state ########
+
+ // ID for current request
+ protected long currentRequestID = -1;
+
+ // the last query plan description
+ private Map currentPlanDescription;
+
+ // the last query debug log
+ private String debugLog;
+
+ // the last query annotations
+ private List<Annotation> annotations;
+
+ // resultSet object produced by execute methods on the statement.
+ protected ResultSetImpl resultSet;
+
+ private List<Exception> serverWarnings;
+
+ // the per-execution security payload
+ private Serializable payload;
+
+ /** List of INSERT, UPDATE, DELETE AND SELECT INTO commands */
+ private List batchedUpdates;
+
+ /** Array of update counts as returned by executeBatch() */
+ protected int[] updateCounts;
+
+ /** default Calendar instance for converting date/time/timestamp values */
+ private Calendar defaultCalendar;
+ /** Max rows to be returned by executing the statement */
+ private int maxRows = NO_LIMIT;
+ private int maxFieldSize = NO_LIMIT;
+
+ /** SPIN_TIMEOUT determines how responsive asynch operations will be to
+ * statement cancellation, closure, or execution timeouts.
+ * 1/2 second was chosen as default.
+ */
+ private static int SPIN_TIMEOUT = 500;
+
+ //Map<out/inout/return param index --> index in results>
+ protected Map outParamIndexMap = new HashMap();
+
+ private Pattern setStatement =
Pattern.compile("\\s*set\\s*(\\w+)\\s*=\\s*(\\w*)", Pattern.CASE_INSENSITIVE);
//$NON-NLS-1$
+
+ /**
+ * Factory Constructor
+ * @param driverConnection
+ * @param resultSetType
+ * @param resultSetConcurrency
+ */
+ static StatementImpl newInstance(ConnectionImpl driverConnection, int resultSetType,
int resultSetConcurrency) {
+ return new StatementImpl(driverConnection, resultSetType, resultSetConcurrency);
+ }
+
+ /**
+ * MMStatement Constructor.
+ * @param driverConnection
+ * @param resultSetType
+ * @param resultSetConcurrency
+ */
+ StatementImpl(ConnectionImpl driverConnection, int resultSetType, int
resultSetConcurrency) {
+ this.driverConnection = driverConnection;
+ this.resultSetType = resultSetType;
+ this.resultSetConcurrency = resultSetConcurrency;
+ this.execProps = new
Properties(this.driverConnection.getConnectionProperties());
+
+ // Set initial fetch size
+ String fetchSizeStr =
this.execProps.getProperty(ExecutionProperties.PROP_FETCH_SIZE);
+ if(fetchSizeStr != null) {
+ try {
+ this.fetchSize = Integer.parseInt(fetchSizeStr);
+ } catch(Exception e) {
+ // silently failover to default
+ }
+ }
+ }
+
+ protected DQP getDQP() {
+ return this.driverConnection.getDQP();
+ }
+
+ protected ConnectionImpl getMMConnection() {
+ return this.driverConnection;
+ }
+
+ protected TimeZone getServerTimeZone() throws SQLException {
+ return this.driverConnection.getServerConnection().getLogonResult().getTimeZone();
+ }
+
+ /**
+ * Reset all per-execution state - this should be done before executing
+ * a new command.
+ */
+ protected void resetExecutionState() throws SQLException {
+ this.currentRequestID = -1;
+
+ this.currentPlanDescription = null;
+ this.debugLog = null;
+ this.annotations = null;
+
+ if ( this.resultSet != null ) {
+ this.resultSet.close();
+ this.resultSet = null;
+ }
+
+ this.serverWarnings = null;
+
+ this.batchedUpdates = null;
+ this.updateCounts = null;
+ this.outParamIndexMap.clear();
+ }
+
+ /**
+ * Adds sql to this statement object's current list of commands.
+ * @param sql statement to be added to the batch
+ */
+ public void addBatch(String sql) throws SQLException {
+ //Check to see the statement is closed and throw an exception
+ checkStatement();
+ if (batchedUpdates == null) {
+ batchedUpdates = new ArrayList();
+ }
+ batchedUpdates.add(sql);
+ }
+
+ /**
+ * This method can be used by one thread to cancel a statement that is being
+ * executed by another thread.
+ * @throws SQLException should never occur.
+ */
+ public void cancel() throws SQLException {
+ /* Defect 19848 - Mark the statement cancelled before sending the CANCEL
request.
+ * Otherwise, it's possible get into a race where the server response is
quicker
+ * than the exception in the exception in the conditionalWait(), which results
in
+ * the statement.executeQuery() call throwing the server's exception instead
of the
+ * one generated by the conditionalWait() method.
+ */
+ commandStatus = CANCELLED;
+ cancelRequest();
+ }
+
+ /**
+ * Warning could be schema validation errors or partial results warnings.
+ * @throws SQLException should never occur.
+ */
+ public void clearWarnings() throws SQLException {
+ //Check to see the statement is closed and throw an exception
+ checkStatement();
+
+ // clear all the warnings on this statement, after this, getWarnings() should
return null
+ serverWarnings = null;
+ }
+
+ /**
+ * Makes the set of commands in the current batch empty.
+ *
+ * @throws SQLException if a database access error occurs or the
+ * driver does not support batch statements
+ */
+ public void clearBatch() throws SQLException {
+ batchedUpdates.clear();
+ }
+
+ /**
+ * In many cases, it is desirable to immediately release a Statements's database
+ * and JDBC resources instead of waiting for this to happen when it is automatically
+ * closed; the close method provides this immediate release.
+ * @throws SQLException should never occur.
+ */
+ public void close() throws SQLException {
+ if ( isClosed ) {
+ return;
+ }
+
+ // close the the server's statement object (if necessary)
+ if(resultSet != null) {
+ resultSet.close();
+ resultSet = null;
+ }
+
+ isClosed = true;
+
+ // Remove link from connection to statement
+ this.driverConnection.closeStatement(this);
+
+
logger.fine(JDBCPlugin.Util.getString("MMStatement.Close_stmt_success"));
//$NON-NLS-1$
+ driverConnection = null;
+ }
+
+ /**
+ * <p> This utility method checks if the jdbc statement is closed and
+ * throws an exception if it is closed. </p>
+ * @throws SQLException if the statement object is closed.
+ */
+ protected void checkStatement() throws SQLException {
+ //Check to see the connection is closed and proceed if it is not
+ if ( isClosed ) {
+ throw new
TeiidSQLException(JDBCPlugin.Util.getString("MMStatement.Stmt_closed"));
//$NON-NLS-1$
+ }
+ }
+
+ //## JDBC4.0-begin ##
+ @Override
+ //## JDBC4.0-end ##
+ public boolean execute(String sql) throws SQLException {
+ executeSql(new String[] {sql}, false, ResultsMode.EITHER);
+ return hasResultSet();
+ }
+
+ //## JDBC4.0-begin ##
+ @Override
+ //## JDBC4.0-end ##
+ public int[] executeBatch() throws SQLException {
+ if (batchedUpdates == null || batchedUpdates.isEmpty()) {
+ return new int[0];
+ }
+ String[] commands = (String[])batchedUpdates.toArray(new
String[batchedUpdates.size()]);
+ executeSql(commands, true, ResultsMode.UPDATECOUNT);
+ return updateCounts;
+ }
+
+ //## JDBC4.0-begin ##
+ @Override
+ //## JDBC4.0-end ##
+ public ResultSet executeQuery(String sql) throws SQLException {
+ executeSql(new String[] {sql}, false, ResultsMode.RESULTSET);
+ return resultSet;
+ }
+
+ //## JDBC4.0-begin ##
+ @Override
+ //## JDBC4.0-end ##
+ public int executeUpdate(String sql) throws SQLException {
+ String[] commands = new String[] {sql};
+ executeSql(commands, false, ResultsMode.UPDATECOUNT);
+ return this.updateCounts[0];
+ }
+
+ protected boolean hasResultSet() throws SQLException {
+ return resultSet != null && resultSet.getMetaData().getColumnCount() >
0;
+ }
+
+ protected void createResultSet(ResultsMessage resultsMsg) throws SQLException {
+ //create out/return parameter index map if there is any
+ List listOfParameters = resultsMsg.getParameters();
+ if(listOfParameters != null){
+ //get the size of result set
+ int resultSetSize = 0;
+ Iterator iteratorOfParameters = listOfParameters.iterator();
+ while(iteratorOfParameters.hasNext()){
+ ParameterInfo parameter = (ParameterInfo)iteratorOfParameters.next();
+ if(parameter.getType() == ParameterInfo.RESULT_SET){
+ resultSetSize = parameter.getNumColumns();
+ //one ResultSet only
+ break;
+ }
+ }
+
+ //return needs to be the first
+ int index = 0; //index in user call - {?=call sp(?)}
+ int count = 0;
+ iteratorOfParameters = listOfParameters.iterator();
+ while(iteratorOfParameters.hasNext()){
+ ParameterInfo parameter = (ParameterInfo)iteratorOfParameters.next();
+ if(parameter.getType() == ParameterInfo.RETURN_VALUE){
+ count++;
+ index++;
+ outParamIndexMap.put(new Integer(index), new Integer(resultSetSize +
count));
+ break;
+ }
+ }
+
+ iteratorOfParameters = listOfParameters.iterator();
+ while(iteratorOfParameters.hasNext()){
+ ParameterInfo parameter = (ParameterInfo)iteratorOfParameters.next();
+ if(parameter.getType() != ParameterInfo.RETURN_VALUE &&
parameter.getType() != ParameterInfo.RESULT_SET){
+ index++;
+ if(parameter.getType() == ParameterInfo.OUT || parameter.getType() ==
ParameterInfo.INOUT){
+ count++;
+ outParamIndexMap.put(new Integer(index), new Integer(resultSetSize +
count));
+ }
+ }
+ }
+ }
+
+ resultSet = new ResultSetImpl(resultsMsg, this, null, outParamIndexMap.size());
+ resultSet.setMaxFieldSize(this.maxFieldSize);
+ }
+
+ protected void executeSql(String[] commands, boolean isBatchedCommand, ResultsMode
resultsMode)
+ throws SQLException, TeiidSQLException {
+ checkStatement();
+ resetExecutionState();
+
+ //handle set statement
+ if (commands.length == 1 && resultsMode != ResultsMode.RESULTSET) {
+ Matcher match = setStatement.matcher(commands[0]);
+ if (match.matches()) {
+ String key = match.group(1);
+ String value = match.group(2);
+ this.driverConnection.getConnectionProperties().setProperty(key, value);
+ this.updateCounts = new int[] {0};
+ return;
+ }
+ }
+
+ RequestMessage reqMessage = createRequestMessage(commands, isBatchedCommand,
resultsMode);
+ ResultsMessage resultsMsg = null;
+ try {
+ resultsMsg = sendRequestMessageAndWait(reqMessage);
+ } catch ( Throwable ex ) {
+ String msg =
JDBCPlugin.Util.getString("MMStatement.Error_executing_stmt",
reqMessage.getCommandString()); //$NON-NLS-1$
+ logger.log(Level.SEVERE, msg, ex);
+ throw TeiidSQLException.create(ex, msg);
+ }
+
+ // warnings thrown
+ List resultsWarning = resultsMsg.getWarnings();
+
+ setAnalysisInfo(resultsMsg);
+
+ if (resultsMsg.getException() != null) {
+ throw TeiidSQLException.create(resultsMsg.getException());
+ }
+
+ // save warnings if have any
+ if (resultsWarning != null) {
+ accumulateWarnings(resultsWarning);
+ }
+
+ if (resultsMsg.isUpdateResult()) {
+ List[] results = resultsMsg.getResults();
+ this.updateCounts = new int[results.length];
+ for (int i = 0; i < results.length; i++) {
+ updateCounts[i] = (Integer)results[i].get(0);
+ }
+
+ // In update scenarios close the statement implicitly
+ try {
+ getDQP().closeRequest(getCurrentRequestID());
+ } catch (MetaMatrixProcessingException e) {
+ throw TeiidSQLException.create(e);
+ } catch (MetaMatrixComponentException e) {
+ throw TeiidSQLException.create(e);
+ }
+ } else {
+ createResultSet(resultsMsg);
+ }
+
+ logger.fine(JDBCPlugin.Util.getString("MMStatement.Success_query",
reqMessage.getCommandString())); //$NON-NLS-1$
+ }
+
+ protected RequestMessage createRequestMessage(String[] commands,
+ boolean isBatchedCommand, ResultsMode resultsMode) {
+ RequestMessage reqMessage = new RequestMessage();
+ reqMessage.setCommands(commands);
+ reqMessage.setBatchedUpdate(isBatchedCommand);
+ reqMessage.setResultsMode(resultsMode);
+ return reqMessage;
+ }
+
+ /**
+ * Retreives the fetch direction this Statement object set as a performance hint
+ * to the driver. The int returned will be one of the following constants from
+ * the ResultSet interface: FETCH_FORWARD, FETCH_REVERSE, or FETCH_UNKNOWN.
+ * @return int value indicating the direction in which results need to be fetched
+ * @throws SQLException should never occur.
+ */
+ public int getFetchDirection() throws SQLException {
+ return this.fetchDirection;
+ }
+
+ /**
+ * Retreives the fetch size this Statement object set as a performance hint
+ * to the driver. This is the number of rows the server fetches at a time when
+ * the result set needs more rows.
+ * @return int value indicating the number of rows the server fetches
+ * @throws SQLException should never occur.
+ */
+ public int getFetchSize() throws SQLException {
+ return fetchSize;
+ }
+
+ /**
+ * Retreives the maximum number of bytes that a result set column may contain.
+ * @return int value giving the maximum size of a field
+ * @throws SQLException should never occur.
+ */
+ public int getMaxFieldSize() throws SQLException {
+ return maxFieldSize;
+ }
+
+ /**
+ * Retrives the maximum number of rows that a ResultSet object may contain.
+ * If the limit is exceeded the excess rows are dropped.
+ * @return Max limit on rows on ResultSet.
+ * @throws SQLException should never iccure.
+ */
+ public int getMaxRows() throws SQLException {
+ return maxRows;
+ }
+
+ /**
+ * Moves to this Statement object's next result, returns true if
+ * it is a ResultSet object, and implicitly closes any current
+ * ResultSet object(s) obtained with the method #getResultSet.
+ * @return true if the next result is a ResultSet object;
+ * false if it is an update count or there are no more results
+ * @throws SQLException if there is an error in database.
+ */
+ public boolean getMoreResults() throws SQLException {
+ //Check to see the statement is closed and throw an exception
+ checkStatement();
+
+ // close any current ResultSet
+ if ( resultSet != null ) {
+ resultSet.close();
+ resultSet = null;
+ }
+ // set the existing update count to -1
+ // indicating that there are no more results
+ this.updateCounts = null;
+ return false;
+ }
+
+ /**
+ * Moves to this Statement object's next result, deals with any current
+ * ResultSet object(s) according to the instructions specified by the
+ * given flag, and returns true if the next result is a ResultSet object.
+ * @param current flag that gives instruction on what should happen
+ * to current ResultSet objects obtained using the method getResultSet(
+ * CLOSE_CURRENT_RESULT, KEEP_CURRENT_RESULT, or CLOSE_ALL_RESULTS).
+ * @return true if the next result is a ResultSet object; false if it
+ * is an update count or there are no more results
+ * @throws SQLException if there is an error in database.
+ */
+ public boolean getMoreResults(int current) throws SQLException {
+ checkStatement();
+
+ /*if (current == CLOSE_ALL_RESULTS || current == CLOSE_CURRENT_RESULT) {
+ // since MetaMatrix only supports one ResultSet per statement,
+ // these two cases are handled the same way.
+ if (resultSet != null) {
+ resultSet.close();
+ }
+ } else if (current == KEEP_CURRENT_RESULT) {
+ // do nothing
+ }
+
+ rowsAffected = -1;
+ */
+ return false;
+ }
+
+
+ /**
+ * Return the number of seconds the driver will wait for a statement object
+ * to execute
+ * @return int value giving the query timeout in seconds
+ * @throws SQLException should never occur
+ */
+ public int getQueryTimeout() throws SQLException {
+ //Check to see the statement is closed and throw an exception
+ checkStatement();
+ return this.queryTimeout;
+ }
+
+ /**
+ * Returns a ResultSet object that was produced by a call to the method execute.
+ * We currently do not support execute method which could return multiple result
+ * sets.
+ * @return ResultSet object giving the next available ResultSet
+ * @throws SQLException should never occur
+ */
+ public ResultSet getResultSet() throws SQLException {
+ //Check to see the statement is closed and throw an exception
+ checkStatement();
+ if (!hasResultSet()) {
+ return null;
+ }
+ return resultSet;
+ }
+
+ /**
+ * Retrieves the concurrency mode for the ResultSet objects generated from
+ * queries that this Statement object executes. All ResultSets are currently
+ * read only.
+ * @return intvalue giving the ResultSet concurrency
+ * @throws SQLException should never occur
+ */
+ public int getResultSetConcurrency() throws SQLException {
+ return this.resultSetConcurrency;
+ }
+
+ /**
+ * Retrieves the type of the ResultSet objects generated from queries that this
+ * statement executes.
+ * @return int value indicating the type of the ResultSet
+ * @throws SQLException should never occur
+ */
+ public int getResultSetType() {
+ return this.resultSetType;
+ }
+
+ /**
+ * This method returns the number of rows affected by a statement modifying a table.
+ * @return Number of rows affected.
+ * @throws SQLException should never occur
+ */
+ public int getUpdateCount() throws SQLException {
+ checkStatement();
+ if (this.updateCounts == null) {
+ return -1;
+ }
+ return this.updateCounts[0];
+ }
+
+ protected void accumulateWarnings(List<Exception> serverWarnings) {
+ if (serverWarnings == null || serverWarnings.isEmpty()) {
+ return;
+ }
+ if (this.serverWarnings == null) {
+ this.serverWarnings = new ArrayList<Exception>();
+ }
+ this.serverWarnings.addAll(serverWarnings);
+ }
+
+ /**
+ * This method returns warnings returned by server.
+ * @return null value as there are no warnings
+ * @throws SQLException should never occur
+ */
+ public SQLWarning getWarnings() throws SQLException {
+ //Check to see the statement is closed and throw an exception
+ checkStatement();
+
+ if (serverWarnings != null && serverWarnings.size() != 0) {
+ return WarningUtil.convertWarnings(serverWarnings);
+ }
+ return null;
+ }
+
+ /**
+ * This method enbles/disables escape processing. When escape processing is
+ * enabled the driver will scan any escape syntax and do escape substitution
+ * before sending the escaped sql statement to the server
+ * @param enable boolean value indicating if the escape processing should be turned
on
+ * @throws SQLException should never occur
+ */
+ public void setEscapeProcessing(boolean enable) throws SQLException {
+ //Check to see the statement is closed and throw an exception
+ checkStatement();
+ // do nothing, escape processing is always enabled.
+ }
+
+ public void setFetchDirection(int direction) throws SQLException {
+ checkStatement();
+ }
+
+ public void setFetchSize(int rows) throws SQLException {
+ //Check to see the statement is closed and throw an exception
+ checkStatement();
+ if ( rows < 0 ) {
+ String msg =
JDBCPlugin.Util.getString("MMStatement.Invalid_fetch_size"); //$NON-NLS-1$
+ throw new TeiidSQLException(msg);
+ }
+ // sets the fetch size on this statement
+ if (rows == 0) {
+ this.fetchSize = BaseDataSource.DEFAULT_FETCH_SIZE;
+ } else {
+ this.fetchSize = rows;
+ }
+ }
+
+ /**
+ * Sets the limit on the maximum number of rows in a ResultSet object. This
+ * method is currently implemented to throw an exception as it is not possible
+ * to limit the number of rows.
+ * @param maxRows int value indicating maximum rows that can be returned in a
ResultSet
+ */
+ public void setMaxRows(int maxRows) throws SQLException {
+ //Check to see the statement is closed and throw an exception
+ checkStatement();
+ this.maxRows = maxRows;
+ }
+
+ /**
+ * This sets to seconds the time limit for the number of seconds for a driver
+ * to wait for a statement object to be executed.
+ * @param seconds Maximum number of seconds for a statement object to execute.
+ * throws SQLException, should never occur
+ */
+ public void setQueryTimeout(int seconds) throws SQLException {
+ //Check to see the statement is closed and throw an exception
+ checkStatement();
+ if (seconds >= 0) {
+ queryTimeout = seconds;
+ }
+ else {
+ throw new
TeiidSQLException(JDBCPlugin.Util.getString("MMStatement.Bad_timeout_value"));
//$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Helper method for copy the connection properties to request message.
+ * @param res Request message that these properties to be copied to.
+ * @throws TeiidSQLException
+ */
+ protected void copyPropertiesToRequest(RequestMessage res) throws TeiidSQLException
{
+ // Get partial mode
+ String partial =
getExecutionProperty(ExecutionProperties.PROP_PARTIAL_RESULTS_MODE);
+ res.setPartialResults(Boolean.valueOf(partial).booleanValue());
+
+ // Get xml validation mode
+ String validate = getExecutionProperty(ExecutionProperties.PROP_XML_VALIDATION);
+ if(validate == null) {
+ res.setValidationMode(false);
+ } else {
+ res.setValidationMode(Boolean.valueOf(validate).booleanValue());
+ }
+
+ // Get xml format mode
+ String format = getExecutionProperty(ExecutionProperties.PROP_XML_FORMAT);
+ res.setXMLFormat(format);
+
+ // Get transaction auto-wrap mode
+ String txnAutoWrapMode =
getExecutionProperty(ExecutionProperties.PROP_TXN_AUTO_WRAP);
+ try {
+ res.setTxnAutoWrapMode(txnAutoWrapMode);
+ } catch (MetaMatrixProcessingException e) {
+ throw TeiidSQLException.create(e);
+ }
+
+ // Get result set cache mode
+ String rsCache =
getExecutionProperty(ExecutionProperties.RESULT_SET_CACHE_MODE);
+ res.setUseResultSetCache(Boolean.valueOf(rsCache).booleanValue());
+
+ res.setAnsiQuotedIdentifiers(Boolean.valueOf(
+ getExecutionProperty(ExecutionProperties.ANSI_QUOTED_IDENTIFIERS))
+ .booleanValue());
+ String sqlOptions = getExecutionProperty(ExecutionProperties.PROP_SQL_OPTIONS);
+ if (sqlOptions != null &&
+
sqlOptions.toUpperCase().indexOf(ExecutionProperties.SQL_OPTION_SHOWPLAN.toUpperCase())
>= 0) {
+ res.setShowPlan(true);
+ }
+ }
+
+ /**
+ * Ends the command and sets the status to TIMED_OUT.
+ */
+ protected void timeoutOccurred() {
+
logger.warning(JDBCPlugin.Util.getString("MMStatement.Timeout_ocurred_in_Statement."));
//$NON-NLS-1$
+ try {
+ cancel();
+ commandStatus = TIMED_OUT;
+ queryTimeout = NO_TIMEOUT;
+ currentRequestID = -1;
+ if (this.resultSet != null) {
+ this.resultSet.close();
+ }
+ } catch (SQLException se) {
+ logger.log(Level.SEVERE,
JDBCPlugin.Util.getString("MMStatement.Error_timing_out."), se); //$NON-NLS-1$
+ }
+ }
+
+ protected void cancelRequest() throws SQLException {
+ checkStatement();
+
+ try {
+ this.getDQP().cancelRequest(currentRequestID);
+ } catch (MetaMatrixProcessingException e) {
+ throw TeiidSQLException.create(e);
+ } catch (MetaMatrixComponentException e) {
+ throw TeiidSQLException.create(e);
+ }
+ }
+
+ /**
+ * Set the per-statement security payload. This optional payload will
+ * accompany each request to the data source(s) so that the connector
+ * will have access to it.
+ * <br>Once the payload is set, it will be used for each statment
+ * execution until it is set to <code>null</code>, a new payload is set
on
+ * the statement or the statement is closed.</br>
+ *
+ * <p>To remove an existing payload from a statement, call this method
+ * with a <code>null</code> argument.</p>
+ * @param payload The payload that is to accompany requests executed
+ * from this statement.
+ * @since 4.2
+ */
+ public void setPayload(Serializable payload) {
+ this.payload = payload;
+ }
+
+ public void setExecutionProperty(String name, String value) {
+ this.execProps.put(name, value);
+ }
+
+ public String getExecutionProperty(String name) {
+ return (String) this.execProps.get(name);
+ }
+
+ /**
+ * Send out request message with necessary states.
+ */
+ protected ResultsMessage sendRequestMessageAndWait(RequestMessage reqMsg)
+ throws SQLException, InterruptedException, TimeoutException {
+ this.currentRequestID = this.driverConnection.nextRequestID();
+ // Create a request message
+ reqMsg.setExecutionPayload(this.payload);
+ reqMsg.setCursorType(this.resultSetType);
+ reqMsg.setFetchSize(this.fetchSize);
+ reqMsg.setStyleSheet(this.styleSheet);
+ reqMsg.setRowLimit(this.maxRows);
+ reqMsg.setTransactionIsolation(this.driverConnection.getTransactionIsolation());
+
+ // Get connection properties and set them onto request message
+ copyPropertiesToRequest(reqMsg);
+
+ reqMsg.setExecutionId(this.currentRequestID);
+
+ Future<ResultsMessage> pendingResult = null;
+ try {
+ pendingResult = this.getDQP().executeRequest(this.currentRequestID, reqMsg);
+ } catch (MetaMatrixException e) {
+ throw TeiidSQLException.create(e);
+ }
+ long timeoutMillis = queryTimeout * 1000;
+ long endTime = System.currentTimeMillis() + timeoutMillis;
+ ResultsMessage result = null;
+ while (result == null) {
+
+ if (timeoutMillis > 0 && endTime <= System.currentTimeMillis()
&& commandStatus != TIMED_OUT && commandStatus != CANCELLED) {
+ timeoutOccurred();
+ }
+
+ checkStatement();
+ try {
+ result = pendingResult.get(SPIN_TIMEOUT, TimeUnit.MILLISECONDS);
+ } catch (ExecutionException e) {
+ throw TeiidSQLException.create(e);
+ } catch (TimeoutException e) {
+ continue;
+ }
+ }
+
+ if (commandStatus == CANCELLED) {
+ throw new
TeiidSQLException(JDBCPlugin.Util.getString("MMStatement.Cancel_before_execute"));
//$NON-NLS-1$
+ }
+
+ if (commandStatus == TIMED_OUT) {
+ throw new
TimeoutException(JDBCPlugin.Util.getString("MMStatement.Timeout_before_complete"));
//$NON-NLS-1$
+ }
+ return result;
+ }
+
+ long getCurrentRequestID() {
+ return this.currentRequestID;
+ }
+
+ /**
+ * <p> This method sets a style sheet to this object. The style sheet is
+ * to perform transformations.
+ * @param reader The reader object from which the styleSheet is to be read
+ * @throws IOException if unable to read the style sheet from the Reader object.
+ */
+ public void attachStylesheet(Reader reader) throws IOException {
+ this.styleSheet = ObjectConverterUtil.convertToString(reader);
+ }
+
+ /**
+ * <p> This method removes any existing style sheet on this object.
+ */
+ public void clearStylesheet() {
+ this.styleSheet = null;
+ }
+
+ void setPlanDescription(Map planDescription) {
+ this.currentPlanDescription = planDescription;
+ }
+
+ void setDebugLog(String debugLog) {
+ this.debugLog = debugLog;
+ }
+
+ void setAnnotations(List<Annotation> annotations) {
+ this.annotations = annotations;
+ }
+
+ /**
+ * Get Query plan description.
+ * If the Statement has a resultSet, we get the plan description from the result set
+ * If that plan description is null, though, we return the very first plan
description
+ * that was created from the resultsMessage in the method: setAnalysisInfo.
+ * The plan description from the result set can be null if the resultsMsg stored in
the
+ * result set hasn't been created when getPlanDescription is called.
+ * @return Query plan description, if it exists, otherwise null
+ */
+ public PlanNode getPlanDescription() {
+ Map planDescription = null;
+ if(this.resultSet != null) {
+ planDescription = this.resultSet.getUpdatedPlanDescription();
+ }
+ if(planDescription != null) {
+ this.currentPlanDescription = planDescription;
+ return PlanNode.constructFromMap(this.currentPlanDescription);
+ }else if(this.currentPlanDescription != null) {
+ return PlanNode.constructFromMap(this.currentPlanDescription);
+ }
+ return null;
+ }
+
+ /**
+ * Get query planner debug log.
+ * @return Query planner debug log, or null if it doesn't exist
+ */
+ public String getDebugLog() {
+ return this.debugLog;
+ }
+
+ /**
+ * Get annotations
+ * @return Query planner annotations - Collection of Annotation
+ */
+ public Collection<Annotation> getAnnotations() {
+ return this.annotations;
+ }
+
+ public void setPartialResults(boolean isPartialResults){
+ if(isPartialResults){
+ this.execProps.put(ExecutionProperties.PROP_PARTIAL_RESULTS_MODE,
"true"); //$NON-NLS-1$
+ }
+ }
+
+ public String getRequestIdentifier() {
+ if(this.currentRequestID >= 0) {
+ return Long.toString(this.currentRequestID);
+ }
+ return null;
+ }
+
+ /**
+ * Check is the statement is closed. Used primarily by the unit tests.
+ * @return true if the statement is closed; false otherwise.
+ */
+ public boolean isClosed() {
+ return this.isClosed;
+ }
+
+ protected void setAnalysisInfo(ResultsMessage resultsMsg) {
+ this.debugLog = resultsMsg.getDebugLog();
+ this.currentPlanDescription = resultsMsg.getPlanDescription();
+ Collection serverAnnotations = resultsMsg.getAnnotations();
+ if(serverAnnotations != null) {
+ List<Annotation> annotations = new
ArrayList<Annotation>(serverAnnotations.size());
+ Iterator annIter = serverAnnotations.iterator();
+ while(annIter.hasNext()) {
+ String[] serverAnnotation = (String[]) annIter.next();
+ Annotation annotation = new Annotation(serverAnnotation);
+ annotations.add(annotation);
+ }
+ this.annotations = annotations;
+ }
+ }
+
+ Calendar getDefaultCalendar() {
+ if (defaultCalendar == null) {
+ defaultCalendar = Calendar.getInstance();
+ }
+ return defaultCalendar;
+ }
+
+ void setDefaultCalendar(Calendar cal) {
+ this.defaultCalendar = cal;
+ }
+
+ public boolean isPoolable() throws SQLException {
+ checkStatement();
+ return false;
+ }
+
+ public void setPoolable(boolean arg0) throws SQLException {
+ checkStatement();
+ }
+
+ public Connection getConnection() throws SQLException {
+ return this.driverConnection;
+ }
+
+ public boolean execute(String sql, int autoGeneratedKeys)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public boolean execute(String sql, int[] columnIndexes) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public boolean execute(String sql, String[] columnNames)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public int executeUpdate(String sql, int autoGeneratedKeys)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public int executeUpdate(String sql, int[] columnIndexes)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public int executeUpdate(String sql, String[] columnNames)
+ throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public ResultSet getGeneratedKeys() throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public int getResultSetHoldability() throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setCursorName(String name) throws SQLException {
+ throw SqlUtil.createFeatureNotSupportedException();
+ }
+
+ public void setMaxFieldSize(int max) throws SQLException {
+ checkStatement();
+ if ( max < 0 ) {
+ throw new
TeiidSQLException(JDBCPlugin.Util.getString("MMStatement.Invalid_field_size"));
//$NON-NLS-1$
+ }
+ this.maxFieldSize = max;
+ }
+}
\ No newline at end of file
Copied: trunk/client/src/main/java/org/teiid/jdbc/TeiidDataSource.java (from rev 1983,
trunk/client-jdbc/src/main/java/org/teiid/jdbc/TeiidDataSource.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/TeiidDataSource.java
(rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/TeiidDataSource.java 2010-03-22 21:01:44 UTC
(rev 1986)
@@ -0,0 +1,479 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.Connection;
+import java.util.Properties;
+
+import org.teiid.net.TeiidURL;
+
+
+/**
+ * The Teiid JDBC DataSource implementation class of {@link javax.sql.DataSource} and
+ * {@link javax.sql.XADataSource}.
+ * <p>
+ * The {@link javax.sql.DataSource} interface follows the JavaBean design pattern,
+ * meaning the implementation class has <i>properties</i> that are accessed
with getter methods
+ * and set using setter methods, and where the getter and setter methods follow the
JavaBean
+ * naming convention (e.g.,
<code>get</code><i>PropertyName</i><code>() :
</code><i>PropertyType</i>
+ * and
<code>set</code><i>PropertyName</i><code>(</code><i>PropertyType</i><code>)
: void</code>).
+ * </p>
+ * The {@link javax.sql.XADataSource} interface is almost identical to the {@link
javax.sql.DataSource}
+ * interface, but rather than returning {@link java.sql.Connection} instances, there are
methods that
+ * return {@link javax.sql.XAConnection} instances that can be used with distributed
transactions.
+ * <p>
+ * The following are the properties for this DataSource:
+ * <table cellspacing="0" cellpadding="0" border="1"
width="100%">
+ * <tr><td><b>Property
Name</b></td><td><b>Type</b></td><td><b>Description</b></td></tr>
+ * <tr><td>portNumber </td><td><code>int
</code></td><td>The port number where a Teiid Server is listening
+ * for
requests.</td></tr>
+ * <tr><td>serverName
</td><td><code>String</code></td><td>The hostname or
IP address of the Teiid Server.</td></tr>
+ * <table>
+ * If "serverName" property is not set then data source will try to create a
embedded connection to the Teiid server.
+ * </p>
+ */
+public class TeiidDataSource extends BaseDataSource {
+
+ private static final long serialVersionUID = -5170316154373144878L;
+
+ /**
+ * The port number where a server is listening for requests.
+ * This property name is one of the standard property names defined by the JDBC 2.0
specification,
+ * and is <i>optional</i>.
+ */
+ private int portNumber;
+
+ /**
+ * The name of the host where the sServer is running.
+ * This property name is one of the standard property names defined by the JDBC 2.0
specification,
+ * and is <i>required</i>.
+ */
+ private String serverName;
+
+ /**
+ * Specify whether to make a secure (SSL, mms:) connection or a normal non-SSL mm:
connection.
+ * the default is to use a non-secure connection.
+ * @since 5.0.2
+ */
+ private boolean secure = false;
+
+ /**
+ * Holds a comma delimited list of alternate Server(s):Port(s) that can
+ * be used for connection fail-over.
+ * @since 5.5
+ */
+ private String alternateServers;
+
+ /**
+ * The auto failover mode for calls made to the query engine. If true query engine
calls that fail will
+ * allow the connection to choose another process.
+ */
+ private String autoFailover;
+
+ private String discoveryStrategy;
+
+ /**
+ * Constructor for MMDataSource.
+ */
+ public TeiidDataSource() {
+ }
+
+ //
--------------------------------------------------------------------------------------------
+ // H E L P E R M E T H O D S
+ //
--------------------------------------------------------------------------------------------
+
+ protected Properties buildProperties(final String userName, final String password) {
+ Properties props = super.buildProperties(userName, password);
+
+ if (this.getAutoFailover() != null) {
+ props.setProperty(TeiidURL.CONNECTION.AUTO_FAILOVER,
this.getAutoFailover());
+ }
+
+ if (this.getDiscoveryStrategy() != null) {
+ props.setProperty(TeiidURL.CONNECTION.DISCOVERY_STRATEGY,
this.getDiscoveryStrategy());
+ }
+
+ return props;
+ }
+
+ private Properties buildServerProperties(final String userName, final String
password) {
+ Properties props = buildProperties(userName, password);
+
+ props.setProperty(TeiidURL.CONNECTION.SERVER_URL,this.buildServerURL());
+
+ return props;
+ }
+
+ protected String buildServerURL() {
+ if ( this.alternateServers == null ) {
+ // Format: "mm://server:port"
+ return new TeiidURL(this.serverName, this.portNumber,
this.secure).getAppServerURL();
+ }
+
+ // Format: "mm://server1:port,server2:port,..."
+ String serverURL = ""; //$NON-NLS-1$
+
+ serverURL = "" + ( this.secure ? TeiidURL.SECURE_PROTOCOL :
TeiidURL.DEFAULT_PROTOCOL ); //$NON-NLS-1$
+ serverURL += "" + this.serverName; //$NON-NLS-1$
+ if ( this.portNumber != 0 )
+ serverURL += TeiidURL.COLON_DELIMITER + this.portNumber;
+ if ( this.alternateServers.length() > 0 ) {
+ String[] as = this.alternateServers.split( TeiidURL.COMMA_DELIMITER);
+
+ for ( int i = 0; i < as.length; i++ ) {
+ String[] server = as[i].split( TeiidURL.COLON_DELIMITER );
+
+ if ( server.length > 0 ) {
+ serverURL += TeiidURL.COMMA_DELIMITER + server[0];
+ if ( server.length > 1 ) {
+ serverURL += TeiidURL.COLON_DELIMITER + server[1];
+ } else {
+ serverURL += TeiidURL.COLON_DELIMITER + this.portNumber;
+ }
+ }
+ }
+ }
+
+ return new TeiidURL(serverURL).getAppServerURL();
+ }
+
+ protected String buildURL() {
+ return new JDBCURL(this.getDatabaseName(), buildServerURL(),
buildProperties(getUser(), getPassword())).getJDBCURL();
+ }
+
+ protected void validateProperties( final String userName, final String password)
throws java.sql.SQLException {
+ super.validateProperties(userName, password);
+
+ String reason = reasonWhyInvalidPortNumber(this.portNumber);
+ if ( reason != null ) {
+ throw createConnectionError(reason);
+ }
+
+ reason = reasonWhyInvalidServerName(this.serverName);
+ if ( reason != null ) {
+ throw createConnectionError(reason);
+ }
+
+ reason = reasonWhyInvalidAlternateServers(this.alternateServers);
+ if ( reason != null) {
+ throw createConnectionError(reason);
+ }
+ }
+
+ private TeiidSQLException createConnectionError(String reason) {
+ String msg = JDBCPlugin.Util.getString("MMDataSource.Err_connecting",
reason); //$NON-NLS-1$
+ return new TeiidSQLException(msg);
+ }
+
+ //
--------------------------------------------------------------------------------------------
+ // D A T A S O U R C E M E T H O D S
+ //
--------------------------------------------------------------------------------------------
+
+ /**
+ * Attempt to establish a database connection.
+ * @return a Connection to the database
+ * @throws java.sql.SQLException if a database-access error occurs
+ * @see javax.sql.DataSource#getConnection()
+ */
+ public Connection getConnection() throws java.sql.SQLException {
+ return getConnection(null,null);
+ }
+
+ /**
+ * Attempt to establish a database connection.
+ * @param userName the database user on whose behalf the Connection is being made
+ * @param password the user's password
+ * @return a Connection to the database
+ * @throws java.sql.SQLException if a database-access error occurs
+ * @see javax.sql.DataSource#getConnection(java.lang.String, java.lang.String)
+ */
+ public Connection getConnection(String userName, String password) throws
java.sql.SQLException {
+ final TeiidDriver driver = new TeiidDriver();
+
+ // check if this is embedded connection
+ if (getServerName() == null) {
+ final Properties props = buildEmbeddedProperties(userName, password);
+ String url = new JDBCURL(getDatabaseName(), null, props).getJDBCURL();
+ return driver.connect(url, props);
+ }
+
+ // if not proceed with socket connection.
+ validateProperties(userName,password);
+ final Properties props = buildServerProperties(userName, password);
+ return driver.connect(buildURL(), props);
+
+ }
+
+ private Properties buildEmbeddedProperties(final String userName, final String password)
{
+ Properties props = buildProperties(userName, password);
+ return props;
+ }
+
+ /**
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ return buildURL();
+ }
+
+ //
--------------------------------------------------------------------------------------------
+ // P R O P E R T Y M E T H O D S
+ //
--------------------------------------------------------------------------------------------
+
+ /**
+ * Returns the port number.
+ * @return the port number
+ */
+ public int getPortNumber() {
+ return portNumber;
+ }
+
+ /**
+ * Returns the name of the server.
+ * @return the name of the server
+ */
+ public String getServerName() {
+ return serverName;
+ }
+
+ /**
+ * Returns a flag indicating whether to create a secure connection or not.
+ * @return True if using secure mms: protocol, false for normal mm: protocol.
+ * @since 5.0.2
+ */
+ public boolean isSecure() {
+ return this.secure;
+ }
+
+ /**
+ * Returns a string containing a comma delimited list of alternate
+ * MetaMatrix Server(s).
+ *
+ * The list will be in the form of server2[:port2][,server3[:port3]]. If no
+ * alternate servers have been defined <code>null</code> is returned.
+ * @return A comma delimited list of server:port or <code>null</code> If
+ * no alternate servers are defined.
+ * @since 5.5
+ */
+ public String getAlternateServers() {
+ if ( this.alternateServers != null && this.alternateServers.length() < 1
)
+ return null;
+ return this.alternateServers;
+ }
+
+ /**
+ * Sets the portNumber.
+ * @param portNumber The portNumber to set
+ */
+ public void setPortNumber(final int portNumber) {
+ this.portNumber = portNumber;
+ }
+
+ /**
+ * Sets the serverName.
+ * @param serverName The serverName to set
+ */
+ public void setServerName(final String serverName) {
+ this.serverName = serverName;
+ }
+
+ /**
+ * Sets the secure flag to use mms: protocol instead of the default mm: protocol.
+ * @param secure True to use mms:
+ * @since 5.0.2
+ */
+ public void setSecure(final boolean secure) {
+ this.secure = secure;
+ }
+
+ /**
+ * Sets a list of alternate server(s) that can be used for
+ * connection fail-over.
+ *
+ * The form of the list should be server2[:port2][,server3:[port3][,...]].
+ *
+ * If ":port" is omitted, the port defined by
<code>portNumber</code> is used.
+ *
+ * If <code>servers</code> is empty or <code>null</code>, the
value of
+ * <code>alternateServers</code> is cleared.
+ * @param servers A comma delimited list of alternate
+ * Server(s):Port(s) to use for connection fail-over. If blank or
+ * <code>null</code>, the list is cleared.
+ * @since 5.5
+ */
+ public void setAlternateServers(final String servers) {
+ this.alternateServers = servers;
+ if ( this.alternateServers != null && this.alternateServers.length() < 1
)
+ this.alternateServers = null;
+ }
+
+
+ //
--------------------------------------------------------------------------------------------
+ // V A L I D A T I O N M E T H O D S
+ //
--------------------------------------------------------------------------------------------
+
+ /**
+ * Return the reason why the supplied port number may be invalid, or null
+ * if it is considered valid.
+ * @param portNumber a possible value for the property
+ * @return the reason why the property is invalid, or null if it is considered valid
+ * @see #setPortNumber(int)
+ */
+ public static String reasonWhyInvalidPortNumber( final int portNumber) {
+ if ( portNumber == 0 ) {
+ return null; // default is always fine
+ }
+ if ( portNumber < 1 ) {
+ return
JDBCPlugin.Util.getString("MMDataSource.Port_number_must_be_positive");
//$NON-NLS-1$
+ }
+ return null;
+ }
+
+ /**
+ * Return the reason why the supplied server name may be invalid, or null
+ * if it is considered valid.
+ * @param serverName a possible value for the property
+ * @return the reason why the property is invalid, or null if it is considered valid
+ * @see #setServerName(String)
+ * */
+ public static String reasonWhyInvalidServerName( final String serverName ) {
+ if ( serverName == null || serverName.trim().length() == 0 ) {
+ return
JDBCPlugin.Util.getString("MMDataSource.Server_name_required"); //$NON-NLS-1$
+ }
+ return null;
+ }
+
+ /**
+ * The reason why "socketsPerVM" is invalid.
+ * @param value of "socketsPerVM" property
+ * @return reason
+ */
+ public static String reasonWhyInvalidSocketsPerVM(final String socketsPerVM) {
+ if (socketsPerVM != null) {
+ int value = -1;
+ try {
+ value = Integer.parseInt(socketsPerVM);
+ } catch (Exception e) {
+ }
+
+ if (value <= 0) {
+ return
JDBCPlugin.Util.getString("MMDataSource.Sockets_per_vm_invalid"); //$NON-NLS-1$
+ }
+ }
+ return null;
+ }
+
+
+ /**
+ * The reason why "stickyConnections" is invalid.
+ * @param value of "stickyConnections" property
+ * @return reason
+ */
+ public static String reasonWhyInvalidStickyConnections(final String
stickyConnections) {
+ if (stickyConnections != null) {
+ if ((! stickyConnections.equalsIgnoreCase("true")) &&
//$NON-NLS-1$
+ (! stickyConnections.equalsIgnoreCase("false"))) {
//$NON-NLS-1$
+ return
JDBCPlugin.Util.getString("MMDataSource.Sticky_connections_invalid");
//$NON-NLS-1$
+ }
+ }
+ return null;
+ }
+
+ /**
+ * The reason why "alternateServers" is invalid.
+ * @param value of "alternateServers" property
+ * @return reason
+ */
+ public static String reasonWhyInvalidAlternateServers(final String alternateServers)
{
+ if ( alternateServers == null || alternateServers.trim().length() < 1 )
+ return null;
+
+ String[] as = alternateServers.split( TeiidURL.COMMA_DELIMITER);
+ String sReason = null;
+ String reason = ""; //$NON-NLS-1$
+ int reasonCount = 0;
+ final String newline = System.getProperty("line.separator");
//$NON-NLS-1$
+
+ for ( int i = 0; i < as.length; i++ ) {
+ String[] server = as[i].split( TeiidURL.COLON_DELIMITER );
+
+ if ( server.length < 1 || server.length > 2 ) {
+ // ie "server:31000:an invalid value"
+ // ie "server,server:31000"
+ return JDBCPlugin.Util.getString("MMDataSource.Alternate_Servers_format");
//$NON-NLS-1$
+ }
+
+ // check the server name portion
+ sReason = reasonWhyInvalidServerName(server[0] );
+ if ( sReason != null ) {
+ reason += (reason.length() > 0 ? newline : "" ) + sReason;
//$NON-NLS-1$
+ reasonCount++;
+ sReason = null;
+ }
+
+ if ( server.length > 1 ) {
+ // check the port portion
+ int port = 0;
+ // parse the int from the string
+ try { port = Integer.parseInt(server[1]); }
+ catch ( NumberFormatException e ) {
+ // ie "server:invalid_port"
+ reason += (reason.length() > 0 ? newline : "" ) //$NON-NLS-1$
+ + JDBCPlugin.Util.getString("MMDataSource.serverPort_must_be_a_number");
//$NON-NLS-1$
+ reasonCount++;
+ }
+ sReason = reasonWhyInvalidPortNumber(port);
+ if ( sReason != null ) {
+ reason += (reason.length() > 0 ? newline : "" ) + sReason;
//$NON-NLS-1$
+ reasonCount++;
+ sReason = null;
+ }
+ }
+ }
+ if ( reasonCount < 1 ) return null;
+ return
JDBCPlugin.Util.getString("MMDataSource.alternateServer_is_invalid",
String.valueOf(reasonCount), reason); //$NON-NLS-1$
+ }
+
+ /**
+ * @return Returns the transparentFailover.
+ */
+ public String getAutoFailover() {
+ return this.autoFailover;
+ }
+
+ /**
+ * @param transparentFailover The transparentFailover to set.
+ */
+ public void setAutoFailover(String autoFailover) {
+ this.autoFailover = autoFailover;
+ }
+
+ public String getDiscoveryStrategy() {
+ return discoveryStrategy;
+ }
+
+ public void setDiscoveryStrategy(String discoveryStrategy) {
+ this.discoveryStrategy = discoveryStrategy;
+ }
+}
+
Property changes on: trunk/client/src/main/java/org/teiid/jdbc/TeiidDataSource.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Copied: trunk/client/src/main/java/org/teiid/jdbc/TeiidDriver.java (from rev 1983,
trunk/client-jdbc/src/main/java/org/teiid/jdbc/TeiidDriver.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/TeiidDriver.java
(rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/TeiidDriver.java 2010-03-22 21:01:44 UTC
(rev 1986)
@@ -0,0 +1,164 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.Connection;
+import java.sql.Driver;
+import java.sql.DriverManager;
+import java.sql.DriverPropertyInfo;
+import java.sql.SQLException;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.metamatrix.common.util.ApplicationInfo;
+import com.metamatrix.common.util.PropertiesUtils;
+
+/**
+ * JDBC Driver class for Teiid Embedded and Teiid Server. This class automatically
registers with the
+ * {@link DriverManager}
+ *
+ * The accepted URL format for the connection
+ * <ul>
+ * <li> Server/socket connection:<b>
jdbc:teiid:<vdb-name>@mm[s]://<server-name>:<port>;[user=<user-name>][password=<user-password>][other-properties]*</b>
+ * <li> Embedded connection:<b>
jdbc:teiid:<vdb-name>@<file-path-to-deploy.properties>;[user=<user-name>][password=<user-password>][other-properties]*</b>
+ * </ul>
+ * The user, password properties are needed if the user authentication is turned on. All
the "other-properties" are simple name value pairs.
+ * Look at {@link JDBCURL} KNOWN_PROPERTIES for list of known properties allowed.
+ */
+
+public class TeiidDriver implements Driver {
+
+ private static Logger logger = Logger.getLogger("org.teiid.jdbc");
//$NON-NLS-1$
+ static final String DRIVER_NAME = "Teiid JDBC Driver"; //$NON-NLS-1$
+
+ private static TeiidDriver INSTANCE = new TeiidDriver();
+
+ static {
+ try {
+ DriverManager.registerDriver(INSTANCE);
+ } catch(SQLException e) {
+ // Logging
+ String logMsg =
JDBCPlugin.Util.getString("MMDriver.Err_registering", e.getMessage());
//$NON-NLS-1$
+ logger.log(Level.SEVERE, logMsg);
+ }
+ }
+
+ public static TeiidDriver getInstance() {
+ return INSTANCE;
+ }
+
+ /**
+ * Should be a singleton and only constructed in {@link #getInstance}.
+ */
+ public TeiidDriver() {
+ // this is not singleton, if you want singleton make this private.
+ }
+
+ public Connection connect(String url, Properties info) throws SQLException {
+
+ if (EmbeddedProfile.acceptsURL(url)) {
+ return EmbeddedProfile.connect(url, info);
+ }
+ else if (SocketProfile.acceptsURL(url)) {
+ return SocketProfile.connect(url, info);
+ }
+ return null;
+ }
+
+ /**
+ * Returns true if the driver thinks that it can open a connection to the given URL.
+ * Expected URL format for server mode is
+ * jdbc:teiid::VDB@mm://server:port;version=1;user=username;password=password
+ *
+ * @param The URL used to establish a connection.
+ * @return A boolean value indicating whether the driver understands the
subprotocol.
+ * @throws SQLException, should never occur
+ */
+ public boolean acceptsURL(String url) throws SQLException {
+ return EmbeddedProfile.acceptsURL(url) || SocketProfile.acceptsURL(url);
+ }
+
+ /**
+ * Get's the driver's major version number. Initially this should be 1.
+ * @return major version number of the driver.
+ */
+ public int getMajorVersion() {
+ return ApplicationInfo.getInstance().getMajorReleaseVersion();
+ }
+
+ /**
+ * Get's the driver's minor version number. Initially this should be 0.
+ * @return major version number of the driver.
+ */
+ public int getMinorVersion() {
+ return ApplicationInfo.getInstance().getMinorReleaseVersion();
+ }
+
+ public String getDriverName() {
+ return DRIVER_NAME;
+ }
+
+ public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws
SQLException {
+ if(info == null) {
+ info = new Properties();
+ } else {
+ info = PropertiesUtils.clone(info);
+ }
+
+ // construct list of driverPropertyInfo objects
+ List<DriverPropertyInfo> driverProps = new
LinkedList<DriverPropertyInfo>();
+
+ if (EmbeddedProfile.acceptsURL(url)) {
+ EmbeddedProfile.parseURL(url, info);
+ } else if (SocketProfile.acceptsURL(url)) {
+ SocketProfile.parseURL(url, info);
+ }
+
+ for (String property: JDBCURL.KNOWN_PROPERTIES) {
+ DriverPropertyInfo dpi = new DriverPropertyInfo(property,
info.getProperty(property));
+ if (property.equals(BaseDataSource.VDB_NAME)) {
+ dpi.required = true;
+ }
+ driverProps.add(dpi);
+ }
+
+ // create an array of DriverPropertyInfo objects
+ DriverPropertyInfo [] propInfo = new DriverPropertyInfo[driverProps.size()];
+
+ // copy the elements from the list to the array
+ return driverProps.toArray(propInfo);
+ }
+
+ /**
+ * This method returns true if the driver passes jdbc compliance tests.
+ * @return true if the driver is jdbc complaint, else false.
+ */
+ public boolean jdbcCompliant() {
+ return false;
+ }
+}
+
+
Property changes on: trunk/client/src/main/java/org/teiid/jdbc/TeiidDriver.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Copied: trunk/client/src/main/java/org/teiid/jdbc/TeiidSQLException.java (from rev 1983,
trunk/client-jdbc/src/main/java/org/teiid/jdbc/TeiidSQLException.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/TeiidSQLException.java
(rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/TeiidSQLException.java 2010-03-22 21:01:44
UTC (rev 1986)
@@ -0,0 +1,228 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.net.MalformedURLException;
+import java.net.NoRouteToHostException;
+import java.net.UnknownHostException;
+import java.sql.SQLException;
+
+import org.teiid.client.security.InvalidSessionException;
+import org.teiid.client.security.LogonException;
+import org.teiid.net.CommunicationException;
+import org.teiid.net.ConnectionException;
+
+
+import com.metamatrix.api.exception.MetaMatrixProcessingException;
+import com.metamatrix.api.exception.query.ProcedureErrorInstructionException;
+import com.metamatrix.core.MetaMatrixCoreException;
+import com.metamatrix.core.MetaMatrixRuntimeException;
+
+/**
+ * Teiid specific SQLException
+ */
+
+public class TeiidSQLException extends SQLException {
+
+ private static final long serialVersionUID = 3672305321346173922L;
+
+ /**
+ * No-arg constructor required by Externalizable semantics.
+ */
+ public TeiidSQLException() {
+ super();
+ }
+
+ public TeiidSQLException(String reason) {
+ super(reason, SQLStates.DEFAULT);
+ }
+
+ public TeiidSQLException(String reason, String state) {
+ super(reason, state);
+ }
+
+ public static TeiidSQLException create(Throwable exception) {
+ if (exception instanceof TeiidSQLException) {
+ return (TeiidSQLException)exception;
+ }
+ return create(exception, exception.getMessage());
+ }
+
+ public TeiidSQLException(Throwable ex, String reason, String sqlState) {
+ super(reason, sqlState); // passing the message to the super class constructor.
+ initCause(ex);
+ }
+
+ private TeiidSQLException(SQLException ex, String message, boolean addChildren) {
+ super(message, ex.getSQLState() == null ? SQLStates.DEFAULT : ex.getSQLState(),
ex.getErrorCode());
+
+ if (addChildren) {
+ SQLException childException = ex; // this a child to the SQLException
constructed from reason
+
+ while (childException != null) {
+ if (childException instanceof TeiidSQLException) {
+ super.setNextException(ex);
+ break;
+ }
+ super.setNextException(new TeiidSQLException(childException,
getMessage(childException, null),false));
+ childException = childException.getNextException();
+ }
+ }
+ }
+ public static TeiidSQLException create(Throwable exception, String message) {
+ message = getMessage(exception, message);
+ Throwable origException = exception;
+ if (exception instanceof TeiidSQLException) {
+ if (message.equals(exception.getMessage())) {
+ return (TeiidSQLException) exception;
+ }
+ }
+ if (exception instanceof SQLException) {
+ return new TeiidSQLException((SQLException) exception, message, true);
+ }
+ String sqlState = SQLStates.DEFAULT;
+
+ exception = findRootException(exception);
+
+ sqlState = determineSQLState(exception, sqlState);
+ return new TeiidSQLException(origException, message, sqlState);
+ }
+
+ /**
+ * @param exception
+ * @param sqlState
+ * @return
+ */
+ private static String determineSQLState(Throwable exception,
+ String sqlState) {
+ if (exception instanceof InvalidSessionException) {
+ sqlState = SQLStates.CONNECTION_EXCEPTION_STALE_CONNECTION;
+ } else if (exception instanceof LogonException) {
+ sqlState = SQLStates.INVALID_AUTHORIZATION_SPECIFICATION_NO_SUBCLASS;
+ } else if (exception instanceof ProcedureErrorInstructionException) {
+ sqlState = SQLStates.VIRTUAL_PROCEDURE_ERROR;
+ } else if (exception instanceof MetaMatrixProcessingException) {
+ sqlState = SQLStates.USAGE_ERROR;
+ } else if (exception instanceof UnknownHostException
+ || exception instanceof ConnectException
+ || exception instanceof MalformedURLException
+ || exception instanceof NoRouteToHostException
+ || exception instanceof ConnectionException) {
+ sqlState =
SQLStates.CONNECTION_EXCEPTION_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION;
+ } else if (exception instanceof IOException) {
+ sqlState = SQLStates.CONNECTION_EXCEPTION_STALE_CONNECTION;
+ } else if (exception instanceof MetaMatrixCoreException) {
+ if (exception instanceof CommunicationException) {
+ sqlState = SQLStates.CONNECTION_EXCEPTION_STALE_CONNECTION;
+ }
+
+ Throwable originalException = exception;
+ exception = originalException.getCause();
+ exception = findRootException(exception);
+
+ if (exception instanceof CommunicationException) {
+ sqlState = SQLStates.USAGE_ERROR;
+ exception = exception.getCause();
+ }
+
+ if (exception != null && exception != originalException) {
+ sqlState = determineSQLState(exception, sqlState);
+ }
+ }
+ return sqlState;
+ }
+
+ /**
+ * @param exception
+ * @return
+ */
+ private static Throwable findRootException(Throwable exception) {
+ if (exception instanceof MetaMatrixRuntimeException) {
+ while (exception.getCause() != exception
+ && exception.getCause() != null) {
+ exception = exception.getCause();
+ }
+ if (exception instanceof MetaMatrixRuntimeException) {
+ MetaMatrixRuntimeException runtimeException = (MetaMatrixRuntimeException)
exception;
+ while (runtimeException.getChild() != exception
+ && runtimeException.getChild() != null) {
+ if (runtimeException.getChild() instanceof MetaMatrixRuntimeException) {
+ runtimeException = (MetaMatrixRuntimeException) runtimeException
+ .getChild();
+ } else {
+ exception = runtimeException.getChild();
+ break;
+ }
+ }
+ }
+ }
+ return exception;
+ }
+
+ /**
+ * @param exception
+ * @param message
+ * @return
+ * @since 4.1
+ */
+ private static String getMessage(Throwable exception,
+ String message) {
+ if (message == null) {
+ message = exception.getMessage();
+ if (message == null) {
+ message = exception.getClass().getName();
+ }
+ }
+ return message;
+ }
+
+
+ /**
+ * @see java.lang.Throwable#getCause()
+ * @since 4.3.2
+ */
+ public Throwable getCause() {
+ if (this.getNextException() != null) {
+ return getNextException();
+ }
+ return super.getCause();
+ }
+
+ /**
+ * @see org.teiid.jdbc.api.SQLException#isSystemErrorState()
+ * @since 4.3
+ */
+ public boolean isSystemErrorState() {
+ return SQLStates.isSystemErrorState(getSQLState());
+ }
+
+ /**
+ * @see org.teiid.jdbc.api.SQLException#isUsageErrorState()
+ * @since 4.3
+ */
+ public boolean isUsageErrorState() {
+ return SQLStates.isUsageErrorState(getSQLState());
+ }
+}
\ No newline at end of file
Copied: trunk/client/src/main/java/org/teiid/jdbc/TeiidStatement.java (from rev 1983,
trunk/client-jdbc/src/main/java/org/teiid/jdbc/TeiidStatement.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/TeiidStatement.java
(rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/TeiidStatement.java 2010-03-22 21:01:44 UTC
(rev 1986)
@@ -0,0 +1,115 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Serializable;
+import java.util.Collection;
+
+import org.teiid.client.plan.Annotation;
+import org.teiid.client.plan.PlanNode;
+
+
+
+/**
+ * This interface provides methods in
+ * addition to the standard JDBC methods.
+ */
+public interface TeiidStatement extends java.sql.Statement {
+
+ /**
+ * Get the execution property value.
+ * @param name Execution property name
+ * @return Execution property value or null if not set
+ */
+ String getExecutionProperty(String name);
+
+ /**
+ * Set the execution property value.
+ * @param name Execution property name
+ * @param value Execution property value
+ */
+ void setExecutionProperty(String name, String value);
+
+ /**
+ * Obtain the query plan object representation from the last
+ * command executed on this Statement, if a query plan was
+ * requested in the command. If no plan was requested, this
+ * method will return null.
+ * @return PlanNode representing the root of the query plan
+ */
+ PlanNode getPlanDescription();
+
+ /**
+ * Obtain the query planner debug log from the last command
+ * executed on this Statement, if it was requested with
+ * OPTION DEBUG. If no debug output was requested, this
+ * method will return null.
+ * @return Debug log or null if no log exists
+ */
+ String getDebugLog();
+
+ /**
+ * Get collection of annotations from the query planner from
+ * the last command executed on the Statement
+ * @return Collection of {@link Annotation}s, may return null
+ */
+ Collection<Annotation> getAnnotations();
+
+ /**
+ * Attach a stylesheet to be applied on the server for XML queries
+ * executed with this Statement.
+ * @param reader Reader for reading a stylesheet in XML
+ * @throws IOException If an error occurs reading the stylesheet
+ * @deprecated
+ */
+ void attachStylesheet(Reader reader) throws IOException;
+
+ /**
+ * Clear any previously attached stylesheet for this Statement object.
+ * @deprecated
+ */
+ void clearStylesheet();
+
+ /**
+ * Get ID for last execution which can be used for matching up executions
+ * on the client side with executions in the server logs.
+ * @return String identifier for the last execution
+ */
+ String getRequestIdentifier();
+
+ /**
+ * Set the per-statement security payload. This optional payload will
+ * accompany each request to the data source(s) so that the connector
+ * will have access to it.
+ *
+ * <p>To remove an existing payload from a statement, call this method
+ * with a <code>null</code> argument.</p>
+ *
+ * @param payload The payload that is to accompany requests executed
+ * from this statement.
+ * @since 4.2
+ */
+ void setPayload(Serializable payload);
+}
Property changes on: trunk/client/src/main/java/org/teiid/jdbc/TeiidStatement.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Copied: trunk/client/src/main/java/org/teiid/jdbc/WarningUtil.java (from rev 1983,
trunk/client-jdbc/src/main/java/org/teiid/jdbc/WarningUtil.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/WarningUtil.java
(rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/WarningUtil.java 2010-03-22 21:01:44 UTC
(rev 1986)
@@ -0,0 +1,86 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.SQLWarning;
+import java.util.List;
+
+import org.teiid.client.SourceWarning;
+
+
+
+/**
+ * Utilities for creating SQLWarnings.
+ */
+class WarningUtil {
+
+ private WarningUtil() {
+ }
+
+ /**
+ * Used to wrap warnings/exceptions into SQLWarning.
+ * The chain of warnings is translated into a chain of SQLWarnings.
+ * @param reason String object which is the description of the warning.
+ * @param ex Throwable object which needs to be wrapped.
+ */
+ static SQLWarning createWarning(Throwable ex) {
+ if(ex instanceof SourceWarning) {
+ SourceWarning exception = (SourceWarning)ex;
+ if (exception.isPartialResultsError()) {
+ PartialResultsWarning warning = new
PartialResultsWarning(JDBCPlugin.Util.getString("WarningUtil.Failures_occurred"));
//$NON-NLS-1$
+ warning.addConnectorFailure(exception.getConnectorBindingName(),
TeiidSQLException.create(exception));
+ return warning;
+ }
+ }
+ //## JDBC4.0-begin ##
+ return new SQLWarning(ex);
+ //## JDBC4.0-end ##
+ /*## JDBC3.0-JDK1.5-begin ##
+ return new SQLWarning(ex.getMessage());
+ ## JDBC3.0-JDK1.5-end ##*/
+
+ }
+
+ /**
+ * Convert a List of warnings from the server into a single SQLWarning chain.
+ * @param exceptions List of exceptions from server
+ * @return Chain of SQLWarning corresponding to list of exceptions
+ */
+ static SQLWarning convertWarnings(List<Exception> exceptions) {
+ if(exceptions == null || exceptions.size() == 0) {
+ return null;
+ }
+ SQLWarning warning = null;
+
+ for (Exception ex : exceptions) {
+ SQLWarning newWarning = createWarning(ex);
+ if(warning == null) {
+ warning = newWarning;
+ } else {
+ warning.setNextWarning(newWarning);
+ }
+ }
+
+ return warning;
+ }
+}
Copied: trunk/client/src/main/java/org/teiid/jdbc/WrapperImpl.java (from rev 1983,
trunk/client-jdbc/src/main/java/org/teiid/jdbc/WrapperImpl.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/WrapperImpl.java
(rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/WrapperImpl.java 2010-03-22 21:01:44 UTC
(rev 1986)
@@ -0,0 +1,51 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.SQLException;
+//## JDBC4.0-begin ##
+import java.sql.Wrapper;
+//## JDBC4.0-end ##
+
+import com.metamatrix.core.util.ArgCheck;
+
+public class WrapperImpl
+ //## JDBC4.0-begin ##
+ implements Wrapper
+ //## JDBC4.0-end ##
+ {
+ public boolean isWrapperFor(Class<?> iface) throws SQLException {
+ ArgCheck.isNotNull(iface);
+
+ return iface.isInstance(this);
+ }
+
+ public <T> T unwrap(Class<T> iface) throws SQLException {
+ if (!isWrapperFor(iface)) {
+ throw new SQLException(JDBCPlugin.Util.getString("WrapperImpl.wrong_class",
iface)); //$NON-NLS-1$
+ }
+
+ return iface.cast(this);
+ }
+
+}
Copied: trunk/client/src/main/java/org/teiid/jdbc/XAConnectionImpl.java (from rev 1983,
trunk/client-jdbc/src/main/java/org/teiid/jdbc/XAConnectionImpl.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/XAConnectionImpl.java
(rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/XAConnectionImpl.java 2010-03-22 21:01:44
UTC (rev 1986)
@@ -0,0 +1,176 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.HashSet;
+import java.util.Iterator;
+
+import javax.sql.ConnectionEvent;
+import javax.sql.ConnectionEventListener;
+//## JDBC4.0-begin ##
+import javax.sql.StatementEventListener;
+//## JDBC4.0-end ##
+import javax.sql.XAConnection;
+import javax.transaction.xa.XAResource;
+
+/**
+ * Implementation of XAConnection.
+ */
+public class XAConnectionImpl implements XAConnection{
+
+ interface ConnectionSource {
+
+ ConnectionImpl createConnection() throws SQLException;
+
+ }
+
+ private final class CloseInterceptor implements
+ InvocationHandler {
+
+ private ConnectionImpl proxiedConnection;
+
+ CloseInterceptor(ConnectionImpl connection) {
+ this.proxiedConnection = connection;
+ }
+
+ public Object invoke(Object proxy,
+ Method method,
+ Object[] args) throws Throwable {
+ if ("close".equals(method.getName())) { //$NON-NLS-1$
+ this.proxiedConnection.recycleConnection();
+ XAConnectionImpl.this.notifyListener(null);
+ return null;
+ }
+
+ try {
+ return method.invoke(this.proxiedConnection, args);
+ } catch (InvocationTargetException e) {
+ //TODO: notify listeners about critical errors
+ throw e.getTargetException();
+ }
+ }
+ }
+
+ private HashSet listeners;
+ private XAResource resource;
+ private ConnectionImpl connection;
+ private ConnectionSource cs;
+
+ private boolean isClosed;
+
+ public static XAConnectionImpl newInstance (ConnectionSource cs){
+ return new XAConnectionImpl(cs);
+ }
+
+ public XAConnectionImpl(ConnectionSource cs){
+ this.cs = cs;
+ }
+
+ public Connection getConnection() throws SQLException{
+ ConnectionImpl conn = getMMConnection();
+
+ Connection result =
(Connection)Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[]
{Connection.class}, new CloseInterceptor(conn));
+
+ return result;
+ }
+
+ ConnectionImpl getMMConnection() throws SQLException {
+ if(isClosed){
+ throw new
SQLException(JDBCPlugin.Util.getString("MMXAConnection.connection_is_closed"));
//$NON-NLS-1$
+ }
+
+ if(connection == null){
+ try{
+ connection = cs.createConnection();
+ }catch(SQLException e){
+ notifyListener(e);
+ throw e;
+ }
+ }
+
+ return connection;
+ }
+
+ public synchronized void addConnectionEventListener(ConnectionEventListener listener){
+ if(listeners == null){
+ listeners = new HashSet();
+ }
+ this.listeners.add(listener);
+ }
+
+ public synchronized void removeConnectionEventListener(ConnectionEventListener
listener){
+ if(listeners == null){
+ return;
+ }
+ this.listeners.remove(listener);
+ }
+
+ public XAResource getXAResource() throws SQLException{
+ if(resource == null){
+ resource = XAResourceImpl.newInstance(this);
+ }
+ return resource;
+ }
+
+ public void close()throws SQLException{
+ if(connection != null && !connection.isClosed()){
+ connection.close();
+ }
+ isClosed = true;
+ }
+
+ /**
+ * Notify listeners, if there is any, about the connection status.
+ * If e is null, the connection is properly closed.
+ * @param e
+ */
+ protected synchronized void notifyListener(SQLException e){
+ if(listeners != null && !listeners.isEmpty()){
+ Iterator iter = listeners.iterator();
+ while(iter.hasNext()){
+ ConnectionEventListener listener = (ConnectionEventListener)iter.next();
+ if(e == null){
+ //no exception
+ listener.connectionClosed(new ConnectionEvent(this));
+ }else{
+ //exception occurred
+ listener.connectionErrorOccurred(new ConnectionEvent(this, e));
+ }
+ }
+ }
+ }
+
+ //## JDBC4.0-begin ##
+ public void addStatementEventListener(StatementEventListener arg0) {
+ }
+
+ public void removeStatementEventListener(StatementEventListener arg0) {
+ }
+ //## JDBC4.0-end ##
+}
Copied: trunk/client/src/main/java/org/teiid/jdbc/XAResourceImpl.java (from rev 1983,
trunk/client-jdbc/src/main/java/org/teiid/jdbc/XAResourceImpl.java)
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/XAResourceImpl.java
(rev 0)
+++ trunk/client/src/main/java/org/teiid/jdbc/XAResourceImpl.java 2010-03-22 21:01:44 UTC
(rev 1986)
@@ -0,0 +1,209 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.SQLException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.transaction.xa.XAException;
+import javax.transaction.xa.XAResource;
+import javax.transaction.xa.Xid;
+
+import org.teiid.client.xa.XATransactionException;
+import org.teiid.client.xa.XidImpl;
+import org.teiid.net.CommunicationException;
+
+
+/**
+ * Implementation of XAResource.
+ */
+public class XAResourceImpl implements XAResource{
+ private static Logger logger = Logger.getLogger("org.teiid.jdbc");
//$NON-NLS-1$
+
+ private XAConnectionImpl mmConnection;
+ private int timeOut;
+
+ public static XAResourceImpl newInstance (XAConnectionImpl mmConnection){
+ return new XAResourceImpl(mmConnection);
+ }
+
+ public XAResourceImpl(XAConnectionImpl mmConnection){
+ this.mmConnection = mmConnection;
+ }
+
+ /**
+ * @see javax.transaction.xa.XAResource#commit(javax.transaction.xa.Xid, boolean)
+ */
+ public void commit(Xid xid, boolean onePhase) throws XAException {
+ XidImpl mmXid = getMMXid(xid);
+ try{
+ getMMConnection().commitTransaction(mmXid, onePhase);
+ }catch(SQLException e){
+ String logMsg = JDBCPlugin.Util.getString("MMXAResource.FailedCommitTXN",
xid, onePhase ? "true":"false"); //$NON-NLS-1$ //$NON-NLS-2$
//$NON-NLS-3$
+ throw handleError(e, logMsg);
+ }
+ }
+
+ private XAException handleError(Exception e,String logMsg) {
+ logger.log(Level.SEVERE, logMsg, e);
+
+ if(e instanceof TeiidSQLException){
+ Throwable ex = ((TeiidSQLException)e).getCause();
+ if(ex instanceof XAException){
+ return (XAException)ex;
+ }
+ if (ex instanceof XATransactionException) {
+ return ((XATransactionException)ex).getXAException();
+ }
+ }
+ return new XAException(XAException.XAER_RMERR);
+ }
+
+ /**
+ * @see javax.transaction.xa.XAResource#end(javax.transaction.xa.Xid, int)
+ */
+ public void end(Xid xid, int flag) throws XAException {
+ XidImpl mmXid = getMMXid(xid);
+ try{
+ getMMConnection().endTransaction(mmXid, flag);
+ }catch(SQLException e){
+ String logMsg =
JDBCPlugin.Util.getString("MMXAResource.FailedEndTXN", xid, new Integer(flag));
//$NON-NLS-1$
+ throw handleError(e, logMsg);
+ }
+ }
+
+ /**
+ * @see javax.transaction.xa.XAResource#forget(javax.transaction.xa.Xid)
+ */
+ public void forget(Xid xid) throws XAException {
+ XidImpl mmXid = getMMXid(xid);
+ try{
+ getMMConnection().forgetTransaction(mmXid);
+ }catch(SQLException e){
+ String logMsg =
JDBCPlugin.Util.getString("MMXAResource.FailedForgetTXN", xid); //$NON-NLS-1$
+ throw handleError(e, logMsg);
+ }
+ }
+
+ /**
+ * @see javax.transaction.xa.XAResource#getTransactionTimeout()
+ */
+ public int getTransactionTimeout() throws XAException {
+ return timeOut;
+ }
+
+ /**
+ * @see javax.transaction.xa.XAResource#isSameRM(javax.transaction.xa.XAResource)
+ */
+ public boolean isSameRM(XAResource arg0) throws XAException {
+ if (arg0 == this) {
+ return true;
+ }
+ if (!(arg0 instanceof XAResourceImpl)) {
+ return false;
+ }
+ XAResourceImpl other = (XAResourceImpl)arg0;
+ try {
+ return this.getMMConnection().isSameProcess(other.getMMConnection());
+ } catch (CommunicationException e) {
+ throw handleError(e,
JDBCPlugin.Util.getString("MMXAResource.FailedISSameRM")); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * @see javax.transaction.xa.XAResource#prepare(javax.transaction.xa.Xid)
+ */
+ public int prepare(Xid xid) throws XAException {
+ XidImpl mmXid = getMMXid(xid);
+ try{
+ return getMMConnection().prepareTransaction(mmXid);
+ }catch(SQLException e){
+ String logMsg =
JDBCPlugin.Util.getString("MMXAResource.FailedPrepareTXN", xid); //$NON-NLS-1$
+ throw handleError(e, logMsg);
+ }
+ }
+
+ /**
+ * @see javax.transaction.xa.XAResource#recover(int)
+ */
+ public Xid[] recover(int flag) throws XAException {
+ try{
+ return getMMConnection().recoverTransaction(flag);
+ }catch(SQLException e){
+ String logMsg =
JDBCPlugin.Util.getString("MMXAResource.FailedRecoverTXN", flag); //$NON-NLS-1$
+ throw handleError(e, logMsg);
+ }
+ }
+
+ /**
+ * @see javax.transaction.xa.XAResource#rollback(javax.transaction.xa.Xid)
+ */
+ public void rollback(Xid xid) throws XAException {
+ XidImpl mmXid = getMMXid(xid);
+ try{
+ getMMConnection().rollbackTransaction(mmXid);
+ }catch(SQLException e){
+ String logMsg =
JDBCPlugin.Util.getString("MMXAResource.FailedRollbackTXN", xid); //$NON-NLS-1$
+ throw handleError(e, logMsg);
+ }
+ }
+
+ /**
+ * @see javax.transaction.xa.XAResource#setTransactionTimeout(int)
+ */
+ public boolean setTransactionTimeout(int seconds) throws XAException {
+ timeOut = seconds;
+ return true;
+ }
+
+ /**
+ * @see javax.transaction.xa.XAResource#start(javax.transaction.xa.Xid, int)
+ */
+ public void start(Xid xid, int flag) throws XAException {
+ XidImpl mmXid = getMMXid(xid);
+ try{
+ getMMConnection().startTransaction(mmXid, flag, timeOut);
+ }catch(SQLException e){
+ String logMsg =
JDBCPlugin.Util.getString("MMXAResource.FailedStartTXN", xid, new
Integer(flag)); //$NON-NLS-1$
+ handleError(e, logMsg);
+ }
+ }
+
+ private ConnectionImpl getMMConnection() throws XAException{
+ try{
+ return this.mmConnection.getMMConnection();
+ }catch(SQLException e){
+ throw new XAException(XAException.XAER_RMFAIL);
+ }
+ }
+
+ /**
+ * @param xid
+ * @return
+ * @throws XAException
+ */
+ private XidImpl getMMXid(Xid originalXid) {
+ return new XidImpl(originalXid);
+ }
+}
Copied: trunk/client/src/main/resources/META-INF (from rev 1983,
trunk/client-jdbc/src/main/resources/META-INF)
Copied: trunk/client/src/main/resources/org/teiid/jdbc (from rev 1983,
trunk/client-jdbc/src/main/resources/org/teiid/jdbc)
Copied: trunk/client/src/test/java/org/teiid/jdbc/TestAllResultsImpl.java (from rev 1983,
trunk/client-jdbc/src/test/java/org/teiid/jdbc/TestAllResultsImpl.java)
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestAllResultsImpl.java
(rev 0)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestAllResultsImpl.java 2010-03-22 21:01:44
UTC (rev 1986)
@@ -0,0 +1,927 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.List;
+import java.util.TimeZone;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Matchers;
+import org.teiid.client.DQP;
+import org.teiid.client.RequestMessage;
+import org.teiid.client.ResultsMessage;
+import org.teiid.client.util.ResultsFuture;
+import org.teiid.jdbc.ResultSetImpl;
+import org.teiid.jdbc.StatementImpl;
+
+import com.metamatrix.api.exception.MetaMatrixProcessingException;
+import com.metamatrix.common.types.MMJDBCSQLTypeInfo;
+import com.metamatrix.common.util.TimestampWithTimezone;
+import com.metamatrix.query.unittest.TimestampUtil;
+
+public class TestAllResultsImpl {
+
+ private static final long REQUEST_ID = 0;
+ private static final int TYPE_FORWARD_ONLY = ResultSet.TYPE_FORWARD_ONLY;
+ private static final int TYPE_SCROLL_SENSITIVE = ResultSet.TYPE_SCROLL_SENSITIVE;
+
+ private StatementImpl statement;
+
+ @Before public void setUp() throws Exception {
+ statement = TestMMResultSet.createMockStatement(TYPE_SCROLL_SENSITIVE);
+ }
+
+ /** test hasNext(), actual result set should return FALSE. */
+ @Test public void testHasNext1() throws Exception {
+ ResultSetImpl rs = new ResultSetImpl(exampleResultsMsg1(),
+ statement);
+ while (rs.next()) {
+ // just walk through
+ }
+
+ boolean actual = rs.hasNext();
+ boolean expected = false;
+ assertEquals(expected, actual);
+
+ rs.close();
+ }
+
+ /** test hasNext(), actual result set should return TRUE. */
+ @Test public void testHasNext2() throws Exception {
+ List[] results = exampleResults1(5);
+ ResultSetImpl rs = new ResultSetImpl(exampleResultsMsg1(),
+ statement);
+
+ for (int i = 1; i < results.length; i++) {
+ rs.next();
+ }
+
+ boolean actual = rs.hasNext();
+ boolean expected = true;
+ assertEquals(expected, actual);
+
+ rs.close();
+ }
+
+ /**
+ * test next(), whether the result set's cursor is positioned on next row or
+ * not
+ */
+ @Test public void testNext1() throws Exception {
+ ResultSetImpl rs = new ResultSetImpl(exampleResultsMsg1(),
+ statement);
+
+ // point to first row
+ boolean actual = rs.next();
+ boolean expected = true;
+ assertEquals(" Actual doesn't match with expected. ", expected, actual);
//$NON-NLS-1$
+
+ rs.close();
+ }
+
+ /** test next(), walk through all rows of a result set and compare each row. */
+ @Test public void testNext2() throws Exception {
+ List[] results = exampleResults1(5);
+ ResultSetImpl rs = new ResultSetImpl(exampleResultsMsg1(),
+ statement);
+
+ int i = 0;
+ while (rs.next()) {
+ // walk through and compare
+ List actual = rs.getCurrentRecord();
+ List expected = results[i];
+ assertEquals(expected, actual);
+ i++;
+ }
+
+ rs.close();
+ }
+
+ /** test next(), get result set and close without walking through */
+ @Test public void testNext3() throws Exception {
+ ResultSetImpl rs = new ResultSetImpl(exampleResultsMsg1(),
+ statement);
+ assertEquals(new Integer(0), new Integer(rs.getRow()));
+
+ rs.close();
+ }
+
+ /** test next(), walk through partial rows of a result set */
+ @Test public void testNext4() throws Exception {
+ List[] results = exampleResults1(5);
+ ResultSetImpl rs = new ResultSetImpl(exampleResultsMsg1(),
+ statement);
+
+ for (int i = 0; i < results.length - 1; i++) {
+ rs.next();
+ List actual = rs.getCurrentRecord();
+ List expected = results[i];
+ assertEquals(expected, actual);
+ }
+
+ rs.close();
+ }
+
+ /** test next(), when hasNext() == false */
+ @Test public void testNext5() throws Exception {
+ ResultSetImpl rs = new ResultSetImpl(exampleResultsMsg1(),
+ statement);
+ while (rs.next()) {
+ // just walk through until hasNext() == false;
+ }
+
+ boolean actual = rs.hasNext();
+ boolean expected = false;
+ assertEquals(expected, actual);
+
+ rs.close();
+ }
+
+ /** test getObject() at columnIndex = 2 of 5th row */
+ @Test public void testGetObject1() throws Exception {
+ List[] results = exampleResults2();
+ ResultSetImpl rs = new ResultSetImpl(exampleResultsMsg2a(),
+ statement);
+
+ String actual = null;
+ String expected = "a3"; //$NON-NLS-1$
+
+ // move cursor to the 4th row
+ for (int i = 0; i < results.length - 2; i++) {
+ rs.next();
+ }
+
+ // only compare the 4th row's 2nd column
+ if (rs.next()) {
+ actual = (String) rs.getObject(2);
+ }
+
+ assertEquals(expected, actual);
+
+ rs.close();
+ }
+
+ /** Should fail, test getObject() at wrong columnIndex */
+ @Test public void testGetObject2() throws Exception {
+ ResultSetImpl rs = new ResultSetImpl(exampleResultsMsg2a(),
+ statement);
+
+ if (rs.next()) {
+ // ERROR -- there are totally only 2 columns inside result set, 6 is
+ // an invalid one
+ try {
+ rs.getObject(6);
+ } catch (Exception e) {
+ if (e instanceof IllegalArgumentException) {
+ // OK
+ }
+ }
+ }
+
+ rs.close();
+ }
+
+ @Test public void testGetRow() throws Exception {
+ ResultSetImpl rs = new ResultSetImpl(exampleResultsMsg2(),
+ statement);
+
+ int expected = 0;
+ assertEquals(expected, rs.getRow());
+
+ if (rs.next()) {
+ expected = 1;
+ assertEquals(expected, rs.getRow());
+ }
+ rs.close();
+
+ }
+
+ @Test public void testPrevious() throws Exception {
+ List[] results = exampleResults1(5);
+ ResultSetImpl rs = new ResultSetImpl(exampleResultsMsg1(),
+ statement);
+
+ while (rs.next()) {
+ // just walk to the end;
+ }
+
+ // walk reversely;
+ int i = results.length - 1;
+ while (rs.previous()) {
+ List expected = new ArrayList();
+ expected.add(new Integer(i + 1));
+ assertEquals(expected, rs.getCurrentRecord());
+ i--;
+ }
+
+ rs.close();
+ }
+
+ @Test public void testGetCurrentRecord() throws Exception {
+ List[] results = exampleResults2();
+ ResultSetImpl rs = new ResultSetImpl(exampleResultsMsg2(),
+ statement);
+
+ rs.next();
+ List actual = rs.getCurrentRecord();
+ assertEquals(results[0], actual);
+ rs.close();
+ }
+
+ @Test public void testGetMetaData() throws Exception {
+ ResultSetImpl rs = new ResultSetImpl(exampleResultsMsg2a(),
+ statement);
+ ResultSetMetaData rmetadata = rs.getMetaData();
+ assertEquals(2, rmetadata.getColumnCount());
+
+ String[] columnNames = columnNames();
+ String[] dataTypes = dataTypes();
+ for (int i = 0; i < 2; i++) {
+ assertEquals(columnNames[i], rmetadata.getColumnName(i + 1));
+ assertEquals(dataTypes[i], rmetadata.getColumnTypeName(i + 1));
+ }
+ rs.close();
+ }
+
+ @Test public void testResultsWarnings() throws Exception {
+ ResultSetImpl rs = new ResultSetImpl(exampleResultsMsg2(),
+ statement);
+ rs.close();
+ }
+
+ @Test public void testClose() throws Exception {
+ ResultSetImpl rs = new ResultSetImpl(exampleResultsMsg2(),
+ statement);
+ rs.close();
+ verify(statement, times(0)).close();
+ }
+
+ @Test public void testGetFetchSize() throws Exception {
+ StatementImpl s = mock(StatementImpl.class);
+ stub(s.getFetchSize()).toReturn(500);
+ ResultSetImpl rs = new ResultSetImpl(exampleResultsMsg2(), s);
+ assertEquals(500, rs.getFetchSize());
+ rs.setFetchSize(100);
+ assertEquals(100, rs.getFetchSize());
+ }
+
+ // //////////////////////Functions refer to ResultSet's TYPE_FORWARD_ONLY///
+ // /////////////////
+ @Test(expected=SQLException.class) public void testIsAfterLast1() throws Exception {
+ ResultSetImpl rs = helpGetResultSetImpl(TYPE_FORWARD_ONLY);
+ rs.last();
+ }
+
+ @Test(expected=SQLException.class) public void testAfterLast1() throws Exception {
+ ResultSetImpl rs = helpGetResultSetImpl(TYPE_FORWARD_ONLY);
+ rs.afterLast();
+ }
+
+ @Test public void testIsBeforeFirst1() throws Exception {
+ ResultSetImpl rs = helpGetResultSetImpl(TYPE_FORWARD_ONLY);
+
+ // right before the first row
+ boolean actual = rs.isBeforeFirst();
+ assertEquals(true, actual);
+ rs.close();
+ }
+
+ @Test public void testIsBeforeFirst2() throws Exception {
+ ResultSetImpl rs = helpGetNoResults(TYPE_FORWARD_ONLY);
+
+ // right before the first row
+ boolean actual = rs.isBeforeFirst();
+ assertEquals(false, actual);
+ rs.close();
+ }
+
+ @Test(expected=SQLException.class) public void testBeforeFirst1() throws Exception {
+ ResultSetImpl rs = helpGetResultSetImpl(TYPE_FORWARD_ONLY);
+
+ // move cursor to the first row
+ rs.next();
+
+ // move back to before first row
+ rs.beforeFirst();
+ }
+
+ @Test public void testIsFirst1() throws Exception {
+ ResultSetImpl rs = helpGetResultSetImpl(TYPE_FORWARD_ONLY);
+
+ // move cursor to the first row
+ rs.next();
+ boolean actual = rs.isFirst();
+ assertEquals(true, actual);
+ rs.close();
+ }
+
+ @Test public void testIsFirst2() throws Exception {
+ ResultSetImpl rs = helpGetNoResults(TYPE_FORWARD_ONLY);
+
+ // move cursor to the first row
+ rs.next();
+ boolean actual = rs.isFirst();
+ assertEquals(false, actual);
+ rs.close();
+ }
+
+ @Test(expected=SQLException.class) public void testFirst1() throws Exception {
+ ResultSetImpl rs = helpGetResultSetImpl(TYPE_FORWARD_ONLY);
+
+ // move cursor to the first row
+ rs.next();
+ rs.first();
+ }
+
+ @Test(expected=SQLException.class) public void testFirst2() throws Exception {
+ ResultSetImpl rs = helpGetNoResults(TYPE_FORWARD_ONLY);
+
+ // move cursor to the first row
+ rs.next();
+ rs.first();
+ }
+
+ @Test public void testFindColumn() throws Exception {
+ ResultSetImpl rs = new ResultSetImpl(exampleResultsMsg2a(),
+ statement);
+
+ assertEquals(1, rs.findColumn("IntNum")); //$NON-NLS-1$
+ rs.close();
+ }
+
+ @Test public void testIsLast1() throws Exception {
+ ResultSetImpl rs = helpGetResultSetImpl(TYPE_FORWARD_ONLY);
+
+ // move cursor to the last row
+ boolean actual = rs.isLast();
+ assertEquals(false, actual);
+ }
+
+ @Test public void testIsLast2() throws Exception {
+ ResultSetImpl rs = helpGetNoResults(TYPE_FORWARD_ONLY);
+
+ // move cursor to the last row
+ boolean actual = rs.isLast();
+ assertEquals(false, actual);
+ }
+
+ @Test(expected=SQLException.class) public void testLast1() throws Exception {
+ ResultSetImpl rs = helpGetResultSetImpl(TYPE_FORWARD_ONLY);
+
+ rs.last();
+ }
+
+ @Test public void testRelative1() throws Exception {
+ ResultSetImpl rs = new ResultSetImpl(exampleResultsMsg2(),
+ statement);
+
+ // move to 1st row
+ rs.next();
+ // move to 2nd row
+ boolean actual = rs.relative(1);
+ assertEquals(true, actual);
+ assertEquals(2, rs.getRow());
+
+ actual = rs.relative(-1);
+ assertEquals(true, actual);
+ assertEquals(1, rs.getRow());
+ rs.close();
+ }
+
+ @Test(expected=SQLException.class) public void testAbsolute1() throws Exception {
+ ResultSetImpl rs = helpGetResultSetImpl(TYPE_FORWARD_ONLY);
+
+ rs.absolute(1);
+ }
+
+ // //////////Functions refer to other types other than ResultSet's
+ // TYPE_FORWARD_ONLY//////
+
+ @Test public void testAfterLast1a() throws Exception {
+ ResultSetImpl rs = helpGetResultSetImpl(TYPE_SCROLL_SENSITIVE);
+
+ // move cursor right past the last row
+ rs.afterLast();
+
+ // the expected row == 0 because it pasts the last row
+ assertEquals(0, rs.getRow());
+ rs.close();
+ }
+
+ @Test public void testIsAfterLast1a() throws Exception {
+ ResultSetImpl rs = helpGetResultSetImpl(TYPE_SCROLL_SENSITIVE);
+
+ // the last row
+ rs.last();
+ boolean actual = rs.isAfterLast();
+ assertEquals(false, actual);
+
+ // move after the last row
+ rs.next();
+ actual = rs.isAfterLast();
+ assertEquals(true, actual);
+ rs.close();
+ }
+
+ @Test public void testIsBeforeFirst1a() throws Exception {
+ ResultSetImpl rs = helpGetResultSetImpl(TYPE_SCROLL_SENSITIVE);
+
+ // right before the first row
+ boolean actual = rs.isBeforeFirst();
+ assertEquals(true, actual);
+ rs.close();
+ }
+
+ @Test public void testBeforeFirst1a() throws Exception {
+ ResultSetImpl rs = helpGetResultSetImpl(TYPE_SCROLL_SENSITIVE);
+
+ // move cursor to the first row
+ rs.next();
+ rs.next();
+
+ // move back to before first row
+ rs.beforeFirst();
+
+ assertEquals(0, rs.getRow());
+ rs.close();
+ }
+
+ @Test public void testIsFirst1a() throws Exception {
+ ResultSetImpl rs = helpGetResultSetImpl(TYPE_SCROLL_SENSITIVE);
+
+ // move cursor to the first row
+ rs.next();
+ boolean actual = rs.isFirst();
+ assertEquals(true, actual);
+
+ // check row number
+ assertEquals(1, rs.getRow());
+ rs.close();
+ }
+
+ @Test public void testFirst1a() throws Exception {
+ ResultSetImpl rs = helpGetResultSetImpl(TYPE_SCROLL_SENSITIVE);
+
+ // move cursor to the first row
+ boolean actual = rs.first();
+ assertEquals(true, actual);
+ assertEquals(1, rs.getRow());
+
+ // move cursor to the first row starting from the last row
+ rs.afterLast();
+ actual = rs.first();
+ assertEquals(true, actual);
+ assertEquals(1, rs.getRow());
+
+ // move cursor to the first row from random number;
+ rs.absolute(3);
+ actual = rs.first();
+ assertEquals(true, actual);
+ assertEquals(1, rs.getRow());
+ rs.close();
+ }
+
+ @Test public void testIsLast1a() throws Exception {
+ ResultSetImpl rs = helpGetResultSetImpl(TYPE_SCROLL_SENSITIVE);
+
+ // check whether the movement of cursor is successful
+ rs.last();
+ boolean actual = rs.isLast();
+ assertEquals(true, actual);
+
+ // check row number
+ assertEquals(5, rs.getRow());
+ rs.close();
+ }
+
+ @Test public void testLast1a() throws Exception {
+ ResultSetImpl rs = helpGetResultSetImpl(TYPE_SCROLL_SENSITIVE);
+
+ // check whether the movement of cursor is successful
+ boolean actual = rs.last();
+ assertEquals(true, actual);
+
+ // check weather the current row is the last row
+ assertEquals(5, rs.getRow());
+ rs.close();
+ }
+
+ /** normal relative move, only including moving from valid row to valid one */
+ @Test public void testRelative1a() throws Exception {
+ ResultSetImpl rs = helpGetResultSetImpl(TYPE_SCROLL_SENSITIVE);
+
+ // move to 1st row
+ rs.next();
+ // move to 2nd row
+ boolean actual = rs.relative(1);
+
+ assertEquals(true, actual);
+ assertEquals(2, rs.getRow());
+
+ actual = rs.relative(-1);
+ assertEquals(true, actual);
+ assertEquals(1, rs.getRow());
+ rs.close();
+ }
+
+ /** normal relative move, including moving from valid row to invalid one */
+ @Test public void testRelative1b() throws Exception {
+ ResultSetImpl rs = helpGetResultSetImpl(TYPE_SCROLL_SENSITIVE);
+
+ // move to 1st row
+ rs.next();
+ // move to 2nd row
+ boolean actual = rs.relative(1);
+ actual = rs.relative(-1);
+
+ // test if move before first
+ actual = rs.relative(-3);
+ // relative should return false when not on a row
+ assertEquals(false, actual);
+ assertEquals(0, rs.getRow());
+
+ // test if move after last
+ // this line is very important because it positions the cursor in a
+ // valid row!!!
+ rs.beforeFirst();
+ rs.next();
+ actual = rs.relative(7);
+ // should return false because it's not on a valid row
+ assertEquals(false, actual);
+ assertEquals(0, rs.getRow());
+ rs.close();
+ }
+
+ /** check only moving from an invalid row */
+ @Test public void testRelative1c() throws Exception {
+ ResultSetImpl rs = helpGetResultSetImpl(TYPE_SCROLL_SENSITIVE);
+
+ // test if move before first will work or not
+ // default to before first
+ try {
+ rs.relative(-2);
+ fail("relative move from an invalid row should fail"); //$NON-NLS-1$
+ } catch (SQLException e) {
+
+ }
+ assertEquals(
+ " Should still be before the first row ", true, rs.isBeforeFirst());
//$NON-NLS-1$
+ assertEquals(0, rs.getRow());
+
+ try {
+ rs.relative(2);
+ fail("relative move from an invalid row should fail"); //$NON-NLS-1$
+ } catch (SQLException e) {
+
+ }
+ assertEquals(
+ " Should still be before the first row ", true, rs.isBeforeFirst());
//$NON-NLS-1$
+ assertEquals(0, rs.getRow());
+ // test if move after last will work or not
+
+ rs.afterLast();
+
+ try {
+ rs.relative(2);
+ fail("relative move from an invalid row should fail"); //$NON-NLS-1$
+ } catch (SQLException e) {
+
+ }
+ assertEquals(
+ " Should still be after the last row. ", true, rs.isAfterLast());
//$NON-NLS-1$
+ assertEquals(0, rs.getRow());
+ try {
+ rs.relative(-2);
+ fail("relative move from an invalid row should fail"); //$NON-NLS-1$
+ } catch (SQLException e) {
+
+ }
+ assertEquals(
+ " Should still be after the last row. ", true, rs.isAfterLast());
//$NON-NLS-1$
+ assertEquals(0, rs.getRow());
+ rs.close();
+ }
+
+ /** test only valid row in result set */
+ @Test public void testAbsolute1a() throws Exception {
+ ResultSetImpl rs = helpGetResultSetImpl(TYPE_SCROLL_SENSITIVE);
+
+ // start from beginning
+ boolean actual = rs.absolute(1);
+ assertEquals(true, actual);
+ assertEquals(1, rs.getRow());
+
+ actual = rs.absolute(12);
+ assertEquals(false, actual);
+ assertEquals(0, rs.getRow());
+
+ // start from right after last
+ rs.afterLast();
+ actual = rs.absolute(-1);
+ assertEquals(true, actual);
+ assertEquals(5, rs.getRow());
+
+ actual = rs.absolute(-2);
+ assertEquals(true, actual);
+ assertEquals(4, rs.getRow());
+ rs.close();
+ }
+
+ /** test only valid row in result set */
+ @Test public void testAbsolute2a() throws Exception {
+ ResultSetImpl rs = helpGetNoResults(TYPE_SCROLL_SENSITIVE);
+
+ // start from beginning
+ assertEquals(false, rs.absolute(1));
+ assertEquals(0, rs.getRow());
+
+ // start from right after last
+ rs.afterLast();
+ assertEquals(false, rs.absolute(-1));
+ assertEquals(0, rs.getRow());
+
+ rs.close();
+ }
+
+ /**
+ * 3 batches
+ */
+ @Test public void testMoreResults() throws Exception {
+ int fetchSize = 5;
+ int batchLength = 4;
+ int totalLength = 10;
+
+ ResultSetImpl rs = helpTestBatching(statement, fetchSize, batchLength,
+ totalLength);
+
+ assertTrue(rs.absolute(6));
+ assertTrue(rs.absolute(-1));
+ assertFalse(rs.next());
+
+ for (int i = 0; i < totalLength; i++) {
+ assertTrue(rs.previous());
+ }
+ }
+
+ static ResultSetImpl helpTestBatching(StatementImpl statement, int fetchSize, int
batchLength,
+ int totalLength) throws InterruptedException, ExecutionException,
+ MetaMatrixProcessingException, SQLException, TimeoutException {
+ DQP dqp = mock(DQP.class);
+ stub(statement.getDQP()).toReturn(dqp);
+ stub(statement.getFetchSize()).toReturn(fetchSize);
+ for (int i = batchLength; i < totalLength; i += batchLength) {
+ //forward requests
+ ResultsFuture<ResultsMessage> nextBatch = mock(ResultsFuture.class);
+ stub(nextBatch.get(Matchers.anyLong(),
(TimeUnit)Matchers.anyObject())).toReturn(exampleResultsMsg4(i + 1, Math.min(batchLength,
totalLength - i), fetchSize, i + batchLength >= totalLength));
+ stub(dqp.processCursorRequest(REQUEST_ID, i + 1, fetchSize)).toReturn(nextBatch);
+
+ if (i + batchLength < totalLength) {
+ //backward requests
+ ResultsFuture<ResultsMessage> previousBatch = mock(ResultsFuture.class);
+ stub(previousBatch.get(Matchers.anyLong(),
(TimeUnit)Matchers.anyObject())).toReturn(exampleResultsMsg4(i - batchLength + 1, i,
fetchSize, false));
+ stub(dqp.processCursorRequest(REQUEST_ID, i, fetchSize)).toReturn(previousBatch);
+ }
+ }
+
+ ResultsMessage msg = exampleResultsMsg4(1, batchLength, fetchSize, batchLength ==
totalLength);
+ return new ResultSetImpl(msg, statement);
+ }
+
+ // /////////////////////Helper Method///////////////////
+ static List<Object>[] exampleResults1(int length) {
+ return exampleResults1(length, 1);
+ }
+
+ static List<Object>[] exampleResults1(int length, int begin) {
+ List<Object>[] results = new List[length];
+
+ for (int i = 0; i < results.length; i++) {
+ results[i] = new ArrayList<Object>();
+ results[i].add(new Integer(begin + i));
+ }
+
+ return results;
+ }
+
+ private List[] exampleResults2() {
+ List[] results = new List[5];
+
+ for (int i = 0; i < results.length; i++) {
+ results[i] = new ArrayList();
+ results[i].add(new Integer(i));
+ results[i].add(new String("a" + i)); //$NON-NLS-1$
+ }
+
+ return results;
+ }
+
+ private String[] columnNames() {
+ String[] names = new String[2];
+ names[0] = new String("IntNum"); //$NON-NLS-1$
+ names[1] = new String("StringNum"); //$NON-NLS-1$
+ return names;
+ }
+
+ private String[] dataTypes() {
+ String[] types = new String[2];
+ types[0] = MMJDBCSQLTypeInfo.INTEGER;
+ types[1] = MMJDBCSQLTypeInfo.STRING;
+ return types;
+ }
+
+ private ResultSetImpl helpGetResultSetImpl(int type)
+ throws SQLException {
+ ResultsMessage rsMsg = exampleResultsMsg2();
+ statement = TestMMResultSet.createMockStatement(type);
+ ResultSetImpl rs = new ResultSetImpl(rsMsg, statement);
+ return rs;
+ }
+
+ private ResultSetImpl helpGetNoResults(int type) throws SQLException {
+ ResultsMessage rsMsg = exampleResultsMsg3();
+ statement = TestMMResultSet.createMockStatement(type);
+ ResultSetImpl rs = new ResultSetImpl(rsMsg, statement);
+ return rs;
+ }
+
+ /** without metadata info. */
+ private ResultsMessage exampleResultsMsg1() {
+ return exampleMessage(exampleResults1(5), new String[] { "IntNum" }, new
String[] { MMJDBCSQLTypeInfo.INTEGER }); //$NON-NLS-1$
+ }
+
+ private ResultsMessage exampleMessage(List<Object>[] results, String[]
columnNames, String[] datatypes) {
+ RequestMessage request = new RequestMessage();
+ request.setExecutionId(REQUEST_ID);
+ ResultsMessage resultsMsg = new ResultsMessage(request);
+ resultsMsg.setResults(results);
+ resultsMsg.setColumnNames(columnNames);
+ resultsMsg.setDataTypes(datatypes);
+ resultsMsg.setFinalRow(results.length);
+ resultsMsg.setLastRow(results.length);
+ resultsMsg.setFirstRow(1);
+ return resultsMsg;
+ }
+
+ /** without metadata info. */
+ private ResultsMessage exampleResultsMsg2() {
+ return exampleMessage(exampleResults2(), new String[] { "IntNum",
"StringNum" }, new String[] { MMJDBCSQLTypeInfo.INTEGER,
MMJDBCSQLTypeInfo.STRING }); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /** with limited metadata info. */
+ private ResultsMessage exampleResultsMsg2a() {
+ ResultsMessage resultsMsg = exampleResultsMsg2();
+ List[] results = exampleResults2();
+ resultsMsg.setDataTypes(dataTypes());
+ resultsMsg.setColumnNames(columnNames());
+
+ resultsMsg.setResults(results);
+ resultsMsg.setFinalRow(results.length);
+ resultsMsg.setLastRow(results.length);
+ resultsMsg.setFirstRow(1);
+ return resultsMsg;
+ }
+
+ /** no rows. */
+ private ResultsMessage exampleResultsMsg3() {
+ return exampleMessage(new List[0], new String[] { "IntNum",
"StringNum" }, new String[] { MMJDBCSQLTypeInfo.INTEGER,
MMJDBCSQLTypeInfo.STRING }); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ private static ResultsMessage exampleResultsMsg4(int begin, int length, int fetchSize,
boolean lastBatch) {
+ RequestMessage request = new RequestMessage();
+ request.setExecutionId(REQUEST_ID);
+ ResultsMessage resultsMsg = new ResultsMessage(request);
+ List[] results = exampleResults1(length, begin);
+ resultsMsg.setResults(results);
+ resultsMsg.setColumnNames(new String[] { "IntKey" }); //$NON-NLS-1$
+ resultsMsg.setDataTypes(new String[] { MMJDBCSQLTypeInfo.INTEGER });
+ resultsMsg.setFirstRow(begin);
+ if (lastBatch) {
+ resultsMsg.setFinalRow(begin + results.length - 1);
+ }
+ resultsMsg.setLastRow(begin + results.length - 1);
+ return resultsMsg;
+ }
+
+ @Test public void testNotCallingNext() throws SQLException {
+ ResultSetImpl cs = new ResultSetImpl(exampleResultsMsg2a(),
+ statement);
+
+ try {
+ cs.getObject(1);
+ fail("Exception expected"); //$NON-NLS-1$
+ } catch (SQLException e) {
+ assertEquals("The cursor is not on a valid row.", e.getMessage());
//$NON-NLS-1$
+ }
+ }
+
+ @Test public void testDateType() throws SQLException {
+ RequestMessage request = new RequestMessage();
+ request.setExecutionId(REQUEST_ID);
+ ResultsMessage resultsMsg = new ResultsMessage(request);
+ resultsMsg.setResults(new List[] {Arrays.asList(new Timestamp(0))});
+ resultsMsg.setColumnNames(new String[] { "TS" }); //$NON-NLS-1$
+ resultsMsg.setDataTypes(new String[] { MMJDBCSQLTypeInfo.TIMESTAMP });
+ resultsMsg.setFirstRow(1);
+ resultsMsg.setFinalRow(1);
+ resultsMsg.setLastRow(1);
+ ResultSetImpl rs = new ResultSetImpl(resultsMsg, statement);
+ assertTrue(rs.next());
+ //assumes the mock statement is setup with GMT-5 server and GMT-6 client
+
+ //will adjust ahead one hour
+ assertEquals(new Timestamp(3600000), rs.getObject(1));
+
+ //will be the same as the original
+ assertEquals(new Timestamp(0), rs.getTimestamp(1,
Calendar.getInstance(TimeZone.getTimeZone("GMT-05:00")))); //$NON-NLS-1$
+ }
+
+ @Test public void testWasNull() throws SQLException{
+ ResultsMessage message = exampleMessage(new List[] { Arrays.asList((String)null),
Arrays.asList("1") }, new String[] { "string" }, //$NON-NLS-1$
+ new String[] { MMJDBCSQLTypeInfo.STRING });
+ ResultSetImpl rs = new ResultSetImpl(message, statement);
+ assertTrue(rs.next());
+ assertEquals(Boolean.FALSE.booleanValue(), rs.getBoolean(1));
+ assertTrue(rs.wasNull());
+ assertEquals(0, rs.getShort(1));
+ assertTrue(rs.wasNull());
+ assertEquals(0, rs.getInt(1));
+ assertTrue(rs.wasNull());
+ assertEquals(0l, rs.getLong(1));
+ assertTrue(rs.wasNull());
+ assertEquals(0f, rs.getFloat(1), 0);
+ assertTrue(rs.wasNull());
+ assertEquals(0d, rs.getDouble(1), 0);
+ assertTrue(rs.wasNull());
+ assertNull(rs.getString(1));
+ assertTrue(rs.wasNull());
+ assertTrue(rs.next());
+ assertEquals(1, rs.getShort(1));
+ assertFalse(rs.wasNull());
+ assertFalse(rs.next());
+ }
+
+ @Test public void testGetters() throws SQLException{
+ TimeZone.setDefault(TimeZone.getTimeZone("GMT-05:00")); //$NON-NLS-1$
+ ResultsMessage message = exampleMessage(new List[] { Arrays.asList(1,
TimestampUtil.createTime(0, 0, 0), TimestampUtil.createDate(1, 1, 1),
TimestampUtil.createTimestamp(1, 1, 1, 1, 1, 1, 1), "<root/>") },
//$NON-NLS-1$
+ new String[] { "int", "time", "date",
"timestamp", "sqlxml" }, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
//$NON-NLS-4$ //$NON-NLS-5$
+ new String[] { MMJDBCSQLTypeInfo.INTEGER, MMJDBCSQLTypeInfo.TIME,
MMJDBCSQLTypeInfo.DATE, MMJDBCSQLTypeInfo.TIMESTAMP, MMJDBCSQLTypeInfo.STRING });
+ TimestampWithTimezone.resetCalendar(TimeZone.getTimeZone("GMT-06:00"));
//$NON-NLS-1$
+ ResultSetImpl rs = new ResultSetImpl(message, statement);
+ assertTrue(rs.next());
+ assertEquals(Boolean.TRUE.booleanValue(), rs.getBoolean(1));
+ assertEquals(1, rs.getShort(1));
+ assertEquals(1, rs.getInt(1));
+ assertEquals(1l, rs.getLong(1));
+ assertEquals(1f, rs.getFloat(1), 0);
+ assertEquals(1d, rs.getDouble(1), 0);
+ assertEquals("1", rs.getString(1)); //$NON-NLS-1$
+ assertEquals(Integer.valueOf(1), rs.getObject(1));
+ //the mock statement is in GMT-6 the server results are from GMT-5, so we expect them
to display the same
+ assertEquals(TimestampUtil.createTime(0, 0, 0), rs.getTime(2));
+ assertEquals(TimestampUtil.createDate(1, 1, 1), rs.getDate(3));
+ assertEquals(TimestampUtil.createTimestamp(1, 1, 1, 1, 1, 1, 1), rs.getTimestamp(4));
+ assertEquals("<?xml version=\"1.0\"
encoding=\"UTF-8\"?><root/>", rs.getSQLXML(5).getString());
//$NON-NLS-1$
+ try {
+ rs.getSQLXML(1);
+ } catch (SQLException e) {
+ assertEquals("Unable to transform the column value 1 to a SQLXML.",
e.getMessage()); //$NON-NLS-1$
+ }
+ assertFalse(rs.next());
+ TimestampWithTimezone.resetCalendar(null);
+ }
+
+}
Copied: trunk/client/src/test/java/org/teiid/jdbc/TestBatchResults.java (from rev 1983,
trunk/client-jdbc/src/test/java/org/teiid/jdbc/TestBatchResults.java)
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestBatchResults.java
(rev 0)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestBatchResults.java 2010-03-22 21:01:44
UTC (rev 1986)
@@ -0,0 +1,375 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import static org.junit.Assert.*;
+
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+import org.teiid.jdbc.BatchResults.Batch;
+import org.teiid.jdbc.BatchResults.BatchFetcher;
+
+
+/**
+ * @since 4.3
+ */
+public class TestBatchResults {
+
+ static class MockBatchFetcher implements BatchFetcher {
+
+ private int totalRows = 50;
+ private boolean throwException;
+ List<Integer> batchCalls = new ArrayList<Integer>();
+
+ public MockBatchFetcher() {
+
+ }
+
+ public MockBatchFetcher(int totalRows) {
+ this.totalRows = totalRows;
+ }
+
+ public Batch requestBatch(int beginRow) throws SQLException {
+ batchCalls.add(beginRow);
+ if (throwException) {
+ throw new SQLException();
+ }
+ boolean isLast = false;
+ int endRow = beginRow + 9;
+ if (beginRow%10==0) {
+ endRow = beginRow - 9;
+ }
+ if(beginRow > endRow) {
+ if(endRow < 1) {
+ endRow = 1;
+ }
+ int i = beginRow;
+ beginRow = endRow;
+ endRow = i;
+ } else if(endRow > totalRows) {
+ endRow = totalRows;
+ isLast = true;
+ }
+ return new Batch(createBatch(beginRow, endRow), beginRow, endRow, isLast);
+ }
+
+ public void throwException() {
+ this.throwException = true;
+ }
+
+ }
+
+ private static List[] createBatch(int begin, int end) {
+ List[] results = new List[end - begin + 1];
+ for(int i=0; i<(end - begin + 1); i++) {
+ results[i] = new ArrayList();
+ results[i].add(new Integer(i+begin));
+ }
+ return results;
+ }
+
+ private List[] createEmptyBatch() {
+ List[] results = new List[0];
+ return results;
+ }
+
+ @Test public void testGetCurrentRow1() throws Exception{
+ //empty batch
+ BatchResults batchResults = new BatchResults(createEmptyBatch(), 0, 0, true);
+ assertNull(batchResults.getCurrentRow());
+ batchResults.next();
+ assertNull(batchResults.getCurrentRow());
+ }
+
+ @Test public void testGetCurrentRow2() throws Exception{
+ BatchResults batchResults = new BatchResults(createBatch(1, 10), 1, 10, true);
+ assertNull(batchResults.getCurrentRow());
+ batchResults.next();
+ List expectedResult = new ArrayList();
+ expectedResult.add(new Integer(1));
+ assertEquals(batchResults.getCurrentRow(), expectedResult);
+ }
+
+ @Test public void testHasNext1() throws Exception{
+ //empty batch
+ BatchResults batchResults = new BatchResults(createEmptyBatch(), 0, 0, true);
+ assertFalse(batchResults.hasNext());
+ }
+
+ @Test public void testHasNext2() throws Exception{
+ //one row batch
+ BatchResults batchResults = new BatchResults(createBatch(1, 1), 1, 1, true);
+ assertTrue(batchResults.hasNext());
+ }
+
+ @Test public void testHasNext3() throws Exception{
+ BatchResults batchResults = new BatchResults(createBatch(1, 10), 1, 10, true);
+ assertTrue(batchResults.hasNext());
+ }
+
+ @Test public void testNext1() throws Exception{
+ //empty batch
+ BatchResults batchResults = new BatchResults(createEmptyBatch(), 0, 0, true);
+ assertFalse(batchResults.next());
+ }
+
+ @Test public void testNext2() throws Exception{
+ //one row batch
+ BatchResults batchResults = new BatchResults(createBatch(1, 1), 1, 1, true);
+ assertTrue(batchResults.next());
+ List expectedResult = new ArrayList();
+ expectedResult.add(new Integer(1));
+ assertEquals(batchResults.getCurrentRow(), expectedResult);
+ assertFalse(batchResults.next());
+ }
+
+ @Test public void testNext3() throws Exception{
+ //one row batch, multiple batches
+ BatchResults batchResults = new BatchResults(createBatch(1, 1), 1, 1, false);
+ batchResults.setBatchFetcher(new MockBatchFetcher());
+ assertTrue(batchResults.next());
+ assertTrue(batchResults.next());
+ List expectedResult = new ArrayList();
+ expectedResult.add(new Integer(2));
+ assertEquals(batchResults.getCurrentRow(), expectedResult);
+ }
+
+ @Test public void testNext4() throws Exception{
+ BatchResults batchResults = new BatchResults(createBatch(1, 10), 1, 10, false);
+ batchResults.setBatchFetcher(new MockBatchFetcher());
+ int i;
+ for(i=0; i<10; i++) {
+ assertTrue(batchResults.next());
+ List expectedResult = new ArrayList();
+ expectedResult.add(new Integer(i+1));
+ assertEquals(batchResults.getCurrentRow(), expectedResult);
+ }
+ while(batchResults.next()) {
+ List expectedResult = new ArrayList();
+ expectedResult.add(new Integer((i++)+1));
+ assertEquals(batchResults.getCurrentRow(), expectedResult);
+ }
+ assertFalse(batchResults.next());
+ }
+
+ @Test public void testHasPrevious1() throws Exception{
+ //empty batch
+ BatchResults batchResults = new BatchResults(createEmptyBatch(), 0, 0, true);
+ assertFalse(batchResults.hasPrevious());
+ }
+
+ @Test public void testHasPrevious2() throws Exception{
+ //one row batch
+ BatchResults batchResults = new BatchResults(createBatch(1, 1), 1, 1, true);
+ assertFalse(batchResults.hasPrevious());
+ batchResults.next();
+ assertFalse(batchResults.hasPrevious());
+ batchResults.next();
+ assertTrue(batchResults.hasPrevious());
+ }
+
+ @Test public void testPrevious1() throws Exception{
+ //empty batch
+ BatchResults batchResults = new BatchResults(createEmptyBatch(), 0, 0, true);
+ assertFalse(batchResults.previous());
+ }
+
+ @Test public void testPrevious2() throws Exception{
+ //one row batch
+ BatchResults batchResults = new BatchResults(createBatch(1, 1), 1, 1, true);
+ assertTrue(batchResults.next());
+ assertFalse(batchResults.previous());
+ List expectedResult = new ArrayList();
+ expectedResult.add(new Integer(1));
+ while(batchResults.next()) {
+ }
+ assertTrue(batchResults.previous());
+ assertEquals(batchResults.getCurrentRow(), expectedResult);
+ }
+
+ @Test public void testPrevious3() throws Exception{
+ //one row batch, multiple batches
+ BatchResults batchResults = new BatchResults(createBatch(1, 1), 1, 1, false);
+ batchResults.setBatchFetcher(new MockBatchFetcher());
+ assertFalse(batchResults.previous());
+ assertTrue(batchResults.next());
+ assertFalse(batchResults.previous());
+ while(batchResults.next()) {
+ }
+ assertTrue(batchResults.previous());
+ while(batchResults.previous()) {
+ }
+ batchResults.next();
+ batchResults.next();
+ batchResults.next();
+ batchResults.previous();
+ List expectedResult = new ArrayList();
+ expectedResult.add(new Integer(2));
+ assertEquals(batchResults.getCurrentRow(), expectedResult);
+ }
+
+ @Test public void testPrevious4() throws Exception{
+ BatchResults batchResults = new BatchResults(createBatch(1, 10), 1, 10, false);
+ batchResults.setBatchFetcher(new MockBatchFetcher());
+ int i;
+ for(i=0; i<=10; i++) {
+ assertTrue(batchResults.next());
+ }
+ for(i=10; i>0; i--) {
+ batchResults.previous();
+ List expectedResult = new ArrayList();
+ expectedResult.add(new Integer(i));
+ assertEquals(batchResults.getCurrentRow(), expectedResult);
+ }
+ }
+
+ @Test public void testAbsolute1() throws Exception{
+ //empty batch
+ BatchResults batchResults = new BatchResults(createEmptyBatch(), 0, 0, true);
+ assertFalse(batchResults.absolute(0));
+ assertFalse(batchResults.absolute(1));
+ }
+
+ @Test public void testAbsolute2() throws Exception{
+ //one row batch
+ BatchResults batchResults = new BatchResults(createBatch(1, 1), 1, 1, true);
+ batchResults.setBatchFetcher(new MockBatchFetcher());
+ assertFalse(batchResults.absolute(0));
+ assertTrue(batchResults.absolute(1));
+ assertTrue(batchResults.absolute(1));
+ List expectedResult = new ArrayList();
+ expectedResult.add(new Integer(1));
+ assertEquals(batchResults.getCurrentRow(), expectedResult);
+ }
+
+ @Test public void testAbsolute3() throws Exception{
+ BatchResults batchResults = new BatchResults(createBatch(1, 10), 1, 10, false);
+ batchResults.setBatchFetcher(new MockBatchFetcher(200));
+ assertFalse(batchResults.absolute(0));
+ assertTrue(batchResults.absolute(11));
+ List expectedResult = new ArrayList();
+ expectedResult.add(new Integer(11));
+ assertEquals(batchResults.getCurrentRow(), expectedResult);
+ assertTrue(batchResults.absolute(1));
+ expectedResult = new ArrayList();
+ expectedResult.add(new Integer(1));
+ assertEquals(batchResults.getCurrentRow(), expectedResult);
+ assertTrue(batchResults.absolute(100));
+ expectedResult = new ArrayList();
+ expectedResult.add(new Integer(100));
+ assertEquals(batchResults.getCurrentRow(), expectedResult);
+ }
+
+ //move backwards with absolute
+ @Test public void testAbsolute4() throws Exception{
+ //one row batch
+ BatchResults batchResults = new BatchResults(createBatch(1, 1), 1, 1, false);
+ batchResults.setBatchFetcher(new MockBatchFetcher());
+ assertTrue(batchResults.absolute(10));
+ assertTrue(batchResults.absolute(2));
+ List expectedResult = new ArrayList();
+ expectedResult.add(new Integer(2));
+ assertEquals(batchResults.getCurrentRow(), expectedResult);
+ }
+
+ @Test public void testAbsolute5() throws Exception{
+ //one row batch
+ BatchResults batchResults = new BatchResults(createBatch(1, 1), 1, 1, false);
+ batchResults.setBatchFetcher(new MockBatchFetcher());
+ assertTrue(batchResults.absolute(-1));
+ List expectedResult = new ArrayList();
+ expectedResult.add(new Integer(50));
+ assertEquals(batchResults.getCurrentRow(), expectedResult);
+
+ assertFalse(batchResults.absolute(-100));
+ }
+
+ @Test public void testCurrentRowNumber() throws Exception {
+ BatchResults batchResults = new BatchResults(createBatch(1, 1), 1, 1, true);
+ assertEquals(0, batchResults.getCurrentRowNumber());
+ batchResults.next();
+ assertEquals(1, batchResults.getCurrentRowNumber());
+ batchResults.next();
+ assertEquals(2, batchResults.getCurrentRowNumber());
+ assertFalse(batchResults.next());
+ assertEquals(2, batchResults.getCurrentRowNumber());
+ }
+
+ @Test public void testSetException() throws Exception {
+ BatchResults batchResults = new BatchResults(createBatch(1, 1), 1, 1, false);
+ MockBatchFetcher batchFetcher = new MockBatchFetcher();
+ batchResults.setBatchFetcher(batchFetcher);
+ batchFetcher.throwException();
+ batchResults.next();
+ try {
+ batchResults.hasNext();
+ fail("Expected exception, but did not get.");
+ }catch(SQLException e) {
+ }
+ }
+
+ @Test public void testBatching() throws Exception {
+ BatchResults batchResults = new BatchResults(createBatch(1, 10), 1, 10, false);
+ MockBatchFetcher batchFetcher = new MockBatchFetcher(60);
+ batchResults.setBatchFetcher(batchFetcher);
+
+ for(int i=0; i<45; i++) {
+ assertTrue(batchResults.next());
+ }
+
+ for(int i=0; i<44; i++) {
+ assertTrue(batchResults.previous());
+ assertEquals(new Integer(44 - i), batchResults.getCurrentRow().get(0));
+ }
+
+ // verify batch calls
+ checkResults(new int[] {
+ // going forwards - end > begin
+ 11,
+ 21,
+ 31,
+ 41,
+ // going backwards - begin > end
+ // last 3 batches were saved, only need the first 2 again
+ 20,
+ 10,
+ }, batchFetcher.batchCalls);
+
+ assertTrue(batchResults.absolute(50));
+ assertEquals(new Integer(50), batchResults.getCurrentRow().get(0));
+ }
+
+ private void checkResults(int[] expectedCalls, List<Integer> batchCalls) {
+ assertEquals(expectedCalls.length, batchCalls.size());
+
+ for(int i=0; i<batchCalls.size(); i++) {
+ int range = batchCalls.get(i);
+ int expected = expectedCalls[i];
+ assertEquals("On call " + i + " expected different
begin", expected, range);
+ }
+ }
+
+}
Copied: trunk/client/src/test/java/org/teiid/jdbc/TestDataTypeTransformer.java (from rev
1983, trunk/client-jdbc/src/test/java/org/teiid/jdbc/TestDataTypeTransformer.java)
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestDataTypeTransformer.java
(rev 0)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestDataTypeTransformer.java 2010-03-22
21:01:44 UTC (rev 1986)
@@ -0,0 +1,55 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.Clob;
+import java.sql.SQLException;
+
+import javax.sql.rowset.serial.SerialClob;
+
+import org.teiid.jdbc.DataTypeTransformer;
+
+import junit.framework.TestCase;
+
+public class TestDataTypeTransformer extends TestCase {
+
+ public void testClobToStringConversion() throws Exception {
+ Clob clob = new SerialClob("foo".toCharArray()); //$NON-NLS-1$
+ String value = DataTypeTransformer.getString(clob);
+ assertEquals("foo", value); //$NON-NLS-1$
+ }
+
+ public void testInvalidTransformation() throws Exception {
+ try {
+ DataTypeTransformer.getDate(Integer.valueOf(1));
+ fail("exception expected"); //$NON-NLS-1$
+ } catch (SQLException e) {
+ assertEquals("Unable to transform the column value 1 to a Date.",
e.getMessage()); //$NON-NLS-1$
+ }
+ }
+
+ public void testGetByte() throws Exception {
+ assertEquals(0, DataTypeTransformer.getShort(null));
+ }
+
+}
Property changes on:
trunk/client/src/test/java/org/teiid/jdbc/TestDataTypeTransformer.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Copied: trunk/client/src/test/java/org/teiid/jdbc/TestEmbeddedProfile.java (from rev 1983,
trunk/client-jdbc/src/test/java/org/teiid/jdbc/TestEmbeddedProfile.java)
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestEmbeddedProfile.java
(rev 0)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestEmbeddedProfile.java 2010-03-22 21:01:44
UTC (rev 1986)
@@ -0,0 +1,121 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+package org.teiid.jdbc;
+
+import static org.junit.Assert.*;
+
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.Properties;
+
+import org.junit.Test;
+
+
+
+public class TestEmbeddedProfile {
+ EmbeddedProfile EmbeddedProfile = new EmbeddedProfile();
+
+ /*
+ * Test method for
'com.metamatrix.jdbc.EmbeddedEmbeddedProfile.acceptsURL(String)'
+ * // (\\w:[\\\\,\\/]|file:\\/\\/|\\/|\\\\|(\\.){1,2}){1}
+ */
+ @Test public void testAcceptsURL() {
+
+ // ClassPath based URL
+
assertFalse(org.teiid.jdbc.EmbeddedProfile.acceptsURL("jdbc:teiid:BQT@classpath:/dqp.properties;partialResultsMode=true"));
//$NON-NLS-1$
+
+ // These are specific to the MMorg.teiid.jdbc.EmbeddedProfile and should not be
suported
+
assertFalse(org.teiid.jdbc.EmbeddedProfile.acceptsURL("jdbc:teiid:BQT@mm://host:7001;version=1"));
//$NON-NLS-1$
+
assertFalse(org.teiid.jdbc.EmbeddedProfile.acceptsURL("jdbc:teiid:BQT@mms://host:7001;version=1"));
//$NON-NLS-1$
+
+
assertTrue(org.teiid.jdbc.EmbeddedProfile.acceptsURL("jdbc:teiid:BQT"));
//$NON-NLS-1$
+
assertFalse(org.teiid.jdbc.EmbeddedProfile.acceptsURL("jdbc:teiid:BQT!/path/foo.properties"));
//$NON-NLS-1$
+
assertTrue(org.teiid.jdbc.EmbeddedProfile.acceptsURL("jdbc:teiid:BQT;"));
//$NON-NLS-1$
+
assertTrue(org.teiid.jdbc.EmbeddedProfile.acceptsURL("jdbc:teiid:BQT;version=1;logFile=foo.txt"));
//$NON-NLS-1$
+ }
+
+ @Test public void testParseURL() throws SQLException{
+ Properties p = new Properties();
+ org.teiid.jdbc.EmbeddedProfile.parseURL("jdbc:teiid:BQT", p);
//$NON-NLS-1$
+ assertTrue(p.getProperty(BaseDataSource.VDB_NAME).equals("BQT"));
//$NON-NLS-1$
+ assertEquals(2, p.size());
+ }
+
+ @Test public void testParseURL2() throws SQLException {
+ Properties p = new Properties();
+ org.teiid.jdbc.EmbeddedProfile.parseURL("jdbc:teiid:BQT;version=3", p);
//$NON-NLS-1$
+ assertTrue(p.getProperty(BaseDataSource.VDB_NAME).equals("BQT"));
//$NON-NLS-1$
+ assertTrue(p.getProperty(BaseDataSource.VDB_VERSION).equals("3"));
//$NON-NLS-1$
+ assertTrue(p.getProperty(BaseDataSource.VERSION).equals("3"));
//$NON-NLS-1$
+ assertEquals(4, p.size());
+ }
+
+ @Test public void testParseURL3() throws SQLException{
+ Properties p = new Properties();
+
org.teiid.jdbc.EmbeddedProfile.parseURL("jdbc:teiid:BQT@/metamatrix/dqp/dqp.properties;version=4;autoCommitTxn=ON;partialResultsMode=YES;",
p); //$NON-NLS-1$
+ assertTrue(p.getProperty(BaseDataSource.VDB_NAME).equals("BQT"));
//$NON-NLS-1$
+ assertTrue(p.getProperty(BaseDataSource.VDB_VERSION).equals("4"));
//$NON-NLS-1$
+ assertTrue(p.getProperty(BaseDataSource.VERSION).equals("4"));
//$NON-NLS-1$
+
assertTrue(p.getProperty(ExecutionProperties.PROP_TXN_AUTO_WRAP).equals("ON"));
//$NON-NLS-1$
+
assertTrue(p.getProperty(ExecutionProperties.PROP_PARTIAL_RESULTS_MODE).equals("YES"));
//$NON-NLS-1$
+ assertEquals(6, p.size());
+ }
+
+ @Test public void testParseURL4() throws SQLException{
+ Properties p = new Properties();
+
org.teiid.jdbc.EmbeddedProfile.parseURL("jdbc:teiid:BQT;partialResultsMode=true",
p); //$NON-NLS-1$
+ assertTrue(p.getProperty(BaseDataSource.VDB_NAME).equals("BQT"));
//$NON-NLS-1$
+
assertTrue(p.getProperty(ExecutionProperties.PROP_PARTIAL_RESULTS_MODE).equals("true"));
//$NON-NLS-1$
+ assertEquals(3, p.size());
+ }
+
+ @Test public void testParseURL5() throws SQLException{
+ Properties p = new Properties();
+ org.teiid.jdbc.EmbeddedProfile.parseURL("jdbc:teiid:BQT", p);
//$NON-NLS-1$
+ assertTrue(p.getProperty(BaseDataSource.VDB_NAME).equals("BQT"));
//$NON-NLS-1$
+ }
+
+ @Test public void testParseURL55() throws SQLException{
+ Properties p = new Properties();
+ org.teiid.jdbc.EmbeddedProfile.parseURL("jdbc:teiid:BQT;", p);
//$NON-NLS-1$
+ assertTrue(p.getProperty(BaseDataSource.VDB_NAME).equals("BQT"));
//$NON-NLS-1$
+ }
+
+ @Test public void testParseURL6() throws SQLException{
+ Properties p = new Properties();
+
org.teiid.jdbc.EmbeddedProfile.parseURL("jdbc:teiid:BQT;partialResultsMode=true;version=1",
p); //$NON-NLS-1$
+ assertTrue(p.getProperty(BaseDataSource.VDB_NAME).equals("BQT"));
//$NON-NLS-1$
+
assertTrue(p.getProperty(ExecutionProperties.PROP_PARTIAL_RESULTS_MODE).equals("true"));
//$NON-NLS-1$
+ assertTrue(p.getProperty(BaseDataSource.VDB_VERSION).equals("1"));
//$NON-NLS-1$
+ assertEquals(5, p.size());
+
+ }
+
+ @Test public void test() throws Exception {
+ try {
+ Class.forName("org.teiid.jdbc.TeiidDriver"); //$NON-NLS-1$
+
DriverManager.getConnection("jdbc:teiid:Parts@invalidConfig.properties;version=1");
//$NON-NLS-1$
+ fail();
+ } catch (SQLException e) {
+ }
+ }
+}
Property changes on: trunk/client/src/test/java/org/teiid/jdbc/TestEmbeddedProfile.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Copied: trunk/client/src/test/java/org/teiid/jdbc/TestMMCallableStatement.java (from rev
1983, trunk/client-jdbc/src/test/java/org/teiid/jdbc/TestMMCallableStatement.java)
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestMMCallableStatement.java
(rev 0)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestMMCallableStatement.java 2010-03-22
21:01:44 UTC (rev 1986)
@@ -0,0 +1,109 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright (C) 2008 Red Hat, Inc.
+ * Licensed to Red Hat, Inc. under one or more contributor
+ * license agreements. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import org.mockito.Mockito;
+import org.teiid.client.RequestMessage;
+import org.teiid.client.ResultsMessage;
+import org.teiid.client.metadata.ParameterInfo;
+import org.teiid.client.security.LogonResult;
+import org.teiid.jdbc.CallableStatementImpl;
+import org.teiid.jdbc.ConnectionImpl;
+import org.teiid.jdbc.ResultSetImpl;
+import org.teiid.net.ServerConnection;
+
+import com.metamatrix.common.types.MMJDBCSQLTypeInfo;
+
+public class TestMMCallableStatement extends TestCase {
+
+ public void testWasNull() throws Exception {
+ CallableStatementImpl mmcs = getCallableStatement();
+
+ Map<Integer, Integer> params = new HashMap<Integer, Integer>();
+ mmcs.outParamIndexMap = params;
+ params.put(Integer.valueOf(1), Integer.valueOf(1));
+ params.put(Integer.valueOf(2), Integer.valueOf(2));
+ ResultSetImpl rs = Mockito.mock(ResultSetImpl.class);
+ mmcs.resultSet = rs;
+ Mockito.stub(rs.getOutputParamValue(1)).toReturn(null);
+ Mockito.stub(rs.getOutputParamValue(2)).toReturn(Boolean.TRUE);
+ mmcs.getBoolean(1);
+ assertTrue(mmcs.wasNull());
+ assertTrue(mmcs.getBoolean(2));
+ assertFalse(mmcs.wasNull());
+ }
+
+ public void testGetOutputParameter() throws Exception {
+ CallableStatementImpl mmcs = getCallableStatement();
+
+ RequestMessage request = new RequestMessage();
+ request.setExecutionId(1);
+ ResultsMessage resultsMsg = new ResultsMessage(request);
+ List[] results = new List[] {Arrays.asList(null, null, null), Arrays.asList(null, 1,
2)};
+ resultsMsg.setResults(results);
+ resultsMsg.setColumnNames(new String[] { "IntNum", "Out1",
"Out2" }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ resultsMsg.setDataTypes(new String[] { MMJDBCSQLTypeInfo.INTEGER,
MMJDBCSQLTypeInfo.INTEGER, MMJDBCSQLTypeInfo.INTEGER });
+ resultsMsg.setFinalRow(results.length);
+ resultsMsg.setLastRow(results.length);
+ resultsMsg.setFirstRow(1);
+ resultsMsg.setParameters(Arrays.asList(new ParameterInfo(ParameterInfo.RESULT_SET, 1),
new ParameterInfo(ParameterInfo.OUT, 1), new ParameterInfo(ParameterInfo.OUT, 1)));
+ mmcs.createResultSet(resultsMsg);
+ assertEquals(1, mmcs.getInt(1));
+ assertEquals(2, mmcs.getInt(2));
+ }
+
+ public void testUnknownIndex() throws Exception {
+ CallableStatementImpl mmcs = getCallableStatement();
+
+ mmcs.outParamIndexMap = new HashMap<Integer, Integer>();
+
+ try {
+ mmcs.getBoolean(0);
+ fail("expected exception"); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ assertEquals("Parameter is not found at index 0.", e.getMessage());
+ }
+ }
+
+ private CallableStatementImpl getCallableStatement() throws SQLException {
+ ConnectionImpl conn = Mockito.mock(ConnectionImpl.class);
+ ServerConnection sc = Mockito.mock(ServerConnection.class);
+
+ Mockito.stub(sc.getLogonResult()).toReturn(new LogonResult());
+ Mockito.stub(conn.getServerConnection()).toReturn(sc);
+
+ CallableStatementImpl mmcs = new CallableStatementImpl(conn, "{?=call x(?)}",
ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
+ return mmcs;
+ }
+
+}
Property changes on:
trunk/client/src/test/java/org/teiid/jdbc/TestMMCallableStatement.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Copied: trunk/client/src/test/java/org/teiid/jdbc/TestMMConnection.java (from rev 1983,
trunk/client-jdbc/src/test/java/org/teiid/jdbc/TestMMConnection.java)
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestMMConnection.java
(rev 0)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestMMConnection.java 2010-03-22 21:01:44
UTC (rev 1986)
@@ -0,0 +1,132 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import static org.mockito.Mockito.*;
+
+import java.sql.SQLException;
+import java.util.Properties;
+
+import junit.framework.TestCase;
+
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.teiid.client.DQP;
+import org.teiid.client.security.LogonResult;
+import org.teiid.client.security.SessionToken;
+import org.teiid.client.util.ResultsFuture;
+import org.teiid.client.xa.XATransactionException;
+import org.teiid.client.xa.XidImpl;
+import org.teiid.jdbc.BaseDataSource;
+import org.teiid.jdbc.ConnectionImpl;
+import org.teiid.net.ServerConnection;
+
+
+public class TestMMConnection extends TestCase {
+
+ protected static final String STD_DATABASE_NAME = "QT_Ora9DS";
//$NON-NLS-1$
+ protected static final int STD_DATABASE_VERSION = 1;
+
+ static String serverUrl =
"jdbc:metamatrix:QT_Ora9DS@mm://localhost:7001;version=1;user=metamatrixadmin;password=mm";
//$NON-NLS-1$
+
+ public TestMMConnection(String name) {
+ super(name);
+ }
+
+ public static ConnectionImpl getMMConnection() {
+ ServerConnection mock = mock(ServerConnection.class);
+ DQP dqp = mock(DQP.class);
+ try {
+ stub(dqp.start((XidImpl)Mockito.anyObject(), Mockito.anyInt(),
Mockito.anyInt())).toAnswer(new Answer() {
+ @Override
+ public Object answer(InvocationOnMock invocation) throws Throwable {
+ return ResultsFuture.NULL_FUTURE;
+ }
+ });
+ stub(dqp.rollback((XidImpl)Mockito.anyObject())).toAnswer(new Answer() {
+ @Override
+ public Object answer(InvocationOnMock invocation) throws Throwable {
+ return ResultsFuture.NULL_FUTURE;
+ }
+ });
+ stub(dqp.rollback()).toAnswer(new Answer() {
+ @Override
+ public Object answer(InvocationOnMock invocation) throws Throwable {
+ return ResultsFuture.NULL_FUTURE;
+ }
+ });
+ } catch (XATransactionException e) {
+ throw new RuntimeException(e);
+ }
+ stub(mock.getService(DQP.class)).toReturn(dqp);
+ Properties props = new Properties();
+ props.setProperty(BaseDataSource.VDB_NAME, STD_DATABASE_NAME);
+ props.setProperty(BaseDataSource.VDB_VERSION,
String.valueOf(STD_DATABASE_VERSION));
+ props.setProperty(BaseDataSource.USER_NAME, "metamatrixadmin");
//$NON-NLS-1$
+ stub(mock.getLogonResult()).toReturn(new LogonResult(new SessionToken(1,
"metamatrixadmin"), STD_DATABASE_NAME,STD_DATABASE_VERSION , "fake"));
//$NON-NLS-1$
+ return new ConnectionImpl(mock, props, serverUrl);
+ }
+
+ public void testGetMetaData() throws Exception {
+ assertNotNull(getMMConnection().getMetaData());
+ }
+
+ public void testGetSchema() throws Exception {
+ assertEquals("Actual schema is not equql to the expected one. ",
STD_DATABASE_NAME, getMMConnection().getVDBName()); //$NON-NLS-1$
+ }
+
+ public void testNativeSql() throws Exception {
+ String sql = "SELECT * FROM BQT1.SmallA"; //$NON-NLS-1$
+ assertEquals("Actual schema is not equql to the expected one. ", sql,
getMMConnection().nativeSQL(sql)); //$NON-NLS-1$
+ }
+
+ /** test getUserName() through DriverManager */
+ public void testGetUserName2() throws Exception {
+ assertEquals("Actual userName is not equal to the expected one. ",
"metamatrixadmin", getMMConnection().getUserName()); //$NON-NLS-1$
//$NON-NLS-2$
+ }
+
+ /** test isReadOnly default value on Connection */
+ public void testIsReadOnly() throws Exception {
+ assertEquals(false, getMMConnection().isReadOnly());
+ }
+
+ /** test setReadOnly on Connection */
+ public void testSetReadOnly1() throws Exception {
+ ConnectionImpl conn = getMMConnection();
+ conn.setReadOnly(true);
+ assertEquals(true, conn.isReadOnly());
+ }
+
+ /** test setReadOnly on Connection during a transaction */
+ public void testSetReadOnly2() throws Exception {
+ ConnectionImpl conn = getMMConnection();
+ conn.setAutoCommit(false);
+ try {
+ conn.setReadOnly(true);
+ fail("Error Expected"); //$NON-NLS-1$
+ } catch (SQLException e) {
+ // error expected
+ }
+ }
+}
Copied: trunk/client/src/test/java/org/teiid/jdbc/TestMMDriver.java (from rev 1983,
trunk/client-jdbc/src/test/java/org/teiid/jdbc/TestMMDriver.java)
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestMMDriver.java
(rev 0)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestMMDriver.java 2010-03-22 21:01:44 UTC
(rev 1986)
@@ -0,0 +1,134 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.DriverPropertyInfo;
+import java.util.Properties;
+
+import org.teiid.net.TeiidURL;
+
+
+
+import junit.framework.TestCase;
+
+
+public class TestMMDriver extends TestCase {
+ TeiidDriver drv = new TeiidDriver();
+ public String localhost = "localhost"; //$NON-NLS-1$
+
+ public TestMMDriver(String name) {
+ super(name);
+ }
+
+ /** Valid format of urls*/
+ public void testAcceptsURL1() throws Exception {
+ assertNotNull(drv);
+ assertTrue(drv.acceptsURL("jdbc:metamatrix:jvdb@mm://localhost:1234"));
//$NON-NLS-1$
+
assertTrue(drv.acceptsURL("jdbc:metamatrix:vdb@mm://localhost:1234;version=x"));
//$NON-NLS-1$
+ assertTrue(drv.acceptsURL("jdbc:metamatrix:vdb@mm://localhost:1234"));
//$NON-NLS-1$
+
assertTrue(drv.acceptsURL("jdbc:metamatrix:vdb@mm://localhost:1234,localhost2:12342,localhost3:12343"));
//$NON-NLS-1$
+
assertTrue(drv.acceptsURL("jdbc:metamatrix:vdb@mm://localhost:1234;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log"));
//$NON-NLS-1$
+
assertTrue(drv.acceptsURL("jdbc:metamatrix:vdb@mm://localhost:1234,localhost2:12342,localhost3:12343;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log"));
//$NON-NLS-1$
+
assertTrue(drv.acceptsURL("jdbc:metamatrix:vdb@mms://localhost:1234;logLevel=1;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log"));
//$NON-NLS-1$
+
assertTrue(!drv.acceptsURL("jdbc:metamatrix:@mm://localhost:1234;logLevel=2;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log"));
//$NON-NLS-1$
+
assertTrue(drv.acceptsURL("jdbc:metamatrix:vdb@mm://localhost:1234;logLevel=2;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log;autoCommitTxn=OFF;paritalResultsMode=true"));
//$NON-NLS-1$
+
assertTrue(drv.acceptsURL("jdbc:metamatrix:jvdb@mms://localhost:1234"));
//$NON-NLS-1$
+
assertTrue(drv.acceptsURL("jdbc:metamatrix:vdb@mm://localhost:1234;version=x"));
//$NON-NLS-1$
+
assertTrue(drv.acceptsURL("jdbc:metamatrix:vdb@mm://localhost:1234,localhost2:12342,localhost3:12343"));
//$NON-NLS-1$
+
assertTrue(drv.acceptsURL("jdbc:metamatrix:vdb@mms://localhost:1234,localhost2:12342,localhost3:12343;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log"));
//$NON-NLS-1$
+
assertTrue(drv.acceptsURL("jdbc:metamatrix:vdb@mms://localhost:1234;logLevel=2;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log;autoCommitTxn=OFF;paritalResultsMode=true"));
//$NON-NLS-1$
+
assertTrue(drv.acceptsURL("jdbc:metamatrix:vdb@mm://127.0.0.1:1234;logLevel=2"));
//$NON-NLS-1$
+ assertTrue(drv.acceptsURL("jdbc:metamatrix:vdb@mms://127.0.0.1:1234"));
//$NON-NLS-1$
+
assertTrue(drv.acceptsURL("jdbc:metamatrix:vdb@mm://127.0.0.1:1234,localhost.mydomain.com:63636;logLevel=2"));
//$NON-NLS-1$
+
assertTrue(drv.acceptsURL("jdbc:metamatrix:vdb@mm://my-host.mydomain.com:53535,127.0.0.1:1234"));
//$NON-NLS-1$
+
assertTrue(drv.acceptsURL("jdbc:metamatrix:vdb@mm://123.123.123.123:53535,127.0.0.1:1234"));
//$NON-NLS-1$
+
+ //DQP type
+
assertTrue(!drv.acceptsURL("jdbc:metamatrix:jvdb@c:/dqp.properties;version=1"));
//$NON-NLS-1$
+
assertTrue(!drv.acceptsURL("jdbc:metamatrix:jvdb@/foo/dqp.properties;version=1"));
//$NON-NLS-1$
+
assertTrue(!drv.acceptsURL("jdbc:metamatrix:jvdb@../foo/dqp.properties;version=1"));
//$NON-NLS-1$
+
+
assertTrue(!drv.acceptsURL("jdbc:metamatrix:jvdb@mm://localhost:port"));
//$NON-NLS-1$
+
assertTrue(!drv.acceptsURL("jdbc:metamatrix:vdb@localhost:port;version=x"));
//$NON-NLS-1$
+ assertTrue(!drv.acceptsURL("jdbc:metamatrix:@localhost:1234"));
//$NON-NLS-1$
+
assertTrue(!drv.acceptsURL("jdbc:metamatrix:@localhost:1234,localhost2:12342,localhost3:12343"));
//$NON-NLS-1$
+
assertTrue(!drv.acceptsURL("jdbc:metamatrix:@localhost:1234;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log"));
//$NON-NLS-1$
+
assertTrue(!drv.acceptsURL("jdbc:metamatrix:@localhost:1234,localhost2:12342,localhost3:12343;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log"));
//$NON-NLS-1$
+
assertTrue(!drv.acceptsURL("jdbc:metamatrix:@localhost:1234;logLevel=1;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log"));
//$NON-NLS-1$
+
assertTrue(!drv.acceptsURL("jdbc:metamatrix:@localhost:1234;logLevel=2;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log"));
//$NON-NLS-1$
+
assertTrue(!drv.acceptsURL("jdbc:metamatrix:@localhost:1234;logLevel=2;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log;autoCommitTxn=OFF;paritalResultsMode=true"));
//$NON-NLS-1$
+
assertTrue(!drv.acceptsURL("jdbc:metamatrix:@localhost:1234;stickyConnections=false;socketsPerVM=4"));
//$NON-NLS-1$
+
assertTrue(!drv.acceptsURL("jdbc:metamatrix:vdb@mm://my_host.mydomain.com:53535,127.0.0.1:1234"));
//$NON-NLS-1$
+ }
+
+ /** Invalid format of urls*/
+ public void testAcceptsURL2() throws Exception {
+ assertNotNull(drv);
+ assertTrue(!drv.acceptsURL("jdbc:matamatrix:test")); //$NON-NLS-1$
+ assertTrue(!drv.acceptsURL("metamatrix:test")); //$NON-NLS-1$
+ assertTrue(!drv.acceptsURL("jdbc&matamatrix:test")); //$NON-NLS-1$
+ assertTrue(!drv.acceptsURL("jdbc;metamatrix:test")); //$NON-NLS-1$
+ }
+
+ public void testParseURL() throws Exception{
+ Properties p = new Properties();
+ SocketProfile.parseURL("jdbc:metamatrix:BQT@mm://slwxp157:1234", p);
//$NON-NLS-1$
+ assertTrue(p.getProperty(BaseDataSource.VDB_NAME).equals("BQT"));
//$NON-NLS-1$
+
assertTrue(p.getProperty(TeiidURL.CONNECTION.SERVER_URL).equals("mm://slwxp157:1234"));
//$NON-NLS-1$
+ assertEquals(3, p.size());
+ }
+
+ public void testParseURL2() throws Exception {
+ Properties p = new Properties();
+
SocketProfile.parseURL("jdbc:metamatrix:BQT@mms://slwxp157:1234;version=3", p);
//$NON-NLS-1$
+ assertTrue(p.getProperty(BaseDataSource.VDB_NAME).equals("BQT"));
//$NON-NLS-1$
+ assertTrue(p.getProperty(BaseDataSource.VDB_VERSION).equals("3"));
//$NON-NLS-1$
+
assertTrue(p.getProperty(TeiidURL.CONNECTION.SERVER_URL).equals("mms://slwxp157:1234"));
//$NON-NLS-1$
+ assertTrue(p.getProperty(BaseDataSource.VERSION).equals("3"));
//$NON-NLS-1$
+
assertTrue(p.getProperty(BaseDataSource.APP_NAME).equals(BaseDataSource.DEFAULT_APP_NAME));
+ assertEquals(5, p.size());
+ }
+
+ public void testParseURL3() throws Exception{
+ Properties p = new Properties();
+
SocketProfile.parseURL("jdbc:metamatrix:BQT@mm://slwxp157:1234,slntmm01:43401,sluxmm09:43302;version=4;autoCommitTxn=ON;partialResultsMode=YES;ApplicationName=Client",
p); //$NON-NLS-1$
+ assertTrue(p.getProperty(BaseDataSource.VDB_NAME).equals("BQT"));
//$NON-NLS-1$
+ assertTrue(p.getProperty(BaseDataSource.VDB_VERSION).equals("4"));
//$NON-NLS-1$
+
assertTrue(p.getProperty(ExecutionProperties.PROP_TXN_AUTO_WRAP).equals("ON"));
//$NON-NLS-1$
+
assertTrue(p.getProperty(ExecutionProperties.PROP_PARTIAL_RESULTS_MODE).equals("YES"));
//$NON-NLS-1$
+
assertTrue(p.getProperty(TeiidURL.CONNECTION.SERVER_URL).equals("mm://slwxp157:1234,slntmm01:43401,sluxmm09:43302"));
//$NON-NLS-1$
+ assertTrue(p.getProperty(BaseDataSource.VERSION).equals("4"));
//$NON-NLS-1$
+ assertTrue(p.getProperty(BaseDataSource.APP_NAME).equals("Client"));
//$NON-NLS-1$
+ assertEquals(7, p.size());
+ }
+
+ public void testGetPropertyInfo1() throws Exception {
+ DriverPropertyInfo info[] =
drv.getPropertyInfo("jdbc:metamatrix:vdb@mm://localhost:12345;applicationName=x",
null); //$NON-NLS-1$
+
+ assertEquals(17, info.length);
+ assertEquals(false, info[0].required);
+ assertEquals("ApplicationName", info[0].name); //$NON-NLS-1$
+ assertEquals("x", info[0].value); //$NON-NLS-1$
+ }
+
+}
Property changes on: trunk/client/src/test/java/org/teiid/jdbc/TestMMDriver.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Copied: trunk/client/src/test/java/org/teiid/jdbc/TestMMJDBCURL.java (from rev 1983,
trunk/client-jdbc/src/test/java/org/teiid/jdbc/TestMMJDBCURL.java)
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestMMJDBCURL.java
(rev 0)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestMMJDBCURL.java 2010-03-22 21:01:44 UTC
(rev 1986)
@@ -0,0 +1,342 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.net.URLEncoder;
+import java.util.Properties;
+
+import org.teiid.jdbc.BaseDataSource;
+import org.teiid.jdbc.ExecutionProperties;
+import org.teiid.jdbc.JDBCURL;
+import org.teiid.net.TeiidURL;
+
+import junit.framework.TestCase;
+
+
+
+/**
+ * @since 4.3
+ */
+public class TestMMJDBCURL extends TestCase {
+
+ // Need to allow embedded spaces and ='s within optional properties
+ public final void testCredentials() throws Exception {
+ String credentials = URLEncoder.encode("defaultToLogon,(system=BQT1 SQL
Server 2000 Simple Cap,user=xyz,password=xyz)", "UTF-8"); //$NON-NLS-1$
//$NON-NLS-2$
+ JDBCURL url = new
JDBCURL("jdbc:metamatrix:QT_sqls2kds@mm://slwxp136:43100;credentials="+credentials);
//$NON-NLS-1$
+ Properties p = url.getProperties();
+ assertEquals("defaultToLogon,(system=BQT1 SQL Server 2000 Simple
Cap,user=xyz,password=xyz)", p.getProperty("credentials"));
//$NON-NLS-1$//$NON-NLS-2$
+ }
+
+ public void testJDBCURLWithProperties() {
+ String URL =
"jdbc:metamatrix:bqt@mm://localhost:12345;version=1;user=xyz;password=***;logLevel=1;configFile=testdata/bqt/dqp_stmt_e2e.xmi;disableLocalTxn=true;autoFailover=false";
//$NON-NLS-1$
+
+ Properties expectedProperties = new Properties();
+ expectedProperties.setProperty("version", "1"); //$NON-NLS-1$
//$NON-NLS-2$
+ expectedProperties.setProperty("user", "xyz"); //$NON-NLS-1$
//$NON-NLS-2$
+ expectedProperties.setProperty("password", "***");
//$NON-NLS-1$ //$NON-NLS-2$
+ expectedProperties.setProperty("logLevel", "1");
//$NON-NLS-1$ //$NON-NLS-2$
+ expectedProperties.setProperty("configFile",
"testdata/bqt/dqp_stmt_e2e.xmi"); //$NON-NLS-1$ //$NON-NLS-2$
+ expectedProperties.setProperty(ExecutionProperties.DISABLE_LOCAL_TRANSACTIONS,
"true"); //$NON-NLS-1$
+ expectedProperties.setProperty(TeiidURL.CONNECTION.AUTO_FAILOVER,
"false"); //$NON-NLS-1$
+ JDBCURL url = new JDBCURL(URL);
+ assertEquals("bqt", url.getVDBName()); //$NON-NLS-1$
+ assertEquals("mm://localhost:12345", url.getConnectionURL());
//$NON-NLS-1$
+ assertEquals(expectedProperties, url.getProperties());
+ }
+
+ public void testJDBCURLWithoutProperties() {
+ String URL = "jdbc:metamatrix:bqt@mm://localhost:12345"; //$NON-NLS-1$
+
+ JDBCURL url = new JDBCURL(URL);
+ assertEquals("bqt", url.getVDBName()); //$NON-NLS-1$
+ assertEquals("mm://localhost:12345", url.getConnectionURL());
//$NON-NLS-1$
+ assertEquals(new Properties(), url.getProperties());
+ }
+
+ public void testCaseConversion() {
+ // Different case ------------------------------------HERE -v
----------------and HERE -v
+ String URL =
"jdbc:metamatrix:bqt@mm://localhost:12345;VERSION=1;user=xyz;password=***;configFile=testdata/bqt/dqp_stmt_e2e.xmi";
//$NON-NLS-1$
+
+ Properties expectedProperties = new Properties();
+ expectedProperties.setProperty("version", "1"); //$NON-NLS-1$
//$NON-NLS-2$
+ expectedProperties.setProperty("user", "xyz"); //$NON-NLS-1$
//$NON-NLS-2$
+ expectedProperties.setProperty("password", "***");
//$NON-NLS-1$ //$NON-NLS-2$
+ expectedProperties.setProperty("configFile",
"testdata/bqt/dqp_stmt_e2e.xmi"); //$NON-NLS-1$ //$NON-NLS-2$
+ JDBCURL url = new JDBCURL(URL);
+ assertEquals("bqt", url.getVDBName()); //$NON-NLS-1$
+ assertEquals("mm://localhost:12345", url.getConnectionURL());
//$NON-NLS-1$
+ assertEquals(expectedProperties, url.getProperties());
+ }
+
+ public void testWithExtraSemicolons() {
+ String URL =
"jdbc:metamatrix:bqt@mm://localhost:12345;version=1;user=xyz;password=***;logLevel=1;;;configFile=testdata/bqt/dqp_stmt_e2e.xmi;;";
//$NON-NLS-1$
+
+ Properties expectedProperties = new Properties();
+ expectedProperties.setProperty("version", "1"); //$NON-NLS-1$
//$NON-NLS-2$
+ expectedProperties.setProperty("user", "xyz"); //$NON-NLS-1$
//$NON-NLS-2$
+ expectedProperties.setProperty("password", "***");
//$NON-NLS-1$ //$NON-NLS-2$
+ expectedProperties.setProperty("logLevel", "1");
//$NON-NLS-1$ //$NON-NLS-2$
+ expectedProperties.setProperty("configFile",
"testdata/bqt/dqp_stmt_e2e.xmi"); //$NON-NLS-1$ //$NON-NLS-2$
+ JDBCURL url = new JDBCURL(URL);
+ assertEquals("bqt", url.getVDBName()); //$NON-NLS-1$
+ assertEquals("mm://localhost:12345", url.getConnectionURL());
//$NON-NLS-1$
+ assertEquals(expectedProperties, url.getProperties());
+ }
+
+ public void testWithWhitespace() {
+ String URL = "jdbc:metamatrix:bqt@mm://localhost:12345; version =1;user= xyz
;password=***; logLevel = 1 ; configFile=testdata/bqt/dqp_stmt_e2e.xmi ;";
//$NON-NLS-1$
+
+ Properties expectedProperties = new Properties();
+ expectedProperties.setProperty("version", "1"); //$NON-NLS-1$
//$NON-NLS-2$
+ expectedProperties.setProperty("user", "xyz"); //$NON-NLS-1$
//$NON-NLS-2$
+ expectedProperties.setProperty("password", "***");
//$NON-NLS-1$ //$NON-NLS-2$
+ expectedProperties.setProperty("logLevel", "1");
//$NON-NLS-1$ //$NON-NLS-2$
+ expectedProperties.setProperty("configFile",
"testdata/bqt/dqp_stmt_e2e.xmi"); //$NON-NLS-1$ //$NON-NLS-2$
+ JDBCURL url = new JDBCURL(URL);
+ assertEquals("bqt", url.getVDBName()); //$NON-NLS-1$
+ assertEquals("mm://localhost:12345", url.getConnectionURL());
//$NON-NLS-1$
+ assertEquals(expectedProperties, url.getProperties());
+ }
+
+ public void testNoPropertyValue() {
+ String URL =
"jdbc:metamatrix:bqt@mm://localhost:12345;version=1;user=xyz;password=***;logLevel=;configFile=";
//$NON-NLS-1$
+
+ Properties expectedProperties = new Properties();
+ expectedProperties.setProperty("version", "1"); //$NON-NLS-1$
//$NON-NLS-2$
+ expectedProperties.setProperty("user", "xyz"); //$NON-NLS-1$
//$NON-NLS-2$
+ expectedProperties.setProperty("password", "***");
//$NON-NLS-1$ //$NON-NLS-2$
+ expectedProperties.setProperty("logLevel", ""); //$NON-NLS-1$
//$NON-NLS-2$
+ expectedProperties.setProperty("configFile", "");
//$NON-NLS-1$ //$NON-NLS-2$
+ JDBCURL url = new JDBCURL(URL);
+ assertEquals("bqt", url.getVDBName()); //$NON-NLS-1$
+ assertEquals("mm://localhost:12345", url.getConnectionURL());
//$NON-NLS-1$
+ assertEquals(expectedProperties, url.getProperties());
+ }
+
+ public void testInvalidProtocol() {
+ String URL =
"jdbc:monkeymatrix:bqt@mm://localhost:12345;version=1;user=xyz;password=***;logLevel=1";
//$NON-NLS-1$
+ try {
+ new JDBCURL(URL);
+ fail("Illegal argument should have failed."); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ public void testNoVDBName() {
+ String URL =
"jdbc:metamatrix:@mm://localhost:12345;version=1;user=xyz;password=***;logLevel=1";
//$NON-NLS-1$
+ try {
+ new JDBCURL(URL);
+ fail("Illegal argument should have failed."); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ public void testNoAtSignInURL() {
+ String URL =
"jdbc:metamatrix:bqt!mm://localhost:12345;version=1;user=xyz;password=***;logLevel=1";
//$NON-NLS-1$
+ try {
+ new JDBCURL(URL);
+ // No @ sign is llowed as part of embedded driver now,
+ // but this form of URL rejected in the acceptURL
+ //fail("Illegal argument should have failed.");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ public void testMoreThanOneAtSign() {
+ String URL =
"jdbc:metamatrix:bqt@mm://localhost:12345;version=1;user=xy@;password=***;logLevel=1";
//$NON-NLS-1$
+ try {
+ // this allowed as customer properties can have @ in their properties
+ new JDBCURL(URL);
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ public void testNoEqualsInProperty() {
+ String URL =
"jdbc:metamatrix:bqt@mm://localhost:12345;version=1;user=xyz;password***;logLevel=1";
//$NON-NLS-1$
+ try {
+ new JDBCURL(URL);
+ fail("Illegal argument should have failed."); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ public void testMoreThanOneEqualsInProperty() {
+ String URL =
"jdbc:metamatrix:bqt@mm://localhost:12345;version=1;user=xyz;password==***;logLevel=1";
//$NON-NLS-1$
+ try {
+ new JDBCURL(URL);
+ fail("Illegal argument should have failed."); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ URL =
"jdbc:metamatrix:bqt@mm://localhost:12345;version=1;user=xyz;password=***=;logLevel=1";
//$NON-NLS-1$
+ try {
+ new JDBCURL(URL);
+ fail("Illegal argument should have failed."); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ URL =
"jdbc:metamatrix:bqt@mm://localhost:12345;version=1;user=xyz;=password=***;logLevel=1";
//$NON-NLS-1$
+ try {
+ new JDBCURL(URL);
+ fail("Illegal argument should have failed."); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ public void testNoKeyInProperty() {
+ String URL =
"jdbc:metamatrix:bqt@mm://localhost:12345;version=1;user=xyz;=***;logLevel=1";
//$NON-NLS-1$
+ try {
+ new JDBCURL(URL);
+ fail("Illegal argument should have failed."); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ public void testConstructor() {
+ JDBCURL url = new JDBCURL("myVDB", "mm://myhost:12345",null);
//$NON-NLS-1$ //$NON-NLS-2$
+ assertEquals("jdbc:teiid:myVDB@mm://myhost:12345", url.getJDBCURL());
//$NON-NLS-1$
+
+ Properties props = new Properties();
+ props.setProperty(BaseDataSource.USER_NAME, "myuser"); //$NON-NLS-1$
+ props.setProperty(BaseDataSource.PASSWORD, "mypassword");
//$NON-NLS-1$
+ props.put("ClieNTtOKeN", new Integer(1)); //$NON-NLS-1$
+ url = new JDBCURL("myVDB", "mm://myhost:12345", props);
//$NON-NLS-1$ //$NON-NLS-2$
+
assertEquals("jdbc:teiid:myVDB@mm://myhost:12345;user=myuser;password=mypassword",
url.getJDBCURL()); //$NON-NLS-1$
+ }
+
+ public void testConstructor_Exception() {
+ try {
+ new JDBCURL(null, "myhost", null); //$NON-NLS-1$
+ fail("Should have failed."); //$NON-NLS-1$
+ } catch (Exception e) {
+
+ }
+ try {
+ new JDBCURL(" ", "myhost", null); //$NON-NLS-1$
//$NON-NLS-2$
+ fail("Should have failed."); //$NON-NLS-1$
+ } catch (Exception e) {
+
+ }
+
+ try {
+ // in embedded situation there is no connection url
+ new JDBCURL("myVDB", " ", null); //$NON-NLS-1$
//$NON-NLS-2$
+ } catch (Exception e) {
+
+ }
+ }
+
+ public void testNormalize() {
+ Properties props = new Properties();
+ props.setProperty("UsEr", "myuser"); //$NON-NLS-1$
//$NON-NLS-2$
+ props.setProperty("pAssWOrD", "mypassword"); //$NON-NLS-1$
//$NON-NLS-2$
+ props.put("ClieNTtOKeN", new Integer(1)); //$NON-NLS-1$
+ JDBCURL.normalizeProperties(props);
+ assertEquals("myuser", props.getProperty(BaseDataSource.USER_NAME));
//$NON-NLS-1$
+ assertEquals("mypassword", props.getProperty(BaseDataSource.PASSWORD));
//$NON-NLS-1$
+ }
+
+ public final void testEncodedPropertyProperties() throws Exception {
+ String password =
"=@#^&*()+!%$^%@#_-)_~{}||\\`':;,./<>?password has = & %";
//$NON-NLS-1$
+ Properties props = new Properties();
+ props.setProperty("UsEr", "foo"); //$NON-NLS-1$
//$NON-NLS-2$
+ props.setProperty("PASswoRd", password); //$NON-NLS-1$
+ JDBCURL.normalizeProperties(props);
+
+ assertEquals(password, props.getProperty("password")); //$NON-NLS-1$
+ assertEquals("foo", props.getProperty("user"));
//$NON-NLS-1$//$NON-NLS-2$
+ }
+
+ public final void testEncodedPropertyInURL() throws Exception {
+ String password =
"=@#^&*()+!%$^%@#_-)_~{}||\\`':;,./<>?password has = & %";
//$NON-NLS-1$
+ String encPassword = URLEncoder.encode(password, "UTF-8");
//$NON-NLS-1$
+ JDBCURL url = new
JDBCURL("jdbc:metamatrix:QT_sqls2kds@mm://slwxp136:43100;PASswoRd="+encPassword);
//$NON-NLS-1$
+ Properties p = url.getProperties();
+ assertEquals(password, p.getProperty("password")); //$NON-NLS-1$
+ }
+
+
+ public void testGetServerURL_NoProperties() {
+ String result = new
JDBCURL("jdbc:metamatrix:designtimecatalog@mm://slwxp172:44401;user=ddifranco;password=mm").getConnectionURL();
//$NON-NLS-1$
+ assertEquals("mm://slwxp172:44401", result); //$NON-NLS-1$
+ }
+
+ public void testGetServerURL_Properties() {
+ String result = new
JDBCURL("jdbc:metamatrix:designtimecatalog@mm://slwxp172:44401;user=ddifranco;password=mm").getConnectionURL();
//$NON-NLS-1$
+ assertEquals("mm://slwxp172:44401", result); //$NON-NLS-1$
+ }
+
+ /**
+ * Test getServerURL with a valid URL and password that contains at least
+ * one ASCII character in the range of 32 to 126 excluding the ; and = sign.
+ *
+ * @since 5.0.2
+ */
+ public void testGetServerURL_PasswordProperties() throws Exception {
+ String result = null;
+ String srcURL =
"jdbc:metamatrix:designtimecatalog@mm://slwxp172:44401;user=ddifranco;password=";
//$NON-NLS-1$
+ String password = null;
+ String tgtURL = "mm://slwxp172:44401"; //$NON-NLS-1$
+
+
+ for ( char ch = 32; ch <= 126; ch++ ) {
+ //exclude URL reserved characters
+ if ( ch != ';' && ch != '=' && ch !=
'%') {
+ password = ch+"mm"; //$NON-NLS-1$
+ result = new JDBCURL(srcURL+URLEncoder.encode(password,
"UTF-8")).getConnectionURL(); //$NON-NLS-1$
+ assertEquals("Failed to obtain correct ServerURL when using password
"+password,tgtURL, result); //$NON-NLS-1$
+ }
+ }
+
+ }
+
+ public void testGetServerURL_2Servers() {
+ String result = new
JDBCURL("jdbc:metamatrix:designtimecatalog@mm://slwxp172:44401,slabc123:12345;user=ddifranco;password=mm").getConnectionURL();
//$NON-NLS-1$
+ assertEquals("mm://slwxp172:44401,slabc123:12345", result);
//$NON-NLS-1$
+ }
+
+ public void testBuildEmbeedURL() {
+ JDBCURL url = new JDBCURL("vdb", "/home/foo/deploy.properties",
new Properties()); //$NON-NLS-1$ //$NON-NLS-2$
+ assertEquals("jdbc:teiid:vdb@/home/foo/deploy.properties",
url.getJDBCURL()); //$NON-NLS-1$
+
+ Properties p = new Properties();
+ p.setProperty("user", "test"); //$NON-NLS-1$ //$NON-NLS-2$
+ p.setProperty("password", "pass"); //$NON-NLS-1$ //$NON-NLS-2$
+ p.setProperty("autoFailover", "true"); //$NON-NLS-1$
//$NON-NLS-2$
+ p.setProperty("any", "thing"); //$NON-NLS-1$ //$NON-NLS-2$
+
+ url = new JDBCURL("vdb", "/home/foo/deploy.properties", p);
//$NON-NLS-1$ //$NON-NLS-2$
+
assertTrue(url.getJDBCURL().startsWith("jdbc:teiid:vdb@/home/foo/deploy.properties;user=test;"));
//$NON-NLS-1$
+ assertTrue(url.getJDBCURL().indexOf("any=thing")!=-1); //$NON-NLS-1$
+ assertTrue(url.getJDBCURL().indexOf("password=pass")!=-1); //$NON-NLS-1$
+ assertTrue(url.getJDBCURL().indexOf("autoFailover=true")!=-1);
//$NON-NLS-1$
+
+ }
+}
Copied: trunk/client/src/test/java/org/teiid/jdbc/TestMMPreparedStatement.java (from rev
1983, trunk/client-jdbc/src/test/java/org/teiid/jdbc/TestMMPreparedStatement.java)
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestMMPreparedStatement.java
(rev 0)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestMMPreparedStatement.java 2010-03-22
21:01:44 UTC (rev 1986)
@@ -0,0 +1,343 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import static org.junit.Assert.*;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.TimeZone;
+
+import org.junit.Test;
+import org.mockito.Matchers;
+import org.mockito.Mockito;
+import org.teiid.client.DQP;
+import org.teiid.client.RequestMessage;
+import org.teiid.client.ResultsMessage;
+import org.teiid.client.RequestMessage.ResultsMode;
+import org.teiid.client.security.LogonResult;
+import org.teiid.client.util.ResultsFuture;
+import org.teiid.jdbc.ConnectionImpl;
+import org.teiid.jdbc.PreparedStatementImpl;
+import org.teiid.jdbc.TeiidSQLException;
+import org.teiid.net.ServerConnection;
+
+
+/**
+ * Test case to validate general operations on an <code>MMPreparedStatement
+ * </code>
+ */
+public class TestMMPreparedStatement {
+
+ /**
+ * Test that <code>MMPreparedStatement</code>'s
<code>execute()</code> method
+ * will throw a <code>MMSQLException</code> if a connection does not exist.
+ *
+ * @throws Exception
+ */
+ @Test(expected=TeiidSQLException.class) public void testUpdateException() throws
Exception {
+ PreparedStatementImpl statement = getMMPreparedStatement("delete from
table"); //$NON-NLS-1$
+ statement.execute();
+ }
+
+ /**
+ * Verify that the <code>executeBatch()</code> method of <code>
+ * MMPreparedStatement</code> is resulting in the correct command,
+ * parameter values for each command of the batch, and the request type
+ * are being set in the request message that would normally be sent to the
+ * server.
+ *
+ * @throws Exception
+ */
+ @Test public void testBatchedUpdateExecution() throws Exception {
+ // Build up a fake connection instance for use with the prepared statement
+ ConnectionImpl conn = Mockito.mock(ConnectionImpl.class);
+ DQP dqp = Mockito.mock(DQP.class);
+ ServerConnection serverConn = Mockito.mock(ServerConnection.class);
+ LogonResult logonResult = Mockito.mock(LogonResult.class);
+
+ // stub methods
+ Mockito.stub(conn.getServerConnection()).toReturn(serverConn);
+ Mockito.stub(serverConn.getLogonResult()).toReturn(logonResult);
+ Mockito.stub(logonResult.getTimeZone()).toReturn(TimeZone.getDefault());
+
+ // a dummy result message that is specific to this test case
+ ResultsFuture<ResultsMessage> results = new
ResultsFuture<ResultsMessage>();
+ Mockito.stub(dqp.executeRequest(Matchers.anyLong(),
(RequestMessage)Matchers.anyObject())).toReturn(results);
+ ResultsMessage rm = new ResultsMessage();
+ rm.setResults(new List<?>[] {Arrays.asList(0), Arrays.asList(0),
Arrays.asList(0)});
+ rm.setUpdateResult(true);
+ results.getResultsReceiver().receiveResults(rm);
+ Mockito.stub(conn.getDQP()).toReturn(dqp);
+
+ // some update SQL
+ String sqlCommand = "delete from table where col=?"; //$NON-NLS-1$
+ TestableMMPreparedStatement statement = (TestableMMPreparedStatement)
getMMPreparedStatement(conn, sqlCommand);
+
+ ArrayList<ArrayList<Object>> expectedParameterValues = new
ArrayList<ArrayList<Object>>(3);
+ // Add some batches and their parameter values
+ expectedParameterValues.add( new ArrayList<Object>( Arrays.asList( new Object[] {
new Integer(1) } ) ) );
+ statement.setInt(1, new Integer(1));
+ statement.addBatch();
+ expectedParameterValues.add( new ArrayList<Object>( Arrays.asList( new Object[] {
new Integer(2) } ) ) );
+ statement.setInt(1, new Integer(2));
+ statement.addBatch();
+ expectedParameterValues.add( new ArrayList<Object>( Arrays.asList( new Object[] {
new Integer(3) } ) ) );
+ statement.setInt(1, new Integer(3));
+ statement.addBatch();
+
+ // execute the batch and verify that it matches our dummy results
+ // message set earlier
+ assertTrue(Arrays.equals(new int[] {0, 0, 0}, statement.executeBatch()));
+
+ // Now verify the statement's RequestMessage is what we expect
+ assertEquals("Command does not match", sqlCommand,
statement.requestMessage.getCommandString()); //$NON-NLS-1$
+ assertEquals("Parameter values do not match", expectedParameterValues,
statement.requestMessage.getParameterValues()); //$NON-NLS-1$
+ assertTrue("RequestMessage.isBatchedUpdate should be true",
statement.requestMessage.isBatchedUpdate()); //$NON-NLS-1$
+ assertFalse("RequestMessage.isCallableStatement should be false",
statement.requestMessage.isCallableStatement()); //$NON-NLS-1$
+ assertTrue("RequestMessage.isPreparedStatement should be true",
statement.requestMessage.isPreparedStatement()); //$NON-NLS-1$
+ }
+
+ /**
+ * Verify that the <code>clearBatch()</code> method of
+ * <code>MMPreparedStatement</code> is clearing the list of batched
+ * commands.
+ * <p>
+ * This is done by first adding command parameter values to the batch and
+ * then invoking the <code>clearBatch()</code> method.
+ *
+ * @throws Exception
+ */
+ @Test public void testClearBatch() throws Exception {
+ PreparedStatementImpl statement = getMMPreparedStatement("delete from table where
col=?"); //$NON-NLS-1$
+ // Add some stuff
+ statement.setInt(1, new Integer(1));
+ statement.addBatch();
+ statement.setInt(1, new Integer(2));
+ statement.addBatch();
+ // Make sure something is really there
+ assertTrue("MMPreparedStatement.ParameterValuesList should not be empty",
statement.getParameterValuesList().size() > 0); //$NON-NLS-1$
+ // Now clear it
+ statement.clearBatch();
+ assertTrue("MMPreparedStatement.ParameterValuesList should be empty",
statement.getParameterValuesList().size() == 0); //$NON-NLS-1$
+ }
+
+ /**
+ * Adds additional batches of command parameter values to a prepared
+ * statement after a previous list has been cleared.
+ * <p>
+ * This is done by first adding command parameter values to the batch and
+ * then invoking the <code>clearBatch()</code> method. Then a different
+ * set of command parameter values are added to the existing batch command.
+ * <p>
+ * The expected result is the command parameter list for the batches will
+ * only reflect what was added after <code>clearBatch()</code> was invoked.
+ *
+ * @throws Exception
+ */
+ @Test public void testClearBatchAddBatch() throws Exception {
+ PreparedStatementImpl statement = getMMPreparedStatement("delete from table where
col=?"); //$NON-NLS-1$
+
+ statement.setInt(1, new Integer(1));
+ statement.addBatch();
+ statement.setInt(1, new Integer(2));
+ statement.addBatch();
+ // Make sure something is really there
+ assertTrue("MMPreparedStatement.ParameterValuesList should not be empty",
statement.getParameterValuesList().size() > 0); //$NON-NLS-1$
+ // Now clear it
+ statement.clearBatch();
+ // Make sure it is empty now
+ assertTrue("MMPreparedStatement.ParameterValuesList should be empty",
statement.getParameterValuesList().size() == 0); //$NON-NLS-1$
+
+ ArrayList<ArrayList<Object>> expectedParameterValues = new
ArrayList<ArrayList<Object>>(1);
+
+ // Now add something for validation
+ expectedParameterValues.add( new ArrayList<Object>( Arrays.asList( new Object[] {
new Integer(5) } ) ) );
+ statement.setInt(1, new Integer(5));
+ statement.addBatch();
+ assertEquals("MMPreparedStatement.ParameterValuesList does not match",
expectedParameterValues, statement.getParameterValuesList()); //$NON-NLS-1$
+ }
+
+ /**
+ * Test the <code>addBatch()</code> method of
<code>MMPreparedStatement</code>
+ * to verify that the command parameter values of the batch are added to the
+ * command parameter values list.
+ *
+ * @throws Exception
+ */
+ @Test public void testAddBatch() throws Exception {
+ PreparedStatementImpl statement = getMMPreparedStatement("delete from table where
col=?"); //$NON-NLS-1$
+
+ ArrayList<ArrayList<Object>> expectedParameterValues = new
ArrayList<ArrayList<Object>>(1);
+
+ // First we add a single batch
+ expectedParameterValues.add( new ArrayList<Object>( Arrays.asList( new Object[] {
new Integer(1) } ) ) );
+ statement.setInt(1, new Integer(1));
+ statement.addBatch();
+ assertEquals("MMPreparedStatement.ParameterValuesList does not match",
expectedParameterValues, statement.getParameterValuesList()); //$NON-NLS-1$
+
+ // Now add some more batches just for sanity sake
+ expectedParameterValues.add( new ArrayList<Object>( Arrays.asList( new Object[] {
new Integer(3) } ) ) );
+ expectedParameterValues.add( new ArrayList<Object>( Arrays.asList( new Object[] {
new Integer(5) } ) ) );
+ statement.setInt(1, new Integer(3));
+ statement.addBatch();
+ statement.setInt(1, new Integer(5));
+ statement.addBatch();
+ assertEquals("MMPreparedStatement.ParameterValuesList does not match",
expectedParameterValues, statement.getParameterValuesList()); //$NON-NLS-1$
+ }
+
+ /**
+ * Test the <code>addBatch()</code> method of
<code>MMPreparedStatement</code>
+ * using a batch with an empty parameter value list. The test will verify
+ * no failures occur when there are no command parameter values defined
+ * when the <code>addBatch()</code> method is invoked.
+ * <p>
+ * It is valid to add an empty parameter value list to a batch list.
+ * <p>
+ * For example:
+ * <p>
+ * <code>PreparedStatement stmt = conn.prepareStatement(sql);<br \>
+ * stmt.addBatch();<br \>
+ * stmt.addBatch();<br \>
+ * stmt.executeBatch();</code>
+ *
+ * @throws Exception
+ */
+ @Test public void testAddBatchNoParameterValues() throws Exception {
+ PreparedStatementImpl statement = getMMPreparedStatement("delete from table where
col=?"); //$NON-NLS-1$
+
+ // This will hold our expected values list
+ ArrayList<ArrayList<Object>> expectedParameterValues = new
ArrayList<ArrayList<Object>>(1);
+
+ // First batch has an empty parameter value list
+ expectedParameterValues.add( new ArrayList<Object>(Collections.emptyList()) );
+
+ // No values have been set so we are adding a batch with an empty
+ // parameter value list
+ statement.addBatch();
+
+ // Second batch contains a parameter value list
+ expectedParameterValues.add( new ArrayList<Object>( Arrays.asList( new Object[] {
new Integer(1) } ) ) );
+
+ // We now are adding a batch that does have parameter values
+ statement.setInt(1, new Integer(1));
+ statement.addBatch();
+
+ // Check to see if our statement contains our expected parameter value list
+ assertEquals("MMPreparedStatement.ParameterValuesList does not match",
expectedParameterValues, statement.getParameterValuesList()); //$NON-NLS-1$
+ }
+
+ /**
+ * A helper method to get an <code>MMPreparedStatement</code> that can be
+ * used for simple test cases.
+ * <p>
+ * The returned value is an instance of
<code>TestableMMPreparedStatement</code>
+ * <p>
+ * This method invokes <code>getMMPreparedStatement(final MMConnection conn,
+ * final String sql)</code> with a fake connection object constructed by
+ * <code>Mockito</code>.
+ *
+ * @param sql the query for the prepared statement
+ * @return an instance of TestableMMPreparedStatement
+ * @throws SQLException
+ */
+ protected PreparedStatementImpl getMMPreparedStatement(final String sql) throws
SQLException {
+ ConnectionImpl conn = Mockito.mock(ConnectionImpl.class);
+ ServerConnection serverConn = Mockito.mock(ServerConnection.class);
+ LogonResult logonResult = Mockito.mock(LogonResult.class);
+
+ Mockito.stub(conn.getServerConnection()).toReturn(serverConn);
+ Mockito.stub(serverConn.getLogonResult()).toReturn(logonResult);
+ Mockito.stub(logonResult.getTimeZone()).toReturn(TimeZone.getDefault());
+
+ return getMMPreparedStatement(conn, sql);
+ }
+
+ /**
+ * A helper method to get an <code>MMPreparedStatement</code> that can be
+ * used for simple test cases.
+ * <p>
+ * The returned value is an instance of
<code>TestableMMPreparedStatement</code>
+ * <p>
+ * <code>conn</code> should be a valid instance of
<code>MMConnection</code>
+ * or this method will fail.
+ *
+ * @param conn an instance of <code>MMConnection</code>
+ * @param sql the query for the prepared statement
+ * @return an instance of TestableMMPreparedStatement
+ * @throws SQLException
+ */
+ protected PreparedStatementImpl getMMPreparedStatement(final ConnectionImpl conn, final
String sql) throws SQLException {
+ TestableMMPreparedStatement statement = new TestableMMPreparedStatement(conn, sql,
ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
+
+ // Make sure everything is empty on start
+ assertTrue("MMPreparedStatement.ParameterValuesList should be empty",
statement.getParameterValuesList().size() == 0); //$NON-NLS-1$
+ assertTrue("MMPreparedStatement.ParameterValues should be empty",
statement.getParameterValues().size() == 0); //$NON-NLS-1$
+
+ return statement;
+ }
+
+ /**
+ * Represents an extension to <code>MMPreparedStatement</code> that
+ * gives access to the <code>RequestMessage</code> that is passed
+ * around inside <code>MMPreparedStatement</code>.
+ * <p>
+ * This extension simply adds a field named <code>requestMessage</code>
+ * which is <code>public</code>. This field gets set when the
<code>protected</code>
+ * method <code>createRequestMessage()</code> is called.
+ * <p>
+ * This extension also overrides <code>RequestMessage
createRequestMessage(String[] commands,
+ * boolean isBatchedCommand, Boolean requiresResultSet)</code> so that
+ * reference to the created <code>RequestMessage</code> can be retained in
+ * the field <code>requestMessage</code>.
+ */
+ class TestableMMPreparedStatement extends PreparedStatementImpl {
+ /**
+ * Contains a reference to the <code>RequestMessage</code> created by
+ * a call to <code>createRequestMessage(String[] commands,
+ * boolean isBatchedCommand, Boolean requiresResultSet)</code>. This
+ * will allow easy access to the prepared statement's request message
+ * generated by a call to one of the statement's execute methods.
+ */
+ public RequestMessage requestMessage;
+ @Override
+ protected RequestMessage createRequestMessage(String[] commands,
+ boolean isBatchedCommand, ResultsMode resultsMode) {
+ this.requestMessage = super
+ .createRequestMessage(commands, isBatchedCommand, resultsMode);
+ return this.requestMessage;
+ }
+
+ public TestableMMPreparedStatement(ConnectionImpl connection,
+ String sql, int resultSetType, int resultSetConcurrency)
+ throws SQLException {
+ super(connection, sql, resultSetType, resultSetConcurrency);
+ }
+
+ }
+
+}
Property changes on:
trunk/client/src/test/java/org/teiid/jdbc/TestMMPreparedStatement.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Copied: trunk/client/src/test/java/org/teiid/jdbc/TestMMResultSet.java (from rev 1983,
trunk/client-jdbc/src/test/java/org/teiid/jdbc/TestMMResultSet.java)
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestMMResultSet.java
(rev 0)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestMMResultSet.java 2010-03-22 21:01:44 UTC
(rev 1986)
@@ -0,0 +1,753 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.List;
+import java.util.TimeZone;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
+
+import org.junit.Test;
+import org.teiid.client.DQP;
+import org.teiid.client.ResultsMessage;
+
+import com.metamatrix.api.exception.MetaMatrixProcessingException;
+
+public class TestMMResultSet {
+
+ /** test next() without walking through */
+ @Test public void testNext1() throws SQLException {
+ ResultSet cs = helpExecuteQuery();
+ assertEquals(" Actual doesn't match with expected. ", new
Integer(0), new Integer(cs.getRow())); //$NON-NLS-1$
+ cs.close();
+ }
+
+ /** test next() with walking through all the rows and compare records */
+ @Test public void testNext2() throws SQLException {
+ List[] expected = TestAllResultsImpl.exampleResults1(1000);
+ ResultSetImpl cs = helpExecuteQuery();
+
+ int i=0;
+ while(cs.next()) {
+ assertEquals(" Actual doesn't match with expected. ",
expected[i], cs.getCurrentRecord()); //$NON-NLS-1$
+ i++;
+ }
+
+ cs.close();
+ }
+
+ /** test with LargeA -- only work with real model rather than fake metadata*/
+
+ // Note for all the following: processor batch size is 100,
+ // so some of these tests check what happens when the client
+ // fetch size is above, the same, or below it
+ public static final int PROC_BATCH_SIZE = 100;
+
+ /** Test stability when next() is called beyond the rowcount. */
+ @Test public void testNextBeyondEnd_fetchEqualsCount() throws Exception {
+ helpTestNextBeyondResultSet(1000, 1000);
+ }
+
+ /** Test stability when next() is called beyond the rowcount. */
+ @Test public void testNextBeyondEnd_fetchLessThanCount() throws Exception {
+ helpTestNextBeyondResultSet(100, 1000);
+ }
+
+ /** Test stability when next() is called beyond the rowcount with one more row. */
+ @Test public void testNextBeyondEnd_fetchLessThanCount1() throws Exception {
+ helpTestNextBeyondResultSet(100, 101);
+ }
+
+ /** Test stability when next() is called beyond the rowcount. */
+ @Test public void testNextBeyondEnd_fetchLessThanCountNonMultiple() throws Exception
{
+ helpTestNextBeyondResultSet(120, 1000);
+ }
+
+ /** Test stability when next() is called beyond the rowcount. */
+ @Test public void testNextBeyondEnd_fetchGreaterThanCount() throws Exception {
+ helpTestNextBeyondResultSet(300, PROC_BATCH_SIZE);
+ }
+
+ /** Test stability when next() is called beyond the rowcount. */
+ @Test public void testNextBeyondEnd_fetchGreaterThanCountNonMultiple() throws
Exception {
+ helpTestNextBeyondResultSet(310, PROC_BATCH_SIZE-50);
+ }
+
+ /** Test stability when next() is called beyond the rowcount. */
+ @Test public void testNextBeyondEnd_fetchGreaterThanCountNonMultiple2() throws
Exception {
+ helpTestNextBeyondResultSet(300, PROC_BATCH_SIZE+10);
+ }
+
+ /** Test that the returned results walks through all results if
+ * fetchSize < rows < proc batch size.
+ * Test for defect 11356
+ */
+ @Test public void
testNextBeyondEnd_fetchLessThanCount_ResultsBetweenFetchAndProcBatch() throws Exception {
+ helpTestNextBeyondResultSet(30, PROC_BATCH_SIZE-25);
+ }
+
+ public void helpTestNextBeyondResultSet(int fetchSize, int numRows) throws Exception
{
+ ResultSet cs = helpExecuteQuery(fetchSize, numRows,
ResultSet.TYPE_SCROLL_INSENSITIVE);
+ try {
+ Object lastRowValue = null;
+ for (int rowNum = 1; rowNum <= numRows; rowNum++) {
+ assertEquals("Should return true before end cs.next()", true,
cs.next()); //$NON-NLS-1$
+ }
+
+ lastRowValue = cs.getObject(1);
+
+ // Should just return false and leave cursor where it is
+ for(int i=numRows+1; i<numRows+4; i++) {
+ assertEquals("Should return false when going past the end: " +
i, false, cs.next()); //$NON-NLS-1$
+ assertEquals("Is after last should be true: " + i, true,
cs.isAfterLast()); //$NON-NLS-1$
+ }
+
+ // Should still be just after last row
+ cs.previous();
+ assertEquals("Is last should be true", true, cs.isLast());
//$NON-NLS-1$
+ assertEquals("Not on last row", lastRowValue, cs.getObject(1));
//$NON-NLS-1$
+
+ } finally {
+ cs.close();
+ }
+ }
+
+ /** test both next() and previous() -- when result set scroll in bidirection */
+ @Test public void testBidirection() throws SQLException {
+ ResultSetImpl cs = helpExecuteQuery();
+ assertNotNull(cs);
+ cs.absolute(290);
+ assertEquals(" Actual value doesn't match with expected one.", new
Integer(290), cs.getCurrentRecord().get(0)); //$NON-NLS-1$
+ cs.next();
+ assertEquals(" Actual value doesn't match with expected one.", new
Integer(291), cs.getCurrentRecord().get(0)); //$NON-NLS-1$
+ cs.next();
+ assertEquals(" Actual value doesn't match with expected one.", new
Integer(292), cs.getCurrentRecord().get(0)); //$NON-NLS-1$
+ cs.previous();
+ assertEquals(" Actual value doesn't match with expected one.", new
Integer(291), cs.getCurrentRecord().get(0)); //$NON-NLS-1$
+ cs.next();
+ assertEquals(" Actual value doesn't match with expected one.", new
Integer(292), cs.getCurrentRecord().get(0)); //$NON-NLS-1$
+ cs.close();
+ }
+
+ /** test hasNext() without walking through any row */
+ @Test public void testHasNext1() throws SQLException {
+ ResultSetImpl cs = helpExecuteQuery();
+ assertEquals(" hasNext() doesn't match expected value. ", true,
cs.hasNext()); //$NON-NLS-1$
+ cs.close();
+ }
+
+ /** test hasNext() with blocking for the Next batch -- triggering point */
+ @Test public void testHasNext2() throws SQLException {
+ ResultSetImpl cs = helpExecuteQuery();
+ cs.absolute(100);
+ assertEquals(" hasNext() doesn't match expected value. ", true,
cs.hasNext()); //$NON-NLS-1$
+ cs.close();
+ }
+
+ /** test hasNext() with nextBatch!=null -- short response */
+ @Test public void testHasNext3() throws SQLException {
+ ResultSetImpl cs = helpExecuteQuery();
+ int i = 0;
+ while (cs.next()) {
+ if (i == 289) {
+ break;
+ }
+ i++;
+ }
+ assertEquals(" hasNext() doesn't match expected value. ", true,
cs.hasNext()); //$NON-NLS-1$
+ cs.close();
+ }
+
+ /** at the end of all batches */
+ @Test public void testHasNext4() throws SQLException {
+ ResultSetImpl cs = helpExecuteQuery();
+ cs.absolute(1000);
+ assertTrue(!cs.hasNext());
+ cs.close();
+ }
+
+ /** walk all way through from the end back to first row */
+ @Test public void testPrevious1() throws SQLException {
+ ResultSetImpl cs = helpExecuteQuery();
+ List[] expected = TestAllResultsImpl.exampleResults1(1000);
+ while(cs.next()) {
+ //System.out.println(" rs.next == " + cs.getCurrentRecord());
+ }
+ // cursor is after the last row. getRow() should return 0 when not on a valid
row
+ assertEquals(" current row doesn't match expected value. ", 0,
cs.getRow()); //$NON-NLS-1$
+
+ int i= 1000;
+ while (cs.previous()) {
+ //System.out.println(" rs.previous == " + cs.getCurrentRecord());
+ assertEquals(" Actual doesn't match with expected. ",
expected[i-1], cs.getCurrentRecord()); //$NON-NLS-1$
+ i--;
+ }
+ assertEquals(" current row doesn't match expected value. ", 0,
cs.getRow()); //$NON-NLS-1$
+ cs.close();
+ }
+
+ /** test the previous in the middle of a batch */
+ @Test public void testPrevious2() throws SQLException {
+ ResultSetImpl cs = helpExecuteQuery();
+ cs.absolute(290);
+
+ // cursor is at the row of 289 now
+ assertTrue(cs.previous());
+ assertEquals(" current row doesn't match expected value. ", 289,
cs.getRow()); //$NON-NLS-1$
+ cs.close();
+ }
+
+ /** walk all way through from the end back to first row */
+ @Test public void testPrevious3() throws Exception {
+ //large batch size
+ ResultSetImpl cs = helpExecuteQuery(600, 10000,
ResultSet.TYPE_SCROLL_INSENSITIVE);
+ List[] expected = TestAllResultsImpl.exampleResults1(10000);
+ while(cs.next()) {
+ }
+ // cursor is after the last row. getRow() should return 0 when not on a valid
row
+ assertEquals(" current row doesn't match expected value. ", 0,
cs.getRow()); //$NON-NLS-1$
+
+ int i= 10000;
+ while (cs.previous()) {
+ //System.out.println(" rs.previous == " + cs.getCurrentRecord());
+ assertEquals(" Actual doesn't match with expected. ",
expected[i-1], cs.getCurrentRecord()); //$NON-NLS-1$
+ i--;
+ }
+ assertEquals(" current row doesn't match expected value. ", 0,
cs.getRow()); //$NON-NLS-1$
+ cs.close();
+ }
+
+ /** walk all way through from the end back to first row */
+ @Test public void testPrevious4() throws Exception {
+ //small batch size
+ ResultSetImpl cs = helpExecuteQuery(50, 1000,
ResultSet.TYPE_SCROLL_INSENSITIVE);
+ List[] expected = TestAllResultsImpl.exampleResults1(1000);
+ while(cs.next()) {
+ //System.out.println(" rs.next == " + cs.getCurrentRecord());
+ }
+ // cursor is after the last row. getRow() should return 0 when not on a valid
row
+ assertEquals(" current row doesn't match expected value. ", 0,
cs.getRow()); //$NON-NLS-1$
+
+ int i= 1000;
+ while (cs.previous()) {
+ //System.out.println(" rs.previous == " + cs.getCurrentRecord());
+ assertEquals(" Actual doesn't match with expected. ",
expected[i-1], cs.getCurrentRecord()); //$NON-NLS-1$
+ i--;
+ }
+ assertEquals(" current row doesn't match expected value. ", 0,
cs.getRow()); //$NON-NLS-1$
+ cs.close();
+ }
+
+ /** test rare case that cursor change direction */
+ @Test public void testChangeDirection() throws SQLException {
+ ResultSetImpl cs = helpExecuteQuery();
+ cs.absolute(291);
+ cs.previous();
+
+ assertEquals(" current row doesn't match expected value. ", 290,
cs.getRow()); //$NON-NLS-1$
+ cs.close();
+ }
+
+ @Test public void testIsFirst() throws SQLException {
+ ResultSetImpl cs = helpExecuteQuery();
+ cs.next();
+ assertTrue(cs.isFirst());
+ cs.close();
+ }
+
+ /** test cursor is in the middle of all batches */
+ @Test public void testIsLast1() throws SQLException {
+ ResultSetImpl cs = helpExecuteQuery();
+ cs.next();
+ assertTrue(!cs.isLast());
+ cs.close();
+ }
+
+ /** test cursor at the triggering point -- blocking case*/
+ @Test public void testIsLast2() throws SQLException {
+ ResultSetImpl cs = helpExecuteQuery();
+
+ int i = 0;
+ while (cs.next()) {
+ if (i == 99) {
+ break;
+ }
+ i++;
+ }
+
+ assertTrue(!cs.isLast());
+ cs.close();
+ }
+
+ /** test cursor at the last row of all batches */
+ @Test public void testIsLast3() throws SQLException {
+ ResultSetImpl cs = helpExecuteQuery();
+ cs.absolute(1000);
+ assertTrue(cs.isLast());
+ cs.close();
+ }
+
+ @Test public void testIsBeforeFirst() throws SQLException {
+ ResultSetImpl cs = helpExecuteQuery();
+ assertTrue(cs.isBeforeFirst());
+ cs.close();
+ }
+
+ @Test public void testBeforeFirst() throws SQLException {
+ ResultSetImpl cs = helpExecuteQuery();
+
+ // move to row 1
+ cs.next();
+ assertEquals(" Current row number doesn't match with expected
one.", 1, cs.getRow()); //$NON-NLS-1$
+
+ // move back to before first row
+ cs.beforeFirst();
+ assertTrue(cs.isBeforeFirst());
+ cs.close();
+ }
+
+ @Test public void testFirst() throws SQLException {
+ ResultSetImpl cs = helpExecuteQuery();
+
+ // move to row #2
+ cs.next();
+ cs.next();
+ assertEquals(" Current row number doesn't match with expected
one.", 2, cs.getRow()); //$NON-NLS-1$
+
+ // move back to the 1st row
+ cs.first();
+ assertEquals(" Current row number doesn't match with expected
one.", 1, cs.getRow()); //$NON-NLS-1$
+ cs.close();
+ }
+
+ @Test public void testAfterLast() throws SQLException {
+ ResultSetImpl cs = helpExecuteQuery();
+ cs.afterLast();
+ assertTrue(cs.isAfterLast());
+ cs.close();
+ }
+
+ /** right after the last row */
+ @Test public void testIsAfterLast1() throws SQLException {
+ ResultSetImpl cs = helpExecuteQuery();
+ cs.absolute(1000);
+ cs.next();
+ assertTrue(cs.isAfterLast());
+ cs.close();
+ }
+
+ /** right before the first */
+ @Test public void testIsAfterLast2() throws Exception {
+ ResultSetImpl cs = helpExecuteQuery();
+ assertTrue(!cs.isAfterLast());
+ cs.close();
+ }
+
+ /** absolute with cursor movement backward in the same batch -- absolute(positive)
*/
+ @Test public void testAbsolute1() throws SQLException {
+ ResultSetImpl cs = helpExecuteQuery();
+
+ // move to row #2
+ cs.next();
+ cs.next();
+ assertEquals(" Current row number doesn't match with expected
one.", 2, cs.getRow()); //$NON-NLS-1$
+
+ // move back to the 1st row
+ cs.absolute(1);
+ assertEquals(" Current row number doesn't match with expected
one.", 1, cs.getRow()); //$NON-NLS-1$
+ cs.close();
+ }
+
+ /** absolute with cursor movement forward in the same batch -- absolute(positive) */
+ @Test public void testAbsolute2() throws SQLException {
+ ResultSetImpl cs = helpExecuteQuery();
+
+ // move to row #2
+ cs.next();
+ cs.next();
+ assertEquals(" Current row number doesn't match with expected
one.", 2, cs.getRow()); //$NON-NLS-1$
+
+ // move back to the 1st row
+ cs.absolute(3);
+ assertEquals(" Current row number doesn't match with expected
one.", 3, cs.getRow()); //$NON-NLS-1$
+ cs.close();
+ }
+
+ /** absolute with cursor movement forward -- absolute(positive) -- blocking */
+ @Test public void testAbsolute3() throws SQLException {
+ ResultSetImpl cs = helpExecuteQuery();
+
+ // move to row #2
+ cs.next();
+ cs.next();
+ assertEquals(" Current row number doesn't match with expected
one.", 2, cs.getRow()); //$NON-NLS-1$
+
+ // move to row #100 -- blocking
+ cs.absolute(100);
+ assertEquals(" Current row number doesn't match with expected
one.", 100, cs.getRow()); //$NON-NLS-1$
+ cs.close();
+ }
+
+ /** absolute with cursor movement forward -- absolute(positive) -- triggering point
*/
+ @Test public void testAbsolute4() throws SQLException {
+ ResultSetImpl cs = helpExecuteQuery();
+
+ // move to row #2
+ cs.next();
+ cs.next();
+ assertEquals(" Current row number doesn't match with expected
one.", 2, cs.getRow()); //$NON-NLS-1$
+
+ // move to row #200 -- new batch
+ cs.absolute(200);
+ assertEquals(" Current row number doesn't match with expected
one.", 200, cs.getRow()); //$NON-NLS-1$
+ cs.close();
+ }
+
+ /** absolute with cursor movement back in the same batch -- absolute(negative) */
+ @Test public void testAbsolute5() throws SQLException {
+ ResultSetImpl cs = helpExecuteQuery();
+
+ // move to row #2
+ cs.next();
+ cs.next();
+ assertEquals(" Current row number doesn't match with expected
one.", 2, cs.getRow()); //$NON-NLS-1$
+
+ // move back to the 1st row
+ cs.absolute(-1);
+ assertEquals(" Current row number doesn't match with expected
one.", 1000, cs.getRow()); //$NON-NLS-1$
+ cs.close();
+ }
+
+ /** absolute after last row */
+ @Test public void testAbsolute6() throws SQLException {
+ ResultSetImpl cs = helpExecuteQuery();
+ cs.absolute(1005);
+ // Cursor should be after last row. getRow() should return 0 because
+ // cursor is not on a valid row
+ assertEquals(" Current row number doesn't match with expected
one.", 0, cs.getRow()); //$NON-NLS-1$
+ cs.close();
+ }
+
+ /** relative(positive) -- forward to another batch */
+ @Test public void testRelative1() throws SQLException {
+ ResultSetImpl cs = helpExecuteQuery();
+
+ // move to the row #3
+ cs.absolute(3);
+ assertEquals(" Current row number doesn't match with expected
one.", 3, cs.getRow()); //$NON-NLS-1$
+
+ // move to the row #140
+ cs.relative(137);
+ assertEquals(" Current row number doesn't match with expected
one.", 140, cs.getRow()); //$NON-NLS-1$
+ cs.close();
+ }
+
+ /** relative(negative) -- backward to another batch */
+ @Test public void testRelative2() throws SQLException {
+ ResultSetImpl cs = helpExecuteQuery();
+
+ // move to the row #137
+ cs.absolute(137);
+ assertEquals(" Current row number doesn't match with expected
one.", 137, cs.getRow()); //$NON-NLS-1$
+
+ // move to the row #4
+ cs.relative(-133);
+ assertEquals(" Current row number doesn't match with expected
one.", 4, cs.getRow()); //$NON-NLS-1$
+ cs.close();
+ }
+
+ /** relative(negative) -- backward to triggering point or blocking batch */
+ @Test public void testRelative3() throws SQLException {
+ ResultSetImpl cs = helpExecuteQuery();
+
+ // move to the row #137
+ cs.absolute(137);
+ assertEquals(" Current row number doesn't match with expected
one.", 137, cs.getRow()); //$NON-NLS-1$
+
+ // move to the row #100
+ cs.relative(-37);
+ assertEquals(" Current row number doesn't match with expected
one.", 100, cs.getRow()); //$NON-NLS-1$
+ cs.close();
+ }
+
+ /** relative(negative) -- backward to triggering point or blocking batch */
+ @Test public void testRelative4() throws SQLException {
+ ResultSetImpl cs = helpExecuteQuery();
+
+ // move to the row #237 in the third batch, so that the fourth batch has been
requested when we switch direction
+ cs.absolute(237);
+ assertEquals(" Current row number doesn't match with expected
one.", 237, cs.getRow()); //$NON-NLS-1$
+
+ // move to the row #37
+ cs.relative(-200);
+ assertEquals(" Current row number doesn't match with expected
one.", 37, cs.getRow()); //$NON-NLS-1$
+ cs.close();
+ }
+
+ /** in the first fetched batch */
+ @Test public void testGetRow1() throws SQLException {
+ ResultSet cs = helpExecuteQuery();
+
+ int i = 0;
+ while (cs.next()) {
+ if (i == 102) {
+ break;
+ }
+ i++;
+ }
+
+ assertEquals(" Current row number doesn't match with expected
one.", i+1, cs.getRow()); //$NON-NLS-1$
+ cs.close();
+ }
+
+ /** in the first batch */
+ @Test public void testGetRow2() throws SQLException {
+ ResultSet cs = helpExecuteQuery();
+
+ cs.next();
+ assertEquals(" Current row number doesn't match with expected
one.", 1, cs.getRow()); //$NON-NLS-1$
+ cs.close();
+ }
+
+ /** in the triggering point -- blocking */
+ @Test public void testGetRow3() throws SQLException {
+ ResultSet cs = helpExecuteQuery();
+ int i = 0;
+ while (cs.next()) {
+ if (i == 99) {
+ break;
+ }
+ i++;
+ }
+ assertEquals(" Current row number doesn't match with expected
one.", 100, cs.getRow()); //$NON-NLS-1$
+ cs.close();
+ }
+
+ @Test public void testGetCurrentRecord() throws SQLException {
+ ResultSet cs = helpExecuteQuery();
+ cs.absolute(103);
+ assertEquals(" Current record doesn't match with expected one.",
new Integer(103), ((ResultSetImpl)cs).getCurrentRecord().get(0));
//$NON-NLS-1$
+ cs.close();
+ }
+
+ /** test close() without walking through any of the record*/
+ @Test public void testClose() throws SQLException {
+ ResultSetImpl cs = helpExecuteQuery();
+ assertEquals(" Actual doesn't match with expected. ", new
Integer(0), new Integer(cs.getRow())); //$NON-NLS-1$
+ cs.close();
+ }
+
+ /** test basic results-related metadata */
+ @Test public void testGetMetaData() throws SQLException {
+ ResultSetImpl cs = helpExecuteQuery();
+
+ // check result set metadata
+ // expected column info.
+ List columnName = getBQTRSMetaData1a();
+ List columnType = getBQTRSMetaData1b();
+ List columnTypeName = getBQTRSMetaData1c();
+
+ ResultSetMetaData rm = cs.getMetaData();
+ assertNotNull(rm);
+
+ for (int j = 1; j <= rm.getColumnCount(); j++) {
+ assertEquals(" Actual doesn't match with expected. ",
columnName.get(j-1), rm.getColumnName(j)); //$NON-NLS-1$
+ assertEquals(" Actual doesn't match with expected. ",
columnType.get(j-1), new Integer(rm.getColumnType(j))); //$NON-NLS-1$
+ assertEquals(" Actual doesn't match with expected. ",
columnTypeName.get(j-1), rm.getColumnTypeName(j)); //$NON-NLS-1$
+ }
+
+ cs.close();
+ }
+
+ @Test public void testFindColumn() throws SQLException {
+ ResultSetImpl cs = helpExecuteQuery();
+ ResultSetMetaData rm = cs.getMetaData();
+ assertNotNull(rm);
+ //assertEquals(" Actual columnName doesn't match with expected. ",
1, cs.findColumn("BQT1.MediumA.IntKey"));
+ assertEquals(" Actual columnName doesn't match with expected. ", 1,
cs.findColumn("IntKey")); //$NON-NLS-1$ //$NON-NLS-2$
+ cs.close();
+ }
+
+ @Test public void testFindNonExistentColumn() throws SQLException {
+ ResultSet rs = helpExecuteQuery();
+ rs.next();
+ try {
+ rs.findColumn("BOGUS"); //$NON-NLS-1$
+ } catch(SQLException e) {
+ }
+
+ try {
+ rs.getObject("BOGUS"); //$NON-NLS-1$
+ } catch(SQLException e) {
+ }
+ rs.close();
+ }
+
+ @Test public void testGetStatement() throws SQLException {
+ ResultSetImpl cs = helpExecuteQuery();
+ assertNotNull(cs.getStatement());
+ cs.close();
+ }
+
+ @Test public void testGetPlanDescription() throws SQLException {
+ ResultSetImpl cs = helpExecuteQuery();
+ assertNotNull(cs);
+
+ assertNull((cs.getStatement()).getPlanDescription());
+ cs.close();
+ }
+
+ /** getObject(String) */
+ @Test public void testGetObject2() throws SQLException {
+ ResultSet cs = helpExecuteQuery();
+
+ // move to the 1st row
+ cs.next();
+ assertEquals(" Actual value doesn't match with expected. ", new
Integer(1), cs.getObject("IntKey")); //$NON-NLS-1$ //$NON-NLS-2$
+ cs.close();
+ }
+
+ @Test public void testGetWarnings() throws SQLException {
+ ResultSet cs = helpExecuteQuery();
+ assertNull(cs.getWarnings());
+ cs.close();
+ }
+
+ @Test public void testGetCursorName() throws SQLException {
+ ResultSetImpl cs = helpExecuteQuery();
+ assertNull(cs.getCursorName());
+ cs.close();
+ }
+
+ @Test public void testAllGetters() throws SQLException {
+ ResultSetImpl cs = helpExecuteQuery();
+ cs.next();
+ assertEquals(" Actual value of getInt() doesn't match with expected one.
", 1, cs.getInt("IntKey")); //$NON-NLS-1$ //$NON-NLS-2$
+ assertEquals(" Actual value of getString() doesn't match with expected
one. ", "1", cs.getString("IntKey")); //$NON-NLS-1$ //$NON-NLS-2$
//$NON-NLS-3$
+
+ // Add these back when the MediumA has all those columns
+ assertEquals(" Actual value of getFloat() doesn't match with expected
one. ", new Float(1), new Float(cs.getFloat("IntKey"))); //$NON-NLS-1$
//$NON-NLS-2$
+ assertEquals(" Actual value of getLong() doesn't match with expected
one. ", 1, cs.getLong("IntKey")); //$NON-NLS-1$ //$NON-NLS-2$
+ assertEquals(" Actual value of getDouble() doesn't match with expected
one. ", new Double(1), new Double(cs.getDouble("IntKey"))); //$NON-NLS-1$
//$NON-NLS-2$
+ assertEquals(" Actual value of getByte() doesn't match with expected
one. ", (byte)1, cs.getByte("IntKey")); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /** test wasNull() for ResultSet, this result actually is not a cursor result, but
AllResults here. */
+ @Test public void testWasNull() throws SQLException {
+ ResultSet cs = helpExecuteQuery();
+ cs.next();
+ assertNotNull(cs.getObject("IntKey")); //$NON-NLS-1$
+ assertFalse(cs.wasNull());
+ }
+
+ @Test public void testForwardOnly() throws Exception {
+ ResultSetImpl cs = helpExecuteQuery(400, 1000, ResultSet.TYPE_FORWARD_ONLY);
+
+ while (cs.next()) {
+ cs.getObject(1);
+ }
+
+ assertTrue(cs.isAfterLast());
+ cs.close();
+ }
+
+ @Test public void testOutputParameter() throws Exception {
+ StatementImpl statement = createMockStatement(ResultSet.TYPE_FORWARD_ONLY);
+ ResultsMessage resultsMsg = new ResultsMessage();
+ resultsMsg.setResults(new List<?>[] {Arrays.asList(1, null, null),
Arrays.asList(null, 2, 3)});
+ resultsMsg.setLastRow(2);
+ resultsMsg.setFirstRow(1);
+ resultsMsg.setFinalRow(2);
+ resultsMsg.setColumnNames(new String[] {"x", "out1",
"out2"}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ resultsMsg.setDataTypes(new String[] {"integer", "integer",
"integer"}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ ResultSetImpl cs = new ResultSetImpl(resultsMsg, statement, null, 2);
+
+ int count = 0;
+ while (cs.next()) {
+ cs.getObject(1);
+ count++;
+ }
+ assertEquals(1, count);
+ assertTrue(cs.isAfterLast());
+ assertEquals(2, cs.getOutputParamValue(2));
+ assertEquals(3, cs.getOutputParamValue(3));
+ }
+
+ /////////////////////// Helper Method ///////////////////
+
+ private ResultSetImpl helpExecuteQuery() {
+ try {
+ return helpExecuteQuery(400, 1000, ResultSet.TYPE_SCROLL_INSENSITIVE);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private ResultSetImpl helpExecuteQuery(int fetchSize, int totalResults, int
cursorType) throws SQLException, MetaMatrixProcessingException, InterruptedException,
ExecutionException, TimeoutException {
+ StatementImpl statement = createMockStatement(cursorType);
+ return TestAllResultsImpl.helpTestBatching(statement, fetchSize, Math.min(fetchSize,
totalResults), totalResults);
+ }
+
+ static StatementImpl createMockStatement(int cursorType) throws SQLException {
+ StatementImpl statement = mock(StatementImpl.class);
+ stub(statement.getDQP()).toReturn(mock(DQP.class));
+ stub(statement.getResultSetType()).toReturn(cursorType);
+ TimeZone tz = TimeZone.getTimeZone("GMT-06:00"); //$NON-NLS-1$
+ TimeZone serverTz = TimeZone.getTimeZone("GMT-05:00"); //$NON-NLS-1$
+ stub(statement.getDefaultCalendar()).toReturn(Calendar.getInstance(tz));
+ stub(statement.getServerTimeZone()).toReturn(serverTz);
+ return statement;
+ }
+
+ ////////////////////////Expected Results////////////////
+ /** column name */
+ private List getBQTRSMetaData1a() {
+ List results = new ArrayList();
+ results.add("IntKey"); //$NON-NLS-1$
+ return results;
+ }
+
+ /** column type */
+ private List getBQTRSMetaData1b() {
+ List results = new ArrayList();
+ results.add(new Integer(Types.INTEGER));
+ return results;
+ }
+
+ /** column type name*/
+ private List getBQTRSMetaData1c() {
+ List results = new ArrayList();
+ results.add("integer"); //$NON-NLS-1$
+ return results;
+ }
+}
Copied: trunk/client/src/test/java/org/teiid/jdbc/TestMMSQLException.java (from rev 1983,
trunk/client-jdbc/src/test/java/org/teiid/jdbc/TestMMSQLException.java)
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestMMSQLException.java
(rev 0)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestMMSQLException.java 2010-03-22 21:01:44
UTC (rev 1986)
@@ -0,0 +1,235 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.net.MalformedURLException;
+import java.net.NoRouteToHostException;
+import java.net.SocketException;
+import java.net.SocketTimeoutException;
+import java.net.UnknownHostException;
+import java.sql.SQLException;
+
+import org.teiid.jdbc.TeiidSQLException;
+import org.teiid.net.CommunicationException;
+import org.teiid.net.ConnectionException;
+
+import junit.framework.TestCase;
+
+import com.metamatrix.api.exception.MetaMatrixException;
+import com.metamatrix.api.exception.MetaMatrixProcessingException;
+import com.metamatrix.api.exception.query.ProcedureErrorInstructionException;
+import com.metamatrix.core.MetaMatrixCoreException;
+import com.metamatrix.core.MetaMatrixRuntimeException;
+
+public class TestMMSQLException extends TestCase {
+
+ /*
+ * Test method for 'com.metamatrix.jdbc.MMSQLException.MMSQLException()'
+ */
+ public void testMMSQLException() {
+ TeiidSQLException e = new TeiidSQLException();
+ String sqlState = e.getSQLState();
+ Throwable cause = e.getCause();
+ int errorCode = e.getErrorCode();
+ Throwable nestedException = e.getCause();
+ SQLException nextException = e.getNextException();
+
+ assertTrue(
+ "Expected MMSQLException.getSQLState() to return <null> but got
\"" //$NON-NLS-1$
+ + sqlState + "\" instead.", sqlState == null); //$NON-NLS-1$
+ assertTrue(
+ "Expected MMSQLException.getCause() to return <null> but got ["
//$NON-NLS-1$
+ + (cause != null ? cause.getClass().getName()
+ : "<unknown>") + "] instead.", cause == null);
//$NON-NLS-1$ //$NON-NLS-2$
+ assertTrue(
+ "Expected MMSQLException.getErrorCode() to return [0] but got ["
//$NON-NLS-1$
+ + errorCode + "] instead.", errorCode == 0); //$NON-NLS-1$
+ assertTrue(
+ "Expected MMSQLException.getNestedException() to return <null> but got
[" //$NON-NLS-1$
+ + (nestedException != null ? nestedException.getClass()
+ .getName() : "<unknown>") + "] instead.", //$NON-NLS-1$
//$NON-NLS-2$
+ nestedException == null);
+ assertTrue(
+ "Expected MMSQLException.getNextException() to return <null> but got a
SQLException with message \"" //$NON-NLS-1$
+ + (nextException != null ? nextException.getMessage()
+ : "") + "\" instead.", nextException == null);
//$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /*
+ * Test method for 'com.metamatrix.jdbc.MMSQLException.create(Throwable)'
+ *
+ * Tests various simple exceptions to see if the expected SQLState is
+ * returend.
+ */
+ public void testCreateThrowable_01() {
+ testCreateThrowable(new CommunicationException(
+ "A test MM Communication Exception"), //$NON-NLS-1$
+ SQLStates.CONNECTION_EXCEPTION_STALE_CONNECTION);
+ testCreateThrowable(
+ new ConnectException("A test connection attempt exception"), //$NON-NLS-1$
+ SQLStates.CONNECTION_EXCEPTION_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION);
+ testCreateThrowable(
+ new ConnectionException("A test MM Connection Exception"), //$NON-NLS-1$
+ SQLStates.CONNECTION_EXCEPTION_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION);
+ testCreateThrowable(new IOException(
+ "A test Generic java.io.IOException"), //$NON-NLS-1$
+ SQLStates.CONNECTION_EXCEPTION_STALE_CONNECTION);
+ testCreateThrowable(
+ new MalformedURLException(
+ "A test java.net.MalformedURLException"), //$NON-NLS-1$
+ SQLStates.CONNECTION_EXCEPTION_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION);
+ testCreateThrowable(new MetaMatrixCoreException(
+ "A test Generic MM Core Exception"), SQLStates.DEFAULT); //$NON-NLS-1$
+ testCreateThrowable(new MetaMatrixException("A test MM Exception"),
//$NON-NLS-1$
+ SQLStates.DEFAULT);
+ testCreateThrowable(new MetaMatrixProcessingException(
+ "A test Generic MM Query Processing Exception"), //$NON-NLS-1$
+ SQLStates.USAGE_ERROR);
+ testCreateThrowable(new MetaMatrixRuntimeException(
+ "A test MM Runtime Exception"), SQLStates.DEFAULT); //$NON-NLS-1$
+ testCreateThrowable(new TeiidSQLException(
+ "A test Generic MM SQL Exception"), SQLStates.DEFAULT); //$NON-NLS-1$
+ testCreateThrowable(
+ new NoRouteToHostException(
+ "A test java.net.NoRouteToHostException"), //$NON-NLS-1$
+ SQLStates.CONNECTION_EXCEPTION_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION);
+ testCreateThrowable(new NullPointerException("A test NPE"), //$NON-NLS-1$
+ SQLStates.DEFAULT);
+ testCreateThrowable(new ProcedureErrorInstructionException(
+ "A test SQL Procedure Error exception"), //$NON-NLS-1$
+ SQLStates.VIRTUAL_PROCEDURE_ERROR);
+ testCreateThrowable(new SocketTimeoutException(
+ "A test socket timeout exception"), //$NON-NLS-1$
+ SQLStates.CONNECTION_EXCEPTION_STALE_CONNECTION);
+ testCreateThrowable(
+ new UnknownHostException("A test connection attempt exception"),
//$NON-NLS-1$
+ SQLStates.CONNECTION_EXCEPTION_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION);
+ }
+
+ /*
+ * Test method for 'com.metamatrix.jdbc.MMSQLException.create(Throwable)'
+ *
+ * Tests various nested exceptions to see if the expected SQLState is
+ * returend.
+ */
+ public void testCreateThrowable_02() {
+ testCreateThrowable(
+ new CommunicationException(new ConnectException(
+ "A test java.net.ConnectException"), //$NON-NLS-1$
+ "Test Communication Exception with a ConnectException in it"),
//$NON-NLS-1$
+ SQLStates.CONNECTION_EXCEPTION_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION);
+ testCreateThrowable(new CommunicationException(new SocketException(
+ "A test java.net.SocketException"), //$NON-NLS-1$
+ "Test Communication Exception with a SocketException in it"),
//$NON-NLS-1$
+ SQLStates.CONNECTION_EXCEPTION_STALE_CONNECTION);
+ testCreateThrowable(
+ new MetaMatrixException(new SocketTimeoutException(
+ "A test java.net.SocketTimeoutException"), //$NON-NLS-1$
+ "Test MetaMatrixException with a SocketTimeoutException in it"),
//$NON-NLS-1$
+ SQLStates.CONNECTION_EXCEPTION_STALE_CONNECTION);
+ }
+
+ public void testCreateThrowable3() {
+ TeiidSQLException e = testCreateThrowable(
+ new MetaMatrixCoreException(
+ new MetaMatrixRuntimeException(
+ new SocketTimeoutException(
+ "A test MM Invalid Session
Exception"), //$NON-NLS-1$
+ "Test MetaMatrixRuntimeException with a
InvalidSessionException in it"), //$NON-NLS-1$
+ "Test MM Core Exception with an MM Runtime
Exception in it and an InvalidSessionException nested within"), //$NON-NLS-1$
+ SQLStates.CONNECTION_EXCEPTION_STALE_CONNECTION);
+
+ //test to ensure that wrapping mmsqlexceptions works
+ TeiidSQLException e1 = TeiidSQLException.create(e, "new message");
//$NON-NLS-1$
+ assertEquals("new message", e1.getMessage()); //$NON-NLS-1$
+ testCreateThrowable(((TeiidSQLException)e1.getCause()).getCause(),
SQLStates.CONNECTION_EXCEPTION_STALE_CONNECTION);
+ }
+
+ /*
+ * Helper method to test SQLState and general MMSQLException validation
+ */
+ private TeiidSQLException testCreateThrowable(Throwable ecause, String esqlState) {
+ TeiidSQLException e = TeiidSQLException.create(ecause);
+ if (ecause.getClass() == TeiidSQLException.class) {
+ ecause = null;
+ }
+ String sqlState = e.getSQLState();
+ Throwable cause = e.getCause();
+ int errorCode = e.getErrorCode();
+ Throwable nestedException = e.getCause();
+ SQLException nextException = e.getNextException();
+
+ assertTrue("Expected MMSQLException.getSQLState() to return \""
//$NON-NLS-1$
+ + esqlState + "\" but got \"" + sqlState + "\"
instead.", //$NON-NLS-1$ //$NON-NLS-2$
+ sqlState.compareTo(esqlState) == 0);
+ assertTrue("Expected MMSQLException.getCause() to return [" //$NON-NLS-1$
+ + (ecause != null ? ecause.getClass().getName() : "<null>")
//$NON-NLS-1$
+ + "] but got [" //$NON-NLS-1$
+ + (cause != null ? cause.getClass().getName() : "<unknown>")
//$NON-NLS-1$
+ + "] instead.", cause == ecause); //$NON-NLS-1$
+ assertTrue(
+ "Expected MMSQLException.getErrorCode() to return [0] but got ["
//$NON-NLS-1$
+ + errorCode + "] instead.", errorCode == 0); //$NON-NLS-1$
+ assertTrue("Expected MMSQLException.getNestedException() to return ["
//$NON-NLS-1$
+ + (ecause != null ? ecause.getClass().getName() : "<null>")
//$NON-NLS-1$
+ + "] but got [" //$NON-NLS-1$
+ + (nestedException != null ? nestedException.getClass()
+ .getName() : "<unknown>") + "] instead.", //$NON-NLS-1$
//$NON-NLS-2$
+ nestedException == ecause);
+ assertTrue(
+ "Expected MMSQLException.getNextException() to return <null> but got a
SQLException with message \"" //$NON-NLS-1$
+ + (nextException != null ? nextException.getMessage()
+ : "") + "\" instead.", nextException == null);
//$NON-NLS-1$ //$NON-NLS-2$
+ return e;
+ }
+
+ public void testCreate() {
+ TeiidSQLException exception = TeiidSQLException.create(new Exception());
+
+ assertEquals(exception.getMessage(), Exception.class.getName());
+ assertNotNull(exception.getSQLState());
+ assertEquals(exception.getSQLState(), "38000"); //$NON-NLS-1$
+
+ assertEquals(exception, TeiidSQLException.create(exception));
+ }
+
+ public void testCreateFromSQLException() {
+ SQLException sqlexception = new SQLException("foo", "21");
//$NON-NLS-1$ //$NON-NLS-2$
+
+ SQLException nested = new SQLException("bar"); //$NON-NLS-1$
+
+ sqlexception.setNextException(nested);
+
+ String message = "top level message"; //$NON-NLS-1$
+
+ TeiidSQLException exception = TeiidSQLException.create(sqlexception, message);
+
+ assertEquals(exception.getMessage(), message);
+ assertEquals(exception.getSQLState(), sqlexception.getSQLState());
+ assertEquals(exception.getNextException().getMessage(),
sqlexception.getMessage());
+ assertEquals(exception.getNextException().getNextException().getMessage(),
nested.getMessage());
+ }
+
+}
Copied: trunk/client/src/test/java/org/teiid/jdbc/TestMMStatement.java (from rev 1983,
trunk/client-jdbc/src/test/java/org/teiid/jdbc/TestMMStatement.java)
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestMMStatement.java
(rev 0)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestMMStatement.java 2010-03-22 21:01:44 UTC
(rev 1986)
@@ -0,0 +1,75 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import static org.junit.Assert.*;
+
+import java.sql.ResultSet;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Properties;
+
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.teiid.client.DQP;
+import org.teiid.client.RequestMessage;
+import org.teiid.client.ResultsMessage;
+import org.teiid.client.util.ResultsFuture;
+import org.teiid.jdbc.ConnectionImpl;
+import org.teiid.jdbc.TeiidSQLException;
+import org.teiid.jdbc.StatementImpl;
+
+
+public class TestMMStatement {
+
+ @Test(expected=TeiidSQLException.class) public void testUpdateException() throws
Exception {
+ StatementImpl statement = new StatementImpl(Mockito.mock(ConnectionImpl.class),
ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
+ statement.executeQuery("delete from table"); //$NON-NLS-1$
+ }
+
+ @Test public void testBatchExecution() throws Exception {
+ ConnectionImpl conn = Mockito.mock(ConnectionImpl.class);
+ DQP dqp = Mockito.mock(DQP.class);
+ ResultsFuture<ResultsMessage> results = new
ResultsFuture<ResultsMessage>();
+ Mockito.stub(dqp.executeRequest(Mockito.anyLong(),
(RequestMessage)Mockito.anyObject())).toReturn(results);
+ ResultsMessage rm = new ResultsMessage();
+ rm.setResults(new List<?>[] {Arrays.asList(1), Arrays.asList(2)});
+ rm.setUpdateResult(true);
+ results.getResultsReceiver().receiveResults(rm);
+ Mockito.stub(conn.getDQP()).toReturn(dqp);
+ StatementImpl statement = new StatementImpl(conn, ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY);
+ statement.addBatch("delete from table"); //$NON-NLS-1$
+ statement.addBatch("delete from table1"); //$NON-NLS-1$
+ assertTrue(Arrays.equals(new int[] {1, 2}, statement.executeBatch()));
+ }
+
+ @Test public void testSetStatement() throws Exception {
+ ConnectionImpl conn = Mockito.mock(ConnectionImpl.class);
+ Properties p = new Properties();
+ Mockito.stub(conn.getConnectionProperties()).toReturn(p);
+ StatementImpl statement = new StatementImpl(conn, ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY);
+ assertFalse(statement.execute("set foo = bar")); //$NON-NLS-1$
+ assertEquals("bar", p.get("foo")); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+}
Property changes on: trunk/client/src/test/java/org/teiid/jdbc/TestMMStatement.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Copied: trunk/client/src/test/java/org/teiid/jdbc/TestMMXAConnection.java (from rev 1983,
trunk/client-jdbc/src/test/java/org/teiid/jdbc/TestMMXAConnection.java)
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestMMXAConnection.java
(rev 0)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestMMXAConnection.java 2010-03-22 21:01:44
UTC (rev 1986)
@@ -0,0 +1,72 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+import javax.transaction.xa.XAResource;
+
+import org.teiid.client.xa.XidImpl;
+import org.teiid.jdbc.ConnectionImpl;
+import org.teiid.jdbc.StatementImpl;
+import org.teiid.jdbc.XAConnectionImpl;
+
+import junit.framework.TestCase;
+
+
+
+public class TestMMXAConnection extends TestCase {
+
+ public void testConnectionClose() throws Exception {
+
+ final ConnectionImpl mmConn = TestMMConnection.getMMConnection();
+
+ XAConnectionImpl xaConn = new XAConnectionImpl(new XAConnectionImpl.ConnectionSource()
{
+ //## JDBC4.0-begin ##
+ @Override
+ //## JDBC4.0-end ##
+ public ConnectionImpl createConnection() throws SQLException {
+ return mmConn;
+ }
+ });
+
+ Connection conn = xaConn.getConnection();
+ StatementImpl stmt = (StatementImpl)conn.createStatement();
+ conn.setAutoCommit(false);
+ conn.close();
+
+ assertTrue(stmt.isClosed());
+ assertTrue(conn.getAutoCommit());
+
+ conn = xaConn.getConnection();
+ stmt = (StatementImpl)conn.createStatement();
+ XAResource resource = xaConn.getXAResource();
+ resource.start(new XidImpl(1, new byte[0], new byte[0]), XAResource.TMNOFLAGS);
+ conn.close();
+
+ assertTrue(stmt.isClosed());
+ assertTrue(conn.getAutoCommit());
+ }
+
+}
Property changes on: trunk/client/src/test/java/org/teiid/jdbc/TestMMXAConnection.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Copied: trunk/client/src/test/java/org/teiid/jdbc/TestSocketProfile.java (from rev 1983,
trunk/client-jdbc/src/test/java/org/teiid/jdbc/TestSocketProfile.java)
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestSocketProfile.java
(rev 0)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestSocketProfile.java 2010-03-22 21:01:44
UTC (rev 1986)
@@ -0,0 +1,121 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.sql.SQLException;
+import java.util.Properties;
+
+import org.junit.Test;
+import org.teiid.net.TeiidURL;
+
+
+public class TestSocketProfile {
+ public String localhost = "localhost"; //$NON-NLS-1$
+
+ /** Valid format of urls*/
+ @Test public void testAcceptsURL1() throws Exception {
+
assertTrue(SocketProfile.acceptsURL("jdbc:teiid:jvdb@mm://localhost:1234"));
//$NON-NLS-1$
+
assertTrue(SocketProfile.acceptsURL("jdbc:metamatrix:jvdb@mm://localhost:1234"));
//$NON-NLS-1$
+
assertTrue(SocketProfile.acceptsURL("jdbc:teiid:vdb@mm://localhost:1234;version=x"));
//$NON-NLS-1$
+
assertTrue(SocketProfile.acceptsURL("jdbc:teiid:vdb@mm://localhost:1234"));
//$NON-NLS-1$
+
assertTrue(SocketProfile.acceptsURL("jdbc:teiid:vdb@mm://localhost:1234,localhost2:12342,localhost3:12343"));
//$NON-NLS-1$
+
assertTrue(SocketProfile.acceptsURL("jdbc:teiid:vdb@mm://localhost:1234;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log"));
//$NON-NLS-1$
+
assertTrue(SocketProfile.acceptsURL("jdbc:teiid:vdb@mm://localhost:1234,localhost2:12342,localhost3:12343;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log"));
//$NON-NLS-1$
+
assertTrue(SocketProfile.acceptsURL("jdbc:teiid:vdb@mms://localhost:1234;logLevel=1;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log"));
//$NON-NLS-1$
+
assertTrue(!SocketProfile.acceptsURL("jdbc:teiid:@mm://localhost:1234;logLevel=2;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log"));
//$NON-NLS-1$
+
assertTrue(SocketProfile.acceptsURL("jdbc:teiid:vdb@mm://localhost:1234;logLevel=2;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log;autoCommitTxn=OFF;paritalResultsMode=true"));
//$NON-NLS-1$
+
assertTrue(SocketProfile.acceptsURL("jdbc:teiid:jvdb@mms://localhost:1234"));
//$NON-NLS-1$
+
assertTrue(SocketProfile.acceptsURL("jdbc:teiid:vdb@mm://localhost:1234;version=x"));
//$NON-NLS-1$
+
assertTrue(SocketProfile.acceptsURL("jdbc:teiid:vdb@mm://localhost:1234,localhost2:12342,localhost3:12343"));
//$NON-NLS-1$
+
assertTrue(SocketProfile.acceptsURL("jdbc:teiid:vdb@mms://localhost:1234,localhost2:12342,localhost3:12343;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log"));
//$NON-NLS-1$
+
assertTrue(SocketProfile.acceptsURL("jdbc:teiid:vdb@mms://localhost:1234;logLevel=2;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log;autoCommitTxn=OFF;paritalResultsMode=true"));
//$NON-NLS-1$
+
assertTrue(SocketProfile.acceptsURL("jdbc:teiid:vdb@mm://127.0.0.1:1234;logLevel=2"));
//$NON-NLS-1$
+
assertTrue(SocketProfile.acceptsURL("jdbc:teiid:vdb@mms://127.0.0.1:1234"));
//$NON-NLS-1$
+
assertTrue(SocketProfile.acceptsURL("jdbc:teiid:vdb@mm://127.0.0.1:1234,localhost.mydomain.com:63636;logLevel=2"));
//$NON-NLS-1$
+
assertTrue(SocketProfile.acceptsURL("jdbc:teiid:vdb@mm://my-host.mydomain.com:53535,127.0.0.1:1234"));
//$NON-NLS-1$
+
assertTrue(SocketProfile.acceptsURL("jdbc:teiid:vdb@mm://123.123.123.123:53535,127.0.0.1:1234"));
//$NON-NLS-1$
+
+
assertTrue(!SocketProfile.acceptsURL("jdbc:metamatrix:jvdb@localhost:1234"));
//$NON-NLS-1$
+
assertTrue(!SocketProfile.acceptsURL("jdbc:teiid:jvdb@localhost:1234"));
//$NON-NLS-1$
+
+ //DQP type
+
assertTrue(!SocketProfile.acceptsURL("jdbc:teiid:jvdb@c:/dqp.properties;version=1"));
//$NON-NLS-1$
+
assertTrue(!SocketProfile.acceptsURL("jdbc:teiid:jvdb@/foo/dqp.properties;version=1"));
//$NON-NLS-1$
+
assertTrue(!SocketProfile.acceptsURL("jdbc:teiid:jvdb@../foo/dqp.properties;version=1"));
//$NON-NLS-1$
+
+
assertTrue(!SocketProfile.acceptsURL("jdbc:teiid:jvdb@mm://localhost:port"));
//$NON-NLS-1$
+
assertTrue(!SocketProfile.acceptsURL("jdbc:teiid:vdb@localhost:port;version=x"));
//$NON-NLS-1$
+ assertTrue(!SocketProfile.acceptsURL("jdbc:teiid:@localhost:1234"));
//$NON-NLS-1$
+
assertTrue(!SocketProfile.acceptsURL("jdbc:teiid:@localhost:1234,localhost2:12342,localhost3:12343"));
//$NON-NLS-1$
+
assertTrue(!SocketProfile.acceptsURL("jdbc:teiid:@localhost:1234;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log"));
//$NON-NLS-1$
+
assertTrue(!SocketProfile.acceptsURL("jdbc:teiid:@localhost:1234,localhost2:12342,localhost3:12343;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log"));
//$NON-NLS-1$
+
assertTrue(!SocketProfile.acceptsURL("jdbc:teiid:@localhost:1234;logLevel=1;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log"));
//$NON-NLS-1$
+
assertTrue(!SocketProfile.acceptsURL("jdbc:teiid:@localhost:1234;logLevel=2;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log"));
//$NON-NLS-1$
+
assertTrue(!SocketProfile.acceptsURL("jdbc:teiid:@localhost:1234;logLevel=2;logFile=D:\\metamatrix\\work\\DQP\\log\\jdbcLogFile.log;autoCommitTxn=OFF;paritalResultsMode=true"));
//$NON-NLS-1$
+
assertTrue(!SocketProfile.acceptsURL("jdbc:teiid:@localhost:1234;stickyConnections=false;socketsPerVM=4"));
//$NON-NLS-1$
+
assertTrue(!SocketProfile.acceptsURL("jdbc:teiid:vdb@mm://my_host.mydomain.com:53535,127.0.0.1:1234"));
//$NON-NLS-1$
+ }
+
+ /** Invalid format of urls*/
+ @Test public void testAcceptsURL2() throws Exception {
+ assertTrue(!SocketProfile.acceptsURL("jdbc:matamatrix:test"));
//$NON-NLS-1$
+ assertTrue(!SocketProfile.acceptsURL("metamatrix:test"));
//$NON-NLS-1$
+ assertTrue(!SocketProfile.acceptsURL("jdbc&matamatrix:test"));
//$NON-NLS-1$
+ assertTrue(!SocketProfile.acceptsURL("jdbc;metamatrix:test"));
//$NON-NLS-1$
+ }
+
+ @Test public void testParseURL() throws SQLException{
+ Properties p = new Properties();
+ SocketProfile.parseURL("jdbc:teiid:BQT@mm://slwxp157:1234", p);
//$NON-NLS-1$
+ assertTrue(p.getProperty(BaseDataSource.VDB_NAME).equals("BQT"));
//$NON-NLS-1$
+
assertTrue(p.getProperty(TeiidURL.CONNECTION.SERVER_URL).equals("mm://slwxp157:1234"));
//$NON-NLS-1$
+ assertEquals(3, p.size());
+ }
+
+ @Test public void testParseURL2() throws SQLException {
+ Properties p = new Properties();
+ SocketProfile.parseURL("jdbc:teiid:BQT@mms://slwxp157:1234;version=3",
p); //$NON-NLS-1$
+ assertTrue(p.getProperty(BaseDataSource.VDB_NAME).equals("BQT"));
//$NON-NLS-1$
+ assertTrue(p.getProperty(BaseDataSource.VDB_VERSION).equals("3"));
//$NON-NLS-1$
+
assertTrue(p.getProperty(TeiidURL.CONNECTION.SERVER_URL).equals("mms://slwxp157:1234"));
//$NON-NLS-1$
+ assertTrue(p.getProperty(BaseDataSource.VERSION).equals("3"));
//$NON-NLS-1$
+
assertTrue(p.getProperty(BaseDataSource.APP_NAME).equals(BaseDataSource.DEFAULT_APP_NAME));
+ assertEquals(5, p.size());
+ }
+
+ @Test public void testParseURL3() throws SQLException{
+ Properties p = new Properties();
+
SocketProfile.parseURL("jdbc:teiid:BQT@mm://slwxp157:1234,slntmm01:43401,sluxmm09:43302;version=4;autoCommitTxn=ON;partialResultsMode=YES;ApplicationName=Client",
p); //$NON-NLS-1$
+ assertTrue(p.getProperty(BaseDataSource.VDB_NAME).equals("BQT"));
//$NON-NLS-1$
+ assertTrue(p.getProperty(BaseDataSource.VDB_VERSION).equals("4"));
//$NON-NLS-1$
+
assertTrue(p.getProperty(ExecutionProperties.PROP_TXN_AUTO_WRAP).equals("ON"));
//$NON-NLS-1$
+
assertTrue(p.getProperty(ExecutionProperties.PROP_PARTIAL_RESULTS_MODE).equals("YES"));
//$NON-NLS-1$
+
assertTrue(p.getProperty(TeiidURL.CONNECTION.SERVER_URL).equals("mm://slwxp157:1234,slntmm01:43401,sluxmm09:43302"));
//$NON-NLS-1$
+ assertTrue(p.getProperty(BaseDataSource.VERSION).equals("4"));
//$NON-NLS-1$
+ assertTrue(p.getProperty(BaseDataSource.APP_NAME).equals("Client"));
//$NON-NLS-1$
+ assertEquals(7, p.size());
+ }
+}
Property changes on: trunk/client/src/test/java/org/teiid/jdbc/TestSocketProfile.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Copied: trunk/client/src/test/java/org/teiid/jdbc/TestTeiidDataSource.java (from rev 1983,
trunk/client-jdbc/src/test/java/org/teiid/jdbc/TestTeiidDataSource.java)
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestTeiidDataSource.java
(rev 0)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestTeiidDataSource.java 2010-03-22 21:01:44
UTC (rev 1986)
@@ -0,0 +1,633 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintWriter;
+import java.sql.Connection;
+import java.sql.SQLException;
+
+import org.teiid.jdbc.BaseDataSource;
+import org.teiid.jdbc.TeiidDataSource;
+
+import junit.framework.TestCase;
+
+import com.metamatrix.core.util.UnitTestUtil;
+
+public class TestTeiidDataSource extends TestCase {
+
+ protected static final boolean VALID = true;
+ protected static final boolean INVALID = false;
+
+ private TeiidDataSource dataSource;
+
+ protected static final String STD_SERVER_NAME =
"unitTestServerName"; //$NON-NLS-1$
+ protected static final String STD_DATABASE_NAME =
"unitTestVdbName"; //$NON-NLS-1$
+ protected static final String STD_DATABASE_VERSION =
"unitTestVdbVersion"; //$NON-NLS-1$
+ protected static final String STD_DATA_SOURCE_NAME =
"unitTestDataSourceName"; //$NON-NLS-1$
+ protected static final int STD_PORT_NUMBER = 7001;
+ protected static final String STD_LOG_FILE =
UnitTestUtil.getTestScratchPath() + "/unitTestLogFile"; //$NON-NLS-1$
+ protected static final int STD_LOG_LEVEL = 2;
+ protected static final String STD_TXN_WRAP = TeiidDataSource.TXN_WRAP_AUTO;
+ protected static final String STD_PARTIAL_MODE = "false";
//$NON-NLS-1$
+ protected static final String STD_CONFIG_FILE =
UnitTestUtil.getTestDataPath() + "/bqt/bqt.properties"; //$NON-NLS-1$
+ protected static final String STD_ALTERNATE_SERVERS =
"unitTestServerName2:7001,unitTestServerName2:7002,unitTestServerName3:7001";
//$NON-NLS-1$
+
+ /**
+ * Constructor for TestTeiidDataSource.
+ * @param name
+ */
+ public TestTeiidDataSource(String name) {
+ super(name);
+ }
+
+ /**
+ * @see TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ dataSource = new TeiidDataSource();
+ dataSource.setServerName(STD_SERVER_NAME);
+ dataSource.setDatabaseVersion(STD_DATABASE_VERSION);
+ dataSource.setDatabaseName(STD_DATABASE_NAME);
+ dataSource.setPortNumber(STD_PORT_NUMBER);
+ dataSource.setDataSourceName(STD_DATA_SOURCE_NAME);
+ dataSource.setTransactionAutoWrap(STD_TXN_WRAP);
+ dataSource.setPartialResultsMode(STD_PARTIAL_MODE);
+ dataSource.setSecure(true);
+ dataSource.setAlternateServers(STD_ALTERNATE_SERVERS);
+ }
+
+ // =========================================================================
+ // H E L P E R M E T H O D S
+ // =========================================================================
+
+ protected String getReasonWhyInvalid( final String propertyName, final String value )
{
+ if ( propertyName.equals("DatabaseName") ) { //$NON-NLS-1$
+ return TeiidDataSource.reasonWhyInvalidDatabaseName(value);
+ } else if ( propertyName.equals("DatabaseVersion") ) { //$NON-NLS-1$
+ return TeiidDataSource.reasonWhyInvalidDatabaseVersion(value);
+ } else if ( propertyName.equals("DataSourceName") ) { //$NON-NLS-1$
+ return TeiidDataSource.reasonWhyInvalidDataSourceName(value);
+ } else if ( propertyName.equals("Description") ) { //$NON-NLS-1$
+ return TeiidDataSource.reasonWhyInvalidDescription(value);
+ } else if ( propertyName.equals("ServerName") ) { //$NON-NLS-1$
+ return TeiidDataSource.reasonWhyInvalidServerName(value);
+ } else if ( propertyName.equals("TransactionAutoWrap") ) {
//$NON-NLS-1$
+ return TeiidDataSource.reasonWhyInvalidTransactionAutoWrap(value);
+ } else if ( propertyName.equals("partialResultsMode")) { //$NON-NLS-1$
+ return TeiidDataSource.reasonWhyInvalidPartialResultsMode(value);
+ } else if ( propertyName.equals("socketsPerVM")) { //$NON-NLS-1$
+ return TeiidDataSource.reasonWhyInvalidSocketsPerVM(value);
+ } else if ( propertyName.equals("stickyConnections")) { //$NON-NLS-1$
+ return TeiidDataSource.reasonWhyInvalidStickyConnections(value);
+ } else if ( propertyName.equals("alternateServers")) { //$NON-NLS-1$
+ return TeiidDataSource.reasonWhyInvalidAlternateServers(value);
+ }
+
+ fail("Unknown property name \"" + propertyName +
"\""); //$NON-NLS-1$ //$NON-NLS-2$
+ return null;
+ }
+
+ protected String getReasonWhyInvalid( final String propertyName, final int value ) {
+ if ( propertyName.equals("PortNumber") ) { //$NON-NLS-1$
+ return TeiidDataSource.reasonWhyInvalidPortNumber(value);
+ }
+ fail("Unknown property name \"" + propertyName +
"\""); //$NON-NLS-1$ //$NON-NLS-2$
+ return null;
+ }
+
+ public void helpTestReasonWhyInvalid( final String propertyName, final String value,
+ final boolean shouldBeValid) {
+ final String reason = getReasonWhyInvalid(propertyName,value);
+ if ( shouldBeValid ) {
+ assertNull("Unexpectedly considered invalid value \"" + value
+ "\"; reason = " + reason,reason); //$NON-NLS-1$ //$NON-NLS-2$
+ } else {
+ assertNotNull("Unexpectedly found no reason for value \"" +
value + "\"",reason); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+
+ public void helpTestReasonWhyInvalid( final String propertyName, final int value,
+ final boolean shouldBeValid) {
+ final String reason = getReasonWhyInvalid(propertyName,value);
+ if ( shouldBeValid ) {
+ assertNull("Unexpectedly considered invalid value " + value +
"; reason = " + reason,reason); //$NON-NLS-1$ //$NON-NLS-2$
+ } else {
+ assertNotNull("Unexpectedly found no reason for value " +
value,reason); //$NON-NLS-1$
+ }
+ }
+
+ public void helpTestBuildingURL( final String vdbName, final String vdbVersion,
+ final String serverName, final int portNumber,
+ final String alternateServers,
+ final String txnAutoWrap, final String partialMode,
+ final int fetchSize, final boolean showPlan,
+ final boolean secure, final String expectedURL) {
+
+ final TeiidDataSource ds = new TeiidDataSource();
+ ds.setServerName(serverName);
+ ds.setDatabaseVersion(vdbVersion);
+ ds.setDatabaseName(vdbName);
+ ds.setPortNumber(portNumber);
+ ds.setFetchSize(fetchSize);
+ ds.setTransactionAutoWrap(txnAutoWrap);
+ ds.setPartialResultsMode(partialMode);
+ if(showPlan) {
+ ds.setSqlOptions(ExecutionProperties.SQL_OPTION_SHOWPLAN);
+ }
+ ds.setSecure(secure);
+ ds.setAlternateServers(alternateServers);
+
+ final String url = ds.buildURL();
+ assertEquals(expectedURL, url);
+ }
+
+ public Connection helpTestConnection( final String vdbName, final String vdbVersion,
+ final String serverName, final int portNumber, final
String alternateServers,
+ final String user, final String password,
+ final String dataSourceName,
+ final String txnAutoWrap, final String partialMode,
+ final String configFile )
+ throws SQLException {
+
+ TeiidDataSource ds = new TeiidDataSource();
+
+ ds.setServerName(serverName);
+ ds.setDatabaseVersion(vdbVersion);
+ ds.setDatabaseName(vdbName);
+ ds.setPortNumber(portNumber);
+ ds.setUser(user);
+ ds.setPassword(password);
+ ds.setDataSourceName(dataSourceName);
+ ds.setTransactionAutoWrap(txnAutoWrap);
+ ds.setPartialResultsMode(partialMode);
+ ds.setAlternateServers(alternateServers);
+
+ return ds.getConnection();
+
+ }
+
+ // =========================================================================
+ // T E S T C A S E S
+ // =========================================================================
+
+ // ----------------------------------------------------------------
+ // Test Getters
+ // ----------------------------------------------------------------
+
+ public void testGetServerName() {
+ final String result = dataSource.getServerName();
+ assertEquals(result,STD_SERVER_NAME);
+ }
+
+ public void testGetDatabaseVersion() {
+ final String result = dataSource.getDatabaseVersion();
+ assertEquals(result,STD_DATABASE_VERSION);
+ }
+
+ public void testGetDatabaseName() {
+ final String result = dataSource.getDatabaseName();
+ assertEquals(result,STD_DATABASE_NAME);
+ }
+
+ public void testGetDefaultApplicationName() {
+ final String result = dataSource.getApplicationName();
+ assertEquals(result,BaseDataSource.DEFAULT_APP_NAME);
+ }
+
+ public void testGetApplicationName() {
+ dataSource.setApplicationName("ClientApp"); //$NON-NLS-1$
+ final String result = dataSource.getApplicationName();
+ assertEquals(result,"ClientApp"); //$NON-NLS-1$
+ }
+
+ public void testGetPortNumber() {
+ final int result = dataSource.getPortNumber();
+ assertEquals(result,STD_PORT_NUMBER);
+ }
+
+ public void testGetDataSourceName() {
+ final String result = dataSource.getDataSourceName();
+ assertEquals(result,STD_DATA_SOURCE_NAME);
+ }
+
+ public void testGetLoginTimeout() {
+ try {
+ final int actual = 1000;
+ dataSource.setLoginTimeout(actual);
+ final int result = dataSource.getLoginTimeout();
+ assertEquals(result,actual);
+ } catch ( SQLException e ) {
+ fail("Error obtaining login timeout"); //$NON-NLS-1$
+ }
+ }
+
+ public void testGetLogWriter() {
+ try {
+ final PrintWriter actual = new PrintWriter( new ByteArrayOutputStream() );
+ dataSource.setLogWriter(actual);
+ final PrintWriter result = dataSource.getLogWriter();
+ assertEquals(result,actual);
+ } catch ( SQLException e ) {
+ fail("Error obtaining login timeout"); //$NON-NLS-1$
+ }
+ }
+
+ public void testGetTransactionAutoWrap() {
+ final String result = dataSource.getTransactionAutoWrap();
+ assertEquals(result,STD_TXN_WRAP);
+ }
+
+ public void testGetShowPlan() {
+ assertTrue(dataSource.getSqlOptions() == null);
+ dataSource.setSqlOptions(ExecutionProperties.SQL_OPTION_SHOWPLAN);
+ assertTrue(dataSource.getSqlOptions() ==
ExecutionProperties.SQL_OPTION_SHOWPLAN);
+ dataSource.setSqlOptions(null);
+ assertTrue(dataSource.getSqlOptions() == null);
+ }
+
+ public void testGetSecure() {
+ assertTrue(dataSource.isSecure());
+ dataSource.setSecure(false);
+ assertFalse(dataSource.isSecure());
+ }
+
+ public void testGetAlternateServers() {
+ String result = dataSource.getAlternateServers();
+ assertEquals(result,STD_ALTERNATE_SERVERS);
+ dataSource.setAlternateServers(null);
+ result = dataSource.getAlternateServers();
+ assertNull(result);
+ dataSource.setAlternateServers(STD_ALTERNATE_SERVERS);
+ result = dataSource.getAlternateServers();
+ assertEquals(result,STD_ALTERNATE_SERVERS);
+ }
+
+ // ----------------------------------------------------------------
+ // Test invalid reasons
+ // ----------------------------------------------------------------
+
+ public void testReasonWhyInvalidDatabaseName1() {
+ helpTestReasonWhyInvalid("DatabaseName", "Valid VDB Name",
VALID); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ public void testReasonWhyInvalidDatabaseName2() {
+ helpTestReasonWhyInvalid("DatabaseName", "", INVALID);
//$NON-NLS-1$ //$NON-NLS-2$
+ }
+ public void testReasonWhyInvalidDatabaseName3() {
+ helpTestReasonWhyInvalid("DatabaseName", null, INVALID); //$NON-NLS-1$
+ }
+
+
+ public void testReasonWhyInvalidDatabaseVersion1() {
+ helpTestReasonWhyInvalid("DatabaseVersion", "Valid VDB
Version", VALID); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ public void testReasonWhyInvalidDatabaseVersion2() {
+ helpTestReasonWhyInvalid("DatabaseVersion", "1", VALID);
//$NON-NLS-1$ //$NON-NLS-2$
+ }
+ public void testReasonWhyInvalidDatabaseVersion3() {
+ helpTestReasonWhyInvalid("DatabaseVersion", "1.2.3", VALID);
//$NON-NLS-1$ //$NON-NLS-2$
+ }
+ public void testReasonWhyInvalidDatabaseVersion4() {
+ helpTestReasonWhyInvalid("DatabaseVersion", "1 2 3", VALID);
//$NON-NLS-1$ //$NON-NLS-2$
+ }
+ public void testReasonWhyInvalidDatabaseVersion5() {
+ helpTestReasonWhyInvalid("DatabaseVersion", "", VALID);
//$NON-NLS-1$ //$NON-NLS-2$
+ }
+ public void testReasonWhyInvalidDatabaseVersion6() {
+ helpTestReasonWhyInvalid("DatabaseVersion", null, VALID);
//$NON-NLS-1$
+ }
+
+
+ public void testReasonWhyInvalidDataSourceName1() {
+ helpTestReasonWhyInvalid("DataSourceName", "Valid Data Source
Name", VALID); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ public void testReasonWhyInvalidDataSourceName2() {
+ helpTestReasonWhyInvalid("DataSourceName", "", VALID);
//$NON-NLS-1$ //$NON-NLS-2$
+ }
+ public void testReasonWhyInvalidDataSourceName3() {
+ helpTestReasonWhyInvalid("DataSourceName", "", VALID);
//$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+
+ public void testReasonWhyInvalidDescription1() {
+ helpTestReasonWhyInvalid("Description", "Valid App Name",
VALID); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ public void testReasonWhyInvalidDescription2() {
+ helpTestReasonWhyInvalid("Description", "", VALID);
//$NON-NLS-1$ //$NON-NLS-2$
+ }
+ public void testReasonWhyInvalidDescription3() {
+ helpTestReasonWhyInvalid("Description", null, VALID); //$NON-NLS-1$
+ }
+
+ public void testReasonWhyInvalidPortNumber1() {
+ helpTestReasonWhyInvalid("PortNumber", 1, VALID); //$NON-NLS-1$
+ }
+ public void testReasonWhyInvalidPortNumber2() {
+ helpTestReasonWhyInvalid("PortNumber", 9999999, VALID); //$NON-NLS-1$
+ }
+ public void testReasonWhyInvalidPortNumber3() {
+ helpTestReasonWhyInvalid("PortNumber", 0, VALID); //$NON-NLS-1$
+ }
+ public void testReasonWhyInvalidPortNumber4() {
+ helpTestReasonWhyInvalid("PortNumber", -1, INVALID); //$NON-NLS-1$
+ }
+
+
+ public void testReasonWhyInvalidServerName1() {
+ helpTestReasonWhyInvalid("ServerName", "Valid Server Name",
VALID); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ public void testReasonWhyInvalidServerName2() {
+ helpTestReasonWhyInvalid("ServerName", "Valid Server Name",
VALID); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ public void testReasonWhyInvalidServerName3() {
+ helpTestReasonWhyInvalid("ServerName", "", INVALID);
//$NON-NLS-1$ //$NON-NLS-2$
+ }
+ public void testReasonWhyInvalidServerName4() {
+ helpTestReasonWhyInvalid("ServerName", null, INVALID); //$NON-NLS-1$
+ }
+
+
+ public void testReasonWhyInvalidTransactionAutoWrap1() {
+ helpTestReasonWhyInvalid("TransactionAutoWrap",
TeiidDataSource.TXN_WRAP_OFF, VALID); //$NON-NLS-1$
+ }
+ public void testReasonWhyInvalidTransactionAutoWrap2() {
+ helpTestReasonWhyInvalid("TransactionAutoWrap",
TeiidDataSource.TXN_WRAP_ON, VALID); //$NON-NLS-1$
+ }
+ public void testReasonWhyInvalidTransactionAutoWrap3() {
+ helpTestReasonWhyInvalid("TransactionAutoWrap",
TeiidDataSource.TXN_WRAP_AUTO, VALID); //$NON-NLS-1$
+ }
+ public void testReasonWhyInvalidTransactionAutoWrap5() {
+ helpTestReasonWhyInvalid("TransactionAutoWrap", "off",
INVALID); // lowercase value //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ public void testReasonWhyInvalidTransactionAutoWrap6() {
+ helpTestReasonWhyInvalid("TransactionAutoWrap", "Invalid
AutoWrap", INVALID); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ public void testreasonWhyInvalidPartialResultsMode1() {
+ helpTestReasonWhyInvalid("partialResultsMode", "Invalid partial
mode", INVALID); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ public void testreasonWhyInvalidPartialResultsMode2() {
+ helpTestReasonWhyInvalid("partialResultsMode", "true",
VALID); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ public void testReasonWhyInvalidSocketsPerVM1() {
+ helpTestReasonWhyInvalid("socketsPerVM", null, VALID); //$NON-NLS-1$
+ }
+ public void testReasonWhyInvalidSocketsPerVM2() {
+ helpTestReasonWhyInvalid("socketsPerVM", "4", VALID);
//$NON-NLS-1$ //$NON-NLS-2$
+ }
+ public void testReasonWhyInvalidSocketsPerVM3() {
+ helpTestReasonWhyInvalid("socketsPerVM", "-3", INVALID);
//$NON-NLS-1$ //$NON-NLS-2$
+ }
+ public void testReasonWhyInvalidSocketsPerVM4() {
+ helpTestReasonWhyInvalid("socketsPerVM", "5.6", INVALID);
//$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ public void testReasonWhyInvalidStickyConnections1() {
+ helpTestReasonWhyInvalid("stickyConnections", null, VALID);
//$NON-NLS-1$
+ }
+ public void testReasonWhyInvalidStickyConnections2() {
+ helpTestReasonWhyInvalid("stickyConnections", "false",
VALID); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ public void testReasonWhyInvalidStickyConnections3() {
+ helpTestReasonWhyInvalid("stickyConnections", "YES",
INVALID); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ public void testReasonWhyInvalidAlternateServers1() {
+ helpTestReasonWhyInvalid("alternateServers", null, VALID); //$NON-NLS-1$
+ }
+ public void testReasonWhyInvalidAlternateServers2() {
+ helpTestReasonWhyInvalid("alternateServers", "", VALID);
//$NON-NLS-1$ //$NON-NLS-2$
+ }
+ public void testReasonWhyInvalidAlternateServers3() {
+ helpTestReasonWhyInvalid("alternateServers", "server", VALID);
//$NON-NLS-1$ //$NON-NLS-2$
+ }
+ public void testReasonWhyInvalidAlternateServers4() {
+ helpTestReasonWhyInvalid("alternateServers", "server:100",
VALID); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ public void testReasonWhyInvalidAlternateServers5() {
+ helpTestReasonWhyInvalid("alternateServers", "server:port",
INVALID); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ public void testReasonWhyInvalidAlternateServers6() {
+ helpTestReasonWhyInvalid("alternateServers", "server:100:1",
INVALID); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ public void testReasonWhyInvalidAlternateServers7() {
+ helpTestReasonWhyInvalid("alternateServers", "server:100:abc",
INVALID); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ public void testReasonWhyInvalidAlternateServers8() {
+ helpTestReasonWhyInvalid("alternateServers", "server:abc:100",
INVALID); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ public void testReasonWhyInvalidAlternateServers9() {
+ helpTestReasonWhyInvalid("alternateServers", ":100", INVALID);
//$NON-NLS-1$ //$NON-NLS-2$
+ }
+ public void testReasonWhyInvalidAlternateServers10() {
+ helpTestReasonWhyInvalid("alternateServers", ":abc", INVALID);
//$NON-NLS-1$ //$NON-NLS-2$
+ }
+ public void testReasonWhyInvalidAlternateServers11() {
+ helpTestReasonWhyInvalid("alternateServers",
"server1:100,server2", VALID); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ public void testReasonWhyInvalidAlternateServers12() {
+ helpTestReasonWhyInvalid("alternateServers",
"server1:100,server2:101", VALID); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ public void testReasonWhyInvalidAlternateServers13() {
+ helpTestReasonWhyInvalid("alternateServers", "server1:100,",
VALID); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ public void testReasonWhyInvalidAlternateServers14() {
+ helpTestReasonWhyInvalid("alternateServers",
"server1:100,server2:abc", INVALID); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ public void testReasonWhyInvalidAlternateServers15() {
+ helpTestReasonWhyInvalid("alternateServers",
"server1:100,server2:101:abc", INVALID); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ public void testReasonWhyInvalidAlternateServers16() {
+ helpTestReasonWhyInvalid("alternateServers",
"server1,server2:100", VALID); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ public void testReasonWhyInvalidAlternateServers17() {
+ helpTestReasonWhyInvalid("alternateServers", "server1,server2",
VALID); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ public void testReasonWhyInvalidAlternateServers18() {
+ helpTestReasonWhyInvalid("alternateServers", ",server2:100",
INVALID); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ public void testReasonWhyInvalidAlternateServers19() {
+ helpTestReasonWhyInvalid("alternateServers",
"server1,server2,server3,server4:500", VALID); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+
+
+
+ // ----------------------------------------------------------------
+ // Test building URLs
+ // ----------------------------------------------------------------
+
+ public void testBuildingURL1() {
+ final String serverName = "hostName"; //$NON-NLS-1$
+ final String vdbName = "vdbName"; //$NON-NLS-1$
+ final String vdbVersion = "1.2.3"; //$NON-NLS-1$
+ final int portNumber = 7001;
+ final String transactionAutoWrap = null;
+ final String partialMode = "true"; //$NON-NLS-1$
+ final boolean secure = false;
+
helpTestBuildingURL(vdbName,vdbVersion,serverName,portNumber,null,transactionAutoWrap,
partialMode, 500, false, secure,
+
"jdbc:teiid:vdbName@mm://hostname:7001;fetchSize=500;ApplicationName=JDBC;VirtualDatabaseVersion=1.2.3;partialResultsMode=true;VirtualDatabaseName=vdbName");
//$NON-NLS-1$
+ }
+
+ public void testBuildingURL2() {
+ final String serverName = "hostName"; //$NON-NLS-1$
+ final String vdbName = "vdbName"; //$NON-NLS-1$
+ final String vdbVersion = ""; //$NON-NLS-1$
+ final int portNumber = 7001;
+ final String transactionAutoWrap = TeiidDataSource.TXN_WRAP_AUTO;
+ final String partialMode = "false"; //$NON-NLS-1$
+ final boolean secure = false;
+
helpTestBuildingURL(vdbName,vdbVersion,serverName,portNumber,null,transactionAutoWrap,
partialMode, -1, false, secure,
+
"jdbc:teiid:vdbName@mm://hostname:7001;ApplicationName=JDBC;partialResultsMode=false;autoCommitTxn=DETECT;VirtualDatabaseName=vdbName");
//$NON-NLS-1$
+ }
+
+ public void testBuildURL3() {
+ final String serverName = "hostName"; //$NON-NLS-1$
+ final String vdbName = "vdbName"; //$NON-NLS-1$
+ final String vdbVersion = ""; //$NON-NLS-1$
+ final int portNumber = 7001;
+ final String transactionAutoWrap = TeiidDataSource.TXN_WRAP_AUTO;
+ final String partialMode = "false"; //$NON-NLS-1$
+ final boolean secure = false;
+
helpTestBuildingURL(vdbName,vdbVersion,serverName,portNumber,null,transactionAutoWrap,
partialMode, -1, true, secure,
+
"jdbc:teiid:vdbName@mm://hostname:7001;ApplicationName=JDBC;partialResultsMode=false;autoCommitTxn=DETECT;VirtualDatabaseName=vdbName;sqlOptions=SHOWPLAN");
//$NON-NLS-1$
+ }
+
+ // Test secure protocol
+ public void testBuildURL4() {
+ final String serverName = "hostName"; //$NON-NLS-1$
+ final String vdbName = "vdbName"; //$NON-NLS-1$
+ final String vdbVersion = ""; //$NON-NLS-1$
+ final int portNumber = 7001;
+ final String transactionAutoWrap = TeiidDataSource.TXN_WRAP_AUTO;
+ final String partialMode = "false"; //$NON-NLS-1$
+ final boolean secure = true;
+
helpTestBuildingURL(vdbName,vdbVersion,serverName,portNumber,null,transactionAutoWrap,
partialMode, -1, true, secure,
+
"jdbc:teiid:vdbName@mms://hostname:7001;ApplicationName=JDBC;partialResultsMode=false;autoCommitTxn=DETECT;VirtualDatabaseName=vdbName;sqlOptions=SHOWPLAN");
//$NON-NLS-1$
+ }
+
+ /*
+ * Test alternate servers list
+ *
+ * Server list uses server:port pairs
+ */
+ public void testBuildURL5() {
+ final String serverName = "hostName"; //$NON-NLS-1$
+ final String vdbName = "vdbName"; //$NON-NLS-1$
+ final String vdbVersion = ""; //$NON-NLS-1$
+ final int portNumber = 7001;
+ final String alternateServers =
"hostName:7002,hostName2:7001,hostName2:7002"; //$NON-NLS-1$
+ final String transactionAutoWrap = TeiidDataSource.TXN_WRAP_AUTO;
+ final String partialMode = "false"; //$NON-NLS-1$
+ final boolean secure = false;
+
helpTestBuildingURL(vdbName,vdbVersion,serverName,portNumber,alternateServers,transactionAutoWrap,
partialMode, -1, true, secure,
+
"jdbc:teiid:vdbName@mm://hostName:7001,hostName:7002,hostName2:7001,hostName2:7002;ApplicationName=JDBC;partialResultsMode=false;autoCommitTxn=DETECT;VirtualDatabaseName=vdbName;sqlOptions=SHOWPLAN");
//$NON-NLS-1$
+ }
+
+ /*
+ * Test alternate servers list
+ *
+ * Server list uses server:port pairs and we set secure to true
+ */
+ public void testBuildURL6() {
+ final String serverName = "hostName"; //$NON-NLS-1$
+ final String vdbName = "vdbName"; //$NON-NLS-1$
+ final String vdbVersion = ""; //$NON-NLS-1$
+ final int portNumber = 7001;
+ final String alternateServers =
"hostName:7002,hostName2:7001,hostName2:7002"; //$NON-NLS-1$
+ final String transactionAutoWrap = TeiidDataSource.TXN_WRAP_AUTO;
+ final String partialMode = "false"; //$NON-NLS-1$
+ final boolean secure = true;
+
helpTestBuildingURL(vdbName,vdbVersion,serverName,portNumber,alternateServers,transactionAutoWrap,
partialMode, -1, true, secure,
+
"jdbc:teiid:vdbName@mms://hostName:7001,hostName:7002,hostName2:7001,hostName2:7002;ApplicationName=JDBC;partialResultsMode=false;autoCommitTxn=DETECT;VirtualDatabaseName=vdbName;sqlOptions=SHOWPLAN");
//$NON-NLS-1$
+ }
+
+ /*
+ * Test alternate servers list
+ *
+ * Server list uses server:port pairs and server with no port
+ * In this case, the server with no port should default to ds.portNumber.
+ */
+ public void testBuildURL7() {
+ final String serverName = "hostName"; //$NON-NLS-1$
+ final String vdbName = "vdbName"; //$NON-NLS-1$
+ final String vdbVersion = ""; //$NON-NLS-1$
+ final int portNumber = 7001;
+ final String alternateServers =
"hostName:7002,hostName2,hostName2:7002"; //$NON-NLS-1$
+ final String transactionAutoWrap = TeiidDataSource.TXN_WRAP_AUTO;
+ final String partialMode = "false"; //$NON-NLS-1$
+ final boolean secure = false;
+
helpTestBuildingURL(vdbName,vdbVersion,serverName,portNumber,alternateServers,transactionAutoWrap,
partialMode, -1, true, secure,
+
"jdbc:teiid:vdbName@mm://hostName:7001,hostName:7002,hostName2:7001,hostName2:7002;ApplicationName=JDBC;partialResultsMode=false;autoCommitTxn=DETECT;VirtualDatabaseName=vdbName;sqlOptions=SHOWPLAN");
//$NON-NLS-1$
+ }
+
+ public void testBuildURL_AdditionalProperties() {
+ final TeiidDataSource ds = new TeiidDataSource();
+ ds.setAdditionalProperties("foo=bar;a=b"); //$NON-NLS-1$
+ ds.setServerName("hostName"); //$NON-NLS-1$
+ ds.setDatabaseName("vdbName"); //$NON-NLS-1$
+ ds.setPortNumber(1);
+
assertEquals("jdbc:teiid:vdbName@mm://hostname:1;fetchSize=2048;ApplicationName=JDBC;a=b;VirtualDatabaseName=vdbName;foo=bar",
ds.buildURL()); //$NON-NLS-1$
+ }
+
+ public void testInvalidDataSource() {
+ final String serverName = "hostName"; //$NON-NLS-1$
+ final String vdbName = "vdbName"; //$NON-NLS-1$
+ final String vdbVersion = ""; //$NON-NLS-1$
+ final int portNumber = -1; // this is what is invalid
+ final String dataSourceName = null;
+ final String transactionAutoWrap = null;
+ final String configFile = UnitTestUtil.getTestDataPath() +
"/config.txt"; //$NON-NLS-1$
+ try {
+ helpTestConnection(vdbName,vdbVersion,serverName,portNumber, null, null,
null, dataSourceName,transactionAutoWrap,
+ "false", configFile); // TRUE TO OVERRIDE USERNAME &
PASSWORD //$NON-NLS-1$
+ fail("Unexpectedly able to connect"); //$NON-NLS-1$
+ } catch ( SQLException e) {
+ // this is expected!
+ }
+ }
+
+ /*
+ * Test invalid alternateServer list
+ *
+ * Server list uses a non numeric value for port.
+ */
+ public void testInvalidDataSource2() {
+ final String serverName = "hostName"; //$NON-NLS-1$
+ final String vdbName = "vdbName"; //$NON-NLS-1$
+ final String vdbVersion = ""; //$NON-NLS-1$
+ final int portNumber = 31000;
+ final String alternateServers = "hostName:-1"; // this is what is
invalid //$NON-NLS-1$
+ final String dataSourceName = null;
+ final String transactionAutoWrap = null;
+ final String configFile = UnitTestUtil.getTestDataPath() +
"/config.txt"; //$NON-NLS-1$
+ try {
+ helpTestConnection(vdbName, vdbVersion, serverName, portNumber,
+ alternateServers, null, null, dataSourceName, transactionAutoWrap,
"false", configFile); //$NON-NLS-1$ // TRUE TO OVERRIDE USERNAME &
PASSWORD
+ fail("Unexpectedly able to connect"); //$NON-NLS-1$
+ } catch ( SQLException e) {
+ // this is expected!
+ }
+ }
+}
\ No newline at end of file
Property changes on: trunk/client/src/test/java/org/teiid/jdbc/TestTeiidDataSource.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Copied: trunk/client/src/test/java/org/teiid/jdbc/TestTeiidDriver.java (from rev 1983,
trunk/client-jdbc/src/test/java/org/teiid/jdbc/TestTeiidDriver.java)
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestTeiidDriver.java
(rev 0)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestTeiidDriver.java 2010-03-22 21:01:44 UTC
(rev 1986)
@@ -0,0 +1,55 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+
+import java.sql.DriverPropertyInfo;
+
+import org.junit.Test;
+
+public class TestTeiidDriver {
+ TeiidDriver drv = new TeiidDriver();
+
+
+ @Test public void testGetPropertyInfo1() throws Exception {
+ DriverPropertyInfo info[] =
drv.getPropertyInfo("jdbc:teiid:vdb@mm://localhost:12345", null); //$NON-NLS-1$
+ assertEquals(17, info.length);
+ }
+
+ @Test public void testAccepts() throws Exception {
+ assertTrue(drv.acceptsURL("jdbc:teiid:vdb@mm://localhost:12345"));
//$NON-NLS-1$
+
assertTrue(drv.acceptsURL("jdbc:teiid:vdb@mm://localhost:12345;user=foo;password=bar"));
//$NON-NLS-1$
+ assertTrue(drv.acceptsURL("jdbc:teiid:vdb")); //$NON-NLS-1$
+ assertFalse(drv.acceptsURL("jdbc:teiid:vdb@/foo/blah/deploy.properties"));
//$NON-NLS-1$
+
+ assertTrue(drv.acceptsURL("jdbc:teiid:vdb@mm://localhost:12345"));
//$NON-NLS-1$
+
assertTrue(drv.acceptsURL("jdbc:teiid:vdb@mm://localhost:12345;user=foo;password=bar"));
//$NON-NLS-1$
+ assertTrue(drv.acceptsURL("jdbc:teiid:vdb")); //$NON-NLS-1$
+ assertFalse(drv.acceptsURL("jdbc:teiid:vdb@/foo/blah/deploy.properties"));
//$NON-NLS-1$
+
+ }
+
+}
Property changes on: trunk/client/src/test/java/org/teiid/jdbc/TestTeiidDriver.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Copied: trunk/client/src/test/java/org/teiid/jdbc/TestWrapperImpl.java (from rev 1983,
trunk/client-jdbc/src/test/java/org/teiid/jdbc/TestWrapperImpl.java)
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestWrapperImpl.java
(rev 0)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestWrapperImpl.java 2010-03-22 21:01:44 UTC
(rev 1986)
@@ -0,0 +1,91 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.jdbc;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.sql.SQLException;
+//## JDBC4.0-begin ##
+import java.sql.Wrapper;
+
+import org.teiid.jdbc.WrapperImpl;
+//## JDBC4.0-end ##
+
+import junit.framework.TestCase;
+
+public class TestWrapperImpl extends TestCase {
+ //## JDBC4.0-begin ##
+ interface Foo extends Wrapper {
+ void callMe();
+ }
+
+ static class FooImpl extends WrapperImpl implements Foo {
+
+ boolean wasCalled;
+
+ public void callMe() {
+ wasCalled = true;
+ }
+
+ }
+ //## JDBC4.0-end ##
+ public void testProxy() throws SQLException {
+ //## JDBC4.0-begin ##
+ final FooImpl fooImpl = new FooImpl();
+
+ Foo proxy = (Foo)Proxy.newProxyInstance(TestWrapperImpl.class.getClassLoader(), new
Class[] {Foo.class}, new InvocationHandler() {
+
+ public Object invoke(Object arg0, Method arg1, Object[] arg2)
+ throws Throwable {
+ if (arg1.getName().equals("callMe")) {
+ return null;
+ }
+ try {
+ return arg1.invoke(fooImpl, arg2);
+ } catch (InvocationTargetException e) {
+ throw e.getTargetException();
+ }
+ }
+
+ });
+
+ proxy.callMe();
+
+ assertFalse(fooImpl.wasCalled);
+
+ proxy.unwrap(Foo.class).callMe();
+
+ assertTrue(fooImpl.wasCalled);
+
+ try {
+ proxy.unwrap(String.class);
+ fail("expected exception");
+ } catch (SQLException e) {
+ assertEquals("Wrapped object is not an instance of class java.lang.String",
e.getMessage());
+ }
+ //## JDBC4.0-end ##
+ }
+
+}
Copied: trunk/client/src/test/java/org/teiid/jdbc/plan (from rev 1983,
trunk/client-jdbc/src/test/java/org/teiid/jdbc/plan)
Modified: trunk/client/src/test/java/org/teiid/jdbc/plan/TestTextOutputVisitor.java
===================================================================
---
trunk/client-jdbc/src/test/java/org/teiid/jdbc/plan/TestTextOutputVisitor.java 2010-03-22
14:47:51 UTC (rev 1983)
+++ trunk/client/src/test/java/org/teiid/jdbc/plan/TestTextOutputVisitor.java 2010-03-22
21:01:44 UTC (rev 1986)
@@ -27,6 +27,10 @@
import java.util.HashMap;
import java.util.List;
+import org.teiid.client.plan.DefaultDisplayHelper;
+import org.teiid.client.plan.PlanNode;
+import org.teiid.client.plan.TextOutputVisitor;
+
import junit.framework.TestCase;
Modified: trunk/client/src/test/java/org/teiid/jdbc/plan/TestXMLOutputVisitor.java
===================================================================
---
trunk/client-jdbc/src/test/java/org/teiid/jdbc/plan/TestXMLOutputVisitor.java 2010-03-22
14:47:51 UTC (rev 1983)
+++ trunk/client/src/test/java/org/teiid/jdbc/plan/TestXMLOutputVisitor.java 2010-03-22
21:01:44 UTC (rev 1986)
@@ -22,6 +22,9 @@
package org.teiid.jdbc.plan;
+import org.teiid.client.plan.DefaultDisplayHelper;
+import org.teiid.client.plan.XMLOutputVisitor;
+
import junit.framework.TestCase;
Copied: trunk/client/src/test/java/org/teiid/jdbc/util (from rev 1983,
trunk/client-jdbc/src/test/java/org/teiid/jdbc/util)
Modified: trunk/console/pom.xml
===================================================================
--- trunk/console/pom.xml 2010-03-22 20:34:29 UTC (rev 1985)
+++ trunk/console/pom.xml 2010-03-22 21:01:44 UTC (rev 1986)
@@ -208,16 +208,6 @@
<dependency>
<groupId>org.jboss.teiid</groupId>
- <artifactId>teiid-client-jdbc</artifactId>
- </dependency>
- <dependency>
- <groupId>org.jboss.teiid</groupId>
- <artifactId>teiid-client-jdbc</artifactId>
- <type>test-jar</type>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.teiid</groupId>
<artifactId>teiid-common-core</artifactId>
</dependency>
<dependency>
Modified:
trunk/engine/src/main/java/org/teiid/dqp/internal/transaction/TransactionServerImpl.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/dqp/internal/transaction/TransactionServerImpl.java 2010-03-22
20:34:29 UTC (rev 1985)
+++
trunk/engine/src/main/java/org/teiid/dqp/internal/transaction/TransactionServerImpl.java 2010-03-22
21:01:44 UTC (rev 1986)
@@ -398,17 +398,14 @@
private void rollbackDirect(TransactionContext tc)
throws XATransactionException {
try {
- this.transactionManager.resume(tc.getTransaction());
this.transactionManager.rollback();
} catch (SecurityException e) {
throw new XATransactionException(e);
} catch (SystemException e) {
throw new XATransactionException(e);
- } catch (InvalidTransactionException e) {
- throw new XATransactionException(e);
- } finally {
- transactions.removeTransactionContext(tc);
- }
+ } finally {
+ transactions.removeTransactionContext(tc);
+ }
}
public void suspend(TransactionContext context) throws XATransactionException {
Modified: trunk/jboss-integration/pom.xml
===================================================================
--- trunk/jboss-integration/pom.xml 2010-03-22 20:34:29 UTC (rev 1985)
+++ trunk/jboss-integration/pom.xml 2010-03-22 21:01:44 UTC (rev 1986)
@@ -73,13 +73,12 @@
<type>test-jar</type>
<scope>test</scope>
</dependency>
-
+
<dependency>
<groupId>org.jboss.teiid</groupId>
- <artifactId>teiid-client-jdbc</artifactId>
- <scope>test</scope>
+ <artifactId>teiid-client</artifactId>
</dependency>
-
+
<dependency>
<groupId>org.jboss.naming</groupId>
<artifactId>jnp-client</artifactId>
Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml 2010-03-22 20:34:29 UTC (rev 1985)
+++ trunk/pom.xml 2010-03-22 21:01:44 UTC (rev 1986)
@@ -275,18 +275,6 @@
</dependency>
<dependency>
<groupId>org.jboss.teiid</groupId>
- <artifactId>teiid-client-jdbc</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.jboss.teiid</groupId>
- <artifactId>teiid-client-jdbc</artifactId>
- <type>test-jar</type>
- <version>${project.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.jboss.teiid</groupId>
<artifactId>teiid-engine</artifactId>
<version>${project.version}</version>
</dependency>
@@ -482,7 +470,6 @@
<module>common-core</module>
<module>connector-api</module>
<module>client</module>
- <module>client-jdbc</module>
<module>engine</module>
<module>connectors</module>
<module>console</module>
Modified: trunk/runtime/pom.xml
===================================================================
--- trunk/runtime/pom.xml 2010-03-22 20:34:29 UTC (rev 1985)
+++ trunk/runtime/pom.xml 2010-03-22 21:01:44 UTC (rev 1986)
@@ -45,11 +45,6 @@
<artifactId>teiid-metadata</artifactId>
</dependency>
<dependency>
- <groupId>org.jboss.teiid</groupId>
- <artifactId>teiid-client-jdbc</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
<groupId>org.jboss.teiid</groupId>
<artifactId>teiid-cache-jbosscache</artifactId>
</dependency>
Modified: trunk/test-integration/db/pom.xml
===================================================================
--- trunk/test-integration/db/pom.xml 2010-03-22 20:34:29 UTC (rev 1985)
+++ trunk/test-integration/db/pom.xml 2010-03-22 21:01:44 UTC (rev 1986)
@@ -38,7 +38,7 @@
<dependency>
<groupId>org.jboss.teiid</groupId>
- <artifactId>teiid-client-jdbc</artifactId>
+ <artifactId>teiid-client</artifactId>
<type>test-jar</type>
<scope>compile</scope>
</dependency>
Modified: trunk/test-integration/pom.xml
===================================================================
--- trunk/test-integration/pom.xml 2010-03-22 20:34:29 UTC (rev 1985)
+++ trunk/test-integration/pom.xml 2010-03-22 21:01:44 UTC (rev 1986)
@@ -52,11 +52,11 @@
</dependency>
<dependency>
<groupId>org.jboss.teiid</groupId>
- <artifactId>teiid-client-jdbc</artifactId>
+ <artifactId>teiid-client</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.teiid</groupId>
- <artifactId>teiid-client-jdbc</artifactId>
+ <artifactId>teiid-client</artifactId>
<type>test-jar</type>
</dependency>
<dependency>