initial commit
This commit is contained in:
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
.koka
|
||||||
|
.vscode
|
||||||
|
koka-test.sqlite3
|
||||||
27
README.md
Normal file
27
README.md
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
# sqlite
|
||||||
|
|
||||||
|
Koka binding for [SQLite3](https://www.sqlite.org/index.html).
|
||||||
|
|
||||||
|
This package uses the SQLite3 standard amalgamation, version 3.51.2.
|
||||||
|
The following compile-time options are enabled:
|
||||||
|
|
||||||
|
```
|
||||||
|
#define SQLITE_DQS 0
|
||||||
|
#define SQLITE_DEFAULT_MEMSTATUS 0
|
||||||
|
#define SQLITE_LIKE_DOESNT_MATCH_BLOBS
|
||||||
|
#define SQLITE_OMIT_AUTOINIT
|
||||||
|
#define SQLITE_STRICT_SUBTYPE 1
|
||||||
|
#define SQLITE_ENABLE_CARRAY
|
||||||
|
#define SQLITE_ENABLE_COLUMN_METADATA
|
||||||
|
#define SQLITE_ENABLE_DBSTAT_VTAB
|
||||||
|
#define SQLITE_ENABLE_FTS5
|
||||||
|
#define SQLITE_ENABLE_GEOPOLY
|
||||||
|
#define SQLITE_ENABLE_HIDDEN_COLUMNS
|
||||||
|
#define SQLITE_ENABLE_ICU
|
||||||
|
#define SQLITE_ENABLE_MATH_FUNCTIONS
|
||||||
|
#define SQLITE_ENABLE_NORMALIZE
|
||||||
|
#define SQLITE_ENABLE_PERCENTILE
|
||||||
|
#define SQLITE_ENABLE_RTREE
|
||||||
|
#define SQLITE_ENABLE_SESSION
|
||||||
|
#define SQLITE_SOUNDEX
|
||||||
|
```
|
||||||
49
sqlite/capi.kk
Normal file
49
sqlite/capi.kk
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
// Minimal SQLite3 C API wrapper.
|
||||||
|
// This module is for internal use and should not be used directly.
|
||||||
|
module sqlite/capi
|
||||||
|
|
||||||
|
pub import std/num/int32
|
||||||
|
|
||||||
|
extern import
|
||||||
|
c file "sqlite-define.c"
|
||||||
|
extern import
|
||||||
|
c file "sqlite3.c"
|
||||||
|
extern import
|
||||||
|
c file "sqlite-inline.c"
|
||||||
|
|
||||||
|
extern make-sqlite-ok(): int32
|
||||||
|
c inline "SQLITE_OK"
|
||||||
|
pub val int32/sqlite-ok: int32 = make-sqlite-ok()
|
||||||
|
|
||||||
|
pub extern initialize(): int32
|
||||||
|
c inline "sqlite3_initialize()"
|
||||||
|
|
||||||
|
pub extern shutdown(): int32
|
||||||
|
c inline "sqlite3_shutdown()"
|
||||||
|
|
||||||
|
pub extern errstr(x: int32): string
|
||||||
|
c "kk_sqlite3_errstr"
|
||||||
|
|
||||||
|
pub extern extended-errcode(^db: any): int32
|
||||||
|
c "kk_sqlite3_extended_errcode"
|
||||||
|
|
||||||
|
pub extern error-offset(^db: any): int
|
||||||
|
c "kk_sqlite3_error_offset"
|
||||||
|
|
||||||
|
pub extern open-v2(^filename: string, flags: int32, ^vfs: string): (any, int32)
|
||||||
|
c "kk_sqlite3_open_v2"
|
||||||
|
|
||||||
|
pub extern close(^db: any): int32
|
||||||
|
c "kk_sqlite3_close"
|
||||||
|
|
||||||
|
pub extern prepare-v3(^db: any, ^sql: sslice, flags: int32): (any, sslice, int32)
|
||||||
|
c "kk_sqlite3_prepare_v3"
|
||||||
|
|
||||||
|
pub extern finalize(^stmt: any): int32
|
||||||
|
c "kk_sqlite3_finalize"
|
||||||
|
|
||||||
|
pub extern step(^stmt: any): int32
|
||||||
|
c "kk_sqlite3_step"
|
||||||
|
|
||||||
|
pub extern reset(^stmt: any): int32
|
||||||
|
c "kk_sqlite3_reset"
|
||||||
20
sqlite/sqlite-define.c
Normal file
20
sqlite/sqlite-define.c
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
// Rather than requiring every importer to manage defines,
|
||||||
|
// set some here and include the SQLite3 amalgamation.
|
||||||
|
#define SQLITE_DQS 0
|
||||||
|
#define SQLITE_DEFAULT_MEMSTATUS 0
|
||||||
|
#define SQLITE_LIKE_DOESNT_MATCH_BLOBS
|
||||||
|
#define SQLITE_OMIT_AUTOINIT
|
||||||
|
#define SQLITE_STRICT_SUBTYPE 1
|
||||||
|
#define SQLITE_ENABLE_CARRAY
|
||||||
|
#define SQLITE_ENABLE_COLUMN_METADATA
|
||||||
|
#define SQLITE_ENABLE_DBSTAT_VTAB
|
||||||
|
#define SQLITE_ENABLE_FTS5
|
||||||
|
#define SQLITE_ENABLE_GEOPOLY
|
||||||
|
// #define SQLITE_ENABLE_HIDDEN_COLUMNS
|
||||||
|
// #define SQLITE_ENABLE_ICU
|
||||||
|
#define SQLITE_ENABLE_MATH_FUNCTIONS
|
||||||
|
#define SQLITE_ENABLE_NORMALIZE
|
||||||
|
#define SQLITE_ENABLE_PERCENTILE
|
||||||
|
#define SQLITE_ENABLE_RTREE
|
||||||
|
#define SQLITE_ENABLE_SESSION
|
||||||
|
#define SQLITE_SOUNDEX
|
||||||
83
sqlite/sqlite-inline.c
Normal file
83
sqlite/sqlite-inline.c
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
#include <kklib.h>
|
||||||
|
#include <sqlite3.h>
|
||||||
|
|
||||||
|
static inline sqlite3 *borrow_db(kk_box_t cref, kk_context_t *_ctx) {
|
||||||
|
return (sqlite3 *)kk_cptr_unbox_borrowed(cref, _ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
kk_string_t kk_sqlite3_errstr(int32_t x, kk_context_t *_ctx) {
|
||||||
|
const char *s = sqlite3_errstr((int)x);
|
||||||
|
if (s == NULL) {
|
||||||
|
return kk_string_empty();
|
||||||
|
}
|
||||||
|
return kk_string_alloc_from_utf8(s, _ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t kk_sqlite3_extended_errcode(kk_box_t cref, kk_context_t *_ctx) {
|
||||||
|
sqlite3 *db = borrow_db(cref, _ctx);
|
||||||
|
return (int32_t)sqlite3_extended_errcode(db);
|
||||||
|
}
|
||||||
|
|
||||||
|
kk_integer_t kk_sqlite3_error_offset(kk_box_t cref, kk_context_t *_ctx) {
|
||||||
|
sqlite3 *db = borrow_db(cref, _ctx);
|
||||||
|
int r = sqlite3_error_offset(db);
|
||||||
|
return kk_integer_from_int(r, _ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
kk_std_core_types__tuple2 kk_sqlite3_open_v2(kk_string_t filename, int32_t flags, kk_string_t vfs, kk_context_t *_ctx) {
|
||||||
|
kk_ssize_t vfs_len = 0;
|
||||||
|
const char *name = kk_string_cbuf_borrow(filename, NULL, _ctx);
|
||||||
|
const char *v = kk_string_cbuf_borrow(vfs, &vfs_len, _ctx);
|
||||||
|
sqlite3 *db = NULL;
|
||||||
|
int r = sqlite3_open_v2(name, &db, (int)flags, vfs_len != 0 ? v : NULL);
|
||||||
|
return kk_std_core_types__new_Tuple2(kk_box_box(kk_cptr_box(db, _ctx), _ctx), kk_int32_box((int32_t)r, _ctx), _ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t kk_sqlite3_close(kk_box_t cref, kk_context_t *_ctx) {
|
||||||
|
sqlite3 *db = borrow_db(cref, _ctx);
|
||||||
|
return (int32_t)sqlite3_close(db);
|
||||||
|
}
|
||||||
|
|
||||||
|
kk_std_core_types__tuple3 kk_sqlite3_prepare_v3(kk_box_t cref, kk_std_core_sslice__sslice sql, int32_t flags, kk_context_t *_ctx) {
|
||||||
|
kk_box_t fst, snd, thd;
|
||||||
|
sqlite3 *db = borrow_db(cref, _ctx);
|
||||||
|
|
||||||
|
kk_intx_t sql_start = kk_integer_clamp_borrow(sql.start, _ctx);
|
||||||
|
kk_intx_t sql_len = kk_integer_clamp_borrow(sql.len, _ctx);
|
||||||
|
// TODO(zephyr): instead of borrowing and then duping to construct left,
|
||||||
|
// check whether we can replace the reference
|
||||||
|
const char *sql_bytes = kk_string_cbuf_borrow(sql.str, NULL, _ctx) + sql_start;
|
||||||
|
|
||||||
|
sqlite3_stmt *stmt = NULL;
|
||||||
|
const char *left_bytes = NULL;
|
||||||
|
int r = sqlite3_prepare_v3(db, sql_bytes, (int)sql_len, flags, &stmt, &left_bytes);
|
||||||
|
|
||||||
|
kk_std_core_sslice__sslice left = {
|
||||||
|
.str = kk_string_dup(sql.str, _ctx),
|
||||||
|
.start = kk_integer_from_int(sql_start + (left_bytes - sql_bytes), _ctx),
|
||||||
|
.len = kk_integer_from_int(sql_len - (left_bytes - sql_bytes), _ctx),
|
||||||
|
};
|
||||||
|
fst = kk_box_box(kk_cptr_box(stmt, _ctx), _ctx);
|
||||||
|
snd = kk_std_core_sslice__sslice_box(left, _ctx);
|
||||||
|
thd = kk_int32_box((int32_t)r, _ctx);
|
||||||
|
return kk_std_core_types__new_Tuple3(fst, snd, thd, _ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline sqlite3_stmt *borrow_stmt(kk_box_t cref, kk_context_t *_ctx) {
|
||||||
|
return (sqlite3_stmt *)kk_cptr_unbox_borrowed(cref, _ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t kk_sqlite3_finalize(kk_box_t cref, kk_context_t *_ctx) {
|
||||||
|
sqlite3_stmt *stmt = borrow_stmt(cref, _ctx);
|
||||||
|
return (int32_t)sqlite3_finalize(stmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t kk_sqlite3_step(kk_box_t cref, kk_context_t *_ctx) {
|
||||||
|
sqlite3_stmt *stmt = borrow_stmt(cref, _ctx);
|
||||||
|
return (int32_t)sqlite3_step(stmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t kk_sqlite3_reset(kk_box_t cref, kk_context_t *_ctx) {
|
||||||
|
sqlite3_stmt *stmt = borrow_stmt(cref, _ctx);
|
||||||
|
return (int32_t)sqlite3_reset(stmt);
|
||||||
|
}
|
||||||
432
sqlite/sqlite-result.kk
Normal file
432
sqlite/sqlite-result.kk
Normal file
@@ -0,0 +1,432 @@
|
|||||||
|
module sqlite/sqlite-result
|
||||||
|
|
||||||
|
import sqlite/capi
|
||||||
|
|
||||||
|
// Result codes returned from SQLite3 C API routines.
|
||||||
|
pub type sqlite-result
|
||||||
|
Ok
|
||||||
|
Row
|
||||||
|
Done
|
||||||
|
Error-Code(code: sqlite-error, pos: int)
|
||||||
|
Ok-Load-Permanently
|
||||||
|
|
||||||
|
// Error result codes.
|
||||||
|
//
|
||||||
|
// The base variants correspond to the primary result codes.
|
||||||
|
// With the exception of `SQLITE_OK_LOAD_PERMANENTLY`, extended result codes
|
||||||
|
// are represented by an additional argument to the primary result code's constructor.
|
||||||
|
// All error codes carry the field for such arguments, even if there is no
|
||||||
|
// extended result code associated with it, so that wildcard pattern matches
|
||||||
|
// do not need to update if new extended result codes are added in the future.
|
||||||
|
pub type sqlite-error
|
||||||
|
Error(ext: maybe<ext-error>)
|
||||||
|
Internal(ext: maybe<ext-internal>)
|
||||||
|
Perm(ext: maybe<ext-perm>)
|
||||||
|
Abort(ext: maybe<ext-abort>)
|
||||||
|
Busy(ext: maybe<ext-busy>)
|
||||||
|
Locked(ext: maybe<ext-locked>)
|
||||||
|
No-Mem(ext: maybe<ext-no-mem>)
|
||||||
|
Read-Only(ext: maybe<ext-read-only>)
|
||||||
|
Interrupt(ext: maybe<ext-interrupt>)
|
||||||
|
IO-Err(ext: maybe<ext-io-err>)
|
||||||
|
Corrupt(ext: maybe<ext-corrupt>)
|
||||||
|
Not-Found(ext: maybe<ext-not-found>)
|
||||||
|
Full(ext: maybe<ext-full>)
|
||||||
|
Cant-Open(ext: maybe<ext-cant-open>)
|
||||||
|
Protocol(ext: maybe<ext-protocol>)
|
||||||
|
Schema(ext: maybe<ext-schema>)
|
||||||
|
Too-Big(ext: maybe<ext-too-big>)
|
||||||
|
Constraint(ext: maybe<ext-constraint>)
|
||||||
|
Mismatch(ext: maybe<ext-mismatch>)
|
||||||
|
Misuse(ext: maybe<ext-misuse>)
|
||||||
|
No-LFS(ext: maybe<ext-no-lfs>)
|
||||||
|
Auth(ext: maybe<ext-auth>)
|
||||||
|
Range(ext: maybe<ext-range>)
|
||||||
|
Not-A-DB(ext: maybe<ext-not-a-db>)
|
||||||
|
Notice(ext: maybe<ext-notice>)
|
||||||
|
Warning(ext: maybe<ext-warning>)
|
||||||
|
// Empty(ext: maybe<ext-empty>) // unused
|
||||||
|
// Format(ext: maybe<ext-format>) // unused
|
||||||
|
|
||||||
|
// Extended result codes for the `ERROR` primary result code.
|
||||||
|
pub type ext-error
|
||||||
|
Error-Missing-Coll-Seq
|
||||||
|
Error-Retry
|
||||||
|
Error-Snapshot
|
||||||
|
|
||||||
|
// Extended result codes for the `INTERNAL` primary result code.
|
||||||
|
pub type ext-internal
|
||||||
|
|
||||||
|
// Extended result codes for the `PERM` primary result code.
|
||||||
|
pub type ext-perm
|
||||||
|
|
||||||
|
// Extended result codes for the `ABORT` primary result code.
|
||||||
|
pub type ext-abort
|
||||||
|
Abort-Rollback
|
||||||
|
|
||||||
|
// Extended result codes for the `BUSY` primary result code.
|
||||||
|
pub type ext-busy
|
||||||
|
Busy-Recovery
|
||||||
|
Busy-Snapshot
|
||||||
|
Busy-Timeout
|
||||||
|
|
||||||
|
// Extended result codes for the `LOCKED` primary result code.
|
||||||
|
pub type ext-locked
|
||||||
|
Locked-Shared-Cache
|
||||||
|
Locked-VTab
|
||||||
|
|
||||||
|
// Extended result codes for the `NOMEM` primary result code.
|
||||||
|
pub type ext-no-mem
|
||||||
|
|
||||||
|
// Extended result codes for the `READONLY` primary result code.
|
||||||
|
pub type ext-read-only
|
||||||
|
Read-Only-Recovery
|
||||||
|
Read-Only-Cant-Lock
|
||||||
|
Read-Only-Rollback
|
||||||
|
Read-Only-DB-Moved
|
||||||
|
Read-Only-Cant-Init
|
||||||
|
Read-Only-Directory
|
||||||
|
|
||||||
|
// Extended result codes for the `INTERRUPT` primary result code.
|
||||||
|
pub type ext-interrupt
|
||||||
|
|
||||||
|
// Extended result codes for the `IOERR` primary result code.
|
||||||
|
pub type ext-io-err
|
||||||
|
IO-Err-Read
|
||||||
|
IO-Err-Short-Read
|
||||||
|
IO-Err-Write
|
||||||
|
IO-Err-Fsync
|
||||||
|
IO-Err-Dir-Fsync
|
||||||
|
IO-Err-Truncate
|
||||||
|
IO-Err-Fstat
|
||||||
|
IO-Err-Unlock
|
||||||
|
IO-Err-Read-Lock
|
||||||
|
IO-Err-Delete
|
||||||
|
IO-Err-No-Mem
|
||||||
|
IO-Err-Access
|
||||||
|
IO-Err-Check-Reserved-Lock
|
||||||
|
IO-Err-Lock
|
||||||
|
IO-Err-Close
|
||||||
|
IO-Err-Shm-Open
|
||||||
|
IO-Err-Shm-Size
|
||||||
|
IO-Err-Shm-Map
|
||||||
|
IO-Err-Seek
|
||||||
|
IO-Err-Delete-No-Ent
|
||||||
|
IO-Err-Mmap
|
||||||
|
IO-Err-Get-Temp-Path
|
||||||
|
IO-Err-Convpath
|
||||||
|
IO-Err-Vnode
|
||||||
|
IO-Err-Auth
|
||||||
|
IO-Err-Begin-Atomic
|
||||||
|
IO-Err-Commit-Atomic
|
||||||
|
IO-Err-Rollback-Atomic
|
||||||
|
IO-Err-Data
|
||||||
|
IO-Err-Corrupt-FS
|
||||||
|
// IO-Err-Blocked // unused
|
||||||
|
// IO-Err-Dir-Close // unused
|
||||||
|
// IO-Err-Shm-Lock // unused
|
||||||
|
|
||||||
|
// Extended result codes for the `CORRUPT` primary result code.
|
||||||
|
pub type ext-corrupt
|
||||||
|
Corrupt-Vtab
|
||||||
|
Corrupt-Sequence
|
||||||
|
Corrupt-Index
|
||||||
|
|
||||||
|
// Extended result codes for the `NOTFOUND` primary result code.
|
||||||
|
pub type ext-not-found
|
||||||
|
|
||||||
|
// Extended result codes for the `FULL` primary result code.
|
||||||
|
pub type ext-full
|
||||||
|
|
||||||
|
// Extended result codes for the `CANTOPEN` primary result code.
|
||||||
|
pub type ext-cant-open
|
||||||
|
Cant-Open-Isdir
|
||||||
|
Cant-Open-Fullpath
|
||||||
|
Cant-Open-Convpath
|
||||||
|
Cant-Open-DirtyWAL
|
||||||
|
Cant-Open-Symlink
|
||||||
|
// Cant-Open-Notempdir // unused
|
||||||
|
|
||||||
|
// Extended result codes for the `PROTOCOL` primary result code.
|
||||||
|
pub type ext-protocol
|
||||||
|
|
||||||
|
// Extended result codes for the `SCHEMA` primary result code.
|
||||||
|
pub type ext-schema
|
||||||
|
|
||||||
|
// Extended result codes for the `TOOBIG` primary result code.
|
||||||
|
pub type ext-too-big
|
||||||
|
|
||||||
|
// Extended result codes for the `CONSTRAINT` primary result code.
|
||||||
|
pub type ext-constraint
|
||||||
|
Constraint-Check
|
||||||
|
Constraint-Commithook
|
||||||
|
Constraint-Foreignkey
|
||||||
|
Constraint-Function
|
||||||
|
Constraint-Notnull
|
||||||
|
Constraint-Primarykey
|
||||||
|
Constraint-Trigger
|
||||||
|
Constraint-Unique
|
||||||
|
Constraint-VTab
|
||||||
|
Constraint-Rowid
|
||||||
|
Constraint-Pinned
|
||||||
|
Constraint-Datatype
|
||||||
|
|
||||||
|
// Extended result codes for the `MISMATCH` primary result code.
|
||||||
|
pub type ext-mismatch
|
||||||
|
|
||||||
|
// Extended result codes for the `MISUSE` primary result code.
|
||||||
|
pub type ext-misuse
|
||||||
|
|
||||||
|
// Extended result codes for the `NOLFS` primary result code.
|
||||||
|
pub type ext-no-lfs
|
||||||
|
|
||||||
|
// Extended result codes for the `AUTH` primary result code.
|
||||||
|
pub type ext-auth
|
||||||
|
Auth-User
|
||||||
|
|
||||||
|
// Extended result codes for the `RANGE` primary result code.
|
||||||
|
pub type ext-range
|
||||||
|
|
||||||
|
// Extended result codes for the `NOTADB` primary result code.
|
||||||
|
pub type ext-not-a-db
|
||||||
|
|
||||||
|
// Extended result codes for the `NOTICE` primary result code.
|
||||||
|
pub type ext-notice
|
||||||
|
Notice-Recover-WAL
|
||||||
|
Notice-Recover-Rollback
|
||||||
|
|
||||||
|
// Extended result codes for the `WARNING` primary result code.
|
||||||
|
pub type ext-warning
|
||||||
|
Warning-Autoindex
|
||||||
|
|
||||||
|
// Convert an SQLite3 result to its integer value.
|
||||||
|
pub fun int32(r: sqlite-result): int32
|
||||||
|
match r
|
||||||
|
Ok -> 0.int32
|
||||||
|
Row -> 100.int32
|
||||||
|
Done -> 101.int32
|
||||||
|
Error-Code(err, _) -> match err
|
||||||
|
Error(Nothing) -> 1.int32
|
||||||
|
Error(Just(Error-Missing-Coll-Seq)) -> 257.int32
|
||||||
|
Error(Just(Error-Retry)) -> 513.int32
|
||||||
|
Error(Just(Error-Snapshot)) -> 769.int32
|
||||||
|
Internal(_) -> 2.int32
|
||||||
|
Perm(_) -> 3.int32
|
||||||
|
Abort(Nothing) -> 4.int32
|
||||||
|
Abort(Just(Abort-Rollback)) -> 516.int32
|
||||||
|
Busy(Nothing) -> 5.int32
|
||||||
|
Busy(Just(Busy-Recovery)) -> 261.int32
|
||||||
|
Busy(Just(Busy-Snapshot)) -> 517.int32
|
||||||
|
Busy(Just(Busy-Timeout)) -> 773.int32
|
||||||
|
Locked(Nothing) -> 6.int32
|
||||||
|
Locked(Just(Locked-Shared-Cache)) -> 262.int32
|
||||||
|
Locked(Just(Locked-VTab)) -> 518.int32
|
||||||
|
No-Mem(_) -> 7.int32
|
||||||
|
Read-Only(Nothing) -> 8.int32
|
||||||
|
Read-Only(Just(Read-Only-Recovery)) -> 264.int32
|
||||||
|
Read-Only(Just(Read-Only-Cant-Lock)) -> 520.int32
|
||||||
|
Read-Only(Just(Read-Only-Rollback)) -> 776.int32
|
||||||
|
Read-Only(Just(Read-Only-DB-Moved)) -> 1032.int32
|
||||||
|
Read-Only(Just(Read-Only-Cant-Init)) -> 1288.int32
|
||||||
|
Read-Only(Just(Read-Only-Directory)) -> 1544.int32
|
||||||
|
Interrupt(_) -> 9.int32
|
||||||
|
IO-Err(Nothing) -> 10.int32
|
||||||
|
IO-Err(Just(IO-Err-Read)) -> 266.int32
|
||||||
|
IO-Err(Just(IO-Err-Short-Read)) -> 522.int32
|
||||||
|
IO-Err(Just(IO-Err-Write)) -> 778.int32
|
||||||
|
IO-Err(Just(IO-Err-Fsync)) -> 1034.int32
|
||||||
|
IO-Err(Just(IO-Err-Dir-Fsync)) -> 1290.int32
|
||||||
|
IO-Err(Just(IO-Err-Truncate)) -> 1546.int32
|
||||||
|
IO-Err(Just(IO-Err-Fstat)) -> 1802.int32
|
||||||
|
IO-Err(Just(IO-Err-Unlock)) -> 2058.int32
|
||||||
|
IO-Err(Just(IO-Err-Read-Lock)) -> 2314.int32
|
||||||
|
IO-Err(Just(IO-Err-Delete)) -> 2570.int32
|
||||||
|
IO-Err(Just(IO-Err-No-Mem)) -> 3082.int32
|
||||||
|
IO-Err(Just(IO-Err-Access)) -> 3338.int32
|
||||||
|
IO-Err(Just(IO-Err-Check-Reserved-Lock)) -> 3594.int32
|
||||||
|
IO-Err(Just(IO-Err-Lock)) -> 3850.int32
|
||||||
|
IO-Err(Just(IO-Err-Close)) -> 4106.int32
|
||||||
|
IO-Err(Just(IO-Err-Shm-Open)) -> 4618.int32
|
||||||
|
IO-Err(Just(IO-Err-Shm-Size)) -> 4874.int32
|
||||||
|
IO-Err(Just(IO-Err-Shm-Map)) -> 5386.int32
|
||||||
|
IO-Err(Just(IO-Err-Seek)) -> 5642.int32
|
||||||
|
IO-Err(Just(IO-Err-Delete-No-Ent)) -> 5898.int32
|
||||||
|
IO-Err(Just(IO-Err-Mmap)) -> 6154.int32
|
||||||
|
IO-Err(Just(IO-Err-Get-Temp-Path)) -> 6410.int32
|
||||||
|
IO-Err(Just(IO-Err-Convpath)) -> 6666.int32
|
||||||
|
IO-Err(Just(IO-Err-Vnode)) -> 6922.int32
|
||||||
|
IO-Err(Just(IO-Err-Auth)) -> 7178.int32
|
||||||
|
IO-Err(Just(IO-Err-Begin-Atomic)) -> 7434.int32
|
||||||
|
IO-Err(Just(IO-Err-Commit-Atomic)) -> 7690.int32
|
||||||
|
IO-Err(Just(IO-Err-Rollback-Atomic)) -> 7946.int32
|
||||||
|
IO-Err(Just(IO-Err-Data)) -> 8202.int32
|
||||||
|
IO-Err(Just(IO-Err-Corrupt-FS)) -> 8458.int32
|
||||||
|
Corrupt(Nothing) -> 11.int32
|
||||||
|
Corrupt(Just(Corrupt-Vtab)) -> 267.int32
|
||||||
|
Corrupt(Just(Corrupt-Sequence)) -> 523.int32
|
||||||
|
Corrupt(Just(Corrupt-Index)) -> 779.int32
|
||||||
|
Not-Found(_) -> 12.int32
|
||||||
|
Full(_) -> 13.int32
|
||||||
|
Cant-Open(Nothing) -> 14.int32
|
||||||
|
Cant-Open(Just(Cant-Open-Isdir)) -> 526.int32
|
||||||
|
Cant-Open(Just(Cant-Open-Fullpath)) -> 782.int32
|
||||||
|
Cant-Open(Just(Cant-Open-Convpath)) -> 1038.int32
|
||||||
|
Cant-Open(Just(Cant-Open-DirtyWAL)) -> 1294.int32
|
||||||
|
Cant-Open(Just(Cant-Open-Symlink)) -> 1550.int32
|
||||||
|
Protocol(_) -> 15.int32
|
||||||
|
Schema(_) -> 17.int32
|
||||||
|
Too-Big(_) -> 18.int32
|
||||||
|
Constraint(Nothing) -> 19.int32
|
||||||
|
Constraint(Just(Constraint-Check)) -> 275.int32
|
||||||
|
Constraint(Just(Constraint-Commithook)) -> 531.int32
|
||||||
|
Constraint(Just(Constraint-Foreignkey)) -> 787.int32
|
||||||
|
Constraint(Just(Constraint-Function)) -> 1043.int32
|
||||||
|
Constraint(Just(Constraint-Notnull)) -> 1299.int32
|
||||||
|
Constraint(Just(Constraint-Primarykey)) -> 1555.int32
|
||||||
|
Constraint(Just(Constraint-Trigger)) -> 1811.int32
|
||||||
|
Constraint(Just(Constraint-Unique)) -> 2067.int32
|
||||||
|
Constraint(Just(Constraint-VTab)) -> 2323.int32
|
||||||
|
Constraint(Just(Constraint-Rowid)) -> 2579.int32
|
||||||
|
Constraint(Just(Constraint-Pinned)) -> 2835.int32
|
||||||
|
Constraint(Just(Constraint-Datatype)) -> 3091.int32
|
||||||
|
Mismatch(_) -> 20.int32
|
||||||
|
Misuse(_) -> 21.int32
|
||||||
|
No-LFS(_) -> 21.int32
|
||||||
|
Auth(Nothing) -> 23.int32
|
||||||
|
Auth(Just(Auth-User)) -> 279.int32
|
||||||
|
Range(_) -> 25.int32
|
||||||
|
Not-A-DB(_) -> 26.int32
|
||||||
|
Notice(Nothing) -> 27.int32
|
||||||
|
Notice(Just(Notice-Recover-WAL)) -> 283.int32
|
||||||
|
Notice(Just(Notice-Recover-Rollback)) -> 539.int32
|
||||||
|
Warning(Nothing) -> 28.int32
|
||||||
|
Warning(Just(Warning-Autoindex)) -> 284.int32
|
||||||
|
Ok-Load-Permanently -> 256.int32
|
||||||
|
|
||||||
|
// Get the SQLite result corresponding to a result code from the C API.
|
||||||
|
// Throws an exception if `r` does not correspond to a valid result.
|
||||||
|
pub fun int32/sqlite-result(r: int32, pos: int = -1): exn sqlite-result
|
||||||
|
match r.int
|
||||||
|
0 -> Ok
|
||||||
|
256 -> Ok-Load-Permanently
|
||||||
|
1 -> Error-Code(Error(Nothing), pos)
|
||||||
|
257 -> Error-Code(Error(Just(Error-Missing-Coll-Seq)), pos)
|
||||||
|
513 -> Error-Code(Error(Just(Error-Retry)), pos)
|
||||||
|
769 -> Error-Code(Error(Just(Error-Snapshot)), pos)
|
||||||
|
2 -> Error-Code(Internal(Nothing), pos)
|
||||||
|
3 -> Error-Code(Perm(Nothing), pos)
|
||||||
|
4 -> Error-Code(Abort(Nothing), pos)
|
||||||
|
516 -> Error-Code(Abort(Just(Abort-Rollback)), pos)
|
||||||
|
5 -> Error-Code(Busy(Nothing), pos)
|
||||||
|
261 -> Error-Code(Busy(Just(Busy-Recovery)), pos)
|
||||||
|
517 -> Error-Code(Busy(Just(Busy-Snapshot)), pos)
|
||||||
|
773 -> Error-Code(Busy(Just(Busy-Timeout)), pos)
|
||||||
|
6 -> Error-Code(Locked(Nothing), pos)
|
||||||
|
262 -> Error-Code(Locked(Just(Locked-Shared-Cache)), pos)
|
||||||
|
518 -> Error-Code(Locked(Just(Locked-VTab)), pos)
|
||||||
|
7 -> Error-Code(No-Mem(Nothing), pos)
|
||||||
|
8 -> Error-Code(Read-Only(Nothing), pos)
|
||||||
|
264 -> Error-Code(Read-Only(Just(Read-Only-Recovery)), pos)
|
||||||
|
520 -> Error-Code(Read-Only(Just(Read-Only-Cant-Lock)), pos)
|
||||||
|
776 -> Error-Code(Read-Only(Just(Read-Only-Rollback)), pos)
|
||||||
|
1032 -> Error-Code(Read-Only(Just(Read-Only-DB-Moved)), pos)
|
||||||
|
1288 -> Error-Code(Read-Only(Just(Read-Only-Cant-Init)), pos)
|
||||||
|
1544 -> Error-Code(Read-Only(Just(Read-Only-Directory)), pos)
|
||||||
|
9 -> Error-Code(Interrupt(Nothing), pos)
|
||||||
|
10 -> Error-Code(IO-Err(Nothing), pos)
|
||||||
|
266 -> Error-Code(IO-Err(Just(IO-Err-Read)), pos)
|
||||||
|
522 -> Error-Code(IO-Err(Just(IO-Err-Short-Read)), pos)
|
||||||
|
778 -> Error-Code(IO-Err(Just(IO-Err-Write)), pos)
|
||||||
|
1034 -> Error-Code(IO-Err(Just(IO-Err-Fsync)), pos)
|
||||||
|
1290 -> Error-Code(IO-Err(Just(IO-Err-Dir-Fsync)), pos)
|
||||||
|
1546 -> Error-Code(IO-Err(Just(IO-Err-Truncate)), pos)
|
||||||
|
1802 -> Error-Code(IO-Err(Just(IO-Err-Fstat)), pos)
|
||||||
|
2058 -> Error-Code(IO-Err(Just(IO-Err-Unlock)), pos)
|
||||||
|
2314 -> Error-Code(IO-Err(Just(IO-Err-Read-Lock)), pos)
|
||||||
|
2570 -> Error-Code(IO-Err(Just(IO-Err-Delete)), pos)
|
||||||
|
3082 -> Error-Code(IO-Err(Just(IO-Err-No-Mem)), pos)
|
||||||
|
3338 -> Error-Code(IO-Err(Just(IO-Err-Access)), pos)
|
||||||
|
3594 -> Error-Code(IO-Err(Just(IO-Err-Check-Reserved-Lock)), pos)
|
||||||
|
3850 -> Error-Code(IO-Err(Just(IO-Err-Lock)), pos)
|
||||||
|
4106 -> Error-Code(IO-Err(Just(IO-Err-Close)), pos)
|
||||||
|
4618 -> Error-Code(IO-Err(Just(IO-Err-Shm-Open)), pos)
|
||||||
|
4874 -> Error-Code(IO-Err(Just(IO-Err-Shm-Size)), pos)
|
||||||
|
5386 -> Error-Code(IO-Err(Just(IO-Err-Shm-Map)), pos)
|
||||||
|
5642 -> Error-Code(IO-Err(Just(IO-Err-Seek)), pos)
|
||||||
|
5898 -> Error-Code(IO-Err(Just(IO-Err-Delete-No-Ent)), pos)
|
||||||
|
6154 -> Error-Code(IO-Err(Just(IO-Err-Mmap)), pos)
|
||||||
|
6410 -> Error-Code(IO-Err(Just(IO-Err-Get-Temp-Path)), pos)
|
||||||
|
6666 -> Error-Code(IO-Err(Just(IO-Err-Convpath)), pos)
|
||||||
|
6922 -> Error-Code(IO-Err(Just(IO-Err-Vnode)), pos)
|
||||||
|
7178 -> Error-Code(IO-Err(Just(IO-Err-Auth)), pos)
|
||||||
|
7434 -> Error-Code(IO-Err(Just(IO-Err-Begin-Atomic)), pos)
|
||||||
|
7690 -> Error-Code(IO-Err(Just(IO-Err-Commit-Atomic)), pos)
|
||||||
|
7946 -> Error-Code(IO-Err(Just(IO-Err-Rollback-Atomic)), pos)
|
||||||
|
8202 -> Error-Code(IO-Err(Just(IO-Err-Data)), pos)
|
||||||
|
8458 -> Error-Code(IO-Err(Just(IO-Err-Corrupt-FS)), pos)
|
||||||
|
11 -> Error-Code(Corrupt(Nothing), pos)
|
||||||
|
267 -> Error-Code(Corrupt(Just(Corrupt-Vtab)), pos)
|
||||||
|
523 -> Error-Code(Corrupt(Just(Corrupt-Sequence)), pos)
|
||||||
|
779 -> Error-Code(Corrupt(Just(Corrupt-Index)), pos)
|
||||||
|
12 -> Error-Code(Not-Found(Nothing), pos)
|
||||||
|
13 -> Error-Code(Full(Nothing), pos)
|
||||||
|
14 -> Error-Code(Cant-Open(Nothing), pos)
|
||||||
|
526 -> Error-Code(Cant-Open(Just(Cant-Open-Isdir)), pos)
|
||||||
|
782 -> Error-Code(Cant-Open(Just(Cant-Open-Fullpath)), pos)
|
||||||
|
1038 -> Error-Code(Cant-Open(Just(Cant-Open-Convpath)), pos)
|
||||||
|
1294 -> Error-Code(Cant-Open(Just(Cant-Open-DirtyWAL)), pos)
|
||||||
|
1550 -> Error-Code(Cant-Open(Just(Cant-Open-Symlink)), pos)
|
||||||
|
15 -> Error-Code(Protocol(Nothing), pos)
|
||||||
|
17 -> Error-Code(Schema(Nothing), pos)
|
||||||
|
18 -> Error-Code(Too-Big(Nothing), pos)
|
||||||
|
19 -> Error-Code(Constraint(Nothing), pos)
|
||||||
|
275 -> Error-Code(Constraint(Just(Constraint-Check)), pos)
|
||||||
|
531 -> Error-Code(Constraint(Just(Constraint-Commithook)), pos)
|
||||||
|
787 -> Error-Code(Constraint(Just(Constraint-Foreignkey)), pos)
|
||||||
|
1043 -> Error-Code(Constraint(Just(Constraint-Function)), pos)
|
||||||
|
1299 -> Error-Code(Constraint(Just(Constraint-Notnull)), pos)
|
||||||
|
1555 -> Error-Code(Constraint(Just(Constraint-Primarykey)), pos)
|
||||||
|
1811 -> Error-Code(Constraint(Just(Constraint-Trigger)), pos)
|
||||||
|
2067 -> Error-Code(Constraint(Just(Constraint-Unique)), pos)
|
||||||
|
2323 -> Error-Code(Constraint(Just(Constraint-VTab)), pos)
|
||||||
|
2579 -> Error-Code(Constraint(Just(Constraint-Rowid)), pos)
|
||||||
|
2835 -> Error-Code(Constraint(Just(Constraint-Pinned)), pos)
|
||||||
|
3091 -> Error-Code(Constraint(Just(Constraint-Datatype)), pos)
|
||||||
|
20 -> Error-Code(Mismatch(Nothing), pos)
|
||||||
|
21 -> Error-Code(Misuse(Nothing), pos)
|
||||||
|
21 -> Error-Code(No-LFS(Nothing), pos)
|
||||||
|
23 -> Error-Code(Auth(Nothing), pos)
|
||||||
|
279 -> Error-Code(Auth(Just(Auth-User)), pos)
|
||||||
|
25 -> Error-Code(Range(Nothing), pos)
|
||||||
|
26 -> Error-Code(Not-A-DB(Nothing), pos)
|
||||||
|
27 -> Error-Code(Notice(Nothing), pos)
|
||||||
|
283 -> Error-Code(Notice(Just(Notice-Recover-WAL)), pos)
|
||||||
|
539 -> Error-Code(Notice(Just(Notice-Recover-Rollback)), pos)
|
||||||
|
28 -> Error-Code(Warning(Nothing), pos)
|
||||||
|
284 -> Error-Code(Warning(Just(Warning-Autoindex)), pos)
|
||||||
|
100 -> Row
|
||||||
|
101 -> Done
|
||||||
|
v -> throw("invalid SQLite3 result code " ++ v.show, ExnRange)
|
||||||
|
|
||||||
|
// Convert an SQLite result to its corresponding primary result.
|
||||||
|
// E.g., `Constraint(Just(Constraint-Unique))` is converted to `Constraint(Nothing)`.
|
||||||
|
pub fun primary(r: sqlite-result): sqlite-result
|
||||||
|
match r
|
||||||
|
Error-Code(Error(Just(_)), pos) -> Error-Code(Error(Nothing), pos)
|
||||||
|
Error-Code(Abort(Just(_)), pos) -> Error-Code(Abort(Nothing), pos)
|
||||||
|
Error-Code(Busy(Just(_)), pos) -> Error-Code(Busy(Nothing), pos)
|
||||||
|
Error-Code(Locked(Just(_)), pos) -> Error-Code(Locked(Nothing), pos)
|
||||||
|
Error-Code(Read-Only(Just(_)), pos) -> Error-Code(Read-Only(Nothing), pos)
|
||||||
|
Error-Code(IO-Err(Just(_)), pos) -> Error-Code(IO-Err(Nothing), pos)
|
||||||
|
Error-Code(Corrupt(Just(_)), pos) -> Error-Code(Corrupt(Nothing), pos)
|
||||||
|
Error-Code(Cant-Open(Just(_)), pos) -> Error-Code(Cant-Open(Nothing), pos)
|
||||||
|
Error-Code(Constraint(Just(_)), pos) -> Error-Code(Constraint(Nothing), pos)
|
||||||
|
Error-Code(Auth(Just(_)), pos) -> Error-Code(Auth(Nothing), pos)
|
||||||
|
Error-Code(Notice(Just(_)), pos) -> Error-Code(Notice(Nothing), pos)
|
||||||
|
Error-Code(Warning(Just(_)), pos) -> Error-Code(Warning(Nothing), pos)
|
||||||
|
Ok-Load-Permanently -> Ok
|
||||||
|
r -> r
|
||||||
|
|
||||||
|
// Get the message corresponding to a result code.
|
||||||
|
pub fun show(r: sqlite-result): string
|
||||||
|
capi/errstr(r.int32)
|
||||||
265952
sqlite/sqlite3.c
Normal file
265952
sqlite/sqlite3.c
Normal file
File diff suppressed because it is too large
Load Diff
13968
sqlite/sqlite3.h
Normal file
13968
sqlite/sqlite3.h
Normal file
File diff suppressed because it is too large
Load Diff
116
sqlite/sqlite3.kk
Normal file
116
sqlite/sqlite3.kk
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
// Low level wrapper around a modern subset of the SQLite3 API.
|
||||||
|
//
|
||||||
|
// Using this module involves manual resource management.
|
||||||
|
//
|
||||||
|
module sqlite/sqlite3
|
||||||
|
|
||||||
|
import sqlite/capi
|
||||||
|
pub import sqlite/sqlite-result
|
||||||
|
|
||||||
|
// Helper to convert error codes returned directly from SQLite3 to the
|
||||||
|
// corresponding objects.
|
||||||
|
fun trusted-result(r: int32, pos: int = -1): sqlite-result
|
||||||
|
with final ctl throw-exn(exn) impossible(exn.message)
|
||||||
|
r.sqlite-result(pos)
|
||||||
|
|
||||||
|
// Database handle. An sqlite3 object is obtained by calling one of `open`,
|
||||||
|
// `open-existing`, or `read-only` and must be `close`d once all use is finished.
|
||||||
|
abstract struct sqlite3
|
||||||
|
cref: any
|
||||||
|
|
||||||
|
// Get the result code and position of the last operation.
|
||||||
|
pub fun last-result(db: sqlite3): sqlite-result
|
||||||
|
capi/extended-errcode(db.cref).trusted-result(capi/error-offset(db.cref))
|
||||||
|
|
||||||
|
///////////// System lifetime /////////////
|
||||||
|
|
||||||
|
// NOTE(zephyr): sqlite3/initialize has the qualifier on its name because
|
||||||
|
// type inference doesn't know whether to select this one or the capi function
|
||||||
|
// when constructing startup-initialized below, and there's no way to specify
|
||||||
|
// this one without the qualifier.
|
||||||
|
// This is probably a Koka bug.
|
||||||
|
|
||||||
|
// Initialize SQLite3.
|
||||||
|
// This function is automatically called during program initialization;
|
||||||
|
// see `startup-initialized`.
|
||||||
|
// If there is a call to `shutdown`, then there must be another call to
|
||||||
|
// `initialize` before the next use of any other SQLite3 function.
|
||||||
|
pub fun sqlite3/initialize(): sqlite-result
|
||||||
|
capi/initialize().trusted-result
|
||||||
|
|
||||||
|
// Release resources held by SQLite3.
|
||||||
|
// There must not be any `sqlite3` object which is not closed.
|
||||||
|
pub fun sqlite3/shutdown(): sqlite-result
|
||||||
|
capi/shutdown().trusted-result
|
||||||
|
|
||||||
|
// The result of initializing SQLite3 during program startup.
|
||||||
|
pub val startup-initialized = sqlite3/initialize()
|
||||||
|
|
||||||
|
///////////// Database lifetime /////////////
|
||||||
|
|
||||||
|
// Modes that can be used to name a database to be opened.
|
||||||
|
pub type db-name
|
||||||
|
Filename(path: string)
|
||||||
|
URI(uri: string)
|
||||||
|
Memory-Shared(name: string) // in-memory database with shared cache
|
||||||
|
Memory
|
||||||
|
|
||||||
|
// Synchronization modes in which to open a database.
|
||||||
|
pub type sync-mode
|
||||||
|
Single-Thread // No concurrent use is safe.
|
||||||
|
Multi-Thread // The database is thread-safe, but connections are not.
|
||||||
|
Serialized // The database and connections are always thread-safe.
|
||||||
|
|
||||||
|
fun open-raw(name: db-name, base-flags: int32, sync-mode: sync-mode, vfs: string): (sqlite3, sqlite-result)
|
||||||
|
val flags = match sync-mode
|
||||||
|
Single-Thread -> base-flags.or(0x02000000.i32) // | EXRESCODE
|
||||||
|
Multi-Thread -> base-flags.or(0x02008000.i32) // | EXRESCODE | NOMUTEX
|
||||||
|
Serialized -> base-flags.or(0x02010000.i32) // | EXRESCODE | FULLMUTEX
|
||||||
|
val (db, r) = match name
|
||||||
|
Filename(path) -> capi/open-v2(path, flags, vfs)
|
||||||
|
URI(uri) -> capi/open-v2(uri, flags.or(0x00000040.i32), vfs) // | URI
|
||||||
|
Memory-Shared(name) -> capi/open-v2("file:" ++ name ++ "?mode=memory&cache=shared", flags.or(0x000200C0.i32), vfs) // | URI | SHAREDCACHE | MEMORY
|
||||||
|
Memory -> capi/open-v2(":memory:", flags.or(0x00000080.i32), vfs) // | MEMORY
|
||||||
|
(Sqlite3(db), r.trusted-result)
|
||||||
|
|
||||||
|
// Open or create a database in read-write mode.
|
||||||
|
pub fun open(name: db-name, sync-mode: sync-mode = Serialized, vfs: string = ""): (sqlite3, sqlite-result)
|
||||||
|
open-raw(name, 6.i32, sync-mode, vfs)
|
||||||
|
|
||||||
|
// Open an existing database in read-write mode.
|
||||||
|
pub fun open-existing(name: db-name, sync-mode: sync-mode = Serialized, vfs: string = ""): (sqlite3, sqlite-result)
|
||||||
|
open-raw(name, 2.i32, sync-mode, vfs)
|
||||||
|
|
||||||
|
// Open a database in read-only mode.
|
||||||
|
pub fun read-only(name: db-name, sync-mode: sync-mode = Serialized, vfs: string = ""): (sqlite3, sqlite-result)
|
||||||
|
open-raw(name, 1.i32, sync-mode, vfs)
|
||||||
|
|
||||||
|
pub fun close(db: sqlite3): sqlite-result
|
||||||
|
capi/close(db.cref).trusted-result
|
||||||
|
|
||||||
|
///////////// Statements /////////////
|
||||||
|
|
||||||
|
// Prepared SQL statement.
|
||||||
|
// Corresponds to `sqlite3_stmt *` in the C API.
|
||||||
|
abstract struct statement
|
||||||
|
cref: any
|
||||||
|
|
||||||
|
pub fun prepare(db: sqlite3, sql: sslice, persistent: bool = False, disable-vtab: bool = False, disable-log: bool = False): either<sqlite-result, (statement, sslice)>
|
||||||
|
val flags = 0.i32
|
||||||
|
.or(persistent.int32 * 0x01.i32)
|
||||||
|
.or(disable-vtab.int32 * 0x04.i32)
|
||||||
|
.or(disable-log.int32 * 0x10.i32)
|
||||||
|
val (stmt, left, r) = capi/prepare-v3(db.cref, sql, flags)
|
||||||
|
if r == int32/sqlite-ok then
|
||||||
|
Right((Statement(stmt), left))
|
||||||
|
else
|
||||||
|
Left(r.trusted-result(capi/error-offset(db.cref)))
|
||||||
|
|
||||||
|
pub fun statement/finalize(stmt: statement): sqlite-result
|
||||||
|
capi/finalize(stmt.cref).trusted-result
|
||||||
|
|
||||||
|
pub fun statement/step(stmt: statement): sqlite-result
|
||||||
|
capi/step(stmt.cref).trusted-result
|
||||||
|
|
||||||
|
pub fun statement/reset(stmt: statement): sqlite-result
|
||||||
|
capi/reset(stmt.cref).trusted-result
|
||||||
17
test.nix.sh
Executable file
17
test.nix.sh
Executable file
@@ -0,0 +1,17 @@
|
|||||||
|
#!/usr/bin/env nix-shell
|
||||||
|
#! nix-shell -i bash --pure
|
||||||
|
#! nix-shell -p sqlite koka
|
||||||
|
#! nix-shell -I https://github.com/NixOS/nixpkgs/archive/e764fc9a405871f1f6ca3d1394fb422e0a0c3951.tar.gz
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
koka -e --ccincdir=./sqlite test/test.kk
|
||||||
|
|
||||||
|
RESULT=$(sqlite3 koka-test.sqlite3 'SELECT * FROM koka')
|
||||||
|
if [[ "$RESULT" != "value inserted from koka" ]]; then
|
||||||
|
echo "FAIL"
|
||||||
|
echo "want: value inserted from koka"
|
||||||
|
echo " got: $RESULT"
|
||||||
|
else
|
||||||
|
echo "PASS"
|
||||||
|
fi
|
||||||
27
test/test.kk
Normal file
27
test/test.kk
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
module test
|
||||||
|
|
||||||
|
import sqlite/sqlite3
|
||||||
|
|
||||||
|
// TODO(zephyr): For now, we're just doing a very basic test to estimate whether
|
||||||
|
// I'm doing Koka FFI correctly. An actual test suite would be excellent.
|
||||||
|
|
||||||
|
fun stmt(db: sqlite3, text: string)
|
||||||
|
println(text)
|
||||||
|
match db.prepare(text.slice)
|
||||||
|
Left(r-prep) -> println(" prepare result: " ++ r-prep.show)
|
||||||
|
Right((stmt, rest)) ->
|
||||||
|
println(" prepare remainder: " ++ rest.show)
|
||||||
|
val r-step = stmt.step
|
||||||
|
println(" step result: " ++ r-step.show)
|
||||||
|
val r-fin = stmt.finalize
|
||||||
|
println(" finalize result: " ++ r-fin.show)
|
||||||
|
|
||||||
|
pub fun main()
|
||||||
|
println("initialize result: " ++ startup-initialized.show)
|
||||||
|
val (db, r-open) = open(Filename("koka-test.sqlite3"))
|
||||||
|
println("open result: " ++ r-open.show)
|
||||||
|
stmt(db, "DROP TABLE IF EXISTS koka; -- reset previous test runs")
|
||||||
|
stmt(db, "CREATE TABLE koka(v TEXT NOT NULL)")
|
||||||
|
stmt(db, "INSERT INTO koka VALUES ('value inserted from koka');")
|
||||||
|
val r-close = db.close
|
||||||
|
println("close result: " ++ r-close.show)
|
||||||
Reference in New Issue
Block a user