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