changeset 1115:150465f2895c

Database quotas
author Adam Chlipala <adamc@hcoop.net>
date Sun, 03 Jan 2010 17:13:45 -0500 (2010-01-03)
parents 01b6c7144a44
children ce56795b2e5f
files include/types.h include/urweb.h src/c/request.c src/c/urweb.c src/sqlite.sml
diffstat 5 files changed, 53 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- 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 <time.h>
 #include <unistd.h>
+#include <stdint.h>
 
 typedef long long uw_Basis_int;
 typedef double uw_Basis_float;
--- 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);
--- 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;
--- 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;
--- 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;",