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

Source for file mssql.php

Documentation is available at mssql.php

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 4                                                        |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2004 The PHP Group                                |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.02 of the PHP license,      |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available at through the world-wide-web at                           |
  11. // | http://www.php.net/license/2_02.txt.                                 |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Author: Sterling Hughes <sterling@php.net>                           |
  17. // | Maintainer: Daniel Convissor <danielc@php.net>                       |
  18. // +----------------------------------------------------------------------+
  19. //
  20. // $Id: mssql.php,v 1.53 2004/03/05 01:46:53 danielc Exp $
  21.  
  22. require_once 'DB/common.php';
  23.  
  24. /**
  25.  * Database independent query interface definition for PHP's Microsoft SQL Server
  26.  * extension.
  27.  *
  28.  * @package  DB
  29.  * @version  $Id: mssql.php,v 1.53 2004/03/05 01:46:53 danielc Exp $
  30.  * @category Database
  31.  * @author   Sterling Hughes <sterling@php.net>
  32.  */
  33. class DB_mssql extends DB_common
  34. {
  35.     // {{{ properties
  36.  
  37.     var $connection;
  38.     var $phptype$dbsyntax;
  39.     var $prepare_tokens = array();
  40.     var $prepare_types = array();
  41.     var $transaction_opcount = 0;
  42.     var $autocommit = true;
  43.     var $_db = null;
  44.  
  45.     // }}}
  46.     // {{{ constructor
  47.  
  48.     function DB_mssql()
  49.     {
  50.         $this->DB_common();
  51.         $this->phptype = 'mssql';
  52.         $this->dbsyntax = 'mssql';
  53.         $this->features = array(
  54.             'prepare' => false,
  55.             'pconnect' => true,
  56.             'transactions' => true,
  57.             'limit' => 'emulate'
  58.         );
  59.         // XXX Add here error codes ie: 'S100E' => DB_ERROR_SYNTAX
  60.         $this->errorcode_map = array(
  61.             170   => DB_ERROR_SYNTAX,
  62.             207   => DB_ERROR_NOSUCHFIELD,
  63.             208   => DB_ERROR_NOSUCHTABLE,
  64.             245   => DB_ERROR_INVALID_NUMBER,
  65.             515   => DB_ERROR_CONSTRAINT_NOT_NULL,
  66.             547   => DB_ERROR_CONSTRAINT,
  67.             2627  => DB_ERROR_CONSTRAINT,
  68.             2714  => DB_ERROR_ALREADY_EXISTS,
  69.             3701  => DB_ERROR_NOSUCHTABLE,
  70.             8134  => DB_ERROR_DIVZERO,
  71.         );
  72.     }
  73.  
  74.     // }}}
  75.     // {{{ connect()
  76.  
  77.     function connect($dsninfo$persistent = false)
  78.     {
  79.         if (!DB::assertExtension('mssql'&& !DB::assertExtension('sybase')
  80.             && !DB::assertExtension('sybase_ct'))
  81.         {
  82.             return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
  83.         }
  84.         $this->dsn $dsninfo;
  85.         $dbhost $dsninfo['hostspec'$dsninfo['hostspec''localhost';
  86.         $dbhost .= $dsninfo['port'':' $dsninfo['port''';
  87.  
  88.         $connect_function $persistent 'mssql_pconnect' 'mssql_connect';
  89.  
  90.         if ($dbhost && $dsninfo['username'&& $dsninfo['password']{
  91.             $conn @$connect_function($dbhost$dsninfo['username'],
  92.                                        $dsninfo['password']);
  93.         elseif ($dbhost && $dsninfo['username']{
  94.             $conn @$connect_function($dbhost$dsninfo['username']);
  95.         else {
  96.             $conn @$connect_function($dbhost);
  97.         }
  98.         if (!$conn{
  99.             return $this->raiseError(DB_ERROR_CONNECT_FAILEDnullnull,
  100.                                          null@mssql_get_last_message());
  101.         }
  102.         if ($dsninfo['database']{
  103.             if (!@mssql_select_db($dsninfo['database']$conn)) {
  104.                 return $this->raiseError(DB_ERROR_NODBSELECTEDnullnull,
  105.                                          null@mssql_get_last_message());
  106.             }
  107.             $this->_db $dsninfo['database'];
  108.         }
  109.         $this->connection = $conn;
  110.         return DB_OK;
  111.     }
  112.  
  113.     // }}}
  114.     // {{{ disconnect()
  115.  
  116.     function disconnect()
  117.     {
  118.         $ret @mssql_close($this->connection);
  119.         $this->connection = null;
  120.         return $ret;
  121.     }
  122.  
  123.     // }}}
  124.     // {{{ simpleQuery()
  125.  
  126.     function simpleQuery($query)
  127.     {
  128.         $ismanip DB::isManip($query);
  129.         $this->last_query = $query;
  130.         if (!@mssql_select_db($this->_db$this->connection)) {
  131.             return $this->mssqlRaiseError(DB_ERROR_NODBSELECTED);
  132.         }
  133.         $query $this->modifyQuery($query);
  134.         if (!$this->autocommit && $ismanip{
  135.             if ($this->transaction_opcount == 0{
  136.                 $result @mssql_query('BEGIN TRAN'$this->connection);
  137.                 if (!$result{
  138.                     return $this->mssqlRaiseError();
  139.                 }
  140.             }
  141.             $this->transaction_opcount++;
  142.         }
  143.         $result @mssql_query($query$this->connection);
  144.         if (!$result{
  145.             return $this->mssqlRaiseError();
  146.         }
  147.         // Determine which queries that should return data, and which
  148.         // should return an error code only.
  149.         return $ismanip DB_OK : $result;
  150.     }
  151.  
  152.     // }}}
  153.     // {{{ nextResult()
  154.  
  155.     /**
  156.      * Move the internal mssql result pointer to the next available result
  157.      *
  158.      * @param valid fbsql result resource
  159.      *
  160.      * @access public
  161.      *
  162.      * @return true if a result is available otherwise return false
  163.      */
  164.     function nextResult($result)
  165.     {
  166.         return @mssql_next_result($result);
  167.     }
  168.  
  169.     // }}}
  170.     // {{{ fetchInto()
  171.  
  172.     /**
  173.      * Fetch a row and insert the data into an existing array.
  174.      *
  175.      * Formating of the array and the data therein are configurable.
  176.      * See DB_result::fetchInto() for more information.
  177.      *
  178.      * @param resource $result    query result identifier
  179.      * @param array    $arr       (reference) array where data from the row
  180.      *                             should be placed
  181.      * @param int      $fetchmode how the resulting array should be indexed
  182.      * @param int      $rownum    the row number to fetch
  183.      *
  184.      * @return mixed DB_OK on success, null when end of result set is
  185.      *                reached or on failure
  186.      *
  187.      * @see DB_result::fetchInto()
  188.      * @access private
  189.      */
  190.     function fetchInto($result&$arr$fetchmode$rownum=null)
  191.     {
  192.         if ($rownum !== null{
  193.             if (!@mssql_data_seek($result$rownum)) {
  194.                 return null;
  195.             }
  196.         }
  197.         if ($fetchmode DB_FETCHMODE_ASSOC{
  198.             $arr @mssql_fetch_array($resultMSSQL_ASSOC);
  199.             if ($this->options['portability'DB_PORTABILITY_LOWERCASE && $arr{
  200.                 $arr array_change_key_case($arrCASE_LOWER);
  201.             }
  202.         else {
  203.             $arr @mssql_fetch_row($result);
  204.         }
  205.         if (!$arr{
  206.             /* This throws informative error messages,
  207.                don't use it for now
  208.             if ($msg = @mssql_get_last_message()) {
  209.                 return $this->raiseError($msg);
  210.             }
  211.             */
  212.             return null;
  213.         }
  214.         if ($this->options['portability'DB_PORTABILITY_RTRIM{
  215.             $this->_rtrimArrayValues($arr);
  216.         }
  217.         if ($this->options['portability'DB_PORTABILITY_NULL_TO_EMPTY{
  218.             $this->_convertNullArrayValuesToEmpty($arr);
  219.         }
  220.         return DB_OK;
  221.     }
  222.  
  223.     // }}}
  224.     // {{{ freeResult()
  225.  
  226.     function freeResult($result)
  227.     {
  228.         return @mssql_free_result($result);
  229.     }
  230.  
  231.     // }}}
  232.     // {{{ numCols()
  233.  
  234.     function numCols($result)
  235.     {
  236.         $cols @mssql_num_fields($result);
  237.         if (!$cols{
  238.             return $this->mssqlRaiseError();
  239.         }
  240.         return $cols;
  241.     }
  242.  
  243.     // }}}
  244.     // {{{ numRows()
  245.  
  246.     function numRows($result)
  247.     {
  248.         $rows @mssql_num_rows($result);
  249.         if ($rows === false{
  250.             return $this->mssqlRaiseError();
  251.         }
  252.         return $rows;
  253.     }
  254.  
  255.     // }}}
  256.     // {{{ autoCommit()
  257.  
  258.     /**
  259.      * Enable/disable automatic commits
  260.      */
  261.     function autoCommit($onoff = false)
  262.     {
  263.         // XXX if $this->transaction_opcount > 0, we should probably
  264.         // issue a warning here.
  265.         $this->autocommit = $onoff ? true : false;
  266.         return DB_OK;
  267.     }
  268.  
  269.     // }}}
  270.     // {{{ commit()
  271.  
  272.     /**
  273.      * Commit the current transaction.
  274.      */
  275.     function commit()
  276.     {
  277.         if ($this->transaction_opcount > 0{
  278.             if (!@mssql_select_db($this->_db$this->connection)) {
  279.                 return $this->mssqlRaiseError(DB_ERROR_NODBSELECTED);
  280.             }
  281.             $result @mssql_query('COMMIT TRAN'$this->connection);
  282.             $this->transaction_opcount = 0;
  283.             if (!$result{
  284.                 return $this->mssqlRaiseError();
  285.             }
  286.         }
  287.         return DB_OK;
  288.     }
  289.  
  290.     // }}}
  291.     // {{{ rollback()
  292.  
  293.     /**
  294.      * Roll back (undo) the current transaction.
  295.      */
  296.     function rollback()
  297.     {
  298.         if ($this->transaction_opcount > 0{
  299.             if (!@mssql_select_db($this->_db$this->connection)) {
  300.                 return $this->mssqlRaiseError(DB_ERROR_NODBSELECTED);
  301.             }
  302.             $result @mssql_query('ROLLBACK TRAN'$this->connection);
  303.             $this->transaction_opcount = 0;
  304.             if (!$result{
  305.                 return $this->mssqlRaiseError();
  306.             }
  307.         }
  308.         return DB_OK;
  309.     }
  310.  
  311.     // }}}
  312.     // {{{ affectedRows()
  313.  
  314.     /**
  315.      * Gets the number of rows affected by the last query.
  316.      * if the last query was a select, returns 0.
  317.      *
  318.      * @return number of rows affected by the last query or DB_ERROR
  319.      */
  320.     function affectedRows()
  321.     {
  322.         if (DB::isManip($this->last_query)) {
  323.             $res @mssql_query('select @@rowcount'$this->connection);
  324.             if (!$res{
  325.                 return $this->mssqlRaiseError();
  326.             }
  327.             $ar @mssql_fetch_row($res);
  328.             if (!$ar{
  329.                 $result = 0;
  330.             else {
  331.                 @mssql_free_result($res);
  332.                 $result $ar[0];
  333.             }
  334.         else {
  335.             $result = 0;
  336.         }
  337.         return $result;
  338.     }
  339.  
  340.     // }}}
  341.     // {{{ nextId()
  342.  
  343.     /**
  344.      * Returns the next free id in a sequence
  345.      *
  346.      * @param string  $seq_name  name of the sequence
  347.      * @param boolean $ondemand  when true, the seqence is automatically
  348.      *                            created if it does not exist
  349.      *
  350.      * @return int  the next id number in the sequence.  DB_Error if problem.
  351.      *
  352.      * @internal
  353.      * @see DB_common::nextID()
  354.      * @access public
  355.      */
  356.     function nextId($seq_name$ondemand = true)
  357.     {
  358.         $seqname $this->getSequenceName($seq_name);
  359.         if (!@mssql_select_db($this->_db$this->connection)) {
  360.             return $this->mssqlRaiseError(DB_ERROR_NODBSELECTED);
  361.         }
  362.         $repeat = 0;
  363.         do {
  364.             $this->pushErrorHandling(PEAR_ERROR_RETURN);
  365.             $result $this->query("INSERT INTO $seqname (vapor) VALUES (0)");
  366.             $this->popErrorHandling();
  367.             if ($ondemand && DB::isError($result&&
  368.                 ($result->getCode(== DB_ERROR || $result->getCode(== DB_ERROR_NOSUCHTABLE))
  369.             {
  370.                 $repeat = 1;
  371.                 $result $this->createSequence($seq_name);
  372.                 if (DB::isError($result)) {
  373.                     return $this->raiseError($result);
  374.                 }
  375.             elseif (!DB::isError($result)) {
  376.                 $result =$this->query("SELECT @@IDENTITY FROM $seqname");
  377.                 $repeat = 0;
  378.             else {
  379.                 $repeat = false;
  380.             }
  381.         while ($repeat);
  382.         if (DB::isError($result)) {
  383.             return $this->raiseError($result);
  384.         }
  385.         $result $result->fetchRow(DB_FETCHMODE_ORDERED);
  386.         return $result[0];
  387.     }
  388.  
  389.     /**
  390.      * Creates a new sequence
  391.      *
  392.      * @param string $seq_name  name of the new sequence
  393.      *
  394.      * @return int  DB_OK on success.  A DB_Error object is returned if
  395.      *               problems arise.
  396.      *
  397.      * @internal
  398.      * @see DB_common::createSequence()
  399.      * @access public
  400.      */
  401.     function createSequence($seq_name)
  402.     {
  403.         $seqname $this->getSequenceName($seq_name);
  404.         return $this->query("CREATE TABLE $seqname ".
  405.                             '([id] [int] IDENTITY (1, 1) NOT NULL ,' .
  406.                             '[vapor] [int] NULL)');
  407.     }
  408.  
  409.     // }}}
  410.     // {{{ dropSequence()
  411.  
  412.     /**
  413.      * Deletes a sequence
  414.      *
  415.      * @param string $seq_name  name of the sequence to be deleted
  416.      *
  417.      * @return int  DB_OK on success.  DB_Error if problems.
  418.      *
  419.      * @internal
  420.      * @see DB_common::dropSequence()
  421.      * @access public
  422.      */
  423.     function dropSequence($seq_name)
  424.     {
  425.         $seqname $this->getSequenceName($seq_name);
  426.         return $this->query("DROP TABLE $seqname");
  427.     }
  428.  
  429.     // }}}
  430.     // {{{ errorNative()
  431.  
  432.     /**
  433.      * Determine MS SQL Server error code by querying @@ERROR.
  434.      *
  435.      * @return mixed  mssql's native error code or DB_ERROR if unknown.
  436.      */
  437.     function errorNative()
  438.     {
  439.         $res @mssql_query('select @@ERROR as ErrorCode'$this->connection);
  440.         if (!$res{
  441.             return DB_ERROR;
  442.         }
  443.         $row @mssql_fetch_row($res);
  444.         return $row[0];
  445.     }
  446.  
  447.     // }}}
  448.     // {{{ errorCode()
  449.  
  450.     /**
  451.      * Determine PEAR::DB error code from mssql's native codes.
  452.      *
  453.      * If <var>$nativecode</var> isn't known yet, it will be looked up.
  454.      *
  455.      * @param  mixed  $nativecode  mssql error code, if known
  456.      * @return integer  an error number from a DB error constant
  457.      * @see errorNative()
  458.      */
  459.     function errorCode($nativecode = null)
  460.     {
  461.         if (!$nativecode{
  462.             $nativecode $this->errorNative();
  463.         }
  464.         if (isset($this->errorcode_map[$nativecode])) {
  465.             return $this->errorcode_map[$nativecode];
  466.         else {
  467.             return DB_ERROR;
  468.         }
  469.     }
  470.  
  471.     // }}}
  472.     // {{{ mssqlRaiseError()
  473.  
  474.     /**
  475.      * Gather information about an error, then use that info to create a
  476.      * DB error object and finally return that object.
  477.      *
  478.      * @param  integer  $code  PEAR error number (usually a DB constant) if
  479.      *                          manually raising an error
  480.      * @return object  DB error object
  481.      * @see errorCode()
  482.      * @see errorNative()
  483.      * @see DB_common::raiseError()
  484.      */
  485.     function mssqlRaiseError($code = null)
  486.     {
  487.         $message @mssql_get_last_message();
  488.         if (!$code{
  489.             $code $this->errorNative();
  490.         }
  491.         return $this->raiseError($this->errorCode($code)nullnullnull,
  492.                                  "$code - $message");
  493.     }
  494.  
  495.     // }}}
  496.     // {{{ tableInfo()
  497.  
  498.     /**
  499.      * Returns information about a table or a result set.
  500.      *
  501.      * NOTE: only supports 'table' and 'flags' if <var>$result</var>
  502.      * is a table name.
  503.      *
  504.      * @param object|string $result  DB_result object from a query or a
  505.      *                                 string containing the name of a table
  506.      * @param int            $mode    a valid tableInfo mode
  507.      * @return array  an associative array with the information requested
  508.      *                 or an error object if something is wrong
  509.      * @access public
  510.      * @internal
  511.      * @see DB_common::tableInfo()
  512.      */
  513.     function tableInfo($result$mode = null)
  514.     {
  515.         if (isset($result->result)) {
  516.             /*
  517.              * Probably received a result object.
  518.              * Extract the result resource identifier.
  519.              */
  520.             $id $result->result;
  521.             $got_string = false;
  522.         elseif (is_string($result)) {
  523.             /*
  524.              * Probably received a table name.
  525.              * Create a result resource identifier.
  526.              */
  527.             if (!@mssql_select_db($this->_db$this->connection)) {
  528.                 return $this->mssqlRaiseError(DB_ERROR_NODBSELECTED);
  529.             }
  530.             $id @mssql_query("SELECT * FROM $result WHERE 1=0",
  531.                                $this->connection);
  532.             $got_string = true;
  533.         else {
  534.             /*
  535.              * Probably received a result resource identifier.
  536.              * Copy it.
  537.              * Depricated.  Here for compatibility only.
  538.              */
  539.             $id $result;
  540.             $got_string = false;
  541.         }
  542.  
  543.         if (!is_resource($id)) {
  544.             return $this->mssqlRaiseError(DB_ERROR_NEED_MORE_DATA);
  545.         }
  546.  
  547.         if ($this->options['portability'DB_PORTABILITY_LOWERCASE{
  548.             $case_func 'strtolower';
  549.         else {
  550.             $case_func 'strval';
  551.         }
  552.  
  553.         $count @mssql_num_fields($id);
  554.  
  555.         // made this IF due to performance (one if is faster than $count if's)
  556.         if (!$mode{
  557.             for ($i=0; $i<$count$i++{
  558.                 $res[$i]['table'$got_string $case_func($result'';
  559.                 $res[$i]['name']  $case_func(@mssql_field_name($id$i));
  560.                 $res[$i]['type']  @mssql_field_type($id$i);
  561.                 $res[$i]['len']   @mssql_field_length($id$i);
  562.                 // We only support flags for tables
  563.                 $res[$i]['flags'$got_string $this->_mssql_field_flags($result$res[$i]['name']'';
  564.             }
  565.  
  566.         else // full
  567.             $res['num_fields']$count;
  568.  
  569.             for ($i=0; $i<$count$i++{
  570.                 $res[$i]['table'$got_string $case_func($result'';
  571.                 $res[$i]['name']  $case_func(@mssql_field_name($id$i));
  572.                 $res[$i]['type']  @mssql_field_type($id$i);
  573.                 $res[$i]['len']   @mssql_field_length($id$i);
  574.                 // We only support flags for tables
  575.                 $res[$i]['flags'$got_string $this->_mssql_field_flags($result$res[$i]['name']'';
  576.  
  577.                 if ($mode DB_TABLEINFO_ORDER{
  578.                     $res['order'][$res[$i]['name']] $i;
  579.                 }
  580.                 if ($mode DB_TABLEINFO_ORDERTABLE{
  581.                     $res['ordertable'][$res[$i]['table']][$res[$i]['name']] $i;
  582.                 }
  583.             }
  584.         }
  585.  
  586.         // free the result only if we were called on a table
  587.         if ($got_string{
  588.             @mssql_free_result($id);
  589.         }
  590.         return $res;
  591.     }
  592.  
  593.     // }}}
  594.     // {{{ getSpecialQuery()
  595.  
  596.     /**
  597.      * Returns the query needed to get some backend info
  598.      * @param string $type What kind of info you want to retrieve
  599.      * @return string The SQL query string
  600.      */
  601.     function getSpecialQuery($type)
  602.     {
  603.         switch ($type{
  604.             case 'tables':
  605.                 return "select name from sysobjects where type = 'U' order by name";
  606.             case 'views':
  607.                 return "select name from sysobjects where type = 'V'";
  608.             default:
  609.                 return null;
  610.         }
  611.     }
  612.  
  613.     // }}}
  614.     // {{{ _mssql_field_flags()
  615.  
  616.     /**
  617.      * Get the flags for a field, currently supports "not_null", "primary_key",
  618.      * "auto_increment" (mssql identity), "timestamp" (mssql timestamp),
  619.      * "unique_key" (mssql unique index, unique check or primary_key) and
  620.      * "multiple_key" (multikey index)
  621.      *
  622.      * mssql timestamp is NOT similar to the mysql timestamp so this is maybe
  623.      * not useful at all - is the behaviour of mysql_field_flags that primary
  624.      * keys are alway unique? is the interpretation of multiple_key correct?
  625.      *
  626.      * @param string The table name
  627.      * @param string The field
  628.      * @author Joern Barthel <j_barthel@web.de>
  629.      * @access private
  630.      */
  631.     function _mssql_field_flags($table$column)
  632.     {
  633.         static $tableName = null;
  634.         static $flags = array();
  635.  
  636.         if ($table != $tableName{
  637.  
  638.             $flags = array();
  639.             $tableName $table;
  640.  
  641.             // get unique and primary keys
  642.             $res $this->getAll("EXEC SP_HELPINDEX[$table]"DB_FETCHMODE_ASSOC);
  643.  
  644.             foreach ($res as $val{
  645.                 $keys explode(', '$val['index_keys']);
  646.  
  647.                 if (sizeof($keys> 1{
  648.                     foreach ($keys as $key{
  649.                         $this->_add_flag($flags[$key]'multiple_key');
  650.                     }
  651.                 }
  652.  
  653.                 if (strpos($val['index_description']'primary key')) {
  654.                     foreach ($keys as $key{
  655.                         $this->_add_flag($flags[$key]'primary_key');
  656.                     }
  657.                 elseif (strpos($val['index_description']'unique')) {
  658.                     foreach ($keys as $key{
  659.                         $this->_add_flag($flags[$key]'unique_key');
  660.                     }
  661.                 }
  662.             }
  663.  
  664.             // get auto_increment, not_null and timestamp
  665.             $res $this->getAll("EXEC SP_COLUMNS[$table]"DB_FETCHMODE_ASSOC);
  666.  
  667.             foreach ($res as $val{
  668.                 $val array_change_key_case($valCASE_LOWER);
  669.                 if ($val['nullable'== '0'{
  670.                     $this->_add_flag($flags[$val['column_name']]'not_null');
  671.                 }
  672.                 if (strpos($val['type_name']'identity')) {
  673.                     $this->_add_flag($flags[$val['column_name']]'auto_increment');
  674.                 }
  675.                 if (strpos($val['type_name']'timestamp')) {
  676.                     $this->_add_flag($flags[$val['column_name']]'timestamp');
  677.                 }
  678.             }
  679.         }
  680.  
  681.         if (array_key_exists($column$flags)) {
  682.             return(implode(' '$flags[$column]));
  683.         }
  684.         return '';
  685.     }
  686.  
  687.     // }}}
  688.     // {{{ _add_flag()
  689.  
  690.     /**
  691.      * Adds a string to the flags array if the flag is not yet in there
  692.      * - if there is no flag present the array is created.
  693.      *
  694.      * @param reference  Reference to the flag-array
  695.      * @param value      The flag value
  696.      * @access private
  697.      * @author Joern Barthel <j_barthel@web.de>
  698.      */
  699.     function _add_flag(&$array$value)
  700.     {
  701.         if (!is_array($array)) {
  702.             $array = array($value);
  703.         elseif (!in_array($value$array)) {
  704.             array_push($array$value);
  705.         }
  706.     }
  707.  
  708.     // }}}
  709.     // {{{ quoteIdentifier()
  710.  
  711.     /**
  712.      * Quote a string so it can be safely used as a table / column name
  713.      *
  714.      * Quoting style depends on which database driver is being used.
  715.      *
  716.      * @param string $str  identifier name to be quoted
  717.      *
  718.      * @return string  quoted identifier string
  719.      *
  720.      * @since 1.6.0
  721.      * @access public
  722.      */
  723.     function quoteIdentifier($str)
  724.     {
  725.         return '[' str_replace(']'']]'$str']';
  726.     }
  727.  
  728.     // }}}
  729. }
  730.  
  731. /*
  732.  * Local variables:
  733.  * tab-width: 4
  734.  * c-basic-offset: 4
  735.  * End:
  736.  */
  737.  
  738. ?>

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