Completed
Branch develop (c2aa4c)
by Anton
05:17
created

TableSchema::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 10
rs 9.4286
cc 2
eloc 5
nc 2
nop 4
1
<?php
2
/**
3
 * Spiral Framework.
4
 *
5
 * @license   MIT
6
 * @author    Anton Titov (Wolfy-J)
7
 */
8
namespace Spiral\Database\Drivers\MySQL\Schemas;
9
10
use Spiral\Database\Entities\Driver;
11
use Spiral\Database\Entities\Schemas\AbstractCommander;
12
use Spiral\Database\Entities\Schemas\AbstractTable;
13
use Spiral\Database\Exceptions\SchemaException;
14
15
/**
16
 * MySQL table schema.
17
 */
18
class TableSchema extends AbstractTable
19
{
20
    /**
21
     * List of most common MySQL table engines.
22
     */
23
    const ENGINE_INNODB = 'InnoDB';
24
    const ENGINE_MYISAM = 'MyISAM';
25
    const ENGINE_MEMORY = 'Memory';
26
27
    /**
28
     * MySQL table engine.
29
     *
30
     * @var string
31
     */
32
    private $engine = self::ENGINE_INNODB;
33
34
    /**
35
     * @param Driver            $driver Parent driver.
36
     * @param AbstractCommander $commander
37
     * @param string            $name   Table name, must include table prefix.
38
     * @param string            $prefix Database specific table prefix.
39
     */
40
    public function __construct(Driver $driver, AbstractCommander $commander, $name, $prefix)
41
    {
42
        parent::__construct($driver, $commander, $name, $prefix);
43
44
        //Let's load table type, just for fun
45
        if ($this->exists()) {
46
            $query = $driver->query('SHOW TABLE STATUS WHERE Name = ?', [$name]);
47
            $this->engine = $query->fetch()['Engine'];
48
        }
49
    }
50
51
    /**
52
     * Change table engine. Such operation will be applied only at moment of table creation.
53
     *
54
     * @param string $engine
55
     * @return $this
56
     */
57
    public function setEngine($engine)
58
    {
59
        if ($this->exists()) {
60
            throw new SchemaException("Table engine can be set only at moment of creation.");
61
        }
62
63
        $this->engine = $engine;
64
65
        return $this;
66
    }
67
68
    /**
69
     * @return string
70
     */
71
    public function getEngine()
72
    {
73
        return $this->engine;
74
    }
75
76
    /**
77
     * {@inheritdoc}
78
     */
79
    protected function loadColumns()
80
    {
81
        $query = "SHOW FULL COLUMNS FROM {$this->getName(true)}";
82
83
        foreach ($this->driver->query($query)->bind(0, $name) as $column) {
84
            $this->registerColumn($this->columnSchema($name, $column));
85
        }
86
87
        return $this;
88
    }
89
90
    /**
91
     * {@inheritdoc}
92
     */
93
    protected function loadIndexes()
94
    {
95
        $query = "SHOW INDEXES FROM {$this->getName(true)}";
96
97
        $indexes = [];
98
        $primaryKeys = [];
99
        foreach ($this->driver->query($query) as $index) {
100
            if ($index['Key_name'] == 'PRIMARY') {
101
                $primaryKeys[] = $index['Column_name'];
102
                continue;
103
            }
104
105
            $indexes[$index['Key_name']][] = $index;
106
        }
107
108
        $this->setPrimaryKeys($primaryKeys);
109
110
        foreach ($indexes as $name => $schema) {
111
            $this->registerIndex($this->indexSchema($name, $schema));
112
        }
113
114
        return $this;
115
    }
116
117
    /**
118
     * {@inheritdoc}
119
     */
120
    protected function loadReferences()
121
    {
122
        $query = "SELECT * FROM information_schema.referential_constraints "
123
            . "WHERE constraint_schema = ? AND table_name = ?";
124
125
        $references = $this->driver->query($query, [$this->driver->getSource(), $this->getName()]);
126
127
        foreach ($references->all() as $reference) {
128
            $query = "SELECT * FROM information_schema.key_column_usage "
129
                . "WHERE constraint_name = ? AND table_schema = ? AND table_name = ?";
130
131
            $column = $this->driver->query(
132
                $query,
133
                [$reference['CONSTRAINT_NAME'], $this->driver->getSource(), $this->getName()]
134
            )->fetch();
135
136
            $this->registerReference(
137
                $this->referenceSchema($reference['CONSTRAINT_NAME'], $reference + $column)
138
            );
139
        }
140
141
        return $this;
142
    }
143
144
    /**
145
     * {@inheritdoc}
146
     */
147
    protected function columnSchema($name, $schema = null)
148
    {
149
        return new ColumnSchema($this, $name, $schema);
150
    }
151
152
    /**
153
     * {@inheritdoc}
154
     */
155
    protected function indexSchema($name, $schema = null)
156
    {
157
        return new IndexSchema($this, $name, $schema);
158
    }
159
160
    /**
161
     * {@inheritdoc}
162
     */
163
    protected function referenceSchema($name, $schema = null)
164
    {
165
        return new ReferenceSchema($this, $name, $schema);
166
    }
167
}