The Query Writer is responsible for building the queries for a
specific database and executing them through the adapter.
public getWriter ( ) : RedBeanPHP\QueryWriter | ||
Результат | RedBeanPHP\QueryWriter |
/** * Makes a copy of a bean. This method makes a deep copy * of the bean.The copy will have the following features. * - All beans in own-lists will be duplicated as well * - All references to shared beans will be copied but not the shared beans themselves * - All references to parent objects (_id fields) will be copied but not the parents themselves * In most cases this is the desired scenario for copying beans. * This function uses a trail-array to prevent infinite recursion, if a recursive bean is found * (i.e. one that already has been processed) the ID of the bean will be returned. * This should not happen though. * * Note: * This function does a reflectional database query so it may be slow. * * Note: * this function actually passes the arguments to a protected function called * duplicate() that does all the work. This method takes care of creating a clone * of the bean to avoid the bean getting tainted (triggering saving when storing it). * * @param OODBBean $bean bean to be copied * @param array $trail for internal usage, pass array() * @param boolean $preserveIDs for internal usage * * @return OODBBean */ public function dup(OODBBean $bean, $trail = array(), $preserveIDs = FALSE) { if (!count($this->tables)) { $this->tables = $this->toolbox->getWriter()->getTables(); } if (!count($this->columns)) { foreach ($this->tables as $table) { $this->columns[$table] = $this->toolbox->getWriter()->getColumns($table); } } $rs = $this->duplicate(clone $bean, $trail, $preserveIDs); if (!$this->cacheTables) { $this->tables = array(); $this->columns = array(); } return $rs; }
/** * 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 ToolBox $tb toolbox to configure facade with * * @return ToolBox */ public static function configureFacadeWithToolbox(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 Finder(self::$toolbox); self::$associationManager = new AssociationManager(self::$toolbox); self::$redbean->setAssociationManager(self::$associationManager); self::$labelMaker = new LabelMaker(self::$toolbox); $helper = new SimpleModelHelper(); $helper->attachEventListeners(self::$redbean); self::$redbean->setBeanHelper(new SimpleFacadeBeanHelper()); self::$duplicationManager = new DuplicationManager(self::$toolbox); self::$tagManager = new TagManager(self::$toolbox); return $oldTools; }
/** * Constructor * * @param ToolBox $tools toolbox */ public function __construct(ToolBox $tools) { $this->oodb = $tools->getRedBean(); $this->adapter = $tools->getDatabaseAdapter(); $this->writer = $tools->getWriter(); $this->toolbox = $tools; }
/** * Returns all beans that have been tagged with ALL of the tags given. * * 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 taggedAll($beanType, $tagList, $sql = '', $bindings = array()) { $tags = $this->extractTagsIfNeeded($tagList); $records = $this->toolbox->getWriter()->queryTagged($beanType, $tags, TRUE, $sql, $bindings); return $this->redbean->convertToBeans($beanType, $records); }
/** * Returns a hashmap with bean arrays keyed by type using an SQL * query as its resource. Given an SQL query like 'SELECT movie.*, review.* FROM movie... JOIN review' * this method will return movie and review beans. * * Example: * * $stuff = $finder->findMulti('movie,review', ' * SELECT movie.*, review.* FROM movie * LEFT JOIN review ON review.movie_id = movie.id'); * * After this operation, $stuff will contain an entry 'movie' containing all * movies and an entry named 'review' containing all reviews (all beans). * You can also pass bindings. * * If you want to re-map your beans, so you can use $movie->ownReviewList without * having RedBeanPHP executing an SQL query you can use the fourth parameter to * define a selection of remapping closures. * * The remapping argument (optional) should contain an array of arrays. * Each array in the remapping array should contain the following entries: * * array( * 'a' => TYPE A * 'b' => TYPE B * 'matcher' => MATCHING FUNCTION ACCEPTING A, B and ALL BEANS * 'do' => OPERATION FUNCTION ACCEPTING A, B, ALL BEANS, ALL REMAPPINGS * ) * * Using this mechanism you can build your own 'preloader' with tiny function * snippets (and those can be re-used and shared online of course). * * Example: * * array( * 'a' => 'movie' //define A as movie * 'b' => 'review' //define B as review * 'matcher' => function( $a, $b ) { * return ( $b->movie_id == $a->id ); //Perform action if review.movie_id equals movie.id * } * 'do' => function( $a, $b ) { * $a->noLoad()->ownReviewList[] = $b; //Add the review to the movie * $a->clearHistory(); //optional, act 'as if these beans have been loaded through ownReviewList'. * } * ) * * The Query Template parameter is optional as well but can be used to * set a different SQL template (sprintf-style) for processing the original query. * * @note the SQL query provided IS NOT THE ONE used internally by this function, * this function will pre-process the query to get all the data required to find the beans. * * @note if you use the 'book.*' notation make SURE you're * selector starts with a SPACE. ' book.*' NOT ',book.*'. This is because * it's actually an SQL-like template SLOT, not real SQL. * * @note instead of an SQL query you can pass a result array as well. * * @param string|array $types a list of types (either array or comma separated string) * @param string|array $sqlOrArr an SQL query or an array of prefetched records * @param array $bindings optional, bindings for SQL query * @param array $remappings optional, an array of remapping arrays * @param string $queryTemplate optional, query template * * @return array */ public function findMulti($types, $sql, $bindings = array(), $remappings = array(), $queryTemplate = ' %s.%s AS %s__%s') { if (!is_array($types)) { $types = explode(',', $types); } if (!is_array($sql)) { $writer = $this->toolbox->getWriter(); $adapter = $this->toolbox->getDatabaseAdapter(); //Repair the query, replace book.* with book.id AS book_id etc.. foreach ($types as $type) { $pattern = " {$type}.*"; if (strpos($sql, $pattern) !== FALSE) { $newSelectorArray = array(); $columns = $writer->getColumns($type); foreach ($columns as $column => $definition) { $newSelectorArray[] = sprintf($queryTemplate, $type, $column, $type, $column); } $newSelector = implode(',', $newSelectorArray); $sql = str_replace($pattern, $newSelector, $sql); } } $rows = $adapter->get($sql, $bindings); } else { $rows = $sql; } //Gather the bean data from the query results using the prefix $wannaBeans = array(); foreach ($types as $type) { $wannaBeans[$type] = array(); $prefix = "{$type}__"; foreach ($rows as $rowkey => $row) { $wannaBean = array(); foreach ($row as $cell => $value) { if (strpos($cell, $prefix) === 0) { $property = substr($cell, strlen($prefix)); unset($rows[$rowkey][$cell]); $wannaBean[$property] = $value; } } if (!isset($wannaBean['id'])) { continue; } if (is_null($wannaBean['id'])) { continue; } $wannaBeans[$type][$wannaBean['id']] = $wannaBean; } } //Turn the rows into beans $beans = array(); foreach ($wannaBeans as $type => $wannabees) { $beans[$type] = $this->redbean->convertToBeans($type, $wannabees); } //Apply additional re-mappings foreach ($remappings as $remapping) { $a = $remapping['a']; $b = $remapping['b']; $matcher = $remapping['matcher']; $do = $remapping['do']; foreach ($beans[$a] as $bean) { foreach ($beans[$b] as $putBean) { if ($matcher($bean, $putBean, $beans)) { $do($bean, $putBean, $beans, $remapping); } } } } return $beans; }