diff --git a/src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php b/src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php index f6450c1b41c9..8486e499d313 100755 --- a/src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php +++ b/src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php @@ -246,12 +246,12 @@ public function compileDropAllTypes($types) /** * Compile the SQL needed to retrieve all table names. * - * @param string|array $schema + * @param string|array $searchPath * @return string */ - public function compileGetAllTables($schema) + public function compileGetAllTables($searchPath) { - return "select tablename from pg_catalog.pg_tables where schemaname in ('".implode("','", (array) $schema)."')"; + return "select tablename from pg_catalog.pg_tables where schemaname in ('".implode("','", (array) $searchPath)."')"; } /** @@ -260,9 +260,9 @@ public function compileGetAllTables($schema) * @param string|array $schema * @return string */ - public function compileGetAllViews($schema) + public function compileGetAllViews($searchPath) { - return "select viewname from pg_catalog.pg_views where schemaname in ('".implode("','", (array) $schema)."')"; + return "select viewname from pg_catalog.pg_views where schemaname in ('".implode("','", (array) $searchPath)."')"; } /** diff --git a/src/Illuminate/Database/Schema/PostgresBuilder.php b/src/Illuminate/Database/Schema/PostgresBuilder.php index 0cba5f4d9a16..c249ccf02ebe 100755 --- a/src/Illuminate/Database/Schema/PostgresBuilder.php +++ b/src/Illuminate/Database/Schema/PostgresBuilder.php @@ -107,7 +107,9 @@ public function dropAllTypes() public function getAllTables() { return $this->connection->select( - $this->grammar->compileGetAllTables((array) $this->connection->getConfig('schema')) + $this->grammar->compileGetAllTables( + $this->parseSearchPath($this->connection->getConfig('search_path')) + ) ); } @@ -119,7 +121,9 @@ public function getAllTables() public function getAllViews() { return $this->connection->select( - $this->grammar->compileGetAllViews((array) $this->connection->getConfig('schema')) + $this->grammar->compileGetAllViews( + $this->parseSearchPath($this->connection->getConfig('search_path')) + ) ); } @@ -209,6 +213,10 @@ protected function parseSearchPath($searchPath) array_walk($searchPath, function (&$schema) { $schema = trim($schema, '\'"'); + + $schema = $schema === '$user' + ? $this->connection->getConfig('username') + : $schema; }); return $searchPath; diff --git a/tests/Database/DatabasePostgresBuilderTest.php b/tests/Database/DatabasePostgresBuilderTest.php index f41e271a4428..54e64e2e54e5 100644 --- a/tests/Database/DatabasePostgresBuilderTest.php +++ b/tests/Database/DatabasePostgresBuilderTest.php @@ -241,6 +241,51 @@ public function testWhenDatabaseNotDefaultGetColumnListingWithFullyQualifiedRefe $builder->getColumnListing('mydatabase.myapp.foo'); } + /** + * Ensure that when the search_path contains just one schema, only that + * schema is passed into the query that is executed to acquire the list + * of tables to be dropped. + */ + public function testDropAllTablesWithOneSchemaInSearchPath() + { + $connection = $this->getConnection(); + $connection->shouldReceive('getConfig')->with('search_path')->andReturn('public'); + $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'); + $builder = $this->getBuilder($connection); + + $builder->dropAllTables(); + } + + /** + * Ensure that when the search_path contains more than one schema, both + * schemas are passed into the query that is executed to acquire the list + * of tables to be dropped. Furthermore, ensure that the special '$user' + * variable is resolved to the username specified on the database connection + * in the process. + */ + public function testDropAllTablesWithMoreThanOneSchemaInSearchPath() + { + $connection = $this->getConnection(); + $connection->shouldReceive('getConfig')->with('username')->andReturn('foouser'); + $connection->shouldReceive('getConfig')->with('search_path')->andReturn('"$user", public'); + $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'])->andReturn("select tablename from pg_catalog.pg_tables where schemaname in ('foouser','public')"); + $connection->shouldReceive('select')->with("select tablename from pg_catalog.pg_tables where schemaname in ('foouser','public')")->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'); + $builder = $this->getBuilder($connection); + + $builder->dropAllTables(); + } + protected function getConnection() { return m::mock(Connection::class);