1. codernity
  2. CodernityDB-PHPClient

Commits

codernity  committed beb6f58 Draft

First public release

  • Participants
  • Branches default
  • Tags 0.1.0

Comments (0)

Files changed (3)

File README.rst

View file
  • Ignore whitespace
+=====================
+CodernityDB-PHPClient
+=====================
+
+CodernityDB-PHPClient is a simple CodernityDB_ client library written in pure PHP.
+Can be used with standard http sockets or curl. CodernityDB-HTTP_ is required to work with CodernityDB-PHPClient.
+
+Contribute & Bugs & Requests
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+CodernityDB-PHPClient is one of projects developed and released by Codernity_, so you can contact us directly in any case.
+
+Do you want to contribute? Great! Then just fork our repository on Bitbucket and do a pull request. It can't be more easy!
+
+To fill a bug please use also use Bitbucket.
+
+Support
+~~~~~~~
+
+In case of any problems, feature request you can also contact us directly.
+
+Do you want customized version of CodernityDB-PHPClient? No problem, just contact us.
+
+
+.. _Codernity: http://codernity.com
+.. _CodernityDB: https://bitbucket.org/codernity/codernitydb
+.. _CodernityDB-HTTP: https://bitbucket.org/codernity/codernitydb-http
+

File codernitydb.php

View file
  • Ignore whitespace
