Passed
Push — master ( 914087...c6011d )
by Alexander
11:22
created

Connection::open()   B

Complexity

Conditions 11
Paths 72

Size

Total Lines 50
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 25
CRAP Score 11.0069

Importance

Changes 0
Metric Value
cc 11
eloc 26
nc 72
nop 0
dl 0
loc 50
ccs 25
cts 26
cp 0.9615
crap 11.0069
rs 7.3166
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Db\Connection;
6
7
use Psr\Log\LogLevel;
8
use Throwable;
9
use Yiisoft\Cache\Dependency\Dependency;
10
use Yiisoft\Db\AwareTrait\LoggerAwareTrait;
11
use Yiisoft\Db\AwareTrait\ProfilerAwareTrait;
12
use Yiisoft\Db\Cache\QueryCache;
13
use Yiisoft\Db\Query\BatchQueryResult;
14
use Yiisoft\Db\Query\BatchQueryResultInterface;
15
use Yiisoft\Db\Query\QueryInterface;
16
use Yiisoft\Db\Schema\TableSchemaInterface;
17
use Yiisoft\Db\Transaction\TransactionInterface;
18
19
abstract class Connection implements ConnectionInterface
20
{
21
    use LoggerAwareTrait;
22
    use ProfilerAwareTrait;
23
24
    protected ?TransactionInterface $transaction = null;
25
    private bool $enableSavepoint = true;
26
    private int $serverRetryInterval = 600;
0 ignored issues
show
introduced by
The private property $serverRetryInterval is not used, and could be removed.
Loading history...
27
    private string $tablePrefix = '';
28
29
    public function __construct(private QueryCache $queryCache)
30
    {
31
    }
32
33
    public function beginTransaction(string $isolationLevel = null): TransactionInterface
34
    {
35
        $this->open();
36
        $this->transaction = $this->getTransaction();
37
38
        if ($this->transaction === null) {
39
            $this->transaction = $this->createTransaction();
40
        }
41
42
        if ($this->logger !== null) {
43
            $this->transaction->setLogger($this->logger);
44
        }
45
46
        $this->transaction->begin($isolationLevel);
47
48
        return $this->transaction;
49
    }
50
51
    public function cache(callable $callable, int $duration = null, Dependency $dependency = null): mixed
52
    {
53
        $this->queryCache->setInfo(
54
            [$duration ?? $this->queryCache->getDuration(), $dependency]
55
        );
56
        /** @var mixed */
57
        $result = $callable($this);
58
        $this->queryCache->removeLastInfo();
59
60
        return $result;
61
    }
62
63
    public function createBatchQueryResult(QueryInterface $query, bool $each = false): BatchQueryResultInterface
64
    {
65
        return new BatchQueryResult($query, $each);
66
    }
67
68
    public function getTablePrefix(): string
69
    {
70
        return $this->tablePrefix;
71
    }
72
73
    public function getTableSchema(string $name, bool $refresh = false): ?TableSchemaInterface
74
    {
75
        return $this->getSchema()->getTableSchema($name, $refresh);
76
    }
77
78
    public function getTransaction(): ?TransactionInterface
79
    {
80
        return $this->transaction && $this->transaction->isActive() ? $this->transaction : null;
81
    }
82
83
    public function isSavepointEnabled(): bool
84
    {
85
        return $this->enableSavepoint;
86
    }
87
88
    public function noCache(callable $callable): mixed
89
    {
90
        $queryCache = $this->queryCache;
91
        $queryCache->setInfo(false);
92
        /** @var mixed */
93
        $result = $callable($this);
94
        $queryCache->removeLastInfo();
95
96
        return $result;
97
    }
98
99
    public function setEnableSavepoint(bool $value): void
100
    {
101
        $this->enableSavepoint = $value;
102
    }
103
104
    public function setTablePrefix(string $value): void
105
    {
106
        $this->tablePrefix = $value;
107
    }
108
109
    public function transaction(callable $callback, string $isolationLevel = null): mixed
110
    {
111
        $transaction = $this->beginTransaction($isolationLevel);
112
113
        $level = $transaction->getLevel();
114
115
        try {
116
            /** @var mixed */
117
            $result = $callback($this);
118
119
            if ($transaction->isActive() && $transaction->getLevel() === $level) {
120
                $transaction->commit();
121
            }
122
        } catch (Throwable $e) {
123
            $this->rollbackTransactionOnLevel($transaction, $level);
124
125
            throw $e;
126
        }
127
128
        return $result;
129
    }
130
131
    /**
132
     * Rolls back given {@see TransactionInterface} object if it's still active and level match. In some cases rollback
133
     * can fail, so this method is fail-safe. Exceptions thrown from rollback will be caught and just logged with
134
     * {@see logger->log()}.
135
     *
136
     * @param TransactionInterface $transaction TransactionInterface object given from {@see beginTransaction()}.
137
     * @param int $level TransactionInterface level just after {@see beginTransaction()} call.
138
     */
139
    private function rollbackTransactionOnLevel(TransactionInterface $transaction, int $level): void
140
    {
141
        if ($transaction->isActive() && $transaction->getLevel() === $level) {
142
            /**
143
             * {@see https://github.com/yiisoft/yii2/pull/13347}
144
             */
145
            try {
146
                $transaction->rollBack();
147
            } catch (\Exception $e) {
148
                if ($this->logger !== null) {
149
                    $this->logger->log(LogLevel::ERROR, (string) $e, [__METHOD__]);
150
                    /** hide this exception to be able to continue throwing original exception outside */
151
                }
152
            }
153
        }
154
    }
155
}
156