RPM Package Manager, CVS Repository http://rpm5.org/cvs/ ____________________________________________________________________________
Server: rpm5.org Name: Per Øyvind Karlsen Root: /v/rpm/cvs Email: pkarl...@rpm5.org Module: rpm Date: 27-May-2011 16:50:27 Branch: rpm-5_3 Handle: 2011052714502700 Modified files: (Branch: rpm-5_3) rpm/rpmdb rpmdb.c Log: come up with a better hack for querying nvra with disttag/distepoch that should be rather generic Summary: Revision Changes Path 1.386.2.12 +80 -12 rpm/rpmdb/rpmdb.c ____________________________________________________________________________ patch -p0 <<'@@ .' Index: rpm/rpmdb/rpmdb.c ============================================================================ $ cvs diff -u -r1.386.2.11 -r1.386.2.12 rpmdb.c --- rpm/rpmdb/rpmdb.c 24 Mar 2011 16:51:17 -0000 1.386.2.11 +++ rpm/rpmdb/rpmdb.c 27 May 2011 14:50:27 -0000 1.386.2.12 @@ -2446,24 +2446,92 @@ /* XXX Special case #4: gather primary keys with patterns. */ rpmRC rc; + rc = dbiFindMatches(dbi, keyp, &set); #if defined(RPM_VENDOR_MANDRIVA) /* - * ugly hack to workaround disttag/distepoch pattern matching issue to buy some + * Hack to workaround disttag/distepoch pattern matching issue to buy some * time to come up with better pattern fix.. + * One size should fit all now.. ;) + * + * This patch will try match NVR first, then for all matches returned, + * it will match disttag, distepoch & arch individually. */ - const char *tmp = strstr(keyp, "-mdv2011.0"); - if(tmp) { - const char *origkeyp = keyp; - size_t klen = strlen(keyp); - keyp = alloca(klen); - memset((void*)keyp, klen, 0); - klen = tmp-origkeyp+1; - snprintf((char*)keyp, klen, "%s", origkeyp); - if(strlen(tmp) > sizeof("-mdv2011.0")-1) - stpcpy((char*)keyp+(klen-1), &tmp[sizeof("-mdv2011.0")-1]); + + /* We'll only try this if query fails */ + if(!rc && ((const char*)keyp)[0] != '^' && tag == RPMTAG_NVRA && + (set == NULL || set->count < 1)) { + size_t i; + char *tmp = (char*)keyp; + + /* If pattern has less than three '-', it can't contain disttag, so + * no point in trying */ + for (i = 0; (tmp = strchr(tmp, '-')); i++, tmp++); + if (i >= 3) { + dbiIndex pdbi; + DBC *pdbc; + const char *origkeyp = keyp; + size_t klen = strlen(keyp)+1; + size_t size = 0; + int xx; + + keyp = alloca(klen); + stpcpy((char*)keyp, origkeyp); + tmp = strrchr(keyp, '-'); + *tmp = '\0'; + rc = dbiFindMatches(dbi, keyp, &set); + + pdbi = dbiOpen(db, RPMDBI_PACKAGES, 0); + xx = dbiCopen(pdbi, dbiTxnid(pdbi), &pdbc, 0); + + for(i = 0; i < set->count; i++) { + DBT k = DBT_INIT; + DBT v = DBT_INIT; + Header h; + uint32_t offset = _hton_ui(set->recs[i].hdrNum); + rpmTag checkTags[] = + { RPMTAG_DISTTAG, RPMTAG_DISTEPOCH, RPMTAG_ARCH }; + int j; + + memset(&k, 0, sizeof(k)); + memset(&v, 0, sizeof(v)); + k.data = &offset; + k.size = sizeof(offset); + + xx = dbiGet(dbi, pdbc, &k, &v, DB_SET); + h = headerLoad(v.data); + tmp = (char*)((size_t)keyp + strlen(keyp) + 1); + + for (j = 0; j < (int)(sizeof(checkTags)/sizeof(checkTags[0])) && + *tmp != '\0'; j++) { + he->tag = checkTags[j]; + if(headerGet(h, he, 0)) { + size_t len = strlen(he->p.str); + + if (he->tag == RPMTAG_ARCH && *tmp == '.') + tmp++; + + if(!strncmp(he->p.str, tmp, len)) + tmp += len; + _free(he->p.ptr); + } + } + if(j && *tmp == '\0') { + set->recs[size].hdrNum = set->recs[i].hdrNum; + set->recs[size].tagNum = set->recs[i].tagNum; + size++; + } + + h = headerFree(h); + } + if(set->count != size) { + set->count = size; + set->recs = realloc(set->recs, size * sizeof(*set->recs)); + } + + xx = dbiCclose(pdbi, pdbc, 0); + } } #endif - rc = dbiFindMatches(dbi, keyp, &set); if ((rc && rc != RPMRC_NOTFOUND) || set == NULL || set->count < 1) { /* error or empty set */ set = dbiFreeIndexSet(set); @@ . ______________________________________________________________________ RPM Package Manager http://rpm5.org CVS Sources Repository rpm-cvs@rpm5.org