QueryFavorite   A
last analyzed

Complexity

Total Complexity 24

Size/Duplication

Total Lines 220
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 92
c 2
b 0
f 0
dl 0
loc 220
rs 10
wmc 24

10 Methods

Rating   Name   Duplication   Size   Complexity  
A getQueryCount() 0 6 3
A deleteQuery() 0 17 2
A getLimit() 0 3 1
A getQueries() 0 21 4
A updateQuery() 0 22 2
A createQuery() 0 21 2
A getQuery() 0 10 2
A __construct() 0 11 2
A getWhereClause() 0 23 5
A user() 0 3 1
1
<?php
2
3
namespace Lagdo\DbAdmin\Service\DbAdmin;
4
5
use Lagdo\DbAdmin\Config\AuthInterface;
6
use Lagdo\DbAdmin\Driver\DriverInterface;
7
use Lagdo\Facades\Logger;
8
9
use function implode;
10
11
/**
12
 * SQL queries logging and storage.
13
 */
14
class QueryFavorite
15
{
16
    use ConnectionTrait;
17
18
    /**
19
     * @var bool
20
     */
21
    private bool $enabled;
22
23
    /**
24
     * @var int
25
     */
26
    private int $limit;
27
28
    /**
29
     * The constructor
30
     *
31
     * @param AuthInterface $auth
32
     * @param DriverInterface $driver
33
     * @param array $database
34
     * @param array $options
35
     */
36
    public function __construct(private AuthInterface $auth,
37
        private DriverInterface $driver, array $database, array $options)
38
    {
39
        $this->enabled = (bool)($options['enduser']['enabled'] ?? false);
40
        $this->limit = (int)($options['enduser']['limit'] ?? 15);
41
        if (!$this->enabled) {
42
            return;
43
        }
44
45
        // Connect to the logging database.
46
        $this->connect($driver, $database);
47
    }
48
49
    /**
50
     * @var string
51
     */
52
    protected function user(): string
53
    {
54
        return $this->auth->user();
55
    }
56
57
    /**
58
     * @param array $values
59
     *
60
     * @return bool
61
     */
62
    public function createQuery(array $values): bool
63
    {
64
        $values = [
65
            'title' => $values['title'],
66
            'query' => $values['query'],
67
            'driver' => $values['driver'],
68
            'last_update' => $this->currentTime(),
69
            'owner_id' => $this->getOwnerId(),
70
        ];
71
        $sql = "insert into dbadmin_stored_commands" .
72
            "(title,query,driver,last_update,owner_id) " .
73
            "values(:title,:query,:driver,:last_update,:owner_id)";
74
        $statement = $this->executeQuery($sql, $values);
75
        if ($statement !== false) {
76
            return true;
77
        }
78
79
        Logger::warning('Unable to save command in the query logging database.', [
80
            'error' => $this->connection->error(),
81
        ]);
82
        return false;
83
    }
84
85
    /**
86
     * @param int $queryId
87
     * @param array $values
88
     *
89
     * @return bool
90
     */
91
    public function updateQuery(int $queryId, array $values): bool
92
    {
93
        $values = [
94
            'title' => $values['title'],
95
            'query' => $values['query'],
96
            'driver' => $values['driver'],
97
            'last_update' => $this->currentTime(),
98
            'owner_id' => $this->getOwnerId(),
99
            'query_id' => $queryId,
100
        ];
101
        $sql = "update dbadmin_stored_commands set title=:title," .
102
            "query=:query,driver=:driver,last_update=:last_update " .
103
            "where id=:query_id and owner_id=:owner_id";
104
        $statement = $this->executeQuery($sql, $values);
105
        if ($statement !== false) {
106
            return true;
107
        }
108
109
        Logger::warning('Unable to save command in the query logging database.', [
110
            'error' => $this->connection->error(),
111
        ]);
112
        return false;
113
    }
114
115
    /**
116
     * @param int $queryId
117
     *
118
     * @return bool
119
     */
120
    public function deleteQuery(int $queryId): bool
121
    {
122
        $values = [
123
            'owner_id' => $this->getOwnerId(),
124
            'query_id' => $queryId,
125
        ];
126
        $sql = "delete from dbadmin_stored_commands where " .
127
            "id=:query_id and owner_id=:owner_id";
128
        $statement = $this->executeQuery($sql, $values);
129
        if ($statement !== false) {
130
            return true;
131
        }
132
133
        Logger::warning('Unable to save command in the query logging database.', [
134
            'error' => $this->connection->error(),
135
        ]);
136
        return false;
137
    }
138
139
    /**
140
     * @return int
141
     */
142
    public function getLimit(): int
143
    {
144
        return $this->limit;
145
    }
146
147
    /**
148
     * @param array $filters
149
     *
150
     * @return array
151
     */
152
    private function getWhereClause(array $filters): array
153
    {
154
        $values = [
155
            'owner_id' => $this->getOwnerId(),
156
        ];
157
        $clauses = ['c.owner_id=:owner_id'];
158
        if (isset($filters['title'])) {
159
            $values['title'] = "%{$filters['title']}%";
160
            $clauses[] = "c.title like :title";
161
        }
162
        if (isset($filters['driver'])) {
163
            $values['driver'] = $filters['driver'];
164
            $clauses[] = "c.driver=:driver";
165
        }
166
        if (isset($filters['from'])) {
167
            $values['from'] = $filters['from'];
168
            $clauses[] = "c.last_update>=:from";
169
        }
170
        if (isset($filters['to'])) {
171
            $values['to'] = $filters['to'];
172
            $clauses[] = "c.last_update<=:to";
173
        }
174
        return [$values, 'where ' . implode(' and ', $clauses)];
175
    }
176
177
    /**
178
     * @param array $filters
179
     *
180
     * @return int
181
     */
182
    public function getQueryCount(array $filters): int
183
    {
184
        [$values, $whereClause] = $this->getWhereClause($filters);
185
        $sql = "select count(*) as cnt from dbadmin_stored_commands c $whereClause";
186
        $statement = $this->executeQuery($sql, $values);
187
        return !$statement || !($row = $statement->fetchAssoc()) ? 0 : $row['cnt'];
188
    }
189
190
    /**
191
     * @param array $filters
192
     * @param int $page
193
     *
194
     * @return array
195
     */
196
    public function getQueries(array $filters, int $page): array
197
    {
198
        [$values, $whereClause] = $this->getWhereClause($filters);
199
        $offsetClause = $page > 1 ? 'offset ' . ($page - 1) * $this->limit : '';
200
        // PostgreSQL doesn't allow the use of distinct and order by
201
        // a field not in the select clause in the same SQL query.
202
        $sql = "select c.* from dbadmin_stored_commands c $whereClause " .
203
            "order by c.last_update desc,c.id desc limit {$this->limit} $offsetClause";
204
        $statement = $this->executeQuery($sql, $values);
205
        if ($statement !== false) {
206
            $commands = [];
207
            while (($row = $statement->fetchAssoc())) {
208
                $commands[] = $row;
209
            }
210
            return $commands;
211
        }
212
213
        Logger::warning('Unable to read commands from the query logging database.', [
214
            'error' => $this->connection->error(),
215
        ]);
216
        return [];
217
    }
218
219
    /**
220
     * @param int $queryId
221
     *
222
     * @return array|null
223
     */
224
    public function getQuery(int $queryId): ?array
225
    {
226
        $values = [
227
            'query_id' => $queryId,
228
            'owner_id' => $this->getOwnerId(),
229
        ];
230
        $sql = "select c.* from dbadmin_stored_commands c where " .
231
            "id=:query_id and owner_id=:owner_id";
232
        $statement = $this->executeQuery($sql, $values);
233
        return !$statement ? null : $statement->fetchAssoc();
234
    }
235
}
236