PageRenderTime 38ms CodeModel.GetById 10ms RepoModel.GetById 1ms app.codeStats 0ms

/cake/tests/cases/libs/model/datasources/dbo/dbo_postgres.test.php

https://github.com/hardsshah/bookmarks
PHP | 629 lines | 373 code | 30 blank | 226 comment | 3 complexity | de33a42ecb4bb3cf5057005db6c970de MD5 | raw file
  1. <?php
  2. /* SVN FILE: $Id$ */
  3. /**
  4. * DboPostgresTest file
  5. *
  6. * PHP versions 4 and 5
  7. *
  8. * CakePHP(tm) : Rapid Development Framework (http://www.cakephp.org)
  9. * Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
  10. *
  11. * Licensed under The MIT License
  12. * Redistributions of files must retain the above copyright notice.
  13. *
  14. * @filesource
  15. * @copyright Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
  16. * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
  17. * @package cake
  18. * @subpackage cake.cake.libs
  19. * @since CakePHP(tm) v 1.2.0
  20. * @version $Revision$
  21. * @modifiedby $LastChangedBy$
  22. * @lastmodified $Date$
  23. * @license http://www.opensource.org/licenses/mit-license.php The MIT License
  24. */
  25. App::import('Core', array('Model', 'DataSource', 'DboSource', 'DboPostgres'));
  26. App::import('Model', 'App');
  27. require_once dirname(dirname(dirname(__FILE__))) . DS . 'models.php';
  28. /**
  29. * DboPostgresTestDb class
  30. *
  31. * @package cake
  32. * @subpackage cake.tests.cases.libs.model.datasources
  33. */
  34. class DboPostgresTestDb extends DboPostgres {
  35. /**
  36. * simulated property
  37. *
  38. * @var array
  39. * @access public
  40. */
  41. var $simulated = array();
  42. /**
  43. * execute method
  44. *
  45. * @param mixed $sql
  46. * @access protected
  47. * @return void
  48. */
  49. function _execute($sql) {
  50. $this->simulated[] = $sql;
  51. return null;
  52. }
  53. /**
  54. * getLastQuery method
  55. *
  56. * @access public
  57. * @return void
  58. */
  59. function getLastQuery() {
  60. return $this->simulated[count($this->simulated) - 1];
  61. }
  62. }
  63. /**
  64. * PostgresTestModel class
  65. *
  66. * @package cake
  67. * @subpackage cake.tests.cases.libs.model.datasources
  68. */
  69. class PostgresTestModel extends Model {
  70. /**
  71. * name property
  72. *
  73. * @var string 'PostgresTestModel'
  74. * @access public
  75. */
  76. var $name = 'PostgresTestModel';
  77. /**
  78. * useTable property
  79. *
  80. * @var bool false
  81. * @access public
  82. */
  83. var $useTable = false;
  84. /**
  85. * find method
  86. *
  87. * @param mixed $conditions
  88. * @param mixed $fields
  89. * @param mixed $order
  90. * @param mixed $recursive
  91. * @access public
  92. * @return void
  93. */
  94. function find($conditions = null, $fields = null, $order = null, $recursive = null) {
  95. return $conditions;
  96. }
  97. /**
  98. * findAll method
  99. *
  100. * @param mixed $conditions
  101. * @param mixed $fields
  102. * @param mixed $order
  103. * @param mixed $recursive
  104. * @access public
  105. * @return void
  106. */
  107. function findAll($conditions = null, $fields = null, $order = null, $recursive = null) {
  108. return $conditions;
  109. }
  110. /**
  111. * schema method
  112. *
  113. * @access public
  114. * @return void
  115. */
  116. function schema() {
  117. return array(
  118. 'id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
  119. 'client_id' => array('type' => 'integer', 'null' => '', 'default' => '0', 'length' => '11'),
  120. 'name' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
  121. 'login' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
  122. 'passwd' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '255'),
  123. 'addr_1' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '255'),
  124. 'addr_2' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '25'),
  125. 'zip_code' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
  126. 'city' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
  127. 'country' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
  128. 'phone' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
  129. 'fax' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
  130. 'url' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '255'),
  131. 'email' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
  132. 'comments' => array('type' => 'text', 'null' => '1', 'default' => '', 'length' => ''),
  133. 'last_login'=> array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => ''),
  134. 'created' => array('type' => 'date', 'null' => '1', 'default' => '', 'length' => ''),
  135. 'updated' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null)
  136. );
  137. }
  138. }
  139. /**
  140. * DboPostgresTest class
  141. *
  142. * @package cake
  143. * @subpackage cake.tests.cases.libs.model.datasources.dbo
  144. */
  145. class DboPostgresTest extends CakeTestCase {
  146. /**
  147. * Do not automatically load fixtures for each test, they will be loaded manually
  148. * using CakeTestCase::loadFixtures
  149. *
  150. * @var boolean
  151. * @access public
  152. */
  153. var $autoFixtures = false;
  154. /**
  155. * Fixtures
  156. *
  157. * @var object
  158. * @access public
  159. */
  160. var $fixtures = array('core.user', 'core.binary_test', 'core.comment', 'core.article',
  161. 'core.tag', 'core.articles_tag', 'core.attachment', 'core.person', 'core.post', 'core.author');
  162. /**
  163. * Actual DB connection used in testing
  164. *
  165. * @var DboSource
  166. * @access public
  167. */
  168. var $db = null;
  169. /**
  170. * Simulated DB connection used in testing
  171. *
  172. * @var DboSource
  173. * @access public
  174. */
  175. var $db2 = null;
  176. /**
  177. * Skip if cannot connect to postgres
  178. *
  179. * @access public
  180. */
  181. function skip() {
  182. $this->_initDb();
  183. $this->skipif($this->db->config['driver'] != 'postgres', 'PostgreSQL connection not available');
  184. }
  185. /**
  186. * Set up test suite database connection
  187. *
  188. * @access public
  189. */
  190. function startTest() {
  191. $this->_initDb();
  192. }
  193. /**
  194. * Sets up a Dbo class instance for testing
  195. *
  196. * @access public
  197. */
  198. function setUp() {
  199. Configure::write('Cache.disable', true);
  200. $this->startTest();
  201. $this->db =& ConnectionManager::getDataSource('test_suite');
  202. $this->db2 = new DboPostgresTestDb($this->db->config, false);
  203. $this->model = new PostgresTestModel();
  204. }
  205. /**
  206. * Sets up a Dbo class instance for testing
  207. *
  208. * @access public
  209. */
  210. function tearDown() {
  211. Configure::write('Cache.disable', false);
  212. unset($this->db2);
  213. }
  214. /**
  215. * Test field and value quoting method
  216. *
  217. * @access public
  218. */
  219. function testQuoting() {
  220. $result = $this->db2->fields($this->model);
  221. $expected = array(
  222. '"PostgresTestModel"."id" AS "PostgresTestModel__id"',
  223. '"PostgresTestModel"."client_id" AS "PostgresTestModel__client_id"',
  224. '"PostgresTestModel"."name" AS "PostgresTestModel__name"',
  225. '"PostgresTestModel"."login" AS "PostgresTestModel__login"',
  226. '"PostgresTestModel"."passwd" AS "PostgresTestModel__passwd"',
  227. '"PostgresTestModel"."addr_1" AS "PostgresTestModel__addr_1"',
  228. '"PostgresTestModel"."addr_2" AS "PostgresTestModel__addr_2"',
  229. '"PostgresTestModel"."zip_code" AS "PostgresTestModel__zip_code"',
  230. '"PostgresTestModel"."city" AS "PostgresTestModel__city"',
  231. '"PostgresTestModel"."country" AS "PostgresTestModel__country"',
  232. '"PostgresTestModel"."phone" AS "PostgresTestModel__phone"',
  233. '"PostgresTestModel"."fax" AS "PostgresTestModel__fax"',
  234. '"PostgresTestModel"."url" AS "PostgresTestModel__url"',
  235. '"PostgresTestModel"."email" AS "PostgresTestModel__email"',
  236. '"PostgresTestModel"."comments" AS "PostgresTestModel__comments"',
  237. '"PostgresTestModel"."last_login" AS "PostgresTestModel__last_login"',
  238. '"PostgresTestModel"."created" AS "PostgresTestModel__created"',
  239. '"PostgresTestModel"."updated" AS "PostgresTestModel__updated"'
  240. );
  241. $this->assertEqual($result, $expected);
  242. $expected = "'1.2'";
  243. $result = $this->db2->value(1.2, 'float');
  244. $this->assertIdentical($expected, $result);
  245. $expected = "'1,2'";
  246. $result = $this->db2->value('1,2', 'float');
  247. $this->assertIdentical($expected, $result);
  248. }
  249. /**
  250. * testColumnParsing method
  251. *
  252. * @access public
  253. * @return void
  254. */
  255. function testColumnParsing() {
  256. $this->assertEqual($this->db2->column('text'), 'text');
  257. $this->assertEqual($this->db2->column('date'), 'date');
  258. $this->assertEqual($this->db2->column('boolean'), 'boolean');
  259. $this->assertEqual($this->db2->column('character varying'), 'string');
  260. $this->assertEqual($this->db2->column('time without time zone'), 'time');
  261. $this->assertEqual($this->db2->column('timestamp without time zone'), 'datetime');
  262. }
  263. /**
  264. * testValueQuoting method
  265. *
  266. * @access public
  267. * @return void
  268. */
  269. function testValueQuoting() {
  270. $this->assertEqual($this->db2->value('0', 'integer'), "'0'");
  271. $this->assertEqual($this->db2->value('', 'integer'), 'NULL');
  272. $this->assertEqual($this->db2->value('', 'float'), 'NULL');
  273. $this->assertEqual($this->db2->value('', 'integer', false), "DEFAULT");
  274. $this->assertEqual($this->db2->value('', 'float', false), "DEFAULT");
  275. $this->assertEqual($this->db2->value('0.0', 'float'), "'0.0'");
  276. $this->assertEqual($this->db2->value('t', 'boolean'), "TRUE");
  277. $this->assertEqual($this->db2->value('f', 'boolean'), "FALSE");
  278. $this->assertEqual($this->db2->value(true), "TRUE");
  279. $this->assertEqual($this->db2->value(false), "FALSE");
  280. $this->assertEqual($this->db2->value('t'), "'t'");
  281. $this->assertEqual($this->db2->value('f'), "'f'");
  282. $this->assertEqual($this->db2->value('true', 'boolean'), 'TRUE');
  283. $this->assertEqual($this->db2->value('false', 'boolean'), 'FALSE');
  284. $this->assertEqual($this->db2->value('', 'boolean'), 'FALSE');
  285. $this->assertEqual($this->db2->value(0, 'boolean'), 'FALSE');
  286. $this->assertEqual($this->db2->value(1, 'boolean'), 'TRUE');
  287. $this->assertEqual($this->db2->value('1', 'boolean'), 'TRUE');
  288. $this->assertEqual($this->db2->value(null, 'boolean'), "NULL");
  289. }
  290. /**
  291. * Tests that different Postgres boolean 'flavors' are properly returned as native PHP booleans
  292. *
  293. * @access public
  294. * @return void
  295. */
  296. function testBooleanNormalization() {
  297. $this->assertTrue($this->db2->boolean('t'));
  298. $this->assertTrue($this->db2->boolean('true'));
  299. $this->assertTrue($this->db2->boolean('TRUE'));
  300. $this->assertTrue($this->db2->boolean(true));
  301. $this->assertTrue($this->db2->boolean(1));
  302. $this->assertTrue($this->db2->boolean(" "));
  303. $this->assertFalse($this->db2->boolean('f'));
  304. $this->assertFalse($this->db2->boolean('false'));
  305. $this->assertFalse($this->db2->boolean('FALSE'));
  306. $this->assertFalse($this->db2->boolean(false));
  307. $this->assertFalse($this->db2->boolean(0));
  308. $this->assertFalse($this->db2->boolean(''));
  309. }
  310. /**
  311. * testLastInsertIdMultipleInsert method
  312. *
  313. * @access public
  314. * @return void
  315. */
  316. function testLastInsertIdMultipleInsert() {
  317. $db1 = ConnectionManager::getDataSource('test_suite');
  318. if (PHP5) {
  319. $db2 = clone $db1;
  320. } else {
  321. $db2 = $db1;
  322. }
  323. $db2->connect();
  324. $this->assertNotEqual($db1->connection, $db2->connection);
  325. $table = $db1->fullTableName('users', false);
  326. $password = '5f4dcc3b5aa765d61d8327deb882cf99';
  327. $db1->execute(
  328. "INSERT INTO {$table} (\"user\", password) VALUES ('mariano', '{$password}')"
  329. );
  330. $db2->execute("INSERT INTO {$table} (\"user\", password) VALUES ('hoge', '{$password}')");
  331. $this->assertEqual($db1->lastInsertId($table), 1);
  332. $this->assertEqual($db2->lastInsertId($table), 2);
  333. }
  334. /**
  335. * Tests that table lists and descriptions are scoped to the proper Postgres schema
  336. *
  337. * @access public
  338. * @return void
  339. */
  340. function testSchemaScoping() {
  341. $db1 =& ConnectionManager::getDataSource('test_suite');
  342. $db1->cacheSources = false;
  343. $db1->reconnect(array('persistent' => false));
  344. $db1->query('CREATE SCHEMA _scope_test');
  345. $db2 =& ConnectionManager::create(
  346. 'test_suite_2',
  347. array_merge($db1->config, array('driver' => 'postgres', 'schema' => '_scope_test'))
  348. );
  349. $db2->cacheSources = false;
  350. $db2->query('DROP SCHEMA _scope_test');
  351. }
  352. /**
  353. * Tests that column types without default lengths in $columns do not have length values
  354. * applied when generating schemas.
  355. *
  356. * @access public
  357. * @return void
  358. */
  359. function testColumnUseLength() {
  360. $result = array('name' => 'foo', 'type' => 'string', 'length' => 100, 'default' => 'FOO');
  361. $expected = '"foo" varchar(100) DEFAULT \'FOO\'';
  362. $this->assertEqual($this->db->buildColumn($result), $expected);
  363. $result = array('name' => 'foo', 'type' => 'text', 'length' => 100, 'default' => 'FOO');
  364. $expected = '"foo" text DEFAULT \'FOO\'';
  365. $this->assertEqual($this->db->buildColumn($result), $expected);
  366. }
  367. /**
  368. * Tests that binary data is escaped/unescaped properly on reads and writes
  369. *
  370. * @access public
  371. * @return void
  372. */
  373. function testBinaryDataIntegrity() {
  374. $data = '%PDF-1.3
  375. %ƒÂÚÂÎßÛ†–ƒ∆
  376. 4 0 obj
  377. << /Length 5 0 R /Filter /FlateDecode >>
  378. stream
  379. xÂľYMì€∆Ω„ƒ%)nĂŻ0ÂŻĂŽâ-ÂŤĂŠ]Q"πXµáÿ•Ip - P�V,]Ú#c˚ˇ‰ut¥†∏Ti9�Ü=”›Ø_˜4>à∑‚ÉpcĂŠ¢PxĂŚÂŽ2q\'
  380. 1UÂŞbU ᡒ+ö«√[ıµ⁄ão"R∑"HiGĂŚä€(å≠≈^Ãøsm?YlƒÃõªfi‹âšB&‚Î◊7’^¸°ĂˇË›?2¹Ø€œďŹu#ÂŽU√ˇúág¼C;ä")n})JÂşIÔ3ËSnÑÎ¥≤ıD∆¢∂Msx1ĂźèG˚±Œ™⁄>ÂśySĂŻufØ ˝¸?UπÃã√6flÌÚC=øK?˝…s 
  381. ˛§¯ˇ:-˜ò7€ÓFæ∂∑Õ˛∆“€™>ÄąlflëÅd«ÜQdI ›ÎB%W¿ΊıÉn~h vĂŞCS>ÂŤĂŠ˛(ØôK!€¡zB!√
  382. [œÜ"ûß ·iH¸[Àºæ∑¯¡L,ÀÚAlS∫ˆ=∫Œ≤cÄr&ˆÈ:√ÿ£˚È«4fl•À]vc›bÅôÿî=siXe4/¡p]ã]ôÆIœ™ Ωflà_ƒ‚G?«7 ùÿ ı¯K4ïIpV◊÷·\'éµóªÚæ>î
  383. ;›sĂş!2flÂŹF•/ˆ‘jÂŁ
  384. dw"IÊÜπ<ôÿˆ%IG1ytÛDflXg|Éòa§˜}C˛¿ÿe°G´Ú±jÍm~¿/∂hã<#-¥•ıùe87€t˜õ6w}´{æ
  385. €šĂŞâ€“ ∆¡ 6⁄\
  386. rAÀBĂšZ3aË‚r$G¡$Ăł0Ñ ßâUY4È™¡%ˆ‘Ÿ2rc<IĂľ-cĂŻ. 
  387. [ŒöâF€ Ă‰â€Ą+QglMÉîÉÄúÌ|¸#x7ÂĽÂŤMgVÎ-Gšâ€˘Â I?Á‘”Lzw∞pHů◊nefqCĂŽ.•¨∆ÿÛyÂĄ˙fb≤üŒœAëÕNq=´@ ’cQdÖúAÉIqùŸ˘+2&∏ Àù.…‚ƒœ3E’Oi—‰:>ͤĹ
  388. =Õec=ĂŤR˝”eĂą=<V$ì˙+x+¢ïÒÕ<Ă eWĂĽÂť–˚∫Õ §&ÂŁĂ  ]fPA´âtĂŤnöå∏◊ó „Ë@∆≠´ĂˇË˜}a_CI˚ŠyòHg,Ă´SSVĂŹBƒl4 L.ÈY…á,2∂íäÙ.$ó¸¤Ĺ¸*€óy
  389. π?G,ˆšÂˇĂ†ĂŽĂ§=^Vkvo¹ó{§ƒ2¹¨ÏüoÍD-ãÊ ó¼cVÙ\'™G~\'p¢%* ã˚÷
  390. ÂŞÂşnh˚ºO^∏…®[Ó“‚ÅfıÌ≥∫F!“(π∑T6`ÂŹtΩÆ0ĂŹÂťrTÎ`»Ñ«
  391. ]Ōp˝)=¿Ô0∆öV‡ˆ„ø~¯ÁÔ∏b*fc»‡Îı„Ú}∆“ˆ‚ˆŤĂœ†˙ˆ~<ÿ·Ù vĂŠ1‹pÂżTD∆ÔîÄ“úhˆ*Ú€îe)K –¨ĂšJ3Ÿ∞ã>ÊuNĂŞ°“√Ü ‹Ê9iÙ0˙AAEÍ ˙`∂£\'Ăťce•åƒX›ŸÁ´1SK{qdĂĄ"tÏ[wQ#SÂľBe∞∑µó…ÌV`B"Ñ≥„!è_Óφ-Âş*Âşú¿Ë0ˆeê∂´ë+HFj…‡zvHÓN|ÔLáÝù3ĂľÜ$z%sá…pÎóV38âs Çoµ•ß3†<9B¡¨Ý~¢3)ÂxóÿÁCÕòÆ ∫Í=ÿSπS;∆~±êÆTEp∑óÈ÷ÀuĂŹDHÈ $ÉõæÜjݧ"≤ÃONMÂŽRËíRr{ĂľS ∏Ê™opÂąW;”ˆŤkÔˇflTæ∑óflË” ÆC©Ô[≥◊ËšÂ¨hĂŞ"ÆbF?Ăş%h˙ˇ4xèÕ(Ăł2ÙáíM])Ñd|=fĂŤ-cI0ĂąL¢kÖêk‰Rƒ«ıÄWĂą8mO3∏&√æËXÂŻHĂł—ì]yF2»–˜ádàà‡‹Çο„≥7mÂŞHAS∑¶.;Œx(1}�_kdŠ.dç48M\'Ă ĂĄÂŞCp^KrĂ­<ɉXÓıĂŻl!Ì$N<ı∞BÂťG]…∂Ó¯>˛ÔbõÒπÀ•:Ă´O<j∂™œ%âÏ—>@È$pÖu‹Ê´-QqV ?V≥JÆÍqÛX8(lπï@zgÖ}Fe<ˇ‡Sñ“ÿ˜ê?6‡L∍Oß~Âľ�–?ËeäÚ®YîÕ =Ü=¢DÁu*GvBk;)LÂŹNÂŤĂŽ:flö∂≠ÇΩq„Ñm하Ë∂‚"û≥§:±≤i^ΩÑ!)WĹyŧôá„„áÒĂ´€™â‰ â€”„˘rĹ‚PdĂŞĂŁh˘ßHVç5ȂŹĂ§ĂŒĂ›§Ă–/M=gĂŤ¾¹ÿGĂť1coÔuñæ‘zÂŽ.õ∑7ÉÏÜÆ,°’€ ĂĂ‰ĂŒâˆ‚7e º® íˆ⁄◊øNWK”ÂYµ‚ñé;¾œgV-fl>ÂľtË¥áßN2 ÂŻÂśBaP-)eW.Ă Ă´t^∏1›C∑Ö?€ž&”5’4jvã–ªZ á+4% ´0€ŚÂťĂş^°´Š Ýiπ∑é®óܱÒÿ‰ïˆÌ–†â—ŠĂ†19rQ=Í|ı•rMĂŚÂŹ;ò‰€°ĂŠ9.” ‹˝V«ã¯∏,+ĂŤÂŽj*¥¡/';
  392. $model =& new AppModel(array('name' => 'BinaryTest', 'ds' => 'test_suite'));
  393. $model->save(compact('data'));
  394. $result = $model->find('first');
  395. $this->assertEqual($result['BinaryTest']['data'], $data);
  396. }
  397. /**
  398. * Tests the syntax of generated schema indexes
  399. *
  400. * @access public
  401. * @return void
  402. */
  403. function testSchemaIndexSyntax() {
  404. $schema = new CakeSchema();
  405. $schema->tables = array('i18n' => array(
  406. 'id' => array(
  407. 'type' => 'integer', 'null' => false, 'default' => null,
  408. 'length' => 10, 'key' => 'primary'
  409. ),
  410. 'locale' => array('type'=>'string', 'null' => false, 'length' => 6, 'key' => 'index'),
  411. 'model' => array('type'=>'string', 'null' => false, 'key' => 'index'),
  412. 'foreign_key' => array(
  413. 'type'=>'integer', 'null' => false, 'length' => 10, 'key' => 'index'
  414. ),
  415. 'field' => array('type'=>'string', 'null' => false, 'key' => 'index'),
  416. 'content' => array('type'=>'text', 'null' => true, 'default' => null),
  417. 'indexes' => array(
  418. 'PRIMARY' => array('column' => 'id', 'unique' => 1),
  419. 'locale' => array('column' => 'locale', 'unique' => 0),
  420. 'model' => array('column' => 'model', 'unique' => 0),
  421. 'row_id' => array('column' => 'foreign_key', 'unique' => 0),
  422. 'field' => array('column' => 'field', 'unique' => 0)
  423. )
  424. ));
  425. $result = $this->db->createSchema($schema);
  426. $this->assertNoPattern('/^CREATE INDEX(.+);,$/', $result);
  427. }
  428. /**
  429. * testCakeSchema method
  430. *
  431. * Test that schema generated postgresql queries are valid. ref #5696
  432. * Check that the create statement for a schema generated table is the same as the original sql
  433. *
  434. * @return void
  435. * @access public
  436. */
  437. function testCakeSchema() {
  438. $db1 =& ConnectionManager::getDataSource('test_suite');
  439. $db1->cacheSources = false;
  440. $db1->reconnect(array('persistent' => false));
  441. $db1->query('CREATE TABLE ' . $db1->fullTableName('datatypes') . ' (
  442. id serial NOT NULL,
  443. "varchar" character varying(40) NOT NULL,
  444. "timestamp" timestamp without time zone,
  445. date date,
  446. CONSTRAINT test_suite_data_types_pkey PRIMARY KEY (id)
  447. )');
  448. $model =& ClassRegistry::init('datatypes');
  449. $schema = new CakeSchema(array('connection' => 'test_suite'));
  450. $result = $schema->read(array('connection' => 'test_suite'));
  451. $schema->tables = $result['tables']['missing'];
  452. $result = $db1->createSchema($schema, 'datatypes');
  453. $this->assertNoPattern('/timestamp DEFAULT/', $result);
  454. $this->assertPattern('/timestamp\s*,/', $result);
  455. $db1->query('DROP TABLE ' . $db1->fullTableName('datatypes'));
  456. $db1->query($result);
  457. $result2 = $schema->read(array('connection' => 'test_suite'));
  458. $schema->tables = $result2['tables']['missing'];
  459. $result2 = $db1->createSchema($schema, 'datatypes');
  460. $this->assertEqual($result, $result2);
  461. $db1->query('DROP TABLE ' . $db1->fullTableName('datatypes'));
  462. }
  463. /**
  464. * Test index generation from table info.
  465. *
  466. * @return void
  467. **/
  468. function testIndexGeneration() {
  469. $name = $this->db->fullTableName('index_test', false);
  470. $this->db->query('CREATE TABLE ' . $name . ' ("id" serial NOT NULL PRIMARY KEY, "bool" integer, "small_char" varchar(50), "description" varchar(40) )');
  471. $this->db->query('CREATE INDEX pointless_bool ON ' . $name . '("bool")');
  472. $this->db->query('CREATE UNIQUE INDEX char_index ON ' . $name . '("small_char")');
  473. $expected = array(
  474. 'PRIMARY' => array('column' => 'id', 'unique' => 1),
  475. 'pointless_bool' => array('column' => 'bool', 'unique' => 0),
  476. 'char_index' => array('column' => 'small_char', 'unique' => 1),
  477. );
  478. $result = $this->db->index($name);
  479. $this->assertEqual($expected, $result);
  480. $this->db->query('DROP TABLE ' . $name);
  481. $name = $this->db->fullTableName('index_test_2', false);
  482. $this->db->query('CREATE TABLE ' . $name . ' ("id" serial NOT NULL PRIMARY KEY, "bool" integer, "small_char" varchar(50), "description" varchar(40) )');
  483. $this->db->query('CREATE UNIQUE INDEX multi_col ON ' . $name . '("small_char", "bool")');
  484. $expected = array(
  485. 'PRIMARY' => array('column' => 'id', 'unique' => 1),
  486. 'multi_col' => array('column' => array('small_char', 'bool'), 'unique' => 1),
  487. );
  488. $result = $this->db->index($name);
  489. $this->assertEqual($expected, $result);
  490. $this->db->query('DROP TABLE ' . $name);
  491. }
  492. /**
  493. * Test the alterSchema capabilities of postgres
  494. *
  495. * @access public
  496. * @return void
  497. */
  498. function testAlterSchema() {
  499. $Old =& new CakeSchema(array(
  500. 'connection' => 'test_suite',
  501. 'name' => 'AlterPosts',
  502. 'alter_posts' => array(
  503. 'id' => array('type' => 'integer', 'key' => 'primary'),
  504. 'author_id' => array('type' => 'integer', 'null' => false),
  505. 'title' => array('type' => 'string', 'null' => false),
  506. 'body' => array('type' => 'text'),
  507. 'published' => array('type' => 'string', 'length' => 1, 'default' => 'N'),
  508. 'created' => array('type' => 'datetime'),
  509. 'updated' => array('type' => 'datetime'),
  510. )
  511. ));
  512. $this->db->query($this->db->createSchema($Old));
  513. $New =& new CakeSchema(array(
  514. 'connection' => 'test_suite',
  515. 'name' => 'AlterPosts',
  516. 'alter_posts' => array(
  517. 'id' => array('type' => 'integer', 'key' => 'primary'),
  518. 'author_id' => array('type' => 'integer', 'null' => false),
  519. 'title' => array('type' => 'string', 'null' => false),
  520. 'body' => array('type' => 'string', 'length' => 500),
  521. 'status' => array('type' => 'integer', 'length' => 3),
  522. 'created' => array('type' => 'datetime'),
  523. 'updated' => array('type' => 'datetime'),
  524. )
  525. ));
  526. $this->db->query($this->db->alterSchema($New->compare($Old), 'alter_posts'));
  527. $model = new CakeTestModel(array('table' => 'alter_posts', 'ds' => 'test_suite'));
  528. $result = $model->schema();
  529. $this->assertTrue(isset($result['status']));
  530. $this->assertFalse(isset($result['published']));
  531. $this->assertEqual($result['body']['type'], 'string');
  532. $this->db->query($this->db->dropSchema($New));
  533. }
  534. /**
  535. * Test the alter index capabilities of postgres
  536. *
  537. * @access public
  538. * @return void
  539. */
  540. function testAlterIndexes() {
  541. $this->db->cacheSources = false;
  542. $schema1 =& new CakeSchema(array(
  543. 'name' => 'AlterTest1',
  544. 'connection' => 'test_suite',
  545. 'altertest' => array(
  546. 'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
  547. 'name' => array('type' => 'string', 'null' => false, 'length' => 50),
  548. 'group1' => array('type' => 'integer', 'null' => true),
  549. 'group2' => array('type' => 'integer', 'null' => true)
  550. )
  551. ));
  552. $this->db->query($this->db->createSchema($schema1));
  553. $schema2 =& new CakeSchema(array(
  554. 'name' => 'AlterTest2',
  555. 'connection' => 'test_suite',
  556. 'altertest' => array(
  557. 'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
  558. 'name' => array('type' => 'string', 'null' => false, 'length' => 50),
  559. 'group1' => array('type' => 'integer', 'null' => true),
  560. 'group2' => array('type' => 'integer', 'null' => true),
  561. 'indexes' => array(
  562. 'name_idx' => array('column' => 'name', 'unique' => 0),
  563. 'group_idx' => array('column' => 'group1', 'unique' => 0),
  564. 'compound_idx' => array('column' => array('group1', 'group2'), 'unique' => 0),
  565. 'PRIMARY' => array('column' => 'id', 'unique' => 1)
  566. )
  567. )
  568. ));
  569. $this->db->query($this->db->alterSchema($schema2->compare($schema1)));
  570. $indexes = $this->db->index('altertest');
  571. $this->assertEqual($schema2->tables['altertest']['indexes'], $indexes);
  572. // Change three indexes, delete one and add another one
  573. $schema3 =& new CakeSchema(array(
  574. 'name' => 'AlterTest3',
  575. 'connection' => 'test_suite',
  576. 'altertest' => array(
  577. 'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
  578. 'name' => array('type' => 'string', 'null' => false, 'length' => 50),
  579. 'group1' => array('type' => 'integer', 'null' => true),
  580. 'group2' => array('type' => 'integer', 'null' => true),
  581. 'indexes' => array(
  582. 'name_idx' => array('column' => 'name', 'unique' => 1),
  583. 'group_idx' => array('column' => 'group2', 'unique' => 0),
  584. 'compound_idx' => array('column' => array('group2', 'group1'), 'unique' => 0),
  585. 'another_idx' => array('column' => array('group1', 'name'), 'unique' => 0))
  586. )));
  587. $this->db->query($this->db->alterSchema($schema3->compare($schema2)));
  588. $indexes = $this->db->index('altertest');
  589. $this->assertEqual($schema3->tables['altertest']['indexes'], $indexes);
  590. // Compare us to ourself.
  591. $this->assertEqual($schema3->compare($schema3), array());
  592. // Drop the indexes
  593. $this->db->query($this->db->alterSchema($schema1->compare($schema3)));
  594. $indexes = $this->db->index('altertest');
  595. $this->assertEqual(array(), $indexes);
  596. $this->db->query($this->db->dropSchema($schema1));
  597. }
  598. }
  599. ?>