* A Storage backend
*
* @package Extbase
- * @subpackage Persistence
+ * @subpackage Persistence\Storage
* @version $Id: $
*/
class Tx_Extbase_Persistence_Storage_Typo3DbBackend implements Tx_Extbase_Persistence_Storage_BackendInterface, t3lib_Singleton {
protected $databaseHandle;
/**
- * The TYPO3 page select object. Used for language and workspace overlay
- *
- * @var t3lib_pageSelect
+ * @var Tx_Extbase_Persistence_DataMapper
*/
- protected $pageSelectObject;
+ protected $dataMapper;
/**
- * TRUE if the framework should add the "enable fields" (e.g. checking for hidden or deleted records)
+ * The TYPO3 page select object. Used for language and workspace overlay
*
- * @var boolean
- */
- protected $useEnableFields = TRUE;
-
- /**
- * TRUE if automatic cache clearing in TCEMAIN should be done on insert/update/delete, FALSE otherwise.
- *
- * @var boolean
+ * @var t3lib_pageSelect
*/
- protected $automaticCacheClearing = FALSE;
+ protected $pageSelectObject;
/**
* Constructs this Storage Backend instance
public function __construct($databaseHandle) {
$this->databaseHandle = $databaseHandle;
}
-
+
/**
- * Set the automatic cache clearing flag.
- * If TRUE, then inserted/updated/deleted records trigger a TCEMAIN cache clearing.
- *
- * @param $automaticCacheClearing boolean if TRUE, enables automatic cache clearing
+ * Injects the DataMapper to map nodes to objects
+ *
+ * @param Tx_Extbase_Persistence_Mapper_DataMapper $dataMapper
* @return void
- * @internal
*/
- public function setAutomaticCacheClearing($automaticCacheClearing) {
- $this->automaticCacheClearing = (boolean)$automaticCacheClearing;
+ public function injectDataMapper(Tx_Extbase_Persistence_Mapper_DataMapper $dataMapper) {
+ $this->dataMapper = $dataMapper;
}
/**
$fields = array();
$values = array();
$parameters = array();
- unset($row['uid']); // TODO Check if the offset exists
+ if (isset($row['uid'])) {
+ unset($row['uid']);
+ }
foreach ($row as $columnName => $value) {
$fields[] = $columnName;
$values[] = '?';
* @return array The matching tuples
*/
public function getRows(Tx_Extbase_Persistence_QOM_QueryObjectModelInterface $query) {
- $sql = array();
- $sql['tables'] = array();
- $sql['fields'] = array();
- $sql['where'] = array();
- $sql['enableFields'] = array();
- $sql['orderings'] = array();
- $parameters = array();
- $tuples = array();
+ $statement = $this->parseQuery($query);
+// debug($statement, -2); // FIXME remove debug code
+ $result = $this->databaseHandle->sql_query($statement);
+ $this->checkSqlErrors();
+ if ($result) {
+ $tuples = $this->getRowsFromResult($query->getSource(), $result);
+ }
- $this->parseSource($query, $sql, $parameters);
- $sqlString = 'SELECT ' . implode(',', $sql['fields']) . ' FROM ' . implode(' ', $sql['tables']);
+ return $tuples;
+ }
+
+ /**
+ * Returns an array with tuples matching the query.
+ *
+ * @param Tx_Extbase_Persistence_QOM_QueryObjectModelInterface $query
+ * @return array The matching tuples
+ */
+ public function parseQuery(Tx_Extbase_Persistence_QOM_QueryObjectModelInterface $query) {
+ $statement = '';
+ $parameters = array();
+ $constraint = $query->getConstraint();
+ if($constraint instanceof Tx_Extbase_Persistence_QOM_StatementInterface) {
+ if ($constraint->getLanguage() === Tx_Extbase_Persistence_QOM_QueryObjectModelInterface::TYPO3_SQL_MYSQL) {
+ $statement = $constraint->getStatement();
+ $parameters= $query->getBoundVariableValues();
+ } else {
+ throw new Tx_Extbase_Persistence_Exception('Unsupported query language.', 1248701951);
+ }
+ } else {
+ $sql = array();
+ $sql['tables'] = array();
+ $sql['fields'] = array();
+ $sql['where'] = array();
+ $sql['additionalWhereClause'] = array();
+ $sql['orderings'] = array();
+ $sql['limit'] = array();
+ $tuples = array();
+
+ $source = $query->getSource();
+ $this->parseSource($query, $source, $sql, $parameters);
+
+ $statement = 'SELECT ' . implode(',', $sql['fields']) . ' FROM ' . implode(' ', $sql['tables']);
+
+ $this->parseConstraint($constraint, $source, $sql, $parameters, $query->getBoundVariableValues());
+
+ if (!empty($sql['where'])) {
+ $statement .= ' WHERE ' . implode('', $sql['where']);
+ if (!empty($sql['additionalWhereClause'])) {
+ $statement .= ' AND ' . implode(' AND ', $sql['additionalWhereClause']);
+ }
+ } elseif (!empty($sql['additionalWhereClause'])) {
+ $statement .= ' WHERE ' . implode(' AND ', $sql['additionalWhereClause']);
+ }
- $this->parseConstraint($query->getConstraint(), $sql, $parameters, $query->getBoundVariableValues());
- if (!empty($sql['where'])) {
- $sqlString .= ' WHERE ' . implode('', $sql['where']);
- if (!empty($sql['enableFields'])) {
- $sqlString .= ' AND ' . implode(' AND ', $sql['enableFields']);
+ $this->parseOrderings($query->getOrderings(), $source, $sql);
+ if (!empty($sql['orderings'])) {
+ $statement .= ' ORDER BY ' . implode(', ', $sql['orderings']);
}
- } elseif (!empty($sql['enableFields'])) {
- $sqlString .= ' WHERE ' . implode(' AND ', $sql['enableFields']);
- }
- $this->parseOrderings($query->getOrderings(), $sql, $parameters, $query->getBoundVariableValues());
- if (!empty($sql['orderings'])) {
- $sqlString .= ' ORDER BY ' . implode(', ', $sql['orderings']);
+ $this->parseLimitAndOffset($query->getLimit(), $query->getOffset(), $sql);
+ if (!empty($sql['limit'])) {
+ $statement .= ' LIMIT ' . $sql['limit'];
+ }
}
- $this->replacePlaceholders($sqlString, $parameters);
-
- $result = $this->databaseHandle->sql_query($sqlString);
- $this->checkSqlErrors();
- if ($result) {
- // TODO Check for selector name
- $tuples = $this->getRowsFromResult($query->getSelectorName(), $result);
- }
-
- return $tuples;
+ $this->replacePlaceholders($statement, $parameters);
+ // debug($statement,-2);
+ return $statement;
}
/**
*
* @param array $properties The properties of the Value Object
* @param Tx_Extbase_Persistence_Mapper_DataMap $dataMap The Data Map
- * @return array The matching tuples
+ * @return array The matching uid
*/
public function hasValueObject(array $properties, Tx_Extbase_Persistence_Mapper_DataMap $dataMap) {
$fields = array();
$parameters = array();
foreach ($properties as $propertyName => $propertyValue) {
- if ($dataMap->isPersistableProperty($propertyName) && ($propertyName !== 'uid')) {
+ // FIXME We couple the Backend to the Entity implementation (uid, isClone); changes there breaks this method
+ if ($dataMap->isPersistableProperty($propertyName) && ($propertyName !== 'uid') && ($propertyName !== 'pid') && ($propertyName !== 'isClone')) {
$fields[] = $dataMap->getColumnMap($propertyName)->getColumnName() . '=?';
$parameters[] = $dataMap->convertPropertyValueToFieldValue($propertyValue);
}
}
-
- $sqlString = 'SELECT * FROM ' . $dataMap->getTableName() . ' WHERE ' . implode('', $fields);
- $this->replacePlaceholders($sqlString, $parameters);
- $res = $this->databaseHandle->sql_query($sqlString);
+ $sql = array();
+ $sql['additionalWhereClause'] = array();
+
+ $tableName = $dataMap->getTableName();
+ $this->addEnableFieldsStatement($tableName, $sql);
+
+ $statement = 'SELECT * FROM ' . $tableName;
+ $statement .= ' WHERE ' . implode(' AND ', $fields);
+ if (!empty($sql['additionalWhereClause'])) {
+ $statement .= ' AND ' . implode(' AND ', $sql['additionalWhereClause']);
+ }
+ $this->replacePlaceholders($statement, $parameters);
+ $res = $this->databaseHandle->sql_query($statement);
$this->checkSqlErrors();
$row = $this->databaseHandle->sql_fetch_assoc($res);
if ($row !== FALSE) {
* Transforms a Query Source into SQL and parameter arrays
*
* @param Tx_Extbase_Persistence_QOM_QueryObjectModel $query
+ * @param Tx_Extbase_Persistence_QOM_SourceInterface $source The source
* @param array &$sql
* @param array &$parameters
* @return void
*/
- protected function parseSource(Tx_Extbase_Persistence_QOM_QueryObjectModel $query, array &$sql, array &$parameters) {
- $source = $query->getSource();
+ protected function parseSource(Tx_Extbase_Persistence_QOM_QueryObjectModelInterface $query, Tx_Extbase_Persistence_QOM_SourceInterface $source, array &$sql, array &$parameters) {
if ($source instanceof Tx_Extbase_Persistence_QOM_SelectorInterface) {
- $selectorName = $source->getSelectorName();
- $sql['fields'][] = $selectorName . '.*';
- $sql['tables'][] = $selectorName;
- // TODO Should we make the usage of enableFields configurable? And how? Because the Query object and even the QOM should be abstracted from the storage backend.
- if ($this->useEnableFields === TRUE) {
- $this->addEnableFieldsStatement($selectorName, $sql);
+ $tableName = $source->getSelectorName();
+ $sql['fields'][] = $tableName . '.*';
+ $sql['tables'][] = $tableName;
+ $querySettings = $query->getQuerySettings();
+ if ($querySettings instanceof Tx_Extbase_Persistence_Typo3QuerySettingsInterface) {
+ if ($querySettings->getRespectEnableFields()) {
+ $this->addEnableFieldsStatement($tableName, $sql);
+ }
+ if ($querySettings->getRespectStoragePage()) {
+ $this->addPageIdStatement($tableName, $sql);
+ }
}
} elseif ($source instanceof Tx_Extbase_Persistence_QOM_JoinInterface) {
- $this->parseJoin($source, $sql, $parameters);
+ $this->parseJoin($query, $source, $sql);
}
}
/**
* Transforms a Join into SQL and parameter arrays
*
- * @param Tx_Extbase_Persistence_QOM_JoinInterface $join
- * @param array &$sql
- * @param array &$parameters
+ * @param Tx_Extbase_Persistence_QOM_QueryObjectModel $query The Query Object Model
+ * @param Tx_Extbase_Persistence_QOM_JoinInterface $join The join
+ * @param array &$sql The query parts
* @return void
*/
- protected function parseJoin(Tx_Extbase_Persistence_QOM_JoinInterface $join, array &$sql, array &$parameters) {
- $leftSelectorName = $join->getLeft()->getSelectorName();
- $rightSelectorName = $join->getRight()->getSelectorName();
+ protected function parseJoin(Tx_Extbase_Persistence_QOM_QueryObjectModelInterface $query, Tx_Extbase_Persistence_QOM_JoinInterface $join, array &$sql) {
+ $leftSource = $join->getLeft();
+ $leftTableName = $leftSource->getSelectorName();
+ $rightSource = $join->getRight();
+ $rightTableName = $rightSource->getSelectorName();
- $sql['fields'][] = $leftSelectorName . '.*';
- $sql['fields'][] = $rightSelectorName . '.*';
+ $sql['fields'][] = $leftTableName . '.*';
+ $sql['fields'][] = $rightTableName . '.*';
// TODO Implement support for different join types and nested joins
- $sql['tables'][] = $leftSelectorName . ' LEFT JOIN ' . $rightSelectorName;
+ $sql['tables'][] = $leftTableName . ' LEFT JOIN ' . $rightTableName;
$joinCondition = $join->getJoinCondition();
// TODO Check the parsing of the join
if ($joinCondition instanceof Tx_Extbase_Persistence_QOM_EquiJoinCondition) {
- $sql['tables'][] = 'ON ' . $joinCondition->getSelector1Name() . '.' . $joinCondition->getProperty1Name() . ' = ' . $joinCondition->getSelector2Name() . '.' . $joinCondition->getProperty2Name();
+ // 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['tables'][] = 'ON ' . $joinCondition->getSelector1Name() . '.' . $column1Name . ' = ' . $joinCondition->getSelector2Name() . '.' . $column2Name;
}
// TODO Implement childtableWhere
- $this->addEnableFieldsStatement($leftSelectorName, $sql);
- $this->addEnableFieldsStatement($rightSelectorName, $sql);
+ $querySettings = $query->getQuerySettings();
+ if ($querySettings instanceof Tx_Extbase_Persistence_Typo3QuerySettingsInterface) {
+ if ($querySettings->getRespectEnableFields()) {
+ $this->addEnableFieldsStatement($leftTableName, $sql);
+ $this->addEnableFieldsStatement($rightTableName, $sql);
+ }
+ if ($querySettings->getRespectStoragePage()) {
+ $this->addPageIdStatement($leftTableName, $sql);
+ $this->addPageIdStatement($rightTableName, $sql);
+ }
+ }
}
/**
* Transforms a constraint into SQL and parameter arrays
*
- * @param Tx_Extbase_Persistence_QOM_ConstraintInterface $constraint
- * @param array &$sql
- * @param array &$parameters
- * @param array $boundVariableValues
+ * @param Tx_Extbase_Persistence_QOM_ConstraintInterface $constraint The constraint
+ * @param Tx_Extbase_Persistence_QOM_SourceInterface $source The source
+ * @param array &$sql The query parts
+ * @param array &$parameters The parameters that will replace the markers
+ * @param array $boundVariableValues The bound variables in the query (key) and their values (value)
* @return void
*/
- protected function parseConstraint(Tx_Extbase_Persistence_QOM_ConstraintInterface $constraint = NULL, array &$sql, array &$parameters, array $boundVariableValues) {
+ protected function parseConstraint(Tx_Extbase_Persistence_QOM_ConstraintInterface $constraint = NULL, Tx_Extbase_Persistence_QOM_SourceInterface $source, array &$sql, array &$parameters, array $boundVariableValues) {
if ($constraint instanceof Tx_Extbase_Persistence_QOM_AndInterface) {
$sql['where'][] = '(';
- $this->parseConstraint($constraint->getConstraint1(), $sql, $parameters, $boundVariableValues);
+ $this->parseConstraint($constraint->getConstraint1(), $source, $sql, $parameters, $boundVariableValues);
$sql['where'][] = ' AND ';
- $this->parseConstraint($constraint->getConstraint2(), $sql, $parameters, $boundVariableValues);
+ $this->parseConstraint($constraint->getConstraint2(), $source, $sql, $parameters, $boundVariableValues);
$sql['where'][] = ')';
} elseif ($constraint instanceof Tx_Extbase_Persistence_QOM_OrInterface) {
$sql['where'][] = '(';
- $this->parseConstraint($constraint->getConstraint1(), $sql, $parameters, $boundVariableValues);
+ $this->parseConstraint($constraint->getConstraint1(), $source, $sql, $parameters, $boundVariableValues);
$sql['where'][] = ' OR ';
- $this->parseConstraint($constraint->getConstraint2(), $sql, $parameters, $boundVariableValues);
+ $this->parseConstraint($constraint->getConstraint2(), $source, $sql, $parameters, $boundVariableValues);
$sql['where'][] = ')';
} elseif ($constraint instanceof Tx_Extbase_Persistence_QOM_NotInterface) {
$sql['where'][] = 'NOT (';
- $this->parseConstraint($constraint->getConstraint(), $sql, $parameters, $boundVariableValues);
+ $this->parseConstraint($constraint->getConstraint(), $source, $sql, $parameters, $boundVariableValues);
$sql['where'][] = ')';
} elseif ($constraint instanceof Tx_Extbase_Persistence_QOM_ComparisonInterface) {
- $this->parseComparison($constraint, $sql, $parameters, $boundVariableValues);
+ $this->parseComparison($constraint, $source, $sql, $parameters, $boundVariableValues);
} elseif ($constraint instanceof Tx_Extbase_Persistence_QOM_RelatedInterface) {
$this->parseRelated($constraint, $sql, $parameters, $boundVariableValues);
}
* Parse a Comparison into SQL and parameter arrays.
*
* @param Tx_Extbase_Persistence_QOM_ComparisonInterface $comparison The comparison to parse
+ * @param Tx_Extbase_Persistence_QOM_SourceInterface $source The source
* @param array &$sql SQL query parts to add to
* @param array &$parameters Parameters to bind to the SQL
* @param array $boundVariableValues The bound variables in the query and their values
* @return void
*/
- protected function parseComparison(Tx_Extbase_Persistence_QOM_ComparisonInterface $comparison, array &$sql, array &$parameters, array $boundVariableValues) {
+ protected function parseComparison(Tx_Extbase_Persistence_QOM_ComparisonInterface $comparison, Tx_Extbase_Persistence_QOM_SourceInterface $source, array &$sql, array &$parameters, array $boundVariableValues) {
if (!($comparison->getOperand2() instanceof Tx_Extbase_Persistence_QOM_BindVariableValueInterface)) throw new Tx_Extbase_Persistence_Exception('Type of operand is not supported', 1247581135);
$value = $boundVariableValues[$comparison->getOperand2()->getBindVariableName()];
}
$parameters[] = $value;
- $this->parseDynamicOperand($comparison->getOperand1(), $operator, $sql, $parameters);
+ $this->parseDynamicOperand($comparison->getOperand1(), $operator, $source, $sql, $parameters);
}
/**
*
* @param Tx_Extbase_Persistence_QOM_DynamicOperandInterface $operand
* @param string $operator One of the JCR_OPERATOR_* constants
- * @param array $boundVariableValues
- * @param array &$parameters
- * @param string $valueFunction an aoptional SQL function to apply to the operand value
+ * @param Tx_Extbase_Persistence_QOM_SourceInterface $source The source
+ * @param array &$sql The query parts
+ * @param array &$parameters The parameters that will replace the markers
+ * @param string $valueFunction an optional SQL function to apply to the operand value
* @return void
*/
- protected function parseDynamicOperand(Tx_Extbase_Persistence_QOM_DynamicOperandInterface $operand, $operator, array &$sql, array &$parameters, $valueFunction = NULL) {
+ protected function parseDynamicOperand(Tx_Extbase_Persistence_QOM_DynamicOperandInterface $operand, $operator, Tx_Extbase_Persistence_QOM_SourceInterface $source, array &$sql, array &$parameters, $valueFunction = NULL) {
if ($operand instanceof Tx_Extbase_Persistence_QOM_LowerCaseInterface) {
- $this->parseDynamicOperand($operand->getOperand(), $operator, $sql, $parameters, 'LOWER');
+ $this->parseDynamicOperand($operand->getOperand(), $operator, $source, $sql, $parameters, 'LOWER');
} elseif ($operand instanceof Tx_Extbase_Persistence_QOM_UpperCaseInterface) {
- $this->parseDynamicOperand($operand->getOperand(), $operator, $sql, $parameters, 'UPPER');
+ $this->parseDynamicOperand($operand->getOperand(), $operator, $source, $sql, $parameters, 'UPPER');
} elseif ($operand instanceof Tx_Extbase_Persistence_QOM_PropertyValueInterface) {
- $selectorName = $operand->getSelectorName();
+ $tableName = $operand->getSelectorName();
+ // FIXME Discuss the translation from propertyName to columnName
+ if ($source instanceof Tx_Extbase_Persistence_QOM_SelectorInterface) {
+ $className = $source->getNodeTypeName();
+ } else {
+ $className = '';
+ }
+ $columnName = $this->dataMapper->convertPropertyNameToColumnName($operand->getPropertyName(), $className);
$operator = $this->resolveOperator($operator);
if ($valueFunction === NULL) {
- $constraintSQL .= (!empty($selectorName) ? $selectorName . '.' : '') . $operand->getPropertyName() . ' ' . $operator . ' ?';
+ $constraintSQL .= (!empty($tableName) ? $tableName . '.' : '') . $columnName . ' ' . $operator . ' ?';
} else {
- $constraintSQL .= $valueFunction . '(' . (!empty($selectorName) ? $selectorName . '.' : '') . $operand->getPropertyName() . ' ' . $operator . ' ?';
+ $constraintSQL .= $valueFunction . '(' . (!empty($tableName) ? $tableName . '.' : '') . $columnName . ' ' . $operator . ' ?';
}
$sql['where'][] = $constraintSQL;
* Replace query placeholders in a query part by the given
* parameters.
*
- * @param string $queryPart The query part with placeholders
+ * @param string $sqlString The query part with placeholders
* @param array $parameters The parameters
* @return string The query part with replaced placeholders
*/
protected function replacePlaceholders(&$sqlString, array $parameters) {
if (substr_count($sqlString, '?') !== count($parameters)) throw new Tx_Extbase_Persistence_Exception('The number of question marks to replace must be equal to the number of parameters.', 1242816074);
+ $offset = 0;
foreach ($parameters as $parameter) {
- $markPosition = strpos($sqlString, '?');
+ $markPosition = strpos($sqlString, '?', $offset);
if ($markPosition !== FALSE) {
- // TODO This is a bit hacky; improve the handling of $parameter === NULL
if ($parameter === NULL) {
$parameter = 'NULL';
} else {
- $parameter = '"' . $parameter . '"';
+ $parameter = $this->databaseHandle->fullQuoteStr($parameter, 'foo'); // FIXME This may not work with DBAL; check this
}
$sqlString = substr($sqlString, 0, $markPosition) . $parameter . substr($sqlString, $markPosition + 1);
}
+ $offset = $markPosition + strlen($parameter);
}
}
/**
* Builds the enable fields statement
*
- * @param string $selectorName The selector name (= database table name)
+ * @param string $tableName The database table name
* @param array &$sql The query parts
* @return void
*/
- protected function addEnableFieldsStatement($selectorName, array &$sql) {
- // TODO We have to call the appropriate API method if we are in TYPO3BE mode
- if (is_array($GLOBALS['TCA'][$selectorName]['ctrl'])) {
- $statement = substr($GLOBALS['TSFE']->sys_page->enableFields($selectorName), 4);
+ protected function addEnableFieldsStatement($tableName, array &$sql) {
+ if (is_array($GLOBALS['TCA'][$tableName]['ctrl'])) {
+ if (TYPO3_MODE === 'FE') {
+ $statement = $GLOBALS['TSFE']->sys_page->enableFields($tableName);
+ } else { // TYPO3_MODE === 'BE'
+ $statement = t3lib_BEfunc::deleteClause($tableName);
+ $statement .= t3lib_BEfunc::BEenableFields($tableName);
+ }
if(!empty($statement)) {
- $sql['enableFields'][] = $statement;
+ $statement = substr($statement, 5);
+ $sql['additionalWhereClause'][] = $statement;
}
}
}
/**
- * Transforms orderings into SQL
+ * Builds the page ID checking statement
*
- * @param array $orderings
- * @param array &$sql
- * @param array &$parameters
- * @param array $boundVariableValues
+ * @param string $tableName The database table name
+ * @param array &$sql The query parts
+ * @return void
+ */
+ protected function addPageIdStatement($tableName, array &$sql) {
+ if (is_array($GLOBALS['TCA'][$tableName]['ctrl'])) {
+ $extbaseFrameworkConfiguration = Tx_Extbase_Dispatcher::getExtbaseFrameworkConfiguration();
+ $sql['additionalWhereClause'][] = $tableName . '.pid IN (' . implode(', ', t3lib_div::intExplode(',', $extbaseFrameworkConfiguration['persistence']['storagePid'])) . ')';
+ }
+ }
+
+ /**
+ * Transforms orderings into SQL.
+ *
+ * @param array $orderings Ann 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, array &$sql, array &$parameters, array $boundVariableValues) {
+ protected function parseOrderings(array $orderings, Tx_Extbase_Persistence_QOM_SourceInterface $source, array &$sql) {
foreach ($orderings as $ordering) {
$operand = $ordering->getOperand();
$order = $ordering->getOrder();
$order = 'DESC';
break;
default:
- throw new Tx_Extbase_Persistence_Exception('Unsupported order encountered.', 1242816074);
+ throw new Tx_Extbase_Persistence_Exception_UnsupportedOrder('Unsupported order encountered.', 1242816074);
+ }
+ $tableName = $operand->getSelectorName();
+ if ((strlen($tableName) == 0) && (source instanceof Tx_Extbase_Persistence_QOM_SelectorInterface)) {
+ $tableName = $source->getSelectorName();
+ }
+ $columnName = $this->dataMapper->convertPropertyNameToColumnName($operand->getPropertyName(), $tableName);
+ if (strlen($tableName) > 0) {
+ $sql['orderings'][] = $tableName . '.' . $columnName . ' ' . $order;
+ } else {
+ $sql['orderings'][] = $columnName . ' ' . $order;
}
-
- $sql['orderings'][] = $ordering->getOperand()->getPropertyName() . ' ' . $order;
}
}
}
+ /**
+ * Transforms limit and offset into SQL
+ *
+ * @param int $limit
+ * @param int $offset
+ * @param array &$sql
+ * @return void
+ */
+ protected function parseLimitAndOffset($limit, $offset, array &$sql) {
+ if ($limit !== NULL && $offset !== NULL) {
+ $sql['limit'] = $offset . ', ' . $limit;
+ } elseif ($limit !== NULL) {
+ $sql['limit'] = $limit;
+ }
+ }
+
/**
* Transforms a Resource from a database query to an array of rows. Performs the language and
* workspace overlay before.
*
+ * @param Tx_Extbase_Persistence_QOM_SourceInterface $source The source (selector od join)
+ * @param resource &$sql The resource
* @return array The result as an array of rows (tuples)
*/
- protected function getRowsFromResult($tableName, $res) {
+ protected function getRowsFromResult(Tx_Extbase_Persistence_QOM_SourceInterface $source, $res) {
$rows = array();
while ($row = $this->databaseHandle->sql_fetch_assoc($res)) {
- $row = $this->doLanguageAndWorkspaceOverlay($tableName, $row);
+ if ($source instanceof Tx_Extbase_Persistence_QOM_SelectorInterface) {
+ // FIXME The overlay is only performed if we query a single table; no joins
+ $row = $this->doLanguageAndWorkspaceOverlay($source->getSelectorName(), $row);
+ }
if (is_array($row)) {
// TODO Check if this is necessary, maybe the last line is enough
$arrayKeys = range(0,count($row));
} else {
require_once(PATH_t3lib . 'class.t3lib_page.php');
$this->pageSelectObject = t3lib_div::makeInstance( 't3lib_pageSelect' );
- //$this->pageSelectObject->versioningPreview = TRUE;
if ($workspaceUid === NULL) {
$workspaceUid = $GLOBALS['BE_USER']->workspace;
}
// TODO Skip if empty languageoverlay (languagevisibility)
return $row;
}
-
+
/**
* Checks if there are SQL errors in the last query, and if yes, throw an exception.
- *
+ *
* @return void
* @throws Tx_Extbase_Persistence_Storage_Exception_SqlError
*/
/**
* Clear the TYPO3 page cache for the given record.
* Much of this functionality is taken from t3lib_tcemain::clear_cache() which unfortunately only works with logged-in BE user.
- *
+ *
* @param $tableName Table name of the record
* @param $uid UID of the record
* @return void
*/
protected function clearPageCache($tableName, $uid) {
- if ($this->automaticCacheClearing !== TRUE) return;
+ $extbaseSettings = Tx_Extbase_Dispatcher::getExtbaseFrameworkConfiguration();
+ if (isset($extbaseSettings['persistence']['enableAutomaticCacheClearing']) && $extbaseSettings['persistence']['enableAutomaticCacheClearing'] === '1') {
+ } else {
+ // if disabled, return
+ return;
+ }
+
+ $result = $this->databaseHandle->exec_SELECTquery('pid', $tableName, 'uid='.intval($uid));
- $pageCache = $GLOBALS['typo3CacheManager']->getCache('cache_pages');
- $pageSectionCache = $GLOBALS['typo3CacheManager']->getCache('cache_pagesection');
-
- $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery('pid', $tableName, 'uid='.intval($uid));
-
$pageIdsToClear = array();
- if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) {
+ if ($row = $this->databaseHandle->sql_fetch_assoc($result)) {
$storagePage = $row['pid'];
$pageIdsToClear[] = $storagePage;
}
if (!$storagePage) {
return;
}
-
+
$pageTSConfig = t3lib_BEfunc::getPagesTSconfig($storagePage);
-
- if ($pageTSConfig['clearCacheCmd']) {
- $clearCacheCommands = t3lib_div::trimExplode(',',strtolower($TSConfig['clearCacheCmd']),1);
- $clearCacheCommands = array_unique($clearCacheCommands);
- foreach ($clearCacheCommands as $clearCacheCommand) {
- if (t3lib_div::testInt($clearCacheCommand)) {
- $pageIdsToClear[] = $clearCacheCommand;
- }
+ if (isset($pageTSConfig['TCEMAIN.']['clearCacheCmd'])) {
+ $clearCacheCommands = t3lib_div::trimExplode(',',strtolower($pageTSConfig['TCEMAIN.']['clearCacheCmd']),1);
+ $clearCacheCommands = array_unique($clearCacheCommands);
+ foreach ($clearCacheCommands as $clearCacheCommand) {
+ if (t3lib_div::testInt($clearCacheCommand)) {
+ $pageIdsToClear[] = $clearCacheCommand;
}
}
-
- foreach ($pageIdsToClear as $pageIdToClear) {
- $pageCache->flushByTag('pageId_' . $pageIdToClear);
- $pageSectionCache->flushByTag('pageId_' . $pageIdToClear);
}
+
+ Tx_Extbase_Utility_Cache::clearPageCache($pageIdsToClear);
}
}