Completed
Push — master ( 1f7a6d...d6c443 )
by P.R.
03:14
created

AuditDataLayer::createAuditTrigger()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 22
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 11
nc 1
nop 9
dl 0
loc 22
ccs 12
cts 12
cp 1
crap 1
rs 9.9
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
declare(strict_types=1);
3
4
namespace SetBased\Audit\MySql;
5
6
use SetBased\Audit\Metadata\TableColumnsMetadata;
7
use SetBased\Audit\MySql\Sql\AlterAuditTableAddColumns;
8
use SetBased\Audit\MySql\Sql\CreateAuditTable;
9
use SetBased\Audit\MySql\Sql\CreateAuditTrigger;
10
use SetBased\Audit\Style\AuditStyle;
11
use SetBased\Helper\CodeStore\MySqlCompoundSyntaxCodeStore;
12
use SetBased\Stratum\BulkHandler;
13
use SetBased\Stratum\Helper\RowSetHelper;
14
use SetBased\Stratum\MySql\StaticDataLayer;
15
16
/**
17
 * Class for executing SQL statements and retrieving metadata from MySQL.
18
 */
19
class AuditDataLayer extends StaticDataLayer
20
{
21
  //--------------------------------------------------------------------------------------------------------------------
22
  /**
23
   * The Output decorator.
24
   *
25
   * @var AuditStyle
26
   */
27
  private static $io;
28
29
  //--------------------------------------------------------------------------------------------------------------------
30
  /**
31
   * Adds new columns to an audit table.
32
   *
33
   * @param string               $auditSchemaName The name of audit schema.
34
   * @param string               $tableName       The name of the table.
35
   * @param TableColumnsMetadata $columns         The metadata of the new columns.
36
   */
37 2
  public static function addNewColumns(string $auditSchemaName, string $tableName, TableColumnsMetadata $columns): void
38
  {
39 2
    $helper = new AlterAuditTableAddColumns($auditSchemaName, $tableName, $columns);
40 2
    $sql    = $helper->buildStatement();
41
42 2
    static::executeNone($sql);
43 2
  }
44
45
  //--------------------------------------------------------------------------------------------------------------------
46
  /**
47
   * Creates an audit table.
48
   *
49
   * @param string               $dataSchemaName  The name of the data schema.
50
   * @param string               $auditSchemaName The name of the audit schema.
51
   * @param string               $tableName       The name of the table.
52
   * @param TableColumnsMetadata $columns         The metadata of the columns of the audit table (i.e. the audit
53
   *                                              columns and columns of the data table).
54
   */
55 25
  public static function createAuditTable(string $dataSchemaName,
56
                                          string $auditSchemaName,
57
                                          string $tableName,
58
                                          TableColumnsMetadata $columns): void
59
  {
60 25
    $helper = new CreateAuditTable($dataSchemaName, $auditSchemaName, $tableName, $columns);
61 25
    $sql    = $helper->buildStatement();
62
63 25
    static::executeNone($sql);
64 25
  }
65
66
  //--------------------------------------------------------------------------------------------------------------------
67
  /**
68
   * Creates a trigger on a table.
69
   *
70
   * @param string               $dataSchemaName         The name of the data schema.
71
   * @param string               $auditSchemaName        The name of the audit schema.
72
   * @param string               $tableName              The name of the table.
73
   * @param string               $triggerAction          The trigger action (i.e. INSERT, UPDATE, or DELETE).
74
   * @param string               $triggerName            The name of the trigger.
75
   * @param TableColumnsMetadata $additionalAuditColumns The metadata of the additional audit columns.
76
   * @param TableColumnsMetadata $tableColumns           The metadata of the data table columns.
77
   * @param string|null          $skipVariable           The skip variable.
78
   * @param string[]             $additionSql            Additional SQL statements.
79
   */
80 28
  public static function createAuditTrigger(string $dataSchemaName,
81
                                            string $auditSchemaName,
82
                                            string $tableName,
83
                                            string $triggerName,
84
                                            string $triggerAction,
85
                                            TableColumnsMetadata $additionalAuditColumns,
86
                                            TableColumnsMetadata $tableColumns,
87
                                            ?string $skipVariable,
88
                                            array $additionSql): void
89
  {
90 28
    $helper = new CreateAuditTrigger($dataSchemaName,
91 28
                                     $auditSchemaName,
92 28
                                     $tableName,
93 28
                                     $triggerName,
94 28
                                     $triggerAction,
95 28
                                     $additionalAuditColumns,
96 28
                                     $tableColumns,
97 28
                                     $skipVariable,
98 28
                                     $additionSql);
99 28
    $sql    = $helper->buildStatement();
100
101 28
    static::executeNone($sql);
102 28
  }
103
104
  //--------------------------------------------------------------------------------------------------------------------
105
  /**
106
   * Creates a temporary table for getting column type information for audit columns.
107
   *
108
   * @param string  $schemaName   The name of the table schema.
109
   * @param string  $tableName    The table name.
110
   * @param array[] $auditColumns Audit columns from config file.
111
   */
112 19
  public static function createTemporaryTable(string $schemaName, string $tableName, array $auditColumns): void
113
  {
114 19
    $sql = new MySqlCompoundSyntaxCodeStore();
115 19
    $sql->append(sprintf('create table `%s`.`%s` (', $schemaName, $tableName));
116 19
    foreach ($auditColumns as $column)
117
    {
118 19
      $sql->append(sprintf('%s %s', $column['column_name'], $column['column_type']));
119 19
      if (end($auditColumns)!==$column)
120
      {
121 19
        $sql->appendToLastLine(',');
122
      }
123
    }
124 19
    $sql->append(')');
125
126 19
    static::executeNone($sql->getCode());
127 19
  }
128
129
  //--------------------------------------------------------------------------------------------------------------------
130
  /**
131
   * Drops a temporary table.
132
   *
133
   * @param string $schemaName The name of the table schema.
134
   * @param string $tableName  The name of the table.
135
   */
136 19
  public static function dropTemporaryTable(string $schemaName, string $tableName): void
137
  {
138 19
    $sql = sprintf('drop table `%s`.`%s`', $schemaName, $tableName);
139
140 19
    static::executeNone($sql);
141 19
  }
142
143
  //--------------------------------------------------------------------------------------------------------------------
144
  /**
145
   * Drops a trigger.
146
   *
147
   * @param string $triggerSchema The name of the trigger schema.
148
   * @param string $triggerName   The mame of trigger.
149
   */
150 10
  public static function dropTrigger(string $triggerSchema, string $triggerName): void
151
  {
152 10
    $sql = sprintf('drop trigger `%s`.`%s`', $triggerSchema, $triggerName);
153
154 10
    static::executeNone($sql);
155 10
  }
156
157
  //--------------------------------------------------------------------------------------------------------------------
158
  /**
159
   * @inheritdoc
160
   */
161
  public static function executeBulk(BulkHandler $bulkHandler, string $query): void
162
  {
163
    static::logQuery($query);
164
165
    parent::executeBulk($bulkHandler, $query);
166
  }
167
168
  //--------------------------------------------------------------------------------------------------------------------
169
  /**
170
   * @inheritdoc
171
   */
172
  public static function executeMulti(string $queries): array
173
  {
174
    static::logQuery($queries);
175
176
    return parent::executeMulti($queries);
177
  }
178
179
  //--------------------------------------------------------------------------------------------------------------------
180
  /**
181
   * @inheritdoc
182
   */
183 28
  public static function executeNone(string $query): int
184
  {
185 28
    static::logQuery($query);
186
187 28
    return parent::executeNone($query);
188
  }
189
190
  //--------------------------------------------------------------------------------------------------------------------
191
  /**
192
   * @inheritdoc
193
   */
194
  public static function executeRow0(string $query): ?array
195
  {
196
    static::logQuery($query);
197
198
    return parent::executeRow0($query);
199
  }
200
201
  //--------------------------------------------------------------------------------------------------------------------
202
  /**
203
   * @inheritdoc
204
   */
205 25
  public static function executeRow1(string $query): array
206
  {
207 25
    static::logQuery($query);
208
209 25
    return parent::executeRow1($query);
210
  }
211
212
  //--------------------------------------------------------------------------------------------------------------------
213
  /**
214
   * @inheritdoc
215
   */
216 29
  public static function executeRows(string $query): array
217
  {
218 29
    static::logQuery($query);
219
220 29
    return parent::executeRows($query);
221
  }
222
223
  //--------------------------------------------------------------------------------------------------------------------
224
  /**
225
   * @inheritdoc
226
   */
227
  public static function executeSingleton0(string $query)
228
  {
229
    static::logQuery($query);
230
231
    return parent::executeSingleton0($query);
232
  }
233
234
  //--------------------------------------------------------------------------------------------------------------------
235
  /**
236
   * @inheritdoc
237
   */
238
  public static function executeSingleton1(string $query)
239
  {
240
    static::logQuery($query);
241
242
    return parent::executeSingleton1($query);
243
  }
244
245
  //--------------------------------------------------------------------------------------------------------------------
246
  /**
247
   * @inheritdoc
248
   */
249
  public static function executeTable(string $query): int
250
  {
251
    static::logQuery($query);
252
253
    return parent::executeTable($query);
254
  }
255
256
  //--------------------------------------------------------------------------------------------------------------------
257
  /**
258
   * Selects metadata of all columns of table.
259
   *
260
   * @param string $schemaName The name of the table schema.
261
   * @param string $tableName  The name of the table.
262
   *
263
   * @return array[]
264
   */
265 28
  public static function getTableColumns(string $schemaName, string $tableName): array
266
  {
267
    // When a column has no default prior to MariaDB 10.2.7 column_default is null from MariaDB 10.2.7
268
    // column_default = 'NULL' (string(4)).
269 28
    $sql = sprintf("
270
select COLUMN_NAME                    as column_name
271
,      COLUMN_TYPE                    as column_type
272
,      ifnull(COLUMN_DEFAULT, 'NULL') as column_default 
273
,      IS_NULLABLE                    as is_nullable
274
,      CHARACTER_SET_NAME             as character_set_name
275
,      COLLATION_NAME                 as collation_name
276
from   information_schema.COLUMNS
277
where  TABLE_SCHEMA = %s
278
and    TABLE_NAME   = %s
279
order by ORDINAL_POSITION",
280 28
                   static::quoteString($schemaName),
281 28
                   static::quoteString($tableName));
282
283 28
    return static::executeRows($sql);
284
  }
285
286
  //--------------------------------------------------------------------------------------------------------------------
287
  /**
288
   * Selects table engine, character_set_name and table_collation.
289
   *
290
   * @param string $schemaName The name of the table schema.
291
   * @param string $tableName  The name of the table.
292
   *
293
   * @return array
294
   */
295 25
  public static function getTableOptions(string $schemaName, string $tableName): array
296
  {
297 25
    $sql = sprintf('
298
select t1.TABLE_SCHEMA       as table_schema
299
,      t1.TABLE_NAME         as table_name
300
,      t1.TABLE_COLLATION    as table_collation
301
,      t1.ENGINE             as engine
302
,      t2.CHARACTER_SET_NAME as character_set_name
303
from       information_schema.TABLES                                t1
304
inner join information_schema.COLLATION_CHARACTER_SET_APPLICABILITY t2  on  t2.COLLATION_NAME = t1.TABLE_COLLATION
305
where t1.TABLE_SCHEMA = %s
306
and   t1.TABLE_NAME   = %s',
307 25
                   static::quoteString($schemaName),
308 25
                   static::quoteString($tableName));
309
310 25
    return static::executeRow1($sql);
311
  }
312
313
  //--------------------------------------------------------------------------------------------------------------------
314
  /**
315
   * Selects all triggers on a table.
316
   *
317
   * @param string $schemaName The name of the table schema.
318
   * @param string $tableName  The name of the table.
319
   *
320
   * @return array[]
321
   */
322 28
  public static function getTableTriggers(string $schemaName, string $tableName): array
323
  {
324 28
    $sql = sprintf('
325
select TRIGGER_NAME as trigger_name
326
from   information_schema.TRIGGERS
327
where  TRIGGER_SCHEMA     = %s
328
and    EVENT_OBJECT_TABLE = %s
329
order by Trigger_Name',
330 28
                   static::quoteString($schemaName),
331 28
                   static::quoteString($tableName));
332
333 28
    return static::executeRows($sql);
334
  }
335
336
  //--------------------------------------------------------------------------------------------------------------------
337
  /**
338
   * Selects all table names in a schema.
339
   *
340
   * @param string $schemaName The name of the schema.
341
   *
342
   * @return array[]
343
   */
344 29
  public static function getTablesNames(string $schemaName): array
345
  {
346 29
    $sql = sprintf("
347
select TABLE_NAME as table_name
348
from   information_schema.TABLES
349
where  TABLE_SCHEMA = %s
350
and    TABLE_TYPE   = 'BASE TABLE'
351 29
order by TABLE_NAME", static::quoteString($schemaName));
352
353 29
    return static::executeRows($sql);
354
  }
355
356
  //--------------------------------------------------------------------------------------------------------------------
357
  /**
358
   * Selects all triggers in a schema
359
   *
360
   * @param string $schemaName The name of the table schema.
361
   *
362
   * @return array[]
363
   */
364
  public static function getTriggers(string $schemaName): array
365
  {
366
    $sql = sprintf('
367
select EVENT_OBJECT_TABLE as table_name
368
,      TRIGGER_NAME       as trigger_name
369
from   information_schema.TRIGGERS
370
where  TRIGGER_SCHEMA     = %s
371
order by EVENT_OBJECT_TABLE
372
,        TRIGGER_NAME',
373
                   static::quoteString($schemaName));
374
375
    return static::executeRows($sql);
376
  }
377
378
  //--------------------------------------------------------------------------------------------------------------------
379
  /**
380
   * Acquires a write lock on a table.
381
   *
382
   * @param string $schemaName The schema of the table.
383
   * @param string $tableName  The table name.
384
   */
385 28
  public static function lockTable(string $schemaName, string $tableName): void
386
  {
387 28
    $sql = sprintf('lock tables `%s`.`%s` write', $schemaName, $tableName);
388
389 28
    static::executeNone($sql);
390 28
  }
391
392
  //--------------------------------------------------------------------------------------------------------------------
393
  /**
394
   * Resolves the canonical column types of the additional audit columns.
395
   *
396
   * @param string  $auditSchema            The name of the audit schema.
397
   * @param array[] $additionalAuditColumns The metadata of the additional audit columns.
398
   *
399
   * @return TableColumnsMetadata
400
   */
401 29
  public static function resolveCanonicalAdditionalAuditColumns(string $auditSchema,
402
                                                                array $additionalAuditColumns): TableColumnsMetadata
403
  {
404 29
    if (empty($additionalAuditColumns))
405
    {
406 10
      return new TableColumnsMetadata([], 'AuditColumnMetadata');
407
    }
408
409 19
    $tableName = '_TMP_'.uniqid();
410 19
    static::createTemporaryTable($auditSchema, $tableName, $additionalAuditColumns);
411 19
    $columns = AuditDataLayer::getTableColumns($auditSchema, $tableName);
412 19
    static::dropTemporaryTable($auditSchema, $tableName);
413
414 19
    foreach ($additionalAuditColumns as $column)
415
    {
416 19
      $key = RowSetHelper::findInRowSet($columns, 'column_name', $column['column_name']);
417
418 19
      if (isset($column['value_type']))
419
      {
420 19
        $columns[$key]['value_type'] = $column['value_type'];
421
      }
422 19
      if (isset($column['expression']))
423
      {
424 19
        $columns[$key]['expression'] = $column['expression'];
425
      }
426
    }
427
428 19
    return new TableColumnsMetadata($columns, 'AuditColumnMetadata');
429
  }
430
431
  //--------------------------------------------------------------------------------------------------------------------
432
  /**
433
   * Sets the Output decorator.
434
   *
435
   * @param AuditStyle $io The Output decorator.
436
   */
437 29
  public static function setIo(AuditStyle $io)
438
  {
439 29
    self::$io = $io;
440 29
  }
441
442
  //--------------------------------------------------------------------------------------------------------------------
443
  /**
444
   * Releases all table locks.
445
   */
446 28
  public static function unlockTables(): void
447
  {
448 28
    $sql = 'unlock tables';
449
450 28
    static::executeNone($sql);
451 28
  }
452
453
  //--------------------------------------------------------------------------------------------------------------------
454
  /**
455
   * Logs the query on the console.
456
   *
457
   * @param string $query The query.
458
   */
459 29
  private static function logQuery(string $query): void
460
  {
461 29
    $query = trim($query);
462
463 29
    if (strpos($query, "\n")!==false)
464
    {
465
      // Query is a multi line query.
466 29
      self::$io->logVeryVerbose('Executing query:');
467 29
      self::$io->logVeryVerbose('<sql>%s</sql>', $query);
468
    }
469
    else
470
    {
471
      // Query is a single line query.
472 28
      self::$io->logVeryVerbose('Executing query: <sql>%s</sql>', $query);
473
    }
474 29
  }
475
476
  //--------------------------------------------------------------------------------------------------------------------
477
}
478
479
//----------------------------------------------------------------------------------------------------------------------
480