1 /*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved. 5 * 6 */ 7 using System; 8 using System.Collections; 9 using System.Collections.Generic; 10 using System.Text; 11 using BerkeleyDB.Internal; 12 13 namespace BerkeleyDB { 14 /// <summary> 15 /// A class representing database cursors over secondary indexes, which 16 /// allow for traversal of database records. 17 /// </summary> 18 public class SecondaryCursor 19 : BaseCursor, IEnumerable<KeyValuePair<DatabaseEntry, 20 KeyValuePair<DatabaseEntry, DatabaseEntry>>> { 21 private KeyValuePair<DatabaseEntry, 22 KeyValuePair<DatabaseEntry, DatabaseEntry>> cur; 23 /// <summary> 24 /// The secondary key and primary key/data pair at which the cursor 25 /// currently points. 26 /// </summary> 27 public KeyValuePair<DatabaseEntry, 28 KeyValuePair<DatabaseEntry, DatabaseEntry>> Current { 29 get { return cur; } 30 private set { cur = value; } 31 } SecondaryCursor(DBC dbc)32 internal SecondaryCursor(DBC dbc) : base(dbc) { } 33 34 /// <summary> 35 /// Protected method wrapping DBC->pget() 36 /// </summary> 37 /// <param name="key">The secondary key</param> 38 /// <param name="pkey">The primary key</param> 39 /// <param name="data">The primary data</param> 40 /// <param name="flags">Flags to pass to DBC->pget</param> 41 /// <param name="info">Locking parameters</param> 42 /// <returns></returns> PGet( DatabaseEntry key, DatabaseEntry pkey, DatabaseEntry data, uint flags, LockingInfo info)43 protected bool PGet( 44 DatabaseEntry key, DatabaseEntry pkey, 45 DatabaseEntry data, uint flags, LockingInfo info) { 46 flags |= (info == null) ? 0 : info.flags; 47 try { 48 dbc.pget(key, pkey, data, flags); 49 Current = new KeyValuePair<DatabaseEntry, 50 KeyValuePair<DatabaseEntry, DatabaseEntry>>(key, 51 new KeyValuePair<DatabaseEntry, DatabaseEntry>(pkey, data)); 52 return true; 53 } catch (NotFoundException) { 54 Current = new KeyValuePair<DatabaseEntry, 55 KeyValuePair<DatabaseEntry, DatabaseEntry>>( 56 null, new KeyValuePair<DatabaseEntry, DatabaseEntry>()); 57 return false; 58 } 59 } 60 61 /// <summary> 62 /// Delete the key/data pair to which the cursor refers from the primary 63 /// database and all secondary indices. 64 /// </summary> 65 /// <remarks> 66 /// <para> 67 /// The cursor position is unchanged after a delete, and subsequent 68 /// calls to cursor functions expecting the cursor to refer to an 69 /// existing key will fail. 70 /// </para> 71 /// </remarks> 72 /// <exception cref="KeyEmptyException"> 73 /// The element has already been deleted. 74 /// </exception> Delete()75 public new void Delete() { 76 base.Delete(); 77 Current = 78 new KeyValuePair<DatabaseEntry, 79 KeyValuePair<DatabaseEntry, DatabaseEntry>>( 80 null, new KeyValuePair<DatabaseEntry, DatabaseEntry>()); 81 } 82 83 /// <summary> 84 /// Create a new cursor that uses the same transaction and locker ID as 85 /// the original cursor. 86 /// </summary> 87 /// <remarks> 88 /// This is useful when an application is using locking and requires two 89 /// or more cursors in the same thread of control. 90 /// </remarks> 91 /// <param name="keepPosition"> 92 /// If true, the newly created cursor is initialized to refer to the 93 /// same position in the database as the original cursor (if any) and 94 /// hold the same locks (if any). If false, or the original cursor does 95 /// not hold a database position and locks, the created cursor is 96 /// uninitialized and will behave like a cursor newly created by 97 /// <see cref="BaseDatabase.Cursor"/>.</param> 98 /// <returns>A newly created cursor</returns> Duplicate(bool keepPosition)99 public SecondaryCursor Duplicate(bool keepPosition) { 100 return new SecondaryCursor( 101 dbc.dup(keepPosition ? DbConstants.DB_POSITION : 0)); 102 } 103 IEnumerable.GetEnumerator()104 IEnumerator IEnumerable.GetEnumerator() { 105 return GetEnumerator(); 106 } 107 108 /// <summary> 109 /// Returns an enumerator that iterates through the 110 /// <see cref="SecondaryCursor"/>. 111 /// </summary> 112 /// <remarks> 113 /// The enumerator will begin at the cursor's current position (or the 114 /// first record if the cursor has not yet been positioned) and iterate 115 /// forwards (i.e. in the direction of <see cref="MoveNext"/>) over the 116 /// remaining records. 117 /// </remarks> 118 /// <returns>An enumerator for the SecondaryCursor.</returns> 119 public new IEnumerator<KeyValuePair<DatabaseEntry, GetEnumerator()120 KeyValuePair<DatabaseEntry, DatabaseEntry>>> GetEnumerator() { 121 while (MoveNext()) 122 yield return Current; 123 } 124 125 /// <summary> 126 /// Set the cursor to refer to the first key/data pair of the database, 127 /// and store the secondary key along with the corresponding primary 128 /// key/data pair in <see cref="Current"/>. If the first key has 129 /// duplicate values, the first data item in the set of duplicates is 130 /// stored in <see cref="Current"/>. 131 /// </summary> 132 /// <remarks> 133 /// If positioning the cursor fails, <see cref="Current"/> will contain 134 /// an empty <see cref="KeyValuePair{T,T}"/>. 135 /// </remarks> 136 /// <returns> 137 /// True if the cursor was positioned successfully, false otherwise. 138 /// </returns> MoveFirst()139 public bool MoveFirst() { return MoveFirst(null); } 140 /// <summary> 141 /// Set the cursor to refer to the first key/data pair of the database, 142 /// and store the secondary key along with the corresponding primary 143 /// key/data pair in <see cref="Current"/>. If the first key has 144 /// duplicate values, the first data item in the set of duplicates is 145 /// stored in <see cref="Current"/>. 146 /// </summary> 147 /// <remarks> 148 /// If positioning the cursor fails, <see cref="Current"/> will contain 149 /// an empty <see cref="KeyValuePair{T,T}"/>. 150 /// </remarks> 151 /// <param name="info">The locking behavior to use.</param> 152 /// <returns> 153 /// True if the cursor was positioned successfully, false otherwise. 154 /// </returns> MoveFirst(LockingInfo info)155 public bool MoveFirst(LockingInfo info) { 156 DatabaseEntry key = new DatabaseEntry(); 157 DatabaseEntry pkey = new DatabaseEntry(); 158 DatabaseEntry data = new DatabaseEntry(); 159 160 return MoveFirst(key, pkey, data, info); 161 } 162 /// <summary> 163 /// Set the cursor to refer to the first key/data pair of the database, 164 /// and store the secondary key along with the corresponding primary 165 /// key/data pair in <see cref="Current"/>. If the first key has 166 /// duplicate values, the first data item in the set of duplicates is 167 /// stored in <see cref="Current"/>. If <paramref name="key"/>, or 168 /// <paramref name="pkey"/>, or <paramref name="data"/> is 169 /// partial <see cref="DatabaseEntry"/>, its 170 /// <see cref="DatabaseEntry.PartialLen"/> bytes starting 171 /// <see cref="DatabaseEntry.PartialOffset"/> bytes from the beginning 172 /// of the retrieved data record are returned as if they comprised the 173 /// entire record. If any or all of the specified bytes do not exist 174 /// in the record, MoveFirst is successful, and any existing bytes are 175 /// returned. 176 /// </summary> 177 /// <remarks> 178 /// If positioning the cursor fails, <see cref="Current"/> will contain 179 /// an empty <see cref="KeyValuePair{T,T}"/>. 180 /// </remarks> 181 /// <param name="key">The retrieved key in secondary db</param> 182 /// <param name="pkey">The retrieved key in primary db</param> 183 /// <param name="data">The retrieved data in primary db</param> 184 /// <returns> 185 /// True if the cursor was positioned successfully, false otherwise. 186 /// </returns> MoveFirst( DatabaseEntry key, DatabaseEntry pkey, DatabaseEntry data)187 public bool MoveFirst( 188 DatabaseEntry key, DatabaseEntry pkey, DatabaseEntry data) { 189 return MoveFirst(key, pkey, data, null); 190 } 191 /// <summary> 192 /// Set the cursor to refer to the first key/data pair of the database, 193 /// and store the secondary key along with the corresponding primary 194 /// key/data pair in <see cref="Current"/>. If the first key has 195 /// duplicate values, the first data item in the set of duplicates is 196 /// stored in <see cref="Current"/>. If <paramref name="key"/>, or 197 /// <paramref name="pkey"/>, or <paramref name="data"/> is 198 /// partial <see cref="DatabaseEntry"/>, its 199 /// <see cref="DatabaseEntry.PartialLen"/> bytes starting 200 /// <see cref="DatabaseEntry.PartialOffset"/> bytes from the beginning 201 /// of the retrieved data record are returned as if they comprised the 202 /// entire record. If any or all of the specified bytes do not exist 203 /// in the record, MoveFirst is successful, and any existing bytes are 204 /// returned. 205 /// </summary> 206 /// <remarks> 207 /// If positioning the cursor fails, <see cref="Current"/> will contain 208 /// an empty <see cref="KeyValuePair{T,T}"/>. 209 /// </remarks> 210 /// <param name="key">The retrieved key in secondary db</param> 211 /// <param name="pkey">The retrieved key in primary db</param> 212 /// <param name="data">The retrieved data in primary db</param> 213 /// <param name="info">The locking behavior to use.</param> 214 /// <returns> 215 /// True if the cursor was positioned successfully, false otherwise. 216 /// </returns> MoveFirst(DatabaseEntry key, DatabaseEntry pkey, DatabaseEntry data, LockingInfo info)217 public bool MoveFirst(DatabaseEntry key, DatabaseEntry pkey, 218 DatabaseEntry data, LockingInfo info) { 219 return PGet(key, pkey, data, DbConstants.DB_FIRST, info); 220 } 221 222 /// <summary> 223 /// Set the cursor to refer to <paramref name="key"/>, and store the 224 /// primary key/data pair associated with the given secondary key in 225 /// <see cref="Current"/>. In the presence of duplicate key values, the 226 /// first data item in the set of duplicates is stored in 227 /// <see cref="Current"/>. 228 /// </summary> 229 /// <remarks> 230 /// If positioning the cursor fails, <see cref="Current"/> will contain 231 /// an empty <see cref="KeyValuePair{T,T}"/>. 232 /// </remarks> 233 /// <param name="key">The key at which to position the cursor</param> 234 /// <param name="exact"> 235 /// If false and in a database configured for sorted duplicates, 236 /// position the cursor at the smallest key greater than or equal to the 237 /// specified key, permitting partial key matches and range searches. 238 /// Otherwise, require the given key to match the key in the database 239 /// exactly. 240 /// </param> 241 /// <returns> 242 /// True if the cursor was positioned successfully, false otherwise. 243 /// </returns> Move(DatabaseEntry key, bool exact)244 public bool Move(DatabaseEntry key, bool exact) { 245 return Move(key, exact, null); 246 } 247 /// <summary> 248 /// Set the cursor to refer to <paramref name="key"/>, and store the 249 /// primary key/data pair associated with the given secondary key in 250 /// <see cref="Current"/>. In the presence of duplicate key values, the 251 /// first data item in the set of duplicates is stored in 252 /// <see cref="Current"/>. 253 /// </summary> 254 /// <remarks> 255 /// If positioning the cursor fails, <see cref="Current"/> will contain 256 /// an empty <see cref="KeyValuePair{T,T}"/>. 257 /// </remarks> 258 /// <param name="key">The key at which to position the cursor</param> 259 /// <param name="exact"> 260 /// If false and in a database configured for sorted duplicates, 261 /// position the cursor at the smallest key greater than or equal to the 262 /// specified key, permitting partial key matches and range searches. 263 /// Otherwise, require the given key to match the key in the database 264 /// exactly. 265 /// </param> 266 /// <param name="info">The locking behavior to use.</param> 267 /// <returns> 268 /// True if the cursor was positioned successfully, false otherwise. 269 /// </returns> Move(DatabaseEntry key, bool exact, LockingInfo info)270 public bool Move(DatabaseEntry key, bool exact, LockingInfo info) { 271 DatabaseEntry pkey = new DatabaseEntry(); 272 DatabaseEntry data = new DatabaseEntry(); 273 274 return Move(key, pkey, data, exact, info); 275 } 276 /// <summary> 277 /// Set the cursor to refer to <paramref name="key"/>, and store the 278 /// primary key/data pair associated with the given secondary key in 279 /// <see cref="Current"/>. In the presence of duplicate key values, the 280 /// first data item in the set of duplicates is stored in 281 /// <see cref="Current"/>. If <paramref name="key"/>, or 282 /// <paramref name="pkey"/>, or <paramref name="data"/> is 283 /// partial <see cref="DatabaseEntry"/>, its 284 /// <see cref="DatabaseEntry.PartialLen"/> bytes starting 285 /// <see cref="DatabaseEntry.PartialOffset"/> bytes from the beginning 286 /// of the retrieved data record are returned as if they comprised the 287 /// entire record. If any or all of the specified bytes do not exist 288 /// in the record, Move is successful, and any existing bytes are 289 /// returned. 290 /// </summary> 291 /// <remarks> 292 /// If positioning the cursor fails, <see cref="Current"/> will contain 293 /// an empty <see cref="KeyValuePair{T,T}"/>. 294 /// </remarks> 295 /// <param name="key">The key at which to position the cursor</param> 296 /// <param name="pkey"> 297 /// The key of the current matching record in primary db 298 /// </param> 299 /// <param name="data"> 300 /// The data of the current matching record in primary db 301 /// </param> 302 /// <param name="exact"> 303 /// If false and in a database configured for sorted duplicates, 304 /// position the cursor at the smallest key greater than or equal to the 305 /// specified key, permitting partial key matches and range searches. 306 /// Otherwise, require the given key to match the key in the database 307 /// exactly. 308 /// </param> 309 /// <returns> 310 /// True if the cursor was positioned successfully, false otherwise. 311 /// </returns> Move(DatabaseEntry key, DatabaseEntry pkey, DatabaseEntry data, bool exact)312 public bool Move(DatabaseEntry key, DatabaseEntry pkey, 313 DatabaseEntry data, bool exact) { 314 return Move(key, pkey, data, exact, null); 315 } 316 /// <summary> 317 /// Set the cursor to refer to <paramref name="key"/>, and store the 318 /// primary key/data pair associated with the given secondary key in 319 /// <see cref="Current"/>. In the presence of duplicate key values, the 320 /// first data item in the set of duplicates is stored in 321 /// <see cref="Current"/>. If <paramref name="key"/>, or 322 /// <paramref name="pkey"/>, or <paramref name="data"/> is 323 /// partial <see cref="DatabaseEntry"/>, its 324 /// <see cref="DatabaseEntry.PartialLen"/> bytes starting 325 /// <see cref="DatabaseEntry.PartialOffset"/> bytes from the beginning 326 /// of the retrieved data record are returned as if they comprised the 327 /// entire record. If any or all of the specified bytes do not exist 328 /// in the record, Move is successful, and any existing bytes are 329 /// returned. 330 /// </summary> 331 /// <remarks> 332 /// If positioning the cursor fails, <see cref="Current"/> will contain 333 /// an empty <see cref="KeyValuePair{T,T}"/>. 334 /// </remarks> 335 /// <param name="key">The key at which to position the cursor</param> 336 /// <param name="pkey"> 337 /// The key of the current matching record in primary db 338 /// </param> 339 /// <param name="data"> 340 /// The data of the current matching record in primary db 341 /// </param> 342 /// <param name="exact"> 343 /// If false and in a database configured for sorted duplicates, 344 /// position the cursor at the smallest key greater than or equal to the 345 /// specified key, permitting partial key matches and range searches. 346 /// Otherwise, require the given key to match the key in the database 347 /// exactly. 348 /// </param> 349 /// <param name="info">The locking behavior to use.</param> 350 /// <returns> 351 /// True if the cursor was positioned successfully, false otherwise. 352 /// </returns> Move(DatabaseEntry key, DatabaseEntry pkey, DatabaseEntry data, bool exact, LockingInfo info)353 public bool Move(DatabaseEntry key, DatabaseEntry pkey, 354 DatabaseEntry data, bool exact, LockingInfo info) { 355 return PGet(key, pkey, data, 356 exact ? DbConstants.DB_SET : DbConstants.DB_SET_RANGE, info); 357 } 358 359 /// <summary> 360 /// Move the cursor to the specified key/data pair of the database. The 361 /// cursor is positioned to a key/data pair if both the key and data 362 /// match the values provided on the key and data parameters. 363 /// </summary> 364 /// <remarks> 365 /// <para> 366 /// If positioning the cursor fails, <see cref="Current"/> will contain 367 /// an empty <see cref="KeyValuePair{T,T}"/>. 368 /// </para> 369 /// <para> 370 /// If this flag is specified on a database configured without sorted 371 /// duplicate support, the value of <paramref name="exact"/> is ignored. 372 /// </para> 373 /// </remarks> 374 /// <param name="pair"> 375 /// The key/data pair at which to position the cursor. 376 /// </param> 377 /// <param name="exact"> 378 /// If false and in a database configured for sorted duplicates, 379 /// position the cursor at the smallest data value which is greater than 380 /// or equal to the value provided by <paramref name="pair"/>.Value (as 381 /// determined by the comparison function). Otherwise, require the given 382 /// key and data to match the key and data in the database exactly. 383 /// </param> 384 /// <returns> 385 /// True if the cursor was positioned successfully, false otherwise. 386 /// </returns> Move(KeyValuePair<DatabaseEntry, KeyValuePair<DatabaseEntry, DatabaseEntry>> pair, bool exact)387 public bool Move(KeyValuePair<DatabaseEntry, 388 KeyValuePair<DatabaseEntry, DatabaseEntry>> pair, bool exact) { 389 return Move(pair, exact, null); 390 } 391 /// <summary> 392 /// Move the cursor to the specified key/data pair of the database. The 393 /// cursor is positioned to a key/data pair if both the key and data 394 /// match the values provided on the key and data parameters. 395 /// </summary> 396 /// <remarks> 397 /// <para> 398 /// If positioning the cursor fails, <see cref="Current"/> will contain 399 /// an empty <see cref="KeyValuePair{T,T}"/>. 400 /// </para> 401 /// <para> 402 /// If this flag is specified on a database configured without sorted 403 /// duplicate support, the value of <paramref name="exact"/> is ignored. 404 /// </para> 405 /// </remarks> 406 /// <param name="pair"> 407 /// The key/data pair at which to position the cursor. 408 /// </param> 409 /// <param name="exact"> 410 /// If false and in a database configured for sorted duplicates, 411 /// position the cursor at the smallest data value which is greater than 412 /// or equal to the value provided by <paramref name="pair"/>.Value (as 413 /// determined by the comparison function). Otherwise, require the given 414 /// key and data to match the key and data in the database exactly. 415 /// </param> 416 /// <param name="info">The locking behavior to use.</param> 417 /// <returns> 418 /// True if the cursor was positioned successfully, false otherwise. 419 /// </returns> Move(KeyValuePair<DatabaseEntry, KeyValuePair<DatabaseEntry, DatabaseEntry>> pair, bool exact, LockingInfo info)420 public bool Move(KeyValuePair<DatabaseEntry, 421 KeyValuePair<DatabaseEntry, DatabaseEntry>> pair, 422 bool exact, LockingInfo info) { 423 return PGet(pair.Key, pair.Value.Key, pair.Value.Value, exact ? 424 DbConstants.DB_GET_BOTH : DbConstants.DB_GET_BOTH_RANGE, info); 425 } 426 427 /// <summary> 428 /// Set the cursor to refer to the last key/data pair of the database, 429 /// and store the secondary key and primary key/data pair in 430 /// <see cref="Current"/>. If the last key has duplicate values, the 431 /// last data item in the set of duplicates is stored in 432 /// <see cref="Current"/>. 433 /// </summary> 434 /// <remarks> 435 /// If positioning the cursor fails, <see cref="Current"/> will contain 436 /// an empty <see cref="KeyValuePair{T,T}"/>. 437 /// </remarks> 438 /// <returns> 439 /// True if the cursor was positioned successfully, false otherwise. 440 /// </returns> MoveLast()441 public bool MoveLast() { return MoveLast(null); } 442 /// <summary> 443 /// Set the cursor to refer to the last key/data pair of the database, 444 /// and store the secondary key and primary key/data pair in 445 /// <see cref="Current"/>. If the last key has duplicate values, the 446 /// last data item in the set of duplicates is stored in 447 /// <see cref="Current"/>. 448 /// </summary> 449 /// <remarks> 450 /// If positioning the cursor fails, <see cref="Current"/> will contain 451 /// an empty <see cref="KeyValuePair{T,T}"/>. 452 /// </remarks> 453 /// <param name="info">The locking behavior to use.</param> 454 /// <returns> 455 /// True if the cursor was positioned successfully, false otherwise. 456 /// </returns> MoveLast(LockingInfo info)457 public bool MoveLast(LockingInfo info) { 458 DatabaseEntry key = new DatabaseEntry(); 459 DatabaseEntry pkey = new DatabaseEntry(); 460 DatabaseEntry data = new DatabaseEntry(); 461 462 return MoveLast(key, pkey, data, info); 463 } 464 /// <summary> 465 /// Set the cursor to refer to the last key/data pair of the database, 466 /// and store the secondary key and primary key/data pair in 467 /// <see cref="Current"/>. If the last key has duplicate values, the 468 /// last data item in the set of duplicates is stored in 469 /// <see cref="Current"/>. If <paramref name="key"/>, or 470 /// <paramref name="pkey"/>, or <paramref name="data"/> is 471 /// partial <see cref="DatabaseEntry"/>, its 472 /// <see cref="DatabaseEntry.PartialLen"/> bytes starting 473 /// <see cref="DatabaseEntry.PartialOffset"/> bytes from the beginning 474 /// of the retrieved data record are returned as if they comprised the 475 /// entire record. If any or all of the specified bytes do not exist 476 /// in the record, MoveLast is successful, and any existing bytes are 477 /// returned. 478 /// </summary> 479 /// <remarks> 480 /// If positioning the cursor fails, <see cref="Current"/> will contain 481 /// an empty <see cref="KeyValuePair{T,T}"/>. 482 /// </remarks> 483 /// <param name="key">The retrieved key in secondary db</param> 484 /// <param name="pkey"> 485 /// The key of the matching record in primary db 486 /// </param> 487 /// <param name="data"> 488 /// The data of the matching record in primary db 489 /// </param> 490 /// <returns> 491 /// True if the cursor was positioned successfully, false otherwise. 492 /// </returns> MoveLast( DatabaseEntry key, DatabaseEntry pkey, DatabaseEntry data)493 public bool MoveLast( 494 DatabaseEntry key, DatabaseEntry pkey, DatabaseEntry data) { 495 return MoveLast(key, pkey, data, null); 496 } 497 /// <summary> 498 /// Set the cursor to refer to the last key/data pair of the database, 499 /// and store the secondary key and primary key/data pair in 500 /// <see cref="Current"/>. If the last key has duplicate values, the 501 /// last data item in the set of duplicates is stored in 502 /// <see cref="Current"/>. If <paramref name="key"/>, or 503 /// <paramref name="pkey"/>, or <paramref name="data"/> is 504 /// partial <see cref="DatabaseEntry"/>, its 505 /// <see cref="DatabaseEntry.PartialLen"/> bytes starting 506 /// <see cref="DatabaseEntry.PartialOffset"/> bytes from the beginning 507 /// of the retrieved data record are returned as if they comprised the 508 /// entire record. If any or all of the specified bytes do not exist 509 /// in the record, MoveLast is successful, and any existing bytes are 510 /// returned. 511 /// </summary> 512 /// <remarks> 513 /// If positioning the cursor fails, <see cref="Current"/> will contain 514 /// an empty <see cref="KeyValuePair{T,T}"/>. 515 /// </remarks> 516 /// <param name="key">The retrieved key in secondary db</param> 517 /// <param name="pkey"> 518 /// The key of the matching record in primary db 519 /// </param> 520 /// <param name="data"> 521 /// The data of the matching record in primary db 522 /// </param> 523 /// <param name="info">The locking behavior to use</param> 524 /// <returns> 525 /// True if the cursor was positioned successfully, false otherwise. 526 /// </returns> MoveLast(DatabaseEntry key, DatabaseEntry pkey, DatabaseEntry data, LockingInfo info)527 public bool MoveLast(DatabaseEntry key, DatabaseEntry pkey, 528 DatabaseEntry data, LockingInfo info) { 529 return PGet(key, pkey, data, DbConstants.DB_LAST, info); 530 } 531 532 /// <summary> 533 /// If the cursor is not yet initialized, MoveNext is identical to 534 /// <see cref="MoveFirst()"/>. Otherwise, move the cursor to the next 535 /// key/data pair of the database, and store the secondary key and 536 /// primary key/data pair in <see cref="Current"/>. In the presence of 537 /// duplicate key values, the value of <see cref="Current">Current.Key 538 /// </see> may not change. 539 /// </summary> 540 /// <remarks> 541 /// If positioning the cursor fails, <see cref="Current"/> will contain 542 /// an empty <see cref="KeyValuePair{T,T}"/>. 543 /// </remarks> 544 /// <returns> 545 /// True if the cursor was positioned successfully, false otherwise. 546 /// </returns> MoveNext()547 public bool MoveNext() { return MoveNext(null); } 548 /// <summary> 549 /// If the cursor is not yet initialized, MoveNext is identical to 550 /// <see cref="MoveFirst()"/>. Otherwise, move the cursor to the next 551 /// key/data pair of the database, and store the secondary key and 552 /// primary key/data pair in <see cref="Current"/>. In the presence of 553 /// duplicate key values, the value of <see cref="Current">Current.Key 554 /// </see> may not change. 555 /// </summary> 556 /// <remarks> 557 /// If positioning the cursor fails, <see cref="Current"/> will contain 558 /// an empty <see cref="KeyValuePair{T,T}"/>. 559 /// </remarks> 560 /// <param name="info">The locking behavior to use.</param> 561 /// <returns> 562 /// True if the cursor was positioned successfully, false otherwise. 563 /// </returns> MoveNext(LockingInfo info)564 public bool MoveNext(LockingInfo info) { 565 DatabaseEntry key = new DatabaseEntry(); 566 DatabaseEntry pkey = new DatabaseEntry(); 567 DatabaseEntry data = new DatabaseEntry(); 568 569 return MoveNext(key, pkey, data, info); 570 } 571 /// <summary> 572 /// If the cursor is not yet initialized, MoveNext is identical to 573 /// <see cref="MoveFirst()"/>. Otherwise, move the cursor to the next 574 /// key/data pair of the database, and store the secondary key and 575 /// primary key/data pair in <see cref="Current"/>. In the presence of 576 /// duplicate key values, the value of <see cref="Current">Current.Key 577 /// </see> may not change. If <paramref name="key"/>, or 578 /// <paramref name="pkey"/>, or <paramref name="data"/> is 579 /// partial <see cref="DatabaseEntry"/>, its 580 /// <see cref="DatabaseEntry.PartialLen"/> bytes starting 581 /// <see cref="DatabaseEntry.PartialOffset"/> bytes from the beginning 582 /// of the retrieved data record are returned as if they comprised the 583 /// entire record. If any or all of the specified bytes do not exist 584 /// in the record, MoveNext is successful, and any existing bytes are 585 /// returned. 586 /// </summary> 587 /// <remarks> 588 /// If positioning the cursor fails, <see cref="Current"/> will contain 589 /// an empty <see cref="KeyValuePair{T,T}"/>. 590 /// </remarks> 591 /// <param name="key">The retrieved key in secondary db</param> 592 /// <param name="pkey"> 593 /// The key of the matching record in primary db 594 /// </param> 595 /// <param name="data"> 596 /// The data of the matching record in primary db 597 /// </param> 598 /// <returns> 599 /// True if the cursor was positioned successfully, false otherwise. 600 /// </returns> MoveNext( DatabaseEntry key, DatabaseEntry pkey, DatabaseEntry data)601 public bool MoveNext( 602 DatabaseEntry key, DatabaseEntry pkey, DatabaseEntry data) { 603 return MoveNext(key, pkey, data, null); 604 } 605 /// <summary> 606 /// If the cursor is not yet initialized, MoveNext is identical to 607 /// <see cref="MoveFirst(LockingInfo)"/>. Otherwise, move the cursor 608 /// to the next key/data pair of the database, and store the secondary 609 /// key and primary key/data pair in <see cref="Current"/>. In the 610 /// presence of duplicate key values, the value of <see cref="Current"> 611 /// Current.Key </see> may not change. If <paramref name="key"/>, or 612 /// <paramref name="pkey"/>, or <paramref name="data"/> is 613 /// partial <see cref="DatabaseEntry"/>, its 614 /// <see cref="DatabaseEntry.PartialLen"/> bytes starting 615 /// <see cref="DatabaseEntry.PartialOffset"/> bytes from the beginning 616 /// of the retrieved data record are returned as if they comprised the 617 /// entire record. If any or all of the specified bytes do not exist 618 /// in the record, MoveNext is successful, and any existing bytes are 619 /// returned. 620 /// </summary> 621 /// <remarks> 622 /// If positioning the cursor fails, <see cref="Current"/> will contain 623 /// an empty <see cref="KeyValuePair{T,T}"/>. 624 /// </remarks> 625 /// <param name="key">The retrieved key in secondary db</param> 626 /// <param name="pkey"> 627 /// The key of the matching record in primary db 628 /// </param> 629 /// <param name="data"> 630 /// The data of the matching record in primary db 631 /// </param> 632 /// <param name="info">The locking behavior to use</param> 633 /// <returns> 634 /// True if the cursor was positioned successfully, false otherwise. 635 /// </returns> MoveNext(DatabaseEntry key, DatabaseEntry pkey, DatabaseEntry data, LockingInfo info)636 public bool MoveNext(DatabaseEntry key, DatabaseEntry pkey, 637 DatabaseEntry data, LockingInfo info) { 638 return PGet(key, pkey, data, DbConstants.DB_NEXT, info); 639 } 640 641 /// <summary> 642 /// If the next key/data pair of the database is a duplicate data record 643 /// for the current key/data pair, move the cursor to the next key/data 644 /// pair in the database, and store the secondary key and primary 645 /// key/data pair in <see cref="Current"/>. MoveNextDuplicate will 646 /// return false if the next key/data pair of the database is not a 647 /// duplicate data record for the current key/data pair. 648 /// </summary> 649 /// <remarks> 650 /// If positioning the cursor fails, <see cref="Current"/> will contain 651 /// an empty <see cref="KeyValuePair{T,T}"/>. 652 /// </remarks> 653 /// <returns> 654 /// True if the cursor was positioned successfully, false otherwise. 655 /// </returns> MoveNextDuplicate()656 public bool MoveNextDuplicate() { return MoveNextDuplicate(null); } 657 /// <summary> 658 /// If the next key/data pair of the database is a duplicate data record 659 /// for the current key/data pair, move the cursor to the next key/data 660 /// pair in the database, and store the secondary key and primary 661 /// key/data pair in <see cref="Current"/>. MoveNextDuplicate will 662 /// return false if the next key/data pair of the database is not a 663 /// duplicate data record for the current key/data pair. 664 /// </summary> 665 /// <remarks> 666 /// If positioning the cursor fails, <see cref="Current"/> will contain 667 /// an empty <see cref="KeyValuePair{T,T}"/>. 668 /// </remarks> 669 /// <param name="info">The locking behavior to use.</param> 670 /// <returns> 671 /// True if the cursor was positioned successfully, false otherwise. 672 /// </returns> MoveNextDuplicate(LockingInfo info)673 public bool MoveNextDuplicate(LockingInfo info) { 674 DatabaseEntry key = new DatabaseEntry(); 675 DatabaseEntry pkey = new DatabaseEntry(); 676 DatabaseEntry data = new DatabaseEntry(); 677 678 return MoveNextDuplicate(key, pkey, data, info); 679 } 680 /// <summary> 681 /// If the next key/data pair of the database is a duplicate data record 682 /// for the current key/data pair, move the cursor to the next key/data 683 /// pair in the database, and store the secondary key and primary 684 /// key/data pair in <see cref="Current"/>. MoveNextDuplicate will 685 /// return false if the next key/data pair of the database is not a 686 /// duplicate data record for the current key/data pair. If 687 /// <paramref name="key"/>, or <paramref name="pkey"/>, or 688 /// <paramref name="data"/> is partial <see cref="DatabaseEntry"/>, 689 /// its <see cref="DatabaseEntry.PartialLen"/> bytes starting 690 /// <see cref="DatabaseEntry.PartialOffset"/> bytes from the beginning 691 /// of the retrieved data record are returned as if they comprised the 692 /// entire record. If any or all of the specified bytes do not exist 693 /// in the record, MoveNextDuplicate is successful, and any existing bytes are 694 /// returned. 695 /// </summary> 696 /// <remarks> 697 /// If positioning the cursor fails, <see cref="Current"/> will contain 698 /// an empty <see cref="KeyValuePair{T,T}"/>. 699 /// </remarks> 700 /// <param name="key">The retrieved key in secondary db</param> 701 /// <param name="pkey"> 702 /// The key of the matching record in primary db 703 /// </param> 704 /// <param name="data"> 705 /// The data of the matching record in primary db 706 /// </param> 707 /// <returns> 708 /// True if the cursor was positioned successfully, false otherwise. 709 /// </returns> MoveNextDuplicate( DatabaseEntry key, DatabaseEntry pkey, DatabaseEntry data)710 public bool MoveNextDuplicate( 711 DatabaseEntry key, DatabaseEntry pkey, DatabaseEntry data) { 712 return MoveNextDuplicate(key, pkey, data, null); 713 } 714 /// <summary> 715 /// If the next key/data pair of the database is a duplicate data record 716 /// for the current key/data pair, move the cursor to the next key/data 717 /// pair in the database, and store the secondary key and primary 718 /// key/data pair in <see cref="Current"/>. MoveNextDuplicate will 719 /// return false if the next key/data pair of the database is not a 720 /// duplicate data record for the current key/data pair. If 721 /// <paramref name="key"/>, or <paramref name="pkey"/>, or 722 /// <paramref name="data"/> is partial <see cref="DatabaseEntry"/>, 723 /// its <see cref="DatabaseEntry.PartialLen"/> bytes starting 724 /// <see cref="DatabaseEntry.PartialOffset"/> bytes from the beginning 725 /// of the retrieved data record are returned as if they comprised the 726 /// entire record. If any or all of the specified bytes do not exist 727 /// in the record, MoveNextDuplicate is successful, and any existing bytes are 728 /// returned. 729 /// </summary> 730 /// <remarks> 731 /// If positioning the cursor fails, <see cref="Current"/> will contain 732 /// an empty <see cref="KeyValuePair{T,T}"/>. 733 /// </remarks> 734 /// <param name="key">The retrieved key in secondary db</param> 735 /// <param name="pkey"> 736 /// The key of the matching record in primary db 737 /// </param> 738 /// <param name="data"> 739 /// The data of the matching record in primary db 740 /// </param> 741 /// <param name="info">The locking behavior to use</param> 742 /// <returns> 743 /// True if the cursor was positioned successfully, false otherwise. 744 /// </returns> MoveNextDuplicate(DatabaseEntry key, DatabaseEntry pkey, DatabaseEntry data, LockingInfo info)745 public bool MoveNextDuplicate(DatabaseEntry key, DatabaseEntry pkey, 746 DatabaseEntry data, LockingInfo info) { 747 return PGet(key, pkey, data, DbConstants.DB_NEXT_DUP, info); 748 } 749 750 /// <summary> 751 /// If the cursor is not yet initialized, MoveNextUnique is identical to 752 /// <see cref="MoveFirst()"/>. Otherwise, move the cursor to the next 753 /// non-duplicate key in the database, and store the secondary key and 754 /// primary key/data pair in <see cref="Current"/>. MoveNextUnique will 755 /// return false if no non-duplicate key/data pairs exist after the 756 /// cursor position in the database. 757 /// </summary> 758 /// <remarks> 759 /// If positioning the cursor fails, <see cref="Current"/> will contain 760 /// an empty <see cref="KeyValuePair{T,T}"/>. 761 /// </remarks> 762 /// <returns> 763 /// True if the cursor was positioned successfully, false otherwise. 764 /// </returns> MoveNextUnique()765 public bool MoveNextUnique() { return MoveNextUnique(null); } 766 /// <summary> 767 /// If the cursor is not yet initialized, MoveNextUnique is identical to 768 /// <see cref="MoveFirst()"/>. Otherwise, move the cursor to the next 769 /// non-duplicate key in the database, and store the secondary key and 770 /// primary key/data pair in <see cref="Current"/>. MoveNextUnique will 771 /// return false if no non-duplicate key/data pairs exist after the 772 /// cursor position in the database. 773 /// </summary> 774 /// <remarks> 775 /// <para> 776 /// If the database is a Queue or Recno database, MoveNextUnique will 777 /// ignore any keys that exist but were never explicitly created by the 778 /// application, or those that were created and later deleted. 779 /// </para> 780 /// <para> 781 /// If positioning the cursor fails, <see cref="Current"/> will contain 782 /// an empty <see cref="KeyValuePair{T,T}"/>. 783 /// </para> 784 /// </remarks> 785 /// <param name="info">The locking behavior to use.</param> 786 /// <returns> 787 /// True if the cursor was positioned successfully, false otherwise. 788 /// </returns> MoveNextUnique(LockingInfo info)789 public bool MoveNextUnique(LockingInfo info) { 790 DatabaseEntry key = new DatabaseEntry(); 791 DatabaseEntry pkey = new DatabaseEntry(); 792 DatabaseEntry data = new DatabaseEntry(); 793 794 return MoveNextUnique(key, pkey, data, info); 795 } 796 /// <summary> 797 /// If the cursor is not yet initialized, MoveNextUnique is identical to 798 /// <see cref="MoveFirst()"/>. Otherwise, move the cursor to the next 799 /// non-duplicate key in the database, and store the secondary key and 800 /// primary key/data pair in <see cref="Current"/>. MoveNextUnique will 801 /// return false if no non-duplicate key/data pairs exist after the 802 /// cursor position in the database. If <paramref name="key"/>, or 803 /// <paramref name="pkey"/>, or <paramref name="data"/> is 804 /// partial <see cref="DatabaseEntry"/>, its 805 /// <see cref="DatabaseEntry.PartialLen"/> bytes starting 806 /// <see cref="DatabaseEntry.PartialOffset"/> bytes from the beginning 807 /// of the retrieved data record are returned as if they comprised the 808 /// entire record. If any or all of the specified bytes do not exist 809 /// in the record, MoveNextUnique is successful, and any existing bytes 810 /// are returned. 811 /// </summary> 812 /// <remarks> 813 /// If positioning the cursor fails, <see cref="Current"/> will contain 814 /// an empty <see cref="KeyValuePair{T,T}"/>. 815 /// </remarks> 816 /// <param name="key">The retrieved key in secondary db</param> 817 /// <param name="pkey"> 818 /// The key of the matching record in primary db 819 /// </param> 820 /// <param name="data"> 821 /// The data of the matching record in primary db 822 /// </param> 823 /// <returns> 824 /// True if the cursor was positioned successfully, false otherwise. 825 /// </returns> MoveNextUnique( DatabaseEntry key, DatabaseEntry pkey, DatabaseEntry data)826 public bool MoveNextUnique( 827 DatabaseEntry key, DatabaseEntry pkey, DatabaseEntry data) { 828 return MoveNextUnique(key, pkey, data, null); 829 } 830 /// <summary> 831 /// If the cursor is not yet initialized, MoveNextUnique is identical to 832 /// <see cref="MoveFirst(LockingInfo)"/>. Otherwise, move the cursor to 833 /// the next non-duplicate key in the database, and store the secondary 834 /// key and primary key/data pair in <see cref="Current"/>. 835 /// MoveNextUnique will return false if no non-duplicate key/data pairs 836 /// exist after the cursor position in the database. If 837 /// <paramref name="key"/>, or <paramref name="pkey"/>, or 838 /// <paramref name="data"/> is partial <see cref="DatabaseEntry"/>, its 839 /// <see cref="DatabaseEntry.PartialLen"/> bytes starting 840 /// <see cref="DatabaseEntry.PartialOffset"/> bytes from the beginning 841 /// of the retrieved data record are returned as if they comprised the 842 /// entire record. If any or all of the specified bytes do not exist 843 /// in the record, MoveNextUnique is successful, and any existing bytes 844 /// are returned. 845 /// </summary> 846 /// <remarks> 847 /// If positioning the cursor fails, <see cref="Current"/> will contain 848 /// an empty <see cref="KeyValuePair{T,T}"/>. 849 /// </remarks> 850 /// <param name="key">The retrieved key in secondary db</param> 851 /// <param name="pkey"> 852 /// The key of the matching record in primary db 853 /// </param> 854 /// <param name="data"> 855 /// The data of the matching record in primary db 856 /// </param> 857 /// <param name="info">The locking behavior to use</param> 858 /// <returns> 859 /// True if the cursor was positioned successfully, false otherwise. 860 /// </returns> MoveNextUnique(DatabaseEntry key, DatabaseEntry pkey, DatabaseEntry data, LockingInfo info)861 public bool MoveNextUnique(DatabaseEntry key, DatabaseEntry pkey, 862 DatabaseEntry data, LockingInfo info) { 863 return PGet(key, pkey, data, DbConstants.DB_NEXT_NODUP, info); 864 } 865 866 /// <summary> 867 /// If the cursor is not yet initialized, MovePrev is identical to 868 /// <see cref="MoveLast()"/>. Otherwise, move the cursor to the previous 869 /// key/data pair of the database, and store the secondary key and 870 /// primary key/data pair in <see cref="Current"/>. In the presence of 871 /// duplicate key values, the value of <see cref="Current">Current.Key 872 /// </see> may not change. 873 /// </summary> 874 /// <remarks> 875 /// If positioning the cursor fails, <see cref="Current"/> will contain 876 /// an empty <see cref="KeyValuePair{T,T}"/>. 877 /// </remarks> 878 /// <returns> 879 /// True if the cursor was positioned successfully, false otherwise. 880 /// </returns> MovePrev()881 public bool MovePrev() { return MovePrev(null); } 882 /// <summary> 883 /// If the cursor is not yet initialized, MovePrev is identical to 884 /// <see cref="MoveLast(LockingInfo)"/>. Otherwise, move the cursor to 885 /// the previous key/data pair of the database, and store the secondary 886 /// key and primary key/data pair in <see cref="Current"/>. In the 887 /// presence of duplicate key values, the value of <see cref="Current"> 888 /// Current.Key</see> may not change. 889 /// </summary> 890 /// <remarks> 891 /// If positioning the cursor fails, <see cref="Current"/> will contain 892 /// an empty <see cref="KeyValuePair{T,T}"/>. 893 /// </remarks> 894 /// <param name="info">The locking behavior to use.</param> 895 /// <returns> 896 /// True if the cursor was positioned successfully, false otherwise. 897 /// </returns> MovePrev(LockingInfo info)898 public bool MovePrev(LockingInfo info) { 899 DatabaseEntry key = new DatabaseEntry(); 900 DatabaseEntry pkey = new DatabaseEntry(); 901 DatabaseEntry data = new DatabaseEntry(); 902 903 return MovePrev(key, pkey, data, info); 904 } 905 /// <summary> 906 /// If the cursor is not yet initialized, MovePrev is identical to 907 /// <see cref="MoveLast()"/>. Otherwise, move the cursor to the previous 908 /// key/data pair of the database, and store the secondary key and 909 /// primary key/data pair in <see cref="Current"/>. In the presence of 910 /// duplicate key values, the value of <see cref="Current">Current.Key 911 /// </see> may not change. If <paramref name="key"/>, or 912 /// <paramref name="pkey"/>, or <paramref name="data"/> is 913 /// partial <see cref="DatabaseEntry"/>, its 914 /// <see cref="DatabaseEntry.PartialLen"/> bytes starting 915 /// <see cref="DatabaseEntry.PartialOffset"/> bytes from the beginning 916 /// of the retrieved data record are returned as if they comprised the 917 /// entire record. If any or all of the specified bytes do not exist 918 /// in the record, MovePrev is successful, and any existing bytes are 919 /// returned. 920 /// </summary> 921 /// <remarks> 922 /// If positioning the cursor fails, <see cref="Current"/> will contain 923 /// an empty <see cref="KeyValuePair{T,T}"/>. 924 /// </remarks> 925 /// <param name="key">The retrieved key in secondary db</param> 926 /// <param name="pkey"> 927 /// The key of the matching record in primary db 928 /// </param> 929 /// <param name="data"> 930 /// The data of the matching record in primary db 931 /// </param> 932 /// <returns> 933 /// True if the cursor was positioned successfully, false otherwise. 934 /// </returns> MovePrev( DatabaseEntry key, DatabaseEntry pkey, DatabaseEntry data)935 public bool MovePrev( 936 DatabaseEntry key, DatabaseEntry pkey, DatabaseEntry data) { 937 return MovePrev(key, pkey, data, null); 938 } 939 /// <summary> 940 /// If the cursor is not yet initialized, MovePrev is identical to 941 /// <see cref="MoveLast(LockingInfo)"/>. Otherwise, move the cursor to 942 /// the previous key/data pair of the database, and store the secondary 943 /// key and primary key/data pair in <see cref="Current"/>. In the 944 /// presence of duplicate key values, the value of <see cref="Current"> 945 /// Current.Key</see> may not change. If <paramref name="key"/>, or 946 /// <paramref name="pkey"/>, or <paramref name="data"/> is 947 /// partial <see cref="DatabaseEntry"/>, its 948 /// <see cref="DatabaseEntry.PartialLen"/> bytes starting 949 /// <see cref="DatabaseEntry.PartialOffset"/> bytes from the beginning 950 /// of the retrieved data record are returned as if they comprised the 951 /// entire record. If any or all of the specified bytes do not exist 952 /// in the record, MovePrev is successful, and any existing bytes are 953 /// returned. 954 /// </summary> 955 /// <remarks> 956 /// If positioning the cursor fails, <see cref="Current"/> will contain 957 /// an empty <see cref="KeyValuePair{T,T}"/>. 958 /// </remarks> 959 /// <param name="key">The retrieved key in secondary db</param> 960 /// <param name="pkey"> 961 /// The key of the matching record in primary db 962 /// </param> 963 /// <param name="data"> 964 /// The data of the matching record in primary db 965 /// </param> 966 /// <param name="info">The locking behavior to use</param> 967 /// <returns> 968 /// True if the cursor was positioned successfully, false otherwise. 969 /// </returns> MovePrev(DatabaseEntry key, DatabaseEntry pkey, DatabaseEntry data, LockingInfo info)970 public bool MovePrev(DatabaseEntry key, DatabaseEntry pkey, 971 DatabaseEntry data, LockingInfo info) { 972 return PGet(key, pkey, data, DbConstants.DB_PREV, info); 973 } 974 975 /// <summary> 976 /// If the previous key/data pair of the database is a duplicate data 977 /// record for the current key/data pair, the cursor is moved to the 978 /// previous key/data pair of the database, and the secondary key and 979 /// primary key/data pair in <see cref="Current"/>. MovePrevDuplicate 980 /// will return false if the previous key/data pair of the database is 981 /// not a duplicate data record for the current key/data pair. 982 /// </summary> 983 /// <remarks> 984 /// If positioning the cursor fails, <see cref="Current"/> will contain 985 /// an empty <see cref="KeyValuePair{T,T}"/>. 986 /// </remarks> 987 /// <returns> 988 /// True if the cursor was positioned successfully, false otherwise. 989 /// </returns> MovePrevDuplicate()990 public bool MovePrevDuplicate() { return MovePrevDuplicate(null); } 991 /// <summary> 992 /// If the previous key/data pair of the database is a duplicate data 993 /// record for the current key/data pair, the cursor is moved to the 994 /// previous key/data pair of the database, and the secondary key and 995 /// primary key/data pair in <see cref="Current"/>. MovePrevDuplicate 996 /// will return false if the previous key/data pair of the database is 997 /// not a duplicate data record for the current key/data pair. 998 /// </summary> 999 /// <remarks> 1000 /// If positioning the cursor fails, <see cref="Current"/> will contain 1001 /// an empty <see cref="KeyValuePair{T,T}"/>. 1002 /// </remarks> 1003 /// <param name="info">The locking behavior to use.</param> 1004 /// <returns> 1005 /// True if the cursor was positioned successfully, false otherwise. 1006 /// </returns> MovePrevDuplicate(LockingInfo info)1007 public bool MovePrevDuplicate(LockingInfo info) { 1008 DatabaseEntry key = new DatabaseEntry(); 1009 DatabaseEntry pkey = new DatabaseEntry(); 1010 DatabaseEntry data = new DatabaseEntry(); 1011 1012 return MovePrevDuplicate(key, pkey, data, info); 1013 } 1014 /// <summary> 1015 /// If the previous key/data pair of the database is a duplicate data 1016 /// record for the current key/data pair, the cursor is moved to the 1017 /// previous key/data pair of the database, and the secondary key and 1018 /// primary key/data pair in <see cref="Current"/>. MovePrevDuplicate 1019 /// will return false if the previous key/data pair of the database is 1020 /// not a duplicate data record for the current key/data pair. If 1021 /// <paramref name="key"/>, or <paramref name="pkey"/>, or 1022 /// <paramref name="data"/> is partial <see cref="DatabaseEntry"/>, its 1023 /// <see cref="DatabaseEntry.PartialLen"/> bytes starting 1024 /// <see cref="DatabaseEntry.PartialOffset"/> bytes from the beginning 1025 /// of the retrieved data record are returned as if they comprised the 1026 /// entire record. If any or all of the specified bytes do not exist 1027 /// in the record, MovePrevDuplicate is successful, and any existing 1028 /// bytes are returned. 1029 /// </summary> 1030 /// <remarks> 1031 /// If positioning the cursor fails, <see cref="Current"/> will contain 1032 /// an empty <see cref="KeyValuePair{T,T}"/>. 1033 /// </remarks> 1034 /// <param name="key">The retrieved key in secondary db</param> 1035 /// <param name="pkey"> 1036 /// The key of the matching record in primary db 1037 /// </param> 1038 /// <param name="data"> 1039 /// The data of the matching record in primary db 1040 /// </param> 1041 /// <returns> 1042 /// True if the cursor was positioned successfully, false otherwise. 1043 /// </returns> MovePrevDuplicate( DatabaseEntry key, DatabaseEntry pkey, DatabaseEntry data)1044 public bool MovePrevDuplicate( 1045 DatabaseEntry key, DatabaseEntry pkey, DatabaseEntry data) { 1046 return MovePrevDuplicate(key, pkey, data, null); 1047 } 1048 /// <summary> 1049 /// If the previous key/data pair of the database is a duplicate data 1050 /// record for the current key/data pair, the cursor is moved to the 1051 /// previous key/data pair of the database, and the secondary key and 1052 /// primary key/data pair in <see cref="Current"/>. MovePrevDuplicate 1053 /// will return false if the previous key/data pair of the database is 1054 /// not a duplicate data record for the current key/data pair. If 1055 /// <paramref name="key"/>, or <paramref name="pkey"/>, or 1056 /// <paramref name="data"/> is partial <see cref="DatabaseEntry"/>, its 1057 /// <see cref="DatabaseEntry.PartialLen"/> bytes starting 1058 /// <see cref="DatabaseEntry.PartialOffset"/> bytes from the beginning 1059 /// of the retrieved data record are returned as if they comprised the 1060 /// entire record. If any or all of the specified bytes do not exist 1061 /// in the record, MovePrevDuplicate is successful, and any existing 1062 /// bytes are returned. 1063 /// </summary> 1064 /// <remarks> 1065 /// If positioning the cursor fails, <see cref="Current"/> will contain 1066 /// an empty <see cref="KeyValuePair{T,T}"/>. 1067 /// </remarks> 1068 /// <param name="key">The retrieved key in secondary db</param> 1069 /// <param name="pkey"> 1070 /// The key of the matching record in primary db 1071 /// </param> 1072 /// <param name="data"> 1073 /// The data of the matching record in primary db 1074 /// </param> 1075 /// <param name="info">The locking behavior to use</param> 1076 /// <returns> 1077 /// True if the cursor was positioned successfully, false otherwise. 1078 /// </returns> MovePrevDuplicate(DatabaseEntry key, DatabaseEntry pkey, DatabaseEntry data, LockingInfo info)1079 public bool MovePrevDuplicate(DatabaseEntry key, DatabaseEntry pkey, 1080 DatabaseEntry data, LockingInfo info) { 1081 return PGet(key, pkey, data, DbConstants.DB_PREV_DUP, info); 1082 } 1083 1084 /// <summary> 1085 /// If the cursor is not yet initialized, MovePrevUnique is identical to 1086 /// <see cref="MoveLast()"/>. Otherwise, move the cursor to the previous 1087 /// non-duplicate key in the database, and store the secondary key and 1088 /// primary key/data pair in <see cref="Current"/>. MovePrevUnique will 1089 /// return false if no non-duplicate key/data pairs exist after the 1090 /// cursor position in the database. 1091 /// </summary> 1092 /// <remarks> 1093 /// If positioning the cursor fails, <see cref="Current"/> will contain 1094 /// an empty <see cref="KeyValuePair{T,T}"/>. 1095 /// </remarks> 1096 /// <returns> 1097 /// True if the cursor was positioned successfully, false otherwise. 1098 /// </returns> MovePrevUnique()1099 public bool MovePrevUnique() { return MovePrevUnique(null); } 1100 /// <summary> 1101 /// If the cursor is not yet initialized, MovePrevUnique is identical to 1102 /// <see cref="MoveLast(LockingInfo)"/>. Otherwise, move the cursor to 1103 /// the previous non-duplicate key in the database, and store the 1104 /// secondary key and primary key/data pair in <see cref="Current"/>. 1105 /// MovePrevUnique will return false if no non-duplicate key/data pairs 1106 /// exist after the cursor position in the database. 1107 /// </summary> 1108 /// <remarks> 1109 /// If positioning the cursor fails, <see cref="Current"/> will contain 1110 /// an empty <see cref="KeyValuePair{T,T}"/>. 1111 /// </remarks> 1112 /// <param name="info">The locking behavior to use.</param> 1113 /// <returns> 1114 /// True if the cursor was positioned successfully, false otherwise. 1115 /// </returns> MovePrevUnique(LockingInfo info)1116 public bool MovePrevUnique(LockingInfo info) { 1117 DatabaseEntry key = new DatabaseEntry(); 1118 DatabaseEntry pkey = new DatabaseEntry(); 1119 DatabaseEntry data = new DatabaseEntry(); 1120 1121 return MovePrevUnique(key, pkey, data, info); 1122 } 1123 /// <summary> 1124 /// If the cursor is not yet initialized, MovePrevUnique is identical to 1125 /// <see cref="MoveLast()"/>. Otherwise, move the cursor to the previous 1126 /// non-duplicate key in the database, and store the secondary key and 1127 /// primary key/data pair in <see cref="Current"/>. MovePrevUnique will 1128 /// return false if no non-duplicate key/data pairs exist after the 1129 /// cursor position in the database. If <paramref name="key"/>, or 1130 /// <paramref name="pkey"/>, or <paramref name="data"/> is 1131 /// partial <see cref="DatabaseEntry"/>, its 1132 /// <see cref="DatabaseEntry.PartialLen"/> bytes starting 1133 /// <see cref="DatabaseEntry.PartialOffset"/> bytes from the beginning 1134 /// of the retrieved data record are returned as if they comprised the 1135 /// entire record. If any or all of the specified bytes do not exist 1136 /// in the record, MovePrevUnique is successful, and any existing bytes 1137 /// are returned. 1138 /// </summary> 1139 /// <remarks> 1140 /// If positioning the cursor fails, <see cref="Current"/> will contain 1141 /// an empty <see cref="KeyValuePair{T,T}"/>. 1142 /// </remarks> 1143 /// <param name="key">The retrieved key in secondary db</param> 1144 /// <param name="pkey"> 1145 /// The key of the matching record in primary db 1146 /// </param> 1147 /// <param name="data"> 1148 /// The data of the matching record in primary db 1149 /// </param> 1150 /// <returns> 1151 /// True if the cursor was positioned successfully, false otherwise. 1152 /// </returns> MovePrevUnique( DatabaseEntry key, DatabaseEntry pkey, DatabaseEntry data)1153 public bool MovePrevUnique( 1154 DatabaseEntry key, DatabaseEntry pkey, DatabaseEntry data) { 1155 return MovePrevUnique(key, pkey, data, null); 1156 } 1157 /// <summary> 1158 /// If the cursor is not yet initialized, MovePrevUnique is identical to 1159 /// <see cref="MoveLast(LockingInfo)"/>. Otherwise, move the cursor to 1160 /// the previous non-duplicate key in the database, and store the 1161 /// secondary key and primary key/data pair in <see cref="Current"/>. 1162 /// MovePrevUnique will return false if no non-duplicate key/data pairs 1163 /// exist after the cursor position in the database. If 1164 /// <paramref name="key"/>, or <paramref name="pkey"/>, or 1165 /// <paramref name="data"/> is partial <see cref="DatabaseEntry"/>, its 1166 /// <see cref="DatabaseEntry.PartialLen"/> bytes starting 1167 /// <see cref="DatabaseEntry.PartialOffset"/> bytes from the beginning 1168 /// of the retrieved data record are returned as if they comprised the 1169 /// entire record. If any or all of the specified bytes do not exist 1170 /// in the record, MovePrevUnique is successful, and any existing bytes 1171 /// are returned. 1172 /// </summary> 1173 /// <remarks> 1174 /// If positioning the cursor fails, <see cref="Current"/> will contain 1175 /// an empty <see cref="KeyValuePair{T,T}"/>. 1176 /// </remarks> 1177 /// <param name="key">The retrieved key in secondary db</param> 1178 /// <param name="pkey"> 1179 /// The key of the matching record in primary db 1180 /// </param> 1181 /// <param name="data"> 1182 /// The data of the matching record in primary db 1183 /// </param> 1184 /// <param name="info">The locking behavior to use</param> 1185 /// <returns> 1186 /// True if the cursor was positioned successfully, false otherwise. 1187 /// </returns> MovePrevUnique(DatabaseEntry key, DatabaseEntry pkey, DatabaseEntry data, LockingInfo info)1188 public bool MovePrevUnique(DatabaseEntry key, DatabaseEntry pkey, 1189 DatabaseEntry data, LockingInfo info) { 1190 return PGet(key, pkey, data, DbConstants.DB_PREV_NODUP, info); 1191 } 1192 1193 /// <summary> 1194 /// Store the secondary key and primary key/data pair to which the 1195 /// cursor refers in <see cref="Current"/>. 1196 /// </summary> 1197 /// <remarks> 1198 /// If positioning the cursor fails, <see cref="Current"/> will contain 1199 /// an empty <see cref="KeyValuePair{T,T}"/>. 1200 /// </remarks> 1201 /// <returns> 1202 /// True if the cursor was positioned successfully, false otherwise. 1203 /// </returns> Refresh()1204 public bool Refresh() { return Refresh(null); } 1205 /// <summary> 1206 /// Store the secondary key and primary key/data pair to which the 1207 /// cursor refers in <see cref="Current"/>. 1208 /// </summary> 1209 /// <remarks> 1210 /// If positioning the cursor fails, <see cref="Current"/> will contain 1211 /// an empty <see cref="KeyValuePair{T,T}"/>. 1212 /// </remarks> 1213 /// <param name="info">The locking behavior to use.</param> 1214 /// <returns> 1215 /// True if the cursor was positioned successfully, false otherwise. 1216 /// </returns> Refresh(LockingInfo info)1217 public bool Refresh(LockingInfo info) { 1218 DatabaseEntry key = new DatabaseEntry(); 1219 DatabaseEntry pkey = new DatabaseEntry(); 1220 DatabaseEntry data = new DatabaseEntry(); 1221 1222 return Refresh(key, pkey, data, info); 1223 } 1224 /// <summary> 1225 /// Store the secondary key and primary key/data pair to which the 1226 /// cursor refers in <see cref="Current"/>. If <paramref name="key"/>, 1227 /// or <paramref name="pkey"/>, or <paramref name="data"/> is 1228 /// partial <see cref="DatabaseEntry"/>, its 1229 /// <see cref="DatabaseEntry.PartialLen"/> bytes starting 1230 /// <see cref="DatabaseEntry.PartialOffset"/> bytes from the beginning 1231 /// of the retrieved data record are returned as if they comprised the 1232 /// entire record. If any or all of the specified bytes do not exist 1233 /// in the record, Refresh is successful, and any existing bytes are 1234 /// returned. 1235 /// </summary> 1236 /// <remarks> 1237 /// If positioning the cursor fails, <see cref="Current"/> will contain 1238 /// an empty <see cref="KeyValuePair{T,T}"/>. 1239 /// </remarks> 1240 /// <param name="key">The retrieved key in secondary db</param> 1241 /// <param name="pkey"> 1242 /// The key of the matching record in primary db 1243 /// </param> 1244 /// <param name="data"> 1245 /// The data of the matching record in primary db 1246 /// </param> 1247 /// <returns> 1248 /// True if the cursor was positioned successfully, false otherwise. 1249 /// </returns> Refresh( DatabaseEntry key, DatabaseEntry pkey, DatabaseEntry data)1250 public bool Refresh( 1251 DatabaseEntry key, DatabaseEntry pkey, DatabaseEntry data) { 1252 return Refresh(key, pkey, data, null); 1253 } 1254 /// <summary> 1255 /// Store the secondary key and primary key/data pair to which the 1256 /// cursor refers in <see cref="Current"/>. If <paramref name="key"/>, 1257 /// or <paramref name="pkey"/>, or <paramref name="data"/> is 1258 /// partial <see cref="DatabaseEntry"/>, its 1259 /// <see cref="DatabaseEntry.PartialLen"/> bytes starting 1260 /// <see cref="DatabaseEntry.PartialOffset"/> bytes from the beginning 1261 /// of the retrieved data record are returned as if they comprised the 1262 /// entire record. If any or all of the specified bytes do not exist 1263 /// in the record, Refresh is successful, and any existing bytes are 1264 /// returned. 1265 /// </summary> 1266 /// <remarks> 1267 /// If positioning the cursor fails, <see cref="Current"/> will contain 1268 /// an empty <see cref="KeyValuePair{T,T}"/>. 1269 /// </remarks> 1270 /// <param name="key">The retrieved key in secondary db</param> 1271 /// <param name="pkey"> 1272 /// The key of the matching record in primary db 1273 /// </param> 1274 /// <param name="data"> 1275 /// The data of the matching record in primary db 1276 /// </param> 1277 /// <param name="info">The locking behavior to use</param> 1278 /// <returns> 1279 /// True if the cursor was positioned successfully, false otherwise. 1280 /// </returns> Refresh(DatabaseEntry key, DatabaseEntry pkey, DatabaseEntry data, LockingInfo info)1281 public bool Refresh(DatabaseEntry key, DatabaseEntry pkey, 1282 DatabaseEntry data, LockingInfo info) { 1283 return PGet(key, pkey, data, DbConstants.DB_CURRENT, info); 1284 } 1285 } 1286 } 1287 1288