Completed
Push — master ( c27d2d...a49ccc )
by Ondřej
03:50
created

TxHandle::assertOpen()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 12
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 7
nc 3
nop 0
1
<?php
2
namespace Ivory\Connection;
3
4
use Ivory\Exception\InvalidStateException;
5
use Ivory\Result\IQueryResult;
6
use Ivory\Type\Ivory\IdentifierSerializer;
7
use Ivory\Type\Std\StringType;
8
9
/**
10
 * {@inheritdoc}
11
 *
12
 * This implementation checks, upon destruction, whether the transaction has properly been closed. If not, i.e., when
13
 * the transaction handle gets lost and thus no further means of controlling the transaction are available, a warning is
14
 * emitted.
15
 */
16
class TxHandle implements ITxHandle
17
{
18
    private $open = true;
19
    private $stmtExec;
20
    private $txCtl;
21
    private $identSerializer;
22
    private $stringSerializer;
23
24
    public function __construct(IStatementExecution $stmtExec, IObservableTransactionControl $observableTxCtl)
25
    {
26
        $this->stmtExec = $stmtExec;
27
        $this->txCtl = $observableTxCtl;
28
        $this->identSerializer = new IdentifierSerializer();
29
        $this->stringSerializer = new StringType('pg_catalog', 'text');
30
    }
31
32
    public function __destruct()
33
    {
34
        if ($this->open) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
35
            // TODO: notify on an open transaction handle
36
        }
37
    }
38
39
    private function assertOpen()
40
    {
41
        if (!$this->open) {
42
            if ($this->txCtl->inTransaction()) {
43
                throw new InvalidStateException(
44
                    'Controlling the transaction using a wrong handle - this has already been closed'
45
                );
46
            } else {
47
                throw new InvalidStateException('The transaction is not open anymore');
48
            }
49
        }
50
    }
51
52
    public function isOpen(): bool
53
    {
54
        return $this->open;
55
    }
56
57
    public function setupTransaction($transactionOptions)
58
    {
59
        $this->assertOpen();
60
        $txConfig = TxConfig::create($transactionOptions);
61
        $this->stmtExec->rawCommand('SET TRANSACTION ' . $txConfig->toSql());
62
    }
63
64
    public function setTransactionSnapshot(string $snapshotId)
65
    {
66
        $this->assertOpen();
67
        $this->stmtExec->rawCommand("SET TRANSACTION SNAPSHOT {$this->stringSerializer->serializeValue($snapshotId)}");
68
        return true;
69
    }
70
71
    public function exportTransactionSnapshot(): string
72
    {
73
        $this->assertOpen();
74
75
        /** @var IQueryResult $r */
76
        $r = $this->stmtExec->rawQuery('SELECT pg_export_snapshot()');
77
        return $r->value();
78
    }
79
80
    public function commit()
81
    {
82
        $this->assertOpen();
83
        $this->stmtExec->rawCommand('COMMIT');
84
        $this->open = false;
85
        $this->txCtl->notifyTransactionCommit();
86
    }
87
88
    public function rollback()
89
    {
90
        $this->assertOpen();
91
        $this->stmtExec->rawCommand('ROLLBACK');
92
        $this->open = false;
93
        $this->txCtl->notifyTransactionRollback();
94
    }
95
96
    public function savepoint(string $name)
97
    {
98
        $this->assertOpen();
99
        $this->stmtExec->rawCommand(sprintf('SAVEPOINT %s', $this->identSerializer->serializeValue($name)));
100
        $this->txCtl->notifySavepointSaved($name);
101
    }
102
103
    public function rollbackToSavepoint(string $name)
104
    {
105
        $this->assertOpen();
106
        $this->stmtExec->rawCommand(sprintf('ROLLBACK TO SAVEPOINT %s', $this->identSerializer->serializeValue($name)));
107
        $this->txCtl->notifyRollbackToSavepoint($name);
108
    }
109
110
    public function releaseSavepoint(string $name)
111
    {
112
        $this->assertOpen();
113
        $this->stmtExec->rawCommand(sprintf('RELEASE SAVEPOINT %s', $this->identSerializer->serializeValue($name)));
114
        $this->txCtl->notifySavepointReleased($name);
115
    }
116
117
    public function prepareTransaction(string $name)
118
    {
119
        $this->assertOpen();
120
        $this->stmtExec->rawCommand("PREPARE TRANSACTION {$this->stringSerializer->serializeValue($name)}");
121
        $this->open = false;
122
        $this->txCtl->notifyTransactionPrepared($name);
123
    }
124
}
125