00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "csv.h"
00011 #include "csv_local.h"
00012 #include "csv_extern.h"
00013
00014 static int compare_uint32(DB *, const DBT *, const DBT *);
00015
00016
00017
00018
00019
00020 int
00021 csv_env_open(const char *home, int is_rdonly)
00022 {
00023 int ret;
00024
00025 dbenv = NULL;
00026 db = NULL;
00027
00028
00029 if ((ret = db_env_create(&dbenv, 0)) != 0) {
00030 fprintf(stderr,
00031 "%s: db_env_create: %s\n", progname, db_strerror(ret));
00032 return (1);
00033 }
00034
00035
00036
00037
00038
00039 dbenv->set_errfile(dbenv, stderr);
00040 dbenv->set_errpfx(dbenv, progname);
00041
00042
00043
00044
00045
00046 if ((ret = dbenv->set_cachesize(dbenv, 0, 1048576, 1)) != 0) {
00047 dbenv->err(dbenv, ret, "DB_ENV->set_cachesize");
00048 return (1);
00049 }
00050
00051
00052
00053
00054
00055
00056 if ((ret = dbenv->open(dbenv, home,
00057 DB_JOINENV | DB_USE_ENVIRON, 0)) != 0 &&
00058 (ret = dbenv->open(dbenv, home,
00059 DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE | DB_USE_ENVIRON, 0)) != 0) {
00060 dbenv->err(dbenv, ret, "DB_ENV->open");
00061 return (1);
00062 }
00063
00064
00065 if ((ret = db_create(&db, dbenv, 0)) != 0) {
00066 dbenv->err(dbenv, ret, "db_create");
00067 return (1);
00068 }
00069
00070
00071
00072
00073 if ((ret = db->set_pagesize(db, 32 * 1024)) != 0) {
00074 dbenv->err(dbenv, ret, "DB->set_pagesize");
00075 return (1);
00076 }
00077
00078
00079
00080
00081
00082
00083
00084 if ((ret = db->set_bt_compare(db, compare_uint32)) != 0) {
00085 dbenv->err(dbenv, ret, "DB->set_bt_compare");
00086 return (1);
00087 }
00088
00089
00090 if ((ret = db->open(db, NULL,
00091 "primary", NULL, DB_BTREE, is_rdonly ? 0 : DB_CREATE, 0)) != 0) {
00092 dbenv->err(dbenv, ret, "DB->open: primary");
00093 return (1);
00094 }
00095
00096
00097 if ((ret = csv_secondary_open()) != 0)
00098 return (1);
00099
00100 return (0);
00101 }
00102
00103
00104
00105
00106
00107 int
00108 csv_env_close()
00109 {
00110 int ret, t_ret;
00111
00112 ret = 0;
00113
00114
00115 ret = csv_secondary_close();
00116
00117
00118 if (db != NULL && (t_ret = db->close(db, 0)) != 0) {
00119 dbenv->err(dbenv, ret, "DB->close");
00120 if (ret == 0)
00121 ret = t_ret;
00122 }
00123 if ((t_ret = dbenv->close(dbenv, 0)) != 0) {
00124 fprintf(stderr,
00125 "%s: DB_ENV->close: %s\n", progname, db_strerror(ret));
00126 if (ret == 0)
00127 ret = t_ret;
00128 }
00129
00130 return (ret);
00131 }
00132
00133
00134
00135
00136
00137 int
00138 csv_secondary_open()
00139 {
00140 DB *sdb;
00141 DbField *f;
00142 int ret, (*fcmp)(DB *, const DBT *, const DBT *);
00143
00144
00145
00146
00147 for (f = fieldlist; f->name != NULL; ++f) {
00148 if (f->indx == 0)
00149 continue;
00150
00151 if ((ret = db_create(&sdb, dbenv, 0)) != 0) {
00152 dbenv->err(dbenv, ret, "db_create");
00153 return (1);
00154 }
00155 sdb->app_private = f;
00156
00157
00158 if ((ret = sdb->set_pagesize(sdb, 8 * 1024)) != 0) {
00159 dbenv->err(dbenv, ret, "DB->set_pagesize");
00160 return (1);
00161 }
00162
00163
00164
00165
00166
00167 switch (f->type) {
00168 case DOUBLE:
00169 fcmp = compare_double;
00170 break;
00171 case ULONG:
00172 fcmp = compare_ulong;
00173 break;
00174 case NOTSET:
00175 case STRING:
00176 default:
00177 fcmp = NULL;
00178 break;
00179 }
00180 if (fcmp != NULL &&
00181 (ret = sdb->set_bt_compare(sdb, fcmp)) != 0) {
00182 dbenv->err(dbenv, ret, "DB->set_bt_compare");
00183 return (1);
00184 }
00185
00186
00187 if ((ret = sdb->set_flags(sdb, DB_DUPSORT)) != 0) {
00188 dbenv->err(dbenv, ret, "DB->set_flags");
00189 return (1);
00190 }
00191 if ((ret = sdb->set_dup_compare(sdb, compare_ulong)) != 0) {
00192 dbenv->err(dbenv, ret, "DB->set_dup_compare");
00193 return (1);
00194 }
00195
00196 if ((ret = sdb->open(
00197 sdb, NULL, f->name, NULL, DB_BTREE, DB_CREATE, 0)) != 0) {
00198 dbenv->err(dbenv, ret, "DB->open: %s", f->name);
00199 return (1);
00200 }
00201 if ((ret = sdb->associate(
00202 db, NULL, sdb, secondary_callback, DB_CREATE)) != 0) {
00203 dbenv->err(dbenv, ret, "DB->set_associate");
00204 return (1);
00205 }
00206 f->secondary = sdb;
00207 }
00208
00209 return (0);
00210 }
00211
00212
00213
00214
00215
00216 int
00217 csv_secondary_close()
00218 {
00219 DbField *f;
00220 int ret, t_ret;
00221
00222 ret = 0;
00223 for (f = fieldlist; f->name != NULL; ++f)
00224 if (f->secondary != NULL && (t_ret =
00225 f->secondary->close(f->secondary, 0)) != 0 && ret == 0)
00226 ret = t_ret;
00227
00228 return (ret);
00229 }
00230
00231
00232
00233
00234
00235 static int
00236 compare_uint32(DB *db_arg, const DBT *a_arg, const DBT *b_arg)
00237 {
00238 u_int32_t a, b;
00239
00240 db_arg = db_arg;
00241
00242 memcpy(&a, a_arg->data, sizeof(u_int32_t));
00243 memcpy(&b, b_arg->data, sizeof(u_int32_t));
00244 return (a > b ? 1 : ((a < b) ? -1 : 0));
00245 }