Skip to content

Instantly share code, notes, and snippets.

@p2k
Created August 21, 2012 11:31
Show Gist options
  • Save p2k/3414739 to your computer and use it in GitHub Desktop.
Save p2k/3414739 to your computer and use it in GitHub Desktop.
PHP class for easy use of CouchDB databases
<?php
/*
* class.couchdb.php - A class for easy use of CouchDB databases in PHP
*
* Copyright (C) 2012 Patrick "p2k" Schneider <[email protected]>
*
* This 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 3 of the License, or
* (at your option) any later version.
*
* This software 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 this software. If not, see <http://www.gnu.org/licenses/>.
*/
class CouchDB
{
private $db_auth = false;
private $db_host;
private $db_port;
private $db_prefix;
public function __construct($db_user = false, $db_pass = false, $db_host = "localhost", $db_port = 5984, $db_prefix = "")
{
if ($db_user !== false || $db_pass !== false)
$this->db_auth = "Basic " . base64_encode("$db_user:$db_pass");
$this->db_host = $db_host;
$this->db_port = $db_port;
$this->db_prefix = $db_prefix;
}
public function getView($db_name, $view_id, $view_name, $start_key = NULL, $end_key = NULL, $include_docs = false, $group_level = NULL)
{
$url = $this->db_prefix . "/$db_name/_design/$view_id/_view/$view_name";
$query = array();
if ($start_key !== NULL)
$query["start_key"] = json_encode($start_key);
if ($end_key !== NULL)
$query["end_key"] = json_encode($end_key);
if ($include_docs)
$query["include_docs"] = "true";
if ($group_level !== NULL)
$query["group_level"] = $group_level;
if (count($query) > 0)
$url .= "?" . http_build_query($query);
list($status, $reason, $headers, $result) = $this->sendJSONRequest("GET", $url);
if ($status != 200)
throw new Exception("getView: $status $reason");
return $result;
}
public function getViewMultiKey($db_name, $view_id, $view_name, $keys, $include_docs = false, $group = false)
{
$url = $this->db_prefix . "/$db_name/_design/$view_id/_view/$view_name";
$query = array("keys" => json_encode($keys));
if ($include_docs)
$query["include_docs"] = "true";
if ($group)
$query["group"] = "true";
$url .= "?" . http_build_query($query);
list($status, $reason, $headers, $result) = $this->sendJSONRequest("GET", $url);
if ($status != 200)
throw new Exception("getViewMultiKey: $status $reason");
return $result;
}
public function getDocument($db_name, $doc_id)
{
list($status, $reason, $headers, $doc) = $this->sendJSONRequest("GET", $this->db_prefix . "/$db_name/$doc_id");
if ($status != 200)
throw new Exception("getDocument: $status $reason");
return $doc;
}
public function putDocument($db_name, $doc)
{
if ($doc->_id === NULL) // Create new document?
$doc->_id = $this->getUUID();
list($status, $reason, $headers, $ret) = $this->sendJSONRequest("PUT", $this->db_prefix . "/$db_name/$doc->_id", $doc);
if ($status != 200 && $status != 201)
throw new Exception("putDocument: $status $reason");
$doc->_rev = $ret->rev;
return array($doc->_id, $doc->_rev);
}
public function deleteDocument($db_name, $doc_id, $doc_rev)
{
list($status, $reason, $headers, $ret) = $this->sendJSONRequest("DELETE", $this->db_prefix . "/$db_name/$doc_id?rev=$doc_rev");
if ($status != 200)
throw new Exception("deleteDocument: $status $reason");
}
private function getUUID()
{
list($status, $reason, $headers, $result) = $this->sendJSONRequest("GET", "/_uuids");
if ($status != 200)
throw new Exception("getUUID: $status $reason");
return $result->uuids[0];
}
private function sendJSONRequest($method, $url, $post_data = NULL)
{
// Open socket
$s = fsockopen($this->db_host, $this->db_port, $errno, $errstr);
if (!$s)
throw new Exception("fsockopen: $errno: $errstr");
// Prepare request
$request = "$method $url HTTP/1.0\r\n" .
($this->db_auth === false ? "" : "Authorization: $this->db_auth\r\n") .
"User-Agent: couchdb-php/1.0\r\n" .
"Host: $this->db_host:$this->db_port\r\n" .
"Accept: application/json\r\n" .
"Connection: close\r\n";
if ($method == "POST" || $method == "PUT") {
$json_data = json_encode($post_data);
$request .= "Content-Type: application/json\r\n" .
"Content-Length: " . strlen($json_data) . "\r\n\r\n" .
$json_data;
}
else
$request .= "\r\n";
// Send request
fwrite($s, $request);
$response = "";
// Receive response
while (!feof($s)) {
$response .= fgets($s);
}
// Split header & body
list($header, $body) = explode("\r\n\r\n", $response);
// Parse header
$headers = array();
$first = true;
foreach (explode("\r\n", $header) as $line) {
if ($first) {
$status = intval(substr($line, 9, 3));
$reason = substr($line, 13);
$first = false;
}
else {
$p = strpos($line, ":");
$headers[strtolower(substr($line, 0, $p))] = substr($line, $p+2);
}
}
// Return results
return array($status, $reason, $headers, json_decode($body));
}
}
?>
@integrii
Copy link

This isn't a Gist... this should be an actual github project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment