| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253 |
- <?php
- namespace App\Services;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Support\Facades\File;
- use Illuminate\Support\Facades\Artisan;
- use App\Models\User;
- use App\Database\Migrations\MasterMigration;
- use App\Database\Migrations\TenantMigration;
- class MigrationService
- {
- protected $masterDatabase = 'easia_master';
- public function runMasterMigrations()
- {
-
- $this->setupMasterConnection();
- $masterMigrations = $this->getMasterMigrationFiles();
- if (empty($masterMigrations)) {
- return ['message' => 'No master migrations found.', 'migrations' => []];
- }
- // Create a temporary directory for master migrations only
- $tempPath = storage_path('app/temp_master_migrations');
- if (!File::exists($tempPath)) {
- File::makeDirectory($tempPath, 0755, true);
- }
- // Copy only master migrations to temp directory
- foreach ($masterMigrations as $migration) {
- $source = database_path('migrations/' . $migration);
- $destination = $tempPath . '/' . $migration;
- File::copy($source, $destination);
- }
- try {
- // Run migrations from temp directory
- Artisan::call('migrate', [
- '--database' => 'master',
- '--path' => 'storage/app/temp_master_migrations'
- ]);
- $output = Artisan::output();
- } finally {
- // Clean up temp directory
- File::deleteDirectory($tempPath);
- }
- return [
- 'message' => 'Master migrations completed successfully!',
- 'database' => $this->masterDatabase,
- 'migrations' => $masterMigrations,
- 'output' => $output
- ];
- }
- public function runTenantMigrations()
- {
- $tenants = $this->getTenants();
- $results = [];
- if ($tenants->isEmpty()) {
- return ['message' => 'No tenants found.', 'results' => []];
- }
- $tenantMigrations = $this->getTenantMigrationFiles();
- if (empty($tenantMigrations)) {
- return ['message' => 'No tenant migrations found.', 'results' => []];
- }
- // Create a temporary directory for tenant migrations only
- $tempPath = storage_path('app/temp_tenant_migrations');
- if (!File::exists($tempPath)) {
- File::makeDirectory($tempPath, 0755, true);
- }
- // Copy only tenant migrations to temp directory
- foreach ($tenantMigrations as $migration) {
- $source = database_path('migrations/' . $migration);
- $destination = $tempPath . '/' . $migration;
- File::copy($source, $destination);
- }
- foreach ($tenants as $tenant) {
- try {
- $this->setupTenantConnection($tenant);
- Artisan::call('migrate', [
- '--database' => 'tenant',
- '--path' => 'storage/app/temp_tenant_migrations'
- ]);
- $results[] = [
- 'tenant' => $tenant->tenant_database,
- 'status' => 'success',
- 'message' => 'Migrations completed successfully'
- ];
- } catch (\Exception $e) {
- $results[] = [
- 'tenant' => $tenant->tenant_database,
- 'status' => 'error',
- 'message' => $e->getMessage()
- ];
- }
- }
- // Clean up temp directory
- File::deleteDirectory($tempPath);
- return [
- 'message' => 'Tenant migrations process completed',
- 'results' => $results
- ];
- }
- public function rollbackMasterMigrations($steps = 1)
- {
- $this->setupMasterConnection();
- Artisan::call('migrate:rollback', [
- '--database' => 'master',
- '--step' => $steps
- ]);
- return [
- 'message' => "Master database rolled back {$steps} step(s)",
- 'database' => $this->masterDatabase,
- 'output' => Artisan::output()
- ];
- }
- public function rollbackTenantMigrations($steps = 1)
- {
- $tenants = $this->getTenants();
- $results = [];
- foreach ($tenants as $tenant) {
- try {
- $this->setupTenantConnection($tenant);
- Artisan::call('migrate:rollback', [
- '--database' => 'tenant',
- '--step' => $steps
- ]);
- $results[] = [
- 'tenant' => $tenant->tenant_database,
- 'status' => 'success',
- 'message' => "Rolled back {$steps} step(s)"
- ];
- } catch (\Exception $e) {
- $results[] = [
- 'tenant' => $tenant->tenant_database,
- 'status' => 'error',
- 'message' => $e->getMessage()
- ];
- }
- }
- return [
- 'message' => 'Tenant rollback process completed',
- 'results' => $results
- ];
- }
- protected function setupMasterConnection()
- {
- config(['database.connections.master' => [
- 'driver' => 'mysql',
- 'host' => env('DB_HOST', '127.0.0.1'),
- 'port' => env('DB_PORT', '3306'),
- 'database' => $this->masterDatabase,
- 'username' => env('DB_USERNAME'),
- 'password' => env('DB_PASSWORD'),
- 'charset' => 'utf8mb4',
- 'collation' => 'utf8mb4_unicode_ci',
- 'prefix' => '',
- 'strict' => true,
- 'engine' => null,
- ]]);
- config(['database.default' => 'master']);
- DB::purge('master');
- DB::reconnect('master');
- }
- protected function setupTenantConnection($tenant)
- {
- config(['database.connections.tenant' => [
- 'driver' => 'mysql',
- 'host' => env('DB_HOST', '127.0.0.1'),
- 'port' => env('DB_PORT', '3306'),
- 'database' => $tenant->tenant_database,
- 'username' => $tenant->tenant_username,
- 'password' => $tenant->tenant_password,
- 'charset' => 'utf8mb4',
- 'collation' => 'utf8mb4_unicode_ci',
- 'prefix' => '',
- 'strict' => true,
- 'engine' => null,
- ]]);
- config(['database.default' => 'tenant']);
- DB::purge('tenant');
- DB::reconnect('tenant');
- }
- protected function getTenants()
- {
- return User::select('tenant_database', 'tenant_username', 'tenant_password')
- ->whereNotNull('tenant_database')
- ->distinct()
- ->get();
- }
- protected function getMasterMigrationFiles()
- {
- $migrationPath = database_path('migrations');
- $files = File::glob($migrationPath . '/*.php');
- $masterMigrations = [];
- foreach ($files as $file) {
- $content = File::get($file);
- if (strpos($content, 'extends MasterMigration') !== false) {
- $masterMigrations[] = basename($file);
- }
- }
- return $masterMigrations;
- }
- protected function getTenantMigrationFiles()
- {
- $migrationPath = database_path('migrations');
- $files = File::glob($migrationPath . '/*.php');
- $tenantMigrations = [];
- foreach ($files as $file) {
- $content = File::get($file);
- if (strpos($content, 'extends TenantMigration') !== false) {
- $tenantMigrations[] = basename($file);
- }
- }
- return $tenantMigrations;
- }
- }
|