/[cvs]/nfo/php/libs/net.php.pear/DB/pgsql.php
ViewVC logotype

Contents of /nfo/php/libs/net.php.pear/DB/pgsql.php

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (show annotations)
Tue Oct 29 19:11:41 2002 UTC (21 years, 8 months ago) by cvsjoko
Branch: MAIN
CVS Tags: HEAD
+ new pear-libraries

1 <?php
2 //
3 // +----------------------------------------------------------------------+
4 // | PHP Version 4 |
5 // +----------------------------------------------------------------------+
6 // | Copyright (c) 1997-2002 The PHP Group |
7 // +----------------------------------------------------------------------+
8 // | This source file is subject to version 2.02 of the PHP license, |
9 // | that is bundled with this package in the file LICENSE, and is |
10 // | available at through the world-wide-web at |
11 // | http://www.php.net/license/2_02.txt. |
12 // | If you did not receive a copy of the PHP license and are unable to |
13 // | obtain it through the world-wide-web, please send a note to |
14 // | license@php.net so we can mail you a copy immediately. |
15 // +----------------------------------------------------------------------+
16 // | Authors: Rui Hirokawa <rui_hirokawa@ybb.ne.jp> |
17 // | Stig Bakken <ssb@fast.no> |
18 // +----------------------------------------------------------------------+
19 //
20 // $Id: pgsql.php,v 1.65.2.3 2002/04/10 08:38:42 edink Exp $
21 //
22 // Database independent query interface definition for PHP's PostgreSQL
23 // extension.
24 //
25
26 //
27 // XXX legend:
28 //
29 // XXX ERRORMSG: The error message from the pgsql function should
30 // be registered here.
31 //
32
33 require_once 'DB/common.php';
34
35 class DB_pgsql extends DB_common
36 {
37 // {{{ properties
38
39 var $connection;
40 var $phptype, $dbsyntax;
41 var $prepare_tokens = array();
42 var $prepare_types = array();
43 var $transaction_opcount = 0;
44 var $dsn = array();
45 var $row = array();
46 var $num_rows = array();
47 var $affected = 0;
48 var $autocommit = true;
49 var $fetchmode = DB_FETCHMODE_ORDERED;
50
51 // }}}
52 // {{{ constructor
53
54 function DB_pgsql()
55 {
56 $this->DB_common();
57 $this->phptype = 'pgsql';
58 $this->dbsyntax = 'pgsql';
59 $this->features = array(
60 'prepare' => false,
61 'pconnect' => true,
62 'transactions' => true,
63 'limit' => 'alter'
64 );
65 $this->errorcode_map = array(
66 );
67 }
68
69 // }}}
70 // {{{ connect()
71
72 /**
73 * Connect to a database and log in as the specified user.
74 *
75 * @param $dsn the data source name (see DB::parseDSN for syntax)
76 * @param $persistent (optional) whether the connection should
77 * be persistent
78 *
79 * @return int DB_OK on success, a DB error code on failure
80 */
81 function connect($dsninfo, $persistent = false)
82 {
83 if (!DB::assertExtension('pgsql'))
84 return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
85
86 $this->dsn = $dsninfo;
87 $protocol = (isset($dsninfo['protocol'])) ? $dsninfo['protocol'] : 'tcp';
88 $connstr = '';
89
90 if ($protocol == 'tcp') {
91 if ($dsninfo['hostspec']) {
92 $connstr = 'host=' . $dsninfo['hostspec'];
93 }
94 if ($dsninfo['port']) {
95 $connstr .= ' port=' . $dsninfo['port'];
96 }
97 }
98
99 if (isset($dsninfo['database'])) {
100 $connstr .= ' dbname=' . $dsninfo['database'];
101 }
102 if (!empty($dsninfo['username'])) {
103 $connstr .= ' user=' . $dsninfo['username'];
104 }
105 if (!empty($dsninfo['password'])) {
106 $connstr .= ' password=' . $dsninfo['password'];
107 }
108 if (!empty($dsninfo['options'])) {
109 $connstr .= ' options=' . $dsninfo['options'];
110 }
111 if (!empty($dsninfo['tty'])) {
112 $connstr .= ' tty=' . $dsninfo['tty'];
113 }
114
115 $connect_function = $persistent ? 'pg_pconnect' : 'pg_connect';
116 // catch error
117 ob_start();
118 $conn = $connect_function($connstr);
119 $error = ob_get_contents();
120 ob_end_clean();
121 if ($conn == false) {
122 return $this->raiseError(DB_ERROR_CONNECT_FAILED, null,
123 null, null, strip_tags($error));
124 }
125 $this->connection = $conn;
126 return DB_OK;
127 }
128
129 // }}}
130 // {{{ disconnect()
131
132 /**
133 * Log out and disconnect from the database.
134 *
135 * @return bool TRUE on success, FALSE if not connected.
136 */
137 function disconnect()
138 {
139 $ret = @pg_close($this->connection); // XXX ERRORMSG
140 $this->connection = null;
141 return $ret;
142 }
143
144 // }}}
145 // {{{ simpleQuery()
146
147 /**
148 * Send a query to PostgreSQL and return the results as a
149 * PostgreSQL resource identifier.
150 *
151 * @param $query the SQL query
152 *
153 * @return int returns a valid PostgreSQL result for successful SELECT
154 * queries, DB_OK for other successful queries. A DB error code
155 * is returned on failure.
156 */
157 function simpleQuery($query)
158 {
159 $ismanip = DB::isManip($query);
160 $this->last_query = $query;
161 $query = $this->modifyQuery($query);
162 if (!$this->autocommit && $ismanip) {
163 if ($this->transaction_opcount == 0) {
164 $result = @pg_exec($this->connection, "begin;");
165 if (!$result) {
166 return $this->pgsqlRaiseError();
167 }
168 }
169 $this->transaction_opcount++;
170 }
171 $result = @pg_exec($this->connection, $query);
172 if (!$result) {
173 return $this->pgsqlRaiseError();
174 }
175 // Determine which queries that should return data, and which
176 // should return an error code only.
177 if ($ismanip) {
178 $this->affected = @pg_cmdtuples($result);
179 return DB_OK;
180 } elseif (preg_match('/^\s*\(?\s*SELECT\s+/si', $query) &&
181 !preg_match('/^\s*\(?\s*SELECT\s+INTO\s/si', $query)) {
182 /* PostgreSQL commands:
183 ABORT, ALTER, BEGIN, CLOSE, CLUSTER, COMMIT, COPY,
184 CREATE, DECLARE, DELETE, DROP TABLE, EXPLAIN, FETCH,
185 GRANT, INSERT, LISTEN, LOAD, LOCK, MOVE, NOTIFY, RESET,
186 REVOKE, ROLLBACK, SELECT, SELECT INTO, SET, SHOW,
187 UNLISTEN, UPDATE, VACUUM
188 */
189 $this->row[$result] = 0; // reset the row counter.
190 $numrows = $this->numrows($result);
191 if (is_object($numrows)) {
192 return $numrows;
193 }
194 $this->num_rows[$result] = $numrows;
195 $this->affected = 0;
196 return $result;
197 } else {
198 $this->affected = 0;
199 return DB_OK;
200 }
201 }
202
203 // }}}
204 // {{{ nextResult()
205
206 /**
207 * Move the internal pgsql result pointer to the next available result
208 *
209 * @param a valid fbsql result resource
210 *
211 * @access public
212 *
213 * @return true if a result is available otherwise return false
214 */
215 function nextResult($result)
216 {
217 return false;
218 }
219
220 // }}}
221 // {{{ errorCode()
222
223 /**
224 * Map native error codes to DB's portable ones. Requires that
225 * the DB implementation's constructor fills in the $errorcode_map
226 * property.
227 *
228 * @param $nativecode the native error code, as returned by the backend
229 * database extension (string or integer)
230 *
231 * @return int a portable DB error code, or FALSE if this DB
232 * implementation has no mapping for the given error code.
233 */
234
235 function errorCode($errormsg)
236 {
237 static $error_regexps;
238 if (empty($error_regexps)) {
239 $error_regexps = array(
240 '/(Table does not exist\.|Relation [\"\'].*[\"\'] does not exist|sequence does not exist|class ".+" not found)$/' => DB_ERROR_NOSUCHTABLE,
241 '/Relation [\"\'].*[\"\'] already exists|Cannot insert a duplicate key into (a )?unique index.*/' => DB_ERROR_ALREADY_EXISTS,
242 '/divide by zero$/' => DB_ERROR_DIVZERO,
243 '/pg_atoi: error in .*: can\'t parse /' => DB_ERROR_INVALID_NUMBER,
244 '/ttribute [\"\'].*[\"\'] not found$|Relation [\"\'].*[\"\'] does not have attribute [\"\'].*[\"\']/' => DB_ERROR_NOSUCHFIELD,
245 '/parser: parse error at or near \"/' => DB_ERROR_SYNTAX,
246 '/referential integrity violation/' => DB_ERROR_CONSTRAINT
247 );
248 }
249 foreach ($error_regexps as $regexp => $code) {
250 if (preg_match($regexp, $errormsg)) {
251 return $code;
252 }
253 }
254 // Fall back to DB_ERROR if there was no mapping.
255 return DB_ERROR;
256 }
257
258 // }}}
259 /**
260 * Fetch and return a row of data (it uses fetchInto for that)
261 * @param $result PostgreSQL result identifier
262 * @param $fetchmode format of fetched row array
263 * @param $rownum the absolute row number to fetch
264 *
265 * @return array a row of data, or false on error
266 */
267 function fetchRow($result, $fetchmode = DB_FETCHMODE_DEFAULT, $rownum=null)
268 {
269 if ($fetchmode == DB_FETCHMODE_DEFAULT) {
270 $fetchmode = $this->fetchmode;
271 }
272 $res = $this->fetchInto ($result, $arr, $fetchmode, $rownum);
273 if ($res !== DB_OK) {
274 return $res;
275 }
276 return $arr;
277 }
278
279 // {{{ fetchInto()
280
281 /**
282 * Fetch a row and insert the data into an existing array.
283 *
284 * @param $result PostgreSQL result identifier
285 * @param $row (reference) array where data from the row is stored
286 * @param $fetchmode how the array data should be indexed
287 * @param $rownum the row number to fetch
288 *
289 * @return int DB_OK on success, a DB error code on failure
290 */
291 function fetchInto($result, &$row, $fetchmode, $rownum=null)
292 {
293 $rownum = ($rownum !== null) ? $rownum : $this->row[$result];
294 if ($rownum >= $this->num_rows[$result]) {
295 return null;
296 }
297 if ($fetchmode & DB_FETCHMODE_ASSOC) {
298 $row = @pg_fetch_array($result, $rownum, PGSQL_ASSOC);
299 } else {
300 $row = @pg_fetch_row($result, $rownum);
301 }
302 if (!$row) {
303 $err = pg_errormessage($this->connection);
304 if (!$err) {
305 return null;
306 }
307 return $this->pgsqlRaiseError();
308 }
309 $this->row[$result] = ++$rownum;
310 return DB_OK;
311 }
312
313 // }}}
314 // {{{ freeResult()
315
316 /**
317 * Free the internal resources associated with $result.
318 *
319 * @param $result int PostgreSQL result identifier or DB statement identifier
320 *
321 * @return bool TRUE on success, FALSE if $result is invalid
322 */
323 function freeResult($result)
324 {
325 if (is_resource($result)) {
326 return @pg_freeresult($result);
327 }
328 if (!isset($this->prepare_tokens[(int)$result])) {
329 return false;
330 }
331 unset($this->prepare_tokens[(int)$result]);
332 unset($this->prepare_types[(int)$result]);
333 unset($this->row[(int)$result]);
334 unset($this->num_rows[(int)$result]);
335 $this->affected = 0;
336 return true;
337 }
338
339 // }}}
340 // {{{ quote()
341 /**
342 * Quote the given string so it can be safely used within string delimiters
343 * in a query.
344 * @param $string mixed Data to be quoted
345 * @return mixed "NULL" string, quoted string or original data
346 */
347 function quote($str = null)
348 {
349 switch (strtolower(gettype($str))) {
350 case 'null':
351 return 'NULL';
352 case 'integer':
353 case 'double' :
354 return $str;
355 case 'string':
356 default:
357 $str = str_replace("'", "''", $str);
358 //PostgreSQL treats a backslash as an escape character.
359 $str = str_replace('\\', '\\\\', $str);
360 return "'$str'";
361 }
362 }
363 // }}}
364 // {{{ numCols()
365
366 /**
367 * Get the number of columns in a result set.
368 *
369 * @param $result resource PostgreSQL result identifier
370 *
371 * @return int the number of columns per row in $result
372 */
373 function numCols($result)
374 {
375 $cols = @pg_numfields($result);
376 if (!$cols) {
377 return $this->pgsqlRaiseError();
378 }
379 return $cols;
380 }
381
382 // }}}
383 // {{{ numRows()
384
385 /**
386 * Get the number of rows in a result set.
387 *
388 * @param $result resource PostgreSQL result identifier
389 *
390 * @return int the number of rows in $result
391 */
392 function numRows($result)
393 {
394 $rows = @pg_numrows($result);
395 if ($rows === null) {
396 return $this->pgsqlRaiseError();
397 }
398 return $rows;
399 }
400
401 // }}}
402 // {{{ errorNative()
403
404 /**
405 * Get the native error code of the last error (if any) that
406 * occured on the current connection.
407 *
408 * @return int native PostgreSQL error code
409 */
410 function errorNative()
411 {
412 return pg_errormessage($this->connection);
413 }
414
415 // }}}
416 // {{{ autoCommit()
417
418 /**
419 * Enable/disable automatic commits
420 */
421 function autoCommit($onoff = false)
422 {
423 // XXX if $this->transaction_opcount > 0, we should probably
424 // issue a warning here.
425 $this->autocommit = $onoff ? true : false;
426 return DB_OK;
427 }
428
429 // }}}
430 // {{{ commit()
431
432 /**
433 * Commit the current transaction.
434 */
435 function commit()
436 {
437 if ($this->transaction_opcount > 0) {
438 // (disabled) hack to shut up error messages from libpq.a
439 //@fclose(@fopen("php://stderr", "w"));
440 $result = @pg_exec($this->connection, "end;");
441 $this->transaction_opcount = 0;
442 if (!$result) {
443 return $this->pgsqlRaiseError();
444 }
445 }
446 return DB_OK;
447 }
448
449 // }}}
450 // {{{ rollback()
451
452 /**
453 * Roll back (undo) the current transaction.
454 */
455 function rollback()
456 {
457 if ($this->transaction_opcount > 0) {
458 $result = @pg_exec($this->connection, "abort;");
459 $this->transaction_opcount = 0;
460 if (!$result) {
461 return $this->pgsqlRaiseError();
462 }
463 }
464 return DB_OK;
465 }
466
467 // }}}
468 // {{{ affectedRows()
469
470 /**
471 * Gets the number of rows affected by the last query.
472 * if the last query was a select, returns 0.
473 *
474 * @return int number of rows affected by the last query or DB_ERROR
475 */
476 function affectedRows()
477 {
478 return $this->affected;
479 }
480 // }}}
481 // {{{ nextId()
482
483 /**
484 * Get the next value in a sequence.
485 *
486 * We are using native PostgreSQL sequences. If a sequence does
487 * not exist, it will be created, unless $ondemand is false.
488 *
489 * @access public
490 * @param string $seq_name the name of the sequence
491 * @param bool $ondemand whether to create the sequence on demand
492 * @return a sequence integer, or a DB error
493 */
494 function nextId($seq_name, $ondemand = true)
495 {
496 $seqname = $this->getSequenceName($seq_name);
497 $repeat = 0;
498 do {
499 $this->pushErrorHandling(PEAR_ERROR_RETURN);
500 $result = $this->query("SELECT NEXTVAL('${seqname}')");
501 $this->popErrorHandling();
502 if ($ondemand && DB::isError($result) &&
503 $result->getCode() == DB_ERROR_NOSUCHTABLE) {
504 $repeat = 1;
505 $result = $this->createSequence($seq_name);
506 if (DB::isError($result)) {
507 return $this->raiseError($result);
508 }
509 } else {
510 $repeat = 0;
511 }
512 } while ($repeat);
513 if (DB::isError($result)) {
514 return $this->raiseError($result);
515 }
516 $arr = $result->fetchRow(DB_FETCHMODE_ORDERED);
517 $result->free();
518 return $arr[0];
519 }
520
521 // }}}
522 // {{{ createSequence()
523
524 /**
525 * Create the sequence
526 *
527 * @param string $seq_name the name of the sequence
528 * @return mixed DB_OK on success or DB error on error
529 * @access public
530 */
531 function createSequence($seq_name)
532 {
533 $seqname = $this->getSequenceName($seq_name);
534 $this->pushErrorHandling(PEAR_ERROR_RETURN);
535 $result = $this->query("CREATE SEQUENCE ${seqname}");
536 $this->popErrorHandling();
537 return $result;
538 }
539
540 // }}}
541 // {{{ dropSequence()
542
543 /**
544 * Drop a sequence
545 *
546 * @param string $seq_name the name of the sequence
547 * @return mixed DB_OK on success or DB error on error
548 * @access public
549 */
550 function dropSequence($seq_name)
551 {
552 $seqname = $this->getSequenceName($seq_name);
553 return $this->query("DROP SEQUENCE ${seqname}");
554 }
555
556 // }}}
557 // {{{ modifyLimitQuery()
558
559 function modifyLimitQuery($query, $from, $count)
560 {
561 $query = $query . " LIMIT $count, $from";
562 return $query;
563 }
564
565 // }}}
566 // {{{ pgsqlRaiseError()
567
568 function pgsqlRaiseError($errno = null)
569 {
570 $native = $this->errorNative();
571 if ($errno === null) {
572 $err = $this->errorCode($native);
573 } else {
574 $err = $errno;
575 }
576 return $this->raiseError($err, null, null, null, $native);
577 }
578
579 // }}}
580 // {{{ _pgFieldFlags()
581
582 /**
583 * Flags of a Field
584 *
585 * @param int $resource PostgreSQL result identifier
586 * @param int $num_field the field number
587 *
588 * @return string The flags of the field ("not_null", "default_xx", "primary_key",
589 * "unique" and "multiple_key" are supported)
590 * @access private
591 */
592 function _pgFieldFlags($resource, $num_field, $table_name)
593 {
594 $field_name = @pg_fieldname($resource, $num_field);
595
596 $result = pg_exec($this->connection, "SELECT f.attnotnull, f.atthasdef
597 FROM pg_attribute f, pg_class tab, pg_type typ
598 WHERE tab.relname = typ.typname
599 AND typ.typrelid = f.attrelid
600 AND f.attname = '$field_name'
601 AND tab.relname = '$table_name'");
602 if (pg_numrows($result) > 0) {
603 $row = pg_fetch_row($result, 0);
604 $flags = ($row[0] == 't') ? 'not_null ' : '';
605
606 if ($row[1] == 't') {
607 $result = pg_exec($this->connection, "SELECT a.adsrc
608 FROM pg_attribute f, pg_class tab, pg_type typ, pg_attrdef a
609 WHERE tab.relname = typ.typname AND typ.typrelid = f.attrelid
610 AND f.attrelid = a.adrelid AND f.attname = '$field_name'
611 AND tab.relname = '$table_name'");
612 $row = pg_fetch_row($result, 0);
613 $num = str_replace('\'', '', $row[0]);
614
615 $flags .= "default_$num ";
616 }
617 }
618 $result = pg_exec($this->connection, "SELECT i.indisunique, i.indisprimary, i.indkey
619 FROM pg_attribute f, pg_class tab, pg_type typ, pg_index i
620 WHERE tab.relname = typ.typname
621 AND typ.typrelid = f.attrelid
622 AND f.attrelid = i.indrelid
623 AND f.attname = '$field_name'
624 AND tab.relname = '$table_name'");
625 $count = pg_numrows($result);
626
627 for ($i = 0; $i < $count ; $i++) {
628 $row = pg_fetch_row($result, $i);
629 $keys = explode(" ", $row[2]);
630
631 if (in_array($num_field + 1, $keys)) {
632 $flags .= ($row[0] == 't') ? 'unique ' : '';
633 $flags .= ($row[1] == 't') ? 'primary ' : '';
634 if (count($keys) > 1)
635 $flags .= 'multiple_key ';
636 }
637 }
638
639 return trim($flags);
640 }
641
642 // }}}
643 // {{{ tableInfo()
644
645 /**
646 * Returns information about a table or a result set
647 *
648 * NOTE: doesn't support table name and flags if called from a db_result
649 *
650 * @param mixed $resource PostgreSQL result identifier or table name
651 * @param int $mode A valid tableInfo mode (DB_TABLEINFO_ORDERTABLE or
652 * DB_TABLEINFO_ORDER)
653 *
654 * @return array An array with all the information
655 */
656 function tableInfo($result, $mode = null)
657 {
658 $count = 0;
659 $id = 0;
660 $res = array();
661
662 /*
663 * depending on $mode, metadata returns the following values:
664 *
665 * - mode is false (default):
666 * $result[]:
667 * [0]["table"] table name
668 * [0]["name"] field name
669 * [0]["type"] field type
670 * [0]["len"] field length
671 * [0]["flags"] field flags
672 *
673 * - mode is DB_TABLEINFO_ORDER
674 * $result[]:
675 * ["num_fields"] number of metadata records
676 * [0]["table"] table name
677 * [0]["name"] field name
678 * [0]["type"] field type
679 * [0]["len"] field length
680 * [0]["flags"] field flags
681 * ["order"][field name] index of field named "field name"
682 * The last one is used, if you have a field name, but no index.
683 * Test: if (isset($result['meta']['myfield'])) { ...
684 *
685 * - mode is DB_TABLEINFO_ORDERTABLE
686 * the same as above. but additionally
687 * ["ordertable"][table name][field name] index of field
688 * named "field name"
689 *
690 * this is, because if you have fields from different
691 * tables with the same field name * they override each
692 * other with DB_TABLEINFO_ORDER
693 *
694 * you can combine DB_TABLEINFO_ORDER and
695 * DB_TABLEINFO_ORDERTABLE with DB_TABLEINFO_ORDER |
696 * DB_TABLEINFO_ORDERTABLE * or with DB_TABLEINFO_FULL
697 */
698
699 // if $result is a string, then we want information about a
700 // table without a resultset
701
702 if (is_string($result)) {
703 $id = pg_exec($this->connection,"SELECT * FROM $result");
704 if (empty($id)) {
705 return $this->pgsqlRaiseError();
706 }
707 } else { // else we want information about a resultset
708 $id = $result;
709 if (empty($id)) {
710 return $this->pgsqlRaiseError();
711 }
712 }
713
714 $count = @pg_numfields($id);
715
716 // made this IF due to performance (one if is faster than $count if's)
717 if (empty($mode)) {
718
719 for ($i=0; $i<$count; $i++) {
720 $res[$i]['table'] = (is_string($result)) ? $result : '';
721 $res[$i]['name'] = @pg_fieldname ($id, $i);
722 $res[$i]['type'] = @pg_fieldtype ($id, $i);
723 $res[$i]['len'] = @pg_fieldsize ($id, $i);
724 $res[$i]['flags'] = (is_string($result)) ? $this->_pgFieldflags($id, $i, $result) : '';
725 }
726
727 } else { // full
728 $res["num_fields"]= $count;
729
730 for ($i=0; $i<$count; $i++) {
731 $res[$i]['table'] = (is_string($result)) ? $result : '';
732 $res[$i]['name'] = @pg_fieldname ($id, $i);
733 $res[$i]['type'] = @pg_fieldtype ($id, $i);
734 $res[$i]['len'] = @pg_fieldsize ($id, $i);
735 $res[$i]['flags'] = (is_string($result)) ? $this->_pgFieldFlags($id, $i, $result) : '';
736 if ($mode & DB_TABLEINFO_ORDER) {
737 $res['order'][$res[$i]['name']] = $i;
738 }
739 if ($mode & DB_TABLEINFO_ORDERTABLE) {
740 $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
741 }
742 }
743 }
744
745 // free the result only if we were called on a table
746 if (is_resource($id)) {
747 @pg_freeresult($id);
748 }
749 return $res;
750 }
751
752 // }}}
753 // {{{ getTablesQuery()
754
755 /**
756 * Returns the query needed to get some backend info
757 * @param string $type What kind of info you want to retrieve
758 * @return string The SQL query string
759 */
760 function getSpecialQuery($type)
761 {
762 switch ($type) {
763 case 'tables': {
764 $sql = "SELECT c.relname as \"Name\"
765 FROM pg_class c, pg_user u
766 WHERE c.relowner = u.usesysid AND c.relkind = 'r'
767 AND not exists (select 1 from pg_views where viewname = c.relname)
768 AND c.relname !~ '^pg_'
769 UNION
770 SELECT c.relname as \"Name\"
771 FROM pg_class c
772 WHERE c.relkind = 'r'
773 AND not exists (select 1 from pg_views where viewname = c.relname)
774 AND not exists (select 1 from pg_user where usesysid = c.relowner)
775 AND c.relname !~ '^pg_'";
776 break;
777 }
778 case 'views': {
779 // Table cols: viewname | viewowner | definition
780 $sql = "SELECT viewname FROM pg_views";
781 break;
782 }
783 case 'users': {
784 // cols: usename |usesysid|usecreatedb|usetrace|usesuper|usecatupd|passwd |valuntil
785 $sql = 'SELECT usename FROM pg_user';
786 break;
787 }
788 case 'databases': {
789 $sql = 'SELECT datname FROM pg_database';
790 break;
791 }
792 case 'functions': {
793 $sql = 'SELECT proname FROM pg_proc';
794 break;
795 }
796 default:
797 return null;
798 }
799 return $sql;
800 }
801
802 // }}}
803
804 }
805
806 // Local variables:
807 // tab-width: 4
808 // c-basic-offset: 4
809 // End:
810 ?>

MailToCvsAdmin">MailToCvsAdmin
ViewVC Help
Powered by ViewVC 1.1.26 RSS 2.0 feed