+<?php
+
+/*
+Copyright (C) 2011-2012 Codernity.com
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program 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 Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+class Codernitydb
+{
+
+    /**
+     * @var string CodernityDB-HTTP host address
+     */
+    private $_host = 'localhost';
+
+    /**
+     * @var string CodernityDB-HTTP port number
+     */
+    private $_port = 9876;
+
+    /**
+     * @var string CodernityDB-HTTP username
+     */
+    private $_username = null;
+
+    /**
+     * @var string CodernityDB-HTTP password
+     */
+    private $_password = null;
+
+    /**
+     * @var boolean tell if curl PHP extension has been detected
+     */
+    protected $_curl = false;
+
+    /**
+     * @var boolean tell if msgpack PHP extension has been detected
+     */
+    protected $_msgpack = false;
+
+    /**
+     * @var string default request content type
+     */
+    protected $_contentType = 'application/json';
+
+    /**
+    * class constructor
+    *
+    * @param array $config cofiguration data
+    */
+    public function __construct($config = array())
+    {
+
+        if (isset($config['host']))
+            $this->_host = $config['host'];
+        if (isset($config['port']))
+            $this->_host = $config['port'];
+
+        $this->_username = $config['username'];
+        $this->_password = $config['password'];
+
+        if (function_exists('curl_init'))
+            $this->_curl = true;
+
+        if (function_exists('msgpack_pack'))
+            $this->_msgpack = true;
+
+        if($this->_msgpack)
+            $this->_contentType = 'application/msgpack';
+
+    }
+
+    /**
+     * getting data
+     * 
+     * @param string $docId document ID
+     * @return stdClass { status: [int] response code,
+     * doc: [array] decoded response body |
+     * details: [array] decoded response body }
+     */
+    public function get($docId)
+    {
+        $response = $this->_makeRequest('GET', '/get/id/' . $docId);
+        $output = new StdClass;
+        $output->status = $response->status;
+
+        if ($response->status == 200) {
+            $output->doc = $response->content;
+        } else {
+            $output->details = $response->content;
+        }
+        
+        return $output;
+    }
+
+    /**
+     * inserting new document
+     *
+     * @param array $doc document
+     * @return stdClass { status: [int] response code,
+     * doc: [array] decoded response body |
+     * details: [array] decoded response body }
+     */
+    public function insert($doc)
+    {
+        $response = $this->_makeRequest('POST', '/insert', $doc);
+        $output = new StdClass;
+        $output->status = $response->status;
+
+        if ($response->status == 200) {
+            $output->doc = $response->content;
+        } else {
+            $output->details = $response->content;
+        }
+
+        return $output;
+    }
+
+    /**
+     * update existing document
+     * 
+     * @param array $doc document
+     * @return stdClass { status: [int] response code,
+     * doc: [array] decoded response body |
+     * details: [array] decoded response body }
+     */
+    public function update($doc)
+    {
+        $response = $this->_makeRequest('POST', '/update', $doc);
+        $output = new StdClass;
+        $output->status = $response->status;
+
+        if ($response->status == 200) {
+            $output->doc = $response->content;
+        } else {
+            $output->details = $response->content;
+        }
+
+        return $output;
+    }
+
+    /**
+     * purging data
+     *
+     * @param string $docId document id
+     * @param string $revId revision id
+     * @return stdClass { true | status: [int] response code,
+     * details: [array] decoded response body }
+     */
+    public function delete($docId, $revId)
+    {
+        $data = array(
+            '_id' => $docId,
+            '_rev' => $revId
+        );
+
+        $response = $this->_makeRequest('POST', '/delete', $data);
+        if ($response->status == 200) {
+            return $response->content;
+        }
+
+        $output = new StdClass;
+        $output->details = $response->content;
+        return $output;
+    }
+
+    /**
+     * prepares HTTP request
+     */
+    private function _makeRequest($method, $url, $data = false)
+    {
+        if ($this->_curl)
+            return $this->_makeCurlRequest($method, $url, $data);
+        else
+            return $this->_makeSocketRequest($method, $url, $data);
+    }
+
+    /**
+     * makes CURL request
+     */
+    private function _makeCurlRequest($method, $url, $data = false)
+    {
+        $ch = curl_init();
+        curl_setopt($ch, CURLOPT_URL, $this->_host . $url);
+        curl_setopt($ch, CURLOPT_PORT, $this->_port);
+        curl_setopt(
+            $ch,
+            CURLOPT_USERPWD,
+            $this->_username . ":" . $this->_password
+        );
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+        curl_setopt(
+            $ch,
+            CURLOPT_HTTPHEADER,
+            array('Content-type: ' . $this->_contentType)
+        );
+
+        if (is_object($data) || is_array($data)) {
+            $data = $this->_prepareInputData($data);
+            curl_setopt($ch, CURLOPT_POST, true);
+            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
+        }
+
+        $content = curl_exec($ch);
+
+        if ($content === false) {
+            throw new Exception(
+                'Could not open connection to '
+                . $this->_host . ':' . $this->_port . ': '
+                . curl_error($ch)
+            );
+            return false;
+        }
+
+        $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
+
+        $output = new StdClass;
+        $output->status = $status;
+        $output->content = $this->_prepareOutputData($content);
+        return $output;
+    }
+
+    /**
+     * makes Socket request
+     */
+    private function _makeSocketRequest($method, $url, $data = false)
+    {
+        $request = $this->_prepareSocketRequest($method, $url, $data);
+
+        $socket = @fsockopen(
+            $this->_host,
+            $this->_port,
+            $errNum,
+            $errString
+        );
+        
+        if (!$socket) {
+            throw new Exception(
+                'Could not open connection to '
+                . $this->_host . ':' . $this->_port . ': '
+                . $errString.' (' . $errNum . ')'
+            );
+            return false;
+        }
+
+        fwrite($socket, $request);
+        $response = '';
+        while (!feof($socket))
+            $response .= fgets($socket);
+
+        @fclose($socket);
+        return $this->_parseSocketResponse($response);
+    }
+
+    /**
+     * encodes input data to JSON
+     */
+    private function _prepareInputData($data)
+    {
+        if($this->_msgpack)
+            $func = 'msgpack_pack';
+        else
+            $func = 'json_encode';
+        
+        return $func(
+            array(
+                'data' => $data
+            )
+        );
+    }
+
+    /**
+     * decodes output data from JSON
+     */
+    private function _prepareOutputData($data)
+    {
+        if ($this->_msgpack)
+            return msgpack_unpack($data);
+        else
+            return get_object_vars(json_decode($data));
+    }
+
+    /**
+     * prepares socket request content
+     */
+    private function _prepareSocketRequest($method, $url, $data)
+    {
+        $request = "$method $url HTTP/1.0\r\n";
+        $request .= "Host: $this->_host \r\n";
+        $request .= 'Authorization: Basic ' . base64_encode(
+            $this->_username . ':' . $this->_password
+        ) . "\r\n";
+        $request .= "Accept: ' . $this->_contentType
+                . ',text/html,text/plain,*/*\r\n";
+
+        if (is_object($data) || is_array($data)) {
+            $data = $this->_prepareInputData($data);
+            $request .= "Content-Type: $this->_contentType\r\n";
+            $request .= "Content-Length: strlen($data)\r\n\r\n";
+            $request .= $data."\r\n";
+        } else {
+            $request .= "\r\n";
+        }
+        
+        return $request;
+    }
+
+    /**
+     * returns body and status from socket response
+     */
+    private function _parseSocketResponse($rawData, $jsonAsArray = FALSE)
+    {
+        if (!strlen($rawData))
+            throw new InvalidArgumentException("no data to parse");
+        while (
+            !substr_compare(
+                $rawData, "HTTP/1.1 100 Continue\r\n\r\n",
+                0,
+                25
+            )
+        ) {
+            $rawData = substr($rawData, 25);
+        }
+        $response = new StdClass;
+        list($headers, $body) = explode("\r\n\r\n", $rawData, 2);
+        $headersArray = explode("\n", $headers);
+        $statusLine = reset($headersArray);
+        $statusArray = explode(' ', $statusLine, 3);
+        $response->status = trim($statusArray[1]);
+        if (strlen($body)) {
+            $response->content =
+                preg_match(
+                    '@Content-Type:\s+' . $this->_contentType.'@i',
+                    $headers
+                )
+                ? json_decode($body, $jsonAsArray)
+                : $body;
+        }
+        return $response;
+    }
+
+}

