Multi databases support, #12
git-svn-id: svn+ssh://code.netmonsters.ru/svn/majestic/branches/evo@113 4cb57b5f-5bbd-dd11-951b-001d605cbbc5
This commit is contained in:
161
model/DbStatement.php
Normal file
161
model/DbStatement.php
Normal file
@ -0,0 +1,161 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright NetMonsters <team@netmonsters.ru>
|
||||
* @link http://netmonsters.ru
|
||||
* @package Majestic
|
||||
* @subpackage db
|
||||
* @since 2010-02-19
|
||||
* @version SVN: $Id$
|
||||
* @filesource $URL$
|
||||
*/
|
||||
|
||||
abstract class DbStatement
|
||||
{
|
||||
|
||||
/**
|
||||
* @var DbDriver
|
||||
*/
|
||||
protected $driver;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $sql;
|
||||
|
||||
protected $map = null;
|
||||
|
||||
protected $params = array();
|
||||
|
||||
protected $result;
|
||||
|
||||
public function __construct($driver, $sql)
|
||||
{
|
||||
$this->driver = $driver;
|
||||
$this->sql = $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $style
|
||||
* @return array
|
||||
*/
|
||||
public function fetchAll($style = Db::FETCH_OBJ)
|
||||
{
|
||||
$data = array();
|
||||
while ($row = $this->fetch($style)) {
|
||||
$data[] = $row;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $field
|
||||
*/
|
||||
public function fetchField($field)
|
||||
{
|
||||
$row = $this->fetch(Db::FETCH_ASSOC);
|
||||
if (isset($row[$field])) {
|
||||
return $row[$field];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $params
|
||||
* @return bool
|
||||
*/
|
||||
public function execute($params = null)
|
||||
{
|
||||
if (is_array($params)) {
|
||||
foreach ($params as $param => &$value) {
|
||||
$this->bindParam($param, $value);
|
||||
}
|
||||
}
|
||||
return $this->driverExecute($this->assemble());
|
||||
}
|
||||
|
||||
protected function mapPlaceholders()
|
||||
{
|
||||
$matches = array();
|
||||
if(preg_match_all('/(\?|:[A-z0-9_]+)/u', $this->sql, $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->sql;
|
||||
}
|
||||
|
||||
$query = $this->sql;
|
||||
$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;
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$this->close();
|
||||
}
|
||||
|
||||
/* Abstract methods */
|
||||
|
||||
abstract public function fetch($style = Db::FETCH_OBJ);
|
||||
|
||||
abstract public function fetchObject($class = 'stdClass');
|
||||
|
||||
abstract public function close();
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
abstract public function affectedRows();
|
||||
|
||||
abstract public function numRows();
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
abstract protected function driverExecute($sql);
|
||||
}
|
Reference in New Issue
Block a user