Le petit coin de Nicolas

Aller au contenu | Aller au menu | Aller à la recherche

CouchDB

Créer votre première application CouchDB (Partie 4)

Pour ceux qui utiliserait le code mis dans les exemples, sachez qu'à partir de la version 0.10, le contenu du fichier lists/all.js qui s'écrivait :

function(head, row, req, info) {
  // !json templates.all
  // !code vendor/couchapp/path.js
  // !code vendor/couchapp/template.js
 
  return respondWith(req, {
    html : function() {
      if (head) {
        return template(templates.all.head, {
          assets : assetPath(),
        });
      } else if (row) {
        return template(templates.all.row, {
          fav: row.value,
        });
      } else {
        return template(templates.all.tail, {
            assets : assetPath(),
        });
      }
    },
  })
};

s'écrit désormais :

function(head, req) {
  // !json templates.all
  // !code vendor/couchapp/path.js
  // !code vendor/couchapp/date.js
  // !code vendor/couchapp/template.js
  // !json myfav
 
  provides("html", function() {
      
      send(template(templates.all.head, {
          assets : assetPath(),
          title : myfav.title,
       }));
      
      var row, key;
      while (row = getRow()) {
        key = row.key;
        var fav = row.value;
        send(template(templates.all.row, {
            url: fav.url,
            title: fav.title,
            description: fav.description,                      
        }));
      }
      
      return template(templates.all.tail, {
            assets : assetPath(),
      });
  });
};

et bien sur templates/all/row.html devient :

<dt><a href="<%= url %>"><%= title %></a></dt>
<dd><%= description %></dd>

Au passage, il m'a fallu récupérer la nouvelle version de vendor/couchapp/path.js.

Pour ceux que ça intéresse, le code est disponible ici : http://bitbucket.org/nsteinmetz/mycouchfav/.

Pour ceux qui veulent voir le rendu :

Voilà, c'était histoire de me remotiver dans cette prise en main de CouchDB/CouchApp - peut-être que la prochaine fois, on verra un formulaire de soumission de favoris... ;-)

CouchDB 0.10.1 on Slackware 13.0

Dépendances de CouchDB

Dans un premier temps, il vous faut récupérer les slackbuilds suivants :

Les autres dépendances sont normalement satisfaites :

  • curl : à vérifier en utilisant un curl-config --version
  • make & gcc

