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 <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 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->db_home_dir = DEFAULT_HOMEDIR; 111 my_stock->inventory_dbp = NULL; 112 my_stock->vendor_dbp = NULL; 113 114 my_stock->inventory_db_name = NULL; 115 my_stock->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->db_home_dir) + strlen(INVENTORYDB) + 1; 126 my_stock->inventory_db_name = malloc(size); 127 snprintf(my_stock->inventory_db_name, size, "%s%s", 128 my_stock->db_home_dir, INVENTORYDB); 129 130 /* Create the Vendor DB file name */ 131 size = strlen(my_stock->db_home_dir) + strlen(VENDORDB) + 1; 132 my_stock->vendor_db_name = malloc(size); 133 snprintf(my_stock->vendor_db_name, size, "%s%s", 134 my_stock->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(&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->set_errfile(dbp, error_file_pointer); 176 dbp->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->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->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(&(my_stock->vendor_dbp), 217 my_stock->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(&(my_stock->inventory_dbp), 228 my_stock->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->inventory_dbp != NULL) { 261 ret = my_stock->inventory_dbp->close(my_stock->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->vendor_dbp != NULL) { 268 ret = my_stock->vendor_dbp->close(my_stock->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