Skip to content

Commit

Permalink
fix: "artisan db:wipe" command does not drop tables in all schemas
Browse files Browse the repository at this point in the history
  • Loading branch information
mmic-bjohnson authored and cbj4074 committed Mar 17, 2022
1 parent b05f89a commit ed926e0
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 18 deletions.
37 changes: 32 additions & 5 deletions src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ public function compileDropIfExists(Blueprint $blueprint, Fluent $command)
*/
public function compileDropAllTables($tables)
{
return 'drop table "'.implode('","', $tables).'" cascade';
return 'drop table '.implode(',', $this->escapeObjectReferences($tables)).' cascade';
}

/**
Expand All @@ -283,7 +283,7 @@ public function compileDropAllTables($tables)
*/
public function compileDropAllViews($views)
{
return 'drop view "'.implode('","', $views).'" cascade';
return 'drop view '.implode(',', $this->escapeObjectReferences($views)).' cascade';
}

/**
Expand All @@ -294,7 +294,7 @@ public function compileDropAllViews($views)
*/
public function compileDropAllTypes($types)
{
return 'drop type "'.implode('","', $types).'" cascade';
return 'drop type '.implode(',', $this->escapeObjectReferences($types)).' cascade';
}

/**
Expand All @@ -305,7 +305,7 @@ public function compileDropAllTypes($types)
*/
public function compileGetAllTables($searchPath)
{
return "select tablename from pg_catalog.pg_tables where schemaname in ('".implode("','", (array) $searchPath)."')";
return "select tablename, schemaname from pg_catalog.pg_tables where schemaname in ('".implode("','", (array) $searchPath)."')";
}

/**
Expand All @@ -316,7 +316,7 @@ public function compileGetAllTables($searchPath)
*/
public function compileGetAllViews($searchPath)
{
return "select viewname from pg_catalog.pg_views where schemaname in ('".implode("','", (array) $searchPath)."')";
return "select viewname, schemaname from pg_catalog.pg_views where schemaname in ('".implode("','", (array) $searchPath)."')";
}

