Remove messages.inc, rebuildLanguage.php, writeMessagesArray.inc
[mediawiki.git] / tests / phpunit / includes / db / DatabaseSQLTest.php
blob5c2d4b7045cd731950bb6157a6b16975cc796054
1 <?php
3 /**
4 * Test the abstract database layer
5 * This is a non DBMS depending test.
6 */
7 class DatabaseSQLTest extends MediaWikiTestCase {
9 /**
10 * @var DatabaseTestHelper
12 private $database;
14 protected function setUp() {
15 parent::setUp();
16 $this->database = new DatabaseTestHelper( __CLASS__ );
19 protected function assertLastSql( $sqlText ) {
20 $this->assertEquals(
21 $this->database->getLastSqls(),
22 $sqlText
26 /**
27 * @dataProvider provideSelect
28 * @covers DatabaseBase::select
30 public function testSelect( $sql, $sqlText ) {
31 $this->database->select(
32 $sql['tables'],
33 $sql['fields'],
34 isset( $sql['conds'] ) ? $sql['conds'] : array(),
35 __METHOD__,
36 isset( $sql['options'] ) ? $sql['options'] : array(),
37 isset( $sql['join_conds'] ) ? $sql['join_conds'] : array()
39 $this->assertLastSql( $sqlText );
42 public static function provideSelect() {
43 return array(
44 array(
45 array(
46 'tables' => 'table',
47 'fields' => array( 'field', 'alias' => 'field2' ),
48 'conds' => array( 'alias' => 'text' ),
50 "SELECT field,field2 AS alias " .
51 "FROM table " .
52 "WHERE alias = 'text'"
54 array(
55 array(
56 'tables' => 'table',
57 'fields' => array( 'field', 'alias' => 'field2' ),
58 'conds' => array( 'alias' => 'text' ),
59 'options' => array( 'LIMIT' => 1, 'ORDER BY' => 'field' ),
61 "SELECT field,field2 AS alias " .
62 "FROM table " .
63 "WHERE alias = 'text' " .
64 "ORDER BY field " .
65 "LIMIT 1"
67 array(
68 array(
69 'tables' => array( 'table', 't2' => 'table2' ),
70 'fields' => array( 'tid', 'field', 'alias' => 'field2', 't2.id' ),
71 'conds' => array( 'alias' => 'text' ),
72 'options' => array( 'LIMIT' => 1, 'ORDER BY' => 'field' ),
73 'join_conds' => array( 't2' => array(
74 'LEFT JOIN', 'tid = t2.id'
75 ) ),
77 "SELECT tid,field,field2 AS alias,t2.id " .
78 "FROM table LEFT JOIN table2 t2 ON ((tid = t2.id)) " .
79 "WHERE alias = 'text' " .
80 "ORDER BY field " .
81 "LIMIT 1"
83 array(
84 array(
85 'tables' => array( 'table', 't2' => 'table2' ),
86 'fields' => array( 'tid', 'field', 'alias' => 'field2', 't2.id' ),
87 'conds' => array( 'alias' => 'text' ),
88 'options' => array( 'LIMIT' => 1, 'GROUP BY' => 'field', 'HAVING' => 'COUNT(*) > 1' ),
89 'join_conds' => array( 't2' => array(
90 'LEFT JOIN', 'tid = t2.id'
91 ) ),
93 "SELECT tid,field,field2 AS alias,t2.id " .
94 "FROM table LEFT JOIN table2 t2 ON ((tid = t2.id)) " .
95 "WHERE alias = 'text' " .
96 "GROUP BY field HAVING COUNT(*) > 1 " .
97 "LIMIT 1"
99 array(
100 array(
101 'tables' => array( 'table', 't2' => 'table2' ),
102 'fields' => array( 'tid', 'field', 'alias' => 'field2', 't2.id' ),
103 'conds' => array( 'alias' => 'text' ),
104 'options' => array(
105 'LIMIT' => 1,
106 'GROUP BY' => array( 'field', 'field2' ),
107 'HAVING' => array( 'COUNT(*) > 1', 'field' => 1 )
109 'join_conds' => array( 't2' => array(
110 'LEFT JOIN', 'tid = t2.id'
111 ) ),
113 "SELECT tid,field,field2 AS alias,t2.id " .
114 "FROM table LEFT JOIN table2 t2 ON ((tid = t2.id)) " .
115 "WHERE alias = 'text' " .
116 "GROUP BY field,field2 HAVING (COUNT(*) > 1) AND field = '1' " .
117 "LIMIT 1"
119 array(
120 array(
121 'tables' => array( 'table' ),
122 'fields' => array( 'alias' => 'field' ),
123 'conds' => array( 'alias' => array( 1, 2, 3, 4 ) ),
125 "SELECT field AS alias " .
126 "FROM table " .
127 "WHERE alias IN ('1','2','3','4')"
133 * @dataProvider provideUpdate
134 * @covers DatabaseBase::update
136 public function testUpdate( $sql, $sqlText ) {
137 $this->database->update(
138 $sql['table'],
139 $sql['values'],
140 $sql['conds'],
141 __METHOD__,
142 isset( $sql['options'] ) ? $sql['options'] : array()
144 $this->assertLastSql( $sqlText );
147 public static function provideUpdate() {
148 return array(
149 array(
150 array(
151 'table' => 'table',
152 'values' => array( 'field' => 'text', 'field2' => 'text2' ),
153 'conds' => array( 'alias' => 'text' ),
155 "UPDATE table " .
156 "SET field = 'text'" .
157 ",field2 = 'text2' " .
158 "WHERE alias = 'text'"
160 array(
161 array(
162 'table' => 'table',
163 'values' => array( 'field = other', 'field2' => 'text2' ),
164 'conds' => array( 'id' => '1' ),
166 "UPDATE table " .
167 "SET field = other" .
168 ",field2 = 'text2' " .
169 "WHERE id = '1'"
171 array(
172 array(
173 'table' => 'table',
174 'values' => array( 'field = other', 'field2' => 'text2' ),
175 'conds' => '*',
177 "UPDATE table " .
178 "SET field = other" .
179 ",field2 = 'text2'"
185 * @dataProvider provideDelete
186 * @covers DatabaseBase::delete
188 public function testDelete( $sql, $sqlText ) {
189 $this->database->delete(
190 $sql['table'],
191 $sql['conds'],
192 __METHOD__
194 $this->assertLastSql( $sqlText );
197 public static function provideDelete() {
198 return array(
199 array(
200 array(
201 'table' => 'table',
202 'conds' => array( 'alias' => 'text' ),
204 "DELETE FROM table " .
205 "WHERE alias = 'text'"
207 array(
208 array(
209 'table' => 'table',
210 'conds' => '*',
212 "DELETE FROM table"
218 * @dataProvider provideUpsert
219 * @covers DatabaseBase::upsert
221 public function testUpsert( $sql, $sqlText ) {
222 $this->database->upsert(
223 $sql['table'],
224 $sql['rows'],
225 $sql['uniqueIndexes'],
226 $sql['set'],
227 __METHOD__
229 $this->assertLastSql( $sqlText );
232 public static function provideUpsert() {
233 return array(
234 array(
235 array(
236 'table' => 'upsert_table',
237 'rows' => array( 'field' => 'text', 'field2' => 'text2' ),
238 'uniqueIndexes' => array( 'field' ),
239 'set' => array( 'field' => 'set' ),
241 "BEGIN; " .
242 "UPDATE upsert_table " .
243 "SET field = 'set' " .
244 "WHERE ((field = 'text')); " .
245 "INSERT IGNORE INTO upsert_table " .
246 "(field,field2) " .
247 "VALUES ('text','text2'); " .
248 "COMMIT"
254 * @dataProvider provideDeleteJoin
255 * @covers DatabaseBase::deleteJoin
257 public function testDeleteJoin( $sql, $sqlText ) {
258 $this->database->deleteJoin(
259 $sql['delTable'],
260 $sql['joinTable'],
261 $sql['delVar'],
262 $sql['joinVar'],
263 $sql['conds'],
264 __METHOD__
266 $this->assertLastSql( $sqlText );
269 public static function provideDeleteJoin() {
270 return array(
271 array(
272 array(
273 'delTable' => 'table',
274 'joinTable' => 'table_join',
275 'delVar' => 'field',
276 'joinVar' => 'field_join',
277 'conds' => array( 'alias' => 'text' ),
279 "DELETE FROM table " .
280 "WHERE field IN (" .
281 "SELECT field_join FROM table_join WHERE alias = 'text'" .
284 array(
285 array(
286 'delTable' => 'table',
287 'joinTable' => 'table_join',
288 'delVar' => 'field',
289 'joinVar' => 'field_join',
290 'conds' => '*',
292 "DELETE FROM table " .
293 "WHERE field IN (" .
294 "SELECT field_join FROM table_join " .
301 * @dataProvider provideInsert
302 * @covers DatabaseBase::insert
304 public function testInsert( $sql, $sqlText ) {
305 $this->database->insert(
306 $sql['table'],
307 $sql['rows'],
308 __METHOD__,
309 isset( $sql['options'] ) ? $sql['options'] : array()
311 $this->assertLastSql( $sqlText );
314 public static function provideInsert() {
315 return array(
316 array(
317 array(
318 'table' => 'table',
319 'rows' => array( 'field' => 'text', 'field2' => 2 ),
321 "INSERT INTO table " .
322 "(field,field2) " .
323 "VALUES ('text','2')"
325 array(
326 array(
327 'table' => 'table',
328 'rows' => array( 'field' => 'text', 'field2' => 2 ),
329 'options' => 'IGNORE',
331 "INSERT IGNORE INTO table " .
332 "(field,field2) " .
333 "VALUES ('text','2')"
335 array(
336 array(
337 'table' => 'table',
338 'rows' => array(
339 array( 'field' => 'text', 'field2' => 2 ),
340 array( 'field' => 'multi', 'field2' => 3 ),
342 'options' => 'IGNORE',
344 "INSERT IGNORE INTO table " .
345 "(field,field2) " .
346 "VALUES " .
347 "('text','2')," .
348 "('multi','3')"
354 * @dataProvider provideInsertSelect
355 * @covers DatabaseBase::insertSelect
357 public function testInsertSelect( $sql, $sqlText ) {
358 $this->database->insertSelect(
359 $sql['destTable'],
360 $sql['srcTable'],
361 $sql['varMap'],
362 $sql['conds'],
363 __METHOD__,
364 isset( $sql['insertOptions'] ) ? $sql['insertOptions'] : array(),
365 isset( $sql['selectOptions'] ) ? $sql['selectOptions'] : array()
367 $this->assertLastSql( $sqlText );
370 public static function provideInsertSelect() {
371 return array(
372 array(
373 array(
374 'destTable' => 'insert_table',
375 'srcTable' => 'select_table',
376 'varMap' => array( 'field_insert' => 'field_select', 'field' => 'field2' ),
377 'conds' => '*',
379 "INSERT INTO insert_table " .
380 "(field_insert,field) " .
381 "SELECT field_select,field2 " .
382 "FROM select_table"
384 array(
385 array(
386 'destTable' => 'insert_table',
387 'srcTable' => 'select_table',
388 'varMap' => array( 'field_insert' => 'field_select', 'field' => 'field2' ),
389 'conds' => array( 'field' => 2 ),
391 "INSERT INTO insert_table " .
392 "(field_insert,field) " .
393 "SELECT field_select,field2 " .
394 "FROM select_table " .
395 "WHERE field = '2'"
397 array(
398 array(
399 'destTable' => 'insert_table',
400 'srcTable' => 'select_table',
401 'varMap' => array( 'field_insert' => 'field_select', 'field' => 'field2' ),
402 'conds' => array( 'field' => 2 ),
403 'insertOptions' => 'IGNORE',
404 'selectOptions' => array( 'ORDER BY' => 'field' ),
406 "INSERT IGNORE INTO insert_table " .
407 "(field_insert,field) " .
408 "SELECT field_select,field2 " .
409 "FROM select_table " .
410 "WHERE field = '2' " .
411 "ORDER BY field"
417 * @dataProvider provideReplace
418 * @covers DatabaseBase::replace
420 public function testReplace( $sql, $sqlText ) {
421 $this->database->replace(
422 $sql['table'],
423 $sql['uniqueIndexes'],
424 $sql['rows'],
425 __METHOD__
427 $this->assertLastSql( $sqlText );
430 public static function provideReplace() {
431 return array(
432 array(
433 array(
434 'table' => 'replace_table',
435 'uniqueIndexes' => array( 'field' ),
436 'rows' => array( 'field' => 'text', 'field2' => 'text2' ),
438 "DELETE FROM replace_table " .
439 "WHERE ( field='text' ); " .
440 "INSERT INTO replace_table " .
441 "(field,field2) " .
442 "VALUES ('text','text2')"
444 array(
445 array(
446 'table' => 'module_deps',
447 'uniqueIndexes' => array( array( 'md_module', 'md_skin' ) ),
448 'rows' => array(
449 'md_module' => 'module',
450 'md_skin' => 'skin',
451 'md_deps' => 'deps',
454 "DELETE FROM module_deps " .
455 "WHERE ( md_module='module' AND md_skin='skin' ); " .
456 "INSERT INTO module_deps " .
457 "(md_module,md_skin,md_deps) " .
458 "VALUES ('module','skin','deps')"
460 array(
461 array(
462 'table' => 'module_deps',
463 'uniqueIndexes' => array( array( 'md_module', 'md_skin' ) ),
464 'rows' => array(
465 array(
466 'md_module' => 'module',
467 'md_skin' => 'skin',
468 'md_deps' => 'deps',
469 ), array(
470 'md_module' => 'module2',
471 'md_skin' => 'skin2',
472 'md_deps' => 'deps2',
476 "DELETE FROM module_deps " .
477 "WHERE ( md_module='module' AND md_skin='skin' ); " .
478 "INSERT INTO module_deps " .
479 "(md_module,md_skin,md_deps) " .
480 "VALUES ('module','skin','deps'); " .
481 "DELETE FROM module_deps " .
482 "WHERE ( md_module='module2' AND md_skin='skin2' ); " .
483 "INSERT INTO module_deps " .
484 "(md_module,md_skin,md_deps) " .
485 "VALUES ('module2','skin2','deps2')"
487 array(
488 array(
489 'table' => 'module_deps',
490 'uniqueIndexes' => array( 'md_module', 'md_skin' ),
491 'rows' => array(
492 array(
493 'md_module' => 'module',
494 'md_skin' => 'skin',
495 'md_deps' => 'deps',
496 ), array(
497 'md_module' => 'module2',
498 'md_skin' => 'skin2',
499 'md_deps' => 'deps2',
503 "DELETE FROM module_deps " .
504 "WHERE ( md_module='module' ) OR ( md_skin='skin' ); " .
505 "INSERT INTO module_deps " .
506 "(md_module,md_skin,md_deps) " .
507 "VALUES ('module','skin','deps'); " .
508 "DELETE FROM module_deps " .
509 "WHERE ( md_module='module2' ) OR ( md_skin='skin2' ); " .
510 "INSERT INTO module_deps " .
511 "(md_module,md_skin,md_deps) " .
512 "VALUES ('module2','skin2','deps2')"
514 array(
515 array(
516 'table' => 'module_deps',
517 'uniqueIndexes' => array(),
518 'rows' => array(
519 'md_module' => 'module',
520 'md_skin' => 'skin',
521 'md_deps' => 'deps',
524 "INSERT INTO module_deps " .
525 "(md_module,md_skin,md_deps) " .
526 "VALUES ('module','skin','deps')"
532 * @dataProvider provideNativeReplace
533 * @covers DatabaseBase::nativeReplace
535 public function testNativeReplace( $sql, $sqlText ) {
536 $this->database->nativeReplace(
537 $sql['table'],
538 $sql['rows'],
539 __METHOD__
541 $this->assertLastSql( $sqlText );
544 public static function provideNativeReplace() {
545 return array(
546 array(
547 array(
548 'table' => 'replace_table',
549 'rows' => array( 'field' => 'text', 'field2' => 'text2' ),
551 "REPLACE INTO replace_table " .
552 "(field,field2) " .
553 "VALUES ('text','text2')"
559 * @dataProvider provideConditional
560 * @covers DatabaseBase::conditional
562 public function testConditional( $sql, $sqlText ) {
563 $this->assertEquals( trim( $this->database->conditional(
564 $sql['conds'],
565 $sql['true'],
566 $sql['false']
567 ) ), $sqlText );
570 public static function provideConditional() {
571 return array(
572 array(
573 array(
574 'conds' => array( 'field' => 'text' ),
575 'true' => 1,
576 'false' => 'NULL',
578 "(CASE WHEN field = 'text' THEN 1 ELSE NULL END)"
580 array(
581 array(
582 'conds' => array( 'field' => 'text', 'field2' => 'anothertext' ),
583 'true' => 1,
584 'false' => 'NULL',
586 "(CASE WHEN field = 'text' AND field2 = 'anothertext' THEN 1 ELSE NULL END)"
588 array(
589 array(
590 'conds' => 'field=1',
591 'true' => 1,
592 'false' => 'NULL',
594 "(CASE WHEN field=1 THEN 1 ELSE NULL END)"
600 * @dataProvider provideBuildConcat
601 * @covers DatabaseBase::buildConcat
603 public function testBuildConcat( $stringList, $sqlText ) {
604 $this->assertEquals( trim( $this->database->buildConcat(
605 $stringList
606 ) ), $sqlText );
609 public static function provideBuildConcat() {
610 return array(
611 array(
612 array( 'field', 'field2' ),
613 "CONCAT(field,field2)"
615 array(
616 array( "'test'", 'field2' ),
617 "CONCAT('test',field2)"
623 * @dataProvider provideBuildLike
624 * @covers DatabaseBase::buildLike
626 public function testBuildLike( $array, $sqlText ) {
627 $this->assertEquals( trim( $this->database->buildLike(
628 $array
629 ) ), $sqlText );
632 public static function provideBuildLike() {
633 return array(
634 array(
635 'text',
636 "LIKE 'text'"
638 array(
639 array( 'text', new LikeMatch( '%' ) ),
640 "LIKE 'text%'"
642 array(
643 array( 'text', new LikeMatch( '%' ), 'text2' ),
644 "LIKE 'text%text2'"
646 array(
647 array( 'text', new LikeMatch( '_' ) ),
648 "LIKE 'text_'"
654 * @dataProvider provideUnionQueries
655 * @covers DatabaseBase::unionQueries
657 public function testUnionQueries( $sql, $sqlText ) {
658 $this->assertEquals( trim( $this->database->unionQueries(
659 $sql['sqls'],
660 $sql['all']
661 ) ), $sqlText );
664 public static function provideUnionQueries() {
665 return array(
666 array(
667 array(
668 'sqls' => array( 'RAW SQL', 'RAW2SQL' ),
669 'all' => true,
671 "(RAW SQL) UNION ALL (RAW2SQL)"
673 array(
674 array(
675 'sqls' => array( 'RAW SQL', 'RAW2SQL' ),
676 'all' => false,
678 "(RAW SQL) UNION (RAW2SQL)"
680 array(
681 array(
682 'sqls' => array( 'RAW SQL', 'RAW2SQL', 'RAW3SQL' ),
683 'all' => false,
685 "(RAW SQL) UNION (RAW2SQL) UNION (RAW3SQL)"
691 * @covers DatabaseBase::commit
693 public function testTransactionCommit() {
694 $this->database->begin( __METHOD__ );
695 $this->database->commit( __METHOD__ );
696 $this->assertLastSql( 'BEGIN; COMMIT' );
700 * @covers DatabaseBase::rollback
702 public function testTransactionRollback() {
703 $this->database->begin( __METHOD__ );
704 $this->database->rollback( __METHOD__ );
705 $this->assertLastSql( 'BEGIN; ROLLBACK' );
709 * @covers DatabaseBase::dropTable
711 public function testDropTable() {
712 $this->database->setExistingTables( array( 'table' ) );
713 $this->database->dropTable( 'table', __METHOD__ );
714 $this->assertLastSql( 'DROP TABLE table' );
718 * @covers DatabaseBase::dropTable
720 public function testDropNonExistingTable() {
721 $this->assertFalse(
722 $this->database->dropTable( 'non_existing', __METHOD__ )