/**
  * @param            $rootTable
  * @param Relation[] $joinedTables
  * @throws NoSuchTableException
  */
 public function validateJoins($rootTable, array $joinedTables)
 {
     $relations = $this->mapper->getRelations($rootTable);
     $count = 0;
     foreach ($joinedTables as $join) {
         foreach ($relations as $relation) {
             if ($relation->target == $join->target) {
                 $count++;
                 break;
             }
         }
     }
     if (count($joinedTables) !== $count) {
         throw new NoSuchTableException(sprintf('There are invalid joins (at least %d)', count($joinedTables) - $count));
     }
 }
 /**
  * Search by a specific pattern
  *
  * @param SearchContainer $searchContainer
  * @return SearchContainer
  * @throws MissingParameterException
  * @throws NoSuchColumnException
  * @throws NoSuchTableException
  * @throws NoPrimaryKeyFoundException
  */
 public function buildSearchContainer(SearchContainer $searchContainer)
 {
     $this->tableIndexes = [];
     $this->repository->hasTable($searchContainer->getRootTable());
     // add primary key
     $searchContainer->primaryKey = $this->repository->getPrimaryKeyOfTable($searchContainer->getRootTable());
     // validate target table
     if ($searchContainer->targetTable === null) {
         $searchContainer->targetTable = $searchContainer->getRootTable();
     }
     $this->repository->hasTable($searchContainer->targetTable);
     // validate joins
     if (count($searchContainer->getJoinedTables()) == 0) {
         $relations = $this->repository->getRecursiveRelations($searchContainer->getRootTable());
         foreach ($relations as $join) {
             $searchContainer->addJoin($join);
         }
     } else {
         $this->repository->completeJoins($searchContainer->getRootTable(), $searchContainer->getJoinedTables());
     }
     // validate previous search id
     if ($searchContainer->getSearchId() !== null) {
         $searchContainer->addJoin(new Relation($searchContainer->getRootTable(), 'search_result', $searchContainer->primaryKey, 'primary_key'));
     }
     // validate fields
     if ($searchContainer->getLookupFields() === null) {
         // add root table fields
         $fields = $this->repository->getFields($searchContainer->getRootTable());
         foreach ($fields as $field) {
             $searchContainer->addLookup($field);
         }
         // add fields of joined tables
         foreach ($searchContainer->getJoinedTables() as $join) {
             $this->repository->hasTable($join->target);
             foreach ($this->repository->getFields($join->target, $join->alias) as $field) {
                 $searchContainer->addLookup($field);
             }
         }
     } else {
         $this->validator->validateFields($searchContainer->getRootTable(), $searchContainer->getLookupFields());
         foreach ($searchContainer->getLookupFields() as $lookupField) {
             foreach ($searchContainer->getJoinedTables() as $joinedTable) {
                 if ($lookupField->table == $joinedTable->target && $lookupField->table !== $searchContainer->getRootTable()) {
                     $lookupField->table = $joinedTable->alias;
                 }
             }
         }
     }
     return $searchContainer;
 }