Completed
Push — master ( cd78ea...1f7a6d )
by P.R.
02:52
created

Audit::unknownTables()   A

Complexity

Conditions 6
Paths 6

Size

Total Lines 27
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 7.3329

Importance

Changes 0
Metric Value
cc 6
eloc 13
nc 6
nop 0
dl 0
loc 27
ccs 8
cts 12
cp 0.6667
crap 7.3329
rs 9.2222
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace SetBased\Audit\Audit;
5
6
use SetBased\Audit\AuditTable;
7
use SetBased\Audit\Metadata\TableColumnsMetadata;
8
use SetBased\Audit\MySql\AuditDataLayer;
9
use SetBased\Audit\Style\AuditStyle;
10
use SetBased\Config\TypedConfig;
11
use SetBased\Stratum\Helper\RowSetHelper;
12
13
/**
14
 * Class for executing auditing actions for tables.
15
 */
16
class Audit
17
{
18
  //--------------------------------------------------------------------------------------------------------------------
19
  /**
20
   * The metadata of the additional audit columns.
21
   *
22
   * @var TableColumnsMetadata
23
   */
24
  private $additionalAuditColumns;
25
26
  /**
27
   * The names of all tables in audit schema.
28
   *
29
   * @var array
30
   */
31
  private $auditSchemaTables;
32
33
  /**
34
   * The strong typed configuration reader and writer.
35
   *
36
   * @var TypedConfig
37
   */
38
  private $config;
39
40
  /**
41
   * The names of all tables in data schema.
42
   *
43
   * @var array
44
   */
45
  private $dataSchemaTables;
46
47
  /**
48
   * The Output decorator.
49
   *
50
   * @var AuditStyle
51
   */
52
  private $io;
53
54
  //--------------------------------------------------------------------------------------------------------------------
55
  /**
56
   * Object constructor.
57
   *
58
   * @param TypedConfig $config The strong typed configuration reader and writer.
59
   * @param AuditStyle  $io     The Output decorator.
60
   */
61 26
  public function __construct(TypedConfig $config, AuditStyle $io)
62
  {
63 26
    $this->config = $config;
64 26
    $this->io     = $io;
65
66 26
    $this->additionalAuditColumns =
67 26
      AuditDataLayer::resolveCanonicalAdditionalAuditColumns($this->config->getManString('database.audit_schema'),
68 26
                                                             $this->config->getManArray('audit_columns'));
69 26
  }
70
71
  //--------------------------------------------------------------------------------------------------------------------
72
  /**
73
   * Getting list of all tables from information_schema of database from config file.
74
   */
75 26
  public function listOfTables(): void
76
  {
77 26
    $this->dataSchemaTables  = AuditDataLayer::getTablesNames($this->config->getManString('database.data_schema'));
78 26
    $this->auditSchemaTables = AuditDataLayer::getTablesNames($this->config->getManString('database.audit_schema'));
79 26
  }
80
81
  //--------------------------------------------------------------------------------------------------------------------
82
  /**
83
   * The main method: executes the auditing actions for tables.
84
   */
85 26
  public function main(): void
86
  {
87 26
    $this->listOfTables();
88
89 26
    $this->unknownTables();
90
91 26
    $this->obsoleteTables();
92
93 26
    $this->knownTables();
94 26
  }
95
96
  //--------------------------------------------------------------------------------------------------------------------
97
  /**
98
   * Removes tables listed in the config file that are not longer in the data schema from the config file.
99
   */
100 26
  public function obsoleteTables(): void
101
  {
102 26
    foreach ($this->config->getManArray('tables') as $tableName => $dummy)
103
    {
104 25
      if (RowSetHelper::searchInRowSet($this->dataSchemaTables, 'table_name', $tableName)===null)
105
      {
106 8
        $this->io->writeln(sprintf('<info>Removing obsolete table %s from config file</info>', $tableName));
107
108
        // Unset table (work a round bug in \Noodlehaus\Config::remove()).
109 8
        $config = $this->config->getConfig();
110 8
        $tables = $config['tables'];
111 8
        unset($tables[$tableName]);
112 25
        $config->set('tables', $tables);
113
      }
114
    }
115 26
  }
116
117
  //--------------------------------------------------------------------------------------------------------------------
118
  /**
119
   * Compares the tables listed in the config file and the tables found in the data schema.
120
   */
121 26
  public function unknownTables(): void
122
  {
123 26
    foreach ($this->dataSchemaTables as $table)
124
    {
125 25
      if ($this->config->getOptArray('tables.'.$table['table_name'])!==null)
126
      {
127 25
        if ($this->config->getOptBool('tables.'.$table['table_name'].'.audit')===null)
128
        {
129
          $this->io->writeln(sprintf('<info>Audit not set for table %s</info>', $table['table_name']));
130
        }
131
        else
132
        {
133 25
          if ($this->config->getManBool('tables.'.$table['table_name'].'.audit'))
134
          {
135 25
            if ($this->config->getOptString('tables.'.$table['table_name'].'.alias')===null)
136
            {
137
              $config                                          = $this->config->getConfig();
138 25
              $config['tables'][$table['table_name']]['alias'] = AuditTable::getRandomAlias();
139
            }
140
          }
141
        }
142
      }
143
      else
144
      {
145
        $this->io->writeln(sprintf('<info>Found new table %s</info>', $table['table_name']));
146
        $config = $this->config->getConfig();
147 25
        $config->set('tables.'.$table['table_name'], ['audit' => null, 'alias' => null, 'skip' => null]);
148
      }
149
    }
150 26
  }
151
152
  //--------------------------------------------------------------------------------------------------------------------
153
  /**
154
   * Processed known tables.
155
   */
156 26
  private function knownTables(): void
157
  {
158 26
    foreach ($this->dataSchemaTables as $table)
159
    {
160 25
      if ($this->config->getManBool('tables.'.$table['table_name'].'.audit'))
161
      {
162 25
        $currentTable = new AuditTable($this->io,
163 25
                                       $this->config->getManString('database.data_schema'),
164 25
                                       $this->config->getManString('database.audit_schema'),
165 25
                                       $table['table_name'],
166 25
                                       $this->additionalAuditColumns,
167 25
                                       $this->config->getOptString('tables.'.$table['table_name'].'.alias'),
168 25
                                       $this->config->getOptString('tables.'.$table['table_name'].'.skip'));
169
170
        // Ensure the audit table exists.
171 25
        if (RowSetHelper::searchInRowSet($this->auditSchemaTables, 'table_name', $table['table_name'])===null)
172
        {
173 22
          $currentTable->createAuditTable();
174
        }
175
176
        // Drop and create audit triggers and add new columns to the audit table.
177 25
        $currentTable->main($this->config->getManArray('additional_sql'));
178
      }
179
      else
180
      {
181
        AuditTable::dropAuditTriggers($this->io,
182
                                      $this->config->getManString('database.data_schema'),
183 25
                                      $table['table_name']);
184
      }
185
    }
186 26
  }
187
188
  //--------------------------------------------------------------------------------------------------------------------
189
}
190
191
//----------------------------------------------------------------------------------------------------------------------
192