実際のリポジトリ上のURL http://svn.openpear.org/Net_TokyoTyrant/tags/0.2.0-beta/TokyoTyrant.php

repository browser : package Net_TokyoTyrant

revision
744
author
cocoiti
path
/Net_TokyoTyrant/tags/0.2.0-beta
last modified
2009/04/25 23:22:21

new protcol TokyoTyrant

source

<?php
class Net_TokyoTyrantException extends Exception {};
class Net_TokyoTyrantNetworkException extends Net_TokyoTyrantException {};
class Net_TokyoTyrantProtocolException extends Net_TokyoTyrantException {};

// License: MIT

class Net_TokyoTyrant
{
    private
      $connect = false;
    private
      $socket;
    private
      $errorNo, $errorMessage;
    private
      $socket_timeout;

    const RDBXOLCKNON = 0;
    const RDBXOLCKREC = 1;
    const RDBXOLCKGLB = 2;
    
    public function connect($server, $port, $timeout = 10)
    {
        $this->close();
        $this->socket = @fsockopen($server,$port, $this->errorNo, $errorMessage, $timeout);
        if (! $this->socket) {
            throw new Net_TokyoTyrantNetworkException(sprintf('%s, %s', $this->errorNo, $errorMessage));
        }
        $this->connect = true;
    }

    public function setTimeout($timeout)
    {
        $this->socket_timeout = $timeout;
        stream_set_timeout($this->socket, $timeout);
    }

    public function getTimeout()
    {
        return $this->socket_timeout;
    }

    public function close()
    {
        if ($this->connect) {
            fclose($this->socket);
        }
    }


    private function _read($length)
    {
        if ($this->connect === false) {
            throw new Net_TokyoTyrantException('not connected');
        }

        if (@feof($this->socket)) 
        {
            throw new Net_TokyoTyrantNetworkException('socket read eof error');
        }

        $result = fread($this->socket, $length);
        if ($result === false) {
            throw new Net_TokyoTyrantNetworkException('socket read error');
        }
        return $result;
    }


    private function _write($data)
    {
        $result = fwrite($this->socket, $data);
        if ($result === false) {
            throw new Net_TokyoTyrantNetworkException('socket read error');
        }
    }



    private function _doRequest($cmd, $values = array())
    {
        $this->_write($cmd . $this->_makeBin($values));
    }

    private function _makeBin($values){
        $int = '';
        $str = '';

        foreach ($values as  $value) {
            if (is_array($value)) {
                $str .= $this->_makeBin($value);
                continue;
            }

            if (! is_int($value)) {
                $int .= pack('N', strlen($value));
                $str .= $value;
                continue;
            } 

            $int .= pack('N', $value);
        }
        return $int . $str;
    }


    protected function _getResponse()
    {
        $res = fread($this->socket, 1);
        $res = unpack('c', $res);
        if ($res[1] !== 0) {
            throw new Net_TokyoTyrantProtocolException('Error Response');
        }
        return true; 
    }
    

    protected function _getInt1()
    {
        $result = '';
        $res = $this->_read(1);
        $res = unpack('c', $res);
        return $res[1];
    }

    protected function _getInt4()
    {
        $result = '';
        $res = $this->_read(4);
        $res = unpack('N', $res);
        return $res[1];
    }

    protected function _getInt8()
    {
        $result = '';
        $res = $this->_read(8);
        $res = unpack('N*', $res);
        return array($res[1], $res[2]);
    }

    protected function _getValue()
    {
        $result = '';
        $size = $this->_getInt4();
        return $this->_read($size);
    }


    protected function _getKeyValue()
    {
        $result = array();
        $ksize = $this->_getInt4();
        $vsize = $this->_getInt4();
        $result[] = $this->_read($ksize);
        $result[] = $this->_read($vsize);
        return $result;
    }

    protected function _getData()
    {
        $result = '';
        $size = $this->_getInt4();
        if ($size === 0) {
            return '';
        }
        return $this->_read((int) $size);
    }
    
    protected function _getDataList()
    {
        $result = array();
        
        $listCount = $this->_getInt4();
        for($i = 0;$i < $listCount; $i++) {
            $result[] = $this->_getValue();
        }
        return $result;
    }


    protected function _getKeyValueList()
    {
        $result = array();
        
        $listCount = $this->_getInt4();
        for($i = 0;$i < $listCount; $i++) {
            list($key, $value)  = $this->_getKeyValue();
            $result[$key] = $value;
        }
        return $result;
    }

    public function put($key, $value)
    {
        $cmd = pack('c*', 0xC8,0x10);
        $this->_doRequest($cmd, array((string) $key,(string) $value));
        try {
            $this->_getResponse();
        } catch (Net_TokyoTyrantProtocolException $e) {
            return false;
        }
        return true;
    }

    public function putkeep($key, $value)
    {
        $cmd = pack('c*', 0xC8,0x11);
        $this->_doRequest($cmd, array((string) $key,(string) $value));
        try {
            $this->_getResponse();
        } catch (Net_TokyoTyrantProtocolException $e) {
            return false;
        }
        return true;
    }
    
    public function putcat($key, $value)
    {
        $cmd = pack('c*', 0xC8,0x12);
        $this->_doRequest($cmd, array((string) $key,(string) $value));
        try {
            $this->_getResponse();
        } catch (Net_TokyoTyrantProtocolException $e) {
            return false;
        }
        return true;
    }
    
