001: /*
002:
003: Derby - Class CallableStatementTest
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derbyTesting.functionTests.tests.jdbc4;
023:
024: import junit.framework.*;
025:
026: import org.apache.derbyTesting.junit.BaseJDBCTestCase;
027:
028: import java.io.IOException;
029: import java.io.Reader;
030: import java.sql.*;
031: import java.lang.reflect.Method;
032: import java.util.Vector;
033:
034: /**
035: * Tests of the <code>java.sql.CallableStatement</code> JDBC40 API.
036: */
037: public class CallableStatementTest extends BaseJDBCTestCase {
038:
039: /** Default callable statement used by the tests. */
040: private CallableStatement cStmt = null;
041:
042: /**
043: * Create a test with the given name.
044: *
045: * @param name name of the test.
046: */
047: public CallableStatementTest(String name) {
048: super (name);
049: }
050:
051: /**
052: * Create a default callable statement and connection.
053: *
054: * @throws SQLException if creation of connection or callable statement
055: * fail.
056: */
057: protected void setUp() throws SQLException {
058: cStmt = prepareCall("? = CALL FLOOR(?)");
059: cStmt.registerOutParameter(1, Types.DOUBLE);
060: }
061:
062: /**
063: * Close default callable statement and connection.
064: *
065: * @throws SQLException if closing of the connection or the callable
066: * statement fail.
067: */
068: protected void tearDown() throws Exception {
069: if (cStmt != null && !cStmt.isClosed()) {
070: cStmt.close();
071: }
072:
073: super .tearDown();
074: }
075:
076: public void testNamedParametersAreNotSupported()
077: throws SQLException {
078: DatabaseMetaData met = getConnection().getMetaData();
079: assertFalse(
080: "Named parameters are not supported, but the metadata "
081: + "says they are", met
082: .supportsNamedParameters());
083: met = null;
084: }
085:
086: public void testGetDoubleIntOnInParameter() throws SQLException {
087: cStmt.setDouble(2, 3.3);
088: cStmt.execute();
089: try {
090: cStmt.getDouble(2);
091: fail("Calling getDouble on an IN parameter should throw "
092: + "an exception");
093: } catch (SQLException sqle) {
094: // SQLState differ between DerbyNetClient and embedded.
095: String sqlState = usingDerbyNetClient() ? "XJ091" : "XCL26";
096: assertSQLState("Unexpected SQLState", sqlState, sqle);
097: }
098: }
099:
100: public void testGetNClobIntNotImplemented() throws SQLException {
101: try {
102: cStmt.getNClob(1);
103: fail("CallableStatement.getNClob(int) should not be implemented");
104: } catch (SQLFeatureNotSupportedException sfnse) {
105: // We are fine, do nothing.
106: }
107: }
108:
109: public void testGetNClobStringNotImplemented() throws SQLException {
110: try {
111: cStmt.getNClob("some-parameter-name");
112: fail("CallableStatement.getNClob(String) "
113: + "should not be implemented");
114: } catch (SQLFeatureNotSupportedException sfnse) {
115: // We are fine, do nothing.
116: }
117: }
118:
119: public void testGetNStringIntNotImplemented() throws SQLException {
120: try {
121: cStmt.getNString(1);
122: fail("CallableStatement.getNString(int) "
123: + "should not be implemented");
124: } catch (SQLFeatureNotSupportedException sfnse) {
125: // We are fine, do nothing.
126: }
127: }
128:
129: public void testGetNStringStringNotImplemented()
130: throws SQLException {
131: try {
132: cStmt.getNString("some-parameter-name");
133: fail("CallableStatement.getNString(String) "
134: + "should not be implemented");
135: } catch (SQLFeatureNotSupportedException sfnse) {
136: // We are fine, do nothing.
137: }
138: }
139:
140: public void testGetCharacterStreamIntOnInvalidTypeDOUBLE()
141: throws SQLException {
142: cStmt.setDouble(2, 3.3);
143: cStmt.execute();
144: try {
145: cStmt.getCharacterStream(1);
146: fail("An exception signalling invalid data type conversion "
147: + "should have been thrown");
148: } catch (SQLDataException sqlde) {
149: assertSQLState(
150: "Exception with invalid SQL state thrown on "
151: + "invalid data type conversion", "22005",
152: sqlde);
153: }
154: }
155:
156: /**
157: * Test which SQLState is thrown when getCharacterStream is called
158: * on an IN parameter of an unsupported type.
159: */
160: public void testGetCharacterStreamIntOnInParameterOfInvalidType()
161: throws SQLException {
162: cStmt.setDouble(2, 3.3);
163: cStmt.execute();
164: try {
165: cStmt.getCharacterStream(2);
166: fail("Calling getCharacterStream on an IN parameter should "
167: + "throw an exception");
168: } catch (SQLException sqle) {
169: // SQLState differ between DerbyNetClient and embedded.
170: String sqlState = usingDerbyNetClient() ? "XJ091" : "XCL26";
171: assertSQLState(
172: "Exception with invalid SQL state thrown for "
173: + "getCharacterStream on IN parameter",
174: sqlState, sqle);
175: }
176: }
177:
178: /**
179: * Test which SQLState is thrown when getCharacterStream is called
180: * on an IN parameter of a supported type.
181: */
182: public void testGetCharacterStreamIntOnInParameterOfValidType()
183: throws SQLException {
184: cStmt = CallableStatementTestSetup
185: .getBinaryDirectProcedure(getConnection());
186: cStmt.setString(1, "A string");
187: cStmt.execute();
188: try {
189: cStmt.getCharacterStream(1);
190: fail("Calling getCharacterStream on an IN parameter should "
191: + "throw an exception");
192: } catch (SQLException sqle) {
193: // SQLState differ between DerbyNetClient and embedded.
194: String sqlState = usingDerbyNetClient() ? "XJ091" : "XCL26";
195: assertSQLState(
196: "Exception with invalid SQL state thrown for "
197: + "getCharacterStream on IN parameter",
198: sqlState, sqle);
199: }
200: }
201:
202: /**
203: * Test basic use of getCharacterStream on character data.
204: * Create a CallableStatement that takes an integer as input and returns
205: * the number as a string. The string is read as a stream, and the integer
206: * is recreated from it and compared to the integer passed in.
207: */
208: public void testGetCharacterStreamIntVARCHAR() throws IOException,
209: SQLException {
210: cStmt = CallableStatementTestSetup
211: .getIntToStringFunction(getConnection());
212: cStmt.setInt(2, 4509);
213: assertFalse("No resultsets should be returned", cStmt.execute());
214: assertEquals("Incorrect updatecount", -1, cStmt
215: .getUpdateCount());
216: // Get a character stream
217: Reader cStream = cStmt.getCharacterStream(1);
218: assertFalse("Stream should not be null", cStmt.wasNull());
219: assertNotNull(
220: "Stream is null even though wasNull() returned false",
221: cStream);
222: char[] chars = new char[4];
223: assertEquals("Wrong number of characters read", 4, cStream
224: .read(chars));
225: // Make sure we have reached end of stream.
226: assertEquals(
227: "Expected end of stream, but there were more data", -1,
228: cStream.read());
229: cStream.close();
230: String result = new String(chars);
231: assertEquals(
232: "Incorrect result obtained through java.io.Reader",
233: "4509", result);
234: }
235:
236: /**
237: * Test basic use of getCharacterStream on binary data.
238: * Create a CallableStatement that takes a string as input and returns
239: * a byte representation, which is then read through a stream. The string
240: * is recreated and compared to the one passed in. Note that strings must
241: * be represented in UTF-16BE for this to work.
242: */
243: public void testGetCharacterStreamIntVARBINARYDirect()
244: throws IOException, SQLException {
245: String data = "This is the test string.";
246: cStmt = CallableStatementTestSetup
247: .getBinaryDirectProcedure(getConnection());
248: cStmt.setString(1, data);
249: assertFalse("No resultsets should be returned", cStmt.execute());
250: // Note that getUpdateCount behaves differently on client and embedded.
251: assertEquals("Incorrect updatecount", usingEmbedded() ? 0 : -1,
252: cStmt.getUpdateCount());
253: Reader cStream = cStmt.getCharacterStream(2);
254: assertFalse("Stream should not be null", cStmt.wasNull());
255: assertNotNull(
256: "Stream is null even though wasNull() returned false",
257: cStream);
258: // Assume we don't know how many bytes the string will be represented
259: // by, just create enough space and read until stream is exhausted.
260: // To be able to read the string back, getBytes must be called with
261: // UTF-16BE charset, because Derby uses UTF-16BE encoding as default.
262: // JDBC does not specify which charset to use for binary data, and
263: // UTF-16BE was apparently selected to match JCC.
264: char[] tmpChars = new char[data.length() * 4];
265: int curChar = cStream.read();
266: int index = 0;
267: while (curChar != -1) {
268: tmpChars[index] = (char) curChar;
269: index++;
270: curChar = cStream.read();
271: }
272: cStream.close();
273: char[] chars = new char[index];
274: System.arraycopy(tmpChars, 0, chars, 0, index);
275: String result = new String(chars);
276: assertEquals(
277: "Incorrect result obtained through java.io.Reader",
278: data, result);
279: }
280:
281: /**
282: * Fetch a string stored as bytes from the database through a reader,
283: * then recreate the string.
284: */
285: public void testGetCharacterStreamIntVARBINARYFromDb()
286: throws IOException, SQLException {
287: cStmt = CallableStatementTestSetup
288: .getBinaryFromDbFunction(getConnection());
289: cStmt.setInt(2, CallableStatementTestSetup.STRING_BYTES_ID);
290: assertFalse("No resultsets should be returned", cStmt.execute());
291: assertEquals("Incorrect updatecount", -1, cStmt
292: .getUpdateCount());
293: Reader cStream = cStmt.getCharacterStream(1);
294: assertFalse("Stream should not be null", cStmt.wasNull());
295: assertNotNull(
296: "Stream is null even though wasNull() returned false",
297: cStream);
298: char[] tmpChars = new char[32672];
299: int curChar = cStream.read();
300: int index = 0;
301: while (curChar != -1) {
302: tmpChars[index] = (char) curChar;
303: index++;
304: curChar = cStream.read();
305: }
306: char[] chars = new char[index];
307: System.arraycopy(tmpChars, 0, chars, 0, index);
308: tmpChars = null;
309: cStream.close();
310: String result = new String(chars);
311: assertEquals("Strings not equal",
312: CallableStatementTestSetup.STRING_BYTES, result);
313: }
314:
315: /**
316: * Read a SQL NULL value from a VARBINARY column through a reader.
317: */
318: public void testGetCharacterStreamIntOnVARBINARYWithNull()
319: throws SQLException {
320: cStmt = CallableStatementTestSetup
321: .getBinaryFromDbFunction(getConnection());
322: cStmt.setInt(2, CallableStatementTestSetup.SQL_NULL_ID);
323: assertFalse("No resultsets should be returned", cStmt.execute());
324: assertEquals("Incorrect updatecount", -1, cStmt
325: .getUpdateCount());
326: Reader cStream = cStmt.getCharacterStream(1);
327: assertTrue("Stream should be null", cStmt.wasNull());
328: assertNull(
329: "Stream is not null even though wasNull() returned true",
330: cStream);
331: }
332:
333: /**
334: * Read a SQL NULL value from a VARCHAR column through a reader.
335: */
336: public void testGetCharacterStreamIntOnVARCHARWithNull()
337: throws SQLException {
338: cStmt = CallableStatementTestSetup
339: .getVarcharFromDbFunction(getConnection());
340: cStmt.setInt(2, CallableStatementTestSetup.SQL_NULL_ID);
341: assertFalse("No resultsets should be returned", cStmt.execute());
342: assertEquals("Incorrect updatecount", -1, cStmt
343: .getUpdateCount());
344: Reader cStream = cStmt.getCharacterStream(1);
345: assertTrue("Stream should be null", cStmt.wasNull());
346: assertNull(
347: "Stream is not null even though wasNull() returned true",
348: cStream);
349: }
350:
351: public void testGetCharacterStreamStringNotImplemented()
352: throws SQLException {
353: try {
354: cStmt.getCharacterStream("some-parameter-name");
355: fail("CallableStatement.getCharacterStream(String) "
356: + "should not be implemented");
357: } catch (SQLFeatureNotSupportedException sfnse) {
358: // We are fine, do nothing.
359: }
360: }
361:
362: public void testGetNCharacterStreamIntNotImplemented()
363: throws SQLException {
364: try {
365: cStmt.getNCharacterStream(1);
366: fail("CallableStatement.getNCharacterStream(int) "
367: + "should not be implemented");
368: } catch (SQLFeatureNotSupportedException sfnse) {
369: // We are fine, do nothing.
370: }
371: }
372:
373: public void testGetNCharacterStreamStringNotImplemented()
374: throws SQLException {
375: try {
376: cStmt.getNCharacterStream("some-parameter-name");
377: fail("CallableStatement.getNCharacterStream(String) "
378: + "should not be implemented");
379: } catch (SQLFeatureNotSupportedException sfnse) {
380: // We are fine, do nothing.
381: }
382: }
383:
384: public void testSetBlobNotImplemented() throws SQLException {
385: try {
386: cStmt.setBlob("some-parameter-name", (Blob) null);
387: fail("CallableStatement.setBlob(String, Blob) "
388: + "should not be implemented");
389: } catch (SQLFeatureNotSupportedException sfnse) {
390: // We are fine, do nothing.
391: }
392: }
393:
394: public void testSetClobNotImplemented() throws SQLException {
395: try {
396: cStmt.setClob("some-parameter-name", (Clob) null);
397: fail("CallableStatement.setClob(String, Clob) "
398: + "should not be implemented");
399: } catch (SQLFeatureNotSupportedException sfnse) {
400: // We are fine, do nothing.
401: }
402: }
403:
404: public void testSetNCharacterStreamNotImplemented()
405: throws SQLException {
406: try {
407: cStmt.setNCharacterStream("some-parameter-name", null, 0l);
408: fail("CallableStatement.setNCharacterStream(String,Reader,long) "
409: + "should not be implemented");
410: } catch (SQLFeatureNotSupportedException sfnse) {
411: // We are fine, do nothing.
412: }
413: }
414:
415: public void testSetNClobNClobNotImplemented() throws SQLException {
416: try {
417: cStmt.setNClob("some-parameter-name", (NClob) null);
418: fail("CallableStatement.setNClob(String, NClob) "
419: + "should not be implemented");
420: } catch (SQLFeatureNotSupportedException sfnse) {
421: // We are fine, do nothing.
422: }
423: }
424:
425: public void testSetNClobReaderNotImplemented() throws SQLException {
426: try {
427: cStmt.setNClob("some-parameter-name", null, 0l);
428: fail("CallableStatement.setNClob(String, Reader, long) "
429: + "should not be implemented");
430: } catch (SQLFeatureNotSupportedException sfnse) {
431: // We are fine, do nothing.
432: }
433: }
434:
435: public void testSetNStringNotImplemented() throws SQLException {
436: try {
437: cStmt.setNString("some-parameter-name", "some-value");
438: fail("CallableStatement.setNString(String, String) "
439: + "should not be implemented");
440: } catch (SQLFeatureNotSupportedException sfnse) {
441: // We are fine, do nothing.
442: }
443: }
444:
445: public void testGetSQLXMLIntNotImplemented() throws SQLException {
446: try {
447: cStmt.getSQLXML(1);
448: fail("CallableStatement.getSQLXML(int) "
449: + "should not be implemented");
450: } catch (SQLFeatureNotSupportedException sfnse) {
451: // We are fine, do nothing.
452: }
453: }
454:
455: public void testGetSQLXMLStringNotImplemented() throws SQLException {
456: try {
457: cStmt.getSQLXML("some-parameter-name");
458: fail("CallableStatement.getSQLXML(String) "
459: + "should not be implemented");
460: } catch (SQLFeatureNotSupportedException sfnse) {
461: // We are fine, do nothing.
462: }
463: }
464:
465: public void testSetSQLXMLNotImplemented() throws SQLException {
466: try {
467: cStmt.setSQLXML("some-parameter-name", null);
468: fail("CallableStatement.setSQLXML(String, SQLXML) "
469: + "should not be implemented");
470: } catch (SQLFeatureNotSupportedException sfnse) {
471: // We are fine, do nothing.
472: }
473: }
474:
475: /** Helper method for testIsWrapperFor*Statement test cases. */
476: private void testIsWrapperForXXXStatement(Class klass)
477: throws SQLException {
478: assertTrue("The CallableStatement is not a wrapper for "
479: + klass.getName(), cStmt.isWrapperFor(klass));
480: }
481:
482: public void testIsWrapperForStatement() throws SQLException {
483: testIsWrapperForXXXStatement(Statement.class);
484: }
485:
486: public void testIsWrapperForPreparedStatement() throws SQLException {
487: testIsWrapperForXXXStatement(PreparedStatement.class);
488: }
489:
490: public void testIsWrapperForCallableStatement() throws SQLException {
491: testIsWrapperForXXXStatement(CallableStatement.class);
492: }
493:
494: public void testIsNotWrapperForResultSet() throws SQLException {
495: assertFalse(cStmt.isWrapperFor(ResultSet.class));
496: }
497:
498: public void testUnwrapStatement() throws SQLException {
499: Statement stmt = cStmt.unwrap(Statement.class);
500: assertSame("Unwrap returned wrong object.", cStmt, stmt);
501: }
502:
503: public void testUnwrapPreparedStatement() throws SQLException {
504: PreparedStatement ps = cStmt.unwrap(PreparedStatement.class);
505: assertSame("Unwrap returned wrong object.", cStmt, ps);
506: }
507:
508: public void testUnwrapCallableStatement() throws SQLException {
509: Statement cs = cStmt.unwrap(CallableStatement.class);
510: assertSame("Unwrap returned wrong object.", cStmt, cs);
511: }
512:
513: public void testUnwrapResultSet() {
514: try {
515: ResultSet rs = cStmt.unwrap(ResultSet.class);
516: fail("Unwrap didn't fail.");
517: } catch (SQLException e) {
518: assertSQLState("XJ128", e);
519: }
520: }
521:
522: /**
523: *
524: * Tests the setCharacterStream method that accepts length as a long
525: * parameter in the Callable Statement interface
526: *
527: * @throws SQLException Upon any error that occurs while calling this
528: * method
529: *
530: */
531:
532: public void testSetCharacterStream() throws SQLException {
533: try {
534: cStmt.setCharacterStream("Some String", null, 0L);
535: fail("CallableStatement.setCharacterStream() "
536: + "should not be implemented");
537: } catch (SQLFeatureNotSupportedException sqlfne) {
538: //Do nothing as this is the expected behaviour
539:
540: }
541: }
542:
543: /**
544: *
545: * Tests the setAsciiStream method that accepts length as a long
546: * parameter in the Callable Statement interface
547: *
548: * @throws SQLException Upon any error that occurs while calling this
549: * method
550: *
551: */
552:
553: public void testSetAsciiStream() throws SQLException {
554: try {
555: cStmt.setAsciiStream("Some String", null, 0L);
556: fail("CallableStatement.setAsciiStream() "
557: + "should not be implemented");
558: } catch (SQLFeatureNotSupportedException sqlfne) {
559: //Do nothing as this is the expected behaviour
560:
561: }
562: }
563:
564: /**
565: *
566: * Tests the setBinaryStream method that accepts length as a long
567: * parameter in the Callable Statement interface
568: *
569: * @throws SQLException Upon any error that occurs while calling this
570: * method
571: *
572: */
573:
574: public void testSetBinaryStream() throws SQLException {
575: try {
576: cStmt.setBinaryStream("Some String", null, 0L);
577: fail("CallableStatement.setBinaryStream() "
578: + "should not be implemented");
579: } catch (SQLFeatureNotSupportedException sqlfne) {
580: //Do nothing as this is the expected behaviour
581:
582: }
583: }
584:
585: /**
586: * Return suite with all tests of the class.
587: */
588: public static Test suite() {
589: TestSuite mainSuite = new TestSuite();
590: TestSuite suite = new TestSuite(CallableStatementTest.class,
591: "CallableStatementTest suite");
592: mainSuite.addTest(new CallableStatementTestSetup(suite));
593: mainSuite.addTest(SetObjectUnsupportedTest.suite(true));
594: return mainSuite;
595: }
596:
597: } // End class CallableStatementTest
|