Browse Source

Fix fatal errors when cascaded deletes are used with MySQL.

We cannot use unbuffered queries to delete has many associations as the
nested delete cannot be excuted while the previous cursor is still open.

Refs #5637
Mark Story 11 years ago
parent
commit
fd4c30d5fa

+ 1 - 1
src/ORM/Association/DependentDeleteTrait.php

@@ -44,7 +44,7 @@ trait DependentDeleteTrait
         $conditions = array_combine($foreignKey, $entity->extract($primaryKey));
 
         if ($this->_cascadeCallbacks) {
-            $query = $this->find('all')->where($conditions)->bufferResults(false);
+            $query = $this->find('all')->where($conditions);
             foreach ($query as $related) {
                 $table->delete($related, $options);
             }

+ 2 - 4
tests/TestCase/ORM/Association/HasManyTest.php

@@ -480,10 +480,8 @@ class HasManyTest extends TestCase
         $query->expects($this->any())
             ->method('getIterator')
             ->will($this->returnValue($iterator));
-        $query->expects($this->once())
-            ->method('bufferResults')
-            ->with(false)
-            ->will($this->returnSelf());
+        $query->expects($this->never())
+            ->method('bufferResults');
 
         $this->article->expects($this->once())
             ->method('find')

+ 20 - 2
tests/TestCase/ORM/TableTest.php

@@ -1965,8 +1965,7 @@ class TableTest extends TestCase
             'dependent' => true,
         ]);
 
-        $query = $table->find('all')->where(['id' => 1]);
-        $entity = $query->first();
+        $entity = $table->get(1);
         $result = $table->delete($entity);
 
         $articles = $table->association('articles')->target();
@@ -1979,6 +1978,25 @@ class TableTest extends TestCase
     }
 
     /**
+     * Test delete with dependent records
+     *
+     * @return void
+     */
+    public function testDeleteDependentHasMany()
+    {
+        $table = TableRegistry::get('authors');
+        $table->hasMany('articles', [
+            'foreignKey' => 'author_id',
+            'dependent' => true,
+            'cascadeCallbacks' => true,
+        ]);
+
+        $entity = $table->get(1);
+        $result = $table->delete($entity);
+        $this->assertTrue($result);
+    }
+
+    /**
      * Test delete with dependent = false does not cascade.
      *
      * @return void