3 namespace RedBeanPHP\Repository;
5 use RedBeanPHP\OODBBean as OODBBean;
6 use RedBeanPHP\QueryWriter as QueryWriter;
7 use RedBeanPHP\RedException as RedException;
8 use RedBeanPHP\BeanHelper as BeanHelper;
9 use RedBeanPHP\RedException\SQL as SQLException;
10 use RedBeanPHP\Repository as Repository;
14 * OODB manages two repositories, a fluid one that
15 * adjust the database schema on-the-fly to accomodate for
16 * new bean types (tables) and new properties (columns) and
17 * a frozen one for use in a production environment. OODB
18 * allows you to swap the repository instances using the freeze()
21 * @file RedBeanPHP/Repository/Frozen.php
22 * @author Gabor de Mooij and the RedBeanPHP community
26 * copyright (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community
27 * This source file is subject to the BSD/GPLv2 License that is bundled
28 * with this source code in the file license.txt.
30 class Frozen extends Repository
34 * In fluid mode, this suppresses exceptions caused by missing structures.
35 * However the implementation in frozen mode is rather the opposite, it
36 * will just re-throw every exception.
38 * @param \Exception $exception exception to handle
42 protected function handleException( \Exception $exception )
48 * Stores a cleaned bean; i.e. only scalar values. This is the core of the store()
49 * method. When all lists and embedded beans (parent objects) have been processed and
50 * removed from the original bean the bean is passed to this method to be stored
53 * @param OODBBean $bean the clean bean
57 protected function storeBean( OODBBean $bean )
59 if ( $bean->getMeta( 'changed' ) ) {
61 list( $properties, $table ) = $bean->getPropertiesAndType();
62 $id = $properties['id'];
63 unset($properties['id']);
64 $updateValues = array();
67 foreach( $properties as $key => $value ) {
68 $updateValues[] = array( $k1 => $key, $k2 => $value );
70 $bean->id = $this->writer->updateRecord( $table, $updateValues, $id );
71 $bean->setMeta( 'changed', FALSE );
73 $bean->setMeta( 'tainted', FALSE );
77 * Part of the store() functionality.
78 * Handles all new additions after the bean has been saved.
79 * Stores addition bean in own-list, extracts the id and
80 * adds a foreign key. Also adds a constraint in case the type is
81 * in the dependent list.
83 * Note that this method raises a custom exception if the bean
84 * is not an instance of OODBBean. Therefore it does not use
85 * a type hint. This allows the user to take action in case
86 * invalid objects are passed in the list.
88 * @param OODBBean $bean bean to process
89 * @param array $ownAdditions list of addition beans in own-list
92 * @throws RedException
94 protected function processAdditions( $bean, $ownAdditions )
96 $beanType = $bean->getMeta( 'type' );
98 $cachedIndex = array();
99 foreach ( $ownAdditions as $addition ) {
100 if ( $addition instanceof OODBBean ) {
102 $myFieldLink = $beanType . '_id';
103 $alias = $bean->getMeta( 'sys.alias.' . $addition->getMeta( 'type' ) );
104 if ( $alias ) $myFieldLink = $alias . '_id';
106 $addition->$myFieldLink = $bean->id;
107 $addition->setMeta( 'cast.' . $myFieldLink, 'id' );
108 $this->store( $addition );
111 throw new RedException( 'Array may only contain OODBBeans' );
117 * Dispenses a new bean (a OODBBean Bean Object)
118 * of the specified type. Always
119 * use this function to get an empty bean object. Never
120 * instantiate a OODBBean yourself because it needs
121 * to be configured before you can use it with RedBean. This
122 * function applies the appropriate initialization /
123 * configuration for you.
125 * @param string $type type of bean you want to dispense
126 * @param int $number number of beans you would like to get
127 * @param boolean $alwaysReturnArray if TRUE always returns the result as an array
131 public function dispense( $type, $number = 1, $alwaysReturnArray = FALSE )
133 $OODBBEAN = defined( 'REDBEAN_OODBBEAN_CLASS' ) ? REDBEAN_OODBBEAN_CLASS : '\RedBeanPHP\OODBBean';
135 for ( $i = 0; $i < $number; $i++ ) {
136 /** @var \RedBeanPHP\OODBBean $bean */
137 $bean = new $OODBBEAN;
138 $bean->initializeForDispense( $type, $this->oodb->getBeanHelper() );
139 $this->oodb->signal( 'dispense', $bean );
143 return ( count( $beans ) === 1 && !$alwaysReturnArray ) ? array_pop( $beans ) : $beans;
147 * Loads a bean from the object database.
148 * It searches for a OODBBean Bean Object in the
149 * database. It does not matter how this bean has been stored.
150 * RedBean uses the primary key ID $id and the string $type
151 * to find the bean. The $type specifies what kind of bean you
152 * are looking for; this is the same type as used with the
153 * dispense() function. If RedBean finds the bean it will return
154 * the OODB Bean object; if it cannot find the bean
155 * RedBean will return a new bean of type $type and with
156 * primary key ID 0. In the latter case it acts basically the
157 * same as dispense().
160 * If the bean cannot be found in the database a new bean of
161 * the specified type will be generated and returned.
163 * @param string $type type of bean you want to load
164 * @param integer $id ID of the bean you want to load
167 * @throws SQLException
169 public function load( $type, $id )
171 $bean = $this->dispense( $type );
172 if ( isset( $this->stash[$this->nesting][$id] ) ) {
173 $row = $this->stash[$this->nesting][$id];
176 $rows = $this->writer->queryRecord( $type, array( 'id' => array( $id ) ) );
177 } catch ( SQLException $exception ) {
178 if ( $this->writer->sqlStateIn( $exception->getSQLState(),
180 QueryWriter::C_SQLSTATE_NO_SUCH_COLUMN,
181 QueryWriter::C_SQLSTATE_NO_SUCH_TABLE )
184 throw $exception; //only throw if frozen
187 if ( empty( $rows ) ) {
190 $row = array_pop( $rows );
192 $bean->importRow( $row );
194 $this->oodb->signal( 'open', $bean );
197 return $bean->setMeta( 'tainted', FALSE );