Search code examples
jsonerlangmnesia

How to convert Mnesia query results to a JSON'able list?


I am trying to use JSX to convert a list of tuples to a JSON object.

The list items are based on a record definition:

-record(player, {index, name, description}).

and looks like this:

[
    {player,1,"John Doe","Hey there"},
    {player,2,"Max Payne","I am here"}
]

The query function looks like this:

select_all() ->
    SelectAllFunction =
        fun() ->
            qlc:eval(qlc:q(
                [Player ||
                    Player <- mnesia:table(player)
                ]
            ))
        end,
    mnesia:transaction(SelectAllFunction).

What's the proper way to make it convertable to a JSON knowing that I have a schema of the record used and knowing the structure of tuples?


Solution

  • You'll have to convert the record into a term that jsx can encode to JSON correctly. Assuming you want an array of objects in the JSON for the list of player records, you'll have to either convert each player to a map or list of tuples. You'll also have to convert the strings to binaries or else jsx will encode it to a list of integers. Here's some sample code:

    -record(player, {index, name, description}).
    
    player_to_json_encodable(#player{index = Index, name = Name, description = Description}) ->
        [{index, Index}, {name, list_to_binary(Name)}, {description, list_to_binary(Description)}].
    
    go() ->
        Players = [
            {player, 1, "John Doe", "Hey there"},
            % the following is just some sugar for a tuple like above
            #player{index = 2, name = "Max Payne", description = "I am here"}
        ],
        JSON = jsx:encode(lists:map(fun player_to_json_encodable/1, Players)),
        io:format("~s~n", [JSON]).
    

    Test:

    1> r:go().
    [{"index":1,"name":"John Doe","description":"Hey there"},{"index":2,"name":"Max Payne","description":"I am here"}]