]> pd.if.org Git - zpackage/blob - lib/findpkg.c
072f9f1cbd21745259eeb1c0b59e412424bd490a
[zpackage] / lib / findpkg.c
1 #define _POSIX_C_SOURCE 200809L
2
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <string.h>
6 #include <ctype.h>
7
8 #include "zpm.h"
9
10 #include "sqlite3.h"
11
12 #define DMARK fprintf(stderr, "mark %s %s:%d\n", __FILE__, __func__, __LINE__)
13
14 /*
15  * flags 0 = find installed
16  * flags 1 = skip installed
17  * flags 2 = skip not installed
18  */
19
20 struct zpm_package *zpm_package_alloc(struct zpm *zpm) {
21         struct zpm_package *pkg;
22
23         pkg = malloc(sizeof *pkg);
24         if (pkg) {
25                 pkg->zpm = zpm;
26                 pkg->release = 0;
27         }
28         return pkg;
29 }
30
31 void zpm_sqlite_error(struct zpm *zpm) {
32         zpm->error = 1;
33         if (zpm->errmsg) free(zpm->errmsg);
34         zpm->errmsg = strdup((const char *)sqlite3_errmsg(zpm->db));
35 }
36
37 char *zpm_findpkg(struct zpm *zpm, char *pkgstr) {
38         char *select = "select pkgid, package, version, release from packages_pkgid";
39         char *group = "group by package having max( version||'-'||release collate vercmp) order by length(package), package, version||'-'||release collate vercmp";
40 #if 0
41         char *sstr[] = {
42                 "status = 'installed'",
43                 "",
44                 "status != 'installed'"
45         };
46 #endif
47
48 //      char *order = "order by package, version collate vercmp, cast(release as integer)";
49         sqlite3_str *sql;
50         sqlite3_stmt *stmt;
51         char *query, *pkgid = 0;
52         char package[32];
53         char version[32];
54         int release;
55
56         if (pkgstr == NULL) {
57                 fprintf(stderr, "trying to parse null string\n");
58                 return NULL;
59         }
60
61         /* null pkgstr find "best" package
62          * best is shortest complete package if any are complete
63          * shortest incomplete if any are incomplete
64          * where more than one version is in those sets, best is
65          * latest as determined by vercmp
66          */
67
68         /* given a package name, get the packages */
69         /* no package name, get all */
70
71         //              char where[1024] = "";
72
73         zpm_parse_package(pkgstr, package, version, &release);
74
75         /* install a collation function */
76         zpm_addvercmp(zpm);
77
78         /* TODO allow more args to nail down version and release */
79
80         sql = sqlite3_str_new(zpm->db);
81         sqlite3_str_appendall(sql, select);
82         sqlite3_str_appendf(sql, " where package = %Q", package);
83         if (*version) {
84                 sqlite3_str_appendf(sql, " and version = %Q", version);
85         }
86         if (release) {
87                 sqlite3_str_appendf(sql, " and release = %d", release);
88         }
89         sqlite3_str_appendf(sql, " %s", group);
90         sqlite3_str_appendf(sql, " limit 1");
91
92         if (sqlite3_str_errcode(sql)) {
93                 zpm->error = 1;
94                 sqlite3_free(sqlite3_str_finish(sql));
95                 return 0;
96         }
97
98         query = sqlite3_str_finish(sql);
99         sqlite3_prepare_v2(zpm->db, query, strlen(query), &stmt, NULL);
100         sqlite3_free(query);
101
102 #if 0
103         if (zpm->pkgid) {
104                 free(zpm->pkgid);
105         }
106         zpm->pkgid = 0;
107 #endif
108
109         switch (sqlite3_step(stmt)) {
110                 case SQLITE_ROW:
111                         pkgid = strdup((const char *)sqlite3_column_text(stmt, 0));
112                         break;
113                 case SQLITE_DONE:
114                         /* not found */
115                         break;
116                 default:
117                         zpm_sqlite_error(zpm);
118                         break;
119         }
120         sqlite3_finalize(stmt);
121
122         return pkgid;
123 }