Completed
Push — master ( 3c3a68...38d739 )
by P.R.
02:44
created

Audit::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 6
ccs 5
cts 5
cp 1
rs 9.4285
cc 1
eloc 4
nc 1
nop 3
crap 1
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 = [];
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[$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>Found new table %s</info>', $table['table_name']));
146
          $this->io->writeln(sprintf('<info>audit is not set for table %s</info>', $table['table_name']));
147
        }
148
        else
149
        {
150 12
          if ($this->config['tables'][$table['table_name']]['audit'])
151 12
          {
152 12
            if (!isset($this->config['tables'][$table['table_name']]['alias']))
153 12
            {
154
              $this->config['tables'][$table['table_name']]['alias'] = AuditTable::getRandomAlias();
155
            }
156 12
          }
157
        }
158 12
      }
159
      else
160
      {
161
        $this->io->writeln(sprintf('<info>Found new table %s</info>', $table['table_name']));
162
        $this->config['tables'][$table['table_name']] = ['audit' => false,
163
                                                         'alias' => null,
164
                                                         'skip'  => null];
165
      }
166 13
    }
167 13
  }
168
169
  //--------------------------------------------------------------------------------------------------------------------
170
  /**
171
   * Resolves the canonical column types of the audit table columns.
172
   */
173 13
  protected function resolveCanonicalAuditColumns()
174
  {
175 13
    if (empty($this->config['audit_columns']))
176 13
    {
177 4
      $this->auditColumnsMetadata = new TableColumnsMetadata();
178 4
    }
179
    else
180
    {
181 9
      $schema    = $this->config['database']['audit_schema'];
182 9
      $tableName = '_TMP_'.uniqid();
183 9
      AuditDataLayer::createTemporaryTable($schema, $tableName, $this->config['audit_columns']);
184 9
      $columns = AuditDataLayer::getTableColumns($schema, $tableName);
185 9
      AuditDataLayer::dropTemporaryTable($schema, $tableName);
186
187 9
      foreach ($this->config['audit_columns'] as $audit_column)
188
      {
189 9
        $key = StaticDataLayer::searchInRowSet('column_name', $audit_column['column_name'], $columns);
190 9
        if (isset($audit_column['value_type']))
191 9
        {
192 9
          $columns[$key]['value_type'] = $audit_column['value_type'];
193 9
        }
194 9
        if (isset($audit_column['expression']))
195 9
        {
196 2
          $columns[$key]['expression'] = $audit_column['expression'];
197 2
        }
198 9
      }
199
200 9
      $this->auditColumnsMetadata = new TableColumnsMetadata($columns, 'AuditColumnMetadata');
201
    }
202 13
  }
203
204
  //--------------------------------------------------------------------------------------------------------------------
205
  /**
206
   * Processed known tables.
207
   *
208
   * @return int The exit status.
209
   */
210 13
  private function knownTables()
211
  {
212 13
    $status = 0;
213
214 13
    foreach ($this->dataSchemaTables as $table)
215
    {
216 12
      if ($this->config['tables'][$table['table_name']]['audit'])
217 12
      {
218 12
        if (isset($this->configMetadata[$table['table_name']]))
219 12
        {
220 1
          $tableColumns = $this->configMetadata[$table['table_name']];
221 1
        }
222
        else
223
        {
224 11
          $tableColumns = [];
225
        }
226
227 12
        $configTable = new TableMetadata($table['table_name'],
228 12
                                         $this->config['database']['data_schema'],
229 12
                                         $tableColumns);
230
231 12
        $currentTable = new AuditTable($this->io,
232 12
                                       $configTable,
233 12
                                       $this->config['database']['audit_schema'],
234 12
                                       $this->auditColumnsMetadata,
235 12
                                       $this->config['tables'][$table['table_name']]['alias'],
236 12
                                       $this->config['tables'][$table['table_name']]['skip']);
237
238
        // Ensure an audit table exists.
239 12
        if (StaticDataLayer::searchInRowSet('table_name', $table['table_name'], $this->auditSchemaTables)===null)
240 12
        {
241 9
          $currentTable->createAuditTable();
242 9
        }
243
244
        // Drop and create audit triggers and add new columns to the audit table.
245 12
        $ok = $currentTable->main($this->config['additional_sql']);
246
        if ($ok)
247 12
        {
248 12
          $columns = new TableColumnsMetadata(AuditDataLayer::getTableColumns($this->config['database']['data_schema'],
249 12
                                                                              $table['table_name']));
250 12
          $this->setConfigTableColumns($table['table_name'], $columns);
251 12
        }
252
        else
253
        {
254 1
          $status += 1;
255
        }
256 12
      }
257
      else
258
      {
259
        $configTable = new TableMetadata($table['table_name'],
260
                                         $this->config['database']['data_schema'],
261
                                         []);
262
263
        $currentTable = new AuditTable($this->io,
264
                                       $configTable,
265
                                       $this->config['database']['audit_schema'],
266
                                       $this->auditColumnsMetadata,
267
                                       '',
268
                                       '');
269
270
        $currentTable->dropAuditTriggers($this->config['database']['data_schema'], $table['table_name']);
271
      }
272 13
    }
273
274 13
    return $status;
275
  }
276
277
  //--------------------------------------------------------------------------------------------------------------------
278
}
279
280
//----------------------------------------------------------------------------------------------------------------------
281