Pgsql.php 11 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
<?php
/*
 *  $Id$
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * This software consists of voluntary contributions made by many individuals
 * and is licensed under the LGPL. For more information, see
 * <http://www.phpdoctrine.com>.
 */
Doctrine::autoload('Doctrine_Import');
/**
 * @package     Doctrine
24
 * @subpackage  Import
25 26 27 28 29 30 31 32
 * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
 * @author      Konsta Vesterinen <kvesteri@cc.hut.fi>
 * @author      Paul Cooper <pgc@ucecom.com>
 * @author      Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
 * @version     $Revision$
 * @link        www.phpdoctrine.com
 * @since       1.0
 */
lsmith's avatar
lsmith committed
33 34 35
class Doctrine_Import_Pgsql extends Doctrine_Import
{

zYne's avatar
zYne committed
36 37
    protected $sql = array(
                        'listDatabases' => 'SELECT datname FROM pg_database',
38
                        'listFunctions' => "SELECT
zYne's avatar
zYne committed
39 40 41 42 43 44 45 46 47
                                                proname
                                            FROM
                                                pg_proc pr,
                                                pg_type tp
                                            WHERE
                                                tp.oid = pr.prorettype
                                                AND pr.proisagg = FALSE
                                                AND tp.typname <> 'trigger'
                                                AND pr.pronamespace IN
lsmith's avatar
lsmith committed
48
                                                    (SELECT oid FROM pg_namespace
zYne's avatar
zYne committed
49
                                                     WHERE nspname NOT LIKE 'pg_%' AND nspname != 'information_schema'",
50
                        'listSequences' => "SELECT
lsmith's avatar
lsmith committed
51 52 53
                                                relname
                                            FROM
                                                pg_class
zYne's avatar
zYne committed
54 55 56
                                            WHERE relkind = 'S' AND relnamespace IN
                                                (SELECT oid FROM pg_namespace
                                                 WHERE nspname NOT LIKE 'pg_%' AND nspname != 'information_schema')",
57
                        'listTables'    => "SELECT
zYne's avatar
zYne committed
58 59
                                                c.relname AS table_name
                                            FROM pg_class c, pg_user u
lsmith's avatar
lsmith committed
60
                                            WHERE c.relowner = u.usesysid
zYne's avatar
zYne committed
61 62 63 64 65 66 67 68 69 70 71
                                                AND c.relkind = 'r'
                                                AND NOT EXISTS (SELECT 1 FROM pg_views WHERE viewname = c.relname)
                                                AND c.relname !~ '^(pg_|sql_)'
                                            UNION
                                            SELECT c.relname AS table_name
                                            FROM pg_class c
                                            WHERE c.relkind = 'r'
                                                AND NOT EXISTS (SELECT 1 FROM pg_views WHERE viewname = c.relname)
                                                AND NOT EXISTS (SELECT 1 FROM pg_user WHERE usesysid = c.relowner)
                                                AND c.relname !~ '^pg_'",
                        'listViews'     => 'SELECT viewname FROM pg_views',
72 73 74
                        'listUsers'     => 'SELECT usename FROM pg_user',
                        'listTableConstraints' => "SELECT
                                                        relname
lsmith's avatar
lsmith committed
75 76
                                                   FROM
                                                        pg_class
77 78 79
                                                   WHERE oid IN (
                                                        SELECT indexrelid
                                                        FROM pg_index, pg_class
lsmith's avatar
lsmith committed
80 81
                                                        WHERE pg_class.relname = %s
                                                            AND pg_class.oid = pg_index.indrelid
82 83 84 85 86 87 88
                                                            AND (indisunique = 't' OR indisprimary = 't')
                                                        )",
                        'listTableIndexes'     => "SELECT
                                                        relname
                                                   FROM
                                                        pg_class
                                                   WHERE oid IN (
lsmith's avatar
lsmith committed
89
                                                        SELECT indexrelid
90
                                                        FROM pg_index, pg_class
zYne's avatar
zYne committed
91
                                                        WHERE pg_class.relname = %s
lsmith's avatar
lsmith committed
92 93
                                                            AND pg_class.oid=pg_index.indrelid
                                                            AND indisunique != 't'
94 95 96
                                                            AND indisprimary != 't'
                                                        )",
                        'listTableColumns'     => "SELECT
lsmith's avatar
lsmith committed
97 98 99
                                                        a.attnum,
                                                        a.attname AS field,
                                                        t.typname AS type,
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
                                                        format_type(a.atttypid, a.atttypmod) AS complete_type,
                                                        a.attnotnull AS isnotnull,
                                                        (SELECT 't'
                                                          FROM pg_index
                                                          WHERE c.oid = pg_index.indrelid
                                                          AND pg_index.indkey[0] = a.attnum
                                                          AND pg_index.indisprimary = 't'
                                                        ) AS pri,
                                                        (SELECT pg_attrdef.adsrc
                                                          FROM pg_attrdef
                                                          WHERE c.oid = pg_attrdef.adrelid
                                                          AND pg_attrdef.adnum=a.attnum
                                                        ) AS default
                                                  FROM pg_attribute a, pg_class c, pg_type t
                                                  WHERE c.relname = %s
                                                        AND a.attnum > 0
                                                        AND a.attrelid = c.oid
                                                        AND a.atttypid = t.oid
                                                  ORDER BY a.attnum",
zYne's avatar
zYne committed
119
                        );
120

121 122 123 124 125 126
    /**
     * lists all database triggers
     *
     * @param string|null $database
     * @return array
     */
lsmith's avatar
lsmith committed
127 128
    public function listTriggers($database = null)
    {
129 130

    }
131

132 133 134 135 136 137
    /**
     * lists table constraints
     *
     * @param string $table     database table name
     * @return array
     */
lsmith's avatar
lsmith committed
138 139
    public function listTableConstraints($table)
    {
140 141
        $table = $this->conn->quote($table);
        $query = sprintf($this->sql['listTableConstraints'], $table);
lsmith's avatar
lsmith committed
142

143 144
        return $this->conn->fetchColumn($query);
    }
145

146 147 148 149 150 151
    /**
     * lists table constraints
     *
     * @param string $table     database table name
     * @return array
     */
lsmith's avatar
lsmith committed
152 153
    public function listTableColumns($table)
    {
zYne's avatar
zYne committed
154 155 156
        $table = $this->conn->quote($table);
        $query = sprintf($this->sql['listTableColumns'], $table);
        $result = $this->conn->fetchAssoc($query);
157

158 159
        $columns     = array();
        foreach ($result as $key => $val) {
zYne's avatar
zYne committed
160 161 162
            $val = array_change_key_case($val, CASE_LOWER);

            if (strtolower($val['type']) === 'varchar') {
zYne's avatar
zYne committed
163
                // get length from varchar definition
164
                $length = preg_replace('~.*\(([0-9]*)\).*~', '$1', $val['complete_type']);
zYne's avatar
zYne committed
165
                $val['length'] = $length;
166
            }
zYne's avatar
zYne committed
167 168 169
            
            $decl = $this->conn->dataDict->getPortableDeclaration($val);

170
            $description = array(
zYne's avatar
zYne committed
171
                'name'      => $val['field'],
zYne's avatar
zYne committed
172 173 174
                'ntype'     => $val['type'],
                'type'      => $decl['type'][0],
                'alltypes'  => $decl['type'],
zYne's avatar
zYne committed
175 176 177 178 179 180
                'length'    => $decl['length'],
                'fixed'     => $decl['fixed'],
                'unsigned'  => $decl['unsigned'],
                'notnull'   => ($val['isnotnull'] == ''),
                'default'   => $val['default'],
                'primary'   => ($val['pri'] == 't'),
181
            );
zYne's avatar
zYne committed
182
            $columns[$val['field']] = $description;
183 184 185
        }
        return $columns;
    }
186

187 188 189 190 191 192
    /**
     * list all indexes in a table
     *
     * @param string $table     database table name
     * @return array
     */
lsmith's avatar
lsmith committed
193 194
    public function listTableIndexes($table)
    {
195 196
        $table = $this->conn->quote($table);
        $query = sprintf($this->sql['listTableIndexes'], $table);
197 198 199

        return $this->conn->fetchColumn($query);
    }
200

201 202 203 204 205 206
    /**
     * lists tables
     *
     * @param string|null $database
     * @return array
     */
lsmith's avatar
lsmith committed
207 208
    public function listTables($database = null)
    {
zYne's avatar
zYne committed
209
        return $this->conn->fetchColumn($this->sql['listTables']);
210
    }
211

212 213 214 215 216 217
    /**
     * lists table triggers
     *
     * @param string $table     database table name
     * @return array
     */
lsmith's avatar
lsmith committed
218 219
    public function listTableTriggers($table)
    {
zYne's avatar
zYne committed
220 221 222 223 224 225 226 227 228
        $query = 'SELECT trg.tgname AS trigger_name
                    FROM pg_trigger trg,
                         pg_class tbl
                   WHERE trg.tgrelid = tbl.oid';
        if ($table !== null) {
            $table = $this->conn->quote(strtoupper($table), 'string');
            $query .= " AND tbl.relname = $table";
        }
        return $this->conn->fetchColumn($query);
229
    }
230

231 232 233 234 235 236
    /**
     * list the views in the database that reference a given table
     *
     * @param string $table     database table name
     * @return array
     */
lsmith's avatar
lsmith committed
237 238
    public function listTableViews($table)
    {
239 240
        return $this->conn->fetchColumn($query);
    }
241
}