Sunny Books
What we have

Cloudant: a cloud database service

Cloudant is a non-relational, distributed database service that based on the apache CouchDB. (see another article) Cloudant's service provides integrated data management, search, and analytics engine designed for web applications and requires zero-configuration.

Features

1. Advanced data management: Cloudant scales your database on the CouchDB framework and provides hosting, administrative tools, analytics and commercial support for CouchDB.

2. scalable: cloudant provides the painless scalability for all applications, so you don’t need to worry about it.

3. global data distribution network: The Cloudant Data Layer is a collection of database clusters that are hosted and scaled within or across multiple, top-tier data centers around the globe. Cloudant automatically replicates your data across this network as needed to push it closer to your global user base, reducing network latency.

4. Mobile sync: Cloudant not only syncs between data centers around the world, but also between data centers and mobile devices.

5. Incremental MapReduce: Cloudant’s Incremental MapReduce keeps indexes up-to-date with new transactions and updates without requiring a full reindexing of your data.

6. Full-text search: High-performance full-text indexing and search, without the difficulty and cost of managing text and operational data in separate databases. Includes multi-language support.

The data in cloudant can be managed via Javascript or CURL. The folowings are the example of managing data via PHP and CRUL.

class cloudant {
private $base = "cloudant.com";
private $username = "your_username"; 
private $password = "your_password"; 
private $db = "your_database";
// search indexes
private $search_fields = "/_design/name/_view/view1"; //your design view here
private $search_fields_url;
private $base_url;
private $base_url2;
private $base_url_animal;
private $referer;

function __construct() {
    // base_url
    $this->base_url = "https://".$this->username."@".
    	$this->password.".".$this->base."/".$this->db;
    // base url 2
    $this->base_url2 = "https://".$this->username.":".
    	$this->password."@".$this->username.".".$this->base."/".$this->db;
    // referer (for attachment)
    $this->referer = "https://".$this->username.".cloudant.com";
    // search indexes
    $this->search_fields_url = $this->base_url."/".$this->search_fields;
}

//-------------------------------------------------
// all documents, returns an array
// pagination is an option
function get_all_docs ($content=true, $start=false, $duration=false) {
    if($content==true) { // docs with full content
        $url = $this->base_url."/_all_docs?include_docs=true";
        if($start && $duration) {
            $url .="&limit=".$duration."&skip=".$start;
        }
    }
    else { // docs with only id and rev
        $url = $this->base_url."/_all_docs";
        if($start && $duration) {
            $url .="?limit=".$duration."&skip=".$start;
        }
    }
    
    $output = $this->fetch_page($url);
    return json_decode($output,true);		
}

//-------------------------------------------------
// all documents, returns an array
// pagination is an option
function get_all_docs_v2 ($content=true, $start=false, $duration=false) {
    if($content==true) { // docs with full content
        $url = $this->base_url2."/_all_docs?include_docs=true";
        if($start && $duration) {
            $url .="&limit=".$duration."&skip=".$start;
        }
    }
    else { // docs with only id and rev
        $url = $this->base_url2."/_all_docs";
        if($start && $duration) {
            $url .="?limit=".$duration."&skip=".$start;
        }
    }
    
    $exe = "curl ".$url;
    $output = array();
    exec($exe,$output);
    return $output;
}


//-------------------------------------------------
// get record from id, returns an array if found, otherwise return false
// same as fetch
function get_doc($id, $content=true) {
    if($content==true) {
        $url = $this->base_url."/".$id."?include_docs=true";
    }
    else {
        $url = $this->base_url."/".$id;
    }
    $output = $this->fetch_page($url);
    $outputArr = json_decode($output,true);
    if(array_key_exists("_id", $outputArr)) {
        return $outputArr;	
    }
    else return false;
        
}

function get_doc_v2($id, $content=true) {
    if($content==true) {
        $url = $this->base_url2."/".$id."?include_docs=true";
    }
    else {
        $url = $this->base_url2."/".$id;
    }
    $exe = "curl ".$url;
    $output = array();
    exec($exe,$output);
    $output = json_decode($output[0],true);
    if(!isset($output["error"])) { // return array if succeed
        return $output;
    }
    else return false; // otherwie return false
}

//-------------------------------------------------
// add (insert) ONE document
//-------------------------------------------------
// use function fetch_page
function add($dataArr) {
    // check if the doc already exist with _id
    $id = $dataArr["_id"];
    
    if($this->get_doc($id)==false) {// no doc exist, insert it
        $json_fields = json_encode($dataArr);
        $output = $this->fetch_page($this->base_url,"insert", $json_fields);
        if(isset($output["ok"])) {
            return json_decode($output,true);	
        }
        else return false;
    }
    else return false;
}

//-------------------------------------------------
// use exec function
function add_v2($dataArr) {
    // check if the doc already exist with _id
    $id = $dataArr["_id"];
    
    if($this->get_doc($id, $content=true)==false) {// no doc exist, insert it
        $json_fields = json_encode($dataArr);
        $exe = "curl -d '".$json_fields."'  -X POST ".
        	$this->base_url2."/  -H \"Content-Type:application/json\"";
        $output = array();
        exec($exe,$output);
        $output = json_decode($output[0],true);
        if(isset($output["ok"])) { // return array if succeed
            return $output;
        }
        else return false; // otherwie return false
    }
    else return false;
}


//-------------------------------------------------
// insert MULTIPLE documents 
// INPUT multi array
//-------------------------------------------------
function insert_bulk ($docsArr) {
    // prepare json bulk file
    $insert_bulk = $this->build_json_bulk($docsArr);
    // exe
    $url = $this->base_url2."/_bulk_docs";
    $exe = "curl -d '".$insert_bulk."' ".$url." -H \"Content-Type:application/json\"";
    $output = array();
    exec($exe,$output);
    $output = json_decode($output[0],true);
    return $output;
}


//-------------------------------------------------
// UPDATE ONE doc
// update is as same as insert, need include _rev in the document body
// NOTE: input array must include all the fields for updating and the field _id, 
// 		 the missed fields will NOT be put into the document
//-------------------------------------------------
function update($dataArr) {
    // get _rev
    $id = $dataArr["_id"];
    if($id) {
        $rev = $this->get_rev($id);
        $dataArr["_rev"] = $rev;
        $json_fields = json_encode($dataArr);
        $output = $this->fetch_page($this->base_url,"insert", $json_fields);
        return json_decode($output,true);	
    }
    else return false;
    
}

//-------------------------------------------------
function update_v2($dataArr) {
    // get _rev
    $id = $dataArr["_id"];
    if($id) {
        $rev = $this->get_rev($id);
        $dataArr["_rev"] = $rev;
        $json_fields = json_encode($dataArr);
        $exe = "curl -d '".$json_fields."'  -X POST ".
        	$this->base_url2."/  -H \"Content-Type:application/json\"";
        $output = array();
        exec($exe,$output);
        $output = json_decode($output[0],true);
        if(isset($output["ok"])) { // return array if succeed
            return $output;
        }
        else return false; // otherwie return false
    }
    else return false;
    
}

//-------------------------------------------------
// Update MULTIPLE Documents
function update_bulk ($docsArr) {
    foreach($docsArr as $key=>$doc) {
        $id = $doc["_id"];
        if($id) {
            $rev = $this->get_rev($id);
            $docsArr[$key]["_rev"] = $rev;
        }
    }
    $this->insert_bulk($docsArr);
}

//-------------------------------------------------
// DELETE ONE doc
// return output array if succeed, otherwise return false
//-------------------------------------------------
function delete($id) {
    // get the old record => _rev
    $rev = $this->get_rev($id);
    if($rev) {
        $url = $this->base_url."/".$id."?rev=".$rev;
        $output = $this->fetch_page($url, "delete");
        $output = json_decode($output,true);
        
        if(isset($output["ok"])) { // return array if succeed
            return $output;
        }
        else return false; // otherwie return false
    }
    else return false;
}

//-------------------------------------------------
function delete_v2($id) {
    $rev = $this->get_rev($id);
    $url = $this->base_url2."/".$id;
    $delete = "{\"_rev\":\"".$rev."\",  \"_deleted\":true}";
    if($rev) {
        $exe = "curl -d '".$delete."'  -X PUT ".$url;
        $output = array();
        exec($exe,$output);
        $output = json_decode($output[0],true);
        if(isset($output["ok"])) { // return array if succeed
            return $output;
        }
        else return false; // otherwie return false
    }
    else return false;
}


//-------------------------------------------------
// get _rev from one doc
//-------------------------------------------------
function get_rev($id) {
    $url = $this->base_url."/".$id;
    $headersArr = $this->fetch_page($url,"rev");
    if (array_key_exists('Etag', $headersArr)) {
        $rev = $headersArr["Etag"];
        $rev = str_replace("\"", "", $rev); // remove " from header etag
        return $rev;
    }
    else return false;
}

//-------------------------------------------------
// SEARCH
//-------------------------------------------------
function search ($fields, $sort=false, $start=false, $duration=false, $content=true) {
    $url = $this->search_fields_url;
    // search fields
    if(is_array($fields)) {
        $newFldArr = array();
        foreach($fields as $field) {
        	// replace empty char to "20%" for url
            $newFldArr[] = str_replace(" ","%20", $field); 
        }
        $url .="?q=".implode("%20AND%20", $newFldArr);
    }
    else {
        $url .= "?q=".$fields;
    }
    //sorting
    if($sort) {
        if(is_array($sort)) {
            $newSortArr = array();
            foreach($sort as $sort) {
                $newSortArr[] = "\"".$sort."\"";
            }
            $urlStr = implode(",", $newSortArr);
            $url .= "&sort=[".$urlStr."]";
        }
        else {
            $url .= "&sort=\"".$sort."\"";
        }
    }
    // pagination
    if($start && $duration) {
        $url .="&limit=".$duration."&skip=".$start;
    }
    // include full content
    if($content) {
        $url .= "&include_docs=true";
    }
    $output = $this->fetch_page($url);
    return json_decode($output,true);	
}



//-------------------------------------------------
// File Attachment
// one attachment per time
function attach_img ($attachArr) {
    // get _rev 
    $id = $attachArr["id"];
    $rev = $this->get_rev($id);
    
    $info = getimagesize($attachArr["fLoc"]);
    $fName = $attachArr["fName"];
    $fLoc = $attachArr["fLoc"];
    
    $dst = $this->base_url2."/".$id."/".$fName;
    
    $exe   = "curl ".
              "-H \"Referer: ".$this->referer."\" ".
              "-H \"Content-Type: ".$info['mime']."\" ".
              "-X PUT --data-binary @".$fLoc." ".
              $dst.
              "?rev=".$rev;
    $rtnArr = array(); 
    exec($exe,$rtnArr); 
    $rtnArr = json_decode($rtnArr[0],true);
    return $rtnArr;

}
//-------------------------------------------------




//-------------------------------------------------
//-------------------------------------------------
private function build_json_bulk ($inputArr) {
    // prepare json bulk file
    $json_bulk = "{\"docs\":[";
    $docStrArr = array();						 
    foreach($inputArr as $docArr) {
        $docStr = json_encode ($docArr);
        $docStrArr[] = $docStr;
    }
    $json_bulk .=implode(",",$docStrArr);
    $json_bulk .="]}";
    return $json_bulk;
}


private function fetch_page($url, $action=false, $data=false) {
    $ch = curl_init();	 // initialize curl handle
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_USERPWD, "$this->username:$this->password");
    curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
    
