00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "db_config.h"
00011
00012 #ifndef lint
00013 static const char copyright[] =
00014 "Copyright (c) 1996-2005\nSleepycat Software Inc. All rights reserved.\n";
00015 #endif
00016
00017 #ifndef NO_SYSTEM_INCLUDES
00018 #include <sys/types.h>
00019
00020 #include <fcntl.h>
00021 #include <string.h>
00022 #endif
00023
00024 #include "db_int.h"
00025 #include "db185_int.h"
00026
00027 static int db185_close __P((DB185 *));
00028 static int db185_compare __P((DB *, const DBT *, const DBT *));
00029 static int db185_del __P((const DB185 *, const DBT185 *, u_int));
00030 static int db185_fd __P((const DB185 *));
00031 static int db185_get __P((const DB185 *, const DBT185 *, DBT185 *, u_int));
00032 static u_int32_t
00033 db185_hash __P((DB *, const void *, u_int32_t));
00034 static size_t db185_prefix __P((DB *, const DBT *, const DBT *));
00035 static int db185_put __P((const DB185 *, DBT185 *, const DBT185 *, u_int));
00036 static int db185_seq __P((const DB185 *, DBT185 *, DBT185 *, u_int));
00037 static int db185_sync __P((const DB185 *, u_int));
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 DB185 *
00049 __db185_open(file, oflags, mode, type, openinfo)
00050 const char *file;
00051 int oflags, mode;
00052 DBTYPE type;
00053 const void *openinfo;
00054 {
00055 const BTREEINFO *bi;
00056 const HASHINFO *hi;
00057 const RECNOINFO *ri;
00058 DB *dbp;
00059 DB185 *db185p;
00060 DB_FH *fhp;
00061 int ret;
00062
00063 dbp = NULL;
00064 db185p = NULL;
00065
00066 if ((ret = db_create(&dbp, NULL, 0)) != 0)
00067 goto err;
00068
00069 if ((ret = __os_calloc(NULL, 1, sizeof(DB185), &db185p)) != 0)
00070 goto err;
00071
00072
00073
00074
00075
00076
00077 switch (type) {
00078 case 0:
00079 type = DB_BTREE;
00080 if ((bi = openinfo) != NULL) {
00081 if (bi->flags & ~R_DUP)
00082 goto einval;
00083 if (bi->flags & R_DUP)
00084 (void)dbp->set_flags(dbp, DB_DUP);
00085 if (bi->cachesize != 0)
00086 (void)dbp->set_cachesize
00087 (dbp, 0, bi->cachesize, 0);
00088 if (bi->minkeypage != 0)
00089 (void)dbp->set_bt_minkey(dbp, bi->minkeypage);
00090 if (bi->psize != 0)
00091 (void)dbp->set_pagesize(dbp, bi->psize);
00092 if (bi->prefix != NULL) {
00093 db185p->prefix = bi->prefix;
00094 dbp->set_bt_prefix(dbp, db185_prefix);
00095 }
00096 if (bi->compare != NULL) {
00097 db185p->compare = bi->compare;
00098 dbp->set_bt_compare(dbp, db185_compare);
00099 }
00100 if (bi->lorder != 0)
00101 dbp->set_lorder(dbp, bi->lorder);
00102 }
00103 break;
00104 case 1:
00105 type = DB_HASH;
00106 if ((hi = openinfo) != NULL) {
00107 if (hi->bsize != 0)
00108 (void)dbp->set_pagesize(dbp, hi->bsize);
00109 if (hi->ffactor != 0)
00110 (void)dbp->set_h_ffactor(dbp, hi->ffactor);
00111 if (hi->nelem != 0)
00112 (void)dbp->set_h_nelem(dbp, hi->nelem);
00113 if (hi->cachesize != 0)
00114 (void)dbp->set_cachesize
00115 (dbp, 0, hi->cachesize, 0);
00116 if (hi->hash != NULL) {
00117 db185p->hash = hi->hash;
00118 (void)dbp->set_h_hash(dbp, db185_hash);
00119 }
00120 if (hi->lorder != 0)
00121 dbp->set_lorder(dbp, hi->lorder);
00122 }
00123
00124 break;
00125 case 2:
00126 type = DB_RECNO;
00127
00128
00129 (void)dbp->set_flags(dbp, DB_RENUMBER);
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152 if (file != NULL) {
00153 if (oflags & O_CREAT && __os_exists(file, NULL) != 0)
00154 if (__os_openhandle(NULL, file,
00155 oflags, mode, &fhp) == 0)
00156 (void)__os_closehandle(NULL, fhp);
00157 (void)dbp->set_re_source(dbp, file);
00158
00159 if (O_RDONLY)
00160 oflags &= ~O_RDONLY;
00161 oflags |= O_RDWR;
00162 file = NULL;
00163 }
00164
00165 if ((ri = openinfo) != NULL) {
00166
00167
00168
00169
00170 #define BFMSG \
00171 "Berkeley DB: DB 1.85's recno bfname field is not supported.\n"
00172 if (ri->bfname != NULL) {
00173 dbp->errx(dbp, "%s", BFMSG);
00174 goto einval;
00175 }
00176
00177 if (ri->flags & ~(R_FIXEDLEN | R_NOKEY | R_SNAPSHOT))
00178 goto einval;
00179 if (ri->flags & R_FIXEDLEN) {
00180 if (ri->bval != 0)
00181 (void)dbp->set_re_pad(dbp, ri->bval);
00182 if (ri->reclen != 0)
00183 (void)dbp->set_re_len(dbp, ri->reclen);
00184 } else
00185 if (ri->bval != 0)
00186 (void)dbp->set_re_delim(dbp, ri->bval);
00187
00188
00189
00190
00191
00192
00193 if (ri->flags & R_SNAPSHOT)
00194 (void)dbp->set_flags(dbp, DB_SNAPSHOT);
00195
00196 if (ri->cachesize != 0)
00197 (void)dbp->set_cachesize
00198 (dbp, 0, ri->cachesize, 0);
00199 if (ri->psize != 0)
00200 (void)dbp->set_pagesize(dbp, ri->psize);
00201 if (ri->lorder != 0)
00202 dbp->set_lorder(dbp, ri->lorder);
00203 }
00204 break;
00205 default:
00206 goto einval;
00207 }
00208
00209 db185p->close = db185_close;
00210 db185p->del = db185_del;
00211 db185p->fd = db185_fd;
00212 db185p->get = db185_get;
00213 db185p->put = db185_put;
00214 db185p->seq = db185_seq;
00215 db185p->sync = db185_sync;
00216
00217
00218
00219
00220
00221
00222
00223 db185p->dbp = dbp;
00224 dbp->api_internal = db185p;
00225
00226
00227 if ((ret = dbp->open(dbp, NULL,
00228 file, NULL, type, __db_oflags(oflags), mode)) != 0)
00229 goto err;
00230
00231
00232 if ((ret = dbp->cursor(dbp, NULL, &((DB185 *)db185p)->dbc, 0)) != 0)
00233 goto err;
00234
00235 return (db185p);
00236
00237 einval: ret = EINVAL;
00238
00239 err: if (db185p != NULL)
00240 __os_free(NULL, db185p);
00241 if (dbp != NULL)
00242 (void)dbp->close(dbp, 0);
00243
00244 __os_set_errno(ret);
00245 return (NULL);
00246 }
00247
00248 static int
00249 db185_close(db185p)
00250 DB185 *db185p;
00251 {
00252 DB *dbp;
00253 int ret;
00254
00255 dbp = db185p->dbp;
00256
00257 ret = dbp->close(dbp, 0);
00258
00259 __os_free(NULL, db185p);
00260
00261 if (ret == 0)
00262 return (0);
00263
00264 __os_set_errno(ret);
00265 return (-1);
00266 }
00267
00268 static int
00269 db185_del(db185p, key185, flags)
00270 const DB185 *db185p;
00271 const DBT185 *key185;
00272 u_int flags;
00273 {
00274 DB *dbp;
00275 DBT key;
00276 int ret;
00277
00278 dbp = db185p->dbp;
00279
00280 memset(&key, 0, sizeof(key));
00281 key.data = key185->data;
00282 key.size = key185->size;
00283
00284 if (flags & ~R_CURSOR)
00285 goto einval;
00286 if (flags & R_CURSOR)
00287 ret = db185p->dbc->c_del(db185p->dbc, 0);
00288 else
00289 ret = dbp->del(dbp, NULL, &key, 0);
00290
00291 switch (ret) {
00292 case 0:
00293 return (0);
00294 case DB_NOTFOUND:
00295 return (1);
00296 }
00297
00298 if (0) {
00299 einval: ret = EINVAL;
00300 }
00301 __os_set_errno(ret);
00302 return (-1);
00303 }
00304
00305 static int
00306 db185_fd(db185p)
00307 const DB185 *db185p;
00308 {
00309 DB *dbp;
00310 int fd, ret;
00311
00312 dbp = db185p->dbp;
00313
00314 if ((ret = dbp->fd(dbp, &fd)) == 0)
00315 return (fd);
00316
00317 __os_set_errno(ret);
00318 return (-1);
00319 }
00320
00321 static int
00322 db185_get(db185p, key185, data185, flags)
00323 const DB185 *db185p;
00324 const DBT185 *key185;
00325 DBT185 *data185;
00326 u_int flags;
00327 {
00328 DB *dbp;
00329 DBT key, data;
00330 int ret;
00331
00332 dbp = db185p->dbp;
00333
00334 memset(&key, 0, sizeof(key));
00335 key.data = key185->data;
00336 key.size = key185->size;
00337 memset(&data, 0, sizeof(data));
00338 data.data = data185->data;
00339 data.size = data185->size;
00340
00341 if (flags)
00342 goto einval;
00343
00344 switch (ret = dbp->get(dbp, NULL, &key, &data, 0)) {
00345 case 0:
00346 data185->data = data.data;
00347 data185->size = data.size;
00348 return (0);
00349 case DB_NOTFOUND:
00350 return (1);
00351 }
00352
00353 if (0) {
00354 einval: ret = EINVAL;
00355 }
00356 __os_set_errno(ret);
00357 return (-1);
00358 }
00359
00360 static int
00361 db185_put(db185p, key185, data185, flags)
00362 const DB185 *db185p;
00363 DBT185 *key185;
00364 const DBT185 *data185;
00365 u_int flags;
00366 {
00367 DB *dbp;
00368 DBC *dbcp_put;
00369 DBT key, data;
00370 int ret, t_ret;
00371
00372 dbp = db185p->dbp;
00373
00374 memset(&key, 0, sizeof(key));
00375 key.data = key185->data;
00376 key.size = key185->size;
00377 memset(&data, 0, sizeof(data));
00378 data.data = data185->data;
00379 data.size = data185->size;
00380
00381 switch (flags) {
00382 case 0:
00383 ret = dbp->put(dbp, NULL, &key, &data, 0);
00384 break;
00385 case R_CURSOR:
00386 ret = db185p->dbc->c_put(db185p->dbc, &key, &data, DB_CURRENT);
00387 break;
00388 case R_IAFTER:
00389 case R_IBEFORE:
00390 if (dbp->type != DB_RECNO)
00391 goto einval;
00392
00393 if ((ret = dbp->cursor(dbp, NULL, &dbcp_put, 0)) != 0)
00394 break;
00395 if ((ret =
00396 dbcp_put->c_get(dbcp_put, &key, &data, DB_SET)) == 0) {
00397 memset(&data, 0, sizeof(data));
00398 data.data = data185->data;
00399 data.size = data185->size;
00400 ret = dbcp_put->c_put(dbcp_put, &key, &data,
00401 flags == R_IAFTER ? DB_AFTER : DB_BEFORE);
00402 }
00403 if ((t_ret = dbcp_put->c_close(dbcp_put)) != 0 && ret == 0)
00404 ret = t_ret;
00405 break;
00406 case R_NOOVERWRITE:
00407 ret = dbp->put(dbp, NULL, &key, &data, DB_NOOVERWRITE);
00408 break;
00409 case R_SETCURSOR:
00410 if (dbp->type != DB_BTREE && dbp->type != DB_RECNO)
00411 goto einval;
00412
00413 if ((ret = dbp->put(dbp, NULL, &key, &data, 0)) != 0)
00414 break;
00415 ret =
00416 db185p->dbc->c_get(db185p->dbc, &key, &data, DB_SET_RANGE);
00417 break;
00418 default:
00419 goto einval;
00420 }
00421
00422 switch (ret) {
00423 case 0:
00424 key185->data = key.data;
00425 key185->size = key.size;
00426 return (0);
00427 case DB_KEYEXIST:
00428 return (1);
00429 }
00430
00431 if (0) {
00432 einval: ret = EINVAL;
00433 }
00434 __os_set_errno(ret);
00435 return (-1);
00436 }
00437
00438 static int
00439 db185_seq(db185p, key185, data185, flags)
00440 const DB185 *db185p;
00441 DBT185 *key185, *data185;
00442 u_int flags;
00443 {
00444 DB *dbp;
00445 DBT key, data;
00446 int ret;
00447
00448 dbp = db185p->dbp;
00449
00450 memset(&key, 0, sizeof(key));
00451 key.data = key185->data;
00452 key.size = key185->size;
00453 memset(&data, 0, sizeof(data));
00454 data.data = data185->data;
00455 data.size = data185->size;
00456
00457 switch (flags) {
00458 case R_CURSOR:
00459 flags = DB_SET_RANGE;
00460 break;
00461 case R_FIRST:
00462 flags = DB_FIRST;
00463 break;
00464 case R_LAST:
00465 if (dbp->type != DB_BTREE && dbp->type != DB_RECNO)
00466 goto einval;
00467 flags = DB_LAST;
00468 break;
00469 case R_NEXT:
00470 flags = DB_NEXT;
00471 break;
00472 case R_PREV:
00473 if (dbp->type != DB_BTREE && dbp->type != DB_RECNO)
00474 goto einval;
00475 flags = DB_PREV;
00476 break;
00477 default:
00478 goto einval;
00479 }
00480 switch (ret = db185p->dbc->c_get(db185p->dbc, &key, &data, flags)) {
00481 case 0:
00482 key185->data = key.data;
00483 key185->size = key.size;
00484 data185->data = data.data;
00485 data185->size = data.size;
00486 return (0);
00487 case DB_NOTFOUND:
00488 return (1);
00489 }
00490
00491 if (0) {
00492 einval: ret = EINVAL;
00493 }
00494 __os_set_errno(ret);
00495 return (-1);
00496 }
00497
00498 static int
00499 db185_sync(db185p, flags)
00500 const DB185 *db185p;
00501 u_int flags;
00502 {
00503 DB *dbp;
00504 int ret;
00505
00506 dbp = db185p->dbp;
00507
00508 switch (flags) {
00509 case 0:
00510 break;
00511 case R_RECNOSYNC:
00512
00513
00514
00515
00516 #define RSMSG \
00517 "Berkeley DB: DB 1.85's R_RECNOSYNC sync flag is not supported.\n"
00518 dbp->errx(dbp, "%s", RSMSG);
00519
00520 default:
00521 goto einval;
00522 }
00523
00524 if ((ret = dbp->sync(dbp, 0)) == 0)
00525 return (0);
00526
00527 if (0) {
00528 einval: ret = EINVAL;
00529 }
00530 __os_set_errno(ret);
00531 return (-1);
00532 }
00533
00534
00535
00536
00537
00538 static int
00539 db185_compare(dbp, a, b)
00540 DB *dbp;
00541 const DBT *a, *b;
00542 {
00543 DBT185 a185, b185;
00544
00545 a185.data = a->data;
00546 a185.size = a->size;
00547 b185.data = b->data;
00548 b185.size = b->size;
00549
00550 return (((DB185 *)dbp->api_internal)->compare(&a185, &b185));
00551 }
00552
00553
00554
00555
00556
00557 static size_t
00558 db185_prefix(dbp, a, b)
00559 DB *dbp;
00560 const DBT *a, *b;
00561 {
00562 DBT185 a185, b185;
00563
00564 a185.data = a->data;
00565 a185.size = a->size;
00566 b185.data = b->data;
00567 b185.size = b->size;
00568
00569 return (((DB185 *)dbp->api_internal)->prefix(&a185, &b185));
00570 }
00571
00572
00573
00574
00575
00576 static u_int32_t
00577 db185_hash(dbp, key, len)
00578 DB *dbp;
00579 const void *key;
00580 u_int32_t len;
00581 {
00582 return (((DB185 *)dbp->api_internal)->hash(key, (size_t)len));
00583 }