ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
class.ilDBPdoManager.php
Go to the documentation of this file.
1<?php
2require_once('./Services/Database/interfaces/interface.ilDBManager.php');
3
10
14 protected $pdo;
18 protected $db_instance;
19
20
27 public function __construct(\PDO $pdo, ilDBPdo $db_instance) {
28 $this->pdo = $pdo;
29 $this->db_instance = $db_instance;
30 }
31
32
36 protected $query_utils;
37
38
42 public function getQueryUtils() {
43 if (!$this->query_utils) {
44 $this->query_utils = new ilMySQLQueryUtils($this->db_instance);
45 }
46
47 return $this->query_utils;
48 }
49
50
54 public function getDBInstance() {
55 return $this->db_instance;
56 }
57
58
63 public function listTables($database = null) {
64 $str = 'SHOW TABLES ' . ($database ? ' IN ' . $database : '');
65 $r = $this->pdo->query($str);
66 $tables = array();
67
68 $sequence_identifier = "_seq";
69 while ($data = $r->fetchColumn()) {
70 if (!preg_match("/{$sequence_identifier}$/um", $data)) {
71 $tables[] = $data;
72 }
73 }
74
75 return $tables;
76 }
77
78
84 protected function fixSequenceName($sqn, $check = false) {
85 $seq_pattern = '/^' . preg_replace('/%s/', '([a-z0-9_]+)', ilDBConstants::SEQUENCE_FORMAT) . '$/i';
86 $seq_name = preg_replace($seq_pattern, '\\1', $sqn);
87 if ($seq_name && !strcasecmp($sqn, $this->db_instance->getSequenceName($seq_name))) {
88 return $seq_name;
89 }
90 if ($check) {
91 return false;
92 }
93
94 return $sqn;
95 }
96
97
102 public function listSequences($database = null) {
103 $query = "SHOW TABLES";
104 if (!is_null($database)) {
105 $query .= " FROM $database";
106 }
107
108 $res = $this->db_instance->query($query);
109
110 $result = array();
111 while ($table_name = $this->db_instance->fetchAssoc($res)) {
112 if ($sqn = $this->fixSequenceName(reset($table_name), true)) {
113 $result[] = $sqn;
114 }
115 }
116 if ($this->db_instance->options['portability']) {
117 $result = array_map(($this->db_instance->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $result);
118 }
119
120 return $result;
121 }
122
123
131 public function createConstraint($table, $name, $definition) {
132 $db = $this->db_instance;
133
134 $table = $db->quoteIdentifier($table, true);
135 $name = $db->quoteIdentifier($db->getIndexName($name), true);
136 $query = "ALTER TABLE $table ADD CONSTRAINT $name";
137 if (!empty($definition['primary'])) {
138 $query .= ' PRIMARY KEY';
139 } elseif (!empty($definition['unique'])) {
140 $query .= ' UNIQUE';
141 }
142 $fields = array();
143 foreach (array_keys($definition['fields']) as $field) {
144 $fields[] = $db->quoteIdentifier($field, true);
145 }
146 $query .= ' (' . implode(', ', $fields) . ')';
147
148 return $this->pdo->exec($query);
149 }
150
151
158 public function createSequence($seq_name, $start = 1, $options = array()) {
159 $sequence_name = $this->db_instance->quoteIdentifier($this->db_instance->getSequenceName($seq_name));
160 $seqcol_name = $this->db_instance->quoteIdentifier(ilDBConstants::SEQUENCE_COLUMNS_NAME);
161
162 $options_strings = array();
163
164 if (!empty($options['comment'])) {
165 $options_strings['comment'] = 'COMMENT = ' . $this->db_instance->quote($options['comment'], 'text');
166 }
167
168 if (!empty($options['charset'])) {
169 $options_strings['charset'] = 'DEFAULT CHARACTER SET ' . $options['charset'];
170 if (!empty($options['collate'])) {
171 $options_strings['charset'] .= ' COLLATE ' . $options['collate'];
172 }
173 }
174
175 $type = false;
176 if (!empty($options['type'])) {
177 $type = $options['type'];
178 }
179 if ($type) {
180 $options_strings[] = "ENGINE = $type";
181 }
182
183 $query = "CREATE TABLE $sequence_name ($seqcol_name INT NOT NULL AUTO_INCREMENT, PRIMARY KEY ($seqcol_name))";
184
185 if (!empty($options_strings)) {
186 $query .= ' ' . implode(' ', $options_strings);
187 }
188 $this->pdo->exec($query);
189
190 if ($start == 1) {
191 return true;
192 }
193
194 $query = "INSERT INTO $sequence_name ($seqcol_name) VALUES (" . ($start - 1) . ')';
195 $this->pdo->exec($query);
196
197 return true;
198 }
199
200
208 public function alterTable($name, $changes, $check) {
209 $db = $this->db_instance;
210
211 foreach ($changes as $change_name => $change) {
212 switch ($change_name) {
213 case 'add':
214 case 'remove':
215 case 'change':
216 case 'rename':
217 case 'name':
218 break;
219 default:
220 throw new ilDatabaseException('change type "' . $change_name . '" not yet supported');
221 }
222 }
223
224 if ($check) {
225 return true;
226 }
227
228 $query = '';
229 if (!empty($changes['name'])) {
230 $change_name = $db->quoteIdentifier($changes['name']);
231 $query .= 'RENAME TO ' . $change_name;
232 }
233
234 if (!empty($changes['add']) && is_array($changes['add'])) {
235 foreach ($changes['add'] as $field_name => $field) {
236 if ($query) {
237 $query .= ', ';
238 }
239 $query .= 'ADD ' . $db->getFieldDefinition()->getDeclaration($field['type'], $field_name, $field);
240 }
241 }
242
243 if (!empty($changes['remove']) && is_array($changes['remove'])) {
244 foreach ($changes['remove'] as $field_name => $field) {
245 if ($query) {
246 $query .= ', ';
247 }
248 $field_name = $db->quoteIdentifier($field_name);
249 $query .= 'DROP ' . $field_name;
250 }
251 }
252
253 $rename = array();
254 if (!empty($changes['rename']) && is_array($changes['rename'])) {
255 foreach ($changes['rename'] as $field_name => $field) {
256 $rename[$field['name']] = $field_name;
257 }
258 }
259
260 if (!empty($changes['change']) && is_array($changes['change'])) {
261 foreach ($changes['change'] as $field_name => $field) {
262 if ($query) {
263 $query .= ', ';
264 }
265 if (isset($rename[$field_name])) {
266 $old_field_name = $rename[$field_name];
267 unset($rename[$field_name]);
268 } else {
269 $old_field_name = $field_name;
270 }
271 $old_field_name = $db->quoteIdentifier($old_field_name);
272 $query .= "CHANGE $old_field_name " . $this->db_instance->getFieldDefinition()
273 ->getDeclaration($field['definition']['type'], $field_name, $field['definition']);
274 }
275 }
276
277 if (!empty($rename) && is_array($rename)) {
278 foreach ($rename as $rename_name => $renamed_field) {
279 if ($query) {
280 $query .= ', ';
281 }
282 $field = $changes['rename'][$renamed_field];
283 $renamed_field = $db->quoteIdentifier($renamed_field);
284 $query .= 'CHANGE ' . $renamed_field . ' ' . $this->db_instance->getFieldDefinition()
285 ->getDeclaration($field['definition']['type'], $field['name'], $field['definition']);
286 }
287 }
288
289 if (!$query) {
290 return true;
291 }
292
293 $name = $db->quoteIdentifier($name, true);
294
295 $statement = "ALTER TABLE $name $query";
296
297 return $this->pdo->exec($statement);
298 }
299
300
307 public function createTable($name, $fields, $options = array()) {
308 $options['type'] = $this->db_instance->getStorageEngine();
309
310 return $this->pdo->exec($this->getQueryUtils()->createTable($name, $fields, $options));
311 }
312
313
314
315
316
317 //
318 // ilDBPdoManagerInterface
319 //
324 public function getIndexName($idx) {
325 return $this->db_instance->getIndexName($idx);
326 }
327
328
333 public function getSequenceName($sqn) {
334 return $this->db_instance->getSequenceName($sqn);
335 }
336
337
343 public function listTableFields($table) {
344 $table = $this->db_instance->quoteIdentifier($table);
345 $query = "SHOW COLUMNS FROM $table";
346 $result = $this->db_instance->query($query);
347 $return = array();
348 while ($data = $this->db_instance->fetchObject($result)) {
349 $return[] = $data->Field;
350 }
351
352 return $return;
353 }
354
355
361 public function listTableConstraints($table) {
362 $key_name = 'Key_name';
363 $non_unique = 'Non_unique';
364
365 $db = $this->getDBInstance();
366 if ($db->options['portability']) {
367 if ($db->options['field_case'] == CASE_LOWER) {
368 $key_name = strtolower($key_name);
369 $non_unique = strtolower($non_unique);
370 } else {
371 $key_name = strtoupper($key_name);
372 $non_unique = strtoupper($non_unique);
373 }
374 }
375
376 $table = $this->db_instance->quoteIdentifier($table);
377 $query = "SHOW INDEX FROM $table";
378 $result_set = $this->db_instance->query($query);
379
380 $result = array();
381 while ($index_data = $this->db_instance->fetchAssoc($result_set)) {
382 if (!$index_data[$non_unique]) {
383 if ($index_data[$key_name] !== 'PRIMARY') {
384 $index = $this->fixIndexName($index_data[$key_name]);
385 } else {
386 $index = 'PRIMARY';
387 }
388 if (!empty($index)) {
389 $index = strtolower($index);
390 $result[$index] = true;
391 }
392 }
393 }
394
395 if ($this->db_instance->options['portability']) {
396 $result = array_change_key_case($result, $this->db_instance->options['field_case']);
397 }
398
399 return array_keys($result);
400 }
401
402
408 public function listTableIndexes($table) {
409 $key_name = 'Key_name';
410 $non_unique = 'Non_unique';
411 if ($this->db_instance->options['portability']) {
412 if ($this->db_instance->options['field_case'] == CASE_LOWER) {
413 $key_name = strtolower($key_name);
414 $non_unique = strtolower($non_unique);
415 } else {
416 $key_name = strtoupper($key_name);
417 $non_unique = strtoupper($non_unique);
418 }
419 }
420
421 $table = $this->db_instance->quoteIdentifier($table);
422 $query = "SHOW INDEX FROM $table";
423 $result_set = $this->db_instance->query($query);
424 $indexes = array();
425 while ($index_data = $this->db_instance->fetchAssoc($result_set)) {
426 $indexes[] = $index_data;
427 }
428 $result = array();
429 foreach ($indexes as $index_data) {
430 if ($index_data[$non_unique] && ($index = $this->fixIndexName($index_data[$key_name]))) {
431 $result[$index] = true;
432 }
433 }
434
435 if ($this->db_instance->options['portability']) {
436 $result = array_change_key_case($result, $this->db_instance->options['field_case']);
437 }
438
439 return array_keys($result);
440 }
441
442
447 protected function fixIndexName($idx) {
448 $idx_pattern = '/^' . preg_replace('/%s/', '([a-z0-9_]+)', ilDBPdoFieldDefinition::INDEX_FORMAT) . '$/i';
449 $idx_name = preg_replace($idx_pattern, '\\1', $idx);
450 if ($idx_name && !strcasecmp($idx, $this->db_instance->getIndexName($idx_name))) {
451 return $idx_name;
452 }
453
454 return $idx;
455 }
456
457
464 public function createIndex($table, $name, $definition) {
465 $table = $this->db_instance->quoteIdentifier($table, true);
466 $name = $this->db_instance->quoteIdentifier($this->db_instance->getIndexName($name), true);
467 $query = "CREATE INDEX $name ON $table";
468 $fields = array();
469 foreach ($definition['fields'] as $field => $fieldinfo) {
470 if (!empty($fieldinfo['length'])) {
471 $fields[] = $this->db_instance->quoteIdentifier($field, true) . '(' . $fieldinfo['length'] . ')';
472 } else {
473 $fields[] = $this->db_instance->quoteIdentifier($field, true);
474 }
475 }
476 $query .= ' (' . implode(', ', $fields) . ')';
477
478 return $this->pdo->exec($query);
479 }
480
481
487 public function dropIndex($table, $name) {
488 $table = $this->db_instance->quoteIdentifier($table, true);
489 $name = $this->db_instance->quoteIdentifier($this->db_instance->getIndexName($name), true);
490
491 return $this->pdo->exec("DROP INDEX $name ON $table");
492 }
493
494
499 public function dropSequence($table_name) {
500 $sequence_name = $this->db_instance->quoteIdentifier($this->db_instance->getSequenceName($table_name));
501
502 return $this->pdo->exec("DROP TABLE $sequence_name");
503 }
504
505
513 public function getTableCreationQuery($name, $fields, $options = array()) {
514 return $this->getQueryUtils()->createTable($name, $fields, $options);
515 }
516
517
524 public function dropConstraint($table, $name, $primary = false) {
525 $db = $this->getDBInstance();
526 $table = $db->quoteIdentifier($table, true);
527 if ($primary || strtolower($name) == 'primary') {
528 $query = "ALTER TABLE $table DROP PRIMARY KEY";
529 } else {
530 $name = $db->quoteIdentifier($db->getIndexName($name), true);
531 $query = "ALTER TABLE $table DROP INDEX $name";
532 }
533
534 return $this->pdo->exec($query);
535 }
536
537
541 public function dropTable($name) {
542 $db = $this->getDBInstance();
543
544 $name = $db->quoteIdentifier($name, true);
545
546 return $db->manipulate("DROP TABLE $name");
547 }
548}
$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.
$r
Definition: example_031.php:79
Interface ilDBManager.
Interface ilDBPdoManagerInterface.
if(!is_array($argv)) $options