Test Failed
Pull Request — master (#79)
by Alexander
03:10
created

StdoutQueryLogger   A

Complexity

Total Complexity 29

Size/Duplication

Total Lines 113
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 29
eloc 59
c 1
b 0
f 0
dl 0
loc 113
ccs 0
cts 53
cp 0
rs 10

10 Methods

Rating   Name   Duplication   Size   Complexity  
A countWriteQueries() 0 3 1
A print() 0 12 4
A cleanBuffer() 0 3 1
A display() 0 3 1
A isPostgresSystemQuery() 0 10 6
C log() 0 34 12
A __construct() 0 6 1
A hide() 0 3 1
A countReadQueries() 0 3 1
A getBuffer() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Yii\Cycle\Logger;
6
7
use Psr\Log\LoggerInterface;
8
use Psr\Log\LoggerTrait;
9
use Psr\Log\LogLevel;
10
11
/**
12
 * Temporary LoggerInterface class
13
 * Slightly adapted for SQL queries
14
 *
15
 * @package Yiisoft\Yii\Cycle\Logger
16
 *
17
 * @deprecated In the future StdoutLogger will be removed (when we will have debug-tools)
18
 */
19
class StdoutQueryLogger implements LoggerInterface
20
{
21
    use LoggerTrait;
22
23
    private bool $display;
24
25
    private int $countWrites;
26
    private int $countReads;
27
    private array $buffer = [];
28
    /** @var false|resource */
29
    private $fp;
30
31
    public function __construct()
32
    {
33
        $this->display = true;
34
        $this->countWrites = 0;
35
        $this->countReads = 0;
36
        $this->fp = fopen('php://stdout', 'w');
37
    }
38
39
    public function countWriteQueries(): int
40
    {
41
        return $this->countWrites;
42
    }
43
44
    public function countReadQueries(): int
45
    {
46
        return $this->countReads;
47
    }
48
49
    public function log($level, $message, array $context = []): void
50
    {
51
        if (!empty($context['elapsed'])) {
52
            $sql = strtolower($message);
53
            if (
54
                strpos($sql, 'insert') === 0 ||
55
                strpos($sql, 'update') === 0 ||
56
                strpos($sql, 'delete') === 0
57
            ) {
58
                $this->countWrites++;
59
            } elseif (!$this->isPostgresSystemQuery($sql)) {
60
                ++$this->countReads;
61
            }
62
        }
63
64
        if ($level === LogLevel::ERROR) {
65
            $this->print(" ! \033[31m" . $message . "\033[0m");
66
        } elseif ($level === LogLevel::ALERT) {
67
            $this->print(" ! \033[35m" . $message . "\033[0m");
68
        } elseif (strpos($message, 'SHOW') === 0) {
69
            $this->print(" > \033[34m" . $message . "\033[0m");
70
        } else {
71
            if ($this->isPostgresSystemQuery($message)) {
72
                $this->print(" > \033[90m" . $message . "\033[0m");
73
74
                return;
75
            }
76
77
            if (strpos($message, 'SELECT') === 0) {
78
                $this->print(" > \033[32m" . $message . "\033[0m");
79
            } elseif (strpos($message, 'INSERT') === 0) {
80
                $this->print(" > \033[36m" . $message . "\033[0m");
81
            } else {
82
                $this->print(" > \033[33m" . $message . "\033[0m");
83
            }
84
        }
85
    }
86
87
    private function print(string $str): void
88
    {
89
        $this->buffer[] = $str;
90
        if (!$this->display || $this->fp === false) {
91
            return;
92
        }
93
        try {
94
            fwrite($this->fp, "{$str}\n");
0 ignored issues
show
Bug introduced by
It seems like $this->fp can also be of type true; however, parameter $handle of fwrite() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

94
            fwrite(/** @scrutinizer ignore-type */ $this->fp, "{$str}\n");
Loading history...
95
        } catch (\Throwable $e) {
96
            /** @psalm-suppress InvalidPropertyAssignmentValue */
97
            fclose($this->fp);
0 ignored issues
show
Bug introduced by
It seems like $this->fp can also be of type true; however, parameter $handle of fclose() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

97
            fclose(/** @scrutinizer ignore-type */ $this->fp);
Loading history...
98
            $this->fp = false;
99
        }
100
    }
101
102
    public function display(): void
103
    {
104
        $this->display = true;
105
    }
106
107
    public function hide(): void
108
    {
109
        $this->display = false;
110
    }
111
112
    public function getBuffer(): array
113
    {
114
        return $this->buffer;
115
    }
116
117
    public function cleanBuffer(): void
118
    {
119
        $this->buffer = [];
120
    }
121
122
    protected function isPostgresSystemQuery(string $query): bool
123
    {
124
        $query = strtolower($query);
125
        return (bool) (
126
            strpos($query, 'tc.constraint_name') ||
127
            strpos($query, 'pg_indexes') ||
128
            strpos($query, 'tc.constraint_name') ||
129
            strpos($query, 'pg_constraint') ||
130
            strpos($query, 'information_schema') ||
131
            strpos($query, 'pg_class')
132
        )
133
134
135
136
         ;
137
    }
138
}
139