-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
qiang.xue
committed
Jun 10, 2009
1 parent
7c9033c
commit 61d96d5
Showing
4 changed files
with
243 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,193 @@ | ||
<?php | ||
|
||
class CDbFixture extends CApplicationComponent | ||
{ | ||
public $basePath; | ||
public $connectionID='db'; | ||
public $dbSchemaFile='schema.php'; | ||
public $tableSchemaSuffix='.schema'; | ||
|
||
private $_db; | ||
private $_rows; // fixture name, row alias => row | ||
private $_records; // fixture name, row alias => array(class name, primary key) or AR object | ||
|
||
public function init() | ||
{ | ||
parent::init(); | ||
if($this->basePath===null) | ||
$this->basePath=Yii::getPathOfAlias('application.tests.fixtures'); | ||
} | ||
|
||
public function getRows($name) | ||
{ | ||
if(isset($this->_rows[$name])) | ||
return $this->_rows[$name]; | ||
else | ||
return false; | ||
} | ||
|
||
public function hasRecord($name,$alias) | ||
{ | ||
return isset($this->_records[$name][$alias]); | ||
} | ||
|
||
public function getRecord($name,$alias) | ||
{ | ||
if(isset($this->_records[$name][$alias])) | ||
{ | ||
if($this->_records[$name][$alias] instanceof CActiveRecord) | ||
return $this->_records[$name][$alias]; | ||
else | ||
{ | ||
$config=$this->_records[$name][$alias]; | ||
$modelClass=$config[0]; | ||
unset($config[0]); | ||
return $this->_records[$name][$alias]=CActiveRecord::model($modelClass)->findByPk(count($config)>1 ? $config : $config[1]); | ||
} | ||
} | ||
else | ||
return false; | ||
} | ||
|
||
public function getDbConnection() | ||
{ | ||
if($this->_db===null) | ||
{ | ||
$this->_db=Yii::app()->getComponent($this->connectionID); | ||
if(!$this->_db instanceof CDbConnection) | ||
throw new CException(Yii::t('yii','CDbFixture.connectionID "{id}" is invalid. Please make sure it refers to the ID of a CDbConnection application component.', | ||
array('{id}'=>$id))); | ||
} | ||
return $this->_db; | ||
} | ||
|
||
public function prepare() | ||
{ | ||
$fileName=$this->basePath.DIRECTORY_SEPARATOR.$this->dbSchemaFile.'.php'; | ||
if(is_file($fileName)) | ||
require($fileName); | ||
} | ||
|
||
public function load($fixtures) | ||
{ | ||
$this->getDbConnection()->getSchema()->checkIntegrity(false); | ||
|
||
$this->_rows=array(); | ||
$this->_records=array(); | ||
foreach($fixtures as $varName=>$modelClass) | ||
$this->loadFixture($varName,$modelClass); | ||
|
||
$this->getDbConnection()->getSchema()->checkIntegrity(true); | ||
} | ||
|
||
public function unload($fixtures) | ||
{ | ||
// unlock FK constraints | ||
|
||
foreach($fixtures as $varName=>$modelClass) | ||
$this->unloadFixture($varName,$modelClass); | ||
|
||
// reset sequence? | ||
// Lock FK constraints | ||
} | ||
|
||
protected function truncateTable($tableName) | ||
{ | ||
$db=$this->getDbConnection(); | ||
if(($table=$db->getSchema()->getTable($tableName))!==null) | ||
{ | ||
$db->createCommand('DELETE FROM '.$table->rawName)->execute(); | ||
$db->getSchema()->resetSequence($table,1); | ||
} | ||
else | ||
throw new Exception("Table '$tableName' does not exist."); | ||
} | ||
|
||
protected function resetTable($tableName) | ||
{ | ||
$fileName=$this->basePath.DIRECTORY_SEPARATOR.$tableName.$this->tableSchemaSuffix.'.php'; | ||
if(is_file($fileName)) | ||
require($fileName); | ||
else | ||
$this->truncateTable($tableName); | ||
} | ||
|
||
protected function loadTable($tableName) | ||
{ | ||
$fileName=$this->basePath.DIRECTORY_SEPARATOR.$tableName.'.php'; | ||
if(!is_file($fileName)) | ||
throw new Exception("Unable to find the fixture file '$fileName'."); | ||
return require($fileName); | ||
} | ||
|
||
protected function getTableName($modelClass) | ||
{ | ||
if($modelClass[0]===':') // it is a table name, no model available | ||
return $tableName=substr($modelClass,1); | ||
else | ||
{ | ||
$modelClass=Yii::import($modelClass,true); | ||
return CActiveRecord::model($modelClass)->tableName(); | ||
} | ||
} | ||
|
||
public function loadFixture($varName,$modelClass) | ||
{ | ||
$db=$this->getDbConnection(); | ||
$tableName=$this->getTableName($modelClass); | ||
if($modelClass[0]!==':') | ||
$model=CActiveRecord::model($modelClass); | ||
|
||
if(($table=$db->getSchema()->getTable($tableName))===null) | ||
throw new Exception("Table '$tableName' does not exist."); | ||
|
||
$builder=$db->getSchema()->getCommandBuilder(); | ||
|
||
$this->resetTable($tableName); | ||
|
||
foreach($this->loadTable($tableName) as $alias=>$row) | ||
{ | ||
$builder->createInsertCommand($table,$row)->execute(); | ||
$primaryKey=$table->primaryKey; | ||
if($table->sequenceName!==null) | ||
{ | ||
if(is_string($primaryKey) && !isset($row[$primaryKey])) | ||
$row[$primaryKey]=$builder->getLastInsertID($table); | ||
else if(is_array($primaryKey)) | ||
{ | ||
foreach($primaryKey as $pk) | ||
{ | ||
if(!isset($row[$pk])) | ||
{ | ||
$row[$pk]=$builder->getLastInsertID($table); | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
|
||
if(is_integer($varName)) | ||
continue; | ||
|
||
$this->_rows[$varName][$alias]=$row; | ||
|
||
if(is_string($alias) && isset($model)) // prepare for loading AR when needed | ||
{ | ||
$this->_records[$varName][$alias][0]=$modelClass; | ||
if(is_array($table->primaryKey)) | ||
{ | ||
foreach($table->primaryKey as $key) | ||
$this->_records[$varName][$alias][$key]=$row[$key]; | ||
} | ||
else | ||
$this->_records[$varName][$alias][]=$row[$table->primaryKey]; | ||
} | ||
} | ||
} | ||
|
||
public function unloadFixture($varName,$modelClass) | ||
{ | ||
$db=$this->getDbConnection(); | ||
$tableName=$this->getTableName($modelClass); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
<?php | ||
|
||
Yii::import('system.test.CTestCase'); | ||
|
||
class CActiveRecordTestCase extends CTestCase | ||
{ | ||
public function __get($name) | ||
{ | ||
if(($rows=$this->getFixture()->getRows($name))!==false) | ||
return $rows; | ||
else | ||
throw new Exception("Unknown property '$name' for class '".get_class($this)."'."); | ||
} | ||
|
||
public function __call($name,$params) | ||
{ | ||
if(isset($params[0]) && $this->getFixture()->hasRecord($name,$params[0])) | ||
return $this->getFixture()->getRecord($name,$params[0]); | ||
else | ||
throw new Exception("Unknown method '$name' for class '".get_class($this)."'."); | ||
} | ||
|
||
public function getFixture() | ||
{ | ||
return Yii::app()->getComponent('fixture'); | ||
} | ||
|
||
public function fixtures() | ||
{ | ||
return array(); | ||
} | ||
|
||
public function setUp() | ||
{ | ||
parent::setUp(); | ||
$this->getFixture()->load($this->fixtures()); | ||
} | ||
|
||
public function tearDown() | ||
{ | ||
$this->getFixture()->unload($this->fixtures()); | ||
parent::tearDown(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<?php | ||
|
||
class CTestCase extends PHPUnit_Framework_TestCase | ||
{ | ||
} |