我是Erlang的初学者和一般的函数式编程。为了好玩,为了让我开始,我正在转换一个现有的Ruby Sinatra REST(ish)API来查询PostgreSQL并返回JSON。
在Erlang方面,我使用Cowboy,Epgsql和Jiffy作为JSON库。
Epgsql以下列格式返回结果:
{ok, [{column,<<"column_name">>,int4,4,-1,0}], [{<<"value">>}]}
但是Jiffy在编码为JSON时需要以下格式:
{[{<<"column_name">>,<<"value">>}]}
以下代码用于将epgsql输出转换为适合jiffy的输入:
假设Data
是Epgsql输出,而Key
是正在创建的JSON对象的名称:
{_, C, R} = Data,
Columns = [X || {_, X, _, _, _, _} <- C,
Rows = tuple_to_list(hd(R)),
Result = {[{atom_to_binary(Key, utf8), {lists:zip(Columns, Rows)}}]}.
但是,我想知道这是否有效Erlang?
我查看了Epgsql和Jiffy的文档,看不到任何更明显的方法来执行转换。
谢谢。
答案 0 :(得分:1)
是的,需要解析它。
例如函数解析结果
parse_result({error, #error{ code = <<"23505">>, extra = Extra }}) ->
{match, [Column]} =
re:run(proplists:get_value(detail, Extra),
"Key \\(([^\\)]+)\\)", [{capture, all_but_first, binary}]),
throw({error, {non_unique, Column}});
parse_result({error, #error{ message = Msg }}) ->
throw({error, Msg});
parse_result({ok, Cols, Rows}) ->
to_map(Cols, Rows);
parse_result({ok, Counts, Cols, Rows}) ->
{ok, Counts, to_map(Cols, Rows)};
parse_result(Result) ->
Result.
并将功能转换为地图
to_map(Cols, Rows) ->
[ maps:from_list(lists:zipwith(fun(#column{name = N}, V) -> {N, V} end,
Cols, tuple_to_list(Row))) || Row <- Rows ].
并将其编码为json。您可以更改我的代码并将输出作为proplist。