CouchDB - base de données Apache NoSQL

Image d'agrément

Apache CouchDB est un système de gestion de base de données orienté documents et bla bla bli et bla bla bla. Bon on ne va pas réécrire l'histoire, si vous êtes là c'est quand même que vous savez de quoi il retourne. À la limite pour les plus curieux il y a wikipedia qui en parle et si vraiment ça ne vous suffit pas il y à aussi le guide O'Reilly. Mais si vous voulez savoir comment ça marche alors ne bougez pas c'est ici que ça se passe et ça commence maintenant . . .

Installer couchDB

Apache propose d'installer CouchDB depuis les sources ou depuis les dépôts Apache, c'est cette dernière option que nous allons suivre ici. Je suis sur une distribution basée sur Debian mais je vous fais confiance pour adapter les commandes à votre environnement.

CouchDB est un système de gestion de base de données, pour communiquer avec lui sur le protocole HTTP vous devez avoir un serveur HTTP installé et fonctionnel. Si ce n'est pas le cas mais que vous êtes pressé un simple # apt install apache2 suffira.

Mise à jour et/ou installation des outils

On commence par faire une mise à jour du registre de notre gestionnaire de dépôts et on installe les outils nécessaires si besoin.

# apt update && apt install -y curl apt-transport-https gnupg
...
Tous les paquets sont à jour.
...
curl est déjà la version la plus récente (7.74.0-1.3+deb11u10).
0 mis à jour, 0 nouvellement installés, 0 à enlever et 0 non mis à jour.

Sur ma distribution tout est déjà présent.

Ajout des dépôts Apache pour CouchDB

On installe la clé public nécessaire à la communication entre les dépôts Apache et notre serveur.

$ curl https://couchdb.apache.org/repo/keys.asc | gpg --dearmor | sudo tee /usr/share/keyrings/couchdb-archive-keyring.gpg >/dev/null 2>&1

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  3882  100  3882    0     0  10843      0 --:--:-- --:--:-- --:--:-- 10843

La commande source s'assure que les variables d'environnement propres à l'OS soient chargées.

$ source /etc/os-release

On ajoute le dépôt Apache CouchDB dans le répertoire /etc/apt/sources.list.d/

$ echo "deb [signed-by=/usr/share/keyrings/couchdb-archive-keyring.gpg] https://apache.jfrog.io/artifactory/couchdb-deb/ ${VERSION_CODENAME} main" \
    | sudo tee /etc/apt/sources.list.d/couchdb.list >/dev/null

On relance une mise à jour de nos dépôts.

# apt update

PATATRAQUE . . .

E: Entrée 1 mal formée dans list fichier /etc/apt/sources.list.d/couchdb.list (Component)
E: La liste des sources ne peut être lue.

Don't panic, C'est un problème qui m'incombe et qui ne devrait pas se produire chez vous.
Ma distribution locale est une "Bunsenlabs Beryllium" basée sur Debian Bullseye dont le fichier $ cat /etc/os-release ne mentionne pas de ${VERSION_CODENAME}. J'ai donc juste eu à éditer le fichier # nano /etc/apt/sources.list.d/couchdb.list pour ajouter "bullseye" juste avant "main" et tout est rentré dans l'ordre.

# apt update
...
Réception de :8 https://apache.jfrog.io/artifactory/couchdb-deb bullseye InRelease [6 004 B]
Réception de :9 https://apache.jfrog.io/artifactory/couchdb-deb bullseye/main amd64 Packages [4 738 B]
10,7 ko réceptionnés en 1s (7 931 o/s)
...

Installation de CouchDb

# apt install couchdb

Durant l'installation il vous sera demander de choisir:

Welcome to Fauxton

Assurez vous d'avoir le port 5984 ouvert sans quoi ça ne fonctionnera pas.

Pour nous aider dans la gestion de nos bases de données, CouchDB propose un outil graphique accessible avec un navigateur internet à l'adresse http://127.0.0.1:5984/_utils.

fauxton

