3 use Wikimedia\ScopedCallback;
4 use Wikimedia\TestingAccessWrapper;
15 'revision_comment_temp',
39 TestingAccessWrapper::newFromObject( $store )->stage = $stage;
52 $this->assertEquals( $expect,
$result );
63 $result = $store->getFields( $key );
64 $this->assertEquals( $expect,
$result );
69 'Simple table, old' => [
71 [
'ipb_reason_text' =>
'ipb_reason',
'ipb_reason_data' =>
'NULL',
'ipb_reason_cid' =>
'NULL' ],
73 'Simple table, write-both' => [
75 [
'ipb_reason_old' =>
'ipb_reason',
'ipb_reason_id' =>
'ipb_reason_id' ],
77 'Simple table, write-new' => [
79 [
'ipb_reason_old' =>
'ipb_reason',
'ipb_reason_id' =>
'ipb_reason_id' ],
81 'Simple table, new' => [
83 [
'ipb_reason_id' =>
'ipb_reason_id' ],
89 'rev_comment_text' =>
'rev_comment',
90 'rev_comment_data' =>
'NULL',
91 'rev_comment_cid' =>
'NULL',
94 'Revision, write-both' => [
96 [
'rev_comment_old' =>
'rev_comment',
'rev_comment_pk' =>
'rev_id' ],
98 'Revision, write-new' => [
100 [
'rev_comment_old' =>
'rev_comment',
'rev_comment_pk' =>
'rev_id' ],
104 [
'rev_comment_pk' =>
'rev_id' ],
110 'img_description_text' =>
'img_description',
111 'img_description_data' =>
'NULL',
112 'img_description_cid' =>
'NULL',
115 'Image, write-both' => [
117 [
'img_description_old' =>
'img_description',
'img_description_pk' =>
'img_name' ],
119 'Image, write-new' => [
121 [
'img_description_old' =>
'img_description',
'img_description_pk' =>
'img_name' ],
125 [
'img_description_pk' =>
'img_name' ],
139 $this->assertEquals( $expect,
$result );
150 $result = $store->getJoin( $key );
151 $this->assertEquals( $expect,
$result );
156 'Simple table, old' => [
160 'ipb_reason_text' =>
'ipb_reason',
161 'ipb_reason_data' =>
'NULL',
162 'ipb_reason_cid' =>
'NULL',
167 'Simple table, write-both' => [
169 'tables' => [
'comment_ipb_reason' =>
'comment' ],
171 'ipb_reason_text' =>
'COALESCE( comment_ipb_reason.comment_text, ipb_reason )',
172 'ipb_reason_data' =>
'comment_ipb_reason.comment_data',
173 'ipb_reason_cid' =>
'comment_ipb_reason.comment_id',
176 'comment_ipb_reason' => [
'LEFT JOIN',
'comment_ipb_reason.comment_id = ipb_reason_id' ],
180 'Simple table, write-new' => [
182 'tables' => [
'comment_ipb_reason' =>
'comment' ],
184 'ipb_reason_text' =>
'COALESCE( comment_ipb_reason.comment_text, ipb_reason )',
185 'ipb_reason_data' =>
'comment_ipb_reason.comment_data',
186 'ipb_reason_cid' =>
'comment_ipb_reason.comment_id',
189 'comment_ipb_reason' => [
'LEFT JOIN',
'comment_ipb_reason.comment_id = ipb_reason_id' ],
193 'Simple table, new' => [
195 'tables' => [
'comment_ipb_reason' =>
'comment' ],
197 'ipb_reason_text' =>
'comment_ipb_reason.comment_text',
198 'ipb_reason_data' =>
'comment_ipb_reason.comment_data',
199 'ipb_reason_cid' =>
'comment_ipb_reason.comment_id',
202 'comment_ipb_reason' => [
'JOIN',
'comment_ipb_reason.comment_id = ipb_reason_id' ],
211 'rev_comment_text' =>
'rev_comment',
212 'rev_comment_data' =>
'NULL',
213 'rev_comment_cid' =>
'NULL',
218 'Revision, write-both' => [
221 'temp_rev_comment' =>
'revision_comment_temp',
222 'comment_rev_comment' =>
'comment',
225 'rev_comment_text' =>
'COALESCE( comment_rev_comment.comment_text, rev_comment )',
226 'rev_comment_data' =>
'comment_rev_comment.comment_data',
227 'rev_comment_cid' =>
'comment_rev_comment.comment_id',
230 'temp_rev_comment' => [
'LEFT JOIN',
'temp_rev_comment.revcomment_rev = rev_id' ],
231 'comment_rev_comment' => [
'LEFT JOIN',
232 'comment_rev_comment.comment_id = temp_rev_comment.revcomment_comment_id' ],
236 'Revision, write-new' => [
239 'temp_rev_comment' =>
'revision_comment_temp',
240 'comment_rev_comment' =>
'comment',
243 'rev_comment_text' =>
'COALESCE( comment_rev_comment.comment_text, rev_comment )',
244 'rev_comment_data' =>
'comment_rev_comment.comment_data',
245 'rev_comment_cid' =>
'comment_rev_comment.comment_id',
248 'temp_rev_comment' => [
'LEFT JOIN',
'temp_rev_comment.revcomment_rev = rev_id' ],
249 'comment_rev_comment' => [
'LEFT JOIN',
250 'comment_rev_comment.comment_id = temp_rev_comment.revcomment_comment_id' ],
257 'temp_rev_comment' =>
'revision_comment_temp',
258 'comment_rev_comment' =>
'comment',
261 'rev_comment_text' =>
'comment_rev_comment.comment_text',
262 'rev_comment_data' =>
'comment_rev_comment.comment_data',
263 'rev_comment_cid' =>
'comment_rev_comment.comment_id',
266 'temp_rev_comment' => [
'JOIN',
'temp_rev_comment.revcomment_rev = rev_id' ],
267 'comment_rev_comment' => [
'JOIN',
268 'comment_rev_comment.comment_id = temp_rev_comment.revcomment_comment_id' ],
277 'img_description_text' =>
'img_description',
278 'img_description_data' =>
'NULL',
279 'img_description_cid' =>
'NULL',
284 'Image, write-both' => [
287 'temp_img_description' =>
'image_comment_temp',
288 'comment_img_description' =>
'comment',
291 'img_description_text' =>
'COALESCE( comment_img_description.comment_text, img_description )',
292 'img_description_data' =>
'comment_img_description.comment_data',
293 'img_description_cid' =>
'comment_img_description.comment_id',
296 'temp_img_description' => [
'LEFT JOIN',
'temp_img_description.imgcomment_name = img_name' ],
297 'comment_img_description' => [
'LEFT JOIN',
298 'comment_img_description.comment_id = temp_img_description.imgcomment_description_id' ],
302 'Image, write-new' => [
305 'temp_img_description' =>
'image_comment_temp',
306 'comment_img_description' =>
'comment',
309 'img_description_text' =>
'COALESCE( comment_img_description.comment_text, img_description )',
310 'img_description_data' =>
'comment_img_description.comment_data',
311 'img_description_cid' =>
'comment_img_description.comment_id',
314 'temp_img_description' => [
'LEFT JOIN',
'temp_img_description.imgcomment_name = img_name' ],
315 'comment_img_description' => [
'LEFT JOIN',
316 'comment_img_description.comment_id = temp_img_description.imgcomment_description_id' ],
323 'temp_img_description' =>
'image_comment_temp',
324 'comment_img_description' =>
'comment',
327 'img_description_text' =>
'comment_img_description.comment_text',
328 'img_description_data' =>
'comment_img_description.comment_data',
329 'img_description_cid' =>
'comment_img_description.comment_id',
332 'temp_img_description' => [
'JOIN',
'temp_img_description.imgcomment_name = img_name' ],
333 'comment_img_description' => [
'JOIN',
334 'comment_img_description.comment_id = temp_img_description.imgcomment_description_id' ],
342 $this->assertSame( $expect[
'text'], $actual->text,
"text $from" );
343 $this->assertInstanceOf( get_class( $expect[
'message'] ), $actual->message,
344 "message class $from" );
345 $this->assertSame( $expect[
'message']->getKeysToTry(), $actual->message->getKeysToTry(),
346 "message keys $from" );
347 $this->assertEquals( $expect[
'message']->
text(), $actual->message->text(),
348 "message rendering $from" );
349 $this->assertEquals( $expect[
'data'], $actual->data,
"data $from" );
364 'text' => $expect[
'text'],
365 'message' =>
new RawMessage(
'$1', [ $expect[
'text'] ] ),
376 foreach ( $stages
as $writeStage => $readRange ) {
377 if ( $key ===
'ipb_reason' ) {
378 $extraFields[
'ipb_address'] = __CLASS__ .
"#$writeStage";
381 $wstore = $this->
makeStore( $writeStage );
382 $usesTemp = $key ===
'rev_comment';
385 list( $fields, $callback ) = $wstore->insertWithTempTable(
386 $this->db, $key, $comment, $data
389 $fields = $wstore->insert( $this->db, $key, $comment, $data );
393 $this->assertSame( $expect[
'text'], $fields[$key],
"old field, stage=$writeStage" );
395 $this->assertArrayNotHasKey( $key, $fields,
"old field, stage=$writeStage" );
398 $this->assertArrayHasKey(
"{$key}_id", $fields,
"new field, stage=$writeStage" );
400 $this->assertArrayNotHasKey(
"{$key}_id", $fields,
"new field, stage=$writeStage" );
403 $this->db->insert( $table, $extraFields + $fields, __METHOD__ );
404 $id = $this->db->insertId();
409 for ( $readStage = $readRange[0]; $readStage <= $readRange[1]; $readStage++ ) {
410 $rstore = $this->
makeStore( $readStage );
412 $fieldRow = $this->db->selectRow(
414 $rstore->getFields( $key ),
419 $queryInfo = $rstore->getJoin( $key );
420 $joinRow = $this->db->selectRow(
421 [ $table ] + $queryInfo[
'tables'],
422 $queryInfo[
'fields'],
431 $rstore->getCommentLegacy( $this->db, $key, $fieldRow ),
432 "w=$writeStage, r=$readStage, from getFields()"
436 $rstore->getComment( $key, $joinRow ),
437 "w=$writeStage, r=$readStage, from getJoin()"
454 $table, $key, $pk, $extraFields, $comment, $data, $expect
457 'text' => $expect[
'text'],
458 'message' =>
new RawMessage(
'$1', [ $expect[
'text'] ] ),
469 foreach ( $stages
as $writeStage => $readRange ) {
470 if ( $key ===
'ipb_reason' ) {
471 $extraFields[
'ipb_address'] = __CLASS__ .
"#$writeStage";
475 $usesTemp = $key ===
'rev_comment';
478 list( $fields, $callback ) = $wstore->insertWithTempTable(
479 $this->db, $comment, $data
482 $fields = $wstore->insert( $this->db, $comment, $data );
486 $this->assertSame( $expect[
'text'], $fields[$key],
"old field, stage=$writeStage" );
488 $this->assertArrayNotHasKey( $key, $fields,
"old field, stage=$writeStage" );
491 $this->assertArrayHasKey(
"{$key}_id", $fields,
"new field, stage=$writeStage" );
493 $this->assertArrayNotHasKey(
"{$key}_id", $fields,
"new field, stage=$writeStage" );
496 $this->db->insert( $table, $extraFields + $fields, __METHOD__ );
497 $id = $this->db->insertId();
502 for ( $readStage = $readRange[0]; $readStage <= $readRange[1]; $readStage++ ) {
505 $fieldRow = $this->db->selectRow(
507 $rstore->getFields(),
512 $queryInfo = $rstore->getJoin();
513 $joinRow = $this->db->selectRow(
514 [ $table ] + $queryInfo[
'tables'],
515 $queryInfo[
'fields'],
524 $rstore->getCommentLegacy( $this->db, $fieldRow ),
525 "w=$writeStage, r=$readStage, from getFields()"
529 $rstore->getComment( $joinRow ),
530 "w=$writeStage, r=$readStage, from getJoin()"
539 $msgComment =
new Message(
'parentheses', [
'message comment' ] );
540 $textCommentMsg =
new RawMessage(
'$1', [
'text comment' ] );
541 $nestedMsgComment =
new Message( [
'parentheses',
'rawmessage' ], [
new Message(
'mainpage' ) ] );
543 'ipb_range_start' =>
'',
544 'ipb_range_end' =>
'',
545 'ipb_timestamp' =>
$db->timestamp(),
546 'ipb_expiry' =>
$db->getInfinity(),
552 'rev_timestamp' =>
$db->timestamp(),
555 null,
'comment store comment',
null, [
'foo' =>
'bar' ]
559 'Simple table, text comment' => [
560 'ipblocks',
'ipb_reason',
'ipb_id', $ipbfields,
'text comment',
null, [
561 'text' =>
'text comment',
562 'message' => $textCommentMsg,
566 'Simple table, text comment with data' => [
567 'ipblocks',
'ipb_reason',
'ipb_id', $ipbfields,
'text comment', [
'message' => 42 ], [
568 'text' =>
'text comment',
569 'message' => $textCommentMsg,
570 'data' => [
'message' => 42 ],
573 'Simple table, message comment' => [
574 'ipblocks',
'ipb_reason',
'ipb_id', $ipbfields, $msgComment,
null, [
575 'text' =>
'(message comment)',
576 'message' => $msgComment,
580 'Simple table, message comment with data' => [
581 'ipblocks',
'ipb_reason',
'ipb_id', $ipbfields, $msgComment, [
'message' => 42 ], [
582 'text' =>
'(message comment)',
583 'message' => $msgComment,
584 'data' => [
'message' => 42 ],
587 'Simple table, nested message comment' => [
588 'ipblocks',
'ipb_reason',
'ipb_id', $ipbfields, $nestedMsgComment,
null, [
589 'text' =>
'(Main Page)',
590 'message' => $nestedMsgComment,
594 'Simple table, CommentStoreComment' => [
595 'ipblocks',
'ipb_reason',
'ipb_id', $ipbfields, clone $comStoreComment, [
'baz' =>
'baz' ], [
596 'text' =>
'comment store comment',
597 'message' => $comStoreComment->message,
598 'data' => [
'foo' =>
'bar' ],
602 'Revision, text comment' => [
603 'revision',
'rev_comment',
'rev_id', $revfields,
'text comment',
null, [
604 'text' =>
'text comment',
605 'message' => $textCommentMsg,
609 'Revision, text comment with data' => [
610 'revision',
'rev_comment',
'rev_id', $revfields,
'text comment', [
'message' => 42 ], [
611 'text' =>
'text comment',
612 'message' => $textCommentMsg,
613 'data' => [
'message' => 42 ],
616 'Revision, message comment' => [
617 'revision',
'rev_comment',
'rev_id', $revfields, $msgComment,
null, [
618 'text' =>
'(message comment)',
619 'message' => $msgComment,
623 'Revision, message comment with data' => [
624 'revision',
'rev_comment',
'rev_id', $revfields, $msgComment, [
'message' => 42 ], [
625 'text' =>
'(message comment)',
626 'message' => $msgComment,
627 'data' => [
'message' => 42 ],
630 'Revision, nested message comment' => [
631 'revision',
'rev_comment',
'rev_id', $revfields, $nestedMsgComment,
null, [
632 'text' =>
'(Main Page)',
633 'message' => $nestedMsgComment,
637 'Revision, CommentStoreComment' => [
638 'revision',
'rev_comment',
'rev_id', $revfields, clone $comStoreComment, [
'baz' =>
'baz' ], [
639 'text' =>
'comment store comment',
640 'message' => $comStoreComment->message,
641 'data' => [
'foo' =>
'bar' ],
648 Wikimedia\suppressWarnings();
649 $reset =
new ScopedCallback(
'Wikimedia\restoreWarnings' );
652 $res = $store->getComment(
'dummy', [
'dummy' =>
'comment' ] );
653 $this->assertSame(
'',
$res->text );
654 $res = $store->getComment(
'dummy', [
'dummy' =>
'comment' ],
true );
655 $this->assertSame(
'comment',
$res->text );
659 $store->getComment(
'dummy', [
'dummy' =>
'comment' ] );
660 $this->fail(
'Expected exception not thrown' );
661 }
catch ( InvalidArgumentException $ex ) {
662 $this->assertSame(
'$row does not contain fields needed for comment dummy', $ex->getMessage() );
664 $res = $store->getComment(
'dummy', [
'dummy' =>
'comment' ],
true );
665 $this->assertSame(
'comment',
$res->text );
667 $store->getComment(
'dummy', [
'dummy_id' => 1 ] );
668 $this->fail(
'Expected exception not thrown' );
669 }
catch ( InvalidArgumentException $ex ) {
671 '$row does not contain fields needed for comment dummy and getComment(), '
672 .
'but does have fields for getCommentLegacy()',
679 $store->getComment(
'rev_comment', [
'rev_comment' =>
'comment' ] );
680 $this->fail(
'Expected exception not thrown' );
681 }
catch ( InvalidArgumentException $ex ) {
683 '$row does not contain fields needed for comment rev_comment', $ex->getMessage()
686 $res = $store->getComment(
'rev_comment', [
'rev_comment' =>
'comment' ],
true );
687 $this->assertSame(
'comment',
$res->text );
689 $store->getComment(
'rev_comment', [
'rev_comment_pk' => 1 ] );
690 $this->fail(
'Expected exception not thrown' );
691 }
catch ( InvalidArgumentException $ex ) {
693 '$row does not contain fields needed for comment rev_comment and getComment(), '
694 .
'but does have fields for getCommentLegacy()',
717 $store->insert( $this->db,
'rev_comment',
'foo' );
728 $store->insertWithTempTable( $this->db,
'ipb_reason',
'foo' );
737 $wrap->formerTempTables += [
'ipb_reason' =>
'1.30' ];
739 $this->
hideDeprecated(
'CommentStore::insertWithTempTable for ipb_reason' );
741 list( $fields, $callback ) = $store->insertWithTempTable( $this->db,
'ipb_reason',
'foo' );
742 $this->assertTrue( is_callable( $callback ) );
746 $comment = str_repeat(
'💣', 16400 );
747 $truncated1 = str_repeat(
'💣', 63 ) .
'...';
751 $fields = $store->insert( $this->db,
'ipb_reason', $comment );
752 $this->assertSame( $truncated1, $fields[
'ipb_reason'] );
753 $stored = $this->db->selectField(
754 'comment',
'comment_text', [
'comment_id' => $fields[
'ipb_reason_id'] ], __METHOD__
756 $this->assertSame( $truncated2, $stored );
765 $store->insert( $this->db,
'ipb_reason',
'foo', [
766 'long' => str_repeat(
'💣', 16400 )