Repository: codeigniter4/CodeIgniter4 (PHP)

Issue:
Dev: Database Forge should support dropping keys
I realized the other day that [Forge](https://codeigniter.com/user_guide/dbmgmt/forge.html) only supports dropping foreign keys. It should also be able to drop unique indexes, etc. 

Syntax would be much like the existing `->dropForeignKey()` method. 

Must work across all currently supported databases. 



Discussion:

Patch:
diff --git a/system/Database/Forge.php b/system/Database/Forge.php
index 501d2e3ade8d..8e0b7e43c7f3 100644
--- a/system/Database/Forge.php
+++ b/system/Database/Forge.php
@@ -167,6 +167,13 @@ class Forge
      */
     protected $dropConstraintStr;
 
+    /**
+     * DROP INDEX statement
+     *
+     * @var string
+     */
+    protected $dropIndexStr = 'DROP INDEX %s ON %s';
+
     /**
      * Constructor.
      */
@@ -421,6 +428,32 @@ public function addForeignKey($fieldName = '', string $tableName = '', $tableFie
         return $this;
     }
 
+    /**
+     * Drop Key
+     *
+     * @throws DatabaseException
+     *
+     * @return bool
+     */
+    public function dropKey(string $table, string $keyName)
+    {
+        $sql = sprintf(
+            $this->dropIndexStr,
+            $this->db->escapeIdentifiers($this->db->DBPrefix . $keyName),
+            $this->db->escapeIdentifiers($this->db->DBPrefix . $table),
+        );
+
+        if ($sql === '') {
+            if ($this->db->DBDebug) {
+                throw new DatabaseException('This feature is not available for the database you are using.');
+            }
+
+            return false;
+        }
+
+        return $this->db->query($sql);
+    }
+
     /**
      * @throws DatabaseException
      *
diff --git a/system/Database/MySQLi/Forge.php b/system/Database/MySQLi/Forge.php
index 094ae54264f9..d00c26dd1ca7 100644
--- a/system/Database/MySQLi/Forge.php
+++ b/system/Database/MySQLi/Forge.php
@@ -220,4 +220,20 @@ protected function _processIndexes(string $table): string
 
         return $sql;
     }
+
+    /**
+     * Drop Key
+     *
+     * @return bool
+     */
+    public function dropKey(string $table, string $keyName)
+    {
+        $sql = sprintf(
+            $this->dropIndexStr,
+            $this->db->escapeIdentifiers($keyName),
+            $this->db->escapeIdentifiers($this->db->DBPrefix . $table),
+        );
+
+        return $this->db->query($sql);
+    }
 }
diff --git a/system/Database/Postgre/Forge.php b/system/Database/Postgre/Forge.php
index 2f1a0769bd07..a050c6888e38 100644
--- a/system/Database/Postgre/Forge.php
+++ b/system/Database/Postgre/Forge.php
@@ -32,6 +32,13 @@ class Forge extends BaseForge
      */
     protected $dropConstraintStr = 'ALTER TABLE %s DROP CONSTRAINT %s';
 
+    /**
+     * DROP INDEX statement
+     *
+     * @var string
+     */
+    protected $dropIndexStr = 'DROP INDEX %s';
+
     /**
      * UNSIGNED support
      *
diff --git a/system/Database/SQLSRV/Forge.php b/system/Database/SQLSRV/Forge.php
index ae920ceae152..14d297604cbe 100755
--- a/system/Database/SQLSRV/Forge.php
+++ b/system/Database/SQLSRV/Forge.php
@@ -26,6 +26,13 @@ class Forge extends BaseForge
      */
     protected $dropConstraintStr;
 
