| <?php |
|
|
| |
| |
| |
| |
| |
| |
|
|
| namespace Piwik\Plugins\DBStats; |
|
|
| use Exception; |
| use Piwik\Common; |
| use Piwik\DataTable; |
| use Piwik\DbHelper; |
| use Piwik\Option; |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| class MySQLMetadataProvider |
| { |
| |
| |
| |
| private $tableStatuses = null; |
|
|
| |
| |
| |
| public $dataAccess = null; |
|
|
| public function __construct(MySQLMetadataDataAccess $dataAccess) |
| { |
| $this->dataAccess = $dataAccess; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| public function getDBStatus() |
| { |
| return $this->dataAccess->getDBStatus(); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| public function getTableStatus($table) |
| { |
| $prefixed = Common::prefixTable($table); |
|
|
| |
| if (!is_null($this->tableStatuses) && isset($this->tableStatuses[$prefixed])) { |
| return $this->tableStatuses[$prefixed]; |
| } else { |
| return $this->dataAccess->getTableStatus($prefixed); |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| public function getAllTablesStatus($matchingRegex = null) |
| { |
| if (is_null($this->tableStatuses)) { |
| $tablesPiwik = DbHelper::getTablesInstalled(); |
|
|
| $this->tableStatuses = array(); |
| foreach ($this->dataAccess->getAllTablesStatus() as $t) { |
| if (in_array($t['Name'], $tablesPiwik)) { |
| $this->tableStatuses[$t['Name']] = $t; |
| } |
| } |
| } |
|
|
| if (is_null($matchingRegex)) { |
| return $this->tableStatuses; |
| } |
|
|
| $result = array(); |
| foreach ($this->tableStatuses as $status) { |
| if (preg_match($matchingRegex, $status['Name'])) { |
| $result[] = $status; |
| } |
| } |
| return $result; |
| } |
|
|
| |
| |
| |
| |
| |
| public function getAllLogTableStatus() |
| { |
| $regex = "/^" . Common::prefixTable('log_') . "(?!profiling)/"; |
| return $this->getAllTablesStatus($regex); |
| } |
|
|
| |
| |
| |
| |
| |
| public function getAllNumericArchiveStatus() |
| { |
| $regex = "/^" . Common::prefixTable('archive_numeric') . "_/"; |
| return $this->getAllTablesStatus($regex); |
| } |
|
|
| |
| |
| |
| |
| |
| public function getAllBlobArchiveStatus() |
| { |
| $regex = "/^" . Common::prefixTable('archive_blob') . "_/"; |
| return $this->getAllTablesStatus($regex); |
| } |
|
|
| |
| |
| |
| |
| |
| public function getAllAdminTableStatus() |
| { |
| $regex = "/^" . Common::prefixTable('') . "(?!archive_|(?:log_(?!profiling)))/"; |
| return $this->getAllTablesStatus($regex); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| public function getRowCountsAndSizeByBlobName($forceCache = false) |
| { |
| $extraSelects = array("SUM(OCTET_LENGTH(value)) AS 'blob_size'", "SUM(LENGTH(name)) AS 'name_size'"); |
| $extraCols = array('blob_size', 'name_size'); |
| return $this->getRowCountsByArchiveName( |
| $this->getAllBlobArchiveStatus(), |
| 'getEstimatedBlobArchiveRowSize', |
| $forceCache, |
| $extraSelects, |
| $extraCols |
| ); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| public function getRowCountsAndSizeByMetricName($forceCache = false) |
| { |
| return $this->getRowCountsByArchiveName( |
| $this->getAllNumericArchiveStatus(), |
| 'getEstimatedRowsSize', |
| $forceCache |
| ); |
| } |
|
|
| |
| |
| |
| |
| private function getRowCountsByArchiveName( |
| $statuses, |
| $getRowSizeMethod, |
| $forceCache = false, |
| $otherSelects = array(), |
| $otherDataTableColumns = array() |
| ) { |
| $extraCols = ''; |
| if (!empty($otherSelects)) { |
| $extraCols = ', ' . implode(', ', $otherSelects); |
| } |
|
|
| $cols = array_merge(array('row_count'), $otherDataTableColumns); |
|
|
| $dataTable = new DataTable(); |
| foreach ($statuses as $status) { |
| $dataTableOptionName = $this->getCachedOptionName($status['Name'], 'byArchiveName'); |
|
|
| |
| $cachedData = Option::get($dataTableOptionName); |
| if ($cachedData !== false && !$forceCache) { |
| $table = DataTable::fromSerializedArray($cachedData); |
| } else { |
| $table = new DataTable(); |
| $table->addRowsFromSimpleArray($this->dataAccess->getRowCountsByArchiveName($status['Name'], $extraCols)); |
|
|
| $reduceArchiveRowName = array($this, 'reduceArchiveRowName'); |
| $table->filter('GroupBy', array('label', $reduceArchiveRowName)); |
|
|
| $serializedTables = $table->getSerialized(); |
| $serializedTable = reset($serializedTables); |
| Option::set($dataTableOptionName, $serializedTable); |
| } |
|
|
| |
| $getEstimatedSize = array($this, $getRowSizeMethod); |
| $table->filter( |
| 'ColumnCallbackAddColumn', |
| array($cols, 'estimated_size', $getEstimatedSize, array($status)) |
| ); |
|
|
| $dataTable->addDataTable($table); |
| } |
| return $dataTable; |
| } |
|
|
| |
| |
| |
| public function getEstimatedRowsSize($row_count, $status) |
| { |
| if ($status['Rows'] == 0) { |
| return 0; |
| } |
| $avgRowSize = ($status['Data_length'] + $status['Index_length']) / $status['Rows']; |
| return $avgRowSize * $row_count; |
| } |
|
|
| |
| |
| |
| |
| |
| public function getEstimatedBlobArchiveRowSize($row_count, $blob_size, $name_size, $status) |
| { |
| |
| static $fixedSizeColumnLength = null; |
| if (is_null($fixedSizeColumnLength)) { |
| $fixedSizeColumnLength = 0; |
| foreach ($this->dataAccess->getColumnsFromTable($status['Name']) as $column) { |
| $columnType = $column['Type']; |
|
|
| if (($paren = strpos($columnType, '(')) !== false) { |
| $columnType = substr($columnType, 0, $paren); |
| } |
|
|
| $fixedSizeColumnLength += $this->getSizeOfDatabaseType($columnType); |
| } |
| } |
| |
| if ($status['Rows'] == 0) { |
| $avgRowSize = 0; |
| } else { |
| $avgRowSize = $status['Index_length'] / $status['Rows'] + $fixedSizeColumnLength; |
| } |
|
|
| |
| return $avgRowSize * $row_count + $blob_size + $name_size; |
| } |
|
|
| |
| private function getSizeOfDatabaseType($columnType) |
| { |
| switch (strtolower($columnType)) { |
| case "tinyint": |
| case "year": |
| return 1; |
| case "smallint": |
| return 2; |
| case "mediumint": |
| case "date": |
| case "time": |
| return 3; |
| case "int": |
| case "float": |
| case "timestamp": |
| return 4; |
| case "bigint": |
| case "double": |
| case "real": |
| case "datetime": |
| return 8; |
| default: |
| return 0; |
| } |
| } |
|
|
| |
| |
| |
| private function getCachedOptionName($tableName, $suffix) |
| { |
| return 'dbstats_cached_' . $tableName . '_' . $suffix; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| public function reduceArchiveRowName($name) |
| { |
| |
| if (strpos($name, 'done') === 0) { |
| return 'done'; |
| } |
|
|
| |
| if (preg_match("/^Goal_(?:-?[0-9]+_)?(.*)/", $name, $matches)) { |
| $name = "Goal_*_" . $matches[1]; |
| } |
|
|
| |
| if (preg_match("/^(.*)_[0-9]+$/", $name, $matches)) { |
| $name = $matches[1] . "_*"; |
| } |
|
|
| return $name; |
| } |
|
|
| |
| |
| |
| public function clearStatusCache() |
| { |
| $this->tableStatuses = null; |
| } |
| } |
|
|