summaryrefslogtreecommitdiff
path: root/db-4.8.30/examples_c/csv/db.c
diff options
context:
space:
mode:
authorJesse Morgan <jesse@jesterpm.net>2016-12-17 21:28:53 -0800
committerJesse Morgan <jesse@jesterpm.net>2016-12-17 21:28:53 -0800
commit54df2afaa61c6a03cbb4a33c9b90fa572b6d07b8 (patch)
tree18147b92b969d25ffbe61935fb63035cac820dd0 /db-4.8.30/examples_c/csv/db.c
Berkeley DB 4.8 with rust build script for linux.
Diffstat (limited to 'db-4.8.30/examples_c/csv/db.c')
-rw-r--r--db-4.8.30/examples_c/csv/db.c244
1 files changed, 244 insertions, 0 deletions
diff --git a/db-4.8.30/examples_c/csv/db.c b/db-4.8.30/examples_c/csv/db.c
new file mode 100644
index 0000000..efa9208
--- /dev/null
+++ b/db-4.8.30/examples_c/csv/db.c
@@ -0,0 +1,244 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2005-2009 Oracle. All rights reserved.
+ *
+ * $Id$
+ */
+
+#include "csv.h"
+#include "csv_local.h"
+#include "csv_extern.h"
+
+static int compare_uint32(DB *, const DBT *, const DBT *);
+
+/*
+ * csv_env_init --
+ * Initialize the database environment.
+ */
+int
+csv_env_open(const char *home, int is_rdonly)
+{
+ int ret;
+
+ dbenv = NULL;
+ db = NULL;
+
+ /* Create a database environment handle. */
+ if ((ret = db_env_create(&dbenv, 0)) != 0) {
+ fprintf(stderr,
+ "%s: db_env_create: %s\n", progname, db_strerror(ret));
+ return (1);
+ }
+
+ /*
+ * Configure Berkeley DB error reporting to stderr, with our program
+ * name as the prefix.
+ */
+ dbenv->set_errfile(dbenv, stderr);
+ dbenv->set_errpfx(dbenv, progname);
+
+ /*
+ * The default Berkeley DB cache size is fairly small; configure a
+ * 1MB cache for now. This value will require tuning in the future.
+ */
+ if ((ret = dbenv->set_cachesize(dbenv, 0, 1048576, 1)) != 0) {
+ dbenv->err(dbenv, ret, "DB_ENV->set_cachesize");
+ return (1);
+ }
+
+ /*
+ * We may be working with an existing environment -- try and join it.
+ * If that fails, create a new database environment; for now, we only
+ * need a cache, no logging, locking, or transactions.
+ */
+ if ((ret = dbenv->open(dbenv, home,
+ DB_JOINENV | DB_USE_ENVIRON, 0)) != 0 &&
+ (ret = dbenv->open(dbenv, home,
+ DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE | DB_USE_ENVIRON, 0)) != 0) {
+ dbenv->err(dbenv, ret, "DB_ENV->open");
+ return (1);
+ }
+
+ /* Create the primary database handle. */
+ if ((ret = db_create(&db, dbenv, 0)) != 0) {
+ dbenv->err(dbenv, ret, "db_create");
+ return (1);
+ }
+
+ /*
+ * Records may be relatively large -- use a large page size.
+ */
+ if ((ret = db->set_pagesize(db, 32 * 1024)) != 0) {
+ dbenv->err(dbenv, ret, "DB->set_pagesize");
+ return (1);
+ }
+
+ /*
+ * The primary database uses an integer as its key; on little-endian
+ * machines, integers sort badly using the default Berkeley DB sort
+ * function (which is lexicographic). Specify a comparison function
+ * for the database.
+ */
+ if ((ret = db->set_bt_compare(db, compare_uint32)) != 0) {
+ dbenv->err(dbenv, ret, "DB->set_bt_compare");
+ return (1);
+ }
+
+ /* Open the primary database. */
+ if ((ret = db->open(db, NULL,
+ "primary", NULL, DB_BTREE, is_rdonly ? 0 : DB_CREATE, 0)) != 0) {
+ dbenv->err(dbenv, ret, "DB->open: primary");
+ return (1);
+ }
+
+ /* Open the secondaries. */
+ if ((ret = csv_secondary_open()) != 0)
+ return (1);
+
+ return (0);
+}
+
+/*
+ * csv_env_close --
+ * Discard the database environment.
+ */
+int
+csv_env_close()
+{
+ int ret, t_ret;
+
+ ret = 0;
+
+ /* Close the secondaries. */
+ ret = csv_secondary_close();
+
+ /* Close the primary handle. */
+ if (db != NULL && (t_ret = db->close(db, 0)) != 0) {
+ dbenv->err(dbenv, ret, "DB->close");
+ if (ret == 0)
+ ret = t_ret;
+ }
+ if ((t_ret = dbenv->close(dbenv, 0)) != 0) {
+ fprintf(stderr,
+ "%s: DB_ENV->close: %s\n", progname, db_strerror(ret));
+ if (ret == 0)
+ ret = t_ret;
+ }
+
+ return (ret);
+}
+
+/*
+ * csv_secondary_open --
+ * Open any secondary indices.
+ */
+int
+csv_secondary_open()
+{
+ DB *sdb;
+ DbField *f;
+ int ret, (*fcmp)(DB *, const DBT *, const DBT *);
+
+ /*
+ * Create secondary database handles.
+ */
+ for (f = fieldlist; f->name != NULL; ++f) {
+ if (f->indx == 0)
+ continue;
+
+ if ((ret = db_create(&sdb, dbenv, 0)) != 0) {
+ dbenv->err(dbenv, ret, "db_create");
+ return (1);
+ }
+ sdb->app_private = f;
+
+ /* Keys are small, use a relatively small page size. */
+ if ((ret = sdb->set_pagesize(sdb, 8 * 1024)) != 0) {
+ dbenv->err(dbenv, ret, "DB->set_pagesize");
+ return (1);
+ }
+
+ /*
+ * Sort the database based on the underlying type. Skip
+ * strings, Berkeley DB defaults to lexicographic sort.
+ */
+ switch (f->type) {
+ case DOUBLE:
+ fcmp = compare_double;
+ break;
+ case UNSIGNED_LONG:
+ fcmp = compare_ulong;
+ break;
+ case NOTSET:
+ case STRING:
+ default:
+ fcmp = NULL;
+ break;
+ }
+ if (fcmp != NULL &&
+ (ret = sdb->set_bt_compare(sdb, fcmp)) != 0) {
+ dbenv->err(dbenv, ret, "DB->set_bt_compare");
+ return (1);
+ }
+
+ /* Always configure secondaries for sorted duplicates. */
+ if ((ret = sdb->set_flags(sdb, DB_DUPSORT)) != 0) {
+ dbenv->err(dbenv, ret, "DB->set_flags");
+ return (1);
+ }
+ if ((ret = sdb->set_dup_compare(sdb, compare_ulong)) != 0) {
+ dbenv->err(dbenv, ret, "DB->set_dup_compare");
+ return (1);
+ }
+
+ if ((ret = sdb->open(
+ sdb, NULL, f->name, NULL, DB_BTREE, DB_CREATE, 0)) != 0) {
+ dbenv->err(dbenv, ret, "DB->open: %s", f->name);
+ return (1);
+ }
+ if ((ret = sdb->associate(
+ db, NULL, sdb, secondary_callback, DB_CREATE)) != 0) {
+ dbenv->err(dbenv, ret, "DB->set_associate");
+ return (1);
+ }
+ f->secondary = sdb;
+ }
+
+ return (0);
+}
+
+/*
+ * csv_secondary_close --
+ * Close any secondary indices.
+ */
+int
+csv_secondary_close()
+{
+ DbField *f;
+ int ret, t_ret;
+
+ ret = 0;
+ for (f = fieldlist; f->name != NULL; ++f)
+ if (f->secondary != NULL && (t_ret =
+ f->secondary->close(f->secondary, 0)) != 0 && ret == 0)
+ ret = t_ret;
+
+ return (ret);
+}
+
+/*
+ * compare_uint32 --
+ * Compare two keys.
+ */
+static int
+compare_uint32(DB *db_arg, const DBT *a_arg, const DBT *b_arg)
+{
+ u_int32_t a, b;
+
+ db_arg = db_arg; /* Quiet compiler. */
+
+ memcpy(&a, a_arg->data, sizeof(u_int32_t));
+ memcpy(&b, b_arg->data, sizeof(u_int32_t));
+ return (a > b ? 1 : ((a < b) ? -1 : 0));
+}