SelectFacade::query()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Lagdo\DbAdmin\Db\Driver\Facades;
4
5
use Lagdo\DbAdmin\Db\Page\Dql\SelectEntity;
6
use Lagdo\DbAdmin\Db\Page\Dql\SelectQuery;
7
use Lagdo\DbAdmin\Db\Page\Dql\SelectResult;
8
use Lagdo\DbAdmin\Db\Service\TimerService;
9
use Exception;
10
11
use function count;
12
13
/**
14
 * Facade to table select functions
15
 */
16
class SelectFacade extends AbstractFacade
17
{
18
    /**
19
     * @var SelectQuery|null
20
     */
21
    private SelectQuery|null $selectQuery = null;
22
23
    /**
24
     * @var SelectResult|null
25
     */
26
    private SelectResult|null $selectResult = null;
27
28
    /**
29
     * @param AbstractFacade $dbFacade
30
     * @param TimerService $timer
31
     */
32
    public function __construct(AbstractFacade $dbFacade, protected TimerService $timer)
33
    {
34
        parent::__construct($dbFacade);
35
    }
36
37
    /**
38
     * @return SelectQuery
39
     */
40
    private function query(): SelectQuery
41
    {
42
        return $this->selectQuery ??= new SelectQuery($this->page, $this->driver, $this->utils);
0 ignored issues
show
Bug introduced by
It seems like $this->driver can also be of type null; however, parameter $driver of Lagdo\DbAdmin\Db\Page\Dq...ectQuery::__construct() does only seem to accept Lagdo\DbAdmin\Driver\DriverInterface, 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

42
        return $this->selectQuery ??= new SelectQuery($this->page, /** @scrutinizer ignore-type */ $this->driver, $this->utils);
Loading history...
43
    }
44
45
    /**
46
     * @return SelectResult
47
     */
48
    private function result(): SelectResult
49
    {
50
        return $this->selectResult ??= new SelectResult($this->page, $this->driver, $this->utils);
0 ignored issues
show
Bug introduced by
It seems like $this->driver can also be of type null; however, parameter $driver of Lagdo\DbAdmin\Db\Page\Dq...ctResult::__construct() does only seem to accept Lagdo\DbAdmin\Driver\DriverInterface, 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

50
        return $this->selectResult ??= new SelectResult($this->page, /** @scrutinizer ignore-type */ $this->driver, $this->utils);
Loading history...
51
    }
52
53
    /**
54
     * @param string $table The table name
55
     * @param array $queryOptions The query options
56
     *
57
     * @return SelectEntity
58
     * @throws Exception
59
     */
60
    private function prepareSelect(string $table, array $queryOptions = []): SelectEntity
61
    {
62
        $tableStatus = $this->driver->tableStatusOrName($table);
0 ignored issues
show
Bug introduced by
The method tableStatusOrName() does not exist on null. ( Ignorable by Annotation )

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

62
        /** @scrutinizer ignore-call */ 
63
        $tableStatus = $this->driver->tableStatusOrName($table);

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...
63
        $tableName = $this->page->tableName($tableStatus);
64
        $selectEntity = new SelectEntity($table,
65
            $tableName, $tableStatus, $queryOptions);
66
        $this->query()->prepareSelect($selectEntity);
67
68
        return $selectEntity;
69
    }
70
71
    /**
72
     * Get required data for create/update on tables
73
     *
74
     * @param string $table The table name
75
     * @param array $queryOptions The query options
76
     *
77
     * @return SelectEntity
78
     * @throws Exception
79
     */
80
    public function getSelectData(string $table, array $queryOptions = []): SelectEntity
81
    {
82
        return $this->prepareSelect($table, $queryOptions);
83
    }
84
85
    /**
86
     * @param SelectEntity $selectEntity
87
     *
88
     * @return bool
89
     */
90
    private function hasGroupsInFields(SelectEntity $selectEntity): bool
91
    {
92
        return count($selectEntity->group) <
93
            count($selectEntity->select);
94
    }
95
96
    /**
97
     * Get required data for create/update on tables
98
     *
99
     * @param string $table The table name
100
     * @param array $queryOptions The query options
101
     *
102
     * @return int
103
     */
104
    public function countSelect(string $table, array $queryOptions): int
105
    {
106
        $selectEntity = $this->prepareSelect($table, $queryOptions);
107
108
        try {
109
            $query = $this->driver->getRowCountQuery($table,
110
                $selectEntity->where, $this->hasGroupsInFields($selectEntity),
111
                $selectEntity->group);
112
            return (int)$this->driver->result($query);
113
        } catch(Exception) {
114
            return -1;
115
        }
116
    }
117
118
    /**
119
     * @param SelectEntity $selectEntity
120
     *
121
     * @return void
122
     */
123
    private function executeQuery(SelectEntity $selectEntity): void
124
    {
125
        $this->timer->start();
126
127
        // From driver.inc.php
128
        $statement = $this->driver->execute($selectEntity->query);
129
        $selectEntity->duration = $this->timer->duration();
130
        $selectEntity->rows = [];
131
132
        // From adminer.inc.php
133
        if (!$statement) {
134
            $selectEntity->error = $this->driver->error();
135
            return;
136
        }
137
138
        // From select.inc.php
139
        $selectEntity->rows = [];
140
        while (($row = $statement->fetchAssoc())) {
141
            if ($selectEntity->page && $this->driver->jush() === "oracle") {
142
                unset($row["RNUM"]);
143
            }
144
            $selectEntity->rows[] = $row;
145
        }
146
    }
147
148
    /**
149
     * Get required data for create/update on tables
150
     *
151
     * @param string $table The table name
152
     * @param array $queryOptions The query options
153
     *
154
     * @return array
155
     * @throws Exception
156
     */
157
    public function execSelect(string $table, array $queryOptions): array
158
    {
159
        $selectEntity = $this->prepareSelect($table, $queryOptions);
160
161
        $this->executeQuery($selectEntity);
162
163
        if ($selectEntity->error !== null) {
164
            return [
165
                'message' => $selectEntity->error,
166
            ];
167
        }
168
        if (!$selectEntity->rows) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $selectEntity->rows of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
169
            return [
170
                'message' => $this->utils->trans->lang('No rows.'),
171
            ];
172
        }
173
174
        // $backward_keys = $this->driver->backwardKeys($table, $tableName);
175
        // lengths = $this->getValuesLengths($rows, $selectEntity->queryOptions);
176
177
        $this->result()->setResultHeaders($selectEntity);
178
179
        return [
180
            'headers' => $selectEntity->headers,
181
            'query' => $selectEntity->query,
182
            'limit' => $selectEntity->limit,
183
            'duration' => $selectEntity->duration,
184
            'rows' => $this->result()->getRows($selectEntity),
185
        ];
186
    }
187
}
188