Total Complexity | 50 |
Total Lines | 671 |
Duplicated Lines | 0 % |
Changes | 0 |
Complex classes like Postgres74 often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Postgres74, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
17 | class Postgres74 extends Postgres80 |
||
18 | { |
||
19 | public $major_version = 7.4; |
||
20 | // List of all legal privileges that can be applied to different types |
||
21 | // of objects. |
||
22 | public $privlist = [ |
||
23 | 'table' => ['SELECT', 'INSERT', 'UPDATE', 'DELETE', 'RULE', 'REFERENCES', 'TRIGGER', 'ALL PRIVILEGES'], |
||
24 | 'view' => ['SELECT', 'INSERT', 'UPDATE', 'DELETE', 'RULE', 'REFERENCES', 'TRIGGER', 'ALL PRIVILEGES'], |
||
25 | 'sequence' => ['SELECT', 'UPDATE', 'ALL PRIVILEGES'], |
||
26 | 'database' => ['CREATE', 'TEMPORARY', 'ALL PRIVILEGES'], |
||
27 | 'function' => ['EXECUTE', 'ALL PRIVILEGES'], |
||
28 | 'language' => ['USAGE', 'ALL PRIVILEGES'], |
||
29 | 'schema' => ['CREATE', 'USAGE', 'ALL PRIVILEGES'], |
||
30 | ]; |
||
31 | |||
32 | // Database functions |
||
33 | |||
34 | /** |
||
35 | * Alters a database |
||
36 | * the multiple return vals are for postgres 8+ which support more functionality in alter database. |
||
37 | * |
||
38 | * @param string $dbName The name of the database |
||
39 | * @param string $newName new name for the database |
||
40 | * @param string $newOwner The new owner for the database |
||
41 | * @param string $comment |
||
42 | * |
||
43 | * @return bool|int 0 success |
||
44 | */ |
||
45 | public function alterDatabase($dbName, $newName, $newOwner = '', $comment = '') |
||
58 | } |
||
59 | |||
60 | /** |
||
61 | * Return all database available on the server. |
||
62 | * |
||
63 | * @param null|string $currentdatabase |
||
64 | * |
||
65 | * @return \ADORecordSet A list of databases, sorted alphabetically |
||
66 | */ |
||
67 | public function getDatabases($currentdatabase = null) |
||
68 | { |
||
69 | $conf = $this->conf; |
||
70 | $server_info = $this->server_info; |
||
|
|||
71 | |||
72 | if (isset($conf['owned_only']) && $conf['owned_only'] && !$this->isSuperUser()) { |
||
73 | $username = $server_info['username']; |
||
74 | $this->clean($username); |
||
75 | $clause = " AND pu.usename='{$username}'"; |
||
76 | } else { |
||
77 | $clause = ''; |
||
78 | } |
||
79 | |||
80 | if ($currentdatabase != null) { |
||
81 | $this->clean($currentdatabase); |
||
82 | $orderby = "ORDER BY pdb.datname = '{$currentdatabase}' DESC, pdb.datname"; |
||
83 | } else { |
||
84 | $orderby = 'ORDER BY pdb.datname'; |
||
85 | } |
||
86 | |||
87 | if (!$conf['show_system']) { |
||
88 | $where = ' AND NOT pdb.datistemplate'; |
||
89 | } else { |
||
90 | $where = ' AND pdb.datallowconn'; |
||
91 | } |
||
92 | |||
93 | $sql = "SELECT pdb.datname AS datname, |
||
94 | pu.usename AS datowner, |
||
95 | pg_encoding_to_char(encoding) AS datencoding, |
||
96 | (SELECT description FROM pg_description pd WHERE pdb.oid=pd.objoid) AS datcomment |
||
97 | FROM pg_database pdb, pg_user pu |
||
98 | WHERE pdb.datdba = pu.usesysid |
||
99 | {$where} |
||
100 | {$clause} |
||
101 | {$orderby}"; |
||
102 | |||
103 | return $this->selectSet($sql); |
||
104 | } |
||
105 | |||
106 | /** |
||
107 | * Searches all system catalogs to find objects that match a certain name. |
||
108 | * |
||
109 | * @param $term The search term |
||
110 | * @param $filter The object type to restrict to ('' means no restriction) |
||
111 | * |
||
112 | * @return \ADORecordSet A recordset |
||
113 | */ |
||
114 | public function findObject($term, $filter) |
||
115 | { |
||
116 | $conf = $this->conf; |
||
117 | |||
118 | /*about escaping: |
||
119 | * SET standard_conforming_string is not available before 8.2 |
||
120 | * So we must use PostgreSQL specific notation :/ |
||
121 | * E'' notation is not available before 8.1 |
||
122 | * $$ is available since 8.0 |
||
123 | * Nothing specific from 7.4 |
||
124 | */ |
||
125 | |||
126 | // Escape search term for ILIKE match |
||
127 | $term = str_replace('_', '\\_', $term); |
||
128 | $term = str_replace('%', '\\%', $term); |
||
129 | $this->clean($term); |
||
130 | $this->clean($filter); |
||
131 | |||
132 | // Exclude system relations if necessary |
||
133 | if (!$conf['show_system']) { |
||
134 | // XXX: The mention of information_schema here is in the wrong place, but |
||
135 | // it's the quickest fix to exclude the info schema from 7.4 |
||
136 | $where = " AND pn.nspname NOT LIKE 'pg\\\\_%' AND pn.nspname != 'information_schema'"; |
||
137 | $lan_where = 'AND pl.lanispl'; |
||
138 | } else { |
||
139 | $where = ''; |
||
140 | $lan_where = ''; |
||
141 | } |
||
142 | |||
143 | // Apply outer filter |
||
144 | $sql = ''; |
||
145 | if ($filter != '') { |
||
146 | $sql = 'SELECT * FROM ('; |
||
147 | } |
||
148 | |||
149 | $sql .= " |
||
150 | SELECT 'SCHEMA' AS type, oid, NULL AS schemaname, NULL AS relname, nspname AS name |
||
151 | FROM pg_catalog.pg_namespace pn WHERE nspname ILIKE '%{$term}%' {$where} |
||
152 | UNION ALL |
||
153 | SELECT CASE WHEN relkind='r' THEN 'TABLE' WHEN relkind='v' THEN 'VIEW' WHEN relkind='S' THEN 'SEQUENCE' END, pc.oid, |
||
154 | pn.nspname, NULL, pc.relname FROM pg_catalog.pg_class pc, pg_catalog.pg_namespace pn |
||
155 | WHERE pc.relnamespace=pn.oid AND relkind IN ('r', 'v', 'S') AND relname ILIKE '%{$term}%' {$where} |
||
156 | UNION ALL |
||
157 | SELECT CASE WHEN pc.relkind='r' THEN 'COLUMNTABLE' ELSE 'COLUMNVIEW' END, NULL, pn.nspname, pc.relname, pa.attname FROM pg_catalog.pg_class pc, pg_catalog.pg_namespace pn, |
||
158 | pg_catalog.pg_attribute pa WHERE pc.relnamespace=pn.oid AND pc.oid=pa.attrelid |
||
159 | AND pa.attname ILIKE '%{$term}%' AND pa.attnum > 0 AND NOT pa.attisdropped AND pc.relkind IN ('r', 'v') {$where} |
||
160 | UNION ALL |
||
161 | SELECT 'FUNCTION', pp.oid, pn.nspname, NULL, pp.proname || '(' || pg_catalog.oidvectortypes(pp.proargtypes) || ')' FROM pg_catalog.pg_proc pp, pg_catalog.pg_namespace pn |
||
162 | WHERE pp.pronamespace=pn.oid AND NOT pp.proisagg AND pp.proname ILIKE '%{$term}%' {$where} |
||
163 | UNION ALL |
||
164 | SELECT 'INDEX', NULL, pn.nspname, pc.relname, pc2.relname FROM pg_catalog.pg_class pc, pg_catalog.pg_namespace pn, |
||
165 | pg_catalog.pg_index pi, pg_catalog.pg_class pc2 WHERE pc.relnamespace=pn.oid AND pc.oid=pi.indrelid |
||
166 | AND pi.indexrelid=pc2.oid |
||
167 | AND NOT EXISTS ( |
||
168 | SELECT 1 FROM pg_catalog.pg_depend d JOIN pg_catalog.pg_constraint c |
||
169 | ON (d.refclassid = c.tableoid AND d.refobjid = c.oid) |
||
170 | WHERE d.classid = pc2.tableoid AND d.objid = pc2.oid AND d.deptype = 'i' AND c.contype IN ('u', 'p') |
||
171 | ) |
||
172 | AND pc2.relname ILIKE '%{$term}%' {$where} |
||
173 | UNION ALL |
||
174 | SELECT 'CONSTRAINTTABLE', NULL, pn.nspname, pc.relname, pc2.conname FROM pg_catalog.pg_class pc, pg_catalog.pg_namespace pn, |
||
175 | pg_catalog.pg_constraint pc2 WHERE pc.relnamespace=pn.oid AND pc.oid=pc2.conrelid AND pc2.conrelid != 0 |
||
176 | AND CASE WHEN pc2.contype IN ('f', 'c') THEN TRUE ELSE NOT EXISTS ( |
||
177 | SELECT 1 FROM pg_catalog.pg_depend d JOIN pg_catalog.pg_constraint c |
||
178 | ON (d.refclassid = c.tableoid AND d.refobjid = c.oid) |
||
179 | WHERE d.classid = pc2.tableoid AND d.objid = pc2.oid AND d.deptype = 'i' AND c.contype IN ('u', 'p') |
||
180 | ) END |
||
181 | AND pc2.conname ILIKE '%{$term}%' {$where} |
||
182 | UNION ALL |
||
183 | SELECT 'CONSTRAINTDOMAIN', pt.oid, pn.nspname, pt.typname, pc.conname FROM pg_catalog.pg_type pt, pg_catalog.pg_namespace pn, |
||
184 | pg_catalog.pg_constraint pc WHERE pt.typnamespace=pn.oid AND pt.oid=pc.contypid AND pc.contypid != 0 |
||
185 | AND pc.conname ILIKE '%{$term}%' {$where} |
||
186 | UNION ALL |
||
187 | SELECT 'TRIGGER', NULL, pn.nspname, pc.relname, pt.tgname FROM pg_catalog.pg_class pc, pg_catalog.pg_namespace pn, |
||
188 | pg_catalog.pg_trigger pt WHERE pc.relnamespace=pn.oid AND pc.oid=pt.tgrelid |
||
189 | AND ( pt.tgisconstraint = 'f' OR NOT EXISTS |
||
190 | (SELECT 1 FROM pg_catalog.pg_depend d JOIN pg_catalog.pg_constraint c |
||
191 | ON (d.refclassid = c.tableoid AND d.refobjid = c.oid) |
||
192 | WHERE d.classid = pt.tableoid AND d.objid = pt.oid AND d.deptype = 'i' AND c.contype = 'f')) |
||
193 | AND pt.tgname ILIKE '%{$term}%' {$where} |
||
194 | UNION ALL |
||
195 | SELECT 'RULETABLE', NULL, pn.nspname AS schemaname, c.relname AS tablename, r.rulename FROM pg_catalog.pg_rewrite r |
||
196 | JOIN pg_catalog.pg_class c ON c.oid = r.ev_class |
||
197 | LEFT JOIN pg_catalog.pg_namespace pn ON pn.oid = c.relnamespace |
||
198 | WHERE c.relkind='r' AND r.rulename != '_RETURN' AND r.rulename ILIKE '%{$term}%' {$where} |
||
199 | UNION ALL |
||
200 | SELECT 'RULEVIEW', NULL, pn.nspname AS schemaname, c.relname AS tablename, r.rulename FROM pg_catalog.pg_rewrite r |
||
201 | JOIN pg_catalog.pg_class c ON c.oid = r.ev_class |
||
202 | LEFT JOIN pg_catalog.pg_namespace pn ON pn.oid = c.relnamespace |
||
203 | WHERE c.relkind='v' AND r.rulename != '_RETURN' AND r.rulename ILIKE '%{$term}%' {$where} |
||
204 | "; |
||
205 | |||
206 | // Add advanced objects if show_advanced is set |
||
207 | if ($conf['show_advanced']) { |
||
208 | $sql .= " |
||
209 | UNION ALL |
||
210 | SELECT CASE WHEN pt.typtype='d' THEN 'DOMAIN' ELSE 'TYPE' END, pt.oid, pn.nspname, NULL, |
||
211 | pt.typname FROM pg_catalog.pg_type pt, pg_catalog.pg_namespace pn |
||
212 | WHERE pt.typnamespace=pn.oid AND typname ILIKE '%{$term}%' |
||
213 | AND (pt.typrelid = 0 OR (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = pt.typrelid)) |
||
214 | {$where} |
||
215 | UNION ALL |
||
216 | SELECT 'OPERATOR', po.oid, pn.nspname, NULL, po.oprname FROM pg_catalog.pg_operator po, pg_catalog.pg_namespace pn |
||
217 | WHERE po.oprnamespace=pn.oid AND oprname ILIKE '%{$term}%' {$where} |
||
218 | UNION ALL |
||
219 | SELECT 'CONVERSION', pc.oid, pn.nspname, NULL, pc.conname FROM pg_catalog.pg_conversion pc, |
||
220 | pg_catalog.pg_namespace pn WHERE pc.connamespace=pn.oid AND conname ILIKE '%{$term}%' {$where} |
||
221 | UNION ALL |
||
222 | SELECT 'LANGUAGE', pl.oid, NULL, NULL, pl.lanname FROM pg_catalog.pg_language pl |
||
223 | WHERE lanname ILIKE '%{$term}%' {$lan_where} |
||
224 | UNION ALL |
||
225 | SELECT DISTINCT ON (p.proname) 'AGGREGATE', p.oid, pn.nspname, NULL, p.proname FROM pg_catalog.pg_proc p |
||
226 | LEFT JOIN pg_catalog.pg_namespace pn ON p.pronamespace=pn.oid |
||
227 | WHERE p.proisagg AND p.proname ILIKE '%{$term}%' {$where} |
||
228 | UNION ALL |
||
229 | SELECT DISTINCT ON (po.opcname) 'OPCLASS', po.oid, pn.nspname, NULL, po.opcname FROM pg_catalog.pg_opclass po, |
||
230 | pg_catalog.pg_namespace pn WHERE po.opcnamespace=pn.oid |
||
231 | AND po.opcname ILIKE '%{$term}%' {$where} |
||
232 | "; |
||
233 | } // Otherwise just add domains |
||
234 | else { |
||
235 | $sql .= " |
||
236 | UNION ALL |
||
237 | SELECT 'DOMAIN', pt.oid, pn.nspname, NULL, |
||
238 | pt.typname FROM pg_catalog.pg_type pt, pg_catalog.pg_namespace pn |
||
239 | WHERE pt.typnamespace=pn.oid AND pt.typtype='d' AND typname ILIKE '%{$term}%' |
||
240 | AND (pt.typrelid = 0 OR (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = pt.typrelid)) |
||
241 | {$where} |
||
242 | "; |
||
243 | } |
||
244 | |||
245 | if ($filter != '') { |
||
246 | // We use like to make RULE, CONSTRAINT and COLUMN searches work |
||
247 | $sql .= ") AS sub WHERE type LIKE '{$filter}%' "; |
||
248 | } |
||
249 | |||
250 | $sql .= 'ORDER BY type, schemaname, relname, name'; |
||
251 | |||
252 | return $this->selectSet($sql); |
||
253 | } |
||
254 | |||
255 | /** |
||
256 | * Returns table locks information in the current database. |
||
257 | * |
||
258 | * @return \ADORecordSet A recordset |
||
259 | */ |
||
260 | public function getLocks() |
||
261 | { |
||
262 | $conf = $this->conf; |
||
263 | |||
264 | if (!$conf['show_system']) { |
||
265 | $where = "AND pn.nspname NOT LIKE 'pg\\\\_%'"; |
||
266 | } else { |
||
267 | $where = "AND nspname !~ '^pg_t(emp_[0-9]+|oast)$'"; |
||
268 | } |
||
269 | |||
270 | $sql = "SELECT pn.nspname, pc.relname AS tablename, pl.transaction, pl.pid, pl.mode, pl.granted |
||
271 | FROM pg_catalog.pg_locks pl, pg_catalog.pg_class pc, pg_catalog.pg_namespace pn |
||
272 | WHERE pl.relation = pc.oid AND pc.relnamespace=pn.oid {$where} |
||
273 | ORDER BY nspname,tablename"; |
||
274 | |||
275 | return $this->selectSet($sql); |
||
276 | } |
||
277 | |||
278 | /** |
||
279 | * Returns the current database encoding. |
||
280 | * |
||
281 | * @return The encoding. eg. SQL_ASCII, UTF-8, etc. |
||
282 | */ |
||
283 | public function getDatabaseEncoding() |
||
284 | { |
||
285 | $sql = 'SELECT getdatabaseencoding() AS encoding'; |
||
286 | |||
287 | return $this->selectField($sql, 'encoding'); |
||
288 | } |
||
289 | |||
290 | // Table functions |
||
291 | |||
292 | /** |
||
293 | * Alters a column in a table OR view. |
||
294 | * |
||
295 | * @param $table The table in which the column resides |
||
296 | * @param $column The column to alter |
||
297 | * @param $name The new name for the column |
||
298 | * @param $notnull (boolean) True if not null, false otherwise |
||
299 | * @param $oldnotnull (boolean) True if column is already not null, false otherwise |
||
300 | * @param $default The new default for the column |
||
301 | * @param $olddefault The old default for the column |
||
302 | * @param $type The new type for the column |
||
303 | * @param $length The optional size of the column (ie. 30 for varchar(30)) |
||
304 | * @param $array True if array type, false otherwise |
||
305 | * @param $oldtype The old type for the column |
||
306 | * @param $comment Comment for the column |
||
307 | * |
||
308 | * @return array|bool|int 0 success |
||
309 | */ |
||
310 | public function alterColumn( |
||
311 | $table, |
||
312 | $column, |
||
313 | $name, |
||
314 | $notnull, |
||
315 | $oldnotnull, |
||
316 | $default, |
||
317 | $olddefault, |
||
318 | $type, |
||
319 | $length, |
||
320 | $array, |
||
321 | $oldtype, |
||
322 | $comment |
||
323 | ) { |
||
324 | $status = $this->beginTransaction(); |
||
325 | if ($status != 0) { |
||
326 | return -1; |
||
327 | } |
||
328 | |||
329 | // @@ NEED TO HANDLE "NESTED" TRANSACTION HERE |
||
330 | if ($notnull != $oldnotnull) { |
||
331 | $status = $this->setColumnNull($table, $column, !$notnull); |
||
332 | if ($status != 0) { |
||
333 | $this->rollbackTransaction(); |
||
334 | |||
335 | return -2; |
||
336 | } |
||
337 | } |
||
338 | |||
339 | // Set default, if it has changed |
||
340 | if ($default != $olddefault) { |
||
341 | if ($default == '') { |
||
342 | $status = $this->dropColumnDefault($table, $column); |
||
343 | } else { |
||
344 | $status = $this->setColumnDefault($table, $column, $default); |
||
345 | } |
||
346 | |||
347 | if ($status != 0) { |
||
348 | $this->rollbackTransaction(); |
||
349 | |||
350 | return -3; |
||
351 | } |
||
352 | } |
||
353 | |||
354 | // Rename the column, if it has been changed |
||
355 | if ($column != $name) { |
||
356 | $status = $this->renameColumn($table, $column, $name); |
||
357 | if ($status != 0) { |
||
358 | $this->rollbackTransaction(); |
||
359 | |||
360 | return -4; |
||
361 | } |
||
362 | } |
||
363 | |||
364 | // The $name and $table parameters must be cleaned for the setComment function. |
||
365 | // It's ok to do that here since this is the last time these variables are used. |
||
366 | $this->fieldClean($name); |
||
367 | $this->fieldClean($table); |
||
368 | $status = $this->setComment('COLUMN', $name, $table, $comment); |
||
369 | if ($status != 0) { |
||
370 | $this->rollbackTransaction(); |
||
371 | |||
372 | return -5; |
||
373 | } |
||
374 | |||
375 | return $this->endTransaction(); |
||
376 | } |
||
377 | |||
378 | /** |
||
379 | * Returns table information. |
||
380 | * |
||
381 | * @param $table The name of the table |
||
382 | * |
||
383 | * @return \ADORecordSet A recordset |
||
384 | */ |
||
385 | public function getTable($table) |
||
386 | { |
||
387 | $c_schema = $this->_schema; |
||
388 | $this->clean($c_schema); |
||
389 | $this->clean($table); |
||
390 | |||
391 | $sql = " |
||
392 | SELECT |
||
393 | c.relname, n.nspname, u.usename AS relowner, |
||
394 | pg_catalog.obj_description(c.oid, 'pg_class') AS relcomment |
||
395 | FROM pg_catalog.pg_class c |
||
396 | LEFT JOIN pg_catalog.pg_user u ON u.usesysid = c.relowner |
||
397 | LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace |
||
398 | WHERE c.relkind = 'r' |
||
399 | AND n.nspname = '{$c_schema}' |
||
400 | AND c.relname = '{$table}'"; |
||
401 | |||
402 | return $this->selectSet($sql); |
||
403 | } |
||
404 | |||
405 | /** |
||
406 | * Returns the current default_with_oids setting. |
||
407 | * |
||
408 | * @return default_with_oids setting |
||
409 | */ |
||
410 | public function getDefaultWithOid() |
||
411 | { |
||
412 | // 8.0 is the first release to have this setting |
||
413 | // Prior releases don't have this setting... oids always activated |
||
414 | return 'on'; |
||
415 | } |
||
416 | |||
417 | /** |
||
418 | * Returns a list of all constraints on a table, |
||
419 | * including constraint name, definition, related col and referenced namespace, |
||
420 | * table and col if needed. |
||
421 | * |
||
422 | * @param $table the table where we are looking for fk |
||
423 | * |
||
424 | * @return \ADORecordSet A recordset |
||
425 | */ |
||
426 | public function getConstraintsWithFields($table) |
||
427 | { |
||
428 | $c_schema = $this->_schema; |
||
429 | $this->clean($c_schema); |
||
430 | $this->clean($table); |
||
431 | |||
432 | // get the max number of col used in a constraint for the table |
||
433 | $sql = "SELECT DISTINCT |
||
434 | max(SUBSTRING(array_dims(c.conkey) FROM '^\\\\[.*:(.*)\\\\]$')) as nb |
||
435 | FROM pg_catalog.pg_constraint AS c |
||
436 | JOIN pg_catalog.pg_class AS r ON (c.conrelid=r.oid) |
||
437 | JOIN pg_catalog.pg_namespace AS ns ON (r.relnamespace=ns.oid) |
||
438 | WHERE |
||
439 | r.relname = '{$table}' AND ns.nspname='{$c_schema}'"; |
||
440 | |||
441 | $rs = $this->selectSet($sql); |
||
442 | |||
443 | if ($rs->EOF) { |
||
444 | $max_col = 0; |
||
1 ignored issue
–
show
|
|||
445 | } else { |
||
446 | $max_col = $rs->fields['nb']; |
||
447 | } |
||
448 | |||
449 | $sql = ' |
||
450 | SELECT |
||
451 | c.oid AS conid, c.contype, c.conname, pg_catalog.pg_get_constraintdef(c.oid, true) AS consrc, |
||
452 | ns1.nspname as p_schema, r1.relname as p_table, ns2.nspname as f_schema, |
||
453 | r2.relname as f_table, f1.attname as p_field, f1.attnum AS p_attnum, f2.attname as f_field, |
||
454 | f2.attnum AS f_attnum, pg_catalog.obj_description(c.oid, \'pg_constraint\') AS constcomment, |
||
455 | c.conrelid, c.confrelid |
||
456 | FROM |
||
457 | pg_catalog.pg_constraint AS c |
||
458 | JOIN pg_catalog.pg_class AS r1 ON (c.conrelid=r1.oid) |
||
459 | JOIN pg_catalog.pg_attribute AS f1 ON (f1.attrelid=r1.oid AND (f1.attnum=c.conkey[1]'; |
||
460 | for ($i = 2; $i <= $rs->fields['nb']; ++$i) { |
||
461 | $sql .= " OR f1.attnum=c.conkey[${i}]"; |
||
462 | } |
||
463 | $sql .= ')) |
||
464 | JOIN pg_catalog.pg_namespace AS ns1 ON r1.relnamespace=ns1.oid |
||
465 | LEFT JOIN ( |
||
466 | pg_catalog.pg_class AS r2 JOIN pg_catalog.pg_namespace AS ns2 ON (r2.relnamespace=ns2.oid) |
||
467 | ) ON (c.confrelid=r2.oid) |
||
468 | LEFT JOIN pg_catalog.pg_attribute AS f2 ON |
||
469 | (f2.attrelid=r2.oid AND ((c.confkey[1]=f2.attnum AND c.conkey[1]=f1.attnum)'; |
||
470 | for ($i = 2; $i <= $rs->fields['nb']; ++$i) { |
||
471 | $sql .= " OR (c.confkey[${i}]=f2.attnum AND c.conkey[${i}]=f1.attnum)"; |
||
472 | } |
||
473 | |||
474 | $sql .= sprintf(")) |
||
1 ignored issue
–
show
|
|||
475 | WHERE |
||
476 | r1.relname = '%s' AND ns1.nspname='%s' |
||
477 | ORDER BY 1", $table, $c_schema); |
||
1 ignored issue
–
show
|
|||
478 | |||
479 | return $this->selectSet($sql); |
||
480 | } |
||
481 | |||
482 | // Constraint functions |
||
483 | |||
484 | /** |
||
485 | * Returns all sequences in the current database. |
||
486 | * |
||
487 | * @param bool $all |
||
488 | * |
||
489 | * @return \ADORecordSet A recordset |
||
490 | */ |
||
491 | public function getSequences($all = false) |
||
492 | { |
||
493 | $c_schema = $this->_schema; |
||
494 | $this->clean($c_schema); |
||
495 | if ($all) { |
||
496 | // Exclude pg_catalog and information_schema tables |
||
497 | $sql = "SELECT n.nspname, c.relname AS seqname, u.usename AS seqowner |
||
498 | FROM pg_catalog.pg_class c, pg_catalog.pg_user u, pg_catalog.pg_namespace n |
||
499 | WHERE c.relowner=u.usesysid AND c.relnamespace=n.oid |
||
500 | AND c.relkind = 'S' |
||
501 | AND n.nspname NOT IN ('pg_catalog', 'information_schema', 'pg_toast') |
||
502 | ORDER BY nspname, seqname"; |
||
503 | } else { |
||
504 | $sql = "SELECT c.relname AS seqname, u.usename AS seqowner, pg_catalog.obj_description(c.oid, 'pg_class') AS seqcomment |
||
505 | FROM pg_catalog.pg_class c, pg_catalog.pg_user u, pg_catalog.pg_namespace n |
||
506 | WHERE c.relowner=u.usesysid AND c.relnamespace=n.oid |
||
507 | AND c.relkind = 'S' AND n.nspname='{$c_schema}' ORDER BY seqname"; |
||
508 | } |
||
509 | |||
510 | return $this->selectSet($sql); |
||
511 | } |
||
512 | |||
513 | // Sequence functions |
||
514 | |||
515 | /** |
||
516 | * Returns all details for a particular function. |
||
517 | * |
||
518 | * @param $function_oid |
||
519 | * |
||
520 | * @return \ADORecordSet Function info |
||
521 | * |
||
522 | * @internal param string The $func name of the function to retrieve |
||
523 | */ |
||
524 | public function getFunction($function_oid) |
||
525 | { |
||
526 | $this->clean($function_oid); |
||
527 | |||
528 | $sql = " |
||
529 | SELECT |
||
530 | pc.oid AS prooid, |
||
531 | proname, |
||
532 | pg_catalog.pg_get_userbyid(proowner) AS proowner, |
||
533 | nspname as proschema, |
||
534 | lanname as prolanguage, |
||
535 | pg_catalog.format_type(prorettype, NULL) as proresult, |
||
536 | prosrc, |
||
537 | probin, |
||
538 | proretset, |
||
539 | proisstrict, |
||
540 | provolatile, |
||
541 | prosecdef, |
||
542 | pg_catalog.oidvectortypes(pc.proargtypes) AS proarguments, |
||
543 | pg_catalog.obj_description(pc.oid, 'pg_proc') AS procomment |
||
544 | FROM |
||
545 | pg_catalog.pg_proc pc, pg_catalog.pg_language pl, pg_catalog.pg_namespace n |
||
546 | WHERE |
||
547 | pc.oid = '${function_oid}'::oid |
||
548 | AND pc.prolang = pl.oid |
||
549 | AND n.oid = pc.pronamespace |
||
550 | "; |
||
551 | |||
552 | return $this->selectSet($sql); |
||
553 | } |
||
554 | |||
555 | // Function functions |
||
556 | |||
557 | /** |
||
558 | * Returns a list of all casts in the database. |
||
559 | * |
||
560 | * @return All casts |
||
561 | */ |
||
562 | public function getCasts() |
||
563 | { |
||
564 | $conf = $this->conf; |
||
565 | |||
566 | if ($conf['show_system']) { |
||
567 | $where = ''; |
||
568 | } else { |
||
569 | $where = " |
||
570 | AND n1.nspname NOT LIKE 'pg\\\\_%' |
||
571 | AND n2.nspname NOT LIKE 'pg\\\\_%' |
||
572 | AND n3.nspname NOT LIKE 'pg\\\\_%' |
||
573 | "; |
||
574 | } |
||
575 | |||
576 | $sql = " |
||
577 | SELECT |
||
578 | c.castsource::pg_catalog.regtype AS castsource, |
||
579 | c.casttarget::pg_catalog.regtype AS casttarget, |
||
580 | CASE WHEN c.castfunc=0 THEN NULL |
||
581 | ELSE c.castfunc::pg_catalog.regprocedure END AS castfunc, |
||
582 | c.castcontext, |
||
583 | obj_description(c.oid, 'pg_cast') as castcomment |
||
584 | FROM |
||
585 | (pg_catalog.pg_cast c LEFT JOIN pg_catalog.pg_proc p ON c.castfunc=p.oid JOIN pg_catalog.pg_namespace n3 ON p.pronamespace=n3.oid), |
||
586 | pg_catalog.pg_type t1, |
||
587 | pg_catalog.pg_type t2, |
||
588 | pg_catalog.pg_namespace n1, |
||
589 | pg_catalog.pg_namespace n2 |
||
590 | WHERE |
||
591 | c.castsource=t1.oid |
||
592 | AND c.casttarget=t2.oid |
||
593 | AND t1.typnamespace=n1.oid |
||
594 | AND t2.typnamespace=n2.oid |
||
595 | {$where} |
||
596 | ORDER BY 1, 2 |
||
597 | "; |
||
598 | |||
599 | return $this->selectSet($sql); |
||
600 | } |
||
601 | |||
602 | public function hasAlterColumnType() |
||
603 | { |
||
604 | return false; |
||
605 | } |
||
606 | |||
607 | // Capabilities |
||
608 | |||
609 | public function hasCreateFieldWithConstraints() |
||
1 ignored issue
–
show
|
|||
610 | { |
||
611 | return false; |
||
612 | } |
||
613 | |||
614 | public function hasAlterDatabaseOwner() |
||
615 | { |
||
616 | return false; |
||
617 | } |
||
618 | |||
619 | public function hasAlterSchemaOwner() |
||
620 | { |
||
621 | return false; |
||
622 | } |
||
623 | |||
624 | public function hasFunctionAlterOwner() |
||
625 | { |
||
626 | return false; |
||
627 | } |
||
628 | |||
629 | public function hasNamedParams() |
||
630 | { |
||
631 | return false; |
||
632 | } |
||
633 | |||
634 | public function hasQueryCancel() |
||
635 | { |
||
636 | return false; |
||
637 | } |
||
638 | |||
639 | public function hasTablespaces() |
||
640 | { |
||
641 | return false; |
||
642 | } |
||
643 | |||
644 | public function hasMagicTypes() |
||
645 | { |
||
646 | return false; |
||
647 | } |
||
648 | |||
649 | /** |
||
650 | * Protected method which alter a table |
||
651 | * SHOULDN'T BE CALLED OUTSIDE OF A TRANSACTION. |
||
652 | * |
||
653 | * @param $tblrs The table recordSet returned by getTable() |
||
654 | * @param $name The new name for the table |
||
655 | * @param $owner The new owner for the table |
||
656 | * @param $schema The new schema for the table |
||
657 | * @param $comment The comment on the table |
||
658 | * @param $tablespace The new tablespace for the table ('' means leave as is) |
||
659 | * |
||
660 | * @return int 0 success |
||
661 | */ |
||
662 | protected function _alterTable($tblrs, $name, $owner, $schema, $comment, $tablespace) |
||
688 | } |
||
689 | } |
||
690 |