Bien sûr, si votre serveur est distant, vous devrez indiquer sa véritable adresse IP pour pouvoir y accéder. C'est pour moi l'occasion de vous parler du fichier de configuration de CouchDB "local.ini" et d'y jeter un rapide (mais intéressé) coup d’œil.

# nano /opt/couchdb/etc/local.ini

Faites défiler le document jusqu'à la section "[chttpd]", les lignes qui nous intéressent sont les suivantes:

[chttpd]
;port = 5984
;bind_address = 127.0.0.1

Décommentez la ligne "bind-address" et changez l'adresse IP 127.0.0.1 par 0.0.0.0. Ainsi CouchDB sera en mesure de répondre sur toutes les adresses IP dont celle de votre serveur.

Une fois entrée l'adresse http://ip_ou_domaine:5984/_utils dans votre navigateur, vous serez invité à entrer le couple admin/motDePasse que vous avez renseigné durant l'installation.

Je ne souhaite pas m'étaler sur le sujet Fauxton et préfère me focaliser sur la manipulation des bases de données CouchDB avec la ligne de commande et l'outils cURL car ce que vous savez faire avec cURL en ligne de commande vous saurez le faire avec Fauxton.

Utiliser CouchDB avec cURL

cURL est un outils en ligne de commande qui a pour vocation le transfert de données depuis ou vers un serveur en s'appuyant sur un large éventail de protocoles, les pages de man curl vous en diront plus à ce sujet. C'est avec le protocole HTTP que cURL et CouchDB vont communiquer.

Assurez vous d'avoir le port 5984 ouvert sans quoi ça ne fonctionnera pas.

CouchDB welcome

On commence par vérifier que CouchDB répond correctement à une simple requête cURL.

$ curl http://127.0.0.1:5984/

Si tout s'est bien passé on devrait voir quelque chose comme ça:

{"couchdb":"Welcome","version":"3.3.2","git_sha":"11a234070","uuid":"e186b7f337e371cbaa26712ef88c418c","features":["access-ready","partitioned","pluggable-storage-engines","reshard","scheduler"],"vendor":{"name":"The Apache Software Foundation"}}

L'onglet "Verify" de Fauxton permet de lancer un test sur l'ensemble des commandes nécessaires au bon fonctionnement de CouchDb.

Lister les bases existantes

Les fragments d'URL qui commencent par un trait de soulignement "_", comme par exemple "_all_dbs", sont des composants spéciaux ayant une fonction prédéfinit au sein du serveur CouchDB. Leur nom aide à déterminer à quelle partie du serveur on accède.

La commande suivante affiche les bases de données existantes sur votre serveur.

$ curl -X GET http://admin:password@127.0.0.1:5984/_all_dbs
["_replicator","_users"]

Les deux bases déjà présentes, "_replicator" et "_users", ont été créées à l'installation est sont nécessaires au fonctionnement de CouchDB. N'y touchez pas et n'en parlons plus!

Par défaut cURL fais ses requêtes avec la méthode GET, l'option -X permet de séléctionner une autre méthode tel que PUT, POST, ou DELETE. L'écriture curl -X GET http... est donc identique à curl http....

L'option -v aura pour effet de rendre cURL plus verbeux et sera utile pour le débogage.

