[limb-svn] r6694 - in 3.x/trunk/limb/active_record: src tests/cases tests/cases/.fixture
svn at limb-project.com
svn at limb-project.com
Thu Jan 17 18:41:52 MSK 2008
Author: serega
Date: 2008-01-17 18:41:51 +0300 (Thu, 17 Jan 2008)
New Revision: 6694
URL: http://fisheye.limb-project.com/changelog/limb/?cs=6694
Added:
3.x/trunk/limb/active_record/src/lmbARRecordSetJoinDecorator.class.php
3.x/trunk/limb/active_record/tests/cases/lmbARRecordSetJoinDecoratorTest.class.php
Modified:
3.x/trunk/limb/active_record/src/lmbARManyToManyCollection.class.php
3.x/trunk/limb/active_record/src/lmbAROneToManyCollection.class.php
3.x/trunk/limb/active_record/src/lmbARQuery.class.php
3.x/trunk/limb/active_record/src/lmbARRecordSetAttachDecorator.class.php
3.x/trunk/limb/active_record/src/lmbARRecordSetDecorator.class.php
3.x/trunk/limb/active_record/src/lmbARRelationCollection.class.php
3.x/trunk/limb/active_record/src/lmbActiveRecord.class.php
3.x/trunk/limb/active_record/tests/cases/.fixture/init_tests.mysql
3.x/trunk/limb/active_record/tests/cases/lmbAROneToManyCollectionTest.class.php
3.x/trunk/limb/active_record/tests/cases/lmbARQueryTest.class.php
3.x/trunk/limb/active_record/tests/cases/lmbARRecordSetDecoratorTest.class.php
3.x/trunk/limb/active_record/tests/cases/lmbARTestingObjectMother.class.php
3.x/trunk/limb/active_record/tests/cases/lmbActiveRecordTest.class.php
Log:
-- lmbARQuery :: create() factory method added. lmbActiveRecord, lmbARCollection and it's children now uses lmbARQuery :: create() internally
-- nesting eager fetching functionality added.
e.g lmbARQuery :: create('Author')->attach('books' => array('attach' => 'categories'))->fetch() - will load all authors with books and books with categories in 3 sql queries.
lmbARQuery :: create('lecture')->with('course' => array('with' => 'program')) - will load lectures with courses and courses with programs in 1 sql query (we suppose programs has many courser and courses has many lectures, lectures many belongs to courses, courses many belongs to programs)
-- lmbARRecordSetJoinDecorator added to support a part of nesting eager fetching functionality
Modified: 3.x/trunk/limb/active_record/src/lmbARManyToManyCollection.class.php
===================================================================
--- 3.x/trunk/limb/active_record/src/lmbARManyToManyCollection.class.php 2008-01-17 15:36:47 UTC (rev 6693)
+++ 3.x/trunk/limb/active_record/src/lmbARManyToManyCollection.class.php 2008-01-17 15:41:51 UTC (rev 6694)
@@ -17,9 +17,9 @@
*/
class lmbARManyToManyCollection extends lmbARRelationCollection
{
- protected function _createARQuery($magic_params = array())
+ protected function _createARQuery($params = array())
{
- $query = self :: createFullARQueryForRelation($this->relation_info, $this->conn, $magic_params);
+ $query = self :: createFullARQueryForRelation($this->relation_info, $this->conn, $params);
$join_table = $this->conn->quoteIdentifier($this->relation_info['table']);
$field = $this->conn->quoteIdentifier($this->relation_info['field']);
@@ -28,12 +28,12 @@
return $query;
}
- static function createFullARQueryForRelation($relation_info, $conn, $magic_params = array())
+ static function createFullARQueryForRelation($relation_info, $conn, $params = array())
{
- return parent :: createFullARQueryForRelation(__CLASS__, $relation_info, $conn, $magic_params);
+ return parent :: createFullARQueryForRelation(__CLASS__, $relation_info, $conn, $params);
}
- static function createCoreARQueryForRelation($relation_info, $conn)
+ static function createCoreARQueryForRelation($relation_info, $conn, $params = array())
{
$class = $relation_info['class'];
$object = new $class();
@@ -46,7 +46,7 @@
$sql = "SELECT %fields% FROM {$table} INNER JOIN {$join_table} ON {$table}.{$object->getPrimaryKeyName()} = {$join_table}.{$foreign_field}" .
" %tables% %left_join% %where% %group% %having% %order%";
- $query = new lmbARQuery($class, $conn, $sql);
+ $query = lmbARQuery :: create($class, $params, $conn, $sql);
$fields = $object->getDbTable()->getColumnsForSelect();
foreach($fields as $field => $alias)
Modified: 3.x/trunk/limb/active_record/src/lmbAROneToManyCollection.class.php
===================================================================
--- 3.x/trunk/limb/active_record/src/lmbAROneToManyCollection.class.php 2008-01-17 15:36:47 UTC (rev 6693)
+++ 3.x/trunk/limb/active_record/src/lmbAROneToManyCollection.class.php 2008-01-17 15:41:51 UTC (rev 6694)
@@ -16,21 +16,21 @@
*/
class lmbAROneToManyCollection extends lmbARRelationCollection
{
- protected function _createARQuery($magic_params = array())
+ protected function _createARQuery($params = array())
{
- $query = self :: createFullARQueryForRelation($this->relation_info, $this->conn, $magic_params);
+ $query = self :: createFullARQueryForRelation($this->relation_info, $this->conn, $params);
$query->addCriteria(new lmbSQLFieldCriteria($this->relation_info['field'], $this->owner->getId()));
return $query;
}
- static function createFullARQueryForRelation($relation_info, $conn, $magic_params = array())
+ static function createFullARQueryForRelation($relation_info, $conn, $params = array())
{
- return parent :: createFullARQueryForRelation(__CLASS__, $relation_info, $conn, $magic_params);
+ return parent :: createFullARQueryForRelation(__CLASS__, $relation_info, $conn, $params);
}
- static function createCoreARQueryForRelation($relation_info, $conn)
+ static function createCoreARQueryForRelation($relation_info, $conn, $params = array())
{
- return new lmbARQuery($relation_info['class'], $conn);
+ return lmbARQuery :: create($relation_info['class'], $params, $conn);
}
function add($object)
Modified: 3.x/trunk/limb/active_record/src/lmbARQuery.class.php
===================================================================
--- 3.x/trunk/limb/active_record/src/lmbARQuery.class.php 2008-01-17 15:36:47 UTC (rev 6693)
+++ 3.x/trunk/limb/active_record/src/lmbARQuery.class.php 2008-01-17 15:41:51 UTC (rev 6694)
@@ -8,6 +8,7 @@
*/
lmb_require('limb/dbal/src/query/lmbSelectRawQuery.class.php');
lmb_require('limb/active_record/src/lmbARRecordSetAttachDecorator.class.php');
+lmb_require('limb/active_record/src/lmbARRecordSetJoinDecorator.class.php');
class lmbARQuery extends lmbSelectRawQuery
{
@@ -33,37 +34,10 @@
}
}
- function with($relation_name)
+ function with($relation_name, $params = array())
{
- $relation_info = $this->_base_object->getRelationInfo($relation_name);
- $this->_with[$relation_name] = $relation_info;
-
- if(!$relation_info || !isset($relation_info['class']))
- throw new lmbException('Relation info "' . $relation_name .'" not found in "' . $this->_base_class_name . '" or does not contain "class" property');
-
- $class_name = $relation_info['class'];
- $object = new $class_name(null, $this->_conn);
- $this->_addFieldsForObject($object, $relation_name, $prefix = $relation_name . '__');
-
- $relation_type = $this->_base_object->getRelationType($relation_name);
- switch($relation_type)
- {
- case lmbActiveRecord :: HAS_ONE:
- case lmbActiveRecord :: MANY_BELONGS_TO:
- $this->addLeftJoin($object->getTableName(),
- $object->getPrimaryKeyName(),
- $this->_base_object->getTableName(),
- $relation_info['field'],
- $relation_name);
- break;
- case lmbActiveRecord :: BELONGS_TO:
- $this->addLeftJoin($object->getTableName(),
- $relation_info['field'],
- $this->_base_object->getTableName(),
- $this->_base_object->getPrimaryKeyName(),
- $relation_name);
- break;
- }
+ $this->_with[$relation_name] = $params;
+
return $this;
}
@@ -82,12 +56,72 @@
function fetch($decorate = true)
{
+ $this->_applyJoins($this->_base_object, $this->_with);
+
$rs = parent :: fetch();
- $rs = $this->_decorateWithAttachDecorator($rs);
+
+ if($decorate)
+ $rs = new lmbARRecordSetDecorator($rs, $this->_base_class_name, $this->_conn);
- if($decorate)
- return new lmbARRecordSetDecorator($rs, $this->_base_class_name, $this->_conn, $this->_with);
+ $rs = $this->_decorateWithJoinDecorator($rs);
+
+ return $this->_decorateWithAttachDecorator($rs);
+ }
+
+ protected function _applyJoins($base_object, $joins, $parent_relation_name = '')
+ {
+ if(is_string($joins))
+ $joins = array($joins => array());
+
+ if($parent_relation_name)
+ $prefix = $parent_relation_name . '__';
else
+ {
+ $parent_relation_name = $base_object->getTableName();
+ $prefix = '';
+ }
+
+ foreach($joins as $relation_name => $params)
+ {
+ $relation_info = $base_object->getRelationInfo($relation_name);
+
+ if(!$relation_info || !isset($relation_info['class']))
+ throw new lmbException('Relation info "' . $relation_name .'" not found in "' . get_class($base_object) . '" or does not contain "class" property');
+
+ $class_name = $relation_info['class'];
+ $object = new $class_name(null, $this->_conn);
+ $this->_addFieldsForObject($object, $prefix . $relation_name, $prefix . $relation_name . '__');
+
+ $relation_type = $base_object->getRelationType($relation_name);
+ switch($relation_type)
+ {
+ case lmbActiveRecord :: HAS_ONE:
+ case lmbActiveRecord :: MANY_BELONGS_TO:
+ $this->addLeftJoin($object->getTableName(),
+ $object->getPrimaryKeyName(),
+ $parent_relation_name,
+ $relation_info['field'],
+ $prefix . $relation_name);
+ break;
+ case lmbActiveRecord :: BELONGS_TO:
+ $this->addLeftJoin($object->getTableName(),
+ $relation_info['field'],
+ $parent_relation_name,
+ $base_object->getPrimaryKeyName(),
+ $prefix . $relation_name);
+ break;
+ }
+
+ if(isset($params['with']))
+ $this->_applyJoins($object, $params['with'], $prefix . $relation_name);
+ }
+ }
+
+ protected function _decorateWithJoinDecorator($rs)
+ {
+ if(count($this->_with))
+ return new lmbARRecordSetJoinDecorator($rs, $this->_base_object, $this->_conn, $this->_with);
+ else
return $rs;
}
@@ -98,4 +132,60 @@
else
return $rs;
}
+
+ static function create($class_name, $params = array(), $conn = null, $sql = '')
+ {
+ if(!$conn)
+ $conn = lmbToolkit :: instance()->getDefaultDbConnection();
+
+ $object = new $class_name;
+ $query = new lmbARQuery($class_name, $conn, $sql);
+
+ if(isset($params['criteria']) && $params['criteria'])
+ $criteria = lmbSQLCriteria :: objectify($params['criteria']);
+ else
+ $criteria = lmbSQLCriteria :: create();
+
+ $has_class_criteria = false;
+ if(isset($params['class']))
+ {
+ $filter_object = new $params['class'];
+ $criteria = $filter_object->addClassCriteria($criteria);
+ $has_class_criteria = true;
+ }
+
+ if(!$has_class_criteria)
+ $object->addClassCriteria($criteria);
+
+ $query->where($criteria);
+
+ $sort_params = (isset($params['sort']) && $params['sort']) ? $params['sort'] : $object->getDefaultSortParams();
+ $query->order($sort_params);
+
+ $with = (isset($params['with']) && $params['with']) ? $params['with'] : array();
+ if(!is_array($with))
+ $with = explode(',', $with);
+
+ foreach($with as $relation_name=> $params_or_relation_name)
+ {
+ if(is_numeric($relation_name))
+ $query->with(trim($params_or_relation_name));
+ else
+ $query->with(trim($relation_name), $params_or_relation_name);
+ }
+
+ $attach = (isset($params['attach']) && $params['attach']) ? $params['attach'] : array();
+ if(!is_array($attach))
+ $attach = explode(',', $attach);
+
+ foreach($attach as $relation_name => $params_or_relation_name)
+ {
+ if(is_numeric($relation_name))
+ $query->attach(trim($params_or_relation_name));
+ else
+ $query->attach(trim($relation_name), $params_or_relation_name);
+ }
+
+ return $query;
+ }
}
Modified: 3.x/trunk/limb/active_record/src/lmbARRecordSetAttachDecorator.class.php
===================================================================
--- 3.x/trunk/limb/active_record/src/lmbARRecordSetAttachDecorator.class.php 2008-01-17 15:36:47 UTC (rev 6693)
+++ 3.x/trunk/limb/active_record/src/lmbARRecordSetAttachDecorator.class.php 2008-01-17 15:41:51 UTC (rev 6694)
@@ -21,12 +21,16 @@
protected $base_object;
protected $conn;
protected $attach_relations = array();
+ protected $prefix = "";
- function __construct($record_set, $base_object, $conn = null, $attach_relations = array())
+ function __construct($record_set, $base_object, $conn = null, $attach_relations = array(), $prefix = "")
{
$this->base_object = $base_object;
$this->conn = $conn;
+ if(is_string($attach_relations))
+ $attach_relations = array($attach_relations => array());
$this->attach_relations = $attach_relations;
+ $this->prefix = $prefix;
parent :: __construct($record_set);
}
@@ -45,14 +49,14 @@
{
case lmbActiveRecord :: HAS_ONE:
case lmbActiveRecord :: MANY_BELONGS_TO:
- $ids = lmbArrayHelper :: getColumnValues($relation_info['field'], $this->iterator);
+ $ids = lmbArrayHelper :: getColumnValues($this->prefix . $relation_info['field'], $this->iterator);
$attached_objects = lmbActiveRecord :: findByIds($relation_class, $ids, $params, $this->conn);
$this->loaded_attaches[$relation_name] = lmbCollection :: toFlatArray($attached_objects,
$key_field = $relation_object->getPrimaryKeyName(),
$export_each = false);
break;
case lmbActiveRecord :: BELONGS_TO:
- $ids = lmbArrayHelper :: getColumnValues($this->base_object->getPrimaryKeyName(), $this->iterator);
+ $ids = lmbArrayHelper :: getColumnValues($this->prefix . $this->base_object->getPrimaryKeyName(), $this->iterator);
$criteria = lmbSQLCriteria :: in($relation_info['field'], $ids);
$params['criteria'] = isset($params['criteria']) ? $params['criteria']->addAnd($criteria) : $criteria;
@@ -69,7 +73,7 @@
$query = lmbAROneToManyCollection :: createFullARQueryForRelation($relation_info, $this->conn, $params);
- $ids = lmbArrayHelper :: getColumnValues($this->base_object->getPrimaryKeyName(), $this->iterator);
+ $ids = lmbArrayHelper :: getColumnValues($this->prefix . $this->base_object->getPrimaryKeyName(), $this->iterator);
$query->addCriteria(lmbSQLCriteria :: in($relation_info['field'], $ids));
$attached_objects = $query->fetch();
@@ -86,7 +90,7 @@
$query = lmbARManyToManyCollection :: createFullARQueryForRelation($relation_info, $this->conn, $params);
$query->addField($relation_info['table']. '.' . $relation_info['field'], "link__id");
- $ids = lmbArrayHelper :: getColumnValues($this->base_object->getPrimaryKeyName(), $this->iterator);
+ $ids = lmbArrayHelper :: getColumnValues($this->prefix . $this->base_object->getPrimaryKeyName(), $this->iterator);
$query->addCriteria(lmbSQLCriteria :: in($relation_info['field'], $ids));
$attached_objects = $query->fetch();
@@ -102,7 +106,9 @@
function current()
{
- $record = parent :: current();
+ $object = parent :: current();
+
+ $fields = new lmbSet();
foreach($this->attach_relations as $relation_name => $params)
{
@@ -113,16 +119,22 @@
{
case lmbActiveRecord :: HAS_ONE:
case lmbActiveRecord :: MANY_BELONGS_TO:
- $record->set($relation_name, $this->loaded_attaches[$relation_name][$record->get($relation_info['field'])]);
+ $fields->set($this->prefix . $relation_name, $this->loaded_attaches[$relation_name][$object->get($this->prefix . $relation_info['field'])]);
break;
case lmbActiveRecord :: BELONGS_TO:
+ $fields->set($this->prefix . $relation_name, $this->loaded_attaches[$relation_name][$object->get($this->prefix . $this->base_object->getPrimaryKeyName())]);
+ break;
case lmbActiveRecord :: HAS_MANY:
case lmbActiveRecord :: HAS_MANY_TO_MANY:
- $record->set($relation_name, $this->loaded_attaches[$relation_name][$record->get($this->base_object->getPrimaryKeyName())]);
+ $collection = $this->base_object->createRelationCollection($relation_name);
+ $collection->setDataset(new lmbCollection($this->loaded_attaches[$relation_name][$object->get($this->prefix . $this->base_object->getPrimaryKeyName())]));
+ $fields->set($this->prefix . $relation_name, $collection);
break;
}
}
- return $record;
+
+ $object->loadFromRecord($fields);
+ return $object;
}
function at($pos)
Modified: 3.x/trunk/limb/active_record/src/lmbARRecordSetDecorator.class.php
===================================================================
--- 3.x/trunk/limb/active_record/src/lmbARRecordSetDecorator.class.php 2008-01-17 15:36:47 UTC (rev 6693)
+++ 3.x/trunk/limb/active_record/src/lmbARRecordSetDecorator.class.php 2008-01-17 15:41:51 UTC (rev 6694)
@@ -20,13 +20,11 @@
{
protected $class_path;
protected $conn;
- protected $with_relations = array();
- function __construct($record_set, $class_path, $conn = null, $with_relations = array())
+ function __construct($record_set, $class_path, $conn = null)
{
$this->class_path = $class_path;
$this->conn = $conn;
- $this->with_relations = $with_relations;
parent :: __construct($record_set);
}
@@ -42,35 +40,10 @@
protected function _createObjectFromRecord($record)
{
$object = $this->_createObject($record);
- $this->_extractPrefixedFieldsAsActiveRecords($record);
$object->loadFromRecord($record);
return $object;
}
- protected function _extractPrefixedFieldsAsActiveRecords($record)
- {
- foreach($this->with_relations as $relation_name => $relation_info)
- {
- $fields = new lmbSet();
- $prefix = $relation_name . '__';
-
- foreach($record->export() as $field => $value)
- {
- if(strpos($field, $prefix) === 0)
- {
- $non_prefixes_field_name = substr($field, strlen($prefix));
- $fields->set($non_prefixes_field_name, $value);
- $record->remove($field);
- }
- }
-
- $related_object_class = $relation_info['class'];
- $related_object = new $related_object_class(null, $this->conn);
- $related_object->loadFromRecord($fields);
- $record->set($relation_name, $related_object);
- }
- }
-
protected function _createObject($record)
{
if($path = $record->get(lmbActiveRecord :: getInheritanceField()))
Added: 3.x/trunk/limb/active_record/src/lmbARRecordSetJoinDecorator.class.php
===================================================================
--- 3.x/trunk/limb/active_record/src/lmbARRecordSetJoinDecorator.class.php (rev 0)
+++ 3.x/trunk/limb/active_record/src/lmbARRecordSetJoinDecorator.class.php 2008-01-17 15:41:51 UTC (rev 6694)
@@ -0,0 +1,99 @@
+<?php
+/*
+ * Limb PHP Framework
+ *
+ * @link http://limb-project.com
+ * @copyright Copyright © 2004-2007 BIT(http://bit-creative.com)
+ * @license LGPL http://www.gnu.org/copyleft/lesser.html
+ */
+lmb_require('limb/core/src/lmbCollectionDecorator.class.php');
+lmb_require('limb/core/src/lmbClassPath.class.php');
+lmb_require('limb/core/src/lmbSet.class.php');
+
+/**
+ * class lmbARRecordSetDecorator.
+ *
+ * @package active_record
+ * @version $Id: lmbARRecordSetDecorator.class.php 6691 2008-01-15 14:55:59Z serega $
+ */
+class lmbARRecordSetJoinDecorator extends lmbCollectionDecorator
+{
+ protected $base_object;
+ protected $conn;
+ protected $join_relations = array();
+ protected $prefix;
+
+ function __construct($record_set, $base_object, $conn = null, $join_relations = array(), $prefix = '')
+ {
+ $this->base_object = $base_object;
+ $this->conn = $conn;
+ if(is_string($join_relations))
+ $join_relations = array($join_relations => array());
+ $this->join_relations = $join_relations;
+ $this->prefix = $prefix;
+
+ parent :: __construct($record_set);
+ }
+
+ function rewind()
+ {
+ foreach($this->join_relations as $relation_name => $params)
+ {
+ $relation_info = $this->base_object->getRelationInfo($relation_name);
+ $object = new $relation_info['class'];
+ if(isset($params['with']))
+ $this->iterator = new lmbARRecordSetJoinDecorator($this->iterator, $object, $this->conn, $params['with'], $this->prefix . $relation_name . '__');
+ if(isset($params['attach']))
+ $this->iterator = new lmbARRecordSetAttachDecorator($this->iterator, $object, $this->conn, $params['attach'], $relation_name . '__');
+ }
+
+ parent :: rewind();
+ }
+
+ function current()
+ {
+ if(!$record = parent :: current())
+ return null;
+
+ $this->_extractPrefixedFieldsAsActiveRecords($record);
+
+ return $record;
+ }
+
+ protected function _extractPrefixedFieldsAsActiveRecords($record)
+ {
+ foreach($this->join_relations as $relation_name => $params)
+ {
+ $relation_info = $this->base_object->getRelationInfo($relation_name);
+ $fields = new lmbSet();
+ $prefix = $this->prefix . $relation_name . '__';
+
+ foreach($record->export() as $field => $value)
+ {
+ if(strpos($field, $prefix) === 0)
+ {
+ $non_prefixes_field_name = substr($field, strlen($prefix));
+ $fields->set($non_prefixes_field_name, $value);
+ $record->remove($field);
+ }
+ }
+
+ $related_object_class = $relation_info['class'];
+ $related_object = new $related_object_class(null, $this->conn);
+ $related_object->loadFromRecord($fields);
+ $record->set($this->prefix . $relation_name, $related_object);
+ }
+ }
+
+ function at($pos)
+ {
+ if(!$record = parent :: at($pos))
+ return null;
+
+ $this->_extractPrefixedFieldsAsActiveRecords($record);
+
+ return $record;
+ }
+}
+
+
Modified: 3.x/trunk/limb/active_record/src/lmbARRelationCollection.class.php
===================================================================
--- 3.x/trunk/limb/active_record/src/lmbARRelationCollection.class.php 2008-01-17 15:36:47 UTC (rev 6693)
+++ 3.x/trunk/limb/active_record/src/lmbARRelationCollection.class.php 2008-01-17 15:41:51 UTC (rev 6694)
@@ -25,7 +25,8 @@
protected $conn;
protected $is_owner_new;
protected $decorators = array();
- protected $fetch_with_relations = array();
+ protected $join_relations = array();
+ protected $attach_relations = array();
protected $default_params = array();
function __construct($relation, $owner, $criteria = null, $conn = null)
@@ -33,8 +34,8 @@
$this->relation = $relation;
$this->owner = $owner;
$this->relation_info = $owner->getRelationInfo($relation);
- $this->default_params['criteria'] = lmbSQLCriteria :: objectify($criteria);
- $this->default_params['sort'] = array();
+ if($criteria)
+ $this->default_params['criteria'] = lmbSQLCriteria :: objectify($criteria);
if(is_object($conn))
$this->conn = $conn;
@@ -54,6 +55,11 @@
$this->is_owner_new = $this->owner->isNew();
$this->dataset = null;
}
+
+ function setDataset($dataset)
+ {
+ $this->dataset = $dataset;
+ }
protected function _ensureDataset()
{
@@ -74,14 +80,22 @@
if(is_string($magic_params) || is_object($magic_params))
$magic_params = array('criteria' => lmbSQLCriteria :: objectify($magic_params));
- $magic_params['criteria'] = isset($magic_params['criteria']) ? $magic_params['criteria']->addAnd($this->default_params['criteria']) : $this->default_params['criteria'];
- $magic_params['sort'] = isset($magic_params['sort']) ? $magic_params['sort'] : $this->default_params['sort'];
+ if(isset($this->default_params['criteria']))
+ {
+ if(isset($magic_params['criteria']))
+ $magic_params['criteria']->addAnd($this->default_params['criteria']);
+ else
+ $magic_params['criteria'] = $this->default_params['criteria'];
+ }
+ if(!isset($magic_params['sort']) && isset($this->default_params['sort']))
+ $magic_params['sort'] = $this->default_params['sort'];
+
+ $magic_params['with'] = $this->join_relations;
+ $magic_params['attach'] = $this->attach_relations;
+
$query = $this->_createARQuery($magic_params);
- foreach($this->fetch_with_relations as $relation)
- $query->with($relation);
-
$rs = $query->fetch();
return $this->_applyDecorators($rs);
@@ -95,43 +109,29 @@
return $rs->current();
}
- function with($relation_name)
+ function with($relation_name, $params = array())
{
- $this->fetch_with_relations[] = $relation_name;
+ $this->join_relations[$relation_name] = $params;
return $this;
}
- static function createFullARQueryForRelation($class, $relation_info, $conn, $magic_params = array())
+ function attach($relation_name, $params = array())
{
- $object = new $relation_info['class'];
+ $this->attach_relations[$relation_name] = $params;
+ return $this;
+ }
- $criteria = isset($magic_params['criteria']) ? $magic_params['criteria'] : new lmbSQLCriteria();
+ static function createFullARQueryForRelation($calling_class, $relation_info, $conn, $params = array())
+ {
+ if(!isset($params['sort']) && isset($relation_info['sort_params']))
+ $params['sort'] = $relation_info['sort_params'];
- $has_class_criteria = false;
- if(isset($magic_params['class']))
- {
- $filter_object = new $magic_params['class'];
- $criteria = $filter_object->addClassCriteria($criteria);
- $has_class_criteria = true;
- }
-
- if(!$has_class_criteria)
- $object->addClassCriteria($criteria);
-
- $query = call_user_func_array(array($class, 'createCoreARQueryForRelation'), array($relation_info, $conn));
+ $query = call_user_func_array(array($calling_class, 'createCoreARQueryForRelation'), array($relation_info, $conn, $params));
- $query->addCriteria($criteria);
-
- $sort_params = array();
- if(isset($magic_params['sort']))
- $sort_params = $magic_params['sort'];
-
- self :: applySortParams($query, $relation_info, $sort_params);
-
return $query;
}
- abstract static function createCoreARQueryForRelation($relation_info, $conn);
+ abstract static function createCoreARQueryForRelation($relation_info, $conn, $params = array());
abstract protected function _createARQuery($magic_params = array());
Modified: 3.x/trunk/limb/active_record/src/lmbActiveRecord.class.php
===================================================================
--- 3.x/trunk/limb/active_record/src/lmbActiveRecord.class.php 2008-01-17 15:36:47 UTC (rev 6693)
+++ 3.x/trunk/limb/active_record/src/lmbActiveRecord.class.php 2008-01-17 15:41:51 UTC (rev 6694)
@@ -684,7 +684,7 @@
$this->_hasManyToManyRelation($relation);
}
/**
- * Generic magis getter for any attribute
+ * Generic magic setter for any attribute
* @param string property name
* @param mixed property value
*/
@@ -1553,7 +1553,7 @@
*/
protected function _find($params = array())
{
- $query = $this->_createARQuery($params);
+ $query = lmbARQuery :: create(get_class($this), $params, $this->_db_conn);
$rs = $query->fetch();
$return_first = false;
@@ -1580,28 +1580,6 @@
return $rs;
}
- protected function _createARQuery($params)
- {
- $query = new lmbARQuery(get_class($this), $this->_db_conn);
-
- $criteria = (isset($params['criteria']) && $params['criteria']) ? $params['criteria'] : lmbSQLCriteria :: create();
- $criteria = $this->addClassCriteria($criteria);
- $query->addCriteria($criteria);
-
- $sort_params = (isset($params['sort']) && $params['sort']) ? $params['sort'] : $this->_default_sort_params;
- foreach($sort_params as $field => $sort_type)
- $query->addOrder($field, $sort_type);
-
- $with = (isset($params['with']) && $params['with']) ? $params['with'] : array();
- if(!is_array($with))
- $with = explode(',', $with);
-
- foreach($with as $relation_name)
- $query->with(trim($relation_name));
-
- return $query;
- }
-
/**
* Finds a collection of records(not lmbActiveRecord objects!) from database table
* @param string|object filtering criteria
@@ -1610,10 +1588,8 @@
*/
function findAllRecords($criteria = null, $sort_params = array())
{
- $query = $this->_createARQuery(array('criteria' => $criteria, 'sort' => $sort_params));
+ $query = lmbARQuery :: create(get_class($this), $params = array('criteria' => $criteria, 'sort' => $sort_params), $this->_db_conn);
return $query->fetch($decorate = false);
-
- return $this->_db_table->select($this->addClassCriteria($criteria), $sort_params, $columns);
}
/**
* Adds class name criterion to passed in criteria
@@ -1671,7 +1647,7 @@
$this->_is_new = false;
}
/**
- * Loads current object with data from database record, overwrites any previous data, marks object dirty and unsets new status
+ * Loads current object with data from database record, overwrites any previous data, resets object dirtiness and unsets new status
* @param object database record object
*/
function loadFromRecord($record)
Modified: 3.x/trunk/limb/active_record/tests/cases/.fixture/init_tests.mysql
===================================================================
--- 3.x/trunk/limb/active_record/tests/cases/.fixture/init_tests.mysql 2008-01-17 15:36:47 UTC (rev 6693)
+++ 3.x/trunk/limb/active_record/tests/cases/.fixture/init_tests.mysql 2008-01-17 15:41:51 UTC (rev 6694)
@@ -58,9 +58,17 @@
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+DROP TABLE IF EXISTS `program_for_test`;
+CREATE TABLE `program_for_test` (
+ `id` bigint(20) NOT NULL auto_increment,
+ `title` varchar(255) default NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
DROP TABLE IF EXISTS `course_for_test`;
CREATE TABLE `course_for_test` (
`id` bigint(20) NOT NULL auto_increment,
+ `program_id` bigint(20) default NULL,
`title` varchar(255) default NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Modified: 3.x/trunk/limb/active_record/tests/cases/lmbAROneToManyCollectionTest.class.php
===================================================================
--- 3.x/trunk/limb/active_record/tests/cases/lmbAROneToManyCollectionTest.class.php 2008-01-17 15:36:47 UTC (rev 6693)
+++ 3.x/trunk/limb/active_record/tests/cases/lmbAROneToManyCollectionTest.class.php 2008-01-17 15:41:51 UTC (rev 6694)
@@ -662,7 +662,6 @@
$l->setTitle($title);
return $l;
}
-
}
Modified: 3.x/trunk/limb/active_record/tests/cases/lmbARQueryTest.class.php
===================================================================
--- 3.x/trunk/limb/active_record/tests/cases/lmbARQueryTest.class.php 2008-01-17 15:36:47 UTC (rev 6693)
+++ 3.x/trunk/limb/active_record/tests/cases/lmbARQueryTest.class.php 2008-01-17 15:41:51 UTC (rev 6694)
@@ -275,6 +275,241 @@
$this->assertEqual($groups[1]->getId(), $group1->getId());
$this->assertEqual($groups[1]->getTitle(), 'AAA');
}
+
+ function testFetch_NestedWithProperty_In_Attach_ForHasMany()
+ {
+ $course1 = $this->creator->createCourse();
+ $course2 = $this->creator->createCourse();
+
+ $alt_course1 = $this->creator->createCourse();
+ $alt_course2 = $this->creator->createCourse();
+
+ $lecture1 = $this->creator->createLecture($course1, $alt_course2);
+ $lecture2 = $this->creator->createLecture($course2, $alt_course1);
+ $lecture3 = $this->creator->createLecture($course1, $alt_course2);
+ $lecture4 = $this->creator->createLecture($course1, $alt_course1);
+
+ $query = new lmbARQuery('CourseForTest', $this->conn);
+ $query->where(lmbSQLCriteria :: in('id', array($course1->getId(), $course2->getId())));
+ $arr = $query->attach('lectures', array('with' => 'alt_course'))->fetch()->getArray();
+
+ //make sure we really eager fetching
+ $this->db->delete('lecture_for_test');
+ $this->db->delete('course_for_test');
+
+ $this->assertIsA($arr[0], 'CourseForTest');
+ $this->assertEqual($arr[0]->getTitle(), $course1->getTitle());
+ $lectures = $arr[0]->getLectures();
+ $this->assertEqual(count($lectures), 3);
+ $this->assertEqual($lectures[0]->getId(), $lecture1->getId());
+ $this->assertEqual($lectures[0]->getAltCourse()->getTitle(), $alt_course2->getTitle());
+ $this->assertEqual($lectures[1]->getId(), $lecture3->getId());
+ $this->assertEqual($lectures[1]->getAltCourse()->getTitle(), $alt_course2->getTitle());
+ $this->assertEqual($lectures[2]->getId(), $lecture4->getId());
+ $this->assertEqual($lectures[2]->getAltCourse()->getTitle(), $alt_course1->getTitle());
+
+
+ $this->assertIsA($arr[1], 'CourseForTest');
+ $this->assertEqual($arr[1]->getTitle(), $course2->getTitle());
+ $lectures = $arr[1]->getLectures();
+ $this->assertEqual(count($lectures), 1);
+ $this->assertEqual($lectures[0]->getId(), $lecture2->getId());
+ $this->assertEqual($lectures[0]->getAltCourse()->getTitle(), $alt_course1->getTitle());
+ }
+
+ function testFetch_NestedAttachProperty_In_With()
+ {
+ $course1 = $this->creator->createCourse();
+ $course2 = $this->creator->createCourse();
+
+ $alt_course1 = $this->creator->createCourse();
+ $alt_course2 = $this->creator->createCourse();
+
+ $lecture1 = $this->creator->createLecture($course1, $alt_course2);
+ $lecture2 = $this->creator->createLecture($course2, $alt_course1);
+ $lecture3 = $this->creator->createLecture($course1, $alt_course2);
+ $lecture4 = $this->creator->createLecture($course1, $alt_course1);
+
+ $lecture5 = $this->creator->createLecture($alt_course2);
+ $lecture6 = $this->creator->createLecture($alt_course1);
+ $lecture7 = $this->creator->createLecture($alt_course2);
+ $lecture8 = $this->creator->createLecture($alt_course1);
+
+ $query = new lmbARQuery('LectureForTest', $this->conn);
+ $query->where(lmbSQLCriteria :: equal('course_id', $course1->getId()));
+ $iterator = $query->with('alt_course', array('attach' => 'lectures'))->fetch();
+ $arr = $iterator->getArray();
+
+ //make sure we really eager fetching
+ $this->db->delete('lecture_for_test');
+ $this->db->delete('course_for_test');
+
+ $this->assertIsA($arr[0], 'LectureForTest');
+ $this->assertEqual($arr[0]->getTitle(), $lecture1->getTitle());
+
+ $this->assertEqual($arr[0]->getAltCourse()->getTitle(), $alt_course2->getTitle());
+ $alt_course_lectures = $arr[0]->getAltCourse()->getLectures();
+ $this->assertEqual($alt_course_lectures[0]->getId(), $lecture5->getId());
+ $this->assertEqual($alt_course_lectures[1]->getId(), $lecture7->getId());
+
+ $this->assertEqual($arr[1]->getId(), $lecture3->getId());
+ $this->assertEqual($arr[1]->getAltCourse()->getTitle(), $alt_course2->getTitle());
+ $alt_course_lectures = $arr[1]->getAltCourse()->getLectures();
+ $this->assertEqual($alt_course_lectures[0]->getId(), $lecture5->getId());
+ $this->assertEqual($alt_course_lectures[1]->getId(), $lecture7->getId());
+
+ $this->assertEqual($arr[2]->getId(), $lecture4->getId());
+ $this->assertEqual($arr[2]->getAltCourse()->getTitle(), $alt_course1->getTitle());
+ $alt_course_lectures = $arr[2]->getAltCourse()->getLectures();
+ $this->assertEqual($alt_course_lectures[0]->getId(), $lecture6->getId());
+ $this->assertEqual($alt_course_lectures[1]->getId(), $lecture8->getId());
+ }
+
+ function testFetchNested_AttachProperty_In_WithProperty_In_Attach()
+ {
+ $course1 = $this->creator->createCourse();
+ $course2 = $this->creator->createCourse();
+
+ $alt_course1 = $this->creator->createCourse();
+ $alt_course2 = $this->creator->createCourse();
+
+ $lecture1 = $this->creator->createLecture($course1, $alt_course2);
+ $lecture2 = $this->creator->createLecture($course2, $alt_course1);
+ $lecture3 = $this->creator->createLecture($course1, $alt_course2);
+ $lecture4 = $this->creator->createLecture($course1, $alt_course1);
+
+ $lecture5 = $this->creator->createLecture($alt_course2);
+ $lecture6 = $this->creator->createLecture($alt_course1);
+ $lecture7 = $this->creator->createLecture($alt_course2);
+ $lecture8 = $this->creator->createLecture($alt_course1);
+
+ $query = new lmbARQuery('CourseForTest', $this->conn);
+ $query->where(lmbSQLCriteria :: in('id', array($course1->getId(), $course2->getId())));
+ $arr = $query->attach('lectures', array('with' => array('alt_course' => array('attach' => 'lectures'))))->fetch()->getArray();
+
+ //make sure we really eager fetching
+ $this->db->delete('lecture_for_test');
+ $this->db->delete('course_for_test');
+
+ $this->assertIsA($arr[0], 'CourseForTest');
+ $this->assertEqual($arr[0]->getTitle(), $course1->getTitle());
+ $lectures = $arr[0]->getLectures();
+ $this->assertEqual(count($lectures), 3);
+ $this->assertEqual($lectures[0]->getId(), $lecture1->getId());
+ $this->assertEqual($lectures[0]->getAltCourse()->getTitle(), $alt_course2->getTitle());
+ $alt_course_lectures = $lectures[0]->getAltCourse()->getLectures();
+ $this->assertEqual($alt_course_lectures[0]->getId(), $lecture5->getId());
+ $this->assertEqual($alt_course_lectures[1]->getId(), $lecture7->getId());
+
+ $this->assertEqual($lectures[1]->getId(), $lecture3->getId());
+ $this->assertEqual($lectures[1]->getAltCourse()->getTitle(), $alt_course2->getTitle());
+ $alt_course_lectures = $lectures[1]->getAltCourse()->getLectures();
+ $this->assertEqual($alt_course_lectures[0]->getId(), $lecture5->getId());
+ $this->assertEqual($alt_course_lectures[1]->getId(), $lecture7->getId());
+
+ $this->assertEqual($lectures[2]->getId(), $lecture4->getId());
+ $this->assertEqual($lectures[2]->getAltCourse()->getTitle(), $alt_course1->getTitle());
+ $alt_course_lectures = $lectures[2]->getAltCourse()->getLectures();
+ $this->assertEqual($alt_course_lectures[0]->getId(), $lecture6->getId());
+ $this->assertEqual($alt_course_lectures[1]->getId(), $lecture8->getId());
+
+ $this->assertIsA($arr[1], 'CourseForTest');
+ $this->assertEqual($arr[1]->getTitle(), $course2->getTitle());
+ $lectures = $arr[1]->getLectures();
+ $this->assertEqual(count($lectures), 1);
+ $this->assertEqual($lectures[0]->getId(), $lecture2->getId());
+ $this->assertEqual($lectures[0]->getAltCourse()->getTitle(), $alt_course1->getTitle());
+
+ $alt_course_lectures = $lectures[0]->getAltCourse()->getLectures();
+ $this->assertEqual($alt_course_lectures[0]->getId(), $lecture6->getId());
+ $this->assertEqual($alt_course_lectures[1]->getId(), $lecture8->getId());
+ }
+
+ function testFetch_NestedWithProperty_In_With()
+ {
+ $program1 = $this->creator->createProgram();
+ $program2 = $this->creator->createProgram();
+ $course1 = $this->creator->createCourse($program1);
+ $course2 = $this->creator->createCourse($program2);
+ $lecture1 = $this->creator->createLecture($course1);
+ $lecture2 = $this->creator->createLecture($course2);
+
+ $query = new lmbARQuery('LectureForTest', $this->conn);
+ $iterator = $query->with('course', array('with' => 'program'))->fetch();
+ $arr = $iterator->getArray();
+
+ //make sure we really eager fetching
+ $this->db->delete('lecture_for_test');
+ $this->db->delete('course_for_test');
+ $this->db->delete('program_for_test');
+
+ $this->assertIsA($arr[0], 'LectureForTest');
+ $this->assertEqual($arr[0]->getTitle(), $lecture1->getTitle());
+ $this->assertEqual($arr[1]->getTitle(), $lecture2->getTitle());
+
+ $this->assertEqual($arr[0]->getCourse()->getTitle(), $course1->getTitle());
+ $this->assertEqual($arr[1]->getCourse()->getTitle(), $course2->getTitle());
+
+ $this->assertEqual($arr[0]->getCourse()->getProgram()->getTitle(), $program1->getTitle());
+ $this->assertEqual($arr[1]->getCourse()->getProgram()->getTitle(), $program2->getTitle());
+ }
+
+ function testFetch_NestedAttachProperty_In_Attach()
+ {
+ $program1 = $this->creator->createProgram();
+ $program2 = $this->creator->createProgram();
+ $course1 = $this->creator->createCourse($program1);
+ $course2 = $this->creator->createCourse($program2);
+ $course3 = $this->creator->createCourse($program1);
+ $course4 = $this->creator->createCourse($program2);
+ $lecture1 = $this->creator->createLecture($course1);
+ $lecture2 = $this->creator->createLecture($course2);
+ $lecture3 = $this->creator->createLecture($course3);
+ $lecture4 = $this->creator->createLecture($course4);
+ $lecture5 = $this->creator->createLecture($course1);
+ $lecture6 = $this->creator->createLecture($course2);
+ $lecture7 = $this->creator->createLecture($course3);
+ $lecture8 = $this->creator->createLecture($course4);
+
+ $query = new lmbARQuery('ProgramForTest', $this->conn);
+ $iterator = $query->attach('courses', array('attach' => 'lectures'))->fetch();
+
+ $arr = $iterator->getArray();
+
+ //make sure we really eager fetching
+ $this->db->delete('lecture_for_test');
+ $this->db->delete('course_for_test');
+ $this->db->delete('program_for_test');
+
+ $this->assertIsA($arr[0], 'ProgramForTest');
+ $this->assertEqual($arr[0]->getTitle(), $program1->getTitle());
+
+ $courses = $arr[0]->getCourses();
+
+ $this->assertEqual($courses[0]->getTitle(), $course1->getTitle());
+ $lectures = $courses[0]->getLectures();
+ $this->assertEqual($lectures[0]->getTitle(), $lecture1->getTitle());
+ $this->assertEqual($lectures[1]->getTitle(), $lecture5->getTitle());
+
+ $this->assertEqual($courses[1]->getTitle(), $course3->getTitle());
+ $lectures = $courses[1]->getLectures();
+ $this->assertEqual($lectures[0]->getTitle(), $lecture3->getTitle());
+ $this->assertEqual($lectures[1]->getTitle(), $lecture7->getTitle());
+
+ $this->assertEqual($arr[1]->getTitle(), $program2->getTitle());
+
+ $courses = $arr[1]->getCourses();
+
+ $this->assertEqual($courses[0]->getTitle(), $course2->getTitle());
+ $lectures = $courses[0]->getLectures();
+ $this->assertEqual($lectures[0]->getTitle(), $lecture2->getTitle());
+ $this->assertEqual($lectures[1]->getTitle(), $lecture6->getTitle());
+
+ $this->assertEqual($courses[1]->getTitle(), $course4->getTitle());
+ $lectures = $courses[1]->getLectures();
+ $this->assertEqual($lectures[0]->getTitle(), $lecture4->getTitle());
+ $this->assertEqual($lectures[1]->getTitle(), $lecture8->getTitle());
+ }
}
Modified: 3.x/trunk/limb/active_record/tests/cases/lmbARRecordSetDecoratorTest.class.php
===================================================================
--- 3.x/trunk/limb/active_record/tests/cases/lmbARRecordSetDecoratorTest.class.php 2008-01-17 15:36:47 UTC (rev 6693)
+++ 3.x/trunk/limb/active_record/tests/cases/lmbARRecordSetDecoratorTest.class.php 2008-01-17 15:41:51 UTC (rev 6694)
@@ -61,30 +61,6 @@
$this->assertEqual($iterator[1]->getCourse()->getTitle(), $course->getTitle());
}
- function testProcessPrefixedFieldsAsRelatedActiveRecords()
- {
- $course = $this->_createCourseWithTwoLectures();
- $lecture = new LectureForTest();
- $course_info = $lecture->getRelationInfo('course');
-
- $db = new lmbSimpleDb(lmbToolkit :: instance()->getDefaultDbConnection());
- $sql = 'SELECT lecture_for_test.*, course_for_test.id as course__id, course_for_test.title as course__title
- FROM lecture_for_test LEFT JOIN course_for_test ON course_for_test.id = lecture_for_test.course_id';
- $decorated = lmbDBAL :: fetch($sql);
-
- $iterator = new lmbARRecordSetDecorator($decorated, 'LectureForTest', null, array('course' => $course_info));
-
- // let's fetch all data in order to actually call rewind() and current();
- $arr = $iterator->getArray();
-
- // now let's remove everything from db tables so we can be sure that processing is correct
- $db->delete('lecture_for_test');
- $db->delete('course_for_test');
-
- $this->assertEqual($arr[0]->getCourse()->getTitle(), $course->getTitle());
- $this->assertEqual($arr[1]->getCourse()->getTitle(), $course->getTitle());
- }
-
function testIfRecordIsEmpty()
{
$iterator = new lmbARRecordSetDecorator(new lmbCollection(), 'LectureForTest');
Added: 3.x/trunk/limb/active_record/tests/cases/lmbARRecordSetJoinDecoratorTest.class.php
===================================================================
--- 3.x/trunk/limb/active_record/tests/cases/lmbARRecordSetJoinDecoratorTest.class.php (rev 0)
+++ 3.x/trunk/limb/active_record/tests/cases/lmbARRecordSetJoinDecoratorTest.class.php 2008-01-17 15:41:51 UTC (rev 6694)
@@ -0,0 +1,71 @@
+<?php
+/*
+ * Limb PHP Framework
+ *
+ * @link http://limb-project.com
+ * @copyright Copyright © 2004-2007 BIT(http://bit-creative.com)
+ * @license LGPL http://www.gnu.org/copyleft/lesser.html
+ */
+require_once('limb/active_record/src/lmbARRecordSetJoinDecorator.class.php');
+require_once(dirname(__FILE__) . '/lmbAROneToManyRelationsTest.class.php');
+
+class lmbARRecordSetJoinDecoratorTest extends UnitTestCase
+{
+ function setUp()
+ {
+ $this->_dbCleanUp();
+ }
+
+ function tearDown()
+ {
+ $this->_dbCleanUp();
+ }
+
+ function _dbCleanUp()
+ {
+ lmbActiveRecord :: delete('CourseForTest');
+ lmbActiveRecord :: delete('LectureForTest');
+ }
+
+ function testProcessPrefixedFieldsAsRelatedActiveRecords()
+ {
+ $course = $this->_createCourseWithTwoLectures();
+ $lecture = new LectureForTest();
+ $course_info = $lecture->getRelationInfo('course');
+
+ $db = new lmbSimpleDb(lmbToolkit :: instance()->getDefaultDbConnection());
+ $sql = 'SELECT lecture_for_test.*, course_for_test.id as course__id, course_for_test.title as course__title
+ FROM lecture_for_test LEFT JOIN course_for_test ON course_for_test.id = lecture_for_test.course_id';
+ $decorated = lmbDBAL :: fetch($sql);
+
+ $iterator = new lmbARRecordSetJoinDecorator($decorated, new LectureForTest(), null, array('course' => $course_info));
+
+ // let's fetch all data in order to actually call rewind() and current();
+ $arr = $iterator->getArray();
+
+ // now let's remove everything from db tables so we can be sure that processing is correct
+ $db->delete('lecture_for_test');
+ $db->delete('course_for_test');
+
+ $this->assertEqual($arr[0]->get('course')->getTitle(), $course->getTitle());
+ $this->assertEqual($arr[1]->get('course')->getTitle(), $course->getTitle());
+ }
+
+ function _createCourseWithTwoLectures()
+ {
+ $course = new CourseForTest();
+ $course->setTitle($title = 'General Course');
+
+ $l1 = new LectureForTest();
+ $l1->setTitle('Physics');
+ $l2 = new LectureForTest();
+ $l2->setTitle('Math');
+
+ $course->addToLectures($l1);
+ $course->addToLectures($l2);
+ $course->save();
+
+ return $course;
+ }
+}
+
Modified: 3.x/trunk/limb/active_record/tests/cases/lmbARTestingObjectMother.class.php
===================================================================
--- 3.x/trunk/limb/active_record/tests/cases/lmbARTestingObjectMother.class.php 2008-01-17 15:36:47 UTC (rev 6693)
+++ 3.x/trunk/limb/active_record/tests/cases/lmbARTestingObjectMother.class.php 2008-01-17 15:41:51 UTC (rev 6694)
@@ -23,6 +23,14 @@
'class' => 'PersonForTest'));
}
+class ProgramForTest extends lmbActiveRecord
+{
+ protected $_db_table_name = 'program_for_test';
+
+ protected $_has_many = array('courses' => array('field' => 'program_id',
+ 'class' => 'CourseForTest'));
+}
+
class CourseForTest extends lmbActiveRecord
{
protected $_db_table_name = 'course_for_test';
@@ -31,6 +39,10 @@
'alt_lectures' => array('field' => 'alt_course_id',
'class' => 'LectureForTest'));
+ protected $_many_belongs_to = array('program' => array('field' => 'program_id',
+ 'class' => 'ProgramForTest',
+ 'can_be_null' => true));
+
public $save_calls = 0;
function save()
@@ -141,13 +153,25 @@
return $number;
}
- function createCourse()
+ function createCourse($program = null)
{
$course = new CourseForTest();
$course->setTitle('Course_'. rand(0, 100));
+
+ if($program)
+ $course->setProgram($program);
+
$course->save();
return $course;
}
+
+ function createProgram()
+ {
+ $program = new ProgramForTest();
+ $program->setTitle('Program_'. rand(0, 100));
+ $program->save();
+ return $program;
+ }
function createLecture($course, $alt_course = null, $title = '')
{
Modified: 3.x/trunk/limb/active_record/tests/cases/lmbActiveRecordTest.class.php
===================================================================
--- 3.x/trunk/limb/active_record/tests/cases/lmbActiveRecordTest.class.php 2008-01-17 15:36:47 UTC (rev 6693)
+++ 3.x/trunk/limb/active_record/tests/cases/lmbActiveRecordTest.class.php 2008-01-17 15:41:51 UTC (rev 6694)
@@ -653,6 +653,41 @@
$this->assertEqual($arr[2]->getCourse()->getTitle(), $course1->getTitle());
$this->assertEqual($arr[2]->getAltCourse()->getTitle(), $alt_course2->getTitle());
}
+
+ function testFindAttachRelatedObjects_HasMany()
+ {
+ $course1 = $this->creator->createCourse();
+ $course2 = $this->creator->createCourse();
+
+ $lecture1 = $this->creator->createLecture($course1, null, 'ZZZ');
+ $lecture2 = $this->creator->createLecture($course2, null, 'CCC');
+ $lecture3 = $this->creator->createLecture($course1, null, 'AAA');
+ $lecture4 = $this->creator->createLecture($course1, null, 'BBB');
+
+ $rs = lmbActiveRecord :: find('CourseForTest', array('attach' => array('lectures' => array('sort' => array('title' => 'ASC')))));
+ $arr = $rs->getArray();
+
+ //make sure we really eager fetching
+ $this->db->delete('lecture_for_test');
+
+ $this->assertIsA($arr[0], 'CourseForTest');
+ $this->assertEqual($arr[0]->getTitle(), $course1->getTitle());
+ $lectures = $arr[0]->getLectures();
+ $this->assertEqual(count($lectures), 3);
+ $this->assertEqual($lectures[0]->getId(), $lecture3->getId());
+ $this->assertEqual($lectures[0]->getTitle(), 'AAA');
+ $this->assertEqual($lectures[1]->getId(), $lecture4->getId());
+ $this->assertEqual($lectures[1]->getTitle(), 'BBB');
+ $this->assertEqual($lectures[2]->getId(), $lecture1->getId());
+ $this->assertEqual($lectures[2]->getTitle(), 'ZZZ');
+
+ $this->assertIsA($arr[1], 'CourseForTest');
+ $this->assertEqual($arr[1]->getTitle(), $course2->getTitle());
+ $lectures = $arr[1]->getLectures();
+ $this->assertEqual(count($lectures), 1);
+ $this->assertEqual($lectures[0]->getId(), $lecture2->getId());
+ $this->assertEqual($lectures[0]->getTitle(), 'CCC');
+ }
function testFindBySql()
{
More information about the limb-svn
mailing list