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>Database 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="DB.html" title="Chapter 2. Databases" />
11    <link rel="previous" href="CoreEnvUsage.html" title="Managing Databases in Environments" />
12    <link rel="next" href="DBEntry.html" title="Chapter 3. Database Records" />
13  </head>
14  <body>
15    <div class="navheader">
16      <table width="100%" summary="Navigation header">
17        <tr>
18          <th colspan="3" align="center">Database Example</th>
19        </tr>
20        <tr>
21          <td width="20%" align="left"><a accesskey="p" href="CoreEnvUsage.html">Prev</a> </td>
22          <th width="60%" align="center">Chapter 2. Databases</th>
23          <td width="20%" align="right"> <a accesskey="n" href="DBEntry.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="CoreDbUsage"></a>Database Example</h2>
33          </div>
34        </div>
35        <div></div>
36      </div>
37      <p>
38        Throughout this book we will build a couple of applications that load
39        and retrieve inventory data from DB databases. While we are not yet ready to
40        begin reading from or writing to our databases, we can at least create
41        some important structures and functions that we will use to manage our
42        databases. 
43    </p>
44      <p>
45        Note that subsequent examples in this book will build on this code to
46        perform the more interesting work of writing to and reading from the
47        databases. 
48    </p>
49      <p>
50        Note that you can find the complete implementation of these functions
51        in:
52    </p>
53      <pre class="programlisting"><span class="emphasis"><em>DB_INSTALL</em></span>/examples_c/getting_started</pre>
54      <p>
55        where <tt class="literal"><span class="emphasis"><em>DB_INSTALL</em></span></tt> is the location where you
56        placed your DB distribution.  
57    </p>
58      <div class="example">
59        <a id="stock-db"></a>
60        <p class="title">
61          <b>Example 2.1 The stock_db Structure</b>
62        </p>
63        <p>
64            To begin, we create a structure that we will use to hold all our
65            database pointers and database names:
66        </p>
67        <a id="c_db11"></a>
68        <pre class="programlisting">/* File: gettingstarted_common.h */
69#include &lt;db.h&gt;
70
71typedef struct stock_dbs {
72    DB *inventory_dbp; /* Database containing inventory information */
73    DB *vendor_dbp;    /* Database containing vendor information */
74
75    char *db_home_dir;       /* Directory containing the database files */
76    char *inventory_db_name; /* Name of the inventory database */
77    char *vendor_db_name;    /* Name of the vendor database */
78} STOCK_DBS;
79
80/* Function prototypes */
81int databases_setup(STOCK_DBS *, const char *, FILE *);
82int databases_close(STOCK_DBS *);
83void initialize_stockdbs(STOCK_DBS *);
84int open_database(DB **, const char *, const char *,
85    FILE *);
86void set_db_filenames(STOCK_DBS *my_stock); </pre>
87      </div>
88      <div class="example">
89        <a id="stock-db-functions"></a>
90        <p class="title">
91          <b>Example 2.2 The stock_db Utility Functions</b>
92        </p>
93        <p>
94            Before continuing, we want some utility functions that we use to
95            make sure the stock_db structure is in a sane state before using it.
96            One is a simple function that initializes all the structure's
97            pointers to a useful default.The second is more interesting
98            in that it is used to place a
99            common path on all our database names so that we can explicitly
100            identify where all the database files should reside.
101        </p>
102        <a id="c_db12"></a>
103        <pre class="programlisting">/* File: gettingstarted_common.c */
104#include "gettingstarted_common.h"
105
106/* Initializes the STOCK_DBS struct.*/
107void
108initialize_stockdbs(STOCK_DBS *my_stock)
109{
110    my_stock-&gt;db_home_dir = DEFAULT_HOMEDIR;
111    my_stock-&gt;inventory_dbp = NULL;
112    my_stock-&gt;vendor_dbp = NULL;
113
114    my_stock-&gt;inventory_db_name = NULL;
115    my_stock-&gt;vendor_db_name = NULL;
116}
117
118/* Identify all the files that will hold our databases. */
119void
120set_db_filenames(STOCK_DBS *my_stock)
121{
122    size_t size;
123
124    /* Create the Inventory DB file name */
125    size = strlen(my_stock-&gt;db_home_dir) + strlen(INVENTORYDB) + 1;
126    my_stock-&gt;inventory_db_name = malloc(size);
127    snprintf(my_stock-&gt;inventory_db_name, size, "%s%s",
128      my_stock-&gt;db_home_dir, INVENTORYDB);
129
130    /* Create the Vendor DB file name */
131    size = strlen(my_stock-&gt;db_home_dir) + strlen(VENDORDB) + 1;
132    my_stock-&gt;vendor_db_name = malloc(size);
133    snprintf(my_stock-&gt;vendor_db_name, size, "%s%s",
134      my_stock-&gt;db_home_dir, VENDORDB);
135} </pre>
136      </div>
137      <div class="example">
138        <a id="open-db"></a>
139        <p class="title">
140          <b>Example 2.3 open_database() Function</b>
141        </p>
142        <p>
143			We are opening multiple databases, and we are
144			opening those databases using identical flags and error reporting
145			settings. It is therefore worthwhile to create a function that
146			performs this operation for us:
147		</p>
148        <a id="c_db13"></a>
149        <pre class="programlisting">/* File: gettingstarted_common.c */
150    
151/* Opens a database */
152int
153open_database(DB **dbpp,       /* The DB handle that we are opening */
154    const char *file_name,     /* The file in which the db lives */
155    const char *program_name,  /* Name of the program calling this 
156                                * function */
157    FILE *error_file_pointer)  /* File where we want error messages sent */
158{
159    DB *dbp;    /* For convenience */
160    u_int32_t open_flags;
161    int ret;
162
163    /* Initialize the DB handle */
164    ret = db_create(&amp;dbp, NULL, 0);
165    if (ret != 0) {
166        fprintf(error_file_pointer, "%s: %s\n", program_name,
167                db_strerror(ret));
168        return(ret);
169    }
170
171    /* Point to the memory malloc'd by db_create() */
172    *dbpp = dbp;
173                                                                                                                               
174    /* Set up error handling for this database */
175    dbp-&gt;set_errfile(dbp, error_file_pointer);
176    dbp-&gt;set_errpfx(dbp, program_name);
177
178    /* Set the open flags */
179    open_flags = DB_CREATE;
180
181    /* Now open the database */
182    ret = dbp-&gt;open(dbp,        /* Pointer to the database */
183                    NULL,       /* Txn pointer */
184                    file_name,  /* File name */
185                    NULL,       /* Logical db name (unneeded) */
186                    DB_BTREE,   /* Database type (using btree) */
187                    open_flags, /* Open flags */
188                    0);         /* File mode. Using defaults */
189    if (ret != 0) {
190        dbp-&gt;err(dbp, ret, "Database '%s' open failed.", file_name);
191        return(ret);
192    }
193                                                                                                                               
194    return (0);
195}</pre>
196      </div>
197      <div class="example">
198        <a id="databasesetup"></a>
199        <p class="title">
200          <b>Example 2.4 The databases_setup() Function</b>
201        </p>
202        <p>
203            Now that we have our <tt class="function">open_database()</tt> function,
204            we can use it to open a database. We now create a simple function
205            that will open all our databases for us.
206        </p>
207        <a id="c_db14"></a>
208        <pre class="programlisting">/* opens all databases */
209int
210databases_setup(STOCK_DBS *my_stock, const char *program_name,
211  FILE *error_file_pointer)
212{
213    int ret;
214
215    /* Open the vendor database */
216    ret = open_database(&amp;(my_stock-&gt;vendor_dbp),
217      my_stock-&gt;vendor_db_name,
218      program_name, error_file_pointer);
219    if (ret != 0)
220        /*
221         * Error reporting is handled in open_database() so just return
222         * the return code here.
223         */
224        return (ret);
225
226    /* Open the inventory database */
227    ret = open_database(&amp;(my_stock-&gt;inventory_dbp),
228      my_stock-&gt;inventory_db_name,
229      program_name, error_file_pointer);
230    if (ret != 0)
231        /*
232         * Error reporting is handled in open_database() so just return
233         * the return code here.
234         */
235        return (ret);
236
237    printf("databases opened successfully\n");
238    return (0);
239}</pre>
240      </div>
241      <div class="example">
242        <a id="database_close"></a>
243        <p class="title">
244          <b>Example 2.5 The databases_close() Function</b>
245        </p>
246        <p>
247            Finally, it is useful to have a function that can close all our databases for us:
248        </p>
249        <a id="c_db15"></a>
250        <pre class="programlisting">/* Closes all the databases. */
251int
252databases_close(STOCK_DBS *my_stock)
253{
254    int ret;
255    /*
256     * Note that closing a database automatically flushes its cached data
257     * to disk, so no sync is required here.
258     */
259
260    if (my_stock-&gt;inventory_dbp != NULL) {
261        ret = my_stock-&gt;inventory_dbp-&gt;close(my_stock-&gt;inventory_dbp, 0);
262        if (ret != 0)
263            fprintf(stderr, "Inventory database close failed: %s\n",
264              db_strerror(ret));
265    }
266
267    if (my_stock-&gt;vendor_dbp != NULL) {
268        ret = my_stock-&gt;vendor_dbp-&gt;close(my_stock-&gt;vendor_dbp, 0);
269        if (ret != 0)
270            fprintf(stderr, "Vendor database close failed: %s\n",
271              db_strerror(ret));
272    }
273
274    printf("databases closed.\n");
275    return (0);
276} </pre>
277      </div>
278    </div>
279    <div class="navfooter">
280      <hr />
281      <table width="100%" summary="Navigation footer">
282        <tr>
283          <td width="40%" align="left"><a accesskey="p" href="CoreEnvUsage.html">Prev</a> </td>
284          <td width="20%" align="center">
285            <a accesskey="u" href="DB.html">Up</a>
286          </td>
287          <td width="40%" align="right"> <a accesskey="n" href="DBEntry.html">Next</a></td>
288        </tr>
289        <tr>
290          <td width="40%" align="left" valign="top">Managing Databases in Environments </td>
291          <td width="20%" align="center">
292            <a accesskey="h" href="index.html">Home</a>
293          </td>
294          <td width="40%" align="right" valign="top"> Chapter 3. Database Records</td>
295        </tr>
296      </table>
297    </div>
298  </body>
299</html>
300