1<?php
2
3// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the GNU Affero General Public License v3.0.
4// See the LICENCE file in the repository root for full licence text.
5
6namespace App\Libraries;
7
8use Illuminate\Database\ConnectionInterface;
9
10class TransactionStateManager
11{
12 private array $states;
13
14 public function __construct()
15 {
16 $this->resetStates();
17 }
18
19 public function isCompleted()
20 {
21 foreach ($this->states as $_name => $state) {
22 if (!$state->isCompleted()) {
23 return false;
24 }
25 }
26
27 return true;
28 }
29
30 public function begin(ConnectionInterface $connection)
31 {
32 $name = $connection->getName();
33
34 $this->push($name, new TransactionState($connection));
35 }
36
37 public function commit()
38 {
39 if ($this->isCompleted()) {
40 foreach ($this->states as $_name => $state) {
41 $state->commit();
42 }
43 $this->resetStates();
44 }
45 }
46
47 public function current(string $name)
48 {
49 return $this->states[$name] ?? $this->states[''];
50 }
51
52 public function rollback()
53 {
54 if ($this->isCompleted()) {
55 foreach ($this->states as $_name => $state) {
56 $state->rollback();
57 }
58 $this->resetStates();
59 }
60 }
61
62 private function push(string $name, $item)
63 {
64 $this->states[$name] ??= $item;
65 }
66
67 private function resetStates(): void
68 {
69 // for handling cases outside of transactions.
70 $this->states = ['' => new TransactionState(null)];
71 }
72}