/src/controllers.erl

https://github.com/insane/Rape · Erlang · 99 lines · 88 code · 10 blank · 1 comment · 2 complexity · 83172168f892169b064ec1716589b99a MD5 · raw file

  1. -module(controllers).
  2. -export([urls/0, shops/2, add_shop/2, local_client/0]).
  3. urls() ->
  4. [
  5. {"^$", shops},
  6. {"^shops/?$", shops},
  7. {"^add_shop/?$", add_shop}
  8. ].
  9. shops('GET', Req) ->
  10. Shops = fetch_shops(),
  11. {ok, HTML} = shops_dtl:render([{shops, Shops}]),
  12. Req:ok({"text/html", HTML});
  13. shops('POST', Req) ->
  14. PostData = Req:parse_post(),
  15. Types = proplists:get_all_values("type", PostData),
  16. EntityTypes = proplists:get_all_values("entity_type", PostData),
  17. Shops = fetch_shops(Types, EntityTypes),
  18. {ok, HTML} = shops_dtl:render([{shops, Shops}]),
  19. Req:ok({"text/html", HTML}).
  20. add_shop('GET', Req) ->
  21. {ok, HTML} = add_shop_dtl:render([]),
  22. Req:ok({"text/html", HTML});
  23. add_shop('POST', Req) ->
  24. Pid = local_client(),
  25. PostData = Req:parse_post(),
  26. Types = proplists:get_all_values("type", PostData),
  27. Shop = mochijson2:encode([{"type", Types} | proplists:delete("type", PostData)]),
  28. ShopObj = riakc_obj:new(<<"shops">>, undefined, Shop),
  29. {ok, Key} = riakc_pb_socket:put(Pid, ShopObj),
  30. add_to_index(Pid, ["shops" | Types], Key),
  31. Req:respond({302,
  32. [{"Location", "/shops"},
  33. {"Content-Type", "text/html; charset=UTF-8"}],
  34. ""}).
  35. fetch_shops() ->
  36. fetch_shops([], []).
  37. fetch_shops(Types, EntityTypes) ->
  38. Pid = local_client(),
  39. Keys = case Types of
  40. [] ->
  41. case riakc_pb_socket:get(Pid, <<"shops">>, <<"keys">>) of
  42. {ok, KeysObj} ->
  43. mochijson2:decode(binary_to_term(riakc_obj:get_value(KeysObj)));
  44. {error, notfound} ->
  45. []
  46. end;
  47. _ ->
  48. lists:usort(find_keys(Types, Pid))
  49. end,
  50. Inputs = [{<<"shops">>, Key} || Key <- Keys],
  51. case riakc_pb_socket:mapred(Pid, Inputs,
  52. [{map, {modfun, rape_mapred, foo}, none, true}]) of
  53. {ok, [{0, Res}]} ->
  54. lists:map(fun({struct, X}) -> X end,
  55. [mochijson2:decode(binary_to_term(ShopBin)) || ShopBin <- Res]);
  56. {ok, []} ->
  57. []
  58. end.
  59. find_keys(Types, Pid) ->
  60. find_keys(Types, Pid, []).
  61. find_keys([], _, Acc) -> Acc;
  62. find_keys([T | Types], Pid, Acc) ->
  63. Keys = case riakc_pb_socket:get(Pid, list_to_binary(T), <<"keys">>) of
  64. {ok, KeysObj} ->
  65. mochijson2:decode(binary_to_term(riakc_obj:get_value(KeysObj)));
  66. {error, notfound} ->
  67. []
  68. end,
  69. find_keys(Types, Pid, Acc ++ Keys).
  70. %% Y U NO HAVE SECONDARY INDEX SUPPORT YET, ERLANG RIAK CLIENT?!?!
  71. add_to_index(_, [], _) ->
  72. ok;
  73. add_to_index(Pid, [T | Types], Key) ->
  74. case riakc_pb_socket:get(Pid, list_to_binary(T), <<"keys">>) of
  75. {ok, IndexObj} ->
  76. Keys = mochijson2:decode(binary_to_term(riakc_obj:get_value(IndexObj))),
  77. Keys1 = mochijson2:encode([Key | Keys]),
  78. IndexObj1 = riakc_obj:update_value(IndexObj, Keys1),
  79. riakc_pb_socket:put(Pid, IndexObj1),
  80. add_to_index(Pid, Types, Key);
  81. {error, notfound} ->
  82. Keys = mochijson2:encode([Key]),
  83. IndexObj = riakc_obj:new(list_to_binary(T), <<"keys">>, Keys),
  84. riakc_pb_socket:put(Pid, IndexObj),
  85. add_to_index(Pid, Types, Key)
  86. end.
  87. local_client() ->
  88. {ok, Pid} = riakc_pb_socket:start_link("127.0.0.1", 8081),
  89. Pid.