Completed
Push — master ( c95337...5e0152 )
by P.R.
04:34
created

Audit   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 265
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 84.88%

Importance

Changes 5
Bugs 0 Features 0
Metric Value
wmc 23
c 5
b 0
f 0
lcom 1
cbo 6
dl 0
loc 265
ccs 73
cts 86
cp 0.8488
rs 10

7 Methods

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