Tokyo Tyrant的PHP类

Tyrant文件夹里的文件

Common.php

<?php
/**
* Tokyo Tyrant network API for PHP
*
* Copyright (c) 2009 Bertrand Mansion <bmansion@mamasam.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package Tyrant
* @author Bertrand Mansion <bmansion@mamasam.com>
* @license http://www.opensource.org/licenses/mit-license.php MIT License
* @link http://mamasam.indefero.net/p/tyrant/
*/
require_once dirname(__FILE__).'/../Tyrant.php';
require_once dirname(__FILE__).'/Exception.php';

/**
* Abstract base class for all types of database connections
*
* This base class is mostly here to avoid duplication of code since
* databases share common functions. It
*
* @package Tyrant
* @author Bertrand Mansion <bmansion@mamasam.com>
*/
abstract class Tyrant_Common implements ArrayAccess, Countable, Iterator
{
protected $socket;

abstract function put($key, $value);
abstract function get($key);


public function __construct(&$socket)
{
$this->socket =& $socket;
}

/**
* Close the connection to TokyoTyrant
*/
public function disconnect()
{
if (is_resource($this->socket)) {
socket_close($this->socket);
$this->socket = null;
}
}

/**
* Returns the connection socket
* @return resource Connection socket
*/
public function &socket()
{
return $this->socket;
}

/**
* Removes a record
*
* @param string Specifies the primary key
* @return bool True when successful, false otherwise
*/
public function out($key)
{
$cmd = pack('CCN', 0xC8, 0x20, strlen($key)) . $key;
$code = $this->_send($cmd);
if ($code !== 0) {
return false;
}
return true;
}

/**
* Gets the size of the value of a record
*
* @param string Specifies the key
* @return int|false Number with size or false otherwise
*/
public function vsiz($key)
{
$cmd = pack("CCN", 0xC8, 0x38, strlen($key)) . $key;
$code = $this->_send($cmd);
if ($code !== 0) {
return false;
}
return $this->_recvInt32();
}

/**
* Initializes the iterator
*
* The iterator is used in order to access the key of every record
* stored in a database.
*
* @return bool True when successful, false otherwise
*/
public function iterinit()
{
$cmd = pack("CC", 0xC8, 0x50);
$code = $this->_send($cmd);
if ($code !== 0) {
return false;
}
return true;
}

/**
* Gets the next key of the iterator
*
* It is possible to access every record by iteration of
* calling this method. It is allowed to update or remove
* records whose keys are fetched while the iteration.
* However, it is not assured if updating the database is
* occurred while the iteration. Besides, the order of this
* traversal access method is arbitrary, so it is not assured
* that the order of storing matches the one of the traversal
* access.
*
* @return mixed Either the next key when successful, false if no more records are available
*/
public function iternext()
{
$cmd = pack("CC", 0xC8, 0x51);
$code = $this->_send($cmd);
if ($code !== 0) {
return false;
}
$ksiz = $this->_recvInt32();
if ($ksiz === false) {
return false;
}
$kref = $this->_recv($ksiz);
return $kref;
}

/**
* Gets forward matching keys
*
* The return value is an array of the keys of the
* corresponding records. This method does never fail and return
* an empty array even if no record corresponds. Note that this
* method may be very slow because every key in the database is
* scanned.
*
* @param string Prefix of the corresponding keys
* @param int Maximum number of keys to be fetched. If it
* is not defined or negative, no limit is specified.
* @return array An array of found primary keys
*/
public function fwmkeys($prefix, $max = null)
{
$keys = array();
if (empty($max) || $max < 0) {
$max = (1<<31);
}
$cmd = pack("CCNN", 0xC8, 0x58, strlen($prefix), $max) . $prefix;
$code = $this->_send($cmd);
if ($code !== 0) {
return $keys;
}
$knum = $this->_recvInt32();
if ($knum === false) {
return $keys;
}
for ($i = 0; $i < $knum; $i++) {
$ksiz = $this->_recvInt32();
if ($ksiz === false) {
return $keys;
}
$kref = $this->_recv($ksiz);
$keys[] = $kref;
}
return $keys;
}

/**
* Synchronizes updated contents with the file and the device
* @return bool True when successful, false otherwise
*/
public function sync()
{
$cmd = pack('CC', 0xC8, 0x70);
$code = $this->_send($cmd);
if ($code !== 0) {
return false;
}
return true;
}

/**
* Optimize the database file
* @return bool True when successful, false otherwise
*/
public function optimize($params = "")
{
$cmd = pack('CCN', 0xC8, 0x71, strlen($params)) . $params;
$code = $this->_send($cmd);
if ($code !== 0) {
return false;
}
return true;
}

/**
* Remove all records
* @return bool True when successful, false otherwise
*/
public function vanish()
{
$cmd = pack('CC', 0xC8, 0x72);
$code = $this->_send($cmd);
if ($code !== 0) {
return false;
}
return true;
}

/**
* Copy the database file
*
* The database file is assured to be kept synchronized and not modified
* while the copying or executing operation is in progress.
* So, this method is useful to create a backup file of the database file.
*
* @param string Specifies the path of the destination file.
* If it begins with `@', the trailing substring
* is executed as a command line.
* @return True if successful, false otherwise.
*/
public function copy($path)
{
$cmd = pack('CCN', 0xC8, 0x73, strlen($path)) . $path;
$code = $this->_send($cmd);
if ($code !== 0) {
return false;
}
return true;
}

/**
* Restore the database with update log
*
* @param Specifies the path of the update log directory
* @param Specifies the beginning time stamp in microseconds
* @param Specifies options by bitwise-or:
* - Tyrant::ROCHKCON for consistency checking
* @return True if successful, false otherwise.
*/
public function restore($path, $msec, $opts = 0)
{
$cmd = pack('CCN', 0xC8, 0x74, strlen($path)) .
$this->_pack64($msec) . $opts . $path;
$code = $this->_send($cmd);
if ($code !== 0) {
return false;
}
return true;
}

/**
* Get the number of records
* @return int|false Number of records or false if something goes wrong
*/
public function rnum()
{
$cmd = pack('CC', 0xC8, 0x80);
$code = $this->_send($cmd);
if ($code !== 0) {
return false;
}
return $this->_recvInt64();
}

/**
* Get the size of the database
* @return mixed Database size or false if something goes wrong
*/
public function size()
{
$cmd = pack('CC', 0xC8, 0x81);
$code = $this->_send($cmd);
if ($code !== 0) {
return false;
}
return $this->_recvInt64();
}

/**
* Get some statistics about the database
* @return array Array of statistics about the database
*/
public function stat()
{
$cmd = pack('CC', 0xC8, 0x88);
$code = $this->_send($cmd);
if ($code !== 0) {
return false;
}
$value = $this->_recv();
$value = explode("\n", trim($value));
$stats = array();
foreach ($value as $v) {
$v = explode("\t", $v);
$stats[$v[0]] = $v[1];
}
return $stats;
}


/**
* Call a versatile function for miscellaneous operations
*
* All databases support "putlist", "outlist", and "getlist".
* - putlist is to store records. It receives keys and values one
* after the other, and returns an empty list.
* - outlist is to remove records. It receives keys, and returns
* an empty list.
* - getlist is to retrieve records. It receives keys, and returns
* values.
*
* Table database supports "setindex", "search", "genuid".
*
* @param string Specifies the name of the function
* @param array Specifies an array containing arguments
* @param int Specifies options by bitwise-or
* bitflag that can be Tyrant::MONOULOG to prevent
* writing to the update log
* @return array|false Values or false if something goes wrong
*/
public function misc($name, Array $args = array(), $opts = 0)
{
$cmd = pack('CCNNN', 0xC8, 0x90, strlen($name), $opts,
count($args)) . $name;
foreach ($args as $arg) {
$cmd .= pack('N', strlen($arg)) . $arg;
}
$code = $this->_send($cmd);
if ($code !== 0) {
return false;
}
$rnum = $this->_recvInt32();
$res = array();
for ($i = 0; $i < $rnum; $i++) {
$esiz = $this->_recvInt32();
if ($esiz === false) {
return false;
}
$eref = $this->_recv($esiz);
if ($eref === false) {
return false;
}
$res[] = $eref;
}
return $res;
}


/**
* Call a function of the script language extension
*
* @param string Specifies the function name
* @param string Specifies the key. Defaults to an empty string.
* @param string Specifies the value. Defaults to an empty string.
* @param int Specifies options by bitwise-or:
* - Tyrant::XOLCKREC for record locking
* - Tyrant::XOLCKGLB for global locking
* Defaults to no option.
* @return mixed Value of the response or false on failure
*/
public function ext($name, $key = '', $value = '', $opts = 0)
{
$cmd = pack('CCNNNN', 0xC8, 0x68, strlen($name), $opts,
strlen($key), strlen($value)) .
$name . $key . $value;
$code = $this->_send($cmd);
if ($code !== 0) {
return false;
}
$vsiz = $this->_recvInt32();
if ($vsiz < 0) {
return false;
}
$vbuf = $this->_recv($vsiz);
return $vbuf;
}


protected function _socketWrite($cmd)
{
$len = strlen($cmd);
$offset = 0;
while ($offset < $len) {
$sent = socket_write($this->socket, substr($cmd, $offset), $len-$offset);
if ($sent === false) {
return false;
}
$offset += $sent;
}
return ($offset < $len) ? false : true;
}

protected function _send($cmd)
{
$status = $this->_socketWrite($cmd);
if ($status === false) {
return false;
}
$code = $this->_recvCode();
if ($code === false) {
return false;
}
return $code;
}

protected function _recv($len = null)
{
if (is_null($len)) {
$len = $this->_recvInt32();
if ($len === false) {
return false;
}
}
if ($len < 1) {
return "";
}
$str = "";
if (($rec = socket_recv($this->socket, $str, $len, 0)) <= 0) {
return false;
}
if (strlen($str) == $len) {
return $str;
}
$len -= strlen($str);
while ($len > 0) {
$tstr = "";
if (($rec = socket_recv($this->socket, $tstr, $len, 0)) <= 0) {
return false;
}
$len -= strlen($tstr);
$str .= $tstr;
}
return $str;
}

protected function _recvCode()
{
if (($rbuf = $this->_recv(1)) !== false) {
$c = unpack("C", $rbuf);
if (!isset($c[1])) {
return false;
}
return $c[1];
}
return false;
}

protected function _recvInt32()
{
if (($rbuf = $this->_recv(4)) !== false) {
$num = unpack("N", $rbuf);
if (!isset($num[1])) {
return false;
}
$size = unpack("l", pack("l", $num[1]));
return $size[1];
}
return false;
}

protected function _recvInt64()
{
if (($rbuf = $this->_recv(8)) !== false) {
return $this->_unpack64($rbuf);
}
return false;
}

/**
* Portability function to pack a x64 value with PHP limitations
* @return mixed Packed number
*/
protected function _pack64($v)
{
// x64
if (PHP_INT_SIZE >= 8) {
$v = (int)$v;
return pack ("NN", $v>>32, $v&0xFFFFFFFF);
}
// x32, int
if (is_int($v)) {
return pack("NN", $v < 0 ? -1 : 0, $v);
}
// x32, bcmath
if (function_exists("bcmul")) {
if (bccomp($v, 0) == -1) {
$v = bcadd("18446744073709551616", $v);
}
$h = bcdiv($v, "4294967296", 0);
$l = bcmod($v, "4294967296");
return pack ("NN", (float)$h, (float)$l); // conversion to float is intentional; int would lose 31st bit
}
// x32, no-bcmath
$p = max(0, strlen($v) - 13);
$lo = abs((float)substr($v, $p));
$hi = abs((float)substr($v, 0, $p));
$m = $lo + $hi*1316134912.0; // (10 ^ 13) % (1 << 32) = 1316134912
$q = floor($m/4294967296.0);
$l = $m - ($q*4294967296.0);
$h = $hi*2328.0 + $q; // (10 ^ 13) / (1 << 32) = 2328
if ($v < 0) {
if ($l == 0) {
$h = 4294967296.0 - $h;
} else {
$h = 4294967295.0 - $h;
$l = 4294967296.0 - $l;
}
}
return pack("NN", $h, $l);
}

/**
* Portability function to unpack a x64 value with PHP limitations
* @return mixed Might return a string of numbers or the actual value
*/
protected function _unpack64($v)
{
list($hi, $lo) = array_values (unpack("N*N*", $v));
// x64
if (PHP_INT_SIZE >= 8) {
if ($hi < 0) $hi += (1<<32); // because php 5.2.2 to 5.2.5 is totally fucked up again
if ($lo < 0) $lo += (1<<32);
return ($hi<<32) + $lo;
}
// x32, int
if ($hi == 0) {
if ($lo > 0) {
return $lo;
}
return sprintf("%u", $lo);
} elseif ($hi == -1) {
// x32, int
if ($lo < 0) {
return $lo;
}
return sprintf("%.0f", $lo - 4294967296.0);
}
$neg = "";
$c = 0;
if ($hi < 0) {
$hi = ~$hi;
$lo = ~$lo;
$c = 1;
$neg = "-";
}
$hi = sprintf ("%u", $hi);
$lo = sprintf ("%u", $lo);
// x32, bcmath
if (function_exists("bcmul")) {
return $neg . bcadd(bcadd($lo, bcmul($hi, "4294967296")), $c);
}
// x32, no-bcmath
$hi = (float)$hi;
$lo = (float)$lo;
$q = floor($hi/10000000.0);
$r = $hi - $q*10000000.0;
$m = $lo + $r*4967296.0;
$mq = floor($m/10000000.0);
$l = $m - $mq*10000000.0 + $c;
$h = $q*4294967296.0 + $r*429.0 + $mq;
$h = sprintf("%.0f", $h);
$l = sprintf("%07.0f", $l);
if ($h == "0") {
return $neg . sprintf("%.0f", (float)$l);
}
return $neg . $h . $l;
}

/**
* Store the current iterator key or false if no key is available
* @var string
*/
protected $_current;

/**
* Rewind the Iterator to the first element.
* Similar to the reset() function for arrays in PHP
* @return void
*/
public function rewind()
{
$this->iterinit();
$this->_current = $this->iternext();
}

/**
* Return the current element.
* Similar to the current() function for arrays in PHP
* @return mixed current element from the collection
*/
public function current()
{
return $this->get($this->_current);
}

/**
* Return the identifying key of the current element.
* Similar to the key() function for arrays in PHP
* @return mixed either an integer or a string
*/
public function key()
{
return $this->_current;
}

/**
* Move forward to next element.
* Similar to the next() function for arrays in PHP
* @return void
*/
public function next()
{
$this->_current = $this->iternext();
}

/**
* Check if there is a current element after calls to rewind() or next().
* Used to check if we've iterated to the end of the collection
* @return boolean FALSE if there's nothing more to iterate over
*/
public function valid()
{
return $this->_current !== false;
}


/**
* Returns whether the key exists
* @return boolean
*/
public function offsetExists($offset)
{
return $this->vsiz($offset) !== false;
}

/**
* Returns the value associated with the key
* @return mixed
*/
public function offsetGet($offset)
{
return $this->get($offset);
}

/**
* Sets a value for the key
* @return boolean True if value was set successfully
*/
public function offsetSet($offset, $value)
{
return $this->put($offset, $value);
}

/**
* Removes the value for the key
* @return void
*/
public function offsetUnset($offset)
{
$this->out($offset);
}

/**
* Returns the number of records in the database
* @return int Number of records
*/
public function count()
{
return $this->rnum();
}
}