$ curl -v http://admin:password@127.0.0.1:5984/_all_dbs
*   Trying 127.0.0.1:5984...
* Connected to 127.0.0.1 (127.0.0.1) port 5984 (#0)
* Server auth using Basic with user 'admin'
> GET /_all_dbs HTTP/1.1
> Host: 127.0.0.1:5984
> Authorization: Basic YWRatW64SGMzMxNz
> User-Agent: curl/7.74.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Cache-Control: must-revalidate
< Content-Type: application/json
< Date: Wed, 29 Nov 2023 16:25:14 GMT
< ETag: "AH8JUISKTAC7CA9N3YNRMNOY8"
< Server: CouchDB/3.3.2 (Erlang OTP/24)
< Transfer-Encoding: chunked
< X-Couch-Request-ID: 8a74655a62
< X-CouchDB-Body-Time: 0
< 
["_replicator","_users"]
* Connection #0 to host 127.0.0.1 left intact

Je vous invite à lire cette partie de la doc qui explique en détail cette discussion entre cURL et CouchDB.

Créer une nouvelle base de donnée

$ curl -X PUT http://admin:password@127.0.0.1:5984/contacts
{"ok":true}

Le message {"ok":true} est limpide mais si vous doutez du bon fonctionnement de cette commande, relancer celle qui permet d'afficher les bases de données existantes devrait vous rassurer.

$ curl -X GET http://admin:password@127.0.0.1:5984/_all_dbs
["_replicator","_users","contacts"]

Notre base "contacts" a bien été créée.

Ajouter un document dans la base de donnée

Il semblerait que dans le monde NoSQL on ne dise pas "ajouter une entrée" mais "ajouter un document".

curl -X PUT http://admin:password@127.0.0.1:5984/contacts/515bdd8612c54978df021212bd0021c5 -d '{"nom":"Leper","prenom":"Noël","email":"nono@mail.com"}'

La commande mérite quelques explications:

Il est possible d'utiliser des identifiants plus simples (1,2,3,...) ou au contraire plus complexes et plus longs (Aa-158 ... 79_xX) du moment qu'ils sont uniques.
Si vous manquez d'inspiration, CouchDB met à disposition un outils pour générer un UUID.

$ curl -X GET http://127.0.0.1:5984/_uuids
{"uuids":["714bdd8622c54978df021212bd0036c3"]}

Une fois la commande "PUT" envoyée, la réponse de CouchDB ne se fait pas attendre.

{"ok":true,"id":"515bdd8612c54978df021212bd0021c5","rev":"1-fa9c784a72347c22fed844eccb2ff317"}

On retrouve l'information "ok":true qui confirme que l'opération s'est bien déroulée, ainsi que l'UUID du document qui vient d'être créé. S'ajoute à cela un numéro de révision généré automatiquement par CouchDB. Voyons tout de suite ce qui se cache derrière ce nombre.

Les numéros de révision

Comme nous l'explique la documentation, quand on apporte une modification à un document, CouchDB ne se contente pas de charger un champ pour en modifier la valeur. Au lieu de cela il récupère la totalité du document et le réécrit complètement.

Chaque fois qu'un document est modifié, CouchDB génère un nouveau numéro de révision. Cette mécanique permet de contrôler qu'une modification ne puisse être apportée sur un document seulement si celui qui la demande dispose du bon numéro de révision. Par exemple; si deux personnes travaillent sur le même document, seule la première qui validera l'enregistrement sera satisfaite et provoquera l'enregistrement ET le changement de "_rev" alors que la seconde, n'ayant plus le même numéro de révision, obtiendra un message d'erreur.

La structure d'un numéro de révision n'est pas très importante, d'ailleurs la documentations n'est pas très claire à ce sujet, "The revision number is the MD5 hash of the transport representation of a document". Toute fois elle ajoute que ce hachage MD5 est préfixé d'un numéro; 1 à la création du document, puis 2 lors de la première modification et ainsi de suite. Ce numéro s'incrémentera de plus en plus au fur et à mesure des modifications apportées au document.

Récupérer un document

On récupère un document grâce à son identifiant.

$ curl -X GET http://admin:password@127.0.0.1:5984/contacts/515bdd8612c54978df021212bd0021c5

Si tout s'est bien déroulé CouchDB vous répondra quelque chose comme ça:

{"_id":"515bdd8612c54978df021212bd0021c5","_rev":"1-fa9c784a72347c22fed844eccb2ff317","nom":"Leper","prenom":"Noël","email":"nono@mail.com"}

Modifier un document

La commande pour modifier un document dans CouchDb est presque identique à celle qui permet de créer un document mais la seule présence du UUID ne suffit pas, vous devrez préciser également le numéro de révision (_rev) qui à été généré lors de la création du document.

curl -X PUT http://admin:password@127.0.0.1:5984/contacts/515bdd8612c54978df021212bd0021c5 -d '{"_rev":"1-fa9c784a72347c22fed844eccb2ff317","nom":"Leper","prenom":"Noël","tel":"01 02 03 04 05","email":"nono@mail.com"}'

Si tout s'est déroulé comme prévu CouchDB devrait répondre quelque chose comme ça:

{"ok":true,"id":"515bdd8612c54978df021212bd0021c5","rev":"2-3baf652c9776e8f96c05086bb4ab63fc"}

J'attire votre attention sur le fait que la modification du document portait sur l'ajout d'un nouveau champ (tel) qui s'est fait à la volée. Les bases de données NoSQL ont cette particularité de créer ou supprimer des champs comme bon vous semble.

N'oubliez pas ce qui a été dit plus haut au chapitre des numéros de révision, l'application CouchDB ne se contente pas de remplacer la valeur d'un champ, elle réécrit tout le document. Ne pas réécrire un champ et sa valeur équivaut à les supprimer du document.

Réplication / sauvegarde

La sauvegarde de la base de données peut se faire de manière "naïve" ou "brute" en copiant simplement le répertoire /var/lib/couchdb/ vers un support quelconque. Mais vous préférerez sans doute utiliser une méthode plus subtile: la réplication.

La réplication d'une base de donnée, que ce soit pour une simple sauvegarde ou pour synchroniser la même base sur deux appareils (ordinateur, smartphone, ...), s’effectue grâce à une simple requête HTTP.

Les exemples utilisés jusqu'ici on été fait depuis une machine locale (127.0.0.1), c'est cette machine qui servira de source. La cible de la réplication sera une machine distante qui répondra à l'adresse IP 50.50.50.50. Il va de sois que CouchDB aura préalablement été installé et configuré sur cette dernière.

La documentation sur la réplication est ambiguë, elle nous dit d'abords qu'il n'est pas possible de créer à la volée la base de donnée à répliquer, puis on nous explique plus loin qu'il est possible de le faire. Il y à en effet deux manières de le faire.

Méthode en deux temps

On crée la base de donnée de réplication sur le serveur cible.

curl -X PUT http://admin:password@50.50.50.50:5984/contacts-copie
{"ok":true}

Ci-dessus on crée la bdd depuis la machine locale sur le serveur distant. Une autre approche aurait été de se connecter sur le serveur distant en SSH puis de créer cette bdd "localement" sur l'adresse 127.0.0.1.

Puis on procède à la réplication.

curl -X POST http://admin:password@127.0.0.1:5984/_replicate \
-d '{"source":"http://admin:password@127.0.0.1:5984/contacts","target":"http://admin:password@50.50.50.50:5984/contacts-copie"}' \
-H "Content-Type: application/json"

Méthode à la volée

On saute l'étape de création de la base de données et on ajoute l'option JSON "create_target":true au corps de la requête POST.

curl -X POST http://admin:password@127.0.0.1:5984/_replicate \
-d '{"create_target":true,"source":"http://admin:password@127.0.0.1:5984/contacts","target":"http://admin:password@50.50.50.50:5984/contacts-copie"}' \
-H "Content-Type: application/json"

Nous avons vu plus haut que le drapeau -d indique à cURL le corps de la requête, le drapeau -H demande à inclure dans la requête une en-tête supplémentaire.

Ce que nous venons de faire,une copie de local vers distant, s'appel une réplication push, l'inverse, une copie de distant vers local, s'appel une réplication pull.

Nous n'avons vu ici que la partie visible de l'iceberg, Le domaine de la réplication est en réalité bien plus vaste et complexe qu'une simple copie de base de donnée comme en témoigne le chapitre qui lui est consacré dans la documentation.

Supprimer une base de données

ATTENTION aucune demande de confirmation ne vous sera demander.

$ curl -X DELETE http://admin:password@127.0.0.1:5984/contacts/
{"ok":true}

Utiliser CouchDB et un langage de programmation

Bon c'est bien joli tout ça mais concrètement il va bien falloir exécuter toutes ces commandes par l'intermédiaire d'un langage de programmation coté serveur. À priori il est possible de communiquer avec CouchDB depuis n'importe quel langage de programmation du moment qu'il sache utiliser cURL mais nous allons nous focaliser ici uniquement sur le langage PHP.

Les exemples suivants ont été réalisés avec une version 7.4 de PHP.

CouchDB/cURL et PHP

PHP dispose d'un module pour utiliser cURL qu'il vous faudra probablement installer si vous n'avez jamais utilisé cURL avec PHP.

# apt install php-curl

Ceci fait nous allons reprendre quelques unes des commandes que nous avons vue ci-dessus mais cette fois avec le langage de programmation coté serveur, PHP.

Ai-je besoin de vous demander si vous avez PHP installé sur votre ordinateur?

Inscrivez ces quelques lignes dans un fichier .php et exécutez le depuis votre navigateur.

<?php

$curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, 'http://127.0.0.1:5984/');
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_HTTPHEADER, array(
        'Content-type: application/json',
        'Accept: */*'
    ));
    $couchdb_json_reponse = curl_exec($curl);
