2010-08-13 19:26:19 +03:00
|
|
|
|
<?php
|
|
|
|
|
/*-------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* LiveStreet Engine Social Networking
|
|
|
|
|
* Copyright © 2008 Mzhelskiy Maxim
|
|
|
|
|
*
|
|
|
|
|
*--------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* Official site: www.livestreet.ru
|
|
|
|
|
* Contact e-mail: rus.engine@gmail.com
|
|
|
|
|
*
|
|
|
|
|
* GNU General Public License, version 2:
|
|
|
|
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|
|
|
|
*
|
|
|
|
|
---------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/**
|
2012-04-18 08:33:41 +03:00
|
|
|
|
* Системный класс мапера ORM для работы с БД
|
2010-08-13 19:26:19 +03:00
|
|
|
|
*
|
2012-04-18 08:33:41 +03:00
|
|
|
|
* @package engine.orm
|
|
|
|
|
* @since 1.0
|
2010-08-13 19:26:19 +03:00
|
|
|
|
*/
|
|
|
|
|
class MapperORM extends Mapper {
|
2011-08-28 21:49:01 +03:00
|
|
|
|
/**
|
2012-04-18 08:33:41 +03:00
|
|
|
|
* Добавление сущности в БД
|
2011-08-28 21:49:01 +03:00
|
|
|
|
*
|
2012-04-18 08:33:41 +03:00
|
|
|
|
* @param EntityORM $oEntity Объект сущности
|
|
|
|
|
* @return int|bool Если есть primary индекс с автоинкрементом, то возвращает его для новой записи
|
2011-08-28 21:49:01 +03:00
|
|
|
|
*/
|
2010-08-13 19:26:19 +03:00
|
|
|
|
public function AddEntity($oEntity) {
|
|
|
|
|
$sTableName = self::GetTableName($oEntity);
|
2012-04-18 08:33:41 +03:00
|
|
|
|
|
|
|
|
|
$sql = "INSERT INTO ".$sTableName." SET ?a ";
|
2013-02-11 12:38:24 +02:00
|
|
|
|
return $this->oDb->query($sql,$oEntity->_getDataFields());
|
2010-08-13 19:26:19 +03:00
|
|
|
|
}
|
2011-08-28 21:49:01 +03:00
|
|
|
|
/**
|
|
|
|
|
* Обновление сущности
|
|
|
|
|
*
|
2012-04-18 08:33:41 +03:00
|
|
|
|
* @param EntityORM $oEntity Объект сущности
|
|
|
|
|
* @return int|bool Возвращает число измененых записей в БД
|
2011-08-28 21:49:01 +03:00
|
|
|
|
*/
|
2010-08-29 10:03:53 +03:00
|
|
|
|
public function UpdateEntity($oEntity) {
|
2010-08-13 19:26:19 +03:00
|
|
|
|
$sTableName = self::GetTableName($oEntity);
|
2012-02-08 17:06:18 +02:00
|
|
|
|
|
|
|
|
|
if($aPrimaryKey=$oEntity->_getPrimaryKey()) {
|
|
|
|
|
// Возможен составной ключ
|
|
|
|
|
if (!is_array($aPrimaryKey)) {
|
|
|
|
|
$aPrimaryKey=array($aPrimaryKey);
|
|
|
|
|
}
|
|
|
|
|
$sWhere=' 1 = 1 ';
|
|
|
|
|
foreach ($aPrimaryKey as $sField) {
|
|
|
|
|
$sWhere.=' and '.$this->oDb->escape($sField,true)." = ".$this->oDb->escape($oEntity->_getDataOne($sField));
|
|
|
|
|
}
|
|
|
|
|
$sql = "UPDATE ".$sTableName." SET ?a WHERE {$sWhere}";
|
2013-02-11 12:38:24 +02:00
|
|
|
|
return $this->oDb->query($sql,$oEntity->_getDataFields());
|
2011-03-25 18:35:15 +02:00
|
|
|
|
} else {
|
|
|
|
|
$aOriginalData = $oEntity->_getOriginalData();
|
|
|
|
|
$sWhere = implode(' AND ',array_map(create_function(
|
2012-04-18 08:33:41 +03:00
|
|
|
|
'$k,$v,$oDb',
|
|
|
|
|
'return "{$oDb->escape($k,true)} = {$oDb->escape($v)}";'
|
|
|
|
|
),array_keys($aOriginalData),array_values($aOriginalData),array_fill(0,count($aOriginalData),$this->oDb)));
|
|
|
|
|
$sql = "UPDATE ".$sTableName." SET ?a WHERE 1=1 AND ". $sWhere;
|
2013-02-11 12:38:24 +02:00
|
|
|
|
return $this->oDb->query($sql,$oEntity->_getDataFields());
|
2011-03-25 18:35:15 +02:00
|
|
|
|
}
|
2010-08-13 19:26:19 +03:00
|
|
|
|
}
|
2011-08-28 21:49:01 +03:00
|
|
|
|
/**
|
|
|
|
|
* Удаление сущности
|
|
|
|
|
*
|
2012-04-18 08:33:41 +03:00
|
|
|
|
* @param EntityORM $oEntity Объект сущности
|
|
|
|
|
* @return int|bool Возвращает число удаленных записей в БД
|
2011-08-28 21:49:01 +03:00
|
|
|
|
*/
|
2012-04-18 08:33:41 +03:00
|
|
|
|
public function DeleteEntity($oEntity) {
|
2010-08-13 19:26:19 +03:00
|
|
|
|
$sTableName = self::GetTableName($oEntity);
|
2012-04-18 08:33:41 +03:00
|
|
|
|
|
2012-02-08 17:06:18 +02:00
|
|
|
|
if($aPrimaryKey=$oEntity->_getPrimaryKey()) {
|
|
|
|
|
// Возможен составной ключ
|
|
|
|
|
if (!is_array($aPrimaryKey)) {
|
|
|
|
|
$aPrimaryKey=array($aPrimaryKey);
|
|
|
|
|
}
|
|
|
|
|
$sWhere=' 1 = 1 ';
|
|
|
|
|
foreach ($aPrimaryKey as $sField) {
|
|
|
|
|
$sWhere.=' and '.$this->oDb->escape($sField,true)." = ".$this->oDb->escape($oEntity->_getDataOne($sField));
|
|
|
|
|
}
|
|
|
|
|
$sql = "DELETE FROM ".$sTableName." WHERE {$sWhere}";
|
|
|
|
|
return $this->oDb->query($sql);
|
2011-03-25 18:35:15 +02:00
|
|
|
|
} else {
|
|
|
|
|
$aOriginalData = $oEntity->_getOriginalData();
|
|
|
|
|
$sWhere = implode(' AND ',array_map(create_function(
|
2012-04-18 08:33:41 +03:00
|
|
|
|
'$k,$v,$oDb',
|
|
|
|
|
'return "{$oDb->escape($k,true)} = {$oDb->escape($v)}";'
|
|
|
|
|
),array_keys($aOriginalData),array_values($aOriginalData),array_fill(0,count($aOriginalData),$this->oDb)));
|
|
|
|
|
$sql = "DELETE FROM ".$sTableName." WHERE 1=1 AND ". $sWhere;
|
2011-03-25 18:35:15 +02:00
|
|
|
|
return $this->oDb->query($sql);
|
|
|
|
|
}
|
2010-08-13 19:26:19 +03:00
|
|
|
|
}
|
2011-08-28 21:49:01 +03:00
|
|
|
|
/**
|
|
|
|
|
* Получение сущности по фильтру
|
|
|
|
|
*
|
2012-04-18 08:33:41 +03:00
|
|
|
|
* @param array $aFilter Фильтр
|
|
|
|
|
* @param string $sEntityFull Название класса сущности
|
|
|
|
|
* @return EntityORM|null
|
2011-08-28 21:49:01 +03:00
|
|
|
|
*/
|
2010-08-13 19:26:19 +03:00
|
|
|
|
public function GetByFilter($aFilter,$sEntityFull) {
|
2010-11-13 07:43:25 +02:00
|
|
|
|
$oEntitySample=Engine::GetEntity($sEntityFull);
|
2010-08-13 19:26:19 +03:00
|
|
|
|
$sTableName = self::GetTableName($sEntityFull);
|
2012-04-18 08:33:41 +03:00
|
|
|
|
|
2011-02-24 12:39:35 +02:00
|
|
|
|
list($aFilterFields,$sFilterFields)=$this->BuildFilter($aFilter,$oEntitySample);
|
2012-04-18 08:33:41 +03:00
|
|
|
|
|
|
|
|
|
$sql = "SELECT * FROM ".$sTableName." WHERE 1=1 {$sFilterFields} LIMIT 0,1";
|
2010-08-13 19:26:19 +03:00
|
|
|
|
$aQueryParams=array_merge(array($sql),array_values($aFilterFields));
|
2012-04-18 08:33:41 +03:00
|
|
|
|
|
2010-08-13 19:26:19 +03:00
|
|
|
|
if($aRow=call_user_func_array(array($this->oDb,'selectRow'),$aQueryParams)) {
|
|
|
|
|
$oEntity=Engine::GetEntity($sEntityFull,$aRow);
|
|
|
|
|
$oEntity->_SetIsNew(false);
|
|
|
|
|
return $oEntity;
|
|
|
|
|
}
|
2012-04-18 08:33:41 +03:00
|
|
|
|
return null;
|
2010-08-13 19:26:19 +03:00
|
|
|
|
}
|
2011-08-28 21:49:01 +03:00
|
|
|
|
/**
|
|
|
|
|
* Получение списка сущностей по фильтру
|
|
|
|
|
*
|
2012-04-18 08:33:41 +03:00
|
|
|
|
* @param array $aFilter Фильтр
|
|
|
|
|
* @param string $sEntityFull Название класса сущности
|
|
|
|
|
* @return array
|
2011-08-28 21:49:01 +03:00
|
|
|
|
*/
|
2010-08-13 19:26:19 +03:00
|
|
|
|
public function GetItemsByFilter($aFilter,$sEntityFull) {
|
2010-11-13 07:43:25 +02:00
|
|
|
|
$oEntitySample=Engine::GetEntity($sEntityFull);
|
2010-08-13 19:26:19 +03:00
|
|
|
|
$sTableName = self::GetTableName($sEntityFull);
|
2012-04-18 08:33:41 +03:00
|
|
|
|
|
2011-02-24 12:31:54 +02:00
|
|
|
|
list($aFilterFields,$sFilterFields)=$this->BuildFilter($aFilter,$oEntitySample);
|
2013-01-11 10:41:11 +02:00
|
|
|
|
list($sOrder,$sLimit,$sGroup)=$this->BuildFilterMore($aFilter,$oEntitySample);
|
2012-04-18 08:33:41 +03:00
|
|
|
|
|
2013-01-11 10:41:11 +02:00
|
|
|
|
$sql = "SELECT * FROM ".$sTableName." WHERE 1=1 {$sFilterFields} {$sGroup} {$sOrder} {$sLimit} ";
|
2010-08-13 19:26:19 +03:00
|
|
|
|
$aQueryParams=array_merge(array($sql),array_values($aFilterFields));
|
|
|
|
|
$aItems=array();
|
|
|
|
|
if($aRows=call_user_func_array(array($this->oDb,'select'),$aQueryParams)) {
|
|
|
|
|
foreach($aRows as $aRow) {
|
|
|
|
|
$oEntity=Engine::GetEntity($sEntityFull,$aRow);
|
|
|
|
|
$oEntity->_SetIsNew(false);
|
|
|
|
|
$aItems[] = $oEntity;
|
2010-09-21 18:01:05 +03:00
|
|
|
|
}
|
2010-08-13 19:26:19 +03:00
|
|
|
|
}
|
|
|
|
|
return $aItems;
|
|
|
|
|
}
|
2011-08-28 21:49:01 +03:00
|
|
|
|
/**
|
|
|
|
|
* Получение числа сущностей по фильтру
|
|
|
|
|
*
|
2012-04-18 08:33:41 +03:00
|
|
|
|
* @param array $aFilter Фильтр
|
|
|
|
|
* @param string $sEntityFull Название класса сущности
|
|
|
|
|
* @return int
|
2011-08-28 21:49:01 +03:00
|
|
|
|
*/
|
2010-09-21 18:01:05 +03:00
|
|
|
|
public function GetCountItemsByFilter($aFilter,$sEntityFull) {
|
2010-11-13 07:43:25 +02:00
|
|
|
|
$oEntitySample=Engine::GetEntity($sEntityFull);
|
2010-09-21 18:01:05 +03:00
|
|
|
|
$sTableName = self::GetTableName($sEntityFull);
|
2012-04-18 08:33:41 +03:00
|
|
|
|
|
|
|
|
|
list($aFilterFields,$sFilterFields)=$this->BuildFilter($aFilter,$oEntitySample);
|
2013-07-10 10:06:23 +03:00
|
|
|
|
list($sOrder,$sLimit,$sGroup)=$this->BuildFilterMore($aFilter,$oEntitySample);
|
2012-04-18 08:33:41 +03:00
|
|
|
|
|
2013-08-05 07:50:15 +03:00
|
|
|
|
if ($sGroup) {
|
|
|
|
|
/**
|
|
|
|
|
* Т.к. count меняет свою логику при наличии группировки
|
|
|
|
|
*/
|
|
|
|
|
$sql = "SELECT SQL_CALC_FOUND_ROWS * FROM `".$sTableName."` WHERE 1=1 {$sFilterFields} {$sGroup} ";
|
|
|
|
|
} else {
|
|
|
|
|
$sql = "SELECT count(*) as c FROM ".$sTableName." WHERE 1=1 {$sFilterFields} {$sGroup} ";
|
|
|
|
|
}
|
2012-04-18 08:33:41 +03:00
|
|
|
|
$aQueryParams=array_merge(array($sql),array_values($aFilterFields));
|
2011-02-24 12:31:54 +02:00
|
|
|
|
if($aRow=call_user_func_array(array($this->oDb,'selectRow'),$aQueryParams)) {
|
2013-08-05 07:50:15 +03:00
|
|
|
|
if ($sGroup) {
|
|
|
|
|
$aRow=$this->oDb->selectRow('SELECT FOUND_ROWS() as c;');
|
|
|
|
|
}
|
2011-02-24 12:31:54 +02:00
|
|
|
|
return $aRow['c'];
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2011-08-28 21:49:01 +03:00
|
|
|
|
/**
|
|
|
|
|
* Получение сущностей по связанной таблице
|
|
|
|
|
*
|
2012-04-18 08:33:41 +03:00
|
|
|
|
* @param array $aFilter Фильтр
|
|
|
|
|
* @param string $sEntityFull Название класса сущности
|
|
|
|
|
* @return array
|
2011-08-28 21:49:01 +03:00
|
|
|
|
*/
|
2011-03-25 18:35:15 +02:00
|
|
|
|
public function GetItemsByJoinTable($aFilter,$sEntityFull) {
|
|
|
|
|
$oEntitySample=Engine::GetEntity($sEntityFull);
|
|
|
|
|
$sTableName = self::GetTableName($sEntityFull);
|
2011-08-28 21:49:01 +03:00
|
|
|
|
$sPrimaryKey = $oEntitySample->_getPrimaryKey();
|
|
|
|
|
|
2011-03-25 18:35:15 +02:00
|
|
|
|
list($aFilterFields,$sFilterFields)=$this->BuildFilter($aFilter,$oEntitySample);
|
|
|
|
|
list($sOrder,$sLimit)=$this->BuildFilterMore($aFilter,$oEntitySample);
|
|
|
|
|
|
|
|
|
|
$sql = "SELECT a.*, b.* FROM ?# a LEFT JOIN ".$sTableName." b ON b.?# = a.?# WHERE a.?#=? {$sFilterFields} {$sOrder} {$sLimit}";
|
|
|
|
|
$aQueryParams=array_merge(array($sql,$aFilter['#join_table'],$sPrimaryKey,$aFilter['#relation_key'],$aFilter['#by_key'],$aFilter['#by_value']),array_values($aFilterFields));
|
2011-08-28 21:49:01 +03:00
|
|
|
|
|
2011-03-25 18:35:15 +02:00
|
|
|
|
$aItems = array();
|
|
|
|
|
if($aRows=call_user_func_array(array($this->oDb,'select'),$aQueryParams)) {
|
|
|
|
|
foreach($aRows as $aRow) {
|
|
|
|
|
$oEntity=Engine::GetEntity($sEntityFull,$aRow);
|
|
|
|
|
$oEntity->_SetIsNew(false);
|
|
|
|
|
$aItems[] = $oEntity;
|
2011-08-28 21:49:01 +03:00
|
|
|
|
}
|
2011-03-25 18:35:15 +02:00
|
|
|
|
}
|
|
|
|
|
return $aItems;
|
|
|
|
|
}
|
2011-05-04 17:07:12 +03:00
|
|
|
|
|
2011-08-28 21:49:01 +03:00
|
|
|
|
/**
|
|
|
|
|
* Получение числа сущностей по связанной таблице
|
|
|
|
|
*
|
2012-04-18 08:33:41 +03:00
|
|
|
|
* @param array $aFilter Фильтр
|
|
|
|
|
* @param string $sEntityFull Название класса сущности
|
|
|
|
|
* @return int
|
2011-08-28 21:49:01 +03:00
|
|
|
|
*/
|
2012-04-18 08:33:41 +03:00
|
|
|
|
public function GetCountItemsByJoinTable($aFilter,$sEntityFull) {
|
2011-05-04 17:07:12 +03:00
|
|
|
|
$oEntitySample=Engine::GetEntity($sEntityFull);
|
|
|
|
|
list($aFilterFields,$sFilterFields)=$this->BuildFilter($aFilter,$oEntitySample);
|
|
|
|
|
|
2011-05-31 16:04:05 +03:00
|
|
|
|
$sql = "SELECT count(*) as c FROM ?# a WHERE a.?#=? {$sFilterFields}";
|
|
|
|
|
$aQueryParams=array_merge(array($sql,$aFilter['#join_table'],$aFilter['#by_key'],$aFilter['#by_value']),array_values($aFilterFields));
|
2011-05-04 17:07:12 +03:00
|
|
|
|
|
2012-04-18 08:33:41 +03:00
|
|
|
|
if($aRow=call_user_func_array(array($this->oDb,'selectRow'),$aQueryParams)) {
|
2011-05-04 17:07:12 +03:00
|
|
|
|
return $aRow['c'];
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2011-08-28 21:49:01 +03:00
|
|
|
|
/**
|
|
|
|
|
* Построение фильтра
|
|
|
|
|
*
|
2012-04-18 08:33:41 +03:00
|
|
|
|
* @param array $aFilter Фильтр
|
|
|
|
|
* @param EntityORM $oEntitySample Объект сущности
|
|
|
|
|
* @return array
|
2011-08-28 21:49:01 +03:00
|
|
|
|
*/
|
2011-02-24 12:31:54 +02:00
|
|
|
|
public function BuildFilter($aFilter,$oEntitySample) {
|
2010-09-21 18:01:05 +03:00
|
|
|
|
$aFilterFields=array();
|
|
|
|
|
foreach ($aFilter as $k=>$v) {
|
2011-03-27 21:52:31 +03:00
|
|
|
|
if (substr($k,0,1)=='#' || (is_string($v) && substr($v,0,1)=='#')) {
|
2012-04-18 08:33:41 +03:00
|
|
|
|
|
2010-09-21 18:01:05 +03:00
|
|
|
|
} else {
|
2010-11-13 07:43:25 +02:00
|
|
|
|
$aFilterFields[$oEntitySample->_getField($k)]=$v;
|
2010-09-21 18:01:05 +03:00
|
|
|
|
}
|
2012-04-18 08:33:41 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$sFilterFields='';
|
|
|
|
|
foreach ($aFilterFields as $k => $v) {
|
2011-02-24 12:31:54 +02:00
|
|
|
|
$aK=explode(' ',trim($k));
|
2012-12-29 10:57:51 +02:00
|
|
|
|
$sFieldCurrent=$this->oDb->escape($aK[0],true);
|
2011-02-24 12:31:54 +02:00
|
|
|
|
$sConditionCurrent=' = ';
|
|
|
|
|
if (count($aK)>1) {
|
|
|
|
|
$sConditionCurrent=strtolower($aK[1]);
|
|
|
|
|
}
|
2011-03-27 21:52:31 +03:00
|
|
|
|
if (strtolower($sConditionCurrent)=='in') {
|
2011-03-25 18:35:15 +02:00
|
|
|
|
$sFilterFields.=" and {$sFieldCurrent} {$sConditionCurrent} ( ?a ) ";
|
2011-02-24 12:31:54 +02:00
|
|
|
|
} else {
|
2011-03-25 18:35:15 +02:00
|
|
|
|
$sFilterFields.=" and {$sFieldCurrent} {$sConditionCurrent} ? ";
|
2011-02-24 12:31:54 +02:00
|
|
|
|
}
|
2010-09-21 18:01:05 +03:00
|
|
|
|
}
|
2012-04-18 08:33:41 +03:00
|
|
|
|
if (isset($aFilter['#where']) and is_array($aFilter['#where'])) {
|
|
|
|
|
// '#where' => array('id = ?d OR name = ?' => array(1,'admin'));
|
|
|
|
|
foreach ($aFilter['#where'] as $sFilterKey => $aValues) {
|
|
|
|
|
$aFilterFields = array_merge($aFilterFields, $aValues);
|
|
|
|
|
$sFilterFields .= ' and '. trim($sFilterKey) .' ';
|
2011-04-19 15:49:13 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
2011-02-24 12:31:54 +02:00
|
|
|
|
return array($aFilterFields,$sFilterFields);
|
2010-09-21 18:01:05 +03:00
|
|
|
|
}
|
2011-08-28 21:49:01 +03:00
|
|
|
|
/**
|
|
|
|
|
* Построение дополнительного фильтра
|
2012-04-18 08:33:41 +03:00
|
|
|
|
* Здесь учитываются ключи фильтра вида #*
|
2011-08-28 21:49:01 +03:00
|
|
|
|
*
|
2012-04-18 08:33:41 +03:00
|
|
|
|
* @param array $aFilter Фильтр
|
|
|
|
|
* @param EntityORM $oEntitySample Объект сущности
|
|
|
|
|
* @return array
|
2011-08-28 21:49:01 +03:00
|
|
|
|
*/
|
2011-03-25 18:35:15 +02:00
|
|
|
|
public function BuildFilterMore($aFilter,$oEntitySample) {
|
|
|
|
|
// Сортировка
|
|
|
|
|
$sOrder='';
|
|
|
|
|
if (isset($aFilter['#order'])) {
|
|
|
|
|
if(!is_array($aFilter['#order'])) {
|
|
|
|
|
$aFilter['#order'] = array($aFilter['#order']);
|
|
|
|
|
}
|
|
|
|
|
foreach ($aFilter['#order'] as $key=>$value) {
|
|
|
|
|
if (is_numeric($key)) {
|
|
|
|
|
$key=$value;
|
|
|
|
|
$value='asc';
|
|
|
|
|
} elseif (!in_array($value,array('asc','desc'))) {
|
|
|
|
|
$value='asc';
|
|
|
|
|
}
|
2012-12-29 10:57:51 +02:00
|
|
|
|
$key = $this->oDb->escape($oEntitySample->_getField($key),true);
|
2011-03-25 18:35:15 +02:00
|
|
|
|
$sOrder.=" {$key} {$value},";
|
|
|
|
|
}
|
|
|
|
|
$sOrder=trim($sOrder,',');
|
|
|
|
|
if ($sOrder!='') {
|
|
|
|
|
$sOrder="ORDER BY {$sOrder}";
|
|
|
|
|
}
|
2010-11-13 07:43:25 +02:00
|
|
|
|
}
|
2012-04-18 08:33:41 +03:00
|
|
|
|
|
2011-03-25 18:35:15 +02:00
|
|
|
|
// Постраничность
|
|
|
|
|
if (isset($aFilter['#page']) and is_array($aFilter['#page']) and count($aFilter['#page'])==2) { // array(2,15) - 2 - page, 15 - count
|
|
|
|
|
$aFilter['#limit']=array(($aFilter['#page'][0]-1)*$aFilter['#page'][1],$aFilter['#page'][1]);
|
2010-11-13 07:43:25 +02:00
|
|
|
|
}
|
2012-04-18 08:33:41 +03:00
|
|
|
|
|
2011-03-25 18:35:15 +02:00
|
|
|
|
// Лимит
|
|
|
|
|
$sLimit='';
|
|
|
|
|
if (isset($aFilter['#limit'])) { // допустимы варианты: limit=10 , limit=array(10) , limit=array(10,15)
|
|
|
|
|
$aLimit=$aFilter['#limit'];
|
|
|
|
|
if (is_numeric($aLimit)) {
|
|
|
|
|
$iBegin=0;
|
|
|
|
|
$iEnd=$aLimit;
|
|
|
|
|
} elseif (is_array($aLimit)) {
|
|
|
|
|
if (count($aLimit)>1) {
|
|
|
|
|
$iBegin=$aLimit[0];
|
|
|
|
|
$iEnd=$aLimit[1];
|
|
|
|
|
} else {
|
|
|
|
|
$iBegin=0;
|
|
|
|
|
$iEnd=$aLimit[0];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
$sLimit="LIMIT {$iBegin}, {$iEnd}";
|
2010-08-29 10:03:53 +03:00
|
|
|
|
}
|
2013-01-11 10:41:11 +02:00
|
|
|
|
|
|
|
|
|
// Группировка
|
|
|
|
|
$sGroup='';
|
|
|
|
|
if (isset($aFilter['#group'])) {
|
|
|
|
|
if(!is_array($aFilter['#group'])) {
|
|
|
|
|
$aFilter['#group'] = array($aFilter['#group']);
|
|
|
|
|
}
|
|
|
|
|
foreach ($aFilter['#group'] as $sField) {
|
|
|
|
|
$sField = $this->oDb->escape($oEntitySample->_getField($sField),true);
|
|
|
|
|
$sGroup.=" {$sField},";
|
|
|
|
|
}
|
|
|
|
|
$sGroup=trim($sGroup,',');
|
|
|
|
|
if ($sGroup!='') {
|
|
|
|
|
$sGroup="GROUP BY {$sGroup}";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return array($sOrder,$sLimit,$sGroup);
|
2010-08-29 10:03:53 +03:00
|
|
|
|
}
|
2011-08-28 21:49:01 +03:00
|
|
|
|
/**
|
2012-04-18 08:33:41 +03:00
|
|
|
|
* Список колонок/полей сущности
|
2011-08-28 21:49:01 +03:00
|
|
|
|
*
|
2012-04-18 08:33:41 +03:00
|
|
|
|
* @param EntityORM $oEntity Объект сущности
|
|
|
|
|
* @return array
|
2011-08-28 21:49:01 +03:00
|
|
|
|
*/
|
2010-11-13 07:43:25 +02:00
|
|
|
|
public function ShowColumnsFrom($oEntity) {
|
|
|
|
|
$sTableName = self::GetTableName($oEntity);
|
2011-02-14 15:32:20 +02:00
|
|
|
|
return $this->ShowColumnsFromTable($sTableName);
|
|
|
|
|
}
|
2011-08-28 21:49:01 +03:00
|
|
|
|
/**
|
2012-04-18 08:33:41 +03:00
|
|
|
|
* Список колонок/полей таблицы
|
2011-08-28 21:49:01 +03:00
|
|
|
|
*
|
2012-04-18 08:33:41 +03:00
|
|
|
|
* @param string $sTableName Название таблицы
|
|
|
|
|
* @return array
|
2011-08-28 21:49:01 +03:00
|
|
|
|
*/
|
2011-02-14 15:32:20 +02:00
|
|
|
|
public function ShowColumnsFromTable($sTableName) {
|
2011-02-27 16:46:01 +02:00
|
|
|
|
if (false === ($aItems = Engine::getInstance()->Cache_GetLife("columns_table_{$sTableName}"))) {
|
|
|
|
|
$sql = "SHOW COLUMNS FROM ".$sTableName;
|
|
|
|
|
$aItems = array();
|
|
|
|
|
if($aRows=$this->oDb->select($sql)) {
|
|
|
|
|
foreach($aRows as $aRow) {
|
|
|
|
|
$aItems[] = $aRow['Field'];
|
|
|
|
|
if($aRow['Key']=='PRI') {
|
|
|
|
|
$aItems['#primary_key'] = $aRow['Field'];
|
|
|
|
|
}
|
2010-11-13 07:43:25 +02:00
|
|
|
|
}
|
2011-02-27 16:46:01 +02:00
|
|
|
|
}
|
|
|
|
|
Engine::getInstance()->Cache_SetLife($aItems, "columns_table_{$sTableName}");
|
2010-11-13 07:43:25 +02:00
|
|
|
|
}
|
|
|
|
|
return $aItems;
|
|
|
|
|
}
|
2012-02-08 17:06:18 +02:00
|
|
|
|
/**
|
|
|
|
|
* Primary индекс сущности
|
|
|
|
|
*
|
2012-04-18 08:33:41 +03:00
|
|
|
|
* @param EntityORM $oEntity Объект сущности
|
|
|
|
|
* @return array
|
2012-02-08 17:06:18 +02:00
|
|
|
|
*/
|
|
|
|
|
public function ShowPrimaryIndexFrom($oEntity) {
|
|
|
|
|
$sTableName = self::GetTableName($oEntity);
|
|
|
|
|
return $this->ShowPrimaryIndexFromTable($sTableName);
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* Primary индекс таблицы
|
|
|
|
|
*
|
2012-04-18 08:33:41 +03:00
|
|
|
|
* @param string $sTableName Название таблицы
|
|
|
|
|
* @return array
|
2012-02-08 17:06:18 +02:00
|
|
|
|
*/
|
|
|
|
|
public function ShowPrimaryIndexFromTable($sTableName) {
|
|
|
|
|
if (false === ($aItems = Engine::getInstance()->Cache_GetLife("index_table_{$sTableName}"))) {
|
|
|
|
|
$sql = "SHOW INDEX FROM ".$sTableName;
|
|
|
|
|
$aItems = array();
|
|
|
|
|
if($aRows=$this->oDb->select($sql)) {
|
|
|
|
|
foreach($aRows as $aRow) {
|
|
|
|
|
if ($aRow['Key_name']=='PRIMARY') {
|
|
|
|
|
$aItems[$aRow['Seq_in_index']]=$aRow['Column_name'];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Engine::getInstance()->Cache_SetLife($aItems, "index_table_{$sTableName}");
|
|
|
|
|
}
|
|
|
|
|
return $aItems;
|
|
|
|
|
}
|
2011-08-28 21:49:01 +03:00
|
|
|
|
/**
|
|
|
|
|
* Возвращает имя таблицы для сущности
|
|
|
|
|
*
|
2012-04-18 08:33:41 +03:00
|
|
|
|
* @param EntityORM $oEntity Объект сущности
|
|
|
|
|
* @return string
|
2011-08-28 21:49:01 +03:00
|
|
|
|
*/
|
2010-08-13 19:26:19 +03:00
|
|
|
|
public static function GetTableName($oEntity) {
|
|
|
|
|
/**
|
|
|
|
|
* Варианты таблиц:
|
|
|
|
|
* prefix_user -> если модуль совпадает с сущностью
|
|
|
|
|
* prefix_user_invite -> если модуль не сопадает с сущностью
|
2013-01-26 11:29:37 +02:00
|
|
|
|
* Если сущность плагина:
|
|
|
|
|
* prefix_pluginname_user
|
|
|
|
|
* prefix_pluginname_user_invite
|
2010-08-13 19:26:19 +03:00
|
|
|
|
*/
|
2012-01-21 13:46:07 +02:00
|
|
|
|
$sClass = Engine::getInstance()->Plugin_GetDelegater('entity', is_object($oEntity)?get_class($oEntity):$oEntity);
|
2013-01-26 11:29:37 +02:00
|
|
|
|
$sPluginName = func_underscore(Engine::GetPluginName($sClass));
|
2012-01-21 13:46:07 +02:00
|
|
|
|
$sModuleName = func_underscore(Engine::GetModuleName($sClass));
|
|
|
|
|
$sEntityName = func_underscore(Engine::GetEntityName($sClass));
|
2010-08-29 10:03:53 +03:00
|
|
|
|
if (strpos($sEntityName,$sModuleName)===0) {
|
|
|
|
|
$sTable=func_underscore($sEntityName);
|
2010-08-13 19:26:19 +03:00
|
|
|
|
} else {
|
2010-08-29 10:03:53 +03:00
|
|
|
|
$sTable=func_underscore($sModuleName).'_'.func_underscore($sEntityName);
|
2010-08-13 19:26:19 +03:00
|
|
|
|
}
|
2013-01-26 11:29:37 +02:00
|
|
|
|
if ($sPluginName) {
|
|
|
|
|
$sTablePlugin=$sPluginName.'_'.$sTable;
|
|
|
|
|
/**
|
|
|
|
|
* Для обратной совместимости с 1.0.1
|
|
|
|
|
* Если такая таблица определена в конфиге, то ок, если нет, то используем старый вариант без имени плагина
|
|
|
|
|
*/
|
|
|
|
|
if (Config::Get('db.table.'.$sTablePlugin)) {
|
|
|
|
|
$sTable=$sTablePlugin;
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-04-18 08:33:41 +03:00
|
|
|
|
/**
|
|
|
|
|
* Если название таблиц переопределено в конфиге, то возвращаем его
|
|
|
|
|
*/
|
2010-08-13 19:26:19 +03:00
|
|
|
|
if(Config::Get('db.table.'.$sTable)) {
|
|
|
|
|
return Config::Get('db.table.'.$sTable);
|
|
|
|
|
} else {
|
|
|
|
|
return Config::Get('db.table.prefix').$sTable;
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-08-28 21:49:01 +03:00
|
|
|
|
/**
|
2012-04-18 08:33:41 +03:00
|
|
|
|
* Загрузка данных из таблицы связи many_to_many
|
|
|
|
|
*
|
|
|
|
|
* @param string $sDbTableAlias Алиас имени таблицы связи, например, 'db.table.my_relation'
|
|
|
|
|
* @param string $sEntityKey Название поля в таблице связи с id сущности, для которой зегружаются объекты.
|
|
|
|
|
* @param int $iEntityId Id сущнсоти, для который загружаются объекты
|
|
|
|
|
* @param string $sRelationKey Название поля в таблице связи с id сущности, объекты которой загружаются по связи.
|
|
|
|
|
* @return array Список id из столбца $sRelationKey, у которых столбец $sEntityKey = $iEntityId
|
|
|
|
|
*/
|
2011-08-28 21:49:01 +03:00
|
|
|
|
public function getManyToManySet($sDbTableAlias, $sEntityKey, $iEntityId, $sRelationKey) {
|
|
|
|
|
if (!Config::Get($sDbTableAlias)) return array();
|
|
|
|
|
$sql = 'SELECT ?# FROM '.Config::Get($sDbTableAlias).' WHERE ?# = ?d';
|
|
|
|
|
return $this->oDb->selectCol($sql, $sRelationKey, $sEntityKey, $iEntityId);
|
|
|
|
|
}
|
|
|
|
|
/**
|
2012-04-18 08:33:41 +03:00
|
|
|
|
* Обновление связи many_to_many
|
|
|
|
|
*
|
|
|
|
|
* @param string $sDbTableAlias Алиас имени таблицы связи
|
|
|
|
|
* @param string $sEntityKey Название поля в таблице связи с id сущности, для которой обновляются связи.
|
|
|
|
|
* @param int $iEntityId Id сущнсоти, для который обновляются связи
|
|
|
|
|
* @param string $sRelationKey Название поля в таблице связи с id сущности, с объектами которой назначаются связи.
|
|
|
|
|
* @param array $aInsertSet Массив id для $sRelationKey, которые нужно добавить
|
|
|
|
|
* @param array $aDeleteSet Массив id для $sRelationKey, которые нужно удалить
|
|
|
|
|
* @return bool
|
|
|
|
|
*/
|
2011-08-28 21:49:01 +03:00
|
|
|
|
public function updateManyToManySet($sDbTableAlias, $sEntityKey, $iEntityId, $sRelationKey, $aInsertSet, $aDeleteSet) {
|
|
|
|
|
if (!Config::Get($sDbTableAlias)) return false;
|
|
|
|
|
if (count($aDeleteSet)) {
|
|
|
|
|
$sql = 'DELETE FROM '.Config::Get($sDbTableAlias).' WHERE ?# = ?d AND ?# IN (?a)';
|
|
|
|
|
$this->oDb->query($sql, $sEntityKey, $iEntityId, $sRelationKey, $aDeleteSet);
|
|
|
|
|
}
|
2011-05-03 14:55:17 +03:00
|
|
|
|
|
2011-08-28 21:49:01 +03:00
|
|
|
|
if (count($aInsertSet)) {
|
|
|
|
|
$sql = 'INSERT INTO '.Config::Get($sDbTableAlias).' (?#,?#) VALUES ';
|
|
|
|
|
$aParams = array();
|
|
|
|
|
foreach ($aInsertSet as $iId) {
|
|
|
|
|
$sql .= '(?d, ?d), ';
|
|
|
|
|
$aParams[] = $iEntityId;
|
|
|
|
|
$aParams[] = $iId;
|
|
|
|
|
}
|
|
|
|
|
$sql = substr($sql, 0, -2); // удаление последних ", "
|
|
|
|
|
call_user_func_array(array($this->oDb, 'query'), array_merge(array($sql,$sEntityKey, $sRelationKey), $aParams));
|
|
|
|
|
}
|
2012-04-18 08:33:41 +03:00
|
|
|
|
return true;
|
2011-08-28 21:49:01 +03:00
|
|
|
|
}
|
|
|
|
|
/**
|
2012-04-18 08:33:41 +03:00
|
|
|
|
* Удаление связей many_to_many для объекта. Используется при удалении сущности,
|
|
|
|
|
* чтобы не удалять большие коллекции связанных объектов через updateManyToManySet(),
|
|
|
|
|
* где используется IN.
|
|
|
|
|
*
|
|
|
|
|
* @param string $sDbTableAlias Алиас имени таблицы связи
|
|
|
|
|
* @param string $sEntityKey Название поля в таблице связи с id сущности, для которой удаляются связи.
|
|
|
|
|
* @param int $iEntityId Id сущнсоти, для который удаляются связи
|
|
|
|
|
* @return bool
|
|
|
|
|
*/
|
2011-08-28 21:49:01 +03:00
|
|
|
|
public function deleteManyToManySet($sDbTableAlias, $sEntityKey, $iEntityId) {
|
|
|
|
|
if (!Config::Get($sDbTableAlias)) return false;
|
|
|
|
|
$sql = 'DELETE FROM '.Config::Get($sDbTableAlias).' WHERE ?# = ?d';
|
|
|
|
|
$this->oDb->query($sql, $sEntityKey, $iEntityId);
|
2012-04-18 08:33:41 +03:00
|
|
|
|
return true;
|
2011-08-28 21:49:01 +03:00
|
|
|
|
}
|
|
|
|
|
}
|