Exception.php

<?php
/**
* Tokyo Tyrant network API for PHP
*
* Copyright (c) 2009 Bertrand Mansion <bmansion@mamasam.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package Tyrant
* @author Bertrand Mansion <bmansion@mamasam.com>
* @license http://www.opensource.org/licenses/mit-license.php MIT License
* @link http://mamasam.indefero.net/p/tyrant/
*/

/**
* Base class for Exceptions in Tyrant package
*
* @package Tyrant
*/
class Tyrant_Exception extends Exception { }

Query.php

<?php
/**
* Tokyo Tyrant network API for PHP
*
* Copyright (c) 2009 Bertrand Mansion <bmansion@mamasam.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package Tyrant
* @author Bertrand Mansion <bmansion@mamasam.com>
* @license http://www.opensource.org/licenses/mit-license.php MIT License
* @link http://mamasam.indefero.net/p/tyrant/
*/

/**
* Query class for the RDBTable database queries
*
* @package Tyrant
* @author Bertrand Mansion <bmansion@mamasam.com>
*/
class Tyrant_Query
{
/**
* Query arguments
* @var array
*/
protected $args = array();

/**
* Query condition: string is equal to
*/
const QCSTREQ = 0;

/**
* Query condition: string is included in
*/
const QCSTRINC = 1;

/**
* Query condition: string begins with
*/
const QCSTRBW = 2;

/**
* Query condition: string ends with
*/
const QCSTREW = 3;

/**
* Query condition: string includes all tokens in
*/
const QCSTRAND = 4;

/**
* Query condition: string includes at least one token in
*/
const QCSTROR = 5;

/**
* Query condition: string is equal to at least one token in
*/
const QCSTROREQ = 6;

/**
* Query condition: string matches regular expressions of
*/
const QCSTRRX = 7;

/**
* Query condition: number is equal to
*/
const QCNUMEQ = 8;

/**
* Query condition: number is greater than
*/
const QCNUMGT = 9;

/**
* Query condition: number is greater than or equal to
*/
const QCNUMGE = 10;

/**
* Query condition: number is less than
*/
const QCNUMLT = 11;

/**
* Query condition: number is less than or equal to
*/
const QCNUMLE = 12;

/**
* Query condition: number is between two tokens of
*/
const QCNUMBT = 13;

/**
* Query condition: number is equal to at least one token in
*/
const QCNUMOREQ = 14;

/**
* Query condition: full-text search with the phrase of the expression
*/
const QCFTSPH = 15;

/**
* Query condition: full-text search with all tokens in the expression
*/
const QCFTSAND = 16;

/**
* Query condition: full-text search with at least one token in the expression
*/
const QCFTSOR = 17;

/**
* Query condition: full-text search with the compound expression
*/
const QCFTSEX = 18;

/**
* Query condition: negation flag
*/
const QCNEGATE = 16777216;

/**
* Query condition: no index flag
*/
const QCNOIDX = 33554432;

/**
* Order type: string ascending
*/
const QOSTRASC = 0;

/**
* Order type: string descending
*/
const QOSTRDESC = 1;

/**
* Order type: number ascending
*/
const QONUMASC = 2;

/**
* Order type: number descending
*/
const QONUMDESC = 3;

/**
* Add a query argument for "string is equal to column"
* @param string Column to query upon
* @param string Value to search
*/
public function is($name, $expr)
{
$this->addCond($name, self::QCSTREQ, $expr);
}

/**
* Add a query argument for "string is included in column"
* @param string Column to query upon
* @param string Value to search
*/
public function like($name, $expr)
{
$this->addCond($name, self::QCSTRINC, $expr);
}

/**
* Add a query argument for "string includes at least one token from column"
* @param string Column to query upon
* @param string Value to search
*/
public function has($name, $expr)
{
$this->addCond($name, self::QCSTROR, $expr);
}

/**
* Add a query argument for "string includes all tokens from column"
* @param string Column to query upon
* @param string Value to search
*/
public function hasAll($name, $expr)
{
$this->addCond($name, self::QCSTRAND, $expr);
}

/**
* Add a query argument for "string is equal to at least one token from column"
* @param string Column to query upon
* @param string Value to search
*/
public function isOne($name, $expr)
{
$this->addCond($name, self::QCSTROREQ, $expr);
}

/**
* Add a query argument for "string begins with"
* @param string Column to query upon
* @param string Value to search
*/
public function starts($name, $expr)
{
$this->addCond($name, self::QCSTRBW, $expr);
}

/**
* Add a query argument for "string ends with"
* @param string Column to query upon
* @param string Value to search
*/
public function ends($name, $expr)
{
$this->addCond($name, self::QCSTREW, $expr);
}

/**
* Add a query argument for "string matches regular expressions of"
* @param string Column to query upon
* @param string Value to search
*/
public function matches($name, $expr)
{
$this->addCond($name, self::QCSTRRX, $expr);
}

/**
* Add a query argument for "number is equal to"
* @param string Column to query upon
* @param string Value to search
*/
public function eq($name, $expr)
{
$this->addCond($name, self::QCNUMEQ, $expr);
}

/**
* Add a query argument for "number is greater than"
* @param string Column to query upon
* @param string Value to search
*/
public function gt($name, $expr)
{
$this->addCond($name, self::QCNUMGT, $expr);
}

/**
* Add a query argument for "number is greater than or equal to"
* @param string Column to query upon
* @param string Value to search
*/
public function gte($name, $expr)
{
$this->addCond($name, self::QCNUMGE, $expr);
}

/**
* Add a query argument for "number is less than"
* @param string Column to query upon
* @param string Value to search
*/
public function lt($name, $expr)
{
$this->addCond($name, self::QCNUMLT, $expr);
}

/**
* Add a query argument for "number is less than or equal to"
* @param string Column to query upon
* @param string Value to search
*/
public function lte($name, $expr)
{
$this->addCond($name, self::QCNUMLE, $expr);
}

/**
* Add a query argument for "number is between two tokens of"
* @param string Column to query upon
* @param string Value to search
*/
public function between($name, $expr)
{
$this->addCond($name, self::QCNUMBT, $expr);
}

/**
* Add a query argument for "number is equal to at least one token in"
* @param string Column to query upon
* @param string Value to search
*/
public function eqOne($name, $expr)
{
$this->addCond($name, self::QCNUMOREQ, $expr);
}

/**
* Add a sort parameter for the query
* @param string Column to sort
* @param string 'numeric' or 'literal'
* @param string 'asc' or 'desc'
*/
public function sortBy($name, $type = 'numeric', $direction = 'asc')
{
if ($type != 'numeric') {
$type = $direction != 'asc' ? self::QOSTRDESC : self::QOSTRASC;
} else {
$type = $direction != 'asc' ? self::QONUMDESC : self::QONUMASC;
}
$this->setOrder($name, $type);
}

/**
* Add a narrowing condition for the query.
* @param string Name of a column. An empty string means the primary key.
* @param int Operation type, see class constants.
* @param mixed Operand exression.
*/
public function addCond($name, $op, $expr)
{
$this->args[] = "addcond\0" . $name . "\0" . $op . "\0" . $expr;
}

/**
* Add a sort parameter for the query
* @param string Name of a column.
* @param int Sort type, see class constants.
*/
public function setOrder($name, $type)
{
$this->args['order'] = "setorder\0" . $name . "\0" . $type;
}

/**
* Limit the number of records returned by the query
* @param int Maximum number of records returned
* @param int Number of records to skip
*/
public function setLimit($max = -1, $skip = -1)
{
$this->args['limit'] = "setlimit\0" . $max . "\0" . $skip;
}

/**
* Return the query arguments
* @return array Query arguments
*/
public function args()
{
return $this->args;
}
}

