ILIAS  trunk Revision v11.0_alpha-1713-gd8962da2f67
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
class.ilDBPdoReverse.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
25 class ilDBPdoReverse implements ilDBReverse
26 {
28 
32  public function __construct(protected \PDO $pdo, protected \ilDBPdo $db_instance)
33  {
34  }
35 
36  public function getQueryUtils(): \ilMySQLQueryUtils
37  {
38  if ($this->query_utils === null) {
39  $this->query_utils = new ilMySQLQueryUtils($this->db_instance);
40  }
41 
42  return $this->query_utils;
43  }
44 
48  public function getTableFieldDefinition(string $table_name, string $field_name): array
49  {
50  $table = $this->db_instance->quoteIdentifier($table_name);
51  $query = "SHOW COLUMNS FROM $table LIKE " . $this->db_instance->quote($field_name);
52  $res = $this->pdo->query($query);
53  $columns = [];
54  while ($data = $res->fetch(PDO::FETCH_ASSOC)) {
55  $columns[] = $data;
56  }
57 
58  $ilDBPdoFieldDefinition = $this->db_instance->getFieldDefinition();
59 
60  foreach ($columns as $column) {
61  $column = array_change_key_case($column, CASE_LOWER);
62  $column['name'] = $column['field'];
63  unset($column['field']);
64  $column = array_change_key_case($column, CASE_LOWER);
65  if ($field_name === $column['name'] && $ilDBPdoFieldDefinition !== null) {
66  [$types, $length, $unsigned, $fixed] = $ilDBPdoFieldDefinition->mapNativeDatatype($column);
67  $notnull = false;
68  if (empty($column['null']) || $column['null'] !== 'YES') {
69  $notnull = true;
70  }
71  $default = false;
72  if (array_key_exists('default', $column)) {
73  $default = $column['default'];
74  if ($notnull && is_null($default)) {
75  $default = '';
76  }
77  }
78  $autoincrement = false;
79  if (!empty($column['extra']) && $column['extra'] === 'auto_increment') {
80  $autoincrement = true;
81  }
82 
83  $definition[0] = [
84  'notnull' => $notnull,
85  'nativetype' => preg_replace('/^([a-z]+)[^a-z].*/i', '\\1', (string) $column['type']),
86  ];
87  if (!is_null($length)) {
88  $definition[0]['length'] = $length;
89  }
90  if (!is_null($unsigned)) {
91  $definition[0]['unsigned'] = $unsigned;
92  }
93  if (!is_null($fixed)) {
94  $definition[0]['fixed'] = $fixed;
95  }
96  if ($default !== false) {
97  $definition[0]['default'] = $default;
98  }
99  if ($autoincrement) {
100  $definition[0]['autoincrement'] = $autoincrement;
101  }
102  foreach ($types as $key => $type) {
103  $definition[$key] = $definition[0];
104  if ($type === 'clob' || $type === 'blob') {
105  unset($definition[$key]['default']);
106  }
107  $definition[$key]['type'] = $type;
108  $definition[$key]['mdb2type'] = $type;
109  }
110 
111  return $definition;
112  }
113  }
114 
115  throw new ilDatabaseException('it was not specified an existing table column');
116  }
117 
122  public function getTableIndexDefinition(string $table, string $constraint_name): array
123  {
124  $table = $this->db_instance->quoteIdentifier($table, true);
125  $query = "SHOW INDEX FROM $table /*!50002 WHERE Key_name = %s */";
126  $index_name_pdo = $this->db_instance->getIndexName($constraint_name);
127  $result = $this->db_instance->query(sprintf($query, $this->db_instance->quote($index_name_pdo)));
128  $data = $this->db_instance->fetchAssoc($result);
129 
130  if ($data) {
131  $constraint_name = $index_name_pdo;
132  }
133 
134  $result = $this->db_instance->query(sprintf($query, $this->db_instance->quote($constraint_name)));
135 
136  $colpos = 1;
137  $definition = [];
138  while (is_object($row = $result->fetchObject())) {
139  $row = array_change_key_case((array) $row, CASE_LOWER);
140 
141  $key_name = $row['key_name'];
142 
143  if ($constraint_name === $key_name) {
144  if (!$row['non_unique']) {
145  throw new ilDatabaseException('it was not specified an existing table index');
146  }
147  $column_name = $row['column_name'];
148  $definition['fields'][$column_name] = [
149  'position' => $colpos++,
150  ];
151  if (!empty($row['collation'])) {
152  $definition['fields'][$column_name]['sorting'] = ($row['collation'] === 'A' ? 'ascending' : 'descending');
153  }
154  }
155  }
156 
157  if (empty($definition['fields'])) {
158  throw new ilDatabaseException('it was not specified an existing table index (index does not exist)');
159  }
160 
161  return $definition;
162  }
163 
168  public function getTableConstraintDefinition(string $table, string $index_name): array
169  {
170  $index_name = strtolower($index_name);
171  $table = $this->db_instance->quoteIdentifier($table, true);
172  $query = "SHOW INDEX FROM $table /*!50002 WHERE Key_name = %s */";
173 
174  if (strtolower($index_name) !== 'primary') {
175  $constraint_name_pdo = $this->db_instance->getIndexName($index_name);
176  $result = $this->db_instance->query(sprintf($query, $this->db_instance->quote($constraint_name_pdo)));
177  $data = $this->db_instance->fetchAssoc($result);
178  if ($data) {
179  // apply 'idxname_format' only if the query succeeded, otherwise
180  // fallback to the given $index_name, without transformation
181  $index_name = strtolower($constraint_name_pdo);
182  }
183  }
184 
185  $result = $this->db_instance->query(sprintf($query, $this->db_instance->quote($index_name)));
186 
187  $colpos = 1;
188  $definition = [];
189  while (is_object($row = $result->fetchObject())) {
190  $row = (array) $row;
191  $row = array_change_key_case($row, CASE_LOWER);
192  $key_name = $row['key_name'];
193  if ($this->db_instance->options['portability'] ?? null) {
194  $key_name = strtolower((string) $key_name);
195  }
196  $key_name = strtolower((string) $key_name); // FSX fix
197  if ($index_name === $key_name) {
198  if ($row['non_unique']) {
199  throw new ilDatabaseException(' is not an existing table constraint');
200  }
201  if (strtolower((string) $row['key_name']) === 'primary') {
202  $definition['primary'] = true;
203  } else {
204  $definition['unique'] = true;
205  }
206  $column_name = $row['column_name'];
207  if ($this->db_instance->options['portability'] ?? null) {
208  if ($this->db_instance->options['field_case'] == CASE_LOWER) {
209  $column_name = strtolower((string) $column_name);
210  } else {
211  $column_name = strtoupper((string) $column_name);
212  }
213  }
214  $definition['fields'][$column_name] = [
215  'position' => $colpos++,
216  ];
217  if (!empty($row['collation'])) {
218  $definition['fields'][$column_name]['sorting'] = ($row['collation'] === 'A' ? 'ascending' : 'descending');
219  }
220  }
221  }
222 
223  if (empty($definition['fields'])) {
224  throw new ilDatabaseException(' is not an existing table constraint');
225  }
226 
227  return $definition;
228  }
229 
233  public function getTriggerDefinition(string $trigger): array
234  {
235  throw new ilDatabaseException('not yet implemented ' . __METHOD__);
236  }
237 }
$res
Definition: ltiservices.php:66
ilMySQLQueryUtils $query_utils
getTableConstraintDefinition(string $table, string $index_name)
getTriggerDefinition(string $trigger)
Interface ilDBReverse.
Class pdoDB.
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
getTableFieldDefinition(string $table_name, string $field_name)
__construct(protected \PDO $pdo, protected \ilDBPdo $db_instance)
ilDBPdoReverse constructor.
Class ilMySQLQueryUtils.
Class ilDBPdoReverse.
getTableIndexDefinition(string $table, string $constraint_name)