Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PostgreSQL Support #896

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

PseudoResonance
Copy link
Contributor

@PseudoResonance PseudoResonance commented Jan 8, 2025

Adds PostgreSQL as an alternative database option. Additionally, adds configurable driver option to the DynamicDatabaseConnection part.

The database driver type is saved in a new column driver of the DatabaseHost, allowing for potentially other databases in the future if desired.

I've tried to test everything I could think of, but please let me know if there's anything I missed, or if something should be adjusted. I want this to be as minimal of a maintenance burden as possible, but I do really want Postgres support because there's much better support for running it in a Kubernetes HA setup with CloudnativePG.

Comment on lines 1 to 33
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
switch (Schema::getConnection()->getDriverName()) {
case 'pgsql':
$database = DB::connection()->getDatabaseName();
DB::statement(sprintf('REVOKE CONNECT ON DATABASE "%s" FROM public', $database));
break;
}
}

/**
* Reverse the migrations.
*/
public function down(): void
{
switch (Schema::getConnection()->getDriverName()) {
case 'pgsql':
$database = DB::connection()->getDatabaseName();
DB::statement(sprintf('GRANT CONNECT ON DATABASE "%s" TO public', $database));
break;
}
}
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The user should do it not migrations

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or should it be part of the installer?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should probably be documented somewhere then that it's important if your panel database is on the same server as the server one.

});
break;
case 'pgsql':
DB::statement('ALTER TABLE egg_variables ALTER COLUMN rules TYPE jsonb USING to_jsonb(rules)');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless absolute necessity you shouldn't use raw statements and what i see from other migrations tells me its not mandatory

Comment on lines 31 to 38
switch (Schema::getConnection()->getDriverName()) {
case 'mariadb':
case 'mysql':
$table->dropForeign('service_options_nest_id_foreign');
break;
case 'sqlite':
$table->dropForeign(['nest_id']);
break;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
switch (Schema::getConnection()->getDriverName()) {
case 'mariadb':
case 'mysql':
$table->dropForeign('service_options_nest_id_foreign');
break;
case 'sqlite':
$table->dropForeign(['nest_id']);
break;
$table->dropForeign(['nest_id']);

Those are old format

composer.json Outdated Show resolved Hide resolved
compose.yml Outdated Show resolved Hide resolved
Comment on lines +38 to +49
switch ($database->host->driver) {
case 'mysql':
case 'mariadb':
$database->dropUser($database->username, $database->remote);
$database->createUser($database->database, $database->username, $database->remote, $password, $database->max_connections);
$database->assignUserToDatabase($database->database, $database->username, $database->remote);
$database->flush();
break;
case 'pgsql':
$database->updateUserPassword($database->database, $database->username, $database->remote, $password);
break;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use if/else or match

@@ -57,6 +64,7 @@ class DatabaseHost extends Model
'password' => 'nullable|string',
'node_ids' => 'nullable|array',
'node_ids.*' => 'required|integer,exists:nodes,id',
'driver' => 'required|string',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
'driver' => 'required|string',
'driver' => 'required|string|in:' . self::DRIVERS,

public const DRIVERS = 'mysql,mariadb,pgsql';

if ($driver === 'sqlite') {
return true;
}
switch ($driver) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use match

Comment on lines +122 to +132
config()->set('database.connections._panel_install_test', [
'driver' => $driver,
'host' => $host,
'port' => $port,
'database' => $database,
'username' => $username,
'password' => $password,
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'strict' => true,
]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use DynamicDatabaseConnection instead

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason why DynamicDatabaseConnection doesn't just have a static set function?

Comment on lines +9 to +25
public const DB_DEFAULTS = [
'mysql' => [
'DB_CHARSET' => 'utf8',
'DB_COLLATION' => 'utf8_unicode_ci',
'DEFAULT_DB' => 'mysql',
],
'mariadb' => [
'DB_CHARSET' => 'utf8',
'DB_COLLATION' => 'utf8_unicode_ci',
'DEFAULT_DB' => 'mysql',
],
'pgsql' => [
'DB_CHARSET' => 'utf8',
'DB_COLLATION' => 'en_US',
'DEFAULT_DB' => 'postgres',
],
];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use config instead

Copy link
Contributor

@RMartinOscar RMartinOscar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Almost there, please rebase to not use the PR #894

@lancepioch
Copy link
Member

Sorry, I'm not comfortable with changing that many past migrations and adding switch statements to that many of them, especially from that many years back. Most likely what would have to happen is migration squashing to get it to work properly with Postgresql. Please see here: https://laravel.com/docs/11.x/migrations#squashing-migrations

@lancepioch lancepioch closed this Jan 9, 2025
@github-actions github-actions bot locked and limited conversation to collaborators Jan 9, 2025
@pelican-dev pelican-dev unlocked this conversation Jan 9, 2025
@RMartinOscar RMartinOscar reopened this Jan 9, 2025
@PseudoResonance PseudoResonance marked this pull request as draft January 9, 2025 05:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants