Blob


1 /*
2 * Copyright (c) 2022 Omar Polo <op@openbsd.org>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
17 #include <err.h>
18 #include <stdio.h>
19 #include <stdlib.h>
21 #include <sqlite3.h>
23 #include "db.h"
24 #include "dictionary.h"
25 #include "tokenize.h"
27 #include "mkftsidx.h"
29 #ifndef SQLPORTS
30 #define SQLPORTS "/usr/local/share/sqlports"
31 #endif
33 #define QNUM "select count(*) from portsq;"
34 #define QALL "select pkgstem, comment, descr_contents from portsq;"
36 static int
37 countports(sqlite3 *db)
38 {
39 sqlite3_stmt *stmt;
40 int r, n = -1;
42 r = sqlite3_prepare_v2(db, QNUM, -1, &stmt, NULL);
43 if (r != SQLITE_OK) {
44 warnx("failed to prepare statement: %s",
45 sqlite3_errstr(r));
46 return -1;
47 }
49 r = sqlite3_step(stmt);
50 if (r == SQLITE_ROW)
51 n = sqlite3_column_int(stmt, 0);
53 sqlite3_finalize(stmt);
54 return n;
55 }
57 int
58 idx_ports(struct dictionary *dict, struct db_entry **entries, size_t *len,
59 int argc, char **argv)
60 {
61 const char *dbpath;
62 sqlite3 *db;
63 sqlite3_stmt *stmt;
64 size_t i;
65 int r;
67 if (argc > 1)
68 usage();
69 else if (argc == 1)
70 dbpath = *argv;
71 else
72 dbpath = SQLPORTS;
74 if ((r = sqlite3_open(dbpath, &db)) != SQLITE_OK)
75 errx(1, "can't open %s: %s", dbpath, sqlite3_errstr(r));
77 if ((r = countports(db)) == -1 || r == 0) {
78 warnx("error querying the db or empty portsq table!");
79 goto done;
80 }
81 *len = r;
83 if ((*entries = calloc(*len, sizeof(**entries))) == NULL)
84 err(1, "calloc");
86 r = sqlite3_prepare_v2(db, QALL, -1, &stmt, NULL);
87 if (r != SQLITE_OK)
88 errx(1, "failed to prepare statement: %s", sqlite3_errstr(r));
90 for (i = 0; i < *len; ++i) {
91 const char *pkgstem, *comment, *descr;
92 char *doc, **toks;
94 r = sqlite3_step(stmt);
95 if (r == SQLITE_DONE)
96 break;
97 if (r != SQLITE_ROW)
98 errx(1, "sqlite3_step: %s", sqlite3_errstr(r));
100 pkgstem = sqlite3_column_text(stmt, 0);
101 comment = sqlite3_column_text(stmt, 1);
102 descr = sqlite3_column_text(stmt, 2);
104 (*entries)[i].name = xstrdup(pkgstem);
105 (*entries)[i].descr = xstrdup(comment);
107 r = asprintf(&doc, "%s %s %s", pkgstem,
108 comment != NULL ? comment : "",
109 descr != NULL ? descr : "");
110 if (r == -1)
111 err(1, "asprintf");
113 if ((toks = tokenize(doc)) == NULL)
114 err(1, "tokenize");
115 if (!dictionary_add_words(dict, toks, i))
116 err(1, "dictionary_add_words");
117 freetoks(toks);
118 free(doc);
121 done:
122 sqlite3_close(db);
123 return 0;