RDB.php

<?php
/**
* Tokyo Tyrant network API for PHP
*
* Copyright (c) 2009 Bertrand Mansion <bmansion@mamasam.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package Tyrant
* @author Bertrand Mansion <bmansion@mamasam.com>
* @license http://www.opensource.org/licenses/mit-license.php MIT License
* @link http://mamasam.indefero.net/p/tyrant/
*/

require_once dirname(__FILE__).'/Common.php';

/**
* Hash and other types of database connection, all except the Table type
*
* @package Tyrant
* @author Bertrand Mansion <bmansion@mamasam.com>
*/
class Tyrant_RDB extends Tyrant_Common
{
/**
* Unconditionally set key to value
* If a record with the same key exists in the database,
* it is overwritten.
*
* @param string|int Specifies the key.
* @param mixed A scalar value (or an object with __toString)
* @return bool True if successful, false otherwise
* @throws Tyrant_Exception
*/
public function put($key, $value)
{
$cmd = pack('CCNN', 0xC8, 0x10, strlen($key), strlen($value)) .
$key . $value;
$code = $this->_send($cmd);
if ($code !== 0) {
throw new Tyrant_Exception("Put error");
}
return true;
}

/**
* Store a new record
* If a record with the same key exists in the database,
* this method has no effect.
*
* @param string|int Specifies the key.
* @param mixed A scalar value (or an object with __toString)
* @return bool True if successful, false otherwise
* @throws Tyrant_Exception
*/
public function putkeep($key, $value)
{
$cmd = pack('CCNN', 0xC8, 0x11, strlen($key), strlen($value)) .
$key . $value;
$code = $this->_send($cmd);
if ($code !== 0) {
throw new Tyrant_Exception("Put error");
}
return true;
}

/**
* Append value to the existing value for key, or set key to
* value if it does not already exist.
*
* @param string|int Specifies the key.
* @param mixed A scalar value (or an object with __toString)
* @return bool True if successful, false otherwise
* @throws Tyrant_Exception
*/
public function putcat($key, $value)
{
$cmd = pack('CCNN', 0xC8, 0x12, strlen($key), strlen($value)) .
$key . $value;
$code = $this->_send($cmd);
if ($code !== 0) {
throw new Tyrant_Exception("Put error");
}
return true;
}

/**
* Concatenate a value at the end of the existing record and
* shift it to the left
*
* @param string|int Specifies the key.
* @param mixed A scalar value (or an object with __toString)
* @return bool True if successful, false otherwise
* @throws Tyrant_Exception
*/
public function putshl($key, $value, $width)
{
$width = $width < 0 ? 0 : (int)$width;
$cmd = pack('CCNNN', 0xC8, 0x13, strlen($key), strlen($value), $width) .
$key . $value;
$code = $this->_send($cmd);
if ($code !== 0) {
throw new Tyrant_Exception("Put error");
}
return true;
}

/**
* Set key to value without waiting for a server response
*
* @param string|int Specifies the key.
* @param mixed A scalar value (or an object with __toString)
* @return bool True if successful, false otherwise
* @throws Tyrant_Exception
*/
public function putnr($key, $value)
{
$cmd = pack('CCNN', 0xC8, 0x18, strlen($key), strlen($value)) .
$key . $value;
$status = $this->_socketWrite($cmd);
if ($status === false) {
throw new Tyrant_Exception("Put error");
}
return true;
}

/**
* Get the value of a key from the server
*
* @param string|int Specifies the key.
* @return string|null The value
*/
public function get($key)
{
$cmd = pack('CCN', 0xC8, 0x30, strlen($key)) . $key;
$code = $this->_send($cmd);
if ($code !== 0) {
return null;
}
$value = $this->_recv();
return $value;
}

/**
* Retrieve records
* As a result of this method, keys existing in the database have
* the corresponding values and keys not existing in the database
* are removed.
*
* @param array Associative array containing the retrieval keys
* The array is given by reference so it will be
* filled with the values found.
* @return int|false Number of retrieved records or false on failure.
*/
public function mget(&$recs)
{
$rnum = 0;
$cmd = "";
foreach ($recs as $key => $value) {
$cmd .= pack("N", strlen($key)) . $key;
$rnum++;
}
$cmd = pack("CCN", 0xC8, 0x31, $rnum) . $cmd;
$code = $this->_send($cmd);
if ($code !== 0) {
return false;
}
$rnum = $this->_recvInt32();
if ($rnum === false) {
return false;
}
$recs = array();
for ($i = 0; $i < $rnum; $i++) {
$ksiz = $this->_recvInt32();
$vsiz = $this->_recvInt32();
if ($ksiz === false || $vsiz === false) {
return false;
}
$kref = $this->_recv($ksiz);
$vref = $this->_recv($vsiz);
$recs[$kref] = $vref;
}
return $rnum;
}

/**
* Add an integer to a record
* If the corresponding record exists, the value is treated as
* an integer and is added to the existing value. If no record exists,
* a new record is created with the value.
*
* @param string The key
* @param int The additional value
* @return int|false The summation value or false
* @throws Tyrant_Exception
*/
public function addInt($key, $num = 0)
{
$cmd = pack("CCNN", 0xC8, 0x60, strlen($key), (int)$num) . $key;
$code = $this->_send($cmd);
if ($code !== 0) {
throw new Tyrant_Exception("Could not addInt to ".$key);
}
return $this->_recvInt32();
}

/**
* Add a real number to a record
* If the corresponding record exists, the value is treated as
* a real number and is added to the existing value. If no record exists,
* a new record is created with the value.
*
* @param string The key
* @param int The additional value
* @return int|false The summation value or false
* @throws Tyrant_Exception
*/
public function addDouble($key, $num = 0)
{
$integ = substr($num, 0, strpos($num, '.'));
$fract = (abs($num) - floor(abs($num)))*1000000000000;
$cmd = pack('CCN', 0xC8, 0x61, strlen($key)) .
$this->_pack64($integ) . $this->_pack64($fract) . $key;
$code = $this->_send($cmd);
if ($code !== 0) {
throw new Tyrant_Exception("AddDouble error");
}
$integ = $this->_recvint64();
$fract = $this->_recvint64();
return $integ + ($fract / 1000000000000);
}
}

