1 21 package org.apache.derbyTesting.functionTests.tests.lang; 22 23 import java.io.UnsupportedEncodingException ; 24 import java.sql.Date ; 25 import java.sql.PreparedStatement ; 26 import java.sql.ResultSet ; 27 import java.sql.SQLException ; 28 import java.sql.Statement ; 29 import java.sql.Time ; 30 import java.sql.Timestamp ; 31 import java.sql.Types ; 32 import java.util.Calendar ; 33 import java.util.Random ; 34 35 import junit.framework.Test; 36 import junit.framework.TestSuite; 37 38 import org.apache.derbyTesting.junit.BaseJDBCTestCase; 39 import org.apache.derbyTesting.junit.CleanDatabaseTestSetup; 40 41 42 public class TimeHandlingTest extends BaseJDBCTestCase { 43 44 48 private static final String [] CURRENT_TIME_FUNCTIONS = 49 {"CURRENT TIME", "CURRENT_TIME"}; 50 51 55 private static final String [] CURRENT_TIMESTAMP_FUNCTIONS = 56 {"CURRENT TIMESTAMP", "CURRENT_TIMESTAMP"}; 57 58 61 private static final long SLEEP_TIME = 2000; 62 63 66 private Calendar cal; 67 68 69 public static Test suite() 70 { 71 TestSuite suite = new TestSuite(TimeHandlingTest.class); 72 73 return new CleanDatabaseTestSetup(suite) { 74 protected void decorateSQL(Statement s) throws SQLException { 75 76 s.execute("CREATE FUNCTION SLEEP() RETURNS INTEGER" + 77 " LANGUAGE JAVA PARAMETER STYLE JAVA" + 78 " NO SQL " + 79 " EXTERNAL NAME '"+ 80 TimeHandlingTest.class.getName().concat(".sleep'")); 81 82 s.execute("CREATE TABLE TIME_ALL (ID INT," + 83 " C_T TIME," + 84 " C_D DATE," + 85 " C_TS TIMESTAMP)"); 86 87 for (int f = 0; f < CURRENT_TIME_FUNCTIONS.length; f++) 88 { 89 s.execute("ALTER TABLE TIME_ALL ADD COLUMN" + 90 " D_T" + f + " TIME WITH DEFAULT " + 91 CURRENT_TIME_FUNCTIONS[f]); 92 } 93 for (int f = 0; f < CURRENT_TIMESTAMP_FUNCTIONS.length; f++) 94 { 95 s.execute("ALTER TABLE TIME_ALL ADD COLUMN" + 96 " D_TS" + f + " TIMESTAMP WITH DEFAULT " + 97 CURRENT_TIMESTAMP_FUNCTIONS[f]); 98 } 99 } 100 }; 101 } 102 103 110 public static int sleep() throws InterruptedException { 111 Thread.sleep(SLEEP_TIME); 112 return 0; 113 } 114 115 public TimeHandlingTest(String name) { 116 super(name); 117 } 118 119 125 protected void setUp() throws UnsupportedEncodingException , SQLException 126 { 127 cal = Calendar.getInstance(); 128 runSQLCommands("DELETE FROM TIME_ALL;"); 129 } 130 131 141 public void testInertTime() throws SQLException , UnsupportedEncodingException 142 { 143 getConnection().setAutoCommit(false); 144 146 147 Random r = new Random (); 148 149 156 final int itk = 71; 159 160 PreparedStatement ps = prepareStatement( 161 "INSERT INTO TIME_ALL(ID, C_T) VALUES (?, ?)"); 162 163 for (int i = 0; i < 500; i++) { 164 165 int id = r.nextInt(1000000); 167 ps.setInt(1, id); 168 169 Time ct = getCodedTime(id); 170 171 switch ((id % itk) % 3) 172 { 173 case 0: ps.setTime(2, ct); 175 break; 176 case 1: ps.setString(2, ct.toString()); 178 break; 179 case 2: ps.setString(2, ct.toString().replace(':', '.')); 181 break; 182 default: 183 fail("not reached"); 184 185 } 186 ps.executeUpdate(); 187 } 188 ps.close(); 189 commit(); 190 191 Statement s = createStatement(); 192 193 ResultSet rs = s.executeQuery("SELECT ID, C_T FROM TIME_ALL"); 194 int rowCount = 0; 195 while (rs.next()) 196 { 197 int id = rs.getInt(1); 198 Time t = checkTimeValue(rs, 2); 199 assertTimeEqual(getCodedTime(id), t); 200 rowCount++; 201 } 202 rs.close(); 203 s.close(); 204 commit(); 205 206 assertEquals(rowCount, 500); 207 } 208 209 218 private Time getCodedTime(int id) 219 { 220 final int hk = 17; 221 final int mk = 41; 222 final int sk = 67; 223 224 int hour = (id % hk) % 24; 225 int min = (id % mk) % 60; 226 int sec = (id % sk) % 60; 227 228 return getTime19700101(hour, min ,sec); 229 } 230 231 241 public void testCurrentTime() throws SQLException , InterruptedException 242 { 243 currentFunctionTests(Types.TIME, CURRENT_TIME_FUNCTIONS); 244 } 245 246 256 public void testCurrentTimestamp() throws SQLException , InterruptedException 257 { 258 currentFunctionTests(Types.TIMESTAMP, CURRENT_TIMESTAMP_FUNCTIONS); 259 } 260 273 private void currentFunctionTests(int jdbcType, String [] functions) 274 throws SQLException , InterruptedException 275 { 276 Statement s = createStatement(); 277 278 for (int f = 0; f < functions.length; f++) { 280 checkCurrentQuery(jdbcType, s, "VALUES " + functions[f], 281 new int[] {1}, 1); 282 } 283 284 StringBuffer rb = new StringBuffer ("("); 287 for (int f = 0; f < functions.length; f++) { 288 if (f != 0) 289 rb.append(", "); 290 rb.append(functions[f]); 291 } 292 rb.append(")"); 293 String row = rb.toString(); 294 295 int[] columns = new int[functions.length]; 296 for (int f = 0; f < columns.length; f++) 297 columns[f] = f + 1; 298 299 String sql = "VALUES " + row; 301 checkCurrentQuery(jdbcType, s, sql, columns, functions.length); 302 303 304 sql = "VALUES " + row + "," + row + "," + row; 306 checkCurrentQuery(jdbcType, s, sql, columns, 3 * functions.length); 307 308 String sleepRow = row.substring(0, row.length() - 1) 311 + ", SLEEP())"; 312 313 sql = "VALUES " + sleepRow + "," + sleepRow + "," + sleepRow; 314 checkCurrentQuery(jdbcType, s, sql, columns, 3 * functions.length); 315 316 317 String ccol = null; 319 String dcol = null; 320 switch (jdbcType) 321 { 322 case Types.TIME: 323 dcol = "D_T"; 324 ccol = "C_T"; 325 break; 326 case Types.TIMESTAMP: 327 dcol = "D_TS"; 328 ccol = "C_TS"; 329 break; 330 case Types.DATE: 331 dcol = "D_D"; 332 ccol = "C_D"; 333 break; 334 default: 335 fail("Unexpected JDBC Type " + jdbcType); 336 } 337 338 StringBuffer rm = new StringBuffer (); 340 for (int f = 0; f < functions.length; f++) { 341 if (f != 0) 342 rm.append(", "); 343 rm.append(functions[f]); 344 } 345 String mrow = rm.toString(); 346 347 StringBuffer sb = new StringBuffer (); 349 sb.append(ccol); for (int f = 0; f < functions.length; f++) { 351 sb.append(", "); 352 sb.append(dcol); 353 sb.append(f); 354 } 355 String typeColumnList = sb.toString(); 356 String selectAllType = "SELECT " + typeColumnList + " FROM TIME_ALL"; 357 358 int[] tableColumns = new int[columns.length + 1]; 359 for (int i = 0; i < tableColumns.length; i++) 360 tableColumns[i] = i+1; 361 362 String insert = "INSERT INTO TIME_ALL(" + ccol + ") VALUES " + mrow; 366 s.executeUpdate("DELETE FROM TIME_ALL"); 367 long start = System.currentTimeMillis(); 368 s.executeUpdate(insert); 369 long end = System.currentTimeMillis(); 370 ResultSet rs = s.executeQuery(selectAllType); 371 rs.next(); 372 checkCurrentMultiple(jdbcType, start, end, rs, tableColumns, 373 functions.length * (functions.length + 1)); 374 rs.close(); 375 376 sb = new StringBuffer (); 380 for (int f = 0; f < functions.length; f++) { 381 if (f != 0) 382 sb.append(", "); 383 sb.append("(SLEEP(), "); 384 sb.append(functions[f]); 385 sb.append(")"); 386 } 387 String mSleepRow = sb.toString(); 388 389 insert = "INSERT INTO TIME_ALL(ID, " + ccol + ") " + 390 " SELECT * FROM TABLE (VALUES " + 391 mSleepRow + 392 ") AS T"; 393 394 s.executeUpdate("DELETE FROM TIME_ALL"); 395 start = System.currentTimeMillis(); 396 s.executeUpdate(insert); 397 end = System.currentTimeMillis(); 398 rs = s.executeQuery(selectAllType); 399 rs.next(); 400 checkCurrentMultiple(jdbcType, start, end, rs, tableColumns, 401 functions.length * (functions.length + 1)); 402 rs.close(); 403 404 PreparedStatement psQ = prepareStatement( 407 selectAllType + " WHERE ID = ?"); 408 409 Object last = null; 410 for (int f = 0; f < functions.length; f++) { 411 PreparedStatement psI = prepareStatement("INSERT INTO TIME_ALL(ID, " + 412 ccol + ")" + 413 " VALUES (?, " + functions[f] +")"); 414 s.executeUpdate("DELETE FROM TIME_ALL"); 415 416 for (int i = 1; i <=3; i++) { 417 psI.setInt(1, i); 418 psQ.setInt(1, i); 419 start = System.currentTimeMillis(); 420 psI.executeUpdate(); 421 end = System.currentTimeMillis(); 422 423 rs = psQ.executeQuery(); 424 rs.next(); 425 Object next = checkCurrentMultiple(jdbcType, start, end, rs, 426 tableColumns, functions.length + 1); 427 rs.close(); 428 429 if (last != null) { 430 assertFalse("CURRENT value not changed over executions", 434 last.equals(next)); 435 } 436 last = next; 437 438 Thread.sleep(SLEEP_TIME); 440 } 441 psI.close(); 442 443 } 444 445 psQ.close(); 446 s.close(); 447 } 448 449 460 private void checkCurrentQuery(int sqlType, 461 Statement s, String sql, int[] columns, int expectedCount) 462 throws SQLException 463 { 464 long start = System.currentTimeMillis(); 465 ResultSet rs = s.executeQuery(sql); 466 rs.next(); 467 long end = System.currentTimeMillis(); 468 checkCurrentMultiple(sqlType, start, end, rs, 469 columns, expectedCount); 470 rs.close(); 471 } 472 473 486 private Object checkCurrentMultiple(int jdbcType, long start, long end, ResultSet rs, 487 int[] columns, int expectedCount) throws SQLException 488 { 489 switch (jdbcType) 490 { 491 case Types.TIME: 492 return checkCurrentTimeMultiple(start, end, rs, columns, expectedCount); 493 case Types.TIMESTAMP: 494 return checkCurrentTimestampMultiple(start, end, rs, columns, expectedCount); 495 default: 496 fail("Unexpected type " + jdbcType); 497 return null; 498 } 499 } 500 501 511 private Time checkCurrentTimeMultiple(long start, long end, ResultSet rs, 512 int[] columns, int expectedCount) throws SQLException 513 { 514 Time base = checkCurrentTimeValue(start, end, rs, columns[0]); 519 assertNotNull(base); 520 int count = 1; 521 522 for (int i = 1; i < columns.length; i++) 524 { 525 Time t = checkCurrentTimeValue(start, end, rs, columns[i]); 526 assertEquals("CURENT TIME changed during execution", base, t); 527 count++; 528 } 529 530 while (rs.next()) { 532 for (int i = 0; i < columns.length; i++) 533 { 534 Time t = checkCurrentTimeValue(start, end, rs, columns[i]); 535 assertEquals("CURENT TIME changed during execution", base, t); 536 count++; 537 } 538 } 539 540 assertEquals(expectedCount, count); 541 542 return base; 543 } 544 554 private Timestamp checkCurrentTimestampMultiple(long start, long end, ResultSet rs, 555 int[] columns, int expectedCount) throws SQLException 556 { 557 Timestamp base = checkCurrentTimestampValue(start, end, rs, columns[0]); 562 assertNotNull(base); 563 int count = 1; 564 565 for (int i = 1; i < columns.length; i++) 567 { 568 Timestamp ts = checkCurrentTimestampValue(start, end, rs, columns[i]); 569 assertEquals("CURENT TIMESTAMP changed during execution", base, ts); 570 count++; 571 } 572 573 while (rs.next()) { 575 for (int i = 0; i < columns.length; i++) 576 { 577 Timestamp ts = checkCurrentTimestampValue(start, end, rs, columns[i]); 578 assertEquals("CURENT TIMESTAMP changed during execution", base, ts); 579 count++; 580 } 581 } 582 583 assertEquals(expectedCount, count); 584 585 return base; 586 } 587 596 private Time checkTimeValue(ResultSet rs, int column) throws SQLException 597 { 598 assertEquals(java.sql.Types.TIME, rs.getMetaData().getColumnType(column)); 599 600 try { 601 rs.getDate(column); 602 fail("ResultSet.getDate() succeeded on TIME column"); 603 } catch (SQLException e) { 604 assertSQLState("22005", e); 605 } 606 607 Time tv = rs.getTime(column); 608 assertEquals(tv == null, rs.wasNull()); 609 610 Object ov = rs.getObject(column); 611 assertEquals(ov == null, rs.wasNull()); 612 613 if (tv == null) { 614 assertNull(ov); 615 return null; 616 } 617 618 assertTrue(ov instanceof java.sql.Time ); 619 assertEquals(tv, ov); 620 621 assertTime1970(tv); 623 cal.clear(); 624 cal.setTime(tv); 625 626 assertEquals(0, cal.get(Calendar.MILLISECOND)); 629 630 long now = System.currentTimeMillis(); 631 Timestamp tsv = rs.getTimestamp(column); 632 long now2 = System.currentTimeMillis(); 633 assertNotNull(tsv); 634 assertFalse(rs.wasNull()); 635 636 assertTimeEqual(tv, tsv); 638 639 if (!(isDateEqual(now, tsv) || isDateEqual(now2, tsv))) 644 { 645 fail("TIME to java.sql.Timestamp does not contain current date " + tsv); 646 } 647 648 String sv = rs.getString(column); 649 assertNotNull(sv); 650 assertFalse(rs.wasNull()); 651 652 assertEquals("ResultSet String converted to java.sql.Time mismatch", 654 tv, getTime19700101(sv, cal)); 655 656 return tv; 657 } 658 659 668 private Timestamp checkTimestampValue(ResultSet rs, int column) throws SQLException 669 { 670 assertEquals(java.sql.Types.TIMESTAMP, 671 rs.getMetaData().getColumnType(column)); 672 673 674 Timestamp tsv = rs.getTimestamp(column); 675 assertEquals(tsv == null, rs.wasNull()); 676 677 Object ov = rs.getObject(column); 678 assertEquals(ov == null, rs.wasNull()); 679 680 if (tsv == null) { 681 assertNull(ov); 682 return null; 683 } 684 685 assertTrue(ov instanceof java.sql.Timestamp ); 686 assertEquals(tsv, ov); 687 688 Time tv = rs.getTime(column); 689 assertNotNull(tv); 690 assertFalse(rs.wasNull()); 691 692 assertTime1970(tv); 694 695 if (!usingDerbyNetClient()) 699 assertTimeEqual(tv, tsv); 700 701 String sv = rs.getString(column); 702 assertNotNull(sv); 703 assertFalse(rs.wasNull()); 704 705 assertEquals("ResultSet String converted to java.sql.Timestamp mismatch", 707 tsv, Timestamp.valueOf(sv)); 708 709 return tsv; 710 } 711 712 723 private Time checkCurrentTimeValue(long start, long end, 724 ResultSet rs, int column) throws SQLException 725 { 726 Time tv = checkTimeValue(rs, column); 727 728 731 Time st = getTime19700101(start, cal); 732 Time et = getTime19700101(end, cal); 733 734 735 if (st.after(et)) { 736 741 assertTrue("CURRENT TIME outside of range when test crossing midnight", 742 (tv.equals(st) || tv.after(st)) 743 || (tv.equals(et) || tv.before(et))); 744 } 745 else 746 { 747 749 assertFalse("CURRENT TIME before start of statement", tv.before(st)); 752 assertFalse("CURRENT TIME after end of statement", tv.after(et)); 753 } 754 755 return tv; 756 } 757 768 private Timestamp checkCurrentTimestampValue(long start, long end, 769 ResultSet rs, int column) throws SQLException 770 { 771 Timestamp tsv = checkTimestampValue(rs, column); 772 773 776 Timestamp st = new Timestamp (start); 777 Timestamp et = new Timestamp (end); 778 779 780 if (st.after(et)) { 781 786 assertTrue("CURRENT TIME outside of range when test crossing midnight", 787 (tsv.equals(st) || tsv.after(st)) 788 || (tsv.equals(et) || tsv.before(et))); 789 } 790 else 791 { 792 794 assertFalse("CURRENT TIME before start of statement", tsv.before(st)); 797 assertFalse("CURRENT TIME after end of statement", tsv.after(et)); 798 } 799 800 return tsv; 801 } 802 803 813 private Time getTime19700101(int hour, int min, int sec) 814 { 815 cal.clear(); 816 cal.set(1970, Calendar.JANUARY, 1); 817 cal.set(Calendar.MILLISECOND, 0); 818 819 cal.set(Calendar.HOUR_OF_DAY, hour); 820 cal.set(Calendar.MINUTE, min); 821 cal.set(Calendar.SECOND, sec); 822 823 Time to = new Time (cal.getTime().getTime()); 824 assertTime1970(to); 825 return to; 826 } 827 828 838 private Time getTime19700101(long t, Calendar cal) 839 { 840 cal.clear(); 841 cal.setTime(new Date (t)); 844 cal.set(1970, Calendar.JANUARY, 1); 845 cal.set(Calendar.MILLISECOND, 0); 846 847 Time to = new Time (cal.getTime().getTime()); 848 assertTime1970(to); 849 return to; 850 } 851 852 862 private Time getTime19700101(String s, Calendar cal) 863 { 864 cal.clear(); 865 cal.setTime(Time.valueOf(s)); 868 cal.set(1970, Calendar.JANUARY, 1); 869 cal.set(Calendar.MILLISECOND, 0); 870 871 Time to = new Time (cal.getTime().getTime()); 872 assertTime1970(to); 873 return to; 874 } 875 876 883 private void assertTime1970(Time t) { 884 885 893 cal.clear(); 894 cal.setTime(t); 895 896 assertEquals(1970, cal.get(Calendar.YEAR)); 897 assertEquals(Calendar.JANUARY, cal.get(Calendar.MONTH)); 898 assertEquals(1, cal.get(Calendar.DATE)); 899 } 900 901 907 private void assertTimeEqual(java.util.Date tv1, java.util.Date tv2) 908 { 909 cal.clear(); 910 cal.setTime(tv1); 911 912 int hour = cal.get(Calendar.HOUR_OF_DAY); 913 int min = cal.get(Calendar.MINUTE); 914 int sec = cal.get(Calendar.SECOND); 915 int ms = cal.get(Calendar.MILLISECOND); 916 917 cal.clear(); 919 cal.setTime(tv2); 920 assertEquals(hour, cal.get(Calendar.HOUR_OF_DAY)); 921 assertEquals(min, cal.get(Calendar.MINUTE)); 922 assertEquals(sec, cal.get(Calendar.SECOND)); 923 assertEquals(ms, cal.get(Calendar.MILLISECOND)); 924 } 925 926 931 private boolean isDateEqual(long d, Timestamp tsv) 932 { 933 cal.clear(); 934 cal.setTime(new java.util.Date (d)); 935 int day = cal.get(Calendar.DAY_OF_MONTH); 936 int month = cal.get(Calendar.MONTH); 937 int year = cal.get(Calendar.YEAR); 938 939 cal.clear(); 940 cal.setTime(tsv); 941 942 return day == cal.get(Calendar.DAY_OF_MONTH) 943 && month == cal.get(Calendar.MONTH) 944 && year == cal.get(Calendar.YEAR); 945 } 946 } 947 | Popular Tags |