Completed
Push — master ( b7efbe...08e0f6 )
by P.R.
01:05
created

AuditDiff::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 7
ccs 0
cts 6
cp 0
rs 9.4285
cc 1
eloc 5
nc 1
nop 4
crap 2
1
<?php
2
//----------------------------------------------------------------------------------------------------------------------
3
namespace SetBased\Audit\MySql;
4
5
use SetBased\Audit\MySql\Helper\DiffTableHelper;
6
use SetBased\Audit\MySql\Metadata\TableColumnsMetadata;
7
use SetBased\Stratum\MySql\StaticDataLayer;
8
use SetBased\Stratum\Style\StratumStyle;
9
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
10
use Symfony\Component\Console\Helper\Table;
11
use Symfony\Component\Console\Input\InputInterface;
12
use Symfony\Component\Console\Output\OutputInterface;
13
14
//----------------------------------------------------------------------------------------------------------------------
15
/**
16
 * Class for executing auditing actions for tables.
17
 */
18
class AuditDiff
19
{
20
  //--------------------------------------------------------------------------------------------------------------------
21
  /**
22
   * The metadata (additional) audit columns (as stored in the config file).
23
   *
24
   * @var TableColumnsMetadata
25
   */
26
  private $auditColumnsMetadata;
27
28
  /**
29
   * The names of all tables in audit schema.
30
   *
31
   * @var array
32
   */
33
  private $auditSchemaTables;
34
35
  /**
36
   * The content of the configuration file.
37
   *
38
   * @var array
39
   */
40
  private $config;
41
42
  /**
43
   * The names of all tables in data schema.
44
   *
45
   * @var array
46
   */
47
  private $dataSchemaTables;
48
49
  /**
50
   * Array with columns for each table.
51
   * array [
52
   *    table_name [
53
   *            column [
54
   *                    data table type,
55
   *                    audit table type
56
   *                    ],
57
   *                      ...
58
   *               ]
59
   *       ]
60
   *
61
   * @var array[]
62
   */
63
  private $diffColumns;
64
65
  /**
66
   * If set all tables and columns are shown.
67
   *
68
   * @var boolean
69
   */
70
  private $full;
71
72
  /**
73
   * The Input interface.
74
   *
75
   * @var InputInterface
76
   */
77
  private $input;
78
79
  /**
80
   * The Output decorator.
81
   *
82
   * @var StratumStyle
83
   */
84
  private $io;
85
86
  /**
87
   * The Output interface.
88
   *
89
   * @var OutputInterface
90
   */
91
  private $output;
92
93
  //--------------------------------------------------------------------------------------------------------------------
94
  /**
95
   * Object constructor.
96
   *
97
   * @param array[]         $config The content of the configuration file.
98
   * @param StratumStyle    $io     The Output decorator.
99
   * @param InputInterface  $input
100
   * @param OutputInterface $output
101
   */
102
  public function __construct(&$config, $io, $input, $output)
103
  {
104
    $this->io     = $io;
105
    $this->config = &$config;
106
    $this->input  = $input;
107
    $this->output = $output;
108
  }
109
110
  //--------------------------------------------------------------------------------------------------------------------
111
  /**
112
   * The main method: executes the auditing actions for tables.
113
   */
114
  public function main()
115
  {
116
    // Style for column names with miss matched column types.
117
    $style = new OutputFormatterStyle(null, 'red');
118
    $this->output->getFormatter()->setStyle('mm_column', $style);
119
120
    // Style for column types of columns with miss matched column types.
121
    $style = new OutputFormatterStyle('yellow');
122
    $this->output->getFormatter()->setStyle('mm_type', $style);
123
124
    // Style for obsolete tables.
125
    $style = new OutputFormatterStyle('yellow');
126
    $this->output->getFormatter()->setStyle('obsolete_table', $style);
127
128
    // Style for missing tables.
129
    $style = new OutputFormatterStyle('red');
130
    $this->output->getFormatter()->setStyle('miss_table', $style);
131
132
    $this->full = $this->input->getOption('full');
133
134
    $this->resolveCanonicalAuditColumns();
135
136
    $this->listOfTables();
137
138
    $this->getDiff();
139
140
    $this->printDiff();
141
  }
142
143
  //--------------------------------------------------------------------------------------------------------------------
144
  /**
145
   * Writes the difference between the audit tables and metadata tables to the output.
146
   */
147
  private function diffTables()
148
  {
149
    foreach ($this->config['tables'] as $tableName => $table)
150
    {
151
      $res = StaticDataLayer::searchInRowSet('table_name', $tableName, $this->auditSchemaTables);
152
      if ($table['audit'] && !isset($res))
153
      {
154
        $this->output->writeln(sprintf('<miss_table>%s</>', $tableName));
155
      }
156
      else if (!$table['audit'] && isset($res))
157
      {
158
        $this->output->writeln(sprintf('<obsolete_table>%s</>', $tableName));
159
      }
160
    }
161
  }
162
163
  //--------------------------------------------------------------------------------------------------------------------
164
  /**
165
   * Computes the difference between data and audit tables.
166
   */
167
  private function getDiff()
168
  {
169
    foreach ($this->dataSchemaTables as $table)
170
    {
171
      if ($this->config['tables'][$table['table_name']]['audit'])
172
      {
173
174
        $res = StaticDataLayer::searchInRowSet('table_name', $table['table_name'], $this->auditSchemaTables);
175
        if (isset($res))
176
        {
177
          $this->diffColumns[$table['table_name']] = new AuditDiffTable($this->config['database']['data_schema'],
178
                                                                        $this->config['database']['audit_schema'],
179
                                                                        $table['table_name'],
180
                                                                        $this->config['audit_columns']);
181
        }
182
      }
183
    }
184
  }
185
186
  //--------------------------------------------------------------------------------------------------------------------
187
  /**
188
   * Getting list of all tables from information_schema of database from config file.
189
   */
190
  private function listOfTables()
191
  {
192
    $this->dataSchemaTables = AuditDataLayer::getTablesNames($this->config['database']['data_schema']);
193
194
    $this->auditSchemaTables = AuditDataLayer::getTablesNames($this->config['database']['audit_schema']);
195
  }
196
197
  //--------------------------------------------------------------------------------------------------------------------
198
  /**
199
   * Writes the difference between the audit and data tables to the output.
200
   */
201
  private function printDiff()
202
  {
203
    $first = true;
204
    if (isset($this->diffColumns))
205
    {
206
      /** @var AuditDiffTable $diffTable */
207
      foreach ($this->diffColumns as $tableName => $diffTable)
208
      {
209
        $columns = $diffTable->getDiffColumns();
0 ignored issues
show
Bug introduced by
The method getDiffColumns cannot be called on $diffTable (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
210
        // Remove matching columns unless the full option is used.
211
        if (!$this->full)
212
        {
213
          $columns = $diffTable->removeMatchingColumns();
0 ignored issues
show
Bug introduced by
The method removeMatchingColumns cannot be called on $diffTable (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
214
        }
215
216
        if (!empty($columns))
217
        {
218
          // Add an empty line between tables.
219
          if ($first)
220
          {
221
            $first = false;
222
          }
223
          else
224
          {
225
            $this->output->writeln('');
226
          }
227
228
          // Write table name.
229
          $this->output->writeln($tableName);
230
231
          // Write table with columns.
232
          $rows = new DiffTableHelper($this->config['database']['data_schema'],
233
                                      $this->config['database']['audit_schema'],
234
                                      $tableName,
235
                                      $this->config['audit_columns'],
236
                                      $this->full);
237
          $rows->appendRows($columns);
238
          $rows->addHighlighting();
239
          $table = new Table($this->output);
240
          $table->setHeaders(['column', 'data table', 'audit table', 'config'])
241
                ->setRows($rows->getRows());
242
          $table->render();
243
        }
244
      }
245
      $this->diffTables();
246
    }
247
  }
248
249
  //--------------------------------------------------------------------------------------------------------------------
250
  /**
251
   * Resolves the canonical column types of the audit table columns.
252
   */
253 View Code Duplication
  private function resolveCanonicalAuditColumns()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
254
  {
255
    if (empty($this->config['audit_columns']))
256
    {
257
      $this->auditColumnsMetadata = new TableColumnsMetadata();
258
    }
259
    else
260
    {
261
      $schema    = $this->config['database']['audit_schema'];
262
      $tableName = '_TMP_'.uniqid();
263
      AuditDataLayer::createTemporaryTable($schema, $tableName, $this->config['audit_columns']);
264
      $columns = AuditDataLayer::getTableColumns($schema, $tableName);
265
      AuditDataLayer::dropTemporaryTable($schema, $tableName);
266
267
      foreach ($this->config['audit_columns'] as $audit_column)
268
      {
269
        $key = StaticDataLayer::searchInRowSet('column_name', $audit_column['column_name'], $columns);
270
        if (isset($audit_column['value_type']))
271
        {
272
          $columns[$key]['value_type'] = $audit_column['value_type'];
273
        }
274
        if (isset($audit_column['expression']))
275
        {
276
          $columns[$key]['expression'] = $audit_column['expression'];
277
        }
278
      }
279
280
      $this->auditColumnsMetadata = new TableColumnsMetadata($columns, 'AuditColumnMetadata');
281
    }
282
  }
283
284
  //--------------------------------------------------------------------------------------------------------------------
285
}
286
287
//----------------------------------------------------------------------------------------------------------------------
288