Hi
New to erlang and have been thrown in at the deep end. I'm making some modifications for the initial service discovery for mod_muc.erl
I have a mysql table containing location details, the table has three fields - name, lon and lat
The idea is to discover only those rooms within an certain radius based on GPS position
I have a working odbc query and have it returning the following (moded) result set
[{"world"},{"world1"},{"test1"}]
The rooms are discovered with the following query inside get_vh_rooms(Host)
mnesia:dirty_select(muc_online_room,
[{#muc_online_room{name_host = '$1', _ = '_'},
[{'==', {element, 2, '$1'},Host}],
['$_']}]).
This grabs all Rooms
If I change it to
mnesia:dirty_select(muc_online_room,
[{#muc_online_room{name_host = '$1', _ = '_'},
[{'==', {element, 1, '$1'},"world"}],
['$_']}]).
It will grab only the room called world and I can extend the pattern to grab more than one room. However I need to do it generically without hard-coding the room names.
So could anyone advise me on how traverse a list of rooms and pass the values to an mnesia query.
It SHOULD be easy but I've had less than 7 days experience of erlang.
I envision it as something like this
mnesia:dirty_select(muc_online_room,
[{#muc_online_room{name_host = '$1', _ = '_'},
[{'==', {element, 1, '$1'},MyRoom}],
['$_']}]).
Where MyRoom corresponds to each element of the list above but I have no idea how to traverse it and dynamically generate the pattern to pass to mnesia
Thanks in advance
You can specify a list of
You can specify a list of matches in your match spec to be passed to
mnesia:dirty_select
:[{#muc_online_room{name_host = '$1', _ = '_'}, [{'==', {element, 1, '$1'}, Room}], ['$_']} || {Room} <- Rooms]
where
Rooms
is a list of rooms returned by your ODBC query. It is effectively the same as something like:mnesia:dirty_select(muc_online_room,
[{#muc_online_room{name_host = '$1', _ = '_'}, [{'==', {element, 1, '$1'}, "world"}], ['$_']},
{#muc_online_room{name_host = '$1', _ = '_'}, [{'==', {element, 1, '$1'}, "world1"}], ['$_']},
{#muc_online_room{name_host = '$1', _ = '_'}, [{'==', {element, 1, '$1'}, "test1"}], ['$_']}]).
I can't vouch for the performance of a very long list of matches though, so test it with a long list.
Hi Thanks for the reply I
Hi
Thanks for the reply
I figured it out. The problem was generating the list in the first place. I ended up with the code below that "appears" to work
make_results({selected, ["name"], Items}) ->
[make_result(Item) || Item <- Items] .
%% Execute the ODBC query and parse the result set
Results = ejabberd_odbc:sql_query("suse1.local", ["SELECT name FROM loc"]),
ListOfRooms = make_results(Results),
RoomString1 = [],
ListOfPatterns = lists:map(fun(X) ->
RoomString2 = [{#muc_online_room{name_host = '$1', _ = '_'},
[{'==', {element, 1, '$1'}, X }],
['$_']}],
string:concat(RoomString1,RoomString2)
end, ListOfRooms),
Pattern = lists:merge(ListOfPatterns),
mnesia:dirty_select(muc_online_room,Pattern).
And the revised
And the revised version
make_results({selected, ["name"], Items}) ->
[make_result(Item) || Item <- Items] .
make_result({Name}) ->
[{#muc_online_room{name_host = '$1', _ = '_'},
[{'==', {element, 1, '$1'}, Name }],
['$_']}].
Results = ejabberd_odbc:sql_query("suse1.local", ["SELECT name FROM location"]),
ListOfRooms = make_results(Results),
Pattern = lists:merge(ListOfRooms),
mnesia:dirty_select(muc_online_room,Pattern).