将epgsql结果转换为JSON

时间:2015-04-21 19:33:08

标签: json postgresql erlang

我是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的文档,看不到任何更明显的方法来执行转换。

谢谢。

1 个答案:

答案 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。