From b6f9b692cd319ffbe43fbd191b13613532d82e37 Mon Sep 17 00:00:00 2001 From: Nathan Wagner Date: Fri, 22 Feb 2019 03:20:59 +0000 Subject: [PATCH] add range search to findpkg --- lib/findpkg.c | 119 ++++++++++++++++++++++++++++++++++++++++++-------- src/findpkg.c | 36 ++++++++++++--- zpm.h | 1 + 3 files changed, 133 insertions(+), 23 deletions(-) diff --git a/lib/findpkg.c b/lib/findpkg.c index 6d7981a..8dd0ad1 100644 --- a/lib/findpkg.c +++ b/lib/findpkg.c @@ -81,24 +81,39 @@ char *select = "select printf('%%s-%%s-%%s',P.package,P.version,P.release) as pk return pkgid; } -int zpm_libraries_needed(struct zpm *zpm, char *pkgid, jsw_atree_t *list) { - char *pkglibsneeded = "\ - with pkglibs as (\ - select distinct EN.needed as soname, PF.pkgid\ - from elfneeded EN\ - join packagefiles_pkgid PF on PF.hash = EN.file\ - ),\ - pkgprovides as (\ - select distinct EL.soname, PF.pkgid\ - from elflibraries EL\ - join packagefiles_pkgid PF on PF.hash = EL.file\ - )\ - select distinct PL.soname, PP.soname is not null as selfsatisfied\ - from pkglibs PL\ - left join pkgprovides PP on PL.pkgid = PP.pkgid and PL.soname = PP.soname\ - where PL.pkgid = %Q\ - "; +int zpm_packages_needed(struct zpm *zpm, char *pkgid, jsw_atree_t *list) { + char *pkglibsneeded = "select soname, selfsatisfied from package_libraries_needed where pkgid = %Q"; + sqlite3_stmt *st; + int count = 0; + int rv; + + st = zpm_dbquery(zpm, pkglibsneeded, pkgid); + + while ((rv = sqlite3_step(st)) == SQLITE_ROW) { + char *soname; + int self; + + soname = (char *)sqlite3_column_text(st, 0); + /* TODO check and skip self sats */ + self = sqlite3_column_int(st,1); + if (self) { + continue; + } + count++; + + /* if it's in needed, we've already looked at this one */ + if (list && !jsw_afind(list, soname)) { + jsw_ainsert(list, soname); + } + } + sqlite3_finalize(st); + return count; +} + + +int zpm_libraries_needed(struct zpm *zpm, char *pkgid, jsw_atree_t *list) { + char *pkglibsneeded = "select soname, selfsatisfied from package_libraries_needed where pkgid = %Q"; sqlite3_stmt *st; int count = 0; int rv; @@ -176,6 +191,76 @@ char *zpm_findpkg(struct zpm *zpm, char *pkgstr, char *where) { } + sqlite3_str_appendall(sql, " "); + sqlite3_str_appendall(sql, group); + sqlite3_str_appendall(sql, " limit 1;"); + + if (sqlite3_str_errcode(sql)) { + zpm->error = 1; + sqlite3_free(sqlite3_str_finish(sql)); + return 0; + } + + query = sqlite3_str_finish(sql); + + pkgid = zpm_db_string(zpm, query);; + + sqlite3_free(query); + + return pkgid; +} + +char *zpm_findpkg_range(struct zpm *zpm, char *minpkg, char *maxpkg, char *where, int wantleast) { + int release; + char version[32]; + char package[32]; + + char *select = "select pkgid, package, version, release from packages_pkgid"; + char *last = "order by version collate vercmp desc, cast(release as integer) desc"; + char *first = "order by version collate vercmp, cast(release as integer)"; + char *group; + + char *query, *pkgid = 0; + sqlite3_str *sql; + + group = wantleast ? first : last; + /* null pkgstr find "best" package + * best is shortest complete package if any are complete + * shortest incomplete if any are incomplete + * where more than one version is in those sets, best is + * latest as determined by vercmp + */ + + sql = sqlite3_str_new(zpm->db); + + sqlite3_str_appendall(sql, select); + sqlite3_str_appendall(sql, " where true"); + + if (minpkg) { + sqlite3_str_appendf(sql, " and pkgid >= %Q collate vercmp", + minpkg); + zpm_parse_package(minpkg, package, version, &release); + if (*package != 0) { + sqlite3_str_appendf(sql, " and package = %Q", + package); + } + } + + if (maxpkg) { + sqlite3_str_appendf(sql, " and pkgid <= %Q collate vercmp", + maxpkg); + zpm_parse_package(maxpkg, package, version, &release); + if (*package != 0) { + sqlite3_str_appendf(sql, " and package = %Q", + package); + } + } + + if (where) { + sqlite3_str_appendall(sql, " and "); + sqlite3_str_appendall(sql, where); + } + sqlite3_str_appendall(sql, " "); sqlite3_str_appendall(sql, group); sqlite3_str_appendall(sql, " limit 1;"); diff --git a/src/findpkg.c b/src/findpkg.c index 4ee3f12..775269f 100644 --- a/src/findpkg.c +++ b/src/findpkg.c @@ -15,6 +15,8 @@ int main(int ac, char **av){ int opt, argn; struct zpm zpm; char *dbfile = 0, *pkgstr = 0, *pkgid = 0; + int range = 0, wantleast = 0, argismax = 0; + char *minpkg = 0, *maxpkg = 0; char *sql; sqlite3_str *include; @@ -29,7 +31,7 @@ int main(int ac, char **av){ include = sqlite3_str_new(NULL); exclude = sqlite3_str_new(NULL); - while ((opt = getopt(ac, av, "f:s:S:I")) != -1) { + while ((opt = getopt(ac, av, "f:s:S:Imrl")) != -1) { switch (opt) { case 'f': dbfile = optarg; break; case 's': sqlite3_str_appendf(include,",%Q", optarg); @@ -38,6 +40,9 @@ int main(int ac, char **av){ break; case 'I': sqlite3_str_appendall(include,",'installed'"); break; + case 'l': wantleast = 1; break; + case 'r': range = 1; break; + case 'm': argismax = 1; range = 1; break; default: usage(); exit(EXIT_FAILURE); @@ -46,6 +51,20 @@ int main(int ac, char **av){ } argn = optind; + if (ac < argn) { + usage(); + exit(EXIT_FAILURE); + } + + pkgstr = minpkg = av[argn]; + if (ac > argn) { + maxpkg = av[argn+1]; + } + + if (maxpkg) { + range = 1; + } + if (!dbfile) { fprintf(stderr, "must specify db\n"); return 1; @@ -68,13 +87,18 @@ int main(int ac, char **av){ excludes+1); } - if (ac >= argn) { - pkgstr = av[argn]; - } - sql = sqlite3_str_value(query); - pkgid = zpm_findpkg(&zpm, pkgstr, sql); + if (range) { + if (argismax) { + /* swap the sense of the arguments */ + minpkg = maxpkg; + maxpkg = pkgstr; + } + pkgid = zpm_findpkg_range(&zpm, minpkg, maxpkg, sql, wantleast); + } else { + pkgid = zpm_findpkg(&zpm, pkgstr, sql); + } sqlite3_free(sql); if (pkgid) { diff --git a/zpm.h b/zpm.h index b090b3a..157eb37 100644 --- a/zpm.h +++ b/zpm.h @@ -88,6 +88,7 @@ struct zpm_package { int zpm_parse_package(char *pstr, char *name, char *ver, int *rel); char *zpm_findpkg(struct zpm *zpm, char *pkgstr, char *where); +char *zpm_findpkg_range(struct zpm *zpm, char *minpkg, char *maxpkg, char *where, int wantleast); int zpm_findhash(struct zpm *zpm, char *find, char *dest); char *zpm_findlib(struct zpm *zpm, char *soname, char *where); int zpm_libraries_needed(struct zpm *zpm, char *pkgid, jsw_atree_t *list); -- 2.40.0