From 3e555002ac5b96c51735f2a04b217e8795433724 Mon Sep 17 00:00:00 2001 From: Drew Richards Date: Tue, 30 Apr 2019 10:42:30 -0400 Subject: [PATCH] Allows dropping types when running php artisan migrate:fresh --- .../Console/Migrations/FreshCommand.php | 21 ++++++++++++ src/Illuminate/Database/Schema/Builder.php | 12 +++++++ .../Schema/Grammars/PostgresGrammar.php | 21 ++++++++++++ .../Database/Schema/PostgresBuilder.php | 34 +++++++++++++++++++ .../Foundation/Testing/RefreshDatabase.php | 18 ++++++++-- .../DatabasePostgresSchemaGrammarTest.php | 7 ++++ 6 files changed, 110 insertions(+), 3 deletions(-) diff --git a/src/Illuminate/Database/Console/Migrations/FreshCommand.php b/src/Illuminate/Database/Console/Migrations/FreshCommand.php index 28c1e9973fbc..5852fe96cc58 100644 --- a/src/Illuminate/Database/Console/Migrations/FreshCommand.php +++ b/src/Illuminate/Database/Console/Migrations/FreshCommand.php @@ -47,6 +47,12 @@ public function handle() $this->info('Dropped all tables successfully.'); + if ($this->option('drop-types')) { + $this->dropAllTypes($database); + + $this->info('Dropped all types successfully.'); + } + $this->call('migrate', array_filter([ '--database' => $database, '--path' => $this->input->getOption('path'), @@ -86,6 +92,19 @@ protected function dropAllViews($database) ->dropAllViews(); } + /** + * Drop all of the database types. + * + * @param string $database + * @return void + */ + protected function dropAllTypes($database) + { + $this->laravel['db']->connection($database) + ->getSchemaBuilder() + ->dropAllTypes(); + } + /** * Determine if the developer has requested database seeding. * @@ -123,6 +142,8 @@ protected function getOptions() ['drop-views', null, InputOption::VALUE_NONE, 'Drop all tables and views'], + ['drop-types', null, InputOption::VALUE_NONE, 'Drop all tables and types (Postgres only)'], + ['force', null, InputOption::VALUE_NONE, 'Force the operation to run when in production'], ['path', null, InputOption::VALUE_OPTIONAL, 'The path to the migrations files to be executed'], diff --git a/src/Illuminate/Database/Schema/Builder.php b/src/Illuminate/Database/Schema/Builder.php index d80f375b7ac0..f8f060ef54aa 100755 --- a/src/Illuminate/Database/Schema/Builder.php +++ b/src/Illuminate/Database/Schema/Builder.php @@ -216,6 +216,18 @@ public function dropAllViews() throw new LogicException('This database driver does not support dropping all views.'); } + /** + * Drop all types from the database. + * + * @return void + * + * @throws \LogicException + */ + public function dropAllTypes() + { + throw new LogicException('This database driver does not support dropping all types'); + } + /** * Rename a table on the schema. * diff --git a/src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php b/src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php index 7233e070030d..59ecae6cadea 100755 --- a/src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php +++ b/src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php @@ -219,6 +219,17 @@ public function compileDropAllViews($views) return 'drop view "'.implode('","', $views).'" cascade'; } + /** + * Compile the SQL needed to drop all types. + * + * @param array $types + * @return string + */ + public function compileDropAllTypes($types) + { + return 'drop type "'.implode('","', $types).'" cascade'; + } + /** * Compile the SQL needed to retrieve all table names. * @@ -241,6 +252,16 @@ public function compileGetAllViews($schema) return "select viewname from pg_catalog.pg_views where schemaname = '{$schema}'"; } + /** + * Compile the SQL needed to retrieve all type names. + * + * @return string + */ + public function compileGetAllTypes() + { + return "select distinct pg_type.typname from pg_type inner join pg_enum on pg_enum.enumtypid = pg_type.oid"; + } + /** * Compile a drop column command. * diff --git a/src/Illuminate/Database/Schema/PostgresBuilder.php b/src/Illuminate/Database/Schema/PostgresBuilder.php index bdeb972a6747..af03af7e18e1 100755 --- a/src/Illuminate/Database/Schema/PostgresBuilder.php +++ b/src/Illuminate/Database/Schema/PostgresBuilder.php @@ -75,6 +75,28 @@ public function dropAllViews() ); } + /** + * Drop all types from the database. + */ + public function dropAllTypes() + { + $types = []; + + foreach ($this->getAllTypes() as $row) { + $row = (array) $row; + + $types[] = reset($row); + } + + if (empty($types)) { + return; + } + + $this->connection->statement( + $this->grammar->compileDropAllTypes($types) + ); + } + /** * Get all of the table names for the database. * @@ -99,6 +121,18 @@ protected function getAllViews() ); } + /** + * Get all of the type names for the database. + * + * @return array + */ + protected function getAllTypes() + { + return $this->connection->select( + $this->grammar->compileGetAllTypes() + ); + } + /** * Get the column listing for a given table. * diff --git a/src/Illuminate/Foundation/Testing/RefreshDatabase.php b/src/Illuminate/Foundation/Testing/RefreshDatabase.php index be3360514071..a6892be196f8 100644 --- a/src/Illuminate/Foundation/Testing/RefreshDatabase.php +++ b/src/Illuminate/Foundation/Testing/RefreshDatabase.php @@ -50,9 +50,10 @@ protected function refreshInMemoryDatabase() protected function refreshTestDatabase() { if (! RefreshDatabaseState::$migrated) { - $this->artisan('migrate:fresh', $this->shouldDropViews() ? [ - '--drop-views' => true, - ] : []); + $this->artisan('migrate:fresh', [ + '--drop-views' => $this->shouldDropViews(), + '--drop-types' => $this->shouldDropTypes(), + ]); $this->app[Kernel::class]->setArtisan(null); @@ -114,4 +115,15 @@ protected function shouldDropViews() return property_exists($this, 'dropViews') ? $this->dropViews : false; } + + /** + * Determine if types should be dropped when refreshing the database. + * + * @return bool + */ + protected function shouldDropTypes() + { + return property_exists($this, 'dropTypes') + ? $this->dropTypes : false; + } } diff --git a/tests/Database/DatabasePostgresSchemaGrammarTest.php b/tests/Database/DatabasePostgresSchemaGrammarTest.php index 0307198ea787..065bf06200e6 100755 --- a/tests/Database/DatabasePostgresSchemaGrammarTest.php +++ b/tests/Database/DatabasePostgresSchemaGrammarTest.php @@ -832,6 +832,13 @@ public function testDropAllViewsEscapesTableNames() $this->assertEquals('drop view "alpha","beta","gamma" cascade', $statement); } + public function testDropAllTypesEscapesTableNames() + { + $statement = $this->getGrammar()->compileDropAllTypes(['alpha', 'beta', 'gamma']); + + $this->assertEquals('drop type "alpha","beta","gamma" cascade', $statement); + } + protected function getConnection() { return m::mock(Connection::class);