Yaffs site version 1.1
[yaffs-website] / vendor / gabordemooij / redbean / testing / RedUNIT / Postgres / Writer.php
1 <?php
2
3 namespace RedUNIT\Postgres;
4
5 use RedUNIT\Postgres as Postgres;
6 use RedBeanPHP\Facade as R;
7 use RedBeanPHP\AssociationManager as AssociationManager;
8 use RedBeanPHP\QueryWriter\PostgreSQL as PostgreSQL;
9 use RedBeanPHP\RedException\SQL as SQL;
10
11 /**
12  * Writer
13  *
14  * Tests for PostgreSQL Query Writer.
15  * This test class contains Query Writer specific tests.
16  * Use this class to add tests to test Query Writer specific
17  * behaviours, quirks and issues.
18  *
19  * @file    RedUNIT/Postgres/Writer.php
20  * @desc    A collection of writer specific tests.
21  * @author  Gabor de Mooij and the RedBeanPHP Community
22  * @license New BSD/GPLv2
23  *
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.
27  */
28 class Writer extends Postgres
29 {
30         /**
31          * Test scanning and coding.
32          *
33          * @return void
34          */
35         public function testScanningAndCoding()
36         {
37                 $toolbox = R::getToolBox();
38                 $adapter = $toolbox->getDatabaseAdapter();
39                 $writer  = $toolbox->getWriter();
40                 $redbean = $toolbox->getRedBean();
41                 $pdo     = $adapter->getDatabase();
42
43                 $a = new AssociationManager( $toolbox );
44
45                 $adapter->exec( "DROP TABLE IF EXISTS testtable" );
46
47                 asrt( in_array( "testtable", $writer->getTables() ), FALSE );
48
49                 $writer->createTable( "testtable" );
50
51                 asrt( in_array( "testtable", $writer->getTables() ), TRUE );
52
53                 asrt( count( array_keys( $writer->getColumns( "testtable" ) ) ), 1 );
54
55                 asrt( in_array( "id", array_keys( $writer->getColumns( "testtable" ) ) ), TRUE );
56                 asrt( in_array( "c1", array_keys( $writer->getColumns( "testtable" ) ) ), FALSE );
57
58                 $writer->addColumn( "testtable", "c1", 1 );
59
60                 asrt( count( array_keys( $writer->getColumns( "testtable" ) ) ), 2 );
61
62                 asrt( in_array( "c1", array_keys( $writer->getColumns( "testtable" ) ) ), TRUE );
63
64                 foreach ( $writer->sqltype_typeno as $key => $type ) {
65                         if ( $type < 100 ) {
66                                 asrt( $writer->code( $key, TRUE ), $type );
67                         } else {
68                                 asrt( $writer->code( $key ), PostgreSQL::C_DATATYPE_SPECIFIED );
69                         }
70                 }
71
72                 asrt( $writer->code( PostgreSQL::C_DATATYPE_SPECIAL_DATETIME ), PostgreSQL::C_DATATYPE_SPECIFIED );
73
74                 asrt( $writer->code( "unknown" ), PostgreSQL::C_DATATYPE_SPECIFIED );
75
76                 asrt( $writer->scanType( FALSE ), PostgreSQL::C_DATATYPE_INTEGER );
77                 asrt( $writer->scanType( TRUE ), PostgreSQL::C_DATATYPE_INTEGER );
78
79                 asrt( $writer->scanType( NULL ), PostgreSQL::C_DATATYPE_INTEGER );
80
81                 asrt( $writer->scanType( 2 ), PostgreSQL::C_DATATYPE_INTEGER );
82
83                 asrt( $writer->scanType( 255 ), PostgreSQL::C_DATATYPE_INTEGER );
84                 asrt( $writer->scanType( 256 ), PostgreSQL::C_DATATYPE_INTEGER );
85
86                 asrt( $writer->scanType( -1 ), PostgreSQL::C_DATATYPE_INTEGER );
87
88                 asrt( $writer->scanType( 1.5 ), PostgreSQL::C_DATATYPE_DOUBLE );
89
90                 asrt( $writer->scanType( INF ), PostgreSQL::C_DATATYPE_TEXT );
91
92                 asrt( $writer->scanType( "abc" ), PostgreSQL::C_DATATYPE_TEXT );
93
94                 asrt( $writer->scanType( "2001-10-10", TRUE ), PostgreSQL::C_DATATYPE_SPECIAL_DATE );
95
96                 asrt( $writer->scanType( "2001-10-10 10:00:00", TRUE ), PostgreSQL::C_DATATYPE_SPECIAL_DATETIME );
97
98                 asrt( $writer->scanType( "2001-10-10 10:00:00" ), PostgreSQL::C_DATATYPE_TEXT );
99
100                 asrt( $writer->scanType( "2001-10-10" ), PostgreSQL::C_DATATYPE_TEXT );
101
102                 asrt( $writer->scanType( str_repeat( "lorem ipsum", 100 ) ), PostgreSQL::C_DATATYPE_TEXT );
103
104                 $writer->widenColumn( "testtable", "c1", PostgreSQL::C_DATATYPE_TEXT );
105
106                 $cols = $writer->getColumns( "testtable" );
107
108                 asrt( $writer->code( $cols["c1"] ), PostgreSQL::C_DATATYPE_TEXT );
109
110                 $writer->addColumn( "testtable", "special", PostgreSQL::C_DATATYPE_SPECIAL_DATE );
111
112                 $cols = $writer->getColumns( "testtable" );
113
114                 asrt( $writer->code( $cols['special'], TRUE ), PostgreSQL::C_DATATYPE_SPECIAL_DATE );
115
116                 asrt( $writer->code( $cols['special'], FALSE ), PostgreSQL::C_DATATYPE_SPECIFIED );
117
118                 $writer->addColumn( "testtable", "special2", PostgreSQL::C_DATATYPE_SPECIAL_DATETIME );
119
120                 $cols = $writer->getColumns( "testtable" );
121
122                 asrt( $writer->code( $cols['special2'], TRUE ), PostgreSQL::C_DATATYPE_SPECIAL_DATETIME );
123
124                 asrt( $writer->code( $cols['special'], FALSE ), PostgreSQL::C_DATATYPE_SPECIFIED );
125
126                 //$id = $writer->insertRecord("testtable", array("c1"), array(array("lorem ipsum")));
127
128                 $id = $writer->updateRecord( "testtable", array( array( "property" => "c1", "value" => "lorem ipsum" ) ) );
129
130                 $row = $writer->queryRecord( "testtable", array( "id" => array( $id ) ) );
131
132                 asrt( $row[0]["c1"], "lorem ipsum" );
133
134                 $writer->updateRecord( "testtable", array( array( "property" => "c1", "value" => "ipsum lorem" ) ), $id );
135
136                 $row = $writer->queryRecord( "testtable", array( "id" => array( $id ) ) );
137
138                 asrt( $row[0]["c1"], "ipsum lorem" );
139
140                 $writer->deleteRecord( "testtable", array( "id" => array( $id ) ) );
141
142                 $row = $writer->queryRecord( "testtable", array( "id" => array( $id ) ) );
143
144                 asrt( empty( $row ), TRUE );
145         }
146
147         /**
148          * (FALSE should be stored as 0 not as '')
149          *
150          * @return void
151          */
152         public function testZeroIssue()
153         {
154                 testpack( "Zero issue" );
155
156                 $toolbox = R::getToolBox();
157                 $redbean = $toolbox->getRedBean();
158
159                 $bean = $redbean->dispense( "zero" );
160
161                 $bean->zero  = FALSE;
162                 $bean->title = "bla";
163
164                 $redbean->store( $bean );
165
166                 asrt( count( $redbean->find( "zero", array(), " zero = 0 " ) ), 1 );
167
168                 testpack( "Test ANSI92 issue in clearrelations" );
169
170                 $a = new AssociationManager( $toolbox );
171
172                 $book    = $redbean->dispense( "book" );
173                 $author1 = $redbean->dispense( "author" );
174                 $author2 = $redbean->dispense( "author" );
175
176                 $book->title = "My First Post";
177
178                 $author1->name = "Derek";
179                 $author2->name = "Whoever";
180
181                 set1toNAssoc( $a, $book, $author1 );
182                 set1toNAssoc( $a, $book, $author2 );
183
184                 pass();
185         }
186
187         /**
188          * Various.
189          * Tests whether writer correctly handles keyword 'group' and SQL state 23000 issue.
190          * These tests remain here to make sure issues 9 and 10 never happen again.
191          * However this bug will probably never re-appear due to changed architecture.
192          *
193          * @return void
194          */
195         public function testIssue9and10()
196         {
197                 $toolbox = R::getToolBox();
198                 $redbean = $toolbox->getRedBean();
199                 $adapter = $toolbox->getDatabaseAdapter();
200
201                 $a = new AssociationManager( $toolbox );
202
203                 $book = $redbean->dispense( "book" );
204
205                 $author1 = $redbean->dispense( "author" );
206                 $author2 = $redbean->dispense( "author" );
207
208                 $book->title = "My First Post";
209
210                 $author1->name = "Derek";
211                 $author2->name = "Whoever";
212
213                 $a->associate( $book, $author1 );
214                 $a->associate( $book, $author2 );
215
216                 pass();
217
218                 testpack( "Test Association Issue Group keyword (Issues 9 and 10)" );
219
220                 R::nuke();
221
222                 $group = $redbean->dispense( "group" );
223
224                 $group->name = "mygroup";
225
226                 $redbean->store( $group );
227
228                 try {
229                         $a->associate( $group, $book );
230
231                         pass();
232                 } catch ( SQL $e ) {
233                         fail();
234                 }
235
236                 // Test issue SQL error 23000
237                 try {
238                         $a->associate( $group, $book );
239
240                         pass();
241                 } catch ( SQL $e ) {
242                         fail();
243                 }
244
245                 asrt( (int) $adapter->getCell( "select count(*) from book_group" ), 1 ); //just 1 rec!
246         }
247
248         /**
249          * Test various.
250          * Test various somewhat uncommon trash/unassociate scenarios.
251          * (i.e. unassociate unrelated beans, trash non-persistant beans etc).
252          * Should be handled gracefully - no output checking.
253          *
254          * @return void
255          */
256         public function testVaria()
257         {
258                 $toolbox = R::getToolBox();
259                 $redbean = $toolbox->getRedBean();
260
261                 $a = new AssociationManager( $toolbox );
262
263                 $book    = $redbean->dispense( "book" );
264                 $author1 = $redbean->dispense( "author" );
265                 $author2 = $redbean->dispense( "author" );
266
267                 $book->title = "My First Post";
268
269                 $author1->name = "Derek";
270                 $author2->name = "Whoever";
271
272                 $a->unassociate( $book, $author1 );
273                 $a->unassociate( $book, $author2 );
274
275                 pass();
276
277                 $redbean->trash( $redbean->dispense( "bla" ) );
278
279                 pass();
280
281                 $bean = $redbean->dispense( "bla" );
282
283                 $bean->name = 1;
284                 $bean->id   = 2;
285
286                 $redbean->trash( $bean );
287
288                 pass();
289         }
290
291         /**
292          * Test special types.
293          *
294          * @return void
295          */
296         public function testTypes()
297         {
298                 testpack( 'Special data types' );
299
300                 $bean = R::dispense( 'bean' );
301
302                 $bean->date = 'someday';
303
304                 R::store( $bean );
305
306                 $cols = R::getColumns( 'bean' );
307
308                 asrt( $cols['date'], 'text' );
309
310                 $bean = R::dispense( 'bean' );
311
312                 $bean->date = '2011-10-10';
313
314                 R::store( $bean );
315
316                 $cols = R::getColumns( 'bean' );
317
318                 asrt( $cols['date'], 'text' );
319         }
320
321         /**
322          * Test dates.
323          *
324          * @return void
325          */
326         public function testTypesDates()
327         {
328                 $bean = R::dispense( 'bean' );
329
330                 $bean->date = '2011-10-10';
331
332                 R::store( $bean );
333
334                 $cols = R::getColumns( 'bean' );
335
336                 asrt( $cols['date'], 'date' );
337         }
338
339         /**
340          * Datetime.
341          *
342          * @return void
343          */
344         public function testTypesDateTimes()
345         {
346                 $bean = R::dispense( 'bean' );
347
348                 $bean->date = '2011-10-10 10:00:00';
349
350                 R::store( $bean );
351
352                 $cols = R::getColumns( 'bean' );
353
354                 asrt( $cols['date'], 'timestamp without time zone' );
355         }
356
357         /**
358          * Test spatial data types.
359          *
360          * @return void
361          */
362         public function testTypesPoints()
363         {
364                 $bean = R::dispense( 'bean' );
365
366                 $bean->point = '(92,12)';
367
368                 R::store( $bean );
369
370                 $cols = R::getColumns( 'bean' );
371
372                 asrt( $cols['point'], 'point' );
373
374                 $bean = R::load( 'bean', $bean->id );
375
376                 asrt( $bean->point, '(92,12)' );
377
378                 $bean->note = 'taint';
379
380                 R::store( $bean );
381
382                 $bean = R::load( 'bean', $bean->id );
383
384                 asrt( $bean->point, '(92,12)' );
385         }
386
387         /**
388          * Test points.
389          *
390          * @return void
391          */
392         public function testTypesDecPoints()
393         {
394                 $bean = R::dispense( 'bean' );
395
396                 $bean->point = '(9.2,1.2)';
397
398                 R::store( $bean );
399
400                 $cols = R::getColumns( 'bean' );
401
402                 asrt( $cols['point'], 'point' );
403
404                 $bean = R::load( 'bean', $bean->id );
405
406                 asrt( $bean->point, '(9.2,1.2)' );
407
408                 $bean->note = 'taint';
409
410                 R::store( $bean );
411
412                 $bean = R::load( 'bean', $bean->id );
413
414                 asrt( $bean->point, '(9.2,1.2)' );
415         }
416
417         /**
418          * Test polygons.
419          *
420          * @return void
421          */
422         public function testPolygons()
423         {
424                 $bean = R::dispense( 'bean' );
425                 $bean->polygon = '((0,0),(1,1),(2,0))';
426                 R::store( $bean );
427                 $cols = R::getColumns( 'bean' );
428                 asrt( $cols['polygon'], 'polygon' );
429                 $bean = R::load( 'bean', $bean->id );
430                 asrt( $bean->polygon, '((0,0),(1,1),(2,0))' );
431                 $bean->note = 'taint';
432                 R::store( $bean );
433                 $bean = R::load( 'bean', $bean->id );
434                 asrt( $bean->polygon, '((0,0),(1,1),(2,0))' );
435                 $bean = R::dispense( 'bean' );
436                 $bean->polygon = '((0,0),(1.2,1),(2,0.3))';
437                 R::store( $bean );
438                 $cols = R::getColumns( 'bean' );
439                 asrt( $cols['polygon'], 'polygon' );
440                 $bean = R::load( 'bean', $bean->id );
441                 asrt( $bean->polygon, '((0,0),(1.2,1),(2,0.3))' );
442                 $bean->note = 'taint';
443                 R::store( $bean );
444                 $bean = R::load( 'bean', $bean->id );
445                 asrt( $bean->polygon, '((0,0),(1.2,1),(2,0.3))' );
446         }
447
448         /**
449          * Test multi points.
450          *
451          * @return void
452          */
453         public function testTypesMultiDecPoints()
454         {
455                 $bean = R::dispense( 'bean' );
456
457                 $bean->line = '[(1.2,1.4),(2.2,34)]';
458
459                 R::store( $bean );
460
461                 $cols = R::getColumns( 'bean' );
462
463                 asrt( $cols['line'], 'lseg' );
464
465                 $bean = R::load( 'bean', $bean->id );
466
467                 asrt( $bean->line, '[(1.2,1.4),(2.2,34)]' );
468
469                 $bean->note = 'taint';
470
471                 R::store( $bean );
472
473                 $bean = R::load( 'bean', $bean->id );
474
475                 asrt( $bean->line, '[(1.2,1.4),(2.2,34)]' );
476         }
477
478         /**
479          * More points...
480          *
481          * @return void
482          */
483         public function testTypesWeirdPoints()
484         {
485                 $bean = R::dispense( 'bean' );
486
487                 $bean->circle = '<(9.2,1.2),7.9>';
488
489                 R::store( $bean );
490
491                 $cols = R::getColumns( 'bean' );
492
493                 asrt( $cols['circle'], 'circle' );
494
495                 $bean = R::load( 'bean', $bean->id );
496
497                 asrt( $bean->circle, '<(9.2,1.2),7.9>' );
498
499                 $bean->note = 'taint';
500
501                 R::store( $bean );
502
503                 $bean = R::load( 'bean', $bean->id );
504
505                 asrt( $bean->circle, '<(9.2,1.2),7.9>' );
506         }
507
508         /**
509          * Test money types.
510          *
511          * @return void
512          */
513         public function testTypesMon()
514         {
515                 $bean       = R::dispense( 'bean' );
516
517                 $bean->amount = '22.99';
518
519                 R::store( $bean );
520
521                 $cols = R::getColumns( 'bean' );
522
523                 asrt( $cols['amount'], 'numeric' );
524
525                 R::nuke();
526
527                 $bean       = R::dispense( 'bean' );
528
529                 $bean->amount = '-22.99';
530
531                 R::store( $bean );
532
533                 $cols = R::getColumns( 'bean' );
534
535                 asrt( $cols['amount'], 'numeric' );
536         }
537
538         /**
539          * Test money data type.
540          *
541          * @return void
542          */
543         public function testTypesMoney()
544         {
545                 $bean = R::dispense( 'bean' );
546
547                 $bean->money = '$123.45';
548
549                 R::store( $bean );
550
551                 $cols = R::getColumns( 'bean' );
552
553                 asrt( $cols['money'], 'money' );
554
555                 $bean = R::load( 'bean', $bean->id );
556
557                 asrt( $bean->money, '$123.45' );
558
559                 $bean->note = 'taint';
560
561                 R::store( $bean );
562
563                 $bean = R::load( 'bean', $bean->id );
564
565                 asrt( $bean->money, '$123.45' );
566
567                 $bean->money = '$123,455.01';
568
569                 R::store($bean);
570
571                 $bean = $bean->fresh();
572
573                 asrt( $bean->money, '$123,455.01' );
574
575         }
576
577         /**
578          * Test negative money data type.
579          *
580          * @return void
581          */
582         public function testTypesNegativeMoney()
583         {
584                 $bean = R::dispense( 'bean' );
585
586                 $bean->money = '-$123.45';
587
588                 R::store( $bean );
589
590                 $cols = R::getColumns( 'bean' );
591
592                 asrt( $cols['money'], 'money' );
593
594                 $bean = R::load( 'bean', $bean->id );
595
596                 asrt( $bean->money, '-$123.45' );
597
598                 $bean->note = 'taint';
599
600                 R::store( $bean );
601
602                 $bean = R::load( 'bean', $bean->id );
603
604                 asrt( $bean->money, '-$123.45' );
605         }
606
607         /**
608          * Issue #340
609          * Redbean is currently picking up bcrypt hashed passwords
610          * (which look like this: $2y$12$85lAS....SnpDNVGPAC7w0G)
611          * as PostgreSQL money types.
612          * Then, once R::store is called on the bean, it chokes and throws the following error:
613          * PHP Fatal error: Uncaught [22P02] - SQLSTATE[22P02]: Invalid text representation: 7 ERROR:
614          * invalid input syntax for type money: ....
615          *
616          * @return void
617          */
618         public function testTypesInvalidMoney()
619         {
620                 $bean = R::dispense( 'bean' );
621
622                 $bean->nomoney = '$2y$12$85lAS';
623
624                 R::store( $bean );
625
626                 $cols = R::getColumns( 'bean' );
627
628                 asrt( $cols['nomoney'], 'text' );
629
630                 $bean = R::load( 'bean', $bean->id );
631
632                 asrt( $bean->nomoney, '$2y$12$85lAS' );
633
634                 $bean->note = 'taint';
635
636                 R::store( $bean );
637
638                 $bean = R::load( 'bean', $bean->id );
639
640                 asrt( $bean->nomoney, '$2y$12$85lAS' );
641         }
642
643         /**
644          * Test types of strings.
645          *
646          * @return void
647          */
648         public function testTypesStrings()
649         {
650                 $bean = R::dispense( 'bean' );
651
652                 $bean->data = 'abcdefghijk';
653
654                 R::store( $bean );
655
656                 $cols = R::getColumns( 'bean' );
657
658                 asrt( $cols['data'], 'text' );
659
660                 $bean = R::load( 'bean', $bean->id );
661
662                 asrt( $bean->data, 'abcdefghijk' );
663
664                 $bean->data = '(1,2)';
665
666                 R::store( $bean );
667
668                 $cols = R::getColumns( 'bean' );
669
670                 asrt( $cols['data'], 'text' );
671
672                 $bean->data = '[(1.2,1.4),(2.2,34)]';
673
674                 R::store( $bean );
675
676                 $cols = R::getColumns( 'bean' );
677
678                 asrt( $cols['data'], 'text' );
679
680                 $bean->data = '<(9.2,1.2),7.9>';
681
682                 R::store( $bean );
683
684                 $cols = R::getColumns( 'bean' );
685
686                 asrt( $cols['data'], 'text' );
687
688                 $bean->data = '$25';
689
690                 R::store( $bean );
691
692                 $cols = R::getColumns( 'bean' );
693
694                 asrt( $cols['data'], 'text' );
695
696                 $bean->data = '2012-10-10 10:00:00';
697
698                 R::store( $bean );
699
700                 $cols = R::getColumns( 'bean' );
701
702                 asrt( $cols['data'], 'text' );
703         }
704 }