+    /**
+     * DROP INDEX statement
+     *
+     * @var string
+     */
+    protected $dropIndexStr;
+
     /**
      * CREATE DATABASE IF statement
      *
@@ -106,6 +113,7 @@ public function __construct(BaseConnection $db)
         $this->renameTableStr = 'EXEC sp_rename [' . $this->db->escapeIdentifiers($this->db->schema) . '.%s] , %s ;';
 
         $this->dropConstraintStr = 'ALTER TABLE ' . $this->db->escapeIdentifiers($this->db->schema) . '.%s DROP CONSTRAINT %s';
+        $this->dropIndexStr      = 'DROP INDEX %s ON ' . $this->db->escapeIdentifiers($this->db->schema) . '.%s';
     }
 
     /**
diff --git a/system/Database/SQLite3/Forge.php b/system/Database/SQLite3/Forge.php
index 3275322beb92..1f48f20bd54e 100644
--- a/system/Database/SQLite3/Forge.php
+++ b/system/Database/SQLite3/Forge.php
@@ -20,6 +20,13 @@
  */
 class Forge extends BaseForge
 {
+    /**
+     * DROP INDEX statement
+     *
+     * @var string
+     */
+    protected $dropIndexStr = 'DROP INDEX %s';
+
     /**
      * @var Connection
      */
diff --git a/user_guide_src/source/changelogs/v4.1.5.rst b/user_guide_src/source/changelogs/v4.1.5.rst
index 6b9b75324c36..328e45163cb3 100644
--- a/user_guide_src/source/changelogs/v4.1.5.rst
+++ b/user_guide_src/source/changelogs/v4.1.5.rst
@@ -9,6 +9,7 @@ Enhancements:
 
 - Added Cache config for reserved characters
 - The ``addForeignKey`` function of the ``Forge`` class can now define composite foreign keys in an array
+- The ``dropKey`` function of the ``Forge`` class can remove key
 
 Changes:
 
diff --git a/user_guide_src/source/dbmgmt/forge.rst b/user_guide_src/source/dbmgmt/forge.rst
index 6cbdfe506e8a..66d7ebd75e09 100644
--- a/user_guide_src/source/dbmgmt/forge.rst
+++ b/user_guide_src/source/dbmgmt/forge.rst
@@ -304,6 +304,17 @@ Execute a DROP FOREIGN KEY.
     // Produces: ALTER TABLE 'tablename' DROP FOREIGN KEY 'users_foreign'
     $forge->dropForeignKey('tablename','users_foreign');
 
+
+Dropping a Key
+======================
+
+Execute a DROP KEY.
+
+::
+
+    // Produces: DROP INDEX `users_index` ON `tablename`
+    $forge->dropKey('tablename','users_index');
+
 Renaming a table
 ================
 


Test patch:
diff --git a/tests/system/Database/Live/ForgeTest.php b/tests/system/Database/Live/ForgeTest.php
index d459bc92e391..981269d12a08 100644
--- a/tests/system/Database/Live/ForgeTest.php
+++ b/tests/system/Database/Live/ForgeTest.php
@@ -1068,4 +1068,38 @@ public function testDropMultipleColumnWithString()
 
         $this->forge->dropTable('forge_test_four', true);
     }
+
+    public function testDropKey()
+    {
+        $this->forge->dropTable('key_test_users', true);
+        $keyName = 'key_test_users_id';
+
+        $attributes = [];
+
+        if ($this->db->DBDriver === 'MySQLi') {
+            $keyName    = 'id';
+            $attributes = ['ENGINE' => 'InnoDB'];
+        }
+
+        $this->forge->addField([
+            'id' => [
+                'type'       => 'INTEGER',
+                'constraint' => 11,
+            ],
+            'name' => [
+                'type'       => 'VARCHAR',
+                'constraint' => 255,
+            ],
+        ]);
+        $this->forge->addKey('id');
+        $this->forge->createTable('key_test_users', true, $attributes);
+
+        $this->forge->dropKey('key_test_users', $keyName);
+
+        $foreignKeyData = $this->db->getIndexData('key_test_users');
+
+        $this->assertEmpty($foreignKeyData);
+
+        $this->forge->dropTable('key_test_users', true);
+    }
 }