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

svn at limb-project.com svn at limb-project.com
Tue Jun 5 15:38:45 MSD 2007


Author: serega
Date: 2007-06-05 15:38:45 +0400 (Tue, 05 Jun 2007)
New Revision: 5938
URL: http://fisheye.limb-project.com/changelog/limb/?cs=5938

Added:
   3.x/trunk/limb/active_record/tests/cases/lmbActiveRecordRelationsDefinitionMethodsTest.class.php
Modified:
   3.x/trunk/limb/active_record/src/lmbAROneToManyCollection.class.php
   3.x/trunk/limb/active_record/src/lmbActiveRecord.class.php
   3.x/trunk/limb/active_record/tests/cases/lmbActiveRecordOneToManyRelationsTest.class.php
   3.x/trunk/limb/active_record/tests/cases/lmbActiveRecordOneToOneRelationsTest.class.php
Log:
-- lmbActiveRecord :: _defineRelations() relations added. This method is called in constructor.
-- lmbActiveRecord :: _hasOne($relation_name, $info), _hasMany($relation_name, $info), _hasManyToMany($relation_name, $info), _belongsTo($relation_name, $info), _composedOf($relation_name, $info) methods added what can be used in _defineRelations() methods. This is convenient in some cases with complex inheritance
-- lmbActiveRecord "has_one" relation now can have "nullify" property. If parent object is removed all child objects will have null is appropriate field in db table.
-- lmbActiveRecord "belongs_to" relation now nullifies appropriate field in parent object record in db table by default. Be sure to use "can_be_null" with "true" value in relation info in parent class (has_one side of one2one relation).

Modified: 3.x/trunk/limb/active_record/src/lmbAROneToManyCollection.class.php
===================================================================
--- 3.x/trunk/limb/active_record/src/lmbAROneToManyCollection.class.php	2007-06-05 07:13:46 UTC (rev 5937)
+++ 3.x/trunk/limb/active_record/src/lmbAROneToManyCollection.class.php	2007-06-05 11:38:45 UTC (rev 5938)
@@ -1,13 +1,13 @@
 <?php
-/*
- * Limb PHP Framework
- *
- * @link http://limb-project.com
- *
- * @copyright  Copyright &copy; 2004-2007 BIT
- * @license    LGPL http://www.gnu.org/copyleft/lesser.html
- * @version    $Id$
- * @package    $package$
+/*
+ * Limb PHP Framework
+ *
+ * @link http://limb-project.com
+ *
+ * @copyright  Copyright &copy; 2004-2007 BIT
+ * @license    LGPL http://www.gnu.org/copyleft/lesser.html
+ * @version    $Id$
+ * @package    $package$
  */
 lmb_require('limb/active_record/src/lmbARRelationCollection.class.php');
 
@@ -65,6 +65,17 @@
     $object->set($this->relation_info['field'], $this->owner->getId());
     $object->save($error_list);
   }
+
+  function nullify()
+  {
+    $rs = $this->find();
+    foreach($rs as $object)
+    {
+      $object->set($this->relation_info['field'], null);
+      $object->save();
+    }
+
+  }
 }
 
 ?>