curl_close($curl);

echo $couchdb_json_reponse;

Si tout fonctionne correctement vous devriez voir la même réponse que celle qui nous a été retournée avec la commande utilisée au début du paragraphe sur cURL: {"couchdb":"Welcome","version":"3.3.2",...

Ajouter une base de données

Pour créer une base de donnée CouchDB avec PHP nous avons besoin du couple "admin:password" et du nom que nous avons choisi pour la base, ici ce sera "contacts".

On peut ensuite initialiser une session cURL avec curl_init(). J'ai volontairement indenté le code pour plus de clarté. On va ensuite égrainer tout un tas d'options de transmissions grâce à la fonction curl_setopt(). Elle prends trois paramètres:

Je ne vais pas toutes les expliquer, leur nom parle pour elles. Vous pouvez toujours jeter un coup d’œil dans le manuel PHP si vous souhaitez plus de précision.

Une fois les options définis on peut exécuter la requête curl_exec() et récupérer le retour dans la variable $couchdb_json_reponse et fermer la session.

<?php

$login = "admin:password";
$database = "contacts";

$curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, 'http://127.0.0.1:5984/'.$database);
    curl_setopt($curl, CURLOPT_USERPWD, $login);
    curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT');
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_HTTPHEADER, array(
        'Content-type: application/json',
        'Accept: */*'
    ));
    $couchdb_json_reponse = curl_exec($curl);
