Rajout de doctrine/orm
[zf2.biz/galerie.git] / vendor / doctrine / dbal / lib / Doctrine / DBAL / Schema / Index.php
1 <?php
2 /*
3  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14  *
15  * This software consists of voluntary contributions made by many individuals
16  * and is licensed under the MIT license. For more information, see
17  * <http://www.doctrine-project.org>.
18  */
19
20 namespace Doctrine\DBAL\Schema;
21
22 use Doctrine\DBAL\Schema\Visitor\Visitor;
23
24 class Index extends AbstractAsset implements Constraint
25 {
26     /**
27      * @var array
28      */
29     protected $_columns;
30
31     /**
32      * @var bool
33      */
34     protected $_isUnique = false;
35
36     /**
37      * @var bool
38      */
39     protected $_isPrimary = false;
40
41     /**
42      * Platform specific flags for indexes.
43      *
44      * @var array
45      */
46     protected $_flags = array();
47
48     /**
49      * @param string $indexName
50      * @param array $column
51      * @param bool $isUnique
52      * @param bool $isPrimary
53      */
54     public function __construct($indexName, array $columns, $isUnique = false, $isPrimary = false, array $flags = array())
55     {
56         $isUnique = ($isPrimary)?true:$isUnique;
57
58         $this->_setName($indexName);
59         $this->_isUnique = $isUnique;
60         $this->_isPrimary = $isPrimary;
61
62         foreach ($columns as $column) {
63             $this->_addColumn($column);
64         }
65         foreach ($flags as $flag) {
66             $this->addFlag($flag);
67         }
68     }
69
70     /**
71      * @param string $column
72      */
73     protected function _addColumn($column)
74     {
75         if(is_string($column)) {
76             $this->_columns[] = $column;
77         } else {
78             throw new \InvalidArgumentException("Expecting a string as Index Column");
79         }
80     }
81
82     /**
83      * @return array
84      */
85     public function getColumns()
86     {
87         return $this->_columns;
88     }
89
90     /**
91      * @return array
92      */
93     public function getUnquotedColumns()
94     {
95         return array_map(array($this, 'trimQuotes'), $this->getColumns());
96     }
97
98     /**
99      * Is the index neither unique nor primary key?
100      *
101      * @return bool
102      */
103     public function isSimpleIndex()
104     {
105         return !$this->_isPrimary && !$this->_isUnique;
106     }
107
108     /**
109      * @return bool
110      */
111     public function isUnique()
112     {
113         return $this->_isUnique;
114     }
115
116     /**
117      * @return bool
118      */
119     public function isPrimary()
120     {
121         return $this->_isPrimary;
122     }
123
124     /**
125      * @param  string $columnName
126      * @param  int $pos
127      * @return bool
128      */
129     public function hasColumnAtPosition($columnName, $pos = 0)
130     {
131         $columnName   = $this->trimQuotes(strtolower($columnName));
132         $indexColumns = array_map('strtolower', $this->getUnquotedColumns());
133         return array_search($columnName, $indexColumns) === $pos;
134     }
135
136     /**
137      * Check if this index exactly spans the given column names in the correct order.
138      *
139      * @param array $columnNames
140      * @return boolean
141      */
142     public function spansColumns(array $columnNames)
143     {
144         $sameColumns = true;
145         for ($i = 0; $i < count($this->_columns); $i++) {
146             if (!isset($columnNames[$i]) || $this->trimQuotes(strtolower($this->_columns[$i])) != $this->trimQuotes(strtolower($columnNames[$i]))) {
147                 $sameColumns = false;
148             }
149         }
150         return $sameColumns;
151     }
152
153     /**
154      * Check if the other index already fullfills all the indexing and constraint needs of the current one.
155      *
156      * @param Index $other
157      * @return bool
158      */
159     public function isFullfilledBy(Index $other)
160     {
161         // allow the other index to be equally large only. It being larger is an option
162         // but it creates a problem with scenarios of the kind PRIMARY KEY(foo,bar) UNIQUE(foo)
163         if (count($other->getColumns()) != count($this->getColumns())) {
164             return false;
165         }
166
167         // Check if columns are the same, and even in the same order
168         $sameColumns = $this->spansColumns($other->getColumns());
169
170         if ($sameColumns) {
171             if ( ! $this->isUnique() && !$this->isPrimary()) {
172                 // this is a special case: If the current key is neither primary or unique, any uniqe or
173                 // primary key will always have the same effect for the index and there cannot be any constraint
174                 // overlaps. This means a primary or unique index can always fullfill the requirements of just an
175                 // index that has no constraints.
176                 return true;
177             } else if ($other->isPrimary() != $this->isPrimary()) {
178                 return false;
179             } else if ($other->isUnique() != $this->isUnique()) {
180                 return false;
181             }
182             return true;
183         }
184         return false;
185     }
186
187     /**
188      * Detect if the other index is a non-unique, non primary index that can be overwritten by this one.
189      *
190      * @param Index $other
191      * @return bool
192      */
193     public function overrules(Index $other)
194     {
195         if ($other->isPrimary()) {
196             return false;
197         } else if ($this->isSimpleIndex() && $other->isUnique()) {
198             return false;
199         }
200
201         if ($this->spansColumns($other->getColumns()) && ($this->isPrimary() || $this->isUnique())) {
202             return true;
203         }
204         return false;
205     }
206
207     /**
208      * Add Flag for an index that translates to platform specific handling.
209      *
210      * @example $index->addFlag('CLUSTERED')
211      * @param string $flag
212      * @return Index
213      */
214     public function addFlag($flag)
215     {
216         $this->flags[strtolower($flag)] = true;
217         return $this;
218     }
219
220     /**
221      * Does this index have a specific flag?
222      *
223      * @param string $flag
224      * @return bool
225      */
226     public function hasFlag($flag)
227     {
228         return isset($this->flags[strtolower($flag)]);
229     }
230
231     /**
232      * Remove a flag
233      *
234      * @param string $flag
235      * @return void
236      */
237     public function removeFlag($flag)
238     {
239         unset($this->flags[strtolower($flag)]);
240     }
241 }
242