Modified: 3.x/trunk/limb/active_record/src/lmbActiveRecord.class.php
===================================================================
--- 3.x/trunk/limb/active_record/src/lmbActiveRecord.class.php	2007-06-05 07:13:46 UTC (rev 5937)
+++ 3.x/trunk/limb/active_record/src/lmbActiveRecord.class.php	2007-06-05 11:38:45 UTC (rev 5938)
@@ -163,6 +163,8 @@
   {
     parent :: __construct();
 
+    $this->_defineRelations();
+
     $this->_db_meta_info = lmbToolkit :: instance()->getActiveRecordMetaInfo($this);
 
     $this->_db_table = $this->_db_meta_info->getDbTable();
@@ -224,6 +226,41 @@
   {
     return $this->_error_list;
   }
+
+  protected function _defineRelations()
+  {
+  }
+
+  protected function _hasOne($relation_name, $info)
+  {
+    $this->_has_one[$relation_name] = $info;
+  }
+
+  protected function _hasMany($relation_name, $info)
+  {
+    $this->_has_many[$relation_name] = $info;
+  }
+
+  protected function _hasManyToMany($relation_name, $info)
+  {
+    $this->_has_many_to_many[$relation_name] = $info;
+  }
+
+  protected function _belongsTo($relation_name, $info)
+  {
+    $this->_belongs_to[$relation_name] = $info;
+  }
+
+  protected function _manyBelongsTo($relation_name, $info)
+  {
+    $this->_many_belongs_to[$relation_name] = $info;
+  }
+
+  protected function _composedOf($relation_name, $info)
+  {
+    $this->_composed_of[$relation_name] = $info;
+  }
+
   /**
    *  Returns relation info array defined during class declaration
    *  @return array
@@ -338,6 +375,14 @@
 
   protected function _savePreRelationObject($property, $info, $save_relation_obj = true)
   {
+    if($this->isDirtyProperty($info['field']))
+    {
+      $value = $this->_getRaw($info['field']);
+      if(is_null($value))
+        $this->_setRaw($property, null);
+      return;
+    }
+
     $object = $this->_getRaw($property);
     if(is_object($object))
     {
@@ -1389,6 +1434,7 @@
     $this->_removeOneToOneObjects();
     $this->_removeOneToManyObjects();
     $this->_removeManyToManyRecords();
+    $this->_removeBelongsToRelations();
 
     $this->_deleteDbRecord();
 
@@ -1453,7 +1499,14 @@
   {
     foreach($this->_has_many as $property => $info)
     {
-      if($collection = $this->get($property))
+      $collection = $this->get($property);
+
+      if(!$collection)
+        continue;
+
+      if(isset($info['nullify']) && $info['nullify'])
+        $collection->nullify();
+      else
         $collection->removeAll();
     }
   }
@@ -1467,6 +1520,18 @@
     }
   }
 
+  protected function _removeBelongsToRelations()
+  {
+    foreach($this->_belongs_to as $property => $info)
+    {
+      if($parent = $this->get($property))
+      {
+        $parent->set($info['field'], null);
+        $parent->save();
+      }
+    }
+  }
+
   protected function _createSQLStatement($sql)
   {
     $conn = lmbToolkit :: instance()->getDefaultDbConnection();

Modified: 3.x/trunk/limb/active_record/tests/cases/lmbActiveRecordOneToManyRelationsTest.class.php
===================================================================
--- 3.x/trunk/limb/active_record/tests/cases/lmbActiveRecordOneToManyRelationsTest.class.php	2007-06-05 07:13:46 UTC (rev 5937)
+++ 3.x/trunk/limb/active_record/tests/cases/lmbActiveRecordOneToManyRelationsTest.class.php	2007-06-05 11:38:45 UTC (rev 5938)
@@ -1,13 +1,13 @@
 <?php
-/*
- * Limb PHP Framework
- *
- * @link http://limb-project.com
- *
- * @copyright  Copyright &copy; 2004-2007 BIT
- * @license    LGPL http://www.gnu.org/copyleft/lesser.html
- * @version    $Id$
- * @package    $package$
+/*
+ * Limb PHP Framework
+ *
+ * @link http://limb-project.com
+ *
+ * @copyright  Copyright &copy; 2004-2007 BIT
+ * @license    LGPL http://www.gnu.org/copyleft/lesser.html
+ * @version    $Id$
+ * @package    $package$
  */
 lmb_require('limb/active_record/src/lmbActiveRecord.class.php');
 lmb_require('limb/active_record/src/lmbAROneToManyCollection.class.php');
@@ -64,6 +64,14 @@
                                                    'collection' => 'LecturesForTestCollectionStub'));
 }
 
