Completed
Pull Request — master (#42)
by Dima
27:18
created

Audit::dropTriggersFromObsoleteTable()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 7

Duplication

Lines 12
Ratio 100 %

Code Coverage

Tests 9
CRAP Score 2

Importance

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