Version 1
[yaffs-website] / vendor / gabordemooij / redbean / RedBeanPHP / Repository / Frozen.php
1 <?php
2
3 namespace RedBeanPHP\Repository;
4
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;
11
12 /**
13  * Frozen 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()
19  * method.
20  *
21  * @file    RedBeanPHP/Repository/Frozen.php
22  * @author  Gabor de Mooij and the RedBeanPHP community
23  * @license BSD/GPLv2
24  *
25  * @copyright
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.
29  */
30 class Frozen extends Repository
31 {
32         /**
33          * Handles exceptions.
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.
37          *
38          * @param \Exception $exception exception to handle
39          *
40          * @return void
41          */
42         protected function handleException( \Exception $exception )
43         {
44                 throw $exception;
45         }
46
47         /**
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
51          * in the database.
52          *
53          * @param OODBBean $bean the clean bean
54          *
55          * @return void
56          */
57         protected function storeBean( OODBBean $bean )
58         {
59                 if ( $bean->getMeta( 'changed' ) ) {
60
61                         list( $properties, $table ) = $bean->getPropertiesAndType();
62                         $id = $properties['id'];
63                         unset($properties['id']);
64                         $updateValues = array();
65                         $k1 = 'property';
66                         $k2 = 'value';
67                         foreach( $properties as $key => $value ) {
68                                 $updateValues[] = array( $k1 => $key, $k2 => $value );
69                         }
70                         $bean->id = $this->writer->updateRecord( $table, $updateValues, $id );
71                         $bean->setMeta( 'changed', FALSE );
72                 }
73                 $bean->setMeta( 'tainted', FALSE );
74         }
75
76         /**
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.
82          *
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.
87          *
88          * @param OODBBean $bean         bean to process
89          * @param array    $ownAdditions list of addition beans in own-list
90          *
91          * @return void
92          * @throws RedException
93          */
94         protected function processAdditions( $bean, $ownAdditions )
95         {
96                 $beanType = $bean->getMeta( 'type' );
97
98                 $cachedIndex = array();
99                 foreach ( $ownAdditions as $addition ) {
100                         if ( $addition instanceof OODBBean ) {
101
102                                 $myFieldLink = $beanType . '_id';
103                                 $alias = $bean->getMeta( 'sys.alias.' . $addition->getMeta( 'type' ) );
104                                 if ( $alias ) $myFieldLink = $alias . '_id';
105
106                                 $addition->$myFieldLink = $bean->id;
107                                 $addition->setMeta( 'cast.' . $myFieldLink, 'id' );
108                                 $this->store( $addition );
109
110                         } else {
111                                 throw new RedException( 'Array may only contain OODBBeans' );
112                         }
113                 }
114         }
115
116         /**
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.
124          *
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
128          *
129          * @return OODBBean
130          */
131         public function dispense( $type, $number = 1, $alwaysReturnArray = FALSE )
132         {
133                 $OODBBEAN = defined( 'REDBEAN_OODBBEAN_CLASS' ) ? REDBEAN_OODBBEAN_CLASS : '\RedBeanPHP\OODBBean';
134                 $beans = array();
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 );
140                         $beans[] = $bean;
141                 }
142
143                 return ( count( $beans ) === 1 && !$alwaysReturnArray ) ? array_pop( $beans ) : $beans;
144         }
145
146         /**
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().
158          *
159          * Important note:
160          * If the bean cannot be found in the database a new bean of
161          * the specified type will be generated and returned.
162          *
163          * @param string  $type type of bean you want to load
164          * @param integer $id   ID of the bean you want to load
165          *
166          * @return OODBBean
167          * @throws SQLException
168          */
169         public function load( $type, $id )
170         {
171                 $bean = $this->dispense( $type );
172                 if ( isset( $this->stash[$this->nesting][$id] ) ) {
173                         $row = $this->stash[$this->nesting][$id];
174                 } else {
175                         try {
176                                 $rows = $this->writer->queryRecord( $type, array( 'id' => array( $id ) ) );
177                         } catch ( SQLException $exception ) {
178                                 if ( $this->writer->sqlStateIn( $exception->getSQLState(),
179                                         array(
180                                                 QueryWriter::C_SQLSTATE_NO_SUCH_COLUMN,
181                                                 QueryWriter::C_SQLSTATE_NO_SUCH_TABLE )
182                                 )
183                                 ) {
184                                         throw $exception; //only throw if frozen
185                                 }
186                         }
187                         if ( empty( $rows ) ) {
188                                 return $bean;
189                         }
190                         $row = array_pop( $rows );
191                 }
192                 $bean->importRow( $row );
193                 $this->nesting++;
194                 $this->oodb->signal( 'open', $bean );
195                 $this->nesting--;
196
197                 return $bean->setMeta( 'tainted', FALSE );
198         }
199 }