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 : ")"
45 : "VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16)",
46 : "TTTTTTTTTIIITTTT",
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 : [FTS_APPEND] = {
136 : NULL,
137 : "INSERT OR IGNORE INTO pkg_search(id, name, origin) "
138 : "VALUES (?1, ?2 || '-' || ?3, ?4);",
139 : "ITTT"
140 : },
141 : [PROVIDE] = {
142 : NULL,
143 : "INSERT OR IGNORE INTO provides(provide) VALUES(?1)",
144 : "T",
145 : },
146 : [PROVIDES] = {
147 : NULL,
148 : "INSERT OR IGNORE INTO pkg_provides(package_id, provide_id) "
149 : "VALUES (?1, (SELECT id FROM provides WHERE provide = ?2))",
150 : "IT",
151 : },
152 : [REQUIRE] = {
153 : NULL,
154 : "INSERT OR IGNORE INTO requires(require) VALUES(?1)",
155 : "T",
156 : },
157 : [REQUIRES] = {
158 : NULL,
159 : "INSERT OR IGNORE INTO pkg_requires(package_id, require_id) "
160 : "VALUES (?1, (SELECT id FROM requires WHERE require = ?2))",
161 : "IT",
162 : },
163 : /* PRSTMT_LAST */
164 : };
165 :
166 : const char *
167 0 : pkg_repo_binary_sql_prstatement(sql_prstmt_index s)
168 : {
169 0 : if (s < PRSTMT_LAST)
170 0 : return (sql_prepared_statements[s].sql);
171 : else
172 0 : return ("unknown");
173 : }
174 :
175 : sqlite3_stmt*
176 0 : pkg_repo_binary_stmt_prstatement(sql_prstmt_index s)
177 : {
178 0 : if (s < PRSTMT_LAST)
179 0 : return (sql_prepared_statements[s].stmt);
180 : else
181 0 : return (NULL);
182 : }
183 :
184 : int
185 15 : pkg_repo_binary_init_prstatements(sqlite3 *sqlite)
186 : {
187 : sql_prstmt_index i, last;
188 : int ret;
189 :
190 15 : last = PRSTMT_LAST;
191 :
192 330 : for (i = 0; i < last; i++) {
193 315 : ret = sqlite3_prepare_v2(sqlite, SQL(i), -1, &STMT(i), NULL);
194 315 : if (ret != SQLITE_OK) {
195 0 : ERROR_SQLITE(sqlite, SQL(i));
196 0 : return (EPKG_FATAL);
197 : }
198 : }
199 :
200 15 : return (EPKG_OK);
201 : }
202 :
203 : int
204 114 : pkg_repo_binary_run_prstatement(sql_prstmt_index s, ...)
205 : {
206 : int retcode; /* Returns SQLITE error code */
207 : va_list ap;
208 : sqlite3_stmt *stmt;
209 : int i;
210 : const char *argtypes;
211 :
212 114 : stmt = STMT(s);
213 114 : argtypes = sql_prepared_statements[s].argtypes;
214 :
215 114 : sqlite3_reset(stmt);
216 :
217 114 : va_start(ap, s);
218 :
219 693 : for (i = 0; argtypes[i] != '\0'; i++)
220 : {
221 579 : switch (argtypes[i]) {
222 : case 'T':
223 450 : sqlite3_bind_text(stmt, i + 1, va_arg(ap, const char*),
224 : -1, SQLITE_STATIC);
225 450 : break;
226 : case 'I':
227 129 : sqlite3_bind_int64(stmt, i + 1, va_arg(ap, int64_t));
228 129 : break;
229 : }
230 : }
231 :
232 114 : va_end(ap);
233 :
234 114 : retcode = sqlite3_step(stmt);
235 :
236 114 : return (retcode);
237 : }
238 :
239 :
240 : const char *
241 54 : pkg_repo_binary_get_filename(const char *name)
242 : {
243 : static char reponame[MAXPATHLEN];
244 :
245 54 : snprintf(reponame, sizeof(reponame), REPO_NAME_PREFIX "%s.sqlite",
246 : name);
247 :
248 54 : return (reponame);
249 : }
250 :
251 : void
252 16 : pkg_repo_binary_finalize_prstatements(void)
253 : {
254 : sql_prstmt_index i, last;
255 :
256 16 : last = PRSTMT_LAST;
257 :
258 352 : for (i = 0; i < last; i++)
259 : {
260 336 : if (STMT(i) != NULL) {
261 315 : sqlite3_finalize(STMT(i));
262 315 : STMT(i) = NULL;
263 : }
264 : }
265 16 : return;
266 : }
|