Best way to print a Mnesia spreadsheet

I tried this piece of code:

print_next(Current) -> case mnesia:dirty_next(muppet, Current) of '$end_of_table' -> io:format("~n", []), ok; Next -> [Muppet] = mnesia:dirty_read({muppet, Next}), io:format("~p~n", [Muppet]), print_next(Next), ok end. print() -> case mnesia:dirty_first(muppet) of '$end_of_table' -> ok; First -> [Muppet] = mnesia:dirty_read({muppet, First}), io:format("~p~n", [Muppet]), print_next(First), ok end. 

But it takes so long. I can also use dirty_all_keys and then dirty_all_keys over the list of keys, but I want to know if there is a better way to print the contents of the Mnesia table.

+6
source share
4 answers

Well, if the goal is to view the contents of your table, there is an application called tv that can view ETS and mnesia tables.

If you want to see the entire contents of the table on your terminal, try something like this:

  traverse_table_and_show (Table_name) ->
     Iterator = fun (Rec, _) ->
                     io: format ("~ p ~ n", [Rec]),
                     []
                 end
     case mnesia: is_transaction () of
         true -> mnesia: foldl (Iterator, [], Table_name);
         false -> 
             Exec = fun ({Fun, Tab}) -> mnesia: foldl (Fun, [], Tab) end,
             mnesia: activity (transaction, Exec, [{Iterator, Table_name}], mnesia_frag)
     end.

Then, if your table is called muppet , you use this function as follows:

  traverse_table_and_show (muppet).

The advantages of this:
If it is executed as part of a transaction, it will not have problems with nested transactions. This works less because it is executed as part of a single mnesia transaction via the mnesia iterator functionality compared to your implementation of get_next_key -> do_read_with_key ->, then reads the record (this is a lot of operations). At the same time, mnesia will automatically report that it has covered all the records in the entire table. Also, if the table is fragmented, your functionality will only display entries in the first fragment. This will repeat all the fragments belonging to this table.

In this mnesia iteration method, I do nothing with the Accumulator variable, which should be combined with Iterator fun, and so you see the underscore for the second variable.

Details of this iteration can be found here: http://www.erlang.org/doc/man/mnesia.html#foldl-3

+7
source

If you just need a quick and dirty way to print the contents of a Mnesia table in a shell, and if your table is not of type disc_only_copies , you can take advantage of the fact that Mnesia stores its data in ETS tables and starts:

 ets:tab2list(my_table). 

or, if you think that the shell cuts the data too much:

 rp(ets:tab2list(my_table)). 

Not recommended for "real" code, of course.

+9
source

To quickly and easily view the contents of a table, you can use the select mnesia function with catch-all Match Specification as follows:

 CatchAll = [{'_',[],['$_']}]. mnesia:dirty_select(TableName, CatchAll). 

and also you can run it inside the transaction context:

 CatchAll = [{'_',[],['$_']}]. SelectFun = fun() -> mnesia:select(TableName, CatchAll) end. mnesia:transaction(SelectFun). 

however, be careful if you are in a production environment with big data.

+5
source

As Muzaya said, you can use tv (table visualization tool) to view mnesia and ets tables. Alternatively, you can use the following code to get the mnesia table data - print on the terminal or in case you want to save the result in a file:

 select_all() -> mnesia:transaction( fun() -> P=qlc:e(qlc:q([E || E <- mnesia:table(tableName)])), %query to select all data from table named 'tableName' io:format(" ~p ~n ", [P]), % Prints table data on terminal to_file("fileName.txt",P) % to_file method writes the data to file end ). to_file(File, L) -> mnesia:transaction( fun() -> {ok, S} = file:open(File, write), lists:foreach(fun(X) -> io:format(S, "~p.~n" ,[X]) end, L), file:close(S) end). 
+2
source

Source: https://habr.com/ru/post/899272/


All Articles