Issues (1)

src/Tracer.php (1 issue)

Labels
Severity
1
<?php
2
3
/*
4
 * Tracer
5
 *
6
 */
7
8
namespace HexMakina\Tracer;
9
10
use HexMakina\BlackBox\Database\{ConnectionInterface
11
                                ,TableManipulationInterface
12
                                ,TraceInterface
13
                                ,SelectInterface};
14
15
class Tracer implements \HexMakina\BlackBox\Database\TracerInterface
16
{
17
    private ConnectionInterface $connection;
18
    private TableManipulationInterface $tracing_table;
19
20
    public function __construct(ConnectionInterface $connection)
21
    {
22
        $this->connection = $connection;
23
    }
24
25
    public function setTracingTableName(string $table_name) : void
26
    {
27
        $this->tracing_table = $this->connection->schema()->table($table_name);
0 ignored issues
show
The method schema() does not exist on HexMakina\BlackBox\Database\ConnectionInterface. ( Ignorable by Annotation )

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

27
        $this->tracing_table = $this->connection->/** @scrutinizer ignore-call */ schema()->table($table_name);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
28
    }
29
30
    public function tracingTable(): TableManipulationInterface
31
    {
32
        return $this->tracing_table;
33
    }
34
35
    public function trace(TraceInterface $t): bool
36
    {
37
        $trace = [];
38
        $trace['query_type'] = $t->queryCode();
39
        $trace['query_table'] = $t->tableName();
40
        $trace['query_id'] = $t->tablePk();
41
        $trace['query_by'] = $t->operatorId();
42
43
        try {
44
            $this->tracingTable()->connection()->transact();
45
            $query = $this->tracingTable()->insert($trace)->run();
46
47
            // if we delete a record, we remove all traces of update
48
            if ($query->isSuccess() && $t->isDelete()) {
49
                $trace['query_type'] = Trace::CODE_UPDATE;
50
                unset($trace['query_by']);
51
                $this->tracingTable()->delete($trace)->run();
52
            }
53
            $this->tracingTable()->connection()->commit();
54
            return true;
55
        } catch (\Exception $e) {
56
            $this->tracingTable()->connection()->rollback();
57
            return false;
58
        }
59
    }
60
61
    /**
62
     * @param array<string, mixed> $options
63
     * @return array<array>
64
     */
65
    public function traces(array $options = []): array
66
    {
67
        // TODO SELECT field order can't change without adapting the result parsing code (foreach $res)
68
        $select_fields = [
69
          'SUBSTR(query_on, 1, 10) AS working_day',
70
          'query_table',
71
          'query_id',
72
          'GROUP_CONCAT(DISTINCT query_type, "-", query_by) as action_by'
73
        ];
74
        $q = $this->tracingTable()->select($select_fields);
75
        $q->orderBy(['', 'working_day', 'DESC']);
76
        $q->orderBy([$this->tracingTable()->name(), 'query_table', 'DESC']);
77
        $q->orderBy([$this->tracingTable()->name(), 'query_id', 'DESC']);
78
79
        $q->groupBy(['working_day']);
80
        $q->groupBy('query_table');
81
        $q->groupBy('query_id');
82
        $q->having("action_by NOT LIKE '%D%'");
83
84
        $limit = 1000;
85
        if (!empty($options['limit'])) {
86
            $limit = intval($options['limit']);
87
            unset($options['limit']);
88
        }
89
        $q->limit($limit);
90
91
        $this->filter($q, $options);
92
        $res = $q->retNum(); // ret num to list()
93
        return $this->export($res);
94
    }
95
    /**
96
     * @param array<string, mixed> $options
97
     */
98
    private function filter(SelectInterface $q, array $options) : void
99
    {
100
        if (isset($options['on'])) {
101
            $q->whereLike('query_on', $options['on'] . '%');
102
        }
103
104
        if (isset($options['by'])) {
105
            $q->whereEQ('query_by', $options['operator']);
106
        }
107
108
        if (isset($options['pk'])) {
109
            $q->whereEQ('query_id', $options['pk']);
110
        }
111
112
        if (isset($options['table'])) {
113
            $q->whereEQ('query_table', $options['table']);
114
        }
115
116
        if (isset($options['tables'])) {
117
            $q->whereStringIn('query_table', $options['tables']);
118
        }
119
    }
120
    /**
121
     * @param array<array> $res
122
     * @return array<array>
123
     */
124
    private function export($res) : array
125
    {
126
        $ret = [];
127
128
        foreach ($res as $r) {
129
            list($working_day, $class, $instance_id, $logs) = $r;
130
131
            if (!isset($ret[$working_day])) {
132
                $ret[$working_day] = [];
133
            }
134
            if (!isset($ret[$working_day][$class])) {
135
                $ret[$working_day][$class] = [];
136
            }
137
138
            $ret[$working_day][$class][$instance_id] = $logs;
139
        }
140
        return $ret;
141
    }
142
}
143