/*
* Microsoft JDBC Driver for SQL Server
*
* Copyright(c) Microsoft Corporation All rights reserved.
*
* This program is made available under the terms of the MIT License. See the LICENSE file in the project root for more information.
*/
package com.microsoft.sqlserver.jdbc.unit.statement;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import org.junit.jupiter.api.Test;
import org.junit.platform.runner.JUnitPlatform;
import org.junit.runner.RunWith;
import com.microsoft.sqlserver.jdbc.ISQLServerPreparedStatement;
import com.microsoft.sqlserver.jdbc.SQLServerCallableStatement;
import com.microsoft.sqlserver.jdbc.SQLServerException;
import com.microsoft.sqlserver.jdbc.SQLServerStatement;
import com.microsoft.sqlserver.testframework.AbstractTest;
import com.microsoft.sqlserver.testframework.DBConnection;
/**
* Tests isWrapperFor methods
*
*/
@RunWith(JUnitPlatform.class)
public class WrapperTest extends AbstractTest {
/**
* Wrapper tests
* @throws Exception
*/
@Test
public void wrapTest() throws Exception {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
Connection con = DriverManager.getConnection(connectionString);
Statement stmt = con.createStatement();
try {
// First make sure that a statement can be unwrapped
boolean isWrapper = ((SQLServerStatement) stmt).isWrapperFor(Class.forName("com.microsoft.sqlserver.jdbc.SQLServerStatement"));
assertEquals(isWrapper, true, "SQLServerStatement should be a wrapper for self");
isWrapper = ((SQLServerStatement) stmt).isWrapperFor(Class.forName("com.microsoft.sqlserver.jdbc.ISQLServerStatement"));
assertEquals(isWrapper, true, "SQLServerStatement should be a wrapper for ISQLServerStatement");
isWrapper = ((SQLServerStatement) stmt).isWrapperFor(Class.forName("com.microsoft.sqlserver.jdbc.SQLServerConnection"));
assertEquals(isWrapper, false, "SQLServerStatement should not be a wrapper for SQLServerConnection");
// Now make sure that we can unwrap a SQLServerCallableStatement to a SQLServerStatement
CallableStatement cs = con.prepareCall("{ ? = CALL " + "ProcName" + " (?, ?, ?, ?) }");
// Test the class first
isWrapper = ((SQLServerCallableStatement) cs).isWrapperFor(Class.forName("com.microsoft.sqlserver.jdbc.SQLServerStatement"));
assertEquals(isWrapper, true, "SQLServerCallableStatement should be a wrapper for SQLServerStatement");
// Now unwrap the Callable to a statement and call a SQLServerStatement specific function and make sure it succeeds.
SQLServerStatement stmt2 = (SQLServerStatement) ((SQLServerCallableStatement) cs)
.unwrap(Class.forName("com.microsoft.sqlserver.jdbc.SQLServerStatement"));
stmt2.setResponseBuffering("adaptive");
// now test the interface
isWrapper = ((SQLServerCallableStatement) cs).isWrapperFor(Class.forName("com.microsoft.sqlserver.jdbc.ISQLServerCallableStatement"));
assertEquals(isWrapper, true, "SQLServerCallableStatement should be a wrapper for ISQLServerCallableStatement");
// Now unwrap the Callable to a statement and call a SQLServerStatement specific function and make sure it succeeds.
ISQLServerPreparedStatement stmt4 = (ISQLServerPreparedStatement) ((SQLServerCallableStatement) cs)
.unwrap(Class.forName("com.microsoft.sqlserver.jdbc.ISQLServerPreparedStatement"));
stmt4.setResponseBuffering("adaptive");
if (isKatmaiServer())
stmt4.setDateTimeOffset(1, null);
// Try Unwrapping CallableStatement to a callableStatement
isWrapper = ((SQLServerCallableStatement) cs).isWrapperFor(Class.forName("com.microsoft.sqlserver.jdbc.SQLServerCallableStatement"));
assertEquals(isWrapper, true, "SQLServerCallableStatement should be a wrapper for SQLServerCallableStatement");
// Now unwrap the Callable to a SQLServerCallableStatement and call a SQLServerStatement specific function and make sure it succeeds.
SQLServerCallableStatement stmt3 = (SQLServerCallableStatement) ((SQLServerCallableStatement) cs)
.unwrap(Class.forName("com.microsoft.sqlserver.jdbc.SQLServerCallableStatement"));
stmt3.setResponseBuffering("adaptive");
if (isKatmaiServer()) {
stmt3.setDateTimeOffset(1, null);
}
if (null != stmt4) {
stmt4.close();
}
if (null != cs) {
cs.close();
}
}
catch (UnsupportedOperationException e) {
assertEquals(System.getProperty("java.specification.version"), "1.5", "isWrapperFor should be supported in anything other than 1.5");
assertTrue(e.getMessage().equalsIgnoreCase("This operation is not supported."), "Wrong exception message");
}
finally {
if (null != stmt) {
stmt.close();
}
if (null != con) {
con.close();
}
}
}
/**
* Tests expected unwrapper failures
* @throws Exception
*/
@Test
public void unWrapFailureTest() throws Exception {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
Connection con = DriverManager.getConnection(connectionString);
SQLServerStatement stmt = (SQLServerStatement) con.createStatement();
try {
String str = "java.lang.String";
boolean isWrapper = stmt.isWrapperFor(Class.forName(str));
stmt.unwrap(Class.forName(str));
assertEquals(isWrapper, false, "SQLServerStatement should not be a wrapper for string");
stmt.unwrap(Class.forName(str));
assertTrue(false, "An exception should have been thrown. This code should not be reached");
}
catch (SQLServerException ex) {
Throwable t = ex.getCause();
Class exceptionClass = Class.forName("java.lang.ClassCastException");
assertEquals(t.getClass(), exceptionClass, "The cause in the exception class does not match");
}
catch (UnsupportedOperationException e) {
assertEquals(System.getProperty("java.specification.version"), "1.5", "isWrapperFor should be supported in anything other than 1.5");
assertEquals(e.getMessage(), "This operation is not supported.", "Wrong exception message");
}
finally {
if (null != stmt) {
stmt.close();
}
if (null != con) {
con.close();
}
}
}
private static boolean isKatmaiServer() throws Exception {
DBConnection conn = new DBConnection(connectionString);
double version = conn.getServerVersion();
conn.close();
return ((version >= 10.0) ? true : false);
}
}