Commit 90d34063 authored by doctrine's avatar doctrine

Preliminary support for composite primary keys

Many-to-Many alias bug fixed
parent 814eef80
...@@ -128,7 +128,7 @@ class Doctrine_DBStatement extends PDOStatement { ...@@ -128,7 +128,7 @@ class Doctrine_DBStatement extends PDOStatement {
/** /**
* @param array $params * @param array $params
*/ */
public function execute($params) { public function execute(array $params = null) {
$time = microtime(); $time = microtime();
$result = parent::execute($params); $result = parent::execute($params);
......
...@@ -16,5 +16,9 @@ class Doctrine_Identifier { ...@@ -16,5 +16,9 @@ class Doctrine_Identifier {
* constant for normal identifier * constant for normal identifier
*/ */
const NORMAL = 3; const NORMAL = 3;
/**
* constant for composite identifier
*/
const COMPOSITE = 4;
} }
?> ?>
...@@ -127,26 +127,25 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite ...@@ -127,26 +127,25 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
// clean data array // clean data array
$cols = $this->cleanData(); $cols = $this->cleanData();
$this->prepareIdentifiers($exists);
if( ! $exists) { if( ! $exists) {
if($cols > 0) if($cols > 0)
$this->state = Doctrine_Record::STATE_TDIRTY; $this->state = Doctrine_Record::STATE_TDIRTY;
else else
$this->state = Doctrine_Record::STATE_TCLEAN; $this->state = Doctrine_Record::STATE_TCLEAN;
// listen the onCreate event // listen the onCreate event
$this->table->getAttribute(Doctrine::ATTR_LISTENER)->onCreate($this); $this->table->getAttribute(Doctrine::ATTR_LISTENER)->onCreate($this);
} else { } else {
$this->state = Doctrine_Record::STATE_CLEAN; $this->state = Doctrine_Record::STATE_CLEAN;
if($cols <= 1) if($cols <= 1)
$this->state = Doctrine_Record::STATE_PROXY; $this->state = Doctrine_Record::STATE_PROXY;
$this->prepareIdentifiers();
// listen the onLoad event // listen the onLoad event
$this->table->getAttribute(Doctrine::ATTR_LISTENER)->onLoad($this); $this->table->getAttribute(Doctrine::ATTR_LISTENER)->onLoad($this);
...@@ -200,16 +199,26 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite ...@@ -200,16 +199,26 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
* *
* @return void * @return void
*/ */
public function prepareIdentifiers() { private function prepareIdentifiers($exists = true) {
switch($this->table->getIdentifierType()): switch($this->table->getIdentifierType()):
case Doctrine_Identifier::AUTO_INCREMENT: case Doctrine_Identifier::AUTO_INCREMENT:
case Doctrine_Identifier::SEQUENCE: case Doctrine_Identifier::SEQUENCE:
$name = $this->table->getIdentifier(); if($exists) {
$name = $this->table->getIdentifier();
if(isset($this->data[$name]))
$this->id = $this->data[$name]; if(isset($this->data[$name]))
$this->id = $this->data[$name];
unset($this->data[$name]);
}
break;
case Doctrine_Identifier::COMPOSITE:
$names = $this->table->getIdentifier();
$this->id = array();
unset($this->data[$name]); foreach($names as $name) {
$this->id[$name] = isset($this->data[$name])?$this->data[$name]:null;
}
break; break;
endswitch; endswitch;
} }
...@@ -603,10 +612,10 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite ...@@ -603,10 +612,10 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
*/ */
final public function saveAssociations() { final public function saveAssociations() {
foreach($this->table->getForeignKeys() as $fk): foreach($this->table->getForeignKeys() as $fk):
$table = $fk->getTable(); $table = $fk->getTable();
$name = $table->getComponentName(); $name = $table->getComponentName();
$alias = $this->table->getAlias($name);
if($fk instanceof Doctrine_Association) { if($fk instanceof Doctrine_Association) {
switch($fk->getType()): switch($fk->getType()):
case Doctrine_Relation::MANY_COMPOSITE: case Doctrine_Relation::MANY_COMPOSITE:
...@@ -614,15 +623,16 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite ...@@ -614,15 +623,16 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
break; break;
case Doctrine_Relation::MANY_AGGREGATE: case Doctrine_Relation::MANY_AGGREGATE:
$asf = $fk->getAssociationFactory(); $asf = $fk->getAssociationFactory();
if(isset($this->references[$name])) {
$new = $this->references[$name]; if(isset($this->references[$alias])) {
if( ! isset($this->originals[$name])) { $new = $this->references[$alias];
$this->loadReference($name);
if( ! isset($this->originals[$alias])) {
$this->loadReference($alias);
} }
$r = $this->getRelationOperations($name,$new); $r = $this->getRelationOperations($alias,$new);
foreach($r["delete"] as $record) { foreach($r["delete"] as $record) {
$query = "DELETE FROM ".$asf->getTableName()." WHERE ".$fk->getForeign()." = ?" $query = "DELETE FROM ".$asf->getTableName()." WHERE ".$fk->getForeign()." = ?"
...@@ -635,7 +645,7 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite ...@@ -635,7 +645,7 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
$reldao->set($fk->getLocal(),$this); $reldao->set($fk->getLocal(),$this);
$reldao->save(); $reldao->save();
} }
$this->originals[$name] = clone $this->references[$name]; $this->originals[$alias] = clone $this->references[$alias];
} }
break; break;
endswitch; endswitch;
...@@ -644,24 +654,24 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite ...@@ -644,24 +654,24 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
switch($fk->getType()): switch($fk->getType()):
case Doctrine_Relation::ONE_COMPOSITE: case Doctrine_Relation::ONE_COMPOSITE:
if(isset($this->originals[$name]) && $this->originals[$name]->getID() != $this->references[$name]->getID()) if(isset($this->originals[$alias]) && $this->originals[$alias]->getID() != $this->references[$alias]->getID())
$this->originals[$name]->delete(); $this->originals[$alias]->delete();
break; break;
case Doctrine_Relation::MANY_COMPOSITE: case Doctrine_Relation::MANY_COMPOSITE:
if(isset($this->references[$name])) { if(isset($this->references[$alias])) {
$new = $this->references[$name]; $new = $this->references[$alias];
if( ! isset($this->originals[$name])) if( ! isset($this->originals[$alias]))
$this->loadReference($name); $this->loadReference($alias);
$r = $this->getRelationOperations($name,$new); $r = $this->getRelationOperations($alias,$new);
foreach($r["delete"] as $record) { foreach($r["delete"] as $record) {
$record->delete(); $record->delete();
} }
$this->originals[$name] = clone $this->references[$name]; $this->originals[$alias] = clone $this->references[$alias];
} }
break; break;
endswitch; endswitch;
...@@ -675,7 +685,7 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite ...@@ -675,7 +685,7 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
* *
* The algorithm here is very simple and definitely not * The algorithm here is very simple and definitely not
* the fastest one, since we have to iterate through the collections twice. * the fastest one, since we have to iterate through the collections twice.
* the complexity of this algorithm is O(2*n^2) * the complexity of this algorithm is O(n^2)
* *
* First we iterate through the new collection and get the * First we iterate through the new collection and get the
* records that do not exist in the old collection (Doctrine_Records that need to be added). * records that do not exist in the old collection (Doctrine_Records that need to be added).
...@@ -764,6 +774,10 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite ...@@ -764,6 +774,10 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
$this->cleanData(); $this->cleanData();
$this->state = Doctrine_Record::STATE_TCLEAN; $this->state = Doctrine_Record::STATE_TCLEAN;
$this->modified = array(); $this->modified = array();
} elseif($id === true) {
$this->prepareIdentifiers(false);
$this->state = Doctrine_Record::STATE_CLEAN;
$this->modified = array();
} else { } else {
$this->id = $id; $this->id = $id;
$this->state = Doctrine_Record::STATE_CLEAN; $this->state = Doctrine_Record::STATE_CLEAN;
...@@ -771,8 +785,8 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite ...@@ -771,8 +785,8 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
} }
} }
/** /**
* return the primary key this object is pointing at * return the primary key(s) this object is pointing at
* @return int id * @return mixed id
*/ */
final public function getID() { final public function getID() {
return $this->id; return $this->id;
...@@ -916,6 +930,8 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite ...@@ -916,6 +930,8 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
} }
/** /**
* binds One-to-One composite relation
*
* @param string $objTableName * @param string $objTableName
* @param string $fkField * @param string $fkField
* @return void * @return void
...@@ -924,6 +940,8 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite ...@@ -924,6 +940,8 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
$this->table->bind($componentName,$foreignKey,Doctrine_Relation::ONE_COMPOSITE, $localKey); $this->table->bind($componentName,$foreignKey,Doctrine_Relation::ONE_COMPOSITE, $localKey);
} }
/** /**
* binds One-to-Many composite relation
*
* @param string $objTableName * @param string $objTableName
* @param string $fkField * @param string $fkField
* @return void * @return void
...@@ -932,6 +950,8 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite ...@@ -932,6 +950,8 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
$this->table->bind($componentName,$foreignKey,Doctrine_Relation::MANY_COMPOSITE, $localKey); $this->table->bind($componentName,$foreignKey,Doctrine_Relation::MANY_COMPOSITE, $localKey);
} }
/** /**
* binds One-to-One aggregate relation
*
* @param string $objTableName * @param string $objTableName
* @param string $fkField * @param string $fkField
* @return void * @return void
...@@ -940,6 +960,8 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite ...@@ -940,6 +960,8 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
$this->table->bind($componentName,$foreignKey,Doctrine_Relation::ONE_AGGREGATE, $localKey); $this->table->bind($componentName,$foreignKey,Doctrine_Relation::ONE_AGGREGATE, $localKey);
} }
/** /**
* binds One-to-Many aggregate relation
*
* @param string $objTableName * @param string $objTableName
* @param string $fkField * @param string $fkField
* @return void * @return void
...@@ -957,7 +979,7 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite ...@@ -957,7 +979,7 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
} }
/** /**
* setPrimaryKey * setPrimaryKey
* @param string $key * @param mixed $key
*/ */
final public function setPrimaryKey($key) { final public function setPrimaryKey($key) {
$this->table->setPrimaryKey($key); $this->table->setPrimaryKey($key);
...@@ -982,6 +1004,8 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite ...@@ -982,6 +1004,8 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
} }
/** /**
* hasColumn * hasColumn
* sets a column definition
*
* @param string $name * @param string $name
* @param string $type * @param string $type
* @param integer $length * @param integer $length
......
...@@ -155,6 +155,12 @@ class Sensei extends Doctrine_Access { ...@@ -155,6 +155,12 @@ class Sensei extends Doctrine_Access {
return false; return false;
} }
} }
/**
* returns a session variable
*
* @param mixed $name
* @return mixed
*/
public function get($name) { public function get($name) {
foreach($this->vars as $var) { foreach($this->vars as $var) {
if($var->name == $name) { if($var->name == $name) {
...@@ -162,6 +168,14 @@ class Sensei extends Doctrine_Access { ...@@ -162,6 +168,14 @@ class Sensei extends Doctrine_Access {
} }
} }
} }
/**
* sets a session variable
* returns true on success, false on failure
*
* @param mixed $name
* @param mixed $value
* @return boolean
*/
public function set($name,$value) { public function set($name,$value) {
foreach($this->vars as $var) { foreach($this->vars as $var) {
if($var->name == $name) { if($var->name == $name) {
......
...@@ -41,7 +41,7 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab ...@@ -41,7 +41,7 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab
private $transaction_level = 0; private $transaction_level = 0;
/** /**
* @var PDO $cacheHandler * @var PDO $cacheHandler cache handler
*/ */
private $cacheHandler; private $cacheHandler;
/** /**
...@@ -328,7 +328,7 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab ...@@ -328,7 +328,7 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab
} }
/** /**
* clear * clear
* clears the whole registry * clears all repositories
* *
* @return void * @return void
*/ */
...@@ -341,6 +341,7 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab ...@@ -341,6 +341,7 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab
/** /**
* close * close
* closes the session * closes the session
*
* @return void * @return void
*/ */
public function close() { public function close() {
...@@ -353,7 +354,8 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab ...@@ -353,7 +354,8 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab
} }
/** /**
* get the current transaction nesting level * get the current transaction nesting level
* @return integer transaction nesting level *
* @return integer
*/ */
public function getTransactionLevel() { public function getTransactionLevel() {
return $this->transaction_level; return $this->transaction_level;
...@@ -471,16 +473,17 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab ...@@ -471,16 +473,17 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab
$this->insert($record); $this->insert($record);
if($increment) {
if($increment && $k == 0) { if($k == 0) {
// record uses auto_increment column // record uses auto_increment column
$id = $table->getMaxIdentifier(); $id = $table->getMaxIdentifier();
} }
$record->setID($id); $record->setID($id);
$id++;
$id++; } else
$record->setID(true);
// listen the onInsert event // listen the onInsert event
$record->getTable()->getAttribute(Doctrine::ATTR_LISTENER)->onInsert($record); $record->getTable()->getAttribute(Doctrine::ATTR_LISTENER)->onInsert($record);
...@@ -693,14 +696,22 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab ...@@ -693,14 +696,22 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab
} }
$params = array_values($array); $params = array_values($array);
$params[] = $record->getID(); $id = $record->getID();
if( ! is_array($id))
$id = array($id);
$id = array_values($id);
$params = array_merge($params, $id);
$sql = "UPDATE ".$record->getTable()->getTableName()." SET ".implode(", ",$set)." WHERE ".implode(" = ? && ",$record->getTable()->getPrimaryKeys())." = ?"; $sql = "UPDATE ".$record->getTable()->getTableName()." SET ".implode(", ",$set)." WHERE ".implode(" = ? && ",$record->getTable()->getPrimaryKeys())." = ?";
$stmt = $this->dbh->prepare($sql); $stmt = $this->dbh->prepare($sql);
$stmt->execute($params); $stmt->execute($params);
$record->setID($record->getID()); $record->setID(true);
return true; return true;
} }
......
...@@ -77,6 +77,12 @@ class Doctrine_Table extends Doctrine_Configurable { ...@@ -77,6 +77,12 @@ class Doctrine_Table extends Doctrine_Configurable {
* @var array $bound bound relations * @var array $bound bound relations
*/ */
private $bound = array(); private $bound = array();
/**
* @var array $boundAliases bound relation aliases
*/
private $boundAliases = array();
/** /**
* @var array $inheritanceMap inheritanceMap is used for inheritance mapping, keys representing columns and values * @var array $inheritanceMap inheritanceMap is used for inheritance mapping, keys representing columns and values
* the column values that should correspond to child classes * the column values that should correspond to child classes
...@@ -144,37 +150,43 @@ class Doctrine_Table extends Doctrine_Configurable { ...@@ -144,37 +150,43 @@ class Doctrine_Table extends Doctrine_Configurable {
$this->identifierType = Doctrine_Identifier::AUTO_INCREMENT; $this->identifierType = Doctrine_Identifier::AUTO_INCREMENT;
break; break;
default: default:
foreach($this->primaryKeys as $pk) { if(count($this->primaryKeys) > 1) {
$o = $this->columns[$pk][2]; $this->identifier = $this->primaryKeys;
$e = explode("|",$o); $this->identifierType = Doctrine_Identifier::COMPOSITE;
$found = false;
} else {
foreach($this->primaryKeys as $pk) {
foreach($e as $option) { $o = $this->columns[$pk][2];
if($found) $e = explode("|",$o);
break; $found = false;
$e2 = explode(":",$option);
foreach($e as $option) {
switch(strtolower($e2[0])): if($found)
case "unique": break;
$this->identifierType = Doctrine_Identifier::UNIQUE;
$found = true; $e2 = explode(":",$option);
break;
case "autoincrement": switch(strtolower($e2[0])):
$this->identifierType = Doctrine_Identifier::AUTO_INCREMENT; case "unique":
$found = true; $this->identifierType = Doctrine_Identifier::UNIQUE;
break; $found = true;
case "seq": break;
$this->identifierType = Doctrine_Identifier::SEQUENCE; case "autoincrement":
$found = true; $this->identifierType = Doctrine_Identifier::AUTO_INCREMENT;
break; $found = true;
endswitch; break;
case "seq":
$this->identifierType = Doctrine_Identifier::SEQUENCE;
$found = true;
break;
endswitch;
}
if( ! isset($this->identifierType))
$this->identifierType = Doctrine_Identifier::NORMAL;
$this->identifier = $pk;
} }
if( ! isset($this->identifierType))
$this->identifierType = Doctrine_Identifier::NORMAL;
$this->identifier = $pk;
} }
endswitch; endswitch;
...@@ -259,6 +271,20 @@ class Doctrine_Table extends Doctrine_Configurable { ...@@ -259,6 +271,20 @@ class Doctrine_Table extends Doctrine_Configurable {
final public function hasColumn($name) { final public function hasColumn($name) {
return isset($this->columns[$name]); return isset($this->columns[$name]);
} }
/**
* @param mixed $key
* @return void
*/
final public function setPrimaryKey($key) {
switch(gettype($key)):
case "array":
$this->primaryKeys = array_values($key);
break;
case "string":
$this->primaryKeys[] = $key;
break;
endswitch;
}
/** /**
* returns all primary keys * returns all primary keys
* @return array * @return array
...@@ -348,6 +374,32 @@ class Doctrine_Table extends Doctrine_Configurable { ...@@ -348,6 +374,32 @@ class Doctrine_Table extends Doctrine_Configurable {
return $this->bound[$name]; return $this->bound[$name];
} }
/**
* returns a bound relation array
*
* @param string $name
* @return array
*/
final public function getBoundForName($name) {
foreach($this->bound as $k => $bound) {
if($bound[3] == $name) {
return $this->bound[$k];
}
}
throw new InvalidKeyException();
}
/**
* returns the alias for given component name
*
* @param string $name
* @return string
*/
final public function getAlias($name) {
if(isset($this->boundAliases[$name]))
return $this->boundAliases[$name];
return $name;
}
/** /**
* @param string $name * @param string $name
* @param string $field * @param string $field
...@@ -360,11 +412,13 @@ class Doctrine_Table extends Doctrine_Configurable { ...@@ -360,11 +412,13 @@ class Doctrine_Table extends Doctrine_Configurable {
$e = explode(" as ",$name); $e = explode(" as ",$name);
$name = $e[0]; $name = $e[0];
if(isset($e[1])) if(isset($e[1])) {
$alias = $e[1]; $alias = $e[1];
else $this->boundAliases[$name] = $alias;
} else
$alias = $name; $alias = $name;
$this->bound[$alias] = array($field,$type,$localKey,$name); $this->bound[$alias] = array($field,$type,$localKey,$name);
} }
/** /**
...@@ -395,7 +449,6 @@ class Doctrine_Table extends Doctrine_Configurable { ...@@ -395,7 +449,6 @@ class Doctrine_Table extends Doctrine_Configurable {
return $this->relations[$name]; return $this->relations[$name];
if(isset($this->bound[$name])) { if(isset($this->bound[$name])) {
$type = $this->bound[$name][1]; $type = $this->bound[$name][1];
$local = $this->bound[$name][2]; $local = $this->bound[$name][2];
$e = explode(".",$this->bound[$name][0]); $e = explode(".",$this->bound[$name][0]);
...@@ -436,7 +489,7 @@ class Doctrine_Table extends Doctrine_Configurable { ...@@ -436,7 +489,7 @@ class Doctrine_Table extends Doctrine_Configurable {
foreach($classes as $class) { foreach($classes as $class) {
try { try {
$bound = $table->getBound($class); $bound = $table->getBoundForName($class);
break; break;
} catch(InvalidKeyException $exc) { } catch(InvalidKeyException $exc) {
...@@ -517,10 +570,15 @@ class Doctrine_Table extends Doctrine_Configurable { ...@@ -517,10 +570,15 @@ class Doctrine_Table extends Doctrine_Configurable {
*/ */
public function find($id) { public function find($id) {
if($id !== null) { if($id !== null) {
if( ! is_array($id))
$id = array($id);
else
$id = array_values($id);
$query = $this->query." WHERE ".implode(" = ? AND ",$this->primaryKeys)." = ?"; $query = $this->query." WHERE ".implode(" = ? AND ",$this->primaryKeys)." = ?";
$query = $this->applyInheritance($query); $query = $this->applyInheritance($query);
$params = array_merge(array($id), array_values($this->inheritanceMap)); $params = array_merge($id, array_values($this->inheritanceMap));
$this->data = $this->session->execute($query,$params)->fetch(PDO::FETCH_ASSOC); $this->data = $this->session->execute($query,$params)->fetch(PDO::FETCH_ASSOC);
...@@ -588,19 +646,28 @@ class Doctrine_Table extends Doctrine_Configurable { ...@@ -588,19 +646,28 @@ class Doctrine_Table extends Doctrine_Configurable {
*/ */
public function getRecord() { public function getRecord() {
$key = $this->getIdentifier(); $key = $this->getIdentifier();
if(isset($this->data[$key])) {
$id = $this->data[$key];
if(isset($this->identityMap[$id]))
$record = $this->identityMap[$id];
else {
$record = new $this->name($this);
$this->identityMap[$id] = $record;
}
$this->data = array();
return $record; if( ! is_array($key))
$key = array($key);
foreach($key as $k) {
if( ! isset($this->data[$k]))
throw new Doctrine_Exception("No primary key found");
$id[] = $this->data[$k];
}
$id = implode(' ', $id);
if(isset($this->identityMap[$id]))
$record = $this->identityMap[$id];
else {
$record = new $this->name($this);
$this->identityMap[$id] = $record;
} }
throw new Doctrine_Exception("No primary key found"); $this->data = array();
return $record;
} }
/** /**
* @param $id database row id * @param $id database row id
......
<?php <?php
/** /**
* Doctrine_Validator * Doctrine_Validator
* Doctrine_Session uses this class for transaction validation
*
* @package Doctrine ORM
* @url www.phpdoctrine.com
* @license LGPL
*/ */
class Doctrine_Validator { class Doctrine_Validator {
/** /**
...@@ -25,11 +30,11 @@ class Doctrine_Validator { ...@@ -25,11 +30,11 @@ class Doctrine_Validator {
const ERR_UNIQUE = 3; const ERR_UNIQUE = 3;
/** /**
* @var array $stack error stack * @var array $stack error stack
*/ */
private $stack = array(); private $stack = array();
/** /**
* @var array $validators an array of validator objects * @var array $validators an array of validator objects
*/ */
private static $validators = array(); private static $validators = array();
/** /**
......
...@@ -3,13 +3,65 @@ require_once("UnitTestCase.class.php"); ...@@ -3,13 +3,65 @@ require_once("UnitTestCase.class.php");
class Doctrine_RecordTestCase extends Doctrine_UnitTestCase { class Doctrine_RecordTestCase extends Doctrine_UnitTestCase {
public function testCompositePK() {
$record = new EntityReference();
$this->assertEqual($record->getTable()->getIdentifier(), array("entity1","entity2"));
$this->assertEqual($record->getTable()->getIdentifierType(), Doctrine_Identifier::COMPOSITE);
$this->assertEqual($record->getID(), array("entity1" => null, "entity2" => null));
$this->assertEqual($record->getState(), Doctrine_Record::STATE_TCLEAN);
$record->entity1 = 3;
$record->entity2 = 4;
$this->assertEqual($record->entity2, 4);
$this->assertEqual($record->entity1, 3);
$this->assertEqual($record->getState(), Doctrine_Record::STATE_TDIRTY);
$this->assertEqual($record->getID(), array("entity1" => null, "entity2" => null));
$record->save();
$this->assertEqual($record->getState(), Doctrine_Record::STATE_CLEAN);
$this->assertEqual($record->entity2, 4);
$this->assertEqual($record->entity1, 3);
$this->assertEqual($record->getID(), array("entity1" => 3, "entity2" => 4));
$record = $record->getTable()->find($record->getID());
$this->assertEqual($record->getState(), Doctrine_Record::STATE_CLEAN);
$this->assertEqual($record->entity2, 4);
$this->assertEqual($record->entity1, 3);
$this->assertEqual($record->getID(), array("entity1" => 3, "entity2" => 4));
$record->entity2 = 5;
$record->entity1 = 2;
$this->assertEqual($record->getState(), Doctrine_Record::STATE_DIRTY);
$this->assertEqual($record->entity2, 5);
$this->assertEqual($record->entity1, 2);
$this->assertEqual($record->getID(), array("entity1" => 3, "entity2" => 4));
$record->save();
$this->assertEqual($record->getState(), Doctrine_Record::STATE_CLEAN);
$this->assertEqual($record->entity2, 5);
$this->assertEqual($record->entity1, 2);
$this->assertEqual($record->getID(), array("entity1" => 2, "entity2" => 5));
$record = $record->getTable()->find($record->getID());
$this->assertEqual($record->getState(), Doctrine_Record::STATE_CLEAN);
$this->assertEqual($record->entity2, 5);
$this->assertEqual($record->entity1, 2);
$this->assertEqual($record->getID(), array("entity1" => 2, "entity2" => 5));
}
public function testManyToManyTreeStructure() { public function testManyToManyTreeStructure() {
$task = $this->session->create("Task"); $task = $this->session->create("Task");
$this->assertEqual($task->getTable()->getAlias("Resource"), "ResourceAlias");
$task->name = "Task 1"; $task->name = "Task 1";
$task->Resource[0]->name = "Resource 1"; $task->ResourceAlias[0]->name = "Resource 1";
$this->session->flush(); $this->session->flush();
$this->assertTrue($task->ResourceAlias[0] instanceof Resource);
$this->assertEqual($task->ResourceAlias[0]->name, "Resource 1");
$this->assertEqual($this->dbh->query("SELECT COUNT(*) FROM assignment")->fetch(PDO::FETCH_NUM),array(1)); $this->assertEqual($this->dbh->query("SELECT COUNT(*) FROM assignment")->fetch(PDO::FETCH_NUM),array(1));
$task = new Task(); $task = new Task();
...@@ -18,28 +70,28 @@ class Doctrine_RecordTestCase extends Doctrine_UnitTestCase { ...@@ -18,28 +70,28 @@ class Doctrine_RecordTestCase extends Doctrine_UnitTestCase {
$this->assertTrue($task->Subtask[0] instanceof Task); $this->assertTrue($task->Subtask[0] instanceof Task);
$this->assertEqual($task->Subtask[0]->getState(), Doctrine_Record::STATE_TCLEAN); $this->assertEqual($task->Subtask[0]->getState(), Doctrine_Record::STATE_TCLEAN);
$this->assertTrue($task->Resource[0] instanceof Resource); $this->assertTrue($task->ResourceAlias[0] instanceof Resource);
$this->assertEqual($task->Resource[0]->getState(), Doctrine_Record::STATE_TCLEAN); $this->assertEqual($task->ResourceAlias[0]->getState(), Doctrine_Record::STATE_TCLEAN);
$task->name = "Task 1"; $task->name = "Task 1";
$task->Resource[0]->name = "Resource 1"; $task->ResourceAlias[0]->name = "Resource 1";
$task->Subtask[0]->name = "Subtask 1"; $task->Subtask[0]->name = "Subtask 1";
$this->assertEqual($task->name, "Task 1"); $this->assertEqual($task->name, "Task 1");
$this->assertEqual($task->Resource[0]->name, "Resource 1"); $this->assertEqual($task->ResourceAlias[0]->name, "Resource 1");
$this->assertEqual($task->Resource->count(), 1); $this->assertEqual($task->ResourceAlias->count(), 1);
$this->assertEqual($task->Subtask[0]->name, "Subtask 1"); $this->assertEqual($task->Subtask[0]->name, "Subtask 1");
$this->session->flush(); $this->session->flush();
$task = $task->getTable()->find($task->getID()); $task = $task->getTable()->find($task->getID());
$this->assertEqual($task->name, "Task 1"); $this->assertEqual($task->name, "Task 1");
$this->assertEqual($task->Resource[0]->name, "Resource 1"); $this->assertEqual($task->ResourceAlias[0]->name, "Resource 1");
$this->assertEqual($task->Resource->count(), 1); $this->assertEqual($task->ResourceAlias->count(), 1);
$this->assertEqual($task->Subtask[0]->name, "Subtask 1"); $this->assertEqual($task->Subtask[0]->name, "Subtask 1");
} }
public function testOne2OneForeign() { public function testOne2OneForeign() {
...@@ -248,7 +300,7 @@ class Doctrine_RecordTestCase extends Doctrine_UnitTestCase { ...@@ -248,7 +300,7 @@ class Doctrine_RecordTestCase extends Doctrine_UnitTestCase {
$this->assertEqual($e->code,2); $this->assertEqual($e->code,2);
$this->assertEqual($e->message,"changed message"); $this->assertEqual($e->message,"changed message");
$this->assertEqual($e->Description[0]->description, "1st changed description"); $this->assertEqual($e->Description[0]->description, "1st changed description");
$this->assertEqual($e->Description[1]->description, "2nd changed description"); $this->assertEqual($e->Description[1]->description, "2nd changed description");
} }
public function testInsert() { public function testInsert() {
...@@ -553,5 +605,6 @@ class Doctrine_RecordTestCase extends Doctrine_UnitTestCase { ...@@ -553,5 +605,6 @@ class Doctrine_RecordTestCase extends Doctrine_UnitTestCase {
$user = $this->session->getTable("User")->find(4); $user = $this->session->getTable("User")->find(4);
$this->assertTrue($user->getIterator() instanceof ArrayIterator); $this->assertTrue($user->getIterator() instanceof ArrayIterator);
} }
} }
?> ?>
...@@ -92,11 +92,16 @@ class Sensei_UnitTestCase extends UnitTestCase { ...@@ -92,11 +92,16 @@ class Sensei_UnitTestCase extends UnitTestCase {
$this->assertEqual($this->record->entity_id, 1); $this->assertEqual($this->record->entity_id, 1);
} }
public function testLogout() { public function testLogout() {
$this->assertTrue($this->sensei->logout()); $this->assertTrue($this->sensei->logout());
$this->assertEqual($this->record->logged_in, 0); $this->assertEqual($this->record->logged_in, 0);
$this->assertEqual($this->record->entity_id, 0); $this->assertEqual($this->record->entity_id, 0);
$this->assertEqual($this->record->getState(), Doctrine_Record::STATE_DIRTY);
$this->assertEqual($this->record->getTable()->getIdentifierType(), Doctrine_Identifier::AUTO_INCREMENT);
$this->assertEqual($this->record->getID(), 1);
$this->sensei->flush(); $this->sensei->flush();
...@@ -104,5 +109,6 @@ class Sensei_UnitTestCase extends UnitTestCase { ...@@ -104,5 +109,6 @@ class Sensei_UnitTestCase extends UnitTestCase {
$this->assertEqual($this->record->entity_id, 0); $this->assertEqual($this->record->entity_id, 0);
} }
} }
?> ?>
...@@ -31,7 +31,7 @@ class Doctrine_UnitTestCase extends UnitTestCase { ...@@ -31,7 +31,7 @@ class Doctrine_UnitTestCase extends UnitTestCase {
$this->manager->setAttribute(Doctrine::ATTR_CACHE, Doctrine::CACHE_NONE); $this->manager->setAttribute(Doctrine::ATTR_CACHE, Doctrine::CACHE_NONE);
$this->manager->setAttribute(Doctrine::ATTR_FETCHMODE, Doctrine::FETCH_IMMEDIATE); $this->manager->setAttribute(Doctrine::ATTR_FETCHMODE, Doctrine::FETCH_IMMEDIATE);
$this->tables = array("entity","email","phonenumber","groupuser","album","song","element","error","description","address","account","task","resource","assignment"); $this->tables = array("entity","entityReference","email","phonenumber","groupuser","album","song","element","error","description","address","account","task","resource","assignment");
......
...@@ -16,7 +16,13 @@ class Entity extends Doctrine_Record { ...@@ -16,7 +16,13 @@ class Entity extends Doctrine_Record {
$this->hasColumn("email_id","integer"); $this->hasColumn("email_id","integer");
} }
} }
class EntityReference extends Doctrine_Record {
public function setTableDefinition() {
$this->hasColumn("entity1","integer");
$this->hasColumn("entity2","integer");
$this->setPrimaryKey(array("entity1","entity2"));
}
}
class Account extends Doctrine_Record { class Account extends Doctrine_Record {
public function setTableDefinition() { public function setTableDefinition() {
$this->hasColumn("entity_id","integer"); $this->hasColumn("entity_id","integer");
...@@ -128,7 +134,7 @@ class Song extends Doctrine_Record { ...@@ -128,7 +134,7 @@ class Song extends Doctrine_Record {
class Task extends Doctrine_Record { class Task extends Doctrine_Record {
public function setUp() { public function setUp() {
$this->hasMany("Resource","Assignment.resource_id"); $this->hasMany("Resource as ResourceAlias","Assignment.resource_id");
$this->hasMany("Task as Subtask","Subtask.parent_id"); $this->hasMany("Task as Subtask","Subtask.parent_id");
} }
public function setTableDefinition() { public function setTableDefinition() {
...@@ -139,11 +145,11 @@ class Task extends Doctrine_Record { ...@@ -139,11 +145,11 @@ class Task extends Doctrine_Record {
class Resource extends Doctrine_Record { class Resource extends Doctrine_Record {
public function setUp() { public function setUp() {
$this->hasMany("Task","Assignment.task_id"); $this->hasMany("Task as TaskAlias","Assignment.task_id");
} }
public function setTableDefinition() { public function setTableDefinition() {
$this->hasColumn("name","string",100); $this->hasColumn("name","string",100);
} }
} }
class Assignment extends Doctrine_Record { class Assignment extends Doctrine_Record {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment