2011年6月2日星期四

PHP extension for interfacing with MySQL Handler Socket

有关于 HandlerSocket 的介绍、性能及其安装,可参考Using SQL as NoSQL。而 PHP extension for interfacing with MySQL Handler Socket,实际上这里php-handlersocket有整体的介绍,包括其安装、使用方法。现在纯粹是因为自己测试时犯了一很基础的错误,所以,罚自己多敲点字。

安装


[bash]
[root@localhost php-handlersocket]# /usr/local/php/bin/phpize
[root@localhost php-handlersocket]# ./configure --with-php-config=/usr/local/php/bin/php-config
[root@localhost php-handlersocket]# make
[root@localhost php-handlersocket]# make install
[/bash]
说明:
1 编译时需要 libhsclient 库(libhsclient - HandlerSocket client library)。
2 安装成功时,在 PHP 的 extension dir 生成一名为 handlersocket.so,将extension=handlersocket.so加入 php.ini, 重启 PHP 服务。

HandlerSocket Class methods


HandlerSocket::construct

创建一 HandlerSocket Object。
[php]
HandlerSocket::__construct ( string $host, string $port [, array $options ] )
[/php]
参数:

  • $host MySQL 服务器 host name。

  • $port HandlerSocket 的端口地址。


返回值:
返回 HandlerSocket Object。

HandlerSocket::openIndex

在对数据库表做任何的增删改查操作前,必须先选择一索引。
[php]
public bool HandlerSocket::openIndex ( int $id, string $db, string $table, string $index, string $fields )
[/php]
参数:

  • $id HandlerSocket ID; 1 SELECT, 2 UPDATE, 3 INSERT, 4 DELETE。

  • $db 数据库名

  • $table 表名

  • $index 索引名, 可以是手动创建的索引名。这个参数可为空,一般指定时是用于 SELECT,eg: 指定为主键:HandlerSocket::PRIMARY

  • $fields 字段名(多个字段名,用逗号分隔),可为空。


返回值:
成功时返回 TRUE, 反之亦然。

HandlerSocket::executeSingle

在表上做增删改查操作。
[php]
public mixed HandlerSocket::executeSingle ( int $id, string $op, array $fields [, int $limit, int $skip, string $modop, array $values, array $filters, int $invalues_key, array $invalues ] )
[/php]
参数:

  • $id HandlerSocket ID; 1 SELECT, 2 UPDATE, 3 INSERT, 4 DELETE。

  • $op 操作符,有如下可选项, '=', '>=', '<=', '>', '<', '+'。

  • $fields 查询中所用到的字段,数组,其长度必须等于或小于指定的列数。

  • $limit 最多影响的行数(最开始根据这个函数名称有在怀疑这个参数,测试时发现,如果存在满足条件的多条记录时,会根据这个参数指定的值返回记录数)。

  • $skip 在检索记录前忽略掉的行数。

  • $modop 指定修改操作,可选值:'U', 'D'。

  • $values 数组,用于做 UPDATE 操作时指定修改的值。

  • $filters 过滤的选项。

  • $invalues_key ? (enabled : 0 / disabled : -1).

  • $invalues IN options


返回值:
返回做对应操作时的执行结果。

HandlerSocket::executeMulti

在一次调用中执行多个操作,即多个 HandlerSocket::executeSingle 的合并。
[php]
public mixed HandlerSocket::executeMulti ( array $requests )
[/php]
参数:

  • $requrest 多组 executeSingle 参数,用数组的形式体现。


注意:
等同于:HandlerSocket::executeSingle($requests00, $requests01, ...), HandlerSocket::executeSingle($requests10, ...) ...
返回结果:
返回做对应操作时的执行结果。

HandlerSocket::executeUpdate

To update a record from a table using an index.
[php]
public mixed HandlerSocket::executeUpdate ( int $id, string $op, array $fields, array $values [, int $limit, int $skip, array $filters, int $invalues_key, array $invalues ] )
[/php]
参数:

  • $id HandlerSocket ID; 2 UPDATE 。

  • $op 操作符,有如下可选项, '=', '>=', '<=', '>', '<', '+'。

  • $fields 查询中所用到的字段,数组,其长度必须等于或小于指定的列数。

  • $values UPDAET 时指定修改的值。

  • $limit 最多影响的行数。

  • $skip 在检索记录前忽略掉的行数。

  • $filters 过滤的选项。

  • $invalues_key ? (enabled : 0 / disabled : -1).

  • $invalues IN options


注意:
等同于:HandlerSocket::executeSingle($id, $op, $fields, $limit, $skip, 'U', $values, $filters, $invalues_key, $invalues)
返回值:
返回做对应操作时的执行结果。

