Completed
Branch master (0ecb66)
by P.R.
04:50
created

AuditDataLayer::executeNone()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

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