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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (hide 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 cvsjoko 1.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