CoreCursorUsage.html   [plain text]


<?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.62.4" />
    <link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
    <link rel="up" href="Cursors.html" title="Chapter 4. Using Cursors" />
    <link rel="previous" 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></div>
      </div>
      <p>
        In 
             
            <a href="DbCXXUsage.html">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 <tt class="classname">example_database_read</tt>
        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 <tt class="classname">example_database_load</tt>
            application. See 
                 
                <a href="DbCXXUsage.html#exampledbload-cxx">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 <tt class="literal"><span class="emphasis"><em>DB_INSTALL</em></span></tt> 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>
        <p>
            To begin, we include the necessary header files and perform our
            forward declarations. We also write our <tt class="function">usage()</tt>
            function.
        </p>
        <a id="cxx_cursor10"></a>
        <pre class="programlisting">// File: example_database_read.cpp
#include &lt;iostream&gt;
#include &lt;fstream&gt;
#include &lt;cstdlib&gt;
                                                                                                                                    
#include "MyDb.hpp"
#include "gettingStartedCommon.hpp"

// Forward declarations
int show_all_records(MyDb &amp;inventoryDB, MyDb &amp;vendorDB);
int show_vendor(MyDb &amp;vendorDB, const char *vendor); </pre>
        <p>
        Next we write our <tt class="function">main()</tt> 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 &amp;e) {
        std::cerr &lt;&lt; "Error reading databases. " &lt;&lt; std::endl;
        std::cerr &lt;&lt; e.what() &lt;&lt; std::endl;
        return(e.get_errno());
    } catch(std::exception &amp;e) {
        std::cerr &lt;&lt; "Error reading databases. " &lt;&lt; std::endl;
        std::cerr &lt;&lt; e.what() &lt;&lt; std::endl;
        return(-1);
    }

    return(0);
} // End main </pre>
        <p>
        Next we need to write the <tt class="function">show_all_records()</tt>
        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 &amp;inventoryDB, MyDb &amp;vendorDB)
{
    // Get a cursor to the inventory db
    Dbc *cursorp;
    try {
        inventoryDB.getDb().cursor(NULL, &amp;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-&gt;get(&amp;key, &amp;data, DB_NEXT)) == 0 )
        {
            InventoryData inventoryItem(data.get_data());
            inventoryItem.show();

            show_vendor(vendorDB, inventoryItem.getVendor().c_str());
        }
    } catch(DbException &amp;e) {
        inventoryDB.getDb().err(e.get_errno(), "Error in show_all_records");
        cursorp-&gt;close();
        throw e;
    } catch(std::exception &amp;e) {
        cursorp-&gt;close();
        throw e;
    }

    cursorp-&gt;close();
    return (0);
} </pre>
        <p>
        Note that the <tt class="classname">InventoryData</tt> class that we use here
        is described in
        <a href="DbCXXUsage.html#InventoryData">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
        <tt class="function">get()</tt> 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 &amp;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(&amp;my_vendor);
        data.set_ulen(sizeof(VENDOR));
        data.set_flags(DB_DBT_USERMEM);

        // Get the record
        vendorDB.getDb().get(NULL, &amp;key, &amp;data, 0);
        std::cout &lt;&lt; "        " &lt;&lt; my_vendor.street &lt;&lt; "\n"
                  &lt;&lt; "        " &lt;&lt; my_vendor.city &lt;&lt; ", "
                  &lt;&lt; my_vendor.state &lt;&lt; "\n"
                  &lt;&lt; "        " &lt;&lt; my_vendor.zipcode &lt;&lt; "\n"
                  &lt;&lt; "        " &lt;&lt; my_vendor.phone_number &lt;&lt; "\n"
                  &lt;&lt; "        Contact: " &lt;&lt; my_vendor.sales_rep &lt;&lt; "\n"
                  &lt;&lt; "                 " &lt;&lt; my_vendor.sales_rep_phone
                  &lt;&lt; std::endl;

    } catch(DbException &amp;e) {
        vendorDB.getDb().err(e.get_errno(), "Error in show_vendor");
        throw e;
    } catch(std::exception &amp;e) {
        throw e;
    }
    return (0);
} </pre>
      </div>
      <p>
        That completes the implementation of
        <tt class="classname">example_database_read()</tt>. 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>