1
0
mirror of synced 2024-12-05 03:06:05 +03:00

Custom primary key column support

This commit is contained in:
doctrine 2006-04-23 08:12:01 +00:00
parent 1cc0c764c3
commit 7327d3b69e
22 changed files with 342 additions and 193 deletions

View File

@ -59,9 +59,17 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
public function getTable() {
return $this->table;
}
/**
* whether or not an offset batch has been expanded
* @return boolean
*/
public function isExpanded($offset) {
return isset($this->expanded[$offset]);
}
/**
* whether or not this collection is expandable
* @return boolean
*/
public function isExpandable() {
return $this->expandable;
}
@ -175,7 +183,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
$ids = $this->getPrimaryKeys();
if( ! empty($ids)) {
$where[] = "id NOT IN (".substr(str_repeat("?, ",count($ids)),0,-2).")";
$where[] = $this->table->getIdentifier()." NOT IN (".substr(str_repeat("?, ",count($ids)),0,-2).")";
$params = array_merge($params,$ids);
}
@ -191,7 +199,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
$table = $fk->getTable();
$graph = new Doctrine_DQL_Parser($table->getSession());
$q = "FROM ".$table->getComponentName()." WHERE ".$table->getComponentName().".id IN ($query)";
$q = "FROM ".$table->getComponentName()." WHERE ".$table->getComponentName().".".$table->getIdentifier()." IN ($query)";
}
}
@ -291,9 +299,11 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
*/
public function getPrimaryKeys() {
$list = array();
$name = $this->table->getIdentifier();
foreach($this->data as $record):
if(is_array($record) && isset($record['id'])) {
$list[] = $record['id'];
if(is_array($record) && isset($record[$name])) {
$list[] = $record[$name];
} else {
$list[] = $record->getID();
}

View File

@ -53,13 +53,14 @@ class Doctrine_Collection_Batch extends Doctrine_Collection {
return false;
$id = $record->getID();
$identifier = $this->table->getIdentifier();
foreach($this->data as $key => $v) {
if(is_object($v)) {
if($v->getID() == $id)
break;
} elseif(is_array($v["id"])) {
if($v["id"] == $id)
} elseif(is_array($v[$identifier])) {
if($v[$identifier] == $id)
break;
}
}
@ -77,7 +78,7 @@ class Doctrine_Collection_Batch extends Doctrine_Collection {
if(is_object($this->data[$i]))
$id = $this->data[$i]->getID();
elseif(is_array($this->data[$i]))
$id = $this->data[$i]["id"];
$id = $this->data[$i][$identifier];
$a[$i] = $id;
@ -87,11 +88,10 @@ class Doctrine_Collection_Batch extends Doctrine_Collection {
$pk = $this->table->getPrimaryKeys();
$query = $this->table->getQuery()." WHERE ";
$query .= ($c > 1)?$pk[0]." IN (":$pk[0]." = ";
$query .= ($c > 1)?$identifier." IN (":$pk[0]." = ";
$query .= substr(str_repeat("?, ",count($a)),0,-2);
$query .= ($c > 1)?") ORDER BY ".$pk[0]." ASC":"";
$stmt = $this->table->getSession()->execute($query,array_values($a));
foreach($a as $k => $id) {

View File

@ -66,9 +66,9 @@ class Doctrine_DB extends PDO implements Countable, IteratorAggregate {
try {
$this->queries[] = $query;
$time = microtime();
$stmt = parent::query($query);
$this->exectimes[] = (microtime() - $time);
return $stmt;
} catch(PDOException $e) {

View File

@ -348,7 +348,7 @@ class Doctrine_DQL_Parser {
* remove duplicated data rows and map data into objects
*/
foreach($data as $key => $row):
if(empty($row) || empty($row['id']))
if(empty($row))
continue;
$key = ucwords($key);
@ -725,23 +725,24 @@ class Doctrine_DQL_Parser {
$reference = implode(".",$a);
$objTable = $this->session->getTable(end($a));
$where = $objTable->getTableName().".".$field." ".$operator." ".$value;
if(count($a) > 1 && isset($a[1])) {
$root = $a[0];
$fk = $this->tnames[$root]->getForeignKey($a[1]);
if($fk instanceof Doctrine_Association) {
$asf = $fk->getAssociationFactory();
switch($fk->getType()):
case Doctrine_Table::ONE_AGGREGATE:
case Doctrine_Table::ONE_COMPOSITE:
case Doctrine_Relation::ONE_AGGREGATE:
case Doctrine_Relation::ONE_COMPOSITE:
break;
case Doctrine_Table::MANY_AGGREGATE:
case Doctrine_Table::MANY_COMPOSITE:
case Doctrine_Relation::MANY_AGGREGATE:
case Doctrine_Relation::MANY_COMPOSITE:
$b = array_shift($a);
$b = array_shift($a);
$graph = new Doctrine_DQL_Parser($this->session);
$graph->parseQuery("FROM $b-l WHERE $where");
$where = $this->tnames[$root]->getTableName().".id IN (SELECT ".$fk->getLocal()." FROM ".$asf->getTableName()." WHERE ".$fk->getForeign()." IN (".$graph->getQuery()."))";
$where = $this->tnames[$root]->getTableName().".".$this->tnames[$root]->getIdentifier()." IN (SELECT ".$fk->getLocal()." FROM ".$asf->getTableName()." WHERE ".$fk->getForeign()." IN (".$graph->getQuery()."))";
break;
endswitch;
} else
@ -782,15 +783,15 @@ class Doctrine_DQL_Parser {
if($fk instanceof Doctrine_ForeignKey ||
$fk instanceof Doctrine_LocalKey) {
switch($fk->getType()):
case Doctrine_Table::ONE_AGGREGATE:
case Doctrine_Table::ONE_COMPOSITE:
case Doctrine_Relation::ONE_AGGREGATE:
case Doctrine_Relation::ONE_COMPOSITE:
$this->where[] = "(".$tname.".".$fk->getLocal()." = ".$tname2.".".$fk->getForeign().")";
$this->from[$tname] = true;
$this->from[$tname2] = true;
break;
case Doctrine_Table::MANY_AGGREGATE:
case Doctrine_Table::MANY_COMPOSITE:
case Doctrine_Relation::MANY_AGGREGATE:
case Doctrine_Relation::MANY_COMPOSITE:
$this->join[$tname] = "LEFT JOIN ".$tname2." ON ".$tname.".".$fk->getLocal()." = ".$tname2.".".$fk->getForeign();
$this->joined[] = $tname2;
$this->from[$tname] = true;
@ -800,12 +801,12 @@ class Doctrine_DQL_Parser {
$asf = $fk->getAssociationFactory();
switch($fk->getType()):
case Doctrine_Table::ONE_AGGREGATE:
case Doctrine_Table::ONE_COMPOSITE:
case Doctrine_Relation::ONE_AGGREGATE:
case Doctrine_Relation::ONE_COMPOSITE:
break;
case Doctrine_Table::MANY_AGGREGATE:
case Doctrine_Table::MANY_COMPOSITE:
case Doctrine_Relation::MANY_AGGREGATE:
case Doctrine_Relation::MANY_COMPOSITE:
//$this->addWhere("SELECT ".$fk->getLocal()." FROM ".$asf->getTableName()." WHERE ".$fk->getForeign()." IN (SELECT ".$fk->getTable()->getComponentName().")");
$this->from[$tname] = true;

View File

@ -16,7 +16,7 @@ class Doctrine_DataDict {
public function createTable($tablename, $columns) {
foreach($columns as $name => $args) {
$r[] = $name." ".$this->getADOType($args[0],$args[1])." ".$args[2];
$r[] = $name." ".$this->getADOType($args[0],$args[1])." ".str_replace("|"," ",$args[2]);
}

View File

@ -0,0 +1,20 @@
<?php
class Doctrine_Identifier {
/**
* constant for unique identifier
*/
const UNIQUE = 0;
/**
* constant for auto_increment identifier
*/
const AUTO_INCREMENT = 1;
/**
* constant for sequence identifier
*/
const SEQUENCE = 2;
/**
* constant for normal identifier
*/
const NORMAL = 3;
}
?>

View File

@ -6,7 +6,9 @@ require_once("EventListener.class.php");
* @package Doctrine ORM
* @url www.phpdoctrine.com
* @license LGPL
* @version 1.0 alpha
*
* Doctrine_Manager is the base component of all doctrine based projects.
* It opens and keeps track of all sessions (database connections).
*/
class Doctrine_Manager extends Doctrine_Configurable implements Countable, IteratorAggregate {
/**
@ -26,7 +28,6 @@ class Doctrine_Manager extends Doctrine_Configurable implements Countable, Itera
*/
private $root;
/**
* constructor
*/
@ -63,13 +64,16 @@ class Doctrine_Manager extends Doctrine_Configurable implements Countable, Itera
}
}
/**
* @return string the root directory of Doctrine
* returns the root directory of Doctrine
* @return string
*/
final public function getRoot() {
return $this->root;
}
/**
* getInstance this class uses the singleton pattern
* getInstance
* this class uses the singleton pattern
* @return Doctrine_Manager
*/
final public static function getInstance() {
static $instance;
@ -80,10 +84,12 @@ class Doctrine_Manager extends Doctrine_Configurable implements Countable, Itera
}
/**
* openSession open a new session and save it to Doctrine_Manager->sessions
* @param PDO $pdo PDO database driver
* @param string $name name of the session, if empty numeric key is used
* @return Doctrine_Session the opened session object
* openSession
* opens a new session and saves it to Doctrine_Manager->sessions
*
* @param PDO $pdo PDO database driver
* @param string $name name of the session, if empty numeric key is used
* @return Doctrine_Session
*/
final public function openSession(PDO $pdo, $name = null) {
// initialize the default attributes
@ -158,7 +164,7 @@ class Doctrine_Manager extends Doctrine_Configurable implements Countable, Itera
}
/**
* setCurrentSession
* @param mixed $key the session key
* @param mixed $key the session key
* @throws InvalidKeyException
* @return void
*/
@ -171,13 +177,14 @@ class Doctrine_Manager extends Doctrine_Configurable implements Countable, Itera
}
/**
* count
* @return integer the number of open sessions
* @return integer the number of open sessions
*/
public function count() {
return count($this->sessions);
}
/**
* getIterator
* returns an ArrayIterator that iterates through open sessions
* @return ArrayIterator
*/
public function getIterator() {
@ -185,7 +192,9 @@ class Doctrine_Manager extends Doctrine_Configurable implements Countable, Itera
}
/**
* getCurrentSession
* @return object Doctrine_Session
* returns the current session
* @throws Doctrine_Session_Exception if there are no open sessions
* @return Doctrine_Session
*/
final public function getCurrentSession() {
$i = $this->currIndex;
@ -196,6 +205,8 @@ class Doctrine_Manager extends Doctrine_Configurable implements Countable, Itera
}
/**
* __toString
* returns a string representation of this object
* @return string
*/
public function __toString() {
$r[] = "<pre>";

View File

@ -117,6 +117,7 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
self::$index++;
$keys = $this->table->getPrimaryKeys();
if( ! $exists) {
// listen the onPreCreate event
@ -151,26 +152,15 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
else
$this->loaded = true;
// id property is protected
$keys = $this->table->getPrimaryKeys();
if(count($keys) == 1) {
$this->id = $this->data[$keys[0]];
} else {
/**
$this->id = array();
foreach($keys as $key) {
$this->id[] = $this->data[$key];
}
*/
}
$this->prepareIdentifiers();
// listen the onLoad event
$this->table->getAttribute(Doctrine::ATTR_LISTENER)->onLoad($this);
}
// add data access object to registry
$this->table->getRepository()->add($this);
unset($this->data['id']);
$this->table->setData(array());
}
@ -189,6 +179,8 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
}
/**
* isLoaded
* whether or not this object has been fully loaded
* @return boolean
*/
public function isLoaded() {
return $this->loaded;
@ -221,6 +213,22 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
return $cols;
}
/**
* @return void
*/
public function prepareIdentifiers() {
switch($this->table->getIdentifierType()):
case Doctrine_Identifier::AUTO_INCREMENT:
case Doctrine_Identifier::SEQUENCE:
$name = $this->table->getIdentifier();
if(isset($this->data[$name]))
$this->id = $this->data[$name];
unset($this->data[$name]);
break;
endswitch;
}
/**
* this method is automatically called when this Doctrine_Record is serialized
*/
@ -269,9 +277,8 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
$this->cleanData();
unset($this->data['id']);
//unset($this->data['id']);
$this->table->getAttribute(Doctrine::ATTR_LISTENER)->onWakeUp($this);
}
@ -322,10 +329,12 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
$query = $this->table->getQuery()." WHERE ".implode(" = ? && ",$this->table->getPrimaryKeys())." = ?";
$this->data = $this->table->getSession()->execute($query,array($this->getID()))->fetch(PDO::FETCH_ASSOC);
unset($this->data["id"]);
$this->modified = array();
$this->cleanData();
$this->prepareIdentifiers();
$this->loaded = true;
$this->state = Doctrine_Record::STATE_CLEAN;
@ -338,15 +347,17 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
*/
final public function factoryRefresh() {
$data = $this->table->getData();
$id = $this->id;
$this->prepareIdentifiers();
if($this->id != $data["id"])
if($this->id != $id)
throw new Doctrine_Refresh_Exception();
$this->data = $data;
$this->cleanData();
unset($this->data["id"]);
$this->state = Doctrine_Record::STATE_CLEAN;
$this->modified = array();
$this->loaded = true;
@ -404,7 +415,7 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
}
return $this->data[$name];
}
if($name == "id")
if($name == $this->table->getIdentifier())
return $this->id;
if( ! isset($this->references[$name]))
@ -479,21 +490,21 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
if($fk instanceof Doctrine_ForeignKey ||
$fk instanceof Doctrine_LocalKey) {
switch($fk->getType()):
case Doctrine_Table::MANY_COMPOSITE:
case Doctrine_Table::MANY_AGGREGATE:
case Doctrine_Relation::MANY_COMPOSITE:
case Doctrine_Relation::MANY_AGGREGATE:
// one-to-many relation found
if( ! ($value instanceof Doctrine_Collection))
throw new Doctrine_Exception("Couldn't call Doctrine::set(), second argument should be an instance of Doctrine_Collection when setting one-to-many references.");
$value->setReference($this,$fk);
break;
case Doctrine_Table::ONE_COMPOSITE:
case Doctrine_Table::ONE_AGGREGATE:
case Doctrine_Relation::ONE_COMPOSITE:
case Doctrine_Relation::ONE_AGGREGATE:
// one-to-one relation found
if( ! ($value instanceof Doctrine_Record))
throw new Doctrine_Exception("Couldn't call Doctrine::set(), second argument should be an instance of Doctrine_Record when setting one-to-one references.");
if($fk->getLocal() == "id") {
if($fk->getLocal() == $this->table->getIdentifier()) {
$this->references[$name]->set($fk->getForeign(),$this);
} else {
$this->set($fk->getLocal(),$value);
@ -561,6 +572,28 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
}
return $a;
}
/**
* returns an array of modified fields and values with data preparation
* adds column aggregation inheritance and converts Records into primary key values
*
* @return array
*/
final public function getPrepared() {
$a = array();
foreach($this->table->getInheritanceMap() as $k => $v) {
$this->set($k,$v);
}
foreach($this->modified as $k => $v) {
if($this->data[$v] instanceof Doctrine_Record) {
$this->data[$v] = $this->data[$v]->getID();
}
$a[$v] = $this->data[$v];
}
return $a;
}
/**
* this class implements countable interface
* @return integer the number of columns
@ -589,10 +622,10 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
if($fk instanceof Doctrine_Association) {
switch($fk->getType()):
case Doctrine_Table::MANY_COMPOSITE:
case Doctrine_Relation::MANY_COMPOSITE:
break;
case Doctrine_Table::MANY_AGGREGATE:
case Doctrine_Relation::MANY_AGGREGATE:
$asf = $fk->getAssociationFactory();
if(isset($this->references[$name])) {
@ -623,12 +656,12 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
$fk instanceof Doctrine_LocalKey) {
switch($fk->getType()):
case Doctrine_Table::ONE_COMPOSITE:
case Doctrine_Relation::ONE_COMPOSITE:
if(isset($this->originals[$name]) && $this->originals[$name]->getID() != $this->references[$name]->getID())
$this->originals[$name]->delete();
break;
case Doctrine_Table::MANY_COMPOSITE:
case Doctrine_Relation::MANY_COMPOSITE:
if(isset($this->references[$name])) {
$new = $this->references[$name];
@ -808,8 +841,8 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
case Doctrine_Record::STATE_TDIRTY:
case Doctrine_Record::STATE_TCLEAN:
if($type == Doctrine_Table::ONE_COMPOSITE ||
$type == Doctrine_Table::ONE_AGGREGATE) {
if($type == Doctrine_Relation::ONE_COMPOSITE ||
$type == Doctrine_Relation::ONE_AGGREGATE) {
// ONE-TO-ONE
$this->references[$name] = $table->create();
@ -833,8 +866,8 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
case Doctrine_Record::STATE_CLEAN:
case Doctrine_Record::STATE_PROXY:
switch($fk->getType()):
case Doctrine_Table::ONE_COMPOSITE:
case Doctrine_Table::ONE_AGGREGATE:
case Doctrine_Relation::ONE_COMPOSITE:
case Doctrine_Relation::ONE_AGGREGATE:
// ONE-TO-ONE
$id = $this->get($local);
@ -855,7 +888,8 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
$this->references[$name] = $table->create();
$this->references[$name]->set($fk->getForeign(), $this);
} else {
$coll = $graph->query("FROM ".$name." WHERE ".$name.".".$fk->getForeign()." = ?", array($id));
$dql = "FROM ".$name." WHERE ".$name.".".$fk->getForeign()." = ?";
$coll = $graph->query($dql, array($id));
$this->references[$name] = $coll[0];
$this->references[$name]->set($fk->getForeign(), $this);
}
@ -864,7 +898,7 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
default:
// ONE-TO-MANY
if($fk instanceof Doctrine_ForeignKey) {
$id = $this->get($local);
$id = $this->get($local);
$query = "FROM ".$name." WHERE ".$name.".".$fk->getForeign()." = ?";
$coll = $graph->query($query,array($id));
@ -880,7 +914,7 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
$query = "SELECT ".$foreign." FROM ".$asf->getTableName()." WHERE ".$local." = ?";
$graph = new Doctrine_DQL_Parser($table->getSession());
$query = "FROM ".$table->getComponentName()." WHERE ".$table->getComponentName().".id IN ($query)";
$query = "FROM ".$table->getComponentName()." WHERE ".$table->getComponentName().".".$table->getIdentifier()." IN ($query)";
$coll = $graph->query($query, array($this->getID()));
@ -898,32 +932,32 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
* @param string $fkField
* @return void
*/
final public function ownsOne($componentName,$foreignKey, $localKey = "id") {
$this->table->bind($componentName,$foreignKey,Doctrine_Table::ONE_COMPOSITE, $localKey);
final public function ownsOne($componentName,$foreignKey, $localKey = null) {
$this->table->bind($componentName,$foreignKey,Doctrine_Relation::ONE_COMPOSITE, $localKey);
}
/**
* @param string $objTableName
* @param string $fkField
* @return void
*/
final public function ownsMany($componentName,$foreignKey, $localKey = "id") {
$this->table->bind($componentName,$foreignKey,Doctrine_Table::MANY_COMPOSITE, $localKey);
final public function ownsMany($componentName,$foreignKey, $localKey = null) {
$this->table->bind($componentName,$foreignKey,Doctrine_Relation::MANY_COMPOSITE, $localKey);
}
/**
* @param string $objTableName
* @param string $fkField
* @return void
*/
final public function hasOne($componentName,$foreignKey, $localKey = "id") {
$this->table->bind($componentName,$foreignKey,Doctrine_Table::ONE_AGGREGATE, $localKey);
final public function hasOne($componentName,$foreignKey, $localKey = null) {
$this->table->bind($componentName,$foreignKey,Doctrine_Relation::ONE_AGGREGATE, $localKey);
}
/**
* @param string $objTableName
* @param string $fkField
* @return void
*/
final public function hasMany($componentName,$foreignKey, $localKey = "id") {
$this->table->bind($componentName,$foreignKey,Doctrine_Table::MANY_AGGREGATE, $localKey);
final public function hasMany($componentName,$foreignKey, $localKey = null) {
$this->table->bind($componentName,$foreignKey,Doctrine_Relation::MANY_AGGREGATE, $localKey);
}
/**
* setInheritanceMap

View File

@ -10,6 +10,28 @@
*
*/
class Doctrine_Relation {
/**
* RELATION CONSTANTS
*/
/**
* constant for ONE_TO_ONE and MANY_TO_ONE aggregate relationships
*/
const ONE_AGGREGATE = 0;
/**
* constant for ONE_TO_ONE and MANY_TO_ONE composite relationships
*/
const ONE_COMPOSITE = 1;
/**
* constant for MANY_TO_MANY and ONE_TO_MANY aggregate relationships
*/
const MANY_AGGREGATE = 2;
/**
* constant for MANY_TO_MANY and ONE_TO_MANY composite relationships
*/
const MANY_COMPOSITE = 3;
/**
* @var Doctrine_Table $table foreign factory
*/
@ -39,7 +61,6 @@ class Doctrine_Relation {
$this->type = $type;
}
/**
* @see Doctrine_Table::BIND_ONE, Doctrine_Table::BIND_MANY
* @return integer bind type 1 or 0
*/
public function getType() {

View File

@ -47,7 +47,7 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab
* @var array $tables an array containing all the initialized Doctrine_Table objects
* keys representing Doctrine_Table component names and values as Doctrine_Table objects
*/
protected $tables = array();
protected $tables = array();
/**
* @var Doctrine_Validator $validator transaction validator
*/
@ -299,7 +299,8 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab
}
}
/**
* clear -- clears the whole registry
* clear
* clears the whole registry
* @return void
*/
public function clear() {
@ -415,7 +416,7 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab
if(empty($this->insert))
return false;
foreach($this->insert as $name => $inserts) {
if( ! isset($inserts[0]))
@ -427,11 +428,11 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab
$increment = false;
$id = null;
$keys = $table->getPrimaryKeys();
if(count($keys) == 1 && $keys[0] == "id") {
if(count($keys) == 1 && $keys[0] == $table->getIdentifier()) {
// record uses auto_increment column
$sql = "SELECT MAX(id) FROM ".$record->getTable()->getTableName();
$sql = "SELECT MAX(".$table->getIdentifier().") FROM ".$record->getTable()->getTableName();
$stmt = $this->dbh->query($sql);
$data = $stmt->fetch(PDO::FETCH_NUM);
$id = $data[0];
@ -474,10 +475,10 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab
$keys = $table->getPrimaryKeys();
$tablename = $table->getTableName();
if(count($keys) == 1 && $keys[0] == "id") {
if(count($keys) == 1 && $keys[0] == $table->getIdentifier()) {
// record uses auto_increment column
$sql = "SELECT MAX(id) FROM ".$tablename;
$sql = "SELECT MAX(".$table->getIdentifier().") FROM ".$tablename;
$stmt = $this->dbh->query($sql);
$data = $stmt->fetch(PDO::FETCH_NUM);
$values[$tablename] = $data[0];
@ -521,14 +522,16 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab
public function bulkDelete() {
foreach($this->delete as $name => $deletes) {
$record = false;
$ids = array();
$ids = array();
foreach($deletes as $k => $record) {
$ids[] = $record->getID();
$record->setID(null);
}
if($record instanceof Doctrine_Record) {
$table = $record->getTable();
$params = substr(str_repeat("?, ",count($ids)),0,-2);
$query = "DELETE FROM ".$record->getTable()->getTableName()." WHERE id IN(".$params.")";
$query = "DELETE FROM ".$record->getTable()->getTableName()." WHERE ".$table->getIdentifier()." IN(".$params.")";
$this->execute($query,$ids);
$record->getTable()->getCache()->deleteMultiple($ids);
@ -592,8 +595,8 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab
if($fk instanceof Doctrine_ForeignKey ||
$fk instanceof Doctrine_LocalKey) {
switch($fk->getType()):
case Doctrine_Table::ONE_COMPOSITE:
case Doctrine_Table::MANY_COMPOSITE:
case Doctrine_Relation::ONE_COMPOSITE:
case Doctrine_Relation::MANY_COMPOSITE:
$local = $fk->getLocal();
$foreign = $fk->getForeign();
@ -630,11 +633,10 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab
*/
private function update(Doctrine_Record $record) {
$array = $record->getModified();
if(empty($array))
return false;
$set = array();
foreach($array as $name => $value):
$set[] = $name." = ?";
@ -668,26 +670,16 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab
* @return boolean
*/
private function insert(Doctrine_Record $record,$id = null) {
$array = $record->getModified();
$array = $record->getPrepared();
if(empty($array))
return false;
foreach($record->getTable()->getInheritanceMap() as $k=>$v):
$array[$k] = $v;
endforeach;
$seq = $record->getTable()->getSequenceName();
if( ! empty($seq)) {
$id = $this->getNextID($seq);
$array["id"] = $id;
}
foreach($array as $k => $value) {
if($value instanceof Doctrine_Record) {
$array[$k] = $value->getID();
$record->set($k,$value->getID());
}
$id = $this->getNextID($seq);
$name = $record->getTable()->getIdentifier();
$array[$name] = $id;
}
if(isset($this->validator)) {
@ -717,8 +709,8 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab
final public function deleteComposites(Doctrine_Record $record) {
foreach($record->getTable()->getForeignKeys() as $fk) {
switch($fk->getType()):
case Doctrine_Table::ONE_COMPOSITE:
case Doctrine_Table::MANY_COMPOSITE:
case Doctrine_Relation::ONE_COMPOSITE:
case Doctrine_Relation::MANY_COMPOSITE:
$obj = $record->get($fk->getTable()->getComponentName());
$obj->delete();
break;

View File

@ -48,10 +48,10 @@ class Doctrine_Session_Mysql extends Doctrine_Session_Common {
$keys = $table->getPrimaryKeys();
$tablename = $table->getTableName();
if(count($keys) == 1 && $keys[0] == "id") {
if(count($keys) == 1 && $keys[0] == $table->getIdentifier()) {
// record uses auto_increment column
$sql[] = "SELECT MAX(".$tablename.".id) as $tablename FROM ".$tablename;
$sql[] = "SELECT MAX(".$tablename.".".$table->getIdentifier().") as $tablename FROM ".$tablename;
$values[$tablename] = 0;
$array[] = $tablename;
}
@ -85,11 +85,11 @@ class Doctrine_Session_Mysql extends Doctrine_Session_Common {
$increment = false;
$id = null;
$keys = $table->getPrimaryKeys();
if(count($keys) == 1 && $keys[0] == "id") {
if(count($keys) == 1 && $keys[0] == $table->getIdentifier()) {
// record uses auto_increment column
$sql = "SELECT MAX(id) FROM ".$record->getTable()->getTableName();
$sql = "SELECT MAX(".$table->getIdentifier().") FROM ".$record->getTable()->getTableName();
$stmt = $this->getDBH()->query($sql);
$data = $stmt->fetch(PDO::FETCH_NUM);
$id = $data[0];
@ -111,20 +111,8 @@ class Doctrine_Session_Mysql extends Doctrine_Session_Common {
$id++;
}
$array = $record->getPrepared();
$array = $record->getModified();
foreach($record->getTable()->getInheritanceMap() as $k=>$v):
$array[$k] = $v;
endforeach;
foreach($array as $k => $value) {
if($value instanceof Doctrine_Record) {
$array[$k] = $value->getID();
$record->set($k,$value->getID());
}
}
if(isset($this->validator)) {
if( ! $this->validator->validateRecord($record)) {
continue;

View File

@ -12,23 +12,6 @@ require_once("Configurable.class.php");
* @version 1.0 alpha
*/
class Doctrine_Table extends Doctrine_Configurable {
/**
* constant for ONE_TO_ONE and MANY_TO_ONE aggregate relationships
*/
const ONE_AGGREGATE = 0;
/**
* constant for ONE_TO_ONE and MANY_TO_ONE composite relationships
*/
const ONE_COMPOSITE = 1;
/**
* constant for MANY_TO_MANY and ONE_TO_MANY aggregate relationships
*/
const MANY_AGGREGATE = 2;
/**
* constant for MANY_TO_MANY and ONE_TO_MANY composite relationships
*/
const MANY_COMPOSITE = 3;
/**
* @var boolean $isNewEntry whether ot not this table created a new record or not, used only internally
*/
@ -46,9 +29,13 @@ class Doctrine_Table extends Doctrine_Configurable {
*/
private $primaryKeys = array();
/**
* @var integer $primaryType
* @var mixed $identifier
*/
private $primaryType;
private $identifier;
/**
* @var integer $identifierType
*/
private $identifierType;
/**
* @var string $query cached simple query
*/
@ -117,7 +104,7 @@ class Doctrine_Table extends Doctrine_Configurable {
throw new Doctrine_Exception("Couldn't find class $name");
$record = new $name($this);
$record->setUp();
$names = array();
@ -151,14 +138,44 @@ class Doctrine_Table extends Doctrine_Configurable {
switch(count($this->primaryKeys)):
case 0:
$this->columns = array_merge(array("id" => array("integer",11,"AUTOINCREMENT PRIMARY")), $this->columns);
$this->columns = array_merge(array("id" => array("integer",11,"autoincrement|primary")), $this->columns);
$this->primaryKeys[] = "id";
break;
case 1:
$this->identifier = "id";
$this->identifierType = Doctrine_Identifier::AUTO_INCREMENT;
break;
default:
foreach($this->primaryKeys as $pk) {
$o = $this->columns[$pk][2];
$e = explode("|",$o);
$found = false;
foreach($e as $option) {
if($found)
break;
$e2 = explode(":",$option);
switch(strtolower($e2[0])):
case "unique":
$this->identifierType = Doctrine_Identifier::UNIQUE;
$found = true;
break;
case "autoincrement":
$this->identifierType = Doctrine_Identifier::AUTO_INCREMENT;
$found = true;
break;
case "seq":
$this->identifierType = Doctrine_Identifier::SEQUENCE;
$found = true;
break;
endswitch;
}
if( ! isset($this->identifierType))
$this->identifierType = Doctrine_Identifier::NORMAL;
$this->identifier = $pk;
}
endswitch;
if($this->getAttribute(Doctrine::ATTR_CREATE_TABLES)) {
@ -170,6 +187,8 @@ class Doctrine_Table extends Doctrine_Configurable {
} else {
throw new Doctrine_Exception("Class '$name' has no table definition.");
}
$record->setUp();
// save parents
array_pop($names);
@ -216,6 +235,18 @@ class Doctrine_Table extends Doctrine_Configurable {
$this->primaryKeys[] = $name;
}
}
/**
* @return mixed
*/
final public function getIdentifier() {
return $this->identifier;
}
/**
* @return integer
*/
final public function getIdentifierType() {
return $this->identifierType;
}
/**
* hasColumn
* @return boolean
@ -274,8 +305,8 @@ class Doctrine_Table extends Doctrine_Configurable {
try {
$fk = $this->getForeignKey($k);
switch($fk->getType()):
case Doctrine_Table::ONE_COMPOSITE:
case Doctrine_Table::MANY_COMPOSITE:
case Doctrine_Relation::ONE_COMPOSITE:
case Doctrine_Relation::MANY_COMPOSITE:
$n = $fk->getTable()->getComponentName();
$array[] = $name.".".$n;
$e = $fk->getTable()->getCompositePaths();
@ -323,7 +354,9 @@ class Doctrine_Table extends Doctrine_Configurable {
// is reference table used?
if($e[0] != $name && $e[0] == $this->name)
$this->bound[$name] = array($field,Doctrine_Table::MANY_COMPOSITE);
$this->bound[$name] = array($field,Doctrine_Relation::MANY_COMPOSITE);
$this->bound[$name] = array($field,$type,$localKey);
}
@ -361,31 +394,42 @@ class Doctrine_Table extends Doctrine_Configurable {
return $this->foreignKeys[$name];
if(isset($this->bound[$name])) {
$type = $this->bound[$name][1];
$field = $this->bound[$name][0];
$type = $this->bound[$name][1];
$local = $this->bound[$name][2];
$e = explode(".",$field);
$objTable = $this->session->getTable($name);
switch($e[0]):
case $name:
if( ! isset($local))
$local = $this->identifier;
// ONE-TO-MANY or ONE-TO-ONE
$foreignKey = new Doctrine_ForeignKey($objTable,$this->bound[$name][2],$e[1],$type);
$foreignKey = new Doctrine_ForeignKey($objTable,$local,$e[1],$type);
break;
case $this->name:
// ONE-TO-ONE
if($type <= Doctrine_Table::ONE_COMPOSITE)
$foreignKey = new Doctrine_LocalKey($objTable,$e[1],$this->bound[$name][2],$type);
else
if($type <= Doctrine_Relation::ONE_COMPOSITE) {
if( ! isset($local))
$local = $objTable->getIdentifier();
$foreignKey = new Doctrine_LocalKey($objTable,$e[1],$local,$type);
} else
throw new Doctrine_Mapping_Exception();
break;
default:
if(in_array($e[0], $this->parents)) {
// ONE-TO-ONE
if($type <= Doctrine_Table::ONE_COMPOSITE)
$foreignKey = new Doctrine_LocalKey($objTable,$e[1],$this->bound[$name][2],$type);
else
if($type <= Doctrine_Relation::ONE_COMPOSITE) {
if( ! isset($local))
$local = $objTable->getIdentifier();
$foreignKey = new Doctrine_LocalKey($objTable,$e[1],$local,$type);
} else
throw new Doctrine_Mapping_Exception();
} else {
// POSSIBLY MANY-TO-MANY
@ -400,7 +444,8 @@ class Doctrine_Table extends Doctrine_Configurable {
}
}
if( ! isset($local))
$local = $this->identifier;
$e2 = explode(".",$bound[0]);
@ -409,7 +454,7 @@ class Doctrine_Table extends Doctrine_Configurable {
$associationTable = $this->session->getTable($e2[0]);
$this->foreignKeys[$e2[0]] = new Doctrine_ForeignKey($associationTable,$this->bound[$name][2],$e2[1],Doctrine_Table::MANY_COMPOSITE);
$this->foreignKeys[$e2[0]] = new Doctrine_ForeignKey($associationTable,$local,$e2[1],Doctrine_Relation::MANY_COMPOSITE);
$foreignKey = new Doctrine_Association($objTable,$associationTable,$e2[1],$e[1],$type);
}

View File

@ -1,8 +1,27 @@
<?php
/**
* Doctrine_Validator
*/
class Doctrine_Validator {
/**
* ERROR CONSTANTS
*/
/**
* constant for length error
*/
const ERR_LENGTH = 0;
/**
* constant for type error
*/
const ERR_TYPE = 1;
/**
* constant for general validation error
*/
const ERR_VALID = 2;
/**
* constant for unique validator error
*/
const ERR_UNIQUE = 3;
/**
@ -81,6 +100,7 @@ class Doctrine_Validator {
return true;
}
/**
* whether or not this validator has errors
* @return boolean
*/
public function hasErrors() {
@ -93,6 +113,7 @@ class Doctrine_Validator {
return $this->stack;
}
/**
* returns the type of loosely typed variable
* @param mixed $var
*/
public static function gettype($var) {

View File

@ -40,7 +40,7 @@ class Doctrine_Collection_OffsetTestCase extends Doctrine_UnitTestCase {
$this->session->setAttribute(Doctrine::ATTR_COLL_LIMIT, 1);
$users = $this->session->query("FROM User-b, User.Phonenumber-o WHERE User.id = 5");
$users = $this->session->query("FROM User-b, User.Phonenumber-o WHERE User.".$this->objTable->getIdentifier()." = 5");
$this->assertEqual(count($users), 1);

View File

@ -37,7 +37,8 @@ class Doctrine_CollectionTestCase extends Doctrine_UnitTestCase {
$this->assertTrue($coll[2]->getState() == Doctrine_Record::STATE_PROXY);
$generator = new Doctrine_IndexGenerator("id");
$generator = new Doctrine_IndexGenerator($this->objTable->getIdentifier());
$coll->setGenerator($generator);
$generator = $coll->getGenerator();
$this->assertEqual($generator->getIndex($this->old), 4);

View File

@ -168,7 +168,7 @@ class Doctrine_DQL_ParserTestCase extends Doctrine_UnitTestCase {
$this->assertEqual($users->count(),8);
$users = $graph->query("FROM User-b WHERE User.name LIKE '%Jack%'");
$this->assertTrue($graph->getQuery() == "SELECT entity.id AS User__id FROM entity WHERE (entity.name LIKE '%Jack%') AND (entity.type = 0)");
$this->assertEqual($graph->getQuery(), "SELECT entity.id AS User__id FROM entity WHERE (entity.name LIKE '%Jack%') AND (entity.type = 0)");
$this->assertEqual($users->count(),0);

View File

@ -0,0 +1,4 @@
<?php
class Doctrine_IdentifierTestCase extends Doctrine_UnitTestCase {
}
?>

View File

@ -129,7 +129,6 @@ class Doctrine_RecordTestCase extends Doctrine_UnitTestCase {
$e->code = 1;
// ADDING NEW RECORD
$this->assertEqual($e->code,1);
$this->assertEqual($e->file_md5, md5(0));
$this->assertEqual($e->message, "user error");
@ -163,10 +162,10 @@ class Doctrine_RecordTestCase extends Doctrine_UnitTestCase {
$this->assertEqual($e2->Description[1]->file_md5, $e2->file_md5);
$e->save();
$coll = $this->session->query("FROM Error-I");
$e = $coll[0];
$this->assertEqual($e->code,1);
$this->assertEqual($e->file_md5, md5(0));

View File

@ -1,27 +1,30 @@
<?php
require_once("UnitTestCase.class.php");
class Doctrine_TableTestCase extends Doctrine_UnitTestCase {
public function testGetIdentifier() {
$table = $this->session->getTable("User");
}
public function testGetForeignKey() {
$fk = $this->objTable->getForeignKey("Group");
$this->assertTrue($fk instanceof Doctrine_Association);
$this->assertTrue($fk->getTable() instanceof Doctrine_Table);
$this->assertTrue($fk->getType() == Doctrine_Table::MANY_AGGREGATE);
$this->assertTrue($fk->getType() == Doctrine_Relation::MANY_AGGREGATE);
$this->assertTrue($fk->getLocal() == "user_id");
$this->assertTrue($fk->getForeign() == "group_id");
$fk = $this->objTable->getForeignKey("Email");
$this->assertTrue($fk instanceof Doctrine_LocalKey);
$this->assertTrue($fk->getTable() instanceof Doctrine_Table);
$this->assertTrue($fk->getType() == Doctrine_Table::ONE_COMPOSITE);
$this->assertTrue($fk->getType() == Doctrine_Relation::ONE_COMPOSITE);
$this->assertTrue($fk->getLocal() == "email_id");
$this->assertTrue($fk->getForeign() == "id");
$this->assertTrue($fk->getForeign() == $fk->getTable()->getIdentifier());
$fk = $this->objTable->getForeignKey("Phonenumber");
$this->assertTrue($fk instanceof Doctrine_ForeignKey);
$this->assertTrue($fk->getTable() instanceof Doctrine_Table);
$this->assertTrue($fk->getType() == Doctrine_Table::MANY_COMPOSITE);
$this->assertTrue($fk->getLocal() == "id");
$this->assertTrue($fk->getType() == Doctrine_Relation::MANY_COMPOSITE);
$this->assertTrue($fk->getLocal() == $this->objTable->getIdentifier());
$this->assertTrue($fk->getForeign() == "entity_id");
}
public function testGetComponentName() {

View File

@ -1,13 +1,6 @@
<?php
require_once("../classes/Doctrine.class.php");
/**
function __autoload($class) {
Doctrine::autoload($class);
}
*/
Doctrine::loadAll();
require_once("classes.php");
@ -38,11 +31,18 @@ class Doctrine_UnitTestCase extends UnitTestCase {
$this->manager = Doctrine_Manager::getInstance();
$this->manager->setAttribute(Doctrine::ATTR_CACHE, Doctrine::CACHE_NONE);
$this->manager->setAttribute(Doctrine::ATTR_FETCHMODE, Doctrine::FETCH_IMMEDIATE);
$this->tables = array("entity","email","phonenumber","groupuser","album","song","element","error","description","address","account");
$tables = $this->tables;
if($this->manager->count() > 0) {
$this->session = $this->manager->getSession(0);
$this->session->clear();
$this->dbh = $this->session->getDBH();
$this->listener = $this->manager->getAttribute(Doctrine::ATTR_LISTENER);
} else {
$this->dbh = Doctrine_DB::getConnection();
$this->session = $this->manager->openSession($this->dbh);
@ -50,8 +50,6 @@ class Doctrine_UnitTestCase extends UnitTestCase {
$this->manager->setAttribute(Doctrine::ATTR_LISTENER, $this->listener);
}
$this->tables = array("entity","email","phonenumber","groupuser","album","song","element","error","description","address","account");
$tables = $this->tables;
foreach($tables as $name) {
$this->dbh->query("DROP TABLE IF EXISTS $name");
}
@ -62,6 +60,7 @@ class Doctrine_UnitTestCase extends UnitTestCase {
}
$this->objTable = $this->session->getTable("User");
$this->repository = $this->objTable->getRepository();
//$this->cache = $this->objTable->getCache();

View File

@ -6,6 +6,7 @@ class Entity extends Doctrine_Record {
$this->ownsOne("Account","Account.entity_id");
}
public function setTableDefinition() {
$this->hasColumn("id","integer",20,"autoincrement|primary");
$this->hasColumn("name","string",50);
$this->hasColumn("loginname","string",20,"unique");
$this->hasColumn("password","string",16);
@ -84,7 +85,6 @@ class Groupuser extends Doctrine_Record {
$this->hasColumn("user_id","integer");
}
}
class Phonenumber extends Doctrine_Record {
public function setTableDefinition() {
$this->hasColumn("phonenumber","string",20);

View File

@ -23,18 +23,19 @@ error_reporting(E_ALL);
$test = new GroupTest("Doctrine Framework Unit Tests");
$test->addTestCase(new Doctrine_TableTestCase());
$test->addTestCase(new Doctrine_SessionTestCase());
$test->addTestCase(new Doctrine_RecordTestCase());
$test->addTestCase(new Doctrine_ValidatorTestCase());
$test->addTestCase(new Doctrine_ManagerTestCase());
$test->addTestCase(new Doctrine_TableTestCase());
$test->addTestCase(new Doctrine_AccessTestCase());
@ -57,7 +58,6 @@ $test->addTestCase(new Doctrine_CollectionTestCase());
$test->addTestCase(new Doctrine_Collection_OffsetTestCase());
$test->addTestCase(new Sensei_UnitTestCase());
//$test->addTestCase(new Doctrine_Cache_FileTestCase());
//$test->addTestCase(new Doctrine_Cache_SqliteTestCase());