This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /** |
||
4 | * @link http://www.yiiframework.com/ |
||
5 | * @copyright Copyright (c) 2008 Yii Software LLC |
||
6 | * @license http://www.yiiframework.com/license/ |
||
7 | */ |
||
8 | |||
9 | namespace edgardmessias\db\ibm\db2; |
||
10 | |||
11 | use yii\base\InvalidParamException; |
||
12 | use yii\db\Constraint; |
||
13 | use yii\db\Expression; |
||
14 | use yii\db\Query; |
||
15 | |||
16 | /** |
||
17 | * QueryBuilder is the query builder for DB2 databases. |
||
18 | * |
||
19 | * @property Connection $db Connetion |
||
20 | * |
||
21 | * @author Edgard Lorraine Messias <[email protected]> |
||
22 | * @author Nikita Verkhovin <[email protected]> |
||
23 | */ |
||
24 | class QueryBuilder extends \yii\db\QueryBuilder |
||
25 | { |
||
26 | public $typeMap = [ |
||
27 | Schema::TYPE_PK => 'integer NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1) PRIMARY KEY', |
||
28 | Schema::TYPE_BIGPK => 'bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1) PRIMARY KEY', |
||
29 | Schema::TYPE_STRING => 'varchar(255)', |
||
30 | Schema::TYPE_TEXT => 'clob', |
||
31 | Schema::TYPE_SMALLINT => 'smallint', |
||
32 | Schema::TYPE_INTEGER => 'integer', |
||
33 | Schema::TYPE_BIGINT => 'bigint', |
||
34 | Schema::TYPE_FLOAT => 'float', |
||
35 | Schema::TYPE_DOUBLE => 'double', |
||
36 | Schema::TYPE_DECIMAL => 'decimal(10,0)', |
||
37 | Schema::TYPE_DATETIME => 'timestamp', |
||
38 | Schema::TYPE_TIMESTAMP => 'timestamp', |
||
39 | Schema::TYPE_TIME => 'time', |
||
40 | Schema::TYPE_DATE => 'date', |
||
41 | Schema::TYPE_BINARY => 'blob', |
||
42 | Schema::TYPE_BOOLEAN => 'smallint', |
||
43 | Schema::TYPE_MONEY => 'decimal(19,4)', |
||
44 | ]; |
||
45 | |||
46 | 337 | protected function defaultExpressionBuilders() |
|
47 | { |
||
48 | 337 | return array_merge(parent::defaultExpressionBuilders(), [ |
|
49 | 337 | 'yii\db\conditions\InCondition' => 'edgardmessias\db\ibm\db2\conditions\InConditionBuilder', |
|
50 | 337 | 'yii\db\conditions\LikeCondition' => 'edgardmessias\db\ibm\db2\conditions\LikeConditionBuilder', |
|
51 | 337 | ]); |
|
52 | } |
||
53 | |||
54 | /** |
||
55 | * Builds a SQL statement for truncating a DB table. |
||
56 | * @param string $table the table to be truncated. The name will be properly quoted by the method. |
||
57 | * @return string the SQL statement for truncating a DB table. |
||
58 | */ |
||
59 | 1 | public function truncateTable($table) |
|
60 | { |
||
61 | 1 | return 'TRUNCATE TABLE ' . $this->db->quoteTableName($table) . ' IMMEDIATE'; |
|
62 | } |
||
63 | |||
64 | /** |
||
65 | * @inheritdoc |
||
66 | */ |
||
67 | 5 | public function resetSequence($tableName, $value = null) |
|
68 | { |
||
69 | 5 | $table = $this->db->getTableSchema($tableName); |
|
70 | |||
71 | 5 | if ($table !== null && isset($table->columns[$table->sequenceName])) { |
|
72 | 5 | if ($value === null) { |
|
73 | $sql = 'SELECT MAX("'. $table->sequenceName .'") FROM "'. $tableName . '"'; |
||
74 | $value = $this->db->createCommand($sql)->queryScalar() + 1; |
||
75 | } else { |
||
76 | 5 | $value = (int) $value; |
|
77 | } |
||
78 | 5 | return 'ALTER TABLE "' . $tableName . '" ALTER COLUMN "'.$table->sequenceName.'" RESTART WITH ' . $value; |
|
79 | } elseif ($table === null) { |
||
80 | throw new InvalidParamException("Table not found: $tableName"); |
||
0 ignored issues
–
show
|
|||
81 | } else { |
||
82 | throw new InvalidParamException("There is no sequence associated with table '$tableName'."); |
||
0 ignored issues
–
show
The class
yii\base\InvalidParamException has been deprecated with message: since 2.0.14. Use [[InvalidArgumentException]] instead.
This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead. ![]() |
|||
83 | } |
||
84 | } |
||
85 | |||
86 | /** |
||
87 | * Builds a SQL statement for enabling or disabling integrity check. |
||
88 | * @param boolean $check whether to turn on or off the integrity check. |
||
89 | * @param string $schema the schema of the tables. Defaults to empty string, meaning the current or default schema. |
||
90 | * @param string $table the table name. Defaults to empty string, meaning that no table will be changed. |
||
91 | * @return string the SQL statement for checking integrity |
||
92 | * @throws \yii\base\NotSupportedException if this is not supported by the underlying DBMS |
||
93 | * @see http://www-01.ibm.com/support/knowledgecenter/SSEPGG_10.5.0/com.ibm.db2.luw.sql.ref.doc/doc/r0000998.html?cp=SSEPGG_10.5.0%2F2-12-7-227 |
||
94 | */ |
||
95 | public function checkIntegrity($check = true, $schema = '', $table = '') |
||
96 | { |
||
97 | if ($table) { |
||
98 | $tableNames = [$table]; |
||
99 | } else { |
||
100 | if (!$schema) { |
||
101 | $schema = $this->db->defaultSchema; |
||
102 | } |
||
103 | |||
104 | //Return only tables |
||
105 | $sql = "SELECT t.tabname FROM syscat.tables AS t" |
||
106 | . " WHERE t.type in ('T') AND t.ownertype != 'S'"; |
||
107 | |||
108 | /** |
||
109 | * Filter by integrity pending |
||
110 | * @see http://www-01.ibm.com/support/knowledgecenter/SSEPGG_9.7.0/com.ibm.db2.luw.sql.ref.doc/doc/r0001063.html |
||
111 | */ |
||
112 | if ($check) { |
||
113 | $sql .= " AND t.status = 'C'"; |
||
114 | } |
||
115 | if ($schema) { |
||
116 | $sql .= ' AND t.tabschema = :schema'; |
||
117 | } |
||
118 | |||
119 | $command = $this->db->createCommand($sql); |
||
120 | if ($schema) { |
||
121 | $command->bindValue(':schema', $schema); |
||
122 | } |
||
123 | |||
124 | $tableNames = $command->queryColumn(); |
||
125 | } |
||
126 | |||
127 | if (empty($tableNames)) { |
||
128 | return ''; |
||
129 | } |
||
130 | |||
131 | $quotedTableNames = []; |
||
132 | foreach ($tableNames as $tableName) { |
||
133 | $quotedTableNames[] = $this->db->quoteTableName($tableName) . ($check? '' : ' ALL'); |
||
134 | } |
||
135 | |||
136 | $enable = $check ? 'CHECKED' : 'UNCHECKED'; |
||
137 | return 'SET INTEGRITY FOR ' . implode(', ', $quotedTableNames) . ' IMMEDIATE ' . $enable. ';'; |
||
138 | } |
||
139 | |||
140 | /** |
||
141 | * @inheritdoc |
||
142 | */ |
||
143 | 263 | public function buildOrderByAndLimit($sql, $orderBy, $limit, $offset) |
|
144 | { |
||
145 | 263 | $limitOffsetStatment = $this->buildLimit($limit, $offset); |
|
146 | 263 | if ($limitOffsetStatment != '') { |
|
147 | 25 | $sql = str_replace(':query', $sql, $limitOffsetStatment); |
|
148 | |||
149 | //convert "item"."id" to "id" to use in OVER() |
||
150 | 25 | $newOrderBy = []; |
|
151 | |||
152 | 25 | if(!empty($orderBy)){ |
|
153 | 9 | foreach ($orderBy as $name => $direction) { |
|
154 | 9 | if(is_string($name)){ |
|
155 | 9 | $e = explode('.', $name); |
|
156 | 9 | $name = array_pop($e); |
|
157 | 9 | } |
|
158 | 9 | $newOrderBy[$name] = $direction; |
|
159 | 9 | } |
|
160 | 9 | } |
|
161 | |||
162 | 25 | $orderByStatment = $this->buildOrderBy($newOrderBy); |
|
163 | |||
164 | 25 | $sql = str_replace(':order', $orderByStatment,$sql); |
|
165 | 25 | }else{ |
|
166 | 256 | $orderByStatment = $this->buildOrderBy($orderBy); |
|
167 | 256 | if ($orderByStatment !== '') { |
|
168 | 36 | $sql .= $this->separator . $orderByStatment; |
|
169 | 36 | } |
|
170 | } |
||
171 | 263 | return $sql; |
|
172 | } |
||
173 | |||
174 | /** |
||
175 | * @inheritdoc |
||
176 | */ |
||
177 | 263 | public function buildLimit($limit, $offset) |
|
178 | { |
||
179 | 263 | if (!$this->hasLimit($limit) && !$this->hasOffset($offset)) { |
|
180 | 256 | return ''; |
|
181 | } |
||
182 | |||
183 | 25 | if (!$this->hasOffset($offset)) { |
|
184 | 23 | return ':query :order FETCH FIRST ' . $limit . ' ROWS ONLY'; |
|
185 | } |
||
186 | |||
187 | /** |
||
188 | * @todo Need remote the `RN_` from result to use in "INSERT" query |
||
189 | */ |
||
190 | 3 | $limitOffsetStatment = 'SELECT * FROM (SELECT SUBQUERY_.*, ROW_NUMBER() OVER(:order) AS RN_ FROM ( :query ) AS SUBQUERY_) as t WHERE :offset :limit'; |
|
191 | |||
192 | 3 | $replacement = $this->hasOffset($offset) ? 't.RN_ > ' . $offset : 't.RN_ > 0'; |
|
193 | 3 | $limitOffsetStatment = str_replace(':offset', $replacement, $limitOffsetStatment); |
|
194 | |||
195 | 3 | $replacement = ''; |
|
196 | |||
197 | 3 | if ($this->hasLimit($limit)) { |
|
198 | 2 | if ($limit instanceof \yii\db\ExpressionInterface || $offset instanceof \yii\db\ExpressionInterface) { |
|
199 | 1 | $replacement = 'AND t.RN_ <= (' . $limit . ' + ' . $offset . ')'; |
|
200 | 1 | } else { |
|
201 | 1 | $replacement = 'AND t.RN_ <= ' . ($limit + $offset); |
|
202 | } |
||
203 | 2 | } |
|
204 | 3 | $limitOffsetStatment = str_replace(':limit', $replacement, $limitOffsetStatment); |
|
205 | |||
206 | 3 | return $limitOffsetStatment; |
|
207 | } |
||
208 | |||
209 | /** |
||
210 | * @inheritdoc |
||
211 | */ |
||
212 | 1 | public function alterColumn($table, $column, $type) |
|
213 | { |
||
214 | 1 | return 'ALTER TABLE ' . $this->db->quoteTableName($table) . ' ALTER COLUMN ' |
|
215 | 1 | . $this->db->quoteColumnName($column) . ' SET DATA TYPE ' |
|
216 | 1 | . $this->getColumnType($type); |
|
217 | } |
||
218 | |||
219 | /** |
||
220 | * @inheritdoc |
||
221 | */ |
||
222 | 62 | public function prepareInsertValues($table, $columns, $params = []) |
|
223 | { |
||
224 | 62 | $result = parent::prepareInsertValues($table, $columns, $params); |
|
225 | |||
226 | // Empty placeholders, replace for (DEFAULT, DEFAULT, ...) |
||
227 | 59 | if (empty($result[1]) && $result[2] === ' DEFAULT VALUES') { |
|
228 | 1 | $schema = $this->db->getSchema(); |
|
229 | 1 | if (($tableSchema = $schema->getTableSchema($table)) !== null) { |
|
230 | 1 | $columnSchemas = $tableSchema->columns; |
|
231 | 1 | } else { |
|
232 | $columnSchemas = []; |
||
233 | } |
||
234 | 1 | $result[1] = array_fill(0, count($columnSchemas), 'DEFAULT'); |
|
235 | 1 | } |
|
236 | |||
237 | 59 | return $result; |
|
238 | } |
||
239 | |||
240 | /** |
||
241 | * @inheritdoc |
||
242 | */ |
||
243 | 17 | public function upsert($table, $insertColumns, $updateColumns, &$params) |
|
244 | { |
||
245 | /** @var Constraint[] $constraints */ |
||
246 | 17 | list($uniqueNames, $insertNames, $updateNames) = $this->prepareUpsertColumns($table, $insertColumns, $updateColumns, $constraints); |
|
247 | 17 | if (empty($uniqueNames)) { |
|
248 | 3 | return $this->insert($table, $insertColumns, $params); |
|
249 | } |
||
250 | |||
251 | 14 | $onCondition = ['or']; |
|
252 | 14 | $quotedTableName = $this->db->quoteTableName($table); |
|
253 | 14 | foreach ($constraints as $constraint) { |
|
254 | 14 | $constraintCondition = ['and']; |
|
255 | 14 | foreach ($constraint->columnNames as $name) { |
|
0 ignored issues
–
show
The expression
$constraint->columnNames of type array<integer,string>|null is not guaranteed to be traversable. How about adding an additional type check?
There are different options of fixing this problem.
![]() |
|||
256 | 14 | $quotedName = $this->db->quoteColumnName($name); |
|
257 | 14 | $constraintCondition[] = "$quotedTableName.$quotedName=\"EXCLUDED\".$quotedName"; |
|
258 | 14 | } |
|
259 | 14 | $onCondition[] = $constraintCondition; |
|
260 | 14 | } |
|
261 | 14 | $on = $this->buildCondition($onCondition, $params); |
|
262 | 14 | list(, $placeholders, $values, $params) = $this->prepareInsertValues($table, $insertColumns, $params); |
|
263 | 14 | if (!empty($placeholders)) { |
|
264 | 6 | $usingSelectValues = []; |
|
265 | 6 | foreach ($insertNames as $index => $name) { |
|
266 | 6 | $usingSelectValues[$name] = new Expression($placeholders[$index]); |
|
267 | 6 | } |
|
268 | 6 | $usingSubQuery = (new Query()) |
|
269 | 6 | ->select($usingSelectValues) |
|
270 | 6 | ->from('SYSIBM.SYSDUMMY1'); |
|
271 | 6 | list($usingValues, $params) = $this->build($usingSubQuery, $params); |
|
272 | 6 | } |
|
273 | 14 | $mergeSql = 'MERGE INTO ' . $this->db->quoteTableName($table) . ' ' |
|
274 | 14 | . 'USING (' . (isset($usingValues) ? $usingValues : ltrim($values, ' ')) . ') "EXCLUDED" ' |
|
275 | 14 | . "ON ($on)"; |
|
276 | 14 | $insertValues = []; |
|
277 | 14 | foreach ($insertNames as $name) { |
|
278 | 14 | $quotedName = $this->db->quoteColumnName($name); |
|
279 | 14 | if (strrpos($quotedName, '.') === false) { |
|
280 | 14 | $quotedName = '"EXCLUDED".' . $quotedName; |
|
281 | 14 | } |
|
282 | 14 | $insertValues[] = $quotedName; |
|
283 | 14 | } |
|
284 | 14 | $insertSql = 'INSERT (' . implode(', ', $insertNames) . ')' |
|
285 | 14 | . ' VALUES (' . implode(', ', $insertValues) . ')'; |
|
286 | 14 | if ($updateColumns === false) { |
|
287 | 4 | return "$mergeSql WHEN NOT MATCHED THEN $insertSql"; |
|
288 | } |
||
289 | |||
290 | 10 | if ($updateColumns === true) { |
|
291 | 4 | $updateColumns = []; |
|
292 | 4 | foreach ($updateNames as $name) { |
|
293 | 4 | $quotedName = $this->db->quoteColumnName($name); |
|
294 | 4 | if (strrpos($quotedName, '.') === false) { |
|
295 | 4 | $quotedName = '"EXCLUDED".' . $quotedName; |
|
296 | 4 | } |
|
297 | 4 | $updateColumns[$name] = new Expression($quotedName); |
|
298 | 4 | } |
|
299 | 4 | } |
|
300 | 10 | list($updates, $params) = $this->prepareUpdateSets($table, $updateColumns, $params); |
|
301 | 10 | $updateSql = 'UPDATE SET ' . implode(', ', $updates); |
|
302 | 10 | return "$mergeSql WHEN MATCHED THEN $updateSql WHEN NOT MATCHED THEN $insertSql"; |
|
303 | } |
||
304 | |||
305 | /** |
||
306 | * Creates a SELECT EXISTS() SQL statement. |
||
307 | * @param string $rawSql the subquery in a raw form to select from. |
||
308 | * @return string the SELECT EXISTS() SQL statement. |
||
309 | * |
||
310 | * @since 2.0.8 |
||
311 | */ |
||
312 | 21 | public function selectExists($rawSql) |
|
313 | { |
||
314 | 21 | return 'SELECT CASE WHEN COUNT(*)>0 THEN 1 ELSE 0 END FROM (' . $rawSql . ') CHECKEXISTS';; |
|
315 | } |
||
316 | |||
317 | /** |
||
318 | * Builds a SQL command for adding comment to column |
||
319 | * |
||
320 | * @param string $table the table whose column is to be commented. The table name will be properly quoted by the method. |
||
321 | * @param string $column the name of the column to be commented. The column name will be properly quoted by the method. |
||
322 | * @return string the SQL statement for adding comment on column |
||
323 | * @since 2.0.8 |
||
324 | */ |
||
325 | 2 | public function dropCommentFromColumn($table, $column) |
|
326 | { |
||
327 | 2 | return 'COMMENT ON COLUMN ' . $this->db->quoteTableName($table) . '.' . $this->db->quoteColumnName($column) . " IS ''"; |
|
328 | } |
||
329 | |||
330 | /** |
||
331 | * Builds a SQL command for adding comment to table |
||
332 | * |
||
333 | * @param string $table the table whose column is to be commented. The table name will be properly quoted by the method. |
||
334 | * @return string the SQL statement for adding comment on column |
||
335 | * @since 2.0.8 |
||
336 | */ |
||
337 | 1 | public function dropCommentFromTable($table) |
|
338 | { |
||
339 | 1 | return 'COMMENT ON TABLE ' . $this->db->quoteTableName($table) . " IS ''"; |
|
340 | } |
||
341 | |||
342 | /** |
||
343 | * @inheritdoc |
||
344 | */ |
||
345 | 2 | public function dropIndex($name, $table) |
|
346 | { |
||
347 | 2 | return 'DROP INDEX ' . $this->db->quoteTableName($name); |
|
348 | } |
||
349 | |||
350 | /** |
||
351 | * {@inheritdoc} |
||
352 | */ |
||
353 | 2 | public function addDefaultValue($name, $table, $column, $value) |
|
354 | { |
||
355 | 2 | return 'ALTER TABLE ' . $this->db->quoteTableName($table) |
|
356 | 2 | . ' ALTER COLUMN ' . $this->db->quoteColumnName($column) |
|
357 | 2 | . ' SET DEFAULT ' . $this->db->quoteValue($value); |
|
358 | } |
||
359 | |||
360 | /** |
||
361 | * {@inheritdoc} |
||
362 | */ |
||
363 | 2 | public function dropDefaultValue($name, $table) |
|
364 | { |
||
365 | 2 | return 'ALTER TABLE ' . $this->db->quoteTableName($table) |
|
366 | 2 | . ' ALTER COLUMN ' . $this->db->quoteColumnName($name) |
|
367 | 2 | . ' DROP DEFAULT'; |
|
368 | } |
||
369 | } |
||
370 |
This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.