Branch data Line data Source code
1 : : /* Copyright (c) 2014, Vsevolod Stakhov
2 : : * All rights reserved.
3 : : *
4 : : * Redistribution and use in source and binary forms, with or without
5 : : * modification, are permitted provided that the following conditions are met:
6 : : * * Redistributions of source code must retain the above copyright
7 : : * notice, this list of conditions and the following disclaimer.
8 : : * * Redistributions in binary form must reproduce the above copyright
9 : : * notice, this list of conditions and the following disclaimer in the
10 : : * documentation and/or other materials provided with the distribution.
11 : : *
12 : : * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY
13 : : * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
14 : : * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15 : : * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY
16 : : * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17 : : * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18 : : * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19 : : * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20 : : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21 : : * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22 : : */
23 : :
24 : : #include <stdlib.h>
25 : : #include <stdio.h>
26 : : #include <stdbool.h>
27 : : #include <string.h>
28 : :
29 : : #include <sqlite3.h>
30 : :
31 : : #include "pkg.h"
32 : : #include "private/event.h"
33 : : #include "private/pkg.h"
34 : : #include "private/pkgdb.h"
35 : : #include "private/utils.h"
36 : : #include "binary_private.h"
37 : :
38 : : static sql_prstmt sql_prepared_statements[PRSTMT_LAST] = {
39 : : [PKG] = {
40 : : NULL,
41 : : "INSERT OR REPLACE INTO packages ("
42 : : "origin, name, version, comment, desc, arch, maintainer, www, "
43 : : "prefix, pkgsize, flatsize, licenselogic, cksum, path, manifestdigest, olddigest, "
44 : : "vital)"
45 : : "VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16, ?17)",
46 : : "TTTTTTTTTIIITTTTI",
47 : : },
48 : : [DEPS] = {
49 : : NULL,
50 : : "INSERT OR REPLACE INTO deps (origin, name, version, package_id) "
51 : : "VALUES (?1, ?2, ?3, ?4)",
52 : : "TTTI",
53 : : },
54 : : [CAT1] = {
55 : : NULL,
56 : : "INSERT OR IGNORE INTO categories(name) VALUES(?1)",
57 : : "T",
58 : : },
59 : : [CAT2] = {
60 : : NULL,
61 : : "INSERT OR ROLLBACK INTO pkg_categories(package_id, category_id) "
62 : : "VALUES (?1, (SELECT id FROM categories WHERE name = ?2))",
63 : : "IT",
64 : : },
65 : : [LIC1] = {
66 : : NULL,
67 : : "INSERT OR IGNORE INTO licenses(name) VALUES(?1)",
68 : : "T",
69 : : },
70 : : [LIC2] = {
71 : : NULL,
72 : : "INSERT OR ROLLBACK INTO pkg_licenses(package_id, license_id) "
73 : : "VALUES (?1, (SELECT id FROM licenses WHERE name = ?2))",
74 : : "IT",
75 : : },
76 : : [OPT1] = {
77 : : NULL,
78 : : "INSERT OR IGNORE INTO option(option) "
79 : : "VALUES (?1)",
80 : : "T",
81 : : },
82 : : [OPT2] = {
83 : : NULL,
84 : : "INSERT OR ROLLBACK INTO pkg_option (option_id, value, package_id) "
85 : : "VALUES (( SELECT option_id FROM option WHERE option = ?1), ?2, ?3)",
86 : : "TTI",
87 : : },
88 : : [SHLIB1] = {
89 : : NULL,
90 : : "INSERT OR IGNORE INTO shlibs(name) VALUES(?1)",
91 : : "T",
92 : : },
93 : : [SHLIB_REQD] = {
94 : : NULL,
95 : : "INSERT OR IGNORE INTO pkg_shlibs_required(package_id, shlib_id) "
96 : : "VALUES (?1, (SELECT id FROM shlibs WHERE name = ?2))",
97 : : "IT",
98 : : },
99 : : [SHLIB_PROV] = {
100 : : NULL,
101 : : "INSERT OR IGNORE INTO pkg_shlibs_provided(package_id, shlib_id) "
102 : : "VALUES (?1, (SELECT id FROM shlibs WHERE name = ?2))",
103 : : "IT",
104 : : },
105 : : [EXISTS] = {
106 : : NULL,
107 : : "SELECT count(*) FROM packages WHERE cksum=?1",
108 : : "T",
109 : : },
110 : : [ANNOTATE1] = {
111 : : NULL,
112 : : "INSERT OR IGNORE INTO annotation(annotation) "
113 : : "VALUES (?1)",
114 : : "T",
115 : : },
116 : : [ANNOTATE2] = {
117 : : NULL,
118 : : "INSERT OR ROLLBACK INTO pkg_annotation(package_id, tag_id, value_id) "
119 : : "VALUES (?1,"
120 : : " (SELECT annotation_id FROM annotation WHERE annotation=?2),"
121 : : " (SELECT annotation_id FROM annotation WHERE annotation=?3))",
122 : : "ITT",
123 : : },
124 : : [REPO_VERSION] = {
125 : : NULL,
126 : : "SELECT version FROM packages WHERE origin=?1",
127 : : "T",
128 : : },
129 : : [DELETE] = {
130 : : NULL,
131 : : "DELETE FROM packages WHERE origin=?1;"
132 : : "DELETE FROM pkg_search WHERE origin=?1;",
133 : : "TT",
134 : : },
135 : : [PROVIDE] = {
136 : : NULL,
137 : : "INSERT OR IGNORE INTO provides(provide) VALUES(?1)",
138 : : "T",
139 : : },
140 : : [PROVIDES] = {
141 : : NULL,
142 : : "INSERT OR IGNORE INTO pkg_provides(package_id, provide_id) "
143 : : "VALUES (?1, (SELECT id FROM provides WHERE provide = ?2))",
144 : : "IT",
145 : : },
146 : : [REQUIRE] = {
147 : : NULL,
148 : : "INSERT OR IGNORE INTO requires(require) VALUES(?1)",
149 : : "T",
150 : : },
151 : : [REQUIRES] = {
152 : : NULL,
153 : : "INSERT OR IGNORE INTO pkg_requires(package_id, require_id) "
154 : : "VALUES (?1, (SELECT id FROM requires WHERE require = ?2))",
155 : : "IT",
156 : : },
157 : : /* PRSTMT_LAST */
158 : : };
159 : :
160 : : const char *
161 : 0 : pkg_repo_binary_sql_prstatement(sql_prstmt_index s)
162 : : {
163 [ # # ]: 0 : if (s < PRSTMT_LAST)
164 : 0 : return (sql_prepared_statements[s].sql);
165 : : else
166 : 0 : return ("unknown");
167 : 0 : }
168 : :
169 : : sqlite3_stmt*
170 : 0 : pkg_repo_binary_stmt_prstatement(sql_prstmt_index s)
171 : : {
172 [ # # ]: 0 : if (s < PRSTMT_LAST)
173 : 0 : return (sql_prepared_statements[s].stmt);
174 : : else
175 : 0 : return (NULL);
176 : 0 : }
177 : :
178 : : int
179 : 177 : pkg_repo_binary_init_prstatements(sqlite3 *sqlite)
180 : : {
181 : : sql_prstmt_index i, last;
182 : : int ret;
183 : :
184 : 177 : last = PRSTMT_LAST;
185 : :
186 [ + + ]: 3717 : for (i = 0; i < last; i++) {
187 : 3540 : ret = sqlite3_prepare_v2(sqlite, SQL(i), -1, &STMT(i), NULL);
188 [ - + ]: 3540 : if (ret != SQLITE_OK) {
189 : 0 : ERROR_SQLITE(sqlite, SQL(i));
190 : 0 : return (EPKG_FATAL);
191 : : }
192 : 3540 : }
193 : :
194 : 177 : return (EPKG_OK);
195 : 177 : }
196 : :
197 : : int
198 : 876 : pkg_repo_binary_run_prstatement(sql_prstmt_index s, ...)
199 : : {
200 : : int retcode; /* Returns SQLITE error code */
201 : : va_list ap;
202 : : sqlite3_stmt *stmt;
203 : : int i;
204 : : const char *argtypes;
205 : :
206 : 876 : stmt = STMT(s);
207 : 876 : argtypes = sql_prepared_statements[s].argtypes;
208 : :
209 : 876 : sqlite3_reset(stmt);
210 : :
211 : 876 : va_start(ap, s);
212 : :
213 [ + + ]: 4720 : for (i = 0; argtypes[i] != '\0'; i++)
214 : : {
215 [ - + + ]: 3844 : switch (argtypes[i]) {
216 : : case 'T':
217 [ + + ]: 2905 : sqlite3_bind_text(stmt, i + 1, va_arg(ap, const char*),
218 : : -1, SQLITE_STATIC);
219 : 2905 : break;
220 : : case 'I':
221 [ + + ]: 939 : sqlite3_bind_int64(stmt, i + 1, va_arg(ap, int64_t));
222 : 939 : break;
223 : : }
224 : 3844 : }
225 : :
226 : 876 : va_end(ap);
227 : :
228 : 876 : retcode = sqlite3_step(stmt);
229 : :
230 : 876 : return (retcode);
231 : : }
232 : :
233 : : /*
234 : : * Returns a path relative to the dbdir.
235 : : */
236 : : const char *
237 : 788 : pkg_repo_binary_get_filename(struct pkg_repo *repo)
238 : : {
239 [ + + ]: 788 : if (repo->dbpath == NULL)
240 : 140 : xasprintf(&repo->dbpath, "repos/%s/db", repo->name);
241 : 788 : return (repo->dbpath);
242 : : }
243 : :
244 : : void
245 : 237 : pkg_repo_binary_finalize_prstatements(void)
246 : : {
247 : : sql_prstmt_index i, last;
248 : :
249 : 237 : last = PRSTMT_LAST;
250 : :
251 [ + + ]: 4977 : for (i = 0; i < last; i++)
252 : : {
253 [ + + ]: 4740 : if (STMT(i) != NULL) {
254 : 3320 : sqlite3_finalize(STMT(i));
255 : 3320 : STMT(i) = NULL;
256 : 3320 : }
257 : 4740 : }
258 : 237 : }
|