Added feature #13209: MySQL extended INSERT statements cannot be parsed
authorXavier Perseguers <typo3@perseguers.ch>
Sun, 7 Feb 2010 13:14:39 +0000 (13:14 +0000)
committerXavier Perseguers <typo3@perseguers.ch>
Sun, 7 Feb 2010 13:14:39 +0000 (13:14 +0000)
git-svn-id: https://svn.typo3.org/TYPO3v4/Extensions/dbal/trunk@29765 735d13b6-9817-0410-8766-e36946ffe9aa

typo3/sysext/dbal/ChangeLog
typo3/sysext/dbal/class.ux_t3lib_sqlparser.php
typo3/sysext/dbal/tests/db_oracle_testcase.php
typo3/sysext/dbal/tests/sqlparser_general_testcase.php

index 7789038..5481dff 100644 (file)
@@ -1,3 +1,7 @@
+2010-02-07  Xavier Perseguers  <typo3@perseguers.ch>
+
+       * Added feature #13209: MySQL extended INSERT statements cannot be parsed
+
 2010-02-06  Xavier Perseguers  <typo3@perseguers.ch>
 
        * Added unit tests for bug #13430: Cannot parse INSERT when VALUES has no space before left parenthesis
index d402ef2..24b804f 100644 (file)
@@ -163,7 +163,7 @@ class ux_t3lib_sqlparser extends t3lib_sqlparser {
         * Compiles an INSERT statement from components array
         *
         * @param array Array of SQL query components
-        * @return string SQL INSERT query
+        * @return string SQL INSERT query / array
         * @see parseINSERT()
         */
        function compileINSERT($components) {
@@ -172,18 +172,25 @@ class ux_t3lib_sqlparser extends t3lib_sqlparser {
                                $query = parent::compileINSERT($components);
                                break;
                        case 'adodb':
+                               $values = array();
+
                                if (isset($components['VALUES_ONLY']) && is_array($components['VALUES_ONLY'])) {
-                                       $fields = $GLOBALS['TYPO3_DB']->cache_fieldType[$components['TABLE']];
-                                       $fc = 0;
-                                       foreach ($fields as $fn => $fd) {
-                                               $query[$fn] = $components['VALUES_ONLY'][$fc++][0];
-                                       }
+                                       $valuesComponents = $components['EXTENDED'] === '1' ? $components['VALUES_ONLY'] : array($components['VALUES_ONLY']);
+                                       $tableFields = array_keys($GLOBALS['TYPO3_DB']->cache_fieldType[$components['TABLE']]);
                                } else {
-                                               // Initialize:
-                                       foreach ($components['FIELDS'] as $fN => $fV) {
-                                               $query[$fN]=$fV[0];
+                                       $valuesComponents = $components['EXTENDED'] === '1' ? $components['FIELDS'] : array($components['FIELDS']);
+                                       $tableFields = array_keys($valuesComponents[0]);
+                               }
+
+                               foreach ($valuesComponents as $valuesComponent) {
+                                       $fields = array();
+                                       $fc = 0;
+                                       foreach ($valuesComponent as $fV) {
+                                               $fields[$tableFields[$fc++]] = $fV[0];
                                        }
+                                       $values[] = $fields;
                                }
+                               $query = count($values) === 1 ? $values[0] : $values;
                                break;
                }
 
index 54f1860..c49736d 100644 (file)
@@ -139,6 +139,48 @@ class db_oracle_testcase extends BaseTestCase {
                $this->assertEquals($expected, $query);
        }
 
+       /**
+        * @test
+        */
+       public function canCompileInsertWithFields() {
+               $parseString = 'INSERT INTO static_territories (uid, pid, tr_iso_nr, tr_parent_iso_nr, tr_name_en) ';
+               $parseString .= "VALUES ('1', '0', '2', '0', 'Africa');";
+               $components = $GLOBALS['TYPO3_DB']->SQLparser->_callRef('parseINSERT', $parseString);
+
+               $this->assertTrue(is_array($components), $components);
+               $insert = $GLOBALS['TYPO3_DB']->SQLparser->_callRef('compileINSERT', $components);
+
+               $expected = array(
+                       'uid' => '1',
+                       'pid' => '0',
+                       'tr_iso_nr' => '2',
+                       'tr_parent_iso_nr' => '0',
+                       'tr_name_en' => 'Africa',
+               );
+               $this->assertEquals($expected, $insert);
+       }
+
+       /**
+        * @test
+        * http://bugs.typo3.org/view.php?id=13209
+        */
+       public function canCompileExtendedInsert() {
+               $parseString = "INSERT INTO static_territories VALUES ('1', '0', '2', '0', 'Africa'),('2', '0', '9', '0', 'Oceania')," .
+                       "('3', '0', '19', '0', 'Americas'),('4', '0', '142', '0', 'Asia');";
+               $components = $GLOBALS['TYPO3_DB']->SQLparser->_callRef('parseINSERT', $parseString);
+
+               $this->assertTrue(is_array($components), $components);
+               $insert = $GLOBALS['TYPO3_DB']->SQLparser->_callRef('compileINSERT', $components);
+
+               $this->assertEquals(4, count($insert));
+
+               for ($i = 0; $i < count($insert); $i++) {
+                       foreach (t3lib_div::trimExplode(',', 'uid,pid,tr_iso_nr,tr_parent_iso_nr,tr_name_en') as $field) {
+                               $this->assertTrue(isset($insert[$i][$field]), 'Could not find ' . $field . ' column');
+                       }
+               }
+       }
+
        ///////////////////////////////////////
        // Tests concerning quoting
        ///////////////////////////////////////
index e520488..84afaca 100644 (file)
@@ -234,6 +234,53 @@ class sqlparser_general_testcase extends BaseTestCase {
                $this->assertEquals($expected, $insert);
        }
 
+       /**
+        * @test
+        */
+       public function canParseInsertWithFields() {
+               $parseString = 'INSERT INTO static_territories (uid, pid, tr_iso_nr, tr_parent_iso_nr, tr_name_en) ';
+               $parseString .= "VALUES ('1', '0', '2', '0', 'Africa');";
+               $components = $this->fixture->_callRef('parseINSERT', $parseString);
+
+               $this->assertTrue(is_array($components), $components);
+               $insert = $this->cleanSql($this->fixture->compileINSERT($components));
+               $expected = 'INSERT INTO static_territories (uid, pid, tr_iso_nr, tr_parent_iso_nr, tr_name_en) ';
+               $expected .= "VALUES ('1', '0', '2', '0', 'Africa')";
+               $this->assertEquals($expected, $insert);
+       }
+
+       /**
+        * @test
+        * http://bugs.typo3.org/view.php?id=13209
+        */
+       public function canParseExtendedInsert() {
+               $parseString = "INSERT INTO static_territories VALUES ('1', '0', '2', '0', 'Africa'),('2', '0', '9', '0', 'Oceania')," .
+                       "('3', '0', '19', '0', 'Americas'),('4', '0', '142', '0', 'Asia');";
+               $components = $this->fixture->_callRef('parseINSERT', $parseString);
+
+               $this->assertTrue(is_array($components), $components);
+               $insert = $this->cleanSql($this->fixture->compileINSERT($components));
+               $expected = "INSERT INTO static_territories VALUES ('1', '0', '2', '0', 'Africa'), ('2', '0', '9', '0', 'Oceania'), " .
+                       "('3', '0', '19', '0', 'Americas'), ('4', '0', '142', '0', 'Asia')";
+               $this->assertEquals($expected, $insert);
+       }
+
+       /**
+        * @test
+        * http://bugs.typo3.org/view.php?id=13209
+        */
+       public function canParseExtendedInsertWithFields() {
+               $parseString = 'INSERT INTO static_territories (uid, pid, tr_iso_nr, tr_parent_iso_nr, tr_name_en) ';
+               $parseString .= "VALUES ('1', '0', '2', '0', 'Africa'),('2', '0', '9', '0', 'Oceania');";
+               $components = $this->fixture->_callRef('parseINSERT', $parseString);
+
+               $this->assertTrue(is_array($components), $components);
+               $insert = $this->cleanSql($this->fixture->compileINSERT($components));
+               $expected = 'INSERT INTO static_territories (uid, pid, tr_iso_nr, tr_parent_iso_nr, tr_name_en) ';
+               $expected .= "VALUES ('1', '0', '2', '0', 'Africa'), ('2', '0', '9', '0', 'Oceania')";
+               $this->assertEquals($expected, $insert);
+       }
+
        ///////////////////////////////////////
        // Tests concerning JOINs
        ///////////////////////////////////////