You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

253 lines
6.0 KiB

<?php
/**
* Класс модели данных
*
* @copyright NetMonsters <team@netmonsters.ru>
* @link
* @package Majestic
* @subpackage DB
* @since
* @version SVN: $Id$
* @filesource $URL$
*/
abstract class Model
{
private $handler;
protected $table = false;
protected $primary_key = 'id';
function __construct()
{
$this->handler = DBConnector::getConnect(Env::getParam('db_settings'));
}
/**
* Выполняет запрос и возвращает сырой результат
*
* @param string $sql
* @return resource
*/
function exec($sql)
{
if (DEBUG_ENABLE) {
$time = microtime(true);
}
$res = DBConnector::query($this->handler, $sql);
if ($error = DBConnector::error($this->handler)) {
throw new MJException("<b>Query Error:</b>\n".$sql."\n<b>Error:</b>\n".$error, 1);
}
if (DEBUG_ENABLE) {
DBConnector::$queries[] = $sql.'; ('.round((microtime(true)-$time)*1000, 1).'ms)';
}
return $res;
}
/**
* Выполняет запрос и возвращает объект результата
*
* @param string $sql
* @return object
*/
function query($sql)
{
$res = $this->exec($sql);
switch (strtolower(substr($sql, 0, 6))) {
case 'select':
case '(selec':
return new ModelSelectResult($res);
case 'insert':
case 'replac':
return new ModelInsertResult($this->handler, $res); //$res for postgreSQL
default:
return new ModelChangeResult($this->handler, $res); //$res for postgreSQL
}
}
/**
* Экранирует строку
*
* @param mixed $data - строка для экранирования
* @return mixed
*/
function escape($data)
{
if(is_array($data)){
foreach($data as $id => $val){
$data[$id] = DBConnector::escape($this->handler, $val);
}
return $data;
}
return DBConnector::escape($this->handler, $data);
}
//////////////////////////
function update($id, $data)
{
$sql = '';
foreach ($data as $key => $val) {
$sql .= $key."='".$this->escape($val)."', ";
}
return $this->query('UPDATE '.$this->table.' SET '.rtrim($sql, ', ').' WHERE '.$this->primary_key.'='.(int) $id);
}
function insert($data, $postfix = '')
{
$keys = array();
$values = array();
foreach ($data as $key => $val) {
$keys[] = $key;
$values[] = $this->escape($val);
}
return $this->query('INSERT INTO '.$this->table.' ('.implode(',', $keys).") VALUES('".implode("','", $values)."') ".$postfix);
}
function delete($id)
{
return $this->query('DELETE FROM '.$this->table.' WHERE '.$this->primary_key.'='.(int) $id);
}
function get($id)
{
return $this->query('SELECT * FROM '.$this->table.' WHERE '.$this->primary_key.'='.(int) $id);
}
function getList($limit = false, $sort = 'ASC')
{
return $this->query('SELECT *
FROM '.$this->table.'
ORDER BY '.$this->primary_key.' '.($sort == 'ASC' ? 'ASC' : 'DESC')
.($limit !== false ? ' LIMIT '.(int) $limit : ''))->fetchAll();
}
function setAutocommit($set)
{
return DBConnector::autocommit($this->handler, (bool) $set);
}
function commit()
{
return DBConnector::commit($this->handler);
}
function rollback()
{
return DBConnector::rollback($this->handler);
}
}
class ModelResult
{
function __call($name, $args)
{
throw new MJException('Call undeclared method "'.$name.'" in "'.get_class($this).'" class', -1);
}
}
class ModelSelectResult extends ModelResult
{
public $result;
function __construct($res)
{
$this->result = $res;
}
function fetch($class_name = false)
{
return DBConnector::fetchObject($this->result, $class_name);
}
function fetchField($field, $default = false)
{
$row = $this->fetch();
return isset($row->$field) ? $row->$field : $default;
}
function fetchAll($key = false)
{
$array = array();
if ($key) {
while ($row = DBConnector::fetchObject($this->result)) {
$array[$row->$key] = $row;
}
} else {
while ($row = DBConnector::fetchObject($this->result)) {
$array[] = $row;
}
}
return $array;
}
/**
* Fetches all SQL result rows as an array of key-value pairs.
*
* The first column is the key, the second column is the
* value.
*
* @return array
*/
public function fetchPairs()
{
if (!method_exists('DBConnector', 'fetchArray')) {
throw new Exception('Method not implemented yet.');
}
$data = array();
while ($row = DBConnector::fetchArray($this->result, DBConnector::FETCH_NUM)) {
$data[$row[0]] = $row[1];
}
return $data;
}
function count()
{
return DBConnector::numRows($this->result);
}
function free()
{
DBConnector::free($this->result);
}
function __destruct() {
$this->free();
}
}
class ModelChangeResult extends ModelResult
{
public $affected;
function __construct($resource, $result)
{
$this->affected = DBConnector::affectedRows($resource, $result);
}
function count()
{
return $this->affected;
}
}
class ModelInsertResult extends ModelChangeResult
{
public $id;
function __construct($resource, $result)
{
parent::__construct($resource, $result);
$this->id = DBConnector::getId($resource);
}
function getId()
{
return $this->id;
}
}
?>