1<?xml version="1.0" encoding="UTF-8" standalone="no"?> 2<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 3<html xmlns="http://www.w3.org/1999/xhtml"> 4 <head> 5 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 6 <title>Getting Records Using the Cursor</title> 7 <link rel="stylesheet" href="gettingStarted.css" type="text/css" /> 8 <meta name="generator" content="DocBook XSL Stylesheets V1.62.4" /> 9 <link rel="home" href="index.html" title="Getting Started with Berkeley DB" /> 10 <link rel="up" href="Cursors.html" title="Chapter 4. Using Cursors" /> 11 <link rel="previous" href="Cursors.html" title="Chapter 4. Using Cursors" /> 12 <link rel="next" href="PutEntryWCursor.html" title="Putting Records Using Cursors" /> 13 </head> 14 <body> 15 <div class="navheader"> 16 <table width="100%" summary="Navigation header"> 17 <tr> 18 <th colspan="3" align="center">Getting Records Using the Cursor</th> 19 </tr> 20 <tr> 21 <td width="20%" align="left"><a accesskey="p" href="Cursors.html">Prev</a> </td> 22 <th width="60%" align="center">Chapter 4. Using Cursors</th> 23 <td width="20%" align="right"> <a accesskey="n" href="PutEntryWCursor.html">Next</a></td> 24 </tr> 25 </table> 26 <hr /> 27 </div> 28 <div class="sect1" lang="en" xml:lang="en"> 29 <div class="titlepage"> 30 <div> 31 <div> 32 <h2 class="title" style="clear: both"><a id="Positioning"></a>Getting Records Using the Cursor</h2> 33 </div> 34 </div> 35 <div></div> 36 </div> 37 <p> 38 To iterate over database records, from the first record to 39 the last, simply open the cursor and then use the 40 41 42 <tt class="methodname">Dbc::get()</tt> 43 method. 44 <span>Note that you need to supply the 45 <tt class="literal">DB_NEXT</tt> flag to this method.</span> 46 For example: 47 </p> 48 <a id="cxx_cursor3"></a> 49 <pre class="programlisting">#include <db_cxx.h> 50 51... 52 53Db my_database(NULL, 0); 54Dbc *cursorp; 55 56try { 57 // Database open omitted for clarity 58 59 // Get a cursor 60 my_database.cursor(NULL, &cursorp, 0); 61 62 Dbt key, data; 63 int ret; 64 65 // Iterate over the database, retrieving each record in turn. 66 while ((ret = cursorp->get(&key, &data, DB_NEXT)) == 0) { 67 // Do interesting things with the Dbts here. 68 } 69 if (ret != DB_NOTFOUND) { 70 // ret should be DB_NOTFOUND upon exiting the loop. 71 // Dbc::get() will by default throw an exception if any 72 // significant errors occur, so by default this if block 73 // can never be reached. 74 } 75} catch(DbException &e) { 76 my_database.err(e.get_errno(), "Error!"); 77} catch(std::exception &e) { 78 my_database.errx("Error! %s", e.what()); 79} 80 81// Cursors must be closed 82if (cursorp != NULL) 83 cursorp->close(); 84 85my_database.close(0);</pre> 86 <p> 87 To iterate over the database from the last record to the first, use 88 <tt class="literal">DB_PREV</tt> instead of <tt class="literal">DB_NEXT</tt>: 89 </p> 90 <a id="cxx_cursor4"></a> 91 <pre class="programlisting">#include <db_cxx.h> 92 93... 94 95Db my_database(NULL, 0); 96Dbc *cursorp; 97 98try { 99 // Database open omitted for clarity 100 101 // Get a cursor 102 my_database.cursor(NULL, &cursorp, 0); 103 104 Dbt key, data; 105 int ret; 106 // Iterate over the database, retrieving each record in turn. 107 while ((ret = cursorp->get(&key, &data, DB_PREV)) == 0) { 108 // Do interesting things with the Dbts here. 109 } 110 if (ret != DB_NOTFOUND) { 111 // ret should be DB_NOTFOUND upon exiting the loop. 112 // Dbc::get() will by default throw an exception if any 113 // significant errors occur, so by default this if block 114 // can never be reached. 115 } 116} catch(DbException &e) { 117 my_database.err(e.get_errno(), "Error!"); 118} catch(std::exception &e) { 119 my_database.errx("Error! %s", e.what()); 120} 121 122// Cursors must be closed 123if (cursorp != NULL) 124 cursorp->close(); 125 126my_database.close(0);</pre> 127 <div class="sect2" lang="en" xml:lang="en"> 128 <div class="titlepage"> 129 <div> 130 <div> 131 <h3 class="title"><a id="cursorsearch"></a>Searching for Records</h3> 132 </div> 133 </div> 134 <div></div> 135 </div> 136 <p> 137 You can use cursors to search for database records. You can search based 138 on just a key, or you can search based on both the key and the data. 139 You can also perform partial matches if your database supports sorted 140 duplicate sets. In all cases, the key and data parameters of these 141 methods are filled with the key and data values of the database record 142 to which the cursor is positioned as a result of the search. 143 </p> 144 <p> 145 Also, if the search fails, then cursor's state is left unchanged 146 and 147 148 <tt class="literal">DB_NOTFOUND</tt> 149 is returned. 150 151 152 </p> 153 <p> 154 To use a cursor to search for a record, use 155 156 <span>Dbt::get()<tt class="methodname"></tt>.</span> 157 When you use this method, you can provide the following flags: 158 </p> 159 <div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"> 160 <h3 class="title">Note</h3> 161 <p> 162 Notice in the following list that the cursor flags use the 163 keyword <tt class="literal">SET</tt> when the cursor examines just the key 164 portion of the records (in this case, the cursor is set to the 165 record whose key matches the value provided to the cursor). 166 Moreover, when the cursor uses the keyword <tt class="literal">GET</tt>, 167 then the cursor is positioned to both the key 168 <span class="emphasis"><em>and</em></span> the data values provided to the cursor. 169 </p> 170 <p> 171 Regardless of the keyword you use to get a record with a cursor, the 172 cursor's key and data 173 174 <span><tt class="classname">Dbt</tt>s</span> 175 are filled with the data retrieved from the record to which the 176 cursor is positioned. 177 </p> 178 </div> 179 <div class="itemizedlist"> 180 <ul type="disc"> 181 <li> 182 <p> 183 184 <tt class="literal">DB_SET</tt> 185 </p> 186 <p> 187 Moves the cursor to the first record in the database with 188 the specified key. 189 </p> 190 </li> 191 <li> 192 <p> 193 194 <tt class="literal">DB_SET_RANGE</tt> 195 </p> 196 <p> 197 <span>Identical to 198 <tt class="literal">DB_SET</tt> 199 200 unless you are using the BTree access. In this case, the cursor 201 moves</span> 202 203 204 to the first record in the database whose 205 key is greater than or equal to the specified key. This comparison 206 is determined by the 207 208 <span>comparison function</span> 209 that you provide for the database. If no 210 211 <span>comparison function</span> 212 is provided, then the default 213 214 lexicographical sorting is used. 215 </p> 216 <p> 217 For example, suppose you have database records that use the 218 following 219 <span>Strings</span> 220 221 as keys: 222 </p> 223 <pre class="programlisting">Alabama 224Alaska 225Arizona</pre> 226 <p> 227 Then providing a search key of <tt class="literal">Alaska</tt> moves the 228 cursor to the second key noted above. Providing a key of 229 <tt class="literal">Al</tt> moves the cursor to the first key (<tt class="literal">Alabama</tt>), providing 230 a search key of <tt class="literal">Alas</tt> moves the cursor to the second key 231 (<tt class="literal">Alaska</tt>), and providing a key of <tt class="literal">Ar</tt> moves the 232 cursor to the last key (<tt class="literal">Arizona</tt>). 233 </p> 234 </li> 235 <li> 236 <p> 237 238 <tt class="literal">DB_GET_BOTH</tt> 239 </p> 240 <p> 241 Moves the cursor to the first record in the database that uses 242 the specified key and data. 243 </p> 244 </li> 245 <li> 246 <p> 247 248 <tt class="literal">DB_GET_BOTH_RANGE</tt> 249 </p> 250 <p> 251 Moves the cursor to the first record in the database whose key matches the specified 252 key and whose data is 253 greater than or equal to the specified data. If the database supports 254 duplicate records, then on matching the key, the cursor is moved to 255 the duplicate record with the smallest data that is greater than or 256 equal to the specified data. 257 </p> 258 <p> 259 For example, 260 261 <span>suppose your database uses BTree 262 and it has </span> 263 database records that use the following key/data pairs: 264 </p> 265 <pre class="programlisting">Alabama/Athens 266Alabama/Florence 267Alaska/Anchorage 268Alaska/Fairbanks 269Arizona/Avondale 270Arizona/Florence </pre> 271 <p>then providing:</p> 272 <div class="informaltable"> 273 <table border="1" width="80%"> 274 <colgroup> 275 <col /> 276 <col /> 277 <col /> 278 </colgroup> 279 <thead> 280 <tr> 281 <th>a search key of ...</th> 282 <th>and a search data of ...</th> 283 <th>moves the cursor to ...</th> 284 </tr> 285 </thead> 286 <tbody> 287 <tr> 288 <td>Alaska</td> 289 <td>Fa</td> 290 <td>Alaska/Fairbanks</td> 291 </tr> 292 <tr> 293 <td>Arizona</td> 294 <td>Fl</td> 295 <td>Arizona/Florence</td> 296 </tr> 297 <tr> 298 <td>Alaska</td> 299 <td>An</td> 300 <td>Alaska/Anchorage</td> 301 </tr> 302 </tbody> 303 </table> 304 </div> 305 </li> 306 </ul> 307 </div> 308 <p> 309 For example, assuming a database containing sorted duplicate records of 310 U.S. States/U.S Cities key/data pairs (both as 311 <span>Strings),</span> 312 313 then the following code fragment can be used to position the cursor 314 to any record in the database and print its key/data values: 315 316 </p> 317 <a id="cxx_cursor5"></a> 318 <pre class="programlisting">#include <db_cxx.h> 319#include <string.h> 320 321... 322 323Db my_database(NULL, 0); 324Dbc *cursorp; 325 326try { 327 // database open omitted for clarity 328 329 // Get a cursor 330 my_database.cursor(NULL, &cursorp, 0); 331 332 // Search criteria 333 char *search_key = "Alaska"; 334 char *search_data = "Fa"; 335 336 // Set up our DBTs 337 Dbt key(search_key, strlen(search_key) + 1); 338 Dbt data(search_data, strlen(search_data) + 1); 339 340 // Position the cursor to the first record in the database whose 341 // key matches the search key and whose data begins with the search 342 // data. 343 int ret = cursorp->get(&key, &data, DB_GET_BOTH_RANGE); 344 if (!ret) { 345 // Do something with the data 346 } 347} catch(DbException &e) { 348 my_database.err(e.get_errno(), "Error!"); 349} catch(std::exception &e) { 350 my_database.errx("Error! %s", e.what()); 351} 352 353// Close the cursor 354if (cursorp != NULL) 355 cursorp->close(); 356 357// Close the database 358my_database.close(0); </pre> 359 </div> 360 <div class="sect2" lang="en" xml:lang="en"> 361 <div class="titlepage"> 362 <div> 363 <div> 364 <h3 class="title"><a id="getdups"></a>Working with Duplicate Records</h3> 365 </div> 366 </div> 367 <div></div> 368 </div> 369 <p> 370 A record is a duplicate of another record if the two records share the 371 same key. For duplicate records, only the data portion of the record is unique. 372 </p> 373 <p> 374 Duplicate records are supported only for the BTree or Hash access methods. 375 For information on configuring your database to use duplicate records, 376 see <a href="btree.html#duplicateRecords">Allowing Duplicate Records</a>. 377 </p> 378 <p> 379 If your database supports duplicate records, then it can potentially 380 contain multiple records that share the same key. 381 382 383 384 <span>By default, normal database 385 get operations will only return the first such record in a set 386 of duplicate records. Typically, subsequent duplicate records are 387 accessed using a cursor. 388 </span> 389 390 The following 391 392 393 <span><tt class="methodname">Dbc::get()</tt> flags</span> 394 are interesting when working with databases that support duplicate records: 395 </p> 396 <div class="itemizedlist"> 397 <ul type="disc"> 398 <li> 399 <p> 400 401 <span> 402 <tt class="literal">DB_NEXT</tt>, 403 <tt class="literal">DB_PREV</tt> 404 </span> 405 </p> 406 <p> 407 Shows the next/previous record in the database, regardless of 408 whether it is a duplicate of the current record. For an example of 409 using these methods, see <a href="Positioning.html">Getting Records Using the Cursor</a>. 410 </p> 411 </li> 412 <li> 413 <p> 414 415 <tt class="literal">DB_GET_BOTH_RANGE</tt> 416 </p> 417 <p> 418 Useful for seeking the cursor to a specific record, regardless of 419 whether it is a duplicate record. See <a href="Positioning.html#cursorsearch">Searching for Records</a> for more 420 information. 421 </p> 422 </li> 423 <li> 424 <p> 425 426 <span> 427 <tt class="literal">DB_NEXT_NODUP</tt>, 428 <tt class="literal">DB_PREV_NODUP</tt> 429 </span> 430 </p> 431 <p> 432 Gets the next/previous non-duplicate record in the database. This 433 allows you to skip over all the duplicates in a set of duplicate 434 records. If you call 435 436 <span> 437 438 <tt class="methodname">Dbc::get()</tt> 439 with <tt class="literal">DB_PREV_NODUP</tt>, 440 </span> 441 then the cursor is positioned to the last record for the previous 442 key in the database. For example, if you have the following records 443 in your database: 444 </p> 445 <pre class="programlisting">Alabama/Athens 446Alabama/Florence 447Alaska/Anchorage 448Alaska/Fairbanks 449Arizona/Avondale 450Arizona/Florence</pre> 451 <p> 452 and your cursor is positioned to <tt class="literal">Alaska/Fairbanks</tt>, 453 and you then call 454 455 <span> 456 457 <tt class="methodname">Dbc::get()</tt> 458 with <tt class="literal">DB_PREV_NODUP</tt>, 459 </span> 460 then the cursor is positioned to Alabama/Florence. Similarly, if 461 you call 462 463 <span> 464 465 <tt class="methodname">Dbc::get()</tt> 466 with <tt class="literal">DB_NEXT_NODUP</tt>, 467 </span> 468 469 then the cursor is positioned to the first record corresponding to 470 the next key in the database. 471 </p> 472 <p> 473 If there is no next/previous key in the database, then 474 475 <tt class="literal">DB_NOTFOUND</tt> 476 is returned, and the cursor is left unchanged. 477 </p> 478 </li> 479 <li> 480 <p> 481 482 <tt class="literal">DB_NEXT_DUP</tt> 483 </p> 484 <p> 485 486 Gets the 487 488 <span>next</span> 489 record that shares the current key. If the 490 cursor is positioned at the last record in the duplicate set and 491 you call 492 493 <span> 494 495 <tt class="methodname">Dbc::get()</tt> 496 with <tt class="literal">DB_NEXT_DUP</tt>, 497 </span> 498 499 then 500 501 <tt class="literal">DB_NOTFOUND</tt> 502 is returned and the cursor is left unchanged. 503 504 </p> 505 </li> 506 </ul> 507 </div> 508 <p> 509 For example, the following code fragment positions a cursor to a key 510 511 512 513 <span>and displays it and all its 514 duplicates.</span> 515 516 517 </p> 518 <a id="cxx_cursor6"></a> 519 <pre class="programlisting">#include <db_cxx.h> 520#include <string.h> 521 522... 523 524char *search_key = "Al"; 525 526Db my_database(NULL, 0); 527Dbc *cursorp; 528 529try { 530 // database open omitted for clarity 531 532 // Get a cursor 533 my_database.cursor(NULL, &cursorp, 0); 534 535 // Set up our DBTs 536 Dbt key(search_key, strlen(search_key) + 1); 537 Dbt data; 538 539 // Position the cursor to the first record in the database whose 540 // key and data begin with the correct strings. 541 int ret = cursorp->get(&key, &data, DB_SET); 542 while (ret != DB_NOTFOUND) { 543 std::cout << "key: " << (char *)key.get_data() 544 << "data: " << (char *)data.get_data()<< std::endl; 545 ret = cursorp->get(&key, &data, DB_NEXT_DUP); 546 } 547} catch(DbException &e) { 548 my_database.err(e.get_errno(), "Error!"); 549} catch(std::exception &e) { 550 my_database.errx("Error! %s", e.what()); 551} 552 553// Close the cursor 554if (cursorp != NULL) 555 cursorp->close(); 556 557// Close the database 558my_database.close(0); </pre> 559 </div> 560 </div> 561 <div class="navfooter"> 562 <hr /> 563 <table width="100%" summary="Navigation footer"> 564 <tr> 565 <td width="40%" align="left"><a accesskey="p" href="Cursors.html">Prev</a> </td> 566 <td width="20%" align="center"> 567 <a accesskey="u" href="Cursors.html">Up</a> 568 </td> 569 <td width="40%" align="right"> <a accesskey="n" href="PutEntryWCursor.html">Next</a></td> 570 </tr> 571 <tr> 572 <td width="40%" align="left" valign="top">Chapter 4. Using Cursors </td> 573 <td width="20%" align="center"> 574 <a accesskey="h" href="index.html">Home</a> 575 </td> 576 <td width="40%" align="right" valign="top"> Putting Records Using Cursors</td> 577 </tr> 578 </table> 579 </div> 580 </body> 581</html> 582