MDB2
[ class tree: MDB2 ] [ index: MDB2 ] [ all elements ]

Source for file pgsql.php

Documentation is available at pgsql.php

  1. <?php
  2. // +----------------------------------------------------------------------+
  3. // | PHP versions 4 and 5                                                 |
  4. // +----------------------------------------------------------------------+
  5. // | Copyright (c) 1998-2008 Manuel Lemos, Tomas V.V.Cox,                 |
  6. // | Stig. S. Bakken, Lukas Smith                                         |
  7. // | All rights reserved.                                                 |
  8. // +----------------------------------------------------------------------+
  9. // | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB  |
  10. // | API as well as database abstraction for PHP applications.            |
  11. // | This LICENSE is in the BSD license style.                            |
  12. // |                                                                      |
  13. // | Redistribution and use in source and binary forms, with or without   |
  14. // | modification, are permitted provided that the following conditions   |
  15. // | are met:                                                             |
  16. // |                                                                      |
  17. // | Redistributions of source code must retain the above copyright       |
  18. // | notice, this list of conditions and the following disclaimer.        |
  19. // |                                                                      |
  20. // | Redistributions in binary form must reproduce the above copyright    |
  21. // | notice, this list of conditions and the following disclaimer in the  |
  22. // | documentation and/or other materials provided with the distribution. |
  23. // |                                                                      |
  24. // | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken,    |
  25. // | Lukas Smith nor the names of his contributors may be used to endorse |
  26. // | or promote products derived from this software without specific prior|
  27. // | written permission.                                                  |
  28. // |                                                                      |
  29. // | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS  |
  30. // | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT    |
  31. // | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS    |
  32. // | FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE      |
  33. // | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,          |
  34. // | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
  35. // | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
  36. // |  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED  |
  37. // | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT          |
  38. // | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
  39. // | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE          |
  40. // | POSSIBILITY OF SUCH DAMAGE.                                          |
  41. // +----------------------------------------------------------------------+
  42. // | Author: Paul Cooper <pgc@ucecom.com>                                 |
  43. // +----------------------------------------------------------------------+
  44. //
  45. // $Id: pgsql.php 327310 2012-08-27 15:16:18Z danielc $
  46.  
  47. require_once 'MDB2/Driver/Manager/Common.php';
  48.  
  49. /**
  50.  * MDB2 MySQL driver for the management modules
  51.  *
  52.  * @package MDB2
  53.  * @category Database
  54.  * @author  Paul Cooper <pgc@ucecom.com>
  55.  */
  56. class MDB2_Driver_Manager_pgsql extends MDB2_Driver_Manager_Common
  57. {
  58.     // {{{ createDatabase()
  59.  
  60.     /**
  61.      * create a new database
  62.      *
  63.      * @param string $name    name of the database that should be created
  64.      * @param array  $options array with charset info
  65.      *
  66.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  67.      * @access public
  68.      */
  69.     function createDatabase($name$options = array())
  70.     {
  71.         $db $this->getDBInstance();
  72.         if (MDB2::isError($db)) {
  73.             return $db;
  74.         }
  75.  
  76.         $name  $db->quoteIdentifier($nametrue);
  77.         $query 'CREATE DATABASE ' $name;
  78.         if (!empty($options['charset'])) {
  79.             $query .= ' WITH ENCODING ' $db->quote($options['charset']'text');
  80.         }
  81.         return $db->standaloneQuery($querynulltrue);
  82.     }
  83.  
  84.     // }}}
  85.     // {{{ alterDatabase()
  86.  
  87.     /**
  88.      * alter an existing database
  89.      *
  90.      * @param string $name    name of the database that is intended to be changed
  91.      * @param array  $options array with name, owner info
  92.      *
  93.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  94.      * @access public
  95.      */
  96.     function alterDatabase($name$options = array())
  97.     {
  98.         $db $this->getDBInstance();
  99.         if (MDB2::isError($db)) {
  100.             return $db;
  101.         }
  102.  
  103.         $query '';
  104.         if (!empty($options['name'])) {
  105.             $query .= ' RENAME TO ' $options['name'];
  106.         }
  107.         if (!empty($options['owner'])) {
  108.             $query .= ' OWNER TO ' $options['owner'];
  109.         }
  110.  
  111.         if (empty($query)) {
  112.             return MDB2_OK;
  113.         }
  114.  
  115.         $query 'ALTER DATABASE '$db->quoteIdentifier($nametrue$query;
  116.         return $db->standaloneQuery($querynulltrue);
  117.     }
  118.  
  119.     // }}}
  120.     // {{{ dropDatabase()
  121.  
  122.     /**
  123.      * drop an existing database
  124.      *
  125.      * @param string $name name of the database that should be dropped
  126.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  127.      * @access public
  128.      */
  129.     function dropDatabase($name)
  130.     {
  131.         $db $this->getDBInstance();
  132.         if (MDB2::isError($db)) {
  133.             return $db;
  134.         }
  135.  
  136.         $name $db->quoteIdentifier($nametrue);
  137.         $query = "DROP DATABASE $name";
  138.         return $db->standaloneQuery($querynulltrue);
  139.     }
  140.  
  141.     // }}}
  142.     // {{{ _getAdvancedFKOptions()
  143.  
  144.     /**
  145.      * Return the FOREIGN KEY query section dealing with non-standard options
  146.      * as MATCH, INITIALLY DEFERRED, ON UPDATE, ...
  147.      *
  148.      * @param array $definition 
  149.      * @return string 
  150.      * @access protected
  151.      */
  152.     function _getAdvancedFKOptions($definition)
  153.     {
  154.         $query '';
  155.         if (!empty($definition['match'])) {
  156.             $query .= ' MATCH '.$definition['match'];
  157.         }
  158.         if (!empty($definition['onupdate'])) {
  159.             $query .= ' ON UPDATE '.$definition['onupdate'];
  160.         }
  161.         if (!empty($definition['ondelete'])) {
  162.             $query .= ' ON DELETE '.$definition['ondelete'];
  163.         }
  164.         if (!empty($definition['deferrable'])) {
  165.             $query .= ' DEFERRABLE';
  166.         else {
  167.             $query .= ' NOT DEFERRABLE';
  168.         }
  169.         if (!empty($definition['initiallydeferred'])) {
  170.             $query .= ' INITIALLY DEFERRED';
  171.         else {
  172.             $query .= ' INITIALLY IMMEDIATE';
  173.         }
  174.         return $query;
  175.     }
  176.  
  177.     // }}}
  178.     // {{{ truncateTable()
  179.  
  180.     /**
  181.      * Truncate an existing table (if the TRUNCATE TABLE syntax is not supported,
  182.      * it falls back to a DELETE FROM TABLE query)
  183.      *
  184.      * @param string $name name of the table that should be truncated
  185.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  186.      * @access public
  187.      */
  188.     function truncateTable($name)
  189.     {
  190.         $db $this->getDBInstance();
  191.         if (MDB2::isError($db)) {
  192.             return $db;
  193.         }
  194.  
  195.         $name $db->quoteIdentifier($nametrue);
  196.         $result $db->exec("TRUNCATE TABLE $name");
  197.         if (MDB2::isError($result)) {
  198.             return $result;
  199.         }
  200.         return MDB2_OK;
  201.     }
  202.  
  203.     // }}}
  204.     // {{{ vacuum()
  205.  
  206.     /**
  207.      * Optimize (vacuum) all the tables in the db (or only the specified table)
  208.      * and optionally run ANALYZE.
  209.      *
  210.      * @param string $table table name (all the tables if empty)
  211.      * @param array  $options an array with driver-specific options:
  212.      *                - timeout [int] (in seconds) [mssql-only]
  213.      *                - analyze [boolean] [pgsql and mysql]
  214.      *                - full [boolean] [pgsql-only]
  215.      *                - freeze [boolean] [pgsql-only]
  216.      *
  217.      * @return mixed MDB2_OK success, a MDB2 error on failure
  218.      * @access public
  219.      */
  220.     function vacuum($table = null$options = array())
  221.     {
  222.         $db $this->getDBInstance();
  223.         if (MDB2::isError($db)) {
  224.             return $db;
  225.         }
  226.         $query 'VACUUM';
  227.  
  228.         if (!empty($options['full'])) {
  229.             $query .= ' FULL';
  230.         }
  231.         if (!empty($options['freeze'])) {
  232.             $query .= ' FREEZE';
  233.         }
  234.         if (!empty($options['analyze'])) {
  235.             $query .= ' ANALYZE';
  236.         }
  237.  
  238.         if (!empty($table)) {
  239.             $query .= ' '.$db->quoteIdentifier($tabletrue);
  240.         }
  241.         $result $db->exec($query);
  242.         if (MDB2::isError($result)) {
  243.             return $result;
  244.         }
  245.         return MDB2_OK;
  246.     }
  247.  
  248.     // }}}
  249.     // {{{ alterTable()
  250.  
  251.     /**
  252.      * alter an existing table
  253.      *
  254.      * @param string $name         name of the table that is intended to be changed.
  255.      * @param array $changes     associative array that contains the details of each type
  256.      *                              of change that is intended to be performed. The types of
  257.      *                              changes that are currently supported are defined as follows:
  258.      *
  259.      *                              name
  260.      *
  261.      *                                 New name for the table.
  262.      *
  263.      *                             add
  264.      *
  265.      *                                 Associative array with the names of fields to be added as
  266.      *                                  indexes of the array. The value of each entry of the array
  267.      *                                  should be set to another associative array with the properties
  268.      *                                  of the fields to be added. The properties of the fields should
  269.      *                                  be the same as defined by the MDB2 parser.
  270.      *
  271.      *
  272.      *                             remove
  273.      *
  274.      *                                 Associative array with the names of fields to be removed as indexes
  275.      *                                  of the array. Currently the values assigned to each entry are ignored.
  276.      *                                  An empty array should be used for future compatibility.
  277.      *
  278.      *                             rename
  279.      *
  280.      *                                 Associative array with the names of fields to be renamed as indexes
  281.      *                                  of the array. The value of each entry of the array should be set to
  282.      *                                  another associative array with the entry named name with the new
  283.      *                                  field name and the entry named Declaration that is expected to contain
  284.      *                                  the portion of the field declaration already in DBMS specific SQL code
  285.      *                                  as it is used in the CREATE TABLE statement.
  286.      *
  287.      *                             change
  288.      *
  289.      *                                 Associative array with the names of the fields to be changed as indexes
  290.      *                                  of the array. Keep in mind that if it is intended to change either the
  291.      *                                  name of a field and any other properties, the change array entries
  292.      *                                  should have the new names of the fields as array indexes.
  293.      *
  294.      *                                 The value of each entry of the array should be set to another associative
  295.      *                                  array with the properties of the fields to that are meant to be changed as
  296.      *                                  array entries. These entries should be assigned to the new values of the
  297.      *                                  respective properties. The properties of the fields should be the same
  298.      *                                  as defined by the MDB2 parser.
  299.      *
  300.      *                             Example
  301.      *                                 array(
  302.      *                                     'name' => 'userlist',
  303.      *                                     'add' => array(
  304.      *                                         'quota' => array(
  305.      *                                             'type' => 'integer',
  306.      *                                             'unsigned' => 1
  307.      *                                         )
  308.      *                                     ),
  309.      *                                     'remove' => array(
  310.      *                                         'file_limit' => array(),
  311.      *                                         'time_limit' => array()
  312.      *                                     ),
  313.      *                                     'change' => array(
  314.      *                                         'name' => array(
  315.      *                                             'length' => '20',
  316.      *                                             'definition' => array(
  317.      *                                                 'type' => 'text',
  318.      *                                                 'length' => 20,
  319.      *                                             ),
  320.      *                                         )
  321.      *                                     ),
  322.      *                                     'rename' => array(
  323.      *                                         'sex' => array(
  324.      *                                             'name' => 'gender',
  325.      *                                             'definition' => array(
  326.      *                                                 'type' => 'text',
  327.      *                                                 'length' => 1,
  328.      *                                                 'default' => 'M',
  329.      *                                             ),
  330.      *                                         )
  331.      *                                     )
  332.      *                                 )
  333.      *
  334.      * @param boolean $check     indicates whether the function should just check if the DBMS driver
  335.      *                              can perform the requested table alterations if the value is true or
  336.      *                              actually perform them otherwise.
  337.      * @access public
  338.      *
  339.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  340.      */
  341.     function alterTable($name$changes$check)
  342.     {
  343.         $db $this->getDBInstance();
  344.         if (MDB2::isError($db)) {
  345.             return $db;
  346.         }
  347.  
  348.         foreach ($changes as $change_name => $change{
  349.             switch ($change_name{
  350.             case 'add':
  351.             case 'remove':
  352.             case 'change':
  353.             case 'name':
  354.             case 'rename':
  355.                 break;
  356.             default:
  357.                 return $db->raiseError(MDB2_ERROR_CANNOT_ALTERnullnull,
  358.                     'change type "'.$change_name.'\" not yet supported'__FUNCTION__);
  359.             }
  360.         }
  361.  
  362.         if ($check{
  363.             return MDB2_OK;
  364.         }
  365.  
  366.         $name $db->quoteIdentifier($nametrue);
  367.  
  368.         if (!empty($changes['remove']&& is_array($changes['remove'])) {
  369.             foreach ($changes['remove'as $field_name => $field{
  370.                 $field_name $db->quoteIdentifier($field_nametrue);
  371.                 $query 'DROP ' $field_name;
  372.                 $result $db->exec("ALTER TABLE $name $query");
  373.                 if (MDB2::isError($result)) {
  374.                     return $result;
  375.                 }
  376.             }
  377.         }
  378.  
  379.         if (!empty($changes['rename']&& is_array($changes['rename'])) {
  380.             foreach ($changes['rename'as $field_name => $field{
  381.                 $field_name $db->quoteIdentifier($field_nametrue);
  382.                 $result $db->exec("ALTER TABLE $name RENAME COLUMN $field_name TO ".$db->quoteIdentifier($field['name']true));
  383.                 if (MDB2::isError($result)) {
  384.                     return $result;
  385.                 }
  386.             }
  387.         }
  388.  
  389.         if (!empty($changes['add']&& is_array($changes['add'])) {
  390.             foreach ($changes['add'as $field_name => $field{
  391.                 $query 'ADD ' $db->getDeclaration($field['type']$field_name$field);
  392.                 $result $db->exec("ALTER TABLE $name $query");
  393.                 if (MDB2::isError($result)) {
  394.                     return $result;
  395.                 }
  396.             }
  397.         }
  398.  
  399.         if (!empty($changes['change']&& is_array($changes['change'])) {
  400.             foreach ($changes['change'as $field_name => $field{
  401.                 $field_name $db->quoteIdentifier($field_nametrue);
  402.                 if (!empty($field['definition']['type'])) {
  403.                     $server_info $db->getServerVersion();
  404.                     if (MDB2::isError($server_info)) {
  405.                         return $server_info;
  406.                     }
  407.                     if (is_array($server_info&& $server_info['major'< 8{
  408.                         return $db->raiseError(MDB2_ERROR_CANNOT_ALTERnullnull,
  409.                             'changing column type for "'.$change_name.'\" requires PostgreSQL 8.0 or above'__FUNCTION__);
  410.                     }
  411.                     $db->loadModule('Datatype'nulltrue);
  412.                     $type $db->datatype->getTypeDeclaration($field['definition']);
  413.                     $query = "ALTER $field_name TYPE $type USING CAST($field_name AS $type)";
  414.                     $result $db->exec("ALTER TABLE $name $query");
  415.                     if (MDB2::isError($result)) {
  416.                         return $result;
  417.                     }
  418.                 }
  419.                 if (array_key_exists('default'$field['definition'])) {
  420.                     $query = "ALTER $field_name SET DEFAULT ".$db->quote($field['definition']['default']$field['definition']['type']);
  421.                     $result $db->exec("ALTER TABLE $name $query");
  422.                     if (MDB2::isError($result)) {
  423.                         return $result;
  424.                     }
  425.                 }
  426.                 if (array_key_exists('notnull'$field['definition'])) {
  427.                     $query = "ALTER $field_name ".($field['definition']['notnull''SET' 'DROP').' NOT NULL';
  428.                     $result $db->exec("ALTER TABLE $name $query");
  429.                     if (MDB2::isError($result)) {
  430.                         return $result;
  431.                     }
  432.                 }
  433.             }
  434.         }
  435.  
  436.         if (!empty($changes['name'])) {
  437.             $change_name $db->quoteIdentifier($changes['name']true);
  438.             $result $db->exec("ALTER TABLE $name RENAME TO ".$change_name);
  439.             if (MDB2::isError($result)) {
  440.                 return $result;
  441.             }
  442.         }
  443.  
  444.         return MDB2_OK;
  445.     }
  446.  
  447.     // }}}
  448.     // {{{ listDatabases()
  449.  
  450.     /**
  451.      * list all databases
  452.      *
  453.      * @return mixed array of database names on success, a MDB2 error on failure
  454.      * @access public
  455.      */
  456.     function listDatabases()
  457.     {
  458.         $db $this->getDBInstance();
  459.         if (MDB2::isError($db)) {
  460.             return $db;
  461.         }
  462.  
  463.         $query 'SELECT datname FROM pg_database';
  464.         $result2 $db->standaloneQuery($queryarray('text')false);
  465.         if (!MDB2::isResultCommon($result2)) {
  466.             return $result2;
  467.         }
  468.  
  469.         $result $result2->fetchCol();
  470.         $result2->free();
  471.         if (MDB2::isError($result)) {
  472.             return $result;
  473.         }
  474.         if ($db->options['portability'MDB2_PORTABILITY_FIX_CASE{
  475.             $result array_map(($db->options['field_case'== CASE_LOWER ? 'strtolower' 'strtoupper')$result);
  476.         }
  477.         return $result;
  478.     }
  479.  
  480.     // }}}
  481.     // {{{ listUsers()
  482.  
  483.     /**
  484.      * list all users
  485.      *
  486.      * @return mixed array of user names on success, a MDB2 error on failure
  487.      * @access public
  488.      */
  489.     function listUsers()
  490.     {
  491.         $db $this->getDBInstance();
  492.         if (MDB2::isError($db)) {
  493.             return $db;
  494.         }
  495.  
  496.         $query 'SELECT usename FROM pg_user';
  497.         $result2 $db->standaloneQuery($queryarray('text')false);
  498.         if (!MDB2::isResultCommon($result2)) {
  499.             return $result2;
  500.         }
  501.  
  502.         $result $result2->fetchCol();
  503.         $result2->free();
  504.         return $result;
  505.     }
  506.  
  507.     // }}}
  508.     // {{{ listViews()
  509.  
  510.     /**
  511.      * list all views in the current database
  512.      *
  513.      * @return mixed array of view names on success, a MDB2 error on failure
  514.      * @access public
  515.      */
  516.     function listViews()
  517.     {
  518.         $db $this->getDBInstance();
  519.         if (MDB2::isError($db)) {
  520.             return $db;
  521.         }
  522.  
  523.         $query "SELECT viewname
  524.                     FROM pg_views
  525.                    WHERE schemaname NOT IN ('pg_catalog', 'information_schema')
  526.                      AND viewname !~ '^pg_'";
  527.         $result $db->queryCol($query);
  528.         if (MDB2::isError($result)) {
  529.             return $result;
  530.         }
  531.         if ($db->options['portability'MDB2_PORTABILITY_FIX_CASE{
  532.             $result array_map(($db->options['field_case'== CASE_LOWER ? 'strtolower' 'strtoupper')$result);
  533.         }
  534.         return $result;
  535.     }
  536.  
  537.     // }}}
  538.     // {{{ listTableViews()
  539.  
  540.     /**
  541.      * list the views in the database that reference a given table
  542.      *
  543.      * @param string table for which all referenced views should be found
  544.      * @return mixed array of view names on success, a MDB2 error on failure
  545.      * @access public
  546.      */
  547.     function listTableViews($table)
  548.     {
  549.         $db $this->getDBInstance();
  550.         if (MDB2::isError($db)) {
  551.             return $db;
  552.         }
  553.  
  554.         $query 'SELECT viewname FROM pg_views NATURAL JOIN pg_tables';
  555.         $query.= ' WHERE tablename ='.$db->quote($table'text');
  556.         $result $db->queryCol($query);
  557.         if (MDB2::isError($result)) {
  558.             return $result;
  559.         }
  560.         if ($db->options['portability'MDB2_PORTABILITY_FIX_CASE{
  561.             $result array_map(($db->options['field_case'== CASE_LOWER ? 'strtolower' 'strtoupper')$result);
  562.         }
  563.         return $result;
  564.     }
  565.  
  566.     // }}}
  567.     // {{{ listFunctions()
  568.  
  569.     /**
  570.      * list all functions in the current database
  571.      *
  572.      * @return mixed array of function names on success, a MDB2 error on failure
  573.      * @access public
  574.      */
  575.     function listFunctions()
  576.     {
  577.         $db $this->getDBInstance();
  578.         if (MDB2::isError($db)) {
  579.             return $db;
  580.         }
  581.  
  582.         $query "
  583.             SELECT
  584.                 proname
  585.             FROM
  586.                 pg_proc pr,
  587.                 pg_type tp
  588.             WHERE
  589.                 tp.oid = pr.prorettype
  590.                 AND pr.proisagg = FALSE
  591.                 AND tp.typname <> 'trigger'
  592.                 AND pr.pronamespace IN
  593.                     (SELECT oid FROM pg_namespace WHERE nspname NOT LIKE 'pg_%' AND nspname != 'information_schema')";
  594.         $result $db->queryCol($query);
  595.         if (MDB2::isError($result)) {
  596.             return $result;
  597.         }
  598.         if ($db->options['portability'MDB2_PORTABILITY_FIX_CASE{
  599.             $result array_map(($db->options['field_case'== CASE_LOWER ? 'strtolower' 'strtoupper')$result);
  600.         }
  601.         return $result;
  602.     }
  603.  
  604.     // }}}
  605.     // {{{ listTableTriggers()
  606.  
  607.     /**
  608.      * list all triggers in the database that reference a given table
  609.      *
  610.      * @param string table for which all referenced triggers should be found
  611.      * @return mixed array of trigger names on success, a MDB2 error on failure
  612.      * @access public
  613.      */
  614.     function listTableTriggers($table = null)
  615.     {
  616.         $db $this->getDBInstance();
  617.         if (MDB2::isError($db)) {
  618.             return $db;
  619.         }
  620.  
  621.         $query 'SELECT trg.tgname AS trigger_name
  622.                     FROM pg_trigger trg,
  623.                          pg_class tbl
  624.                    WHERE trg.tgrelid = tbl.oid';
  625.         if (null !== $table{
  626.             $table $db->quote(strtoupper($table)'text');
  627.             $query .= " AND UPPER(tbl.relname) = $table";
  628.         }
  629.         $result $db->queryCol($query);
  630.         if (MDB2::isError($result)) {
  631.             return $result;
  632.         }
  633.         if ($db->options['portability'MDB2_PORTABILITY_FIX_CASE{
  634.             $result array_map(($db->options['field_case'== CASE_LOWER ? 'strtolower' 'strtoupper')$result);
  635.         }
  636.         return $result;
  637.     }
  638.  
  639.     // }}}
  640.     // {{{ listTables()
  641.  
  642.     /**
  643.      * list all tables in the current database
  644.      *
  645.      * @return mixed array of table names on success, a MDB2 error on failure
  646.      * @access public
  647.      */
  648.     function listTables()
  649.     {
  650.         $db $this->getDBInstance();
  651.         if (MDB2::isError($db)) {
  652.             return $db;
  653.         }
  654.  
  655.         // gratuitously stolen from PEAR DB _getSpecialQuery in pgsql.php
  656.         $query 'SELECT c.relname AS "Name"'
  657.             . ' FROM pg_class c, pg_user u'
  658.             . ' WHERE c.relowner = u.usesysid'
  659.             . " AND c.relkind = 'r'"
  660.             . ' AND NOT EXISTS'
  661.             . ' (SELECT 1 FROM pg_views'
  662.             . '  WHERE viewname = c.relname)'
  663.             . " AND c.relname !~ '^(pg_|sql_)'"
  664.             . ' UNION'
  665.             . ' SELECT c.relname AS "Name"'
  666.             . ' FROM pg_class c'
  667.             . " WHERE c.relkind = 'r'"
  668.             . ' AND NOT EXISTS'
  669.             . ' (SELECT 1 FROM pg_views'
  670.             . '  WHERE viewname = c.relname)'
  671.             . ' AND NOT EXISTS'
  672.             . ' (SELECT 1 FROM pg_user'
  673.             . '  WHERE usesysid = c.relowner)'
  674.             . " AND c.relname !~ '^pg_'";
  675.         $result $db->queryCol($query);
  676.         if (MDB2::isError($result)) {
  677.             return $result;
  678.         }
  679.         if ($db->options['portability'MDB2_PORTABILITY_FIX_CASE{
  680.             $result array_map(($db->options['field_case'== CASE_LOWER ? 'strtolower' 'strtoupper')$result);
  681.         }
  682.         return $result;
  683.     }
  684.  
  685.     // }}}
  686.     // {{{ listTableFields()
  687.  
  688.     /**
  689.      * list all fields in a table in the current database
  690.      *
  691.      * @param string $table name of table that should be used in method
  692.      * @return mixed array of field names on success, a MDB2 error on failure
  693.      * @access public
  694.      */
  695.     function listTableFields($table)
  696.     {
  697.         $db $this->getDBInstance();
  698.         if (MDB2::isError($db)) {
  699.             return $db;
  700.         }
  701.  
  702.         list($schema$table$this->splitTableSchema($table);
  703.  
  704.         $table $db->quoteIdentifier($tabletrue);
  705.         if (!empty($schema)) {
  706.             $table $db->quoteIdentifier($schematrue'.' .$table;
  707.         }
  708.         $db->setLimit(1);
  709.         $result2 $db->query("SELECT * FROM $table");
  710.         if (MDB2::isError($result2)) {
  711.             return $result2;
  712.         }
  713.         $result $result2->getColumnNames();
  714.         $result2->free();
  715.         if (MDB2::isError($result)) {
  716.             return $result;
  717.         }
  718.         return array_flip($result);
  719.     }
  720.  
  721.     // }}}
  722.     // {{{ listTableIndexes()
  723.  
  724.     /**
  725.      * list all indexes in a table
  726.      *
  727.      * @param string $table name of table that should be used in method
  728.      * @return mixed array of index names on success, a MDB2 error on failure
  729.      * @access public
  730.      */
  731.     function listTableIndexes($table)
  732.     {
  733.         $db $this->getDBInstance();
  734.         if (MDB2::isError($db)) {
  735.             return $db;
  736.         }
  737.  
  738.         list($schema$table$this->splitTableSchema($table);
  739.  
  740.         $table $db->quote($table'text');
  741.         $subquery = "SELECT indexrelid
  742.                        FROM pg_index
  743.                   LEFT JOIN pg_class ON pg_class.oid = pg_index.indrelid
  744.                   LEFT JOIN pg_namespace ON pg_class.relnamespace = pg_namespace.oid
  745.                       WHERE pg_class.relname = $table
  746.                         AND indisunique != 't'
  747.                         AND indisprimary != 't'";
  748.         if (!empty($schema)) {
  749.             $subquery .= ' AND pg_namespace.nspname = '.$db->quote($schema'text');
  750.         }
  751.         $query = "SELECT relname FROM pg_class WHERE oid IN ($subquery)";
  752.         $indexes $db->queryCol($query'text');
  753.         if (MDB2::isError($indexes)) {
  754.             return $indexes;
  755.         }
  756.  
  757.         $result = array();
  758.         foreach ($indexes as $index{
  759.             $index $this->_fixIndexName($index);
  760.             if (!empty($index)) {
  761.                 $result[$index= true;
  762.             }
  763.         }
  764.  
  765.         if ($db->options['portability'MDB2_PORTABILITY_FIX_CASE{
  766.             $result array_change_key_case($result$db->options['field_case']);
  767.         }
  768.         return array_keys($result);
  769.     }
  770.  
  771.     // }}}
  772.     // {{{ dropConstraint()
  773.  
  774.     /**
  775.      * drop existing constraint
  776.      *
  777.      * @param string $table   name of table that should be used in method
  778.      * @param string $name    name of the constraint to be dropped
  779.      * @param string $primary hint if the constraint is primary
  780.      *
  781.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  782.      * @access public
  783.      */
  784.     function dropConstraint($table$name$primary = false)
  785.     {
  786.         $db $this->getDBInstance();
  787.         if (MDB2::isError($db)) {
  788.             return $db;
  789.         }
  790.  
  791.         // is it an UNIQUE index?
  792.         $query 'SELECT relname
  793.                     FROM pg_class
  794.                    WHERE oid IN (
  795.                          SELECT indexrelid
  796.                            FROM pg_index, pg_class
  797.                           WHERE pg_class.relname = '.$db->quote($table'text').'
  798.                             AND pg_class.oid = pg_index.indrelid
  799.                             AND indisunique = \'t\')
  800.                   EXCEPT
  801.                   SELECT conname
  802.                    FROM pg_constraint, pg_class
  803.                   WHERE pg_constraint.conrelid = pg_class.oid
  804.                     AND relname = '$db->quote($table'text');
  805.         $unique $db->queryCol($query'text');
  806.         if (MDB2::isError($unique|| empty($unique)) {
  807.             // not an UNIQUE index, maybe a CONSTRAINT
  808.             return parent::dropConstraint($table$name$primary);
  809.         }
  810.  
  811.         if (in_array($name$unique)) {
  812.             $result $db->exec('DROP INDEX '.$db->quoteIdentifier($nametrue));
  813.             if (MDB2::isError($result)) {
  814.                 return $result;
  815.             }
  816.             return MDB2_OK;
  817.         }
  818.         $idxname $db->getIndexName($name);
  819.         if (in_array($idxname$unique)) {
  820.             $result $db->exec('DROP INDEX '.$db->quoteIdentifier($idxnametrue));
  821.             if (MDB2::isError($result)) {
  822.                 return $result;
  823.             }
  824.             return MDB2_OK;
  825.         }
  826.         return $db->raiseError(MDB2_ERROR_NOT_FOUNDnullnull,
  827.             $name ' is not an existing constraint for table ' $table__FUNCTION__);
  828.     }
  829.  
  830.     // }}}
  831.     // {{{ listTableConstraints()
  832.  
  833.     /**
  834.      * list all constraints in a table
  835.      *
  836.      * @param string $table name of table that should be used in method
  837.      * @return mixed array of constraint names on success, a MDB2 error on failure
  838.      * @access public
  839.      */
  840.     function listTableConstraints($table)
  841.     {
  842.         $db $this->getDBInstance();
  843.         if (MDB2::isError($db)) {
  844.             return $db;
  845.         }
  846.  
  847.         list($schema$table$this->splitTableSchema($table);
  848.  
  849.         $table $db->quote($table'text');
  850.         $query 'SELECT conname
  851.                     FROM pg_constraint
  852.                LEFT JOIN pg_class ON pg_constraint.conrelid = pg_class.oid
  853.                LEFT JOIN pg_namespace ON pg_class.relnamespace = pg_namespace.oid
  854.                    WHERE relname = ' .$table;
  855.         if (!empty($schema)) {
  856.             $query .= ' AND pg_namespace.nspname = ' $db->quote($schema'text');
  857.         }
  858.         $query .= '
  859.                    UNION DISTINCT
  860.                   SELECT relname
  861.                     FROM pg_class
  862.                    WHERE oid IN (
  863.                          SELECT indexrelid
  864.                            FROM pg_index
  865.                       LEFT JOIN pg_class ON pg_class.oid = pg_index.indrelid
  866.                       LEFT JOIN pg_namespace ON pg_class.relnamespace = pg_namespace.oid
  867.                           WHERE pg_class.relname = '.$table.'
  868.                             AND indisunique = \'t\'';
  869.         if (!empty($schema)) {
  870.             $query .= ' AND pg_namespace.nspname = ' $db->quote($schema'text');
  871.         }
  872.         $query .= ')';
  873.         $constraints $db->queryCol($query);
  874.         if (MDB2::isError($constraints)) {
  875.             return $constraints;
  876.         }
  877.  
  878.         $result = array();
  879.         foreach ($constraints as $constraint{
  880.             $constraint $this->_fixIndexName($constraint);
  881.             if (!empty($constraint)) {
  882.                 $result[$constraint= true;
  883.             }
  884.         }
  885.  
  886.         if ($db->options['portability'MDB2_PORTABILITY_FIX_CASE
  887.             && $db->options['field_case'== CASE_LOWER
  888.         {
  889.             $result array_change_key_case($result$db->options['field_case']);
  890.         }
  891.         return array_keys($result);
  892.     }
  893.  
  894.     // }}}
  895.     // {{{ createSequence()
  896.  
  897.     /**
  898.      * create sequence
  899.      *
  900.      * @param string $seq_name name of the sequence to be created
  901.      * @param string $start start value of the sequence; default is 1
  902.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  903.      * @access public
  904.      */
  905.     function createSequence($seq_name$start = 1)
  906.     {
  907.         $db $this->getDBInstance();
  908.         if (MDB2::isError($db)) {
  909.             return $db;
  910.         }
  911.  
  912.         $sequence_name $db->quoteIdentifier($db->getSequenceName($seq_name)true);
  913.         $result $db->exec("CREATE SEQUENCE $sequence_name INCREMENT 1".
  914.             ($start < 1 ? " MINVALUE $start" : '')." START $start");
  915.         if (MDB2::isError($result)) {
  916.             return $result;
  917.         }
  918.         return MDB2_OK;
  919.     }
  920.  
  921.     // }}}
  922.     // {{{ dropSequence()
  923.  
  924.     /**
  925.      * drop existing sequence
  926.      *
  927.      * @param string $seq_name name of the sequence to be dropped
  928.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  929.      * @access public
  930.      */
  931.     function dropSequence($seq_name)
  932.     {
  933.         $db $this->getDBInstance();
  934.         if (MDB2::isError($db)) {
  935.             return $db;
  936.         }
  937.  
  938.         $sequence_name $db->quoteIdentifier($db->getSequenceName($seq_name)true);
  939.         $result $db->exec("DROP SEQUENCE $sequence_name");
  940.         if (MDB2::isError($result)) {
  941.             return $result;
  942.         }
  943.         return MDB2_OK;
  944.     }
  945.  
  946.     // }}}
  947.     // {{{ listSequences()
  948.  
  949.     /**
  950.      * list all sequences in the current database
  951.      *
  952.      * @return mixed array of sequence names on success, a MDB2 error on failure
  953.      * @access public
  954.      */
  955.     function listSequences()
  956.     {
  957.         $db $this->getDBInstance();
  958.         if (MDB2::isError($db)) {
  959.             return $db;
  960.         }
  961.  
  962.         $query "SELECT relname FROM pg_class WHERE relkind = 'S' AND relnamespace IN";
  963.         $query.= "(SELECT oid FROM pg_namespace WHERE nspname NOT LIKE 'pg_%' AND nspname != 'information_schema')";
  964.         $table_names $db->queryCol($query);
  965.         if (MDB2::isError($table_names)) {
  966.             return $table_names;
  967.         }
  968.         $result = array();
  969.         foreach ($table_names as $table_name{
  970.             $result[$this->_fixSequenceName($table_name);
  971.         }
  972.         if ($db->options['portability'MDB2_PORTABILITY_FIX_CASE{
  973.             $result array_map(($db->options['field_case'== CASE_LOWER ? 'strtolower' 'strtoupper')$result);
  974.         }
  975.         return $result;
  976.     }
  977. }
  978. ?>

Documentation generated on Mon, 11 Mar 2019 15:51:23 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.