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>Using C Structures with DB</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="DBEntry.html" title="Chapter 3. Database Records" />
11    <link rel="previous" href="usingDbt.html" title="Reading and Writing Database Records" />
12    <link rel="next" href="DbUsage.html" title="Database Usage Example" />
13  </head>
14  <body>
15    <div class="navheader">
16      <table width="100%" summary="Navigation header">
17        <tr>
18          <th colspan="3" align="center">Using C Structures with DB</th>
19        </tr>
20        <tr>
21          <td width="20%" align="left"><a accesskey="p" href="usingDbt.html">Prev</a> </td>
22          <th width="60%" align="center">Chapter 3. Database Records</th>
23          <td width="20%" align="right"> <a accesskey="n" href="DbUsage.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="cstructs"></a>Using C Structures with DB</h2>
33          </div>
34        </div>
35        <div></div>
36      </div>
37      <p>
38        Storing data in structures is a handy way to pack varied types of
39        information into each database record. DB databases are sometimes
40        thought of as a two column table where column 1 is the key and column 2 is
41        the data. By using structures, you can effectively turn this table into
42        <span class="emphasis"><em>n</em></span> columns where <span class="emphasis"><em>n-1</em></span> columns
43        are contained in the structure.
44    </p>
45      <p>
46       So long as a C structure contains fields that are not pointers, you can safely
47       store and retrieve them in the same way as you would any primitive
48       datatype.  The following code fragment illustrates this:
49    </p>
50      <a id="c_dbt6"></a>
51      <pre class="programlisting">#include &lt;db.h&gt;
52#include &lt;string.h&gt;
53
54typedef struct my_struct {
55    int id;
56    char familiar_name[MAXLINE]; /* Some suitably large value */
57    char surname[MAXLINE];
58} MY_STRUCT;
59
60...
61
62DBT key, data;
63DB *my_database;
64MY_STRUCT user;
65char *fname = "David";
66char *sname = "Rider";
67
68/* Database open omitted for clarity */
69
70user.id = 1;
71strncpy(user.familiar_name, fname, strlen(fname)+1);
72strncpy(user.surname, sname, strlen(sname)+1);
73
74/* Zero out the DBTs before using them. */
75memset(&amp;key, 0, sizeof(DBT));
76memset(&amp;data, 0, sizeof(DBT));
77
78key.data = &amp;(user.id);
79key.size = sizeof(int);
80
81data.data = &amp;user;
82data.size = sizeof(MY_STRUCT); 
83
84my_database-&gt;put(my_database, NULL, &amp;key, &amp;data, DB_NOOVERWRITE);</pre>
85      <p>
86        To retrieve the structure, make sure you supply your own
87        memory. The reason why is that like real numbers, some systems require
88        structures to be aligned in a specific way. Because it is possible that
89        the memory DB provides is not aligned properly, for safest result simply
90        use your own memory:
91    </p>
92      <a id="c_dbt7"></a>
93      <pre class="programlisting">#include &lt;db.h&gt;
94#include &lt;string.h&gt;
95
96...
97
98DBT key, data;
99DB *my_database;
100MY_STRUCT user;
101
102/* Database open omitted for clarity */
103
104/* Zero out the DBTs before using them. */
105memset(&amp;key, 0, sizeof(DBT));
106memset(&amp;data, 0, sizeof(DBT));
107
108/* Initialize the structure */
109memset(&amp;user, 0, sizeof(MY_STRUCT));
110user.id = 1;
111
112key.data = &amp;user.id;
113key.size = sizeof(int);
114
115/* Use our memory to retrieve the structure */
116data.data = &amp;user;
117data.ulen = sizeof(MY_STRUCT); 
118data.flags = DB_DBT_USERMEM;
119
120my_database-&gt;get(my_database, NULL, &amp;key, &amp;data, 0);
121
122printf("Familiar name: %s\n", user.familiar_name);
123printf("Surname: %s\n", user.surname); </pre>
124      <p>
125        Be aware that while this is the easiest way to manage structures stored
126        in DB databases, this approach does suffer from causing your
127        database to be larger than is strictly necessary. Each structure stored
128        in the database is of a fixed size, and you do not see any space savings
129        from storing a (for example) 5 character surname versus a 20 character
130        surname. 
131    </p>
132      <p>
133        For a simple example such as this, the padding stored with each record
134        is probably not critical. However, if you are storing structures that
135        contain a very large number of character arrays, or if you are simply
136        storing millions of records, then you may want to avoid this approach.
137        The wasted space in each record will only serve to make your databases
138        larger than need be, which will in turn require a larger cache and more
139        disk I/O than you would ordinarily need.
140    </p>
141      <p>
142        An alternative approach is described next.
143    </p>
144      <div class="sect2" lang="en" xml:lang="en">
145        <div class="titlepage">
146          <div>
147            <div>
148              <h3 class="title"><a id="cstructdynamic"></a>C Structures with Pointers</h3>
149            </div>
150          </div>
151          <div></div>
152        </div>
153        <p>
154        It is often necessary in C structures 
155            
156            
157            to use fields 
158            
159            
160        that are pointers to
161        dynamically allocated memory. This is particularly
162        true if you want to store character strings (or any kind of an array for
163        that matter), and you want to avoid any overhead caused by
164        pre-designating the size of the array. 
165    </p>
166        <p>
167       When storing structures 
168            
169       like these you need to make sure that all of
170       the data pointed to and contained by the structure 
171       
172            
173       is lined up in a
174       single contiguous block of memory.  Remember that DB stores data
175       located at a specific address and of a particular size. If your structure
176            
177       includes fields 
178            
179       that are pointing to dynamically allocated memory, then
180       the data that you want to store can be located in different, not
181       necessarily contiguous, locations on the heap. 
182    </p>
183        <p>
184        The easiest way to solve this problem is to pack your data
185        into a single memory location and then store the data in that location.
186        (This process is sometimes called <span class="emphasis"><em>marshalling the
187        data</em></span>.)
188        For example:
189    </p>
190        <a id="c_dbt8"></a>
191        <pre class="programlisting">#include &lt;db.h&gt;
192#include &lt;string.h&gt;
193#include &lt;stdlib.h&gt;
194
195typedef struct my_struct {
196    int id;
197    char *familiar_name;
198    char *surname;
199} MY_STRUCT;
200
201...
202
203DBT key, data;
204DB *my_database;
205MY_STRUCT user;
206int buffsize, bufflen;
207char fname[ ] = "Pete";
208char sname[10];
209char *databuff;
210
211strncpy(sname, "Oar", strlen("Oar")+1);
212
213/* Database open omitted for clarity */
214
215user.id = 1;
216user.familiar_name = fname;
217user.surname = sname;
218
219/* Some of the structure's data is on the stack, and 
220 * some is on the heap. To store this structure's data, we
221 * need to marshall it -- pack it all into a single location 
222 * in memory.
223 */
224
225/* Get the buffer */
226buffsize = sizeof(int) + 
227  (strlen(user.familiar_name) + strlen(user.surname) + 2);
228databuff = malloc(buffsize);
229memset(databuff, 0, buffsize);
230
231/* copy everything to the buffer */
232memcpy(databuff, &amp;(user.id), sizeof(int));
233bufflen = sizeof(int);
234
235memcpy(databuff + bufflen, user.familiar_name, 
236  strlen(user.familiar_name) + 1);
237bufflen += strlen(user.familiar_name) + 1;
238
239memcpy(databuff + bufflen, user.surname, 
240  strlen(user.surname) + 1);
241bufflen += strlen(user.surname) + 1;
242
243/* Now store it */
244
245/* Zero out the DBTs before using them. */
246memset(&amp;key, 0, sizeof(DBT));
247memset(&amp;data, 0, sizeof(DBT));
248
249key.data = &amp;(user.id);
250key.size = sizeof(int);
251
252data.data = databuff;
253data.size = bufflen;
254
255my_database-&gt;put(my_database, NULL, &amp;key, &amp;data, DB_NOOVERWRITE);
256free(sname);
257free(databuff);</pre>
258        <p>
259        To retrieve the stored structure:
260    </p>
261        <a id="c_dbt9"></a>
262        <pre class="programlisting">#include &lt;db.h&gt;
263#include &lt;string.h&gt;
264#include &lt;stdlib.h&gt;
265
266typedef struct my_struct {
267    char *familiar_name;
268    char *surname;
269    int id;
270} MY_STRUCT;
271
272...
273
274int id;
275DBT key, data;
276DB *my_database;
277MY_STRUCT user;
278char *buffer;
279
280/* Database open omitted for clarity */
281
282
283/* Zero out the DBTs before using them. */
284memset(&amp;key, 0, sizeof(DBT));
285memset(&amp;data, 0, sizeof(DBT));
286
287id = 1;
288key.data = &amp;id;
289key.size = sizeof(int);
290
291my_database-&gt;get(my_database, NULL, &amp;key, &amp;data, 0);
292
293/* 
294 * Some compilers won't allow pointer arithmetic on void *'s,
295 * so use a char * instead.
296 */
297buffer = data.data;
298
299user.id = *((int *)data.data);
300user.familiar_name = buffer + sizeof(int);
301user.surname = buffer + sizeof(int) + strlen(user.familiar_name) + 1; </pre>
302      </div>
303    </div>
304    <div class="navfooter">
305      <hr />
306      <table width="100%" summary="Navigation footer">
307        <tr>
308          <td width="40%" align="left"><a accesskey="p" href="usingDbt.html">Prev</a> </td>
309          <td width="20%" align="center">
310            <a accesskey="u" href="DBEntry.html">Up</a>
311          </td>
312          <td width="40%" align="right"> <a accesskey="n" href="DbUsage.html">Next</a></td>
313        </tr>
314        <tr>
315          <td width="40%" align="left" valign="top">Reading and Writing Database Records </td>
316          <td width="20%" align="center">
317            <a accesskey="h" href="index.html">Home</a>
318          </td>
319          <td width="40%" align="right" valign="top"> Database Usage Example</td>
320        </tr>
321      </table>
322    </div>
323  </body>
324</html>
325