ILIAS  release_6 Revision v6.24-5-g0c8bfefb3b8
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}
$result
An exception for terminatinating execution or to throw for unit testing.
Class ilDBPdoManager.
fixSequenceName($sqn, $check=false)
listTables($database=null)
createTable($name, $fields, $options=array())
__construct(\PDO $pdo, ilDBPdo $db_instance)
ilDBPdoManager constructor.
createConstraint($table, $name, $definition)
getTableCreationQuery($name, $fields, $options=array())
alterTable($name, $changes, $check)
dropSequence($table_name)
dropConstraint($table, $name, $primary=false)
dropIndex($table, $name)
listSequences($database=null)
createSequence($seq_name, $start=1, $options=array())
createIndex($table, $name, $definition)
Class pdoDB.
Class ilDatabaseException.
Class ilMySQLQueryUtils.
Interface ilDBManager.
Interface ilDBPdoManagerInterface.
if($format !==null) $name
Definition: metadata.php:230
$index
Definition: metadata.php:128
$query
$type
foreach($_POST as $key=> $value) $res
$data
Definition: storeScorm.php:23