Project

General

Profile

Actions

Feature #32051

open

Concat ordering for Database request

Added by Anonymous almost 13 years ago. Updated over 1 year ago.

Status:
New
Priority:
Should have
Assignee:
-
Category:
Extbase
Target version:
-
Start date:
2011-11-24
Due date:
% Done:

90%

Estimated time:
PHP Version:
Tags:
Complexity:
Sprint Focus:

Description

Hi there

it would be nice to be able to made "concat orderings" over multiple fields with database.

I'd imagine this looking like this:


$query = $this->createQuery();

$query->setOrderings(
array(
'CONCAT(field1,field2,field3) as 'fieldx' => Tx_Extbase_Persistence_QueryInterface::ORDER_DESCENDING
)
);

The code must then check with preg_match if CONCAT\((.*)\) as ([^\s]+) is set.

I'm probably going to implement something like this by my self and I'll post it as soon as I've got something that works.

Greets Tizian


Related issues 1 (0 open1 closed)

Related to TYPO3 Core - Feature #79054: Custom Order By ClauseClosed2016-12-20

Actions
Actions #1

Updated by Anonymous almost 13 years ago

  • % Done changed from 0 to 90

Hello there

I as promised I made a patch and here is how it works:

New Version of Tx_Extbase_Persistence_Storage_Typo3DbBackend::parseOrderings

    /**
     * Transforms orderings into SQL.
     *
     * @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 $propertyName => $order) {
            switch ($order) {
                case Tx_Extbase_Persistence_QOM_QueryObjectModelConstantsInterface::JCR_ORDER_ASCENDING: // Deprecated since Extbase 1.1
                case Tx_Extbase_Persistence_QueryInterface::ORDER_ASCENDING:
                    $order = 'ASC';
                    break;
                case Tx_Extbase_Persistence_QOM_QueryObjectModelConstantsInterface::JCR_ORDER_DESCENDING: // Deprecated since Extbase 1.1
                case Tx_Extbase_Persistence_QueryInterface::ORDER_DESCENDING:
                    $order = 'DESC';
                    break;
                default:
                    throw new Tx_Extbase_Persistence_Exception_UnsupportedOrder('Unsupported order encountered.', 1242816074);
            }
            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();
            }

            $aConcatFields = array();
            if(preg_match('/(concat)\(([^)]*)\)\s*as\s+([^\s]+)/i', $propertyName, $aConcatFields)) {
                $currentTable = $sql['fields'];

                // just get the first table name to simulate a proper table field
                foreach($currentTable as $table => $fields) {
                    $sql['fields'][$table] = $fields . ',' . $aConcatFields[1] . '('.$aConcatFields[2].') as ' . $aConcatFields[3];
                }
                // $sql['fields'] = $aConcatFields[1] . '('.$aConcatFields[3].') as ' . $aConcatFields[4];
                $columnName = $aConcatFields[3];

                $tableName = '';

            } else {
                $columnName = $this->dataMapper->convertPropertyNameToColumnName($propertyName, $className);
            }

            if (strlen($tableName) > 0) {
                $sql['orderings'][] = $tableName . '.' . $columnName . ' ' . $order;
            } else {
                $sql['orderings'][] = $columnName . ' ' . $order;
            }
        }
    }

The counting method has to be modified as well (Tx_Extbase_Persistence_Storage_Typo3DbBackend::getObjectCountByQuery):

    /**
     * Returns the number of tuples matching the query.
     *
     * @param Tx_Extbase_Persistence_QOM_QueryObjectModelInterface $query
     * @return integer The number of matching tuples
     */
    public function getObjectCountByQuery(Tx_Extbase_Persistence_QueryInterface $query) {
        $constraint = $query->getConstraint();
        if($constraint instanceof Tx_Extbase_Persistence_QOM_StatementInterface) {
            throw new Tx_Extbase_Persistence_Storage_Exception_BadConstraint('Could not execute count on queries with a constraint of type Tx_Extbase_Persistence_QOM_StatementInterface', 1256661045);
        }
        $parameters = array();
        $statementParts = $this->parseQuery($query, $parameters);
        // if limit is set, we need to count the rows "manually" as COUNT(*) ignores LIMIT constraints
        if (!empty($statementParts['limit'])) {
            $statement = $this->buildQuery($statementParts, $parameters);
            $this->replacePlaceholders($statement, $parameters);
            $result = $this->databaseHandle->sql_query($statement);
            $this->checkSqlErrors($statement);
            $count = $this->databaseHandle->sql_num_rows($result);
        } else {
            $statementParts['fields'] = array('COUNT(*)');
            // Backup the ordering statement
            $oderings = $statementParts['orderings'];
            // remove it since for count we do not need any ordering
            $statementParts['orderings'] = null;
            // make the query
            $statement = $this->buildQuery($statementParts, $parameters);
            // put back the orderings to the statemet parts
            $statementParts['orderings'] = $orderings;
            unset($orderings);
            $this->replacePlaceholders($statement, $parameters);
            $result = $this->databaseHandle->sql_query($statement);
            $this->checkSqlErrors($statement);
            $rows = $this->getRowsFromResult($query->getSource(), $result);
            $count = current(current($rows));
        }
        $this->databaseHandle->sql_free_result($result);
        return $count;
    }

