# HG changeset patch # User Adam Chlipala # Date 1262556825 18000 # Node ID 150465f2895c25239e9745575eb38f84d6544b8a # Parent 01b6c7144a444974fd089414d158b39341231dfe Database quotas diff -r 01b6c7144a44 -r 150465f2895c include/types.h --- a/include/types.h Sun Jan 03 15:58:34 2010 -0500 +++ b/include/types.h Sun Jan 03 17:13:45 2010 -0500 @@ -3,6 +3,7 @@ #include #include +#include typedef long long uw_Basis_int; typedef double uw_Basis_float; diff -r 01b6c7144a44 -r 150465f2895c include/urweb.h --- a/include/urweb.h Sun Jan 03 15:58:34 2010 -0500 +++ b/include/urweb.h Sun Jan 03 17:13:45 2010 -0500 @@ -40,6 +40,7 @@ __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 @@ 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 -r 01b6c7144a44 -r 150465f2895c src/c/request.c --- a/src/c/request.c Sun Jan 03 15:58:34 2010 -0500 +++ b/src/c/request.c Sun Jan 03 17:13:45 2010 -0500 @@ -23,9 +23,10 @@ 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 -r 01b6c7144a44 -r 150465f2895c src/c/urweb.c --- a/src/c/urweb.c Sun Jan 03 15:58:34 2010 -0500 +++ b/src/c/urweb.c Sun Jan 03 17:13:45 2010 -0500 @@ -470,8 +470,6 @@ 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 @@ 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 @@ if (uw_time > ctx->deadline) uw_error(ctx, FATAL, "Maximum running time exceeded"); } + +size_t uw_database_max = SIZE_MAX; diff -r 01b6c7144a44 -r 150465f2895c src/sqlite.sml --- a/src/sqlite.sml Sun Jan 03 15:58:34 2010 -0500 +++ b/src/sqlite.sml Sun Jan 03 17:13:45 2010 -0500 @@ -260,6 +260,8 @@ newline, string "sqlite3 *sqlite;", newline, + string "sqlite3_stmt *stmt;", + newline, string "uw_conn *conn;", newline, newline, @@ -269,6 +271,44 @@ 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;",