fix(brain): Postgres portability for brain connection + migrations
Three related fixes so the brain DB works on Postgres, not just MariaDB:
1. config.php — brain charset/collation was hardcoded to utf8mb4 which
Postgres rejects as client_encoding. Now driver-aware: utf8 for
pgsql, utf8mb4 otherwise. Override via BRAIN_DB_CHARSET env var.
2. Migration 000008 (create_brain_memories) — self-referential FK on
supersedes_id was declared inside Schema::create{}, causing Postgres
to evaluate it before the PK index existed ('no unique constraint
matching given keys'). Split into Schema::create + separate
Schema::table to guarantee PK is in place when FK is added.
3. Migration 000009 (drop workspace FK) — try/catch inside the Blueprint
closure couldn't catch deferred SQL failures. Replaced with a
constraint-exists pre-query against information_schema, supporting
both pgsql and mariadb/mysql drivers. Fresh installs no longer fail
trying to drop a constraint that was never created.
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
e58986a3b4
commit
4e190dc7ec
3 changed files with 40 additions and 8 deletions
|
|
@ -43,7 +43,15 @@ return new class extends Migration
|
|||
$table->index('agent_id');
|
||||
$table->index(['workspace_id', 'type']);
|
||||
$table->index(['workspace_id', 'project']);
|
||||
});
|
||||
|
||||
// Self-referential FK added AFTER create so Postgres sees the
|
||||
// primary key on `id` when evaluating the constraint. Adding it
|
||||
// inside the create{} block ordered the FK before the PK index
|
||||
// on some Postgres versions, breaking with:
|
||||
// SQLSTATE[42830]: there is no unique constraint matching
|
||||
// given keys for referenced table "brain_memories"
|
||||
$schema->table('brain_memories', function (Blueprint $table) {
|
||||
$table->foreign('supersedes_id')
|
||||
->references('id')
|
||||
->on('brain_memories')
|
||||
|
|
|
|||
|
|
@ -25,13 +25,34 @@ return new class extends Migration
|
|||
return;
|
||||
}
|
||||
|
||||
$schema->table('brain_memories', function (Blueprint $table) {
|
||||
try {
|
||||
// Laravel Blueprint defers statement execution until the closure
|
||||
// returns, so a try/catch INSIDE the closure doesn't catch the
|
||||
// deferred SQL's failure. Instead, check the constraint exists
|
||||
// before issuing the drop, across both pgsql + mariadb backends.
|
||||
$conn = $schema->getConnection();
|
||||
$driver = $conn->getDriverName();
|
||||
$constraint = 'brain_memories_workspace_id_foreign';
|
||||
|
||||
$exists = match ($driver) {
|
||||
'pgsql' => (bool) $conn->selectOne(
|
||||
"SELECT 1 FROM information_schema.table_constraints
|
||||
WHERE table_name = 'brain_memories' AND constraint_name = ?",
|
||||
[$constraint],
|
||||
),
|
||||
'mariadb', 'mysql' => (bool) $conn->selectOne(
|
||||
"SELECT 1 FROM information_schema.table_constraints
|
||||
WHERE table_schema = DATABASE() AND table_name = 'brain_memories'
|
||||
AND constraint_name = ?",
|
||||
[$constraint],
|
||||
),
|
||||
default => false, // unknown driver — don't attempt the drop
|
||||
};
|
||||
|
||||
if ($exists) {
|
||||
$schema->table('brain_memories', function (Blueprint $table) {
|
||||
$table->dropForeign(['workspace_id']);
|
||||
} catch (\Throwable) {
|
||||
// FK doesn't exist — fresh install, nothing to drop.
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
|
|
|
|||
|
|
@ -95,8 +95,11 @@ return [
|
|||
'database' => env('BRAIN_DB_DATABASE', env('DB_DATABASE', 'forge')),
|
||||
'username' => env('BRAIN_DB_USERNAME', env('DB_USERNAME', 'forge')),
|
||||
'password' => env('BRAIN_DB_PASSWORD', env('DB_PASSWORD', '')),
|
||||
'charset' => 'utf8mb4',
|
||||
'collation' => 'utf8mb4_unicode_ci',
|
||||
// charset defaults: utf8 for pgsql (Postgres rejects 'utf8mb4'),
|
||||
// utf8mb4 for everything else (MariaDB/MySQL). Override with
|
||||
// BRAIN_DB_CHARSET if your instance needs something specific.
|
||||
'charset' => env('BRAIN_DB_CHARSET', env('BRAIN_DB_DRIVER', env('DB_CONNECTION', 'mariadb')) === 'pgsql' ? 'utf8' : 'utf8mb4'),
|
||||
'collation' => env('BRAIN_DB_COLLATION', 'utf8mb4_unicode_ci'),
|
||||
'prefix' => '',
|
||||
],
|
||||
],
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue