1 <?php
2 3 4 5 6 7 8
9
10 defined('JPATH_PLATFORM') or die;
11
12 13 14 15 16
17 class JSchemaChangeitemMysql extends JSchemaChangeitem
18 {
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
36 protected function buildCheckQuery()
37 {
38
39 $this->checkStatus = -1;
40 $result = null;
41
42
43 $this->updateQuery = str_replace("\n", '', $this->updateQuery);
44
45
46 $find = array('#((\s*)\(\s*([^)\s]+)\s*)(\))#', '#(\s)(\s*)#');
47 $replace = array('($3)', '$1');
48 $updateQuery = preg_replace($find, $replace, $this->updateQuery);
49 $wordArray = explode(' ', $updateQuery);
50
51
52
53 if (count($wordArray) < 6)
54 {
55
56 return;
57 }
58
59
60 $command = strtoupper($wordArray[0] . ' ' . $wordArray[1]);
61
62
63 if (($command === 'UPDATE `#__UTF8_CONVERSION`'
64 || $command === 'UPDATE #__UTF8_CONVERSION')
65 && strtoupper($wordArray[2]) === 'SET'
66 && strtolower(substr(str_replace('`', '', $wordArray[3]), 0, 9)) === 'converted')
67 {
68
69 $this->queryType = 'UTF8CNV';
70
71
72 return;
73 }
74
75 if ($command === 'ALTER TABLE')
76 {
77 $alterCommand = strtoupper($wordArray[3] . ' ' . $wordArray[4]);
78
79 if ($alterCommand === 'ADD COLUMN')
80 {
81 $result = 'SHOW COLUMNS IN ' . $wordArray[2] . ' WHERE field = ' . $this->fixQuote($wordArray[5]);
82 $this->queryType = 'ADD_COLUMN';
83 $this->msgElements = array($this->fixQuote($wordArray[2]), $this->fixQuote($wordArray[5]));
84 }
85 elseif ($alterCommand === 'ADD INDEX' || $alterCommand === 'ADD KEY')
86 {
87 if ($pos = strpos($wordArray[5], '('))
88 {
89 $index = $this->fixQuote(substr($wordArray[5], 0, $pos));
90 }
91 else
92 {
93 $index = $this->fixQuote($wordArray[5]);
94 }
95
96 $result = 'SHOW INDEXES IN ' . $wordArray[2] . ' WHERE Key_name = ' . $index;
97 $this->queryType = 'ADD_INDEX';
98 $this->msgElements = array($this->fixQuote($wordArray[2]), $index);
99 }
100 elseif ($alterCommand === 'ADD UNIQUE')
101 {
102 $idxIndexName = 5;
103
104 if (isset($wordArray[6]))
105 {
106 $addCmdCheck = strtoupper($wordArray[5]);
107
108 if ($addCmdCheck === 'INDEX' || $addCmdCheck === 'KEY')
109 {
110 $idxIndexName = 6;
111 }
112 }
113
114 if ($pos = strpos($wordArray[$idxIndexName], '('))
115 {
116 $index = $this->fixQuote(substr($wordArray[$idxIndexName], 0, $pos));
117 }
118 else
119 {
120 $index = $this->fixQuote($wordArray[$idxIndexName]);
121 }
122
123 $result = 'SHOW INDEXES IN ' . $wordArray[2] . ' WHERE Key_name = ' . $index;
124 $this->queryType = 'ADD_INDEX';
125 $this->msgElements = array($this->fixQuote($wordArray[2]), $index);
126 }
127 elseif ($alterCommand === 'DROP INDEX' || $alterCommand === 'DROP KEY')
128 {
129 $index = $this->fixQuote($wordArray[5]);
130 $result = 'SHOW INDEXES IN ' . $wordArray[2] . ' WHERE Key_name = ' . $index;
131 $this->queryType = 'DROP_INDEX';
132 $this->checkQueryExpected = 0;
133 $this->msgElements = array($this->fixQuote($wordArray[2]), $index);
134 }
135 elseif ($alterCommand === 'DROP COLUMN')
136 {
137 $index = $this->fixQuote($wordArray[5]);
138 $result = 'SHOW COLUMNS IN ' . $wordArray[2] . ' WHERE Field = ' . $index;
139 $this->queryType = 'DROP_COLUMN';
140 $this->checkQueryExpected = 0;
141 $this->msgElements = array($this->fixQuote($wordArray[2]), $index);
142 }
143 elseif (strtoupper($wordArray[3]) === 'MODIFY')
144 {
145
146 $type = $wordArray[5];
147
148 if (isset($wordArray[6]))
149 {
150 $type = $this->fixInteger($wordArray[5], $wordArray[6]);
151 }
152
153 154 155 156
157 $typeCheck = $this->fixUtf8mb4TypeChecks($type);
158
159 $result = 'SHOW COLUMNS IN ' . $wordArray[2] . ' WHERE field = ' . $this->fixQuote($wordArray[4])
160 . ' AND ' . $typeCheck;
161 $this->queryType = 'CHANGE_COLUMN_TYPE';
162 $this->msgElements = array($this->fixQuote($wordArray[2]), $this->fixQuote($wordArray[4]), $type);
163 }
164 elseif (strtoupper($wordArray[3]) === 'CHANGE')
165 {
166
167 $type = $wordArray[6];
168
169 if (isset($wordArray[7]))
170 {
171 $type = $this->fixInteger($wordArray[6], $wordArray[7]);
172 }
173
174 175 176 177
178 $typeCheck = $this->fixUtf8mb4TypeChecks($type);
179
180 $result = 'SHOW COLUMNS IN ' . $wordArray[2] . ' WHERE field = ' . $this->fixQuote($wordArray[5])
181 . ' AND ' . $typeCheck;
182 $this->queryType = 'CHANGE_COLUMN_TYPE';
183 $this->msgElements = array($this->fixQuote($wordArray[2]), $this->fixQuote($wordArray[5]), $type);
184 }
185 }
186
187 if ($command === 'CREATE TABLE')
188 {
189 if (strtoupper($wordArray[2] . $wordArray[3] . $wordArray[4]) === 'IFNOTEXISTS')
190 {
191 $table = $wordArray[5];
192 }
193 else
194 {
195 $table = $wordArray[2];
196 }
197
198 $result = 'SHOW TABLES LIKE ' . $this->fixQuote($table);
199 $this->queryType = 'CREATE_TABLE';
200 $this->msgElements = array($this->fixQuote($table));
201 }
202
203
204 if ($this->checkQuery = $result)
205 {
206
207 $this->checkStatus = 0;
208 }
209 else
210 {
211
212 $this->checkStatus = -1;
213 }
214 }
215
216 217 218 219 220 221 222 223 224 225 226 227
228 private function fixInteger($type1, $type2)
229 {
230 $result = $type1;
231
232 if (strtolower($type1) === 'integer' && strtolower(substr($type2, 0, 8)) === 'unsigned')
233 {
234 $result = 'int(10) unsigned';
235 }
236 elseif (strtolower(substr($type2, 0, 8)) === 'unsigned')
237 {
238 $result = $type1 . ' unsigned';
239 }
240
241 return $result;
242 }
243
244 245 246 247 248 249 250 251 252 253 254
255 private function fixQuote($string)
256 {
257 $string = str_replace('`', '', $string);
258 $string = str_replace(';', '', $string);
259 $string = str_replace('#__', $this->db->getPrefix(), $string);
260
261 return $this->db->quote($string);
262 }
263
264 265 266 267 268 269 270 271 272 273 274
275 private function fixUtf8mb4TypeChecks($type)
276 {
277 $fixedType = str_replace(';', '', $type);
278
279 if ($this->db->hasUTF8mb4Support())
280 {
281 $uType = strtoupper($fixedType);
282
283 if ($uType === 'TINYTEXT')
284 {
285 $typeCheck = 'type IN (' . $this->db->quote('TINYTEXT') . ',' . $this->db->quote('TEXT') . ')';
286 }
287 elseif ($uType === 'TEXT')
288 {
289 $typeCheck = 'type IN (' . $this->db->quote('TEXT') . ',' . $this->db->quote('MEDIUMTEXT') . ')';
290 }
291 elseif ($uType === 'MEDIUMTEXT')
292 {
293 $typeCheck = 'type IN (' . $this->db->quote('MEDIUMTEXT') . ',' . $this->db->quote('LONGTEXT') . ')';
294 }
295 else
296 {
297 $typeCheck = 'type = ' . $this->db->quote($fixedType);
298 }
299 }
300 else
301 {
302 $typeCheck = 'type = ' . $this->db->quote($fixedType);
303 }
304
305 return $typeCheck;
306 }
307 }
308