HandlerSocket::executeDelete

To delete a record from a table using an index.
[php]
public mixed HandlerSocket::executeDelete ( int $id, string $op, array $fields [, int $limit, int $skip, array $filters, int $invalues_key, array $invalues ] )
[/php]
参数:

  • $id HandlerSocket ID; 4 DELETE 。

  • $op 操作符,有如下可选项, '=', '>=', '<=', '>', '<', '+'。

  • $fields 查询中所用到的字段,数组,其长度必须等于或小于指定的列数。

  • $limit 最多影响的行数。

  • $skip 在检索记录前忽略掉的行数。

  • $filters 过滤的选项。

  • $invalues_key ? (enabled : 0 / disabled : -1).

  • $invalues IN options


注意:
等同于:HandlerSocket::executeSingle($id, $op, $fields, $limit, $skip, 'D', NULL, $filters, $invalues_key, $invalues)
返回值:
返回做对应操作时的执行结果。

HandlerSocket::executeInsert

To insert a record from a table using an index.
[php]
public mixed HandlerSocket::executeInsert ( int $id, array $values )
[/php]
参数:

  • $id HandlerSocket ID; 3 INSERT 。

  • $values HandlerSocket::openIndex 指定的字段参数所对应的值,但是以数组的形式体现。


注意:
等同于:HandlerSocket::executeSingle($id, '+', $values, 0, 0, NULL, NULL, NULL) ,第三个参数中指定的值必须和在此之前调用 HandlerSocket::openIndex 时第五个参数指定的字段对应。
返回值:
返回做对应操作时的执行结果。

HandlerSocket::getError

取得最近一次的错误信息。
[php]
public string HandlerSocket::getError ( void )
[/php]
返回值:
返回最近的错误信息(时间上)。

Example


测试表 schema:
[sql]
CREATE TABLE `hstesttbl` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`k` char(6) DEFAULT NULL,
`v` char(6) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_hstesttbl_k` (`k`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
[/sql]

[php]
$host = 'localhost';
$port = 9998;
$port_wr = 9999;
$dbname = 'hstestdb';
$table = 'hstesttbl';

//GET
$hs = new HandlerSocket($host, $port);
if (!($hs->openIndex(1, $dbname, $table, HandlerSocket::PRIMARY, 'k,v'))) {
echo $hs->getError(), PHP_EOL;
die();
}

$retval = $hs->executeSingle(1, '=', array('k1'), 1, 0);
var_dump($retval);

$retval = $hs->executeMulti(
array(
array(1, '=', array('k1'), 1, 0),
array(1, '=', array('k2'), 1, 0)
)
);
var_dump($retval);
unset($hs);


//UPDATE
$hs = new HandlerSocket($host, $port_wr);
if (!($hs->openIndex(2, $dbname, $table, '', 'v'))) {
echo $hs->getError(), PHP_EOL;
die();
}

if ($hs->executeUpdate(2, '=', array('k1'), array('V1'), 1, 0) === false) {
echo $hs->getError(), PHP_EOL;
die();
}

unset($hs);


//INSERT
$hs = new HandlerSocket($host, $port_wr);
if (!($hs->openIndex(3, $dbname, $table, '', 'k,v'))) {
echo $hs->getError(), PHP_EOL;
die();
}

if ($hs->executeInsert(3, array('k2', 'v2')) === false) {
echo $hs->getError(), PHP_EOL;
}
if ($hs->executeInsert(3, array('k3', 'v3')) === false) {
echo 'A', $hs->getError(), PHP_EOL;
}
if ($hs->executeInsert(3, array('k4', 'v4')) === false) {
echo 'B', $hs->getError(), PHP_EOL;
}

unset($hs);


//DELETE
$hs = new HandlerSocket($host, $port_wr);
if (!($hs->openIndex(4, $dbname, $table, '', ''))) {
echo $hs->getError(), PHP_EOL;
die();
}

if ($hs->executeDelete(4, '=', array('k2')) === false) {
echo $hs->getError(), PHP_EOL;
die();
}
[/php]

PS: 因为建立测试表时忘记指定存储引擎为 InnoDB, 测试 INSERT 操作时,怎样都是失败。后面为了验证问题的出处,用 perl 的 API 做同样的测试操作,结果也是失败。查看表结构后,修改储存引擎为 InnoDB,才成功。只是这个问题的错误信息太难理解,就几个数字,在没找到答案之前,害我还去查看了下 HandlerSocket 的源代码,当然,没有从中得到任何的提示。

没有评论:

发表评论