public function updateTableAlias(ParserCallback $callback, &$callerSession) {
        list($tableAlias, $columnName) = ColumnNameHelper::splitColumnName($callback->marker);

        $updateAllowed = FALSE;
        if (isset($tableAlias)) {
            if (isset($this->oldTableAlias) && ($tableAlias === $this->oldTableAlias)) {
                $updateAllowed = TRUE;
            }
        }
        elseif (!isset($this->oldTableAlias)) {
            $updateAllowed = TRUE;
        }

        if ($updateAllowed) {
            $callback->marker = ColumnNameHelper::combineColumnName($this->newTableAlias, $columnName);
        }

        $this->adjustCallbackObject($callback, $callerSession);
    }
Example #2
0
 public function assembleColumnName($tableAlias)
 {
     $selectedTableAlias = $this->tableAlias;
     if (isset($selectedTableAlias)) {
         if (isset($tableAlias) && $selectedTableAlias != $tableAlias) {
             throw new UnsupportedOperationException();
         }
     } else {
         $this->tableAlias = $tableAlias;
         $selectedTableAlias = $tableAlias;
     }
     return ColumnNameHelper::combineColumnName($selectedTableAlias, $this->name);
 }
    public function assembleColumnName($tableAlias) {
        $selectedTableAlias = $this->tableAlias;

        if (isset($selectedTableAlias)) {
            if (isset($tableAlias) && ($selectedTableAlias != $tableAlias)) {
                throw new UnsupportedOperationException();
            }
        }
        else {
            $this->tableAlias = $tableAlias;
            $selectedTableAlias = $tableAlias;
        }

        list(, $columnName) = ReferencePathHelper::splitReference($this->name);

        return ColumnNameHelper::combineColumnName($selectedTableAlias, $columnName);
    }
    public function prepareSections(array $requestedColumnNames = NULL) {
        $retrieveAllColumns = !isset($requestedColumnNames);

        $tableCount = count($this->tables);
        if ($tableCount === 0) {
            throw new IllegalStateException(t('Tables have not been defined for this statement'));
        }

        if ($tableCount === 1) {
            $table = $this->tables[0];
            if ($table instanceof SubquerySection) {
                if (!isset($table->columns) && !isset($this->conditions) && !isset($this->groupByColumns) && !isset($this->havingConditions)) {
                    return array(TRUE, new AssembledSections(NULL, $table->body, NULL, NULL, NULL));
                }
            }
        }

        // we need to find each column in order to avoid using sub select
        $isColumnAccessible = TRUE;

        $columnNameUsage = NULL;
        if (!$retrieveAllColumns) {
            // preparing tables which support each requested column
            foreach ($requestedColumnNames as $columnName) {
                $columnNameUsage[$columnName] = array();
            }

            // preparing tables which support 'where' subject columns for which we did not select table alias
            if (isset($this->conditions)) {
                foreach ($this->conditions as $condition) {
                    if (!isset($condition->subjectTableAlias)) {
                        $columnNameUsage[(($condition instanceof AbstractConditionSection) ? $condition->subjectColumnName : NULL)] = array();
                    }
                }
            }
        }

        // if the statement contains just one table we do not need to worry about columns
        if (!$retrieveAllColumns) {
            if (($tableCount === 1) && (($table = $this->tables[0]) instanceof TableSection)) {
                if (isset($columnNameUsage)) {
                    foreach ($columnNameUsage as &$usage) {
                        $usage[] = $table;
                    }
                    unset($usage);
                }
            }
            else {
                // calculating how many tables support each column
                for ($i = 0; ($i < $tableCount) && $isColumnAccessible; $i++) {
                    $table = $this->tables[$i];
                    if (isset($table->columns)) {
                        foreach ($table->columns as $column) {
                            if (isset($columnNameUsage[$column->alias])) {
                                $columnNameUsage[$column->alias][] = $table;
                            }
                        }
                    }
                    else {
                        if ($table instanceof TableSection) {
                            // list of columns is not provided for the table
                            // I hope that is because the table is just transitioning table to access data from other table
                            // I do not want to use $isColumnAccessible = FALSE until we have a use case
                        }
                        else {
                            // there is no access to columns for this type of table
                            $isColumnAccessible = FALSE;
                        }
                    }
                }

                // checking how many tables support each column
                if (isset($columnNameUsage)) {
                    foreach ($columnNameUsage as $sourceTables) {
                        if (count($sourceTables) !== 1) {
                            $isColumnAccessible = FALSE;
                            break;
                        }
                    }
                }
            }
        }

        $useTableNameAsAlias = $tableCount > 1;

        $indentSectionElement = str_pad('', SelectStatementPrint::INDENT__SECTION_ELEMENT);

        $indexedSelect = $unindexedSelect = NULL;
        if ($isColumnAccessible && !$retrieveAllColumns) {
            // all columns are linked to corresponding tables
            foreach ($requestedColumnNames as $columnName) {
                $sourceTable = $columnNameUsage[$columnName][0];
                $column = $sourceTable->findColumnByAlias($columnName);
                if (isset($column) && !$column->visible) {
                    continue;
                }

                $columnTableAlias = $sourceTable->prepareColumnTableAlias($useTableNameAsAlias);

                // if there is no such columns we return just requested column name
                if (isset($column)) {
                    $assembledColumn = $column->assemble($columnTableAlias);
                    if (isset($column->requestColumnIndex)) {
                        $indexedSelect[$column->requestColumnIndex][] = $assembledColumn;
                    }
                    else {
                        $unindexedSelect[] = $assembledColumn;
                    }
                }
                else {
                    $unindexedSelect[] = ColumnNameHelper::combineColumnName($columnTableAlias, $columnName);
                }
            }
        }
        else {
            foreach ($this->tables as $table) {
                // we ignore a table which provides list of columns but the list is empty
                if (isset($table->columns) && (count($table->columns) === 0)) {
                    continue;
                }

                $columnTableAlias = $table->prepareColumnTableAlias($useTableNameAsAlias);
                if (isset($table->columns)) {
                    // returning only columns which are configured for the table
                    foreach ($table->columns as $column) {
                        if (!$column->visible) {
                            continue;
                        }

                        $assembledColumn = $column->assemble($columnTableAlias);
                        if (isset($column->requestColumnIndex)) {
                            $indexedSelect[$column->requestColumnIndex][] = $assembledColumn;
                        }
                        else {
                            $unindexedSelect[] = $assembledColumn;
                        }
                    }
                }
                else {
                    // returning all columns from the table
                    $unindexedSelect[] = ColumnNameHelper::combineColumnName($columnTableAlias, '*');
                }
            }
        }
        // sorting select columns by request column index. If the index is not provided, corresponding column is placed at the end of the list
        $sortedSelect = array();
        if (isset($indexedSelect)) {
            ksort($indexedSelect);
            foreach ($indexedSelect as $assembledColumns) {
                $sortedSelect = array_merge($sortedSelect, $assembledColumns);
            }
        }
        if (isset($unindexedSelect)) {
            $sortedSelect= array_merge($sortedSelect, $unindexedSelect);
        }
        $select = (count($sortedSelect) > 0) ? implode(",\n$indentSectionElement", $sortedSelect) : NULL;

        $from = NULL;
        for ($i = 0; $i < $tableCount; $i++) {
            $table = $this->tables[$i];
            if ($i > 0) {
                $from .= "\n" . $indentSectionElement . 'LEFT OUTER JOIN ';
            }
            $from .= $table->assemble();
            // assembling join conditions
            if ($i === 0) {
                if (isset($table->conditions)) {
                    throw new IllegalStateException(t('Join conditions should not be defined for %tableName table', array('%tableName' => $table->name)));
                }
            }
            else {
                if (isset($table->conditions)) {
                    $from .= ' ON ';
                    for ($j = 0, $c = count($table->conditions); $j < $c; $j++) {
                        $condition = $table->conditions[$j];
                        if ($j > 0) {
                            $from .= ' AND ';
                        }

                        $from .= $condition->assemble($this, $table, $useTableNameAsAlias);
                    }
                }
                else {
                    throw new IllegalStateException(t('Join conditions were not defined for %tableName table', array('%tableName' => $table->name)));
                }
            }
        }

        $where = NULL;
        if (isset($this->conditions)) {
            foreach ($this->conditions as $condition) {
                if (isset($where)) {
                    $where .= "\n   AND ";
                }

                if (isset($condition->subjectTableAlias)) {
                    $subjectTable = $this->getTable($condition->subjectTableAlias);
                }
                else {
                    // We do not have table alias
                    // Solution: find a column in a table and use the table alias and the column name to generate the condition
                    if (isset($columnNameUsage)) {
                        $sourceTables = $columnNameUsage[(($condition instanceof AbstractConditionSection) ? $condition->subjectColumnName : NULL)];
                        $subjectTable = (count($sourceTables) === 1) ? $sourceTables[0] : NULL;
                    }
                    else {
                        $subjectTable = $this->findColumnTable($condition->subjectColumnName);
                    }
                    if (!isset($subjectTable)) {
                        throw new IllegalStateException(t(
                        	'Condition for %columnName column cannot be prepared',
                            array('%columnName' => $condition->subjectColumnName)));
                    }
                }

                $where .= $condition->assemble($this, $subjectTable, $useTableNameAsAlias);
            }
        }

        $groupBy = NULL;
        if (isset($this->groupByColumns)) {
            foreach ($this->groupByColumns as $groupByColumn) {
                if (isset($groupBy)) {
                    $groupBy .= ', ';
                }
                $groupBy .= $groupByColumn->assemble(NULL);
            }
        }

        $having = NULL;
        if (isset($this->havingConditions)) {
            foreach ($this->havingConditions as $havingCondition) {
                if (isset($having)) {
                    $having .= "\n   AND ";
                }
                $having .= $havingCondition->assemble($this, FALSE);
            }
        }

        $isSubqueryRequired = !$isColumnAccessible;

        return array($isSubqueryRequired, new AssembledSections($select, $from, $where, $groupBy, $having));
    }
    public function assemble(Statement $statement, AbstractTableSection $table, $useTableNameAsAlias) {
        list($referencedDatasetName, $referencedColumnName) = ReferencePathHelper::splitReference($this->subjectColumnName);

        $columnByAlias = $table->findColumnByAlias($referencedColumnName);
        $column = isset($columnByAlias) ? $table->findColumn($referencedColumnName) : NULL;

        $selectedColumn = isset($columnByAlias) && isset($column)
            ? $column
            : $columnByAlias;

        $tableAlias = $table->prepareColumnTableAlias($useTableNameAsAlias);

        return
            (isset($selectedColumn) ? $selectedColumn->assembleColumnName($tableAlias) : ColumnNameHelper::combineColumnName($tableAlias, $referencedColumnName))
                . $this->joinValue->assemble($statement, $useTableNameAsAlias);
    }