[FEATURE] Add SELECT_mm_query to DatabaseConnection 11/42811/4
authorMorton Jonuschat <m.jonuschat@mojocode.de>
Fri, 21 Aug 2015 12:40:52 +0000 (14:40 +0200)
committerChristian Kuhn <lolli@schwarzbu.ch>
Tue, 15 Sep 2015 09:19:08 +0000 (11:19 +0200)
Query building and execution has been separated to facilitate inspection
of the generated statements as well as enabling the usage of the
statement building in EXT:dbal.

Resolves: #19494
Resolves: #20892
Releases: master
Change-Id: Ibd5accbf2c2caa9cb9db42dbcf49051d4e113003
Reviewed-on: http://review.typo3.org/42811
Reviewed-by: Mathias Brodala <mbrodala@pagemachine.de>
Tested-by: Mathias Brodala <mbrodala@pagemachine.de>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
typo3/sysext/core/Classes/Database/DatabaseConnection.php
typo3/sysext/core/Documentation/Changelog/master/Feature-19494-AddSELECTmmQueryMethodToDatabaseConnection.rst [new file with mode: 0644]
typo3/sysext/core/Tests/Unit/Database/DatabaseConnectionTest.php
typo3/sysext/dbal/Tests/Unit/Database/DatabaseConnectionTest.php

