<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>Cursor Example</title> <link rel="stylesheet" href="gettingStarted.css" type="text/css" /> <meta name="generator" content="DocBook XSL Stylesheets V1.73.2" /> <link rel="start" href="index.html" title="Getting Started with Berkeley DB" /> <link rel="up" href="Cursors.html" title="Chapter 4. Using Cursors" /> <link rel="prev" href="ReplacingEntryWCursor.html" title="Replacing Records Using Cursors" /> <link rel="next" href="indexes.html" title="Chapter 5. Secondary Databases" /> </head> <body> <div class="navheader"> <table width="100%" summary="Navigation header"> <tr> <th colspan="3" align="center">Cursor Example</th> </tr> <tr> <td width="20%" align="left"><a accesskey="p" href="ReplacingEntryWCursor.html">Prev</a> </td> <th width="60%" align="center">Chapter 4. Using Cursors</th> <td width="20%" align="right"> <a accesskey="n" href="indexes.html">Next</a></td> </tr> </table> <hr /> </div> <div class="sect1" lang="en" xml:lang="en"> <div class="titlepage"> <div> <div> <h2 class="title" style="clear: both"><a id="CoreCursorUsage"></a>Cursor Example</h2> </div> </div> </div> <p> In <a class="xref" href="DbCXXUsage.html" title="Database Usage Example">Database Usage Example</a> we wrote an application that loaded two databases with vendor and inventory information. In this example, we will write an application to display all of the items in the inventory database. As a part of showing any given inventory item, we will look up the vendor who can provide the item and show the vendor's contact information. </p> <p> Specifically, the <code class="classname">example_database_read</code> application does the following: </p> <div class="orderedlist"> <ol type="1"> <li> <p> Opens the the inventory and vendor databases that were created by our <code class="classname">example_database_load</code> application. See <a class="xref" href="DbCXXUsage.html#exampledbload-cxx" title="Example 3.3 example_database_load">example_database_load</a> for information on how that application creates the databases and writes data to them. </p> </li> <li> <p>Obtains a cursor from the inventory database.</p> </li> <li> <p> Steps through the inventory database, displaying each record as it goes. </p> </li> <li> <p> Gets the name of the vendor for that inventory item from the inventory record. </p> </li> <li> <p> Uses the vendor name to look up the vendor record in the vendor database. </p> </li> <li> <p>Displays the vendor record.</p> </li> </ol> </div> <p> Remember that you can find the complete implementation of this application in: </p> <pre class="programlisting"><span class="emphasis"><em>DB_INSTALL</em></span>/examples_cxx/getting_started</pre> <p> where <code class="literal"><span class="emphasis"><em>DB_INSTALL</em></span></code> is the location where you placed your DB distribution. </p> <div class="example"> <a id="CoreEIR-cxx"></a> <p class="title"> <b>Example 4.1 example_database_read</b> </p> <div class="example-contents"> <p> To begin, we include the necessary header files and perform our forward declarations. We also write our <code class="function">usage()</code> function. </p> <a id="cxx_cursor10"></a> <pre class="programlisting">// File: example_database_read.cpp #include <iostream> #include <fstream> #include <cstdlib> #include "MyDb.hpp" #include "gettingStartedCommon.hpp" // Forward declarations int show_all_records(MyDb &inventoryDB, MyDb &vendorDB); int show_vendor(MyDb &vendorDB, const char *vendor); </pre> <p> Next we write our <code class="function">main()</code> function. Note that it is somewhat unnecessarily complicated here because we will be extending it in the next chapter to perform inventory item lookups. </p> <a id="cxx_cursor11"></a> <pre class="programlisting">// Displays all inventory items and the associated vendor record. int main (int argc, char *argv[]) { // Initialize the path to the database files std::string databaseHome("./"); // Database names std::string vDbName("vendordb.db"); std::string iDbName("inventorydb.db"); // Parse the command line arguments // Omitted for brevity try { // Open all databases. MyDb inventoryDB(databaseHome, iDbName); MyDb vendorDB(databaseHome, vDbName); show_all_records(inventoryDB, vendorDB); } catch(DbException &e) { std::cerr << "Error reading databases. " << std::endl; std::cerr << e.what() << std::endl; return(e.get_errno()); } catch(std::exception &e) { std::cerr << "Error reading databases. " << std::endl; std::cerr << e.what() << std::endl; return(-1); } return(0); } // End main </pre> <p> Next we need to write the <code class="function">show_all_records()</code> function. This function displays all of the inventory records found in the inventory database. Once it shows the inventory record, it retrieves the vendor's name from that record and uses it to look up and display the appropriate vendor record: </p> <a id="cxx_cursor12"></a> <pre class="programlisting">// Shows all the records in the inventory database. // For each inventory record shown, the appropriate // vendor record is also displayed. int show_all_records(MyDb &inventoryDB, MyDb &vendorDB) { // Get a cursor to the inventory db Dbc *cursorp; try { inventoryDB.getDb().cursor(NULL, &cursorp, 0); // Iterate over the inventory database, from the first record // to the last, displaying each in turn Dbt key, data; int ret; while ((ret = cursorp->get(&key, &data, DB_NEXT)) == 0 ) { InventoryData inventoryItem(data.get_data()); inventoryItem.show(); show_vendor(vendorDB, inventoryItem.getVendor().c_str()); } } catch(DbException &e) { inventoryDB.getDb().err(e.get_errno(), "Error in show_all_records"); cursorp->close(); throw e; } catch(std::exception &e) { cursorp->close(); throw e; } cursorp->close(); return (0); } </pre> <p> Note that the <code class="classname">InventoryData</code> class that we use here is described in <a class="xref" href="DbCXXUsage.html#InventoryData" title="Example 3.2 InventoryData Class">InventoryData Class</a>. </p> <p> Having displayed the inventory record, we now want to display the vendor record corresponding to this record. In this case we do not need to use a cursor to display the vendor record. Using a cursor here complicates our code slightly for no good gain. Instead, we simply perform a <code class="function">get()</code> directly against the vendor database. </p> <a id="cxx_cursor13"></a> <pre class="programlisting">// Shows a vendor record. Each vendor record is an instance of // a vendor structure. See loadVendorDB() in // example_database_load for how this structure was originally // put into the database. int show_vendor(MyDb &vendorDB, const char *vendor) { Dbt data; VENDOR my_vendor; try { // Set the search key to the vendor's name // vendor is explicitly cast to char * to stop a compiler // complaint. Dbt key((char *)vendor, strlen(vendor) + 1); // Make sure we use the memory we set aside for the VENDOR // structure rather than the memory that DB allocates. // Some systems may require structures to be aligned in memory // in a specific way, and DB may not get it right. data.set_data(&my_vendor); data.set_ulen(sizeof(VENDOR)); data.set_flags(DB_DBT_USERMEM); // Get the record vendorDB.getDb().get(NULL, &key, &data, 0); std::cout << " " << my_vendor.street << "\n" << " " << my_vendor.city << ", " << my_vendor.state << "\n" << " " << my_vendor.zipcode << "\n" << " " << my_vendor.phone_number << "\n" << " Contact: " << my_vendor.sales_rep << "\n" << " " << my_vendor.sales_rep_phone << std::endl; } catch(DbException &e) { vendorDB.getDb().err(e.get_errno(), "Error in show_vendor"); throw e; } catch(std::exception &e) { throw e; } return (0); } </pre> </div> </div> <br class="example-break" /> <p> That completes the implementation of <code class="classname">example_database_read()</code>. In the next chapter, we will extend this application to make use of a secondary database so that we can query the inventory database for a specific inventory item. </p> </div> <div class="navfooter"> <hr /> <table width="100%" summary="Navigation footer"> <tr> <td width="40%" align="left"><a accesskey="p" href="ReplacingEntryWCursor.html">Prev</a> </td> <td width="20%" align="center"> <a accesskey="u" href="Cursors.html">Up</a> </td> <td width="40%" align="right"> <a accesskey="n" href="indexes.html">Next</a></td> </tr> <tr> <td width="40%" align="left" valign="top">Replacing Records Using Cursors </td> <td width="20%" align="center"> <a accesskey="h" href="index.html">Home</a> </td> <td width="40%" align="right" valign="top"> Chapter 5. Secondary Databases</td> </tr> </table> </div> </body> </html>