In Debug mode all SQL that happens under the hood will
be printed to the screen and/or logged.
If no database connection has been configured using R::setup() or
R::selectDatabase() this method will throw an exception.
There are 2 debug styles:
Classic: separate parameter bindings, explicit and complete but less readable
Fancy: interpersed bindings, truncates large strings, highlighted schema changes
Fancy style is more readable but sometimes incomplete.
The first parameter turns debugging ON or OFF.
The second parameter indicates the mode of operation:
0 Log and write to STDOUT classic style (default)
1 Log only, class style
2 Log and write to STDOUT fancy style
3 Log only, fancy style
This function always returns the logger instance created to generate the
debug messages.
/** * Test explicit flush. * * @return void */ public function testExplicitCacheFlush() { testpack('Test cache flush (explicit)'); R::debug(true, 1); $logger = R::getDatabaseAdapter()->getDatabase()->getLogger(); $bean = R::dispense('bean'); $bean->title = 'abc'; $id1 = R::store($bean); $logger->clear(); $bean = R::load('bean', $id1); asrt($bean->title, 'abc'); asrt(count($logger->grep('SELECT *')), 1); $bean = R::load('bean', $id1); asrt(count($logger->grep('SELECT *')), 1); R::getWriter()->flushCache(); $bean = R::load('bean', $id1); asrt(count($logger->grep('SELECT *')), 2); R::getWriter()->flushCache(); R::getWriter()->setUseCache(FALSE); }
/** * Test Full fluid UUID support. * */ public function testFullSupport() { //Rewire objects to support UUIDs. $oldToolBox = R::getToolBox(); $oldAdapter = $oldToolBox->getDatabaseAdapter(); $uuidWriter = new \UUIDWriterPostgres($oldAdapter); $newRedBean = new OODB($uuidWriter); $newToolBox = new ToolBox($newRedBean, $oldAdapter, $uuidWriter); R::configureFacadeWithToolbox($newToolBox); list($mansion, $rooms, $ghosts, $key) = R::dispenseAll('mansion,room*3,ghost*4,key'); $mansion->name = 'Haunted Mansion'; $mansion->xownRoomList = $rooms; $rooms[0]->name = 'Green Room'; $rooms[1]->name = 'Red Room'; $rooms[2]->name = 'Blue Room'; $ghosts[0]->name = 'zero'; $ghosts[1]->name = 'one'; $ghosts[2]->name = 'two'; $ghosts[3]->name = 'three'; $rooms[0]->noLoad()->sharedGhostList = array($ghosts[0], $ghosts[1]); $rooms[1]->noLoad()->sharedGhostList = array($ghosts[0], $ghosts[2]); $rooms[2]->noLoad()->sharedGhostList = array($ghosts[1], $ghosts[3], $ghosts[2]); $rooms[2]->xownKey = array($key); //Can we store a bean hierachy with UUIDs? R::debug(1); $id = R::store($mansion); //exit; asrt(is_string($id), TRUE); asrt(strlen($id), 36); $haunted = R::load('mansion', $id); asrt($haunted->name, 'Haunted Mansion'); asrt(is_string($haunted->id), TRUE); asrt(strlen($haunted->id), 36); asrt(is_array($haunted->xownRoomList), TRUE); asrt(count($haunted->ownRoom), 3); $rooms = $haunted->xownRoomList; //Do some counting... $greenRoom = NULL; foreach ($rooms as $room) { if ($room->name === 'Green Room') { $greenRoom = $room; break; } } asrt(!is_null($greenRoom), TRUE); asrt(is_array($greenRoom->with(' ORDER BY id ')->sharedGhostList), TRUE); asrt(count($greenRoom->sharedGhostList), 2); $names = array(); foreach ($greenRoom->sharedGhost as $ghost) { $names[] = $ghost->name; } sort($names); $names = implode(',', $names); asrt($names, 'one,zero'); $rooms = $haunted->xownRoomList; $blueRoom = NULL; foreach ($rooms as $room) { if ($room->name === 'Blue Room') { $blueRoom = $room; break; } } asrt(!is_null($blueRoom), TRUE); asrt(is_array($blueRoom->sharedGhostList), TRUE); asrt(count($blueRoom->sharedGhostList), 3); $names = array(); foreach ($blueRoom->sharedGhost as $ghost) { $names[] = $ghost->name; } sort($names); $names = implode(',', $names); asrt($names, 'one,three,two'); $rooms = $haunted->xownRoomList; $redRoom = NULL; foreach ($rooms as $room) { if ($room->name === 'Red Room') { $redRoom = $room; break; } } $names = array(); foreach ($redRoom->sharedGhost as $ghost) { $names[] = $ghost->name; } sort($names); $names = implode(',', $names); asrt($names, 'two,zero'); asrt(!is_null($redRoom), TRUE); asrt(is_array($redRoom->sharedGhostList), TRUE); asrt(count($redRoom->sharedGhostList), 2); //Can we repaint a room? $redRoom->name = 'Yellow Room'; $id = R::store($redRoom); $yellowRoom = R::load('room', $id); asrt($yellowRoom->name, 'Yellow Room'); asrt(!is_null($yellowRoom), TRUE); asrt(is_array($yellowRoom->sharedGhostList), TRUE); asrt(count($yellowRoom->sharedGhostList), 2); //Can we throw one ghost out? array_pop($yellowRoom->sharedGhost); R::store($yellowRoom); $yellowRoom = $yellowRoom->fresh(); asrt($yellowRoom->name, 'Yellow Room'); asrt(!is_null($yellowRoom), TRUE); asrt(is_array($yellowRoom->sharedGhostList), TRUE); asrt(count($yellowRoom->sharedGhostList), 1); //can we remove one of the rooms? asrt(R::count('key'), 1); $list = $mansion->withCondition(' "name" = ? ', array('Blue Room'))->xownRoomList; $room = reset($list); unset($mansion->xownRoomList[$room->id]); R::store($mansion); asrt(R::count('room'), 2); //and what about its dependent beans? asrt(R::count('key'), 0); asrt(R::count('ghost_room'), 3); //and can we find ghosts? $ghosts = R::find('ghost'); asrt(count($ghosts), 4); $ghosts = R::findAll('ghost', 'ORDER BY id'); asrt(count($ghosts), 4); $ghosts = R::findAll('ghost', 'ORDER BY id LIMIT 2'); asrt(count($ghosts), 2); $ghostZero = R::findOne('ghost', ' "name" = ? ', array('zero')); asrt($ghostZero instanceof OODBBean, TRUE); //can we create link properties on existing tables? $blackRoom = R::dispense('room'); $blackRoom->name = 'Black Room'; $ghostZero->link('ghost_room', array('mood' => 'grumpy'))->room = $blackRoom; R::store($ghostZero); $ghostZero = $ghostZero->fresh(); $list = $ghostZero->sharedRoomList; asrt(count($list), 3); $ghostZero = $ghostZero->fresh(); $list = $ghostZero->withCondition(' ghost_room.mood = ? ', array('grumpy'))->sharedRoomList; asrt(count($list), 1); //can we load a batch? $ids = R::getCol('SELECT id FROM ghost'); $ghosts = R::batch('ghost', $ids); asrt(count($ghosts), 4); //can we do an aggregation? $ghosts = $greenRoom->aggr('ownGhostRoom', 'ghost', 'ghost'); asrt(count($ghosts), 2); //can we duplicate the mansion? asrt(R::count('mansion'), 1); asrt(R::count('room'), 3); asrt(R::count('ghost'), 4); $copy = R::dup($mansion); R::store($copy); asrt(R::count('mansion'), 2); asrt(R::count('room'), 5); //black room does not belong to mansion 1 asrt(R::count('ghost'), 4); //can we do some counting using the list? asrt($copy->countOwn('room'), 2); $rooms = $copy->withCondition(' "name" = ? ', array('Green Room'))->xownRoomList; $room = reset($rooms); asrt($room->countShared('ghost'), 2); //Finally restore old toolbox R::configureFacadeWithToolbox($oldToolBox); }
/** * Prepare test pack (mostly: nuke the entire database) */ public function prepare() { R::freeze(FALSE); R::debug(FALSE); R::nuke(); }
/** * Test Facade transactions. * * @return void * * @throws\Exception */ public function testTransactionInFacade() { testpack('Test transaction in facade'); $bean = R::dispense('bean'); $bean->name = 'a'; R::store($bean); R::trash($bean); R::freeze(TRUE); $bean = R::dispense('bean'); $bean->name = 'a'; R::store($bean); asrt(R::count('bean'), 1); R::trash($bean); asrt(R::count('bean'), 0); $bean = R::dispense('bean'); $bean->name = 'a'; $id = R::transaction(function () use(&$bean) { return R::transaction(function () use(&$bean) { return R::store($bean); }); }); asrt((int) $id, (int) $bean->id); R::trash($bean); $bean = R::dispense('bean'); $bean->name = 'a'; $id = R::transaction(function () use(&$bean) { return R::store($bean); }); asrt((int) $id, (int) $bean->id); R::trash($bean); $bean = R::dispense('bean'); $bean->name = 'a'; try { R::transaction(function () use($bean) { R::store($bean); R::transaction(function () { throw new \Exception(); }); }); } catch (\Exception $e) { pass(); } asrt(R::count('bean'), 0); $bean = R::dispense('bean'); $bean->name = 'a'; try { R::transaction(function () use($bean) { R::transaction(function () use($bean) { R::store($bean); throw new \Exception(); }); }); } catch (\Exception $e) { pass(); } asrt(R::count('bean'), 0); $bean = R::dispense('bean'); $bean->name = 'a'; try { R::transaction(function () use($bean) { R::transaction(function () use($bean) { R::store($bean); }); }); } catch (\Exception $e) { pass(); } asrt(R::count('bean'), 1); R::freeze(FALSE); try { R::transaction('nope'); fail(); } catch (\Exception $e) { pass(); } testpack('Test Camelcase 2 underscore'); $names = array('oneACLRoute' => 'one_acl_route', 'ALLUPPERCASE' => 'alluppercase', 'clientServerArchitecture' => 'client_server_architecture', 'camelCase' => 'camel_case', 'peer2peer' => 'peer2peer', 'fromUs4You' => 'from_us4_you', 'lowercase' => 'lowercase', 'a1A2b' => 'a1a2b'); $bean = R::dispense('bean'); foreach ($names as $name => $becomes) { $bean->{$name} = 1; asrt(isset($bean->{$becomes}), TRUE); } testpack('Misc Tests'); R::debug(1); flush(); ob_start(); R::exec('SELECT 123'); $out = ob_get_contents(); ob_end_clean(); flush(); pass(); asrt(strpos($out, 'SELECT 123') !== FALSE, TRUE); R::debug(0); flush(); ob_start(); R::exec('SELECT 123'); $out = ob_get_contents(); ob_end_clean(); flush(); pass(); asrt($out, ''); R::debug(0); pass(); testpack('test to string override'); $band = R::dispense('band'); $str = strval($band); asrt($str, 'bigband'); testpack('test whether we can use isset/set in model'); $band->setProperty('property1', 123); asrt($band->property1, 123); asrt($band->checkProperty('property1'), TRUE); asrt($band->checkProperty('property2'), FALSE); $band = new \Model_Band(); $bean = R::dispense('band'); $bean->property3 = 123; $band->loadBean($bean); $bean->property4 = 345; $band->setProperty('property1', 123); asrt($band->property1, 123); asrt($band->checkProperty('property1'), TRUE); asrt($band->checkProperty('property2'), FALSE); asrt($band->property3, 123); asrt($band->property4, 345); testpack('Can we pass a\\PDO object to Setup?'); $pdo = new \PDO('sqlite:test.db'); R::addDatabase('pdo', $pdo); R::selectDatabase('pdo'); R::getCell('SELECT 123;'); testpack('Test array interface of beans'); $bean = R::dispense('bean'); $bean->hello = 'hi'; $bean->world = 'planet'; asrt($bean['hello'], 'hi'); asrt(isset($bean['hello']), TRUE); asrt(isset($bean['bye']), FALSE); $bean['world'] = 'sphere'; asrt($bean->world, 'sphere'); foreach ($bean as $key => $el) { if ($el == 'sphere' || $el == 'hi' || $el == 0) { pass(); } else { fail(); } if ($key == 'hello' || $key == 'world' || $key == 'id') { pass(); } else { fail(); } } asrt(count($bean), 3); unset($bean['hello']); asrt(count($bean), 2); asrt(count(R::dispense('countable')), 1); // Otherwise untestable... $bean->setBeanHelper(new SimpleFacadeBeanHelper()); R::getRedBean()->setBeanHelper(new SimpleFacadeBeanHelper()); pass(); // Test whether properties like owner and shareditem are still possible testpack('Test Bean Interface for Lists'); $bean = R::dispense('bean'); // Must not be list, because first char after own is lowercase asrt(is_array($bean->owner), FALSE); // Must not be list, because first char after shared is lowercase asrt(is_array($bean->shareditem), FALSE); asrt(is_array($bean->own), FALSE); asrt(is_array($bean->shared), FALSE); asrt(is_array($bean->own_item), FALSE); asrt(is_array($bean->shared_item), FALSE); asrt(is_array($bean->{'own item'}), FALSE); asrt(is_array($bean->{'shared Item'}), FALSE); }
/** * Test whether the number of update queries * executed is limited to the ones that are absolutely * necessary to sync the database. * * @return void */ public function testUpdateQueries() { $book = R::dispense('book'); $book->title = 'Eye of Wight'; $book->xownPageList = R::dispense('page', 10); $book->sharedCategoryList = R::dispense('category', 2); $n = 1; foreach ($book->xownPageList as $page) { $page->number = $n++; } $book->sharedCategory[0]->name = 'adventure'; $book->sharedCategory[1]->name = 'puzzle'; $book->author = R::dispense('author'); $book->author->name = 'John'; $book->map = R::dispense('map'); $book->map->name = 'Wight'; $book->map->xownLocationList = R::dispense('location', 3); asrt($book->getMeta('tainted'), TRUE); asrt($book->getMeta('changed'), TRUE); R::store($book); asrt($book->getMeta('tainted'), FALSE); asrt($book->getMeta('changed'), FALSE); $logger = R::debug(1, 1); $book = $book->fresh(); asrt($book->getMeta('tainted'), FALSE); asrt($book->getMeta('changed'), FALSE); $book->author; asrt($book->getMeta('tainted'), TRUE); asrt($book->getMeta('changed'), FALSE); $logger->clear(); R::store($book); //read only, no updates $numberOfUpdateQueries = $logger->grep('UPDATE'); asrt(count($numberOfUpdateQueries), 0); $book->title = 'Spirit of the Stones'; R::store($book); //changed title, 1 update $numberOfUpdateQueries = $logger->grep('UPDATE'); asrt(count($numberOfUpdateQueries), 1); $logger->clear(); //store again, no changes, no updates R::store($book); $numberOfUpdateQueries = $logger->grep('UPDATE'); asrt(count($numberOfUpdateQueries), 0); $logger->clear(); $book = $book->fresh(); $book->xownPageList; asrt($book->getMeta('tainted'), TRUE); asrt($book->getMeta('changed'), FALSE); R::store($book); //access only, no update $numberOfUpdateQueries = $logger->grep('UPDATE'); asrt(count($numberOfUpdateQueries), 0); $logger->clear(); $book = $book->fresh(); $book->sharedCategoryList; asrt($book->getMeta('tainted'), TRUE); asrt($book->getMeta('changed'), FALSE); R::store($book); //access only, no update $numberOfUpdateQueries = $logger->grep('UPDATE'); asrt(count($numberOfUpdateQueries), 0); $logger->clear(); $book = $book->fresh(); unset($book->xownPageList[5]); asrt($book->getMeta('tainted'), TRUE); asrt($book->getMeta('changed'), FALSE); R::store($book); //remove only, no update, just 1 delete $numberOfUpdateQueries = $logger->grep('UPDATE'); asrt(count($numberOfUpdateQueries), 0); $numberOfUpdateQueries = $logger->grep('DELETE'); asrt(count($numberOfUpdateQueries), 1); $book = $book->fresh(); asrt(count($book->xownPageList), 9); $logger->clear(); $book = $book->fresh(); $book->xownPageList[] = R::dispense('page'); asrt($book->getMeta('tainted'), TRUE); asrt($book->getMeta('changed'), FALSE); R::store($book); //no update, 1 insert, just adding $numberOfUpdateQueries = $logger->grep('UPDATE'); asrt(count($numberOfUpdateQueries), 0); $numberOfUpdateQueries = $logger->grep('INSERT'); asrt(count($numberOfUpdateQueries), 1); $book = $book->fresh(); asrt(count($book->xownPageList), 10); $logger->clear(); $book = $book->fresh(); $book->map->xownLocationList[1]->name = 'Horshoe Bay'; asrt($book->getMeta('tainted'), TRUE); asrt($book->getMeta('changed'), FALSE); asrt($book->map->getMeta('tainted'), TRUE); asrt($book->map->getMeta('changed'), FALSE); asrt($book->map->xownLocationList[1]->getMeta('tainted'), TRUE); asrt($book->map->xownLocationList[1]->getMeta('changed'), TRUE); R::store($book); //1 update for child of parent, no other updates $numberOfUpdateQueries = $logger->grep('UPDATE'); asrt(count($numberOfUpdateQueries), 1); $book = $book->fresh(); asrt($book->map->xownLocationList[1]->name, 'Horshoe Bay'); $logger->clear(); R::store($book); //just access, no updates $numberOfUpdateQueries = $logger->grep('UPDATE'); asrt(count($numberOfUpdateQueries), 0); $logger->clear(); $book = $book->fresh(); $book->ownPageList[2]->number = 99; R::store($book); //1 update, do not update rest of pages or book itself $numberOfUpdateQueries = $logger->grep('UPDATE'); asrt(count($numberOfUpdateQueries), 1); $book = $book->fresh(); $book->author->name = 'Worsley'; $logger->clear(); R::store($book); //1 update for parent $numberOfUpdateQueries = $logger->grep('UPDATE'); asrt(count($numberOfUpdateQueries), 1); $author = R::dispense('author'); $author->name = 'J.W.'; R::store($author); $book = $book->fresh(); $book->author = $author; $author->name = 'JW'; $logger->clear(); R::store($book); //2 updates, one for author, one for link field: author_id needs update. $numberOfUpdateQueries = $logger->grep('UPDATE'); asrt(count($numberOfUpdateQueries), 2); $author->country = R::dispense('country')->setAttr('name', 'England'); R::store($author); $book = $book->fresh(); $book->author->country->name = 'Wight'; $logger->clear(); R::store($book); //1 update, country only, dont update for intermediate parents: book -> author -> ... $numberOfUpdateQueries = $logger->grep('UPDATE'); asrt(count($numberOfUpdateQueries), 1); }
/** * Test basic and complex common usage scenarios for * relations and associations. * * @return void */ public function testScenarios() { list($q1, $q2) = R::dispense('quote', 2); list($pic1, $pic2) = R::dispense('picture', 2); list($book, $book2, $book3) = R::dispense('book', 4); list($topic1, $topic2, $topic3, $topic4, $topic5) = R::dispense('topic', 5); list($page1, $page2, $page3, $page4, $page5, $page6, $page7) = R::dispense('page', 7); $q1->text = 'lorem'; $q2->text = 'ipsum'; $book->title = 'abc'; $book2->title = 'def'; $book3->title = 'ghi'; $page1->title = 'pagina1'; $page2->title = 'pagina2'; $page3->title = 'pagina3'; $page4->title = 'pagina4'; $page5->title = 'pagina5'; $page6->title = 'cover1'; $page7->title = 'cover2'; $topic1->name = 'holiday'; $topic2->name = 'cooking'; $topic3->name = 'gardening'; $topic4->name = 'computing'; $topic5->name = 'christmas'; // Add one page to the book $book->ownPage[] = $page1; $id = R::store($book); asrt(count($book->ownPage), 1); asrt(reset($book->ownPage)->getMeta('type'), 'page'); $book = R::load('book', $id); asrt(count($book->ownPage), 1); asrt(reset($book->ownPage)->getMeta('type'), 'page'); // Performing an own addition $book->ownPage[] = $page2; $id = R::store($book); $book = R::load('book', $id); asrt(count($book->ownPage), 2); // Performing a deletion $book = R::load('book', $id); unset($book->ownPage[1]); $id = R::store($book); $book = R::load('book', $id); asrt(count($book->ownPage), 1); asrt(reset($book->ownPage)->getMeta('type'), 'page'); asrt(R::count('page'), 2); //still exists asrt(reset($book->ownPage)->id, '2'); // Doing a change in one of the owned items $book->ownPage[2]->title = 'page II'; $id = R::store($book); $book = R::load('book', $id); asrt(reset($book->ownPage)->title, 'page II'); // Change by reference now... don't copy! $refToPage2 = $book->ownPage[2]; $refToPage2->title = 'page II b'; $id = R::store($book); $book = R::load('book', $id); asrt(reset($book->ownPage)->title, 'page II b'); // Doing all actions combined $book->ownPage[] = $page3; R::store($book); $book = R::load('book', $id); unset($book->ownPage[2]); // And test custom key $book->ownPage['customkey'] = $page4; $book->ownPage[3]->title = "THIRD"; R::store($book); $book = R::load('book', $id); asrt(count($book->ownPage), 2); $p4 = $book->ownPage[4]; $p3 = $book->ownPage[3]; asrt($p4->title, 'pagina4'); asrt($p3->title, 'THIRD'); // Test replacing an element $book = R::load('book', $id); $book->ownPage[4] = $page5; R::store($book); $book = R::load('book', $id); asrt(count($book->ownPage), 2); $p5 = $book->ownPage[5]; asrt($p5->title, 'pagina5'); // Other way around - single bean asrt($p5->book->title, 'abc'); asrt(R::load('page', 5)->book->title, 'abc'); asrt(R::load('page', 3)->book->title, 'abc'); // Add the other way around - single bean $page1->id = 0; $page1->book = $book2; $page1 = R::load('page', R::store($page1)); asrt($page1->book->title, 'def'); $b2 = R::load('book', $id); asrt(count($b2->ownPage), 2); // Remove the other way around - single bean unset($page1->book); R::store($page1); $b2 = R::load('book', $book2->id); asrt(count($b2->ownPage), 1); //does not work $page1->book = NULL; R::store($page1); $b2 = R::load('book', $book2->id); asrt(count($b2->ownPage), 0); //works // Re-add the page $b2->ownPage[] = $page1; R::store($b2); $b2 = R::load('book', $book2->id); asrt(count($b2->ownPage), 1); // Different, less elegant way to remove $page1 = reset($b2->ownPage); $page1->book_id = NULL; R::store($page1); $b2 = R::load('book', $book2->id); asrt(count($b2->ownPage), 0); // Re-add the page $b2->ownPage[] = $page1; R::store($b2); $b2 = R::load('book', $book2->id); asrt(count($b2->ownPage), 1); // Another less elegant way to remove $page1->book = NULL; R::store($page1); $cols = R::getColumns('page'); asrt(isset($cols['book']), FALSE); $b2 = R::load('book', $book2->id); asrt(count($b2->ownPage), 0); // Re-add the page $b2->ownPage[] = $page1; R::store($b2); $b2 = R::load('book', $book2->id); asrt(count($b2->ownPage), 1); // Another less elegant... just plain ugly... way to remove $page1->book = FALSE; R::store($page1); $cols = R::getColumns('page'); asrt(isset($cols['book']), FALSE); $b2 = R::load('book', $book2->id); asrt(count($b2->ownPage), 0); // Re-add the page $b2->ownPage[] = $page1; R::store($b2); $b2 = R::load('book', $book2->id); asrt(count($b2->ownPage), 1); // You are not allowed to re-use the field for something else foreach (array(1, -2.1, array(), TRUE, 'NULL', new \stdClass(), 'just a string', array('a' => 1), 0) as $value) { try { $page1->book = $value; fail(); } catch (RedException $e) { pass(); } } // Test fk, not allowed to set to 0 $page1 = reset($b2->ownPage); $page1->book_id = 0; // Even uglier way, but still needs to work $page1 = reset($b2->ownPage); $page1->book_id = NULL; R::store($b2); $b2 = R::load('book', $book2->id); asrt(count($b2->ownPage), 0); // Test shared items $book = R::load('book', $id); $book->sharedTopic[] = $topic1; $id = R::store($book); // Add an item asrt(count($book->sharedTopic), 1); asrt(reset($book->sharedTopic)->name, 'holiday'); $book = R::load('book', $id); asrt(count($book->sharedTopic), 1); asrt(reset($book->sharedTopic)->name, 'holiday'); // Add another item $book->sharedTopic[] = $topic2; $id = R::store($book); $tidx = R::store(R::dispense('topic')); $book = R::load('book', $id); asrt(count($book->sharedTopic), 2); $t1 = $book->sharedTopic[1]; $t2 = $book->sharedTopic[2]; asrt($t1->name, 'holiday'); asrt($t2->name, 'cooking'); // Remove an item unset($book->sharedTopic[2]); asrt(count($book->sharedTopic), 1); $id = R::store($book); $book = R::load('book', $id); asrt(count($book->sharedTopic), 1); asrt(reset($book->sharedTopic)->name, 'holiday'); // Add and change $book->sharedTopic[] = $topic3; $book->sharedTopic[1]->name = 'tropics'; $id = R::store($book); $book = R::load('book', $id); asrt(count($book->sharedTopic), 2); asrt($book->sharedTopic[1]->name, 'tropics'); testids($book->sharedTopic); R::trash(R::load('topic', $tidx)); $id = R::store($book); $book = R::load('book', $id); // Delete without save unset($book->sharedTopic[1]); $book = R::load('book', $id); asrt(count($book->sharedTopic), 2); $book = R::load('book', $id); // Delete without init asrt(R::count('topic'), 3); unset($book->sharedTopic[1]); $id = R::store($book); asrt(R::count('topic'), 3); asrt(count($book->sharedTopic), 1); asrt(count($book2->sharedTopic), 0); // Add same topic to other book $book2->sharedTopic[] = $topic3; asrt(count($book2->sharedTopic), 1); $id2 = R::store($book2); asrt(count($book2->sharedTopic), 1); $book2 = R::load('book', $id2); asrt(count($book2->sharedTopic), 1); // Get books for topic asrt($topic3->countShared('book'), 2); $t3 = R::load('topic', $topic3->id); asrt(count($t3->sharedBook), 2); // Nuke an own-array, replace entire array at once without getting first $page2->id = 0; $page2->title = 'yet another page 2'; $page4->id = 0; $page4->title = 'yet another page 4'; $book = R::load('book', $id); $book->ownPage = array($page2, $page4); R::store($book); $book = R::load('book', $id); asrt(count($book->ownPage), 2); asrt(reset($book->ownPage)->title, 'yet another page 2'); asrt(end($book->ownPage)->title, 'yet another page 4'); testids($book->ownPage); // Test with alias format $book3->cover = $page6; $idb3 = R::store($book3); $book3 = R::load('book', $idb3); $justACover = $book3->fetchAs('page')->cover; asrt($book3->cover instanceof OODBBean, TRUE); asrt($justACover->title, 'cover1'); // No page property asrt(isset($book3->page), FALSE); // Test doubling and other side effects ... should not occur.. $book3->sharedTopic = array($topic1, $topic2); $book3 = R::load('book', R::store($book3)); $book3->sharedTopic = array(); $book3 = R::load('book', R::store($book3)); asrt(count($book3->sharedTopic), 0); $book3->sharedTopic[] = $topic1; $book3 = R::load('book', R::store($book3)); // Added only one, not more? asrt(count($book3->sharedTopic), 1); asrt(intval(R::getCell("select count(*) from book_topic where book_id = {$idb3}")), 1); // Add the same $book3->sharedTopic[] = $topic1; $book3 = R::load('book', R::store($book3)); asrt(count($book3->sharedTopic), 1); asrt(intval(R::getCell("select count(*) from book_topic where book_id = {$idb3}")), 1); $book3->sharedTopic['differentkey'] = $topic1; $book3 = R::load('book', R::store($book3)); asrt(count($book3->sharedTopic), 1); asrt(intval(R::getCell("select count(*) from book_topic where book_id = {$idb3}")), 1); // Ugly assign, auto array generation $book3->ownPage[] = $page1; $book3 = R::load('book', R::store($book3)); asrt(count($book3->ownPage), 1); asrt(intval(R::getCell("select count(*) from page where book_id = {$idb3} ")), 1); $book3 = R::load('book', $idb3); $book3->ownPage = array(); // No change until saved asrt(intval(R::getCell("select count(*) from page where book_id = {$idb3} ")), 1); $book3 = R::load('book', R::store($book3)); asrt(intval(R::getCell("select count(*) from page where book_id = {$idb3} ")), 0); asrt(count($book3->ownPage), 0); $book3 = R::load('book', $idb3); /** * Why do I need to do this ---> why does trash() not set id -> 0? * Because you unset() so trash is done on origin not bean */ $page1->id = 0; $page2->id = 0; $page3->id = 0; $book3->ownPage[] = $page1; $book3->ownPage[] = $page2; $book3->ownPage[] = $page3; $book3 = R::load('book', R::store($book3)); asrt(intval(R::getCell("select count(*) from page where book_id = {$idb3} ")), 3); asrt(count($book3->ownPage), 3); unset($book3->ownPage[$page2->id]); $book3->ownPage[] = $page3; $book3->ownPage['try_to_trick_ya'] = $page3; $book3 = R::load('book', R::store($book3)); asrt(intval(R::getCell("select count(*) from page where book_id = {$idb3} ")), 2); asrt(count($book3->ownPage), 2); // Delete and re-add $book3 = R::load('book', $idb3); unset($book3->ownPage[10]); $book3->ownPage[] = $page1; $book3 = R::load('book', R::store($book3)); asrt(count($book3->ownPage), 2); $book3 = R::load('book', $idb3); unset($book3->sharedTopic[1]); $book3->sharedTopic[] = $topic1; $book3 = R::load('book', R::store($book3)); asrt(count($book3->sharedTopic), 1); // Test performance $logger = R::debug(true, 1); $book = R::load('book', 1); $book->sharedTopic = array(); R::store($book); // No more than 1 update asrt(count($logger->grep('UPDATE')), 1); $book = R::load('book', 1); $logger->clear(); print_r($book->sharedTopic, 1); // No more than 1 select asrt(count($logger->grep('SELECT')), 1); $logger->clear(); $book->sharedTopic[] = $topic1; $book->sharedTopic[] = $topic2; asrt(count($logger->grep('SELECT')), 0); R::store($book); $book->sharedTopic[] = $topic3; // Now do NOT clear all and then add one, just add the one $logger->clear(); R::store($book); $book = R::load('book', 1); asrt(count($book->sharedTopic), 3); // No deletes asrt(count($logger->grep("DELETE FROM")), 0); $book->sharedTopic['a'] = $topic3; unset($book->sharedTopic['a']); R::store($book); $book = R::load('book', 1); asrt(count($book->sharedTopic), 3); // No deletes asrt(count($logger->grep("DELETE FROM")), 0); $book->ownPage = array(); R::store($book); asrt(count($book->ownPage), 0); $book->ownPage[] = $page1; $book->ownPage['a'] = $page2; asrt(count($book->ownPage), 2); R::store($book); unset($book->ownPage['a']); asrt(count($book->ownPage), 2); unset($book->ownPage[11]); R::store($book); $book = R::load('book', 1); asrt(count($book->ownPage), 1); $aPage = $book->ownPage[10]; unset($book->ownPage[10]); $aPage->title .= ' changed '; $book->ownPage['anotherPage'] = $aPage; $logger->clear(); R::store($book); // if ($db=="mysql") asrt(count($logger->grep("SELECT")),0); $book = R::load('book', 1); asrt(count($book->ownPage), 1); $ap = reset($book->ownPage); asrt($ap->title, "pagina1 changed "); // Fix udiff instead of diff $book3->ownPage = array($page3, $page1); $i = R::store($book3); $book3 = R::load('book', $i); asrt(intval(R::getCell("select count(*) from page where book_id = {$idb3} ")), 2); asrt(count($book3->ownPage), 2); $pic1->name = 'aaa'; $pic2->name = 'bbb'; R::store($pic1); R::store($q1); $book3->ownPicture[] = $pic1; $book3->ownQuote[] = $q1; $book3 = R::load('book', R::store($book3)); // two own-arrays -->forgot array_merge asrt(count($book3->ownPicture), 1); asrt(count($book3->ownQuote), 1); asrt(count($book3->ownPage), 2); $book3 = R::load('book', R::store($book3)); unset($book3->ownPicture[1]); $book3 = R::load('book', R::store($book3)); asrt(count($book3->ownPicture), 0); asrt(count($book3->ownQuote), 1); asrt(count($book3->ownPage), 2); $book3 = R::load('book', R::store($book3)); $NOTE = 0; $quotes = R::dispense('quote', 10); foreach ($quotes as &$justSomeQuote) { $justSomeQuote->note = 'note' . ++$NOTE; } $pictures = R::dispense('picture', 10); foreach ($pictures as &$justSomePic) { $justSomePic->note = 'note' . ++$NOTE; } $topics = R::dispense('topic', 10); foreach ($topics as &$justSomeTopic) { $justSomeTopic->note = 'note' . ++$NOTE; } for ($j = 0; $j < 10; $j++) { // Do several mutations for ($x = 0; $x < rand(1, 20); $x++) { modgr($book3, $quotes, $pictures, $topics); } $qbefore = count($book3->ownQuote); $pbefore = count($book3->ownPicture); $tbefore = count($book3->sharedTopic); $qjson = json_encode($book->ownQuote); $pjson = json_encode($book->ownPicture); $tjson = json_encode($book->sharedTopic); $book3 = R::load('book', R::store($book3)); asrt(count($book3->ownQuote), $qbefore); asrt(count($book3->ownPicture), $pbefore); asrt(count($book3->sharedTopic), $tbefore); asrt(json_encode($book->ownQuote), $qjson); asrt(json_encode($book->ownPicture), $pjson); asrt(json_encode($book->sharedTopic), $tjson); testids($book->ownQuote); testids($book->ownPicture); testids($book->sharedTopic); } }
/** * Test duplication and caching. * * @return void */ public function DupAndCache() { testpack('Dup() and Cache'); $can = R::dispense('can')->setAttr('size', 3); $can->ownCoffee[] = R::dispense('coffee')->setAttr('color', 'black'); $can->sharedTag[] = R::dispense('tag')->setAttr('name', 'cool'); $can = R::load('can', R::store($can)); $d = new DuplicationManager(R::getToolBox()); $d->setCacheTables(TRUE); ob_start(); R::debug(1); $x = $d->dup($can); $queries = ob_get_contents(); R::debug(0); ob_end_clean(); $len1 = strlen($queries); asrt($len1 > 40, TRUE); asrt(isset($x->ownCoffee), TRUE); asrt(count($x->ownCoffee), 1); asrt(isset($x->sharedTag), TRUE); asrt(count($x->sharedTag), 1); $cache = $d->getSchema(); R::nuke(); $can = R::dispense('can')->setAttr('size', 3); $can->ownCoffee[] = R::dispense('coffee')->setAttr('color', 'black'); $can->sharedTag[] = R::dispense('tag')->setAttr('name', 'cool'); $can = R::load('can', R::store($can)); $d = new DuplicationManager(R::getToolBox()); /** * $cache = '{"book": { * "id": "INTEGER", * "title": "TEXT" * }, "bean": { * "id": "INTEGER", * "prop": "INTEGER" * }, "pessoa": { * "id": "INTEGER", * "nome": "TEXT", * "nome_meio": "TEXT", * "sobrenome": "TEXT", * "nascimento": "NUMERIC", * "reg_owner": "TEXT" * }, "documento": { * "id": "INTEGER", * "nome_documento": "TEXT", * "numero_documento": "TEXT", * "reg_owner": "TEXT", * "ownPessoa_id": "INTEGER" * }, "can": { * "id": "INTEGER", * "size": "INTEGER" * }, "coffee": { * "id": "INTEGER", * "color": "TEXT", * "can_id": "INTEGER" * }, "tag": { * "id": "INTEGER", * "name": "TEXT" * }, "can_tag": { * "id": "INTEGER", * "tag_id": "INTEGER", * "can_id": "INTEGER" * }}' */ $d->setTables($cache); ob_start(); R::debug(1); $x = $d->dup($can); $queries = ob_get_contents(); ob_end_clean(); R::debug(0); $len2 = strlen($queries); asrt(isset($x->ownCoffee), TRUE); asrt(count($x->ownCoffee), 1); asrt(isset($x->sharedTag), TRUE); asrt(count($x->sharedTag), 1); asrt(json_encode($cache), json_encode($d->getSchema())); asrt($len1 > $len2, TRUE); }
/** * Tests freezing the database. * After freezing the database, schema modifications are no longer * allowed and referring to missing columns will now cause exceptions. * * @return void */ public function testFreezer() { $toolbox = R::getToolBox(); $adapter = $toolbox->getDatabaseAdapter(); $writer = $toolbox->getWriter(); $redbean = $toolbox->getRedBean(); $pdo = $adapter->getDatabase(); $a = new AssociationManager($toolbox); $post = $redbean->dispense('post'); $post->title = 'title'; $redbean->store($post); $page = $redbean->dispense('page'); $page->name = 'title'; $redbean->store($page); $page = $redbean->dispense("page"); $page->name = "John's page"; $idpage = $redbean->store($page); $page2 = $redbean->dispense("page"); $page2->name = "John's second page"; $idpage2 = $redbean->store($page2); $a->associate($page, $page2); $redbean->freeze(TRUE); $page = $redbean->dispense("page"); $page->sections = 10; $page->name = "half a page"; try { $id = $redbean->store($page); fail(); } catch (SQL $e) { pass(); } $post = $redbean->dispense("post"); $post->title = "existing table"; try { $id = $redbean->store($post); pass(); } catch (SQL $e) { fail(); } asrt(in_array("name", array_keys($writer->getColumns("page"))), TRUE); asrt(in_array("sections", array_keys($writer->getColumns("page"))), FALSE); $newtype = $redbean->dispense("newtype"); $newtype->property = 1; try { $id = $redbean->store($newtype); fail(); } catch (SQL $e) { pass(); } $logger = R::debug(true, 1); // Now log and make sure no 'describe SQL' happens $page = $redbean->dispense("page"); $page->name = "just another page that has been frozen..."; $id = $redbean->store($page); $page = $redbean->load("page", $id); $page->name = "just a frozen page..."; $redbean->store($page); $page2 = $redbean->dispense("page"); $page2->name = "an associated frozen page"; $a->associate($page, $page2); $a->related($page, "page"); $a->unassociate($page, $page2); $a->clearRelations($page, "page"); $items = $redbean->find("page", array(), array("1")); $redbean->trash($page); $redbean->freeze(FALSE); asrt(count($logger->grep("SELECT")) > 0, TRUE); asrt(count($logger->grep("describe")) < 1, TRUE); asrt(is_array($logger->getLogs()), TRUE); R::debug(false); }
public static function ConfigSetup($arrconfig = null) { if (is_array($arrconfig) && !empty($arrconfig)) { if ($arrconfig['server']) { self::$server = $arrconfig['server']; } if ($arrconfig['databasename']) { self::$databasename = $arrconfig['databasename']; } if ($arrconfig['username']) { self::$username = $arrconfig['username']; } if ($arrconfig['password']) { self::$password = $arrconfig['password']; } if ($arrconfig['port']) { self::$port = $arrconfig['port']; } } self::$connection = new PDO('mysql:host=' . self::$server . ';port=' . self::$port . ';dbname=' . self::$databasename . ';', self::$username, self::$password); self::$connection->query('SET NAMES utf8'); R::setup(self::$connection); R::freeze(true); self::$logsrv = new \RedBeanPHP\Plugin\SystemlogsService(); R::debug(true, 1); }
/** * Test whether findOne gets a LIMIT 1 * clause. * * @return void */ public function testFindOneLimitOne() { R::nuke(); list($book1, $book2) = R::dispense('book', 2); $book1->title = 'a'; $book2->title = 'b'; R::storeAll(array($book1, $book2)); $logger = R::debug(1, 1); $logger->clear(); $found = R::findOne('book'); asrt(count($logger->grep('LIMIT 1')), 1); asrt($found instanceof \RedBeanPHP\OODBBean, TRUE); $logger->clear(); $found = R::findOne('book', ' title = ? ', array('a')); asrt(count($logger->grep('LIMIT 1')), 1); asrt($found instanceof \RedBeanPHP\OODBBean, TRUE); $logger->clear(); $found = R::findOne('book', ' title = ? LIMIT 1', array('b')); asrt(count($logger->grep('LIMIT 1')), 1); $logger->clear(); $found = R::findOne('book', ' title = ? limit 1', array('b')); asrt(count($logger->grep('LIMIT 1')), 0); asrt(count($logger->grep('limit 1')), 1); asrt($found instanceof \RedBeanPHP\OODBBean, TRUE); $found = R::findOne('book', ' title = ? LIMIT 2', array('b')); asrt(count($logger->grep('LIMIT 2')), 1); asrt($found instanceof \RedBeanPHP\OODBBean, TRUE); }