summaryrefslogtreecommitdiff
path: root/rpmdb
diff options
context:
space:
mode:
authorjbj <devnull@localhost>2001-06-06 12:36:31 +0000
committerjbj <devnull@localhost>2001-06-06 12:36:31 +0000
commitf0a67ca8b05a635340213158e9086b3bdf5443fd (patch)
treef3851640877936a02f4c92571116ddb72ebc8418 /rpmdb
parentc635bbf0aedc73aa138078ffe1c761507de9d91a (diff)
downloadrpm-f0a67ca8b05a635340213158e9086b3bdf5443fd.tar.gz
rpm-f0a67ca8b05a635340213158e9086b3bdf5443fd.tar.bz2
rpm-f0a67ca8b05a635340213158e9086b3bdf5443fd.zip
- permit duplicates for btree indices.
CVS patchset: 4843 CVS date: 2001/06/06 12:36:31
Diffstat (limited to 'rpmdb')
-rw-r--r--rpmdb/Makefile.am3
-rw-r--r--rpmdb/db3.c48
-rw-r--r--rpmdb/dbconfig.c3
-rw-r--r--rpmdb/rpmdb.c185
-rw-r--r--rpmdb/rpmdb.h26
-rw-r--r--rpmdb/tdbi.c78
6 files changed, 230 insertions, 113 deletions
diff --git a/rpmdb/Makefile.am b/rpmdb/Makefile.am
index c80af813c..288cc6de5 100644
--- a/rpmdb/Makefile.am
+++ b/rpmdb/Makefile.am
@@ -58,5 +58,8 @@ sources:
lclint:
lclint $(DEFS) $(INCLUDES) $(librpmdb_la_SOURCES)
+tdbi: librpmdb.la tdbi.o
+ $(LINK) -all-static $@.o $< $(mylibpaths) $(mylibs) $(LIBS)
+
tfalloc: librpmdb.la tfalloc.o
$(LINK) -all-static $@.o $< $(mylibpaths) $(mylibs) $(LIBS)
diff --git a/rpmdb/db3.c b/rpmdb/db3.c
index 855e12c9c..4bb77f2f2 100644
--- a/rpmdb/db3.c
+++ b/rpmdb/db3.c
@@ -591,8 +591,8 @@ static int db3cdel(dbiIndex dbi, DBC * dbcursor,
}
static int db3cget(dbiIndex dbi, DBC * dbcursor,
- void ** keyp, size_t * keylen,
- void ** datap, size_t * datalen,
+ /*@null@*/ void ** keyp, /*@null@*/ size_t * keylen,
+ /*@null@*/ void ** datap, /*@null@*/ size_t * datalen,
/*@unused@*/ unsigned int flags)
/*@modifies *keyp, *keylen, *datap, *datalen, fileSystem @*/
{
@@ -996,13 +996,6 @@ static int db3open(/*@keep@*/ rpmdb rpmdb, int rpmtag, dbiIndex * dbip)
rc = cvtdberr(dbi, "db->set_h_ffactor", rc, _debug);
if (rc) break;
}
-#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR < 2
- if (dbi->dbi_h_hash_fcn) {
- rc = db->set_h_hash(db, dbi->dbi_h_hash_fcn);
- rc = cvtdberr(dbi, "db->set_h_hash", rc, _debug);
- if (rc) break;
- }
-#endif
if (dbi->dbi_h_nelem) {
rc = db->set_h_nelem(db, dbi->dbi_h_nelem);
rc = cvtdberr(dbi, "db->set_h_nelem", rc, _debug);
@@ -1013,8 +1006,13 @@ static int db3open(/*@keep@*/ rpmdb rpmdb, int rpmtag, dbiIndex * dbip)
rc = cvtdberr(dbi, "db->set_h_flags", rc, _debug);
if (rc) break;
}
-/* XXX db-3.2.9 has added a DB arg to the callback. */
-#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR < 2
+/* XXX db-3.2.9 has added a DB arg to the call. */
+#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR > 2
+ if (dbi->dbi_h_hash_fcn) {
+ rc = db->set_h_hash(db, dbi->dbi_h_hash_fcn);
+ rc = cvtdberr(dbi, "db->set_h_hash", rc, _debug);
+ if (rc) break;
+ }
if (dbi->dbi_h_dup_compare_fcn) {
rc = db->set_dup_compare(db, dbi->dbi_h_dup_compare_fcn);
rc = cvtdberr(dbi, "db->set_dup_compare", rc, _debug);
@@ -1023,6 +1021,34 @@ static int db3open(/*@keep@*/ rpmdb rpmdb, int rpmtag, dbiIndex * dbip)
#endif
break;
case DB_BTREE:
+ if (dbi->dbi_bt_flags) {
+ rc = db->set_flags(db, dbi->dbi_bt_flags);
+ rc = cvtdberr(dbi, "db->set_bt_flags", rc, _debug);
+ if (rc) break;
+ }
+ if (dbi->dbi_bt_minkey) {
+ rc = db->set_bt_minkey(db, dbi->dbi_bt_minkey);
+ rc = cvtdberr(dbi, "db->set_bt_minkey", rc, _debug);
+ if (rc) break;
+ }
+/* XXX db-3.2.9 has added a DB arg to the call. */
+#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR > 2
+ if (dbi->dbi_bt_compare_fcn) {
+ rc = db->set_bt_compare(db, dbi->dbi_bt_compare_fcn);
+ rc = cvtdberr(dbi, "db->set_bt_compare", rc, _debug);
+ if (rc) break;
+ }
+ if (dbi->dbi_bt_dup_compare_fcn) {
+ rc = db->set_dup_compare(db, dbi->dbi_bt_dup_compare_fcn);
+ rc = cvtdberr(dbi, "db->set_dup_compare", rc, _debug);
+ if (rc) break;
+ }
+ if (dbi->dbi_bt_prefix_fcn) {
+ rc = db->set_bt_prefix(db, dbi->dbi_bt_prefix_fcn);
+ rc = cvtdberr(dbi, "db->set_bt_prefix", rc, _debug);
+ if (rc) break;
+ }
+#endif
break;
case DB_RECNO:
if (dbi->dbi_re_delim) {
diff --git a/rpmdb/dbconfig.c b/rpmdb/dbconfig.c
index 74bb782a5..782b1727c 100644
--- a/rpmdb/dbconfig.c
+++ b/rpmdb/dbconfig.c
@@ -487,6 +487,9 @@ dbiIndex db3New(rpmdb rpmdb, int rpmtag)
dbi->dbi_use_cursors = 1; /* Cursors are always used now. */
+ if ((dbi->dbi_bt_flags | dbi->dbi_h_flags) & DB_DUP)
+ dbi->dbi_permit_dups = 1;
+
return dbi;
}
diff --git a/rpmdb/rpmdb.c b/rpmdb/rpmdb.c
index 858b70ee1..3a1aca5af 100644
--- a/rpmdb/rpmdb.c
+++ b/rpmdb/rpmdb.c
@@ -44,14 +44,14 @@ static int dbiTagsMax = 0;
/**
* Return dbi index used for rpm tag.
* @param rpmtag rpm header tag
- * @return dbi index, -1 on error
+ * @return dbi index, -1 on error
*/
-static int dbiTagToDbix(int rpmtag) /*@*/
+static int dbiTagToDbix(int rpmtag)
+ /*@*/
{
int dbix;
- if (dbiTags == NULL || dbiTagsMax <= 0)
- return -1;
+ if (dbiTags != NULL)
for (dbix = 0; dbix < dbiTagsMax; dbix++) {
if (rpmtag == dbiTags[dbix])
return dbix;
@@ -73,20 +73,19 @@ static void dbiTagsInit(void)
/*@-nullpass@*/
dbiTagStr = rpmExpand("%{_dbi_tags}", NULL);
+ /*@=nullpass@*/
if (!(dbiTagStr && *dbiTagStr && *dbiTagStr != '%')) {
dbiTagStr = _free(dbiTagStr);
dbiTagStr = xstrdup(_dbiTagStr_default);
}
- /*@=nullpass@*/
- if (dbiTagsMax || dbiTags) {
- dbiTags = _free(dbiTags);
- dbiTagsMax = 0;
- }
+ /* Discard previous values. */
+ dbiTags = _free(dbiTags);
+ dbiTagsMax = 0;
/* Always allocate package index */
- dbiTagsMax = 1;
- dbiTags = xcalloc(1, dbiTagsMax * sizeof(*dbiTags));
+ dbiTags = xcalloc(1, sizeof(*dbiTags));
+ dbiTags[dbiTagsMax++] = RPMDBI_PACKAGES;
for (o = dbiTagStr; o && *o; o = oe) {
while (*o && xisspace(*o))
@@ -172,14 +171,21 @@ fprintf(stderr, "--- RMW %s (%s:%u)\n", tagName(dbi->dbi_rpmtag), f, l);
return (*dbi->dbi_vec->cclose) (dbi, dbcursor, flags);
}
-#define printable(_c) (((_c) >= ' ') && ((_c) <= '\177'))
+static int printable(const void * ptr, size_t len) /*@*/
+{
+ const char * s = ptr;
+ int i;
+ for (i = 0; i < len; i++, s++)
+ if (!(*s >= ' ' && *s <= '~')) return 0;
+ return 1;
+}
INLINE int dbiDel(dbiIndex dbi, DBC * dbcursor, const void * keyp, size_t keylen, unsigned int flags)
{
int NULkey;
int rc;
- /* XXX make sure that keylen is correct for "" lookup */
+ /* Make sure that keylen is correct for "" lookup. */
NULkey = (keyp && *((char *)keyp) == '\0' && keylen == 0);
if (NULkey) keylen++;
rc = (*dbi->dbi_vec->cdel) (dbi, dbcursor, keyp, keylen, flags);
@@ -197,13 +203,13 @@ INLINE int dbiGet(dbiIndex dbi, DBC * dbcursor, void ** keypp, size_t * keylenp,
int NULkey;
int rc;
- /* XXX make sure that keylen is correct for "" lookup */
- /*@-nullderef -nullpass@*/
- NULkey = (keypp && *keypp && *((char *)(*keypp)) == '\0' && keylenp && *keylenp == 0);
- if (NULkey && keylenp) (*keylenp)++;
- rc = (*dbi->dbi_vec->cget) (dbi, dbcursor, keypp, keylenp, datapp, datalenp, flags);
- if (NULkey && keylenp) (*keylenp)--;
- /*@=nullderef =nullpass@*/
+ /* Make sure that keylen is correct for "" lookup. */
+ NULkey = (keypp && *keypp && *((char *)(*keypp)) == '\0');
+ NULkey = (keylenp && *keylenp == 0 && NULkey);
+ if (keylenp && NULkey) (*keylenp)++;
+ rc = (*dbi->dbi_vec->cget) (dbi, dbcursor,
+ keypp, keylenp, datapp, datalenp, flags);
+ if (keylenp && NULkey) (*keylenp)--;
/*@-nullderef -nullpass@*/
if (_debug < 0 || dbi->dbi_debug) {
@@ -212,9 +218,7 @@ if (_debug < 0 || dbi->dbi_debug) {
char keyval[64];
keyval[0] = '\0';
if (keypp && *keypp && keylenp) {
- if (*keylenp <= sizeof(int) &&
- !( printable( ((unsigned char *)(*keypp))[0] ) && printable( ((unsigned char *)(*keypp))[1] ) &&
- printable( ((unsigned char *)(*keypp))[2] ) && printable( ((unsigned char *)(*keypp))[3] ))) {
+ if (*keylenp <= sizeof(int) && !printable(*keypp, *keylenp)) {
int keyint = 0;
memcpy(&keyint, *keypp, sizeof(keyint));
sprintf(keyval, "#%d", keyint);
@@ -254,9 +258,7 @@ if (_debug < 0 || dbi->dbi_debug) {
char keyval[64];
keyval[0] = '\0';
if (keyp) {
- if (keylen == sizeof(int) &&
- !( printable( ((unsigned char *)keyp)[0] ) && printable( ((unsigned char *)keyp)[1] ) &&
- printable( ((unsigned char *)keyp)[2] ) && printable( ((unsigned char *)keyp)[3] ))){
+ if (keylen == sizeof(int) && !printable(keyp, keylen)) {
int keyint = 0;
memcpy(&keyint, keyp, sizeof(keyint));
sprintf(keyval, "#%d", keyint);
@@ -408,6 +410,7 @@ exit:
* @return new item
*/
static INLINE dbiIndexItem dbiIndexNewItem(unsigned int hdrNum, unsigned int tagNum)
+ /*@*/
{
dbiIndexItem rec = xcalloc(1, sizeof(*rec));
rec->hdrNum = hdrNum;
@@ -436,9 +439,10 @@ union _dbswap {
* @return -1 error, 0 success, 1 not found
*/
static int dbiSearch(dbiIndex dbi, DBC * dbcursor,
- const char * keyp, size_t keylen, /*@out@*/ dbiIndexSet * setp)
- /*@modifies *dbcursor, *setp @*/
+ const char * keyp, size_t keylen, /*@out@*/ dbiIndexSet * setp)
+ /*@modifies *dbcursor, *setp, fileSystem @*/
{
+ unsigned int gflags = 0; /* dbiGet() flags */
void * datap = NULL;
size_t datalen = 0;
int rc;
@@ -447,7 +451,8 @@ static int dbiSearch(dbiIndex dbi, DBC * dbcursor,
if (keylen == 0) keylen = strlen(keyp);
/*@-mods@*/ /* FIX: indirection @*/
- rc = dbiGet(dbi, dbcursor, (void **)&keyp, &keylen, &datap, &datalen, 0);
+ rc = dbiGet(dbi, dbcursor, (void **)&keyp, &keylen, &datap, &datalen,
+ gflags);
/*@=mods@*/
if (rc > 0) {
@@ -524,6 +529,8 @@ static int dbiUpdateIndex(dbiIndex dbi, DBC * dbcursor,
const void * keyp, size_t keylen, dbiIndexSet set)
/*@modifies *dbcursor, set, fileSystem @*/
{
+ unsigned int pflags = 0; /* dbiPut() flags */
+ unsigned int dflags = 0; /* dbiDel() flags */
void * datap;
size_t datalen;
int rc;
@@ -574,7 +581,7 @@ static int dbiUpdateIndex(dbiIndex dbi, DBC * dbcursor,
break;
}
- rc = dbiPut(dbi, dbcursor, keyp, keylen, datap, datalen, 0);
+ rc = dbiPut(dbi, dbcursor, keyp, keylen, datap, datalen, pflags);
if (rc) {
rpmError(RPMERR_DBPUTINDEX,
@@ -584,7 +591,7 @@ static int dbiUpdateIndex(dbiIndex dbi, DBC * dbcursor,
} else {
- rc = dbiDel(dbi, dbcursor, keyp, keylen, 0);
+ rc = dbiDel(dbi, dbcursor, keyp, keylen, dflags);
if (rc) {
rpmError(RPMERR_DBPUTINDEX,
@@ -599,7 +606,9 @@ static int dbiUpdateIndex(dbiIndex dbi, DBC * dbcursor,
/*@=compmempass =mustmod@*/
/* XXX assumes hdrNum is first int in dbiIndexItem */
-static int hdrNumCmp(const void * one, const void * two) {
+static int hdrNumCmp(const void * one, const void * two)
+ /*@*/
+{
const int * a = one, * b = two;
return (*a - *b);
}
@@ -697,11 +706,12 @@ unsigned int dbiIndexRecordFileNumber(dbiIndexSet set, int recno) {
}
/* XXX transaction.c */
-void dbiFreeIndexSet(dbiIndexSet set) {
+dbiIndexSet dbiFreeIndexSet(dbiIndexSet set) {
if (set) {
set->recs = _free(set->recs);
set = _free(set);
}
+ return set;
}
/**
@@ -865,6 +875,7 @@ static int openDatabase(/*@null@*/ const char * prefix,
{
rpmdb db;
int rc;
+ unsigned int gflags = 0; /* dbiGet() flags */
static int _initialized = 0;
int justCheck = flags & RPMDB_FLAG_JUSTCHECK;
int minimal = flags & RPMDB_FLAG_MINIMAL;
@@ -945,7 +956,7 @@ static int openDatabase(/*@null@*/ const char * prefix,
break;
dbcursor = NULL;
xx = dbiCopen(dbi, &dbcursor, 0);
- xx = dbiGet(dbi, dbcursor, &keyp, NULL, NULL, NULL, 0);
+ xx = dbiGet(dbi, dbcursor, &keyp, NULL, NULL, NULL, gflags);
if (xx == 0) {
const char * akey = keyp;
if (akey && strchr(akey, '/')) {
@@ -1082,8 +1093,7 @@ static int rpmdbFindByFile(rpmdb db, /*@null@*/ const char * filespec,
rc = -2;
if (rc) {
- dbiFreeIndexSet(allMatches);
- allMatches = NULL;
+ allMatches = dbiFreeIndexSet(allMatches);
fpCacheFree(fpc);
return rc;
}
@@ -1141,16 +1151,12 @@ static int rpmdbFindByFile(rpmdb db, /*@null@*/ const char * filespec,
}
rec = _free(rec);
- if (allMatches) {
- dbiFreeIndexSet(allMatches);
- allMatches = NULL;
- }
+ allMatches = dbiFreeIndexSet(allMatches);
fpCacheFree(fpc);
if ((*matches)->count == 0) {
- dbiFreeIndexSet(*matches);
- *matches = NULL;
+ *matches = dbiFreeIndexSet(*matches);
return 1;
}
@@ -1190,8 +1196,7 @@ int rpmdbCountPackages(rpmdb db, const char * name)
else /* not found */
rc = 0;
- if (matches)
- dbiFreeIndexSet(matches);
+ matches = dbiFreeIndexSet(matches);
return rc;
}
@@ -1205,7 +1210,7 @@ static int dbiFindMatches(dbiIndex dbi, DBC * dbcursor,
/*@null@*/ const char * version,
/*@null@*/ const char * release,
/*@out@*/ dbiIndexSet * matches)
- /*@modifies dbi, *dbcursor, *matches @*/
+ /*@modifies dbi, *dbcursor, *matches, fileSystem @*/
{
int gotMatches;
int rc;
@@ -1276,8 +1281,9 @@ static int dbiFindMatches(dbiIndex dbi, DBC * dbcursor,
exit:
if (rc && matches && *matches) {
- /*@-unqualifiedtrans@*/dbiFreeIndexSet(*matches);/*@=unqualifiedtrans@*/
- *matches = NULL;
+ /*@-unqualifiedtrans@*/
+ *matches = dbiFreeIndexSet(*matches);
+ /*@=unqualifiedtrans@*/
}
return rc;
}
@@ -1292,7 +1298,7 @@ exit:
*/
static int dbiFindByLabel(dbiIndex dbi, DBC * dbcursor,
/*@null@*/ const char * arg, /*@out@*/ dbiIndexSet * matches)
- /*@modifies dbi, *dbcursor, *matches @*/
+ /*@modifies dbi, *dbcursor, *matches, fileSystem @*/
{
char * localarg, * chptr;
char * release;
@@ -1303,10 +1309,10 @@ static int dbiFindByLabel(dbiIndex dbi, DBC * dbcursor,
/* did they give us just a name? */
rc = dbiFindMatches(dbi, dbcursor, arg, NULL, NULL, matches);
if (rc != 1) return rc;
- if (*matches) {
- /*@-unqualifiedtrans@*/dbiFreeIndexSet(*matches);/*@=unqualifiedtrans@*/
- *matches = NULL;
- }
+
+ /*@-unqualifiedtrans@*/
+ *matches = dbiFreeIndexSet(*matches);
+ /*@=unqualifiedtrans@*/
/* maybe a name and a release */
localarg = alloca(strlen(arg) + 1);
@@ -1320,10 +1326,10 @@ static int dbiFindByLabel(dbiIndex dbi, DBC * dbcursor,
*chptr = '\0';
rc = dbiFindMatches(dbi, dbcursor, localarg, chptr + 1, NULL, matches);
if (rc != 1) return rc;
- if (*matches) {
- /*@-unqualifiedtrans@*/dbiFreeIndexSet(*matches);/*@=unqualifiedtrans@*/
- *matches = NULL;
- }
+
+ /*@-unqualifiedtrans@*/
+ *matches = dbiFreeIndexSet(*matches);
+ /*@=unqualifiedtrans@*/
/* how about name-version-release? */
@@ -1353,6 +1359,7 @@ static int dbiUpdateRecord(dbiIndex dbi, DBC * dbcursor, int offset, Header h)
void * uh;
size_t uhlen;
int rc = EINVAL; /* XXX W2DO? */
+ unsigned int pflags = 0; /* dbiPut() flags */
int xx;
if (_noDirTokens)
@@ -1362,7 +1369,7 @@ static int dbiUpdateRecord(dbiIndex dbi, DBC * dbcursor, int offset, Header h)
uh = headerUnload(h);
if (uh) {
blockSignals(dbi->dbi_rpmdb, &signalMask);
- rc = dbiPut(dbi, dbcursor, &offset, sizeof(offset), uh, uhlen, 0);
+ rc = dbiPut(dbi, dbcursor, &offset, sizeof(offset), uh, uhlen, pflags);
xx = dbiSync(dbi, 0);
unblockSignals(dbi->dbi_rpmdb, &signalMask);
uh = _free(uh);
@@ -1418,9 +1425,7 @@ rpmdbMatchIterator rpmdbFreeIterator(rpmdbMatchIterator mi)
if (dbi && mi->mi_dbc)
xx = dbiCclose(dbi, mi->mi_dbc, DBI_ITERATOR);
mi->mi_dbc = NULL;
- if (mi->mi_set)
- dbiFreeIndexSet(mi->mi_set);
- mi->mi_set = NULL;
+ mi->mi_set = dbiFreeIndexSet(mi->mi_set);
mi->mi_keyp = _free(mi->mi_keyp);
mi = _free(mi);
return mi;
@@ -1492,6 +1497,7 @@ Header XrpmdbNextIterator(rpmdbMatchIterator mi, const char * f, unsigned l)
dbiIndex dbi;
void * uh = NULL;
size_t uhlen = 0;
+ unsigned int gflags = 0; /* dbiGet() flags */
void * keyp;
size_t keylen;
int rc;
@@ -1528,7 +1534,7 @@ top:
keyp = (void *)mi->mi_keyp; /* XXX FIXME const */
keylen = mi->mi_keylen;
- rc = dbiGet(dbi, mi->mi_dbc, &keyp, &keylen, &uh, &uhlen, 0);
+ rc = dbiGet(dbi, mi->mi_dbc, &keyp, &keylen, &uh, &uhlen, gflags);
if (dbi->dbi_api == 1 && dbi->dbi_rpmtag == RPMDBI_PACKAGES && rc == EFAULT) {
rpmError(RPMERR_INTERNAL,
_("record number %u in database is bad -- skipping.\n"), dbi->dbi_lastoffset);
@@ -1559,7 +1565,7 @@ if (dbi->dbi_api == 1 && dbi->dbi_rpmtag == RPMDBI_PACKAGES && rc == EFAULT) {
/* Retrieve next header */
if (uh == NULL) {
- rc = dbiGet(dbi, mi->mi_dbc, &keyp, &keylen, &uh, &uhlen, 0);
+ rc = dbiGet(dbi, mi->mi_dbc, &keyp, &keylen, &uh, &uhlen, gflags);
if (rc)
return NULL;
}
@@ -1618,7 +1624,9 @@ exit:
/*@=retexpose =retalias@*/
}
-static void rpmdbSortIterator(/*@null@*/ rpmdbMatchIterator mi) {
+static void rpmdbSortIterator(/*@null@*/ rpmdbMatchIterator mi)
+ /*@modifies mi @*/
+{
if (mi && mi->mi_set && mi->mi_set->recs && mi->mi_set->count > 0) {
qsort(mi->mi_set->recs, mi->mi_set->count, sizeof(*mi->mi_set->recs),
hdrNumCmp);
@@ -1627,7 +1635,8 @@ static void rpmdbSortIterator(/*@null@*/ rpmdbMatchIterator mi) {
}
static int rpmdbGrowIterator(/*@null@*/ rpmdbMatchIterator mi,
- const void * keyp, size_t keylen, int fpNum)
+ const void * keyp, size_t keylen, int fpNum)
+ /*@modifies mi, fileSystem @*/
{
dbiIndex dbi = NULL;
DBC * dbcursor = NULL;
@@ -1667,8 +1676,7 @@ static int rpmdbGrowIterator(/*@null@*/ rpmdbMatchIterator mi,
}
}
- if (set)
- dbiFreeIndexSet(set);
+ set = dbiFreeIndexSet(set);
return rc;
}
@@ -1678,10 +1686,8 @@ int rpmdbPruneIterator(rpmdbMatchIterator mi, int * hdrNums,
if (mi == NULL || hdrNums == NULL || nHdrNums <= 0)
return 1;
- /*@-mods@*/ /* FIX: wazzup? */
if (mi->mi_set)
(void) dbiPruneSet(mi->mi_set, hdrNums, nHdrNums, sizeof(*hdrNums), sorted);
- /*@=mods@*/
return 0;
}
@@ -1751,8 +1757,7 @@ fprintf(stderr, "*** RMW %s %p\n", tagName(rpmtag), dbi->dbi_rmw);
dbcursor = NULL;
}
if (rc) { /* error/not found */
- if (set)
- dbiFreeIndexSet(set);
+ set = dbiFreeIndexSet(set);
return NULL;
}
}
@@ -1807,7 +1812,8 @@ fprintf(stderr, "*** RMW %s %p\n", tagName(rpmtag), dbi->dbi_rmw);
* @return 0 on success
*/
static INLINE int removeIndexEntry(dbiIndex dbi, DBC * dbcursor,
- const void * keyp, size_t keylen, dbiIndexItem rec)
+ const void * keyp, size_t keylen, dbiIndexItem rec)
+ /*@modifies *dbcursor, fileSystem @*/
{
dbiIndexSet set = NULL;
int rc;
@@ -1819,15 +1825,14 @@ static INLINE int removeIndexEntry(dbiIndex dbi, DBC * dbcursor,
else if (rc > 0) /* error */
rc = 1; /* error message already generated from dbindex.c */
else { /* success */
- if (!dbiPruneSet(set, rec, 1, sizeof(*rec), 1) &&
- dbiUpdateIndex(dbi, dbcursor, keyp, keylen, set))
+ /*@-mods@*/ /* a single rec is not modified */
+ rc = dbiPruneSet(set, rec, 1, sizeof(*rec), 1);
+ /*@=mods@*/
+ if (rc == 0 && dbiUpdateIndex(dbi, dbcursor, keyp, keylen, set))
rc = 1;
}
- if (set) {
- dbiFreeIndexSet(set);
- set = NULL;
- }
+ set = dbiFreeIndexSet(set);
return rc;
}
@@ -2006,17 +2011,23 @@ int rpmdbRemove(rpmdb rpmdb, int rid, unsigned int hdrNum)
* @return 0 on success
*/
static INLINE int addIndexEntry(dbiIndex dbi, DBC * dbcursor,
- const char * keyp, size_t keylen, dbiIndexItem rec)
+ const char * keyp, size_t keylen, dbiIndexItem rec)
+ /*@modifies *dbcursor, fileSystem @*/
{
dbiIndexSet set = NULL;
int rc;
rc = dbiSearch(dbi, dbcursor, keyp, keylen, &set);
- if (rc > 0) {
- rc = 1; /* error */
+ if (rc > 0) { /* error */
+ rc = 1;
} else {
- if (rc < 0) { /* not found */
+
+ /* With duplicates, cursor is positioned, discard the record. */
+ if (rc == 0 && dbi->dbi_permit_dups)
+ set = dbiFreeIndexSet(set);
+
+ if (set == NULL || rc < 0) { /* not found */
rc = 0;
set = xcalloc(1, sizeof(*set));
}
@@ -2024,11 +2035,7 @@ static INLINE int addIndexEntry(dbiIndex dbi, DBC * dbcursor,
if (dbiUpdateIndex(dbi, dbcursor, keyp, keylen, set))
rc = 1;
}
-
- if (set) {
- dbiFreeIndexSet(set);
- set = NULL;
- }
+ set = dbiFreeIndexSet(set);
return 0;
}
@@ -2044,6 +2051,8 @@ int rpmdbAdd(rpmdb rpmdb, int iid, Header h)
int count = 0;
dbiIndex dbi;
int dbix;
+ unsigned int gflags = 0; /* dbiGet() flags */
+ unsigned int pflags = 0; /* dbiPut() flags */
unsigned int hdrNum = 0;
int rc = 0;
int xx;
@@ -2086,7 +2095,7 @@ int rpmdbAdd(rpmdb rpmdb, int iid, Header h)
/* Retrieve join key for next header instance. */
- rc = dbiGet(dbi, dbcursor, &keyp, &keylen, &datap, &datalen, 0);
+ rc = dbiGet(dbi, dbcursor, &keyp, &keylen, &datap, &datalen, gflags);
hdrNum = 0;
if (rc == 0 && datap)
@@ -2101,7 +2110,7 @@ int rpmdbAdd(rpmdb rpmdb, int iid, Header h)
datalen = sizeof(hdrNum);
}
- rc = dbiPut(dbi, dbcursor, keyp, keylen, datap, datalen, 0);
+ rc = dbiPut(dbi, dbcursor, keyp, keylen, datap, datalen, pflags);
xx = dbiSync(dbi, 0);
xx = dbiCclose(dbi, dbcursor, DBI_WRITECURSOR);
diff --git a/rpmdb/rpmdb.h b/rpmdb/rpmdb.h
index ab465d535..998b24baf 100644
--- a/rpmdb/rpmdb.h
+++ b/rpmdb/rpmdb.h
@@ -47,6 +47,7 @@ struct _dbiIndexSet {
/* XXX hack to get prototypes correct */
#if !defined(DB_VERSION_MAJOR)
+#define DB void
#define DB_ENV void
#define DBC void
#define DBT void
@@ -131,8 +132,8 @@ struct _dbiVec {
* @return 0 on success
*/
int (*cget) (dbiIndex dbi, DBC * dbcursor,
- /*@out@*/ void ** keypp, /*@out@*/ size_t * keylenp,
- /*@out@*/ void ** datapp, /*@out@*/ size_t * datalenp,
+ /*@null@*/ void ** keypp, /*@null@*/ size_t * keylenp,
+ /*@null@*/ void ** datapp, /*@null@*/ size_t * datalenp,
unsigned int flags)
/*@modifies *dbcursor, *keypp, *keylenp, *datapp, *datalenp,
fileSystem @*/;
@@ -212,6 +213,7 @@ struct _dbiIndex {
int dbi_tear_down; /*!< tear down dbenv on close */
int dbi_use_cursors;/*!< access with cursors? (always) */
int dbi_use_dbenv; /*!< use db environment? */
+ int dbi_permit_dups;/*!< permit duplicate entries? */
int dbi_get_rmw_cursor;
int dbi_no_fsync; /*!< no-op fsync for db */
int dbi_no_dbsync; /*!< don't call dbiSync */
@@ -257,21 +259,16 @@ struct _dbiIndex {
/*@*/;
/* hash access parameters */
unsigned int dbi_h_ffactor; /*!< */
-/*@unused@*/ /*@null@*/ unsigned int (*dbi_h_hash_fcn) (const void *bytes, unsigned int length)
- /*@modifies internalState @*/;
+/*@null@*/ unsigned int (*dbi_h_hash_fcn) (DB *, const void *bytes, unsigned int length) /*@*/;
unsigned int dbi_h_nelem; /*!< */
unsigned int dbi_h_flags; /*!< DB_DUP, DB_DUPSORT */
-/*@unused@*/ /*@null@*/ int (*dbi_h_dup_compare_fcn) (const DBT *, const DBT *)
- /*@modifies internalState @*/;
+/*@null@*/ int (*dbi_h_dup_compare_fcn) (DB *, const DBT *, const DBT *) /*@*/;
/* btree access parameters */
int dbi_bt_flags;
-/*@unused@*/ int dbi_bt_minkey;
-/*@unused@*/ /*@null@*/ int (*dbi_bt_compare_fcn) (const DBT *, const DBT *)
- /*@modifies internalState @*/;
-/*@unused@*/ /*@null@*/ int (*dbi_bt_dup_compare_fcn) (const DBT *, const DBT *)
- /*@modifies internalState @*/;
-/*@unused@*/ /*@null@*/ size_t (*dbi_bt_prefix_fcn) (const DBT *, const DBT *)
- /*@modifies internalState @*/;
+ int dbi_bt_minkey;
+/*@null@*/ int (*dbi_bt_compare_fcn) (DB *, const DBT *, const DBT *) /*@*/;
+/*@null@*/ int (*dbi_bt_dup_compare_fcn) (DB *, const DBT *, const DBT *) /*@*/;
+/*@null@*/ size_t (*dbi_bt_prefix_fcn) (DB *, const DBT *, const DBT *) /*@*/;
/* recno access parameters */
int dbi_re_flags;
int dbi_re_delim;
@@ -523,8 +520,9 @@ int rpmdbFindFpList(/*@null@*/ rpmdb db, fingerPrint * fpList,
/** \ingroup dbi
* Destroy set of index database items.
* @param set set of index database items
+ * @return NULL always
*/
-void dbiFreeIndexSet(/*@only@*/ /*@null@*/ dbiIndexSet set)
+/*@null@*/ dbiIndexSet dbiFreeIndexSet(/*@only@*/ /*@null@*/ dbiIndexSet set)
/*@modifies set @*/;
/** \ingroup dbi
diff --git a/rpmdb/tdbi.c b/rpmdb/tdbi.c
new file mode 100644
index 000000000..cece801fb
--- /dev/null
+++ b/rpmdb/tdbi.c
@@ -0,0 +1,78 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <db3/db.h>
+
+static char * dbfile = "/var/lib/rpm/Dirnames";
+
+int
+main(int argc, char *argv[])
+{
+ DB * db = NULL;
+ DB_TXN * txnid = NULL;
+ DBC * dbcursor = NULL;
+ DBT key;
+ DBT data;
+ unsigned int flags;
+ int rc, ec = 0;
+
+ if (argc > 1)
+ dbfile = argv[1];
+
+ if ((rc = db_create(&db, NULL, 0)) != 0) {
+ fprintf(stderr, "db_create: %s\n", db_strerror(rc));
+ exit (1);
+ }
+
+ if ((rc = db->open(db, dbfile, NULL, DB_UNKNOWN, DB_RDONLY, 0664)) != 0) {
+ db->err(db, rc, "db->open");
+ if (!ec) ec = rc;
+ goto err;
+ }
+
+ if ((rc = db->cursor(db, txnid, &dbcursor, 0)) != 0) {
+ db->err(db, rc, "db->cursor");
+ if (!ec) ec = rc;
+ goto err;
+ }
+
+ flags = DB_NEXT;
+ memset(&key, 0, sizeof(key));
+ memset(&data, 0, sizeof(data));
+
+ while ((rc = dbcursor->c_get(dbcursor, &key, &data, flags)) == 0) {
+ const char * kval;
+ size_t klen;
+ db_recno_t nrecs;
+
+ nrecs = 0;
+ if ((rc = dbcursor->c_count(dbcursor, &nrecs, 0)) != 0) {
+ db->err(db, rc, "dbcursor->c_count");
+ if (!ec) ec = rc;
+ }
+ kval = key.data;
+ klen = key.size;
+ printf("%3d %.*s\t%p[%d]\n", nrecs, klen, kval, data.data, data.size);
+
+ memset(&key, 0, sizeof(key));
+ memset(&data, 0, sizeof(data));
+ }
+
+ if (rc != DB_NOTFOUND) {
+ db->err(db, rc, "db->c_get");
+ if (!ec) ec = rc;
+ goto err;
+ }
+
+err:
+ if (dbcursor && (rc = dbcursor->c_close(dbcursor)) != 0) {
+ db->err(db, rc, "dbcursor->c_close");
+ if (!ec) ec = rc;
+ }
+ if ((rc = db->close(db, 0)) != 0) {
+ db->err(db, rc, "db->close");
+ if (!ec) ec = rc;
+ }
+ return ec;
+}