summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Adam Chlipala <adamc@hcoop.net>2010-01-03 17:13:45 -0500
committerGravatar Adam Chlipala <adamc@hcoop.net>2010-01-03 17:13:45 -0500
commit85bd2c1f3750a8a918b93815e3550b462b113de5 (patch)
treec64216bacfaaad2793c146651100f3c289e5daf9
parent86bf1a00aacd96b4d32a1e1e88822a2201594926 (diff)
Database quotas
-rw-r--r--include/types.h1
-rw-r--r--include/urweb.h3
-rw-r--r--src/c/request.c3
-rw-r--r--src/c/urweb.c9
-rw-r--r--src/sqlite.sml40
5 files changed, 53 insertions, 3 deletions
diff --git a/include/types.h b/include/types.h
index 1c52d460..138760e5 100644
--- a/include/types.h
+++ b/include/types.h
@@ -3,6 +3,7 @@
#include <time.h>
#include <unistd.h>
+#include <stdint.h>
typedef long long uw_Basis_int;
typedef double uw_Basis_float;
diff --git a/include/urweb.h b/include/urweb.h
index d05e59ec..75239c62 100644
--- a/include/urweb.h
+++ b/include/urweb.h
@@ -40,6 +40,7 @@ int uw_rollback(uw_context);
__attribute__((noreturn)) void uw_error(uw_context, failure_kind, const char *fmt, ...);
char *uw_error_message(uw_context);
+void uw_set_error_message(uw_context, const char *);
void uw_push_cleanup(uw_context, void (*func)(void *), void *arg);
void uw_pop_cleanup(uw_context);
@@ -260,6 +261,8 @@ void uw_set_currentUrl(uw_context, char *);
extern size_t uw_messages_max, uw_clients_max, uw_headers_max, uw_page_max, uw_heap_max, uw_script_max;
extern size_t uw_inputs_max, uw_cleanup_max, uw_subinputs_max, uw_deltas_max, uw_transactionals_max, uw_globals_max;
+extern size_t uw_database_max;
+
extern int uw_time;
void uw_set_deadline(uw_context, int);
diff --git a/src/c/request.c b/src/c/request.c
index f190ec98..1a2c0a93 100644
--- a/src/c/request.c
+++ b/src/c/request.c
@@ -23,9 +23,10 @@ static int try_rollback(uw_context ctx, void *logger_data, uw_logger log_error)
if (r) {
log_error(logger_data, "Error running SQL ROLLBACK\n");
uw_reset(ctx);
- uw_write(ctx, "HTTP/1.1 500 Internal Server Error\n\r");
+ uw_write(ctx, "HTTP/1.1 500 Internal Server Error\r\n");
uw_write(ctx, "Content-type: text/plain\r\n\r\n");
uw_write(ctx, "Error running SQL ROLLBACK\n");
+ uw_set_error_message(ctx, "Database error; you are probably out of storage space.");
}
return r;
diff --git a/src/c/urweb.c b/src/c/urweb.c
index 27831011..79207abc 100644
--- a/src/c/urweb.c
+++ b/src/c/urweb.c
@@ -470,8 +470,6 @@ uw_context uw_init() {
ctx->needs_push = 0;
ctx->needs_sig = 0;
- ctx->error_message[0] = 0;
-
ctx->source_count = 0;
ctx->n_deltas = ctx->used_deltas = 0;
@@ -702,6 +700,11 @@ char *uw_error_message(uw_context ctx) {
return ctx->error_message;
}
+void uw_set_error_message(uw_context ctx, const char *msg) {
+ strncpy(ctx->error_message, msg, sizeof(ctx->error_message));
+ ctx->error_message[sizeof(ctx->error_message)-1] = 0;
+}
+
static input *INP(uw_context ctx) {
if (ctx->cur_container == NULL)
return ctx->inputs;
@@ -3359,3 +3362,5 @@ void uw_check_deadline(uw_context ctx) {
if (uw_time > ctx->deadline)
uw_error(ctx, FATAL, "Maximum running time exceeded");
}
+
+size_t uw_database_max = SIZE_MAX;
diff --git a/src/sqlite.sml b/src/sqlite.sml
index 485e43b4..593db22e 100644
--- a/src/sqlite.sml
+++ b/src/sqlite.sml
@@ -260,6 +260,8 @@ fun init {dbstring, prepared = ss, tables, views, sequences} =
newline,
string "sqlite3 *sqlite;",
newline,
+ string "sqlite3_stmt *stmt;",
+ newline,
string "uw_conn *conn;",
newline,
newline,
@@ -269,6 +271,44 @@ fun init {dbstring, prepared = ss, tables, views, sequences} =
string "\"Can't open SQLite database.\");",
newline,
newline,
+ string "if (uw_database_max < SIZE_MAX) {",
+ newline,
+ box [string "char buf[100];",
+ newline,
+ newline,
+
+ string "sprintf(buf, \"PRAGMA max_page_count = %llu\", (unsigned long long)(uw_database_max / 1024));",
+ newline,
+ newline,
+
+ string "if (sqlite3_prepare_v2(sqlite, buf, -1, &stmt, NULL) != SQLITE_OK) {",
+ newline,
+ box [string "sqlite3_close(sqlite);",
+ newline,
+ string "uw_error(ctx, FATAL, \"Can't prepare max_page_count query for SQLite database\");",
+ newline],
+ string "}",
+ newline,
+ newline,
+
+ string "if (sqlite3_step(stmt) != SQLITE_ROW) {",
+ newline,
+ box [string "sqlite3_finalize(stmt);",
+ newline,
+ string "sqlite3_close(sqlite);",
+ newline,
+ string "uw_error(ctx, FATAL, \"Can't set max_page_count parameter for SQLite database\");",
+ newline],
+ string "}",
+ newline,
+ newline,
+
+ string "sqlite3_finalize(stmt);",
+ newline],
+ string "}",
+ newline,
+ newline,
+
string "conn = calloc(1, sizeof(uw_conn));",
newline,
string "conn->conn = sqlite;",