curl_close($curl);

echo $couchdb_json_reponse;

Réponse:

{"ok":true}

Ajouter un document

Comme pour la création d'une base de données, nous avons besoin du couple "admin:password" ainsi que du nom de la base pour y ajouter les données. Ensuite nous aurons besoin des données bien sûr, elles seront d'abords déclarées avec un tableau PHP ($user = array(...) puis encodées au format JSON grâce à la fonction PHP json_encode(). On transmettra ces données avec l'options CURLOPT_POSTFIELDS. Enfin nous aurons besoin d'un UUID, ou quelque chose qui y ressemble. Dans l'exemple ci-dessous je l'ai injecté directement dans l'URL avec la fonction PHP uniqid().

<?php

$login = "admin:password";
$database = "contacts";

$user = array(
    'nom'      => 'Leper',
    'prenom'   => 'Noël',
    'email'    => 'nono@email.com'
);
$json_user = json_encode($user);


$curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, 'http://127.0.0.1:5984/'.$database.'/'.uniqid());
    curl_setopt($curl, CURLOPT_USERPWD, $login);
    curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT'); 
    curl_setopt($curl, CURLOPT_POSTFIELDS, $json_user);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_HTTPHEADER, array(
        'Content-type: application/json',
        'Accept: */*'
    ));
    $couchdb_json_reponse = curl_exec($curl);
curl_close($curl);

echo $couchdb_json_reponse;

réponse:

{"ok":true,"id":"656f2cb025cfc","rev":"1-17d6eb63e3cb2ab6664f2f9051eb7e3a"}

Obtenir un UUID par CouchDB

