Current section

Files

Jump to
lamb src lamb_erlang_ffi.erl
Raw

src/lamb_erlang_ffi.erl

-module(lamb_erlang_ffi).
-export([create_table/4, table_id/1, table_info/1, batch/3, continue/1, wrap_tuple/1,
test_query/2]).
create_table(Name, Access, Kind, false)
when is_atom(Name), is_atom(Access), is_atom(Kind) ->
ets:new(Name, [Access, Kind]);
create_table(Name, Access, Kind, true)
when is_atom(Name), is_atom(Access), is_atom(Kind) ->
Name = ets:new(Name, [Access, Kind, named_table]),
ets:whereis(Name).
table_id(Name) when is_atom(Name) ->
case ets:whereis(Name) of
undefined ->
{error, nil};
TableId ->
{ok, TableId}
end.
table_info(Table) ->
case ets:info(Table) of
undefined ->
{error, nil};
Info ->
{ok, extract_info(Info)}
end.
extract_info(Params) ->
[{id, _},
{decentralized_counters, _},
{read_concurrency, _},
{write_concurrency, _},
{compressed, _},
{memory, _},
{owner, _},
{heir, _},
{name, Name},
{size, _},
{node, _},
{named_table, NamedTable},
{type, Type},
{keypos, _},
{protection, Protection}] =
Params,
{Name, Type, Protection, NamedTable}.
batch(TableId, Limit, MatchExpression) ->
Result = ets:select(TableId, MatchExpression, Limit),
partial_handle(Result).
continue(Step) ->
Result = ets:select(Step),
partial_handle(Result).
partial_handle(Result) ->
case Result of
{Objects, '$end_of_table'} ->
{'end', Objects};
{Objects, Continuation} ->
{records, Objects, Continuation};
'$end_of_table' ->
{'end', []}
end.
wrap_tuple(Data) when is_tuple(Data) ->
% When a tuple is found, traverse and wrap in tuple {}
NewData = traverse(Data, 0, tuple_size(Data)),
{NewData};
wrap_tuple(Data) ->
Data.
traverse(Data, Size, Size) ->
Data;
traverse(Data, Index, Size) when Size > Index ->
Element = element(Index + 1, Data),
NewData = setelement(Index + 1, Data, wrap_tuple(Element)),
traverse(NewData, Index + 1, Size).
test_query(Spec, Tuple) ->
case ets:test_ms(Tuple, [Spec]) of
{ok, false} ->
no_match;
{ok, Result} ->
{spec, Result};
{error, Errors} ->
{invalid, lists:map(fun error/1, Errors)}
end.
error({error, Message}) ->
Message;
error({warning, Message}) ->
Message.