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

855 lines
31 KiB
PHP
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* DboPostgresTest file
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package cake
* @subpackage cake.cake.libs
* @since CakePHP(tm) v 1.2.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
App::import('Core', array('Model', 'DataSource', 'DboSource', 'DboPostgres'));
App::import('Model', 'App');
require_once dirname(dirname(dirname(__FILE__))) . DS . 'models.php';
/**
* DboPostgresTestDb class
*
* @package cake
* @subpackage cake.tests.cases.libs.model.datasources
*/
class DboPostgresTestDb extends DboPostgres {
/**
* simulated property
*
* @var array
* @access public
*/
public $simulated = array();
/**
* execute method
*
* @param mixed $sql
* @access protected
* @return void
*/
function _execute($sql, $params = array()) {
$this->simulated[] = $sql;
return null;
}
/**
* getLastQuery method
*
* @access public
* @return void
*/
function getLastQuery() {
return $this->simulated[count($this->simulated) - 1];
}
}
/**
* PostgresTestModel class
*
* @package cake
* @subpackage cake.tests.cases.libs.model.datasources
*/
class PostgresTestModel extends Model {
/**
* name property
*
* @var string 'PostgresTestModel'
* @access public
*/
public $name = 'PostgresTestModel';
/**
* useTable property
*
* @var bool false
* @access public
*/
public $useTable = false;
/**
* belongsTo property
*
* @var array
* @access public
*/
public $belongsTo = array(
'PostgresClientTestModel' => array(
'foreignKey' => 'client_id'
)
);
/**
* find method
*
* @param mixed $conditions
* @param mixed $fields
* @param mixed $order
* @param mixed $recursive
* @access public
* @return void
*/
function find($conditions = null, $fields = null, $order = null, $recursive = null) {
return $conditions;
}
/**
* findAll method
*
* @param mixed $conditions
* @param mixed $fields
* @param mixed $order
* @param mixed $recursive
* @access public
* @return void
*/
function findAll($conditions = null, $fields = null, $order = null, $recursive = null) {
return $conditions;
}
/**
* schema method
*
* @access public
* @return void
*/
function schema($field = false) {
return array(
'id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
'client_id' => array('type' => 'integer', 'null' => '', 'default' => '0', 'length' => '11'),
'name' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
'login' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
'passwd' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '255'),
'addr_1' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '255'),
'addr_2' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '25'),
'zip_code' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
'city' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
'country' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
'phone' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
'fax' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
'url' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '255'),
'email' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
'comments' => array('type' => 'text', 'null' => '1', 'default' => '', 'length' => ''),
'last_login'=> array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => ''),
'created' => array('type' => 'date', 'null' => '1', 'default' => '', 'length' => ''),
'updated' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null)
);
}
}
/**
* PostgresClientTestModel class
*
* @package cake
* @subpackage cake.tests.cases.libs.model.datasources
*/
class PostgresClientTestModel extends Model {
/**
* name property
*
* @var string 'PostgresClientTestModel'
* @access public
*/
public $name = 'PostgresClientTestModel';
/**
* useTable property
*
* @var bool false
* @access public
*/
public $useTable = false;
/**
* schema method
*
* @access public
* @return void
*/
function schema($field = false) {
return array(
'id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8', 'key' => 'primary'),
'name' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
'email' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
'created' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => ''),
'updated' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null)
);
}
}
/**
* DboPostgresTest class
*
* @package cake
* @subpackage cake.tests.cases.libs.model.datasources.dbo
*/
class DboPostgresTest extends CakeTestCase {
/**
* Do not automatically load fixtures for each test, they will be loaded manually
* using CakeTestCase::loadFixtures
*
* @var boolean
* @access public
*/
public $autoFixtures = false;
/**
* Fixtures
*
* @var object
* @access public
*/
public $fixtures = array('core.user', 'core.binary_test', 'core.comment', 'core.article',
'core.tag', 'core.articles_tag', 'core.attachment', 'core.person', 'core.post', 'core.author',
);
/**
* Actual DB connection used in testing
*
* @var DboSource
* @access public
*/
public $Dbo = null;
/**
* Simulated DB connection used in testing
*
* @var DboSource
* @access public
*/
public $Dbo2 = null;
/**
* Sets up a Dbo class instance for testing
*
*/
public function setUp() {
Configure::write('Cache.disable', true);
$this->Dbo = ConnectionManager::getDataSource('test');
$this->skipIf(!($this->Dbo instanceof DboPostgres));
$this->Dbo2 = new DboPostgresTestDb($this->Dbo->config, false);
$this->skipUnless($this->Dbo->config['driver'] == 'postgres', 'PostgreSQL connection not available');
$this->model = new PostgresTestModel();
}
/**
* Sets up a Dbo class instance for testing
*
*/
public function tearDown() {
Configure::write('Cache.disable', false);
unset($this->Dbo2);
}
/**
* Test field quoting method
*
*/
public function testFieldQuoting() {
$fields = array(
'"PostgresTestModel"."id" AS "PostgresTestModel__id"',
'"PostgresTestModel"."client_id" AS "PostgresTestModel__client_id"',
'"PostgresTestModel"."name" AS "PostgresTestModel__name"',
'"PostgresTestModel"."login" AS "PostgresTestModel__login"',
'"PostgresTestModel"."passwd" AS "PostgresTestModel__passwd"',
'"PostgresTestModel"."addr_1" AS "PostgresTestModel__addr_1"',
'"PostgresTestModel"."addr_2" AS "PostgresTestModel__addr_2"',
'"PostgresTestModel"."zip_code" AS "PostgresTestModel__zip_code"',
'"PostgresTestModel"."city" AS "PostgresTestModel__city"',
'"PostgresTestModel"."country" AS "PostgresTestModel__country"',
'"PostgresTestModel"."phone" AS "PostgresTestModel__phone"',
'"PostgresTestModel"."fax" AS "PostgresTestModel__fax"',
'"PostgresTestModel"."url" AS "PostgresTestModel__url"',
'"PostgresTestModel"."email" AS "PostgresTestModel__email"',
'"PostgresTestModel"."comments" AS "PostgresTestModel__comments"',
'"PostgresTestModel"."last_login" AS "PostgresTestModel__last_login"',
'"PostgresTestModel"."created" AS "PostgresTestModel__created"',
'"PostgresTestModel"."updated" AS "PostgresTestModel__updated"'
);
$result = $this->Dbo->fields($this->model);
$expected = $fields;
$this->assertEqual($result, $expected);
$result = $this->Dbo->fields($this->model, null, 'PostgresTestModel.*');
$expected = $fields;
$this->assertEqual($result, $expected);
$result = $this->Dbo->fields($this->model, null, array('*', 'AnotherModel.id', 'AnotherModel.name'));
$expected = array_merge($fields, array(
'"AnotherModel"."id" AS "AnotherModel__id"',
'"AnotherModel"."name" AS "AnotherModel__name"'));
$this->assertEqual($result, $expected);
$result = $this->Dbo->fields($this->model, null, array('*', 'PostgresClientTestModel.*'));
$expected = array_merge($fields, array(
'"PostgresClientTestModel"."id" AS "PostgresClientTestModel__id"',
'"PostgresClientTestModel"."name" AS "PostgresClientTestModel__name"',
'"PostgresClientTestModel"."email" AS "PostgresClientTestModel__email"',
'"PostgresClientTestModel"."created" AS "PostgresClientTestModel__created"',
'"PostgresClientTestModel"."updated" AS "PostgresClientTestModel__updated"'));
$this->assertEqual($result, $expected);
}
/**
* testColumnParsing method
*
* @access public
* @return void
*/
function testColumnParsing() {
$this->assertEqual($this->Dbo2->column('text'), 'text');
$this->assertEqual($this->Dbo2->column('date'), 'date');
$this->assertEqual($this->Dbo2->column('boolean'), 'boolean');
$this->assertEqual($this->Dbo2->column('character varying'), 'string');
$this->assertEqual($this->Dbo2->column('time without time zone'), 'time');
$this->assertEqual($this->Dbo2->column('timestamp without time zone'), 'datetime');
}
/**
* testValueQuoting method
*
* @access public
* @return void
*/
function testValueQuoting() {
$this->assertEqual($this->Dbo->value(1.2, 'float'), "1.200000");
$this->assertEqual($this->Dbo->value('1,2', 'float'), "'1,2'");
$this->assertEqual($this->Dbo->value('0', 'integer'), "0");
$this->assertEqual($this->Dbo->value('', 'integer'), 'NULL');
$this->assertEqual($this->Dbo->value('', 'float'), 'NULL');
$this->assertEqual($this->Dbo->value('', 'integer', false), "NULL");
$this->assertEqual($this->Dbo->value('', 'float', false), "NULL");
$this->assertEqual($this->Dbo->value('0.0', 'float'), "'0.0'");
$this->assertEqual($this->Dbo->value('t', 'boolean'), "'TRUE'");
$this->assertEqual($this->Dbo->value('f', 'boolean'), "'FALSE'");
$this->assertEqual($this->Dbo->value(true), "'TRUE'");
$this->assertEqual($this->Dbo->value(false), "'FALSE'");
$this->assertEqual($this->Dbo->value('t'), "'t'");
$this->assertEqual($this->Dbo->value('f'), "'f'");
$this->assertEqual($this->Dbo->value('true', 'boolean'), "'TRUE'");
$this->assertEqual($this->Dbo->value('false', 'boolean'), "'FALSE'");
$this->assertEqual($this->Dbo->value('', 'boolean'), "'FALSE'");
$this->assertEqual($this->Dbo->value(0, 'boolean'), "'FALSE'");
$this->assertEqual($this->Dbo->value(1, 'boolean'), "'TRUE'");
$this->assertEqual($this->Dbo->value('1', 'boolean'), "'TRUE'");
$this->assertEqual($this->Dbo->value(null, 'boolean'), "NULL");
$this->assertEqual($this->Dbo->value(array()), "NULL");
}
/**
* test that localized floats don't cause trouble.
*
* @return void
*/
function testLocalizedFloats() {
$restore = setlocale(LC_ALL, null);
setlocale(LC_ALL, 'de_DE');
$result = $this->db->value(3.141593, 'float');
$this->assertEqual((string)$result, "3.141593");
$result = $this->db->value(3.14);
$this->assertEqual((string)$result, "3.140000");
setlocale(LC_ALL, $restore);
}
/**
* test that date and time columns do not generate errors with null and nullish values.
*
* @return void
*/
function testDateAndTimeAsNull() {
$this->assertEqual($this->Dbo->value(null, 'date'), 'NULL');
$this->assertEqual($this->Dbo->value('', 'date'), 'NULL');
$this->assertEqual($this->Dbo->value('', 'datetime'), 'NULL');
$this->assertEqual($this->Dbo->value(null, 'datetime'), 'NULL');
$this->assertEqual($this->Dbo->value('', 'timestamp'), 'NULL');
$this->assertEqual($this->Dbo->value(null, 'timestamp'), 'NULL');
$this->assertEqual($this->Dbo->value('', 'time'), 'NULL');
$this->assertEqual($this->Dbo->value(null, 'time'), 'NULL');
}
/**
* Tests that different Postgres boolean 'flavors' are properly returned as native PHP booleans
*
* @access public
* @return void
*/
function testBooleanNormalization() {
$this->assertEquals(1, $this->Dbo2->boolean('t', false));
$this->assertEquals(1, $this->Dbo2->boolean('true', false));
$this->assertEquals(1, $this->Dbo2->boolean('TRUE', false));
$this->assertEquals(1, $this->Dbo2->boolean(true, false));
$this->assertEquals(1, $this->Dbo2->boolean(1, false));
$this->assertEquals(1, $this->Dbo2->boolean(" ", false));
$this->assertEquals(0, $this->Dbo2->boolean('f', false));
$this->assertEquals(0, $this->Dbo2->boolean('false', false));
$this->assertEquals(0, $this->Dbo2->boolean('FALSE', false));
$this->assertEquals(0, $this->Dbo2->boolean(false, false));
$this->assertEquals(0, $this->Dbo2->boolean(0, false));
$this->assertEquals(0, $this->Dbo2->boolean('', false));
}
/**
* testLastInsertIdMultipleInsert method
*
* @access public
* @return void
*/
function testLastInsertIdMultipleInsert() {
$this->loadFixtures('User');
$db1 = ConnectionManager::getDataSource('test');
$db2 = clone $db1;
$db2->connect();
$this->assertNotSame($db1->getConnection(), $db2->getConnection());
$table = $db1->fullTableName('users', false);
$password = '5f4dcc3b5aa765d61d8327deb882cf99';
$db1->execute(
"INSERT INTO {$table} (\"user\", password) VALUES ('mariano', '{$password}')"
);
$db2->execute("INSERT INTO {$table} (\"user\", password) VALUES ('hoge', '{$password}')");
$this->assertEqual($db1->lastInsertId($table), 5);
$this->assertEqual($db2->lastInsertId($table), 6);
}
/**
* Tests that table lists and descriptions are scoped to the proper Postgres schema
*
* @access public
* @return void
*/
function testSchemaScoping() {
$db1 = ConnectionManager::getDataSource('test');
$db1->cacheSources = false;
$db1->reconnect(array('persistent' => false));
$db1->query('CREATE SCHEMA _scope_test');
$db2 = ConnectionManager::create(
'test_2',
array_merge($db1->config, array('driver' => 'postgres', 'schema' => '_scope_test'))
);
$db2->cacheSources = false;
$db2->query('DROP SCHEMA _scope_test');
}
/**
* Tests that column types without default lengths in $columns do not have length values
* applied when generating schemas.
*
* @access public
* @return void
*/
function testColumnUseLength() {
$result = array('name' => 'foo', 'type' => 'string', 'length' => 100, 'default' => 'FOO');
$expected = '"foo" varchar(100) DEFAULT \'FOO\'';
$this->assertEqual($this->Dbo->buildColumn($result), $expected);
$result = array('name' => 'foo', 'type' => 'text', 'length' => 100, 'default' => 'FOO');
$expected = '"foo" text DEFAULT \'FOO\'';
$this->assertEqual($this->Dbo->buildColumn($result), $expected);
}
/**
* Tests that binary data is escaped/unescaped properly on reads and writes
*
* @access public
* @return void
*/
function testBinaryDataIntegrity() {
$this->loadFixtures('BinaryTest');
$data = '%PDF-1.3
%ƒÂÚÂÎßÛ†–ƒ∆
4 0 obj
<< /Length 5 0 R /Filter /FlateDecode >>
stream
xµYMì€∆Ω„WÃ%)nï0¯îâ-«é]Q"πXµáÿ•Ip - P V,]Ú#c˚ˇ‰ut¥†∏Ti9 Ü=”Ø_˜4>à∑Épcé¢Pxæ®2q\'
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
˛§¯ˇ:-˜ò7€ÓFæ∂∑Õ˛∆“V>ılflëÅd«ÜQdI ÎB%W¿ΩıÉn~h vêCS>«é˛(ØôK!€¡zB!√
[œÜ"ûß ·iH¸€ºæ∑¯¡L,ÀÚAlS∫ˆ=∫Œ≤cÄr&ˆÈ:√ÿ£˚È«4fl•À]vcbÅôÿî=siXe4/¡p]ã]ôÆIœ™ Ωflà_ƒG7 ùÿ ı¯K4ïIpV◊÷·\'éµóªÚæ>î
;!2fl¬F•/f∑j£
dw"IÊÜπ<ôÿˆ%IG1ytÛDflXg|Éòa§˜}C˛¿ÿe°G´Ú±jÍm~¿/∂hã<#-¥•ıùe87€t˜õ6w}´
mê ∆¡ 6\
rAÀBùZ3aËr$G·$ó0Ñ üâUY4È™¡%C∑Ÿ2rc<Iõ-cï.
[ŒöâFA†É‡+QglMÉîÉÄúÌ|¸»#x7¥«MgVÎ-GGÚ• I?Á”Lzw∞pHů◊nefqCî.nÕeè∆ÿÛy¡˙fb≤üŒHÜAëÕNq=´@ cQdÖúAÉIqñŸ˘+2&∏ Àù.gŃœ3EPƒOi—‰:>ÍCäı
=Õec=ëR˝”eñ=<V$ì˙+x+¢ïÒÕ<àeWå»–˚∫Õ d§&£àf ]fPA´âtënöå∏◊ó Ë@∆≠K´÷˘}a_CI˚©yòHg,ôSSVìBƒl4 L.ÈY…á,2∂íäÙ.$ó¸CäŸ*€óy
π?G,_√·ÆÎç=^Vkvo±ó{§ƒ2»±¨Ïüo»ëD-ãé fió¥cVÙ\'™G~\'p¢%* ã˚÷
ªºnh˚ºO^∏…®[Ó“ÅfıÌ≥∫F!Eœ(π∑T6`¬tΩÆ0ì»rTÎ`»Ñ«
]≈åp˝)=¿Ô0∆öVÂmˇˆ„ø~¯ÁÔ∏b*fc»‡Îı„Ú}∆tœs∂Y∫ÜaÆ˙X∏~<ÿ·Ù vé1p¿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^∏1C∑Ö?L„&”54jvãªZ ÷+4% ´0l…»ú´© ûiπ∑é®óܱÒÿ‰ïˆÌdˆ◊Æ19rQ=Í|ı•rMæ¬;ò‰Y‰é9. ˝V«ã¯∏,+ë®j*¡·/';
$model = new AppModel(array('name' => 'BinaryTest', 'ds' => 'test'));
$model->save(compact('data'));
$result = $model->find('first');
$this->assertEqual($result['BinaryTest']['data'], $data);
}
/**
* Tests the syntax of generated schema indexes
*
* @access public
* @return void
*/
function testSchemaIndexSyntax() {
$schema = new CakeSchema();
$schema->tables = array('i18n' => array(
'id' => array(
'type' => 'integer', 'null' => false, 'default' => null,
'length' => 10, 'key' => 'primary'
),
'locale' => array('type'=>'string', 'null' => false, 'length' => 6, 'key' => 'index'),
'model' => array('type'=>'string', 'null' => false, 'key' => 'index'),
'foreign_key' => array(
'type'=>'integer', 'null' => false, 'length' => 10, 'key' => 'index'
),
'field' => array('type'=>'string', 'null' => false, 'key' => 'index'),
'content' => array('type'=>'text', 'null' => true, 'default' => null),
'indexes' => array(
'PRIMARY' => array('column' => 'id', 'unique' => 1),
'locale' => array('column' => 'locale', 'unique' => 0),
'model' => array('column' => 'model', 'unique' => 0),
'row_id' => array('column' => 'foreign_key', 'unique' => 0),
'field' => array('column' => 'field', 'unique' => 0)
)
));
$result = $this->Dbo->createSchema($schema);
$this->assertNoPattern('/^CREATE INDEX(.+);,$/', $result);
}
/**
* testCakeSchema method
*
* Test that schema generated postgresql queries are valid. ref #5696
* Check that the create statement for a schema generated table is the same as the original sql
*
* @return void
*/
public function testCakeSchema() {
$db1 = ConnectionManager::getDataSource('test');
$db1->cacheSources = false;
$db1->reconnect(array('persistent' => false));
$db1->rawQuery('CREATE TABLE ' . $db1->fullTableName('datatypes') . ' (
id serial NOT NULL,
"varchar" character varying(40) NOT NULL,
"full_length" character varying NOT NULL,
"timestamp" timestamp without time zone,
"date" date,
CONSTRAINT test_data_types_pkey PRIMARY KEY (id)
)');
$model = new Model(array('name' => 'Datatype', 'ds' => 'test'));
$schema = new CakeSchema(array('connection' => 'test'));
$result = $schema->read(array(
'connection' => 'test',
'models' => array('Datatype')
));
$schema->tables = array('datatypes' => $result['tables']['missing']['datatypes']);
$result = $db1->createSchema($schema, 'datatypes');
$db1->rawQuery('DROP TABLE ' . $db1->fullTableName('datatypes'));
$this->assertNoPattern('/timestamp DEFAULT/', $result);
$this->assertPattern('/\"full_length\"\s*text\s.*,/', $result);
$this->assertPattern('/timestamp\s*,/', $result);
$db1->query($result);
$result2 = $schema->read(array(
'connection' => 'test',
'models' => array('Datatype')
));
$schema->tables = array('datatypes' => $result2['tables']['missing']['datatypes']);
$result2 = $db1->createSchema($schema, 'datatypes');
$this->assertEqual($result, $result2);
$db1->query('DROP TABLE ' . $db1->fullTableName('datatypes'));
}
/**
* Test index generation from table info.
*
* @return void
*/
function testIndexGeneration() {
$name = $this->Dbo->fullTableName('index_test', false);
$this->Dbo->query('CREATE TABLE ' . $name . ' ("id" serial NOT NULL PRIMARY KEY, "bool" integer, "small_char" varchar(50), "description" varchar(40) )');
$this->Dbo->query('CREATE INDEX pointless_bool ON ' . $name . '("bool")');
$this->Dbo->query('CREATE UNIQUE INDEX char_index ON ' . $name . '("small_char")');
$expected = array(
'PRIMARY' => array('column' => 'id', 'unique' => 1),
'pointless_bool' => array('column' => 'bool', 'unique' => 0),
'char_index' => array('column' => 'small_char', 'unique' => 1),
);
$result = $this->Dbo->index($name);
$this->Dbo->query('DROP TABLE ' . $name);
$this->assertEqual($expected, $result);
$name = $this->Dbo->fullTableName('index_test_2', false);
$this->Dbo->query('CREATE TABLE ' . $name . ' ("id" serial NOT NULL PRIMARY KEY, "bool" integer, "small_char" varchar(50), "description" varchar(40) )');
$this->Dbo->query('CREATE UNIQUE INDEX multi_col ON ' . $name . '("small_char", "bool")');
$expected = array(
'PRIMARY' => array('column' => 'id', 'unique' => 1),
'multi_col' => array('column' => array('small_char', 'bool'), 'unique' => 1),
);
$result = $this->Dbo->index($name);
$this->Dbo->query('DROP TABLE ' . $name);
$this->assertEqual($expected, $result);
}
/**
* Test the alterSchema capabilities of postgres
*
* @access public
* @return void
*/
function testAlterSchema() {
$Old = new CakeSchema(array(
'connection' => 'test',
'name' => 'AlterPosts',
'alter_posts' => array(
'id' => array('type' => 'integer', 'key' => 'primary'),
'author_id' => array('type' => 'integer', 'null' => false),
'title' => array('type' => 'string', 'null' => true),
'body' => array('type' => 'text'),
'published' => array('type' => 'string', 'length' => 1, 'default' => 'N'),
'created' => array('type' => 'datetime'),
'updated' => array('type' => 'datetime'),
)
));
$this->Dbo->query($this->Dbo->createSchema($Old));
$New = new CakeSchema(array(
'connection' => 'test',
'name' => 'AlterPosts',
'alter_posts' => array(
'id' => array('type' => 'integer', 'key' => 'primary'),
'author_id' => array('type' => 'integer', 'null' => true),
'title' => array('type' => 'string', 'null' => false, 'default' => 'my title'),
'body' => array('type' => 'string', 'length' => 500),
'status' => array('type' => 'integer', 'length' => 3, 'default' => 1),
'created' => array('type' => 'datetime'),
'updated' => array('type' => 'datetime'),
)
));
$this->Dbo->query($this->Dbo->alterSchema($New->compare($Old), 'alter_posts'));
$model = new CakeTestModel(array('table' => 'alter_posts', 'ds' => 'test'));
$result = $model->schema();
$this->assertTrue(isset($result['status']));
$this->assertFalse(isset($result['published']));
$this->assertEqual($result['body']['type'], 'string');
$this->assertEqual($result['status']['default'], 1);
$this->assertEqual($result['author_id']['null'], true);
$this->assertEqual($result['title']['null'], false);
$this->Dbo->query($this->Dbo->dropSchema($New));
}
/**
* Test the alter index capabilities of postgres
*
* @access public
* @return void
*/
function testAlterIndexes() {
$this->Dbo->cacheSources = false;
$schema1 = new CakeSchema(array(
'name' => 'AlterTest1',
'connection' => 'test',
'altertest' => array(
'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
'name' => array('type' => 'string', 'null' => false, 'length' => 50),
'group1' => array('type' => 'integer', 'null' => true),
'group2' => array('type' => 'integer', 'null' => true)
)
));
$this->Dbo->rawQuery($this->Dbo->createSchema($schema1));
$schema2 = new CakeSchema(array(
'name' => 'AlterTest2',
'connection' => 'test',
'altertest' => array(
'id' => array('type' => 'integer', 'null' => 0, 'default' => 0),
'name' => array('type' => 'string', 'null' => 0, 'length' => 50),
'group1' => array('type' => 'integer', 'null' => 1),
'group2' => array('type' => 'integer', 'null' => 1),
'indexes' => array(
'name_idx' => array('column' => 'name', 'unique' => 0),
'group_idx' => array('column' => 'group1', 'unique' => 0),
'compound_idx' => array('column' => array('group1', 'group2'), 'unique' => 0),
'PRIMARY' => array('column' => 'id', 'unique' => 1)
)
)
));
$this->Dbo->query($this->Dbo->alterSchema($schema2->compare($schema1)));
$indexes = $this->Dbo->index('altertest');
$this->assertEqual($schema2->tables['altertest']['indexes'], $indexes);
// Change three indexes, delete one and add another one
$schema3 = new CakeSchema(array(
'name' => 'AlterTest3',
'connection' => 'test',
'altertest' => array(
'id' => array('type' => 'integer', 'null' => 0, 'default' => 0),
'name' => array('type' => 'string', 'null' => 0, 'length' => 50),
'group1' => array('type' => 'integer', 'null' => 1),
'group2' => array('type' => 'integer', 'null' => 1),
'indexes' => array(
'name_idx' => array('column' => 'name', 'unique' => 1),
'group_idx' => array('column' => 'group2', 'unique' => 0),
'compound_idx' => array('column' => array('group2', 'group1'), 'unique' => 0),
'another_idx' => array('column' => array('group1', 'name'), 'unique' => 0))
)));
$this->Dbo->query($this->Dbo->alterSchema($schema3->compare($schema2)));
$indexes = $this->Dbo->index('altertest');
$this->assertEqual($schema3->tables['altertest']['indexes'], $indexes);
// Compare us to ourself.
$this->assertEqual($schema3->compare($schema3), array());
// Drop the indexes
$this->Dbo->query($this->Dbo->alterSchema($schema1->compare($schema3)));
$indexes = $this->Dbo->index('altertest');
$this->assertEqual(array(), $indexes);
$this->Dbo->query($this->Dbo->dropSchema($schema1));
}
/*
* Test it is possible to use virtual field with postgresql
*
* @access public
* @return void
*/
function testVirtualFields() {
$this->loadFixtures('Article', 'Comment', 'User', 'Attachment', 'Tag', 'ArticlesTag');
$Article = new Article;
$Article->virtualFields = array(
'next_id' => 'Article.id + 1',
'complex' => 'Article.title || Article.body',
'functional' => 'COALESCE(User.user, Article.title)',
'subquery' => 'SELECT count(*) FROM ' . $Article->Comment->table
);
$result = $Article->find('first');
$this->assertEqual($result['Article']['next_id'], 2);
$this->assertEqual($result['Article']['complex'], $result['Article']['title'] . $result['Article']['body']);
$this->assertEqual($result['Article']['functional'], $result['User']['user']);
$this->assertEqual($result['Article']['subquery'], 6);
}
/**
* Tests additional order options for postgres
*
* @access public
* @return void
*/
function testOrderAdditionalParams() {
$result = $this->Dbo->order(array('title' => 'DESC NULLS FIRST', 'body' => 'DESC'));
$expected = ' ORDER BY "title" DESC NULLS FIRST, "body" DESC';
$this->assertEqual($result, $expected);
}
/**
* Test it is possible to do a SELECT COUNT(DISTINCT Model.field) query in postgres and it gets correctly quoted
*/
function testQuoteDistinctInFunction() {
$this->loadFixtures('Article');
$Article = new Article;
$result = $this->Dbo->fields($Article, null, array('COUNT(DISTINCT Article.id)'));
$expected = array('COUNT(DISTINCT "Article"."id")');
$this->assertEqual($result, $expected);
$result = $this->Dbo->fields($Article, null, array('COUNT(DISTINCT id)'));
$expected = array('COUNT(DISTINCT "id")');
$this->assertEqual($result, $expected);
$result = $this->Dbo->fields($Article, null, array('COUNT(DISTINCT FUNC(id))'));
$expected = array('COUNT(DISTINCT FUNC("id"))');
$this->assertEqual($result, $expected);
}
/**
* test that saveAll works even with conditions that lack a model name.
*
* @return void
*/
function testUpdateAllWithNonQualifiedConditions() {
$this->loadFixtures('Article');
$Article = new Article();
$result = $Article->updateAll(array('title' => "'Awesome'"), array('title' => 'Third Article'));
$this->assertTrue($result);
$result = $Article->find('count', array(
'conditions' => array('Article.title' => 'Awesome')
));
$this->assertEqual($result, 1, 'Article count is wrong or fixture has changed.');
}
/**
* test alterSchema on two tables.
*
* @return void
*/
function testAlteringTwoTables() {
$schema1 = new CakeSchema(array(
'name' => 'AlterTest1',
'connection' => 'test',
'altertest' => array(
'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
'name' => array('type' => 'string', 'null' => false, 'length' => 50),
),
'other_table' => array(
'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
'name' => array('type' => 'string', 'null' => false, 'length' => 50),
)
));
$schema2 = new CakeSchema(array(
'name' => 'AlterTest1',
'connection' => 'test',
'altertest' => array(
'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
'field_two' => array('type' => 'string', 'null' => false, 'length' => 50),
),
'other_table' => array(
'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
'field_two' => array('type' => 'string', 'null' => false, 'length' => 50),
)
));
$result = $this->db->alterSchema($schema2->compare($schema1));
$this->assertEqual(2, substr_count($result, 'field_two'), 'Too many fields');
$this->assertFalse(strpos(';ALTER', $result), 'Too many semi colons');
}
}