Comme nous l'avons vu plus haut, CouchDB est en mesure de fournir un ou plusieurs UUID.

<?php

$curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, 'http://127.0.0.1:5984/_uuids');
    curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'GET');
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_HTTPHEADER, array(
        'Content-type: application/json',
        'Accept: */*'
    ));
    $couchdb_json_reponse = curl_exec($curl);
curl_close($curl);

$couchdb_array_reponse = json_decode($couchdb_json_reponse, true);
$uuid = $couchdb_array_reponse['uuids'][0];

echo $uuid;

Récupérer un document

En plus des sempiternels identifiants de connexion et du nom de la base de données, récupérer un document nécessite juste de connaitre son identifiant et de l'ajouter à la suite de l'URL. On récupère ensuite, comme à chaque fois, la réponse envoyée par le serveur CouchDB dans la variable $couchdb_json_reponse et comme son nom le laisse supposer elle contient des données au format JSON, mais dans le cas présent, et si l'opération s'est correctement déroulée, on va vouloir afficher/traiter les données avec PHP. On convertit donc l'objet JSON en tableau PHP avec la fonction "json_decode()".

<?php

$login = "admin:password";
$database = "contacts";
$uuid = '656f2cb025cfc';

$curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, 'http://127.0.0.1:5984/'.$database.'/'.$uuid);
    curl_setopt($curl, CURLOPT_USERPWD, $login);
    curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'GET');
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_HTTPHEADER, array(
        'Content-type: application/json',
        'Accept: */*'
    ));
    $couchdb_json_reponse = curl_exec($curl);
curl_close($curl);

$data = json_decode($couchdb_json_reponse, true);
print_r($data);

Réponse:

Array ( [_id] => 656f2cb025cfc [_rev] => 1-17d6eb63e3cb2ab6664f2f9051eb7e3a [nom] => Leper [prenom] => Noël [email] => nono@email.com )

Modifier un document

Bon là je vais vous laisser bosser un peu, il n'y à rien de particulier par rapport à ce qu'on a fait jusqu'ici c'est juste un peu plus long. J'ai scindé le script en 3 parties: la récupération des données, la modification de ces données et l'envoi des données modifiées

Je me répète mais n'oubliez pas ce qui a été dit plus haut au chapitre des numéros de révision, l'application CouchDB ne se contente pas de remplacer la valeur d'un champ, elle réécrit tout le document. Ne pas réécrire un champ et sa valeur équivaut à les supprimer du document.

<?php

$login = "admin:password";
$database = "contacts";
$uuid = '656f2cb025cfc';

// récupération du document
$curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, 'http://127.0.0.1:5984/'.$database.'/'.$uuid);
    curl_setopt($curl, CURLOPT_USERPWD, $login);
    curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'GET');
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_HTTPHEADER, array(
        'Content-type: application/json',
        'Accept: */*'
    ));
    $couchdb_json_reponse = curl_exec($curl);
curl_close($curl);

// modification du document
$data = json_decode($couchdb_json_reponse, true);
$user = array(
    '_rev'     => $data['_rev'],
    'nom'      => $data['nom'],
    'prenom'   => $data['prenom'],
    'email'    => $data['email'],
    'tel'      => '01.02.03.04.05'
);
$data = json_encode($user);// ne pas oublier d'encoder les données au format JSON

// envoi des données modifiées
$curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, 'http://127.0.0.1:5984/'.$database.'/'.$uuid);
    curl_setopt($curl, CURLOPT_USERPWD, $login);
    curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT');
    curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_HTTPHEADER, array(
        'Content-type: application/json',
        'Accept: */*'
    ));
    $couchdb_json_reponse = curl_exec($curl);
curl_close($curl);

echo $couchdb_json_reponse;

Réponse:

{"ok":true,"id":"656f2cb025cfc","rev":"2-c8e24a89500c9371932c90f1b2bf82ee"}

Ajouter une pièce jointe à un document