    // for insert
    if($action=="insert") {
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array ( "Content-Type:application/json" ) ); 
        curl_setopt($ch, CURLOPT_POSTFIELDS , $data); 
    }
    
    // HEAD only return header info
    if($action=="rev") {
        curl_setopt($ch, CURLOPT_HEADER, 1);
        curl_setopt($ch, CURLOPT_NOBODY, 1);
    }
    
    // DELETE, set customer request as "DELETE"
    if($action=="delete") {
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
    }
    
    $output = curl_exec($ch);
    // return header array for function get_rev
    if($action=="rev") {
        $headersArr = $this->get_headers_from_curl_response($output);
         return $headersArr;
    }
    
    // return whole response for other requests
    else {
        $info = curl_getinfo($ch);
        return $output;
    }
    curl_close($ch);
}

//-------------------------------------------------
// Get header array from curl response
private function get_headers_from_curl_response($response){
    $headers = array();
    $header_text = substr($response, 0, strpos($response, "\r\n\r\n"));
    foreach (explode("\r\n", $header_text) as $i => $line)
        if ($i === 0) {
            $headers['http_code'] = $line;
        }
        else{
            list ($key, $value) = explode(': ', $line);
            $headers[$key] = $value;
        }
    return $headers;
}
}
SUNWEB EXPERT