Test Failed
Push — master ( d02081...898276 )
by P.R.
04:01
created

Diff::currentAuditTable()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 29
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 16
nc 3
nop 1
dl 0
loc 29
rs 8.8571
c 0
b 0
f 0
1
<?php
2
3
namespace SetBased\Audit\Audit;
4
5
use SetBased\Audit\DiffTable;
6
use SetBased\Audit\Metadata\TableColumnsMetadata;
7
use SetBased\Audit\MySql\AuditDataLayer;
8
use SetBased\Audit\MySql\Metadata\TableMetadata;
9
use SetBased\Stratum\Style\StratumStyle;
10
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
11
use Symfony\Component\Console\Input\InputInterface;
12
use Symfony\Component\Console\Output\OutputInterface;
13
14
/**
15
 * Class for executing auditing actions for tables.
16
 */
17
class Diff
18
{
19
  //--------------------------------------------------------------------------------------------------------------------
20
  /**
21
   * The metadata of the additional audit columns.
22
   *
23
   * @var TableColumnsMetadata
24
   */
25
  private $additionalAuditColumns;
26
27
  /**
28
   * The content of the configuration file.
29
   *
30
   * @var array
31
   */
32
  private $config;
33
34
  /**
35
   * The Input interface.
36
   *
37
   * @var InputInterface
38
   */
39
  private $input;
40
41
  /**
42
   * The Output decorator.
43
   *
44
   * @var StratumStyle
45
   */
46
  private $io;
47
48
  /**
49
   * The Output interface.
50
   *
51
   * @var OutputInterface
52
   */
53
  private $output;
54
55
  //--------------------------------------------------------------------------------------------------------------------
56
  /**
57
   * Object constructor.
58
   *
59
   * @param array[]         $config The content of the configuration file.
60
   * @param StratumStyle    $io     The Output decorator.
61
   * @param InputInterface  $input
62
   * @param OutputInterface $output
63
   */
64
  public function __construct(&$config, $io, $input, $output)
65
  {
66
    $this->io     = $io;
67
    $this->config = &$config;
68
    $this->input  = $input;
69
    $this->output = $output;
70
71
    $this->additionalAuditColumns =
72
      AuditDataLayer::resolveCanonicalAdditionalAuditColumns($this->config['database']['audit_schema'],
73
                                                             $this->config['audit_columns']);
74
  }
75
76
  //--------------------------------------------------------------------------------------------------------------------
77
  /**
78
   * The main method: executes the auditing actions for tables.
79
   */
80
  public function main()
81
  {
82
    // Style for column names with miss matched column types.
83
    $style = new OutputFormatterStyle(null, 'red');
84
    $this->output->getFormatter()->setStyle('mm_column', $style);
85
86
    // Style for column types of columns with miss matched column types.
87
    $style = new OutputFormatterStyle('yellow');
88
    $this->output->getFormatter()->setStyle('mm_type', $style);
89
90
    // Style for obsolete tables.
91
    $style = new OutputFormatterStyle('yellow');
92
    $this->output->getFormatter()->setStyle('obsolete_table', $style);
93
94
    // Style for missing tables.
95
    $style = new OutputFormatterStyle('red');
96
    $this->output->getFormatter()->setStyle('miss_table', $style);
97
98
    $lists = $this->getTableLists();
99
100
    $this->currentAuditTables($lists['current']);
101
102
    $this->missingAuditTables($lists['missing']);
103
104
    $this->obsoleteAuditTables($lists['obsolete']);
105
  }
106
107
  //--------------------------------------------------------------------------------------------------------------------
108
  /**
109
   * Prints the difference between a data and and its audit table.
110
   *
111
   * @param string $tableName The table name.
112
   */
113
  private function currentAuditTable($tableName)
114
  {
115
    $columns           = AuditDataLayer::getTableColumns($this->config['database']['data_schema'], $tableName);
116
    $dataTableColumns  = new TableColumnsMetadata($columns);
117
    $columns           = AuditDataLayer::getTableColumns($this->config['database']['audit_schema'], $tableName);
118
    $auditTableColumns = new TableColumnsMetadata($columns, 'AuditColumnMetadata');
119
120
    // In the audit table columns coming from the data table are always nullable.
121
    $dataTableColumns->makeNullable();
122
    $dataTableColumns->unsetDefaults();
123
    $dataTableColumns = TableColumnsMetadata::combine($this->additionalAuditColumns, $dataTableColumns);
124
125
    // In the audit table columns coming from the data table don't have defaults.
126
    foreach($auditTableColumns->getColumns() as $column)
127
    {
128
      if (!in_array($column->getName(), $this->additionalAuditColumns->getColumnNames()))
129
      {
130
        $column->unsetDefault();
131
      }
132
    }
133
134
    $dataTableOptions  = AuditDataLayer::getTableOptions($this->config['database']['data_schema'], $tableName);
135
    $auditTableOptions = AuditDataLayer::getTableOptions($this->config['database']['audit_schema'], $tableName);
136
137
    $dataTable  = new TableMetadata($dataTableOptions, $dataTableColumns);
138
    $auditTable = new TableMetadata($auditTableOptions, $auditTableColumns);
139
140
    $helper = new DiffTable($dataTable, $auditTable);
141
    $helper->print($this->io, $this->input->getOption('full'));
142
  }
143
144
  //--------------------------------------------------------------------------------------------------------------------
145
  /**
146
   * Prints the difference between data and audit tables.
147
   *
148
   * @param string[] $tableNames The names of the current tables.
149
   */
150
  private function currentAuditTables($tableNames)
151
  {
152
    foreach ($tableNames as $tableName)
153
    {
154
      $this->currentAuditTable($tableName);
155
    }
156
  }
157
158
  //--------------------------------------------------------------------------------------------------------------------
159
  /**
160
   * Returns the names of the tables that must be compared.
161
   *
162
   * @return array[]
163
   */
164
  private function getTableLists()
165
  {
166
    $tables1 = [];
167
    foreach ($this->config['tables'] as $tableName => $config)
168
    {
169
      if ($config['audit'])
170
      {
171
        $tables1[] = $tableName;
172
      }
173
    }
174
175
    $tables  = AuditDataLayer::getTablesNames($this->config['database']['data_schema']);
176
    $tables2 = [];
177
    foreach ($tables as $table)
178
    {
179
      $tables2[] = $table['table_name'];
180
    }
181
182
    $tables  = AuditDataLayer::getTablesNames($this->config['database']['audit_schema']);
183
    $tables3 = [];
184
    foreach ($tables as $table)
185
    {
186
      $tables3[] = $table['table_name'];
187
    }
188
189
    return ['current'  => array_intersect($tables1, $tables2, $tables3),
190
            'obsolete' => array_diff($tables3, $tables1),
191
            'missing'  => array_diff($tables1, $tables3)];
192
  }
193
194
  //--------------------------------------------------------------------------------------------------------------------
195
  /**
196
   * Prints the missing audit tables.
197
   *
198
   * @param string[] $tableNames The names of the obsolete tables.
199
   */
200
  private function missingAuditTables($tableNames)
201
  {
202
    if (empty($tableNames)) return;
203
204
    $this->io->title('Missing Audit Tables');
205
    $this->io->listing($tableNames);
206
  }
207
208
  //--------------------------------------------------------------------------------------------------------------------
209
  /**
210
   * Prints the obsolete audit tables.
211
   *
212
   * @param string[] $tableNames The names of the obsolete tables.
213
   */
214
  private function obsoleteAuditTables($tableNames)
215
  {
216
    if (empty($tableNames) || !$this->input->getOption('full')) return;
217
218
    $this->io->title('Obsolete Audit Tables');
219
    $this->io->listing($tableNames);
220
  }
221
222
  //--------------------------------------------------------------------------------------------------------------------
223
}
224
225
//----------------------------------------------------------------------------------------------------------------------
226