Completed
Push — master ( 572dba...24cb60 )
by Thomas
02:09
created

Connection::connectionId()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
namespace Gielfeldt\TransactionalPHP;
4
5
/**
6
 * Class Connection
7
 *
8
 * @package Gielfeldt\TransactionalPHP
9
 */
10
class Connection
11
{
12
    /**
13
     * @var Operation[]
14
     */
15
    protected $operations = [];
16
17
    /**
18
     * @var int
19
     */
20
    protected $idx = 0;
21
22
    /**
23
     * @var int[]
24
     */
25
    protected $savePoints = [];
26
27
    /**
28
     * @var int
29
     */
30
    protected $depth = 0;
31
32
    /**
33
     * @var null|string
34
     */
35
    protected $connectionId;
36
37
    /**
38
     * Connection constructor.
39
     *
40
     * @param null|string $connectionId
41
     *   (optional) The id of the connection.
42
     */
43
    public function __construct($connectionId = null)
44
    {
45
        $this->connectionId = isset($connectionId) ? $connectionId : uniqid();
46
    }
47
48
    /**
49
     * Get connection id.
50
     *
51
     * @return null|string
52
     */
53
    public function connectionId()
54
    {
55
        return $this->connectionId;
56
    }
57
58
    /**
59
     * Remove savepoints to and acquire index of latest active savepoint.
60
     *
61
     * @param int $oldDepth
62
     *   The old depth.
63
     * @param $newDepth
64
     *   The new depth.
65
     *
66
     * @return int|null
67
     *   The last index, if found.
68
     */
69
    public function closeSavepoints($oldDepth, $newDepth)
0 ignored issues
show
Unused Code introduced by
The parameter $newDepth is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
70
    {
71
        $idx = null;
72
        for ($depth = $this->depth + 1; $depth <= $oldDepth; $depth++) {
73
            if (isset($this->savePoints[$depth])) {
74
                $idx = isset($idx) ? $idx : $this->savePoints[$depth];
75
                unset($this->savePoints[$depth]);
76
            }
77
        }
78
        return $idx;
79
    }
80
81
    /**
82
     * {@inheritdoc}
83
     */
84
    public function startTransaction($newDepth = null)
85
    {
86
        $this->depth = isset($newDepth) ? $newDepth : $this->depth + 1;
87
        $this->savePoints[$this->depth] = $this->idx;
88
    }
89
90
    /**
91
     * {@inheritdoc}
92
     */
93
    public function commitTransaction($newDepth = null)
94
    {
95
        $oldDepth = $this->depth;
96
        $this->depth = isset($newDepth) ? $newDepth : $oldDepth - 1;
97
        if ($this->depth < 0) {
98
            throw new \RuntimeException('Trying to commit non-existant transaction.');
99
        }
100
101
        // Remove savepoints to and acquire index of latest active savepoint.
102
        $idx = $this->closeSavepoints($oldDepth, $this->depth);
103
104
        // Is this a real commit.
105
        if ($this->depth == 0 && isset($idx)) {
106
            // Perform the operations if any found.
107
            end($this->operations);
108
            $lastIdx = key($this->operations);
109
            for ($removeIdx = $idx; $removeIdx <= $lastIdx; $removeIdx++) {
110
                $this->performOperation($removeIdx);
111
                $this->removeOperation($removeIdx);
112
            }
113
            $this->idx = $idx;
114
        }
115
    }
116
117
    /**
118
     * {@inheritdoc}
119
     */
120
    public function rollbackTransaction($newDepth = null)
121
    {
122
        $oldDepth = $this->depth;
123
        $this->depth = isset($newDepth) ? $newDepth : $oldDepth - 1;
124
        if ($this->depth < 0) {
125
            throw new \RuntimeException('Trying to rollback non-existant transaction.');
126
        }
127
128
        // Remove savepoints to and acquire index of latest active savepoint.
129
        $idx = $this->closeSavepoints($oldDepth, $this->depth);
130
131
        // Remove operations up until latest active savepoint.
132
        if (isset($idx)) {
133
            end($this->operations);
134
            $lastIdx = key($this->operations);
135
            for ($removeIdx = $idx; $removeIdx <= $lastIdx; $removeIdx++) {
136
                $this->removeOperation($removeIdx);
137
            }
138
            reset($this->operations);
139
        }
140
    }
141
142
    /**
143
     * {@inheritdoc}
144
     */
145
    public function addOperation(Operation $operation)
146
    {
147
        if ($this->depth <= 0) {
148
            return $operation->execute();
149
        }
150
151
        $idx = $this->idx;
152
        $this->idx++;
153
        $this->operations[$idx] = $operation;
154
        $operation->setId($this, $idx);
155
        return $idx;
156
    }
157
158
    /**
159
     * {@inheritdoc}
160
     */
161
    public function getOperation($idx)
162
    {
163
        return isset($this->operations[$idx]) ? $this->operations[$idx] : false;
164
    }
165
166
    /**
167
     * {@inheritdoc}
168
     */
169
    public function performOperation($idx)
170
    {
171
        return isset($this->operations[$idx]) ? $this->operations[$idx]->execute() : null;
172
    }
173
174
    /**
175
     * {@inheritdoc}
176
     */
177
    public function removeOperation($idx)
178
    {
179
        unset($this->operations[$idx]);
180
    }
181
}
182