1 21 29 30 package org.apache.derbyTesting.functionTests.tests.junitTests.compatibility; 31 32 import java.io.*; 33 import java.math.*; 34 import java.sql.*; 35 import java.util.*; 36 37 import junit.framework.*; 38 39 import org.apache.derbyTesting.functionTests.util.DerbyJUnitTest; 40 41 public class JDBCDriverTest extends CompatibilitySuite 42 { 43 49 private static final String ALL_TYPES_TABLE = "allTypesTable"; 50 private static final String KEY_COLUMN = "keyCol"; 51 52 private static final byte[] SAMPLE_BYTES = 56 new byte[] { (byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5 }; 57 private static final String SAMPLE_STRING = "hello"; 58 59 private static final boolean Y = true; 64 private static final boolean _ = false; 65 66 private static final TypeDescriptor[] ALL_TYPES = 76 { 77 79 new TypeDescriptor 80 ( Types.BIGINT, "bigint", IBM_2_4, DRB_10_0, VM_1_3 ), 81 new TypeDescriptor 82 ( Types.BLOB, "blob", IBM_2_4, DRB_10_0, VM_1_3 ), 83 new TypeDescriptor 84 ( Types.CHAR, "char(5)", IBM_2_4, DRB_10_0, VM_1_3 ), 85 new TypeDescriptor 86 ( Types.BINARY, "char(5) for bit data", IBM_2_4, DRB_10_0, VM_1_3 ), 87 new TypeDescriptor 88 ( Types.CLOB, "clob", IBM_2_4, DRB_10_0, VM_1_3 ), 89 new TypeDescriptor 90 ( Types.DATE, "date", IBM_2_4, DRB_10_0, VM_1_3 ), 91 new TypeDescriptor 92 ( Types.DECIMAL, "decimal", IBM_2_4, DRB_10_0, VM_1_3 ), 93 new TypeDescriptor 94 ( Types.DOUBLE, "double", IBM_2_4, DRB_10_0, VM_1_3 ), 95 new TypeDescriptor 96 ( Types.DOUBLE, "double precision", IBM_2_4, DRB_10_0, VM_1_3 ), 97 new TypeDescriptor 98 ( Types.REAL, "float(23)", IBM_2_4, DRB_10_0, VM_1_3 ), 99 new TypeDescriptor 100 ( Types.DOUBLE, "float", IBM_2_4, DRB_10_0, VM_1_3 ), 101 new TypeDescriptor 102 ( Types.INTEGER, "integer", IBM_2_4, DRB_10_0, VM_1_3 ), 103 new TypeDescriptor 104 ( Types.LONGVARCHAR, "long varchar", IBM_2_4, DRB_10_0, VM_1_3 ), 105 new TypeDescriptor 106 ( Types.LONGVARBINARY, "long varchar for bit data", IBM_2_4, DRB_10_0, VM_1_3 ), 107 new TypeDescriptor 108 ( Types.NUMERIC, "numeric", IBM_2_4, DRB_10_0, VM_1_3 ), 109 new TypeDescriptor 110 ( Types.REAL, "real", IBM_2_4, DRB_10_0, VM_1_3 ), 111 new TypeDescriptor 112 ( Types.SMALLINT, "smallint", IBM_2_4, DRB_10_0, VM_1_3 ), 113 new TypeDescriptor 114 ( Types.TIME, "time", IBM_2_4, DRB_10_0, VM_1_3 ), 115 new TypeDescriptor 116 ( Types.TIMESTAMP, "timestamp", IBM_2_4, DRB_10_0, VM_1_3 ), 117 new TypeDescriptor 118 ( Types.VARCHAR, "varchar(5)", IBM_2_4, DRB_10_0, VM_1_3 ), 119 new TypeDescriptor 120 ( Types.VARBINARY, "varchar(5) for bit data", IBM_2_4, DRB_10_0, VM_1_3 ), 121 }; 122 123 private static final Object [] ROW_1 = 128 { 129 131 new Long ( 1L ), 132 new MyBlob( SAMPLE_BYTES ), 133 SAMPLE_STRING, 134 SAMPLE_BYTES, 135 new MyClob( SAMPLE_STRING ), 136 new java.sql.Date ( 1L ), 137 new BigDecimal( 1.0 ), 138 new Double ( 1.0 ), 139 new Double ( 1.0 ), 140 new Float ( (float) 1.0 ), 141 new Double ( 1.0 ), 142 new Integer ( 1 ), 143 SAMPLE_STRING, 144 SAMPLE_BYTES, 145 new BigDecimal( 1.0 ), 146 new Float ( (float) 1.0 ), 147 new Short ( (short) 1 ), 148 new Time( 1L ), 149 new Timestamp( 1L ), 150 SAMPLE_STRING, 151 SAMPLE_BYTES, 152 }; 153 154 private static final T_CN[] COERCIONS = 168 { 169 new T_CN( Types.BIGINT, new boolean[] { Y,_,Y,_,_,_,_,Y,Y,Y,Y,_,Y,Y,Y,_,_,Y,_ } ), 183 new T_CN( Types.BLOB, new boolean[] { _,Y,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_ } ), 184 new T_CN( Types.CHAR, new boolean[] { _,_,Y,_,_,_,_,_,_,_,Y,_,_,_,_,_,_,Y,_ } ), 185 new T_CN( Types.BINARY, new boolean[] { _,_,_,Y,_,_,_,_,_,_,_,Y,_,_,_,_,_,_,Y } ), 186 new T_CN( Types.CLOB, new boolean[] { _,_,_,_,Y,_,_,_,_,_,_,_,_,_,_,_,_,_,_ } ), 187 new T_CN( Types.DATE, new boolean[] { _,_,_,_,_,Y,_,_,_,_,_,_,_,_,_,_,_,_,_ } ), 188 new T_CN( Types.DECIMAL, new boolean[] { Y,_,_,_,_,_,Y,Y,Y,Y,Y,_,Y,Y,Y,_,_,Y,_ } ), 189 new T_CN( Types.DOUBLE, new boolean[] { Y,_,_,_,_,_,Y,Y,Y,Y,Y,_,Y,Y,Y,_,_,Y,_ } ), 190 new T_CN( Types.REAL, new boolean[] { Y,_,Y,_,_,_,Y,Y,Y,Y,Y,_,Y,Y,Y,_,_,Y,_ } ), 191 new T_CN( Types.INTEGER, new boolean[] { Y,_,Y,_,_,_,Y,Y,Y,Y,Y,_,Y,Y,Y,_,_,Y,_ } ), 192 new T_CN( Types.LONGVARCHAR, new boolean[] { _,_,Y,_,_,_,_,_,_,_,Y,_,_,_,_,_,_,Y,_ } ), 193 new T_CN( Types.LONGVARBINARY, new boolean[] { _,_,_,_,_,_,_,_,_,_,_,Y,_,_,_,_,_,_,Y } ), 194 new T_CN( Types.NUMERIC, new boolean[] { Y,_,Y,_,_,_,Y,Y,Y,Y,Y,_,Y,Y,Y,_,_,Y,_ } ), 195 new T_CN( Types.REAL, new boolean[] { Y,_,Y,_,_,_,Y,Y,Y,Y,Y,_,Y,Y,Y,_,_,Y,_ } ), 196 new T_CN( Types.SMALLINT, new boolean[] { Y,_,Y,_,_,_,Y,Y,Y,Y,Y,_,Y,Y,Y,_,_,Y,_ } ), 197 new T_CN( Types.TIME, new boolean[] { _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,Y,_,_,_ } ), 198 new T_CN( Types.TIMESTAMP, new boolean[] { _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,Y,_,_ } ), 199 new T_CN( Types.VARCHAR, new boolean[] { _,_,Y,_,_,_,_,_,_,_,Y,_,_,_,_,_,_,Y,_ } ), 200 new T_CN( Types.VARBINARY, new boolean[] { _,_,_,_,_,_,_,_,_,_,_,Y,_,_,_,_,_,_,Y } ), 201 }; 202 203 209 private static HashMap _types = new HashMap(); 212 private static HashMap _coercionIndex = new HashMap(); 215 221 public JDBCDriverTest() {} 222 223 229 234 public void testSanity() 235 { 236 assertEquals 237 ( "ALL_TYPES.length == ROW_1.length", ALL_TYPES.length, ROW_1.length ); 238 239 int coercionCount = COERCIONS.length; 241 for ( int i = 0; i < coercionCount; i++ ) 242 { assertEquals( "Coercion " + i, coercionCount, COERCIONS[ i ].getCoercions().length ); } 243 } 244 245 250 public void testJDBCDriver() 251 throws Exception 252 { 253 Connection conn = getConnection(); 254 255 dropSchema( conn ); 256 createSchema( conn ); 257 258 datatypesTest( conn ); 259 260 close( conn ); 261 } 262 263 269 private void datatypesTest( Connection conn ) 274 throws Exception 275 { 276 TypeDescriptor[] types = ALL_TYPES; 277 String tableName = ALL_TYPES_TABLE; 278 Object [][] rows = new Object [][] { makeNullRow( types.length ), ROW_1 }; 279 280 checkDBMetadata( conn, tableName ); 281 stuffTable( conn, tableName, types, rows ); 282 readTable( conn, tableName, types, rows, null ); 283 } 284 285 private void checkDBMetadata( Connection conn, String tableName ) 289 throws Exception 290 { 291 String normalizedSchema = DEFAULT_USER_NAME.toUpperCase(); 292 String normalizedTable = tableName.toUpperCase(); 293 DatabaseMetaData dbmd = conn.getMetaData(); 294 295 ResultSet rs = dbmd.getColumns 296 ( null, normalizedSchema, normalizedTable, "%" ); 297 298 println( "Pawing through database metadata for " + normalizedSchema + '.' + normalizedTable ); 299 300 while( rs.next() ) 301 { 302 String columnName = rs.getString( "COLUMN_NAME" ); 303 int actualJdbcType = rs.getInt( "DATA_TYPE" ); 304 TypeDescriptor typeDesc = getType( columnName ); 305 306 if ( columnName.equals( KEY_COLUMN ) ) { continue; } 307 308 StringBuffer buffer = new StringBuffer (); 309 310 buffer.append( "[ " ); 311 buffer.append( rs.getString( "COLUMN_NAME" ) ); 312 buffer.append( ",\t" ); 313 buffer.append( "type( " + rs.getInt( "DATA_TYPE" ) + " ),\t" ); 314 buffer.append( rs.getString( "TYPE_NAME" ) ); 315 buffer.append( " ]" ); 316 317 println( buffer.toString() ); 318 319 assertEquals( columnName, ddmdTypeKludge( typeDesc.getJdbcType() ), actualJdbcType ); 320 } 321 322 close( rs ); 323 } 324 325 private void checkProcMetadata( Connection conn, String procName, TypeDescriptor[] signature ) 329 throws Exception 330 { 331 String normalizedSchema = DEFAULT_USER_NAME.toUpperCase(); 332 String normalizedProc = procName.toUpperCase(); 333 DatabaseMetaData dbmd = conn.getMetaData(); 334 335 ResultSet rs = dbmd.getProcedureColumns 336 ( null, normalizedSchema, normalizedProc, "%" ); 337 338 println( "Pawing through database metadata for " + normalizedSchema + '.' + normalizedProc ); 339 340 while( rs.next() ) 341 { 342 String columnName = rs.getString( "COLUMN_NAME" ); 343 int actualJdbcType = rs.getInt( "DATA_TYPE" ); 344 TypeDescriptor typeDesc = getType( signature, columnName ); 345 346 if ( columnName.equals( KEY_COLUMN ) ) { continue; } 347 348 StringBuffer buffer = new StringBuffer (); 349 350 buffer.append( "[ " ); 351 buffer.append( rs.getString( "COLUMN_NAME" ) ); 352 buffer.append( ",\t" ); 353 buffer.append( "type( " + rs.getInt( "DATA_TYPE" ) + " ),\t" ); 354 buffer.append( rs.getString( "TYPE_NAME" ) ); 355 buffer.append( " ]" ); 356 357 println( buffer.toString() ); 358 359 assertEquals( columnName, ddmdTypeKludge( typeDesc.getJdbcType() ), actualJdbcType ); 360 } 361 362 close( rs ); 363 } 364 365 private void stuffTable 369 ( Connection conn, String tableName, TypeDescriptor[] types, Object [][] rows ) 370 throws Exception 371 { 372 PreparedStatement ps = makeInsert( conn, tableName, types ); 373 int rowCount = rows.length; 374 375 for ( int i = 0; i < rowCount; i++ ) 376 { 377 setRow( ps, i + 1, types, rows[ i ] ); 378 } 379 380 close( ps ); 381 } 382 383 private PreparedStatement makeInsert 384 ( Connection conn, String tableName, TypeDescriptor[] types ) 385 throws Exception 386 { 387 StringBuffer masterBuffer = new StringBuffer (); 388 StringBuffer columnBuffer = new StringBuffer (); 389 StringBuffer valuesBuffer = new StringBuffer (); 390 int columnNumber = 0; 391 int valuesNumber = 0; 392 int typeCount = types.length; 393 394 beginColumnList( columnBuffer ); 395 beginColumnList( valuesBuffer ); 396 397 addColumn( columnBuffer, columnNumber++, doubleQuote( KEY_COLUMN ) ); 398 addColumn( valuesBuffer, valuesNumber++, "?" ); 399 400 for ( int i = 0; i < typeCount; i++ ) 401 { 402 TypeDescriptor type = types[ i ]; 403 404 if ( getServerVersion().atLeast( type.getDerbyVersion() ) ) 405 { 406 String typeName = type.getDerbyTypeName(); 407 String columnDesc = doubleQuote( typeName ); 408 409 addColumn( columnBuffer, columnNumber++, columnDesc ); 410 addColumn( valuesBuffer, valuesNumber++, "?" ); 411 } 412 } 413 414 endColumnList( columnBuffer ); 415 endColumnList( valuesBuffer ); 416 417 masterBuffer.append( "insert into " + tableName + "\n" ); 418 masterBuffer.append( columnBuffer.toString() ); 419 masterBuffer.append( "values\n" ); 420 masterBuffer.append( valuesBuffer.toString() ); 421 422 PreparedStatement ps = prepare( conn, masterBuffer.toString() ); 423 424 return ps; 425 } 426 427 private void readTable 431 ( Connection conn, String tableName, TypeDescriptor[] types, Object [][] rows, List casts ) 432 throws Exception 433 { 434 PreparedStatement ps = readTableQuery( conn, tableName, types ); 435 ResultSet rs = ps.executeQuery(); 436 437 checkRSMD( rs ); 438 checkRows( rs, types, rows, casts ); 439 440 close( rs ); 441 close( ps ); 442 } 443 444 private PreparedStatement readTableQuery 448 ( Connection conn, String tableName, TypeDescriptor[] types ) 449 throws Exception 450 { 451 StringBuffer buffer = new StringBuffer (); 452 int columnNumber = 0; 453 int typeCount = types.length; 454 455 buffer.append( "select \n" ); 456 457 addColumn( buffer, columnNumber++, doubleQuote( KEY_COLUMN ) ); 458 459 for ( int i = 0; i < typeCount; i++ ) 460 { 461 TypeDescriptor type = types[ i ]; 462 463 if ( getServerVersion().atLeast( type.getDerbyVersion() ) ) 464 { 465 String typeName = type.getDerbyTypeName(); 466 String columnDesc = doubleQuote( typeName ); 467 468 addColumn( buffer, columnNumber++, columnDesc ); 469 } 470 } 471 472 buffer.append( "\nfrom " + tableName + "\n" ); 473 buffer.append( "order by " + doubleQuote( KEY_COLUMN ) ); 474 475 PreparedStatement ps = prepare( conn, buffer.toString() ); 476 477 return ps; 478 } 479 480 private void checkRSMD( ResultSet rs ) 485 throws Exception 486 { 487 ResultSetMetaData rsmd = rs.getMetaData(); 488 int columnCount = rsmd.getColumnCount(); 489 int firstTastyColumn = 0; 490 491 println( "ResultSetMetaData:\n" ); 492 493 firstTastyColumn++; 495 for ( int i = firstTastyColumn; i < columnCount; i++ ) 496 { 497 StringBuffer buffer = new StringBuffer (); 498 int columnID = i + 1; 499 String columnName = rsmd.getColumnName( columnID ); 500 TypeDescriptor typeDesc = getType( columnName ); 501 int expectedType = rsmdTypeKludge( typeDesc.getJdbcType() ); 502 int actualType = rsmd.getColumnType( columnID ); 503 504 buffer.append( "[ " ); 505 buffer.append( columnName ); 506 buffer.append( ", type( " ); 507 buffer.append( actualType ); 508 buffer.append( " ), " ); 509 buffer.append( rsmd.getColumnTypeName( columnID ) ); 510 buffer.append( " ]\n" ); 511 512 println( buffer.toString() ); 513 514 assertEquals( columnName, expectedType, actualType ); 515 } 516 517 } 518 519 private void checkRows( ResultSet rs, TypeDescriptor[] types, Object [][] rows, List casts ) 524 throws Exception 525 { 526 int rowCount = rows.length; 527 528 for ( int i = 0; i < rowCount; i++ ) 529 { 530 rs.next(); 531 checkRow( rs, types, rows[ i ], casts ); 532 } 533 } 534 535 private void checkRow( ResultSet rs, TypeDescriptor[] types, Object [] row, List casts ) 540 throws Exception 541 { 542 int typeCount = types.length; 543 544 for ( int i = 0; i < typeCount; i++ ) 545 { 546 TypeDescriptor type = types[ i ]; 547 548 if ( getServerVersion().atLeast( type.getDerbyVersion() ) ) 549 { 550 String columnName = type.getDerbyTypeName(); 551 Object expectedValue = row[ i ]; 552 Object actualValue = getColumn( rs, columnName, type ); 553 554 println( "Comparing column " + columnName + ": " + expectedValue + " to " + actualValue ); 555 compareObjects( columnName, expectedValue, actualValue ); 556 557 checkCoercions( rs, columnName, type, casts ); 558 } 559 } 560 } 561 562 private void checkCoercions( ResultSet rs, String columnName, TypeDescriptor type, List casts ) 566 throws Exception 567 { 568 T_CN coercionDesc = COERCIONS[ getCoercionIndex( type.getJdbcType() ) ]; 569 boolean[] coercions = coercionDesc.getCoercions(); 570 int count = coercions.length; 571 int legalCoercions = 0; 572 573 println( "Checking coercions for " + columnName ); 574 575 for ( int i = 0; i < count; i++ ) 576 { 577 if ( coercions[ i ] ) 578 { 579 legalCoercions++; 580 581 int jdbcType = COERCIONS[ i ].getJdbcType(); 582 Object retval = getColumn( rs, columnName, jdbcType ); 583 584 if ( casts != null ) { casts.add( retval ); } 585 586 println( "\t" + jdbcType + ":\t" + retval ); 587 } 588 589 } 590 592 Object objval = rs.getObject( columnName ); 593 if ( objval == null ) { println( "\tgetObject() = null" ); } 594 else 595 { 596 StringBuffer buffer = new StringBuffer (); 597 buffer.append( "\tgetObject() = " ); 598 buffer.append( objval.getClass().getName() ); 599 buffer.append( "( " ); 600 buffer.append( objval ); 601 buffer.append( " )" ); 602 println( buffer.toString() ); 603 } 604 } 605 606 private int rsmdTypeKludge( int originalJDbcType ) 613 { 614 if ( usingEmbeddedClient() && getServerVMVersion().atLeast( VM_1_4 ) ) { return originalJDbcType; } 616 617 switch( originalJDbcType ) 618 { 619 case Types.NUMERIC: 622 if ( usingEmbeddedClient() ) { return originalJDbcType; } 623 else { return Types.DECIMAL; } 624 625 default: return originalJDbcType; 626 } 627 } 628 629 private int ddmdTypeKludge( int originalJDbcType ) 634 { 635 switch( originalJDbcType ) 636 { 637 case JDBC_BOOLEAN: 638 if ( getServerVMVersion().atLeast( VM_1_4 ) ) { return originalJDbcType; } 639 else { return Types.BIT; } 640 641 default: return originalJDbcType; 642 } 643 } 644 645 private void setRow( PreparedStatement ps, int keyValue, TypeDescriptor[] types, Object [] row ) 650 throws Exception 651 { 652 int param = 1; 653 int typeCount = types.length; 654 655 ps.setInt( param++, keyValue ); 656 657 for ( int i = 0; i < typeCount; i++ ) 658 { 659 TypeDescriptor type = types[ i ]; 660 Object value = row[ i ]; 661 662 if ( getServerVersion().atLeast( type.getDerbyVersion() ) ) 663 { 664 setParameter( ps, param++, type, value ); 665 } 666 } 667 668 ps.execute(); 669 } 670 671 private Object [][] makeRows( Object [][] rows ) 675 { 676 int count = rows.length; 677 int columns = rows[0].length; 678 Object [][] result = new Object [ count + 1 ][]; 679 int idx = 0; 680 681 result[ idx++ ] = makeNullRow( columns ); 682 683 for ( int i = 0; i < count; i++ ) 684 { 685 result[ idx++ ] = rows[ i ]; 686 } 687 688 return result; 689 } 690 691 private Object [] makeNullRow( int rowLength ) 692 { 693 return new Object [ rowLength ]; 694 } 695 696 private void buildTypeMap() 700 { 701 int typeCount = ALL_TYPES.length; 702 703 for ( int i = 0; i < typeCount; i++ ) { putType( ALL_TYPES[ i ] ); } 704 } 705 private void putType( TypeDescriptor type ) 706 { 707 _types.put( type.getDerbyTypeName(), type ); 708 } 709 710 private TypeDescriptor getType( String typeName ) 714 { 715 if ( _types.size() == 0 ) { buildTypeMap(); } 716 717 return (TypeDescriptor) _types.get( typeName ); 718 } 719 720 private TypeDescriptor getType( int jdbcType ) 724 { 725 int count = ALL_TYPES.length; 726 727 for ( int i = 0; i < count; i++ ) 728 { 729 TypeDescriptor type = ALL_TYPES[ i ]; 730 731 if ( type.getJdbcType() == jdbcType ) { return type; } 732 } 733 734 return null; 735 } 736 737 private TypeDescriptor getType( TypeDescriptor[] types, String typeName ) 741 { 742 int count = types.length; 743 744 for ( int i = 0; i < count; i++ ) 745 { 746 TypeDescriptor type = types[ i ]; 747 748 if ( type.getDerbyTypeName().equals( typeName ) ) { return type; } 749 } 750 751 return null; 752 } 753 754 private void buildCoercionMap() 758 { 759 int count = COERCIONS.length; 760 761 for ( int i = 0; i < count; i++ ) { putCoercionIndex( i ); } 762 } 763 private void putCoercionIndex( int index ) 764 { 765 _coercionIndex.put( new Integer ( COERCIONS[ index ].getJdbcType() ), new Integer ( index ) ); 766 } 767 768 private int getCoercionIndex( int jdbcType ) 772 { 773 if ( _coercionIndex.size() == 0 ) { buildCoercionMap(); } 774 775 return ((Integer ) _coercionIndex.get( new Integer ( jdbcType ) )).intValue(); 776 } 777 778 784 790 796 private void createSchema( Connection conn ) 800 throws Exception 801 { 802 createTable( conn, ALL_TYPES_TABLE, ALL_TYPES ); 803 } 804 805 private void createTable( Connection conn, String tableName, TypeDescriptor[] types ) 809 throws Exception 810 { 811 StringBuffer buffer = new StringBuffer (); 812 int columnNumber = 0; 813 int typeCount = types.length; 814 815 buffer.append( "create table " + tableName + "\n" ); 816 beginColumnList( buffer ); 817 818 addColumn( buffer, columnNumber++, doubleQuote( KEY_COLUMN ) + "\tint" ); 819 820 for ( int i = 0; i < typeCount; i++ ) 821 { 822 TypeDescriptor type = types[ i ]; 823 824 if ( getServerVersion().atLeast( type.getDerbyVersion() ) ) 825 { 826 String typeName = type.getDerbyTypeName(); 827 String columnDesc = doubleQuote( typeName ) + '\t' + typeName; 828 829 addColumn( buffer, columnNumber++, columnDesc ); 830 } 831 } 832 833 endColumnList( buffer ); 834 835 PreparedStatement ps = prepare( conn, buffer.toString() ); 836 837 ps.execute(); 838 839 close( ps ); 840 } 841 842 843 private void beginColumnList( StringBuffer buffer ) 847 { 848 buffer.append( "(\n" ); 849 } 850 private void endColumnList( StringBuffer buffer ) 851 { 852 buffer.append( "\n)\n" ); 853 } 854 private void addColumn( StringBuffer buffer, int columnNumber, String text ) 855 { 856 if ( columnNumber > 0 ) { buffer.append( "," ); } 857 858 buffer.append( "\n\t" ); 859 buffer.append( text ); 860 } 861 862 private void dropSchema( Connection conn ) 866 { 867 dropTable( conn, ALL_TYPES_TABLE ); 868 } 869 870 private void setParameter( PreparedStatement ps, int param, TypeDescriptor type, Object value ) 874 throws Exception 875 { 876 int jdbcType = type.getJdbcType(); 877 878 if ( value != null ) 879 { 880 setParameter( ps, param, jdbcType, value ); 881 return; 882 } 883 else if ( clientSupports( type ) ) 884 { 885 ps.setNull( param, jdbcType ); 886 887 return; 888 } 889 890 892 fail( "Unsupported Derby type: " + type.getDerbyTypeName() ); 893 } 894 895 private void checkParameter( ResultSet rs, int param, Object value ) 899 throws Exception 900 { 901 Object actualValue; 902 903 if ( value == null ) 904 { 905 return; 906 } 907 908 println( "Checking " + value.getClass().getName() ); 909 910 if ( value instanceof Boolean ) { actualValue = new Boolean ( rs.getBoolean( param ) ); } 911 else if ( value instanceof Byte ) { actualValue = new Byte ( rs.getByte( param ) ); } 912 else if ( value instanceof Short ) { actualValue = new Short ( rs.getShort( param ) ); } 913 else if ( value instanceof Integer ) { actualValue = new Integer ( rs.getInt( param ) ); } 914 else if ( value instanceof Long ) { actualValue = new Long ( rs.getLong( param ) ); } 915 else if ( value instanceof Float ) { actualValue = new Float ( rs.getFloat( param ) ); } 916 else if ( value instanceof Double ) { actualValue = new Double ( rs.getDouble( param ) ); } 917 else if ( value instanceof String ) { actualValue = rs.getString( param ); } 918 else if ( value instanceof BigDecimal ) { actualValue = rs.getBigDecimal( param ); } 919 else 920 { 921 actualValue = rs.getObject( param ); 922 } 923 924 assertTrue( value.equals( actualValue ) ); 925 } 926 927 928 private boolean clientSupports( TypeDescriptor type ) 930 { 931 Version firstSupportedVersion; 932 933 if ( usingDB2Client() ) { firstSupportedVersion = type.getDb2jccVersion(); } 934 else { firstSupportedVersion = type.getDerbyVersion(); } 935 936 if ( firstSupportedVersion == null ) { return false; } 937 else { return getDriverVersion().atLeast( firstSupportedVersion ); } 938 } 939 940 private Object getColumn( ResultSet rs, String columnName, TypeDescriptor type ) 944 throws Exception 945 { 946 int jdbcType = type.getJdbcType(); 947 948 return getColumn( rs, columnName, jdbcType ); 949 } 950 private Object getOutArg( CallableStatement cs, int arg, TypeDescriptor type ) 954 throws Exception 955 { 956 int jdbcType = type.getJdbcType(); 957 958 return getOutArg( cs, arg, jdbcType ); 959 } 960 private String doubleQuote( String text ) 964 { 965 return '"' + text + '"'; 966 } 967 968 974 980 public static final class TypeDescriptor 981 { 982 private int _jdbcType; 983 private String _derbyTypeName; 984 private Version _db2jccVersion; private Version _derbyVersion; private Version _vmVersion; 988 public TypeDescriptor 989 ( 990 int jdbcType, 991 String derbyTypeName, 992 Version db2jccVersion, 993 Version derbyVersion, 994 Version vmVersion 995 ) 996 { 997 _jdbcType = jdbcType; 998 _derbyTypeName = derbyTypeName; 999 _db2jccVersion = db2jccVersion; 1000 _derbyVersion = derbyVersion; 1001 _vmVersion = vmVersion; 1002 } 1003 1004 public int getJdbcType() { return _jdbcType; } 1005 public String getDerbyTypeName() { return _derbyTypeName; } 1006 public Version getDb2jccVersion() { return _db2jccVersion; } 1007 public Version getDerbyVersion() { return _derbyVersion; } 1008 public Version getVMVersion() { return _vmVersion; } 1009 } 1010 1011 1017 public static final class T_CN 1018 { 1019 private int _jdbcType; 1020 private boolean[] _coercions; 1021 1022 public T_CN( int jdbcType, boolean[] coercions ) 1023 { 1024 _jdbcType = jdbcType; 1025 _coercions = coercions; 1026 } 1027 1028 public int getJdbcType() { return _jdbcType; } 1029 public boolean[] getCoercions() { return _coercions; } 1030 } 1031 1032 1037 public static final class MyBlob implements Blob 1038 { 1039 private byte[] _bytes; 1040 1041 public MyBlob( byte[] bytes ) 1042 { 1043 _bytes = bytes; 1044 } 1045 1046 public InputStream getBinaryStream() 1047 { 1048 return new ByteArrayInputStream( _bytes ); 1049 } 1050 1051 public byte[] getBytes( long position, int length ) { return _bytes; } 1052 1053 public long length() { return (long) _bytes.length; } 1054 1055 public long position( Blob pattern, long start ) { return 0L; } 1056 public long position( byte[] pattern, long start ) { return 0L; } 1057 1058 public boolean equals( Object other ) 1059 { 1060 if ( other == null ) { return false; } 1061 if ( !( other instanceof Blob ) ) { return false; } 1062 1063 Blob that = (Blob) other; 1064 1065 try { 1066 if ( this.length() != that.length() ) { return false; } 1067 1068 InputStream thisStream = this.getBinaryStream(); 1069 InputStream thatStream = that.getBinaryStream(); 1070 1071 while( true ) 1072 { 1073 int nextByte = thisStream.read(); 1074 1075 if ( nextByte < 0 ) { break; } 1076 if ( nextByte != thatStream.read() ) { return false; } 1077 } 1078 } 1079 catch (Exception e) 1080 { 1081 System.err.println( e.getMessage() ); 1082 e.printStackTrace(); 1083 return false; 1084 } 1085 1086 return true; 1087 } 1088 1089 } 1090 1091 1096 public static final class MyClob implements Clob 1097 { 1098 private String _contents; 1099 1100 public MyClob( String contents ) 1101 { 1102 _contents = contents; 1103 } 1104 1105 public InputStream getAsciiStream() 1106 { 1107 try { 1108 return new ByteArrayInputStream( _contents.getBytes( "UTF-8" ) ); 1109 } 1110 catch (Exception e) { return null; } 1111 } 1112 1113 public Reader getCharacterStream() 1114 { 1115 return new CharArrayReader( _contents.toCharArray() ); 1116 } 1117 1118 public String getSubString( long position, int length ) 1119 { 1120 return _contents.substring( (int) position, length ); 1121 } 1122 1123 public long length() { return (long) _contents.length(); } 1124 1125 public long position( Clob searchstr, long start ) { return 0L; } 1126 public long position( String searchstr, long start ) { return 0L; } 1127 1128 public boolean equals( Object other ) 1129 { 1130 if ( other == null ) { return false; } 1131 if ( !( other instanceof Clob ) ) { return false; } 1132 1133 Clob that = (Clob) other; 1134 1135 try { 1136 if ( this.length() != that.length() ) { return false; } 1137 1138 InputStream thisStream = this.getAsciiStream(); 1139 InputStream thatStream = that.getAsciiStream(); 1140 1141 while( true ) 1142 { 1143 int nextByte = thisStream.read(); 1144 1145 if ( nextByte < 0 ) { break; } 1146 if ( nextByte != thatStream.read() ) { return false; } 1147 } 1148 } 1149 catch (Exception e) 1150 { 1151 System.err.println( e.getMessage() ); 1152 e.printStackTrace(); 1153 return false; 1154 } 1155 1156 return true; 1157 } 1158 1159 } 1160 1161} 1162 | Popular Tags |