dimanche 21 novembre 2010

La transition entre les SGBDR et les bases NoSQL



Le contenu des bases NoSQL (Not Only SQL ) n'est pas issu d'une génération spontanée. Une grande partie des informations provient des base de données 'traditionnelles'. Comment passer d'un modèle à un autre ?. Des interfaces vont devoir être développées, voici ma contribution : le module nosql.rb disponible sur Lemon-labs (github).

Ce module rassemble des informations d'une base de données (Postgresql , oracle , mysql etc ) et injecte les données dans une base NoSQL (ici couchdb).

Configuration

Le programme utilise un fichier de syntaxe YaML qui va décrire les sources, les filtres à utiliser et la cible.

Datasource:
adapter: sqlite3
database: db/development.sqlite3
poll: 5
timeout : 5000
Tables:
table_fact: projets
primarykey: id
table_dimension:
filieres:
primarykey: id
foreignkey: filiere_id
technos:
primarykey: id
foreignkey: techno_id
filters:
attributes: id
regexp: create,_id,update
append:
attribute: type,ROW
options:
NoNil: 1
target:
# output: 1
couchdb: http://localhost:5984/projets
Avec les paragraphes suivants:
  • Datasource : c'est l'accès à la base de données relationnelle. Sa syntaxe est celle ActiveRecord de Rails.
  • Table : la première partie décrit la table principale (ou table de fait) . La suivante liste toutes les tables de détails (dimension) et les champs utilisés pour les liens.
  • Filter: le programme constitue un tableau associatif pour la ligne à créer. Les filtres servent à supprimer des champs (exemple : les champs des clés primaires ou étrangères)
  • Append: Cet option ajoute des attributs fixes (exemple : type de ligne)
  • Options : fixe les règles de gestion des champs vides.
  • Target : précise la base NoSQL à charger.

Le programme va récupérer les informations sur les tables, les champs et les liens entre les tables.
Ligne par ligne, le module va entièrement dénormaliser la base pour ensuite l'injecter dans une base NoSQL.


API REST
Le module nosql.rb est associé avec un module nosqlonweb.rb qui lui ajoute un format d'API REST.



Le menu delete_row permet de supprimer toutes les entrées d'une base NoSQL sauf les documents de restitutions.

Le lancement du module web se fait par la commande :
ruby nosqlonweb.rb . Le framework utilisé est 'sinatra'.
L'API retourne ses résultats au format JSON.

Bases supportées
L'utilisation d'active record rend le programme compatible avec la majorité des bases de données. PostgreSQL, Oracle , SQLite, Mysql etc.

Les conséquences de l'annonce d'apple d'inclure une carte SIM dans ses produits


