11 /*@access dbiIndexSet@*/
15 #if DB_VERSION_MAJOR == 2
17 #define _mymemset(_a, _b, _c) memset((_a), (_b), (_c))
19 static inline DBTYPE dbi_to_dbtype(DBI_TYPE dbitype)
22 case DBI_BTREE: return DB_BTREE;
23 case DBI_HASH: return DB_HASH;
24 case DBI_RECNO: return DB_RECNO;
26 /*@notreached@*/ return DB_HASH;
29 static inline /*@observer@*/ /*@null@*/ DB * GetDB(dbiIndex dbi) {
30 return ((DB *)dbi->dbi_db);
33 #if defined(__USE_DB2) || defined(__USE_DB3)
34 #if defined(__USE_DB2)
35 static /*@observer@*/ const char * db_strerror(int error)
38 return ("Successful return: 0");
40 return (strerror(error));
44 return ("DB_INCOMPLETE: Cache flush was unable to complete");
46 return ("DB_KEYEMPTY: Non-existent key/data pair");
48 return ("DB_KEYEXIST: Key/data pair already exists");
49 case DB_LOCK_DEADLOCK:
50 return ("DB_LOCK_DEADLOCK: Locker killed to resolve a deadlock");
51 case DB_LOCK_NOTGRANTED:
52 return ("DB_LOCK_NOTGRANTED: Lock not granted");
54 return ("DB_NOTFOUND: No matching key/data pair found");
55 #if defined(__USE_DB3)
57 return ("DB_OLDVERSION: Database requires a version upgrade");
59 return ("DB_RUNRECOVERY: Fatal error, run database recovery");
62 return ("DB_LOCK_NOTHELD:");
64 return ("DB_REGISTERED:");
70 * Room for a 64-bit number + slop. This buffer is only used
71 * if we're given an unknown error, which should never happen.
72 * Note, however, we're no longer thread-safe if it does.
76 (void)snprintf(ebuf, sizeof(ebuf), "Unknown error: %d", error);
83 static int db_env_create(DB_ENV **dbenvp, int foo)
89 dbenv = xcalloc(1, sizeof(*dbenv));
94 #endif /* __USE_DB2 */
96 static int cvtdberr(dbiIndex dbi, const char * msg, int error, int printit) {
107 fprintf(stderr, "*** db%d %s rc %d %s\n", dbi->dbi_major, msg,
108 rc, db_strerror(error));
114 static int db_init(dbiIndex dbi, const char *home, int dbflags,
115 DB_ENV **dbenvp, void **dbinfop)
117 DB_ENV *dbenv = NULL;
118 FILE * dberrfile = stderr;
119 const char * dberrpfx = "rpmdb";
120 int dbcachesize = 1024 * 1024;
121 int dbpagesize = 32 * 1024; /* 0 - 64K */
124 if (dbenvp == NULL || dbinfop == NULL)
127 rc = db_env_create(&dbenv, 0);
128 rc = cvtdberr(dbi, "db_env_create", rc, _debug);
132 #if defined(__USE_DB3)
134 /* dbenv->set_errcall(???) */
135 xx = dbenv->set_errfile(dberrfile);
136 xx = cvtdberr(dbi, "dbenv->set_errfile", xx, _debug);
137 xx = dbenv->set_errpfx(dberrpfx);
138 xx = cvtdberr(dbi, "dbenv->set_errpfx", xx, _debug);
139 /* dbenv->set_paniccall(???) */
140 /* dbenv->set_verbose(???) */
141 /* dbenv->set_lg_max(???) */
142 /* dbenv->set_lk_conflicts(???) */
143 /* dbenv->set_lk_detect(???) */
144 /* dbenv->set_lk_max(???) */
145 /* dbenv->set_mp_mmapsize(???) */
146 xx = dbenv->set_cachesize(dbcachesize);
147 xx = cvtdberr(dbi, "dbenv->set_cachesize", xx, _debug);
148 /* dbenv->set_tx_max(???) */
149 /* dbenv->set_tx_recover(???) */
152 dbenv->db_errfile = dberrfile;
153 dbenv->db_errpfx = dberrpfx;
154 dbenv->mp_size = dbcachesize;
157 #define _DBFMASK (DB_CREATE|DB_NOMMAP|DB_THREAD)
159 #if defined(__USE_DB3)
160 rc = dbenv->open(dbenv, home, NULL, (dbflags & _DBFMASK), 0);
161 rc = cvtdberr(dbi, "dbenv->open", rc, _debug);
164 xx = db->set_pagesize(db, dbpagesize)
165 xx = cvtdberr(dbi, "db->set_pagesize", xx, _debug);
168 rc = db_appinit(home, NULL, dbenv, (dbflags & _DBFMASK));
169 rc = cvtdberr(dbi, "db_appinit", rc, _debug);
172 { DB_INFO * dbinfo = xcalloc(1, sizeof(*dbinfo));
174 dbinfo->db_pagesize = dbpagesize;
185 #if defined(__USE_DB3)
187 xx = dbenv->close(dbenv);
188 xx = cvtdberr(dbi, "dbenv->close", xx, _debug);
191 if (dbenv) free(dbenv);
195 #endif /* __USE_DB2 || __USE_DB3 */
197 int db2open(dbiIndex dbi)
201 #if defined(__USE_DB2) || defined(__USE_DB3)
202 char * dbhome = NULL;
204 DB_ENV * dbenv = NULL;
205 void * dbinfo = NULL;
208 dbflags = ( !(dbi->dbi_flags & O_RDWR) ? DB_RDONLY :
209 ((dbi->dbi_flags & O_CREAT) ? DB_CREATE : 0));
211 rc = db_init(dbi, dbhome, dbflags, &dbenv, &dbinfo);
214 #if defined(__USE_DB3)
215 rc = db_create(&db, dbenv, 0);
216 rc = cvtdberr(dbi, "db_create", rc, _debug);
218 rc = db->open(db, dbi->dbi_file, NULL, dbi_to_dbtype(dbi->dbi_type),
219 dbflags, dbi->dbi_perms);
220 rc = cvtdberr(dbi, "db->open", rc, _debug);
223 rc = db_open(dbi->dbi_file, dbi_to_dbtype(dbi->dbi_type), dbflags,
224 dbi->dbi_perms, dbenv, dbinfo, &db);
225 rc = cvtdberr(dbi, "db_open", rc, _debug);
226 #endif /* __USE_DB3 */
230 dbi->dbi_dbenv = dbenv;
231 dbi->dbi_dbinfo = dbinfo;
234 dbi->dbi_db = dbopen(dbi->dbi_file, dbi->dbi_flags, dbi->dbi_perms,
235 dbi_to_dbtype(dbi->dbi_type), dbi->dbi_openinfo);
236 #endif /* __USE_DB2 || __USE_DB3 */
238 if (rc == 0 && dbi->dbi_db != NULL) {
240 dbi->dbi_major = DB_VERSION_MAJOR;
241 dbi->dbi_minor = DB_VERSION_MINOR;
242 dbi->dbi_patch = DB_VERSION_PATCH;
249 int db2close(dbiIndex dbi, unsigned int flags) {
250 DB * db = GetDB(dbi);
253 #if defined(__USE_DB2) || defined(__USE_DB3)
255 if (dbi->dbi_dbcursor) {
256 DBC * dbcursor = (DBC *)dbi->dbi_dbcursor;
257 xx = dbcursor->c_close(dbcursor);
258 xx = cvtdberr(dbi, "dbcursor->c_close", xx, _debug);
259 dbi->dbi_dbcursor = NULL;
263 rc = db->close(db, 0);
264 rc = cvtdberr(dbi, "db->close", rc, _debug);
265 db = dbi->dbi_db = NULL;
268 if (dbi->dbi_dbinfo) {
269 free(dbi->dbi_dbinfo);
270 dbi->dbi_dbinfo = NULL;
272 if (dbi->dbi_dbenv) {
273 DB_ENV * dbenv = (DB_ENV *)dbi->dbi_dbenv;
274 #if defined(__USE_DB3)
275 xx = dbenv->close(dbenv);
276 xx = cvtdberr(dbi, "dbenv->close", xx, _debug);
278 xx = db_appexit(dbenv);
279 xx = cvtdberr(dbi, "db_appexit", xx, _debug);
281 free(dbi->dbi_dbenv);
282 dbi->dbi_dbenv = NULL;
291 int db2sync(dbiIndex dbi, unsigned int flags) {
292 DB * db = GetDB(dbi);
295 #if defined(__USE_DB2) || defined(__USE_DB3)
296 rc = db->sync(db, flags);
297 rc = cvtdberr(dbi, "db->sync", rc, _debug);
299 rc = db->sync(db, flags);
305 int db2GetFirstKey(dbiIndex dbi, const char ** keyp) {
310 if (dbi == NULL || dbi->dbi_db == NULL)
314 _mymemset(&key, 0, sizeof(key));
315 _mymemset(&data, 0, sizeof(data));
320 #if defined(__USE_DB2) || defined(__USE_DB3)
321 { DBC * dbcursor = NULL;
322 rc = db->cursor(db, NULL, &dbcursor);
323 rc = cvtdberr(dbi, "db->cursor", rc, _debug);
325 rc = dbcursor->c_get(dbcursor, &key, &data, DB_FIRST);
326 rc = cvtdberr(dbi, "dbcursor->c_get", rc, _debug);
329 xx = dbcursor->c_close(dbcursor);
330 xx = cvtdberr(dbi, "dbcursor->c_close", xx, _debug);
334 rc = db->seq(db, &key, &data, R_FIRST);
337 if (rc == 0 && keyp) {
338 char *k = xmalloc(key.size + 1);
339 memcpy(k, key.data, key.size);
347 int db2SearchIndex(dbiIndex dbi, const char * str, dbiIndexSet * set) {
349 DB * db = GetDB(dbi);
352 if (set) *set = NULL;
353 _mymemset(&key, 0, sizeof(key));
354 _mymemset(&data, 0, sizeof(data));
356 key.data = (void *)str;
357 key.size = strlen(str);
361 #if defined(__USE_DB2) || defined(__USE_DB3)
362 rc = db->get(db, NULL, &key, &data, 0);
363 rc = cvtdberr(dbi, "db->get", rc, _debug);
365 rc = db->get(db, &key, &data, 0);
368 if (rc == 0 && set) {
369 *set = dbiCreateIndexSet();
370 (*set)->recs = xmalloc(data.size);
371 memcpy((*set)->recs, data.data, data.size);
372 (*set)->count = data.size / sizeof(*(*set)->recs);
378 int db2UpdateIndex(dbiIndex dbi, const char * str, dbiIndexSet set) {
380 DB * db = GetDB(dbi);
383 _mymemset(&key, 0, sizeof(key));
384 key.data = (void *)str;
385 key.size = strlen(str);
390 _mymemset(&data, 0, sizeof(data));
391 data.data = set->recs;
392 data.size = set->count * sizeof(*(set->recs));
394 #if defined(__USE_DB2) || defined(__USE_DB3)
395 rc = db->put(db, NULL, &key, &data, 0);
396 rc = cvtdberr(dbi, "db->put", rc, _debug);
398 rc = db->put(db, &key, &data, 0);
403 #if defined(__USE_DB2) || defined(__USE_DB3)
404 rc = db->del(db, NULL, &key, 0);
405 rc = cvtdberr(dbi, "db->del", rc, _debug);
407 rc = db->del(db, &key, 0);
415 #endif /* DB_VERSION_MAJOR == 2 */