統計
| ブランチ: | リビジョン:

pictcode / lib / Cake / Test / Case / Model / CakeSchemaTest.php @ 0b1b8047

履歴 | 表示 | アノテート | ダウンロード (28.483 KB)

1
<?php
2
/**
3
 * Test for Schema database management
4
 *
5
 * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
6
 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
7
 *
8
 * Licensed under The MIT License
9
 * For full copyright and license information, please see the LICENSE.txt
10
 * Redistributions of files must retain the above copyright notice
11
 *
12
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
13
 * @link          http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
14
 * @package       Cake.Test.Case.Model
15
 * @since         CakePHP(tm) v 1.2.0.5550
16
 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
17
 */
18

    
19
App::uses('CakeSchema', 'Model');
20
App::uses('CakeTestFixture', 'TestSuite/Fixture');
21

    
22
/**
23
 * Test for Schema database management
24
 *
25
 * @package       Cake.Test.Case.Model
26
 */
27
class MyAppSchema extends CakeSchema {
28

    
29
/**
30
 * connection property
31
 *
32
 * @var string
33
 */
34
        public $connection = 'test';
35

    
36
/**
37
 * comments property
38
 *
39
 * @var array
40
 */
41
        public $comments = array(
42
                'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
43
                'post_id' => array('type' => 'integer', 'null' => false, 'default' => 0),
44
                'user_id' => array('type' => 'integer', 'null' => false),
45
                'title' => array('type' => 'string', 'null' => false, 'length' => 100),
46
                'comment' => array('type' => 'text', 'null' => false, 'default' => null),
47
                'published' => array('type' => 'string', 'null' => true, 'default' => 'N', 'length' => 1),
48
                'created' => array('type' => 'datetime', 'null' => true, 'default' => null),
49
                'updated' => array('type' => 'datetime', 'null' => true, 'default' => null),
50
                'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)),
51
        );
52

    
53
/**
54
 * posts property
55
 *
56
 * @var array
57
 */
58
        public $posts = array(
59
                'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
60
                'author_id' => array('type' => 'integer', 'null' => true, 'default' => ''),
61
                'title' => array('type' => 'string', 'null' => false, 'default' => 'Title'),
62
                'body' => array('type' => 'text', 'null' => true, 'default' => null),
63
                'summary' => array('type' => 'text', 'null' => true),
64
                'published' => array('type' => 'string', 'null' => true, 'default' => 'Y', 'length' => 1),
65
                'created' => array('type' => 'datetime', 'null' => true, 'default' => null),
66
                'updated' => array('type' => 'datetime', 'null' => true, 'default' => null),
67
                'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)),
68
        );
69

    
70
/**
71
 * _foo property
72
 *
73
 * @var array
74
 */
75
        protected $_foo = array('bar');
76

    
77
/**
78
 * getVar method
79
 *
80
 * @param string $var Name of var
81
 * @return mixed
82
 */
83
        public function getVar($var) {
84
                if (!isset($this->$var)) {
85
                        return null;
86
                }
87
                return $this->$var;
88
        }
89

    
90
}
91

    
92
/**
93
 * TestAppSchema class
94
 *
95
 * @package       Cake.Test.Case.Model
96
 */
