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

AuditDataLayer::showColumns()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 6
ccs 0
cts 3
cp 0
rs 9.4285
cc 1
eloc 3
nc 1
nop 2
crap 2
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
/**
15
 * Class for executing SQL statements and retrieving metadata from MySQL.
16
 */
17
class AuditDataLayer
18
{
19
  //--------------------------------------------------------------------------------------------------------------------
20
  /**
21
   * The connection to the MySQL instance.
22
   *
23
   * @var StaticDataLayer
24
   */
25
  private static $dl;
26
27
  /**
28
   * The Output decorator.
29
   *
30
   * @var StratumStyle
31
   */
32
  private static $io;
33
34
  //--------------------------------------------------------------------------------------------------------------------
35
  /**
36
   * Adds new columns to an audit table.
37
   *
38
   * @param string               $auditSchemaName The name of audit schema.
39
   * @param string               $tableName       The name of the table.
40
   * @param TableColumnsMetadata $columns         The metadata of the new columns.
41
   */
42 1
  public static function addNewColumns($auditSchemaName, $tableName, $columns)
43
  {
44 1
    $helper = new AlterAuditTableAddColumns($auditSchemaName, $tableName, $columns);
45 1
    $sql    = $helper->buildStatement();
46
47 1
    self::executeNone($sql);
48 1
  }
49
50
  //--------------------------------------------------------------------------------------------------------------------
51
  /**
52
   * Connects to a MySQL instance.
53
   *
54
   * Wrapper around [mysqli::__construct](http://php.net/manual/mysqli.construct.php), however on failure an exception
55
   * is thrown.
56
   *
57
   * @param string $host     The hostname.
58
   * @param string $user     The MySQL user name.
59
   * @param string $passWord The password.
60
   * @param string $database The default database.
61
   * @param int    $port     The port number.
62
   */
63 13
  public static function connect($host, $user, $passWord, $database, $port = 3306)
64
  {
65 13
    self::$dl = new StaticDataLayer();
66
67 13
    self::$dl->connect($host, $user, $passWord, $database, $port);
68 13
  }
69
70
  //--------------------------------------------------------------------------------------------------------------------
71
  /**
72
   * Creates an audit table.
73
   *
74
   * @param string               $dataSchemaName  The name of the data schema.
75
   * @param string               $auditSchemaName The name of the audit schema.
76
   * @param string               $tableName       The name of the table.
77
   * @param TableColumnsMetadata $columns         The metadata of the columns of the audit table (i.e. the audit
78
   *                                              columns and columns of the data table).
79
   */
80 9
  public static function createAuditTable($dataSchemaName, $auditSchemaName, $tableName, $columns)
81
  {
82 9
    $helper = new CreateAuditTable($dataSchemaName, $auditSchemaName, $tableName, $columns);
83 9
    $sql    = $helper->buildStatement();
84
85 9
    self::executeNone($sql);
86 9
  }
87
88
  //--------------------------------------------------------------------------------------------------------------------
89
  /**
90
   * Creates a trigger on a table.
91
   *
92
   * @param string               $dataSchemaName  The name of the data schema.
93
   * @param string               $auditSchemaName The name of the audit schema.
94
   * @param string               $tableName       The name of the table.
95
   * @param string               $triggerAction   The trigger action (i.e. INSERT, UPDATE, or DELETE).
96
   * @param string               $triggerName     The name of the trigger.
97
   * @param TableColumnsMetadata $auditColumns    The audit table columns.
98
   * @param TableColumnsMetadata $tableColumns    The data table columns.
99
   * @param string               $skipVariable    The skip variable.
100
   * @param string[]             $additionSql     Additional SQL statements.
101
   */
102 12
  public static function createAuditTrigger($dataSchemaName,
103
                                            $auditSchemaName,
104
                                            $tableName,
105
                                            $triggerAction,
106
                                            $triggerName,
107
                                            $auditColumns,
108
                                            $tableColumns,
109
                                            $skipVariable,
110
                                            $additionSql)
111
  {
112 12
    $helper = new CreateAuditTrigger($dataSchemaName,
113 12
                                     $auditSchemaName,
114 12
                                     $tableName,
115 12
                                     $triggerAction,
116 12
                                     $triggerName,
117 12
                                     $auditColumns,
118 12
                                     $tableColumns,
119 12
                                     $skipVariable,
120 12
                                     $additionSql);
121 12
    $sql    = $helper->buildStatement();
122
123 12
    self::executeNone($sql);
124 12
  }
125
126
  //--------------------------------------------------------------------------------------------------------------------
127
  /**
128
   * Create temp table for getting column type information for audit columns.
129
   *
130
   * @param string  $schemaName   The name of the table schema.
131
   * @param string  $tableName    The table name.
132
   * @param array[] $auditColumns Audit columns from config file.
133
   */
134 9
  public static function createTemporaryTable($schemaName, $tableName, $auditColumns)
135
  {
136 9
    $sql = new MySqlCompoundSyntaxCodeStore();
137 9
    $sql->append(sprintf('create table `%s`.`%s` (', $schemaName, $tableName));
138 9
    foreach ($auditColumns as $column)
139
    {
140 9
      $sql->append(sprintf('%s %s', $column['column_name'], $column['column_type']));
141 9
      if (end($auditColumns)!==$column)
142 9
      {
143 9
        $sql->appendToLastLine(',');
144 9
      }
145 9
    }
146 9
    $sql->append(')');
147
148 9
    self::executeNone($sql->getCode());
149 9
  }
150
151
  //--------------------------------------------------------------------------------------------------------------------
152
  /**
153
   * Closes the connection to the MySQL instance, if connected.
154
   */
155 13
  public static function disconnect()
156
  {
157 13
    if (self::$dl!==null)
158 13
    {
159 13
      self::$dl->disconnect();
160 13
      self::$dl = null;
161 13
    }
162 13
  }
163
164
  //--------------------------------------------------------------------------------------------------------------------
165
  /**
166
   * Drop table.
167
   *
168
   * @param string $schemaName The name of the table schema.
169
   * @param string $tableName  The name of the table.
170
   */
171 9
  public static function dropTemporaryTable($schemaName, $tableName)
172
  {
173 9
    $sql = sprintf('drop table `%s`.`%s`', $schemaName, $tableName);
174
175 9
    self::executeNone($sql);
176 9
  }
177
178
  //--------------------------------------------------------------------------------------------------------------------
179
  /**
180
   * Drops a trigger.
181
   *
182
   * @param string $triggerSchema The name of the trigger schema.
183
   * @param string $triggerName   The mame of trigger.
184
   */
185 6
  public static function dropTrigger($triggerSchema, $triggerName)
186
  {
187 6
    $sql = sprintf('drop trigger `%s`.`%s`', $triggerSchema, $triggerName);
188
189 6
    self::executeNone($sql);
190 6
  }
191
192
  //--------------------------------------------------------------------------------------------------------------------
193
  /**
194
   * @param string $query The SQL statement.
195
   *
196
   * @return int The number of affected rows (if any).
197
   */
198 12
  public static function executeNone($query)
199
  {
200 12
    self::logQuery($query);
201
202 12
    return self::$dl->executeNone($query);
203
  }
204
205
  //--------------------------------------------------------------------------------------------------------------------
206
  /**
207
   * Executes a query that returns 0 or 1 row.
208
   * Throws an exception if the query selects 2 or more rows.
209
   *
210
   * @param string $query The SQL statement.
211
   *
212
   * @return array|null The selected row.
213
   */
214
  public static function executeRow0($query)
215
  {
216
    self::logQuery($query);
217
218
    return self::$dl->executeRow0($query);
219
  }
220
221
  //--------------------------------------------------------------------------------------------------------------------
222
  /**
223
   * Executes a query that returns 1 and only 1 row.
224
   * Throws an exception if the query selects none, 2 or more rows.
225
   *
226
   * @param string $query The SQL statement.
227
   *
228
   * @return array The selected row.
229
   */
230 9
  public static function executeRow1($query)
231
  {
232 9
    self::logQuery($query);
233
234 9
    return self::$dl->executeRow1($query);
235
  }
236
237
  //--------------------------------------------------------------------------------------------------------------------
238
  /**
239
   * Executes a query that returns 0 or more rows.
240
   *
241
   * @param string $query The SQL statement.
242
   *
243
   * @return \array[]
244
   */
245 13
  public static function executeRows($query)
246
  {
247 13
    self::logQuery($query);
248
249 13
    return self::$dl->executeRows($query);
250
  }
251
252
  //--------------------------------------------------------------------------------------------------------------------
253
  /**
254
   * Executes a query that returns 0 or 1 row.
255
   * Throws an exception if the query selects 2 or more rows.
256
   *
257
   * @param string $query The SQL statement.
258
   *
259
   * @return int|string|null The selected row.
260
   */
261
  public static function executeSingleton0($query)
262
  {
263
    self::logQuery($query);
264
265
    return self::$dl->executeSingleton0($query);
266
  }
267
268
  //--------------------------------------------------------------------------------------------------------------------
269
  /**
270
   * Executes a query that returns 1 and only 1 row with 1 column.
271
   * Throws an exception if the query selects none, 2 or more rows.
272
   *
273
   * @param string $query The SQL statement.
274
   *
275
   * @return int|string The selected row.
276
   */
277
  public static function executeSingleton1($query)
278
  {
279
    self::logQuery($query);
280
281
    return self::$dl->executeSingleton1($query);
282
  }
283
284
  //--------------------------------------------------------------------------------------------------------------------
285
  /**
286
   * Selects metadata of all columns of table.
287
   *
288
   * @param string $schemaName The name of the table schema.
289
   * @param string $tableName  The name of the table.
290
   *
291
   * @return \array[]
292
   */
293 12 View Code Duplication
  public static function getTableColumns($schemaName, $tableName)
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
294
  {
295 12
    $sql = sprintf('
296
select COLUMN_NAME        as column_name
297
,      COLUMN_TYPE        as column_type
298
,      IS_NULLABLE        as is_nullable
299
,      CHARACTER_SET_NAME as character_set_name
300
,      COLLATION_NAME     as collation_name
301
from   information_schema.COLUMNS
302
where  TABLE_SCHEMA = %s
303
and    TABLE_NAME   = %s
304 12
order by ORDINAL_POSITION',
305 12
                   self::$dl->quoteString($schemaName),
306 12
                   self::$dl->quoteString($tableName));
307
308 12
    return self::executeRows($sql);
309
  }
310
311
  //--------------------------------------------------------------------------------------------------------------------
312
  /**
313
   * Selects table engine, character_set_name and table_collation.
314
   *
315
   * @param string $schemaName The name of the table schema.
316
   * @param string $tableName  The name of the table.
317
   *
318
   * @return array
319
   */
320 9 View Code Duplication
  public static function getTableOptions($schemaName, $tableName)
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
321
  {
322 9
    $sql = sprintf('
323
SELECT t1.TABLE_COLLATION    as table_collation
324
,      t1.ENGINE             as engine
325
,      t2.CHARACTER_SET_NAME as character_set_name
326
FROM       information_schema.TABLES                                t1
327
inner join information_schema.COLLATION_CHARACTER_SET_APPLICABILITY t2  on  t2.COLLATION_NAME = t1.TABLE_COLLATION
328
WHERE t1.TABLE_SCHEMA = %s
329 9
AND   t1.TABLE_NAME   = %s',
330 9
                   self::$dl->quoteString($schemaName),
331 9
                   self::$dl->quoteString($tableName));
332
333 9
    return self::executeRow1($sql);
334
  }
335
336
  //--------------------------------------------------------------------------------------------------------------------
337
  /**
338
   * Selects all triggers on a table.
339
   *
340
   * @param string $schemaName The name of the table schema.
341
   * @param string $tableName  The name of the table.
342
   *
343
   * @return \array[]
344
   */
345 12 View Code Duplication
  public static function getTableTriggers($schemaName, $tableName)
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
346
  {
347 12
    $sql = sprintf('
348
select TRIGGER_NAME as trigger_name
349
from   information_schema.TRIGGERS
350
where  TRIGGER_SCHEMA     = %s
351
and    EVENT_OBJECT_TABLE = %s
352 12
order by Trigger_Name',
353 12
                   self::$dl->quoteString($schemaName),
354 12
                   self::$dl->quoteString($tableName));
355
356 12
    return self::executeRows($sql);
357
  }
358
359
  //--------------------------------------------------------------------------------------------------------------------
360
  /**
361
   * Selects all table names in a schema.
362
   *
363
   * @param string $schemaName The name of the schema.
364
   *
365
   * @return \array[]
366
   */
367 13
  public static function getTablesNames($schemaName)
368
  {
369 13
    $sql = sprintf("
370
select TABLE_NAME as table_name
371
from   information_schema.TABLES
372
where  TABLE_SCHEMA = %s
373
and    TABLE_TYPE   = 'BASE TABLE'
374 13
order by TABLE_NAME", self::$dl->quoteString($schemaName));
375
376 13
    return self::executeRows($sql);
377
  }
378
379
  //--------------------------------------------------------------------------------------------------------------------
380
  /**
381
   * Selects all triggers in a schema
382
   *
383
   * @param string $schemaName The name of the table schema.
384
   *
385
   * @return \array[]
386
   */
387
  public static function getTriggers($schemaName)
388
  {
389
    $sql = sprintf('
390
select EVENT_OBJECT_TABLE as table_name
391
,      TRIGGER_NAME       as trigger_name
392
from   information_schema.TRIGGERS
393
where  TRIGGER_SCHEMA     = %s
394
order by EVENT_OBJECT_TABLE
395
,        TRIGGER_NAME',
396
                   self::$dl->quoteString($schemaName));
397
398
    return self::executeRows($sql);
399
  }
400
401
  //--------------------------------------------------------------------------------------------------------------------
402
  /**
403
   * Acquires a write lock on a table.
404
   *
405
   * @param string $tableName The table name.
406
   */
407 12
  public static function lockTable($tableName)
408
  {
409 12
    $sql = sprintf('lock tables `%s` write', $tableName);
410
411 12
    self::executeNone($sql);
412 12
  }
413
414
  //--------------------------------------------------------------------------------------------------------------------
415
  /**
416
   * Sets the Output decorator.
417
   *
418
   * @param StratumStyle $io The Output decorator.
419
   */
420 13
  public static function setIo($io)
421
  {
422 13
    self::$io = $io;
423 13
  }
424
425
  //--------------------------------------------------------------------------------------------------------------------
426
  /**
427
   * Drop table.
428
   *
429
   * @param string $schemaName The name of the table schema.
430
   * @param string $tableName  The name of the table.
431
   *
432
   * @return \array[]
433
   */
434
  public static function showColumns($schemaName, $tableName)
435
  {
436
    $sql = sprintf('SHOW COLUMNS FROM `%s`.`%s`', $schemaName, $tableName);
437
438
    return self::executeRows($sql);
439
  }
440
441
  //--------------------------------------------------------------------------------------------------------------------
442
  /**
443
   * Releases all table locks.
444
   */
445 12
  public static function unlockTables()
446
  {
447 12
    $sql = 'unlock tables';
448
449 12
    self::executeNone($sql);
450 12
  }
451
452
  //--------------------------------------------------------------------------------------------------------------------
453
  /**
454
   * Logs the query on the console.
455
   *
456
   * @param string $query The query.
457
   */
458 13
  private static function logQuery($query)
459
  {
460 13
    $query = trim($query);
461
462 13
    if (strpos($query, "\n")!==false)
463 13
    {
464
      // Query is a multi line query.
465 13
      self::$io->logVeryVerbose('Executing query:');
466 13
      self::$io->logVeryVerbose('<sql>%s</sql>', $query);
467 13
    }
468
    else
469
    {
470
      // Query is a single line query.
471 12
      self::$io->logVeryVerbose('Executing query: <sql>%s</sql>', $query);
472
    }
473 13
  }
474
475
  //--------------------------------------------------------------------------------------------------------------------
476
}
477
478
//----------------------------------------------------------------------------------------------------------------------
479