Skip to content

Instantly share code, notes, and snippets.

@massiws
Last active February 17, 2025 21:04
Show Gist options
  • Save massiws/03867e2be58b907f612527008af2e8ec to your computer and use it in GitHub Desktop.
Save massiws/03867e2be58b907f612527008af2e8ec to your computer and use it in GitHub Desktop.
TenancyForLaravel - Squash tenant migrations
<?php
/**
* Dumps the schema of the tenant database.
*
* Backport into archtechx/tenancy v-3.x of the `migrate:dump` command from Tenancy v-4.x.
* @see https://github.com/archtechx/tenancy/pull/807
*
* Usage:
* 1. create a new command in App/Commands/TenantDump.php with the content of this file.
* 2. squash tenants migration running:
* php artisan tenants:dump [--tenant=TENANT_ID] [--prune] [--skip-definer]
*
* --tenant (optional): if not given will be prompted
* --prune (optional) : to remove all tenant's migration files
* --skip-definer : to remove the definer from generated dump
*/
declare(strict_types=1);
namespace App\Console\Commands;
use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Database\ConnectionResolverInterface;
use Illuminate\Database\Console\DumpCommand;
use Illuminate\Filesystem\Filesystem;
use Stancl\Tenancy\Contracts\Tenant;
use Symfony\Component\Console\Input\InputOption;
class TenantDump extends DumpCommand
{
public function __construct()
{
parent::__construct();
$this->setName('tenants:dump');
$this->specifyParameters();
}
public function handle(ConnectionResolverInterface $connections, Dispatcher $dispatcher): int
{
if (is_null($this->option('path'))) {
$this->input->setOption('path', config('tenancy.migration_parameters.--schema-path') ?? database_path('schema/tenant-schema.dump'));
}
$tenant = $this->option('tenant')
?? tenant()
?? $this->ask('What tenant do you want to dump the schema for?')
?? tenancy()->query()->first();
if (! $tenant instanceof Tenant) {
$tenant = tenancy()->find($tenant);
}
if ($tenant === null) {
$this->components->error('Could not find tenant to use for dumping the schema.');
return 1;
}
// Prevent the parent command from pruning the central migrations folder
$prune = $this->option('prune');
$this->input->setOption('prune', false);
tenancy()->runForMultiple([$tenant], fn () => parent::handle($connections, $dispatcher));
if ($prune) {
(new Filesystem)->deleteDirectory(
database_path('migrations/tenant'),
preserve: true
);
$this->components->info('Tenant migrations pruned.');
}
/**
* Omit the view definer from the generated dump.
*
* Example - dump generated without 'skip-definer' option:
* /*!50001 CREATE ALGORITHM=UNDEFINED *
* /*!50013 DEFINER=`root`@`%` SQL SECURITY DEFINER *
* /*!50001 VIEW `my_view_name` AS SELECT ...
*
* Example - dump generated with 'skip-definer' option:
* /*!50001 CREATE ALGORITHM=UNDEFINED *
* /* 50013 DEFINER=`root`@`%` SQL SECURITY DEFINER *
* /*!50001 VIEW `my_view_name` AS SELECT ...
*/
if ($this->option('skip-definer')) {
(new Filesystem)
->replaceInFile('/*!50013 DEFINER', '/* 50013 DEFINER', $this->option('path'));
}
return 0;
}
protected function getOptions(): array
{
return array_merge([
['tenant', null, InputOption::VALUE_OPTIONAL, '', null],
], parent::getOptions());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment