Index: trunk/extensions/SemanticMediaWiki/includes/storage/SMW_SQLHelpers.php |
— | — | @@ -87,21 +87,21 @@ |
88 | 88 | */ |
89 | 89 | protected static function createTable( $tableName, array $fields, $db, $reportTo ) { |
90 | 90 | global $wgDBtype, $wgDBTableOptions, $wgDBname; |
91 | | - |
| 91 | + |
92 | 92 | $sql = 'CREATE TABLE ' . ( ( $wgDBtype == 'postgres' || $wgDBtype == 'sqlite' ) ? '' : "`$wgDBname`." ) . $tableName . ' ('; |
93 | | - |
| 93 | + |
94 | 94 | $fieldSql = array(); |
95 | | - |
| 95 | + |
96 | 96 | foreach ( $fields as $fieldName => $fieldType ) { |
97 | 97 | $fieldSql[] = "$fieldName $fieldType"; |
98 | 98 | } |
99 | | - |
| 99 | + |
100 | 100 | $sql .= implode( ',', $fieldSql ) . ') '; |
101 | | - |
| 101 | + |
102 | 102 | if ( $wgDBtype != 'postgres' && $wgDBtype != 'sqlite' ) { |
103 | 103 | $sql .= $wgDBTableOptions; |
104 | 104 | } |
105 | | - |
| 105 | + |
106 | 106 | $db->query( $sql, __METHOD__ ); |
107 | 107 | } |
108 | 108 | |
— | — | @@ -115,23 +115,22 @@ |
116 | 116 | */ |
117 | 117 | protected static function updateTable( $tableName, array $fields, $db, $reportTo ) { |
118 | 118 | global $wgDBtype; |
119 | | - |
| 119 | + |
120 | 120 | $currentFields = self::getFields( $tableName, $db, $reportTo ); |
121 | 121 | |
122 | 122 | $isPostgres = $wgDBtype == 'postgres'; |
123 | 123 | |
124 | 124 | if ( !$isPostgres ) $position = 'FIRST'; |
125 | | - |
| 125 | + |
126 | 126 | // Loop through all the field definitions, and handle each definition for either postgres or MySQL. |
127 | 127 | foreach ( $fields as $fieldName => $fieldType ) { |
128 | 128 | if ( $isPostgres ) { |
129 | 129 | self::updatePostgresField( $tableName, $fieldName, $fieldType, $currentFields, $db, $reportTo ); |
130 | | - } |
131 | | - else { |
| 130 | + } else { |
132 | 131 | self::updateMySqlField( $tableName, $fieldName, $fieldType, $currentFields, $db, $reportTo, $position ); |
133 | 132 | $position = "AFTER $fieldName"; |
134 | 133 | } |
135 | | - |
| 134 | + |
136 | 135 | $currentFields[$fieldName] = false; |
137 | 136 | } |
138 | 137 | |
— | — | @@ -140,17 +139,16 @@ |
141 | 140 | foreach ( $currentFields as $fieldName => $value ) { |
142 | 141 | if ( $value !== false ) { |
143 | 142 | SMWSQLHelpers::reportProgress( " ... deleting obsolete field $fieldName ... ", $reportTo ); |
144 | | - |
| 143 | + |
145 | 144 | if ( $isPostgres ) { |
146 | 145 | $db->query( 'ALTER TABLE "' . $tableName . '" DROP COLUMN "' . $fieldName . '"', __METHOD__ ); |
147 | | - } |
148 | | - else if ( $wgDBtype == 'sqlite' ) { |
| 146 | + } else if ( $wgDBtype == 'sqlite' ) { |
149 | 147 | // DROP COLUMN not supported in Sqlite3 |
| 148 | + SMWSQLHelpers::reportProgress( " ... deleting obsolete field $fieldName not possible in SQLLite ... you could delete and reinitialize the tables to remove obsolete data, or just keep it ... ", $reportTo ); |
| 149 | + } else { |
| 150 | + $db->query( "ALTER TABLE $tableName DROP COLUMN `$fieldName`", __METHOD__ ); |
150 | 151 | } |
151 | | - else { |
152 | | - $db->query( "ALTER TABLE $tableName DROP COLUMN `$fieldName`", __METHOD__ ); |
153 | | - } |
154 | | - |
| 152 | + |
155 | 153 | SMWSQLHelpers::reportProgress( "done.\n", $reportTo ); |
156 | 154 | } |
157 | 155 | } |
— | — | @@ -225,26 +223,26 @@ |
226 | 224 | if ( substr( $type, 0, 8 ) == 'VARCHAR(' ) { |
227 | 225 | $type .= ' binary'; // just assume this to be the case for VARCHAR, though DESCRIBE will not tell us |
228 | 226 | } |
229 | | - |
| 227 | + |
230 | 228 | if ( $row->Null != 'YES' ) { |
231 | 229 | $type .= ' NOT NULL'; |
232 | 230 | } |
233 | | - |
| 231 | + |
234 | 232 | if ( $row->Key == 'PRI' ) { /// FIXME: updating "KEY" is not possible, the below query will fail in this case. |
235 | 233 | $type .= ' KEY'; |
236 | 234 | } |
237 | | - |
| 235 | + |
238 | 236 | if ( $row->Extra == 'auto_increment' ) { |
239 | 237 | $type .= ' AUTO_INCREMENT'; |
240 | 238 | } |
241 | 239 | } |
242 | | - |
| 240 | + |
243 | 241 | $curfields[$row->Field] = $type; |
244 | 242 | } |
245 | 243 | |
246 | 244 | return $curfields; |
247 | 245 | } |
248 | | - |
| 246 | + |
249 | 247 | /** |
250 | 248 | * Update a single field given it's name and type and an array of current fields. Postgres version. |
251 | 249 | * |
— | — | @@ -257,36 +255,36 @@ |
258 | 256 | */ |
259 | 257 | protected static function updatePostgresField( $tableName, $name, $type, array $currentFields, $db, $reportTo ) { |
260 | 258 | $keypos = strpos( $type, ' PRIMARY KEY' ); |
261 | | - |
| 259 | + |
262 | 260 | if ( $keypos > 0 ) { |
263 | 261 | $type = substr( $type, 0, $keypos ); |
264 | 262 | } |
265 | | - |
| 263 | + |
266 | 264 | if ( !array_key_exists( $name, $currentFields ) ) { |
267 | 265 | self::reportProgress( " ... creating field $name ... ", $reportTo ); |
268 | | - |
| 266 | + |
269 | 267 | $db->query( "ALTER TABLE $tableName ADD \"" . $name . "\" $type", __METHOD__ ); |
270 | | - |
| 268 | + |
271 | 269 | self::reportProgress( "done.\n", $reportTo ); |
272 | 270 | } elseif ( $currentFields[$name] != $type ) { |
273 | 271 | self::reportProgress( " ... changing type of field $name from '$currentFields[$name]' to '$type' ... ", $reportTo ); |
| 272 | + |
274 | 273 | $notnullposnew = strpos( $type, ' NOT NULL' ); |
275 | | - |
276 | 274 | if ( $notnullposnew > 0 ) { |
277 | 275 | $type = substr( $type, 0, $notnullposnew ); |
278 | 276 | } |
279 | | - |
| 277 | + |
280 | 278 | $notnullposold = strpos( $currentFields[$name], ' NOT NULL' ); |
281 | 279 | $typeold = ( $notnullposold > 0 ) ? substr( $currentFields[$name], 0, $notnullposold ) : $currentFields[$name]; |
282 | | - |
| 280 | + |
283 | 281 | if ( $typeold != $type ) { |
284 | 282 | $db->query( "ALTER TABLE " . $tableName . " ALTER COLUMN \"" . $name . "\" ENGINE " . $type, __METHOD__ ); |
285 | 283 | } |
286 | | - |
| 284 | + |
287 | 285 | if ( $notnullposold != $notnullposnew ) { |
288 | 286 | $db->query( "ALTER TABLE " . $tableName . " ALTER COLUMN \"" . $name . "\" " . ( $notnullposnew > 0 ? 'SET' : 'DROP' ) . " NOT NULL", __METHOD__ ); |
289 | 287 | } |
290 | | - |
| 288 | + |
291 | 289 | self::reportProgress( "done.\n", $reportTo ); |
292 | 290 | } else { |
293 | 291 | self::reportProgress( " ... field $name is fine.\n", $reportTo ); |
— | — | @@ -307,14 +305,14 @@ |
308 | 306 | protected static function updateMySqlField( $tableName, $name, $type, array $currentFields, $db, $reportTo, $position ) { |
309 | 307 | if ( !array_key_exists( $name, $currentFields ) ) { |
310 | 308 | self::reportProgress( " ... creating field $name ... ", $reportTo ); |
311 | | - |
| 309 | + |
312 | 310 | $db->query( "ALTER TABLE $tableName ADD `$name` $type $position", __METHOD__ ); |
313 | 311 | $result[$name] = 'new'; |
314 | | - |
| 312 | + |
315 | 313 | self::reportProgress( "done.\n", $reportTo ); |
316 | 314 | } elseif ( $currentFields[$name] != $type ) { |
317 | 315 | self::reportProgress( " ... changing type of field $name from '$currentFields[$name]' to '$type' ... ", $reportTo ); |
318 | | - |
| 316 | + |
319 | 317 | $db->query( "ALTER TABLE $tableName CHANGE `$name` `$name` $type $position", __METHOD__ ); |
320 | 318 | $result[$name] = 'up'; |
321 | 319 | self::reportProgress( "done.\n", $reportTo ); |
— | — | @@ -334,7 +332,7 @@ |
335 | 333 | public static function setupIndex( $rawTableName, array $columns, $db ) { |
336 | 334 | // TODO: $verbose is not a good global name! |
337 | 335 | global $wgDBtype, $verbose; |
338 | | - |
| 336 | + |
339 | 337 | $tableName = $db->tableName( $rawTableName ); |
340 | 338 | |
341 | 339 | if ( $wgDBtype == 'postgres' ) { // postgresql |
— | — | @@ -350,7 +348,7 @@ |
351 | 349 | . " AND c.relname = '" . $tableName . "'" |
352 | 350 | . " AND NOT pg_get_indexdef(i.oid) ~ '^CREATE UNIQUE INDEX'"; |
353 | 351 | $res = $db->query( $sql, __METHOD__ ); |
354 | | - |
| 352 | + |
355 | 353 | if ( !$res ) { |
356 | 354 | return false; |
357 | 355 | } |
— | — | @@ -363,20 +361,19 @@ |
364 | 362 | $db->query( 'DROP INDEX IF EXISTS ' . $row->indexname, __METHOD__ ); |
365 | 363 | } |
366 | 364 | } |
367 | | - |
| 365 | + |
368 | 366 | foreach ( $columns as $key => $index ) { // Ddd the remaining indexes. |
369 | 367 | if ( $index != false ) { |
370 | 368 | $type = 'INDEX'; |
371 | | - |
| 369 | + |
372 | 370 | // If the index is an array, it'll contain the column name as first element, and index type as second one. |
373 | 371 | if ( is_array( $index ) ) { |
374 | 372 | $column = $index[0]; |
375 | 373 | if ( count( $index ) > 1 ) $type = $index[1]; |
376 | | - } |
377 | | - else { |
| 374 | + } else { |
378 | 375 | $column = $index; |
379 | 376 | } |
380 | | - |
| 377 | + |
381 | 378 | if ( $db->indexInfo( $rawTableName, "{$rawTableName}_index{$key}" ) === false ) { |
382 | 379 | $db->query( "CREATE $type {$rawTableName}_index{$key} ON $tableName USING btree(" . $column . ")", __METHOD__ ); |
383 | 380 | } |
— | — | @@ -384,60 +381,59 @@ |
385 | 382 | } |
386 | 383 | } elseif ( $wgDBtype == 'sqlite' ) { // SQLite |
387 | 384 | $res = $db->query( 'PRAGMA index_list(' . $tableName . ')' , __METHOD__ ); |
388 | | - |
| 385 | + |
389 | 386 | if ( !$res ) { |
390 | 387 | return false; |
391 | 388 | } |
392 | | - |
| 389 | + |
393 | 390 | $indexes = array(); |
394 | | - |
| 391 | + |
395 | 392 | foreach ( $db->fetchObject( $res ) as $row ) { |
396 | 393 | if ( !array_key_exists( $row->name, $indexes ) ) { |
397 | 394 | $indexes[$row->name] = array(); |
398 | 395 | } |
399 | | - |
| 396 | + |
400 | 397 | $indexes[$row->name][$row->seq] = $row->name; |
401 | 398 | } |
402 | | - |
| 399 | + |
403 | 400 | foreach ( $indexes as $key => $index ) { // Clean up the existing indexes. |
404 | 401 | $db->query( 'DROP INDEX ' . $key, __METHOD__ ); |
405 | 402 | } |
406 | | - |
| 403 | + |
407 | 404 | foreach ( $columns as $key => $index ) { // Add the remaining indexes. |
408 | 405 | if ( $index != false ) { |
409 | 406 | $type = 'INDEX'; |
410 | | - |
| 407 | + |
411 | 408 | // If the index is an array, it'll contain the column name as first element, and index type as second one. |
412 | 409 | if ( is_array( $index ) ) { |
413 | 410 | $column = $index[0]; |
414 | | - |
| 411 | + |
415 | 412 | if ( count( $index ) > 1 ) { |
416 | 413 | $type = $index[1]; |
417 | 414 | } |
418 | | - } |
419 | | - else { |
| 415 | + } else { |
420 | 416 | $column = $index; |
421 | 417 | } |
422 | | - |
| 418 | + |
423 | 419 | $db->query( "CREATE $type {$tableName}_index{$key} ON $tableName (" . $column . ")", __METHOD__ ); |
424 | 420 | } |
425 | 421 | } |
426 | 422 | } else { // MySQL |
427 | 423 | $res = $db->query( 'SHOW INDEX FROM ' . $tableName , __METHOD__ ); |
428 | | - |
| 424 | + |
429 | 425 | if ( !$res ) { |
430 | 426 | return false; |
431 | 427 | } |
432 | | - |
| 428 | + |
433 | 429 | $indexes = array(); |
434 | | - |
| 430 | + |
435 | 431 | foreach ( $res as $row ) { |
436 | 432 | if ( !array_key_exists( $row->Key_name, $indexes ) ) { |
437 | 433 | $indexes[$row->Key_name] = array(); |
438 | 434 | } |
439 | 435 | $indexes[$row->Key_name][$row->Seq_in_index] = $row->Column_name; |
440 | 436 | } |
441 | | - |
| 437 | + |
442 | 438 | foreach ( $indexes as $key => $index ) { // Clean up the existing indexes. |
443 | 439 | $id = array_search( implode( ',', $index ), $columns ); |
444 | 440 | if ( $id !== false ) { |
— | — | @@ -450,21 +446,20 @@ |
451 | 447 | foreach ( $columns as $key => $index ) { // Add the remaining indexes. |
452 | 448 | if ( $index != false ) { |
453 | 449 | $type = 'INDEX'; |
454 | | - |
| 450 | + |
455 | 451 | // If the index is an array, it'll contain the column name as first element, and index type as second one. |
456 | 452 | if ( is_array( $index ) ) { |
457 | 453 | $column = $index[0]; |
458 | 454 | if ( count( $index ) > 1 ) $type = $index[1]; |
459 | | - } |
460 | | - else { |
| 455 | + } else { |
461 | 456 | $column = $index; |
462 | | - } |
463 | | - |
| 457 | + } |
| 458 | + |
464 | 459 | $db->query( "ALTER TABLE $tableName ADD $type ( $column )", __METHOD__ ); |
465 | 460 | } |
466 | 461 | } |
467 | 462 | } |
468 | | - |
| 463 | + |
469 | 464 | return true; |
470 | 465 | } |
471 | 466 | |