Permalink
Browse files

New preloading.

  • Loading branch information...
gabordemooij committed Nov 29, 2012
1 parent d302686 commit d51b8766833ecdee4204f140e5c4e735d39dfab3
Showing with 128 additions and 11 deletions.
  1. +38 −11 RedBean/OODB.php
  2. +90 −0 testing/RedUNIT/Base/Preloading.php
View
@@ -895,25 +895,52 @@ public function setDepList($dep) {
*/
public function preload($beans, $types) {
foreach($types as $key => $type) {
- $map = array();
- $field = (is_numeric($key)) ? $type : $key;
- $ids = array();
- foreach($beans as $bean) {
- if($id = $bean->{$field.'_id'}){
+ $map = $ids = array();
+ $field = (is_numeric($key)) ? $type : $key;//use an alias?
+ $filteredBeans = $beans;
+ while($p = strpos($field,'.')) { //filtering: find the right beans in the path
+ $nesting = substr($field,0,$p);
+ $filtered = array();
+ foreach($filteredBeans as $bean) {
+ if (is_array($bean->$nesting)) {
+ $filtered = array_merge($filtered,$bean->$nesting);
+ } elseif (!is_null($bean->$nesting)) {
+ $filtered[] = $bean->$nesting;
+ }
+ }
+ $filteredBeans = $filtered;
+ $field = substr($field,$p+1);
+ }
+ if (strpos($type,'.')) $type = $field;
+ foreach($filteredBeans as $bean) { //gather ids to load the desired bean collections
+ if (strpos($field,'own')===0) { //based on bean->id for ownlist
+ $id = $bean->id;
+ $ids[$id] = $id;
+ } elseif($id = $bean->{$field.'_id'}){ //based on bean_id for parent
$ids[$id] = $id;
if (!isset($map[$id])) $map[$id] = array();
$map[$id][] = $bean;
}
}
- $parents = $this->batch($type,$ids);
- foreach($parents as $parent) {
- foreach($map[$parent->id] as $childBean) {
- $childBean->setProperty($field,$parent);
+ if (strpos($field,'own')===0) {//preload for own-list using find
+ $link = $bean->getMeta('type').'_id';
+ $children = $this->find($type,array($link=>$ids));
+ foreach($filteredBeans as $bean) {
+ $list = array();
+ foreach($children as $child) {
+ if ($child->$link==$bean->id) $list[$child->id] = $child;
+ }
+ $bean->setProperty($field,$list);
}
- }
+ } else { //preload for parent objects using batch()
+ foreach($this->batch($type,$ids) as $parent) {
+ foreach($map[$parent->id] as $childBean) {
+ $childBean->setProperty($field,$parent);
+ }
+ }
+ }
}
}
-
}
@@ -149,6 +149,96 @@ public function run() {
asrt($item->author->name,'John');
}
+ //test nested bean preloading
+ R::nuke();
+ $authors = R::dispense('author',2);
+ foreach($authors as $author) {
+ $author->ownBook = R::dispense('book',2);
+ foreach($author->ownBook as $book) {
+ $book->ownPage = R::dispense('page',2);
+ foreach($book->ownPage as $page) $page->ownText = R::dispense('text',1);
+ }
+ }
+ R::storeAll($authors);
+ $texts = R::find('text');
+ R::nuke();
+ $text = reset($texts);
+ asrt(($text->page),null);
+
+ //now with preloading
+ R::nuke();
+ $authors = R::dispense('author',2);
+ foreach($authors as $author) {
+ $author->ownBook = R::dispense('book',2);
+ foreach($author->ownBook as $book) {
+ $book->ownPage = R::dispense('page',2);
+ foreach($book->ownPage as $page) $page->ownText = R::dispense('text',2);
+ }
+ }
+ R::storeAll($authors);
+ $texts = R::find('text');
+ R::preload($texts,array('page','page.book','page.book.author'));
+ R::nuke();
+ $text = reset($texts);
+ asrt(($text->page->id)>0,true);
+ asrt(($text->page->book->id)>0,true);
+ asrt(($text->page->book->author->id)>0,true);
+
+ R::nuke();
+ $authors = R::dispense('author',2);
+ foreach($authors as $author) {
+ $author->alias('coauthor')->ownBook = R::dispense('book',2);
+ foreach($author->alias('coauthor')->ownBook as $book) {
+ $book->ownPage = R::dispense('page',2);
+ foreach($book->ownPage as $page) $page->ownText = R::dispense('text',2);
+ }
+ }
+ R::storeAll($authors);
+ $texts = R::find('text');
+ R::preload($texts,array('page','page.book','page.book.coauthor'=>'author'));
+ R::nuke();
+ $text = reset($texts);
+ asrt(($text->page->id)>0,true);
+ asrt(($text->page->book->id)>0,true);
+ asrt(($text->page->book->fetchAs('author')->coauthor->id)>0,true);
+
+ //now test preloading of own-lists
+ R::nuke();
+ $authors = R::dispense('author',2);
+ foreach($authors as $author) {
+ $author->ownBook = R::dispense('book',2);
+ foreach($author->ownBook as $book) {
+ $book->ownPage = R::dispense('page',2);
+ foreach($book->ownPage as $page) $page->ownText = R::dispense('text',2);
+ }
+ }
+ R::storeAll($authors);
+ $authors = R::find('author');
+ R::preload($authors,array('ownBook'=>'book','ownBook.ownPage'=>'page','ownBook.ownPage.ownText'=>'text'));
+ R::nuke();
+ $author = reset($authors);
+ asrt(count($author->ownBook),2);
+ $book = reset($author->ownBook);
+ asrt(count($book->ownPage),2);
+ $page = reset($book->ownPage);
+ asrt(count($page->ownText),2);
+
+ //now test with empty beans
+ $authors = R::dispense('author',2);
+ R::storeAll($authors);
+ $authors = R::find('author');
+ R::preload($authors,array('ownBook'=>'book','ownBook.ownPage'=>'page','ownBook.ownPage.ownText'=>'text'));
+ $author = reset($authors);
+ asrt(count($author->ownBook),0);
+
+ $texts = R::dispense('text',2);
+ R::storeAll($texts);
+ $texts = R::find('text');
+ R::preload($texts,array('page','page.book'));
+ $text = reset($texts);
+ asrt($text->page,null);
+
+
}
}

0 comments on commit d51b876

Please sign in to comment.