diff options
Diffstat (limited to 'srcs/phpmyadmin/libraries/classes/Partition.php')
| -rw-r--r-- | srcs/phpmyadmin/libraries/classes/Partition.php | 270 |
1 files changed, 270 insertions, 0 deletions
diff --git a/srcs/phpmyadmin/libraries/classes/Partition.php b/srcs/phpmyadmin/libraries/classes/Partition.php new file mode 100644 index 0000000..6727fad --- /dev/null +++ b/srcs/phpmyadmin/libraries/classes/Partition.php @@ -0,0 +1,270 @@ +<?php +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + * Library for extracting information about the partitions + * + * @package PhpMyAdmin + */ +declare(strict_types=1); + +namespace PhpMyAdmin; + +use PhpMyAdmin\SubPartition; + +/** + * base Partition Class + * + * @package PhpMyAdmin + */ +class Partition extends SubPartition +{ + /** + * @var string partition description + */ + protected $description; + /** + * @var SubPartition[] sub partitions + */ + protected $subPartitions = []; + + /** + * Loads data from the fetched row from information_schema.PARTITIONS + * + * @param array $row fetched row + * + * @return void + */ + protected function loadData(array $row) + { + $this->name = $row['PARTITION_NAME']; + $this->ordinal = $row['PARTITION_ORDINAL_POSITION']; + $this->method = $row['PARTITION_METHOD']; + $this->expression = $row['PARTITION_EXPRESSION']; + $this->description = $row['PARTITION_DESCRIPTION']; + // no sub partitions, load all data to this object + if (empty($row['SUBPARTITION_NAME'])) { + $this->loadCommonData($row); + } + } + + /** + * Returns the partiotion description + * + * @return string partition description + */ + public function getDescription() + { + return $this->description; + } + + /** + * Add a sub partition + * + * @param SubPartition $partition Sub partition + * + * @return void + */ + public function addSubPartition(SubPartition $partition) + { + $this->subPartitions[] = $partition; + } + + /** + * Whether there are sub partitions + * + * @return boolean + */ + public function hasSubPartitions() + { + return ! empty($this->subPartitions); + } + + /** + * Returns the number of data rows + * + * @return integer number of rows + */ + public function getRows() + { + if (empty($this->subPartitions)) { + return $this->rows; + } + + $rows = 0; + foreach ($this->subPartitions as $subPartition) { + $rows += $subPartition->rows; + } + return $rows; + } + + /** + * Returns the total data length + * + * @return integer data length + */ + public function getDataLength() + { + if (empty($this->subPartitions)) { + return $this->dataLength; + } + + $dataLength = 0; + foreach ($this->subPartitions as $subPartition) { + $dataLength += $subPartition->dataLength; + } + return $dataLength; + } + + /** + * Returns the tatal index length + * + * @return integer index length + */ + public function getIndexLength() + { + if (empty($this->subPartitions)) { + return $this->indexLength; + } + + $indexLength = 0; + foreach ($this->subPartitions as $subPartition) { + $indexLength += $subPartition->indexLength; + } + return $indexLength; + } + + /** + * Returns the list of sub partitions + * + * @return SubPartition[] + */ + public function getSubPartitions() + { + return $this->subPartitions; + } + + /** + * Returns array of partitions for a specific db/table + * + * @param string $db database name + * @param string $table table name + * + * @access public + * @return Partition[] + */ + public static function getPartitions($db, $table) + { + if (Partition::havePartitioning()) { + $result = $GLOBALS['dbi']->fetchResult( + "SELECT * FROM `information_schema`.`PARTITIONS`" + . " WHERE `TABLE_SCHEMA` = '" . $GLOBALS['dbi']->escapeString($db) + . "' AND `TABLE_NAME` = '" . $GLOBALS['dbi']->escapeString($table) . "'" + ); + if ($result) { + $partitionMap = []; + foreach ($result as $row) { + if (isset($partitionMap[$row['PARTITION_NAME']])) { + $partition = $partitionMap[$row['PARTITION_NAME']]; + } else { + $partition = new Partition($row); + $partitionMap[$row['PARTITION_NAME']] = $partition; + } + + if (! empty($row['SUBPARTITION_NAME'])) { + $parentPartition = $partition; + $partition = new SubPartition($row); + $parentPartition->addSubPartition($partition); + } + } + return array_values($partitionMap); + } + return []; + } + + return []; + } + + /** + * returns array of partition names for a specific db/table + * + * @param string $db database name + * @param string $table table name + * + * @access public + * @return array of partition names + */ + public static function getPartitionNames($db, $table) + { + if (Partition::havePartitioning()) { + return $GLOBALS['dbi']->fetchResult( + "SELECT DISTINCT `PARTITION_NAME` FROM `information_schema`.`PARTITIONS`" + . " WHERE `TABLE_SCHEMA` = '" . $GLOBALS['dbi']->escapeString($db) + . "' AND `TABLE_NAME` = '" . $GLOBALS['dbi']->escapeString($table) . "'" + ); + } + + return []; + } + + /** + * returns the partition method used by the table. + * + * @param string $db database name + * @param string $table table name + * + * @return string|null partition method + */ + public static function getPartitionMethod($db, $table) + { + if (Partition::havePartitioning()) { + $partition_method = $GLOBALS['dbi']->fetchResult( + "SELECT `PARTITION_METHOD` FROM `information_schema`.`PARTITIONS`" + . " WHERE `TABLE_SCHEMA` = '" . $GLOBALS['dbi']->escapeString($db) . "'" + . " AND `TABLE_NAME` = '" . $GLOBALS['dbi']->escapeString($table) . "'" + . " LIMIT 1" + ); + if (! empty($partition_method)) { + return $partition_method[0]; + } + } + return null; + } + + /** + * checks if MySQL server supports partitioning + * + * @static + * @staticvar boolean $have_partitioning + * @staticvar boolean $already_checked + * @access public + * @return boolean + */ + public static function havePartitioning() + { + static $have_partitioning = false; + static $already_checked = false; + + if (! $already_checked) { + if ($GLOBALS['dbi']->getVersion() < 50600) { + if ($GLOBALS['dbi']->fetchValue( + "SELECT @@have_partitioning;" + )) { + $have_partitioning = true; + } + } elseif ($GLOBALS['dbi']->getVersion() >= 80000) { + $have_partitioning = true; + } else { + // see https://dev.mysql.com/doc/refman/5.6/en/partitioning.html + $plugins = $GLOBALS['dbi']->fetchResult("SHOW PLUGINS"); + foreach ($plugins as $value) { + if ($value['Name'] == 'partition') { + $have_partitioning = true; + break; + } + } + } + $already_checked = true; + } + return $have_partitioning; + } +} |
