1 8 9 package com.sleepycat.je.test; 10 11 import java.util.Arrays ; 12 import java.util.List ; 13 14 import junit.framework.Test; 15 16 import com.sleepycat.je.Cursor; 17 import com.sleepycat.je.Database; 18 import com.sleepycat.je.DatabaseConfig; 19 import com.sleepycat.je.DatabaseEntry; 20 import com.sleepycat.je.DatabaseException; 21 import com.sleepycat.je.EnvironmentConfig; 22 import com.sleepycat.je.LockMode; 23 import com.sleepycat.je.OperationStatus; 24 import com.sleepycat.je.SecondaryConfig; 25 import com.sleepycat.je.SecondaryCursor; 26 import com.sleepycat.je.SecondaryDatabase; 27 import com.sleepycat.je.SecondaryKeyCreator; 28 import com.sleepycat.je.Transaction; 29 import com.sleepycat.je.config.EnvironmentParams; 30 import com.sleepycat.je.util.TestUtils; 31 32 public class SecondaryTest extends MultiKeyTxnTestCase { 33 34 private static final int NUM_RECS = 5; 35 private static final int KEY_OFFSET = 100; 36 37 private static EnvironmentConfig envConfig = TestUtils.initEnvConfig(); 38 static { 39 envConfig.setConfigParam(EnvironmentParams.ENV_CHECK_LEAKS.getName(), 40 "false"); 41 envConfig.setConfigParam(EnvironmentParams.NODE_MAX.getName(), 42 "6"); 43 envConfig.setTxnNoSync(Boolean.getBoolean(TestUtils.NO_SYNC)); 44 envConfig.setAllowCreate(true); 45 } 46 47 public static Test suite() { 48 49 return multiKeyTxnTestSuite(SecondaryTest.class, envConfig, null); 50 } 51 52 public void testPutAndDelete() 53 throws DatabaseException { 54 55 SecondaryDatabase secDb = initDb(); 56 Database priDb = secDb.getPrimaryDatabase(); 57 58 DatabaseEntry data = new DatabaseEntry(); 59 DatabaseEntry key = new DatabaseEntry(); 60 OperationStatus status; 61 Transaction txn = txnBegin(); 62 63 64 status = priDb.put(txn, entry(1), entry(2)); 65 assertSame(OperationStatus.SUCCESS, status); 66 status = secDb.get(txn, entry(102), key, data, LockMode.DEFAULT); 67 assertSame(OperationStatus.SUCCESS, status); 68 assertDataEquals(entry(1), key); 69 assertDataEquals(entry(2), data); 70 71 72 status = priDb.putNoOverwrite(txn, entry(1), entry(1)); 73 assertSame(OperationStatus.KEYEXIST, status); 74 status = secDb.get(txn, entry(102), key, data, LockMode.DEFAULT); 75 assertSame(OperationStatus.SUCCESS, status); 76 assertDataEquals(entry(1), key); 77 assertDataEquals(entry(2), data); 78 79 80 status = priDb.put(txn, entry(1), entry(3)); 81 assertSame(OperationStatus.SUCCESS, status); 82 status = secDb.get(txn, entry(102), key, data, LockMode.DEFAULT); 83 assertSame(OperationStatus.NOTFOUND, status); 84 status = secDb.get(txn, entry(103), key, data, LockMode.DEFAULT); 85 assertSame(OperationStatus.SUCCESS, status); 86 assertDataEquals(entry(1), key); 87 assertDataEquals(entry(3), data); 88 89 90 status = priDb.delete(txn, entry(1)); 91 assertSame(OperationStatus.SUCCESS, status); 92 status = priDb.delete(txn, entry(1)); 93 assertSame(OperationStatus.NOTFOUND, status); 94 status = secDb.get(txn, entry(103), key, data, LockMode.DEFAULT); 95 assertSame(OperationStatus.NOTFOUND, status); 96 97 98 status = priDb.put(txn, entry(1), entry(1)); 99 assertSame(OperationStatus.SUCCESS, status); 100 status = priDb.put(txn, entry(2), entry(1)); 101 assertSame(OperationStatus.SUCCESS, status); 102 status = secDb.get(txn, entry(101), key, data, LockMode.DEFAULT); 103 assertSame(OperationStatus.SUCCESS, status); 104 assertDataEquals(entry(1), key); 105 assertDataEquals(entry(1), data); 106 status = secDb.delete(txn, entry(101)); 107 assertSame(OperationStatus.SUCCESS, status); 108 status = secDb.delete(txn, entry(101)); 109 assertSame(OperationStatus.NOTFOUND, status); 110 status = secDb.get(txn, entry(101), key, data, LockMode.DEFAULT); 111 assertSame(OperationStatus.NOTFOUND, status); 112 status = priDb.get(txn, entry(1), data, LockMode.DEFAULT); 113 assertSame(OperationStatus.NOTFOUND, status); 114 status = priDb.get(txn, entry(2), data, LockMode.DEFAULT); 115 assertSame(OperationStatus.NOTFOUND, status); 116 117 121 122 123 124 125 txnCommit(txn); 126 txn = txnBeginCursor(); 127 128 Cursor priCursor = null; 129 SecondaryCursor secCursor = null; 130 try { 131 priCursor = priDb.openCursor(txn, null); 132 secCursor = secDb.openSecondaryCursor(txn, null); 133 134 135 status = priCursor.putNoOverwrite(entry(1), entry(2)); 136 assertSame(OperationStatus.SUCCESS, status); 137 status = secCursor.getSearchKey(entry(102), key, data, 138 LockMode.DEFAULT); 139 assertSame(OperationStatus.SUCCESS, status); 140 assertDataEquals(entry(1), key); 141 assertDataEquals(entry(2), data); 142 143 144 status = priCursor.putCurrent(entry(3)); 145 assertSame(OperationStatus.SUCCESS, status); 146 status = secCursor.getSearchKey(entry(102), key, data, 147 LockMode.DEFAULT); 148 assertSame(OperationStatus.NOTFOUND, status); 149 status = secCursor.getSearchKey(entry(103), key, data, 150 LockMode.DEFAULT); 151 assertSame(OperationStatus.SUCCESS, status); 152 assertDataEquals(entry(1), key); 153 assertDataEquals(entry(3), data); 154 155 156 status = priCursor.delete(); 157 assertSame(OperationStatus.SUCCESS, status); 158 status = priCursor.delete(); 159 assertSame(OperationStatus.KEYEMPTY, status); 160 status = secCursor.getSearchKey(entry(103), key, data, 161 LockMode.DEFAULT); 162 assertSame(OperationStatus.NOTFOUND, status); 163 status = priCursor.getSearchKey(entry(1), data, 164 LockMode.DEFAULT); 165 assertSame(OperationStatus.NOTFOUND, status); 166 167 168 status = priCursor.put(entry(1), entry(4)); 169 assertSame(OperationStatus.SUCCESS, status); 170 status = secCursor.getSearchKey(entry(104), key, data, 171 LockMode.DEFAULT); 172 assertSame(OperationStatus.SUCCESS, status); 173 assertDataEquals(entry(1), key); 174 assertDataEquals(entry(4), data); 175 176 177 status = secCursor.delete(); 178 assertSame(OperationStatus.SUCCESS, status); 179 status = secCursor.delete(); 180 assertSame(OperationStatus.KEYEMPTY, status); 181 status = secCursor.getCurrent(new DatabaseEntry(), key, data, 182 LockMode.DEFAULT); 183 assertSame(OperationStatus.KEYEMPTY, status); 184 status = secCursor.getSearchKey(entry(104), key, data, 185 LockMode.DEFAULT); 186 assertSame(OperationStatus.NOTFOUND, status); 187 status = priCursor.getSearchKey(entry(1), data, 188 LockMode.DEFAULT); 189 assertSame(OperationStatus.NOTFOUND, status); 190 191 195 196 197 } finally { 198 if (secCursor != null) { 199 secCursor.close(); 200 } 201 if (priCursor != null) { 202 priCursor.close(); 203 } 204 } 205 206 txnCommit(txn); 207 secDb.close(); 208 priDb.close(); 209 } 210 211 public void testGet() 212 throws DatabaseException { 213 214 SecondaryDatabase secDb = initDb(); 215 Database priDb = secDb.getPrimaryDatabase(); 216 217 DatabaseEntry data = new DatabaseEntry(); 218 DatabaseEntry key = new DatabaseEntry(); 219 DatabaseEntry secKey = new DatabaseEntry(); 220 OperationStatus status; 221 Transaction txn = txnBegin(); 222 223 227 228 229 for (int i = 0; i < NUM_RECS; i += 1) { 230 status = priDb.put(txn, entry(i), entry(i)); 231 assertSame(OperationStatus.SUCCESS, status); 232 } 233 234 235 for (int i = 0; i < NUM_RECS; i += 1) { 236 237 data.setData(null); 238 status = secDb.get(txn, entry(i + KEY_OFFSET), key, 239 data, LockMode.DEFAULT); 240 assertSame(OperationStatus.SUCCESS, status); 241 assertDataEquals(entry(i), key); 242 assertDataEquals(entry(i), data); 243 } 244 data.setData(null); 245 status = secDb.get(txn, entry(NUM_RECS + KEY_OFFSET), key, 246 data, LockMode.DEFAULT); 247 assertSame(OperationStatus.NOTFOUND, status); 248 249 250 for (int i = 0; i < NUM_RECS; i += 1) { 251 data.setData(null); 252 status = secDb.getSearchBoth(txn, entry(i + KEY_OFFSET), entry(i), 253 data, LockMode.DEFAULT); 254 assertSame(OperationStatus.SUCCESS, status); 255 assertDataEquals(entry(i), data); 256 } 257 data.setData(null); 258 status = secDb.getSearchBoth(txn, entry(NUM_RECS + KEY_OFFSET), 259 entry(NUM_RECS), data, LockMode.DEFAULT); 260 assertSame(OperationStatus.NOTFOUND, status); 261 262 263 txnCommit(txn); 264 txn = txnBeginCursor(); 265 266 SecondaryCursor cursor = secDb.openSecondaryCursor(txn, null); 267 try { 268 269 secKey.setData(null); 270 key.setData(null); 271 data.setData(null); 272 status = cursor.getFirst(secKey, key, data, LockMode.DEFAULT); 273 for (int i = 0; i < NUM_RECS; i += 1) { 274 assertSame(OperationStatus.SUCCESS, status); 275 assertDataEquals(entry(i + KEY_OFFSET), secKey); 276 assertDataEquals(entry(i), key); 277 assertDataEquals(entry(i), data); 278 secKey.setData(null); 279 key.setData(null); 280 data.setData(null); 281 status = cursor.getNext(secKey, key, data, LockMode.DEFAULT); 282 } 283 assertSame(OperationStatus.NOTFOUND, status); 284 285 286 secKey.setData(null); 287 key.setData(null); 288 data.setData(null); 289 status = cursor.getCurrent(secKey, key, data, LockMode.DEFAULT); 290 assertSame(OperationStatus.SUCCESS, status); 291 assertDataEquals(entry(NUM_RECS - 1 + KEY_OFFSET), secKey); 292 assertDataEquals(entry(NUM_RECS - 1), key); 293 assertDataEquals(entry(NUM_RECS - 1), data); 294 295 296 secKey.setData(null); 297 key.setData(null); 298 data.setData(null); 299 status = cursor.getLast(secKey, key, data, LockMode.DEFAULT); 300 for (int i = NUM_RECS - 1; i >= 0; i -= 1) { 301 assertSame(OperationStatus.SUCCESS, status); 302 assertDataEquals(entry(i + KEY_OFFSET), secKey); 303 assertDataEquals(entry(i), key); 304 assertDataEquals(entry(i), data); 305 secKey.setData(null); 306 key.setData(null); 307 data.setData(null); 308 status = cursor.getPrev(secKey, key, data, LockMode.DEFAULT); 309 } 310 assertSame(OperationStatus.NOTFOUND, status); 311 312 313 secKey.setData(null); 314 key.setData(null); 315 data.setData(null); 316 status = cursor.getCurrent(secKey, key, data, LockMode.DEFAULT); 317 assertSame(OperationStatus.SUCCESS, status); 318 assertDataEquals(entry(0 + KEY_OFFSET), secKey); 319 assertDataEquals(entry(0), key); 320 assertDataEquals(entry(0), data); 321 322 323 key.setData(null); 324 data.setData(null); 325 status = cursor.getSearchKey(entry(KEY_OFFSET - 1), key, 326 data, LockMode.DEFAULT); 327 assertSame(OperationStatus.NOTFOUND, status); 328 for (int i = 0; i < NUM_RECS; i += 1) { 329 key.setData(null); 330 data.setData(null); 331 status = cursor.getSearchKey(entry(i + KEY_OFFSET), key, 332 data, LockMode.DEFAULT); 333 assertSame(OperationStatus.SUCCESS, status); 334 assertDataEquals(entry(i), key); 335 assertDataEquals(entry(i), data); 336 } 337 key.setData(null); 338 data.setData(null); 339 status = cursor.getSearchKey(entry(NUM_RECS + KEY_OFFSET), key, 340 data, LockMode.DEFAULT); 341 assertSame(OperationStatus.NOTFOUND, status); 342 343 344 data.setData(null); 345 status = cursor.getSearchKey(entry(KEY_OFFSET - 1), entry(0), 346 data, LockMode.DEFAULT); 347 assertSame(OperationStatus.NOTFOUND, status); 348 for (int i = 0; i < NUM_RECS; i += 1) { 349 data.setData(null); 350 status = cursor.getSearchBoth(entry(i + KEY_OFFSET), entry(i), 351 data, LockMode.DEFAULT); 352 assertSame(OperationStatus.SUCCESS, status); 353 assertDataEquals(entry(i), data); 354 } 355 data.setData(null); 356 status = cursor.getSearchBoth(entry(NUM_RECS + KEY_OFFSET), 357 entry(NUM_RECS), data, 358 LockMode.DEFAULT); 359 assertSame(OperationStatus.NOTFOUND, status); 360 361 362 key.setData(null); 363 data.setData(null); 364 status = cursor.getSearchKeyRange(entry(KEY_OFFSET - 1), key, 365 data, LockMode.DEFAULT); 366 assertSame(OperationStatus.SUCCESS, status); 367 assertDataEquals(entry(0), key); 368 assertDataEquals(entry(0), data); 369 for (int i = 0; i < NUM_RECS; i += 1) { 370 key.setData(null); 371 data.setData(null); 372 status = cursor.getSearchKeyRange(entry(i + KEY_OFFSET), key, 373 data, LockMode.DEFAULT); 374 assertSame(OperationStatus.SUCCESS, status); 375 assertDataEquals(entry(i), key); 376 assertDataEquals(entry(i), data); 377 } 378 key.setData(null); 379 data.setData(null); 380 status = cursor.getSearchKeyRange(entry(NUM_RECS + KEY_OFFSET), 381 key, data, LockMode.DEFAULT); 382 assertSame(OperationStatus.NOTFOUND, status); 383 384 385 data.setData(null); 386 status = cursor.getSearchBothRange(entry(1 + KEY_OFFSET), entry(1), 387 data, LockMode.DEFAULT); 388 assertSame(OperationStatus.SUCCESS, status); 389 assertDataEquals(entry(1), data); 390 for (int i = 0; i < NUM_RECS; i += 1) { 391 data.setData(null); 392 status = cursor.getSearchBothRange(entry(i + KEY_OFFSET), 393 entry(i), data, 394 LockMode.DEFAULT); 395 assertSame(OperationStatus.SUCCESS, status); 396 assertDataEquals(entry(i), data); 397 } 398 data.setData(null); 399 status = cursor.getSearchBothRange(entry(NUM_RECS + KEY_OFFSET), 400 entry(NUM_RECS), data, 401 LockMode.DEFAULT); 402 assertSame(OperationStatus.NOTFOUND, status); 403 404 405 Cursor priCursor = priDb.openCursor(txn, null); 406 try { 407 for (int i = 0; i < NUM_RECS; i += 1) { 408 status = priCursor.put(entry(i + KEY_OFFSET), entry(i)); 409 assertSame(OperationStatus.SUCCESS, status); 410 } 411 } finally { 412 priCursor.close(); 413 } 414 415 416 secKey.setData(null); 417 key.setData(null); 418 data.setData(null); 419 status = cursor.getFirst(secKey, key, data, LockMode.DEFAULT); 420 for (int i = 0; i < NUM_RECS; i += 1) { 421 assertSame(OperationStatus.SUCCESS, status); 422 assertDataEquals(entry(i + KEY_OFFSET), secKey); 423 assertDataEquals(entry(i), key); 424 assertDataEquals(entry(i), data); 425 secKey.setData(null); 426 key.setData(null); 427 data.setData(null); 428 status = cursor.getNextDup(secKey, key, data, 429 LockMode.DEFAULT); 430 assertSame(OperationStatus.SUCCESS, status); 431 assertDataEquals(entry(i + KEY_OFFSET), secKey); 432 assertDataEquals(entry(i + KEY_OFFSET), key); 433 assertDataEquals(entry(i), data); 434 secKey.setData(null); 435 key.setData(null); 436 data.setData(null); 437 status = cursor.getNextDup(secKey, key, data, 438 LockMode.DEFAULT); 439 assertSame(OperationStatus.NOTFOUND, status); 440 secKey.setData(null); 441 key.setData(null); 442 data.setData(null); 443 status = cursor.getNext(secKey, key, data, LockMode.DEFAULT); 444 } 445 assertSame(OperationStatus.NOTFOUND, status); 446 447 448 secKey.setData(null); 449 key.setData(null); 450 data.setData(null); 451 status = cursor.getFirst(secKey, key, data, LockMode.DEFAULT); 452 for (int i = 0; i < NUM_RECS; i += 1) { 453 assertSame(OperationStatus.SUCCESS, status); 454 assertDataEquals(entry(i + KEY_OFFSET), secKey); 455 assertDataEquals(entry(i), key); 456 assertDataEquals(entry(i), data); 457 secKey.setData(null); 458 key.setData(null); 459 data.setData(null); 460 status = cursor.getNextNoDup(secKey, key, data, 461 LockMode.DEFAULT); 462 } 463 assertSame(OperationStatus.NOTFOUND, status); 464 465 466 secKey.setData(null); 467 key.setData(null); 468 data.setData(null); 469 status = cursor.getLast(secKey, key, data, LockMode.DEFAULT); 470 for (int i = NUM_RECS - 1; i >= 0; i -= 1) { 471 assertSame(OperationStatus.SUCCESS, status); 472 assertDataEquals(entry(i + KEY_OFFSET), secKey); 473 assertDataEquals(entry(i + KEY_OFFSET), key); 474 assertDataEquals(entry(i), data); 475 secKey.setData(null); 476 key.setData(null); 477 data.setData(null); 478 status = cursor.getPrevDup(secKey, key, data, 479 LockMode.DEFAULT); 480 assertSame(OperationStatus.SUCCESS, status); 481 assertDataEquals(entry(i + KEY_OFFSET), secKey); 482 assertDataEquals(entry(i), key); 483 assertDataEquals(entry(i), data); 484 secKey.setData(null); 485 key.setData(null); 486 data.setData(null); 487 status = cursor.getPrevDup(secKey, key, data, 488 LockMode.DEFAULT); 489 assertSame(OperationStatus.NOTFOUND, status); 490 secKey.setData(null); 491 key.setData(null); 492 data.setData(null); 493 status = cursor.getPrev(secKey, key, data, LockMode.DEFAULT); 494 } 495 assertSame(OperationStatus.NOTFOUND, status); 496 497 498 secKey.setData(null); 499 key.setData(null); 500 data.setData(null); 501 status = cursor.getLast(secKey, key, data, LockMode.DEFAULT); 502 for (int i = NUM_RECS - 1; i >= 0; i -= 1) { 503 assertSame(OperationStatus.SUCCESS, status); 504 assertDataEquals(entry(i + KEY_OFFSET), secKey); 505 assertDataEquals(entry(i + KEY_OFFSET), key); 506 assertDataEquals(entry(i), data); 507 secKey.setData(null); 508 key.setData(null); 509 data.setData(null); 510 status = cursor.getPrevNoDup(secKey, key, data, 511 LockMode.DEFAULT); 512 } 513 assertSame(OperationStatus.NOTFOUND, status); 514 } finally { 515 cursor.close(); 516 } 517 518 txnCommit(txn); 519 secDb.close(); 520 priDb.close(); 521 } 522 523 public void testOpenAndClose() 524 throws DatabaseException { 525 526 Database priDb = openDatabase(false, "testDB", false); 527 528 529 Database secDbDetached = openDatabase(true, "testSecDB", false); 530 SecondaryDatabase secDb = openSecondary(priDb, true, "testSecDB", 531 false, false); 532 Database secDb2Detached = openDatabase(true, "testSecDB2", false); 533 SecondaryDatabase secDb2 = openSecondary(priDb, true, "testSecDB2", 534 false, false); 535 assertEquals(priDb.getSecondaryDatabases(), 536 Arrays.asList(new SecondaryDatabase[] {secDb, secDb2})); 537 538 Transaction txn = txnBegin(); 539 540 541 checkSecondaryUpdate(txn, priDb, 1, secDbDetached, true, 542 secDb2Detached, true); 543 544 545 txnCommit(txn); 546 txn = txnBegin(); 547 548 549 secDb2.close(); 550 assertEquals(priDb.getSecondaryDatabases(), 551 Arrays.asList(new SecondaryDatabase[] {secDb })); 552 553 554 checkSecondaryUpdate(txn, priDb, 2, secDbDetached, true, 555 secDb2Detached, false); 556 557 558 txnCommit(txn); 559 txn = txnBegin(); 560 561 562 secDb.close(); 563 assertEquals(0, priDb.getSecondaryDatabases().size()); 564 565 566 checkSecondaryUpdate(txn, priDb, 3, secDbDetached, false, 567 secDb2Detached, false); 568 569 570 secDb = openSecondary(priDb, true, "testSecDB", false, false); 571 secDb2 = openSecondary(priDb, true, "testSecDB2", false, false); 572 assertEquals(priDb.getSecondaryDatabases(), 573 Arrays.asList(new SecondaryDatabase[] {secDb, secDb2})); 574 575 576 checkSecondaryUpdate(txn, priDb, 4, secDbDetached, true, 577 secDb2Detached, true); 578 579 580 txnCommit(txn); 581 priDb.close(); 582 assertNull(secDb.getPrimaryDatabase()); 583 assertNull(secDb2.getPrimaryDatabase()); 584 secDb2.close(); 585 secDb.close(); 586 587 secDb2Detached.close(); 588 secDbDetached.close(); 589 } 590 591 594 private void checkSecondaryUpdate(Transaction txn, Database priDb, int val, 595 Database secDb, boolean expectSecDbVal, 596 Database secDb2, boolean expectSecDb2Val) 597 throws DatabaseException { 598 599 OperationStatus status; 600 DatabaseEntry data = new DatabaseEntry(); 601 int secVal = KEY_OFFSET + val; 602 603 status = priDb.put(txn, entry(val), entry(val)); 604 assertSame(OperationStatus.SUCCESS, status); 605 606 status = secDb.get(txn, entry(secVal), data, LockMode.DEFAULT); 607 assertSame(expectSecDbVal ? OperationStatus.SUCCESS 608 : OperationStatus.NOTFOUND, status); 609 610 611 status = secDb2.get(txn, entry(secVal), data, LockMode.DEFAULT); 612 assertSame(expectSecDb2Val ? OperationStatus.SUCCESS 613 : OperationStatus.NOTFOUND, status); 614 615 status = priDb.delete(txn, entry(val)); 616 assertSame(OperationStatus.SUCCESS, status); 617 } 618 619 public void testReadOnly() 620 throws DatabaseException { 621 622 SecondaryDatabase secDb = initDb(); 623 Database priDb = secDb.getPrimaryDatabase(); 624 OperationStatus status; 625 Transaction txn = txnBegin(); 626 627 for (int i = 0; i < NUM_RECS; i += 1) { 628 status = priDb.put(txn, entry(i), entry(i)); 629 assertSame(OperationStatus.SUCCESS, status); 630 } 631 632 637 Database readOnlyPriDb = openDatabase(false, "testDB", true); 638 SecondaryDatabase readOnlySecDb = openSecondary(readOnlyPriDb, 639 true, "testSecDB", 640 false, true); 641 assertNull(readOnlySecDb.getSecondaryConfig().getKeyCreator()); 642 verifyRecords(txn, readOnlySecDb, NUM_RECS, true); 643 644 txnCommit(txn); 645 readOnlySecDb.close(); 646 readOnlyPriDb.close(); 647 secDb.close(); 648 priDb.close(); 649 } 650 651 public void testPopulate() 652 throws DatabaseException { 653 654 Database priDb = openDatabase(false, "testDB", false); 655 Transaction txn = txnBegin(); 656 657 658 659 for (int i = 0; i < NUM_RECS; i += 1) { 660 assertSame(OperationStatus.SUCCESS, 661 priDb.put(txn, entry(i), entry(i))); 662 } 663 txnCommit(txn); 664 665 SecondaryDatabase secDb = openSecondary(priDb, true, "testSecDB", 666 true, false); 667 txn = txnBegin(); 668 verifyRecords(txn, secDb, NUM_RECS, true); 669 txnCommit(txn); 670 671 676 Database secDbDetached = openDatabase(true, "testSecDB", false); 677 secDb.close(); 678 txn = txnBegin(); 679 for (int i = 0; i < NUM_RECS; i += 1) { 680 assertSame(OperationStatus.SUCCESS, 681 secDbDetached.delete(txn, entry(i + KEY_OFFSET))); 682 } 683 verifyRecords(txn, secDbDetached, 0, true); 684 txnCommit(txn); 685 secDb = openSecondary(priDb, true, "testSecDB", true, false); 686 txn = txnBegin(); 687 verifyRecords(txn, secDb, NUM_RECS, true); 688 verifyRecords(txn, secDbDetached, NUM_RECS, true); 689 690 txnCommit(txn); 691 secDbDetached.close(); 692 secDb.close(); 693 priDb.close(); 694 } 695 696 public void testTruncate() 697 throws DatabaseException { 698 699 SecondaryDatabase secDb = initDb(); 700 Database priDb = secDb.getPrimaryDatabase(); 701 Transaction txn = txnBegin(); 702 703 for (int i = 0; i < NUM_RECS; i += 1) { 704 priDb.put(txn, entry(i), entry(i)); 705 } 706 verifyRecords(txn, priDb, NUM_RECS, false); 707 verifyRecords(txn, secDb, NUM_RECS, true); 708 txnCommit(txn); 709 secDb.close(); 710 priDb.close(); 711 712 txn = txnBegin(); 713 assertEquals(NUM_RECS, env.truncateDatabase(txn, "testDB", true)); 714 assertEquals(NUM_RECS, env.truncateDatabase(txn, "testSecDB", true)); 715 txnCommit(txn); 716 717 secDb = initDb(); 718 priDb = secDb.getPrimaryDatabase(); 719 720 txn = txnBegin(); 721 verifyRecords(txn, priDb, 0, false); 722 verifyRecords(txn, secDb, 0, true); 723 txnCommit(txn); 724 725 secDb.close(); 726 priDb.close(); 727 } 728 729 private void verifyRecords(Transaction txn, Database db, int numRecs, 730 boolean isSecondary) 731 throws DatabaseException { 732 733 734 Cursor cursor = db.openCursor(txn, null); 735 try { 736 DatabaseEntry data = new DatabaseEntry(); 737 DatabaseEntry key = new DatabaseEntry(); 738 OperationStatus status; 739 int count = 0; 740 status = cursor.getFirst(key, data, LockMode.DEFAULT); 741 while (status == OperationStatus.SUCCESS) { 742 assertDataEquals(entry(count), data); 743 if (isSecondary) { 744 assertDataEquals(entry(count + KEY_OFFSET), key); 745 } else { 746 assertDataEquals(entry(count), key); 747 } 748 count += 1; 749 status = cursor.getNext(key, data, LockMode.DEFAULT); 750 } 751 assertEquals(numRecs, count); 752 } finally { 753 cursor.close(); 754 } 755 } 756 757 public void testUniqueSecondaryKey() 758 throws DatabaseException { 759 760 Database priDb = openDatabase(false, "testDB", false); 761 SecondaryDatabase secDb = openSecondary(priDb, false, "testSecDB", 762 false, false); 763 DatabaseEntry key; 764 DatabaseEntry data; 765 DatabaseEntry pkey = new DatabaseEntry(); 766 Transaction txn; 767 768 769 txn = txnBegin(); 770 key = entry(0); 771 data = entry(0); 772 priDb.put(txn, key, data); 773 txnCommit(txn); 774 assertEquals(OperationStatus.SUCCESS, 775 secDb.get(null, entry(0 + KEY_OFFSET), 776 pkey, data, null)); 777 assertEquals(0, TestUtils.getTestVal(pkey.getData())); 778 assertEquals(0, TestUtils.getTestVal(data.getData())); 779 780 781 txn = txnBegin(); 782 key = entry(1); 783 data = entry(1); 784 priDb.put(txn, key, data); 785 txnCommit(txn); 786 assertEquals(OperationStatus.SUCCESS, 787 secDb.get(null, entry(1 + KEY_OFFSET), 788 pkey, data, null)); 789 assertEquals(1, TestUtils.getTestVal(pkey.getData())); 790 assertEquals(1, TestUtils.getTestVal(data.getData())); 791 792 793 txn = txnBegin(); 794 key = entry(2); 795 data = entry(0); 796 try { 797 priDb.put(txn, key, data); 798 799 fail(); 800 } catch (DatabaseException e) { 801 txnAbort(txn); 802 803 assertEquals(OperationStatus.NOTFOUND, 804 secDb.get(null, key, data, null)); 805 806 assertEquals(OperationStatus.SUCCESS, 807 secDb.get(null, entry(0 + KEY_OFFSET), 808 pkey, data, null)); 809 assertEquals(0, TestUtils.getTestVal(pkey.getData())); 810 assertEquals(0, TestUtils.getTestVal(data.getData())); 811 } 812 813 814 txn = txnBegin(); 815 key = entry(1); 816 data = entry(1); 817 priDb.put(txn, key, data); 818 txnCommit(txn); 819 assertEquals(OperationStatus.SUCCESS, 820 secDb.get(null, entry(1 + KEY_OFFSET), 821 pkey, data, null)); 822 assertEquals(1, TestUtils.getTestVal(pkey.getData())); 823 assertEquals(1, TestUtils.getTestVal(data.getData())); 824 825 826 txn = txnBegin(); 827 key = entry(1); 828 data = entry(3); 829 priDb.put(txn, key, data); 830 txnCommit(txn); 831 assertEquals(OperationStatus.SUCCESS, 832 secDb.get(null, entry(3 + KEY_OFFSET), 833 pkey, data, null)); 834 assertEquals(1, TestUtils.getTestVal(pkey.getData())); 835 assertEquals(3, TestUtils.getTestVal(data.getData())); 836 837 secDb.close(); 838 priDb.close(); 839 } 840 841 844 public void testOperationsNotAllowed() 845 throws DatabaseException { 846 847 SecondaryDatabase secDb = initDb(); 848 Database priDb = secDb.getPrimaryDatabase(); 849 Transaction txn = txnBegin(); 850 851 852 try { 853 env.openSecondaryDatabase(txn, "xxx", priDb, null); 854 fail(); 855 } catch (NullPointerException expected) { } 856 try { 857 env.openSecondaryDatabase(txn, "xxx", priDb, 858 new SecondaryConfig()); 859 fail(); 860 } catch (NullPointerException expected) { } 861 862 863 SecondaryConfig config = new SecondaryConfig(); 864 config.setKeyCreator(new MyKeyCreator()); 865 config.setMultiKeyCreator 866 (new SimpleMultiKeyCreator(new MyKeyCreator())); 867 try { 868 env.openSecondaryDatabase(txn, "xxx", priDb, config); 869 fail(); 870 } catch (IllegalArgumentException expected) { } 871 872 873 874 DatabaseEntry key = entry(1); 875 DatabaseEntry data = entry(2); 876 877 try { 878 secDb.getSearchBoth(txn, key, data, LockMode.DEFAULT); 879 fail(); 880 } catch (UnsupportedOperationException expected) { } 881 882 try { 883 secDb.put(txn, key, data); 884 fail(); 885 } catch (UnsupportedOperationException expected) { } 886 887 try { 888 secDb.putNoOverwrite(txn, key, data); 889 fail(); 890 } catch (UnsupportedOperationException expected) { } 891 892 try { 893 secDb.putNoDupData(txn, key, data); 894 fail(); 895 } catch (UnsupportedOperationException expected) { } 896 897 try { 898 secDb.truncate(txn, true); 899 fail(); 900 } catch (UnsupportedOperationException expected) { } 901 902 try { 903 secDb.join(new Cursor[0], null); 904 fail(); 905 } catch (UnsupportedOperationException expected) { } 906 907 908 909 txnCommit(txn); 910 txn = txnBeginCursor(); 911 912 SecondaryCursor cursor = null; 913 try { 914 cursor = secDb.openSecondaryCursor(txn, null); 915 916 try { 917 cursor.getSearchBoth(key, data, LockMode.DEFAULT); 918 fail(); 919 } catch (UnsupportedOperationException expected) { } 920 921 try { 922 cursor.getSearchBothRange(key, data, LockMode.DEFAULT); 923 fail(); 924 } catch (UnsupportedOperationException expected) { } 925 926 try { 927 cursor.putCurrent(data); 928 fail(); 929 } catch (UnsupportedOperationException expected) { } 930 931 try { 932 cursor.put(key, data); 933 fail(); 934 } catch (UnsupportedOperationException expected) { } 935 936 try { 937 cursor.putNoOverwrite(key, data); 938 fail(); 939 } catch (UnsupportedOperationException expected) { } 940 941 try { 942 cursor.putNoDupData(key, data); 943 fail(); 944 } catch (UnsupportedOperationException expected) { } 945 } finally { 946 if (cursor != null) { 947 cursor.close(); 948 } 949 } 950 951 txnCommit(txn); 952 secDb.close(); 953 priDb.close(); 954 955 956 priDb = openDatabase(true, "testDBWithDups", false); 957 try { 958 openSecondary(priDb, true, "testSecDB", false, false); 959 fail(); 960 } catch (IllegalArgumentException expected) {} 961 962 priDb.close(); 963 964 965 Database pri1 = openDatabase(false, "pri1", false); 966 Database pri2 = openDatabase(false, "pri2", false); 967 Database sec1 = openSecondary(pri1, false, "sec", false, false); 968 try { 969 openSecondary(pri2, false, "sec", false, false); 970 fail(); 971 } catch (IllegalArgumentException expected) {} 972 sec1.close(); 973 pri1.close(); 974 pri2.close(); 975 } 976 977 980 public void testNullLockMode() 981 throws DatabaseException { 982 983 SecondaryDatabase secDb = initDb(); 984 Database priDb = secDb.getPrimaryDatabase(); 985 Transaction txn = txnBegin(); 986 987 DatabaseEntry key = entry(0); 988 DatabaseEntry data = entry(0); 989 DatabaseEntry secKey = entry(KEY_OFFSET); 990 DatabaseEntry found = new DatabaseEntry(); 991 DatabaseEntry found2 = new DatabaseEntry(); 992 DatabaseEntry found3 = new DatabaseEntry(); 993 994 assertEquals(OperationStatus.SUCCESS, 995 priDb.put(txn, key, data)); 996 assertEquals(OperationStatus.SUCCESS, 997 priDb.put(txn, entry(1), data)); 998 assertEquals(OperationStatus.SUCCESS, 999 priDb.put(txn, entry(2), entry(2))); 1000 1001 1002 1003 assertEquals(OperationStatus.SUCCESS, 1004 priDb.get(txn, key, found, null)); 1005 assertEquals(OperationStatus.SUCCESS, 1006 priDb.getSearchBoth(txn, key, data, null)); 1007 assertEquals(OperationStatus.SUCCESS, 1008 secDb.get(txn, secKey, found, null)); 1009 assertEquals(OperationStatus.SUCCESS, 1010 secDb.get(txn, secKey, found, found2, null)); 1011 assertEquals(OperationStatus.SUCCESS, 1012 secDb.getSearchBoth(txn, secKey, key, found, null)); 1013 1014 1015 1016 txnCommit(txn); 1017 txn = txnBeginCursor(); 1018 Cursor cursor = priDb.openCursor(txn, null); 1019 SecondaryCursor secCursor = secDb.openSecondaryCursor(txn, null); 1020 1021 assertEquals(OperationStatus.SUCCESS, 1022 cursor.getSearchKey(key, found, null)); 1023 assertEquals(OperationStatus.SUCCESS, 1024 cursor.getSearchBoth(key, data, null)); 1025 assertEquals(OperationStatus.SUCCESS, 1026 cursor.getSearchKeyRange(key, found, null)); 1027 assertEquals(OperationStatus.SUCCESS, 1028 cursor.getSearchBothRange(key, data, null)); 1029 assertEquals(OperationStatus.SUCCESS, 1030 cursor.getFirst(found, found2, null)); 1031 assertEquals(OperationStatus.SUCCESS, 1032 cursor.getNext(found, found2, null)); 1033 assertEquals(OperationStatus.SUCCESS, 1034 cursor.getPrev(found, found2, null)); 1035 assertEquals(OperationStatus.NOTFOUND, 1036 cursor.getNextDup(found, found2, null)); 1037 assertEquals(OperationStatus.NOTFOUND, 1038 cursor.getPrevDup(found, found2, null)); 1039 assertEquals(OperationStatus.SUCCESS, 1040 cursor.getNextNoDup(found, found2, null)); 1041 assertEquals(OperationStatus.SUCCESS, 1042 cursor.getPrevNoDup(found, found2, null)); 1043 assertEquals(OperationStatus.SUCCESS, 1044 cursor.getLast(found, found2, null)); 1045 1046 assertEquals(OperationStatus.SUCCESS, 1047 secCursor.getSearchKey(secKey, found, null)); 1048 assertEquals(OperationStatus.SUCCESS, 1049 secCursor.getSearchKeyRange(secKey, found, null)); 1050 assertEquals(OperationStatus.SUCCESS, 1051 secCursor.getFirst(found, found2, null)); 1052 assertEquals(OperationStatus.SUCCESS, 1053 secCursor.getNext(found, found2, null)); 1054 assertEquals(OperationStatus.SUCCESS, 1055 secCursor.getPrev(found, found2, null)); 1056 assertEquals(OperationStatus.SUCCESS, 1057 secCursor.getNextDup(found, found2, null)); 1058 assertEquals(OperationStatus.SUCCESS, 1059 secCursor.getPrevDup(found, found2, null)); 1060 assertEquals(OperationStatus.SUCCESS, 1061 secCursor.getNextNoDup(found, found2, null)); 1062 assertEquals(OperationStatus.SUCCESS, 1063 secCursor.getPrevNoDup(found, found2, null)); 1064 assertEquals(OperationStatus.SUCCESS, 1065 secCursor.getLast(found, found2, null)); 1066 1067 assertEquals(OperationStatus.SUCCESS, 1068 secCursor.getSearchKey(secKey, found, found2, null)); 1069 assertEquals(OperationStatus.SUCCESS, 1070 secCursor.getSearchBoth(secKey, data, found, null)); 1071 assertEquals(OperationStatus.SUCCESS, 1072 secCursor.getSearchKeyRange(secKey, found, found2, null)); 1073 assertEquals(OperationStatus.SUCCESS, 1074 secCursor.getSearchBothRange(secKey, data, found, null)); 1075 assertEquals(OperationStatus.SUCCESS, 1076 secCursor.getFirst(found, found2, found3, null)); 1077 assertEquals(OperationStatus.SUCCESS, 1078 secCursor.getNext(found, found2, found3, null)); 1079 assertEquals(OperationStatus.SUCCESS, 1080 secCursor.getPrev(found, found2, found3, null)); 1081 assertEquals(OperationStatus.SUCCESS, 1082 secCursor.getNextDup(found, found2, found3, null)); 1083 assertEquals(OperationStatus.SUCCESS, 1084 secCursor.getPrevDup(found, found2, found3, null)); 1085 assertEquals(OperationStatus.SUCCESS, 1086 secCursor.getNextNoDup(found, found2, found3, null)); 1087 assertEquals(OperationStatus.SUCCESS, 1088 secCursor.getPrevNoDup(found, found2, found3, null)); 1089 assertEquals(OperationStatus.SUCCESS, 1090 secCursor.getLast(found, found2, found3, null)); 1091 1092 secCursor.close(); 1093 cursor.close(); 1094 txnCommit(txn); 1095 secDb.close(); 1096 priDb.close(); 1097 env.close(); 1098 env = null; 1099 } 1100 1101 1106 public void testCursorState() 1107 throws DatabaseException { 1108 1109 SecondaryDatabase secDb = initDb(); 1110 Database priDb = secDb.getPrimaryDatabase(); 1111 Transaction txn = txnBegin(); 1112 1113 DatabaseEntry key = entry(0); 1114 DatabaseEntry data = entry(0); 1115 DatabaseEntry secKey = entry(KEY_OFFSET); 1116 DatabaseEntry found = new DatabaseEntry(); 1117 DatabaseEntry found2 = new DatabaseEntry(); 1118 1119 assertEquals(OperationStatus.SUCCESS, 1120 priDb.put(txn, key, data)); 1121 1122 txnCommit(txn); 1123 txn = txnBeginCursor(); 1124 Cursor cursor = priDb.openCursor(txn, null); 1125 SecondaryCursor secCursor = secDb.openSecondaryCursor(txn, null); 1126 1127 1128 1129 try { 1130 cursor.count(); 1131 fail(); 1132 } catch (DatabaseException expected) {} 1133 try { 1134 cursor.delete(); 1135 fail(); 1136 } catch (DatabaseException expected) {} 1137 try { 1138 cursor.putCurrent(data); 1139 fail(); 1140 } catch (DatabaseException expected) {} 1141 try { 1142 cursor.getCurrent(key, data, null); 1143 fail(); 1144 } catch (DatabaseException expected) {} 1145 try { 1146 cursor.getNextDup(found, found2, null); 1147 fail(); 1148 } catch (DatabaseException expected) {} 1149 try { 1150 cursor.getPrevDup(found, found2, null); 1151 fail(); 1152 } catch (DatabaseException expected) {} 1153 1154 try { 1155 secCursor.count(); 1156 fail(); 1157 } catch (DatabaseException expected) {} 1158 try { 1159 secCursor.delete(); 1160 fail(); 1161 } catch (DatabaseException expected) {} 1162 try { 1163 secCursor.getCurrent(key, data, null); 1164 fail(); 1165 } catch (DatabaseException expected) {} 1166 try { 1167 secCursor.getNextDup(found, found2, null); 1168 fail(); 1169 } catch (DatabaseException expected) {} 1170 try { 1171 secCursor.getPrevDup(found, found2, null); 1172 fail(); 1173 } catch (DatabaseException expected) {} 1174 1175 1176 1177 assertEquals(OperationStatus.SUCCESS, 1178 cursor.getSearchKey(key, found, null)); 1179 assertEquals(OperationStatus.SUCCESS, 1180 secCursor.getSearchKey(secKey, found, null)); 1181 secCursor.close(); 1182 cursor.close(); 1183 1184 try { 1185 cursor.close(); 1186 fail(); 1187 } catch (DatabaseException expected) {} 1188 try { 1189 cursor.count(); 1190 fail(); 1191 } catch (DatabaseException expected) {} 1192 try { 1193 cursor.delete(); 1194 fail(); 1195 } catch (DatabaseException expected) {} 1196 try { 1197 cursor.put(key, data); 1198 fail(); 1199 } catch (DatabaseException expected) {} 1200 try { 1201 cursor.putNoOverwrite(key, data); 1202 fail(); 1203 } catch (DatabaseException expected) {} 1204 try { 1205 cursor.putNoDupData(key, data); 1206 fail(); 1207 } catch (DatabaseException expected) {} 1208 try { 1209 cursor.putCurrent(data); 1210 fail(); 1211 } catch (DatabaseException expected) {} 1212 try { 1213 cursor.getCurrent(key, data, null); 1214 fail(); 1215 } catch (DatabaseException expected) {} 1216 try { 1217 cursor.getSearchKey(key, found, null); 1218 fail(); 1219 } catch (DatabaseException expected) {} 1220 try { 1221 cursor.getSearchBoth(key, data, null); 1222 fail(); 1223 } catch (DatabaseException expected) {} 1224 try { 1225 cursor.getSearchKeyRange(key, found, null); 1226 fail(); 1227 } catch (DatabaseException expected) {} 1228 try { 1229 cursor.getSearchBothRange(key, data, null); 1230 fail(); 1231 } catch (DatabaseException expected) {} 1232 try { 1233 cursor.getFirst(found, found2, null); 1234 fail(); 1235 } catch (DatabaseException expected) {} 1236 try { 1237 cursor.getNext(found, found2, null); 1238 fail(); 1239 } catch (DatabaseException expected) {} 1240 try { 1241 cursor.getPrev(found, found2, null); 1242 fail(); 1243 } catch (DatabaseException expected) {} 1244 try { 1245 cursor.getNextDup(found, found2, null); 1246 fail(); 1247 } catch (DatabaseException expected) {} 1248 try { 1249 cursor.getPrevDup(found, found2, null); 1250 fail(); 1251 } catch (DatabaseException expected) {} 1252 try { 1253 cursor.getNextNoDup(found, found2, null); 1254 fail(); 1255 } catch (DatabaseException expected) {} 1256 try { 1257 cursor.getPrevNoDup(found, found2, null); 1258 fail(); 1259 } catch (DatabaseException expected) {} 1260 try { 1261 cursor.getLast(found, found2, null); 1262 fail(); 1263 } catch (DatabaseException expected) {} 1264 1265 try { 1266 secCursor.close(); 1267 fail(); 1268 } catch (DatabaseException expected) {} 1269 try { 1270 secCursor.count(); 1271 fail(); 1272 } catch (DatabaseException expected) {} 1273 try { 1274 secCursor.delete(); 1275 fail(); 1276 } catch (DatabaseException expected) {} 1277 try { 1278 secCursor.getCurrent(key, data, null); 1279 fail(); 1280 } catch (DatabaseException expected) {} 1281 try { 1282 secCursor.getSearchKey(secKey, found, null); 1283 fail(); 1284 } catch (DatabaseException expected) {} 1285 try { 1286 secCursor.getSearchKeyRange(secKey, found, null); 1287 fail(); 1288 } catch (DatabaseException expected) {} 1289 try { 1290 secCursor.getFirst(found, found2, null); 1291 fail(); 1292 } catch (DatabaseException expected) {} 1293 try { 1294 secCursor.getNext(found, found2, null); 1295 fail(); 1296 } catch (DatabaseException expected) {} 1297 try { 1298 secCursor.getPrev(found, found2, null); 1299 fail(); 1300 } catch (DatabaseException expected) {} 1301 try { 1302 secCursor.getNextDup(found, found2, null); 1303 fail(); 1304 } catch (DatabaseException expected) {} 1305 try { 1306 secCursor.getPrevDup(found, found2, null); 1307 fail(); 1308 } catch (DatabaseException expected) {} 1309 try { 1310 secCursor.getNextNoDup(found, found2, null); 1311 fail(); 1312 } catch (DatabaseException expected) {} 1313 try { 1314 secCursor.getPrevNoDup(found, found2, null); 1315 fail(); 1316 } catch (DatabaseException expected) {} 1317 try { 1318 secCursor.getLast(found, found2, null); 1319 fail(); 1320 } catch (DatabaseException expected) {} 1321 1322 txnCommit(txn); 1323 secDb.close(); 1324 priDb.close(); 1325 env.close(); 1326 env = null; 1327 } 1328 1329 1332 public void testDirtyReadPartialGet() 1333 throws DatabaseException { 1334 1335 SecondaryDatabase secDb = initDb(); 1336 Database priDb = secDb.getPrimaryDatabase(); 1337 1338 DatabaseEntry data = new DatabaseEntry(); 1339 DatabaseEntry key = new DatabaseEntry(); 1340 DatabaseEntry secKey = new DatabaseEntry(); 1341 OperationStatus status; 1342 1343 1344 Transaction txn = txnBegin(); 1345 status = priDb.put(txn, entry(0), entry(0)); 1346 assertSame(OperationStatus.SUCCESS, status); 1347 txnCommit(txn); 1348 1349 1350 status = secDb.get(null, entry(0 + KEY_OFFSET), key, 1351 data, LockMode.DEFAULT); 1352 assertSame(OperationStatus.SUCCESS, status); 1353 assertDataEquals(entry(0), key); 1354 assertDataEquals(entry(0), data); 1355 1356 1357 data.setPartial(0, 0, true); 1358 status = secDb.get(null, entry(0 + KEY_OFFSET), key, 1359 data, LockMode.READ_UNCOMMITTED); 1360 assertSame(OperationStatus.SUCCESS, status); 1361 assertDataEquals(entry(0), key); 1362 assertEquals(0, data.getData().length); 1363 assertEquals(0, data.getSize()); 1364 1365 1366 data.setPartial(0, 1, true); 1367 status = secDb.get(null, entry(0 + KEY_OFFSET), key, 1368 data, LockMode.READ_UNCOMMITTED); 1369 assertSame(OperationStatus.SUCCESS, status); 1370 assertDataEquals(entry(0), key); 1371 assertEquals(1, data.getData().length); 1372 assertEquals(1, data.getSize()); 1373 1374 secDb.close(); 1375 priDb.close(); 1376 } 1377 1378 1381 private SecondaryDatabase initDb() 1382 throws DatabaseException { 1383 1384 Database priDb = openDatabase(false, "testDB", false); 1385 SecondaryDatabase secDb = openSecondary(priDb, true, "testSecDB", 1386 false, false); 1387 return secDb; 1388 } 1389 1390 private Database openDatabase(boolean allowDuplicates, String name, 1391 boolean readOnly) 1392 throws DatabaseException { 1393 1394 DatabaseConfig dbConfig = new DatabaseConfig(); 1395 dbConfig.setTransactional(isTransactional); 1396 dbConfig.setAllowCreate(true); 1397 dbConfig.setSortedDuplicates(allowDuplicates); 1398 dbConfig.setReadOnly(readOnly); 1399 Transaction txn = txnBegin(); 1400 Database priDb; 1401 try { 1402 priDb = env.openDatabase(txn, name, dbConfig); 1403 } finally { 1404 txnCommit(txn); 1405 } 1406 assertNotNull(priDb); 1407 return priDb; 1408 } 1409 1410 private SecondaryDatabase openSecondary(Database priDb, 1411 boolean allowDuplicates, 1412 String dbName, 1413 boolean allowPopulate, 1414 boolean readOnly) 1415 throws DatabaseException { 1416 1417 List secListBefore = priDb.getSecondaryDatabases(); 1418 SecondaryConfig dbConfig = new SecondaryConfig(); 1419 dbConfig.setTransactional(isTransactional); 1420 dbConfig.setAllowCreate(true); 1421 dbConfig.setSortedDuplicates(allowDuplicates); 1422 dbConfig.setReadOnly(readOnly); 1423 dbConfig.setAllowPopulate(allowPopulate); 1424 if (!readOnly) { 1425 if (useMultiKey) { 1426 dbConfig.setMultiKeyCreator 1427 (new SimpleMultiKeyCreator(new MyKeyCreator())); 1428 } else { 1429 dbConfig.setKeyCreator(new MyKeyCreator()); 1430 } 1431 } 1432 Transaction txn = txnBegin(); 1433 SecondaryDatabase secDb; 1434 try { 1435 secDb = env.openSecondaryDatabase(txn, dbName, priDb, dbConfig); 1436 } finally { 1437 txnCommit(txn); 1438 } 1439 assertNotNull(secDb); 1440 1441 1442 assertSame(priDb, secDb.getPrimaryDatabase()); 1443 SecondaryConfig config2 = secDb.getSecondaryConfig(); 1444 assertEquals(allowPopulate, config2.getAllowPopulate()); 1445 assertEquals(dbConfig.getKeyCreator(), config2.getKeyCreator()); 1446 1447 1448 List secListAfter = priDb.getSecondaryDatabases(); 1449 assertTrue(secListAfter.remove(secDb)); 1450 assertEquals(secListBefore, secListAfter); 1451 1452 return secDb; 1453 } 1454 1455 private DatabaseEntry entry(int val) { 1456 1457 return new DatabaseEntry(TestUtils.getTestArray(val)); 1458 } 1459 1460 private void assertDataEquals(DatabaseEntry e1, DatabaseEntry e2) { 1461 assertTrue(e1.equals(e2)); 1462 } 1463 1464 private static class MyKeyCreator implements SecondaryKeyCreator { 1465 1466 public boolean createSecondaryKey(SecondaryDatabase secondary, 1467 DatabaseEntry key, 1468 DatabaseEntry data, 1469 DatabaseEntry result) 1470 throws DatabaseException { 1471 1472 result.setData( 1473 TestUtils.getTestArray( 1474 TestUtils.getTestVal(data.getData()) + KEY_OFFSET)); 1475 return true; 1476 } 1477 } 1478} 1479 | Popular Tags |