Passed
Push — master ( bc2124...9382be )
by Jean-Christophe
11:15
created

DAO   B

Complexity

Total Complexity 51

Size/Duplication

Total Lines 332
Duplicated Lines 0 %

Test Coverage

Coverage 72.79%

Importance

Changes 8
Bugs 0 Features 2
Metric Value
wmc 51
eloc 116
c 8
b 0
f 2
dl 0
loc 332
ccs 99
cts 136
cp 0.7279
rs 7.92

26 Methods

Rating   Name   Duplication   Size   Complexity  
A getDb() 0 2 1
A getAll() 0 3 1
A getConditionParser() 0 9 2
A startDatabase() 0 4 3
A setCache() 0 2 1
A getCache() 0 2 1
A paginate() 0 2 1
A getDbOffset() 0 2 2
A isConnected() 0 3 3
A getById() 0 2 1
A start() 0 2 1
A getDbCacheInstance() 0 3 1
A closeDb() 0 4 2
A warmupCache() 0 10 2
A setModelDatabase() 0 2 1
A setTransformerOp() 0 2 1
A getDatabase() 0 6 2
A getOne() 0 12 3
A connect() 0 7 2
A count() 0 8 2
B updateDatabaseParams() 0 15 7
A exists() 0 8 2
A getDatabases() 0 10 3
A setModelsDatabases() 0 2 1
A getRownum() 0 13 2
A getAllByIds() 0 12 3

How to fix   Complexity   

Complex Class

Complex classes like DAO 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 DAO, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Ubiquity\orm;
4
5
use Ubiquity\db\Database;
6
use Ubiquity\log\Logger;
7
use Ubiquity\db\SqlUtils;
8
use Ubiquity\orm\traits\DAOUpdatesTrait;
9
use Ubiquity\orm\traits\DAORelationsTrait;
10
use Ubiquity\orm\parser\ConditionParser;
11
use Ubiquity\orm\traits\DAOUQueries;
12
use Ubiquity\orm\traits\DAOCoreTrait;
13
use Ubiquity\orm\traits\DAORelationsPrepareTrait;
14
use Ubiquity\exceptions\DAOException;
15
use Ubiquity\orm\traits\DAORelationsAssignmentsTrait;
16
use Ubiquity\orm\traits\DAOTransactionsTrait;
17
use Ubiquity\controllers\Startup;
18
use Ubiquity\cache\CacheManager;
19
use Ubiquity\orm\traits\DAOPooling;
20
use Ubiquity\orm\traits\DAOBulkUpdatesTrait;
21
use Ubiquity\orm\traits\DAOPreparedTrait;
22
use Ubiquity\cache\dao\AbstractDAOCache;
23
24
/**
25
 * Gateway class between database and object model.
26
 * This class is part of Ubiquity
27
 *
28
 * @author jcheron <[email protected]>
29
 * @version 1.2.5
30
 *
31
 */
