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; } }