Add DatabaseEditor::(getForeignKeys|getIndexInformation)()
authorMatthias Schmidt <gravatronics@live.com>
Tue, 6 Aug 2019 17:53:38 +0000 (19:53 +0200)
committerMatthias Schmidt <gravatronics@live.com>
Tue, 6 Aug 2019 17:53:38 +0000 (19:53 +0200)
wcfsetup/install/files/lib/system/database/editor/DatabaseEditor.class.php
wcfsetup/install/files/lib/system/database/editor/MySQLDatabaseEditor.class.php

index 3592bd0e9770da90444c109b759eca9dbec51f44..15eaf875c7960039c6d6d99c9fb7b88fd8e645de 100644 (file)
@@ -1,6 +1,7 @@
 <?php
 namespace wcf\system\database\editor;
 use wcf\system\database\Database;
+use wcf\system\exception\NotImplementedException;
 
 /**
  * Abstract implementation of a database editor.
@@ -42,13 +43,32 @@ abstract class DatabaseEditor {
        abstract public function getColumns($tableName);
        
        /**
-        * Returns the indices of a table.
+        * Returns information on the foreign keys of a table.
+        * 
+        * @return      array
+        */
+       public function getForeignKeys($tableName) {
+               throw new NotImplementedException();
+       }
+       
+       /**
+        * Returns the names of the indices of a table.
         * 
         * @param       string          $tableName
-        * @return      array           $indices
+        * @return      string[]        $indices
         */
        abstract public function getIndices($tableName);
        
+       /**
+        * Returns information on the indices of a table.
+        * 
+        * @param       string          $tableName
+        * @return      array
+        */
+       public function getIndexInformation($tableName) {
+               throw new NotImplementedException();
+       }
+       
        /**
         * Creates a new database table.
         * 
index 80b2cf98bcb1bab969a83d52400508f41dbdec21..0f22908e5e31a4f1c4436001865fe7aa0c22f21f 100644 (file)
@@ -52,6 +52,94 @@ class MySQLDatabaseEditor extends DatabaseEditor {
                return $columns;
        }
        
+       /**
+        * @inheritDoc
+        */
+       public function getForeignKeys($tableName) {
+               $sql = "SELECT          key_column_usage.CONSTRAINT_NAME,
+                                       key_column_usage.COLUMN_NAME,
+                                       key_column_usage.REFERENCED_TABLE_NAME,
+                                       key_column_usage.REFERENCED_COLUMN_NAME,
+                                       referential_constraints.DELETE_RULE,
+                                       referential_constraints.UPDATE_RULE
+                       FROM            INFORMATION_SCHEMA.KEY_COLUMN_USAGE key_column_usage
+                       INNER JOIN      INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS referential_constraints
+                       ON              (referential_constraints.CONSTRAINT_NAME = key_column_usage.CONSTRAINT_NAME
+                                       AND referential_constraints.CONSTRAINT_SCHEMA = key_column_usage.TABLE_SCHEMA
+                                       AND referential_constraints.TABLE_NAME = key_column_usage.TABLE_NAME)
+                       WHERE           key_column_usage.TABLE_SCHEMA = ?
+                                       AND key_column_usage.TABLE_NAME = ?";
+               $statement = $this->dbObj->prepareStatement($sql);
+               $statement->execute([
+                       $this->dbObj->getDatabaseName(),
+                       $tableName
+               ]);
+               $keyInformation = $statement->fetchAll(\PDO::FETCH_ASSOC);
+               
+               $validActions = ['CASCADE', 'SET NULL', 'NO ACTION'];
+               
+               $foreignKeys = [];
+               foreach ($keyInformation as $information) {
+                       if (!isset($foreignKeys[$information['CONSTRAINT_NAME']])) {
+                               $foreignKeys[$information['CONSTRAINT_NAME']] = [
+                                       'columns' => [$information['COLUMN_NAME']],
+                                       'referencedColumns' => [$information['REFERENCED_COLUMN_NAME']],
+                                       'referencedTable' => $information['REFERENCED_TABLE_NAME'],
+                                       'ON DELETE' => in_array($information['DELETE_RULE'], $validActions) ? $information['DELETE_RULE'] : null,
+                                       'ON UPDATE' => in_array($information['UPDATE_RULE'], $validActions) ? $information['UPDATE_RULE'] : null
+                               ];
+                       }
+                       else {
+                               $foreignKeys[$information['CONSTRAINT_NAME']]['columns'][] = $information['COLUMN_NAME'];
+                               $foreignKeys[$information['CONSTRAINT_NAME']]['referencedColumns'][] = $information['REFERENCED_COLUMN_NAME'];
+                       }
+               }
+               
+               foreach ($foreignKeys as $keyName => $keyData) {
+                       $foreignKeys[$keyName]['columns'] = array_unique($foreignKeys[$keyName]['columns']);
+                       $foreignKeys[$keyName]['referencedColumns'] = array_unique($foreignKeys[$keyName]['referencedColumns']);
+               }
+               
+               return $foreignKeys;
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function getIndexInformation($tableName) {
+               $sql = "SHOW    INDEX
+                       FROM    `".$tableName."`";
+               $statement = $this->dbObj->prepareStatement($sql);
+               $statement->execute();
+               $indices = $statement->fetchAll(\PDO::FETCH_ASSOC);
+               
+               $indexInformation = [];
+               foreach ($indices as $index) {
+                       if (!isset($indexInformation[$index['Key_name']])) {
+                               $type = null;
+                               if ($index['Index_type'] === 'FULLTEXT') {
+                                       $type = 'FULLTEXT';
+                               }
+                               else if ($index['Key_name'] === 'PRIMARY') {
+                                       $type = 'PRIMARY';
+                               }
+                               else if ($index['Non_unique'] == 0) {
+                                       $type = 'UNIQUE';
+                               }
+                               
+                               $indexInformation[$index['Key_name']] = [
+                                       'columns' => [$index['Column_name']],
+                                       'type' => $type
+                               ];
+                       }
+                       else {
+                               $indexInformation[$index['Key_name']]['columns'][] = $index['Column_name'];
+                       }
+               }
+               
+               return $indexInformation;
+       }
+       
        /**
         * @inheritDoc
         */