Greetings Tizian

Actions #2

Updated by Alexander Schnitzler about 12 years ago

Hey,
thanks for the code but would you mind creating a real patch for gerrit?

Actions #3

Updated by Anja Leichsenring over 11 years ago

  • Target version set to Extbase 6.3
Actions #4

Updated by Alexander Opitz about 10 years ago

  • Status changed from New to Needs Feedback

Hi,

was this issue fixed or does it still exists?

Actions #5

Updated by Tizian Schmidlin about 10 years ago

Hello,

the problem still persists I think. I'll try to write a patch and challenge it against Gerrit but since 6.2 has come out I'll have to rewrite it for the new version first.

Actions #6

Updated by Alexander Opitz almost 10 years ago

  • Project changed from 534 to TYPO3 Core
  • Category changed from Extbase: Generic Persistence to Extbase
  • Target version deleted (Extbase 6.3)
Actions #7

Updated by Tizian Schmidlin almost 10 years ago

I given this some thought lately since I stumbled across a similar issue lately.

Maybe the solution would be a set of reserved words that cannot appear in the selected fields when trying to count, so if such field appears, the whole field part, then it would be simply rewritten to COUNT(*).

Sadly I hadn't any time yet to write a patch for this, I hope I'll be able to during the holidays.

Best Regards
Tizian

Actions #8

Updated by Alexander Opitz almost 10 years ago

  • Status changed from Needs Feedback to New
Actions #9

Updated by Mathias Schreiber almost 7 years ago

hey Tizian,

did you get holidays in the last 3 years? :)

Actions #10

Updated by Tizian Schmidlin about 6 years ago

Fair enough, I'll try to make it into core this time, now that I'm all set up, this should not take too long :-)

Actions #11

Updated by Gerrit Code Review over 5 years ago

  • Status changed from New to Under Review

Patch set 1 for branch master of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/c/Packages/TYPO3.CMS/+/61443

Actions #12

Updated by Gerrit Code Review about 5 years ago

Patch set 2 for branch master of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/c/Packages/TYPO3.CMS/+/61443

Actions #13

Updated by Gerrit Code Review about 5 years ago

Patch set 3 for branch master of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/c/Packages/TYPO3.CMS/+/61443

Actions #14

Updated by Gerrit Code Review about 5 years ago

Patch set 4 for branch master of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/c/Packages/TYPO3.CMS/+/61443

Actions #15

Updated by Gerrit Code Review almost 5 years ago

Patch set 5 for branch master of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/c/Packages/TYPO3.CMS/+/61443

Actions #16

Updated by Gerrit Code Review almost 5 years ago

Patch set 6 for branch master of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/c/Packages/TYPO3.CMS/+/61443

Actions #17

Updated by Benni Mack over 4 years ago

Actions #18

Updated by Gerrit Code Review over 3 years ago

Patch set 7 for branch master of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/c/Packages/TYPO3.CMS/+/61443

Actions #19

Updated by Gerrit Code Review over 3 years ago

Patch set 8 for branch master of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/c/Packages/TYPO3.CMS/+/61443

Actions #20

Updated by Gerrit Code Review over 3 years ago

Patch set 9 for branch master of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/c/Packages/TYPO3.CMS/+/61443

Actions #21

Updated by Gerrit Code Review almost 3 years ago

Patch set 10 for branch main of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/c/Packages/TYPO3.CMS/+/61443

Actions #22

Updated by Gerrit Code Review over 2 years ago

Patch set 11 for branch main of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/c/Packages/TYPO3.CMS/+/61443

Actions #23

Updated by Gerrit Code Review over 2 years ago

Patch set 12 for branch main of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/c/Packages/TYPO3.CMS/+/61443

Actions #24

Updated by Benni Mack over 1 year ago

  • Status changed from Under Review to New
Actions

Also available in: Atom PDF