Completed
Branch feature/pre-split (7b42f5)
by Anton
03:44
created

AbstractIndex   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 157
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 2

Importance

Changes 0
Metric Value
dl 0
loc 157
rs 10
c 0
b 0
f 0
wmc 14
lcom 2
cbo 2

8 Methods

Rating   Name   Duplication   Size   Complexity  
A getName() 0 8 2
A isUnique() 0 4 1
A getColumns() 0 4 1
A unique() 0 6 2
A columns() 0 10 2
B sqlStatement() 0 25 3
A compare() 0 7 1
A generateName() 0 12 2
1
<?php
2
/**
3
 * Spiral Framework.
4
 *
5
 * @license   MIT
6
 * @author    Anton Titov (Wolfy-J)
7
 */
8
9
namespace Spiral\Database\Schemas;
10
11
use Spiral\Database\Schemas\Prototypes\AbstractElement;
12
use Spiral\Database\Schemas\IndexInterface;
13
14
/**
15
 * Abstract index schema with read (see IndexInterface) and write abilities. Must be implemented
16
 * by driver to support DBMS specific syntax and creation rules.
17
 */
18
abstract class AbstractIndex extends AbstractElement implements IndexInterface
19
{
20
    /**
21
     * Index types.
22
     */
23
    const NORMAL = 'INDEX';
24
    const UNIQUE = 'UNIQUE';
25
26
    /**
27
     * Index type, by default NORMAL and UNIQUE indexes supported, additional types can be
28
     * implemented on database driver level.
29
     *
30
     * @var string
31
     */
32
    protected $type = self::NORMAL;
33
34
    /**
35
     * Columns used to form index.
36
     *
37
     * @var array
38
     */
39
    protected $columns = [];
40
41
    /**
42
     * {@inheritdoc}
43
     *
44
     * @param bool $quoted Quote name.
45
     */
46
    public function getName($quoted = false)
47
    {
48
        if (empty(parent::getName())) {
49
            $this->setName($this->generateName());
50
        }
51
52
        return parent::getName($quoted);
53
    }
54
55
    /**
56
     * {@inheritdoc}
57
     */
58
    public function isUnique()
59
    {
60
        return $this->type == self::UNIQUE;
61
    }
62
63
    /**
64
     * {@inheritdoc}
65
     */
66
    public function getColumns()
67
    {
68
        return $this->columns;
69
    }
70
71
    /**
72
     * Change index type and behaviour to unique/non-unique state.
73
     *
74
     * @param bool $unique
75
     *
76
     * @return $this
77
     */
78
    public function unique($unique = true)
79
    {
80
        $this->type = $unique ? self::UNIQUE : self::NORMAL;
81
82
        return $this;
83
    }
84
85
    /**
86
     * Change set of index forming columns. Method must support both array and string parameters.
87
     *
88
     * Example:
89
     * $index->columns('key');
90
     * $index->columns('key', 'key2');
91
     * $index->columns(['key', 'key2']);
92
     *
93
     * @param string|array $columns Columns array or comma separated list of parameters.
94
     *
95
     * @return $this
96
     */
97
    public function columns($columns)
98
    {
99
        if (!is_array($columns)) {
100
            $columns = func_get_args();
101
        }
102
103
        $this->columns = $columns;
104
105
        return $this;
106
    }
107
108
    /**
109
     * Index sql creation syntax.
110
     *
111
     * @param bool $includeTable Include table ON statement (not required for inline index
112
     *                           creation).
113
     *
114
     * @return string
115
     */
116
    public function sqlStatement($includeTable = true)
117
    {
118
        $statement = [$this->type];
119
120
        if ($this->isUnique()) {
121
            //UNIQUE INDEX
122
            $statement[] = 'INDEX';
123
        }
124
125
        $statement[] = $this->getName(true);
126
127
        if ($includeTable) {
128
            $statement[] = "ON {$this->table->getName(true)}";
129
        }
130
131
        //Wrapping column names
132
        $columns = implode(', ', array_map(
133
            [$this->table->driver(), 'identifier']
134
            , $this->columns
135
        ));
136
137
        $statement[] = "({$columns})";
138
139
        return implode(' ', $statement);
140
    }
141
142
    /**
143
     * Compare two elements together.
144
     *
145
     * @param self $initial
146
     *
147
     * @return bool
148
     */
149
    public function compare(self $initial)
150
    {
151
        $normalized = clone $initial;
152
        $normalized->declared = $this->declared;
153
154
        return $this == $normalized;
155
    }
156
157
    /**
158
     * Generate unique index name.
159
     *
160
     * @return string
161
     */
162
    protected function generateName()
163
    {
164
        //We can generate name
165
        $name = $this->table->getName() . '_index_' . implode('_', $this->columns) . '_' . uniqid();
166
167
        if (strlen($name) > 64) {
168
            //Many dbs has limitations on identifier length
169
            $name = md5($name);
170
        }
171
172
        return $name;
173
    }
174
}
175