Import BSDDB 4.7.25 (as of svn r89086)
This commit is contained in:
397
docs/gsg/C/usingDbt.html
Normal file
397
docs/gsg/C/usingDbt.html
Normal file
@@ -0,0 +1,397 @@
|
||||
<?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>Reading and Writing Database Records</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="DBEntry.html" title="Chapter 3. Database Records" />
|
||||
<link rel="previous" href="DBEntry.html" title="Chapter 3. Database Records" />
|
||||
<link rel="next" href="cstructs.html" title="Using C Structures with DB" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="navheader">
|
||||
<table width="100%" summary="Navigation header">
|
||||
<tr>
|
||||
<th colspan="3" align="center">Reading and Writing Database Records</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="20%" align="left"><a accesskey="p" href="DBEntry.html">Prev</a> </td>
|
||||
<th width="60%" align="center">Chapter 3. Database Records</th>
|
||||
<td width="20%" align="right"> <a accesskey="n" href="cstructs.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="usingDbt"></a>Reading and Writing Database Records</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div></div>
|
||||
</div>
|
||||
<p>
|
||||
When reading and writing database records, be aware that there are some
|
||||
slight differences in behavior depending on whether your database supports duplicate
|
||||
records. Two or more database records are considered to be duplicates of
|
||||
one another if they share the same key. The collection of records
|
||||
sharing the same key are called a <span class="emphasis"><em>duplicates set.</em></span>
|
||||
|
||||
<span>
|
||||
In DB, a given key is stored only once for a single duplicates set.
|
||||
</span>
|
||||
</p>
|
||||
<p>
|
||||
By default, DB databases do
|
||||
not support duplicate records. Where duplicate records are supported,
|
||||
cursors (see below) are <span>typically</span> used
|
||||
to access all of the records in the duplicates set.
|
||||
</p>
|
||||
<p>
|
||||
DB provides two basic mechanisms for the storage and retrieval of database
|
||||
key/data pairs:
|
||||
</p>
|
||||
<div class="itemizedlist">
|
||||
<ul type="disc">
|
||||
<li>
|
||||
<p>
|
||||
The
|
||||
|
||||
<tt class="methodname">DBT->put()</tt>
|
||||
|
||||
and
|
||||
|
||||
<tt class="methodname">DBT->get()</tt>
|
||||
|
||||
methods provide the easiest access for all non-duplicate records in the database.
|
||||
These methods are described in this section.
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Cursors provide several methods for putting and getting database
|
||||
records. Cursors and their database access methods are described in
|
||||
<a href="Cursors.html">Using Cursors</a>.</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="sect2" lang="en" xml:lang="en">
|
||||
<div class="titlepage">
|
||||
<div>
|
||||
<div>
|
||||
<h3 class="title"><a id="databaseWrite"></a>Writing Records to the Database</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div></div>
|
||||
</div>
|
||||
<p>
|
||||
Records are stored in the database using whatever organization is
|
||||
required by the access method that you have selected. In some cases (such as
|
||||
BTree), records are stored in a sort order that you may want to define
|
||||
(see <a href="btree.html#comparators">Setting Comparison Functions</a> for more information).
|
||||
</p>
|
||||
<p>
|
||||
In any case, the mechanics of putting and getting database records do not
|
||||
change once you have selected your access method, configured your
|
||||
sorting routines (if any), and opened your database. From your
|
||||
code's perspective, a simple database put and get is largely the
|
||||
same no matter what access method you are using.
|
||||
</p>
|
||||
<p>
|
||||
You use
|
||||
<tt class="methodname">DB->put()</tt>
|
||||
|
||||
to put, or write, a database record. This method requires you to provide
|
||||
the record's key and data in the form of a pair of
|
||||
<span><tt class="methodname">DBT</tt> structures.</span>
|
||||
|
||||
You can also provide one or more flags that control DB's behavior
|
||||
for the database write.
|
||||
</p>
|
||||
<p>
|
||||
Of the flags available to this method, <tt class="literal">DB_NOOVERWRITE</tt>
|
||||
may be interesting to you. This flag disallows overwriting (replacing)
|
||||
an existing record in the database. If the provided key already exists
|
||||
in the database, then this method returns <tt class="literal">DB_KEYEXIST</tt> even if
|
||||
the database supports duplicates.
|
||||
</p>
|
||||
<p>
|
||||
For example:
|
||||
</p>
|
||||
<a id="c_dbt3"></a>
|
||||
<pre class="programlisting">#include <db.h>
|
||||
#include <string.h>
|
||||
|
||||
...
|
||||
|
||||
char *description = "Grocery bill.";
|
||||
DBT key, data;
|
||||
DB *my_database;
|
||||
int ret;
|
||||
float money;
|
||||
|
||||
/* Database open omitted for clarity */
|
||||
|
||||
money = 122.45;
|
||||
|
||||
/* Zero out the DBTs before using them. */
|
||||
memset(&key, 0, sizeof(DBT));
|
||||
memset(&data, 0, sizeof(DBT));
|
||||
|
||||
key.data = &money;
|
||||
key.size = sizeof(float);
|
||||
|
||||
data.data = description;
|
||||
data.size = strlen(description) +1;
|
||||
|
||||
ret = my_database->put(my_database, NULL, &key, &data, DB_NOOVERWRITE);
|
||||
if (ret == DB_KEYEXIST) {
|
||||
my_database->err(my_database, ret,
|
||||
"Put failed because key %f already exists", money);
|
||||
}</pre>
|
||||
</div>
|
||||
<div class="sect2" lang="en" xml:lang="en">
|
||||
<div class="titlepage">
|
||||
<div>
|
||||
<div>
|
||||
<h3 class="title"><a id="CoreDatabaseRead"></a>Getting Records from the Database</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div></div>
|
||||
</div>
|
||||
<p>
|
||||
You can use the
|
||||
<tt class="methodname">DB->get()</tt>
|
||||
|
||||
method to retrieve database records. Note that if your
|
||||
database supports duplicate records, then by default this method will only
|
||||
return the first record in a duplicate set. For this reason, if your
|
||||
database supports duplicates, the common solution is to use a cursor to retrieve
|
||||
records from it. Cursors are described in <a href="Cursors.html">Using Cursors</a>.
|
||||
</p>
|
||||
<p>
|
||||
(You can also retrieve a set of duplicate records using a bulk get.
|
||||
To do this, you use the <tt class="literal">DB_MULTIPLE</tt> flag on the
|
||||
call to
|
||||
<span><tt class="methodname">DB->get()</tt>.</span>
|
||||
|
||||
|
||||
For more information, see the DB Programmer's Reference Guide).
|
||||
</p>
|
||||
<p>
|
||||
By default,
|
||||
<tt class="methodname">DB->get()</tt>
|
||||
|
||||
returns the first record found whose key matches the key
|
||||
provide on the call to this method. If your database supports
|
||||
duplicate records, you can change this behavior slightly by supplying
|
||||
the <tt class="literal">DB_GET_BOTH</tt> flag. This flag causes
|
||||
<tt class="methodname">DB->get()</tt>
|
||||
|
||||
to return the first record that matches the provided key and data.
|
||||
</p>
|
||||
<p>
|
||||
If the specified key and/or data does not exist in the database, this
|
||||
method returns <tt class="literal">DB_NOTFOUND</tt>.
|
||||
</p>
|
||||
<a id="c_dbt4"></a>
|
||||
<pre class="programlisting">#include <db.h>
|
||||
#include <string.h>
|
||||
|
||||
...
|
||||
|
||||
DBT key, data;
|
||||
DB *my_database;
|
||||
float money;
|
||||
char description[DESCRIPTION_SIZE + 1];
|
||||
|
||||
/* Database open omitted for clarity */
|
||||
|
||||
money = 122.45;
|
||||
|
||||
/* Zero out the DBTs before using them. */
|
||||
memset(&key, 0, sizeof(DBT));
|
||||
memset(&data, 0, sizeof(DBT));
|
||||
|
||||
key.data = &money;
|
||||
key.size = sizeof(float);
|
||||
|
||||
data.data = description;
|
||||
data.ulen = DESCRIPTION_SIZE + 1;
|
||||
data.flags = DB_DBT_USERMEM;
|
||||
my_database->get(my_database, NULL, &key, &data, 0);
|
||||
|
||||
/*
|
||||
* Description is set into the memory that we supplied.
|
||||
*/ </pre>
|
||||
<p>
|
||||
Note that in this example, the
|
||||
<tt class="literal">data.size</tt>
|
||||
field would be automatically set to the size of the retrieved data.
|
||||
</p>
|
||||
</div>
|
||||
<div class="sect2" lang="en" xml:lang="en">
|
||||
<div class="titlepage">
|
||||
<div>
|
||||
<div>
|
||||
<h3 class="title"><a id="recordDelete"></a>Deleting Records</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div></div>
|
||||
</div>
|
||||
<p>
|
||||
|
||||
You can use the
|
||||
|
||||
<tt class="methodname">DB->del()</tt>
|
||||
|
||||
method to delete a record from the database. If your database supports
|
||||
duplicate records, then all records associated with the provided key are
|
||||
deleted. To delete just one record from a list of duplicates, use a
|
||||
cursor. Cursors are described in <a href="Cursors.html">Using Cursors</a>.
|
||||
|
||||
</p>
|
||||
<p>
|
||||
You can also delete every record in the database by using
|
||||
|
||||
<tt class="methodname">DB->truncate().</tt>
|
||||
|
||||
</p>
|
||||
<p>For example:</p>
|
||||
<a id="c_dbt5"></a>
|
||||
<pre class="programlisting">#include <db.h>
|
||||
#include <string.h>
|
||||
|
||||
...
|
||||
|
||||
DBT key;
|
||||
DB *my_database;
|
||||
float money = 122.45;
|
||||
|
||||
/* Database open omitted for clarity */
|
||||
|
||||
/* Zero out the DBTs before using them. */
|
||||
memset(&key, 0, sizeof(DBT));
|
||||
|
||||
key.data = &money;
|
||||
key.size = sizeof(float);
|
||||
|
||||
my_database->del(my_database, NULL, &key, 0);</pre>
|
||||
</div>
|
||||
<div class="sect2" lang="en" xml:lang="en">
|
||||
<div class="titlepage">
|
||||
<div>
|
||||
<div>
|
||||
<h3 class="title"><a id="datapersist"></a>Data Persistence</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div></div>
|
||||
</div>
|
||||
<p>
|
||||
When you perform a database modification, your modification is made
|
||||
in the in-memory cache. This means that your data modifications
|
||||
are not necessarily flushed to disk, and so your data may not appear
|
||||
in the database after an application restart.
|
||||
</p>
|
||||
<p>
|
||||
Note that as a normal part of closing a database, its cache is
|
||||
written to disk. However, in the event of an application or system
|
||||
failure, there is no guarantee that your databases will close
|
||||
cleanly. In this event, it is possible for you to lose data. Under
|
||||
extremely rare circumstances, it is also possible for you to
|
||||
experience database corruption.
|
||||
</p>
|
||||
<p>
|
||||
Therefore, if you care if your data is durable across system
|
||||
failures, and to guard against the rare possibility of
|
||||
database corruption, you should use transactions to protect your
|
||||
database modifications. Every time you commit a transaction, DB
|
||||
ensures that the data will not be lost due to application or
|
||||
system failure. Transaction usage is described in the
|
||||
|
||||
|
||||
|
||||
|
||||
<span>
|
||||
<i class="citetitle">Berkeley DB Getting Started with Transaction Processing</i> guide.
|
||||
</span>
|
||||
</p>
|
||||
<p>
|
||||
If you do not want to use transactions, then the assumption is that
|
||||
your data is of a nature that it need not exist the next time your
|
||||
application starts. You may want this if, for example, you are using
|
||||
DB to cache data relevant only to the current application
|
||||
runtime.
|
||||
</p>
|
||||
<p>
|
||||
If, however, you are not using transactions for some reason and you
|
||||
still want some guarantee that your database modifications are
|
||||
persistent, then you should periodically
|
||||
|
||||
<span>call <tt class="methodname">DB->sync()</tt>.</span>
|
||||
|
||||
Syncs cause any dirty entries in the in-memory cache and the
|
||||
operating system's file cache to be written to disk. As
|
||||
such, they are quite expensive and you should use them sparingly.
|
||||
</p>
|
||||
<p>
|
||||
Remember that by default a sync is performed any time a non-transactional
|
||||
database is closed cleanly. (You can override this behavior by
|
||||
specifying
|
||||
<tt class="literal">DB_NOSYNC</tt>
|
||||
|
||||
on the call to
|
||||
<span><tt class="methodname">DB->close()</tt>.)</span>
|
||||
|
||||
|
||||
|
||||
That said, you can manually run a sync by calling
|
||||
|
||||
<tt class="methodname">DB->sync().</tt>
|
||||
|
||||
|
||||
|
||||
</p>
|
||||
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
|
||||
<h3 class="title">Note</h3>
|
||||
<p>
|
||||
If your application or system crashes and you are not using
|
||||
transactions, then you should either discard and recreate your
|
||||
databases, or verify them. You can verify a database using
|
||||
<span>DB->verify().</span>
|
||||
|
||||
|
||||
If your databases do not verify cleanly, use the
|
||||
<span><b class="command">db_dump</b></span> command to salvage as much of the
|
||||
database as is possible. Use either the <tt class="literal">-R</tt> or
|
||||
<tt class="literal">-r</tt> command line options to control how
|
||||
aggressive <span><b class="command">db_dump</b></span> should be when salvaging
|
||||
your databases.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="navfooter">
|
||||
<hr />
|
||||
<table width="100%" summary="Navigation footer">
|
||||
<tr>
|
||||
<td width="40%" align="left"><a accesskey="p" href="DBEntry.html">Prev</a> </td>
|
||||
<td width="20%" align="center">
|
||||
<a accesskey="u" href="DBEntry.html">Up</a>
|
||||
</td>
|
||||
<td width="40%" align="right"> <a accesskey="n" href="cstructs.html">Next</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="40%" align="left" valign="top">Chapter 3. Database Records </td>
|
||||
<td width="20%" align="center">
|
||||
<a accesskey="h" href="index.html">Home</a>
|
||||
</td>
|
||||
<td width="40%" align="right" valign="top"> Using C Structures with DB</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user