/** * Transforms a Query Source into SQL and parameter arrays * * @param SourceInterface $source The source * @param array &$sql * @return void */ protected function parseSource(SourceInterface $source, array &$sql) { if ($source instanceof SelectorInterface) { $tableName = $source->getNodeTypeName(); $sql['fields'][$tableName] = $tableName . '.*'; $sql['tables'][$tableName] = $tableName; if ($this->query->getDistinct()) { $sql['fields'][$tableName] = $tableName . '.' . $this->query->getDistinct(); $sql['keywords']['distinct'] = 'DISTINCT'; } } elseif ($source instanceof JoinInterface) { $this->parseJoin($source, $sql); } }
/** * Transforms orderings into SQL. * * @param array $orderings An array of orderings (Qom\Ordering) * @param Qom\SourceInterface $source The source * @param array &$sql The query parts * @throws \TYPO3\CMS\Extbase\Persistence\Generic\Exception\UnsupportedOrderException * @return void */ protected function parseOrderings(array $orderings, Qom\SourceInterface $source, array &$sql) { foreach ($orderings as $propertyName => $order) { switch ($order) { case Qom\QueryObjectModelConstantsInterface::JCR_ORDER_ASCENDING: case QueryInterface::ORDER_ASCENDING: $order = 'ASC'; break; case Qom\QueryObjectModelConstantsInterface::JCR_ORDER_DESCENDING: case QueryInterface::ORDER_DESCENDING: $order = 'DESC'; break; default: throw new \TYPO3\CMS\Extbase\Persistence\Generic\Exception\UnsupportedOrderException('Unsupported order encountered.', 1242816074); } $className = ''; $tableName = ''; if ($source instanceof Qom\SelectorInterface) { $className = $source->getNodeTypeName(); $tableName = $this->dataMapper->convertClassNameToTableName($className); while (strpos($propertyName, '.') !== FALSE) { $this->addUnionStatement($className, $tableName, $propertyName, $sql); } } elseif ($source instanceof Qom\JoinInterface) { $tableName = $source->getLeft()->getSelectorName(); } $columnName = $this->dataMapper->convertPropertyNameToColumnName($propertyName, $className); if ($tableName !== '') { $sql['orderings'][] = $tableName . '.' . $columnName . ' ' . $order; } else { $sql['orderings'][] = $columnName . ' ' . $order; } } }
/** * Parse a Comparison into SQL and parameter arrays. * * @param Qom\ComparisonInterface $comparison The comparison to parse * @param Qom\SourceInterface $source The source * @throws \RuntimeException * @throws \TYPO3\CMS\Extbase\Persistence\Generic\Exception\RepositoryException * @return string */ protected function parseComparison(Qom\ComparisonInterface $comparison, Qom\SourceInterface $source) { if ($comparison->getOperator() === QueryInterface::OPERATOR_CONTAINS) { if ($comparison->getOperand2() === null) { return '1<>1'; } else { $value = $this->dataMapper->getPlainValue($comparison->getOperand2()); if (!$source instanceof Qom\SelectorInterface) { throw new \RuntimeException('Source is not of type "SelectorInterface"', 1395362539); } $className = $source->getNodeTypeName(); $tableName = $this->dataMapper->convertClassNameToTableName($className); $operand1 = $comparison->getOperand1(); $propertyName = $operand1->getPropertyName(); $fullPropertyPath = ''; while (strpos($propertyName, '.') !== false) { $this->addUnionStatement($className, $tableName, $propertyName, $fullPropertyPath); } $columnName = $this->dataMapper->convertPropertyNameToColumnName($propertyName, $className); $dataMap = $this->dataMapper->getDataMap($className); $columnMap = $dataMap->getColumnMap($propertyName); $typeOfRelation = $columnMap instanceof ColumnMap ? $columnMap->getTypeOfRelation() : null; if ($typeOfRelation === ColumnMap::RELATION_HAS_AND_BELONGS_TO_MANY) { $relationTableName = $columnMap->getRelationTableName(); $queryBuilderForSubselect = $this->queryBuilder->getConnection()->createQueryBuilder(); $queryBuilderForSubselect->select($columnMap->getParentKeyFieldName())->from($relationTableName)->where($queryBuilderForSubselect->expr()->eq($columnMap->getChildKeyFieldName(), $this->queryBuilder->createNamedParameter($value))); $additionalWhereForMatchFields = $this->getAdditionalMatchFieldsStatement($queryBuilderForSubselect->expr(), $columnMap, $relationTableName, $relationTableName); if ($additionalWhereForMatchFields) { $queryBuilderForSubselect->andWhere($additionalWhereForMatchFields); } return $this->queryBuilder->expr()->comparison($this->queryBuilder->quoteIdentifier($tableName . '.uid'), 'IN', '(' . $queryBuilderForSubselect->getSQL() . ')'); } elseif ($typeOfRelation === ColumnMap::RELATION_HAS_MANY) { $parentKeyFieldName = $columnMap->getParentKeyFieldName(); if (isset($parentKeyFieldName)) { $childTableName = $columnMap->getChildTableName(); // Build the SQL statement of the subselect $queryBuilderForSubselect = $this->queryBuilder->getConnection()->createQueryBuilder(); $queryBuilderForSubselect->select($parentKeyFieldName)->from($childTableName)->where($queryBuilderForSubselect->expr()->eq('uid', (int) $value)); // Add it to the main query return $this->queryBuilder->expr()->eq($tableName . '.uid', $queryBuilderForSubselect->getSQL()); } else { return $this->queryBuilder->expr()->inSet($tableName . '.' . $columnName, $this->queryBuilder->createNamedParameter($value)); } } else { throw new \TYPO3\CMS\Extbase\Persistence\Generic\Exception\RepositoryException('Unsupported or non-existing property name "' . $propertyName . '" used in relation matching.', 1327065745); } } } else { return $this->parseDynamicOperand($comparison, $source); } }