CouchDB offre la possibilité d'ajouter des pièces jointes aux documents déjà créés. Vous pouvez comparer ces pièces jointes à celles que vous ajoutez habituellement à vos e-mails, des fichiers de n'importe quel type (image, vidéo, audio, pdf, ...). Ajoutons une image en pièce jointe de notre document.

Parmi les éléments dont nous allons avoir besoin pour notre requête cURL on retrouve les habituels login, mot de passe, nom de la base de donnée, uuid et numéro de révision car oui, ajouter une pièce jointe équivaut à modifier le document mais contrairement à la modification que nous avons faite ci dessus, il ne sera pas nécessaire de tout réécrire. On aura également besoin de du nom et du chemin vers la pièce jointe localement pour identifier son "MIME TYPE" et aussi pour la récupérer. On récupérera également les données de la pièce jointe dans une variable grâce à la fonction file_get_contents().

le "Content-type" du fichier est déterminé par les fonctions finfo mais vous pouvez vous restreindre à un seul "MIME TYPE" en l'ajoutant directement à la ligne 'Content-type: image/jpg', par exemple.

<?php

$login = "admin:password";
$database = "contacts";
$uuid = '65731130138aa';
$rev = '2-962d59af91bdef41f69aaf6f803c6e3a';
$url_pj = '/home/user/images/';
$piece_jointe = 'lepernoel.jpg';

$fileinfo = finfo_open(FILEINFO_MIME_TYPE);
$contentType = finfo_file($fileinfo, $url_pj.$piece_jointe);
finfo_close($fileinfo);

$data_pj = file_get_contents($url_pj.$piece_jointe);

$curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, 'http://127.0.0.1:5984/'.$database.'/'.$uuid.'/'.$piece_jointe.'?rev='.$rev);
    curl_setopt($curl, CURLOPT_USERPWD, $login);
    curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT');
    curl_setopt($curl, CURLOPT_POSTFIELDS, $data_pj);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_HTTPHEADER, array(
        'Content-type: '.$contentType,
        'Accept: */*'
    ));
    $couchdb_json_reponse = curl_exec($curl);
curl_close($curl);

echo $couchdb_json_reponse;

Réponse:

{"ok":true,"id":"656f2cb025cfc","rev":"3-962d59af91bdef41f69aaf6f803c6e3a"}

Vous pouvez vérifier que la pièce jointe à bien été ajoutée à CouchDB avec l'aide de Fauxton ou directement depuis son url: http://127.0.0.1:5984/contacts/656f2cb025cfc/lepernoel.jpg

Supprimer un document

On pourrait penser que pour supprimer un document on ait pas besoin d'autre chose que son UUID et pourtant, si vous regarder le retour de cette commande vous verrez que son numéro de révision à été incrémenté. En fait quand vous demandez la suppression d'un document la base de données crée une nouvelle révision qui contient les champs _id et _rev ainsi que l' indicateur _deleted. voir la doc à ce propos.

<?php

$login = "admin:password";
$database = "contacts";
$uuid = '656f2cb025cfc';
$rev = '2-c8e24a89500c9371932c90f1b2bf82ee';

$curl = curl_init();     
    curl_setopt($curl, CURLOPT_URL, 'http://127.0.0.1:5984/'.$database.'/'.$uuid.'?rev='.$rev);
    curl_setopt($curl, CURLOPT_USERPWD, $login);
    curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE');
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_HTTPHEADER, array(
        'Content-type: application/json',
        'Accept: */*'
    ));
    $couchdb_json_reponse = curl_exec($curl);
curl_close($curl);

echo $couchdb_json_reponse;

Réponse:

{"ok":true,"id":"656f2cb025cfc","rev":"3-ca70a61d7efcb164d522b9e68bf885ca"}

Conclusion

Nous arrivons au terme de cette mise en bouche et je ne serais pas étonné que vous vous sentiez encore affamé. En effet nous n'avons exploré ici que la croûte et beaucoup de questions restent encore en suspend. Comme d'habitude vous allez devoir creuser et pratiquer mais la doc est là aussi pour vous aider.

15-Dec-2023
^