3 namespace RedUNIT\Base;
5 use RedUNIT\Base as Base;
6 use RedBeanPHP\Facade as R;
7 use RedBeanPHP\RedException as RedException;
8 use RedBeanPHP\QueryWriter as QueryWriter;
9 use RedBeanPHP\QueryWriter\AQueryWriter as AQueryWriter;
14 * Tests basic update functionality - however this test suite
15 * has grown to cover various other scenarios involving updates as
16 * well, including setting of property filters (necessary for
17 * spatial tools in MySQL), storiging INF value and more...
19 * @file RedUNIT/Base/Update.php
20 * @desc Tests basic storage features through OODB class.
21 * @author Gabor de Mooij and the RedBeanPHP Community
22 * @license New BSD/GPLv2
24 * (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community.
25 * This source file is subject to the New BSD/GPLv2 License that is bundled
26 * with this source code in the file license.txt.
28 class Update extends Base
31 * Test whether we can use SQL filters and
32 * whether they are being applied properly for
33 * different types of SELECT queries in the QueryWriter.
35 public function testSQLFilters()
38 AQueryWriter::setSQLFilters(array(
39 QueryWriter::C_SQLFILTER_READ => array(
40 'book' => array( 'title' => ' LOWER(book.title) '),
42 QueryWriter::C_SQLFILTER_WRITE => array(
43 'book' => array( 'title' => ' UPPER(?) '),
47 $book = R::dispense( 'book' );
48 $book->title = 'story';
50 asrt( R::getCell( 'SELECT title FROM book WHERE id = ?', array( $book->id ) ), 'STORY' );
51 $book = $book->fresh();
52 asrt( $book->title, 'story' );
53 $library = R::dispense( 'library' );
54 $library->sharedBookList[] = $book;
56 $library = $library->fresh();
57 $books = $library->sharedBookList;
58 $book = reset( $books );
59 asrt( $book->title, 'story' );
60 $otherBook = R::dispense('book');
61 $otherBook->sharedBook[] = $book;
62 R::store( $otherBook );
63 $otherBook = $otherBook->fresh();
64 $books = $otherBook->sharedBookList;
65 $book = reset( $books );
66 asrt( $book->title, 'story' );
67 $links = $book->ownBookBookList;
68 $link = reset( $links );
70 AQueryWriter::setSQLFilters(array(
71 QueryWriter::C_SQLFILTER_READ => array(
72 'book' => array( 'title' => ' LOWER(book.title) '),
73 'book_book' => array( 'shelf' => ' LOWER(book_book.shelf) '),
75 QueryWriter::C_SQLFILTER_WRITE => array(
76 'book' => array( 'title' => ' UPPER(?) '),
77 'book_book' => array( 'shelf' => ' UPPER(?) ')
81 asrt( R::getCell( 'SELECT shelf FROM book_book WHERE id = ?', array( $link->id ) ), 'X13' );
82 $otherBook = $otherBook->fresh();
83 unset($book->sharedBookList[$otherBook->id]);
85 AQueryWriter::setSQLFilters(array());
89 * Test unsetting properties.
93 public function testUnsetUpdate()
96 $book = R::dispense( 'book' );
100 $book = $book->fresh();
102 unset( $book->name );
104 $book = $book->fresh();
105 asrt( $book->name, 'x' );
106 asrt( (int) $book->price, 40 );
109 $book = $book->fresh();
110 asrt( $book->name, 'x' );
111 asrt( (int) $book->price, 30 );
113 unset( $book->price );
116 $book = $book->fresh();
117 asrt( $book->name, 'y' );
118 asrt( (int) $book->price, 30 );
122 * Tests whether we can update or unset a parent bean
123 * with an alias without having to use fetchAs and
124 * without loading the aliased bean causing table-not-found
127 public function testUpdatingParentBeansWithAliases()
129 testpack( 'Test updating parent beans with aliases' );
131 $trans = R::dispense( 'transaction' );
132 $seller = R::dispense( 'user' );
133 $trans->seller = $seller;
134 $id = R::store( $trans );
136 $trans = R::load( 'transaction', $id );
137 //should not try to load seller, should not require fetchAs().
139 $trans->seller = R::dispense( 'user' );
141 } catch( Exception $e ) {
144 $trans = R::load( 'transaction', $id );
147 unset( $trans->seller );
149 } catch ( Exception $e ) {
153 $account = R::dispense( 'user' );
154 asrt( count( $account->alias( 'seller' )->ownTransaction ), 0 );
155 $account->alias( 'seller' )->ownTransaction = R::dispense( 'transaction', 10 );
156 $account->alias( 'boo' ); //try to trick me...
157 $id = R::store( $account );
159 $account = R::load( 'user', $id );
160 asrt( count( $account->alias( 'seller' )->ownTransaction ), 10 );
161 //you cannot unset a list
162 unset( $account->alias( 'seller' )->ownTransaction );
163 $id = R::store( $account );
164 $account = R::load( 'user', $id );
165 asrt( count( $account->alias( 'seller' )->ownTransaction ), 10 );
166 $account->alias( 'seller' )->ownTransaction = array();
167 $id = R::store( $account );
168 $account = R::load( 'user', $id );
169 asrt(count($account->alias( 'seller' )->ownTransaction), 0 );
170 asrt(count($account->ownTransaction), 0 );
172 //but also make sure we don't cause extra column issue #335
174 $building = R::dispense('building');
175 $village = R::dispense('village');
176 $building->village = $village;
178 $building = $building->fresh();
179 $building->village = NULL;
181 $building = $building->fresh();
182 $columns = R::inspect('building');
183 asrt( isset( $columns['village'] ), FALSE );
184 asrt( isset( $building->village ), FALSE );
186 $building = R::dispense('building');
187 $village = R::dispense('village');
188 $building->village = $village;
190 $building = $building->fresh();
191 unset($building->village);
193 $building = $building->fresh();
194 $columns = R::inspect('building');
195 asrt( isset( $columns['village'] ), FALSE );
196 asrt( isset( $building->village ), FALSE );
197 $building = R::dispense('building');
198 $village = R::dispense('village');
199 $building->village = $village;
201 $building = $building->fresh();
202 $building->village = FALSE;
204 $building = $building->fresh();
205 $columns = R::inspect('building');
206 asrt( isset( $columns['village'] ), FALSE );
207 asrt( isset( $building->village ), FALSE );
211 * All kinds of tests for basic CRUD.
213 * Does the data survive?
217 public function testUpdatingBeans()
219 testpack( 'Test basic support UUID/override ID default value' );
220 $bean = R::dispense( 'bean' );
222 if ($this->currentlyActiveDriverID === 'mysql') {
223 //otherwise UTF8 causes index overflow in mysql: SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes
224 R::exec('alter table bean modify column id char(3);');
226 R::getWriter()->widenColumn( 'bean', 'id', R::getWriter()->scanType( 'abc' ) );
230 asrt( $bean->id, 'abc' );
231 testpack( 'Test Update' );
235 } catch ( RedException $e ) {
238 $toolbox = R::getToolBox();
239 $adapter = $toolbox->getDatabaseAdapter();
240 $writer = $toolbox->getWriter();
241 $redbean = $toolbox->getRedBean();
242 $pdo = $adapter->getDatabase();
243 $page = $redbean->dispense( "page" );
244 $page->name = "old name";
245 $id = $redbean->store( $page );
246 asrt( $page->getMeta( 'tainted' ), FALSE );
247 $page->setAttr( 'name', "new name" );
248 asrt( $page->getMeta( 'tainted' ), TRUE );
249 $id = $redbean->store( $page );
250 $page = $redbean->load( "page", $id );
251 asrt( $page->name, "new name" );
252 // Null should == NULL after saving
253 $page->rating = NULL;
254 $newid = $redbean->store( $page );
255 $page = $redbean->load( "page", $id );
256 asrt( $page->name, "new name" );
257 asrt( ( $page->rating === NULL ), TRUE );
258 asrt( !$page->rating, TRUE );
259 $page->rating = FALSE;
260 $newid = $redbean->store( $page );
262 $page = $redbean->load( "page", $id );
263 asrt( $page->name, "new name" );
264 asrt( (bool) $page->rating, FALSE );
265 asrt( ( $page->rating == FALSE ), TRUE );
266 asrt( !$page->rating, TRUE );
267 $page->rating = TRUE;
268 $newid = $redbean->store( $page );
270 $page = $redbean->load( "page", $id );
271 asrt( $page->name, "new name" );
272 asrt( (bool) $page->rating, TRUE );
273 asrt( ( $page->rating == TRUE ), TRUE );
274 asrt( ( $page->rating == TRUE ), TRUE );
275 $page->rating = NULL;
277 $page = R::load( 'page', $page->id );
278 asrt( $page->rating, NULL );
280 $newid = $redbean->store( $page );
282 $page = $redbean->load( "page", $id );
283 asrt( $page->name, "new name" );
284 asrt( $page->rating, "1" );
286 $newid = $redbean->store( $page );
287 asrt( $page->rating, "0" );
289 $newid = $redbean->store( $page );
290 asrt( $page->rating, 0 );
292 $newid = $redbean->store( $page );
294 $page = $redbean->load( "page", $id );
295 asrt( $page->name, "new name" );
296 asrt( !$page->rating, TRUE );
297 asrt( ( $page->rating == 0 ), TRUE );
298 asrt( ( $page->rating == FALSE ), TRUE );
300 $newid = $redbean->store( $page );
302 $page = $redbean->load( "page", $id );
303 asrt( $page->name, "new name" );
304 asrt( strval( $page->rating ), "5" );
306 $newid = $redbean->store( $page );
308 $page = $redbean->load( "page", $id );
309 asrt( $page->name, "new name" );
310 asrt( strval( $page->rating ), "300" );
312 $newid = $redbean->store( $page );
314 $page = $redbean->load( "page", $id );
315 asrt( $page->name, "new name" );
316 asrt( strval( $page->rating ), "-2" );
318 $newid = $redbean->store( $page );
320 $page = $redbean->load( "page", $id );
321 asrt( $page->name, "new name" );
322 asrt( ( $page->rating == 2.5 ), TRUE );
323 $page->rating = -3.3;
324 $newid = $redbean->store( $page );
326 $page = $redbean->load( "page", $id );
327 asrt( $page->name, "new name" );
328 asrt( ( $page->rating == -3.3 ), TRUE );
329 $page->rating = "good";
330 $newid = $redbean->store( $page );
332 $page = $redbean->load( "page", $id );
333 asrt( $page->name, "new name" );
334 asrt( $page->rating, "good" );
335 $longtext = str_repeat( 'great! because..', 100 );
336 $page->rating = $longtext;
337 $newid = $redbean->store( $page );
339 $page = $redbean->load( "page", $id );
340 asrt( $page->name, "new name" );
341 asrt( $page->rating, $longtext );
342 // Test leading zeros
343 $numAsString = "0001";
344 $page->numasstring = $numAsString;
345 $redbean->store( $page );
346 $page = $redbean->load( "page", $id );
347 asrt( $page->numasstring, "0001" );
348 $page->numnotstring = "0.123";
349 $redbean->store( $page );
350 $page = $redbean->load( "page", $id );
351 asrt( $page->numnotstring == 0.123, TRUE );
352 $page->numasstring2 = "00.123";
353 $redbean->store( $page );
354 $page = $redbean->load( "page", $id );
355 asrt( $page->numasstring2, "00.123" );
357 $redbean->trash( array() );
359 } catch ( RedException $e ) {
362 $redbean->trash( $page );
363 asrt( (int) $pdo->GetCell( "SELECT count(*) FROM page" ), 0 );
367 * Tests whether empty strings are preserved as such.
371 public function testEmptyStringShouldNotBeStoredAsInteger()
374 $bean = R::dispense('bean');
377 $bean = $bean->fresh();
378 asrt( ( $bean->str === '' ), TRUE);
382 * Test handling of infinity values.
386 public function testStoringInf()
389 $bean = R::dispense( 'bean' );
392 $bean = $bean->fresh();
393 asrt( ( $bean->inf === 'INF' ), TRUE );
394 asrt( ( $bean->inf == 'INF' ), TRUE );
395 $bean->modifyme = 'yes';
397 $bean = $bean->fresh();
398 asrt( ( $bean->inf === 'INF' ), TRUE );
399 asrt( ( $bean->inf == 'INF' ), TRUE );
400 $bean->modifyme = 'yes';