| 1 | <?php |
||
| 2 | |||
| 3 | namespace Lagdo\DbAdmin\Service\Logging; |
||
| 4 | |||
| 5 | use Lagdo\DbAdmin\Db\DbFacade; |
||
| 6 | use Lagdo\DbAdmin\Driver\Db\ConnectionInterface; |
||
| 7 | use Lagdo\DbAdmin\Driver\DriverInterface; |
||
| 8 | use Lagdo\DbAdmin\Service\Options; |
||
| 9 | use Lagdo\Facades\Logger; |
||
| 10 | |||
| 11 | use function count; |
||
| 12 | use function implode; |
||
| 13 | |||
| 14 | /** |
||
| 15 | * SQL queries logging and storage. |
||
| 16 | */ |
||
| 17 | class QueryLogger |
||
| 18 | { |
||
| 19 | /** |
||
| 20 | * @var ConnectionInterface |
||
| 21 | */ |
||
| 22 | private ConnectionInterface $connection; |
||
| 23 | |||
| 24 | /** |
||
| 25 | * @var int |
||
| 26 | */ |
||
| 27 | private int $limit; |
||
| 28 | |||
| 29 | /** |
||
| 30 | * The constructor |
||
| 31 | * |
||
| 32 | * @param DbFacade $db |
||
| 33 | * @param DriverInterface $driver |
||
| 34 | * @param array $database |
||
| 35 | * @param array $options |
||
| 36 | */ |
||
| 37 | public function __construct(private DbFacade $db, |
||
| 38 | private DriverInterface $driver, array $database, array $options) |
||
| 39 | { |
||
| 40 | $this->limit = $options['display']['limit'] ?? 15; |
||
| 41 | |||
| 42 | // Connect to the logging database. |
||
| 43 | $this->connection = $driver->createConnection($database); |
||
| 44 | $this->connection->open($database['name'], $database['schema'] ?? ''); |
||
| 45 | } |
||
| 46 | |||
| 47 | /** |
||
| 48 | * @return int |
||
| 49 | */ |
||
| 50 | public function getLimit(): int |
||
| 51 | { |
||
| 52 | return $this->limit; |
||
| 53 | } |
||
| 54 | |||
| 55 | /** |
||
| 56 | * @return string[] |
||
| 57 | */ |
||
| 58 | public function getCategories(): array |
||
| 59 | { |
||
| 60 | return [ |
||
| 61 | Options::CAT_BUILDER => 'Query builder', |
||
| 62 | Options::CAT_EDITOR => 'Query editor', |
||
| 63 | ]; |
||
| 64 | } |
||
| 65 | |||
| 66 | /** |
||
| 67 | * @param array $filters |
||
| 68 | * |
||
| 69 | * @return string |
||
| 70 | */ |
||
| 71 | private function getWhereClause(array $filters): string |
||
| 72 | { |
||
| 73 | $clauses = []; |
||
| 74 | if (isset($filters['username'])) { |
||
| 75 | $clauses[] = "o.username like '%{$filters['username']}%'"; |
||
| 76 | } |
||
| 77 | if (isset($filters['category'])) { |
||
| 78 | $clauses[] = "c.category={$filters['category']}"; |
||
| 79 | } |
||
| 80 | if (isset($filters['from'])) { |
||
| 81 | $clauses[] = "c.last_update>='{$filters['from']}'"; |
||
| 82 | } |
||
| 83 | if (isset($filters['to'])) { |
||
| 84 | $clauses[] = "c.last_update<='{$filters['to']}'"; |
||
| 85 | } |
||
| 86 | return count($clauses) === 0 ? '' : 'where ' . |
||
| 87 | implode(' and ', $clauses); |
||
| 88 | } |
||
| 89 | |||
| 90 | /** |
||
| 91 | * @param array $filters |
||
| 92 | * |
||
| 93 | * @return int |
||
| 94 | */ |
||
| 95 | public function getCommandCount(array $filters): int |
||
| 96 | { |
||
| 97 | $whereClause = $this->getWhereClause($filters); |
||
| 98 | $statement = "select count(*) as c from dbadmin_runned_commands c " . |
||
| 99 | "inner join dbadmin_owners o on c.owner_id=o.id $whereClause"; |
||
| 100 | $statement = $this->connection->query($statement); |
||
|
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||
| 101 | return !$statement || !($row = $statement->fetchAssoc()) ? 0 : $row['c']; |
||
| 102 | } |
||
| 103 | |||
| 104 | /** |
||
| 105 | * @param array $filters |
||
| 106 | * @param int $page |
||
| 107 | * |
||
| 108 | * @return array |
||
| 109 | */ |
||
| 110 | public function getCommands(array $filters, int $page): array |
||
| 111 | { |
||
| 112 | $whereClause = $this->getWhereClause($filters); |
||
| 113 | $offsetClause = $page > 1 ? 'offset ' . ($page - 1) * $this->limit : ''; |
||
| 114 | // PostgreSQL doesn't allow the use of distinct and order by |
||
| 115 | // a field not in the select clause in the same SQL query. |
||
| 116 | $statement = "select c.*, o.username from dbadmin_runned_commands c " . |
||
| 117 | "inner join dbadmin_owners o on c.owner_id=o.id $whereClause " . |
||
| 118 | "order by c.last_update desc,c.id desc limit {$this->limit} $offsetClause"; |
||
| 119 | $statement = $this->connection->query($statement); |
||
| 120 | if ($statement !== false) { |
||
| 121 | $commands = []; |
||
| 122 | while (($row = $statement->fetchAssoc())) { |
||
| 123 | $commands[] = $row; |
||
| 124 | } |
||
| 125 | return $commands; |
||
| 126 | } |
||
| 127 | |||
| 128 | Logger::warning('Unable to read commands from the query logging database.', [ |
||
| 129 | 'error' => $this->connection->error(), |
||
| 130 | ]); |
||
| 131 | return []; |
||
| 132 | } |
||
| 133 | } |
||
| 134 |