protected function assembleConnectedDatasetSourceStatement(DataControllerCallContext $callcontext, ReferenceLink $link, array $columnNames, array $linkExecutionStack = NULL) { $TABLE_ALIAS__LINK = 'l'; $nestedLinkExecutionStack = $linkExecutionStack; $nestedLinkExecutionStack[] = $link; $selectedColumnNames = ReferenceLinkBuilder::selectReferencedColumnNames4ReferenceLink($nestedLinkExecutionStack, $columnNames); $linkTableAliasPrefix = $TABLE_ALIAS__LINK . $link->linkId; $statement = $this->assembleDatasetSourceStatement($callcontext, $link->dataset, $selectedColumnNames); $statement->addTableAliasPrefix($linkTableAliasPrefix); // adding columns which we use to join with parent dataset if (!$link->isRoot()) { foreach ($link->columnNames as $columnName) { $joinColumnAlias = ReferencePathHelper::assembleDatabaseColumnName($this->getMaximumEntityNameLength(), ReferencePathHelper::assembleReference($link->dataset->name, $columnName)); $joinTable = $statement->findColumnTable($columnName); if (!isset($joinTable)) { $joinTable = $statement->tables[0]; } $joinColumn = $joinTable->findColumnByAlias($joinColumnAlias); if (!isset($joinColumn)) { $joinTable->columns[] = new ColumnSection($columnName, $joinColumnAlias); } } } // adding columns which we use to join with nested datasets if (isset($link->nestedLinks)) { foreach ($link->nestedLinks as $nestedLink) { foreach ($nestedLink->parentColumnNames as $parentColumnName) { $parentColumnAlias = ReferencePathHelper::assembleDatabaseColumnName($this->getMaximumEntityNameLength(), ReferencePathHelper::assembleReference($link->dataset->name, $parentColumnName)); $joinTable = $statement->getColumnTable($parentColumnName); $joinColumn = $joinTable->findColumnByAlias($parentColumnAlias); if (!isset($joinColumn)) { $joinTable->columns[] = new ColumnSection($parentColumnName, $parentColumnAlias); } } } } // collecting columns which we need to mark as invisible $shouldBeInvisibleColumns = NULL; foreach ($statement->tables as $table) { if (isset($table->columns)) { foreach ($table->columns as $column) { $shouldBeInvisibleColumns[$table->alias][$column->alias] = $column; } } else { $table->columns = array(); // We do not need any columns } } // adding or making as visible columns which we need to return if (isset($selectedColumnNames)) { foreach ($selectedColumnNames as $originalColumnName => $selectedColumnName) { // we need to show only those columns which are requested. // All intermediate columns (which are used to link with nested datasets) will not be shown if (array_search($originalColumnName, $columnNames) !== FALSE) { $databaseColumnName = ReferencePathHelper::assembleDatabaseColumnName($this->getMaximumEntityNameLength(), $originalColumnName); $table = $statement->getColumnTable($selectedColumnName, TRUE); $column = $table->findColumnByAlias($databaseColumnName); if (isset($column)) { $column->visible = TRUE; unset($shouldBeInvisibleColumns[$table->alias][$column->alias]); } else { $column = $table->findColumnByAlias($selectedColumnName); if (isset($column)) { // adding clone of the same column with another alias $column = clone $column; $column->visible = TRUE; $column->alias = $databaseColumnName; } else { $column = new ColumnSection($selectedColumnName, $databaseColumnName); } $table->columns[] = $column; } $callcontext->columnMapping[$databaseColumnName] = $originalColumnName; } } } if (isset($shouldBeInvisibleColumns)) { foreach ($shouldBeInvisibleColumns as $tableColumns) { foreach ($tableColumns as $column) { $column->visible = FALSE; } } } // supporting nested links if (isset($link->nestedLinks)) { foreach ($link->nestedLinks as $nestedLink) { $nestedStatement = $this->assembleConnectedDatasetSourceStatement($callcontext, $nestedLink, $columnNames, $nestedLinkExecutionStack); foreach ($nestedLink->parentColumnNames as $referencePointColumnIndex => $parentColumnName) { // preparing parent table alias $parentColumnAlias = ReferencePathHelper::assembleDatabaseColumnName($this->getMaximumEntityNameLength(), ReferencePathHelper::assembleReference($link->dataset->name, $parentColumnName)); $parentTableAlias = $statement->getColumnTable($parentColumnAlias)->alias; // linking with parent $nestedColumnName = $nestedLink->columnNames[$referencePointColumnIndex]; $nestedColumnAlias = ReferencePathHelper::assembleDatabaseColumnName($this->getMaximumEntityNameLength(), ReferencePathHelper::assembleReference($nestedLink->dataset->name, $nestedColumnName)); $nestedStatement->getColumnTable($nestedColumnAlias)->conditions[] = new JoinConditionSection($nestedColumnName, new TableColumnConditionSectionValue($parentTableAlias, $parentColumnName)); } $statement->merge($nestedStatement); } } return $statement; }
protected function detectRoutes(ReferenceLink $rootLink, array $referencePaths) { $routeId = 0; foreach ($referencePaths as $referencePath => $required) { // preparing possible routes $referenceRoutes = $rootLink->prepareRoutes($referencePath); // selecting 'the best' route $selectedRoute = NULL; if (isset($referenceRoutes)) { foreach ($referenceRoutes as $directReferenceFlag => $routes) { foreach ($routes as $route) { if (!isset($selectedRoute) || ($selectedRoute->weight > $route->weight)) { $selectedRoute = $route; } } } } if (isset($selectedRoute)) { $rootLink->assignRouteId($selectedRoute, $routeId); $routeId++; } elseif ($required) { $metamodel = data_controller_get_metamodel(); LogHelper::log_error(t('Could not execute reference path: @referencePath', array('@referencePath' => $referencePath))); list($referencedDatasetName) = ReferencePathHelper::splitReference($referencePath); $referencedDataset = $metamodel->getDataset($referencedDatasetName); throw new IllegalArgumentException(t( '%datasetNameA and %datasetNameB datasets are not connected', array('%datasetNameA' => $rootLink->dataset->publicName, '%datasetNameB' => $referencedDataset->publicName))); } } }