markTestSkipped('PDO and OCI extensions are required.'); $dsn=self::DB_DSN_PREFIX.':dbname='.self::DB_HOST.':'.self::DB_PORT.'/'.self::DB_SERVICE.';charset=UTF8'; $schemaFilePath=realpath(dirname(__FILE__).'/../data/oci.sql'); $this->db=new CDbConnection($dsn, self::DB_USER, self::DB_PASS); $this->db->charset='UTF8'; try { $this->db->active=true; } catch(Exception $e) { echo $e->getMessage(); $this->markTestSkipped("Please read {$schemaFilePath} for details on setting up the test environment for OCI test case."); } $tables=array('comments', 'post_category', 'posts', 'categories', 'profiles', 'users', 'items', 'orders', 'types'); // delete existing sequences foreach($tables as $table) { if($table==='post_category' || $table==='orders' || $table==='types') continue; $sequence=$table.'_id_sequence'; $sql=<<db->createCommand($sql)->execute(); } // delete existing tables foreach($tables as $table) { $sql=<<db->createCommand($sql)->execute(); } $sqls=''; foreach(explode("\n", file_get_contents($schemaFilePath)) as $line) { if(substr($line, 0, 2)==='--') continue; $sqls.=$line."\n"; } foreach(array_filter(explode("\n\n", $sqls)) as $sql) { if(trim($sql)!=='') { if(mb_substr($sql, -4)!=='END;') // do not remove semicolons after BEGIN END blocks $sql=rtrim($sql, ';'); $this->db->createCommand($sql)->execute(); } } } public function tearDown() { $this->db->active=false; } public function testSchema() { $schema=$this->db->schema; $this->assertInstanceOf('CDbSchema', $schema); $this->assertEquals($schema->dbConnection, $this->db); $this->assertInstanceOf('CDbCommandBuilder', $schema->commandBuilder); $this->assertEquals('"users"', $schema->quoteTableName('users')); $this->assertEquals('"id"', $schema->quoteColumnName('id')); $this->assertInstanceOf('CDbTableSchema', $schema->getTable('users')); $this->assertNull($schema->getTable('foo')); } public function testTable() { $table=$this->db->schema->getTable('posts'); $this->assertInstanceOf('CDbTableSchema', $table); $this->assertEquals('posts', $table->name); $this->assertEquals('"posts"', $table->rawName); $this->assertEquals('id', $table->primaryKey); $this->assertEquals(array('author_id'=>array('users', 'id')), $table->foreignKeys); $this->assertEmpty($table->sequenceName); $this->assertCount(5, $table->columns); $this->assertInstanceOf('CDbColumnSchema', $table->getColumn('id')); $this->assertNull($table->getColumn('foo')); $this->assertEquals(array('id', 'title', 'create_time', 'author_id', 'content'), $table->columnNames); $table=$this->db->schema->getTable('orders'); $this->assertEquals(array('key1', 'key2'), $table->primaryKey); $table=$this->db->schema->getTable('items'); $this->assertEquals('id', $table->primaryKey); $this->assertEquals(array('col1'=>array('orders', 'key1'), 'col2'=>array('orders', 'key2')), $table->foreignKeys); $table=$this->db->schema->getTable('types'); $this->assertInstanceOf('CDbTableSchema', $table); $this->assertEquals('types', $table->name); $this->assertEquals('"types"', $table->rawName); $this->assertNull($table->primaryKey); $this->assertEmpty($table->foreignKeys); $this->assertNull($table->sequenceName); $table=$this->db->schema->getTable('invalid'); $this->assertNull($table); } public function testColumn() { $values=array( 'name'=>array('id', 'title', 'create_time', 'author_id', 'content'), 'rawName'=>array('"id"', '"title"', '"create_time"', '"author_id"', '"content"'), 'defaultValue'=>array(null, null, null, null, null), 'size'=>array(null, 512, 6, null, 4000), 'precision'=>array(null, 512, 6, null, 4000), 'scale'=>array(null, null, null, null, null), 'dbType'=>array('NUMBER','VARCHAR2(512)','TIMESTAMP(6)(11)','NUMBER','CLOB(4000)'), 'type'=>array('double','string','string','double','string'), 'isPrimaryKey'=>array(true,false,false,false,false), 'isForeignKey'=>array(false,false,false,true,false), ); $this->checkColumns('posts',$values); } protected function checkColumns($tableName,$values) { $table=$this->db->schema->getTable($tableName); foreach($values as $name=>$value) { foreach(array_values($table->columns) as $i=>$column) { $type1=gettype($column->$name); $type2=gettype($value[$i]); $this->assertTrue($column->$name===$value[$i], "$tableName.{$column->name}.$name is {$column->$name} ($type1), different from the expected {$value[$i]} ($type2)."); } } } public function testCommandBuilder() { $schema=$this->db->schema; $builder=$schema->commandBuilder; $this->assertTrue($builder instanceof CDbCommandBuilder); $table=$schema->getTable('posts'); $c=$builder->createInsertCommand($table,array('title'=>'test post','create_time'=>new CDbExpression('TO_TIMESTAMP(:ts_value, \'YYYY-MM-DD\')', array(':ts_value'=>'2000-01-01')),'author_id'=>1,'content'=>'test content')); $this->assertEquals('INSERT INTO "posts" ("title", "create_time", "author_id", "content") VALUES (:yp0, TO_TIMESTAMP(:ts_value, \'YYYY-MM-DD\'), :yp1, :yp2) RETURNING "id" INTO :RETURN_ID',$c->text); $c->execute(); $this->assertEquals(6,$builder->getLastInsertId($table)); $c=$builder->createCountCommand($table,new CDbCriteria); $this->assertEquals('SELECT COUNT(*) FROM "posts" "t"',$c->text); $this->assertEquals(6,$c->queryScalar()); $c=$builder->createDeleteCommand($table,new CDbCriteria(array( 'condition'=>'"id"=:id', 'params'=>array('id'=>6)))); $this->assertEquals('DELETE FROM "posts" WHERE "id"=:id',$c->text); $c->execute(); $c=$builder->createCountCommand($table,new CDbCriteria); $this->assertEquals(5,$c->queryScalar()); $c=$builder->createFindCommand($table,new CDbCriteria(array( 'select'=>'"id", "title"', 'condition'=>'"id"=:id', 'params'=>array(':id'=>5), 'order'=>'"title"', 'limit'=>2, 'offset'=>0))); $this->assertEquals('WITH USER_SQL AS (SELECT "id", "title" FROM "posts" "t" WHERE "id"=:id ORDER BY "title"), PAGINATION AS (SELECT USER_SQL.*, rownum as rowNumId FROM USER_SQL) SELECT * FROM PAGINATION WHERE rownum <= 2', $c->text); $rows=$c->query()->readAll(); $this->assertEquals(1,count($rows)); $this->assertEquals('post 5',$rows[0]['title']); $c=$builder->createUpdateCommand($table,array('title'=>'new post 5'),new CDbCriteria(array( 'condition'=>'"id"=:id', 'params'=>array('id'=>5)))); $c->execute(); $c=$builder->createFindCommand($table,new CDbCriteria(array( 'select'=>'"title"', 'condition'=>'"id"=:id', 'params'=>array('id'=>5)))); $this->assertEquals('new post 5',$c->queryScalar()); $c=$builder->createSqlCommand('SELECT "title" FROM "posts" WHERE "id"=:id',array(':id'=>3)); $this->assertEquals('post 3',$c->queryScalar()); $c=$builder->createUpdateCounterCommand($table,array('author_id'=>-1),new CDbCriteria(array('condition'=>'"id"=5'))); $this->assertEquals('UPDATE "posts" SET "author_id"="author_id"-1 WHERE "id"=5',$c->text); $c->execute(); $c=$builder->createSqlCommand('SELECT "author_id" FROM "posts" WHERE "id"=5'); $this->assertEquals(2,$c->queryScalar()); // Oracle does not support UPDATE with JOINs so there are no tests of them // test bind by position $c=$builder->createFindCommand($table,new CDbCriteria(array( 'select'=>'"title"', 'condition'=>'"id"=?', 'params'=>array(4)))); $this->assertEquals('SELECT "title" FROM "posts" "t" WHERE "id"=?',$c->text); $this->assertEquals('post 4',$c->queryScalar()); // another bind by position $c=$builder->createUpdateCommand($table,array('title'=>'new post 4'),new CDbCriteria(array( 'condition'=>'"id"=?', 'params'=>array(4)))); $c->execute(); $c=$builder->createSqlCommand('SELECT "title" FROM "posts" WHERE "id"=4'); $this->assertEquals('new post 4',$c->queryScalar()); // testCreateCriteria $c=$builder->createCriteria('column=:value',array(':value'=>'value')); $this->assertEquals('column=:value',$c->condition); $this->assertEquals(array(':value'=>'value'),$c->params); $c=$builder->createCriteria(array('condition'=>'column=:value','params'=>array(':value'=>'value'))); $this->assertEquals('column=:value',$c->condition); $this->assertEquals(array(':value'=>'value'),$c->params); $c2=$builder->createCriteria($c); $this->assertTrue($c2!==$c); $this->assertEquals('column=:value',$c2->condition); $this->assertEquals(array(':value'=>'value'),$c2->params); // testCreatePkCriteria $c=$builder->createPkCriteria($table,1,'author_id>1'); $this->assertEquals('"posts"."id"=1 AND (author_id>1)',$c->condition); $c=$builder->createPkCriteria($table,array(1,2)); $this->assertEquals('"posts"."id" IN (1, 2)',$c->condition); $c=$builder->createPkCriteria($table,array()); $this->assertEquals('0=1',$c->condition); $table2=$schema->getTable('orders'); $c=$builder->createPkCriteria($table2,array('key1'=>1,'key2'=>2),'name=""'); $this->assertEquals('"orders"."key1"=1 AND "orders"."key2"=2 AND (name="")',$c->condition); $c=$builder->createPkCriteria($table2,array(array('key1'=>1,'key2'=>2),array('key1'=>3,'key2'=>4))); $this->assertEquals('("orders"."key1", "orders"."key2") IN ((1, 2), (3, 4))',$c->condition); // createColumnCriteria $c=$builder->createColumnCriteria($table,array('id'=>1,'author_id'=>2),'title=""'); $this->assertEquals('"posts"."id"=:yp0 AND "posts"."author_id"=:yp1 AND (title="")',$c->condition); $c=$builder->createPkCriteria($table2,array()); $this->assertEquals('0=1',$c->condition); } public function testResetSequence() { // we're assuming in this test that COciSchema::resetSequence() is not implemented // empty CDbSchema::resetSequence() being used $max=$this->db->createCommand('SELECT MAX("id") FROM "users"')->queryScalar(); $this->db->createCommand('DELETE FROM "users"')->execute(); $this->db->createCommand('INSERT INTO "users" ("username", "password", "email") VALUES (\'user4\', \'pass4\', \'email4\')')->execute(); $max2=$this->db->createCommand('SELECT MAX("id") FROM "users"')->queryScalar(); $this->assertEquals($max+1, $max2); $userTable=$this->db->schema->getTable('users'); $this->db->createCommand('DELETE FROM "users"')->execute(); $this->db->schema->resetSequence($userTable); $this->db->createCommand('INSERT INTO "users" ("username", "password", "email") VALUES (\'user4\', \'pass4\', \'email4\')')->execute(); $max=$this->db->createCommand('SELECT MAX("id") FROM "users"')->queryScalar(); $this->assertEquals(6, $max); $this->db->createCommand('INSERT INTO "users" ("username", "password", "email") VALUES (\'user4\', \'pass4\', \'email4\')')->execute(); $max=$this->db->createCommand('SELECT MAX("id") FROM "users"')->queryScalar(); $this->assertEquals(7, $max); $this->db->createCommand('DELETE FROM "users"')->execute(); $this->db->schema->resetSequence($userTable, 10); $this->db->createCommand('INSERT INTO "users" ("username", "password", "email") VALUES (\'user4\', \'pass4\', \'email4\')')->execute(); $max=$this->db->createCommand('SELECT MAX("id") FROM "users"')->queryScalar(); $this->assertEquals(8, $max); $this->db->createCommand('INSERT INTO "users" ("username", "password", "email") VALUES (\'user4\', \'pass4\', \'email4\')')->execute(); $max=$this->db->createCommand('SELECT MAX("id") FROM "users"')->queryScalar(); $this->assertEquals(9, $max); } public function testColumnComments() { $tables=$this->db->schema->tables; // specified comments $usersColumns=$tables['users']->columns; $this->assertEquals('User\'s entry primary key', $usersColumns['id']->comment); $this->assertEquals('Имя пользователя', $usersColumns['username']->comment); $this->assertEquals('用户的密码', $usersColumns['password']->comment); $this->assertEquals('דוא"ל של המשתמש', $usersColumns['email']->comment); // empty comments $postsColumns=$tables['posts']->columns; $this->assertEmpty($postsColumns['id']->comment); $this->assertEmpty($postsColumns['title']->comment); $this->assertEmpty($postsColumns['create_time']->comment); $this->assertEmpty($postsColumns['author_id']->comment); $this->assertEmpty($postsColumns['content']->comment); } }