Apple travaille pour doter ses produits (surtout l'iphone) d'une carte SIM native et scellée (non amovible et non modifiable). Cette annonce à déclenchée des gros remous pas seulement dans le monde de la téléphonie. Actuellement un téléphone mobile c'est un portable et un carte SIM délivrée par un opérateur (SFR, Orange etc.) . Cette carte SIM contient deux types d'information: un numéro d'identification international unique (IMSI) et des informations de chiffrement.
Les premiers caractères d IMSI correspondent à l'identifiant de l'opérateur (comme une adresse MAC) .
Quand vous vous rendez à l'étranger:
Votre portable (SFR) se connecte à un relais (VODAFONE) et présente le IMSI , L'opérateur VODAFONE interroge un centre SFR pour savoir si vous avez l'autorisation de SFR d'utiliser votre portable à l'étranger. Si c'est le cas des accords de réciprocité existants entre les opérateurs font que vous pouvez utiliser les réseaux des autres opérateurs à l'étranger sans aucunes formalités.

Que veut faire APPLE :

Apple veux être référencé comme un opérateur téléphonique et que l'APPLE STORE serve d'intermédiaire entre vous et les opérateurs locaux.
Ainsi,il vous sera possible de choisir par le biais de l'APPLE STORE une formule de téléphone (à la journée, semaine , année etc.). Votre mobile sera considéré comme un mobile 'etranger'.

D'autant APPLE n'est pas obligé d'être un vrai opérateur. La firme peut acheter un ilot du pacifique et y mettre une antenne relais et ainsi accéder au statut d'opérateur et bénéficier des accords de réciprocités.

On comprend que cela risque de bouleverser le marché de la téléphonie. D'autant que la carte SIM intégrée permettrait d'être utilisée dans le cadre d'un réseau WIFI ou de mobile à mobile (M2M) et toujours en passant par l'APPLE STORE....
Les opérateurs traditionnels seront relégués à de simples tuyaux.

La stratégie de APPLE passe par le tiroir caisse de l'APPLE Store
Pour Google , l'objectif est plus simple: indexer du contenu et vendre des mots clés aux enchères.
Cela implique l'utilisation de leur OS android sur les mobiles, de la géolocalisation et de la segmentation des utilisateurs. Google travaille surement sur l'indexation des flux vocaux (conversation téléphonique).

jeudi 18 novembre 2010

Le web au bout des doigts:htty




Pour faire du web en ligne de commande il y a le client vintage 'lynx' , la petite commande 'wget'. Le produit le plus puissant du moment est 'curl' qui est devenu le client incontournable des API REST. Il existe maintenant un produit hybride 'htty'. Ce programme permet de faire du web en ligne de commande de manière interactive. Il fonctionne de la même manière qu'un telnet :

ex :

root@eric-1001PX:~# htty google.fr
*** Welcome to htty , the HTTP TTY. Heck To The Yeah!
http://google.fr/> cd images
http://google.fr/images> get
*** Type fol[low] to follow the 'Location' header received in the response
301 Moved Permanently -- 8 headers -- 224-character body
http://google.fr/images> body

301 Moved

301 Moved


The document has moved
here.

http://google.fr/images>



htty reconnait les commandes : cd , get body
Il permet d'examiner les entetes, les réponses, les cookies etc.





En cas d'erreur au lancement de la commande htty :
'require no such file to load -- readline (LoadError)'


faire

cd //ext/readline
2 ruby extconf.rb
3 make
4 sudo make install

jeudi 4 novembre 2010

Le grand retour du 33 tours


Je me suis rendu hier dans une FNAC et à mon grand étonnement, j'ai constaté un agrandissement important du rayon des disques vinyles 33 tours. Tous les week-end, des brocantes spécialisées sur ce thème, offrent aux nostalgiques de quoi assouvir leur passion.
(a signaler : Parc Brassens (15eme) jeudi 11/11 :5ème Marché du disque de collection)

C'est vraiment un phénomène étrange. Alors pourquoi ce renouveau ?

Pour l'objet en tant que tel :
  • Une pochette de 33 tours offre une surface et support agréable à opposer à la taille d'un CD.
  • Un disque vinyle doit se manipuler avec précaution et inspire le respect.
  • Il est facile d'établir un rapport direct entre le disque et la musique qu'il embarque. On 'voit ' la musique, l'avancement du bras de lecture sur le sillon.

Sur le mode d'écoute.
Il y a tout un rituel pour écouter un disque, il faut être patient, pas moyen de zapper facilement d'un morceau à l'autre.

ET pour les jeunes: les DJ sont restés accrochés à leurs bonnes vieilles platines , vive le scratching, geste technique sans aucune signification sur un lecteur de CD.

Les 33 tours qui sont toujours édités représentent des valeurs "sures", le ménage a été fait, il ne reste que les piliers de la musique.

Alors tous à vos platines:



dimanche 31 octobre 2010

Comment créer des vues dans couchdb

Chaque base de données de couchdb propose un répertoire '_design' qui hébergera les vues et les listes liées à votre base.
Les vues sont destinées à restituer les données sans formatage. Les 'shows' et les 'lists' mettent en forme les données. Le 'show' ne s'applique qu'a une entrée à l'inverse de la 'list' qui porte sur un groupe de données.

Concrètement le source des vues est un document JSON. Il faut a chaque fois, récupérer le document source, le modifier et le recharger sur couchdb.



{"_id":"_design/tablefait","_rev":"12-bf5c8cb0de5d7c352af03cb8ea45e8b6",
"language":"javascript",
"views":{
"cam-an-mois":{"map":"function(doc)
{if (doc.TYPE ==\"RAW\") {emit ([doc.campagne,doc.annee,doc.mois], doc); } }"}},
"lists":
{"indexml":"function (head, req)
{ var row;
start({ \"headers\":{\"Content-Type\" : \"application/xml\" }
});
send(\"<entries>\");
while(row = getRow())
{
var xml= new XML (\"<entry/>\");
xml.campagne=row.value.campagne; xml.annee=row.value.annee;
xml.mois=row.value.mois; send(xml);
}
send(\"</entries>\");
}"
}
}



Ici 'tablefait' est le nom du groupe de restitution, 'cam-an-mois' est le nom de la vue qui va servir à restituer les entrées suivant des clés d'index. Enfin 'indexml' est la fonction javascript à appliquer pour formater les résultats.





Utilisation d'une vue sans formatage particulier :
Par un navigateur : http.... 5984/db/_design/tablefait/_view/cam-an-mois?[2010,2010,09]


Avec le formatage XML

Par un navigateur : http.... 5984/db/_design/tablefait/_list/indexml/cam-an-mois?[2010,2010,09]


Attention la construction de l'url est fonction de la version de couchDB.


Les difficultés d'écriture d'une fonction de formatage sont les suivantes:

  • Le javascript de la fonction de formatage sera stocké dans une chaine de caractère. Les quotes sont à protéger par des '\'.
  • A chaque mise au point, le numéro de révision sera à ajuster.

Pour gérer ces problèmes plusieurs solutions sont possibles et seront présentées prochainement.

samedi 30 octobre 2010

Pour aller plus loin avec couchdb: la compilation

J'avais fait quelques ( posts sur le sujet) . Très vite, la manipulation de couchdb nécessite des bouts de javascript et du JSON. Je veux par exemple produire des données sous forme XML, ou proposer des vues avec des mises en page. Pour cela il faudra modifier les listes ou les vues dans couchdb.

La première précaution à prendre est de travailler avec la dernière version de couchdB. La gestion des listes et des vues a évolué d'une version à l'autre.
Pour installer une version récente de couchdb , il faudra probablement mettre à jour votre version de Erlang.


Le lancement de la commande ./configure dans l'archive de couchdb doit produire les erreurs suivantes:
La compilation de couchdb va chercher à résoudre les dépendances dont celle ci :
Is the Mozilla SpiderMonkey library installed?

spidermonkey est le moteur javascript de Firefox. Son installation complète se teste par la commande 'js' (librairie et l'interpréteur) .
Son installation se fait par:
apt-get install libmozjs-dev
Puis vient le tour de la librairie 'international character'
apt-get install libicu-dev

Enfin l'utilitaire 'curl' : c'est avec lui que se fait les premiers essais avec couchdb

apt-get install libcurl4-openssl-dev

Tout ca pour arriver au message :
configure: error: The installed Erlang version is less than 5.6.5 (R12B05).

Vous allez devoir vous payer une petite compilation du langage Erlang.

Rien de bien compliqué , juste un configure , make , make install dans le repertoire otp_src_Rnn

Puis revenir à la compilation de couchdb en précisant :
./configure --with-erlang=/usr/local/bin

Ok tout est bon le make et make install terminent l'opération. Le répertoire /usr/local/bin doit contenir au minimum erl et couchdb.





jeudi 21 octobre 2010

Ceci est un post sur la recursion dans un post sur la recursion


On distingue deux formes de récursion : La recursion directe ou indirecte.

Dans la récursion directe (exemple en ruby) la fonction s'appelle directement.

def facdir(n)
return 1 if n==1
return (n * facdir(n-1))
end


La fonction fac s'appelle en se transmettant le paremetre n-1

Dans la méthode indirecte , la fonction s'appelle aussi , mais elle va se transmettre son contexte
en plus de son parametre normal.
Pour une fonction simple , le contexte sera limité à une variable destinée à accueillir le résultat.


Exemple :


def facind_r(n,prod)
return prod if n==1
return facind_r(n-1,n*prod)
end


La variable 'prod' est le 'contexte'.

L'appel de la fonction se fera par :

def facind(n)
facind_r(n,1)
end



La méthode indirecte est meilleure que la méthode directe.
A l'appel d'une itération le système n'a pas besoin de mettre
dans la pile l'appel de la fonction CAR AUCUNE opération ne sera à réaliser à son retour.







En Haskell :


module Main where

facdir :: Int -> Int
facdir 1 = 1
facdir n = n * facdir(n-1)


facind :: Int ->Int
facind n = facind_r (n,1)

facind_r :: (Int,Int) -> Int
facind_r (1,prod) = prod
facind_r (n,prod) = facind_r( n-1, n* prod )




En Erlang:


-module (fac2).
- export([facdir/1,facind/1]).

facdir(1) -> 1;
facdir(N) -> N * facdir(N-1).

facind(N) -> facind_r(N,1).
facind_r(1,Prod) -> Prod;
facind_r(N,Prod) -> facind_r(N-1,N*Prod).