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 &lt;iostream&gt;
113#include &lt;fstream&gt;
114#include &lt;cstdlib&gt;
115                                                                                                                                    
116#include "MyDb.hpp"
117#include "gettingStartedCommon.hpp"
118
119// Forward declarations
120int show_all_records(MyDb &amp;inventoryDB, MyDb &amp;vendorDB);
121int show_vendor(MyDb &amp;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 &amp;e) {
150        std::cerr &lt;&lt; "Error reading databases. " &lt;&lt; std::endl;
151        std::cerr &lt;&lt; e.what() &lt;&lt; std::endl;
152        return(e.get_errno());
153    } catch(std::exception &amp;e) {
154        std::cerr &lt;&lt; "Error reading databases. " &lt;&lt; std::endl;
155        std::cerr &lt;&lt; e.what() &lt;&lt; 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 &amp;inventoryDB, MyDb &amp;vendorDB)
174{
175    // Get a cursor to the inventory db
176    Dbc *cursorp;
177    try {
178        inventoryDB.getDb().cursor(NULL, &amp;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-&gt;get(&amp;key, &amp;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 &amp;e) {
192        inventoryDB.getDb().err(e.get_errno(), "Error in show_all_records");
193        cursorp-&gt;close();
194        throw e;
195    } catch(std::exception &amp;e) {
196        cursorp-&gt;close();
197        throw e;
198    }
199
200    cursorp-&gt;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 &amp;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(&amp;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, &amp;key, &amp;data, 0);
244        std::cout &lt;&lt; "        " &lt;&lt; my_vendor.street &lt;&lt; "\n"
245                  &lt;&lt; "        " &lt;&lt; my_vendor.city &lt;&lt; ", "
246                  &lt;&lt; my_vendor.state &lt;&lt; "\n"
247                  &lt;&lt; "        " &lt;&lt; my_vendor.zipcode &lt;&lt; "\n"
248                  &lt;&lt; "        " &lt;&lt; my_vendor.phone_number &lt;&lt; "\n"
249                  &lt;&lt; "        Contact: " &lt;&lt; my_vendor.sales_rep &lt;&lt; "\n"
250                  &lt;&lt; "                 " &lt;&lt; my_vendor.sales_rep_phone
251                  &lt;&lt; std::endl;
252
253    } catch(DbException &amp;e) {
254        vendorDB.getDb().err(e.get_errno(), "Error in show_vendor");
255        throw e;
256    } catch(std::exception &amp;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