300 lines
11 KiB
HTML
300 lines
11 KiB
HTML
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||
<head>
|
||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||
<title>Database Example</title>
|
||
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
|
||
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
|
||
<link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
|
||
<link rel="up" href="DB.html" title="Chapter 2. Databases" />
|
||
<link rel="previous" href="CoreEnvUsage.html" title="Managing Databases in Environments" />
|
||
<link rel="next" href="DBEntry.html" title="Chapter 3. Database Records" />
|
||
</head>
|
||
<body>
|
||
<div class="navheader">
|
||
<table width="100%" summary="Navigation header">
|
||
<tr>
|
||
<th colspan="3" align="center">Database Example</th>
|
||
</tr>
|
||
<tr>
|
||
<td width="20%" align="left"><a accesskey="p" href="CoreEnvUsage.html">Prev</a> </td>
|
||
<th width="60%" align="center">Chapter 2. Databases</th>
|
||
<td width="20%" align="right"> <a accesskey="n" href="DBEntry.html">Next</a></td>
|
||
</tr>
|
||
</table>
|
||
<hr />
|
||
</div>
|
||
<div class="sect1" lang="en" xml:lang="en">
|
||
<div class="titlepage">
|
||
<div>
|
||
<div>
|
||
<h2 class="title" style="clear: both"><a id="CoreDbUsage"></a>Database Example</h2>
|
||
</div>
|
||
</div>
|
||
<div></div>
|
||
</div>
|
||
<p>
|
||
Throughout this book we will build a couple of applications that load
|
||
and retrieve inventory data from DB databases. While we are not yet ready to
|
||
begin reading from or writing to our databases, we can at least create
|
||
some important structures and functions that we will use to manage our
|
||
databases.
|
||
</p>
|
||
<p>
|
||
Note that subsequent examples in this book will build on this code to
|
||
perform the more interesting work of writing to and reading from the
|
||
databases.
|
||
</p>
|
||
<p>
|
||
Note that you can find the complete implementation of these functions
|
||
in:
|
||
</p>
|
||
<pre class="programlisting"><span class="emphasis"><em>DB_INSTALL</em></span>/examples_c/getting_started</pre>
|
||
<p>
|
||
where <tt class="literal"><span class="emphasis"><em>DB_INSTALL</em></span></tt> is the location where you
|
||
placed your DB distribution.
|
||
</p>
|
||
<div class="example">
|
||
<a id="stock-db"></a>
|
||
<p class="title">
|
||
<b>Example 2.1 The stock_db Structure</b>
|
||
</p>
|
||
<p>
|
||
To begin, we create a structure that we will use to hold all our
|
||
database pointers and database names:
|
||
</p>
|
||
<a id="c_db11"></a>
|
||
<pre class="programlisting">/* File: gettingstarted_common.h */
|
||
#include <db.h>
|
||
|
||
typedef struct stock_dbs {
|
||
DB *inventory_dbp; /* Database containing inventory information */
|
||
DB *vendor_dbp; /* Database containing vendor information */
|
||
|
||
char *db_home_dir; /* Directory containing the database files */
|
||
char *inventory_db_name; /* Name of the inventory database */
|
||
char *vendor_db_name; /* Name of the vendor database */
|
||
} STOCK_DBS;
|
||
|
||
/* Function prototypes */
|
||
int databases_setup(STOCK_DBS *, const char *, FILE *);
|
||
int databases_close(STOCK_DBS *);
|
||
void initialize_stockdbs(STOCK_DBS *);
|
||
int open_database(DB **, const char *, const char *,
|
||
FILE *);
|
||
void set_db_filenames(STOCK_DBS *my_stock); </pre>
|
||
</div>
|
||
<div class="example">
|
||
<a id="stock-db-functions"></a>
|
||
<p class="title">
|
||
<b>Example 2.2 The stock_db Utility Functions</b>
|
||
</p>
|
||
<p>
|
||
Before continuing, we want some utility functions that we use to
|
||
make sure the stock_db structure is in a sane state before using it.
|
||
One is a simple function that initializes all the structure's
|
||
pointers to a useful default.The second is more interesting
|
||
in that it is used to place a
|
||
common path on all our database names so that we can explicitly
|
||
identify where all the database files should reside.
|
||
</p>
|
||
<a id="c_db12"></a>
|
||
<pre class="programlisting">/* File: gettingstarted_common.c */
|
||
#include "gettingstarted_common.h"
|
||
|
||
/* Initializes the STOCK_DBS struct.*/
|
||
void
|
||
initialize_stockdbs(STOCK_DBS *my_stock)
|
||
{
|
||
my_stock->db_home_dir = DEFAULT_HOMEDIR;
|
||
my_stock->inventory_dbp = NULL;
|
||
my_stock->vendor_dbp = NULL;
|
||
|
||
my_stock->inventory_db_name = NULL;
|
||
my_stock->vendor_db_name = NULL;
|
||
}
|
||
|
||
/* Identify all the files that will hold our databases. */
|
||
void
|
||
set_db_filenames(STOCK_DBS *my_stock)
|
||
{
|
||
size_t size;
|
||
|
||
/* Create the Inventory DB file name */
|
||
size = strlen(my_stock->db_home_dir) + strlen(INVENTORYDB) + 1;
|
||
my_stock->inventory_db_name = malloc(size);
|
||
snprintf(my_stock->inventory_db_name, size, "%s%s",
|
||
my_stock->db_home_dir, INVENTORYDB);
|
||
|
||
/* Create the Vendor DB file name */
|
||
size = strlen(my_stock->db_home_dir) + strlen(VENDORDB) + 1;
|
||
my_stock->vendor_db_name = malloc(size);
|
||
snprintf(my_stock->vendor_db_name, size, "%s%s",
|
||
my_stock->db_home_dir, VENDORDB);
|
||
} </pre>
|
||
</div>
|
||
<div class="example">
|
||
<a id="open-db"></a>
|
||
<p class="title">
|
||
<b>Example 2.3 open_database() Function</b>
|
||
</p>
|
||
<p>
|
||
We are opening multiple databases, and we are
|
||
opening those databases using identical flags and error reporting
|
||
settings. It is therefore worthwhile to create a function that
|
||
performs this operation for us:
|
||
</p>
|
||
<a id="c_db13"></a>
|
||
<pre class="programlisting">/* File: gettingstarted_common.c */
|
||
|
||
/* Opens a database */
|
||
int
|
||
open_database(DB **dbpp, /* The DB handle that we are opening */
|
||
const char *file_name, /* The file in which the db lives */
|
||
const char *program_name, /* Name of the program calling this
|
||
* function */
|
||
FILE *error_file_pointer) /* File where we want error messages sent */
|
||
{
|
||
DB *dbp; /* For convenience */
|
||
u_int32_t open_flags;
|
||
int ret;
|
||
|
||
/* Initialize the DB handle */
|
||
ret = db_create(&dbp, NULL, 0);
|
||
if (ret != 0) {
|
||
fprintf(error_file_pointer, "%s: %s\n", program_name,
|
||
db_strerror(ret));
|
||
return(ret);
|
||
}
|
||
|
||
/* Point to the memory malloc'd by db_create() */
|
||
*dbpp = dbp;
|
||
|
||
/* Set up error handling for this database */
|
||
dbp->set_errfile(dbp, error_file_pointer);
|
||
dbp->set_errpfx(dbp, program_name);
|
||
|
||
/* Set the open flags */
|
||
open_flags = DB_CREATE;
|
||
|
||
/* Now open the database */
|
||
ret = dbp->open(dbp, /* Pointer to the database */
|
||
NULL, /* Txn pointer */
|
||
file_name, /* File name */
|
||
NULL, /* Logical db name (unneeded) */
|
||
DB_BTREE, /* Database type (using btree) */
|
||
open_flags, /* Open flags */
|
||
0); /* File mode. Using defaults */
|
||
if (ret != 0) {
|
||
dbp->err(dbp, ret, "Database '%s' open failed.", file_name);
|
||
return(ret);
|
||
}
|
||
|
||
return (0);
|
||
}</pre>
|
||
</div>
|
||
<div class="example">
|
||
<a id="databasesetup"></a>
|
||
<p class="title">
|
||
<b>Example 2.4 The databases_setup() Function</b>
|
||
</p>
|
||
<p>
|
||
Now that we have our <tt class="function">open_database()</tt> function,
|
||
we can use it to open a database. We now create a simple function
|
||
that will open all our databases for us.
|
||
</p>
|
||
<a id="c_db14"></a>
|
||
<pre class="programlisting">/* opens all databases */
|
||
int
|
||
databases_setup(STOCK_DBS *my_stock, const char *program_name,
|
||
FILE *error_file_pointer)
|
||
{
|
||
int ret;
|
||
|
||
/* Open the vendor database */
|
||
ret = open_database(&(my_stock->vendor_dbp),
|
||
my_stock->vendor_db_name,
|
||
program_name, error_file_pointer);
|
||
if (ret != 0)
|
||
/*
|
||
* Error reporting is handled in open_database() so just return
|
||
* the return code here.
|
||
*/
|
||
return (ret);
|
||
|
||
/* Open the inventory database */
|
||
ret = open_database(&(my_stock->inventory_dbp),
|
||
my_stock->inventory_db_name,
|
||
program_name, error_file_pointer);
|
||
if (ret != 0)
|
||
/*
|
||
* Error reporting is handled in open_database() so just return
|
||
* the return code here.
|
||
*/
|
||
return (ret);
|
||
|
||
printf("databases opened successfully\n");
|
||
return (0);
|
||
}</pre>
|
||
</div>
|
||
<div class="example">
|
||
<a id="database_close"></a>
|
||
<p class="title">
|
||
<b>Example 2.5 The databases_close() Function</b>
|
||
</p>
|
||
<p>
|
||
Finally, it is useful to have a function that can close all our databases for us:
|
||
</p>
|
||
<a id="c_db15"></a>
|
||
<pre class="programlisting">/* Closes all the databases. */
|
||
int
|
||
databases_close(STOCK_DBS *my_stock)
|
||
{
|
||
int ret;
|
||
/*
|
||
* Note that closing a database automatically flushes its cached data
|
||
* to disk, so no sync is required here.
|
||
*/
|
||
|
||
if (my_stock->inventory_dbp != NULL) {
|
||
ret = my_stock->inventory_dbp->close(my_stock->inventory_dbp, 0);
|
||
if (ret != 0)
|
||
fprintf(stderr, "Inventory database close failed: %s\n",
|
||
db_strerror(ret));
|
||
}
|
||
|
||
if (my_stock->vendor_dbp != NULL) {
|
||
ret = my_stock->vendor_dbp->close(my_stock->vendor_dbp, 0);
|
||
if (ret != 0)
|
||
fprintf(stderr, "Vendor database close failed: %s\n",
|
||
db_strerror(ret));
|
||
}
|
||
|
||
printf("databases closed.\n");
|
||
return (0);
|
||
} </pre>
|
||
</div>
|
||
</div>
|
||
<div class="navfooter">
|
||
<hr />
|
||
<table width="100%" summary="Navigation footer">
|
||
<tr>
|
||
<td width="40%" align="left"><a accesskey="p" href="CoreEnvUsage.html">Prev</a> </td>
|
||
<td width="20%" align="center">
|
||
<a accesskey="u" href="DB.html">Up</a>
|
||
</td>
|
||
<td width="40%" align="right"> <a accesskey="n" href="DBEntry.html">Next</a></td>
|
||
</tr>
|
||
<tr>
|
||
<td width="40%" align="left" valign="top">Managing Databases in Environments </td>
|
||
<td width="20%" align="center">
|
||
<a accesskey="h" href="index.html">Home</a>
|
||
</td>
|
||
<td width="40%" align="right" valign="top"> Chapter 3. Database Records</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
</body>
|
||
</html>
|