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

Source for file mssql.php

Documentation is available at mssql.php

  1. <?php
  2. // vim: set et ts=4 sw=4 fdm=marker:
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 4                                                        |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox,                 |
  7. // | Stig. S. Bakken, Lukas Smith, Frank M. Kromann                       |
  8. // | All rights reserved.                                                 |
  9. // +----------------------------------------------------------------------+
  10. // | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB  |
  11. // | API as well as database abstraction for PHP applications.            |
  12. // | This LICENSE is in the BSD license style.                            |
  13. // |                                                                      |
  14. // | Redistribution and use in source and binary forms, with or without   |
  15. // | modification, are permitted provided that the following conditions   |
  16. // | are met:                                                             |
  17. // |                                                                      |
  18. // | Redistributions of source code must retain the above copyright       |
  19. // | notice, this list of conditions and the following disclaimer.        |
  20. // |                                                                      |
  21. // | Redistributions in binary form must reproduce the above copyright    |
  22. // | notice, this list of conditions and the following disclaimer in the  |
  23. // | documentation and/or other materials provided with the distribution. |
  24. // |                                                                      |
  25. // | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken,    |
  26. // | Lukas Smith nor the names of his contributors may be used to endorse |
  27. // | or promote products derived from this software without specific prior|
  28. // | written permission.                                                  |
  29. // |                                                                      |
  30. // | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS  |
  31. // | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT    |
  32. // | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS    |
  33. // | FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE      |
  34. // | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,          |
  35. // | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
  36. // | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
  37. // |  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED  |
  38. // | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT          |
  39. // | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
  40. // | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE          |
  41. // | POSSIBILITY OF SUCH DAMAGE.                                          |
  42. // +----------------------------------------------------------------------+
  43. // | Author: Frank M. Kromann <frank@kromann.info>                        |
  44. // +----------------------------------------------------------------------+
  45. //
  46. // $Id: mssql.php,v 1.12 2004/04/25 10:04:59 lsmith Exp $
  47. //
  48.  
  49. /**
  50.  * MDB2 MSSQL Server driver
  51.  *
  52.  * @package MDB2
  53.  * @category Database
  54.  * @author  Frank M. Kromann <frank@kromann.info>
  55.  */
  56. {
  57.     // {{{ properties
  58.     var $escape_quotes = "'";
  59.  
  60.     // }}}
  61.     // {{{ constructor
  62.  
  63.     /**
  64.     * Constructor
  65.     */
  66.     function MDB2_Driver_mssql()
  67.     {
  68.         $this->MDB2_Driver_Common();
  69.         $this->phptype 'mssql';
  70.         $this->dbsyntax 'mssql';
  71.  
  72.         $this->supported['sequences'= true;
  73.         $this->supported['indexes'= true;
  74.         $this->supported['affected_rows'= true;
  75.         $this->supported['summary_functions'= true;
  76.         $this->supported['order_by_text'= true;
  77.         $this->supported['current_id'= false;
  78.         $this->supported['limit_queries'= true;
  79.         $this->supported['LOBs'= true;
  80.         $this->supported['replace'= true;
  81.         $this->supported['sub_selects'= true;
  82.         $this->supported['transactions'= true;
  83.  
  84.         $db->options['database_device'= false;
  85.         $db->options['database_size'= false;
  86.     }
  87.  
  88.     // }}}
  89.     // {{{ errorInfo()
  90.  
  91.     /**
  92.      * This method is used to collect information about an error
  93.      *
  94.      * @param integer $error 
  95.      * @return array 
  96.      * @access public
  97.      */
  98.     function errorInfo($error = null)
  99.     {
  100.         $native_code = null;
  101.         $result @mssql_query('select @@ERROR as ErrorCode'$this->connection);
  102.         if ($result{
  103.             $native_code @mssql_result($result);
  104.             @mssql_free_result($result);
  105.         }
  106.         $native_msg @mssql_get_last_message();
  107.         if (is_null($error)) {
  108.             static $ecode_map;
  109.             if (empty($ecode_map)) {
  110.                 $ecode_map = array(
  111.                     207   => MDB2_ERROR_NOSUCHFIELD,
  112.                     208   => MDB2_ERROR_NOSUCHTABLE,
  113.                     245   => MDB2_ERROR_INVALID_NUMBER,
  114.                     515   => MDB2_ERROR_CONSTRAINT_NOT_NULL,
  115.                     547   => MDB2_ERROR_CONSTRAINT,
  116.                     1205  => MDB2_ERROR_DEADLOCK,
  117.                     2627  => MDB2_ERROR_CONSTRAINT,
  118.                     2714  => MDB2_ERROR_ALREADY_EXISTS,
  119.                     3701  => MDB2_ERROR_NOSUCHTABLE,
  120.                     8134  => MDB2_ERROR_DIVZERO,
  121.                 );
  122.              }
  123.             if (isset($ecode_map[$native_code])) {
  124.                 $error $ecode_map[$native_code];
  125.             }
  126.         }
  127.         return array($error$native_code$native_msg);
  128.     }
  129.  
  130.     // }}}
  131.     // {{{ quoteIdentifier()
  132.  
  133.     /**
  134.      * Quote a string so it can be safely used as a table / column name
  135.      *
  136.      * Quoting style depends on which database driver is being used.
  137.      *
  138.      * @param string $str  identifier name to be quoted
  139.      *
  140.      * @return string  quoted identifier string
  141.      *
  142.      * @since 1.6.0
  143.      * @access public
  144.      */
  145.     function quoteIdentifier($str)
  146.     {
  147.         return '[' str_replace(']'']]'$str']';
  148.     }
  149.  
  150.     // }}}
  151.     // {{{ autoCommit()
  152.  
  153.     /**
  154.      * Define whether database changes done on the database be automatically
  155.      * committed. This function may also implicitly start or end a transaction.
  156.      *
  157.      * @param boolean $auto_commit    flag that indicates whether the database
  158.      *                                 changes should be committed right after
  159.      *                                 executing every query statement. If this
  160.      *                                 argument is 0 a transaction implicitly
  161.      *                                 started. Otherwise, if a transaction is
  162.      *                                 in progress it is ended by committing any
  163.      *                                 database changes that were pending.
  164.      *
  165.      * @access public
  166.      *
  167.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  168.      */
  169.     function autoCommit($auto_commit)
  170.     {
  171.         $this->debug(($auto_commit 'On' 'Off')'autoCommit');
  172.         if ($this->auto_commit == $auto_commit{
  173.             return MDB2_OK;
  174.         }
  175.         if ($this->connection{
  176.             if ($auto_commit{
  177.                 $result $this->query('COMMIT TRANSACTION');
  178.             else {
  179.                 $result $this->query('BEGIN TRANSACTION');
  180.             }
  181.             if (MDB2::isError($result)) {
  182.                 return $result;
  183.             }
  184.         }
  185.         $this->auto_commit = $auto_commit;
  186.         $this->in_transaction !$auto_commit;
  187.         return MDB2_OK;
  188.     }
  189.  
  190.     // }}}
  191.     // {{{ commit()
  192.  
  193.     /**
  194.      * Commit the database changes done during a transaction that is in
  195.      * progress. This function may only be called when auto-committing is
  196.      * disabled, otherwise it will fail. Therefore, a new transaction is
  197.      * implicitly started after committing the pending changes.
  198.      *
  199.      * @access public
  200.      *
  201.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  202.      */
  203.     function commit()
  204.     {
  205.         $this->debug('commit transaction''commit');
  206.         if ($this->auto_commit{
  207.             return $this->raiseError(MDB2_ERRORnullnull,
  208.             'commit: transaction changes are being auto commited');
  209.         }
  210.         $result $this->query('COMMIT TRANSACTION');
  211.         if (MDB2::isError($result)) {
  212.             return $result;
  213.         }
  214.         return $this->query('BEGIN TRANSACTION');
  215.     }
  216.  
  217.     // }}}
  218.     // {{{ rollback()
  219.  
  220.     /**
  221.      * Cancel any database changes done during a transaction that is in
  222.      * progress. This function may only be called when auto-committing is
  223.      * disabled, otherwise it will fail. Therefore, a new transaction is
  224.      * implicitly started after canceling the pending changes.
  225.      *
  226.      * @access public
  227.      *
  228.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  229.      */
  230.     function rollback()
  231.     {
  232.         $this->debug('rolling back transaction''rollback');
  233.         if ($this->auto_commit{
  234.             return $this->raiseError(MDB2_ERRORnullnull,
  235.                 'rollback: transactions can not be rolled back when changes are auto commited');
  236.         }
  237.         $result $this->query('ROLLBACK TRANSACTION');
  238.         if (MDB2::isError($result)) {
  239.             return $result;
  240.         }
  241.         return $this->query('BEGIN TRANSACTION');
  242.     }
  243.  
  244.     function _doQuery($query)
  245.     {
  246.         $this->current_row $this->affected_rows = -1;
  247.         return @mssql_query($query$this->connection);
  248.     }
  249.  
  250.     // }}}
  251.     // {{{ connect()
  252.  
  253.     /**
  254.      * Connect to the database
  255.      *
  256.      * @return true on success, MDB2 Error Object on failure
  257.      ***/
  258.     function connect()
  259.     {
  260.         if ($this->connection != 0{
  261.             if (count(array_diff($this->connected_dsn$this->dsn)) == 0
  262.                 && $this->opened_persistent == $this->options['persistent'])
  263.             {
  264.                 return MDB2_OK;
  265.             }
  266.             @mssql_close($this->connection);
  267.             $this->connection = 0;
  268.             $this->affected_rows = -1;
  269.         }
  270.  
  271.         if (!PEAR::loadExtension($this->phptype)) {
  272.             return $this->raiseError(nullMDB2_ERROR_NOT_FOUNDnullnull,
  273.                 'connect: extension '.$this->phptype.' is not compiled into PHP');
  274.         }
  275.  
  276.         $function ($this->options['persistent''mssql_pconnect' 'mssql_connect');
  277.  
  278.         $dsninfo $this->dsn;
  279.         $user $dsninfo['username'];
  280.         $pw $dsninfo['password'];
  281.         $dbhost $dsninfo['hostspec'$dsninfo['hostspec''localhost';
  282.         $port   $dsninfo['port'':' $dsninfo['port''';
  283.         $dbhost .= $port;
  284.  
  285.         @ini_set('track_errors'true);
  286.         if ($dbhost && $user && $pw{
  287.             $connection @$function($dbhost$user$pw);
  288.         elseif ($dbhost && $user{
  289.             $connection @$function($dbhost$user);
  290.         elseif ($dbhost{
  291.             $connection @$function($dbhost);
  292.         else {
  293.             $connection = 0;
  294.         }
  295.         @ini_restore('track_errors');
  296.         if ($connection <= 0{
  297.             return $this->raiseError(MDB2_ERROR_CONNECT_FAILEDnullnull,
  298.                 $php_errormsg);
  299.         }
  300.         $this->connection $connection;
  301.         $this->connected_dsn $this->dsn;
  302.         $this->connected_database_name '';
  303.         $this->opened_persistent $this->options['persistent'];
  304.  
  305.         if (isset($this->supported['transactions'])
  306.             && !$this->auto_commit
  307.             && MDB2::isError($this->_doQuery('BEGIN TRANSACTION'))
  308.         {
  309.             @mssql_close($this->connection);
  310.             $this->connection = 0;
  311.             $this->affected_rows = -1;
  312.             return $this->raiseError('connect: Could not begin the initial transaction');
  313.         }
  314.         return MDB2_OK;
  315.     }
  316.  
  317.     // }}}
  318.     // {{{ _close()
  319.     /**
  320.      * all the RDBMS specific things needed close a DB connection
  321.      *
  322.      * @return boolean 
  323.      * @access private
  324.      ***/
  325.     function _close()
  326.     {
  327.         if ($this->connection != 0{
  328.             if (isset($this->supported['transactions']&& !$this->auto_commit{
  329.                 $result $this->_doQuery('ROLLBACK TRANSACTION');
  330.             }
  331.             @mssql_close($this->connection);
  332.             $this->connection = 0;
  333.             $this->affected_rows = -1;
  334.             unset($GLOBALS['_MDB2_databases'][$this->db_index]);
  335.  
  336.             if (isset($result&& MDB2::isError($result)) {
  337.                 return $result;
  338.             }
  339.  
  340.         }
  341.         return MDB2_OK;
  342.     }
  343.  
  344.     // }}}
  345.     // {{{ standaloneQuery()
  346.  
  347.    /**
  348.      * execute a query as DBA
  349.      *
  350.      * @param string $query the SQL query
  351.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  352.      * @access public
  353.      */
  354.     function standaloneQuery($query)
  355.     {
  356.         if (!PEAR::loadExtension($this->phptype)) {
  357.             return $this->raiseError(nullMDB2_ERROR_NOT_FOUNDnullnull,
  358.                 'standaloneQuery: extension '.$this->phptype.' is not compiled into PHP');
  359.         }
  360.         $connection @mssql_connect($this->dsn['hostspec'],$this->dsn['username'],$this->dsn['password']);
  361.         if ($connection == 0{
  362.             return $this->raiseError('standaloneQuery: Could not connect to the Microsoft SQL server');
  363.         }
  364.         $result @mssql_query($query$connection);
  365.         if (!$result{
  366.             return $this->raiseError('standaloneQuery: Could not query a Microsoft SQL server');
  367.         }
  368.         @mssql_close($connection);
  369.         return MDB2_OK;
  370.     }
  371.  
  372.     // }}}
  373.     // {{{ query()
  374.  
  375.     /**
  376.      * Send a query to the database and return any results
  377.      *
  378.      * @param string  $query  the SQL query
  379.      * @param mixed   $types  array that contains the types of the columns in
  380.      *                         the result set
  381.      * @param mixed $result_class string which specifies which result class to use
  382.      * @param mixed $result_wrap_class string which specifies which class to wrap results in
  383.      * @return mixed a result handle or MDB2_OK on success, a MDB2 error on failure
  384.      *
  385.      * @access public
  386.      */
  387.     function &query($query$types = null$result_class = false$result_wrap_class = false)
  388.     {
  389.         $ismanip MDB2::isManip($query);
  390.         $offset $this->row_offset;
  391.         $limit $this->row_limit;
  392.         $this->row_offset $this->row_limit = 0;
  393.         if ($limit > 0{
  394.             $fetch $offset $limit;
  395.             if (!$ismanip{
  396.                 $query str_replace('SELECT'"SELECT TOP $fetch"$query);
  397.             }
  398.         }
  399.         $this->last_query = $query;
  400.         $this->debug($query'query');
  401.  
  402.         $connected $this->connect();
  403.         if (MDB2::isError($connected)) {
  404.             return $connected;
  405.         }
  406.  
  407.         if ($this->database_name{
  408.             if (!@mssql_select_db($this->database_name$this->connection)) {
  409.                 $error =$this->raiseError();
  410.                 return $error;
  411.             }
  412.             $this->connected_database_name $this->database_name;
  413.         }
  414.         if ($result $this->_doQuery($query)) {
  415.             if ($ismanip{
  416.                 return MDB2_OK;
  417.             else {
  418.                 if (!$result_class{
  419.                     $result_class $this->options['result_buffering']
  420.                         ? $this->options['buffered_result_class'$this->options['result_class'];
  421.                 }
  422.                 $class_name sprintf($result_class$this->phptype);
  423.                 $result =new $class_name($this$result$offset$limit);
  424.                 if ($types{
  425.                     $err $result->setResultTypes($types);
  426.                     if (MDB2::isError($err)) {
  427.                         $result->free();
  428.                         return $err;
  429.                     }
  430.                 }
  431.                 if (!$result_wrap_class{
  432.                     $result_wrap_class $this->options['result_wrap_class'];
  433.                 }
  434.                 if ($result_wrap_class{
  435.                     $result =new $result_wrap_class($result);
  436.                 }
  437.                 return $result;
  438.             }
  439.         }
  440.         $error =$this->raiseError();
  441.         return $error;
  442.     }
  443.  
  444.     // }}}
  445.     // {{{ affectedRows()
  446.  
  447.     /**
  448.      * returns the affected rows of a query
  449.      *
  450.      * @return mixed MDB2 Error Object or number of rows
  451.      * @access public
  452.      */
  453.     function affectedRows()
  454.     {
  455.         $affected_rows @mssql_affected_rows($this->connection);
  456.         if ($affected_rows === false{
  457.             return $this->raiseError(MDB2_ERROR_NEED_MORE_DATA);
  458.         }
  459.         return $affected_rows;
  460.     }
  461.  
  462.     // }}}
  463.     // {{{ nextID()
  464.  
  465.     /**
  466.      * returns the next free id of a sequence
  467.      *
  468.      * @param string  $seq_name name of the sequence
  469.      * @param boolean $ondemand when true the seqence is
  470.      *                           automatic created, if it
  471.      *                           not exists
  472.      *
  473.      * @return mixed MDB2 Error Object or id
  474.      * @access public
  475.      */
  476.     function nextID($seq_name$ondemand = true)
  477.     {
  478.         $sequence_name $this->getSequenceName($seq_name);
  479.         $this->expectError(MDB2_ERROR_NOSUCHTABLE);
  480.         $result $this->query("INSERT INTO $sequence_name DEFAULT VALUES");
  481.         $this->popExpect();
  482.         if (MDB2::isError($result)) {
  483.             if ($ondemand && $result->getCode(== MDB2_ERROR_NOSUCHTABLE{
  484.                 $this->loadModule('manager');
  485.                 // Since we are creating the sequence on demand
  486.                 // we know the first id = 1 so initialize the
  487.                 // sequence at 2
  488.                 $result $this->manager->createSequence($seq_name2);
  489.                 if (MDB2::isError($result)) {
  490.                     return $this->raiseError(MDB2_ERRORnullnull,
  491.                         'nextID: on demand sequence could not be created');
  492.                 else {
  493.                     // First ID of a newly created sequence is 1
  494.                     return 1;
  495.                 }
  496.             }
  497.             return $result;
  498.         }
  499.         $value $this->queryOne("SELECT @@IDENTITY FROM $sequence_name"'integer');
  500.         if (is_numeric($value)
  501.             && MDB2::isError($this->query("DELETE FROM $sequence_name WHERE ".$this->options['seqname_col_name']." < $value"))
  502.         {
  503.             $this->warnings['nextID: could not delete previous sequence table values';
  504.         }
  505.         return $value;
  506.     }
  507. }
  508.  
  509. class MDB2_Result_mssql extends MDB2_Result_Common
  510. {
  511.     var $limits;
  512.  
  513.     // }}}
  514.     // {{{ constructor
  515.  
  516.     /**
  517.      * Constructor
  518.      */
  519.     function MDB2_Result_mssql(&$mdb&$result$offset$limit)
  520.     {
  521.         parent::MDB2_Result_Common($mdb$result);
  522.         if ($offset || $limit{
  523.             $this->limits = array(
  524.                 'offset' => $offset,
  525.                 'limit' => $limit,
  526.                 'count' => 0
  527.             );
  528.         }
  529.     }
  530.  
  531.     // }}}
  532.     // {{{ _skipLimitOffset()
  533.  
  534.     /**
  535.      * Skip the first row of a result set.
  536.      *
  537.      * @param resource $result 
  538.      * @return mixed a result handle or MDB2_OK on success, a MDB2 error on failure
  539.      * @access private
  540.      */
  541.     function _skipLimitOffset()
  542.     {
  543.         if (isset($this->limits&& is_array($this->limits)) {
  544.             if ($this->rownum >= $this->limits['limit']{
  545.                 return MDB2_ERROR;
  546.             }
  547.             while ($this->limits['count'$this->limits['offset']{
  548.                 $this->limits['count']++;
  549.                 if (!is_array(@mysql_fetch_row($this->result))) {
  550.                     $this->limits['count'$this->limits['offset'];
  551.                     return MDB2_ERROR;
  552.                 }
  553.             }
  554.         }
  555.         return MDB2_OK;
  556.     }
  557.  
  558.     // }}}
  559.     // {{{ fetch()
  560.  
  561.     /**
  562.     * fetch value from a result set
  563.     *
  564.     * @param int    $rownum    number of the row where the data can be found
  565.     * @param int    $colnum    field number where the data can be found
  566.     * @return mixed string on success, a MDB2 error on failure
  567.     * @access public
  568.     */
  569.     function fetch($rownum = 0$colnum = 0)
  570.     {
  571.         $value @mssql_result($this->result$rownum$colnum);
  572.         if (!$value{
  573.             if (is_null($this->result)) {
  574.                 return $this->mdb->raiseError(MDB2_ERROR_NEED_MORE_DATAnullnull,
  575.                     'fetch: resultset has already been freed');
  576.             }
  577.         }
  578.         if (isset($this->types[$colnum])) {
  579.             $value $this->mdb->datatype->convertResult($value$this->types[$colnum]);
  580.         }
  581.         if ($this->mdb->options['portability'MDB2_PORTABILITY_RTRIM{
  582.             $value rtrim($value);
  583.         }
  584.         if ($value === ''
  585.             && $this->mdb->options['portability'MDB2_PORTABILITY_EMPTY_TO_NULL
  586.         {
  587.             $value = null;
  588.         }
  589.         return $value;
  590.     }
  591.  
  592.     // }}}
  593.     // {{{ fetchRow()
  594.  
  595.     /**
  596.      * Fetch a row and insert the data into an existing array.
  597.      *
  598.      * @param int       $fetchmode  how the array data should be indexed
  599.      * @return int data array on success, a MDB2 error on failure
  600.      * @access public
  601.      */
  602.     function fetchRow($fetchmode = MDB2_FETCHMODE_DEFAULT)
  603.     {
  604.         if ($fetchmode == MDB2_FETCHMODE_DEFAULT{
  605.             $fetchmode $this->mdb->fetchmode;
  606.         }
  607.         if (!$this->_skipLimitOffset()) {
  608.             return null;
  609.         }
  610.         if ($fetchmode MDB2_FETCHMODE_ASSOC{
  611.             $row @mssql_fetch_assoc($this->result);
  612.             if (is_array($row)
  613.                 && $this->mdb->options['portability'MDB2_PORTABILITY_LOWERCASE
  614.             {
  615.                 $row array_change_key_case($rowCASE_LOWER);
  616.             }
  617.         else {
  618.             $row @mssql_fetch_row($this->result);
  619.         }
  620.         if (!$row{
  621.             if (is_null($this->result)) {
  622.                 return $this->mdb->raiseError(MDB2_ERROR_NEED_MORE_DATAnullnull,
  623.                     'fetchRow: resultset has already been freed');
  624.             }
  625.             return null;
  626.         }
  627.         if (isset($this->types)) {
  628.             $row $this->mdb->datatype->convertResultRow($this->types$row);
  629.         }
  630.         if ($this->mdb->options['portability'MDB2_PORTABILITY_EMPTY_TO_NULL{
  631.             $this->mdb->_convertEmptyArrayValuesToNull($row);
  632.         }
  633.         ++$this->rownum;
  634.         return $row;
  635.     }
  636.  
  637.     // }}}
  638.     // {{{ getColumnNames()
  639.  
  640.     /**
  641.      * Retrieve the names of columns returned by the DBMS in a query result.
  642.      *
  643.      * @param resource $result result identifier
  644.      * @return mixed associative array variable
  645.      *       that holds the names of columns. The indexes of the array are
  646.      *       the column names mapped to lower case and the values are the
  647.      *       respective numbers of the columns starting from 0. Some DBMS may
  648.      *       not return any columns when the result set does not contain any
  649.      *       rows.
  650.      * @access public
  651.      */
  652.     function getColumnNames()
  653.     {
  654.         $columns = array();
  655.         $numcols $this->numCols();
  656.         if (MDB2::isError($numcols)) {
  657.             return $numcols;
  658.         }
  659.         for ($column = 0; $column $numcols$column++{
  660.             $column_name @mssql_field_name($this->result$column);
  661.             $columns[$column_name$column;
  662.         }
  663.         if ($this->mdb->options['portability'MDB2_PORTABILITY_LOWERCASE{
  664.             $columns array_change_key_case($columnsCASE_LOWER);
  665.         }
  666.         return $columns;
  667.     }
  668.  
  669.     // }}}
  670.     // {{{ numCols()
  671.  
  672.     /**
  673.      * Count the number of columns returned by the DBMS in a query result.
  674.      *
  675.      * @return mixed integer value with the number of columns, a MDB2 error
  676.      *       on failure
  677.      * @access public
  678.      */
  679.     function numCols()
  680.     {
  681.         $cols @mssql_num_fields($this->result);
  682.         if (is_null($cols)) {
  683.             if (is_null($this->result)) {
  684.                 return $this->mdb->raiseError(MDB2_ERROR_NEED_MORE_DATAnullnull,
  685.                     'numCols: resultset has already been freed');
  686.             }
  687.             return $this->mdb->raiseError();
  688.         }
  689.         return $cols;
  690.     }
  691.  
  692.     // }}}
  693.     // {{{ nextResult()
  694.  
  695.     /**
  696.      * Move the internal result pointer to the next available result
  697.      * Currently not supported
  698.      *
  699.      * @return true if a result is available otherwise return false
  700.      * @access public
  701.      */
  702.     function nextResult()
  703.     {
  704.         if (is_null($this->result)) {
  705.             return $this->mdb->raiseError(MDB2_ERROR_NEED_MORE_DATAnullnull,
  706.                 'nextResult: resultset has already been freed');
  707.         }
  708.         return @mssql_next_result($this->result);
  709.     }
  710.  
  711.     // }}}
  712.     // {{{ free()
  713.  
  714.     /**
  715.      * Free the internal resources associated with $result.
  716.      *
  717.      * @return boolean true on success, false if $result is invalid
  718.      * @access public
  719.      */
  720.     function free()
  721.     {
  722.         $free @mssql_free_result($this->result);
  723.         if (!$free{
  724.             if (is_null($this->result)) {
  725.                 return MDB2_OK;
  726.             }
  727.             return $this->mdb->raiseError();
  728.         }
  729.         $this->result = null;
  730.         return MDB2_OK;
  731.     }
  732. }
  733.  
  734. class MDB2_BufferedResult_mssql extends MDB2_Result_mssql
  735. {
  736.     // }}}
  737.     // {{{ constructor
  738.  
  739.     /**
  740.      * Constructor
  741.      */
  742.     function MDB2_BufferedResult_mssql(&$mdb&$result$offset$limit)
  743.     {
  744.         parent::MDB2_Result_mssql($mdb$result$offset$limit);
  745.     }
  746.  
  747.     // }}}
  748.     // {{{ valid()
  749.  
  750.     /**
  751.      * check if the end of the result set has been reached
  752.      *
  753.      * @return mixed true or false on sucess, a MDB2 error on failure
  754.      * @access public
  755.      */
  756.     function valid()
  757.     {
  758.         $numrows $this->numRows();
  759.         if (MDB2::isError($numrows)) {
  760.             return $numrows;
  761.         }
  762.         return $this->rownum ($numrows - 1);
  763.     }
  764.  
  765.     // }}}
  766.     // {{{ numRows()
  767.  
  768.     /**
  769.      * returns the number of rows in a result object
  770.      *
  771.      * @return mixed MDB2 Error Object or the number of rows
  772.      * @access public
  773.      */
  774.     function numRows()
  775.     {
  776.         $rows @mssql_num_rows($this->result);
  777.         if (is_null($rows)) {
  778.             if (is_null($this->result)) {
  779.                 return $this->mdb->raiseError(MDB2_ERROR_NEED_MORE_DATAnullnull,
  780.                     'numRows: resultset has already been freed');
  781.             }
  782.             return $this->raiseError();
  783.         }
  784.         if (isset($this->limits)) {
  785.             $rows -= $this->limits[0];
  786.             if ($rows < 0{
  787.                 $rows = 0;
  788.             }
  789.         }
  790.         return $rows;
  791.     }
  792. }
  793.  
  794. ?>

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