Erlang (programming language)/Tutorials/Mnesia: Difference between revisions

From Citizendium
Jump to navigation Jump to search
imported>Tom Morris
imported>Meg Taylor
m (spelling: Persistance -> Persistence)
 
Line 18: Line 18:
  +---------------------------------------------+   
  +---------------------------------------------+   
  | 1    | Dali    | The Ghost of Vermeer      |
  | 1    | Dali    | The Ghost of Vermeer      |
  | 2    | Dali    | The Persistance of Memory |
  | 2    | Dali    | The Persistence of Memory |
  | 3    | Vermeer | Girl With Pearl Earring  |
  | 3    | Vermeer | Girl With Pearl Earring  |
  +---------------------------------------------+
  +---------------------------------------------+

Latest revision as of 20:55, 10 February 2010


Mnesia

Mnesia is a database built in erlang. It is built using ETS and DETS. Mnesia is greek for memory.

Using Mnesia

Mnesia is the distributed database written in Erlang, meant to mainly be used by Erlang programs. Simple queries can be written with querly list comprehensions (qlc). Realtime queries can decide to not use transactions.

Explain program: art.erl

The program defines some functions that work similar to SQL. We wish to build a table of artwork named "painting", with fields: index, artist, and title.

Table: painting
 
+---------------------------------------------+ 
| index | artist  | title                     |
+---------------------------------------------+  
| 1     | Dali    | The Ghost of Vermeer      |
| 2     | Dali    | The Persistence of Memory |
| 3     | Vermeer | Girl With Pearl Earring   |
+---------------------------------------------+

art:init(). Starts the database and creates the table: painting.
insert() Puts data into the table
select() Gets data out of the table

Note that the second time we call init() the database is restarted but we get an error when it tries to recreate the table (as it already exists).

Example program: art.erl

-module(art).
-compile(export_all).
-include("/usr/lib/erlang/lib/stdlib-1.14.2/include/qlc.hrl"). 
% include is for fedora RH (your path may very)

-record(painting, {index, artist, title}).
 
init() ->
    mnesia:create_schema([node()]),
    mnesia:start(),
    mnesia:create_table(painting,
        [ {disc_copies, [node()] },
             {attributes,      
                record_info(fields,painting)} ]).
 
insert( Index, Artist, Title) ->
        Insert = 
        fun() -> 
	mnesia:write( 
	#painting{ index=Index,
                   artist=Artist, 
                        title=Title    } )
        end, 
	{atomic, Results} = mnesia:transaction(Insert), 
	Results.
  
select( Index) ->
    Query = 
        fun() ->
            mnesia:read({painting, Index})
        end,
    {atomic, [Results]}=mnesia:transaction(Query),
    % io:format(" ~p ~p ~n ", [Row#painting.artist, Row#painting.title] ),
    Results. 

select_some( Artist) ->
    Query = 
        fun() ->
            mnesia:match_object({painting, '_', Artist, '_' } )
        end,
    {atomic, Results} = mnesia:transaction( Query),
    Results.
 
select_all() -> 
    Query =  
    fun() ->
        qlc:eval( qlc:q(
            [ X || X <- mnesia:table(painting) ] 
        )) 
    end,
    {atomic, Results} = mnesia:transaction(Query),
    Results.
  
select_search( Word ) -> 
    Query =  
    fun() ->
         qlc:eval( qlc:q(
              [ {F1,F2,F3,F4} || 
                   {F1,F2,F3,F4} <- 
                        mnesia:table(painting),
                        (string:str(F3, Word)>0) or  
                        (string:str(F4, Word)>0)
               ] )) 
    end,
    {atomic, Results} = mnesia:transaction(Query),
    Results.
    
 start() ->
       art:insert(1,"Dali","The Ghost of Vermeer"),   
       Out1 = art:select(1),
 	
       art:insert(2,"Dali","The Persistence of Memory"),   
       Out2 = art:select(2),               
 
       art:insert(3,"Vermeer", "Girl With Pearl Earring"),   
       
       Out3 = art:select_some("Dali"),           
 
       Out4 = art:select_all(),
       
       Out5 = art:select_search( "Vermeer" ),
       
       [
       {{select,1},Out1}, 
       {{select,2},Out2}, 
       {{select,"Dali"},Out3}, 
       {{select_all},Out4},
       {{select_search,"Vermeer"},Out5}
       ]. 

Output example

18> c(art).     
{ok,art}
19> art:init(). 
{aborted,{already_exists,painting}}
20> art:start().
[{{select,1},{painting,1,"Dali","The Ghost of Vermeer"}},
 {{select,2},{painting,2,"Dali","The Persistence of Memory"}},
 {{select,"Dali"},
  [{painting,1,"Dali","The Ghost of Vermeer"},
   {painting,2,"Dali","The Persistence of Memory"}]},
 {{select_all},
  [{painting,1,"Dali","The Ghost of Vermeer"},
   {painting,2,"Dali","The Persistence of Memory"},
   {painting,3,"Vermeer","Girl With Pearl Earring"}]},
 {{select_search,"Vermeer"},
  [{painting,1,"Dali","The Ghost of Vermeer"},
   {painting,3,"Vermeer","Girl With Pearl Earring"}]}]

Sample output: some interactive cmds

%   Sample output:
 
%   6> c(art).
%   {ok,art}
  
%   7> art:init(). 
%   {atomic,ok}
 
%   6> art:insert(1,"Dali","The Ghost of Vermeer").
%   {atomic,ok}
  
%   7> art:select(1).
%   {painting,1,"Dali","The Ghost of Vermeer"}