Completed
Pull Request — master (#5)
by James Ekow Abaka
03:53
created

AbstractDatabaseManipulator::getVersion()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 2
nc 2
nop 0
dl 0
loc 4
ccs 0
cts 3
cp 0
crap 6
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace yentu\manipulators;
4
5
use clearice\io\Io;
6
use ntentan\atiaa\DriverFactory;
7
use yentu\Yentu;
8
use yentu\DatabaseAssertor;
9
use yentu\SchemaDescription;
10
use yentu\exceptions\DatabaseManipulatorException;
11
use yentu\Parameters;
12
13
abstract class AbstractDatabaseManipulator
14
{
15
16
    const CONVERT_TO_DRIVER = 'driver';
17
    const CONVERT_TO_YENTU = 'yentu';
18
19
    private $schemaDescription;
20
    private $assertor;
21
    private $connection;
22
    private $dumpQuery;
23
    private $disableQuery;
24
    protected $defaultSchema;
25
    private $io;
26
27 33
    public function __construct(Yentu $yentu, DriverFactory $driverFactory, Io $io)
28
    {
29 33
        $this->connection = $driverFactory->createDriver();
30 33
        $this->connection->connect();
31 33
        $this->io = $io;
32 33
    }
33
34 33
    public function __get($name)
35
    {
36 33
        if ($name === 'description') {
37 33
            return $this->getDescription();
38
        }
39
    }
40
41 10
    public function setDumpQuery($dumpQuery)
42
    {
43 10
        $this->dumpQuery = $dumpQuery;
44 10
    }
45
46 10
    public function setDisableQuery($disableQuery)
47
    {
48 10
        $this->disableQuery = $disableQuery;
49 10
    }
50
51 30
    public function __call($name, $arguments)
52
    {
53 30
        if (preg_match("/^(add|drop|change|executeQuery|reverseQuery)/", $name)) {
54 30
            $details = Parameters::wrap($arguments[0]);
55 30
            $this->description->$name($details);
0 ignored issues
show
Bug Best Practice introduced by
The property description does not exist on yentu\manipulators\AbstractDatabaseManipulator. Since you implemented __get, consider adding a @property annotation.
Loading history...
56 30
            $name = "_$name";
57 30
            new \ReflectionMethod($this, $name);
58 30
            return $this->$name($details);
59
        } else {
60
            throw new \Exception("Failed to execute method '$name'");
61
        }
62
    }
63
64 30
    public function query($query, $bind = false)
65
    {
66
        try {
67 30
            if ($this->dumpQuery) {
68
                echo "$query\n";
69
            }
70
71 30
            $this->io->output("\n    > Running Query [$query]", Io::OUTPUT_LEVEL_3);
72
73 30
            if ($this->disableQuery !== true) {
74 30
                return $this->connection->query($query, $bind);
75
            }
76 1
        } catch (\ntentan\atiaa\exceptions\DatabaseDriverException $e) {
77 1
            throw new DatabaseManipulatorException($e->getMessage());
78
        }
79 10
    }
80
81 27
    public function disconnect()
82
    {
83 27
        $this->connection->disconnect();
84 27
    }
85
86 1
    public function getDefaultSchema()
87
    {
88 1
        return $this->connection->getDefaultSchema();
89
    }
90
91 30
    public function getAssertor()
92
    {
93 30
        if (!is_object($this->assertor)) {
94 30
            $this->assertor = new DatabaseAssertor($this->description);
0 ignored issues
show
Bug Best Practice introduced by
The property description does not exist on yentu\manipulators\AbstractDatabaseManipulator. Since you implemented __get, consider adding a @property annotation.
Loading history...
95
        }
96 30
        return $this->assertor;
97
    }
98
99
    abstract protected function _addSchema($name);
100
101
    abstract protected function _dropSchema($name);
102
103
    abstract protected function _addTable($details);
104
105
    abstract protected function _dropTable($details);
106
107
    abstract protected function _changeTableName($details);
108
109
    abstract protected function _addColumn($details);
110
111
    abstract protected function _changeColumnNulls($details);
112
113
    abstract protected function _changeColumnName($details);
114
115
    abstract protected function _changeColumnDefault($details);
116
117
    abstract protected function _dropColumn($details);
118
119
    abstract protected function _addPrimaryKey($details);
120
121
    abstract protected function _dropPrimaryKey($details);
122
123
    abstract protected function _addUniqueKey($details);
124
125
    abstract protected function _dropUniqueKey($details);
126
127
    abstract protected function _addAutoPrimaryKey($details);
128
129
    abstract protected function _dropAutoPrimaryKey($details);
130
131
    abstract protected function _addForeignKey($details);
132
133
    abstract protected function _dropForeignKey($details);
134
135
    abstract protected function _addIndex($details);
136
137
    abstract protected function _dropIndex($details);
138
139
    abstract protected function _addView($details);
140
141
    abstract protected function _dropView($details);
142
143
    abstract protected function _changeViewDefinition($details);
144
145
    protected function _changeForeignKeyOnDelete($details)
146
    {
147
        $this->_dropForeignKey($details['from']);
148
        $this->_addForeignKey($details['to']);
149
    }
150
151
    protected function _changeForeignKeyOnUpdate($details)
152
    {
153
        $this->_dropForeignKey($details['from']);
154
        $this->_addForeignKey($details['to']);
155
    }
156
157
    protected function _executeQuery($details)
158
    {
159
        $this->query($details['query'], $details['bind'] ?? []);
160
    }
161
162
    protected function _reverseQuery($details)
163
    {
164
        
165
    }
166
167
    abstract public function convertTypes($type, $direction, $length);
168
169
    /**
170
     * 
171
     * @return SchemaDescription
172
     */
173 33
    public function getDescription()
174
    {
175 33
        if (!is_object($this->schemaDescription)) {
176 33
            $this->schemaDescription = SchemaDescription::wrap($this->connection->describe(), $this);
177
        }
178 33
        return $this->schemaDescription;
179
    }
180
181 8
    public function setVersion($version)
182
    {
183 8
        $this->query('INSERT INTO yentu_history(version) values (?)', array($version));
184 8
    }
185
186
    public function getVersion()
187
    {
188
        $version = $this->query("SELECT MAX(version) as version FROM yentu_history");
189
        return isset($version[0]) ? $version[0]['version'] : null;
190
    }
191
192 6
    public function getLastSession()
193
    {
194 6
        $session = $this->query("SELECT session FROM yentu_history ORDER BY id DESC LIMIT 1");
195 6
        return isset($session[0]['session']) ? $session[0]['session'] : null;
196
    }
197
198 3
    public function getSessionVersions($session)
199
    {
200 3
        $sessionVersions = array();
201 3
        $versions = $this->query(
202 3
            "SELECT DISTINCT version FROM yentu_history WHERE session = ?", array($session)
203
        );
204
205 3
        foreach ($versions as $version) {
206 3
            $sessionVersions[] = $version['version'];
207
        }
208
209 3
        return $sessionVersions;
210
    }
211
212 27
    public function createHistory()
213
    {
214
        try {
215 27
            $this->connection->describeTable('yentu_history');
216 27
        } catch (\ntentan\atiaa\exceptions\TableNotFoundException $e) {
217 27
            $this->io->pushOutputLevel(Io::OUTPUT_LEVEL_0);
218 27
            $this->addTable(array('schema' => '', 'name' => 'yentu_history'));
0 ignored issues
show
Bug introduced by
The method addTable() does not exist on yentu\manipulators\AbstractDatabaseManipulator. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

218
            $this->/** @scrutinizer ignore-call */ 
219
                   addTable(array('schema' => '', 'name' => 'yentu_history'));
Loading history...
219
220 27
            $this->addColumn(array('default' => null, 'schema' => '', 'nulls' => true, 'length' => null, 'table' => 'yentu_history', 'name' => 'session', 'type' => 'string'));
0 ignored issues
show
Bug introduced by
The method addColumn() does not exist on yentu\manipulators\AbstractDatabaseManipulator. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

220
            $this->/** @scrutinizer ignore-call */ 
221
                   addColumn(array('default' => null, 'schema' => '', 'nulls' => true, 'length' => null, 'table' => 'yentu_history', 'name' => 'session', 'type' => 'string'));
Loading history...
221 27
            $this->addColumn(array('default' => null, 'schema' => '', 'nulls' => false, 'length' => null, 'table' => 'yentu_history', 'name' => 'version', 'type' => 'string'));
222 27
            $this->addColumn(array('default' => null, 'schema' => '', 'nulls' => true, 'length' => null, 'table' => 'yentu_history', 'name' => 'method', 'type' => 'string'));
223 27
            $this->addColumn(array('default' => null, 'schema' => '', 'nulls' => true, 'length' => null, 'table' => 'yentu_history', 'name' => 'arguments', 'type' => 'text'));
224 27
            $this->addColumn(array('default' => null, 'schema' => '', 'nulls' => true, 'length' => null, 'table' => 'yentu_history', 'name' => 'migration', 'type' => 'string'));
225 27
            $this->addColumn(array('default' => null, 'schema' => '', 'nulls' => true, 'length' => null, 'table' => 'yentu_history', 'name' => 'default_schema', 'type' => 'string'));
226 27
            $this->addColumn(array('default' => null, 'schema' => '', 'nulls' => true, 'length' => null, 'table' => 'yentu_history', 'name' => 'id', 'type' => 'integer'));
227 27
            $this->addPrimaryKey(array('schema' => '', 'table' => 'yentu_history', 'name' => 'yentu_history_pk', 'columns' => array('id')));
0 ignored issues
show
Bug introduced by
The method addPrimaryKey() does not exist on yentu\manipulators\AbstractDatabaseManipulator. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

227
            $this->/** @scrutinizer ignore-call */ 
228
                   addPrimaryKey(array('schema' => '', 'table' => 'yentu_history', 'name' => 'yentu_history_pk', 'columns' => array('id')));
Loading history...
228 27
            $this->addAutoPrimaryKey(array('schema' => '', 'table' => 'yentu_history', 'column' => 'id'));
0 ignored issues
show
Bug introduced by
The method addAutoPrimaryKey() does not exist on yentu\manipulators\AbstractDatabaseManipulator. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

228
            $this->/** @scrutinizer ignore-call */ 
229
                   addAutoPrimaryKey(array('schema' => '', 'table' => 'yentu_history', 'column' => 'id'));
Loading history...
229 27
            $this->io->popOutputLevel();
230
        }
231 27
    }
232
233 10
    public function __clone()
234
    {
235 10
        if (is_object($this->schemaDescription)) {
236
            $this->schemaDescription = clone $this->schemaDescription;
237
        }
238 10
    }
239
240
}
241