Completed
Push — master ( 83448c...a913db )
by P.R.
01:09
created

Audit::knownTables()   B

Complexity

Conditions 6
Paths 10

Size

Total Lines 54
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 33
CRAP Score 6.0009

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 54
ccs 33
cts 34
cp 0.9706
rs 8.7449
cc 6
eloc 29
nc 10
nop 0
crap 6.0009

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
//----------------------------------------------------------------------------------------------------------------------
3
namespace SetBased\Audit\MySql;
4
5
use SetBased\Audit\MySql\Metadata\TableColumnsMetadata;
6
use SetBased\Audit\MySql\Metadata\TableMetadata;
7
use SetBased\Stratum\MySql\StaticDataLayer;
8
use SetBased\Stratum\Style\StratumStyle;
9
10
//----------------------------------------------------------------------------------------------------------------------
11
/**
12
 * Class for executing auditing actions for tables.
13
 */
14
class Audit
15
{
16
  //--------------------------------------------------------------------------------------------------------------------
17
  /**
18
   * The metadata (additional) audit columns (as stored in the config file).
19
   *
20
   * @var TableColumnsMetadata
21
   */
22
  private $auditColumnsMetadata;
23
24
  /**
25
   * The names of all tables in audit schema.
26
   *
27
   * @var array
28
   */
29
  private $auditSchemaTables;
30
31
  /**
32
   * The content of the configuration file.
33
   *
34
   * @var array
35
   */
36
  private $config;
37
38
  /**
39
   * Tables metadata from config file.
40
   *
41
   * @var array
42
   */
43
  private $configMetadata;
44
45
  /**
46
   * The names of all tables in data schema.
47
   *
48
   * @var array
49
   */
50
  private $dataSchemaTables;
51
52
  /**
53
   * The Output decorator.
54
   *
55
   * @var StratumStyle
56
   */
57
  private $io;
58
59
  /**
60
   * If true remove all column information from config file.
61
   *
62
   * @var boolean
63
   */
64
  private $pruneOption;
65
66
  //--------------------------------------------------------------------------------------------------------------------
67
  /**
68
   * Object constructor.
69
   *
70
   * @param array[]      $config         The content of the configuration file.
71
   * @param array[]      $configMetadata The content of the metadata file.
72
   * @param StratumStyle $io             The Output decorator.
73
   */
74 13
  public function __construct(&$config, &$configMetadata, $io)
75
  {
76 13
    $this->config         = &$config;
77 13
    $this->configMetadata = &$configMetadata;
78 13
    $this->io             = $io;
79 13
  }
80
81
  //--------------------------------------------------------------------------------------------------------------------
82
  /**
83
   * Getting list of all tables from information_schema of database from config file.
84
   */
85 13
  public function listOfTables()
86
  {
87 13
    $this->dataSchemaTables = AuditDataLayer::getTablesNames($this->config['database']['data_schema']);
88
89 13
    $this->auditSchemaTables = AuditDataLayer::getTablesNames($this->config['database']['audit_schema']);
90 13
  }
91
92
  //--------------------------------------------------------------------------------------------------------------------
93
  /**
94
   * The main method: executes the auditing actions for tables.
95
   *
96
   * @return int The exit status.
97
   */
98 13
  public function main()
99
  {
100 13
    if ($this->pruneOption)
101 13
    {
102
      $this->configMetadata['table_columns'] = [];
103
    }
104
105 13
    $this->resolveCanonicalAuditColumns();
106
107 13
    $this->listOfTables();
108
109 13
    $this->unknownTables();
110
111 13
    $status = $this->knownTables();
112
113 13
    return $status;
114
  }
115
116
  //--------------------------------------------------------------------------------------------------------------------
117
  /**
118
   * Sets the columns metadata of a table in the configuration file.
119
   *
120
   * @param string               $tableName The name of table.
121
   * @param TableColumnsMetadata $columns   The metadata of the table columns.
122
   */
123 12
  public function setConfigTableColumns($tableName, $columns)
124
  {
125 12
    $newColumns = [];
126 12
    foreach ($columns->getColumns() as $column)
127
    {
128 12
      $newColumns[] = $column->getProperties();
129 12
    }
130 12
    $this->configMetadata['table_columns'][$tableName] = $newColumns;
131 12
  }
132
133
  //--------------------------------------------------------------------------------------------------------------------
134
  /**
135
   * Compares the tables listed in the config file and the tables found in the data schema.
136
   */
137 13
  public function unknownTables()
138
  {
139 13
    foreach ($this->dataSchemaTables as $table)
140
    {
141 12
      if (isset($this->config['tables'][$table['table_name']]))
142 12
      {
143 12
        if (!isset($this->config['tables'][$table['table_name']]['audit']))
144 12
        {
145
          $this->io->writeln(sprintf('<info>audit is not set for table %s</info>', $table['table_name']));
146
        }
147
        else
148
        {
149 12
          if ($this->config['tables'][$table['table_name']]['audit'])
150 12
          {
151 12
            if (!isset($this->config['tables'][$table['table_name']]['alias']))
152 12
            {
153
              $this->config['tables'][$table['table_name']]['alias'] = AuditTable::getRandomAlias();
154
            }
155 12
          }
156
        }
157 12
      }
158
      else
159
      {
160
        $this->io->writeln(sprintf('<info>Found new table %s</info>', $table['table_name']));
161
        $this->config['tables'][$table['table_name']] = ['audit' => false,
162
                                                                 'alias' => null,
163
                                                                 'skip'  => null];
164
      }
165 13
    }
166 13
  }
167
168
  //--------------------------------------------------------------------------------------------------------------------
169
  /**
170
   * Drop triggers from obsolete table.
171
   *
172
   * @param string $schemaName The schema name.
173
   * @param string $tableName  The table name.
174
   */
175 View Code Duplication
  protected function dropTriggersFromObsoleteTable($schemaName, $tableName)
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...
176
  {
177
    $triggers = AuditDataLayer::getTableTriggers($schemaName, $tableName);
178
    foreach ($triggers as $trigger)
179
    {
180
      if (preg_match('/trg_audit_.*_(insert|update|delete)/', $trigger['trigger_name']))
181
      {
182
        $this->io->logInfo('Dropping trigger <dbo>%s</dbo> from obsolete table <dbo>%s</dbo>',
183
                           $trigger['trigger_name'],
184
                           $tableName);
185
186
        AuditDataLayer::dropTrigger($schemaName, $trigger['trigger_name']);
187
      }
188
    }
189
  }
190
191
  //--------------------------------------------------------------------------------------------------------------------
192
  /**
193
   * Resolves the canonical column types of the audit table columns.
194
   */
195 13 View Code Duplication
  protected 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...
196
  {
197 13
    if (empty($this->config['audit_columns']))
198 13
    {
199 4
      $this->auditColumnsMetadata = new TableColumnsMetadata();
200 4
    }
201
    else
202
    {
203 9
      $schema    = $this->config['database']['audit_schema'];
204 9
      $tableName = '_TMP_'.uniqid();
205 9
      AuditDataLayer::createTemporaryTable($schema, $tableName, $this->config['audit_columns']);
206 9
      $columns = AuditDataLayer::getTableColumns($schema, $tableName);
207 9
      AuditDataLayer::dropTemporaryTable($schema, $tableName);
208
209 9
      foreach ($this->config['audit_columns'] as $audit_column)
210
      {
211 9
        $key = StaticDataLayer::searchInRowSet('column_name', $audit_column['column_name'], $columns);
212 9
        if (isset($audit_column['value_type']))
213 9
        {
214 9
          $columns[$key]['value_type'] = $audit_column['value_type'];
215 9
        }
216 9
        if (isset($audit_column['expression']))
217 9
        {
218 2
          $columns[$key]['expression'] = $audit_column['expression'];
219 2
        }
220 9
      }
221
222 9
      $this->auditColumnsMetadata = new TableColumnsMetadata($columns, 'AuditColumnMetadata');
223
    }
224 13
  }
225
226
  //--------------------------------------------------------------------------------------------------------------------
227
  /**
228
   * Processed known tables.
229
   *
230
   * @return int The exit status.
231
   */
232 13
  private function knownTables()
233
  {
234 13
    $status = 0;
235
236 13
    foreach ($this->dataSchemaTables as $table)
237
    {
238 12
      if ($this->config['tables'][$table['table_name']]['audit'])
239 12
      {
240 12
        if (isset($this->configMetadata['table_columns'][$table['table_name']]))
241 12
        {
242 1
          $tableColumns = $this->configMetadata['table_columns'][$table['table_name']];
243 1
        }
244
        else
245
        {
246 11
          $tableColumns = [];
247
        }
248 12
        $configTable = new TableMetadata($table['table_name'],
249 12
                                         $this->config['database']['data_schema'],
250 12
                                         $tableColumns);
251
252 12
        $currentTable = new AuditTable($this->io,
253 12
                                       $configTable,
254 12
                                       $this->config['database']['audit_schema'],
255 12
                                       $this->auditColumnsMetadata,
256 12
                                       $this->config['tables'][$table['table_name']]['alias'],
257 12
                                       $this->config['tables'][$table['table_name']]['skip']);
258
259
        // Ensure an audit table exists.
260 12
        if (StaticDataLayer::searchInRowSet('table_name', $table['table_name'], $this->auditSchemaTables)===null)
261 12
        {
262 9
          $currentTable->createAuditTable();
263 9
        }
264
265
        // Drop and create audit triggers and add new columns to the audit table.
266 12
        $ok = $currentTable->main($this->config['additional_sql']);
267
        if ($ok)
268 12
        {
269 12
          $columns = new TableColumnsMetadata(AuditDataLayer::getTableColumns($this->config['database']['data_schema'],
270 12
                                                                              $table['table_name']));
271 12
          $this->setConfigTableColumns($table['table_name'], $columns);
272 12
        }
273
        else
274
        {
275 1
          $status += 1;
276
        }
277 12
      }
278
      else
279
      {
280
        $this->dropTriggersFromObsoleteTable($this->config['database']['data_schema'], $table['table_name']);
281
      }
282 13
    }
283
284 13
    return $status;
285
  }
286
287
  //--------------------------------------------------------------------------------------------------------------------
288
}
289
290
//----------------------------------------------------------------------------------------------------------------------
291