DatabaseOverridesRepository.php 5.38 KB
Newer Older
1
2
3
4
5
<?php


namespace Source\Gateways\Overrides;

Jacob Priddy's avatar
Jacob Priddy committed
6
7
8
use Carbon\Carbon;
use Source\Sanitize\CastsTo;
use Source\Entities\Override;
9
use Illuminate\Support\Facades\Log;
10
use Source\Gateways\PostgresSQLCodes;
11
use Illuminate\Database\QueryException;
12
13
use Illuminate\Database\ConnectionInterface;
use Source\Exceptions\EntityNotFoundException;
Jacob Priddy's avatar
Jacob Priddy committed
14

15
16
class DatabaseOverridesRepository implements OverridesRepository
{
Jacob Priddy's avatar
Jacob Priddy committed
17
18
    use CastsTo;

19
20
21
22
23
24
25
26
27
28
    /**
     * @var \Illuminate\Database\ConnectionInterface
     */
    protected ConnectionInterface $db;

    public function __construct(ConnectionInterface $db)
    {
        $this->db = $db;
    }

Jacob Priddy's avatar
Jacob Priddy committed
29
30
31
32
33
34
35
36
    /**
     * @param \App\Override $override
     * @return \Source\Entities\Override
     */
    protected static function toOverride(\App\Override $override): Override
    {
        return new Override(
            $override->getAttribute('id'),
37
            $override->getAttribute('reason'),
Jacob Priddy's avatar
Jacob Priddy committed
38
39
40
41
42
43
44
45
46
47
            $override->getAttribute('user_id'),
            $override->getAttribute('door_id'),
            $override->getAttribute('type'),
            $override->getAttribute('start'),
            $override->getAttribute('end'),
            $override->getAttribute('created_at'),
            $override->getAttribute('updated_at')
        );
    }

48
49
50
51
52
53
54
55
56
57
58
59
    /**
     * @param $override
     * @return \Source\Entities\Override
     */
    protected function toOverrideFromRaw($override): Override
    {
        return new Override(
            $override->id,
            $override->reason,
            $override->user_id,
            $override->door_id,
            $override->type,
60
61
62
63
            self::castToCarbon($override->start),
            self::castToCarbon($override->end),
            self::castToCarbon($override->created_at),
            self::castToCarbon($override->updated_at)
64
65
66
        );
    }

Jacob Priddy's avatar
Jacob Priddy committed
67
68
69
    /**
     * @inheritDoc
     */
70
    public function filterHistory(?string $doorId, ?string $userId, ?Carbon $begin, ?Carbon $end): array
Jacob Priddy's avatar
Jacob Priddy committed
71
    {
72
        $query = \App\Override::query()->orderByDesc('created_at');
Jacob Priddy's avatar
Jacob Priddy committed
73

74
        if ($doorId) {
75
            $query->where('door_id', self::castToInt($doorId));
76
        }
Jacob Priddy's avatar
Jacob Priddy committed
77

78
        if ($userId) {
79
            $query->where('user_id', self::castToInt($userId));
80
        }
81

82
83
        if ($begin && $end) {
            $query->whereRaw('((:BEGIN, :END) OVERLAPS ("start", "end"))', [':BEGIN' => $begin, ':END' => $end]);
Jacob Priddy's avatar
Jacob Priddy committed
84
        } elseif ($begin) {
85
            $query->where('end', '>', $begin);
Jacob Priddy's avatar
Jacob Priddy committed
86
        } elseif ($end) {
87
            $query->where('start', '<', $end);
88
        }
89

90
91
92
        return array_map(static function (\App\Override $override) {
            return self::toOverride($override);
        }, $query->get()->values()->all());
Jacob Priddy's avatar
Jacob Priddy committed
93
94
95
96
97
    }

