[limb-svn] r6809 - in 3.x/trunk/limb/active_record: src tests/cases

svn at limb-project.com svn at limb-project.com
Wed Feb 27 14:45:36 MSK 2008


Author: serega
Date: 2008-02-27 14:45:36 +0300 (Wed, 27 Feb 2008)
New Revision: 6809
URL: http://fisheye.limb-project.com/changelog/limb/?cs=6809

Modified:
   3.x/trunk/limb/active_record/src/lmbARManyToManyCollection.class.php
   3.x/trunk/limb/active_record/tests/cases/lmbARManyToManyCollectionTest.class.php
Log:
-- many-to-many relation now only inserts new records and removes removed links only. In the prev. revision many-to-many recreated all links every time

Modified: 3.x/trunk/limb/active_record/src/lmbARManyToManyCollection.class.php
===================================================================
--- 3.x/trunk/limb/active_record/src/lmbARManyToManyCollection.class.php	2008-02-27 11:43:56 UTC (rev 6808)
+++ 3.x/trunk/limb/active_record/src/lmbARManyToManyCollection.class.php	2008-02-27 11:45:36 UTC (rev 6809)
@@ -57,11 +57,37 @@
 
   function set($objects)
   {
-    $this->removeAll();
+    $existing_records = $this->_getExistingRecords($objects);
+    $linked_objects_ids = array_keys($existing_records);
+    
     foreach($objects as $object)
-      $this->add($object);
+    {
+      $id = $object->getId();
+      if(!isset($existing_records[$id]))
+        $this->add($object);
+      else
+        unset($existing_records[$id]);
+    }
+    
+    $to_remove_ids = array_keys($existing_records);
+    if(count($to_remove_ids))
+    {
+      $table = new lmbTableGateway($this->relation_info['table'], $this->conn);
+      $table->delete(lmbSQLCriteria :: in($this->relation_info['foreign_field'], $to_remove_ids));
+    }
   }
-
+  
+  protected function _getExistingRecords($objects)
+  {
+    $table = new lmbTableGateway($this->relation_info['table'], $this->conn);
+    $criteria = new lmbSQLCriteria();
+    $criteria->addAnd(new lmbSQLFieldCriteria($this->relation_info['field'], $this->owner->getId()));
+    $criteria->addAnd(new lmbSQLFieldCriteria($this->relation_info['foreign_field'], null, lmbSQLFieldCriteria :: IS_NOT_NULL));
+    $existing_records = $table->select($criteria);
+    
+    return lmbCollection :: toFlatArray($existing_records, $this->relation_info['foreign_field']);
+  }
+  
   protected function _removeRelatedRecords()
   {
     $table = new lmbTableGateway($this->relation_info['table'], $this->conn);
@@ -74,8 +100,8 @@
 
   protected function _saveObject($object, $error_list = null)
   {
+    $object->save($error_list);
     $table = new lmbTableGateway($this->relation_info['table'], $this->conn);
-    $object->save($error_list);
     $table->insert(array($this->relation_info['field'] => $this->owner->getId(),
                          $this->relation_info['foreign_field'] => $object->getId()));
   }

Modified: 3.x/trunk/limb/active_record/tests/cases/lmbARManyToManyCollectionTest.class.php
===================================================================
--- 3.x/trunk/limb/active_record/tests/cases/lmbARManyToManyCollectionTest.class.php	2008-02-27 11:43:56 UTC (rev 6808)
+++ 3.x/trunk/limb/active_record/tests/cases/lmbARManyToManyCollectionTest.class.php	2008-02-27 11:45:36 UTC (rev 6809)
@@ -498,6 +498,30 @@
     $this->assertEqual($collection->at(1)->getTitle(), $group3->getTitle());
   }
   
+  function testSetDontReInsertSameRecordsIfTheyExists()
+  {
+    $group1 = $this->_initGroup();
+    $group2 = $this->_initGroup();
+    $group3 = $this->_initGroup();
+    $group4 = $this->_initGroup();
+
+    $user = $this->_createUserAndSave(array($group1, $group2, $group3));
+    
+    $table = lmbDBAL :: table('user2group_for_test', $this->conn);
+    $records = $table->select()->getArray();
+    $this->assertEqual(count($records), 3);
+    
+    $collection = new lmbARManyToManyCollection('groups', $user);
+    $collection->set(array($group1, $group2, $group3, $group4));
+
+    $new_records = $table->select()->getArray();
+    $this->assertEqual(count($new_records), 4);
+    $this->assertEqual($records[0]['id'], $new_records[0]['id']);
+    $this->assertEqual($records[1]['id'], $new_records[1]['id']);
+    $this->assertEqual($records[2]['id'], $new_records[2]['id']);
+    $this->assertEqual($new_records[3]['user_id'], $user->getId());
+  }
+  
   function testRemove_DeleteRecordAndCleanUpInternalIterator()
   {
     $group1 = $this->_initGroup();



More information about the limb-svn mailing list