TransactionManager   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 131
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 40
dl 0
loc 131
ccs 44
cts 44
cp 1
rs 10
c 2
b 0
f 0
wmc 14

9 Methods

Rating   Name   Duplication   Size   Complexity  
A abort() 0 10 1
A getTransaction() 0 9 2
A begin() 0 11 1
A getTransactions() 0 3 1
A commit() 0 10 1
A __construct() 0 3 1
A abortRunningTransactions() 0 6 2
A prepareCollections() 0 9 1
A validateId() 0 13 4
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ArangoClient\Transactions;
6
7
use ArangoClient\ArangoClient;
8
use ArangoClient\Exceptions\ArangoException;
9
use ArangoClient\Manager;
10
11
/**
12
 * Class TransactionManager
13
 * Begins transactions and manages those transactions.
14
 *
15
 * @see https://www.arangodb.com/docs/stable/http/transaction-stream-transaction.html
16
 */
17
class TransactionManager extends Manager
18
{
19
    /**
20
     * @var array<string>
21
     */
22
    protected array $transactions = [];
23
24 27
    public function __construct(protected ArangoClient $arangoClient)
25
    {
26 27
        register_shutdown_function([$this, 'abortRunningTransactions']);
27
    }
28
29
    /**
30
     * @return string[]
31
     */
32 6
    public function getTransactions(): array
33
    {
34 6
        return $this->transactions;
35
    }
36
37
    /**
38
     * @throws ArangoException
39
     */
40 24
    public function getTransaction(?string $id = null): string
41
    {
42 24
        $this->validateId($id);
43
44 11
        if ($id === null) {
45 9
            return (string) end($this->transactions);
46
        }
47
48 2
        return $this->transactions[$id];
49
    }
50
51
    /**
52
     * Begin a transactions and return its id.
53
     *
54
     * @param  array<string, array<string>>  $collections
55
     * @param  array<mixed>  $options
56
     *
57
     * @throws ArangoException
58
     */
59 12
    public function begin(array $collections = [], array $options = []): string
60
    {
61 12
        $options['collections'] = $this->prepareCollections($collections);
62
63 12
        $config = ['body' => $options];
64 12
        $result = (object) $this->arangoClient->request('post', '/_api/transaction/begin', $config)->result;
65
66 12
        $id = (string) $result->id;
67 12
        $this->transactions[$id] = $id;
68
69 12
        return $id;
70
    }
71
72
    /**
73
     * @throws ArangoException
74
     */
75 2
    public function commit(?string $id = null): bool
76
    {
77 2
        $id = $this->getTransaction($id);
78
79 2
        $uri = '/_api/transaction/' . $id;
80
81 2
        $this->arangoClient->request('put', $uri);
82 2
        unset($this->transactions[$id]);
83
84 2
        return true;
85
    }
86
87
    /**
88
     * @throws ArangoException
89
     */
90 10
    public function abort(?string $id = null): bool
91
    {
92 10
        $id = $this->getTransaction($id);
93
94 8
        $uri = '/_api/transaction/' . $id;
95
96 8
        $this->arangoClient->request('delete', $uri);
97 8
        unset($this->transactions[$id]);
98
99 8
        return true;
100
    }
101
102
    /**
103
     * @throws ArangoException
104
     */
105 24
    protected function validateId(?string $id = null): bool
106
    {
107
        if (
108 24
            empty($this->transactions)
109
            || (
110 24
                $id !== null
111 24
                && !isset($this->transactions[$id])
112
            )
113
        ) {
114 15
            throw new ArangoException('Transaction not found.', 404);
115
        }
116
117 11
        return true;
118
    }
119
120
    /**
121
     * @param  array<string, array<string>>  $collections
122
     * @return array<string, array<string>>
123
     */
124 12
    protected function prepareCollections(array $collections): array
125
    {
126 12
        $collectionTemplate = [
127 12
            'read' => [],
128 12
            'write' => [],
129 12
            'exclusive' => [],
130 12
        ];
131
132 12
        return array_intersect_key(array_merge($collectionTemplate, $collections), $collectionTemplate);
133
    }
134
135
    /**
136
     * Cleanup any open transactions on shutdown as registered in the constructor.
137
     *
138
     * @see TransactionManager::__construct
139
     *
140
     * @throws ArangoException
141
     */
142 2
    public function abortRunningTransactions(): void
143
    {
144 2
        foreach ($this->transactions as $id) {
145
            try {
146 2
                $this->abort($id);
147
            } finally {
148
                // Ignore any errors, this is just for clean up.
149
            }
150
        }
151
    }
152
}
153