RDBTable.php

<?php
/**
* Tokyo Tyrant network API for PHP
*
* Copyright (c) 2009 Bertrand Mansion <bmansion@mamasam.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package Tyrant
* @author Bertrand Mansion <bmansion@mamasam.com>
* @license http://www.opensource.org/licenses/mit-license.php MIT License
* @link http://mamasam.indefero.net/p/tyrant/
*/

require_once dirname(__FILE__).'/Common.php';
require_once dirname(__FILE__).'/Query.php';

/**
* Table type database connection
*
* @package Tyrant
* @author Bertrand Mansion <bmansion@mamasam.com>
*/
class Tyrant_RDBTable extends Tyrant_Common
{
/**
* index type: lexical string
*/
const ITLEXICAL = 0;

/**
* index type: decimal string
*/
const ITDECIMAL = 1;

/**
* index type: token inverted index
*/
const ITTOKEN = 2;

/**
* index type: q-gram inverted index
*/
const ITQGRAM = 3;

/**
* index type: optimize
*/
const ITOPT = 9998;

/**
* index type: void
*/
const ITVOID = 9999;

/**
* index type: keep existing index
*/
const ITKEEP = 16777216; // 1 << 24

/**
* Store a record
* If a record with the same key exists in the database,
* it is overwritten.
*
* @param string|int Specifies the primary key.
* @param array Associative array containing key/values.
* @return bool True if successful, false otherwise
* @throws Tyrant_Exception
*/
public function put($key, $value)
{
$args = array($key);
foreach ($value as $ckey => $cvalue) {
$args[] = $ckey;
$args[] = $cvalue;
}
$rv = $this->misc('put', $args, 0);
if ($rv === false) {
throw new Tyrant_Exception("Put error");
}
return true;
}

/**
* Store a new record
* If a record with the same key exists in the database,
* this method has no effect.
*
* @param string|int Specifies the primary key.
* @param array Associative array containing key/values.
* @return bool True if successful, false otherwise
* @throws Tyrant_Exception
*/
public function putkeep($key, Array $values)
{
$args = array($key);
foreach ($values as $ckey => $cvalue) {
$args[] = $ckey;
$args[] = $cvalue;
}
$rv = $this->misc('putkeep', $args, 0);
if ($rv === false) {
throw new Tyrant_Exception("Put error");
}
return true;
}

/**
* Concatenate columns of the existing record
* If there is no corresponding record, a new record is created.
*
* @param string|int Specifies the primary key.
* @param array Associative array containing key/values.
* @return bool True if successful, false otherwise
* @throws Tyrant_Exception
*/
public function putcat($key, Array $values)
{
$args = array($key);
foreach ($values as $ckey => $cvalue) {
$args[] = $ckey;
$args[] = $cvalue;
}
$rv = $this->misc('putcat', $args, 0);
if ($rv === false) {
throw new Tyrant_Exception("Put error");
}
return true;
}

/**
* Retrieve a record
* @param int|string Specifies the primary key.
* @return array|false If successful, the return value is an
* associative array, false if no record were found.
*/
public function get($key)
{
$args = array($key);
$rv = $this->misc('get', $args, Tyrant::MONOULOG);
if ($rv === false) {
$rnum = $this->_recvInt32();
return null;
}
$cols = array();
$cnum = count($rv) - 1;
$i = 0;
while ($i < $cnum) {
$cols[$rv[$i]] = $rv[$i+1];
$i += 2;
}
return $cols;
}

/**
* Retrieve records
* Due to the protocol restriction, this method can not handle records
* with binary columns including the "\0" chracter.
*
* @param array Associative array containing the primary keys.
* As a result of this method, keys existing in the
* database have the corresponding columns and keys
* not existing in the database are removed.
* @return int|false If successful, the return value is the number of
* records found. False if none found.
*/
public function mget(Array &$recs)
{
$rnum = 0;
$cmd = "";
foreach ($recs as $key => $value) {
$cmd .= pack("N", strlen($key)) . $key;
$rnum++;
}
$cmd = pack("CCN", 0xC8, 0x31, $rnum) . $cmd;
$code = $this->_send($cmd);
if ($code !== 0) {
return false;
}
$rnum = $this->_recvInt32();
if ($rnum === false) {
return false;
}
$recs = array();
for ($i = 0; $i < $rnum; $i++) {
$ksiz = $this->_recvInt32();
$vsiz = $this->_recvInt32();
if ($ksiz === false || $vsiz === false) {
return false;
}
$cols = array();
$kref = $this->_recv($ksiz);
$vref = $this->_recv($vsiz);
$cary = explode("\0", $vref);
$cnum = count($cary) - 1;
$j = 0;
while ($j < $cnum) {
$cols[$cary[$j]] = $cary[$j+1];
$j += 2;
}
$recs[$kref] = $cols;
}
return $rnum;
}

/**
* Set a column index
* @param string Name of a column.
* If the name of an existing index is specified,
* the index is rebuilt. An empty string means the
* primary key.
* @param int Specifies the index type:
* - Tyrant_RDBTable::ITLEXICAL for lexical string
* - Tyrant_RDBTable::ITDECIMAL for decimal string
* - Tyrant::ITOPT for optimizing the index
* - tyrant_RDBTable::ITVOID for removing the index
* If Tyrant_RDBTable::ITKEEP is added by bitwise-or and
* the index exists, this method merely returns failure.
*
* @return bool True if successful
* @throws Tyrant_Exception
*/
public function setindex($name, $type)
{
$args = array($name, $type);
$rv = $this->misc('setindex', $args, 0);
if ($rv === false) {
throw new Tyrant_Exception("Could not set index on ".$name);
}
return true;
}

/**
* Generate a unique ID number
* @return int The new unique ID number
* @throws Tyrant_Exception
*/
public function genuid()
{
$rv = $this->misc('genuid', array());
if ($rv === false) {
throw new Tyrant_Exception("Could not generate a new unique ID");
}
return $rv[0];
}

/**
* Execute a search
* This method does never fail and return an empty array even
* if no record corresponds.
*
* @param object A Tyrant_Query object
* @return array Array of the primary keys of records found.
*/
public function search(Tyrant_Query $query)
{
$rv = $this->misc("search", $query->args(), Tyrant::MONOULOG);
return empty($rv) ? array() : $rv;
}

/**
* Remove each corresponding records
*
* @param object A Tyrant_Query object
* @return bool True if successful, false otherwise
*/
public function searchOut(Tyrant_Query $query)
{
$args = $query->args();
$args[] = "out";
$rv = $this->misc("search", $args, 0);
return empty($rv) ? array() : $rv;
}

/**
* Get records corresponding to the search of a query object
* The return value is an array of associative arrays with column of
* the corresponding records. This method does never fail and return
* an empty array even if no record corresponds.
* Due to the protocol restriction, this method can not handle records
* with binary columns including the "\0" chracter.
*
* @param object A Tyrant_Query object
* @param string|array Array of column names to be fetched.
* An empty string returns the primary key.
* If it is left null, every column is fetched.
* @return array Array of records found
*/
public function searchGet(Tyrant_Query $query, $names = null)
{
$args = $query->args();
if (is_array($names)) {
$args[] = "get\0" . implode("\0", $names);
} else {
$args[] = "get";
}
$rv = $this->misc("search", $args, Tyrant::MONOULOG);
if (empty($rv)) {
return array();
}
foreach ($rv as $i => $v) {
$cols = array();
$cary = explode("\0", $v);
$cnum = count($cary) - 1;
$j = 0;
while ($j < $cnum) {
$cols[$cary[$j]] = $cary[$j+1];
$j += 2;
}
$rv[$i] = $cols;
}
return $rv;
}

/**
* Get the count of corresponding records
*
* @param object A Tyrant_Query object
* @return int Count of corresponding records or 0 on failure
*/
public function searchCount(Tyrant_Query $query)
{
$args = $query->args();
$args[] = "count";
$rv = $this->misc("search", $args, Tyrant::MONOULOG);
return empty($rv) ? 0 : $rv[0];
}
}

