Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 20 |
|
0.00% |
0 / 8 |
CRAP | |
0.00% |
0 / 1 |
Query | |
0.00% |
0 / 20 |
|
0.00% |
0 / 8 |
210 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
2 | |||
isWriteQuery | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
56 | |||
getVerb | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
fieldHasBit | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getSQL | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getFlags | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getWriteTable | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getCleanedSql | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | /** |
3 | * This program is free software; you can redistribute it and/or modify |
4 | * it under the terms of the GNU General Public License as published by |
5 | * the Free Software Foundation; either version 2 of the License, or |
6 | * (at your option) any later version. |
7 | * |
8 | * This program is distributed in the hope that it will be useful, |
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
11 | * GNU General Public License for more details. |
12 | * |
13 | * You should have received a copy of the GNU General Public License along |
14 | * with this program; if not, write to the Free Software Foundation, Inc., |
15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
16 | * http://www.gnu.org/copyleft/gpl.html |
17 | * |
18 | * @file |
19 | */ |
20 | namespace Wikimedia\Rdbms; |
21 | |
22 | use Wikimedia\Rdbms\Platform\SQLPlatform; |
23 | |
24 | /** |
25 | * Holds information on Query to be executed |
26 | * |
27 | * @ingroup Database |
28 | * @internal |
29 | * @since 1.41 |
30 | */ |
31 | class Query { |
32 | |
33 | /** |
34 | * The possible multi-word values for getVerb(). |
35 | * @internal For use by Query and QueryBuilderFromRawSQL only. |
36 | */ |
37 | public const MULTIWORD_VERBS = [ |
38 | 'RELEASE SAVEPOINT', |
39 | 'ROLLBACK TO SAVEPOINT', |
40 | 'CREATE TEMPORARY', |
41 | 'CREATE INDEX', |
42 | 'DROP INDEX', |
43 | 'CREATE DATABASE', |
44 | 'ALTER DATABASE', |
45 | 'DROP DATABASE', |
46 | ]; |
47 | |
48 | private string $sql; |
49 | private int $flags; |
50 | private string $queryVerb; |
51 | private ?string $writeTable; |
52 | private string $cleanedSql; |
53 | |
54 | /** |
55 | * @param string $sql SQL statement text |
56 | * @param int $flags Bit field of ISQLPlatform::QUERY_CHANGE_* constants |
57 | * @param string $queryVerb The first words of the SQL statement that convey what kind of |
58 | * database/table/column/index command was specified. Except for the cases listed in |
59 | * {@see MULTIWORD_VERBS}, this will be the first word of the SQL statement. |
60 | * @param string|null $writeTable The table targeted for writes, if any. Can be omitted if |
61 | * it would be hard to identify the table (e.g. when parsing an arbitrary SQL string). |
62 | * @param string $cleanedSql Sanitized/simplified SQL statement text for logging. |
63 | * Typically, this means replacing variables / parameter values with placeholders. |
64 | * Can be omitted, in which case the code using the Query is responsible for sanitizing. |
65 | */ |
66 | public function __construct( |
67 | string $sql, |
68 | $flags, |
69 | $queryVerb, |
70 | ?string $writeTable = null, |
71 | $cleanedSql = '' |
72 | ) { |
73 | $this->sql = $sql; |
74 | $this->flags = $flags; |
75 | $this->queryVerb = $queryVerb; |
76 | $this->writeTable = $writeTable; |
77 | $this->cleanedSql = substr( $cleanedSql, 0, 255 ); |
78 | } |
79 | |
80 | public function isWriteQuery(): bool { |
81 | // Check if a SQL wrapper method already flagged the query as a non-write |
82 | if ( |
83 | $this->fieldHasBit( $this->flags, SQLPlatform::QUERY_CHANGE_NONE ) || |
84 | $this->fieldHasBit( $this->flags, SQLPlatform::QUERY_CHANGE_TRX ) || |
85 | $this->fieldHasBit( $this->flags, SQLPlatform::QUERY_CHANGE_LOCKS ) |
86 | ) { |
87 | return false; |
88 | } |
89 | // Check if a SQL wrapper method already flagged the query as a write |
90 | if ( |
91 | $this->fieldHasBit( $this->flags, SQLPlatform::QUERY_CHANGE_ROWS ) || |
92 | $this->fieldHasBit( $this->flags, SQLPlatform::QUERY_CHANGE_SCHEMA ) || |
93 | $this->fieldHasBit( $this->flags, SQLPlatform::QUERY_PSEUDO_PERMANENT ) |
94 | ) { |
95 | return true; |
96 | } |
97 | |
98 | throw new DBLanguageError( __METHOD__ . ' called with incorrect flags parameter' ); |
99 | } |
100 | |
101 | public function getVerb(): string { |
102 | return $this->queryVerb; |
103 | } |
104 | |
105 | private function fieldHasBit( int $flags, int $bit ): bool { |
106 | return ( ( $flags & $bit ) === $bit ); |
107 | } |
108 | |
109 | public function getSQL(): string { |
110 | return $this->sql; |
111 | } |
112 | |
113 | public function getFlags(): int { |
114 | // The whole concept of flags is terrible. This should be deprecated. |
115 | return $this->flags; |
116 | } |
117 | |
118 | /** |
119 | * Get the table which is being written to, or null for a read query or if |
120 | * the destination is unknown. |
121 | */ |
122 | public function getWriteTable(): ?string { |
123 | return $this->writeTable; |
124 | } |
125 | |
126 | /** |
127 | * Get the cleaned/sanitized SQL statement text for logging. |
128 | * Might return an empty string, which means sanitization is the caller's responsibility. |
129 | */ |
130 | public function getCleanedSql(): string { |
131 | return $this->cleanedSql; |
132 | } |
133 | } |