Skip to content

Commit

Permalink
New preloading.
Browse files Browse the repository at this point in the history
  • Loading branch information
gabordemooij committed Nov 29, 2012
1 parent d302686 commit d51b876
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 11 deletions.
49 changes: 38 additions & 11 deletions RedBean/OODB.php
Expand Up @@ -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);
}
}
}
}
}

}


90 changes: 90 additions & 0 deletions testing/RedUNIT/Base/Preloading.php
Expand Up @@ -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.