YetiForceCompany /
YetiForceCRM
This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
| 1 | <?php |
||||||
| 2 | |||||||
| 3 | namespace App; |
||||||
| 4 | |||||||
| 5 | /** |
||||||
| 6 | * Database connection class. |
||||||
| 7 | * |
||||||
| 8 | * @package App |
||||||
| 9 | * |
||||||
| 10 | * @copyright YetiForce S.A. |
||||||
| 11 | * @license YetiForce Public License 6.5 (licenses/LicenseEN.txt or yetiforce.com) |
||||||
| 12 | * @author Mariusz Krzaczkowski <[email protected]> |
||||||
| 13 | * @author Radosław Skrzypczak <[email protected]> |
||||||
| 14 | */ |
||||||
| 15 | class Db extends \yii\db\Connection |
||||||
| 16 | { |
||||||
| 17 | /** |
||||||
| 18 | * Sorting order flag. |
||||||
| 19 | */ |
||||||
| 20 | public const ASC = 'ASC'; |
||||||
| 21 | |||||||
| 22 | /** |
||||||
| 23 | * Sorting order flag. |
||||||
| 24 | */ |
||||||
| 25 | public const DESC = 'DESC'; |
||||||
| 26 | |||||||
| 27 | /** |
||||||
| 28 | * @var bool whether to turn on prepare emulation. Defaults to false, meaning PDO |
||||||
| 29 | * will use the native prepare support if available. For some databases (such as MySQL), |
||||||
| 30 | * this may need to be set true so that PDO can emulate the prepare support to bypass |
||||||
| 31 | * the buggy native prepare support. |
||||||
| 32 | * The default value is null, which means the PDO ATTR_EMULATE_PREPARES value will not be changed |
||||||
| 33 | */ |
||||||
| 34 | public $emulatePrepare = false; |
||||||
| 35 | |||||||
| 36 | /** |
||||||
| 37 | * @var \App\Db Table of connections with database |
||||||
| 38 | */ |
||||||
| 39 | private static $cache = []; |
||||||
| 40 | |||||||
| 41 | /** |
||||||
| 42 | * @var array Configuration with database |
||||||
| 43 | */ |
||||||
| 44 | private static $config = []; |
||||||
| 45 | |||||||
| 46 | /** |
||||||
| 47 | * @var bool Enable caching database instance |
||||||
| 48 | */ |
||||||
| 49 | public static $connectCache = false; |
||||||
| 50 | |||||||
| 51 | /** |
||||||
| 52 | * @var string Database Name |
||||||
| 53 | */ |
||||||
| 54 | public $dbName; |
||||||
| 55 | |||||||
| 56 | /** |
||||||
| 57 | * @var string Database section |
||||||
| 58 | */ |
||||||
| 59 | public $dbType; |
||||||
| 60 | |||||||
| 61 | /** |
||||||
| 62 | * @var string Host database server |
||||||
| 63 | */ |
||||||
| 64 | public $host; |
||||||
| 65 | |||||||
| 66 | /** |
||||||
| 67 | * @var int Port database server |
||||||
| 68 | */ |
||||||
| 69 | public $port; |
||||||
| 70 | |||||||
| 71 | /** {@inheritdoc} */ |
||||||
| 72 | public $schemaMap = [ |
||||||
| 73 | 'pgsql' => 'App\Db\Drivers\Pgsql\Schema', // PostgreSQL |
||||||
| 74 | 'mysqli' => 'yii\db\mysql\Schema', // MySQL |
||||||
| 75 | 'mysql' => 'App\Db\Drivers\Mysql\Schema', // MySQL |
||||||
| 76 | 'sqlite' => 'yii\db\sqlite\Schema', // sqlite 3 |
||||||
| 77 | 'sqlite2' => 'yii\db\sqlite\Schema', // sqlite 2 |
||||||
| 78 | 'sqlsrv' => 'yii\db\mssql\Schema', // newer MSSQL driver on MS Windows hosts |
||||||
| 79 | 'oci' => 'yii\db\oci\Schema', // Oracle driver |
||||||
| 80 | 'mssql' => 'yii\db\mssql\Schema', // older MSSQL driver on MS Windows hosts |
||||||
| 81 | 'dblib' => 'yii\db\mssql\Schema', // dblib drivers on GNU/Linux (and maybe other OSes) hosts |
||||||
| 82 | 'cubrid' => 'yii\db\cubrid\Schema', // CUBRID |
||||||
| 83 | ]; |
||||||
| 84 | |||||||
| 85 | /** |
||||||
| 86 | * @var string the class used to create new database [[Command]] objects. If you want to extend the [[Command]] class, |
||||||
| 87 | * you may configure this property to use your extended version of the class |
||||||
| 88 | */ |
||||||
| 89 | public $commandClass = '\App\Db\Command'; |
||||||
| 90 | |||||||
| 91 | /** |
||||||
| 92 | * @var Cache|string the cache object or the ID of the cache application component that |
||||||
| 93 | * is used to cache the table metadata |
||||||
| 94 | * |
||||||
| 95 | 6356 | * @see enableSchemaCache |
|||||
| 96 | */ |
||||||
| 97 | 6356 | public $schemaCache = false; |
|||||
| 98 | 6356 | ||||||
| 99 | /** |
||||||
| 100 | 3 | * Creates the Db connection instance. |
|||||
| 101 | 3 | * |
|||||
| 102 | 3 | * @param string $type Name of database connection |
|||||
| 103 | 3 | * |
|||||
| 104 | * @return \App\Db |
||||||
| 105 | */ |
||||||
| 106 | public static function getInstance($type = 'base') |
||||||
| 107 | { |
||||||
| 108 | if (isset(self::$cache[$type])) { |
||||||
| 109 | return self::$cache[$type]; |
||||||
| 110 | } |
||||||
| 111 | $db = new self(self::getConfig($type)); |
||||||
| 112 | $db->dbType = $type; |
||||||
| 113 | 4 | self::$cache[$type] = $db; |
|||||
| 114 | return $db; |
||||||
| 115 | 4 | } |
|||||
| 116 | 3 | ||||||
| 117 | /** |
||||||
| 118 | 4 | * Load database connection configuration. |
|||||
| 119 | * |
||||||
| 120 | * @param string $type |
||||||
| 121 | * |
||||||
| 122 | * @return array with database configuration |
||||||
| 123 | */ |
||||||
| 124 | public static function getConfig(string $type) |
||||||
| 125 | { |
||||||
| 126 | if (!isset(self::$config[$type])) { |
||||||
| 127 | self::$config[$type] = Config::db($type) ?? Config::db('base'); |
||||||
| 128 | } |
||||||
| 129 | return self::$config[$type]; |
||||||
| 130 | } |
||||||
| 131 | |||||||
| 132 | /** |
||||||
| 133 | * Set database connection configuration. |
||||||
| 134 | * |
||||||
| 135 | * @param array $config |
||||||
| 136 | * @param string $type |
||||||
| 137 | 2 | */ |
|||||
| 138 | public static function setConfig($config, $type = 'base') |
||||||
| 139 | 2 | { |
|||||
| 140 | 2 | self::$config[$type] = $config; |
|||||
| 141 | 2 | } |
|||||
| 142 | 2 | ||||||
| 143 | 2 | /** |
|||||
| 144 | 2 | * Get info database server. |
|||||
| 145 | 2 | * |
|||||
| 146 | * @return array |
||||||
| 147 | */ |
||||||
| 148 | 2 | public function getInfo() |
|||||
| 149 | { |
||||||
| 150 | $pdo = $this->getSlavePdo(); |
||||||
| 151 | 2 | $statement = $pdo->prepare('SHOW VARIABLES'); |
|||||
| 152 | 2 | $statement->execute(); |
|||||
| 153 | 2 | $conf = $statement->fetchAll(\PDO::FETCH_KEY_PAIR); |
|||||
| 154 | 2 | $statement = $pdo->prepare('SHOW STATUS'); |
|||||
| 155 | 2 | $statement->execute(); |
|||||
| 156 | 2 | $conf = array_merge($conf, $statement->fetchAll(\PDO::FETCH_KEY_PAIR)); |
|||||
| 157 | 2 | $statement = $pdo->prepare('SELECT VERSION()'); |
|||||
| 158 | $statement->execute(); |
||||||
| 159 | $fullVersion = $statement->fetch(\PDO::FETCH_COLUMN); |
||||||
| 160 | [$version] = explode('-', $conf['version']); |
||||||
| 161 | $conf['version_comment'] = $conf['version_comment'] . '|' . $fullVersion; |
||||||
| 162 | $typeDb = 'MySQL'; |
||||||
| 163 | if (false !== stripos($conf['version_comment'], 'MariaDb')) { |
||||||
| 164 | $typeDb = 'MariaDb'; |
||||||
| 165 | } |
||||||
| 166 | $memory = $conf['key_buffer_size'] + ($conf['query_cache_size'] ?? 0) + $conf['tmp_table_size'] + $conf['innodb_buffer_pool_size'] + |
||||||
| 167 | ($conf['innodb_additional_mem_pool_size'] ?? 0) + $conf['innodb_log_buffer_size'] + ($conf['max_connections'] * ($conf['sort_buffer_size'] |
||||||
| 168 | + $conf['read_buffer_size'] + $conf['read_rnd_buffer_size'] + $conf['join_buffer_size'] + $conf['thread_stack'] + $conf['binlog_cache_size'])); |
||||||
| 169 | return \array_merge($conf, [ |
||||||
| 170 | 'driver' => $this->getDriverName(), |
||||||
| 171 | 'typeDb' => $typeDb, |
||||||
| 172 | 6352 | 'serverVersion' => $version, |
|||||
| 173 | 'maximumMemorySize' => $memory, |
||||||
| 174 | 6352 | 'clientVersion' => $pdo->getAttribute(\PDO::ATTR_CLIENT_VERSION), |
|||||
| 175 | 'connectionStatus' => $pdo->getAttribute(\PDO::ATTR_CONNECTION_STATUS), |
||||||
| 176 | 'serverInfo' => $pdo->getAttribute(\PDO::ATTR_SERVER_INFO), |
||||||
| 177 | ]); |
||||||
| 178 | } |
||||||
| 179 | |||||||
| 180 | /** |
||||||
| 181 | * Get database info. |
||||||
| 182 | * |
||||||
| 183 | * @return array |
||||||
| 184 | */ |
||||||
| 185 | public function getDbInfo(): array |
||||||
| 186 | 75 | { |
|||||
| 187 | $return = [ |
||||||
| 188 | 75 | 'isFileSize' => false, |
|||||
| 189 | 'size' => 0, |
||||||
| 190 | 'dataSize' => 0, |
||||||
| 191 | 'indexSize' => 0, |
||||||
| 192 | 'filesSize' => 0, |
||||||
| 193 | 'tables' => [], |
||||||
| 194 | ]; |
||||||
| 195 | $statement = $this->getSlavePdo()->prepare("SHOW TABLE STATUS FROM `{$this->dbName}`"); |
||||||
| 196 | $statement->execute(); |
||||||
| 197 | while ($row = $statement->fetch(\PDO::FETCH_ASSOC)) { |
||||||
| 198 | $return['tables'][$row['Name']] = [ |
||||||
| 199 | 3 | 'rows' => $row['Rows'], |
|||||
| 200 | 'format' => $row['Row_format'], |
||||||
| 201 | 3 | 'engine' => $row['Engine'], |
|||||
| 202 | 'dataSize' => $row['Data_length'], |
||||||
| 203 | 'indexSize' => $row['Index_length'], |
||||||
| 204 | 'collation' => $row['Collation'], |
||||||
| 205 | ]; |
||||||
| 206 | $return['dataSize'] += $row['Data_length']; |
||||||
| 207 | 3 | $return['indexSize'] += $row['Index_length']; |
|||||
| 208 | $return['size'] += $row['Data_length'] += $row['Index_length']; |
||||||
| 209 | } |
||||||
| 210 | try { |
||||||
| 211 | $statement = $this->getSlavePdo()->prepare("SELECT * FROM `information_schema`.`INNODB_SYS_TABLESPACES` WHERE `NAME` LIKE '{$this->dbName}/%'"); |
||||||
| 212 | $statement->execute(); |
||||||
| 213 | while ($row = $statement->fetch(\PDO::FETCH_ASSOC)) { |
||||||
| 214 | $tableName = str_replace($this->dbName . '/', '', $row['NAME']); |
||||||
| 215 | if (!empty($row['ALLOCATED_SIZE'])) { |
||||||
| 216 | if (isset($return['tables'][$tableName])) { |
||||||
| 217 | $return['tables'][$tableName]['fileSize'] = $row['ALLOCATED_SIZE']; |
||||||
| 218 | $return['isFileSize'] = true; |
||||||
| 219 | 11 | } |
|||||
| 220 | $return['filesSize'] += $row['ALLOCATED_SIZE']; |
||||||
| 221 | 11 | } |
|||||
| 222 | 7 | } |
|||||
| 223 | 7 | } catch (\Throwable $th) { |
|||||
|
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
Loading history...
|
|||||||
| 224 | 7 | } |
|||||
| 225 | 7 | return $return; |
|||||
| 226 | 7 | } |
|||||
| 227 | 7 | ||||||
| 228 | /** |
||||||
| 229 | 4 | * Processes a SQL statement by quoting table and column names that are enclosed within double brackets. |
|||||
| 230 | 4 | * Tokens enclosed within double curly brackets are treated as table names, while |
|||||
| 231 | 4 | * tokens enclosed within double square brackets are column names. They will be quoted accordingly. |
|||||
| 232 | 4 | * Also, the percentage character "%" at the beginning or ending of a table name will be replaced |
|||||
| 233 | * with [[tablePrefix]]. |
||||||
| 234 | 11 | * |
|||||
| 235 | * @param string $sql the SQL to be quoted |
||||||
| 236 | * |
||||||
| 237 | * @return string the quoted SQL |
||||||
| 238 | */ |
||||||
| 239 | public function quoteSql($sql) |
||||||
| 240 | { |
||||||
| 241 | return str_replace('#__', $this->tablePrefix, $sql); |
||||||
| 242 | } |
||||||
| 243 | |||||||
| 244 | 10 | /** |
|||||
| 245 | * Returns the ID of the last inserted row or sequence value. |
||||||
| 246 | 10 | * |
|||||
| 247 | * @param string $sequenceName name of the sequence object (required by some DBMS) ex. table vtiger_picklist >>> vtiger_picklist_picklistid_seq |
||||||
| 248 | * |
||||||
| 249 | * @return string the row ID of the last row inserted, or the last value retrieved from the sequence object |
||||||
| 250 | * |
||||||
| 251 | * @see https://www.php.net/manual/en/function.PDO-lastInsertId.php |
||||||
| 252 | */ |
||||||
| 253 | public function getLastInsertID($sequenceName = '') |
||||||
| 254 | { |
||||||
| 255 | return parent::getLastInsertID(str_replace('#__', $this->tablePrefix, $sequenceName)); |
||||||
| 256 | } |
||||||
| 257 | 4 | ||||||
| 258 | /** |
||||||
| 259 | 4 | * Creates the PDO instance. |
|||||
| 260 | 4 | * This method is called by [[open]] to establish a DB connection. |
|||||
| 261 | 4 | * The default implementation will create a PHP PDO instance. |
|||||
| 262 | * You may override this method if the default PDO needs to be adapted for certain DBMS. |
||||||
| 263 | 4 | * |
|||||
| 264 | 4 | * @return PDO the pdo instance |
|||||
|
0 ignored issues
–
show
|
|||||||
| 265 | */ |
||||||
| 266 | protected function createPdoInstance() |
||||||
| 267 | { |
||||||
| 268 | if (Debuger::isDebugBar()) { |
||||||
| 269 | $bebugBar = Debuger::getDebugBar(); |
||||||
| 270 | $pdo = new Debug\DebugBar\TraceablePDO(parent::createPdoInstance()); |
||||||
| 271 | if ($bebugBar->hasCollector('pdo')) { |
||||||
| 272 | $pdoCollector = $bebugBar->getCollector('pdo'); |
||||||
| 273 | $pdoCollector->addConnection($pdo, $this->dbType); |
||||||
|
0 ignored issues
–
show
The method
addConnection() does not exist on DebugBar\DataCollector\DataCollectorInterface. It seems like you code against a sub-type of DebugBar\DataCollector\DataCollectorInterface such as DebugBar\DataCollector\PDO\PDOCollector.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
| 274 | } else { |
||||||
| 275 | $pdoCollector = new \DebugBar\DataCollector\PDO\PDOCollector(); |
||||||
| 276 | $pdoCollector->addConnection($pdo, $this->dbType); |
||||||
| 277 | $bebugBar->addCollector($pdoCollector); |
||||||
| 278 | } |
||||||
| 279 | return $pdo; |
||||||
|
0 ignored issues
–
show
|
|||||||
| 280 | } |
||||||
| 281 | return parent::createPdoInstance(); |
||||||
|
0 ignored issues
–
show
|
|||||||
| 282 | } |
||||||
| 283 | |||||||
| 284 | /** |
||||||
| 285 | * Get table unique ID. Temporary function. |
||||||
| 286 | * |
||||||
| 287 | * @param string $tableName |
||||||
| 288 | * @param false|string $columnName |
||||||
| 289 | * @param bool $seq |
||||||
| 290 | * |
||||||
| 291 | * @return int |
||||||
| 292 | */ |
||||||
| 293 | public function getUniqueID($tableName, $columnName = false, $seq = true) |
||||||
| 294 | { |
||||||
| 295 | if ($seq) { |
||||||
| 296 | $tableName .= '_seq'; |
||||||
| 297 | $id = (new \App\Db\Query())->from($tableName)->scalar($this); |
||||||
| 298 | ++$id; |
||||||
| 299 | $this->createCommand()->update($tableName, [ |
||||||
| 300 | 'id' => $id, |
||||||
| 301 | ])->execute(); |
||||||
| 302 | } else { |
||||||
| 303 | $id = (new \App\Db\Query()) |
||||||
| 304 | ->from($tableName) |
||||||
| 305 | ->max($columnName, $this); |
||||||
| 306 | ++$id; |
||||||
| 307 | } |
||||||
| 308 | return $id; |
||||||
|
0 ignored issues
–
show
|
|||||||
| 309 | } |
||||||
| 310 | |||||||
| 311 | /** |
||||||
| 312 | * Check if table is present in database. |
||||||
| 313 | * |
||||||
| 314 | * @param string $tableName |
||||||
| 315 | * |
||||||
| 316 | * @return bool |
||||||
| 317 | */ |
||||||
| 318 | public function isTableExists($tableName) |
||||||
| 319 | { |
||||||
| 320 | return \in_array(str_replace('#__', $this->tablePrefix, $tableName), $this->getSchema()->getTableNames()); |
||||||
| 321 | } |
||||||
| 322 | |||||||
| 323 | /** |
||||||
| 324 | * Creating a new DB table. |
||||||
| 325 | * |
||||||
| 326 | * @param string $tableName |
||||||
| 327 | * @param mixed $columns |
||||||
| 328 | * |
||||||
| 329 | * @return bool |
||||||
| 330 | */ |
||||||
| 331 | public function createTable($tableName, $columns) |
||||||
| 332 | { |
||||||
| 333 | $tableOptions = null; |
||||||
| 334 | if ('mysql' === $this->getDriverName()) { |
||||||
| 335 | $tableOptions = 'CHARACTER SET utf8 ENGINE=InnoDB'; |
||||||
| 336 | } |
||||||
| 337 | $this->createCommand()->createTable($tableName, $columns, $tableOptions)->execute(); |
||||||
| 338 | } |
||||||
| 339 | |||||||
| 340 | /** |
||||||
| 341 | * Get table keys. |
||||||
| 342 | * |
||||||
| 343 | * @param string $tableName |
||||||
| 344 | * |
||||||
| 345 | * @return array |
||||||
| 346 | */ |
||||||
| 347 | public function getTableKeys($tableName) |
||||||
| 348 | { |
||||||
| 349 | if (Cache::has('getTableKeys', $tableName)) { |
||||||
| 350 | return Cache::get('getTableKeys', $tableName); |
||||||
| 351 | } |
||||||
| 352 | if (!$this->isTableExists($tableName)) { |
||||||
| 353 | return []; |
||||||
| 354 | } |
||||||
| 355 | $tableName = $this->quoteTableName(str_replace('#__', $this->tablePrefix, $tableName)); |
||||||
| 356 | $keys = []; |
||||||
| 357 | if ('mysql' === $this->getDriverName()) { |
||||||
| 358 | $dataReader = $this->createCommand()->setSql('SHOW KEYS FROM ' . $tableName)->query(); |
||||||
| 359 | while ($row = $dataReader->read()) { |
||||||
| 360 | $keys[$row['Key_name']][$row['Column_name']] = ['columnName' => $row['Column_name'], 'unique' => empty($row['Non_unique'])]; |
||||||
| 361 | } |
||||||
| 362 | } |
||||||
| 363 | Cache::save('getTableKeys', $tableName, $keys, Cache::LONG); |
||||||
| 364 | return $keys; |
||||||
| 365 | } |
||||||
| 366 | |||||||
| 367 | /** |
||||||
| 368 | * Get table primary keys. |
||||||
| 369 | * |
||||||
| 370 | * @param type $tableName |
||||||
|
0 ignored issues
–
show
The type
App\type was not found. Maybe you did not declare it correctly or list all dependencies?
The issue could also be caused by a filter entry in the build configuration.
If the path has been excluded in your configuration, e.g. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths Loading history...
|
|||||||
| 371 | * |
||||||
| 372 | * @return type |
||||||
| 373 | */ |
||||||
| 374 | public function getPrimaryKey($tableName) |
||||||
| 375 | { |
||||||
| 376 | if (Cache::has('getPrimaryKey', $tableName)) { |
||||||
| 377 | return Cache::get('getPrimaryKey', $tableName); |
||||||
| 378 | } |
||||||
| 379 | $key = []; |
||||||
| 380 | if ('mysql' === $this->getDriverName()) { |
||||||
| 381 | $tableKeys = $this->getTableKeys($tableName); |
||||||
| 382 | $key = isset($tableKeys['PRIMARY']) ? ['PRIMARY' => array_keys($tableKeys['PRIMARY'])] : []; |
||||||
| 383 | } |
||||||
| 384 | Cache::save('getPrimaryKey', $tableName, $key, Cache::LONG); |
||||||
| 385 | return $key; |
||||||
|
0 ignored issues
–
show
|
|||||||
| 386 | } |
||||||
| 387 | } |
||||||
| 388 |