与Tyrant同级目录的文件

Tyrant.php

<?php
/**
* Tokyo Tyrant network API for PHP
*
* Copyright (c) 2009 Bertrand Mansion <bmansion@mamasam.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package Tyrant
* @author Bertrand Mansion <bmansion@mamasam.com>
* @license http://www.opensource.org/licenses/mit-license.php MIT License
* @link http://mamasam.indefero.net/p/tyrant/
*/

require_once dirname(__FILE__).'/Tyrant/Exception.php';

/**
* Factory for Tokyo Tyrant connections
*
* @package Tyrant
* @author Bertrand Mansion <bmansion@mamasam.com>
*/
class Tyrant
{
/**
* Scripting extension option for record locking
*/
const XOLCKREC = 1;

/**
* scripting extension option for global locking
*/
const XOLCKGLB = 2;

/**
* Misc function option for omission of the update log
*/
const MONOULOG = 1;

/**
* Restore function option for consistency checking
*/
const ROCHKCON = 1;

/**
* Keeps track of the connection objects
* Makes it possible to easily reuse a connection.
* @var array
*/
protected static $connections = array();

/**
* Current connection object
* @var object
*/
protected static $connection;

/**
* Opens a connection to a Tokyo Tyrant server
* <code>
* try {
* $tt = Tyrant::connect('localhost', 1978);
* } catch (Tyrant_Exception $e) {
* echo $e->getMessage();
* }
* </code>
*
* @param string Server hostname or IP address
* @param string Server port
* @param string Optional existing connection id
* @return object Database connection
*/
public static function connect($host = 'localhost', $port = '1978', $id = 0)
{
$id = implode(':', array($host, $port, $id));

// Check if connection already exists

if (isset(self::$connections[$id])) {
$connection =& self::$connections[$id];
return $connection;
}

// Start a new connection

$ip = gethostbyname($host);
$addr = ip2long($ip);
if (empty($addr)) {
throw new Tyrant_Exception("Host not found");
}
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if (!is_resource($socket)){
throw new Tyrant_Exception("Connection refused");
}
if (!socket_connect($socket, $addr, $port)) {
throw new Tyrant_Exception("Connection refused");
}
if (defined('TCP_NODELAY')) {
socket_set_option($socket, SOL_TCP, TCP_NODELAY, 1);
} else {
// See http://bugs.php.net/bug.php?id=46360
socket_set_option($socket, SOL_TCP, 1, 1);
}

// Determine the database type

if (socket_write($socket, pack('CC', 0xC8, 0x88)) === false) {
throw new Tyrant_Exception("Unable to get database type");
}
$str = '';
if (socket_recv($socket, $str, 1, 0) === false) {
throw new Tyrant_Exception("Unable to get database type");
}
$c = unpack("C", $str);
if (!isset($c[1]) || $c[1] !== 0) {
throw new Tyrant_Exception("Unable to get database type");
}
$str = '';
if (socket_recv($socket, $str, 4, 0) === false) {
throw new Tyrant_Exception("Unable to get database type");
}
$num = unpack("N", $str);
if (!isset($num[1])) {
throw new Tyrant_Exception("Unable to get database type");
}
$size = unpack("l", pack("l", $num[1]));
$len = $size[1];
$str = '';
if (socket_recv($socket, $str, $len, 0) === false) {
throw new Tyrant_Exception("Unable to get database type");
}
$value = explode("\n", trim($str));
$stats = array();
foreach ($value as $v) {
$v = explode("\t", $v);
$stats[$v[0]] = $v[1];
}
if (!isset($stats['type'])) {
throw new Tyrant_Exception("Unable to get database type");
}

// Get the right interface for the database type

if ($stats['type'] == 'table') {
include_once dirname(__FILE__).'/Tyrant/RDBTable.php';
$conn = new Tyrant_RDBTable($socket);
} else {
include_once dirname(__FILE__).'/Tyrant/RDB.php';
$conn = new Tyrant_RDB($socket);
}
self::$connections[$id] =& $conn;
self::$connection = $conn;
return $conn;
}

/**
* Return the current connection
* The current connection is set using Tyrant::setConnection() and
* defaults to the last connection made
*
* @return object|null First connection in the stack
*/
public function getConnection()
{
return self::$connection;
}

/**
* Changes the current connection
* @param string Server hostname or IP address
* @param string Server port
* @param string Optional existing connection id
* @return object|null First connection in the stack
*/
public function setConnection($host = 'localhost', $port = '1978', $id = 0)
{
$id = implode(':', array($host, $port, $id));
self::$connection =& self::$connections[$id];
}

/**
* Disconnects and removes a connection
* @param string Server hostname or IP address
* @param string Server port
* @param string Optional existing connection id
*/
public function disconnect($host = 'localhost', $port = '1978', $id = 0)
{
$id = implode(':', array($host, $port, $id));
if (isset(self::$connections[$id])) {
$connection =& self::$connections[$id];
$connection->disconnect();
unset(self::$connections[$id]);
return true;
}
return false;
}
}

