Location: PHPKode > projects > Spiral > ametaireau-spiral-272a2b1/framework/persistence/classes/ORMObjectRepository.php
<?php

namespace spiral\framework\persistence;

use \spiral\framework\persistence\orm\meta\MetaConverter;
use \spiral\framework\persistence\orm\UnitOfWork;
use \spiral\framework\persistence\orm\IdentityMap;
use \spiral\framework\persistence\orm\OIDGenerator;
use \spiral\framework\persistence\query\Query;

/**
 * ORM object repository
 * 
 * This class implements an object-relational mapper under the {@link ObjectRepository} interface.
 * 
 * The ORM implementation is based on many Martin Fowler persistence patterns.
 * You can learn more on it at {@link http://martinfowler.com/eaaCatalog/}.
 * 
 * The {@link StorageEngine} is an adapter to a relational storage tool like a 
 * relational database management system (RDBMS). The communication with a {@link StorageEngine}
 * is done via {@link MetaObject}s that are relational representations of native objects.
 * 
 * The conversion from native object to {@link MetaObject} is done thanks to a {@link MetaConverter}
 * component which is also responsible of converting {@link MetaObject}s to native objects.
 * 
 * The {@link UnitOfWork} is responsible of managing objects status in order to persist objects and only
 * objects that need to.
 * 
 * The {@link IdentityMap} is a map of all native objects that belong to the repository.
 * 
 * The {@link OIDGenerator}'s role is to generate unique OIDs (as its name tells !).
 * 
 * TODO Talk about the QueryInterpreter
 * 
 * @see		StorageEngine
 * @see		MetaConverter
 * @see		UnitOfWork
 * @see		IdentityMap
 * @see		OIDGenerator
 * 
 * @author		Frédéric Sureau <hide@address.com>
 * @copyright	2009 Spiral-project.org <http://www.spiral-project.org>
 * @license		GNU General Public License <http://www.gnu.org/licenses/gpl.html>
 * @todo		Attributes should be initialized
 */
class ORMObjectRepository implements ObjectRepository
{
	/**
	 * Identity map
	 * 
	 * @var	IdentityMap
	 */
	private $_identityMap = null;
	
	/**
	 * OID generator
	 * 
	 * @var	OIDGenerator
	 */
	private $_oidGenerator = null;
	
	/**
	 * Unit of work
	 * 
	 * @var	UnitOfWork
	 */
	private $_unitOfWork = null;
	
	/**
	 * Ensures that the repository contains the specified object.
	 * 
	 * If the repository does not contain the object yet, the object is made persistent and
	 * the OID associated to this object by the repository is returned.
	 * If the object is already registered in the repository, return the existing OID for this object.
	 * 
	 * FIXME The object will not be registered as dirty if it has changed.
	 * 
	 * @param	object	$object		The object to add
	 * @return	mixed	The OID associated to the object by the repository
	 */
	public function add($object)
	{
		// If object is already known, only return its OID
		if($this->_identityMap->containsObject($object))
		{
			// XXX Can check if the object has changed ? Just a proposition.
			return $this->_identityMap->findOIDByObject($object);
		}
		
		// If the object is not in the identity map, add it to the unit of work
		$oid = $this->_oidGenerator->generateOID($object);
		
		$this->_unitOfWork->add($oid, $object);
		$this->_identityMap->register($oid, $object);
		
		return $oid;
	}
	
	/**
	 * Remove an object from the repository
	 * 
	 * The object will be removed from the repository and will not be persistent anymore.
	 * If the object does not exists in the repository, nothing is done.
	 * 
	 * The object must have been loaded in the identity map (means via the {@link ObjectRepository}) before
	 * or it will not be removed.
	 * 
	 * @param	object	$object		The object to remove
	 * @return	void
	 */
	public function remove($object)
	{
		if($this->_identityMap->containsObject($object))
		{
			$oid = $this->_identityMap->findOIDByObject($object);
			$this->_unitOfWork->delete($oid, $object);
		}
	}
	
	/**
	 * Find an object in the repository by its OID
	 * 
	 * Return NULL if no object with this OID can be found.
	 * 
	 * @param	mixed			$oid		The OID of the object you want to find
	 * @return	object|NULL		The object corresponding to the OID or NULL if no object found
	 */
	public function findByOID($oid)
	{
		$object = $this->_identityMap->findObjectByOID($oid);
		
		// TODO Search in the storage engine too !
		
		return $object;
	}
	
	/**
	 * Find objects in the repository using a query
	 * 
	 * Return an array containing all objects that match the query.
	 * The array can be empty if no object can be found.
	 * 
	 * @see		Query
	 * 
	 * @param	Query	$query		Query that you want to execute
	 * @return	array	Array of objects matching the query
	 */
	public function findByQuery(Query $query)
	{
		// TODO Search in the storage engine
	}
	
	/**
	 * Define the identity map to use
	 * 
	 * @param	IdentityMap		$identityMap		Identity map to use
	 * @return	void
	 */
	public function setIdentityMap(IdentityMap $identityMap)
	{
		$this->_identityMap = $identityMap;
	}
	
	/**
	 * Define the OID generator to use
	 * 
	 * @param	OIDGenerator		$oidGenerator		OID generator to use
	 * @return	void
	 */
	public function setOIDGenerator(OIDGenerator  $oidGenerator)
	{
		$this->_oidGenerator = $oidGenerator;
	}
	
	/**
	 * Define the unit of work to use
	 * 
	 * @param	UnitOfWork		$unitOfWork		Unit of work to use
	 * @return	void
	 */
	public function setUnitOfWork(UnitOfWork $unitOfWork)
	{
		$this->_unitOfWork = $unitOfWork;
	}
}
Return current item: Spiral