3 use BookStack\Permissions\JointPermissionBuilder;
4 use Illuminate\Database\Migrations\Migration;
5 use Illuminate\Database\Schema\Blueprint;
6 use Illuminate\Support\Facades\Schema;
8 return new class extends Migration
11 * @var array<string, string|array<string>> $columnByTable
13 protected static array $columnByTable = [
14 'activities' => 'loggable_id',
15 'attachments' => 'uploaded_to',
16 'bookshelves_books' => ['bookshelf_id', 'book_id'],
17 'comments' => 'entity_id',
18 'deletions' => 'deletable_id',
19 'entity_permissions' => 'entity_id',
20 'favourites' => 'favouritable_id',
21 'images' => 'uploaded_to',
22 'joint_permissions' => 'entity_id',
23 'page_revisions' => 'page_id',
24 'references' => ['from_id', 'to_id'],
25 'search_terms' => 'entity_id',
26 'tags' => 'entity_id',
27 'views' => 'viewable_id',
28 'watches' => 'watchable_id',
31 protected static array $nullable = [
32 'activities.loggable_id',
39 public function up(): void
41 // Drop foreign key constraints
42 Schema::table('bookshelves_books', function (Blueprint $table) {
43 $table->dropForeign(['book_id']);
44 $table->dropForeign(['bookshelf_id']);
47 // Update column types to unsigned big integers
48 foreach (static::$columnByTable as $table => $column) {
50 Schema::table($table, function (Blueprint $table) use ($tableName, $column) {
51 if (is_string($column)) {
55 foreach ($column as $col) {
56 if (in_array($tableName . '.' . $col, static::$nullable)) {
57 $table->unsignedBigInteger($col)->nullable()->change();
59 $table->unsignedBigInteger($col)->change();
65 // Convert image and activity zero values to null
66 DB::table('images')->where('uploaded_to', '=', 0)->update(['uploaded_to' => null]);
67 DB::table('activities')->where('loggable_id', '=', 0)->update(['loggable_id' => null]);
69 // Rebuild joint permissions if needed
70 // This was moved here from 2023_01_24_104625_refactor_joint_permissions_storage since the changes
71 // made for this release would mean our current logic would not be compatible with
72 // the database changes being made. This is based on a count since any joint permissions
73 // would have been truncated in the previous migration.
74 if (\Illuminate\Support\Facades\DB::table('joint_permissions')->count() === 0) {
75 app(JointPermissionBuilder::class)->rebuildForAll();
80 * Reverse the migrations.
82 public function down(): void
84 // Convert image null values back to zeros
85 DB::table('images')->whereNull('uploaded_to')->update(['uploaded_to' => '0']);
87 // Revert columns to standard integers
88 foreach (static::$columnByTable as $table => $column) {
90 Schema::table($table, function (Blueprint $table) use ($tableName, $column) {
91 if (is_string($column)) {
95 foreach ($column as $col) {
96 if ($tableName . '.' . $col === 'activities.loggable_id') {
97 $table->unsignedInteger($col)->nullable()->change();
98 } else if ($tableName . '.' . $col === 'images.uploaded_to') {
99 $table->unsignedInteger($col)->default(0)->change();
101 $table->unsignedInteger($col)->change();
107 // Re-add foreign key constraints
108 Schema::table('bookshelves_books', function (Blueprint $table) {
109 $table->foreign('bookshelf_id')->references('id')->on('bookshelves')
110 ->onUpdate('cascade')->onDelete('cascade');
111 $table->foreign('book_id')->references('id')->on('books')
112 ->onUpdate('cascade')->onDelete('cascade');