1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 2002,2008 Oracle. All rights reserved. 5 * 6 * $Id: Cursor.java,v 12.11 2008/04/02 13:43:38 bschmeck 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. Cursors are used for operating on collections of 16records, for iterating over a database, and for saving handles to 17individual records, so that they can be modified after they have been 18read. 19<p> 20Cursors may be used by multiple threads, but only serially. That is, 21the application must serialize access to the handle. 22<p> 23If the cursor is to be used to perform operations on behalf of a 24transaction, the cursor must be opened and closed within the context of 25that single transaction. 26<p> 27Once the cursor close method has been called, the handle may not be 28accessed again, regardless of the close method's success or failure. 29<p> 30To obtain a cursor with default attributes: 31<blockquote><pre> 32 Cursor cursor = myDatabase.openCursor(txn, null); 33</pre></blockquote> 34To customize the attributes of a cursor, use a CursorConfig object. 35<blockquote><pre> 36 CursorConfig config = new CursorConfig(); 37 config.setDirtyRead(true); 38 Cursor cursor = myDatabase.openCursor(txn, config); 39</pre></blockquote> 40<p> 41Modifications to the database during a sequential scan will be reflected 42in the scan; that is, records inserted behind a cursor will not be 43returned while records inserted in front of a cursor will be returned. 44In Queue and Recno databases, missing entries (that is, entries that 45were never explicitly created or that were created and then deleted) 46will be ignored during a sequential scan. 47*/ 48public class Cursor { 49 /* package */ Dbc dbc; 50 /* package */ Database database; 51 /* package */ CursorConfig config; 52 53 // Constructor needed by Java RPC server 54 protected Cursor(final Database database, final CursorConfig config) { 55 this.database = database; 56 this.config = config; 57 } 58 59 Cursor(final Database database, final Dbc dbc, final CursorConfig config) 60 throws DatabaseException { 61 62 this.database = database; 63 this.dbc = dbc; 64 this.config = config; 65 } 66 67 public synchronized void close() 68 throws DatabaseException { 69 70 if (dbc != null) { 71 try { 72 dbc.close(); 73 } finally { 74 dbc = null; 75 } 76 } 77 } 78 79 /** 80 Return a new cursor with the same transaction and locker ID as the 81 original cursor. 82 <p> 83 This is useful when an application is using locking and requires two 84 or more cursors in the same thread of control. 85 <p> 86 @param samePosition 87 If true, the newly created cursor is initialized to refer to the 88 same position in the database as the original cursor (if any) and 89 hold the same locks (if any). If false, or the original cursor does 90 not hold a database position and locks, the returned cursor is 91 uninitialized and will behave like a newly created cursor. 92 <p> 93 @return 94 A new cursor with the same transaction and locker ID as the original 95 cursor. 96 <p> 97 <p> 98@throws DatabaseException if a failure occurs. 99 */ 100 public Cursor dup(final boolean samePosition) 101 throws DatabaseException { 102 103 return new Cursor(database, 104 dbc.dup(samePosition ? DbConstants.DB_POSITION : 0), config); 105 } 106 107 /** 108 Return this cursor's configuration. 109 <p> 110 This may differ from the configuration used to open this object if 111 the cursor existed previously. 112 <p> 113 @return 114 This cursor's configuration. 115 <p> 116 <p> 117@throws DatabaseException if a failure occurs. 118 */ 119 public CursorConfig getConfig() { 120 return config; 121 } 122 123 /** 124 Return the Database handle associated with this Cursor. 125 <p> 126 @return 127 The Database handle associated with this Cursor. 128 <p> 129 */ 130 public Database getDatabase() { 131 return database; 132 } 133 134 /** 135 Return a count of the number of data items for the key to which the 136 cursor refers. 137 <p> 138 @return 139 A count of the number of data items for the key to which the cursor 140 refers. 141 <p> 142 <p> 143@throws DeadlockException if the operation was selected to resolve a 144deadlock. 145<p> 146@throws DatabaseException if a failure occurs. 147 */ 148 public int count() 149 throws DatabaseException { 150 151 return dbc.count(0); 152 } 153 154 /** 155 Delete the key/data pair to which the cursor refers. 156 <p> 157 When called on a cursor opened on a database that has been made into a 158 secondary index, this method the key/data pair from the primary database 159 and all secondary indices. 160 <p> 161 The cursor position is unchanged after a delete, and subsequent calls 162to cursor functions expecting the cursor to refer to an existing key 163will fail. 164 <p> 165 <p> 166@throws DeadlockException if the operation was selected to resolve a 167deadlock. 168<p> 169@throws DatabaseException if a failure occurs. 170 */ 171 public OperationStatus delete() 172 throws DatabaseException { 173 174 return OperationStatus.fromInt(dbc.del(0)); 175 } 176 177 /** 178 Returns the key/data pair to which the cursor refers. 179<p> 180If this method fails for any reason, the position of the cursor will be 181unchanged. 182@throws NullPointerException if a DatabaseEntry parameter is null or 183does not contain a required non-null byte array. 184<p> 185@throws DeadlockException if the operation was selected to resolve a 186deadlock. 187<p> 188@throws IllegalArgumentException if an invalid parameter was specified. 189<p> 190@throws DatabaseException if a failure occurs. 191<p> 192@param key the key 193returned as output. Its byte array does not need to be initialized by the 194caller. 195@param data the data 196returned as output. Multiple results can be retrieved by passing an object 197that is a subclass of {@link com.sleepycat.db.MultipleEntry MultipleEntry}, otherwise its byte array does not 198need to be initialized by the caller. 199@param lockMode the locking attributes; if null, default attributes are used. 200@return {@link com.sleepycat.db.OperationStatus#KEYEMPTY OperationStatus.KEYEMPTY} if the key/pair at the cursor 201position has been deleted; otherwise, {@link com.sleepycat.db.OperationStatus#SUCCESS OperationStatus.SUCCESS}. 202 */ 203 public OperationStatus getCurrent(final DatabaseEntry key, 204 final DatabaseEntry data, 205 LockMode lockMode) 206 throws DatabaseException { 207 208 return OperationStatus.fromInt( 209 dbc.get(key, data, DbConstants.DB_CURRENT | 210 LockMode.getFlag(lockMode) | 211 ((data == null) ? 0 : data.getMultiFlag()))); 212 } 213 214 /** 215 Move the cursor to the first key/data pair of the database, and return 216that pair. If the first key has duplicate values, the first data item 217in the set of duplicates is returned. 218<p> 219If this method fails for any reason, the position of the cursor will be 220unchanged. 221@throws NullPointerException if a DatabaseEntry parameter is null or 222does not contain a required non-null byte array. 223<p> 224@throws DeadlockException if the operation was selected to resolve a 225deadlock. 226<p> 227@throws IllegalArgumentException if an invalid parameter was specified. 228<p> 229@throws DatabaseException if a failure occurs. 230<p> 231@param key the key 232returned as output. Its byte array does not need to be initialized by the 233caller. 234@param data the data 235returned as output. Multiple results can be retrieved by passing an object 236that is a subclass of {@link com.sleepycat.db.MultipleEntry MultipleEntry}, otherwise its byte array does not 237need to be initialized by the caller. 238@param lockMode the locking attributes; if null, default attributes are used. 239@return {@link com.sleepycat.db.OperationStatus#NOTFOUND OperationStatus.NOTFOUND} if no matching key/data pair is 240found; {@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}. 241 */ 242 public OperationStatus getFirst(final DatabaseEntry key, 243 final DatabaseEntry data, 244 LockMode lockMode) 245 throws DatabaseException { 246 247 return OperationStatus.fromInt( 248 dbc.get(key, data, DbConstants.DB_FIRST | 249 LockMode.getFlag(lockMode) | 250 ((data == null) ? 0 : data.getMultiFlag()))); 251 } 252 253 /** 254 Move the cursor to the last key/data pair of the database, and return 255that pair. If the last key has duplicate values, the last data item in 256the set of duplicates is returned. 257<p> 258If this method fails for any reason, the position of the cursor will be 259unchanged. 260@throws NullPointerException if a DatabaseEntry parameter is null or 261does not contain a required non-null byte array. 262<p> 263@throws DeadlockException if the operation was selected to resolve a 264deadlock. 265<p> 266@throws IllegalArgumentException if an invalid parameter was specified. 267<p> 268@throws DatabaseException if a failure occurs. 269<p> 270@param key the key 271returned as output. Its byte array does not need to be initialized by the 272caller. 273@param data the data 274returned as output. Its byte array does not need to be initialized by the 275caller. 276@param lockMode the locking attributes; if null, default attributes are used. 277@return {@link com.sleepycat.db.OperationStatus#NOTFOUND OperationStatus.NOTFOUND} if no matching key/data pair is 278found; {@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}. 279 */ 280 public OperationStatus getLast(final DatabaseEntry key, 281 final DatabaseEntry data, 282 LockMode lockMode) 283 throws DatabaseException { 284 285 return OperationStatus.fromInt( 286 dbc.get(key, data, DbConstants.DB_LAST | 287 LockMode.getFlag(lockMode) | 288 ((data == null) ? 0 : data.getMultiFlag()))); 289 } 290 291 /** 292 Move the cursor to the next key/data pair and return that pair. If 293the matching key has duplicate values, the first data item in the set 294of duplicates is returned. 295<p> 296If the cursor is not yet initialized, move the cursor to the first 297key/data pair of the database, and return that pair. Otherwise, the 298cursor is moved to the next key/data pair of the database, and that pair 299is returned. In the presence of duplicate key values, the value of the 300key may not change. 301<p> 302If this method fails for any reason, the position of the cursor will be 303unchanged. 304@throws NullPointerException if a DatabaseEntry parameter is null or 305does not contain a required non-null byte array. 306<p> 307@throws DeadlockException if the operation was selected to resolve a 308deadlock. 309<p> 310@throws IllegalArgumentException if an invalid parameter was specified. 311<p> 312@throws DatabaseException if a failure occurs. 313<p> 314@param key the key 315returned as output. Its byte array does not need to be initialized by the 316caller. 317@param data the data 318returned as output. Multiple results can be retrieved by passing an object 319that is a subclass of {@link com.sleepycat.db.MultipleEntry MultipleEntry}, otherwise its byte array does not 320need to be initialized by the caller. 321@param lockMode the locking attributes; if null, default attributes are used. 322@return {@link com.sleepycat.db.OperationStatus#NOTFOUND OperationStatus.NOTFOUND} if no matching key/data pair is 323found; {@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}. 324 */ 325 public OperationStatus getNext(final DatabaseEntry key, 326 final DatabaseEntry data, 327 LockMode lockMode) 328 throws DatabaseException { 329 330 return OperationStatus.fromInt( 331 dbc.get(key, data, DbConstants.DB_NEXT | 332 LockMode.getFlag(lockMode) | 333 ((data == null) ? 0 : data.getMultiFlag()))); 334 } 335 336 /** 337 If the next key/data pair of the database is a duplicate data record for 338the current key/data pair, move the cursor to the next key/data pair 339of the database and return that pair. 340<p> 341If this method fails for any reason, the position of the cursor will be 342unchanged. 343@throws NullPointerException if a DatabaseEntry parameter is null or 344does not contain a required non-null byte array. 345<p> 346@throws DeadlockException if the operation was selected to resolve a 347deadlock. 348<p> 349@throws IllegalArgumentException if an invalid parameter was specified. 350<p> 351@throws DatabaseException if a failure occurs. 352<p> 353@param key the key 354returned as output. Its byte array does not need to be initialized by the 355caller. 356@param data the data 357returned as output. Multiple results can be retrieved by passing an object 358that is a subclass of {@link com.sleepycat.db.MultipleEntry MultipleEntry}, otherwise its byte array does not 359need to be initialized by the caller. 360@param lockMode the locking attributes; if null, default attributes are used. 361@return {@link com.sleepycat.db.OperationStatus#NOTFOUND OperationStatus.NOTFOUND} if no matching key/data pair is 362found; {@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}. 363 */ 364 public OperationStatus getNextDup(final DatabaseEntry key, 365 final DatabaseEntry data, 366 LockMode lockMode) 367 throws DatabaseException { 368 369 return OperationStatus.fromInt( 370 dbc.get(key, data, DbConstants.DB_NEXT_DUP | 371 LockMode.getFlag(lockMode) | 372 ((data == null) ? 0 : data.getMultiFlag()))); 373 } 374 375 /** 376 Move the cursor to the next non-duplicate key/data pair and return 377that pair. If the matching key has duplicate values, the first data 378item in the set of duplicates is returned. 379<p> 380If the cursor is not yet initialized, move the cursor to the first 381key/data pair of the database, and return that pair. Otherwise, the 382cursor is moved to the next non-duplicate key of the database, and that 383key/data pair is returned. 384<p> 385If this method fails for any reason, the position of the cursor will be 386unchanged. 387@throws NullPointerException if a DatabaseEntry parameter is null or 388does not contain a required non-null byte array. 389<p> 390@throws DeadlockException if the operation was selected to resolve a 391deadlock. 392<p> 393@throws IllegalArgumentException if an invalid parameter was specified. 394<p> 395@throws DatabaseException if a failure occurs. 396<p> 397@param key the key 398returned as output. Its byte array does not need to be initialized by the 399caller. 400@param data the data 401returned as output. Multiple results can be retrieved by passing an object 402that is a subclass of {@link com.sleepycat.db.MultipleEntry MultipleEntry}, otherwise its byte array does not 403need to be initialized by the caller. 404@param lockMode the locking attributes; if null, default attributes are used. 405@return {@link com.sleepycat.db.OperationStatus#NOTFOUND OperationStatus.NOTFOUND} if no matching key/data pair is 406found; {@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}. 407 */ 408 public OperationStatus getNextNoDup(final DatabaseEntry key, 409 final DatabaseEntry data, 410 LockMode lockMode) 411 throws DatabaseException { 412 413 return OperationStatus.fromInt( 414 dbc.get(key, data, DbConstants.DB_NEXT_NODUP | 415 LockMode.getFlag(lockMode) | 416 ((data == null) ? 0 : data.getMultiFlag()))); 417 } 418 419 /** 420 Move the cursor to the previous key/data pair and return that pair. 421If the matching key has duplicate values, the last data item in the set 422of duplicates is returned. 423<p> 424If the cursor is not yet initialized, move the cursor to the last 425key/data pair of the database, and return that pair. Otherwise, the 426cursor is moved to the previous key/data pair of the database, and that 427pair is returned. In the presence of duplicate key values, the value of 428the key may not change. 429<p> 430If this method fails for any reason, the position of the cursor will be 431unchanged. 432@throws NullPointerException if a DatabaseEntry parameter is null or 433does not contain a required non-null byte array. 434<p> 435@throws DeadlockException if the operation was selected to resolve a 436deadlock. 437<p> 438@throws IllegalArgumentException if an invalid parameter was specified. 439<p> 440@throws DatabaseException if a failure occurs. 441<p> 442@param key the key 443returned as output. Its byte array does not need to be initialized by the 444caller. 445@param data the data 446returned as output. Its byte array does not need to be initialized by the 447caller. 448@param lockMode the locking attributes; if null, default attributes are used. 449@return {@link com.sleepycat.db.OperationStatus#NOTFOUND OperationStatus.NOTFOUND} if no matching key/data pair is 450found; {@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}. 451 */ 452 public OperationStatus getPrev(final DatabaseEntry key, 453 final DatabaseEntry data, 454 LockMode lockMode) 455 throws DatabaseException { 456 457 return OperationStatus.fromInt( 458 dbc.get(key, data, DbConstants.DB_PREV | 459 LockMode.getFlag(lockMode) | 460 ((data == null) ? 0 : data.getMultiFlag()))); 461 } 462 463 /** 464 If the previous key/data pair of the database is a duplicate data record 465for the current key/data pair, move the cursor to the previous key/data 466pair of the database and return that pair. 467<p> 468If this method fails for any reason, the position of the cursor will be 469unchanged. 470@throws NullPointerException if a DatabaseEntry parameter is null or 471does not contain a required non-null byte array. 472<p> 473@throws DeadlockException if the operation was selected to resolve a 474deadlock. 475<p> 476@throws IllegalArgumentException if an invalid parameter was specified. 477<p> 478@throws DatabaseException if a failure occurs. 479<p> 480@param key the key 481returned as output. Its byte array does not need to be initialized by the 482caller. 483@param data the data 484returned as output. Its byte array does not need to be initialized by the 485caller. 486@param lockMode the locking attributes; if null, default attributes are used. 487@return {@link com.sleepycat.db.OperationStatus#NOTFOUND OperationStatus.NOTFOUND} if no matching key/data pair is 488found; {@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}. 489 */ 490 public OperationStatus getPrevDup(final DatabaseEntry key, 491 final DatabaseEntry data, 492 LockMode lockMode) 493 throws DatabaseException { 494 495 return OperationStatus.fromInt( 496 dbc.get(key, data, DbConstants.DB_PREV_DUP | 497 LockMode.getFlag(lockMode) | 498 ((data == null) ? 0 : data.getMultiFlag()))); 499 } 500 501 /** 502 Move the cursor to the previous non-duplicate key/data pair and return 503that pair. If the matching key has duplicate values, the last data item 504in the set of duplicates is returned. 505<p> 506If the cursor is not yet initialized, move the cursor to the last 507key/data pair of the database, and return that pair. Otherwise, the 508cursor is moved to the previous non-duplicate key of the database, and 509that key/data pair is returned. 510<p> 511If this method fails for any reason, the position of the cursor will be 512unchanged. 513@throws NullPointerException if a DatabaseEntry parameter is null or 514does not contain a required non-null byte array. 515<p> 516@throws DeadlockException if the operation was selected to resolve a 517deadlock. 518<p> 519@throws IllegalArgumentException if an invalid parameter was specified. 520<p> 521@throws DatabaseException if a failure occurs. 522<p> 523@param key the key 524returned as output. Its byte array does not need to be initialized by the 525caller. 526@param data the data 527returned as output. Its byte array does not need to be initialized by the 528caller. 529@param lockMode the locking attributes; if null, default attributes are used. 530@return {@link com.sleepycat.db.OperationStatus#NOTFOUND OperationStatus.NOTFOUND} if no matching key/data pair is 531found; {@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}. 532 */ 533 public OperationStatus getPrevNoDup(final DatabaseEntry key, 534 final DatabaseEntry data, 535 LockMode lockMode) 536 throws DatabaseException { 537 538 return OperationStatus.fromInt( 539 dbc.get(key, data, DbConstants.DB_PREV_NODUP | 540 LockMode.getFlag(lockMode) | 541 ((data == null) ? 0 : data.getMultiFlag()))); 542 } 543 544 /** 545 Return the record number associated with the cursor. The record number 546will be returned in the data parameter. 547<p> 548For this method to be called, the underlying database must be of type 549Btree, and it must have been configured to support record numbers. 550<p> 551If this method fails for any reason, the position of the cursor will be 552unchanged. 553@throws NullPointerException if a DatabaseEntry parameter is null or 554does not contain a required non-null byte array. 555<p> 556@throws DeadlockException if the operation was selected to resolve a 557deadlock. 558<p> 559@throws IllegalArgumentException if an invalid parameter was specified. 560<p> 561@throws DatabaseException if a failure occurs. 562<p> 563@param data the data 564returned as output. Its byte array does not need to be initialized by the 565caller. 566@param lockMode the locking attributes; if null, default attributes are used. 567@return {@link com.sleepycat.db.OperationStatus#NOTFOUND OperationStatus.NOTFOUND} if no matching key/data pair is 568found; {@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}. 569 */ 570 public OperationStatus getRecordNumber(final DatabaseEntry data, 571 LockMode lockMode) 572 throws DatabaseException { 573 574 return OperationStatus.fromInt( 575 dbc.get(DatabaseEntry.IGNORE, data, 576 DbConstants.DB_GET_RECNO | 577 LockMode.getFlag(lockMode) | 578 ((data == null) ? 0 : data.getMultiFlag()))); 579 } 580 581 /** 582 Move the cursor to the given key of the database, and return the datum 583associated with the given key. If the matching key has duplicate 584values, the first data item in the set of duplicates is returned. 585<p> 586If this method fails for any reason, the position of the cursor will be 587unchanged. 588@throws NullPointerException if a DatabaseEntry parameter is null or 589does not contain a required non-null byte array. 590<p> 591@throws DeadlockException if the operation was selected to resolve a 592deadlock. 593<p> 594@throws IllegalArgumentException if an invalid parameter was specified. 595<p> 596@throws DatabaseException if a failure occurs. 597<p> 598@param key the key 599used as input. It must be initialized with a non-null byte array by the 600caller. 601@param data the data 602returned as output. Multiple results can be retrieved by passing an object 603that is a subclass of {@link com.sleepycat.db.MultipleEntry MultipleEntry}, otherwise its byte array does not 604need to be initialized by the caller. 605@param lockMode the locking attributes; if null, default attributes are used. 606@return {@link com.sleepycat.db.OperationStatus#NOTFOUND OperationStatus.NOTFOUND} if no matching key/data pair is 607found; {@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}. 608 */ 609 public OperationStatus getSearchKey(final DatabaseEntry key, 610 final DatabaseEntry data, 611 LockMode lockMode) 612 throws DatabaseException { 613 614 return OperationStatus.fromInt( 615 dbc.get(key, data, DbConstants.DB_SET | 616 LockMode.getFlag(lockMode) | 617 ((data == null) ? 0 : data.getMultiFlag()))); 618 } 619 620 /** 621 Move the cursor to the closest matching key of the database, and return 622the data item associated with the matching key. If the matching key has 623duplicate values, the first data item in the set of duplicates is returned. 624<p> 625The returned key/data pair is for the smallest key greater than or equal 626to the specified key (as determined by the key comparison function), 627permitting partial key matches and range searches. 628<p> 629If this method fails for any reason, the position of the cursor will be 630unchanged. 631@throws NullPointerException if a DatabaseEntry parameter is null or 632does not contain a required non-null byte array. 633<p> 634@throws DeadlockException if the operation was selected to resolve a 635deadlock. 636<p> 637@throws IllegalArgumentException if an invalid parameter was specified. 638<p> 639@throws DatabaseException if a failure occurs. 640<p> 641@param key the key 642used as input and returned as output. It must be initialized with a non-null 643byte array by the caller. 644@param data the data 645returned as output. Multiple results can be retrieved by passing an object 646that is a subclass of {@link com.sleepycat.db.MultipleEntry MultipleEntry}, otherwise its byte array does not 647need to be initialized by the caller. 648@param lockMode the locking attributes; if null, default attributes are used. 649@return {@link com.sleepycat.db.OperationStatus#NOTFOUND OperationStatus.NOTFOUND} if no matching key/data pair is 650found; {@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}. 651 */ 652 public OperationStatus getSearchKeyRange(final DatabaseEntry key, 653 final DatabaseEntry data, 654 LockMode lockMode) 655 throws DatabaseException { 656 657 return OperationStatus.fromInt( 658 dbc.get(key, data, DbConstants.DB_SET_RANGE | 659 LockMode.getFlag(lockMode) | 660 ((data == null) ? 0 : data.getMultiFlag()))); 661 } 662 663 /** 664 Move the cursor to the specified key/data pair, where both the key and 665data 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 key 680used as input. It must be initialized with a non-null byte array by the 681caller. 682@param data the data 683used as input. It must be initialized with a non-null byte array by the 684caller. 685@param lockMode the locking attributes; if null, default attributes are used. 686@return {@link com.sleepycat.db.OperationStatus#NOTFOUND OperationStatus.NOTFOUND} if no matching key/data pair is 687found; {@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}. 688 */ 689 public OperationStatus getSearchBoth(final DatabaseEntry key, 690 final DatabaseEntry data, 691 LockMode lockMode) 692 throws DatabaseException { 693 694 return OperationStatus.fromInt( 695 dbc.get(key, data, DbConstants.DB_GET_BOTH | 696 LockMode.getFlag(lockMode) | 697 ((data == null) ? 0 : data.getMultiFlag()))); 698 } 699 700 /** 701 Move the cursor to the specified key and closest matching data item of the 702database. 703<p> 704In the case of any database supporting sorted duplicate sets, the returned 705key/data pair is for the smallest data item greater than or equal to the 706specified data item (as determined by the duplicate comparison function), 707permitting partial matches and range searches in duplicate data sets. 708<p> 709If this method fails for any reason, the position of the cursor will be 710unchanged. 711@throws NullPointerException if a DatabaseEntry parameter is null or 712does not contain a required non-null byte array. 713<p> 714@throws DeadlockException if the operation was selected to resolve a 715deadlock. 716<p> 717@throws IllegalArgumentException if an invalid parameter was specified. 718<p> 719@throws DatabaseException if a failure occurs. 720<p> 721@param key the key 722used as input and returned as output. It must be initialized with a non-null 723byte array by the caller. 724@param data the data 725used as input and returned as output. It must be initialized with a non-null 726byte array by the caller. 727@param lockMode the locking attributes; if null, default attributes are used. 728@return {@link com.sleepycat.db.OperationStatus#NOTFOUND OperationStatus.NOTFOUND} if no matching key/data pair is 729found; {@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}. 730 */ 731 public OperationStatus getSearchBothRange(final DatabaseEntry key, 732 final DatabaseEntry data, 733 LockMode lockMode) 734 throws DatabaseException { 735 736 return OperationStatus.fromInt( 737 dbc.get(key, data, 738 DbConstants.DB_GET_BOTH_RANGE | 739 LockMode.getFlag(lockMode) | 740 ((data == null) ? 0 : data.getMultiFlag()))); 741 } 742 743 /** 744 Move the cursor to the specific numbered record of the database, and 745return the associated key/data pair. 746<p> 747The data field of the specified key must be a byte array containing a 748record number, as described in {@link com.sleepycat.db.DatabaseEntry DatabaseEntry}. This determines 749the record to be retrieved. 750<p> 751For this method to be called, the underlying database must be of type 752Btree, and it must have been configured to support record numbers. 753<p> 754If this method fails for any reason, the position of the cursor will be 755unchanged. 756@throws NullPointerException if a DatabaseEntry parameter is null or 757does not contain a required non-null byte array. 758<p> 759@throws DeadlockException if the operation was selected to resolve a 760deadlock. 761<p> 762@throws IllegalArgumentException if an invalid parameter was specified. 763<p> 764@throws DatabaseException if a failure occurs. 765<p> 766@param key the key 767returned as output. Its byte array does not need to be initialized by the 768caller. 769@param data the data 770returned as output. Multiple results can be retrieved by passing an object 771that is a subclass of {@link com.sleepycat.db.MultipleEntry MultipleEntry}, otherwise its byte array does not 772need to be initialized by the caller. 773@param lockMode the locking attributes; if null, default attributes are used. 774@return {@link com.sleepycat.db.OperationStatus#NOTFOUND OperationStatus.NOTFOUND} if no matching key/data pair is 775found; {@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}. 776 */ 777 public OperationStatus getSearchRecordNumber(final DatabaseEntry key, 778 final DatabaseEntry data, 779 LockMode lockMode) 780 throws DatabaseException { 781 782 return OperationStatus.fromInt( 783 dbc.get(key, data, DbConstants.DB_SET_RECNO | 784 LockMode.getFlag(lockMode) | 785 ((data == null) ? 0 : data.getMultiFlag()))); 786 } 787 788 /** 789 Store a key/data pair into the database. 790<p> 791If the put method succeeds, the cursor is always positioned to refer to 792the newly inserted item. If the put method fails for any reason, the 793state of the cursor will be unchanged. 794<p> 795If the key already appears in the database and duplicates are supported, 796the new data value is inserted at the correct sorted location. If the 797key already appears in the database and duplicates are not supported, 798the existing key/data pair will be replaced. 799<p> 800@param key the key {@link com.sleepycat.db.DatabaseEntry DatabaseEntry} operated on. 801<p> 802@param data the data {@link com.sleepycat.db.DatabaseEntry DatabaseEntry} stored. 803<p> 804<p> 805@throws DeadlockException if the operation was selected to resolve a 806deadlock. 807<p> 808@throws IllegalArgumentException if an invalid parameter was specified. 809<p> 810@throws DatabaseException if a failure occurs. 811 */ 812 public OperationStatus put(final DatabaseEntry key, 813 final DatabaseEntry data) 814 throws DatabaseException { 815 816 return OperationStatus.fromInt( 817 dbc.put(key, data, DbConstants.DB_KEYLAST)); 818 } 819 820 /** 821 Store a key/data pair into the database. 822<p> 823If the putAfter method succeeds, the cursor is always positioned to refer to 824the newly inserted item. If the putAfter method fails for any reason, the 825state of the cursor will be unchanged. 826<p> 827In the case of the Btree and Hash access methods, insert the data 828element as a duplicate element of the key to which the cursor refers. 829The new element appears immediately 830after 831the current cursor position. It is an error to call this method if the 832underlying Btree or Hash database does not support duplicate data items. 833The key parameter is ignored. 834<p> 835In the case of the Hash access method, the putAfter method will fail and 836throw an exception if the current cursor record has already been deleted. 837<p> 838In the case of the Recno access method, it is an error to call this 839method if the underlying Recno database was not configured to have 840mutable record numbers. A new key is created, all records after the 841inserted item are automatically renumbered, and the key of the new 842record is returned in the key parameter. The initial value of the key 843parameter is ignored. 844<p> 845The putAfter method may not be called for the Queue access method. 846<p> 847@param key the key {@link com.sleepycat.db.DatabaseEntry DatabaseEntry} operated on. 848<p> 849@param data the data {@link com.sleepycat.db.DatabaseEntry DatabaseEntry} stored. 850<p> 851<p> 852@throws DeadlockException if the operation was selected to resolve a 853deadlock. 854<p> 855@throws IllegalArgumentException if an invalid parameter was specified. 856<p> 857@throws DatabaseException if a failure occurs. 858 */ 859 public OperationStatus putAfter(final DatabaseEntry key, 860 final DatabaseEntry data) 861 throws DatabaseException { 862 863 return OperationStatus.fromInt( 864 dbc.put(key, data, DbConstants.DB_AFTER)); 865 } 866 867 /** 868 Store a key/data pair into the database. 869<p> 870If the putBefore method succeeds, the cursor is always positioned to refer to 871the newly inserted item. If the putBefore method fails for any reason, the 872state of the cursor will be unchanged. 873<p> 874In the case of the Btree and Hash access methods, insert the data 875element as a duplicate element of the key to which the cursor refers. 876The new element appears immediately 877before 878the current cursor position. It is an error to call this method if the 879underlying Btree or Hash database does not support duplicate data items. 880The key parameter is ignored. 881<p> 882In the case of the Hash access method, the putBefore method will fail and 883throw an exception if the current cursor record has already been deleted. 884<p> 885In the case of the Recno access method, it is an error to call this 886method if the underlying Recno database was not configured to have 887mutable record numbers. A new key is created, all records after the 888inserted item are automatically renumbered, and the key of the new 889record is returned in the key parameter. The initial value of the key 890parameter is ignored. 891<p> 892The putBefore method may not be called for the Queue access method. 893<p> 894@param key the key {@link com.sleepycat.db.DatabaseEntry DatabaseEntry} operated on. 895<p> 896@param data the data {@link com.sleepycat.db.DatabaseEntry DatabaseEntry} stored. 897<p> 898<p> 899@throws DeadlockException if the operation was selected to resolve a 900deadlock. 901<p> 902@throws IllegalArgumentException if an invalid parameter was specified. 903<p> 904@throws DatabaseException if a failure occurs. 905 */ 906 public OperationStatus putBefore(final DatabaseEntry key, 907 final DatabaseEntry data) 908 throws DatabaseException { 909 910 return OperationStatus.fromInt( 911 dbc.put(key, data, DbConstants.DB_BEFORE)); 912 } 913 914 /** 915 Store a key/data pair into the database. 916<p> 917If the putNoOverwrite method succeeds, the cursor is always positioned to refer to 918the newly inserted item. If the putNoOverwrite method fails for any reason, the 919state of the cursor will be unchanged. 920<p> 921If the key already appears in the database, putNoOverwrite will return 922{@link com.sleepycat.db.OperationStatus#KEYEXIST OperationStatus.KEYEXIST}. 923<p> 924@param key the key {@link com.sleepycat.db.DatabaseEntry DatabaseEntry} operated on. 925<p> 926@param data the data {@link com.sleepycat.db.DatabaseEntry DatabaseEntry} stored. 927<p> 928<p> 929@throws DeadlockException if the operation was selected to resolve a 930deadlock. 931<p> 932@throws IllegalArgumentException if an invalid parameter was specified. 933<p> 934@throws DatabaseException if a failure occurs. 935 */ 936 public OperationStatus putNoOverwrite(final DatabaseEntry key, 937 final DatabaseEntry data) 938 throws DatabaseException { 939 940 /* 941 * The tricks here are making sure the cursor doesn't move on error and 942 * noticing that if the key exists, that's an error and we don't want 943 * to return the data. 944 */ 945 Dbc tempDbc = dbc.dup(0); 946 try { 947 int errCode = tempDbc.get(key, DatabaseEntry.IGNORE, 948 DbConstants.DB_SET | database.rmwFlag); 949 if (errCode == 0) 950 return OperationStatus.KEYEXIST; 951 else if (errCode != DbConstants.DB_NOTFOUND && 952 errCode != DbConstants.DB_KEYEMPTY) 953 return OperationStatus.fromInt(errCode); 954 else { 955 Dbc tdbc = dbc; 956 dbc = tempDbc; 957 tempDbc = tdbc; 958 959 return OperationStatus.fromInt( 960 dbc.put(key, data, DbConstants.DB_KEYLAST)); 961 } 962 } finally { 963 tempDbc.close(); 964 } 965 } 966 967 /** 968 Store a key/data pair into the database. 969<p> 970If the putKeyFirst method succeeds, the cursor is always positioned to refer to 971the newly inserted item. If the putKeyFirst method fails for any reason, the 972state of the cursor will be unchanged. 973<p> 974In the case of the Btree and Hash access methods, insert the specified 975key/data pair into the database. 976<p> 977If the underlying database supports duplicate data items, and if the 978key already exists in the database and a duplicate sort function has 979been specified, the inserted data item is added in its sorted location. 980If the key already exists in the database and no duplicate sort function 981has been specified, the inserted data item is added as the 982first 983of the data items for that key. 984<p> 985The putKeyFirst method may not be called for the Queue or Recno access methods. 986<p> 987@param key the key {@link com.sleepycat.db.DatabaseEntry DatabaseEntry} operated on. 988<p> 989@param data the data {@link com.sleepycat.db.DatabaseEntry DatabaseEntry} stored. 990<p> 991<p> 992@throws DeadlockException if the operation was selected to resolve a 993deadlock. 994<p> 995@throws IllegalArgumentException if an invalid parameter was specified. 996<p> 997@throws DatabaseException if a failure occurs. 998 */ 999 public OperationStatus putKeyFirst(final DatabaseEntry key, 1000 final DatabaseEntry data) 1001 throws DatabaseException { 1002 1003 return OperationStatus.fromInt( 1004 dbc.put(key, data, DbConstants.DB_KEYFIRST)); 1005 } 1006 1007 /** 1008 Store a key/data pair into the database. 1009<p> 1010If the putKeyLast method succeeds, the cursor is always positioned to refer to 1011the newly inserted item. If the putKeyLast method fails for any reason, the 1012state of the cursor will be unchanged. 1013<p> 1014In the case of the Btree and Hash access methods, insert the specified 1015key/data pair into the database. 1016<p> 1017If the underlying database supports duplicate data items, and if the 1018key already exists in the database and a duplicate sort function has 1019been specified, the inserted data item is added in its sorted location. 1020If the key already exists in the database and no duplicate sort function 1021has been specified, the inserted data item is added as the 1022last 1023of the data items for that key. 1024<p> 1025The putKeyLast method may not be called for the Queue or Recno access methods. 1026<p> 1027@param key the key {@link com.sleepycat.db.DatabaseEntry DatabaseEntry} operated on. 1028<p> 1029@param data the data {@link com.sleepycat.db.DatabaseEntry DatabaseEntry} stored. 1030<p> 1031<p> 1032@throws DeadlockException if the operation was selected to resolve a 1033deadlock. 1034<p> 1035@throws IllegalArgumentException if an invalid parameter was specified. 1036<p> 1037@throws DatabaseException if a failure occurs. 1038 */ 1039 public OperationStatus putKeyLast(final DatabaseEntry key, 1040 final DatabaseEntry data) 1041 throws DatabaseException { 1042 1043 return OperationStatus.fromInt( 1044 dbc.put(key, data, DbConstants.DB_KEYLAST)); 1045 } 1046 1047 /** 1048 Store a key/data pair into the database. 1049<p> 1050If the putNoDupData method succeeds, the cursor is always positioned to refer to 1051the newly inserted item. If the putNoDupData method fails for any reason, the 1052state of the cursor will be unchanged. 1053<p> 1054In the case of the Btree and Hash access methods, insert 1055the specified key/data pair into the database, unless a key/data pair 1056comparing equally to it already exists in the database. If a matching 1057key/data pair already exists in the database, {@link com.sleepycat.db.OperationStatus#KEYEXIST OperationStatus.KEYEXIST} is returned. 1058<p> 1059This method may only be called if the underlying database has been 1060configured to support sorted duplicate data items. 1061<p> 1062This method may not be called for the Queue or Recno access methods. 1063<p> 1064@param key the key {@link com.sleepycat.db.DatabaseEntry DatabaseEntry} operated on. 1065<p> 1066@param data the data {@link com.sleepycat.db.DatabaseEntry DatabaseEntry} stored. 1067<p> 1068<p> 1069@throws DeadlockException if the operation was selected to resolve a 1070deadlock. 1071<p> 1072@throws IllegalArgumentException if an invalid parameter was specified. 1073<p> 1074@throws DatabaseException if a failure occurs. 1075 */ 1076 public OperationStatus putNoDupData(final DatabaseEntry key, 1077 final DatabaseEntry data) 1078 throws DatabaseException { 1079 1080 return OperationStatus.fromInt( 1081 dbc.put(key, data, DbConstants.DB_NODUPDATA)); 1082 } 1083 1084 /** 1085 Replaces the data in the key/data pair at the current cursor position. 1086 <p> 1087 Whether the putCurrent method succeeds or fails for any reason, the state 1088 of the cursor will be unchanged. 1089 <p> 1090 Overwrite the data of the key/data pair to which the cursor refers with the 1091 specified data item. This method will return OperationStatus.NOTFOUND if 1092 the cursor currently refers to an already-deleted key/data pair. 1093 <p> 1094 For a database that does not support duplicates, the data may be changed by 1095 this method. If duplicates are supported, the data may be changed only if 1096 a custom partial comparator is configured and the comparator considers the 1097 old and new data to be equal (that is, the comparator returns zero). For 1098 more information on partial comparators see {@link 1099 DatabaseConfig#setDuplicateComparator}. 1100 <p> 1101 If the old and new data are unequal according to the comparator, a {@code 1102 DatabaseException} is thrown. Changing the data in this case would change 1103 the sort order of the record, which would change the cursor position, and 1104 this is not allowed. To change the sort order of a record, delete it and 1105 then re-insert it. 1106 <p> 1107 @param data - the data DatabaseEntry stored. 1108 <br> 1109 @throws DeadlockException - if the operation was selected to resolve a 1110 deadlock. 1111 <br> 1112 @throws IllegalArgumentException - if an invalid parameter was specified. 1113 <br> 1114 @throws DatabaseException - if the old and new data are not equal according 1115 to the configured duplicate comparator or default comparator, or if a 1116 failure occurs. 1117 <br> 1118 */ 1119 public OperationStatus putCurrent(final DatabaseEntry data) 1120 throws DatabaseException { 1121 1122 return OperationStatus.fromInt( 1123 dbc.put(DatabaseEntry.UNUSED, data, DbConstants.DB_CURRENT)); 1124 } 1125 1126 /** 1127 Get the cache priority for pages referenced by the cursor. 1128 <p> 1129 This method may be called at any time during the life of the application. 1130 <p> 1131 <p> 1132@throws DatabaseException if a failure occurs. 1133 */ 1134 public CacheFilePriority getPriority() 1135 throws DatabaseException { 1136 1137 return CacheFilePriority.fromFlag(dbc.get_priority()); 1138 } 1139 1140 /** 1141 Set the cache priority for pages referenced by the DBC handle. 1142 <p> 1143 The priority of a page biases the replacement algorithm to be more or less 1144 likely to discard a page when space is needed in the buffer pool. The bias 1145 is temporary, and pages will eventually be discarded if they are not 1146 referenced again. The DBcursor->set_priority method is only advisory, and 1147 does not guarantee pages will be treated in a specific way. 1148 <p> 1149 This method may be called at any time during the life of the application. 1150 <p> 1151 <p> 1152@throws DatabaseException if a failure occurs. 1153 */ 1154 public void setPriority(final CacheFilePriority priority) 1155 throws DatabaseException { 1156 1157 dbc.set_priority(priority.getFlag()); 1158 } 1159} 1160