1 20 package org.apache.derbyTesting.functionTests.tests.jdbcapi; 21 import java.sql.DatabaseMetaData ; 22 import java.sql.ResultSet ; 23 import java.sql.ResultSetMetaData ; 24 import java.sql.SQLException ; 25 import java.sql.PreparedStatement ; 26 import java.sql.Statement ; 27 import java.sql.Types ; 28 import java.util.ArrayList ; 29 import java.util.HashMap ; 30 import java.util.HashSet ; 31 import java.util.Iterator ; 32 import java.util.List ; 33 import java.util.Map ; 34 import java.util.Random ; 35 import java.util.Set ; 36 import junit.extensions.TestSetup; 37 import junit.framework.Test; 38 import junit.framework.TestSuite; 39 40 47 public class SURQueryMixTest extends SURBaseTest 48 { 49 57 public SURQueryMixTest(final String model, final String query, 58 final String cursorName, final boolean positioned) 59 { 60 super("SURQueryMixTest{Model=" + model + ",Query=" +query + ",Cursor=" 61 + cursorName + ",Positioned=" + positioned + "}"); 62 this.query = query; 63 this.cursorName = cursorName; 64 this.positioned = positioned; 65 this.checkRowUpdated = false; 66 this.checkRowDeleted = false; 67 } 68 69 72 public void runTest() 73 throws SQLException 74 { 75 println(query); 76 DatabaseMetaData dbMeta = getConnection().getMetaData(); 77 78 if (dbMeta.ownDeletesAreVisible(ResultSet.TYPE_SCROLL_INSENSITIVE)) { 79 checkRowDeleted = true; 80 } 81 82 Statement s = createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, 83 ResultSet.CONCUR_UPDATABLE); 84 85 s.setCursorName(cursorName); 86 ResultSet rs = s.executeQuery(query); 87 88 checkRowUpdated = dbMeta.ownUpdatesAreVisible(rs.getType()); 89 checkRowDeleted = dbMeta.ownDeletesAreVisible(rs.getType()); 90 91 Map rows = createRowMap(rs); 93 94 final Set updatedRows = new HashSet (); 96 97 final Set deletedRows = new HashSet (); 99 100 testNavigation(rs, rows, updatedRows, deletedRows); 102 103 if (rs.getConcurrency()==ResultSet.CONCUR_UPDATABLE) { 111 112 updateRandomSampleOfNRecords(rs, rows, updatedRows, 2); 114 testNavigation(rs, rows, updatedRows, deletedRows); 115 116 updateRandomSampleOfNRecords(rs, rows, updatedRows, 5); 118 testNavigation(rs, rows, updatedRows, deletedRows); 119 120 updateRandomSampleOfNRecords(rs, rows, updatedRows, 10); 122 testNavigation(rs, rows, updatedRows, deletedRows); 123 124 deleteRandomSampleOfNRecords(rs, rows, deletedRows, 2); 126 testNavigation(rs, rows, updatedRows, deletedRows); 127 128 deleteRandomSampleOfNRecords(rs, rows, deletedRows, 5); 130 testNavigation(rs, rows, updatedRows, deletedRows); 131 132 deleteRandomSampleOfNRecords(rs, rows, deletedRows, 10); 134 testNavigation(rs, rows, updatedRows, deletedRows); 135 } else { 136 assertTrue("ResultSet concurrency downgraded to CONCUR_READ_ONLY", 137 false); 138 } 139 140 rs.close(); 141 s.close(); 142 } 143 144 150 private Map createRowMap(final ResultSet rs) 151 throws SQLException 152 { 153 final Map rows = new HashMap (); 154 rs.beforeFirst(); 155 assertTrue("Unexpected return from isBeforeFirst()", 156 rs.isBeforeFirst()); 157 158 int i = 0; 159 int sum = 0; 160 int expectedSum = 0; 161 boolean checkSum = true; 162 while (rs.next()) { 163 expectedSum += i; 164 i++; 165 String row = getRowString(rs); 166 println(row); 167 rows.put(new Integer (i), row); 168 sum += rs.getInt(1); 169 if (rs.getInt(1) < 0) { 170 checkSum = false; 171 } 172 } 173 if (i<SURDataModelSetup.recordCount) { 174 checkSum = false; 175 } 176 177 assertTrue("Unexpected return from isAfterLast()", rs.isAfterLast()); 178 179 if (checkSum) { 180 assertEquals("Sum for column 1 is not correct", expectedSum, sum); 181 } 182 183 return rows; 184 } 185 186 192 private List createRandomSample(final Map rows, int k) { 193 Random r = new Random (); 194 ArrayList sampledKeys = new ArrayList (); 195 int n = 0; 196 for (Iterator i = rows.keySet().iterator(); i.hasNext();) { 197 Object key = i.next(); 198 n++; 199 if (n<=k) { 200 sampledKeys.add(key); 201 } else { 202 double d = r.nextDouble(); 204 double p = (double) k / (double) n; 206 if (d<p) { 207 int keyToReplace = Math.abs(r.nextInt())%k; 209 sampledKeys.set(keyToReplace, key); 210 } 211 } 212 } 213 return sampledKeys; 214 } 215 216 223 private void deleteRandomSampleOfNRecords(final ResultSet rs, 224 final Map rows, 225 final Set deletedRows, 226 final int k) 227 throws SQLException 228 { 229 List sampledKeys = createRandomSample(rows, k); 230 println("Sampled keys:" + sampledKeys); 231 ResultSetMetaData meta = rs.getMetaData(); 232 for (Iterator i = sampledKeys.iterator(); i.hasNext();) { 233 Integer key = (Integer ) i.next(); 234 rs.absolute(key.intValue()); 235 if (rs.rowDeleted()) continue; if (positioned) { 237 createStatement().executeUpdate 238 ("DELETE FROM T1 WHERE CURRENT OF \"" + cursorName + 239 "\""); 240 } else { 241 rs.deleteRow(); 242 } 243 rs.relative(0); 244 println("Deleted row " + key); 245 rows.put(key, getRowString(rs)); 247 248 deletedRows.add(key); 250 } 251 } 252 253 260 private void updateRandomSampleOfNRecords(final ResultSet rs, 261 final Map rows, 262 final Set updatedRows, 263 final int k) 264 throws SQLException 265 { 266 List sampledKeys = createRandomSample(rows, k); 267 println("Sampled keys:" + sampledKeys); 268 ResultSetMetaData meta = rs.getMetaData(); 269 for (Iterator i = sampledKeys.iterator(); i.hasNext();) { 270 Integer key = (Integer ) i.next(); 271 rs.absolute(key.intValue()); 272 273 if (positioned) { 274 updatePositioned(rs, meta); 275 rs.relative(0); } else { 278 updateRow(rs, meta); 279 } 280 rows.put(key, getRowString(rs)); 282 283 updatedRows.add(key); 285 } 286 } 287 288 293 private void updateRow(final ResultSet rs, final ResultSetMetaData meta) 294 throws SQLException 295 { 296 for (int column = 1; column<=meta.getColumnCount(); column++) { 297 if (meta.getColumnType(column)==Types.INTEGER) { 298 rs.updateInt(column, -rs.getInt(column)); 300 } else { 301 rs.updateString(column, "UPDATED_" + rs.getString(column)); 302 } 303 } 304 rs.updateRow(); 305 } 306 307 312 private void updatePositioned(final ResultSet rs, 313 final ResultSetMetaData meta) 314 throws SQLException 315 { 316 StringBuffer sb = new StringBuffer (); 317 sb.append("UPDATE T1 SET "); 318 for (int column = 1; column<=meta.getColumnCount(); column++) { 319 sb.append(meta.getColumnName(column)); 320 sb.append("=?"); 321 if (column<meta.getColumnCount()) { 322 sb.append(","); 323 } 324 } 325 sb.append(" WHERE CURRENT OF \""); 326 sb.append(cursorName); 327 sb.append("\""); 328 println(sb.toString()); 329 PreparedStatement ps = prepareStatement(sb.toString()); 330 331 for (int column = 1; column<=meta.getColumnCount(); column++) { 332 if (meta.getColumnType(column)==Types.INTEGER) { 333 ps.setInt(column, -rs.getInt(column)); 335 } else { 336 ps.setString(column, "UPDATED_" + rs.getString(column)); 337 } 338 } 339 assertEquals("Expected one row to be updated", 1, ps.executeUpdate()); 340 } 341 342 343 354 private void testNavigation(final ResultSet rs, final Map rows, 355 final Set updatedRows, final Set deletedRows) 356 throws SQLException 357 { 358 rs.afterLast(); 359 { 360 int i = rows.size(); 361 while (rs.previous()) { 362 String rowString = getRowString(rs); 363 assertEquals("Navigating with rs.previous(). The row is " + 364 "different compared to the value when navigating " + 365 "forward.", rows.get(new Integer (i)), rowString); 366 367 368 if (checkRowUpdated && updatedRows.contains(new Integer (i))) { 369 assertTrue("Expected rs.rowUpdated() to return true on " + 370 "updated row " + rowString, rs.rowUpdated()); 371 } 372 if (checkRowDeleted && deletedRows.contains(new Integer (i))) { 373 assertTrue("Expected rs.rowDeleted() to return true on " + 374 "deleted row " + rowString, rs.rowDeleted()); 375 } 376 i--; 377 } 378 } 379 for (int i = 1; i <= rows.size(); i++) { 381 assertTrue("Unexpected return from absolute()", rs.absolute(i)); 382 String rowString = getRowString(rs); 383 assertEquals("Navigating with rs.absolute(). The row is " + 384 "different compared to the value" + 385 " when navigating forward.", 386 rows.get(new Integer (i)), 387 rowString); 388 if (checkRowUpdated && updatedRows.contains(new Integer (i))) { 389 assertTrue("Expected rs.rowUpdated() to return true on " + 390 "updated row " + rowString, rs.rowUpdated()); 391 } 392 if (checkRowDeleted && deletedRows.contains(new Integer (i))) { 393 assertTrue("Expected rs.rowDeleted() to return true on " + 394 "deleted row " + rowString, rs.rowDeleted()); 395 } 396 } 397 assertFalse("Unexpected return from absolute()", rs.absolute(0)); 398 assertTrue("Unexpected return from isBeforeFirst()", 399 rs.isBeforeFirst()); 400 assertFalse("Unexpected return from absolute()", 401 rs.absolute(rows.size() + 1)); 402 assertTrue("Unexpected return from isAfterLast()", rs.isAfterLast()); 403 assertTrue("Unexpected return from absolute()", rs.absolute(-1)); 404 assertTrue("Unexpected return from isLast()", rs.isLast()); 405 assertTrue("Unexpected return from absolute()", rs.absolute(1)); 406 assertTrue("Unexpected return from isFirst()", rs.isFirst()); 407 408 { 410 rs.beforeFirst(); 411 assertTrue("Unexptected return from isBeforeFirst()", 412 rs.isBeforeFirst()); 413 414 int relativePos = rows.size(); 415 assertTrue("Unexpected return from relative()", 416 rs.relative(relativePos)); 417 418 assertTrue("Unexptected return from isLast()", rs.isLast()); 420 assertEquals("Navigating with rs.relative(+). " + 421 "A tuple was different compared to the value" + 422 " when navigating forward.", 423 rows.get(new Integer (relativePos)), 424 getRowString(rs)); 425 426 assertTrue("Unexpected return from relative()", 427 rs.relative((-relativePos + 1))); 428 429 assertTrue("Unexptected return from isFirst()", rs.isFirst()); 431 432 assertEquals("Navigating with rs.relative(-). " + 433 "A tuple was different compared to the value" + 434 " when navigating forward.", 435 rows.get(new Integer (1)), 436 getRowString(rs)); 437 438 } 439 rs.afterLast(); 441 assertTrue("Unexpected return from isAfterLast()", rs.isAfterLast()); 442 assertTrue("Unexpected return from previous()", rs.previous()); 443 assertTrue("Unexpected return from isLast()", rs.isLast()); 444 assertFalse("Unexpected return from next()", rs.next()); 445 assertTrue("Unexpected return from isAfterLast()", rs.isAfterLast()); 446 rs.last(); 447 assertTrue("Unexpected return from isLast()", rs.isLast()); 448 assertFalse("Unexpected return from next()", rs.next()); 449 assertTrue("Unexpected return from isAfterLast()", rs.isAfterLast()); 450 451 452 rs.beforeFirst(); 454 assertTrue("Unexpected return from isBeforeFirst()", 455 rs.isBeforeFirst()); 456 assertTrue("Unexpected return from next()", rs.next()); 457 assertTrue("Unexpected return from isFirst", rs.isFirst()); 458 assertFalse("Unexpected return from previous()", rs.previous()); 459 assertTrue("Unexpected return from isBeforeFirst()", 460 rs.isBeforeFirst()); 461 462 rs.first(); 463 assertTrue("Unexpected return from isFirst", rs.isFirst()); 464 assertFalse("Unexpected return from previous()", rs.previous()); 465 assertTrue("Unexpected return from isBeforeFirst()", 466 rs.isBeforeFirst()); 467 } 468 469 473 private String getRowString(final ResultSet rs) 474 throws SQLException 475 { 476 int numberOfColumns = rs.getMetaData().getColumnCount(); 477 StringBuffer sb = new StringBuffer (); 478 if (rs.rowDeleted()) return ""; 479 for (int i = 1; i <= numberOfColumns; i++) { 480 sb.append(rs.getString(i)); 481 if (i < numberOfColumns) { 482 sb.append(','); 483 } 484 } 485 return sb.toString(); 486 } 487 488 private final String query; 489 private final String cursorName; 490 private final boolean positioned; 491 private boolean checkRowUpdated; 492 private boolean checkRowDeleted; 493 494 private final static String [] selectConditions = new String [] { 495 "WHERE c like 'T%'", 496 " ", 497 "WHERE b > 5", 498 "WHERE id >= a", 499 "WHERE id > 1 and id < 900", 500 "WHERE id = 1", 501 "WHERE id in (1,3,4,600,900,955,966,977,978)", 502 "WHERE a in (1,3,4,600,9200,955,966,977,978)", 503 "WHERE a>2 and a<9000" 504 }; 505 506 private final static String [] projectConditions = new String [] { 507 "id,c,a,b", 508 "id,c", 509 "a,b", 510 "*", 511 "id,a,b,c", 512 "id,a", 513 "a,b,c", 514 "a,c" 515 }; 516 517 private static TestSuite createTestCases(final String modelName) { 518 TestSuite suite = new TestSuite(); 519 for (int doPos = 0; doPos<2; doPos++) { 520 boolean positioned = doPos>0; 522 for (int i = 0; i < selectConditions.length; i++) { 523 for (int j = 0; j < projectConditions.length; j++) { 524 final String cursorName = "cursor_" + i + "_" + j; 525 526 final String stmtString = "SELECT " + projectConditions[j] + 527 " FROM T1 " + selectConditions[i]; 528 suite.addTest(new SURQueryMixTest(modelName, stmtString, cursorName, 529 positioned)); 530 } 531 } 532 } 533 return suite; 534 } 535 536 539 public static Test suite() 540 { 541 TestSuite mainSuite = new TestSuite(); 542 543 if (usingDerbyNet()) 545 return mainSuite; 546 547 548 for (Iterator i = SURDataModelSetup.SURDataModel.values().iterator(); 550 i.hasNext();) { 551 552 SURDataModelSetup.SURDataModel model = 553 (SURDataModelSetup.SURDataModel) i.next(); 554 555 TestSuite suite = createTestCases(model.toString()); 556 TestSetup decorator = new SURDataModelSetup(suite, model); 557 mainSuite.addTest(decorator); 558 } 559 return mainSuite; 560 } 561 562 protected void tearDown() throws Exception { 563 super.tearDown(); 564 con = null; 565 } 566 567 568 } 569 | Popular Tags |