97
class TestAppSchema extends CakeSchema {
98

    
99
/**
100
 * name property
101
 *
102
 * @var string
103
 */
104
        public $name = 'MyApp';
105

    
106
/**
107
 * comments property
108
 *
109
 * @var array
110
 */
111
        public $comments = array(
112
                'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
113
                'article_id' => array('type' => 'integer', 'null' => false),
114
                'user_id' => array('type' => 'integer', 'null' => false),
115
                'comment' => array('type' => 'text', 'null' => true, 'default' => null),
116
                'published' => array('type' => 'string', 'null' => true, 'default' => 'N', 'length' => 1),
117
                'created' => array('type' => 'datetime', 'null' => true, 'default' => null),
118
                'updated' => array('type' => 'datetime', 'null' => true, 'default' => null),
119
                'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)),
120
                'tableParameters' => array(),
121
        );
122

    
123
/**
124
 * posts property
125
 *
126
 * @var array
127
 */
128
        public $posts = array(
129
                'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
130
                'author_id' => array('type' => 'integer', 'null' => false),
131
                'title' => array('type' => 'string', 'null' => false),
132
                'body' => array('type' => 'text', 'null' => true, 'default' => null),
133
                'published' => array('type' => 'string', 'null' => true, 'default' => 'N', 'length' => 1),
134
                'created' => array('type' => 'datetime', 'null' => true, 'default' => null),
135
                'updated' => array('type' => 'datetime', 'null' => true, 'default' => null),
136
                'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)),
137
                'tableParameters' => array(),
138
        );
139

    
140
/**
141
 * posts_tags property
142
 *
143
 * @var array
144
 */
145
        public $posts_tags = array(
146
                'post_id' => array('type' => 'integer', 'null' => false, 'key' => 'primary'),
147
                'tag_id' => array('type' => 'string', 'null' => false, 'key' => 'primary'),
148
                'indexes' => array('posts_tag' => array('column' => array('tag_id', 'post_id'), 'unique' => 1)),
149
                'tableParameters' => array()
150
        );
151

    
152
/**
153
 * tags property
154
 *
155
 * @var array
156
 */
157
        public $tags = array(
158
                'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
159
                'tag' => array('type' => 'string', 'null' => false),
160
                'created' => array('type' => 'datetime', 'null' => true, 'default' => null),
161
                'updated' => array('type' => 'datetime', 'null' => true, 'default' => null),
162
                'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)),
163
                'tableParameters' => array()
164
        );
165

    
166
/**
167
 * datatypes property
168
 *
169
 * @var array
170
 */
171
        public $datatypes = array(
172
                'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
173
                'float_field' => array('type' => 'float', 'null' => false, 'length' => '5,2', 'default' => ''),
174
                'decimal_field' => array('type' => 'decimal', 'length' => '6,3', 'default' => '0.000'),
175
                'huge_int' => array('type' => 'biginteger'),
176
                'bool' => array('type' => 'boolean', 'null' => false, 'default' => false),
177
                'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)),
178
                'tableParameters' => array()
179
        );
180

    
181
/**
182
 * setup method
183
 *
184
 * @param mixed $version
185
 * @return void
186
 */
187
        public function setup($version) {
188
        }
189

    
190
/**
191
 * teardown method
192
 *
193
 * @param mixed $version
194
 * @return void
195
 */
196
        public function teardown($version) {
197
        }
198

    
199
}
200

    
201
/**
202
 * SchemaPost class
203
 *
204
 * @package       Cake.Test.Case.Model
205
 */
206
class SchemaPost extends CakeTestModel {
207

    
208
/**
209
 * useTable property
210
 *
211
 * @var string
212
 */
213
        public $useTable = 'posts';
214

    
215
/**
216
 * hasMany property
217
 *
218
 * @var array
219
 */
220
        public $hasMany = array('SchemaComment');
221

    
222
/**
223
 * hasAndBelongsToMany property
224
 *
225
 * @var array
226
 */
227
        public $hasAndBelongsToMany = array('SchemaTag');
228
}
229

    
230
/**
231
 * SchemaComment class
232
 *
233
 * @package       Cake.Test.Case.Model
234
 */
235
class SchemaComment extends CakeTestModel {
236

    
237
/**
238
 * useTable property
239
 *
240
 * @var string
241
 */
242
        public $useTable = 'comments';
243

    
244
/**
245
 * belongsTo property
246
 *
247
 * @var array
248
 */
249
        public $belongsTo = array('SchemaPost');
250
}
251

    
252
/**
253
 * SchemaTag class
254
 *
255
 * @package       Cake.Test.Case.Model
256
 */
257
class SchemaTag extends CakeTestModel {
258

    
259
/**
260
 * useTable property
261
 *
262
 * @var string
263
 */
264
        public $useTable = 'tags';
265

    
266
/**
267
 * hasAndBelongsToMany property
268
 *
269
 * @var array
270
 */
271
        public $hasAndBelongsToMany = array('SchemaPost');
272
}
273

    
274
/**
275
 * SchemaDatatype class
276
 *
277
 * @package       Cake.Test.Case.Model
278
 */
279
class SchemaDatatype extends CakeTestModel {
280

    
281
/**
282
 * useTable property
283
 *
284
 * @var string
285
 */
286
        public $useTable = 'datatypes';
287
}
288

    
289
/**
290
 * Testdescribe class
291
 *
292
 * This class is defined purely to inherit the cacheSources variable otherwise
293
 * testSchemaCreateTable will fail if listSources has already been called and
294
 * its source cache populated - I.e. if the test is run within a group
295
 *
296
 * @uses          CakeTestModel
297
 * @package       Cake.Test.Case.Model
298
 */
