BF migration issues, R hybrid
This commit is contained in:
parent
3272d985ac
commit
5155815043
|
|
@ -2,6 +2,23 @@
|
|||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Auto-load migrations
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| When true (the default) the package auto-loads its migrations from
|
||||
| `vendor/blax-software/laravel-files/database/migrations` so a fresh
|
||||
| `composer require` + `php artisan migrate` Just Works™. Set to false
|
||||
| if you publish the migrations and want to manage them yourself — the
|
||||
| package will then defer entirely to your published copies.
|
||||
|
|
||||
| See: laravel-workkit/PRINCIPLES/laravel-composer-packages.md
|
||||
|
|
||||
*/
|
||||
|
||||
'run_migrations' => true,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Models
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
/**
|
||||
* Creates the package's `files` table (canonical name overridable via
|
||||
* `config('files.table_names.files')`).
|
||||
*
|
||||
* Idempotent on purpose — see laravel-workkit/PRINCIPLES/laravel-composer-packages.md
|
||||
* (section "Migrations: hybrid auto-load + publishable"). The whole point of
|
||||
* the hybrid pattern is that a consumer can `composer require` + `php artisan
|
||||
* migrate` and have it work, OR publish the migrations to customise them
|
||||
* without the auto-loaded version re-creating the table underneath. Either
|
||||
* path must succeed even if the other already ran.
|
||||
*/
|
||||
return new class extends Migration {
|
||||
public function up(): void
|
||||
{
|
||||
$name = config('files.table_names.files', 'files');
|
||||
|
||||
if (Schema::hasTable($name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Schema::create($name, function (Blueprint $table) {
|
||||
$table->uuid('id')->primary();
|
||||
// UUID rather than `unsignedBigInteger` so the package works
|
||||
// out-of-the-box with the UUID-PK conventions used across the
|
||||
// Blax fleet (see PRINCIPLES section "UUIDs or ULIDs for
|
||||
// everything"). Hosts on bigint user IDs can publish the
|
||||
// migration and swap this column type before running it.
|
||||
$table->uuid('user_id')->nullable()->index();
|
||||
$table->string('name')->nullable();
|
||||
$table->string('type')->nullable();
|
||||
$table->string('extension')->nullable();
|
||||
$table->unsignedBigInteger('size')->nullable();
|
||||
$table->string('disk')->default(config('files.disk', 'local'));
|
||||
$table->string('relativepath')->nullable();
|
||||
$table->json('meta')->nullable();
|
||||
$table->timestamp('last_accessed_at')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists(config('files.table_names.files', 'files'));
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
/**
|
||||
* Creates the `filables` pivot — the polymorphic attachment table that
|
||||
* links a {@see \Blax\Files\Models\File} to whatever host model owns it.
|
||||
*
|
||||
* Idempotent — same rationale as create_blax_files_table. The hybrid
|
||||
* auto-load + publishable pattern only works if re-running the migration
|
||||
* (after publish, or after someone partially created the schema by hand)
|
||||
* is a no-op rather than a crash.
|
||||
*/
|
||||
return new class extends Migration {
|
||||
public function up(): void
|
||||
{
|
||||
$name = config('files.table_names.filables', 'filables');
|
||||
|
||||
if (Schema::hasTable($name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Schema::create($name, function (Blueprint $table) {
|
||||
// UUID PK on the pivot so it pairs cleanly with the UUID-keyed
|
||||
// {@see \Blax\Files\Models\Filable} model (which uses HasUuids).
|
||||
$table->uuid('id')->primary();
|
||||
$table->uuid('file_id');
|
||||
// uuidMorphs for the same reason `user_id` is a UUID on the
|
||||
// files table: Blax host apps are UUID-PK by convention, so a
|
||||
// bigint morph FK wouldn't fit. Hosts that need bigint can
|
||||
// publish + edit.
|
||||
$table->uuidMorphs('filable');
|
||||
$table->string('as')->nullable()->index();
|
||||
$table->smallInteger('order')->nullable()->default(null);
|
||||
$table->json('meta')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->foreign('file_id')
|
||||
->references('id')
|
||||
->on(config('files.table_names.files', 'files'))
|
||||
->cascadeOnDelete();
|
||||
|
||||
$table->unique(['file_id', 'filable_type', 'filable_id', 'as'], 'filables_unique');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists(config('files.table_names.filables', 'filables'));
|
||||
}
|
||||
};
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create(config('files.table_names.filables', 'filables'), function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->uuid('file_id');
|
||||
$table->morphs('filable');
|
||||
$table->string('as')->nullable()->index();
|
||||
$table->smallInteger('order')->nullable()->default(null);
|
||||
$table->json('meta')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->foreign('file_id')
|
||||
->references('id')
|
||||
->on(config('files.table_names.files', 'files'))
|
||||
->cascadeOnDelete();
|
||||
|
||||
$table->unique(['file_id', 'filable_type', 'filable_id', 'as'], 'filables_unique');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists(config('files.table_names.filables', 'filables'));
|
||||
}
|
||||
};
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create(config('files.table_names.files', 'files'), function (Blueprint $table) {
|
||||
$table->uuid('id')->primary();
|
||||
$table->unsignedBigInteger('user_id')->nullable()->index();
|
||||
$table->string('name')->nullable();
|
||||
$table->string('type')->nullable();
|
||||
$table->string('extension')->nullable();
|
||||
$table->unsignedBigInteger('size')->nullable();
|
||||
$table->string('disk')->default(config('files.disk', 'local'));
|
||||
$table->string('relativepath')->nullable();
|
||||
$table->json('meta')->nullable();
|
||||
$table->timestamp('last_accessed_at')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists(config('files.table_names.files', 'files'));
|
||||
}
|
||||
};
|
||||
|
|
@ -15,11 +15,40 @@ class FilesServiceProvider extends \Illuminate\Support\ServiceProvider
|
|||
public function boot()
|
||||
{
|
||||
$this->offerPublishing();
|
||||
$this->registerMigrations();
|
||||
$this->registerModelBindings();
|
||||
$this->registerRoutes();
|
||||
$this->registerCommands();
|
||||
}
|
||||
|
||||
/**
|
||||
* Auto-load the package's migrations so fresh installs work without
|
||||
* publishing. Disabled via `files.run_migrations = false` for projects
|
||||
* that prefer to publish + manage migrations themselves.
|
||||
*
|
||||
* Follows the hybrid auto-load + publishable pattern documented in
|
||||
* `laravel-workkit/PRINCIPLES/laravel-composer-packages.md`.
|
||||
*/
|
||||
protected function registerMigrations(): void
|
||||
{
|
||||
if (! config('files.run_migrations', true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->loadMigrationsFrom(__DIR__ . '/../database/migrations');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up publishing of config and migrations for `php artisan vendor:publish`.
|
||||
*
|
||||
* Migrations are published preserving the SOURCE filename — the
|
||||
* migrations table records filenames, so keeping them identical means
|
||||
* any migration already executed via auto-load is recognised as run
|
||||
* for the published copy too. Slap a fresh `date('Y_m_d_His')` on the
|
||||
* publish destination and Laravel sees a brand-new migration and runs
|
||||
* it again, causing the "table already exists" failures consumers used
|
||||
* to hit before this rewrite.
|
||||
*/
|
||||
protected function offerPublishing()
|
||||
{
|
||||
if (! $this->app->runningInConsole()) {
|
||||
|
|
@ -28,23 +57,24 @@ class FilesServiceProvider extends \Illuminate\Support\ServiceProvider
|
|||
|
||||
$this->publishes([
|
||||
__DIR__ . '/../config/files.php' => $this->app->configPath('files.php'),
|
||||
], 'files-config');
|
||||
], ['files-config', 'config']);
|
||||
|
||||
$this->publishes([
|
||||
__DIR__ . '/../database/migrations/create_blax_files_table.php.stub' => $this->getMigrationFileName('create_blax_files_table.php'),
|
||||
__DIR__ . '/../database/migrations/create_blax_filables_table.php.stub' => $this->getMigrationFileName('create_blax_filables_table.php'),
|
||||
], 'files-migrations');
|
||||
$migrationsPath = __DIR__ . '/../database/migrations';
|
||||
$publishMap = [];
|
||||
foreach (glob($migrationsPath . '/*.php') as $sourcePath) {
|
||||
$publishMap[$sourcePath] = $this->app->databasePath('migrations/' . basename($sourcePath));
|
||||
}
|
||||
|
||||
protected function getMigrationFileName(string $migrationFileName): string
|
||||
{
|
||||
$timestamp = date('Y_m_d_His');
|
||||
$filesystem = $this->app->make(\Illuminate\Filesystem\Filesystem::class);
|
||||
$this->publishes($publishMap, ['files-migrations', 'migrations']);
|
||||
|
||||
return \Illuminate\Support\Collection::make([$this->app->databasePath() . DIRECTORY_SEPARATOR . 'migrations' . DIRECTORY_SEPARATOR])
|
||||
->flatMap(fn($path) => $filesystem->glob($path . '*_' . $migrationFileName))
|
||||
->push($this->app->databasePath() . "/migrations/{$timestamp}_{$migrationFileName}")
|
||||
->first();
|
||||
// Convenience tag: publish everything the package owns in one go.
|
||||
$this->publishes(
|
||||
array_merge(
|
||||
[__DIR__ . '/../config/files.php' => $this->app->configPath('files.php')],
|
||||
$publishMap,
|
||||
),
|
||||
'files',
|
||||
);
|
||||
}
|
||||
|
||||
protected function registerModelBindings(): void
|
||||
|
|
|
|||
Loading…
Reference in New Issue