+class CourseForTestWithNullifyRelationProperty extends lmbActiveRecord
+{
+  protected $_db_table_name = 'course_for_test';
+  protected $_has_many = array('lectures' => array('field' => 'course_id',
+                                                   'class' => 'LectureForTest',
+                                                   'nullify' => true));
+}
+
 Mock :: generate('LectureForTest', 'MockLectureForTest');
 
 class lmbActiveRecordOneToManyRelationsTest extends UnitTestCase
@@ -306,6 +314,30 @@
     $this->assertNull(lmbActiveRecord :: findFirst('LectureForTest', array('criteria' => 'id = ' . $l2->getId())));
   }
 
+  function testNullifyOnDestroy()
+  {
+    $course = new CourseForTestWithNullifyRelationProperty();
+    $course->setTitle('Super course');
+
+    $l1 = new LectureForTest();
+    $l1->setTitle('Physics');
+    $l2 = new LectureForTest();
+    $l2->setTitle('Math');
+
+    $course->addToLectures($l1);
+    $course->addToLectures($l2);
+
+    $course->save();
+
+    $course2 = new CourseForTestWithNullifyRelationProperty($course->getId());
+    $course2->destroy();
+
+    $lectures = lmbActiveRecord :: find('LectureForTest')->getArray();
+    $this->assertEqual(sizeof($lectures), 2);
+    $this->assertNull($lectures[0]->getCourseId());
+    $this->assertNull($lectures[0]->getCourseId());
+  }
+
   function testUseCustomCollection()
   {
     $course = new CourseForTestWithCustomCollection();

Modified: 3.x/trunk/limb/active_record/tests/cases/lmbActiveRecordOneToOneRelationsTest.class.php
===================================================================
--- 3.x/trunk/limb/active_record/tests/cases/lmbActiveRecordOneToOneRelationsTest.class.php	2007-06-05 07:13:46 UTC (rev 5937)
+++ 3.x/trunk/limb/active_record/tests/cases/lmbActiveRecordOneToOneRelationsTest.class.php	2007-06-05 11:38:45 UTC (rev 5938)
@@ -1,13 +1,13 @@
 <?php
-/*
- * Limb PHP Framework
- *
- * @link http://limb-project.com
- *
- * @copyright  Copyright &copy; 2004-2007 BIT
- * @license    LGPL http://www.gnu.org/copyleft/lesser.html
- * @version    $Id$
- * @package    $package$
+/*
+ * Limb PHP Framework
+ *
+ * @link http://limb-project.com
+ *
+ * @copyright  Copyright &copy; 2004-2007 BIT
+ * @license    LGPL http://www.gnu.org/copyleft/lesser.html
+ * @version    $Id$
+ * @package    $package$
  */
 lmb_require('limb/active_record/src/lmbActiveRecord.class.php');
 lmb_require('limb/dbal/src/lmbSimpleDb.class.php');
@@ -35,6 +35,21 @@
                                                          'cascade_delete' => false));
 }
 
