RPM Package Manager, CVS Repository
  http://rpm5.org/cvs/
  ____________________________________________________________________________

  Server: rpm5.org                         Name:   Jeff Johnson
  Root:   /v/rpm/cvs                       Email:  j...@rpm5.org
  Module: rpm                              Date:   22-Jul-2017 16:19:33
  Branch: rpm-5_4                          Handle: 2017072214193300

  Modified files:           (Branch: rpm-5_4)
    rpm/rpmdb               Makefile.am lmdb.c

  Log:
    - lmdb: stub-in the rpm.org lib/backend/ndb/glue.c layer.

  Summary:
    Revision    Changes     Path
    1.134.2.38  +6  -0      rpm/rpmdb/Makefile.am
    1.1.2.2     +905 -6     rpm/rpmdb/lmdb.c
  ____________________________________________________________________________

  patch -p0 <<'@@ .'
  Index: rpm/rpmdb/Makefile.am
  ============================================================================
  $ cvs diff -u -r1.134.2.37 -r1.134.2.38 Makefile.am
  --- rpm/rpmdb/Makefile.am     21 Jul 2017 15:14:23 -0000      1.134.2.37
  +++ rpm/rpmdb/Makefile.am     22 Jul 2017 14:19:33 -0000      1.134.2.38
  @@ -329,9 +329,15 @@
   logio_SOURCES = logio.c logio.h
   logio_LDADD = $(mylibs)
   
  +lmdb_CFLAGS = -I/X/src/rpm/include -I/X/src/rpm
   lmdb_SOURCES = lmdb.c
   lmdb_LDADD = $(mylibs)
   
  +ltest: lmdb
  +     rm -rf testdb && mkdir testdb
  +     ./lmdb
  +     ls -al testdb
  +
   #libsqldb_la_SOURCES = libsqldb.c # sqlite.c
   #libsqldb_la_LIBADD  = $(RPMIO_LDADD_COMMON)
   
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmdb/lmdb.c
  ============================================================================
  $ cvs diff -u -r1.1.2.1 -r1.1.2.2 lmdb.c
  --- rpm/rpmdb/lmdb.c  21 Jul 2017 15:14:23 -0000      1.1.2.1
  +++ rpm/rpmdb/lmdb.c  22 Jul 2017 14:19:33 -0000      1.1.2.2
  @@ -1,16 +1,909 @@
  -#include <stdio.h>
  -#include <stdlib.h>
  -#include <time.h>
  +#include "system.h"
  +
  +#include <rpmio.h>
  +#include <rpmlog.h>
  +#include <argv.h>
  +#include <poptIO.h>
  +
   #include "lmdb.h"
   
  +#include "debug.h"
  +
  +static int _debug = -1;
  +
   #define E(expr) CHECK((rc = (expr)) == MDB_SUCCESS, #expr)
   #define RES(err, expr) ((rc = expr) == (err) || (CHECK(!rc, #expr), 0))
   #define CHECK(test, msg) ((test) ? (void)0 : ((void)fprintf(stderr, \
        "%s:%d: %s: %s\n", __FILE__, __LINE__, msg, mdb_strerror(rc)), abort()))
   
  +/*==============================================================*/
  +
  +#define H_RPMSW
  +
  +#define _RPMTYPES_H
  +typedef struct headerToken_s * Header;
  +typedef int32_t         rpm_tag_t;
  +typedef uint32_t        rpm_tagtype_t;
  +typedef uint32_t        rpm_count_t;
  +typedef rpm_tag_t       rpmTagVal;
  +
  +typedef struct rpmts_s * rpmts;
  +typedef      void *  rpmDbiTag;
  +
  +typedef rpm_tag_t       rpmDbiTagVal;
  +
  +typedef struct dbiIndex_s * dbiIndex;
  +typedef struct dbiCursor_s * dbiCursor;
  +typedef struct dbiIndexSet_s * dbiIndexSet;
  +
  +typedef struct rpmdb_s * rpmdb;
  +
  +#ifdef       REFERENCE
  +struct dbConfig_s {
  +    int      db_mmapsize;    /*!< (10Mb) */
  +    int      db_cachesize;   /*!< (128Kb) */
  +    int      db_verbose;
  +    int      db_no_fsync;    /*!< no-op fsync for db */
  +    int db_eflags;   /*!< obsolete */
  +};
  +
  +struct dbiConfig_s {
  +    int      dbi_oflags;             /*!< open flags */
  +    int      dbi_no_dbsync;          /*!< don't call dbiSync */
  +    int      dbi_lockdbfd;           /*!< do fcntl lock on db fd */
  +};
  +
  +struct rpmdbOps_s;
  +
  +/** \ingroup rpmdb
  + * Describes the collection of index databases used by rpm.
  + */
  +struct rpmdb_s {
  +    char     * db_root;/*!< path prefix */
  +    char     * db_home;/*!< directory path */
  +    char     * db_fullpath;  /*!< full db path including prefix */
  +    int              db_flags;
  +    int              db_mode;        /*!< open mode */
  +    int              db_perms;       /*!< open permissions */
  +    char     * db_descr;     /*!< db backend description (for error msgs) */
  +    struct dbChk_s * db_checked;/*!< headerCheck()'ed package instances */
  +    rpmdb    db_next;
  +    int              db_opens;
  +    dbiIndex db_pkgs;        /*!< Package db */
  +    const rpmDbiTag * db_tags;
  +    int              db_ndbi;        /*!< No. of tag indices. */
  +    dbiIndex         * db_indexes;   /*!< Tag indices. */
  +    int              db_buildindex;  /*!< Index rebuild indicator */
  +
  +    struct rpmdbOps_s * db_ops;      /*!< backend ops */
  +
  +    /* dbenv and related parameters */
  +    void * db_dbenv;         /*!< Backend private handle */
  +    struct dbConfig_s cfg;
  +    int db_remove_env;
  +
  +    struct rpmop_s db_getops;
  +    struct rpmop_s db_putops;
  +    struct rpmop_s db_delops;
  +
  +    int nrefs;                       /*!< Reference count. */
  +};
  +#endif       /* REFERENCE */
  +
  +typedef struct miRE_s * miRE;
  +
  +typedef struct rpmdbMatchIterator_s * rpmdbMatchIterator;
  +struct rpmdbMatchIterator_s {
  +    rpmdbMatchIterator  mi_next;
  +    rpmdb               mi_db;
  +    rpmDbiTagVal        mi_rpmtag;
  +    dbiIndexSet         mi_set;
  +    dbiCursor           mi_dbc;
  +    int                 mi_setx;
  +    Header              mi_h;
  +    int                 mi_sorted;
  +    int                 mi_cflags;
  +    int                 mi_modified;
  +    unsigned int        mi_prevoffset;  /* header instance (native endian) */
  +    unsigned int        mi_offset;      /* header instance (native endian) */
  +    unsigned int        mi_filenum;     /* tag element (native endian) */
  +    int                 mi_nre;
  +    miRE                mi_re;
  +    rpmts               mi_ts;
  +    rpmRC (*mi_hdrchk) (rpmts ts, const void * uh, size_t uc, char ** msg);
  +};
  +
  +typedef struct rpmdbIndexIterator_s * rpmdbIndexIterator;
  +struct rpmdbIndexIterator_s {
  +    rpmdbIndexIterator  ii_next;
  +    rpmdb               ii_db;
  +    dbiIndex            ii_dbi;
  +    rpmDbiTag           ii_rpmtag;
  +    dbiCursor           ii_dbc;
  +    dbiIndexSet         ii_set;
  +    unsigned int        *ii_hdrNums;
  +};
  +
  +#define _RPMUTIL_H
  +
  +#include "lib/rpmdb_internal.h"
  +
  +/*==============================================================*/
  +RPM_GNUC_PURE
  +dbiIndex dbiFree(dbiIndex dbi)
  +{
  +    if (dbi)
  +        free(dbi);
  +    return NULL;
  +}
  +
  +#define      RPMDBI_PACKAGES         0
  +dbiIndex dbiNew(rpmdb rdb, rpmDbiTagVal rpmtag)
  +{
  +    dbiIndex dbi = xcalloc(1, sizeof(*dbi));
  +    dbi->dbi_rpmdb = rdb;
  +#ifdef       NOTYET
  +    dbi->dbi_file = rpmTagGetName(rpmtag);
  +#endif
  +    dbi->dbi_type = (rpmtag == RPMDBI_PACKAGES) ? DBI_PRIMARY : 
DBI_SECONDARY;
  +    dbi->dbi_byteswapped = -1;  /* -1 unknown, 0 native order, 1 alien order 
*/
  +    return dbi;
  +}
  +
  +RPM_GNUC_PURE
  +const char * dbiName(dbiIndex dbi)
  +{
  +    return dbi->dbi_file;
  +}
  +
  +RPM_GNUC_PURE
  +int dbiFlags(dbiIndex dbi)
  +{
  +    return dbi->dbi_flags;
  +}
  +
  +void dbiIndexSetGrow(dbiIndexSet set, unsigned int nrecs)
  +{
  +    size_t need = (set->count + nrecs) * sizeof(*(set->recs));
  +    size_t alloced = set->alloced ? set->alloced : 1 << 4;
  +
  +    while (alloced < need)
  +     alloced <<= 1;
  +
  +    if (alloced != set->alloced) {
  +     set->recs = xrealloc(set->recs, alloced);
  +     set->alloced = alloced;
  +    }
  +}
  +
  +dbiIndexSet dbiIndexSetNew(unsigned int sizehint)
  +{
  +    dbiIndexSet set = xcalloc(1, sizeof(*set));
  +    if (sizehint > 0)
  +     dbiIndexSetGrow(set, sizehint);
  +    return set;
  +}
  +
  +#define      rpmChrootDone() (0)
  +
  +RPM_GNUC_PURE
  +const char *rpmdbHome(rpmdb db)
  +{
  +    const char *dbdir = NULL;
  +    if (db) {
  +        dbdir = rpmChrootDone() ? db->db_home : db->db_fullpath;
  +    }
  +    return dbdir;
  +}
  +
  +/*==============================================================*/
  +typedef struct rpmpkgdb_s * rpmpkgdb;
  +
  +RPM_GNUC_CONST
  +void rpmpkgClose(rpmpkgdb pkgdb)
  +{
  +}
  +
  +RPM_GNUC_CONST
  +int rpmpkgOpen(rpmpkgdb *pkgdbp, const char *filename, int flags, int mode)
  +{
  +    return RPMRC_FAIL;
  +}
  +
  +static int rpmpkgGetLock(rpmpkgdb pkgdb, int type)
  +{
  +#ifdef       NOTYET
  +    if (!pkgdb->fd)
  +     return RPMRC_FAIL;
  +    for (;;) {
  +     if (flock(pkgdb->fd, type)) {
  +         return RPMRC_FAIL;
  +     }
  +     if (!is_correct_db(pkgdb)) {
  +         if (reopen_db(pkgdb)) {
  +             return RPMRC_FAIL;
  +         }
  +         continue;
  +     }
  +     break;
  +    }
  +#endif
  +    return RPMRC_OK;
  +}
  +
  +RPM_GNUC_CONST
  +int rpmpkgLock(rpmpkgdb pkgdb, int excl)
  +{
  +#ifdef       NOTYET
  +    unsigned int *lockcntp = excl ? &pkgdb->locked_excl : 
&pkgdb->locked_shared;
  +    if (*lockcntp > 0 || (!excl && pkgdb->locked_excl)) {
  +     (*lockcntp)++;
  +     return RPMRC_OK;
  +    }
  +    pkgdb->header_ok = 0;
  +    if (rpmpkgGetLock(pkgdb, excl ? LOCK_EX : LOCK_SH)) {
  +     return RPMRC_FAIL;
  +    }
  +    (*lockcntp)++;
  +#endif
  +    return RPMRC_OK;
  +}
  +
  +RPM_GNUC_CONST
  +int rpmpkgUnlock(rpmpkgdb pkgdb, int excl)
  +{
  +#ifdef       NOTYET
  +    unsigned int *lockcntp = excl ? &pkgdb->locked_excl : 
&pkgdb->locked_shared;
  +    if (*lockcntp == 0) {
  +     return RPMRC_FAIL;
  +    }
  +    if (*lockcntp > 1 || (!excl && pkgdb->locked_excl)) {
  +     (*lockcntp)--;
  +     return RPMRC_OK;
  +    }
  +    if (excl && pkgdb->locked_shared) {
  +     /* excl -> shared switch */
  +     if (rpmpkgGetLock(pkgdb, LOCK_SH)) {
  +         return RPMRC_FAIL;
  +     }
  +     (*lockcntp)--;
  +     return RPMRC_OK;
  +    }
  +    flock(pkgdb->fd, LOCK_UN);
  +    (*lockcntp)--;
  +    pkgdb->header_ok = 0;
  +#endif
  +    return RPMRC_OK;
  +}
  +
  +RPM_GNUC_CONST
  +int rpmpkgGet(rpmpkgdb pkgdb, unsigned int pkgidx, unsigned char **blobp, 
unsigned int *bloblp)
  +{
  +    return RPMRC_FAIL;
  +}
  +
  +RPM_GNUC_CONST
  +int rpmpkgPut(rpmpkgdb pkgdb, unsigned int pkgidx, unsigned char *blob, 
unsigned int blobl)
  +{
  +    return RPMRC_FAIL;
  +}
  +
  +RPM_GNUC_CONST
  +int rpmpkgDel(rpmpkgdb pkgdb, unsigned int pkgidx)
  +{
  +    return RPMRC_FAIL;
  +}
  +
  +RPM_GNUC_CONST
  +int rpmpkgList(rpmpkgdb pkgdb, unsigned int **pkgidxlistp, unsigned int 
*npkgidxlistp)
  +{
  +    return RPMRC_FAIL;
  +}
  +
  +RPM_GNUC_CONST
  +int rpmpkgGeneration(rpmpkgdb pkgdb, unsigned int *generationp)
  +{
  +    return RPMRC_FAIL;
  +}
  +
  +RPM_GNUC_CONST
  +int rpmpkgNextPkgIdx(rpmpkgdb pkgdb, unsigned int *pkgidxp)
  +{
  +    return RPMRC_FAIL;
  +}
  +
  +/*==============================================================*/
  +typedef struct rpmxdb_s * rpmxdb;
  +
  +RPM_GNUC_CONST
  +void rpmxdbClose(rpmxdb xdb)
  +{
  +}
  +
  +RPM_GNUC_CONST
  +int rpmxdbOpen(rpmxdb *xdbp, rpmpkgdb pkgdb, const char *filename, int 
flags, int mode)
  +{
  +    return RPMRC_FAIL;
  +}
  +
  +RPM_GNUC_CONST
  +int rpmxdbLookupBlob(rpmxdb xdb, unsigned int *idp, unsigned int blobtag, 
unsigned int subtag, int flags)
  +{
  +    return RPMRC_FAIL;
  +}
  +
  +RPM_GNUC_CONST
  +int rpmxdbIsRdonly(rpmxdb xdb)
  +{
  +    return 1;
  +}
  +
  +RPM_GNUC_CONST
  +int rpmxdbSetUserGeneration(rpmxdb xdb, unsigned int usergeneration)
  +{
  +    return RPMRC_FAIL;
  +}
  +
  +/*==============================================================*/
  +typedef struct rpmidxdb_s *rpmidxdb;
  +
  +RPM_GNUC_CONST
  +void rpmidxClose(rpmidxdb idxdb)
  +{
  +}
  +
  +RPM_GNUC_CONST
  +int rpmidxOpen(rpmidxdb *idxdbp, rpmpkgdb pkgdb, const char *filename, int 
flags, int mode)
  +{
  +    return RPMRC_FAIL;
  +}
  +
  +RPM_GNUC_CONST
  +int rpmidxGet(rpmidxdb idxdb, const unsigned char *key, unsigned int keyl, 
unsigned int **pkgidxlistp, unsigned int *pkgidxnump)
  +{
  +    return RPMRC_FAIL;
  +}
  +
  +RPM_GNUC_CONST
  +int rpmidxPut(rpmidxdb idxdb, const unsigned char *key, unsigned int keyl, 
unsigned int pkgidx, unsigned int datidx)
  +{
  +    return RPMRC_FAIL;
  +}
  +
  +RPM_GNUC_CONST
  +int rpmidxDel(rpmidxdb idxdb, const unsigned char *key, unsigned int keyl, 
unsigned int pkgidx, unsigned int datidx)
  +{
  +    return RPMRC_FAIL;
  +}
  +
  +RPM_GNUC_CONST
  +int rpmidxList(rpmidxdb idxdb, unsigned int **keylistp, unsigned int 
*nkeylistp, unsigned char **datap)
  +{
  +    return RPMRC_FAIL;
  +}
  +
  +RPM_GNUC_CONST
  +int rpmidxOpenXdb(rpmidxdb *idxdbp, rpmpkgdb pkgdb, rpmxdb xdb, unsigned int 
xdbtag)
  +{
  +    return RPMRC_FAIL;
  +}
  +
  +/*==============================================================*/
  +
  +struct dbiCursor_s {
  +    dbiIndex dbi; 
  +    const void *key;
  +    unsigned int keylen;
  +    unsigned int hdrNum;
  +    int flags;
  +
  +    unsigned int *list;
  +    unsigned int nlist;
  +    unsigned int ilist;
  +    unsigned char *listdata;
  +};
  +
  +struct lmdbEnv_s {
  +    rpmpkgdb pkgdb;
  +    rpmxdb xdb;
  +    int refs;
  +
  +    unsigned int hdrNum;
  +    void *data;
  +    unsigned int datalen;
  +};
  +
  +static void closeEnv(rpmdb rdb)
  +{
  +    struct lmdbEnv_s *lmdbenv = rdb->db_dbenv;
  +    if (--lmdbenv->refs == 0) {
  +     if (lmdbenv->xdb) {
  +         rpmxdbClose(lmdbenv->xdb);
  +         rpmlog(RPMLOG_DEBUG, "closed   db index       %s/Index.db\n", 
rpmdbHome(rdb));
  +     }
  +     if (lmdbenv->pkgdb) {
  +         rpmpkgClose(lmdbenv->pkgdb);
  +         rpmlog(RPMLOG_DEBUG, "closed   db index       %s/Packages.db\n", 
rpmdbHome(rdb));
  +     }
  +     if (lmdbenv->data)
  +         free(lmdbenv->data);
  +     free(lmdbenv);
  +     rdb->db_dbenv = 0;
  +    }
  +}
  +
  +static struct lmdbEnv_s *openEnv(rpmdb rdb)
  +{
  +    struct lmdbEnv_s *lmdbenv = rdb->db_dbenv;
  +    if (!lmdbenv)
  +     rdb->db_dbenv = lmdbenv = xcalloc(1, sizeof(struct lmdbEnv_s));
  +    lmdbenv->refs++;
  +    return lmdbenv;
  +}
  +
  +static int lmdb_Close(dbiIndex dbi, unsigned int flags)
  +{
  +    rpmdb rdb = dbi->dbi_rpmdb;
  +    if (dbi->dbi_type != DBI_PRIMARY && dbi->dbi_db) {
  +     rpmidxClose(dbi->dbi_db);
  +     rpmlog(RPMLOG_DEBUG, "closed   db index       %s\n", dbi->dbi_file);
  +    }
  +    if (rdb->db_dbenv)
  +     closeEnv(rdb);
  +    dbi->dbi_db = 0;
  +    return 0;
  +}
  +
  +static int lmdb_Open(rpmdb rdb, rpmDbiTagVal rpmtag, dbiIndex * dbip, int 
flags)
  +{
  +    const char *dbhome = rpmdbHome(rdb);
  +    struct lmdbEnv_s *lmdbenv;
  +    dbiIndex dbi;
  +    int oflags, ioflags;
  +    int rc = -1;
  +
  +    if (dbip)
  +     *dbip = NULL;
  +
  +    if ((dbi = dbiNew(rdb, rpmtag)) == NULL)
  +     return 1;
  +
  +    lmdbenv = openEnv(rdb);
  +
  +    oflags = O_RDWR;
  +    if ((rdb->db_mode & O_ACCMODE) == O_RDONLY)
  +     oflags = O_RDONLY;
  +    
  +    if (dbi->dbi_type == DBI_PRIMARY) {
  +     rpmpkgdb pkgdb = 0;
  +     char *path = rpmGetPath(dbhome, "/Packages.db", NULL);
  +     rpmlog(RPMLOG_DEBUG, "opening  db index       %s mode=0x%x\n", path, 
rdb->db_mode);
  +     rc = rpmpkgOpen(&pkgdb, path, oflags, 0666);
  +     if (rc && errno == ENOENT) {
  +         oflags = O_RDWR|O_CREAT;
  +         dbi->dbi_flags |= DBI_CREATED;
  +         rc = rpmpkgOpen(&pkgdb, path, oflags, 0666);
  +     }
  +     if (rc) {
  +         perror("rpmpkgOpen");
  +         free(path);
  +         lmdb_Close(dbi, 0);
  +         return 1;
  +     }
  +     free(path);
  +     dbi->dbi_db = lmdbenv->pkgdb = pkgdb;
  +
  +     if ((oflags & (O_RDWR | O_RDONLY)) == O_RDONLY)
  +         dbi->dbi_flags |= DBI_RDONLY;
  +    } else {
  +     unsigned int id;
  +     rpmidxdb idxdb = 0;
  +     if (!lmdbenv->pkgdb) {
  +         lmdb_Close(dbi, 0);
  +         return 1;   /* please open primary first */
  +     }
  +     if (!lmdbenv->xdb) {
  +         char *path = rpmGetPath(dbhome, "/Index.db", NULL);
  +         rpmlog(RPMLOG_DEBUG, "opening  db index       %s mode=0x%x\n", 
path, rdb->db_mode);
  +
  +         /* Open indexes readwrite if possible */
  +         ioflags = O_RDWR;
  +         rc = rpmxdbOpen(&lmdbenv->xdb, rdb->db_pkgs->dbi_db, path, ioflags, 
0666);
  +         if (rc && errno == EACCES) {
  +             /* If it is not asked for rw explicitly, try to open ro */
  +             if (!(oflags & O_RDWR)) {
  +                 ioflags = O_RDONLY;
  +                 rc = rpmxdbOpen(&lmdbenv->xdb, rdb->db_pkgs->dbi_db, path, 
ioflags, 0666);
  +             }
  +         } else if (rc && errno == ENOENT) {
  +             ioflags = O_CREAT|O_RDWR;
  +             rc = rpmxdbOpen(&lmdbenv->xdb, rdb->db_pkgs->dbi_db, path, 
ioflags, 0666);
  +         }
  +         if (rc) {
  +             perror("rpmxdbOpen");
  +             free(path);
  +             lmdb_Close(dbi, 0);
  +             return 1;
  +         }
  +         free(path);
  +     }
  +     if (rpmxdbLookupBlob(lmdbenv->xdb, &id, rpmtag, 0, 0) == 
RPMRC_NOTFOUND) {
  +         dbi->dbi_flags |= DBI_CREATED;
  +     }
  +     rpmlog(RPMLOG_DEBUG, "opening  db index       %s tag=%d\n", 
dbiName(dbi), rpmtag);
  +     if (rpmidxOpenXdb(&idxdb, rdb->db_pkgs->dbi_db, lmdbenv->xdb, rpmtag)) {
  +         perror("rpmidxOpenXdb");
  +         lmdb_Close(dbi, 0);
  +         return 1;
  +     }
  +     dbi->dbi_db = idxdb;
  +
  +     if (rpmxdbIsRdonly(lmdbenv->xdb))
  +         dbi->dbi_flags |= DBI_RDONLY;
  +    }
  +
  +    if (dbip != NULL)
  +     *dbip = dbi;
  +    else
  +     lmdb_Close(dbi, 0);
  +
  +    return 0;
  +}
  +
  +static int lmdb_Verify(dbiIndex dbi, unsigned int flags)
  +{
  +    return 1;
  +}
  +
  +static void lmdb_SetFSync(rpmdb rdb, int enable)
  +{
  +}
  +
  +static int indexSync(rpmpkgdb pkgdb, rpmxdb xdb)
  +{
  +    int rc = 0;
  +    if (!pkgdb || !xdb)
  +        return 1;
  +    unsigned int generation = 0;
  +    if (rpmpkgLock(pkgdb, 1))
  +        return 1;
  +    if (rpmpkgGeneration(pkgdb, &generation)) {
  +        rpmpkgUnlock(pkgdb, 1);
  +        return 1;
  +    }
  +    rc = rpmxdbSetUserGeneration(xdb, generation);
  +    rpmpkgUnlock(pkgdb, 1);
  +    return rc;
  +}
  +
  +static int lmdb_Ctrl(rpmdb rdb, dbCtrlOp ctrl)
  +{
  +    struct lmdbEnv_s *lmdbenv = rdb->db_dbenv;
  +
  +    switch (ctrl) {
  +    case DB_CTRL_LOCK_RO:
  +     if (!rdb->db_pkgs)
  +         return 1;
  +     return rpmpkgLock(rdb->db_pkgs->dbi_db, 0);
  +     break;
  +    case DB_CTRL_LOCK_RW:
  +     if (!rdb->db_pkgs)
  +         return 1;
  +     return rpmpkgLock(rdb->db_pkgs->dbi_db, 1);
  +     break;
  +    case DB_CTRL_UNLOCK_RO:
  +     if (!rdb->db_pkgs)
  +         return 1;
  +     return rpmpkgUnlock(rdb->db_pkgs->dbi_db, 0);
  +     break;
  +    case DB_CTRL_UNLOCK_RW:
  +     if (!rdb->db_pkgs)
  +         return 1;
  +     return rpmpkgUnlock(rdb->db_pkgs->dbi_db, 1);
  +     break;
  +    case DB_CTRL_INDEXSYNC:
  +     if (!lmdbenv)
  +         return 1;
  +     return indexSync(lmdbenv->pkgdb, lmdbenv->xdb);
  +     break;
  +    default:
  +     break;
  +    }
  +    return 0;
  +}
  +
  +static dbiCursor lmdb_CursorInit(dbiIndex dbi, unsigned int flags)
  +{
  +    dbiCursor dbc = xcalloc(1, sizeof(*dbc));
  +    dbc->dbi = dbi;
  +    dbc->flags = flags;
  +    return dbc;
  +}
  +
  +static dbiCursor lmdb_CursorFree(dbiIndex dbi, dbiCursor dbc)
  +{
  +    if (dbc) {
  +     if (dbc->list)
  +         free(dbc->list);
  +     if (dbc->listdata)
  +         free(dbc->listdata);
  +     free(dbc);
  +    }
  +    return NULL;
  +}
  +
  +
  +static void setdata(dbiCursor dbc,  unsigned int hdrNum, unsigned char 
*hdrBlob, unsigned int hdrLen)
  +{
  +    struct lmdbEnv_s *lmdbenv = dbc->dbi->dbi_rpmdb->db_dbenv;
  +    if (lmdbenv->data)
  +     free(lmdbenv->data);
  +    lmdbenv->hdrNum  = hdrNum;
  +    lmdbenv->data    = hdrBlob;
  +    lmdbenv->datalen = hdrLen;
  +}
  +
  +static rpmRC lmdb_pkgdbNew(dbiIndex dbi, dbiCursor dbc,  unsigned int 
*hdrNum)
  +{
  +    int rc = RPMRC_FAIL;
  +    rc = rpmpkgNextPkgIdx(dbc->dbi->dbi_db, hdrNum);
  +    if (!rc)
  +     setdata(dbc, *hdrNum, 0, 0);
  +    return rc;
  +}
  +
  +static rpmRC lmdb_pkgdbPut(dbiIndex dbi, dbiCursor dbc,  unsigned int 
hdrNum, unsigned char *hdrBlob, unsigned int hdrLen)
  +{
  +    int rc = RPMRC_FAIL;
  +    rc = rpmpkgPut(dbc->dbi->dbi_db, hdrNum, hdrBlob, hdrLen);
  +    if (!rc) {
  +     dbc->hdrNum = hdrNum;
  +     setdata(dbc, hdrNum, 0, 0);
  +    }
  +    return rc;
  +}
  +
  +static rpmRC lmdb_pkgdbDel(dbiIndex dbi, dbiCursor dbc,  unsigned int hdrNum)
  +{
  +    int rc = RPMRC_FAIL;
  +    dbc->hdrNum = 0;
  +    setdata(dbc, 0, 0, 0);
  +    rc = rpmpkgDel(dbc->dbi->dbi_db, hdrNum);
  +    return rc;
  +}
  +
  +/* iterate over all packages */
  +static rpmRC lmdb_pkgdbIter(dbiIndex dbi, dbiCursor dbc, unsigned char 
**hdrBlob, unsigned int *hdrLen)
  +{
  +    int rc = RPMRC_FAIL;
  +    unsigned int hdrNum;
  +
  +    if (!dbc->list) {
  +     rc = rpmpkgList(dbc->dbi->dbi_db, &dbc->list, &dbc->nlist);
  +     if (rc)
  +         return rc;
  +     dbc->ilist = 0;
  +    }
  +    for (;;) {
  +     if (dbc->ilist >= dbc->nlist) {
  +         rc = RPMRC_NOTFOUND;
  +         break;
  +     }
  +     *hdrBlob = 0;
  +     hdrNum = dbc->list[dbc->ilist];
  +     rc = rpmpkgGet(dbc->dbi->dbi_db, hdrNum, hdrBlob, hdrLen);
  +     if (rc && rc != RPMRC_NOTFOUND)
  +         break;
  +     dbc->ilist++;
  +     if (!rc) {
  +         dbc->hdrNum = hdrNum;
  +         setdata(dbc, hdrNum, *hdrBlob, *hdrLen);
  +         break;
  +     }
  +    }
  +    return rc;
  +}
  +
  +static rpmRC lmdb_pkgdbGet(dbiIndex dbi, dbiCursor dbc, unsigned int hdrNum, 
unsigned char **hdrBlob, unsigned int *hdrLen)
  +{
  +    int rc = RPMRC_FAIL;
  +    struct lmdbEnv_s *lmdbenv = dbc->dbi->dbi_rpmdb->db_dbenv;
  +
  +    if (!hdrNum)
  +     return lmdb_pkgdbIter(dbi, dbc, hdrBlob, hdrLen);
  +    if (hdrNum == lmdbenv->hdrNum && lmdbenv->data) {
  +     *hdrBlob = lmdbenv->data;
  +     *hdrLen = lmdbenv->datalen;
  +     return RPMRC_OK;
  +    }
  +    rc = rpmpkgGet(dbc->dbi->dbi_db, hdrNum, hdrBlob, hdrLen);
  +    if (!rc) {
  +     dbc->hdrNum = hdrNum;
  +     setdata(dbc, hdrNum, *hdrBlob, *hdrLen);
  +    }
  +    return rc;
  +}
  +
  +static unsigned int lmdb_pkgdbKey(dbiIndex dbi, dbiCursor dbc)
  +{
  +    return dbc->hdrNum;
  +}
  +
  +
  +static void addtoset(dbiIndexSet *set, unsigned int *pkglist, unsigned int 
pkglistn)
  +{
  +    unsigned int i, j;
  +    dbiIndexSet newset = dbiIndexSetNew(pkglistn / 2);
  +    for (i = j = 0; i < pkglistn; i += 2) {
  +     newset->recs[j].hdrNum = pkglist[i];
  +     newset->recs[j].tagNum = pkglist[i + 1];
  +     j++;
  +    }
  +    newset->count = j;
  +    if (pkglist)
  +     free(pkglist);
  +    if (*set) {
  +#ifdef       NOTYET
  +     dbiIndexSetAppendSet(*set, newset, 0);
  +     dbiIndexSetFree(newset);
  +#endif
  +    } else
  +     *set = newset;
  +}
  +
  +/* Iterate over all index entries */
  +static rpmRC lmdb_idxdbIter(dbiIndex dbi, dbiCursor dbc, dbiIndexSet *set)
  +{
  +    int rc = RPMRC_FAIL;
  +    if (!dbc->list) {
  +     /* setup iteration list on first call */
  +     rc = rpmidxList(dbc->dbi->dbi_db, &dbc->list, &dbc->nlist, 
&dbc->listdata);
  +     if (rc)
  +         return rc;
  +     dbc->ilist = 0;
  +    }
  +    for (;;) {
  +     unsigned char *k;
  +     unsigned int kl;
  +     unsigned int *pkglist, pkglistn;
  +     if (dbc->ilist >= dbc->nlist) {
  +         rc = RPMRC_NOTFOUND;
  +         break;
  +     }
  +     k = dbc->listdata + dbc->list[dbc->ilist];
  +     kl = dbc->list[dbc->ilist + 1];
  +#if 0
  +     if (searchType == DBC_KEY_SEARCH) {
  +         dbc->ilist += 2;
  +         dbc->key = k;
  +         dbc->keylen = kl;
  +         rc = RPMRC_OK;
  +         break;
  +     }
  +#endif
  +     pkglist = 0;
  +     pkglistn = 0;
  +     rc = rpmidxGet(dbc->dbi->dbi_db, k, kl, &pkglist, &pkglistn);
  +     if (rc && rc != RPMRC_NOTFOUND)
  +         break;
  +     dbc->ilist += 2;
  +     if (!rc && pkglistn) {
  +         addtoset(set, pkglist, pkglistn);
  +         dbc->key = k;
  +         dbc->keylen = kl;
  +         break;
  +     }
  +     if (pkglist)
  +         free(pkglist);
  +    }
  +    return rc;
  +}
  +
  +static rpmRC lmdb_idxdbGet(dbiIndex dbi, dbiCursor dbc, const char *keyp, 
size_t keylen, dbiIndexSet *set, int searchType)
  +{
  +    int rc = RPMRC_FAIL;
  +    unsigned int *pkglist = 0, pkglistn = 0;
  +
  +    if (!keyp)
  +     return lmdb_idxdbIter(dbi, dbc, set);
  +
  +    if (searchType == DBC_PREFIX_SEARCH) {
  +     unsigned int *list = 0, nlist = 0, i = 0;
  +     unsigned char *listdata = 0;
  +     int rrc = RPMRC_NOTFOUND;
  +     rc = rpmidxList(dbc->dbi->dbi_db, &list, &nlist, &listdata);
  +     if (rc)
  +         return rc;
  +     for (i = 0; i < nlist && !rc; i += 2) {
  +         unsigned char *k = listdata + list[i];
  +         unsigned int kl = list[i + 1];
  +         if (kl < keylen || memcmp(k, keyp, keylen) != 0)
  +             continue;
  +         rc = lmdb_idxdbGet(dbi, dbc, (char *)k, kl, set, DBC_NORMAL_SEARCH);
  +         if (rc == RPMRC_NOTFOUND)
  +             rc = 0;
  +         else
  +             rrc = rc;
  +     }
  +     if (list)
  +         free(list);
  +     if (listdata)
  +         free(listdata);
  +     return rc ? rc : rrc;
  +    }
  +
  +    rc = rpmidxGet(dbc->dbi->dbi_db, (const unsigned char *)keyp, keylen, 
&pkglist, &pkglistn);
  +    if (!rc)
  +     addtoset(set, pkglist, pkglistn);
  +    return rc;
  +}
  +
  +static rpmRC lmdb_idxdbPut(dbiIndex dbi, dbiCursor dbc, const char *keyp, 
size_t keylen, dbiIndexItem rec)
  +{
  +    int rc = RPMRC_FAIL;
  +    rc = rpmidxPut(dbc->dbi->dbi_db, (const unsigned char *)keyp, keylen, 
rec->hdrNum, rec->tagNum);
  +    return rc;
  +}
  +
  +static rpmRC lmdb_idxdbDel(dbiIndex dbi, dbiCursor dbc, const char *keyp, 
size_t keylen, dbiIndexItem rec)
  +{
  +    int rc = RPMRC_FAIL;
  +    rc = rpmidxDel(dbc->dbi->dbi_db, (const unsigned char *)keyp, keylen, 
rec->hdrNum, rec->tagNum);
  +    return rc;
  +}
  +
  +static const void * lmdb_idxdbKey(dbiIndex dbi, dbiCursor dbc, unsigned int 
*keylen)
  +{
  +    if (dbc->key && keylen)
  +     *keylen = dbc->keylen;
  +    return dbc->key;
  +}
  +
  +
  +
  +struct rpmdbOps_s lmdb_dbops = {
  +    .open    = lmdb_Open,
  +    .close   = lmdb_Close,
  +    .verify  = lmdb_Verify,
  +    .setFSync        = lmdb_SetFSync,
  +    .ctrl    = lmdb_Ctrl,
  +
  +    .cursorInit      = lmdb_CursorInit,
  +    .cursorFree      = lmdb_CursorFree,
  +
  +    .pkgdbNew        = lmdb_pkgdbNew,
  +    .pkgdbPut        = lmdb_pkgdbPut,
  +    .pkgdbDel        = lmdb_pkgdbDel,
  +    .pkgdbGet        = lmdb_pkgdbGet,
  +    .pkgdbKey        = lmdb_pkgdbKey,
  +
  +    .idxdbGet        = lmdb_idxdbGet,
  +    .idxdbPut        = lmdb_idxdbPut,
  +    .idxdbDel        = lmdb_idxdbDel,
  +    .idxdbKey        = lmdb_idxdbKey
  +};
  +
  +
  +/*==============================================================*/
  +struct poptOption lmdbOptionsTable[] = {
  +  { "debug", 'd', POPT_ARG_VAL,                      &_debug, -1,
  +        NULL, NULL },
  +
  +  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmioAllPoptTable, 0,
  +     N_("Common options for all rpmio executables:"), NULL },
  +
  +  POPT_AUTOALIAS
  +  POPT_AUTOHELP
  +  POPT_TABLEEND
  +};
  +
  +struct rpmdb_s _rpmdb;
  +rpmdb rdb = &_rpmdb;
  +
   int main(int argc, char *argv[])
   {
  -    int i = 0, j = 0, rc;
  +    poptContext con = rpmioInit(argc, argv, lmdbOptionsTable);
  +    int ec = 0;
       MDB_env *env;
       MDB_dbi dbi;
       MDB_val key, data;
  @@ -21,11 +914,14 @@
       int count;
       int *values;
       char sval[32] = "";
  +    int rc;
  +    int i;
  +    int j;
   
       srand(time(NULL));
   
       count = (rand() % 384) + 64;
  -    values = (int *) malloc(count * sizeof(int));
  +    values = (int *) xmalloc(count * sizeof(int));
   
       for (i = 0; i < count; i++)
        values[i] = rand() % 1024;
  @@ -42,6 +938,7 @@
       key.mv_data = sval;
   
       printf("Adding %d values\n", count);
  +    j = 0;
       for (i = 0; i < count; i++) {
        sprintf(sval, "%03x %d foo bar", values[i], values[i]);
        /* Set <data> in each iteration, since MDB_NOOVERWRITE may modify it */
  @@ -160,5 +1057,7 @@
       mdb_dbi_close(env, dbi);
       mdb_env_close(env);
   
  -    return 0;
  +    con = rpmioFini(con);
  +
  +    return ec;
   }
  @@ .
______________________________________________________________________
RPM Package Manager                                    http://rpm5.org
CVS Sources Repository                                rpm-cvs@rpm5.org

Reply via email to