Commit Diff


commit - efbc6291524c83d55010c44b32b07eda0f06059e
commit + e84153de97a14dc5227b415cdd4577a044ec0b73
blob - /dev/null
blob + 0a7a7c5a753b4131d9718194754a7cc1ac97e78f (mode 644)
--- /dev/null
+++ sqlite3/errors.ha
@@ -0,0 +1,52 @@
+// This is free and unencumbered software released into the public domain.
+//
+// Anyone is free to copy, modify, publish, use, compile, sell, or
+// distribute this software, either in source code form or as a compiled
+// binary, for any purpose, commercial or non-commercial, and by any
+// means.
+//
+// In jurisdictions that recognize copyright laws, the author or authors
+// of this software dedicate any and all copyright interest in the
+// software to the public domain. We make this dedication for the benefit
+// of the public at large and to the detriment of our heirs and
+// successors. We intend this dedication to be an overt act of
+// relinquishment in perpetuity of all present and future rights to this
+// software under copyright law.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+
+def sqlite_ok: int = 0;
+def sqlite_row: int = 100;
+def sqlite_done: int = 101;
+
+export type sqlite_error = !void;
+export type sqlite_internal = !void;
+export type sqlite_perm = !void;
+export type sqlite_abort = !void;
+export type sqlite_busy = !void;
+export type sqlite_locked = !void;
+// ...
+export type sqlite_unknown_error = !void;
+
+export type unknown_parameter = !void;
+
+export type error = !(sqlite_error | sqlite_internal | sqlite_perm |
+			sqlite_abort | sqlite_busy | sqlite_locked |
+			sqlite_unknown_error);
+
+export fn strerror(err: error) str = {
+	return "";
+};
+
+fn code2err(code: int) error = {
+	switch (code) {
+	case 1 => return sqlite_error;
+	case => return sqlite_unknown_error;
+	};
+};
blob - /dev/null
blob + 9d2a989972eac004d8e9c43de1fa2e2dfa20ff4a (mode 644)
--- /dev/null
+++ sqlite3/sqlite3.ha
@@ -0,0 +1,246 @@
+// This is free and unencumbered software released into the public domain.
+//
+// Anyone is free to copy, modify, publish, use, compile, sell, or
+// distribute this software, either in source code form or as a compiled
+// binary, for any purpose, commercial or non-commercial, and by any
+// means.
+//
+// In jurisdictions that recognize copyright laws, the author or authors
+// of this software dedicate any and all copyright interest in the
+// software to the public domain. We make this dedication for the benefit
+// of the public at large and to the detriment of our heirs and
+// successors. We intend this dedication to be an overt act of
+// relinquishment in perpetuity of all present and future rights to this
+// software under copyright law.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+
+use strings;
+use types;
+use types::c;
+
+export type sqlite3 = *opaque;
+export type statement = *opaque;
+
+export def OPEN_READONLY:	int = 0x00000001;
+export def OPEN_READWRITE:	int = 0x00000002;
+export def OPEN_CREATE:		int = 0x00000004;
+export def OPEN_DELETEONCLOSE:	int = 0x00000008;	// VFS only
+export def OPEN_EXCLUSIVE:	int = 0x00000010;	// VFS only
+export def OPEN_AUTOPROXY:	int = 0x00000020;	// VFS only
+export def OPEN_URI:		int = 0x00000040;
+// ...
+export def OPEN_NOMUTEX:	int = 0x00008000;
+// ..
+export def OPEN_WAL:		int = 0x00080000;	// VFS only
+export def OPEN_NOFOLLOW:	int = 0x01000000;
+export def OPEN_EXRESCODE:	int = 0x02000000;
+
+export def def_open_flags = OPEN_READWRITE | OPEN_CREATE | OPEN_WAL |
+	OPEN_URI | OPEN_NOMUTEX;
+
+@symbol("sqlite3_open_v2") fn libsqlite3_open_v2(
+	filename: *const c::char,
+	sqlite3: *opaque,
+	flags: int,
+	vfs: nullable *const c::char,
+) int;
+
+// XXX vfs support?
+export fn open(filename: const str, flags: int...) (sqlite3 | error) = {
+	let f = if (len(flags) == 0) def_open_flags else flags[0];
+
+	let path = c::fromstr(filename);
+	defer free(path);
+
+	let addr: uintptr = 0;
+	let ret = libsqlite3_open_v2(path, &addr: *opaque, f, null);
+	if (ret == sqlite_ok) {
+		return (addr: *opaque): sqlite3;
+	};
+	return code2err(ret);
+};
+
+@symbol("sqlite3_close_v2") fn libsqlite3_close_v2(sqlite3: *opaque) int;
+
+export fn close(db: sqlite3) (void | error) = {
+	let ret = libsqlite3_close_v2(db: *opaque);
+	if (ret != sqlite_ok) {
+		return code2err(ret);
+	};
+};
+
+@symbol("sqlite3_prepare_v2") fn libsqlite3_prepare_v2(
+	sqlite3: *opaque,
+	sql: *const c::char,
+	nbyte: int,
+	stmt: *opaque,
+	tail: nullable *opaque,
+) int;
+
+export fn prepare(db: sqlite3, sql: const str) (statement | error) = {
+	let s = c::fromstr(sql);
+	defer free(s);
+
+	let stmt: uintptr = 0;
+	let ret = libsqlite3_prepare_v2(db: *opaque, s, -1, &stmt: *opaque,
+		null);
+	if (ret == sqlite_ok) {
+		return stmt: statement;
+	};
+	return code2err(ret);
+};
+
+// XXX missing
+// sqlite3_bind_blob
+// sqlite3_bind_blob64
+// sqlite3_bind_double
+
+@symbol("sqlite3_bind_parameter_index") fn libsqlite3_bind_parameter_index(
+	stmt: *opaque,
+	name: *const c::char,
+) int;
+
+fn bind_parameter_index(stmt: statement, col: (str | int)) (int | error) = {
+	let name = match (col) {
+	case let n: int => return n;
+	case let n: str => yield n;
+	};
+
+	let n = c::fromstr(name);
+	defer free(n);
+
+	let ret = libsqlite3_bind_parameter_index(stmt: *opaque, n);
+	if (ret == 0) {
+		return sqlite_error;
+	};
+
+	return ret;
+};
+
+@symbol("sqlite3_bind_int") fn libsqlite3_bind_int(
+	stmt: *opaque,
+	col: int,
+	val: int,
+) int;
+
+export fn bind_int(stmt: statement, col: (str | int), v: int) (void | error) = {
+	let n = bind_parameter_index(stmt, col)?;
+	let ret = libsqlite3_bind_int(stmt: *opaque, n, v);
+	if (ret != sqlite_ok) {
+		return code2err(ret);
+	};
+};
+
+@symbol("sqlite3_bind_null") fn libsqlite3_bind_null(
+	stmt: *opaque,
+	col: int,
+) int;
+
+export fn bind_null(stmt: statement, col: (str | int)) (void | error) = {
+	let n = bind_parameter_index(stmt, col)?;
+	let ret = libsqlite3_bind_null(stmt: *opaque, n);
+	if (ret != sqlite_ok) {
+		return code2err(ret);
+	};
+};
+
+fn freecstr(s: *opaque) void = free(s: *c::char);
+
+@symbol("sqlite3_bind_text") fn libsqlite3_bind_text(
+	stmt: *opaque,
+	col: int,
+	val: *const c::char,
+	bytelen: int,
+	freefn: *fn(*opaque) void
+) int;
+
+export fn bind_text(stmt: statement, col: (str | int), v: str) (void | error) = {
+	let n = bind_parameter_index(stmt, col)?;
+
+	let s = c::fromstr(v);
+	// free'd via the callback
+
+	let ret = libsqlite3_bind_text(stmt: *opaque, n, s, -1, &freecstr);
+	if (ret != sqlite_ok) {
+		return code2err(ret);
+	};
+};
+
+export fn bind(
+	stmt: statement,
+	col: (str | int),
+	val: (int | void | str),
+) (void | error) = {
+	match (val) {
+	case let v: int => return bind_int(stmt, col, v);
+	case let v: void => return bind_null(stmt, col);
+	case let v: str => return bind_text(stmt, col, v);
+	};
+};
+
+@symbol("sqlite3_step") fn libsqlite3_step(stmt: *opaque) int;
+
+export fn step(stmt: statement) (bool | error) = {
+	let ret = libsqlite3_step(stmt: *opaque);
+	switch (ret) {
+	case sqlite_row => return true;
+	case sqlite_done => return false;
+	case => return code2err(ret);
+	};
+};
+
+@symbol("sqlite3_column_text") fn libsqlite3_column_text(
+	stmt: *opaque,
+	col: int,
+) *const c::char;
+
+export fn column_text(stmt: statement, col: int) const str = {
+	let s = libsqlite3_column_text(stmt: *opaque, col);
+	if (s == null) {
+		return "";
+	};
+	return c::tostr_unsafe(s);
+};
+
+@symbol("sqlite3_column_int") fn libsqlite3_column_int(
+	stmt: *opaque,
+	col: int,
+) int;
+
+export fn column_int(stmt: statement, col: int) int = {
+	return libsqlite3_column_int(stmt: *opaque, col);
+};
+
+@symbol("sqlite3_finalize") fn libsqlite3_finalize(stmt: *opaque) int;
+
+export fn finalize(stmt: statement) (void | error) = {
+	let ret = libsqlite3_finalize(stmt: *opaque);
+	if (ret != sqlite_ok) {
+		return code2err(ret);
+	};
+};
+
+@symbol("sqlite3_reset") fn libsqlite3_reset(stmt: *opaque) int;
+
+export fn reset(stmt: statement) (void | error) = {
+	let ret = libsqlite3_reset(stmt: *opaque);
+	if (ret != sqlite_ok) {
+		return code2err(ret);
+	};
+};
+
+@symbol("sqlite3_clear_bindings") fn libsqlite3_clear_bindings(stmt: *opaque) int;
+
+export fn clear_bindings(stmt: statement) (void | error) = {
+	let ret = libsqlite3_clear_bindings(stmt: *opaque);
+	if (ret != sqlite_ok) {
+		return code2err(ret);
+	};
+};