FEATURE #2767 wakeless: Allow popuplation of non-DataObject tables with YamlFixture

git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@65555 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Sam Minnee 2008-11-10 23:18:31 +00:00
parent 5c9f0f120b
commit 9565fec5ad
3 changed files with 124 additions and 41 deletions

View File

@ -132,50 +132,81 @@ class YamlFixture extends Object {
$fixtureContent = $parser->load(Director::baseFolder().'/'.$this->fixtureFile);
$this->fixtureDictionary = array();
foreach($fixtureContent as $dataClass => $items) {
foreach($items as $identifier => $fields) {
$obj = new $dataClass();
// If an ID is explicitly passed, then we'll sort out the initial write straight away
// This is just in case field setters triggered by the population code in the next block
// Call $this->write(). (For example, in FileTest)
if(isset($fields['ID'])) {
$obj->ID = $fields['ID'];
$obj->write(false, true);
}
// Populate the dictionary with the ID
foreach($fields as $fieldName => $fieldVal) {
if($obj->many_many($fieldName) || $obj->has_many($fieldName) || $obj->has_one($fieldName)) continue;
$obj->$fieldName = $this->parseFixtureVal($fieldVal);
}
$obj->write();
// has to happen before relations in case a class is referring to itself
$this->fixtureDictionary[$dataClass][$identifier] = $obj->ID;
// Populate all relations
foreach($fields as $fieldName => $fieldVal) {
if($obj->many_many($fieldName) || $obj->has_many($fieldName)) {
$parsedItems = array();
$items = split(' *, *',trim($fieldVal));
foreach($items as $item) {
$parsedItems[] = $this->parseFixtureVal($item);
}
$obj->write();
if($obj->has_many($fieldName)) {
$obj->getComponents($fieldName)->setByIDList($parsedItems);
} elseif($obj->many_many($fieldName)) {
$obj->getManyManyComponents($fieldName)->setByIDList($parsedItems);
}
} elseif($obj->has_one($fieldName)) {
$obj->{$fieldName . 'ID'} = $this->parseFixtureVal($fieldVal);
}
}
$obj->write();
if(ClassInfo::exists($dataClass)) {
$this->writeDataObject($dataClass, $items);
} else {
$this->writeSQL($dataClass, $items);
}
}
}
/**
* Writes the fixture into the database using DataObjects
*
* @param string $dataClass
* @param array $items
*/
protected function writeDataObject($dataClass, $items) {
foreach($items as $identifier => $fields) {
$obj = new $dataClass();
// If an ID is explicitly passed, then we'll sort out the initial write straight away
// This is just in case field setters triggered by the population code in the next block
// Call $this->write(). (For example, in FileTest)
if(isset($fields['ID'])) {
$obj->ID = $fields['ID'];
$obj->write(false, true);
}
// Populate the dictionary with the ID
foreach($fields as $fieldName => $fieldVal) {
if($obj->many_many($fieldName) || $obj->has_many($fieldName) || $obj->has_one($fieldName)) continue;
$obj->$fieldName = $this->parseFixtureVal($fieldVal);
}
$obj->write();
// has to happen before relations in case a class is referring to itself
$this->fixtureDictionary[$dataClass][$identifier] = $obj->ID;
// Populate all relations
foreach($fields as $fieldName => $fieldVal) {
if($obj->many_many($fieldName) || $obj->has_many($fieldName)) {
$parsedItems = array();
$items = split(' *, *',trim($fieldVal));
foreach($items as $item) {
$parsedItems[] = $this->parseFixtureVal($item);
}
$obj->write();
if($obj->has_many($fieldName)) {
$obj->getComponents($fieldName)->setByIDList($parsedItems);
} elseif($obj->many_many($fieldName)) {
$obj->getManyManyComponents($fieldName)->setByIDList($parsedItems);
}
} elseif($obj->has_one($fieldName)) {
$obj->{$fieldName . 'ID'} = $this->parseFixtureVal($fieldVal);
}
}
$obj->write();
}
}
/**
* Writes the fixture into the database directly using a database manipulation
*
* @param string $table
* @param array $items
*/
protected function writeSQL($table, $items) {
foreach($items as $identifier => $fields) {
$manipulation = array($table => array("fields" => array(), "command" => "insert"));
foreach($fields as $fieldName=> $fieldVal) {
$manipulation[$table]["fields"][$fieldName] = "'".$this->parseFixtureVal($fieldVal)."'";
}
DB::manipulate($manipulation);
$this->fixtureDictionary[$table][$identifier] = DB::getGeneratedID($table);
}
}
/**
* Parse a value from a fixture file. If it starts with => it will get an ID from the fixture dictionary
*/
@ -191,4 +222,3 @@ class YamlFixture extends Object {
}
}
}
?>

View File

@ -0,0 +1,30 @@
<?php
class YamlFixtureTest extends SapphireTest {
static $fixture_file = 'sapphire/tests/testing/YamlFixtureTest.yml';
function testSQLInsert() {
$object1 = DataObject::get_by_id("YamlFixtureTest_DataObject", $this->idFromFixture("YamlFixtureTest_DataObject", "testobject1"));
$this->assertTrue($object1->ManyMany()->Count() == 2, "Should be 2 items in this manymany relationship");
$object2 = DataObject::get_by_id("YamlFixtureTest_DataObject", $this->idFromFixture("YamlFixtureTest_DataObject", "testobject2"));
$this->assertTrue($object2->ManyMany()->Count() == 2, "Should be 2 items in this manymany relationship");
}
}
class YamlFixtureTest_DataObject extends DataObject {
static $db = array(
"Name" => "Varchar"
);
static $many_many = array(
"ManyMany" => "YamlFixtureTest_DataObjectRelation"
);
}
class YamlFixtureTest_DataObjectRelation extends DataObject {
static $db = array(
"Name" => "Varchar"
);
static $belongs_many_many = array(
"TestParent" => "YamlFixtureTest_DataObject"
);
}

View File

@ -0,0 +1,23 @@
YamlFixtureTest_DataObject:
testobject1:
Name: TestObject1
testobject2:
Name: TestObject2
YamlFixtureTest_DataObjectRelation:
relation1:
Name: Relation1
relation2:
Name: Relation2
YamlFixtureTest_DataObject_ManyMany:
manymany1:
YamlFixtureTest_DataObjectID: =>YamlFixtureTest_DataObject.testobject1
YamlFixtureTest_DataObjectRelationID: =>YamlFixtureTest_DataObjectRelation.relation1
manymany2:
YamlFixtureTest_DataObjectID: =>YamlFixtureTest_DataObject.testobject1
YamlFixtureTest_DataObjectRelationID: =>YamlFixtureTest_DataObjectRelation.relation2
manymany3:
YamlFixtureTest_DataObjectID: =>YamlFixtureTest_DataObject.testobject2
YamlFixtureTest_DataObjectRelationID: =>YamlFixtureTest_DataObjectRelation.relation1
manymany4:
YamlFixtureTest_DataObjectID: =>YamlFixtureTest_DataObject.testobject2
YamlFixtureTest_DataObjectRelationID: =>YamlFixtureTest_DataObjectRelation.relation2