aboutsummaryrefslogtreecommitdiff
path: root/m2.c
blob: c54b4a3b9ba624d83ea5991130ddf2501e8f70b1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#define _POSIX_C_SOURCE 200809L

#include <fcgiapp.h>
#include <sqlite3.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <assert.h>

struct fcgi_env {
    FCGX_Stream *in;
    FCGX_Stream *out;
    FCGX_Stream *err;
    FCGX_ParamArray *envp;
};

static sqlite3 *db = NULL;

static void cleanup(void) {
    if (db) {
        sqlite3_close(db);
    }
}

static int cb(void *dat, int count, char **data, char **columns) {
    struct fcgi_env *env = dat;
    if (count != 4) {
        FCGX_FPrintF(env->out,
                "Status: 500 Internal Server Error\r\n"
                "Content-type: text/plain\r\n"
                "\r\n"
                "The database returned %d columns.\n",
                count);
        return 1;
    }
    FCGX_FPrintF(env->out,
            "Content-type: application/json\r\n"
            "\r\n"
            "{\"title\":\"%s\",\"title_zh\":\"%s\",\"text\":\"%s\",\"text_zh\":\"%s\"}\n",
            data[0],
            data[1] == NULL ? "" : data[1],
            data[2],
            data[3]);

    return 0;
}

int main(int argc, char **argv) {
    if (argc != 2) {
        fprintf(stderr, "Usage: %s /path/to/data.db\n", argv[0]);
        return 64;
    }
    atexit(cleanup);
    int r;
    if ((r = sqlite3_open_v2(argv[1], &db, SQLITE_OPEN_READONLY, NULL)) != SQLITE_OK) {
        fprintf(stderr, "Cannot open database: %s\n", sqlite3_errstr(r));
        return r;
    }
    FCGX_Stream *in, *out, *err;
    FCGX_ParamArray envp;
    struct fcgi_env env;
    char *errmsg;
    while(FCGX_Accept(&in, &out, &err, &envp) >= 0) {
        env.in = in;
        env.out = out;
        env.err = err;
        env.envp = &envp;
        if ((r = sqlite3_exec(db, "SELECT title,title_zh,text,text_zh FROM v_random_quote",
                        cb, &env, &errmsg))) {
            FCGX_FPrintF(out,
                    "Status: 500 Internal Server Error\r\n"
                    "Content-type: text/plain\r\n"
                    "\r\n"
                    "%s\n",
                    errmsg);
            sqlite3_free(errmsg);
        }
    }
}