Passed
Push — master ( f5da16...2e3bf1 )
by Jean-Christophe
12:28
created

DAO::getRownum()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 2.003

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 11
dl 0
loc 13
ccs 10
cts 11
cp 0.9091
rs 9.9
c 1
b 0
f 0
cc 2
nc 2
nop 2
crap 2.003
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
		}
90
		return static::_getAll ( $db, $className, new ConditionParser ( $nCondition, null, $keyValues ), $included, $useCache );
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $nCondition does not seem to be defined for all execution paths leading up to this point.
Loading history...
91
	}
92
93 4
	public static function paginate($className, $page = 1, $rowsPerPage = 20, $condition = null, $included = true) {
94 4
		return self::getAll ( $className, ($condition ?? '1=1') . ' LIMIT ' . $rowsPerPage . ' OFFSET ' . (($page - 1) * $rowsPerPage), $included );
95
	}
96
97 4
	public static function getRownum($className, $ids) {
98 4
		$tableName = OrmUtils::getTableName ( $className );
99 4
		$db = self::getDb ( $className );
100 4
		$quote = $db->quote;
101 4
		self::parseKey ( $ids, $className, $quote );
102 4
		$condition = SqlUtils::getCondition ( $ids, $className );
103 4
		$keyFields = OrmUtils::getKeyFields ( $className );
104 4
		if (\is_array ( $keyFields )) {
105 4
			$keys = \implode ( ',', $keyFields );
106
		} else {
107
			$keys = '1';
108
		}
109 4
		return $db->getRowNum ( $tableName, $keys, $condition );
110
	}
111
112
	/**
113
	 * Returns the number of objects of $className from the database respecting the condition possibly passed as parameter
114
	 *
115
	 * @param string $className complete classname of the model to load
116
	 * @param string $condition Part following the WHERE of an SQL statement
117
	 * @param array|null $parameters The query parameters
118
	 * @return int|false count of objects
119
	 */
120 30
	public static function count($className, $condition = '', $parameters = null) {
121 30
		$tableName = OrmUtils::getTableName ( $className );
122 30
		if ($condition != '') {
123 9
			$condition = SqlUtils::checkWhere($condition);
124
		}
125 30
		$db = self::getDb ( $className );
126 30
		$quote = $db->quote;
127 30
		return $db->prepareAndFetchColumn ( 'SELECT COUNT(*) FROM ' . $quote . $tableName . $quote . $condition, $parameters );
128
	}
129
130
	/**
131
	 * Tests the existence of objects of $className from the database respecting the condition possibly passed as parameter
132
	 *
133
	 * @param string $className complete classname of the model to load
134
	 * @param string $condition Part following the WHERE of an SQL statement
135
	 * @param array|null $parameters The query parameters
136
	 * @return boolean
137
	 */
138 2
	public static function exists($className, $condition = '', $parameters = null) {
139 2
		$tableName = OrmUtils::getTableName ( $className );
140 2
		if ($condition != '') {
141 2
			$condition = SqlUtils::checkWhere($condition);
142
		}
143 2
		$db = self::getDb ( $className );
144 2
		$quote = $db->quote;
145 2
		return (1 == $db->prepareAndFetchColumn ( "SELECT EXISTS(SELECT 1 FROM {$quote}{$tableName}{$quote}{$condition})", $parameters ));
146
	}
147
148
	/**
149
	 * Returns an instance of $className from the database, from $keyvalues values of the primary key or with a condition
150
	 *
151
	 * @param String $className complete classname of the model to load
152
	 * @param Array|string $condition condition or primary key values
153
	 * @param boolean|array $included if true, charges associate members with association
154
	 * @param array|null $parameters the request parameters
155
	 * @param boolean|null $useCache use cache if true
156
	 * @return object the instance loaded or null if not found
157
	 */
