summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjbj <devnull@localhost>2002-05-04 20:13:14 +0000
committerjbj <devnull@localhost>2002-05-04 20:13:14 +0000
commit81c2a9d267450f62264576199aa5b607391ac3f1 (patch)
tree3570ee3c669ff2e045e6364fba9cd5b54ee770a1
parent40aceb784a9421b0410210187668522525594b7d (diff)
downloadrpm-81c2a9d267450f62264576199aa5b607391ac3f1.tar.gz
rpm-81c2a9d267450f62264576199aa5b607391ac3f1.tar.bz2
rpm-81c2a9d267450f62264576199aa5b607391ac3f1.zip
Add toy db->associate, db->join, dbcursor->c_pget wrappers.
CVS patchset: 5421 CVS date: 2002/05/04 20:13:14
-rw-r--r--build/pack.c2
-rw-r--r--lib/package.c2
-rw-r--r--lib/query.c2
-rw-r--r--lib/rpminstall.c2
-rw-r--r--lib/rpmlib.h2
-rw-r--r--python/header-py.c2
-rw-r--r--rpm2cpio.c2
-rw-r--r--rpmdb/db3.c73
-rw-r--r--rpmdb/rpmdb.c119
-rw-r--r--rpmdb/rpmdb.h178
10 files changed, 266 insertions, 118 deletions
diff --git a/build/pack.c b/build/pack.c
index 768e0c93d..5fbaf9ba6 100644
--- a/build/pack.c
+++ b/build/pack.c
@@ -333,7 +333,7 @@ int readRPM(const char *fileName, Spec *specp, struct rpmlead *lead,
}
switch (rc) {
- case RPMRC_BADMAGIC:
+ case RPMRC_NOTFOUND:
rpmError(RPMERR_BADMAGIC, _("readRPM: %s is not an RPM package\n"),
(fileName ? fileName : "<stdin>"));
return RPMERR_BADMAGIC;
diff --git a/lib/package.c b/lib/package.c
index 78baa2280..ada52b745 100644
--- a/lib/package.c
+++ b/lib/package.c
@@ -172,7 +172,7 @@ int rpmReadPackageFile(rpmTransactionSet ts, FD_t fd,
if (l->magic[0] != RPMLEAD_MAGIC0 || l->magic[1] != RPMLEAD_MAGIC1
|| l->magic[2] != RPMLEAD_MAGIC2 || l->magic[3] != RPMLEAD_MAGIC3) {
rpmError(RPMERR_READLEAD, _("%s: bad magic\n"), fn);
- rc = RPMRC_BADMAGIC;
+ rc = RPMRC_NOTFOUND;
goto exit;
}
diff --git a/lib/query.c b/lib/query.c
index 37bb3af3a..4b24db631 100644
--- a/lib/query.c
+++ b/lib/query.c
@@ -632,7 +632,7 @@ restart:
(void) Fclose(fd);
- if (!(rpmrc == RPMRC_OK || rpmrc == RPMRC_BADMAGIC)) {
+ if (!(rpmrc == RPMRC_OK || rpmrc == RPMRC_NOTFOUND)) {
rpmError(RPMERR_QUERY, _("query of %s failed\n"), fileURL);
res = 1;
/*@loopbreak@*/ break;
diff --git a/lib/rpminstall.c b/lib/rpminstall.c
index 2878e61a1..11e13f2de 100644
--- a/lib/rpminstall.c
+++ b/lib/rpminstall.c
@@ -482,7 +482,7 @@ restart:
continue;
}
- if (eiu->rpmrc != RPMRC_BADMAGIC) {
+ if (eiu->rpmrc != RPMRC_NOTFOUND) {
rpmMessage(RPMMESS_ERROR, _("%s cannot be installed\n"), *eiu->fnp);
eiu->numFailed++; *eiu->fnp = NULL;
break;
diff --git a/lib/rpmlib.h b/lib/rpmlib.h
index 904eca36c..d1f9d43c2 100644
--- a/lib/rpmlib.h
+++ b/lib/rpmlib.h
@@ -16,7 +16,7 @@
*/
typedef enum rpmRC_e {
RPMRC_OK = 0,
- RPMRC_BADMAGIC = 1,
+ RPMRC_NOTFOUND = 1,
RPMRC_FAIL = 2,
RPMRC_BADSIZE = 3,
RPMRC_SHORTREAD = 4
diff --git a/python/header-py.c b/python/header-py.c
index 7e3d12313..93a6af817 100644
--- a/python/header-py.c
+++ b/python/header-py.c
@@ -799,7 +799,7 @@ PyObject * rpmHeaderFromPackage(PyObject * self, PyObject * args) {
isSource = headerIsEntry(header, RPMTAG_SOURCEPACKAGE);
break;
- case RPMRC_BADMAGIC:
+ case RPMRC_NOTFOUND:
Py_INCREF(Py_None);
h = (hdrObject *) Py_None;
break;
diff --git a/rpm2cpio.c b/rpm2cpio.c
index 73bbf804e..397303c66 100644
--- a/rpm2cpio.c
+++ b/rpm2cpio.c
@@ -43,7 +43,7 @@ int main(int argc, char **argv)
case RPMRC_BADSIZE:
case RPMRC_OK:
break;
- case RPMRC_BADMAGIC:
+ case RPMRC_NOTFOUND:
fprintf(stderr, _("argument is not an RPM package\n"));
exit(EXIT_FAILURE);
break;
diff --git a/rpmdb/db3.c b/rpmdb/db3.c
index 9c0f3c334..0d835cbff 100644
--- a/rpmdb/db3.c
+++ b/rpmdb/db3.c
@@ -300,9 +300,7 @@ static int db3sync(dbiIndex dbi, unsigned int flags)
return rc;
}
-#ifdef DYING
-/*@unused@*/
-static int db3c_dup(dbiIndex dbi, DBC * dbcursor, DBC ** dbcp,
+static int db3cdup(dbiIndex dbi, DBC * dbcursor, DBC ** dbcp,
unsigned int flags)
/*@globals fileSystem @*/
/*@modifies *dbcp, fileSystem @*/
@@ -316,7 +314,6 @@ static int db3c_dup(dbiIndex dbi, DBC * dbcursor, DBC ** dbcp,
return rc;
/*@=nullstate @*/
}
-#endif
static int db3cclose(dbiIndex dbi, /*@only@*/ /*@null@*/ DBC * dbcursor,
unsigned int flags)
@@ -416,31 +413,46 @@ static int db3cget(dbiIndex dbi, DBC * dbcursor, DBT * key, DBT * data,
/*@modifies *dbcursor, *key, *data, fileSystem @*/
{
DB * db = dbi->dbi_db;
+ int _printit;
int rc;
assert(db != NULL);
if (dbcursor == NULL) {
- int _printit;
-
/* XXX duplicates require cursors. */
rc = db->get(db, dbi->dbi_txnid, key, data, 0);
/* XXX DB_NOTFOUND can be returned */
_printit = (rc == DB_NOTFOUND ? 0 : _debug);
rc = cvtdberr(dbi, "db->get", rc, _printit);
} else {
- int _printit;
-
/* XXX db3 does DB_FIRST on uninitialized cursor */
rc = dbcursor->c_get(dbcursor, key, data, flags);
/* XXX DB_NOTFOUND can be returned */
_printit = (rc == DB_NOTFOUND ? 0 : _debug);
rc = cvtdberr(dbi, "dbcursor->c_get", rc, _printit);
-
}
- /*@-compmempass -nullstate@*/
return rc;
- /*@=compmempass =nullstate@*/
+}
+
+static int db3cpget(dbiIndex dbi, DBC * dbcursor, DBT * key, DBT * pkey,
+ DBT * data, unsigned int flags)
+ /*@globals fileSystem @*/
+ /*@modifies *dbcursor, *key, *data, fileSystem @*/
+{
+ DB * db = dbi->dbi_db;
+ int _printit;
+ int rc;
+
+ assert(db != NULL);
+ assert(dbcursor != NULL);
+
+ /* XXX db3 does DB_FIRST on uninitialized cursor */
+ rc = dbcursor->c_pget(dbcursor, key, pkey, data, flags);
+ /* XXX DB_NOTFOUND can be returned */
+ _printit = (rc == DB_NOTFOUND ? 0 : _debug);
+ rc = cvtdberr(dbi, "dbcursor->c_pget", rc, _printit);
+
+ return rc;
}
static int db3ccount(dbiIndex dbi, DBC * dbcursor,
@@ -506,6 +518,38 @@ static int db3stat(dbiIndex dbi, unsigned int flags)
return rc;
}
+static int db3associate(dbiIndex dbi, dbiIndex dbisecondary,
+ int (*callback)(DB *, const DBT *, const DBT *, DBT *),
+ unsigned int flags)
+ /*@globals fileSystem @*/
+ /*@modifies dbi, fileSystem @*/
+{
+ DB * db = dbi->dbi_db;
+ DB * secondary = dbisecondary->dbi_db;
+ int rc;
+
+/*@-moduncon@*/ /* FIX: annotate db3 methods */
+ rc = db->associate(db, secondary, callback, flags);
+/*@=moduncon@*/
+ rc = cvtdberr(dbi, "db->associate", rc, _debug);
+ return rc;
+}
+
+static int db3join(dbiIndex dbi, DBC ** curslist, DBC ** dbcp,
+ unsigned int flags)
+ /*@globals fileSystem @*/
+ /*@modifies dbi, fileSystem @*/
+{
+ DB * db = dbi->dbi_db;
+ int rc;
+
+/*@-moduncon@*/ /* FIX: annotate db3 methods */
+ rc = db->join(db, curslist, dbcp, flags);
+/*@=moduncon@*/
+ rc = cvtdberr(dbi, "db->join", rc, _debug);
+ return rc;
+}
+
/*@-moduncon@*/ /* FIX: annotate db3 methods */
static int db3close(/*@only@*/ dbiIndex dbi, /*@unused@*/ unsigned int flags)
/*@globals rpmGlobalMacroContext,
@@ -652,7 +696,7 @@ exit:
}
/*@=moduncon@*/
-static int db3open(rpmdb rpmdb, int rpmtag, dbiIndex * dbip)
+static int db3open(rpmdb rpmdb, rpmTag rpmtag, dbiIndex * dbip)
/*@globals rpmGlobalMacroContext,
fileSystem @*/
/*@modifies *dbip, fileSystem @*/
@@ -1100,8 +1144,9 @@ static int db3open(rpmdb rpmdb, int rpmtag, dbiIndex * dbip)
/*@observer@*/ /*@unchecked@*/
struct _dbiVec db3vec = {
DB_VERSION_MAJOR, DB_VERSION_MINOR, DB_VERSION_PATCH,
- db3open, db3close, db3sync, db3copen, db3cclose, db3cdel, db3cget, db3cput,
- db3ccount, db3byteswapped, db3stat
+ db3open, db3close, db3sync, db3associate, db3join,
+ db3copen, db3cclose, db3cdup, db3cdel, db3cget, db3cpget, db3cput, db3ccount,
+ db3byteswapped, db3stat
};
/*@=exportheadervar@*/
/*@=type@*/
diff --git a/rpmdb/rpmdb.c b/rpmdb/rpmdb.c
index f23cbf47b..fbf80fef4 100644
--- a/rpmdb/rpmdb.c
+++ b/rpmdb/rpmdb.c
@@ -1,4 +1,4 @@
-/*@-sizeoftype @*/
+/*@-compmempass -sizeoftype @*/
/** \ingroup rpmdb dbi
* \file rpmdb/rpmdb.c
*/
@@ -503,7 +503,7 @@ assert(key->size != 0);
* @param flags update flags
* @return 0 success, 1 not found
*/
-/*@-compmempass -mustmod@*/
+/*@-mustmod@*/
static int dbiUpdateIndex(dbiIndex dbi, DBC * dbcursor, DBT * key, DBT * data,
int flags)
/*@globals fileSystem @*/
@@ -535,7 +535,7 @@ static int dbiUpdateIndex(dbiIndex dbi, DBC * dbcursor, DBT * key, DBT * data,
return rc;
}
-/*@=compmempass =mustmod@*/
+/*@=mustmod@*/
/* XXX assumes hdrNum is first int in dbiIndexItem */
static int hdrNumCmp(const void * one, const void * two)
@@ -581,9 +581,7 @@ static int dbiAppendSet(dbiIndexSet set, const void * recs,
if (set->count > 1 && sortset)
qsort(set->recs, set->count, sizeof(*(set->recs)), hdrNumCmp);
- /*@-compmempass@*/ /* FIX: set->recs.{hdrNum,tagNum,fpNum,dbNum} undef */
return 0;
- /*@=compmempass@*/
}
/**
@@ -1018,12 +1016,10 @@ int rpmdbVerify(const char * prefix)
/*@=globs@*/
static int rpmdbFindByFile(rpmdb db, /*@null@*/ const char * filespec,
- /*@out@*/ dbiIndexSet * matches)
+ DBT * key, DBT * data, /*@out@*/ dbiIndexSet * matches)
/*@globals fileSystem @*/
/*@modifies db, *matches, fileSystem @*/
{
-DBT * key = alloca(sizeof(*key));
-DBT * data = alloca(sizeof(*data));
HGE_t hge = (HGE_t)headerGetEntryMinMemory;
HFD_t hfd = headerFreeData;
const char * dirName;
@@ -1217,25 +1213,25 @@ xx = dbt2set(dbi, data, &matches);
* Attempt partial matches on name[-version[-release]] strings.
* @param dbi index database handle (always RPMTAG_NAME)
* @param dbcursor index database cursor
+ * @param key search key/length
+ * @param data search data/length
* @param name package name
* @param version package version (can be a pattern)
* @param release package release (can be a pattern)
* @retval matches set of header instances that match
- * @return 0 on match, 1 on no match, 2 on error
+ * @return RPMRC_OK on match, RPMRC_NOMATCH or RPMRC_FAIL
*/
-static int dbiFindMatches(dbiIndex dbi, DBC * dbcursor,
+static rpmRC dbiFindMatches(dbiIndex dbi, DBC * dbcursor,
+ DBT * key, DBT * data,
const char * name,
/*@null@*/ const char * version,
/*@null@*/ const char * release,
/*@out@*/ dbiIndexSet * matches)
/*@globals fileSystem @*/
- /*@modifies dbi, *dbcursor, *matches, fileSystem @*/
+ /*@modifies dbi, *dbcursor, *key, *data, *matches, fileSystem @*/
{
-DBT * key = alloca(sizeof(*key));
-DBT * data = alloca(sizeof(*data));
- int gotMatches;
+ int gotMatches = 0;
int rc;
-int xx;
int i;
memset(key, 0, sizeof(*key));
@@ -1244,74 +1240,63 @@ key->size = strlen(name);
memset(data, 0, sizeof(*data));
rc = dbiSearch(dbi, dbcursor, key, data, DB_SET);
if (rc == 0)
-xx = dbt2set(dbi, data, matches);
+rc = dbt2set(dbi, data, matches);
if (rc != 0) {
- rc = ((rc == -1) ? 2 : 1);
+ rc = ((rc == -1) ? RPMRC_FAIL : RPMRC_NOTFOUND);
goto exit;
}
if (version == NULL && release == NULL) {
- rc = 0;
+ rc = RPMRC_OK;
goto exit;
}
- gotMatches = 0;
-
/* Make sure the version and release match. */
/*@-branchstate@*/
for (i = 0; i < dbiIndexSetCount(*matches); i++) {
unsigned int recoff = dbiIndexRecordOffset(*matches, i);
+ rpmdbMatchIterator mi;
Header h;
if (recoff == 0)
continue;
- { rpmdbMatchIterator mi;
- mi = rpmdbInitIterator(dbi->dbi_rpmdb,
+ mi = rpmdbInitIterator(dbi->dbi_rpmdb,
RPMDBI_PACKAGES, &recoff, sizeof(recoff));
- /* Set iterator selectors for version/release if available. */
- if (version &&
- rpmdbSetIteratorRE(mi, RPMTAG_VERSION, RPMMIRE_DEFAULT, version))
- {
- rc = 2;
- goto exit;
- }
- if (release &&
- rpmdbSetIteratorRE(mi, RPMTAG_RELEASE, RPMMIRE_DEFAULT, release))
- {
- rc = 2;
- goto exit;
- }
-
- h = rpmdbNextIterator(mi);
- if (h)
- h = headerLink(h, "dbiFindMatches");
- mi = rpmdbFreeIterator(mi);
+ /* Set iterator selectors for version/release if available. */
+ if (version &&
+ rpmdbSetIteratorRE(mi, RPMTAG_VERSION, RPMMIRE_DEFAULT, version))
+ {
+ rc = RPMRC_FAIL;
+ goto exit;
+ }
+ if (release &&
+ rpmdbSetIteratorRE(mi, RPMTAG_RELEASE, RPMMIRE_DEFAULT, release))
+ {
+ rc = RPMRC_FAIL;
+ goto exit;
}
- if (h) /* structure assignment */
+ h = rpmdbNextIterator(mi);
+ if (h)
(*matches)->recs[gotMatches++] = (*matches)->recs[i];
else
(*matches)->recs[i].hdrNum = 0;
-
- h = headerFree(h, "dbiFindMatches");
+ mi = rpmdbFreeIterator(mi);
}
/*@=branchstate@*/
if (gotMatches) {
(*matches)->count = gotMatches;
- rc = 0;
+ rc = RPMRC_OK;
} else
- rc = 1;
+ rc = RPMRC_NOTFOUND;
exit:
- if (rc && matches && *matches) {
- /*@-unqualifiedtrans@*/ /* FIX: double indirection */
+ if (rc && matches && *matches)
*matches = dbiFreeIndexSet(*matches);
- /*@=unqualifiedtrans@*/
- }
return rc;
}
@@ -1323,9 +1308,9 @@ exit:
* @param dbcursor index database cursor
* @param arg name[-version[-release]] string
* @retval matches set of header instances that match
- * @return 0 on match, 1 on no match, 2 on error
+ * @return RPMRC_OK on match, RPMRC_NOMATCH or RPMRC_FAIL
*/
-static int dbiFindByLabel(dbiIndex dbi, DBC * dbcursor,
+static rpmRC dbiFindByLabel(dbiIndex dbi, DBC * dbcursor, DBT * key, DBT * data,
/*@null@*/ const char * arg, /*@out@*/ dbiIndexSet * matches)
/*@globals fileSystem @*/
/*@modifies dbi, *dbcursor, *matches, fileSystem @*/
@@ -1335,13 +1320,13 @@ static int dbiFindByLabel(dbiIndex dbi, DBC * dbcursor,
char * s;
char c;
int brackets;
- int rc;
+ rpmRC rc;
- if (arg == NULL || strlen(arg) == 0) return 1;
+ if (arg == NULL || strlen(arg) == 0) return RPMRC_NOTFOUND;
/* did they give us just a name? */
- rc = dbiFindMatches(dbi, dbcursor, arg, NULL, NULL, matches);
- if (rc != 1) return rc;
+ rc = dbiFindMatches(dbi, dbcursor, key, data, arg, NULL, NULL, matches);
+ if (rc != RPMRC_NOTFOUND) return rc;
/*@-unqualifiedtrans@*/
*matches = dbiFreeIndexSet(*matches);
@@ -1368,11 +1353,11 @@ static int dbiFindByLabel(dbiIndex dbi, DBC * dbcursor,
}
/*@-nullstate@*/ /* FIX: *matches may be NULL. */
- if (s == localarg) return 1;
+ if (s == localarg) return RPMRC_NOTFOUND;
*s = '\0';
- rc = dbiFindMatches(dbi, dbcursor, localarg, s + 1, NULL, matches);
- if (rc != 1) return rc;
+ rc = dbiFindMatches(dbi, dbcursor, key, data, localarg, s + 1, NULL, matches);
+ if (rc != RPMRC_NOTFOUND) return rc;
/*@-unqualifiedtrans@*/
*matches = dbiFreeIndexSet(*matches);
@@ -1398,10 +1383,10 @@ static int dbiFindByLabel(dbiIndex dbi, DBC * dbcursor,
break;
}
- if (s == localarg) return 1;
+ if (s == localarg) return RPMRC_NOTFOUND;
*s = '\0';
- return dbiFindMatches(dbi, dbcursor, localarg, s + 1, release, matches);
+ return dbiFindMatches(dbi, dbcursor, key, data, localarg, s + 1, release, matches);
/*@=nullstate@*/
}
@@ -1951,7 +1936,6 @@ Header XrpmdbNextIterator(rpmdbMatchIterator mi,
return rpmdbNextIterator(mi);
}
-/*@-compmempass@*/
Header rpmdbNextIterator(rpmdbMatchIterator mi)
{
dbiIndex dbi;
@@ -2111,7 +2095,6 @@ exit:
/*@-compdef -usereleased@*/ return mi->mi_h; /*@=compdef =usereleased@*/
/*@=retexpose =retalias@*/
}
-/*@=compmempass@*/
static void rpmdbSortIterator(/*@null@*/ rpmdbMatchIterator mi)
/*@modifies mi @*/
@@ -2236,11 +2219,11 @@ DBT * data = alloca(sizeof(*data));
if (isLabel) {
/* XXX HACK to get rpmdbFindByLabel out of the API */
xx = dbiCopen(dbi, dbi->dbi_txnid, &dbcursor, 0);
- rc = dbiFindByLabel(dbi, dbcursor, keyp, &set);
+ rc = dbiFindByLabel(dbi, dbcursor, key, data, keyp, &set);
xx = dbiCclose(dbi, dbcursor, 0);
dbcursor = NULL;
} else if (rpmtag == RPMTAG_BASENAMES) {
- rc = rpmdbFindByFile(db, keyp, &set);
+ rc = rpmdbFindByFile(db, keyp, key, data, &set);
} else {
xx = dbiCopen(dbi, dbi->dbi_txnid, &dbcursor, 0);
@@ -2643,9 +2626,7 @@ DBT * data = alloca(sizeof(*data));
memset(data, 0, sizeof(*data));
/*@i@*/ data->data = datap;
data->size = datalen;
-/*@-compmempass@*/
rc = dbiGet(dbi, dbcursor, key, data, DB_SET);
-/*@=compmempass@*/
keyp = key->data;
keylen = key->size;
datap = data->data;
@@ -2673,9 +2654,7 @@ DBT * data = alloca(sizeof(*data));
/*@=kepttrans@*/
data->size = datalen;
-/*@-compmempass@*/
rc = dbiPut(dbi, dbcursor, key, data, 0);
-/*@=compmempass@*/
xx = dbiSync(dbi, 0);
xx = dbiCclose(dbi, dbcursor, DB_WRITECURSOR);
@@ -2982,9 +2961,7 @@ key->data = (void *) fpList[i].baseName;
key->size = strlen((char *)key->data);
if (key->size == 0) key->size++; /* XXX "/" fixup. */
- /*@-compmempass@*/
xx = rpmdbGrowIterator(mi, key, i);
- /*@=compmempass@*/
matchList[i] = xcalloc(1, sizeof(*(matchList[i])));
}
@@ -3461,4 +3438,4 @@ exit:
}
/*@=globs@*/
/*@=mods@*/
-/*@=sizeoftype @*/
+/*@=compmempass =sizeoftype @*/
diff --git a/rpmdb/rpmdb.h b/rpmdb/rpmdb.h
index e07cc5a80..4bbd57fab 100644
--- a/rpmdb/rpmdb.h
+++ b/rpmdb/rpmdb.h
@@ -54,7 +54,7 @@ struct _dbiVec {
* @return 0 on success
*/
int (*open) (rpmdb rpmdb, rpmTag rpmtag, /*@out@*/ dbiIndex * dbip)
- /*@globals fileSystem@*/
+ /*@globals fileSystem @*/
/*@modifies *dbip, fileSystem @*/;
/** \ingroup dbi
@@ -64,7 +64,7 @@ struct _dbiVec {
* @return 0 on success
*/
int (*close) (/*@only@*/ dbiIndex dbi, unsigned int flags)
- /*@globals fileSystem@*/
+ /*@globals fileSystem @*/
/*@modifies dbi, fileSystem @*/;
/** \ingroup dbi
@@ -74,20 +74,47 @@ struct _dbiVec {
* @return 0 on success
*/
int (*sync) (dbiIndex dbi, unsigned int flags)
- /*@globals fileSystem@*/
+ /*@globals fileSystem @*/
/*@modifies fileSystem @*/;
/** \ingroup dbi
+ * Associate secondary database with primary.
+ * @param dbi index database handle
+ * @param dbisecondary secondary index database handle
+ * @param callback create secondary key from primary (NULL if DB_RDONLY)
+ * @param flags DB_CREATE or 0
+ * @return 0 on success
+ */
+ int (*associate) (dbiIndex dbi, dbiIndex dbisecondary,
+ int (*callback) (DB *, const DBT *, const DBT *, DBT *),
+ unsigned int flags)
+ /*@globals fileSystem @*/
+ /*@modifies dbi, fileSystem @*/;
+
+/** \ingroup dbi
+ * Return join cursor for list of cursors.
+ * @param dbi index database handle
+ * @param curslist NULL terminated list of database cursors
+ * @retval dbcp address of join database cursor
+ * @param flags DB_JOIN_NOSORT or 0
+ * @return 0 on success
+ */
+ int (*join) (dbiIndex dbi, DBC ** curslist, /*@out@*/ DBC ** dbcp,
+ unsigned int flags)
+ /*@globals fileSystem @*/
+ /*@modifies dbi, *dbcp, fileSystem @*/;
+
+/** \ingroup dbi
* Open database cursor.
* @param dbi index database handle
* @param txnid database transaction handle
- * @retval dbcp address of database cursor
- * @param flags (unused)
+ * @retval dbcp address of new database cursor
+ * @param dbiflags DB_WRITECURSOR or 0
* @return 0 on success
*/
int (*copen) (dbiIndex dbi, /*@null@*/ DB_TXN * txnid,
- /*@out@*/ DBC ** dbcp, unsigned int flags)
- /*@globals fileSystem@*/
+ /*@out@*/ DBC ** dbcp, unsigned int dbiflags)
+ /*@globals fileSystem @*/
/*@modifies dbi, *txnid, *dbcp, fileSystem @*/;
/** \ingroup dbi
@@ -98,10 +125,23 @@ struct _dbiVec {
* @return 0 on success
*/
int (*cclose) (dbiIndex dbi, /*@only@*/ DBC * dbcursor, unsigned int flags)
- /*@globals fileSystem@*/
+ /*@globals fileSystem @*/
/*@modifies dbi, *dbcursor, fileSystem @*/;
/** \ingroup dbi
+ * Duplicate a database cursor.
+ * @param dbi index database handle
+ * @param dbcursor database cursor
+ * @retval dbcp address of new database cursor
+ * @param flags DB_POSITION for same position, 0 for uninitialized
+ * @return 0 on success
+ */
+ int (*cdup) (dbiIndex dbi, DBC * dbcursor, /*@out@*/ DBC ** dbcp,
+ unsigned int flags)
+ /*@globals fileSystem @*/
+ /*@modifies dbi, *dbcp, fileSystem @*/;
+
+/** \ingroup dbi
* Delete (key,data) pair(s) using db->del or dbcursor->c_del.
* @param dbi index database handle
* @param dbcursor database cursor (NULL will use db->del)
@@ -112,7 +152,7 @@ struct _dbiVec {
*/
int (*cdel) (dbiIndex dbi, /*@null@*/ DBC * dbcursor, DBT * key, DBT * data,
unsigned int flags)
- /*@globals fileSystem@*/
+ /*@globals fileSystem @*/
/*@modifies *dbcursor, fileSystem @*/;
/** \ingroup dbi
@@ -126,10 +166,25 @@ struct _dbiVec {
*/
int (*cget) (dbiIndex dbi, /*@null@*/ DBC * dbcursor, DBT * key, DBT * data,
unsigned int flags)
- /*@globals fileSystem@*/
+ /*@globals fileSystem @*/
/*@modifies *dbcursor, *key, *data, fileSystem @*/;
/** \ingroup dbi
+ * Retrieve (key,data) pair using dbcursor->c_pget.
+ * @param dbi index database handle
+ * @param dbcursor database cursor
+ * @param key secondary retrieve key value/length/flags
+ * @param pkey primary retrieve key value/length/flags
+ * @param data primary retrieve data value/length/flags
+ * @param flags DB_NEXT, DB_SET, or 0
+ * @return 0 on success
+ */
+ int (*cpget) (dbiIndex dbi, /*@null@*/ DBC * dbcursor,
+ DBT * key, DBT * pkey, DBT * data, unsigned int flags)
+ /*@globals fileSystem @*/
+ /*@modifies *dbcursor, *key, *pkey, *data, fileSystem @*/;
+
+/** \ingroup dbi
* Store (key,data) pair using db->put or dbcursor->c_put.
* @param dbi index database handle
* @param dbcursor database cursor (NULL will use db->put)
@@ -140,7 +195,7 @@ struct _dbiVec {
*/
int (*cput) (dbiIndex dbi, /*@null@*/ DBC * dbcursor, DBT * key, DBT * data,
unsigned int flags)
- /*@globals fileSystem@*/
+ /*@globals fileSystem @*/
/*@modifies *dbcursor, fileSystem @*/;
/** \ingroup dbi
@@ -154,7 +209,7 @@ struct _dbiVec {
int (*ccount) (dbiIndex dbi, DBC * dbcursor,
/*@out@*/ unsigned int * countp,
unsigned int flags)
- /*@globals fileSystem@*/
+ /*@globals fileSystem @*/
/*@modifies *dbcursor, fileSystem @*/;
/** \ingroup dbi
@@ -163,8 +218,8 @@ struct _dbiVec {
* @return 0 no
*/
int (*byteswapped) (dbiIndex dbi)
- /*@globals fileSystem@*/
- /*@modifies fileSystem@*/;
+ /*@globals fileSystem @*/
+ /*@modifies fileSystem @*/;
/** \ingroup dbi
* Save statistics in database handle.
@@ -173,7 +228,7 @@ struct _dbiVec {
* @return 0 on success
*/
int (*stat) (dbiIndex dbi, unsigned int flags)
- /*@globals fileSystem@*/
+ /*@globals fileSystem @*/
/*@modifies dbi, fileSystem @*/;
};
@@ -226,7 +281,7 @@ struct _dbiIndex {
int dbi_lorder;
/*@unused@*/
void (*db_errcall) (const char *db_errpfx, char *buffer)
- /*@globals fileSystem@*/
+ /*@globals fileSystem @*/
/*@modifies fileSystem @*/;
/*@unused@*/ /*@shared@*/
FILE * dbi_errfile;
@@ -250,7 +305,7 @@ struct _dbiIndex {
#if 0
int (*dbi_tx_recover) (DB_ENV *dbenv, DBT *log_rec,
DB_LSN *lsnp, int redo, void *info)
- /*@globals fileSystem@*/
+ /*@globals fileSystem @*/
/*@modifies fileSystem @*/;
#endif
/* dbinfo parameters */
@@ -409,7 +464,7 @@ extern const char *const prDbiOpenFlags(int dbflags, int print_dbenv_flags)
/*@unused@*/ static inline
int dbiCopen(dbiIndex dbi, /*@null@*/ DB_TXN * txnid,
/*@out@*/ DBC ** dbcp, unsigned int flags)
- /*@globals fileSystem@*/
+ /*@globals fileSystem @*/
/*@modifies dbi, *dbcp, fileSystem @*/
{
return (*dbi->dbi_vec->copen) (dbi, txnid, dbcp, flags);
@@ -424,13 +479,29 @@ int dbiCopen(dbiIndex dbi, /*@null@*/ DB_TXN * txnid,
*/
/*@unused@*/ static inline
int dbiCclose(dbiIndex dbi, /*@only@*/ DBC * dbcursor, unsigned int flags)
- /*@globals fileSystem@*/
+ /*@globals fileSystem @*/
/*@modifies dbi, *dbcursor, fileSystem @*/
{
return (*dbi->dbi_vec->cclose) (dbi, dbcursor, flags);
}
/** \ingroup dbi
+ * Duplicate a database cursor.
+ * @param dbi index database handle
+ * @param dbcursor database cursor
+ * @retval dbcp address of new database cursor
+ * @param flags DB_POSITION for same position, 0 for uninitialized
+ * @return 0 on success
+ */
+/*@unused@*/ static inline
+int dbiCdup(dbiIndex dbi, DBC * dbcursor, /*@out@*/ DBC ** dbcp,
+ unsigned int flags)
+ /*@modifies dbi, *dbcp @*/
+{
+ return (*dbi->dbi_vec->cdup) (dbi, dbcursor, dbcp, flags);
+}
+
+/** \ingroup dbi
* Delete (key,data) pair(s) from index database.
* @param dbi index database handle
* @param dbcursor database cursor (NULL will use db->del)
@@ -442,7 +513,7 @@ int dbiCclose(dbiIndex dbi, /*@only@*/ DBC * dbcursor, unsigned int flags)
/*@unused@*/ static inline
int dbiDel(dbiIndex dbi, /*@null@*/ DBC * dbcursor, DBT * key, DBT * data,
unsigned int flags)
- /*@globals fileSystem@*/
+ /*@globals fileSystem @*/
/*@modifies *dbcursor, fileSystem @*/
{
assert(key->size > 0);
@@ -461,7 +532,7 @@ int dbiDel(dbiIndex dbi, /*@null@*/ DBC * dbcursor, DBT * key, DBT * data,
/*@unused@*/ static inline
int dbiGet(dbiIndex dbi, /*@null@*/ DBC * dbcursor, DBT * key, DBT * data,
unsigned int flags)
- /*@globals fileSystem@*/
+ /*@globals fileSystem @*/
/*@modifies *dbcursor, *key, *data, fileSystem @*/
{
assert((flags == DB_NEXT) || key->size > 0);
@@ -469,6 +540,26 @@ int dbiGet(dbiIndex dbi, /*@null@*/ DBC * dbcursor, DBT * key, DBT * data,
}
/** \ingroup dbi
+ * Retrieve (key,data) pair using dbcursor->c_pget.
+ * @param dbi index database handle
+ * @param dbcursor database cursor (NULL will use db->get)
+ * @param key secondary retrieve key value/length/flags
+ * @param pkey primary retrieve key value/length/flags
+ * @param data primary retrieve data value/length/flags
+ * @param flags DB_NEXT, DB_SET, or 0
+ * @return 0 on success
+ */
+/*@unused@*/ static inline
+int dbiPget(dbiIndex dbi, /*@null@*/ DBC * dbcursor,
+ DBT * key, DBT * pkey, DBT * data, unsigned int flags)
+ /*@globals fileSystem @*/
+ /*@modifies *dbcursor, *key, *pkey, *data, fileSystem @*/
+{
+ assert((flags == DB_NEXT) || key->size > 0);
+ return (dbi->dbi_vec->cpget) (dbi, dbcursor, key, pkey, data, flags);
+}
+
+/** \ingroup dbi
* Store (key,data) pair in index database.
* @param dbi index database handle
* @param dbcursor database cursor (NULL will use db->put)
@@ -480,7 +571,7 @@ int dbiGet(dbiIndex dbi, /*@null@*/ DBC * dbcursor, DBT * key, DBT * data,
/*@unused@*/ static inline
int dbiPut(dbiIndex dbi, /*@null@*/ DBC * dbcursor, DBT * key, DBT * data,
unsigned int flags)
- /*@globals fileSystem@*/
+ /*@globals fileSystem @*/
/*@modifies *dbcursor, *key, fileSystem @*/
{
assert(key->size > 0);
@@ -498,7 +589,7 @@ int dbiPut(dbiIndex dbi, /*@null@*/ DBC * dbcursor, DBT * key, DBT * data,
/*@unused@*/ static inline
int dbiCount(dbiIndex dbi, DBC * dbcursor, /*@out@*/ unsigned int * countp,
unsigned int flags)
- /*@globals fileSystem@*/
+ /*@globals fileSystem @*/
/*@modifies *dbcursor, fileSystem @*/
{
return (*dbi->dbi_vec->ccount) (dbi, dbcursor, countp, flags);
@@ -512,7 +603,7 @@ int dbiCount(dbiIndex dbi, DBC * dbcursor, /*@out@*/ unsigned int * countp,
*/
/*@unused@*/ static inline
int dbiVerify(/*@only@*/ dbiIndex dbi, unsigned int flags)
- /*@globals fileSystem@*/
+ /*@globals fileSystem @*/
/*@modifies dbi, fileSystem @*/
{
dbi->dbi_verify_on_close = 1;
@@ -527,7 +618,7 @@ int dbiVerify(/*@only@*/ dbiIndex dbi, unsigned int flags)
*/
/*@unused@*/ static inline
int dbiClose(/*@only@*/ dbiIndex dbi, unsigned int flags)
- /*@globals fileSystem@*/
+ /*@globals fileSystem @*/
/*@modifies dbi, fileSystem @*/
{
return (*dbi->dbi_vec->close) (dbi, flags);
@@ -541,13 +632,48 @@ int dbiClose(/*@only@*/ dbiIndex dbi, unsigned int flags)
*/
/*@unused@*/ static inline
int dbiSync (dbiIndex dbi, unsigned int flags)
- /*@globals fileSystem@*/
+ /*@globals fileSystem @*/
/*@modifies fileSystem @*/
{
return (*dbi->dbi_vec->sync) (dbi, flags);
}
/** \ingroup dbi
+ * Associate secondary database with primary.
+ * @param dbi index database handle
+ * @param dbisecondary secondary index database handle
+ * @param callback create secondary key from primary (NULL if DB_RDONLY)
+ * @param flags DB_CREATE or 0
+ * @return 0 on success
+ */
+/*@unused@*/ static inline
+int dbiAssociate(dbiIndex dbi, dbiIndex dbisecondary,
+ int (*callback) (DB *, const DBT *, const DBT *, DBT *),
+ unsigned int flags)
+ /*@globals fileSystem @*/
+ /*@modifies dbi, fileSystem @*/
+{
+ return (*dbi->dbi_vec->associate) (dbi, dbisecondary, callback, flags);
+}
+
+/** \ingroup dbi
+ * Return join cursor for list of cursors.
+ * @param dbi index database handle
+ * @param curslist NULL terminated list of database cursors
+ * @retval dbcp address of join database cursor
+ * @param flags DB_JOIN_NOSORT or 0
+ * @return 0 on success
+ */
+/*@unused@*/ static inline
+int dbiJoin(dbiIndex dbi, DBC ** curslist, /*@out@*/ DBC ** dbcp,
+ unsigned int flags)
+ /*@globals fileSystem @*/
+ /*@modifies dbi, *dbcp, fileSystem @*/
+{
+ return (*dbi->dbi_vec->join) (dbi, curslist, dbcp, flags);
+}
+
+/** \ingroup dbi
* Is database byte swapped?
* @param dbi index database handle
* @return 0 no