/** * Join ::= left [JoinType] 'JOIN' right 'ON' JoinCondition * // If JoinType is omitted INNER is assumed. * left ::= Source * right ::= Source * * JoinType ::= Inner | LeftOuter | RightOuter * Inner ::= 'INNER' * LeftOuter ::= 'LEFT OUTER' * RightOuter ::= 'RIGHT OUTER' * * @param QOM\JoinInterface $join * @return string */ protected function convertJoin(QOM\JoinInterface $join) { $left = $this->convertSource($join->getLeft()); $right = $this->convertSource($join->getRight()); $condition = $this->convertJoinCondition($join->getJoinCondition()); return $this->generator->evalJoin($left, $right, $condition, $this->generator->evalJoinType($join->getJoinType())); }
/** * @param QOM\SelectorInterface|QOM\JoinInterface $left * @param QOM\SelectorInterface $right * @param QOM\JoinConditionInterface $condition * * @return string * * @throws NotImplementedException if a SameNodeJoinCondtion is used. */ public function walkJoinCondition($left, QOM\SelectorInterface $right, QOM\JoinConditionInterface $condition) { if ($condition instanceof QOM\ChildNodeJoinConditionInterface) { return $this->walkChildNodeJoinCondition($condition); } if ($condition instanceof QOM\DescendantNodeJoinConditionInterface) { return $this->walkDescendantNodeJoinCondition($condition); } if ($condition instanceof QOM\EquiJoinConditionInterface) { if ($left instanceof QOM\SelectorInterface) { $selectorName = $left->getSelectorName(); } else { $selectorName = $this->getRightJoinSelector($left->getJoinCondition()); } return $this->walkEquiJoinCondition($selectorName, $right->getSelectorName(), $condition); } if ($condition instanceof QOM\SameNodeJoinConditionInterface) { throw new NotImplementedException("SameNodeJoinCondtion"); } }
/** * @param QOM\JoinInterface $source * * @return string * * @throws NotImplementedException */ public function walkJoinSource(QOM\JoinInterface $source) { if (!$source->getLeft() instanceof QOM\SelectorInterface || !$source->getRight() instanceof QOM\SelectorInterface) { throw new NotImplementedException("Join with Joins"); } $this->source = $source->getLeft(); $leftAlias = $this->getTableAlias($source->getLeft()->getSelectorName()); $sql = "FROM phpcr_nodes {$leftAlias} "; $rightAlias = $this->getTableAlias($source->getRight()->getSelectorName()); $nodeTypeClause = $this->sqlNodeTypeClause($rightAlias, $source->getRight()); switch ($source->getJoinType()) { case QOM\QueryObjectModelConstantsInterface::JCR_JOIN_TYPE_INNER: $sql .= "INNER JOIN phpcr_nodes {$rightAlias} "; break; case QOM\QueryObjectModelConstantsInterface::JCR_JOIN_TYPE_LEFT_OUTER: $sql .= "LEFT JOIN phpcr_nodes {$rightAlias} "; break; case QOM\QueryObjectModelConstantsInterface::JCR_JOIN_TYPE_RIGHT_OUTER: $sql .= "RIGHT JOIN phpcr_nodes {$rightAlias} "; break; } $sql .= "ON ( {$leftAlias}.workspace_name = {$rightAlias}.workspace_name AND {$nodeTypeClause} "; $sql .= "AND " . $this->walkJoinCondition($source->getLeft(), $source->getRight(), $source->getJoinCondition()) . " "; $sql .= ") "; // close on-clause $sql .= "WHERE {$leftAlias}.workspace_name = ? AND {$leftAlias}.type IN ('" . $source->getLeft()->getNodeTypeName() . "'"; $subTypes = $this->nodeTypeManager->getSubtypes($source->getLeft()->getNodeTypeName()); foreach ($subTypes as $subType) { /* @var $subType \PHPCR\NodeType\NodeTypeInterface */ $sql .= ", '" . $subType->getName() . "'"; } $sql .= ')'; return $sql; }