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>Cursor Example</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="ReplacingEntryWCursor.html" title="Replacing Records Using Cursors" /> 12 <link rel="next" href="indexes.html" title="Chapter 5. Secondary Databases" /> 13 </head> 14 <body> 15 <div class="navheader"> 16 <table width="100%" summary="Navigation header"> 17 <tr> 18 <th colspan="3" align="center">Cursor Example</th> 19 </tr> 20 <tr> 21 <td width="20%" align="left"><a accesskey="p" href="ReplacingEntryWCursor.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="indexes.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="CoreCursorUsage"></a>Cursor Example</h2> 33 </div> 34 </div> 35 <div></div> 36 </div> 37 <p> 38 In 39 40 <a href="DbCXXUsage.html">Database Usage Example</a> 41 we wrote an 42 application that loaded two databases with 43 vendor and inventory information. In this example, we will write an 44 application to display all of the items in the inventory database. As a 45 part of showing any given inventory item, we will look up the vendor who 46 can provide the item and show the vendor's contact information. 47 </p> 48 <p> 49 Specifically, the <tt class="classname">example_database_read</tt> 50 application does the following: 51 </p> 52 <div class="orderedlist"> 53 <ol type="1"> 54 <li> 55 <p> 56 Opens the the inventory and vendor databases 57 that were created by our <tt class="classname">example_database_load</tt> 58 application. See 59 60 <a href="DbCXXUsage.html#exampledbload-cxx">example_database_load</a> 61 for information on how that 62 application creates the databases and writes data to them. 63 </p> 64 </li> 65 <li> 66 <p>Obtains a cursor from the inventory database.</p> 67 </li> 68 <li> 69 <p> 70 Steps through the inventory database, displaying 71 each record as it goes. 72 </p> 73 </li> 74 <li> 75 <p> 76 Gets the name of the vendor for that inventory item from the 77 inventory record. 78 </p> 79 </li> 80 <li> 81 <p> 82 Uses the vendor name to look up the vendor record in the vendor 83 database. 84 </p> 85 </li> 86 <li> 87 <p>Displays the vendor record.</p> 88 </li> 89 </ol> 90 </div> 91 <p> 92 Remember that you can find the complete implementation of this application 93 in: 94 </p> 95 <pre class="programlisting"><span class="emphasis"><em>DB_INSTALL</em></span>/examples_cxx/getting_started</pre> 96 <p> 97 where <tt class="literal"><span class="emphasis"><em>DB_INSTALL</em></span></tt> is the location where you 98 placed your DB distribution. 99 </p> 100 <div class="example"> 101 <a id="CoreEIR-cxx"></a> 102 <p class="title"> 103 <b>Example 4.1 example_database_read</b> 104 </p> 105 <p> 106 To begin, we include the necessary header files and perform our 107 forward declarations. We also write our <tt class="function">usage()</tt> 108 function. 109 </p> 110 <a id="cxx_cursor10"></a> 111 <pre class="programlisting">// File: example_database_read.cpp 112#include <iostream> 113#include <fstream> 114#include <cstdlib> 115 116#include "MyDb.hpp" 117#include "gettingStartedCommon.hpp" 118 119// Forward declarations 120int show_all_records(MyDb &inventoryDB, MyDb &vendorDB); 121int show_vendor(MyDb &vendorDB, const char *vendor); </pre> 122 <p> 123 Next we write our <tt class="function">main()</tt> function. Note that it is 124 somewhat unnecessarily complicated here because we will be extending it 125 in the next chapter to perform inventory item lookups. 126 </p> 127 <a id="cxx_cursor11"></a> 128 <pre class="programlisting">// Displays all inventory items and the associated vendor record. 129int 130main (int argc, char *argv[]) 131{ 132 // Initialize the path to the database files 133 std::string databaseHome("./"); 134 135 // Database names 136 std::string vDbName("vendordb.db"); 137 std::string iDbName("inventorydb.db"); 138 139 // Parse the command line arguments 140 // Omitted for brevity 141 142 try 143 { 144 // Open all databases. 145 MyDb inventoryDB(databaseHome, iDbName); 146 MyDb vendorDB(databaseHome, vDbName); 147 148 show_all_records(inventoryDB, vendorDB); 149 } catch(DbException &e) { 150 std::cerr << "Error reading databases. " << std::endl; 151 std::cerr << e.what() << std::endl; 152 return(e.get_errno()); 153 } catch(std::exception &e) { 154 std::cerr << "Error reading databases. " << std::endl; 155 std::cerr << e.what() << std::endl; 156 return(-1); 157 } 158 159 return(0); 160} // End main </pre> 161 <p> 162 Next we need to write the <tt class="function">show_all_records()</tt> 163 function. This function displays all 164 of the inventory records found in the inventory database. Once it shows 165 the inventory record, it retrieves the vendor's name from that record 166 and uses it to look up and display the appropriate vendor record: 167 </p> 168 <a id="cxx_cursor12"></a> 169 <pre class="programlisting">// Shows all the records in the inventory database. 170// For each inventory record shown, the appropriate 171// vendor record is also displayed. 172int 173show_all_records(MyDb &inventoryDB, MyDb &vendorDB) 174{ 175 // Get a cursor to the inventory db 176 Dbc *cursorp; 177 try { 178 inventoryDB.getDb().cursor(NULL, &cursorp, 0); 179 180 // Iterate over the inventory database, from the first record 181 // to the last, displaying each in turn 182 Dbt key, data; 183 int ret; 184 while ((ret = cursorp->get(&key, &data, DB_NEXT)) == 0 ) 185 { 186 InventoryData inventoryItem(data.get_data()); 187 inventoryItem.show(); 188 189 show_vendor(vendorDB, inventoryItem.getVendor().c_str()); 190 } 191 } catch(DbException &e) { 192 inventoryDB.getDb().err(e.get_errno(), "Error in show_all_records"); 193 cursorp->close(); 194 throw e; 195 } catch(std::exception &e) { 196 cursorp->close(); 197 throw e; 198 } 199 200 cursorp->close(); 201 return (0); 202} </pre> 203 <p> 204 Note that the <tt class="classname">InventoryData</tt> class that we use here 205 is described in 206 <a href="DbCXXUsage.html#InventoryData">InventoryData Class</a>. 207 </p> 208 <p> 209 Having displayed the inventory record, we now want to display the 210 vendor record corresponding to this record. 211 In this case we do not need to use a 212 cursor to display the vendor record. Using a cursor here complicates our 213 code slightly for no good gain. Instead, we simply perform a 214 <tt class="function">get()</tt> directly against the vendor database. 215 </p> 216 <a id="cxx_cursor13"></a> 217 <pre class="programlisting">// Shows a vendor record. Each vendor record is an instance of 218// a vendor structure. See loadVendorDB() in 219// example_database_load for how this structure was originally 220// put into the database. 221int 222show_vendor(MyDb &vendorDB, const char *vendor) 223{ 224 Dbt data; 225 VENDOR my_vendor; 226 227 try { 228 // Set the search key to the vendor's name 229 // vendor is explicitly cast to char * to stop a compiler 230 // complaint. 231 Dbt key((char *)vendor, strlen(vendor) + 1); 232 233 // Make sure we use the memory we set aside for the VENDOR 234 // structure rather than the memory that DB allocates. 235 // Some systems may require structures to be aligned in memory 236 // in a specific way, and DB may not get it right. 237 238 data.set_data(&my_vendor); 239 data.set_ulen(sizeof(VENDOR)); 240 data.set_flags(DB_DBT_USERMEM); 241 242 // Get the record 243 vendorDB.getDb().get(NULL, &key, &data, 0); 244 std::cout << " " << my_vendor.street << "\n" 245 << " " << my_vendor.city << ", " 246 << my_vendor.state << "\n" 247 << " " << my_vendor.zipcode << "\n" 248 << " " << my_vendor.phone_number << "\n" 249 << " Contact: " << my_vendor.sales_rep << "\n" 250 << " " << my_vendor.sales_rep_phone 251 << std::endl; 252 253 } catch(DbException &e) { 254 vendorDB.getDb().err(e.get_errno(), "Error in show_vendor"); 255 throw e; 256 } catch(std::exception &e) { 257 throw e; 258 } 259 return (0); 260} </pre> 261 </div> 262 <p> 263 That completes the implementation of 264 <tt class="classname">example_database_read()</tt>. In the next chapter, we 265 will extend this application to make use of a secondary database so that 266 we can query the inventory database for a specific inventory item. 267 </p> 268 </div> 269 <div class="navfooter"> 270 <hr /> 271 <table width="100%" summary="Navigation footer"> 272 <tr> 273 <td width="40%" align="left"><a accesskey="p" href="ReplacingEntryWCursor.html">Prev</a> </td> 274 <td width="20%" align="center"> 275 <a accesskey="u" href="Cursors.html">Up</a> 276 </td> 277 <td width="40%" align="right"> <a accesskey="n" href="indexes.html">Next</a></td> 278 </tr> 279 <tr> 280 <td width="40%" align="left" valign="top">Replacing Records Using Cursors </td> 281 <td width="20%" align="center"> 282 <a accesskey="h" href="index.html">Home</a> 283 </td> 284 <td width="40%" align="right" valign="top"> Chapter 5. Secondary Databases</td> 285 </tr> 286 </table> 287 </div> 288 </body> 289</html> 290