Créer les packages des slackbuids (les slackbuils sont prévus pour i486 ; si vous êtes en 64 bits, éditer le fichier <package>.Slackbuild pour modifier la valeur de ARCH.

Pour que le SlackBuild fonctionne, il vous faut mettre l'archive des sources du package à créer dans le répertoire créé en décompressant le fichier slackbuild.

tar xzf js.tar.gz
cd js
./js.SlackBuild
=> Slackware package /tmp/js-1.8.0_rc1-x86_64-1_SBo.tgz created.
 
tar xzf icu4c.tar.gz
cd ../icu4c
./icu4c.SlackBuild
=> Slackware package /tmp/icu4c-4.2.1-x86_64-1_SBo.tgz created
 
tar xzf erlang-otp.tar.gz
cd erlang-otp
./erlang-otp.SlackBuild
=> Slackware package /tmp/erlang-otp-13B03-x86_64-1_SBo.tgz created.

Installer ensuite les packages créés :

nicolas@cassis:/tmp$ sudo installpkg icu4c-4.2.1-x86_64-1_SBo.tgz 
Verifying package icu4c-4.2.1-x86_64-1_SBo.tgz.                   
Installing package icu4c-4.2.1-x86_64-1_SBo.tgz:                  
PACKAGE DESCRIPTION:                                              
# icu4c (International Components for Unicode)                    
#                                                                 
# The International Components for Unicode (ICU) libraries provide
# robust and full-featured Unicode services on a wide variety of  
# platforms.                                                      
#                                                                 
# Homepage: http://www.icu-project.org/                           
#                                                                 
Executing install script for icu4c-4.2.1-x86_64-1_SBo.tgz.        
Package icu4c-4.2.1-x86_64-1_SBo.tgz installed.                   
 
nicolas@cassis:/tmp$ sudo installpkg js-1.8.0_rc1-x86_64-1_SBo.tgz
Verifying package js-1.8.0_rc1-x86_64-1_SBo.tgz.
Installing package js-1.8.0_rc1-x86_64-1_SBo.tgz:
PACKAGE DESCRIPTION:
# SpiderMonkey (Mozilla's JavaScript Engine)
#
# SpiderMonkey is the code-name for the Mozilla's C implementation of
# JavaScript. It can be used by applications such as elinks and others.
#
# This is the standalone version of the engine used by Firefox and other
# Mozilla applications.
#
# Homepage: http://www.mozilla.org/js/spidermonkey
#
Package js-1.8.0_rc1-x86_64-1_SBo.tgz installed.
 
nicolas@cassis:/tmp$ sudo installpkg erlang-otp-13B03-x86_64-1_SBo.tgz
Verifying package erlang-otp-13B03-x86_64-1_SBo.tgz.
Installing package erlang-otp-13B03-x86_64-1_SBo.tgz:
PACKAGE DESCRIPTION:
# Erlang (programming language)
#
# Erlang is a general-purpose concurrent programming language and
# runtime system.
# The sequential subset of Erlang is a functional language,
# with strict evaluation, single assignment, and dynamic typing.
# It was designed by Ericsson to support distributed,
# fault-tolerant, soft-real-time, non-stop applications.
#
# http://www.erlang.org/
#
Executing install script for erlang-otp-13B03-x86_64-1_SBo.tgz.
Package erlang-otp-13B03-x86_64-1_SBo.tgz installed.

Installation de CouchDB

Il vous faut au préalable créer un utilisateur et un groupe couchdb :

groupadd -g 231 couchdb
useradd -u 231 -g couchdb -d /var/lib/couchdb -s /bin/sh couchdb

Récupérer le slackbuild de CouchDB

il vous faut alors procéder de la façon suivante :

tar xzf couchdb.tar.gz
cd couchdb
# récupérer les sources de couchdb 0.10.1 et metter les dans votre répertoire couchdb
# éditer si besoin le SlackBuild
# créer votre package :
./couchdb.Slackbuild
=> Slackware package /tmp/SBo/couchdb-0.10.1-x86_64-1_SBo.tgz created.

Il ne reste plus qu'à installer le paquet :

installpkg /tmp/SBo/couchdb-0.10.1-x86_64-1_SBo.tgz

Démarrage / Arrêt automatique de CouchDB

Editer /etc/rc.d/rc.local pour y ajouter :

if [ -x /etc/rc.d/rc.couchdb ]; then
	. /etc/rc.d/rc.couchdb start
fi

et dans /etc/rc.d/rc.local_shutdown :

if [ -x /etc/rc.d/rc.couchdb ]; then
	. /etc/rc.d/rc.couchdb stop
fi

Ouvrez http://localhost:5984/_utils/

Et voilà... il est maintenant temps de vous relaxer ;-)

Edit 1 : Mise à jour suite à l'approbation & correction de mon slackbuild sur Slackbuilds.org

Couchapp : créer votre première application CouchDB (Partie 3)

Devant la "foule" de commentaires (hum), je continue (tout seul) mon épopée dans les méandres de CouchDB.

