Passed
Push — master ( 7ff405...d0230e )
by Adrian
01:39
created

DbService   B

Complexity

Total Complexity 44

Size/Duplication

Total Lines 267
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 44
dl 0
loc 267
rs 8.3396
c 2
b 0
f 0

11 Methods

Rating   Name   Duplication   Size   Complexity  
A bindMore() 0 6 4
A single() 0 7 1
A column() 0 19 3
A CloseConnection() 0 3 1
A row() 0 14 2
C query() 0 24 8
C queryInit() 0 57 11
A bind() 0 3 1
D getQueryStatement() 0 28 9
A getInstance() 0 7 2
A isArrayAssoc() 0 6 2

How to fix   Complexity   

Complex Class

Complex classes like DbService often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use DbService, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * Author: Adrian Dumitru
5
 * Date: 6/1/2017 4:14 PM
6
 */
7
8
namespace Qpdb\QueryBuilder\DB;
9
10
11
class DbService
12
{
13
14
	const QUERY_TYPE_INSERT = 'INSERT';
15
	const QUERY_TYPE_DELETE = 'DELETE';
16
	const QUERY_TYPE_UPDATE = 'UPDATE';
17
	const QUERY_TYPE_SELECT = 'SELECT';
18
	const QUERY_TYPE_REPLACE = 'REPLACE';
19
	const QUERY_TYPE_SHOW = 'SHOW';
20
	const QUERY_TYPE_DESC = 'DESC';
21
	const QUERY_TYPE_EMPTY = 'EMPTY';
22
	const QUERY_TYPE_OTHER = 'OTHER';
23
	const QUERY_TYPE_EXPLAIN = 'EXPLAIN';
24
25
	const ON_ERROR_THROW_EXCEPTION = 1;
26
	const ON_ERROR_RETURN_ERROR = 2;
27
28
	/**
29
	 * @var DbService
30
	 */
31
	private static $instance;
32
33
	/**
34
	 * @var \PDO
35
	 */
36
	private $pdo;
37
38
	/**
39
	 * @var \PDOStatement
40
	 */
41
	private $sQuery;
42
43
	/**
44
	 * @var array
45
	 */
46
	private $parameters = [];
47
48
49
	/**
50
	 * @param string $query
51
	 * @param array $params
52
	 * @param int $fetchMode
53
	 * @return array|int|null
54
	 */
55
	public function query( $query, $params = null, $fetchMode = \PDO::FETCH_ASSOC )
56
	{
57
58
		$query = trim( str_replace( "\r", " ", $query ) );
59
		$statement = self::getQueryStatement( $query );
60
61
		$this->queryInit( $query, $params );
62
63
		if ( $statement === self::QUERY_TYPE_SELECT ||
64
			$statement === self::QUERY_TYPE_SHOW ||
65
			$statement === self::QUERY_TYPE_DESC ||
66
			$statement === self::QUERY_TYPE_EXPLAIN
67
		) {
68
			return $this->sQuery->fetchAll( $fetchMode );
69
		}
70
		elseif ( $statement === self::QUERY_TYPE_INSERT ||
71
			$statement === self::QUERY_TYPE_UPDATE ||
72
			$statement === self::QUERY_TYPE_DELETE
73
		) {
74
			return $this->sQuery->rowCount();
75
		}
76
		else {
77
78
			return NULL;
79
		}
80
	}
81
82
	/**
83
	 * @param $query
84
	 * @param array $params
85
	 * @return array|null
86
	 */
87
	public function column( $query, $params = null )
88
	{
89
		$this->queryInit( $query, $params );
90
91
		$query = trim( str_replace( "\r", " ", $query ) );
92
		$statement = self::getQueryStatement( $query );
93
94
		if ( $statement === self::QUERY_TYPE_EXPLAIN )
95
			return $this->sQuery->fetchAll( \PDO::FETCH_ASSOC );
96
97
		$Columns = $this->sQuery->fetchAll( \PDO::FETCH_NUM );
98
99
		$column = null;
100
101
		foreach ( $Columns as $cells ) {
102
			$column[] = $cells[ 0 ];
103
		}
104
105
		return $column;
106
	}
107
108
	public function row( $query, $params = null, $fetchmode = \PDO::FETCH_ASSOC )
109
	{
110
		$this->queryInit( $query, $params );
111
112
		$query = trim( str_replace( "\r", " ", $query ) );
113
		$statement = self::getQueryStatement( $query );
114
115
		if ( $statement === self::QUERY_TYPE_EXPLAIN )
116
			return $this->sQuery->fetchAll( \PDO::FETCH_ASSOC );
117
118
		$result = $this->sQuery->fetch( $fetchmode );
119
		$this->sQuery->closeCursor(); // Frees up the connection to the server so that other SQL statements may be issued,
120
121
		return $result;
122
	}
123
124
	public function single( $query, $params = null )
125
	{
126
		$this->queryInit( $query, $params );
127
		$result = $this->sQuery->fetchColumn();
128
		$this->sQuery->closeCursor(); // Frees up the connection to the server so that other SQL statements may be issued
129
130
		return $result;
131
	}
132
133
134
	/**
135
	 * @param string $query
136
	 * @param array $parameters
137
	 */
138
	private function queryInit( $query, $parameters = [] )
139
	{
140
		$this->pdo = DbConnect::getInstance()->getConnection( self::getQueryStatement( $query ) );
141
		$startQueryTime = microtime( true );
142
143
		try {
144
145
			/**
146
			 * Prepare query
147
			 */
148
			$this->sQuery = $this->pdo->prepare( $query );
149
150
			/**
151
			 * Add parameters to the parameter array
152
			 */
153
			if ( self::isArrayAssoc( $parameters ) )
154
				$this->bindMore( $parameters );
155
			else
156
				foreach ( $parameters as $key => $val )
157
					$this->parameters[] = array( $key + 1, $val );
158
159
			if ( count( $this->parameters ) ) {
160
				foreach ( $this->parameters as $param => $value ) {
161
					if ( is_int( $value[ 1 ] ) ) {
162
						$type = \PDO::PARAM_INT;
163
					}
164
					elseif ( is_bool( $value[ 1 ] ) ) {
165
						$type = \PDO::PARAM_BOOL;
166
					}
167
					elseif ( is_null( $value[ 1 ] ) ) {
168
						$type = \PDO::PARAM_NULL;
169
					}
170
					else {
171
						$type = \PDO::PARAM_STR;
172
					}
173
					$this->sQuery->bindValue( $value[ 0 ], $value[ 1 ], $type );
174
				}
175
			}
176
177
			$this->sQuery->execute();
178
179
			if ( DbConfig::getInstance()->isEnableLogQueryDuration() ) {
180
				$duration = microtime( true ) - $startQueryTime;
181
				DbLog::getInstance()->writeQueryDuration( $query, $duration );
182
			}
183
184
		} catch ( \PDOException $e ) {
185
			if ( DbConfig::getInstance()->isEnableLogErrors() ) {
186
				DbLog::getInstance()->writeQueryErros( $query, $e->getCode(), $e->getMessage() );
187
			}
188
			throw new DbException( 'Database error!', DbException::DB_QUERY_ERROR );
189
		}
190
191
		/**
192
		 * Reset the parameters
193
		 */
194
		$this->parameters = array();
195
	}
196
197
198
	public function bindMore( $parray )
199
	{
200
		if ( !count( $this->parameters ) && is_array( $parray ) ) {
201
			$columns = array_keys( $parray );
202
			foreach ( $columns as $i => &$column ) {
203
				$this->bind( $column, $parray[ $column ] );
204
			}
205
		}
206
	}
207
208
	public function bind( $para, $value )
209
	{
210
		$this->parameters[ sizeof( $this->parameters ) ] = [ ":" . $para, $value ];
211
	}
212
213
214
	public function CloseConnection()
215
	{
216
		$this->pdo = null;
217
	}
218
219
220
	/**
221
	 * @param $queryString
222
	 * @return string
223
	 */
224
	public static function getQueryStatement( $queryString )
225
	{
226
		$queryString = trim( $queryString );
227
228
		if ( $queryString === '' ) {
229
			return self::QUERY_TYPE_EMPTY;
230
		}
231
232
		if ( preg_match( '/^(select|insert|update|delete|replace|show|desc|explain)[\s]+/i', $queryString, $matches ) ) {
233
			switch ( strtolower( $matches[ 1 ] ) ) {
234
				case 'select':
235
					return self::QUERY_TYPE_SELECT;
236
				case 'insert':
237
					return self::QUERY_TYPE_INSERT;
238
				case 'update':
239
					return self::QUERY_TYPE_UPDATE;
240
				case 'delete':
241
					return self::QUERY_TYPE_DELETE;
242
				case 'replace':
243
					return self::QUERY_TYPE_REPLACE;
244
				case 'explain':
245
					return self::QUERY_TYPE_EXPLAIN;
246
				default:
247
					return self::QUERY_TYPE_OTHER;
248
			}
249
		}
250
		else {
251
			return self::QUERY_TYPE_OTHER;
252
		}
253
	}
254
255
	/**
256
	 * @param array $arr
257
	 * @return bool
258
	 */
259
	public static function isArrayAssoc( array $arr )
260
	{
261
		if ( array() === $arr )
262
			return false;
263
264
		return array_keys( $arr ) !== range( 0, count( $arr ) - 1 );
265
	}
266
267
268
	/**
269
	 * @return DbService
270
	 */
271
	public static function getInstance()
272
	{
273
		if ( null === self::$instance ) {
274
			self::$instance = new self();
275
		}
276
277
		return self::$instance;
278
	}
279
280
}