2 * Route searcher - database helper functions
5 * This is part of the YARRG website, a tool for assisting
6 * players of Yohoho Puzzle Pirates.
8 * Copyright (C) 2009 Ian Jackson <ijackson@chiark.greenend.org.uk>
10 * This program is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU Affero General Public License as
12 * published by the Free Software Foundation, either version 3 of the
13 * License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Affero General Public License for more details.
20 * You should have received a copy of the GNU Affero General Public License
21 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23 * Yohoho and Puzzle Pirates are probably trademarks of Three Rings and
24 * are used without permission. This program is not endorsed or
25 * sponsored by Three Rings.
31 sqlite3_stmt *ss_ipair;
35 DEBUG_DEFINE_DEBUGF(sql);
36 DEBUG_DEFINE_SOME_DEBUGF(sql,debug2f);
38 static int busy_handler(void *u, int previous) {
39 debugf("[[DB BUSY %d]]",previous);
40 sysassert(! usleep(5000) );
44 void setup_sql(const char *database) {
47 SQL_MUST( sqlite3_open(database, &db) );
48 SQL_MUST( sqlite3_busy_handler(db, busy_handler, 0) );
50 sst= sql_prepare("BEGIN","(begin)");
51 assert( !SQL_STEP(sst) );
52 sqlite3_finalize(sst);
54 islandtablesz= 1 + sql_single_int("SELECT max(islandid) FROM islands");
55 debugf("SQL islandtablesz=%d\n",islandtablesz);
58 int sql_single_int(const char *stmt) {
60 sst= sql_prepare(stmt,"(single int)");
61 assert( SQL_STEP(sst) );
62 int rv= sqlite3_column_int(sst,0);
63 sqlite3_finalize(sst);
67 void sql_fatal(const char *stmt_what, int sqr, const char *act_what) {
68 fatal("SQL call failed, stmt %s code %d: %s: %s",
69 stmt_what, sqr, sqlite3_errmsg(db), act_what);
72 void sql_bind(sqlite3_stmt *ss, int index, int value,
73 const char *ss_what, const char *val_what) {
74 debug2f("SQL BIND %s #%d = %d = %s\n", ss_what, index, value, val_what);
75 int sqr= sqlite3_bind_int(ss, index, value);
76 if (sqr) sql_fatal(ss_what, sqr,
77 masprintf("bind #%d (%s)", index, val_what));
80 sqlite3_stmt *sql_prepare(const char *stmt, const char *what) {
82 debugf("SQL PREPARE %s [[\n%s\n]]\n", what, stmt);
83 SQL_MUST( sqlite3_prepare(db, stmt, -1, &ssr, 0) );
87 int sql_step_distinct(sqlite3_stmt *ssh, const char *ssh_string,
88 const char *file, int line,
89 int *cols, int ncols, int nkeycols) {
91 if (!sql_step(ssh, ssh_string, file, line)) return 0;
94 for (i=0; i<ncols; i++) {
95 int v= sqlite3_column_int(ssh, i);
96 if (v == cols[i]) continue;
100 for ( ; i<ncols; i++)
101 cols[i]= sqlite3_column_int(ssh, i);
107 int sql_step(sqlite3_stmt *ssh, const char *ssh_string,
108 const char *file, int line) {
111 sqr= sqlite3_step((ssh));
114 debug2f("SQL %s DONE\n",ssh_string);
119 fprintf(debug,"SQL %s R",ssh_string);
120 for (i=0; i<sqlite3_column_count(ssh); i++) {
122 const char *txt= (const char*)sqlite3_column_text(ssh,i);
123 fputs(txt ? txt : "<null>", debug);
128 default: fatal("SQL step failed at %s:%d: code %d: %s: %s",
129 file, line, sqr, sqlite3_errmsg(db), ssh_string);