cache的使用类

cache_ttserver.php

<?php
/**
* TokyoCabinet数据库操作类
*/
require_once EXTENTION_PATH.'ttserver/Tyrant.php';
require_once EXTENTION_PATH.'ttserver/Tyrant/Query.php';

class cache_ttserver {
private $_conn = null;
public $_query = object;

/**
* 构造函数-创建TTSERVER连接对象
*/
public function __construct($host , $port) {
$this->_conn = Tyrant::connect($host , $port);
$this->_query = new Tyrant_Query;
}

/**
* 写入一行记录
*/
public function set($key , $value = null) {
$args_num = func_num_args();
if(is_array($key) && $args_num == 1) {
$values = $key;
foreach($values AS $_key => $_val) {
$this->_conn->put($_key , $_val);
}
} else {
return $this->_conn->put($key , $value);
}
return $this;
}

/**
* 读取一行记录
*/
public function get($key) {
if(is_array($key)) {
$keys = $key;
$value = array();
foreach($keys AS $_key) {
$serialized_value = $this->_conn->get($_key);
$value[$_key] = $serialized_value;
}
} else {
$value = $this->_conn->get($key);
}
return $value;
}

/**
* 删除一行记录
*/
public function remove($key) {
return $this->_conn->out($key);
}

/**
* 删除所有记录
*/
public function removeAll() {
return $this->_conn->vanish();
}

/**
* 使用条件:TC HASH数据库
* 写入整形记录。若key存在,则更新记录,否则插入一条记录。
*/
public function add($key , $increment) {
return $this->_conn->addInt($key , $increment);
}

/**
* 使用条件:TC TABLE数据库
* 获取一个连接对象遍历数据库中的所有键/值。
*/
public function getIterator() {
return $this->_conn;
}

/**
* 获取记录数
*/
public function rnum() {
return $this->_conn->rnum();
}

/**
* 使用条件:TC TABLE数据库
* 检索记录集,返回key
*/
public function search() {
return $this->_conn->search($this->_query);
}

/**
* 使用条件:TC TABLE数据库
* 删除检索匹配的记录集
*/
public function searchOut() {
return $this->_conn->searchOut($this->_query);
}

/**
* 使用条件:TC TABLE数据库
* 检索匹配的记录集,返回记录数组
*/
public function searchGet($names = null) {
return $this->_conn->searchGet($this->_query, $names);
}

/**
* 使用条件:TC TABLE数据库
* 统计检索匹配的记录集个数
*/
public function searchCount() {
return $this->_conn->searchCount($this->_query);
}
}









posted on 2011-11-24 20:34 kudosharry 阅读(...) 评论(...)  编辑 收藏

公告

导航

统计

  • 随笔 - 68
  • 文章 - 234
  • 评论 - 7
  • 引用 - 0