    public function putrtt($key, $value, $width)
    {
        $cmd = pack('c*', 0xC8,0x13);
        $this->_doRequest($cmd, array((string) $key, (string) $value, $width));
        try {
            $this->_getResponse();
        } catch (Net_TokyoTyrantProtocolException $e) {
            return false;
        }
        return true;
    }

    public function putnr($key, $value)
    {
        $cmd = pack('c*', 0xC8,0x18);
        $this->_doRequest($cmd, array((string) $key, (string) $value, (int) $width));
        try {
            $this->_getResponse();
        } catch (Net_TokyoTyrantProtocolException $e) {
            return ;
        }
        return ; 
    }

    public function out($key)
    {
        $cmd = pack('c*', 0xC8,0x20);
        $this->_doRequest($cmd, array((string) $key));
        try {
            $this->_getResponse();
        } catch (Net_TokyoTyrantProtocolException $e) {
            return false;
        }
        return true;
    }
    
    public function get($key)
    {
        $cmd = pack('c*', 0xC8,0x30);
        $this->_doRequest($cmd, array((string) $key));
        try {
            $this->_getResponse();
        } catch (Net_TokyoTyrantProtocolException $e) {
            return false;
        }
        return $this->_getData();
    }
    
    public function mget($keys)
    {
        $cmd = pack('c*', 0xC8,0x31);
        $values = array();
        $values[] = count($keys);
        foreach($keys as $key) {
          $values[] = array((string) $key);
        }
        
        $this->_doRequest($cmd, $values);
        try {
            $this->_getResponse();
        } catch (Net_TokyoTyrantProtocolException $e) {
            return false; 
        }
        return $this->_getKeyValueList();
    }

    public function fwmkeys($prefix, $max)
    {
        $cmd = pack('c*', 0xC8,0x58);
        $this->_doRequest($cmd, array((string) $prefix, (int) $max));
        $this->_getResponse();
        return $this->_getDataList();
    }
    
    public function addint($key, $num)
    {
        $cmd = pack('c*', 0xC8,0x60);
        $this->_doRequest($cmd, array((string) $key, (int) $num));
        $this->_getResponse();
        return $this->_getInt4();
    }
  
    public function putint($key, $num)
    {
        //This Code is non support
        $value = pack('V', $num);
        return $this->put($key, $value);
    }
  
    public function getint($key)
    {
        return $this->addint($key, 0);
    }

    public function adddouble($key, $integ, $fract)
    {
        $cmd = pack('c*', 0xC8,0x61);
        $this->_doRequest($cmd, array((string) $key, (int) $intteg, (int) $fract));
        $this->_getResponse();
        return array($this->_getInt8(), $this->_getInt8());
    }


    public function ext($extname, $key, $value, $option = 0)
    {
        $cmd = pack('c*', 0xC8,0x68);
        $this->_doRequest($cmd, array((string) $extname, (int) $option, (string) $key, (string) $value));
        $this->_getResponse();
        return $this->_getData();
    }

    public function vsize($key)
    {
        $cmd = pack('c*', 0xC8,0x38);
        $this->_doRequest($cmd, array((string) $key));
        $this->_getResponse();
        return $this->_getInt4();
    }
    
    public function iterinit()
    {
        $cmd = pack('c*', 0xC8,0x50);
        $this->_doRequest($cmd);
        $this->_getResponse();
        return true;
    }
    
    public function iternext()
    {
        $cmd = pack('c*', 0xC8,0x51);
        $this->_doRequest($cmd);
        try {
            $this->_getResponse();
        } catch (Net_TokyoTyrantProtocolException $e) {
            return false;
        }
        return $this->_getValue();
    }

    public function sync()
    {
        $cmd = pack('c*', 0xC8,0x70);
        $this->_doRequest($cmd);
        $this->_getResponse();
        return true;
    }
    
    public function optimize($param)
    {
        $cmd = pack('c*', 0xC8,0x71);
        $this->_doRequest($cmd, array((string) $param));
        $this->_getResponse();
        return true;
    }

    public function vanish()
    {
        $cmd = pack('c*', 0xC8,0x72);
        $this->_doRequest($cmd);
        $this->_getResponse();
        return true;
    }
    
    public function copy($path)
    {
        $cmd = pack('c*', 0xC8,0x73);
        $this->_doRequest($cmd, array((string) $path));
        $this->_getResponse();
        return true;
    }
    
//    public function restore($path)
//    {
//        $cmd = pack('c*', 0xC8,0x74);
//        $this->_doRequest($cmd, array((string) $path));
//        $this->_getResponse();
//        return true;
//    }
    
    public function setmst($host, $port)
    {
        $cmd = pack('c*', 0xC8,0x78);
        $this->_doRequest($cmd, array((string) $host, (int) $port));
        $this->_getResponse();
        return true;
    }
 
    public function rnum()
    {
        $cmd = pack('c*', 0xC8,0x80);
        $this->_doRequest($cmd);
        $this->_getResponse();
        return $this->_getInt8();
    }
 
    public function size()
    {
        $cmd = pack('c*', 0xC8,0x81);
        $this->_doRequest($cmd);
        $this->_getResponse();
        return $this->_getInt8();
    }

    public function stat()
    {
        $cmd = pack('c*', 0xC8,0x88);
        $this->_doRequest($cmd);
        $this->_getResponse();
        return $this->_getValue();
    }
}