/**
Expand Down Expand Up @@ -1070,4 +1070,31 @@ protected function modifyStoredAs(Blueprint $blueprint, Fluent $column)
return " generated always as ({$column->storedAs}) stored";
}
}

/**
* Escape database object references consitently, schema-qualified or not.
*
* @param array $objects
* @return array
*/
protected function escapeObjectReferences(array $objects): array
{
$escapedObjects = [];

foreach ($objects as $object) {
$parts = explode('.', $object);

$newParts = [];

array_walk($parts, function (&$part) use (&$newParts) {
$part = str_replace(['"',"'"], "", $part);

$newParts[] = $part;
});

$escapedObjects[] = '"' . implode('"."', $parts) . '"';
}

return $escapedObjects;
}
}
2 changes: 1 addition & 1 deletion src/Illuminate/Database/Schema/PostgresBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public function dropAllTables()
foreach ($this->getAllTables() as $row) {
$row = (array) $row;

$table = reset($row);
$table = '"' . $row['schemaname'] . '"."' . $row['tablename'] . '"';

if (! in_array($table, $excludedTables)) {
$tables[] = $table;
Expand Down
24 changes: 12 additions & 12 deletions tests/Database/DatabasePostgresBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -238,10 +238,10 @@ public function testDropAllTablesWhenSearchPathIsString()
$connection->shouldReceive('getConfig')->with('dont_drop')->andReturn(['foo']);
$grammar = m::mock(PostgresGrammar::class);
$connection->shouldReceive('getSchemaGrammar')->once()->andReturn($grammar);
$grammar->shouldReceive('compileGetAllTables')->with(['public'])->andReturn("select tablename from pg_catalog.pg_tables where schemaname in ('public')");
$connection->shouldReceive('select')->with("select tablename from pg_catalog.pg_tables where schemaname in ('public')")->andReturn(['users']);
$grammar->shouldReceive('compileDropAllTables')->with(['users'])->andReturn('drop table "'.implode('","', ['users']).'" cascade');
$connection->shouldReceive('statement')->with('drop table "'.implode('","', ['users']).'" cascade');
$grammar->shouldReceive('compileGetAllTables')->with(['public'])->andReturn("select tablename, schemaname from pg_catalog.pg_tables where schemaname in ('public')");
$connection->shouldReceive('select')->with("select tablename, schemaname from pg_catalog.pg_tables where schemaname in ('public')")->andReturn([['schemaname' => 'public', 'tablename' => 'users']]);
$grammar->shouldReceive('compileDropAllTables')->with(['"public"."users"'])->andReturn('drop table "public"."users" cascade');
$connection->shouldReceive('statement')->with('drop table "public"."users" cascade');
$builder = $this->getBuilder($connection);

$builder->dropAllTables();
Expand All @@ -255,10 +255,10 @@ public function testDropAllTablesWhenSearchPathIsStringOfMany()
$connection->shouldReceive('getConfig')->with('dont_drop')->andReturn(['foo']);
$grammar = m::mock(PostgresGrammar::class);
$connection->shouldReceive('getSchemaGrammar')->once()->andReturn($grammar);
$grammar->shouldReceive('compileGetAllTables')->with(['foouser', 'public', 'foo_bar-Baz.Áüõß'])->andReturn("select tablename from pg_catalog.pg_tables where schemaname in ('foouser','public','foo_bar-Baz.Áüõß')");
$connection->shouldReceive('select')->with("select tablename from pg_catalog.pg_tables where schemaname in ('foouser','public','foo_bar-Baz.Áüõß')")->andReturn(['users', 'users']);
$grammar->shouldReceive('compileDropAllTables')->with(['users', 'users'])->andReturn('drop table "'.implode('","', ['users', 'users']).'" cascade');
$connection->shouldReceive('statement')->with('drop table "'.implode('","', ['users', 'users']).'" cascade');
$grammar->shouldReceive('compileGetAllTables')->with(['foouser', 'public', 'foo_bar-Baz.Áüõß'])->andReturn("select tablename, schemaname from pg_catalog.pg_tables where schemaname in ('foouser','public','foo_bar-Baz.Áüõß')");
$connection->shouldReceive('select')->with("select tablename, schemaname from pg_catalog.pg_tables where schemaname in ('foouser','public','foo_bar-Baz.Áüõß')")->andReturn([['schemaname' => 'users', 'tablename' => 'users']]);
$grammar->shouldReceive('compileDropAllTables')->with(['"users"."users"'])->andReturn('drop table "users"."users" cascade');
$connection->shouldReceive('statement')->with('drop table "users"."users" cascade');
$builder = $this->getBuilder($connection);

$builder->dropAllTables();
Expand All @@ -277,10 +277,10 @@ public function testDropAllTablesWhenSearchPathIsArrayOfMany()
$connection->shouldReceive('getConfig')->with('dont_drop')->andReturn(['foo']);
$grammar = m::mock(PostgresGrammar::class);
$connection->shouldReceive('getSchemaGrammar')->once()->andReturn($grammar);
$grammar->shouldReceive('compileGetAllTables')->with(['foouser', 'dev', 'test', 'spaced schema'])->andReturn("select tablename from pg_catalog.pg_tables where schemaname in ('foouser','dev','test','spaced schema')");
$connection->shouldReceive('select')->with("select tablename from pg_catalog.pg_tables where schemaname in ('foouser','dev','test','spaced schema')")->andReturn(['users', 'users']);
$grammar->shouldReceive('compileDropAllTables')->with(['users', 'users'])->andReturn('drop table "'.implode('","', ['users', 'users']).'" cascade');
$connection->shouldReceive('statement')->with('drop table "'.implode('","', ['users', 'users']).'" cascade');
$grammar->shouldReceive('compileGetAllTables')->with(['foouser', 'dev', 'test', 'spaced schema'])->andReturn("select tablename, schemaname from pg_catalog.pg_tables where schemaname in ('foouser','dev','test','spaced schema')");
$connection->shouldReceive('select')->with("select tablename, schemaname from pg_catalog.pg_tables where schemaname in ('foouser','dev','test','spaced schema')")->andReturn([['schemaname' => 'users', 'tablename' => 'users']]);
$grammar->shouldReceive('compileDropAllTables')->with(['"users"."users"'])->andReturn('drop table "users"."users" cascade');
$connection->shouldReceive('statement')->with('drop table "users"."users" cascade');
$builder = $this->getBuilder($connection);

$builder->dropAllTables();
Expand Down

0 comments on commit ed926e0

Please sign in to comment.