aboutsummaryrefslogtreecommitdiffhomepage
path: root/services/app/src/AlbCtl.php
blob: fb08abaff9746f54d7cbef07fab9505f4b6f3066 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
<?php

declare(strict_types=1);

namespace Nsfisis\Albatross;

use Nsfisis\Albatross\Database\Connection;
use Nsfisis\Albatross\Migrations\MigrationManager;
use Nsfisis\Albatross\Repositories\AnswerRepository;
use Nsfisis\Albatross\Repositories\QuizRepository;
use Nsfisis\Albatross\Repositories\UserRepository;

final class AlbCtl
{
    private Connection $conn;

    public function __construct(
        Config $config,
    ) {
        $this->conn = new Connection(
            driver: 'pgsql',
            host: $config->dbHost,
            port: $config->dbPort,
            name: $config->dbName,
            user: $config->dbUser,
            password: $config->dbPassword,
            max_tries: 10,
            sleep_sec: 3,
        );
    }

    /**
     * @param list<string> $argv
     */
    public function run(array $argv): void
    {
        match ($argv[1] ?? 'help') {
            'migrate' => $this->runMigrate(),
            'promote' => $this->runPromote(),
            'deluser' => $this->runDeleteUser(),
            'delquiz' => $this->runDeleteQuiz(),
            default => $this->runHelp(),
        };
    }

    private function runMigrate(): void
    {
        $migration_manager = new MigrationManager($this->conn);
        $migration_manager->execute();
    }

    private function runPromote(): void
    {
        echo "Username: ";
        $username = trim((string)fgets(STDIN));

        $user_repo = new UserRepository($this->conn);
        $user = $user_repo->findByUsername($username);
        if ($user === null) {
            echo "User '$username' not found.\n";
            return;
        }
        $user_repo->update(
            user_id: $user->user_id,
            is_admin: true,
        );
    }

    private function runDeleteUser(): void
    {
        echo "Username: ";
        $username = trim((string)fgets(STDIN));

        $user_repo = new UserRepository($this->conn);
        $answer_repo = new AnswerRepository($this->conn);

        $this->conn->transaction(function () use ($user_repo, $answer_repo, $username) {
            $user = $user_repo->findByUsername($username);
            if ($user === null) {
                echo "User '$username' not found.\n";
                return;
            }
            $answer_repo->deleteAllByUserId($user->user_id);
            $user_repo->delete($user->user_id);
        });
        // It is unnecessary to destroy existing sessions here because
        // CurrentUserMiddleware will check whether the user exists or not.
    }

    private function runDeleteQuiz(): void
    {
        echo "Quiz ID: ";
        $quiz_id = (int)trim((string)fgets(STDIN));

        $answer_repo = new AnswerRepository($this->conn);
        $quiz_repo = new QuizRepository($this->conn);

        $this->conn->transaction(function () use ($answer_repo, $quiz_repo, $quiz_id) {
            $answer_repo->deleteAllByQuizId($quiz_id);
            $quiz_repo->delete($quiz_id);
        });
    }

    private function runHelp(): void
    {
        echo <<<EOS
        Usage: albctl <command>

        Commands:
          migrate  Run database migrations.
          promote  Promote a user to administrator.
          deluser  Delete a user.
          delquiz  Delete a quiz.
        EOS;
    }
}