1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 2009 Oracle. All rights reserved. 5 * 6 */ 7using System; 8using System.Collections; 9using System.Collections.Generic; 10using System.Text; 11using BerkeleyDB.Internal; 12 13namespace BerkeleyDB { 14 /// <summary> 15 /// A class representing database cursors, which allow for traversal of 16 /// database records. 17 /// </summary> 18 public class Cursor 19 : BaseCursor, 20 IDisposable, IEnumerable<KeyValuePair<DatabaseEntry, DatabaseEntry>> { 21 private KeyValuePair<DatabaseEntry, DatabaseEntry> cur; 22 private KeyValuePair<DatabaseEntry, MultipleDatabaseEntry> curMult; 23 private MultipleKeyDatabaseEntry curMultKey; 24 private DatabaseType dbtype; 25 26 /// <summary> 27 /// Protected member, storing the pagesize of the underlying database. 28 /// Used during bulk get (i.e. Move*Multiple). 29 /// </summary> 30 protected uint pgsz; 31 32 /// <summary> 33 /// Specifies where to place duplicate data elements of the key to which 34 /// the cursor refers. 35 /// </summary> 36 public enum InsertLocation { 37 /// <summary> 38 /// The new element appears immediately after the current cursor 39 /// position. 40 /// </summary> 41 AFTER, 42 /// <summary> 43 /// The new element appears immediately before the current cursor 44 /// position. 45 /// </summary> 46 BEFORE, 47 /// <summary> 48 /// The new element appears as the first of the data items for the 49 /// given key 50 /// </summary> 51 FIRST, 52 /// <summary> 53 /// The new element appears as the last of the data items for the 54 /// given key 55 /// </summary> 56 LAST 57 }; 58 59 /// <summary> 60 /// The key/data pair at which the cursor currently points. 61 /// </summary> 62 /// <remarks> 63 /// Only one of <see cref="Current"/>, <see cref="CurrentMultiple"/> and 64 /// <see cref="CurrentMultipleKey"/> will ever be non-empty. 65 /// </remarks> 66 public KeyValuePair<DatabaseEntry, DatabaseEntry> Current { 67 private set { 68 cur = value; 69 curMult = 70 new KeyValuePair<DatabaseEntry, MultipleDatabaseEntry>(); 71 curMultKey = null; 72 } 73 get { return cur; } 74 } 75 /// <summary> 76 /// The key and multiple data items at which the cursor currently 77 /// points. 78 /// </summary> 79 /// <remarks> 80 /// Only one of <see cref="Current"/>, <see cref="CurrentMultiple"/> and 81 /// <see cref="CurrentMultipleKey"/> will ever be non-empty. 82 /// </remarks> 83 public 84 KeyValuePair<DatabaseEntry, MultipleDatabaseEntry> CurrentMultiple { 85 private set { 86 cur = new KeyValuePair<DatabaseEntry, DatabaseEntry>(); 87 curMult = value; 88 curMultKey = null; 89 } 90 get { return curMult; } 91 } 92 /// <summary> 93 /// The multiple key and data items at which the cursor currently 94 /// points. 95 /// </summary> 96 /// <remarks> 97 /// Only one of <see cref="Current"/>, <see cref="CurrentMultiple"/> and 98 /// <see cref="CurrentMultipleKey"/> will ever be non-empty. 99 /// </remarks> 100 public MultipleKeyDatabaseEntry CurrentMultipleKey { 101 private set { 102 cur = new KeyValuePair<DatabaseEntry, DatabaseEntry>(); 103 curMult = 104 new KeyValuePair<DatabaseEntry, MultipleDatabaseEntry>(); 105 curMultKey = value; 106 } 107 get { return curMultKey; } 108 } 109 private CachePriority _priority; 110 /// <summary> 111 /// The cache priority for pages referenced by the cursor. 112 /// </summary> 113 /// <remarks> 114 /// The priority of a page biases the replacement algorithm to be more 115 /// or less likely to discard a page when space is needed in the buffer 116 /// pool. The bias is temporary, and pages will eventually be discarded 117 /// if they are not referenced again. The setting is only advisory, and 118 /// does not guarantee pages will be treated in a specific way. 119 /// </remarks> 120 public CachePriority Priority { 121 get { return _priority; } 122 set { 123 dbc.set_priority(value.priority); 124 _priority = value; 125 } 126 } 127 128 internal Cursor(DBC dbc, DatabaseType DbType, uint pagesize) 129 : base(dbc) { 130 pgsz = pagesize; 131 dbtype = DbType; 132 } 133 internal Cursor( 134 DBC dbc, DatabaseType DbType, uint pagesize, CachePriority pri) 135 : base(dbc) { 136 Priority = pri; 137 pgsz = pagesize; 138 dbtype = DbType; 139 } 140 141 #region Internal API 142 /* These protected methods do the heavy lifting. The API methods for 143 * Cursor and its subclasses call into them, which allows the API 144 * methods to expose subsets of the arg lists, because some args are 145 * optional. */ 146 147 /* Only BTree and Hash can call this version of Add(). */ 148 /// <summary> 149 /// Protected method for BTree and Hash to insert with KEYFIRST and 150 /// KEYLAST. 151 /// </summary> 152 /// <param name="pair">The key/data pair to add</param> 153 /// <param name="loc">Where to add, if adding duplicate data</param> 154 protected void Add(KeyValuePair<DatabaseEntry, DatabaseEntry> pair, InsertLocation loc) { 155 if (loc == InsertLocation.AFTER) 156 throw new ArgumentException("AFTER may only be specified on Insert()."); 157 if (loc == InsertLocation.BEFORE) 158 throw new ArgumentException("BEFORE may only be specified on Insert()."); 159 Put(pair.Key, pair.Value, (loc == InsertLocation.FIRST) ? DbConstants.DB_KEYFIRST : DbConstants.DB_KEYLAST); 160 } 161 /* Only BTree and Hash can call AddUnique(). */ 162 /// <summary> 163 /// Protected method for BTree and Hash to insert with NODUPDATA. 164 /// </summary> 165 /// <param name="pair">The key/data pair to add</param> 166 protected void AddUnique(KeyValuePair<DatabaseEntry, DatabaseEntry> pair) { 167 Put(pair.Key, pair.Value, DbConstants.DB_NODUPDATA); 168 } 169 /* Only BTree, Hash and Recno can call Insert(). */ 170 /// <summary> 171 /// Protected method for BTree, Hash and Recno to insert with AFTER and 172 /// BEFORE. 173 /// </summary> 174 /// <param name="data">The duplicate data item to add</param> 175 /// <param name="loc"> 176 /// Whether to add the dup data before or after the current cursor 177 /// position 178 /// </param> 179 protected void Insert(DatabaseEntry data, InsertLocation loc) { 180 if (loc == InsertLocation.FIRST) 181 throw new ArgumentException("FIRST may only be specified on Add()."); 182 if (loc == InsertLocation.LAST) 183 throw new ArgumentException("LAST may only be specified on Add()."); 184 DatabaseEntry key = new DatabaseEntry(); 185 Put(key, data, (loc == InsertLocation.AFTER) ? DbConstants.DB_AFTER : DbConstants.DB_BEFORE); 186 } 187 188 /* 189 * All flavors of get and put boil down to a call to one of these two 190 * methods, just with different flags. 191 */ 192 /// <summary> 193 /// Protected method wrapping DBC->get. 194 /// </summary> 195 /// <param name="key">The key to retrieve</param> 196 /// <param name="data">The data to retrieve</param> 197 /// <param name="flags">Modify the behavior of get</param> 198 /// <param name="info">The locking configuration to use</param> 199 /// <returns> 200 /// True if the cursor was positioned successfully, false otherwise. 201 /// </returns> 202 protected bool Get(DatabaseEntry key, DatabaseEntry data, uint flags, LockingInfo info) { 203 flags |= (info == null) ? 0 : info.flags; 204 205 try { 206 dbc.get(key, data, flags); 207 Current = new KeyValuePair<DatabaseEntry, DatabaseEntry>(key, data); 208 return true; 209 } catch (NotFoundException) { 210 Current = new KeyValuePair<DatabaseEntry, DatabaseEntry>(); 211 return false; 212 } 213 } 214 /// <summary> 215 /// Protected method wrapping DBC->get for bulk get. 216 /// </summary> 217 /// <param name="key">The key to retrieve</param> 218 /// <param name="data">The data to retrieve</param> 219 /// <param name="BufferSize">Size of the bulk buffer</param> 220 /// <param name="flags">Modify the behavior of get</param> 221 /// <param name="info">The locking configuration to use</param> 222 /// <param name="isMultKey"> 223 /// If true, use DB_MULTIPLE_KEY instead of DB_MULTIPLE 224 /// </param> 225 /// <returns> 226 /// True if the cursor was positioned successfully, false otherwise. 227 /// </returns> 228 protected bool GetMultiple(DatabaseEntry key, DatabaseEntry data, 229 int BufferSize, uint flags, LockingInfo info, bool isMultKey) { 230 int datasz = 0; 231 bool getboth = false; 232 233 if (flags == DbConstants.DB_GET_BOTH || 234 flags == DbConstants.DB_GET_BOTH_RANGE) { 235 datasz = (int)data.Data.Length; 236 getboth = true; 237 } 238 flags |= (info == null) ? 0 : info.flags; 239 flags |= (isMultKey) ? 240 DbConstants.DB_MULTIPLE_KEY : DbConstants.DB_MULTIPLE; 241 242 for (; ; ) { 243 if (getboth) { 244 byte[] udata = new byte[BufferSize]; 245 Array.Copy(data.Data, udata, datasz); 246 data.UserData = udata; 247 data.size = (uint)datasz; 248 } else { 249 data.UserData = new byte[BufferSize]; 250 } 251 252 try { 253 dbc.get(key, data, flags); 254 if (isMultKey) 255 CurrentMultipleKey = 256 new MultipleKeyDatabaseEntry(dbtype, data); 257 else { 258 MultipleDatabaseEntry mult = 259 new MultipleDatabaseEntry(data); 260 CurrentMultiple = new 261 KeyValuePair<DatabaseEntry, MultipleDatabaseEntry>( 262 key, mult); 263 } 264 return true; 265 } catch (NotFoundException) { 266 if (isMultKey) 267 CurrentMultipleKey = null; 268 else 269 CurrentMultiple = new 270 KeyValuePair<DatabaseEntry, MultipleDatabaseEntry>(); 271 return false; 272 } catch (MemoryException) { 273 int sz = (int)data.size; 274 if (sz > BufferSize) 275 BufferSize = sz; 276 else 277 BufferSize *= 2; 278 } 279 } 280 } 281 282 /// <summary> 283 /// Protected method wrapping DBC->put. 284 /// </summary> 285 /// <param name="key">The key to store</param> 286 /// <param name="data">The data to store</param> 287 /// <param name="flags">Modify the behavior of put</param> 288 protected void Put(DatabaseEntry key, DatabaseEntry data, uint flags) { 289 int ret; 290 ret = dbc.put(key, data, flags); 291 } 292 #endregion Internal API 293 294 /* 295 * User facing API below. These methods just set the flags as needed 296 * before calling Get or Put. 297 */ 298 299 /// <summary> 300 /// Stores the key/data pair in the database. 301 /// </summary> 302 /// <remarks> 303 /// If the underlying database supports duplicate data items, and if the 304 /// key already exists in the database and a duplicate sort function has 305 /// been specified, the inserted data item is added in its sorted 306 /// location. If the key already exists in the database and no duplicate 307 /// sort function has been specified, the inserted data item is added as 308 /// the first of the data items for that key. 309 /// </remarks> 310 /// <param name="pair"> 311 /// The key/data pair to be stored in the database. 312 /// </param> 313 public void Add(KeyValuePair<DatabaseEntry, DatabaseEntry> pair) { 314 Put(pair.Key, pair.Value, DbConstants.DB_KEYFIRST); 315 } 316 317 /// <summary> 318 /// Delete the key/data pair to which the cursor refers. 319 /// </summary> 320 /// <remarks> 321 /// <para> 322 /// The cursor position is unchanged after a delete, and subsequent 323 /// calls to cursor functions expecting the cursor to refer to an 324 /// existing key will fail. 325 /// </para> 326 /// </remarks> 327 /// <exception cref="KeyEmptyException"> 328 /// The element has already been deleted. 329 /// </exception> 330 public new void Delete() { 331 base.Delete(); 332 Current = new KeyValuePair<DatabaseEntry, DatabaseEntry>(); 333 } 334 335 /// <summary> 336 /// Create a new cursor that uses the same transaction and locker ID as 337 /// the original cursor. 338 /// </summary> 339 /// <remarks> 340 /// This is useful when an application is using locking and requires two 341 /// or more cursors in the same thread of control. 342 /// </remarks> 343 /// <param name="keepPosition"> 344 /// If true, the newly created cursor is initialized to refer to the 345 /// same position in the database as the original cursor (if any) and 346 /// hold the same locks (if any). If false, or the original cursor does 347 /// not hold a database position and locks, the created cursor is 348 /// uninitialized and will behave like a cursor newly created by 349 /// <see cref="BaseDatabase.Cursor"/>.</param> 350 /// <returns>A newly created cursor</returns> 351 public Cursor Duplicate(bool keepPosition) { 352 return new Cursor(dbc.dup( 353 keepPosition ? DbConstants.DB_POSITION : 0), dbtype, pgsz); 354 } 355 356 IEnumerator IEnumerable.GetEnumerator() { 357 return GetEnumerator(); 358 } 359 360 /// <summary> 361 /// Returns an enumerator that iterates through the 362 /// <see cref="Cursor"/>. 363 /// </summary> 364 /// <remarks> 365 /// The enumerator will begin at the cursor's current position (or the 366 /// first record if the cursor has not yet been positioned) and iterate 367 /// forwards (i.e. in the direction of <see cref="MoveNext"/>) over the 368 /// remaining records. 369 /// </remarks> 370 /// <returns>An enumerator for the Cursor.</returns> 371 public new IEnumerator<KeyValuePair<DatabaseEntry, DatabaseEntry>> 372 GetEnumerator() { 373 while (MoveNext()) 374 yield return Current; 375 } 376 377 /// <summary> 378 /// Set the cursor to refer to the first key/data pair of the database, 379 /// and store that pair in <see cref="Current"/>. If the first key has 380 /// duplicate values, the first data item in the set of duplicates is 381 /// stored in <see cref="Current"/>. 382 /// </summary> 383 /// <remarks> 384 /// If positioning the cursor fails, <see cref="Current"/> will contain 385 /// an empty <see cref="KeyValuePair{T,T}"/>. 386 /// </remarks> 387 /// <returns> 388 /// True if the cursor was positioned successfully, false otherwise. 389 /// </returns> 390 public bool MoveFirst() { return MoveFirst(null); } 391 /// <summary> 392 /// Set the cursor to refer to the first key/data pair of the database, 393 /// and store that pair in <see cref="Current"/>. If the first key has 394 /// duplicate values, the first data item in the set of duplicates is 395 /// stored in <see cref="Current"/>. 396 /// </summary> 397 /// <remarks> 398 /// If positioning the cursor fails, <see cref="Current"/> will contain 399 /// an empty <see cref="KeyValuePair{T,T}"/>. 400 /// </remarks> 401 /// <param name="info">The locking behavior to use.</param> 402 /// <returns> 403 /// True if the cursor was positioned successfully, false otherwise. 404 /// </returns> 405 public bool MoveFirst(LockingInfo info) { 406 DatabaseEntry key = new DatabaseEntry(); 407 DatabaseEntry data = new DatabaseEntry(); 408 409 return Get(key, data, DbConstants.DB_FIRST, info); 410 } 411 412 /// <summary> 413 /// Set the cursor to refer to the first key/data pair of the database, 414 /// and store that key and as many duplicate data items that can fit in 415 /// a buffer the size of one database page in 416 /// <see cref="CurrentMultiple"/>. 417 /// </summary> 418 /// <overloads> 419 /// If positioning the cursor fails, <see cref="CurrentMultiple"/> will 420 /// contain an empty 421 /// <see cref="KeyValuePair{T,T}"/>. 422 /// </overloads> 423 /// <returns> 424 /// True if the cursor was positioned successfully, false otherwise. 425 /// </returns> 426 public bool MoveFirstMultiple() { 427 return MoveFirstMultiple((int)pgsz, null); 428 } 429 /// <summary> 430 /// Set the cursor to refer to the first key/data pair of the database, 431 /// and store that key and as many duplicate data items that can fit in 432 /// a buffer the size of <paramref name="BufferSize"/> in 433 /// <see cref="CurrentMultiple"/>. 434 /// </summary> 435 /// <param name="BufferSize"> 436 /// The size of a buffer to fill with duplicate data items. Must be at 437 /// least the page size of the underlying database and be a multiple of 438 /// 1024. 439 /// </param> 440 /// <returns> 441 /// True if the cursor was positioned successfully, false otherwise. 442 /// </returns> 443 public bool MoveFirstMultiple(int BufferSize) { 444 return MoveFirstMultiple(BufferSize, null); 445 } 446 /// <summary> 447 /// Set the cursor to refer to the first key/data pair of the database, 448 /// and store that key and as many duplicate data items that can fit in 449 /// a buffer the size of one database page in 450 /// <see cref="CurrentMultiple"/>. 451 /// </summary> 452 /// <param name="info">The locking behavior to use.</param> 453 /// <returns> 454 /// True if the cursor was positioned successfully, false otherwise. 455 /// </returns> 456 public bool MoveFirstMultiple(LockingInfo info) { 457 return MoveFirstMultiple((int)pgsz, info); 458 } 459 /// <summary> 460 /// Set the cursor to refer to the first key/data pair of the database, 461 /// and store that key and as many duplicate data items that can fit in 462 /// a buffer the size of <paramref name="BufferSize"/> in 463 /// <see cref="CurrentMultiple"/>. 464 /// </summary> 465 /// <param name="BufferSize"> 466 /// The size of a buffer to fill with duplicate data items. Must be at 467 /// least the page size of the underlying database and be a multiple of 468 /// 1024. 469 /// </param> 470 /// <param name="info">The locking behavior to use.</param> 471 /// <returns> 472 /// True if the cursor was positioned successfully, false otherwise. 473 /// </returns> 474 public bool MoveFirstMultiple(int BufferSize, LockingInfo info) { 475 DatabaseEntry key = new DatabaseEntry(); 476 DatabaseEntry data = new DatabaseEntry(); 477 478 return GetMultiple( 479 key, data, BufferSize, DbConstants.DB_FIRST, info, false); 480 } 481 482 /// <summary> 483 /// Set the cursor to refer to the first key/data pair of the database, 484 /// and store that pair and as many ensuing key/data pairs that can fit 485 /// in a buffer the size of one database page in 486 /// <see cref="CurrentMultipleKey"/>. 487 /// </summary> 488 /// <returns> 489 /// True if the cursor was positioned successfully, false otherwise. 490 /// </returns> 491 public bool MoveFirstMultipleKey() { 492 return MoveFirstMultipleKey((int)pgsz, null); 493 } 494 /// <summary> 495 /// Set the cursor to refer to the first key/data pair of the database, 496 /// and store that pair and as many ensuing key/data pairs that can fit 497 /// in a buffer the size of <paramref name="BufferSize"/> in 498 /// <see cref="CurrentMultipleKey"/>. 499 /// </summary> 500 /// <param name="BufferSize"> 501 /// The size of a buffer to fill with key/data pairs. Must be at least 502 /// the page size of the underlying database and be a multiple of 1024. 503 /// </param> 504 /// <returns> 505 /// True if the cursor was positioned successfully, false otherwise. 506 /// </returns> 507 public bool MoveFirstMultipleKey(int BufferSize) { 508 return MoveFirstMultipleKey(BufferSize, null); 509 } 510 /// <summary> 511 /// Set the cursor to refer to the first key/data pair of the database, 512 /// and store that pair and as many ensuing key/data pairs that can fit 513 /// in a buffer the size of one database page in 514 /// <see cref="CurrentMultipleKey"/>. 515 /// </summary> 516 /// <param name="info">The locking behavior to use.</param> 517 /// <returns> 518 /// True if the cursor was positioned successfully, false otherwise. 519 /// </returns> 520 public bool MoveFirstMultipleKey(LockingInfo info) { 521 return MoveFirstMultipleKey((int)pgsz, info); 522 } 523 /// <summary> 524 /// Set the cursor to refer to the first key/data pair of the database, 525 /// and store that pair and as many ensuing key/data pairs that can fit 526 /// in a buffer the size of <paramref name="BufferSize"/> in 527 /// <see cref="CurrentMultipleKey"/>. 528 /// </summary> 529 /// <param name="BufferSize"> 530 /// The size of a buffer to fill with key/data pairs. Must be at least 531 /// the page size of the underlying database and be a multiple of 1024. 532 /// </param> 533 /// <param name="info">The locking behavior to use.</param> 534 /// <returns> 535 /// True if the cursor was positioned successfully, false otherwise. 536 /// </returns> 537 public bool MoveFirstMultipleKey(int BufferSize, LockingInfo info) { 538 DatabaseEntry key = new DatabaseEntry(); 539 DatabaseEntry data = new DatabaseEntry(); 540 541 return GetMultiple( 542 key, data, BufferSize, DbConstants.DB_FIRST, info, true); 543 } 544 545 /// <summary> 546 /// Set the cursor to refer to <paramref name="key"/>, and store the 547 /// datum associated with the given key in <see cref="Current"/>. In the 548 /// presence of duplicate key values, the first data item in the set of 549 /// duplicates is stored in <see cref="Current"/>. 550 /// </summary> 551 /// <remarks> 552 /// If positioning the cursor fails, <see cref="Current"/> will contain 553 /// an empty <see cref="KeyValuePair{T,T}"/>. 554 /// </remarks> 555 /// <param name="key">The key at which to position the cursor</param> 556 /// <param name="exact"> 557 /// If true, require the given key to match the key in the database 558 /// exactly. If false, position the cursor at the smallest key greater 559 /// than or equal to the specified key, permitting partial key matches 560 /// and range searches. 561 /// </param> 562 /// <returns> 563 /// True if the cursor was positioned successfully, false otherwise. 564 /// </returns> 565 public bool Move(DatabaseEntry key, bool exact) { 566 return Move(key, exact, null); 567 } 568 /// <summary> 569 /// Set the cursor to refer to <paramref name="key"/>, and store the 570 /// datum associated with the given key in <see cref="Current"/>. In the 571 /// presence of duplicate key values, the first data item in the set of 572 /// duplicates is stored in <see cref="Current"/>. 573 /// </summary> 574 /// <remarks> 575 /// If positioning the cursor fails, <see cref="Current"/> will contain 576 /// an empty <see cref="KeyValuePair{T,T}"/>. 577 /// </remarks> 578 /// <param name="key">The key at which to position the cursor</param> 579 /// <param name="exact"> 580 /// If true, require the given key to match the key in the database 581 /// exactly. If false, position the cursor at the smallest key greater 582 /// than or equal to the specified key, permitting partial key matches 583 /// and range searches. 584 /// </param> 585 /// <param name="info">The locking behavior to use.</param> 586 /// <returns> 587 /// True if the cursor was positioned successfully, false otherwise. 588 /// </returns> 589 public bool Move(DatabaseEntry key, bool exact, LockingInfo info) { 590 DatabaseEntry data = new DatabaseEntry(); 591 592 return Get(key, data, 593 exact ? DbConstants.DB_SET : DbConstants.DB_SET_RANGE, info); 594 } 595 596 /// <summary> 597 /// Move the cursor to the specified key/data pair of the database. The 598 /// cursor is positioned to a key/data pair if both the key and data 599 /// match the values provided on the key and data parameters. 600 /// </summary> 601 /// <remarks> 602 /// <para> 603 /// If positioning the cursor fails, <see cref="Current"/> will contain 604 /// an empty <see cref="KeyValuePair{T,T}"/>. 605 /// </para> 606 /// <para> 607 /// If this flag is specified on a database configured without sorted 608 /// duplicate support, the value of <paramref name="exact"/> is ignored. 609 /// </para> 610 /// </remarks> 611 /// <param name="pair"> 612 /// The key/data pair at which to position the cursor. 613 /// </param> 614 /// <param name="exact"> 615 /// If true, require the given key and data to match the key and data 616 /// in the database exactly. If false, position the cursor at the 617 /// smallest data value which is greater than or equal to the value 618 /// provided by <paramref name="pair.Value"/> (as determined by the 619 /// comparison function). 620 /// </param> 621 /// <returns> 622 /// True if the cursor was positioned successfully, false otherwise. 623 /// </returns> 624 public bool Move( 625 KeyValuePair<DatabaseEntry, DatabaseEntry> pair, bool exact) { 626 return Move(pair, exact, null); 627 } 628 /// <summary> 629 /// Move the cursor to the specified key/data pair of the database. The 630 /// cursor is positioned to a key/data pair if both the key and data 631 /// match the values provided on the key and data parameters. 632 /// </summary> 633 /// <remarks> 634 /// <para> 635 /// If positioning the cursor fails, <see cref="Current"/> will contain 636 /// an empty <see cref="KeyValuePair{T,T}"/>. 637 /// </para> 638 /// <para> 639 /// If this flag is specified on a database configured without sorted 640 /// duplicate support, the value of <paramref name="exact"/> is ignored. 641 /// </para> 642 /// </remarks> 643 /// <param name="pair"> 644 /// The key/data pair at which to position the cursor. 645 /// </param> 646 /// <param name="exact"> 647 /// If true, require the given key and data to match the key and data 648 /// in the database exactly. If false, position the cursor at the 649 /// smallest data value which is greater than or equal to the value 650 /// provided by <paramref name="pair.Value"/> (as determined by the 651 /// comparison function). 652 /// </param> 653 /// <param name="info">The locking behavior to use.</param> 654 /// <returns> 655 /// True if the cursor was positioned successfully, false otherwise. 656 /// </returns> 657 public bool Move(KeyValuePair<DatabaseEntry, DatabaseEntry> pair, 658 bool exact, LockingInfo info) { 659 return Get(pair.Key, pair.Value, exact ? 660 DbConstants.DB_GET_BOTH : DbConstants.DB_GET_BOTH_RANGE, info); 661 } 662 663 /// <summary> 664 /// Set the cursor to refer to the last key/data pair of the database, 665 /// and store that pair in <see cref="Current"/>. If the last key has 666 /// duplicate values, the last data item in the set of duplicates is 667 /// stored in <see cref="Current"/>. 668 /// </summary> 669 /// <remarks> 670 /// If positioning the cursor fails, <see cref="Current"/> will contain 671 /// an empty <see cref="KeyValuePair{T,T}"/>. 672 /// </remarks> 673 /// <returns> 674 /// True if the cursor was positioned successfully, false otherwise. 675 /// </returns> 676 public bool MoveLast() { return MoveLast(null); } 677 /// <summary> 678 /// Set the cursor to refer to the last key/data pair of the database, 679 /// and store that pair in <see cref="Current"/>. If the last key has 680 /// duplicate values, the last data item in the set of duplicates is 681 /// stored in <see cref="Current"/>. 682 /// </summary> 683 /// <remarks> 684 /// If positioning the cursor fails, <see cref="Current"/> will contain 685 /// an empty <see cref="KeyValuePair{T,T}"/>. 686 /// </remarks> 687 /// <param name="info">The locking behavior to use.</param> 688 /// <returns> 689 /// True if the cursor was positioned successfully, false otherwise. 690 /// </returns> 691 public bool MoveLast(LockingInfo info) { 692 DatabaseEntry key = new DatabaseEntry(); 693 DatabaseEntry data = new DatabaseEntry(); 694 695 return Get(key, data, DbConstants.DB_LAST, info); 696 } 697 698 /// <summary> 699 /// Set the cursor to refer to <paramref name="key"/>, and store that 700 /// key and as many duplicate data items associated with the given key that 701 /// can fit in a buffer the size of one database page in 702 /// <see cref="CurrentMultiple"/>. 703 /// </summary> 704 /// <param name="key">The key at which to position the cursor</param> 705 /// <param name="exact"> 706 /// If true, require the given key to match the key in the database 707 /// exactly. If false, position the cursor at the smallest key greater 708 /// than or equal to the specified key, permitting partial key matches 709 /// and range searches. 710 /// </param> 711 /// <returns> 712 /// True if the cursor was positioned successfully, false otherwise. 713 /// </returns> 714 public bool MoveMultiple(DatabaseEntry key, bool exact) { 715 return MoveMultiple(key, exact, (int)pgsz, null); 716 } 717 /// <summary> 718 /// Set the cursor to refer to <paramref name="key"/>, and store that 719 /// key and as many duplicate data items associated with the given key that 720 /// can fit in a buffer the size of <paramref name="BufferSize"/> in 721 /// <see cref="CurrentMultiple"/>. 722 /// </summary> 723 /// <param name="key">The key at which to position the cursor</param> 724 /// <param name="exact"> 725 /// If true, require the given key to match the key in the database 726 /// exactly. If false, position the cursor at the smallest key greater 727 /// than or equal to the specified key, permitting partial key matches 728 /// and range searches. 729 /// </param> 730 /// <param name="BufferSize"> 731 /// The size of a buffer to fill with duplicate data items. Must be at 732 /// least the page size of the underlying database and be a multiple of 733 /// 1024. 734 /// </param> 735 /// <returns> 736 /// True if the cursor was positioned successfully, false otherwise. 737 /// </returns> 738 public bool MoveMultiple( 739 DatabaseEntry key, bool exact, int BufferSize) { 740 return MoveMultiple(key, exact, BufferSize, null); 741 } 742 /// <summary> 743 /// Set the cursor to refer to <paramref name="key"/>, and store that 744 /// key and as many duplicate data items associated with the given key that 745 /// can fit in a buffer the size of one database page in 746 /// <see cref="CurrentMultiple"/>. 747 /// </summary> 748 /// <param name="key">The key at which to position the cursor</param> 749 /// <param name="exact"> 750 /// If true, require the given key to match the key in the database 751 /// exactly. If false, position the cursor at the smallest key greater 752 /// than or equal to the specified key, permitting partial key matches 753 /// and range searches. 754 /// </param> 755 /// <param name="info">The locking behavior to use.</param> 756 /// <returns> 757 /// True if the cursor was positioned successfully, false otherwise. 758 /// </returns> 759 public bool MoveMultiple( 760 DatabaseEntry key, bool exact, LockingInfo info) { 761 return MoveMultiple(key, exact, (int)pgsz, info); 762 } 763 /// <summary> 764 /// Set the cursor to refer to <paramref name="key"/>, and store that 765 /// key and as many duplicate data items associated with the given key that 766 /// can fit in a buffer the size of <paramref name="BufferSize"/> in 767 /// <see cref="CurrentMultiple"/>. 768 /// </summary> 769 /// <param name="key">The key at which to position the cursor</param> 770 /// <param name="exact"> 771 /// If true, require the given key to match the key in the database 772 /// exactly. If false, position the cursor at the smallest key greater 773 /// than or equal to the specified key, permitting partial key matches 774 /// and range searches. 775 /// </param> 776 /// <param name="BufferSize"> 777 /// The size of a buffer to fill with duplicate data items. Must be at 778 /// least the page size of the underlying database and be a multiple of 779 /// 1024. 780 /// </param> 781 /// <param name="info">The locking behavior to use.</param> 782 /// <returns> 783 /// True if the cursor was positioned successfully, false otherwise. 784 /// </returns> 785 public bool MoveMultiple( 786 DatabaseEntry key, bool exact, int BufferSize, LockingInfo info) { 787 DatabaseEntry data = new DatabaseEntry(); 788 789 return GetMultiple(key, data, BufferSize, (exact ? 790 DbConstants.DB_SET : DbConstants.DB_SET_RANGE), info, false); 791 } 792 793 /// <summary> 794 /// Move the cursor to the specified key/data pair of the database, and 795 /// store that key/data pair and as many duplicate data items associated 796 /// with the given key that can fit in a buffer the size of one database 797 /// page in <see cref="CurrentMultiple"/>. The cursor is positioned to a 798 /// key/data pair if both the key and data match the values provided on 799 /// the key and data parameters. 800 /// </summary> 801 /// <param name="pair"> 802 /// The key/data pair at which to position the cursor. 803 /// </param> 804 /// <param name="exact"> 805 /// If true, require the given key and data to match the key and data 806 /// in the database exactly. If false, position the cursor at the 807 /// smallest data value which is greater than or equal to the value 808 /// provided by <paramref name="pair.Value"/> (as determined by the 809 /// comparison function). 810 /// </param> 811 /// <returns> 812 /// True if the cursor was positioned successfully, false otherwise. 813 /// </returns> 814 public bool MoveMultiple( 815 KeyValuePair<DatabaseEntry, DatabaseEntry> pair, bool exact) { 816 return MoveMultiple(pair, exact, (int)pgsz, null); 817 } 818 /// <summary> 819 /// Move the cursor to the specified key/data pair of the database, and 820 /// store that key/data pair and as many duplicate data items associated 821 /// with the given key that can fit in a buffer the size of 822 /// <paramref name="BufferSize"/> in <see cref="CurrentMultiple"/>. The 823 /// cursor is positioned to a key/data pair if both the key and data 824 /// match the values provided on the key and data parameters. 825 /// </summary> 826 /// <param name="pair"> 827 /// The key/data pair at which to position the cursor. 828 /// </param> 829 /// <param name="exact"> 830 /// If true, require the given key and data to match the key and data 831 /// in the database exactly. If false, position the cursor at the 832 /// smallest data value which is greater than or equal to the value 833 /// provided by <paramref name="pair.Value"/> (as determined by the 834 /// comparison function). 835 /// </param> 836 /// <param name="BufferSize"> 837 /// The size of a buffer to fill with duplicate data items. Must be at 838 /// least the page size of the underlying database and be a multiple of 839 /// 1024. 840 /// </param> 841 /// <returns> 842 /// True if the cursor was positioned successfully, false otherwise. 843 /// </returns> 844 public bool MoveMultiple( 845 KeyValuePair<DatabaseEntry, DatabaseEntry> pair, 846 bool exact, int BufferSize) { 847 return MoveMultiple(pair, exact, BufferSize, null); 848 } 849 /// <summary> 850 /// Move the cursor to the specified key/data pair of the database, and 851 /// store that key/data pair and as many duplicate data items associated 852 /// with the given key that can fit in a buffer the size of one database 853 /// page in <see cref="CurrentMultiple"/>. The cursor is positioned to a 854 /// key/data pair if both the key and data match the values provided on 855 /// the key and data parameters. 856 /// </summary> 857 /// <param name="pair"> 858 /// The key/data pair at which to position the cursor. 859 /// </param> 860 /// <param name="exact"> 861 /// If true, require the given key and data to match the key and data 862 /// in the database exactly. If false, position the cursor at the 863 /// smallest data value which is greater than or equal to the value 864 /// provided by <paramref name="pair.Value"/> (as determined by the 865 /// comparison function). 866 /// </param> 867 /// <param name="info">The locking behavior to use.</param> 868 /// <returns> 869 /// True if the cursor was positioned successfully, false otherwise. 870 /// </returns> 871 public bool MoveMultiple( 872 KeyValuePair<DatabaseEntry, DatabaseEntry> pair, 873 bool exact, LockingInfo info) { 874 return MoveMultiple(pair, exact, (int)pgsz, info); 875 } 876 /// <summary> 877 /// Move the cursor to the specified key/data pair of the database, and 878 /// store that key/data pair and as many duplicate data items associated 879 /// with the given key that can fit in a buffer the size of 880 /// <paramref name="BufferSize"/> in <see cref="CurrentMultiple"/>. The 881 /// cursor is positioned to a key/data pair if both the key and data 882 /// match the values provided on the key and data parameters. 883 /// </summary> 884 /// <param name="pair"> 885 /// The key/data pair at which to position the cursor. 886 /// </param> 887 /// <param name="exact"> 888 /// If true, require the given key and data to match the key and data 889 /// in the database exactly. If false, position the cursor at the 890 /// smallest data value which is greater than or equal to the value 891 /// provided by <paramref name="pair.Value"/> (as determined by the 892 /// comparison function). 893 /// </param> 894 /// <param name="BufferSize"> 895 /// The size of a buffer to fill with duplicate data items. Must be at 896 /// least the page size of the underlying database and be a multiple of 897 /// 1024. 898 /// </param> 899 /// <param name="info">The locking behavior to use.</param> 900 /// <returns> 901 /// True if the cursor was positioned successfully, false otherwise. 902 /// </returns> 903 public bool MoveMultiple( 904 KeyValuePair<DatabaseEntry, DatabaseEntry> pair, 905 bool exact, int BufferSize, LockingInfo info) { 906 return GetMultiple(pair.Key, pair.Value, BufferSize, (exact ? 907 DbConstants.DB_GET_BOTH : DbConstants.DB_GET_BOTH_RANGE), 908 info, false); 909 } 910 911 /// <summary> 912 /// Set the cursor to refer to <paramref name="key"/>, and store that 913 /// key and as many ensuing key/data pairs that can fit in a buffer the 914 /// size of one database page in <see cref="CurrentMultipleKey"/>. 915 /// </summary> 916 /// <param name="key">The key at which to position the cursor</param> 917 /// <param name="exact"> 918 /// If true, require the given key to match the key in the database 919 /// exactly. If false, position the cursor at the smallest key greater 920 /// than or equal to the specified key, permitting partial key matches 921 /// and range searches. 922 /// </param> 923 /// <returns> 924 /// True if the cursor was positioned successfully, false otherwise. 925 /// </returns> 926 public bool MoveMultipleKey(DatabaseEntry key, bool exact) { 927 return MoveMultipleKey(key, exact, (int)pgsz, null); 928 } 929 /// <summary> 930 /// Set the cursor to refer to <paramref name="key"/>, and store that 931 /// key and as many ensuing key/data pairs that can fit in a buffer the 932 /// size of <paramref name="BufferSize"/> in 933 /// <see cref="CurrentMultipleKey"/>. 934 /// </summary> 935 /// <param name="key">The key at which to position the cursor</param> 936 /// <param name="exact"> 937 /// If true, require the given key to match the key in the database 938 /// exactly. If false, position the cursor at the smallest key greater 939 /// than or equal to the specified key, permitting partial key matches 940 /// and range searches. 941 /// </param> 942 /// <param name="BufferSize"> 943 /// The size of a buffer to fill with key/data pairs. Must be at least 944 /// the page size of the underlying database and be a multiple of 1024. 945 /// </param> 946 /// <returns> 947 /// True if the cursor was positioned successfully, false otherwise. 948 /// </returns> 949 public bool MoveMultipleKey( 950 DatabaseEntry key, bool exact, int BufferSize) { 951 return MoveMultipleKey(key, exact, BufferSize, null); 952 } 953 /// <summary> 954 /// Set the cursor to refer to <paramref name="key"/>, and store that 955 /// key and as many ensuing key/data pairs that can fit in a buffer the 956 /// size of one database page in <see cref="CurrentMultipleKey"/>. 957 /// </summary> 958 /// <param name="key">The key at which to position the cursor</param> 959 /// <param name="exact"> 960 /// If true, require the given key to match the key in the database 961 /// exactly. If false, position the cursor at the smallest key greater 962 /// than or equal to the specified key, permitting partial key matches 963 /// and range searches. 964 /// </param> 965 /// <param name="info">The locking behavior to use.</param> 966 /// <returns> 967 /// True if the cursor was positioned successfully, false otherwise. 968 /// </returns> 969 public bool MoveMultipleKey( 970 DatabaseEntry key, bool exact, LockingInfo info) { 971 return MoveMultipleKey(key, exact, (int)pgsz, info); 972 } 973 /// <summary> 974 /// Set the cursor to refer to <paramref name="key"/>, and store that 975 /// key and as many ensuing key/data pairs that can fit in a buffer the 976 /// size of <paramref name="BufferSize"/> in 977 /// <see cref="CurrentMultipleKey"/>. 978 /// </summary> 979 /// <param name="key">The key at which to position the cursor</param> 980 /// <param name="exact"> 981 /// If true, require the given key to match the key in the database 982 /// exactly. If false, position the cursor at the smallest key greater 983 /// than or equal to the specified key, permitting partial key matches 984 /// and range searches. 985 /// </param> 986 /// <param name="BufferSize"> 987 /// The size of a buffer to fill with key/data pairs. Must be at least 988 /// the page size of the underlying database and be a multiple of 1024. 989 /// </param> 990 /// <param name="info">The locking behavior to use.</param> 991 /// <returns> 992 /// True if the cursor was positioned successfully, false otherwise. 993 /// </returns> 994 public bool MoveMultipleKey( 995 DatabaseEntry key, bool exact, int BufferSize, LockingInfo info) { 996 DatabaseEntry data = new DatabaseEntry(); 997 998 return GetMultiple(key, data, BufferSize, 999 (exact ? 1000 DbConstants.DB_SET : DbConstants.DB_SET_RANGE), info, true); 1001 } 1002 1003 /// <summary> 1004 /// Move the cursor to the specified key/data pair of the database, and 1005 /// store that key/data pair and as many ensuing key/data pairs that can 1006 /// fit in a buffer the size of one database page in 1007 /// <see cref="CurrentMultipleKey"/>. The cursor is positioned to a 1008 /// key/data pair if both the key and data match the values provided on 1009 /// the key and data parameters. 1010 /// </summary> 1011 /// <param name="pair"> 1012 /// The key/data pair at which to position the cursor. 1013 /// </param> 1014 /// <param name="exact"> 1015 /// If true, require the given key and data to match the key and data 1016 /// in the database exactly. If false, position the cursor at the 1017 /// smallest data value which is greater than or equal to the value 1018 /// provided by <paramref name="pair.Value"/> (as determined by the 1019 /// comparison function). 1020 /// </param> 1021 /// <returns> 1022 /// True if the cursor was positioned successfully, false otherwise. 1023 /// </returns> 1024 public bool MoveMultipleKey( 1025 KeyValuePair<DatabaseEntry, DatabaseEntry> pair, bool exact) { 1026 return MoveMultipleKey(pair, exact, (int)pgsz, null); 1027 } 1028 /// <summary> 1029 /// Move the cursor to the specified key/data pair of the database, and 1030 /// store that key/data pair and as many ensuing key/data pairs that can 1031 /// fit in a buffer the size of <paramref name="BufferSize"/> in 1032 /// <see cref="CurrentMultipleKey"/>. The cursor is positioned to a 1033 /// key/data pair if both the key and data match the values provided on 1034 /// the key and data parameters. 1035 /// </summary> 1036 /// <param name="pair"> 1037 /// The key/data pair at which to position the cursor. 1038 /// </param> 1039 /// <param name="exact"> 1040 /// If true, require the given key and data to match the key and data 1041 /// in the database exactly. If false, position the cursor at the 1042 /// smallest data value which is greater than or equal to the value 1043 /// provided by <paramref name="pair.Value"/> (as determined by the 1044 /// comparison function). 1045 /// </param> 1046 /// <param name="BufferSize"> 1047 /// The size of a buffer to fill with key/data pairs. Must be at least 1048 /// the page size of the underlying database and be a multiple of 1024. 1049 /// </param> 1050 /// <returns> 1051 /// True if the cursor was positioned successfully, false otherwise. 1052 /// </returns> 1053 public bool MoveMultipleKey( 1054 KeyValuePair<DatabaseEntry, DatabaseEntry> pair, 1055 bool exact, int BufferSize) { 1056 return MoveMultipleKey(pair, exact, BufferSize, null); 1057 } 1058 /// <summary> 1059 /// Move the cursor to the specified key/data pair of the database, and 1060 /// store that key/data pair and as many ensuing key/data pairs that can 1061 /// fit in a buffer the size of one database page in 1062 /// <see cref="CurrentMultipleKey"/>. The cursor is positioned to a 1063 /// key/data pair if both the key and data match the values provided on 1064 /// the key and data parameters. 1065 /// </summary> 1066 /// <param name="pair"> 1067 /// The key/data pair at which to position the cursor. 1068 /// </param> 1069 /// <param name="exact"> 1070 /// If true, require the given key and data to match the key and data 1071 /// in the database exactly. If false, position the cursor at the 1072 /// smallest data value which is greater than or equal to the value 1073 /// provided by <paramref name="pair.Value"/> (as determined by the 1074 /// comparison function). 1075 /// </param> 1076 /// <param name="info">The locking behavior to use.</param> 1077 /// <returns> 1078 /// True if the cursor was positioned successfully, false otherwise. 1079 /// </returns> 1080 public bool MoveMultipleKey( 1081 KeyValuePair<DatabaseEntry, DatabaseEntry> pair, 1082 bool exact, LockingInfo info) { 1083 return MoveMultipleKey(pair, exact, (int)pgsz, info); 1084 } 1085 /// <summary> 1086 /// Move the cursor to the specified key/data pair of the database, and 1087 /// store that key/data pair and as many ensuing key/data pairs that can 1088 /// fit in a buffer the size of <paramref name="BufferSize"/> in 1089 /// <see cref="CurrentMultipleKey"/>. The cursor is positioned to a 1090 /// key/data pair if both the key and data match the values provided on 1091 /// the key and data parameters. 1092 /// </summary> 1093 /// <param name="pair"> 1094 /// The key/data pair at which to position the cursor. 1095 /// </param> 1096 /// <param name="exact"> 1097 /// If true, require the given key and data to match the key and data 1098 /// in the database exactly. If false, position the cursor at the 1099 /// smallest data value which is greater than or equal to the value 1100 /// provided by <paramref name="pair.Value"/> (as determined by the 1101 /// comparison function). 1102 /// </param> 1103 /// <param name="BufferSize"> 1104 /// The size of a buffer to fill with key/data pairs. Must be at least 1105 /// the page size of the underlying database and be a multiple of 1024. 1106 /// </param> 1107 /// <param name="info">The locking behavior to use.</param> 1108 /// <returns> 1109 /// True if the cursor was positioned successfully, false otherwise. 1110 /// </returns> 1111 public bool MoveMultipleKey( 1112 KeyValuePair<DatabaseEntry, DatabaseEntry> pair, 1113 bool exact, int BufferSize, LockingInfo info) { 1114 return GetMultiple(pair.Key, pair.Value, BufferSize, (exact ? 1115 DbConstants.DB_GET_BOTH : DbConstants.DB_GET_BOTH_RANGE), 1116 info, true); 1117 } 1118 1119 /// <summary> 1120 /// If the cursor is not yet initialized, MoveNext is identical to 1121 /// <see cref="MoveFirst()"/>. Otherwise, move the cursor to the next 1122 /// key/data pair of the database, and store that pair in 1123 /// <see cref="Current"/>. In the presence of duplicate key values, the 1124 /// value of <see cref="Current">Current.Key</see> may not change. 1125 /// </summary> 1126 /// <remarks> 1127 /// If positioning the cursor fails, <see cref="Current"/> will contain 1128 /// an empty <see cref="KeyValuePair{T,T}"/>. 1129 /// </remarks> 1130 /// <returns> 1131 /// True if the cursor was positioned successfully, false otherwise. 1132 /// </returns> 1133 public bool MoveNext() { return MoveNext(null); } 1134 /// <summary> 1135 /// If the cursor is not yet initialized, MoveNext is identical to 1136 /// <see cref="MoveFirst(LockingInfo)"/>. Otherwise, move the cursor to 1137 /// the next key/data pair of the database, and store that pair in 1138 /// <see cref="Current"/>. In the presence of duplicate key values, the 1139 /// value of <see cref="Current">Current.Key</see> may not change. 1140 /// </summary> 1141 /// <remarks> 1142 /// If positioning the cursor fails, <see cref="Current"/> will contain 1143 /// an empty <see cref="KeyValuePair{T,T}"/>. 1144 /// </remarks> 1145 /// <param name="info">The locking behavior to use.</param> 1146 /// <returns> 1147 /// True if the cursor was positioned successfully, false otherwise. 1148 /// </returns> 1149 public bool MoveNext(LockingInfo info) { 1150 DatabaseEntry key = new DatabaseEntry(); 1151 DatabaseEntry data = new DatabaseEntry(); 1152 1153 return Get(key, data, DbConstants.DB_NEXT, info); 1154 } 1155 1156 /// <summary> 1157 /// If the cursor is not yet initialized, MoveNextMultiple is identical 1158 /// to <see cref="MoveFirstMultiple()"/>. Otherwise, move the cursor to 1159 /// the next key/data pair of the database, and store that pair and as 1160 /// many duplicate data items that can fit in a buffer the size of one 1161 /// database page in <see cref="CurrentMultiple"/>. In the presence of 1162 /// duplicate key values, the value of 1163 /// <see cref="CurrentMultiple">CurrentMultiple.Key</see> may not 1164 /// change. 1165 /// </summary> 1166 /// <returns> 1167 /// True if the cursor was positioned successfully, false otherwise. 1168 /// </returns> 1169 public bool MoveNextMultiple() { 1170 return MoveNextMultiple((int)pgsz, null); 1171 } 1172 /// <summary> 1173 /// If the cursor is not yet initialized, MoveNextMultiple is identical 1174 /// to <see cref="MoveFirstMultiple(int)"/>. Otherwise, move the cursor 1175 /// to the next key/data pair of the database, and store that pair and 1176 /// as many duplicate data items that can fit in a buffer the size of 1177 /// <paramref name="BufferSize"/> in <see cref="CurrentMultiple"/>. In 1178 /// the presence of duplicate key values, the value of 1179 /// <see cref="CurrentMultiple">CurrentMultiple.Key</see> may not 1180 /// change. 1181 /// </summary> 1182 /// <param name="BufferSize"> 1183 /// The size of a buffer to fill with duplicate data items. Must be at 1184 /// least the page size of the underlying database and be a multiple of 1185 /// 1024. 1186 /// </param> 1187 /// <returns> 1188 /// True if the cursor was positioned successfully, false otherwise. 1189 /// </returns> 1190 public bool MoveNextMultiple(int BufferSize) { 1191 return MoveNextMultiple(BufferSize, null); 1192 } 1193 /// <summary> 1194 /// If the cursor is not yet initialized, MoveNextMultiple is identical 1195 /// to <see cref="MoveFirstMultiple(LockingInfo)"/>. Otherwise, move the 1196 /// cursor to the next key/data pair of the database, and store that 1197 /// pair and as many duplicate data items that can fit in a buffer the 1198 /// size of one database page in <see cref="CurrentMultiple"/>. In the 1199 /// presence of duplicate key values, the value of 1200 /// <see cref="CurrentMultiple">CurrentMultiple.Key</see> may not 1201 /// change. 1202 /// </summary> 1203 /// <param name="info">The locking behavior to use.</param> 1204 /// <returns> 1205 /// True if the cursor was positioned successfully, false otherwise. 1206 /// </returns> 1207 public bool MoveNextMultiple(LockingInfo info) { 1208 return MoveNextMultiple((int)pgsz, null); 1209 } 1210 /// <summary> 1211 /// If the cursor is not yet initialized, MoveNextMultiple is identical 1212 /// to <see cref="MoveFirstMultiple(int, LockingInfo)"/>. Otherwise, 1213 /// move the cursor to the next key/data pair of the database, and store 1214 /// that pair and as many duplicate data items that can fit in a buffer 1215 /// the size of <paramref name="BufferSize"/> in 1216 /// <see cref="CurrentMultiple"/>. In the presence of duplicate key 1217 /// values, the value of 1218 /// <see cref="CurrentMultiple">CurrentMultiple.Key</see> may not 1219 /// change. 1220 /// </summary> 1221 /// <param name="BufferSize"> 1222 /// The size of a buffer to fill with duplicate data items. Must be at 1223 /// least the page size of the underlying database and be a multiple of 1224 /// 1024. 1225 /// </param> 1226 /// <param name="info">The locking behavior to use.</param> 1227 /// <returns> 1228 /// True if the cursor was positioned successfully, false otherwise. 1229 /// </returns> 1230 public bool MoveNextMultiple(int BufferSize, LockingInfo info) { 1231 DatabaseEntry key = new DatabaseEntry(); 1232 DatabaseEntry data = new DatabaseEntry(); 1233 1234 return GetMultiple( 1235 key, data, BufferSize, DbConstants.DB_NEXT, info, false); 1236 } 1237 1238 /// <summary> 1239 /// If the cursor is not yet initialized, MoveNextMultipleKey is 1240 /// identical to <see cref="MoveFirstMultipleKey()"/>. Otherwise, move 1241 /// the cursor to the next key/data pair of the database, and store that 1242 /// pair and as many ensuing key/data pairs that can fit in a buffer the 1243 /// size of one database page in <see cref="CurrentMultipleKey"/>. In 1244 /// the presence of duplicate key values, the keys of 1245 /// <see cref="CurrentMultipleKey"/> may not change. 1246 /// </summary> 1247 /// <returns> 1248 /// True if the cursor was positioned successfully, false otherwise. 1249 /// </returns> 1250 public bool MoveNextMultipleKey() { 1251 return MoveNextMultipleKey((int)pgsz, null); 1252 } 1253 /// <summary> 1254 /// If the cursor is not yet initialized, MoveNextMultipleKey is 1255 /// identical to <see cref="MoveFirstMultipleKey(int)"/>. Otherwise, 1256 /// move the cursor to the next key/data pair of the database, and store 1257 /// that pair and as many ensuing key/data pairs that can fit in a 1258 /// buffer the size of <paramref name="BufferSize"/> in 1259 /// <see cref="CurrentMultipleKey"/>. In the presence of duplicate key 1260 /// values, the keys of <see cref="CurrentMultipleKey"/> may not change. 1261 /// </summary> 1262 /// <param name="BufferSize"> 1263 /// The size of a buffer to fill with key/data pairs. Must be at least 1264 /// the page size of the underlying database and be a multiple of 1024. 1265 /// </param> 1266 /// <returns> 1267 /// True if the cursor was positioned successfully, false otherwise. 1268 /// </returns> 1269 public bool MoveNextMultipleKey(int BufferSize) { 1270 return MoveNextMultipleKey(BufferSize, null); 1271 } 1272 /// <summary> 1273 /// If the cursor is not yet initialized, MoveNextMultipleKey is 1274 /// identical to <see cref="MoveFirstMultipleKey(LockingInfo)"/>. 1275 /// Otherwise, move the cursor to the next key/data pair of the 1276 /// database, and store that pair and as many ensuing key/data pairs 1277 /// that can fit in a buffer the size of one database page in 1278 /// <see cref="CurrentMultipleKey"/>. In the presence of duplicate key 1279 /// values, the keys of <see cref="CurrentMultipleKey"/> may not change. 1280 /// </summary> 1281 /// <param name="info">The locking behavior to use.</param> 1282 /// <returns> 1283 /// True if the cursor was positioned successfully, false otherwise. 1284 /// </returns> 1285 public bool MoveNextMultipleKey(LockingInfo info) { 1286 return MoveNextMultipleKey((int)pgsz, null); 1287 } 1288 /// <summary> 1289 /// If the cursor is not yet initialized, MoveNextMultipleKey is 1290 /// identical to <see cref="MoveFirstMultipleKey(int, LockingInfo)"/>. 1291 /// Otherwise, move the cursor to the next key/data pair of the 1292 /// database, and store that pair and as many ensuing key/data pairs 1293 /// that can fit in a buffer the size of <paramref name="BufferSize"/> 1294 /// in <see cref="CurrentMultipleKey"/>. In the presence of duplicate 1295 /// key values, the keys of <see cref="CurrentMultipleKey"/> may not 1296 /// change. 1297 /// </summary> 1298 /// <param name="BufferSize"> 1299 /// The size of a buffer to fill with key/data pairs. Must be at least 1300 /// the page size of the underlying database and be a multiple of 1024. 1301 /// </param> 1302 /// <param name="info">The locking behavior to use.</param> 1303 /// <returns> 1304 /// True if the cursor was positioned successfully, false otherwise. 1305 /// </returns> 1306 public bool MoveNextMultipleKey(int BufferSize, LockingInfo info) { 1307 DatabaseEntry key = new DatabaseEntry(); 1308 DatabaseEntry data = new DatabaseEntry(); 1309 1310 return GetMultiple( 1311 key, data, BufferSize, DbConstants.DB_NEXT, info, true); 1312 } 1313 1314 /// <summary> 1315 /// If the next key/data pair of the database is a duplicate data record 1316 /// for the current key/data pair, move the cursor to the next key/data 1317 /// pair in the database, and store that pair in <see cref="Current"/>. 1318 /// MoveNextDuplicate will return false if the next key/data pair of the 1319 /// database is not a duplicate data record for the current key/data 1320 /// pair. 1321 /// </summary> 1322 /// <remarks> 1323 /// If positioning the cursor fails, <see cref="Current"/> will contain 1324 /// an empty <see cref="KeyValuePair{T,T}"/>. 1325 /// </remarks> 1326 /// <returns> 1327 /// True if the cursor was positioned successfully, false otherwise. 1328 /// </returns> 1329 public bool MoveNextDuplicate() { return MoveNextDuplicate(null); } 1330 /// <summary> 1331 /// If the next key/data pair of the database is a duplicate data record 1332 /// for the current key/data pair, move the cursor to the next key/data 1333 /// pair in the database, and store that pair in <see cref="Current"/>. 1334 /// MoveNextDuplicate will return false if the next key/data pair of the 1335 /// database is not a duplicate data record for the current key/data 1336 /// pair. 1337 /// </summary> 1338 /// <remarks> 1339 /// If positioning the cursor fails, <see cref="Current"/> will contain 1340 /// an empty <see cref="KeyValuePair{T,T}"/>. 1341 /// </remarks> 1342 /// <param name="info">The locking behavior to use.</param> 1343 /// <returns> 1344 /// True if the cursor was positioned successfully, false otherwise. 1345 /// </returns> 1346 public bool MoveNextDuplicate(LockingInfo info) { 1347 DatabaseEntry key = new DatabaseEntry(); 1348 DatabaseEntry data = new DatabaseEntry(); 1349 1350 return Get(key, data, DbConstants.DB_NEXT_DUP, info); 1351 } 1352 1353 /// <summary> 1354 /// If the next key/data pair of the database is a duplicate data record 1355 /// for the current key/data pair, move the cursor to the next key/data 1356 /// pair in the database, and store that pair and as many duplicate data 1357 /// items that can fit in a buffer the size of one database page in 1358 /// <see cref="CurrentMultiple"/>. MoveNextDuplicateMultiple will return 1359 /// false if the next key/data pair of the database is not a duplicate 1360 /// data record for the current key/data pair. 1361 /// </summary> 1362 /// <returns> 1363 /// True if the cursor was positioned successfully, false otherwise. 1364 /// </returns> 1365 public bool MoveNextDuplicateMultiple() { 1366 return MoveNextDuplicateMultiple((int)pgsz, null); 1367 } 1368 /// <summary> 1369 /// If the next key/data pair of the database is a duplicate data record 1370 /// for the current key/data pair, then move cursor to the next key/data 1371 /// pair in the database, and store that pair and as many duplicate data 1372 /// items that can fit in a buffer the size of 1373 /// <paramref name="BufferSize"/> in <see cref="CurrentMultiple"/>. 1374 /// MoveNextDuplicateMultiple will return false if the next key/data 1375 /// pair of the database is not a duplicate data record for the current 1376 /// key/data pair. 1377 /// </summary> 1378 /// <param name="BufferSize"> 1379 /// The size of a buffer to fill with duplicate data items. Must be at 1380 /// least the page size of the underlying database and be a multiple of 1381 /// 1024. 1382 /// </param> 1383 /// <returns> 1384 /// True if the cursor was positioned successfully, false otherwise. 1385 /// </returns> 1386 public bool MoveNextDuplicateMultiple(int BufferSize) { 1387 return MoveNextDuplicateMultiple(BufferSize, null); 1388 } 1389 /// <summary> 1390 /// If the next key/data pair of the database is a duplicate data record 1391 /// for the current key/data pair, move the cursor to the next key/data 1392 /// pair in the database, and store that pair and as many duplicate data 1393 /// items that can fit in a buffer the size of one database page in 1394 /// <see cref="CurrentMultiple"/>. MoveNextDuplicateMultiple will return 1395 /// false if the next key/data pair of the database is not a duplicate 1396 /// data record for the current key/data pair. 1397 /// </summary> 1398 /// <param name="info">The locking behavior to use.</param> 1399 /// <returns> 1400 /// True if the cursor was positioned successfully, false otherwise. 1401 /// </returns> 1402 public bool MoveNextDuplicateMultiple(LockingInfo info) { 1403 return MoveNextDuplicateMultiple((int)pgsz, info); 1404 } 1405 /// <summary> 1406 /// If the next key/data pair of the database is a duplicate data record 1407 /// for the current key/data pair, move the cursor to the next key/data 1408 /// pair in the database, and store that pair and as many duplicate data 1409 /// items that can fit in a buffer the size of 1410 /// <paramref name="BufferSize"/> in <see cref="CurrentMultiple"/>. 1411 /// MoveNextDuplicateMultiple will return false if the next key/data 1412 /// pair of the database is not a duplicate data record for the current 1413 /// key/data pair. 1414 /// </summary> 1415 /// <param name="BufferSize"> 1416 /// The size of a buffer to fill with duplicate data items. Must be at 1417 /// least the page size of the underlying database and be a multiple of 1418 /// 1024. 1419 /// </param> 1420 /// <param name="info">The locking behavior to use.</param> 1421 /// <returns> 1422 /// True if the cursor was positioned successfully, false otherwise. 1423 /// </returns> 1424 public bool MoveNextDuplicateMultiple( 1425 int BufferSize, LockingInfo info) { 1426 DatabaseEntry key = new DatabaseEntry(); 1427 DatabaseEntry data = new DatabaseEntry(); 1428 1429 return GetMultiple( 1430 key, data, BufferSize, DbConstants.DB_NEXT_DUP, info, false); 1431 } 1432 1433 /// <summary> 1434 /// If the next key/data pair of the database is a duplicate data record 1435 /// for the current key/data pair, move the cursor to the next key/data 1436 /// pair in the database, and store that pair and as many duplicate data 1437 /// items that can fit in a buffer the size of one database page in 1438 /// <see cref="CurrentMultipleKey"/>. MoveNextDuplicateMultipleKey will 1439 /// return false if the next key/data pair of the database is not a 1440 /// duplicate data record for the current key/data pair. 1441 /// </summary> 1442 /// <returns> 1443 /// True if the cursor was positioned successfully, false otherwise. 1444 /// </returns> 1445 public bool MoveNextDuplicateMultipleKey() { 1446 return MoveNextDuplicateMultipleKey((int)pgsz, null); 1447 } 1448 /// <summary> 1449 /// If the next key/data pair of the database is a duplicate data record 1450 /// for the current key/data pair, move the cursor to the next key/data 1451 /// pair in the database, and store that pair and as many duplicate data 1452 /// items that can fit in a buffer the size of 1453 /// <paramref name="BufferSize"/> in <see cref="CurrentMultipleKey"/>. 1454 /// MoveNextDuplicateMultipleKey will return false if the next key/data 1455 /// pair of the database is not a duplicate data record for the current 1456 /// key/data pair. 1457 /// </summary> 1458 /// <param name="BufferSize"> 1459 /// The size of a buffer to fill with key/data pairs. Must be at least 1460 /// the page size of the underlying database and be a multiple of 1024. 1461 /// </param> 1462 /// <returns> 1463 /// True if the cursor was positioned successfully, false otherwise. 1464 /// </returns> 1465 public bool MoveNextDuplicateMultipleKey(int BufferSize) { 1466 return MoveNextDuplicateMultipleKey(BufferSize, null); 1467 } 1468 /// <summary> 1469 /// If the next key/data pair of the database is a duplicate data record 1470 /// for the current key/data pair, move the cursor to the next key/data 1471 /// pair in the database, and store that pair and as many duplicate data 1472 /// items that can fit in a buffer the size of one database page in 1473 /// <see cref="CurrentMultipleKey"/>. MoveNextDuplicateMultipleKey will 1474 /// return false if the next key/data pair of the database is not a 1475 /// duplicate data record for the current key/data pair. 1476 /// </summary> 1477 /// <param name="info">The locking behavior to use.</param> 1478 /// <returns> 1479 /// True if the cursor was positioned successfully, false otherwise. 1480 /// </returns> 1481 public bool MoveNextDuplicateMultipleKey(LockingInfo info) { 1482 return MoveNextDuplicateMultipleKey((int)pgsz, info); 1483 } 1484 /// <summary> 1485 /// If the next key/data pair of the database is a duplicate data record 1486 /// for the current key/data pair, move the cursor to the next key/data 1487 /// pair in the database, and store that pair and as many duplicate data 1488 /// items that can fit in a buffer the size of 1489 /// <paramref name="BufferSize"/> in <see cref="CurrentMultipleKey"/>. 1490 /// MoveNextDuplicateMultipleKey will return false if the next key/data 1491 /// pair of the database is not a duplicate data record for the current 1492 /// key/data pair. 1493 /// </summary> 1494 /// <param name="BufferSize"> 1495 /// The size of a buffer to fill with key/data pairs. Must be at least 1496 /// the page size of the underlying database and be a multiple of 1024. 1497 /// </param> 1498 /// <param name="info">The locking behavior to use.</param> 1499 /// <returns> 1500 /// True if the cursor was positioned successfully, false otherwise. 1501 /// </returns> 1502 public bool MoveNextDuplicateMultipleKey( 1503 int BufferSize, LockingInfo info) { 1504 DatabaseEntry key = new DatabaseEntry(); 1505 DatabaseEntry data = new DatabaseEntry(); 1506 1507 return GetMultiple( 1508 key, data, BufferSize, DbConstants.DB_NEXT_DUP, info, true); 1509 } 1510 1511 /// <summary> 1512 /// If the cursor is not yet initialized, MoveNextUnique is identical to 1513 /// <see cref="MoveFirst()"/>. Otherwise, move the cursor to the next 1514 /// non-duplicate key in the database, and store that key and associated 1515 /// datum in <see cref="Current"/>. MoveNextUnique will return false if 1516 /// no non-duplicate key/data pairs exist after the cursor position in 1517 /// the database. 1518 /// </summary> 1519 /// <remarks> 1520 /// If positioning the cursor fails, <see cref="Current"/> will contain 1521 /// an empty <see cref="KeyValuePair{T,T}"/>. 1522 /// </remarks> 1523 /// <returns> 1524 /// True if the cursor was positioned successfully, false otherwise. 1525 /// </returns> 1526 public bool MoveNextUnique() { return MoveNextUnique(null); } 1527 /// <summary> 1528 /// If the cursor is not yet initialized, MoveNextUnique is identical to 1529 /// <see cref="MoveFirst(LockingInfo)"/>. Otherwise, move the cursor to 1530 /// the next non-duplicate key in the database, and store that key and 1531 /// associated datum in <see cref="Current"/>. MoveNextUnique will 1532 /// return false if no non-duplicate key/data pairs exist after the 1533 /// cursor position in the database. 1534 /// </summary> 1535 /// <remarks> 1536 /// <para> 1537 /// If the database is a Queue or Recno database, MoveNextUnique will 1538 /// ignore any keys that exist but were never explicitly created by the 1539 /// application, or those that were created and later deleted. 1540 /// </para> 1541 /// <para> 1542 /// If positioning the cursor fails, <see cref="Current"/> will contain 1543 /// an empty <see cref="KeyValuePair{T,T}"/>. 1544 /// </para> 1545 /// </remarks> 1546 /// <param name="info">The locking behavior to use.</param> 1547 /// <returns> 1548 /// True if the cursor was positioned successfully, false otherwise. 1549 /// </returns> 1550 public bool MoveNextUnique(LockingInfo info) { 1551 DatabaseEntry key = new DatabaseEntry(); 1552 DatabaseEntry data = new DatabaseEntry(); 1553 1554 return Get(key, data, DbConstants.DB_NEXT_NODUP, info); 1555 } 1556 1557 /// <summary> 1558 /// If the cursor is not yet initialized, MoveNextUniqueMultiple is 1559 /// identical to <see cref="MoveFirstMultiple()"/>. Otherwise, move the 1560 /// cursor to the next non-duplicate key in the database, and store that 1561 /// key and associated datum and as many duplicate data items that can 1562 /// fit in a buffer the size of one database page in 1563 /// <see cref="CurrentMultiple"/>. MoveNextUniqueMultiple will return 1564 /// false if no non-duplicate key/data pairs exist after the cursor 1565 /// position in the database. 1566 /// </summary> 1567 /// <returns> 1568 /// True if the cursor was positioned successfully, false otherwise. 1569 /// </returns> 1570 public bool MoveNextUniqueMultiple() { 1571 return MoveNextUniqueMultiple((int)pgsz, null); 1572 } 1573 /// <summary> 1574 /// If the cursor is not yet initialized, MoveNextUniqueMultiple is 1575 /// identical to <see cref="MoveFirstMultiple(int)"/>. Otherwise, move 1576 /// the cursor to the next non-duplicate key in the database, and store 1577 /// that key and associated datum and as many duplicate data items that 1578 /// can fit in a buffer the size of <paramref name="BufferSize"/> in 1579 /// <see cref="CurrentMultiple"/>. MoveNextUniqueMultiple will return 1580 /// false if no non-duplicate key/data pairs exist after the cursor 1581 /// position in the database. 1582 /// </summary> 1583 /// <param name="BufferSize"> 1584 /// The size of a buffer to fill with duplicate data items. Must be at 1585 /// least the page size of the underlying database and be a multiple of 1586 /// 1024. 1587 /// </param> 1588 /// <returns> 1589 /// True if the cursor was positioned successfully, false otherwise. 1590 /// </returns> 1591 public bool MoveNextUniqueMultiple(int BufferSize) { 1592 return MoveNextUniqueMultiple(BufferSize, null); 1593 } 1594 /// <summary> 1595 /// If the cursor is not yet initialized, MoveNextUniqueMultiple is 1596 /// identical to <see cref="MoveFirstMultiple(LockingInfo)"/>. 1597 /// Otherwise, move the cursor to the next non-duplicate key in the 1598 /// database, and store that key and associated datum and as many 1599 /// duplicate data items that can fit in a buffer the size of one 1600 /// database page in <see cref="CurrentMultiple"/>. 1601 /// MoveNextUniqueMultiple will return false if no non-duplicate 1602 /// key/data pairs exist after the cursor position in the database. 1603 /// </summary> 1604 /// <param name="info">The locking behavior to use.</param> 1605 /// <returns> 1606 /// True if the cursor was positioned successfully, false otherwise. 1607 /// </returns> 1608 public bool MoveNextUniqueMultiple(LockingInfo info) { 1609 return MoveNextUniqueMultiple((int)pgsz, info); 1610 } 1611 /// <summary> 1612 /// If the cursor is not yet initialized, MoveNextUniqueMultiple is 1613 /// identical to <see cref="MoveFirstMultiple(int, LockingInfo)"/>. 1614 /// Otherwise, move the cursor to the next non-duplicate key in the 1615 /// database, and store that key and associated datum and as many 1616 /// duplicate data items that can fit in a buffer the size of 1617 /// <paramref name="BufferSize"/> in <see cref="CurrentMultiple"/>. 1618 /// MoveNextUniqueMultiple will return false if no non-duplicate 1619 /// key/data pairs exist after the cursor position in the database. 1620 /// </summary> 1621 /// <param name="BufferSize"> 1622 /// The size of a buffer to fill with duplicate data items. Must be at 1623 /// least the page size of the underlying database and be a multiple of 1624 /// 1024. 1625 /// </param> 1626 /// <param name="info">The locking behavior to use.</param> 1627 /// <returns> 1628 /// True if the cursor was positioned successfully, false otherwise. 1629 /// </returns> 1630 public bool MoveNextUniqueMultiple(int BufferSize, LockingInfo info) { 1631 DatabaseEntry key = new DatabaseEntry(); 1632 DatabaseEntry data = new DatabaseEntry(); 1633 1634 return GetMultiple( 1635 key, data, BufferSize, DbConstants.DB_NEXT_NODUP, info, false); 1636 } 1637 1638 /// <summary> 1639 /// If the cursor is not yet initialized, MoveNextUniqueMultipleKey is 1640 /// identical to <see cref="MoveFirstMultipleKey()"/>. Otherwise, move 1641 /// the cursor to the next non-duplicate key in the database, and store 1642 /// that key and associated datum and as many ensuing key/data pairs 1643 /// that can fit in a buffer the size of one database page in 1644 /// <see cref="CurrentMultipleKey"/>. MoveNextUniqueMultipleKey will 1645 /// return false if no non-duplicate key/data pairs exist after the 1646 /// cursor position in the database. 1647 /// </summary> 1648 /// <returns> 1649 /// True if the cursor was positioned successfully, false otherwise. 1650 /// </returns> 1651 public bool MoveNextUniqueMultipleKey() { 1652 return MoveNextUniqueMultipleKey((int)pgsz, null); 1653 } 1654 /// <summary> 1655 /// If the cursor is not yet initialized, MoveNextUniqueMultipleKey is 1656 /// identical to <see cref="MoveFirstMultipleKey(int)"/>. Otherwise, 1657 /// move the cursor to the next non-duplicate key in the database, and 1658 /// store that key and associated datum and as many ensuing key/data 1659 /// pairs that can fit in a buffer the size of 1660 /// <paramref name="BufferSize"/> in <see cref="CurrentMultipleKey"/>. 1661 /// MoveNextUniqueMultipleKey will return false if no non-duplicate 1662 /// key/data pairs exist after the cursor position in the database. 1663 /// </summary> 1664 /// <param name="BufferSize"> 1665 /// The size of a buffer to fill with key/data pairs. Must be at least 1666 /// the page size of the underlying database and be a multiple of 1024. 1667 /// </param> 1668 /// <returns> 1669 /// True if the cursor was positioned successfully, false otherwise. 1670 /// </returns> 1671 public bool MoveNextUniqueMultipleKey(int BufferSize) { 1672 return MoveNextUniqueMultipleKey(BufferSize, null); 1673 } 1674 /// <summary> 1675 /// If the cursor is not yet initialized, MoveNextUniqueMultipleKey is 1676 /// identical to <see cref="MoveFirstMultipleKey(LockingInfo)"/>. 1677 /// Otherwise, move the cursor to the next non-duplicate key in the 1678 /// database, and store that key and associated datum and as many 1679 /// ensuing key/data pairs that can fit in a buffer the size of one 1680 /// database page in <see cref="CurrentMultipleKey"/>. 1681 /// MoveNextUniqueMultipleKey will return false if no non-duplicate 1682 /// key/data pairs exist after the cursor position in the database. 1683 /// </summary> 1684 /// <param name="info">The locking behavior to use.</param> 1685 /// <returns> 1686 /// True if the cursor was positioned successfully, false otherwise. 1687 /// </returns> 1688 public bool MoveNextUniqueMultipleKey(LockingInfo info) { 1689 return MoveNextUniqueMultipleKey((int)pgsz, info); 1690 } 1691 /// <summary> 1692 /// If the cursor is not yet initialized, MoveNextUniqueMultipleKey is 1693 /// identical to <see cref="MoveFirstMultipleKey(int, LockingInfo)"/>. 1694 /// Otherwise, move the cursor to the next non-duplicate key in the 1695 /// database, and store that key and associated datum and as many 1696 /// ensuing key/data pairs that can fit in a buffer the size of 1697 /// <paramref name="BufferSize"/> in <see cref="CurrentMultipleKey"/>. 1698 /// MoveNextUniqueMultipleKey will return false if no non-duplicate 1699 /// key/data pairs exist after the cursor position in the database. 1700 /// </summary> 1701 /// <param name="BufferSize"> 1702 /// The size of a buffer to fill with key/data pairs. Must be at least 1703 /// the page size of the underlying database and be a multiple of 1024. 1704 /// </param> 1705 /// <param name="info">The locking behavior to use.</param> 1706 /// <returns> 1707 /// True if the cursor was positioned successfully, false otherwise. 1708 /// </returns> 1709 public bool MoveNextUniqueMultipleKey( 1710 int BufferSize, LockingInfo info) { 1711 DatabaseEntry key = new DatabaseEntry(); 1712 DatabaseEntry data = new DatabaseEntry(); 1713 1714 return GetMultiple( 1715 key, data, BufferSize, DbConstants.DB_NEXT_NODUP, info, true); 1716 } 1717 1718 /// <summary> 1719 /// If the cursor is not yet initialized, MovePrev is identical to 1720 /// <see cref="MoveLast()"/>. Otherwise, move the cursor to the previous 1721 /// key/data pair of the database, and store that pair in 1722 /// <see cref="Current"/>. In the presence of duplicate key values, the 1723 /// value of <see cref="Current">Current.Key</see> may not change. 1724 /// </summary> 1725 /// <remarks> 1726 /// If positioning the cursor fails, <see cref="Current"/> will contain 1727 /// an empty <see cref="KeyValuePair{T,T}"/>. 1728 /// </remarks> 1729 /// <returns> 1730 /// True if the cursor was positioned successfully, false otherwise. 1731 /// </returns> 1732 public bool MovePrev() { return MovePrev(null); } 1733 /// <summary> 1734 /// If the cursor is not yet initialized, MovePrev is identical to 1735 /// <see cref="MoveLast(LockingInfo)"/>. Otherwise, move the cursor to 1736 /// the previous key/data pair of the database, and store that pair in 1737 /// <see cref="Current"/>. In the presence of duplicate key values, the 1738 /// value of <see cref="Current">Current.Key</see> may not change. 1739 /// </summary> 1740 /// <remarks> 1741 /// If positioning the cursor fails, <see cref="Current"/> will contain 1742 /// an empty <see cref="KeyValuePair{T,T}"/>. 1743 /// </remarks> 1744 /// <param name="info">The locking behavior to use.</param> 1745 /// <returns> 1746 /// True if the cursor was positioned successfully, false otherwise. 1747 /// </returns> 1748 public bool MovePrev(LockingInfo info) { 1749 DatabaseEntry key = new DatabaseEntry(); 1750 DatabaseEntry data = new DatabaseEntry(); 1751 1752 return Get(key, data, DbConstants.DB_PREV, info); 1753 } 1754 1755 /// <summary> 1756 /// If the previous key/data pair of the database is a duplicate data 1757 /// record for the current key/data pair, the cursor is moved to the 1758 /// previous key/data pair of the database, and that pair is stored in 1759 /// <see cref="Current"/>. MovePrevDuplicate will return false if the 1760 /// previous key/data pair of the database is not a duplicate data 1761 /// record for the current key/data pair. 1762 /// </summary> 1763 /// <remarks> 1764 /// If positioning the cursor fails, <see cref="Current"/> will contain 1765 /// an empty <see cref="KeyValuePair{T,T}"/>. 1766 /// </remarks> 1767 /// <returns> 1768 /// True if the cursor was positioned successfully, false otherwise. 1769 /// </returns> 1770 public bool MovePrevDuplicate() { return MovePrevDuplicate(null); } 1771 /// <summary> 1772 /// If the previous key/data pair of the database is a duplicate data 1773 /// record for the current key/data pair, the cursor is moved to the 1774 /// previous key/data pair of the database, and that pair is stored in 1775 /// <see cref="Current"/>. MovePrevDuplicate will return false if the 1776 /// previous key/data pair of the database is not a duplicate data 1777 /// record for the current key/data pair. 1778 /// </summary> 1779 /// <remarks> 1780 /// If positioning the cursor fails, <see cref="Current"/> will contain 1781 /// an empty <see cref="KeyValuePair{T,T}"/>. 1782 /// </remarks> 1783 /// <param name="info">The locking behavior to use.</param> 1784 /// <returns> 1785 /// True if the cursor was positioned successfully, false otherwise. 1786 /// </returns> 1787 public bool MovePrevDuplicate(LockingInfo info) { 1788 DatabaseEntry key = new DatabaseEntry(); 1789 DatabaseEntry data = new DatabaseEntry(); 1790 1791 return Get(key, data, DbConstants.DB_PREV_DUP, info); 1792 } 1793 1794 /// <summary> 1795 /// If the cursor is not yet initialized, MovePrevUnique is identical to 1796 /// <see cref="MoveLast()"/>. Otherwise, move the cursor to the previous 1797 /// non-duplicate key in the database, and store that key and associated 1798 /// datum in <see cref="Current"/>. MovePrevUnique will return false if 1799 /// no non-duplicate key/data pairs exist after the cursor position in 1800 /// the database. 1801 /// </summary> 1802 /// <remarks> 1803 /// If positioning the cursor fails, <see cref="Current"/> will contain 1804 /// an empty <see cref="KeyValuePair{T,T}"/>. 1805 /// </remarks> 1806 /// <returns> 1807 /// True if the cursor was positioned successfully, false otherwise. 1808 /// </returns> 1809 public bool MovePrevUnique() { return MovePrevUnique(null); } 1810 /// <summary> 1811 /// If the cursor is not yet initialized, MovePrevUnique is identical to 1812 /// <see cref="MoveLast(LockingInfo)"/>. Otherwise, move the cursor to 1813 /// the previous non-duplicate key in the database, and store that key 1814 /// and associated datum in <see cref="Current"/>. MovePrevUnique will 1815 /// return false if no non-duplicate key/data pairs exist after the 1816 /// cursor position in the database. 1817 /// </summary> 1818 /// <remarks> 1819 /// If positioning the cursor fails, <see cref="Current"/> will contain 1820 /// an empty <see cref="KeyValuePair{T,T}"/>. 1821 /// </remarks> 1822 /// <param name="info">The locking behavior to use.</param> 1823 /// <returns> 1824 /// True if the cursor was positioned successfully, false otherwise. 1825 /// </returns> 1826 public bool MovePrevUnique(LockingInfo info) { 1827 DatabaseEntry key = new DatabaseEntry(); 1828 DatabaseEntry data = new DatabaseEntry(); 1829 1830 return Get(key, data, DbConstants.DB_PREV_NODUP, info); 1831 } 1832 1833 /// <summary> 1834 /// Overwrite the data of the key/data pair to which the cursor refers 1835 /// with the specified data item. 1836 /// </summary> 1837 /// <param name="data"></param> 1838 public void Overwrite(DatabaseEntry data) { 1839 DatabaseEntry key = new DatabaseEntry(); 1840 1841 Put(key, data, DbConstants.DB_CURRENT); 1842 } 1843 1844 /// <summary> 1845 /// Store the key/data pair to which the cursor refers in 1846 /// <see cref="Current"/>. 1847 /// </summary> 1848 /// <remarks> 1849 /// If positioning the cursor fails, <see cref="Current"/> will contain 1850 /// an empty <see cref="KeyValuePair{T,T}"/>. 1851 /// </remarks> 1852 /// <returns> 1853 /// True if the cursor was positioned successfully, false otherwise. 1854 /// </returns> 1855 public bool Refresh() { return Refresh(null); } 1856 /// <summary> 1857 /// Store the key/data pair to which the cursor refers in 1858 /// <see cref="Current"/>. 1859 /// </summary> 1860 /// <remarks> 1861 /// If positioning the cursor fails, <see cref="Current"/> will contain 1862 /// an empty <see cref="KeyValuePair{T,T}"/>. 1863 /// </remarks> 1864 /// <param name="info">The locking behavior to use.</param> 1865 /// <returns> 1866 /// True if the cursor was positioned successfully, false otherwise. 1867 /// </returns> 1868 public bool Refresh(LockingInfo info) { 1869 DatabaseEntry key = new DatabaseEntry(); 1870 DatabaseEntry data = new DatabaseEntry(); 1871 1872 return Get(key, data, DbConstants.DB_CURRENT, info); 1873 } 1874 1875 /// <summary> 1876 /// Store the key/data pair to which the cursor refers and as many 1877 /// duplicate data items that can fit in a buffer the size of one 1878 /// database page in <see cref="CurrentMultiple"/>. 1879 /// </summary> 1880 /// <returns> 1881 /// True if the cursor was positioned successfully, false otherwise. 1882 /// </returns> 1883 public bool RefreshMultiple() { 1884 return RefreshMultiple((int)pgsz, null); 1885 } 1886 /// <summary> 1887 /// Store the key/data pair to which the cursor refers and as many 1888 /// duplicate data items that can fit in a buffer the size of 1889 /// <paramref name="BufferSize"/> in <see cref="CurrentMultiple"/>. 1890 /// </summary> 1891 /// <param name="BufferSize"> 1892 /// The size of a buffer to fill with duplicate data items. Must be at 1893 /// least the page size of the underlying database and be a multiple of 1894 /// 1024. 1895 /// </param> 1896 /// <returns> 1897 /// True if the cursor was positioned successfully, false otherwise. 1898 /// </returns> 1899 public bool RefreshMultiple(int BufferSize) { 1900 return RefreshMultiple(BufferSize, null); 1901 } 1902 /// <summary> 1903 /// Store the key/data pair to which the cursor refers and as many 1904 /// duplicate data items that can fit in a buffer the size of one 1905 /// database page in <see cref="CurrentMultiple"/>. 1906 /// </summary> 1907 /// <param name="info">The locking behavior to use.</param> 1908 /// <returns> 1909 /// True if the cursor was positioned successfully, false otherwise. 1910 /// </returns> 1911 public bool RefreshMultiple(LockingInfo info) { 1912 return RefreshMultiple((int)pgsz, info); 1913 } 1914 /// <summary> 1915 /// Store the key/data pair to which the cursor refers and as many 1916 /// duplicate data items that can fit in a buffer the size of 1917 /// <paramref name="BufferSize"/> in <see cref="CurrentMultiple"/>. 1918 /// </summary> 1919 /// <param name="BufferSize"> 1920 /// The size of a buffer to fill with duplicate data items. Must be at 1921 /// least the page size of the underlying database and be a multiple of 1922 /// 1024. 1923 /// </param> 1924 /// <param name="info">The locking behavior to use.</param> 1925 /// <returns> 1926 /// True if the cursor was positioned successfully, false otherwise. 1927 /// </returns> 1928 public bool RefreshMultiple(int BufferSize, LockingInfo info) { 1929 DatabaseEntry key = new DatabaseEntry(); 1930 DatabaseEntry data = new DatabaseEntry(); 1931 1932 return GetMultiple( 1933 key, data, BufferSize, DbConstants.DB_CURRENT, info, false); 1934 } 1935 1936 /// <summary> 1937 /// Store the key/data pair to which the cursor refers and as many 1938 /// ensuing key/data pairs that can fit in a buffer the size of one 1939 /// database page in <see cref="CurrentMultipleKey"/>. 1940 /// </summary> 1941 /// <returns> 1942 /// True if the cursor was positioned successfully, false otherwise. 1943 /// </returns> 1944 public bool RefreshMultipleKey() { 1945 return RefreshMultipleKey((int)pgsz, null); 1946 } 1947 /// <summary> 1948 /// Store the key/data pair to which the cursor refers and as many 1949 /// ensuing key/data pairs that can fit in a buffer the size of 1950 /// <paramref name="BufferSize"/> in <see cref="CurrentMultipleKey"/>. 1951 /// </summary> 1952 /// <param name="BufferSize"> 1953 /// The size of a buffer to fill with key/data pairs. Must be at least 1954 /// the page size of the underlying database and be a multiple of 1024. 1955 /// </param> 1956 /// <returns> 1957 /// True if the cursor was positioned successfully, false otherwise. 1958 /// </returns> 1959 public bool RefreshMultipleKey(int BufferSize) { 1960 return RefreshMultipleKey(BufferSize, null); 1961 } 1962 /// <summary> 1963 /// Store the key/data pair to which the cursor refers and as many 1964 /// ensuing key/data pairs that can fit in a buffer the size of one 1965 /// database page in <see cref="CurrentMultipleKey"/>. 1966 /// </summary> 1967 /// <param name="info">The locking behavior to use.</param> 1968 /// <returns> 1969 /// True if the cursor was positioned successfully, false otherwise. 1970 /// </returns> 1971 public bool RefreshMultipleKey(LockingInfo info) { 1972 return RefreshMultipleKey((int)pgsz, info); 1973 } 1974 /// <summary> 1975 /// Store the key/data pair to which the cursor refers and as many 1976 /// ensuing key/data pairs that can fit in a buffer the size of 1977 /// <paramref name="BufferSize"/> in <see cref="CurrentMultipleKey"/>. 1978 /// </summary> 1979 /// <param name="BufferSize"> 1980 /// The size of a buffer to fill with key/data pairs. Must be at least 1981 /// the page size of the underlying database and be a multiple of 1024. 1982 /// </param> 1983 /// <param name="info">The locking behavior to use.</param> 1984 /// <returns> 1985 /// True if the cursor was positioned successfully, false otherwise. 1986 /// </returns> 1987 public bool RefreshMultipleKey(int BufferSize, LockingInfo info) { 1988 DatabaseEntry key = new DatabaseEntry(); 1989 DatabaseEntry data = new DatabaseEntry(); 1990 1991 return GetMultiple( 1992 key, data, BufferSize, DbConstants.DB_CURRENT, info, true); 1993 } 1994 } 1995} 1996