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