• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/router/db-4.8.30/docs/gsg/CXX/
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>Implementing Key Extractors</title>
7    <link rel="stylesheet" href="gettingStarted.css" type="text/css" />
8    <meta name="generator" content="DocBook XSL Stylesheets V1.73.2" />
9    <link rel="start" href="index.html" title="Getting Started with Berkeley DB" />
10    <link rel="up" href="indexes.html" title="Chapter��5.��Secondary Databases" />
11    <link rel="prev" href="indexes.html" title="Chapter��5.��Secondary Databases" />
12    <link rel="next" href="readSecondary.html" title="Reading 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">Implementing Key 
19        
20        <span>Extractors</span>
21        </th>
22        </tr>
23        <tr>
24          <td width="20%" align="left"><a accesskey="p" href="indexes.html">Prev</a>��</td>
25          <th width="60%" align="center">Chapter��5.��Secondary Databases</th>
26          <td width="20%" align="right">��<a accesskey="n" href="readSecondary.html">Next</a></td>
27        </tr>
28      </table>
29      <hr />
30    </div>
31    <div class="sect1" lang="en" xml:lang="en">
32      <div class="titlepage">
33        <div>
34          <div>
35            <h2 class="title" style="clear: both"><a id="keyCreator"></a>Implementing Key 
36        
37        <span>Extractors</span>
38        </h2>
39          </div>
40        </div>
41      </div>
42      <div class="toc">
43        <dl>
44          <dt>
45            <span class="sect2">
46              <a href="keyCreator.html#multikeys">Working with Multiple Keys</a>
47            </span>
48          </dt>
49        </dl>
50      </div>
51      <p>
52        You must provide every secondary database with a 
53            <span>class</span>
54            
55        that creates keys from primary records. You identify this 
56            <span>class</span>
57            
58        
59        
60        <span>
61            when you associate your secondary database to your primary.
62        </span>
63     </p>
64      <p>
65        You can create keys using whatever data you want. Typically you will
66        base your key on some information found in a record's data, but you
67        can also use information found in the primary record's key. How you build
68        your keys is entirely dependent upon the nature of the index that you
69        want to maintain.
70    </p>
71      <p>
72        You implement a key extractor by writing a function that extracts
73        the necessary information from a primary record's key or data.
74        This function must conform to a specific prototype, and it must be
75        provided as a callback to the <code class="methodname">associate()</code>
76        method.
77    </p>
78      <p>
79        For example, suppose your primary database records contain data that
80        uses the following structure:
81    </p>
82      <a id="c_index3"></a>
83      <pre class="programlisting">typedef struct vendor {
84    char name[MAXFIELD];             /* Vendor name */
85    char street[MAXFIELD];           /* Street name and number */
86    char city[MAXFIELD];             /* City */
87    char state[3];                   /* Two-digit US state code */
88    char zipcode[6];                 /* US zipcode */
89    char phone_number[13];           /* Vendor phone number */
90    char sales_rep[MAXFIELD];        /* Name of sales representative */
91    char sales_rep_phone[MAXFIELD];  /* Sales rep's phone number */
92} VENDOR; </pre>
93      <p>
94        Further suppose that you want to be able to query your primary database
95        based on the name of a sales representative. Then you would write a
96        function that looks like this:
97    </p>
98      <a id="cxx_index4"></a>
99      <pre class="programlisting">#include &lt;db_cxx.h&gt;
100
101...
102
103int
104get_sales_rep(Db *sdbp,          // secondary db handle
105              const Dbt *pkey,   // primary db record's key
106              const Dbt *pdata,  // primary db record's data
107              Dbt *skey)         // secondary db record's key
108{
109    VENDOR *vendor;
110
111    // First, extract the structure contained in the primary's data
112    vendor = (VENDOR *)pdata-&gt;get_data();
113
114    // Now set the secondary key's data to be the representative's name
115    skey-&gt;set_data(vendor-&gt;sales_rep);
116    skey-&gt;set_size(strlen(vendor-&gt;sales_rep) + 1);
117
118    // Return 0 to indicate that the record can be created/updated.
119    return (0);
120} </pre>
121      <p>
122        In order to use this function, you provide it on the
123        <code class="methodname">associate()</code> method after the primary and
124        secondary databases have been created and opened:
125    </p>
126      <a id="cxx_index5"></a>
127      <pre class="programlisting">db.associate(NULL,           // TXN id
128             &amp;sdb,           // Secondary database
129             get_sales_rep,      // Callback used for key creation.
130             0);                 // Flags</pre>
131      <div class="sect2" lang="en" xml:lang="en">
132        <div class="titlepage">
133          <div>
134            <div>
135              <h3 class="title"><a id="multikeys"></a>Working with Multiple Keys</h3>
136            </div>
137          </div>
138        </div>
139        <p>
140                    Until now we have only discussed indexes as if there is
141                    a one-to-one relationship between the secondary key and
142                    the primary database record. In fact, it is possible to
143                    generate multiple keys for any given record, provided
144                    that you take appropriate steps in your key creator
145                    to do so.
146            </p>
147        <p>
148                    For example, suppose you had a database that contained
149                    information about books. Suppose further that you
150                    sometimes want to look up books by author. Because
151                    sometimes books have multiple authors, you may want to
152                    return multiple secondary keys for every book that you
153                    index.
154            </p>
155        <p>
156                    To do this, you write a key extractor that returns a
157                                
158                                <span>Dbt</span>
159                        whose <code class="literal">data</code> member points to an array of
160                                
161                                <span>Dbts.</span>
162                        Each such member of this array contains a single secondary key.
163                        In addition, the 
164                                
165                                <span>Dbt</span>
166                        returned by your key extractor must have a size field
167                        equal to the number of elements contained in the 
168                                
169                                <span>Dbt</span>
170                        array. Also, the flag field for the 
171                                
172                                <span>Dbt</span>
173                        returned by the callback must include 
174                        <code class="literal">DB_DBT_MULTIPLE</code>. For example:
175             </p>
176        <div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
177          <h3 class="title">Note</h3>
178          <p>
179                             It is important that the array of secondary
180                             keys created by your callback not contain
181                             repeats. That is, every element in the array
182                             must be unique. If the array does not contain
183                             a unique set, then the secondary can get out
184                             of sync with the primary.
185                     </p>
186        </div>
187        <pre class="programlisting">int
188my_callback(Db *dbp, const Dbt *pkey, const Dbt *pdata, Dbt *skey)
189{
190    Dbt *tmpdbt;
191    char *tmpdata1, tmpdata2;
192
193    // This example skips the step of extracting the data you
194    // want to use for building your secondary keys from the
195    // pkey or pdata Dbt.
196     
197    // Assume for the purpose of this example that the data 
198    // is temporarily stored in two variables, 
199    // tmpdata1 and tmpdata2.
200
201    // Create an array of Dbts that is large enough for the
202    // number of keys that you want to return. In this case, 
203    // we go with an array of size two. 
204
205    tmpdbt = malloc(sizeof(Dbt) * 2);
206    memset(tmpdbt, 0, sizeof(Dbt) * 2);
207
208    // Now assign secondary keys to each element of the array. 
209    tmpdbt[0].set_data(tmpdata1);
210    tmpdbt[0].set_size((u_int32_t)strlen(tmpdbt[0].data) + 1);
211    tmpdbt[1].set_data(tmpdata2);
212    tmpdbt[1].set_size((u_int32_t)strlen(tmpdbt[1].data) + 1);
213
214    // Now we set flags for the returned Dbt. DB_DBT_MULTIPLE is
215    // required in order for DB to know that the Dbt references an 
216    // array. In addition, we set DB_DBT_APPMALLOC because we
217    // dynamically allocated memory for the Dbt's data field.
218    // DB_DBT_APPMALLOC causes DB to release that memory once it
219    // is done with the returned Dbt. 
220    skey-&gt;set_flags(DB_DBT_MULTIPLE | DB_DBT_APPMALLOC);
221
222    // Point the results data field to the arrays of Dbts
223    skey-&gt;set_data(tmpdbt);
224
225    // Indicate the returned array is of size 2
226    skey-&gt;size = 2;
227
228    return (0);
229} </pre>
230      </div>
231    </div>
232    <div class="navfooter">
233      <hr />
234      <table width="100%" summary="Navigation footer">
235        <tr>
236          <td width="40%" align="left"><a accesskey="p" href="indexes.html">Prev</a>��</td>
237          <td width="20%" align="center">
238            <a accesskey="u" href="indexes.html">Up</a>
239          </td>
240          <td width="40%" align="right">��<a accesskey="n" href="readSecondary.html">Next</a></td>
241        </tr>
242        <tr>
243          <td width="40%" align="left" valign="top">Chapter��5.��Secondary Databases��</td>
244          <td width="20%" align="center">
245            <a accesskey="h" href="index.html">Home</a>
246          </td>
247          <td width="40%" align="right" valign="top">��Reading Secondary Databases</td>
248        </tr>
249      </table>
250    </div>
251  </body>
252</html>
253