bdbobj.c
上传用户:s81996212
上传日期:2007-01-04
资源大小:722k
文件大小:5k
- /*
- ** Copyright 1998 - 2000 Double Precision, Inc. See COPYING for
- ** distribution information.
- */
- #if HAVE_CONFIG_H
- #include "config.h"
- #endif
- #include "bdbobj.h"
- #include <fcntl.h>
- #include <string.h>
- #include <stdlib.h>
- #if HAVE_FCNTL_H
- #include <fcntl.h>
- #endif
- #if HAVE_UNISTD_H
- #include <unistd.h>
- #endif
- void bdbobj_init(struct bdbobj *obj)
- {
- obj->has_dbf=0;
- #if DB_VERSION_MAJOR >= 2
- obj->has_dbc=0;
- #endif
- }
- void bdbobj_close(struct bdbobj *obj)
- {
- #if DB_VERSION_MAJOR >= 2
- if (obj->has_dbc)
- {
- (*obj->dbc->c_close)(obj->dbc);
- obj->has_dbc=0;
- }
- #endif
- if ( obj->has_dbf )
- {
- #if DB_VERSION_MAJOR < 2
- (*obj->dbf->close)(obj->dbf);
- #else
- (*obj->dbf->close)(obj->dbf, 0);
- #endif
- obj->has_dbf=0;
- }
- }
- int bdbobj_open(struct bdbobj *obj, const char *filename, const char *modestr)
- {
- #if DB_VERSION_MAJOR < 2
- int flags=O_RDONLY;
- #else
- int flags=DB_RDONLY;
- #endif
- DBTYPE dbtype=DB_HASH;
- for ( ; *modestr; modestr++)
- switch (*modestr) {
- case 'c':
- case 'C':
- #if DB_VERSION_MAJOR < 2
- flags=O_RDWR|O_CREAT;
- #else
- flags=DB_CREATE;
- #endif
- break;
- case 'w':
- case 'W':
- #if DB_VERSION_MAJOR < 2
- flags=O_RDWR;
- #else
- flags=0;
- #endif
- break;
- case 'n':
- case 'N':
- #if DB_VERSION_MAJOR < 2
- flags=O_RDWR|O_CREAT|O_TRUNC;
- #else
- flags=DB_CREATE|DB_TRUNCATE;
- #endif
- break;
- case 'b':
- case 'B':
- dbtype=DB_BTREE;
- break;
- case 'e':
- case 'E':
- dbtype=DB_RECNO;
- break;
- }
- bdbobj_close(obj);
- #if DB_VERSION_MAJOR < 3
- #if DB_VERSION_MAJOR < 2
- if ( (obj->dbf=dbopen(filename, flags, 0664, dbtype, 0)) != 0)
- #else
- if ( db_open(filename, dbtype, flags, 0664, 0, 0, &obj->dbf) == 0)
- #endif
- #else
- obj->dbf=0;
- if (db_create(&obj->dbf, NULL, 0) == 0)
- {
- if ( (*obj->dbf->open)(obj->dbf, filename, NULL,
- dbtype, flags, 0664))
- {
- (*obj->dbf->close)(obj->dbf, DB_NOSYNC);
- obj->dbf=0;
- }
- }
- if (obj->dbf)
- #endif
- {
- #ifdef FD_CLOEXEC
- #if DB_VERSION_MAJOR < 2
- int fd=(*obj->dbf->fd)(obj->dbf);
- #else
- int fd;
- if ((*obj->dbf->fd)(obj->dbf, &fd))
- fd= -1;
- #endif
- if (fd >= 0) fcntl(fd, F_SETFD, FD_CLOEXEC);
- #endif
- obj->has_dbf=1;
- return (0);
- }
- return (-1);
- }
- int bdbobj_store(struct bdbobj *obj, const char *key, size_t keylen,
- const char *data,
- size_t datalen,
- const char *mode)
- {
- DBT dkey, dval;
- memset(&dkey, 0, sizeof(dkey));
- memset(&dval, 0, sizeof(dval));
- dkey.data=(void *)key;
- dkey.size=keylen;
- dval.data=(void *)data;
- dval.size=datalen;
- #if DB_VERSION_MAJOR < 2
- return (obj->has_dbf ? (*obj->dbf->put)(obj->dbf, &dkey, &dval, (
- *mode == 'i' || *mode == 'I' ? R_NOOVERWRITE:0)):-1);
- #else
- return (obj->has_dbf ? (*obj->dbf->put)(obj->dbf, 0, &dkey, &dval, (
- *mode == 'i' || *mode == 'I' ? DB_NOOVERWRITE:0)):-1);
- #endif
- }
- static char *doquery(struct bdbobj *obj,
- const char *, size_t, size_t *, const char *);
- char *bdbobj_fetch(struct bdbobj *obj, const char *key, size_t keylen,
- size_t *datalen, const char *options)
- {
- char *p=doquery(obj, key, keylen, datalen, options);
- char *q;
- if (!p) return (0);
- q=(char *)malloc(*datalen);
- if (!q) return (0);
- memcpy(q, p, *datalen);
- return (q);
- }
- char *dofetch(struct bdbobj *, const char *, size_t, size_t *);
- static char *doquery(struct bdbobj *obj, const char *key, size_t keylen,
- size_t *datalen, const char *options)
- {
- char *p;
- for (;;)
- {
- if ((p=dofetch(obj, key, keylen, datalen)) != 0)
- return (p);
- if (!options) break;
- if (*options == 'I')
- {
- while (keylen && key[--keylen] != '.')
- ;
- if (!keylen) break;
- continue;
- }
- if (*options == 'D')
- {
- size_t i;
- for (i=0; i<keylen; i++)
- if (key[i] == '@') { ++i; break; }
- if (i < keylen)
- {
- if ((p=dofetch(obj, key, i, datalen)) != 0)
- return (p);
- key += i;
- keylen -= i;
- continue;
- }
- for (i=0; i<keylen; i++)
- if (key[i] == '.') { ++i; break; }
- if (i < keylen)
- {
- key += i;
- keylen -= i;
- continue;
- }
- break;
- }
- break;
- }
- return (0);
- }
- char *dofetch(struct bdbobj *obj, const char *key, size_t keylen,
- size_t *datalen)
- {
- DBT dkey, val;
- if (!obj->has_dbf) return (0);
- memset(&dkey, 0, sizeof(dkey));
- memset(&val, 0, sizeof(val));
- dkey.data=(void *)key;
- dkey.size=keylen;
- #if DB_VERSION_MAJOR < 2
- if ( (*obj->dbf->get)(obj->dbf, &dkey, &val, 0)) return (0);
- #else
- if ( (*obj->dbf->get)(obj->dbf, 0, &dkey, &val, 0)) return (0);
- #endif
- *datalen=val.size;
- return ((char *)val.data);
- }
- int bdbobj_exists(struct bdbobj *obj, const char *key, size_t keylen)
- {
- size_t datalen;
- char *p=doquery(obj, key, keylen, &datalen, 0);
- return (p ? 1:0);
- }