ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
class.ilDBPdoReversePostgres.php
Go to the documentation of this file.
1<?php
2require_once('class.ilDBPdoReverse.php');
3
10
11 // {{{ getTableFieldDefinition()
12
21 public function getTableFieldDefinition($table, $field_name) {
27 $result = $this->db_instance->loadModule(ilDBConstants::MODULE_REVERSE);
28
29 $query = "SELECT a.attname AS name,
30 t.typname AS type,
31 CASE a.attlen
32 WHEN -1 THEN
33 CASE t.typname
34 WHEN 'numeric' THEN (a.atttypmod / 65536)
35 WHEN 'decimal' THEN (a.atttypmod / 65536)
36 WHEN 'money' THEN (a.atttypmod / 65536)
37 ELSE CASE a.atttypmod
38 WHEN -1 THEN NULL
39 ELSE a.atttypmod - 4
40 END
41 END
42 ELSE a.attlen
43 END AS length,
44 CASE t.typname
45 WHEN 'numeric' THEN (a.atttypmod % 65536) - 4
46 WHEN 'decimal' THEN (a.atttypmod % 65536) - 4
47 WHEN 'money' THEN (a.atttypmod % 65536) - 4
48 ELSE 0
49 END AS scale,
50 a.attnotnull,
51 a.atttypmod,
52 a.atthasdef,
53 (SELECT substring(pg_get_expr(d.adbin, d.adrelid) for 128)
54 FROM pg_attrdef d
55 WHERE d.adrelid = a.attrelid
56 AND d.adnum = a.attnum
57 AND a.atthasdef
58 ) as default
59 FROM pg_attribute a,
60 pg_class c,
61 pg_type t
62 WHERE c.relname = " . $db->quote($table, 'text') . "
63 AND a.atttypid = t.oid
64 AND c.oid = a.attrelid
65 AND NOT a.attisdropped
66 AND a.attnum > 0
67 AND a.attname = " . $db->quote($field_name, 'text') . "
68 ORDER BY a.attnum";
69 $column = $db->queryRow($query, null, MDB2_FETCHMODE_ASSOC);
70
71 if (empty($column)) {
72 throw new ilDatabaseException('it was not specified an existing table column');
73 }
74
75 $column = array_change_key_case($column, CASE_LOWER);
76 $mapped_datatype = $db->getFieldDefinition()->mapNativeDatatype($column);
77
78 list($types, $length, $unsigned, $fixed) = $mapped_datatype;
79 $notnull = false;
80 if (!empty($column['attnotnull']) && $column['attnotnull'] == 't') {
81 $notnull = true;
82 }
83 $default = null;
84 if ($column['atthasdef'] === 't'
85 && !preg_match("/nextval\‍('([^']+)'/", $column['default'])
86 ) {
87 $default = $column['default'];#substr($column['adsrc'], 1, -1);
88 if (is_null($default) && $notnull) {
89 $default = '';
90 }
91 }
92 $autoincrement = false;
93 if (preg_match("/nextval\‍('([^']+)'/", $column['default'], $nextvals)) {
94 $autoincrement = true;
95 }
96 $definition[0] = array( 'notnull' => $notnull, 'nativetype' => $column['type'] );
97 if (!is_null($length)) {
98 $definition[0]['length'] = $length;
99 }
100 if (!is_null($unsigned)) {
101 $definition[0]['unsigned'] = $unsigned;
102 }
103 if (!is_null($fixed)) {
104 $definition[0]['fixed'] = $fixed;
105 }
106 if ($default !== false) {
107 $definition[0]['default'] = $default;
108 }
109 if ($autoincrement !== false) {
110 $definition[0]['autoincrement'] = $autoincrement;
111 }
112 foreach ($types as $key => $type) {
113 $definition[$key] = $definition[0];
114 if ($type == 'clob' || $type == 'blob') {
115 unset($definition[$key]['default']);
116 }
117 $definition[$key]['type'] = $type;
118 $definition[$key]['mdb2type'] = $type;
119 }
120
121 return $definition;
122 }
123
124
131 public function getTableIndexDefinition($table, $index_name) {
132 $db = $this->db_instance;
133 $manager = $db->loadModule(ilDBConstants::MODULE_MANAGER);
138 $query = 'SELECT relname, indkey FROM pg_index, pg_class';
139 $query .= ' WHERE pg_class.oid = pg_index.indexrelid';
140 $query .= " AND indisunique != 't' AND indisprimary != 't'";
141 $query .= ' AND pg_class.relname = %s';
142 $index_name_mdb2 = $db->getIndexName($index_name);
143 $failed = false;
144 try {
145 $row = $db->queryRow(sprintf($query, $db->quote($index_name_mdb2, 'text')), null, ilDBConstants::FETCHMODE_DEFAULT);
146 } catch (Exception $e) {
147 $failed = true;
148 }
149 if ($failed || empty($row)) {
150 $row = $db->queryRow(sprintf($query, $db->quote($index_name, 'text')), null, ilDBConstants::FETCHMODE_DEFAULT);
151 }
152
153 if (empty($row)) {
154 throw new ilDatabaseException('it was not specified an existing table index');
155 }
156
157 $row = array_change_key_case($row, CASE_LOWER);
158
159 $columns = $manager->listTableFields($table);
160
161 $definition = array();
162
163 $index_column_numbers = explode(' ', $row['indkey']);
164
165 $colpos = 1;
166 foreach ($index_column_numbers as $number) {
167 $definition['fields'][$columns[($number - 1)]] = array(
168 'position' => $colpos ++,
169 'sorting' => 'ascending',
170 );
171 }
172
173 return $definition;
174 }
175
176 // }}}
177 // {{{ getTableConstraintDefinition()
186 function getTableConstraintDefinition($table, $constraint_name) {
187 $db = $this->db_instance;
188
189 $query = 'SELECT relname, indisunique, indisprimary, indkey FROM pg_index, pg_class';
190 $query .= ' WHERE pg_class.oid = pg_index.indexrelid';
191 $query .= " AND (indisunique = 't' OR indisprimary = 't')";
192 $query .= ' AND pg_class.relname = %s';
193 $constraint_name_mdb2 = $db->getIndexName($constraint_name);
194 try {
195 $row = $db->queryRow(sprintf($query, $db->quote($constraint_name_mdb2, 'text')), null, ilDBConstants::FETCHMODE_ASSOC);
196 } catch (Exception $e) {
197 }
198
199 if ($e instanceof PDOException || empty($row)) {
200 // fallback to the given $index_name, without transformation
201 $row = $db->queryRow(sprintf($query, $db->quote($constraint_name, 'text')), null, ilDBConstants::FETCHMODE_ASSOC);
202 }
203
204 if (empty($row)) {
205 throw new ilDatabaseException($constraint_name . ' is not an existing table constraint');
206 }
207
208 $row = array_change_key_case($row, CASE_LOWER);
209 $columns = $db->loadModule(ilDBConstants::MODULE_MANAGER)->listTableFields($table);
210
211 $definition = array();
212 if ($row['indisprimary'] == 't') {
213 $definition['primary'] = true;
214 } elseif ($row['indisunique'] == 't') {
215 $definition['unique'] = true;
216 }
217
218 $index_column_numbers = explode(' ', $row['indkey']);
219
220 $colpos = 1;
221 foreach ($index_column_numbers as $number) {
222 $definition['fields'][$columns[($number - 1)]] = array(
223 'position' => $colpos ++,
224 'sorting' => 'ascending',
225 );
226 }
227
228 return $definition;
229 }
230
231 // }}}
232 // {{{ getTriggerDefinition()
233
248 function getTriggerDefinition($trigger) {
249 $db = $this->db_instance;
250
251 $query = "SELECT trg.tgname AS trigger_name,
252 tbl.relname AS table_name,
253 CASE
254 WHEN p.proname IS NOT NULL THEN 'EXECUTE PROCEDURE ' || p.proname || '();'
255 ELSE ''
256 END AS trigger_body,
257 CASE trg.tgtype & cast(2 as int2)
258 WHEN 0 THEN 'AFTER'
259 ELSE 'BEFORE'
260 END AS trigger_type,
261 CASE trg.tgtype & cast(28 as int2)
262 WHEN 16 THEN 'UPDATE'
263 WHEN 8 THEN 'DELETE'
264 WHEN 4 THEN 'INSERT'
265 WHEN 20 THEN 'INSERT, UPDATE'
266 WHEN 28 THEN 'INSERT, UPDATE, DELETE'
267 WHEN 24 THEN 'UPDATE, DELETE'
268 WHEN 12 THEN 'INSERT, DELETE'
269 END AS trigger_event,
270 trg.tgenabled AS trigger_enabled,
271 obj_description(trg.oid, 'pg_trigger') AS trigger_comment
272 FROM pg_trigger trg,
273 pg_class tbl,
274 pg_proc p
275 WHERE trg.tgrelid = tbl.oid
276 AND trg.tgfoid = p.oid
277 AND trg.tgname = " . $db->quote($trigger, 'text');
278 $types = array(
279 'trigger_name' => 'text',
280 'table_name' => 'text',
281 'trigger_body' => 'text',
282 'trigger_type' => 'text',
283 'trigger_event' => 'text',
284 'trigger_comment' => 'text',
285 'trigger_enabled' => 'boolean',
286 );
287
288 return $db->queryRow($query, $types, MDB2_FETCHMODE_ASSOC);
289 }
290
291 // }}}
292 // {{{ tableInfo()
293
312 function tableInfo($result, $mode = null) {
313 if (is_string($result)) {
314 return parent::tableInfo($result, $mode);
315 }
316
317 $db = $this->db_instance;
318
319 $resource = MDB2::isResultCommon($result) ? $result->getResource() : $result;
320 if (!is_resource($resource)) {
321 return $db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null, 'Could not generate result resource', __FUNCTION__);
322 }
323
324 if ($db->options['portability']) {
325 if ($db->options['field_case'] == CASE_LOWER) {
326 $case_func = 'strtolower';
327 } else {
328 $case_func = 'strtoupper';
329 }
330 } else {
331 $case_func = 'strval';
332 }
333
334 $count = @pg_num_fields($resource);
335 $res = array();
336
337 if ($mode) {
338 $res['num_fields'] = $count;
339 }
340
341 $db->loadModule('Datatype', null, true);
342 for ($i = 0; $i < $count; $i ++) {
343 $res[$i] = array(
344 'table' => function_exists('pg_field_table') ? @pg_field_table($resource, $i) : '',
345 'name' => $case_func(@pg_field_name($resource, $i)),
346 'type' => @pg_field_type($resource, $i),
347 'length' => @pg_field_size($resource, $i),
348 'flags' => '',
349 );
350 $mdb2type_info = $db->datatype->mapNativeDatatype($res[$i]);
351 if (PEAR::isError($mdb2type_info)) {
352 return $mdb2type_info;
353 }
354 $res[$i]['mdb2type'] = $mdb2type_info[0][0];
355 if ($mode & MDB2_TABLEINFO_ORDER) {
356 $res['order'][$res[$i]['name']] = $i;
357 }
358 if ($mode & MDB2_TABLEINFO_ORDERTABLE) {
359 $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
360 }
361 }
362
363 return $res;
364 }
365}
sprintf('%.4f', $callTime)
$column
Definition: 39dropdown.php:62
$result
const MDB2_ERROR_NEED_MORE_DATA
Definition: MDB2.php:92
const MDB2_FETCHMODE_ASSOC
Column data indexed by column names.
Definition: MDB2.php:134
const MDB2_TABLEINFO_ORDERTABLE
Definition: Common.php:60
const MDB2_TABLEINFO_ORDER
These are constants for the tableInfo-function they are bitwised or'ed.
Definition: Common.php:59
$failed
Definition: Utf8Test.php:85
if(! $in) $columns
Definition: Utf8Test.php:45
An exception for terminatinating execution or to throw for unit testing.
isResultCommon($value)
Tell whether a value is a MDB2 result implementing the common interface.
Definition: MDB2.php:660
isError($data, $code=null)
Tell whether a value is a PEAR error.
Definition: PEAR.php:280
tableInfo($result, $mode=null)
Returns information about a table or a result set.
getTriggerDefinition($trigger)
Get the structure of a trigger into an array.
getTableConstraintDefinition($table, $constraint_name)
Get the structure of a constraint into an array.
Class ilDBPdoReverse.
getTableIndexDefinition($table, $index_name)
getTableFieldDefinition($table_name, $field_name)
Class ilDatabaseException.