1
0
Fork 0
mirror of https://github.com/Oreolek/ifhub.club.git synced 2024-07-01 05:55:02 +03:00

- Save и Delete сущностей без PrimaryKey (с помощью aOriginalData)

- Возможность указать глубину автоопределения у _getField()
- Возможность использования фильтров в релейшенах: $oUser->getTopics(array('topic_date_add >' => '2011'));
- Удалены методы ModuleORM::GetByArray() и ModuleORM::GetCountByArray()
- Алиас для Sample_GetItemsByArrayKey(): Sample_GetItemsByKeyIn()
- Фикс автоопределения искомой сущности Sample_GetItemsByKey()
- Фикс Sample_GetAll() и Sample_GetAnotherSampleAll()
- В MapperORM вынесена обработка #order, #limit, #page в BuildFilterMore()
This commit is contained in:
Alexander Zinchuk 2011-03-25 16:35:15 +00:00
parent face5bc1af
commit 7c1c0811e6
3 changed files with 180 additions and 187 deletions

View file

@ -27,6 +27,8 @@ abstract class EntityORM extends Entity {
const RELATION_TYPE_MANY_TO_MANY='many_to_many';
const RELATION_TYPE_TREE='tree';
protected $_aOriginalData=array();
protected $aFields=array();
protected $aRelations=array();
@ -47,7 +49,7 @@ abstract class EntityORM extends Entity {
if(array_key_exists('#primary_key',$this->aFields)) {
$this->sPrimaryKey = $this->aFields['#primary_key'];
} else {
$this->sPrimaryKey = $this->_getField($this->sPrimaryKey);
$this->sPrimaryKey = $this->_getField($this->sPrimaryKey,2);
}
}
}
@ -123,7 +125,7 @@ abstract class EntityORM extends Entity {
}
public function getChildren() {
if(in_array(self::RELATION_TYPE_TREE,$this->aRelations)) {
return $this->_Method(__FUNCTION__ .'Of');
@ -213,9 +215,14 @@ abstract class EntityORM extends Entity {
$this->_aData[$sKey] = $val;
}
}
$this->_aOriginalData = $this->_aData;
}
}
public function _getOriginalData() {
return $this->_aOriginalData;
}
public function _getFields() {
if(empty($this->aFields)) {
$this->aFields=$this->ShowColumns();
@ -223,20 +230,29 @@ abstract class EntityORM extends Entity {
return $this->aFields;
}
public function _getField($sField) {
public function _getField($sField,$iPersistence=3) {
if($aFields=$this->_getFields()) {
if(in_array($sField,$aFields)) {
return $sField;
}
if($iPersistence==0) {
return null;
}
$sFieldU = func_camelize($sField);
$sEntityField = func_underscore(Engine::GetEntityName($this).$sFieldU);
if(in_array($sEntityField,$aFields)) {
return $sEntityField;
}
if($iPersistence==1) {
return null;
}
$sModuleEntityField = func_underscore(Engine::GetModuleName($this).Engine::GetEntityName($this).$sFieldU);
if(in_array($sModuleEntityField,$aFields)) {
return $sModuleEntityField;
}
if($iPersistence==2) {
return null;
}
$sModuleField = func_underscore(Engine::GetModuleName($this).$sFieldU);
if(in_array($sModuleField,$aFields)) {
return $sModuleField;
@ -287,8 +303,10 @@ abstract class EntityORM extends Entity {
$sRelationType=$this->aRelations[$sKey][0];
$sRelationKey=$this->aRelations[$sKey][2];
$sRelationJoinTable=null;
$sRelationJoinTableKey=0; // foreign key в join-таблице для текущей сущности
if($sRelationType == self::RELATION_TYPE_MANY_TO_MANY && array_key_exists(3, $this->aRelations[$sKey])) {
$sRelationJoinTable=$this->aRelations[$sKey][3];
$sRelationJoinTableKey=isset($this->aRelations[$sKey][4]) ? $this->aRelations[$sKey][4] : $this->_GetPrimaryKey();
}
/**
@ -313,29 +331,32 @@ abstract class EntityORM extends Entity {
$aCmdArgs=array();
switch ($sRelationType) {
case self::RELATION_TYPE_BELONGS_TO :
$sCmd="{$sRelPluginPrefix}{$sRelModuleName}_get{$sRelEntityName}By".func_camelize($sRelPrimaryKey);
$aCmdArgs[0]=$this->_getDataOne($sRelationKey);
$sCmd="{$sRelPluginPrefix}{$sRelModuleName}_get{$sRelEntityName}ByFilter";
$aCmdArgs[0]=array($sRelPrimaryKey => $this->_getDataOne($sRelationKey));
break;
case self::RELATION_TYPE_HAS_ONE :
$sCmd="{$sRelPluginPrefix}{$sRelModuleName}_get{$sRelEntityName}By".func_camelize($sRelationKey);
$aCmdArgs[0]=$iPrimaryKeyValue;
$sCmd="{$sRelPluginPrefix}{$sRelModuleName}_get{$sRelEntityName}ByFilter";
$aCmdArgs[0]=array($sRelationKey => $iPrimaryKeyValue);
break;
case self::RELATION_TYPE_HAS_MANY :
$sCmd="{$sRelPluginPrefix}{$sRelModuleName}_get{$sRelEntityName}ItemsBy".func_camelize($sRelationKey);
$aCmdArgs[0]=$iPrimaryKeyValue;
$sCmd="{$sRelPluginPrefix}{$sRelModuleName}_get{$sRelEntityName}ItemsByFilter";
$aCmdArgs[0]=array($sRelationKey => $iPrimaryKeyValue);
break;
case self::RELATION_TYPE_MANY_TO_MANY :
$sCmd="{$sRelPluginPrefix}Module{$sRelModuleName}_get{$sRelEntityName}ItemsByJoinTable";
$aCmdArgs[0] = array(
'join_table' => $sRelationJoinTable,
'relation_key' => $sRelationKey,
'by_key' => $this->_GetPrimaryKey(),
'by_value' => $iPrimaryKeyValue,
$aCmdArgs[0]=array(
'#join_table' => $sRelationJoinTable,
'#relation_key' => $sRelationKey,
'#by_key' => $sRelationJoinTableKey,
'#by_value' => $iPrimaryKeyValue,
);
break;
default:
break;
}
if(array_key_exists(0,$aArgs) && is_array($aArgs[0])) {
$aCmdArgs[0] = array_merge($aCmdArgs[0], $aArgs[0]);
}
$res=Engine::GetInstance()->_CallModule($sCmd,$aCmdArgs);
$this->aRelationsData[$sKey]=$res;

View file

@ -32,17 +32,36 @@ class MapperORM extends Mapper {
$sTableName = self::GetTableName($oEntity);
$iPrimaryKeyValue=$oEntity->_getDataOne($oEntity->_GetPrimaryKey());
$sql = "UPDATE ".$sTableName." SET ?a WHERE ".$oEntity->_GetPrimaryKey()." = ? ";
return $this->oDb->query($sql,$oEntity->_getData(),$iPrimaryKeyValue);
if(!empty($iPrimaryKeyValue)) {
$sql = "UPDATE ".$sTableName." SET ?a WHERE ".$oEntity->_GetPrimaryKey()." = ? ";
return $this->oDb->query($sql,$oEntity->_getData(),$iPrimaryKeyValue);
} else {
$aOriginalData = $oEntity->_getOriginalData();
$sWhere = implode(' AND ',array_map(create_function(
'$k,$v',
'return "{$k} = \"{$v}\"";'
),array_keys($aOriginalData),array_values($aOriginalData)));
$sql = "UPDATE ".$sTableName." SET ?a WHERE 1=1 AND ". $sWhere;
return $this->oDb->query($sql,$oEntity->_getData());
}
}
public function DeleteEntity($oEntity) {
$sTableName = self::GetTableName($oEntity);
$iPrimaryKeyValue=$oEntity->_getDataOne($oEntity->_GetPrimaryKey());
$sql = "DELETE FROM ".$sTableName." WHERE ".$oEntity->_GetPrimaryKey()." = ? ";
return $this->oDb->query($sql,$iPrimaryKeyValue);
if(!empty($iPrimaryKeyValue)) {
$sql = "DELETE FROM ".$sTableName." WHERE ".$oEntity->_GetPrimaryKey()." = ? ";
return $this->oDb->query($sql,$iPrimaryKeyValue);
} else {
$aOriginalData = $oEntity->_getOriginalData();
$sWhere = implode(' AND ',array_map(create_function(
'$k,$v',
'return "{$k} = \"{$v}\"";'
),array_keys($aOriginalData),array_values($aOriginalData)));
$sql = "DELETE FROM ".$sTableName." WHERE 1=1 AND ". $sWhere;
return $this->oDb->query($sql);
}
}
public function GetByFilter($aFilter,$sEntityFull) {
@ -64,10 +83,102 @@ class MapperORM extends Mapper {
public function GetItemsByFilter($aFilter,$sEntityFull) {
$oEntitySample=Engine::GetEntity($sEntityFull);
$sTableName = self::GetTableName($sEntityFull);
list($aFilterFields,$sFilterFields)=$this->BuildFilter($aFilter,$oEntitySample);
list($sOrder,$sLimit)=$this->BuildFilterMore($aFilter,$oEntitySample);
$sql = "SELECT * FROM ".$sTableName." WHERE 1=1 {$sFilterFields} {$sOrder} {$sLimit} ";
$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;
}
}
return $aItems;
}
public function GetCountItemsByFilter($aFilter,$sEntityFull) {
$oEntitySample=Engine::GetEntity($sEntityFull);
$sTableName = self::GetTableName($sEntityFull);
list($aFilterFields,$sFilterFields)=$this->BuildFilter($aFilter,$oEntitySample);
list($sOrder,$sLimit)=$this->BuildFilterMore($aFilter,$oEntitySample);
$sql = "SELECT count(*) as c FROM ".$sTableName." WHERE 1=1 {$sFilterFields} {$sOrder} {$sLimit} ";
$aQueryParams=array_merge(array($sql),array_values($aFilterFields));
if($aRow=call_user_func_array(array($this->oDb,'selectRow'),$aQueryParams)) {
return $aRow['c'];
}
return 0;
}
public function GetItemsByJoinTable($aFilter,$sEntityFull) {
$oEntitySample=Engine::GetEntity($sEntityFull);
$sTableName = self::GetTableName($sEntityFull);
$sPrimaryKey = $oEntitySample->_GetPrimaryKey();
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));
$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;
}
}
return $aItems;
}
public function BuildFilter($aFilter,$oEntitySample) {
if (isset($aFilter['#where']) and is_array($aFilter['#where'])) {
// '#where' => array('id = ?d OR name = ?' => array(1,'admin'));
foreach ($aFilter['#where'] as $sFilterFields => $aValues) {
return array($aValues,' and '. trim($sFilterFields) .' '); // возвращает первый элемент
}
}
$aFilterFields=array();
foreach ($aFilter as $k=>$v) {
if (substr($k,0,1)=='#') {
} else {
$aFilterFields[$oEntitySample->_getField($k)]=$v;
}
}
$sFilterFields='';
foreach ($aFilterFields as $k => $v) {
$aK=explode(' ',trim($k));
$sFieldCurrent=$aK[0];
$sConditionCurrent=' = ';
if (count($aK)>1) {
$sConditionCurrent=strtolower($aK[1]);
}
if ($sConditionCurrent=='in') {
$sFilterFields.=" and {$sFieldCurrent} {$sConditionCurrent} ( ?a ) ";
} else {
$sFilterFields.=" and {$sFieldCurrent} {$sConditionCurrent} ? ";
}
}
return array($aFilterFields,$sFilterFields);
}
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;
@ -75,6 +186,7 @@ class MapperORM extends Mapper {
} elseif (!in_array($value,array('asc','desc'))) {
$value='asc';
}
$key = $oEntitySample->_getField($key);
$sOrder.=" {$key} {$value},";
}
$sOrder=trim($sOrder,',');
@ -106,141 +218,9 @@ class MapperORM extends Mapper {
}
$sLimit="LIMIT {$iBegin}, {$iEnd}";
}
list($aFilterFields,$sFilterFields)=$this->BuildFilter($aFilter,$oEntitySample);
$sql = "SELECT * FROM ".$sTableName." WHERE 1=1 {$sFilterFields} {$sOrder} {$sLimit} ";
$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;
}
}
return $aItems;
return array($sOrder,$sLimit);
}
public function GetCountItemsByFilter($aFilter,$sEntityFull) {
$oEntitySample=Engine::GetEntity($sEntityFull);
$sTableName = self::GetTableName($sEntityFull);
list($aFilterFields,$sFilterFields)=$this->BuildFilter($aFilter,$oEntitySample);
$sql = "SELECT count(*) as c FROM ".$sTableName." WHERE 1=1 {$sFilterFields} ";
$aQueryParams=array_merge(array($sql),array_values($aFilterFields));
if($aRow=call_user_func_array(array($this->oDb,'selectRow'),$aQueryParams)) {
return $aRow['c'];
}
return 0;
}
public function BuildFilter($aFilter,$oEntitySample) {
if (isset($aFilter['#where']) and is_array($aFilter['#where'])) {
foreach ($aFilter['#where'] as $sKey => $aValues) {
return array($aValues,' and '.$sKey); // возвращает первый элемент
}
}
$aFilterFields=array();
foreach ($aFilter as $k=>$v) {
if (substr($k,0,1)=='#') {
} else {
$aFilterFields[$oEntitySample->_getField($k)]=$v;
}
}
$sFilterFields='';
foreach ($aFilterFields as $k => $v) {
$aK=explode(' ',trim($k));
$sFieldCurrent=$aK[0];
$sConditionCurrent=' = ';
if (count($aK)>1) {
$sConditionCurrent=strtolower($aK[1]);
}
if ($sConditionCurrent=='in') {
$sFilterFields.=" and `$sFieldCurrent` $sConditionCurrent ( ?a ) ";
} else {
$sFilterFields.=" and `$sFieldCurrent` $sConditionCurrent ? ";
}
}
return array($aFilterFields,$sFilterFields);
}
public function GetItemsByArray($aFilter,$sEntityFull) {
$oEntitySample=Engine::GetEntity($sEntityFull);
$sTableName = self::GetTableName($sEntityFull);
$aFilterFields=array();
foreach($aFilter as $k=>$v) {
$aFilterFields[$oEntitySample->_getField($k)]=$v;
}
$sFilterFields='';
if (count($aFilterFields)) {
$sFilterFields=' and '.implode(' IN ( ?a ) and ',array_keys($aFilterFields)).' IN ( ?a ) ';
}
$sql = "SELECT * FROM ".$sTableName." WHERE 1=1 {$sFilterFields} ";
$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;
}
}
return $aItems;
}
public function GetCountItemsByArray($aFilter,$sEntityFull) {
$oEntitySample=Engine::GetEntity($sEntityFull);
$sTableName = self::GetTableName($sEntityFull);
$aFilterFields=array();
foreach($aFilter as $k=>$v) {
$aFilterFields[$oEntitySample->_getField($k)]=$v;
}
$sFilterFields='';
if (count($aFilterFields)) {
$sFilterFields=' and '.implode(' IN ( ?a ) and ',array_keys($aFilterFields)).' IN ( ?a ) ';
}
$sql = "SELECT count(*) as c FROM ".$sTableName." WHERE 1=1 {$sFilterFields} ";
$aQueryParams=array_merge(array($sql),array_values($aFilterFields));
$aItems=array();
if($aRow=call_user_func_array(array($this->oDb,'selectRow'),$aQueryParams)) {
return $aRow['c'];
}
return 0;
}
public function GetItemsByJoinTable($aData,$sEntityFull) {
if(empty($aData)) {
return null;
}
$sTableName = self::GetTableName($sEntityFull);
$sql = "SELECT a.*, b.* FROM ?# a LEFT JOIN ".$sTableName." b USING(?#) WHERE a.?#=?";
$aItems = array();
if($aRows=$this->oDb->select($sql, $aData['join_table'],$aData['relation_key'],$aData['by_key'],$aData['by_value'])) {
foreach($aRows as $aRow) {
$oEntity=Engine::GetEntity($sEntityFull,$aRow);
$oEntity->_SetIsNew(false);
$aItems[] = $oEntity;
}
}
return $aItems;
}
public function ShowColumnsFrom($oEntity) {
$sTableName = self::GetTableName($oEntity);
return $this->ShowColumnsFromTable($sTableName);

View file

@ -240,7 +240,7 @@ abstract class ModuleORM extends Module {
$sEntityFull=Engine::GetPluginPrefix($this).'Module'.Engine::GetModuleName($this).'_Entity'.Engine::GetModuleName(get_class($this));
} elseif (!substr_count($sEntityFull,'_')) {
$sEntityFull=Engine::GetPluginPrefix($this).'Module'.Engine::GetModuleName($this).'_Entity'.$sEntityFull;
}
}
$sEntityFullRoot=$this->Plugin_GetRootDelegater('entity',$sEntityFull);
$sCacheKey=$sEntityFullRoot.'_items_by_filter_'.serialize($aFilter);
@ -256,7 +256,6 @@ abstract class ModuleORM extends Module {
$this->Cache_Set($aEntities,$sCacheKey, $aCacheTags, $iCacheTime);
}
/**
* Если необходимо подцепить связанные данные
*/
@ -326,32 +325,10 @@ abstract class ModuleORM extends Module {
}
$iCount=$this->oMapperORM->GetCountItemsByFilter($aFilter,$sEntityFull);
return $iCount;
}
public function GetItemsByArray($aFilter,$sEntityFull=null) {
foreach ($aFilter as $k=>$v) {
$aFilter[$k.' in']=$v;
unset($aFilter[$k]);
}
$aEntities=array();
$aData=$this->GetItemsByFilter($aFilter,$sEntityFull);
foreach ($aData as $oEntity) {
// здесь под вопросом какое поле использовать в качестве ключа, всегда примари или тот, который передан?
$aEntities[$oEntity->_getDataOne($oEntity->_GetPrimaryKey())]=$oEntity;
}
return $aEntities;
}
public function GetCountItemsByArray($aFilter=array(),$sEntityFull=null) {
foreach ($aFilter as $k=>$v) {
$aFilter[$k.' in']=$v;
unset($aFilter[$k]);
}
return $this->GetCountItemsByFilter($aFilter,$sEntityFull);
}
public function GetItemsByJoinTable($aJoinData=array(),$sEntityFull=null) {
if (is_null($sEntityFull)) {
$sEntityFull=Engine::GetPluginPrefix($this).'Module'.Engine::GetModuleName($this).'_Entity'.Engine::GetModuleName(get_class($this));
@ -409,14 +386,14 @@ abstract class ModuleORM extends Module {
$sNameUnderscore=func_underscore($sName);
$iEntityPosEnd=0;
if(strpos($sNameUnderscore,'_items')>4) {
if(strpos($sNameUnderscore,'_items')>=3) {
$iEntityPosEnd=strpos($sNameUnderscore,'_items');
} else if(strpos($sNameUnderscore,'_by')>4) {
} else if(strpos($sNameUnderscore,'_by')>=3) {
$iEntityPosEnd=strpos($sNameUnderscore,'_by');
} else if(strpos($sNameUnderscore,'_all')>4) {
} else if(strpos($sNameUnderscore,'_all')>=3) {
$iEntityPosEnd=strpos($sNameUnderscore,'_all');
}
if($iEntityPosEnd) {
if($iEntityPosEnd && $iEntityPosEnd > 4) {
$sEntityName=substr($sNameUnderscore,4,$iEntityPosEnd-4);
} else {
$sEntityName=func_underscore(Engine::GetModuleName($this)).'_';
@ -430,10 +407,23 @@ abstract class ModuleORM extends Module {
$sEntityName=func_camelize($sEntityName);
/**
* getUserItemsByArrayId() get_user_items_by_array_id
* getUserItemsByFilter() get_user_items_by_filter
*/
if (preg_match("@^get_([a-z]+)_items_by_array_([_a-z]+)$@i",$sNameUnderscore,$aMatch)) {
return $this->GetItemsByArray(array($aMatch[2]=>$aArgs[0]),$sEntityName);
if (preg_match("@^get_([a-z]+)((_items)|())_by_filter$@i",$sNameUnderscore,$aMatch)) {
if ($aMatch[2]=='_items') {
return $this->GetItemsByFilter($aArgs[0],$sEntityName);
} else {
return $this->GetByFilter($aArgs[0],$sEntityName);
}
}
/**
* getUserItemsByArrayId() get_user_items_by_array_id OR
* getUserItemsByIdIn() get_user_items_by_id_in
*/
if (preg_match("@^get_([a-z]+)_items_by_array_([_a-z]+)$@i",$sNameUnderscore,$aMatch) ||
preg_match("@^get_([a-z]+)_items_by_([_a-z]+)_in$@i",$sNameUnderscore,$aMatch)
) {
return $this->GetItemsByFilter(array("{$aMatch[2]} in"=>$aArgs[0]),$sEntityName);
}
/**
* getUserItemsByJoinTable() get_user_items_by_join_table
@ -462,9 +452,11 @@ abstract class ModuleORM extends Module {
}
}
/**
* getUserAll() get_user_all
* getUserAll() get_user_all OR getUserItemsAll() get_user_items_all
*/
if (preg_match("@^get_([a-z]+)_items_all$@i",$sNameUnderscore,$aMatch)) {
if (preg_match("@^get_([a-z]+)_all$@i",$sNameUnderscore,$aMatch) ||
preg_match("@^get_([a-z]+)_items_all$@i",$sNameUnderscore,$aMatch)
) {
$aFilter=array();
if (isset($aArgs[0]) and is_array($aArgs[0])) {
$aFilter=$aArgs[0];