Changeset 2157

Show
Ignore:
Timestamp:
08/27/2007 12:23:36 PM
Author:
xue
Message:

Oracle paging support with active records

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/framework/Data/Common/Oracle/TOracleCommandBuilder.php

    r2087 r2157  
    2020 * @version $Id$ 
    2121 * @package System.Data.Common 
    22  * @since 3.1.1 
     22 * @since 3.1 
    2323 */ 
    2424class TOracleCommandBuilder extends TDbCommandBuilder 
    2525{ 
     26 
    2627        /** 
    2728         * Overrides parent implementation. Only column of type text or character (and its variants) 
     
    4142                return parent::getSearchExpression($columns, $keywords); 
    4243        } 
     44 
    4345        /** 
    4446         * 
     
    5355 
    5456        /** 
    55          * Overrides parent implementation to use PostgreSQL's ILIKE instead of LIKE (case-sensitive). 
    56          * @param string column name. 
    57          * @param array keywords 
    58          * @return string search condition for all words in one column. 
     57         * Overrides parent implementation to use Oracle way of get paginated RecordSet instead of using LIMIT sql clause. 
     58         * @param string SQL query string. 
     59         * @param integer maximum number of rows, -1 to ignore limit. 
     60         * @param integer row offset, -1 to ignore offset. 
     61         * @return string SQL with limit and offset in Oracle way. 
    5962         */ 
    60         protected function getSearchCondition($column, $words
     63        public function applyLimitOffset($sql, $limit=-1, $offset=-1
    6164        { 
    62                 $conditions=array(); 
    63                 foreach($words as $word) 
    64                         $conditions[] = $column.' LIKE '.$this->getDbConnection()->quoteString('%'.$word.'%'); 
    65                 return '('.implode(' AND ', $conditions).')'; 
     65                if( (int)$limit <= 0 && (int)$offset <= 0 ) 
     66                        return $sql; 
     67 
     68                $pradoNUMLIN = 'pradoNUMLIN'; 
     69                $fieldsALIAS = 'xyz'; 
     70 
     71                $nfimDaSQL       = strlen($sql); 
     72                $nfimDoWhere = ( strpos($sql,'ORDER') !== false ? strpos($sql,'ORDER') : $nfimDaSQL ); 
     73                $niniDoSelect= strpos($sql,'SELECT')+6; 
     74                $nfimDoSelect= ( strpos($sql,'FROM') !== false ? strpos($sql,'FROM') : $nfimDaSQL ); 
     75 
     76 
     77                $niniDoWhere= strpos($sql,'WHERE')+5; 
     78 
     79                $WhereConstraint=substr( $sql, $niniDoWhere, $nfimDoWhere-$niniDoWhere ); 
     80 
     81                $WhereInSubSelect=""; 
     82                $WhereMainSelect=""; 
     83                if(trim($WhereConstraint)!=="") 
     84                { 
     85                        $WhereInSubSelect="WHERE ".$WhereConstraint; 
     86                        $WhereMainSelect="AND ".$WhereConstraint; 
     87                } 
     88 
     89                $sORDERBY        = ''; 
     90                if( stripos($sql,'ORDER') !== false ) { 
     91                        $p = stripos($sql,'ORDER'); 
     92                        $sORDERBY = substr( $sql, $p+8, 10000 ); 
     93                } 
     94 
     95                $fields                 = substr( $sql, 0, $nfimDoSelect ); 
     96                $fields                 = trim( substr( $fields, $niniDoSelect ) ); 
     97                $aliasedFields  = ', '; 
     98 
     99                if( trim($fields) == '*' ) { 
     100                        $aliasedFields  = ", {$fieldsALIAS}.{$fields}"; 
     101                        $fields                 = ''; 
     102                        $arr                    = $this->getTableInfo()->getColumns(); 
     103                        foreach( $arr as $field ) 
     104                        { 
     105                                $fields .= strtolower( $field->getColumnName() ).', '; 
     106                        } 
     107                        $fields = str_replace( '"', '', $fields ); 
     108                        $fields = trim($fields); 
     109                        $fields = substr( $fields, 0, strlen($fields)-1 ); 
     110                } else { 
     111                        if( strpos( $fields, ',' ) !== false ) 
     112                        { 
     113                                $arr= $this->getTableInfo()->getColumns(); 
     114                                foreach( $arr as $field ) 
     115                                { 
     116                                        $field = strtolower( $field ); 
     117                                        $existAS = str_ireplace( ' as ', '-as-', $field ); 
     118                                        if( strpos( $existAS, '-as-' ) === false ) 
     119                                                $aliasedFields .= "{$fieldsALIAS}.".trim($field).", "; 
     120                                        else 
     121                                                $aliasedFields .= "{$field}, "; 
     122                                } 
     123                                $aliasedFields = trim($aliasedFields); 
     124                                $aliasedFields = substr( $aliasedFields, 0, strlen($aliasedFields)-1 ); 
     125                        } 
     126                } 
     127 
     128                /* ************************ 
     129                $newSql = " SELECT $fields FROM ". 
     130                                  "(                                    ". 
     131                                  "             SELECT rownum as {$pradoNUMLIN} {$aliasedFields} FROM ". 
     132                                  " ($sql) {$fieldsALIAS} WHERE rownum <= {$limit} ". 
     133                                  ") WHERE {$pradoNUMLIN} >= {$offset} "; 
     134 
     135                ************************* */ 
     136                $toReg = $offset + $limit-1; 
     137                $fullTableName = $this->getTableInfo()->getTableFullName(); 
     138                if( empty($sORDERBY) ) 
     139                { 
     140                        $newSql = " SELECT $fields FROM " . 
     141                                          "(                                    " . 
     142                                          "             SELECT ROW_NUMBER() OVER ( ORDER BY ROWNUM ) as {$pradoNUMLIN} {$aliasedFields} " . 
     143                                          "             FROM {$fullTableName} {$fieldsALIAS}" . 
     144                                          ") nn                                 " . 
     145                                          " WHERE nn.{$pradoNUMLIN} >= {$offset} AND nn.{$pradoNUMLIN} <= {$toReg} " ; 
     146                } else { 
     147                        $newSql = " SELECT $fields FROM " . 
     148                                          "(                                    " . 
     149                                          "             SELECT ROW_NUMBER() OVER ( ORDER BY {$sORDERBY} ) as {$pradoNUMLIN} {$aliasedFields} " . 
     150                                          "             FROM {$fullTableName} {$fieldsALIAS} $WhereInSubSelect" . 
     151                                          ") nn                                 " . 
     152                                          " WHERE nn.{$pradoNUMLIN} >= {$offset} AND nn.{$pradoNUMLIN} <= {$toReg} $WhereMainSelect" ; 
     153                } 
     154 
     155                return $newSql; 
    66156        } 
     157 
    67158 
    68159}