You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
110 lines
3.5 KiB
110 lines
3.5 KiB
<?php |
|
|
|
namespace App\Http\Controllers; |
|
|
|
use App\Models\DatabaseConnection; |
|
use App\Services\DatabaseConnectionManager; |
|
use Illuminate\Http\RedirectResponse; |
|
use Illuminate\Http\Request; |
|
use Illuminate\View\View; |
|
use InvalidArgumentException; |
|
use RuntimeException; |
|
use Throwable; |
|
|
|
class DatabaseConnectionController extends Controller |
|
{ |
|
public function __construct( |
|
private readonly DatabaseConnectionManager $connections |
|
) { |
|
} |
|
|
|
public function index(): View |
|
{ |
|
return view('database-connections.index', [ |
|
'connections' => DatabaseConnection::query()->orderBy('name')->get(), |
|
'drivers' => [ |
|
'sqlsrv' => 'SQL Server', |
|
'pgsql' => 'PostgreSQL', |
|
'mysql' => 'MySQL', |
|
'mariadb' => 'MariaDB', |
|
], |
|
]); |
|
} |
|
|
|
public function store(Request $request): RedirectResponse |
|
{ |
|
$data = $this->validateConnection($request); |
|
|
|
try { |
|
$this->connections->test($data); |
|
$connection = $this->connections->store($data); |
|
$request->attributes->set('audit_metadata', [ |
|
'name' => $connection->name, |
|
'driver' => $connection->driver, |
|
'host' => $connection->host, |
|
]); |
|
|
|
return back()->with('success', "Connection [{$connection->name}] added."); |
|
} catch (RuntimeException $e) { |
|
return back()->withInput()->with('error', $e->getMessage()); |
|
} catch (Throwable) { |
|
return back()->withInput()->with('error', 'Failed to add database connection.'); |
|
} |
|
} |
|
|
|
public function test(Request $request): RedirectResponse |
|
{ |
|
$data = $this->validateConnection($request, requirePassword: true); |
|
|
|
try { |
|
$message = $this->connections->test($data); |
|
$request->attributes->set('audit_metadata', [ |
|
'driver' => $data['driver'], |
|
'host' => $data['host'], |
|
'test' => true, |
|
]); |
|
|
|
return back()->with('success', $message); |
|
} catch (RuntimeException $e) { |
|
return back()->withInput()->with('error', $e->getMessage()); |
|
} |
|
} |
|
|
|
public function destroy(Request $request, DatabaseConnection $databaseConnection): RedirectResponse |
|
{ |
|
$name = $databaseConnection->name; |
|
$request->attributes->set('audit_metadata', [ |
|
'name' => $name, |
|
'driver' => $databaseConnection->driver, |
|
'host' => $databaseConnection->host, |
|
]); |
|
$databaseConnection->delete(); |
|
|
|
return back()->with('success', "Connection [{$name}] removed."); |
|
} |
|
|
|
private function validateConnection(Request $request, bool $requirePassword = false): array |
|
{ |
|
$rules = [ |
|
'name' => ['required', 'string', 'max:100'], |
|
'driver' => ['required', 'in:sqlsrv,pgsql,mysql,mariadb'], |
|
'host' => ['required', 'string', 'max:255'], |
|
'port' => ['required', 'integer', 'min:1', 'max:65535'], |
|
'database' => ['nullable', 'string', 'max:128'], |
|
'username' => ['required', 'string', 'max:128'], |
|
'password' => [$requirePassword ? 'required' : 'nullable', 'string', 'max:255'], |
|
]; |
|
|
|
$data = $request->validate($rules); |
|
|
|
if (empty($data['port'])) { |
|
$data['port'] = match ($data['driver']) { |
|
'sqlsrv' => 1433, |
|
'pgsql' => 5432, |
|
default => 3306, |
|
}; |
|
} |
|
|
|
return $data; |
|
} |
|
}
|
|
|