Nov/090
Mise en place de Mnesia dans mochiweb
Introduction
Les données de l’applicatif proviennent de plusieurs sources, et sont stockées différemment selon les besoins.
Par exemple, couchDB
ne sera pas utilisé pour stocker les informations d’authentification des utilisateurs. Pour cela, on s’appuiera sur la base de données mnesia
fournie avec erlang
.
Lancement
La première action à faire est de modifier le fichier Rakefile.rb
afin de démarrer le module mnesia
au démarrage de l’application :
task :start => [ :build, 'env:start' ] do system "erl -pa #{EBIN_DIR} #{ROOT}/deps/*/ebin -boot start_sasl -s reloader -s inets -s app -mnesia dir 'db'" end
Les fichiers de données seront stockés dans le répertoire indiqué dans la ligne de commande. Le répertoire sera créé au moment de l’initialisation de la base.
Initialisation
Il est nécessaire ensuite de créer la base elle même. On pourrait ajouter le code nécessaire au niveau de la fonction erlang
de démarrage applicatif. Cependant, on va créer une tâche et une fonction spécifique à cette initialisation. Au démarrage de l’application, on suppose que la base est créée… sinon le système plantera.
Pour cela, on crée une tâche d’initialisation dans le fichier Rakefile.rb
:
namespace 'db' do task :create do system "erl -pa #{EBIN_DIR} -s xxx_db create -mnesia dir 'db' -s init stop" end end
On démarre la fonction create
du module xxx_db
, et les données seront stockées dans le même répertoire que vu précédemment.
Ce module est un fichier créé dans le répertoire des sources src/xxx_db.erl
, et défini ainsi :
-module(xxx_db). -export([create/0]). -include("records.hrl"). (a) create() -> mnesia:delete_schema([node()]), mnesia:create_schema([node()]), (b) mnesia:start(), mnesia:create_table(user, [{disc_copies, [node()]}, {attributes, record_info(fields, user)}]), (c) mnesia:stop().
Une base mnesia
requiert un espace d’adressage qui comporte un certain nombre de propriétés. C’est ce qui est défini dans la création du schéma (b), ici les propriétés par défaut sont positionnées.
On démarre le moteur mnesia
, et on créé les tables nécessaires (c) en suivant les définitions. Ces définitions sont introduites par une directive non vue encore (a) qui permet d’inclure des fichiers de définition. Ce fichier contient la définition des tables et se trouve dans le répertoire source src/records.hrl
. Il a cette forme :
-record(user, {name, password}).
Les records
sont une facilité d’écriture fournie par erlang
et représentent des tuples nommés. Ce fichier sera inclus dans l’applicatif dès que l’on devra manipuler une table mnesia
.
Important : mnesia
considère que le premier champ du record
représente sa clé ! Cette dernière pourra être utilisée pour une interrogation directe.
Note : De même, on peut créer la fonction init/0
qui pré-rempli la base avec des données de référence.
Intégration mochiweb
Mnesia doit être démarré comme tout autre service lors du lancement de notre applicatif. On modifie donc le fichier de démarrage src/xxx_app.erl
afin d’intégrer ce comportement :
start(_Type, _StartArgs) -> application:start(crypto), application:start(mnesia), application:start(ecouch), xxx_deps:ensure(), xxx_sup:start_link(). stop(_State) -> application:stop(ecouch), application:stop(mnesia), application:stop(crypto), ok.
A partir de là, la base mnesia peut être interrogée par l’applicatif. Ces interrogations se font directement par les fonctions de l’API
mnesia
ou bien par le système qlc
basé sur des expressions de listes.