232 lines
9.3 KiB
PHP
232 lines
9.3 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\MigrationSchedule;
|
|
use App\Models\SourceDatabase;
|
|
use App\Models\TargetDatabase;
|
|
use App\Models\Table;
|
|
use App\Models\MigrationRun;
|
|
use App\Jobs\RunMigrationJob;
|
|
use Illuminate\Http\Request;
|
|
use Inertia\Inertia;
|
|
|
|
class MigrationScheduleController extends Controller
|
|
{
|
|
public function index()
|
|
{
|
|
$schedules = MigrationSchedule::with(['sourceDatabase', 'targetDatabase'])
|
|
->withCount('migrationRuns')
|
|
->get();
|
|
|
|
return Inertia::render('Migrations/Index', [
|
|
'schedules' => $schedules,
|
|
]);
|
|
}
|
|
|
|
public function create()
|
|
{
|
|
$sourceDatabases = SourceDatabase::where('is_active', true)->get();
|
|
$targetDatabases = TargetDatabase::where('is_active', true)->get();
|
|
$tables = Table::with('sourceDatabase')->get()->groupBy('source_database_id');
|
|
|
|
return Inertia::render('Migrations/ScheduleForm', [
|
|
'schedule' => null,
|
|
'sourceDatabases' => $sourceDatabases,
|
|
'targetDatabases' => $targetDatabases,
|
|
'tables' => $tables,
|
|
]);
|
|
}
|
|
|
|
public function store(Request $request)
|
|
{
|
|
$validated = $request->validate([
|
|
'name' => 'required|string|max:255',
|
|
'source_database_id' => 'required|exists:source_databases,id',
|
|
'target_database_id' => 'required|exists:target_databases,id',
|
|
'tables' => 'required|array|min:1',
|
|
'tables.*' => 'exists:tables,id',
|
|
'cron_expression' => 'required|string|max:100',
|
|
'timezone' => 'nullable|string|max:50',
|
|
'is_active' => 'boolean',
|
|
'run_in_parallel' => 'boolean',
|
|
'batch_size' => 'integer|min:1',
|
|
'truncate_before_migration' => 'boolean',
|
|
'create_indexes_after' => 'boolean',
|
|
'python_script_path' => 'nullable|string',
|
|
'description' => 'nullable|string',
|
|
]);
|
|
|
|
$validated['timezone'] = $validated['timezone'] ?? 'UTC';
|
|
$validated['is_active'] = $validated['is_active'] ?? true;
|
|
$validated['is_incremental'] = $validated['is_incremental'] ?? false;
|
|
$validated['incremental_column'] = $validated['is_incremental'] ? ($validated['incremental_column'] ?? 'updated_at') : null;
|
|
$validated['use_life_table'] = $validated['use_life_table'] ?? false;
|
|
|
|
if ($validated['use_life_table']) {
|
|
$validated['life_table_name'] = $validated['life_table_name'] ?? null;
|
|
$validated['life_id_column'] = $validated['life_id_column'] ?? null;
|
|
$validated['base_id_column'] = $validated['base_id_column'] ?? null;
|
|
$validated['operation_column'] = $validated['operation_column'] ?? 'x_Operation';
|
|
$validated['datetime_column'] = $validated['datetime_column'] ?? 'x_DateTime';
|
|
}
|
|
|
|
$validated['run_in_parallel'] = $validated['run_in_parallel'] ?? false;
|
|
$validated['batch_size'] = $validated['batch_size'] ?? 1000;
|
|
$validated['truncate_before_migration'] = $validated['truncate_before_migration'] ?? false;
|
|
$validated['create_indexes_after'] = $validated['create_indexes_after'] ?? true;
|
|
|
|
$validated['python_script_args'] = [
|
|
'incremental' => $validated['is_incremental'],
|
|
'incremental_column' => $validated['incremental_column'],
|
|
'use_life_table' => $validated['use_life_table'],
|
|
'life_table_name' => $validated['life_table_name'],
|
|
'life_id_column' => $validated['life_id_column'],
|
|
'base_id_column' => $validated['base_id_column'],
|
|
'operation_column' => $validated['operation_column'],
|
|
'datetime_column' => $validated['datetime_column'],
|
|
];
|
|
|
|
$schedule = MigrationSchedule::create($validated);
|
|
|
|
// Attach tables to schedule
|
|
$schedule->scheduledTables()->sync($validated['tables']);
|
|
|
|
return redirect()->route('migrations.index')
|
|
->with('success', 'Migration schedule created successfully.');
|
|
}
|
|
|
|
public function edit(MigrationSchedule $schedule)
|
|
{
|
|
$schedule->load('scheduledTables');
|
|
|
|
$sourceDatabases = SourceDatabase::where('is_active', true)->get();
|
|
$targetDatabases = TargetDatabase::where('is_active', true)->get();
|
|
$tables = Table::with('sourceDatabase')
|
|
->where('source_database_id', $schedule->source_database_id)
|
|
->get();
|
|
|
|
return Inertia::render('Migrations/ScheduleForm', [
|
|
'schedule' => $schedule,
|
|
'sourceDatabases' => $sourceDatabases,
|
|
'targetDatabases' => $targetDatabases,
|
|
'tables' => $tables,
|
|
]);
|
|
}
|
|
|
|
public function update(Request $request, MigrationSchedule $schedule)
|
|
{
|
|
$validated = $request->validate([
|
|
'name' => 'required|string|max:255',
|
|
'source_database_id' => 'required|exists:source_databases,id',
|
|
'target_database_id' => 'required|exists:target_databases,id',
|
|
'tables' => 'required|array|min:1',
|
|
'tables.*' => 'exists:tables,id',
|
|
'cron_expression' => 'required|string|max:100',
|
|
'timezone' => 'nullable|string|max:50',
|
|
'is_active' => 'boolean',
|
|
'is_incremental' => 'boolean',
|
|
'incremental_column' => 'nullable|string|max:100',
|
|
'use_life_table' => 'boolean',
|
|
'life_table_name' => 'nullable|string|max:255',
|
|
'life_id_column' => 'nullable|string|max:100',
|
|
'base_id_column' => 'nullable|string|max:100',
|
|
'operation_column' => 'nullable|string|max:100',
|
|
'datetime_column' => 'nullable|string|max:100',
|
|
'run_in_parallel' => 'boolean',
|
|
'batch_size' => 'integer|min:1',
|
|
'truncate_before_migration' => 'boolean',
|
|
'create_indexes_after' => 'boolean',
|
|
'python_script_path' => 'nullable|string',
|
|
'description' => 'nullable|string',
|
|
]);
|
|
|
|
$validated['is_incremental'] = $validated['is_incremental'] ?? false;
|
|
$validated['incremental_column'] = $validated['is_incremental'] ? ($validated['incremental_column'] ?? 'updated_at') : null;
|
|
$validated['use_life_table'] = $validated['use_life_table'] ?? false;
|
|
|
|
if ($validated['use_life_table']) {
|
|
$validated['life_table_name'] = $validated['life_table_name'] ?? null;
|
|
$validated['life_id_column'] = $validated['life_id_column'] ?? null;
|
|
$validated['base_id_column'] = $validated['base_id_column'] ?? null;
|
|
$validated['operation_column'] = $validated['operation_column'] ?? 'x_Operation';
|
|
$validated['datetime_column'] = $validated['datetime_column'] ?? 'x_DateTime';
|
|
}
|
|
|
|
$validated['python_script_args'] = [
|
|
'incremental' => $validated['is_incremental'],
|
|
'incremental_column' => $validated['incremental_column'],
|
|
'use_life_table' => $validated['use_life_table'],
|
|
'life_table_name' => $validated['life_table_name'],
|
|
'life_id_column' => $validated['life_id_column'],
|
|
'base_id_column' => $validated['base_id_column'],
|
|
'operation_column' => $validated['operation_column'],
|
|
'datetime_column' => $validated['datetime_column'],
|
|
];
|
|
|
|
$schedule->update($validated);
|
|
|
|
// Sync tables
|
|
$schedule->scheduledTables()->sync($validated['tables']);
|
|
|
|
return redirect()->route('migrations.index')
|
|
->with('success', 'Migration schedule updated successfully.');
|
|
}
|
|
|
|
public function destroy(MigrationSchedule $schedule)
|
|
{
|
|
$schedule->delete();
|
|
|
|
return redirect()->route('migrations.index')
|
|
->with('success', 'Migration schedule deleted successfully.');
|
|
}
|
|
|
|
public function runNow(MigrationSchedule $schedule)
|
|
{
|
|
// Check if there's already a running or pending migration for this schedule
|
|
$existingRun = MigrationRun::where('schedule_id', $schedule->id)
|
|
->whereIn('status', ['pending', 'running'])
|
|
->latest()
|
|
->first();
|
|
|
|
if ($existingRun) {
|
|
return redirect()->back()
|
|
->with('warning', 'Миграция уже выполняется или ожидает в очереди.');
|
|
}
|
|
|
|
$migrationRun = MigrationRun::create([
|
|
'schedule_id' => $schedule->id,
|
|
'status' => 'pending',
|
|
'total_tables' => count($schedule->tables),
|
|
]);
|
|
|
|
RunMigrationJob::dispatch($migrationRun)->onQueue('default');
|
|
|
|
return redirect()->back()
|
|
->with('success', 'Миграция запущена.');
|
|
}
|
|
|
|
public function toggle(MigrationSchedule $schedule)
|
|
{
|
|
$schedule->update(['is_active' => !$schedule->is_active]);
|
|
|
|
return redirect()->back()
|
|
->with('success', 'Schedule ' . ($schedule->is_active ? 'activated' : 'deactivated') . '.');
|
|
}
|
|
|
|
public function show(MigrationSchedule $schedule)
|
|
{
|
|
$schedule->load(['sourceDatabase', 'targetDatabase', 'scheduledTables']);
|
|
|
|
$runs = MigrationRun::where('schedule_id', $schedule->id)
|
|
->orderBy('created_at', 'desc')
|
|
->limit(50)
|
|
->get();
|
|
|
|
return Inertia::render('Migrations/Show', [
|
|
'schedule' => $schedule,
|
|
'runs' => $runs,
|
|
]);
|
|
}
|
|
}
|