PHP Classes

File: OscarCouchDb-0.3.2

Recommend this page to a friend!
  Classes of de saint leger christophe   Oscar CouchDb   OscarCouchDb-0.3.2   Download  
File: OscarCouchDb-0.3.2
Role: Class source
Content type: text/plain
Description: Manage couchDB databases , Add , delete , update , replication automatic ect ...
Class: Oscar CouchDb
Manipulate data on a CouchDB database
Author: By
Last change:
Date: 13 years ago
Size: 28,625 bytes
 

Contents

Class file image Download
<?php /** * Oscar Framework http://fw-oscar.fr * * * @license * * GNU General Public License * * This file is part of Oscar Open Accessibility. * Copyright (c) 2007, 2008 Christophe DE SAINT LEGER. All rights reserved. * * Oscar Open Accessibility is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Oscar Open Accessibility is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Oscar Open Accessibility; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * * @category Oscar library * @package Oscar_couchDB * @subpackage * */ /** * Class Oscar_couchDB. * * * * @author Christophe DE SAINT LEGER <christophe@fw-oscar.fr> * @copyright Copyright (c) 2009, 2009 Christophe DE SAINT LEGER. * @license http://gnu.org/licenses/gpl.txt GNU GPL * @since PHP 5 * @version 0.3.2 * @package Oscar_couchDB * @subpackage */ class Oscar_couchDB{ private static $_host = null; private static $_port = null; private $_body = null; private $_headers= null; private $_types = array("GET","PUT","POST","DELETE","COPY"); private static $_user = null; private static $_pwd = null; public static $_instance = null; /* * Paramétres de replication */ private static $_replica_host_src = null; private static $_replica_port_src = null; private static $_replica_ddb_src = null; private static $_replica_host_dst = null; private static $_replica_port_dst = null; private static $_replica_ddb_dst = null; private static $_autoReplique = FALSE; private static $_test_replication = FALSE; /*** * Constructeur */ private function __construct($host='127.0.0.1',$port=5984){ self::$_host = $host; self::$_port = $port; } /* * Désactive la fonction magique clone */ private function __clone(){ } /* * Singleton */ public static function getInstance(){ if( !(self::$_instance instanceof self) ){ self::$_instance = new self; return self::$_instance; }else{ return self::$_instance; } } /* * Accesseurs */ public function set_user($value){ self::$_user = $value; } public function set_pwd($value){ self::$_pwd = $value; } public function set_host($value){ self::$_host = $value; } public function set_port($value){ self::$_port = $value; } /* * Permet d'activer la réplication automatique * à chaque modification */ public function auto_replique($auto = FALSE){ if( is_bool($auto)){ self::$_autoReplique = $auto; } } /* * Paramétrage a réplication couchDB */ public function set_replication($adr_source,$adr_dest,$port_dest,$database_source=null,$database_dest=null,$checkup = FALSE){ try{ if( !empty($adr_dest) && !empty($adr_source) ){ $err = false; //permute les adresses pour tester $adr_actuelle = self::$_host; self::$_host = $adr_dest; //permute les ports $port_actuel = self::$_port; self::$_port = $port_dest; //si l'on demande des vérifications de paramétres if( $checkup ){ //récupére les infos $Tinfo = $this->send("GET",'/'); //test la connexion au serveur distant if( $Tinfo == null ){ //on remet l'adresse paramétré et le port self::$_host = $adr_actuelle; self::$_port = $port_actuel; throw new Exception("Le serveur cible n'est pas accessible ! ", 011); return (-1); } } //on remet l'adresse paramétré et le port self::$_host = $adr_actuelle; self::$_port = $port_actuel; //test l'existance des base source et destination if( !empty($database_source) && !empty($database_dest) ){ //permute les adresses pour tester $adr_actuelle = self::$_host; self::$_host = $adr_source; //si l'on demande des vérifications de paramétres if( $checkup ){ if( !$this->database_exists($database_source) ){ //création de la base inexistante if( !$this->add($database_source) ){ throw new Exception("La base source n'héxiste pas ... tentative de création échoué !", 001); return -1; } //on remet l'adresse paramétré et le port self::$_host = $adr_actuelle; self::$_port = $port_actuel; } } //on remet l'adresse paramétré et le port self::$_host = $adr_actuelle; self::$_port = $port_actuel; //permute les adresses pour tester $adr_actuelle = self::$_host; self::$_host = $adr_dest; //permute les ports $port_actuel = self::$_port; self::$_port = $port_dest; //si l'on demande des vérifications de paramétres if( $checkup ){ if( !$this->database_exists($database_dest) ){ //création de la base inexistante if( !$this->add($database_dest) ){ throw new Exception("La base cible n'héxiste pas ... tentative de création échoué !", 001); return -1; } //on remet l'adresse paramétré et le port self::$_host = $adr_actuelle; self::$_port = $port_actuel; } } //on remet l'adresse paramétré et le port self::$_host = $adr_actuelle; self::$_port = $port_actuel; //enregistre les paramétres self::$_replica_host_src = $adr_source; self::$_replica_port_src = self::$_port; self::$_replica_ddb_src = $database_source; self::$_replica_host_dst = $adr_dest; self::$_replica_port_dst = $port_dest; self::$_replica_ddb_dst = $database_dest; //si un checkup a été fait .. on ne le refait pas if( $checkup ){ self::$_test_replication = TRUE; } return true; }else{ //enregistre les paramétres /* self::$_replica_host_src = $adr_source; self::$_replica_port_src = self::$_port; self::$_replica_host_dst = $adr_dest; self::$_replica_port_dst = $port_dest; * */ throw new Exception("Erreur , paramétres manquants set_replication",001 ); return false; } } }catch(Exception $e){ echo 'CouchDB - Erreur rencontrée : ' . $e->getMessage(); } } /* * Envoi une requête http au serveur couchDB * data doit être un tableau associatif */ function send($type, $url="/", $data=null, $reponse="array"){ try{ //il doit y avoir un type valide if(in_array($type, $this->_types)){ $json_data = null; if(!empty($data)){ if(is_array($data)){ //encodage des données $json_data = self::_encode_data($data); }else{ if($type != "COPY"){ throw new Exception("Les données doivent etre contruites sous forme de tableua associatif ! <br>", 003); }else{ $json_data = $data; } } } //envoie de la requete $this->requeteur($type, $url, $json_data ); //reponse switch( $reponse ){ case "array": $retour = json_decode($this->_body,true); break; case "json": $retour = $this->_body; break; default: $retour = false; break; } }else{ throw new Exception("Le type n'est pas valide", 001); } return $retour; }catch(Exception $e){ echo 'Erreur rencontrée : ' . $e->getMessage(); } } /* * Méthode permettant d'envoiyer des requetes HTTP au serveur couchDB */ private function requeteur($type, $url, $jsondata=null){ try{ //Tableau qui vat contenir les entêtes $UserAgent = "User-Agent : Mozilla/4.0 (compatible; MSIE 5.0; Windows 95)"; //gestion de la copie $headplus = null; if($type == "COPY"){ $cible = $jsondata; $jsondata = null; $headplus = "Destination: ".$cible."\r\n"; } $fp = fsockopen(self::$_host, self::$_port, $errno, $errstr, 30); if (!$fp) { throw new Exception("$errstr ($errno)<br />\n",002); } else { $out = $type." $url HTTP/1.0\r\n"; $out .= "Host: ".self::$_host."\r\n"; $out .= $headplus; $out .= 'Accept: application/json'."\r\n"; if(self::$_user || self::$_pwd){ $out .= 'Authorization: Basic '.base64_encode(self::$_user.':'.self::$_pwd)."\r\n"; } if($jsondata !=null){ $out .= 'Content-Length: '.strlen($jsondata)."\r\n"; $out .= 'Content-Type: application/json; charset=UTF-8'."\r\n\r\n"; $out .= $jsondata."\r\n"; } else { $out .= "\r\n"; } /* * Envoi des données */ fwrite($fp, $out); $reponse = ""; $this->_body = ""; $this->_headers = ""; /* * Récupération de la réponse */ while (!feof($fp)) { $reponse .= fgets($fp); } /* * Séparation des entetes du corps */ list($this->_headers, $this->_body) = explode("\r\n\r\n", $reponse); fclose($fp); } }catch(Exception $e){ echo 'Erreur rencontrée : ' . $e->getMessage(); } } /* * Encode les données pour les envoyer au format json */ private static function _encode_data($data,$charset="UTF-8"){ $jason_data = json_encode($data); return $jason_data; } /* * Methode de recupération de document */ public function get($database,$id=null,$rev=null){ try{ //Vérification de l'existance de la base if( $this->database_exists($database) ){ //test l'existance de l'id et de la revision if($this->data_exists($database,$id,$rev)){ if(!empty($rev)){ $Trev = array("_rev"=>$rev); }else{ $Trev = null; } $ret = $this->send("GET","/".$database."/".$id,$Trev); return $ret; }else{ return false; } }else{ throw new Exception("La base de données n'héxiste pas !", 0004); } }catch(Exception $e){ echo 'Erreur rencontrée : ' . $e->getMessage(); return false; } } /* * Methode de récupération des versions et de leurs etats */ public function all_revs($database,$id){ try{ //Vérification de l'existance de la base if( $this->database_exists($database) ){ //test l'existance de l'id et de la revision if($this->data_exists($database,$id)){ $ret = $this->send("GET","/".$database."/".$id."?revs_info=true"); $Tret = array(); $Tret['actuel'] = $ret["_rev"]; $Tret['liste'] = $ret["_revs_info"]; return $Tret; }else{ return false; } }else{ throw new Exception("La base de données n'héxiste pas !", 0004); } }catch(Exception $e){ echo 'Erreur rencontrée : ' . $e->getMessage(); return false; } } /* * Méthode de creation base / donne */ public function add($database, $id=null, $data=null){ try{ //si c'est une creation de base if(!empty($database) && $id==null && $data==null ){ //test l'existance de la base if( !$this->database_exists($database) ){ $ret = $this->send("PUT","/".$database); //replication if( self::$_autoReplique == TRUE ){ $this->replique(); } return $ret["ok"]; }else{ throw new Exception("La base existe déjà ! ", 006); } }else{ //creation d'un enregistrement if( $this->database_exists($database) ){ if( !empty($id) ){ //vérifie que l'i n'est pas déjà utilisé if( !$this->data_exists($database,$id) ){ if(is_array($data)){ $ret = $this->send("PUT","/".$database."/".$id.'/', $data); //replication if( self::$_autoReplique == TRUE ){ $this->replique(); } return $ret; }else{ throw new Exception("Les données doivent etre contruites sous forme de tableua associatif ! <br>", 003); } }else{ throw new Exception("L'id unique existe déjà !", 007); } } }else{ throw new Exception("La base de données n'héxiste pas !", 0004); } } }catch(Exception $e){ echo 'Erreur rencontrée : ' . $e->getMessage(); return false; } } /* * Méthode de modification d'un enregistrement */ public function update($database,$id,$rev,$data){ try{ //Vérification de l'existance de la base if( $this->database_exists($database) ){ //test l'existance de l'id et de la revision if($this->data_exists($database,$id,$rev)){ //alors modification if( !empty($data) && is_array($data)){ //insertion de l'id et de la rev $data["_id"] = $id; $data["_rev"] = $rev; $ret = $this->send("PUT","/".$database."/".$id."/",$data); //replication if( self::$_autoReplique == TRUE ){ $this->replique(); } return $ret; }else{ throw new Exception("Les données doivent etre contruites sous forme de tableua associatif ! <br>", 003); } }else{ throw new Exception("Impossible de modifier un enregistrement non existant ! <br>", 008); } }else{ throw new Exception("La base de données n'héxiste pas !", 0004); } }catch(Exception $e){ echo 'Erreur rencontrée : ' . $e->getMessage(); return false; } } /* * Méthode de copy de document vers une cible donnée ( possibilité de spécifier une revision ) */ public function copy($database,$idOrig,$idcible,$revcible=null){ try{ if( !empty($database) && !empty($idOrig) && !empty($idcible) ){ // test l'existance de la base if($this->database_exists($database)){ //test l'existance du document source if($this->data_exists($database,$idOrig)){ // si c'est un remplacement de document existant if($revcible !=null){ if($this->data_exists($database,$idOrig,$revcible) ){ //copy $ret = $this->send("COPY","/".$database."/".$idOrig."/",$idcible."?rev=".$revcible); //replication if( self::$_autoReplique == TRUE ){ $this->replique(); } return $ret; } }else{ //copy $ret = $this->send("COPY","/".$database."/".$idOrig."/",$idcible); //replication if( self::$_autoReplique == TRUE ){ $this->replique(); } return $ret; } }else{ throw new Exception("Impossible de copier un enregistrement non existant ! <br>", 010); } }else{ throw new Exception("La base de données n'héxiste pas !", 0004); } }else{ throw new Exception("Données manquantes pour la copie !", 0009); } }catch(Exception $e){ echo 'Erreur rencontrée : ' . $e->getMessage(); return false; } } /* * Méthode de suppression d'un enregistrement / ou d'une base */ public function delete($database,$id,$rev){ try{ if( !empty($database) ){ //test l'existance de la base if( !$this->database_exists($database) ){ throw new Exception("La base de données n'héxiste pas !", 0004); }else{ if( !empty($id) && !empty($rev) ){ //test l'existance des donnée avec la revision specifié if(!$this->data_exists($database,$id,$rev)){ throw new Exception("L'enregistrement ou la révision n'hexiste pas !", 0005); }else{ $ret = null; $ret = $this->send("DELETE","/".$database."/".$id."?rev=".$rev); //replication if( self::$_autoReplique == TRUE ){ $this->replique(); } if( array_key_exists("ok", $ret) ){ return $ret['ok']; }else{ return false; } } }else{ //si c'est une suppression de base if( empty ($id) && empty($rev) ){ $ret = null; $ret = $this->send("DELETE","/".$database.'/'); //replication if( self::$_autoReplique == TRUE ){ $this->replique(); } if( array_key_exists("ok", $ret) ){ return $ret['ok']; }else{ return false; } }else{ return false; } } } } }catch(Exception $e){ echo 'Erreur rencontrée : ' . $e->getMessage(); return false; } } /* * Test l'existance d'une base */ public function database_exists($database){ $ret = $this->send("GET","/".$database); if( array_key_exists("error", $ret) ){ return false; }else{ return true; } } /* * Test l'existance d'un enregistrement dans la base ( revision ) */ public function data_exists($database, $id, $rev=null){ $ret = null; if($rev !=null){ $ret = $this->send("GET","/".$database."/".$id."?_rev=".$rev); }else{ $ret = $this->send("GET","/".$database."/".$id); } if( array_key_exists("error", $ret) ){ return false; }else{ return true; } } /* * Simple affichage des bases existantes */ public function show_databases(){ $ret = $this->send("GET","/_all_dbs"); return $ret; } /* * Simple affichage de tables d'une base de données */ public function show_tables($database){ try{ if( $this->database_exists($database)){ $ret = $this->send("GET","/".$database."/_all_docs"); return $ret; }else{ throw new Exception("La base de données n'héxiste pas !", 0004); } }catch(Exception $e){ echo 'Erreur rencontrée : ' . $e->getMessage(); return false; } } /* * Méthode de compactaged'une base */ public function compact_database($database){ try{ if( $this->database_exists($database)){ $ret = $this->send("POST","/".$database."/_compact"); //replication if( self::$_autoReplique == TRUE ){ $this->replique(); } return $ret["ok"]; }else{ throw new Exception("La base de données n'héxiste pas !", 0004); } }catch(Exception $e){ echo 'Erreur rencontrée : ' . $e->getMessage(); return false; } } /* * Méthode de réplication */ public function replique($ddt_src=null,$ddb_dest=null){ try{ $flag_replication_ok = false; //test si la réplication est bien configurée if( self::$_replica_host_src == null || self::$_replica_port_src == null || self::$_replica_host_dst == null || self::$_replica_port_dst == null ){ throw new Exception("Vous devez paramétrer votre réplication avant d'utiliser cette méthode !", 0012); }else{ if( empty($ddt_src) || empty($ddb_dest) ){ $ddt_src = self::$_replica_ddb_src; $ddb_dest = self::$_replica_ddb_dst; } //Si les base n'ont pas été testées if ( self::$_test_replication == FALSE ){ //on test de nouveau les bases if( $this->set_replication(self::$_replica_host_src,self::$_replica_host_dst,self::$_replica_port_dst,$ddt_src,$ddb_dest,TRUE) ){ //on peu lancer la réplication $flag_replication_ok = true; }else{ throw new Exception("La configuration de la réplication n'est pas correct !", 0013); } }else{ //on peu lancer la réplication $flag_replication_ok = true; } } //si la configuration est bonne , l'on peut lancer la réplication if( $flag_replication_ok == true ){ $params_replication = array( "source"=>"http://".self::$_replica_host_src.":".self::$_replica_port_src."/".self::$_replica_ddb_src, "target"=>"http://".self::$_replica_host_dst.":".self::$_replica_port_dst."/".self::$_replica_ddb_dst); $retour = $this->send("POST", $url="/_replicate", $params_replication, "array"); return $retour; } }catch(Exception $e){ echo 'Erreur rencontrée : ' . $e->getMessage(); return false; } } } ?>