Completed
Branch master (099915)
by Fabio
08:02
created

TOracleCommandBuilder::applyLimitOffset()   C

Complexity

Conditions 14
Paths 193

Size

Total Lines 82
Code Lines 53

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 210

Importance

Changes 0
Metric Value
cc 14
eloc 53
c 0
b 0
f 0
nc 193
nop 3
dl 0
loc 82
ccs 0
cts 65
cp 0
crap 210
rs 5.4916

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * TOracleCommandBuilder class file.
5
 *
6
 * @author Marcos Nobre <marconobre[at]gmail[dot]com>
7
 * @link https://github.com/pradosoft/prado
8
 * @license https://github.com/pradosoft/prado/blob/master/LICENSE
9
 * @package Prado\Data\Common\Oracle
10
 */
11
12
namespace Prado\Data\Common\Oracle;
13
14
use Prado\Data\Common\TDbCommandBuilder;
15
use Prado\Prado;
16
17
/**
18
 * TOracleCommandBuilder provides specifics methods to create limit/offset query commands
19
 * for Oracle database.
20
 *
21
 * @author Marcos Nobre <marconobre[at]gmail[dot]com>
22
 * @package Prado\Data\Common\Oracle
23
 * @since 3.1
24
 */
25
class TOracleCommandBuilder extends TDbCommandBuilder
26
{
27
28
	/**
29
	 * Overrides parent implementation. Only column of type text or character (and its variants)
30
	 * accepts the LIKE criteria.
31
	 * @param array $fields list of column id for potential search condition.
32
	 * @param string $keywords string of keywords
33
	 * @return string SQL search condition matching on a set of columns.
34
	 */
35
	public function getSearchExpression($fields, $keywords)
36
	{
37
		$columns = [];
38
		foreach ($fields as $field) {
39
			if ($this->isSearchableColumn($this->getTableInfo()->getColumn($field))) {
40
				$columns[] = $field;
41
			}
42
		}
43
		return parent :: getSearchExpression($columns, $keywords);
44
	}
45
	/**
46
	 *
47
	 * @param mixed $column
48
	 * @return bool true if column can be used for LIKE searching.
49
	 */
50
	protected function isSearchableColumn($column)
51
	{
52
		$type = strtolower($column->getDbType());
53
		return $type === 'character varying' || $type === 'varchar2' || $type === 'character' || $type === 'char' || $type === 'text';
54
	}
55
56
	/**
57
	 * Overrides parent implementation to use PostgreSQL's ILIKE instead of LIKE (case-sensitive).
58
	 * @param string $column column name.
59
	 * @param array $words keywords
60
	 * @param mixed $sql
61
	 * @param mixed $limit
62
	 * @param mixed $offset
63
	 * @return string search condition for all words in one column.
64
	 */
65
	/*
66
	*
67
	*	how Oracle don't implements ILIKE, this method won't be overrided
68
	*
69
	protected function getSearchCondition($column, $words)
70
	{
71
		$conditions=array();
72
		foreach($words as $word)
73
			$conditions[] = $column.' LIKE '.$this->getDbConnection()->quoteString('%'.$word.'%');
74
		return '('.implode(' AND ', $conditions).')';
75
	}
76
	*/
77
78
	/**
79
	 * Overrides parent implementation to use Oracle way of get paginated RecordSet instead of using LIMIT sql clause.
80
	 * @param string $sql SQL query string.
81
	 * @param int $limit maximum number of rows, -1 to ignore limit.
82
	 * @param int $offset row offset, -1 to ignore offset.
83
	 * @return string SQL with limit and offset in Oracle way.
84
	 */
85
	public function applyLimitOffset($sql, $limit = -1, $offset = -1)
86
	{
87
		if ((int) $limit <= 0 && (int) $offset <= 0) {
88
			return $sql;
89
		}
90
91
		$pradoNUMLIN = 'pradoNUMLIN';
92
		$fieldsALIAS = 'xyz';
93
94
		$nfimDaSQL = strlen($sql);
95
		$nfimDoWhere = (strpos($sql, 'ORDER') !== false ? strpos($sql, 'ORDER') : $nfimDaSQL);
96
		$niniDoSelect = strpos($sql, 'SELECT') + 6;
97
		$nfimDoSelect = (strpos($sql, 'FROM') !== false ? strpos($sql, 'FROM') : $nfimDaSQL);
98
99
		$WhereInSubSelect = "";
100
		if (strpos($sql, 'WHERE') !== false) {
101
			$WhereInSubSelect = "WHERE " . substr($sql, strpos($sql, 'WHERE') + 5, $nfimDoWhere - $niniDoWhere);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $niniDoWhere seems to be never defined.
Loading history...
102
		}
103
104
		$sORDERBY = '';
105
		if (stripos($sql, 'ORDER') !== false) {
106
			$p = stripos($sql, 'ORDER');
107
			$sORDERBY = substr($sql, $p + 8);
108
		}
109
110
		$fields = substr($sql, 0, $nfimDoSelect);
111
		$fields = trim(substr($fields, $niniDoSelect));
112
		$aliasedFields = ', ';
113
114
		if (trim($fields) == '*') {
115
			$aliasedFields = ", {$fieldsALIAS}.{$fields}";
116
			$fields = '';
117
			$arr = $this->getTableInfo()->getColumns();
118
			foreach ($arr as $field) {
119
				$fields .= strtolower($field->getColumnName()) . ', ';
120
			}
121
			$fields = str_replace('"', '', $fields);
122
			$fields = trim($fields);
123
			$fields = substr($fields, 0, strlen($fields) - 1);
124
		} else {
125
			if (strpos($fields, ',') !== false) {
126
				$arr = $this->getTableInfo()->getColumns();
127
				foreach ($arr as $field) {
128
					$field = strtolower($field);
129
					$existAS = str_ireplace(' as ', '-as-', $field);
130
					if (strpos($existAS, '-as-') === false) {
131
						$aliasedFields .= "{$fieldsALIAS}." . trim($field) . ", ";
132
					} else {
133
						$aliasedFields .= "{$field}, ";
134
					}
135
				}
136
				$aliasedFields = trim($aliasedFields);
137
				$aliasedFields = substr($aliasedFields, 0, strlen($aliasedFields) - 1);
138
			}
139
		}
140
		if ($aliasedFields == ', ') {
141
			$aliasedFields = " , $fieldsALIAS.* ";
142
		}
143
144
		/* ************************
145
		$newSql = " SELECT $fields FROM ".
146
				  "(					".
147
				  "		SELECT rownum as {$pradoNUMLIN} {$aliasedFields} FROM ".
148
				  " ($sql) {$fieldsALIAS} WHERE rownum <= {$limit} ".
149
				  ") WHERE {$pradoNUMLIN} >= {$offset} ";
150
151
		************************* */
152
		$offset = (int) $offset;
153
		$toReg = $offset + $limit;
154
		$fullTableName = $this->getTableInfo()->getTableFullName();
155
		if (empty($sORDERBY)) {
156
			$sORDERBY = "ROWNUM";
157
		}
158
159
		$newSql = " SELECT $fields FROM " .
160
					"(					" .
161
					"		SELECT ROW_NUMBER() OVER ( ORDER BY {$sORDERBY} ) -1 as {$pradoNUMLIN} {$aliasedFields} " .
162
					"		FROM {$fullTableName} {$fieldsALIAS} $WhereInSubSelect" .
163
					") nn					" .
164
					" WHERE nn.{$pradoNUMLIN} >= {$offset} AND nn.{$pradoNUMLIN} < {$toReg} ";
165
		//echo $newSql."\n<br>\n";
166
		return $newSql;
167
	}
168
}
169