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

Source for file sybase.php

Documentation is available at sybase.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. // | Authors: Sterling Hughes <sterling@php.net>                          |
  17. // | Maintainer: Daniel Convissor <danielc@php.net>                       |
  18. // +----------------------------------------------------------------------+
  19. //
  20. // $Id: sybase.php,v 1.52 2004/07/12 19:07:34 danielc Exp $
  21.  
  22.  
  23. // TODO
  24. //    - This driver may fail with multiple connections under the same
  25. //      user/pass/host and different databases
  26.  
  27.  
  28. require_once 'DB/common.php';
  29.  
  30. /**
  31.  * Database independent query interface definition for PHP's Sybase
  32.  * extension.
  33.  *
  34.  * @package  DB
  35.  * @version  $Id: sybase.php,v 1.52 2004/07/12 19:07:34 danielc Exp $
  36.  * @category Database
  37.  * @author   Sterling Hughes <sterling@php.net>
  38.  * @author
  39.  */
  40. class DB_sybase extends DB_common
  41. {
  42.     // {{{ properties
  43.  
  44.     var $connection;
  45.     var $phptype$dbsyntax;
  46.     var $prepare_tokens = array();
  47.     var $prepare_types = array();
  48.     var $transaction_opcount = 0;
  49.     var $autocommit = true;
  50.  
  51.     // }}}
  52.     // {{{ constructor
  53.  
  54.     /**
  55.      * DB_sybase constructor.
  56.      *
  57.      * @access public
  58.      */
  59.     function DB_sybase()
  60.     {
  61.         $this->DB_common();
  62.         $this->phptype = 'sybase';
  63.         $this->dbsyntax = 'sybase';
  64.         $this->features = array(
  65.             'prepare' => false,
  66.             'pconnect' => true,
  67.             'transactions' => false,
  68.             'limit' => 'emulate'
  69.         );
  70.         $this->errorcode_map = array(
  71.         );
  72.     }
  73.  
  74.     // }}}
  75.     // {{{ connect()
  76.  
  77.     /**
  78.      * Connect to a database and log in as the specified user.
  79.      *
  80.      * @param $dsn the data source name (see DB::parseDSN for syntax)
  81.      * @param $persistent (optional) whether the connection should
  82.      *         be persistent
  83.      * @access public
  84.      * @return int DB_OK on success, a DB error on failure
  85.      */
  86.     function connect($dsninfo$persistent = false)
  87.     {
  88.         if (!DB::assertExtension('sybase'&&
  89.             !DB::assertExtension('sybase_ct'))
  90.         {
  91.             return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
  92.         }
  93.  
  94.         $this->dsn $dsninfo;
  95.  
  96.         $interface $dsninfo['hostspec'$dsninfo['hostspec''localhost';
  97.         $connect_function $persistent 'sybase_pconnect' 'sybase_connect';
  98.         $dsninfo['password'!empty($dsninfo['password']$dsninfo['password': false;
  99.         $dsninfo['charset'= isset($dsninfo['charset']$dsninfo['charset': false;
  100.         $dsninfo['appname'= isset($dsninfo['appname']$dsninfo['appname': false;
  101.  
  102.         if ($interface && $dsninfo['username']{
  103.             $conn @$connect_function($interface$dsninfo['username'],
  104.                                        $dsninfo['password'],
  105.                                        $dsninfo['charset'],
  106.                                        $dsninfo['appname']);
  107.         else {
  108.             $conn = false;
  109.         }
  110.  
  111.         if (!$conn{
  112.             return $this->raiseError(DB_ERROR_CONNECT_FAILED);
  113.         }
  114.  
  115.         if ($dsninfo['database']{
  116.             if (!@sybase_select_db($dsninfo['database']$conn)) {
  117.                 return $this->raiseError(DB_ERROR_NODBSELECTEDnull,
  118.                                          nullnull@sybase_get_last_message());
  119.             }
  120.             $this->_db $dsninfo['database'];
  121.         }
  122.  
  123.         $this->connection = $conn;
  124.         return DB_OK;
  125.     }
  126.  
  127.     // }}}
  128.     // {{{ disconnect()
  129.  
  130.     /**
  131.      * Log out and disconnect from the database.
  132.      *
  133.      * @access public
  134.      *
  135.      * @return bool true on success, false if not connected.
  136.      */
  137.     function disconnect()
  138.     {
  139.         $ret @sybase_close($this->connection);
  140.         $this->connection = null;
  141.         return $ret;
  142.     }
  143.  
  144.     // }}}
  145.     // {{{ errorNative()
  146.  
  147.     /**
  148.      * Get the last server error messge (if any)
  149.      *
  150.      * @return string sybase last error message
  151.      */
  152.     function errorNative()
  153.     {
  154.         return @sybase_get_last_message();
  155.     }
  156.  
  157.     // }}}
  158.     // {{{ errorCode()
  159.  
  160.     /**
  161.      * Determine PEAR::DB error code from the database's text error message.
  162.      *
  163.      * @param  string  $errormsg  error message returned from the database
  164.      * @return integer  an error number from a DB error constant
  165.      */
  166.     function errorCode($errormsg)
  167.     {
  168.         static $error_regexps;
  169.         if (!isset($error_regexps)) {
  170.             $error_regexps = array(
  171.                 '/Incorrect syntax near/'
  172.                     => DB_ERROR_SYNTAX,
  173.                 '/^Unclosed quote before the character string [\"\'].*[\"\']\./'
  174.                     => DB_ERROR_SYNTAX,
  175.                 '/Implicit conversion from datatype [\"\'].+[\"\'] to [\"\'].+[\"\'] is not allowed\./'
  176.                     => DB_ERROR_INVALID_NUMBER,
  177.                 '/Cannot drop the table [\"\'].+[\"\'], because it doesn\'t exist in the system catalogs\./'
  178.                     => DB_ERROR_NOSUCHTABLE,
  179.                 '/Only the owner of object [\"\'].+[\"\'] or a user with System Administrator \(SA\) role can run this command\./'
  180.                     => DB_ERROR_ACCESS_VIOLATION,
  181.                 '/^.+ permission denied on object .+, database .+, owner .+/'
  182.                     => DB_ERROR_ACCESS_VIOLATION,
  183.                 '/^.* permission denied, database .+, owner .+/'
  184.                     => DB_ERROR_ACCESS_VIOLATION,
  185.                 '/[^.*] not found\./'
  186.                     => DB_ERROR_NOSUCHTABLE,
  187.                 '/There is already an object named/'
  188.                     => DB_ERROR_ALREADY_EXISTS,
  189.                 '/Invalid column name/'
  190.                     => DB_ERROR_NOSUCHFIELD,
  191.                 '/does not allow null values/'
  192.                     => DB_ERROR_CONSTRAINT_NOT_NULL,
  193.                 '/Command has been aborted/'
  194.                     => DB_ERROR_CONSTRAINT,
  195.             );
  196.         }
  197.  
  198.         foreach ($error_regexps as $regexp => $code{
  199.             if (preg_match($regexp$errormsg)) {
  200.                 return $code;
  201.             }
  202.         }
  203.         return DB_ERROR;
  204.     }
  205.  
  206.     // }}}
  207.     // {{{ sybaseRaiseError()
  208.  
  209.     /**
  210.      * Gather information about an error, then use that info to create a
  211.      * DB error object and finally return that object.
  212.      *
  213.      * @param  integer  $errno  PEAR error number (usually a DB constant) if
  214.      *                           manually raising an error
  215.      * @return object  DB error object
  216.      * @see errorNative()
  217.      * @see errorCode()
  218.      * @see DB_common::raiseError()
  219.      */
  220.     function sybaseRaiseError($errno = null)
  221.     {
  222.         $native $this->errorNative();
  223.         if ($errno === null{
  224.             $errno $this->errorCode($native);
  225.         }
  226.         return $this->raiseError($errnonullnullnull$native);
  227.     }
  228.  
  229.     // }}}
  230.     // {{{ simpleQuery()
  231.  
  232.     /**
  233.      * Send a query to Sybase and return the results as a Sybase resource
  234.      * identifier.
  235.      *
  236.      * @param the SQL query
  237.      *
  238.      * @access public
  239.      *
  240.      * @return mixed returns a valid Sybase result for successful SELECT
  241.      *  queries, DB_OK for other successful queries.  A DB error is
  242.      *  returned on failure.
  243.      */
  244.     function simpleQuery($query)
  245.     {
  246.         $ismanip DB::isManip($query);
  247.         $this->last_query = $query;
  248.         if (!@sybase_select_db($this->_db$this->connection)) {
  249.             return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED);
  250.         }
  251.         $query $this->modifyQuery($query);
  252.         if (!$this->autocommit && $ismanip{
  253.             if ($this->transaction_opcount == 0{
  254.                 $result @sybase_query('BEGIN TRANSACTION'$this->connection);
  255.                 if (!$result{
  256.                     return $this->sybaseRaiseError();
  257.                 }
  258.             }
  259.             $this->transaction_opcount++;
  260.         }
  261.         $result @sybase_query($query$this->connection);
  262.         if (!$result{
  263.             return $this->sybaseRaiseError();
  264.         }
  265.         if (is_resource($result)) {
  266.             $numrows $this->numRows($result);
  267.             if (is_object($numrows)) {
  268.                 return $numrows;
  269.             }
  270.             $this->num_rows[(int)$result$numrows;
  271.             return $result;
  272.         }
  273.         // Determine which queries that should return data, and which
  274.         // should return an error code only.
  275.         return $ismanip DB_OK : $result;
  276.     }
  277.  
  278.     // }}}
  279.     // {{{ nextResult()
  280.  
  281.     /**
  282.      * Move the internal sybase result pointer to the next available result
  283.      *
  284.      * @param valid sybase result resource
  285.      *
  286.      * @access public
  287.      *
  288.      * @return true if a result is available otherwise return false
  289.      */
  290.     function nextResult($result)
  291.     {
  292.         return false;
  293.     }
  294.  
  295.     // }}}
  296.     // {{{ fetchInto()
  297.  
  298.     /**
  299.      * Fetch a row and insert the data into an existing array.
  300.      *
  301.      * Formating of the array and the data therein are configurable.
  302.      * See DB_result::fetchInto() for more information.
  303.      *
  304.      * @param resource $result    query result identifier
  305.      * @param array    $arr       (reference) array where data from the row
  306.      *                             should be placed
  307.      * @param int      $fetchmode how the resulting array should be indexed
  308.      * @param int      $rownum    the row number to fetch
  309.      *
  310.      * @return mixed DB_OK on success, null when end of result set is
  311.      *                reached or on failure
  312.      *
  313.      * @see DB_result::fetchInto()
  314.      * @access private
  315.      */
  316.     function fetchInto($result&$arr$fetchmode$rownum=null)
  317.     {
  318.         if ($rownum !== null{
  319.             if (!@sybase_data_seek($result$rownum)) {
  320.                 return null;
  321.             }
  322.         }
  323.         if ($fetchmode DB_FETCHMODE_ASSOC{
  324.             if (function_exists('sybase_fetch_assoc')) {
  325.                 $arr @sybase_fetch_assoc($result);
  326.             else {
  327.                 if ($arr @sybase_fetch_array($result)) {
  328.                     foreach ($arr as $key => $value{
  329.                         if (is_int($key)) {
  330.                             unset($arr[$key]);
  331.                         }
  332.                     }
  333.                 }
  334.             }
  335.             if ($this->options['portability'DB_PORTABILITY_LOWERCASE && $arr{
  336.                 $arr array_change_key_case($arrCASE_LOWER);
  337.             }
  338.         else {
  339.             $arr @sybase_fetch_row($result);
  340.         }
  341.         if (!$arr{
  342.             // reported not work as seems that sybase_get_last_message()
  343.             // always return a message here
  344.             //if ($errmsg = @sybase_get_last_message()) {
  345.             //    return $this->sybaseRaiseError($errmsg);
  346.             //} else {
  347.                 return null;
  348.             //}
  349.         }
  350.         if ($this->options['portability'DB_PORTABILITY_RTRIM{
  351.             $this->_rtrimArrayValues($arr);
  352.         }
  353.         if ($this->options['portability'DB_PORTABILITY_NULL_TO_EMPTY{
  354.             $this->_convertNullArrayValuesToEmpty($arr);
  355.         }
  356.         return DB_OK;
  357.     }
  358.  
  359.     // }}}
  360.     // {{{ freeResult()
  361.  
  362.     /**
  363.      * Free the internal resources associated with $result.
  364.      *
  365.      * @param $result Sybase result identifier
  366.      *
  367.      * @access public
  368.      *
  369.      * @return bool true on success, false if $result is invalid
  370.      */
  371.     function freeResult($result)
  372.     {
  373.         unset($this->num_rows[(int)$result]);
  374.         return @sybase_free_result($result);
  375.     }
  376.  
  377.     // }}}
  378.     // {{{ numCols()
  379.  
  380.     /**
  381.      * Get the number of columns in a result set.
  382.      *
  383.      * @param $result Sybase result identifier
  384.      *
  385.      * @access public
  386.      *
  387.      * @return int the number of columns per row in $result
  388.      */
  389.     function numCols($result)
  390.     {
  391.         $cols @sybase_num_fields($result);
  392.         if (!$cols{
  393.             return $this->sybaseRaiseError();
  394.         }
  395.         return $cols;
  396.     }
  397.  
  398.     // }}}
  399.     // {{{ numRows()
  400.  
  401.     /**
  402.      * Get the number of rows in a result set.
  403.      *
  404.      * @param $result Sybase result identifier
  405.      *
  406.      * @access public
  407.      *
  408.      * @return int the number of rows in $result
  409.      */
  410.     function numRows($result)
  411.     {
  412.         $rows @sybase_num_rows($result);
  413.         if ($rows === false{
  414.             return $this->sybaseRaiseError();
  415.         }
  416.         return $rows;
  417.     }
  418.  
  419.     // }}}
  420.     // {{{ affectedRows()
  421.  
  422.     /**
  423.      * Gets the number of rows affected by the data manipulation
  424.      * query.  For other queries, this function returns 0.
  425.      *
  426.      * @return number of rows affected by the last query
  427.      */
  428.     function affectedRows()
  429.     {
  430.         if (DB::isManip($this->last_query)) {
  431.             $result @sybase_affected_rows($this->connection);
  432.         else {
  433.             $result = 0;
  434.         }
  435.         return $result;
  436.      }
  437.  
  438.     // }}}
  439.     // {{{ nextId()
  440.  
  441.     /**
  442.      * Returns the next free id in a sequence
  443.      *
  444.      * @param string  $seq_name  name of the sequence
  445.      * @param boolean $ondemand  when true, the seqence is automatically
  446.      *                            created if it does not exist
  447.      *
  448.      * @return int  the next id number in the sequence.  DB_Error if problem.
  449.      *
  450.      * @internal
  451.      * @see DB_common::nextID()
  452.      * @access public
  453.      */
  454.     function nextId($seq_name$ondemand = true)
  455.     {
  456.         $seqname $this->getSequenceName($seq_name);
  457.         if (!@sybase_select_db($this->_db$this->connection)) {
  458.             return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED);
  459.         }
  460.         $repeat = 0;
  461.         do {
  462.             $this->pushErrorHandling(PEAR_ERROR_RETURN);
  463.             $result $this->query("INSERT INTO $seqname (vapor) VALUES (0)");
  464.             $this->popErrorHandling();
  465.             if ($ondemand && DB::isError($result&&
  466.                 ($result->getCode(== DB_ERROR || $result->getCode(== DB_ERROR_NOSUCHTABLE))
  467.             {
  468.                 $repeat = 1;
  469.                 $result $this->createSequence($seq_name);
  470.                 if (DB::isError($result)) {
  471.                     return $this->raiseError($result);
  472.                 }
  473.             elseif (!DB::isError($result)) {
  474.                 $result =$this->query("SELECT @@IDENTITY FROM $seqname");
  475.                 $repeat = 0;
  476.             else {
  477.                 $repeat = false;
  478.             }
  479.         while ($repeat);
  480.         if (DB::isError($result)) {
  481.             return $this->raiseError($result);
  482.         }
  483.         $result $result->fetchRow(DB_FETCHMODE_ORDERED);
  484.         return $result[0];
  485.     }
  486.  
  487.     /**
  488.      * Creates a new sequence
  489.      *
  490.      * @param string $seq_name  name of the new sequence
  491.      *
  492.      * @return int  DB_OK on success.  A DB_Error object is returned if
  493.      *               problems arise.
  494.      *
  495.      * @internal
  496.      * @see DB_common::createSequence()
  497.      * @access public
  498.      */
  499.     function createSequence($seq_name)
  500.     {
  501.         $seqname $this->getSequenceName($seq_name);
  502.         return $this->query("CREATE TABLE $seqname ".
  503.                             '(id numeric(10,0) IDENTITY NOT NULL ,' .
  504.                             'vapor int NULL)');
  505.     }
  506.  
  507.     // }}}
  508.     // {{{ dropSequence()
  509.  
  510.     /**
  511.      * Deletes a sequence
  512.      *
  513.      * @param string $seq_name  name of the sequence to be deleted
  514.      *
  515.      * @return int  DB_OK on success.  DB_Error if problems.
  516.      *
  517.      * @internal
  518.      * @see DB_common::dropSequence()
  519.      * @access public
  520.      */
  521.     function dropSequence($seq_name)
  522.     {
  523.         $seqname $this->getSequenceName($seq_name);
  524.         return $this->query("DROP TABLE $seqname");
  525.     }
  526.  
  527.     // }}}
  528.     // {{{ getSpecialQuery()
  529.  
  530.     /**
  531.      * Returns the query needed to get some backend info
  532.      * @param string $type What kind of info you want to retrieve
  533.      * @return string The SQL query string
  534.      */
  535.     function getSpecialQuery($type)
  536.     {
  537.         switch ($type{
  538.             case 'tables':
  539.                 return "select name from sysobjects where type = 'U' order by name";
  540.             case 'views':
  541.                 return "select name from sysobjects where type = 'V'";
  542.             default:
  543.                 return null;
  544.         }
  545.     }
  546.  
  547.     // }}}
  548.     // {{{ autoCommit()
  549.  
  550.     /**
  551.      * Enable/disable automatic commits
  552.      */
  553.     function autoCommit($onoff = false)
  554.     {
  555.         // XXX if $this->transaction_opcount > 0, we should probably
  556.         // issue a warning here.
  557.         $this->autocommit = $onoff ? true : false;
  558.         return DB_OK;
  559.     }
  560.  
  561.     // }}}
  562.     // {{{ commit()
  563.  
  564.     /**
  565.      * Commit the current transaction.
  566.      */
  567.     function commit()
  568.     {
  569.         if ($this->transaction_opcount > 0{
  570.             if (!@sybase_select_db($this->_db$this->connection)) {
  571.                 return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED);
  572.             }
  573.             $result @sybase_query('COMMIT'$this->connection);
  574.             $this->transaction_opcount = 0;
  575.             if (!$result{
  576.                 return $this->sybaseRaiseError();
  577.             }
  578.         }
  579.         return DB_OK;
  580.     }
  581.  
  582.     // }}}
  583.     // {{{ rollback()
  584.  
  585.     /**
  586.      * Roll back (undo) the current transaction.
  587.      */
  588.     function rollback()
  589.     {
  590.         if ($this->transaction_opcount > 0{
  591.             if (!@sybase_select_db($this->_db$this->connection)) {
  592.                 return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED);
  593.             }
  594.             $result @sybase_query('ROLLBACK'$this->connection);
  595.             $this->transaction_opcount = 0;
  596.             if (!$result{
  597.                 return $this->sybaseRaiseError();
  598.             }
  599.         }
  600.         return DB_OK;
  601.     }
  602.  
  603.     // }}}
  604.     // {{{ tableInfo()
  605.  
  606.     /**
  607.      * Returns information about a table or a result set.
  608.      *
  609.      * NOTE: only supports 'table' and 'flags' if <var>$result</var>
  610.      * is a table name.
  611.      *
  612.      * @param object|string $result  DB_result object from a query or a
  613.      *                                 string containing the name of a table
  614.      * @param int            $mode    a valid tableInfo mode
  615.      * @return array  an associative array with the information requested
  616.      *                 or an error object if something is wrong
  617.      * @access public
  618.      * @internal
  619.      * @since 1.6.0
  620.      * @see DB_common::tableInfo()
  621.      */
  622.     function tableInfo($result$mode = null)
  623.     {
  624.         if (isset($result->result)) {
  625.             /*
  626.              * Probably received a result object.
  627.              * Extract the result resource identifier.
  628.              */
  629.             $id $result->result;
  630.             $got_string = false;
  631.         elseif (is_string($result)) {
  632.             /*
  633.              * Probably received a table name.
  634.              * Create a result resource identifier.
  635.              */
  636.             if (!@sybase_select_db($this->_db$this->connection)) {
  637.                 return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED);
  638.             }
  639.             $id @sybase_query("SELECT * FROM $result WHERE 1=0",
  640.                                 $this->connection);
  641.             $got_string = true;
  642.         else {
  643.             /*
  644.              * Probably received a result resource identifier.
  645.              * Copy it.
  646.              * Deprecated.  Here for compatibility only.
  647.              */
  648.             $id $result;
  649.             $got_string = false;
  650.         }
  651.  
  652.         if (!is_resource($id)) {
  653.             return $this->sybaseRaiseError(DB_ERROR_NEED_MORE_DATA);
  654.         }
  655.  
  656.         if ($this->options['portability'DB_PORTABILITY_LOWERCASE{
  657.             $case_func 'strtolower';
  658.         else {
  659.             $case_func 'strval';
  660.         }
  661.  
  662.         $count @sybase_num_fields($id);
  663.  
  664.         // made this IF due to performance (one if is faster than $count if's)
  665.         if (!$mode{
  666.  
  667.             for ($i=0; $i<$count$i++{
  668.                 $f @sybase_fetch_field($id$i);
  669.  
  670.                 // column_source is often blank
  671.                 if ($got_string{
  672.                     $res[$i]['table'$case_func($result);
  673.                 else {
  674.                     $res[$i]['table'$case_func($f->column_source);
  675.                 }
  676.                 $res[$i]['name']  $case_func($f->name);
  677.                 $res[$i]['type']  $f->type;
  678.                 $res[$i]['len']   $f->max_length;
  679.                 if ($res[$i]['table']{
  680.                     $res[$i]['flags'$this->_sybase_field_flags(
  681.                             $res[$i]['table']$res[$i]['name']);
  682.                 else {
  683.                     $res[$i]['flags''';
  684.                 }
  685.             }
  686.  
  687.         else {
  688.             // get full info
  689.  
  690.             $res['num_fields'$count;
  691.  
  692.             for ($i=0; $i<$count$i++{
  693.                 $f @sybase_fetch_field($id$i);
  694.  
  695.                 // column_source is often blank
  696.                 if ($got_string{
  697.                     $res[$i]['table'$case_func($result);
  698.                 else {
  699.                     $res[$i]['table'$case_func($f->column_source);
  700.                 }
  701.                 $res[$i]['name']  $case_func($f->name);
  702.                 $res[$i]['type']  $f->type;
  703.                 $res[$i]['len']   $f->max_length;
  704.                 if ($res[$i]['table']{
  705.                     $res[$i]['flags'$this->_sybase_field_flags(
  706.                             $res[$i]['table']$res[$i]['name']);
  707.                 else {
  708.                     $res[$i]['flags''';
  709.                 }
  710.  
  711.                 if ($mode DB_TABLEINFO_ORDER{
  712.                     $res['order'][$res[$i]['name']] $i;
  713.                 }
  714.                 if ($mode DB_TABLEINFO_ORDERTABLE{
  715.                     $res['ordertable'][$res[$i]['table']][$res[$i]['name']] $i;
  716.                 }
  717.             }
  718.         }
  719.  
  720.         // free the result only if we were called on a table
  721.         if ($got_string{
  722.             @sybase_free_result($id);
  723.         }
  724.         return $res;
  725.     }
  726.  
  727.     // }}}
  728.     // {{{ _sybase_field_flags()
  729.  
  730.     /**
  731.      * Get the flags for a field.
  732.      *
  733.      * Currently supports:
  734.      *  + <samp>unique_key</samp>    (unique index, unique check or primary_key)
  735.      *  + <samp>multiple_key</samp>  (multi-key index)
  736.      *
  737.      * @param string  $table   table name
  738.      * @param string  $column  field name
  739.      * @return string  space delimited string of flags.  Empty string if none.
  740.      * @access private
  741.      */
  742.     function _sybase_field_flags($table$column)
  743.     {
  744.         static $tableName = null;
  745.         static $flags = array();
  746.  
  747.         if ($table != $tableName{
  748.             $flags = array();
  749.             $tableName $table;
  750.  
  751.             // get unique/primary keys
  752.             $res $this->getAll("sp_helpindex $table"DB_FETCHMODE_ASSOC);
  753.  
  754.             if (!isset($res[0]['index_description'])) {
  755.                 return '';
  756.             }
  757.  
  758.             foreach ($res as $val{
  759.                 $keys explode(', 'trim($val['index_keys']));
  760.  
  761.                 if (sizeof($keys> 1{
  762.                     foreach ($keys as $key{
  763.                         $this->_add_flag($flags[$key]'multiple_key');
  764.                     }
  765.                 }
  766.  
  767.                 if (strpos($val['index_description']'unique')) {
  768.                     foreach ($keys as $key{
  769.                         $this->_add_flag($flags[$key]'unique_key');
  770.                     }
  771.                 }
  772.             }
  773.  
  774.         }
  775.  
  776.         if (array_key_exists($column$flags)) {
  777.             return(implode(' '$flags[$column]));
  778.         }
  779.  
  780.         return '';
  781.     }
  782.  
  783.     // }}}
  784.     // {{{ _add_flag()
  785.  
  786.     /**
  787.      * Adds a string to the flags array if the flag is not yet in there
  788.      * - if there is no flag present the array is created.
  789.      *
  790.      * @param array  $array  reference of flags array to add a value to
  791.      * @param mixed  $value  value to add to the flag array
  792.      * @access private
  793.      */
  794.     function _add_flag(&$array$value)
  795.     {
  796.         if (!is_array($array)) {
  797.             $array = array($value);
  798.         elseif (!in_array($value$array)) {
  799.             array_push($array$value);
  800.         }
  801.     }
  802.  
  803.     // }}}
  804.     // {{{ quoteIdentifier()
  805.  
  806.     /**
  807.      * Quote a string so it can be safely used as a table / column name
  808.      *
  809.      * Quoting style depends on which database driver is being used.
  810.      *
  811.      * @param string $str  identifier name to be quoted
  812.      *
  813.      * @return string  quoted identifier string
  814.      *
  815.      * @since 1.6.0
  816.      * @access public
  817.      */
  818.     function quoteIdentifier($str)
  819.     {
  820.         return '[' str_replace(']'']]'$str']';
  821.     }
  822.  
  823.     // }}}
  824.  
  825. }
  826.  
  827. /*
  828.  * Local variables:
  829.  * tab-width: 4
  830.  * c-basic-offset: 4
  831.  * End:
  832.  */
  833.  
  834. ?>

Documentation generated on Mon, 11 Mar 2019 13:55:57 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.