|
|
<?php /** * @copyright NetMonsters <team@netmonsters.ru> * @link http://netmonsters.ru * @package Majestic * @subpackage db * @since 2010-02-19 * @version SVN: $Id$ * @filesource $URL$ */
/** * @property MySQLiDriver $driver * @property MySQLi_Result $result */ class MySQLiStatement extends DbStatement {
protected $map = null;
public function bindParam($param, &$value) { if ($this->map === null) { $this->mapPlaceholders(); } if (count($this->map) > 0) { if (!is_string($param) && !is_int($param)) { throw new Exception('Placeholder must be an array or string'); } if (is_object($value) && ! ($value instanceof DbExpr)) { throw new Exception('Objects excepts DbExpr not allowed.'); } if (isset($this->map[$param])) { $this->params[$param] = &$value; return true; } } return false; } protected function mapPlaceholders() { $matches = array(); if(preg_match_all('/(\?|:[A-z0-9_]+)/u', $this->request, $matches, PREG_OFFSET_CAPTURE)) { $noname = 0; foreach ($matches[0] as $id=>$match) { $match[2] = $matches[1][$id][0]; $name = ($match[2][0] === ':') ? ltrim($match[2], ':') : $noname++; $this->map[$name]['placeholder'] = $match[0]; $this->map[$name]['offset'][] = $match[1]; } } }
protected function assemble() { if (empty($this->map)) { return $this->request; }
$query = $this->request; $placeholders = array(); foreach($this->map as $name => $place) { $value = $this->driver->quote($this->params[$name]); foreach ($place['offset'] as $offset) { $placeholders[$offset] = array('placeholder' => $place['placeholder'], 'value' => $value); } }
ksort($placeholders);
$increment = 0; foreach($placeholders as $current_offset => $placeholder) { $offset = $current_offset + $increment; $length = mb_strlen($placeholder['placeholder']); $query = mb_substr($query, 0, $offset) . $placeholder['value'] . mb_substr($query, $offset + $length); $increment = (($increment - $length) + mb_strlen($placeholder['value'])); } return $query; }
/** * Fetches single row * * @param mixed $style * @return mixed */ public function fetch($style = Db::FETCH_OBJ) { if (!$this->result) { return false; } $row = false; switch ($style) { case Db::FETCH_OBJ: $row = $this->result->fetch_object(); break; case Db::FETCH_NUM: $row = $this->result->fetch_array(MYSQLI_NUM); break; case Db::FETCH_ASSOC: $row = $this->result->fetch_assoc(); break; case Db::FETCH_BOTH: $row = $this->result->fetch_array(MYSQLI_BOTH); break; default: throw new Exception('Invalid fetch mode "' . $style . '" specified'); } return $row; } /** * @param string $class */ public function fetchObject($class = 'stdClass') { return $this->result->fetch_object($class); }
/** * @return array */ public function fetchPairs() { $data = array(); while ($row = $this->fetch(Db::FETCH_NUM)) { $data[$row[0]] = $row[1]; } return $data; } public function close() { if ($this->result !== null) { $this->result->close(); $this->result = null; } } public function affectedRows() { return $this->driver->getConnection()->affected_rows; } public function numRows() { if ($this->result) { return $this->result->num_rows; } return false; } protected function driverExecute($request) { /** * @var MySQLi */ $mysqli = $this->driver->getConnection(); if (DEBUG) { $profiler = Profiler::getInstance()->profilerCommand('MySQL', $request); $result = $mysqli->query($request); $profiler->end(); } else { $result = $mysqli->query($request); } if ($result === false) { $message = $mysqli->error . "\nQuery: \"" . $request . '"'; throw new Exception($message, $mysqli->errno); } if ($result instanceof MySQLi_Result) { $this->result = $result; } return true; } }
|