Completed
Push — master ( fa00f5...226160 )
by P.R.
03:39
created

Audit::resolveCanonicalAuditColumns()   B

Complexity

Conditions 5
Paths 6

Size

Total Lines 30
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 23
CRAP Score 5

Importance

Changes 2
Bugs 1 Features 0
Metric Value
c 2
b 1
f 0
dl 0
loc 30
ccs 23
cts 23
cp 1
rs 8.439
cc 5
eloc 16
nc 6
nop 0
crap 5
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 11
  public function setConfigTableColumns($tableName, $columns)
115
  {
116 11
    $newColumns = [];
117 11
    foreach ($columns->getColumns() as $column)
118
    {
119 11
      $newColumns[] = $column->getProperties();
120 11
    }
121 11
    $this->config['table_columns'][$tableName] = $newColumns;
122 11
  }
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
   * Resolves the canonical column types of the audit table columns.
162
   */
163 13
  protected function resolveCanonicalAuditColumns()
164
  {
165 13
    if (empty($this->config['audit_columns']))
166 13
    {
167 4
      $this->auditColumnsMetadata = new TableColumnsMetadata();
168 4
    }
169
    else
170
    {
171 9
      $schema    = $this->config['database']['audit_schema'];
172 9
      $tableName = '_TMP_'.uniqid();
173 9
      AuditDataLayer::createTemporaryTable($schema, $tableName, $this->config['audit_columns']);
174 9
      $columns = AuditDataLayer::getTableColumns($schema, $tableName);
175 9
      AuditDataLayer::dropTemporaryTable($schema, $tableName);
176
177 9
      foreach ($this->config['audit_columns'] as $audit_column)
178
      {
179 9
        $key = StaticDataLayer::searchInRowSet('column_name', $audit_column['column_name'], $columns);
180 9
        if (isset($audit_column['value_type']))
181 9
        {
182 9
          $columns[$key]['value_type'] = $audit_column['value_type'];
183 9
        }
184 9
        if (isset($audit_column['expression']))
185 9
        {
186 2
          $columns[$key]['expression'] = $audit_column['expression'];
187 2
        }
188 9
      }
189
190 9
      $this->auditColumnsMetadata = new TableColumnsMetadata($columns, 'AuditColumnMetadata');
191
    }
192 13
  }
193
194
  //--------------------------------------------------------------------------------------------------------------------
195
  /**
196
   * Processed known tables.
197
   *
198
   * @return int The exit status.
199
   */
200 13
  private function knownTables()
201
  {
202 13
    $status = 0;
203
204 13
    foreach ($this->dataSchemaTables as $table)
205
    {
206 12
      if ($this->config['tables'][$table['table_name']]['audit'])
207 12
      {
208 12
        if (isset($this->config['table_columns'][$table['table_name']]))
209 12
        {
210 1
          $tableColumns = $this->config['table_columns'][$table['table_name']];
211 1
        }
212
        else
213
        {
214 11
          $tableColumns = [];
215
        }
216 12
        $configTable = new TableMetadata($table['table_name'],
217 12
                                         $this->config['database']['data_schema'],
218 12
                                         $tableColumns);
219
220 12
        $currentTable = new AuditTable($this->io,
221 12
                                       $configTable,
222 12
                                       $this->config['database']['audit_schema'],
223 12
                                       $this->auditColumnsMetadata,
224 12
                                       $this->config['tables'][$table['table_name']]['alias'],
225 12
                                       $this->config['tables'][$table['table_name']]['skip']);
226
227
        // Ensure an audit table exists.
228 12
        if (StaticDataLayer::searchInRowSet('table_name', $table['table_name'], $this->auditSchemaTables)===null)
229 12
        {
230 9
          $currentTable->createAuditTable();
231 9
        }
232
233
        // Drop and create audit triggers and add new columns to the audit table.
234 12
        $ok = $currentTable->main($this->config['additional_sql']);
235
        if ($ok)
236 12
        {
237 11
          $columns = new TableColumnsMetadata(AuditDataLayer::getTableColumns($this->config['database']['data_schema'],
238 11
                                                                              $table['table_name']));
239 11
          $this->setConfigTableColumns($table['table_name'], $columns);
240 11
        }
241
        else
242
        {
243 1
          $status += 1;
244
        }
245 12
      }
246 13
    }
247
248 13
    return $status;
249
  }
250
251
  //--------------------------------------------------------------------------------------------------------------------
252
}
253
254
//----------------------------------------------------------------------------------------------------------------------
255