/**
  * Funkce pro aktualizaci info o atributech v DB
  * @param Metasource &$metasource
  * @param User $user
  */
 public function updateMetasourceAttributes(Metasource &$metasource, User $user)
 {
     /** @var IPreprocessing $preprocessing */
     $preprocessing = $this->preprocessingFactory->getPreprocessingInstance($metasource->getPpConnection(), $user);
     $ppDataset = $preprocessing->getPpDataset($metasource->ppDatasetId ? $metasource->ppDatasetId : $metasource->name);
     $datasource = $metasource->datasource;
     $metasource->size = $ppDataset->size;
     $ppAttributes = $preprocessing->getPpAttributes($ppDataset);
     #region připravení seznamu aktuálně existujících datasourceColumns
     /** @var Attribute[] $existingAttributesByPpDatasetAttributeId */
     $existingAttributesByPpDatasetAttributeId = [];
     /** @var Attribute[] $existingAttributesByName */
     $existingAttributesByName = [];
     /** @var Attribute[] $attributes */
     $attributes = $metasource->attributes;
     if (!empty($attributes)) {
         foreach ($attributes as &$attribute) {
             if (!empty($attribute->ppDatasetAttributeId)) {
                 $existingAttributesByPpDatasetAttributeId[$attribute->ppDatasetAttributeId] = $attribute;
             } else {
                 $existingAttributesByName[$attribute->name] = $attribute;
             }
         }
     }
     #endregion
     #region aktualizace seznamu sloupců získaných z DB
     if (!empty($ppAttributes)) {
         foreach ($ppAttributes as $ppAttribute) {
             if (!empty($ppAttribute->id) && is_int($ppAttribute->id) && isset($existingAttributesByPpDatasetAttributeId[$ppAttribute->id])) {
                 //sloupec s daným ID již je v databázi
                 $attribute = $existingAttributesByPpDatasetAttributeId[$ppAttribute->id];
                 $modified = false;
                 if ($attribute->name != $ppAttribute->name) {
                     $attribute->name = $ppAttribute->name;
                     $modified = true;
                 }
                 if (!$attribute->active) {
                     $modified = true;
                     $attribute->active = true;
                 }
                 if ($modified) {
                     $this->saveAttribute($attribute);
                 }
                 unset($existingAttributesByPpDatasetAttributeId[$ppAttribute->id]);
             } elseif (!empty($ppAttribute->name) && isset($existingAttributesByName[$ppAttribute->name])) {
                 //sloupec najdeme podle jména
                 $attribute = $existingAttributesByName[$ppAttribute->name];
                 if (!empty($ppAttribute->id) && $attribute->ppDatasetAttributeId != $ppAttribute->id) {
                     $attribute->ppDatasetAttributeId = $ppAttribute->id;
                     $attribute->active = true;
                     $this->saveAttribute($attribute);
                 } elseif (!$attribute->active) {
                     $attribute->active = true;
                     $this->saveAttribute($attribute);
                 }
                 unset($existingAttributesByName[$ppAttribute->name]);
             } elseif (!empty($ppAttribute->field)) {
                 //máme tu nový datový sloupec (který má svoji vazbu na datasource)
                 $attribute = new Attribute();
                 $attribute->metasource = $metasource;
                 try {
                     $datasourceColumn = $this->datasourcesFacade->findDatasourceColumnByDbDatasourceColumnId($datasource, $ppAttribute->field);
                 } catch (\Exception $e) {
                     $datasourceColumn = null;
                 }
                 $attribute->datasourceColumn = $datasourceColumn;
                 $attribute->name = $ppAttribute->name;
                 if (is_int($ppAttribute->id)) {
                     $attribute->ppDatasetAttributeId = $ppAttribute->id;
                 }
                 $attribute->active = true;
                 $attribute->type = $ppAttribute->type;
                 $this->saveAttribute($attribute);
             }
         }
     }
     #endregion
     #region deaktivace již neexistujících sloupců
     //TODO kontrola, jestli je není možné kompletně smazat (pokud ještě nebyly dovytvořeny v rámci preprocessingu)
     if (!empty($existingAttributesByPpDatasetAttributeId)) {
         foreach ($existingAttributesByPpDatasetAttributeId as &$attribute) {
             if ($attribute->active) {
                 $attribute->active = false;
                 $this->saveAttribute($attribute);
             }
         }
     }
     if (!empty($existingAttributesByName)) {
         foreach ($existingAttributesByName as &$attribute) {
             if ($attribute->active) {
                 $attribute->active = false;
                 $this->saveAttribute($attribute);
             }
         }
     }
     #endregion
     //aktualizace datového zdroje z DB
     $metasource = $this->findMetasource($metasource->metasourceId);
     #region vyčištění preprocessing úloh
     if (!empty($metasource->metasourceTasks)) {
         $attributesArr = $metasource->getAttributesArr();
         if (!empty($attributesArr)) {
             foreach ($metasource->metasourceTasks as $metasourceTask) {
                 if ($metasourceTask->type == MetasourceTask::TYPE_PREPROCESSING) {
                     if (!empty($metasourceTask->attributes)) {
                         $finished = true;
                         foreach ($metasourceTask->attributes as $taskAttribute) {
                             if (!$taskAttribute->active) {
                                 $finished = false;
                             }
                         }
                         if ($finished) {
                             $this->metasourceTasksRepository->delete($metasourceTask);
                         }
                     }
                 }
             }
         }
     }
     #endregion
 }