index 6c6c2bf..47b6d42 100644 (file)
@@ -335,15 +335,8 @@ class DatabaseConnection {
         * @see exec_SELECTquery()
         */
        public function exec_SELECT_mm_query($select, $local_table, $mm_table, $foreign_table, $whereClause = '', $groupBy = '', $orderBy = '', $limit = '') {
-               $foreign_table_as = $foreign_table == $local_table ? $foreign_table . StringUtility::getUniqueId('_join') : '';
-               $mmWhere = $local_table ? $local_table . '.uid=' . $mm_table . '.uid_local' : '';
-               $mmWhere .= ($local_table and $foreign_table) ? ' AND ' : '';
-               $tables = ($local_table ? $local_table . ',' : '') . $mm_table;
-               if ($foreign_table) {
-                       $mmWhere .= ($foreign_table_as ?: $foreign_table) . '.uid=' . $mm_table . '.uid_foreign';
-                       $tables .= ',' . $foreign_table . ($foreign_table_as ? ' AS ' . $foreign_table_as : '');
-               }
-               return $this->exec_SELECTquery($select, $tables, $mmWhere . ' ' . $whereClause, $groupBy, $orderBy, $limit);
+               $queryParts = $this->getSelectMmQueryParts($select, $local_table, $mm_table, $foreign_table, $whereClause, $groupBy, $orderBy, $limit);
+               return $this->exec_SELECT_queryArray($queryParts);
        }
 
        /**
@@ -658,6 +651,28 @@ class DatabaseConnection {
        }
 
        /**
+        * Creates a SELECT query, selecting fields ($select) from two/three tables joined
+        * Use $mm_table together with $local_table or $foreign_table to select over two tables. Or use all three tables to select the full MM-relation.
+        * The JOIN is done with [$local_table].uid <--> [$mm_table].uid_local  / [$mm_table].uid_foreign <--> [$foreign_table].uid
+        * The function is very useful for selecting MM-relations between tables adhering to the MM-format used by TCE (TYPO3 Core Engine). See the section on $GLOBALS['TCA'] in Inside TYPO3 for more details.
+        *
+        * @param string $select See exec_SELECT_mm_query()
+        * @param string $local_table See exec_SELECT_mm_query()
+        * @param string $mm_table See exec_SELECT_mm_query()
+        * @param string $foreign_table See exec_SELECT_mm_query()
+        * @param string $whereClause See exec_SELECT_mm_query()
+        * @param string $groupBy See exec_SELECT_mm_query()
+        * @param string $orderBy See exec_SELECT_mm_query()
+        * @param string $limit See exec_SELECT_mm_query()
+        * @return string Full SQL query for SELECT
+        * @see SELECTquery()
+        */
+       public function SELECT_mm_query($select, $local_table, $mm_table, $foreign_table, $whereClause = '', $groupBy = '', $orderBy = '', $limit = '') {
+               $queryParts = $this->getSelectMmQueryParts($select, $local_table, $mm_table, $foreign_table, $whereClause, $groupBy, $orderBy, $limit);
+               return $this->SELECTquery($queryParts['SELECT'], $queryParts['FROM'], $queryParts['WHERE'], $queryParts['GROUPBY'], $queryParts['ORDERBY'], $queryParts['LIMIT']);
+       }
+
+       /**
         * Creates a TRUNCATE TABLE SQL-statement
         *
         * @param string $table See exec_TRUNCATEquery()
@@ -980,6 +995,41 @@ class DatabaseConnection {
                return self::$dateTimeFormats;
        }
 
+       /**
+        * Creates SELECT query components for selecting fields ($select) from two/three tables joined
+        * Use $mm_table together with $local_table or $foreign_table to select over two tables. Or use all three tables to select the full MM-relation.
+        * The JOIN is done with [$local_table].uid <--> [$mm_table].uid_local  / [$mm_table].uid_foreign <--> [$foreign_table].uid
+        * The function is very useful for selecting MM-relations between tables adhering to the MM-format used by TCE (TYPO3 Core Engine). See the section on $GLOBALS['TCA'] in Inside TYPO3 for more details.
+        *
+        * @param string $select See exec_SELECT_mm_query()
+        * @param string $local_table See exec_SELECT_mm_query()
+        * @param string $mm_table See exec_SELECT_mm_query()
+        * @param string $foreign_table See exec_SELECT_mm_query()
+        * @param string $whereClause See exec_SELECT_mm_query()
+        * @param string $groupBy See exec_SELECT_mm_query()
+        * @param string $orderBy See exec_SELECT_mm_query()
+        * @param string $limit See exec_SELECT_mm_query()
+        * @return array SQL query components
+        */
+       protected function getSelectMmQueryParts($select, $local_table, $mm_table, $foreign_table, $whereClause = '', $groupBy = '', $orderBy = '', $limit = '') {
+               $foreign_table_as = $foreign_table == $local_table ? $foreign_table . StringUtility::getUniqueId('_join') : '';
+               $mmWhere = $local_table ? $local_table . '.uid=' . $mm_table . '.uid_local' : '';
+               $mmWhere .= ($local_table and $foreign_table) ? ' AND ' : '';
+               $tables = ($local_table ? $local_table . ',' : '') . $mm_table;
+               if ($foreign_table) {
+                       $mmWhere .= ($foreign_table_as ?: $foreign_table) . '.uid=' . $mm_table . '.uid_foreign';
+                       $tables .= ',' . $foreign_table . ($foreign_table_as ? ' AS ' . $foreign_table_as : '');
+               }
+               return array(
+                       'SELECT' => $select,
+                       'FROM' => $tables,
+                       'WHERE' => $mmWhere . ' ' . $whereClause,
+                       'GROUPBY' => $groupBy,
+                       'ORDERBY' => $orderBy,
+                       'LIMIT' => $limit
+               );
+       }
+
        /**************************************
         *
         * MySQL(i) wrapper functions
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-19494-AddSELECTmmQueryMethodToDatabaseConnection.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-19494-AddSELECTmmQueryMethodToDatabaseConnection.rst
new file mode 100644 (file)
index 0000000..a7253f5
--- /dev/null
@@ -0,0 +1,16 @@
+================================================================
+Feature: #19494 - Add SELECTmmQuery method to DatabaseConnection
+================================================================
+
+Description
+===========
+
+A new method ``SELECT_mm_query`` has been added to the ``DatabaseConnection`` class. This method has been extracted from ``exec_SELECT_mm_query`` to separate the building and execution of M:M queries.
+
+This allows enables the use of the query building in the database abstraction layer.
+
+Example:
+
+.. code-block:: php
+
+  $query = SELECT_mm_query('*', 'table1', 'table1_table2_mm', 'table2', 'AND table1.uid = 1', '', 'table1.title DESC');
index ec73cc9..c5eb890 100644 (file)
@@ -370,4 +370,14 @@ class DatabaseConnectionTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
                $this->assertEquals($expectedResult, $sanitizedArray);
        }
 
+       /**
+        * @test
+        */
+       public function sqlForSelectMmQuery() {
+               $subject = new \TYPO3\CMS\Core\Database\DatabaseConnection();
+               $result = $subject->SELECT_mm_query('*', 'sys_category', 'sys_category_record_mm', 'tt_content', 'AND sys_category.uid = 1', '', 'sys_category.title DESC');
+               $expected = 'SELECT * FROM sys_category,sys_category_record_mm,tt_content WHERE sys_category.uid=sys_category_record_mm.uid_local AND tt_content.uid=sys_category_record_mm.uid_foreign AND sys_category.uid = 1 ORDER BY sys_category.title DESC';
+               $this->assertEquals($expected, $result);
+       }
+
 }
index fb7e9a1..f3a3ca9 100644 (file)
@@ -206,6 +206,15 @@ class DatabaseConnectionTest extends AbstractTestCase {
 
        /**
         * @test
+        */
+       public function sqlForSelectMmQuery() {
+               $result = $this->subject->SELECT_mm_query('*', 'sys_category', 'sys_category_record_mm', 'tt_content', 'AND sys_category.uid = 1', '', 'sys_category.title DESC');
+               $expected = 'SELECT * FROM sys_category,sys_category_record_mm,tt_content WHERE sys_category.uid=sys_category_record_mm.uid_local AND tt_content.uid=sys_category_record_mm.uid_foreign AND sys_category.uid = 1 ORDER BY sys_category.title DESC';
+               $this->assertEquals($expected, $result);
+       }
+
+       /**
+        * @test
         * @see http://forge.typo3.org/issues/16708
         */
        public function minFunctionAndInOperatorCanBeParsed() {