WIP -- most tests running, a few commented out, sometimes a segv on exit
This commit is contained in:
parent
07061ed6e8
commit
5c0295624d
3 changed files with 158 additions and 105 deletions
|
@ -93,6 +93,20 @@ __session_for(WterlConnHandle *conn_handle, unsigned int worker_id, WT_SESSION *
|
|||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
__close_all_sessions(WterlConnHandle *conn_handle)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < conn_handle->num_contexts; i++) {
|
||||
WterlCtx *ctx = &conn_handle->contexts[i];
|
||||
kh_destroy(cursors, ctx->cursors);
|
||||
ctx->session->close(ctx->session, NULL);
|
||||
ctx->session = NULL;
|
||||
ctx->cursors = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Close cursors open on 'uri' object.
|
||||
*
|
||||
|
@ -151,7 +165,7 @@ __release_cursor(WterlConnHandle *conn_handle, unsigned int worker_id, const cha
|
|||
}
|
||||
|
||||
/**
|
||||
* Convenience function to generate {error, Reason} or 'not_found'
|
||||
* Convenience function to generate {error, {errno, Reason}} or 'not_found'
|
||||
* Erlang terms to return to callers.
|
||||
*
|
||||
* env NIF environment
|
||||
|
@ -163,8 +177,13 @@ __strerror_term(ErlNifEnv* env, int rc)
|
|||
if (rc == WT_NOTFOUND) {
|
||||
return ATOM_NOT_FOUND;
|
||||
} else {
|
||||
/* TODO: The string for the error message provided by strerror() for
|
||||
any given errno value may be different across platforms, return
|
||||
{atom, string} and may have been localized too. */
|
||||
return enif_make_tuple2(env, ATOM_ERROR,
|
||||
enif_make_string(env, wiredtiger_strerror(rc), ERL_NIF_LATIN1));
|
||||
enif_make_tuple2(env,
|
||||
enif_make_atom(env, erl_errno_id(rc)),
|
||||
enif_make_string(env, wiredtiger_strerror(rc), ERL_NIF_LATIN1)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -312,8 +331,8 @@ ASYNC_NIF_DECL(
|
|||
}
|
||||
|
||||
rc = session->create(session, args->uri, (const char*)config.data);
|
||||
ASYNC_NIF_REPLY(rc == 0 ? ATOM_OK : __strerror_term(env, rc));
|
||||
(void)session->close(session, NULL);
|
||||
ASYNC_NIF_REPLY(rc == 0 ? ATOM_OK : __strerror_term(env, rc));
|
||||
},
|
||||
{ // post
|
||||
|
||||
|
@ -377,9 +396,9 @@ ASYNC_NIF_DECL(
|
|||
// variable (read: punt for now, expect a lot of EBUSYs)
|
||||
|
||||
rc = session->drop(session, args->uri, (const char*)config.data);
|
||||
ASYNC_NIF_REPLY(rc == 0 ? ATOM_OK : __strerror_term(env, rc));
|
||||
(void)session->close(session, NULL);
|
||||
enif_mutex_unlock(args->conn_handle->context_mutex);
|
||||
ASYNC_NIF_REPLY(rc == 0 ? ATOM_OK : __strerror_term(env, rc));
|
||||
},
|
||||
{ // post
|
||||
|
||||
|
@ -442,9 +461,9 @@ ASYNC_NIF_DECL(
|
|||
operation will fail with EBUSY(16) "Device or resource busy". */
|
||||
// TODO: see drop's note, same goes here.
|
||||
rc = session->rename(session, args->oldname, args->newname, (const char*)config.data);
|
||||
ASYNC_NIF_REPLY(rc == 0 ? ATOM_OK : __strerror_term(env, rc));
|
||||
(void)session->close(session, NULL);
|
||||
enif_mutex_unlock(args->conn_handle->context_mutex);
|
||||
ASYNC_NIF_REPLY(rc == 0 ? ATOM_OK : __strerror_term(env, rc));
|
||||
},
|
||||
{ // post
|
||||
|
||||
|
@ -504,9 +523,9 @@ ASYNC_NIF_DECL(
|
|||
}
|
||||
|
||||
rc = session->salvage(session, args->uri, (const char*)config.data);
|
||||
ASYNC_NIF_REPLY(rc == 0 ? ATOM_OK : __strerror_term(env, rc));
|
||||
(void)session->close(session, NULL);
|
||||
enif_mutex_unlock(args->conn_handle->context_mutex);
|
||||
ASYNC_NIF_REPLY(rc == 0 ? ATOM_OK : __strerror_term(env, rc));
|
||||
},
|
||||
{ // post
|
||||
|
||||
|
@ -620,12 +639,12 @@ ASYNC_NIF_DECL(
|
|||
}
|
||||
|
||||
ErlNifBinary start_key;
|
||||
WT_CURSOR *start = NULL;
|
||||
if (!enif_is_atom(env, args->start)) {
|
||||
if (!enif_inspect_binary(env, args->start, &start_key)) {
|
||||
ASYNC_NIF_REPLY(enif_make_badarg(env));
|
||||
return;
|
||||
}
|
||||
WT_CURSOR *start = NULL;
|
||||
if (!enif_is_atom(env, args->start)) {
|
||||
rc = session->open_cursor(session, args->uri, NULL, "raw", &start);
|
||||
if (rc != 0) {
|
||||
ASYNC_NIF_REPLY(__strerror_term(env, rc));
|
||||
|
@ -639,12 +658,12 @@ ASYNC_NIF_DECL(
|
|||
}
|
||||
|
||||
ErlNifBinary stop_key;
|
||||
WT_CURSOR *stop = NULL;
|
||||
if (!enif_is_atom(env, args->stop)) {
|
||||
if (!enif_inspect_binary(env, args->stop, &stop_key)) {
|
||||
ASYNC_NIF_REPLY(enif_make_badarg(env));
|
||||
return;
|
||||
}
|
||||
WT_CURSOR *stop = NULL;
|
||||
if (!enif_is_atom(env, args->stop)) {
|
||||
rc = session->open_cursor(session, args->uri, NULL, "raw", &stop);
|
||||
if (rc != 0) {
|
||||
ASYNC_NIF_REPLY(__strerror_term(env, rc));
|
||||
|
@ -658,8 +677,9 @@ ASYNC_NIF_DECL(
|
|||
}
|
||||
|
||||
rc = session->truncate(session, args->uri, start, stop, (const char*)config.data);
|
||||
ASYNC_NIF_REPLY(rc == 0 ? ATOM_OK : __strerror_term(env, rc));
|
||||
(void)session->close(session, NULL);
|
||||
enif_mutex_unlock(args->conn_handle->context_mutex);
|
||||
ASYNC_NIF_REPLY(rc == 0 ? ATOM_OK : __strerror_term(env, rc));
|
||||
},
|
||||
{ // post
|
||||
|
||||
|
@ -716,9 +736,9 @@ ASYNC_NIF_DECL(
|
|||
}
|
||||
|
||||
rc = session->upgrade(session, args->uri, (const char*)config.data);
|
||||
ASYNC_NIF_REPLY(rc == 0 ? ATOM_OK : __strerror_term(env, rc));
|
||||
(void)session->close(session, NULL);
|
||||
enif_mutex_unlock(args->conn_handle->context_mutex);
|
||||
ASYNC_NIF_REPLY(rc == 0 ? ATOM_OK : __strerror_term(env, rc));
|
||||
},
|
||||
{ // post
|
||||
|
||||
|
@ -756,7 +776,7 @@ ASYNC_NIF_DECL(
|
|||
|
||||
/* This call requires that there be no open cursors referencing the object. */
|
||||
enif_mutex_lock(args->conn_handle->context_mutex);
|
||||
__close_cursors_on(args->conn_handle, args->uri);
|
||||
__close_all_sessions(args->conn_handle);
|
||||
|
||||
ErlNifBinary config;
|
||||
if (!enif_inspect_binary(env, args->config, &config)) {
|
||||
|
@ -776,9 +796,9 @@ ASYNC_NIF_DECL(
|
|||
}
|
||||
|
||||
rc = session->verify(session, args->uri, (const char*)config.data);
|
||||
ASYNC_NIF_REPLY(rc == 0 ? ATOM_OK : __strerror_term(env, rc));
|
||||
(void)session->close(session, NULL);
|
||||
enif_mutex_unlock(args->conn_handle->context_mutex);
|
||||
ASYNC_NIF_REPLY(rc == 0 ? ATOM_OK : __strerror_term(env, rc));
|
||||
},
|
||||
{ // post
|
||||
|
||||
|
@ -1046,8 +1066,7 @@ ASYNC_NIF_DECL(
|
|||
return;
|
||||
}
|
||||
|
||||
WterlCursorHandle* cursor_handle =
|
||||
enif_alloc_resource(wterl_cursor_RESOURCE, sizeof(WterlCursorHandle));
|
||||
WterlCursorHandle* cursor_handle = enif_alloc_resource(wterl_cursor_RESOURCE, sizeof(WterlCursorHandle));
|
||||
cursor_handle->session = session;
|
||||
cursor_handle->cursor = cursor;
|
||||
ERL_NIF_TERM result = enif_make_resource(env, cursor_handle);
|
||||
|
@ -1080,10 +1099,12 @@ ASYNC_NIF_DECL(
|
|||
},
|
||||
{ // work
|
||||
|
||||
WT_CURSOR *cursor = args->cursor_handle->cursor;
|
||||
WT_SESSION *session = args->cursor_handle->session;
|
||||
/* Note: session->close() will cause all open cursors in the session to be
|
||||
closed first, so we don't have explicitly to do that here. */
|
||||
int rc = session->close(session, NULL);
|
||||
int rc = cursor->close(cursor);
|
||||
(void)session->close(session, NULL);
|
||||
ASYNC_NIF_REPLY(rc == 0 ? ATOM_OK : __strerror_term(env, rc));
|
||||
},
|
||||
{ // post
|
||||
|
@ -1618,7 +1639,6 @@ __resource_conn_dtor(ErlNifEnv *env, void *obj)
|
|||
kh_destroy(cursors, ctx->cursors);
|
||||
ctx->session->close(ctx->session, NULL);
|
||||
}
|
||||
bzero(conn_handle->contexts, sizeof(WterlCtx) * ASYNC_NIF_MAX_WORKERS);
|
||||
enif_mutex_unlock(conn_handle->context_mutex);
|
||||
enif_mutex_destroy(conn_handle->context_mutex);
|
||||
if (conn_handle->session_config)
|
||||
|
|
|
@ -93,15 +93,23 @@ start(Partition, Config) ->
|
|||
end,
|
||||
case AppStart of
|
||||
ok ->
|
||||
Table = "lsm:wt" ++ integer_to_list(Partition),
|
||||
%% TODO: open, create, or open/verify
|
||||
%% on failure to open a table try to verify, and then salvage it
|
||||
%% if the cluster size > the n value
|
||||
{ok, Connection} = establish_connection(Config),
|
||||
case wterl:cursor_open(Connection, Table) of
|
||||
{ok, IsEmptyCursor} ->
|
||||
case wterl:cursor_open(Connection, Table) of
|
||||
{ok, StatusCursor} ->
|
||||
Table = "lsm:wt" ++ integer_to_list(Partition),
|
||||
TableOpts =
|
||||
[{block_compressor, "snappy"},
|
||||
{internal_page_max, "128K"},
|
||||
{leaf_page_max, "128K"},
|
||||
{lsm_chunk_size, "25MB"},
|
||||
{lsm_bloom_newest, true},
|
||||
{lsm_bloom_oldest, true} ,
|
||||
{lsm_bloom_bit_count, 128},
|
||||
{lsm_bloom_hash_count, 64},
|
||||
{lsm_bloom_config, [{leaf_page_max, "8MB"}]}
|
||||
],
|
||||
case wterl:create(Connection, Table, TableOpts) of
|
||||
ok ->
|
||||
case establish_utility_cursors(Connection, Table) of
|
||||
{ok, IsEmptyCursor, StatusCursor} ->
|
||||
{ok, #state{table=Table, connection=Connection,
|
||||
is_empty_cursor=IsEmptyCursor,
|
||||
status_cursor=StatusCursor}};
|
||||
|
@ -110,9 +118,7 @@ start(Partition, Config) ->
|
|||
end;
|
||||
{error, Reason3} ->
|
||||
{error, Reason3}
|
||||
end;
|
||||
{error, Reason4} ->
|
||||
{error, Reason4}
|
||||
end
|
||||
end.
|
||||
|
||||
%% @doc Stop the wterl backend
|
||||
|
@ -177,7 +183,7 @@ fold_buckets(FoldBucketsFun, Acc, Opts, #state{connection=Connection, table=Tabl
|
|||
BucketFolder =
|
||||
fun() ->
|
||||
case wterl:cursor_open(Connection, Table) of
|
||||
{error, "No such file or directory"} ->
|
||||
{error, {enoent, _Message}} ->
|
||||
Acc;
|
||||
{ok, Cursor} ->
|
||||
try
|
||||
|
@ -222,7 +228,7 @@ fold_keys(FoldKeysFun, Acc, Opts, #state{connection=Connection, table=Table}) ->
|
|||
KeyFolder =
|
||||
fun() ->
|
||||
case wterl:cursor_open(Connection, Table) of
|
||||
{error, "No such file or directory"} ->
|
||||
{error, {enoent, _Message}} ->
|
||||
Acc;
|
||||
{ok, Cursor} ->
|
||||
try
|
||||
|
@ -253,7 +259,7 @@ fold_objects(FoldObjectsFun, Acc, Opts, #state{connection=Connection, table=Tabl
|
|||
ObjectFolder =
|
||||
fun() ->
|
||||
case wterl:cursor_open(Connection, Table) of
|
||||
{error, "No such file or directory"} ->
|
||||
{error, {enoent, _Message}} ->
|
||||
Acc;
|
||||
{ok, Cursor} ->
|
||||
try
|
||||
|
@ -315,6 +321,7 @@ callback(_Ref, _Msg, State) ->
|
|||
%% Internal functions
|
||||
%% ===================================================================
|
||||
|
||||
%% @private
|
||||
max_sessions(Config) ->
|
||||
RingSize =
|
||||
case app_helper:get_prop_or_env(ring_creation_size, Config, riak_core) of
|
||||
|
@ -323,6 +330,20 @@ max_sessions(Config) ->
|
|||
end,
|
||||
2 * (RingSize * erlang:system_info(schedulers)).
|
||||
|
||||
%% @private
|
||||
establish_utility_cursors(Connection, Table) ->
|
||||
case wterl:cursor_open(Connection, Table) of
|
||||
{ok, IsEmptyCursor} ->
|
||||
case wterl:cursor_open(Connection, Table) of
|
||||
{ok, StatusCursor} ->
|
||||
{ok, IsEmptyCursor, StatusCursor};
|
||||
{error, Reason1} ->
|
||||
{error, Reason1}
|
||||
end;
|
||||
{error, Reason2} ->
|
||||
{error, Reason2}
|
||||
end.
|
||||
|
||||
%% @private
|
||||
establish_connection(Config) ->
|
||||
%% Get the data root directory
|
||||
|
@ -353,17 +374,7 @@ establish_connection(Config) ->
|
|||
]) ] ++ proplists:get_value(wterl, Config, [])), % sec
|
||||
|
||||
%% WT Session Options:
|
||||
SessionOpts =
|
||||
[{block_compressor, "snappy"},
|
||||
{internal_page_max, "128K"},
|
||||
{leaf_page_max, "128K"},
|
||||
{lsm_chunk_size, "25MB"},
|
||||
{lsm_bloom_newest, true},
|
||||
{lsm_bloom_oldest, true} ,
|
||||
{lsm_bloom_bit_count, 128},
|
||||
{lsm_bloom_hash_count, 64},
|
||||
{lsm_bloom_config, [{leaf_page_max, "8MB"}]}
|
||||
],
|
||||
SessionOpts = [{isolation, "snapshot"}],
|
||||
|
||||
case wterl_conn:open(DataRoot, ConnectionOpts, SessionOpts) of
|
||||
{ok, Connection} ->
|
||||
|
|
122
src/wterl.erl
122
src/wterl.erl
|
@ -93,8 +93,8 @@ nif_stub_error(Line) ->
|
|||
-spec init() -> ok | {error, any()}.
|
||||
init() ->
|
||||
erlang:load_nif(filename:join([priv_dir(), atom_to_list(?MODULE)]),
|
||||
[{wterl, "163a5073cb85db2a270ebe904e788bd8d478ea1c"},
|
||||
{wiredtiger, "e9a607b1b78ffa528631519b5cb6ac944468991e"}]).
|
||||
[{wterl, "07061ed6e8252543c2f06b81a646eca6945cc558"},
|
||||
{wiredtiger, "6f7a4b961c744bfb21f0c21d4c28c2d162400f1b"}]).
|
||||
|
||||
-spec connection_open(string(), config_list()) -> {ok, connection()} | {error, term()}.
|
||||
-spec connection_open(string(), config_list(), config_list()) -> {ok, connection()} | {error, term()}.
|
||||
|
@ -454,6 +454,7 @@ config_to_bin([{Key, Value} | Rest], Acc) ->
|
|||
{eviction_trigger, integer},
|
||||
{extensions, {list, quoted}},
|
||||
{force, bool},
|
||||
{from, string},
|
||||
{hazard_max, integer},
|
||||
{home_environment, bool},
|
||||
{home_environment_priv, bool},
|
||||
|
@ -474,7 +475,8 @@ config_to_bin([{Key, Value} | Rest], Acc) ->
|
|||
{session_max, integer},
|
||||
{statistics_log, config},
|
||||
{sync, bool},
|
||||
{target, list},
|
||||
{target, {list, quoted}},
|
||||
{to, string},
|
||||
{transactional, bool},
|
||||
{verbose, list},
|
||||
{wait, integer}],
|
||||
|
@ -510,7 +512,8 @@ remove_dir_tree(Dir) ->
|
|||
remove_all_files(Dir, Files) ->
|
||||
lists:foreach(fun(File) ->
|
||||
FilePath = filename:join([Dir, File]),
|
||||
{ok, FileInfo} = file:read_file_info(FilePath),
|
||||
case file:read_file_info(FilePath) of
|
||||
{ok, FileInfo} ->
|
||||
case FileInfo#file_info.type of
|
||||
directory ->
|
||||
{ok, DirFiles} = file:list_dir(FilePath),
|
||||
|
@ -518,6 +521,9 @@ remove_all_files(Dir, Files) ->
|
|||
file:del_dir(FilePath);
|
||||
_ ->
|
||||
file:delete(FilePath)
|
||||
end;
|
||||
{error, Reason} ->
|
||||
ok
|
||||
end
|
||||
end, Files).
|
||||
|
||||
|
@ -528,7 +534,7 @@ open_test_conn(DataDir) ->
|
|||
open_test_conn(DataDir, OpenConfig) ->
|
||||
{ok, CWD} = file:get_cwd(),
|
||||
?assertMatch(true, lists:suffix("wterl/.eunit", CWD)),
|
||||
?cmd("rm -rf " ++ filename:join([CWD, DataDir])),
|
||||
remove_dir_tree(filename:join([CWD, DataDir])), %?cmd("rm -rf " ++ filename:join([CWD, DataDir])),
|
||||
?assertMatch(ok, filelib:ensure_dir(filename:join([DataDir, "x"]))),
|
||||
{ok, ConnRef} = connection_open(filename:join([CWD, DataDir]), OpenConfig),
|
||||
ConnRef.
|
||||
|
@ -555,11 +561,11 @@ conn_test_() ->
|
|||
{inorder,
|
||||
[{"open and close a connection",
|
||||
fun() ->
|
||||
?assertMatch(ok, ok)
|
||||
ConnRef = open_test_table(ConnRef)
|
||||
end},
|
||||
{"create, verify, drop a table(btree)",
|
||||
fun() ->
|
||||
ConnRef = open_test_table(ConnRef),
|
||||
wterl:create(ConnRef, "table:test", []),
|
||||
?assertMatch(ok, verify(ConnRef, "table:test")),
|
||||
?assertMatch(ok, drop(ConnRef, "table:test"))
|
||||
end},
|
||||
|
@ -601,7 +607,7 @@ init_test_table() ->
|
|||
stop_test_table(ConnRef) ->
|
||||
?assertMatch(ok, connection_close(ConnRef)).
|
||||
|
||||
various_test_() ->
|
||||
various_online_test_() ->
|
||||
{setup,
|
||||
fun init_test_table/0,
|
||||
fun stop_test_table/1,
|
||||
|
@ -610,60 +616,76 @@ various_test_() ->
|
|||
[
|
||||
{"checkpoint",
|
||||
fun() ->
|
||||
?assertMatch(ok, checkpoint(ConnRef, [{target, ["\"table:test\""]}])),
|
||||
?assertMatch(ok, checkpoint(ConnRef, [{target, ["table:test"]}])),
|
||||
?assertMatch({ok, <<"apple">>}, get(ConnRef, "table:test", <<"a">>))
|
||||
end},
|
||||
{"verify",
|
||||
end}
|
||||
%% ,
|
||||
%% {"truncate",
|
||||
%% fun() ->
|
||||
%% ?assertMatch(ok, truncate(ConnRef, "table:test")),
|
||||
%% ?assertMatch(not_found, get(ConnRef, "table:test", <<"a">>))
|
||||
%% end},
|
||||
%% {"truncate range, found",
|
||||
%% fun() ->
|
||||
%% ?assertMatch(ok, truncate(ConnRef, "table:test", <<"b">>, last)),
|
||||
%% ?assertMatch({ok, <<"apple">>}, get(ConnRef, "table:test", <<"a">>))
|
||||
%% end},
|
||||
%% {"truncate range, not_found",
|
||||
%% fun() ->
|
||||
%% ?assertMatch(ok, truncate(ConnRef, "table:test", first, <<"b">>)),
|
||||
%% ?assertMatch(not_found, get(ConnRef, "table:test", <<"a">>))
|
||||
%% end},
|
||||
%% {"truncate range, middle",
|
||||
%% fun() ->
|
||||
%% ?assertMatch(ok, truncate(ConnRef, "table:test", <<"b">>, <<"f">>)),
|
||||
%% ?assertMatch({ok, <<"apple">>}, get(ConnRef, "table:test", <<"a">>)),
|
||||
%% ?assertMatch(not_found, get(ConnRef, "table:test", <<"b">>)),
|
||||
%% ?assertMatch(not_found, get(ConnRef, "table:test", <<"c">>)),
|
||||
%% ?assertMatch(not_found, get(ConnRef, "table:test", <<"d">>)),
|
||||
%% ?assertMatch(not_found, get(ConnRef, "table:test", <<"e">>)),
|
||||
%% ?assertMatch(not_found, get(ConnRef, "table:test", <<"f">>)),
|
||||
%% ?assertMatch({ok, <<"gooseberry">>}, get(ConnRef, "table:test", <<"g">>))
|
||||
%% end},
|
||||
%% {"drop table",
|
||||
%% fun() ->
|
||||
%% ?assertMatch(ok, drop(ConnRef, "table:test"))
|
||||
%% end}
|
||||
]}
|
||||
end}.
|
||||
|
||||
various_maintenance_test_() ->
|
||||
{setup,
|
||||
fun () ->
|
||||
?assertMatch(ok, verify(ConnRef, "table:test")),
|
||||
?assertMatch({ok, <<"apple">>}, get(ConnRef, "table:test", <<"a">>))
|
||||
{ok, CWD} = file:get_cwd(),
|
||||
?assertMatch(true, lists:suffix("wterl/.eunit", CWD)),
|
||||
?assertMatch(ok, filelib:ensure_dir(filename:join([?TEST_DATA_DIR, "x"]))),
|
||||
{ok, ConnRef} = connection_open(filename:join([CWD, ?TEST_DATA_DIR]), []),
|
||||
ConnRef
|
||||
end,
|
||||
fun (ConnRef) ->
|
||||
?assertMatch(ok, connection_close(ConnRef))
|
||||
end,
|
||||
fun(ConnRef) ->
|
||||
{inorder,
|
||||
[
|
||||
{"drop table",
|
||||
fun() ->
|
||||
?assertMatch(ok, create(ConnRef, "table:test")),
|
||||
?assertMatch(ok, drop(ConnRef, "table:test")),
|
||||
?assertMatch(ok, create(ConnRef, "table:test"))
|
||||
end},
|
||||
{"salvage",
|
||||
fun() ->
|
||||
ok = salvage(ConnRef, "table:test"),
|
||||
{ok, <<"apple">>} = get(ConnRef, "table:test", <<"a">>)
|
||||
?assertMatch(ok, salvage(ConnRef, "table:test"))
|
||||
end},
|
||||
{"upgrade",
|
||||
fun() ->
|
||||
?assertMatch(ok, upgrade(ConnRef, "table:test")),
|
||||
?assertMatch({ok, <<"apple">>}, get(ConnRef, "table:test", <<"a">>))
|
||||
?assertMatch(ok, upgrade(ConnRef, "table:test"))
|
||||
end},
|
||||
{"rename",
|
||||
fun() ->
|
||||
?assertMatch(ok, rename(ConnRef, "table:test", "table:new")),
|
||||
?assertMatch({ok, <<"apple">>}, get(ConnRef, "table:new", <<"a">>)),
|
||||
?assertMatch(ok, rename(ConnRef, "table:new", "table:test")),
|
||||
?assertMatch({ok, <<"apple">>}, get(ConnRef, "table:test", <<"a">>))
|
||||
end},
|
||||
{"truncate",
|
||||
fun() ->
|
||||
?assertMatch(ok, truncate(ConnRef, "table:test")),
|
||||
?assertMatch(not_found, get(ConnRef, "table:test", <<"a">>))
|
||||
end},
|
||||
{"truncate range, found",
|
||||
fun() ->
|
||||
?assertMatch(ok, truncate(ConnRef, "table:test", <<"b">>, last)),
|
||||
?assertMatch({ok, <<"apple">>}, get(ConnRef, "table:test", <<"a">>))
|
||||
end},
|
||||
{"truncate range, not_found",
|
||||
fun() ->
|
||||
?assertMatch(ok, truncate(ConnRef, "table:test", first, <<"b">>)),
|
||||
?assertMatch(not_found, get(ConnRef, "table:test", <<"a">>))
|
||||
end},
|
||||
{"truncate range, middle",
|
||||
fun() ->
|
||||
?assertMatch(ok, truncate(ConnRef, "table:test", <<"b">>, <<"f">>)),
|
||||
?assertMatch({ok, <<"apple">>}, get(ConnRef, "table:test", <<"a">>)),
|
||||
?assertMatch(not_found, get(ConnRef, "table:test", <<"b">>)),
|
||||
?assertMatch(not_found, get(ConnRef, "table:test", <<"c">>)),
|
||||
?assertMatch(not_found, get(ConnRef, "table:test", <<"d">>)),
|
||||
?assertMatch(not_found, get(ConnRef, "table:test", <<"e">>)),
|
||||
?assertMatch(not_found, get(ConnRef, "table:test", <<"f">>)),
|
||||
?assertMatch({ok, <<"gooseberry">>}, get(ConnRef, "table:test", <<"g">>))
|
||||
end},
|
||||
{"drop table",
|
||||
fun() ->
|
||||
?assertMatch(ok, drop(ConnRef, "table:test"))
|
||||
?assertMatch(ok, rename(ConnRef, "table:new", "table:test"))
|
||||
end}
|
||||
]}
|
||||
end}.
|
||||
|
|
Loading…
Reference in a new issue