Ver Fonte

ZF-8597 : fix insert and update with long identifier with Oracle

git-svn-id: http://framework.zend.com/svn/framework/standard/trunk@21108 44c647ce-9c0f-0410-b52a-842ac1e357ba
mikaelkael há 16 anos atrás
pai
commit
978d7d4089

+ 21 - 4
library/Zend/Db/Adapter/Abstract.php

@@ -526,13 +526,27 @@ abstract class Zend_Db_Adapter_Abstract
         // extract and quote col names from the array keys
         $cols = array();
         $vals = array();
+        $i = 0;
         foreach ($bind as $col => $val) {
             $cols[] = $this->quoteIdentifier($col, true);
             if ($val instanceof Zend_Db_Expr) {
                 $vals[] = $val->__toString();
                 unset($bind[$col]);
             } else {
-                $vals[] = '?';
+                if ($this->supportsParameters('positional')) {
+                    $vals[] = '?';
+                } else {
+                    if ($this->supportsParameters('named')) {
+                        unset($bind[$col]);
+                        $bind[':col'.$i] = $val;
+                        $vals[] = ':col'.$i;
+                        $i++;
+                    } else {
+                        /** @see Zend_Db_Adapter_Exception */
+                        require_once 'Zend/Db/Adapter/Exception.php';
+                        throw new Zend_Db_Adapter_Exception(get_class($this) ." doesn't support positional or named binding");
+                    }
+                }
             }
         }
 
@@ -543,7 +557,10 @@ abstract class Zend_Db_Adapter_Abstract
              . 'VALUES (' . implode(', ', $vals) . ')';
 
         // execute the statement and return the number of affected rows
-        $stmt = $this->query($sql, array_values($bind));
+        if ($this->supportsParameters('positional')) {
+            $bind = array_values($bind);
+        }
+        $stmt = $this->query($sql, $bind);
         $result = $stmt->rowCount();
         return $result;
     }
@@ -574,8 +591,8 @@ abstract class Zend_Db_Adapter_Abstract
                 } else {
                     if ($this->supportsParameters('named')) {
                         unset($bind[$col]);
-                        $bind[':'.$col.$i] = $val;
-                        $val = ':'.$col.$i;
+                        $bind[':col'.$i] = $val;
+                        $val = ':col'.$i;
                         $i++;
                     } else {
                         /** @see Zend_Db_Adapter_Exception */

+ 0 - 40
library/Zend/Db/Adapter/Oracle.php

@@ -603,46 +603,6 @@ class Zend_Db_Adapter_Oracle extends Zend_Db_Adapter_Abstract
     }
 
     /**
-     * Inserts a table row with specified data.
-     *
-     * Oracle does not support anonymous ('?') binds.
-     *
-     * @param mixed $table The table to insert data into.
-     * @param array $bind Column-value pairs.
-     * @return int The number of affected rows.
-     */
-    public function insert($table, array $bind)
-    {
-        $i = 0;
-        // extract and quote col names from the array keys
-        $cols = array();
-        $vals = array();
-        foreach ($bind as $col => $val) {
-            $cols[] = $this->quoteIdentifier($col, true);
-            if ($val instanceof Zend_Db_Expr) {
-                $vals[] = $val->__toString();
-                unset($bind[$col]);
-            } else {
-                $vals[] = ':'.$col.$i;
-                unset($bind[$col]);
-                $bind[':'.$col.$i] = $val;
-            }
-            $i++;
-        }
-
-        // build the statement
-        $sql = "INSERT INTO "
-             . $this->quoteIdentifier($table, true)
-             . ' (' . implode(', ', $cols) . ') '
-             . 'VALUES (' . implode(', ', $vals) . ')';
-
-        // execute the statement and return the number of affected rows
-        $stmt = $this->query($sql, $bind);
-        $result = $stmt->rowCount();
-        return $result;
-    }
-
-    /**
      * Check if the adapter supports real SQL parameters.
      *
      * @param string $type 'positional' or 'named'

+ 40 - 0
tests/Zend/Db/Adapter/TestCommon.php

@@ -1781,6 +1781,46 @@ abstract class Zend_Db_Adapter_TestCommon extends Zend_Db_TestSetup
         $this->assertEquals(array_fill(0, 4, 'EMPTY'), $value);
     }
 
+    /**
+     * @group ZF-8597
+     * Oracle is limited to 30 characters for an identifier
+     */
+    public function testAdapterUpdateWithLongColumnIdentifier()
+    {
+        // create test table using no identifier quoting
+        $this->_util->createTable('zf_longidentifier', array(
+            'id'    => 'INTEGER NOT NULL',
+            'veryveryveryverylongidentifier' => 'INTEGER NOT NULL'
+        ));
+        $tableName = $this->_util->getTableName('zf_longidentifier');
+
+        // insert into the table
+        $this->_db->insert($tableName, array(
+            'id' => 1,
+            'veryveryveryverylongidentifier' => 2
+        ));
+
+        //try to update
+        $this->_db->update($tableName,
+                           array('veryveryveryverylongidentifier' => 3),
+                           array($this->_db->quoteIdentifier('id') . ' = 1'));
+
+        // check if the row was inserted as expected
+        $select = $this->_db->select()->from($tableName, array('id', 'veryveryveryverylongidentifier'));
+
+        $stmt = $this->_db->query($select);
+        $fetched = $stmt->fetchAll(Zend_Db::FETCH_NUM);
+        $a = array(
+            0 => array(0 => 1, 1 => 3)
+        );
+        $this->assertEquals($a, $fetched,
+            'result of query not as expected');
+
+        // clean up
+        unset($stmt);
+        $this->_util->dropTable($tableName);
+    }
+
     protected function _testAdapterAlternateStatement($stmtClass)
     {
         $ip = get_include_path();