158 26
	public static function getOne($className, $condition, $included = true, $parameters = null, $useCache = NULL) {
159 26
		$db = self::getDb ( $className );
160 26
		$conditionParser = new ConditionParser ();
161 26
		if (! isset ( $parameters )) {
162 25
			$conditionParser->addKeyValues ( $condition, $className );
163 3
		} elseif (! is_array ( $condition )) {
164 3
			$conditionParser->setCondition ( $condition );
165 3
			$conditionParser->setParams ( $parameters );
166
		} else {
167
			throw new DAOException ( "The \$condition parameter should not be an array if \$parameters is not null" );
168
		}
169 26
		return static::_getOne ( $db, $className, $conditionParser, $included, $useCache );
170
	}
171
172
	/**
173
	 * Returns an instance of $className from the database, from $keyvalues values of the primary key
174
	 *
175
	 * @param String $className complete classname of the model to load
176
	 * @param Array|string $keyValues primary key values or condition
177
	 * @param boolean|array $included if true, charges associate members with association
178
	 * @param array|null $parameters the request parameters
179
	 * @param boolean|null $useCache use cache if true
180
	 * @return object the instance loaded or null if not found
181
	 */
182 31
	public static function getById($className, $keyValues, $included = true, $useCache = NULL) {
183 31
		return static::_getOne ( self::getDatabase ( self::$modelsDatabase [$className] ?? 'default'), $className, self::getConditionParser ( $className, $keyValues ), $included, $useCache );
184
	}
185
186 31
	protected static function getConditionParser($className, $keyValues): ConditionParser {
187 31
		if (! isset ( self::$conditionParsers [$className] )) {
188 14
			$conditionParser = new ConditionParser ();
189 14
			$conditionParser->addKeyValues ( $keyValues, $className );
190 14
			self::$conditionParsers [$className] = $conditionParser;
191
		} else {
192 20
			self::$conditionParsers [$className]->setKeyValues ( $keyValues );
193
		}
194 31
		return self::$conditionParsers [$className];
195
	}
196
197
	/**
198
	 * Establishes the connection to the database using the past parameters
199
	 *
200
	 * @param string $offset
201
	 * @param string $wrapper
202
	 * @param string $dbType
203
	 * @param string $dbName
204
	 * @param string $serverName
205
	 * @param string $port
206
	 * @param string $user
207
	 * @param string $password
208
	 * @param array $options
209
	 * @param boolean $cache
210
	 */
211 118
	public static function connect($offset, $wrapper, $dbType, $dbName, $serverName = '127.0.0.1', $port = '3306', $user = 'root', $password = '', $options = [ ], $cache = false) {
212 118
		self::$db [$offset] = new Database ( $wrapper, $dbType, $dbName, $serverName, $port, $user, $password, $options, $cache, self::$pool );
213
		try {
214 118
			self::$db [$offset]->connect ();
215
		} catch ( \Exception $e ) {
216
			Logger::error ( "DAO", $e->getMessage () );
217
			throw new DAOException ( $e->getMessage (), $e->getCode (), $e->getPrevious () );
218
		}
219 118
	}
220
221
	/**
222
	 * Establishes the connection to the database using the $config array
223
	 *
224
	 * @param array $config the config array (Startup::getConfig())
225
	 */
226 25
	public static function startDatabase(&$config, $offset = null) {
227 25
		$db = $offset ? ($config ['database'] [$offset] ?? ($config ['database'] ?? [ ])) : ($config ['database'] ['default'] ?? $config ['database']);
228 25
		if ($db ['dbName'] !== '') {
229 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);
230
		}
231 25
	}
232
233 190
	public static function getDbOffset(&$config, $offset = null) {
234 190
		return $offset ? ($config ['database'] [$offset] ?? ($config ['database'] ?? [ ])) : ($config ['database'] ['default'] ?? $config ['database']);
235
	}
236
237
	/**
238
	 * Returns true if the connection to the database is established
239
	 *
240
	 * @return boolean
241
	 */
242 8
	public static function isConnected($offset = 'default') {
243 8
		$db = self::$db [$offset] ?? false;
244 8
		return $db && ($db instanceof Database) && $db->isConnected ();
245
	}
