public static function GetRelatedBeans($bean1, $type) { //Get a new association manager $association = new \RedBean_AssociationManager(self::Toolbox()); //return the related beans of type $type return $association->related($bean, $type); }
/** * Test integration with pre-existing schemas. * * @return void */ public function testPlaysNiceWithPreExitsingSchema() { $toolbox = R::$toolbox; $adapter = $toolbox->getDatabaseAdapter(); $writer = $toolbox->getWriter(); $redbean = $toolbox->getRedBean(); $pdo = $adapter->getDatabase(); $a = new RedBean_AssociationManager($toolbox); $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); $adapter->exec("ALTER TABLE " . $writer->esc('page') . "\n\t\tCHANGE " . $writer->esc('name') . " " . $writer->esc('name') . "\n\t\tVARCHAR( 254 ) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL "); $page = $redbean->dispense("page"); $page->name = "Just Another Page In a Table"; $cols = $writer->getColumns("page"); asrt($cols["name"], "varchar(254)"); //$pdo->SethMode(1); $redbean->store($page); pass(); // No crash? $cols = $writer->getColumns("page"); asrt($cols["name"], "varchar(254)"); //must still be same }
/** * Ensures that given an association between * $bean1 and $bean2, * if one of them gets trashed the association will be * automatically removed. * @param RedBean_OODBBean $bean1 * @param RedBean_OODBBean $bean2 * @return boolean $addedFKS */ public static function addConstraint(RedBean_OODBBean $bean1, RedBean_OODBBean $bean2, $dontCache = false) { //Fetch the toolbox $toolbox = RedBean_Setup::getToolBox(); RedBean_CompatManager::scanDirect($toolbox, array(RedBean_CompatManager::C_SYSTEM_MYSQL => "5")); //Create an association manager $association = new RedBean_AssociationManager($toolbox); $writer = $toolbox->getWriter(); $oodb = $toolbox->getRedBean(); $adapter = $toolbox->getDatabaseAdapter(); //Frozen? Then we may not alter the schema! if ($oodb->isFrozen()) { return false; } //$adapter->getDatabase()->setDebugMode(1); $table1 = $bean1->getMeta("type"); $table2 = $bean2->getMeta("type"); $table = $association->getTable(array($table1, $table2)); $idfield1 = $writer->getIDField($bean1->getMeta("type")); $idfield2 = $writer->getIDField($bean2->getMeta("type")); $bean = $oodb->dispense($table); $property1 = $bean1->getMeta("type") . "_id"; $property2 = $bean2->getMeta("type") . "_id"; if ($property1 == $property2) { $property2 = $bean2->getMeta("type") . "2_id"; } $table = $adapter->escape($table); $table1 = $adapter->escape($table1); $table2 = $adapter->escape($table2); $property1 = $adapter->escape($property1); $property2 = $adapter->escape($property2); //In Cache? Then we dont need to bother if (isset(self::$fkcache[$table])) { return false; } $db = $adapter->getCell("select database()"); $fks = $adapter->getCell("\n\t\t\tSELECT count(*)\n\t\t\tFROM information_schema.KEY_COLUMN_USAGE\n\t\t\tWHERE TABLE_SCHEMA ='{$db}' AND TABLE_NAME ='{$table}' AND\n\t\t\tCONSTRAINT_NAME <>'PRIMARY' AND REFERENCED_TABLE_NAME is not null\n\t\t"); //already foreign keys added in this association table if ($fks > 0) { return false; } //add the table to the cache, so we dont have to fire the fk query all the time. if (!$dontCache) { self::$fkcache[$table] = true; } $columns = $writer->getColumns($table); if ($writer->code($columns[$property1]) !== RedBean_QueryWriter_MySQL::C_DATATYPE_UINT32) { $writer->widenColumn($table, $property1, RedBean_QueryWriter_MySQL::C_DATATYPE_UINT32); } if ($writer->code($columns[$property2]) !== RedBean_QueryWriter_MySQL::C_DATATYPE_UINT32) { $writer->widenColumn($table, $property2, RedBean_QueryWriter_MySQL::C_DATATYPE_UINT32); } $sql = "\n\t\t\tALTER TABLE " . $writer->noKW($table) . "\n\t\t\tADD FOREIGN KEY({$property1}) references {$table1}(id) ON DELETE CASCADE;\n\n\t\t"; $adapter->exec($sql); $sql = "\n\t\t\tALTER TABLE " . $writer->noKW($table) . "\n\t\t\tADD FOREIGN KEY({$property2}) references {$table2}(id) ON DELETE CASCADE\n\t\t"; $adapter->exec($sql); return true; }
/** * Preloads the shared beans. * * @param string $type type of beans to load * @param string $sql additional SQL snippet for loading * @param array $bindings parameter bindings for SQL snippet * @param string $field field to store preloaded beans in * * @return void */ private function preloadSharedBeans($type, $sql, $bindings, $field) { $sharedBeans = $this->assocManager->relatedSimple($this->filteredBeans, $type, $sql, $bindings); // Let the filtered beans gather their beans foreach ($this->filteredBeans as $filteredBean) { $list = $this->gatherSharedBeansFromPool($filteredBean, $sharedBeans); $filteredBean->setProperty($field, $list, TRUE, TRUE); $this->fillParamArrayRetrievals($filteredBean, $list); } }
/** * Returns all beans that have been tagged with one or more * of the specified tags. * * Tag list can be either an array with tag names or a comma separated list * of tag names. * * @param string $beanType type of bean you are looking for * @param array|string $tagList list of tags to match * * @return array */ public function tagged($beanType, $tagList) { $tags = $this->extractTagsIfNeeded($tagList); $collection = array(); $tags = $this->redbean->find('tag', array('title' => $tags)); if (is_array($tags) && count($tags) > 0) { $collectionKeys = $this->associationManager->related($tags, $beanType); if ($collectionKeys) { $collection = $this->redbean->batch($beanType, $collectionKeys); } } return $collection; }
/** * Configures the facade, want to have a new Writer? A new Object Database or a new * Adapter and you want it on-the-fly? Use this method to hot-swap your facade with a new * toolbox. * * @param RedBean_ToolBox $tb toolbox * * @return RedBean_ToolBox */ public function configureWithToolbox(RedBean_ToolBox $tb) { $oldTools = $this->toolbox; $this->toolbox = $tb; $this->writer = $this->toolbox->getWriter(); $this->adapter = $this->toolbox->getDatabaseAdapter(); $this->redbean = $this->toolbox->getRedBean(); $this->finder = new RedBean_Finder($this->toolbox); $this->associationManager = new RedBean_AssociationManager($this->toolbox); $this->redbean->setAssociationManager($this->associationManager); $this->labelMaker = new RedBean_LabelMaker($this->toolbox); $this->extAssocManager = new RedBean_AssociationManager_ExtAssociationManager($this->toolbox); $this->associationManager->addEventListener('delete', $this->redbean->beanhelper->helper); $this->duplicationManager = new RedBean_DuplicationManager($this->toolbox); $this->tagManager = new RedBean_TagManager($this->toolbox); $this->f = new RedBean_SQLHelper($this->adapter); $this->x = new RedBean_FindHelper($this); return $oldTools; }
/** * Configures the facade, want to have a new Writer? A new Object Database or a new * Adapter and you want it on-the-fly? Use this method to hot-swap your facade with a new * toolbox. * * @param RedBean_ToolBox $tb toolbox * * @return RedBean_ToolBox */ public static function configureFacadeWithToolbox(RedBean_ToolBox $tb) { $oldTools = self::$toolbox; self::$toolbox = $tb; self::$writer = self::$toolbox->getWriter(); self::$adapter = self::$toolbox->getDatabaseAdapter(); self::$redbean = self::$toolbox->getRedBean(); self::$finder = new RedBean_Finder(self::$toolbox); self::$associationManager = new RedBean_AssociationManager(self::$toolbox); self::$redbean->setAssociationManager(self::$associationManager); self::$labelMaker = new RedBean_LabelMaker(self::$toolbox); self::$extAssocManager = new RedBean_AssociationManager_ExtAssociationManager(self::$toolbox); $helper = new RedBean_ModelHelper(); $helper->attachEventListeners(self::$redbean); self::$associationManager->addEventListener('delete', $helper); self::$duplicationManager = new RedBean_DuplicationManager(self::$toolbox); self::$tagManager = new RedBean_TagManager(self::$toolbox); self::$f = new RedBean_SQLHelper(self::$adapter); return $oldTools; }
/** * Configures the facade, want to have a new Writer? A new Object Database or a new * Adapter and you want it on-the-fly? Use this method to hot-swap your facade with a new * toolbox. * * @static * @param RedBean_ToolBox $tb toolbox * * @return RedBean_ToolBox $tb old, rusty, previously used toolbox */ public static function configureFacadeWithToolbox(RedBean_ToolBox $tb) { $oldTools = self::$toolbox; self::$toolbox = $tb; self::$writer = self::$toolbox->getWriter(); self::$adapter = self::$toolbox->getDatabaseAdapter(); self::$redbean = self::$toolbox->getRedBean(); self::$associationManager = new RedBean_AssociationManager(self::$toolbox); self::$redbean->setAssociationManager(self::$associationManager); self::$extAssocManager = new RedBean_ExtAssociationManager(self::$toolbox); $helper = new RedBean_ModelHelper(); self::$redbean->addEventListener("update", $helper); self::$redbean->addEventListener("open", $helper); self::$redbean->addEventListener("delete", $helper); self::$associationManager->addEventListener("delete", $helper); self::$redbean->addEventListener("after_delete", $helper); self::$redbean->addEventListener("after_update", $helper); self::$redbean->addEventListener("dispense", $helper); return $oldTools; }
/** * Clears associations */ protected function clearRelations() { $this->associationManager->clearRelations($this->bean); }
/** * Test scanning and coding. * * @return void */ public function testScanningAndCoding() { $toolbox = R::$toolbox; $adapter = $toolbox->getDatabaseAdapter(); $writer = $toolbox->getWriter(); $redbean = $toolbox->getRedBean(); $pdo = $adapter->getDatabase(); $a = new RedBean_AssociationManager($toolbox); $this->dropTableIfExists($adapter, 'testtable'); asrt(in_array("testtable", $adapter->getCol("SELECT LOWER(table_name) FROM user_tables")), FALSE); $writer->createTable("testtable"); asrt(in_array("testtable", $adapter->getCol("SELECT LOWER(table_name) FROM user_tables")), TRUE); asrt(count(array_diff($writer->getTables(), $adapter->getCol("SELECT LOWER(table_name) FROM user_tables"))), 0); asrt(count(array_keys($writer->getColumns("testtable"))), 1); asrt(in_array("id", array_keys($writer->getColumns("testtable"))), TRUE); asrt(in_array("c1", array_keys($writer->getColumns("testtable"))), FALSE); $writer->addColumn("testtable", "c1", 1); asrt(count(array_keys($writer->getColumns("testtable"))), 2); asrt(in_array("c1", array_keys($writer->getColumns("testtable"))), TRUE); foreach ($writer->sqltype_typeno as $key => $type) { if ($type < 100) { asrt($writer->code($key), $type); } else { asrt($writer->code($key), 99); } } asrt($writer->code("unknown"), 99); asrt($writer->scanType(FALSE), 0); asrt($writer->scanType(NULL), 0); asrt($writer->scanType(2), 1); asrt($writer->scanType(255), 1); asrt($writer->scanType(256), 2); asrt($writer->scanType(-1), 3); asrt($writer->scanType(1.5), 3); asrt($writer->scanType(INF), 4); asrt($writer->scanType("abc"), 4); asrt($writer->scanType(str_repeat('abcd', 100000)), RedBean_QueryWriter_MySQL::C_DATATYPE_TEXT32); asrt($writer->scanType("2001-10-10", TRUE), RedBean_QueryWriter_Oracle::C_DATATYPE_SPECIAL_DATE); asrt($writer->scanType("2001-10-10 10:00:00", TRUE), RedBean_QueryWriter_Oracle::C_DATATYPE_SPECIAL_DATE); asrt($writer->scanType("2001-10-10 10:00:00.99", TRUE), RedBean_QueryWriter_Oracle::C_DATATYPE_SPECIAL_TIMESTAMP); asrt($writer->scanType("2001-10-10"), 4); asrt($writer->scanType("2001-10-10 10:00:00"), 4); asrt($writer->scanType("2001-10-10 10:00:00.99"), 4); //asrt($writer->scanType("POINT(1 2)",TRUE),RedBean_QueryWriter_MySQL::C_DATATYPE_SPECIAL_POINT); //asrt($writer->scanType("POINT(1 2)"),4); asrt($writer->scanType(str_repeat("lorem ipsum", 100)), 5); $writer->widenColumn("testtable", "c1", 2); $cols = $writer->getColumns("testtable"); asrt($writer->code($cols["c1"]), 2); $writer->widenColumn("testtable", "c1", 3); $cols = $writer->getColumns("testtable"); asrt($writer->code($cols["c1"]), 3); $writer->widenColumn("testtable", "c1", 4); $cols = $writer->getColumns("testtable"); asrt($writer->code($cols["c1"]), 4); $writer->widenColumn("testtable", "c1", 5); $cols = $writer->getColumns("testtable"); asrt($writer->code($cols["c1"]), 5); $id = $writer->updateRecord("testtable", array(array("property" => "c1", "value" => "lorem ipsum"))); $row = $writer->selectRecord("testtable", array("id" => array($id))); asrt($row[0]["c1"], "lorem ipsum"); $writer->updateRecord("testtable", array(array("property" => "c1", "value" => "ipsum lorem")), $id); $row = $writer->queryRecord("testtable", array("id" => array($id))); asrt($row[0]["c1"], "ipsum lorem"); $writer->deleteRecord("testtable", array("id" => array($id))); $row = $writer->queryRecord("testtable", array("id" => array($id))); asrt(empty($row), TRUE); //$pdo->setDebugMode(1); $writer->addColumn("testtable", "c2", 2); try { $writer->addUniqueIndex("testtable", array("c1", "c2")); echo 'to be fixed'; //fail(); //should fail, no content length blob } catch (RedBean_Exception_SQL $e) { pass(); } $writer->addColumn("testtable", "c3", 2); try { $writer->addUniqueIndex("testtable", array("c2", "c3")); pass(); //should fail, no content length blob } catch (RedBean_Exception_SQL $e) { fail(); } $a = $adapter->get("select INDEX_NAME from user_ind_columns where TABLE_NAME='TESTTABLE'"); asrt(count($a), 5); //asrt($a[1]["Key_name"],"UQ_64b283449b9c396053fe1724b4c685a80fd1a54d"); //asrt($a[2]["Key_name"],"UQ_64b283449b9c396053fe1724b4c685a80fd1a54d"); //Zero issue (FALSE should be stored as 0 not as '') testpack("Zero issue"); $this->dropTableIfExists($adapter, 'zero'); $bean = $redbean->dispense("zero"); $bean->zero = FALSE; $bean->title = "bla"; $redbean->store($bean); asrt(count($redbean->find("zero", array(), " zero = 0 ")), 1); R::store(R::dispense('hack')); testpack("Test RedBean Security - bean interface "); asrt(in_array("hack", $adapter->getCol("SELECT LOWER(table_name) FROM user_tables")), TRUE); $bean = $redbean->load("page", "13; drop table hack"); asrt(in_array("hack", $adapter->getCol("SELECT LOWER(table_name) FROM user_tables")), TRUE); try { $bean = $redbean->load("page where 1; drop table hack", 1); } catch (Exception $e) { } asrt(in_array("hack", $adapter->getCol("SELECT LOWER(table_name) FROM user_tables")), TRUE); $bean = $redbean->dispense("page"); $evil = "; drop table hack"; $bean->id = $evil; try { $redbean->store($bean); } catch (Exception $e) { } asrt(in_array("hack", $adapter->getCol("SELECT LOWER(table_name) FROM user_tables")), TRUE); unset($bean->id); $bean->name = "\"" . $evil; try { $redbean->store($bean); } catch (Exception $e) { } asrt(in_array("hack", $adapter->getCol("SELECT LOWER(table_name) FROM user_tables")), TRUE); $bean->name = "'" . $evil; try { $redbean->store($bean); } catch (Exception $e) { } asrt(in_array("hack", $adapter->getCol("SELECT LOWER(table_name) FROM user_tables")), TRUE); $bean->{$evil} = 1; try { $redbean->store($bean); } catch (Exception $e) { } asrt(in_array("hack", $adapter->getCol("SELECT LOWER(table_name) FROM user_tables")), TRUE); unset($bean->{$evil}); $bean->id = 1; $bean->name = "\"" . $evil; try { $redbean->store($bean); } catch (Exception $e) { } asrt(in_array("hack", $adapter->getCol("SELECT LOWER(table_name) FROM user_tables")), TRUE); $bean->name = "'" . $evil; try { $redbean->store($bean); } catch (Exception $e) { } asrt(in_array("hack", $adapter->getCol("SELECT LOWER(table_name) FROM user_tables")), TRUE); $bean->{$evil} = 1; try { $redbean->store($bean); } catch (Exception $e) { } asrt(in_array("hack", $adapter->getCol("SELECT LOWER(table_name) FROM user_tables")), TRUE); try { $redbean->trash($bean); } catch (Exception $e) { } asrt(in_array("hack", $adapter->getCol("SELECT LOWER(table_name) FROM user_tables")), TRUE); try { $redbean->find("::", array(), ""); } catch (Exception $e) { pass(); } $this->dropTableIfExists($adapter, 'sometable'); testpack("Test RedBean Security - query writer"); try { $writer->createTable("sometable` ( `id` INT( 11 ) UNSIGNED NOT NULL AUTO_INCREMENT , PRIMARY KEY ( `id` ) ) ENGINE = InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ; drop table hack; --"); } catch (Exception $e) { } asrt(in_array("hack", $adapter->getCol("SELECT LOWER(table_name) FROM user_tables")), TRUE); testpack("Test ANSI92 issue in clearrelations"); $this->dropTableIfExists($adapter, 'book_group'); $this->dropTableIfExists($adapter, 'author_book'); $this->dropTableIfExists($adapter, 'book'); $this->dropTableIfExists($adapter, 'author'); $redbean = $toolbox->getRedBean(); $a = new RedBean_AssociationManager($toolbox); $book = $redbean->dispense("book"); $author1 = $redbean->dispense("author"); $author2 = $redbean->dispense("author"); $book->title = "My First Post"; $author1->name = "Derek"; $author2->name = "Whoever"; set1toNAssoc($a, $book, $author1); set1toNAssoc($a, $book, $author2); pass(); $this->dropTableIfExists($adapter, 'book_group'); $this->dropTableIfExists($adapter, 'book_author'); $this->dropTableIfExists($adapter, 'author_book'); $this->dropTableIfExists($adapter, 'book'); $this->dropTableIfExists($adapter, 'author'); $redbean = $toolbox->getRedBean(); $a = new RedBean_AssociationManager($toolbox); $book = $redbean->dispense("book"); $author1 = $redbean->dispense("author"); $author2 = $redbean->dispense("author"); $book->title = "My First Post"; $author1->name = "Derek"; $author2->name = "Whoever"; $a->associate($book, $author1); $a->associate($book, $author2); pass(); testpack("Test Association Issue Group keyword (Issues 9 and 10)"); $this->dropTableIfExists($adapter, 'book_group'); $this->dropTableIfExists($adapter, '"group"'); $group = $redbean->dispense("group"); $group->name = "mygroup"; $redbean->store($group); try { $a->associate($group, $book); pass(); } catch (RedBean_Exception_SQL $e) { fail(); } // Test issue SQL error 23000 try { $a->associate($group, $book); pass(); } catch (RedBean_Exception_SQL $e) { fail(); } asrt((int) $adapter->getCell("select count(*) from book_group"), 1); //just 1 rec! $this->dropTableIfExists($adapter, 'book_group'); $this->dropTableIfExists($adapter, 'author_book'); $this->dropTableIfExists($adapter, 'book'); $this->dropTableIfExists($adapter, 'author'); $redbean = $toolbox->getRedBean(); $a = new RedBean_AssociationManager($toolbox); $book = $redbean->dispense("book"); $author1 = $redbean->dispense("author"); $author2 = $redbean->dispense("author"); $book->title = "My First Post"; $author1->name = "Derek"; $author2->name = "Whoever"; $a->unassociate($book, $author1); $a->unassociate($book, $author2); pass(); $redbean->trash($redbean->dispense("bla")); pass(); $bean = $redbean->dispense("bla"); $bean->name = 1; $bean->id = 2; $redbean->trash($bean); pass(); }
asrt(in_array("movie_id", $columns), true); asrt(in_array("id", $columns), false); $movie2 = $redbean2->dispense("movie"); asrt(isset($movie2->movie_id), true); $movie2->name = "movie 2"; $movieid2 = $redbean2->store($movie2); $movie1 = $redbean2->load("movie", $movieid); asrt($movie->name, "movie 1"); $movie2 = $redbean2->load("movie", $movieid2); asrt($movie2->name, "movie 2"); $movies = $redbean2->batch("movie", array($movieid, $movieid2)); asrt(count($movies), 2); asrt($movies[$movieid]->name, "movie 1"); asrt($movies[$movieid2]->name, "movie 2"); $toolbox2 = new RedBean_ToolBox($redbean2, $adapter, $writer2); $a2 = new RedBean_AssociationManager($toolbox2); $a2->associate($movie1, $movie2); $movies = $a2->related($movie1, "movie"); asrt(count($movies), 1); asrt((int) $movies[0], (int) $movieid2); $movies = $a2->related($movie2, "movie"); asrt(count($movies), 1); asrt((int) $movies[0], (int) $movieid); $genre = $redbean2->dispense("genre"); $genre->name = "western"; $a2->associate($movie, $genre); $movies = $a2->related($genre, "movie"); asrt(count($movies), 1); asrt((int) $movies[0], (int) $movieid); $a2->unassociate($movie, $genre); $movies = $a2->related($genre, "movie");
/** * Convenience Method * @param RedBean_OODBBean $bean * @param string $type * @param string $sql * @param array $values * @return array $beans */ public static function findRelated(RedBean_OODBBean $bean, $type, $sql, $values = array()) { $keys = self::$associationManager->related($bean, $type); $sql = str_replace(":keys", implode(",", $keys), $sql); return self::find($type, $sql, $values); }
/** * Ensures that given an association between * $bean1 and $bean2, * if one of them gets trashed the association will be * automatically removed. * @param RedBean_OODBBean $bean1 * @param RedBean_OODBBean $bean2 * @return boolean $addedFKS */ public static function addConstraint(RedBean_OODBBean $bean1, RedBean_OODBBean $bean2, $dontCache = false) { //Fetch the toolbox $toolbox = RedBean_Setup::getToolBox(); RedBean_CompatManager::scanDirect($toolbox, array(RedBean_CompatManager::C_SYSTEM_MYSQL => "5", RedBean_CompatManager::C_SYSTEM_SQLITE => "3", RedBean_CompatManager::C_SYSTEM_POSTGRESQL => "7")); //Create an association manager $association = new RedBean_AssociationManager($toolbox); $writer = $toolbox->getWriter(); $oodb = $toolbox->getRedBean(); $adapter = $toolbox->getDatabaseAdapter(); //Frozen? Then we may not alter the schema! if ($oodb->isFrozen()) { return false; } $table1 = $bean1->getMeta("type"); $table2 = $bean2->getMeta("type"); $table = $association->getTable(array($table1, $table2)); $idfield1 = $writer->getIDField($bean1->getMeta("type")); $idfield2 = $writer->getIDField($bean2->getMeta("type")); $bean = $oodb->dispense($table); $property1 = $bean1->getMeta("type") . "_id"; $property2 = $bean2->getMeta("type") . "_id"; if ($property1 == $property2) { $property2 = $bean2->getMeta("type") . "2_id"; } $table = $adapter->escape($table); $table1 = $adapter->escape($table1); $table2 = $adapter->escape($table2); $property1 = $adapter->escape($property1); $property2 = $adapter->escape($property2); //In Cache? Then we dont need to bother //if (isset(self::$fkcache[$table])) return false; $fkCode = "fk" . md5($table . $property1 . $property2); if (isset(self::$fkcache[$fkCode])) { return false; } //Dispatch to right method try { if ($writer instanceof RedBean_QueryWriter_PostgreSQL) { return self::constraintPostgreSQL($toolbox, $table, $table1, $table2, $property1, $property2, $dontCache); } if ($writer instanceof RedBean_QueryWriter_SQLite) { return self::constraintSQLite($toolbox, $table, $table1, $table2, $property1, $property2, $dontCache); } if ($writer instanceof RedBean_QueryWriter_MySQL) { return self::constraintMySQL($toolbox, $table, $table1, $table2, $property1, $property2, $dontCache); } } catch (RedBean_Exception_SQL $e) { if (!$writer->sqlStateIn($e->getSQLState(), array(RedBean_QueryWriter::C_SQLSTATE_NO_SUCH_COLUMN, RedBean_QueryWriter::C_SQLSTATE_NO_SUCH_TABLE))) { throw $e; } } return false; }
} //test issue SQL error 23000 try { $a->associate($group, $book); pass(); } catch (RedBean_Exception_SQL $e) { fail(); } asrt((int) $adapter->getCell("select count(*) from book_group"), 1); //just 1 rec! $pdo->Execute("DROP TABLE IF EXISTS book"); $pdo->Execute("DROP TABLE IF EXISTS author"); $pdo->Execute("DROP TABLE IF EXISTS book_author"); $pdo->Execute("DROP TABLE IF EXISTS author_book"); $redbean = $toolbox->getRedBean(); $a = new RedBean_AssociationManager($toolbox); $book = $redbean->dispense("book"); $author1 = $redbean->dispense("author"); $author2 = $redbean->dispense("author"); $book->title = "My First Post"; $author1->name = "Derek"; $author2->name = "Whoever"; $a->unassociate($book, $author1); $a->unassociate($book, $author2); pass(); $redbean->trash($redbean->dispense("bla")); pass(); $bean = $redbean->dispense("bla"); $bean->name = 1; $bean->id = 2; $redbean->trash($bean);
/** * Test self referential N-M relations (page_page). * * @return void */ public function testSelfReferential() { $toolbox = R::$toolbox; $adapter = $toolbox->getDatabaseAdapter(); $writer = $toolbox->getWriter(); $redbean = $toolbox->getRedBean(); $pdo = $adapter->getDatabase(); $a = new RedBean_AssociationManager($toolbox); $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); $ids = $a->related($page, "page"); asrt(count($ids), 1); asrt(intval(array_pop($ids)), intval($idpage2)); $ids = $a->related($page2, "page"); asrt(count($ids), 1); asrt(intval(array_pop($ids)), intval($idpage)); $page3 = $redbean->dispense("page"); $page3->name = "third"; $page4 = $redbean->dispense("page"); $page4->name = "fourth"; $a->associate($page3, $page2); $a->associate($page2, $page4); $a->unassociate($page, $page2); asrt(count($a->related($page, "page")), 0); $ids = $a->related($page2, "page"); asrt(count($ids), 2); asrt(in_array($page3->id, $ids), TRUE); asrt(in_array($page4->id, $ids), TRUE); asrt(in_array($page->id, $ids), FALSE); asrt(count($a->related($page3, "page")), 1); asrt(count($a->related($page4, "page")), 1); $a->clearRelations($page2, "page"); asrt(count($a->related($page2, "page")), 0); asrt(count($a->related($page3, "page")), 0); asrt(count($a->related($page4, "page")), 0); try { $a->associate($page2, $page2); pass(); } catch (RedBean_Exception_SQL $e) { fail(); } $pageOne = $redbean->dispense("page"); $pageOne->name = "one"; $pageMore = $redbean->dispense("page"); $pageMore->name = "more"; $pageEvenMore = $redbean->dispense("page"); $pageEvenMore->name = "evenmore"; $pageOther = $redbean->dispense("page"); $pageOther->name = "othermore"; set1toNAssoc($a, $pageOther, $pageMore); set1toNAssoc($a, $pageOne, $pageMore); set1toNAssoc($a, $pageOne, $pageEvenMore); asrt(count($a->related($pageOne, "page")), 2); asrt(count($a->related($pageMore, "page")), 1); asrt(count($a->related($pageEvenMore, "page")), 1); asrt(count($a->related($pageOther, "page")), 0); }
/** * (FALSE should be stored as 0 not as '') * * @return voids */ public function testZeroIssue() { testpack("Zero issue"); $toolbox = R::$toolbox; $redbean = $toolbox->getRedBean(); $adapter = $toolbox->getDatabaseAdapter(); $writer = $toolbox->getWriter(); $pdo = $adapter->getDatabase(); $pdo->Execute("DROP TABLE IF EXISTS `zero`"); $bean = $redbean->dispense("zero"); $bean->zero = FALSE; $bean->title = "bla"; $redbean->store($bean); asrt(count($redbean->find("zero", array(), " zero = 0 ")), 1); R::store(R::dispense('hack')); testpack("Test RedBean Security - bean interface "); asrt(in_array("hack", $adapter->getCol("show tables")), TRUE); $bean = $redbean->load("page", "13; drop table hack"); asrt(in_array("hack", $adapter->getCol("show tables")), TRUE); try { $bean = $redbean->load("page where 1; drop table hack", 1); } catch (Exception $e) { } asrt(in_array("hack", $adapter->getCol("show tables")), TRUE); $bean = $redbean->dispense("page"); $evil = "; drop table hack"; $bean->id = $evil; try { $redbean->store($bean); } catch (Exception $e) { } asrt(in_array("hack", $adapter->getCol("show tables")), TRUE); unset($bean->id); $bean->name = "\"" . $evil; try { $redbean->store($bean); } catch (Exception $e) { } asrt(in_array("hack", $adapter->getCol("show tables")), TRUE); $bean->name = "'" . $evil; try { $redbean->store($bean); } catch (Exception $e) { } asrt(in_array("hack", $adapter->getCol("show tables")), TRUE); $bean->{$evil} = 1; try { $redbean->store($bean); } catch (Exception $e) { } asrt(in_array("hack", $adapter->getCol("show tables")), TRUE); unset($bean->{$evil}); $bean->id = 1; $bean->name = "\"" . $evil; try { $redbean->store($bean); } catch (Exception $e) { } asrt(in_array("hack", $adapter->getCol("show tables")), TRUE); $bean->name = "'" . $evil; try { $redbean->store($bean); } catch (Exception $e) { } asrt(in_array("hack", $adapter->getCol("show tables")), TRUE); $bean->{$evil} = 1; try { $redbean->store($bean); } catch (Exception $e) { } asrt(in_array("hack", $adapter->getCol("show tables")), TRUE); try { $redbean->trash($bean); } catch (Exception $e) { } asrt(in_array("hack", $adapter->getCol("show tables")), TRUE); try { $redbean->find("::", array(), ""); } catch (Exception $e) { pass(); } $adapter->exec("drop table if exists sometable"); testpack("Test RedBean Security - query writer"); try { $writer->createTable("sometable` ( `id` INT( 11 ) UNSIGNED NOT NULL AUTO_INCREMENT , PRIMARY KEY ( `id` ) ) ENGINE = InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ; drop table hack; --"); } catch (Exception $e) { } asrt(in_array("hack", $adapter->getCol("show tables")), TRUE); testpack("Test ANSI92 issue in clearrelations"); $pdo->Execute("DROP TABLE IF EXISTS book_group"); $pdo->Execute("DROP TABLE IF EXISTS author_book"); $pdo->Execute("DROP TABLE IF EXISTS book"); $pdo->Execute("DROP TABLE IF EXISTS author"); $redbean = $toolbox->getRedBean(); $a = new RedBean_AssociationManager($toolbox); $book = $redbean->dispense("book"); $author1 = $redbean->dispense("author"); $author2 = $redbean->dispense("author"); $book->title = "My First Post"; $author1->name = "Derek"; $author2->name = "Whoever"; set1toNAssoc($a, $book, $author1); set1toNAssoc($a, $book, $author2); pass(); $pdo->Execute("DROP TABLE IF EXISTS book_group"); $pdo->Execute("DROP TABLE IF EXISTS book_author"); $pdo->Execute("DROP TABLE IF EXISTS author_book"); $pdo->Execute("DROP TABLE IF EXISTS book"); $pdo->Execute("DROP TABLE IF EXISTS author"); $redbean = $toolbox->getRedBean(); $a = new RedBean_AssociationManager($toolbox); $book = $redbean->dispense("book"); $author1 = $redbean->dispense("author"); $author2 = $redbean->dispense("author"); $book->title = "My First Post"; $author1->name = "Derek"; $author2->name = "Whoever"; $a->associate($book, $author1); $a->associate($book, $author2); pass(); testpack("Test Association Issue Group keyword (Issues 9 and 10)"); $pdo->Execute("DROP TABLE IF EXISTS `book_group`"); $pdo->Execute("DROP TABLE IF EXISTS `group`"); $group = $redbean->dispense("group"); $group->name = "mygroup"; $redbean->store($group); try { $a->associate($group, $book); pass(); } catch (RedBean_Exception_SQL $e) { fail(); } // Test issue SQL error 23000 try { $a->associate($group, $book); pass(); } catch (RedBean_Exception_SQL $e) { fail(); } asrt((int) $adapter->getCell("select count(*) from book_group"), 1); //just 1 rec! $pdo->Execute("DROP TABLE IF EXISTS book_group"); $pdo->Execute("DROP TABLE IF EXISTS author_book"); $pdo->Execute("DROP TABLE IF EXISTS book"); $pdo->Execute("DROP TABLE IF EXISTS author"); $redbean = $toolbox->getRedBean(); $a = new RedBean_AssociationManager($toolbox); $book = $redbean->dispense("book"); $author1 = $redbean->dispense("author"); $author2 = $redbean->dispense("author"); $book->title = "My First Post"; $author1->name = "Derek"; $author2->name = "Whoever"; $a->unassociate($book, $author1); $a->unassociate($book, $author2); pass(); $redbean->trash($redbean->dispense("bla")); pass(); $bean = $redbean->dispense("bla"); $bean->name = 1; $bean->id = 2; $redbean->trash($bean); pass(); }
/** * 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::$toolbox; $adapter = $toolbox->getDatabaseAdapter(); $writer = $toolbox->getWriter(); $redbean = $toolbox->getRedBean(); $pdo = $adapter->getDatabase(); $a = new RedBean_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 (RedBean_Exception_SQL $e) { pass(); } $post = $redbean->dispense("post"); $post->title = "existing table"; try { $id = $redbean->store($post); pass(); } catch (RedBean_Exception_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 (RedBean_Exception_SQL $e) { pass(); } $logger = RedBean_Plugin_QueryLogger::getInstanceAndAttach($adapter); // 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); }
/** * Test the database driver and low level functions. * * @return void */ public function testDriver() { $currentDriver = $this->currentlyActiveDriverID; R::store(R::dispense('justabean')); $adapter = new TroubleDapter(R::$toolbox->getDatabaseAdapter()->getDatabase()); $adapter->setSQLState('HY000'); $writer = new RedBean_QueryWriter_SQLiteT($adapter); $redbean = new RedBean_OODB($writer); $toolbox = new RedBean_ToolBox($redbean, $adapter, $writer); // We can only test this for a known driver... if ($currentDriver === 'sqlite') { try { $redbean->find('bean'); pass(); } catch (Exception $e) { var_dump($e->getSQLState()); fail(); } } $adapter->setSQLState(-999); try { $redbean->find('bean'); fail(); } catch (Exception $e) { pass(); } $beanA = R::dispense('bean'); $beanB = R::dispense('bean'); R::storeAll(array($beanA, $beanB)); $associationManager = new RedBean_AssociationManager($toolbox); $adapter->setSQLState('HY000'); // We can only test this for a known driver... if ($currentDriver === 'sqlite') { try { $associationManager->areRelated($beanA, $beanB); pass(); } catch (Exception $e) { fail(); } } $adapter->setSQLState(-999); try { $associationManager->areRelated($beanA, $beanA); fail(); } catch (Exception $e) { pass(); } try { $redbean->wipe('justabean'); fail(); } catch (Exception $e) { pass(); } $toolbox = R::$toolbox; $adapter = $toolbox->getDatabaseAdapter(); $writer = $toolbox->getWriter(); $redbean = $toolbox->getRedBean(); $pdo = $adapter->getDatabase(); $page = $redbean->dispense("page"); try { $adapter->exec("an invalid query"); fail(); } catch (RedBean_Exception_SQL $e) { pass(); } // Special data type description should result in magic number 99 (specified) if ($currentDriver == 'mysql') { asrt($writer->code(RedBean_QueryWriter_MySQL::C_DATATYPE_SPECIAL_DATE), 99); } if ($currentDriver == 'pgsql') { asrt($writer->code(RedBean_QueryWriter_PostgreSQL::C_DATATYPE_SPECIAL_DATE), 99); } if ($currentDriver == 'CUBRID') { asrt($writer->code(RedBean_QueryWriter_CUBRID::C_DATATYPE_SPECIAL_DATE), 99); } asrt((int) $adapter->getCell("SELECT 123"), 123); $page->aname = "my page"; $id = (int) $redbean->store($page); asrt((int) $page->id, 1); asrt((int) $pdo->GetCell("SELECT count(*) FROM page"), 1); asrt($pdo->GetCell("SELECT aname FROM page LIMIT 1"), "my page"); asrt((int) $id, 1); $page = $redbean->load("page", 1); asrt($page->aname, "my page"); asrt((bool) $page->getMeta("type"), TRUE); asrt(isset($page->id), TRUE); asrt($page->getMeta("type"), "page"); asrt((int) $page->id, $id); }
/** * Test legacy methods, backward compatibility with removed * setAssoc function. * * @return void */ public function testBackwardCompat() { $toolbox = R::$toolbox; $adapter = $toolbox->getDatabaseAdapter(); $writer = $toolbox->getWriter(); $redbean = $toolbox->getRedBean(); $pdo = $adapter->getDatabase(); $rb = $redbean; $testA = $rb->dispense('testA'); $testB = $rb->dispense('testB'); $a = new RedBean_AssociationManager($toolbox); try { $a->related($testA, "testB"); pass(); } catch (Exception $e) { fail(); } $user = $redbean->dispense("user"); $user->name = "John"; $redbean->store($user); $page = $redbean->dispense("page"); $page->name = "John's page"; $redbean->store($page); $page2 = $redbean->dispense("page"); $page2->name = "John's second page"; $redbean->store($page2); $a = new RedBean_AssociationManager($toolbox); $a->associate($page, $user); asrt(count($a->related($user, "page")), 1); $a->associate($user, $page2); asrt(count($a->related($user, "page")), 2); // Can we fetch the assoc ids themselves? $pageKeys = $a->related($user, "page"); $pages = $redbean->batch("page", $pageKeys); $links = $redbean->batch("page_user", $a->related($user, "page", TRUE)); asrt(count($links), 2); // Confirm that the link beans are ok. $link = array_pop($links); asrt(isset($link->page_id), TRUE); asrt(isset($link->user_id), TRUE); asrt(isset($link->id), TRUE); $link = array_pop($links); asrt(isset($link->page_id), TRUE); asrt(isset($link->user_id), TRUE); asrt(isset($link->id), TRUE); $a->unassociate($page, $user); asrt(count($a->related($user, "page")), 1); $a->clearRelations($user, "page"); asrt(count($a->related($user, "page")), 0); $user2 = $redbean->dispense("user"); $user2->name = "Second User"; set1toNAssoc($a, $user2, $page); set1toNAssoc($a, $user, $page); asrt(count($a->related($user2, "page")), 0); asrt(count($a->related($user, "page")), 1); set1toNAssoc($a, $user, $page2); asrt(count($a->related($user, "page")), 2); $pages = $redbean->batch("page", $a->related($user, "page")); asrt(count($pages), 2); $apage = array_shift($pages); asrt($apage->name == "John's page" || $apage->name == "John's second page", TRUE); $apage = array_shift($pages); asrt($apage->name == "John's page" || $apage->name == "John's second page", TRUE); // Test save on the fly $page = $redbean->dispense("page"); $page2 = $redbean->dispense("page"); $page->name = "idless page 1"; $page2->name = "idless page 1"; $a->associate($page, $page2); asrt($page->id > 0, TRUE); asrt($page2->id > 0, TRUE); $idpage = $page->id; $idpage2 = $page2->id; $page = $redbean->dispense("page"); $page->name = "test page"; $id = $redbean->store($page); $user = $redbean->dispense("user"); $a->unassociate($user, $page); pass(); // No error $a->unassociate($page, $user); pass(); // No error $a->clearRelations($page, "user"); pass(); // No error $a->clearRelations($user, "page"); pass(); // No error $a->associate($user, $page); pass(); asrt(count($a->related($user, "page")), 1); asrt(count($a->related($page, "user")), 1); $a->clearRelations($user, "page"); pass(); // No error asrt(count($a->related($user, "page")), 0); asrt(count($a->related($page, "user")), 0); $page = $redbean->load("page", $id); pass(); asrt($page->name, "test page"); }
/** * Test various. * Test various somewhat uncommon trash/unassociate scenarios. * (i.e. unassociate unrelated beans, trash non-persistant beans etc). * Should be handled gracefully - no output checking. * * @return void */ public function testVaria2() { $toolbox = R::$toolbox; $redbean = $toolbox->getRedBean(); $a = new RedBean_AssociationManager($toolbox); $book = $redbean->dispense("book"); $author1 = $redbean->dispense("author"); $author2 = $redbean->dispense("author"); $book->title = "My First Post"; $author1->name = "Derek"; $author2->name = "Whoever"; $a->unassociate($book, $author1); $a->unassociate($book, $author2); pass(); $redbean->trash($redbean->dispense("bla")); pass(); $bean = $redbean->dispense("bla"); $bean->name = 1; $bean->id = 2; $redbean->trash($bean); pass(); }
/** * Unassociates the list items in the trashcan. * * @param RedBean_OODBBean $bean bean * @param array $sharedTrashcan list * * @return void */ private function processSharedTrashcan($bean, $sharedTrashcan) { foreach ($sharedTrashcan as $trash) { $this->assocManager->unassociate($trash, $bean); } }
/** * Begin testing. * This method runs the actual test pack. * * @return void */ public function testFinding() { $toolbox = R::$toolbox; $adapter = $toolbox->getDatabaseAdapter(); $writer = $toolbox->getWriter(); $redbean = $toolbox->getRedBean(); $pdo = $adapter->getDatabase(); $a = new RedBean_AssociationManager($toolbox); $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); $pageOne = $redbean->dispense("page"); $pageOne->name = "one"; $pageMore = $redbean->dispense("page"); $pageMore->name = "more"; $pageEvenMore = $redbean->dispense("page"); $pageEvenMore->name = "evenmore"; $pageOther = $redbean->dispense("page"); $pageOther->name = "othermore"; set1toNAssoc($a, $pageOther, $pageMore); set1toNAssoc($a, $pageOne, $pageMore); set1toNAssoc($a, $pageOne, $pageEvenMore); asrt(count($redbean->find("page", array(), " name LIKE '%more%' ", array())), 3); asrt(count($redbean->find("page", array(), " name LIKE :str ", array(":str" => '%more%'))), 3); asrt(count($redbean->find("page", array(), array(" name LIKE :str ", array(":str" => '%more%')))), 3); asrt(count($redbean->find("page", array(), " name LIKE :str ", array(":str" => '%mxore%'))), 0); asrt(count($redbean->find("page", array("id" => array(2, 3)))), 2); $bean = $redbean->dispense("wine"); $bean->name = "bla"; for ($i = 0; $i < 10; $i++) { $redbean->store($bean); } $redbean->find("wine", array("id" => 5)); // Finder:where call RedBean_OODB::convertToBeans $bean2 = $redbean->load("anotherbean", 5); asrt($bean2->id, 0); $keys = $adapter->getCol("SELECT id FROM page WHERE " . $writer->esc('name') . " LIKE '%John%'"); asrt(count($keys), 2); $pages = $redbean->batch("page", $keys); asrt(count($pages), 2); $p = R::findLast('page'); pass(); $row = R::getRow('select * from page '); asrt(is_array($row), TRUE); asrt(isset($row['name']), TRUE); // Test findAll -- should not throw an exception asrt(count(R::findAll('page')) > 0, TRUE); asrt(count(R::findAll('page', ' ORDER BY id ')) > 0, TRUE); $beans = R::findOrDispense("page"); asrt(count($beans), 6); asrt(is_null(R::findLast('nothing')), TRUE); try { R::find('bean', ' id > 0 ', 'invalid bindings argument'); fail(); } catch (RedBean_Exception_Security $exception) { pass(); } }