Passed
Pull Request — master (#449)
by Wilmer
31:32 queued 29:20
created

AbstractConnection::getTablePrefix()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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