Skip to content

Commit 96302bf

Browse files
[11.x] feat: Create missing pgsql database when running migrations (#54314)
* feat: Create missing pgsql database * feat: Create missing pgsql database * feat: Create missing pgsql database * feat: Create missing pgsql database * feat: Create missing pgsql database * feat: Create missing pgsql database * formatting --------- Co-authored-by: Taylor Otwell <[email protected]>
1 parent 8d2c225 commit 96302bf

File tree

1 file changed

+46
-19
lines changed

1 file changed

+46
-19
lines changed

src/Illuminate/Database/Console/Migrations/MigrateCommand.php

Lines changed: 46 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Illuminate\Database\Migrations\Migrator;
1010
use Illuminate\Database\SQLiteDatabaseDoesNotExistException;
1111
use Illuminate\Database\SqlServerConnection;
12+
use Illuminate\Support\Str;
1213
use PDOException;
1314
use RuntimeException;
1415
use Symfony\Component\Console\Attribute\AsCommand;
@@ -163,26 +164,41 @@ protected function repositoryExists()
163164
{
164165
return retry(2, fn () => $this->migrator->repositoryExists(), 0, function ($e) {
165166
try {
166-
if ($e->getPrevious() instanceof SQLiteDatabaseDoesNotExistException) {
167-
return $this->createMissingSqliteDatabase($e->getPrevious()->path);
168-
}
169-
170-
$connection = $this->migrator->resolveConnection($this->option('database'));
171-
172-
if (
173-
$e->getPrevious() instanceof PDOException &&
174-
$e->getPrevious()->getCode() === 1049 &&
175-
in_array($connection->getDriverName(), ['mysql', 'mariadb'])) {
176-
return $this->createMissingMysqlDatabase($connection);
177-
}
178-
179-
return false;
167+
return $this->handleMissingDatabase($e->getPrevious());
180168
} catch (Throwable) {
181169
return false;
182170
}
183171
});
184172
}
185173

174+
/**
175+
* Attempt to create the database if it is missing.
176+
*
177+
* @param \Throwable $e
178+
* @return bool
179+
*/
180+
protected function handleMissingDatabase(Throwable $e)
181+
{
182+
if ($e instanceof SQLiteDatabaseDoesNotExistException) {
183+
return $this->createMissingSqliteDatabase($e->path);
184+
}
185+
186+
$connection = $this->migrator->resolveConnection($this->option('database'));
187+
188+
if (! $e instanceof PDOException) {
189+
return false;
190+
}
191+
192+
if (($e->getCode() === 1049 && in_array($connection->getDriverName(), ['mysql', 'mariadb'])) ||
193+
(($e->errorInfo[0] ?? null) == '08006' &&
194+
$connection->getDriverName() == 'pgsql' &&
195+
Str::contains($e->getMessage(), '"'.$connection->getDatabaseName().'"'))) {
196+
return $this->createMissingMySqlOrPgsqlDatabase($connection);
197+
}
198+
199+
return false;
200+
}
201+
186202
/**
187203
* Create a missing SQLite database.
188204
*
@@ -213,13 +229,14 @@ protected function createMissingSqliteDatabase($path)
213229
}
214230

215231
/**
216-
* Create a missing MySQL database.
232+
* Create a missing MySQL or Postgres database.
217233
*
234+
* @param \Illuminate\Database\Connection $connection
218235
* @return bool
219236
*
220237
* @throws \RuntimeException
221238
*/
222-
protected function createMissingMysqlDatabase($connection)
239+
protected function createMissingMySqlOrPgsqlDatabase($connection)
223240
{
224241
if ($this->laravel['config']->get("database.connections.{$connection->getName()}.database") !== $connection->getDatabaseName()) {
225242
return false;
@@ -238,15 +255,25 @@ protected function createMissingMysqlDatabase($connection)
238255
throw new RuntimeException('Database was not created. Aborting migration.');
239256
}
240257
}
241-
242258
try {
243-
$this->laravel['config']->set("database.connections.{$connection->getName()}.database", null);
259+
$this->laravel['config']->set(
260+
"database.connections.{$connection->getName()}.database",
261+
match ($connection->getDriverName()) {
262+
'mysql', 'mariadb' => null,
263+
'pgsql' => 'postgres',
264+
},
265+
);
244266

245267
$this->laravel['db']->purge();
246268

247269
$freshConnection = $this->migrator->resolveConnection($this->option('database'));
248270

249-
return tap($freshConnection->unprepared("CREATE DATABASE IF NOT EXISTS `{$connection->getDatabaseName()}`"), function () {
271+
return tap($freshConnection->unprepared(
272+
match ($connection->getDriverName()) {
273+
'mysql', 'mariadb' => "CREATE DATABASE IF NOT EXISTS `{$connection->getDatabaseName()}`",
274+
'pgsql' => 'CREATE DATABASE "'.$connection->getDatabaseName().'"',
275+
}
276+
), function () {
250277
$this->laravel['db']->purge();
251278
});
252279
} finally {

0 commit comments

Comments
 (0)