Merge branch 'master' of github.com:basho/wterl
This commit is contained in:
commit
642da3a44c
3 changed files with 136 additions and 10 deletions
2
Makefile
2
Makefile
|
@ -3,4 +3,4 @@ all:
|
||||||
./rebar compile eunit
|
./rebar compile eunit
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
./rebar clean
|
./rebar clean
|
||||||
|
|
110
c_src/wterl.c
110
c_src/wterl.c
|
@ -29,6 +29,7 @@
|
||||||
|
|
||||||
static ErlNifResourceType* wterl_conn_RESOURCE;
|
static ErlNifResourceType* wterl_conn_RESOURCE;
|
||||||
static ErlNifResourceType* wterl_session_RESOURCE;
|
static ErlNifResourceType* wterl_session_RESOURCE;
|
||||||
|
static ErlNifResourceType* wterl_cursor_RESOURCE;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -40,6 +41,11 @@ typedef struct
|
||||||
WT_SESSION* session;
|
WT_SESSION* session;
|
||||||
} wterl_session_handle;
|
} wterl_session_handle;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
WT_CURSOR* cursor;
|
||||||
|
} wterl_cursor_handle;
|
||||||
|
|
||||||
typedef char TableName[128];
|
typedef char TableName[128];
|
||||||
|
|
||||||
// Atoms (initialized in on_load)
|
// Atoms (initialized in on_load)
|
||||||
|
@ -49,25 +55,31 @@ static ERL_NIF_TERM ATOM_OK;
|
||||||
// Prototypes
|
// Prototypes
|
||||||
static ERL_NIF_TERM wterl_conn_open(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
|
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_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_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_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_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_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_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_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[] =
|
static ErlNifFunc nif_funcs[] =
|
||||||
{
|
{
|
||||||
{"conn_open", 2, wterl_conn_open},
|
{"conn_open", 2, wterl_conn_open},
|
||||||
{"conn_close", 1, wterl_conn_close},
|
{"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_get", 3, wterl_session_get},
|
||||||
{"session_put", 4, wterl_session_put},
|
{"session_put", 4, wterl_session_put},
|
||||||
{"session_delete", 3, wterl_session_delete},
|
{"session_delete", 3, wterl_session_delete},
|
||||||
{"session_close", 1, wterl_session_close},
|
{"session_close", 1, wterl_session_close},
|
||||||
{"table_create", 3, wterl_table_create},
|
{"table_create", 3, wterl_table_create},
|
||||||
{"table_drop", 3, wterl_table_drop},
|
{"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);
|
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;
|
wterl_conn_handle* conn_handle;
|
||||||
if (enif_get_resource(env, argv[0], wterl_conn_RESOURCE, (void**)&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);
|
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)
|
static void wterl_conn_resource_cleanup(ErlNifEnv* env, void* arg)
|
||||||
{
|
{
|
||||||
/* Delete any dynamically allocated memory stored in wterl_handle */
|
/* Delete any dynamically allocated memory stored in wterl_handle */
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
|
|
||||||
-export([conn_open/2,
|
-export([conn_open/2,
|
||||||
conn_close/1,
|
conn_close/1,
|
||||||
session_new/1,
|
session_open/1,
|
||||||
session_get/3,
|
session_get/3,
|
||||||
session_put/4,
|
session_put/4,
|
||||||
session_delete/3,
|
session_delete/3,
|
||||||
|
@ -33,6 +33,9 @@
|
||||||
table_create/3,
|
table_create/3,
|
||||||
table_drop/2,
|
table_drop/2,
|
||||||
table_drop/3,
|
table_drop/3,
|
||||||
|
cursor_open/2,
|
||||||
|
cursor_next/1,
|
||||||
|
cursor_close/1,
|
||||||
config_to_bin/2]).
|
config_to_bin/2]).
|
||||||
|
|
||||||
-on_load(init/0).
|
-on_load(init/0).
|
||||||
|
@ -62,7 +65,7 @@ conn_open(_HomeDir, _Config) ->
|
||||||
conn_close(_ConnRef) ->
|
conn_close(_ConnRef) ->
|
||||||
?nif_stub.
|
?nif_stub.
|
||||||
|
|
||||||
session_new(_ConnRef) ->
|
session_open(_ConnRef) ->
|
||||||
?nif_stub.
|
?nif_stub.
|
||||||
|
|
||||||
session_get(_Ref, _Table, _Key) ->
|
session_get(_Ref, _Table, _Key) ->
|
||||||
|
@ -89,16 +92,24 @@ table_drop(Ref, Name) ->
|
||||||
table_drop(_Ref, _Name, _Config) ->
|
table_drop(_Ref, _Name, _Config) ->
|
||||||
?nif_stub.
|
?nif_stub.
|
||||||
|
|
||||||
|
cursor_open(_Ref, _Table) ->
|
||||||
|
?nif_stub.
|
||||||
|
|
||||||
|
cursor_next(_Cursor) ->
|
||||||
|
?nif_stub.
|
||||||
|
|
||||||
|
cursor_close(_Cursor) ->
|
||||||
|
?nif_stub.
|
||||||
|
|
||||||
%%
|
%%
|
||||||
%% Configuration type information.
|
%% Configuration type information.
|
||||||
%%
|
%%
|
||||||
config_types() ->
|
config_types() ->
|
||||||
[{cache_size, integer},
|
[{cache_size, string},
|
||||||
{create, bool},
|
{create, bool},
|
||||||
{error_prefix, string},
|
{error_prefix, string},
|
||||||
{eviction_target, integer},
|
{eviction_target, integer},
|
||||||
{eviction_trigger, integer},
|
{eviction_trigger, integer},
|
||||||
{exclusive, false},
|
|
||||||
{extensions, string},
|
{extensions, string},
|
||||||
{hazard_max, integer},
|
{hazard_max, integer},
|
||||||
{home_environment, bool},
|
{home_environment, bool},
|
||||||
|
@ -152,15 +163,26 @@ config_to_bin([{Key, Value} | Rest], Acc) ->
|
||||||
-ifdef(TEST).
|
-ifdef(TEST).
|
||||||
|
|
||||||
basic_test() ->
|
basic_test() ->
|
||||||
Opts = [{create, true}],
|
Opts = [{create, true}, {cache_size, "100MB"}],
|
||||||
ok = filelib:ensure_dir(filename:join("/tmp/wterl.basic", "foo")),
|
ok = filelib:ensure_dir(filename:join("/tmp/wterl.basic", "foo")),
|
||||||
{ok, ConnRef} = conn_open("/tmp/wterl.basic", config_to_bin(Opts, [])),
|
{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, Table} = table_create(SRef, "table:test"),
|
||||||
|
|
||||||
ok = session_put(SRef, Table, <<"a">>, <<"apple">>),
|
ok = session_put(SRef, Table, <<"a">>, <<"apple">>),
|
||||||
{ok, <<"apple">>} = session_get(SRef, Table, <<"a">>),
|
{ok, <<"apple">>} = session_get(SRef, Table, <<"a">>),
|
||||||
ok = session_delete(SRef, Table, <<"a">>),
|
ok = session_delete(SRef, Table, <<"a">>),
|
||||||
{error, not_found} = session_get(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 = session_close(SRef),
|
||||||
ok = conn_close(ConnRef).
|
ok = conn_close(ConnRef).
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue