mirror of
https://github.com/MariaDB/server.git
synced 2025-01-18 21:12:26 +01:00
248 lines
4.7 KiB
C++
248 lines
4.7 KiB
C++
|
/*-
|
||
|
* See the file LICENSE for redistribution information.
|
||
|
*
|
||
|
* Copyright (c) 1997, 1998, 1999, 2000
|
||
|
* Sleepycat Software. All rights reserved.
|
||
|
*
|
||
|
* $Id: BtRecExample.cpp,v 11.6 2000/02/19 20:57:59 bostic Exp $
|
||
|
*/
|
||
|
|
||
|
#include "db_config.h"
|
||
|
|
||
|
#ifndef NO_SYSTEM_INCLUDES
|
||
|
#include <sys/types.h>
|
||
|
#include <errno.h>
|
||
|
#include <iostream.h>
|
||
|
#include <stddef.h>
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
#include <unistd.h>
|
||
|
#endif
|
||
|
|
||
|
#include <iomanip.h>
|
||
|
#include <db_cxx.h>
|
||
|
|
||
|
#define DATABASE "access.db"
|
||
|
#define WORDLIST "../test/wordlist"
|
||
|
|
||
|
void usage();
|
||
|
extern "C" int getopt(int, char * const *, const char *);
|
||
|
|
||
|
char *progname = "BtRecExample"; // Program name.
|
||
|
|
||
|
class BtRecExample
|
||
|
{
|
||
|
public:
|
||
|
BtRecExample(FILE *fp);
|
||
|
~BtRecExample();
|
||
|
void run();
|
||
|
void stats();
|
||
|
void show(char *msg, Dbt *key, Dbt *data);
|
||
|
|
||
|
private:
|
||
|
Db *dbp;
|
||
|
Dbc *dbcp;
|
||
|
};
|
||
|
|
||
|
BtRecExample::BtRecExample(FILE *fp)
|
||
|
{
|
||
|
char *p, *t, buf[1024], rbuf[1024];
|
||
|
int ret;
|
||
|
|
||
|
// Remove the previous database.
|
||
|
(void)unlink(DATABASE);
|
||
|
|
||
|
dbp = new Db(NULL, 0);
|
||
|
|
||
|
dbp->set_error_stream(&cerr);
|
||
|
dbp->set_errpfx(progname);
|
||
|
dbp->set_pagesize(1024); // 1K page sizes.
|
||
|
|
||
|
dbp->set_flags(DB_RECNUM); // Record numbers.
|
||
|
dbp->open(DATABASE, NULL, DB_BTREE, DB_CREATE, 0664);
|
||
|
|
||
|
//
|
||
|
// Insert records into the database, where the key is the word
|
||
|
// preceded by its record number, and the data is the same, but
|
||
|
// in reverse order.
|
||
|
//
|
||
|
|
||
|
for (int cnt = 1; cnt <= 1000; ++cnt) {
|
||
|
(void)sprintf(buf, "%04d_", cnt);
|
||
|
if (fgets(buf + 4, sizeof(buf) - 4, fp) == NULL)
|
||
|
break;
|
||
|
u_int32_t len = strlen(buf);
|
||
|
buf[len - 1] = '\0';
|
||
|
for (t = rbuf, p = buf + (len - 2); p >= buf;)
|
||
|
*t++ = *p--;
|
||
|
*t++ = '\0';
|
||
|
|
||
|
// As a convenience for printing, we include the null terminator
|
||
|
// in the stored data.
|
||
|
//
|
||
|
Dbt key(buf, len);
|
||
|
Dbt data(rbuf, len);
|
||
|
|
||
|
if ((ret = dbp->put(NULL, &key, &data, DB_NOOVERWRITE)) != 0) {
|
||
|
dbp->err(ret, "Db::put");
|
||
|
if (ret != DB_KEYEXIST)
|
||
|
throw DbException(ret);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
BtRecExample::~BtRecExample()
|
||
|
{
|
||
|
if (dbcp != 0)
|
||
|
dbcp->close();
|
||
|
dbp->close(0);
|
||
|
delete dbp;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Print out the number of records in the database.
|
||
|
//
|
||
|
void BtRecExample::stats()
|
||
|
{
|
||
|
DB_BTREE_STAT *statp;
|
||
|
|
||
|
dbp->stat(&statp, NULL, 0);
|
||
|
cout << progname << ": database contains "
|
||
|
<< (u_long)statp->bt_ndata << " records\n";
|
||
|
|
||
|
// Note: must use free, not delete.
|
||
|
// This struct is allocated by C.
|
||
|
//
|
||
|
free(statp);
|
||
|
}
|
||
|
|
||
|
void BtRecExample::run()
|
||
|
{
|
||
|
db_recno_t recno;
|
||
|
int ret;
|
||
|
char buf[1024];
|
||
|
|
||
|
// Acquire a cursor for the database.
|
||
|
dbp->cursor(NULL, &dbcp, 0);
|
||
|
|
||
|
//
|
||
|
// Prompt the user for a record number, then retrieve and display
|
||
|
// that record.
|
||
|
//
|
||
|
for (;;) {
|
||
|
// Get a record number.
|
||
|
cout << "recno #> ";
|
||
|
cout.flush();
|
||
|
if (fgets(buf, sizeof(buf), stdin) == NULL)
|
||
|
break;
|
||
|
recno = atoi(buf);
|
||
|
|
||
|
//
|
||
|
// Start with a fresh key each time,
|
||
|
// the dbp->get() routine returns
|
||
|
// the key and data pair, not just the key!
|
||
|
//
|
||
|
Dbt key(&recno, sizeof(recno));
|
||
|
Dbt data;
|
||
|
|
||
|
if ((ret = dbcp->get(&key, &data, DB_SET_RECNO)) != 0) {
|
||
|
dbp->err(ret, "DBcursor->get");
|
||
|
throw DbException(ret);
|
||
|
}
|
||
|
|
||
|
// Display the key and data.
|
||
|
show("k/d\t", &key, &data);
|
||
|
|
||
|
// Move the cursor a record forward.
|
||
|
if ((ret = dbcp->get(&key, &data, DB_NEXT)) != 0) {
|
||
|
dbp->err(ret, "DBcursor->get");
|
||
|
throw DbException(ret);
|
||
|
}
|
||
|
|
||
|
// Display the key and data.
|
||
|
show("next\t", &key, &data);
|
||
|
|
||
|
//
|
||
|
// Retrieve the record number for the following record into
|
||
|
// local memory.
|
||
|
//
|
||
|
data.set_data(&recno);
|
||
|
data.set_size(sizeof(recno));
|
||
|
data.set_ulen(sizeof(recno));
|
||
|
data.set_flags(data.get_flags() | DB_DBT_USERMEM);
|
||
|
|
||
|
if ((ret = dbcp->get(&key, &data, DB_GET_RECNO)) != 0) {
|
||
|
if (ret != DB_NOTFOUND && ret != DB_KEYEMPTY) {
|
||
|
dbp->err(ret, "DBcursor->get");
|
||
|
throw DbException(ret);
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
cout << "retrieved recno: " << (u_long)recno << "\n";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
dbcp->close();
|
||
|
dbcp = NULL;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// show --
|
||
|
// Display a key/data pair.
|
||
|
//
|
||
|
void BtRecExample::show(char *msg, Dbt *key, Dbt *data)
|
||
|
{
|
||
|
cout << msg << (char *)key->get_data()
|
||
|
<< " : " << (char *)data->get_data() << "\n";
|
||
|
}
|
||
|
|
||
|
int
|
||
|
main(int argc, char *argv[])
|
||
|
{
|
||
|
extern char *optarg;
|
||
|
extern int optind;
|
||
|
FILE *fp;
|
||
|
int ch;
|
||
|
|
||
|
while ((ch = getopt(argc, argv, "")) != EOF)
|
||
|
switch (ch) {
|
||
|
case '?':
|
||
|
default:
|
||
|
usage();
|
||
|
}
|
||
|
argc -= optind;
|
||
|
argv += optind;
|
||
|
|
||
|
// Open the word database.
|
||
|
if ((fp = fopen(WORDLIST, "r")) == NULL) {
|
||
|
fprintf(stderr, "%s: open %s: %s\n",
|
||
|
progname, WORDLIST, db_strerror(errno));
|
||
|
exit (1);
|
||
|
}
|
||
|
|
||
|
try {
|
||
|
BtRecExample app(fp);
|
||
|
|
||
|
// Close the word database.
|
||
|
(void)fclose(fp);
|
||
|
fp = NULL;
|
||
|
|
||
|
app.stats();
|
||
|
app.run();
|
||
|
}
|
||
|
catch (DbException &dbe) {
|
||
|
cerr << "Exception: " << dbe.what() << "\n";
|
||
|
return dbe.get_errno();
|
||
|
}
|
||
|
|
||
|
return (0);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
usage()
|
||
|
{
|
||
|
(void)fprintf(stderr, "usage: %s\n", progname);
|
||
|
exit(1);
|
||
|
}
|