Last active
January 8, 2016 08:58
-
-
Save SCdF/50b69e655595c56f679e to your computer and use it in GitHub Desktop.
doc_by_place in Erlang
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
% Benchmarking code for REPL nicked and modified to remove module param from here: | |
% https://erlangcentral.org/wiki/index.php/Measuring_Function_Execution_Time | |
% Params: FnName, Params, Rounds, eg: | |
% TC(DeepGet, [DeepGet, [<<"userCtx">>, <<"name">>], Req], 100000). | |
% TC = fun(TC_F, TC_A, TC_N) when TC_N > 0 -> TC_L = tl([begin {TC_T, _Result} = timer:tc(TC_F, TC_A), TC_T end || _ <- lists:seq(1, TC_N)]), TC_Min = lists:min(TC_L), TC_Max = lists:max(TC_L), TC_Med = lists:nth(round((TC_N - 1) / 2), lists:sort(TC_L)), TC_Avg = round(lists:foldl(fun(TC_X, TC_Sum) -> TC_X + TC_Sum end, 0, TC_L) / (TC_N - 1)), io:format("Range: ~b - ~b mics~nMedian: ~b mics ~nAverage: ~b mics~n", [TC_Min, TC_Max, TC_Med, TC_Avg]), TC_Med end. | |
% Made "cmd+v futon-ready" with the following disgusting display of black magic | |
% cat scratch.erl | sed 's/%.*//' | sed 's/"/\\"/'g | sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/ /g' | pbcopy | |
fun ({Doc}, {Req}) -> | |
SafeGetValue = fun(Key, PropListMaybe, Default) -> | |
if | |
is_tuple(PropListMaybe) andalso size(PropListMaybe) == 1 -> | |
% Some are wrapped in a tuple for some arbitrary reason | |
% {[{...}]} instead of [{...}] | |
proplists:get_value(Key, element(1, PropListMaybe), Default); | |
is_list(PropListMaybe) -> | |
proplists:get_value(Key, PropListMaybe, Default); | |
true -> | |
Default | |
end | |
end, | |
DeepGet = fun(DeepGet, KeyList, PropList) -> | |
if | |
length(KeyList) > 1 andalso PropList == [] -> | |
undefined; | |
length(KeyList) == 1 -> | |
SafeGetValue(hd(KeyList), PropList, undefined); | |
true -> | |
DeepGet(DeepGet, tl(KeyList), SafeGetValue(hd(KeyList), PropList, [])) | |
end | |
end, | |
FindPlace = fun(FindPlace, Place, QueryId) -> | |
if | |
Place == undefined -> | |
false; | |
true -> | |
case SafeGetValue(<<"_id">>, Place, undefined) =:= QueryId of | |
true -> true; | |
false -> FindPlace(FindPlace, SafeGetValue(<<"parent">>, Place, undefined), QueryId) | |
end | |
end | |
end, | |
Ok = fun(Place) -> | |
QueryId = DeepGet(DeepGet, [<<"query">>, <<"id">>], Req), | |
case QueryId =:= undefined of | |
true -> true; % Admin | |
false -> | |
case Place =:= undefined of | |
true -> DeepGet(DeepGet, [<<"query">>, <<"unassigned">>], Req) =:= <<"true">>; | |
false -> FindPlace(FindPlace, Place, QueryId) | |
end | |
end | |
end, | |
CouchUser = list_to_binary([ | |
<<"org.couchdb.user:">>, | |
DeepGet(DeepGet, [<<"userCtx">>, <<"name">>], Req)]), | |
case proplists:get_value(<<"_id">>, Doc) of | |
<<"design/medic">> -> false; % Never replicate the ddoc as it's too big. | |
% Changes are tracked in the watchDesignDoc function of the DB service. | |
<<"resources">> -> true; | |
CouchUser -> true; | |
_ -> case proplists:get_value(<<"type">>, Doc) of | |
<<"data_record">> -> | |
case proplists:get_value(<<"kujua_message">>, Doc) =:= <<"true">> of | |
true -> | |
% Outgoing message | |
Ok( | |
proplists:get_value(<<"contact">>, | |
hd(proplists:get_value(<<"messages">>, | |
hd(proplists:get_value(<<"tasks">>, Doc, [])), [])))); | |
false -> | |
% Incoming message | |
Ok(proplists:get_value(<<"contact">>, Doc)) | |
end; | |
<<"form">> -> true; | |
<<"clinic">> -> Ok(Doc); | |
<<"district_hospital">> -> Ok(Doc); | |
<<"health_centre">> -> Ok(Doc); | |
<<"person">> -> Ok(Doc); | |
_ -> false | |
end | |
end | |
end. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment