mongoose/examples/api_server/db_plugin_sqlite.c

108 lines
3.4 KiB
C

/*
* Copyright (c) 2014 Cesanta Software Limited
* All rights reserved
*/
#include "db_plugin.h"
#include "sqlite3.h"
void *db_open(const char *db_path) {
sqlite3 *db = NULL;
if (sqlite3_open_v2(db_path, &db, SQLITE_OPEN_READWRITE |
SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX, NULL) == SQLITE_OK) {
sqlite3_exec(db, "CREATE TABLE IF NOT EXISTS kv(key PRIMARY KEY, val);",
0, 0, 0);
}
return db;
}
void db_close(void **db_handle) {
if (db_handle != NULL && *db_handle != NULL) {
sqlite3_close(*db_handle);
*db_handle = NULL;
}
}
static void op_set(struct mg_connection *nc, const struct http_message *hm,
const struct mg_str *key, void *db) {
sqlite3_stmt *stmt = NULL;
char value[200];
const struct mg_str *body = hm->query_string.len > 0 ?
&hm->query_string : &hm->body;
mg_get_http_var(body, "value", value, sizeof(value));
if (sqlite3_prepare_v2(db, "INSERT OR REPLACE INTO kv VALUES (?, ?);",
-1, &stmt, NULL) == SQLITE_OK) {
sqlite3_bind_text(stmt, 1, key->p, key->len, SQLITE_STATIC);
sqlite3_bind_text(stmt, 2, value, strlen(value), SQLITE_STATIC);
sqlite3_step(stmt);
sqlite3_finalize(stmt);
}
mg_printf(nc, "%s", "HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n");
}
static void op_get(struct mg_connection *nc, const struct http_message *hm,
const struct mg_str *key, void *db) {
sqlite3_stmt *stmt = NULL;
const char *data = NULL;
int result;
(void) hm;
if (sqlite3_prepare_v2(db, "SELECT val FROM kv WHERE key = ?;",
-1, &stmt, NULL) == SQLITE_OK) {
sqlite3_bind_text(stmt, 1, key->p, key->len, SQLITE_STATIC);
result = sqlite3_step(stmt);
data = (char *) sqlite3_column_text(stmt, 0);
if ((result == SQLITE_OK || result == SQLITE_ROW) && data != NULL) {
mg_printf(nc, "HTTP/1.1 200 OK\r\n"
"Content-Type: text/plain\r\n"
"Content-Length: %d\r\n\r\n%s",
(int) strlen(data), data);
} else {
mg_printf(nc, "%s", "HTTP/1.1 404 Not Found\r\n"
"Content-Length: 0\r\n\r\n");
}
sqlite3_finalize(stmt);
} else {
mg_printf(nc, "%s", "HTTP/1.1 500 Server Error\r\n"
"Content-Length: 0\r\n\r\n");
}
}
static void op_del(struct mg_connection *nc, const struct http_message *hm,
const struct mg_str *key, void *db) {
sqlite3_stmt *stmt = NULL;
int result;
(void) hm;
if (sqlite3_prepare_v2(db, "DELETE FROM kv WHERE key = ?;",
-1, &stmt, NULL) == SQLITE_OK) {
sqlite3_bind_text(stmt, 1, key->p, key->len, SQLITE_STATIC);
result = sqlite3_step(stmt);
if (result == SQLITE_OK || result == SQLITE_ROW) {
mg_printf(nc, "%s", "HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n");
} else {
mg_printf(nc, "%s", "HTTP/1.1 404 Not Found\r\n"
"Content-Length: 0\r\n\r\n");
}
sqlite3_finalize(stmt);
} else {
mg_printf(nc, "%s", "HTTP/1.1 500 Server Error\r\n"
"Content-Length: 0\r\n\r\n");
}
}
void db_op(struct mg_connection *nc, const struct http_message *hm,
const struct mg_str *key, void *db, int op) {
switch (op) {
case API_OP_GET: op_get(nc, hm, key, db); break;
case API_OP_SET: op_set(nc, hm, key, db); break;
case API_OP_DEL: op_del(nc, hm, key, db); break;
default:
mg_printf(nc, "%s", "HTTP/1.0 501 Not Implemented\r\n"
"Content-Length: 0\r\n\r\n");
break;
}
}