| 34 | | /** |
| 35 | | * The name of the entity class that is mapped to the database with this metadata. |
| | 37 | /* The inheritance mapping types */ |
| | 38 | const INHERITANCE_TYPE_NONE = 'none'; |
| | 39 | const INHERITANCE_TYPE_JOINED = 'joined'; |
| | 40 | const INHERITANCE_TYPE_SINGLE_TABLE = 'singleTable'; |
| | 41 | const INHERITANCE_TYPE_TABLE_PER_CLASS = 'tablePerClass'; |
| | 42 | |
| | 43 | /** |
| | 44 | * Inheritance types enumeration. |
| | 45 | * |
| | 46 | * @var array |
| | 47 | */ |
| | 48 | protected static $_inheritanceTypes = array( |
| | 49 | self::INHERITANCE_TYPE_NONE, |
| | 50 | self::INHERITANCE_TYPE_JOINED, |
| | 51 | self::INHERITANCE_TYPE_SINGLE_TABLE, |
| | 52 | self::INHERITANCE_TYPE_TABLE_PER_CLASS |
| | 53 | ); |
| | 54 | |
| | 55 | /* The Id generator types. TODO: belongs more in a DBAL class */ |
| | 56 | const GENERATOR_TYPE_AUTO = 'auto'; |
| | 57 | const GENERATOR_TYPE_SEQUENCE = 'sequence'; |
| | 58 | const GENERATOR_TYPE_TABLE = 'table'; |
| | 59 | const GENERATOR_TYPE_IDENTITY = 'identity'; |
| | 60 | const GENERATOR_TYPE_NONE = 'none'; |
| | 61 | |
| | 62 | /** |
| | 63 | * Id Generator types enumeration. |
| | 64 | * |
| | 65 | * @var array |
| | 66 | */ |
| | 67 | protected static $_generatorTypes = array( |
| | 68 | self::GENERATOR_TYPE_AUTO, |
| | 69 | self::GENERATOR_TYPE_SEQUENCE, |
| | 70 | self::GENERATOR_TYPE_TABLE, |
| | 71 | self::GENERATOR_TYPE_IDENTITY, |
| | 72 | self::GENERATOR_TYPE_NONE |
| | 73 | ); |
| | 74 | |
| | 75 | /** |
| | 76 | * The name of the entity class. |
| 120 | | * The mapping definition array has at least the following values: |
| 121 | | * |
| 122 | | * -- type the column type, eg. 'integer' |
| 123 | | * -- length the column length, eg. 11 |
| 124 | | * |
| 125 | | * additional keys: |
| 126 | | * -- notnull whether or not the column is marked as notnull |
| 127 | | * -- values enum values |
| 128 | | * ... many more |
| | 155 | * The mapping definition array has the following values: |
| | 156 | * |
| | 157 | * - <b>fieldName</b> (string) |
| | 158 | * The name of the field in the Entity. |
| | 159 | * |
| | 160 | * - <b>type</b> (string) |
| | 161 | * The database type of the column. Can be one of Doctrine's portable types. |
| | 162 | * |
| | 163 | * - <b>columnName</b> (string, optional) |
| | 164 | * The column name. Optional. Defaults to the field name. |
| | 165 | * |
| | 166 | * - <b>length</b> (integer, optional) |
| | 167 | * The database length of the column. Optional. Defaults to Doctrine's |
| | 168 | * default values for the portable types. |
| | 169 | * |
| | 170 | * - <b>id</b> (boolean, optional) |
| | 171 | * Marks the field as the primary key of the Entity. Multiple fields of an |
| | 172 | * entity can have the id attribute, forming a composite key. |
| | 173 | * |
| | 174 | * - <b>generatorType</b> (string, optional, requires: id) |
| | 175 | * The generation type used for the field. Optional. Can only be applied on |
| | 176 | * fields that are marked with the 'id' attribute. The possible values are: |
| | 177 | * auto, identity, sequence, table. |
| | 178 | * |
| | 179 | * - <b>generator</b> (array, optional, requires: generationType=table|sequence) |
| | 180 | * The generator options for a table or sequence generator. Can only be applied |
| | 181 | * on fields that have a generationType of 'table' or 'sequence'. |
| | 182 | * |
| | 183 | * - <b>nullable</b> (boolean, optional) |
| | 184 | * Whether the column is nullable. Defaults to TRUE. |
| | 185 | * |
| | 186 | * - <b>columnDefinition</b> (string, optional) |
| | 187 | * The SQL fragment that is used when generating the DDL for the column. |
| | 188 | * |
| | 189 | * - <b>precision</b> (integer, optional) |
| | 190 | * The precision of a decimal column. Only valid if the column type is decimal. |
| | 191 | * |
| | 192 | * - <b>scale</b> (integer, optional) |
| | 193 | * The scale of a decimal column. Only valid if the column type is decimal. |
| 652 | | |
| 653 | | /** |
| 654 | | * Maps a field of the class to a database column. |
| 655 | | * |
| 656 | | * @param string $name The name of the column to map. Syntax: columnName [as propertyName]. |
| 657 | | * The property name is optional. If not used the column will be |
| 658 | | * mapped to a property with the same name. |
| 659 | | * @param string $type The type of the column. |
| 660 | | * @param integer $length The length of the column. |
| 661 | | * @param mixed $options |
| 662 | | * @param boolean $prepend Whether to prepend or append the new column to the column list. |
| 663 | | * By default the column gets appended. |
| 664 | | * |
| 665 | | * @throws Doctrine_ClassMetadata_Exception If trying use wrongly typed parameter. |
| 666 | | * @todo Rename to mapField()/addFieldMapping(). |
| 667 | | */ |
| 668 | | public function mapColumn($name, $type, $length = null, $options = array()) |
| 669 | | { |
| 670 | | // converts 0 => 'primary' to 'primary' => true etc. |
| 671 | | foreach ($options as $k => $option) { |
| 672 | | if (is_numeric($k)) { |
| 673 | | if ( ! empty($option) && $option !== false) { |
| 674 | | $options[$option] = true; |
| | 694 | |
| | 695 | /** |
| | 696 | * Adds a field mapping. |
| | 697 | * |
| | 698 | * @param array $mapping |
| | 699 | */ |
| | 700 | public function mapField(array $mapping) |
| | 701 | { |
| | 702 | $mapping = $this->_validateAndCompleteFieldMapping($mapping); |
| | 703 | if (isset($this->_fieldMappings[$mapping['fieldName']])) { |
| | 704 | throw Doctrine_MappingException::duplicateFieldMapping(); |
| | 705 | } |
| | 706 | $this->_fieldMappings[$mapping['fieldName']] = $mapping; |
| | 707 | } |
| | 708 | |
| | 709 | /** |
| | 710 | * Overrides an existant field mapping. |
| | 711 | * Used i.e. by Entity classes deriving from another Entity class that acts |
| | 712 | * as a mapped superclass to refine the basic mapping. |
| | 713 | * |
| | 714 | * @param array $newMapping |
| | 715 | * @todo Implementation. |
| | 716 | */ |
| | 717 | public function overrideFieldMapping(array $newMapping) |
| | 718 | { |
| | 719 | //... |
| | 720 | } |
| | 721 | |
| | 722 | /** |
| | 723 | * Validates & completes the field mapping. Default values are applied here. |
| | 724 | * |
| | 725 | * @param array $mapping |
| | 726 | * @return array |
| | 727 | */ |
| | 728 | private function _validateAndCompleteFieldMapping(array $mapping) |
| | 729 | { |
| | 730 | // Check mandatory fields |
| | 731 | if ( ! isset($mapping['fieldName'])) { |
| | 732 | throw Doctrine_MappingException::missingFieldName(); |
| | 733 | } |
| | 734 | if ( ! isset($mapping['type'])) { |
| | 735 | throw Doctrine_MappingException::missingType(); |
| | 736 | } |
| | 737 | |
| | 738 | // Complete fieldName and columnName mapping |
| | 739 | if ( ! isset($mapping['columnName'])) { |
| | 740 | $mapping['columnName'] = $mapping['fieldName']; |
| | 741 | } |
| | 742 | $lcColumnName = strtolower($mapping['columnName']); |
| | 743 | |
| | 744 | $this->_columnNames[$mapping['fieldName']] = $mapping['columnName']; |
| | 745 | $this->_fieldNames[$mapping['columnName']] = $mapping['fieldName']; |
| | 746 | $this->_lcColumnToFieldNames[$lcColumnName] = $mapping['fieldName']; |
| | 747 | |
| | 748 | // Complete length mapping |
| | 749 | if ( ! isset($mapping['length'])) { |
| | 750 | $mapping['length'] = $this->_getDefaultLength($mapping['type']); |
| | 751 | } |
| | 752 | |
| | 753 | // Complete id mapping |
| | 754 | if (isset($mapping['id']) && $mapping['id'] === true) { |
| | 755 | if ( ! in_array($mapping['fieldName'], $this->_identifier)) { |
| | 756 | $this->_identifier[] = $mapping['fieldName']; |
| | 757 | } |
| | 758 | if (isset($mapping['generatorType'])) { |
| | 759 | if ( ! in_array($mapping['generatorType'], self::$_generatorTypes)) { |
| | 760 | throw Doctrine_MappingException::invalidGeneratorType($mapping['generatorType']); |
| | 761 | } else if (count($this->_identifier) > 1) { |
| | 762 | throw Doctrine_MappingException::generatorNotAllowedWithCompositeId(); |
| 678 | | } |
| 679 | | |
| 680 | | // extract column name & field name & lowercased column name |
| 681 | | $parts = explode(' as ', $name); |
| 682 | | if (count($parts) > 1) { |
| 683 | | $fieldName = $parts[1]; |
| 684 | | } else { |
| 685 | | $fieldName = $parts[0]; |
| 686 | | } |
| 687 | | $columnName = $parts[0]; |
| 688 | | $lcColumnName = strtolower($parts[0]); |
| 689 | | |
| 690 | | if (isset($this->_fieldMappings[$fieldName])) { |
| 691 | | return; |
| 692 | | } |
| 693 | | |
| 694 | | // Fill column name <-> field name lookup maps |
| 695 | | $this->_columnNames[$fieldName] = $columnName; |
| 696 | | $this->_fieldNames[$columnName] = $fieldName; |
| 697 | | $this->_lcColumnToFieldNames[$lcColumnName] = $fieldName; |
| 698 | | $this->_lcColumnToFieldNames[$lcColumnName] = $fieldName; |
| | 766 | // TODO: validate/complete 'generator' mapping |
| | 767 | |
| | 768 | // Check for composite key |
| | 769 | if ( ! $this->_isIdentifierComposite && count($this->_identifier) > 1) { |
| | 770 | $this->_isIdentifierComposite = true; |
| | 771 | } |
| | 772 | |
| | 773 | } |
| 700 | | |
| 701 | | // Inspect & fill $options |
| 702 | | |
| 703 | | if ($length == null) { |
| 704 | | $length = $this->_getDefaultLength($type); |
| 705 | | } |
| 706 | | |
| 707 | | $options['type'] = $type; |
| 708 | | $options['length'] = $length; |
| 709 | | |
| 710 | | if ( ! $this->_hasDefaultValues && isset($options['default'])) { |
| 711 | | $this->_hasDefaultValues = true; |
| 712 | | } |
| 713 | | if ( ! empty($options['primary'])) { |
| 714 | | if ( ! in_array($fieldName, $this->_identifier)) { |
| 715 | | $this->_identifier[] = $fieldName; |
| 716 | | } |
| 717 | | /*if (isset($options['autoincrement']) && $options['autoincrement'] === true) { |
| 718 | | |
| 719 | | }*/ |
| 720 | | } |
| 721 | | /* |
| 722 | | if ( ! isset($options['immutable'])) { |
| 723 | | $options['immutable'] = false; |
| 724 | | }*/ |
| 725 | | |
| 726 | | $this->_fieldMappings[$fieldName] = $options; |
| 727 | | |
| 728 | | $this->_columnCount++; |
| 729 | | } |
| 730 | | |
| 731 | | /** |
| 732 | | * Gets the default length for a field type. |
| 733 | | * |
| 734 | | * @param unknown_type $type |
| 735 | | * @return unknown |
| | 775 | return $mapping; |
| | 776 | } |
| | 777 | |
| | 778 | /** |
| | 779 | * Gets the default length for a column type. |
| | 780 | * |
| | 781 | * @param string $type |
| | 782 | * @return mixed |
| 784 | | } |
| 785 | | |
| 786 | | /** |
| 787 | | * Checks whether the mapped class has a default value on any field. |
| 788 | | * |
| 789 | | * @return boolean TRUE if the entity has a default value on any field, otherwise false. |
| 790 | | */ |
| 791 | | /*public function hasDefaultValues() |
| 792 | | { |
| 793 | | return $this->_hasDefaultValues; |
| 794 | | }*/ |
| 795 | | |
| 796 | | /** |
| 797 | | * getDefaultValueOf |
| 798 | | * returns the default value(if any) for given field |
| 799 | | * |
| 800 | | * @param string $fieldName |
| 801 | | * @return mixed |
| 802 | | */ |
| 803 | | /*public function getDefaultValueOf($fieldName) |
| 804 | | { |
| 805 | | if ( ! isset($this->_fieldMappings[$fieldName])) { |
| 806 | | throw new Doctrine_Table_Exception("Couldn't get default value. Column ".$fieldName." doesn't exist."); |
| 807 | | } |
| 808 | | if (isset($this->_fieldMappings[$fieldName]['default'])) { |
| 809 | | return $this->_fieldMappings[$fieldName]['default']; |
| 810 | | } else { |
| 811 | | return null; |
| 812 | | } |
| 842 | | * Gets the type of the identifier (primary key) used by the mapped class. The type |
| 843 | | * can be either |
| 844 | | * <tt>Doctrine::IDENTIFIER_NATURAL</tt>, |
| 845 | | * <tt>Doctrine::IDENTIFIER_AUTOINCREMENT</tt>, |
| 846 | | * <tt>Doctrine::IDENTIFIER_SEQUENCE</tt> or |
| 847 | | * <tt>Doctrine::IDENTIFIER_COMPOSITE</tt>. |
| 848 | | * |
| 849 | | * @return integer |
| 850 | | */ |
| 851 | | public function getIdentifierType() |
| 852 | | { |
| 853 | | return $this->_identifierType; |
| 854 | | } |
| 855 | | |
| 856 | | /** |
| 857 | | * Sets the identifier type used by the mapped class. |
| 858 | | */ |
| 859 | | public function setIdentifierType($type) |
| 860 | | { |
| 861 | | $this->_identifierType = $type; |
| 862 | | } |
| 863 | | |
| 864 | | public function hasMappedColumn($columnName) |
| 865 | | { |
| 866 | | return isset($this->_fieldNames[$columnName]); |
| 867 | | } |
| 868 | | |
| 869 | | /** |
| 870 | | * hasField |
| | 875 | * Checks whether the class has a (mapped) field with a certain name. |
| | 876 | * |