The unified diff between revisions [1fb418de..] and [adff2b70..] is displayed below. It can also be downloaded as a raw diff.

#
# old_revision [1fb418de708909ffb7935500c5a31bba681e96b8]
# new_revision [adff2b70cc1870df9f9b4d736b855dffae74eca2]
#
# add_file "src/lsi/sql.c"
#  content [7aa3ffd7ec923fda9767e53f5c5102140106ef40]
# 
# add_file "src/lsi/sql.h"
#  content [b7cec772a92ef2c3d8a68a88d2977aa1a261c66d]
#
============================================================
--- /dev/null	
+++ src/lsi/sql.c	7aa3ffd7ec923fda9767e53f5c5102140106ef40
@@ -0,0 +1,99 @@
+/* sql.c */
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <err.h>
+#include <errno.h>
+#include <stdio.h>
+#include "sqlite3.h"
+#include "vm.h"
+
+sqlite3 *sql_db;
+int sql_initialised = 0;
+
+#define SQL_FILENAME ".lsdata"
+
+void sql_error(char *msg)
+{
+	fprintf(stderr, "sql error: %s: %s\n", msg, sqlite3_errmsg(sql_db));
+}
+
+int sql_init(void)
+{
+	if (sqlite3_open(SQL_FILENAME, &sql_db) != SQLITE_OK) {
+		sql_error("can't open sql database");
+		sql_initialised = 0;
+		return 0;
+	}
+
+	sql_initialised = 1;
+
+	return 1;
+}
+
+void sql_close(void)
+{
+	sqlite3_close(sql_db);
+	/*
+	 * XXX technically, this could return SQLITE_BUSY, which we ought
+	 * to deal with
+	 */
+	sql_initialised = 0;
+}
+
+/*
+ * We return 0 for failure, 1 for query with no rows, 2 for query with
+ * a valid return value.
+ */
+int sql_query(char *query, int qlen, int *result)
+{
+	sqlite3_stmt *stmt;
+	const char *ztail;
+	int done;
+	int rows;
+
+	if (!sql_initialised)
+	    return 0;
+
+	*result = 0;
+	done = 0;
+	rows = 0;
+
+	if (sqlite3_prepare_v2(sql_db, query, qlen, &stmt, &ztail)
+	    != SQLITE_OK) {
+		sql_error("error from sqlite3_prepare");
+		return 0;
+	}
+
+	while (1) {
+		int rv = sqlite3_step(stmt);
+
+		if (rv == SQLITE_DONE) {
+		    done = 1;
+		    break;
+		}
+		if (rv == SQLITE_ROW) {
+		    /* XXX we just deal with one return value for now */
+		    *result = sqlite3_column_int(stmt, 0);
+		    rows++;
+		    continue;
+		}
+		if (rv == SQLITE_OK)
+		    continue;
+		break;
+	}
+
+	if (!done) {
+		sql_error("error after sqlite3_step");
+	}
+	if (sqlite3_finalize(stmt) != SQLITE_OK) {
+		sql_error("error from sqlite3_finalize");
+		return 0;
+	}
+
+	if (done)
+		return (rows ? 2 : 1);
+
+	return 0;
+}
+
============================================================
--- /dev/null	
+++ src/lsi/sql.h	b7cec772a92ef2c3d8a68a88d2977aa1a261c66d
@@ -0,0 +1,5 @@
+/* sql.h */
+
+int sql_init(void);
+void sql_close(void);
+int sql_query(char *query, int qlen, int *result);