14. opening a SQLite database in the monolith dictionary
This will use monolith_sqlite_open
, which is a function
stolen from an existing function which does the same thing,
but inside of graforge. I figured this functionality would
be more worthy of the shorter (and relevant) namespace.
14.1. C Function
<<static_sqlar_function_declarations>>=
sqlite3 * monolith_sqlite_open(monolith_d *m,
const char *fname,
const char *key,
size_t keylen);
<<sqlar_functions>>=
static void free_sqlite_entry(monolith_dict_entry *ent)
{
sqlite3 *db;
db = monolith_dict_entry_data(ent);
sqlite3_close(db);
}
sqlite3 * monolith_sqlite_open(monolith_d *m,
const char *fname,
const char *key,
size_t keylen)
{
sqlite3 *db;
monolith_dict *dict;
monolith_dict_entry *ent;
int rc;
dict = monolith_dict_get(m);
db = NULL;
rc = monolith_dict_newentry(dict, &ent,
key, keylen);
if (rc != MONOLITH_OK) {
fprintf(stderr, "Unable to create entry ");
fwrite(key, 1, keylen, stderr);
fprintf(stderr, "\n");
return NULL;
}
sqlite3_open(fname, &db);
monolith_dict_entry_data_set(ent, db);
monolith_dict_entry_clean(ent, free_sqlite_entry);
return db;
}
14.2. Scheme Function
Called with sqlar:sqlite-open
. This could be called
monolith:sqlite-open
, except that it's sort of a one-off
thing, and the loader is technically in the "sqlar"
namespace. If more general sqlite-related scheme
functions pop up in the future, it might make more
sense to put this in it's own set of functions.
<<sqlar_scheme_entries>>=
{"sqlar:sqlite-open", pp_sqlite_open, 2, 2, {STR,STR,___}},
<<sqlar_scheme_functions>>=
static cell pp_sqlite_open(cell x)
{
const char *file;
const char *name;
monolith_d *m;
m = monolith_data_get();
file = string(car(x));
x = cdr(x);
name = string(car(x));
monolith_sqlite_open(m, file, name, strlen(name));
return UNSPECIFIC;
}
14.3. Pushing SQLite database to runt stack via =monsqlite=
The monsqlite
word will look up the sqlite handle in
the monolith database and push it onto the stack.
<<monsqlite_word_entry>>=
runt_keyword_define(vm,
"monsqlite", 9,
rproc_monsqlite, &c);
runt_cell_data(vm, c, pw);
<<rproc_sqlite_open>>=
static runt_int rproc_monsqlite(runt_vm *vm, runt_ptr p)
{
sqlite3 *db;
int rc;
runt_stacklet *s;
const char *key;
monolith_dict *dict;
monolith_dict_entry *ent;
runt_ptr mp;
monolith_d *m;
rc = runt_ppop(vm, &s);
RUNT_ERROR_CHECK(rc);
key = runt_to_string(s->p);
if (key == NULL) {
runt_print(vm, "This probably wasn't a string\n");
return RUNT_NOT_OK;
}
rc = runt_data_search(vm, "__ml", &mp);
if(rc != RUNT_OK) {
runt_print(vm, "Could not find monolith.\n");
return RUNT_NOT_OK;
}
m = runt_to_cptr(mp);
dict = monolith_dict_get(m);
rc = monolith_dict_find(dict, &ent, key, strlen(key));
if (rc != MONOLITH_OK) {
runt_print(vm, "Could not find SQLite database\n");
return RUNT_NOT_OK;
}
db = monolith_dict_entry_data(ent);
if (db == NULL) {
runt_print(vm, "There was a problem opening the SQLite file\n");
return RUNT_NOT_OK;
}
rc = runt_ppush(vm, &s);
RUNT_ERROR_CHECK(rc);
rgf_stacklet_sqlite(vm, s, db);
return RUNT_OK;
}
prev | home | next