Source Code Cross Referenced for JDBCDriverTest.java in  » Database-DBMS » db-derby-10.2 » org » apache » derbyTesting » functionTests » tests » junitTests » compatibility » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database DBMS » db derby 10.2 » org.apache.derbyTesting.functionTests.tests.junitTests.compatibility 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:
0003:           Derby - Class org.apache.derbyTesting.functionTests.tests.compatibility.JDBCDriverTest
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:         * <p>
0023:         * This JUnit test verifies the compatibility of Derby clients and
0024:         * servers across Derby version levels and supported VMs.
0025:         * </p>
0026:         *
0027:         * @author Rick
0028:         */package org.apache.derbyTesting.functionTests.tests.junitTests.compatibility;
0029:
0030:        import java.io.*;
0031:        import java.math.*;
0032:        import java.sql.*;
0033:        import java.util.*;
0034:
0035:        import junit.framework.*;
0036:
0037:        import org.apache.derbyTesting.functionTests.util.DerbyJUnitTest;
0038:
0039:        public class JDBCDriverTest extends CompatibilitySuite {
0040:            /////////////////////////////////////////////////////////////
0041:            //
0042:            //	CONSTANTS
0043:            //
0044:            /////////////////////////////////////////////////////////////
0045:
0046:            private static final String ALL_TYPES_TABLE = "allTypesTable";
0047:            private static final String KEY_COLUMN = "keyCol";
0048:
0049:            //
0050:            // Data values to be stuffed into columns of ALL_TYPES_TABLE.
0051:            //
0052:            private static final byte[] SAMPLE_BYTES = new byte[] { (byte) 1,
0053:                    (byte) 2, (byte) 3, (byte) 4, (byte) 5 };
0054:            private static final String SAMPLE_STRING = "hello";
0055:
0056:            //
0057:            // These funny constants are defined this way to make the salient
0058:            // facts of the COERCIONS table leap out at you.
0059:            //
0060:            private static final boolean Y = true;
0061:            private static final boolean _ = false;
0062:
0063:            //
0064:            // This table declares the datatypes supported by Derby and the earliest
0065:            // versions of the Derby and the db2jcc client which support these
0066:            // datatypes.
0067:            //
0068:            // If you add a type to this table, make sure you add a corresponding
0069:            // column to the following row table. Also add a corresponding row to the
0070:            // COERCIONS table.
0071:            //
0072:            private static final TypeDescriptor[] ALL_TYPES = {
0073:                    // 10.0 types
0074:
0075:                    new TypeDescriptor(Types.BIGINT, "bigint", IBM_2_4,
0076:                            DRB_10_0, VM_1_3),
0077:                    new TypeDescriptor(Types.BLOB, "blob", IBM_2_4, DRB_10_0,
0078:                            VM_1_3),
0079:                    new TypeDescriptor(Types.CHAR, "char(5)", IBM_2_4,
0080:                            DRB_10_0, VM_1_3),
0081:                    new TypeDescriptor(Types.BINARY, "char(5) for bit data",
0082:                            IBM_2_4, DRB_10_0, VM_1_3),
0083:                    new TypeDescriptor(Types.CLOB, "clob", IBM_2_4, DRB_10_0,
0084:                            VM_1_3),
0085:                    new TypeDescriptor(Types.DATE, "date", IBM_2_4, DRB_10_0,
0086:                            VM_1_3),
0087:                    new TypeDescriptor(Types.DECIMAL, "decimal", IBM_2_4,
0088:                            DRB_10_0, VM_1_3),
0089:                    new TypeDescriptor(Types.DOUBLE, "double", IBM_2_4,
0090:                            DRB_10_0, VM_1_3),
0091:                    new TypeDescriptor(Types.DOUBLE, "double precision",
0092:                            IBM_2_4, DRB_10_0, VM_1_3),
0093:                    new TypeDescriptor(Types.REAL, "float(23)", IBM_2_4,
0094:                            DRB_10_0, VM_1_3),
0095:                    new TypeDescriptor(Types.DOUBLE, "float", IBM_2_4,
0096:                            DRB_10_0, VM_1_3),
0097:                    new TypeDescriptor(Types.INTEGER, "integer", IBM_2_4,
0098:                            DRB_10_0, VM_1_3),
0099:                    new TypeDescriptor(Types.LONGVARCHAR, "long varchar",
0100:                            IBM_2_4, DRB_10_0, VM_1_3),
0101:                    new TypeDescriptor(Types.LONGVARBINARY,
0102:                            "long varchar for bit data", IBM_2_4, DRB_10_0,
0103:                            VM_1_3),
0104:                    new TypeDescriptor(Types.NUMERIC, "numeric", IBM_2_4,
0105:                            DRB_10_0, VM_1_3),
0106:                    new TypeDescriptor(Types.REAL, "real", IBM_2_4, DRB_10_0,
0107:                            VM_1_3),
0108:                    new TypeDescriptor(Types.SMALLINT, "smallint", IBM_2_4,
0109:                            DRB_10_0, VM_1_3),
0110:                    new TypeDescriptor(Types.TIME, "time", IBM_2_4, DRB_10_0,
0111:                            VM_1_3),
0112:                    new TypeDescriptor(Types.TIMESTAMP, "timestamp", IBM_2_4,
0113:                            DRB_10_0, VM_1_3),
0114:                    new TypeDescriptor(Types.VARCHAR, "varchar(5)", IBM_2_4,
0115:                            DRB_10_0, VM_1_3),
0116:                    new TypeDescriptor(Types.VARBINARY,
0117:                            "varchar(5) for bit data", IBM_2_4, DRB_10_0,
0118:                            VM_1_3), };
0119:
0120:            //
0121:            // This table needs to have the same number of entries as ALL_TYPES.
0122:            // The testSanity() test case enforces this at run time.
0123:            //
0124:            private static final Object[] ROW_1 = {
0125:                    // 10.0 columns
0126:
0127:                    new Long(1L), new MyBlob(SAMPLE_BYTES), SAMPLE_STRING,
0128:                    SAMPLE_BYTES, new MyClob(SAMPLE_STRING),
0129:                    new java.sql.Date(1L), new BigDecimal(1.0),
0130:                    new Double(1.0), new Double(1.0), new Float((float) 1.0),
0131:                    new Double(1.0), new Integer(1), SAMPLE_STRING,
0132:                    SAMPLE_BYTES, new BigDecimal(1.0), new Float((float) 1.0),
0133:                    new Short((short) 1), new Time(1L), new Timestamp(1L),
0134:                    SAMPLE_STRING, SAMPLE_BYTES, };
0135:
0136:            //
0137:            // This table needs to have the same number of rows as ALL_TYPES.
0138:            // Each row in this table needs to have the same number of columns as
0139:            // rows in ALL_TYPES. The testSanity() test case enforces this at run time.
0140:            // Note how the funny synonyms for true and false
0141:            // make the salient facts of this table leap out at you.
0142:            //
0143:            // The ugly class name T_CN is an abbreviation which makes it possible to
0144:            // squeeze this table onto a readable screen.
0145:            //
0146:            // Please read the introductory comment top-to-bottom. 'Y' means a coercion
0147:            // is legal; '_' means it isn't.
0148:            //
0149:            private static final T_CN[] COERCIONS = {
0150:                    //												  B|B|C|B|C|D|D|D|R|I|L|L|N|R|S|T|T|V|V
0151:                    //												  I|L|H|I|L|A|E|O|E|N|O|O|U|E|M|I|I|A|A
0152:                    //												  G|O|A|N|O|T|C|U|A|T|N|N|M|A|A|M|M|R|R
0153:                    //												  I|B|R|A|B|E|I|B|L|E|G|G|E|L|L|E|E|C|B
0154:                    //												  N|-|-|R|-|-|M|L|-|G|V|V|R|-|L|-|S|H|I
0155:                    //												  T|-|-|Y|-|-|A|E|-|E|A|A|I|-|I|-|T|A|N
0156:                    //												  -|-|-|-|-|-|L|-|-|R|R|R|C|-|N|-|A|R|A
0157:                    //												  -|-|-|-|-|-|-|-|-|-|C|B|-|-|T|-|M|-|R
0158:                    //												  -|-|-|-|-|-|-|-|-|-|H|I|-|-|-|-|P|-|Y
0159:                    //												  -|-|-|-|-|-|-|-|-|-|A|N|-|-|-|-|-|-|-
0160:                    //												  -|-|-|-|-|-|-|-|-|-|R|A|-|-|-|-|-|-|-
0161:                    //												  -|-|-|-|-|-|-|-|-|-|-|R|-|-|-|-|-|-|-
0162:                    //												  -|-|-|-|-|-|-|-|-|-|-|Y|-|-|-|-|-|-|-
0163:                    new T_CN(Types.BIGINT, new boolean[] { Y, _, Y, _, _, _, _,
0164:                            Y, Y, Y, Y, _, Y, Y, Y, _, _, Y, _ }),
0165:                    new T_CN(Types.BLOB, new boolean[] { _, Y, _, _, _, _, _,
0166:                            _, _, _, _, _, _, _, _, _, _, _, _ }),
0167:                    new T_CN(Types.CHAR, new boolean[] { _, _, Y, _, _, _, _,
0168:                            _, _, _, Y, _, _, _, _, _, _, Y, _ }),
0169:                    new T_CN(Types.BINARY, new boolean[] { _, _, _, Y, _, _, _,
0170:                            _, _, _, _, Y, _, _, _, _, _, _, Y }),
0171:                    new T_CN(Types.CLOB, new boolean[] { _, _, _, _, Y, _, _,
0172:                            _, _, _, _, _, _, _, _, _, _, _, _ }),
0173:                    new T_CN(Types.DATE, new boolean[] { _, _, _, _, _, Y, _,
0174:                            _, _, _, _, _, _, _, _, _, _, _, _ }),
0175:                    new T_CN(Types.DECIMAL, new boolean[] { Y, _, _, _, _, _,
0176:                            Y, Y, Y, Y, Y, _, Y, Y, Y, _, _, Y, _ }),
0177:                    new T_CN(Types.DOUBLE, new boolean[] { Y, _, _, _, _, _, Y,
0178:                            Y, Y, Y, Y, _, Y, Y, Y, _, _, Y, _ }),
0179:                    new T_CN(Types.REAL, new boolean[] { Y, _, Y, _, _, _, Y,
0180:                            Y, Y, Y, Y, _, Y, Y, Y, _, _, Y, _ }),
0181:                    new T_CN(Types.INTEGER, new boolean[] { Y, _, Y, _, _, _,
0182:                            Y, Y, Y, Y, Y, _, Y, Y, Y, _, _, Y, _ }),
0183:                    new T_CN(Types.LONGVARCHAR, new boolean[] { _, _, Y, _, _,
0184:                            _, _, _, _, _, Y, _, _, _, _, _, _, Y, _ }),
0185:                    new T_CN(Types.LONGVARBINARY, new boolean[] { _, _, _, _,
0186:                            _, _, _, _, _, _, _, Y, _, _, _, _, _, _, Y }),
0187:                    new T_CN(Types.NUMERIC, new boolean[] { Y, _, Y, _, _, _,
0188:                            Y, Y, Y, Y, Y, _, Y, Y, Y, _, _, Y, _ }),
0189:                    new T_CN(Types.REAL, new boolean[] { Y, _, Y, _, _, _, Y,
0190:                            Y, Y, Y, Y, _, Y, Y, Y, _, _, Y, _ }),
0191:                    new T_CN(Types.SMALLINT, new boolean[] { Y, _, Y, _, _, _,
0192:                            Y, Y, Y, Y, Y, _, Y, Y, Y, _, _, Y, _ }),
0193:                    new T_CN(Types.TIME, new boolean[] { _, _, _, _, _, _, _,
0194:                            _, _, _, _, _, _, _, _, Y, _, _, _ }),
0195:                    new T_CN(Types.TIMESTAMP, new boolean[] { _, _, _, _, _, _,
0196:                            _, _, _, _, _, _, _, _, _, _, Y, _, _ }),
0197:                    new T_CN(Types.VARCHAR, new boolean[] { _, _, Y, _, _, _,
0198:                            _, _, _, _, Y, _, _, _, _, _, _, Y, _ }),
0199:                    new T_CN(Types.VARBINARY, new boolean[] { _, _, _, _, _, _,
0200:                            _, _, _, _, _, Y, _, _, _, _, _, _, Y }), };
0201:
0202:            /////////////////////////////////////////////////////////////
0203:            //
0204:            //	STATE
0205:            //
0206:            /////////////////////////////////////////////////////////////
0207:
0208:            // map derby type name to type descriptor
0209:            private static HashMap _types = new HashMap(); // maps Derby type names to TypeDescriptors
0210:
0211:            // map jdbc type to index into COERCIONS
0212:            private static HashMap _coercionIndex = new HashMap(); // maps jdbc types to legal coercions
0213:
0214:            /////////////////////////////////////////////////////////////
0215:            //
0216:            //	CONSTRUCTOR
0217:            //
0218:            /////////////////////////////////////////////////////////////
0219:
0220:            public JDBCDriverTest() {
0221:            }
0222:
0223:            /////////////////////////////////////////////////////////////
0224:            //
0225:            //	TEST ENTRY POINTS
0226:            //
0227:            /////////////////////////////////////////////////////////////
0228:
0229:            /**
0230:             * <p>
0231:             * Sanity check the integrity of this test suite.
0232:             * </p>
0233:             */
0234:            public void testSanity() {
0235:                assertEquals("ALL_TYPES.length == ROW_1.length",
0236:                        ALL_TYPES.length, ROW_1.length);
0237:
0238:                // make sure there we completely describe the coercibility of every jdbc type
0239:                int coercionCount = COERCIONS.length;
0240:                for (int i = 0; i < coercionCount; i++) {
0241:                    assertEquals("Coercion " + i, coercionCount, COERCIONS[i]
0242:                            .getCoercions().length);
0243:                }
0244:            }
0245:
0246:            /**
0247:             * <p>
0248:             * Main test of jdbc drivers.
0249:             * </p>
0250:             */
0251:            public void testJDBCDriver() throws Exception {
0252:                Connection conn = getConnection();
0253:
0254:                dropSchema(conn);
0255:                createSchema(conn);
0256:
0257:                datatypesTest(conn);
0258:
0259:                close(conn);
0260:            }
0261:
0262:            /////////////////////////////////////////////////////////////
0263:            //
0264:            //	TEST DATATYPES
0265:            //
0266:            /////////////////////////////////////////////////////////////
0267:
0268:            //
0269:            // Test that we can declare, insert, and select all datatypes that
0270:            // are legal on the server. Test the metadata for these datatypes.
0271:            //
0272:            private void datatypesTest(Connection conn) throws Exception {
0273:                TypeDescriptor[] types = ALL_TYPES;
0274:                String tableName = ALL_TYPES_TABLE;
0275:                Object[][] rows = new Object[][] { makeNullRow(types.length),
0276:                        ROW_1 };
0277:
0278:                checkDBMetadata(conn, tableName);
0279:                stuffTable(conn, tableName, types, rows);
0280:                readTable(conn, tableName, types, rows, null);
0281:            }
0282:
0283:            //
0284:            // Verify that we get the correct DatabaseMetaData for a table.
0285:            //
0286:            private void checkDBMetadata(Connection conn, String tableName)
0287:                    throws Exception {
0288:                String normalizedSchema = DEFAULT_USER_NAME.toUpperCase();
0289:                String normalizedTable = tableName.toUpperCase();
0290:                DatabaseMetaData dbmd = conn.getMetaData();
0291:
0292:                ResultSet rs = dbmd.getColumns(null, normalizedSchema,
0293:                        normalizedTable, "%");
0294:
0295:                println("Pawing through database metadata for "
0296:                        + normalizedSchema + '.' + normalizedTable);
0297:
0298:                while (rs.next()) {
0299:                    String columnName = rs.getString("COLUMN_NAME");
0300:                    int actualJdbcType = rs.getInt("DATA_TYPE");
0301:                    TypeDescriptor typeDesc = getType(columnName);
0302:
0303:                    if (columnName.equals(KEY_COLUMN)) {
0304:                        continue;
0305:                    }
0306:
0307:                    StringBuffer buffer = new StringBuffer();
0308:
0309:                    buffer.append("[ ");
0310:                    buffer.append(rs.getString("COLUMN_NAME"));
0311:                    buffer.append(",\t");
0312:                    buffer.append("type( " + rs.getInt("DATA_TYPE") + " ),\t");
0313:                    buffer.append(rs.getString("TYPE_NAME"));
0314:                    buffer.append(" ]");
0315:
0316:                    println(buffer.toString());
0317:
0318:                    assertEquals(columnName, ddmdTypeKludge(typeDesc
0319:                            .getJdbcType()), actualJdbcType);
0320:                }
0321:
0322:                close(rs);
0323:            }
0324:
0325:            //
0326:            // Verify that we get the correct DatabaseMetaData for a procedure
0327:            //
0328:            private void checkProcMetadata(Connection conn, String procName,
0329:                    TypeDescriptor[] signature) throws Exception {
0330:                String normalizedSchema = DEFAULT_USER_NAME.toUpperCase();
0331:                String normalizedProc = procName.toUpperCase();
0332:                DatabaseMetaData dbmd = conn.getMetaData();
0333:
0334:                ResultSet rs = dbmd.getProcedureColumns(null, normalizedSchema,
0335:                        normalizedProc, "%");
0336:
0337:                println("Pawing through database metadata for "
0338:                        + normalizedSchema + '.' + normalizedProc);
0339:
0340:                while (rs.next()) {
0341:                    String columnName = rs.getString("COLUMN_NAME");
0342:                    int actualJdbcType = rs.getInt("DATA_TYPE");
0343:                    TypeDescriptor typeDesc = getType(signature, columnName);
0344:
0345:                    if (columnName.equals(KEY_COLUMN)) {
0346:                        continue;
0347:                    }
0348:
0349:                    StringBuffer buffer = new StringBuffer();
0350:
0351:                    buffer.append("[ ");
0352:                    buffer.append(rs.getString("COLUMN_NAME"));
0353:                    buffer.append(",\t");
0354:                    buffer.append("type( " + rs.getInt("DATA_TYPE") + " ),\t");
0355:                    buffer.append(rs.getString("TYPE_NAME"));
0356:                    buffer.append(" ]");
0357:
0358:                    println(buffer.toString());
0359:
0360:                    assertEquals(columnName, ddmdTypeKludge(typeDesc
0361:                            .getJdbcType()), actualJdbcType);
0362:                }
0363:
0364:                close(rs);
0365:            }
0366:
0367:            //
0368:            // Stuff a table with rows
0369:            //
0370:            private void stuffTable(Connection conn, String tableName,
0371:                    TypeDescriptor[] types, Object[][] rows) throws Exception {
0372:                PreparedStatement ps = makeInsert(conn, tableName, types);
0373:                int rowCount = rows.length;
0374:
0375:                for (int i = 0; i < rowCount; i++) {
0376:                    setRow(ps, i + 1, types, rows[i]);
0377:                }
0378:
0379:                close(ps);
0380:            }
0381:
0382:            private PreparedStatement makeInsert(Connection conn,
0383:                    String tableName, TypeDescriptor[] types) throws Exception {
0384:                StringBuffer masterBuffer = new StringBuffer();
0385:                StringBuffer columnBuffer = new StringBuffer();
0386:                StringBuffer valuesBuffer = new StringBuffer();
0387:                int columnNumber = 0;
0388:                int valuesNumber = 0;
0389:                int typeCount = types.length;
0390:
0391:                beginColumnList(columnBuffer);
0392:                beginColumnList(valuesBuffer);
0393:
0394:                addColumn(columnBuffer, columnNumber++, doubleQuote(KEY_COLUMN));
0395:                addColumn(valuesBuffer, valuesNumber++, "?");
0396:
0397:                for (int i = 0; i < typeCount; i++) {
0398:                    TypeDescriptor type = types[i];
0399:
0400:                    if (getServerVersion().atLeast(type.getDerbyVersion())) {
0401:                        String typeName = type.getDerbyTypeName();
0402:                        String columnDesc = doubleQuote(typeName);
0403:
0404:                        addColumn(columnBuffer, columnNumber++, columnDesc);
0405:                        addColumn(valuesBuffer, valuesNumber++, "?");
0406:                    }
0407:                }
0408:
0409:                endColumnList(columnBuffer);
0410:                endColumnList(valuesBuffer);
0411:
0412:                masterBuffer.append("insert into " + tableName + "\n");
0413:                masterBuffer.append(columnBuffer.toString());
0414:                masterBuffer.append("values\n");
0415:                masterBuffer.append(valuesBuffer.toString());
0416:
0417:                PreparedStatement ps = prepare(conn, masterBuffer.toString());
0418:
0419:                return ps;
0420:            }
0421:
0422:            //
0423:            // Verify that we can select all legal datatypes in a table.
0424:            //
0425:            private void readTable(Connection conn, String tableName,
0426:                    TypeDescriptor[] types, Object[][] rows, List casts)
0427:                    throws Exception {
0428:                PreparedStatement ps = readTableQuery(conn, tableName, types);
0429:                ResultSet rs = ps.executeQuery();
0430:
0431:                checkRSMD(rs);
0432:                checkRows(rs, types, rows, casts);
0433:
0434:                close(rs);
0435:                close(ps);
0436:            }
0437:
0438:            //
0439:            // Make the select query
0440:            //
0441:            private PreparedStatement readTableQuery(Connection conn,
0442:                    String tableName, TypeDescriptor[] types) throws Exception {
0443:                StringBuffer buffer = new StringBuffer();
0444:                int columnNumber = 0;
0445:                int typeCount = types.length;
0446:
0447:                buffer.append("select \n");
0448:
0449:                addColumn(buffer, columnNumber++, doubleQuote(KEY_COLUMN));
0450:
0451:                for (int i = 0; i < typeCount; i++) {
0452:                    TypeDescriptor type = types[i];
0453:
0454:                    if (getServerVersion().atLeast(type.getDerbyVersion())) {
0455:                        String typeName = type.getDerbyTypeName();
0456:                        String columnDesc = doubleQuote(typeName);
0457:
0458:                        addColumn(buffer, columnNumber++, columnDesc);
0459:                    }
0460:                }
0461:
0462:                buffer.append("\nfrom " + tableName + "\n");
0463:                buffer.append("order by " + doubleQuote(KEY_COLUMN));
0464:
0465:                PreparedStatement ps = prepare(conn, buffer.toString());
0466:
0467:                return ps;
0468:            }
0469:
0470:            //
0471:            // Verify that we get the correct ResultSetMetaData for all datatypes
0472:            // which are legal on the server.
0473:            //
0474:            private void checkRSMD(ResultSet rs) throws Exception {
0475:                ResultSetMetaData rsmd = rs.getMetaData();
0476:                int columnCount = rsmd.getColumnCount();
0477:                int firstTastyColumn = 0;
0478:
0479:                println("ResultSetMetaData:\n");
0480:
0481:                firstTastyColumn++; // skip uninteresting key column
0482:
0483:                for (int i = firstTastyColumn; i < columnCount; i++) {
0484:                    StringBuffer buffer = new StringBuffer();
0485:                    int columnID = i + 1;
0486:                    String columnName = rsmd.getColumnName(columnID);
0487:                    TypeDescriptor typeDesc = getType(columnName);
0488:                    int expectedType = rsmdTypeKludge(typeDesc.getJdbcType());
0489:                    int actualType = rsmd.getColumnType(columnID);
0490:
0491:                    buffer.append("[ ");
0492:                    buffer.append(columnName);
0493:                    buffer.append(", type( ");
0494:                    buffer.append(actualType);
0495:                    buffer.append(" ), ");
0496:                    buffer.append(rsmd.getColumnTypeName(columnID));
0497:                    buffer.append(" ]\n");
0498:
0499:                    println(buffer.toString());
0500:
0501:                    assertEquals(columnName, expectedType, actualType);
0502:                }
0503:
0504:            }
0505:
0506:            //
0507:            // Verify that we select the values we
0508:            // originally inserted into a table.
0509:            //
0510:            private void checkRows(ResultSet rs, TypeDescriptor[] types,
0511:                    Object[][] rows, List casts) throws Exception {
0512:                int rowCount = rows.length;
0513:
0514:                for (int i = 0; i < rowCount; i++) {
0515:                    rs.next();
0516:                    checkRow(rs, types, rows[i], casts);
0517:                }
0518:            }
0519:
0520:            //
0521:            // Verify that we select the values we
0522:            // originally inserted into a row.
0523:            //
0524:            private void checkRow(ResultSet rs, TypeDescriptor[] types,
0525:                    Object[] row, List casts) throws Exception {
0526:                int typeCount = types.length;
0527:
0528:                for (int i = 0; i < typeCount; i++) {
0529:                    TypeDescriptor type = types[i];
0530:
0531:                    if (getServerVersion().atLeast(type.getDerbyVersion())) {
0532:                        String columnName = type.getDerbyTypeName();
0533:                        Object expectedValue = row[i];
0534:                        Object actualValue = getColumn(rs, columnName, type);
0535:
0536:                        println("Comparing column " + columnName + ": "
0537:                                + expectedValue + " to " + actualValue);
0538:                        compareObjects(columnName, expectedValue, actualValue);
0539:
0540:                        checkCoercions(rs, columnName, type, casts);
0541:                    }
0542:                }
0543:            }
0544:
0545:            //
0546:            // Verify all legal jdbc coercions of a data value.
0547:            //
0548:            private void checkCoercions(ResultSet rs, String columnName,
0549:                    TypeDescriptor type, List casts) throws Exception {
0550:                T_CN coercionDesc = COERCIONS[getCoercionIndex(type
0551:                        .getJdbcType())];
0552:                boolean[] coercions = coercionDesc.getCoercions();
0553:                int count = coercions.length;
0554:                int legalCoercions = 0;
0555:
0556:                println("Checking coercions for " + columnName);
0557:
0558:                for (int i = 0; i < count; i++) {
0559:                    if (coercions[i]) {
0560:                        legalCoercions++;
0561:
0562:                        int jdbcType = COERCIONS[i].getJdbcType();
0563:                        Object retval = getColumn(rs, columnName, jdbcType);
0564:
0565:                        if (casts != null) {
0566:                            casts.add(retval);
0567:                        }
0568:
0569:                        println("\t" + jdbcType + ":\t" + retval);
0570:                    }
0571:
0572:                }
0573:                // finally, try getObject()
0574:
0575:                Object objval = rs.getObject(columnName);
0576:                if (objval == null) {
0577:                    println("\tgetObject() = null");
0578:                } else {
0579:                    StringBuffer buffer = new StringBuffer();
0580:                    buffer.append("\tgetObject() = ");
0581:                    buffer.append(objval.getClass().getName());
0582:                    buffer.append("( ");
0583:                    buffer.append(objval);
0584:                    buffer.append(" )");
0585:                    println(buffer.toString());
0586:                }
0587:            }
0588:
0589:            //
0590:            // This kludge compensates for the fact that the DRDA clients report
0591:            // that NUMERIC columns are DECIMAL. See bug 584.
0592:            //
0593:            // In addition, booleans are handled oddly by down-rev clients.
0594:            //
0595:            private int rsmdTypeKludge(int originalJDbcType) {
0596:                // The embedded client does the right thing.
0597:                if (usingEmbeddedClient()
0598:                        && getServerVMVersion().atLeast(VM_1_4)) {
0599:                    return originalJDbcType;
0600:                }
0601:
0602:                switch (originalJDbcType) {
0603:                //This kludge compensates for the fact that the DRDA clients report
0604:                // that NUMERIC columns are DECIMAL. See bug 584.
0605:                case Types.NUMERIC:
0606:                    if (usingEmbeddedClient()) {
0607:                        return originalJDbcType;
0608:                    } else {
0609:                        return Types.DECIMAL;
0610:                    }
0611:
0612:                default:
0613:                    return originalJDbcType;
0614:                }
0615:            }
0616:
0617:            //
0618:            // This kludge compensates for the fact that servers return
0619:            // different jdbc types depending on their vm.
0620:            //
0621:            private int ddmdTypeKludge(int originalJDbcType) {
0622:                switch (originalJDbcType) {
0623:                case JDBC_BOOLEAN:
0624:                    if (getServerVMVersion().atLeast(VM_1_4)) {
0625:                        return originalJDbcType;
0626:                    } else {
0627:                        return Types.BIT;
0628:                    }
0629:
0630:                default:
0631:                    return originalJDbcType;
0632:                }
0633:            }
0634:
0635:            //
0636:            // Insert a row into the ALL_TYPES table. The row contains all datatypes
0637:            // that are legal on the server.
0638:            //
0639:            private void setRow(PreparedStatement ps, int keyValue,
0640:                    TypeDescriptor[] types, Object[] row) throws Exception {
0641:                int param = 1;
0642:                int typeCount = types.length;
0643:
0644:                ps.setInt(param++, keyValue);
0645:
0646:                for (int i = 0; i < typeCount; i++) {
0647:                    TypeDescriptor type = types[i];
0648:                    Object value = row[i];
0649:
0650:                    if (getServerVersion().atLeast(type.getDerbyVersion())) {
0651:                        setParameter(ps, param++, type, value);
0652:                    }
0653:                }
0654:
0655:                ps.execute();
0656:            }
0657:
0658:            //
0659:            // Add a row of null columns.
0660:            //
0661:            private Object[][] makeRows(Object[][] rows) {
0662:                int count = rows.length;
0663:                int columns = rows[0].length;
0664:                Object[][] result = new Object[count + 1][];
0665:                int idx = 0;
0666:
0667:                result[idx++] = makeNullRow(columns);
0668:
0669:                for (int i = 0; i < count; i++) {
0670:                    result[idx++] = rows[i];
0671:                }
0672:
0673:                return result;
0674:            }
0675:
0676:            private Object[] makeNullRow(int rowLength) {
0677:                return new Object[rowLength];
0678:            }
0679:
0680:            //
0681:            // Index the TypeDescriptors by Derby type name.
0682:            //
0683:            private void buildTypeMap() {
0684:                int typeCount = ALL_TYPES.length;
0685:
0686:                for (int i = 0; i < typeCount; i++) {
0687:                    putType(ALL_TYPES[i]);
0688:                }
0689:            }
0690:
0691:            private void putType(TypeDescriptor type) {
0692:                _types.put(type.getDerbyTypeName(), type);
0693:            }
0694:
0695:            //
0696:            // Lookup TypeDescriptors by Derby type name.
0697:            //
0698:            private TypeDescriptor getType(String typeName) {
0699:                if (_types.size() == 0) {
0700:                    buildTypeMap();
0701:                }
0702:
0703:                return (TypeDescriptor) _types.get(typeName);
0704:            }
0705:
0706:            //
0707:            // Lookup TypeDescriptors by jdbc type
0708:            //
0709:            private TypeDescriptor getType(int jdbcType) {
0710:                int count = ALL_TYPES.length;
0711:
0712:                for (int i = 0; i < count; i++) {
0713:                    TypeDescriptor type = ALL_TYPES[i];
0714:
0715:                    if (type.getJdbcType() == jdbcType) {
0716:                        return type;
0717:                    }
0718:                }
0719:
0720:                return null;
0721:            }
0722:
0723:            //
0724:            // Lookup TypeDescriptors by column name in an array of types
0725:            //
0726:            private TypeDescriptor getType(TypeDescriptor[] types,
0727:                    String typeName) {
0728:                int count = types.length;
0729:
0730:                for (int i = 0; i < count; i++) {
0731:                    TypeDescriptor type = types[i];
0732:
0733:                    if (type.getDerbyTypeName().equals(typeName)) {
0734:                        return type;
0735:                    }
0736:                }
0737:
0738:                return null;
0739:            }
0740:
0741:            //
0742:            // Index legal coercions by jdbc type.
0743:            //
0744:            private void buildCoercionMap() {
0745:                int count = COERCIONS.length;
0746:
0747:                for (int i = 0; i < count; i++) {
0748:                    putCoercionIndex(i);
0749:                }
0750:            }
0751:
0752:            private void putCoercionIndex(int index) {
0753:                _coercionIndex.put(new Integer(COERCIONS[index].getJdbcType()),
0754:                        new Integer(index));
0755:            }
0756:
0757:            //
0758:            // Lookup the legal coercions for a given jdbc type.
0759:            //
0760:            private int getCoercionIndex(int jdbcType) {
0761:                if (_coercionIndex.size() == 0) {
0762:                    buildCoercionMap();
0763:                }
0764:
0765:                return ((Integer) _coercionIndex.get(new Integer(jdbcType)))
0766:                        .intValue();
0767:            }
0768:
0769:            /////////////////////////////////////////////////////////////
0770:            //
0771:            //	MINIONS
0772:            //
0773:            /////////////////////////////////////////////////////////////
0774:
0775:            ///////////////////
0776:            //
0777:            //	TYPE MANAGEMENT
0778:            //
0779:            ///////////////////
0780:
0781:            //////////////////
0782:            //
0783:            //	SCHEMA MINIONS
0784:            //
0785:            //////////////////
0786:
0787:            //
0788:            // Create all the tables needed by our test cases.
0789:            //
0790:            private void createSchema(Connection conn) throws Exception {
0791:                createTable(conn, ALL_TYPES_TABLE, ALL_TYPES);
0792:            }
0793:
0794:            //
0795:            // Create a table modelling an array of datatypes.
0796:            //
0797:            private void createTable(Connection conn, String tableName,
0798:                    TypeDescriptor[] types) throws Exception {
0799:                StringBuffer buffer = new StringBuffer();
0800:                int columnNumber = 0;
0801:                int typeCount = types.length;
0802:
0803:                buffer.append("create table " + tableName + "\n");
0804:                beginColumnList(buffer);
0805:
0806:                addColumn(buffer, columnNumber++, doubleQuote(KEY_COLUMN)
0807:                        + "\tint");
0808:
0809:                for (int i = 0; i < typeCount; i++) {
0810:                    TypeDescriptor type = types[i];
0811:
0812:                    if (getServerVersion().atLeast(type.getDerbyVersion())) {
0813:                        String typeName = type.getDerbyTypeName();
0814:                        String columnDesc = doubleQuote(typeName) + '\t'
0815:                                + typeName;
0816:
0817:                        addColumn(buffer, columnNumber++, columnDesc);
0818:                    }
0819:                }
0820:
0821:                endColumnList(buffer);
0822:
0823:                PreparedStatement ps = prepare(conn, buffer.toString());
0824:
0825:                ps.execute();
0826:
0827:                close(ps);
0828:            }
0829:
0830:            //
0831:            // Helper methods for declaring a table.
0832:            //
0833:            private void beginColumnList(StringBuffer buffer) {
0834:                buffer.append("(\n");
0835:            }
0836:
0837:            private void endColumnList(StringBuffer buffer) {
0838:                buffer.append("\n)\n");
0839:            }
0840:
0841:            private void addColumn(StringBuffer buffer, int columnNumber,
0842:                    String text) {
0843:                if (columnNumber > 0) {
0844:                    buffer.append(",");
0845:                }
0846:
0847:                buffer.append("\n\t");
0848:                buffer.append(text);
0849:            }
0850:
0851:            //
0852:            // Drop the tables used by our test cases.
0853:            //
0854:            private void dropSchema(Connection conn) {
0855:                dropTable(conn, ALL_TYPES_TABLE);
0856:            }
0857:
0858:            //
0859:            // Logic for stuffing a data value into a column, given its type.
0860:            //
0861:            private void setParameter(PreparedStatement ps, int param,
0862:                    TypeDescriptor type, Object value) throws Exception {
0863:                int jdbcType = type.getJdbcType();
0864:
0865:                if (value != null) {
0866:                    setParameter(ps, param, jdbcType, value);
0867:                    return;
0868:                } else if (clientSupports(type)) {
0869:                    ps.setNull(param, jdbcType);
0870:
0871:                    return;
0872:                }
0873:
0874:                // client does not support nulls of this type.
0875:
0876:                fail("Unsupported Derby type: " + type.getDerbyTypeName());
0877:            }
0878:
0879:            //
0880:            // Logic for verifying that a value was stuffed correctly.
0881:            //
0882:            private void checkParameter(ResultSet rs, int param, Object value)
0883:                    throws Exception {
0884:                Object actualValue;
0885:
0886:                if (value == null) {
0887:                    return;
0888:                }
0889:
0890:                println("Checking " + value.getClass().getName());
0891:
0892:                if (value instanceof  Boolean) {
0893:                    actualValue = new Boolean(rs.getBoolean(param));
0894:                } else if (value instanceof  Byte) {
0895:                    actualValue = new Byte(rs.getByte(param));
0896:                } else if (value instanceof  Short) {
0897:                    actualValue = new Short(rs.getShort(param));
0898:                } else if (value instanceof  Integer) {
0899:                    actualValue = new Integer(rs.getInt(param));
0900:                } else if (value instanceof  Long) {
0901:                    actualValue = new Long(rs.getLong(param));
0902:                } else if (value instanceof  Float) {
0903:                    actualValue = new Float(rs.getFloat(param));
0904:                } else if (value instanceof  Double) {
0905:                    actualValue = new Double(rs.getDouble(param));
0906:                } else if (value instanceof  String) {
0907:                    actualValue = rs.getString(param);
0908:                } else if (value instanceof  BigDecimal) {
0909:                    actualValue = rs.getBigDecimal(param);
0910:                } else {
0911:                    actualValue = rs.getObject(param);
0912:                }
0913:
0914:                assertTrue(value.equals(actualValue));
0915:            }
0916:
0917:            // return true if the client supports this datatype
0918:            private boolean clientSupports(TypeDescriptor type) {
0919:                Version firstSupportedVersion;
0920:
0921:                if (usingDB2Client()) {
0922:                    firstSupportedVersion = type.getDb2jccVersion();
0923:                } else {
0924:                    firstSupportedVersion = type.getDerbyVersion();
0925:                }
0926:
0927:                if (firstSupportedVersion == null) {
0928:                    return false;
0929:                } else {
0930:                    return getDriverVersion().atLeast(firstSupportedVersion);
0931:                }
0932:            }
0933:
0934:            //
0935:            // Get a data value from a column, given its type.
0936:            //
0937:            private Object getColumn(ResultSet rs, String columnName,
0938:                    TypeDescriptor type) throws Exception {
0939:                int jdbcType = type.getJdbcType();
0940:
0941:                return getColumn(rs, columnName, jdbcType);
0942:            }
0943:
0944:            //
0945:            // Get a data value from a procedure's output arg, given its type.
0946:            //
0947:            private Object getOutArg(CallableStatement cs, int arg,
0948:                    TypeDescriptor type) throws Exception {
0949:                int jdbcType = type.getJdbcType();
0950:
0951:                return getOutArg(cs, arg, jdbcType);
0952:            }
0953:
0954:            //
0955:            // SQL code generation minions 
0956:            //
0957:            private String doubleQuote(String text) {
0958:                return '"' + text + '"';
0959:            }
0960:
0961:            /////////////////////////////////////////////////////////////
0962:            //
0963:            //	INNER CLASSES
0964:            //
0965:            /////////////////////////////////////////////////////////////
0966:
0967:            /**
0968:             * <p>
0969:             * This helper class describes a legal datatype and the version of Derby
0970:             * and db2jcc where the datatype first appears.
0971:             * </p>
0972:             */
0973:            public static final class TypeDescriptor {
0974:                private int _jdbcType;
0975:                private String _derbyTypeName;
0976:                private Version _db2jccVersion; // first db2jcc version which supports this type
0977:                private Version _derbyVersion; // first derby version which supports this type
0978:                private Version _vmVersion; // first vm (jdbc) version which supports this type
0979:
0980:                public TypeDescriptor(int jdbcType, String derbyTypeName,
0981:                        Version db2jccVersion, Version derbyVersion,
0982:                        Version vmVersion) {
0983:                    _jdbcType = jdbcType;
0984:                    _derbyTypeName = derbyTypeName;
0985:                    _db2jccVersion = db2jccVersion;
0986:                    _derbyVersion = derbyVersion;
0987:                    _vmVersion = vmVersion;
0988:                }
0989:
0990:                public int getJdbcType() {
0991:                    return _jdbcType;
0992:                }
0993:
0994:                public String getDerbyTypeName() {
0995:                    return _derbyTypeName;
0996:                }
0997:
0998:                public Version getDb2jccVersion() {
0999:                    return _db2jccVersion;
1000:                }
1001:
1002:                public Version getDerbyVersion() {
1003:                    return _derbyVersion;
1004:                }
1005:
1006:                public Version getVMVersion() {
1007:                    return _vmVersion;
1008:                }
1009:            }
1010:
1011:            /**
1012:             * <p>
1013:             * This helper class captures TypeCoercion logic. I have abbreviated it to
1014:             * this ugly class name so that the COERCIONS table will fit on a readable screen.
1015:             * </p>
1016:             */
1017:            public static final class T_CN {
1018:                private int _jdbcType;
1019:                private boolean[] _coercions;
1020:
1021:                public T_CN(int jdbcType, boolean[] coercions) {
1022:                    _jdbcType = jdbcType;
1023:                    _coercions = coercions;
1024:                }
1025:
1026:                public int getJdbcType() {
1027:                    return _jdbcType;
1028:                }
1029:
1030:                public boolean[] getCoercions() {
1031:                    return _coercions;
1032:                }
1033:            }
1034:
1035:            /**
1036:             * <p>
1037:             * A crude Blob implementation for datatype testing.
1038:             * </p>
1039:             */
1040:            public static final class MyBlob implements  Blob {
1041:                private byte[] _bytes;
1042:
1043:                public MyBlob(byte[] bytes) {
1044:                    _bytes = bytes;
1045:                }
1046:
1047:                public InputStream getBinaryStream() {
1048:                    return new ByteArrayInputStream(_bytes);
1049:                }
1050:
1051:                public byte[] getBytes(long position, int length) {
1052:                    return _bytes;
1053:                }
1054:
1055:                public long length() {
1056:                    return (long) _bytes.length;
1057:                }
1058:
1059:                public long position(Blob pattern, long start) {
1060:                    return 0L;
1061:                }
1062:
1063:                public long position(byte[] pattern, long start) {
1064:                    return 0L;
1065:                }
1066:
1067:                public boolean equals(Object other) {
1068:                    if (other == null) {
1069:                        return false;
1070:                    }
1071:                    if (!(other instanceof  Blob)) {
1072:                        return false;
1073:                    }
1074:
1075:                    Blob that = (Blob) other;
1076:
1077:                    try {
1078:                        if (this .length() != that.length()) {
1079:                            return false;
1080:                        }
1081:
1082:                        InputStream this Stream = this .getBinaryStream();
1083:                        InputStream thatStream = that.getBinaryStream();
1084:
1085:                        while (true) {
1086:                            int nextByte = this Stream.read();
1087:
1088:                            if (nextByte < 0) {
1089:                                break;
1090:                            }
1091:                            if (nextByte != thatStream.read()) {
1092:                                return false;
1093:                            }
1094:                        }
1095:                    } catch (Exception e) {
1096:                        System.err.println(e.getMessage());
1097:                        e.printStackTrace();
1098:                        return false;
1099:                    }
1100:
1101:                    return true;
1102:                }
1103:
1104:            }
1105:
1106:            /**
1107:             * <p>
1108:             * A crude Clob implementation for datatype testing.
1109:             * </p>
1110:             */
1111:            public static final class MyClob implements  Clob {
1112:                private String _contents;
1113:
1114:                public MyClob(String contents) {
1115:                    _contents = contents;
1116:                }
1117:
1118:                public InputStream getAsciiStream() {
1119:                    try {
1120:                        return new ByteArrayInputStream(_contents
1121:                                .getBytes("UTF-8"));
1122:                    } catch (Exception e) {
1123:                        return null;
1124:                    }
1125:                }
1126:
1127:                public Reader getCharacterStream() {
1128:                    return new CharArrayReader(_contents.toCharArray());
1129:                }
1130:
1131:                public String getSubString(long position, int length) {
1132:                    return _contents.substring((int) position, length);
1133:                }
1134:
1135:                public long length() {
1136:                    return (long) _contents.length();
1137:                }
1138:
1139:                public long position(Clob searchstr, long start) {
1140:                    return 0L;
1141:                }
1142:
1143:                public long position(String searchstr, long start) {
1144:                    return 0L;
1145:                }
1146:
1147:                public boolean equals(Object other) {
1148:                    if (other == null) {
1149:                        return false;
1150:                    }
1151:                    if (!(other instanceof  Clob)) {
1152:                        return false;
1153:                    }
1154:
1155:                    Clob that = (Clob) other;
1156:
1157:                    try {
1158:                        if (this .length() != that.length()) {
1159:                            return false;
1160:                        }
1161:
1162:                        InputStream this Stream = this .getAsciiStream();
1163:                        InputStream thatStream = that.getAsciiStream();
1164:
1165:                        while (true) {
1166:                            int nextByte = this Stream.read();
1167:
1168:                            if (nextByte < 0) {
1169:                                break;
1170:                            }
1171:                            if (nextByte != thatStream.read()) {
1172:                                return false;
1173:                            }
1174:                        }
1175:                    } catch (Exception e) {
1176:                        System.err.println(e.getMessage());
1177:                        e.printStackTrace();
1178:                        return false;
1179:                    }
1180:
1181:                    return true;
1182:                }
1183:
1184:            }
1185:
1186:        }
ww___w___.j__a__v__a2s___.___c__o__m_ | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.