7
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
8
* Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
10
* Licensed under The MIT License
11
* Redistributions of files must retain the above copyright notice.
13
* @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
14
* @link http://cakephp.org CakePHP(tm) Project
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)
20
App::import('Core', array('Model', 'DataSource', 'DboSource', 'DboPostgres'));
21
App::import('Model', 'App');
22
require_once dirname(dirname(dirname(__FILE__))) . DS . 'models.php';
25
* DboPostgresTestDb class
28
* @subpackage cake.tests.cases.libs.model.datasources
30
class DboPostgresTestDb extends DboPostgres {
38
var $simulated = array();
47
function _execute($sql) {
48
$this->simulated[] = $sql;
58
function getLastQuery() {
59
return $this->simulated[count($this->simulated) - 1];
64
* PostgresTestModel class
67
* @subpackage cake.tests.cases.libs.model.datasources
69
class PostgresTestModel extends Model {
74
* @var string 'PostgresTestModel'
77
var $name = 'PostgresTestModel';
85
var $useTable = false;
93
var $belongsTo = array(
94
'PostgresClientTestModel' => array(
95
'foreignKey' => 'client_id'
102
* @param mixed $conditions
103
* @param mixed $fields
104
* @param mixed $order
105
* @param mixed $recursive
109
function find($conditions = null, $fields = null, $order = null, $recursive = null) {
116
* @param mixed $conditions
117
* @param mixed $fields
118
* @param mixed $order
119
* @param mixed $recursive
123
function findAll($conditions = null, $fields = null, $order = null, $recursive = null) {
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)
158
* PostgresClientTestModel class
161
* @subpackage cake.tests.cases.libs.model.datasources
163
class PostgresClientTestModel extends Model {
168
* @var string 'PostgresClientTestModel'
171
var $name = 'PostgresClientTestModel';
179
var $useTable = false;
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)
199
* DboPostgresTest class
202
* @subpackage cake.tests.cases.libs.model.datasources.dbo
204
class DboPostgresTest extends CakeTestCase {
207
* Do not automatically load fixtures for each test, they will be loaded manually
208
* using CakeTestCase::loadFixtures
213
var $autoFixtures = false;
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',
225
* Actual DB connection used in testing
233
* Simulated DB connection used in testing
241
* Skip if cannot connect to postgres
247
$this->skipUnless($this->db->config['driver'] == 'postgres', '%s PostgreSQL connection not available');
251
* Set up test suite database connection
255
function startTest() {
260
* Sets up a Dbo class instance for testing
265
Configure::write('Cache.disable', true);
267
$this->db =& ConnectionManager::getDataSource('test_suite');
268
$this->db2 = new DboPostgresTestDb($this->db->config, false);
269
$this->model = new PostgresTestModel();
273
* Sets up a Dbo class instance for testing
277
function tearDown() {
278
Configure::write('Cache.disable', false);
283
* Test field quoting method
287
function testFieldQuoting() {
289
'"PostgresTestModel"."id" AS "PostgresTestModel__id"',
290
'"PostgresTestModel"."client_id" AS "PostgresTestModel__client_id"',
291
'"PostgresTestModel"."name" AS "PostgresTestModel__name"',
292
'"PostgresTestModel"."login" AS "PostgresTestModel__login"',
293
'"PostgresTestModel"."passwd" AS "PostgresTestModel__passwd"',
294
'"PostgresTestModel"."addr_1" AS "PostgresTestModel__addr_1"',
295
'"PostgresTestModel"."addr_2" AS "PostgresTestModel__addr_2"',
296
'"PostgresTestModel"."zip_code" AS "PostgresTestModel__zip_code"',
297
'"PostgresTestModel"."city" AS "PostgresTestModel__city"',
298
'"PostgresTestModel"."country" AS "PostgresTestModel__country"',
299
'"PostgresTestModel"."phone" AS "PostgresTestModel__phone"',
300
'"PostgresTestModel"."fax" AS "PostgresTestModel__fax"',
301
'"PostgresTestModel"."url" AS "PostgresTestModel__url"',
302
'"PostgresTestModel"."email" AS "PostgresTestModel__email"',
303
'"PostgresTestModel"."comments" AS "PostgresTestModel__comments"',
304
'"PostgresTestModel"."last_login" AS "PostgresTestModel__last_login"',
305
'"PostgresTestModel"."created" AS "PostgresTestModel__created"',
306
'"PostgresTestModel"."updated" AS "PostgresTestModel__updated"'
309
$result = $this->db->fields($this->model);
311
$this->assertEqual($result, $expected);
313
$result = $this->db->fields($this->model, null, 'PostgresTestModel.*');
315
$this->assertEqual($result, $expected);
317
$result = $this->db->fields($this->model, null, array('*', 'AnotherModel.id', 'AnotherModel.name'));
318
$expected = array_merge($fields, array(
319
'"AnotherModel"."id" AS "AnotherModel__id"',
320
'"AnotherModel"."name" AS "AnotherModel__name"'));
321
$this->assertEqual($result, $expected);
323
$result = $this->db->fields($this->model, null, array('*', 'PostgresClientTestModel.*'));
324
$expected = array_merge($fields, array(
325
'"PostgresClientTestModel"."id" AS "PostgresClientTestModel__id"',
326
'"PostgresClientTestModel"."name" AS "PostgresClientTestModel__name"',
327
'"PostgresClientTestModel"."email" AS "PostgresClientTestModel__email"',
328
'"PostgresClientTestModel"."created" AS "PostgresClientTestModel__created"',
329
'"PostgresClientTestModel"."updated" AS "PostgresClientTestModel__updated"'));
330
$this->assertEqual($result, $expected);
334
* testColumnParsing method
339
function testColumnParsing() {
340
$this->assertEqual($this->db2->column('text'), 'text');
341
$this->assertEqual($this->db2->column('date'), 'date');
342
$this->assertEqual($this->db2->column('boolean'), 'boolean');
343
$this->assertEqual($this->db2->column('character varying'), 'string');
344
$this->assertEqual($this->db2->column('time without time zone'), 'time');
345
$this->assertEqual($this->db2->column('timestamp without time zone'), 'datetime');
349
* testValueQuoting method
354
function testValueQuoting() {
355
$this->assertIdentical($this->db2->value(1.2, 'float'), "'1.200000'");
356
$this->assertEqual($this->db2->value('1,2', 'float'), "'1,2'");
358
$this->assertEqual($this->db2->value('0', 'integer'), "'0'");
359
$this->assertEqual($this->db2->value('', 'integer'), 'NULL');
360
$this->assertEqual($this->db2->value('', 'float'), 'NULL');
361
$this->assertEqual($this->db2->value('', 'integer', false), "DEFAULT");
362
$this->assertEqual($this->db2->value('', 'float', false), "DEFAULT");
363
$this->assertEqual($this->db2->value('0.0', 'float'), "'0.0'");
365
$this->assertEqual($this->db2->value('t', 'boolean'), "TRUE");
366
$this->assertEqual($this->db2->value('f', 'boolean'), "FALSE");
367
$this->assertEqual($this->db2->value(true), "TRUE");
368
$this->assertEqual($this->db2->value(false), "FALSE");
369
$this->assertEqual($this->db2->value('t'), "'t'");
370
$this->assertEqual($this->db2->value('f'), "'f'");
371
$this->assertEqual($this->db2->value('true', 'boolean'), 'TRUE');
372
$this->assertEqual($this->db2->value('false', 'boolean'), 'FALSE');
373
$this->assertEqual($this->db2->value('', 'boolean'), 'FALSE');
374
$this->assertEqual($this->db2->value(0, 'boolean'), 'FALSE');
375
$this->assertEqual($this->db2->value(1, 'boolean'), 'TRUE');
376
$this->assertEqual($this->db2->value('1', 'boolean'), 'TRUE');
377
$this->assertEqual($this->db2->value(null, 'boolean'), "NULL");
378
$this->assertEqual($this->db2->value(array()), "NULL");
382
* test that localized floats don't cause trouble.
386
function testLocalizedFloats() {
387
$restore = setlocale(LC_ALL, null);
388
setlocale(LC_ALL, 'de_DE');
390
$result = $this->db->value(3.141593, 'float');
391
$this->assertEqual((string)$result, "'3.141593'");
393
$result = $this->db->value(3.14);
394
$this->assertEqual((string)$result, "'3.140000'");
396
setlocale(LC_ALL, $restore);
400
* test that date and time columns do not generate errors with null and nullish values.
404
function testDateAndTimeAsNull() {
405
$this->assertEqual($this->db2->value(null, 'date'), 'NULL');
406
$this->assertEqual($this->db2->value('', 'date'), 'NULL');
408
$this->assertEqual($this->db2->value('', 'datetime'), 'NULL');
409
$this->assertEqual($this->db2->value(null, 'datetime'), 'NULL');
411
$this->assertEqual($this->db2->value('', 'timestamp'), 'NULL');
412
$this->assertEqual($this->db2->value(null, 'timestamp'), 'NULL');
414
$this->assertEqual($this->db2->value('', 'time'), 'NULL');
415
$this->assertEqual($this->db2->value(null, 'time'), 'NULL');
419
* Tests that different Postgres boolean 'flavors' are properly returned as native PHP booleans
424
function testBooleanNormalization() {
425
$this->assertTrue($this->db2->boolean('t'));
426
$this->assertTrue($this->db2->boolean('true'));
427
$this->assertTrue($this->db2->boolean('TRUE'));
428
$this->assertTrue($this->db2->boolean(true));
429
$this->assertTrue($this->db2->boolean(1));
430
$this->assertTrue($this->db2->boolean(" "));
432
$this->assertFalse($this->db2->boolean('f'));
433
$this->assertFalse($this->db2->boolean('false'));
434
$this->assertFalse($this->db2->boolean('FALSE'));
435
$this->assertFalse($this->db2->boolean(false));
436
$this->assertFalse($this->db2->boolean(0));
437
$this->assertFalse($this->db2->boolean(''));
441
* testLastInsertIdMultipleInsert method
446
function testLastInsertIdMultipleInsert() {
447
$db1 = ConnectionManager::getDataSource('test_suite');
456
$this->assertNotEqual($db1->connection, $db2->connection);
458
$table = $db1->fullTableName('users', false);
459
$password = '5f4dcc3b5aa765d61d8327deb882cf99';
461
"INSERT INTO {$table} (\"user\", password) VALUES ('mariano', '{$password}')"
463
$db2->execute("INSERT INTO {$table} (\"user\", password) VALUES ('hoge', '{$password}')");
464
$this->assertEqual($db1->lastInsertId($table), 1);
465
$this->assertEqual($db2->lastInsertId($table), 2);
469
* Tests that table lists and descriptions are scoped to the proper Postgres schema
474
function testSchemaScoping() {
475
$db1 =& ConnectionManager::getDataSource('test_suite');
476
$db1->cacheSources = false;
477
$db1->reconnect(array('persistent' => false));
478
$db1->query('CREATE SCHEMA _scope_test');
480
$db2 =& ConnectionManager::create(
482
array_merge($db1->config, array('driver' => 'postgres', 'schema' => '_scope_test'))
484
$db2->cacheSources = false;
486
$db2->query('DROP SCHEMA _scope_test');
490
* Tests that column types without default lengths in $columns do not have length values
491
* applied when generating schemas.
496
function testColumnUseLength() {
497
$result = array('name' => 'foo', 'type' => 'string', 'length' => 100, 'default' => 'FOO');
498
$expected = '"foo" varchar(100) DEFAULT \'FOO\'';
499
$this->assertEqual($this->db->buildColumn($result), $expected);
501
$result = array('name' => 'foo', 'type' => 'text', 'length' => 100, 'default' => 'FOO');
502
$expected = '"foo" text DEFAULT \'FOO\'';
503
$this->assertEqual($this->db->buildColumn($result), $expected);
507
* Tests that binary data is escaped/unescaped properly on reads and writes
512
function testBinaryDataIntegrity() {
516
<< /Length 5 0 R /Filter /FlateDecode >>
518
xµYMì€∆Ω„WÃ%)nï0¯îâ-«é]Q"πXµáÿ•Ip - P V,]Ú#c˚ˇ‰ut¥†∏Ti9 Ü=”›Ø_˜4>à∑‚Épcé¢Pxæ®2q\'
519
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
520
˛§¯ˇ:-˜ò7€ÓFæ∂∑Õ˛∆“V’>ılflëÅd«ÜQdI›ÎB%W¿ΩıÉn~hvêCS>«é˛(ØôK!€¡zB!√
521
[œÜ"ûß ·iH¸[Àºæ∑¯¡L,ÀÚAlS∫ˆ=∫Œ≤cÄr&ˆÈ:√ÿ£˚È«4fl•À]vc›bÅôÿî=siXe4/¡p]ã]ôÆIœ™ Ωflà_ƒ‚G?«7 ùÿ ı¯K4ïIpV◊÷·\'éµóªÚæ>î
523
dw"IÊÜπ<ôÿˆ%IG1ytÛDflXg|Éòa§˜}C˛¿ÿe°G´Ú±jÍm~¿/∂hã<#-¥•ıùe87€t˜õ6w}´{æ
525
rAÀBùZ3aË‚r$G·$ó0ÑüâUY4È™¡%C∑Ÿ2rc<Iõ-cï.
526
[ŒöâFA†É‡+QglMÉîÉÄúÌ|¸»#x7¥«MgVÎ-GGÚ• I?Á‘”Lzw∞pHů◊nefqCî.nÕeè∆ÿÛy¡˙fb≤üŒHÜAëÕNq=´@ ’cQdÖúAÉIqñŸ˘+2&∏ Àù.gÅ‚ƒœ3EPƒOi—‰:>ÍCäı
527
=Õec=ëR˝”eñ=<V$ì˙+x+¢ïÒÕ<àeWå»–˚∫Õd§&£àf ]fPA´âtënöå∏◊ó„Ë@∆≠K´÷˘}a_CI˚©yòHg,ôSSVìBƒl4 L.ÈY…á,2∂íäÙ.$ó¸CäŸ*€óy
528
π?G,_√·ÆÎç=^Vkvo±ó{§ƒ2»±¨Ïüo»ëD-ãé fió¥cVÙ\'™G~\'p¢%* ã˚÷
529
ªºnh˚ºO^∏…®[Ó“‚ÅfıÌ≥∫F!Eœ(π∑T6`¬tΩÆ0ì»rTÎ`»Ñ«
530
]≈å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*¡·/';
532
$model =& new AppModel(array('name' => 'BinaryTest', 'ds' => 'test_suite'));
533
$model->save(compact('data'));
535
$result = $model->find('first');
536
$this->assertEqual($result['BinaryTest']['data'], $data);
540
* Tests the syntax of generated schema indexes
545
function testSchemaIndexSyntax() {
546
$schema = new CakeSchema();
547
$schema->tables = array('i18n' => array(
549
'type' => 'integer', 'null' => false, 'default' => null,
550
'length' => 10, 'key' => 'primary'
552
'locale' => array('type'=>'string', 'null' => false, 'length' => 6, 'key' => 'index'),
553
'model' => array('type'=>'string', 'null' => false, 'key' => 'index'),
554
'foreign_key' => array(
555
'type'=>'integer', 'null' => false, 'length' => 10, 'key' => 'index'
557
'field' => array('type'=>'string', 'null' => false, 'key' => 'index'),
558
'content' => array('type'=>'text', 'null' => true, 'default' => null),
560
'PRIMARY' => array('column' => 'id', 'unique' => 1),
561
'locale' => array('column' => 'locale', 'unique' => 0),
562
'model' => array('column' => 'model', 'unique' => 0),
563
'row_id' => array('column' => 'foreign_key', 'unique' => 0),
564
'field' => array('column' => 'field', 'unique' => 0)
568
$result = $this->db->createSchema($schema);
569
$this->assertNoPattern('/^CREATE INDEX(.+);,$/', $result);
573
* testCakeSchema method
575
* Test that schema generated postgresql queries are valid. ref #5696
576
* Check that the create statement for a schema generated table is the same as the original sql
581
function testCakeSchema() {
582
$db1 =& ConnectionManager::getDataSource('test_suite');
583
$db1->cacheSources = false;
584
$db1->reconnect(array('persistent' => false));
585
$db1->query('CREATE TABLE ' . $db1->fullTableName('datatypes') . ' (
587
"varchar" character varying(40) NOT NULL,
588
"full_length" character varying NOT NULL,
589
"timestamp" timestamp without time zone,
591
CONSTRAINT test_suite_data_types_pkey PRIMARY KEY (id)
593
$model = new Model(array('name' => 'Datatype', 'ds' => 'test_suite'));
594
$schema = new CakeSchema(array('connection' => 'test_suite'));
595
$result = $schema->read(array(
596
'connection' => 'test_suite',
597
'models' => array('Datatype')
599
$schema->tables = array('datatypes' => $result['tables']['datatypes']);
600
$result = $db1->createSchema($schema, 'datatypes');
602
$this->assertNoPattern('/timestamp DEFAULT/', $result);
603
$this->assertPattern('/\"full_length\"\s*text\s.*,/', $result);
604
$this->assertPattern('/timestamp\s*,/', $result);
606
$db1->query('DROP TABLE ' . $db1->fullTableName('datatypes'));
608
$db1->query($result);
609
$result2 = $schema->read(array(
610
'connection' => 'test_suite',
611
'models' => array('Datatype')
613
$schema->tables = array('datatypes' => $result2['tables']['datatypes']);
614
$result2 = $db1->createSchema($schema, 'datatypes');
615
$this->assertEqual($result, $result2);
617
$db1->query('DROP TABLE ' . $db1->fullTableName('datatypes'));
621
* Test index generation from table info.
625
function testIndexGeneration() {
626
$name = $this->db->fullTableName('index_test', false);
627
$this->db->query('CREATE TABLE ' . $name . ' ("id" serial NOT NULL PRIMARY KEY, "bool" integer, "small_char" varchar(50), "description" varchar(40) )');
628
$this->db->query('CREATE INDEX pointless_bool ON ' . $name . '("bool")');
629
$this->db->query('CREATE UNIQUE INDEX char_index ON ' . $name . '("small_char")');
631
'PRIMARY' => array('column' => 'id', 'unique' => 1),
632
'pointless_bool' => array('column' => 'bool', 'unique' => 0),
633
'char_index' => array('column' => 'small_char', 'unique' => 1),
636
$result = $this->db->index($name);
637
$this->assertEqual($expected, $result);
639
$this->db->query('DROP TABLE ' . $name);
640
$name = $this->db->fullTableName('index_test_2', false);
641
$this->db->query('CREATE TABLE ' . $name . ' ("id" serial NOT NULL PRIMARY KEY, "bool" integer, "small_char" varchar(50), "description" varchar(40) )');
642
$this->db->query('CREATE UNIQUE INDEX multi_col ON ' . $name . '("small_char", "bool")');
644
'PRIMARY' => array('column' => 'id', 'unique' => 1),
645
'multi_col' => array('column' => array('small_char', 'bool'), 'unique' => 1),
647
$result = $this->db->index($name);
648
$this->assertEqual($expected, $result);
649
$this->db->query('DROP TABLE ' . $name);
653
* Test the alterSchema capabilities of postgres
658
function testAlterSchema() {
659
$Old =& new CakeSchema(array(
660
'connection' => 'test_suite',
661
'name' => 'AlterPosts',
662
'alter_posts' => array(
663
'id' => array('type' => 'integer', 'key' => 'primary'),
664
'author_id' => array('type' => 'integer', 'null' => false),
665
'title' => array('type' => 'string', 'null' => true),
666
'body' => array('type' => 'text'),
667
'published' => array('type' => 'string', 'length' => 1, 'default' => 'N'),
668
'created' => array('type' => 'datetime'),
669
'updated' => array('type' => 'datetime'),
672
$this->db->query($this->db->createSchema($Old));
674
$New =& new CakeSchema(array(
675
'connection' => 'test_suite',
676
'name' => 'AlterPosts',
677
'alter_posts' => array(
678
'id' => array('type' => 'integer', 'key' => 'primary'),
679
'author_id' => array('type' => 'integer', 'null' => true),
680
'title' => array('type' => 'string', 'null' => false, 'default' => 'my title'),
681
'body' => array('type' => 'string', 'length' => 500),
682
'status' => array('type' => 'integer', 'length' => 3, 'default' => 1),
683
'created' => array('type' => 'datetime'),
684
'updated' => array('type' => 'datetime'),
687
$this->db->query($this->db->alterSchema($New->compare($Old), 'alter_posts'));
689
$model = new CakeTestModel(array('table' => 'alter_posts', 'ds' => 'test_suite'));
690
$result = $model->schema();
691
$this->assertTrue(isset($result['status']));
692
$this->assertFalse(isset($result['published']));
693
$this->assertEqual($result['body']['type'], 'string');
694
$this->assertEqual($result['status']['default'], 1);
695
$this->assertEqual($result['author_id']['null'], true);
696
$this->assertEqual($result['title']['null'], false);
698
$this->db->query($this->db->dropSchema($New));
702
* Test the alter index capabilities of postgres
707
function testAlterIndexes() {
708
$this->db->cacheSources = false;
710
$schema1 =& new CakeSchema(array(
711
'name' => 'AlterTest1',
712
'connection' => 'test_suite',
713
'altertest' => array(
714
'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
715
'name' => array('type' => 'string', 'null' => false, 'length' => 50),
716
'group1' => array('type' => 'integer', 'null' => true),
717
'group2' => array('type' => 'integer', 'null' => true)
720
$this->db->query($this->db->createSchema($schema1));
722
$schema2 =& new CakeSchema(array(
723
'name' => 'AlterTest2',
724
'connection' => 'test_suite',
725
'altertest' => array(
726
'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
727
'name' => array('type' => 'string', 'null' => false, 'length' => 50),
728
'group1' => array('type' => 'integer', 'null' => true),
729
'group2' => array('type' => 'integer', 'null' => true),
731
'name_idx' => array('column' => 'name', 'unique' => 0),
732
'group_idx' => array('column' => 'group1', 'unique' => 0),
733
'compound_idx' => array('column' => array('group1', 'group2'), 'unique' => 0),
734
'PRIMARY' => array('column' => 'id', 'unique' => 1)
738
$this->db->query($this->db->alterSchema($schema2->compare($schema1)));
740
$indexes = $this->db->index('altertest');
741
$this->assertEqual($schema2->tables['altertest']['indexes'], $indexes);
743
// Change three indexes, delete one and add another one
744
$schema3 =& new CakeSchema(array(
745
'name' => 'AlterTest3',
746
'connection' => 'test_suite',
747
'altertest' => array(
748
'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
749
'name' => array('type' => 'string', 'null' => false, 'length' => 50),
750
'group1' => array('type' => 'integer', 'null' => true),
751
'group2' => array('type' => 'integer', 'null' => true),
753
'name_idx' => array('column' => 'name', 'unique' => 1),
754
'group_idx' => array('column' => 'group2', 'unique' => 0),
755
'compound_idx' => array('column' => array('group2', 'group1'), 'unique' => 0),
756
'another_idx' => array('column' => array('group1', 'name'), 'unique' => 0))
759
$this->db->query($this->db->alterSchema($schema3->compare($schema2)));
761
$indexes = $this->db->index('altertest');
762
$this->assertEqual($schema3->tables['altertest']['indexes'], $indexes);
764
// Compare us to ourself.
765
$this->assertEqual($schema3->compare($schema3), array());
768
$this->db->query($this->db->alterSchema($schema1->compare($schema3)));
770
$indexes = $this->db->index('altertest');
771
$this->assertEqual(array(), $indexes);
773
$this->db->query($this->db->dropSchema($schema1));
777
* Test it is possible to use virtual field with postgresql
782
function testVirtualFields() {
783
$this->loadFixtures('Article', 'Comment');
784
$Article = new Article;
785
$Article->virtualFields = array(
786
'next_id' => 'Article.id + 1',
787
'complex' => 'Article.title || Article.body',
788
'functional' => 'COALESCE(User.user, Article.title)',
789
'subquery' => 'SELECT count(*) FROM ' . $Article->Comment->table
791
$result = $Article->find('first');
792
$this->assertEqual($result['Article']['next_id'], 2);
793
$this->assertEqual($result['Article']['complex'], $result['Article']['title'] . $result['Article']['body']);
794
$this->assertEqual($result['Article']['functional'], $result['Article']['title']);
795
$this->assertEqual($result['Article']['subquery'], 6);
799
* Tests additional order options for postgres
804
function testOrderAdditionalParams() {
805
$result = $this->db->order(array('title' => 'DESC NULLS FIRST', 'body' => 'DESC'));
806
$expected = ' ORDER BY "title" DESC NULLS FIRST, "body" DESC';
807
$this->assertEqual($result, $expected);
811
* Test it is possible to do a SELECT COUNT(DISTINCT Model.field) query in postgres and it gets correctly quoted
813
function testQuoteDistinctInFunction() {
814
$this->loadFixtures('Article');
815
$Article = new Article;
816
$result = $this->db->fields($Article, null, array('COUNT(DISTINCT Article.id)'));
817
$expected = array('COUNT(DISTINCT "Article"."id")');
818
$this->assertEqual($result, $expected);
820
$result = $this->db->fields($Article, null, array('COUNT(DISTINCT id)'));
821
$expected = array('COUNT(DISTINCT "id")');
822
$this->assertEqual($result, $expected);
824
$result = $this->db->fields($Article, null, array('COUNT(DISTINCT FUNC(id))'));
825
$expected = array('COUNT(DISTINCT FUNC("id"))');
826
$this->assertEqual($result, $expected);
830
* test that saveAll works even with conditions that lack a model name.
834
function testUpdateAllWithNonQualifiedConditions() {
835
$this->loadFixtures('Article');
836
$Article =& new Article();
837
$result = $Article->updateAll(array('title' => "'Awesome'"), array('title' => 'Third Article'));
838
$this->assertTrue($result);
840
$result = $Article->find('count', array(
841
'conditions' => array('Article.title' => 'Awesome')
843
$this->assertEqual($result, 1, 'Article count is wrong or fixture has changed.');
847
* test alterSchema on two tables.
851
function testAlteringTwoTables() {
852
$schema1 =& new CakeSchema(array(
853
'name' => 'AlterTest1',
854
'connection' => 'test_suite',
855
'altertest' => array(
856
'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
857
'name' => array('type' => 'string', 'null' => false, 'length' => 50),
859
'other_table' => array(
860
'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
861
'name' => array('type' => 'string', 'null' => false, 'length' => 50),
864
$schema2 =& new CakeSchema(array(
865
'name' => 'AlterTest1',
866
'connection' => 'test_suite',
867
'altertest' => array(
868
'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
869
'field_two' => array('type' => 'string', 'null' => false, 'length' => 50),
871
'other_table' => array(
872
'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
873
'field_two' => array('type' => 'string', 'null' => false, 'length' => 50),
876
$result = $this->db->alterSchema($schema2->compare($schema1));
877
$this->assertEqual(2, substr_count($result, 'field_two'), 'Too many fields');
878
$this->assertFalse(strpos(';ALTER', $result), 'Too many semi colons');