public function updateAttributes($index, array $attrs, array $values, $mva = false)
{
// verify everything
$index = strval($index);
$mva = (bool) $mva;
foreach ($attrs as $attr) {
if (!is_string($attr)) {
throw new \InvalidArgumentException('Attribute name must be a string.');
}
}
foreach ($values as $id => $entry) {
if (!is_numeric($id)) {
throw new \InvalidArgumentException('Document ID must be numeric.');
}
if (!is_array($entry)) {
throw new \InvalidArgumentException('Document must be an array of attribute values.');
}
if (count($entry) !== count($attrs)) {
throw new \InvalidArgumentException('Number of attributes do not match.');
}
foreach ($entry as $v) {
if ($mva) {
if (!is_array($v)) {
throw new \InvalidArgumentException('MVA must be an array.');
}
foreach ($v as $vv) {
if (!is_int($vv)) {
throw new \InvalidArgumentException('Attribute value must be an integer.');
}
}
} else {
if (!is_int($v)) {
throw new \InvalidArgumentException('Attribute value must be an integer.');
}
}
}
}
// build request
$this->mbPush();
$req = pack('N', strlen($index)) . $index;
$req .= pack('N', count($attrs));
foreach ($attrs as $attr) {
$req .= pack('N', strlen($attr)) . $attr;
$req .= pack('N', $mva ? 1 : 0);
}
$req .= pack('N', count($values));
foreach ($values as $id => $entry) {
$req .= $this->packU64($id);
foreach ($entry as $v) {
$req .= pack('N', $mva ? count($v) : $v);
if ($mva) {
foreach ($v as $vv) {
$req .= pack('N', $vv);
}
}
}
}
// connect, send query, get response
if (!($fp = $this->connect())) {
$this->mbPop();
return -1;
}
$len = strlen($req);
$req = pack('nnN', self::SEARCHD_COMMAND_UPDATE, self::VER_COMMAND_UPDATE, $len) . $req;
// add header
if (!$this->send($fp, $req, $len + 8)) {
$this->mbPop();
return -1;
}
if (!($response = $this->getResponse($fp, self::VER_COMMAND_UPDATE))) {
$this->mbPop();
return -1;
}
// parse response
list(, $updated) = unpack('N*', substr($response, 0, 4));
$this->mbPop();
return $updated;
}