+class PersonForTestWithRequiredSocialSecurity extends lmbActiveRecord
+{
+  protected $_db_table_name = 'person_for_test';
+  protected $_has_one = array('social_security' => array('field' => 'ss_id',
+                                                         'class' => 'SocialSecurityForTest',
+                                                         'can_be_null' => true));
+
+  function _createValidator()
+  {
+    $validator = new lmbValidator();
+    $validator->addRequiredObjectRule('social_security');
+    return $validator;
+  }
+}
+
 class SocialSecurityForTest extends lmbActiveRecord
 {
   protected $_belongs_to = array('person' => array('field' => 'ss_id',
@@ -283,15 +298,51 @@
     $this->assertEqual($ss2->getCode(), $number->getCode());
   }
 
-  function testParentRemovalWithoutChildren()
+  function testChildRemovalNullifyParentField()
   {
+    $number = new SocialSecurityForTest();
+    $number->setCode('099123');
+
     $person = new PersonForTest();
     $person->setName('Jim');
+
+    $person->setSocialSecurity($number);
+    $number->setPerson($person);
     $person->save();
 
-    $person->destroy();
+    $number->destroy();
+
+    $person2 = new PersonForTest($person->getId());
+    $this->assertNull($person2->get('ss_id'));
   }
 
+  function testChildRemovalWithRequiredObjectInParentRelationDefinitionThrowsValidationException()
+  {
+    $number = new SocialSecurityForTest();
+    $number->setCode('099123');
+
+    $person = new PersonForTestWithRequiredSocialSecurity();
+    $person->setName('Jim');
+
+    $person->setSocialSecurity($number);
+    $number->setPerson($person);
+    $person->save();
+
+    try
+    {
+      $number->destroy();
+      $this->assertTrue(false);
+    }
+    catch(lmbValidationException $e)
+    {
+      $this->assertTrue(true);
+    }
+
+    $number2 = lmbActiveRecord :: findFirst('SocialSecurityForTest');
+    $this->assertNotNull($number2, 'Removal should not be finished');
+    $this->assertEqual($number2->getId(), $number->getId());
+  }
+
   function testSettingNullDetachesChildObject()
   {
     $person = new PersonForTest();

Added: 3.x/trunk/limb/active_record/tests/cases/lmbActiveRecordRelationsDefinitionMethodsTest.class.php
===================================================================
--- 3.x/trunk/limb/active_record/tests/cases/lmbActiveRecordRelationsDefinitionMethodsTest.class.php	                        (rev 0)
+++ 3.x/trunk/limb/active_record/tests/cases/lmbActiveRecordRelationsDefinitionMethodsTest.class.php	2007-06-05 11:38:45 UTC (rev 5938)
@@ -0,0 +1,139 @@
+<?php
+/**
+ * Limb Web Application Framework
+ *
+ * @link http://limb-project.com
+ *
+ * @copyright  Copyright &copy; 2004-2007 BIT
+ * @license    LGPL http://www.gnu.org/copyleft/lesser.html
+ * @version    $Id: lmbActiveRecordOneToOneRelationsTest.class.php 5887 2007-05-14 08:27:06Z pachanga $
+ * @package    active_record
+ */
+lmb_require('limb/active_record/src/lmbActiveRecord.class.php');
+lmb_require('limb/dbal/src/lmbSimpleDb.class.php');
+
+class TestOneTableObjectWithRelationsByMethods extends lmbActiveRecord
+{
+  protected $_db_table_name = 'test_one_table_object';
+
+  public $relations = array();
+
+  function _defineRelations()
+  {
+    parent :: _defineRelations();
+
+    $this->_hasOne('has_one_relation', $has_one = array('field' => 'child_id',
+                                                        'class' => 'ChildClass'));
+    $this->relations['has_one_relation'] = $has_one;
+
+
+    $this->_hasOne('other_has_one_relation', $other_has_one = array('field' => 'other_child_id',
+                                                                    'class' => 'OtherChildClass'));
+    $this->relations['other_has_one_relation'] = $other_has_one;
+
+
+    $this->_hasMany('has_many_relation', $has_many = array('field' => 'parent_id',
+                                                           'class' => 'ManyChildClass'));
+    $this->relations['has_many_relation'] = $has_many;
+
+
+    $this->_hasMany('other_has_many_relation', $other_has_many = array('field' => 'other_parent_id',
+                                                                       'class' => 'OtherManyChildClass'));
+    $this->relations['other_has_many_relation'] = $other_has_many;
+
+
+    $this->_hasManyToMany('has_many_to_many_relation',  $many_to_many = array('field' => 'my_id',
+                                                                              'foreign_field' => 'important_id',
+                                                                              'class' => 'ImportantClass',
+                                                                              'table_name' => 'me2importand_class'));
+    $this->relations['has_many_to_many_relation'] = $many_to_many;
+
+
+    $this->_hasManyToMany('other_has_many_to_many_relation',  $other_many_to_many = array('field' => 'my_id',
+                                                                                          'foreign_field' => 'other_important_id',
+                                                                                          'class' => 'OtherImportantClass',
+                                                                                          'table_name' => 'me2other_importand_class'));
+    $this->relations['other_has_many_to_many_relation'] = $other_many_to_many;
+
+
+    $this->_belongsTo('belongs_to_relation', $belongs_to = array('field' => 'my_id',
+                                                                 'class' => 'ParentClass'));
+    $this->relations['belongs_to_relation'] = $belongs_to;
+
+
+    $this->_belongsTo('other_belongs_to_relation', $other_belongs_to = array('field' => 'my_id',
+                                                                             'class' => 'OtherParentClass'));
+    $this->relations['other_belongs_to_relation'] = $other_belongs_to;
+
+
+    $this->_manyBelongsTo('many_belongs_to_relation', $many_belongs_to = array('field' => 'parent_id',
+                                                                               'class' => 'ParentClass'));
+    $this->relations['many_belongs_to_relation'] = $many_belongs_to;
+
+
+    $this->_manyBelongsTo('other_many_belongs_to_relation', $other_many_belongs_to =  array('field' => 'parent_id',
+                                                                                            'class' => 'OtherParentClass'));
+    $this->relations['other_many_belongs_to_relation'] = $other_many_belongs_to;
+
+    $this->_composedOf('value_object', $value_object = array('field' => 'date_start',
+                                                             'class' => 'lmbDate',
+                                                             'getter' => 'getStamp'));
+
+    $this->relations['value_object'] = $value_object;
+
+
+    $this->_composedOf('other_value_object', $other_value_object = array('field' => 'date_end',
+                                                                         'class' => 'lmbDate',
+                                                                         'getter' => 'getStamp'));
+    $this->relations['other_value_object'] = $other_value_object;
+  }
+}
+
+class lmbActiveRecordRelationsDefinitionMethodsTest extends UnitTestCase
+{
+  protected $object;
+
+  function setUp()
+  {
+    $this->object = new TestOneTableObjectWithRelationsByMethods();
+    $this->relations = $this->object->relations;
+  }
+
+  function testHasOne()
+  {
+    $this->assertEqual($this->object->getRelationInfo('has_one_relation'), $this->relations['has_one_relation']);
+    $this->assertEqual($this->object->getRelationInfo('other_has_one_relation'), $this->relations['other_has_one_relation']);
+  }
+
+  function testHasMany()
+  {
+    $this->assertEqual($this->object->getRelationInfo('has_many_relation'), $this->relations['has_many_relation']);
+    $this->assertEqual($this->object->getRelationInfo('other_has_many_relation'), $this->relations['other_has_many_relation']);
+  }
+
+  function testHasManyToMany()
+  {
+    $this->assertEqual($this->object->getRelationInfo('has_many_to_many_relation'), $this->relations['has_many_to_many_relation']);
+    $this->assertEqual($this->object->getRelationInfo('other_has_many_to_many_relation'), $this->relations['other_has_many_to_many_relation']);
+  }
+
+  function testBelongsTo()
+  {
+    $this->assertEqual($this->object->getRelationInfo('belongs_to_relation'), $this->relations['belongs_to_relation']);
+    $this->assertEqual($this->object->getRelationInfo('other_belongs_to_relation'), $this->relations['other_belongs_to_relation']);
+  }
+
+  function testManyBelongsTo()
+  {
+    $this->assertEqual($this->object->getRelationInfo('many_belongs_to_relation'), $this->relations['many_belongs_to_relation']);
+    $this->assertEqual($this->object->getRelationInfo('other_many_belongs_to_relation'), $this->relations['other_many_belongs_to_relation']);
+  }
+
+  function testComposedOf()
+  {
+    $this->assertEqual($this->object->getRelationInfo('value_object'), $this->relations['value_object']);
+    $this->assertEqual($this->object->getRelationInfo('other_value_object'), $this->relations['other_value_object']);
+  }
+}
+
+?>



More information about the limb-svn mailing list