Current section
Files
Jump to
Current section
Files
src/lamb_query_erlang_ffi.erl
-module(lamb_query_erlang_ffi).
-export([new/0, update_head/2, update_condition/2, update_body/2, test_query/2, build_matchhead/1, build_matchbody/1]).
new() ->
Head = {'$0', '$1'},
Cond = [],
Body = ['$1'],
{Head, Cond, Body}.
update_head({_Head, Conditions, Body}, NewHead) ->
{NewHead, Conditions, Body}.
update_condition({Head, Conditions, Body}, Condition) ->
{Head, [Condition | Conditions], Body}.
update_body({Head, Conditions, _Body}, NewBody) ->
{Head, Conditions, [wrap_tuple(NewBody)]}.
% TODO: The traversal algorithm needs more basic datastructures.
% - Rename top function to traversal and localize wrap tuple.
% - Will need a stronger test-suite, to understand what is allowed.
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.
build_matchhead(Constructor) ->
case Constructor of
F when is_function(F, 0) ->
F();
F when is_function(F, 1) ->
F('$1');
F when is_function(F, 2) ->
F('$1', '$2');
F when is_function(F, 3) ->
F('$1', '$2', '$3');
F when is_function(F, 4) ->
F('$1', '$2', '$3', '$4');
F when is_function(F, 5) ->
F('$1', '$2', '$3', '$4', '$5');
F when is_function(F, 6) ->
F('$1', '$2', '$3', '$4', '$5', '$6');
F when is_function(F, 7) ->
F('$1', '$2', '$3', '$4', '$5', '$6', '$7');
F when is_function(F, 8) ->
F('$1', '$2', '$3', '$4', '$5', '$6', '$7', '$8');
F when is_function(F, 9) ->
F('$1', '$2', '$3', '$4', '$5', '$6', '$7', '$8', '$9')
end.
build_matchbody(Constructor) ->
case Constructor of
F when is_function(F, 1) ->
F('$0');
F when is_function(F, 2) ->
F('$0','$1');
F when is_function(F, 3) ->
F('$0','$1', '$2');
F when is_function(F, 4) ->
F('$0','$1', '$2', '$3');
F when is_function(F, 5) ->
F('$0','$1', '$2', '$3', '$4');
F when is_function(F, 6) ->
F('$0','$1', '$2', '$3', '$4', '$5');
F when is_function(F, 7) ->
F('$0','$1', '$2', '$3', '$4', '$5', '$6');
F when is_function(F, 8) ->
F('$0','$1', '$2', '$3', '$4', '$5', '$6', '$7');
F when is_function(F, 9) ->
F('$0','$1', '$2', '$3', '$4', '$5', '$6', '$7', '$8');
F when is_function(F, 10) ->
F('$0','$1', '$2', '$3', '$4', '$5', '$6', '$7', '$8', '$9')
end.