chiark / gitweb /
routesearch: actually print number of routes requested, not one less
[ypp-sc-tools.db-live.git] / yarrg / rssql.c
1
2 #include "rscommon.h"
3
4 sqlite3 *db;
5 sqlite3_stmt *ss_ipair;
6
7 int islandtablesz;
8
9 DEBUG_DEFINE_DEBUGF(sql);
10 DEBUG_DEFINE_SOME_DEBUGF(sql,debug2f);
11
12 static int busy_handler(void *u, int previous) {
13   debugf("[[DB BUSY %d]]",previous);
14   sysassert(! usleep(5000) );
15   return 1;
16 }
17
18 void setup_sql(const char *database) {
19   sqlite3_stmt *sst;
20   
21   SQL_MUST( sqlite3_open(database, &db) );
22   SQL_MUST( sqlite3_busy_handler(db, busy_handler, 0) );
23
24   sst= sql_prepare("BEGIN","(begin)");
25   assert( !SQL_STEP(sst) );
26   sqlite3_finalize(sst);
27
28   islandtablesz= 1 + sql_single_int("SELECT max(islandid) FROM islands");
29   debugf("SQL islandtablesz=%d\n",islandtablesz);
30 }
31
32 int sql_single_int(const char *stmt) {
33   sqlite3_stmt *sst;
34   sst= sql_prepare(stmt,"(single int)");
35   assert( SQL_STEP(sst) );
36   int rv= sqlite3_column_int(sst,0);
37   sqlite3_finalize(sst);
38   return rv;
39 }
40
41 void sql_fatal(const char *stmt_what, int sqr, const char *act_what) {
42   fatal("SQL call failed, stmt %s code %d: %s: %s",
43         stmt_what, sqr, sqlite3_errmsg(db), act_what);
44 }
45
46 void sql_bind(sqlite3_stmt *ss, int index, int value,
47               const char *ss_what, const char *val_what) {
48   debug2f("SQL BIND %s #%d = %d = %s\n", ss_what, index, value, val_what);
49   int sqr= sqlite3_bind_int(ss, index, value);
50   if (sqr) sql_fatal(ss_what, sqr,
51                      masprintf("bind #%d (%s)", index, val_what));
52 }
53   
54 sqlite3_stmt *sql_prepare(const char *stmt, const char *what) {
55   sqlite3_stmt *ssr;
56   debugf("SQL PREPARE %s [[\n%s\n]]\n", what, stmt);
57   SQL_MUST( sqlite3_prepare(db, stmt, -1, &ssr, 0) );
58   return ssr;
59 }
60
61 int sql_step_distinct(sqlite3_stmt *ssh, const char *ssh_string,
62                       const char *file, int line,
63                       int *cols, int ncols, int nkeycols) {
64   for (;;) {
65     if (!sql_step(ssh, ssh_string, file, line)) return 0;
66
67     int i;
68     for (i=0; i<ncols; i++) {
69       int v= sqlite3_column_int(ssh, i);
70       if (v == cols[i]) continue;
71       
72       assert(i<nkeycols);
73       cols[i++]= v;
74       for ( ; i<ncols; i++)
75         cols[i]= sqlite3_column_int(ssh, i);
76       return 1;
77     }
78   }
79 }
80
81 int sql_step(sqlite3_stmt *ssh, const char *ssh_string,
82              const char *file, int line) {
83   for (;;) {
84     int sqr;
85     sqr= sqlite3_step((ssh));
86     switch (sqr) {
87     case SQLITE_DONE:
88       debug2f("SQL %s DONE\n",ssh_string);
89       return 0;
90     case SQLITE_ROW:
91       if (DEBUGP(sql2)) {
92         int i;
93         fprintf(debug,"SQL %s R",ssh_string);
94         for (i=0; i<sqlite3_column_count(ssh); i++) {
95           fputc('\t',debug);
96           const char *txt= (const char*)sqlite3_column_text(ssh,i);
97           fputs(txt ? txt : "<null>", debug);
98         }
99         fputs("\n",debug);
100       }
101       return 1;
102     default: fatal("SQL step failed at %s:%d: code %d: %s: %s",
103                    file, line, sqr, sqlite3_errmsg(db), ssh_string);
104     }
105   }
106 }