mirror of
https://github.com/crivion/laranode.git
synced 2026-05-06 13:41:02 +08:00
mysql manager: refactoring to services & actions to keep my controller clean
This commit is contained in:
46
app/Actions/MySQL/GetCharsetsAndCollationsAction.php
Normal file
46
app/Actions/MySQL/GetCharsetsAndCollationsAction.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\MySQL;
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class GetCharsetsAndCollationsAction
|
||||
{
|
||||
public function execute(): array
|
||||
{
|
||||
return [
|
||||
'charsets' => $this->getCharsets(),
|
||||
'collations' => $this->getCollations(),
|
||||
];
|
||||
}
|
||||
|
||||
private function getCharsets(): array
|
||||
{
|
||||
$charsets = DB::select("SHOW CHARACTER SET");
|
||||
|
||||
return collect($charsets)->map(function($charset) {
|
||||
return [
|
||||
'name' => $charset->Charset,
|
||||
'description' => $charset->Description,
|
||||
'default_collation' => $charset->{'Default collation'},
|
||||
'maxlen' => $charset->Maxlen,
|
||||
];
|
||||
})->toArray();
|
||||
}
|
||||
|
||||
private function getCollations(): array
|
||||
{
|
||||
$collations = DB::select("SHOW COLLATION");
|
||||
|
||||
return collect($collations)->map(function($collation) {
|
||||
return [
|
||||
'name' => $collation->Collation,
|
||||
'charset' => $collation->Charset,
|
||||
'id' => $collation->Id,
|
||||
'default' => $collation->Default,
|
||||
'compiled' => $collation->Compiled,
|
||||
'sortlen' => $collation->Sortlen,
|
||||
];
|
||||
})->toArray();
|
||||
}
|
||||
}
|
||||
68
app/Actions/MySQL/GetDatabasesWithStatsAction.php
Normal file
68
app/Actions/MySQL/GetDatabasesWithStatsAction.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\MySQL;
|
||||
|
||||
use App\Models\Database;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class GetDatabasesWithStatsAction
|
||||
{
|
||||
public function __construct(private User $user) {}
|
||||
|
||||
public function execute(): array
|
||||
{
|
||||
$databases = Database::where('user_id', $this->user->id)->get();
|
||||
$items = [];
|
||||
|
||||
foreach ($databases as $database) {
|
||||
$items[] = $this->buildDatabaseItem($database);
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
private function buildDatabaseItem(Database $database): array
|
||||
{
|
||||
$dbName = $database->name;
|
||||
|
||||
// Get table count
|
||||
$tableCount = $this->getTableCount($dbName);
|
||||
|
||||
// Get database size
|
||||
$sizeMb = $this->getDatabaseSize($dbName);
|
||||
|
||||
return [
|
||||
'id' => $database->id,
|
||||
'name' => $database->name,
|
||||
'user' => $this->user->username,
|
||||
'db_user' => $database->db_user,
|
||||
'tables' => $tableCount,
|
||||
'sizeMb' => $sizeMb,
|
||||
'charset' => $database->charset,
|
||||
'collation' => $database->collation,
|
||||
];
|
||||
}
|
||||
|
||||
private function getTableCount(string $dbName): int
|
||||
{
|
||||
$tables = DB::select(
|
||||
"SELECT COUNT(*) as cnt FROM information_schema.tables WHERE table_schema = ?",
|
||||
[$dbName]
|
||||
);
|
||||
|
||||
return (int) ($tables[0]->cnt ?? 0);
|
||||
}
|
||||
|
||||
private function getDatabaseSize(string $dbName): float
|
||||
{
|
||||
$sizeRow = DB::selectOne(
|
||||
"SELECT ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS size_mb
|
||||
FROM information_schema.tables
|
||||
WHERE table_schema = ?",
|
||||
[$dbName]
|
||||
);
|
||||
|
||||
return (float) ($sizeRow->size_mb ?? 0);
|
||||
}
|
||||
}
|
||||
@@ -2,206 +2,81 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Inertia\Inertia;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Support\Facades\Process;
|
||||
use App\Actions\MySQL\GetCharsetsAndCollationsAction;
|
||||
use App\Actions\MySQL\GetDatabasesWithStatsAction;
|
||||
use App\Http\Requests\CreateDatabaseRequest;
|
||||
use App\Http\Requests\DeleteDatabaseRequest;
|
||||
use App\Http\Requests\UpdateDatabaseRequest;
|
||||
use App\Models\Database;
|
||||
use App\Services\MySQL\CreateDatabaseService;
|
||||
use App\Services\MySQL\DeleteDatabaseService;
|
||||
use App\Services\MySQL\UpdateDatabaseService;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Inertia\Inertia;
|
||||
|
||||
class MysqlController extends Controller
|
||||
{
|
||||
|
||||
public function index(Request $request): \Inertia\Response
|
||||
{
|
||||
$user = $request->user();
|
||||
|
||||
// Get databases from our model for the current user
|
||||
$databases = Database::where('user_id', $user->id)->get();
|
||||
|
||||
$items = [];
|
||||
foreach ($databases as $database) {
|
||||
// Get additional info from MySQL
|
||||
$dbName = $database->name;
|
||||
|
||||
// number of tables
|
||||
$tables = DB::select("SELECT COUNT(*) as cnt FROM information_schema.tables WHERE table_schema = ?", [$dbName]);
|
||||
$tableCount = (int) ($tables[0]->cnt ?? 0);
|
||||
|
||||
// total size (data + index)
|
||||
$sizeRow = DB::selectOne("SELECT ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS size_mb FROM information_schema.tables WHERE table_schema = ?", [$dbName]);
|
||||
$sizeMb = (float) ($sizeRow->size_mb ?? 0);
|
||||
|
||||
$items[] = [
|
||||
'id' => $database->id,
|
||||
'name' => $database->name,
|
||||
'user' => $user->username,
|
||||
'db_user' => $database->db_user,
|
||||
'tables' => $tableCount,
|
||||
'sizeMb' => $sizeMb,
|
||||
'charset' => $database->charset,
|
||||
'collation' => $database->collation,
|
||||
];
|
||||
}
|
||||
$databases = (new GetDatabasesWithStatsAction($user))->execute();
|
||||
|
||||
return Inertia::render('Mysql/Index', [
|
||||
'databases' => $items,
|
||||
'databases' => $databases,
|
||||
]);
|
||||
}
|
||||
|
||||
public function getCharsetsAndCollations()
|
||||
public function getCharsetsAndCollations(GetCharsetsAndCollationsAction $action): JsonResponse
|
||||
{
|
||||
// Get available character sets
|
||||
$charsets = DB::select("SHOW CHARACTER SET");
|
||||
$charsetData = collect($charsets)->map(function($charset) {
|
||||
return [
|
||||
'name' => $charset->Charset,
|
||||
'description' => $charset->Description,
|
||||
'default_collation' => $charset->{'Default collation'},
|
||||
'maxlen' => $charset->Maxlen,
|
||||
];
|
||||
});
|
||||
|
||||
// Get available collations
|
||||
$collations = DB::select("SHOW COLLATION");
|
||||
$collationData = collect($collations)->map(function($collation) {
|
||||
return [
|
||||
'name' => $collation->Collation,
|
||||
'charset' => $collation->Charset,
|
||||
'id' => $collation->Id,
|
||||
'default' => $collation->Default,
|
||||
'compiled' => $collation->Compiled,
|
||||
'sortlen' => $collation->Sortlen,
|
||||
];
|
||||
});
|
||||
|
||||
return response()->json([
|
||||
'charsets' => $charsetData,
|
||||
'collations' => $collationData,
|
||||
]);
|
||||
return response()->json($action->execute());
|
||||
}
|
||||
|
||||
public function store(Request $request)
|
||||
public function store(CreateDatabaseRequest $request): RedirectResponse
|
||||
{
|
||||
$request->validate([
|
||||
'name' => ['required', 'string'],
|
||||
'db_user' => ['required', 'string'],
|
||||
'db_pass' => ['required', 'string'],
|
||||
'charset' => ['required', 'string'],
|
||||
'collation' => ['required', 'string'],
|
||||
]);
|
||||
|
||||
$user = $request->user();
|
||||
$prefix = $user->username . '_';
|
||||
|
||||
(new CreateDatabaseService($request->validated(), $user))->handle();
|
||||
|
||||
$name = $request->string('name');
|
||||
$dbUser = $request->string('db_user');
|
||||
$dbPass = $request->string('db_pass');
|
||||
$charset = $request->string('charset');
|
||||
$collation = $request->string('collation');
|
||||
session()->flash('success', 'Database created successfully!');
|
||||
|
||||
if (!str_starts_with($name, $prefix)) {
|
||||
return back()->withErrors(['name' => 'Database name must start with ' . $prefix]);
|
||||
}
|
||||
|
||||
if (!str_starts_with($dbUser, $prefix)) {
|
||||
return back()->withErrors(['db_user' => 'Database username must start with ' . $prefix]);
|
||||
}
|
||||
|
||||
// Create database with charset and collation
|
||||
DB::statement("CREATE DATABASE `$name` CHARACTER SET $charset COLLATE $collation");
|
||||
|
||||
// Create user (if not exists) and grant all privileges on the new DB
|
||||
DB::statement("CREATE USER IF NOT EXISTS `$dbUser`@'localhost' IDENTIFIED BY '$dbPass'");
|
||||
DB::statement("GRANT ALL PRIVILEGES ON `$name`.* TO `$dbUser`@'localhost'");
|
||||
DB::statement("FLUSH PRIVILEGES");
|
||||
|
||||
// Create database record in our model
|
||||
Database::create([
|
||||
'name' => $name,
|
||||
'db_user' => $dbUser,
|
||||
'db_password' => $dbPass,
|
||||
'charset' => $charset,
|
||||
'collation' => $collation,
|
||||
'user_id' => $user->id,
|
||||
]);
|
||||
|
||||
return redirect()->route('mysql.index')->with('success', 'Database created successfully.');
|
||||
return redirect()->route('mysql.index');
|
||||
}
|
||||
|
||||
public function update(Request $request)
|
||||
public function update(UpdateDatabaseRequest $request): RedirectResponse
|
||||
{
|
||||
$request->validate([
|
||||
'id' => ['required', 'integer'],
|
||||
'charset' => ['required', 'string'],
|
||||
'collation' => ['required', 'string'],
|
||||
'db_password' => ['nullable', 'string'],
|
||||
]);
|
||||
|
||||
$user = $request->user();
|
||||
$databaseId = $request->integer('id');
|
||||
$charset = $request->string('charset');
|
||||
$collation = $request->string('collation');
|
||||
$newPassword = $request->string('db_password');
|
||||
|
||||
// Find the database record
|
||||
$database = Database::where('id', $databaseId)
|
||||
->where('user_id', $user->id)
|
||||
->firstOrFail();
|
||||
|
||||
$name = $database->name;
|
||||
$this->authorize('update', $database);
|
||||
|
||||
// Update database charset and collation in MySQL
|
||||
DB::statement("ALTER DATABASE `$name` CHARACTER SET $charset COLLATE $collation");
|
||||
(new UpdateDatabaseService($database, $request->validated()))->handle();
|
||||
|
||||
// Update the database record
|
||||
$updateData = [
|
||||
'charset' => $charset,
|
||||
'collation' => $collation,
|
||||
];
|
||||
session()->flash('success', 'Database updated successfully!');
|
||||
|
||||
// Update password if provided
|
||||
if ($request->filled('db_password')) {
|
||||
$updateData['db_password'] = $newPassword;
|
||||
|
||||
// Update MySQL user password
|
||||
DB::statement("ALTER USER `{$database->db_user}`@'localhost' IDENTIFIED BY '$newPassword'");
|
||||
DB::statement("FLUSH PRIVILEGES");
|
||||
}
|
||||
|
||||
$database->update($updateData);
|
||||
|
||||
return redirect()->route('mysql.index')->with('success', 'Database charset and collation updated successfully.');
|
||||
return redirect()->route('mysql.index');
|
||||
}
|
||||
|
||||
|
||||
public function destroy(Request $request)
|
||||
public function destroy(DeleteDatabaseRequest $request): RedirectResponse
|
||||
{
|
||||
$request->validate([
|
||||
'id' => ['required', 'integer'],
|
||||
]);
|
||||
|
||||
$user = $request->user();
|
||||
$databaseId = $request->integer('id');
|
||||
|
||||
// Find the database record
|
||||
$database = Database::where('id', $databaseId)
|
||||
->where('user_id', $user->id)
|
||||
->firstOrFail();
|
||||
|
||||
$name = $database->name;
|
||||
$dbUser = $database->db_user;
|
||||
$this->authorize('delete', $database);
|
||||
|
||||
// Drop the MySQL database
|
||||
DB::statement("DROP DATABASE IF EXISTS `$name`");
|
||||
(new DeleteDatabaseService($database))->handle();
|
||||
|
||||
// Drop the MySQL user
|
||||
DB::statement("DROP USER IF EXISTS `$dbUser`@'localhost'");
|
||||
DB::statement("FLUSH PRIVILEGES");
|
||||
session()->flash('success', 'Database deleted successfully!');
|
||||
|
||||
// Delete the database record
|
||||
$database->delete();
|
||||
|
||||
return redirect()->route('mysql.index')->with('success', 'Database deleted successfully.');
|
||||
return redirect()->route('mysql.index');
|
||||
}
|
||||
}
|
||||
|
||||
63
app/Http/Requests/CreateDatabaseRequest.php
Normal file
63
app/Http/Requests/CreateDatabaseRequest.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use App\Models\Database;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class CreateDatabaseRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true; // Authorization handled by policy
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
$user = $this->user();
|
||||
$prefix = $user->username . '_';
|
||||
|
||||
return [
|
||||
'name' => [
|
||||
'required',
|
||||
'string',
|
||||
'max:64',
|
||||
'regex:/^' . preg_quote($prefix) . '[a-zA-Z0-9_]+$/',
|
||||
'unique:' . Database::class . ',name'
|
||||
],
|
||||
'db_user' => [
|
||||
'required',
|
||||
'string',
|
||||
'max:32',
|
||||
'regex:/^' . preg_quote($prefix) . '[a-zA-Z0-9_]+$/'
|
||||
],
|
||||
'db_pass' => ['required', 'string', 'min:8'],
|
||||
'charset' => ['required', 'string'],
|
||||
'collation' => ['required', 'string'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get custom messages for validator errors.
|
||||
*/
|
||||
public function messages(): array
|
||||
{
|
||||
$user = $this->user();
|
||||
$prefix = $user->username . '_';
|
||||
|
||||
return [
|
||||
'name.regex' => 'Database name must start with ' . $prefix . ' and contain only letters, numbers, and underscores.',
|
||||
'db_user.regex' => 'Database username must start with ' . $prefix . ' and contain only letters, numbers, and underscores.',
|
||||
'name.unique' => 'A database with this name already exists.',
|
||||
];
|
||||
}
|
||||
}
|
||||
28
app/Http/Requests/DeleteDatabaseRequest.php
Normal file
28
app/Http/Requests/DeleteDatabaseRequest.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class DeleteDatabaseRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true; // Authorization handled by policy
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'id' => ['required', 'integer'],
|
||||
];
|
||||
}
|
||||
}
|
||||
31
app/Http/Requests/UpdateDatabaseRequest.php
Normal file
31
app/Http/Requests/UpdateDatabaseRequest.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdateDatabaseRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true; // Authorization handled by policy
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'id' => ['required', 'integer'],
|
||||
'charset' => ['required', 'string'],
|
||||
'collation' => ['required', 'string'],
|
||||
'db_password' => ['nullable', 'string', 'min:8'],
|
||||
];
|
||||
}
|
||||
}
|
||||
39
app/Policies/DatabasePolicy.php
Normal file
39
app/Policies/DatabasePolicy.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Models\Database;
|
||||
use Illuminate\Auth\Access\Response;
|
||||
|
||||
class DatabasePolicy
|
||||
{
|
||||
/**
|
||||
* Create a new policy instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
public function view(User $user, Database $database): Response
|
||||
{
|
||||
return ($user->isAdmin() || $user->id === $database->user_id)
|
||||
? Response::allow()
|
||||
: Response::deny('You are not authorized to view this database.');
|
||||
}
|
||||
|
||||
public function update(User $user, Database $database): Response
|
||||
{
|
||||
return ($user->isAdmin() || $user->id === $database->user_id)
|
||||
? Response::allow()
|
||||
: Response::deny('You are not authorized to update this database.');
|
||||
}
|
||||
|
||||
public function delete(User $user, Database $database): Response
|
||||
{
|
||||
return ($user->isAdmin() || $user->id === $database->user_id)
|
||||
? Response::allow()
|
||||
: Response::deny('You are not authorized to delete this database.');
|
||||
}
|
||||
}
|
||||
30
app/Providers/AuthServiceProvider.php
Normal file
30
app/Providers/AuthServiceProvider.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Models\Database;
|
||||
use App\Models\Website;
|
||||
use App\Policies\DatabasePolicy;
|
||||
use App\Policies\WebsitePolicy;
|
||||
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
|
||||
|
||||
class AuthServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* The model to policy mappings for the application.
|
||||
*
|
||||
* @var array<class-string, class-string>
|
||||
*/
|
||||
protected $policies = [
|
||||
Website::class => WebsitePolicy::class,
|
||||
Database::class => DatabasePolicy::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* Register any authentication / authorization services.
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
65
app/Services/MySQL/CreateDatabaseService.php
Normal file
65
app/Services/MySQL/CreateDatabaseService.php
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\MySQL;
|
||||
|
||||
use App\Models\Database;
|
||||
use App\Models\User;
|
||||
use Exception;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class CreateDatabaseException extends Exception {}
|
||||
|
||||
class CreateDatabaseService
|
||||
{
|
||||
public function __construct(private array $validated, private User $user) {}
|
||||
|
||||
public function handle(): Database
|
||||
{
|
||||
$this->createMySQLDatabase();
|
||||
$this->createMySQLUser();
|
||||
|
||||
return $this->createDatabaseRecord();
|
||||
}
|
||||
|
||||
private function createMySQLDatabase(): void
|
||||
{
|
||||
$name = $this->validated['name'];
|
||||
$charset = $this->validated['charset'];
|
||||
$collation = $this->validated['collation'];
|
||||
|
||||
try {
|
||||
DB::statement("CREATE DATABASE `$name` CHARACTER SET $charset COLLATE $collation");
|
||||
} catch (Exception $e) {
|
||||
throw new CreateDatabaseException('Failed to create MySQL database: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private function createMySQLUser(): void
|
||||
{
|
||||
$dbUser = $this->validated['db_user'];
|
||||
$dbPass = $this->validated['db_pass'];
|
||||
$name = $this->validated['name'];
|
||||
|
||||
try {
|
||||
DB::statement("CREATE USER IF NOT EXISTS `$dbUser`@'localhost' IDENTIFIED BY '$dbPass'");
|
||||
DB::statement("GRANT ALL PRIVILEGES ON `$name`.* TO `$dbUser`@'localhost'");
|
||||
DB::statement("FLUSH PRIVILEGES");
|
||||
} catch (Exception $e) {
|
||||
// Rollback database creation if user creation fails
|
||||
DB::statement("DROP DATABASE IF EXISTS `{$this->validated['name']}`");
|
||||
throw new CreateDatabaseException('Failed to create MySQL user: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private function createDatabaseRecord(): Database
|
||||
{
|
||||
return Database::create([
|
||||
'name' => $this->validated['name'],
|
||||
'db_user' => $this->validated['db_user'],
|
||||
'db_password' => $this->validated['db_pass'],
|
||||
'charset' => $this->validated['charset'],
|
||||
'collation' => $this->validated['collation'],
|
||||
'user_id' => $this->user->id,
|
||||
]);
|
||||
}
|
||||
}
|
||||
49
app/Services/MySQL/DeleteDatabaseService.php
Normal file
49
app/Services/MySQL/DeleteDatabaseService.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\MySQL;
|
||||
|
||||
use App\Models\Database;
|
||||
use Exception;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class DeleteDatabaseException extends Exception {}
|
||||
|
||||
class DeleteDatabaseService
|
||||
{
|
||||
public function __construct(private Database $database) {}
|
||||
|
||||
public function handle(): void
|
||||
{
|
||||
$this->dropMySQLDatabase();
|
||||
$this->dropMySQLUser();
|
||||
$this->deleteDatabaseRecord();
|
||||
}
|
||||
|
||||
private function dropMySQLDatabase(): void
|
||||
{
|
||||
$name = $this->database->name;
|
||||
|
||||
try {
|
||||
DB::statement("DROP DATABASE IF EXISTS `$name`");
|
||||
} catch (Exception $e) {
|
||||
throw new DeleteDatabaseException('Failed to drop MySQL database: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private function dropMySQLUser(): void
|
||||
{
|
||||
$dbUser = $this->database->db_user;
|
||||
|
||||
try {
|
||||
DB::statement("DROP USER IF EXISTS `$dbUser`@'localhost'");
|
||||
DB::statement("FLUSH PRIVILEGES");
|
||||
} catch (Exception $e) {
|
||||
throw new DeleteDatabaseException('Failed to drop MySQL user: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private function deleteDatabaseRecord(): void
|
||||
{
|
||||
$this->database->delete();
|
||||
}
|
||||
}
|
||||
65
app/Services/MySQL/UpdateDatabaseService.php
Normal file
65
app/Services/MySQL/UpdateDatabaseService.php
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\MySQL;
|
||||
|
||||
use App\Models\Database;
|
||||
use Exception;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class UpdateDatabaseException extends Exception {}
|
||||
|
||||
class UpdateDatabaseService
|
||||
{
|
||||
public function __construct(private Database $database, private array $validated) {}
|
||||
|
||||
public function handle(): void
|
||||
{
|
||||
$this->updateMySQLDatabase();
|
||||
$this->updateMySQLUserPassword();
|
||||
$this->updateDatabaseRecord();
|
||||
}
|
||||
|
||||
private function updateMySQLDatabase(): void
|
||||
{
|
||||
$name = $this->database->name;
|
||||
$charset = $this->validated['charset'];
|
||||
$collation = $this->validated['collation'];
|
||||
|
||||
try {
|
||||
DB::statement("ALTER DATABASE `$name` CHARACTER SET $charset COLLATE $collation");
|
||||
} catch (Exception $e) {
|
||||
throw new UpdateDatabaseException('Failed to update MySQL database charset/collation: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private function updateMySQLUserPassword(): void
|
||||
{
|
||||
if (!isset($this->validated['db_password']) || empty($this->validated['db_password'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$dbUser = $this->database->db_user;
|
||||
$newPassword = $this->validated['db_password'];
|
||||
|
||||
try {
|
||||
DB::statement("ALTER USER `$dbUser`@'localhost' IDENTIFIED BY '$newPassword'");
|
||||
DB::statement("FLUSH PRIVILEGES");
|
||||
} catch (Exception $e) {
|
||||
throw new UpdateDatabaseException('Failed to update MySQL user password: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private function updateDatabaseRecord(): void
|
||||
{
|
||||
$updateData = [
|
||||
'charset' => $this->validated['charset'],
|
||||
'collation' => $this->validated['collation'],
|
||||
];
|
||||
|
||||
if (isset($this->validated['db_password']) && !empty($this->validated['db_password'])) {
|
||||
$updateData['db_password'] = $this->validated['db_password'];
|
||||
}
|
||||
|
||||
$this->database->update($updateData);
|
||||
}
|
||||
}
|
||||
@@ -2,5 +2,6 @@
|
||||
|
||||
return [
|
||||
App\Providers\AppServiceProvider::class,
|
||||
App\Providers\AuthServiceProvider::class,
|
||||
Lab404\Impersonate\ImpersonateServiceProvider::class,
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user