diff options
author | jbj <devnull@localhost> | 2000-04-17 12:28:58 +0000 |
---|---|---|
committer | jbj <devnull@localhost> | 2000-04-17 12:28:58 +0000 |
commit | 29fa01b329203018067a9f90fc859c05e406cc47 (patch) | |
tree | 6ba79aed08e3aaf833a27e699db2548b40206bcf /lib | |
parent | 3a7e311add683b212665084eb5e62a2a566fefc5 (diff) | |
download | rpm-29fa01b329203018067a9f90fc859c05e406cc47.tar.gz rpm-29fa01b329203018067a9f90fc859c05e406cc47.tar.bz2 rpm-29fa01b329203018067a9f90fc859c05e406cc47.zip |
Start composting db interfaces.
CVS patchset: 3680
CVS date: 2000/04/17 12:28:58
Diffstat (limited to 'lib')
-rw-r--r-- | lib/db0.c | 2 | ||||
-rw-r--r-- | lib/db3.c | 2 | ||||
-rw-r--r-- | lib/dbindex.c | 6 | ||||
-rw-r--r-- | lib/dbindex.h | 8 | ||||
-rw-r--r-- | lib/rpmdb.c | 335 |
5 files changed, 292 insertions, 61 deletions
@@ -26,6 +26,8 @@ static inline DBTYPE dbi_to_dbtype(DBI_TYPE dbitype) case DBI_BTREE: return DB_BTREE; case DBI_HASH: return DB_HASH; case DBI_RECNO: return DB_RECNO; + case DBI_QUEUE: return DB_HASH; /* XXX W2DO? */ + case DBI_UNKNOWN: return DB_HASH; /* XXX W2DO? */ } /*@notreached@*/ return DB_HASH; } @@ -44,6 +44,8 @@ static inline DBTYPE dbi_to_dbtype(DBI_TYPE dbitype) case DBI_BTREE: return DB_BTREE; case DBI_HASH: return DB_HASH; case DBI_RECNO: return DB_RECNO; + case DBI_QUEUE: return DB_QUEUE; + case DBI_UNKNOWN: return DB_UNKNOWN; } /*@notreached@*/ return DB_HASH; } diff --git a/lib/dbindex.c b/lib/dbindex.c index 7ea7dcf1a..b16e4d6bc 100644 --- a/lib/dbindex.c +++ b/lib/dbindex.c @@ -44,6 +44,7 @@ unsigned int dbiIndexSetCount(dbiIndexSet set) { return set->count; } +#ifdef DYING dbiIndexRecord dbiReturnIndexRecordInstance(unsigned int recOffset, unsigned int fileNumber) { dbiIndexRecord rec = xmalloc(sizeof(*rec)); rec->recOffset = recOffset; @@ -54,6 +55,7 @@ dbiIndexRecord dbiReturnIndexRecordInstance(unsigned int recOffset, unsigned int void dbiFreeIndexRecordInstance(dbiIndexRecord rec) { if (rec) free(rec); } +#endif unsigned int dbiIndexRecordOffset(dbiIndexSet set, int recno) { return set->recs[recno].recOffset; @@ -169,6 +171,7 @@ int dbiCloseIndex(dbiIndex dbi) { return rc; } +#ifdef DYING int dbiSyncIndex(dbiIndex dbi) { int rc; @@ -247,6 +250,7 @@ int dbiAppendIndexRecord(dbiIndexSet set, dbiIndexRecord rec) return 0; } +#endif dbiIndexSet dbiCreateIndexSet(void) { dbiIndexSet set = xmalloc(sizeof(*set)); @@ -263,6 +267,7 @@ void dbiFreeIndexSet(dbiIndexSet set) { } } +#ifdef DYING /* returns 1 on failure */ int dbiRemoveIndexRecord(dbiIndexSet set, dbiIndexRecord rec) { int from; @@ -284,3 +289,4 @@ int dbiRemoveIndexRecord(dbiIndexSet set, dbiIndexRecord rec) { return (numCopied == num); } +#endif diff --git a/lib/dbindex.h b/lib/dbindex.h index 3f053bdc6..c8f948d39 100644 --- a/lib/dbindex.h +++ b/lib/dbindex.h @@ -6,7 +6,7 @@ */ typedef void DBI_t; -typedef enum { DBI_BTREE, DBI_HASH, DBI_RECNO } DBI_TYPE; +typedef enum { DBI_BTREE, DBI_HASH, DBI_RECNO, DBI_QUEUE, DBI_UNKNOWN } DBI_TYPE; typedef /*@abstract@*/ struct _dbiIndexRecord * dbiIndexRecord; typedef /*@abstract@*/ struct _dbiIndex * dbiIndex; @@ -154,7 +154,7 @@ struct _dbiIndex { int dbi_flags; /*<! flags to use on open */ int dbi_perms; /*<! file permission to use on open */ int dbi_major; /*<! Berkeley db version major */ - unsigned int dbi_lastoffset; + unsigned int dbi_lastoffset; /*<! db0 with falloc.c needs this */ const char * dbi_file; /*<! name of index database */ void * dbi_db; /*<! Berkeley db[123] handle */ @@ -186,6 +186,7 @@ extern "C" { */ int dbiCloseIndex( /*@only@*/ dbiIndex dbi); +#ifdef DYING /** * Flush pending operations to disk. * @param dbi index database handle @@ -217,6 +218,7 @@ int dbiUpdateIndex(dbiIndex dbi, const char * str, dbiIndexSet set); * @return 0 success (always) */ int dbiAppendIndexRecord( /*@out@*/ dbiIndexSet set, dbiIndexRecord rec); +#endif /** * Create empty set of index database items. @@ -224,6 +226,7 @@ int dbiAppendIndexRecord( /*@out@*/ dbiIndexSet set, dbiIndexRecord rec); */ /*@only@*/ dbiIndexSet dbiCreateIndexSet(void); +#ifdef DYING /** * Remove element from set of index database items. * @param set set of index database items @@ -261,6 +264,7 @@ int dbiFreeCursor(dbiIndex dbi); * @param rec element of index database set. */ void dbiFreeIndexRecordInstance( /*@only@*/ dbiIndexRecord rec); +#endif #ifdef __cplusplus } diff --git a/lib/rpmdb.c b/lib/rpmdb.c index ea0b2c034..a267f15df 100644 --- a/lib/rpmdb.c +++ b/lib/rpmdb.c @@ -3,10 +3,10 @@ #include <sys/file.h> #include <signal.h> #include <sys/signal.h> +#include <assert.h> #include <rpmlib.h> -#include <rpmurl.h> -#include <rpmmacro.h> /* XXX for rpmGetPath */ +#include <rpmmacro.h> /* XXX for rpmGetPath/rpmGenPath */ #include "dbindex.h" /*@access dbiIndexSet@*/ @@ -55,6 +55,170 @@ struct _dbiIndex rpmdbi[] = { #define RPMDBI_MAX 8 }; +/** + * Destroy element of index database set. + * @param rec element of index database set. + */ +static void inline dbiFreeIndexRecordInstance(dbiIndexRecord rec) { + if (rec) free(rec); +} + +/** + * Create and initialize element of index database set. + * @param recOffset byte offset of header in db + * @param fileNumber file array index + * @return new element + */ +static dbiIndexRecord inline dbiReturnIndexRecordInstance(unsigned int recOffset, unsigned int fileNumber) { + dbiIndexRecord rec = xmalloc(sizeof(*rec)); + rec->recOffset = recOffset; + rec->fileNumber = fileNumber; + return rec; +} + +/** + * Flush pending operations to disk. + * @param dbi index database handle + */ +static inline int dbiSyncIndex(dbiIndex dbi) { + int rc; + + rc = (*dbi->dbi_vec->sync) (dbi, 0); + return rc; +} + +/** + * Return next index database key. + * @param dbi index database handle + * @param keyp address of first key + * @param keylenp address of first key size + * @return 0 success - fails if rec is not found + */ +static inline int dbiGetNextKey(dbiIndex dbi, void ** keyp, size_t * keylenp) { + int rc; + + if (dbi == NULL) + return 1; + + rc = (*dbi->dbi_vec->cget) (dbi, keyp, keylenp, NULL, NULL); + + return rc; +} + +/** + * Close cursor (if any); + * @param dbi index database handle + * @return 0 success + */ +static inline int dbiFreeCursor(dbiIndex dbi) { + int rc; + + if (dbi == NULL) + return 1; + + rc = (*dbi->dbi_vec->cclose) (dbi); + return rc; +} + +/** + * Return items that match criteria. + * @param dbi index database handle + * @param str search key + * @param set items retrieved from index database + * @return -1 error, 0 success, 1 not found + */ +static inline int dbiSearchIndex(dbiIndex dbi, const char * str, size_t len, + dbiIndexSet * set) +{ + int rc; + + rc = (*dbi->dbi_vec->SearchIndex) (dbi, str, len, set); + + switch (rc) { + case -1: + rpmError(RPMERR_DBGETINDEX, _("error getting record %s from %s"), + str, dbi->dbi_file); + break; + } + return rc; +} + +/** + * Change/delete items that match criteria. + * @param dbi index database handle + * @param str update key + * @param set items to update in index database + * @return 0 success, 1 not found + */ +static inline int dbiUpdateIndex(dbiIndex dbi, const char * str, dbiIndexSet set) { + int rc; + + rc = (*dbi->dbi_vec->UpdateIndex) (dbi, str, set); + + if (set->count) { + if (rc) { + rpmError(RPMERR_DBPUTINDEX, _("error storing record %s into %s"), + str, dbi->dbi_file); + } + } else { + if (rc) { + rpmError(RPMERR_DBPUTINDEX, _("error removing record %s into %s"), + str, dbi->dbi_file); + } + } + + return rc; +} + +/** + * Append element to set of index database items. + * @param set set of index database items + * @param rec item to append to set + * @return 0 success (always) + */ +static inline int dbiAppendIndexRecord(dbiIndexSet set, dbiIndexRecord rec) +{ + set->count++; + + if (set->count == 1) { + set->recs = xmalloc(set->count * sizeof(*(set->recs))); + } else { + set->recs = xrealloc(set->recs, set->count * sizeof(*(set->recs))); + } + set->recs[set->count - 1].recOffset = rec->recOffset; + set->recs[set->count - 1].fileNumber = rec->fileNumber; + + return 0; +} + +/* returns 1 on failure */ +/** + * Remove element from set of index database items. + * @param set set of index database items + * @param rec item to remove from set + * @return 0 success, 1 failure + */ +int dbiRemoveIndexRecord(dbiIndexSet set, dbiIndexRecord rec) { + int from; + int to = 0; + int num = set->count; + int numCopied = 0; + + for (from = 0; from < num; from++) { + if (rec->recOffset != set->recs[from].recOffset || + rec->fileNumber != set->recs[from].fileNumber) { + /* structure assignment */ + if (from != to) set->recs[to] = set->recs[from]; + to++; + numCopied++; + } else { + set->count--; + } + } + + return (numCopied == num); +} + /* XXX the signal handling in here is not thread safe */ /* the requiredbyIndex isn't stricly necessary. In a perfect world, we could @@ -67,7 +231,21 @@ struct _dbiIndex rpmdbi[] = { right area w/o a linear search through the database. */ struct rpmdb_s { - dbiIndex _dbi[RPMDBI_MAX]; + const char * db_root; + const char * db_home; + int db_flags; + DBI_TYPE db_type; + int db_mode; + int db_perms; + int db_major; + int db_mp_mmapsize; + int db_mp_size; + int db_cachesize; + int db_pagesize; + unsigned int db_h_ffactor; + unsigned int db_h_nelem; + unsigned int db_h_flags; + dbiIndex _dbi[RPMDBI_MAX]; #ifdef DYING #define nameIndex _dbi[RPMDBI_NAME] #define fileIndex _dbi[RPMDBI_FILE] @@ -94,45 +272,77 @@ static void unblockSignals(void) sigprocmask(SIG_SETMASK, &signalMask, NULL); } -static int openDbFile(const char * prefix, const char * dbpath, - const dbiIndex dbi, int justCheck, int mode, dbiIndex * dbip) +#define _DB_ROOT "" +#define _DB_HOME "%{_dbpath}" +#define _DB_FLAGS 0 +#define _DB_TYPE DBI_UNKNOWN +#define _DB_MODE 0 +#define _DB_PERMS 0644 +#define _DB_MAJOR -1 +#define _DB_MP_MMAPSIZE 16 * 1024 * 1024 +#define _DB_MP_SIZE 2 * 1024 * 1024 +#define _DB_CACHESIZE 0 +#define _DB_PAGESIZE 0 +#define _DB_H_FFACTOR 0 +#define _DB_H_NELEM 0 +#define _DB_H_FLAGS 0 + +static struct rpmdb_s dbTemplate = { + _DB_ROOT, _DB_HOME, _DB_FLAGS, + _DB_TYPE, _DB_MODE, _DB_PERMS, _DB_MAJOR, + _DB_MAJOR, _DB_MP_MMAPSIZE, _DB_MP_SIZE, _DB_CACHESIZE, _DB_PAGESIZE, + _DB_H_FFACTOR, _DB_H_NELEM, _DB_H_FLAGS +}; + +void rpmdbClose (rpmdb db) { - char * filename, * fn; - int len; + int dbix; - if (dbi == NULL || dbip == NULL) - return 1; - *dbip = NULL; - - len = (prefix ? strlen(prefix) : 0) + - strlen(dbpath) + strlen(dbi->dbi_basename) + 1; - fn = filename = alloca(len); - *fn = '\0'; - switch (urlIsURL(dbpath)) { - case URL_IS_UNKNOWN: - if (prefix && *prefix && - !(prefix[0] == '/' && prefix[1] == '\0' && dbpath[0] == '/')) - fn = stpcpy(fn, prefix); - break; - default: - break; + for (dbix = RPMDBI_MAX; --dbix >= RPMDBI_MIN; ) { + if (db->_dbi[dbix] == NULL) + continue; + dbiCloseIndex(db->_dbi[dbix]); + db->_dbi[dbix] = NULL; } - fn = stpcpy(fn, dbpath); - if (fn > filename && !(fn[-1] == '/' || dbi->dbi_basename[0] == '/')) - fn = stpcpy(fn, "/"); - fn = stpcpy(fn, dbi->dbi_basename); - - if (!justCheck || !rpmfileexists(filename)) { - if ((*dbip = dbiOpenIndex(filename, mode, dbi)) == NULL) - return 1; + if (db->db_root) { + xfree(db->db_root); + db->db_root = NULL; } - - return 0; + if (db->db_home) { + xfree(db->db_home); + db->db_home = NULL; + } + free(db); } -static /*@only@*/ rpmdb newRpmdb(void) +static /*@only@*/ rpmdb newRpmdb(const char * root, const char * home, + int mode, int perms, int flags) { rpmdb db = xcalloc(sizeof(*db), 1); + + *db = dbTemplate; /* structure assignment */ + + if (!(perms & 0600)) perms = 0644; /* XXX sanity */ + + db->db_root = (root ? root : ""); /* accept NULL as a valid prefix */ + if (mode >= 0) db->db_mode = mode; + if (perms >= 0) db->db_perms = perms; + if (flags >= 0) db->db_flags = flags; + + if (db->db_root) + db->db_root = rpmGetPath(db->db_root, NULL); + if (db->db_home) { + db->db_home = rpmGetPath(db->db_home, NULL); + if (!(db->db_home && db->db_home[0] != '%')) { + rpmError(RPMERR_DBOPEN, _("no dbpath has been set")); + goto errxit; + } + } + return db; + +errxit: + if (db) + rpmdbClose(db); return db; } @@ -141,7 +351,7 @@ int openDatabase(const char * prefix, const char * dbpath, rpmdb *dbp, { rpmdb db; int rc; - int justcheck = flags & RPMDB_FLAG_JUSTCHECK; + int justCheck = flags & RPMDB_FLAG_JUSTCHECK; int minimal = flags & RPMDB_FLAG_MINIMAL; if (dbp) @@ -149,25 +359,25 @@ int openDatabase(const char * prefix, const char * dbpath, rpmdb *dbp, if (mode & O_WRONLY) return 1; - if (!(perms & 0600)) /* XXX sanity */ - perms = 0644; - - /* we should accept NULL as a valid prefix */ - if (!prefix) prefix=""; - - db = newRpmdb(); + db = newRpmdb(prefix, dbpath, mode, perms, flags); { int dbix; rc = 0; for (dbix = RPMDBI_MIN; rc == 0 && dbix < RPMDBI_MAX; dbix++) { dbiIndex dbiTemplate; + const char * filename; dbiTemplate = rpmdbi + dbix; - rc = openDbFile(prefix, dbpath, dbiTemplate, justcheck, mode, - &db->_dbi[dbix]); - if (rc) + filename = rpmGenPath(db->db_root, db->db_home, + dbiTemplate->dbi_basename); + + if (!justCheck || !rpmfileexists(filename)) { + db->_dbi[dbix] = dbiOpenIndex(filename, db->db_mode, dbiTemplate); + } + + if (db->_dbi[dbix] == NULL) continue; switch (dbix) { @@ -184,7 +394,7 @@ int openDatabase(const char * prefix, const char * dbpath, rpmdb *dbp, * XXX FIXME: db->fileindex can be NULL under pathological (e.g. mixed * XXX db1/db2 linkage) conditions. */ - if (!justcheck && !dbiGetNextKey(db->_dbi[RPMDBI_FILE], &keyp, NULL)) { + if (!justCheck && !dbiGetNextKey(db->_dbi[RPMDBI_FILE], &keyp, NULL)) { const char * akey; akey = keyp; if (strchr(akey, '/')) { @@ -202,7 +412,7 @@ int openDatabase(const char * prefix, const char * dbpath, rpmdb *dbp, } exit: - if (!(rc || justcheck || dbp == NULL)) + if (!(rc || justCheck || dbp == NULL)) *dbp = db; else rpmdbClose(db); @@ -210,6 +420,7 @@ exit: return rc; } +#ifdef DYING static int doRpmdbOpen (const char * prefix, /*@out@*/ rpmdb * dbp, int mode, int perms, int flags) { @@ -224,36 +435,42 @@ static int doRpmdbOpen (const char * prefix, /*@out@*/ rpmdb * dbp, xfree(dbpath); return rc; } +#endif /* XXX called from python/upgrade.c */ int rpmdbOpenForTraversal(const char * prefix, rpmdb * dbp) { +#ifdef DYING return doRpmdbOpen(prefix, dbp, O_RDONLY, 0644, RPMDB_FLAG_MINIMAL); +#else + return openDatabase(prefix, NULL, dbp, O_RDONLY, 0644, RPMDB_FLAG_MINIMAL); +#endif } /* XXX called from python/rpmmodule.c */ int rpmdbOpen (const char * prefix, rpmdb *dbp, int mode, int perms) { +#ifdef DYING return doRpmdbOpen(prefix, dbp, mode, perms, 0); +#else + return openDatabase(prefix, NULL, dbp, mode, perms, 0); +#endif } int rpmdbInit (const char * prefix, int perms) { rpmdb db; +#ifdef DYING return doRpmdbOpen(prefix, &db, (O_CREAT | O_RDWR), perms, RPMDB_FLAG_JUSTCHECK); -} - -void rpmdbClose (rpmdb db) -{ - int dbix; - - for (dbix = RPMDBI_MAX; --dbix >= RPMDBI_MIN; ) { - if (db->_dbi[dbix] == NULL) - continue; - dbiCloseIndex(db->_dbi[dbix]); - db->_dbi[dbix] = NULL; +#else + int rc; + rc = openDatabase(prefix, NULL, &db, (O_CREAT | O_RDWR), perms, RPMDB_FLAG_JUSTCHECK); + if (db) { + rpmdbClose(db); + db = NULL; } - free(db); + return rc; +#endif } Header rpmdbGetRecord(rpmdb db, unsigned int offset) |