From 2d0b4abcaaa097e6e1b5bf3c43e36a70532cf49a Mon Sep 17 00:00:00 2001 From: zYne Date: Thu, 10 May 2007 19:27:11 +0000 Subject: [PATCH] --- draft/Record.php | 1465 --------------------------------- draft/new-core/Collection.php | 2 +- draft/new-core/Hydrate.php | 2 +- draft/new-core/Query.php | 4 +- draft/new-core/Record.php | 2 +- 5 files changed, 5 insertions(+), 1470 deletions(-) delete mode 100644 draft/Record.php diff --git a/draft/Record.php b/draft/Record.php deleted file mode 100644 index bccc2881f..000000000 --- a/draft/Record.php +++ /dev/null @@ -1,1465 +0,0 @@ -. - */ -Doctrine::autoload('Doctrine_Access'); -/** - * Doctrine_Record - * All record classes should inherit this super class - * - * @author Konsta Vesterinen - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @package Doctrine - * @category Object Relational Mapping - * @link www.phpdoctrine.com - * @since 1.0 - * @version $Revision$ - */ -abstract class Doctrine_Record extends Doctrine_Access implements Countable, IteratorAggregate, Serializable { - /** - * STATE CONSTANTS - */ - - /** - * DIRTY STATE - * a Doctrine_Record is in dirty state when its properties are changed - */ - const STATE_DIRTY = 1; - /** - * TDIRTY STATE - * a Doctrine_Record is in transient dirty state when it is created and some of its fields are modified - * but it is NOT yet persisted into database - */ - const STATE_TDIRTY = 2; - /** - * CLEAN STATE - * a Doctrine_Record is in clean state when all of its properties are loaded from the database - * and none of its properties are changed - */ - const STATE_CLEAN = 3; - /** - * PROXY STATE - * a Doctrine_Record is in proxy state when its properties are not fully loaded - */ - const STATE_PROXY = 4; - /** - * NEW TCLEAN - * a Doctrine_Record is in transient clean state when it is created and none of its fields are modified - */ - const STATE_TCLEAN = 5; - /** - * DELETED STATE - * a Doctrine_Record turns into deleted state when it is deleted - */ - const STATE_DELETED = 6; - /** - * the following protected variables use '_' prefixes, the reason for this is to allow child - * classes call for example $this->id, $this->state for getting the values of columns named 'id' and 'state' - * rather than the values of these protected variables - */ - /** - * @var object Doctrine_Table $table the factory that created this data access object - */ - protected $_table; - /** - * @var integer $id the primary keys of this object - */ - protected $_id = array(); - /** - * @var array $data the record data - */ - protected $_data = array(); - /** - * @var integer $state the state of this record - * @see STATE_* constants - */ - protected $_state; - /** - * @var array $modified an array containing properties that have been modified - */ - protected $_modified = array(); - /** - * @var Doctrine_Validator_ErrorStack error stack object - */ - protected $_errorStack; - /** - * @var Doctrine_Node_ node object - */ - protected $_node; - /** - * @var array $references an array containing all the references - */ - private $references = array(); - /** - * @var array $originals an array containing all the original references - */ - private $originals = array(); - /** - * @var integer $index this index is used for creating object identifiers - */ - private static $index = 1; - /** - * @var Doctrine_Null $null a Doctrine_Null object used for extremely fast - * null value testing - */ - private static $null; - /** - * @var integer $oid object identifier, each Record object has a unique object identifier - */ - private $oid; - - /** - * constructor - * @param Doctrine_Table|null $table a Doctrine_Table object or null, - * if null the table object is retrieved from current connection - * - * @param boolean $isNewEntry whether or not this record is transient - * - * @throws Doctrine_Connection_Exception if object is created using the new operator and there are no - * open connections - * @throws Doctrine_Record_Exception if the cleanData operation fails somehow - */ - public function __construct($table = null, $isNewEntry = false) { - if(isset($table) && $table instanceof Doctrine_Table) { - $this->_table = $table; - $exists = ( ! $isNewEntry); - } else { - $class = get_class($this); - // get the table of this class - $this->_table = Doctrine_Manager::getInstance()->getConnectionForComponent($class)->getTable(get_class($this)); - $exists = false; - } - - // Check if the current connection has the records table in its registry - // If not this record is only used for creating table definition and setting up - // relations. - - if($this->_table->getConnection()->hasTable($this->_table->getComponentName())) { - - $this->oid = self::$index; - - self::$index++; - - $keys = $this->_table->getPrimaryKeys(); - - if( ! $exists) { - // listen the onPreCreate event - $this->_table->getAttribute(Doctrine::ATTR_LISTENER)->onPreCreate($this); - } else { - - // listen the onPreLoad event - $this->_table->getAttribute(Doctrine::ATTR_LISTENER)->onPreLoad($this); - } - // get the data array - $this->_data = $this->_table->getData(); - - - // get the column count - $count = count($this->_data); - - // clean data array - $this->cleanData(); - - $this->prepareIdentifiers($exists); - - if( ! $exists) { - - if($count > 0) - $this->_state = Doctrine_Record::STATE_TDIRTY; - else - $this->_state = Doctrine_Record::STATE_TCLEAN; - - // set the default values for this record - $this->setDefaultValues(); - - // listen the onCreate event - $this->_table->getAttribute(Doctrine::ATTR_LISTENER)->onCreate($this); - - } else { - $this->_state = Doctrine_Record::STATE_CLEAN; - - if($count < $this->_table->getColumnCount()) { - $this->_state = Doctrine_Record::STATE_PROXY; - } - - // listen the onLoad event - $this->_table->getAttribute(Doctrine::ATTR_LISTENER)->onLoad($this); - } - - $this->_errorStack = new Doctrine_Validator_ErrorStack(); - - $repository = $this->_table->getRepository(); - $repository->add($this); - } - $this->construct(); - } - /** - * initNullObject - * - * @param Doctrine_Null $null - * @return void - */ - public static function initNullObject(Doctrine_Null $null) { - self::$null = $null; - } - /** - * @return Doctrine_Null - */ - public static function getNullObject() { - return self::$null; - } - /** - * setUp - * this method is used for setting up relations and attributes - * it should be implemented by child classes - * - * @return void - */ - public function setUp() { } - /** - * construct - * Empty tempalte method to provide concrete Record classes with the possibility - * to hook into the constructor procedure - * - * @return void - */ - public function construct() { } - /** - * getOID - * returns the object identifier - * - * @return integer - */ - public function getOID() { - return $this->oid; - } - /** - * isValid - * - * @return boolean whether or not this record passes all column validations - */ - public function isValid() { - if( ! $this->_table->getAttribute(Doctrine::ATTR_VLD)) - return true; - - // Clear the stack from any previous errors. - $this->_errorStack->clear(); - - // Run validation process - $validator = new Doctrine_Validator(); - $validator->validateRecord($this); - $this->validate(); - if ($this->_state == self::STATE_TDIRTY || $this->_state == self::STATE_TCLEAN) { - $this->validateOnInsert(); - } else { - $this->validateOnUpdate(); - } - - return $this->_errorStack->count() == 0 ? true : false; - } - /** - * Emtpy template method to provide concrete Record classes with the possibility - * to hook into the validation procedure, doing any custom / specialized - * validations that are neccessary. - */ - protected function validate() {} - /** - * Empty tempalte method to provide concrete Record classes with the possibility - * to hook into the validation procedure only when the record is going to be - * updated. - */ - protected function validateOnUpdate() {} - /** - * Empty tempalte method to provide concrete Record classes with the possibility - * to hook into the validation procedure only when the record is going to be - * inserted into the data store the first time. - */ - protected function validateOnInsert() {} - /** - * getErrorStack - * - * @return Doctrine_Validator_ErrorStack returns the errorStack associated with this record - */ - public function getErrorStack() { - return $this->_errorStack; - } - /** - * setDefaultValues - * sets the default values for records internal data - * - * @param boolean $overwrite whether or not to overwrite the already set values - * @return boolean - */ - public function setDefaultValues($overwrite = false) { - if( ! $this->_table->hasDefaultValues()) - return false; - - foreach($this->_data as $column => $value) { - $default = $this->_table->getDefaultValueOf($column); - - if($default === null) - $default = self::$null; - - if($value === self::$null || $overwrite) { - $this->_data[$column] = $default; - $this->_modified[] = $column; - $this->_state = Doctrine_Record::STATE_TDIRTY; - } - } - } - /** - * cleanData - * this method does several things to records internal data - * - * 1. It unserializes array and object typed columns - * 2. Uncompresses gzip typed columns - * 3. Gets the appropriate enum values for enum typed columns - * 4. Initializes special null object pointer for null values (for fast column existence checking purposes) - * - * - * example: - * - * $data = array("name"=>"John","lastname"=> null, "id" => 1,"unknown" => "unknown"); - * $names = array("name", "lastname", "id"); - * $data after operation: - * $data = array("name"=>"John","lastname" => Object(Doctrine_Null)); - * - * here column 'id' is removed since its auto-incremented primary key (read-only) - * - * @throws Doctrine_Record_Exception if unserialization of array/object typed column fails or - * if uncompression of gzip typed column fails - * - * @return integer - */ - private function cleanData($debug = false) { - $tmp = $this->_data; - - $this->_data = array(); - - $count = 0; - - foreach($this->_table->getColumnNames() as $name) { - $type = $this->_table->getTypeOf($name); - - if( ! isset($tmp[$name])) { - $this->_data[$name] = self::$null; - } else { - switch($type): - case "array": - case "object": - - if($tmp[$name] !== self::$null) { - if(is_string($tmp[$name])) { - $value = unserialize($tmp[$name]); - - if($value === false) - throw new Doctrine_Record_Exception("Unserialization of $name failed. ".var_dump(substr($tmp[$lower],0,30)."...",true)); - } else - $value = $tmp[$name]; - - $this->_data[$name] = $value; - } - break; - case "gzip": - - if($tmp[$name] !== self::$null) { - $value = gzuncompress($tmp[$name]); - - - if($value === false) - throw new Doctrine_Record_Exception("Uncompressing of $name failed."); - - $this->_data[$name] = $value; - } - break; - case "enum": - $this->_data[$name] = $this->_table->enumValue($name, $tmp[$name]); - break; - default: - $this->_data[$name] = $tmp[$name]; - endswitch; - $count++; - } - } - - - return $count; - } - /** - * prepareIdentifiers - * prepares identifiers for later use - * - * @param boolean $exists whether or not this record exists in persistent data store - * @return void - */ - private function prepareIdentifiers($exists = true) { - switch($this->_table->getIdentifierType()): - case Doctrine_Identifier::AUTO_INCREMENT: - case Doctrine_Identifier::SEQUENCE: - $name = $this->_table->getIdentifier(); - - if($exists) { - if(isset($this->_data[$name]) && $this->_data[$name] !== self::$null) - $this->_id[$name] = $this->_data[$name]; - } - - unset($this->_data[$name]); - - break; - case Doctrine_Identifier::NORMAL: - $this->_id = array(); - $name = $this->_table->getIdentifier(); - - if(isset($this->_data[$name]) && $this->_data[$name] !== self::$null) - $this->_id[$name] = $this->_data[$name]; - break; - case Doctrine_Identifier::COMPOSITE: - $names = $this->_table->getIdentifier(); - - - foreach($names as $name) { - if($this->_data[$name] === self::$null) - $this->_id[$name] = null; - else - $this->_id[$name] = $this->_data[$name]; - } - break; - endswitch; - } - /** - * serialize - * this method is automatically called when this Doctrine_Record is serialized - * - * @return array - */ - public function serialize() { - $this->_table->getAttribute(Doctrine::ATTR_LISTENER)->onSleep($this); - - $vars = get_object_vars($this); - - unset($vars['references']); - unset($vars['originals']); - unset($vars['_table']); - - $name = $this->_table->getIdentifier(); - $this->_data = array_merge($this->_data, $this->_id); - - foreach($this->_data as $k => $v) { - if($v instanceof Doctrine_Record) - unset($vars['_data'][$k]); - elseif($v === self::$null) { - unset($vars['_data'][$k]); - } else { - switch($this->_table->getTypeOf($k)): - case "array": - case "object": - $vars['_data'][$k] = serialize($vars['_data'][$k]); - break; - endswitch; - } - } - - return serialize($vars); - } - /** - * unseralize - * this method is automatically called everytime a Doctrine_Record object is unserialized - * - * @param string $serialized Doctrine_Record as serialized string - * @throws Doctrine_Record_Exception if the cleanData operation fails somehow - * @return void - */ - public function unserialize($serialized) { - $manager = Doctrine_Manager::getInstance(); - $connection = $manager->getCurrentConnection(); - - $this->oid = self::$index; - self::$index++; - - $this->_table = $connection->getTable(get_class($this)); - - - $array = unserialize($serialized); - - foreach($array as $name => $values) { - $this->$name = $values; - } - - $this->_table->getRepository()->add($this); - - $this->cleanData(); - - $this->prepareIdentifiers($this->exists()); - - $this->_table->getAttribute(Doctrine::ATTR_LISTENER)->onWakeUp($this); - } - /** - * getState - * returns the current state of the object - * - * @see Doctrine_Record::STATE_* constants - * @return integer - */ - public function getState() { - return $this->_state; - } - /** - * state - * returns / assigns the state of this record - * - * @param integer|string $state if set, this method tries to set the record state to $state - * @see Doctrine_Record::STATE_* constants - * - * @throws Doctrine_Record_State_Exception if trying to set an unknown state - * @return null|integer - */ - public function state($state = null) { - if($state == null) { - return $this->_state; - } - $err = false; - if(is_integer($state)) { - - if($state >= 1 && $state <= 6) - $this->_state = $state; - else - $err = true; - - } elseif(is_string($state)) { - $upper = strtoupper($state); - switch($upper) { - case 'DIRTY': - case 'CLEAN': - case 'TDIRTY': - case 'TCLEAN': - case 'PROXY': - case 'DELETED': - $this->_state = constant('Doctrine_Record::STATE_' . $upper); - break; - default: - $err = true; - } - } - - if($err) - throw new Doctrine_Record_State_Exception('Unknown record state ' . $state); - } - /** - * refresh - * refresh internal data from the database - * - * @throws Doctrine_Record_Exception When the refresh operation fails (when the database row - * this record represents does not exist anymore) - * @return boolean - */ - final public function refresh() { - $id = $this->obtainIdentifier(); - if( ! is_array($id)) - $id = array($id); - - if(empty($id)) - return false; - - $id = array_values($id); - - $query = $this->_table->getQuery()." WHERE ".implode(" = ? AND ",$this->_table->getPrimaryKeys())." = ?"; - $stmt = $this->_table->getConnection()->execute($query,$id); - - $this->_data = $stmt->fetch(PDO::FETCH_ASSOC); - - - if( ! $this->_data) - throw new Doctrine_Record_Exception('Failed to refresh. Record does not exist anymore'); - - $this->_data = array_change_key_case($this->_data, CASE_LOWER); - - $this->_modified = array(); - $this->cleanData(true); - - $this->prepareIdentifiers(); - - $this->_state = Doctrine_Record::STATE_CLEAN; - - $this->_table->getAttribute(Doctrine::ATTR_LISTENER)->onLoad($this); - - return true; - } - /** - * factoryRefresh - * refreshes the data from outer source (Doctrine_Table) - * - * @throws Doctrine_Record_Exception When the primary key of this record doesn't match the primary key fetched from a collection - * @return void - */ - final public function factoryRefresh() { - $this->_data = $this->_table->getData(); - $old = $this->_id; - - $this->cleanData(); - - $this->prepareIdentifiers(); - - if($this->_id != $old) - throw new Doctrine_Record_Exception("The refreshed primary key doesn't match the one in the record memory.", Doctrine::ERR_REFRESH); - - $this->_state = Doctrine_Record::STATE_CLEAN; - $this->_modified = array(); - - $this->_table->getAttribute(Doctrine::ATTR_LISTENER)->onLoad($this); - } - /** - * getTable - * returns the table object for this record - * - * @return object Doctrine_Table a Doctrine_Table object - */ - final public function getTable() { - return $this->_table; - } - /** - * getData - * return all the internal data - * - * @return array an array containing all the properties - */ - final public function getData() { - return $this->_data; - } - /** - * rawGet - * returns the value of a property, if the property is not yet loaded - * this method does NOT load it - * - * @param $name name of the property - * @throws Doctrine_Record_Exception if trying to get an unknown property - * @return mixed - */ - - public function rawGet($name) { - if( ! isset($this->_data[$name])) - throw new Doctrine_Record_Exception('Unknown property '. $name); - - if($this->_data[$name] === self::$null) - return null; - - return $this->_data[$name]; - } - - /** - * load - * loads all the unitialized properties from the database - * - * @return boolean - */ - public function load() { - // only load the data from database if the Doctrine_Record is in proxy state - if($this->_state == Doctrine_Record::STATE_PROXY) { - $this->refresh(); - - $this->_state = Doctrine_Record::STATE_CLEAN; - - return true; - } - return false; - } - /** - * get - * returns a value of a property or a related component - * - * @param mixed $name name of the property or related component - * @param boolean $invoke whether or not to invoke the onGetProperty listener - * @throws Doctrine_Record_Exception if trying to get a value of unknown property / related component - * @return mixed - */ - public function get($name, $invoke = true) { - - $listener = $this->_table->getAttribute(Doctrine::ATTR_LISTENER); - $value = self::$null; - $lower = strtolower($name); - - if(isset($this->_data[$lower])) { - - // check if the property is null (= it is the Doctrine_Null object located in self::$null) - if($this->_data[$lower] === self::$null) - $this->load(); - - - if($this->_data[$lower] === self::$null) - $value = null; - else - $value = $this->_data[$lower]; - - } - - - if($value !== self::$null) { - - $value = $this->_table->invokeGet($this, $name, $value); - - if($invoke && $name !== $this->_table->getIdentifier()) - return $this->_table->getAttribute(Doctrine::ATTR_LISTENER)->onGetProperty($this, $name, $value); - else - return $value; - - return $value; - } - - - if(isset($this->_id[$lower])) - return $this->_id[$lower]; - - if($name === $this->_table->getIdentifier()) - return null; - - $rel = $this->_table->getRelation($name); - - try { - if( ! isset($this->references[$name])) - $this->loadReference($name); - } catch(Doctrine_Table_Exception $e) { - throw new Doctrine_Record_Exception("Unknown property / related component '$name'."); - } - - return $this->references[$name]; - } - - /** - * set - * method for altering properties and Doctrine_Record references - * if the load parameter is set to false this method will not try to load uninitialized record data - * - * @param mixed $name name of the property or reference - * @param mixed $value value of the property or reference - * @param boolean $load whether or not to refresh / load the uninitialized record data - * - * @throws Doctrine_Record_Exception if trying to set a value for unknown property / related component - * @throws Doctrine_Record_Exception if trying to set a value of wrong type for related component - * - * @return Doctrine_Record - */ - public function set($name, $value, $load = true) { - $lower = strtolower($name); - - if(isset($this->_data[$lower])) { - - if($value instanceof Doctrine_Record) { - $id = $value->getIncremented(); - - if($id !== null) - $value = $id; - } - - if($load) - $old = $this->get($lower, false); - else - $old = $this->_data[$lower]; - - if($old !== $value) { - - $value = $this->_table->invokeSet($this, $name, $value); - - $value = $this->_table->getAttribute(Doctrine::ATTR_LISTENER)->onSetProperty($this, $name, $value); - - if($value === null) - $value = self::$null; - - $this->_data[$lower] = $value; - $this->_modified[] = $lower; - switch($this->_state): - case Doctrine_Record::STATE_CLEAN: - $this->_state = Doctrine_Record::STATE_DIRTY; - break; - case Doctrine_Record::STATE_TCLEAN: - $this->_state = Doctrine_Record::STATE_TDIRTY; - break; - endswitch; - } - } else { - try { - $this->coreSetRelated($name, $value); - } catch(Doctrine_Table_Exception $e) { - throw new Doctrine_Record_Exception("Unknown property / related component '$name'."); - } - } - } - - public function coreSetRelated($name, $value) { - $rel = $this->_table->getRelation($name); - - // one-to-many or one-to-one relation - if($rel instanceof Doctrine_Relation_ForeignKey || - $rel instanceof Doctrine_Relation_LocalKey) { - if( ! $rel->isOneToOne()) { - // one-to-many relation found - if( ! ($value instanceof Doctrine_Collection)) - throw new Doctrine_Record_Exception("Couldn't call Doctrine::set(), second argument should be an instance of Doctrine_Collection when setting one-to-many references."); - - $value->setReference($this,$rel); - } else { - // one-to-one relation found - if( ! ($value instanceof Doctrine_Record)) - throw new Doctrine_Record_Exception("Couldn't call Doctrine::set(), second argument should be an instance of Doctrine_Record when setting one-to-one references."); - - if($rel instanceof Doctrine_Relation_LocalKey) { - $this->set($rel->getLocal(), $value, false); - } else { - $value->set($rel->getForeign(), $this, false); - } - } - - } elseif($rel instanceof Doctrine_Relation_Association) { - // join table relation found - if( ! ($value instanceof Doctrine_Collection)) - throw new Doctrine_Record_Exception("Couldn't call Doctrine::set(), second argument should be an instance of Doctrine_Collection when setting many-to-many references."); - - } - - $this->references[$name] = $value; - } - /** - * contains - * - * @param string $name - * @return boolean - */ - public function contains($name) { - $lower = strtolower($name); - - if(isset($this->_data[$lower])) - return true; - - if(isset($this->_id[$lower])) - return true; - - if(isset($this->references[$name])) - return true; - - return false; - } - /** - * @param string $name - * @return void - */ - public function __unset($name) { - if(isset($this->_data[$name])) - $this->_data[$name] = array(); - - // todo: what to do with references ? - } - /** - * applies the changes made to this object into database - * this method is smart enough to know if any changes are made - * and whether to use INSERT or UPDATE statement - * - * this method also saves the related components - * - * @param Doctrine_Connection $conn optional connection parameter - * @return void - */ - public function save(Doctrine_Connection $conn = null) { - if($this->_table->isTree() && !$this->getNode()->isValidNode()) - throw new Doctrine_Exception('You must insert the node into the tree before it can be saved'); - - if ($conn === null) { - $conn = $this->_table->getConnection(); - } - $conn->beginTransaction(); - - - $saveLater = $conn->unitOfWork->saveRelated($this); - - if ($this->isValid()) { - $conn->save($this); - } else { - $conn->transaction->addInvalid($this); - } - - foreach($saveLater as $fk) { - $table = $fk->getTable(); - $alias = $this->_table->getAlias($table->getComponentName()); - - if(isset($this->references[$alias])) { - $obj = $this->references[$alias]; - $obj->save(); - } - } - - // save the MANY-TO-MANY associations - - $conn->unitOfWork->saveAssociations($this); - //$this->saveAssociations(); - - $conn->commit(); - } - /** - * replace - * Execute a SQL REPLACE query. A REPLACE query is identical to a INSERT - * query, except that if there is already a row in the table with the same - * key field values, the REPLACE query just updates its values instead of - * inserting a new row. - * - * The REPLACE type of query does not make part of the SQL standards. Since - * practically only MySQL and SQLIte implement it natively, this type of - * query isemulated through this method for other DBMS using standard types - * of queries inside a transaction to assure the atomicity of the operation. - * - * @param Doctrine_Connection $conn optional connection parameter - * @throws Doctrine_Connection_Exception if some of the key values was null - * @throws Doctrine_Connection_Exception if there were no key fields - * @throws PDOException if something fails at PDO level - * @return integer number of rows affected - */ - public function replace(Doctrine_Connection $conn = null) { - if ($conn === null) { - $conn = $this->_table->getConnection(); - } - - return $conn->replace($this->_table->getTableName(), $this->getPrepared(), $this->id); - } - /** - * returns an array of modified fields and associated values - * @return array - */ - public function getModified() { - $a = array(); - - foreach($this->_modified as $k => $v) { - $a[$v] = $this->_data[$v]; - } - return $a; - } - /** - * getPrepared - * - * returns an array of modified fields and values with data preparation - * adds column aggregation inheritance and converts Records into primary key values - * - * @param array $array - * @return array - */ - public function getPrepared(array $array = array()) { - $a = array(); - - if(empty($array)) - $array = $this->_modified; - - foreach($array as $k => $v) { - $type = $this->_table->getTypeOf($v); - - if($this->_data[$v] === self::$null) { - $a[$v] = null; - continue; - } - - switch($type) { - case 'array': - case 'object': - $a[$v] = serialize($this->_data[$v]); - break; - case 'gzip': - $a[$v] = gzcompress($this->_data[$v],5); - break; - case 'boolean': - $a[$v] = (int) $this->_data[$v]; - break; - case 'enum': - $a[$v] = $this->_table->enumIndex($v,$this->_data[$v]); - break; - default: - if($this->_data[$v] instanceof Doctrine_Record) - $this->_data[$v] = $this->_data[$v]->getIncremented(); - - $a[$v] = $this->_data[$v]; - } - } - - foreach($this->_table->getInheritanceMap() as $k => $v) { - $old = $this->get($k, false); - - if((string) $old !== (string) $v || $old === null) { - $a[$k] = $v; - $this->_data[$k] = $v; - } - } - - return $a; - } - /** - * count - * this class implements countable interface - * - * @return integer the number of columns in this record - */ - public function count() { - return count($this->_data); - } - /** - * alias for count() - * - * @return integer the number of columns in this record - */ - public function columnCount() { - return $this->count(); - } - /** - * toArray - * returns the record as an array - * - * @return array - */ - public function toArray() { - $a = array(); - - foreach($this as $column => $value) { - $a[$column] = $value; - } - if($this->_table->getIdentifierType() == Doctrine_Identifier::AUTO_INCREMENT) { - $i = $this->_table->getIdentifier(); - $a[$i] = $this->getIncremented(); - } - return $a; - } - /** - * exists - * returns true if this record is persistent, otherwise false - * - * @return boolean - */ - public function exists() { - return ($this->_state !== Doctrine_Record::STATE_TCLEAN && - $this->_state !== Doctrine_Record::STATE_TDIRTY); - } - /** - * method for checking existence of properties and Doctrine_Record references - * @param mixed $name name of the property or reference - * @return boolean - */ - public function hasRelation($name) { - if(isset($this->_data[$name]) || isset($this->_id[$name])) - return true; - return $this->_table->hasRelation($name); - } - /** - * getIterator - * @return Doctrine_Record_Iterator a Doctrine_Record_Iterator that iterates through the data - */ - public function getIterator() { - return new Doctrine_Record_Iterator($this); - } - /** - * getOriginals - * returns an original collection of related component - * - * @return Doctrine_Collection|false - */ - public function obtainOriginals($name) { - if(isset($this->originals[$name])) - return $this->originals[$name]; - - return false; - } - /** - * deletes this data access object and all the related composites - * this operation is isolated by a transaction - * - * this event can be listened by the onPreDelete and onDelete listeners - * - * @return boolean true on success, false on failure - */ - public function delete(Doctrine_Connection $conn = null) { - if ($conn == null) { - $conn = $this->_table->getConnection(); - } - - return $conn->delete($this); - } - /** - * copy - * returns a copy of this object - * - * @return Doctrine_Record - */ - public function copy() { - $ret = $this->_table->create($this->_data); - $modified = array(); - foreach($this->_data as $key => $val) - if (!($val instanceof Doctrine_Null)) - $ret->_modified[] = $key; - return $ret; - } - /** - * assignIdentifier - * - * @param integer $id - * @return void - */ - final public function assignIdentifier($id = false) { - if($id === false) { - $this->_id = array(); - $this->cleanData(); - $this->_state = Doctrine_Record::STATE_TCLEAN; - $this->_modified = array(); - } elseif($id === true) { - $this->prepareIdentifiers(false); - $this->_state = Doctrine_Record::STATE_CLEAN; - $this->_modified = array(); - } else { - $name = $this->_table->getIdentifier(); - - $this->_id[$name] = $id; - $this->_state = Doctrine_Record::STATE_CLEAN; - $this->_modified = array(); - } - } - /** - * assignOriginals - * - * @param string $alias - * @param Doctrine_Collection $coll - * @return void - */ - public function assignOriginals($alias, Doctrine_Collection $coll) { - $this->originals[$alias] = $coll; - } - /** - * returns the primary keys of this object - * - * @return array - */ - final public function obtainIdentifier() { - return $this->_id; - } - /** - * returns the value of autoincremented primary key of this object (if any) - * - * @return integer - */ - final public function getIncremented() { - $id = current($this->_id); - if($id === false) - return null; - - return $id; - } - /** - * getLast - * this method is used internally be Doctrine_Query - * it is needed to provide compatibility between - * records and collections - * - * @return Doctrine_Record - */ - public function getLast() { - return $this; - } - /** - * hasRefence - * @param string $name - * @return boolean - */ - public function hasReference($name) { - return isset($this->references[$name]); - } - /** - * obtainReference - * - * @param string $name - * @throws Doctrine_Record_Exception if trying to get an unknown related component - */ - public function obtainReference($name) { - if(isset($this->references[$name])) - return $this->references[$name]; - - throw new Doctrine_Record_Exception("Unknown reference $name"); - } - /** - * initalizes a one-to-many / many-to-many relation - * - * @param Doctrine_Collection $coll - * @param Doctrine_Relation $connector - * @return boolean - */ - public function initReference(Doctrine_Collection $coll, Doctrine_Relation $connector) { - $alias = $connector->getAlias(); - - if(isset($this->references[$alias])) - return false; - - if( ! $connector->isOneToOne()) { - if( ! ($connector instanceof Doctrine_Relation_Association)) - $coll->setReference($this, $connector); - - $this->references[$alias] = $coll; - $this->originals[$alias] = clone $coll; - - return true; - } - return false; - } - - public function lazyInitRelated(Doctrine_Collection $coll, Doctrine_Relation $connector) { - - } - /** - * addReference - * @param Doctrine_Record $record - * @param mixed $key - * @return void - */ - public function addReference(Doctrine_Record $record, Doctrine_Relation $connector, $key = null) { - $alias = $connector->getAlias(); - - $this->references[$alias]->add($record, $key); - $this->originals[$alias]->add($record, $key); - } - /** - * getReferences - * @return array all references - */ - public function getReferences() { - return $this->references; - } - /** - * setRelated - * - * @param string $alias - * @param Doctrine_Access $coll - */ - final public function setRelated($alias, Doctrine_Access $coll) { - $this->references[$alias] = $coll; - $this->originals[$alias] = $coll; - } - /** - * loadReference - * loads a related component - * - * @throws Doctrine_Table_Exception if trying to load an unknown related component - * @param string $name - * @return void - */ - final public function loadReference($name) { - $fk = $this->_table->getRelation($name); - - if($fk->isOneToOne()) { - $this->references[$name] = $fk->fetchRelatedFor($this); - } else { - $coll = $fk->fetchRelatedFor($this); - - $this->references[$name] = $coll; - $this->originals[$name] = clone $coll; - } - } - /** - * binds One-to-One composite relation - * - * @param string $objTableName - * @param string $fkField - * @return void - */ - final public function ownsOne($componentName, $foreignKey, $localKey = null) { - $this->_table->bind($componentName, $foreignKey, Doctrine_Relation::ONE_COMPOSITE, $localKey); - } - /** - * binds One-to-Many composite relation - * - * @param string $objTableName - * @param string $fkField - * @return void - */ - final public function ownsMany($componentName,$foreignKey, $localKey = null) { - $this->_table->bind($componentName, $foreignKey, Doctrine_Relation::MANY_COMPOSITE, $localKey); - } - /** - * binds One-to-One aggregate relation - * - * @param string $objTableName - * @param string $fkField - * @return void - */ - final public function hasOne($componentName,$foreignKey, $localKey = null) { - $this->_table->bind($componentName, $foreignKey, Doctrine_Relation::ONE_AGGREGATE, $localKey); - } - /** - * binds One-to-Many aggregate relation - * - * @param string $objTableName - * @param string $fkField - * @return void - */ - final public function hasMany($componentName,$foreignKey, $localKey = null) { - $this->_table->bind($componentName, $foreignKey, Doctrine_Relation::MANY_AGGREGATE, $localKey); - } - /** - * setPrimaryKey - * @param mixed $key - */ - final public function setPrimaryKey($key) { - $this->_table->setPrimaryKey($key); - } - /** - * hasColumn - * sets a column definition - * - * @param string $name - * @param string $type - * @param integer $length - * @param mixed $options - * @return void - */ - final public function hasColumn($name, $type, $length = 2147483647, $options = "") { - $this->_table->setColumn($name, $type, $length, $options); - } - /** - * countRelated - * - * @param string $name the name of the related component - * @return integer - */ - public function countRelated($name) { - $rel = $this->_table->getRelation($name); - $componentName = $rel->getTable()->getComponentName(); - $alias = $rel->getTable()->getAlias(get_class($this)); - $query = new Doctrine_Query(); - $query->from($componentName. '(' . 'COUNT(1)' . ')')->where($componentName. '.' .$alias. '.' . $this->getTable()->getIdentifier(). ' = ?'); - $array = $query->execute(array($this->getIncremented())); - return $array[0]['COUNT(1)']; - } - /** - * merge - * merges this record with an array of values - * - * @param array $values - * @return void - */ - public function merge(array $values) { - foreach($this->_table->getColumnNames() as $value) { - try { - if(isset($values[$value])) - $this->set($value, $values[$value]); - } catch(Exception $e) { - // silence all exceptions - } - } - } - public function setAttribute($attr, $value) { - $this->_table->setAttribute($attr, $value); - } - public function setTableName($tableName) { - $this->_table->setTableName($tableName); - } - public function setInheritanceMap($map) { - $this->_table->setOption('inheritanceMap', $map); - } - public function setEnumValues($column, $values) { - $this->_table->setEnumValues($column, $values); - } - public function option($name, $value = null) { - if($value == null) - $this->_table->getOption($name); - else - $this->_table->setOption($name, $value); - } - public function hasIndex($name ) { - - } - - public function actsAsTree($treeImplName, $args = array()) { - $this->_table->setTree($treeImplName, $args); - } - - /** - * addListener - * - * @param Doctrine_Db_EventListener_Interface|Doctrine_Overloadable $listener - * @return Doctrine_Db - */ - public function addListener($listener, $name = null) { - $this->_table->addListener($listener, $name = null); - return $this; - } - /** - * getListener - * - * @return Doctrine_Db_EventListener_Interface|Doctrine_Overloadable - */ - public function getListener() { - return $this->_table->getListener(); - } - /** - * setListener - * - * @param Doctrine_Db_EventListener_Interface|Doctrine_Overloadable $listener - * @return Doctrine_Db - */ - public function setListener($listener) { - $this->_table->setListener($listener); - return $this; - } - /** - * call - * - * @param string|array $callback valid callback - * @param string $column column name - * @param mixed arg1 ... argN optional callback arguments - * @return Doctrine_Record - */ - public function call($callback, $column) { - $args = func_get_args(); - array_shift($args); - - if(isset($args[0])) { - $column = $args[0]; - $args[0] = $this->get($column); - - $newvalue = call_user_func_array($callback, $args); - - $this->_data[$column] = $newvalue; - } - return $this; - } - /** - * returns a string representation of this object - */ - public function __toString() { - return Doctrine_Lib::getRecordAsString($this); - } - /** - * getter for node assciated with this record - * - * @return mixed if tree returns Doctrine_Node otherwise returns false - */ - public function getNode() { - if(!$this->_table->isTree()) - return false; - - if(!isset($this->_node)) - $this->_node = Doctrine_Node::factory($this, $this->getTable()->getTreeImplName(), $this->getTable()->getTreeOptions()); - - return $this->_node; - } - /** - * used to delete node from tree - MUST BE USE TO DELETE RECORD IF TABLE ACTS AS TREE - * - */ - public function deleteNode() { - $this->getNode()->delete(); - } - -} - diff --git a/draft/new-core/Collection.php b/draft/new-core/Collection.php index 10445e95c..3a8713ae9 100644 --- a/draft/new-core/Collection.php +++ b/draft/new-core/Collection.php @@ -31,7 +31,7 @@ Doctrine::autoload("Doctrine_Access"); * @version $Revision: 1207 $ * @author Konsta Vesterinen */ -class Doctrine_Collection extends Doctrine_Access implements Countable, IteratorAggregate, Serializable +class Doctrine_Collection2 extends Doctrine_Access implements Countable, IteratorAggregate, Serializable { /** * @var array $data an array containing the data access objects of this collection diff --git a/draft/new-core/Hydrate.php b/draft/new-core/Hydrate.php index 7faa528fb..6e947ac69 100644 --- a/draft/new-core/Hydrate.php +++ b/draft/new-core/Hydrate.php @@ -32,7 +32,7 @@ Doctrine::autoload('Doctrine_Access'); * @version $Revision: 1255 $ * @author Konsta Vesterinen */ -abstract class Doctrine_Hydrate extends Doctrine_Access +abstract class Doctrine_Hydrate2 extends Doctrine_Access { /** * QUERY TYPE CONSTANTS diff --git a/draft/new-core/Query.php b/draft/new-core/Query.php index bfedad86f..8573cd4eb 100644 --- a/draft/new-core/Query.php +++ b/draft/new-core/Query.php @@ -20,7 +20,7 @@ */ Doctrine::autoload('Doctrine_Hydrate'); /** - * Doctrine_Query + * Doctrine_Query2 * * @package Doctrine * @license http://www.opensource.org/licenses/lgpl-license.php LGPL @@ -30,7 +30,7 @@ Doctrine::autoload('Doctrine_Hydrate'); * @version $Revision: 1296 $ * @author Konsta Vesterinen */ -class Doctrine_Query extends Doctrine_Hydrate implements Countable { +class Doctrine_Query2 extends Doctrine_Hydrate2 implements Countable { /** * @param array $subqueryAliases the table aliases needed in some LIMIT subqueries */ diff --git a/draft/new-core/Record.php b/draft/new-core/Record.php index 1fb3e9ef4..3f6af2d2f 100644 --- a/draft/new-core/Record.php +++ b/draft/new-core/Record.php @@ -31,7 +31,7 @@ Doctrine::autoload('Doctrine_Access'); * @since 1.0 * @version $Revision: 1298 $ */ -abstract class Doctrine_Record extends Doctrine_Access implements Countable, IteratorAggregate, Serializable +abstract class Doctrine_Record2 extends Doctrine_Access implements Countable, IteratorAggregate, Serializable { /** * STATE CONSTANTS