299
class Testdescribe extends CakeTestModel {
300
}
301

    
302
/**
303
 * SchemaCrossDatabase class
304
 *
305
 * @package       Cake.Test.Case.Model
306
 */
307
class SchemaCrossDatabase extends CakeTestModel {
308

    
309
/**
310
 * useTable property
311
 *
312
 * @var string
313
 */
314
        public $useTable = 'cross_database';
315

    
316
/**
317
 * useDbConfig property
318
 *
319
 * @var string
320
 */
321
        public $useDbConfig = 'test2';
322
}
323

    
324
/**
325
 * SchemaCrossDatabaseFixture class
326
 *
327
 * @package       Cake.Test.Case.Model
328
 */
329
class SchemaCrossDatabaseFixture extends CakeTestFixture {
330

    
331
/**
332
 * name property
333
 *
334
 * @var string
335
 */
336
        public $name = 'CrossDatabase';
337

    
338
/**
339
 * table property
340
 *
341
 * @var string
342
 */
343
        public $table = 'cross_database';
344

    
345
/**
346
 * fields property
347
 *
348
 * @var array
349
 */
350
        public $fields = array(
351
                'id' => array('type' => 'integer', 'key' => 'primary'),
352
                'name' => 'string'
353
        );
354

    
355
/**
356
 * records property
357
 *
358
 * @var array
359
 */
360
        public $records = array(
361
                array('id' => 1, 'name' => 'First'),
362
                array('id' => 2, 'name' => 'Second'),
363
        );
364
}
365

    
366
/**
367
 * SchemaPrefixAuthUser class
368
 *
369
 * @package       Cake.Test.Case.Model
370
 */
371
class SchemaPrefixAuthUser extends CakeTestModel {
372

    
373
/**
374
 * table prefix
375
 *
376
 * @var string
377
 */
378
        public $tablePrefix = 'auth_';
379

    
380
/**
381
 * useTable
382
 *
383
 * @var string
384
 */
385
        public $useTable = 'users';
386
}
387

    
388
/**
389
 * CakeSchemaTest
390
 *
391
 * @package       Cake.Test.Case.Model
392
 */
