Login   Register  
PHP Classes
elePHPant
Icontem

File: OscarCouchDb-0.3.2

Recommend this page to a friend!
Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us
  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: 4 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;
        }

    }
    



}
?>