Completed
Push — master ( 8e94f8...744b49 )
by P.R.
04:26
created

Audit::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 5
ccs 4
cts 4
cp 1
rs 9.4285
cc 1
eloc 3
nc 1
nop 2
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
   * 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 9
  public function __construct(&$config, $io)
67
  {
68 9
    $this->config = $config;
69 9
    $this->io     = $io;
70 9
  }
71
72
  //--------------------------------------------------------------------------------------------------------------------
73
  /**
74
   * Getting list of all tables from information_schema of database from config file.
75
   */
76 9
  public function listOfTables()
77
  {
78 9
    $this->dataSchemaTables = AuditDataLayer::getTablesNames($this->config['database']['data_schema']);
79
80 9
    $this->auditSchemaTables = AuditDataLayer::getTablesNames($this->config['database']['audit_schema']);
81 9
  }
82
83
  //--------------------------------------------------------------------------------------------------------------------
84
  /**
85
   * The main method: executes the auditing actions for tables.
86
   */
87 9
  public function main()
88
  {
89 9
    if ($this->pruneOption)
90 9
    {
91
      $this->config['table_columns'] = [];
92
    }
93
94 9
    $this->resolveCanonicalAuditColumns();
95
96 9
    $this->listOfTables();
97
98 9
    $this->unknownTables();
99
100 9
    $this->knownTables();
101 9
  }
102
103
  //--------------------------------------------------------------------------------------------------------------------
104
  /**
105
   * Sets the columns metadata of a table in the configuration file.
106
   *
107
   * @param string               $tableName The name of table.
108
   * @param TableColumnsMetadata $columns   The metadata of the table columns.
109
   */
110 8
  public function setConfigTableColumns($tableName, $columns)
111
  {
112 8
    $newColumns = [];
113 8
    foreach ($columns->getColumns() as $column)
114
    {
115 8
      $newColumns[] = $column->getProperties();
116 8
    }
117 8
    $this->config['table_columns'][$tableName] = $newColumns;
118 8
  }
119
120
  //--------------------------------------------------------------------------------------------------------------------
121
  /**
122
   * Compares the tables listed in the config file and the tables found in the data schema.
123
   */
124 9
  public function unknownTables()
125
  {
126 9
    foreach ($this->dataSchemaTables as $table)
127
    {
128 8
      if (isset($this->config['tables'][$table['table_name']]))
129 8
      {
130 8
        if (!isset($this->config['tables'][$table['table_name']]['audit']))
131 8
        {
132
          $this->io->writeln(sprintf('<info>audit is not set for table %s</info>', $table['table_name']));
133
        }
134
        else
135
        {
136 8
          if ($this->config['tables'][$table['table_name']]['audit'])
137 8
          {
138 8
            if (!isset($this->config['tables'][$table['table_name']]['alias']))
139 8
            {
140
              $this->config['tables'][$table['table_name']]['alias'] = AuditTable::getRandomAlias();
141
            }
142 8
          }
143
        }
144 8
      }
145
      else
146
      {
147
        $this->io->writeln(sprintf('<info>Found new table %s</info>', $table['table_name']));
148
        $this->config['tables'][$table['table_name']] = ['audit' => false,
149
                                                         'alias' => null,
150
                                                         'skip'  => null];
151
      }
152 9
    }
153 9
  }
154
155
  //--------------------------------------------------------------------------------------------------------------------
156
  /**
157
   * Resolves the canonical column types of the audit table columns.
158
   */
159 9
  protected function resolveCanonicalAuditColumns()
160
  {
161
    // Return immediately of there are no audit columns.
162 9
    if (empty($this->config['audit_columns'])) return;
163
164 8
    $schema    = $this->config['database']['audit_schema'];
165 8
    $tableName = '_TMP_'.uniqid();
166 8
    AuditDataLayer::createTemporaryTable($schema, $tableName, $this->config['audit_columns']);
167 8
    $columns = AuditDataLayer::getTableColumns($schema, $tableName);
168 8
    AuditDataLayer::dropTemporaryTable($schema, $tableName);
169
170 8
    foreach ($this->config['audit_columns'] as $audit_column)
171
    {
172 8
      $key = StaticDataLayer::searchInRowSet('column_name', $audit_column['column_name'], $columns);
173 8
      if (isset($audit_column['value_type']))
174 8
      {
175 8
        $columns[$key]['value_type'] = $audit_column['value_type'];
176 8
      }
177 8
      if (isset($audit_column['expression']))
178 8
      {
179 2
        $columns[$key]['expression'] = $audit_column['expression'];
180 2
      }
181 8
    }
182
183 8
    $this->auditColumnsMetadata = new TableColumnsMetadata($columns, 'AuditColumnMetadata');
184 8
  }
185
186
  //--------------------------------------------------------------------------------------------------------------------
187
  /**
188
   * Processed known tables.
189
   */
190 9
  private function knownTables()
191
  {
192 9
    foreach ($this->dataSchemaTables as $table)
193
    {
194 8
      if ($this->config['tables'][$table['table_name']]['audit'])
195 8
      {
196 8
        $tableColumns = [];
197 8
        if (isset($this->config['table_columns'][$table['table_name']]))
198 8
        {
199 7
          $tableColumns = $this->config['table_columns'][$table['table_name']];
200 7
        }
201 8
        $configTable = new TableMetadata($table['table_name'],
202 8
                                         $this->config['database']['data_schema'],
203 8
                                         $tableColumns);
204
205 8
        $currentTable = new AuditTable($this->io,
206 8
                                       $configTable,
207 8
                                       $this->config['database']['audit_schema'],
208 8
                                       $this->auditColumnsMetadata,
209 8
                                       $this->config['tables'][$table['table_name']]['alias'],
210 8
                                       $this->config['tables'][$table['table_name']]['skip']);
211 8
        $res          = StaticDataLayer::searchInRowSet('table_name',
212 8
                                                        $currentTable->getTableName(),
213 8
                                                        $this->auditSchemaTables);
214 8
        if (!isset($res))
215 8
        {
216 5
          $currentTable->createMissingAuditTable();
217 5
        }
218
219 8
        $columns        = $currentTable->main($this->config['additional_sql']);
220 8
        $alteredColumns = $columns['altered_columns']->getColumns();
221 8
        if (empty($alteredColumns))
222 8
        {
223 8
          $this->setConfigTableColumns($currentTable->getTableName(), $columns['full_columns']);
224 8
        }
225 8
      }
226 9
    }
227 9
  }
228
229
  //--------------------------------------------------------------------------------------------------------------------
230
}
231
232
//----------------------------------------------------------------------------------------------------------------------
233