From 68d0039cf129069e0548fd92e525a066c9ce41df Mon Sep 17 00:00:00 2001 From: xue <> Date: Mon, 27 Aug 2007 17:23:36 +0000 Subject: Oracle paging support with active records --- .../Data/Common/Oracle/TOracleCommandBuilder.php | 111 +++++++++++++++++++-- 1 file changed, 101 insertions(+), 10 deletions(-) (limited to 'framework/Data/Common/Oracle') diff --git a/framework/Data/Common/Oracle/TOracleCommandBuilder.php b/framework/Data/Common/Oracle/TOracleCommandBuilder.php index 5d793e60..732f5a09 100644 --- a/framework/Data/Common/Oracle/TOracleCommandBuilder.php +++ b/framework/Data/Common/Oracle/TOracleCommandBuilder.php @@ -19,10 +19,11 @@ Prado::using('System.Data.Common.TDbCommandBuilder'); * @author Marcos Nobre * @version $Id$ * @package System.Data.Common - * @since 3.1.1 + * @since 3.1 */ class TOracleCommandBuilder extends TDbCommandBuilder { + /** * Overrides parent implementation. Only column of type text or character (and its variants) * accepts the LIKE criteria. @@ -40,6 +41,7 @@ class TOracleCommandBuilder extends TDbCommandBuilder } return parent::getSearchExpression($columns, $keywords); } + /** * * @return boolean true if column can be used for LIKE searching. @@ -52,19 +54,108 @@ class TOracleCommandBuilder extends TDbCommandBuilder } /** - * Overrides parent implementation to use PostgreSQL's ILIKE instead of LIKE (case-sensitive). - * @param string column name. - * @param array keywords - * @return string search condition for all words in one column. + * Overrides parent implementation to use Oracle way of get paginated RecordSet instead of using LIMIT sql clause. + * @param string SQL query string. + * @param integer maximum number of rows, -1 to ignore limit. + * @param integer row offset, -1 to ignore offset. + * @return string SQL with limit and offset in Oracle way. */ - protected function getSearchCondition($column, $words) + public function applyLimitOffset($sql, $limit=-1, $offset=-1) { - $conditions=array(); - foreach($words as $word) - $conditions[] = $column.' LIKE '.$this->getDbConnection()->quoteString('%'.$word.'%'); - return '('.implode(' AND ', $conditions).')'; + if( (int)$limit <= 0 && (int)$offset <= 0 ) + return $sql; + + $pradoNUMLIN = 'pradoNUMLIN'; + $fieldsALIAS = 'xyz'; + + $nfimDaSQL = strlen($sql); + $nfimDoWhere = ( strpos($sql,'ORDER') !== false ? strpos($sql,'ORDER') : $nfimDaSQL ); + $niniDoSelect= strpos($sql,'SELECT')+6; + $nfimDoSelect= ( strpos($sql,'FROM') !== false ? strpos($sql,'FROM') : $nfimDaSQL ); + + + $niniDoWhere= strpos($sql,'WHERE')+5; + + $WhereConstraint=substr( $sql, $niniDoWhere, $nfimDoWhere-$niniDoWhere ); + + $WhereInSubSelect=""; + $WhereMainSelect=""; + if(trim($WhereConstraint)!=="") + { + $WhereInSubSelect="WHERE ".$WhereConstraint; + $WhereMainSelect="AND ".$WhereConstraint; + } + + $sORDERBY = ''; + if( stripos($sql,'ORDER') !== false ) { + $p = stripos($sql,'ORDER'); + $sORDERBY = substr( $sql, $p+8, 10000 ); + } + + $fields = substr( $sql, 0, $nfimDoSelect ); + $fields = trim( substr( $fields, $niniDoSelect ) ); + $aliasedFields = ', '; + + if( trim($fields) == '*' ) { + $aliasedFields = ", {$fieldsALIAS}.{$fields}"; + $fields = ''; + $arr = $this->getTableInfo()->getColumns(); + foreach( $arr as $field ) + { + $fields .= strtolower( $field->getColumnName() ).', '; + } + $fields = str_replace( '"', '', $fields ); + $fields = trim($fields); + $fields = substr( $fields, 0, strlen($fields)-1 ); + } else { + if( strpos( $fields, ',' ) !== false ) + { + $arr= $this->getTableInfo()->getColumns(); + foreach( $arr as $field ) + { + $field = strtolower( $field ); + $existAS = str_ireplace( ' as ', '-as-', $field ); + if( strpos( $existAS, '-as-' ) === false ) + $aliasedFields .= "{$fieldsALIAS}.".trim($field).", "; + else + $aliasedFields .= "{$field}, "; + } + $aliasedFields = trim($aliasedFields); + $aliasedFields = substr( $aliasedFields, 0, strlen($aliasedFields)-1 ); + } + } + + /* ************************ + $newSql = " SELECT $fields FROM ". + "( ". + " SELECT rownum as {$pradoNUMLIN} {$aliasedFields} FROM ". + " ($sql) {$fieldsALIAS} WHERE rownum <= {$limit} ". + ") WHERE {$pradoNUMLIN} >= {$offset} "; + + ************************* */ + $toReg = $offset + $limit-1; + $fullTableName = $this->getTableInfo()->getTableFullName(); + if( empty($sORDERBY) ) + { + $newSql = " SELECT $fields FROM " . + "( " . + " SELECT ROW_NUMBER() OVER ( ORDER BY ROWNUM ) as {$pradoNUMLIN} {$aliasedFields} " . + " FROM {$fullTableName} {$fieldsALIAS}" . + ") nn " . + " WHERE nn.{$pradoNUMLIN} >= {$offset} AND nn.{$pradoNUMLIN} <= {$toReg} " ; + } else { + $newSql = " SELECT $fields FROM " . + "( " . + " SELECT ROW_NUMBER() OVER ( ORDER BY {$sORDERBY} ) as {$pradoNUMLIN} {$aliasedFields} " . + " FROM {$fullTableName} {$fieldsALIAS} $WhereInSubSelect" . + ") nn " . + " WHERE nn.{$pradoNUMLIN} >= {$offset} AND nn.{$pradoNUMLIN} <= {$toReg} $WhereMainSelect" ; + } + + return $newSql; } + } ?> \ No newline at end of file -- cgit v1.2.3