aboutsummaryrefslogtreecommitdiff
path: root/srcs/phpmyadmin/libraries/classes/Partition.php
diff options
context:
space:
mode:
Diffstat (limited to 'srcs/phpmyadmin/libraries/classes/Partition.php')
-rw-r--r--srcs/phpmyadmin/libraries/classes/Partition.php270
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;
+ }
+}