diff --git a/php/Migrations/0001_01_01_000008_create_brain_memories_table.php b/php/Migrations/0001_01_01_000008_create_brain_memories_table.php index e6c680d..509291b 100644 --- a/php/Migrations/0001_01_01_000008_create_brain_memories_table.php +++ b/php/Migrations/0001_01_01_000008_create_brain_memories_table.php @@ -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') diff --git a/php/Migrations/0001_01_01_000009_drop_brain_memories_workspace_fk.php b/php/Migrations/0001_01_01_000009_drop_brain_memories_workspace_fk.php index 3f8ee38..105f79f 100644 --- a/php/Migrations/0001_01_01_000009_drop_brain_memories_workspace_fk.php +++ b/php/Migrations/0001_01_01_000009_drop_brain_memories_workspace_fk.php @@ -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 diff --git a/php/config.php b/php/config.php index 61d8b84..1599522 100644 --- a/php/config.php +++ b/php/config.php @@ -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' => '', ], ],