phplibrary/core/mapper/mapper.php
2016-07-14 16:29:26 +03:00

267 lines
No EOL
8.9 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
require_once 'core/primitive.php';
/**
* Использовать интерфейсы чтобы определить какие действия можно совершать с обьектом и таким образом
* Строить набор действий Action и отображений View для обьекта
* Т.к отображение данных может быть не только на таблицу баз данных
* И возможно реализованны все интерфейсы
*/
interface IDataList
{
function findAll (Collection $request, $id = null);
function findById ($id);
function getCount (Collection $request, $id);
}
interface IDataSave
{
function saveTo ($o);
function updateTo ($o);
}
/**
* Отображение таблицы базы данных в обьекты
* Mapper -> 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 методы. В метаданных хранится тип свойств, проверять при присваивании!!
}
?>