diff --git a/engine/classes/EntityORM.class.php b/engine/classes/EntityORM.class.php index 4b042dc1..57020652 100644 --- a/engine/classes/EntityORM.class.php +++ b/engine/classes/EntityORM.class.php @@ -60,7 +60,7 @@ abstract class EntityORM extends Entity { * * @var unknown_type */ - protected $sPrimaryKey='id'; + protected $sPrimaryKey=null; /** * Флаг новая или нет сущность * @@ -77,15 +77,16 @@ abstract class EntityORM extends Entity { /** * Получение primary key из схемы таблицы * - * @return unknown + * @return string | array */ public function _getPrimaryKey() { - if(!$this->_getDataOne($this->sPrimaryKey)) { - if($this->_getFields()) { - if(array_key_exists('#primary_key',$this->aFields)) { - $this->sPrimaryKey = $this->aFields['#primary_key']; + if(!$this->sPrimaryKey) { + if ($aIndex=$this->ShowPrimaryIndex()) { + if (count($aIndex)>1) { + // Составной индекс + $this->sPrimaryKey=$aIndex; } else { - $this->sPrimaryKey = $this->_getField($this->sPrimaryKey,2); + $this->sPrimaryKey=$aIndex[1]; } } } @@ -193,6 +194,15 @@ abstract class EntityORM extends Entity { return $this->_Method(__FUNCTION__ .'From'); } + /** + * Primary индекс сущности + * + * @return unknown + */ + public function ShowPrimaryIndex() { + return $this->_Method(__FUNCTION__ .'From'); + } + /** * Хук, срабатывает перед сохранением сущности * @@ -515,7 +525,7 @@ abstract class EntityORM extends Entity { $sRelEntityName=Engine::GetEntityName($sEntityRel); $sRelPluginPrefix=Engine::GetPluginPrefix($sEntityRel); $sRelPrimaryKey='id'; - if($oRelEntity=Engine::GetEntity($sEntityRel) and method_exists($oRelEntity,'_getPrimaryKey')) { // для совместимости с сущностями Entity + if($oRelEntity=Engine::GetEntity($sEntityRel)) { $sRelPrimaryKey=$oRelEntity->_getPrimaryKey(); } @@ -558,10 +568,10 @@ abstract class EntityORM extends Entity { // Сохраняем данные только в случае "чистой" выборки if(!$bUseFilter) { $this->aRelationsData[$sKey]=$res; - // Создаём объекты-обёртки для связей MANY_TO_MANY - if ($sRelationType == self::RELATION_TYPE_MANY_TO_MANY) { - $this->_aManyToManyRelations[$sKey] = new LS_ManyToManyRelation($this->aRelationsData[$sKey]); - } + } + // Создаём объекты-обёртки для связей MANY_TO_MANY + if ($sRelationType == self::RELATION_TYPE_MANY_TO_MANY) { + $this->_aManyToManyRelations[$sKey] = new LS_ManyToManyRelation($res); } return $res; } diff --git a/engine/classes/MapperORM.class.php b/engine/classes/MapperORM.class.php index d17da011..15fc70b6 100644 --- a/engine/classes/MapperORM.class.php +++ b/engine/classes/MapperORM.class.php @@ -42,11 +42,18 @@ class MapperORM extends Mapper { */ public function UpdateEntity($oEntity) { $sTableName = self::GetTableName($oEntity); - $iPrimaryKeyValue=$oEntity->_getDataOne($oEntity->_getPrimaryKey()); - - if(!empty($iPrimaryKeyValue)) { - $sql = "UPDATE ".$sTableName." SET ?a WHERE ".$oEntity->_getPrimaryKey()." = ? "; - return $this->oDb->query($sql,$oEntity->_getData(),$iPrimaryKeyValue); + + 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}"; + return $this->oDb->query($sql,$oEntity->_getData()); } else { $aOriginalData = $oEntity->_getOriginalData(); $sWhere = implode(' AND ',array_map(create_function( @@ -66,11 +73,18 @@ class MapperORM extends Mapper { */ public function DeleteEntity($oEntity) { $sTableName = self::GetTableName($oEntity); - $iPrimaryKeyValue=$oEntity->_getDataOne($oEntity->_getPrimaryKey()); - if(!empty($iPrimaryKeyValue)) { - $sql = "DELETE FROM ".$sTableName." WHERE ".$oEntity->_getPrimaryKey()." = ? "; - return $this->oDb->query($sql,$iPrimaryKeyValue); + 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); } else { $aOriginalData = $oEntity->_getOriginalData(); $sWhere = implode(' AND ',array_map(create_function( @@ -341,6 +355,39 @@ class MapperORM extends Mapper { return $aItems; } + /** + * Primary индекс сущности + * + * @param unknown_type $oEntity + * @return unknown + */ + public function ShowPrimaryIndexFrom($oEntity) { + $sTableName = self::GetTableName($oEntity); + return $this->ShowPrimaryIndexFromTable($sTableName); + } + + /** + * Primary индекс таблицы + * + * @param unknown_type $sTableName + * @return unknown + */ + 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; + } + /** * Возвращает имя таблицы для сущности * diff --git a/engine/classes/ModuleORM.class.php b/engine/classes/ModuleORM.class.php index 1a4144ac..9f1881ce 100644 --- a/engine/classes/ModuleORM.class.php +++ b/engine/classes/ModuleORM.class.php @@ -172,6 +172,17 @@ abstract class ModuleORM extends Module { return $res; } + /** + * Primary индекс сущности + * + * @param unknown_type $oEntity + * @return unknown + */ + protected function _ShowPrimaryIndexFrom($oEntity) { + $res=$this->oMapperORM->ShowPrimaryIndexFrom($oEntity); + return $res; + } + /** * Для сущности со связью RELATION_TYPE_TREE возвращает список прямых потомков * @@ -619,6 +630,10 @@ abstract class ModuleORM extends Module { return $this->_ShowColumnsFrom($aArgs[0]); } + if (preg_match("@^showprimaryindexfrom([\w]+)$@i",$sName,$aMatch)) { + return $this->_ShowPrimaryIndexFrom($aArgs[0]); + } + if (preg_match("@^getchildrenof([\w]+)$@i",$sName,$aMatch)) { return $this->_GetChildrenOfEntity($aArgs[0]); }