Completed
Pull Request — master (#30)
by
unknown
02:31
created

DataLayer::dropTable()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 6
rs 9.4285
cc 1
eloc 3
nc 1
nop 2
1
<?php
2
//----------------------------------------------------------------------------------------------------------------------
3
namespace SetBased\Audit\MySql;
4
5
use SetBased\Audit\Columns;
6
use SetBased\Audit\MySql\Helper\CompoundSyntaxStore;
7
use SetBased\Audit\MySql\Sql\AlterAuditTableAddColumns;
8
use SetBased\Audit\MySql\Sql\CreateAuditTable;
9
use SetBased\Audit\MySql\Sql\CreateAuditTrigger;
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 DataLayer
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 Columns $columns         The metadata of the new columns.
41
   */
42
  public static function addNewColumns($auditSchemaName, $tableName, $columns)
43
  {
44
    $helper = new AlterAuditTableAddColumns($auditSchemaName, $tableName, $columns);
45
    $sql    = $helper->buildStatement();
46
47
    self::executeNone($sql);
48
  }
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
  public static function connect($host, $user, $passWord, $database, $port = 3306)
64
  {
65
    self::$dl = new StaticDataLayer();
66
67
    self::$dl->connect($host, $user, $passWord, $database, $port);
68
  }
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 Columns $columns         The metadata of the columns of the audit table (i.e. the audit columns and columns
78
   *                                 of the data table).
79
   */
80
  public static function createAuditTable($dataSchemaName, $auditSchemaName, $tableName, $columns)
81
  {
82
    $helper = new CreateAuditTable($dataSchemaName, $auditSchemaName, $tableName, $columns);
83
    $sql    = $helper->buildStatement();
84
85
    self::executeNone($sql);
86
  }
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 Columns  $tableColumns    The data table columns.
98
   * @param Columns  $auditColumns    The audit table columns.
99
   * @param string   $skipVariable    The skip variable.
100
   * @param string[] $additionSql     Additional SQL statements.
101
   */
102
  public static function createAuditTrigger($dataSchemaName,
103
                                            $auditSchemaName,
104
                                            $tableName,
105
                                            $triggerAction,
106
                                            $triggerName,
107
                                            $tableColumns,
108
                                            $auditColumns,
109
                                            $skipVariable,
110
                                            $additionSql)
111
  {
112
    $helper = new CreateAuditTrigger($dataSchemaName,
113
                                     $auditSchemaName,
114
                                     $tableName,
115
                                     $triggerAction,
116
                                     $triggerName,
117
                                     $tableColumns,
118
                                     $auditColumns,
119
                                     $skipVariable,
120
                                     $additionSql);
121
    $sql    = $helper->buildStatement();
122
123
    self::executeNone($sql);
124
  }
125
126
  //--------------------------------------------------------------------------------------------------------------------
127
  /**
128
   * Closes the connection to the MySQL instance, if connected.
129
   */
130
  public static function disconnect()
131
  {
132
    if (self::$dl!==null)
133
    {
134
      self::$dl->disconnect();
135
      self::$dl = null;
136
    }
137
  }
138
139
  //--------------------------------------------------------------------------------------------------------------------
140
  /**
141
   * Drops a trigger.
142
   *
143
   * @param string $triggerSchema The name of the trigger schema.
144
   * @param string $triggerName   The mame of trigger.
145
   */
146
  public static function dropTrigger($triggerSchema, $triggerName)
147
  {
148
    $sql = sprintf('drop trigger `%s`.`%s`', $triggerSchema, $triggerName);
149
150
    self::executeNone($sql);
151
  }
152
153
  //--------------------------------------------------------------------------------------------------------------------
154
  /**
155
   * @param string $query The SQL statement.
156
   *
157
   * @return int The number of affected rows (if any).
158
   */
159
  public static function executeNone($query)
160
  {
161
    self::logQuery($query);
162
163
    return self::$dl->executeNone($query);
164
  }
165
166
  //--------------------------------------------------------------------------------------------------------------------
167
  /**
168
   * Executes a query that returns 0 or 1 row.
169
   * Throws an exception if the query selects 2 or more rows.
170
   *
171
   * @param string $query The SQL statement.
172
   *
173
   * @return array|null The selected row.
174
   */
175
  public static function executeRow0($query)
176
  {
177
    self::logQuery($query);
178
179
    return self::$dl->executeRow0($query);
180
  }
181
182
  //--------------------------------------------------------------------------------------------------------------------
183
  /**
184
   * Executes a query that returns 1 and only 1 row.
185
   * Throws an exception if the query selects none, 2 or more rows.
186
   *
187
   * @param string $query The SQL statement.
188
   *
189
   * @return array The selected row.
190
   */
191
  public static function executeRow1($query)
192
  {
193
    self::logQuery($query);
194
195
    return self::$dl->executeRow1($query);
196
  }
197
198
  //--------------------------------------------------------------------------------------------------------------------
199
  /**
200
   * Executes a query that returns 0 or more rows.
201
   *
202
   * @param string $query The SQL statement.
203
   *
204
   * @return \array[]
205
   */
206
  public static function executeRows($query)
207
  {
208
    self::logQuery($query);
209
210
    return self::$dl->executeRows($query);
211
  }
212
213
  //--------------------------------------------------------------------------------------------------------------------
214
  /**
215
   * Executes a query that returns 0 or 1 row.
216
   * Throws an exception if the query selects 2 or more rows.
217
   *
218
   * @param string $query The SQL statement.
219
   *
220
   * @return int|string|null The selected row.
221
   */
222
  public static function executeSingleton0($query)
223
  {
224
    self::logQuery($query);
225
226
    return self::$dl->executeSingleton0($query);
227
  }
228
229
  //--------------------------------------------------------------------------------------------------------------------
230
  /**
231
   * Executes a query that returns 1 and only 1 row with 1 column.
232
   * Throws an exception if the query selects none, 2 or more rows.
233
   *
234
   * @param string $query The SQL statement.
235
   *
236
   * @return int|string The selected row.
237
   */
238
  public static function executeSingleton1($query)
239
  {
240
    self::logQuery($query);
241
242
    return self::$dl->executeSingleton1($query);
243
  }
244
245
  //--------------------------------------------------------------------------------------------------------------------
246
  /**
247
   * Selects metadata of all columns of table.
248
   *
249
   * @param string $schemaName The name of the table schema.
250
   * @param string $tableName  The name of the table.
251
   *
252
   * @return \array[]
253
   */
254 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...
255
  {
256
    $sql = sprintf('
257
select COLUMN_NAME        as column_name
258
,      COLUMN_TYPE        as column_type
259
,      IS_NULLABLE        as is_nullable
260
,      CHARACTER_SET_NAME as character_set_name
261
,      COLLATION_NAME     as collation_name
262
from   information_schema.COLUMNS
263
where  TABLE_SCHEMA = %s
264
and    TABLE_NAME   = %s
265
order by ORDINAL_POSITION',
266
                   self::$dl->quoteString($schemaName),
267
                   self::$dl->quoteString($tableName));
268
269
    return self::$dl->executeRows($sql);
270
  }
271
272
  //--------------------------------------------------------------------------------------------------------------------
273
  /**
274
   * Selects table engine, character_set_name and table_collation.
275
   *
276
   * @param string $schemaName The name of the table schema.
277
   * @param string $tableName  The name of the table.
278
   *
279
   * @return array
280
   */
281 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...
282
  {
283
    $sql = sprintf('
284
SELECT 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
                   self::$dl->quoteString($schemaName),
292
                   self::$dl->quoteString($tableName));
293
294
    return self::$dl->executeRow1($sql);
295
  }
296
297
  //--------------------------------------------------------------------------------------------------------------------
298
  /**
299
   * Create temp table for getting column type information for audit columns.
300
   *
301
   * @param string  $schemaName   The name of the table schema.
302
   * @param array[] $auditColumns Audit columns from config file.
303
   *
304
   * @return int
305
   */
306
  public static function createTempTable($schemaName, $auditColumns)
307
  {
308
    $sql = new CompoundSyntaxStore();
309
    $sql->append(sprintf('CREATE TABLE %s.temp (', $schemaName));
310 View Code Duplication
    foreach ($auditColumns as $column)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
311
    {
312
      $sql->append(sprintf('%s %s', $column['column_name'], $column['column_type']));
313
      if (end($auditColumns)!==$column)
314
      {
315
        $sql->appendToLastLine(',');
316
      }
317
    }
318
    $sql->append(')');
319
320
    return self::$dl->executeNone($sql->getCode());
321
  }
322
323
  //--------------------------------------------------------------------------------------------------------------------
324
  /**
325
   * Drop table.
326
   *
327
   * @param string $schemaName The name of the table schema.
328
   * @param string $tableName  The name of the table.
329
   *
330
   * @return int
331
   */
332
  public static function dropTable($schemaName, $tableName)
333
  {
334
    $sql = sprintf('drop table %s.%s', $schemaName, $tableName);
335
336
    return self::$dl->executeNone($sql);
337
  }
338
339
  //--------------------------------------------------------------------------------------------------------------------
340
  /**
341
   * Selects all triggers on a table.
342
   *
343
   * @param string $schemaName The name of the table schema.
344
   * @param string $tableName  The name of the table.
345
   *
346
   * @return \array[]
347
   */
348 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...
349
  {
350
    $sql = sprintf('
351
select Trigger_Name as trigger_name
352
from   information_schema.TRIGGERS
353
where  TRIGGER_SCHEMA     = %s
354
and    EVENT_OBJECT_TABLE = %s
355
order by Trigger_Name',
356
                   self::$dl->quoteString($schemaName),
357
                   self::$dl->quoteString($tableName));
358
359
    return self::$dl->executeRows($sql);
360
  }
361
362
  //--------------------------------------------------------------------------------------------------------------------
363
  /**
364
   * Selects all table names in a schema.
365
   *
366
   * @param string $schemaName The name of the schema.
367
   *
368
   * @return \array[]
369
   */
370
  public static function getTablesNames($schemaName)
371
  {
372
    $sql = sprintf("
373
select TABLE_NAME as table_name
374
from   information_schema.TABLES
375
where  TABLE_SCHEMA = %s
376
and    TABLE_TYPE   = 'BASE TABLE'
377
order by TABLE_NAME", self::$dl->quoteString($schemaName));
378
379
    return self::$dl->executeRows($sql);
380
  }
381
382
  //--------------------------------------------------------------------------------------------------------------------
383
  /**
384
   * Acquires a write lock on a table.
385
   *
386
   * @param string $tableName The table name.
387
   */
388
  public static function lockTable($tableName)
389
  {
390
    $sql = sprintf('lock tables `%s` write', $tableName);
391
392
    self::$dl->executeNone($sql);
393
  }
394
395
  //--------------------------------------------------------------------------------------------------------------------
396
  /**
397
   * Sets the Output decorator.
398
   *
399
   * @param StratumStyle $io The Output decorator.
400
   */
401
  public static function setIo($io)
402
  {
403
    self::$io = $io;
404
  }
405
406
  //--------------------------------------------------------------------------------------------------------------------
407
  /**
408
   * Releases all table locks.
409
   */
410
  public static function unlockTables()
411
  {
412
    $sql = 'unlock tables';
413
414
    self::$dl->executeNone($sql);
415
  }
416
417
  //--------------------------------------------------------------------------------------------------------------------
418
  /**
419
   * Logs the query on the console.
420
   *
421
   * @param string $query The query.
422
   */
423
  private static function logQuery($query)
424
  {
425
    $query = trim($query);
426
427
    if (strpos($query, "\n")!==false)
428
    {
429
      // Query is a multi line query.
430
      self::$io->logVeryVerbose('Executing query:');
431
      self::$io->logVeryVerbose('<sql>%s</sql>', $query);
432
    }
433
    else
434
    {
435
      // Query is a single line query.
436
      self::$io->logVeryVerbose('Executing query: <sql>%s</sql>', $query);
437
    }
438
  }
439
440
  //--------------------------------------------------------------------------------------------------------------------
441
}
442
443
//----------------------------------------------------------------------------------------------------------------------
444