Created
August 8, 2017 01:35
-
-
Save Razoxane/3bc74900b4eb5c983eb0927fa13b95f5 to your computer and use it in GitHub Desktop.
Laravel - Create Index If Not Exists / Drop Index If Exists
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use Illuminate\Support\Facades\Schema; | |
use Illuminate\Database\Schema\Blueprint; | |
use Illuminate\Database\Migrations\Migration; | |
class LaravelConditionalIndexMigration extends Migration | |
{ | |
/** | |
* Run the migrations. | |
* | |
* @return void | |
*/ | |
public function up() | |
{ | |
Schema::table('tablename', function (Blueprint $table) { | |
$sm = Schema::getConnection()->getDoctrineSchemaManager(); | |
$doctrineTable = $sm->listTableDetails('tablename'); | |
if (! $doctrineTable->hasIndex('singlecolumnindexname')) { | |
$table->index('column1', 'singlecolumnindexname'); | |
} | |
if (! $doctrineTable->hasIndex('multicolumnindexname')) { | |
$table->index(['column2', 'column3'], 'multicolumnindexname'); | |
} | |
}); | |
} | |
/** | |
* Reverse the migrations. | |
* | |
* @return void | |
*/ | |
public function down() | |
{ | |
Schema::table('tablename', function (Blueprint $table) { | |
$sm = Schema::getConnection()->getDoctrineSchemaManager(); | |
$doctrineTable = $sm->listTableDetails('tablename'); | |
if ($doctrineTable->hasIndex('singlecolumnindexname')) { | |
$table->dropIndex('singlecolumnindexname'); | |
} | |
if ($doctrineTable->hasIndex('multicolumnindexname')) { | |
$table->dropIndex('multicolumnindexname'); | |
} | |
}); | |
} | |
} |
It appears that the listTableDetails
function is deprecated. There wasn't an obvious replacement from the documentation
I solved the problem this way:
$sm = Schema::getConnection()->getDoctrineSchemaManager();
$index_list = $sm->listTableIndexes('tablename');
if(in_array('indexname', $index_list)) {
$table->dropIndex('indexname');
}
It appears that the
listTableDetails
function is deprecated. There wasn't an obvious replacement from the documentationI solved the problem this way:
$sm = Schema::getConnection()->getDoctrineSchemaManager(); $index_list = $sm->listTableIndexes('tablename'); if(in_array('indexname', $index_list)) { $table->dropIndex('indexname'); }
I don't know in which version it appeared, but now there is a replacement : introspectTable()
I'm glad I found this, because that's exactly what I was looking for! Thanks for the comments!
I made a portable/reuseable solution for it (app/Domain/Migration/MigrationUtil.php
):
<?php
declare(strict_types=1);
namespace App\Domain\Migration;
use Doctrine\DBAL\Exception;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
class MigrationUtil
{
/**
* INFO: https://gist.github.com/Razoxane/3bc74900b4eb5c983eb0927fa13b95f5
*
* @throws Exception
*/
public static function hasIndex(string $tableName, string $indexName): bool
{
$doctrineSchemaManager = Schema::getConnection()->getDoctrineSchemaManager();
return $doctrineSchemaManager->introspectTable($tableName)->hasIndex($indexName);
}
}
usage:
<?php
declare(strict_types=1);
use App\Domain\Migration\MigrationUtil;
use Illuminate\Database\Migrations\Migration;
return new class() extends Migration {
public function up(): void
{
Schema::table('users', static function ($table) {
if (MigrationUtil::hasIndex('users', 'unique_email')) {
$table->dropUnique('unique_email');
}
if (!MigrationUtil::hasIndex('users', 'users_email_unique')) {
$table->unique('email');
}
});
}
};
Thanks! Great stuff 🙇♂️ 💯
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
this helped me a lot, thank you!