aboutsummaryrefslogtreecommitdiff
path: root/db.c
diff options
context:
space:
mode:
Diffstat (limited to 'db.c')
-rw-r--r--db.c137
1 files changed, 117 insertions, 20 deletions
diff --git a/db.c b/db.c
index ced02bf..cf75ec6 100644
--- a/db.c
+++ b/db.c
@@ -3,27 +3,95 @@
#include <stdio.h>
#include <string.h>
#include <sqlite3.h>
+#include <time.h>
#include "db.h"
-static char * textdup(const unsigned char *);
+static char * strdupn(const unsigned char *);
-sqlite3_stmt *
-byid(char *table, int id)
+/*
+ * The `add' functions insert an att/post/user struct into the database.
+ */
+int
+addatt(struct att *att)
{
- char sql[100];
sqlite3_stmt *stmt;
+
+ if(sqlite3_prepare(db, "INSERT INTO atts"
+ " (post, name, description, mime, data)"
+ " VALUES (?, ?, ?, ?, ?)",
+ -1, &stmt, 0) != SQLITE_OK)
+ goto err;
- snprintf(sql, 100, "SELECT oid, * FROM %s WHERE oid = ?", table);
+ if(sqlite3_bind_int(stmt, 1, att->post)
+ != SQLITE_OK)
+ goto err;
- if(sqlite3_prepare(db, sql, -1, &stmt, 0) != SQLITE_OK)
- return NULL;
-
- if(sqlite3_bind_int(stmt, 1, id) != SQLITE_OK)
- return NULL;
+ if(sqlite3_bind_text(stmt, 2, att->name, -1, SQLITE_STATIC)
+ != SQLITE_OK)
+ goto err;
- return stmt;
+ if(sqlite3_bind_text(stmt, 3, att->description, -1, SQLITE_STATIC)
+ != SQLITE_OK)
+ goto err;
+
+ if(sqlite3_bind_text(stmt, 4, att->mime, -1, SQLITE_STATIC)
+ != SQLITE_OK)
+ goto err;
+
+ if(sqlite3_bind_blob(stmt, 5, att->data, att->bytes, SQLITE_STATIC)
+ != SQLITE_OK)
+ goto err;
+
+ if(sqlite3_step(stmt) != SQLITE_DONE)
+ goto err;
+
+ sqlite3_finalize(stmt);
+ return 1;
+err:
+ sqlite3_finalize(stmt);
+ return 0;
}
+int
+adduser(struct user *user)
+{
+ sqlite3_stmt *stmt;
+
+ if(sqlite3_prepare(db, "INSERT INTO users"
+ " (name, full, hash, created)"
+ " VALUES (?, ?, ?, ?)",
+ -1, &stmt, 0) != SQLITE_OK)
+ goto err;
+
+ if(sqlite3_bind_text(stmt, 1, user->name, -1, SQLITE_STATIC)
+ != SQLITE_OK)
+ goto err;
+
+ if(sqlite3_bind_text(stmt, 2, user->full, -1, SQLITE_STATIC)
+ != SQLITE_OK)
+ goto err;
+
+ if(sqlite3_bind_text(stmt, 3, user->hash, -1, SQLITE_STATIC)
+ != SQLITE_OK)
+ goto err;
+
+ if(sqlite3_bind_int(stmt, 4, time(NULL)) != SQLITE_OK)
+ goto err;
+
+ if(sqlite3_step(stmt) != SQLITE_DONE)
+ goto err;
+
+ sqlite3_finalize(stmt);
+ return 1;
+err:
+ sqlite3_finalize(stmt);
+ return 0;
+}
+
+/*
+ * The `get' functions retrieve an att/post/user struct once,
+ * after which the statement is automatically finalized.
+ */
struct att *
getatt(sqlite3_stmt *stmt)
{
@@ -51,6 +119,11 @@ getuser(sqlite3_stmt *stmt)
return user;
}
+/*
+ * The `next' functions create an att/post/user struct by querying
+ * the database with the given stmt. They may be called multiple times
+ * with the same stmt to retrieve multiple rows.
+ */
struct att *
nextatt(sqlite3_stmt *stmt)
{
@@ -67,9 +140,9 @@ nextatt(sqlite3_stmt *stmt)
att->id = sqlite3_column_int(stmt, 0);
att->post = sqlite3_column_int(stmt, 1);
- att->name = textdup(sqlite3_column_text(stmt, 2));
- att->description = textdup(sqlite3_column_text(stmt, 3));
- att->mime = textdup(sqlite3_column_text(stmt, 4));
+ att->name = strdupn(sqlite3_column_text(stmt, 2));
+ att->description = strdupn(sqlite3_column_text(stmt, 3));
+ att->mime = strdupn(sqlite3_column_text(stmt, 4));
att->bytes = sqlite3_column_bytes(stmt, 5);
if(!(att->data = malloc(att->bytes)))
@@ -99,8 +172,8 @@ nextpost(sqlite3_stmt *stmt)
post->user = sqlite3_column_int(stmt, 2);
post->created = sqlite3_column_int(stmt, 3);
post->edited = sqlite3_column_int(stmt, 4);
- post->subject = textdup(sqlite3_column_text(stmt, 5));
- post->text = textdup(sqlite3_column_text(stmt, 6));
+ post->subject = strdupn(sqlite3_column_text(stmt, 5));
+ post->text = strdupn(sqlite3_column_text(stmt, 6));
return post;
}
@@ -120,15 +193,39 @@ nextuser(sqlite3_stmt *stmt)
err(1, "malloc");
user->id = sqlite3_column_int(stmt, 0);
- user->name = textdup(sqlite3_column_text(stmt, 1));
- user->full = textdup(sqlite3_column_text(stmt, 2));
- user->hash = textdup(sqlite3_column_text(stmt, 3));
+ user->name = strdupn(sqlite3_column_text(stmt, 1));
+ user->full = strdupn(sqlite3_column_text(stmt, 2));
+ user->hash = strdupn(sqlite3_column_text(stmt, 3));
+ user->created = sqlite3_column_int(stmt, 4);
return user;
}
+/*
+ * Create a statement that selects from a given table on a given integer.
+ * The returned statement must eventually be finalized by calling
+ * sqlite3_finalize(sqlite3_stmt *).
+ */
+sqlite3_stmt *
+selectbyint(char *table, char *field, int i)
+{
+ char sql[100];
+ sqlite3_stmt *stmt;
+
+ snprintf(sql, 100, "SELECT oid, * FROM %s WHERE %s = ?", table, field);
+
+ if(sqlite3_prepare(db, sql, -1, &stmt, 0) != SQLITE_OK)
+ return NULL;
+
+ if(sqlite3_bind_int(stmt, 1, i) != SQLITE_OK)
+ return NULL;
+
+ return stmt;
+}
+
+/* Return an allocated copy of string unless NULL. */
char *
-textdup(const unsigned char *s)
+strdupn(const unsigned char *s)
{
return s? strdup((char *)s): NULL;
} \ No newline at end of file