Source for file dbapi.abstract.class.inc.php

Documentation is available at dbapi.abstract.class.inc.php

  1. <?php
  2. abstract class DBAPI_abstract {
  3.  
  4.     // -----
  5.     // SETUP 
  6.     // -----
  7.  
  8.      /**
  9.       * The constructor. Can optionally have the database details passed to it, or alternatively it can use the globals (using the globals is deprecated functionality).
  10.       *
  11.       * <<<< TODO throw E_USER_DEPRECATED after ensuring that Install and DocumentParser do not use the globals.
  12.       *
  13.       * @param $parent Parent object e.g. $modx or $install
  14.       * @param $host db hostname
  15.       * @param $dbase db schema name
  16.       * @param $uid db username
  17.       * @param $pwd db password
  18.       * @param $pre table prefix
  19.       * @param $charset client character set
  20.       * @param $connection SQL to set connection character set
  21.       */
  22.      final public function __construct($parent$host ''$dbase ''$uid '',$pwd ''$pre null$charset ''$connection_method 'SET CHARACTER SET'{
  23.           $this->parent $parent;
  24.           $this->config['host'$host $host $GLOBALS['database_server'];
  25.           $this->config['dbase'$dbase $dbase $GLOBALS['dbase'];
  26.           $this->config['user'$uid $uid $GLOBALS['database_user'];
  27.           $this->config['pass'$pwd $pwd $GLOBALS['database_password'];
  28.           $this->config['charset'$charset $charset $GLOBALS['database_connection_charset'];
  29.           $this->config['connection_method'=  $this->_dbconnectionmethod (isset($GLOBALS['database_connection_method']$GLOBALS['database_connection_method'$connection_method);
  30.           $this->config['table_prefix'($pre !== NULL$pre $GLOBALS['table_prefix']// Not currently used by the DBAPI. Used just to store the value.
  31.           $this->initDataTypes();
  32.      }
  33.  
  34.      /**
  35.       * Called in the constructor to set up arrays containing the types
  36.       * of database fields that can be used with specific PHP types.
  37.       * 
  38.       * RDBMS specific.
  39.       */
  40.      abstract protected function initDataTypes();
  41.  
  42.     // -------
  43.     // CONNECT
  44.     // -------
  45.  
  46.      /**
  47.       * Connect to the database.
  48.       *
  49.       * Can optionally have the database details passed to it but this is deprecated functionality. Pass the details in the constructor instead.
  50.       *
  51.       * @param $host db hostname
  52.       * @param $dbase db schema name
  53.       * @param $uid db username
  54.       * @param $pwd db password
  55.       * @param $persist If true, make a persistent connection.
  56.       * @return void 
  57.       */
  58.      final public function connect($host ''$dbase ''$uid ''$pwd ''$persist false{
  59.           
  60.         $uid $uid $uid $this->config['user'];
  61.         $pwd $pwd $pwd $this->config['pass'];
  62.         $host $host $host $this->config['host'];
  63.         $dbase str_replace('`'''$dbase $dbase $this->config['dbase']);
  64.         $charset $this->config['charset'];
  65.         $connection_method $this->config['connection_method'];
  66.  
  67.         $tstart $this->parent->getMicroTime();
  68.         if (!($persist $this->make_persistent_connection($host$uid$pwd$this->make_connection($host$uid$pwd))) {
  69.             $this->parent->messageQuit('Failed to create the database connection!');
  70.             exit;
  71.         else {
  72.             if (!@$this->select_db($dbase)) {
  73.                 $this->parent->messageQuit("Failed to select the database '$dbase'!");
  74.                 exit;
  75.             }
  76.             $this->host $host;
  77.             $this->dbase $dbase;
  78.             @$this->query("{$connection_method} {$charset}")// We should be able to remove this and it's associated functionality
  79.             $this->set_charset($charset);
  80.             
  81.             $tend $this->parent->getMicroTime();
  82.             $totaltime $tend $tstart;
  83.             if ($this->parent->dumpSQL{
  84.                 $this->parent->queryCode .= "<fieldset style='text-align:left'><legend>Database connection</legend>" sprintf("Database connection was created in %2.4f s"$totaltime"</fieldset><br />";
  85.             }
  86.             $this->isConnected true;
  87.             $this->parent->queryTime += $totaltime;
  88.         }
  89.     }
  90.  
  91.     /**
  92.       * Test database connection or selection
  93.       *
  94.       * Intended for installer use only.
  95.       * Does not set character set of connection.
  96.       *
  97.       * Will return false on failure and will not log errors or display any errors via DocumentParser::MessageQuit().
  98.       *
  99.       * @param $host db hostname
  100.       * @param $dbase Optional db schema name
  101.       * @param $uid db username
  102.       * @param $pwd db password
  103.       * @param $query Optional query to run
  104.       */
  105.     function test_connect($host ''$dbase ''$uid ''$pwd ''$query ''{
  106.  
  107.         $uid $uid $uid $this->config['user'];
  108.         $pwd $pwd $pwd $this->config['pass'];
  109.         $host $host $host $this->config['host'];
  110.  
  111.         $output @$this->make_connection($host$uid$pwd)
  112.         
  113.         if ($this->conn && !empty($dbase)) {
  114.             $dbase str_replace('`'''$dbase $dbase $this->config['dbase']);
  115.             if ($output @$this->select_db($dbase)) {
  116.                 $this->dbase $dbase;
  117.             }
  118.         }
  119.         
  120.         if ($this->conn && !empty($query)) {
  121.             $output $this->query($querytrue);
  122.         }
  123.         
  124.         return $output;
  125.     }
  126.     
  127.     /**
  128.      * Make a persistent connection to the database.
  129.      *
  130.      * @return void 
  131.      */
  132.     final public function p_connect({
  133.         $this->connect(''''''''true);
  134.        }
  135.     
  136.     /**
  137.      * Check for connection
  138.      */
  139.     final protected function connection_check({
  140.           if (empty ($this->conn)) 
  141.             $this->connect();
  142.         }
  143.     }
  144.     
  145.     /**
  146.      * Connect to the RDBMS.
  147.      * 
  148.      * RDBMS specific.
  149.      */
  150.     abstract protected function make_connection($host$uid$pwd);
  151.  
  152.     /**
  153.      * Connect to the RDBMS persistently.
  154.      * 
  155.      * RDBMS specific.
  156.      */
  157.     abstract protected function make_persistent_connection($host$uid$pwd);
  158.  
  159.     /**
  160.      * Set connection character set
  161.      *
  162.      * RDBMS specific
  163.      */
  164.     abstract protected function set_charset($charset);
  165.  
  166.     /**
  167.      * Select a database.
  168.      * 
  169.      * RDBMS specific.
  170.      */
  171.     abstract protected function select_db($dbname);
  172.  
  173.     // ----------
  174.     // DISCONNECT
  175.     // ----------
  176.  
  177.     /**
  178.      * Disconnect from db.
  179.      * 
  180.      * RDBMS specific.
  181.      */
  182.     abstract public function disconnect();
  183.  
  184.     // ----------------
  185.     // CLIPPERCMS DBAPI
  186.     // ----------------
  187.  
  188.     /**
  189.      * Escape a string
  190.      *
  191.      * @param string $s 
  192.      * @return string 
  193.      */    
  194.     final public function escape($s{
  195.         $this->connection_check();
  196.         return $this->_escape($s);
  197.     }
  198.  
  199.     /**
  200.      * Query the database.
  201.      *
  202.      * Developers should use select, update, insert (etc), delete where possible
  203.      *
  204.      * @param string $sql 
  205.      * @param bool $suppress_errors If true, return false on error, otherwise quit via MessageQuit().
  206.      * @return resource 
  207.      */
  208.     final public function query($sql$suppress_errors false{
  209.         $this->connection_check();
  210.         $tstart $this->parent->getMicroTime();
  211.         if (!$result @$this->_query($sql$this->conn)) {
  212.             if ($suppress_errors{
  213.                 return false;
  214.             else {
  215.                 $this->parent->messageQuit("Execution of a query to the database failed - " $this->getLastError()$sql);
  216.             }
  217.         else {
  218.             $tend $this->parent->getMicroTime();
  219.             $totaltime $tend $tstart;
  220.             $this->parent->queryTime $this->parent->queryTime $totaltime;
  221.             if ($this->parent->dumpSQL{
  222.                 $this->parent->queryCode .= "<fieldset style='text-align:left'><legend>Query " ($this->executedQueries 1" - " sprintf("%2.4f s"$totaltime"</legend>" $sql "</fieldset><br />";
  223.             }
  224.             $this->parent->executedQueries $this->parent->executedQueries 1;
  225.             return $result;
  226.         }
  227.     }
  228.  
  229.     /**
  230.      * DELETE
  231.      *
  232.      * @param string $from 
  233.      * @param string $where 
  234.      * @param string|array$fields 
  235.      * @return resource 
  236.      */
  237.     final public function delete($from$where ''$fields ''{
  238.         if (!$from{
  239.             return false;
  240.         else {
  241.             if (is_array($fields)) $fields implode(','$fields);
  242.             $where ($where != ''"WHERE $where'';
  243.             return $this->query("DELETE $fields FROM $from $where");
  244.         }
  245.     }
  246.  
  247.     /**
  248.      * SELECT
  249.      * 
  250.      * @param string|array$fields 
  251.      * @param string $from 
  252.      * @param string $where 
  253.      * @param string $orderby 
  254.      * @param string $limit 
  255.      * @return resource 
  256.      */
  257.     final public function select($fields "*"$from ''$where ''$orderby ''$limit ''{
  258.         if (!$from{
  259.             return false;
  260.         else {
  261.             if (is_array($fields)) $fields implode(','$fields);
  262.             $where ($where != ''"WHERE $where'';
  263.             $orderby ($orderby != ''"ORDER BY $orderby '';
  264.             $limit ($limit != ''"LIMIT $limit'';
  265.             return $this->query("SELECT $fields FROM $from $where $orderby $limit");
  266.         }
  267.     }
  268.  
  269.     /**
  270.      * UPDATE
  271.      *
  272.      * @param string|array$fields 
  273.      * @param string $table 
  274.      * @param string $where 
  275.      * @return resource 
  276.      */
  277.     final public function update($fields$table$where ''{
  278.         if (!$table{
  279.             return false;
  280.         else {
  281.             if (!is_array($fields)) {
  282.                 $flds $fields;
  283.             else {
  284.                 $flds '';
  285.                 foreach ($fields as $key => $value{
  286.                     if (!empty ($flds)) $flds .= ',';
  287.                     $flds .= "$key = '$value'";
  288.                 }
  289.             }
  290.             $where ($where != ''"WHERE $where'';
  291.             return $this->query("UPDATE $table SET $flds $where");
  292.         }
  293.     }
  294.  
  295.     /**
  296.      * INSERT
  297.      *
  298.      * @param string|array$fields 
  299.      * @param string $intotable 
  300.      * @param string|array$fromfields 
  301.      * @param string $fromtable 
  302.      * @param string $where 
  303.      * @param string $limit 
  304.      * @return mixed Either last id inserted (if supported) or the result from the query
  305.      */
  306.     final public function insert($fields$intotable$fromfields "*"$fromtable ''$where ''$limit ''{
  307.         return $this->__insert('INSERT'$fields$intotable$fromfields$fromtable$where$limit);
  308.     }
  309.  
  310.     /**
  311.      * INSERT IGNORE
  312.      *
  313.      * @param string|array$fields 
  314.      * @param string $intotable 
  315.      * @param string|array$fromfields 
  316.      * @param string $fromtable 
  317.      * @param string $where 
  318.      * @param string $limit 
  319.      * @return mixed Either last id inserted (if supported) or the result from the query
  320.      */
  321.     public function insert_ignore($fields$intotable$fromfields "*"$fromtable ''$where ''$limit ''{
  322.         return $this->__insert('INSERT IGNORE'$fields$intotable$fromfields$fromtable$where$limit);
  323.     }    
  324.     
  325.     /**
  326.      * REPLACE
  327.      *
  328.      * @param string|array$fields 
  329.      * @param string $intotable 
  330.      * @param string|array$fromfields 
  331.      * @param string $fromtable 
  332.      * @param string $where 
  333.      * @param string $limit 
  334.      * @return mixed Either last id inserted (if supported) or the result from the query
  335.     */
  336.     public function replace($fields$intotable$fromfields "*"$fromtable ''$where ''$limit ''{
  337.         return $this->__insert('REPLACE'$fields$intotable$fromfields$fromtable$where$limit);
  338.     }    
  339.  
  340.     /**
  341.      * Internal private insert function for use by the above.
  342.      */
  343.     private function __insert($insert_method$fields$intotable$fromfields "*"$fromtable ''$where ''$limit ''{
  344.         if (!$intotable{
  345.             return false;
  346.         else {
  347.             $sql '';
  348.             if (!is_array($fields))
  349.                 $flds $fields;
  350.             else {
  351.                 $keys array_keys($fields);
  352.                 $values array_values($fields);
  353.                 $flds '('.implode(','$keys).') '.(!$fromtable && $values 'VALUES(\''.implode('\',\''$values).'\')' '');
  354.             }
  355.             
  356.             if ($fromtable{
  357.                 if (is_array($fromfields)) $fromfields implode(','$fromfields);
  358.                 $where ($where != ''"WHERE $where'';
  359.                 $limit ($limit != ''"LIMIT $limit'';
  360.                 $sql "SELECT $fromfields FROM $fromtable $where $limit";
  361.             }
  362.  
  363.             $rt $this->query("$insert_method $intotable $flds $sql");
  364.             $lid $this->_getInsertId();
  365.             return $lid $lid $rt;
  366.         }
  367.     }
  368.  
  369.     /**
  370.      * Get the last insert ID
  371.      *
  372.      * @return void 
  373.      */
  374.     final public function getInsertId({
  375.         return $this->_getInsertId();
  376.     }
  377.     
  378.     /**
  379.      * Get the number of affected rows.
  380.      *
  381.      * RDBMS specific.
  382.      *
  383.      * @return int 
  384.      */
  385.     abstract public function getAffectedRows();
  386.  
  387.     /**
  388.      * Get the last error.
  389.      *
  390.      * RDBMS specific.
  391.      *
  392.      * @param string $type 
  393.      * @return string 
  394.      */
  395.     abstract public function getLastError($return_number false);
  396.  
  397.     /**
  398.      * Get the number of rows in a resultset. Return 0 if resultset invalid.
  399.      *
  400.      * @param resource $rs Resultset
  401.      * @return int 
  402.      */
  403.     final public function getRecordCount($rs{
  404.         return $rs $this->_recordcount($rs0;
  405.     }
  406.  
  407.     /**
  408.      * Return an array of column values
  409.      *
  410.      * @param resource $rs Resultset
  411.      * @param string $mode 'assoc', 'num' or 'both'.
  412.      * @return array 
  413.      */
  414.     final public function getRow($rs$mode 'assoc'{
  415.         if ($rs{
  416.             if ($mode == 'assoc'{
  417.                 return $this->_getRowAssoc($rs);
  418.             elseif ($mode == 'num'{
  419.                 return $this->_getRowNumeric($rs);
  420.             elseif ($mode == 'both'{
  421.                 return $this->_getRowBoth($rs);
  422.             else {
  423.                 $this->parent->messageQuit("Unknown get type ($mode) specified for getRow - must be empty, 'assoc', 'num' or 'both'.");
  424.             }
  425.         }
  426.     }
  427.     
  428.     /**
  429.      * Returns an array of the values found on column $name
  430.      *
  431.      * @param string $name Column name
  432.      * @param mixed $rsq Resultset or query string
  433.      * @return array 
  434.      */
  435.     final public function getColumn($name$rsq{
  436.     
  437.         if (is_string($rsq)) {
  438.             $rsq $this->query($rsq);
  439.         }
  440.         
  441.         if ($rsq{
  442.             $col array ();
  443.             while ($row $this->getRow($rsq)) {
  444.                 $col[$row[$name];
  445.             }
  446.             return $col;
  447.         }
  448.     }
  449.   
  450.     /**
  451.      * Returns an array containing the column names in a resultset.
  452.      *
  453.      * @param mixed $rsq Resultset or query string
  454.      * @return array 
  455.      */
  456.     final public function getColumnNames($rsq{
  457.     
  458.         if (is_string($rsq)) {
  459.             $rsq $this->query($rsq);
  460.         }
  461.  
  462.         $this->_getColumnNames($rsq);
  463.     }
  464.  
  465.     /**
  466.      * Returns the value from the first column in the set.
  467.      *
  468.      * @param mixed $rsq Resultset or query string
  469.      * @return string 
  470.      */
  471.     final public function getValue($rsq{
  472.  
  473.         if (is_string($rsq)) {
  474.             $rsq $this->query($rsq);
  475.         }
  476.  
  477.         if ($rsq{
  478.             $r $this->getRow($rsq'num');
  479.             return $r[0];
  480.         }
  481.     }
  482.  
  483.     /**
  484.      * Returns an XML representation of the dataset $rsq
  485.      *
  486.      * @param mixed Resultset or query string
  487.      * @return string 
  488.      */
  489.     final public function getXML($rsq{
  490.  
  491.         if (is_string($rsq)) {
  492.             $rsq $this->query($rsq);
  493.         }
  494.         
  495.         $xmldata "<xml>\r\n<recordset>\r\n";
  496.         while ($row $this->getRow($rsq'assoc')) {
  497.             $xmldata .= "<item>\r\n";
  498.             for ($j 0$line each($row)$j++{
  499.                     $xmldata .= "<{$line['key']}>{$line['value']}</{$line['key']}>\r\n";
  500.             }
  501.             $xmldata .= "</item>\r\n";
  502.         }
  503.         $xmldata .= "</recordset>\r\n</xml>";
  504.         return $xmldata;
  505.     }
  506.  
  507.     /**
  508.      * Returns an array of structure detail for each column of a
  509.      *
  510.      * @param string $table The full name of the database table
  511.      * @return array 
  512.      */
  513.     abstract public function getTableMetaData($table);
  514.  
  515.  
  516.     /**
  517.      * Returns a string containing the database server version
  518.      *
  519.      * @return string 
  520.      */
  521.     abstract public function getVersion();
  522.     
  523.     /**
  524.      * Free memory associated with a resultset
  525.      *
  526.      * @return void 
  527.      */
  528.     abstract public function freeResult($rs);
  529.     
  530.     /**
  531.      * Prepares a date in the proper format for specific database types given a UNIX timestamp
  532.      *
  533.      * @param int $timestamp: a UNIX timestamp
  534.      * @param string $fieldType: the type of field to format the date for
  535.      *             (in MySQL, you have DATE, TIME, YEAR, and DATETIME)
  536.      * @return string 
  537.      */
  538.     public function prepareDate($timestamp$fieldType 'DATETIME'{
  539.         $date '';
  540.         if (!$timestamp === false && $timestamp 0{
  541.             switch ($fieldType{
  542.                 case 'DATE' :
  543.                     $date date('Y-m-d'$timestamp);
  544.                     break;
  545.                 case 'TIME' :
  546.                     $date date('H:i:s'$timestamp);
  547.                     break;
  548.                 case 'YEAR' :
  549.                     $date date('Y'$timestamp);
  550.                     break;
  551.                 default :
  552.                     $date date('Y-m-d H:i:s'$timestamp);
  553.                     break;
  554.             }
  555.         }
  556.         return $date;
  557.     }
  558.  
  559.     /**
  560.      * @param string|resource$rsq Resultset or SQL query
  561.      * @param array $params Data grid parameters
  562.      *             columnHeaderClass
  563.      *             tableClass
  564.      *             itemClass
  565.      *             altItemClass
  566.      *             columnHeaderStyle
  567.      *             tableStyle
  568.      *             itemStyle
  569.      *             altItemStyle
  570.      *             columns
  571.      *             fields
  572.      *             colWidths
  573.      *             colAligns
  574.      *             colColors
  575.      *             colTypes
  576.      *             cellPadding
  577.      *             cellSpacing
  578.      *             header
  579.      *             footer
  580.      *             pageSize
  581.      *             pagerLocation
  582.      *             pagerClass
  583.      *             pagerStyle
  584.      *
  585.      */
  586.     final public function getHTMLGrid($rsq$params{
  587.  
  588.         if (is_string($rsq)) {
  589.             $rsq $this->query($rsq);
  590.         }
  591.         
  592.         if ($rsq{
  593.             require_once(dirname(__FILE__).'../includes/controls/datagrid.class.php');
  594.             
  595.             $grd new DataGrid(''$rsq);
  596.  
  597.             $grd->noRecordMsg $params['noRecordMsg'];
  598.  
  599.             $grd->columnHeaderClass $params['columnHeaderClass'];
  600.             $grd->cssClass $params['cssClass'];
  601.             $grd->itemClass $params['itemClass'];
  602.             $grd->altItemClass $params['altItemClass'];
  603.  
  604.             $grd->columnHeaderStyle $params['columnHeaderStyle'];
  605.             $grd->cssStyle $params['cssStyle'];
  606.             $grd->itemStyle $params['itemStyle'];
  607.             $grd->altItemStyle $params['altItemStyle'];
  608.  
  609.             $grd->columns $params['columns'];
  610.             $grd->fields $params['fields'];
  611.             $grd->colWidths $params['colWidths'];
  612.             $grd->colAligns $params['colAligns'];
  613.             $grd->colColors $params['colColors'];
  614.             $grd->colTypes $params['colTypes'];
  615.             $grd->colWraps $params['colWraps'];
  616.  
  617.             $grd->cellPadding $params['cellPadding'];
  618.             $grd->cellSpacing $params['cellSpacing'];
  619.             $grd->header $params['header'];
  620.             $grd->footer $params['footer'];
  621.             $grd->pageSize $params['pageSize'];
  622.             $grd->pagerLocation $params['pagerLocation'];
  623.             $grd->pagerClass $params['pagerClass'];
  624.             $grd->pagerStyle $params['pagerStyle'];
  625.  
  626.             return $grd->render();
  627.         }
  628.     }
  629.  
  630.     /**
  631.     * Turns a recordset into a multidimensional array
  632.     * @param resource $rs Resultset
  633.     * @return mixed An array of row arrays from recordset, or empty array if
  634.     *                the recordset was empty, returns false if no recordset
  635.     *                was passed
  636.     */
  637.     final public function makeArray ($rs{
  638.         if (!$rs{
  639.             return false;
  640.         else {
  641.             $rsArray array();
  642.             while ($row $this->getRow($rs)) {
  643.                 $rsArray[$row;
  644.             }
  645.             return $rsArray;
  646.         }
  647.     }
  648.     
  649.     /**
  650.      * Get name of host.
  651.      *
  652.      * @return string 
  653.      */
  654.     final public function getHostname({
  655.             return $this->host;
  656.     }
  657.  
  658.     /**
  659.      * Get name of database.
  660.      *
  661.      * @return string 
  662.      */
  663.     final public function getDBname({
  664.             return $this->dbase;
  665.     }
  666.  
  667.     /**
  668.      * Is a variable a resultset handle?
  669.      *
  670.      * @param mixed $var 
  671.      * @return bool 
  672.      */
  673.     abstract function is_handle($var);
  674.  
  675.     /**
  676.      * Test for presence of Clipper db tables
  677.      *
  678.      * @param string $prefix 
  679.      * @return bool; 
  680.      */
  681.     abstract function tables_present($prefix);
  682.  
  683.     /**
  684.      * Get table engine
  685.      *
  686.      * @return string 
  687.      */
  688.     abstract function table_engine($table);
  689.  
  690.     // -------------------------------------------
  691.     // LOW LEVEL RBDMS-SPECIFIC INTERNAL FUNCTIONS
  692.     // -------------------------------------------
  693.  
  694.     /**
  695.      * Escape a string,
  696.      * 
  697.      * RDBMS specific.
  698.      */
  699.     abstract protected function _escape($s);
  700.  
  701.     /**
  702.      * Make a query.
  703.      * 
  704.      * RDBMS specific.
  705.      */
  706.     abstract protected function _query($sql);
  707.  
  708.     /**
  709.      * Get the last insert ID.
  710.      * 
  711.      * RDBMS specific.
  712.      */
  713.     abstract protected function _getInsertId();
  714.  
  715.     /**
  716.      * Get the number of records in the resultset.
  717.      *
  718.      * RDBMS specific.
  719.      */
  720.     abstract protected function _recordcount($rs);
  721.  
  722.     /**
  723.      * Get the column names in a resultset
  724.      *
  725.      * RDBMS specific.
  726.      *
  727.      * @param mixed $rs resultset
  728.      * @return array 
  729.      */
  730.     abstract protected function _getColumnNames($rs);
  731.     
  732.     /**
  733.      * Get a row into an associative array.
  734.      *
  735.      * RDBMS specific.
  736.      */
  737.     abstract protected function _getRowAssoc($rs);
  738.  
  739.     /**
  740.      * Get a row into a numeric array.
  741.      *
  742.      * RDBMS specific.
  743.      */
  744.     abstract protected function _getRowNumeric($rs);
  745.  
  746.     /**
  747.      * Get a row into both an associative and numeric array.
  748.      *
  749.      * RDBMS specific.
  750.      */
  751.     abstract protected function _getRowBoth($rs);
  752.  
  753. }

Documentation generated on Fri, 21 Jun 2013 12:37:00 +0100 by phpDocumentor 1.4.4