/*-
 * See the file LICENSE for redistribution information.
 *
 * Copyright (c) 1997, 2016 Oracle and/or its affiliates.  All rights reserved.
 *
 * ex_btrec-- A basic example of using record numbers in a btree.
 *  
 *   This example program shows how to store automatically numbered records in a
 *   btree database, one of the kinds of access methods provided by Berkeley DB.
 *   Access methods determine how key-value pairs are stored in the file.
 *   B-tree is one of the most commonly used types because it supports sorted
 *   access to variable length records.
 *   
 *   The program first reads 1000 records from file "wordlist" and then stores
 *   the data in the "access.db" database. The key of each record is the record
 *   number concatenated with a word from the word list; the data is the same,
 *   but in reverse order. Then it opens a cursor to fetch key/data pairs.
 *   The user selects a record by entering its record number. Both the specified
 *   record and the one following it will be displayed.
 *   
 * Database: access.db 
 * Wordlist directory: ../test/tcl/wordlist
 *
 * $Id: ex_btrec.c,v 0f73af5ae3da 2010/05/10 05:38:40 alexander $
 */

#include <sys/types.h>

#include <errno.h>
#include <stdlib.h>
#include <string.h>

#include <db.h>


#define	DATABASE	"access.db"
#define	WORDLIST	"../test/tcl/wordlist"
int	main __P((void));

int	ex_btrec __P((void));
void	show __P((const char *, DBT *, DBT *));

int
main()
{
	return (ex_btrec() == 1 ? EXIT_FAILURE : EXIT_SUCCESS);
}

int
ex_btrec()
{
	DB *dbp;		/* Handle of the main database to store the content of wordlist. */
	DBC *dbcp;		/* Handle of database cursor used for putting or getting the word data. */
	DBT key;		/* The key to dbcp->put()/from dbcp->get(). */
	DBT data;		/* The data to dbcp->put()/from dbcp->get(). */
	DB_BTREE_STAT *statp;	/* The statistic pointer to record the total amount of record number. */
	FILE *fp;		/* File pointer that points to the wordlist. */
	db_recno_t recno;	/* Record number to retrieve a record in access.db database. */
	size_t len;		/* The size of buffer. */
	int cnt;		/* The count variable to read records from wordlist. */
	int ret;		/* Return code from call into Berkeley DB. */
	char *p;		/* Pointer to store buffer. */
	char *t;		/* Pointer to store reverse buffer. */
	char buf[1024];		/* Buffer to store key value. */
	char rbuf[1024];	/* Reverse buffer to store data value. */
	const char *progname = "ex_btrec";		/* Program name. */

	/* Create the database handle. */
	if ((ret = db_create(&dbp, NULL, 0)) != 0) {
		fprintf(stderr,
		    "%s: db_create: %s\n", progname, db_strerror(ret));
		return (1);
	}

	/*
	 * Prefix any error messages with the name of this program and a ':'.
	 * Setting the errfile to stderr is not necessary, since that is the
	 * default; it is provided here as a placeholder showing where one
	 * could direct error messages to an application-specific log file.
	 */
	dbp->set_errfile(dbp, stderr);
	dbp->set_errpfx(dbp, progname);

	/* Configure the database to use 1KB page sizes and record numbering. */
	if ((ret = dbp->set_pagesize(dbp, 1024)) != 0) {
		dbp->err(dbp, ret, "set_pagesize");
		return (1);
	}
	if ((ret = dbp->set_flags(dbp, DB_RECNUM)) != 0) {
		dbp->err(dbp, ret, "set_flags: DB_RECNUM");
		return (1);
	}
	/* Open it with DB_CREATE, making it a DB_BTREE. */
	if ((ret = dbp->open(dbp,
	    NULL, DATABASE, NULL, DB_BTREE, DB_CREATE, 0664)) != 0) {
		dbp->err(dbp, ret, "open: %s", DATABASE);
		return (1);
	}

	/*
	 * Insert records in the wordlist into the database. The key is the
	 * word preceded by its record number, and the data contains the same
	 * characters in the key, but in reverse order.
	 */
	memset(&key, 0, sizeof(DBT));
	memset(&data, 0, sizeof(DBT));
        for(cnt = 0; cnt < 0xFFFFFFFF; cnt++) {
           key.data = &cnt;
           key.size = sizeof(cnt);
           data.data = &cnt;
           data.size = sizeof(cnt);

           printf("%d\n", cnt);
	   if((dbp->put(dbp, NULL, &key, &data, DB_NOOVERWRITE)) != 0) {

           }
        }

/*
        for(cnt = 0; cnt < 0xFFFFFFFF; cnt++) {
		key.data = &cnt;
		key.size = sizeof(recno);
		memset(&data, 0, sizeof(data));
	}
*/

	/* Close the cursor, then its database. */
	if ((ret = dbcp->close(dbcp)) != 0) {
		dbp->err(dbp, ret, "DBcursor->close");
		goto err1;
	}
	if ((ret = dbp->close(dbp, 0)) != 0) {
		/*
		 * This uses fprintf rather than dbp->err because the dbp has
		 * been deallocated by dbp->close() and may no longer be used.
		 */
		fprintf(stderr,
		    "%s: DB->close: %s\n", progname, db_strerror(ret));
		return (1);
	}

	return (0);

err2:	(void)dbcp->close(dbcp);
err1:	(void)dbp->close(dbp, 0);
	return (ret);

}

/*
 * show --
 *	Display a key/data pair.
 *
 * Parameters:
 *  msg		print message
 *  key		the target key to print
 *  data	the target data to print
 */
void
show(msg, key, data)
	const char *msg;
	DBT *key, *data;
{
	printf("%s%.*s : %.*s\n", msg,
	    (int)key->size, (char *)key->data,
	    (int)data->size, (char *)data->data);
}
