User:NicDumZ/GSoC

Schema change

 * Convert cl_to to cl_inline, a foreign key to cat_id
 * add cat_redir . If not null, the category is a redirect, and cat_redir is the cat_id of the target category
 * Add cl_target :
 * When the included category is not a redirect, cl_target=cl_inline=cat_id
 * When the included category is a redirect, cl_inline is the cat_id of the redirect, cl_target is the cat_id of the redirect target

''cat_pages, cat_subcats, and cat_files only count the direct category inclusions. If a page belongs to a category through a category, it will not be included in these counts.''

A side effect of that schema change is that when a non-existing category is linked from an article, we now need to create a corresponding row in the category table, regardless of the existence of the said category page.

Category redirect

 * 1) redirect in category alpha includes all articles from alpha into beta.

The double redirect fixer has been tested with category redirects and is working.

Using #redirect or #redirect category:beta has the same frontend effect. However, because of the way #redirect is currently handled, the former currently makes category alpha a member of category beta. In both cases, viewing category:beta page never displays category:alpha as a member of category:beta. The only "user-viewable" consequence of that difference is in cat_pages and cat_subcats when accessed via : when using the former syntax, cat_pages and cat_subcats get incremented.

Category moves
Moving large categories is non-trivial. A new Job type has been created to defer those large category moves, see CategoryLinksUpdate.

A category move is not allowed if the target category contains pages.

Similarly, when trying to move alpha to beta, if beta has no members, we check for any CategoryLinkUpdate job in the Job Queue affecting category beta: if one such Job is pending, it means that beta will soon "gain" new members, and the move is aborted.