[teiid-commits] teiid SVN: r3591 - in trunk: connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc and 3 other directories.

teiid-commits at lists.jboss.org teiid-commits at lists.jboss.org
Thu Oct 27 13:05:18 EDT 2011


Author: shawkins
Date: 2011-10-27 13:05:18 -0400 (Thu, 27 Oct 2011)
New Revision: 3591

Modified:
   trunk/api/src/main/java/org/teiid/language/Call.java
   trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/JDBCProcedureExecution.java
   trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/oracle/OracleExecutionFactory.java
   trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/oracle/TestOracleTranslator.java
   trunk/documentation/reference/src/main/docbook/en-US/content/translators.xml
Log:
TEIID-832 added support for calling oracle stored procedures returning cursor/resultsets

Modified: trunk/api/src/main/java/org/teiid/language/Call.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/Call.java	2011-10-27 14:44:07 UTC (rev 3590)
+++ trunk/api/src/main/java/org/teiid/language/Call.java	2011-10-27 17:05:18 UTC (rev 3591)
@@ -93,6 +93,9 @@
     	return null;
     }
 
+    /**
+     * @return the result set types or a zero length array if no result set is returned
+     */
     public Class<?>[] getResultSetColumnTypes() {
     	ColumnSet<Procedure> resultSet = this.metadataObject.getResultSet();
     	if (resultSet == null) {

Modified: trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/JDBCProcedureExecution.java
===================================================================
--- trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/JDBCProcedureExecution.java	2011-10-27 14:44:07 UTC (rev 3590)
+++ trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/JDBCProcedureExecution.java	2011-10-27 17:05:18 UTC (rev 3591)
@@ -31,10 +31,10 @@
 import org.teiid.language.Argument;
 import org.teiid.language.Call;
 import org.teiid.language.Command;
-import org.teiid.translator.TranslatorException;
 import org.teiid.translator.DataNotAvailableException;
 import org.teiid.translator.ExecutionContext;
 import org.teiid.translator.ProcedureExecution;
+import org.teiid.translator.TranslatorException;
 
 /**
  */
@@ -87,7 +87,10 @@
         	List<Object> result = new ArrayList<Object>();
         	int paramIndex = 1;
         	if (proc.getReturnType() != null) {
-        		addParameterValue(result, paramIndex++, proc.getReturnType());
+        		if (proc.getReturnParameter() != null) {
+        			addParameterValue(result, paramIndex, proc.getReturnType());
+        		}
+        		paramIndex++;
         	}
         	for (Argument parameter : proc.getArguments()) {
         		switch (parameter.getDirection()) {

Modified: trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/oracle/OracleExecutionFactory.java
===================================================================
--- trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/oracle/OracleExecutionFactory.java	2011-10-27 14:44:07 UTC (rev 3590)
+++ trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/oracle/OracleExecutionFactory.java	2011-10-27 17:05:18 UTC (rev 3591)
@@ -26,7 +26,9 @@
 
 import static org.teiid.translator.TypeFacility.RUNTIME_NAMES.*;
 
+import java.sql.CallableStatement;
 import java.sql.PreparedStatement;
+import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Timestamp;
 import java.sql.Types;
@@ -35,6 +37,7 @@
 import java.util.Collection;
 import java.util.List;
 
+import org.teiid.language.Call;
 import org.teiid.language.ColumnReference;
 import org.teiid.language.Command;
 import org.teiid.language.DerivedColumn;
@@ -42,6 +45,7 @@
 import org.teiid.language.ExpressionValueSource;
 import org.teiid.language.Function;
 import org.teiid.language.Insert;
+import org.teiid.language.LanguageObject;
 import org.teiid.language.Limit;
 import org.teiid.language.Literal;
 import org.teiid.language.NamedTable;
@@ -55,6 +59,7 @@
 import org.teiid.translator.SourceSystemFunctions;
 import org.teiid.translator.Translator;
 import org.teiid.translator.TranslatorException;
+import org.teiid.translator.TranslatorProperty;
 import org.teiid.translator.TypeFacility;
 import org.teiid.translator.jdbc.AliasModifier;
 import org.teiid.translator.jdbc.ConvertModifier;
@@ -62,6 +67,7 @@
 import org.teiid.translator.jdbc.FunctionModifier;
 import org.teiid.translator.jdbc.JDBCExecutionFactory;
 import org.teiid.translator.jdbc.LocateFunctionModifier;
+import org.teiid.translator.jdbc.TranslatedCommand;
 
 
 @Translator(name="oracle", description="A translator for Oracle 9i Database or later")
@@ -85,6 +91,14 @@
 	public static final String WITHIN_DISTANCE = "sdo_within_distance"; //$NON-NLS-1$
 	public static final String NEAREST_NEIGHBOR_DISTANCE = "sdo_nn_distance"; //$NON-NLS-1$
 	public static final String ORACLE_SDO = "Oracle-SDO"; //$NON-NLS-1$
+
+	/*
+	 * Handling for cursor return values
+	 */
+	static final class RefCursorType {}
+	static int CURSOR_TYPE = -10;
+
+	private boolean oracleSuppliedDriver = true;
     
     public void start() throws TranslatorException {
         super.start();
@@ -548,4 +562,46 @@
     	return "REGEXP_LIKE"; //$NON-NLS-1$
     }
     
+    public void setOracleSuppliedDriver(boolean oracleNative) {
+		this.oracleSuppliedDriver = oracleNative;
+	}
+    
+	@TranslatorProperty(display="Oracle Native Driver", description="True if the driver is an Oracle supplied driver",advanced=true)
+    public boolean isOracleSuppliedDriver() {
+		return oracleSuppliedDriver;
+	}
+		
+    @Override
+    public List<?> translate(LanguageObject obj, ExecutionContext context) {
+    	if (oracleSuppliedDriver && obj instanceof Call) {
+    		Call call = (Call)obj;
+    		//oracle returns the resultset as a parameter
+    		if (call.getReturnType() == null) {
+    			call.setReturnType(RefCursorType.class);
+    		}
+    	}
+    	return super.translate(obj, context);
+    }
+    
+    @Override
+    protected void registerSpecificTypeOfOutParameter(
+    		CallableStatement statement, Class<?> runtimeType, int index)
+    		throws SQLException {
+    	if (oracleSuppliedDriver && index == 1 && runtimeType == RefCursorType.class) {
+    		statement.registerOutParameter(1, CURSOR_TYPE);
+    	} else {
+    		super.registerSpecificTypeOfOutParameter(statement, runtimeType, index);
+    	}
+    }
+    
+    @Override
+    public ResultSet executeStoredProcedure(CallableStatement statement,
+    		TranslatedCommand command, Class<?> returnType) throws SQLException {
+    	ResultSet rs = super.executeStoredProcedure(statement, command, returnType);
+    	if (!oracleSuppliedDriver || returnType != RefCursorType.class) {
+    		return rs;
+    	}
+    	return (ResultSet)statement.getObject(1);
+    }
+    
 }

Modified: trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/oracle/TestOracleTranslator.java
===================================================================
--- trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/oracle/TestOracleTranslator.java	2011-10-27 14:44:07 UTC (rev 3590)
+++ trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/oracle/TestOracleTranslator.java	2011-10-27 17:05:18 UTC (rev 3591)
@@ -24,10 +24,15 @@
 
 import static org.junit.Assert.*;
 
+import java.sql.CallableStatement;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.util.Arrays;
 import java.util.List;
 
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.Mockito;
 import org.teiid.cdk.CommandBuilder;
 import org.teiid.cdk.api.TranslationUtility;
 import org.teiid.core.types.DataTypeManager;
@@ -45,6 +50,7 @@
 import org.teiid.query.unittest.RealMetadataFactory;
 import org.teiid.translator.ExecutionContext;
 import org.teiid.translator.TranslatorException;
+import org.teiid.translator.jdbc.JDBCProcedureExecution;
 import org.teiid.translator.jdbc.TranslatedCommand;
 import org.teiid.translator.jdbc.TranslationHelper;
 
@@ -789,5 +795,32 @@
                 input, output, 
                 TRANSLATOR);
     }
+    
+    @Test public void testCallWithResultSet() throws Exception {
+        String input = "call spTest5(1)"; //$NON-NLS-1$
+        String output = "{ ?= call spTest5(?)}";  //$NON-NLS-1$
 
+        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+                input, output, 
+                TRANSLATOR);
+    }
+    
+	@Test public void testProcedureExecution() throws Exception {
+		Command command = TranslationHelper.helpTranslate(TranslationHelper.BQT_VDB, "call spTest8(1)"); //$NON-NLS-1$
+		Connection connection = Mockito.mock(Connection.class);
+		CallableStatement cs = Mockito.mock(CallableStatement.class);
+		Mockito.stub(cs.getUpdateCount()).toReturn(-1);
+		ResultSet rs = Mockito.mock(ResultSet.class);
+		Mockito.stub(cs.getObject(1)).toReturn(rs);
+		Mockito.stub(cs.getInt(3)).toReturn(4);
+		Mockito.stub(connection.prepareCall("{ ?= call spTest8(?,?)}")).toReturn(cs); //$NON-NLS-1$
+		OracleExecutionFactory ef = new OracleExecutionFactory();
+		
+		JDBCProcedureExecution procedureExecution = new JDBCProcedureExecution(command, connection, Mockito.mock(ExecutionContext.class),  ef);
+		procedureExecution.execute();
+		assertEquals(Arrays.asList(4), procedureExecution.getOutputParameterValues());
+		Mockito.verify(cs, Mockito.times(1)).registerOutParameter(1, OracleExecutionFactory.CURSOR_TYPE);
+		Mockito.verify(cs, Mockito.times(1)).getObject(1);
+	}
+
 }

Modified: trunk/documentation/reference/src/main/docbook/en-US/content/translators.xml
===================================================================
--- trunk/documentation/reference/src/main/docbook/en-US/content/translators.xml	2011-10-27 14:44:07 UTC (rev 3590)
+++ trunk/documentation/reference/src/main/docbook/en-US/content/translators.xml	2011-10-27 17:05:18 UTC (rev 3591)
@@ -322,6 +322,12 @@
                     A rownum colum should have a name in source of <code>rownum</code>.  These rownum columns do not 
                     have the same semantics as the Oracle rownum construct so care must be taken in their usage. 
                     </para>
+                    <para>Oracle specific execution properties:</para>
+		            <itemizedlist>
+		            	<listitem>
+		            		<para><emphasis>OracleSuppliedDriver</emphasis> - indicates that the Oracle supplied driver (typically prefixed by ojdbc) is being used.  Defaults to true.  Set to false when using DataDirect or other Oracle JDBC drivers.</para>
+		            	</listitem>
+	            	</itemizedlist>
                 </listitem>
                 <listitem>
                     <para>



More information about the teiid-commits mailing list