From 0fdb2290205f6c14fe02e2ee239bc307f8958222 Mon Sep 17 00:00:00 2001 From: lsmith Date: Sun, 2 Sep 2007 08:53:16 +0000 Subject: [PATCH] - added support for Doctrine::ATTR_USE_NATIVE_ENUM (defaults to off, no BC break) --- lib/Doctrine.php | 15 ++-- lib/Doctrine/Configurable.php | 15 ++-- lib/Doctrine/DataDict/Mysql.php | 14 +++- lib/Doctrine/Table.php | 128 +++++++++++++++++--------------- 4 files changed, 96 insertions(+), 76 deletions(-) diff --git a/lib/Doctrine.php b/lib/Doctrine.php index 64fa08cc1..4f51a5c11 100644 --- a/lib/Doctrine.php +++ b/lib/Doctrine.php @@ -73,7 +73,7 @@ final class Doctrine const ERR_LOADMODULE = -34; const ERR_INSUFFICIENT_DATA = -35; const ERR_CLASS_NAME = -36; - + /** * PDO derived constants */ @@ -119,13 +119,13 @@ final class Doctrine /** * ATTRIBUTE CONSTANTS */ - + /** * PDO derived attributes */ const ATTR_AUTOCOMMIT = 0; const ATTR_PREFETCH = 1; - const ATTR_TIMEOUT = 2; + const ATTR_TIMEOUT = 2; const ATTR_ERRMODE = 3; const ATTR_SERVER_VERSION = 4; const ATTR_CLIENT_VERSION = 5; @@ -156,7 +156,7 @@ final class Doctrine const ATTR_DBNAME_FORMAT = 117; const ATTR_TBLCLASS_FORMAT = 119; const ATTR_EXPORT = 140; - const ATTR_DECIMAL_PLACES = 141; + const ATTR_DECIMAL_PLACES = 141; const ATTR_PORTABILITY = 106; const ATTR_VLD = 107; @@ -169,6 +169,7 @@ final class Doctrine const ATTR_DEF_VARCHAR_LENGTH = 114; const ATTR_DEF_TABLESPACE = 115; const ATTR_EMULATE_DATABASE = 116; + const ATTR_USE_NATIVE_ENUM = 117; const ATTR_DEFAULT_SEQUENCE = 133; /** TODO: REMOVE THE FOLLOWING CONSTANTS AND UPDATE THE DOCS ! */ @@ -322,7 +323,7 @@ final class Doctrine /** * EXPORT CONSTANTS */ - + /** * turns of exporting */ @@ -462,7 +463,7 @@ final class Doctrine * @return boolean */ public static function autoload($classname) - { + { if (class_exists($classname, false)) { return false; } @@ -540,7 +541,7 @@ final class Doctrine { if (preg_match('~(^[a-z])|(_[a-z])|([\W])|(_{2})~', $classname)) { return false; - } + } return true; } diff --git a/lib/Doctrine/Configurable.php b/lib/Doctrine/Configurable.php index 5b0835eb8..9c2f14001 100644 --- a/lib/Doctrine/Configurable.php +++ b/lib/Doctrine/Configurable.php @@ -43,7 +43,7 @@ abstract class Doctrine_Configurable extends Doctrine_Object protected $parent; /** * @var array $_impl an array containing concrete implementations for class templates - * keys as template names and values as names of the concrete + * keys as template names and values as names of the concrete * implementation classes */ protected $_impl = array(); @@ -70,7 +70,7 @@ abstract class Doctrine_Configurable extends Doctrine_Object { if (is_string($attribute)) { $upper = strtoupper($attribute); - + $const = 'Doctrine::ATTR_' . $attribute; if (defined($const)) { $this->_state = constant($const); @@ -93,7 +93,7 @@ abstract class Doctrine_Configurable extends Doctrine_Object throw new Doctrine_Exception("ATTR_CREATE_TABLES has been deprecated. See exporting in the first chapter of the manual."); break; case Doctrine::ATTR_ACCESSORS: - throw new Doctrine_Exception("Get / Set filtering is deprecated (slowed down Doctrine too much)."); + throw new Doctrine_Exception("Get / Set filtering is deprecated (slowed down Doctrine too much)."); break; case Doctrine::ATTR_COLL_LIMIT: if ($value < 1) { @@ -125,6 +125,7 @@ abstract class Doctrine_Configurable extends Doctrine_Object case Doctrine::ATTR_ACCESSOR_PREFIX_GET: case Doctrine::ATTR_ACCESSOR_PREFIX_SET: case Doctrine::ATTR_EMULATE_DATABASE: + case Doctrine::ATTR_USE_NATIVE_ENUM: case Doctrine::ATTR_DEFAULT_SEQUENCE: case Doctrine::ATTR_EXPORT: case Doctrine::ATTR_DECIMAL_PLACES: @@ -169,7 +170,7 @@ abstract class Doctrine_Configurable extends Doctrine_Object public function setImpl($template, $class) { $this->_impl[$template] = $class; - + return $this; } /** @@ -198,7 +199,7 @@ abstract class Doctrine_Configurable extends Doctrine_Object if ( ! isset($this->attributes[Doctrine::ATTR_CACHE])) { throw new Doctrine_Exception('Cache driver not initialized.'); } - + return $this->attributes[Doctrine::ATTR_CACHE]; } /** @@ -219,7 +220,7 @@ abstract class Doctrine_Configurable extends Doctrine_Object { if ( ! isset($this->attributes[Doctrine::ATTR_RECORD_LISTENER]) || ! ($this->attributes[Doctrine::ATTR_RECORD_LISTENER] instanceof Doctrine_Record_Listener_Chain)) { - + $this->attributes[Doctrine::ATTR_RECORD_LISTENER] = new Doctrine_Record_Listener_Chain(); } $this->attributes[Doctrine::ATTR_RECORD_LISTENER]->add($listener, $name); @@ -268,7 +269,7 @@ abstract class Doctrine_Configurable extends Doctrine_Object { if ( ! isset($this->attributes[Doctrine::ATTR_LISTENER]) || ! ($this->attributes[Doctrine::ATTR_LISTENER] instanceof Doctrine_EventListener_Chain)) { - + $this->attributes[Doctrine::ATTR_LISTENER] = new Doctrine_EventListener_Chain(); } $this->attributes[Doctrine::ATTR_LISTENER]->add($listener, $name); diff --git a/lib/Doctrine/DataDict/Mysql.php b/lib/Doctrine/DataDict/Mysql.php index c58916cbe..7ca6f6f23 100644 --- a/lib/Doctrine/DataDict/Mysql.php +++ b/lib/Doctrine/DataDict/Mysql.php @@ -134,9 +134,9 @@ class Doctrine_DataDict_Mysql extends Doctrine_DataDict */ public function getNativeDeclaration($field) { - if ( ! isset($field['type'])) { + if ( ! isset($field['type'])) { throw new Doctrine_DataDict_Exception('Missing column type.'); - } + } switch ($field['type']) { case 'char': @@ -185,9 +185,17 @@ class Doctrine_DataDict_Mysql extends Doctrine_DataDict } } return 'LONGBLOB'; + case 'enum': + if ($this->conn->getAttribute(Doctrine::ATTR_USE_NATIVE_ENUM)) { + $values = array(); + foreach ($field['values'] as $value) { + $values[] = $this->conn->quote($value, 'varchar'); + } + return 'ENUM('.implode(', ', $values).')'; + } + // fall back to integer case 'integer': case 'int': - case 'enum': if (!empty($field['length'])) { $length = $field['length']; if ($length <= 1) { diff --git a/lib/Doctrine/Table.php b/lib/Doctrine/Table.php index 03039c1ab..4349de2ae 100644 --- a/lib/Doctrine/Table.php +++ b/lib/Doctrine/Table.php @@ -100,7 +100,7 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable * -- parents the parent classes of this component * * -- declaringClass name of the table definition declaring class (when using inheritance the class - * that defines the table structure can be any class in the inheritance hierarchy, + * that defines the table structure can be any class in the inheritance hierarchy, * hence we need reflection to check out which class actually calls setTableDefinition) * * -- tableName database table name, in most cases this is the same as component name but in some cases @@ -189,7 +189,7 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable do { if ($class === 'Doctrine_Record') { - break; + break; } $name = $class; @@ -217,7 +217,7 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable if ($this->isTree()) { $this->getTree()->setTableDefinition(); } - + $this->columnCount = count($this->columns); if ( ! isset($this->options['tableName'])) { @@ -231,7 +231,7 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable 'length' => 20, 'autoincrement' => true, 'primary' => true)), $this->columns); - + $this->primaryKeys[] = 'id'; $this->identifier = 'id'; $this->identifierType = Doctrine::IDENTIFIER_AUTOINC; @@ -241,19 +241,19 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable if (count($this->primaryKeys) > 1) { $this->identifier = $this->primaryKeys; $this->identifierType = Doctrine::IDENTIFIER_COMPOSITE; - + } else { foreach ($this->primaryKeys as $pk) { $e = $this->columns[$pk]; - + $found = false; - + foreach ($e as $option => $value) { if ($found) break; - + $e2 = explode(':', $option); - + switch (strtolower($e2[0])) { case 'autoincrement': case 'autoinc': @@ -264,7 +264,7 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable case 'sequence': $this->identifierType = Doctrine::IDENTIFIER_SEQUENCE; $found = true; - + if ($value) { $this->options['sequenceName'] = $value; } else { @@ -313,7 +313,7 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable * @return boolean whether or not the export operation was successful * false if table already existed in the database */ - public function export() + public function export() { $this->conn->export->exportTable($this); } @@ -353,7 +353,7 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable if ($parseForeignKeys) { if ($this->getAttribute(Doctrine::ATTR_EXPORT) & Doctrine::EXPORT_CONSTRAINTS) { - + $constraints = array(); $emptyIntegrity = array('onUpdate' => null, @@ -367,13 +367,13 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable if ($relation->hasConstraint()) { throw new Doctrine_Table_Exception("Badly constructed integrity constraints."); } - + continue; } $integrity = array('onUpdate' => $fk['onUpdate'], 'onDelete' => $fk['onDelete']); - + if ($relation instanceof Doctrine_Relation_LocalKey) { $def = array('local' => $relation->getLocal(), 'foreign' => $relation->getForeign(), @@ -398,9 +398,9 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable } } $options['primary'] = $primary; - - return array('tableName' => $this->getOption('tableName'), - 'columns' => $columns, + + return array('tableName' => $this->getOption('tableName'), + 'columns' => $columns, 'options' => array_merge($this->getOptions(), $options)); } /** @@ -453,7 +453,7 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable * * @param string $option */ - public function __isset($option) + public function __isset($option) { return isset($this->options[$option]); } @@ -480,7 +480,7 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable } /** * addCheckConstraint - * + * * adds a check constraint to this table * * @return void @@ -492,12 +492,12 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable } else { $this->options['checks'][] = $definition; } - + return $this; } /** * addIndex - * + * * adds an index to this table * * @return void @@ -511,7 +511,7 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable * * @return array|boolean array on success, FALSE on failure */ - public function getIndex($index) + public function getIndex($index) { if (isset($this->options['indexes'][$index])) { return $this->options['indexes'][$index]; @@ -523,11 +523,11 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable { $options = array(); $options['type'] = $type; - + if ( ! isset($args[1])) { $args[1] = array(); } - + // the following is needed for backwards compatibility if (is_string($args[1])) { if ( ! isset($args[2])) { @@ -542,7 +542,7 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable $e = explode('.', $args[1]); if (in_array($e[0], $classes)) { if ($options['type'] >= Doctrine_Relation::MANY) { - $options['foreign'] = $e[1]; + $options['foreign'] = $e[1]; } else { $options['local'] = $e[1]; } @@ -558,13 +558,13 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable $options = array_merge($args[2], $options); $this->_parser->bind($args[0], $options); - } else { + } else { $options = array_merge($args[1], $options); $this->_parser->bind($args[0], $options); } } - /** + /** * hasRelation * * @param string $alias the relation to check if exists @@ -573,7 +573,7 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable public function hasRelation($alias) { return $this->_parser->hasRelation($alias); - } + } /** * getRelation @@ -616,7 +616,7 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable } /** * setOption - * sets an option and returns this object in order to + * sets an option and returns this object in order to * allow flexible method chaining * * @see Doctrine_Table::$_options for available options @@ -959,13 +959,13 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable public function addRecord(Doctrine_Record $record) { $id = implode(' ', $record->identifier()); - + if (isset($this->identityMap[$id])) { return false; } - + $this->identityMap[$id] = $record; - + return true; } /** @@ -979,13 +979,13 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable { if ( ! empty($this->data)) { $this->data = array_change_key_case($this->data, CASE_LOWER); - + $key = $this->getIdentifier(); - + if ( ! is_array($key)) { $key = array($key); } - + $found = false; foreach ($key as $k) { if ( ! isset($this->data[$k])) { @@ -995,7 +995,7 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable } $id[] = $this->data[$k]; } - + if ($found) { $recordName = $this->getClassnameToReturn(); $record = new $recordName($this, true); @@ -1006,7 +1006,7 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable $id = implode(' ', $id); - + if (isset($this->identityMap[$id])) { $record = $this->identityMap[$id]; $record->hydrate($this->data); @@ -1028,17 +1028,17 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable /** * Get the classname to return. Most often this is just the options['name'] * - * Check the subclasses option and the inheritanceMap for each subclass to see - * if all the maps in a subclass is met. If this is the case return that - * subclass name. If no subclasses match or if there are no subclasses defined + * Check the subclasses option and the inheritanceMap for each subclass to see + * if all the maps in a subclass is met. If this is the case return that + * subclass name. If no subclasses match or if there are no subclasses defined * return the name of the class for this tables record. * - * @todo this function could use reflection to check the first time it runs - * if the subclassing option is not set. + * @todo this function could use reflection to check the first time it runs + * if the subclassing option is not set. * * @return string The name of the class to create * - */ + */ public function getClassnameToReturn() { if (!isset($this->options['subclasses'])) { @@ -1068,8 +1068,8 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable final public function getProxy($id = null) { if ($id !== null) { - $query = 'SELECT ' . implode(', ',$this->primaryKeys) - . ' FROM ' . $this->getTableName() + $query = 'SELECT ' . implode(', ',$this->primaryKeys) + . ' FROM ' . $this->getTableName() . ' WHERE ' . implode(' = ? && ',$this->primaryKeys) . ' = ?'; $query = $this->applyInheritance($query); @@ -1122,10 +1122,17 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable */ public function enumValue($field, $index) { - if ($index instanceof Doctrine_Null) + if ($index instanceof Doctrine_Null) { return $index; + } - return isset($this->columns[$field]['values'][$index]) ? $this->columns[$field]['values'][$index] : $index; + if (!$this->conn->getAttribute(Doctrine::ATTR_USE_NATIVE_ENUM) + && isset($this->columns[$field]['values'][$index]) + ) { + return $this->columns[$field]['values'][$index]; + } + + return $index; } /** * enumIndex @@ -1138,10 +1145,13 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable { $values = $this->getEnumValues($field); - return array_search($value, $values); + $index = array_search($value, $values); + if ($index === false || !$this->conn->getAttribute(Doctrine::ATTR_USE_NATIVE_ENUM)) { + return $index; + } + return ($index+1); } - /** - * getColumnCount + /* getColumnCount * * @return integer the number of columns in this table */ @@ -1216,7 +1226,7 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable } /** * prepareValue - * this method performs special data preparation depending on + * this method performs special data preparation depending on * the type of the given column * * 1. It unserializes array and object typed columns @@ -1283,13 +1293,13 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable * getter for associated tree * * @return mixed if tree return instance of Doctrine_Tree, otherwise returns false - */ + */ public function getTree() { if (isset($this->options['treeImpl'])) { if ( ! $this->tree) { $options = isset($this->options['treeOptions']) ? $this->options['treeOptions'] : array(); - $this->tree = Doctrine_Tree::factory($this, - $this->options['treeImpl'], + $this->tree = Doctrine_Tree::factory($this, + $this->options['treeImpl'], $options ); } @@ -1297,7 +1307,7 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable } return false; } - public function getComponentName() + public function getComponentName() { return $this->options['name']; } @@ -1307,13 +1317,13 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable } public function setTableName($tableName) { - $this->options['tableName'] = $tableName; + $this->options['tableName'] = $tableName; } /** * determine if table acts as tree * * @return mixed if tree return true, otherwise returns false - */ + */ public function isTree() { return ( ! is_null($this->options['treeImpl'])) ? true : false; } @@ -1323,10 +1333,10 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable if ( ! isset($this->_templates[$template])) { throw new Doctrine_Table_Exception('Template ' . $template . ' not loaded'); } - + return $this->_templates[$template]; } - + public function addTemplate($template, Doctrine_Template $impl) { $this->_templates[$template] = $impl;