more WiredTiger prototyping
A number of changes: * Added exported functions to close connections and sessions. * Added exported functions to create and drop tables. Currently not happy with the shape of these functions, though, as they treat tables in Erlang just as strings, and they force users of sessions to have to pass both sessions and tables into get/put/delete operations. It might be better to take a table identifier as part of the session creation function and store that identifier with the session resource. * Added implementations for key-value get, put, and delete. * Added very minimal unit tests for the changes above.
This commit is contained in:
parent
dcb4270f9d
commit
b93946a5e0
2 changed files with 271 additions and 21 deletions
244
c_src/wterl.c
244
c_src/wterl.c
|
@ -39,23 +39,34 @@ typedef struct
|
|||
WT_SESSION* session;
|
||||
} wterl_session_handle;
|
||||
|
||||
typedef char TableName[128];
|
||||
|
||||
// Atoms (initialized in on_load)
|
||||
static ERL_NIF_TERM ATOM_ERROR;
|
||||
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_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 ErlNifFunc nif_funcs[] =
|
||||
{
|
||||
{"conn_open", 2, wterl_conn_open},
|
||||
{"conn_close", 1, wterl_conn_close},
|
||||
{"session_new", 1, wterl_session_new},
|
||||
{"session_get", 2, wterl_session_get},
|
||||
{"session_put", 3, wterl_session_put},
|
||||
{"session_delete", 2, wterl_session_delete}
|
||||
{"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},
|
||||
};
|
||||
|
||||
|
||||
|
@ -63,7 +74,7 @@ static ERL_NIF_TERM wterl_conn_open(ErlNifEnv* env, int argc, const ERL_NIF_TERM
|
|||
{
|
||||
char homedir[4096];
|
||||
ErlNifBinary configBin;
|
||||
if (enif_get_string(env, argv[0], homedir, sizeof(homedir), ERL_NIF_LATIN1) &&
|
||||
if (enif_get_string(env, argv[0], homedir, sizeof homedir, ERL_NIF_LATIN1) &&
|
||||
enif_inspect_binary(env, argv[1], &configBin))
|
||||
{
|
||||
WT_CONNECTION* conn;
|
||||
|
@ -75,7 +86,7 @@ static ERL_NIF_TERM wterl_conn_open(ErlNifEnv* env, int argc, const ERL_NIF_TERM
|
|||
handle->conn = conn;
|
||||
ERL_NIF_TERM result = enif_make_resource(env, handle);
|
||||
enif_release_resource(handle);
|
||||
return enif_make_tuple2(env, enif_make_atom(env, "ok"), result);
|
||||
return enif_make_tuple2(env, ATOM_OK, result);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -88,7 +99,24 @@ static ERL_NIF_TERM wterl_conn_open(ErlNifEnv* env, int argc, const ERL_NIF_TERM
|
|||
{
|
||||
return enif_make_badarg(env);
|
||||
}
|
||||
}
|
||||
|
||||
static ERL_NIF_TERM wterl_conn_close(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))
|
||||
{
|
||||
WT_CONNECTION* conn = conn_handle->conn;
|
||||
int rc = conn->close(conn, NULL);
|
||||
if (rc != 0)
|
||||
{
|
||||
return enif_make_tuple2(env, ATOM_ERROR,
|
||||
enif_make_string(env, wiredtiger_strerror(rc),
|
||||
ERL_NIF_LATIN1));
|
||||
}
|
||||
return ATOM_OK;
|
||||
}
|
||||
return enif_make_badarg(env);
|
||||
}
|
||||
|
||||
static ERL_NIF_TERM wterl_session_new(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
|
||||
|
@ -107,7 +135,7 @@ static ERL_NIF_TERM wterl_session_new(ErlNifEnv* env, int argc, const ERL_NIF_TE
|
|||
ERL_NIF_TERM result = enif_make_resource(env, shandle);
|
||||
enif_keep_resource(conn_handle);
|
||||
enif_release_resource(shandle);
|
||||
return enif_make_tuple2(env, enif_make_atom(env, "ok"), result);
|
||||
return enif_make_tuple2(env, ATOM_OK, result);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -116,25 +144,216 @@ static ERL_NIF_TERM wterl_session_new(ErlNifEnv* env, int argc, const ERL_NIF_TE
|
|||
ERL_NIF_LATIN1));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return enif_make_badarg(env);
|
||||
}
|
||||
}
|
||||
|
||||
static ERL_NIF_TERM wterl_session_get(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
|
||||
{
|
||||
return enif_make_atom(env, "ok");
|
||||
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;
|
||||
ErlNifBinary key;
|
||||
if (enif_get_string(env, argv[1], table, sizeof table, ERL_NIF_LATIN1) &&
|
||||
enif_inspect_binary(env, argv[2], &key))
|
||||
{
|
||||
WT_CURSOR* cursor;
|
||||
int rc = session->open_cursor(session, table, NULL, "overwrite,raw", &cursor);
|
||||
if (rc != 0)
|
||||
{
|
||||
return enif_make_tuple2(env, ATOM_ERROR,
|
||||
enif_make_string(env, wiredtiger_strerror(rc),
|
||||
ERL_NIF_LATIN1));
|
||||
}
|
||||
WT_ITEM raw_key;
|
||||
raw_key.data = key.data;
|
||||
raw_key.size = key.size;
|
||||
cursor->set_key(cursor, &raw_key);
|
||||
rc = cursor->search(cursor);
|
||||
if (rc == 0)
|
||||
{
|
||||
WT_ITEM raw_value;
|
||||
rc = cursor->get_value(cursor, &raw_value);
|
||||
cursor->close(cursor, NULL);
|
||||
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
|
||||
{
|
||||
cursor->close(cursor, NULL);
|
||||
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_session_put(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
|
||||
{
|
||||
return enif_make_atom(env, "ok");
|
||||
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;
|
||||
ErlNifBinary key, value;
|
||||
if (enif_get_string(env, argv[1], table, sizeof table, ERL_NIF_LATIN1) &&
|
||||
enif_inspect_binary(env, argv[2], &key) && enif_inspect_binary(env, argv[3], &value))
|
||||
{
|
||||
WT_CURSOR* cursor;
|
||||
int rc = session->open_cursor(session, table, NULL, "overwrite,raw", &cursor);
|
||||
if (rc != 0)
|
||||
{
|
||||
return enif_make_tuple2(env, ATOM_ERROR,
|
||||
enif_make_string(env, wiredtiger_strerror(rc),
|
||||
ERL_NIF_LATIN1));
|
||||
}
|
||||
WT_ITEM raw_key, raw_value;
|
||||
raw_key.data = key.data;
|
||||
raw_key.size = key.size;
|
||||
cursor->set_key(cursor, &raw_key);
|
||||
raw_value.data = value.data;
|
||||
raw_value.size = value.size;
|
||||
cursor->set_value(cursor, &raw_value);
|
||||
rc = cursor->insert(cursor);
|
||||
cursor->close(cursor, NULL);
|
||||
if (rc != 0)
|
||||
{
|
||||
return enif_make_tuple2(env, ATOM_ERROR,
|
||||
enif_make_string(env, wiredtiger_strerror(rc),
|
||||
ERL_NIF_LATIN1));
|
||||
}
|
||||
return ATOM_OK;
|
||||
}
|
||||
}
|
||||
return enif_make_badarg(env);
|
||||
}
|
||||
|
||||
static ERL_NIF_TERM wterl_session_delete(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
|
||||
{
|
||||
return enif_make_atom(env, "ok");
|
||||
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;
|
||||
ErlNifBinary key;
|
||||
if (enif_get_string(env, argv[1], table, sizeof table, ERL_NIF_LATIN1) &&
|
||||
enif_inspect_binary(env, argv[2], &key))
|
||||
{
|
||||
WT_CURSOR* cursor;
|
||||
int rc = session->open_cursor(session, table, NULL, "raw", &cursor);
|
||||
if (rc != 0)
|
||||
{
|
||||
return enif_make_tuple2(env, ATOM_ERROR,
|
||||
enif_make_string(env, wiredtiger_strerror(rc),
|
||||
ERL_NIF_LATIN1));
|
||||
}
|
||||
WT_ITEM raw_key;
|
||||
raw_key.data = key.data;
|
||||
raw_key.size = key.size;
|
||||
cursor->set_key(cursor, &raw_key);
|
||||
rc = cursor->remove(cursor);
|
||||
cursor->close(cursor, NULL);
|
||||
if (rc != 0)
|
||||
{
|
||||
return enif_make_tuple2(env, ATOM_ERROR,
|
||||
enif_make_string(env, wiredtiger_strerror(rc),
|
||||
ERL_NIF_LATIN1));
|
||||
}
|
||||
return ATOM_OK;
|
||||
}
|
||||
}
|
||||
return enif_make_badarg(env);
|
||||
}
|
||||
|
||||
static ERL_NIF_TERM wterl_session_close(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;
|
||||
int rc = session->close(session, NULL);
|
||||
if (rc != 0)
|
||||
{
|
||||
return enif_make_tuple2(env, ATOM_ERROR,
|
||||
enif_make_string(env, wiredtiger_strerror(rc),
|
||||
ERL_NIF_LATIN1));
|
||||
}
|
||||
return ATOM_OK;
|
||||
}
|
||||
return enif_make_badarg(env);
|
||||
}
|
||||
|
||||
static ERL_NIF_TERM wterl_table_create(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;
|
||||
char config[256];
|
||||
if (enif_get_string(env, argv[1], table, sizeof table, ERL_NIF_LATIN1) &&
|
||||
enif_get_string(env, argv[2], config, sizeof config, ERL_NIF_LATIN1))
|
||||
{
|
||||
int rc = session->create(session, table, config);
|
||||
if (rc == 0)
|
||||
{
|
||||
return enif_make_tuple2(env, ATOM_OK, enif_make_string(env, table, ERL_NIF_LATIN1));
|
||||
}
|
||||
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_table_drop(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;
|
||||
char config[256];
|
||||
if (enif_get_string(env, argv[1], table, sizeof table, ERL_NIF_LATIN1) &&
|
||||
enif_get_string(env, argv[2], config, sizeof config, ERL_NIF_LATIN1))
|
||||
{
|
||||
int rc = session->drop(session, table, config);
|
||||
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)
|
||||
|
@ -162,6 +381,7 @@ static int on_load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
|
|||
&wterl_session_resource_cleanup,
|
||||
flags, NULL);
|
||||
ATOM_ERROR = enif_make_atom(env, "error");
|
||||
ATOM_OK = enif_make_atom(env, "ok");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,10 +23,16 @@
|
|||
|
||||
|
||||
-export([conn_open/2,
|
||||
conn_close/1,
|
||||
session_new/1,
|
||||
session_get/2,
|
||||
session_put/3,
|
||||
session_delete/2,
|
||||
session_get/3,
|
||||
session_put/4,
|
||||
session_delete/3,
|
||||
session_close/1,
|
||||
table_create/2,
|
||||
table_create/3,
|
||||
table_drop/2,
|
||||
table_drop/3,
|
||||
config_to_bin/2]).
|
||||
|
||||
-on_load(init/0).
|
||||
|
@ -53,18 +59,35 @@ init() ->
|
|||
conn_open(_HomeDir, _Config) ->
|
||||
?nif_stub.
|
||||
|
||||
conn_close(_ConnRef) ->
|
||||
?nif_stub.
|
||||
|
||||
session_new(_ConnRef) ->
|
||||
?nif_stub.
|
||||
|
||||
session_get(_Ref, _Key) ->
|
||||
session_get(_Ref, _Table, _Key) ->
|
||||
?nif_stub.
|
||||
|
||||
session_put(_Ref, _Key, _Value) ->
|
||||
session_put(_Ref, _Table, _Key, _Value) ->
|
||||
?nif_stub.
|
||||
|
||||
session_delete(_Ref, _Key) ->
|
||||
session_delete(_Ref, _Table, _Key) ->
|
||||
?nif_stub.
|
||||
|
||||
session_close(_Ref) ->
|
||||
?nif_stub.
|
||||
|
||||
table_create(Ref, Name) ->
|
||||
table_create(Ref, Name, "").
|
||||
|
||||
table_create(_Ref, _Name, _Config) ->
|
||||
?nif_stub.
|
||||
|
||||
table_drop(Ref, Name) ->
|
||||
table_drop(Ref, Name, "").
|
||||
|
||||
table_drop(_Ref, _Name, _Config) ->
|
||||
?nif_stub.
|
||||
|
||||
%%
|
||||
%% Configuration type information.
|
||||
|
@ -132,6 +155,13 @@ basic_test() ->
|
|||
Opts = [{create, true}],
|
||||
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_new(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 = session_close(SRef),
|
||||
ok = conn_close(ConnRef).
|
||||
|
||||
-endif.
|
||||
|
|
Loading…
Reference in a new issue