aboutsummaryrefslogtreecommitdiffhomepage
path: root/services/app/src/Repositories/UserRepository.php
blob: adca39758486f03ac881997aed206854f2cd72f1 (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
117
118
119
120
121
122
123
124
125
126
127
<?php

declare(strict_types=1);

namespace Nsfisis\Albatross\Repositories;

use Nsfisis\Albatross\Database\Connection;
use Nsfisis\Albatross\Exceptions\EntityValidationException;
use Nsfisis\Albatross\Models\User;
use PDOException;

final class UserRepository
{
    public function __construct(
        private readonly Connection $conn,
    ) {
    }

    /**
     * @return User[]
     */
    public function listAll(): array
    {
        $result = $this->conn
            ->query()
            ->select('users')
            ->fields(['user_id', 'username', 'is_admin'])
            ->orderBy([['user_id', 'ASC']])
            ->execute();
        return array_map($this->mapRawRowToUser(...), $result);
    }

    public function findById(int $user_id): ?User
    {
        $result = $this->conn
            ->query()
            ->select('users')
            ->fields(['user_id', 'username', 'is_admin'])
            ->where('user_id = :user_id')
            ->first()
            ->execute(['user_id' => $user_id]);
        return isset($result) ? $this->mapRawRowToUser($result) : null;
    }

    public function findByUsername(string $username): ?User
    {
        $result = $this->conn
            ->query()
            ->select('users')
            ->fields(['user_id', 'username', 'is_admin'])
            ->where('username = :username')
            ->first()
            ->execute(['username' => $username]);
        return isset($result) ? $this->mapRawRowToUser($result) : null;
    }

    /**
     * @return positive-int
     */
    public function create(
        string $username,
        bool $is_admin,
    ): int {
        $user = User::create(
            username: $username,
            is_admin: $is_admin,
        );

        try {
            return $this->conn
                ->query()
                ->insert('users')
                ->values([
                    'username' => $user->username,
                    'is_admin' => +$user->is_admin,
                ])
                ->execute();
        } catch (PDOException $e) {
            throw new EntityValidationException(
                message: 'ユーザの作成に失敗しました',
                previous: $e,
            );
        }
    }

    public function update(
        int $user_id,
        bool $is_admin,
    ): void {
        $this->conn
            ->query()
            ->update('users')
            ->set([
                'is_admin' => +$is_admin,
            ])
            ->where('user_id = :user_id')
            ->execute(['user_id' => $user_id]);
    }

    public function delete(int $user_id): void
    {
        $this->conn
            ->query()
            ->delete('users')
            ->where('user_id = :user_id')
            ->execute(['user_id' => $user_id]);
    }

    /**
     * @param array<string, string> $row
     */
    private function mapRawRowToUser(array $row): User
    {
        assert(isset($row['user_id']));
        assert(isset($row['username']));
        assert(isset($row['is_admin']));

        $user_id = (int) $row['user_id'];
        $is_admin = (bool) $row['is_admin'];

        return new User(
            user_id: $user_id,
            username: $row['username'],
            is_admin: $is_admin,
        );
    }
}