    /**
     * @inheritDoc
     */
98
    public function activeOverrideForDoorBetween(string $doorId, Carbon $begin, Carbon $end): ?Override
Jacob Priddy's avatar
Jacob Priddy committed
99
    {
100
101
102
103
104
105
106
107
108
109
        $query = <<<QUERY
select A.id, A.reason, A.user_id, A.door_id, A.type, A.start, A.end, A.created_at, A.updated_at
from overrides as A
WHERE A.door_id = :DOOR_ID
  AND ((:BEGIN, :END) OVERLAPS (A.start, A.end))
  ORDER BY A.created_at DESC
  LIMIT 1
QUERY;

        $override = $this->db->selectOne($query, [
110
            ':DOOR_ID' => self::castToInt($doorId),
111
112
113
            ':BEGIN' => $begin,
            ':END' => $end,
        ]);
Jacob Priddy's avatar
Jacob Priddy committed
114
115
116
117
118

        if (!$override) {
            return null;
        }

119
        return $this->toOverrideFromRaw($override);
Jacob Priddy's avatar
Jacob Priddy committed
120
121
122
    }

    /**
Jacob Priddy's avatar
Jacob Priddy committed
123
124
125
     * @param \App\Override             $o
     * @param \Source\Entities\Override $override
     * @throws \Source\Exceptions\EntityNotFoundException
Jacob Priddy's avatar
Jacob Priddy committed
126
     */
Jacob Priddy's avatar
Jacob Priddy committed
127
    protected function saveOverride(\App\Override $o, Override $override): void
Jacob Priddy's avatar
Jacob Priddy committed
128
129
130
131
132
133
    {
        $o->setAttribute('user_id', $override->getUserId());
        $o->setAttribute('door_id', $override->getDoorId());
        $o->setAttribute('type', $override->getType());
        $o->setAttribute('start', $override->getStart());
        $o->setAttribute('end', $override->getEnd());
134
        $o->setAttribute('reason', $override->getReason());
Jacob Priddy's avatar
Jacob Priddy committed
135

136
137
138
        try {
            $o->save();
        } catch (QueryException $e) {
139
            if ($e->getCode() === PostgresSQLCodes::FOREIGN_KEY_VIOLATION) {
Jacob Priddy's avatar
Jacob Priddy committed
140
                throw new EntityNotFoundException('Cannot save override because the specified user or door does not exist.');
141
142
            }

Jacob Priddy's avatar
Jacob Priddy committed
143
            Log::error('Failed saving override: ' . $e);
144
145
146

            throw $e;
        }
Jacob Priddy's avatar
Jacob Priddy committed
147
148
149
150
151
152
153
154
155
156
157
158
159
160
    }

    /**
     * @inheritDoc
     */
    public function addOverride(Override $override): Override
    {
        $o = new \App\Override();

        if ($override->getCreatedAt()) {
            $o->setCreatedAt($override->getCreatedAt());
        }

        $this->saveOverride($o, $override);
Jacob Priddy's avatar
Jacob Priddy committed
161
162
163

        return self::toOverride($o);
    }
164
165
166
167

    /**
     * @inheritDoc
     */
Jacob Priddy's avatar
Jacob Priddy committed
168
    public function updateOverride(string $overrideId, Override $override): Override
169
170
    {
        /** @var \App\Override $o */
171
        $o = \App\Override::query()->find(self::castToInt($overrideId));
172
173
174
175
176

        if (!$o) {
            throw new EntityNotFoundException('Override with id "' . $overrideId . '" does not exist.');
        }

Jacob Priddy's avatar
Jacob Priddy committed
177
        $this->saveOverride($o, $override);
178
179
180

        return self::toOverride($o);
    }
181
182
183
184
185
186
187

    /**
     * @inheritDoc
     */
    public function get(string $overrideId): ?Override
    {
        /** @var \App\Override $o */
188
        $o = \App\Override::query()->find(self::castToInt($overrideId));
189
190
191
192
193
194
195

        if (!$o) {
            return null;
        }

        return self::toOverride($o);
    }
196
}