393
class CakeSchemaTest extends CakeTestCase {
394

    
395
/**
396
 * fixtures property
397
 *
398
 * @var array
399
 */
400
        public $fixtures = array(
401
                'core.post', 'core.tag', 'core.posts_tag', 'core.test_plugin_comment',
402
                'core.datatype', 'core.auth_user', 'core.author',
403
                'core.test_plugin_article', 'core.user', 'core.comment',
404
                'core.prefix_test'
405
        );
406

    
407
/**
408
 * setUp method
409
 *
410
 * @return void
411
 */
412
        public function setUp() {
413
                parent::setUp();
414
                ConnectionManager::getDataSource('test')->cacheSources = false;
415
                $this->Schema = new TestAppSchema();
416
        }
417

    
418
/**
419
 * tearDown method
420
 *
421
 * @return void
422
 */
423
        public function tearDown() {
424
                parent::tearDown();
425
                if (file_exists(TMP . 'tests' . DS . 'schema.php')) {
426
                        unlink(TMP . 'tests' . DS . 'schema.php');
427
                }
428
                unset($this->Schema);
429
                CakePlugin::unload();
430
        }
431

    
432
/**
433
 * testSchemaName method
434
 *
435
 * @return void
436
 */
437
        public function testSchemaName() {
438
                $Schema = new CakeSchema();
439
                $this->assertEquals('App', $Schema->name);
440
        }
441

    
442
/**
443
 * testSchemaRead method
444
 *
445
 * @return void
446
 */
447
        public function testSchemaRead() {
448
                $read = $this->Schema->read(array(
449
                        'connection' => 'test',
450
                        'name' => 'TestApp',
451
                        'models' => array('SchemaPost', 'SchemaComment', 'SchemaTag', 'SchemaDatatype')
452
                ));
453
                unset($read['tables']['missing']);
454

    
455
                $expected = array('comments', 'datatypes', 'posts', 'posts_tags', 'tags');
456
                foreach ($expected as $table) {
457
                        $this->assertTrue(isset($read['tables'][$table]), 'Missing table ' . $table);
458
                }
459
                foreach ($this->Schema->tables as $table => $fields) {
460
                        $this->assertEquals(array_keys($fields), array_keys($read['tables'][$table]));
461
                }
462

    
463
                if (isset($read['tables']['datatypes']['float_field']['length'])) {
464
                        $this->assertEquals(
465
                                $read['tables']['datatypes']['float_field']['length'],
466
                                $this->Schema->tables['datatypes']['float_field']['length']
467
                        );
468
                }
469

    
470
                $this->assertEquals(
471
                        $read['tables']['datatypes']['float_field']['type'],
472
                        $this->Schema->tables['datatypes']['float_field']['type']
473
                );
474

    
475
                $this->assertEquals(
476
                        $read['tables']['datatypes']['float_field']['null'],
477
                        $this->Schema->tables['datatypes']['float_field']['null']
478
                );
479

    
480
                $db = ConnectionManager::getDataSource('test');
481
                $config = $db->config;
482
                $config['prefix'] = 'schema_test_prefix_';
483
                ConnectionManager::create('schema_prefix', $config);
484
                $read = $this->Schema->read(array('connection' => 'schema_prefix', 'models' => false));
485
                $this->assertTrue(empty($read['tables']));
486

    
487
                $read = $this->Schema->read(array(
488
                        'connection' => 'test',
489
                        'name' => 'TestApp',
490
                        'models' => array('SchemaComment', 'SchemaTag', 'SchemaPost')
491
                ));
492
                $this->assertFalse(isset($read['tables']['missing']['posts_tags']), 'Join table marked as missing');
493
        }
494

    
495
/**
496
 * testSchemaReadWithAppModel method
497
 *
498
 * @return void
499
 */
500
        public function testSchemaReadWithAppModel() {
501
                $connections = ConnectionManager::enumConnectionObjects();
502
                ConnectionManager::drop('default');
503
                ConnectionManager::create('default', $connections['test']);
504
                try {
505
                        $this->Schema->read(array(
506
                                'connection' => 'default',
507
                                'name' => 'TestApp',
508
                                'models' => array('AppModel')
509
                        ));
510
                } catch(MissingTableException $mte) {
511
                        ConnectionManager::drop('default');
512
                        $this->fail($mte->getMessage());
513
                }
514
                ConnectionManager::drop('default');
515
        }
516

    
517
/**
518
 * testSchemaReadWithOddTablePrefix method
519
 *
520
 * @return void
521
 */
522
        public function testSchemaReadWithOddTablePrefix() {
523
                $config = ConnectionManager::getDataSource('test')->config;
524
                $this->skipIf(!empty($config['prefix']), 'This test can not be executed with datasource prefix set.');
525

    
526
                $SchemaPost = ClassRegistry::init('SchemaPost');
527
                $SchemaPost->tablePrefix = 'po';
528
                $SchemaPost->useTable = 'sts';
529
                $read = $this->Schema->read(array(
530
                        'connection' => 'test',
531
                        'name' => 'TestApp',
532
                        'models' => array('SchemaPost')
533
                ));
534

    
535
                $this->assertFalse(isset($read['tables']['missing']['posts']), 'Posts table was not read from tablePrefix');
536
        }
537

    
538
/**
539
 * test read() with tablePrefix properties.
540
 *
541
 * @return void
542
 */
543
        public function testSchemaReadWithTablePrefix() {
544
                $config = ConnectionManager::getDataSource('test')->config;
545
                $this->skipIf(!empty($config['prefix']), 'This test can not be executed with datasource prefix set.');
546

    
547
                $Schema = new CakeSchema();
548
                $read = $Schema->read(array(
549
                        'connection' => 'test',
550
                        'name' => 'TestApp',
551
                        'models' => array('SchemaPrefixAuthUser')
552
                ));
553
                unset($read['tables']['missing']);
554
                $this->assertTrue(isset($read['tables']['auth_users']), 'auth_users key missing %s');
555
        }
556

    
557
/**
558
 * test reading schema with config prefix.
559
 *
560
 * @return void
561
 */
562
        public function testSchemaReadWithConfigPrefix() {
563
                $this->skipIf($this->db instanceof Sqlite, 'Cannot open 2 connections to Sqlite');
564

    
565
                $db = ConnectionManager::getDataSource('test');
566
                $config = $db->config;
567
                $this->skipIf(!empty($config['prefix']), 'This test can not be executed with datasource prefix set.');
568

    
569
                $config['prefix'] = 'schema_test_prefix_';
570
                ConnectionManager::create('schema_prefix', $config);
571
                $read = $this->Schema->read(array('connection' => 'schema_prefix', 'models' => false));
572
                $this->assertTrue(empty($read['tables']));
573

    
574
                $config['prefix'] = 'prefix_';
575
                ConnectionManager::create('schema_prefix2', $config);
576
                $read = $this->Schema->read(array(
577
                        'connection' => 'schema_prefix2',
578
                        'name' => 'TestApp',
579
                        'models' => false));
580
                $this->assertTrue(isset($read['tables']['prefix_tests']));
581
        }
582

    
583
/**
584
 * test reading schema from plugins.
585
 *
586
 * @return void
587
 */
588
        public function testSchemaReadWithPlugins() {
589
                App::objects('model', null, false);
590
                App::build(array(
591
                        'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
592
                ));
593
                CakePlugin::load('TestPlugin');
594

    
595
                $Schema = new CakeSchema();
596
                $Schema->plugin = 'TestPlugin';
597
                $read = $Schema->read(array(
598
                        'connection' => 'test',
599
                        'name' => 'TestApp',
600
                        'models' => true
601
                ));
602
                unset($read['tables']['missing']);
603
                $this->assertTrue(isset($read['tables']['auth_users']));
604
                $this->assertTrue(isset($read['tables']['authors']));
605
                $this->assertTrue(isset($read['tables']['test_plugin_comments']));
606
                $this->assertTrue(isset($read['tables']['posts']));
607
                $this->assertTrue(count($read['tables']) >= 4);
608

    
609
                App::build();
610
        }
611

    
612
/**
613
 * test reading schema with tables from another database.
614
 *
615
 * @return void
616
 */
617
        public function testSchemaReadWithCrossDatabase() {
618
                $config = ConnectionManager::enumConnectionObjects();
619
                $this->skipIf(
620
                        !isset($config['test']) || !isset($config['test2']),
621
                        'Primary and secondary test databases not configured, ' .
622
                        'skipping cross-database join tests. ' .
623
                        'To run these tests, you must define $test and $test2 in your database configuration.'
624
                );
625

    
626
                $db = ConnectionManager::getDataSource('test2');
627
                $fixture = new SchemaCrossDatabaseFixture();
628
                $fixture->create($db);
629
                $fixture->insert($db);
630

    
631
                $read = $this->Schema->read(array(
632
                        'connection' => 'test',
633
                        'name' => 'TestApp',
634
                        'models' => array('SchemaCrossDatabase', 'SchemaPost')
635
                ));
636
                $this->assertTrue(isset($read['tables']['posts']));
637
                $this->assertFalse(isset($read['tables']['cross_database']), 'Cross database should not appear');
638
                $this->assertFalse(isset($read['tables']['missing']['cross_database']), 'Cross database should not appear');
639

    
640
                $read = $this->Schema->read(array(
641
                        'connection' => 'test2',
642
                        'name' => 'TestApp',
643
                        'models' => array('SchemaCrossDatabase', 'SchemaPost')
644
                ));
645
                $this->assertFalse(isset($read['tables']['posts']), 'Posts should not appear');
646
                $this->assertFalse(isset($read['tables']['posts']), 'Posts should not appear');
647
                $this->assertTrue(isset($read['tables']['cross_database']));
648

    
649
                $fixture->drop($db);
650
        }
651

    
652
/**
653
 * test that tables are generated correctly
654
 *
655
 * @return void
656
 */
657
        public function testGenerateTable() {
658
                $posts = array(
659
                        'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
660
                        'author_id' => array('type' => 'integer', 'null' => false),
661
                        'title' => array('type' => 'string', 'null' => false),
662
                        'body' => array('type' => 'text', 'null' => true, 'default' => null),
663
                        'published' => array('type' => 'string', 'null' => true, 'default' => 'N', 'length' => 1),
664
                        'created' => array('type' => 'datetime', 'null' => true, 'default' => null),
665
                        'updated' => array('type' => 'datetime', 'null' => true, 'default' => null),
666
                        'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)),
667
                );
668
                $result = $this->Schema->generateTable('posts', $posts);
669
                $this->assertRegExp('/public \$posts/', $result);
670

    
671
                $posts = array(
672
                        'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
673
                        'author_id' => array('type' => 'integer', 'null' => false),
674
                        'title' => array('type' => 'string', 'null' => false),
675
                        'body' => array('type' => 'text', 'null' => true, 'default' => null),
676
                        'published' => array('type' => 'string', 'null' => true, 'default' => 'N', 'length' => 1),
677
                        'created' => array('type' => 'datetime', 'null' => true, 'default' => null),
678
                        'updated' => array('type' => 'datetime', 'null' => true, 'default' => null),
679
                        'indexes' => array(
680
                                'PRIMARY' => array('column' => 'id', 'unique' => true),
681
                                'MyFtIndex' => array('column' => array('title', 'body'), 'type' => 'fulltext')
682
                        )
683
                );
684
                $result = $this->Schema->generateTable('fields', $posts);
685
                $this->assertRegExp('/public \$fields/', $result);
686
                $this->assertRegExp('/\'type\' \=\> \'fulltext\'/', $result);
687
        }
688

    
689
/**
690
 * testSchemaWrite method
691
 *
692
 * @return void
693
 */
694
        public function testSchemaWrite() {
695
                $write = $this->Schema->write(array(
696
                        'name' => 'MyOtherApp',
697
                        'tables' => $this->Schema->tables,
698
                        'path' => TMP . 'tests'
699
                ));
700
                $file = file_get_contents(TMP . 'tests' . DS . 'schema.php');
701
                $this->assertEquals($write, $file);
702

    
703
                require_once TMP . 'tests' . DS . 'schema.php';
704
                $OtherSchema = new MyOtherAppSchema();
705
                $this->assertEquals($this->Schema->tables, $OtherSchema->tables);
706
        }
707

    
708
/**
709
 * testSchemaComparison method
710
 *
711
 * @return void
712
 */
713
        public function testSchemaComparison() {
714
                $New = new MyAppSchema();
715
                $compare = $New->compare($this->Schema);
716
                $expected = array(
717
                        'comments' => array(
718
                                'add' => array(
719
                                        'post_id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'after' => 'id'),
720
                                        'title' => array('type' => 'string', 'null' => false, 'length' => 100, 'after' => 'user_id'),
721
                                ),
722
                                'drop' => array(
723
                                        'article_id' => array('type' => 'integer', 'null' => false),
724
                                        'tableParameters' => array(),
725
                                ),
726
                                'change' => array(
727
                                        'comment' => array('type' => 'text', 'null' => false, 'default' => null),
728
                                )
729
                        ),
730
                        'posts' => array(
731
                                'add' => array(
732
                                        'summary' => array('type' => 'text', 'null' => true, 'after' => 'body'),
733
                                ),
734
                                'drop' => array(
735
                                        'tableParameters' => array(),
736
                                ),
737
                                'change' => array(
738
                                        'author_id' => array('type' => 'integer', 'null' => true, 'default' => ''),
739
                                        'title' => array('type' => 'string', 'null' => false, 'default' => 'Title'),
740
                                        'published' => array('type' => 'string', 'null' => true, 'default' => 'Y', 'length' => 1)
741
                                )
742
                        ),
743
                );
744
                $this->assertEquals($expected, $compare);
745
                $this->assertNull($New->getVar('comments'));
746
                $this->assertEquals(array('bar'), $New->getVar('_foo'));
747

    
748
                $tables = array(
749
                        'missing' => array(
750
                                'categories' => array(
751
                                        'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'key' => 'primary'),
752
                                        'created' => array('type' => 'datetime', 'null' => false, 'default' => null),
753
                                        'modified' => array('type' => 'datetime', 'null' => false, 'default' => null),
754
                                        'name' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 100),
755
                                        'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1)),
756
                                        'tableParameters' => array('charset' => 'latin1', 'collate' => 'latin1_swedish_ci', 'engine' => 'MyISAM')
757
                                )
758
                        ),
759
                        'ratings' => array(
760
                                'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'key' => 'primary'),
761
                                'foreign_key' => array('type' => 'integer', 'null' => false, 'default' => null),
762
                                'model' => array('type' => 'varchar', 'null' => false, 'default' => null),
763
                                'value' => array('type' => 'float', 'null' => false, 'length' => '5,2', 'default' => null),
764
                                'created' => array('type' => 'datetime', 'null' => false, 'default' => null),
765
                                'modified' => array('type' => 'datetime', 'null' => false, 'default' => null),
766
                                'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1)),
767
                                'tableParameters' => array('charset' => 'latin1', 'collate' => 'latin1_swedish_ci', 'engine' => 'MyISAM')
768
                        )
769
                );
770
                $compare = $New->compare($this->Schema, $tables);
771
                $expected = array(
772
                        'ratings' => array(
773
                                'create' => array(
774
                                        'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'key' => 'primary'),
775
                                        'foreign_key' => array('type' => 'integer', 'null' => false, 'default' => null),
776
                                        'model' => array('type' => 'varchar', 'null' => false, 'default' => null),
777
                                        'value' => array('type' => 'float', 'null' => false, 'length' => '5,2', 'default' => null),
778
                                        'created' => array('type' => 'datetime', 'null' => false, 'default' => null),
779
                                        'modified' => array('type' => 'datetime', 'null' => false, 'default' => null),
780
                                        'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1)),
781
                                        'tableParameters' => array('charset' => 'latin1', 'collate' => 'latin1_swedish_ci', 'engine' => 'MyISAM')
782
                                )
783
                        )
784
                );
785
                $this->assertEquals($expected, $compare);
786
        }
