0001: /*
0002:
0003: Derby - Class org.apache.derbyTesting.functionTests.tests.jdbcapi.blobclob4BLOB
0004:
0005: Licensed to the Apache Software Foundation (ASF) under one or more
0006: contributor license agreements. See the NOTICE file distributed with
0007: this work for additional information regarding copyright ownership.
0008: The ASF licenses this file to You under the Apache License, Version 2.0
0009: (the "License"); you may not use this file except in compliance with
0010: the License. You may obtain a copy of the License at
0011:
0012: http://www.apache.org/licenses/LICENSE-2.0
0013:
0014: Unless required by applicable law or agreed to in writing, software
0015: distributed under the License is distributed on an "AS IS" BASIS,
0016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0017: See the License for the specific language governing permissions and
0018: limitations under the License.
0019:
0020: */
0021:
0022: package org.apache.derbyTesting.functionTests.tests.jdbcapi;
0023:
0024: import java.io.ByteArrayInputStream;
0025: import java.io.File;
0026: import java.io.FileInputStream;
0027: import java.io.FileNotFoundException;
0028: import java.io.FileOutputStream;
0029: import java.io.FileReader;
0030: import java.io.FileWriter;
0031: import java.io.IOException;
0032: import java.io.InputStream;
0033: import java.io.InputStreamReader;
0034: import java.io.OutputStream;
0035: import java.io.OutputStreamWriter;
0036: import java.io.Reader;
0037: import java.io.StringBufferInputStream;
0038: import java.io.StringReader;
0039: import java.io.Writer;
0040: import java.sql.Blob;
0041: import java.sql.Clob;
0042: import java.sql.Connection;
0043: import java.sql.PreparedStatement;
0044: import java.sql.ResultSet;
0045: import java.sql.ResultSetMetaData;
0046: import java.sql.SQLException;
0047: import java.io.UnsupportedEncodingException;
0048: import java.sql.Statement;
0049: import java.sql.Types;
0050: import java.util.zip.CRC32;
0051:
0052: import org.apache.derby.tools.JDBCDisplayUtil;
0053: import org.apache.derby.tools.ij;
0054: import org.apache.derbyTesting.functionTests.util.Formatters;
0055: import org.apache.derbyTesting.functionTests.util.TestUtil;
0056: import java.util.Arrays;
0057:
0058: /**
0059: * Test of JDBC blob and clob
0060: *
0061: * @author paulat
0062: */
0063:
0064: public class blobclob4BLOB {
0065:
0066: static String[] fileName;
0067: static long[] fileCRC32;
0068: static String[] basefileName; // for printing messages so that no path info is in .out
0069: static String filePath;
0070: static String unicodeFilePath;
0071: static String sep;
0072: static long[] fileLength;
0073: static int numFiles;
0074: static int numRows;
0075: static int numStrings;
0076: static String[] unicodeStrings;
0077: static int numRowsUnicode;
0078: static String unicodeFileName;
0079:
0080: static boolean isDerbyNet = false;
0081: static boolean debug = true;
0082: private static final String START = "\nSTART: ";
0083:
0084: static {
0085: numFiles = 5;
0086: filePath = "extin";
0087: fileName = new String[numFiles];
0088: basefileName = new String[numFiles];
0089: fileLength = new long[numFiles];
0090: fileCRC32 = new long[numFiles];
0091:
0092: fileName[0] = "short.utf"; // set up a short (fit in one page) blob/clob
0093: fileName[1] = "littleclob.utf"; // set up a long (longer than a page) blob/clob
0094: fileName[2] = "empty.utf"; // set up a blob/clob with nothing in it
0095: fileName[3] = "searchclob.utf"; // set up a blob/clob to search with
0096: fileName[4] = "aclob.utf"; // set up a really long (over 300K) blob/clob
0097:
0098: for (int i = 0; i < numFiles; i++) {
0099: basefileName[i] = fileName[i];
0100: }
0101:
0102: numRows = 10;
0103:
0104: numStrings = 3;
0105: unicodeStrings = new String[numStrings];
0106: unicodeStrings[0] = "\u0061\u0062\u0063"; // abc
0107: unicodeStrings[1] = "\u0370\u0371\u0372";
0108: unicodeStrings[2] = "\u05d0\u05d1\u05d2";
0109: numRowsUnicode = 6;
0110:
0111: unicodeFilePath = "extinout";
0112: unicodeFileName = "unicodeFile.txt";
0113: }
0114:
0115: public static void main(String[] args) {
0116: System.out.println("Test blobclob starting");
0117:
0118: isDerbyNet = TestUtil.isNetFramework();
0119:
0120: try {
0121: // first check to see if the path to extin/out dir is ok.
0122: sep = System.getProperty("file.separator");
0123: boolean exists = (new File(filePath, fileName[0])).exists();
0124: if (!exists) {
0125: String userDir = System.getProperty("user.dir");
0126: filePath = userDir + sep + ".." + sep + filePath;
0127: unicodeFilePath = userDir + sep + ".." + sep
0128: + unicodeFilePath;
0129: }
0130: for (int i = 0; i < numFiles; i++) {
0131: fileName[i] = filePath + sep + fileName[i];
0132:
0133: FileInputStream fis = new FileInputStream(fileName[i]);
0134: fileCRC32[i] = getStreamCheckSum(fis);
0135: }
0136: unicodeFileName = unicodeFilePath + sep + unicodeFileName;
0137:
0138: // use the ij utility to read the property file and
0139: // make the initial connection.
0140: ij.getPropertyArg(args);
0141: Connection conn = ij.startJBMS();
0142: // turn off autocommit, otherwise blobs/clobs cannot hang around
0143: // until end of transaction
0144: conn.setAutoCommit(false);
0145:
0146: prepareCLOBMAIN(conn);
0147: prepareSearchClobTable(conn);
0148: prepareUnicodeTable(conn);
0149: prepareUnicodeFile(conn);
0150: // prepareBinaryTable(conn);
0151:
0152: setCharacterStreamTest(conn);
0153:
0154: // unicodeTest();
0155: // clobTestGroupfetch(conn);
0156:
0157: clobTest0(conn);
0158: clobTest11(conn);
0159: clobTest12(conn);
0160: clobTest13Trigger(conn);
0161: clobTest2(conn);
0162: clobTest22(conn);
0163: clobTest3(conn);
0164: clobTest32(conn);
0165: clobTest4(conn);
0166: clobTest42(conn);
0167: clobTest51(conn);
0168: clobTest52(conn);
0169: clobTest53(conn);
0170: clobTest54(conn);
0171: clobTest6(conn);
0172: clobTest7(conn);
0173:
0174: clobTest8(conn);
0175:
0176: clobTest91(conn);
0177: clobTest92(conn);
0178: clobTest93(conn);
0179: clobTest94(conn);
0180: clobTest95(conn);
0181:
0182: // restart the connection
0183: conn = ij.startJBMS();
0184:
0185: // do not run these tests with DerbyNet
0186: if (!TestUtil.isJCCFramework()) {
0187: clobTest10(conn);
0188: clobTest14(conn);
0189: }
0190:
0191: conn.setAutoCommit(false);
0192: clobTest96(conn);
0193:
0194: prepareBlobTable(conn);
0195: prepareSearchBlobTable(conn);
0196:
0197: blobTest0(conn);
0198: blobTest2(conn);
0199: blobTest3(conn);
0200: blobTest4(conn);
0201: blobTest51(conn);
0202: blobTest52(conn);
0203: blobTest53(conn);
0204: blobTest54(conn);
0205: blobTest6(conn);
0206: blobTest7(conn);
0207: blobTest8Trigger(conn);
0208: blobTest91(conn);
0209: blobTest92(conn);
0210: blobTest93(conn);
0211: blobTest94(conn);
0212: blobTest95(conn);
0213:
0214: // restart the connection
0215: conn = ij.startJBMS();
0216: conn.setAutoCommit(false);
0217: blobTest96(conn);
0218:
0219: // do not run these tests with DerbyNet
0220: if (!TestUtil.isJCCFramework()) {
0221: blobTest10(conn);
0222: blobTest11(conn);
0223: }
0224:
0225: clobTestSelfDestructive(conn);
0226: clobTestSelfDestructive2(conn);
0227:
0228: conn.commit();
0229: clobNegativeTest_Derby265(conn);
0230: blobNegativeTest_Derby265(conn);
0231:
0232: // restart the connection for cleaning up
0233: conn = ij.startJBMS();
0234: String[] testObjects = { "table testclob_main",
0235: "table searchclob", "table testunicode",
0236: "table testunicode2", "table testclob10",
0237: "table testinteger", "table testclobcolumn",
0238: "table testclob2", "table testclob7",
0239: "table testlongrowclob", "table testblob",
0240: "table searchblob", "table testvarbinary",
0241: "table testinteger2", "table testblobcolumn",
0242: "table testblob2", "table testblobx",
0243: "table testlongrowblob", "table maps",
0244: "table maps_blob" };
0245: Statement stmt = conn.createStatement();
0246: TestUtil.cleanUpTest(stmt, testObjects);
0247: conn.close();
0248: System.out.println("FINISHED TEST blobclob :-)");
0249: } catch (SQLException e) {
0250: TestUtil.dumpSQLExceptions(e);
0251: if (debug)
0252: e.printStackTrace(System.out);
0253: } catch (Throwable e) {
0254: System.out.println("xFAIL -- unexpected exception:"
0255: + e.toString());
0256: // e.fillInStackTrace();
0257: if (debug)
0258: e.printStackTrace(System.out);
0259: }
0260: System.out.println("Test blobclob finished\n");
0261: }
0262:
0263: private static void insertRow(PreparedStatement ps, String s)
0264: throws SQLException {
0265: ps.clearParameters();
0266: ps.setString(1, s);
0267: ps.setInt(2, s.length());
0268: ps.executeUpdate();
0269: }
0270:
0271: private static void insertRow(PreparedStatement ps, String s, int i)
0272: throws SQLException {
0273: ps.setString(1, s);
0274: ps.setInt(2, s.length());
0275: ps.setInt(3, i);
0276: ps.executeUpdate();
0277: }
0278:
0279: private static void insertRow(PreparedStatement ps, byte[] b)
0280: throws SQLException, IOException {
0281: ps.setBytes(1, b);
0282: ps.setInt(2, b.length);
0283: ps.setLong(3, getStreamCheckSum(new ByteArrayInputStream(b)));
0284: ps.executeUpdate();
0285: }
0286:
0287: /*
0288: Set up a table with all kinds of CLOB values,
0289: some short (less than 1 page), some long (more than 1 page)
0290: some very large (many pages).
0291: Table has 2 cols: the first is the value, the second is the length of
0292: the value.
0293: (Also sets the fileLength array.)
0294: */
0295: private static void prepareCLOBMAIN(Connection conn) {
0296: System.out.println(START + "prepareCLOBMAIN");
0297: ResultSet rs;
0298: Statement stmt;
0299:
0300: try {
0301: stmt = conn.createStatement();
0302: stmt.execute(
0303: // creating table small then add large column - that way forcing table to have default small page size, but have large rows.
0304: "create table testCLOB_MAIN (b integer)");
0305: stmt
0306: .execute("alter table testCLOB_MAIN add column a CLOB(1M)");
0307: PreparedStatement ps = conn
0308: .prepareStatement("insert into testCLOB_MAIN (a, b) values(?,?)");
0309:
0310: // insert small strings
0311: insertRow(ps, "");
0312: insertRow(ps,
0313: "you can lead a horse to water but you can't form it into beverage");
0314: insertRow(ps, "a stitch in time says ouch");
0315: insertRow(ps, "here is a string with a return \n character");
0316:
0317: // insert larger strings using setAsciiStream
0318: for (int i = 0; i < numFiles; i++) {
0319: // prepare an InputStream from the file
0320: File file = new File(fileName[i]);
0321: fileLength[i] = file.length();
0322: /*
0323: System.out.println("inserting filename[" +i +
0324: "]" + basefileName[i] +
0325: " length: " + fileLength[i]);
0326: */
0327: InputStream fileIn = new FileInputStream(file);
0328:
0329: System.out.println("===> inserting " + basefileName[i]
0330: + " length = " + fileLength[i]);
0331:
0332: // insert a streaming column
0333: ps.setAsciiStream(1, fileIn, (int) fileLength[i]);
0334: ps.setInt(2, (int) fileLength[i]);
0335: ps.executeUpdate();
0336: ps.clearParameters();
0337: fileIn.close();
0338: }
0339:
0340: // insert a null
0341: ps.setNull(1, Types.CLOB);
0342: ps.setInt(2, 0);
0343: ps.executeUpdate();
0344:
0345: conn.commit();
0346:
0347: // set numRows
0348: rs = stmt
0349: .executeQuery("select count(*) from testCLOB_MAIN");
0350: int realNumRows = -1;
0351: if (rs.next())
0352: realNumRows = rs.getInt(1);
0353: if (realNumRows <= 0)
0354: System.out
0355: .println("FAIL. No rows in table testCLOB_MAIN");
0356: if (realNumRows != numRows)
0357: System.out.println("FAIL. numRows is incorrect");
0358: rs.close();
0359:
0360: } catch (SQLException e) {
0361: TestUtil.dumpSQLExceptions(e);
0362: if (debug)
0363: e.printStackTrace(System.out);
0364: } catch (Throwable e) {
0365: System.out.println("FAIL -- unexpected exception:"
0366: + e.toString());
0367: if (debug)
0368: e.printStackTrace(System.out);
0369: }
0370: //System.out.println("prepareCLOBMAIN finished");
0371: }
0372:
0373: /*
0374: Set up a table with clobs to search for
0375: most short (less than 1 page), some long (more than 1 page)
0376: some very large (many pages) ??
0377: */
0378: private static void prepareSearchClobTable(Connection conn) {
0379: System.out.println(START + "prepareSearchClobTable");
0380: ResultSet rs;
0381: Statement stmt;
0382:
0383: try {
0384: stmt = conn.createStatement();
0385: // creating table small then add large column - that way forcing table to have default small page size, but have large rows.
0386: stmt.execute("create table searchClob (b integer)");
0387: stmt
0388: .execute("alter table searchClob add column a CLOB(300k)");
0389: PreparedStatement ps = conn
0390: .prepareStatement("insert into searchClob (a, b) values(?,?)");
0391: insertRow(ps, "horse");
0392: insertRow(ps, "ouch");
0393: insertRow(ps, "\n");
0394: insertRow(ps, "");
0395: insertRow(ps, "Beginning");
0396: insertRow(ps, "position-69");
0397: insertRow(ps, "I-am-hiding-here-at-position-5910");
0398: insertRow(ps, "Position-9907");
0399:
0400: // insert larger strings using setAsciiStream
0401: for (int i = 0; i < numFiles; i++) {
0402: // prepare an InputStream from the file
0403: File file = new File(fileName[i]);
0404: fileLength[i] = file.length();
0405: InputStream fileIn = new FileInputStream(file);
0406:
0407: /*
0408: System.out.println("inserting filename[" +i +
0409: "]" + basefileName[i] +
0410: " length: " + fileLength[i]);
0411: */
0412: System.out.println("===> inserting " + basefileName[i]
0413: + " length = " + fileLength[i]);
0414:
0415: // insert a streaming column
0416:
0417: ps.setAsciiStream(1, fileIn, (int) fileLength[i]);
0418: ps.setInt(2, (int) fileLength[i]);
0419: ps.executeUpdate();
0420: ps.clearParameters();
0421: fileIn.close();
0422: }
0423:
0424: // insert a null
0425: ps.setNull(1, Types.CLOB);
0426: ps.setInt(2, 0);
0427: ps.executeUpdate();
0428:
0429: conn.commit();
0430: } catch (SQLException e) {
0431: TestUtil.dumpSQLExceptions(e);
0432: if (debug)
0433: e.printStackTrace(System.out);
0434: } catch (Throwable e) {
0435: System.out.println("FAIL -- unexpected exception:"
0436: + e.toString());
0437: if (debug)
0438: e.printStackTrace(System.out);
0439: }
0440: System.out.println("prepareSearchClobTable finished");
0441: }
0442:
0443: /*
0444: Set up a table with unicode strings in it
0445: some short (less than 1 page), some long (more than 1 page)
0446: Table has 3 cols: the first is the value, the second is the length of
0447: the value, the third is the array index (or else -1 for the ones from files).
0448: (Also sets the fileLength array.)
0449: Try slurping the thing into a String.
0450: */
0451: private static void prepareUnicodeTable(Connection conn) {
0452: ResultSet rs;
0453: Statement stmt;
0454: System.out.println(START + "prepareUnicodeTable");
0455: try {
0456: stmt = conn.createStatement();
0457: // creating table small then add large column - that way forcing table to have default small page size, but have large rows.
0458: stmt
0459: .execute("create table testUnicode (b integer, c integer)");
0460: stmt
0461: .execute("alter table testUnicode add column a CLOB(100k)");
0462: PreparedStatement ps = conn.prepareStatement(
0463: // "insert into testUnicode values(?,?,?)");
0464: "insert into testUnicode (a, b, c) values(?,?,?)");
0465:
0466: // insert small strings
0467:
0468: for (int i = 0; i < numStrings; i++) {
0469: insertRow(ps, unicodeStrings[i], i);
0470: }
0471:
0472: StringBuffer sb = new StringBuffer(5000);
0473: for (int i = 0; i < 5000; i++)
0474: sb.append('q');
0475: String largeString = new String(sb);
0476:
0477: // insert larger strings
0478: for (int i = 0; i < numStrings; i++) {
0479: insertRow(ps, unicodeStrings[i] + largeString
0480: + unicodeStrings[i] + "pppppppppp", i);
0481: }
0482: conn.commit();
0483:
0484: // set numRows
0485: rs = stmt.executeQuery("select count(*) from testUnicode");
0486: int realNumRows = -1;
0487: if (rs.next())
0488: realNumRows = rs.getInt(1);
0489: if (realNumRows <= 0)
0490: System.out
0491: .println("FAIL. No rows in table testUnicode");
0492: if (realNumRows != numRowsUnicode)
0493: System.out.println("FAIL. numRowsUnicode is incorrect");
0494:
0495: } catch (SQLException e) {
0496: TestUtil.dumpSQLExceptions(e);
0497: } catch (Throwable e) {
0498: System.out.println("FAIL -- unexpected exception:"
0499: + e.toString());
0500: if (debug)
0501: e.printStackTrace(System.out);
0502: }
0503:
0504: }
0505:
0506: /*
0507: Tests PreparedStatement.setCharacterStream
0508: */
0509: private static void setCharacterStreamTest(Connection conn) {
0510: ResultSet rs;
0511: Statement stmt;
0512: System.out.println(START + "setCharacterStreamTest");
0513: try {
0514: stmt = conn.createStatement();
0515: // forcing table with default table space.
0516: stmt
0517: .execute("call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.storage.pageSize','4096')");
0518: stmt.execute("create table testUnicode2 (a CLOB(100k))");
0519: stmt
0520: .execute("call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.storage.pageSize','0')");
0521: PreparedStatement ps = conn
0522: .prepareStatement("insert into testUnicode2 values(?)");
0523:
0524: // insert large string using setCharacterStream
0525: // prepare an InputStream from the file
0526: File file = new File(unicodeFileName);
0527: InputStream fileIS = new FileInputStream(file);
0528: Reader filer = new InputStreamReader(fileIS, "UTF8");
0529: // insert a streaming column
0530: ps.setCharacterStream(1, filer, 5009);
0531: ps.executeUpdate();
0532: filer.close();
0533: conn.commit();
0534:
0535: rs = stmt.executeQuery("select a from testUnicode2");
0536: while (rs.next()) {
0537: Clob clob = rs.getClob(1);
0538: System.out
0539: .println("Length of clob is " + clob.length());
0540: Reader r = clob.getCharacterStream();
0541: char[] buf = new char[3];
0542: for (int i = 0; i < numStrings; i++) {
0543: r.read(buf);
0544: if (unicodeStrings[i].equals(new String(buf)))
0545: System.out.println("unicode string " + i
0546: + " matched");
0547: else
0548: System.out.println("unicode string " + i
0549: + " not matched");
0550: }
0551: for (int i = 0; i < 5000; i++) {
0552: int c = r.read();
0553: if (c == -1) {
0554: System.out.println("EOF reached at i = " + i);
0555: break;
0556: }
0557: if ((char) c != 'p') {
0558: System.out.println("A p was missed, got a "
0559: + (char) c);
0560: }
0561: }
0562: if (r.read() != -1)
0563: System.out.println("EOF was missed");
0564: else
0565: System.out.println("EOF matched");
0566: }
0567: conn.commit();
0568:
0569: System.out.println("setCharacterStreamTest finished");
0570: } catch (SQLException e) {
0571: TestUtil.dumpSQLExceptions(e);
0572: } catch (Throwable e) {
0573: System.out.println("FAIL -- unexpected exception:"
0574: + e.toString());
0575: if (debug)
0576: e.printStackTrace(System.out);
0577: }
0578: }
0579:
0580: /*
0581: Make a file with unicode stuff in it.
0582: */
0583: private static void prepareUnicodeFile(Connection conn) {
0584: System.out.println(START + "prepareUnicodeFile");
0585: try {
0586: File file = new File(unicodeFileName);
0587: OutputStream fos = new FileOutputStream(file);
0588: Writer filew = new OutputStreamWriter(fos, "UTF8");
0589: // FileWriter filew = new FileWriter(file);
0590: filew.write(unicodeStrings[0]);
0591: filew.write(unicodeStrings[1]);
0592: filew.write(unicodeStrings[2]);
0593: for (int i = 0; i < 5000; i++)
0594: filew.write('p');
0595: filew.close();
0596:
0597: InputStream fis = new FileInputStream(file);
0598: Reader filer = new InputStreamReader(fis, "UTF8");
0599: // FileReader filer = new FileReader(file);
0600: char bufs[][] = new char[numStrings][3];
0601: for (int i = 0; i < numStrings; i++) {
0602: filer.read(bufs[i]);
0603: String s = new String(bufs[i]);
0604: if (s.equals(unicodeStrings[i]))
0605: System.out.println("unicode string " + i
0606: + " correct");
0607: else
0608: System.out.println("FAILED: unicode string " + i
0609: + " incorrect");
0610: }
0611: for (int i = 0; i < 5000; i++)
0612: if (filer.read() != 'p')
0613: System.out.println("Not a p : i = " + i);
0614: if (filer.read() != -1)
0615: System.out.println("Not EOF");
0616: filer.close();
0617: System.out.println("Finished prepareUnicodeFile");
0618: } catch (Throwable e) {
0619: System.out.println("FAIL -- unexpected exception:"
0620: + e.toString());
0621: if (debug)
0622: e.printStackTrace(System.out);
0623: }
0624: }
0625:
0626: /*
0627: basic test of getAsciiStream
0628: also tests length
0629: need to run prepareCLOBMAIN first
0630: */
0631: private static void clobTest0(Connection conn) {
0632: ResultSet rs;
0633: Statement stmt;
0634: System.out.println(START + "clobTest0");
0635: try {
0636: stmt = conn.createStatement();
0637: rs = stmt.executeQuery("select a,b from testCLOB_MAIN");
0638: byte[] buff = new byte[128];
0639: // fetch row back, get the column as a clob.
0640: Clob clob;
0641: int clobLength, i = 0;
0642: while (rs.next()) {
0643: i++;
0644: // get the first column in select as a clob
0645: clob = rs.getClob(1);
0646: if (clob == null)
0647: continue;
0648: InputStream fin = clob.getAsciiStream();
0649: int columnSize = 0;
0650: for (;;) {
0651: int size = fin.read(buff);
0652: if (size == -1)
0653: break;
0654: columnSize += size;
0655: }
0656: clobLength = rs.getInt(2);
0657:
0658: if (columnSize != clobLength)
0659: System.out
0660: .println("test failed, columnSize should be "
0661: + clobLength
0662: + ", but it is "
0663: + columnSize + ", i = " + i);
0664: if (columnSize != clob.length()) {
0665: System.out
0666: .println("test failed, clob.length() should be "
0667: + columnSize
0668: + ", but it is "
0669: + clob.length() + ", i = " + i);
0670: }
0671: }
0672: rs.close();
0673: conn.commit();
0674: System.out.println("clobTest0 finished");
0675: } catch (SQLException e) {
0676: TestUtil.dumpSQLExceptions(e);
0677: } catch (Throwable e) {
0678: System.out.println("FAIL -- unexpected exception:"
0679: + e.toString());
0680: if (debug)
0681: e.printStackTrace(System.out);
0682: }
0683: }
0684:
0685: /*
0686: basic test of getCharacterStream
0687: also tests length
0688: need to run prepareCLOBMAIN first
0689: */
0690: private static void clobTest11(Connection conn) {
0691:
0692: ResultSetMetaData met;
0693: ResultSet rs;
0694: Statement stmt;
0695: System.out.println(START + "clobTest1");
0696: try {
0697: stmt = conn.createStatement();
0698: rs = stmt.executeQuery("select a,b from testCLOB_MAIN");
0699: met = rs.getMetaData();
0700: char[] buff = new char[128];
0701: // fetch row back, get the column as a clob.
0702: int i = 0, clobLength = 0;
0703: while (rs.next()) {
0704: i++;
0705: // get the first column as a clob
0706: Clob clob = rs.getClob(1);
0707: if (clob == null)
0708: continue;
0709: Reader reader = clob.getCharacterStream();
0710: int columnSize = 0;
0711: for (;;) {
0712: int size = reader.read(buff);
0713: if (size == -1)
0714: break;
0715: // System.out.println("the next buffer is :" + buff);
0716: columnSize += size;
0717: }
0718: clobLength = rs.getInt(2);
0719: if (columnSize != clobLength)
0720: System.out
0721: .println("test failed, columnSize should be "
0722: + clobLength
0723: + ", but it is "
0724: + columnSize + ", i = " + i);
0725: if (columnSize != clob.length())
0726: System.out
0727: .println("test failed, clob.length() should be "
0728: + columnSize
0729: + ", but it is "
0730: + clob.length() + ", i = " + i);
0731:
0732: }
0733: rs.close();
0734: conn.commit();
0735: System.out.println("clobTest11 finished");
0736: } catch (SQLException e) {
0737: TestUtil.dumpSQLExceptions(e);
0738: } catch (Throwable e) {
0739: System.out.println("FAIL -- unexpected exception:"
0740: + e.toString());
0741: if (debug)
0742: e.printStackTrace(System.out);
0743: }
0744: }
0745:
0746: /*
0747: test of getCharacterStream on a table containing unicode characters
0748: need to run prepareUnicodeTable first
0749: */
0750: private static void clobTest12(Connection conn) {
0751: ResultSet rs;
0752: Statement stmt;
0753: System.out.println(START + "clobTest12");
0754: try {
0755: stmt = conn.createStatement();
0756: rs = stmt.executeQuery("select a,b,c from testUnicode");
0757: int i = 0, colLength = 0, arrayIndex = 0;
0758: while (rs.next()) {
0759: i++;
0760: colLength = rs.getInt(2);
0761: arrayIndex = rs.getInt(3);
0762: Clob clob = rs.getClob(1);
0763: if (clob == null) {
0764: System.out
0765: .println("row " + i + " is null, skipped");
0766: continue;
0767: }
0768: Reader reader = clob.getCharacterStream();
0769:
0770: int columnSize = 0, c;
0771: String compareString = "";
0772: for (;;) {
0773: c = reader.read();
0774: if (c == -1)
0775: break;
0776: if (columnSize < 3)
0777: compareString += (char) c;
0778: columnSize++;
0779: }
0780: if (compareString.equals(unicodeStrings[arrayIndex]))
0781: System.out.println("Succeeded to match, row " + i);
0782: else {
0783: System.out.println("Failed to match, row " + i
0784: + ". compareString = " + compareString
0785: + ". arrayIndex = " + arrayIndex
0786: + ". unicodeStrings[arrayIndex] = "
0787: + unicodeStrings[arrayIndex]);
0788:
0789: }
0790: if (columnSize != colLength)
0791: System.out
0792: .println("test failed, columnSize should be "
0793: + colLength
0794: + ", but it is "
0795: + columnSize + ", i = " + i);
0796: else
0797: System.out.println("PASSED, row " + i
0798: + ", length was " + columnSize);
0799: }
0800: conn.commit();
0801: System.out.println("clobTest12 finished");
0802: } catch (SQLException e) {
0803: TestUtil.dumpSQLExceptions(e);
0804: } catch (Throwable e) {
0805: System.out.println("FAIL -- unexpected exception:"
0806: + e.toString());
0807: if (debug)
0808: e.printStackTrace(System.out);
0809: }
0810: }
0811:
0812: /**
0813: * Test triggers on CLOB columns.
0814: */
0815: private static void clobTest13Trigger(Connection conn) {
0816: System.out.println(START + "clobTest13Trigger");
0817: try {
0818: Statement stmt = conn.createStatement();
0819: stmt
0820: .executeUpdate("CREATE TABLE clobTest13TriggerA (a CLOB(400k), b int)");
0821: stmt
0822: .executeUpdate("CREATE TABLE clobTest13TriggerB (a CLOB(400k), b int)");
0823: stmt
0824: .executeUpdate("create trigger T13A after update on testCLOB_MAIN "
0825: + "referencing new as n old as o "
0826: + "for each row mode db2sql "
0827: + "insert into clobTest13TriggerA(a, b) values (n.a, n.b)");
0828: stmt
0829: .executeUpdate("create trigger T13B after INSERT on clobTest13TriggerA "
0830: + "referencing new_table as n "
0831: + "for each statement mode db2sql "
0832: + "insert into clobTest13TriggerB(a, b) select n.a, n.b from n");
0833:
0834: conn.commit();
0835: ResultSet rs = stmt
0836: .executeQuery("select a,length(a),b from testCLOB_MAIN order by b");
0837:
0838: showClobContents("testCLOB_MAIN", rs);
0839:
0840: rs.close();
0841: conn.commit();
0842: int rowCount = stmt
0843: .executeUpdate("UPDATE testCLOB_MAIN set b = b + 0");
0844: System.out.println("main update row count :" + rowCount);
0845: conn.commit();
0846: rs = stmt
0847: .executeQuery("select a,length(a),b from clobTest13TriggerA order by b");
0848: showClobContents("row trigger", rs);
0849: rs.close();
0850: conn.commit();
0851:
0852: rs = stmt
0853: .executeQuery("select a,length(a),b from clobTest13TriggerB order by b");
0854: showClobContents("statement trigger", rs);
0855: rs.close();
0856: conn.commit();
0857:
0858: stmt.executeUpdate("DROP TRIGGER T13A");
0859: stmt.executeUpdate("DROP TABLE clobTest13TriggerB");
0860: stmt.executeUpdate("DROP TABLE clobTest13TriggerA");
0861:
0862: stmt.close();
0863: conn.commit();
0864: System.out.println("clobTest13Trigger finished");
0865: } catch (SQLException e) {
0866: TestUtil.dumpSQLExceptions(e);
0867: do {
0868: e.printStackTrace(System.out);
0869: e = e.getNextException();
0870: } while (e != null);
0871:
0872: } catch (Throwable e) {
0873: System.out.println("FAIL -- unexpected exception:"
0874: + e.toString());
0875: if (debug)
0876: e.printStackTrace(System.out);
0877: }
0878:
0879: }
0880:
0881: /*
0882: test getSubString
0883: need to run prepareCLOBMAIN first
0884: */
0885: private static void clobTest2(Connection conn) {
0886: ResultSet rs;
0887: Statement stmt;
0888: System.out.println(START + "clobTest2");
0889: try {
0890: stmt = conn.createStatement();
0891: rs = stmt.executeQuery("select a,b from testCLOB_MAIN");
0892: int i = 0, clobLength = 0;
0893: Clob clob;
0894: while (rs.next()) {
0895: i++;
0896: clob = rs.getClob(1);
0897: if (clob == null)
0898: continue;
0899: clobLength = rs.getInt(2);
0900: blobclob4BLOB.printInterval(clob, 9905, 50, 0, i,
0901: clobLength);
0902: blobclob4BLOB.printInterval(clob, 5910, 150, 1, i,
0903: clobLength);
0904: blobclob4BLOB.printInterval(clob, 5910, 50, 2, i,
0905: clobLength);
0906: blobclob4BLOB.printInterval(clob, 204, 50, 3, i,
0907: clobLength);
0908: blobclob4BLOB.printInterval(clob, 68, 50, 4, i,
0909: clobLength);
0910: blobclob4BLOB.printInterval(clob, 1, 50, 5, i,
0911: clobLength);
0912: blobclob4BLOB.printInterval(clob, 1, 1, 6, i,
0913: clobLength);
0914: blobclob4BLOB.printInterval(clob, 1, 0, 7, i,
0915: clobLength); // length 0 at start
0916: blobclob4BLOB.printInterval(clob, clobLength + 1, 0, 8,
0917: i, clobLength); // and end
0918: /*
0919: System.out.println(i + "(0) " + clob.getSubString(9905,50));
0920: System.out.println(i + "(1) " + clob.getSubString(5910,150));
0921: System.out.println(i + "(2) " + clob.getSubString(5910,50));
0922: System.out.println(i + "(3) " + clob.getSubString(204,50));
0923: System.out.println(i + "(4) " + clob.getSubString(68,50));
0924: System.out.println(i + "(5) " + clob.getSubString(1,50));
0925: System.out.println(i + "(6) " + clob.getSubString(1,1));
0926: */
0927: if (clobLength > 100) {
0928: String res = clob
0929: .getSubString(clobLength - 99, 200);
0930: System.out.println(i + "(9) ");
0931: if (res.length() != 100)
0932: System.out
0933: .println("FAIL : length of substring is "
0934: + res.length()
0935: + " should be 100");
0936: else
0937: System.out.println(res);
0938: }
0939: }
0940: rs.close();
0941: System.out.println("clobTest2 finished");
0942: } catch (SQLException e) {
0943: TestUtil.dumpSQLExceptions(e);
0944: } catch (Throwable e) {
0945: System.out.println("FAIL -- unexpected exception:"
0946: + e.toString());
0947: if (debug)
0948: e.printStackTrace(System.out);
0949: }
0950: }
0951:
0952: /*
0953: test getSubString with unicode
0954: need to run prepareUnicodeTable first
0955: */
0956: private static void clobTest22(Connection conn) {
0957: ResultSet rs;
0958: Statement stmt;
0959: System.out.println(START + "clobTest22");
0960: try {
0961: stmt = conn.createStatement();
0962: rs = stmt.executeQuery("select a,b,c from testUnicode");
0963: int i = 0, clobLength = 0, arrayIndex = 0;
0964: Clob clob;
0965: while (rs.next()) {
0966: i++;
0967: System.out.print("Row " + i + " : ");
0968: clob = rs.getClob(1);
0969: if (clob == null)
0970: continue;
0971: clobLength = rs.getInt(2);
0972: arrayIndex = rs.getInt(3);
0973: if (clob.getSubString(1, 3).equals(
0974: unicodeStrings[arrayIndex]))
0975: System.out.println("Succeeded");
0976: else
0977: System.out.println("Failed");
0978: if (clobLength > 5000) {
0979: if (clob.getSubString(5004, 3).equals(
0980: unicodeStrings[arrayIndex]))
0981: System.out.println("Second time Succeeded");
0982: else
0983: System.out.println("Second time Failed");
0984: }
0985: }
0986: System.out.println("clobTest22 finished");
0987: } catch (SQLException e) {
0988: TestUtil.dumpSQLExceptions(e);
0989: } catch (Throwable e) {
0990: System.out.println("FAIL -- unexpected exception:"
0991: + e.toString());
0992: if (debug)
0993: e.printStackTrace(System.out);
0994: }
0995: }
0996:
0997: /*
0998: test position with a String argument
0999: need to run prepareCLOBMAIN first
1000: */
1001: private static void clobTest3(Connection conn) {
1002: ResultSet rs;
1003: Statement stmt;
1004: System.out.println(START + "clobTest3");
1005: try {
1006: stmt = conn.createStatement();
1007: rs = stmt.executeQuery("select a,b from testCLOB_MAIN");
1008: int i = 0, clobLength = 0;
1009: Clob clob;
1010: while (rs.next()) {
1011: i++;
1012: clob = rs.getClob(1);
1013: if (clob == null)
1014: continue;
1015: clobLength = rs.getInt(2);
1016: if (clobLength > 20000)
1017: continue;
1018: blobclob4BLOB.printPosition(i, "horse", 1, clob,
1019: clobLength);
1020: blobclob4BLOB.printPosition(i, "ouch", 1, clob,
1021: clobLength);
1022: blobclob4BLOB.printPosition(i, "\n", 1, clob,
1023: clobLength);
1024: blobclob4BLOB.printPosition(i, "", 1, clob, clobLength);
1025: blobclob4BLOB.printPosition(i, "Beginning", 1, clob,
1026: clobLength);
1027: blobclob4BLOB.printPosition(i, "Beginning", 2, clob,
1028: clobLength);
1029: blobclob4BLOB.printPosition(i, "position-69", 1, clob,
1030: clobLength);
1031: blobclob4BLOB.printPosition(i, "This-is-position-204",
1032: 1, clob, clobLength);
1033: blobclob4BLOB.printPosition(i,
1034: "I-am-hiding-here-at-position-5910", 1, clob,
1035: clobLength);
1036: blobclob4BLOB.printPosition(i,
1037: "I-am-hiding-here-at-position-5910", 5910,
1038: clob, clobLength);
1039: blobclob4BLOB.printPosition(i,
1040: "I-am-hiding-here-at-position-5910", 5911,
1041: clob, clobLength);
1042: blobclob4BLOB.printPosition(i, "Position-9907", 1,
1043: clob, clobLength);
1044: }
1045: rs.close();
1046: System.out.println("clobTest3 finished");
1047: } catch (SQLException e) {
1048: TestUtil.dumpSQLExceptions(e);
1049: } catch (Throwable e) {
1050: System.out.println("FAIL -- unexpected exception:"
1051: + e.toString());
1052: if (debug)
1053: e.printStackTrace(System.out);
1054: }
1055: }
1056:
1057: /*
1058: test position with a unicode String argument
1059: need to run prepareUnicodeTable first
1060: */
1061: private static void clobTest32(Connection conn) {
1062: ResultSet rs;
1063: Statement stmt;
1064: System.out.println(START + "clobTest32");
1065: try {
1066: stmt = conn.createStatement();
1067: rs = stmt.executeQuery("select a,b,c from testUnicode");
1068: int i = 0, clobLength = 0, arrayIndex = 0;
1069: long pos = 0;
1070: Clob clob;
1071: while (rs.next()) {
1072: i++;
1073: clob = rs.getClob(1);
1074: if (clob == null)
1075: continue;
1076: clobLength = rs.getInt(2);
1077: arrayIndex = rs.getInt(3);
1078:
1079: pos = clob.position(unicodeStrings[arrayIndex], 1);
1080: if (pos == 1)
1081: System.out
1082: .println("Succeeded: Found unicode string "
1083: + arrayIndex + " at position "
1084: + pos + ",row " + i);
1085: else
1086: System.out.println("Failed: Found unicode string "
1087: + arrayIndex + " at position " + pos
1088: + ",row " + i);
1089:
1090: pos = clob.position(unicodeStrings[arrayIndex], 4000);
1091: if (pos == 5004 || (pos == -1 && clobLength < 4000))
1092: System.out
1093: .println("Succeeded: Found unicode string "
1094: + arrayIndex + " at position "
1095: + pos + ",row " + i);
1096: else
1097: System.out.println("Failed: Found unicode string "
1098: + arrayIndex + " at position " + pos
1099: + ",row " + i);
1100: }
1101: System.out.println("clobTest32 finished");
1102: } catch (SQLException e) {
1103: TestUtil.dumpSQLExceptions(e);
1104: } catch (Throwable e) {
1105: System.out.println("FAIL -- unexpected exception:"
1106: + e.toString());
1107: if (debug)
1108: e.printStackTrace(System.out);
1109: }
1110: }
1111:
1112: /*
1113: test position with a Clob argument
1114: need to run prepareCLOBMAIN and prepareSearchClobTable first
1115: */
1116: private static void clobTest4(Connection conn) {
1117: ResultSet rs, rs2;
1118: Statement stmt, stmt2;
1119: System.out.println(START + "clobTest4");
1120: try {
1121: stmt = conn.createStatement();
1122: rs = stmt.executeQuery("select a,b from testCLOB_MAIN");
1123: int i = 0, clobLength = 0;
1124: Clob clob;
1125: while (rs.next()) {
1126: i++;
1127: clob = rs.getClob(1);
1128: if (clob == null)
1129: continue;
1130: clobLength = rs.getInt(2);
1131: if (clobLength > 20000) {
1132: System.out.println("testCLOB_MAIN row " + i
1133: + " skipped (too large)");
1134: continue;
1135: }
1136: // inner loop over table of clobs to search for
1137: // clobs
1138: stmt2 = conn.createStatement();
1139: rs2 = stmt2.executeQuery("select a,b from searchClob");
1140: int j = 0, clobLength2 = 0;
1141: Clob searchClob;
1142: String searchStr;
1143: while (rs2.next()) {
1144: j++;
1145: searchClob = rs2.getClob(1);
1146: if (searchClob == null)
1147: continue;
1148: clobLength2 = rs2.getInt(2);
1149: if (clobLength2 > 20000) {
1150: System.out.println("searchClob row " + j
1151: + " skipped (too large)");
1152: continue;
1153: }
1154: if (clobLength2 < 150)
1155: searchStr = rs2.getString(1);
1156: else
1157: searchStr = null;
1158:
1159: printPositionClob(i, searchStr, 1, clob, j,
1160: searchClob);
1161: }
1162: }
1163: rs.close();
1164: System.out.println("clobTest4 finished");
1165: } catch (SQLException e) {
1166: TestUtil.dumpSQLExceptions(e);
1167: if (debug)
1168: e.printStackTrace(System.out);
1169: } catch (Throwable e) {
1170: System.out.println("FAIL -- unexpected exception:"
1171: + e.toString());
1172: if (debug)
1173: e.printStackTrace(System.out);
1174: }
1175: }
1176:
1177: /*
1178: test position with a Clob argument containing unicode characters
1179: need to run prepareCLOBMAIN and prepareSearchClobTable first
1180: */
1181: private static void clobTest42(Connection conn) {
1182: ResultSet rs;
1183: Statement stmt;
1184: System.out.println(START + "clobTest42");
1185: try {
1186: stmt = conn.createStatement();
1187: rs = stmt.executeQuery("select a,b,c from testUnicode");
1188: Clob[] clobArray = new Clob[numRowsUnicode];
1189: int i = 0;
1190: long pos = 0;
1191: while (rs.next()) {
1192: clobArray[i++] = rs.getClob(1);
1193: }
1194:
1195: for (int j = 0; j < 3; j++) {
1196: pos = clobArray[j + 3].position(clobArray[j], 1);
1197: if (pos == 1)
1198: System.out
1199: .println("Succeeded: Found clob at position "
1200: + pos + ",row " + j);
1201: else
1202: System.out
1203: .println("Failed: Found clob at position "
1204: + pos + ",row " + j);
1205: // pos = clobArray[i*2].position(clobArray[i*3],1);
1206: }
1207: System.out.println("clobTest42 finished");
1208: } catch (SQLException e) {
1209: TestUtil.dumpSQLExceptions(e);
1210: } catch (Throwable e) {
1211: System.out.println("FAIL -- unexpected exception:"
1212: + e.toString());
1213: if (debug)
1214: e.printStackTrace(System.out);
1215: }
1216: }
1217:
1218: private static void printPositionClob(int rowNum, String searchStr,
1219: long position, Clob clob, int searchRowNum, Clob searchClob) {
1220: try {
1221: long result = clob.position(searchClob, position);
1222: if ("".equals(searchStr) && (result == 1)) {
1223: System.out
1224: .println("position(clob) FOUND @ 1 with empty search clob in clob of length "
1225: + clob.length());
1226: return;
1227: }
1228: if (result != -1) {
1229: System.out.print("Found ");
1230: if (searchStr != null)
1231: System.out.print(searchStr);
1232: else
1233: System.out
1234: .print("clob (row " + searchRowNum + ") ");
1235: System.out.println(" in row " + rowNum
1236: + " at position " + result);
1237: } else {
1238: System.out
1239: .println("position(clob) NOT FOUND "
1240: + rowNum
1241: + " searchStr "
1242: + (searchStr != null ? searchStr
1243: : ">150chars"));
1244: }
1245: } catch (SQLException e) {
1246: TestUtil.dumpSQLExceptions(e);
1247: }
1248: }
1249:
1250: /* datatype tests */
1251:
1252: // make sure clobs work for small CLOB fields
1253: // also test length method
1254: private static void clobTest51(Connection conn) {
1255:
1256: ResultSetMetaData met;
1257: ResultSet rs;
1258: Statement stmt;
1259: System.out.println(START + "clobTest51");
1260: try {
1261: stmt = conn.createStatement();
1262: stmt.execute("create table testCLOB10 (a CLOB(10))");
1263:
1264: PreparedStatement ps = conn
1265: .prepareStatement("insert into testCLOB10 values(?)");
1266: String val = "";
1267: for (int i = 0; i < 10; i++) {
1268: // insert a string
1269: ps.setString(1, val);
1270: ps.executeUpdate();
1271: val += "x";
1272: }
1273:
1274: rs = stmt.executeQuery("select a from testCLOB10");
1275: met = rs.getMetaData();
1276: byte[] buff = new byte[128];
1277: int j = 0;
1278: // fetch all rows back, get the columns as clobs.
1279: while (rs.next()) {
1280: // get the first column as a clob
1281: Clob clob = rs.getClob(1);
1282: if (clob == null)
1283: continue;
1284: InputStream fin = clob.getAsciiStream();
1285: int columnSize = 0;
1286: for (;;) {
1287: int size = fin.read(buff);
1288: if (size == -1)
1289: break;
1290: columnSize += size;
1291: }
1292: if (columnSize != j)
1293: System.out.println("FAIL - Expected clob size : "
1294: + j + " Got clob size : " + columnSize);
1295: if (clob.length() != j)
1296: System.out
1297: .println("FAIL - Expected clob length : "
1298: + j + " Got clob length : "
1299: + clob.length());
1300: j++;
1301: }
1302: System.out.println("clobTest51 finished");
1303: } catch (SQLException e) {
1304: if (isDerbyNet)
1305: System.out.println("EXPECTED SQL Exception: "
1306: + e.getMessage());
1307: else
1308: TestUtil.dumpSQLExceptions(e);
1309: } catch (Throwable e) {
1310: System.out.println("FAIL -- unexpected exception:"
1311: + e.toString());
1312: if (debug)
1313: e.printStackTrace(System.out);
1314: }
1315: }
1316:
1317: // make sure cannot get a clob from an int column
1318: private static void clobTest52(Connection conn) {
1319:
1320: ResultSetMetaData met;
1321: ResultSet rs;
1322: Statement stmt;
1323:
1324: try {
1325: System.out.println(START + "clobTest52");
1326: stmt = conn.createStatement();
1327: System.out.println("create table testInteger (a integer)");
1328: stmt.execute("create table testInteger (a integer)");
1329:
1330: int i = 1;
1331: System.out.println("insert into testInteger values('158')");
1332: PreparedStatement ps = conn
1333: .prepareStatement("insert into testInteger values(158)");
1334: ps.executeUpdate();
1335:
1336: System.out.println("select a from testInteger");
1337: rs = stmt.executeQuery("select a from testInteger");
1338: met = rs.getMetaData();
1339: while (rs.next()) {
1340: // get the first column as a clob
1341: System.out.println("getClob(1)");
1342: Clob clob = rs.getClob(1);
1343: if (clob == null)
1344: System.out.println("clob is null");
1345: else
1346: System.out.println("clob is not null");
1347: }
1348: System.out.println("clobTest52 finished");
1349: } catch (SQLException e) {
1350: System.out.println("52: SQLException");
1351: if (isDerbyNet)
1352: System.out.println("EXPECTED SQL Exception: "
1353: + e.getMessage());
1354: else
1355: TestUtil.dumpSQLExceptions(e);
1356: } catch (Throwable e) {
1357: System.out.println("52: Throwable");
1358: System.out.println("FAIL -- unexpected exception:"
1359: + e.toString());
1360: if (debug)
1361: e.printStackTrace(System.out);
1362: }
1363: }
1364:
1365: // test creating a clob column, currently this doesn't work since we don't
1366: // have a clob datatype (get a syntax error on the create table statement)
1367: private static void clobTest53(Connection conn) {
1368:
1369: ResultSetMetaData met;
1370: ResultSet rs;
1371: Statement stmt;
1372: System.out.println(START + "clobTest53");
1373: try {
1374: stmt = conn.createStatement();
1375: stmt.execute("create table testClobColumn (a clob(1K))");
1376:
1377: System.out.println("clobTest53 finished");
1378: } catch (SQLException e) {
1379: TestUtil.dumpSQLExceptions(e);
1380: } catch (Throwable e) {
1381: System.out.println("FAIL -- unexpected exception:"
1382: + e.toString());
1383: if (debug)
1384: e.printStackTrace(System.out);
1385: }
1386: }
1387:
1388: /*
1389: make sure setClob doesn't work on an int column
1390: need to run prepareCLOBMAIN first
1391: */
1392: private static void clobTest54(Connection conn) {
1393: ResultSet rs;
1394: Statement stmt1, stmt2;
1395: System.out.println(START + "clobTest54");
1396: try {
1397: stmt1 = conn.createStatement();
1398: stmt1
1399: .execute("create table testClob2 (a integer, b integer)");
1400: PreparedStatement ps = conn
1401: .prepareStatement("insert into testClob2 values(?,?)");
1402: stmt2 = conn.createStatement();
1403: rs = stmt2.executeQuery("select a,b from testCLOB_MAIN");
1404: Clob clob;
1405: int clobLength;
1406: while (rs.next()) {
1407: // get the first ncolumn as a clob
1408: clob = rs.getClob(1);
1409: if (clob == null)
1410: continue;
1411: clobLength = rs.getInt(2);
1412: ps.setClob(1, clob);
1413: ps.setInt(2, clobLength);
1414: ps.executeUpdate();
1415: }
1416: rs.close();
1417: conn.commit();
1418:
1419: System.out.println("clobTest54 finished");
1420: } catch (SQLException e) {
1421: // Can't do a setClob on an int column. This is expected
1422: TestUtil.dumpSQLExceptions(e, true);
1423: } catch (Throwable e) {
1424: System.out.println("FAIL -- unexpected exception:"
1425: + e.toString());
1426: if (debug)
1427: e.printStackTrace(System.out);
1428: }
1429: System.out.println("end clobTest54");
1430: }
1431:
1432: /*
1433: test raising of exceptions
1434: need to run prepareCLOBMAIN first
1435: */
1436: private static void clobTest6(Connection conn) {
1437: ResultSet rs;
1438: Statement stmt;
1439: System.out.println(START + "clobTest6");
1440: try {
1441: stmt = conn.createStatement();
1442: rs = stmt.executeQuery("select a,b from testCLOB_MAIN");
1443: int i = 0, clobLength = 0;
1444: Clob clob;
1445: rs.next();
1446: clob = rs.getClob(1);
1447: clobLength = rs.getInt(2);
1448: rs.close();
1449: if (clob == null)
1450: return;
1451:
1452: // 0 or negative position value
1453: try {
1454: clob.getSubString(0, 5);
1455: System.out.println("FAIL = clob.getSubString(0,5)");
1456: } catch (SQLException e) {
1457: boolean isExpected = isOutOfBoundException(e);
1458:
1459: TestUtil.dumpSQLExceptions(e, isExpected);
1460: }
1461:
1462: // negative length value
1463: try {
1464: clob.getSubString(1, -76);
1465: System.out.println("FAIL = getSubString(1,-76)");
1466: } catch (SQLException e) {
1467: TestUtil.dumpSQLExceptions(e, isOutOfBoundException(e));
1468: }
1469: // boundary negative 1 length
1470: try {
1471: clob.getSubString(1, -1);
1472: System.out.println("FAIL = getSubString(1,-1)");
1473: } catch (SQLException e) {
1474: TestUtil.dumpSQLExceptions(e, isOutOfBoundException(e));
1475: }
1476: // before start with length zero
1477: try {
1478: clob.getSubString(0, 0);
1479: System.out.println("FAIL = getSubString(0,0)");
1480: } catch (SQLException e) {
1481: TestUtil.dumpSQLExceptions(e, isOutOfBoundException(e));
1482: }
1483: // 2 past end with length 0
1484: try {
1485: clob.getSubString(clobLength + 2, 0);
1486: System.out
1487: .println("FAIL = getSubString(clobLength + 2,0)");
1488: } catch (SQLException e) {
1489: TestUtil.dumpSQLExceptions(e, isOutOfBoundException(e));
1490: }
1491: // 0 or negative position value
1492: try {
1493: clob.position("xx", -4000);
1494: System.out.println("FAIL = position('xx',-4000)");
1495: } catch (SQLException e) {
1496: TestUtil.dumpSQLExceptions(e, isOutOfBoundException(e));
1497: }
1498: // null pattern
1499: try {
1500: clob.position((String) null, 5);
1501: System.out.println("FAIL = position((String) null,5)");
1502: } catch (SQLException e) {
1503: TestUtil.dumpSQLExceptions(e, "XJ072".equals(e
1504: .getSQLState()));
1505: }
1506: // 0 or negative position value
1507: try {
1508: clob.position(clob, -42);
1509: System.out.println("FAIL = position(clob,-42)");
1510: } catch (SQLException e) {
1511: TestUtil.dumpSQLExceptions(e, isOutOfBoundException(e));
1512: }
1513: // null pattern
1514: try {
1515: clob.position((Clob) null, 5);
1516: System.out.println("FAIL = pposition((Clob) null,5)");
1517: } catch (SQLException e) {
1518: TestUtil.dumpSQLExceptions(e, "XJ072".equals(e
1519: .getSQLState()));
1520: }
1521: System.out.println("clobTest6 finished");
1522: } catch (SQLException e) {
1523: TestUtil.dumpSQLExceptions(e);
1524: } catch (Throwable e) {
1525: System.out.println("FAIL -- unexpected exception:"
1526: + e.toString());
1527: if (debug)
1528: e.printStackTrace(System.out);
1529: }
1530: }
1531:
1532: /*
1533: test setClob
1534: need to run prepareCLOBMAIN first
1535: */
1536: private static void clobTest7(Connection conn) {
1537: ResultSet rs, rs2;
1538: Statement stmt1, stmt2;
1539: System.out.println(START + "clobTest7");
1540: try {
1541: stmt1 = conn.createStatement();
1542: stmt1
1543: .execute("create table testClob7 (a CLOB(300k), b integer)");
1544: PreparedStatement ps = conn
1545: .prepareStatement("insert into testClob7 values(?,?)");
1546: stmt2 = conn.createStatement();
1547: rs = stmt2.executeQuery("select a,b from testCLOB_MAIN");
1548: Clob clob;
1549: int clobLength;
1550: int rownum = 0;
1551: while (rs.next()) {
1552: // get the first column as a clob
1553: clob = rs.getClob(1);
1554: if (clob == null)
1555: continue;
1556: clobLength = rs.getInt(2);
1557: ps.setClob(1, clob);
1558: ps.setInt(2, clobLength);
1559: ps.executeUpdate();
1560: }
1561: rs.close();
1562: conn.commit();
1563:
1564: rs2 = stmt2.executeQuery("select a,b from testClob7");
1565: Clob clob2;
1566: int clobLength2, j = 0;
1567: while (rs2.next()) {
1568: j++;
1569: // get the first column as a clob
1570: clob2 = rs2.getClob(1);
1571: if (clob2 == null)
1572: continue;
1573: clobLength2 = rs2.getInt(2);
1574: if (clob2.length() != clobLength2)
1575: System.out.println("FAILED at row " + j);
1576: }
1577: rs2.close();
1578:
1579: conn.commit();
1580: System.out.println("clobTest7 finished");
1581: } catch (SQLException e) {
1582: TestUtil.dumpSQLExceptions(e);
1583: if (debug)
1584: e.printStackTrace(System.out);
1585: } catch (Throwable e) {
1586: System.out.println("FAIL -- unexpected exception:"
1587: + e.toString());
1588: if (debug)
1589: e.printStackTrace(System.out);
1590: }
1591: }
1592:
1593: /**
1594: Agressive test of position.
1595: */
1596: private static void clobTest8(Connection conn) {
1597: System.out.println(START + "clobTest8");
1598: try {
1599: Statement s = conn.createStatement();
1600:
1601: s
1602: .execute("CREATE TABLE C8.T8POS(id INT NOT NULL PRIMARY KEY, DD CLOB(1m), pos INT, L INT)");
1603: s.execute("CREATE TABLE C8.T8PATT(PATT CLOB(300k))");
1604:
1605: // characters used to fill the String
1606: char[] fill = new char[4];
1607: fill[0] = 'd'; // 1 byte UTF8 character (ASCII)
1608: fill[1] = '\u03a9'; // 2 byte UTF8 character (Greek)
1609: fill[2] = '\u0e14'; // 3 byte UTF8 character (Thai)
1610: fill[3] = 'j'; // 1 byte UTF8 character (ASCII)
1611:
1612: char[] base = new char[256 * 1024];
1613:
1614: for (int i = 0; i < base.length; i += 4) {
1615:
1616: base[i] = fill[0];
1617: base[i + 1] = fill[1];
1618: base[i + 2] = fill[2];
1619: base[i + 3] = fill[3];
1620:
1621: }
1622:
1623: char[] patternBase = new char[2 * 1024];
1624: for (int i = 0; i < patternBase.length; i += 8) {
1625:
1626: patternBase[i] = 'p';
1627: patternBase[i + 1] = 'a';
1628: patternBase[i + 2] = 't';
1629: patternBase[i + 3] = '\u03aa';
1630: patternBase[i + 4] = (char) i; // changed value to keep pattern varyinh
1631: patternBase[i + 5] = 'b';
1632: patternBase[i + 6] = 'm';
1633: patternBase[i + 7] = '\u0e15';
1634:
1635: }
1636:
1637: PreparedStatement ps = conn
1638: .prepareStatement("INSERT INTO C8.T8POS VALUES (?, ?, ?, ?)");
1639: PreparedStatement psp = conn
1640: .prepareStatement("INSERT INTO C8.T8PATT VALUES (?)");
1641:
1642: T8insert(ps, 1, base, 256, patternBase, 8, 100, true);
1643: T8insert(ps, 2, base, 3988, patternBase, 8, 2045, true);
1644: T8insert(ps, 3, base, 16321, patternBase, 8, 4566, true);
1645: T8insert(ps, 4, base, 45662, patternBase, 8, 34555, true);
1646: T8insert(ps, 5, base, 134752, patternBase, 8, 67889, true);
1647: T8insert(ps, 6, base, 303, patternBase, 8, 80, false);
1648: T8insert(ps, 7, base, 4566, patternBase, 8, 2086, false);
1649: T8insert(ps, 8, base, 17882, patternBase, 8, 4426, false);
1650: T8insert(ps, 9, base, 41567, patternBase, 8, 31455, false);
1651: String pstr = T8insert(ps, 10, base, 114732, patternBase,
1652: 8, 87809, false);
1653:
1654: conn.commit();
1655:
1656: psp.setString(1, pstr);
1657: psp.executeUpdate();
1658:
1659: System.out.println("small string pattern");
1660: checkClob8(s, pstr);
1661: conn.commit();
1662:
1663: System.out.println("small java.sql.Clob pattern");
1664: ResultSet rsc = s
1665: .executeQuery("SELECT PATT FROM C8.T8PATT");
1666: rsc.next();
1667: checkClob8(s, rsc.getClob(1));
1668:
1669: rsc.close();
1670:
1671: conn.commit();
1672:
1673: s.execute("DELETE FROM C8.T8POS");
1674: s.execute("DELETE FROM C8.T8PATT");
1675:
1676: T8insert(ps, 1, base, 256, patternBase, 134, 100, true);
1677: T8insert(ps, 2, base, 3988, patternBase, 134, 2045, true);
1678: T8insert(ps, 3, base, 16321, patternBase, 134, 4566, true);
1679: T8insert(ps, 4, base, 45662, patternBase, 134, 34555, true);
1680: T8insert(ps, 5, base, 134752, patternBase, 134, 67889, true);
1681: T8insert(ps, 6, base, 303, patternBase, 134, 80, false);
1682: T8insert(ps, 7, base, 4566, patternBase, 134, 2086, false);
1683: T8insert(ps, 8, base, 17882, patternBase, 134, 4426, false);
1684: T8insert(ps, 9, base, 41567, patternBase, 134, 31455, false);
1685: pstr = T8insert(ps, 10, base, 114732, patternBase, 134,
1686: 87809, false);
1687:
1688: conn.commit();
1689: psp.setString(1, pstr);
1690: psp.executeUpdate();
1691: conn.commit();
1692:
1693: System.out.println("medium string pattern");
1694: checkClob8(s, pstr);
1695: conn.commit();
1696:
1697: System.out.println("medium java.sql.Clob pattern");
1698: rsc = s.executeQuery("SELECT PATT FROM C8.T8PATT");
1699: rsc.next();
1700: checkClob8(s, rsc.getClob(1));
1701:
1702: s.execute("DELETE FROM C8.T8POS");
1703: s.execute("DELETE FROM C8.T8PATT");
1704:
1705: T8insert(ps, 1, base, 256, patternBase, 679, 100, true);
1706: T8insert(ps, 2, base, 3988, patternBase, 679, 2045, true);
1707: T8insert(ps, 3, base, 16321, patternBase, 679, 4566, true);
1708: T8insert(ps, 4, base, 45662, patternBase, 679, 34555, true);
1709: T8insert(ps, 5, base, 134752, patternBase, 679, 67889, true);
1710: T8insert(ps, 6, base, 303, patternBase, 679, 80, false);
1711: T8insert(ps, 7, base, 4566, patternBase, 679, 2086, false);
1712: T8insert(ps, 8, base, 17882, patternBase, 679, 4426, false);
1713: T8insert(ps, 9, base, 41567, patternBase, 679, 31455, false);
1714: pstr = T8insert(ps, 10, base, 114732, patternBase, 679,
1715: 87809, false);
1716:
1717: conn.commit();
1718: psp.setString(1, pstr);
1719: psp.executeUpdate();
1720: conn.commit();
1721:
1722: System.out.println("long string pattern");
1723: checkClob8(s, pstr);
1724: conn.commit();
1725:
1726: System.out.println("long java.sql.Clob pattern");
1727: rsc = s.executeQuery("SELECT PATT FROM C8.T8PATT");
1728: rsc.next();
1729: checkClob8(s, rsc.getClob(1));
1730:
1731: s.execute("DELETE FROM C8.T8POS");
1732: s.execute("DELETE FROM C8.T8PATT");
1733: ps.close();
1734: psp.close();
1735: //
1736:
1737: s.execute("DROP TABLE C8.T8POS");
1738: s.execute("DROP TABLE C8.T8PATT");
1739:
1740: s.close();
1741:
1742: conn.commit();
1743:
1744: System.out.println("complete clobTest8");
1745:
1746: } catch (SQLException e) {
1747: TestUtil.dumpSQLExceptions(e);
1748: e.printStackTrace(System.out);
1749: } catch (Throwable e) {
1750: System.out.println("FAIL -- unexpected exception:"
1751: + e.toString());
1752: e.printStackTrace(System.out);
1753: }
1754: }
1755:
1756: private static void checkClob8(Statement s, String pstr)
1757: throws SQLException {
1758:
1759: ResultSet rs = s
1760: .executeQuery("SELECT ID, DD, POS, L FROM C8.T8POS ORDER BY 1");
1761:
1762: while (rs.next()) {
1763:
1764: int id = rs.getInt(1);
1765:
1766: System.out.print("@" + id + " ");
1767:
1768: java.sql.Clob cl = rs.getClob(2);
1769:
1770: int pos = rs.getInt(3);
1771: int len = rs.getInt(4);
1772:
1773: long clobPosition = cl.position(pstr, 1);
1774: if (clobPosition == (long) pos) {
1775: System.out.print(" position MATCH(" + pos + ")");
1776: } else {
1777: System.out.print(" position FAIL(" + clobPosition
1778: + "!=" + pos + ")");
1779: }
1780:
1781: System.out.println("");
1782: }
1783: rs.close();
1784: }
1785:
1786: private static void checkClob8(Statement s, Clob pstr)
1787: throws SQLException {
1788: ResultSet rs = s
1789: .executeQuery("SELECT ID, DD, POS, L FROM C8.T8POS ORDER BY 1");
1790:
1791: while (rs.next()) {
1792:
1793: int id = rs.getInt(1);
1794:
1795: System.out.print("@" + id + " ");
1796:
1797: java.sql.Clob cl = rs.getClob(2);
1798:
1799: int pos = rs.getInt(3);
1800: int len = rs.getInt(4);
1801:
1802: long clobPosition = cl.position(pstr, 1);
1803: if (clobPosition == (long) pos) {
1804: System.out.print(" position MATCH(" + pos + ")");
1805: } else {
1806: System.out.print(" position FAIL(" + clobPosition
1807: + "!=" + pos + ")");
1808: }
1809:
1810: System.out.println("");
1811: }
1812: rs.close();
1813: }
1814:
1815: private static String T8insert(PreparedStatement ps, int id,
1816: char[] base, int bl, char[] pattern, int pl, int pos,
1817: boolean addPattern) throws SQLException {
1818:
1819: StringBuffer sb = new StringBuffer();
1820: sb.append(base, 0, bl);
1821:
1822: // Assume the pattern looks like Abcdefgh
1823: // put together a block of misleading matches such as
1824: // AAbAbcAbcdAbcde
1825:
1826: int last = addPatternPrefix(sb, pattern, pl, 5, 10);
1827:
1828: if (last >= (pos / 2))
1829: pos = (last + 10) * 2;
1830:
1831: // now a set of misleading matches up to half the pattern width
1832: last = addPatternPrefix(sb, pattern, pl, pl / 2, pos / 2);
1833:
1834: if (last >= pos)
1835: pos = last + 13;
1836:
1837: // now a complete set of misleading matches
1838: pos = addPatternPrefix(sb, pattern, pl, pl - 1, pos);
1839:
1840: if (addPattern) {
1841: // and then the pattern
1842: sb.insert(pos, pattern, 0, pl);
1843: } else {
1844: pos = -1;
1845: }
1846:
1847: String dd = sb.toString();
1848: String pstr = new String(pattern, 0, pl);
1849:
1850: if (pos != dd.indexOf(pstr)) {
1851: System.out
1852: .println("FAIL - test confused pattern not at expected location");
1853:
1854: System.out.println("POS = " + pos + " index "
1855: + dd.indexOf(pstr));
1856: System.out.println("LENG " + dd.length());
1857: // System.out.println(sb.toString());
1858: }
1859:
1860: // JDBC uses 1 offset for first character
1861: if (pos != -1)
1862: pos = pos + 1;
1863:
1864: ps.setInt(1, id);
1865: ps.setString(2, dd);
1866: ps.setInt(3, pos);
1867: ps.setInt(4, dd.length());
1868: ps.executeUpdate();
1869:
1870: return pstr;
1871:
1872: }
1873:
1874: private static int addPatternPrefix(StringBuffer sb,
1875: char[] pattern, int pl, int fakeCount, int pos) {
1876:
1877: for (int i = 0; i < fakeCount && i < (pl - 1); i++) {
1878:
1879: sb.insert(pos, pattern, 0, i + 1);
1880: pos += i + 1;
1881: }
1882:
1883: return pos;
1884: }
1885:
1886: /* advanced tests */
1887:
1888: // make sure clob is still around after we go to the next row,
1889: // after we close the result set, and after we close the statement
1890: private static void clobTest91(Connection conn) {
1891: ResultSet rs;
1892: Statement stmt;
1893: System.out.println(START + "clobTest91");
1894: try {
1895: stmt = conn.createStatement();
1896: rs = stmt.executeQuery("select a,b from testCLOB_MAIN");
1897: byte[] buff = new byte[128];
1898: Clob[] clobArray = new Clob[numRows];
1899: int[] clobLengthArray = new int[numRows];
1900: int j = 0;
1901: while (rs.next()) {
1902: clobArray[j] = rs.getClob(1);
1903: clobLengthArray[j++] = rs.getInt(2);
1904: }
1905: rs.close();
1906: stmt.close();
1907:
1908: for (int i = 0; i < numRows; i++) {
1909: if (clobArray[i] == null) {
1910: System.out
1911: .println("row " + i + " is null, skipped");
1912: continue;
1913: }
1914: InputStream fin = clobArray[i].getAsciiStream();
1915: int columnSize = 0;
1916: for (;;) {
1917: int size = fin.read(buff);
1918: if (size == -1)
1919: break;
1920: columnSize += size;
1921: }
1922: if (columnSize != clobLengthArray[i])
1923: System.out
1924: .println("test failed, columnSize should be "
1925: + clobLengthArray[i]
1926: + ", but it is "
1927: + columnSize
1928: + ", i = " + i);
1929: if (columnSize != clobArray[i].length())
1930: System.out
1931: .println("test failed, clobArray[i].length() should be "
1932: + columnSize
1933: + ", but it is "
1934: + clobArray[i].length()
1935: + ", i = "
1936: + i);
1937: System.out.println("done row " + i + ", length was "
1938: + clobLengthArray[i]);
1939: }
1940: System.out.println("clobTest91 finished");
1941: } catch (SQLException e) {
1942: TestUtil.dumpSQLExceptions(e);
1943: } catch (Throwable e) {
1944: System.out.println("FAIL -- unexpected exception:"
1945: + e.toString());
1946: if (debug)
1947: e.printStackTrace(System.out);
1948: }
1949: }
1950:
1951: /*
1952: test locking
1953: need to run prepareCLOBMAIN fverirst
1954: */
1955: private static void clobTest92(Connection conn) {
1956: ResultSet rs;
1957: Statement stmt, stmt2;
1958: System.out.println(START + "clobTest92");
1959: try {
1960: stmt = conn.createStatement();
1961: rs = stmt.executeQuery("select a,b from testCLOB_MAIN");
1962: // fetch row back, get the column as a clob.
1963: Clob clob = null, shortClob = null;
1964: int clobLength;
1965: while (rs.next()) {
1966: clobLength = rs.getInt(2);
1967: if (clobLength == 10000)
1968: clob = rs.getClob(1);
1969: if (clobLength == 26)
1970: shortClob = rs.getClob(1);
1971: }
1972: rs.close();
1973:
1974: Connection conn2 = ij.startJBMS();
1975: // turn off autocommit, otherwise blobs/clobs cannot hang around
1976: // until end of transaction
1977: conn2.setAutoCommit(false);
1978:
1979: // update should go through since we don't get any locks on clobs
1980: // that are not long columns
1981: stmt2 = conn2.createStatement();
1982: stmt2
1983: .executeUpdate("update testCLOB_MAIN set a = 'foo' where b = 26");
1984: if (shortClob.length() != 26)
1985: System.out.println("FAILED: clob length changed to "
1986: + shortClob.length());
1987: // should timeout waiting for the lock to do this
1988: stmt2 = conn2.createStatement();
1989: stmt2
1990: .executeUpdate("update testCLOB_MAIN set b = b + 1 where b = 10000");
1991:
1992: conn.commit();
1993: conn2.rollback();
1994: System.out.println("clobTest92 finished");
1995: } catch (SQLException e) {
1996: TestUtil.dumpSQLExceptions(e);
1997: } catch (Throwable e) {
1998: System.out.println("FAIL -- unexpected exception:"
1999: + e.toString());
2000: if (debug)
2001: e.printStackTrace(System.out);
2002: }
2003: }
2004:
2005: /*
2006: test locking with a long row + long column
2007: */
2008: private static void clobTest93(Connection conn) {
2009: ResultSet rs;
2010: Statement stmt, stmt2;
2011: System.out.println(START + "clobTest93");
2012: try {
2013: stmt = conn.createStatement();
2014: // creating table to fit within default 4k table size, then add large columns
2015: stmt
2016: .execute("create table testLongRowClob (a varchar(2000))");
2017: stmt
2018: .execute("alter table testLongRowClob add column b varchar(3000)");
2019: stmt
2020: .execute("alter table testLongRowClob add column c varchar(2000)");
2021: stmt
2022: .execute("alter table testLongRowClob add column d varchar(3000)");
2023: stmt
2024: .execute("alter table testLongRowClob add column e CLOB(400k)");
2025: PreparedStatement ps = conn
2026: .prepareStatement("insert into testLongRowClob values(?,?,?,?,?)");
2027: ps.setString(1, Formatters.padString("blaaa", 2000));
2028: ps.setString(2, Formatters.padString("tralaaaa", 3000));
2029: ps.setString(3, Formatters.padString("foodar", 2000));
2030: ps.setString(4, Formatters.padString("moped", 3000));
2031: File file = new File(fileName[1]);
2032: if (file.length() < 10000)
2033: System.out.println("ERROR: wrong file tested");
2034: InputStream fileIn = new FileInputStream(file);
2035: ps.setAsciiStream(5, fileIn, (int) file.length());
2036: ps.executeUpdate();
2037: fileIn.close();
2038: conn.commit();
2039:
2040: stmt = conn.createStatement();
2041: rs = stmt.executeQuery("select e from testLongRowClob");
2042: // fetch row back, get the column as a clob.
2043: Clob clob = null;
2044: while (rs.next())
2045: clob = rs.getClob(1);
2046: rs.close();
2047:
2048: Connection conn2 = ij.startJBMS();
2049: // turn off autocommit, otherwise blobs/clobs cannot hang around
2050: // until end of transaction
2051: conn2.setAutoCommit(false);
2052: // the following should timeout
2053: stmt2 = conn2.createStatement();
2054: stmt2
2055: .executeUpdate("update testLongRowClob set e = 'smurfball' where a = 'blaaa'");
2056:
2057: conn.commit();
2058: conn2.commit();
2059: System.out.println("clobTest92 finished");
2060: } catch (SQLException e) {
2061: TestUtil.dumpSQLExceptions(e);
2062: } catch (Throwable e) {
2063: System.out.println("FAIL -- unexpected exception:"
2064: + e.toString());
2065: if (debug)
2066: e.printStackTrace(System.out);
2067: }
2068: }
2069:
2070: /*
2071: test accessing clob after commit
2072: need to run prepareCLOBMAIN first
2073: */
2074: private static void clobTest94(Connection conn) {
2075: ResultSet rs;
2076: Statement stmt;
2077: System.out.println(START + "clobTest94");
2078: try {
2079: stmt = conn.createStatement();
2080: rs = stmt.executeQuery("select a,b from testCLOB_MAIN");
2081: // fetch row back, get the column as a clob.
2082: Clob clob = null, shortClob = null;
2083: int clobLength;
2084: int i = 0;
2085: while (rs.next()) {
2086: //System.out.println("ACCESSING ROW:" + i++);
2087: clobLength = rs.getInt(2);
2088: if (clobLength == 10000)
2089: clob = rs.getClob(1);
2090: if (clobLength == 26)
2091: shortClob = rs.getClob(1);
2092: }
2093: rs.close();
2094: conn.commit();
2095:
2096: // no problem accessing this after commit since it is in memory
2097: System.out.println("shortClob length after commit is "
2098: + shortClob.length());
2099: // these should all give blob/clob data unavailable exceptions
2100: try {
2101: clob.length();
2102: } catch (SQLException e) {
2103: TestUtil.dumpSQLExceptions(e);
2104: }
2105: try {
2106: clob.getSubString(2, 3);
2107: } catch (SQLException e) {
2108: TestUtil.dumpSQLExceptions(e);
2109: }
2110: try {
2111: clob.getAsciiStream();
2112: } catch (SQLException e) {
2113: TestUtil.dumpSQLExceptions(e);
2114: }
2115: try {
2116: clob.position("foo", 2);
2117: } catch (SQLException e) {
2118: TestUtil.dumpSQLExceptions(e);
2119: }
2120: try {
2121: clob.position(clob, 2);
2122: } catch (SQLException e) {
2123: TestUtil.dumpSQLExceptions(e);
2124: }
2125:
2126: System.out.println("clobTest94 finished");
2127: } catch (SQLException e) {
2128: TestUtil.dumpSQLExceptions(e);
2129: } catch (Throwable e) {
2130: System.out.println("FAIL -- unexpected exception:"
2131: + e.toString());
2132: if (debug)
2133: e.printStackTrace(System.out);
2134: }
2135: }
2136:
2137: /*
2138: test accessing clob after closing the connection
2139: need to run prepareCLOBMAIN first
2140: */
2141: private static void clobTest95(Connection conn) {
2142: ResultSet rs;
2143: Statement stmt;
2144: System.out.println(START + "clobTest95");
2145: try {
2146: stmt = conn.createStatement();
2147: rs = stmt.executeQuery("select a,b from testCLOB_MAIN");
2148: // fetch row back, get the column as a clob.
2149: Clob clob = null, shortClob = null;
2150: int clobLength;
2151: while (rs.next()) {
2152: clobLength = rs.getInt(2);
2153: if (clobLength == 10000)
2154: clob = rs.getClob(1);
2155: if (clobLength == 26)
2156: shortClob = rs.getClob(1);
2157: }
2158: rs.close();
2159: conn.commit();
2160: conn.close();
2161:
2162: try {
2163: // no problem accessing this after commit since it is in memory
2164: System.out
2165: .println("shortClob length after closing connection is "
2166: + shortClob.length());
2167: } catch (SQLException e) {
2168: if (isDerbyNet)
2169: System.out.println("EXPECTED SQL Exception: "
2170: + e.getMessage());
2171: else
2172: TestUtil.dumpSQLExceptions(e);
2173:
2174: }
2175: // these should all give blob/clob data unavailable exceptions
2176: try {
2177: clob.length();
2178: } catch (SQLException e) {
2179: if (isDerbyNet)
2180: System.out.println("EXPECTED SQL Exception: "
2181: + e.getMessage());
2182: else
2183: TestUtil.dumpSQLExceptions(e);
2184: }
2185: try {
2186: clob.getSubString(2, 3);
2187: } catch (SQLException e) {
2188: if (isDerbyNet)
2189: System.out.println("EXPECTED SQL Exception: "
2190: + e.getMessage());
2191: else
2192: TestUtil.dumpSQLExceptions(e);
2193: }
2194: try {
2195: clob.getAsciiStream();
2196: } catch (SQLException e) {
2197: if (isDerbyNet)
2198: System.out.println("EXPECTED SQL Exception: "
2199: + e.getMessage());
2200: else
2201: TestUtil.dumpSQLExceptions(e);
2202: }
2203: try {
2204: clob.position("foo", 2);
2205: } catch (SQLException e) {
2206: if (isDerbyNet)
2207: System.out.println("EXPECTED SQL Exception: "
2208: + e.getMessage());
2209: else
2210: TestUtil.dumpSQLExceptions(e);
2211: }
2212: try {
2213: clob.position(clob, 2);
2214: } catch (SQLException e) {
2215:
2216: if (isDerbyNet)
2217: System.out.println("EXPECTED SQL Exception: "
2218: + e.getMessage());
2219: else
2220: TestUtil.dumpSQLExceptions(e);
2221: }
2222:
2223: System.out.println("clobTest95 finished");
2224: } catch (SQLException e) {
2225: TestUtil.dumpSQLExceptions(e);
2226: } catch (Throwable e) {
2227: System.out.println("FAIL -- unexpected exception:"
2228: + e.toString());
2229: if (debug)
2230: e.printStackTrace(System.out);
2231: }
2232: }
2233:
2234: /*
2235: test clob finalizer closes the container
2236: (should only release table and row locks that are read_committed)
2237: need to run prepareCLOBMAIN first
2238: NOTE: this test does not produce output since it needs to call the
2239: garbage collector whose behaviour is unreliable. It is in the test run to
2240: exercise the code (most of the time).
2241: */
2242: private static void clobTest96(Connection conn) {
2243: ResultSet rs;
2244: Statement stmt;
2245: System.out.println(START + "clobTest96");
2246: try {
2247: stmt = conn.createStatement();
2248: rs = stmt.executeQuery("select a,b from testCLOB_MAIN");
2249: byte[] buff = new byte[128];
2250: Clob[] clobArray = new Clob[numRows];
2251: int[] clobLengthArray = new int[numRows];
2252: int j = 0;
2253: while (rs.next()) {
2254: clobArray[j] = rs.getClob(1);
2255: clobLengthArray[j++] = rs.getInt(2);
2256: }
2257: rs.close();
2258: stmt.close();
2259:
2260: for (int i = 0; i < numRows; i++) {
2261: clobArray[i] = null;
2262: }
2263:
2264: System.gc();
2265: System.gc();
2266:
2267: // System.out.println("after gc");
2268: // printLockTable(conn);
2269:
2270: System.out.println("clobTest96 finished");
2271: } catch (SQLException e) {
2272: TestUtil.dumpSQLExceptions(e);
2273: } catch (Throwable e) {
2274: System.out.println("FAIL -- unexpected exception:"
2275: + e.toString());
2276: if (debug)
2277: e.printStackTrace(System.out);
2278: }
2279: }
2280:
2281: /*
2282: test clob finalizer closes the container
2283: (should only release table and row locks that are read_committed)
2284: need to run prepareCLOBMAIN first
2285: NOTE: this test does not produce output since it needs to call the
2286: garbage collector whose behaviour is unreliable. It is in the test run to
2287: exercise the code (most of the time).
2288: */
2289: /*
2290: The bug here is that if we do 2 getBlobs on the same column, we reopen the
2291: container twice, but only remember the 2nd container. Then closing the
2292: container on one of the blobs causes the 2nd one not to work.
2293: (Also, closing both blobs leaves one container open.)
2294: */
2295:
2296: private static void bug2(Connection conn) {
2297: ResultSet rs;
2298: Statement stmt;
2299: System.out.println(START + "bug2");
2300: try {
2301: stmt = conn.createStatement();
2302: rs = stmt.executeQuery("select a,b from testCLOB_MAIN");
2303: byte[] buff = new byte[128];
2304: Clob[] clobArray = new Clob[numRows * 2];
2305: int[] clobLengthArray = new int[numRows * 2];
2306: int j = 0;
2307: while (rs.next()) {
2308: clobArray[j] = rs.getClob(1);
2309: clobLengthArray[j++] = rs.getInt(2);
2310: clobArray[j] = rs.getClob(1);
2311: clobLengthArray[j++] = rs.getInt(2);
2312: }
2313: rs.close();
2314: stmt.close();
2315:
2316: // null out clobs at all the even positions
2317: for (int i = 0; i < numRows * 2; i = i + 2) {
2318: clobArray[i] = null;
2319: }
2320:
2321: System.gc();
2322: System.gc();
2323:
2324: System.out.println("after gc");
2325: // printLockTable(conn);
2326:
2327: // access clobs at all the odd positions
2328: for (int i = 1; i < numRows * 2 + 1; i = i + 2) {
2329: if (clobArray[i].length() != clobLengthArray[i])
2330: System.out.println("Error at array position " + i);
2331: }
2332:
2333: System.out.println("clobTest97 finished");
2334: } catch (SQLException e) {
2335: TestUtil.dumpSQLExceptions(e);
2336: } catch (Throwable e) {
2337: System.out.println("FAIL -- unexpected exception:"
2338: + e.toString());
2339: if (debug)
2340: e.printStackTrace(System.out);
2341: }
2342: }
2343:
2344: /*
2345: test locking
2346: need to run prepareCLOBMAIN first
2347: */
2348: private static void clobTestGroupfetch(Connection conn) {
2349: ResultSet rs;
2350: Statement stmt, stmt2;
2351: System.out.println(START + "clobTestGroupFetch");
2352: try {
2353: stmt = conn.createStatement();
2354: rs = stmt.executeQuery("select a,b from testCLOB_MAIN");
2355: // fetch row back, get the column as a clob.
2356: int clobLength;
2357: while (rs.next()) {
2358: clobLength = rs.getInt(2);
2359: String s = rs.getString(1);
2360: printLockTable(conn);
2361: }
2362: rs.close();
2363:
2364: System.out.println("clobTestGroupFetch finished");
2365: } catch (SQLException e) {
2366: TestUtil.dumpSQLExceptions(e);
2367: } catch (Throwable e) {
2368: System.out.println("FAIL -- unexpected exception:"
2369: + e.toString());
2370: if (debug)
2371: e.printStackTrace(System.out);
2372: }
2373: }
2374:
2375: /*
2376: This bug is happening because the clob.length() sets the stream to some
2377: position (probably to the end). Then when you do a getString() on the same
2378: column, you are using the same SQLChar object, and you try to call readExternal
2379: on the stream, but since it isn't at the beginning it doesn't work.
2380: */
2381: private static void bug(Connection conn) {
2382: ResultSet rs;
2383: Statement stmt, stmt2;
2384: System.out.println(START + "bug");
2385: try {
2386: stmt = conn.createStatement();
2387: // creating table to fit within default 4k table size, then add large columns
2388: stmt
2389: .execute("create table testLongRowClob (a varchar(2000))");
2390: stmt
2391: .execute("alter table testLongRowClob add column b varchar(3000)");
2392: stmt
2393: .execute("alter table testLongRowClob add column c varchar(2000)");
2394: stmt
2395: .execute("alter table testLongRowClob add column d varchar(3000)");
2396: stmt
2397: .execute("alter table testLongRowClob add column e CLOB(400k)");
2398: PreparedStatement ps = conn
2399: .prepareStatement("insert into testLongRowClob values(?,?,?,?,?)");
2400: ps.setString(1, Formatters.padString("blaaa", 2000));
2401: ps.setString(2, Formatters.padString("tralaaaa", 3000));
2402: ps.setString(3, Formatters.padString("foodar", 2000));
2403: ps.setString(4, Formatters.padString("moped", 3000));
2404: File file = new File(fileName[1]);
2405: if (file.length() < 10000)
2406: System.out.println("ERROR: wrong file tested");
2407: InputStream fileIn = new FileInputStream(file);
2408: ps.setAsciiStream(5, fileIn, (int) file.length());
2409: ps.executeUpdate();
2410: fileIn.close();
2411: conn.commit();
2412:
2413: Connection conn2 = ij.startJBMS();
2414: // turn off autocommit, otherwise blobs/clobs cannot hang around
2415: // until end of transaction
2416: conn2.setAutoCommit(false);
2417:
2418: // printLockTable(conn2);
2419: stmt = conn.createStatement();
2420: rs = stmt.executeQuery("select e from testLongRowClob");
2421: printLockTable(conn2);
2422:
2423: // fetch row back, get the column as a clob.
2424: Clob clob = null;
2425: int clobLength, i = 0;
2426: while (rs.next()) {
2427: i++;
2428: clob = rs.getClob(1);
2429: System.out.println("got it");
2430: // bug doesn't happen if the below is commented out
2431: System.out.println("clob length is " + clob.length());
2432: System.out.println("the thing as a string is : \n"
2433: + rs.getString(1));
2434: printLockTable(conn2);
2435: }
2436: rs.close();
2437: System.out.println("After closing result set");
2438: printLockTable(conn2);
2439:
2440: stmt2 = conn2.createStatement();
2441: stmt2
2442: .executeUpdate("update testLongRowClob set e = 'smurfball' where a = 'blaaa'");
2443: printLockTable(conn2);
2444:
2445: System.out.println("clob length is " + clob.length());
2446:
2447: conn.commit();
2448: conn2.commit();
2449: System.out.println("clobTest92 finished");
2450: } catch (SQLException e) {
2451: TestUtil.dumpSQLExceptions(e);
2452: } catch (Throwable e) {
2453: System.out.println("FAIL -- unexpected exception:"
2454: + e.toString());
2455: if (debug)
2456: e.printStackTrace(System.out);
2457: }
2458: }
2459:
2460: // test getAsciiStream, print out the result
2461: // this is just temporary, for comparison with getAsciiStream
2462: private static void clobTest9999(Connection conn) {
2463:
2464: ResultSetMetaData met;
2465: ResultSet rs;
2466: Statement stmt;
2467: System.out.println(START + "clobTest9999");
2468: try {
2469: stmt = conn.createStatement();
2470: stmt
2471: .execute("call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.storage.pageSize','4096')");
2472: stmt.execute("create table clobTest9999 (a CLOB(300k))");
2473: stmt
2474: .execute("call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.storage.pageSize','0')");
2475:
2476: int i = 4;
2477: // prepare an InputStream from the file
2478: File file = new File(fileName[i]);
2479: fileLength[i] = file.length();
2480: InputStream fileIn = new FileInputStream(file);
2481:
2482: System.out.println("===> testing " + fileName[i]
2483: + " length = " + fileLength[i]);
2484:
2485: // insert a streaming column
2486: PreparedStatement ps = conn
2487: .prepareStatement("insert into clobTest9999 values(?)");
2488: ps.setAsciiStream(1, fileIn, (int) fileLength[i]);
2489: ps.executeUpdate();
2490: fileIn.close();
2491:
2492: rs = stmt.executeQuery("select a from clobTest9999");
2493: met = rs.getMetaData();
2494: // fetch row back, get the column as a clob.
2495: while (rs.next()) {
2496: // get the first column as a clob
2497: Clob clob = rs.getClob(1);
2498: InputStream fin = clob.getAsciiStream();
2499: int columnSize = 0;
2500: for (;;) {
2501: int j = fin.read();
2502: if (j == -1)
2503: break;
2504: System.out.print((char) j);
2505: }
2506: }
2507: System.out.println("Finished clobTest9999");
2508:
2509: } catch (SQLException e) {
2510: TestUtil.dumpSQLExceptions(e);
2511: } catch (Throwable e) {
2512: System.out.println("FAIL -- unexpected exception:"
2513: + e.toString());
2514: if (debug)
2515: e.printStackTrace(System.out);
2516: }
2517: }
2518:
2519: /**
2520: * Test fix for derby-1382.
2521: *
2522: * Test that the getClob() returns the correct value for the clob before and
2523: * after updating the clob when using result sets of type
2524: * TYPE_SCROLL_INSENSITIVE.
2525: *
2526: * The method updateString(int, String) is used to set the value on the
2527: * clob because the method updateBlob(int, Blob) has not yet been
2528: * implemented for DerbyNetClient.
2529: *
2530: * @param conn Connection
2531: * @throws SQLException
2532: */
2533: private static void clobTest10(Connection conn) throws SQLException {
2534: Statement s = conn.createStatement();
2535: s.execute("CREATE TABLE derby1382 (c1 int, c2 clob)");
2536:
2537: String clobData = "initial clob ";
2538: PreparedStatement ps = conn
2539: .prepareStatement("insert into derby1382 values (?, ?)");
2540: for (int i = 0; i < 10; i++) {
2541: ps.setInt(1, i);
2542: ps.setString(2, clobData + i);
2543: ps.execute();
2544: }
2545: ps.close();
2546:
2547: Statement scrollStmt = conn.createStatement(
2548: ResultSet.TYPE_SCROLL_INSENSITIVE,
2549: ResultSet.CONCUR_UPDATABLE);
2550: ResultSet rs = scrollStmt
2551: .executeQuery("SELECT * FROM derby1382");
2552:
2553: String value;
2554: Clob c;
2555:
2556: rs.first();
2557: checkContentsBeforeAndAfterUpdatingClob(rs);
2558: rs.next();
2559: checkContentsBeforeAndAfterUpdatingClob(rs);
2560: rs.relative(3);
2561: checkContentsBeforeAndAfterUpdatingClob(rs);
2562: rs.absolute(7);
2563: checkContentsBeforeAndAfterUpdatingClob(rs);
2564: rs.previous();
2565: checkContentsBeforeAndAfterUpdatingClob(rs);
2566: rs.last();
2567: checkContentsBeforeAndAfterUpdatingClob(rs);
2568: rs.previous();
2569: checkContentsBeforeAndAfterUpdatingClob(rs);
2570:
2571: rs.close();
2572: scrollStmt.close();
2573:
2574: s.execute("DROP TABLE derby1382");
2575: s.close();
2576: }
2577:
2578: private static void checkContentsBeforeAndAfterUpdatingClob(
2579: ResultSet rs) throws SQLException {
2580: Clob c;
2581: String value, expectedValue;
2582: String clobData = "initial clob ";
2583: String updatedClobData = "updated clob ";
2584:
2585: c = rs.getClob(2);
2586: // check contents
2587: value = c.getSubString(1, (int) c.length());
2588: expectedValue = clobData + rs.getInt(1);
2589: if (value.compareToIgnoreCase(expectedValue) != 0) {
2590: System.out.println("clobTest10 - Error: wrong clob value");
2591: }
2592: // update contents
2593: value = updatedClobData + rs.getInt(1);
2594: rs.updateString(2, value);
2595: rs.updateRow();
2596: // check update values
2597: rs.next(); // leave the row
2598: rs.previous(); // go back to updated row
2599: c = rs.getClob(2);
2600: // check contents
2601: value = c.getSubString(1, (int) c.length());
2602: expectedValue = updatedClobData + rs.getInt(1);
2603: if (value.compareToIgnoreCase(expectedValue) != 0) {
2604: System.out.println("clobTest10 - Error: wrong clob value");
2605: }
2606: }
2607:
2608: /**
2609: * Test fix for derby-1421.
2610: *
2611: * Test that the getClob() returns the correct value for the blob before and
2612: * after updating the Clob using the method updateCharacterStream().
2613: *
2614: * @param conn Connection
2615: * @throws SQLException
2616: */
2617: private static void clobTest14(Connection conn) throws SQLException {
2618: Statement s = conn.createStatement();
2619: s.execute("CREATE TABLE derby1421 (c1 int, c2 clob)");
2620:
2621: String clobData = "initial clob ";
2622: PreparedStatement ps = conn
2623: .prepareStatement("insert into derby1421 values (?, ?)");
2624: for (int i = 0; i < 10; i++) {
2625: ps.setInt(1, i);
2626: ps.setString(2, clobData + i);
2627: ps.execute();
2628: }
2629: ps.close();
2630:
2631: Statement scrollStmt = conn.createStatement(
2632: ResultSet.TYPE_SCROLL_INSENSITIVE,
2633: ResultSet.CONCUR_UPDATABLE);
2634: ResultSet rs = scrollStmt
2635: .executeQuery("SELECT * FROM derby1421");
2636:
2637: rs.first();
2638: updateClobWithUpdateCharacterStream(rs);
2639: rs.next();
2640: updateClobWithUpdateCharacterStream(rs);
2641: rs.relative(3);
2642: updateClobWithUpdateCharacterStream(rs);
2643: rs.absolute(7);
2644: updateClobWithUpdateCharacterStream(rs);
2645: rs.previous();
2646: updateClobWithUpdateCharacterStream(rs);
2647: rs.last();
2648: updateClobWithUpdateCharacterStream(rs);
2649: rs.previous();
2650: updateClobWithUpdateCharacterStream(rs);
2651:
2652: rs.close();
2653: scrollStmt.close();
2654:
2655: s.execute("DROP TABLE derby1421");
2656: s.close();
2657: }
2658:
2659: private static void updateClobWithUpdateCharacterStream(ResultSet rs)
2660: throws SQLException {
2661: Clob c;
2662: String value, expectedValue;
2663: String clobData = "initial clob ";
2664: String updatedClobData = "updated clob ";
2665:
2666: c = rs.getClob(2);
2667: // check contents
2668: value = c.getSubString(1, (int) c.length());
2669: expectedValue = clobData + rs.getInt(1);
2670: if (value.compareToIgnoreCase(expectedValue) != 0) {
2671: System.out.println("clobTest14 - Error: wrong clob value");
2672: }
2673:
2674: // update contents
2675: value = (updatedClobData + rs.getInt(1));
2676: Reader updateValue = new StringReader(value);
2677: rs.updateCharacterStream(2, updateValue, value.length());
2678: rs.updateRow();
2679: // check update values
2680: rs.next(); // leave the row
2681: rs.previous(); // go back to updated row
2682: c = rs.getClob(2);
2683: // check contents
2684: value = c.getSubString(1, (int) c.length());
2685: expectedValue = updatedClobData + rs.getInt(1);
2686: if (value.compareToIgnoreCase(expectedValue) != 0) {
2687: System.out.println("clobTest14 - Error: wrong clob value");
2688: }
2689: }
2690:
2691: // test behaviour of system with self destructive user
2692: // update a long column underneath a clob
2693: private static void clobTestSelfDestructive(Connection conn) {
2694: ResultSet rs;
2695: Statement stmt;
2696: System.out.println(START + "clobTestSelfDestructive");
2697: try {
2698: stmt = conn.createStatement();
2699: rs = stmt
2700: .executeQuery("select a,b from testCLOB_MAIN where b = 10000");
2701: byte[] buff = new byte[128];
2702: // fetch row back, get the column as a clob.
2703: Clob clob = null;
2704: InputStream fin;
2705: int clobLength = 0, i = 0;
2706: if (rs.next()) {
2707: i++;
2708: clobLength = rs.getInt(2);
2709: // get the first column as a clob
2710: clob = rs.getClob(1);
2711: }
2712: System.out
2713: .println("length of clob chosen is " + clobLength);
2714: fin = clob.getAsciiStream();
2715: int columnSize = 0;
2716:
2717: PreparedStatement ps = conn
2718: .prepareStatement("update testCLOB_MAIN set a = ? where b = 10000");
2719: StringBuffer foo = new StringBuffer();
2720: for (int k = 0; k < 1000; k++)
2721: foo.append('j');
2722: ps.setString(1, foo.toString());
2723: ps.executeUpdate();
2724:
2725: System.out.println("After update");
2726:
2727: rs = stmt
2728: .executeQuery("select a from testCLOB_MAIN where b = 10000");
2729: while (rs.next()) {
2730: int j = 1;
2731: String val = rs.getString(1);
2732: System.out.println("Row " + j
2733: + " value.substring(0,50) is "
2734: + val.substring(0, 50));
2735: j++;
2736: }
2737:
2738: while (columnSize < 11000) {
2739: int size = fin.read(buff);
2740: if (size == -1)
2741: break;
2742: columnSize += size;
2743: // printing the return from each read is very implementation dependent
2744: }
2745: System.out.println(columnSize + " total bytes read");
2746:
2747: if (columnSize != clobLength)
2748: System.out.println("test failed, columnSize should be "
2749: + clobLength + ", but it is " + columnSize
2750: + ", i = " + i);
2751: if (columnSize != clob.length())
2752: System.out
2753: .println("test failed, clob.length() should be "
2754: + columnSize
2755: + ", but it is "
2756: + clob.length() + ", i = " + i);
2757: conn.rollback();
2758: System.out.println("clobTestSelfDestructive finished");
2759: } catch (SQLException e) {
2760: TestUtil.dumpSQLExceptions(e);
2761: } catch (Throwable e) {
2762: System.out.println("FAIL -- unexpected exception:"
2763: + e.toString());
2764: if (debug)
2765: e.printStackTrace(System.out);
2766: }
2767: }
2768:
2769: // test behaviour of system with self destructive user
2770: // drop table and see what happens to the clob
2771: // expect an IOException when moving to a new page of the long column
2772: private static void clobTestSelfDestructive2(Connection conn) {
2773: ResultSet rs;
2774: Statement stmt;
2775: System.out.println(START + "clobTestSelfDestructive2");
2776: try {
2777: stmt = conn.createStatement();
2778: rs = stmt
2779: .executeQuery("select a,b from testCLOB_MAIN where b = 10000");
2780: byte[] buff = new byte[128];
2781: // fetch row back, get the column as a clob.
2782: Clob clob = null;
2783: InputStream fin;
2784: int clobLength = 0, i = 0;
2785: if (rs.next()) {
2786: i++;
2787: clobLength = rs.getInt(2);
2788: // get the first column as a clob
2789: clob = rs.getClob(1);
2790: }
2791: System.out
2792: .println("length of clob chosen is " + clobLength);
2793: fin = clob.getAsciiStream();
2794: int columnSize = 0;
2795:
2796: stmt.executeUpdate("drop table testCLOB_MAIN");
2797: System.out.println("After drop");
2798:
2799: System.out
2800: .println("Expect to get an IOException, container has been closed");
2801: while (columnSize < 11000) {
2802: int size = fin.read(buff);
2803: if (size == -1)
2804: break;
2805: columnSize += size;
2806: // printing the return from each read is very implementation dependent
2807: }
2808: System.out.println(columnSize + " total bytes read");
2809:
2810: conn.rollback();
2811: System.out.println("clobTestSelfDestructive2 finished");
2812: } catch (SQLException e) {
2813: TestUtil.dumpSQLExceptions(e);
2814: } catch (java.io.IOException ioe) {
2815: System.out.println("EXPECTED IO Exception:"
2816: + ioe.getMessage());
2817: } catch (Throwable e) {
2818: System.out.println("FAIL -- unexpected exception:"
2819: + e.toString());
2820: if (debug)
2821: e.printStackTrace(System.out);
2822: }
2823: }
2824:
2825: private static void printLockTable(Connection conn) {
2826: ResultSet rs;
2827: Statement stmt, stmt2;
2828: try {
2829: System.out
2830: .println("\nLock table\n----------------------------------------");
2831: stmt = conn.createStatement();
2832: rs = stmt
2833: .executeQuery("select xid,type,lockcount,mode,tablename,lockname,state from SYSCS_DIAG.LOCK_TABLE t where t.tableType <> 'S'");
2834: while (rs.next()) {
2835: String xid = rs.getString("xid");
2836: String type = rs.getString("type");
2837: String lockcount = rs.getString("lockcount");
2838: String mode = rs.getString("mode");
2839: String tablename = rs.getString("tablename");
2840: String lockname = rs.getString("lockname");
2841: String state = rs.getString("state");
2842: System.out.println("Lock{xid = " + xid + ", type = "
2843: + type + ", lockcount = " + lockcount
2844: + ", mode = " + mode + ", tablename = "
2845: + tablename + ", lockname = " + lockname
2846: + ", state = " + state + " } ");
2847: }
2848: System.out
2849: .println("----------------------------------------\n");
2850: } catch (SQLException e) {
2851: TestUtil.dumpSQLExceptions(e);
2852: } catch (Throwable e) {
2853: System.out.println("FAIL -- unexpected exception:"
2854: + e.toString());
2855: if (debug)
2856: e.printStackTrace(System.out);
2857: }
2858: }
2859:
2860: private static void unicodeTest() {
2861: System.out.println(START + "unicodeTest");
2862: try {
2863: // String to Unicode bytes
2864: byte[] unicodeArray = { 0xfffffffe, 0xffffffff, 0x01, 0x68,
2865: 0x00, 0x65, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x6f };
2866: String str = new String(unicodeArray, "Unicode");
2867: System.out.println("First string is : " + str);
2868: // byte[] array = str.getBytes("UnicodeBigUnmarked");
2869: // Unicode bytes to String
2870: // double byte not supported
2871: // str = new String (array, "DoubleByte");
2872: // System.out.println("Second string is : " + str);
2873:
2874: byte[] uni2 = { 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x74,
2875: 0x68, 0x65, 0x72, 0x65 };
2876: String suni2 = new String(uni2, "Unicode");
2877: System.out.println("uni2 is :" + uni2);
2878:
2879: String uni3 = "\u0020\u0021\u0023";
2880: System.out.println("uni3 is :" + uni3);
2881: String uni4 = "\u0061\u0062\u0063";
2882: System.out.println("uni4 is :" + uni4);
2883: System.out.println("uni4 equals abc ? "
2884: + uni4.equals("abc"));
2885: String uni5 = "\u0370\u0371\u0372";
2886: System.out.println("uni5 is :" + uni5);
2887: System.out.println("uni5 equals ??? ? "
2888: + uni5.equals("???"));
2889: System.out.println("uni5 equals uni5 ? "
2890: + uni5.equals(uni5));
2891: String uni6 = "\u05d0\u05d1\u05d2";
2892: System.out.println("uni6 is :" + uni6);
2893: System.out.println("uni5 equals uni6 ? "
2894: + uni5.equals(uni6));
2895: System.out.println("uni6 equals uni6 ? "
2896: + uni6.equals(uni6));
2897:
2898: FileWriter fw;
2899:
2900: } catch (Throwable e) {
2901: System.out.println("FAIL -- unexpected exception:"
2902: + e.toString());
2903: if (debug)
2904: e.printStackTrace(System.out);
2905: }
2906: }
2907:
2908: /*
2909: Set up a table with all kinds of blob values,
2910: some short (less than 1 page), some long (more than 1 page)
2911: some very large (many pages).
2912: Table has 2 cols: the first is the value, the second is the length of
2913: the value.
2914: (Also sets the fileLength array.)
2915: */
2916: private static void prepareBlobTable(Connection conn) {
2917: ResultSet rs;
2918: Statement stmt;
2919: System.out.println(START + "prepareBlobTable");
2920: try {
2921: stmt = conn.createStatement();
2922: // creating table to fit within default 4k table size, then add large column
2923: stmt.execute("create table testBlob (b integer)");
2924: stmt
2925: .execute("alter table testBlob add column a blob(300k)");
2926: stmt
2927: .execute("alter table testBlob add column crc32 BIGINT");
2928:
2929: PreparedStatement ps = conn
2930: .prepareStatement("insert into testBlob (a, b, crc32) values(?,?,?)");
2931:
2932: // insert small strings
2933: insertRow(ps, "".getBytes("US-ASCII"));
2934: insertRow(ps,
2935: "you can lead a horse to water but you can't form it into beverage"
2936: .getBytes("US-ASCII"));
2937: insertRow(ps, "a stitch in time says ouch"
2938: .getBytes("US-ASCII"));
2939: insertRow(ps, "here is a string with a return \n character"
2940: .getBytes("US-ASCII"));
2941:
2942: // insert larger strings using setBinaryStream
2943: for (int i = 0; i < numFiles; i++) {
2944: // prepare an InputStream from the file
2945: File file = new File(fileName[i]);
2946: fileLength[i] = file.length();
2947: InputStream fileIn = new FileInputStream(file);
2948:
2949: System.out.println("===> inserting " + basefileName[i]
2950: + " length = " + fileLength[i]);
2951:
2952: // insert a streaming column
2953: ps.setBinaryStream(1, fileIn, (int) fileLength[i]);
2954: ps.setInt(2, (int) fileLength[i]);
2955: ps.setLong(3, fileCRC32[i]);
2956: ps.executeUpdate();
2957: fileIn.close();
2958: }
2959:
2960: // insert a null
2961: ps.setNull(1, Types.BLOB);
2962: ps.setInt(2, 0);
2963: ps.setNull(3, Types.BIGINT);
2964: ps.executeUpdate();
2965:
2966: ps.close();
2967: conn.commit();
2968:
2969: // set numRows
2970: rs = stmt.executeQuery("select count(*) from testBlob");
2971: int realNumRows = -1;
2972: if (rs.next())
2973: realNumRows = rs.getInt(1);
2974: if (realNumRows <= 0)
2975: System.out
2976: .println("FAIL. No rows in table testCLOB_MAIN");
2977: if (realNumRows != numRows)
2978: System.out.println("FAIL. numRows is incorrect");
2979:
2980: stmt.close();
2981: conn.commit();
2982:
2983: } catch (SQLException e) {
2984: TestUtil.dumpSQLExceptions(e);
2985: } catch (Throwable e) {
2986: System.out.println("FAIL -- unexpected exception:"
2987: + e.toString());
2988: if (debug)
2989: e.printStackTrace(System.out);
2990: }
2991: }
2992:
2993: /*
2994: Set up a table with binary values,
2995: Table has 2 cols: the first is the value, the second is the length of
2996: the value.
2997: */
2998: private static void prepareBinaryTable(Connection conn) {
2999: ResultSet rs;
3000: Statement stmt;
3001: System.out.println(START + "prepareBinaryTable");
3002: try {
3003: stmt = conn.createStatement();
3004: stmt
3005: .execute("create table testBinary (a blob(80), b integer, crc32 bigint)");
3006: PreparedStatement ps = conn
3007: .prepareStatement("insert into testBinary values(?,?,?)");
3008:
3009: // insert small strings
3010: insertRow(ps, "".getBytes("US-ASCII"));
3011: insertRow(ps,
3012: "you can lead a horse to water but you can't form it into beverage"
3013: .getBytes("US-ASCII"));
3014: insertRow(ps, "a stitch in time says ouch"
3015: .getBytes("US-ASCII"));
3016: insertRow(ps, "here is a string with a return \n character"
3017: .getBytes("US-ASCII"));
3018:
3019: // insert a null
3020: // ps.setNull(1, Types.BINARY);
3021: // ps.setInt(2, 0);
3022: // ps.executeUpdate();
3023:
3024: conn.commit();
3025: } catch (SQLException e) {
3026: TestUtil.dumpSQLExceptions(e);
3027: } catch (Throwable e) {
3028: System.out.println("FAIL -- unexpected exception:"
3029: + e.toString());
3030: if (debug)
3031: e.printStackTrace(System.out);
3032: }
3033: }
3034:
3035: /*
3036: Set up a table with blobs to search for
3037: most short (less than 1 page), some long (more than 1 page)
3038: some very large (many pages) ??
3039: */
3040: private static void prepareSearchBlobTable(Connection conn) {
3041: ResultSet rs;
3042: Statement stmt;
3043: System.out.println(START + "prepareSearchBlobTable");
3044: try {
3045: stmt = conn.createStatement();
3046: // creating table to fit within default 4k table size, then add large column
3047: stmt.execute("create table searchBlob (b integer)");
3048: stmt
3049: .execute("alter table searchBlob add column a blob(300k)");
3050: stmt
3051: .execute("alter table searchBlob add column crc32 BIGINT");
3052: PreparedStatement ps = conn
3053: .prepareStatement("insert into searchBlob (a, b, crc32) values(?,?,?)");
3054: insertRow(ps, "horse".getBytes("US-ASCII"));
3055: insertRow(ps, "ouch".getBytes("US-ASCII"));
3056: insertRow(ps, "\n".getBytes("US-ASCII"));
3057: insertRow(ps, "".getBytes("US-ASCII"));
3058: insertRow(ps, "Beginning".getBytes("US-ASCII"));
3059: insertRow(ps, "position-69".getBytes("US-ASCII"));
3060: insertRow(ps, "I-am-hiding-here-at-position-5910"
3061: .getBytes("US-ASCII"));
3062: insertRow(ps, "Position-9907".getBytes("US-ASCII"));
3063:
3064: // insert larger blobs using setBinaryStream
3065: for (int i = 0; i < numFiles; i++) {
3066: // prepare an InputStream from the file
3067: File file = new File(fileName[i]);
3068: fileLength[i] = file.length();
3069: InputStream fileIn = new FileInputStream(file);
3070:
3071: System.out.println("===> inserting " + basefileName[i]
3072: + " length = " + fileLength[i]);
3073:
3074: // insert a streaming column
3075: ps.setBinaryStream(1, fileIn, (int) fileLength[i]);
3076: ps.setInt(2, (int) fileLength[i]);
3077: ps.setLong(3, fileCRC32[i]);
3078: ps.executeUpdate();
3079: fileIn.close();
3080: }
3081:
3082: // insert a null
3083: ps.setNull(1, Types.BLOB);
3084: ps.setInt(2, 0);
3085: ps.setNull(3, Types.BIGINT);
3086: ps.executeUpdate();
3087:
3088: conn.commit();
3089: } catch (SQLException e) {
3090: TestUtil.dumpSQLExceptions(e);
3091: } catch (Throwable e) {
3092: System.out.println("FAIL -- unexpected exception:"
3093: + e.toString());
3094: if (debug)
3095: e.printStackTrace(System.out);
3096: }
3097: }
3098:
3099: /*
3100: basic test of getBinaryStream
3101: also tests length
3102: need to run prepareBlobTable first
3103: */
3104: private static void blobTest0(Connection conn) {
3105: ResultSet rs;
3106: Statement stmt;
3107: System.out.println(START + "blobTest0");
3108: try {
3109: stmt = conn.createStatement();
3110: rs = stmt.executeQuery("select a,b,crc32 from testBlob");
3111: testBlobContents(rs);
3112: stmt.close();
3113: conn.commit();
3114: System.out.println("blobTest0 finished");
3115: } catch (SQLException e) {
3116: TestUtil.dumpSQLExceptions(e);
3117: } catch (Throwable e) {
3118: System.out.println("FAIL -- unexpected exception:"
3119: + e.toString());
3120: if (debug)
3121: e.printStackTrace(System.out);
3122: }
3123: }
3124:
3125: /**
3126: * Test the contents of the testBlob table or ResultSet
3127: * with identical shape.
3128: * @param rs
3129: * @throws SQLException
3130: * @throws IOException
3131: */
3132: private static void testBlobContents(ResultSet rs)
3133: throws SQLException, IOException {
3134: int nullCount = 0;
3135: int rowCount = 0;
3136: byte[] buff = new byte[128];
3137: // fetch row back, get the long varbinary column as a blob.
3138: Blob blob;
3139: int blobLength = 0, i = 0;
3140: while (rs.next()) {
3141: i++;
3142: // get the first column as a clob
3143: blob = rs.getBlob(1);
3144: long crc32 = rs.getLong(3);
3145: boolean crc2Null = rs.wasNull();
3146: if (blob == null) {
3147: if (!crc2Null)
3148: System.out
3149: .println("FAIL: NULL BLOB but non-NULL checksum");
3150: nullCount++;
3151: continue;
3152: }
3153:
3154: rowCount++;
3155:
3156: long blobcrc32 = getStreamCheckSum(blob.getBinaryStream());
3157:
3158: if (blobcrc32 != crc32) {
3159: System.out
3160: .println("FAIL: mismatched checksums for blob with length "
3161: + blob.length());
3162: }
3163:
3164: InputStream fin = blob.getBinaryStream();
3165: int columnSize = 0;
3166: for (;;) {
3167: int size = fin.read(buff);
3168: if (size == -1)
3169: break;
3170: columnSize += size;
3171: }
3172: blobLength = rs.getInt(2);
3173: if (columnSize != blobLength)
3174: System.out.println("test failed, columnSize should be "
3175: + blobLength + ", but it is " + columnSize
3176: + ", i = " + i);
3177: if (columnSize != blob.length())
3178: System.out
3179: .println("test failed, blob.length() should be "
3180: + columnSize
3181: + ", but it is "
3182: + blob.length() + ", i = " + i);
3183: }
3184: System.out.println("Row Count " + rowCount + " Null Row "
3185: + nullCount);
3186: }
3187:
3188: /*
3189: test getBytes
3190: need to run prepareBlobTable first
3191: */
3192: private static void blobTest2(Connection conn) {
3193: ResultSet rs;
3194: Statement stmt;
3195: System.out.println(START + "blobTest2");
3196: try {
3197: stmt = conn.createStatement();
3198: rs = stmt.executeQuery("select a,b from testBlob");
3199: int i = 0, blobLength = 0;
3200: Blob blob;
3201: while (rs.next()) {
3202: i++;
3203: blob = rs.getBlob(1);
3204: if (blob == null)
3205: continue;
3206: blobLength = rs.getInt(2);
3207: blobclob4BLOB.printInterval(blob, 9905, 50, 0, i,
3208: blobLength);
3209: blobclob4BLOB.printInterval(blob, 5910, 150, 1, i,
3210: blobLength);
3211: blobclob4BLOB.printInterval(blob, 5910, 50, 2, i,
3212: blobLength);
3213: blobclob4BLOB.printInterval(blob, 204, 50, 3, i,
3214: blobLength);
3215: blobclob4BLOB.printInterval(blob, 68, 50, 4, i,
3216: blobLength);
3217: blobclob4BLOB.printInterval(blob, 1, 50, 5, i,
3218: blobLength);
3219: blobclob4BLOB.printInterval(blob, 1, 1, 6, i,
3220: blobLength);
3221: blobclob4BLOB.printInterval(blob, 1, 0, 7, i,
3222: blobLength); // length 0 at start
3223: blobclob4BLOB.printInterval(blob, blobLength + 1, 0, 8,
3224: i, blobLength); // and end
3225: /*
3226: System.out.println(i + "(0) " + new String(blob.getBytes(9905,50), "US-ASCII"));
3227: System.out.println(i + "(1) " + new String(blob.getBytes(5910,150), "US-ASCII"));
3228: System.out.println(i + "(2) " + new String(blob.getBytes(5910,50), "US-ASCII"));
3229: System.out.println(i + "(3) " + new String(blob.getBytes(204,50), "US-ASCII"));
3230: System.out.println(i + "(4) " + new String(blob.getBytes(68,50), "US-ASCII"));
3231: System.out.println(i + "(5) " + new String(blob.getBytes(1,50), "US-ASCII"));
3232: System.out.println(i + "(6) " + new String(blob.getBytes(1,1), "US-ASCII"));
3233: */
3234: if (blobLength > 100) {
3235: byte[] res = blob.getBytes(blobLength - 99, 200);
3236: System.out.println(i + "(9) ");
3237: if (res.length != 100)
3238: System.out.println("FAIL : length of bytes is "
3239: + res.length + " should be 100");
3240: else
3241: System.out.println(new String(res, "US-ASCII")); // ensure fixed string
3242: }
3243: }
3244: stmt.close();
3245: conn.commit();
3246: System.out.println("blobTest2 finished");
3247: } catch (SQLException e) {
3248: TestUtil.dumpSQLExceptions(e);
3249: } catch (Throwable e) {
3250: System.out.println("FAIL -- unexpected exception:"
3251: + e.toString());
3252: if (debug)
3253: e.printStackTrace(System.out);
3254: }
3255: }
3256:
3257: /*
3258: test position with a byte[] argument
3259: need to run prepareBlobTable first
3260: */
3261: private static void blobTest3(Connection conn) {
3262: ResultSet rs;
3263: Statement stmt;
3264: System.out.println(START + "blobTest3");
3265: try {
3266: stmt = conn.createStatement();
3267: rs = stmt.executeQuery("select a,b from testBlob");
3268: int i = 0, blobLength = 0;
3269: Blob blob;
3270: while (rs.next()) {
3271: i++;
3272: blob = rs.getBlob(1);
3273: if (blob == null)
3274: continue;
3275: blobLength = rs.getInt(2);
3276: if (blobLength > 20000)
3277: continue;
3278: blobLength = rs.getInt(2);
3279: blobclob4BLOB.printPosition(i, "horse", 1, blob,
3280: blobLength);
3281: blobclob4BLOB.printPosition(i, "ouch", 1, blob,
3282: blobLength);
3283: blobclob4BLOB.printPosition(i, "\n", 1, blob,
3284: blobLength);
3285: blobclob4BLOB.printPosition(i, "", 1, blob, blobLength);
3286: blobclob4BLOB.printPosition(i, "Beginning", 1, blob,
3287: blobLength);
3288: blobclob4BLOB.printPosition(i, "Beginning", 2, blob,
3289: blobLength);
3290: blobclob4BLOB.printPosition(i, "position-69", 1, blob,
3291: blobLength);
3292: blobclob4BLOB.printPosition(i, "This-is-position-204",
3293: 1, blob, blobLength);
3294: blobclob4BLOB.printPosition(i,
3295: "I-am-hiding-here-at-position-5910", 1, blob,
3296: blobLength);
3297: blobclob4BLOB.printPosition(i,
3298: "I-am-hiding-here-at-position-5910", 5910,
3299: blob, blobLength);
3300: blobclob4BLOB.printPosition(i,
3301: "I-am-hiding-here-at-position-5910", 5911,
3302: blob, blobLength);
3303: blobclob4BLOB.printPosition(i, "Position-9907", 1,
3304: blob, blobLength);
3305: }
3306: stmt.close();
3307: conn.commit();
3308: System.out.println("blobTest3 finished");
3309: } catch (SQLException e) {
3310: TestUtil.dumpSQLExceptions(e);
3311: } catch (Throwable e) {
3312: System.out.println("FAIL -- unexpected exception:"
3313: + e.toString());
3314: if (debug)
3315: e.printStackTrace(System.out);
3316: }
3317: }
3318:
3319: /*
3320: test position with a Blob argument
3321: need to run prepareBlobTable and prepareSearchBlobTable first
3322: */
3323: private static void blobTest4(Connection conn) {
3324: ResultSet rs, rs2;
3325: Statement stmt, stmt2;
3326: System.out.println(START + "blobTest4");
3327: try {
3328: stmt = conn.createStatement();
3329: rs = stmt.executeQuery("select a,b from testBlob");
3330: int i = 0, blobLength = 0;
3331: Blob blob;
3332: while (rs.next()) {
3333: i++;
3334: blob = rs.getBlob(1);
3335: if (blob == null)
3336: continue;
3337: blobLength = rs.getInt(2);
3338: if (blobLength > 20000) {
3339: System.out.println("testBlob row " + i
3340: + " skipped (too large)");
3341: continue;
3342: }
3343: // inner loop over table of blobs to search for
3344: // blobs
3345: stmt2 = conn.createStatement();
3346: rs2 = stmt2.executeQuery("select a,b from searchBlob");
3347: int j = 0, blobLength2 = 0;
3348: Blob searchBlob;
3349: String searchStr;
3350: while (rs2.next()) {
3351: j++;
3352: searchBlob = rs2.getBlob(1);
3353: if (searchBlob == null)
3354: continue;
3355: blobLength2 = rs2.getInt(2);
3356: if (blobLength2 > 20000) {
3357: System.out.println("searchBlob row " + j
3358: + " skipped (too large)");
3359: continue;
3360: }
3361: if (blobLength2 < 150)
3362: // get string for printing from bytes in fixed format
3363: searchStr = new String(rs2.getBytes(1),
3364: "US-ASCII");
3365: else
3366: searchStr = null;
3367:
3368: printPositionBlob(i, searchStr, 1, blob, j,
3369: searchBlob);
3370: }
3371: stmt2.close();
3372: }
3373: stmt.close();
3374: conn.commit();
3375: System.out.println("blobTest4 finished");
3376: } catch (SQLException e) {
3377: TestUtil.dumpSQLExceptions(e);
3378: } catch (Throwable e) {
3379: System.out.println("FAIL -- unexpected exception:"
3380: + e.toString());
3381: if (debug)
3382: e.printStackTrace(System.out);
3383: }
3384: }
3385:
3386: /**
3387: * Test triggers on BLOB columns.
3388: */
3389: private static void blobTest8Trigger(Connection conn) {
3390: System.out.println(START + "blobTest8Trigger");
3391: try {
3392: Statement stmt = conn.createStatement();
3393: stmt
3394: .executeUpdate("CREATE TABLE blobTest8TriggerA (a BLOB(400k), b int, crc32 BIGINT)");
3395: stmt
3396: .executeUpdate("CREATE TABLE blobTest8TriggerB (a BLOB(400k), b int, crc32 BIGINT)");
3397: stmt
3398: .executeUpdate("create trigger T8A after update on testBlob "
3399: + "referencing new as n old as o "
3400: + "for each row mode db2sql "
3401: + "insert into blobTest8TriggerA(a, b, crc32) values (n.a, n.b, n.crc32)");
3402: stmt
3403: .executeUpdate("create trigger T8B after INSERT on blobTest8TriggerA "
3404: + "referencing new_table as n "
3405: + "for each statement mode db2sql "
3406: + "insert into blobTest8TriggerB(a, b, crc32) select n.a, n.b, n.crc32 from n");
3407:
3408: conn.commit();
3409: ResultSet rs = stmt
3410: .executeQuery("select a,b,crc32 from blobTest8TriggerA");
3411: testBlobContents(rs);
3412: rs.close();
3413: conn.commit();
3414: stmt.executeUpdate("UPDATE testBlob set b = b + 0");
3415: conn.commit();
3416: rs = stmt
3417: .executeQuery("select a,b,crc32 from blobTest8TriggerA");
3418: testBlobContents(rs);
3419: rs.close();
3420: conn.commit();
3421:
3422: rs = stmt
3423: .executeQuery("select a,b,crc32 from blobTest8TriggerB");
3424: testBlobContents(rs);
3425: rs.close();
3426: conn.commit();
3427: stmt.executeUpdate("DROP TRIGGER T8A");
3428: stmt.executeUpdate("DROP TABLE blobTest8TriggerB");
3429: stmt.executeUpdate("DROP TABLE blobTest8TriggerA");
3430:
3431: stmt.close();
3432: conn.commit();
3433: System.out.println("blobTest8Trigger finished");
3434: } catch (SQLException e) {
3435: TestUtil.dumpSQLExceptions(e);
3436: do {
3437: e.printStackTrace(System.out);
3438: e = e.getNextException();
3439: } while (e != null);
3440:
3441: } catch (Throwable e) {
3442: System.out.println("FAIL -- unexpected exception:"
3443: + e.toString());
3444: if (debug)
3445: e.printStackTrace(System.out);
3446: }
3447:
3448: }
3449:
3450: private static void printPositionBlob(int rowNum, String searchStr,
3451: long position, Blob blob, int searchRowNum, Blob searchBlob) {
3452:
3453: try {
3454: long result = blob.position(searchBlob, position);
3455: if ((searchStr != null) && searchStr.equals("")
3456: && (result == 1))
3457: return;
3458: if (result != -1) {
3459: System.out.print("Found ");
3460: if (searchStr != null)
3461: System.out.print(searchStr);
3462: else
3463: System.out
3464: .print("blob (row " + searchRowNum + ") ");
3465: System.out.println(" in row " + rowNum
3466: + " at position " + result);
3467: }
3468: } catch (SQLException e) {
3469: TestUtil.dumpSQLExceptions(e);
3470: }
3471: }
3472:
3473: /* datatype tests */
3474:
3475: // make sure blobs work for regular varbinary fields
3476: // also test length method
3477: private static void blobTest51(Connection conn) {
3478:
3479: ResultSetMetaData met;
3480: ResultSet rs;
3481: Statement stmt;
3482: System.out.println(START + "blobTest51");
3483: try {
3484: stmt = conn.createStatement();
3485: stmt.execute("create table testVarbinary (a blob(13))");
3486:
3487: PreparedStatement ps = conn
3488: .prepareStatement("insert into testVarbinary values(?)");
3489: String val = "";
3490:
3491: for (int i = 0; i < 10; i++) {
3492: // insert a string
3493: ps.setBytes(1, val.getBytes("US-ASCII"));
3494: ps.executeUpdate();
3495: val = val.trim() + "x";
3496: }
3497:
3498: rs = stmt.executeQuery("select a from testVarbinary");
3499: met = rs.getMetaData();
3500: byte[] buff = new byte[128];
3501: int j = 0;
3502: // fetch all rows back, get the columns as clobs.
3503: while (rs.next()) {
3504: // get the first column as a clob
3505: Blob blob = rs.getBlob(1);
3506: if (blob == null)
3507: continue;
3508: InputStream fin = blob.getBinaryStream();
3509: int columnSize = 0;
3510: for (;;) {
3511: int size = fin.read(buff);
3512: if (size == -1)
3513: break;
3514: columnSize += size;
3515: }
3516: if (columnSize != j)
3517: System.out.println("FAIL - Expected blob size : "
3518: + j + " Got blob size : " + columnSize);
3519: if (blob.length() != j)
3520: System.out
3521: .println("FAIL - Expected blob length : "
3522: + j + " Got blob length : "
3523: + blob.length());
3524: j++;
3525: }
3526: ps.close();
3527: stmt.close();
3528: conn.commit();
3529: System.out.println("blobTest51 finished");
3530: } catch (SQLException e) {
3531: TestUtil.dumpSQLExceptions(e);
3532: } catch (Throwable e) {
3533: System.out.println("FAIL -- unexpected exception:"
3534: + e.toString());
3535: if (debug)
3536: e.printStackTrace(System.out);
3537: }
3538: }
3539:
3540: // make sure cannot get a blob from an int column
3541: private static void blobTest52(Connection conn) {
3542:
3543: Statement stmt = null;
3544: System.out.println(START + "blobTest52");
3545: try {
3546: stmt = conn.createStatement();
3547: stmt.execute("create table testInteger2 (a integer)");
3548:
3549: PreparedStatement ps = conn
3550: .prepareStatement("insert into testInteger2 values(158)");
3551: ps.executeUpdate();
3552: ps.close();
3553:
3554: ResultSet rs = stmt
3555: .executeQuery("select a from testInteger2");
3556: while (rs.next()) {
3557: // get the first column as a clob
3558: try {
3559: Blob blob = rs.getBlob(1);
3560: System.out
3561: .println("FAIL fetched java.sql.Blob from INT column");
3562: } catch (SQLException e) {
3563: TestUtil.dumpSQLExceptions(e, "22005".equals(e
3564: .getSQLState())
3565: || "XCL12".equals(e.getSQLState()));
3566: break;
3567: }
3568: }
3569: stmt.close();
3570: conn.commit();
3571:
3572: } catch (SQLException e) {
3573: TestUtil.dumpSQLExceptions(e);
3574: } catch (Throwable e) {
3575: System.out.println("FAIL -- unexpected exception:"
3576: + e.toString());
3577: if (debug)
3578: e.printStackTrace(System.out);
3579: }
3580: System.out.println("blobTest52 finished");
3581: }
3582:
3583: // test creating a blob column, currently this doesn't work since we don't
3584: // have a blob datatype (get a syntax error on the create table statement)
3585: private static void blobTest53(Connection conn) {
3586:
3587: ResultSetMetaData met;
3588: ResultSet rs;
3589: Statement stmt;
3590: System.out.println(START + "blobTest53");
3591: try {
3592: stmt = conn.createStatement();
3593: stmt.execute("create table testBlobColumn (a blob(1K))");
3594: stmt.close();
3595: System.out.println("blobTest53 finished");
3596: } catch (SQLException e) {
3597: TestUtil.dumpSQLExceptions(e);
3598: } catch (Throwable e) {
3599: System.out.println("FAIL -- unexpected exception:"
3600: + e.toString());
3601: if (debug)
3602: e.printStackTrace(System.out);
3603: }
3604: }
3605:
3606: /*
3607: make sure setBlob doesn't work for an int column
3608: need to run prepareBlobTable first
3609: */
3610: private static void blobTest54(Connection conn) {
3611: ResultSet rs;
3612: Statement stmt;
3613: System.out.println(START + "blobTest54");
3614: try {
3615: stmt = conn.createStatement();
3616: stmt
3617: .execute("create table testBlob2 (a integer, b integer)");
3618: PreparedStatement ps = conn
3619: .prepareStatement("insert into testBlob2 values(?,?)");
3620: rs = stmt.executeQuery("select a,b from testBlob");
3621: Blob blob;
3622: int blobLength;
3623: while (rs.next()) {
3624: // get the first column as a blob
3625: blob = rs.getBlob(1);
3626: if (blob == null)
3627: continue;
3628: blobLength = rs.getInt(2);
3629: try {
3630: ps.setBlob(1, blob);
3631: ps.setInt(2, blobLength);
3632: ps.executeUpdate();
3633: System.out
3634: .println("FAIL setBlob worked on INT column");
3635: } catch (SQLException e) {
3636: TestUtil.dumpSQLExceptions(e, "22005".equals(e
3637: .getSQLState())
3638: || "XCL12".equals(e.getSQLState()));
3639: break;
3640: }
3641: }
3642: rs.close();
3643: conn.commit();
3644: stmt.close();
3645:
3646: } catch (SQLException e) {
3647: TestUtil.dumpSQLExceptions(e);
3648: } catch (Throwable e) {
3649: System.out.println("FAIL -- unexpected exception:"
3650: + e.toString());
3651: if (debug)
3652: e.printStackTrace(System.out);
3653: }
3654: System.out.println("blobTest54 finished");
3655: }
3656:
3657: /*
3658: test raising of exceptions
3659: need to run prepareBlobTable first
3660: */
3661: private static void blobTest6(Connection conn) {
3662: ResultSet rs;
3663: Statement stmt;
3664: System.out.println(START + "blobTest6");
3665: try {
3666: stmt = conn.createStatement();
3667: rs = stmt.executeQuery("select a,b from testBlob");
3668: int i = 0, blobLength = 0;
3669: Blob blob;
3670: while (rs.next()) {
3671: if (i > 0)
3672: break;
3673: i++;
3674: blob = rs.getBlob(1);
3675: if (blob == null)
3676: continue;
3677: blobLength = rs.getInt(2);
3678: // test end cases
3679:
3680: // 0 or negative position value
3681: try {
3682: blob.getBytes(0, 5);
3683: } catch (SQLException e) {
3684: TestUtil.dumpSQLExceptions(e,
3685: isOutOfBoundException(e));
3686: }
3687: // negative length value
3688: try {
3689: blob.getBytes(1, -76);
3690: } catch (SQLException e) {
3691: TestUtil.dumpSQLExceptions(e,
3692: isOutOfBoundException(e));
3693: }
3694: // zero length value
3695: try {
3696: blob.getBytes(1, -1);
3697: } catch (SQLException e) {
3698: TestUtil.dumpSQLExceptions(e,
3699: isOutOfBoundException(e));
3700: }
3701: // before begin length 0
3702: try {
3703: blob.getBytes(0, 0);
3704: } catch (SQLException e) {
3705: TestUtil.dumpSQLExceptions(e,
3706: isOutOfBoundException(e));
3707: }
3708: // after end length 0
3709: try {
3710: blob.getBytes(blobLength + 2, 0);
3711: } catch (SQLException e) {
3712: TestUtil.dumpSQLExceptions(e,
3713: isOutOfBoundException(e));
3714: }
3715: // 0 or negative position value
3716: try {
3717: blob.position(new byte[0], -4000);
3718: } catch (SQLException e) {
3719: TestUtil.dumpSQLExceptions(e,
3720: isOutOfBoundException(e));
3721: }
3722: // null pattern
3723: try {
3724: // bug 5247 in network server (NPE)
3725: blob.position((byte[]) null, 5);
3726: } catch (SQLException e) {
3727: TestUtil.dumpSQLExceptions(e,
3728: isNullSearchPattern(e));
3729: }
3730: // 0 or negative position value
3731: try {
3732: blob.position(blob, -42);
3733: } catch (SQLException e) {
3734: TestUtil.dumpSQLExceptions(e,
3735: isOutOfBoundException(e));
3736: }
3737: // null pattern
3738: try {
3739: blob.position((Blob) null, 5);
3740: } catch (SQLException e) {
3741: TestUtil.dumpSQLExceptions(e,
3742: isNullSearchPattern(e));
3743: }
3744: }
3745: stmt.close();
3746: conn.commit();
3747: System.out.println("blobTest6 finished");
3748: } catch (SQLException e) {
3749: TestUtil.dumpSQLExceptions(e);
3750: } catch (Throwable e) {
3751: if (e instanceof NullPointerException) {
3752: if (isDerbyNet)
3753: System.out
3754: .println("NullPointerException: KNOWN JCC issue Bug 5247");
3755: } else {
3756: System.out.println("FAIL -- unexpected exception:"
3757: + e.toString());
3758: if (debug)
3759: e.printStackTrace(System.out);
3760: }
3761: }
3762: }
3763:
3764: /*
3765: test setBlob
3766: need to run prepareBlobTable first
3767: */
3768: private static void blobTest7(Connection conn) {
3769: ResultSet rs, rs2;
3770: Statement stmt1, stmt2;
3771: System.out.println(START + "blobTest7");
3772: try {
3773: stmt1 = conn.createStatement();
3774: stmt1
3775: .execute("create table testBlobX (a blob(300K), b integer)");
3776: PreparedStatement ps = conn
3777: .prepareStatement("insert into testBlobX values(?,?)");
3778: stmt2 = conn.createStatement();
3779: rs = stmt2.executeQuery("select a,b from testBlob");
3780: Blob blob;
3781: int blobLength;
3782: while (rs.next()) {
3783: // get the first column as a blob
3784: blob = rs.getBlob(1);
3785: if (blob == null)
3786: continue;
3787: blobLength = rs.getInt(2);
3788: ps.setBlob(1, blob);
3789: ps.setInt(2, blobLength);
3790: ps.executeUpdate();
3791: }
3792: rs.close();
3793: conn.commit();
3794:
3795: rs2 = stmt2.executeQuery("select a,b from testBlobX");
3796: Blob blob2;
3797: int blobLength2, j = 0;
3798: while (rs2.next()) {
3799: j++;
3800: // get the first column as a clob
3801: blob2 = rs2.getBlob(1);
3802: if (blob2 == null)
3803: continue;
3804: blobLength2 = rs2.getInt(2);
3805: if (blob2.length() != blobLength2)
3806: System.out.println("FAILED at row " + j);
3807: }
3808: rs2.close();
3809:
3810: stmt1.close();
3811: stmt2.close();
3812: conn.commit();
3813: System.out.println("blobTest7 finished");
3814: } catch (SQLException e) {
3815: TestUtil.dumpSQLExceptions(e);
3816: } catch (Throwable e) {
3817: System.out
3818: .println("blobTest7 FAIL -- unexpected exception:"
3819: + e.toString());
3820: e.fillInStackTrace();
3821: if (debug)
3822: e.printStackTrace(System.out);
3823: }
3824: }
3825:
3826: /* advanced tests */
3827:
3828: // make sure blob is still around after we go to the next row,
3829: // after we close the result set, and after we close the statement
3830: private static void blobTest91(Connection conn) {
3831: ResultSet rs;
3832: Statement stmt;
3833: System.out.println(START + "blobTest91");
3834: try {
3835: stmt = conn.createStatement();
3836: rs = stmt.executeQuery("select a,b from testBlob");
3837: byte[] buff = new byte[128];
3838: Blob[] blobArray = new Blob[numRows];
3839: int[] blobLengthArray = new int[numRows];
3840: int j = 0;
3841: while (rs.next()) {
3842: blobArray[j] = rs.getBlob(1);
3843: blobLengthArray[j++] = rs.getInt(2);
3844: }
3845: rs.close();
3846: stmt.close();
3847:
3848: for (int i = 0; i < numRows; i++) {
3849: if (blobArray[i] == null) {
3850: System.out
3851: .println("row " + i + " is null, skipped");
3852: continue;
3853: }
3854: InputStream fin = blobArray[i].getBinaryStream();
3855: int columnSize = 0;
3856: for (;;) {
3857: int size = fin.read(buff);
3858: if (size == -1)
3859: break;
3860: columnSize += size;
3861: }
3862: if (columnSize != blobLengthArray[i])
3863: System.out
3864: .println("test failed, columnSize should be "
3865: + blobLengthArray[i]
3866: + ", but it is "
3867: + columnSize
3868: + ", i = " + i);
3869: if (columnSize != blobArray[i].length())
3870: System.out
3871: .println("test failed, blobArray[i].length() should be "
3872: + columnSize
3873: + ", but it is "
3874: + blobArray[i].length()
3875: + ", i = "
3876: + i);
3877: System.out.println("done row " + i + ", length was "
3878: + blobLengthArray[i]);
3879: }
3880: System.out.println("blobTest91 finished");
3881: } catch (SQLException e) {
3882: TestUtil.dumpSQLExceptions(e);
3883: } catch (Throwable e) {
3884: System.out.println("FAIL -- unexpected exception:"
3885: + e.toString());
3886: if (debug)
3887: e.printStackTrace(System.out);
3888: }
3889: }
3890:
3891: /*
3892: test locking
3893: need to run prepareBlobTable first
3894: */
3895: private static void blobTest92(Connection conn) {
3896: ResultSet rs;
3897: Statement stmt, stmt2;
3898: System.out.println(START + "blobTest92");
3899: try {
3900: stmt = conn.createStatement();
3901: rs = stmt.executeQuery("select a,b from testBlob");
3902: // fetch row back, get the column as a blob.
3903: Blob blob = null, shortBlob = null;
3904: int blobLength;
3905: while (rs.next()) {
3906: blobLength = rs.getInt(2);
3907: if (blobLength == 10000)
3908: blob = rs.getBlob(1);
3909: if (blobLength == 26)
3910: shortBlob = rs.getBlob(1);
3911: }
3912: rs.close();
3913:
3914: Connection conn2 = ij.startJBMS();
3915: // turn off autocommit, otherwise blobs/clobs cannot hang around
3916: // until end of transaction
3917: conn2.setAutoCommit(false);
3918: if (!TestUtil.isNetFramework()) {
3919: // Note: Locks held until the end of transaction only for embedded.
3920: // Network Server cannot differentiate a getBlob from a getBytes so
3921: // does not hold locks for blob calls (DERBY-255)
3922: // The LOB is materialized on the client so we do not need to hold locks.
3923: // One ugly thing about this test is that these rows are used by other tests.
3924: // If this tests fails and the rows get updated, other tests can get
3925: // NullPointer exceptions.
3926:
3927: // Update should go through since we don't get any locks on blobs
3928: // that are not long columns
3929: stmt2 = conn2.createStatement();
3930: stmt2
3931: .executeUpdate("update testBlob set a = null where b = 26");
3932: if (shortBlob.length() != 26)
3933: System.out
3934: .println("FAILED: blob length changed to "
3935: + shortBlob.length());
3936: // should timeout waiting for the lock to do this
3937:
3938: stmt2 = conn2.createStatement();
3939: stmt2
3940: .executeUpdate("update testBlob set b = b + 1 where b = 10000");
3941: throw new Exception(
3942: "FAIL: Should have gotten lock timeout");
3943: } else {
3944: System.out
3945: .println("Locks not held by Network Server for Blobs since they are materialized on client");
3946: }
3947: conn.commit();
3948: conn2.commit();
3949: System.out.println("blobTest92 finished");
3950: } catch (SQLException e) {
3951: TestUtil.dumpSQLExceptions(e);
3952: } catch (Throwable e) {
3953: System.out.println("FAIL -- unexpected exception:"
3954: + e.toString());
3955: if (debug)
3956: e.printStackTrace(System.out);
3957: }
3958: }
3959:
3960: /*
3961: test locking with a long row + long column
3962: */
3963: private static void blobTest93(Connection conn) {
3964: ResultSet rs;
3965: Statement stmt, stmt2;
3966: System.out.println(START + "blobTest93");
3967: try {
3968: stmt = conn.createStatement();
3969: // creating table to fit within default 4k table size, then add large columns
3970: stmt
3971: .execute("create table testLongRowBlob (a varchar(2000))");
3972: stmt
3973: .execute("alter table testLongRowBlob add column b varchar(3000)");
3974: stmt
3975: .execute("alter table testLongRowBlob add column c varchar(2000)");
3976: stmt
3977: .execute("alter table testLongRowBlob add column d varchar(3000)");
3978: stmt
3979: .execute("alter table testLongRowBlob add column e blob(300k)");
3980: PreparedStatement ps = conn
3981: .prepareStatement("insert into testLongRowBlob values(?,?,?,?,?)");
3982: ps.setString(1, Formatters.padString("blaaa", 2000));
3983: ps.setString(2, Formatters.padString("tralaaaa", 3000));
3984: ps.setString(3, Formatters.padString("foodar", 2000));
3985: ps.setString(4, Formatters.padString("moped", 3000));
3986: File file = new File(fileName[1]);
3987: if (file.length() < 10000)
3988: System.out.println("ERROR: wrong file tested");
3989: InputStream fileIn = new FileInputStream(file);
3990:
3991: ps.setBinaryStream(5, fileIn, (int) file.length());
3992: ps.executeUpdate();
3993: fileIn.close();
3994: conn.commit();
3995:
3996: stmt = conn.createStatement();
3997: rs = stmt.executeQuery("select e from testLongRowBlob");
3998: Blob blob = null;
3999: while (rs.next()) {
4000: blob = rs.getBlob(1);
4001: checkBlobAgainstFile(1, blob);
4002: }
4003: rs.close();
4004:
4005: Connection conn2 = ij.startJBMS();
4006: // turn off autocommit, otherwise blobs/clobs cannot hang around
4007: // until end of transaction
4008: conn2.setAutoCommit(false);
4009: // the following should timeout
4010: stmt2 = conn2.createStatement();
4011: stmt2
4012: .executeUpdate("update testLongRowBlob set e = null where a = 'blaaa'");
4013:
4014: conn.commit();
4015: conn2.commit();
4016: System.out.println("blobTest93 finished");
4017: } catch (SQLException e) {
4018: TestUtil.dumpSQLExceptions(e);
4019: } catch (Throwable e) {
4020: System.out.println("FAIL -- unexpected exception:"
4021: + e.toString());
4022: if (debug)
4023: e.printStackTrace(System.out);
4024: }
4025: }
4026:
4027: /*
4028: test accessing blob after commit
4029: need to run prepareCLOBMAIN first
4030: */
4031: private static void blobTest94(Connection conn) {
4032: ResultSet rs;
4033: Statement stmt;
4034: System.out.println(START + "blobTest94");
4035: try {
4036: stmt = conn.createStatement();
4037: rs = stmt.executeQuery("select a,b from testBlob");
4038: // fetch row back, get the column as a blob.
4039: Blob blob = null, shortBlob = null;
4040: int blobLength;
4041: while (rs.next()) {
4042: blobLength = rs.getInt(2);
4043: if (blobLength == 10000)
4044: blob = rs.getBlob(1);
4045: if (blobLength == 26)
4046: shortBlob = rs.getBlob(1);
4047: }
4048: rs.close();
4049: conn.commit();
4050:
4051: // no problem accessing this after commit since it is in memory
4052: if (shortBlob != null)
4053: System.out.println("shortBlob length after commit is "
4054: + shortBlob.length());
4055: // these should all give blob/clob data unavailable exceptions
4056:
4057: try {
4058: blob.length();
4059: } catch (SQLException e) {
4060: TestUtil.dumpSQLExceptions(e);
4061: }
4062: try {
4063: blob.getBytes(2, 3);
4064: } catch (SQLException e) {
4065: TestUtil.dumpSQLExceptions(e);
4066: }
4067: try {
4068: blob.getBinaryStream();
4069: } catch (SQLException e) {
4070: TestUtil.dumpSQLExceptions(e);
4071: }
4072: try {
4073: blob.position("foo".getBytes("US-ASCII"), 2);
4074: } catch (SQLException e) {
4075: TestUtil.dumpSQLExceptions(e);
4076: }
4077: try {
4078: blob.position(blob, 2);
4079: } catch (SQLException e) {
4080: TestUtil.dumpSQLExceptions(e);
4081: }
4082:
4083: System.out.println("blobTest94 finished");
4084: } catch (SQLException e) {
4085: TestUtil.dumpSQLExceptions(e);
4086: } catch (Throwable e) {
4087: System.out.println("FAIL -- unexpected exception:"
4088: + e.toString());
4089: if (debug)
4090: e.printStackTrace(System.out);
4091: }
4092:
4093: }
4094:
4095: /*
4096: test accessing blob after closing the connection
4097: need to run prepareCLOBMAIN first
4098: */
4099: private static void blobTest95(Connection conn) {
4100: ResultSet rs;
4101: Statement stmt;
4102: System.out.println(START + "blobTest95");
4103: try {
4104: stmt = conn.createStatement();
4105: rs = stmt.executeQuery("select a,b from testBlob");
4106: // fetch row back, get the column as a blob.
4107: Blob blob = null, shortBlob = null;
4108: int blobLength;
4109: while (rs.next()) {
4110: blobLength = rs.getInt(2);
4111: if (blobLength == 10000)
4112: blob = rs.getBlob(1);
4113: if (blobLength == 26)
4114: shortBlob = rs.getBlob(1);
4115: }
4116: rs.close();
4117: conn.rollback();
4118: conn.close();
4119:
4120: try {
4121: // no problem accessing this after commit since it is in memory
4122: System.out
4123: .println("shortBlob length after closing the connection is "
4124: + shortBlob.length());
4125: } catch (SQLException e) {
4126: expectedExceptionForNSOnly(e);
4127: }
4128:
4129: // these should all give blob/clob data unavailable exceptions
4130: try {
4131: blob.length();
4132: } catch (SQLException e) {
4133: expectedExceptionForNSOnly(e);
4134: }
4135: try {
4136: blob.getBytes(2, 3);
4137: } catch (SQLException e) {
4138: expectedExceptionForNSOnly(e);
4139: }
4140: try {
4141: blob.getBinaryStream();
4142: } catch (SQLException e) {
4143: expectedExceptionForNSOnly(e);
4144: }
4145: try {
4146: blob.position("foo".getBytes("US-ASCII"), 2);
4147: } catch (SQLException e) {
4148: expectedExceptionForNSOnly(e);
4149: }
4150: try {
4151: blob.position(blob, 2);
4152: } catch (SQLException e) {
4153: expectedExceptionForNSOnly(e);
4154: }
4155:
4156: // restart the connection
4157: conn = ij.startJBMS();
4158: conn.setAutoCommit(false);
4159:
4160: System.out.println("blobTest95 finished");
4161: } catch (SQLException e) {
4162: TestUtil.dumpSQLExceptions(e);
4163: } catch (Throwable e) {
4164: System.out.println("FAIL -- unexpected exception:"
4165: + e.toString());
4166: if (debug)
4167: e.printStackTrace(System.out);
4168: }
4169: }
4170:
4171: /*
4172: test blob finalizer closes the container
4173: (should only release table and row locks that are read_committed)
4174: need to run prepareCLOBMAIN first
4175: NOTE: this test does not produce output since it needs to call the
4176: garbage collector whose behaviour is unreliable. It is in the test run to
4177: exercise the code (most of the time).
4178: */
4179: private static void blobTest96(Connection conn) {
4180: ResultSet rs;
4181: Statement stmt;
4182: System.out.println(START + "blobTest96");
4183: try {
4184: stmt = conn.createStatement();
4185: rs = stmt.executeQuery("select a,b from testBlob");
4186: byte[] buff = new byte[128];
4187: Blob[] blobArray = new Blob[numRows];
4188: int[] blobLengthArray = new int[numRows];
4189: int j = 0;
4190: while (rs.next()) {
4191: blobArray[j] = rs.getBlob(1);
4192: blobLengthArray[j++] = rs.getInt(2);
4193: }
4194: rs.close();
4195: stmt.close();
4196:
4197: // printLockTable(conn);
4198:
4199: for (int i = 0; i < numRows; i++) {
4200: blobArray[i] = null;
4201: }
4202:
4203: // printLockTable(conn);
4204:
4205: System.gc();
4206: System.gc();
4207:
4208: // System.out.println("after gc");
4209: // printLockTable(conn);
4210:
4211: System.out.println("blobTest96 finished");
4212: } catch (SQLException e) {
4213: TestUtil.dumpSQLExceptions(e);
4214: } catch (Throwable e) {
4215: System.out.println("FAIL -- unexpected exception:"
4216: + e.toString());
4217: if (debug)
4218: e.printStackTrace(System.out);
4219: }
4220: }
4221:
4222: /**
4223: * Test fix for derby-1382.
4224: *
4225: * Test that the getBlob() returns the correct value for the blob before and
4226: * after updating the blob when using result sets of type
4227: * TYPE_SCROLL_INSENSITIVE.
4228: *
4229: * The method updateBytes(int, byte[]) is used to set the value on the
4230: * clob because the method updateClob(int, Clob) has not yet been
4231: * implemented for DerbyNetClient.
4232:
4233: *
4234: * @param conn Connection
4235: * @throws SQLException
4236: */
4237: private static void blobTest10(Connection conn) throws SQLException {
4238: Statement s = conn.createStatement();
4239: s.execute("CREATE TABLE derby1382 (c1 int, c2 blob)");
4240:
4241: String blobData = "initial blob ";
4242: PreparedStatement ps = conn
4243: .prepareStatement("insert into derby1382 values (?, ?)");
4244: for (int i = 0; i < 10; i++) {
4245: ps.setInt(1, i);
4246: ps.setBytes(2, (blobData + i).getBytes());
4247: ps.execute();
4248: }
4249: ps.close();
4250:
4251: Statement scrollStmt = conn.createStatement(
4252: ResultSet.TYPE_SCROLL_INSENSITIVE,
4253: ResultSet.CONCUR_UPDATABLE);
4254: ResultSet rs = scrollStmt
4255: .executeQuery("SELECT * FROM derby1382");
4256:
4257: rs.first();
4258: checkContentsBeforeAndAfterUpdatingBlob(rs);
4259: rs.next();
4260: checkContentsBeforeAndAfterUpdatingBlob(rs);
4261: rs.relative(3);
4262: checkContentsBeforeAndAfterUpdatingBlob(rs);
4263: rs.absolute(7);
4264: checkContentsBeforeAndAfterUpdatingBlob(rs);
4265: rs.previous();
4266: checkContentsBeforeAndAfterUpdatingBlob(rs);
4267: rs.last();
4268: checkContentsBeforeAndAfterUpdatingBlob(rs);
4269: rs.previous();
4270: checkContentsBeforeAndAfterUpdatingBlob(rs);
4271:
4272: rs.close();
4273: scrollStmt.close();
4274:
4275: s.execute("DROP TABLE derby1382");
4276: s.close();
4277: }
4278:
4279: private static void checkContentsBeforeAndAfterUpdatingBlob(
4280: ResultSet rs) throws SQLException {
4281: Blob b;
4282: byte[] value, expectedValue;
4283: String blobData = "initial blob ";
4284: String updatedBlobData = "updated blob ";
4285:
4286: b = rs.getBlob(2);
4287: // check contents
4288: value = b.getBytes(1, blobData.length() + 1);
4289: expectedValue = (blobData + rs.getInt(1)).getBytes();
4290: if (!Arrays.equals(value, expectedValue)) {
4291: System.out.println("blobTest10 - Error: wrong blob value");
4292: }
4293:
4294: // update contents
4295: value = (updatedBlobData + rs.getInt(1)).getBytes();
4296: rs.updateBytes(2, value);
4297: rs.updateRow();
4298: // check update values
4299: rs.next(); // leave the row
4300: rs.previous(); // go back to updated row
4301: b = rs.getBlob(2);
4302: // check contents
4303: value = b.getBytes(1, updatedBlobData.length() + 1);
4304: expectedValue = (updatedBlobData + rs.getInt(1)).getBytes();
4305: if (!Arrays.equals(value, expectedValue)) {
4306: System.out.println("blobTest10 - Error: wrong blob value");
4307: }
4308: }
4309:
4310: /**
4311: * Test fix for derby-1421.
4312: *
4313: * Test that the getBlob() returns the correct value for the blob before and
4314: * after updating the blob using the method updateBinaryStream().
4315: *
4316: * @param conn Connection
4317: * @throws SQLException
4318: */
4319: private static void blobTest11(Connection conn) throws SQLException {
4320: Statement s = conn.createStatement();
4321: s.execute("CREATE TABLE derby1421 (c1 int, c2 blob)");
4322:
4323: String blobData = "initial blob ";
4324: PreparedStatement ps = conn
4325: .prepareStatement("insert into derby1421 values (?, ?)");
4326: for (int i = 0; i < 10; i++) {
4327: ps.setInt(1, i);
4328: ps.setBytes(2, (blobData + i).getBytes());
4329: ps.execute();
4330: }
4331: ps.close();
4332:
4333: Statement scrollStmt = conn.createStatement(
4334: ResultSet.TYPE_SCROLL_INSENSITIVE,
4335: ResultSet.CONCUR_UPDATABLE);
4336: ResultSet rs = scrollStmt
4337: .executeQuery("SELECT * FROM derby1421");
4338:
4339: rs.first();
4340: updateBlobWithUpdateBinaryStream(rs);
4341: rs.next();
4342: updateBlobWithUpdateBinaryStream(rs);
4343: rs.relative(3);
4344: updateBlobWithUpdateBinaryStream(rs);
4345: rs.absolute(7);
4346: updateBlobWithUpdateBinaryStream(rs);
4347: rs.previous();
4348: updateBlobWithUpdateBinaryStream(rs);
4349: rs.last();
4350: updateBlobWithUpdateBinaryStream(rs);
4351: rs.previous();
4352: updateBlobWithUpdateBinaryStream(rs);
4353:
4354: rs.close();
4355: scrollStmt.close();
4356:
4357: s.execute("DROP TABLE derby1421");
4358: s.close();
4359: }
4360:
4361: private static void updateBlobWithUpdateBinaryStream(ResultSet rs)
4362: throws SQLException {
4363: Blob b;
4364: byte[] value, expectedValue;
4365: String blobData = "initial blob ";
4366: String updatedBlobData = "updated blob ";
4367:
4368: b = rs.getBlob(2);
4369: // check contents
4370: value = b.getBytes(1, blobData.length() + 1);
4371: expectedValue = (blobData + rs.getInt(1)).getBytes();
4372: if (!Arrays.equals(value, expectedValue)) {
4373: System.out.println("blobTest11 - Error: wrong blob value");
4374: }
4375:
4376: // update contents
4377: value = (updatedBlobData + rs.getInt(1)).getBytes();
4378: InputStream updateValue = new ByteArrayInputStream(value);
4379: rs.updateBinaryStream(2, updateValue, value.length);
4380: rs.updateRow();
4381: // check update values
4382: rs.next(); // leave the row
4383: rs.previous(); // go back to updated row
4384: b = rs.getBlob(2);
4385: // check contents
4386: value = b.getBytes(1, updatedBlobData.length() + 1);
4387: expectedValue = (updatedBlobData + rs.getInt(1)).getBytes();
4388: if (!Arrays.equals(value, expectedValue)) {
4389: System.out.println("blobTest11 - Error: wrong blob value");
4390: }
4391: }
4392:
4393: /**
4394: * Test fix for derby-265.
4395: * Test that if getBlob is called after the transaction
4396: * in which it was created is committed, a proper user error
4397: * is thrown instead of an NPE.
4398: * Basically per the spec, getBlob is valid only for the duration of
4399: * the transaction in it was created in
4400: * @param conn
4401: * @throws SQLException
4402: * @throws FileNotFoundException
4403: * @throws IOException
4404: */
4405: private static void blobNegativeTest_Derby265(Connection conn)
4406: throws SQLException, FileNotFoundException, IOException {
4407: System.out.println(START + "blobTestNegativeTest_Derby265");
4408: // basically setup the tables for clob and blob
4409: Statement s = conn.createStatement();
4410: s
4411: .execute("create table \"MAPS_BLOB\"(MAP_ID int, MAP_NAME varchar(20),REGION varchar(20),AREA varchar(20), PHOTO_FORMAT varchar(20),PICTURE blob(2G))");
4412: conn.setAutoCommit(false);
4413: PreparedStatement ps = conn
4414: .prepareStatement("insert into \"MAPS_BLOB\" values(?,?,?,?,?,?)");
4415:
4416: for (int i = 0; i < 3; i++) {
4417: FileInputStream fis = new FileInputStream(fileName[4]);
4418: ps.setInt(1, i);
4419: ps.setString(2, "x" + i);
4420: ps.setString(3, "abc");
4421: ps.setString(4, "abc");
4422: ps.setString(5, "abc");
4423: ps.setBinaryStream(6, new java.io.BufferedInputStream(fis),
4424: 300000);
4425: ps.executeUpdate();
4426: fis.close();
4427: }
4428: conn.commit();
4429:
4430: conn.setAutoCommit(true);
4431: System.out.println("-----------------------------");
4432:
4433: s = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY,
4434: ResultSet.CONCUR_READ_ONLY);
4435: s
4436: .execute("SELECT \"MAP_ID\", \"MAP_NAME\", \"REGION\", \"AREA\", \"PHOTO_FORMAT\", \"PICTURE\" FROM \"MAPS_BLOB\"");
4437: ResultSet rs1 = s.getResultSet();
4438: Statement s2 = conn
4439: .createStatement(ResultSet.TYPE_FORWARD_ONLY,
4440: ResultSet.CONCUR_READ_ONLY);
4441: s2
4442: .executeQuery("SELECT \"MAP_ID\", \"MAP_NAME\", \"REGION\", \"AREA\", \"PHOTO_FORMAT\", \"PICTURE\" FROM \"MAPS_BLOB\"");
4443: ResultSet rs2 = s2.getResultSet();
4444: rs2.next();
4445:
4446: Blob b2 = rs2.getBlob(6);
4447: rs1.next();
4448: Blob b1 = rs1.getBlob(6);
4449: try {
4450: rs1.close();
4451: rs2.next();
4452: rs2.getBlob(6);
4453: } catch (SQLException sqle) {
4454: String sqlstate = sqle.getSQLState();
4455: boolean expected = (sqlstate != null && (sqlstate
4456: .equals("XJ073") || sqlstate.equals("XCL30")));
4457: if (!expected) {
4458: TestUtil.dumpSQLExceptions(sqle, expected);
4459: }
4460: } finally {
4461: rs2.close();
4462: s2.close();
4463: s.close();
4464: ps.close();
4465: }
4466:
4467: }
4468:
4469: /**
4470: * Test fix for derby-265.
4471: * Test that if getClob is called after the transaction
4472: * in which it was created is committed, a proper user error
4473: * is thrown instead of an NPE.
4474: * Basically per the spec, getClob is valid only for the duration of
4475: * the transaction in it was created in
4476: * @param conn
4477: * @throws SQLException
4478: * @throws FileNotFoundException
4479: * @throws IOException
4480: */
4481: private static void clobNegativeTest_Derby265(Connection conn)
4482: throws SQLException, FileNotFoundException, IOException {
4483:
4484: System.out.println(START + "clobNegativeTest_Derby265");
4485: // basically setup the tables for clob
4486: Statement s = conn.createStatement();
4487: s
4488: .execute("create table \"MAPS\"(MAP_ID int, MAP_NAME varchar(20),REGION varchar(20),AREA varchar(20), PHOTO_FORMAT varchar(20),PICTURE clob(2G))");
4489: conn.setAutoCommit(false);
4490: PreparedStatement ps = conn
4491: .prepareStatement("insert into \"MAPS\" values(?,?,?,?,?,?)");
4492: for (int i = 0; i < 3; i++) {
4493: File file = new File(fileName[4]);
4494: InputStream fileIS = new FileInputStream(file);
4495: Reader fr = new InputStreamReader(fileIS, "US-ASCII");
4496: ps.setInt(1, i);
4497: ps.setString(2, "x" + i);
4498: ps.setString(3, "abc");
4499: ps.setString(4, "abc");
4500: ps.setString(5, "abc");
4501: ps.setCharacterStream(6, fr, 300000);
4502: ps.executeUpdate();
4503: fr.close();
4504: }
4505: conn.commit();
4506:
4507: conn.setAutoCommit(true);
4508: System.out.println("-----------------------------");
4509: s = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY,
4510: ResultSet.CONCUR_READ_ONLY);
4511: s
4512: .execute("SELECT \"MAP_ID\", \"MAP_NAME\", \"REGION\", \"AREA\", \"PHOTO_FORMAT\", \"PICTURE\" FROM \"MAPS\"");
4513: ResultSet rs1 = s.getResultSet();
4514: Statement s2 = conn
4515: .createStatement(ResultSet.TYPE_FORWARD_ONLY,
4516: ResultSet.CONCUR_READ_ONLY);
4517: s2
4518: .executeQuery("SELECT \"MAP_ID\", \"MAP_NAME\", \"REGION\", \"AREA\", \"PHOTO_FORMAT\", \"PICTURE\" FROM \"MAPS\"");
4519: ResultSet rs2 = s2.getResultSet();
4520: rs2.next();
4521:
4522: Clob b2 = rs2.getClob(6); // should be fine
4523: rs1.next();
4524: Clob b1 = rs1.getClob(6);
4525: try {
4526: rs1.close(); // this commits the transaction
4527: rs2.next();
4528: rs2.getClob(6); // no longer valid
4529: } catch (SQLException sqle) {
4530: String sqlstate = sqle.getSQLState();
4531: boolean expected = (sqlstate != null && (sqlstate
4532: .equals("XJ073") || sqlstate.equals("XCL30")));
4533: if (!expected) {
4534: TestUtil.dumpSQLExceptions(sqle, expected);
4535: }
4536: } finally {
4537: rs2.close();
4538: s2.close();
4539: s.close();
4540: ps.close();
4541: }
4542:
4543: }
4544:
4545: static void printInterval(Clob clob, long pos, int length,
4546: int testNum, int iteration, int clobLength) {
4547: if (pos > clobLength + 1)
4548: System.out.println("CLOB getSubString " + pos + " > "
4549: + clobLength);
4550: try {
4551: /*
4552: System.out.println("printInterval(" + clob + "," + pos +"," +
4553: length +"," + testNum + "," + iteration + "," +
4554: clobLength + ")");
4555: */
4556: String ss = clob.getSubString(pos, length);
4557:
4558: System.out.println(iteration + "(" + testNum + ") (len "
4559: + length + ") " + ss);
4560: if (ss.length() > length)
4561: System.out.println("FAIL getSubString(" + pos + ","
4562: + length + ") returned a string of length "
4563: + ss.length());
4564:
4565: long l1 = clob.length();
4566: if (l1 != clobLength) {
4567: System.out
4568: .println("CHECK - test has mismatched lengths "
4569: + l1 + " != " + clobLength);
4570: }
4571: if (pos > clobLength + 1)
4572: System.out
4573: .println("CLOB FAIL - NO ERROR ON getSubString POS TOO LARGE "
4574: + pos + " > " + clobLength);
4575:
4576: } catch (SQLException e) {
4577: String state = e.getSQLState();
4578: boolean expected = false;
4579:
4580: if (pos < 1 || pos > clobLength + 1) {
4581: if (isOutOfBoundException(e))
4582: expected = true;
4583: } else {
4584: System.out.println("FAIL -- unexpected exception:"
4585: + e.toString());
4586: }
4587: TestUtil.dumpSQLExceptions(e, expected);
4588: } catch (StringIndexOutOfBoundsException obe) {
4589: // Known bug. JCC 5914.
4590: if ((pos > clobLength) && isDerbyNet) {
4591: System.out.println("EXPECTED Out of bounds exception");
4592: } else {
4593: System.out.println("FAIL -- unexpected exception:"
4594: + obe.toString());
4595: if (debug)
4596: obe.printStackTrace(System.out);
4597: }
4598: } catch (Exception e) {
4599: System.out.println("FAIL -- unexpected exception:"
4600: + e.toString());
4601: if (debug)
4602: e.printStackTrace(System.out);
4603: }
4604: }
4605:
4606: static void printInterval(Blob blob, long pos, int length,
4607: int testNum, int iteration, long blobLength) {
4608: if (pos > blobLength + 1)
4609: System.out.println("testing Blob.getBytes() with pos "
4610: + pos + " > " + blobLength);
4611: try {
4612: // generate a new string out of the blob for comparison,
4613: // ensure it's using fixed format.
4614: System.out
4615: .println(iteration
4616: + "("
4617: + testNum
4618: + ") "
4619: + new String(blob.getBytes(pos, length),
4620: "US-ASCII"));
4621:
4622: long l1 = blob.length();
4623: if (l1 != blobLength) {
4624: System.out
4625: .println("CHECK - test has mismatched lengths "
4626: + l1 + " != " + blobLength);
4627: }
4628: if (pos > blobLength + 1)
4629: System.out
4630: .println("FAIL testing Blob.getBytes() with pos "
4631: + pos + " > " + blobLength);
4632: } catch (SQLException e) {
4633: String state = e.getSQLState();
4634: boolean expected = false;
4635:
4636: if (pos < 1 || pos > blobLength + 1)
4637: expected = isOutOfBoundException(e);
4638:
4639: TestUtil.dumpSQLExceptions(e, expected);
4640: } catch (Exception e) {
4641: System.out
4642: .println("FAIL: Caught exception " + e.toString());
4643: }
4644: }
4645:
4646: static void printPosition(int rowNum, String searchStr,
4647: long position, Clob clob, long clobLength) {
4648:
4649: try {
4650:
4651: long result = clob.position(searchStr, position);
4652:
4653: System.out.println("Found "
4654: + searchStr
4655: + " in row "
4656: + rowNum
4657: + " starting from position "
4658: + position
4659: + " at position "
4660: + (result == -1 ? " NOTFOUND " : Long
4661: .toString(result)));
4662:
4663: long l1 = clob.length();
4664: if (l1 != clobLength) {
4665: System.out
4666: .println("CHECK - test has mismatched lengths "
4667: + l1 + " != " + clobLength);
4668: }
4669:
4670: } catch (SQLException e) {
4671: String state = e.getSQLState();
4672: boolean expected = false;
4673:
4674: if (position < 1 || position > clobLength)
4675: expected = isOutOfBoundException(e);
4676:
4677: if (searchStr == null)
4678: if ("XJ072".equals(state))
4679: expected = true;
4680:
4681: if ("".equals(searchStr))
4682: if ("XJ078".equals(state))
4683: expected = true;
4684:
4685: TestUtil.dumpSQLExceptions(e, expected);
4686: e.printStackTrace(System.out);
4687: }
4688: }
4689:
4690: static void printPosition(int rowNum, String searchStr,
4691: long position, Blob blob, int blobLength)
4692: throws UnsupportedEncodingException {
4693: try {
4694: long result = blob.position(searchStr.getBytes("US-ASCII"),
4695: position);
4696: if ((searchStr == "") && (result == 1))
4697: return;
4698: if (result != -1)
4699: System.out.println("Found " + searchStr + " in row "
4700: + rowNum + " starting from position "
4701: + position + " at position " + result);
4702:
4703: long l1 = blob.length();
4704: if (l1 != blobLength) {
4705: System.out
4706: .println("CHECK - test has mismatched lengths "
4707: + l1 + " != " + blobLength);
4708: }
4709: } catch (SQLException e) {
4710: String state = e.getSQLState();
4711: boolean expected = false;
4712:
4713: if (position < 1 || position > blobLength)
4714: expected = isOutOfBoundException(e);
4715:
4716: if (searchStr == null)
4717: if ("XJ072".equals(state))
4718: expected = true;
4719:
4720: if ("".equals(searchStr))
4721: if ("XJ078".equals(state))
4722: expected = true;
4723:
4724: TestUtil.dumpSQLExceptions(e, expected);
4725: }
4726: }
4727:
4728: /**
4729: * In network server we expect an exception.
4730: * In embedded we don't
4731: */
4732:
4733: static private void expectedExceptionForNSOnly(SQLException se) {
4734: TestUtil.dumpSQLExceptions(se, isDerbyNet);
4735: }
4736:
4737: static private boolean isOutOfBoundException(SQLException se) {
4738: String sqlState = se.getSQLState();
4739: String msg = se.getMessage();
4740: if ("XJ070".equals(sqlState)
4741: || "XJ071".equals(sqlState)
4742: || "XJ076".equals(sqlState)
4743: || (sqlState == null && ((msg
4744: .indexOf("Index Out Of Bound") != -1) || (msg
4745: .indexOf("Invalid position") != -1))))
4746: return true;
4747:
4748: return false;
4749: }
4750:
4751: static private boolean isNullSearchPattern(SQLException se) {
4752: String sqlState = se.getSQLState();
4753: if ("XJ072".equals(sqlState)
4754: || (sqlState == null && se.getMessage().indexOf(
4755: "Search pattern cannot be null") != -1))
4756: return true;
4757:
4758: return false;
4759: }
4760:
4761: /**
4762: * Run some simple checks comparing the Blob
4763: * to the file's length and checksum.
4764: * @throws SQLException
4765: * @throws IOException
4766: *
4767: */
4768: private static void checkBlobAgainstFile(int fileid, Blob blob)
4769: throws SQLException, IOException {
4770:
4771: if (blob.length() != fileLength[fileid])
4772: System.out.println("FAIL BLOB length mismatch: " + "BLOB "
4773: + blob.length() + " FILE " + fileLength[fileid]);
4774:
4775: long blobsum = getStreamCheckSum(blob.getBinaryStream());
4776: if (blobsum != fileCRC32[fileid])
4777: System.out.println("FAIL BLOB checksum mismatch: "
4778: + "BLOB " + blobsum + " FILE " + fileCRC32[fileid]);
4779: }
4780:
4781: /**
4782: * Get the CRC32 checksum of a stream, reading
4783: * its contents entirely and closing it.
4784: */
4785: private static long getStreamCheckSum(InputStream in)
4786: throws IOException {
4787: CRC32 sum = new CRC32();
4788:
4789: byte[] buf = new byte[32 * 1024];
4790:
4791: for (;;) {
4792: int read = in.read(buf);
4793: if (read == -1)
4794: break;
4795: sum.update(buf, 0, read);
4796: }
4797: in.close();
4798: return sum.getValue();
4799: }
4800:
4801: private static void showClobContents(String tag, ResultSet rs)
4802: throws SQLException, IOException {
4803: while (rs.next()) {
4804: InputStream is = rs.getAsciiStream(1);
4805: if (is == null) {
4806: System.out.println(tag + ": NULL");
4807: continue;
4808: }
4809: long clobcrc = getStreamCheckSum(is);
4810: int clobLength = rs.getInt(2);
4811: int b = rs.getInt(3);
4812:
4813: System.out.println(tag + ": length " + clobLength
4814: + " crc32 " + clobcrc + " " + b);
4815: }
4816: }
4817: }
|