File example.php

View file
  • Ignore whitespace
+<?php
+
+/*
+Copyright (C) 2011-2012 Codernity.com
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program 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 Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+require_once dirname(__FILE__) . '/codernitydb.php';
+
+$config = array(
+    'username' => 'admin',
+    'password' => 'password'
+);
+
+$db = new Codernitydb($config);
+
+$doc = array(
+    'key1' => 'Value 1',
+    'key2' => 'Value 2'
+);
+
+$insert = $db->insert($doc);
+
+echo "INSERT:\n----------------------------------------------------\n";
+var_dump($insert);
+
+if ($insert->status != 200) {
+    echo $insert->details['error'];
+    exit;
+}
+
+$docId = $insert->doc['_id'];
+$revId = $insert->doc['_rev'];
+
+$get = $db->get($docId);
+
+echo "GET:\n----------------------------------------------------\n";
+print_r($get);
+
+if ($get->status != 200) {
+    echo $get->details['error'];
+    exit;
+}
+
+$doc = $get->doc;
+$doc['key3'] = 'Value 3';
+$update = $db->update($doc);
+
+if ($update->status != 200) {
+    echo $update->details['error'];
+    exit;
+}
+
+echo "UPDATE:\n----------------------------------------------------\n";
+print_r($update);
+
+$docId = $update->doc['_id'];
+$revId = $update->doc['_rev'];
+
+$get = $db->get($docId);
+
+echo "GET:\n----------------------------------------------------\n";
+print_r($get);
+
+$delete = $db->delete($docId, $revId);
+
+if ($delete !== true) {
+    echo $delete->details['error'];
+    exit;
+}
+
+echo "DELETE:\n----------------------------------------------------\n";
+var_dump($delete);