787

    
788
/**
789
 * test comparing '' and null and making sure they are different.
790
 *
791
 * @return void
792
 */
793
        public function testCompareEmptyStringAndNull() {
794
                $One = new CakeSchema(array(
795
                        'posts' => array(
796
                                'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'key' => 'primary'),
797
                                'name' => array('type' => 'string', 'null' => false, 'default' => '')
798
                        )
799
                ));
800
                $Two = new CakeSchema(array(
801
                        'posts' => array(
802
                                'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'key' => 'primary'),
803
                                'name' => array('type' => 'string', 'null' => false, 'default' => null)
804
                        )
805
                ));
806
                $compare = $One->compare($Two);
807
                $expected = array(
808
                        'posts' => array(
809
                                'change' => array(
810
                                        'name' => array('type' => 'string', 'null' => false, 'default' => null)
811
                                )
812
                        )
813
                );
814
                $this->assertEquals($expected, $compare);
815
        }
816

    
817
/**
818
 * Test comparing tableParameters and indexes.
819
 *
820
 * @return void
821
 */
822
        public function testTableParametersAndIndexComparison() {
823
                $old = array(
824
                        'posts' => array(
825
                                'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
826
                                'author_id' => array('type' => 'integer', 'null' => false),
827
                                'title' => array('type' => 'string', 'null' => false),
828
                                'indexes' => array(
829
                                        'PRIMARY' => array('column' => 'id', 'unique' => true)
830
                                ),
831
                                'tableParameters' => array(
832
                                        'charset' => 'latin1',
833
                                        'collate' => 'latin1_general_ci'
834
                                )
835
                        ),
836
                        'comments' => array(
837
                                'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
838
                                'post_id' => array('type' => 'integer', 'null' => false, 'default' => 0),
839
                                'comment' => array('type' => 'text'),
840
                                'indexes' => array(
841
                                        'PRIMARY' => array('column' => 'id', 'unique' => true),
842
                                        'post_id' => array('column' => 'post_id'),
843
                                ),
844
                                'tableParameters' => array(
845
                                        'engine' => 'InnoDB',
846
                                        'charset' => 'latin1',
847
                                        'collate' => 'latin1_general_ci'
848
                                )
849
                        )
850
                );
851
                $new = array(
852
                        'posts' => array(
853
                                'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
854
                                'author_id' => array('type' => 'integer', 'null' => false),
855
                                'title' => array('type' => 'string', 'null' => false),
856
                                'indexes' => array(
857
                                        'PRIMARY' => array('column' => 'id', 'unique' => true),
858
                                        'author_id' => array('column' => 'author_id'),
859
                                ),
860
                                'tableParameters' => array(
861
                                        'charset' => 'utf8',
862
                                        'collate' => 'utf8_general_ci',
863
                                        'engine' => 'MyISAM'
864
                                )
865
                        ),
866
                        'comments' => array(
867
                                'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
868
                                'post_id' => array('type' => 'integer', 'null' => false, 'default' => 0),
869
                                'comment' => array('type' => 'text'),
870
                                'indexes' => array(
871
                                        'PRIMARY' => array('column' => 'id', 'unique' => true),
872
                                ),
873
                                'tableParameters' => array(
874
                                        'charset' => 'utf8',
875
                                        'collate' => 'utf8_general_ci'
876
                                )
877
                        )
878
                );
879
                $compare = $this->Schema->compare($old, $new);
880
                $expected = array(
881
                        'posts' => array(
882
                                'add' => array(
883
                                        'indexes' => array('author_id' => array('column' => 'author_id')),
884
                                ),
885
                                'change' => array(
886
                                        'tableParameters' => array(
887
                                                'charset' => 'utf8',
888
                                                'collate' => 'utf8_general_ci',
889
                                                'engine' => 'MyISAM'
890
                                        )
891
                                )
892
                        ),
893
                        'comments' => array(
894
                                'drop' => array(
895
                                        'indexes' => array('post_id' => array('column' => 'post_id')),
896
                                ),
897
                                'change' => array(
898
                                        'tableParameters' => array(
899
                                                'charset' => 'utf8',
900
                                                'collate' => 'utf8_general_ci',
901
                                        )
902
                                )
903
                        )
904
                );
905
                $this->assertEquals($expected, $compare);
906
        }
