diff --git a/framework/core/src/Database/Migrator.php b/framework/core/src/Database/Migrator.php index 8dccce81c4..91dc873d13 100644 --- a/framework/core/src/Database/Migrator.php +++ b/framework/core/src/Database/Migrator.php @@ -11,6 +11,7 @@ use Flarum\Database\Exception\MigrationKeyMissing; use Flarum\Extension\Extension; +use Flarum\Install\DatabaseConfig; use Illuminate\Contracts\Filesystem\FileNotFoundException; use Illuminate\Database\ConnectionInterface; use Illuminate\Filesystem\Filesystem; @@ -224,8 +225,11 @@ public function resolve(string $path, string $file): array * * @param string $path to the directory containing the dump. */ - public function installFromSchema(string $path, string $driver): bool + public function installFromSchema(string $path, DatabaseConfig $dbConfig): bool { + $driver = $dbConfig->toArray()['driver']; + $pgSearchPath = $dbConfig->toArray()['search_path'] ?? 'public'; + $schemaPath = "$path/$driver-install.dump"; if (! file_exists($schemaPath)) { @@ -252,11 +256,16 @@ public function installFromSchema(string $path, string $driver): bool $this->connection->getTablePrefix() ?? '', $statement ); + + if ($driver === 'pgsql' && $pgSearchPath != 'public') { + $statement = preg_replace('/(public)([\s.;])/', "$pgSearchPath\$2", $statement); + } + $this->connection->statement($statement); } if ($driver === 'pgsql') { - $this->connection->statement('SELECT pg_catalog.set_config(\'search_path\', \'public\', false)'); + $this->connection->statement("SELECT pg_catalog.set_config('search_path', '$pgSearchPath', false)"); } $this->connection->getSchemaBuilder()->enableForeignKeyConstraints(); diff --git a/framework/core/src/Install/Console/FileDataProvider.php b/framework/core/src/Install/Console/FileDataProvider.php index 4dd828407e..721b91d245 100644 --- a/framework/core/src/Install/Console/FileDataProvider.php +++ b/framework/core/src/Install/Console/FileDataProvider.php @@ -73,6 +73,7 @@ private function getDatabaseConfiguration(): DatabaseConfig $this->databaseConfiguration['host'] ?? 'localhost', $this->databaseConfiguration['port'] ?? 3306, $this->databaseConfiguration['database'] ?? 'flarum', + $this->databaseConfiguration['search_path'] ?? 'public', $this->databaseConfiguration['username'] ?? 'root', $this->databaseConfiguration['password'] ?? '', $this->databaseConfiguration['prefix'] ?? '' diff --git a/framework/core/src/Install/Console/UserDataProvider.php b/framework/core/src/Install/Console/UserDataProvider.php index d546d9d9a7..67735505b0 100644 --- a/framework/core/src/Install/Console/UserDataProvider.php +++ b/framework/core/src/Install/Console/UserDataProvider.php @@ -56,19 +56,30 @@ private function getDatabaseConfiguration(): DatabaseConfig if (Str::contains($host, ':')) { [$host, $port] = explode(':', $host, 2); } + } + + $database = $this->ask('Database name (required):', required: true); + + if ($driver === 'pgsql') { + $schema = $this->ask('Schema (Default: public):', 'public'); + } + if (in_array($driver, ['mysql', 'mariadb', 'pgsql'])) { $user = $this->ask('Database user (required):', required: true); $password = $this->secret('Database password:'); } + $prefix = $this->ask('Prefix:'); + return new DatabaseConfig( $driver, $host ?? null, intval($port), - $this->ask('Database name (required):', required: true), + $database, + $schema ?? null, $user ?? null, $password ?? null, - $this->ask('Prefix:') + $prefix ?? null ); } diff --git a/framework/core/src/Install/Controller/InstallController.php b/framework/core/src/Install/Controller/InstallController.php index f3297d19f7..799fad8142 100644 --- a/framework/core/src/Install/Controller/InstallController.php +++ b/framework/core/src/Install/Controller/InstallController.php @@ -93,6 +93,7 @@ private function makeDatabaseConfig(array $input): DatabaseConfig $host, intval($port), Arr::get($input, 'dbName'), + Arr::get($input, 'dbSchema'), Arr::get($input, 'dbUsername'), Arr::get($input, 'dbPassword'), Arr::get($input, 'tablePrefix') diff --git a/framework/core/src/Install/DatabaseConfig.php b/framework/core/src/Install/DatabaseConfig.php index bf7b39fe3d..79a1b3ce0f 100644 --- a/framework/core/src/Install/DatabaseConfig.php +++ b/framework/core/src/Install/DatabaseConfig.php @@ -19,6 +19,7 @@ public function __construct( private readonly ?string $host, private readonly int $port, private string $database, + private readonly ?string $schema, private readonly ?string $username, #[\SensitiveParameter] private readonly ?string $password, private readonly ?string $prefix @@ -58,6 +59,10 @@ private function validate(): void throw new ValidationFailed('Please specify the database name.'); } + if (empty($this->schema) && $this->driver == 'pgsql') { + throw new ValidationFailed('Please specify the schema name.'); + } + if (empty($this->username) && in_array($this->driver, ['mysql', 'mariadb', 'pgsql'])) { throw new ValidationFailed('Please specify the username for accessing the database.'); } @@ -100,7 +105,7 @@ private function driverOptions(): array 'username' => $this->username, 'password' => $this->password, 'charset' => 'utf8', - 'search_path' => 'public', + 'search_path' => $this->schema, 'sslmode' => 'prefer', ], 'sqlite' => [ diff --git a/framework/core/src/Install/Installation.php b/framework/core/src/Install/Installation.php index 6a821c2b93..0c6c9ec836 100644 --- a/framework/core/src/Install/Installation.php +++ b/framework/core/src/Install/Installation.php @@ -138,7 +138,7 @@ function ($connection) { }); $pipeline->pipe(function () { - return new Steps\RunMigrations($this->db, $this->dbConfig->toArray()['driver'], $this->getMigrationPath()); + return new Steps\RunMigrations($this->db, $this->dbConfig, $this->getMigrationPath()); }); $pipeline->pipe(function () { diff --git a/framework/core/src/Install/Steps/RunMigrations.php b/framework/core/src/Install/Steps/RunMigrations.php index da78d065c1..73077edc2e 100644 --- a/framework/core/src/Install/Steps/RunMigrations.php +++ b/framework/core/src/Install/Steps/RunMigrations.php @@ -11,6 +11,7 @@ use Flarum\Database\DatabaseMigrationRepository; use Flarum\Database\Migrator; +use Flarum\Install\DatabaseConfig; use Flarum\Install\Step; use Illuminate\Database\ConnectionInterface; use Illuminate\Filesystem\Filesystem; @@ -19,7 +20,7 @@ { public function __construct( private ConnectionInterface $database, - private string $driver, + private DatabaseConfig $dbConfig, private string $path ) { } @@ -33,7 +34,7 @@ public function run(): void { $migrator = $this->getMigrator(); - if (! $migrator->repositoryExists() && ! $migrator->installFromSchema($this->path, $this->driver)) { + if (! $migrator->repositoryExists() && ! $migrator->installFromSchema($this->path, $this->dbConfig)) { $migrator->getRepository()->createRepository(); } diff --git a/framework/core/views/install/install.php b/framework/core/views/install/install.php index 8f08032bd7..4205ec82b1 100644 --- a/framework/core/views/install/install.php +++ b/framework/core/views/install/install.php @@ -36,6 +36,13 @@ +