1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 2002,2008 Oracle. All rights reserved. 5 * 6 * $Id: SecondaryCursor.java,v 12.7 2008/01/17 05:04:53 mjc Exp $ 7 */ 8 9package com.sleepycat.db; 10 11import com.sleepycat.db.internal.DbConstants; 12import com.sleepycat.db.internal.Dbc; 13 14/** 15A database cursor for a secondary database. Cursors are not thread safe 16and the application is responsible for coordinating any multithreaded 17access to a single cursor object. 18<p> 19Secondary cursors are returned by 20{@link SecondaryDatabase#openCursor SecondaryDatabase.openCursor} and 21{@link SecondaryDatabase#openSecondaryCursor 22SecondaryDatabase.openSecondaryCursor}. The distinguishing characteristics 23of a secondary cursor are: 24<ul> 25<li>Direct calls to <code>put()</code> methods on a secondary cursor are 26prohibited. 27<li>The {@link #delete} method of a secondary cursor will delete the primary 28record and as well as all its associated secondary records. 29<li>Calls to all get methods will return the data from the associated 30primary database. 31<li>Additional get method signatures are provided to return the primary key 32in an additional pKey parameter. 33<li>Calls to {@link #dup} will return a {@link SecondaryCursor}. 34<li>The {@link #dupSecondary} method is provided to return a {@link 35SecondaryCursor} that doesn't require casting. 36</ul> 37<p> 38To obtain a secondary cursor with default attributes: 39<blockquote><pre> 40 SecondaryCursor cursor = myDb.openSecondaryCursor(txn, null); 41</pre></blockquote> 42To customize the attributes of a cursor, use a CursorConfig object. 43<blockquote><pre> 44 CursorConfig config = new CursorConfig(); 45 config.setDirtyRead(true); 46 SecondaryCursor cursor = myDb.openSecondaryCursor(txn, config); 47</pre></blockquote> 48*/ 49public class SecondaryCursor extends Cursor { 50 /* package */ 51 SecondaryCursor(final SecondaryDatabase database, 52 final Dbc dbc, 53 final CursorConfig config) 54 throws DatabaseException { 55 56 super(database, dbc, config); 57 } 58 59 /** 60 Return the SecondaryDatabase handle associated with this Cursor. 61 <p> 62 @return 63 The SecondaryDatabase handle associated with this Cursor. 64 <p> 65 */ 66 public SecondaryDatabase getSecondaryDatabase() { 67 return (SecondaryDatabase)super.getDatabase(); 68 } 69 70 /** 71 Returns a new <code>SecondaryCursor</code> for the same transaction as 72 the original cursor. 73 */ 74 public Cursor dup(final boolean samePosition) 75 throws DatabaseException { 76 77 return dupSecondary(samePosition); 78 } 79 80 /** 81 Returns a new copy of the cursor as a <code>SecondaryCursor</code>. 82 <p> 83 Calling this method is the equivalent of calling {@link #dup} and 84 casting the result to {@link SecondaryCursor}. 85 <p> 86 @see #dup 87 */ 88 public SecondaryCursor dupSecondary(final boolean samePosition) 89 throws DatabaseException { 90 91 return new SecondaryCursor(getSecondaryDatabase(), 92 dbc.dup(samePosition ? DbConstants.DB_POSITION : 0), config); 93 } 94 95 /** 96 Returns the key/data pair to which the cursor refers. 97<p> 98If this method fails for any reason, the position of the cursor will be 99unchanged. 100@throws NullPointerException if a DatabaseEntry parameter is null or 101does not contain a required non-null byte array. 102<p> 103@throws DeadlockException if the operation was selected to resolve a 104deadlock. 105<p> 106@throws IllegalArgumentException if an invalid parameter was specified. 107<p> 108@throws DatabaseException if a failure occurs. 109<p> 110@param key the secondary key 111returned as output. Its byte array does not need to be initialized by the 112caller. 113@param pKey the primary key 114returned as output. Its byte array does not need to be initialized by the 115caller. 116@param data the primary data 117returned as output. Multiple results can be retrieved by passing an object 118that is a subclass of {@link com.sleepycat.db.MultipleEntry MultipleEntry}, otherwise its byte array does not 119need to be initialized by the caller. 120@param lockMode the locking attributes; if null, default attributes are used. 121@return {@link com.sleepycat.db.OperationStatus#KEYEMPTY OperationStatus.KEYEMPTY} if the key/pair at the cursor 122position has been deleted; otherwise, {@link com.sleepycat.db.OperationStatus#SUCCESS OperationStatus.SUCCESS}. 123 */ 124 public OperationStatus getCurrent(final DatabaseEntry key, 125 final DatabaseEntry pKey, 126 final DatabaseEntry data, 127 LockMode lockMode) 128 throws DatabaseException { 129 130 return OperationStatus.fromInt( 131 dbc.pget(key, pKey, data, 132 DbConstants.DB_CURRENT | LockMode.getFlag(lockMode) | 133 ((data == null) ? 0 : data.getMultiFlag()))); 134 } 135 136 /** 137 Move the cursor to the first key/data pair of the database, and return 138that pair. If the first key has duplicate values, the first data item 139in the set of duplicates is returned. 140<p> 141If this method fails for any reason, the position of the cursor will be 142unchanged. 143@throws NullPointerException if a DatabaseEntry parameter is null or 144does not contain a required non-null byte array. 145<p> 146@throws DeadlockException if the operation was selected to resolve a 147deadlock. 148<p> 149@throws IllegalArgumentException if an invalid parameter was specified. 150<p> 151@throws DatabaseException if a failure occurs. 152<p> 153@param key the secondary key 154returned as output. Its byte array does not need to be initialized by the 155caller. 156@param pKey the primary key 157returned as output. Its byte array does not need to be initialized by the 158caller. 159@param data the primary data 160returned as output. Multiple results can be retrieved by passing an object 161that is a subclass of {@link com.sleepycat.db.MultipleEntry MultipleEntry}, otherwise its byte array does not 162need to be initialized by the caller. 163@param lockMode the locking attributes; if null, default attributes are used. 164@return {@link com.sleepycat.db.OperationStatus#NOTFOUND OperationStatus.NOTFOUND} if no matching key/data pair is 165found; {@link com.sleepycat.db.OperationStatus#KEYEMPTY OperationStatus.KEYEMPTY} if the database is a Queue or Recno database and the specified key exists, but was never explicitly created by the application or was later deleted; otherwise, {@link com.sleepycat.db.OperationStatus#SUCCESS OperationStatus.SUCCESS}. 166 */ 167 public OperationStatus getFirst(final DatabaseEntry key, 168 final DatabaseEntry pKey, 169 final DatabaseEntry data, 170 LockMode lockMode) 171 throws DatabaseException { 172 173 return OperationStatus.fromInt( 174 dbc.pget(key, pKey, data, 175 DbConstants.DB_FIRST | LockMode.getFlag(lockMode) | 176 ((data == null) ? 0 : data.getMultiFlag()))); 177 } 178 179 /** 180 Move the cursor to the last key/data pair of the database, and return 181that pair. If the last key has duplicate values, the last data item in 182the set of duplicates is returned. 183<p> 184If this method fails for any reason, the position of the cursor will be 185unchanged. 186@throws NullPointerException if a DatabaseEntry parameter is null or 187does not contain a required non-null byte array. 188<p> 189@throws DeadlockException if the operation was selected to resolve a 190deadlock. 191<p> 192@throws IllegalArgumentException if an invalid parameter was specified. 193<p> 194@throws DatabaseException if a failure occurs. 195<p> 196@param key the secondary key 197returned as output. Its byte array does not need to be initialized by the 198caller. 199@param pKey the primary key 200returned as output. Its byte array does not need to be initialized by the 201caller. 202@param data the primary data 203returned as output. Its byte array does not need to be initialized by the 204caller. 205@param lockMode the locking attributes; if null, default attributes are used. 206@return {@link com.sleepycat.db.OperationStatus#NOTFOUND OperationStatus.NOTFOUND} if no matching key/data pair is 207found; {@link com.sleepycat.db.OperationStatus#KEYEMPTY OperationStatus.KEYEMPTY} if the database is a Queue or Recno database and the specified key exists, but was never explicitly created by the application or was later deleted; otherwise, {@link com.sleepycat.db.OperationStatus#SUCCESS OperationStatus.SUCCESS}. 208 */ 209 public OperationStatus getLast(final DatabaseEntry key, 210 final DatabaseEntry pKey, 211 final DatabaseEntry data, 212 LockMode lockMode) 213 throws DatabaseException { 214 215 return OperationStatus.fromInt( 216 dbc.pget(key, pKey, data, 217 DbConstants.DB_LAST | LockMode.getFlag(lockMode) | 218 ((data == null) ? 0 : data.getMultiFlag()))); 219 } 220 221 /** 222 Move the cursor to the next key/data pair and return that pair. If 223the matching key has duplicate values, the first data item in the set 224of duplicates is returned. 225<p> 226If the cursor is not yet initialized, move the cursor to the first 227key/data pair of the database, and return that pair. Otherwise, the 228cursor is moved to the next key/data pair of the database, and that pair 229is returned. In the presence of duplicate key values, the value of the 230key may not change. 231<p> 232If this method fails for any reason, the position of the cursor will be 233unchanged. 234@throws NullPointerException if a DatabaseEntry parameter is null or 235does not contain a required non-null byte array. 236<p> 237@throws DeadlockException if the operation was selected to resolve a 238deadlock. 239<p> 240@throws IllegalArgumentException if an invalid parameter was specified. 241<p> 242@throws DatabaseException if a failure occurs. 243<p> 244@param key the secondary key 245returned as output. Its byte array does not need to be initialized by the 246caller. 247@param pKey the primary key 248returned as output. Its byte array does not need to be initialized by the 249caller. 250@param data the primary data 251returned as output. Multiple results can be retrieved by passing an object 252that is a subclass of {@link com.sleepycat.db.MultipleEntry MultipleEntry}, otherwise its byte array does not 253need to be initialized by the caller. 254@param lockMode the locking attributes; if null, default attributes are used. 255@return {@link com.sleepycat.db.OperationStatus#NOTFOUND OperationStatus.NOTFOUND} if no matching key/data pair is 256found; {@link com.sleepycat.db.OperationStatus#KEYEMPTY OperationStatus.KEYEMPTY} if the database is a Queue or Recno database and the specified key exists, but was never explicitly created by the application or was later deleted; otherwise, {@link com.sleepycat.db.OperationStatus#SUCCESS OperationStatus.SUCCESS}. 257 */ 258 public OperationStatus getNext(final DatabaseEntry key, 259 final DatabaseEntry pKey, 260 final DatabaseEntry data, 261 LockMode lockMode) 262 throws DatabaseException { 263 264 return OperationStatus.fromInt( 265 dbc.pget(key, pKey, data, 266 DbConstants.DB_NEXT | LockMode.getFlag(lockMode) | 267 ((data == null) ? 0 : data.getMultiFlag()))); 268 } 269 270 /** 271 If the next key/data pair of the database is a duplicate data record for 272the current key/data pair, move the cursor to the next key/data pair 273of the database and return that pair. 274<p> 275If this method fails for any reason, the position of the cursor will be 276unchanged. 277@throws NullPointerException if a DatabaseEntry parameter is null or 278does not contain a required non-null byte array. 279<p> 280@throws DeadlockException if the operation was selected to resolve a 281deadlock. 282<p> 283@throws IllegalArgumentException if an invalid parameter was specified. 284<p> 285@throws DatabaseException if a failure occurs. 286<p> 287@param key the secondary key 288returned as output. Its byte array does not need to be initialized by the 289caller. 290@param pKey the primary key 291returned as output. Its byte array does not need to be initialized by the 292caller. 293@param data the primary data 294returned as output. Multiple results can be retrieved by passing an object 295that is a subclass of {@link com.sleepycat.db.MultipleEntry MultipleEntry}, otherwise its byte array does not 296need to be initialized by the caller. 297@param lockMode the locking attributes; if null, default attributes are used. 298@return {@link com.sleepycat.db.OperationStatus#NOTFOUND OperationStatus.NOTFOUND} if no matching key/data pair is 299found; {@link com.sleepycat.db.OperationStatus#KEYEMPTY OperationStatus.KEYEMPTY} if the database is a Queue or Recno database and the specified key exists, but was never explicitly created by the application or was later deleted; otherwise, {@link com.sleepycat.db.OperationStatus#SUCCESS OperationStatus.SUCCESS}. 300 */ 301 public OperationStatus getNextDup(final DatabaseEntry key, 302 final DatabaseEntry pKey, 303 final DatabaseEntry data, 304 LockMode lockMode) 305 throws DatabaseException { 306 307 return OperationStatus.fromInt( 308 dbc.pget(key, pKey, data, 309 DbConstants.DB_NEXT_DUP | LockMode.getFlag(lockMode) | 310 ((data == null) ? 0 : data.getMultiFlag()))); 311 } 312 313 /** 314 Move the cursor to the next non-duplicate key/data pair and return 315that pair. If the matching key has duplicate values, the first data 316item in the set of duplicates is returned. 317<p> 318If the cursor is not yet initialized, move the cursor to the first 319key/data pair of the database, and return that pair. Otherwise, the 320cursor is moved to the next non-duplicate key of the database, and that 321key/data pair is returned. 322<p> 323If this method fails for any reason, the position of the cursor will be 324unchanged. 325@throws NullPointerException if a DatabaseEntry parameter is null or 326does not contain a required non-null byte array. 327<p> 328@throws DeadlockException if the operation was selected to resolve a 329deadlock. 330<p> 331@throws IllegalArgumentException if an invalid parameter was specified. 332<p> 333@throws DatabaseException if a failure occurs. 334<p> 335@param key the secondary key 336returned as output. Its byte array does not need to be initialized by the 337caller. 338@param pKey the primary key 339returned as output. Its byte array does not need to be initialized by the 340caller. 341@param data the primary data 342returned as output. Multiple results can be retrieved by passing an object 343that is a subclass of {@link com.sleepycat.db.MultipleEntry MultipleEntry}, otherwise its byte array does not 344need to be initialized by the caller. 345@param lockMode the locking attributes; if null, default attributes are used. 346@return {@link com.sleepycat.db.OperationStatus#NOTFOUND OperationStatus.NOTFOUND} if no matching key/data pair is 347found; {@link com.sleepycat.db.OperationStatus#KEYEMPTY OperationStatus.KEYEMPTY} if the database is a Queue or Recno database and the specified key exists, but was never explicitly created by the application or was later deleted; otherwise, {@link com.sleepycat.db.OperationStatus#SUCCESS OperationStatus.SUCCESS}. 348 */ 349 public OperationStatus getNextNoDup(final DatabaseEntry key, 350 final DatabaseEntry pKey, 351 final DatabaseEntry data, 352 LockMode lockMode) 353 throws DatabaseException { 354 355 return OperationStatus.fromInt( 356 dbc.pget(key, pKey, data, 357 DbConstants.DB_NEXT_NODUP | LockMode.getFlag(lockMode) | 358 ((data == null) ? 0 : data.getMultiFlag()))); 359 } 360 361 /** 362 Move the cursor to the previous key/data pair and return that pair. 363If the matching key has duplicate values, the last data item in the set 364of duplicates is returned. 365<p> 366If the cursor is not yet initialized, move the cursor to the last 367key/data pair of the database, and return that pair. Otherwise, the 368cursor is moved to the previous key/data pair of the database, and that 369pair is returned. In the presence of duplicate key values, the value of 370the key may not change. 371<p> 372If this method fails for any reason, the position of the cursor will be 373unchanged. 374@throws NullPointerException if a DatabaseEntry parameter is null or 375does not contain a required non-null byte array. 376<p> 377@throws DeadlockException if the operation was selected to resolve a 378deadlock. 379<p> 380@throws IllegalArgumentException if an invalid parameter was specified. 381<p> 382@throws DatabaseException if a failure occurs. 383<p> 384@param key the secondary key 385returned as output. Its byte array does not need to be initialized by the 386caller. 387@param pKey the primary key 388returned as output. Its byte array does not need to be initialized by the 389caller. 390@param data the primary data 391returned as output. Its byte array does not need to be initialized by the 392caller. 393@param lockMode the locking attributes; if null, default attributes are used. 394@return {@link com.sleepycat.db.OperationStatus#NOTFOUND OperationStatus.NOTFOUND} if no matching key/data pair is 395found; {@link com.sleepycat.db.OperationStatus#KEYEMPTY OperationStatus.KEYEMPTY} if the database is a Queue or Recno database and the specified key exists, but was never explicitly created by the application or was later deleted; otherwise, {@link com.sleepycat.db.OperationStatus#SUCCESS OperationStatus.SUCCESS}. 396 */ 397 public OperationStatus getPrev(final DatabaseEntry key, 398 final DatabaseEntry pKey, 399 final DatabaseEntry data, 400 LockMode lockMode) 401 throws DatabaseException { 402 403 return OperationStatus.fromInt( 404 dbc.pget(key, pKey, data, 405 DbConstants.DB_PREV | LockMode.getFlag(lockMode) | 406 ((data == null) ? 0 : data.getMultiFlag()))); 407 } 408 409 /** 410 If the previous key/data pair of the database is a duplicate data record 411for the current key/data pair, move the cursor to the previous key/data 412pair of the database and return that pair. 413<p> 414If this method fails for any reason, the position of the cursor will be 415unchanged. 416@throws NullPointerException if a DatabaseEntry parameter is null or 417does not contain a required non-null byte array. 418<p> 419@throws DeadlockException if the operation was selected to resolve a 420deadlock. 421<p> 422@throws IllegalArgumentException if an invalid parameter was specified. 423<p> 424@throws DatabaseException if a failure occurs. 425<p> 426@param key the secondary key 427returned as output. Its byte array does not need to be initialized by the 428caller. 429@param pKey the primary key 430returned as output. Its byte array does not need to be initialized by the 431caller. 432@param data the primary data 433returned as output. Its byte array does not need to be initialized by the 434caller. 435@param lockMode the locking attributes; if null, default attributes are used. 436@return {@link com.sleepycat.db.OperationStatus#NOTFOUND OperationStatus.NOTFOUND} if no matching key/data pair is 437found; {@link com.sleepycat.db.OperationStatus#KEYEMPTY OperationStatus.KEYEMPTY} if the database is a Queue or Recno database and the specified key exists, but was never explicitly created by the application or was later deleted; otherwise, {@link com.sleepycat.db.OperationStatus#SUCCESS OperationStatus.SUCCESS}. 438 */ 439 public OperationStatus getPrevDup(final DatabaseEntry key, 440 final DatabaseEntry pKey, 441 final DatabaseEntry data, 442 LockMode lockMode) 443 throws DatabaseException { 444 445 /* 446 * "Get the previous duplicate" isn't directly supported by the C API, 447 * so here's how to get it: dup the cursor and call getPrev, then dup 448 * the result and call getNextDup. If both succeed then there was a 449 * previous duplicate and the first dup is sitting on it. Keep that, 450 * and call getCurrent to fill in the user's buffers. 451 */ 452 Dbc dup1 = dbc.dup(DbConstants.DB_POSITION); 453 try { 454 int errCode = dup1.get(DatabaseEntry.IGNORE, DatabaseEntry.IGNORE, 455 DbConstants.DB_PREV | LockMode.getFlag(lockMode)); 456 if (errCode == 0) { 457 Dbc dup2 = dup1.dup(DbConstants.DB_POSITION); 458 try { 459 errCode = dup2.get(DatabaseEntry.IGNORE, 460 DatabaseEntry.IGNORE, 461 DbConstants.DB_NEXT_DUP | LockMode.getFlag(lockMode)); 462 } finally { 463 dup2.close(); 464 } 465 } 466 if (errCode == 0) 467 errCode = dup1.pget(key, pKey, data, 468 DbConstants.DB_CURRENT | LockMode.getFlag(lockMode) | 469 ((data == null) ? 0 : data.getMultiFlag())); 470 if (errCode == 0) { 471 Dbc tdbc = dbc; 472 dbc = dup1; 473 dup1 = tdbc; 474 } 475 return OperationStatus.fromInt(errCode); 476 } finally { 477 dup1.close(); 478 } 479 } 480 481 /** 482 Move the cursor to the previous non-duplicate key/data pair and return 483that pair. If the matching key has duplicate values, the last data item 484in the set of duplicates is returned. 485<p> 486If the cursor is not yet initialized, move the cursor to the last 487key/data pair of the database, and return that pair. Otherwise, the 488cursor is moved to the previous non-duplicate key of the database, and 489that key/data pair is returned. 490<p> 491If this method fails for any reason, the position of the cursor will be 492unchanged. 493@throws NullPointerException if a DatabaseEntry parameter is null or 494does not contain a required non-null byte array. 495<p> 496@throws DeadlockException if the operation was selected to resolve a 497deadlock. 498<p> 499@throws IllegalArgumentException if an invalid parameter was specified. 500<p> 501@throws DatabaseException if a failure occurs. 502<p> 503@param key the secondary key 504returned as output. Its byte array does not need to be initialized by the 505caller. 506@param pKey the primary key 507returned as output. Its byte array does not need to be initialized by the 508caller. 509@param data the primary data 510returned as output. Its byte array does not need to be initialized by the 511caller. 512@param lockMode the locking attributes; if null, default attributes are used. 513@return {@link com.sleepycat.db.OperationStatus#NOTFOUND OperationStatus.NOTFOUND} if no matching key/data pair is 514found; {@link com.sleepycat.db.OperationStatus#KEYEMPTY OperationStatus.KEYEMPTY} if the database is a Queue or Recno database and the specified key exists, but was never explicitly created by the application or was later deleted; otherwise, {@link com.sleepycat.db.OperationStatus#SUCCESS OperationStatus.SUCCESS}. 515 */ 516 public OperationStatus getPrevNoDup(final DatabaseEntry key, 517 final DatabaseEntry pKey, 518 final DatabaseEntry data, 519 LockMode lockMode) 520 throws DatabaseException { 521 522 return OperationStatus.fromInt( 523 dbc.pget(key, pKey, data, 524 DbConstants.DB_PREV_NODUP | LockMode.getFlag(lockMode) | 525 ((data == null) ? 0 : data.getMultiFlag()))); 526 } 527 528 /** 529 Return the record number associated with the cursor. The record number 530will be returned in the data parameter. 531<p> 532For this method to be called, the underlying database must be of type 533Btree, and it must have been configured to support record numbers. 534<p> 535When called on a cursor opened on a database that has been made into a 536secondary index, the method returns the record numbers of both the 537secondary and primary databases. If either underlying database is not of 538type Btree or is not configured with record numbers, the out-of-band 539record number of 0 is returned. 540<p> 541If this method fails for any reason, the position of the cursor will be 542unchanged. 543@throws NullPointerException if a DatabaseEntry parameter is null or 544does not contain a required non-null byte array. 545<p> 546@throws DeadlockException if the operation was selected to resolve a 547deadlock. 548<p> 549@throws IllegalArgumentException if an invalid parameter was specified. 550<p> 551@throws DatabaseException if a failure occurs. 552<p> 553@param secondaryRecno the secondary record number 554returned as output. Its byte array does not need to be initialized by the 555caller. 556@param primaryRecno the primary record number 557returned as output. Its byte array does not need to be initialized by the 558caller. 559@param lockMode the locking attributes; if null, default attributes are used. 560@return {@link com.sleepycat.db.OperationStatus#NOTFOUND OperationStatus.NOTFOUND} if no matching key/data pair is 561found; {@link com.sleepycat.db.OperationStatus#KEYEMPTY OperationStatus.KEYEMPTY} if the database is a Queue or Recno database and the specified key exists, but was never explicitly created by the application or was later deleted; otherwise, {@link com.sleepycat.db.OperationStatus#SUCCESS OperationStatus.SUCCESS}. 562 */ 563 public OperationStatus getRecordNumber(final DatabaseEntry secondaryRecno, 564 final DatabaseEntry primaryRecno, 565 LockMode lockMode) 566 throws DatabaseException { 567 568 return OperationStatus.fromInt( 569 dbc.pget(DatabaseEntry.IGNORE, secondaryRecno, primaryRecno, 570 DbConstants.DB_GET_RECNO | LockMode.getFlag(lockMode))); 571 } 572 573 /** 574 Move the cursor to the given key of the database, and return the datum 575associated with the given key. If the matching key has duplicate 576values, the first data item in the set of duplicates is returned. 577<p> 578If this method fails for any reason, the position of the cursor will be 579unchanged. 580@throws NullPointerException if a DatabaseEntry parameter is null or 581does not contain a required non-null byte array. 582<p> 583@throws DeadlockException if the operation was selected to resolve a 584deadlock. 585<p> 586@throws IllegalArgumentException if an invalid parameter was specified. 587<p> 588@throws DatabaseException if a failure occurs. 589<p> 590@param key the secondary key 591used as input. It must be initialized with a non-null byte array by the 592caller. 593@param pKey the primary key 594returned as output. Its byte array does not need to be initialized by the 595caller. 596@param data the primary data 597returned as output. Multiple results can be retrieved by passing an object 598that is a subclass of {@link com.sleepycat.db.MultipleEntry MultipleEntry}, otherwise its byte array does not 599need to be initialized by the caller. 600@param lockMode the locking attributes; if null, default attributes are used. 601@return {@link com.sleepycat.db.OperationStatus#NOTFOUND OperationStatus.NOTFOUND} if no matching key/data pair is 602found; {@link com.sleepycat.db.OperationStatus#KEYEMPTY OperationStatus.KEYEMPTY} if the database is a Queue or Recno database and the specified key exists, but was never explicitly created by the application or was later deleted; otherwise, {@link com.sleepycat.db.OperationStatus#SUCCESS OperationStatus.SUCCESS}. 603 */ 604 public OperationStatus getSearchKey(final DatabaseEntry key, 605 final DatabaseEntry pKey, 606 final DatabaseEntry data, 607 LockMode lockMode) 608 throws DatabaseException { 609 610 return OperationStatus.fromInt( 611 dbc.pget(key, pKey, data, 612 DbConstants.DB_SET | LockMode.getFlag(lockMode) | 613 ((data == null) ? 0 : data.getMultiFlag()))); 614 } 615 616 /** 617 Move the cursor to the closest matching key of the database, and return 618the data item associated with the matching key. If the matching key has 619duplicate values, the first data item in the set of duplicates is returned. 620<p> 621The returned key/data pair is for the smallest key greater than or equal 622to the specified key (as determined by the key comparison function), 623permitting partial key matches and range searches. 624<p> 625If this method fails for any reason, the position of the cursor will be 626unchanged. 627@throws NullPointerException if a DatabaseEntry parameter is null or 628does not contain a required non-null byte array. 629<p> 630@throws DeadlockException if the operation was selected to resolve a 631deadlock. 632<p> 633@throws IllegalArgumentException if an invalid parameter was specified. 634<p> 635@throws DatabaseException if a failure occurs. 636<p> 637@param key the secondary key 638used as input and returned as output. It must be initialized with a non-null 639byte array by the caller. 640@param pKey the primary key 641returned as output. Its byte array does not need to be initialized by the 642caller. 643@param data the primary data 644returned as output. Multiple results can be retrieved by passing an object 645that is a subclass of {@link com.sleepycat.db.MultipleEntry MultipleEntry}, otherwise its byte array does not 646need to be initialized by the caller. 647@param lockMode the locking attributes; if null, default attributes are used. 648@return {@link com.sleepycat.db.OperationStatus#NOTFOUND OperationStatus.NOTFOUND} if no matching key/data pair is 649found; {@link com.sleepycat.db.OperationStatus#KEYEMPTY OperationStatus.KEYEMPTY} if the database is a Queue or Recno database and the specified key exists, but was never explicitly created by the application or was later deleted; otherwise, {@link com.sleepycat.db.OperationStatus#SUCCESS OperationStatus.SUCCESS}. 650 */ 651 public OperationStatus getSearchKeyRange(final DatabaseEntry key, 652 final DatabaseEntry pKey, 653 final DatabaseEntry data, 654 LockMode lockMode) 655 throws DatabaseException { 656 657 return OperationStatus.fromInt( 658 dbc.pget(key, pKey, data, 659 DbConstants.DB_SET_RANGE | LockMode.getFlag(lockMode) | 660 ((data == null) ? 0 : data.getMultiFlag()))); 661 } 662 663 /** 664 Move the cursor to the specified secondary and primary key, where both 665the primary and secondary key items must match. 666<p> 667If this method fails for any reason, the position of the cursor will be 668unchanged. 669@throws NullPointerException if a DatabaseEntry parameter is null or 670does not contain a required non-null byte array. 671<p> 672@throws DeadlockException if the operation was selected to resolve a 673deadlock. 674<p> 675@throws IllegalArgumentException if an invalid parameter was specified. 676<p> 677@throws DatabaseException if a failure occurs. 678<p> 679@param key the secondary key 680used as input. It must be initialized with a non-null byte array by the 681caller. 682@param pKey the primary key 683used as input. It must be initialized with a non-null byte array by the 684caller. 685@param data the primary data 686returned as output. Its byte array does not need to be initialized by the 687caller. 688@param lockMode the locking attributes; if null, default attributes are used. 689@return {@link com.sleepycat.db.OperationStatus#NOTFOUND OperationStatus.NOTFOUND} if no matching key/data pair is 690found; {@link com.sleepycat.db.OperationStatus#KEYEMPTY OperationStatus.KEYEMPTY} if the database is a Queue or Recno database and the specified key exists, but was never explicitly created by the application or was later deleted; otherwise, {@link com.sleepycat.db.OperationStatus#SUCCESS OperationStatus.SUCCESS}. 691 */ 692 public OperationStatus getSearchBoth(final DatabaseEntry key, 693 final DatabaseEntry pKey, 694 final DatabaseEntry data, 695 LockMode lockMode) 696 throws DatabaseException { 697 698 return OperationStatus.fromInt( 699 dbc.pget(key, pKey, data, 700 DbConstants.DB_GET_BOTH | LockMode.getFlag(lockMode) | 701 ((data == null) ? 0 : data.getMultiFlag()))); 702 } 703 704 /** 705 Move the cursor to the specified secondary key and closest matching primary 706key of the database. 707<p> 708In the case of any database supporting sorted duplicate sets, the returned 709key/data pair is for the smallest primary key greater than or equal to the 710specified primary key (as determined by the key comparison function), 711permitting partial matches and range searches in duplicate data sets. 712<p> 713If this method fails for any reason, the position of the cursor will be 714unchanged. 715@throws NullPointerException if a DatabaseEntry parameter is null or 716does not contain a required non-null byte array. 717<p> 718@throws DeadlockException if the operation was selected to resolve a 719deadlock. 720<p> 721@throws IllegalArgumentException if an invalid parameter was specified. 722<p> 723@throws DatabaseException if a failure occurs. 724<p> 725@param key the secondary key 726used as input and returned as output. It must be initialized with a non-null 727byte array by the caller. 728@param pKey the primary key 729used as input and returned as output. It must be initialized with a non-null 730byte array by the caller. 731@param data the primary data 732returned as output. Its byte array does not need to be initialized by the 733caller. 734@param lockMode the locking attributes; if null, default attributes are used. 735@return {@link com.sleepycat.db.OperationStatus#NOTFOUND OperationStatus.NOTFOUND} if no matching key/data pair is 736found; {@link com.sleepycat.db.OperationStatus#KEYEMPTY OperationStatus.KEYEMPTY} if the database is a Queue or Recno database and the specified key exists, but was never explicitly created by the application or was later deleted; otherwise, {@link com.sleepycat.db.OperationStatus#SUCCESS OperationStatus.SUCCESS}. 737 */ 738 public OperationStatus getSearchBothRange(final DatabaseEntry key, 739 final DatabaseEntry pKey, 740 final DatabaseEntry data, 741 LockMode lockMode) 742 throws DatabaseException { 743 744 return OperationStatus.fromInt( 745 dbc.pget(key, pKey, data, 746 DbConstants.DB_GET_BOTH_RANGE | LockMode.getFlag(lockMode) | 747 ((data == null) ? 0 : data.getMultiFlag()))); 748 } 749 750 /** 751 Move the cursor to the specific numbered record of the database, and 752return the associated key/data pair. 753<p> 754The data field of the specified key must be a byte array containing a 755record number, as described in {@link com.sleepycat.db.DatabaseEntry DatabaseEntry}. This determines 756the record to be retrieved. 757<p> 758For this method to be called, the underlying database must be of type 759Btree, and it must have been configured to support record numbers. 760<p> 761If this method fails for any reason, the position of the cursor will be 762unchanged. 763@throws NullPointerException if a DatabaseEntry parameter is null or 764does not contain a required non-null byte array. 765<p> 766@throws DeadlockException if the operation was selected to resolve a 767deadlock. 768<p> 769@throws IllegalArgumentException if an invalid parameter was specified. 770<p> 771@throws DatabaseException if a failure occurs. 772<p> 773@param secondaryRecno the secondary record number 774used as input. It must be initialized with a non-null byte array by the 775caller. 776@param data the primary data 777returned as output. Multiple results can be retrieved by passing an object 778that is a subclass of {@link com.sleepycat.db.MultipleEntry MultipleEntry}, otherwise its byte array does not 779need to be initialized by the caller. 780@param lockMode the locking attributes; if null, default attributes are used. 781@return {@link com.sleepycat.db.OperationStatus#NOTFOUND OperationStatus.NOTFOUND} if no matching key/data pair is 782found; {@link com.sleepycat.db.OperationStatus#KEYEMPTY OperationStatus.KEYEMPTY} if the database is a Queue or Recno database and the specified key exists, but was never explicitly created by the application or was later deleted; otherwise, {@link com.sleepycat.db.OperationStatus#SUCCESS OperationStatus.SUCCESS}. 783 */ 784 public OperationStatus getSearchRecordNumber( 785 final DatabaseEntry secondaryRecno, 786 final DatabaseEntry pKey, 787 final DatabaseEntry data, 788 LockMode lockMode) 789 throws DatabaseException { 790 791 return OperationStatus.fromInt( 792 dbc.pget(secondaryRecno, pKey, data, 793 DbConstants.DB_SET_RECNO | LockMode.getFlag(lockMode) | 794 ((data == null) ? 0 : data.getMultiFlag()))); 795 } 796} 797