Merge branch 'master' of github.com:basho/wterl

This commit is contained in:
Steve Vinoski 2012-02-16 13:32:34 -05:00
commit 642da3a44c
3 changed files with 136 additions and 10 deletions

View file

@ -3,4 +3,4 @@ all:
./rebar compile eunit
clean:
./rebar clean
./rebar clean

View file

@ -29,6 +29,7 @@
static ErlNifResourceType* wterl_conn_RESOURCE;
static ErlNifResourceType* wterl_session_RESOURCE;
static ErlNifResourceType* wterl_cursor_RESOURCE;
typedef struct
{
@ -40,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)
@ -49,25 +55,31 @@ 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_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_open", 2, wterl_cursor_open},
{"cursor_next", 1, wterl_cursor_next},
{"cursor_close", 1, wterl_cursor_close},
};
@ -120,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))
@ -357,6 +369,98 @@ 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_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_CURSOR* cursor;
if (enif_get_string(env, argv[1], table, sizeof table, 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[])
{
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)
{
return ATOM_OK;
}
else
{
return enif_make_tuple2(env, ATOM_ERROR,
enif_make_string(env, wiredtiger_strerror(rc),
ERL_NIF_LATIN1));
}
}
return enif_make_badarg(env);
}
static void wterl_conn_resource_cleanup(ErlNifEnv* env, void* arg)
{
/* Delete any dynamically allocated memory stored in wterl_handle */

View file

@ -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,6 +33,9 @@
table_create/3,
table_drop/2,
table_drop/3,
cursor_open/2,
cursor_next/1,
cursor_close/1,
config_to_bin/2]).
-on_load(init/0).
@ -62,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) ->
@ -89,16 +92,24 @@ table_drop(Ref, Name) ->
table_drop(_Ref, _Name, _Config) ->
?nif_stub.
cursor_open(_Ref, _Table) ->
?nif_stub.
cursor_next(_Cursor) ->
?nif_stub.
cursor_close(_Cursor) ->
?nif_stub.
%%
%% Configuration type information.
%%
config_types() ->
[{cache_size, integer},
[{cache_size, string},
{create, bool},
{error_prefix, string},
{eviction_target, integer},
{eviction_trigger, integer},
{exclusive, false},
{extensions, string},
{hazard_max, integer},
{home_environment, bool},
@ -152,15 +163,26 @@ config_to_bin([{Key, Value} | Rest], Acc) ->
-ifdef(TEST).
basic_test() ->
Opts = [{create, true}],
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).