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

  Server: rpm5.org                         Name:   Jeff Johnson
  Root:   /v/rpm/cvs                       Email:  [email protected]
  Module: rpm                              Date:   18-Apr-2010 05:17:11
  Branch: HEAD                             Handle: 2010041803171000

  Modified files:
    rpm/rpmio               rpmsql.c rpmsql.h

  Log:
    - rpmsql: haul out the trash.

  Summary:
    Revision    Changes     Path
    2.44        +421 -271   rpm/rpmio/rpmsql.c
    2.21        +22 -6      rpm/rpmio/rpmsql.h
  ____________________________________________________________________________

  patch -p0 <<'@@ .'
  Index: rpm/rpmio/rpmsql.c
  ============================================================================
  $ cvs diff -u -r2.43 -r2.44 rpmsql.c
  --- rpm/rpmio/rpmsql.c        16 Apr 2010 21:07:47 -0000      2.43
  +++ rpm/rpmio/rpmsql.c        18 Apr 2010 03:17:10 -0000      2.44
  @@ -71,6 +71,10 @@
       
   
   VTDBG((stderr, "==> %s(%p)\n", __FUNCTION__, vt));
  +    vt->argv = argvFree(vt->argv);
  +    vt->argc = 0;
  +    vt->fields = argvFree(vt->fields);
  +    vt->nfields = 0;
       vt->cols = argvFree(vt->cols);
       vt->ncols = 0;
       vt->av = argvFree(vt->av);
  @@ -96,45 +100,142 @@
       return &VT->vt;
   }
   
  -rpmvt rpmvtNew(void * db, void * pModule, rpmvData vd, const char * prefix)
  +rpmvt rpmvtNew(void * db, void * pModule, const char *const * argv, rpmvd vd)
   {
       rpmvt vt = rpmvtLink(rpmvtGetPool(_rpmvtPool));
   
       vt->db = db;
  +    (void) argvAppend(&vt->argv, (ARGV_t) argv);
  +    vt->argc = argvCount(vt->argv);
  +    if (vd->split && *vd->split && vd->parse && *vd->parse) {
  +     char * parse = rpmExpand(vd->parse, NULL);
  +     int xx;
  +     xx = argvSplit(&vt->fields, parse, vd->split);
  +assert(xx == 0);
  +     vt->nfields = argvCount(vt->fields);
  +     parse = _free(parse);
  +    }
  +
       vt->av = NULL;
       vt->ac = 0;
  +
       vt->vd = vd;
  -    vt->prefix = prefix;
  +fprintf(stderr, "\tprefix: %s\n", vd->prefix);
  +fprintf(stderr, "\t split: %s\n", vd->split);
  +fprintf(stderr, "\t parse: %s\n", vd->parse);
  +fprintf(stderr, "\t nrows: %d\n", vd->nrows);
  +fprintf(stderr, "\t ncols: %d\n", vd->ncols);
  +
       return vt;
   }
   
  -static int rpmvtLoadArgv(rpmvt vt, int argc, const char *const * argv)
  +/*==============================================================*/
  +
  +static int rpmvtLoadArgv(rpmvt vt, rpmvt * vtp)
   {
  +    static const char _type[] = "TEXT";
       rpmsql sql = _rpmsqlI;
       sqlite3 * db = (sqlite3 *) vt->db;
  -    const char * _modName = argv[0];
  -    const char * _dbName = argv[1];
  -    const char * _tblName = argv[2];
  -    const char * url = (argv[3] ? argv[3] : "/");
  -    const char * path = NULL;
  -    int ut = urlPath(url, &path);
  -    char * fn = xstrdup(path);
  -    size_t nfn = strlen(fn);
  -    char * bn = (fn[nfn-1] == '/' ? fn : basename(fn));
  -    char * t = rpmExpand("CREATE TABLE ", _dbName, ".", _tblName,
  -             " ( '", (bn && *bn ? bn : "val"), "' TEXT);", NULL);
  +#define      modName vt->argv[0]
  +#define      dbName  vt->argv[1]
  +#define      tblName vt->argv[2]
  +
  +    rpmvd vd = vt->vd;
  +    const char * uprefix;
  +    const char * prefix;
  +
  +    char * s = NULL;
  +    size_t ns;
  +
  +    char * fn;
  +    size_t nfn;
  +    char * t, * te;
  +
  +    size_t nb;
       int rc = SQLITE_OK;
       int xx;
  +    int i;
   
  -VTDBG((stderr, "\t%s\n", t));
  -#ifdef       REFERENCE
  -/* XXX unsnark patterns from column names */
  -create virtual table yumdb using Argv(/var/lib/yum/yumdb/[a-z]/[0-9a-f]*);
  ---> rpmvtCreate(0x9b632d8,(nil),0x9b71628[4],0x9b6f358,0xbf8b2bac)
  -     CREATE TABLE main.yumdb ( '[0-9a-f]*' TEXT);
  -sqlite3_declare_vtab(0x9b632d8): rc(0) not an error
  -#endif
  +static const char _hidden[] = "\
  +\t'path' HIDDEN TEXT,\n\
  +\t'id' HIDDEN TEXT,\n\
  +";
  +
  +fprintf(stderr, "--> %s(%p,%p)\n", __FUNCTION__, vt, vtp);
  +argvPrint("vt->argv", (ARGV_t)vt->argv, NULL);
  +
  +    prefix = (vd->prefix ? vd->prefix : "");
  +    if (vt->argv[3]) {
  +     /* XXX slice out the quotes that sqlite passes through ...  */
  +     static char _quotes[] = "'\"";
  +     int quoted = (strchr(_quotes, *vt->argv[3]) != NULL);
  +     s = rpmExpand(vt->argv[3] + quoted, NULL);
  +     ns = strlen(s);
  +     if (quoted) s[--ns] = '\0';
  +     /* XXX Strip file:/// et al (if present). */
  +     (void) urlPath(s, &uprefix);
  +     /* XXX Prefer user override to global prefix (if absolute path). */
  +     if (*uprefix == '/')
  +         prefix = "";
  +    } else
  +     uprefix = NULL;
  +
  +    fn = rpmGetPath(prefix, uprefix, NULL);
  +    nfn = strlen(fn);
  +
  +    nb = 0;
  +    nb += sizeof("CREATE TABLE ") - 1;
  +    nb += strlen(dbName) + (sizeof(".")-1) + strlen(tblName);
  +    nb += (sizeof(" (\n")-1);
  +
  +    nb += strlen(_hidden);
  +
  +    if (vt->argc <= 4) {
  +assert(vt->fields);
  +     for (i = 0; i < vt->nfields; i++) {
  +         nb += sizeof("\t'' ,\n");
  +         nb += strlen(vt->fields[i]);
  +         nb += strlen(_type);
  +     }
  +    } else {
  +     for (i = 4; i < vt->argc; i++) {
  +         nb += sizeof("\t'' ,\n");
  +         nb += strlen(vt->argv[i]);
  +         nb += strlen(_type);
  +     }
  +    }
  +    nb--;
  +    nb += sizeof(");") - 1;
  +
  +    te = t = xmalloc(nb + 1);
  +    te = stpcpy(te, "CREATE TABLE ");
  +    te = stpcpy(stpcpy(stpcpy(te, dbName), "."), tblName);
  +    te = stpcpy(te, " (\n");
   
  +    te = stpcpy(te, _hidden);
  +    xx = argvAdd(&vt->cols, "path");
  +    xx = argvAdd(&vt->cols, "id");
  +
  +    if (vt->argc <= 4) {
  +assert(vt->fields);
  +     for (i = 0; i < vt->nfields; i++) {
  +         te = stpcpy(stpcpy(stpcpy(te, "\t'"), vt->fields[i]), "' ");
  +         te = stpcpy(stpcpy(te, _type), ",\n");
  +         xx = argvAdd(&vt->cols, vt->fields[i]);
  +     }
  +    } else {
  +     for (i = 4; i < vt->argc; i++) {
  +         te = stpcpy(stpcpy(stpcpy(te, "\t'"), vt->argv[i]), "' ");
  +         te = stpcpy(stpcpy(te, _type), ",\n");
  +         xx = argvAdd(&vt->cols, vt->argv[i]);
  +     }
  +    }
  +    te--;
  +    te[-1] = '\n';
  +    te = stpcpy(te, ");");
  +    *te = '\0';
  +
  +fprintf(stderr, "%s\n", t);
       rc = rpmsqlCmd(sql, "declare_vtab", db,
                sqlite3_declare_vtab(db, t));
       t = _free(t);
  @@ -144,25 +245,29 @@
            const char ** av = NULL;
            int ac = 0;
                
  -         if (rpmGlob(url, &ac, &av))
  +         xx = rpmGlob(fn, &ac, &av);
  +fprintf(stderr, "GLOB: %d = Glob(%s) av %p[%d]\n", xx, fn, av, ac);
  +         if (xx)
                rc = SQLITE_NOTFOUND;           /* XXX */
            else
                xx = argvAppend(&vt->av, (ARGV_t)av);
            av = argvFree(av);
        } else
        if (fn[nfn-1] == '/') {
  -         DIR * dir = Opendir(url);
  +         DIR * dir = Opendir(fn);
            struct dirent * dp;
  +fprintf(stderr, " DIR: %p = Opendir(%s)\n", dir, fn);
            if (dir == NULL)
                rc = SQLITE_NOTFOUND;           /* XXX */
            else
            while ((dp = Readdir(dir)) != NULL)
                if (strcmp(dp->d_name, ".") && strcmp(dp->d_name, ".."))
  -                     xx = argvAdd(&vt->av, dp->d_name);
  +                 xx = argvAdd(&vt->av, dp->d_name);
            if (dir) xx = Closedir(dir);
        } else
        if (!Access(fn, R_OK)) {
            FD_t fd = Fopen(fn, "r.fpio");
  +fprintf(stderr, "FILE: %p = Fopen(%s)\n", fd, fn);
            if (fd == NULL || Ferror(fd))
                rc = SQLITE_NOTFOUND;           /* XXX */
            else
  @@ -171,61 +276,68 @@
        } else
            rc = SQLITE_NOTFOUND;               /* XXX */
       } else
  -     xx = argvAppend(&vt->av, (ARGV_t)&argv[3]);
  +    if (!strcasecmp(modName, "Env")) {
  +fprintf(stderr, " ENV: %d = getenv(%p[%d])\n", xx, &vt->argv[3], 
argvCount(&vt->argv[3]));
  +     for (i = 3; i < vt->argc; i++) {
  +         char * t = rpmExpand(vt->argv[i], "=", getenv(vt->argv[i]), NULL);
  +         xx = argvAdd(&vt->av, t);
  +         t = _free(t);
  +     }
  +    } else {
  +     xx = argvAppend(&vt->av, (ARGV_t)&vt->argv[3]);
  +fprintf(stderr, "LIST: %d = Append(%p[%d])\n", xx, &vt->argv[3], 
argvCount(&vt->argv[3]));
  +    }
   
       vt->ac = argvCount((ARGV_t)vt->av);
   
       fn = _free(fn);
  +    s = _free(s);
  +
  +argvPrint("vt->av", (ARGV_t)vt->av, NULL);
  +
  +    if (vtp) {
  +     if (!rc)
  +         *vtp = (rpmvt) vt;
  +     else {
  +         *vtp = NULL;
  +         (void) rpmvtFree(vt);
  +         vt = NULL;
  +     }
  +    } else {
  +     vt = rpmvtFree(vt);
  +     vt = NULL;
  +    }
  +
  +fprintf(stderr, "<-- %s(%p,%p) rc %d\n", __FUNCTION__, vt, vtp, rc);
   
       return rc;
   }
   
  +/*==============================================================*/
  +
  +static struct rpmvd_s _argVD = {
  +     .nrows  = -1
  +};
  +
   int rpmvtCreate(void * _db, void * pAux,
                int argc, const char *const * argv,
                rpmvt * vtp, char ** pzErr)
   {
  -    static const char _prefix[] = "";
  -    rpmvt vt = rpmvtNew(_db, pAux, NULL, _prefix);
  -    int rc = SQLITE_OK;
  -
  -    /* Create the columns in the virtual table. */
  -    rc = rpmvtLoadArgv(vt, argc, argv);
  -
  -    if (vtp)
  -     *vtp = (!rc ? vt : NULL);
  -    else
  -     (void) rpmvtFree(vt);
  -
  -    return rc;
  +    return rpmvtLoadArgv(rpmvtNew(_db, pAux, argv, &_argVD), vtp);
   }
   
   int rpmvtConnect(void * _db, void * pAux,
                int argc, const char *const * argv,
                rpmvt * vtp, char ** pzErr)
   {
  -    static const char _prefix[] = "";
  -    rpmvt vt = rpmvtNew(_db, pAux, NULL, _prefix);
  -    int rc = SQLITE_OK;
  -
  -    /* Create the columns in the virtual table. */
  -    rc = rpmvtLoadArgv(vt, argc, argv);
  -
  -    if (vtp)
  -     *vtp = (rpmvt ) (!rc ? rpmvtLink(vt) : NULL);
  -    else
  -     (void) rpmvtFree(vt);
  -
  -    return rc;
  +    return rpmvtLoadArgv(rpmvtNew(_db, pAux, argv, &_argVD), vtp);
   }
   
  +#ifdef       NOTYET
   static void dumpInfo(const char * msg, const struct sqlite3_index_info * s)
   {
   fprintf(stderr, "--------------------- %s\n", (msg ? msg : ""));
   #define _PRT(f,v) fprintf(stderr, "%20s: " #f "\n", #v, s->v)
  -        _PRT(%d, nConstraint);
  -        _PRT(%p, aConstraint);
  -        _PRT(%d, nOrderBy);
  -        _PRT(%p, aOrderBy);
           _PRT(%p, aConstraintUsage);
           _PRT(%d, idxNum);
           _PRT(%s, idxStr);
  @@ -234,14 +346,36 @@
           _PRT(%g, estimatedCost);
   #undef  _PRT
   }
  -
  +#endif
   
   int rpmvtBestIndex(rpmvt vt, void * _pInfo)
   {
       sqlite3_index_info * pInfo = (sqlite3_index_info *) _pInfo;
       int rc = SQLITE_OK;
  +#ifdef       NOTYET
  +    int i;
  +#endif
  +
  +VTDBG((stderr, "--> %s(%p,%p)\n", __FUNCTION__, vt, pInfo));
  +
  +#ifdef       NOTYET
  +    if (pInfo->aConstraint)
  +    for (i = 0; i < pInfo->nConstraint; i++) {
  +     const struct sqlite3_index_constraint * p = pInfo->aConstraint + i;
  +     fprintf(stderr, "\tcol %s(%d) 0x%02x 0x%02x\n", vt->cols[p->iColumn], 
p->iColumn,
  +             p->op, p->usable);
  +    }
  +    if (pInfo->aOrderBy)
  +    for (i = 0; i < pInfo->nOrderBy; i++) {
  +     const struct sqlite3_index_orderby * p = pInfo->aOrderBy + i;
  +     fprintf(stderr, "\tcol %s(%d) %s\n", vt->cols[p->iColumn], p->iColumn,
  +             (p->desc ? "DESC" : "ASC"));
  +    }
       dumpInfo(__FUNCTION__, pInfo);
  +#endif
  +
   VTDBG((stderr, "<-- %s(%p,%p) rc %d\n", __FUNCTION__, vt, pInfo, rc));
  +
       return rc;
   }
   
  @@ -257,10 +391,90 @@
       return 0;        /* SQLITE_OK */
   }
   
  +static const char * dumpArg(rpmvArg _v)
  +{
  +    static char buf[BUFSIZ];
  +    char * b = buf;
  +    size_t nb = sizeof(buf);
  +    sqlite3_value * v = (sqlite3_value *) _v;
  +    int vtype = sqlite3_value_type(v);
  +    unsigned long long ll;
  +    double d;
  +    const void * p;
  +    const char * s;
  +
  +    snprintf(b, nb, "%p(%d)", v, vtype);
  +    nb -= strlen(b);
  +    b += strlen(b);
  +
  +    switch (vtype) {
  +    case SQLITE_INTEGER:
  +     ll = (unsigned long long) sqlite3_value_int64(v);
  +     snprintf(b, nb, " INT  %lld", ll);
  +     break;
  +    case SQLITE_FLOAT:
  +     d = sqlite3_value_double(v);
  +     snprintf(b, nb, " REAL %g", d);
  +     break;
  +    case SQLITE_BLOB:
  +     p = sqlite3_value_blob(v);
  +     snprintf(b, nb, " BLOB %p", p);
  +     break;
  +    case SQLITE_NULL:
  +     snprintf(b, nb, " NULL");
  +     break;
  +    case SQLITE_TEXT:
  +     s = (const char *)sqlite3_value_text(v);
  +     snprintf(b, nb, " TEXT \"%s\"", s);
  +     break;
  +    default:
  +     snprintf(b, nb, " UNKNOWN");
  +     break;
  +    }
  +
  +    return buf;
  +}
  +
  +static void dumpArgv(const char * msg, int argc, rpmvArg * _argv)
  +{
  +    if (argc > 0 && _argv) {
  +     int i;
  +     fprintf(stderr, "--------------------- %s\n", (msg ? msg : ""));
  +     for (i = 0; i < argc; i++)
  +         fprintf(stderr, "\targv[%d] %s\n", i, dumpArg(_argv[i]));
  +    }
  +}
  +
   int rpmvtUpdate(rpmvt vt, int argc, rpmvArg * _argv, int64_t * pRowid)
   {
       sqlite3_value ** argv = (sqlite3_value **) _argv;
       int rc = SQLITE_OK;
  +
  +VTDBG((stderr, "--> %s(%p,%p[%u],%p)\n", __FUNCTION__, vt, argv, 
(unsigned)argc, pRowid));
  +
  +    if (argc == 0 || argv == NULL) {
  +dumpArgv("ERROR", argc, _argv);
  +     rc = SQLITE_NOTFOUND;   /* XXX */
  +    } else
  +    if (argc == 1) {
  +     fprintf(stderr, "\tDELETE ROW 0x%llx\n",
  +             *(unsigned long long *)argv[0]);
  +    } else
  +    if (argv[0] == NULL) {
  +     fprintf(stderr, "\tADD ROW 0x%llx\n",
  +             *(unsigned long long *)argv[1]);
  +dumpArgv("ADD ROW", argc, _argv);
  +    } else
  +    if (argv[0] == argv[1]) {
  +     fprintf(stderr, "\tUPDATE ROW 0x%llx\n",
  +             *(unsigned long long *)argv[1]);
  +dumpArgv("UPDATE argv", argc-2, _argv+2);
  +    } else {
  +     fprintf(stderr, "\tREPLACE ROW 0x%llx from 0x%llx\n",
  +             *(unsigned long long *)argv[0], *(unsigned long long *)argv[1]);
  +dumpArgv("REPLACE argv", argc-2, _argv+2);
  +    }
  +
   VTDBG((stderr, "<-- %s(%p,%p[%u],%p) rc %d\n", __FUNCTION__, vt, argv, 
(unsigned)argc, pRowid, rc));
       return rc;
   }
  @@ -390,10 +604,14 @@
       sqlite3_value ** argv = (sqlite3_value **) _argv;
       int rc = SQLITE_OK;
   
  +VCDBG((stderr, "--> %s(%p,%d,%s,%p[%u]) [%d:%d]\n", __FUNCTION__, vc, 
idxNum, idxStr, argv, (unsigned)argc, vc->ix, vc->nrows));
  +dumpArgv(__FUNCTION__, argc, _argv);
  +
       if (vc->nrows > 0)
        vc->ix = 0;
   
  -VCDBG((stderr, "<-- %s(%p,%d,%s,%p[%u]) rc %d\n", __FUNCTION__, vc, idxNum, 
idxStr, argv, (unsigned)argc, rc));
  +VCDBG((stderr, "<-- %s(%p,%d,%s,%p[%u]) [%d:%d] rc %d\n", __FUNCTION__, vc, 
idxNum, idxStr, argv, (unsigned)argc, vc->ix, vc->nrows, rc));
  +
       return rc;
   }
   
  @@ -422,14 +640,33 @@
   {
       sqlite3_context * pContext = (sqlite3_context *) _pContext;
       rpmvt vt = vc->vt;
  +    rpmvd vd = vt->vd;
  +    const char * path = vt->av[vc->ix];
  +    const char * col = vt->cols[colx];
       int rc = SQLITE_OK;
   
  -    switch (colx) {
  -    case 0:  sqlite3_result_text(pContext, vt->av[vc->ix], -1, 
SQLITE_STATIC); break;
  -     /* XXX default behavior with no result() sets SQL NULL anyways. */
  -    default: sqlite3_result_null(pContext);          break;
  -    }
  +    if (!strcmp(col, "path"))
  +     sqlite3_result_text(pContext, path, -1, SQLITE_STATIC);
  +    else
  +    if (vt->nfields > 0) {
  +     ARGV_t av = NULL;       /* XXX move to rpmvcNext for performance */
  +     int xx = argvSplit(&av, path, vd->split);
  +     int i;
  +assert(vt->fields);
  +xx = xx;
  +     for (i = 0; i < vt->nfields; i++) {
  +         if (strcmp(col, vt->fields[i]))
  +             continue;
  +         sqlite3_result_text(pContext, av[i], -1, SQLITE_TRANSIENT);
  +         break;
  +     }
  +     if (i == vt->nfields)
  +         sqlite3_result_null(pContext);
  +     av = argvFree(av);
  +    } else
  +     sqlite3_result_null(pContext);  /* XXX unnecessary */
   
  +if (rc)
   VCDBG((stderr, "<-- %s(%p,%p,%d) rc %d\n", __FUNCTION__, vc, pContext, colx, 
rc));
   
       return rc;
  @@ -442,7 +679,8 @@
       if (pRowid)
        *pRowid = vc->ix;
   
  -VCDBG((stderr, "<-- %s(%p,%p) rc %d\n", __FUNCTION__, vc, pRowid, rc));
  +if (rc)
  +VCDBG((stderr, "<-- %s(%p,%p) rc %d rowid 0x%llx\n", __FUNCTION__, vc, 
pRowid, rc, (unsigned long long)(pRowid ? *pRowid : 0xf00)));
       return rc;
   }
   
  @@ -2085,16 +2323,18 @@
   
   static int _fsdb_debug = 0;
   
  -static int fsdbLoadArgv(rpmvt vt, int argc, const char *const * argv)
  +static int fsdbLoadArgv(rpmvt vt, rpmvt * vtp)
   {
       static const char _type[] = "TEXT";
       rpmsql sql = _rpmsqlI;
       sqlite3 * db = (sqlite3 *) vt->db;
  -    const char * _modName = argv[0];
  -    const char * _dbName = argv[1];
  -    const char * _tblName = argv[2];
  +#define      modName vt->argv[0]
  +#define      dbName  vt->argv[1]
  +#define      tblName vt->argv[2]
  +
  +    rpmvd vd = vt->vd;
  +    const char * pat = (vt->argv[3] ? vt->argv[3] : "*");
   
  -    const char * pat = (argv[3] ? argv[3] : "*");
       char * fn;
       size_t nfn;
       char * t, * te;
  @@ -2107,26 +2347,25 @@
   static const char _hidden[] = "\
   \t'path' HIDDEN TEXT,\n\
   \t'id' HIDDEN TEXT,\n\
  -\t'uuid' HIDDEN TEXT,\n\
   ";
   
   if (_fsdb_debug)
  -fprintf(stderr, "--> %s(%p,%p,%p,%p[%u])\n", __FUNCTION__, sql, db, vt, 
argv, (unsigned)argc);
  -argvPrint("argv", (ARGV_t)argv, NULL);
  +fprintf(stderr, "--> %s(%p,%p)\n", __FUNCTION__, vt, vtp);
  +argvPrint("vt->argv", (ARGV_t)vt->argv, NULL);
   
  -    fn = rpmGetPath(vt->prefix, pat, NULL);
  +    fn = rpmGetPath(vd->prefix, pat, NULL);
       nfn = strlen(fn);
   
       nb = 0;
       nb += sizeof("CREATE TABLE ") - 1;
  -    nb += strlen(_dbName) + (sizeof(".")-1) + strlen(_tblName);
  +    nb += strlen(dbName) + (sizeof(".")-1) + strlen(tblName);
       nb += (sizeof(" (\n")-1);
   
       nb += strlen(_hidden);
   
  -    for (i = 4; i < argc; i++) {
  +    for (i = 4; i < vt->argc; i++) {
        nb += sizeof("\t'' ,\n");
  -     nb += strlen(argv[i]);
  +     nb += strlen(vt->argv[i]);
        nb += strlen(_type);
       }
       nb--;
  @@ -2134,18 +2373,17 @@
   
       te = t = xmalloc(nb + 1);
       te = stpcpy(te, "CREATE TABLE ");
  -    te = stpcpy(stpcpy(stpcpy(te, _dbName), "."), _tblName);
  +    te = stpcpy(stpcpy(stpcpy(te, dbName), "."), tblName);
       te = stpcpy(te, " (\n");
   
       te = stpcpy(te, _hidden);
       xx = argvAdd(&vt->cols, "path");
       xx = argvAdd(&vt->cols, "id");
  -    xx = argvAdd(&vt->cols, "uuid");
   
  -    for (i = 4; i < argc; i++) {
  -     te = stpcpy(stpcpy(stpcpy(te, "\t'"), argv[i]), "' ");
  +    for (i = 4; i < vt->argc; i++) {
  +     te = stpcpy(stpcpy(stpcpy(te, "\t'"), vt->argv[i]), "' ");
        te = stpcpy(stpcpy(te, _type), ",\n");
  -     xx = argvAdd(&vt->cols, argv[i]);
  +     xx = argvAdd(&vt->cols, vt->argv[i]);
       }
       te--;
       te[-1] = '\n';
  @@ -2197,118 +2435,126 @@
   
   argvPrint("vt->av", (ARGV_t)vt->av, NULL);
   
  +    if (vtp) {
  +     if (!rc)
  +         *vtp = (rpmvt) vt;
  +     else {
  +         *vtp = NULL;
  +         (void) rpmvtFree(vt);
  +         vt = NULL;
  +     }
  +    } else {
  +     vt = rpmvtFree(vt);
  +     vt = NULL;
  +    }
  +
   if (_fsdb_debug)
  -fprintf(stderr, "<-- %s(%p,%p,%p,%p[%u]) rc %d\n", __FUNCTION__, sql, db, 
vt, argv, (unsigned)argc, rc);
  +fprintf(stderr, "<-- %s(%p,%p) rc %d\n", __FUNCTION__, vt, vtp, rc);
   
       return rc;
   }
   
   /*==============================================================*/
   
  -static int _grdb_debug = 0;
  +static int _env_debug = 1;
   
  -static int grdbCreateConnect(void * _db, void * pAux,
  +#ifdef       NOTYET
  +static struct rpmvd_s _envVD = {
  +     .split  = "=",
  +     .parse  = "key=val",
  +     .ncols  = -1
  +};
  +
  +static int envCreateConnect(void * _db, void * pAux,
                int argc, const char *const * argv,
                rpmvt * vtp, char ** pzErr)
   {
  -    static const char _prefix[] = "";
  -    rpmvt vt = rpmvtNew(_db, pAux, NULL, _prefix);
  -    int rc = SQLITE_OK;
  -
  -    /* Create the columns in the virtual table. */
  -    rc = fsdbLoadArgv(vt, argc, argv);
  -
  -    if (vtp)
  -     *vtp = (!rc ? vt : NULL);
  -    else
  -     (void) rpmvtFree(vt);
  -
  -    return rc;
  +    return rpmvtLoadArgv(rpmvtNew(_db, pAux, argv, &_argVD), vtp);
   }
  +#endif
   
  -static int grdbColumn(rpmvc vc, void * _pContext, int colx)
  +static int envColumn(rpmvc vc, void * _pContext, int colx)
   {
       sqlite3_context * pContext = (sqlite3_context *) _pContext;
       rpmvt vt = vc->vt;
       const char * path = vt->av[vc->ix];
       const char * col = vt->cols[colx];
  -#ifdef       UNUSED
       const char * t;
       const char * te;
  -#endif
  -    ARGV_t av = NULL;                /* XXX move to rpmvcNext for 
performance */
  -    int ac;
  -    int xx;
       int rc = SQLITE_OK;
   
  -if (_grdb_debug < 0)
  -fprintf(stderr, "--> %s(%p,%p,%d)\n", __FUNCTION__, vc, pContext, colx);
  +if (_env_debug)
  +fprintf(stderr, "--> %s(%p,%p,%d) path \"%s\" col \"%s\"\n", __FUNCTION__, 
vc, pContext, colx, path, col);
   
  -#ifdef       UNUSED
  -    /* Split out {id,name} pointers. */
  +    /* Split out {KEY,VAL} pointers. */
       if ((t = strrchr(path, '/')) == NULL)
        t = path;
       else
        t++;
  -    te = t + strlen(t);
  -#endif
  -
  -    xx = argvSplit(&av, path, ":");
  -    ac = argvCount(av);
  +    if ((te = strchr(t, '=')) == NULL)
  +     te = t + strlen(t);
   
       if (!strcmp(col, "path"))
        sqlite3_result_text(pContext, path, -1, SQLITE_STATIC);
  -#ifdef       NOTYET
       else if (!strcmp(col, "id"))
        sqlite3_result_text(pContext, t, (te-t), SQLITE_STATIC);
  -#endif
  -    else if (!strcmp(col, "group") && ac > 0)
  -     sqlite3_result_text(pContext, av[0], -1, SQLITE_TRANSIENT);
  -    else if (!strcmp(col, "passwd") && ac > 1)
  -     sqlite3_result_text(pContext, av[1], -1, SQLITE_TRANSIENT);
  -    else if (!strcmp(col, "gid") && ac > 2)
  -     sqlite3_result_text(pContext, av[2], -1, SQLITE_TRANSIENT);
  -    else if (!strcmp(col, "groups") && ac > 3)
  -     sqlite3_result_text(pContext, av[3], -1, SQLITE_TRANSIENT);
  -    else
  -     sqlite3_result_null(pContext);
  -
  -    av = argvFree(av);
  +    else {
  +     if (*te)
  +         sqlite3_result_text(pContext, te+1, -1, SQLITE_STATIC);
  +     else
  +         sqlite3_result_null(pContext);
  +    }
   
  -if (_grdb_debug < 0)
  +if (_env_debug)
   fprintf(stderr, "<-- %s(%p,%p,%d) rc %d\n", __FUNCTION__, vc, pContext, 
colx, rc);
   
       return rc;
   }
   
  +struct sqlite3_module envModule = {
  +#ifdef       NOTYET
  +    .xCreate = (void *) envCreateConnect,
  +    .xConnect        = (void *) envCreateConnect,
  +#endif
  +    .xColumn = (void *) envColumn,
  +};
  +
  +/*==============================================================*/
  +
  +static struct rpmvd_s _grdbVD = {
  +     .prefix = "%{?_etc_group}%{!?_etc_group:/etc/group}",
  +     .split  = ":",
  +     .parse  = "group:pw:gid:groups",
  +     .nrows  = -1
  +};
  +
  +static int grdbCreateConnect(void * _db, void * pAux,
  +             int argc, const char *const * argv,
  +             rpmvt * vtp, char ** pzErr)
  +{
  +    return rpmvtLoadArgv(rpmvtNew(_db, pAux, argv, &_grdbVD), vtp);
  +}
  +
   struct sqlite3_module grdbModule = {
  -    .iVersion        = 0,
       .xCreate = (void *) grdbCreateConnect,
       .xConnect        = (void *) grdbCreateConnect,
  -    .xColumn = (void *) grdbColumn,
   };
   
   /*==============================================================*/
   
   static int _nixdb_debug = 0;
   
  +static struct rpmvd_s _nixdbVD = {
  +     .prefix = "%{?_nixdb}%{!?_nixdb:/nix/store}/*-",
  +     .parse  = "id-name",
  +     .nrows  = -1
  +};
  +
   static int nixdbCreateConnect(void * _db, void * pAux,
                int argc, const char *const * argv,
                rpmvt * vtp, char ** pzErr)
   {
  -    static const char _prefix[] = "%{?_nixdb}%{!?_nixdb:/nix/store}/*-";
  -    rpmvt vt = rpmvtNew(_db, pAux, NULL, _prefix);
  -    int rc = SQLITE_OK;
  -
  -    /* Create the columns in the virtual table. */
  -    rc = fsdbLoadArgv(vt, argc, argv);
  -
  -    if (vtp)
  -     *vtp = (!rc ? vt : NULL);
  -    else
  -     (void) rpmvtFree(vt);
  -
  -    return rc;
  +    return fsdbLoadArgv(rpmvtNew(_db, pAux, argv, &_nixdbVD), vtp);
   }
   
   static int nixdbColumn(rpmvc vc, void * _pContext, int colx)
  @@ -2348,7 +2594,6 @@
   }
   
   struct sqlite3_module nixdbModule = {
  -    .iVersion        = 0,
       .xCreate = (void *) nixdbCreateConnect,
       .xConnect        = (void *) nixdbCreateConnect,
       .xColumn = (void *) nixdbColumn,
  @@ -2358,23 +2603,17 @@
   
   static int _procdb_debug = 0;
   
  +static struct rpmvd_s _procdbVD = {
  +     .prefix = "%{?_procdb}%{!?_procdb:/proc/[0-9]}",
  +     .parse  = "id",
  +     .nrows  = -1
  +};
  +
   static int procdbCreateConnect(void * _db, void * pAux,
                int argc, const char *const * argv,
                rpmvt * vtp, char ** pzErr)
   {
  -    static const char _prefix[] = "%{?_procdb}%{!?_procdb:/proc/[0-9]}";
  -    rpmvt vt = rpmvtNew(_db, pAux, NULL, _prefix);
  -    int rc = SQLITE_OK;
  -
  -    /* Create the columns in the virtual table. */
  -    rc = fsdbLoadArgv(vt, argc, argv);
  -
  -    if (vtp)
  -     *vtp = (!rc ? vt : NULL);
  -    else
  -     (void) rpmvtFree(vt);
  -
  -    return rc;
  +    return fsdbLoadArgv(rpmvtNew(_db, pAux, argv, &_procdbVD), vtp);
   }
   
   static int procdbColumn(rpmvc vc, void * _pContext, int colx)
  @@ -2422,7 +2661,6 @@
   }
   
   struct sqlite3_module procdbModule = {
  -    .iVersion        = 0,
       .xCreate = (void *) procdbCreateConnect,
       .xConnect        = (void *) procdbCreateConnect,
       .xColumn = (void *) procdbColumn,
  @@ -2430,116 +2668,39 @@
   
   /*==============================================================*/
   
  -static int _pwdb_debug = 0;
  +static struct rpmvd_s _pwdbVD = {
  +     .prefix = "%{?_etc_passwd}%{!?_etc_passwd:/etc/passwd}",
  +     .split  = ":",
  +     .parse  = "user:passwd:uid:gid:gecos:dir:shell",
  +     .nrows  = -1
  +};
   
   static int pwdbCreateConnect(void * _db, void * pAux,
                int argc, const char *const * argv,
                rpmvt * vtp, char ** pzErr)
   {
  -    static const char _prefix[] = "";
  -    rpmvt vt = rpmvtNew(_db, pAux, NULL, _prefix);
  -    int rc = SQLITE_OK;
  -
  -    /* Create the columns in the virtual table. */
  -    rc = fsdbLoadArgv(vt, argc, argv);
  -
  -    if (vtp)
  -     *vtp = (!rc ? vt : NULL);
  -    else
  -     (void) rpmvtFree(vt);
  -
  -    return rc;
  -}
  -
  -static int pwdbColumn(rpmvc vc, void * _pContext, int colx)
  -{
  -    sqlite3_context * pContext = (sqlite3_context *) _pContext;
  -    rpmvt vt = vc->vt;
  -    const char * path = vt->av[vc->ix];
  -    const char * col = vt->cols[colx];
  -#ifdef       UNUSED
  -    const char * t;
  -    const char * te;
  -#endif
  -    ARGV_t av = NULL;                /* XXX move to rpmvcNext for 
performance */
  -    int ac;
  -    int xx;
  -    int rc = SQLITE_OK;
  -
  -if (_pwdb_debug < 0)
  -fprintf(stderr, "--> %s(%p,%p,%d)\n", __FUNCTION__, vc, pContext, colx);
  -
  -#ifdef       UNUSED
  -    /* Split out {id,name} pointers. */
  -    if ((t = strrchr(path, '/')) == NULL)
  -     t = path;
  -    else
  -     t++;
  -    te = t + strlen(t);
  -#endif
  -
  -    xx = argvSplit(&av, path, ":");
  -    ac = argvCount(av);
  -
  -    if (!strcmp(col, "path"))
  -     sqlite3_result_text(pContext, path, -1, SQLITE_STATIC);
  -#ifdef       NOTYET
  -    else if (!strcmp(col, "id"))
  -     sqlite3_result_text(pContext, t, (te-t), SQLITE_STATIC);
  -#endif
  -    else if (!strcmp(col, "user") && ac > 0)
  -     sqlite3_result_text(pContext, av[0], -1, SQLITE_TRANSIENT);
  -    else if (!strcmp(col, "passwd") && ac > 1)
  -     sqlite3_result_text(pContext, av[1], -1, SQLITE_TRANSIENT);
  -    else if (!strcmp(col, "uid") && ac > 2)
  -     sqlite3_result_text(pContext, av[2], -1, SQLITE_TRANSIENT);
  -    else if (!strcmp(col, "gid") && ac > 3)
  -     sqlite3_result_text(pContext, av[3], -1, SQLITE_TRANSIENT);
  -    else if (!strcmp(col, "gecos") && ac > 4)
  -     sqlite3_result_text(pContext, av[4], -1, SQLITE_TRANSIENT);
  -    else if (!strcmp(col, "home") && ac > 5)
  -     sqlite3_result_text(pContext, av[5], -1, SQLITE_TRANSIENT);
  -    else if (!strcmp(col, "shell") && ac > 6)
  -     sqlite3_result_text(pContext, av[6], -1, SQLITE_TRANSIENT);
  -    else
  -     sqlite3_result_null(pContext);
  -
  -    av = argvFree(av);
  -
  -if (_pwdb_debug < 0)
  -fprintf(stderr, "<-- %s(%p,%p,%d) rc %d\n", __FUNCTION__, vc, pContext, 
colx, rc);
  -
  -    return rc;
  +    return rpmvtLoadArgv(rpmvtNew(_db, pAux, argv, &_pwdbVD), vtp);
   }
   
   struct sqlite3_module pwdbModule = {
  -    .iVersion        = 0,
       .xCreate = (void *) pwdbCreateConnect,
       .xConnect        = (void *) pwdbCreateConnect,
  -    .xColumn = (void *) pwdbColumn,
   };
   
   /*==============================================================*/
   
   static int _stat_debug = 0;
   
  +static struct rpmvd_s _statVD = {
  +     .parse  = "st_dev st_ino st_mode st_nlink st_uid st_gid st_rdev st_size 
st_blksize st_blocks st_atime st_mtime st_ctime",
  +     .nrows  = -1
  +};
  +
   static int statCreateConnect(void * _db, void * pAux,
                int argc, const char *const * argv,
                rpmvt * vtp, char ** pzErr)
   {
  -    static const char _prefix[] = "";
  -    rpmvt vt = rpmvtNew(_db, pAux, NULL, _prefix);
  -    int rc = SQLITE_OK;
  -
  -    /* Create the columns in the virtual table. */
  -    rc = fsdbLoadArgv(vt, argc, argv);
  -
  -    if (vtp)
  -     *vtp = (!rc ? vt : NULL);
  -    else
  -     (void) rpmvtFree(vt);
  -
  -    return rc;
  +    return fsdbLoadArgv(rpmvtNew(_db, pAux, argv, &_statVD), vtp);
   }
   
   static int statColumn(rpmvc vc, void * _pContext, int colx)
  @@ -2548,10 +2709,6 @@
       rpmvt vt = vc->vt;
       const char * path = vt->av[vc->ix];
       const char * col = vt->cols[colx];
  -#ifdef       UNUSED
  -    const char * t;
  -    const char * te;
  -#endif
       struct stat sb, *st = &sb;       /* XXX move to rpmvcNext for 
performance */
       int ret = Lstat(path, &sb);
       int rc = SQLITE_OK;
  @@ -2562,10 +2719,6 @@
   
       if (!strcmp(col, "path"))
        sqlite3_result_text(pContext, path, -1, SQLITE_STATIC);
  -#ifdef       NOTYET
  -    else if (!strcmp(col, "id"))
  -     sqlite3_result_text(pContext, t, (te-t), SQLITE_STATIC);
  -#endif
       else if (!strcmp(col, "st_dev") && !ret)
        sqlite3_result_int64(pContext, st->st_dev);
       else if (!strcmp(col, "st_ino") && !ret)
  @@ -2603,7 +2756,6 @@
   }
   
   struct sqlite3_module statModule = {
  -    .iVersion        = 0,
       .xCreate = (void *) statCreateConnect,
       .xConnect        = (void *) statCreateConnect,
       .xColumn = (void *) statColumn,
  @@ -2613,23 +2765,17 @@
   
   static int _yumdb_debug = 0;
   
  +static struct rpmvd_s _yumdbVD = {
  +     .prefix = "%{?_yumdb}%{!?_yumdb:/var/lib/yum/yumdb}/",
  +     .parse  = "id-NVRA",
  +     .nrows  = -1
  +};
  +
   static int yumdbCreateConnect(void * _db, void * pAux,
                int argc, const char *const * argv,
                rpmvt * vtp, char ** pzErr)
   {
  -    static const char _prefix[] = 
"%{?_yumdb}%{!?_yumdb:/var/lib/yum/yumdb}/";
  -    rpmvt vt = rpmvtNew(_db, pAux, NULL, _prefix);
  -    int rc = SQLITE_OK;
  -
  -    /* Create the columns in the virtual table. */
  -    rc = fsdbLoadArgv(vt, argc, argv);
  -
  -    if (vtp)
  -     *vtp = (!rc ? vt : NULL);
  -    else
  -     (void) rpmvtFree(vt);
  -
  -    return rc;
  +    return fsdbLoadArgv(rpmvtNew(_db, pAux, argv, &_yumdbVD), vtp);
   }
   
   static int yumdbColumn(rpmvc vc, void * _pContext, int colx)
  @@ -2703,7 +2849,6 @@
   }
   
   struct sqlite3_module yumdbModule = {
  -    .iVersion        = 0,
       .xCreate = (void *) yumdbCreateConnect,
       .xConnect        = (void *) yumdbCreateConnect,
       .xColumn = (void *) yumdbColumn,
  @@ -2712,7 +2857,6 @@
   /*==============================================================*/
   
   struct sqlite3_module _rpmvmTemplate = {
  -    .iVersion        = 0,
       .xCreate = (void *) rpmvtCreate,
       .xConnect        = (void *) rpmvtConnect,
       .xBestIndex      = (void *) rpmvtBestIndex,
  @@ -2736,6 +2880,7 @@
   
   static struct rpmsqlVMT_s __VMT[] = {
     { "Argv",          NULL, NULL },
  +  { "Env",           &envModule, NULL },
     { "Grdb",          &grdbModule, NULL },
     { "Nixdb",         &nixdbModule, NULL },
     { "Procdb",                &procdbModule, NULL },
  @@ -5386,8 +5531,11 @@
        static const char _zInitrc[]    = "/.sqliterc";
        static const char _zHistory[]   = "/.sqlite_history";
        /* XXX getpwuid? */
  +sql->zHome = _free(sql->zHome);
        sql->zHome = xstrdup(getenv("HOME"));
  +sql->zInitrc = _free(sql->zInitrc);
        sql->zInitrc = rpmGetPath(sql->zHome, _zInitrc, NULL);
  +sql->zHistory = _free(sql->zHistory);
        sql->zHistory = rpmGetPath(sql->zHome, _zHistory, NULL);
        /*
         ** Prompt strings. Initialized in main. Settable with
  @@ -5397,8 +5545,10 @@
        if (sql->zPrompt == NULL) {     /* XXX this test is useless */
            char * t = xstrdup((av && av[0] ? av[0] : "sql"));
            char * bn = basename(t);
  +sql->zPrompt = _free(sql->zPrompt);
            sql->zPrompt = rpmExpand(bn, "> ", NULL);
            t = _free(t);
  +sql->zContinue = _free(sql->zContinue);
            sql->zContinue = t = xstrdup(sql->zPrompt);
            while (*t && *t != '>')
                *t++ = '-';
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmio/rpmsql.h
  ============================================================================
  $ cvs diff -u -r2.20 -r2.21 rpmsql.h
  --- rpm/rpmio/rpmsql.h        16 Apr 2010 17:56:55 -0000      2.20
  +++ rpm/rpmio/rpmsql.h        18 Apr 2010 03:17:10 -0000      2.21
  @@ -10,7 +10,8 @@
   #include <argv.h>
   
   typedef void * rpmvArg;
  -typedef void * rpmvData;
  +
  +typedef /*...@abstract@*/ struct rpmvd_s * rpmvd;
   
   typedef /*...@abstract@*/ struct rpmvc_s * rpmvc;
   typedef /*...@abstract@*/ struct rpmvt_s * rpmvt;
  @@ -138,12 +139,20 @@
   struct rpmvt_s {
       struct rpmvt_vtab_s _base;       /* for sqlite */
       void * db;                       /* SQL database handle. */
  -    const char * prefix;
  +
  +    int argc;
  +    const char ** argv;
  +
  +    int nfields;
  +    const char ** fields;
  +
       int ncols;                       /* No. of column items. */
       const char ** cols;              /* Column headers/types. */
  +
       int ac;
       const char ** av;
  -    rpmvData vd;             /* Data object. */
  +
  +    rpmvd vd;                /* Data object. */
   };
   struct rpmVT_s {
       struct rpmioItem_s _item;        /*!< usage mutex and pool identifier. */
  @@ -153,6 +162,13 @@
       int nrefs;                       /*!< (unused) keep splint happy */
   #endif
   };
  +struct rpmvd_s {
  +    const char * prefix;
  +    const char * split;
  +    const char * parse;
  +    int nrows;
  +    int ncols;
  +};
   #endif       /* _RPMVT_INTERNAL */
   
   #ifdef       _RPMVC_INTERNAL
  @@ -164,7 +180,7 @@
       rpmvt vt;                        /* Linkage to virtual table. */
       int ix;                  /* Current row index. */
       int nrows;                       /* No. of row items. */
  -    rpmvData vd;             /* Data object. */
  +    rpmvd vd;                /* Data object. */
   };
   struct rpmVC_s {
       struct rpmioItem_s _item;        /*!< usage mutex and pool identifier. */
  @@ -323,7 +339,7 @@
   #define      rpmvtFree(_vt)  \
       ((rpmvt)rpmioFreePoolItem(((rpmioItem)(_vt))-1, __FUNCTION__, __FILE__, 
__LINE__))
   
  -rpmvt rpmvtNew(void * db, void * pModule, rpmvData vd, const char * prefix)
  +rpmvt rpmvtNew(void * db, void * pModule, const char *const *argv, rpmvd vd)
        /*...@*/;
   
   /**
  @@ -386,7 +402,7 @@
    * @param vt         virtual table
    * @param argc
    * @param argv
  - * @retval *pRowid
  + * @retval *pRowid   (insert) new rowid
    * @return           0 on success
    */
   int rpmvtUpdate(rpmvt vt, int argc, rpmvArg * _argv, int64_t * pRowid)
  @@ .
______________________________________________________________________
RPM Package Manager                                    http://rpm5.org
CVS Sources Repository                                [email protected]

Reply via email to