Erlang AWS DynamoDB client
Erlang Makefile
Latest commit b949a64 Sep 2, 2016 @dialtone dialtone committed on GitHub Merge pull request #16 from SemanticSugar/table_region_query
Support query/get in other regions
Permalink
Failed to load latest commit information.
include
src
.gitignore
LICENSE add license Jan 18, 2012
Makefile
README.md update readme to reflect new IMDS functionality Oct 18, 2014
rebar
rebar.config

README.md

Here's how you use this thing without using any macro help:

dinerl:setup("AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "us-east-1b").

or (use a specific endpoint by specifying the zone, and obtain security tokens from the local instance metadata server):

dinerl:setup("us-east-1b").

or (obtain security tokens from the local instance metadata server, and use the zone returned from the instance metadata server to determine the endpoint):

dinerl:setup().

then:

dinerl:create_table(<<"TestTable">>, [{<<"HashKeyElement">>, [{<<"AttributeName">>, <<"Key">>}, {<<"AttributeType">>, <<"S">>}]}], 50, 50).
dinerl:list_tables().
dinerl:put_item(<<"TestTable">>, [{<<"Key">>, [{<<"S">>, <<"jello">>}]}], []).
dinerl:get_item(<<"TestTable">>, [{<<"HashKeyElement">>, [{<<"S">>, <<"jello">>}]}], []).

put(Key, Value, TTL, Now) ->
    dinerl:put_item(<<"Attributions">>, [{<<"UserKey">>, [{<<"S">>, Key}]},
                                         {<<"Updated">>, [{<<"N">>, list_to_binary(integer_to_list(Now))}]},
                                         {<<"TTL">>, [{<<"N">>, list_to_binary(integer_to_list(TTL))}]},
                                         {<<"Value">>, [{<<"S">>, Value}]}], []).

get(Key, Now, Default) ->
    case dinerl:get_item(<<"Attributions">>, [{<<"HashKeyElement">>, [{<<"S">>, Key}]}], [{attrs, [<<"TTL">>, <<"Updated">>, <<"Value">>, <<"Visited">>]}]) of
        {ok, Element} ->
            ParsedResult = parsejson(Element),
            return_if_not_expired(Key, ParsedResult, Now, Default);

        {error, Short, Long} ->
            io:format("~p", [Long]),
            Default
    end.

add(Key, Value, TTL, Now) ->
    dinerl:update_item(<<"Attributions">>,
                       [{<<"HashKeyElement">>, [{<<"S">>, Key}]}],
                       [{update, [{<<"Visited">>, [{value, [{<<"SS">>, [Value]}]},
                                                   {action, add}]},
                                  {<<"Updated">>, [{value, [{<<"N">>, list_to_binary(integer_to_list(Now))}]},
                                                   {action, put}]},
                                  {<<"TTL">>, [{value, [{<<"N">>, list_to_binary(integer_to_list(TTL))}]},
                                               {action, put}]}]}]).



parsejson([]) ->
    [];
parsejson({struct, L}) ->
    parsejson(L);
parsejson([{<<"Item">>, {struct, Fields}}|_Rest]) ->
    parsejsonfields(Fields, []);
parsejson([_H|T]) ->
    parsejson(T).

parsejsonfields([], Acc) ->
    Acc;
parsejsonfields([{Name, {struct, [{<<"N">>, Value}]}}|Rest], Acc) ->
    parsejsonfields(Rest, [{Name, list_to_integer(binary_to_list(Value))}|Acc]);
parsejsonfields([{Name, {struct, [{<<"S">>, Value}]}}|Rest], Acc) ->
    parsejsonfields(Rest, [{Name, Value}|Acc]);
parsejsonfields([{Name, {struct, [{<<"NS">>, Value}]}}|Rest], Acc) ->
    parsejsonfields(Rest, [{Name, all_to_int(Value)}|Acc]);
parsejsonfields([{Name, {struct, [{<<"SS">>, Value}]}}|Rest], Acc) ->
    parsejsonfields(Rest, [{Name, Value}|Acc]).


return_if_not_expired(_, [], _, Default) ->
    Default;
return_if_not_expired(Key, ParsedResult, Now, Default) ->
    Updated = proplists:get_value(<<"Updated">>, ParsedResult),
    TTL = proplists:get_value(<<"TTL">>, ParsedResult),
    case (Updated+TTL) > Now of
        true ->
            ParsedResult;
        false ->
            dinerl:delete_item(<<"Attributions">>, [{<<"HashKeyElement">>, [{<<"S">>, Key}]}], []),
            Default
    end.

all_to_int(L) ->
    all_to_int(L, []).
all_to_int([], Acc) ->
    lists:reverse(Acc);
all_to_int([H|T], Acc) ->
    all_to_int(T, [list_to_integer(binary_to_list(H))|Acc]).

pytime() ->
    pytime(erlang:now()).
pytime({MegaSecs, Secs, MicroSecs}) ->
    erlang:trunc((1.0e+6 * MegaSecs) + Secs + (1.0e-6 * MicroSecs)).