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

Source for file odbc.php

Documentation is available at odbc.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. // | Authors: Frank M. Kromann <frank@kromann.info>                       |
  43. // |          David Coallier <davidc@php.net>                             |
  44. // |          Lorenzo Alberton <l.alberton@quipo.it>                      |
  45. // +----------------------------------------------------------------------+
  46. //
  47. // $Id: mssql.php,v 1.109 2008/03/05 12:55:57 afz Exp $
  48. //
  49.  
  50. require_once 'MDB2/Driver/Manager/Common.php';
  51.  
  52. // {{{ class MDB2_Driver_Manager_mssql
  53.  
  54. /**
  55.  * MDB2 MSSQL driver for the management modules
  56.  *
  57.  * @package MDB2
  58.  * @category Database
  59.  * @author  Frank M. Kromann <frank@kromann.info>
  60.  * @author  David Coallier <davidc@php.net>
  61.  * @author  Lorenzo Alberton <l.alberton@quipo.it>
  62.  */
  63. class MDB2_Driver_Manager_odbc extends MDB2_Driver_Manager_Common
  64. {
  65.     // {{{ createDatabase()
  66.     /**
  67.      * create a new database
  68.      *
  69.      * @param string $name    name of the database that should be created
  70.      * @param array  $options array with collation info
  71.      *
  72.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  73.      * @access public
  74.      */
  75.     function createDatabase($name$options = array())
  76.     {
  77.         $db =$this->getDBInstance();
  78.         if (MDB2::isError($db)) {
  79.             return $db;
  80.         }
  81.  
  82.         $name $db->quoteIdentifier($nametrue);
  83.         $query = "CREATE DATABASE $name";
  84.         if ($db->options['database_device']{
  85.             $query.= ' ON '.$db->options['database_device'];
  86.             $query.= $db->options['database_size''=' .
  87.                      $db->options['database_size''';
  88.         }
  89.         if (!empty($options['collation'])) {
  90.             $query .= ' COLLATE ' $options['collation'];
  91.         }
  92.         return $db->standaloneQuery($querynulltrue);
  93.     }
  94.  
  95.     // }}}
  96.     // {{{ alterDatabase()
  97.  
  98.     /**
  99.      * alter an existing database
  100.      *
  101.      * @param string $name    name of the database that is intended to be changed
  102.      * @param array  $options array with name, collation info
  103.      *
  104.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  105.      * @access public
  106.      */
  107.     function alterDatabase($name$options = array())
  108.     {
  109.         $db =$this->getDBInstance();
  110.         if (MDB2::isError($db)) {
  111.             return $db;
  112.         }
  113.  
  114.         $query '';
  115.         if (!empty($options['name'])) {
  116.             $query .= ' MODIFY NAME = ' .$db->quoteIdentifier($options['name']true);
  117.         }
  118.         if (!empty($options['collation'])) {
  119.             $query .= ' COLLATE ' $options['collation'];
  120.         }
  121.         if (!empty($query)) {
  122.             $query 'ALTER DATABASE '$db->quoteIdentifier($nametrue$query;
  123.             return $db->standaloneQuery($querynulltrue);
  124.         }
  125.         return MDB2_OK;
  126.     }
  127.  
  128.     // }}}
  129.     // {{{ dropDatabase()
  130.  
  131.     /**
  132.      * drop an existing database
  133.      *
  134.      * @param string $name name of the database that should be dropped
  135.      *
  136.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  137.      * @access public
  138.      */
  139.     function dropDatabase($name)
  140.     {
  141.         $db =$this->getDBInstance();
  142.         if (MDB2::isError($db)) {
  143.             return $db;
  144.         }
  145.  
  146.         $name $db->quoteIdentifier($nametrue);
  147.         return $db->standaloneQuery("DROP DATABASE $name"nulltrue);
  148.     }
  149.  
  150.     // }}}
  151.     // {{{ _getTemporaryTableQuery()
  152.  
  153.     /**
  154.      * Override the parent method.
  155.      *
  156.      * @return string The string required to be placed between "CREATE" and "TABLE"
  157.      *                 to generate a temporary table, if possible.
  158.      */
  159.     function _getTemporaryTableQuery()
  160.     {
  161.         return '';
  162.     }
  163.  
  164.     // }}}
  165.     // {{{ _getAdvancedFKOptions()
  166.  
  167.     /**
  168.      * Return the FOREIGN KEY query section dealing with non-standard options
  169.      * as MATCH, INITIALLY DEFERRED, ON UPDATE, ...
  170.      *
  171.      * @param array $definition 
  172.      *
  173.      * @return string 
  174.      * @access protected
  175.      */
  176.     function _getAdvancedFKOptions($definition)
  177.     {
  178.         $query '';
  179.         if (!empty($definition['onupdate'])) {
  180.             $query .= ' ON UPDATE '.$definition['onupdate'];
  181.         }
  182.         if (!empty($definition['ondelete'])) {
  183.             $query .= ' ON DELETE '.$definition['ondelete'];
  184.         }
  185.         return $query;
  186.     }
  187.  
  188.     // }}}
  189.     // {{{ createTable()
  190.  
  191.     /**
  192.      * create a new table
  193.      *
  194.      * @param string $name   Name of the database that should be created
  195.      * @param array  $fields Associative array that contains the definition of each field of the new table
  196.      *                        The indexes of the array entries are the names of the fields of the table an
  197.      *                        the array entry values are associative arrays like those that are meant to be
  198.      *                        passed with the field definitions to get[Type]Declaration() functions.
  199.      *
  200.      *                       Example
  201.      *                         array(
  202.      *
  203.      *                             'id' => array(
  204.      *                                 'type' => 'integer',
  205.      *                                 'unsigned' => 1,
  206.      *                                 'notnull' => 1,
  207.      *                                 'default' => 0,
  208.      *                             ),
  209.      *                             'name' => array(
  210.      *                                 'type' => 'text',
  211.      *                                 'length' => 12,
  212.      *                             ),
  213.      *                             'description' => array(
  214.      *                                 'type' => 'text',
  215.      *                                 'length' => 12,
  216.      *                             )
  217.      *                         );
  218.      * @param array $options An associative array of table options:
  219.      *                           array(
  220.      *                               'comment' => 'Foo',
  221.      *                               'temporary' => true|false,
  222.      *                           );
  223.      *
  224.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  225.      * @access public
  226.      */
  227.     function createTable($name$fields$options = array())
  228.     {
  229.         if (!empty($options['temporary'])) {
  230.             $name '#'.$name;
  231.         }
  232.         return parent::createTable($name$fields$options);
  233.     }
  234.  
  235.     // }}}
  236.     // {{{ truncateTable()
  237.  
  238.     /**
  239.      * Truncate an existing table (if the TRUNCATE TABLE syntax is not supported,
  240.      * it falls back to a DELETE FROM TABLE query)
  241.      *
  242.      * @param string $name name of the table that should be truncated
  243.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  244.      * @access public
  245.      */
  246.     function truncateTable($name)
  247.     {
  248.         $db =$this->getDBInstance();
  249.         if (MDB2::isError($db)) {
  250.             return $db;
  251.         }
  252.  
  253.         $name $db->quoteIdentifier($nametrue);
  254.         $result $db->exec("TRUNCATE TABLE $name");
  255.         if (MDB2::isError($result)) {
  256.             return $result;
  257.         }
  258.         return MDB2_OK;
  259.     }
  260.  
  261.     // }}}
  262.     // {{{ vacuum()
  263.  
  264.     /**
  265.      * Optimize (vacuum) all the tables in the db (or only the specified table)
  266.      * and optionally run ANALYZE.
  267.      *
  268.      * @param string $table table name (all the tables if empty)
  269.      * @param array  $options an array with driver-specific options:
  270.      *                - timeout [int] (in seconds) [mssql-only]
  271.      *                - analyze [boolean] [pgsql and mysql]
  272.      *                - full [boolean] [pgsql-only]
  273.      *                - freeze [boolean] [pgsql-only]
  274.      *
  275.      *  NB: you have to run the NSControl Create utility to enable VACUUM
  276.      *
  277.      * @return mixed MDB2_OK success, a MDB2 error on failure
  278.      * @access public
  279.      */
  280.     function vacuum($table = null$options = array())
  281.     {
  282.         $db =$this->getDBInstance();
  283.         if (MDB2::isError($db)) {
  284.             return $db;
  285.         }
  286.         $timeout = isset($options['timeout']? (int)$options['timeout': 300;
  287.  
  288.         $query 'NSControl Create';
  289.         $result $db->exec($query);
  290.         if (MDB2::isError($result)) {
  291.             return $result;
  292.         }
  293.  
  294.         $result $db->exec('EXEC NSVacuum '.$timeout);
  295.         if (MDB2::isError($result)) {
  296.             return $result;
  297.         }
  298.         return MDB2_OK;
  299.     }
  300.  
  301.     // }}}
  302.     // {{{ alterTable()
  303.  
  304.     /**
  305.      * alter an existing table
  306.      *
  307.      * @param string  $name    name of the table that is intended to be changed.
  308.      * @param array   $changes associative array that contains the details of each type
  309.      *                          of change that is intended to be performed. The types of
  310.      *                          changes that are currently supported are defined as follows:
  311.      *
  312.      *                              name
  313.      *
  314.      *                                 New name for the table.
  315.      *
  316.      *                             add
  317.      *
  318.      *                                 Associative array with the names of fields to be added as
  319.      *                                  indexes of the array. The value of each entry of the array
  320.      *                                  should be set to another associative array with the properties
  321.      *                                  of the fields to be added. The properties of the fields should
  322.      *                                  be the same as defined by the MDB2 parser.
  323.      *
  324.      *
  325.      *                             remove
  326.      *
  327.      *                                 Associative array with the names of fields to be removed as indexes
  328.      *                                  of the array. Currently the values assigned to each entry are ignored.
  329.      *                                  An empty array should be used for future compatibility.
  330.      *
  331.      *                             rename
  332.      *
  333.      *                                 Associative array with the names of fields to be renamed as indexes
  334.      *                                  of the array. The value of each entry of the array should be set to
  335.      *                                  another associative array with the entry named name with the new
  336.      *                                  field name and the entry named Declaration that is expected to contain
  337.      *                                  the portion of the field declaration already in DBMS specific SQL code
  338.      *                                  as it is used in the CREATE TABLE statement.
  339.      *
  340.      *                             change
  341.      *
  342.      *                                 Associative array with the names of the fields to be changed as indexes
  343.      *                                  of the array. Keep in mind that if it is intended to change either the
  344.      *                                  name of a field and any other properties, the change array entries
  345.      *                                  should have the new names of the fields as array indexes.
  346.      *
  347.      *                                 The value of each entry of the array should be set to another associative
  348.      *                                  array with the properties of the fields to that are meant to be changed as
  349.      *                                  array entries. These entries should be assigned to the new values of the
  350.      *                                  respective properties. The properties of the fields should be the same
  351.      *                                  as defined by the MDB2 parser.
  352.      *
  353.      *                             Example
  354.      *                                 array(
  355.      *                                     'name' => 'userlist',
  356.      *                                     'add' => array(
  357.      *                                         'quota' => array(
  358.      *                                             'type' => 'integer',
  359.      *                                             'unsigned' => 1
  360.      *                                         )
  361.      *                                     ),
  362.      *                                     'remove' => array(
  363.      *                                         'file_limit' => array(),
  364.      *                                         'time_limit' => array()
  365.      *                                     ),
  366.      *                                     'change' => array(
  367.      *                                         'name' => array(
  368.      *                                             'length' => '20',
  369.      *                                             'definition' => array(
  370.      *                                                 'type' => 'text',
  371.      *                                                 'length' => 20,
  372.      *                                             ),
  373.      *                                         )
  374.      *                                     ),
  375.      *                                     'rename' => array(
  376.      *                                         'sex' => array(
  377.      *                                             'name' => 'gender',
  378.      *                                             'definition' => array(
  379.      *                                                 'type' => 'text',
  380.      *                                                 'length' => 1,
  381.      *                                                 'default' => 'M',
  382.      *                                             ),
  383.      *                                         )
  384.      *                                     )
  385.      *                                 )
  386.      *
  387.      * @param boolean $check   indicates whether the function should just check if the DBMS driver
  388.      *                          can perform the requested table alterations if the value is true or
  389.      *                          actually perform them otherwise.
  390.      *
  391.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  392.      * @access public
  393.      */
  394.     function alterTable($name$changes$check)
  395.     {
  396.         $db =$this->getDBInstance();
  397.         if (MDB2::isError($db)) {
  398.             return $db;
  399.         }
  400.         $name_quoted $db->quoteIdentifier($nametrue);
  401.  
  402.         foreach ($changes as $change_name => $change{
  403.             switch ($change_name{
  404.             case 'remove':
  405.             case 'rename':
  406.             case 'add':
  407.             case 'change':
  408.             case 'name':
  409.                 break;
  410.             default:
  411.                 return $db->raiseError(MDB2_ERROR_CANNOT_ALTERnullnull,
  412.                     'change type "'.$change_name.'" not yet supported'__FUNCTION__);
  413.             }
  414.         }
  415.  
  416.         if ($check{
  417.             return MDB2_OK;
  418.         }
  419.  
  420.         $idxname_format $db->getOption('idxname_format');
  421.         $db->setOption('idxname_format''%s');
  422.  
  423.         if (!empty($changes['remove']&& is_array($changes['remove'])) {
  424.             $result $this->_dropConflictingIndices($namearray_keys($changes['remove']));
  425.             if (MDB2::isError($result)) {
  426.                 $db->setOption('idxname_format'$idxname_format);
  427.                 return $result;
  428.             }
  429.             $result $this->_dropConflictingConstraints($namearray_keys($changes['remove']));
  430.             if (MDB2::isError($result)) {
  431.                 $db->setOption('idxname_format'$idxname_format);
  432.                 return $result;
  433.             }
  434.  
  435.             $query '';
  436.             foreach ($changes['remove'as $field_name => $field{
  437.                 if ($query{
  438.                     $query.= ', ';
  439.                 }
  440.                 $field_name $db->quoteIdentifier($field_nametrue);
  441.                 $query.= 'COLUMN ' $field_name;
  442.             }
  443.  
  444.             $result $db->exec("ALTER TABLE $name_quoted DROP $query");
  445.             if (MDB2::isError($result)) {
  446.                 $db->setOption('idxname_format'$idxname_format);
  447.                 return $result;
  448.             }
  449.         }
  450.  
  451.         if (!empty($changes['rename']&& is_array($changes['rename'])) {
  452.             foreach ($changes['rename'as $field_name => $field{
  453.                 $field_name $db->quoteIdentifier($field_nametrue);
  454.                 $result $db->exec("sp_rename '$name_quoted.$field_name', '".$field['name']."', 'COLUMN'");
  455.                 if (MDB2::isError($result)) {
  456.                     $db->setOption('idxname_format'$idxname_format);
  457.                     return $result;
  458.                 }
  459.             }
  460.         }
  461.  
  462.         if (!empty($changes['add']&& is_array($changes['add'])) {
  463.             $query '';
  464.             foreach ($changes['add'as $field_name => $field{
  465.                 if ($query{
  466.                     $query.= ', ';
  467.                 else {
  468.                     $query.= 'ADD ';
  469.                 }
  470.                 $query.= $db->getDeclaration($field['type']$field_name$field);
  471.             }
  472.  
  473.             $result $db->exec("ALTER TABLE $name_quoted $query");
  474.             if (MDB2::isError($result)) {
  475.                 $db->setOption('idxname_format'$idxname_format);
  476.                 return $result;
  477.             }
  478.         }
  479.  
  480.         $dropped_indices     = array();
  481.         $dropped_constraints = array();
  482.  
  483.         if (!empty($changes['change']&& is_array($changes['change'])) {
  484.             $dropped $this->_dropConflictingIndices($namearray_keys($changes['change']));
  485.             if (MDB2::isError($dropped)) {
  486.                 $db->setOption('idxname_format'$idxname_format);
  487.                 return $dropped;
  488.             }
  489.             $dropped_indices array_merge($dropped_indices$dropped);
  490.             $dropped $this->_dropConflictingConstraints($namearray_keys($changes['change']));
  491.             if (MDB2::isError($dropped)) {
  492.                 $db->setOption('idxname_format'$idxname_format);
  493.                 return $dropped;
  494.             }
  495.             $dropped_constraints array_merge($dropped_constraints$dropped);
  496.  
  497.             foreach ($changes['change'as $field_name => $field{
  498.                 //MSSQL doesn't allow multiple ALTER COLUMNs in one query
  499.                 $query 'ALTER COLUMN ';
  500.  
  501.                 //MSSQL doesn't allow changing the DEFAULT value of a field in altering mode
  502.                 if (array_key_exists('default'$field['definition'])) {
  503.                     unset($field['definition']['default']);
  504.                 }
  505.  
  506.                 $query .= $db->getDeclaration($field['definition']['type']$field_name$field['definition']);
  507.                 $result $db->exec("ALTER TABLE $name_quoted $query");
  508.                 if (MDB2::isError($result)) {
  509.                     $db->setOption('idxname_format'$idxname_format);
  510.                     return $result;
  511.                 }
  512.             }
  513.         }
  514.  
  515.         // restore the dropped conflicting indices and constraints
  516.         foreach ($dropped_indices as $index_name => $index{
  517.             $result $this->createIndex($name$index_name$index);
  518.             if (MDB2::isError($result)) {
  519.                 $db->setOption('idxname_format'$idxname_format);
  520.                 return $result;
  521.             }
  522.         }
  523.         foreach ($dropped_constraints as $constraint_name => $constraint{
  524.             $result $this->createConstraint($name$constraint_name$constraint);
  525.             if (MDB2::isError($result)) {
  526.                 $db->setOption('idxname_format'$idxname_format);
  527.                 return $result;
  528.             }
  529.         }
  530.  
  531.         $db->setOption('idxname_format'$idxname_format);
  532.  
  533.         if (!empty($changes['name'])) {
  534.             $new_name $db->quoteIdentifier($changes['name']true);
  535.             $result $db->exec("sp_rename '$name_quoted', '$new_name'");
  536.             if (MDB2::isError($result)) {
  537.                 return $result;
  538.             }
  539.         }
  540.  
  541.         return MDB2_OK;
  542.     }
  543.  
  544.     // }}}
  545.     // {{{ _dropConflictingIndices()
  546.  
  547.     /**
  548.      * Drop the indices that prevent a successful ALTER TABLE action
  549.      *
  550.      * @param string $table  table name
  551.      * @param array  $fields array of names of the fields affected by the change
  552.      *
  553.      * @return array dropped indices definitions
  554.      */
  555.     function _dropConflictingIndices($table$fields)
  556.     {
  557.         $db =$this->getDBInstance();
  558.         if (MDB2::isError($db)) {
  559.             return $db;
  560.         }
  561.  
  562.         $dropped = array();
  563.         $index_names $this->listTableIndexes($table);
  564.         if (MDB2::isError($index_names)) {
  565.             return $index_names;
  566.         }
  567.         $db->loadModule('Reverse');
  568.         $indexes = array();
  569.         foreach ($index_names as $index_name{
  570.             $idx_def $db->reverse->getTableIndexDefinition($table$index_name);
  571.             if (!MDB2::isError($idx_def)) {
  572.                 $indexes[$index_name$idx_def;
  573.             }
  574.         }
  575.         foreach ($fields as $field_name{
  576.             foreach ($indexes as $index_name => $index{
  577.                 if (!isset($dropped[$index_name]&& array_key_exists($field_name$index['fields'])) {
  578.                     $dropped[$index_name$index;
  579.                     $result $this->dropIndex($table$index_name);
  580.                     if (MDB2::isError($result)) {
  581.                         return $result;
  582.                     }
  583.                 }
  584.             }
  585.         }
  586.  
  587.         return $dropped;
  588.     }
  589.  
  590.     // }}}
  591.     // {{{ _dropConflictingConstraints()
  592.  
  593.     /**
  594.      * Drop the constraints that prevent a successful ALTER TABLE action
  595.      *
  596.      * @param string $table  table name
  597.      * @param array  $fields array of names of the fields affected by the change
  598.      *
  599.      * @return array dropped constraints definitions
  600.      */
  601.     function _dropConflictingConstraints($table$fields)
  602.     {
  603.         $db =$this->getDBInstance();
  604.         if (MDB2::isError($db)) {
  605.             return $db;
  606.         }
  607.  
  608.         $dropped = array();
  609.         $constraint_names $this->listTableConstraints($table);
  610.         if (MDB2::isError($constraint_names)) {
  611.             return $constraint_names;
  612.         }
  613.         $db->loadModule('Reverse');
  614.         $constraints = array();
  615.         foreach ($constraint_names as $constraint_name{
  616.             $cons_def $db->reverse->getTableConstraintDefinition($table$constraint_name);
  617.             if (!MDB2::isError($cons_def)) {
  618.                 $constraints[$constraint_name$cons_def;
  619.             }
  620.         }
  621.         foreach ($fields as $field_name{
  622.             foreach ($constraints as $constraint_name => $constraint{
  623.                 if (!isset($dropped[$constraint_name]&& array_key_exists($field_name$constraint['fields'])) {
  624.                     $dropped[$constraint_name$constraint;
  625.                     $result $this->dropConstraint($table$constraint_name);
  626.                     if (MDB2::isError($result)) {
  627.                         return $result;
  628.                     }
  629.                 }
  630.             }
  631.             // also drop implicit DEFAULT constraints
  632.             $default $this->_getTableFieldDefaultConstraint($table$field_name);
  633.             if (!MDB2::isError($default&& !empty($default)) {
  634.                 $result $this->dropConstraint($table$default);
  635.                 if (MDB2::isError($result)) {
  636.                     return $result;
  637.                 }
  638.             }
  639.         }
  640.  
  641.         return $dropped;
  642.     }
  643.  
  644.     // }}}
  645.     // {{{ _getTableFieldDefaultConstraint()
  646.  
  647.     /**
  648.      * Get the default constraint for a table field
  649.      *
  650.      * @param string $table name of table that should be used in method
  651.      * @param string $field name of field that should be used in method
  652.      *
  653.      * @return mixed name of default constraint on success, a MDB2 error on failure
  654.      * @access private
  655.      */
  656.     function _getTableFieldDefaultConstraint($table$field)
  657.     {
  658.         $db =$this->getDBInstance();
  659.         if (MDB2::isError($db)) {
  660.             return $db;
  661.         }
  662.  
  663.         $table $db->quoteIdentifier($tabletrue);
  664.         $field $db->quote($field'text');
  665.         $query = "SELECT OBJECT_NAME(syscolumns.cdefault)
  666.                     FROM syscolumns
  667.                    WHERE syscolumns.id = object_id('$table')
  668.                      AND syscolumns.name = $field
  669.                      AND syscolumns.cdefault <> 0";
  670.         return $db->queryOne($query);
  671.     }
  672.  
  673.     // }}}
  674.     // {{{ listTables()
  675.  
  676.     /**
  677.      * list all tables in the current database
  678.      *
  679.      * @return mixed array of table names on success, a MDB2 error on failure
  680.      * @access public
  681.      */
  682.     function listTables()
  683.     {
  684.         $db =$this->getDBInstance();
  685.  
  686.         if (MDB2::isError($db)) {
  687.             return $db;
  688.         }
  689.         $res = odbc_tables($db->connection);
  690.         $result = array();
  691.         while (odbc_fetch_row($res)){
  692.              if(odbc_result($res,"TABLE_TYPE")=="TABLE"{
  693.                  $table_name = odbc_result($res,"TABLE_NAME");
  694.                 if (!$this->_fixSequenceName($table_nametrue)) {
  695.                     $result[$table_name;
  696.                 }                 
  697.              }
  698.         }
  699.  
  700.         if ($db->options['portability'MDB2_PORTABILITY_FIX_CASE{
  701.             $result array_map(($db->options['field_case'== CASE_LOWER ?
  702.                         'strtolower' 'strtoupper')$result);
  703.         }
  704.         return $result;
  705.     }
  706.  
  707.     // }}}
  708.     // {{{ listTableFields()
  709.  
  710.     /**
  711.      * list all fields in a table in the current database
  712.      *
  713.      * @param string $table name of table that should be used in method
  714.      *
  715.      * @return mixed array of field names on success, a MDB2 error on failure
  716.      * @access public
  717.      */
  718.     function listTableFields($table)
  719.     {
  720.         $db =$this->getDBInstance();
  721.         if (MDB2::isError($db)) {
  722.             return $db;
  723.         }
  724.  
  725.         $rs = odbc_columns($db->connection"%""%"$table);
  726.         $columns = array();
  727.         while($data = odbc_fetch_array($rs)) {
  728.             $columns[$data[COLUMN_NAME];
  729.         }
  730.         
  731.         /*
  732.         throw new Exception(); 
  733.         
  734.         $table = $db->quoteIdentifier($table, true);
  735.         $columns = $db->queryCol("SELECT c.name
  736.                                     FROM syscolumns c
  737.                                LEFT JOIN sysobjects o ON c.id = o.id
  738.                                    WHERE o.name = '$table'");
  739.         if (MDB2::isError($columns)) {
  740.             return $columns;
  741.         }
  742.         */
  743.         if ($db->options['portability'MDB2_PORTABILITY_FIX_CASE{
  744.             $columns array_map(($db->options['field_case'== CASE_LOWER ? 'strtolower' 'strtoupper')$columns);
  745.         }
  746.         return $columns;
  747.     }
  748.  
  749.     // }}}
  750.     // {{{ listTableIndexes()
  751.  
  752.     /**
  753.      * list all indexes in a table
  754.      *
  755.      * @param string $table name of table that should be used in method
  756.      *
  757.      * @return mixed array of index names on success, a MDB2 error on failure
  758.      * @access public
  759.      */
  760.     function listTableIndexes($table)
  761.     {
  762.         $db =$this->getDBInstance();
  763.         if (MDB2::isError($db)) {
  764.             return $db;
  765.         }
  766.  
  767.         $key_name 'INDEX_NAME';
  768.         $pk_name 'PK_NAME';
  769.         if ($db->options['portability'MDB2_PORTABILITY_FIX_CASE{
  770.             if ($db->options['field_case'== CASE_LOWER{
  771.                 $key_name strtolower($key_name);
  772.                 $pk_name  strtolower($pk_name);
  773.             else {
  774.                 $key_name strtoupper($key_name);
  775.                 $pk_name  strtoupper($pk_name);
  776.             }
  777.         }
  778.         
  779.         //$table = $db->quote($table, 'text');
  780.         //$query = "EXEC sp_statistics @table_name=$table";
  781.         $table "V_PARTNERSTAMM";
  782.         $res = odbc_statistics($db->connection,$db->dsn[username],$db->dsn[username],$table,0,0);
  783.         $indexes = array();
  784.         while($data = odbc_fetch_array($res)) {
  785.             $indexes[$data[$key_name];
  786.         }
  787.  
  788.         
  789.         $res = odbc_primarykeys($db->connection,$db->dsn[username],$db->dsn[username],$table);
  790.         
  791.         
  792.         $pk_all = array();
  793.         while($data = odbc_fetch_array($res)) {
  794.             $pk_all[$data[$key_name];
  795.         }
  796.  
  797.         $result = array();
  798.         foreach ($indexes as $index{
  799.             if (!in_array($index$pk_all&& ($index $this->_fixIndexName($index))) {
  800.                 $result[$index= true;
  801.             }
  802.         }
  803.  
  804.         if ($db->options['portability'MDB2_PORTABILITY_FIX_CASE{
  805.             $result array_change_key_case($result$db->options['field_case']);
  806.         }
  807.         return array_keys($result);
  808.     }
  809.  
  810.     // }}}
  811.     // {{{ listDatabases()
  812.  
  813.     /**
  814.      * list all databases
  815.      *
  816.      * @return mixed array of database names on success, a MDB2 error on failure
  817.      * @access public
  818.      */
  819.     function listDatabases()
  820.     {
  821.         $db =$this->getDBInstance();
  822.         if (MDB2::isError($db)) {
  823.             return $db;
  824.         }
  825.  
  826.         $result $db->queryCol('SELECT name FROM sys.databases');
  827.         if (MDB2::isError($result)) {
  828.             return $result;
  829.         }
  830.         if ($db->options['portability'MDB2_PORTABILITY_FIX_CASE{
  831.             $result array_map(($db->options['field_case'== CASE_LOWER ? 'strtolower' 'strtoupper')$result);
  832.         }
  833.         return $result;
  834.     }
  835.  
  836.     // }}}
  837.     // {{{ listUsers()
  838.  
  839.     /**
  840.      * list all users
  841.      *
  842.      * @return mixed array of user names on success, a MDB2 error on failure
  843.      * @access public
  844.      */
  845.     function listUsers()
  846.     {
  847.         $db =$this->getDBInstance();
  848.         if (MDB2::isError($db)) {
  849.             return $db;
  850.         }
  851.  
  852.         $result $db->queryCol('SELECT DISTINCT loginame FROM master..sysprocesses');
  853.         if (MDB2::isError($result|| empty($result)) {
  854.             return $result;
  855.         }
  856.         foreach (array_keys($resultas $k{
  857.             $result[$ktrim($result[$k]);
  858.         }
  859.         return $result;
  860.     }
  861.  
  862.     // }}}
  863.     // {{{ listFunctions()
  864.  
  865.     /**
  866.      * list all functions in the current database
  867.      *
  868.      * @return mixed array of function names on success, a MDB2 error on failure
  869.      * @access public
  870.      */
  871.     function listFunctions()
  872.     {
  873.         $db =$this->getDBInstance();
  874.         if (MDB2::isError($db)) {
  875.             return $db;
  876.         }
  877.  
  878.         $query "SELECT name
  879.                     FROM sysobjects
  880.                    WHERE objectproperty(id, N'IsMSShipped') = 0
  881.                     AND (objectproperty(id, N'IsTableFunction') = 1
  882.                      OR objectproperty(id, N'IsScalarFunction') = 1)";
  883.         /*
  884.         SELECT ROUTINE_NAME
  885.           FROM INFORMATION_SCHEMA.ROUTINES
  886.          WHERE ROUTINE_TYPE = 'FUNCTION'
  887.         */
  888.         $result $db->queryCol($query);
  889.         if (MDB2::isError($result)) {
  890.             return $result;
  891.         }
  892.         if ($db->options['portability'MDB2_PORTABILITY_FIX_CASE{
  893.             $result array_map(($db->options['field_case'== CASE_LOWER ? 'strtolower' 'strtoupper')$result);
  894.         }
  895.         return $result;
  896.     }
  897.  
  898.     // }}}
  899.     // {{{ listTableTriggers()
  900.  
  901.     /**
  902.      * list all triggers in the database that reference a given table
  903.      *
  904.      * @param string table for which all referenced triggers should be found
  905.      *
  906.      * @return mixed array of trigger names on success,  otherwise, false which
  907.      *                could be a db error if the db is not instantiated or could
  908.      *                be the results of the error that occured during the
  909.      *                querying of the sysobject module.
  910.      * @access public
  911.      */
  912.     function listTableTriggers($table = null)
  913.     {
  914.         $db =$this->getDBInstance();
  915.         if (MDB2::isError($db)) {
  916.             return $db;
  917.         }
  918.  
  919.         $table $db->quote($table'text');
  920.         $query "SELECT o.name
  921.                     FROM sysobjects o
  922.                    WHERE xtype = 'TR'
  923.                      AND OBJECTPROPERTY(o.id, 'IsMSShipped') = 0";
  924.         if (!is_null($table)) {
  925.             $query .= " AND object_name(parent_obj) = $table";
  926.         }
  927.  
  928.         $result $db->queryCol($query);
  929.         if (MDB2::isError($result)) {
  930.             return $result;
  931.         }
  932.  
  933.         if ($db->options['portability'MDB2_PORTABILITY_FIX_CASE &&
  934.             $db->options['field_case'== CASE_LOWER)
  935.         {
  936.             $result array_map(($db->options['field_case'== CASE_LOWER ?
  937.                 'strtolower' 'strtoupper')$result);
  938.         }
  939.         return $result;
  940.     }
  941.  
  942.     // }}}
  943.     // {{{ listViews()
  944.  
  945.     /**
  946.      * list all views in the current database
  947.      *
  948.      * @param string database, the current is default
  949.      *
  950.      * @return mixed array of view names on success, a MDB2 error on failure
  951.      * @access public
  952.      */
  953.     function listViews()
  954.     {
  955.         $db =$this->getDBInstance();
  956.         if (MDB2::isError($db)) {
  957.             return $db;
  958.         }
  959.  
  960.         $res = odbc_tables($db->connection);
  961.         $result = array();
  962.         while (odbc_fetch_row($res)){
  963.              if(odbc_result($res,"TABLE_TYPE")=="VIEW"{
  964.                  $table_name = odbc_result($res,"TABLE_NAME");
  965.                 if (!$this->_fixSequenceName($table_nametrue)) {
  966.                     $result[$table_name;
  967.                 }                 
  968.              }
  969.         }
  970.  
  971.         if ($db->options['portability'MDB2_PORTABILITY_FIX_CASE &&
  972.             $db->options['field_case'== CASE_LOWER)
  973.         {
  974.             $result array_map(($db->options['field_case'== CASE_LOWER ?
  975.                           'strtolower' 'strtoupper')$result);
  976.         }
  977.         return $result;
  978.     }
  979.  
  980.     // }}}
  981.     // {{{ dropIndex()
  982.  
  983.     /**
  984.      * drop existing index
  985.      *
  986.      * @param string $table name of table that should be used in method
  987.      * @param string $name  name of the index to be dropped
  988.      *
  989.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  990.      * @access public
  991.      */
  992.     function dropIndex($table$name)
  993.     {
  994.         $db =$this->getDBInstance();
  995.         if (MDB2::isError($db)) {
  996.             return $db;
  997.         }
  998.  
  999.         $table $db->quoteIdentifier($tabletrue);
  1000.         $name $db->quoteIdentifier($db->getIndexName($name)true);
  1001.         $result $db->exec("DROP INDEX $table.$name");
  1002.         if (MDB2::isError($result)) {
  1003.             return $result;
  1004.         }
  1005.         return MDB2_OK;
  1006.     }
  1007.  
  1008.     // }}}
  1009.     // {{{ listTableConstraints()
  1010.  
  1011.     /**
  1012.      * list all constraints in a table
  1013.      *
  1014.      * @param string $table name of table that should be used in method
  1015.      *
  1016.      * @return mixed array of constraint names on success, a MDB2 error on failure
  1017.      * @access public
  1018.      */
  1019.     function listTableConstraints($table)
  1020.     {
  1021.         return array();
  1022.         $db =$this->getDBInstance();
  1023.         if (MDB2::isError($db)) {
  1024.             return $db;
  1025.         }
  1026.         $table $db->quoteIdentifier($tabletrue);
  1027.  
  1028.         $query = "SELECT c.constraint_name
  1029.                     FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS c
  1030.                    WHERE c.constraint_catalog = DB_NAME()
  1031.                      AND c.table_name = '$table'";
  1032.         $constraints $db->queryCol($query);
  1033.         if (MDB2::isError($constraints)) {
  1034.             return $constraints;
  1035.         }
  1036.  
  1037.         $result = array();
  1038.         foreach ($constraints as $constraint{
  1039.             $constraint $this->_fixIndexName($constraint);
  1040.             if (!empty($constraint)) {
  1041.                 $result[$constraint= true;
  1042.             }
  1043.         }
  1044.  
  1045.         if ($db->options['portability'MDB2_PORTABILITY_FIX_CASE{
  1046.             $result array_change_key_case($result$db->options['field_case']);
  1047.         }
  1048.         return array_keys($result);
  1049.     }
  1050.  
  1051.     // }}}
  1052.     // {{{ createSequence()
  1053.  
  1054.     /**
  1055.      * create sequence
  1056.      *
  1057.      * @param string $seq_name name of the sequence to be created
  1058.      * @param string $start    start value of the sequence; default is 1
  1059.      *
  1060.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  1061.      * @access public
  1062.      */
  1063.     function createSequence($seq_name$start = 1)
  1064.     {
  1065.         $db =$this->getDBInstance();
  1066.         if (MDB2::isError($db)) {
  1067.             return $db;
  1068.         }
  1069.  
  1070.         $sequence_name $db->quoteIdentifier($db->getSequenceName($seq_name)true);
  1071.         $seqcol_name $db->quoteIdentifier($db->options['seqcol_name']true);
  1072.         $query = "CREATE TABLE $sequence_name ($seqcol_name " .
  1073.                  "INT PRIMARY KEY CLUSTERED IDENTITY($start,1) NOT NULL)";
  1074.  
  1075.         $res $db->exec($query);
  1076.         if (MDB2::isError($res)) {
  1077.             return $res;
  1078.         }
  1079.  
  1080.         $query = "SET IDENTITY_INSERT $sequence_name ON ".
  1081.                  "INSERT INTO $sequence_name ($seqcol_name) VALUES ($start)";
  1082.         $res $db->exec($query);
  1083.  
  1084.         if (!MDB2::isError($res)) {
  1085.             return MDB2_OK;
  1086.         }
  1087.  
  1088.         $result $db->exec("DROP TABLE $sequence_name");
  1089.         if (MDB2::isError($result)) {
  1090.             return $db->raiseError($resultnullnull,
  1091.                 'could not drop inconsistent sequence table'__FUNCTION__);
  1092.         }
  1093.  
  1094.         return $db->raiseError($resnullnull,
  1095.             'could not create sequence table'__FUNCTION__);
  1096.     }
  1097.  
  1098.     // }}}
  1099.     // {{{ dropSequence()
  1100.  
  1101.     /**
  1102.      * This function drops an existing sequence
  1103.      *
  1104.      * @param string $seq_name name of the sequence to be dropped
  1105.      *
  1106.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  1107.      * @access public
  1108.      */
  1109.     function dropSequence($seq_name)
  1110.     {
  1111.         $db =$this->getDBInstance();
  1112.         if (MDB2::isError($db)) {
  1113.             return $db;
  1114.         }
  1115.  
  1116.         $sequence_name $db->quoteIdentifier($db->getSequenceName($seq_name)true);
  1117.         $result $db->exec("DROP TABLE $sequence_name");
  1118.         if (MDB2::isError($result)) {
  1119.             return $result;
  1120.         }
  1121.         return MDB2_OK;
  1122.     }
  1123.  
  1124.     // }}}
  1125.     // {{{ listSequences()
  1126.  
  1127.     /**
  1128.      * list all sequences in the current database
  1129.      *
  1130.      * @return mixed array of sequence names on success, a MDB2 error on failure
  1131.      * @access public
  1132.      */
  1133.     function listSequences()
  1134.     {
  1135.         return array();
  1136.         $db =$this->getDBInstance();
  1137.         if (MDB2::isError($db)) {
  1138.             return $db;
  1139.         }
  1140.  
  1141.         $query "SELECT name FROM sysobjects WHERE xtype = 'U'";
  1142.         $table_names $db->queryCol($query);
  1143.         if (MDB2::isError($table_names)) {
  1144.             return $table_names;
  1145.         }
  1146.         $result = array();
  1147.         foreach ($table_names as $table_name{
  1148.             if ($sqn $this->_fixSequenceName($table_nametrue)) {
  1149.                 $result[$sqn;
  1150.             }
  1151.         }
  1152.         if ($db->options['portability'MDB2_PORTABILITY_FIX_CASE{
  1153.             $result array_map(($db->options['field_case'== CASE_LOWER ?
  1154.                           'strtolower' 'strtoupper')$result);
  1155.         }
  1156.         return $result;
  1157.     }
  1158.  
  1159.     // }}}
  1160. }
  1161.  
  1162. // }}}
  1163. ?>

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