00001
00002
00003
00004
00005
00006
00007
00008 #include "config.h"
00009
00010 #ifndef lint
00011 static const char revid[] = "$Id: db__method_8c-source.html,v 1.1 2008/06/08 10:17:52 sebdiaz Exp $";
00012 #endif
00013
00014 #ifndef NO_SYSTEM_INCLUDES
00015 #include <sys/types.h>
00016
00017 #ifdef HAVE_RPC
00018 #include <rpc/rpc.h>
00019 #endif
00020
00021 #include <errno.h>
00022 #include <string.h>
00023 #endif
00024
00025 #ifdef HAVE_RPC
00026 #include "db_server.h"
00027 #endif
00028
00029 #include "db_int.h"
00030 #include "db_page.h"
00031 #include "db_am.h"
00032 #include "btree.h"
00033 #include "hash.h"
00034 #include "qam.h"
00035 #include "xa.h"
00036 #include "xa_ext.h"
00037
00038 #ifdef HAVE_RPC
00039 #include "gen_client_ext.h"
00040 #include "rpc_client_ext.h"
00041 #endif
00042
00043 static int __db_get_byteswapped __P((DB *));
00044 static DBTYPE
00045 __db_get_type __P((DB *));
00046 static int __db_init __P((DB *, u_int32_t));
00047 static int __db_key_range
00048 __P((DB *, DB_TXN *, DBT *, DB_KEY_RANGE *, u_int32_t));
00049 static int __db_set_cachesize __P((DB *, u_int32_t, u_int32_t, int));
00050 static int __db_set_dup_compare __P((DB *, int (*)(const DBT *, const DBT *)));
00051 static void __db_set_errcall __P((DB *, void (*)(const char *, char *)));
00052 static void __db_set_errfile __P((DB *, FILE *));
00053 static int __db_set_feedback __P((DB *, void (*)(DB *, int, int)));
00054 static int __db_set_flags __P((DB *, u_int32_t));
00055 static int __db_set_lorder __P((DB *, int));
00056 static int __db_set_malloc __P((DB *, void *(*)(size_t)));
00057 static int __db_set_pagesize __P((DB *, u_int32_t));
00058 static int __db_set_realloc __P((DB *, void *(*)(void *, size_t)));
00059 static void __db_set_errpfx __P((DB *, const char *));
00060 static int __db_set_paniccall __P((DB *, void (*)(DB_ENV *, int)));
00061 static void __dbh_err __P((DB *, int, const char *, ...));
00062 static void __dbh_errx __P((DB *, const char *, ...));
00063
00064
00065
00066
00067
00068 int
00069 CDB_db_create(dbpp, dbenv, flags)
00070 DB **dbpp;
00071 DB_ENV *dbenv;
00072 u_int32_t flags;
00073 {
00074 DB *dbp;
00075 int ret;
00076
00077
00078 switch (flags) {
00079 case 0:
00080 break;
00081 case DB_XA_CREATE:
00082 if (dbenv != NULL) {
00083 CDB___db_err(dbenv,
00084 "XA applications may not specify an environment to CDB_db_create");
00085 return (EINVAL);
00086 }
00087
00088
00089
00090
00091
00092
00093
00094 dbenv = TAILQ_FIRST(&DB_GLOBAL(db_envq));
00095 break;
00096 default:
00097 return (CDB___db_ferr(dbenv, "CDB_db_create", 0));
00098 }
00099
00100
00101 if ((ret = CDB___os_calloc(dbenv, 1, sizeof(*dbp), &dbp)) != 0)
00102 return (ret);
00103 #ifdef HAVE_RPC
00104 if (dbenv != NULL && dbenv->cl_handle != NULL)
00105 ret = __dbcl_init(dbp, dbenv, flags);
00106 else
00107 #endif
00108 ret = __db_init(dbp, flags);
00109 if (ret != 0) {
00110 CDB___os_free(dbp, sizeof(*dbp));
00111 return (ret);
00112 }
00113
00114
00115 if (dbenv == NULL) {
00116 if ((ret = CDB_db_env_create(&dbenv, 0)) != 0) {
00117 CDB___os_free(dbp, sizeof(*dbp));
00118 return (ret);
00119 }
00120 dbenv->dblocal_ref = 0;
00121 F_SET(dbenv, DB_ENV_DBLOCAL);
00122 }
00123 if (F_ISSET(dbenv, DB_ENV_DBLOCAL))
00124 ++dbenv->dblocal_ref;
00125
00126 dbp->dbenv = dbenv;
00127
00128 *dbpp = dbp;
00129 return (0);
00130 }
00131
00132
00133
00134
00135
00136 static int
00137 __db_init(dbp, flags)
00138 DB *dbp;
00139 u_int32_t flags;
00140 {
00141 int ret;
00142
00143 dbp->log_fileid = DB_LOGFILEID_INVALID;
00144
00145 TAILQ_INIT(&dbp->free_queue);
00146 TAILQ_INIT(&dbp->active_queue);
00147 TAILQ_INIT(&dbp->join_queue);
00148
00149 FLD_SET(dbp->am_ok,
00150 DB_OK_BTREE | DB_OK_HASH | DB_OK_QUEUE | DB_OK_RECNO);
00151
00152 dbp->close = CDB___db_close;
00153 dbp->cursor = CDB___db_cursor;
00154 dbp->del = NULL;
00155 dbp->err = __dbh_err;
00156 dbp->errx = __dbh_errx;
00157 dbp->fd = CDB___db_fd;
00158 dbp->get = CDB___db_get;
00159 dbp->get_byteswapped = __db_get_byteswapped;
00160 dbp->get_type = __db_get_type;
00161 dbp->join = CDB___db_join;
00162 dbp->key_range = __db_key_range;
00163 dbp->open = CDB___db_open;
00164 dbp->put = CDB___db_put;
00165 dbp->remove = CDB___db_remove;
00166 dbp->rename = CDB___db_rename;
00167 dbp->set_cachesize = __db_set_cachesize;
00168 dbp->set_dup_compare = __db_set_dup_compare;
00169 dbp->set_errcall = __db_set_errcall;
00170 dbp->set_errfile = __db_set_errfile;
00171 dbp->set_errpfx = __db_set_errpfx;
00172 dbp->set_feedback = __db_set_feedback;
00173 dbp->set_flags = __db_set_flags;
00174 dbp->set_lorder = __db_set_lorder;
00175 dbp->set_malloc = __db_set_malloc;
00176 dbp->set_pagesize = __db_set_pagesize;
00177 dbp->set_paniccall = __db_set_paniccall;
00178 dbp->set_realloc = __db_set_realloc;
00179 dbp->stat = NULL;
00180 dbp->sync = CDB___db_sync;
00181 dbp->tags = 0;
00182 dbp->upgrade = CDB___db_upgrade;
00183 dbp->verify = CDB___db_verify;
00184
00185 if ((ret = CDB___bam_db_create(dbp)) != 0)
00186 return (ret);
00187 if ((ret = CDB___ham_db_create(dbp)) != 0)
00188 return (ret);
00189 if ((ret = CDB___qam_db_create(dbp)) != 0)
00190 return (ret);
00191
00192
00193
00194
00195
00196 if (LF_ISSET(DB_XA_CREATE) && (ret = CDB___db_xa_create(dbp)) != 0)
00197 return (ret);
00198
00199 return (0);
00200 }
00201
00202
00203
00204
00205
00206
00207
00208 int
00209 CDB___dbh_am_chk(dbp, flags)
00210 DB *dbp;
00211 u_int32_t flags;
00212 {
00213
00214
00215
00216
00217
00218 if ((LF_ISSET(DB_OK_BTREE) && FLD_ISSET(dbp->am_ok, DB_OK_BTREE)) ||
00219 (LF_ISSET(DB_OK_HASH) && FLD_ISSET(dbp->am_ok, DB_OK_HASH)) ||
00220 (LF_ISSET(DB_OK_QUEUE) && FLD_ISSET(dbp->am_ok, DB_OK_QUEUE)) ||
00221 (LF_ISSET(DB_OK_RECNO) && FLD_ISSET(dbp->am_ok, DB_OK_RECNO))) {
00222 FLD_CLR(dbp->am_ok, ~flags);
00223 return (0);
00224 }
00225
00226 CDB___db_err(dbp->dbenv,
00227 "call implies an access method which is inconsistent with previous calls");
00228 return (EINVAL);
00229 }
00230
00231
00232
00233
00234
00235 static void
00236 #ifdef __STDC__
00237 __dbh_err(DB *dbp, int error, const char *fmt, ...)
00238 #else
00239 __dbh_err(dbp, error, fmt, va_alist)
00240 DB *dbp;
00241 int error;
00242 const char *fmt;
00243 va_dcl
00244 #endif
00245 {
00246 va_list ap;
00247
00248 #ifdef __STDC__
00249 va_start(ap, fmt);
00250 #else
00251 va_start(ap);
00252 #endif
00253 CDB___db_real_err(dbp->dbenv, error, 1, 1, fmt, ap);
00254
00255 va_end(ap);
00256 }
00257
00258
00259
00260
00261
00262 static void
00263 #ifdef __STDC__
00264 __dbh_errx(DB *dbp, const char *fmt, ...)
00265 #else
00266 __dbh_errx(dbp, fmt, va_alist)
00267 DB *dbp;
00268 const char *fmt;
00269 va_dcl
00270 #endif
00271 {
00272 va_list ap;
00273
00274 #ifdef __STDC__
00275 va_start(ap, fmt);
00276 #else
00277 va_start(ap);
00278 #endif
00279 CDB___db_real_err(dbp->dbenv, 0, 0, 1, fmt, ap);
00280
00281 va_end(ap);
00282 }
00283
00284
00285
00286
00287
00288 static int
00289 __db_get_byteswapped(dbp)
00290 DB *dbp;
00291 {
00292 DB_ILLEGAL_BEFORE_OPEN(dbp, "get_byteswapped");
00293
00294 return (F_ISSET(dbp, DB_AM_SWAP) ? 1 : 0);
00295 }
00296
00297
00298
00299
00300
00301 static DBTYPE
00302 __db_get_type(dbp)
00303 DB *dbp;
00304 {
00305 DB_ILLEGAL_BEFORE_OPEN(dbp, "get_type");
00306
00307 return (dbp->type);
00308 }
00309
00310
00311
00312
00313
00314 static int
00315 __db_key_range(dbp, txn, key, kr, flags)
00316 DB *dbp;
00317 DB_TXN *txn;
00318 DBT *key;
00319 DB_KEY_RANGE *kr;
00320 u_int32_t flags;
00321 {
00322 COMPQUIET(txn, NULL);
00323 COMPQUIET(key, NULL);
00324 COMPQUIET(kr, NULL);
00325 COMPQUIET(flags, 0);
00326
00327 DB_ILLEGAL_BEFORE_OPEN(dbp, "key_range");
00328 DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE);
00329
00330 return (EINVAL);
00331 }
00332
00333
00334
00335
00336
00337 static int
00338 __db_set_cachesize(dbp, cache_gbytes, cache_bytes, ncache)
00339 DB *dbp;
00340 u_int32_t cache_gbytes, cache_bytes;
00341 int ncache;
00342 {
00343 DB_ILLEGAL_IN_ENV(dbp, "set_cachesize");
00344 DB_ILLEGAL_AFTER_OPEN(dbp, "set_cachesize");
00345
00346 return (dbp->dbenv->set_cachesize(
00347 dbp->dbenv, cache_gbytes, cache_bytes, ncache));
00348 }
00349
00350
00351
00352
00353
00354 static int
00355 __db_set_dup_compare(dbp, func)
00356 DB *dbp;
00357 int (*func) __P((const DBT *, const DBT *));
00358 {
00359 DB_ILLEGAL_AFTER_OPEN(dbp, "dup_compare");
00360 DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE | DB_OK_HASH);
00361
00362 dbp->dup_compare = func;
00363
00364 return (0);
00365 }
00366
00367 static void
00368 __db_set_errcall(dbp, errcall)
00369 DB *dbp;
00370 void (*errcall) __P((const char *, char *));
00371 {
00372 dbp->dbenv->set_errcall(dbp->dbenv, errcall);
00373 }
00374
00375 static void
00376 __db_set_errfile(dbp, errfile)
00377 DB *dbp;
00378 FILE *errfile;
00379 {
00380 dbp->dbenv->set_errfile(dbp->dbenv, errfile);
00381 }
00382
00383 static void
00384 __db_set_errpfx(dbp, errpfx)
00385 DB *dbp;
00386 const char *errpfx;
00387 {
00388 dbp->dbenv->set_errpfx(dbp->dbenv, errpfx);
00389 }
00390
00391 static int
00392 __db_set_feedback(dbp, feedback)
00393 DB *dbp;
00394 void (*feedback) __P((DB *, int, int));
00395 {
00396 dbp->db_feedback = feedback;
00397 return (0);
00398 }
00399
00400 static int
00401 __db_set_flags(dbp, flags)
00402 DB *dbp;
00403 u_int32_t flags;
00404 {
00405 int ret;
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415 if ((ret = CDB___bam_set_flags(dbp, &flags)) != 0)
00416 return (ret);
00417 if ((ret = CDB___ram_set_flags(dbp, &flags)) != 0)
00418 return (ret);
00419
00420 return (flags == 0 ? 0 : CDB___db_ferr(dbp->dbenv, "DB->set_flags", 0));
00421 }
00422
00423 static int
00424 __db_set_lorder(dbp, db_lorder)
00425 DB *dbp;
00426 int db_lorder;
00427 {
00428 int ret;
00429
00430 DB_ILLEGAL_AFTER_OPEN(dbp, "set_lorder");
00431
00432
00433 switch (ret = CDB___db_byteorder(dbp->dbenv, db_lorder)) {
00434 case 0:
00435 F_CLR(dbp, DB_AM_SWAP);
00436 break;
00437 case DB_SWAPBYTES:
00438 F_SET(dbp, DB_AM_SWAP);
00439 break;
00440 default:
00441 return (ret);
00442
00443 }
00444 return (0);
00445 }
00446
00447 static int
00448 __db_set_malloc(dbp, func)
00449 DB *dbp;
00450 void *(*func) __P((size_t));
00451 {
00452 DB_ILLEGAL_AFTER_OPEN(dbp, "set_malloc");
00453
00454 dbp->db_malloc = func;
00455 return (0);
00456 }
00457
00458 static int
00459 __db_set_pagesize(dbp, db_pagesize)
00460 DB *dbp;
00461 u_int32_t db_pagesize;
00462 {
00463 DB_ILLEGAL_AFTER_OPEN(dbp, "set_pagesize");
00464
00465 if (db_pagesize < DB_MIN_PGSIZE) {
00466 CDB___db_err(dbp->dbenv, "page sizes may not be smaller than %lu",
00467 (u_long)DB_MIN_PGSIZE);
00468 return (EINVAL);
00469 }
00470 if (db_pagesize > DB_MAX_PGSIZE) {
00471 CDB___db_err(dbp->dbenv, "page sizes may not be larger than %lu",
00472 (u_long)DB_MAX_PGSIZE);
00473 return (EINVAL);
00474 }
00475
00476
00477
00478
00479
00480 if ((u_int32_t)1 << CDB___db_log2(db_pagesize) != db_pagesize) {
00481 CDB___db_err(dbp->dbenv, "page sizes must be a power-of-2");
00482 return (EINVAL);
00483 }
00484
00485
00486
00487
00488
00489
00490 dbp->pgsize = db_pagesize;
00491
00492 return (0);
00493 }
00494
00495 static int
00496 __db_set_realloc(dbp, func)
00497 DB *dbp;
00498 void *(*func) __P((void *, size_t));
00499 {
00500 DB_ILLEGAL_AFTER_OPEN(dbp, "set_realloc");
00501
00502 dbp->db_realloc = func;
00503 return (0);
00504 }
00505
00506 static int
00507 __db_set_paniccall(dbp, paniccall)
00508 DB *dbp;
00509 void (*paniccall) __P((DB_ENV *, int));
00510 {
00511 return (dbp->dbenv->set_paniccall(dbp->dbenv, paniccall));
00512 }
00513
00514 #ifdef HAVE_RPC
00515
00516
00517
00518
00519
00520
00521
00522
00523 int
00524 __dbcl_init(dbp, dbenv, flags)
00525 DB *dbp;
00526 DB_ENV *dbenv;
00527 u_int32_t flags;
00528 {
00529 CLIENT *cl;
00530 __db_create_reply *replyp;
00531 __db_create_msg req;
00532 int ret;
00533
00534 TAILQ_INIT(&dbp->free_queue);
00535 TAILQ_INIT(&dbp->active_queue);
00536
00537 dbp->close = __dbcl_db_close;
00538 dbp->cursor = __dbcl_db_cursor;
00539 dbp->del = __dbcl_db_del;
00540 dbp->err = __dbh_err;
00541 dbp->errx = __dbh_errx;
00542 dbp->fd = __dbcl_db_fd;
00543 dbp->get = __dbcl_db_get;
00544 dbp->get_byteswapped = __dbcl_db_swapped;
00545 dbp->get_type = __db_get_type;
00546 dbp->join = __dbcl_db_join;
00547 dbp->key_range = __dbcl_db_key_range;
00548 dbp->open = __dbcl_db_open;
00549 dbp->put = __dbcl_db_put;
00550 dbp->remove = __dbcl_db_remove;
00551 dbp->rename = __dbcl_db_rename;
00552 dbp->set_cachesize = __dbcl_db_cachesize;
00553 dbp->set_dup_compare = NULL;
00554 dbp->set_errcall = __db_set_errcall;
00555 dbp->set_errfile = __db_set_errfile;
00556 dbp->set_errpfx = __db_set_errpfx;
00557 dbp->set_feedback = __dbcl_db_feedback;
00558 dbp->set_flags = __dbcl_db_flags;
00559 dbp->set_lorder = __dbcl_db_lorder;
00560 dbp->set_malloc = __dbcl_db_malloc;
00561 dbp->set_pagesize = __dbcl_db_pagesize;
00562 dbp->set_paniccall = __dbcl_db_panic;
00563 dbp->set_realloc = __dbcl_db_realloc;
00564 dbp->stat = __dbcl_db_stat;
00565 dbp->sync = __dbcl_db_sync;
00566 dbp->upgrade = __dbcl_db_upgrade;
00567
00568
00569
00570
00571 dbp->set_bt_compare = __dbcl_db_bt_compare;
00572 dbp->set_bt_maxkey = __dbcl_db_bt_maxkey;
00573 dbp->set_bt_minkey = __dbcl_db_bt_minkey;
00574 dbp->set_bt_prefix = __dbcl_db_bt_prefix;
00575 dbp->set_h_ffactor = __dbcl_db_h_ffactor;
00576 dbp->set_h_hash = __dbcl_db_h_hash;
00577 dbp->set_h_nelem = __dbcl_db_h_nelem;
00578 dbp->set_re_delim = __dbcl_db_re_delim;
00579 dbp->set_re_len = __dbcl_db_re_len;
00580 dbp->set_re_pad = __dbcl_db_re_pad;
00581 dbp->set_re_source = __dbcl_db_re_source;
00582
00583 cl = (CLIENT *)dbenv->cl_handle;
00584 req.flags = flags;
00585 req.envpcl_id = dbenv->cl_id;
00586
00587
00588
00589
00590 replyp = __db_db_create_1(&req, cl);
00591 if (replyp == NULL) {
00592 CDB___db_err(dbenv, clnt_sperror(cl, "Berkeley DB"));
00593 return (DB_NOSERVER);
00594 }
00595
00596 if ((ret = replyp->status) != 0)
00597 return (ret);
00598
00599 dbp->cl_id = replyp->dbpcl_id;
00600 return (0);
00601 }
00602 #endif