/** * Tests automatic resolvement of parent beans * without fetchAs() using inferFetchType (foreign keys). * * @return void */ public function testAutoResolver() { R::nuke(); list($project, $teacher, $student) = R::dispenseAll('project,person,person'); $teacher->name = 'teacher'; $student->name = 'student'; $project->teacher = $teacher; $project->student = $student; R::store($project); $project = $project->fresh(); asrt($project->teacher instanceof OODBBean, TRUE); asrt($project->student instanceof OODBBean, TRUE); asrt($project->teacher->name, 'teacher'); asrt($project->student->name, 'student'); $project2 = R::dispense('project'); $teacher2 = R::dispense('person'); $teacher2->name = 'teacher2'; $project2->teacher = $teacher2; R::store($project2); $project2 = $project2->fresh(); asrt($project2->teacher instanceof OODBBean, TRUE); asrt($project2->teacher->name, 'teacher2'); asrt(is_null($project2->student), TRUE); $project = $project->fresh(); asrt($project->fetchAs('person')->teacher instanceof OODBBean, TRUE); asrt($project->fetchAs('person')->student instanceof OODBBean, TRUE); asrt($project->fetchAs('person')->teacher->name, 'teacher'); asrt($project->fetchAs('person')->student->name, 'student'); $project = $project->fresh(); $export = R::exportAll(array($project), TRUE); asrt(isset($export[0]['teacher']['name']), TRUE); asrt(isset($export[0]['student']['name']), TRUE); asrt($export[0]['teacher']['name'], 'teacher'); asrt($export[0]['student']['name'], 'student'); //Also test the default implementation... $nullWriter = new \NullWriter(R::getDatabaseAdapter()); asrt(is_null($nullWriter->inferFetchType('test', 'test')), TRUE); //Realteacher should take precedence over fetchAs-teacher, name conventions first! //also: ensure we do not use autoresolv for anything except when truly necessary! (performance) $realTeacher = R::dispense('teacher'); $realTeacher->name = 'real'; R::store($realTeacher); //ID must be same asrt($realTeacher->id, $teacher->id); $project = $project->fresh(); asrt($project->teacher->name, 'real'); }
/** * Test parameter binding. * * @return void */ public function testParamBindingWithPostgres() { testpack("param binding pgsql"); $page = R::dispense("page"); $page->name = "abc"; $page->number = 2; R::store($page); R::exec("insert into page (name) values(:name) ", array(":name" => "my name")); R::exec("insert into page (number) values(:one) ", array(":one" => 1)); R::exec("insert into page (number) values(:one) ", array(":one" => "1")); R::exec("insert into page (number) values(:one) ", array(":one" => "1234")); R::exec("insert into page (number) values(:one) ", array(":one" => "-21")); pass(); testpack('Test whether we can properly bind and receive NULL values'); $adapter = R::getDatabaseAdapter(); asrt($adapter->getCell('SELECT TEXT( :nil ) ', array(':nil' => 'NULL')), 'NULL'); asrt($adapter->getCell('SELECT TEXT( :nil ) ', array(':nil' => NULL)), NULL); asrt($adapter->getCell('SELECT TEXT( ? ) ', array('NULL')), 'NULL'); asrt($adapter->getCell('SELECT TEXT( ? ) ', array(NULL)), NULL); }
/** * Can we manually set a logger and enable logging? * * @return void */ public function testCanSetLogger() { R::nuke(); R::store(R::dispense('bean')); $logger = new RDefault(); $logger->setMode(RDefault::C_LOGGER_ARRAY); $database = R::getDatabaseAdapter()->getDatabase(); $database->setLogger($logger); asrt($database->getLogger(), $logger); $database->setEnableLogging(FALSE); $logs = $logger->getLogs(); asrt(is_array($logs), TRUE); asrt(count($logs), 0); $database->setEnableLogging(TRUE); $logs = $logger->getLogs(); asrt(is_array($logs), TRUE); asrt(count($logs), 0); R::findOne('bean'); //writes 3 log entries $logs = $logger->getLogs(); asrt(is_array($logs), TRUE); asrt(count($logs), 3); }
/** * 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); }
/** * Tests FUSE and lists, FUSE enforces no more than * 3 sugar cubes in coffee. * * @return void */ public function testCoffeeWithSugarAndFUSE() { $coffee = R::dispense('coffee'); $coffee->size = 'XL'; $coffee->ownSugar = R::dispense('sugar', 5); $id = R::store($coffee); $coffee = R::load('coffee', $id); asrt(count($coffee->ownSugar), 3); $coffee->ownSugar = R::dispense('sugar', 2); $id = R::store($coffee); $coffee = R::load('coffee', $id); asrt(count($coffee->ownSugar), 2); $cocoa = R::dispense('cocoa'); $cocoa->name = 'Fair Cocoa'; list($taste1, $taste2) = R::dispense('taste', 2); $taste1->name = 'sweet'; $taste2->name = 'bitter'; $cocoa->ownTaste = array($taste1, $taste2); R::store($cocoa); $cocoa->name = 'Koko'; R::store($cocoa); if (method_exists(R::getDatabaseAdapter()->getDatabase(), 'getPDO')) { $pdo = R::getDatabaseAdapter()->getDatabase()->getPDO(); $driver = new RPDO($pdo); pass(); asrt($pdo->getAttribute(\PDO::ATTR_ERRMODE), \PDO::ERRMODE_EXCEPTION); asrt($pdo->getAttribute(\PDO::ATTR_DEFAULT_FETCH_MODE), \PDO::FETCH_ASSOC); asrt(strval($driver->GetCell('select 123')), '123'); } $a = new SQL(); $a->setSqlState('test'); $b = strval($a); asrt(strpos($b, '[test] - ') === 0, TRUE); }
/** * Issue #171 * The index name argument is not unique in processEmbeddedBean etc. * * @return void */ public function testIssue171() { R::getDatabaseAdapter()->addEventListener('sql_exec', $this); $account = R::dispense('account'); $user = R::dispense('user'); $player = R::dispense('player'); $account->ownUser[] = $user; R::store($account); asrt(strpos(implode(',', $this->queries), 'index_foreignkey_user_account') !== FALSE, TRUE); $this->queries = array(); $account->ownPlayer[] = $player; R::store($account); asrt(strpos(implode(',', $this->queries), 'index_foreignkey_player_accou') !== FALSE, TRUE); }
/** * Test common Facade usage scenarios. * * @return void */ public function testCommonUsageFacade() { $toolbox = R::getToolBox(); $adapter = $toolbox->getDatabaseAdapter(); $writer = $toolbox->getWriter(); $redbean = $toolbox->getRedBean(); $pdo = $adapter->getDatabase(); $a = new AssociationManager($toolbox); asrt(R::getRedBean() instanceof OODB, TRUE); asrt(R::getToolBox() instanceof ToolBox, TRUE); asrt(R::getDatabaseAdapter() instanceof Adapter, TRUE); asrt(R::getWriter() instanceof QueryWriter, TRUE); $book = R::dispense("book"); asrt($book instanceof OODBBean, TRUE); $book->title = "a nice book"; $id = R::store($book); asrt($id > 0, TRUE); $book = R::load("book", (int) $id); asrt($book->title, "a nice book"); asrt(R::load('book', 999)->title, NULL); R::freeze(TRUE); try { R::load('bookies', 999); fail(); } catch (\Exception $e) { pass(); } R::freeze(FALSE); $author = R::dispense("author"); $author->name = "me"; R::store($author); $book9 = R::dispense("book"); $author9 = R::dispense("author"); $author9->name = "mr Nine"; $a9 = R::store($author9); $book9->author_id = $a9; $bk9 = R::store($book9); $book9 = R::load("book", $bk9); $author = R::load("author", $book9->author_id); asrt($author->name, "mr Nine"); R::trash($author); R::trash($book9); pass(); $book2 = R::dispense("book"); $book2->title = "second"; R::store($book2); $book3 = R::dispense("book"); $book3->title = "third"; R::store($book3); asrt(count(R::find("book")), 3); asrt(count(R::findAll("book")), 3); asrt(count(R::findAll("book", " LIMIT 2")), 2); asrt(count(R::find("book", " id=id ")), 3); asrt(count(R::find("book", " title LIKE ?", array("third"))), 1); asrt(count(R::find("book", " title LIKE ?", array("%d%"))), 2); // Find without where clause asrt(count(R::findAll('book', ' order by id')), 3); R::trash($book3); R::trash($book2); asrt(count(R::getAll("SELECT * FROM book ")), 1); asrt(count(R::getCol("SELECT title FROM book ")), 1); asrt((int) R::getCell("SELECT 123 "), 123); $book = R::dispense("book"); $book->title = "not so original title"; $author = R::dispense("author"); $author->name = "Bobby"; R::store($book); $aid = R::store($author); $author = R::findOne("author", " name = ? ", array("Bobby")); }
/** * Test parameter binding with\PDO. * * @return void */ public function testPDOParameterBinding() { $toolbox = R::getToolBox(); $adapter = $toolbox->getDatabaseAdapter(); $writer = $toolbox->getWriter(); $redbean = $toolbox->getRedBean(); $pdo = $adapter->getDatabase(); R::getDatabaseAdapter()->getDatabase()->setUseStringOnlyBinding(TRUE); try { R::getAll("select * from job limit ? ", array(1)); fail(); } catch (\Exception $e) { pass(); } try { R::getAll("select * from job limit :l ", array(":l" => 1)); fail(); } catch (\Exception $e) { pass(); } try { R::exec("select * from job limit ? ", array(1)); fail(); } catch (\Exception $e) { pass(); } try { R::exec("select * from job limit :l ", array(":l" => 1)); fail(); } catch (\Exception $e) { pass(); } R::getDatabaseAdapter()->getDatabase()->setUseStringOnlyBinding(FALSE); try { R::getAll("select * from job limit ? ", array(1)); pass(); } catch (\Exception $e) { print_r($e); fail(); } try { R::getAll("select * from job limit :l ", array(":l" => 1)); pass(); } catch (\Exception $e) { fail(); } try { R::exec("select * from job limit ? ", array(1)); pass(); } catch (\Exception $e) { fail(); } try { R::exec("select * from job limit :l ", array(":l" => 1)); pass(); } catch (\Exception $e) { fail(); } testpack("Test findOrDispense"); $person = R::findOrDispense("person", " job = ? ", array("developer")); asrt(count($person) > 0, TRUE); $person = R::findOrDispense("person", " job = ? ", array("musician")); asrt(count($person) > 0, TRUE); $musician = array_pop($person); asrt(intval($musician->id), 0); try { $adapter->exec("an invalid query"); fail(); } catch (SQL $e) { pass(); } asrt((int) $adapter->getCell("SELECT 123"), 123); asrt((int) $adapter->getCell("SELECT ?", array("987")), 987); asrt((int) $adapter->getCell("SELECT ?+?", array("987", "2")), 989); asrt((int) $adapter->getCell("SELECT :numberOne+:numberTwo", array(":numberOne" => 42, ":numberTwo" => 50)), 92); $pair = $adapter->getAssoc("SELECT 'thekey','thevalue' "); asrt(is_array($pair), TRUE); asrt(count($pair), 1); asrt(isset($pair["thekey"]), TRUE); asrt($pair["thekey"], "thevalue"); testpack('Test whether we can properly bind and receive NULL values'); asrt($adapter->getCell('SELECT :nil ', array(':nil' => 'NULL')), 'NULL'); asrt($adapter->getCell('SELECT :nil ', array(':nil' => NULL)), NULL); asrt($adapter->getCell('SELECT ? ', array('NULL')), 'NULL'); asrt($adapter->getCell('SELECT ? ', array(NULL)), NULL); }
/** * Only fire update query if the bean really contains different * values. But make sure beans several 'parents' away still get * saved. * * @return void */ public function testBeanTainting() { $logger = R::getDatabaseAdapter()->getDatabase()->getLogger(); list($i, $k, $c, $s) = R::dispenseAll('invoice,customer,city,state'); $i->customer = $k; $i->status = 0; $k->city = $c; $c->state = $s; $s->name = 'x'; R::store($i); $i = $i->fresh(); asrt($i->customer->city->state->name, 'x'); $i->status = 1; R::freeze(true); $logger = R::debug(1, 1); //do we properly skip unmodified but tainted parent beans? R::store($i); $numberOfUpdateQueries = $logger->grep('UPDATE'); asrt(count($numberOfUpdateQueries), 1); //does cascade update still work? $i = $i->fresh(); $i->customer->city->state->name = 'y'; R::store($i); $i = $i->fresh(); asrt($i->customer->city->state->name, 'y'); $i = $i->fresh(); $differentCity = R::dispense('city'); R::store($differentCity); $i->customer->city = $differentCity; R::store($i); $i = $i->fresh(); asrt($i->customer->city->id != $c->id, TRUE); asrt(is_null($i->customer->city->state), TRUE); $i->customer->city = NULL; R::store($i); $i = $i->fresh(); asrt(is_null($i->customer->city), TRUE); $i->customer = $k; $i->status = 0; $k->city = $c; $c->state = $s; $s->name = 'x'; R::store($i); R::freeze(FALSE); $i = $i->fresh(); //can we still change remote parent? $i->customer->city->name = 'q'; $logger->clear(); R::store($i); $numberOfUpdateQueries = $logger->grep('UPDATE'); //print_r($logger->getLogs()); asrt(count($numberOfUpdateQueries), 1); $i = $i->fresh(); asrt($i->customer->city->name, 'q'); //do we properly skip unmodified but tainted parent beans? $i->status = 3; $logger->clear(); R::store($i); $numberOfUpdateQueries = $logger->grep('UPDATE'); asrt(count($numberOfUpdateQueries), 1); }
/** * Test selecting. * * @return void */ public function testSelects() { $rooms = R::dispense('room', 2); $rooms[0]->kind = 'suite'; $rooms[1]->kind = 'classic'; $rooms[0]->number = 6; $rooms[1]->number = 7; R::store($rooms[0]); R::store($rooms[1]); $rooms = R::getAssoc('SELECT * FROM room WHERE id < -999'); asrt(is_array($rooms), TRUE); asrt(count($rooms), 0); $rooms = R::getAssoc('SELECT ' . R::getWriter()->esc('number') . ', kind FROM room ORDER BY kind ASC'); foreach ($rooms as $key => $room) { asrt($key === 6 || $key === 7, TRUE); asrt($room == 'classic' || $room == 'suite', TRUE); } $rooms = R::getDatabaseAdapter()->getAssoc('SELECT kind FROM room'); foreach ($rooms as $key => $room) { asrt($room == 'classic' || $room == 'suite', TRUE); asrt($room, $key); } $rooms = R::getAssoc('SELECT `number`, kind FROM rooms2 ORDER BY kind ASC'); asrt(count($rooms), 0); asrt(is_array($rooms), TRUE); // GetCell should return NULL in case of exception asrt(NULL, R::getCell('SELECT dream FROM fantasy')); }
/** * Test debugging with custom logger. * * @return void */ public function testDebugCustomLogger() { testpack('Test debug mode with custom logger'); $pdoDriver = new RPDO(R::getDatabaseAdapter()->getDatabase()->getPDO()); $customLogger = new CustomLogger(); $pdoDriver->setDebugMode(TRUE, $customLogger); $pdoDriver->Execute('SELECT 123'); asrt(count($customLogger->getLogMessage()), 1); $pdoDriver->setDebugMode(TRUE, NULL); asrt($pdoDriver->getLogger() instanceof RDefault, TRUE); testpack('Test bean->getProperties method'); $bean = R::dispense('bean'); $bean->property = 'hello'; $props = $bean->getProperties(); asrt(isset($props['property']), TRUE); asrt($props['property'], 'hello'); }
/** * Test closing database connection. * * @return void */ public function testClose() { asrt(R::getDatabaseAdapter()->getDatabase()->isConnected(), TRUE); R::close(); asrt(R::getDatabaseAdapter()->getDatabase()->isConnected(), FALSE); }
public static function getLog() { $log = R::getDatabaseAdapter()->getDatabase()->getLogger(); return $log->getLogs(); }