3 use Wikimedia\ScopedCallback;
4 use Wikimedia\TestingAccessWrapper;
15 'revision_comment_temp',
28 TestingAccessWrapper::newFromObject( $store )->stage = $stage;
39 $store = $this->
makeStore( $stage, $key );
41 $this->assertEquals( $expect,
$result );
46 'Simple table, old' => [
48 [
'ipb_reason_text' =>
'ipb_reason',
'ipb_reason_data' =>
'NULL',
'ipb_reason_cid' =>
'NULL' ],
50 'Simple table, write-both' => [
52 [
'ipb_reason_old' =>
'ipb_reason',
'ipb_reason_id' =>
'ipb_reason_id' ],
54 'Simple table, write-new' => [
56 [
'ipb_reason_old' =>
'ipb_reason',
'ipb_reason_id' =>
'ipb_reason_id' ],
58 'Simple table, new' => [
60 [
'ipb_reason_id' =>
'ipb_reason_id' ],
66 'rev_comment_text' =>
'rev_comment',
67 'rev_comment_data' =>
'NULL',
68 'rev_comment_cid' =>
'NULL',
71 'Revision, write-both' => [
73 [
'rev_comment_old' =>
'rev_comment',
'rev_comment_pk' =>
'rev_id' ],
75 'Revision, write-new' => [
77 [
'rev_comment_old' =>
'rev_comment',
'rev_comment_pk' =>
'rev_id' ],
81 [
'rev_comment_pk' =>
'rev_id' ],
87 'img_description_text' =>
'img_description',
88 'img_description_data' =>
'NULL',
89 'img_description_cid' =>
'NULL',
92 'Image, write-both' => [
94 [
'img_description_old' =>
'img_description',
'img_description_pk' =>
'img_name' ],
96 'Image, write-new' => [
98 [
'img_description_old' =>
'img_description',
'img_description_pk' =>
'img_name' ],
102 [
'img_description_pk' =>
'img_name' ],
114 $store = $this->
makeStore( $stage, $key );
116 $this->assertEquals( $expect,
$result );
121 'Simple table, old' => [
125 'ipb_reason_text' =>
'ipb_reason',
126 'ipb_reason_data' =>
'NULL',
127 'ipb_reason_cid' =>
'NULL',
132 'Simple table, write-both' => [
134 'tables' => [
'comment_ipb_reason' =>
'comment' ],
136 'ipb_reason_text' =>
'COALESCE( comment_ipb_reason.comment_text, ipb_reason )',
137 'ipb_reason_data' =>
'comment_ipb_reason.comment_data',
138 'ipb_reason_cid' =>
'comment_ipb_reason.comment_id',
141 'comment_ipb_reason' => [
'LEFT JOIN',
'comment_ipb_reason.comment_id = ipb_reason_id' ],
145 'Simple table, write-new' => [
147 'tables' => [
'comment_ipb_reason' =>
'comment' ],
149 'ipb_reason_text' =>
'COALESCE( comment_ipb_reason.comment_text, ipb_reason )',
150 'ipb_reason_data' =>
'comment_ipb_reason.comment_data',
151 'ipb_reason_cid' =>
'comment_ipb_reason.comment_id',
154 'comment_ipb_reason' => [
'LEFT JOIN',
'comment_ipb_reason.comment_id = ipb_reason_id' ],
158 'Simple table, new' => [
160 'tables' => [
'comment_ipb_reason' =>
'comment' ],
162 'ipb_reason_text' =>
'comment_ipb_reason.comment_text',
163 'ipb_reason_data' =>
'comment_ipb_reason.comment_data',
164 'ipb_reason_cid' =>
'comment_ipb_reason.comment_id',
167 'comment_ipb_reason' => [
'JOIN',
'comment_ipb_reason.comment_id = ipb_reason_id' ],
176 'rev_comment_text' =>
'rev_comment',
177 'rev_comment_data' =>
'NULL',
178 'rev_comment_cid' =>
'NULL',
183 'Revision, write-both' => [
186 'temp_rev_comment' =>
'revision_comment_temp',
187 'comment_rev_comment' =>
'comment',
190 'rev_comment_text' =>
'COALESCE( comment_rev_comment.comment_text, rev_comment )',
191 'rev_comment_data' =>
'comment_rev_comment.comment_data',
192 'rev_comment_cid' =>
'comment_rev_comment.comment_id',
195 'temp_rev_comment' => [
'LEFT JOIN',
'temp_rev_comment.revcomment_rev = rev_id' ],
196 'comment_rev_comment' => [
'LEFT JOIN',
197 'comment_rev_comment.comment_id = temp_rev_comment.revcomment_comment_id' ],
201 'Revision, write-new' => [
204 'temp_rev_comment' =>
'revision_comment_temp',
205 'comment_rev_comment' =>
'comment',
208 'rev_comment_text' =>
'COALESCE( comment_rev_comment.comment_text, rev_comment )',
209 'rev_comment_data' =>
'comment_rev_comment.comment_data',
210 'rev_comment_cid' =>
'comment_rev_comment.comment_id',
213 'temp_rev_comment' => [
'LEFT JOIN',
'temp_rev_comment.revcomment_rev = rev_id' ],
214 'comment_rev_comment' => [
'LEFT JOIN',
215 'comment_rev_comment.comment_id = temp_rev_comment.revcomment_comment_id' ],
222 'temp_rev_comment' =>
'revision_comment_temp',
223 'comment_rev_comment' =>
'comment',
226 'rev_comment_text' =>
'comment_rev_comment.comment_text',
227 'rev_comment_data' =>
'comment_rev_comment.comment_data',
228 'rev_comment_cid' =>
'comment_rev_comment.comment_id',
231 'temp_rev_comment' => [
'JOIN',
'temp_rev_comment.revcomment_rev = rev_id' ],
232 'comment_rev_comment' => [
'JOIN',
233 'comment_rev_comment.comment_id = temp_rev_comment.revcomment_comment_id' ],
242 'img_description_text' =>
'img_description',
243 'img_description_data' =>
'NULL',
244 'img_description_cid' =>
'NULL',
249 'Image, write-both' => [
252 'temp_img_description' =>
'image_comment_temp',
253 'comment_img_description' =>
'comment',
256 'img_description_text' =>
'COALESCE( comment_img_description.comment_text, img_description )',
257 'img_description_data' =>
'comment_img_description.comment_data',
258 'img_description_cid' =>
'comment_img_description.comment_id',
261 'temp_img_description' => [
'LEFT JOIN',
'temp_img_description.imgcomment_name = img_name' ],
262 'comment_img_description' => [
'LEFT JOIN',
263 'comment_img_description.comment_id = temp_img_description.imgcomment_description_id' ],
267 'Image, write-new' => [
270 'temp_img_description' =>
'image_comment_temp',
271 'comment_img_description' =>
'comment',
274 'img_description_text' =>
'COALESCE( comment_img_description.comment_text, img_description )',
275 'img_description_data' =>
'comment_img_description.comment_data',
276 'img_description_cid' =>
'comment_img_description.comment_id',
279 'temp_img_description' => [
'LEFT JOIN',
'temp_img_description.imgcomment_name = img_name' ],
280 'comment_img_description' => [
'LEFT JOIN',
281 'comment_img_description.comment_id = temp_img_description.imgcomment_description_id' ],
288 'temp_img_description' =>
'image_comment_temp',
289 'comment_img_description' =>
'comment',
292 'img_description_text' =>
'comment_img_description.comment_text',
293 'img_description_data' =>
'comment_img_description.comment_data',
294 'img_description_cid' =>
'comment_img_description.comment_id',
297 'temp_img_description' => [
'JOIN',
'temp_img_description.imgcomment_name = img_name' ],
298 'comment_img_description' => [
'JOIN',
299 'comment_img_description.comment_id = temp_img_description.imgcomment_description_id' ],
307 $this->assertSame( $expect[
'text'], $actual->text,
"text $from" );
308 $this->assertInstanceOf( get_class( $expect[
'message'] ), $actual->message,
309 "message class $from" );
310 $this->assertSame( $expect[
'message']->getKeysToTry(), $actual->message->getKeysToTry(),
311 "message keys $from" );
312 $this->assertEquals( $expect[
'message']->
text(), $actual->message->text(),
313 "message rendering $from" );
314 $this->assertEquals( $expect[
'data'], $actual->data,
"data $from" );
329 'text' => $expect[
'text'],
330 'message' =>
new RawMessage(
'$1', [ $expect[
'text'] ] ),
341 foreach ( $stages
as $writeStage => $readRange ) {
342 if ( $key ===
'ipb_reason' ) {
343 $extraFields[
'ipb_address'] = __CLASS__ .
"#$writeStage";
346 $wstore = $this->
makeStore( $writeStage, $key );
347 $usesTemp = $key ===
'rev_comment';
350 list( $fields, $callback ) = $wstore->insertWithTempTable( $this->db, $comment, $data );
352 $fields = $wstore->insert( $this->db, $comment, $data );
356 $this->assertSame( $expect[
'text'], $fields[$key],
"old field, stage=$writeStage" );
358 $this->assertArrayNotHasKey( $key, $fields,
"old field, stage=$writeStage" );
361 $this->assertArrayHasKey(
"{$key}_id", $fields,
"new field, stage=$writeStage" );
363 $this->assertArrayNotHasKey(
"{$key}_id", $fields,
"new field, stage=$writeStage" );
366 $this->db->insert( $table, $extraFields + $fields, __METHOD__ );
367 $id = $this->db->insertId();
372 for ( $readStage = $readRange[0]; $readStage <= $readRange[1]; $readStage++ ) {
373 $rstore = $this->
makeStore( $readStage, $key );
375 $fieldRow = $this->db->selectRow(
377 $rstore->getFields(),
382 $queryInfo = $rstore->getJoin();
383 $joinRow = $this->db->selectRow(
384 [ $table ] + $queryInfo[
'tables'],
385 $queryInfo[
'fields'],
394 $rstore->getCommentLegacy( $this->db, $fieldRow ),
395 "w=$writeStage, r=$readStage, from getFields()"
399 $rstore->getComment( $joinRow ),
400 "w=$writeStage, r=$readStage, from getJoin()"
409 $msgComment =
new Message(
'parentheses', [
'message comment' ] );
410 $textCommentMsg =
new RawMessage(
'$1', [
'text comment' ] );
411 $nestedMsgComment =
new Message( [
'parentheses',
'rawmessage' ], [
new Message(
'mainpage' ) ] );
413 'ipb_range_start' =>
'',
414 'ipb_range_end' =>
'',
416 'ipb_timestamp' =>
$db->timestamp(),
417 'ipb_expiry' =>
$db->getInfinity(),
424 'rev_user_text' =>
'',
425 'rev_timestamp' =>
$db->timestamp(),
428 null,
'comment store comment',
null, [
'foo' =>
'bar' ]
432 'Simple table, text comment' => [
433 'ipblocks',
'ipb_reason',
'ipb_id', $ipbfields,
'text comment',
null, [
434 'text' =>
'text comment',
435 'message' => $textCommentMsg,
439 'Simple table, text comment with data' => [
440 'ipblocks',
'ipb_reason',
'ipb_id', $ipbfields,
'text comment', [
'message' => 42 ], [
441 'text' =>
'text comment',
442 'message' => $textCommentMsg,
443 'data' => [
'message' => 42 ],
446 'Simple table, message comment' => [
447 'ipblocks',
'ipb_reason',
'ipb_id', $ipbfields, $msgComment,
null, [
448 'text' =>
'(message comment)',
449 'message' => $msgComment,
453 'Simple table, message comment with data' => [
454 'ipblocks',
'ipb_reason',
'ipb_id', $ipbfields, $msgComment, [
'message' => 42 ], [
455 'text' =>
'(message comment)',
456 'message' => $msgComment,
457 'data' => [
'message' => 42 ],
460 'Simple table, nested message comment' => [
461 'ipblocks',
'ipb_reason',
'ipb_id', $ipbfields, $nestedMsgComment,
null, [
462 'text' =>
'(Main Page)',
463 'message' => $nestedMsgComment,
467 'Simple table, CommentStoreComment' => [
468 'ipblocks',
'ipb_reason',
'ipb_id', $ipbfields, clone $comStoreComment, [
'baz' =>
'baz' ], [
469 'text' =>
'comment store comment',
470 'message' => $comStoreComment->message,
471 'data' => [
'foo' =>
'bar' ],
475 'Revision, text comment' => [
476 'revision',
'rev_comment',
'rev_id', $revfields,
'text comment',
null, [
477 'text' =>
'text comment',
478 'message' => $textCommentMsg,
482 'Revision, text comment with data' => [
483 'revision',
'rev_comment',
'rev_id', $revfields,
'text comment', [
'message' => 42 ], [
484 'text' =>
'text comment',
485 'message' => $textCommentMsg,
486 'data' => [
'message' => 42 ],
489 'Revision, message comment' => [
490 'revision',
'rev_comment',
'rev_id', $revfields, $msgComment,
null, [
491 'text' =>
'(message comment)',
492 'message' => $msgComment,
496 'Revision, message comment with data' => [
497 'revision',
'rev_comment',
'rev_id', $revfields, $msgComment, [
'message' => 42 ], [
498 'text' =>
'(message comment)',
499 'message' => $msgComment,
500 'data' => [
'message' => 42 ],
503 'Revision, nested message comment' => [
504 'revision',
'rev_comment',
'rev_id', $revfields, $nestedMsgComment,
null, [
505 'text' =>
'(Main Page)',
506 'message' => $nestedMsgComment,
510 'Revision, CommentStoreComment' => [
511 'revision',
'rev_comment',
'rev_id', $revfields, clone $comStoreComment, [
'baz' =>
'baz' ], [
512 'text' =>
'comment store comment',
513 'message' => $comStoreComment->message,
514 'data' => [
'foo' =>
'bar' ],
521 MediaWiki\suppressWarnings();
522 $reset =
new ScopedCallback(
'MediaWiki\restoreWarnings' );
525 $res = $store->getComment( [
'dummy' =>
'comment' ] );
526 $this->assertSame(
'',
$res->text );
527 $res = $store->getComment( [
'dummy' =>
'comment' ],
true );
528 $this->assertSame(
'comment',
$res->text );
532 $store->getComment( [
'dummy' =>
'comment' ] );
533 $this->fail(
'Expected exception not thrown' );
534 }
catch ( InvalidArgumentException $ex ) {
535 $this->assertSame(
'$row does not contain fields needed for comment dummy', $ex->getMessage() );
537 $res = $store->getComment( [
'dummy' =>
'comment' ],
true );
538 $this->assertSame(
'comment',
$res->text );
540 $store->getComment( [
'dummy_id' => 1 ] );
541 $this->fail(
'Expected exception not thrown' );
542 }
catch ( InvalidArgumentException $ex ) {
544 '$row does not contain fields needed for comment dummy and getComment(), '
545 .
'but does have fields for getCommentLegacy()',
552 $store->getComment( [
'rev_comment' =>
'comment' ] );
553 $this->fail(
'Expected exception not thrown' );
554 }
catch ( InvalidArgumentException $ex ) {
556 '$row does not contain fields needed for comment rev_comment', $ex->getMessage()
559 $res = $store->getComment( [
'rev_comment' =>
'comment' ],
true );
560 $this->assertSame(
'comment',
$res->text );
562 $store->getComment( [
'rev_comment_pk' => 1 ] );
563 $this->fail(
'Expected exception not thrown' );
564 }
catch ( InvalidArgumentException $ex ) {
566 '$row does not contain fields needed for comment rev_comment and getComment(), '
567 .
'but does have fields for getCommentLegacy()',
589 $store = $this->
makeStore( $stage,
'rev_comment' );
590 $store->insert( $this->db,
'foo' );
600 $store = $this->
makeStore( $stage,
'ipb_reason' );
601 $store->insertWithTempTable( $this->db,
'foo' );
610 $wrap->formerTempTables += [
'ipb_reason' =>
'1.30' ];
612 $this->
hideDeprecated(
'CommentStore::insertWithTempTable for ipb_reason' );
613 $store = $this->
makeStore( $stage,
'ipb_reason' );
614 list( $fields, $callback ) = $store->insertWithTempTable( $this->db,
'foo' );
615 $this->assertTrue( is_callable( $callback ) );
619 $comment = str_repeat(
'💣', 16400 );
620 $truncated1 = str_repeat(
'💣', 63 ) .
'...';
624 $fields = $store->insert( $this->db, $comment );
625 $this->assertSame( $truncated1, $fields[
'ipb_reason'] );
626 $stored = $this->db->selectField(
627 'comment',
'comment_text', [
'comment_id' => $fields[
'ipb_reason_id'] ], __METHOD__
629 $this->assertSame( $truncated2, $stored );
638 $store->insert( $this->db,
'foo', [
639 'long' => str_repeat(
'💣', 16400 )