Mercurial > hg > Members > shoshi > webvirt
comparison cake/tests/cases/libs/model/datasources/dbo/dbo_postgres.test.php @ 0:261e66bd5a0c
hg init
author | Shoshi TAMAKI <shoshi@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Sun, 24 Jul 2011 21:08:31 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:261e66bd5a0c |
---|---|
1 <?php | |
2 /** | |
3 * DboPostgresTest file | |
4 * | |
5 * PHP versions 4 and 5 | |
6 * | |
7 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) | |
8 * Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org) | |
9 * | |
10 * Licensed under The MIT License | |
11 * Redistributions of files must retain the above copyright notice. | |
12 * | |
13 * @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org) | |
14 * @link http://cakephp.org CakePHP(tm) Project | |
15 * @package cake | |
16 * @subpackage cake.cake.libs | |
17 * @since CakePHP(tm) v 1.2.0 | |
18 * @license MIT License (http://www.opensource.org/licenses/mit-license.php) | |
19 */ | |
20 App::import('Core', array('Model', 'DataSource', 'DboSource', 'DboPostgres')); | |
21 App::import('Model', 'App'); | |
22 require_once dirname(dirname(dirname(__FILE__))) . DS . 'models.php'; | |
23 | |
24 /** | |
25 * DboPostgresTestDb class | |
26 * | |
27 * @package cake | |
28 * @subpackage cake.tests.cases.libs.model.datasources | |
29 */ | |
30 class DboPostgresTestDb extends DboPostgres { | |
31 | |
32 /** | |
33 * simulated property | |
34 * | |
35 * @var array | |
36 * @access public | |
37 */ | |
38 var $simulated = array(); | |
39 | |
40 /** | |
41 * execute method | |
42 * | |
43 * @param mixed $sql | |
44 * @access protected | |
45 * @return void | |
46 */ | |
47 function _execute($sql) { | |
48 $this->simulated[] = $sql; | |
49 return null; | |
50 } | |
51 | |
52 /** | |
53 * getLastQuery method | |
54 * | |
55 * @access public | |
56 * @return void | |
57 */ | |
58 function getLastQuery() { | |
59 return $this->simulated[count($this->simulated) - 1]; | |
60 } | |
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 /** | |
72 * name property | |
73 * | |
74 * @var string 'PostgresTestModel' | |
75 * @access public | |
76 */ | |
77 var $name = 'PostgresTestModel'; | |
78 | |
79 /** | |
80 * useTable property | |
81 * | |
82 * @var bool false | |
83 * @access public | |
84 */ | |
85 var $useTable = false; | |
86 | |
87 /** | |
88 * belongsTo property | |
89 * | |
90 * @var array | |
91 * @access public | |
92 */ | |
93 var $belongsTo = array( | |
94 'PostgresClientTestModel' => array( | |
95 'foreignKey' => 'client_id' | |
96 ) | |
97 ); | |
98 | |
99 /** | |
100 * find method | |
101 * | |
102 * @param mixed $conditions | |
103 * @param mixed $fields | |
104 * @param mixed $order | |
105 * @param mixed $recursive | |
106 * @access public | |
107 * @return void | |
108 */ | |
109 function find($conditions = null, $fields = null, $order = null, $recursive = null) { | |
110 return $conditions; | |
111 } | |
112 | |
113 /** | |
114 * findAll method | |
115 * | |
116 * @param mixed $conditions | |
117 * @param mixed $fields | |
118 * @param mixed $order | |
119 * @param mixed $recursive | |
120 * @access public | |
121 * @return void | |
122 */ | |
123 function findAll($conditions = null, $fields = null, $order = null, $recursive = null) { | |
124 return $conditions; | |
125 } | |
126 | |
127 /** | |
128 * schema method | |
129 * | |
130 * @access public | |
131 * @return void | |
132 */ | |
133 function schema() { | |
134 return array( | |
135 'id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'), | |
136 'client_id' => array('type' => 'integer', 'null' => '', 'default' => '0', 'length' => '11'), | |
137 'name' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'), | |
138 'login' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'), | |
139 'passwd' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '255'), | |
140 'addr_1' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '255'), | |
141 'addr_2' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '25'), | |
142 'zip_code' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'), | |
143 'city' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'), | |
144 'country' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'), | |
145 'phone' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'), | |
146 'fax' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'), | |
147 'url' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '255'), | |
148 'email' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'), | |
149 'comments' => array('type' => 'text', 'null' => '1', 'default' => '', 'length' => ''), | |
150 'last_login'=> array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => ''), | |
151 'created' => array('type' => 'date', 'null' => '1', 'default' => '', 'length' => ''), | |
152 'updated' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null) | |
153 ); | |
154 } | |
155 } | |
156 | |
157 /** | |
158 * PostgresClientTestModel class | |
159 * | |
160 * @package cake | |
161 * @subpackage cake.tests.cases.libs.model.datasources | |
162 */ | |
163 class PostgresClientTestModel extends Model { | |
164 | |
165 /** | |
166 * name property | |
167 * | |
168 * @var string 'PostgresClientTestModel' | |
169 * @access public | |
170 */ | |
171 var $name = 'PostgresClientTestModel'; | |
172 | |
173 /** | |
174 * useTable property | |
175 * | |
176 * @var bool false | |
177 * @access public | |
178 */ | |
179 var $useTable = false; | |
180 | |
181 /** | |
182 * schema method | |
183 * | |
184 * @access public | |
185 * @return void | |
186 */ | |
187 function schema() { | |
188 return array( | |
189 'id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8', 'key' => 'primary'), | |
190 'name' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'), | |
191 'email' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'), | |
192 'created' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => ''), | |
193 'updated' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null) | |
194 ); | |
195 } | |
196 } | |
197 | |
198 /** | |
199 * DboPostgresTest class | |
200 * | |
201 * @package cake | |
202 * @subpackage cake.tests.cases.libs.model.datasources.dbo | |
203 */ | |
204 class DboPostgresTest extends CakeTestCase { | |
205 | |
206 /** | |
207 * Do not automatically load fixtures for each test, they will be loaded manually | |
208 * using CakeTestCase::loadFixtures | |
209 * | |
210 * @var boolean | |
211 * @access public | |
212 */ | |
213 var $autoFixtures = false; | |
214 | |
215 /** | |
216 * Fixtures | |
217 * | |
218 * @var object | |
219 * @access public | |
220 */ | |
221 var $fixtures = array('core.user', 'core.binary_test', 'core.comment', 'core.article', | |
222 'core.tag', 'core.articles_tag', 'core.attachment', 'core.person', 'core.post', 'core.author', | |
223 'core.datatype', | |
224 ); | |
225 /** | |
226 * Actual DB connection used in testing | |
227 * | |
228 * @var DboSource | |
229 * @access public | |
230 */ | |
231 var $db = null; | |
232 | |
233 /** | |
234 * Simulated DB connection used in testing | |
235 * | |
236 * @var DboSource | |
237 * @access public | |
238 */ | |
239 var $db2 = null; | |
240 | |
241 /** | |
242 * Skip if cannot connect to postgres | |
243 * | |
244 * @access public | |
245 */ | |
246 function skip() { | |
247 $this->_initDb(); | |
248 $this->skipUnless($this->db->config['driver'] == 'postgres', '%s PostgreSQL connection not available'); | |
249 } | |
250 | |
251 /** | |
252 * Set up test suite database connection | |
253 * | |
254 * @access public | |
255 */ | |
256 function startTest() { | |
257 $this->_initDb(); | |
258 } | |
259 | |
260 /** | |
261 * Sets up a Dbo class instance for testing | |
262 * | |
263 * @access public | |
264 */ | |
265 function setUp() { | |
266 Configure::write('Cache.disable', true); | |
267 $this->startTest(); | |
268 $this->db =& ConnectionManager::getDataSource('test_suite'); | |
269 $this->db2 = new DboPostgresTestDb($this->db->config, false); | |
270 $this->model = new PostgresTestModel(); | |
271 } | |
272 | |
273 /** | |
274 * Sets up a Dbo class instance for testing | |
275 * | |
276 * @access public | |
277 */ | |
278 function tearDown() { | |
279 Configure::write('Cache.disable', false); | |
280 unset($this->db2); | |
281 } | |
282 | |
283 /** | |
284 * Test field quoting method | |
285 * | |
286 * @access public | |
287 */ | |
288 function testFieldQuoting() { | |
289 $fields = array( | |
290 '"PostgresTestModel"."id" AS "PostgresTestModel__id"', | |
291 '"PostgresTestModel"."client_id" AS "PostgresTestModel__client_id"', | |
292 '"PostgresTestModel"."name" AS "PostgresTestModel__name"', | |
293 '"PostgresTestModel"."login" AS "PostgresTestModel__login"', | |
294 '"PostgresTestModel"."passwd" AS "PostgresTestModel__passwd"', | |
295 '"PostgresTestModel"."addr_1" AS "PostgresTestModel__addr_1"', | |
296 '"PostgresTestModel"."addr_2" AS "PostgresTestModel__addr_2"', | |
297 '"PostgresTestModel"."zip_code" AS "PostgresTestModel__zip_code"', | |
298 '"PostgresTestModel"."city" AS "PostgresTestModel__city"', | |
299 '"PostgresTestModel"."country" AS "PostgresTestModel__country"', | |
300 '"PostgresTestModel"."phone" AS "PostgresTestModel__phone"', | |
301 '"PostgresTestModel"."fax" AS "PostgresTestModel__fax"', | |
302 '"PostgresTestModel"."url" AS "PostgresTestModel__url"', | |
303 '"PostgresTestModel"."email" AS "PostgresTestModel__email"', | |
304 '"PostgresTestModel"."comments" AS "PostgresTestModel__comments"', | |
305 '"PostgresTestModel"."last_login" AS "PostgresTestModel__last_login"', | |
306 '"PostgresTestModel"."created" AS "PostgresTestModel__created"', | |
307 '"PostgresTestModel"."updated" AS "PostgresTestModel__updated"' | |
308 ); | |
309 | |
310 $result = $this->db->fields($this->model); | |
311 $expected = $fields; | |
312 $this->assertEqual($result, $expected); | |
313 | |
314 $result = $this->db->fields($this->model, null, 'PostgresTestModel.*'); | |
315 $expected = $fields; | |
316 $this->assertEqual($result, $expected); | |
317 | |
318 $result = $this->db->fields($this->model, null, array('*', 'AnotherModel.id', 'AnotherModel.name')); | |
319 $expected = array_merge($fields, array( | |
320 '"AnotherModel"."id" AS "AnotherModel__id"', | |
321 '"AnotherModel"."name" AS "AnotherModel__name"')); | |
322 $this->assertEqual($result, $expected); | |
323 | |
324 $result = $this->db->fields($this->model, null, array('*', 'PostgresClientTestModel.*')); | |
325 $expected = array_merge($fields, array( | |
326 '"PostgresClientTestModel"."id" AS "PostgresClientTestModel__id"', | |
327 '"PostgresClientTestModel"."name" AS "PostgresClientTestModel__name"', | |
328 '"PostgresClientTestModel"."email" AS "PostgresClientTestModel__email"', | |
329 '"PostgresClientTestModel"."created" AS "PostgresClientTestModel__created"', | |
330 '"PostgresClientTestModel"."updated" AS "PostgresClientTestModel__updated"')); | |
331 $this->assertEqual($result, $expected); | |
332 } | |
333 | |
334 /** | |
335 * testColumnParsing method | |
336 * | |
337 * @access public | |
338 * @return void | |
339 */ | |
340 function testColumnParsing() { | |
341 $this->assertEqual($this->db2->column('text'), 'text'); | |
342 $this->assertEqual($this->db2->column('date'), 'date'); | |
343 $this->assertEqual($this->db2->column('boolean'), 'boolean'); | |
344 $this->assertEqual($this->db2->column('character varying'), 'string'); | |
345 $this->assertEqual($this->db2->column('time without time zone'), 'time'); | |
346 $this->assertEqual($this->db2->column('timestamp without time zone'), 'datetime'); | |
347 } | |
348 | |
349 /** | |
350 * testValueQuoting method | |
351 * | |
352 * @access public | |
353 * @return void | |
354 */ | |
355 function testValueQuoting() { | |
356 $this->assertIdentical($this->db2->value(1.2, 'float'), "'1.200000'"); | |
357 $this->assertEqual($this->db2->value('1,2', 'float'), "'1,2'"); | |
358 | |
359 $this->assertEqual($this->db2->value('0', 'integer'), "'0'"); | |
360 $this->assertEqual($this->db2->value('', 'integer'), 'NULL'); | |
361 $this->assertEqual($this->db2->value('', 'float'), 'NULL'); | |
362 $this->assertEqual($this->db2->value('', 'integer', false), "DEFAULT"); | |
363 $this->assertEqual($this->db2->value('', 'float', false), "DEFAULT"); | |
364 $this->assertEqual($this->db2->value('0.0', 'float'), "'0.0'"); | |
365 | |
366 $this->assertEqual($this->db2->value('t', 'boolean'), "TRUE"); | |
367 $this->assertEqual($this->db2->value('f', 'boolean'), "FALSE"); | |
368 $this->assertEqual($this->db2->value(true), "TRUE"); | |
369 $this->assertEqual($this->db2->value(false), "FALSE"); | |
370 $this->assertEqual($this->db2->value('t'), "'t'"); | |
371 $this->assertEqual($this->db2->value('f'), "'f'"); | |
372 $this->assertEqual($this->db2->value('true', 'boolean'), 'TRUE'); | |
373 $this->assertEqual($this->db2->value('false', 'boolean'), 'FALSE'); | |
374 $this->assertEqual($this->db2->value('', 'boolean'), 'FALSE'); | |
375 $this->assertEqual($this->db2->value(0, 'boolean'), 'FALSE'); | |
376 $this->assertEqual($this->db2->value(1, 'boolean'), 'TRUE'); | |
377 $this->assertEqual($this->db2->value('1', 'boolean'), 'TRUE'); | |
378 $this->assertEqual($this->db2->value(null, 'boolean'), "NULL"); | |
379 $this->assertEqual($this->db2->value(array()), "NULL"); | |
380 } | |
381 | |
382 /** | |
383 * test that localized floats don't cause trouble. | |
384 * | |
385 * @return void | |
386 */ | |
387 function testLocalizedFloats() { | |
388 $restore = setlocale(LC_ALL, null); | |
389 setlocale(LC_ALL, 'de_DE'); | |
390 | |
391 $result = $this->db->value(3.141593, 'float'); | |
392 $this->assertEqual((string)$result, "'3.141593'"); | |
393 | |
394 $result = $this->db->value(3.14); | |
395 $this->assertEqual((string)$result, "'3.140000'"); | |
396 | |
397 setlocale(LC_ALL, $restore); | |
398 } | |
399 | |
400 /** | |
401 * test that date and time columns do not generate errors with null and nullish values. | |
402 * | |
403 * @return void | |
404 */ | |
405 function testDateAndTimeAsNull() { | |
406 $this->assertEqual($this->db2->value(null, 'date'), 'NULL'); | |
407 $this->assertEqual($this->db2->value('', 'date'), 'NULL'); | |
408 | |
409 $this->assertEqual($this->db2->value('', 'datetime'), 'NULL'); | |
410 $this->assertEqual($this->db2->value(null, 'datetime'), 'NULL'); | |
411 | |
412 $this->assertEqual($this->db2->value('', 'timestamp'), 'NULL'); | |
413 $this->assertEqual($this->db2->value(null, 'timestamp'), 'NULL'); | |
414 | |
415 $this->assertEqual($this->db2->value('', 'time'), 'NULL'); | |
416 $this->assertEqual($this->db2->value(null, 'time'), 'NULL'); | |
417 } | |
418 | |
419 /** | |
420 * Tests that different Postgres boolean 'flavors' are properly returned as native PHP booleans | |
421 * | |
422 * @access public | |
423 * @return void | |
424 */ | |
425 function testBooleanNormalization() { | |
426 $this->assertTrue($this->db2->boolean('t')); | |
427 $this->assertTrue($this->db2->boolean('true')); | |
428 $this->assertTrue($this->db2->boolean('TRUE')); | |
429 $this->assertTrue($this->db2->boolean(true)); | |
430 $this->assertTrue($this->db2->boolean(1)); | |
431 $this->assertTrue($this->db2->boolean(" ")); | |
432 | |
433 $this->assertFalse($this->db2->boolean('f')); | |
434 $this->assertFalse($this->db2->boolean('false')); | |
435 $this->assertFalse($this->db2->boolean('FALSE')); | |
436 $this->assertFalse($this->db2->boolean(false)); | |
437 $this->assertFalse($this->db2->boolean(0)); | |
438 $this->assertFalse($this->db2->boolean('')); | |
439 } | |
440 | |
441 /** | |
442 * test that default -> false in schemas works correctly. | |
443 * | |
444 * @return void | |
445 */ | |
446 function testBooleanDefaultFalseInSchema() { | |
447 $model = new Model(array('name' => 'Datatype', 'table' => 'datatypes', 'ds' => 'test_suite')); | |
448 $model->create(); | |
449 $this->assertIdentical(false, $model->data['Datatype']['bool']); | |
450 } | |
451 | |
452 /** | |
453 * testLastInsertIdMultipleInsert method | |
454 * | |
455 * @access public | |
456 * @return void | |
457 */ | |
458 function testLastInsertIdMultipleInsert() { | |
459 $db1 = ConnectionManager::getDataSource('test_suite'); | |
460 | |
461 $table = $db1->fullTableName('users', false); | |
462 $password = '5f4dcc3b5aa765d61d8327deb882cf99'; | |
463 $db1->execute( | |
464 "INSERT INTO {$table} (\"user\", password) VALUES ('mariano', '{$password}')" | |
465 ); | |
466 $this->assertEqual($db1->lastInsertId($table), 1); | |
467 | |
468 $db1->execute("INSERT INTO {$table} (\"user\", password) VALUES ('hoge', '{$password}')"); | |
469 $this->assertEqual($db1->lastInsertId($table), 2); | |
470 } | |
471 | |
472 /** | |
473 * Tests that table lists and descriptions are scoped to the proper Postgres schema | |
474 * | |
475 * @access public | |
476 * @return void | |
477 */ | |
478 function testSchemaScoping() { | |
479 $db1 =& ConnectionManager::getDataSource('test_suite'); | |
480 $db1->cacheSources = false; | |
481 $db1->reconnect(array('persistent' => false)); | |
482 $db1->query('CREATE SCHEMA _scope_test'); | |
483 | |
484 $db2 =& ConnectionManager::create( | |
485 'test_suite_2', | |
486 array_merge($db1->config, array('driver' => 'postgres', 'schema' => '_scope_test')) | |
487 ); | |
488 $db2->cacheSources = false; | |
489 | |
490 $db2->query('DROP SCHEMA _scope_test'); | |
491 } | |
492 | |
493 /** | |
494 * Tests that column types without default lengths in $columns do not have length values | |
495 * applied when generating schemas. | |
496 * | |
497 * @access public | |
498 * @return void | |
499 */ | |
500 function testColumnUseLength() { | |
501 $result = array('name' => 'foo', 'type' => 'string', 'length' => 100, 'default' => 'FOO'); | |
502 $expected = '"foo" varchar(100) DEFAULT \'FOO\''; | |
503 $this->assertEqual($this->db->buildColumn($result), $expected); | |
504 | |
505 $result = array('name' => 'foo', 'type' => 'text', 'length' => 100, 'default' => 'FOO'); | |
506 $expected = '"foo" text DEFAULT \'FOO\''; | |
507 $this->assertEqual($this->db->buildColumn($result), $expected); | |
508 } | |
509 | |
510 /** | |
511 * Tests that binary data is escaped/unescaped properly on reads and writes | |
512 * | |
513 * @access public | |
514 * @return void | |
515 */ | |
516 function testBinaryDataIntegrity() { | |
517 $data = '%PDF-1.3 | |
518 %ƒÂÚÂÎßÛ†–ƒ∆ | |
519 4 0 obj | |
520 << /Length 5 0 R /Filter /FlateDecode >> | |
521 stream | |
522 xµYMì€∆Ω„WÃ%)nï0¯îâ-«é]Q"πXµáÿ•Ip - P V,]Ú#c˚ˇ‰ut¥†∏Ti9 Ü=”›Ø_˜4>à∑‚Épcé¢Pxæ®2q\' | |
523 1UªbUᡒ+ö«√[ıµ⁄ão"R∑"HiGæä€(å≠≈^Ãøsm?YlƒÃõªfi‹âEÚB&‚Î◊7bÒ^¸m°÷˛?2±Øs“fiu#®U√ˇú÷g¥C;ä")n})JºIÔ3ËSnÑÎ¥≤ıD∆¢∂Msx1üèG˚±Œ™⁄>¶ySïufØ ˝¸?UπÃã√6flÌÚC=øK?˝…s | |
524 ˛§¯ˇ:-˜ò7€ÓFæ∂∑Õ˛∆“V’>ılflëÅd«ÜQdI›ÎB%W¿ΩıÉn~hvêCS>«é˛(ØôK!€¡zB!√ | |
525 [œÜ"ûß ·iH¸[Àºæ∑¯¡L,ÀÚAlS∫ˆ=∫Œ≤cÄr&ˆÈ:√ÿ£˚È«4fl•À]vc›bÅôÿî=siXe4/¡p]ã]ôÆIœ™ Ωflà_ƒ‚G?«7 ùÿ ı¯K4ïIpV◊÷·\'éµóªÚæ>î | |
526 ;›sú!2fl¬F•/f∑j£ | |
527 dw"IÊÜπ<ôÿˆ%IG1ytÛDflXg|Éòa§˜}C˛¿ÿe°G´Ú±jÍm~¿/∂hã<#-¥•ıùe87€t˜õ6w}´{æ | |
528 m‹ê– ∆¡ 6⁄\ | |
529 rAÀBùZ3aË‚r$G·$ó0ÑüâUY4È™¡%C∑Ÿ2rc<Iõ-cï. | |
530 [ŒöâFA†É‡+QglMÉîÉÄúÌ|¸»#x7¥«MgVÎ-GGÚ• I?Á‘”Lzw∞pHů◊nefqCî.nÕeè∆ÿÛy¡˙fb≤üŒHÜAëÕNq=´@ ’cQdÖúAÉIqñŸ˘+2&∏ Àù.gÅ‚ƒœ3EPƒOi—‰:>ÍCäı | |
531 =Õec=ëR˝”eñ=<V$ì˙+x+¢ïÒÕ<àeWå»–˚∫Õd§&£àf ]fPA´âtënöå∏◊ó„Ë@∆≠K´÷˘}a_CI˚©yòHg,ôSSVìBƒl4 L.ÈY…á,2∂íäÙ.$ó¸CäŸ*€óy | |
532 π?G,_√·ÆÎç=^Vkvo±ó{§ƒ2»±¨Ïüo»ëD-ãé fió¥cVÙ\'™G~\'p¢%* ã˚÷ | |
533 ªºnh˚ºO^∏…®[Ó“‚ÅfıÌ≥∫F!Eœ(π∑T6`¬tΩÆ0ì»rTÎ`»Ñ« | |
534 ]≈åp˝)=¿Ô0∆öVÂmˇˆ„ø~¯ÁÔ∏b*fc»‡Îı„Ú}∆tœs∂Y∫ÜaÆ˙X∏~<ÿ·Ùvé1‹p¿TD∆ÔîÄ“úhˆ*Ú€îe)K–p¨Ú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;ÂUÔ P∫kÔˇflTæ∑óflË”ÆC©Ô[≥◊HÁ˚¨hê"ÆbF?ú%h˙ˇ4xèÕ(ó2ÙáíM])Ñd|=fë-cI0ñL¢kÖêk‰Rƒ«ıÄWñ8mO3∏&√æËX¯Hó—ì]yF2»–˜ádàà‡‹Çο„≥7mªHAS∑¶.;Œx(1} _kd©.fidç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Ä÷Òôc’≠—s™rı‚Pdêãh˘ßHVç5fifiÈF€çÌÛuçÖ/M=gëµ±ÿGû1coÔuñæ‘z®. õ∑7ÉÏÜÆ,°’H†ÍÉÌ∂7e º® íˆ⁄◊øNWK”ÂYµ‚ñé;µ¶gV-fl>µtË¥áßN2 ¯¶BaP-)eW.àôt^∏1›C∑Ö?L„&”5’4jvã–ªZ ÷+4% ´0l…»ú^°´© ûiπ∑é®óܱÒÿ‰ïˆÌ–dˆ◊Æ19rQ=Í|ı•rMæ¬;ò‰Y‰é9.”‹˝V«ã¯∏,+ë®j*¡·/'; | |
535 | |
536 $model =& new AppModel(array('name' => 'BinaryTest', 'ds' => 'test_suite')); | |
537 $model->save(compact('data')); | |
538 | |
539 $result = $model->find('first'); | |
540 $this->assertEqual($result['BinaryTest']['data'], $data); | |
541 } | |
542 | |
543 /** | |
544 * Tests the syntax of generated schema indexes | |
545 * | |
546 * @access public | |
547 * @return void | |
548 */ | |
549 function testSchemaIndexSyntax() { | |
550 $schema = new CakeSchema(); | |
551 $schema->tables = array('i18n' => array( | |
552 'id' => array( | |
553 'type' => 'integer', 'null' => false, 'default' => null, | |
554 'length' => 10, 'key' => 'primary' | |
555 ), | |
556 'locale' => array('type'=>'string', 'null' => false, 'length' => 6, 'key' => 'index'), | |
557 'model' => array('type'=>'string', 'null' => false, 'key' => 'index'), | |
558 'foreign_key' => array( | |
559 'type'=>'integer', 'null' => false, 'length' => 10, 'key' => 'index' | |
560 ), | |
561 'field' => array('type'=>'string', 'null' => false, 'key' => 'index'), | |
562 'content' => array('type'=>'text', 'null' => true, 'default' => null), | |
563 'indexes' => array( | |
564 'PRIMARY' => array('column' => 'id', 'unique' => 1), | |
565 'locale' => array('column' => 'locale', 'unique' => 0), | |
566 'model' => array('column' => 'model', 'unique' => 0), | |
567 'row_id' => array('column' => 'foreign_key', 'unique' => 0), | |
568 'field' => array('column' => 'field', 'unique' => 0) | |
569 ) | |
570 )); | |
571 | |
572 $result = $this->db->createSchema($schema); | |
573 $this->assertNoPattern('/^CREATE INDEX(.+);,$/', $result); | |
574 } | |
575 | |
576 /** | |
577 * testCakeSchema method | |
578 * | |
579 * Test that schema generated postgresql queries are valid. ref #5696 | |
580 * Check that the create statement for a schema generated table is the same as the original sql | |
581 * | |
582 * @return void | |
583 * @access public | |
584 */ | |
585 function testCakeSchema() { | |
586 $db1 =& ConnectionManager::getDataSource('test_suite'); | |
587 $db1->cacheSources = false; | |
588 $db1->reconnect(array('persistent' => false)); | |
589 $db1->query('CREATE TABLE ' . $db1->fullTableName('datatype_tests') . ' ( | |
590 id serial NOT NULL, | |
591 "varchar" character varying(40) NOT NULL, | |
592 "full_length" character varying NOT NULL, | |
593 "timestamp" timestamp without time zone, | |
594 date date, | |
595 CONSTRAINT test_suite_data_types_pkey PRIMARY KEY (id) | |
596 )'); | |
597 $model = new Model(array('name' => 'DatatypeTest', 'ds' => 'test_suite')); | |
598 $schema = new CakeSchema(array('connection' => 'test_suite')); | |
599 $result = $schema->read(array( | |
600 'connection' => 'test_suite', | |
601 )); | |
602 $schema->tables = array('datatype_tests' => $result['tables']['missing']['datatype_tests']); | |
603 $result = $db1->createSchema($schema, 'datatype_tests'); | |
604 | |
605 $this->assertNoPattern('/timestamp DEFAULT/', $result); | |
606 $this->assertPattern('/\"full_length\"\s*text\s.*,/', $result); | |
607 $this->assertPattern('/timestamp\s*,/', $result); | |
608 | |
609 $db1->query('DROP TABLE ' . $db1->fullTableName('datatype_tests')); | |
610 | |
611 $db1->query($result); | |
612 $result2 = $schema->read(array( | |
613 'connection' => 'test_suite', | |
614 'models' => array('DatatypeTest') | |
615 )); | |
616 $schema->tables = array('datatype_tests' => $result2['tables']['missing']['datatype_tests']); | |
617 $result2 = $db1->createSchema($schema, 'datatype_tests'); | |
618 $this->assertEqual($result, $result2); | |
619 | |
620 $db1->query('DROP TABLE ' . $db1->fullTableName('datatype_tests')); | |
621 } | |
622 | |
623 /** | |
624 * Test index generation from table info. | |
625 * | |
626 * @return void | |
627 */ | |
628 function testIndexGeneration() { | |
629 $name = $this->db->fullTableName('index_test', false); | |
630 $this->db->query('CREATE TABLE ' . $name . ' ("id" serial NOT NULL PRIMARY KEY, "bool" integer, "small_char" varchar(50), "description" varchar(40) )'); | |
631 $this->db->query('CREATE INDEX pointless_bool ON ' . $name . '("bool")'); | |
632 $this->db->query('CREATE UNIQUE INDEX char_index ON ' . $name . '("small_char")'); | |
633 $expected = array( | |
634 'PRIMARY' => array('column' => 'id', 'unique' => 1), | |
635 'pointless_bool' => array('column' => 'bool', 'unique' => 0), | |
636 'char_index' => array('column' => 'small_char', 'unique' => 1), | |
637 | |
638 ); | |
639 $result = $this->db->index($name); | |
640 $this->assertEqual($expected, $result); | |
641 | |
642 $this->db->query('DROP TABLE ' . $name); | |
643 $name = $this->db->fullTableName('index_test_2', false); | |
644 $this->db->query('CREATE TABLE ' . $name . ' ("id" serial NOT NULL PRIMARY KEY, "bool" integer, "small_char" varchar(50), "description" varchar(40) )'); | |
645 $this->db->query('CREATE UNIQUE INDEX multi_col ON ' . $name . '("small_char", "bool")'); | |
646 $expected = array( | |
647 'PRIMARY' => array('column' => 'id', 'unique' => 1), | |
648 'multi_col' => array('column' => array('small_char', 'bool'), 'unique' => 1), | |
649 ); | |
650 $result = $this->db->index($name); | |
651 $this->assertEqual($expected, $result); | |
652 $this->db->query('DROP TABLE ' . $name); | |
653 } | |
654 | |
655 /** | |
656 * Test the alterSchema capabilities of postgres | |
657 * | |
658 * @access public | |
659 * @return void | |
660 */ | |
661 function testAlterSchema() { | |
662 $Old =& new CakeSchema(array( | |
663 'connection' => 'test_suite', | |
664 'name' => 'AlterPosts', | |
665 'alter_posts' => array( | |
666 'id' => array('type' => 'integer', 'key' => 'primary'), | |
667 'author_id' => array('type' => 'integer', 'null' => false), | |
668 'title' => array('type' => 'string', 'null' => true), | |
669 'body' => array('type' => 'text'), | |
670 'published' => array('type' => 'string', 'length' => 1, 'default' => 'N'), | |
671 'created' => array('type' => 'datetime'), | |
672 'updated' => array('type' => 'datetime'), | |
673 ) | |
674 )); | |
675 $this->db->query($this->db->createSchema($Old)); | |
676 | |
677 $New =& new CakeSchema(array( | |
678 'connection' => 'test_suite', | |
679 'name' => 'AlterPosts', | |
680 'alter_posts' => array( | |
681 'id' => array('type' => 'integer', 'key' => 'primary'), | |
682 'author_id' => array('type' => 'integer', 'null' => true), | |
683 'title' => array('type' => 'string', 'null' => false, 'default' => 'my title'), | |
684 'body' => array('type' => 'string', 'length' => 500), | |
685 'status' => array('type' => 'integer', 'length' => 3, 'default' => 1), | |
686 'created' => array('type' => 'datetime'), | |
687 'updated' => array('type' => 'datetime'), | |
688 ) | |
689 )); | |
690 $this->db->query($this->db->alterSchema($New->compare($Old), 'alter_posts')); | |
691 | |
692 $model = new CakeTestModel(array('table' => 'alter_posts', 'ds' => 'test_suite')); | |
693 $result = $model->schema(); | |
694 $this->assertTrue(isset($result['status'])); | |
695 $this->assertFalse(isset($result['published'])); | |
696 $this->assertEqual($result['body']['type'], 'string'); | |
697 $this->assertEqual($result['status']['default'], 1); | |
698 $this->assertEqual($result['author_id']['null'], true); | |
699 $this->assertEqual($result['title']['null'], false); | |
700 | |
701 $this->db->query($this->db->dropSchema($New)); | |
702 } | |
703 | |
704 /** | |
705 * Test the alter index capabilities of postgres | |
706 * | |
707 * @access public | |
708 * @return void | |
709 */ | |
710 function testAlterIndexes() { | |
711 $this->db->cacheSources = false; | |
712 | |
713 $schema1 =& new CakeSchema(array( | |
714 'name' => 'AlterTest1', | |
715 'connection' => 'test_suite', | |
716 'altertest' => array( | |
717 'id' => array('type' => 'integer', 'null' => false, 'default' => 0), | |
718 'name' => array('type' => 'string', 'null' => false, 'length' => 50), | |
719 'group1' => array('type' => 'integer', 'null' => true), | |
720 'group2' => array('type' => 'integer', 'null' => true) | |
721 ) | |
722 )); | |
723 $this->db->query($this->db->createSchema($schema1)); | |
724 | |
725 $schema2 =& new CakeSchema(array( | |
726 'name' => 'AlterTest2', | |
727 'connection' => 'test_suite', | |
728 'altertest' => array( | |
729 'id' => array('type' => 'integer', 'null' => false, 'default' => 0), | |
730 'name' => array('type' => 'string', 'null' => false, 'length' => 50), | |
731 'group1' => array('type' => 'integer', 'null' => true), | |
732 'group2' => array('type' => 'integer', 'null' => true), | |
733 'indexes' => array( | |
734 'name_idx' => array('column' => 'name', 'unique' => 0), | |
735 'group_idx' => array('column' => 'group1', 'unique' => 0), | |
736 'compound_idx' => array('column' => array('group1', 'group2'), 'unique' => 0), | |
737 'PRIMARY' => array('column' => 'id', 'unique' => 1) | |
738 ) | |
739 ) | |
740 )); | |
741 $this->db->query($this->db->alterSchema($schema2->compare($schema1))); | |
742 | |
743 $indexes = $this->db->index('altertest'); | |
744 $this->assertEqual($schema2->tables['altertest']['indexes'], $indexes); | |
745 | |
746 // Change three indexes, delete one and add another one | |
747 $schema3 =& new CakeSchema(array( | |
748 'name' => 'AlterTest3', | |
749 'connection' => 'test_suite', | |
750 'altertest' => array( | |
751 'id' => array('type' => 'integer', 'null' => false, 'default' => 0), | |
752 'name' => array('type' => 'string', 'null' => false, 'length' => 50), | |
753 'group1' => array('type' => 'integer', 'null' => true), | |
754 'group2' => array('type' => 'integer', 'null' => true), | |
755 'indexes' => array( | |
756 'name_idx' => array('column' => 'name', 'unique' => 1), | |
757 'group_idx' => array('column' => 'group2', 'unique' => 0), | |
758 'compound_idx' => array('column' => array('group2', 'group1'), 'unique' => 0), | |
759 'another_idx' => array('column' => array('group1', 'name'), 'unique' => 0)) | |
760 ))); | |
761 | |
762 $this->db->query($this->db->alterSchema($schema3->compare($schema2))); | |
763 | |
764 $indexes = $this->db->index('altertest'); | |
765 $this->assertEqual($schema3->tables['altertest']['indexes'], $indexes); | |
766 | |
767 // Compare us to ourself. | |
768 $this->assertEqual($schema3->compare($schema3), array()); | |
769 | |
770 // Drop the indexes | |
771 $this->db->query($this->db->alterSchema($schema1->compare($schema3))); | |
772 | |
773 $indexes = $this->db->index('altertest'); | |
774 $this->assertEqual(array(), $indexes); | |
775 | |
776 $this->db->query($this->db->dropSchema($schema1)); | |
777 } | |
778 | |
779 /* | |
780 * Test it is possible to use virtual field with postgresql | |
781 * | |
782 * @access public | |
783 * @return void | |
784 */ | |
785 function testVirtualFields() { | |
786 $this->loadFixtures('Article', 'Comment'); | |
787 $Article = new Article; | |
788 $Article->virtualFields = array( | |
789 'next_id' => 'Article.id + 1', | |
790 'complex' => 'Article.title || Article.body', | |
791 'functional' => 'COALESCE(User.user, Article.title)', | |
792 'subquery' => 'SELECT count(*) FROM ' . $Article->Comment->table | |
793 ); | |
794 $result = $Article->find('first'); | |
795 $this->assertEqual($result['Article']['next_id'], 2); | |
796 $this->assertEqual($result['Article']['complex'], $result['Article']['title'] . $result['Article']['body']); | |
797 $this->assertEqual($result['Article']['functional'], $result['Article']['title']); | |
798 $this->assertEqual($result['Article']['subquery'], 6); | |
799 } | |
800 | |
801 /** | |
802 * Tests additional order options for postgres | |
803 * | |
804 * @access public | |
805 * @return void | |
806 */ | |
807 function testOrderAdditionalParams() { | |
808 $result = $this->db->order(array('title' => 'DESC NULLS FIRST', 'body' => 'DESC')); | |
809 $expected = ' ORDER BY "title" DESC NULLS FIRST, "body" DESC'; | |
810 $this->assertEqual($result, $expected); | |
811 } | |
812 | |
813 /** | |
814 * Test it is possible to do a SELECT COUNT(DISTINCT Model.field) query in postgres and it gets correctly quoted | |
815 */ | |
816 function testQuoteDistinctInFunction() { | |
817 $this->loadFixtures('Article'); | |
818 $Article = new Article; | |
819 $result = $this->db->fields($Article, null, array('COUNT(DISTINCT Article.id)')); | |
820 $expected = array('COUNT(DISTINCT "Article"."id")'); | |
821 $this->assertEqual($result, $expected); | |
822 | |
823 $result = $this->db->fields($Article, null, array('COUNT(DISTINCT id)')); | |
824 $expected = array('COUNT(DISTINCT "id")'); | |
825 $this->assertEqual($result, $expected); | |
826 | |
827 $result = $this->db->fields($Article, null, array('COUNT(DISTINCT FUNC(id))')); | |
828 $expected = array('COUNT(DISTINCT FUNC("id"))'); | |
829 $this->assertEqual($result, $expected); | |
830 } | |
831 | |
832 /** | |
833 * test that saveAll works even with conditions that lack a model name. | |
834 * | |
835 * @return void | |
836 */ | |
837 function testUpdateAllWithNonQualifiedConditions() { | |
838 $this->loadFixtures('Article'); | |
839 $Article =& new Article(); | |
840 $result = $Article->updateAll(array('title' => "'Awesome'"), array('title' => 'Third Article')); | |
841 $this->assertTrue($result); | |
842 | |
843 $result = $Article->find('count', array( | |
844 'conditions' => array('Article.title' => 'Awesome') | |
845 )); | |
846 $this->assertEqual($result, 1, 'Article count is wrong or fixture has changed.'); | |
847 } | |
848 | |
849 /** | |
850 * test alterSchema on two tables. | |
851 * | |
852 * @return void | |
853 */ | |
854 function testAlteringTwoTables() { | |
855 $schema1 =& new CakeSchema(array( | |
856 'name' => 'AlterTest1', | |
857 'connection' => 'test_suite', | |
858 'altertest' => array( | |
859 'id' => array('type' => 'integer', 'null' => false, 'default' => 0), | |
860 'name' => array('type' => 'string', 'null' => false, 'length' => 50), | |
861 ), | |
862 'other_table' => array( | |
863 'id' => array('type' => 'integer', 'null' => false, 'default' => 0), | |
864 'name' => array('type' => 'string', 'null' => false, 'length' => 50), | |
865 ) | |
866 )); | |
867 $schema2 =& new CakeSchema(array( | |
868 'name' => 'AlterTest1', | |
869 'connection' => 'test_suite', | |
870 'altertest' => array( | |
871 'id' => array('type' => 'integer', 'null' => false, 'default' => 0), | |
872 'field_two' => array('type' => 'string', 'null' => false, 'length' => 50), | |
873 ), | |
874 'other_table' => array( | |
875 'id' => array('type' => 'integer', 'null' => false, 'default' => 0), | |
876 'field_two' => array('type' => 'string', 'null' => false, 'length' => 50), | |
877 ) | |
878 )); | |
879 $result = $this->db->alterSchema($schema2->compare($schema1)); | |
880 $this->assertEqual(2, substr_count($result, 'field_two'), 'Too many fields'); | |
881 $this->assertFalse(strpos(';ALTER', $result), 'Too many semi colons'); | |
882 } | |
883 } |