Dans les points non traités la dernière fois, nous allons voir ce jour :

  • Voir comment on peut remplacer le "My favs ... " dans head.html par une variable extérieure au template (facile - déjà fait mais cela rajoutait une grande quantité d"infos à ce post déjà très long je pense...),
  • Mieux comprendre les "!json" et "!code".

Externaliser le "My favs ..."

Commençons par créer un fichier "myfav.json" à la racine du projet contenant, qui contiendra une valeur qui sera utilisé dans la balise title et en tête de page du site :

{
   "title": "My favs - All my bookmarks."
}

Ensuite dans "list/all.js", nous avons deux actions à mener :

  • Faire en sorte que ce fichier soit lu lors de la création de la liste, afin de récupérer la valeur de "title",
  • Mettre à la disposition du template la valeur title contenu dans myfav.json.

Ce qui nous donne :

function(head, row, req, info) {
  // !json templates.all
  // !code vendor/couchapp/path.js
  // !code vendor/couchapp/template.js
  // !json myfav
 
  return respondWith(req, {
    html : function() {
      if (head) {
        return template(templates.all.head, {
          assets : assetPath(),
          title : myfav.title,
        });
      } else if (row) {
        return template(templates.all.row, {
          fav: row.value,          
        });
      } else {
        return template(templates.all.tail, {
            assets : assetPath(),
        });
      }
    },
  })
};

Dans la mesure où je ne veux faire apparaître la valeur de "title" que pour la balise <title></title> et en tête de page, je n'ai besoin de le fournir que pour le template head.

D'ailleurs le fichier templates/all/head.html devient :

<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" href="../../style/main.css" type="text/css"/>
    <title><%= title %></title>
  </head>
  <body>
    <div id="header">
        <h1><%= title %></h1>
    </div>
    <div id="content">
      <h2>Recently...</h2>
      <dl>

Si vous rajoutez par ex <%= title %> dans templates/all/row.html en pensant que la valeur sera renseignez et bien vous vous trompez et provoquerez une jolie erreur au niveau de CouchDB.

Faites un push de votre application et rendez-vous ensuite sur http://localhost:5984/myfav/_design/mycouchfav/_list/all/favs/ pour apprécier le résultat.

Dans la même veine, il vous reste à modifier "shows/fav.js" et "templates/fav.html" ; par contre, utilisant déjà la variable title pour le titre du favori, j'utilise à la place la variable site_title :

function(doc, req) {  
  // !json templates.fav
  // !code vendor/couchapp/template.js
  // !code vendor/couchapp/path.js
  // !json myfav
 
  // we only show html
  return template(templates.fav, {
    title : doc.title,
    url : doc.url,
    description : doc.description,
    assets : assetPath(),
    site_title : myfav.title,
  });
}
<!DOCTYPE html>
<html>
  <head>
    <title><%= title %> - <%= site_title %></title>
    <link rel="stylesheet" href="../../style/main.css" type="text/css">
  </head>
  <body>
    <div id="header">
        <h1><%= site_title %></h1>
    </div>
    <div id="content">
      <h2><a href="<%= url %>"><%= title %></a></h2>
        <div class="body"><%= description %></div>
    </div>    
  </body>
  <script src="/_utils/script/json2.js"></script>
  <script src="/_utils/script/jquery.js?1.2.6"></script>
  <script src="/_utils/script/jquery.couch.js"></script>
  <script src="<%= assets %>/vendor/couchapp/jquery.couchapp.js"></script>
</html>

Faites un push de votre application et rendez-vous ensuite sur http://localhost:5984/myfav/_design/mycouchfav/_show/fav/couchdbkit pour apprécier le résultat.

Mieux comprendre "!json" et "!code"

Grosso modo, !code et !json ont la même objectif : insérer des données dans votre vue. La différence tient dans le fait que !code injecte du code alors que !json injecte des données ou des fichiers (en utilisant par ex !json _attachments/file.ext).

De même, attention lors de vos inclusions : dans le cas d'une arboresence, si vous appelez un élément de premier niveau, alors tous ses sous-niveaux seront inclus. L'écriture suivante est donc redondante :

function(doc) {
  // !json lib
  // !json lib.templates.post
}

Pour plus d'info, voir la fin de cette page.

Voilà pour aujourd'hui, suite au prochain épisode...

Couchapp : créer votre première application CouchDB (Partie 2)

La dernière fois, je vous ai laissé avec pas grand chose, à savoir couchapp installé et une squelette d'application.

Aujourd'hui, nous allons être nettement plus ambitieux en prenant comme prétexte une application de gestion de favoris (à la delicious, en mode mono-utilisateur). Nous allons aborder le rendu d'un document en tant que tel (aka "show") et les listes de documents (aka "list").

Avant toute chose... couchapp !

Générons notre petite application :

couchapp-cloned	mycouchapp
tetram:CouchDB nicolas$ couchapp generate mycouchfav
[INFO] Generating a new CouchApp in /Users/nicolas/Documents/Projets/CouchDB/mycouchfav

Et poussons notre application dans notre instance CouchDB (que vous avez démarré par ailleurs) :

tetram:CouchDB nicolas$ cd mycouchfav/
tetram:mycouchfav nicolas$ couchapp push myfav
[INFO] Pushing CouchApp in /Users/nicolas/Documents/Projets/CouchDB/mycouchfav to design doc:
http://127.0.0.1:5984/myfav/_design/mycouchfav
[INFO] Visit your CouchApp here:
http://127.0.0.1:5984/myfav/_design/mycouchfav/index.html

Vinrent ensuite les documents

Commençons par nous créer trois favoris depuis Futon ( http://localhost:5984/_utils/) avec la structure suivante :

  • title
  • url
  • description
  • tag

Ci-après mon jeu d'exemple au format json :

{
   "_id": "couchdb",
   "title": "CouchDB Official site",
   "url": "http://couchdb.apache.org/",
   "description": "Apache CouchDB is a distributed, fault-tolerant and schema-free document-oriented database accessible via a RESTful HTTP/JSON API",
   "tag": [
       "couchdb",
       "database",
       "document"
   ]
}
 
{
   "_id": "couchdbkit",
   "title": "Couchdbkit",
   "description": "Couchdbkit goal is to provide a framework for your Python application to access and manage Couchdb.",
   "url": "http://www.couchdbkit.org/",
   "tag": [
       "couchdb",
       "python",
       "framework"
   ]
}
 
{
   "_id": "couchapp",
   "title": "couchapp",
   "description": "Utilities to make standalone CouchDB application development simple",
   "url": "http://github.com/couchapp/couchapp/tree/master",
   "tag": [
       "couchdb",
       "python",
       "ruby"
   ]
}


Tu me le montres ton document ?

L'url pour accéder à un document est du type :

http://localhost:5984/<nom_de_la_db>/_design/<nom_du_design>/_show/<nom_du_show>/<id_du_document>

Dans notre cas, par ex : http://localhost:5984/myfav/_design/mycouchfav/_show/fav/couchdbkit (si je prends le favori ayant pour id "couchdbkit".

Vous venez de déduire que mon "show" se nomme "fav". Plus exactement, il s'agit du fichier show/fav.js avec le contenu suivant :

function(doc, req) {  
    // !json templates.fav
    // !code vendor/couchapp/template.js
    // !code vendor/couchapp/path.js
 
    return template(templates.fav, {
        title : doc.title,
        url : doc.url,
        description : doc.description,
        assets : assetPath(),
       }
    );
}

Expliquons ce qu'il contient :

  • Pour un show, la fonction js prend 2 arguments : doc et req ; ce dernier content la requête et va trouver le document associée à cette requête.
  • On initialise une variable json, qui est utilisée ensuite pour appelé le template templates/fav.html
  • On inclut ensuite 2 fichiers js fournis par couchapp
  • Le return indique que l'on va charger le fichier templates/fav.html avec 4 variables qui sont le titre (title), l'url, la description du favori, ainsi qu'une variable assets qui permet de renseigner un chemin vers différents fichiers (css, js, etc).

Il nous resque plus qu'à construire le fichier templates/fav.html :

<!DOCTYPE html>
<html>
    <head> 
        <title><%= title %></title>
    </head>
    <body>
    <div id="header"></div>
    <div id="content">
        <h1><a href="<%= url %>"><%= title %></a></h1>
        <div class="body"><%= description %></div>
    </div>    
</body>
<script src="/_utils/script/json2.js"></script>
<script src="/_utils/script/jquery.js?1.2.6"></script>
<script src="/_utils/script/jquery.couch.js"></script>
<script src="<%= assets %>/vendor/couchapp/jquery.couchapp.js"></script>
</html>

Il ne nous reste plus qu'à .... et non pas visualiser votre page mais au préalable pousser vos fichiers dans votre instance CouchDB :

tetram:mycouchfav nicolas$ couchapp push myfav
[INFO] Pushing CouchApp in /Users/nicolas/Documents/Projets/CouchDB/mycouchfav to design doc:
http://127.0.0.1:5984/myfav/_design/mycouchfav
[INFO] Visit your CouchApp here:
http://127.0.0.1:5984/myfav/_design/mycouchfav/index.html

Maintenant, ouvrez votre navigateur sur l'url http://localhost:5984/myfav/_design/mycouchfav/_show/fav/couchdbkit et vous retrouvez le contenu très sommairement présenté de votre favori avec son titre, son url et sa description.

En conclusion, pour afficher un document, il nous faut :

  • Un template (ici : templates/fav.html)
  • Une fonction en javascript qui nous permet de manipuler les attributs du documents en vue de leur rendu. La fonction est de type function(doc,req). La fonction est située dans un fichier shows/nom_du_show.js (ici shows/fav.js)
  • Ne pas oublier de faire un "couchapp push" pour envoyer vos fichiers dans votre instance CouchDB
  • Une url du type : http://localhost:5984/<nom_de_la_db>/_design/<nom_du_design>/_show/<nom_du_show>/<id_du_document>

Et ta liste, tu me la montres aussi ?

Pour les listes, c'est un peu plus complexe mais pas insurmontable :-)

L'url est du type :

http://localhost:5984/<nom_de_la_db>/_design/<nom_du_design>/_list/<nom_de_la_liste>/<nom_de_la_vue>?<paramètres>

Supposons que je veuille créer la page d'accueil de mon application, celle-ci listant tous les favoris stockés. Le nom de la liste pourrait donc tout naturellement s'appeller "all" et le nom de la vue "favs". On pourrait imaginer avoir une liste "search" par ex pour afficher les résultats d'une recherche sur les favoris avec des paramètres de recherche.

Il faut donc bien avoir en tête qu'une liste est un moyen d'afficher une vue. Une même vue peut donc partager plusieurs listes.

Ex :

http://localhost:5984/myfav/_design/mycouchfav/_list/all/favs
http://localhost:5984/myfav/_design/mycouchfav/_list/search/favs?limit=25&key=%22python%22

Commençons donc par créer notre vue, avec le fichier views/favs/map.js

function(doc) {
    emit(doc._id, {title: doc.title, description: doc.description, url:doc.url })   
};

Cette fonction me renvoi tous les documents de mon instance, trié par "_id" et avec une série de variables (title, description, url - je ne les réexplique pas, ce sont les mêmes que précédemment).

Passons à notre liste : lists/all.js

Note : Pour ceux qui son en CouchDB >= 0.10.x, le code est à récupérer dans ce billet. Le code ci-dessous est valable pour CouchDB 0.9.x

function(head, row, req, info) {
  // !json templates.all
  // !code vendor/couchapp/path.js
  // !code vendor/couchapp/template.js
 
  return respondWith(req, {
    html : function() {
      if (head) {
        return template(templates.all.head, {
          assets : assetPath(),
        });
      } else if (row) {
        return template(templates.all.row, {
          fav: row.value,
        });
      } else {
        return template(templates.all.tail, {
            assets : assetPath(),
        });
      }
    },
  })
};

La nouveauté ici tient dans la fonction qui prend différents paramètres en compte (contenus honteusement récupérés de benoitc "Légo 2 : les listes"):

  • head: est renseigné lorsque couchdb envoie la tête de la vue. head est un objet contenant les paramètres "total-rows" et "offset" correspondant au résultat de la vue. Cela nous permet, par exemple comme dans l'exemple ci-dessus, afficher l'entête d'une page html en chargeant un template particulier.
  • row : la ligne de la vue actuellement envoyée par CouchDB.
  • req : un objet contenant les paramètres de la requête
  • row_info : un objet contenant les infos sur la ligne en cours, sa position, quel était la ligne précendente, quelle est la première ligne de la vue.

L'autre nouveauté tient dans la gestion des templates HTML :

  • Pour head, on va charger templates/all/head.html
  • Pour chaque ligne de résultat, on va charger templates/all/row.html
  • Une fois que les résultats de la requête sont épuisés, on va charger templates/all/tail.html (qui fait donc office de voiture-balai).

Contenu de templates/all/head.html :

<!DOCTYPE html>
<html>
  <head>
    <title>My favs</title>
    <link rel="stylesheet" href="../../screen.css" type="text/css"/>
  </head>
  <body>
    <div id="header">
      <h2>My favs...</h2>
    </div>
    <div id="content">
      <h1>Recently...</h1>
      <dl id="bookmarks">

Contenu de templates/all/row.html :

  <dt><a href="<%= fav.url %>"><%= fav.title %></a></dt>
  <dd><%= fav.description %></dd>

Contenu de templates/all/tail.html :

    </dl>
  </div>
</body>
<script src="/_utils/script/json2.js"></script>
<script src="/_utils/script/jquery.js"></script>
<script src="/_utils/script/jquery.couch.js"></script>
<script src="<%= assets %>/vendor/couchapp/jquery.couchapp.js"></script>
</html>

Il ne vous reste plus qu'à pousser vos modifications dans votre instane CouchDB (ici en mode verbeux pour bien voir ce qui est poussé) :

tetram:mycouchfav nicolas$ couchapp push -v myfav
[INFO] push lists/all.js
[INFO] push shows/fav.js
[INFO] push templates/all/head.html
[INFO] push templates/all/row.html
[INFO] push templates/all/tail.html
[INFO] push templates/fav.html
[INFO] push vendor/couchapp/_attachments/jquery.couchapp.js
[INFO] push vendor/couchapp/couchapp.js
[INFO] push vendor/couchapp/date.js
[INFO] push vendor/couchapp/path.js
[INFO] push vendor/couchapp/README.md
[INFO] push vendor/couchapp/template.js
[INFO] push views/favs/map.js
[INFO] process code macro: /Users/nicolas/Documents/Projets/CouchDB/mycouchfav/vendor/couchapp/template.js
[INFO] process code macro: /Users/nicolas/Documents/Projets/CouchDB/mycouchfav/vendor/couchapp/path.js
[INFO] process code macro: /Users/nicolas/Documents/Projets/CouchDB/mycouchfav/vendor/couchapp/path.js
[INFO] process code macro: /Users/nicolas/Documents/Projets/CouchDB/mycouchfav/vendor/couchapp/template.js
[INFO] Pushing CouchApp in /Users/nicolas/Documents/Projets/CouchDB/mycouchfav to design doc:
http://127.0.0.1:5984/myfav/_design/mycouchfav
[INFO] Visit your CouchApp here:
http://127.0.0.1:5984/myfav/_design/mycouchfav/index.html

Rendez vous ensuite sur : http://localhost:5984/myfav/_design/mycouchfav/_list/all/favs

Au bout du compte, nous venons de voir pour les listes :

  • Les listes comme moyen d'afficher une vue,
  • Cela se traduit par un fichier de vue (views/mon_de_ma_vue/map.js) et un fichier liste (lists/<nom_de_ma_liste>.js)
  • La liste est une fonction de type function(head, row, req, info)
  • On peut spliter les templates en head.html / row.html / tail.html
  • url de type : http://localhost:5984/<nom_de_la_db>/_design/<nom_du_design>/_list/<nom_de_la_liste>/<nom_de_la_vue>?<paramètres>

Au bout de cette "journée"

Nous avons vu aux termes des parties 1 et 2 :

  • Comment installer couchapp et générer le squelette d'une application Couchdb
  • Jouer un peu avec Futon pour créer des enregistrements dans CouchDB (même si je ne le couvre pas directement, voir pas du tout en fait)
  • Comment afficher des documents sous forme de "list/views" pour une collection de documents et de "show" pour un document de façon unitaire

Il reste encore plein de choses à voir (au moins à mon niveau) :

  • Voir comment on peut remplacer le "My favs ... " dans head.html par une variable extérieure au template (facile - déjà fait mais cela rajoutait une grande quantité d"infos à ce post déjà très long je pense...)
  • Mieux comprendre les "!json" et "!code"
  • Les options de tri
  • <insérer votre sujet ici via un commentaire>
  • ...

Sources utiles

Les lectures indispensables pour faire ce tutoriel :

Au passage, les nouveautés de CouchDB / Couchapp mentionnées pat Benoit sont des plus intéressantes (surtout pour les listes, plus souple/flexible a priori).

Merci à benoitc pour éclairer ma lanterne sur couchdb/couchapp ces derniers jours :-)

Couchapp : créer votre première application CouchDB (Partie 1)

Je continue ma découverte de CouchDB avec Couchapp, logiciel qui se définit comme un ensemble d'outils pour simplifier le développement d'une application avec CouchDB.

Ce billet chercher à compléter / mettre à jour le billet de Benoit Chesneau : "Et les légos s'emboitèrent" que je vous conseille de lire par ailleurs.

Installation de Couchapp

tetram:CouchDB nicolas$ sudo easy_install couchapp

Cela vous installe couchapp 0.3.2 à ce jour.

Génération du squelette de votre application

tetram:CouchDB nicolas$ couchapp generate mycouchapp
[INFO] Generating a new CouchApp in /Users/nicolas/Documents/Projets/CouchDB/mycouchapp

Le contenu est le suivant :

tetram:CouchDB nicolas$ ls mycouchapp/
_attachments	lists		vendor
lib		shows		views

Pour pousser votre application dans votre instance CouchDB dans une base "monapp" :

tetram:CouchDB nicolas$ cd mycouchapp/
tetram:mycouchapp nicolas$ couchapp push monapp -v
[INFO] push vendor/couchapp/_attachments/jquery.couchapp.js
[INFO] push vendor/couchapp/couchapp.js
[INFO] push vendor/couchapp/date.js
[INFO] push vendor/couchapp/path.js
[INFO] push vendor/couchapp/README.md
[INFO] push vendor/couchapp/template.js
[INFO] Pushing CouchApp in /Users/nicolas/Documents/Projets/CouchDB/mycouchapp to design doc:
http://127.0.0.1:5984/monapp/_design/mycouchapp
[INFO] Visit your CouchApp here:
http://127.0.0.1:5984/monapp/_design/mycouchapp/index.html
[INFO] Attaching index.html (413)
[INFO] Attaching style/main.css (21)
[INFO] Attaching vendor/couchapp/jquery.couchapp.js (6984)

Si vous ouvrez votre navigateur sur http://127.0.0.1:5984/monapp/_design/mycouchapp/index.html, vous voyez l'écran suivant :

Couchapp-1.png

A ce stade, 2 commandes ont été utilisées :

  • generate : crée le squelette d'application
  • push : envoie l'application dans couchdb

Si vous voulez récupérer une application de couchdb, il faut utiliser la commande "clone". Cela permet d'éditer votre application couchdb depuis votre disque dur et non plus depuis futon par ex. Au passage, vous ne pouvez pas cloner votre application dans le même répertoire que l'initial :

tetram:mycouchapp nicolas$ cd ..
tetram:CouchDB nicolas$ couchapp clone http://127.0.0.1:5984/monapp/_design/mycouchapp
[CRITICAL] an app already exist here: mycouchapp

Il vous faut donc spécifier un chemin différent :

tetram:CouchDB nicolas$ couchapp clone http://127.0.0.1:5984/monapp/_design/mycouchapp mycouchapp-cloned
[INFO] Cloning mycouchapp to mycouchapp-cloned...
tetram:CouchDB nicolas$ ls mycouchapp-cloned/
_attachments	lib		shows		views
couchapp.json	lists		vendor

A noter que la version clonée a un fichier couchapp.json en plus et donc je ne connais pas encore l'intérêt / l'utilité à ce stade.

Si on revient un instant sur ces répertoires :

  • _attachments contiendra les fichiers attachés à votre application
  • views contient les vues
  • lists contient les listes de vues ; utilisées par ex pour une page listant les 10 derniers documents par ex style page d'accueil d'un blog.
  • shows contient les rendus d'un document ; la visualisation d'un article d'un blog par ex.
  • lib contient les modèles et macros
  • vendor contient des composants tiers fournis par couchapp pour le moment mais on peut imaginer je suppose d'autres briques tierces dans cet espace .

Voilà pour un début, dès que je suis plus clair sur les listes / vues / rendus, vous aurez droit à un autre billet :-)

CouchDB - Premier tour d'horizon

Pour ceux qui ne connaissent pas (encore) CouchDB : c'est une base documentaire (et non pas relationnelle comme MySQL, PostgreSQL, Oracle, etc) qui possède les caractéristiques suivantes :

  • Pas de schéma ("schema-less") : contrairement aux bases de données relationnelles, la modification du schema de votre base ne revient pas à modifier votre schéma pour tout l'existant. Seulement pour le document en question, voir pour la révision du document en question. Vous êtes donc beaucoup plus libre dans la gestion de vos documents.
  • Tolérance à la panne ("Fault tolerant") avec en prime des mécanismes de réplication distribuée, une gestion des conflits, etc.
  • Accès aux données via une API RESTful JSON/HTTP
  • Peut être indexé/requêtée
  • Les requêtes se font en Javascript

Pour appréhender CouchDB, je vous invite à parcourir les slides données par J Chris Anderson, un des fondateur de couchdb. Accessoirement, CouchDB est maintenant un projet Apache, d'où l'url : http://couchdb.apache.org/.

J'avais lu des slides sur couchdb en février 2008. J'avais trouvé ça fort intéressant mais vu la jeunesse du projet et mes objectifs de l'époque, je l'avais laissé de coté. J'avais eu une piqure de rappel en lisant les slides de pycon-fr 2008 de Benoit Chesneau sur Couchdb et Python. J'ai eu ma dernière piqûre de rappel lors de pycon-fr 2009 toujours par Benoit lors de sa présentation Python et les bases de données non-SQL.

Tout ça pour dire que pour commencer à appréhender CouchDB, je vous conseille :

  • L'introduction et la vue technique (la fin peut être lue en diagonale éventuellement) sur le site du projet,
  • Le livre en ligne "CouchDB : the definitive guide. Même s'il n'est pas encore fini, les premiers chapitres permettent de se faire une idée plus claire sur l'écosystème CouchDB.
  • La série de billets de Benoit Chesneau sur CouchDB. Il en prévoyait 6, je n'en vois que 3 pour le moment... Cela permet de décanter un peu ce que l'on a lu en anglais et de mieux comprendre comment se positionnent les "couchapps" vis à vis de CouchDB.
  • Sous Mac OS X, plutôt que vous embêter avec les ports, il y a CouchDBX qui fait tout tout seul, le tout dans un unique package et avec une interface graphique dédiée à Futon (l'interface d'administration de CouchDB).

Dans ce que j'ai pu également glaner sur le web :

Questions résolues :

  • La connexion entre un framework MVC et le coté "Schema free" de CouchDB a-t-il du sens ? Niko m'a répondu : "model means business, not rdbms nor persistence"

Questions à élucider :

  • L'ajout d'un champ dans un document : comment se comporte la vue mise à jour pour les anciens documents ? Apparemment, le javascript fait un test d'existence lors de la fonction de type "Map"... donc pas de problème mais à confirmer.
  • A partir de quel moment il faut sortir du socle CouchDB pour y insérer un Django par ex ? Dès lors que l'on ne peut pas réaliser une action en javascript ?
  • Plein d'autres non formulées à ce stade

En tous cas, CouchDB m'a fait changer mon point de vue sur Javascript ;-)

Affaire à suivre...