]> pd.if.org Git - zpackage/blob - lib/findpkg.c
6d7981a315055bbe50024fe73b3fe6ca34e3a698
[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_libraries_needed(struct zpm *zpm, char *pkgid, jsw_atree_t *list) {
85         char *pkglibsneeded = "\
86                                with pkglibs as (\
87                                                select distinct EN.needed as soname, PF.pkgid\
88                                                from elfneeded EN\
89                                                join packagefiles_pkgid PF on PF.hash = EN.file\
90                                                ),\
91                                pkgprovides as (\
92                                                select distinct EL.soname, PF.pkgid\
93                                                from elflibraries EL\
94                                                join packagefiles_pkgid PF on PF.hash = EL.file\
95                                               )\
96                                select distinct PL.soname, PP.soname is not null as selfsatisfied\
97                                from pkglibs PL\
98                                left join pkgprovides PP on PL.pkgid = PP.pkgid and PL.soname = PP.soname\
99                                where PL.pkgid = %Q\
100                                ";
101
102         sqlite3_stmt *st;
103         int count = 0;
104         int rv;
105
106         st = zpm_dbquery(zpm, pkglibsneeded, pkgid);
107
108         while ((rv = sqlite3_step(st)) == SQLITE_ROW) {
109                 char *soname;
110                 int self;
111
112                 soname = (char *)sqlite3_column_text(st, 0);
113                 /* TODO check and skip self sats */
114                 self = sqlite3_column_int(st,1);
115                 if (self) {
116                         continue;
117                 }
118                 count++;
119
120                 /* if it's in needed, we've already looked at this one */
121                 if (list && !jsw_afind(list, soname)) {
122                         jsw_ainsert(list, soname);
123                 }
124         }
125
126         sqlite3_finalize(st);
127         return count;
128 }
129
130 char *zpm_findpkg(struct zpm *zpm, char *pkgstr, char *where) {
131         char *select = "select pkgid, package, version, release from packages_pkgid";
132 #if 0
133         char *group = "group by package having max( version||'-'||release collate vercmp) order by length(package), package, version||'-'||release collate vercmp";
134 #else
135         char *group = "order by package, version collate vercmp desc, cast(release as integer)";
136         //group = "order by package, version , cast(release as integer)";
137 #endif
138         sqlite3_str *sql;
139         char *query, *pkgid = 0;
140
141         /* null pkgstr find "best" package
142          * best is shortest complete package if any are complete
143          * shortest incomplete if any are incomplete
144          * where more than one version is in those sets, best is
145          * latest as determined by vercmp
146          */
147
148         sql = sqlite3_str_new(zpm->db);
149
150         sqlite3_str_appendall(sql, select);
151         sqlite3_str_appendall(sql, " where true");
152
153         if (pkgstr) {
154                 int release;
155                 char version[32];
156                 char package[32];
157
158                 zpm_parse_package(pkgstr, package, version, &release);
159                 if (*package != 0) {
160                         sqlite3_str_appendf(sql, " and package = %Q",
161                                         package);
162                 }
163                 if (*version != 0) {
164                         sqlite3_str_appendf(sql, " and version = %Q",
165                                         version);
166                 }
167                 if (release != 0) {
168                         sqlite3_str_appendf(sql, " and release = %d",
169                                         release);
170                 }
171         }
172
173         if (where) {
174                 sqlite3_str_appendall(sql, " and ");
175                 sqlite3_str_appendall(sql, where);
176         }
177
178
179         sqlite3_str_appendall(sql, " ");
180         sqlite3_str_appendall(sql, group);
181         sqlite3_str_appendall(sql, " limit 1;");
182
183         if (sqlite3_str_errcode(sql)) {
184                 zpm->error = 1;
185                 sqlite3_free(sqlite3_str_finish(sql));
186                 return 0;
187         }
188
189         query = sqlite3_str_finish(sql);
190
191         pkgid = zpm_db_string(zpm, query);;
192
193         sqlite3_free(query);
194
195         return pkgid;
196 }