CakeSchemaTest.php 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018
  1. <?php
  2. /**
  3. * Test for Schema database management
  4. *
  5. *
  6. * PHP 5
  7. *
  8. * CakePHP(tm) Tests <http://book.cakephp.org/view/1196/Testing>
  9. * Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
  10. *
  11. * Licensed under The MIT License
  12. * Redistributions of files must retain the above copyright notice
  13. *
  14. * @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
  15. * @link http://book.cakephp.org/view/1196/Testing CakePHP(tm) Tests
  16. * @package Cake.Test.Case.Model
  17. * @since CakePHP(tm) v 1.2.0.5550
  18. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  19. */
  20. App::uses('CakeSchema', 'Model');
  21. App::uses('CakeTestFixture', 'TestSuite/Fixture');
  22. /**
  23. * Test for Schema database management
  24. *
  25. * @package Cake.Test.Case.Model
  26. */
  27. class MyAppSchema extends CakeSchema {
  28. /**
  29. * name property
  30. *
  31. * @var string 'MyApp'
  32. */
  33. public $name = 'MyApp';
  34. /**
  35. * connection property
  36. *
  37. * @var string 'test'
  38. */
  39. public $connection = 'test';
  40. /**
  41. * comments property
  42. *
  43. * @var array
  44. */
  45. public $comments = array(
  46. 'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
  47. 'post_id' => array('type' => 'integer', 'null' => false, 'default' => 0),
  48. 'user_id' => array('type' => 'integer', 'null' => false),
  49. 'title' => array('type' => 'string', 'null' => false, 'length' => 100),
  50. 'comment' => array('type' => 'text', 'null' => false, 'default' => null),
  51. 'published' => array('type' => 'string', 'null' => true, 'default' => 'N', 'length' => 1),
  52. 'created' => array('type' => 'datetime', 'null' => true, 'default' => null),
  53. 'updated' => array('type' => 'datetime', 'null' => true, 'default' => null),
  54. 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)),
  55. );
  56. /**
  57. * posts property
  58. *
  59. * @var array
  60. */
  61. public $posts = array(
  62. 'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
  63. 'author_id' => array('type' => 'integer', 'null' => true, 'default' => ''),
  64. 'title' => array('type' => 'string', 'null' => false, 'default' => 'Title'),
  65. 'body' => array('type' => 'text', 'null' => true, 'default' => null),
  66. 'summary' => array('type' => 'text', 'null' => true),
  67. 'published' => array('type' => 'string', 'null' => true, 'default' => 'Y', 'length' => 1),
  68. 'created' => array('type' => 'datetime', 'null' => true, 'default' => null),
  69. 'updated' => array('type' => 'datetime', 'null' => true, 'default' => null),
  70. 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)),
  71. );
  72. /**
  73. * _foo property
  74. *
  75. * @var array
  76. */
  77. protected $_foo = array('bar');
  78. /**
  79. * setup method
  80. *
  81. * @param mixed $version
  82. * @return void
  83. */
  84. public function setup($version) {
  85. }
  86. /**
  87. * teardown method
  88. *
  89. * @param mixed $version
  90. * @return void
  91. */
  92. public function teardown($version) {
  93. }
  94. /**
  95. * getVar method
  96. *
  97. * @param string $var Name of var
  98. * @return mixed
  99. */
  100. public function getVar($var) {
  101. if (!isset($this->$var)) {
  102. return null;
  103. }
  104. return $this->$var;
  105. }
  106. }
  107. /**
  108. * TestAppSchema class
  109. *
  110. * @package Cake.Test.Case.Model
  111. */
  112. class TestAppSchema extends CakeSchema {
  113. /**
  114. * name property
  115. *
  116. * @var string 'MyApp'
  117. */
  118. public $name = 'MyApp';
  119. /**
  120. * comments property
  121. *
  122. * @var array
  123. */
  124. public $comments = array(
  125. 'id' => array('type' => 'integer', 'null' => false, 'default' => 0,'key' => 'primary'),
  126. 'article_id' => array('type' => 'integer', 'null' => false),
  127. 'user_id' => array('type' => 'integer', 'null' => false),
  128. 'comment' => array('type' => 'text', 'null' => true, 'default' => null),
  129. 'published' => array('type' => 'string', 'null' => true, 'default' => 'N', 'length' => 1),
  130. 'created' => array('type' => 'datetime', 'null' => true, 'default' => null),
  131. 'updated' => array('type' => 'datetime', 'null' => true, 'default' => null),
  132. 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)),
  133. 'tableParameters' => array(),
  134. );
  135. /**
  136. * posts property
  137. *
  138. * @var array
  139. */
  140. public $posts = array(
  141. 'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
  142. 'author_id' => array('type' => 'integer', 'null' => false),
  143. 'title' => array('type' => 'string', 'null' => false),
  144. 'body' => array('type' => 'text', 'null' => true, 'default' => null),
  145. 'published' => array('type' => 'string', 'null' => true, 'default' => 'N', 'length' => 1),
  146. 'created' => array('type' => 'datetime', 'null' => true, 'default' => null),
  147. 'updated' => array('type' => 'datetime', 'null' => true, 'default' => null),
  148. 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)),
  149. 'tableParameters' => array(),
  150. );
  151. /**
  152. * posts_tags property
  153. *
  154. * @var array
  155. */
  156. public $posts_tags = array(
  157. 'post_id' => array('type' => 'integer', 'null' => false, 'key' => 'primary'),
  158. 'tag_id' => array('type' => 'string', 'null' => false, 'key' => 'primary'),
  159. 'indexes' => array('posts_tag' => array('column' => array('tag_id', 'post_id'), 'unique' => 1)),
  160. 'tableParameters' => array()
  161. );
  162. /**
  163. * tags property
  164. *
  165. * @var array
  166. */
  167. public $tags = array(
  168. 'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
  169. 'tag' => array('type' => 'string', 'null' => false),
  170. 'created' => array('type' => 'datetime', 'null' => true, 'default' => null),
  171. 'updated' => array('type' => 'datetime', 'null' => true, 'default' => null),
  172. 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)),
  173. 'tableParameters' => array()
  174. );
  175. /**
  176. * datatypes property
  177. *
  178. * @var array
  179. */
  180. public $datatypes = array(
  181. 'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
  182. 'float_field' => array('type' => 'float', 'null' => false, 'length' => '5,2', 'default' => ''),
  183. 'bool' => array('type' => 'boolean', 'null' => false, 'default' => false),
  184. 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)),
  185. 'tableParameters' => array()
  186. );
  187. /**
  188. * setup method
  189. *
  190. * @param mixed $version
  191. * @return void
  192. */
  193. public function setup($version) {
  194. }
  195. /**
  196. * teardown method
  197. *
  198. * @param mixed $version
  199. * @return void
  200. */
  201. public function teardown($version) {
  202. }
  203. }
  204. /**
  205. * SchmeaPost class
  206. *
  207. * @package Cake.Test.Case.Model
  208. */
  209. class SchemaPost extends CakeTestModel {
  210. /**
  211. * name property
  212. *
  213. * @var string 'SchemaPost'
  214. */
  215. public $name = 'SchemaPost';
  216. /**
  217. * useTable property
  218. *
  219. * @var string 'posts'
  220. */
  221. public $useTable = 'posts';
  222. /**
  223. * hasMany property
  224. *
  225. * @var array
  226. */
  227. public $hasMany = array('SchemaComment');
  228. /**
  229. * hasAndBelongsToMany property
  230. *
  231. * @var array
  232. */
  233. public $hasAndBelongsToMany = array('SchemaTag');
  234. }
  235. /**
  236. * SchemaComment class
  237. *
  238. * @package Cake.Test.Case.Model
  239. */
  240. class SchemaComment extends CakeTestModel {
  241. /**
  242. * name property
  243. *
  244. * @var string 'SchemaComment'
  245. */
  246. public $name = 'SchemaComment';
  247. /**
  248. * useTable property
  249. *
  250. * @var string 'comments'
  251. */
  252. public $useTable = 'comments';
  253. /**
  254. * belongsTo property
  255. *
  256. * @var array
  257. */
  258. public $belongsTo = array('SchemaPost');
  259. }
  260. /**
  261. * SchemaTag class
  262. *
  263. * @package Cake.Test.Case.Model
  264. */
  265. class SchemaTag extends CakeTestModel {
  266. /**
  267. * name property
  268. *
  269. * @var string 'SchemaTag'
  270. */
  271. public $name = 'SchemaTag';
  272. /**
  273. * useTable property
  274. *
  275. * @var string 'tags'
  276. */
  277. public $useTable = 'tags';
  278. /**
  279. * hasAndBelongsToMany property
  280. *
  281. * @var array
  282. */
  283. public $hasAndBelongsToMany = array('SchemaPost');
  284. }
  285. /**
  286. * SchemaDatatype class
  287. *
  288. * @package Cake.Test.Case.Model
  289. */
  290. class SchemaDatatype extends CakeTestModel {
  291. /**
  292. * name property
  293. *
  294. * @var string 'SchemaDatatype'
  295. */
  296. public $name = 'SchemaDatatype';
  297. /**
  298. * useTable property
  299. *
  300. * @var string 'datatypes'
  301. */
  302. public $useTable = 'datatypes';
  303. }
  304. /**
  305. * Testdescribe class
  306. *
  307. * This class is defined purely to inherit the cacheSources variable otherwise
  308. * testSchemaCreatTable will fail if listSources has already been called and
  309. * its source cache populated - I.e. if the test is run within a group
  310. *
  311. * @uses CakeTestModel
  312. * @package
  313. * @package Cake.Test.Case.Model
  314. */
  315. class Testdescribe extends CakeTestModel {
  316. /**
  317. * name property
  318. *
  319. * @var string 'Testdescribe'
  320. */
  321. public $name = 'Testdescribe';
  322. }
  323. /**
  324. * SchemaCrossDatabase class
  325. *
  326. * @package Cake.Test.Case.Model
  327. */
  328. class SchemaCrossDatabase extends CakeTestModel {
  329. /**
  330. * name property
  331. *
  332. * @var string 'SchemaCrossDatabase'
  333. */
  334. public $name = 'SchemaCrossDatabase';
  335. /**
  336. * useTable property
  337. *
  338. * @var string 'posts'
  339. */
  340. public $useTable = 'cross_database';
  341. /**
  342. * useDbConfig property
  343. *
  344. * @var string 'test2'
  345. */
  346. public $useDbConfig = 'test2';
  347. }
  348. /**
  349. * SchemaCrossDatabaseFixture class
  350. *
  351. * @package Cake.Test.Case.Model
  352. */
  353. class SchemaCrossDatabaseFixture extends CakeTestFixture {
  354. /**
  355. * name property
  356. *
  357. * @var string 'CrossDatabase'
  358. */
  359. public $name = 'CrossDatabase';
  360. /**
  361. * table property
  362. *
  363. */
  364. public $table = 'cross_database';
  365. /**
  366. * fields property
  367. *
  368. * @var array
  369. */
  370. public $fields = array(
  371. 'id' => array('type' => 'integer', 'key' => 'primary'),
  372. 'name' => 'string'
  373. );
  374. /**
  375. * records property
  376. *
  377. * @var array
  378. */
  379. public $records = array(
  380. array('id' => 1, 'name' => 'First'),
  381. array('id' => 2, 'name' => 'Second'),
  382. );
  383. }
  384. /**
  385. * SchemaPrefixAuthUser class
  386. *
  387. * @package Cake.Test.Case.Model
  388. */
  389. class SchemaPrefixAuthUser extends CakeTestModel {
  390. /**
  391. * name property
  392. *
  393. * @var string
  394. */
  395. public $name = 'SchemaPrefixAuthUser';
  396. /**
  397. * table prefix
  398. *
  399. * @var string
  400. */
  401. public $tablePrefix = 'auth_';
  402. /**
  403. * useTable
  404. *
  405. * @var string
  406. */
  407. public $useTable = 'users';
  408. }
  409. /**
  410. * CakeSchemaTest
  411. *
  412. * @package Cake.Test.Case.Model
  413. */
  414. class CakeSchemaTest extends CakeTestCase {
  415. /**
  416. * fixtures property
  417. *
  418. * @var array
  419. */
  420. public $fixtures = array(
  421. 'core.post', 'core.tag', 'core.posts_tag', 'core.test_plugin_comment',
  422. 'core.datatype', 'core.auth_user', 'core.author',
  423. 'core.test_plugin_article', 'core.user', 'core.comment',
  424. 'core.prefix_test'
  425. );
  426. /**
  427. * setUp method
  428. *
  429. * @return void
  430. */
  431. public function setUp() {
  432. parent::setUp();
  433. ConnectionManager::getDataSource('test')->cacheSources = false;
  434. $this->Schema = new TestAppSchema();
  435. }
  436. /**
  437. * tearDown method
  438. *
  439. * @return void
  440. */
  441. public function tearDown() {
  442. parent::tearDown();
  443. if (file_exists(TMP . 'tests' . DS .'schema.php')) {
  444. unlink(TMP . 'tests' . DS .'schema.php');
  445. }
  446. unset($this->Schema);
  447. CakePlugin::unload();
  448. }
  449. /**
  450. * testSchemaName method
  451. *
  452. * @return void
  453. */
  454. public function testSchemaName() {
  455. $Schema = new CakeSchema();
  456. $this->assertEqual(strtolower($Schema->name), strtolower(APP_DIR));
  457. Configure::write('App.dir', 'Some.name.with.dots');
  458. $Schema = new CakeSchema();
  459. $this->assertEqual($Schema->name, 'SomeNameWithDots');
  460. Configure::write('App.dir', 'app');
  461. }
  462. /**
  463. * testSchemaRead method
  464. *
  465. * @return void
  466. */
  467. public function testSchemaRead() {
  468. $read = $this->Schema->read(array(
  469. 'connection' => 'test',
  470. 'name' => 'TestApp',
  471. 'models' => array('SchemaPost', 'SchemaComment', 'SchemaTag', 'SchemaDatatype')
  472. ));
  473. unset($read['tables']['missing']);
  474. $expected = array('comments', 'datatypes', 'posts', 'posts_tags', 'tags');
  475. foreach ($expected as $table) {
  476. $this->assertTrue(isset($read['tables'][$table]), 'Missing table ' . $table);
  477. }
  478. foreach ($this->Schema->tables as $table => $fields) {
  479. $this->assertEqual(array_keys($fields), array_keys($read['tables'][$table]));
  480. }
  481. if (isset($read['tables']['datatypes']['float_field']['length'])) {
  482. $this->assertEqual(
  483. $read['tables']['datatypes']['float_field']['length'],
  484. $this->Schema->tables['datatypes']['float_field']['length']
  485. );
  486. }
  487. $this->assertEqual(
  488. $read['tables']['datatypes']['float_field']['type'],
  489. $this->Schema->tables['datatypes']['float_field']['type']
  490. );
  491. $this->assertEqual(
  492. $read['tables']['datatypes']['float_field']['null'],
  493. $this->Schema->tables['datatypes']['float_field']['null']
  494. );
  495. $db = ConnectionManager::getDataSource('test');
  496. $config = $db->config;
  497. $config['prefix'] = 'schema_test_prefix_';
  498. ConnectionManager::create('schema_prefix', $config);
  499. $read = $this->Schema->read(array('connection' => 'schema_prefix', 'models' => false));
  500. $this->assertTrue(empty($read['tables']));
  501. $read = $this->Schema->read(array(
  502. 'connection' => 'test',
  503. 'name' => 'TestApp',
  504. 'models' => array('SchemaComment', 'SchemaTag', 'SchemaPost')
  505. ));
  506. $this->assertFalse(isset($read['tables']['missing']['posts_tags']), 'Join table marked as missing');
  507. }
  508. /**
  509. * testSchemaReadWithAppModel method
  510. *
  511. * @access public
  512. * @return void
  513. */
  514. public function testSchemaReadWithAppModel() {
  515. $connections = ConnectionManager::enumConnectionObjects();
  516. ConnectionManager::drop('default');
  517. ConnectionManager::create('default', $connections['test']);
  518. try {
  519. $read = $this->Schema->read(array(
  520. 'connection' => 'default',
  521. 'name' => 'TestApp',
  522. 'models' => array('AppModel')
  523. ));
  524. } catch(MissingTableException $mte) {
  525. ConnectionManager::drop('default');
  526. $this->fail($mte->getMessage());
  527. }
  528. ConnectionManager::drop('default');
  529. }
  530. /**
  531. * testSchemaReadWithOddTablePrefix method
  532. *
  533. * @return void
  534. */
  535. public function testSchemaReadWithOddTablePrefix() {
  536. $config = ConnectionManager::getDataSource('test')->config;
  537. $this->skipIf(!empty($config['prefix']), 'This test can not be executed with datasource prefix set.');
  538. $SchemaPost = ClassRegistry::init('SchemaPost');
  539. $SchemaPost->tablePrefix = 'po';
  540. $SchemaPost->useTable = 'sts';
  541. $read = $this->Schema->read(array(
  542. 'connection' => 'test',
  543. 'name' => 'TestApp',
  544. 'models' => array('SchemaPost')
  545. ));
  546. $this->assertFalse(isset($read['tables']['missing']['posts']), 'Posts table was not read from tablePrefix');
  547. }
  548. /**
  549. * test read() with tablePrefix properties.
  550. *
  551. * @return void
  552. */
  553. public function testSchemaReadWithTablePrefix() {
  554. $config = ConnectionManager::getDataSource('test')->config;
  555. $this->skipIf(!empty($config['prefix']), 'This test can not be executed with datasource prefix set.');
  556. $model = new SchemaPrefixAuthUser();
  557. $Schema = new CakeSchema();
  558. $read = $Schema->read(array(
  559. 'connection' => 'test',
  560. 'name' => 'TestApp',
  561. 'models' => array('SchemaPrefixAuthUser')
  562. ));
  563. unset($read['tables']['missing']);
  564. $this->assertTrue(isset($read['tables']['auth_users']), 'auth_users key missing %s');
  565. }
  566. /**
  567. * test reading schema with config prefix.
  568. *
  569. * @return void
  570. */
  571. public function testSchemaReadWithConfigPrefix() {
  572. $this->skipIf($this->db instanceof Sqlite, 'Cannot open 2 connections to Sqlite');
  573. $db = ConnectionManager::getDataSource('test');
  574. $config = $db->config;
  575. $config['prefix'] = 'schema_test_prefix_';
  576. ConnectionManager::create('schema_prefix', $config);
  577. $read = $this->Schema->read(array('connection' => 'schema_prefix', 'models' => false));
  578. $this->assertTrue(empty($read['tables']));
  579. $config['prefix'] = 'prefix_';
  580. ConnectionManager::create('schema_prefix2', $config);
  581. $read = $this->Schema->read(array(
  582. 'connection' => 'schema_prefix2',
  583. 'name' => 'TestApp',
  584. 'models' => false));
  585. $this->assertTrue(isset($read['tables']['prefix_tests']));
  586. }
  587. /**
  588. * test reading schema from plugins.
  589. *
  590. * @return void
  591. */
  592. public function testSchemaReadWithPlugins() {
  593. App::objects('model', null, false);
  594. App::build(array(
  595. 'plugins' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
  596. ));
  597. CakePlugin::load('TestPlugin');
  598. $Schema = new CakeSchema();
  599. $Schema->plugin = 'TestPlugin';
  600. $read = $Schema->read(array(
  601. 'connection' => 'test',
  602. 'name' => 'TestApp',
  603. 'models' => true
  604. ));
  605. unset($read['tables']['missing']);
  606. $this->assertTrue(isset($read['tables']['auth_users']));
  607. $this->assertTrue(isset($read['tables']['authors']));
  608. $this->assertTrue(isset($read['tables']['test_plugin_comments']));
  609. $this->assertTrue(isset($read['tables']['posts']));
  610. $this->assertTrue(count($read['tables']) >= 4);
  611. App::build();
  612. }
  613. /**
  614. * test reading schema with tables from another database.
  615. *
  616. * @return void
  617. */
  618. public function testSchemaReadWithCrossDatabase() {
  619. $config = new DATABASE_CONFIG();
  620. $this->skipIf(
  621. !isset($config->test) || !isset($config->test2),
  622. 'Primary and secondary test databases not configured, skipping cross-database join tests.'
  623. . ' To run these tests, you must define $test and $test2 in your database configuration.'
  624. );
  625. $db2 = ConnectionManager::getDataSource('test2');
  626. $fixture = new SchemaCrossDatabaseFixture();
  627. $fixture->create($db2);
  628. $fixture->insert($db2);
  629. $read = $this->Schema->read(array(
  630. 'connection' => 'test',
  631. 'name' => 'TestApp',
  632. 'models' => array('SchemaCrossDatabase', 'SchemaPost')
  633. ));
  634. $this->assertTrue(isset($read['tables']['posts']));
  635. $this->assertFalse(isset($read['tables']['cross_database']), 'Cross database should not appear');
  636. $this->assertFalse(isset($read['tables']['missing']['cross_database']), 'Cross database should not appear');
  637. $read = $this->Schema->read(array(
  638. 'connection' => 'test2',
  639. 'name' => 'TestApp',
  640. 'models' => array('SchemaCrossDatabase', 'SchemaPost')
  641. ));
  642. $this->assertFalse(isset($read['tables']['posts']), 'Posts should not appear');
  643. $this->assertFalse(isset($read['tables']['posts']), 'Posts should not appear');
  644. $this->assertTrue(isset($read['tables']['cross_database']));
  645. $fixture->drop($db2);
  646. }
  647. /**
  648. * test that tables are generated correctly
  649. *
  650. * @return void
  651. */
  652. public function testGenerateTable() {
  653. $posts = array(
  654. 'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
  655. 'author_id' => array('type' => 'integer', 'null' => false),
  656. 'title' => array('type' => 'string', 'null' => false),
  657. 'body' => array('type' => 'text', 'null' => true, 'default' => null),
  658. 'published' => array('type' => 'string', 'null' => true, 'default' => 'N', 'length' => 1),
  659. 'created' => array('type' => 'datetime', 'null' => true, 'default' => null),
  660. 'updated' => array('type' => 'datetime', 'null' => true, 'default' => null),
  661. 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)),
  662. );
  663. $result = $this->Schema->generateTable('posts', $posts);
  664. $this->assertPattern('/var \$posts/', $result);
  665. }
  666. /**
  667. * testSchemaWrite method
  668. *
  669. * @return void
  670. */
  671. public function testSchemaWrite() {
  672. $write = $this->Schema->write(array('name' => 'MyOtherApp', 'tables' => $this->Schema->tables, 'path' => TMP . 'tests'));
  673. $file = file_get_contents(TMP . 'tests' . DS .'schema.php');
  674. $this->assertEqual($write, $file);
  675. require_once( TMP . 'tests' . DS .'schema.php');
  676. $OtherSchema = new MyOtherAppSchema();
  677. $this->assertEqual($this->Schema->tables, $OtherSchema->tables);
  678. }
  679. /**
  680. * testSchemaComparison method
  681. *
  682. * @return void
  683. */
  684. public function testSchemaComparison() {
  685. $New = new MyAppSchema();
  686. $compare = $New->compare($this->Schema);
  687. $expected = array(
  688. 'comments' => array(
  689. 'add' => array(
  690. 'post_id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'after' => 'id'),
  691. 'title' => array('type' => 'string', 'null' => false, 'length' => 100, 'after' => 'user_id'),
  692. ),
  693. 'drop' => array(
  694. 'article_id' => array('type' => 'integer', 'null' => false),
  695. 'tableParameters' => array(),
  696. ),
  697. 'change' => array(
  698. 'comment' => array('type' => 'text', 'null' => false, 'default' => null),
  699. )
  700. ),
  701. 'posts' => array(
  702. 'add' => array(
  703. 'summary' => array('type' => 'text', 'null' => true, 'after' => 'body'),
  704. ),
  705. 'drop' => array(
  706. 'tableParameters' => array(),
  707. ),
  708. 'change' => array(
  709. 'author_id' => array('type' => 'integer', 'null' => true, 'default' => ''),
  710. 'title' => array('type' => 'string', 'null' => false, 'default' => 'Title'),
  711. 'published' => array('type' => 'string', 'null' => true, 'default' => 'Y', 'length' => 1)
  712. )
  713. ),
  714. );
  715. $this->assertEqual($expected, $compare);
  716. $this->assertNull($New->getVar('comments'));
  717. $this->assertEqual($New->getVar('_foo'), array('bar'));
  718. $tables = array(
  719. 'missing' => array(
  720. 'categories' => array(
  721. 'id' => array('type' => 'integer', 'null' => false, 'default' => NULL, 'key' => 'primary'),
  722. 'created' => array('type' => 'datetime', 'null' => false, 'default' => NULL),
  723. 'modified' => array('type' => 'datetime', 'null' => false, 'default' => NULL),
  724. 'name' => array('type' => 'string', 'null' => false, 'default' => NULL, 'length' => 100),
  725. 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1)),
  726. 'tableParameters' => array('charset' => 'latin1', 'collate' => 'latin1_swedish_ci', 'engine' => 'MyISAM')
  727. )
  728. ),
  729. 'ratings' => array(
  730. 'id' => array('type' => 'integer', 'null' => false, 'default' => NULL, 'key' => 'primary'),
  731. 'foreign_key' => array('type' => 'integer', 'null' => false, 'default' => NULL),
  732. 'model' => array('type' => 'varchar', 'null' => false, 'default' => NULL),
  733. 'value' => array('type' => 'float', 'null' => false, 'length' => '5,2', 'default' => NULL),
  734. 'created' => array('type' => 'datetime', 'null' => false, 'default' => NULL),
  735. 'modified' => array('type' => 'datetime', 'null' => false, 'default' => NULL),
  736. 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1)),
  737. 'tableParameters' => array('charset' => 'latin1', 'collate' => 'latin1_swedish_ci', 'engine' => 'MyISAM')
  738. )
  739. );
  740. $compare = $New->compare($this->Schema, $tables);
  741. $expected = array(
  742. 'ratings' => array(
  743. 'add' => array(
  744. 'id' => array('type' => 'integer', 'null' => false, 'default' => NULL, 'key' => 'primary'),
  745. 'foreign_key' => array('type' => 'integer', 'null' => false, 'default' => NULL, 'after' => 'id'),
  746. 'model' => array('type' => 'varchar', 'null' => false, 'default' => NULL, 'after' => 'foreign_key'),
  747. 'value' => array('type' => 'float', 'null' => false, 'length' => '5,2', 'default' => NULL, 'after' => 'model'),
  748. 'created' => array('type' => 'datetime', 'null' => false, 'default' => NULL, 'after' => 'value'),
  749. 'modified' => array('type' => 'datetime', 'null' => false, 'default' => NULL, 'after' => 'created'),
  750. 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1)),
  751. 'tableParameters' => array('charset' => 'latin1', 'collate' => 'latin1_swedish_ci', 'engine' => 'MyISAM')
  752. )
  753. )
  754. );
  755. $this->assertEqual($expected, $compare);
  756. }
  757. /**
  758. * test comparing '' and null and making sure they are different.
  759. *
  760. * @return void
  761. */
  762. public function testCompareEmptyStringAndNull() {
  763. $One = new CakeSchema(array(
  764. 'posts' => array(
  765. 'id' => array('type' => 'integer', 'null' => false, 'default' => NULL, 'key' => 'primary'),
  766. 'name' => array('type' => 'string', 'null' => false, 'default' => '')
  767. )
  768. ));
  769. $Two = new CakeSchema(array(
  770. 'posts' => array(
  771. 'id' => array('type' => 'integer', 'null' => false, 'default' => NULL, 'key' => 'primary'),
  772. 'name' => array('type' => 'string', 'null' => false, 'default' => null)
  773. )
  774. ));
  775. $compare = $One->compare($Two);
  776. $expected = array(
  777. 'posts' => array(
  778. 'change' => array(
  779. 'name' => array('type' => 'string', 'null' => false, 'default' => null)
  780. )
  781. )
  782. );
  783. $this->assertEqual($expected, $compare);
  784. }
  785. /**
  786. * Test comparing tableParameters and indexes.
  787. *
  788. * @return void
  789. */
  790. public function testTableParametersAndIndexComparison() {
  791. $old = array(
  792. 'posts' => array(
  793. 'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
  794. 'author_id' => array('type' => 'integer', 'null' => false),
  795. 'title' => array('type' => 'string', 'null' => false),
  796. 'indexes' => array(
  797. 'PRIMARY' => array('column' => 'id', 'unique' => true)
  798. ),
  799. 'tableParameters' => array(
  800. 'charset' => 'latin1',
  801. 'collate' => 'latin1_general_ci'
  802. )
  803. ),
  804. 'comments' => array(
  805. 'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
  806. 'post_id' => array('type' => 'integer', 'null' => false, 'default' => 0),
  807. 'comment' => array('type' => 'text'),
  808. 'indexes' => array(
  809. 'PRIMARY' => array('column' => 'id', 'unique' => true),
  810. 'post_id' => array('column' => 'post_id'),
  811. ),
  812. 'tableParameters' => array(
  813. 'engine' => 'InnoDB',
  814. 'charset' => 'latin1',
  815. 'collate' => 'latin1_general_ci'
  816. )
  817. )
  818. );
  819. $new = array(
  820. 'posts' => array(
  821. 'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
  822. 'author_id' => array('type' => 'integer', 'null' => false),
  823. 'title' => array('type' => 'string', 'null' => false),
  824. 'indexes' => array(
  825. 'PRIMARY' => array('column' => 'id', 'unique' => true),
  826. 'author_id' => array('column' => 'author_id'),
  827. ),
  828. 'tableParameters' => array(
  829. 'charset' => 'utf8',
  830. 'collate' => 'utf8_general_ci',
  831. 'engine' => 'MyISAM'
  832. )
  833. ),
  834. 'comments' => array(
  835. 'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
  836. 'post_id' => array('type' => 'integer', 'null' => false, 'default' => 0),
  837. 'comment' => array('type' => 'text'),
  838. 'indexes' => array(
  839. 'PRIMARY' => array('column' => 'id', 'unique' => true),
  840. ),
  841. 'tableParameters' => array(
  842. 'charset' => 'utf8',
  843. 'collate' => 'utf8_general_ci'
  844. )
  845. )
  846. );
  847. $compare = $this->Schema->compare($old, $new);
  848. $expected = array(
  849. 'posts' => array(
  850. 'add' => array(
  851. 'indexes' => array('author_id' => array('column' => 'author_id')),
  852. ),
  853. 'change' => array(
  854. 'tableParameters' => array(
  855. 'charset' => 'utf8',
  856. 'collate' => 'utf8_general_ci',
  857. 'engine' => 'MyISAM'
  858. )
  859. )
  860. ),
  861. 'comments' => array(
  862. 'drop' => array(
  863. 'indexes' => array('post_id' => array('column' => 'post_id')),
  864. ),
  865. 'change' => array(
  866. 'tableParameters' => array(
  867. 'charset' => 'utf8',
  868. 'collate' => 'utf8_general_ci',
  869. )
  870. )
  871. )
  872. );
  873. $this->assertEquals($expected, $compare);
  874. }
  875. /**
  876. * testSchemaLoading method
  877. *
  878. * @return void
  879. */
  880. public function testSchemaLoading() {
  881. $Other = $this->Schema->load(array('name' => 'MyOtherApp', 'path' => TMP . 'tests'));
  882. $this->assertEqual($Other->name, 'MyOtherApp');
  883. $this->assertEqual($Other->tables, $this->Schema->tables);
  884. }
  885. /**
  886. * test loading schema files inside of plugins.
  887. *
  888. * @return void
  889. */
  890. public function testSchemaLoadingFromPlugin() {
  891. App::build(array(
  892. 'plugins' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
  893. ));
  894. CakePlugin::load('TestPlugin');
  895. $Other = $this->Schema->load(array('name' => 'TestPluginApp', 'plugin' => 'TestPlugin'));
  896. $this->assertEqual($Other->name, 'TestPluginApp');
  897. $this->assertEqual(array_keys($Other->tables), array('test_plugin_acos'));
  898. App::build();
  899. }
  900. /**
  901. * testSchemaCreateTable method
  902. *
  903. * @return void
  904. */
  905. public function testSchemaCreateTable() {
  906. $db = ConnectionManager::getDataSource('test');
  907. $db->cacheSources = false;
  908. $Schema = new CakeSchema(array(
  909. 'connection' => 'test',
  910. 'testdescribes' => array(
  911. 'id' => array('type' => 'integer', 'key' => 'primary'),
  912. 'int_null' => array('type' => 'integer', 'null' => true),
  913. 'int_not_null' => array('type' => 'integer', 'null' => false),
  914. ),
  915. ));
  916. $sql = $db->createSchema($Schema);
  917. $col = $Schema->tables['testdescribes']['int_null'];
  918. $col['name'] = 'int_null';
  919. $column = $this->db->buildColumn($col);
  920. $this->assertPattern('/' . preg_quote($column, '/') . '/', $sql);
  921. $col = $Schema->tables['testdescribes']['int_not_null'];
  922. $col['name'] = 'int_not_null';
  923. $column = $this->db->buildColumn($col);
  924. $this->assertPattern('/' . preg_quote($column, '/') . '/', $sql);
  925. }
  926. }