diff --git a/README b/README index e69de29..4cd2e33 100644 --- a/README +++ b/README @@ -0,0 +1 @@ +Work in progress.... \ No newline at end of file diff --git a/c_src/esqlite_nif.c b/c_src/esqlite_nif.c index f291ecb..90241f4 100644 --- a/c_src/esqlite_nif.c +++ b/c_src/esqlite_nif.c @@ -9,42 +9,75 @@ #define MAX_PATHNAME 512 /* unfortunately not in sqlite.h. */ +static ErlNifResourceType *esqlite_sqlite3_type = NULL; + static ERL_NIF_TERM _atom_ok; static ERL_NIF_TERM _atom_error; +typedef struct { + sqlite3 *db; +} esqlite_sqlite3; + +/* + */ +static void descruct_esqlite_sqlite3(ErlNifEnv *env, void *esqlite_db) +{ + /* The destructor should only be called after all the prepared statements are finalized... */ + /* TODO keep references, so this is the case */ + int rc; + + rc = sqlite3_close(((esqlite_sqlite3 *) esqlite_db)->db); + if(rc == SQLITE_BUSY) { + /* Can I raise exceptions here errors here? */ + fprintf(stderr, "Close failed, still busy\n"); + } +} + /* * Open database. Expects utf-8 input */ static ERL_NIF_TERM esqlite_open_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { - int rc; char filename[MAX_PATHNAME]; sqlite3 *db; + esqlite_sqlite3 *esqldb; + ERL_NIF_TERM esqlite_db; - /* TODO ignore the utf-8 stuff for now */ + /* TODO ignores the utf-8 stuff for now. nifs only encoding is latin1 */ if(!enif_get_string(env, argv[0], filename, MAX_PATHNAME, ERL_NIF_LATIN1)) return enif_make_badarg(env); - /* open the database */ - rc = sqlite3_open(filename, &db); - if( rc ) { + if(sqlite3_open(filename, &db)) { fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); - /* maak een error tuple */ + /* TODO maak een error tuple */ return enif_make_tuple2(env, _atom_error, _atom_error); /* todo add error message */ } - /* and wrap it in an erlang resource */ - fprintf(stderr, "The database is open.\n"); - sqlite3_close(db); - fprintf(stderr, "And closed\n"); - - return enif_make_tuple2(env, _atom_ok, _atom_ok); + esqldb = enif_alloc_resource(esqlite_sqlite3_type, sizeof(esqlite_sqlite3)); + esqldb->db = db; + esqlite_db = enif_make_resource(env, esqldb); + enif_release_resource(esqldb); + + return enif_make_tuple2(env, _atom_ok, esqlite_db); +} + +static ERL_NIF_TERM esqlite_prepare_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{ + + return enif_make_tuple2(env, _atom_ok, _atom_ok); } static int on_load(ErlNifEnv* env, void** priv, ERL_NIF_TERM info) { + ErlNifResourceType *rt = enif_open_resource_type(env, "esqlite", "esqlite_sqlite3_type", + descruct_esqlite_sqlite3, ERL_NIF_RT_CREATE, NULL); + if(!rt) + return -1; + + esqlite_sqlite3_type = rt; + _atom_ok = enif_make_atom(env, "ok"); _atom_error = enif_make_atom(env, "error"); @@ -54,6 +87,7 @@ static int on_load(ErlNifEnv* env, void** priv, ERL_NIF_TERM info) static ErlNifFunc nif_funcs[] = { {"open", 1, esqlite_open_nif}, + {"prepare", 2, esqlite_prepare_nif} }; ERL_NIF_INIT(esqlite, nif_funcs, on_load, NULL, NULL, NULL); diff --git a/src/esqlite.erl b/src/esqlite.erl index 09f8313..733ec1e 100644 --- a/src/esqlite.erl +++ b/src/esqlite.erl @@ -5,7 +5,7 @@ -module(esqlite). -author("Maas-Maarten Zeeman "). --export([open/1]). +-export([open/1, prepare/2]). -on_load(init/0). @@ -17,3 +17,6 @@ init() -> open(_Filename) -> exit(nif_library_not_loaded). +prepare(_Db, _Sql) -> + exit(nif_library_not_loaded). +