=================================================================== RCS file: /cvs/mandoc/mandocdb.c,v retrieving revision 1.133 retrieving revision 1.138 diff -u -p -r1.133 -r1.138 --- mandoc/mandocdb.c 2014/04/10 02:46:21 1.133 +++ mandoc/mandocdb.c 2014/04/18 21:55:38 1.138 @@ -1,4 +1,4 @@ -/* $Id: mandocdb.c,v 1.133 2014/04/10 02:46:21 schwarze Exp $ */ +/* $Id: mandocdb.c,v 1.138 2014/04/18 21:55:38 schwarze Exp $ */ /* * Copyright (c) 2011, 2012 Kristaps Dzonsons * Copyright (c) 2011, 2012, 2013, 2014 Ingo Schwarze @@ -55,22 +55,22 @@ extern const char *const mansearch_keynames[]; #define SQL_EXEC(_v) \ if (SQLITE_OK != sqlite3_exec(db, (_v), NULL, NULL, NULL)) \ - fprintf(stderr, "%s\n", sqlite3_errmsg(db)) + say("", "%s: %s", (_v), sqlite3_errmsg(db)) #define SQL_BIND_TEXT(_s, _i, _v) \ if (SQLITE_OK != sqlite3_bind_text \ ((_s), (_i)++, (_v), -1, SQLITE_STATIC)) \ - fprintf(stderr, "%s\n", sqlite3_errmsg(db)) + say(mlink->file, "%s", sqlite3_errmsg(db)) #define SQL_BIND_INT(_s, _i, _v) \ if (SQLITE_OK != sqlite3_bind_int \ ((_s), (_i)++, (_v))) \ - fprintf(stderr, "%s\n", sqlite3_errmsg(db)) + say(mlink->file, "%s", sqlite3_errmsg(db)) #define SQL_BIND_INT64(_s, _i, _v) \ if (SQLITE_OK != sqlite3_bind_int64 \ ((_s), (_i)++, (_v))) \ - fprintf(stderr, "%s\n", sqlite3_errmsg(db)) + say(mlink->file, "%s", sqlite3_errmsg(db)) #define SQL_STEP(_s) \ if (SQLITE_DONE != sqlite3_step((_s))) \ - fprintf(stderr, "%s\n", sqlite3_errmsg(db)) + say(mlink->file, "%s", sqlite3_errmsg(db)) enum op { OP_DEFAULT = 0, /* new dbs from dir list or default config */ @@ -100,7 +100,7 @@ struct inodev { struct mpage { struct inodev inodev; /* used for hashing routine */ - int64_t recno; /* id in mpages SQL table */ + int64_t pageid; /* pageid in mpages SQL table */ enum form form; /* format from file content */ char *sec; /* section from file content */ char *arch; /* architecture from file content */ @@ -442,15 +442,25 @@ main(int argc, char *argv[]) */ if (0 == set_basedir(path_arg)) goto out; - for (i = 0; i < argc; i++) - filescan(argv[i]); - if (0 == dbopen(1)) - goto out; - if (OP_TEST != op) - dbprune(); + if (dbopen(1)) { + for (i = 0; i < argc; i++) + filescan(argv[i]); + if (OP_TEST != op) + dbprune(); + } else { + /* + * Database missing or corrupt. + * Recreate from scratch. + */ + op = OP_DEFAULT; + if (0 == treescan()) + goto out; + if (0 == dbopen(0)) + goto out; + } if (OP_DELETE != op) mpages_merge(mc, mp); - dbclose(1); + dbclose(OP_DEFAULT == op ? 0 : 1); } else { /* * If we have arguments, use them as our manpaths. @@ -1099,7 +1109,7 @@ mpages_merge(struct mchars *mc, struct mparse *mp) * to the target. */ - if (mpage_dest->recno) + if (mpage_dest->pageid) dbadd_mlink(mlink); if (NULL == mlink->next) @@ -1154,18 +1164,17 @@ mpages_merge(struct mchars *mc, struct mparse *mp) putkey(mpage, mlink->name, NAME_FILE); } + assert(NULL == mpage->desc); if (NULL != mdoc) { if (NULL != (cp = mdoc_meta(mdoc)->name)) putkey(mpage, cp, NAME_HEAD); - assert(NULL == mpage->desc); parse_mdoc(mpage, mdoc_node(mdoc)); - if (NULL == mpage->desc) - mpage->desc = mandoc_strdup( - mpage->mlinks->name); } else if (NULL != man) parse_man(mpage, man_node(man)); else parse_cat(mpage, fd[0]); + if (NULL == mpage->desc) + mpage->desc = mandoc_strdup(mpage->mlinks->name); if (warnings && !use_all) for (mlink = mpage->mlinks; mlink; @@ -1205,7 +1214,6 @@ names_check(void) { sqlite3_stmt *stmt; const char *name, *sec, *arch, *key; - size_t i; int irc; sqlite3_prepare_v2(db, @@ -1221,8 +1229,8 @@ names_check(void) ") USING (pageid);", -1, &stmt, NULL); - i = 1; - SQL_BIND_INT64(stmt, i, NAME_TITLE); + if (SQLITE_OK != sqlite3_bind_int64(stmt, 1, NAME_TITLE)) + say("", "%s", sqlite3_errmsg(db)); while (SQLITE_ROW == (irc = sqlite3_step(stmt))) { name = sqlite3_column_text(stmt, 0); @@ -1303,8 +1311,6 @@ parse_cat(struct mpage *mpage, int fd) if (warnings) say(mpage->mlinks->file, "Cannot find NAME section"); - assert(NULL == mpage->desc); - mpage->desc = mandoc_strdup(mpage->mlinks->name); fclose(stream); free(title); return; @@ -1343,7 +1349,6 @@ parse_cat(struct mpage *mpage, int fd) plen -= 2; } - assert(NULL == mpage->desc); mpage->desc = mandoc_strdup(p); fclose(stream); free(title); @@ -1483,7 +1488,6 @@ parse_man(struct mpage *mpage, const struct man_node * while (' ' == *start) start++; - assert(NULL == mpage->desc); mpage->desc = mandoc_strdup(start); free(title); return; @@ -1898,7 +1902,7 @@ dbadd_mlink(const struct mlink *mlink) SQL_BIND_TEXT(stmts[STMT_INSERT_LINK], i, mlink->dsec); SQL_BIND_TEXT(stmts[STMT_INSERT_LINK], i, mlink->arch); SQL_BIND_TEXT(stmts[STMT_INSERT_LINK], i, mlink->name); - SQL_BIND_INT64(stmts[STMT_INSERT_LINK], i, mlink->mpage->recno); + SQL_BIND_INT64(stmts[STMT_INSERT_LINK], i, mlink->mpage->pageid); SQL_STEP(stmts[STMT_INSERT_LINK]); sqlite3_reset(stmts[STMT_INSERT_LINK]); } @@ -1950,13 +1954,14 @@ dbadd(struct mpage *mpage, struct mchars *mc) SQL_BIND_TEXT(stmts[STMT_INSERT_PAGE], i, mpage->desc); SQL_BIND_INT(stmts[STMT_INSERT_PAGE], i, FORM_SRC == mpage->form); SQL_STEP(stmts[STMT_INSERT_PAGE]); - mpage->recno = sqlite3_last_insert_rowid(db); + mpage->pageid = sqlite3_last_insert_rowid(db); sqlite3_reset(stmts[STMT_INSERT_PAGE]); while (NULL != mlink) { dbadd_mlink(mlink); mlink = mlink->next; } + mlink = mpage->mlinks; for (key = ohash_first(&names, &slot); NULL != key; key = ohash_next(&names, &slot)) { @@ -1966,7 +1971,7 @@ dbadd(struct mpage *mpage, struct mchars *mc) i = 1; SQL_BIND_INT64(stmts[STMT_INSERT_NAME], i, key->mask); SQL_BIND_TEXT(stmts[STMT_INSERT_NAME], i, key->rendered); - SQL_BIND_INT64(stmts[STMT_INSERT_NAME], i, mpage->recno); + SQL_BIND_INT64(stmts[STMT_INSERT_NAME], i, mpage->pageid); SQL_STEP(stmts[STMT_INSERT_NAME]); sqlite3_reset(stmts[STMT_INSERT_NAME]); if (key->rendered != key->key) @@ -1981,7 +1986,7 @@ dbadd(struct mpage *mpage, struct mchars *mc) i = 1; SQL_BIND_INT64(stmts[STMT_INSERT_KEY], i, key->mask); SQL_BIND_TEXT(stmts[STMT_INSERT_KEY], i, key->rendered); - SQL_BIND_INT64(stmts[STMT_INSERT_KEY], i, mpage->recno); + SQL_BIND_INT64(stmts[STMT_INSERT_KEY], i, mpage->pageid); SQL_STEP(stmts[STMT_INSERT_KEY]); sqlite3_reset(stmts[STMT_INSERT_KEY]); if (key->rendered != key->key) @@ -2177,30 +2182,32 @@ create_tables: sql = "CREATE TABLE \"mpages\" (\n" " \"desc\" TEXT NOT NULL,\n" " \"form\" INTEGER NOT NULL,\n" - " \"id\" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL\n" + " \"pageid\" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL\n" ");\n" "\n" "CREATE TABLE \"mlinks\" (\n" " \"sec\" TEXT NOT NULL,\n" " \"arch\" TEXT NOT NULL,\n" " \"name\" TEXT NOT NULL,\n" - " \"pageid\" INTEGER NOT NULL REFERENCES mpages(id) " + " \"pageid\" INTEGER NOT NULL REFERENCES mpages(pageid) " "ON DELETE CASCADE\n" ");\n" + "CREATE INDEX mlinks_pageid_idx ON mlinks (pageid);\n" "\n" "CREATE TABLE \"names\" (\n" " \"bits\" INTEGER NOT NULL,\n" " \"name\" TEXT NOT NULL,\n" - " \"pageid\" INTEGER NOT NULL REFERENCES mpages(id) " + " \"pageid\" INTEGER NOT NULL REFERENCES mpages(pageid) " "ON DELETE CASCADE\n" ");\n" "\n" "CREATE TABLE \"keys\" (\n" " \"bits\" INTEGER NOT NULL,\n" " \"key\" TEXT NOT NULL,\n" - " \"pageid\" INTEGER NOT NULL REFERENCES mpages(id) " + " \"pageid\" INTEGER NOT NULL REFERENCES mpages(pageid) " "ON DELETE CASCADE\n" - ");\n"; + ");\n" + "CREATE INDEX keys_pageid_idx ON keys (pageid);\n"; if (SQLITE_OK != sqlite3_exec(db, sql, NULL, NULL, NULL)) { exitcode = (int)MANDOCLEVEL_SYSERR; @@ -2210,7 +2217,7 @@ create_tables: prepare_statements: SQL_EXEC("PRAGMA foreign_keys = ON"); - sql = "DELETE FROM mpages WHERE id IN " + sql = "DELETE FROM mpages WHERE pageid IN " "(SELECT pageid FROM mlinks WHERE " "sec=? AND arch=? AND name=?)"; sqlite3_prepare_v2(db, sql, -1, &stmts[STMT_DELETE_PAGE], NULL);