]> git.ozlabs.org Git - ccan/blob - tools/_infotojson/sqlite3_database.c
ed62aee07b94e154c1f75450fdeedccc9c69ea5d
[ccan] / tools / _infotojson / sqlite3_database.c
1 /* SQLite3 database backend. */
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <unistd.h>
5 #include <sqlite3.h>
6 #include "database.h"
7 #include "utils.h"
8
9 /* sqlite3_busy_timeout sleeps for a *second*.  What a piece of shit. */
10 static int busy(void *unused __attribute__((unused)), int count)
11 {
12         usleep(50000);
13
14         /* If we've been stuck for 1000 iterations (at least 50
15          * seconds), give up. */
16         return (count < 1000);
17 }
18
19 void *db_open(const char *file)
20 {
21         sqlite3 *handle;
22
23         int err = sqlite3_open(file, &handle);
24         if (err != SQLITE_OK)
25                 printf("Error %i from sqlite3_open of db '%s'\n", err, file);
26         sqlite3_busy_handler(handle, busy, NULL);
27
28         return handle;
29 }
30
31 static int query_cb(void *data, int num, char**vals,
32                     char**names __attribute__((unused)))
33 {
34         int i;
35         struct db_query *query = data;
36         query->rows = realloc_array(query->rows, query->num_rows+1);
37         query->rows[query->num_rows] = new_array(char *, num);
38         for (i = 0; i < num; i++) {
39                 /* We don't count rows with NULL results
40                  * (eg. count(*),player where count turns out to be
41                  * zero. */
42                 if (!vals[i])
43                         return 0;
44                 query->rows[query->num_rows][i] = strdup(vals[i]);
45         }
46         query->num_rows++;
47         return 0;
48
49
50 /* Runs query (SELECT).  Fails if > 1 row returned.  Fills in columns. */
51 struct db_query *db_query(void *h, const char *query)
52 {
53         struct db_query *ret;
54         char *err;
55
56         ret = (struct db_query*) palloc(sizeof(struct db_query));
57         ret->rows = NULL;
58         ret->num_rows = 0;
59         if (sqlite3_exec(h, query, query_cb, ret, &err) != SQLITE_OK)
60                 printf("Failed sqlite3 query '%s': %s", query, err);
61         return ret;
62 }
63
64 /* Runs command (CREATE TABLE/INSERT) */
65 void db_command(void *h, const char *command)
66 {
67         char *err;
68
69         if (sqlite3_exec(h, command, NULL, NULL, &err) != SQLITE_OK)
70                 printf("Failed sqlite3 command '%s': %s", command, err);
71 }
72
73 /* Starts transaction.  Doesn't need to nest. */
74 /*void db_transaction_start(void *h)
75 {
76         char *err;
77         if (sqlite3_exec(h, "BEGIN EXCLUSIVE TRANSACTION", NULL, NULL, &err)!=SQLITE_OK)
78                 printf("Starting sqlite3 transaction: %s\n", err);
79 }
80
81 /* Finishes transaction, or rolls it back and caller needs to start again. */
82 /*
83 bool db_transaction_finish(void *h)
84 {
85         switch (sqlite3_exec(h, "COMMIT TRANSACTION;", NULL, NULL, NULL)) {
86         case SQLITE_OK:
87                 return true;
88         case SQLITE_BUSY:
89                 if (sqlite3_exec(h, "ROLLBACK TRANSACTION;", NULL, NULL, NULL)
90                     != SQLITE_OK)
91                         printf("Ending sqlite3 busy rollback failed");
92                 return false;
93         default:
94                 printf("Strange sqlite3 error return from COMMIT");
95         }
96 }*/
97
98 /* Closes database (only called when everything OK). */
99 void db_close(void *h)
100 {
101         sqlite3_close(h);
102 }
103