246
247
	/**
248
	 * Sets the transformer operation
249
	 *
250
	 * @param string $op
251
	 */
252
	public static function setTransformerOp($op) {
253
		self::$transformerOp = $op;
254
	}
255
256
	/**
257
	 * Closes the active pdo connection to the database
258
	 */
259 71
	public static function closeDb($offset = 'default') {
260 71
		$db = self::$db [$offset] ?? false;
261 71
		if ($db !== false) {
262 70
			$db->close ();
263
		}
264 71
	}
265
266
	/**
267
	 * Defines the database connection to use for $model class
268
	 *
269
	 * @param string $model a model class
270
	 * @param string $database a database connection defined in config.php
271
	 */
272 10
	public static function setModelDatabase($model, $database = 'default') {
273 10
		self::$modelsDatabase [$model] = $database;
274 10
	}
275
276
	/**
277
	 * Defines the database connections to use for models classes
278
	 *
279
	 * @param array $modelsDatabase
280
	 */
281
	public static function setModelsDatabases($modelsDatabase) {
282
		self::$modelsDatabase = $modelsDatabase;
283
	}
284
285
	/**
286
	 * Returns the database instance defined at $offset key in config
287
	 *
288
	 * @param string $offset
289
	 * @return \Ubiquity\db\Database
290
	 */
291 122
	public static function getDatabase($offset = 'default') {
292 122
		if (! isset ( self::$db [$offset] )) {
293 17
			self::startDatabase ( Startup::$config, $offset );
294
		}
295 122
		SqlUtils::$quote = self::$db [$offset]->quote;
296 122
		return self::$db [$offset];
297
	}
298
299 6
	public static function getDatabases() {
300 6
		$config = Startup::getConfig ();
301 6
		if (isset ( $config ['database'] )) {
302 6
			if (isset ( $config ['database'] ['dbName'] )) {
303
				return [ 'default' ];
304
			} else {
305 6
				return \array_keys ( $config ['database'] );
306
			}
307
		}
308
		return [ ];
309
	}
310
311
	public static function updateDatabaseParams(array &$config, array $parameters, $offset = 'default') {
312
		if ($offset === 'default') {
313
			if (isset ( $config ['database'] [$offset] )) {
314
				foreach ( $parameters as $k => $param ) {
315
					$config ['database'] [$offset] [$k] = $param;
316
				}
317
			} else {
318
				foreach ( $parameters as $k => $param ) {
319
					$config ['database'] [$k] = $param;
320
				}
321
			}
322
		} else {
323
			if (isset ( $config ['database'] [$offset] )) {
324
				foreach ( $parameters as $k => $param ) {
325
					$config ['database'] [$offset] [$k] = $param;
326
				}
327
			}
328
		}
329
	}
330
331 39
	public static function start() {
332 39
		self::$modelsDatabase = CacheManager::getModelsDatabases ();
333 39
	}
334
335
	public static function getDbCacheInstance($model) {
336
		$db = static::$db [self::$modelsDatabase [$model] ?? 'default'];
337
		return $db->getCacheInstance ();
338
	}
339
340 2
	public static function warmupCache($className, $condition = '', $included = false, $parameters = [ ]) {
341 2
		$objects = self::getAll ( $className, $condition, $included, $parameters );
342 2
		foreach ( $objects as $o ) {
343 2
			self::$cache->store ( $className, OrmUtils::getKeyValues ( $o ), $o );
344
		}
345 2
		self::$cache->optimize ();
346 2
		$offset = self::$modelsDatabase [$className] ?? 'default';
347 2
		$db = self::$db [$offset];
348 2
		$db->close ();
349 2
		unset ( self::$db [$offset] );
350 2
	}
351
352 2
	public static function setCache(AbstractDAOCache $cache) {
353 2
		self::$cache = $cache;
354 2
	}
355
356
	/**
357
	 *
358
	 * @return \Ubiquity\cache\dao\AbstractDAOCache
359
	 */
360 63
	public static function getCache() {
361 63
		return static::$cache;
362
	}
363
}
364