]> pd.if.org Git - zpackage/blob - lib/findpkg.c
add range search to findpkg
[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 #include "lib/jsw/jsw_atree.h"
12
13 #define DMARK fprintf(stderr, "mark %s %s:%d\n", __FILE__, __func__, __LINE__)
14
15 /*
16  * flags 0 = find installed
17  * flags 1 = skip installed
18  * flags 2 = skip not installed
19  */
20
21 struct zpm_package *zpm_package_alloc(struct zpm *zpm) {
22         struct zpm_package *pkg;
23
24         pkg = malloc(sizeof *pkg);
25         if (pkg) {
26                 pkg->zpm = zpm;
27                 pkg->release = 0;
28         }
29         return pkg;
30 }
31
32 void zpm_sqlite_error(struct zpm *zpm) {
33         zpm->error = 1;
34         if (zpm->errmsg) free(zpm->errmsg);
35         zpm->errmsg = strdup((const char *)sqlite3_errmsg(zpm->db));
36 }
37
38 char *zpm_findlib(struct zpm *zpm, char *soname, char *where) {
39         sqlite3_str *sql;
40         char *query, *pkgid = 0;
41
42 char *select = "select printf('%%s-%%s-%%s',P.package,P.version,P.release) as pkgid, P.package, P.version, P.release\
43         from packagefiles PF\
44         join elflibraries EL on EL.file = PF.hash\
45         join packages P on P.package = PF.package and P.version = PF.version and P.release = PF.release";
46         char *order = "order by P.package, P.version, cast(P.release as integer)";
47
48         /* null pkgstr find "best" package
49          * best is shortest complete package if any are complete
50          * shortest incomplete if any are incomplete
51          * where more than one version is in those sets, best is
52          * latest as determined by vercmp
53          */
54
55         sql = sqlite3_str_new(zpm->db);
56
57         sqlite3_str_appendall(sql, select);
58         sqlite3_str_appendf(sql, " where P.hash is not null and EL.soname = %Q", soname);
59
60         if (where) {
61                 sqlite3_str_appendall(sql, " and ");
62                 sqlite3_str_appendall(sql, where);
63         }
64
65         sqlite3_str_appendall(sql, " ");
66         sqlite3_str_appendall(sql, order);
67         sqlite3_str_appendall(sql, " limit 1;");
68
69         if (sqlite3_str_errcode(sql)) {
70                 zpm->error = 1;
71                 sqlite3_free(sqlite3_str_finish(sql));
72                 return 0;
73         }
74
75         query = sqlite3_str_finish(sql);
76
77         pkgid = zpm_db_string(zpm, query);;
78
79         sqlite3_free(query);
80
81         return pkgid;
82 }
83
84 int zpm_packages_needed(struct zpm *zpm, char *pkgid, jsw_atree_t *list) {
85         char *pkglibsneeded = "select soname, selfsatisfied from package_libraries_needed where pkgid = %Q";
86         sqlite3_stmt *st;
87         int count = 0;
88         int rv;
89
90         st = zpm_dbquery(zpm, pkglibsneeded, pkgid);
91
92         while ((rv = sqlite3_step(st)) == SQLITE_ROW) {
93                 char *soname;
94                 int self;
95
96                 soname = (char *)sqlite3_column_text(st, 0);
97                 /* TODO check and skip self sats */
98                 self = sqlite3_column_int(st,1);
99                 if (self) {
100                         continue;
101                 }
102                 count++;
103
104                 /* if it's in needed, we've already looked at this one */
105                 if (list && !jsw_afind(list, soname)) {
106                         jsw_ainsert(list, soname);
107                 }
108         }
109
110         sqlite3_finalize(st);
111         return count;
112 }
113
114
115 int zpm_libraries_needed(struct zpm *zpm, char *pkgid, jsw_atree_t *list) {
116         char *pkglibsneeded = "select soname, selfsatisfied from package_libraries_needed where pkgid = %Q";
117         sqlite3_stmt *st;
118         int count = 0;
119         int rv;
120
121         st = zpm_dbquery(zpm, pkglibsneeded, pkgid);
122
123         while ((rv = sqlite3_step(st)) == SQLITE_ROW) {
124                 char *soname;
125                 int self;
126
127                 soname = (char *)sqlite3_column_text(st, 0);
128                 /* TODO check and skip self sats */
129                 self = sqlite3_column_int(st,1);
130                 if (self) {
131                         continue;
132                 }
133                 count++;
134
135                 /* if it's in needed, we've already looked at this one */
136                 if (list && !jsw_afind(list, soname)) {
137                         jsw_ainsert(list, soname);
138                 }
139         }
140
141         sqlite3_finalize(st);
142         return count;
143 }
144
145 char *zpm_findpkg(struct zpm *zpm, char *pkgstr, char *where) {
146         char *select = "select pkgid, package, version, release from packages_pkgid";
147 #if 0
148         char *group = "group by package having max( version||'-'||release collate vercmp) order by length(package), package, version||'-'||release collate vercmp";
149 #else
150         char *group = "order by package, version collate vercmp desc, cast(release as integer)";
151         //group = "order by package, version , cast(release as integer)";
152 #endif
153         sqlite3_str *sql;
154         char *query, *pkgid = 0;
155
156         /* null pkgstr find "best" package
157          * best is shortest complete package if any are complete
158          * shortest incomplete if any are incomplete
159          * where more than one version is in those sets, best is
160          * latest as determined by vercmp
161          */
162
163         sql = sqlite3_str_new(zpm->db);
164
165         sqlite3_str_appendall(sql, select);
166         sqlite3_str_appendall(sql, " where true");
167
168         if (pkgstr) {
169                 int release;
170                 char version[32];
171                 char package[32];
172
173                 zpm_parse_package(pkgstr, package, version, &release);
174                 if (*package != 0) {
175                         sqlite3_str_appendf(sql, " and package = %Q",
176                                         package);
177                 }
178                 if (*version != 0) {
179                         sqlite3_str_appendf(sql, " and version = %Q",
180                                         version);
181                 }
182                 if (release != 0) {
183                         sqlite3_str_appendf(sql, " and release = %d",
184                                         release);
185                 }
186         }
187
188         if (where) {
189                 sqlite3_str_appendall(sql, " and ");
190                 sqlite3_str_appendall(sql, where);
191         }
192
193
194         sqlite3_str_appendall(sql, " ");
195         sqlite3_str_appendall(sql, group);
196         sqlite3_str_appendall(sql, " limit 1;");
197
198         if (sqlite3_str_errcode(sql)) {
199                 zpm->error = 1;
200                 sqlite3_free(sqlite3_str_finish(sql));
201                 return 0;
202         }
203
204         query = sqlite3_str_finish(sql);
205
206         pkgid = zpm_db_string(zpm, query);;
207
208         sqlite3_free(query);
209
210         return pkgid;
211 }
212
213 char *zpm_findpkg_range(struct zpm *zpm, char *minpkg, char *maxpkg, char *where, int wantleast) {
214         int release;
215         char version[32];
216         char package[32];
217
218         char *select = "select pkgid, package, version, release from packages_pkgid";
219         char *last = "order by version collate vercmp desc, cast(release as integer) desc";
220         char *first = "order by version collate vercmp, cast(release as integer)";
221         char *group;
222
223         char *query, *pkgid = 0;
224         sqlite3_str *sql;
225
226         group = wantleast ? first : last;
227         /* null pkgstr find "best" package
228          * best is shortest complete package if any are complete
229          * shortest incomplete if any are incomplete
230          * where more than one version is in those sets, best is
231          * latest as determined by vercmp
232          */
233
234         sql = sqlite3_str_new(zpm->db);
235
236         sqlite3_str_appendall(sql, select);
237         sqlite3_str_appendall(sql, " where true");
238
239         if (minpkg) {
240                 sqlite3_str_appendf(sql, " and pkgid >= %Q collate vercmp",
241                                 minpkg);
242                 zpm_parse_package(minpkg, package, version, &release);
243                 if (*package != 0) {
244                         sqlite3_str_appendf(sql, " and package = %Q",
245                                         package);
246                 }
247         }
248
249         if (maxpkg) {
250                 sqlite3_str_appendf(sql, " and pkgid <= %Q collate vercmp",
251                                 maxpkg);
252                 zpm_parse_package(maxpkg, package, version, &release);
253                 if (*package != 0) {
254                         sqlite3_str_appendf(sql, " and package = %Q",
255                                         package);
256                 }
257         }
258
259         if (where) {
260                 sqlite3_str_appendall(sql, " and ");
261                 sqlite3_str_appendall(sql, where);
262         }
263
264         sqlite3_str_appendall(sql, " ");
265         sqlite3_str_appendall(sql, group);
266         sqlite3_str_appendall(sql, " limit 1;");
267
268         if (sqlite3_str_errcode(sql)) {
269                 zpm->error = 1;
270                 sqlite3_free(sqlite3_str_finish(sql));
271                 return 0;
272         }
273
274         query = sqlite3_str_finish(sql);
275
276         pkgid = zpm_db_string(zpm, query);;
277
278         sqlite3_free(query);
279
280         return pkgid;
281 }