Table   A
last analyzed

Complexity

Total Complexity 20

Size/Duplication

Total Lines 197
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 83.1%

Importance

Changes 24
Bugs 0 Features 1
Metric Value
wmc 20
c 24
b 0
f 1
lcom 1
cbo 2
dl 0
loc 197
ccs 59
cts 71
cp 0.831
rs 10

8 Methods

Rating   Name   Duplication   Size   Complexity  
A getName() 0 3 1
A getCollation() 0 3 1
A checkCollationMismatchBetweenTableAndColumns() 0 17 4
A __construct() 0 6 1
A getResult() 0 17 1
A checkColumns() 0 9 2
B checkDuplicateIndices() 0 31 5
B checkRedundantIndicesOnPrimaryKey() 0 33 5
1
<?php
2
3
namespace Zortje\MySQLKeeper\Database;
4
5
use Zortje\MySQLKeeper\Database\Table\ColumnCollection;
6
use Zortje\MySQLKeeper\Database\Table\IndexCollection;
7
8
/**
9
 * Class Table
10
 *
11
 * @package Zortje\MySQLKeeper\Database
12
 */
13
class Table {
14
15
	/**
16
	 * @var string Table name
17
	 */
18
	private $name;
19
20
	/**
21
	 * @var string Table collation
22
	 */
23
	private $collation;
24
25
	/**
26
	 * @var ColumnCollection Table columns
27
	 */
28
	private $columns;
29
30
	/**
31
	 * @var IndexCollection Table indices
32
	 */
33
	private $indices;
34
35
	/**
36
	 * @param string           $name      Table name
37
	 * @param string           $collation Table collation
38
	 * @param ColumnCollection $columns   Table columns
39
	 * @param IndexCollection  $indices   Table indices
40
	 */
41
	public function __construct($name, $collation, ColumnCollection $columns, IndexCollection $indices) {
42
		$this->name      = $name;
43
		$this->collation = $collation;
44
		$this->columns   = $columns;
45
		$this->indices   = $indices;
46
	}
47
48
	/**
49
	 * Get Table name
50
	 *
51
	 * @return string Table name
52
	 */
53 1
	public function getName() {
54 1
		return $this->name;
55
	}
56
57
	/**
58
	 * Get Table collation
59
	 *
60
	 * @return string Table collation
61
	 */
62 1
	public function getCollation() {
63 1
		return $this->collation;
64
	}
65
66
	/**
67
	 * Get result for table
68
	 *
69
	 * @return array Result
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<string,array>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
70
	 */
71 2
	public function getResult() {
72 2
		$result = [];
73
74
		/**
75
		 * Get issues
76
		 */
77 2
		$issues = [];
78
79 2
		$issues = array_merge($issues, $this->checkColumns($this->columns));
80 2
		$issues = array_merge($issues, $this->checkDuplicateIndices($this->indices));
81 2
		$issues = array_merge($issues, $this->checkRedundantIndicesOnPrimaryKey($this->columns, $this->indices));
82 2
		$issues = array_merge($issues, $this->checkCollationMismatchBetweenTableAndColumns($this->columns));
83
84 2
		$result['issues'] = $issues;
85
86 2
		return $result;
87
	}
88
89
	/**
90
	 * Get result for columns
91
	 *
92
	 * @param ColumnCollection $columns Table columns
93
	 *
94
	 * @return array Result
95
	 */
96
	public function checkColumns(ColumnCollection $columns) {
97
		$result = [];
98
99
		foreach ($columns as $column) {
100
			$result = array_merge($result, $column->getResult());
101
		}
102
103
		return $result;
104
	}
105
106
	/**
107
	 * Check for duplicate indices
108
	 *
109
	 * @param IndexCollection $indices Table indices
110
	 *
111
	 * @return array Result
112
	 */
113 2
	public function checkDuplicateIndices(IndexCollection $indices) {
114 2
		$result = [];
115
116 2
		$indicesSecondary = clone $indices;
117
118 2
		foreach ($indices as $i => $index) {
119 2
			foreach ($indicesSecondary as $j => $indexSecondary) {
120
				/**
121
				 * Only check index that came before current index
122
				 */
123 2
				if ($j >= $i) {
124 2
					break;
125
				}
126
127
				/**
128
				 * Check if index is duplicate
129
				 */
130 2
				if ($index->isDuplicate($indexSecondary) === true) {
131 1
					$result[] = [
132 1
						'type'        => 'index',
133 1
						'key'         => $index->getKeyName(),
134 1
						'description' => sprintf('Is duplicate of %s', $indexSecondary->getKeyName())
135 1
					];
136
137 1
					break;
138
				}
139 2
			}
140 2
		}
141
142 2
		return $result;
143
	}
144
145
	/**
146
	 * Check for redundant indices on primary key column
147
	 *
148
	 * @param ColumnCollection $columns Table columns
149
	 * @param IndexCollection  $indices Table indices
150
	 *
151
	 * @return array Result
152
	 */
153 1
	public function checkRedundantIndicesOnPrimaryKey(ColumnCollection $columns, IndexCollection $indices) {
154 1
		$result = [];
155
156
		/**
157
		 * Check primary key columns
158
		 */
159 1
		foreach ($columns->isPrimaryKey() as $column) {
160 1
			$colums = [$column->getField()];
161
162
			/**
163
			 * Check non primary key indices
164
			 */
165 1
			foreach ($indices->isNotPrimaryKey() as $index) {
166
				/**
167
				 * Check indices with just our primary key column
168
				 */
169 1
				if ($index->isColumnsEqual($colums) === true) {
170 1
					$indexType = $index->isUnique() === true ? 'unique' : 'key';
171
172
					/**
173
					 * Check if index is unique
174
					 */
175 1
					$result[] = [
176 1
						'type'        => 'index',
177 1
						'key'         => $index->getKeyName(),
178 1
						'description' => sprintf('An %s index on the primary key column is redundant', $indexType)
179 1
					];
180 1
				}
181 1
			}
182 1
		}
183
184 1
		return $result;
185
	}
186
187
	/**
188
	 * @param ColumnCollection $columns Table columns
189
	 *
190
	 * @return array Result
191
	 */
192 1
	public function checkCollationMismatchBetweenTableAndColumns(ColumnCollection $columns) {
193 1
		$result = [];
194
195 1
		foreach ($columns as $column) {
196 1
			if ($column->hasCollation() === true) {
197 1
				if ($column->getCollation() !== $this->getCollation()) {
198 1
					$result[] = [
199 1
						'type'        => 'column',
200 1
						'key'         => $column->getField(),
201
						'description' => 'Column is not using same collation as table'
202 1
					];
203 1
				}
204 1
			}
205 1
		}
206
207 1
		return $result;
208
	}
209
}
210