*/
protected function setRelations(Tx_Extbase_Persistence_Mapper_ColumnMap &$columnMap, $columnConfiguration) {
if (isset($columnConfiguration) && $columnConfiguration['type'] !== 'passthrough') {
- if (isset($columnConfiguration['foreign_table']) && !isset($columnConfiguration['MM']) && !(isset($columnConfiguration['foreign_label']) || isset($columnConfiguration['foreign_selector']))) {
+ if (isset($columnConfiguration['foreign_table']) && !isset($columnConfiguration['MM']) && !isset($columnConfiguration['foreign_selector'])) {
if ($columnConfiguration['maxitems'] == 1) {
$this->setOneToOneRelation($columnMap, $columnConfiguration);
} else {
$this->setOneToManyRelation($columnMap, $columnConfiguration);
}
- } elseif (isset($columnConfiguration['MM']) || (isset($columnConfiguration['foreign_label']) || isset($columnConfiguration['foreign_selector']))) {
+ } elseif (isset($columnConfiguration['MM']) || isset($columnConfiguration['foreign_selector'])) {
$this->setManyToManyRelation($columnMap, $columnConfiguration);
} else {
$columnMap->setTypeOfRelation(Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_NONE);
*/
protected function setOneToOneRelation(Tx_Extbase_Persistence_Mapper_ColumnMap &$columnMap, $columnConfiguration) {
$columnMap->setTypeOfRelation(Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_ONE);
- $columnMap->setChildClassName($this->determineChildClassName($columnConfiguration));
$columnMap->setChildTableName($columnConfiguration['foreign_table']);
$columnMap->setChildTableWhereStatement($columnConfiguration['foreign_table_where']);
$columnMap->setChildSortbyFieldName($columnConfiguration['foreign_sortby']);
*/
protected function setOneToManyRelation(Tx_Extbase_Persistence_Mapper_ColumnMap &$columnMap, $columnConfiguration) {
$columnMap->setTypeOfRelation(Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_MANY);
- $columnMap->setChildClassName($this->determineChildClassName($columnConfiguration));
$columnMap->setChildTableName($columnConfiguration['foreign_table']);
$columnMap->setChildTableWhereStatement($columnConfiguration['foreign_table_where']);
$columnMap->setChildSortbyFieldName($columnConfiguration['foreign_sortby']);
if ($columnConfiguration['type'] === 'inline') {
$columns = $this->getColumnsDefinition($columnConfiguration['foreign_table']);
$childKeyFieldName = $this->determineChildKeyFieldName($columnConfiguration);
- $columnMap->setChildClassName($this->determineChildClassName($columns[$childKeyFieldName]['config']));
$columnMap->setChildTableName($columns[$childKeyFieldName]['config']['foreign_table']);
$columnMap->setRelationTableName($columnConfiguration['foreign_table']);
$columnMap->setParentKeyFieldName($columnConfiguration['foreign_field']);
$columnMap->setChildKeyFieldName($childKeyFieldName);
$columnMap->setChildSortByFieldName($columnConfiguration['foreign_sortby']);
} else {
- $columnMap->setChildClassName($this->determineChildClassName($columnConfiguration));
$columnMap->setChildTableName($columnConfiguration['foreign_table']);
$columnMap->setChildTableWhereStatement($columnConfiguration['foreign_table_where']);
$columnMap->setRelationTableName($columnConfiguration['MM']);
return $childKeyFieldName;
}
- /**
- * This function determines the child class name. It can either be defined as foreign_class in the column configuration (TCA)
- * or it must be defined in the extbase framework configuration (reverse mapping from tableName to className).
- *
- * @param $columnConfiguration The column configuration (from TCA)
- * @return string The class name of the related child object
- */
- protected function determineChildClassName($columnConfiguration) {
- $foreignClassName = '';
- if (is_string($columnConfiguration['foreign_class']) && (strlen($columnConfiguration['foreign_class']) > 0)) {
- $foreignClassName = $columnConfiguration['foreign_class'];
- }
- if (empty($foreignClassName)){
- $extbaseSettings = Tx_Extbase_Dispatcher::getExtbaseFrameworkConfiguration();
- // TODO Apply a cache to increase performance (profile first)
- if (is_array($extbaseSettings['persistence']['classes'])) {
- foreach ($extbaseSettings['persistence']['classes'] as $className => $classConfiguration) {
- if ($classConfiguration['mapping']['tableName'] === $columnConfiguration['foreign_table']) {
- $foreignClassName = $className;
- break;
- }
- }
- }
- }
- // TODO Throw exception if no appropriate class name was found
- return $foreignClassName;
- }
-
/**
* Sets the column maps.
*
$parentKeyFieldName = $columnMap->getParentKeyFieldName();
$childSortByFieldName = $columnMap->getChildSortByFieldName();
if ($columnMap->getTypeOfRelation() === Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_ONE) {
- $query = $queryFactory->create($this->getType($parentObject, $propertyName));
+ $query = $queryFactory->create($this->getType(get_class($parentObject), $propertyName));
if (isset($parentKeyFieldName)) {
$query->matching($query->equals($parentKeyFieldName, $parentObject->getUid()));
} else {
$query->setSource($source);
if (!empty($childSortByFieldName)) {
- $query->setOrderings(array($relationTableName . '.' . $childSortByFieldName => Tx_Extbase_Persistence_QueryInterface::ORDER_ASCENDING));
+ $query->setOrderings(array($childSortByFieldName => Tx_Extbase_Persistence_QueryInterface::ORDER_ASCENDING));
}
// attempt to support MM_match_fields
/**
* Returns the type of a child object.
*
- * @param Tx_Extbase_DomainObject_DomainObjectInterface $parentObject The object instance this proxy is part of
+ * @param string $parentClassName The class name of the object this proxy is part of
* @param string $propertyName The name of the proxied property in it's parent
* @return string The class name of the child object
*/
- protected function getType(Tx_Extbase_DomainObject_DomainObjectInterface $parentObject, $propertyName) {
- $propertyMetaData = $this->reflectionService->getClassSchema(get_class($parentObject))->getProperty($propertyName);
- $columnMap = $this->getDataMap(get_class($parentObject))->getColumnMap($propertyName);
- $childClassName = $columnMap->getChildClassName();
- if (!empty($childClassName)) {
- $elementType = $childClassName;
- } elseif (!empty($propertyMetaData['type'])) {
- $elementType = $propertyMetaData['type'];
+ public function getType($parentClassName, $propertyName) {
+ $propertyMetaData = $this->reflectionService->getClassSchema($parentClassName)->getProperty($propertyName);
+ if (!empty($propertyMetaData['type'])) {
+ $type = $propertyMetaData['type'];
} else {
throw new Tx_Extbase_Persistence_Exception_UnexpectedTypeException('Could not determine the child object object type.', 1251315967);
}
- return $elementType;
+ return $type;
}
/**
*/
public function getElementType($parentClassName, $propertyName) {
$propertyMetaData = $this->reflectionService->getClassSchema($parentClassName)->getProperty($propertyName);
- $columnMap = $this->getDataMap($parentClassName)->getColumnMap($propertyName);
- $childClassName = $columnMap->getChildClassName();
- if (!empty($childClassName)) {
- $elementType = $childClassName;
- } elseif (!empty($propertyMetaData['elementType'])) {
+ if (!empty($propertyMetaData['elementType'])) {
$elementType = $propertyMetaData['elementType'];
} else {
throw new Tx_Extbase_Persistence_Exception_UnexpectedTypeException('Could not determine the type of the contained objects.', 1251315966);
$this->checkSqlErrors();
$rows = $this->getRowsFromResult($query->getSource(), $result);
$rows = $this->doLanguageAndWorkspaceOverlay($query->getSource(), $rows);
-
- // $objectData = $this->processObjectRecords($statementHandle);
+ // TODO: implement $objectData = $this->processObjectRecords($statementHandle);
return $rows;
}
*/
public function parseQuery(Tx_Extbase_Persistence_QueryInterface $query, array &$parameters) {
$sql = array();
+ $sql['keywords'] = array();
$sql['tables'] = array();
$sql['unions'] = array();
$sql['fields'] = array();
* @return string The SQL statement
*/
public function buildQuery(array $sql) {
- $statement = 'SELECT DISTINCT ' . implode(',', $sql['fields']) . ' FROM ' . implode(' ', $sql['tables']) . ' '. implode(' ', $sql['unions']);
+ $statement = 'SELECT ' . implode(' ', $sql['keywords']) . ' '. implode(',', $sql['fields']) . ' FROM ' . implode(' ', $sql['tables']) . ' '. implode(' ', $sql['unions']);
if (!empty($sql['where'])) {
$statement .= ' WHERE ' . implode('', $sql['where']);
if (!empty($sql['additionalWhereClause'])) {
protected function parseSource(Tx_Extbase_Persistence_QOM_SourceInterface $source, array &$sql) {
if ($source instanceof Tx_Extbase_Persistence_QOM_SelectorInterface) {
$tableName = $source->getSelectorName();
- $sql['fields'][] = $tableName . '.*';
+ $sql['fields'][$tableName] = $tableName . '.*';
$sql['tables'][$tableName] = $tableName;
} elseif ($source instanceof Tx_Extbase_Persistence_QOM_JoinInterface) {
$this->parseJoin($source, $sql);
*/
protected function parseJoin(Tx_Extbase_Persistence_QOM_JoinInterface $join, array &$sql) {
$leftSource = $join->getLeft();
+ $leftClassName = $leftSource->getNodeTypeName();
$leftTableName = $leftSource->getSelectorName();
+ // $sql['fields'][$leftTableName] = $leftTableName . '.*';
$rightSource = $join->getRight();
- $rightTableName = $rightSource->getSelectorName();
-
- $sql['fields'][] = $leftTableName . '.*';
- $sql['fields'][] = $rightTableName . '.*';
-
- // TODO Implement support for different join types and nested joins
+ if ($rightSource instanceof Tx_Extbase_Persistence_QOM_JoinInterface) {
+ $rightClassName = $rightSource->getLeft()->getNodeTypeName();
+ $rightTableName = $rightSource->getLeft()->getSelectorName();
+ } else {
+ $rightClassName = $rightSource->getNodeTypeName();
+ $rightTableName = $rightSource->getSelectorName();
+ $sql['fields'][$leftTableName] = $rightTableName . '.*';
+ }
+
$sql['tables'][$leftTableName] = $leftTableName;
- $sql['unions'][$rightTableName] = 'LEFT JOIN ' . $rightTableName;
+ $sql['unions'][$rightTableName] = 'INNER JOIN ' . $rightTableName;
$joinCondition = $join->getJoinCondition();
- // TODO Check the parsing of the join
if ($joinCondition instanceof Tx_Extbase_Persistence_QOM_EquiJoinCondition) {
- // TODO Discuss, if we should use $leftSource instead of $selector1Name
- $column1Name = $this->dataMapper->convertPropertyNameToColumnName($joinCondition->getProperty1Name(), $leftSource->getNodeTypeName());
- $column2Name = $this->dataMapper->convertPropertyNameToColumnName($joinCondition->getProperty2Name(), $rightSource->getNodeTypeName());
- $sql['unions'][$joinCondition->getSelector2Name()] .= ' ON ' . $joinCondition->getSelector1Name() . '.' . $column1Name . ' = ' . $joinCondition->getSelector2Name() . '.' . $column2Name;
+ $column1Name = $this->dataMapper->convertPropertyNameToColumnName($joinCondition->getProperty1Name(), $leftClassName);
+ $column2Name = $this->dataMapper->convertPropertyNameToColumnName($joinCondition->getProperty2Name(), $rightClassName);
+ $sql['unions'][$rightTableName] .= ' ON ' . $joinCondition->getSelector1Name() . '.' . $column1Name . ' = ' . $joinCondition->getSelector2Name() . '.' . $column2Name;
+ }
+ if ($rightSource instanceof Tx_Extbase_Persistence_QOM_JoinInterface) {
+ $this->parseJoin($rightSource, $sql);
}
- // TODO Implement childtableWhere
}
/**
$sql['where'][] = '1<>1';
} else {
$className = $source->getNodeTypeName();
+ $tableName = $this->dataMapper->convertClassNameToTableName($className);
$propertyName = $operand1->getPropertyName();
while (strpos($propertyName, '.') !== FALSE) {
- $this->addUnionStatement($className, $propertyName, $sql);
+ $this->addUnionStatement($className, $tableName, $propertyName, $sql);
}
- $tableName = $this->dataMapper->convertClassNameToTableName($className);
$columnName = $this->dataMapper->convertPropertyNameToColumnName($propertyName, $className);
$dataMap = $this->dataMapper->getDataMap($className);
$columnMap = $dataMap->getColumnMap($propertyName);
}
}
$this->parseDynamicOperand($operand1, $operator, $source, $sql, $parameters);
- $parameters[] = $this->getPlainValue($operand2);
+ $parameters[] = $this->getPlainValue($operand2);
}
}
} elseif ($operand instanceof Tx_Extbase_Persistence_QOM_UpperCaseInterface) {
$this->parseDynamicOperand($operand->getOperand(), $operator, $source, $sql, $parameters, 'UPPER');
} elseif ($operand instanceof Tx_Extbase_Persistence_QOM_PropertyValueInterface) {
+ $propertyName = $operand->getPropertyName();
if ($source instanceof Tx_Extbase_Persistence_QOM_SelectorInterface) { // FIXME Only necessary to differ from Join
$className = $source->getNodeTypeName();
+ $tableName = $this->dataMapper->convertClassNameToTableName($className);
+ while (strpos($propertyName, '.') !== FALSE) {
+ $this->addUnionStatement($className, $tableName, $propertyName, $sql);
+ }
+ } elseif ($source instanceof Tx_Extbase_Persistence_QOM_JoinInterface) {
+ $tableName = $source->getJoinCondition()->getSelector1Name();
}
- $propertyName = $operand->getPropertyName();
- while (strpos($propertyName, '.') !== FALSE) {
- $this->addUnionStatement($className, $propertyName, $sql);
- }
- $tableName = $this->dataMapper->convertClassNameToTableName($className);
$columnName = $this->dataMapper->convertPropertyNameToColumnName($propertyName, $className);
$operator = $this->resolveOperator($operator);
if ($valueFunction === NULL) {
}
}
- protected function addUnionStatement(&$className, &$propertyPath, array &$sql) {
+ protected function addUnionStatement(&$className, &$tableName, &$propertyPath, array &$sql) {
$explodedPropertyPath = explode('.', $propertyPath, 2);
$propertyName = $explodedPropertyPath[0];
$columnName = $this->dataMapper->convertPropertyNameToColumnName($propertyName, $className);
} else {
$sql['unions'][$childTableName] = 'INNER JOIN ' . $childTableName . ' ON ' . $tableName . '.' . $columnName . '=' . $childTableName . '.uid';
}
- $className = $columnMap->getChildClassName();
+ $className = $this->dataMapper->getType($className, $propertyName);
} elseif ($columnMap->getTypeOfRelation() === Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_MANY) {
if (isset($parentKeyFieldName)) {
$sql['unions'][$childTableName] = 'INNER JOIN ' . $childTableName . ' ON ' . $tableName . '.uid=' . $childTableName . '.' . $parentKeyFieldName;
} else {
throw new Tx_Extbase_Persistence_Exception('Could not determine type of relation.', 1252502725);
}
+ // TODO check if there is another solution for this
+ $sql['keywords']['distinct'] = 'DISTINCT';
$propertyPath = $explodedPropertyPath[1];
+ $tableName = $childTableName;
}
/**
/**
* Transforms orderings into SQL.
*
- * @param array $orderings Ann array of orderings (Tx_Extbase_Persistence_QOM_Ordering)
+ * @param array $orderings An array of orderings (Tx_Extbase_Persistence_QOM_Ordering)
* @param Tx_Extbase_Persistence_QOM_SourceInterface $source The source
* @param array &$sql The query parts
* @return void
*/
protected function parseOrderings(array $orderings, Tx_Extbase_Persistence_QOM_SourceInterface $source, array &$sql) {
- foreach ($orderings as $ordering) {
- $operand = $ordering->getOperand();
- $order = $ordering->getOrder();
- if ($operand instanceof Tx_Extbase_Persistence_QOM_PropertyValue) {
- switch ($order) {
- case Tx_Extbase_Persistence_QOM_QueryObjectModelConstantsInterface::JCR_ORDER_ASCENDING:
- $order = 'ASC';
- break;
- case Tx_Extbase_Persistence_QOM_QueryObjectModelConstantsInterface::JCR_ORDER_DESCENDING:
- $order = 'DESC';
- break;
- default:
- throw new Tx_Extbase_Persistence_Exception_UnsupportedOrder('Unsupported order encountered.', 1242816074);
- }
- $tableName = $operand->getSelectorName();
- $className = '';
- if ($source instanceof Tx_Extbase_Persistence_QOM_SelectorInterface) {
- $className = $source->getNodeTypeName();
- }
- $columnName = $this->dataMapper->convertPropertyNameToColumnName($operand->getPropertyName(), $className);
- if (strlen($tableName) > 0) {
- $sql['orderings'][] = $tableName . '.' . $columnName . ' ' . $order;
- } else {
- $sql['orderings'][] = $columnName . ' ' . $order;
+ foreach ($orderings as $propertyName => $order) {
+ if ($source instanceof Tx_Extbase_Persistence_QOM_SelectorInterface) {
+ $className = $source->getNodeTypeName();
+ $tableName = $this->dataMapper->convertClassNameToTableName($className);
+ while (strpos($propertyName, '.') !== FALSE) {
+ $this->addUnionStatement($className, $tableName, $propertyName, $sql);
}
+ } elseif ($source instanceof Tx_Extbase_Persistence_QOM_JoinInterface) {
+ $tableName = $source->getLeft()->getSelectorName();
+ }
+ $columnName = $this->dataMapper->convertPropertyNameToColumnName($propertyName, $className);
+ if (strlen($tableName) > 0) {
+ $sql['orderings'][] = $tableName . '.' . $columnName . ' ' . $order;
+ } else {
+ $sql['orderings'][] = $columnName . ' ' . $order;
}
}
}