From 5a7936bf1c9434117f4c6635c8e0016b7e93d07d Mon Sep 17 00:00:00 2001 From: Keith Bostic Date: Thu, 16 Feb 2012 13:22:03 -0500 Subject: [PATCH] Change the cursor open/close code to match other resources (RESOURCE structure that holds the WiredTiger resource). Change names to be consistent, open/XXX/close. Add cursor next call. --- c_src/wterl.c | 102 +++++++++++++++++++++++++++++++++++++------------- src/wterl.erl | 25 ++++++++++--- 2 files changed, 97 insertions(+), 30 deletions(-) diff --git a/c_src/wterl.c b/c_src/wterl.c index 8b06ed8..0b53689 100644 --- a/c_src/wterl.c +++ b/c_src/wterl.c @@ -41,6 +41,11 @@ typedef struct WT_SESSION* session; } wterl_session_handle; +typedef struct +{ + WT_CURSOR* cursor; +} wterl_cursor_handle; + typedef char TableName[128]; // Atoms (initialized in on_load) @@ -50,28 +55,30 @@ static ERL_NIF_TERM ATOM_OK; // Prototypes static ERL_NIF_TERM wterl_conn_open(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM wterl_conn_close(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); -static ERL_NIF_TERM wterl_session_new(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM wterl_session_open(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM wterl_session_get(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM wterl_session_put(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM wterl_session_delete(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM wterl_session_close(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM wterl_table_create(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM wterl_table_drop(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); -static ERL_NIF_TERM wterl_cursor_create(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM wterl_cursor_open(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM wterl_cursor_next(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM wterl_cursor_close(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ErlNifFunc nif_funcs[] = { {"conn_open", 2, wterl_conn_open}, {"conn_close", 1, wterl_conn_close}, - {"session_new", 1, wterl_session_new}, + {"session_open", 1, wterl_session_open}, {"session_get", 3, wterl_session_get}, {"session_put", 4, wterl_session_put}, {"session_delete", 3, wterl_session_delete}, {"session_close", 1, wterl_session_close}, {"table_create", 3, wterl_table_create}, {"table_drop", 3, wterl_table_drop}, - {"cursor_create", 2, wterl_cursor_create}, + {"cursor_open", 2, wterl_cursor_open}, + {"cursor_next", 1, wterl_cursor_next}, {"cursor_close", 1, wterl_cursor_close}, }; @@ -125,7 +132,7 @@ static ERL_NIF_TERM wterl_conn_close(ErlNifEnv* env, int argc, const ERL_NIF_TER return enif_make_badarg(env); } -static ERL_NIF_TERM wterl_session_new(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +static ERL_NIF_TERM wterl_session_open(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { wterl_conn_handle* conn_handle; if (enif_get_resource(env, argv[0], wterl_conn_RESOURCE, (void**)&conn_handle)) @@ -362,38 +369,83 @@ static ERL_NIF_TERM wterl_table_drop(ErlNifEnv* env, int argc, const ERL_NIF_TER return enif_make_badarg(env); } -static ERL_NIF_TERM wterl_cursor_create(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +static ERL_NIF_TERM wterl_cursor_open(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { wterl_session_handle* session_handle; if (enif_get_resource(env, argv[0], wterl_session_RESOURCE, (void**)&session_handle)) { - WT_SESSION* session = session_handle->session; - TableName table; + WT_SESSION* session = session_handle->session; + TableName table; + WT_CURSOR* cursor; if (enif_get_string(env, argv[1], table, sizeof table, ERL_NIF_LATIN1)) - { - WT_CURSOR* cursor; - int rc = session->open_cursor(session, table, NULL, "overwrite,raw", &cursor); - if (rc == 0) - { - ERL_NIF_TERM result = enif_make_resource(env, cursor); - return enif_make_tuple2(env, ATOM_OK, result); - } - else - { - return enif_make_tuple2(env, ATOM_ERROR, - enif_make_string(env, wiredtiger_strerror(rc), - ERL_NIF_LATIN1)); - } - } + { + int rc = session->open_cursor(session, table, NULL, "overwrite,raw", &cursor); + if (rc == 0) + { + wterl_cursor_handle* handle = enif_alloc_resource(wterl_cursor_RESOURCE, + sizeof(wterl_cursor_handle)); + handle->cursor = cursor; + ERL_NIF_TERM result = enif_make_resource(env, handle); + enif_keep_resource(session_handle); + enif_release_resource(handle); + return (enif_make_tuple2(env, ATOM_OK, result)); + } + else + { + return enif_make_tuple2(env, ATOM_ERROR, + enif_make_string(env, wiredtiger_strerror(rc), + ERL_NIF_LATIN1)); + } + } + } + return enif_make_badarg(env); +} + +static ERL_NIF_TERM wterl_cursor_next(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{ + wterl_cursor_handle *cursor_handle; + if (enif_get_resource(env, argv[0], wterl_cursor_RESOURCE, (void**)&cursor_handle)) + { + WT_CURSOR* cursor = cursor_handle->cursor; + int rc = cursor->next(cursor); + if (rc == 0) + { + WT_ITEM raw_value; + rc = cursor->get_value(cursor, &raw_value); + if (rc != 0) + { + return enif_make_tuple2(env, ATOM_ERROR, + enif_make_string(env, wiredtiger_strerror(rc), + ERL_NIF_LATIN1)); + } + ErlNifBinary value; + enif_alloc_binary(raw_value.size, &value); + memcpy(value.data, raw_value.data, raw_value.size); + return enif_make_tuple2(env, ATOM_OK, enif_make_binary(env, &value)); + } + else + { + if (rc == WT_NOTFOUND) + { + return enif_make_tuple2(env, ATOM_ERROR, enif_make_atom(env, "not_found")); + } + else + { + return enif_make_tuple2(env, ATOM_ERROR, + enif_make_string(env, wiredtiger_strerror(rc), + ERL_NIF_LATIN1)); + } + } } return enif_make_badarg(env); } static ERL_NIF_TERM wterl_cursor_close(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { - WT_CURSOR* cursor; - if (enif_get_resource(env, argv[1], wterl_cursor_RESOURCE, (void**)&cursor)) + wterl_cursor_handle *cursor_handle; + if (enif_get_resource(env, argv[0], wterl_cursor_RESOURCE, (void**)&cursor_handle)) { + WT_CURSOR* cursor = cursor_handle->cursor; int rc = cursor->close(cursor, NULL); if (rc == 0) { diff --git a/src/wterl.erl b/src/wterl.erl index 612ad58..64f8bb5 100644 --- a/src/wterl.erl +++ b/src/wterl.erl @@ -24,7 +24,7 @@ -export([conn_open/2, conn_close/1, - session_new/1, + session_open/1, session_get/3, session_put/4, session_delete/3, @@ -33,7 +33,8 @@ table_create/3, table_drop/2, table_drop/3, - cursor_create/2, + cursor_open/2, + cursor_next/1, cursor_close/1, config_to_bin/2]). @@ -64,7 +65,7 @@ conn_open(_HomeDir, _Config) -> conn_close(_ConnRef) -> ?nif_stub. -session_new(_ConnRef) -> +session_open(_ConnRef) -> ?nif_stub. session_get(_Ref, _Table, _Key) -> @@ -91,7 +92,10 @@ table_drop(Ref, Name) -> table_drop(_Ref, _Name, _Config) -> ?nif_stub. -cursor_create(_Ref, _Table) -> +cursor_open(_Ref, _Table) -> + ?nif_stub. + +cursor_next(_Cursor) -> ?nif_stub. cursor_close(_Cursor) -> @@ -162,12 +166,23 @@ basic_test() -> Opts = [{create, true}, {cache_size, "100MB"}], ok = filelib:ensure_dir(filename:join("/tmp/wterl.basic", "foo")), {ok, ConnRef} = conn_open("/tmp/wterl.basic", config_to_bin(Opts, [])), - {ok, SRef} = session_new(ConnRef), + {ok, SRef} = session_open(ConnRef), {ok, Table} = table_create(SRef, "table:test"), + ok = session_put(SRef, Table, <<"a">>, <<"apple">>), {ok, <<"apple">>} = session_get(SRef, Table, <<"a">>), ok = session_delete(SRef, Table, <<"a">>), {error, not_found} = session_get(SRef, Table, <<"a">>), + + {ok, Cursor} = cursor_open(SRef, Table), + ok = cursor_close(Cursor), + + ok = session_put(SRef, Table, <<"a">>, <<"apple">>), + {ok, Cursor} = cursor_open(SRef, Table), + {ok, <<"apple">>} = cursor_next(Cursor), + {error, not_found} = cursor_next(Cursor), + ok = cursor_close(Cursor), + ok = session_close(SRef), ok = conn_close(ConnRef).