907

    
908
/**
909
 * Test comparing with field changed from VARCHAR to DATETIME
910
 *
911
 * @return void
912
 */
913
        public function testCompareVarcharToDatetime() {
914
                $old = array(
915
                        'posts' => array(
916
                                'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
917
                                'author_id' => array('type' => 'integer', 'null' => false),
918
                                'title' => array('type' => 'string', 'null' => true, 'length' => 45),
919
                                'indexes' => array(
920
                                        'PRIMARY' => array('column' => 'id', 'unique' => true)
921
                                ),
922
                                'tableParameters' => array(
923
                                        'charset' => 'latin1',
924
                                        'collate' => 'latin1_general_ci'
925
                                )
926
                        ),
927
                );
928
                $new = array(
929
                        'posts' => array(
930
                                'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
931
                                'author_id' => array('type' => 'integer', 'null' => false),
932
                                'title' => array('type' => 'datetime', 'null' => false),
933
                                'indexes' => array(
934
                                        'PRIMARY' => array('column' => 'id', 'unique' => true)
935
                                ),
936
                                'tableParameters' => array(
937
                                        'charset' => 'latin1',
938
                                        'collate' => 'latin1_general_ci'
939
                                )
940
                        ),
941
                );
942
                $compare = $this->Schema->compare($old, $new);
943
                $expected = array(
944
                        'posts' => array(
945
                                'change' => array(
946
                                        'title' => array(
947
                                                'type' => 'datetime',
948
                                                'null' => false,
949
                                        )
950
                                )
951
                        ),
952
                );
953
                $this->assertEquals($expected, $compare, 'Invalid SQL, datetime does not have length');
954
        }