32
class DAO {
33
	use DAOCoreTrait,DAOUpdatesTrait,DAORelationsTrait,DAORelationsPrepareTrait,DAORelationsAssignmentsTrait,
34
	DAOUQueries,DAOTransactionsTrait,DAOPooling,DAOBulkUpdatesTrait,DAOPreparedTrait;
35
36
	/**
37
	 *
38
	 * @var Database
39
	 */
40
	public static $db;
41
	public static $useTransformers = false;
42
	public static $transformerOp = 'transform';
43
	private static $conditionParsers = [ ];
44
	protected static $modelsDatabase = [ ];
45
	/**
46
	 *
47
	 * @var AbstractDAOCache
48
	 */
49
	protected static $cache;
50
51 119
	public static function getDb($model) {
52 119
		return self::getDatabase ( self::$modelsDatabase [$model] ?? 'default');
53
	}
54
55
	/**
56
	 * Returns an array of $className objects from the database
57
	 *
58
	 * @param string $className class name of the model to load
59
	 * @param string $condition Part following the WHERE of an SQL statement
60
	 * @param boolean|array $included if true, loads associate members with associations, if array, example : ['client.*','commands']
61
	 * @param array|null $parameters
62
	 * @param boolean $useCache use the active cache if true
63
	 * @return array
64
	 */
65 37
	public static function getAll($className, $condition = '', $included = true, $parameters = null, $useCache = NULL) {
66 37
		$db = self::getDb ( $className );
67 37
		return static::_getAll ( $db, $className, new ConditionParser ( $condition, null, $parameters ), $included, $useCache );
68
	}
69
70
	/**
71
	 * Returns an array of $className objects loaded by id from the database
72
	 *
73
	 * @param string $className class name of the model to load
74
	 * @param array|null $parameters
75
	 * @param boolean|array $included if true, loads associate members with associations, if array, example : ['client.*','commands']
76
	 * @param string $condition additional condition
77
	 * @param boolean $useCache use the active cache if true
78
	 * @return array
79
	 */
80
	public static function getAllByIds($className, $keyValues = [ ], $included = true, $condition = '', $useCache = NULL) {
81
		$db = self::getDb ( $className );
82
		$key = OrmUtils::getFirstKey ( $className );
83
		$countK = \count ( $keyValues );
84
		if ($countK > 0) {
85
			$nCondition = $key . ' IN (' . \str_repeat ( '?,', $countK - 1 ) . '?)';
86
			if ($condition != null) {
87
				$nCondition .= ' AND ' . $condition;
88
			}
89
			return static::_getAll ( $db, $className, new ConditionParser ( $nCondition, null, $keyValues ), $included, $useCache );
90
		}
91
		return [];
92
		
93
	}
94
95 4
	public static function paginate($className, $page = 1, $rowsPerPage = 20, $condition = null, $included = true) {
96 4
		return self::getAll ( $className, ($condition ?? '1=1') . ' LIMIT ' . $rowsPerPage . ' OFFSET ' . (($page - 1) * $rowsPerPage), $included );
97
	}
98
99 4
	public static function getRownum($className, $ids) {
100 4
		$tableName = OrmUtils::getTableName ( $className );
101 4
		$db = self::getDb ( $className );
102 4
		$quote = $db->quote;
103 4
		self::parseKey ( $ids, $className, $quote );
104 4
		$condition = SqlUtils::getCondition ( $ids, $className );
105 4
		$keyFields = OrmUtils::getKeyFields ( $className );
106 4
		if (\is_array ( $keyFields )) {
107 4
			$keys = \implode ( ',', $keyFields );
108
		} else {
109
			$keys = '1';
110
		}
111 4
		return $db->getRowNum ( $tableName, $keys, $condition );
112
	}
113
114
	/**
115
	 * Returns the number of objects of $className from the database respecting the condition possibly passed as parameter
116
	 *
117
	 * @param string $className complete classname of the model to load
118
	 * @param string $condition Part following the WHERE of an SQL statement
119
	 * @param array|null $parameters The query parameters
120
	 * @return int|false count of objects
121
	 */
122 30
	public static function count($className, $condition = '', $parameters = null) {
123 30
		$tableName = OrmUtils::getTableName ( $className );
124 30
		if ($condition != '') {
125 9
			$condition = SqlUtils::checkWhere($condition);
126
		}
127 30
		$db = self::getDb ( $className );
128 30
		$quote = $db->quote;
129 30
		return $db->prepareAndFetchColumn ( 'SELECT COUNT(*) FROM ' . $quote . $tableName . $quote . $condition, $parameters );
130
	}
131
132
	/**
133
	 * Tests the existence of objects of $className from the database respecting the condition possibly passed as parameter
134
	 *
135
	 * @param string $className complete classname of the model to load
136
	 * @param string $condition Part following the WHERE of an SQL statement
137
	 * @param array|null $parameters The query parameters
138
	 * @return boolean
139
	 */
140 2
	public static function exists($className, $condition = '', $parameters = null) {
141 2
		$tableName = OrmUtils::getTableName ( $className );
142 2
		if ($condition != '') {
143 2
			$condition = SqlUtils::checkWhere($condition);
144
		}
145 2
		$db = self::getDb ( $className );
146 2
		$quote = $db->quote;
147 2
		return (1 == $db->prepareAndFetchColumn ( "SELECT EXISTS(SELECT 1 FROM {$quote}{$tableName}{$quote}{$condition})", $parameters ));
148
	}
149
150
	/**
151
	 * Returns an instance of $className from the database, from $keyvalues values of the primary key or with a condition
152
	 *
153
	 * @param String $className complete classname of the model to load
154
	 * @param Array|string $condition condition or primary key values
155
	 * @param boolean|array $included if true, charges associate members with association
156
	 * @param array|null $parameters the request parameters
157
	 * @param boolean|null $useCache use cache if true
158
	 * @return object the instance loaded or null if not found
159
	 */
160 26
	public static function getOne($className, $condition, $included = true, $parameters = null, $useCache = NULL) {
161 26
		$db = self::getDb ( $className );
162 26
		$conditionParser = new ConditionParser ();
163 26
		if (! isset ( $parameters )) {
164 25
			$conditionParser->addKeyValues ( $condition, $className );
165 3
		} elseif (! is_array ( $condition )) {
166 3
			$conditionParser->setCondition ( $condition );
167 3
			$conditionParser->setParams ( $parameters );
168
		} else {
169
			throw new DAOException ( "The \$condition parameter should not be an array if \$parameters is not null" );
170
		}
171 26
		return static::_getOne ( $db, $className, $conditionParser, $included, $useCache );
172
	}
173
174
	/**
175
	 * Returns an instance of $className from the database, from $keyvalues values of the primary key
176
	 *
177
	 * @param String $className complete classname of the model to load
178
	 * @param Array|string $keyValues primary key values or condition
179
	 * @param boolean|array $included if true, charges associate members with association
180
	 * @param array|null $parameters the request parameters
181
	 * @param boolean|null $useCache use cache if true
182
	 * @return object the instance loaded or null if not found
183
	 */
184 31
	public static function getById($className, $keyValues, $included = true, $useCache = NULL) {
185 31
		return static::_getOne ( self::getDatabase ( self::$modelsDatabase [$className] ?? 'default'), $className, self::getConditionParser ( $className, $keyValues ), $included, $useCache );
186
	}
187
188 31
	protected static function getConditionParser($className, $keyValues): ConditionParser {
189 31
		if (! isset ( self::$conditionParsers [$className] )) {
190 14
			$conditionParser = new ConditionParser ();
191 14
			$conditionParser->addKeyValues ( $keyValues, $className );
192 14
			self::$conditionParsers [$className] = $conditionParser;
193
		} else {
194 20
			self::$conditionParsers [$className]->setKeyValues ( $keyValues );
195
		}
196 31
		return self::$conditionParsers [$className];
197
	}
198
199
	/**
200
	 * Establishes the connection to the database using the past parameters
201
	 *
202
	 * @param string $offset
203
	 * @param string $wrapper
204
	 * @param string $dbType
205
	 * @param string $dbName
206
	 * @param string $serverName
207
	 * @param string $port
208
	 * @param string $user
209
	 * @param string $password
210
	 * @param array $options
211
	 * @param boolean $cache
212
	 */
213 118
	public static function connect($offset, $wrapper, $dbType, $dbName, $serverName = '127.0.0.1', $port = '3306', $user = 'root', $password = '', $options = [ ], $cache = false) {
214 118
		self::$db [$offset] = new Database ( $wrapper, $dbType, $dbName, $serverName, $port, $user, $password, $options, $cache, self::$pool );
215
		try {
216 118
			self::$db [$offset]->connect ();
217
		} catch ( \Exception $e ) {
218
			Logger::error ( "DAO", $e->getMessage () );
219
			throw new DAOException ( $e->getMessage (), $e->getCode (), $e->getPrevious () );
220
		}
221 118
	}
222
223
	/**
224
	 * Establishes the connection to the database using the $config array
225
	 *
226
	 * @param array $config the config array (Startup::getConfig())
227
	 */
228 25
	public static function startDatabase(&$config, $offset = null) {
229 25
		$db = $offset ? ($config ['database'] [$offset] ?? ($config ['database'] ?? [ ])) : ($config ['database'] ['default'] ?? $config ['database']);
230 25
		if ($db ['dbName'] !== '') {
231 25
			self::connect ( $offset ?? 'default', $db ['wrapper'] ?? \Ubiquity\db\providers\pdo\PDOWrapper::class, $db ['type'], $db ['dbName'], $db ['serverName'] ?? '127.0.0.1', $db ['port'] ?? 3306, $db ['user'] ?? 'root', $db ['password'] ?? '', $db ['options'] ?? [ ], $db ['cache'] ?? false);
232
		}
233 25
	}
234
235 190
	public static function getDbOffset(&$config, $offset = null) {
236 190
		return $offset ? ($config ['database'] [$offset] ?? ($config ['database'] ?? [ ])) : ($config ['database'] ['default'] ?? $config ['database']);
237
	}
238
239
	/**
240
	 * Returns true if the connection to the database is established
241
	 *
242
	 * @return boolean
243
	 */
244 8
	public static function isConnected($offset = 'default') {
245 8
		$db = self::$db [$offset] ?? false;
246 8
		return $db && ($db instanceof Database) && $db->isConnected ();
247
	}
248
249
	/**
250
	 * Sets the transformer operation
251
	 *
252
	 * @param string $op
253
	 */
254
	public static function setTransformerOp($op) {
255
		self::$transformerOp = $op;
256
	}
257
258
	/**
259
	 * Closes the active pdo connection to the database
260
	 */
261 71
	public static function closeDb($offset = 'default') {
262 71
		$db = self::$db [$offset] ?? false;
263 71
		if ($db !== false) {
264 70
			$db->close ();
265
		}
266 71
	}
267
268
	/**
269
	 * Defines the database connection to use for $model class
270
	 *
271
	 * @param string $model a model class
272
	 * @param string $database a database connection defined in config.php
273
	 */
274 10
	public static function setModelDatabase($model, $database = 'default') {
275 10
		self::$modelsDatabase [$model] = $database;
276 10
	}
277
278
	/**
279
	 * Defines the database connections to use for models classes
280
	 *
281
	 * @param array $modelsDatabase
282
	 */
283
	public static function setModelsDatabases($modelsDatabase) {
284
		self::$modelsDatabase = $modelsDatabase;
285
	}
286
287
	/**
288
	 * Returns the database instance defined at $offset key in config
289
	 *
290
	 * @param string $offset
291
	 * @return \Ubiquity\db\Database
292
	 */
293 122
	public static function getDatabase($offset = 'default') {
294 122
		if (! isset ( self::$db [$offset] )) {
295 17
			self::startDatabase ( Startup::$config, $offset );
296
		}
297 122
		SqlUtils::$quote = self::$db [$offset]->quote;
298 122
		return self::$db [$offset];
299
	}
300
301 6
	public static function getDatabases() {
302 6
		$config = Startup::getConfig ();
303 6
		if (isset ( $config ['database'] )) {
304 6
			if (isset ( $config ['database'] ['dbName'] )) {
305
				return [ 'default' ];
306
			} else {
307 6
				return \array_keys ( $config ['database'] );
308
			}
309
		}
310
		return [ ];
311
	}
312
313
	public static function updateDatabaseParams(array &$config, array $parameters, $offset = 'default') {
314
		if ($offset === 'default') {
315
			if (isset ( $config ['database'] [$offset] )) {
316
				foreach ( $parameters as $k => $param ) {
317
					$config ['database'] [$offset] [$k] = $param;
318
				}
319
			} else {
320
				foreach ( $parameters as $k => $param ) {
321
					$config ['database'] [$k] = $param;
322
				}
323
			}
324
		} else {
325
			if (isset ( $config ['database'] [$offset] )) {
326
				foreach ( $parameters as $k => $param ) {
327
					$config ['database'] [$offset] [$k] = $param;
328
				}
329
			}
330
		}
331
	}
332
333 39
	public static function start() {
334 39
		self::$modelsDatabase = CacheManager::getModelsDatabases ();
335 39
	}
336
337
	public static function getDbCacheInstance($model) {
338
		$db = static::$db [self::$modelsDatabase [$model] ?? 'default'];
339
		return $db->getCacheInstance ();
340
	}
341
342 2
	public static function warmupCache($className, $condition = '', $included = false, $parameters = [ ]) {
343 2
		$objects = self::getAll ( $className, $condition, $included, $parameters );
344 2
		foreach ( $objects as $o ) {
345 2
			self::$cache->store ( $className, OrmUtils::getKeyValues ( $o ), $o );
346
		}
347 2
		self::$cache->optimize ();
348 2
		$offset = self::$modelsDatabase [$className] ?? 'default';
349 2
		$db = self::$db [$offset];
350 2
		$db->close ();
351 2
		unset ( self::$db [$offset] );
352 2
	}
353
354 2
	public static function setCache(AbstractDAOCache $cache) {
355 2
		self::$cache = $cache;
356 2
	}
357
358
	/**
359
	 *
360
	 * @return \Ubiquity\cache\dao\AbstractDAOCache
361
	 */
362 63
	public static function getCache() {
363 63
		return static::$cache;
364
	}
365
}
366