Commit 4d752746 authored by romanb's avatar romanb

The usual 2.0 refactoring/implementation commit.

parent 51f957bc
...@@ -141,20 +141,20 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable ...@@ -141,20 +141,20 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
protected $_mappedEmbeddedValues = array(); protected $_mappedEmbeddedValues = array();
/** /**
* An array of field names. used to look up field names from column names. * Enter description here...
* Keys are column names and values are field names.
* This is the reverse lookup map of $_columnNames.
* *
* @var array * @var array
*/ */
protected $_fieldNames = array(); protected $_attributes = array('loadReferences' => true);
/** /**
* Enter description here... * An array of field names. used to look up field names from column names.
* Keys are column names and values are field names.
* This is the reverse lookup map of $_columnNames.
* *
* @var unknown_type * @var array
*/ */
protected $_attributes = array('loadReferences' => true); protected $_fieldNames = array();
/** /**
* An array of column names. Keys are field names and values column names. * An array of column names. Keys are field names and values column names.
...@@ -165,12 +165,21 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable ...@@ -165,12 +165,21 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
*/ */
protected $_columnNames = array(); protected $_columnNames = array();
/**
* Map that maps lowercased column names to field names.
* Mainly used during hydration because Doctrine enforces PDO_CASE_LOWER
* for portability.
*
* @var array
*/
protected $_lcColumnToFieldNames = array();
/** /**
* Enter description here... * Enter description here...
* *
* @var unknown_type * @var unknown_type
*/ */
protected $_subclassFieldNames = array(); //protected $_subclassFieldNames = array();
/** /**
* Caches enum value mappings. Keys are field names and values arrays with the * Caches enum value mappings. Keys are field names and values arrays with the
...@@ -192,7 +201,7 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable ...@@ -192,7 +201,7 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
* *
* @var integer * @var integer
*/ */
protected $_columnCount; //protected $_columnCount;
/** /**
* Whether or not this class has default values. * Whether or not this class has default values.
...@@ -540,10 +549,8 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable ...@@ -540,10 +549,8 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
} }
/** /**
* getFieldName * Gets the field name for a column name.
* * If no field name can be found the column name is returned.
* returns the field name for a column name
* if no field name can be found the column name is returned.
* *
* @param string $columnName column name * @param string $columnName column name
* @return string column alias * @return string column alias
...@@ -555,28 +562,57 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable ...@@ -555,28 +562,57 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
} }
/** /**
* * Gets the field name for a completely lowercased column name.
* Mainly used during hydration.
*
* @param string $lcColumnName
* @return string
*/ */
public function lookupFieldName($columnName) public function getFieldNameForLowerColumnName($lcColumnName)
{ {
if (isset($this->_fieldNames[$columnName])) { return isset($this->_lcColumnToFieldNames[$lcColumnName]) ?
return $this->_fieldNames[$columnName]; $this->_lcColumnToFieldNames[$lcColumnName] : $lcColumnName;
} else if (isset($this->_subclassFieldNames[$columnName])) { }
return $this->_subclassFieldNames[$columnName];
} public function hasLowerColumn($lcColumnName)
{
$classMetadata = $this; return isset($this->_lcColumnToFieldNames[$lcColumnName]);
$conn = $this->_em; }
/**
* Looks up the field name for a (lowercased) column name.
*
* This is mostly used during hydration, because we want to make the
* conversion to field names while iterating over the result set for best
* performance. By doing this at that point, we can avoid re-iterating over
* the data just to convert the column names to field names.
*
* However, when this is happening, we don't know the real
* class name to instantiate yet (the row data may target a sub-type), hence
* this method looks up the field name in the subclass mappings if it's not
* found on this class mapping.
* This lookup on subclasses is costly but happens only *once* for a column
* during hydration because the hydrator caches effectively.
*/
public function lookupFieldName($lcColumnName)
{
if (isset($this->_lcColumnToFieldNames[$lcColumnName])) {
return $this->_lcColumnToFieldNames[$lcColumnName];
}/* else if (isset($this->_subclassFieldNames[$lcColumnName])) {
return $this->_subclassFieldNames[$lcColumnName];
}*/
foreach ($classMetadata->getSubclasses() as $subClass) { foreach ($this->getSubclasses() as $subClass) {
$subClassMetadata = $conn->getClassMetadata($subClass); $subClassMetadata = $this->_em->getClassMetadata($subClass);
if ($subClassMetadata->hasColumn($columnName)) { if ($subClassMetadata->hasLowerColumn($lcColumnName)) {
$this->_subclassFieldNames[$columnName] = $subClassMetadata->getFieldName($columnName); /*$this->_subclassFieldNames[$lcColumnName] = $subClassMetadata->
return $this->_subclassFieldNames[$columnName]; getFieldNameForLowerColumnName($lcColumnName);
return $this->_subclassFieldNames[$lcColumnName];*/
return $subClassMetadata->getFieldNameForLowerColumnName($lcColumnName);
} }
} }
throw new Doctrine_ClassMetadata_Exception("No field name found for column name '$columnName' during lookup."); throw new Doctrine_ClassMetadata_Exception("No field name found for column name '$lcColumnName' during lookup.");
} }
/** /**
...@@ -615,26 +651,30 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable ...@@ -615,26 +651,30 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
} }
} }
// extract column name & field name // extract column name & field name & lowercased column name
$parts = explode(' as ', $name); $parts = explode(' as ', $name);
if (count($parts) > 1) { if (count($parts) > 1) {
$fieldName = $parts[1]; $fieldName = $parts[1];
} else { } else {
$fieldName = $parts[0]; $fieldName = $parts[0];
} }
$name = strtolower($parts[0]); $columnName = $parts[0];
$lcColumnName = strtolower($parts[0]);
if (isset($this->_columnNames[$fieldName])) { if (isset($this->_mappedColumns[$columnName])) {
return; return;
} }
// Fill column name <-> field name lookup maps
if ($prepend) { if ($prepend) {
$this->_columnNames = array_merge(array($fieldName => $name), $this->_columnNames); $this->_columnNames = array_merge(array($fieldName => $columnName), $this->_columnNames);
$this->_fieldNames = array_merge(array($name => $fieldName), $this->_fieldNames); $this->_fieldNames = array_merge(array($columnName => $fieldName), $this->_fieldNames);
} else { } else {
$this->_columnNames[$fieldName] = $name; $this->_columnNames[$fieldName] = $columnName;
$this->_fieldNames[$name] = $fieldName; $this->_fieldNames[$columnName] = $fieldName;
} }
$this->_lcColumnToFieldNames[$lcColumnName] = $fieldName;
// Inspect & fill $options // Inspect & fill $options
...@@ -662,9 +702,9 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable ...@@ -662,9 +702,9 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
}*/ }*/
if ($prepend) { if ($prepend) {
$this->_mappedColumns = array_merge(array($name => $options), $this->_mappedColumns); $this->_mappedColumns = array_merge(array($columnName => $options), $this->_mappedColumns);
} else { } else {
$this->_mappedColumns[$name] = $options; $this->_mappedColumns[$columnName] = $options;
} }
$this->_columnCount++; $this->_columnCount++;
......
...@@ -65,7 +65,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -65,7 +65,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
* *
* @var Doctrine_Entity * @var Doctrine_Entity
*/ */
protected $reference; protected $_owner;
/** /**
* The reference field of the collection. * The reference field of the collection.
...@@ -93,7 +93,14 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -93,7 +93,14 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
* *
* @var Doctrine_Null * @var Doctrine_Null
*/ */
protected static $null; //protected static $null;
/**
* The EntityManager.
*
* @var EntityManager
*/
protected $_em;
/** /**
* Constructor. * Constructor.
...@@ -104,15 +111,12 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -104,15 +111,12 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
*/ */
public function __construct($entityBaseType, $keyField = null) public function __construct($entityBaseType, $keyField = null)
{ {
if (is_string($entityBaseType)) { $this->_entityBaseType = $entityBaseType;
$this->_entityBaseType = $entityBaseType; $this->_em = Doctrine_EntityManagerFactory::getManager($entityBaseType);
$mapper = Doctrine_EntityManagerFactory::getManager($entityBaseType) $this->_mapper = $this->_em->getEntityPersister($entityBaseType);
->getEntityPersister($entityBaseType);
}
$this->_mapper = $mapper;
if ($keyField === null) { if ($keyField === null) {
$keyField = $mapper->getClassMetadata()->getBoundQueryPart('indexBy'); $keyField = $this->_mapper->getClassMetadata()->getBoundQueryPart('indexBy');
} }
if ($keyField === null) { if ($keyField === null) {
...@@ -127,39 +131,6 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -127,39 +131,6 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
} }
} }
/**
* initNullObject
* Initializes the null object for this collection.
*
* @return void
*/
public static function initNullObject(Doctrine_Null $null)
{
self::$null = $null;
}
/**
* getTable
* Returns the table of the mapper of the collection.
*
* @return Doctrine_Table
*/
public function getTable()
{
return $this->_mapper->getTable();
}
/**
* getMapper
* Returns the mapper of this collection.
*
* @return Doctrine_Mapper
*/
public function getMapper()
{
return $this->_mapper;
}
/** /**
* setData * setData
* *
...@@ -306,25 +277,25 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -306,25 +277,25 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
} }
/** /**
* setReference * INTERNAL:
* sets a reference pointer * sets a reference pointer
* *
* @return void * @return void
*/ */
public function setReference(Doctrine_Entity $record, Doctrine_Relation $relation) public function setReference(Doctrine_Entity $entity, Doctrine_Relation $relation)
{ {
$this->reference = $record; $this->_owner = $entity;
$this->relation = $relation; $this->relation = $relation;
if ($relation instanceof Doctrine_Relation_ForeignKey || if ($relation instanceof Doctrine_Relation_ForeignKey ||
$relation instanceof Doctrine_Relation_LocalKey) { $relation instanceof Doctrine_Relation_LocalKey) {
$this->referenceField = $relation->getForeignFieldName(); $this->referenceField = $relation->getForeignFieldName();
$value = $record->get($relation->getLocalFieldName()); $value = $entity->get($relation->getLocalFieldName());
foreach ($this->data as $record) { foreach ($this->data as $entity) {
if ($value !== null) { if ($value !== null) {
$record->set($this->referenceField, $value, false); $entity->set($this->referenceField, $value, false);
} else { } else {
$record->set($this->referenceField, $this->reference, false); $entity->set($this->referenceField, $this->_owner, false);
} }
} }
} else if ($relation instanceof Doctrine_Relation_Association) { } else if ($relation instanceof Doctrine_Relation_Association) {
...@@ -333,18 +304,18 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -333,18 +304,18 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
} }
/** /**
* INTERNAL:
* getReference * getReference
* *
* @return mixed * @return mixed
*/ */
public function getReference() public function getReference()
{ {
return $this->reference; return $this->_owner;
} }
/** /**
* remove * Removes an entity from the collection.
* removes a specified collection element
* *
* @param mixed $key * @param mixed $key
* @return boolean * @return boolean
...@@ -357,8 +328,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -357,8 +328,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
} }
/** /**
* contains * Checks whether the collection contains an entity.
* whether or not this collection contains a specified element
* *
* @param mixed $key the key of the element * @param mixed $key the key of the element
* @return boolean * @return boolean
...@@ -378,17 +348,8 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -378,17 +348,8 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
} }
/** /**
* get
* returns a record for given key * returns a record for given key
* *
* There are two special cases:
*
* 1. if null is given as a key a new record is created and attached
* at the end of the collection
*
* 2. if given key does not exist, then a new record is create and attached
* to the given key
*
* Collection also maps referential information to newly created records * Collection also maps referential information to newly created records
* *
* @param mixed $key the key of the element * @param mixed $key the key of the element
...@@ -396,33 +357,10 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -396,33 +357,10 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
*/ */
public function get($key) public function get($key)
{ {
if ( ! isset($this->data[$key])) { if (isset($this->data[$key])) {
$record = $this->_mapper->create(); return $this->data[$key];
if (isset($this->referenceField)) {
$value = $this->reference->get($this->relation->getLocalFieldName());
if ($value !== null) {
$record->set($this->referenceField, $value, false);
} else {
$record->set($this->referenceField, $this->reference, false);
}
}
if ($key === null) {
$this->data[] = $record;
} else {
$this->data[$key] = $record;
}
if (isset($this->_keyField)) {
$record->set($this->_keyField, $key);
}
return $record;
} }
return null;
return $this->data[$key];
} }
/** /**
...@@ -491,16 +429,16 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -491,16 +429,16 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
* @internal Can't type-hint the second parameter to Doctrine_Entity because we need * @internal Can't type-hint the second parameter to Doctrine_Entity because we need
* to adhere to the Doctrine_Access::set() signature. * to adhere to the Doctrine_Access::set() signature.
*/ */
public function set($key, $record) public function set($key, $entity)
{ {
if ( ! $record instanceOf Doctrine_Entity) { if ( ! $entity instanceof Doctrine_Entity) {
throw new Doctrine_Collection_Exception('Value variable in set is not an instance of Doctrine_Entity'); throw new Doctrine_Collection_Exception('Value variable in set is not an instance of Doctrine_Entity');
} }
if (isset($this->referenceField)) { if (isset($this->referenceField)) {
$record->set($this->referenceField, $this->reference, false); $entity->set($this->referenceField, $this->_owner, false);
} }
$this->data[$key] = $record; $this->data[$key] = $entity;
} }
/** /**
...@@ -517,12 +455,12 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -517,12 +455,12 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
} }
if (isset($this->referenceField)) { if (isset($this->referenceField)) {
$value = $this->reference->get($this->relation->getLocalFieldName()); $value = $this->_owner->get($this->relation->getLocalFieldName());
if ($value !== null) { if ($value !== null) {
$record->set($this->referenceField, $value, false); $record->set($this->referenceField, $value, false);
} else { } else {
$record->set($this->referenceField, $this->reference, false); $record->set($this->referenceField, $this->_owner, false);
} }
} }
/* /*
...@@ -559,6 +497,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -559,6 +497,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
} }
/** /**
* INTERNAL:
* loadRelated * loadRelated
* *
* @param mixed $name * @param mixed $name
...@@ -578,8 +517,10 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -578,8 +517,10 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
$list[] = $value; $list[] = $value;
} }
} }
$query->from($this->_mapper->getComponentName() . '(' . implode(", ",$this->_mapper->getTable()->getPrimaryKeys()) . ')'); $query->from($this->_mapper->getComponentName()
$query->where($this->_mapper->getComponentName() . '.id IN (' . substr(str_repeat("?, ", count($list)),0,-2) . ')'); . '(' . implode(", ",$this->_mapper->getTable()->getPrimaryKeys()) . ')');
$query->where($this->_mapper->getComponentName()
. '.id IN (' . substr(str_repeat("?, ", count($list)),0,-2) . ')');
return $query; return $query;
} }
...@@ -607,6 +548,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -607,6 +548,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
} }
/** /**
* INTERNAL:
* populateRelated * populateRelated
* *
* @param string $name * @param string $name
...@@ -929,9 +871,9 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -929,9 +871,9 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
$this->data = array(); $this->data = array();
if ($this->reference) { if ($this->_owner) {
$this->reference->free($deep); $this->_owner->free($deep);
$this->reference = null; $this->_owner = null;
} }
} }
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
* The Configuration is the container for all configuration options of Doctrine. * The Configuration is the container for all configuration options of Doctrine.
* It combines all configuration options from DBAL & ORM. * It combines all configuration options from DBAL & ORM.
* *
* @author Roman Borschel <roman@code-factory.org>
* @since 2.0 * @since 2.0
*/ */
class Doctrine_Configuration class Doctrine_Configuration
......
...@@ -78,10 +78,9 @@ abstract class Doctrine_Connection implements Countable ...@@ -78,10 +78,9 @@ abstract class Doctrine_Connection implements Countable
/** /**
* The PDO database handle. * The PDO database handle.
* *
* @var PDO * @var PDO
* @todo Rename to $pdo.
*/ */
protected $dbh; protected $_pdo;
/** /**
* The Configuration. * The Configuration.
...@@ -116,14 +115,14 @@ abstract class Doctrine_Connection implements Countable ...@@ -116,14 +115,14 @@ abstract class Doctrine_Connection implements Countable
* *
* @var string $driverName * @var string $driverName
*/ */
protected $driverName; protected $_driverName;
/** /**
* Whether or not a connection has been established. * Whether or not a connection has been established.
* *
* @var boolean $isConnected * @var boolean $isConnected
*/ */
protected $isConnected = false; protected $_isConnected = false;
/** /**
* An array containing all features this driver supports, keys representing feature * An array containing all features this driver supports, keys representing feature
...@@ -163,7 +162,7 @@ abstract class Doctrine_Connection implements Countable ...@@ -163,7 +162,7 @@ abstract class Doctrine_Connection implements Countable
* *
* @var array $availableDrivers * @var array $availableDrivers
*/ */
private static $availableDrivers = array( private static $_availableDrivers = array(
'Mysql', 'Pgsql', 'Oracle', 'Informix', 'Mssql', 'Sqlite', 'Firebird' 'Mysql', 'Pgsql', 'Oracle', 'Informix', 'Mssql', 'Sqlite', 'Firebird'
); );
...@@ -172,7 +171,7 @@ abstract class Doctrine_Connection implements Countable ...@@ -172,7 +171,7 @@ abstract class Doctrine_Connection implements Countable
* *
* @var integer * @var integer
*/ */
protected $_count = 0; protected $_queryCount = 0;
/* /*
...@@ -220,14 +219,13 @@ abstract class Doctrine_Connection implements Countable ...@@ -220,14 +219,13 @@ abstract class Doctrine_Connection implements Countable
/** /**
* Constructor. * Constructor.
* *
* @param Doctrine_Manager $manager the manager object * @param array $params The connection parameters.
* @param PDO|Doctrine_Adapter_Interface $adapter database driver
*/ */
public function __construct(array $params) public function __construct(array $params)
{ {
if (isset($params['pdo'])) { if (isset($params['pdo'])) {
$this->dbh = $params['pdo']; $this->_pdo = $params['pdo'];
$this->isConnected = true; $this->_isConnected = true;
} }
$this->_params = $params; $this->_params = $params;
} }
...@@ -319,27 +317,36 @@ abstract class Doctrine_Connection implements Countable ...@@ -319,27 +317,36 @@ abstract class Doctrine_Connection implements Countable
} }
/** /**
* getDriverName
*
* Gets the name of the instance driver * Gets the name of the instance driver
* *
* @return void * @return void
*/ */
public function getDriverName() public function getDriverName()
{ {
return $this->driverName; return $this->_driverName;
} }
/** /**
* returns the database handler which this connection uses * returns the database handler which this connection uses
* *
* @return PDO the database handler * @return PDO the database handler
* @deprecated
*/ */
public function getDbh() public function getDbh()
{ {
//$this->connect(); $this->connect();
return $this->_pdo;
return $this->dbh; }
/**
* Gets the PDO handle used by the connection.
*
* @return PDO
*/
public function getPdo()
{
$this->connect();
return $this->_pdo;
} }
/** /**
...@@ -349,36 +356,43 @@ abstract class Doctrine_Connection implements Countable ...@@ -349,36 +356,43 @@ abstract class Doctrine_Connection implements Countable
*/ */
public function connect() public function connect()
{ {
if ($this->isConnected) { if ($this->_isConnected) {
return false; return false;
} }
//$event = new Doctrine_Event($this, Doctrine_Event::CONN_CONNECT); //$event = new Doctrine_Event($this, Doctrine_Event::CONN_CONNECT);
//$this->getListener()->preConnect($event); //$this->getListener()->preConnect($event);
$e = explode(':', $this->options['dsn']); // TODO: the extension_loaded check can happen earlier, maybe in the factory
if (extension_loaded('pdo')) { if (extension_loaded('pdo')) {
if (in_array($e[0], PDO::getAvailableDrivers())) { $driverOptions = isset($this->_params['driverOptions']) ?
$this->dbh = new PDO( $this->_params['driverOptions'] : array();
$this->options['dsn'], $this->options['username'], $user = isset($this->_params['user']) ?
$this->options['password'], $this->options['other']); $this->_params['user'] : null;
$this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $password = isset($this->_params['password']) ?
$this->dbh->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER); $this->_params['password'] : null;
} $this->_pdo = new PDO(
$this->_constructPdoDsn(),
$user,
$password,
$driverOptions
);
$this->_pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->_pdo->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER);
} else { } else {
throw new Doctrine_Connection_Exception("Couldn't locate driver named " . $e[0]); throw new Doctrine_Connection_Exception("Couldn't locate driver named " . $e[0]);
} }
// attach the pending attributes to adapter // attach the pending attributes to adapter
foreach($this->pendingAttributes as $attr => $value) { /*foreach($this->pendingAttributes as $attr => $value) {
// some drivers don't support setting this so we just skip it // some drivers don't support setting this so we just skip it
if ($attr == Doctrine::ATTR_DRIVER_NAME) { if ($attr == Doctrine::ATTR_DRIVER_NAME) {
continue; continue;
} }
$this->dbh->setAttribute($attr, $value); $this->_pdo->setAttribute($attr, $value);
} }*/
$this->isConnected = true; $this->_isConnected = true;
//$this->getListener()->postConnect($event); //$this->getListener()->postConnect($event);
return true; return true;
...@@ -394,7 +408,7 @@ abstract class Doctrine_Connection implements Countable ...@@ -394,7 +408,7 @@ abstract class Doctrine_Connection implements Countable
*/ */
protected function _constructPdoDsn() protected function _constructPdoDsn()
{ {
throw Doctrine_Exception::notImplemented('_constructPdoDsn', get_class($this));
} }
/** /**
...@@ -402,19 +416,11 @@ abstract class Doctrine_Connection implements Countable ...@@ -402,19 +416,11 @@ abstract class Doctrine_Connection implements Countable
*/ */
public function incrementQueryCount() public function incrementQueryCount()
{ {
$this->_count++; $this->_queryCount++;
} }
/** /**
* converts given driver name * Checks whether a certain feature is supported.
*
* @param
*/
public function driverName($name)
{}
/**
* supports
* *
* @param string $feature the name of the feature * @param string $feature the name of the feature
* @return boolean whether or not this drivers supports given feature * @return boolean whether or not this drivers supports given feature
...@@ -665,7 +671,7 @@ abstract class Doctrine_Connection implements Countable ...@@ -665,7 +671,7 @@ abstract class Doctrine_Connection implements Countable
*/ */
public function quote($input, $type = null) public function quote($input, $type = null)
{ {
return $this->dbh->quote($input, $type); return $this->_pdo->quote($input, $type);
} }
/** /**
...@@ -782,7 +788,7 @@ abstract class Doctrine_Connection implements Countable ...@@ -782,7 +788,7 @@ abstract class Doctrine_Connection implements Countable
$stmt = false; $stmt = false;
if ( ! $event->skipOperation) { if ( ! $event->skipOperation) {
$stmt = $this->dbh->prepare($statement); $stmt = $this->_pdo->prepare($statement);
} }
$this->getAttribute(Doctrine::ATTR_LISTENER)->postPrepare($event); $this->getAttribute(Doctrine::ATTR_LISTENER)->postPrepare($event);
...@@ -846,8 +852,8 @@ abstract class Doctrine_Connection implements Countable ...@@ -846,8 +852,8 @@ abstract class Doctrine_Connection implements Countable
$this->getAttribute(Doctrine::ATTR_LISTENER)->preQuery($event); $this->getAttribute(Doctrine::ATTR_LISTENER)->preQuery($event);
if ( ! $event->skipOperation) { if ( ! $event->skipOperation) {
$stmt = $this->dbh->query($query); $stmt = $this->_pdo->query($query);
$this->_count++; $this->_queryCount++;
} }
$this->getAttribute(Doctrine::ATTR_LISTENER)->postQuery($event); $this->getAttribute(Doctrine::ATTR_LISTENER)->postQuery($event);
...@@ -881,8 +887,8 @@ abstract class Doctrine_Connection implements Countable ...@@ -881,8 +887,8 @@ abstract class Doctrine_Connection implements Countable
$this->getAttribute(Doctrine::ATTR_LISTENER)->preExec($event); $this->getAttribute(Doctrine::ATTR_LISTENER)->preExec($event);
if ( ! $event->skipOperation) { if ( ! $event->skipOperation) {
$count = $this->dbh->exec($query); $count = $this->_pdo->exec($query);
$this->_count++; $this->_queryCount++;
} }
$this->getAttribute(Doctrine::ATTR_LISTENER)->postExec($event); $this->getAttribute(Doctrine::ATTR_LISTENER)->postExec($event);
...@@ -926,7 +932,7 @@ abstract class Doctrine_Connection implements Countable ...@@ -926,7 +932,7 @@ abstract class Doctrine_Connection implements Countable
//$event = new Doctrine_Event($this, Doctrine_Event::CONN_ERROR); //$event = new Doctrine_Event($this, Doctrine_Event::CONN_ERROR);
//$this->getListener()->preError($event); //$this->getListener()->preError($event);
$name = 'Doctrine_Connection_' . $this->driverName . '_Exception'; $name = 'Doctrine_Connection_' . $this->_driverName . '_Exception';
$exc = new $name($e->getMessage(), (int) $e->getCode()); $exc = new $name($e->getMessage(), (int) $e->getCode());
if ( ! is_array($e->errorInfo)) { if ( ! is_array($e->errorInfo)) {
...@@ -949,7 +955,7 @@ abstract class Doctrine_Connection implements Countable ...@@ -949,7 +955,7 @@ abstract class Doctrine_Connection implements Countable
*/ */
public function count() public function count()
{ {
return $this->_count; return $this->_queryCount;
} }
/** /**
...@@ -964,8 +970,8 @@ abstract class Doctrine_Connection implements Countable ...@@ -964,8 +970,8 @@ abstract class Doctrine_Connection implements Countable
$this->clear(); $this->clear();
unset($this->dbh); unset($this->_pdo);
$this->isConnected = false; $this->_isConnected = false;
//$this->getAttribute(Doctrine::ATTR_LISTENER)->postClose($event); //$this->getAttribute(Doctrine::ATTR_LISTENER)->postClose($event);
} }
...@@ -990,7 +996,7 @@ abstract class Doctrine_Connection implements Countable ...@@ -990,7 +996,7 @@ abstract class Doctrine_Connection implements Countable
{ {
$this->connect(); $this->connect();
return $this->dbh->errorCode(); return $this->_pdo->errorCode();
} }
/** /**
...@@ -1003,7 +1009,7 @@ abstract class Doctrine_Connection implements Countable ...@@ -1003,7 +1009,7 @@ abstract class Doctrine_Connection implements Countable
{ {
$this->connect(); $this->connect();
return $this->dbh->errorInfo(); return $this->_pdo->errorInfo();
} }
/** /**
......
...@@ -38,7 +38,7 @@ class Doctrine_Connection_Mock extends Doctrine_Connection_Common ...@@ -38,7 +38,7 @@ class Doctrine_Connection_Mock extends Doctrine_Connection_Common
/** /**
* @var string $driverName the name of this connection driver * @var string $driverName the name of this connection driver
*/ */
protected $driverName = 'MySql'; protected $_driverName = 'Mysql';
/** /**
* the constructor * the constructor
......
...@@ -40,7 +40,7 @@ class Doctrine_Connection_Mysql extends Doctrine_Connection_Common ...@@ -40,7 +40,7 @@ class Doctrine_Connection_Mysql extends Doctrine_Connection_Common
* *
* @var string * @var string
*/ */
protected $driverName = 'Mysql'; protected $_driverName = 'Mysql';
/** /**
* the constructor * the constructor
...@@ -206,5 +206,31 @@ class Doctrine_Connection_Mysql extends Doctrine_Connection_Common ...@@ -206,5 +206,31 @@ class Doctrine_Connection_Mysql extends Doctrine_Connection_Common
$query = 'REPLACE INTO ' . $tableName . ' (' . $query . ') VALUES (' . $values . ')'; $query = 'REPLACE INTO ' . $tableName . ' (' . $query . ') VALUES (' . $values . ')';
return $this->exec($query); return $this->exec($query);
}
/**
* Constructs the MySql PDO DSN.
*
* Overrides Connection#_constructPdoDsn().
*
* @return string The DSN.
*/
protected function _constructPdoDsn()
{
$dsn = 'mysql:';
if (isset($this->_params['host'])) {
$dsn .= 'host=' . $this->_params['host'] . ';';
}
if (isset($this->_params['port'])) {
$dsn .= 'port=' . $this->_params['port'] . ';';
}
if (isset($this->_params['dbname'])) {
$dsn .= 'dbname=' . $this->_params['dbname'] . ';';
}
if (isset($this->_params['unix_socket'])) {
$dsn .= 'unix_socket=' . $this->_params['unix_socket'] . ';';
}
return $dsn;
} }
} }
...@@ -38,7 +38,7 @@ class Doctrine_Connection_Sqlite extends Doctrine_Connection_Common ...@@ -38,7 +38,7 @@ class Doctrine_Connection_Sqlite extends Doctrine_Connection_Common
/** /**
* @var string $driverName the name of this connection driver * @var string $driverName the name of this connection driver
*/ */
protected $driverName = 'Sqlite'; protected $_driverName = 'Sqlite';
/** /**
* the constructor * the constructor
...@@ -67,13 +67,14 @@ class Doctrine_Connection_Sqlite extends Doctrine_Connection_Common ...@@ -67,13 +67,14 @@ class Doctrine_Connection_Sqlite extends Doctrine_Connection_Common
'prepared_statements' => 'emulated', 'prepared_statements' => 'emulated',
'identifier_quoting' => true, 'identifier_quoting' => true,
'pattern_escaping' => false, 'pattern_escaping' => false,
); );
parent::__construct($params); parent::__construct($params);
if ($this->isConnected) { if ($this->_isConnected) {
$this->dbh->sqliteCreateFunction('mod', array('Doctrine_Expression_Sqlite', 'modImpl'), 2); $this->_pdo->sqliteCreateFunction('mod', array('Doctrine_Expression_Sqlite', 'modImpl'), 2);
$this->dbh->sqliteCreateFunction('md5', 'md5', 1); $this->_pdo->sqliteCreateFunction('md5', 'md5', 1);
$this->dbh->sqliteCreateFunction('now', 'time', 0); $this->_pdo->sqliteCreateFunction('now', 'time', 0);
} }
} }
...@@ -85,15 +86,15 @@ class Doctrine_Connection_Sqlite extends Doctrine_Connection_Common ...@@ -85,15 +86,15 @@ class Doctrine_Connection_Sqlite extends Doctrine_Connection_Common
*/ */
public function connect() public function connect()
{ {
if ($this->isConnected) { if ($this->_isConnected) {
return false; return false;
} }
parent::connect(); parent::connect();
$this->dbh->sqliteCreateFunction('mod', array('Doctrine_Expression_Sqlite', 'modImpl'), 2); $this->_pdo->sqliteCreateFunction('mod', array('Doctrine_Expression_Sqlite', 'modImpl'), 2);
$this->dbh->sqliteCreateFunction('md5', 'md5', 1); $this->_pdo->sqliteCreateFunction('md5', 'md5', 1);
$this->dbh->sqliteCreateFunction('now', 'time', 0); $this->_pdo->sqliteCreateFunction('now', 'time', 0);
} }
/** /**
...@@ -125,18 +126,37 @@ class Doctrine_Connection_Sqlite extends Doctrine_Connection_Common ...@@ -125,18 +126,37 @@ class Doctrine_Connection_Sqlite extends Doctrine_Connection_Common
*/ */
public function dropDatabase() public function dropDatabase()
{ {
try { try {
if ( ! $dsn = $this->getOption('dsn')) { if ( ! $dsn = $this->getOption('dsn')) {
throw new Doctrine_Connection_Exception('You must create your Doctrine_Connection by using a valid Doctrine style dsn in order to use the create/drop database functionality'); throw new Doctrine_Connection_Exception('You must create your Doctrine_Connection by using a valid Doctrine style dsn in order to use the create/drop database functionality');
} }
$info = $this->getManager()->parseDsn($dsn);
$this->export->dropDatabase($info['database']); $info = $this->getManager()->parseDsn($dsn);
return 'Successfully dropped database for connection "' . $this->getName() . '" at path "' . $info['database'] . '"'; $this->export->dropDatabase($info['database']);
} catch (Exception $e) {
return $e; return 'Successfully dropped database for connection "' . $this->getName() . '" at path "' . $info['database'] . '"';
} } catch (Exception $e) {
return $e;
}
}
/**
* Constructs the Sqlite PDO DSN.
*
* Overrides Connection#_constructPdoDsn().
*
* @return string The DSN.
*/
protected function _constructPdoDsn()
{
$dsn = 'sqlite:';
if (isset($this->_params['path'])) {
$dsn .= $this->_params['path'];
} else if (isset($this->_params['memory'])) {
$dsn .= ':memory:';
}
return $dsn;
} }
} }
\ No newline at end of file
...@@ -22,17 +22,19 @@ ...@@ -22,17 +22,19 @@
#namespace Doctrine::ORM::Internal; #namespace Doctrine::ORM::Internal;
/** /**
* The UnitOfWork is responsible for writing out changes to the database at * The UnitOfWork is responsible for tracking changes to objects during an
* the correct time and in the correct order. * "object-level" transaction and for writing out changes to the database at
* in the correct order.
* *
* Some terminology: * Some terminology:
* *
* <b>New entity</b>: A new entity is an entity that already has an identity but * <b>New entity</b>: A new entity is an entity that already has an identity but
* is not yet persisted into the database. This is usually the case for all * is not yet persisted into the database. This is usually the case for all
* newly saved entities that use a SEQUENCE id generator. Entities with an * newly saved/persisted entities that use a SEQUENCE id generator. Entities with an
* IDENTITY id generator get persisted as soon as they're saved in order to * IDENTITY id generator get persisted as soon as they're saved in order to
* obtain the identifier. Therefore entities that use an IDENTITY id generator * obtain the identifier. Therefore entities that use an IDENTITY id generator
* never appear in the list of new entities of the UoW. * never appear in the list of new entities of the UoW.
* New entities are inserted into the database when the is UnitOfWork committed.
* *
* <b>Dirty entity</b>: A dirty entity is a managed entity whose values have * <b>Dirty entity</b>: A dirty entity is a managed entity whose values have
* been altered. * been altered.
...@@ -53,7 +55,7 @@ ...@@ -53,7 +55,7 @@
* @author Roman Borschel <roman@code-factory.org> * @author Roman Borschel <roman@code-factory.org>
* @todo package:orm. Figure out a useful implementation. * @todo package:orm. Figure out a useful implementation.
*/ */
class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module class Doctrine_Connection_UnitOfWork
{ {
/** /**
* The identity map that holds references to all managed entities that have * The identity map that holds references to all managed entities that have
...@@ -94,6 +96,17 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module ...@@ -94,6 +96,17 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
*/ */
protected $_commitOrderCalculator; protected $_commitOrderCalculator;
/**
* Constructor.
* Created a new UnitOfWork.
*
* @param Doctrine_EntityManager $em
*/
public function __construct(Doctrine_EntityManager $em)
{
$this->_em = $em;
}
/** /**
* Commits the unit of work, executing all operations that have been postponed * Commits the unit of work, executing all operations that have been postponed
* up to this point. * up to this point.
...@@ -201,7 +214,6 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module ...@@ -201,7 +214,6 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
} }
/** /**
* buildFlushTree
* builds a flush tree that is used in transactions * builds a flush tree that is used in transactions
* *
* The returned array has all the initialized components in * The returned array has all the initialized components in
...@@ -301,14 +313,13 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module ...@@ -301,14 +313,13 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
} }
/** /**
* saveAll
* persists all the pending records from all tables * persists all the pending records from all tables
* *
* @throws PDOException if something went wrong at database level * @throws PDOException if something went wrong at database level
* @return void * @return void
* @deprecated * @deprecated
*/ */
public function saveAll() /*public function saveAll()
{ {
$this->conn->beginInternalTransaction(); $this->conn->beginInternalTransaction();
// get the flush tree // get the flush tree
...@@ -337,7 +348,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module ...@@ -337,7 +348,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
} }
} }
$this->conn->commit(); $this->conn->commit();
} }*/
/** /**
* Adds an entity to the pool of managed entities. * Adds an entity to the pool of managed entities.
......
...@@ -52,6 +52,12 @@ class Doctrine_ConnectionFactory ...@@ -52,6 +52,12 @@ class Doctrine_ConnectionFactory
} }
/**
* Creates a connection object with the specified parameters.
*
* @param array $params
* @return Connection
*/
public function createConnection(array $params) public function createConnection(array $params)
{ {
// check for existing pdo object // check for existing pdo object
...@@ -80,14 +86,6 @@ class Doctrine_ConnectionFactory ...@@ -80,14 +86,6 @@ class Doctrine_ConnectionFactory
if ( ! isset($params['driver'])) { if ( ! isset($params['driver'])) {
throw Doctrine_ConnectionFactory_Exception::driverRequired(); throw Doctrine_ConnectionFactory_Exception::driverRequired();
} }
// user
if ( ! isset($params['user'])) {
throw Doctrine_ConnectionFactory_Exception::userRequired();
}
// password
if ( ! isset($params['password'])) {
throw Doctrine_ConnectionFactory_Exception::passwordRequired();
}
// check validity of parameters // check validity of parameters
......
...@@ -148,7 +148,7 @@ class Doctrine_EntityManager ...@@ -148,7 +148,7 @@ class Doctrine_EntityManager
$this->_name = $name; $this->_name = $name;
$this->_metadataFactory = new Doctrine_ClassMetadata_Factory( $this->_metadataFactory = new Doctrine_ClassMetadata_Factory(
$this, new Doctrine_ClassMetadata_CodeDriver()); $this, new Doctrine_ClassMetadata_CodeDriver());
$this->_unitOfWork = new Doctrine_Connection_UnitOfWork($conn); $this->_unitOfWork = new Doctrine_Connection_UnitOfWork($this);
$this->_nullObject = Doctrine_Null::$INSTANCE; $this->_nullObject = Doctrine_Null::$INSTANCE;
} }
...@@ -463,8 +463,8 @@ class Doctrine_EntityManager ...@@ -463,8 +463,8 @@ class Doctrine_EntityManager
/** /**
* Creates an entity. Used for reconstitution as well as initial creation. * Creates an entity. Used for reconstitution as well as initial creation.
* *
* @param * @param string $className The name of the entity class.
* @param * @param array $data The data for the entity.
* @return Doctrine_Entity * @return Doctrine_Entity
*/ */
public function createEntity($className, array $data) public function createEntity($className, array $data)
...@@ -485,22 +485,19 @@ class Doctrine_EntityManager ...@@ -485,22 +485,19 @@ class Doctrine_EntityManager
} }
if ($isNew) { if ($isNew) {
$entity = new $className(true); $entity = new $className;
//$entity->_setData($data);
} else { } else {
$idHash = $this->_unitOfWork->getIdentifierHash($id); $idHash = $this->_unitOfWork->getIdentifierHash($id);
if ($entity = $this->_unitOfWork->tryGetByIdHash($idHash, if ($entity = $this->_unitOfWork->tryGetByIdHash($idHash,
$classMetadata->getRootClassName())) { $classMetadata->getRootClassName())) {
return $entity; return $entity;
} else { } else {
$entity = new $className(false); $entity = new $className;
//$entity->_setData($data);
$this->_unitOfWork->registerIdentity($entity); $this->_unitOfWork->registerIdentity($entity);
} }
} }
} else { } else {
$entity = new $className(true); $entity = new $className;
//$entity->_setData($data);
} }
/*if (count($data) < $classMetadata->getMappedColumnCount()) { /*if (count($data) < $classMetadata->getMappedColumnCount()) {
...@@ -508,7 +505,6 @@ class Doctrine_EntityManager ...@@ -508,7 +505,6 @@ class Doctrine_EntityManager
} else { } else {
$entity->_state(Doctrine_Entity::STATE_CLEAN); $entity->_state(Doctrine_Entity::STATE_CLEAN);
}*/ }*/
$this->_tmpEntityData = array();
return $entity; return $entity;
} }
...@@ -519,7 +515,9 @@ class Doctrine_EntityManager ...@@ -519,7 +515,9 @@ class Doctrine_EntityManager
*/ */
public function _getTmpEntityData() public function _getTmpEntityData()
{ {
return $this->_tmpEntityData; $data = $this->_tmpEntityData;
$this->_tmpEntityData = array();
return $data;
} }
/** /**
...@@ -528,7 +526,6 @@ class Doctrine_EntityManager ...@@ -528,7 +526,6 @@ class Doctrine_EntityManager
* classname will be returned. * classname will be returned.
* *
* @return string The name of the class to instantiate. * @return string The name of the class to instantiate.
* @todo Can be optimized performance-wise.
*/ */
private function _inferCorrectClassName(array $data, $className) private function _inferCorrectClassName(array $data, $className)
{ {
...@@ -553,10 +550,10 @@ class Doctrine_EntityManager ...@@ -553,10 +550,10 @@ class Doctrine_EntityManager
* *
* @return UnitOfWork * @return UnitOfWork
*/ */
public function getUnitOfWork() /*public function getUnitOfWork()
{ {
return $this->_unitOfWork; return $this->_unitOfWork;
} }*/
/** /**
* Gets the EventManager used by the EntityManager. * Gets the EventManager used by the EntityManager.
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
* instances as well as keeping track of all created EntityManagers and * instances as well as keeping track of all created EntityManagers and
* hard bindings to Entities. * hard bindings to Entities.
* *
* @author Roman Borschel <roman@code-factory.org>
* @since 2.0 * @since 2.0
*/ */
class Doctrine_EntityManagerFactory class Doctrine_EntityManagerFactory
...@@ -52,21 +53,44 @@ class Doctrine_EntityManagerFactory ...@@ -52,21 +53,44 @@ class Doctrine_EntityManagerFactory
*/ */
private $_config; private $_config;
/**
* Constructor.
* Creates a new EntityManagerFactory.
*/
public function __construct() public function __construct()
{ {
$this->_connFactory = new Doctrine_ConnectionFactory(); $this->_connFactory = new Doctrine_ConnectionFactory();
} }
/**
* Sets the Configuration that is injected into all EntityManagers
* (and their Connections) that are created by this factory.
*
* @param Doctrine_Configuration $eventManager
*/
public function setConfiguration(Doctrine_Configuration $config) public function setConfiguration(Doctrine_Configuration $config)
{ {
$this->_config = $config; $this->_config = $config;
} }
/**
* Sets the EventManager that is injected into all EntityManagers
* (and their Connections) that are created by this factory.
*
* @param Doctrine_EventManager $eventManager
*/
public function setEventManager(Doctrine_EventManager $eventManager) public function setEventManager(Doctrine_EventManager $eventManager)
{ {
$this->_eventManager = $eventManager; $this->_eventManager = $eventManager;
} }
/**
* Creates an EntityManager.
*
* @param unknown_type $connParams
* @param unknown_type $name
* @return unknown
*/
public function createEntityManager($connParams, $name = null) public function createEntityManager($connParams, $name = null)
{ {
if ( ! $this->_config) { if ( ! $this->_config) {
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
*/ */
/** /**
* The default mapping strategy maps a single entity instance to a single database table, * The default persister strategy maps a single entity instance to a single database table,
* as is the case in Single Table Inheritance & Concrete Table Inheritance. * as is the case in Single Table Inheritance & Concrete Table Inheritance.
* *
* @author Roman Borschel <roman@code-factory.org> * @author Roman Borschel <roman@code-factory.org>
......
...@@ -30,7 +30,8 @@ ...@@ -30,7 +30,8 @@
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.phpdoctrine.org * @link www.phpdoctrine.org
* @since 1.0 * @since 1.0
* @version $Revision$ * @version $Revision$
* @todo Remove. The 2.0 event system has no listener interfaces.
*/ */
class Doctrine_EventListener implements Doctrine_EventListener_Interface class Doctrine_EventListener implements Doctrine_EventListener_Interface
{ {
......
...@@ -21,12 +21,33 @@ ...@@ -21,12 +21,33 @@
#namespace Doctrine::Common; #namespace Doctrine::Common;
/**
* The EventManager is the central point of Doctrine's event listener system.
* Listeners are registered on the manager and events are dispatch through the
* manager.
*
* @author Roman Borschel <roman@code-factory.org>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @since 2.0
*/
class Doctrine_EventManager class Doctrine_EventManager
{ {
/**
* Map of registered listeners.
* <event> => <listeners>
*
* @var array
*/
private $_listeners = array(); private $_listeners = array();
/**
public function dispatchEvent($event) { * Dispatches an event to all registered listeners.
*
* @param string|Event $event The name of the event or the event object.
* @return boolean
*/
public function dispatchEvent($event)
{
$argIsCallback = is_string($event); $argIsCallback = is_string($event);
$callback = $argIsCallback ? $event : $event->getType(); $callback = $argIsCallback ? $event : $event->getType();
...@@ -40,25 +61,43 @@ class Doctrine_EventManager ...@@ -40,25 +61,43 @@ class Doctrine_EventManager
return ! $event->getDefaultPrevented(); return ! $event->getDefaultPrevented();
} }
/**
public function getListeners($callback = null) { * Gets the listeners of a specific event or all listeners.
return $callback ? $this->_listeners[$callback] : $this->_listeners; *
* @param string $event The name of the event.
* @return
*/
public function getListeners($event = null)
{
return $event ? $this->_listeners[$event] : $this->_listeners;
} }
/**
public function hasListeners($callback) { * Checks whether an event has any registered listeners.
return isset($this->_listeners[$callback]); *
* @param string $event
* @return boolean
*/
public function hasListeners($event)
{
return isset($this->_listeners[$event]);
} }
/**
public function addEventListener($callbacks, $listener) { * Adds an event listener that listens on the specified events.
*
* @param string|array $events The event(s) to listen on.
* @param object $listener The listener object.
*/
public function addEventListener($events, $listener)
{
// TODO: maybe check for duplicate registrations? // TODO: maybe check for duplicate registrations?
if ( ! is_array($callbacks)) { if ( ! is_array($events)) {
$callbacks = array($callbacks); $events = array($events);
} }
foreach ($callbacks as $callback) { foreach ($events as $event) {
$this->_listeners[$callback] = $listener; $this->_listeners[$event] = $listener;
} }
} }
} }
......
...@@ -46,6 +46,11 @@ class Doctrine_Exception extends Exception ...@@ -46,6 +46,11 @@ class Doctrine_Exception extends Exception
public function getInnerException() public function getInnerException()
{ {
return $this->_innerException; return $this->_innerException;
}
public static function notImplemented($method, $class)
{
return new self("The method '$method' is not implemented in the class '$class'.");
} }
} }
...@@ -355,8 +355,6 @@ class Doctrine_HydratorNew extends Doctrine_Hydrator_Abstract ...@@ -355,8 +355,6 @@ class Doctrine_HydratorNew extends Doctrine_Hydrator_Abstract
foreach ($data as $key => $value) { foreach ($data as $key => $value) {
// Parse each column name only once. Cache the results. // Parse each column name only once. Cache the results.
if ( ! isset($cache[$key])) { if ( ! isset($cache[$key])) {
// check ignored names. fastest solution for now. if we get more we'll start
// to introduce a list.
if ($this->_isIgnoredName($key)) continue; if ($this->_isIgnoredName($key)) continue;
// cache general information like the column name <-> field name mapping // cache general information like the column name <-> field name mapping
...@@ -439,8 +437,6 @@ class Doctrine_HydratorNew extends Doctrine_Hydrator_Abstract ...@@ -439,8 +437,6 @@ class Doctrine_HydratorNew extends Doctrine_Hydrator_Abstract
foreach ($data as $key => $value) { foreach ($data as $key => $value) {
// Parse each column name only once. Cache the results. // Parse each column name only once. Cache the results.
if ( ! isset($cache[$key])) { if ( ! isset($cache[$key])) {
// check ignored names. fastest solution for now. if we get more we'll start
// to introduce a list.
if ($this->_isIgnoredName($key)) continue; if ($this->_isIgnoredName($key)) continue;
// cache general information like the column name <-> field name mapping // cache general information like the column name <-> field name mapping
......
...@@ -30,7 +30,8 @@ ...@@ -30,7 +30,8 @@
* @link www.phpdoctrine.org * @link www.phpdoctrine.org
* @since 1.0 * @since 1.0
* @version $Revision$ * @version $Revision$
* @author Konsta Vesterinen <kvesteri@cc.hut.fi> * @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @todo Remove.
*/ */
class Doctrine_Manager implements Doctrine_Configurable, Countable, IteratorAggregate class Doctrine_Manager implements Doctrine_Configurable, Countable, IteratorAggregate
{ {
......
...@@ -540,13 +540,14 @@ class Doctrine_Query extends Doctrine_Query_Abstract ...@@ -540,13 +540,14 @@ class Doctrine_Query extends Doctrine_Query_Abstract
return $this; return $this;
} }
/** /**
* Empty template method to provide Query subclasses with the possibility * Empty template method to provide Query subclasses with the possibility
* to hook into the query building procedure, doing any custom / specialized * to hook into the query building procedure, doing any custom / specialized
* query building procedures that are neccessary. * query building procedures that are neccessary.
* *
* @return void * @return void
* @deprecated Should be removed. Extending Query is no good solution. Should
* Things like this should be done through listeners.
*/ */
public function preQuery() public function preQuery()
{ {
...@@ -559,12 +560,43 @@ class Doctrine_Query extends Doctrine_Query_Abstract ...@@ -559,12 +560,43 @@ class Doctrine_Query extends Doctrine_Query_Abstract
* post query procedures (for example logging) that are neccessary. * post query procedures (for example logging) that are neccessary.
* *
* @return void * @return void
* @deprecated Should be removed. Extending Query is no good solution. Should
* Things like this should be done through listeners.
*/ */
public function postQuery() public function postQuery()
{ {
} }
/**
* Gets the list of results for the query.
*
* @param integer $hydrationMode
* @return mixed
*/
public function getResultList($hydrationMode = null)
{
return $this->execute(array(), $hydrationMode);
}
/**
* Gets the single result of the query.
* Enforces the uniqueness of the result. If the result is not unique,
* a QueryException is thrown.
*
* @param integer $hydrationMode
* @return mixed
* @throws QueryException If the query result is not unique.
*/
public function getSingleResult($hydrationMode = null)
{
$result = $this->execute(array(), $hydrationMode);
if (count($result) > 1) {
throw Doctrine_Query_Exception::nonUniqueResult();
}
return is_array($result) ? array_shift($result) : $result->getFirst();
}
/** /**
* This method is automatically called when this Doctrine_Hydrate is serialized. * This method is automatically called when this Doctrine_Hydrate is serialized.
......
...@@ -987,5 +987,28 @@ abstract class Doctrine_Query_Abstract ...@@ -987,5 +987,28 @@ abstract class Doctrine_Query_Abstract
* @return string SQL query * @return string SQL query
*/ */
abstract public function getSql(); abstract public function getSql();
/**
* Sets a query parameter.
*
* @param string|integer $key
* @param mixed $value
*/
public function setParameter($key, $value)
{
$this->_params[$key] = $value;
}
/**
* Sets a collection of query parameters.
*
* @param array $params
*/
public function setParameters(array $params)
{
foreach ($params as $key => $value) {
$this->setParameter($key, $value);
}
}
} }
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
* and is licensed under the LGPL. For more information, see * and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.org>. * <http://www.phpdoctrine.org>.
*/ */
Doctrine::autoload('Doctrine_Exception');
/** /**
* Doctrine_Query_Exception * Doctrine_Query_Exception
* *
...@@ -31,4 +31,9 @@ Doctrine::autoload('Doctrine_Exception'); ...@@ -31,4 +31,9 @@ Doctrine::autoload('Doctrine_Exception');
* @author Konsta Vesterinen <kvesteri@cc.hut.fi> * @author Konsta Vesterinen <kvesteri@cc.hut.fi>
*/ */
class Doctrine_Query_Exception extends Doctrine_Exception class Doctrine_Query_Exception extends Doctrine_Exception
{ } {
\ No newline at end of file public static function nonUniqueResult()
{
return new self("The query contains more than one result.");
}
}
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
* and is licensed under the LGPL. For more information, see * and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.org>. * <http://www.phpdoctrine.org>.
*/ */
Doctrine::autoload('Doctrine_Connection_Module');
/** /**
* Doctrine_Sequence * Doctrine_Sequence
* The base class for sequence handling drivers. * The base class for sequence handling drivers.
......
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
#namespace Doctrine::DBAL::Transactions; #namespace Doctrine::DBAL::Transactions;
/** /**
* Doctrine_Transaction
* Handles transaction savepoint and isolation abstraction * Handles transaction savepoint and isolation abstraction
* *
* @author Konsta Vesterinen <kvesteri@cc.hut.fi> * @author Konsta Vesterinen <kvesteri@cc.hut.fi>
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
* @author Konsta Vesterinen <kvesteri@cc.hut.fi> * @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link http://www.phpdoctrine.org * @link http://www.phpdoctrine.org
* @since 1.0 * @since 2.0
* @version $Revision$ * @version $Revision$
*/ */
class Orm_Query_DqlGenerationTest extends Doctrine_OrmTestCase class Orm_Query_DqlGenerationTest extends Doctrine_OrmTestCase
......
...@@ -9,7 +9,7 @@ class Orm_UnitOfWorkTest extends Doctrine_OrmTestCase ...@@ -9,7 +9,7 @@ class Orm_UnitOfWorkTest extends Doctrine_OrmTestCase
protected function setUp() { protected function setUp() {
parent::setUp(); parent::setUp();
$this->_user = new ForumUser(); $this->_user = new ForumUser();
$this->_unitOfWork = $this->_em->getUnitOfWork(); $this->_unitOfWork = new Doctrine_Connection_UnitOfWork($this->_em);
} }
protected function tearDown() { protected function tearDown() {
......
...@@ -19,7 +19,8 @@ class Doctrine_TestUtil ...@@ -19,7 +19,8 @@ class Doctrine_TestUtil
//return Doctrine_Manager::connection($dsn, 'testconn'); //return Doctrine_Manager::connection($dsn, 'testconn');
} else { } else {
$params = array( $params = array(
'pdo' => new PDO('sqlite::memory:') 'driver' => 'sqlite',
'memory' => true
); );
} }
......
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