ILIAS  release_6 Revision v6.24-5-g0c8bfefb3b8
All Data Structures Namespaces Files Functions Variables Modules Pages
class.ilDBPdoManager.php
Go to the documentation of this file.
1 <?php
2 
9 {
10 
14  protected $pdo;
18  protected $db_instance;
19 
20 
27  public function __construct(\PDO $pdo, ilDBPdo $db_instance)
28  {
29  $this->pdo = $pdo;
30  $this->db_instance = $db_instance;
31  }
32 
33 
37  protected $query_utils;
38 
39 
43  public function getQueryUtils()
44  {
45  if (!$this->query_utils) {
46  $this->query_utils = new ilMySQLQueryUtils($this->db_instance);
47  }
48 
49  return $this->query_utils;
50  }
51 
52 
56  public function getDBInstance()
57  {
58  return $this->db_instance;
59  }
60 
61 
66  public function listTables($database = null)
67  {
68  $str = 'SHOW TABLES ' . ($database ? ' IN ' . $database : '');
69  $r = $this->pdo->query($str);
70  $tables = array();
71 
72  $sequence_identifier = "_seq";
73  while ($data = $r->fetchColumn()) {
74  if (!preg_match("/{$sequence_identifier}$/um", $data)) {
75  $tables[] = $data;
76  }
77  }
78 
79  return $tables;
80  }
81 
82 
88  protected function fixSequenceName($sqn, $check = false)
89  {
90  $seq_pattern = '/^' . preg_replace('/%s/', '([a-z0-9_]+)', ilDBConstants::SEQUENCE_FORMAT) . '$/i';
91  $seq_name = preg_replace($seq_pattern, '\\1', $sqn);
92  if ($seq_name && !strcasecmp($sqn, $this->db_instance->getSequenceName($seq_name))) {
93  return $seq_name;
94  }
95  if ($check) {
96  return false;
97  }
98 
99  return $sqn;
100  }
101 
102 
107  public function listSequences($database = null)
108  {
109  $query = "SHOW TABLES";
110  if (!is_null($database)) {
111  $query .= " FROM $database";
112  }
113 
114  $res = $this->db_instance->query($query);
115 
116  $result = array();
117  while ($table_name = $this->db_instance->fetchAssoc($res)) {
118  if ($sqn = $this->fixSequenceName(reset($table_name), true)) {
119  $result[] = $sqn;
120  }
121  }
122  if ($this->db_instance->options['portability'] ?? null) {
123  $result = array_map(($this->db_instance->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $result);
124  }
125 
126  return $result;
127  }
128 
129 
137  public function createConstraint($table, $name, $definition)
138  {
139  $db = $this->db_instance;
140 
141  $table = $db->quoteIdentifier($table, true);
142  $name = $db->quoteIdentifier($db->getIndexName($name), true);
143  $query = "ALTER TABLE $table ADD CONSTRAINT $name";
144  if (!empty($definition['primary'])) {
145  $query .= ' PRIMARY KEY';
146  } elseif (!empty($definition['unique'])) {
147  $query .= ' UNIQUE';
148  }
149  $fields = array();
150  foreach (array_keys($definition['fields']) as $field) {
151  $fields[] = $db->quoteIdentifier($field, true);
152  }
153  $query .= ' (' . implode(', ', $fields) . ')';
154 
155  return $this->pdo->exec($query);
156  }
157 
158 
165  public function createSequence($seq_name, $start = 1, $options = array())
166  {
167  $sequence_name = $this->db_instance->quoteIdentifier($this->db_instance->getSequenceName($seq_name));
168  $seqcol_name = $this->db_instance->quoteIdentifier(ilDBConstants::SEQUENCE_COLUMNS_NAME);
169 
170  $options_strings = array();
171 
172  if (!empty($options['comment'])) {
173  $options_strings['comment'] = 'COMMENT = ' . $this->db_instance->quote($options['comment'], 'text');
174  }
175 
176  if (!empty($options['charset'])) {
177  $options_strings['charset'] = 'DEFAULT CHARACTER SET ' . $options['charset'];
178  if (!empty($options['collate'])) {
179  $options_strings['charset'] .= ' COLLATE ' . $options['collate'];
180  }
181  }
182 
183  $type = false;
184  if (!empty($options['type'])) {
185  $type = $options['type'];
186  }
187  if ($type) {
188  $options_strings[] = "ENGINE = $type";
189  }
190 
191  $query = "CREATE TABLE $sequence_name ($seqcol_name INT NOT NULL AUTO_INCREMENT, PRIMARY KEY ($seqcol_name))";
192 
193  if (!empty($options_strings)) {
194  $query .= ' ' . implode(' ', $options_strings);
195  }
196  $this->pdo->exec($query);
197 
198  if ($start == 1) {
199  return true;
200  }
201 
202  $query = "INSERT INTO $sequence_name ($seqcol_name) VALUES (" . ($start - 1) . ')';
203  $this->pdo->exec($query);
204 
205  return true;
206  }
207 
208 
216  public function alterTable($name, $changes, $check)
217  {
218  $db = $this->db_instance;
219 
220  foreach ($changes as $change_name => $change) {
221  switch ($change_name) {
222  case 'add':
223  case 'remove':
224  case 'change':
225  case 'rename':
226  case 'name':
227  break;
228  default:
229  throw new ilDatabaseException('change type "' . $change_name . '" not yet supported');
230  }
231  }
232 
233  if ($check) {
234  return true;
235  }
236 
237  $query = '';
238  if (!empty($changes['name'])) {
239  $change_name = $db->quoteIdentifier($changes['name']);
240  $query .= 'RENAME TO ' . $change_name;
241  }
242 
243  if (!empty($changes['add']) && is_array($changes['add'])) {
244  foreach ($changes['add'] as $field_name => $field) {
245  if ($query) {
246  $query .= ', ';
247  }
248  $query .= 'ADD ' . $db->getFieldDefinition()->getDeclaration($field['type'], $field_name, $field);
249  }
250  }
251 
252  if (!empty($changes['remove']) && is_array($changes['remove'])) {
253  foreach ($changes['remove'] as $field_name => $field) {
254  if ($query) {
255  $query .= ', ';
256  }
257  $field_name = $db->quoteIdentifier($field_name);
258  $query .= 'DROP ' . $field_name;
259  }
260  }
261 
262  $rename = array();
263  if (!empty($changes['rename']) && is_array($changes['rename'])) {
264  foreach ($changes['rename'] as $field_name => $field) {
265  $rename[$field['name']] = $field_name;
266  }
267  }
268 
269  if (!empty($changes['change']) && is_array($changes['change'])) {
270  foreach ($changes['change'] as $field_name => $field) {
271  if ($query) {
272  $query .= ', ';
273  }
274  if (isset($rename[$field_name])) {
275  $old_field_name = $rename[$field_name];
276  unset($rename[$field_name]);
277  } else {
278  $old_field_name = $field_name;
279  }
280  $old_field_name = $db->quoteIdentifier($old_field_name);
281  $query .= "CHANGE $old_field_name " . $this->db_instance->getFieldDefinition()
282  ->getDeclaration($field['definition']['type'], $field_name, $field['definition']);
283  }
284  }
285 
286  if (!empty($rename) && is_array($rename)) {
287  foreach ($rename as $rename_name => $renamed_field) {
288  if ($query) {
289  $query .= ', ';
290  }
291  $field = $changes['rename'][$renamed_field];
292  $renamed_field = $db->quoteIdentifier($renamed_field);
293  $query .= 'CHANGE ' . $renamed_field . ' ' . $this->db_instance->getFieldDefinition()
294  ->getDeclaration($field['definition']['type'], $field['name'], $field['definition']);
295  }
296  }
297 
298  if (!$query) {
299  return true;
300  }
301 
302  $name = $db->quoteIdentifier($name, true);
303 
304  $statement = "ALTER TABLE $name $query";
305 
306  return $this->pdo->exec($statement);
307  }
308 
309 
316  public function createTable($name, $fields, $options = array())
317  {
318  $options['type'] = $this->db_instance->getStorageEngine();
319 
320  return $this->pdo->exec($this->getQueryUtils()->createTable($name, $fields, $options));
321  }
322 
323 
324 
325 
326 
327  //
328  // ilDBPdoManagerInterface
329  //
334  public function getIndexName($idx)
335  {
336  return $this->db_instance->getIndexName($idx);
337  }
338 
339 
344  public function getSequenceName($sqn)
345  {
346  return $this->db_instance->getSequenceName($sqn);
347  }
348 
349 
355  public function listTableFields($table)
356  {
357  $table = $this->db_instance->quoteIdentifier($table);
358  $query = "SHOW COLUMNS FROM $table";
359  $result = $this->db_instance->query($query);
360  $return = array();
361  while ($data = $this->db_instance->fetchObject($result)) {
362  $return[] = $data->Field;
363  }
364 
365  return $return;
366  }
367 
368 
374  public function listTableConstraints($table)
375  {
376  $key_name = 'Key_name';
377  $non_unique = 'Non_unique';
378 
379  $db = $this->getDBInstance();
380  if ($db->options['portability']) {
381  if ($db->options['field_case'] == CASE_LOWER) {
382  $key_name = strtolower($key_name);
383  $non_unique = strtolower($non_unique);
384  } else {
385  $key_name = strtoupper($key_name);
386  $non_unique = strtoupper($non_unique);
387  }
388  }
389 
390  $table = $this->db_instance->quoteIdentifier($table);
391  $query = "SHOW INDEX FROM $table";
392  $result_set = $this->db_instance->query($query);
393 
394  $result = array();
395  while ($index_data = $this->db_instance->fetchAssoc($result_set)) {
396  if (!$index_data[$non_unique]) {
397  if ($index_data[$key_name] !== 'PRIMARY') {
398  $index = $this->fixIndexName($index_data[$key_name]);
399  } else {
400  $index = 'PRIMARY';
401  }
402  if (!empty($index)) {
403  $index = strtolower($index);
404  $result[$index] = true;
405  }
406  }
407  }
408 
409  if ($this->db_instance->options['portability']) {
410  $result = array_change_key_case($result, $this->db_instance->options['field_case']);
411  }
412 
413  return array_keys($result);
414  }
415 
416 
422  public function listTableIndexes($table)
423  {
424  $key_name = 'Key_name';
425  $non_unique = 'Non_unique';
426  if ($this->db_instance->options['portability'] ?? null) {
427  if ($this->db_instance->options['field_case'] == CASE_LOWER) {
428  $key_name = strtolower($key_name);
429  $non_unique = strtolower($non_unique);
430  } else {
431  $key_name = strtoupper($key_name);
432  $non_unique = strtoupper($non_unique);
433  }
434  }
435 
436  $table = $this->db_instance->quoteIdentifier($table);
437  $query = "SHOW INDEX FROM $table";
438  $result_set = $this->db_instance->query($query);
439  $indexes = array();
440  while ($index_data = $this->db_instance->fetchAssoc($result_set)) {
441  $indexes[] = $index_data;
442  }
443  $result = array();
444  foreach ($indexes as $index_data) {
445  if ($index_data[$non_unique] && ($index = $this->fixIndexName($index_data[$key_name]))) {
446  $result[$index] = true;
447  }
448  }
449 
450  if ($this->db_instance->options['portability'] ?? null) {
451  $result = array_change_key_case($result, $this->db_instance->options['field_case']);
452  }
453 
454  return array_keys($result);
455  }
456 
457 
462  protected function fixIndexName($idx)
463  {
464  $idx_pattern = '/^' . preg_replace('/%s/', '([a-z0-9_]+)', ilDBPdoFieldDefinition::INDEX_FORMAT) . '$/i';
465  $idx_name = preg_replace($idx_pattern, '\\1', $idx);
466  if ($idx_name && !strcasecmp($idx, $this->db_instance->getIndexName($idx_name))) {
467  return $idx_name;
468  }
469 
470  return $idx;
471  }
472 
473 
480  public function createIndex($table, $name, $definition)
481  {
482  $table = $this->db_instance->quoteIdentifier($table, true);
483  $name = $this->db_instance->quoteIdentifier($this->db_instance->getIndexName($name), true);
484  $query = "CREATE INDEX $name ON $table";
485  $fields = array();
486  foreach ($definition['fields'] as $field => $fieldinfo) {
487  if (!empty($fieldinfo['length'])) {
488  $fields[] = $this->db_instance->quoteIdentifier($field, true) . '(' . $fieldinfo['length'] . ')';
489  } else {
490  $fields[] = $this->db_instance->quoteIdentifier($field, true);
491  }
492  }
493  $query .= ' (' . implode(', ', $fields) . ')';
494 
495  return $this->pdo->exec($query);
496  }
497 
498 
504  public function dropIndex($table, $name)
505  {
506  $table = $this->db_instance->quoteIdentifier($table, true);
507  $name = $this->db_instance->quoteIdentifier($this->db_instance->getIndexName($name), true);
508 
509  return $this->pdo->exec("DROP INDEX $name ON $table");
510  }
511 
512 
517  public function dropSequence($table_name)
518  {
519  $sequence_name = $this->db_instance->quoteIdentifier($this->db_instance->getSequenceName($table_name));
520 
521  return $this->pdo->exec("DROP TABLE $sequence_name");
522  }
523 
524 
532  public function getTableCreationQuery($name, $fields, $options = array())
533  {
534  return $this->getQueryUtils()->createTable($name, $fields, $options);
535  }
536 
537 
544  public function dropConstraint($table, $name, $primary = false)
545  {
546  $db = $this->getDBInstance();
547  $table = $db->quoteIdentifier($table, true);
548  if ($primary || strtolower($name) == 'primary') {
549  $query = "ALTER TABLE $table DROP PRIMARY KEY";
550  } else {
551  $name = $db->quoteIdentifier($db->getIndexName($name), true);
552  $query = "ALTER TABLE $table DROP INDEX $name";
553  }
554 
555  return $this->pdo->exec($query);
556  }
557 
558 
562  public function dropTable($name)
563  {
564  $db = $this->getDBInstance();
565 
566  $name = $db->quoteIdentifier($name, true);
567 
568  return $db->manipulate("DROP TABLE $name");
569  }
570 }
alterTable($name, $changes, $check)
listTables($database=null)
listSequences($database=null)
$data
Definition: storeScorm.php:23
$result
Interface ilDBManager.
$type
fixSequenceName($sqn, $check=false)
dropTable($name)
Table-name mixed
dropSequence($table_name)
getTableCreationQuery($name, $fields, $options=array())
Interface ilDBPdoManagerInterface.
Class ilDatabaseException.
createConstraint($table, $name, $definition)
createTable($name, $fields, $options=array())
$index
Definition: metadata.php:128
Class pdoDB.
if($format !==null) $name
Definition: metadata.php:230
foreach($_POST as $key=> $value) $res
dropConstraint($table, $name, $primary=false)
$query
createIndex($table, $name, $definition)
Class ilMySQLQueryUtils.
__construct(\PDO $pdo, ilDBPdo $db_instance)
ilDBPdoManager constructor.
Class ilDBPdoManager.
dropIndex($table, $name)
createSequence($seq_name, $start=1, $options=array())