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