955

    
956
/**
957
 * testSchemaLoading method
958
 *
959
 * @return void
960
 */
961
        public function testSchemaLoading() {
962
                $Other = $this->Schema->load(array('name' => 'MyOtherApp', 'path' => TMP . 'tests'));
963
                $this->assertEquals('MyOtherApp', $Other->name);
964
                $this->assertEquals($Other->tables, $this->Schema->tables);
965
        }
966

    
967
/**
968
 * test loading schema files inside of plugins.
969
 *
970
 * @return void
971
 */
972
        public function testSchemaLoadingFromPlugin() {
973
                App::build(array(
974
                        'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
975
                ));
976
                CakePlugin::load('TestPlugin');
977
                $Other = $this->Schema->load(array('name' => 'TestPluginApp', 'plugin' => 'TestPlugin'));
978
                $this->assertEquals('TestPluginApp', $Other->name);
979
                $this->assertEquals(array('test_plugin_acos'), array_keys($Other->tables));
980

    
981
                App::build();
982
        }
983

    
984
/**
985
 * testSchemaCreateTable method
986
 *
987
 * @return void
988
 */
989
        public function testSchemaCreateTable() {
990
                $db = ConnectionManager::getDataSource('test');
991
                $db->cacheSources = false;
992

    
993
                $Schema = new CakeSchema(array(
994
                        'connection' => 'test',
995
                        'testdescribes' => array(
996
                                'id' => array('type' => 'integer', 'key' => 'primary'),
997
                                'int_null' => array('type' => 'integer', 'null' => true),
998
                                'int_not_null' => array('type' => 'integer', 'null' => false),
999
                        ),
1000
                ));
1001
                $sql = $db->createSchema($Schema);
1002

    
1003
                $col = $Schema->tables['testdescribes']['int_null'];
1004
                $col['name'] = 'int_null';
1005
                $column = $this->db->buildColumn($col);
1006
                $this->assertRegExp('/' . preg_quote($column, '/') . '/', $sql);
1007

    
1008
                $col = $Schema->tables['testdescribes']['int_not_null'];
1009
                $col['name'] = 'int_not_null';
1010
                $column = $this->db->buildColumn($col);
1011
                $this->assertRegExp('/' . preg_quote($column, '/') . '/', $sql);
1012
        }
1013
}