DataMapper implements IDataList, IDataSave, IDataSort, IDataDelete ... * * @package core */ class DataMapper implements IDataList { /* Хранить метаданные в статическом свойстве класса для ототбражения ?!, + Скрипт для генерации метаданных!! */ public $factory; public $className; /* Класс на который будет отображаться строчка таблицы */ public $filter = ""; /* */ public $schema = array (); /* Соответствие между свойством обьекта и столбцом, добавить тип для записей !! */ public $database; /* Таблица */ public $index; /* Индексный столбец */ public $db; /* Соединение с базой данных */ public $reference = array (null, null); public function __construct () { } public function setRange ($stmt, $page, $size) { $stmt->setLimit ($size); $stmt->setOffset (($page-1) * $size); } public function listSQL (array $list) { return implode ($list, ","); } /** * Поиск строки в таблице по идентификатору * @param $id Значение идентификатора * @return Обьект класса $className */ public function findById ($id) { // Строки запроса преобразовать в методы (getSQLSelect ...) // Query::from($this->database)->where ($this->index, "=", $id)->select(); $stmt = $this->db->prepareStatement ("SELECT * FROM ".$this->database." WHERE ".$this->index." = ?"); $stmt->setInt (1, $id); $rs = $stmt->executeQuery (); $rs->next (); return $this->mapOne ($rs); } /** * Преобразует parseResult в обьект */ public /* private */ function mapOne ($rs) { $result = new $this->className (); foreach ($this->schema as $key => $value) { list($value) = $value; $result->$value->setRes($rs, $key); } return $result; } public /* private */ function mapAll ($rs) { $result = array (); // Преобразование SQL в обьект while ($rs->next ()) { $result[] = $this->mapOne ($rs); } return $result; } private function clean ($value) { return strtolower(trim(iconv('utf-8', 'cp1251', $value))); } /** * Преобразует параметры формы в SQL запрос WHERE * @param array $params * @param array $schema * @return string */ public function requestToSQL (Collection $request, array $schema) { $result = array (); foreach ($schema as $key => $value) { $param = $request->get ($key); if ($param) { array_push ($result, "lower (".$value.") LIKE '".$this->clean ($param)."%'"); } } if (empty ($result)) return null; return implode ($result, " AND "); } /** * Удаление строк из таблицы с заданными индексами * @param $list array Массив идентефикаторов */ public function deleteList (array $list) { // Query::from($this->database)->where($this->index, "in", $list)->delete(); $sql = "DELETE FROM " . $this->database . " WHERE " . $this->index . " IN (" . $this->listSQL ($list) . ")"; return $this->db->executeQuery ($sql); } public static function findKey (array $schema, $sort) { foreach ($schema as $key => $item) { list($item) = $item; if ($item == $sort) { return $key; } } return $sort; } public function getOrder (Collection $request) { $order = ""; $sort = $request->get('key'); $desc = ($request->get('desc') == 0)? 'DESC' : 'ASC'; if ($sort) { $sort = self::findKey ($this->schema, $sort); $order = " ORDER BY $sort $desc"; } return $order; } /** * Извлекает список записей из базы данных */ public function findAll (Collection $request, $id = null) { $name0 = $this->database; $foreign = $this->reference[1]; // Переписать используя Query !!! if ($foreign && $id) { $filter = ($this->filter)?$filter = " AND ".$this->filter: ""; $sql = "SELECT t1.* FROM $name0 as t1 WHERE t1.$foreign = $id " . $filter.self::getOrder($request); } else { $filter = ($this->filter)?$filter = " WHERE " . $this->filter: ""; $sql = "SELECT * FROM $name0 " . $filter . self::getOrder($request); } $stmt = $this->db->prepareStatement ($sql); $page = $request->get('page'); $limit = $request->get('size'); if ($page && $limit) { $this->setRange($stmt, $page, $limit); } return $this->mapAll($stmt->executeQuery()); } public function getCount (Collection $request, $id) { $name0 = $this->database; $foreign = $this->reference[1]; // Переписать используя Query !!! if ($foreign && $id) { $filter = ($this->filter)?$filter = " AND " . $this->filter: ""; $sql = "SELECT count(t1.*) as length FROM $name0 as t1 WHERE t1.$foreign = $id " . $filter; } else { $filter = ($this->filter)?$filter = " WHERE " . $this->filter: ""; $sql = "SELECT count(*) as length FROM $name0 " . $filter; } $rs = $this->db->executeQuery($sql); $rs->next(); return $rs->getInt('length'); } /** * Добавление записи в базу данных * @param $o Обьект для записи в базу данных */ public function saveTo (Model $o) { $keys = array (); $values = array (); foreach ($this->schema as $key => $value) { list($value) = $value; if ($key != $this->index) { $keys[] = $key; $values[] = "'".$o->$value."'"; } } $stmt = $this->db->prepareStatement ("INSERT INTO ".$this->database." (".implode ($keys, ",").") VALUES (".implode ($values, ",").")"); $stmt->executeQuery (); } /** * Обновляет запись в базе данных * @param $o Обьект для обновления */ public function updateTo (Model $o) { $keys_values = array (); foreach ($this->schema as $key => $value) { list($value) = $value; if ($key != $this->index && !($o->$value instanceof FKey)) { $keys_values[] = $key." = '".$o->$value."'"; } } // Для всех должен быть идентефикатор id $stmt = $this->db->prepareStatement ("UPDATE ".$this->database." SET ".implode($keys_values, ",")." WHERE ".$this->index." = ".$o->id); $stmt->executeQuery (); } function saveDB (Model $o) { if ($o->id) { $this->updateTo($o); } else { $this->saveTo($o); } } function getModel($name) { require_once 'core/Mapper/Factory.php'; if (!$this->factory) { $this->factory = new ModelFactory($this->db); } return $this->factory->getModel($name); } } /** * */ class Model { public function __construct () { foreach (get_class_vars (get_class ($this)) as $key => $value) { $this->$key = new Primitive (); } } // __get, __set методы. В метаданных хранится тип свойств, проверять при присваивании!! } ?>