2010-08-15 18:55:08 +00:00
< ? php
2010-08-21 18:20:09 +00:00
/**
* PostgreSQL - specific updater .
*
2012-05-06 05:50:15 +00:00
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License along
* with this program ; if not , write to the Free Software Foundation , Inc . ,
* 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA .
* http :// www . gnu . org / copyleft / gpl . html
*
2010-08-21 18:20:09 +00:00
* @ file
* @ ingroup Deployment
*/
2010-12-01 20:15:45 +00:00
2010-08-15 18:55:08 +00:00
/**
* Class for handling updates to Postgres databases .
*
* @ ingroup Deployment
* @ since 1.17
*/
2010-08-21 20:23:42 +00:00
class PostgresUpdater extends DatabaseUpdater {
2010-08-22 08:07:26 +00:00
2011-11-20 17:54:47 +00:00
/**
* @ var DatabasePostgres
*/
protected $db ;
2010-08-22 08:07:26 +00:00
/**
* @ todo FIXME : Postgres should use sequential updates like Mysql , Sqlite
* and everybody else . It never got refactored like it should ' ve .
2012-02-09 21:35:05 +00:00
* @ return array
2010-08-22 08:07:26 +00:00
*/
2010-08-15 18:55:08 +00:00
protected function getCoreUpdateList () {
2010-08-22 08:07:26 +00:00
return array (
2012-03-14 20:20:53 +00:00
# rename tables 1.7.3
# r15791 Change reserved word table names "user" and "text"
2012-03-22 02:42:44 +00:00
array ( 'renameTable' , 'user' , 'mwuser' ),
array ( 'renameTable' , 'text' , 'pagecontent' ),
array ( 'renameIndex' , 'mwuser' , 'user_pkey' , 'mwuser_pkey' ),
array ( 'renameIndex' , 'mwuser' , 'user_user_name_key' , 'mwuser_user_name_key' ),
array ( 'renameIndex' , 'pagecontent' , 'text_pkey' , 'pagecontent_pkey' ),
2012-03-14 20:20:53 +00:00
2010-08-22 08:07:26 +00:00
# renamed sequences
array ( 'renameSequence' , 'ipblocks_ipb_id_val' , 'ipblocks_ipb_id_seq' ),
array ( 'renameSequence' , 'rev_rev_id_val' , 'revision_rev_id_seq' ),
array ( 'renameSequence' , 'text_old_id_val' , 'text_old_id_seq' ),
array ( 'renameSequence' , 'rc_rc_id_seq' , 'recentchanges_rc_id_seq' ),
array ( 'renameSequence' , 'log_log_id_seq' , 'logging_log_id_seq' ),
array ( 'renameSequence' , 'pr_id_val' , 'page_restrictions_pr_id_seq' ),
2011-11-16 19:54:38 +00:00
array ( 'renameSequence' , 'us_id_seq' , 'uploadstash_us_id_seq' ),
2010-08-22 08:07:26 +00:00
2012-03-22 02:42:44 +00:00
# since r58263
array ( 'renameSequence' , 'category_id_seq' , 'category_cat_id_seq' ),
# new sequences if not renamed above
array ( 'addSequence' , 'logging' , false , 'logging_log_id_seq' ),
array ( 'addSequence' , 'page_restrictions' , false , 'page_restrictions_pr_id_seq' ),
array ( 'addSequence' , 'filearchive' , 'fa_id' , 'filearchive_fa_id_seq' ),
2010-08-22 08:07:26 +00:00
# new tables
array ( 'addTable' , 'category' , 'patch-category.sql' ),
2010-09-13 14:26:38 +00:00
array ( 'addTable' , 'page' , 'patch-page.sql' ),
2010-08-22 08:07:26 +00:00
array ( 'addTable' , 'querycachetwo' , 'patch-querycachetwo.sql' ),
array ( 'addTable' , 'page_props' , 'patch-page_props.sql' ),
array ( 'addTable' , 'page_restrictions' , 'patch-page_restrictions.sql' ),
array ( 'addTable' , 'profiling' , 'patch-profiling.sql' ),
array ( 'addTable' , 'protected_titles' , 'patch-protected_titles.sql' ),
array ( 'addTable' , 'redirect' , 'patch-redirect.sql' ),
array ( 'addTable' , 'updatelog' , 'patch-updatelog.sql' ),
array ( 'addTable' , 'change_tag' , 'patch-change_tag.sql' ),
2010-12-30 18:53:48 +00:00
array ( 'addTable' , 'tag_summary' , 'patch-tag_summary.sql' ),
array ( 'addTable' , 'valid_tag' , 'patch-valid_tag.sql' ),
2010-08-22 08:07:26 +00:00
array ( 'addTable' , 'user_properties' , 'patch-user_properties.sql' ),
array ( 'addTable' , 'log_search' , 'patch-log_search.sql' ),
array ( 'addTable' , 'l10n_cache' , 'patch-l10n_cache.sql' ),
array ( 'addTable' , 'iwlinks' , 'patch-iwlinks.sql' ),
2010-09-04 04:10:23 +00:00
array ( 'addTable' , 'msg_resource' , 'patch-msg_resource.sql' ),
array ( 'addTable' , 'msg_resource_links' , 'patch-msg_resource_links.sql' ),
2010-09-04 04:14:51 +00:00
array ( 'addTable' , 'module_deps' , 'patch-module_deps.sql' ),
2011-10-24 19:55:01 +00:00
array ( 'addTable' , 'uploadstash' , 'patch-uploadstash.sql' ),
array ( 'addTable' , 'user_former_groups' , 'patch-user_former_groups.sql' ),
2012-04-13 18:55:14 +00:00
array ( 'addTable' , 'external_user' , 'patch-external_user.sql' ),
2013-01-22 00:08:09 +00:00
array ( 'addTable' , 'sites' , 'patch-sites.sql' ),
2010-08-22 08:07:26 +00:00
# Needed before new field
array ( 'convertArchive2' ),
# new fields
2012-03-22 02:42:44 +00:00
array ( 'addPgField' , 'updatelog' , 'ul_value' , 'TEXT' ),
2010-08-22 08:07:26 +00:00
array ( 'addPgField' , 'archive' , 'ar_deleted' , 'SMALLINT NOT NULL DEFAULT 0' ),
array ( 'addPgField' , 'archive' , 'ar_len' , 'INTEGER' ),
array ( 'addPgField' , 'archive' , 'ar_page_id' , 'INTEGER' ),
array ( 'addPgField' , 'archive' , 'ar_parent_id' , 'INTEGER' ),
2012-10-10 14:09:37 +00:00
array ( 'addPgField' , 'archive' , 'ar_content_model' , 'TEXT' ),
array ( 'addPgField' , 'archive' , 'ar_content_format' , 'TEXT' ),
2010-09-08 17:51:42 +00:00
array ( 'addPgField' , 'categorylinks' , 'cl_sortkey_prefix' , " TEXT NOT NULL DEFAULT '' " ),
array ( 'addPgField' , 'categorylinks' , 'cl_collation' , " TEXT NOT NULL DEFAULT 0 " ),
array ( 'addPgField' , 'categorylinks' , 'cl_type' , " TEXT NOT NULL DEFAULT 'page' " ),
2010-08-22 08:07:26 +00:00
array ( 'addPgField' , 'image' , 'img_sha1' , " TEXT NOT NULL DEFAULT '' " ),
array ( 'addPgField' , 'ipblocks' , 'ipb_allow_usertalk' , 'SMALLINT NOT NULL DEFAULT 0' ),
array ( 'addPgField' , 'ipblocks' , 'ipb_anon_only' , 'SMALLINT NOT NULL DEFAULT 0' ),
array ( 'addPgField' , 'ipblocks' , 'ipb_by_text' , " TEXT NOT NULL DEFAULT '' " ),
array ( 'addPgField' , 'ipblocks' , 'ipb_block_email' , 'SMALLINT NOT NULL DEFAULT 0' ),
array ( 'addPgField' , 'ipblocks' , 'ipb_create_account' , 'SMALLINT NOT NULL DEFAULT 1' ),
array ( 'addPgField' , 'ipblocks' , 'ipb_deleted' , 'SMALLINT NOT NULL DEFAULT 0' ),
array ( 'addPgField' , 'ipblocks' , 'ipb_enable_autoblock' , 'SMALLINT NOT NULL DEFAULT 1' ),
2012-03-28 02:44:32 +00:00
array ( 'addPgField' , 'ipblocks' , 'ipb_parent_block_id' , 'INTEGER DEFAULT NULL REFERENCES ipblocks(ipb_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED' ),
2010-08-22 08:07:26 +00:00
array ( 'addPgField' , 'filearchive' , 'fa_deleted' , 'SMALLINT NOT NULL DEFAULT 0' ),
2012-10-20 03:36:03 +00:00
array ( 'addPgField' , 'filearchive' , 'fa_sha1' , " TEXT NOT NULL DEFAULT '' " ),
2010-08-22 08:07:26 +00:00
array ( 'addPgField' , 'logging' , 'log_deleted' , 'SMALLINT NOT NULL DEFAULT 0' ),
array ( 'addPgField' , 'logging' , 'log_id' , " INTEGER NOT NULL PRIMARY KEY DEFAULT nextval('logging_log_id_seq') " ),
array ( 'addPgField' , 'logging' , 'log_params' , 'TEXT' ),
array ( 'addPgField' , 'mwuser' , 'user_editcount' , 'INTEGER' ),
array ( 'addPgField' , 'mwuser' , 'user_newpass_time' , 'TIMESTAMPTZ' ),
array ( 'addPgField' , 'oldimage' , 'oi_deleted' , 'SMALLINT NOT NULL DEFAULT 0' ),
array ( 'addPgField' , 'oldimage' , 'oi_major_mime' , " TEXT NOT NULL DEFAULT 'unknown' " ),
array ( 'addPgField' , 'oldimage' , 'oi_media_type' , 'TEXT' ),
array ( 'addPgField' , 'oldimage' , 'oi_metadata' , " BYTEA NOT NULL DEFAULT '' " ),
array ( 'addPgField' , 'oldimage' , 'oi_minor_mime' , " TEXT NOT NULL DEFAULT 'unknown' " ),
array ( 'addPgField' , 'oldimage' , 'oi_sha1' , " TEXT NOT NULL DEFAULT '' " ),
2012-10-10 14:09:37 +00:00
array ( 'addPgField' , 'page' , 'page_content_model' , 'TEXT' ),
2010-08-22 08:07:26 +00:00
array ( 'addPgField' , 'page_restrictions' , 'pr_id' , " INTEGER NOT NULL UNIQUE DEFAULT nextval('page_restrictions_pr_id_seq') " ),
array ( 'addPgField' , 'profiling' , 'pf_memory' , 'NUMERIC(18,10) NOT NULL DEFAULT 0' ),
array ( 'addPgField' , 'recentchanges' , 'rc_deleted' , 'SMALLINT NOT NULL DEFAULT 0' ),
array ( 'addPgField' , 'recentchanges' , 'rc_log_action' , 'TEXT' ),
array ( 'addPgField' , 'recentchanges' , 'rc_log_type' , 'TEXT' ),
array ( 'addPgField' , 'recentchanges' , 'rc_logid' , 'INTEGER NOT NULL DEFAULT 0' ),
array ( 'addPgField' , 'recentchanges' , 'rc_new_len' , 'INTEGER' ),
array ( 'addPgField' , 'recentchanges' , 'rc_old_len' , 'INTEGER' ),
array ( 'addPgField' , 'recentchanges' , 'rc_params' , 'TEXT' ),
array ( 'addPgField' , 'redirect' , 'rd_interwiki' , 'TEXT NULL' ),
array ( 'addPgField' , 'redirect' , 'rd_fragment' , 'TEXT NULL' ),
array ( 'addPgField' , 'revision' , 'rev_deleted' , 'SMALLINT NOT NULL DEFAULT 0' ),
array ( 'addPgField' , 'revision' , 'rev_len' , 'INTEGER' ),
array ( 'addPgField' , 'revision' , 'rev_parent_id' , 'INTEGER DEFAULT NULL' ),
2012-10-10 14:09:37 +00:00
array ( 'addPgField' , 'revision' , 'rev_content_model' , 'TEXT' ),
array ( 'addPgField' , 'revision' , 'rev_content_format' , 'TEXT' ),
2010-08-22 08:07:26 +00:00
array ( 'addPgField' , 'site_stats' , 'ss_active_users' , " INTEGER DEFAULT '-1' " ),
array ( 'addPgField' , 'user_newtalk' , 'user_last_timestamp' , 'TIMESTAMPTZ' ),
array ( 'addPgField' , 'logging' , 'log_user_text' , " TEXT NOT NULL DEFAULT '' " ),
array ( 'addPgField' , 'logging' , 'log_page' , 'INTEGER' ),
array ( 'addPgField' , 'interwiki' , 'iw_api' , " TEXT NOT NULL DEFAULT '' " ),
array ( 'addPgField' , 'interwiki' , 'iw_wikiid' , " TEXT NOT NULL DEFAULT '' " ),
2011-11-01 19:02:13 +00:00
array ( 'addPgField' , 'revision' , 'rev_sha1' , " TEXT NOT NULL DEFAULT '' " ),
array ( 'addPgField' , 'archive' , 'ar_sha1' , " TEXT NOT NULL DEFAULT '' " ),
2012-01-12 17:10:48 +00:00
array ( 'addPgField' , 'uploadstash' , 'us_chunk_inx' , " INTEGER NULL " ),
2012-01-12 22:11:12 +00:00
array ( 'addPgField' , 'job' , 'job_timestamp' , " TIMESTAMPTZ " ),
2012-10-22 16:59:04 +00:00
array ( 'addPgField' , 'job' , 'job_random' , " INTEGER NOT NULL DEFAULT 0 " ),
2012-12-26 03:56:17 +00:00
array ( 'addPgField' , 'job' , 'job_attempts' , " INTEGER NOT NULL DEFAULT 0 " ),
2012-10-22 16:59:04 +00:00
array ( 'addPgField' , 'job' , 'job_token' , " TEXT NOT NULL DEFAULT '' " ),
array ( 'addPgField' , 'job' , 'job_token_timestamp' , " TIMESTAMPTZ " ),
array ( 'addPgField' , 'job' , 'job_sha1' , " TEXT NOT NULL DEFAULT '' " ),
2010-08-22 08:07:26 +00:00
# type changes
array ( 'changeField' , 'archive' , 'ar_deleted' , 'smallint' , '' ),
array ( 'changeField' , 'archive' , 'ar_minor_edit' , 'smallint' , 'ar_minor_edit::smallint DEFAULT 0' ),
array ( 'changeField' , 'filearchive' , 'fa_deleted' , 'smallint' , '' ),
array ( 'changeField' , 'filearchive' , 'fa_height' , 'integer' , '' ),
array ( 'changeField' , 'filearchive' , 'fa_metadata' , 'bytea' , " decode(fa_metadata,'escape') " ),
array ( 'changeField' , 'filearchive' , 'fa_size' , 'integer' , '' ),
array ( 'changeField' , 'filearchive' , 'fa_width' , 'integer' , '' ),
array ( 'changeField' , 'filearchive' , 'fa_storage_group' , 'text' , '' ),
array ( 'changeField' , 'filearchive' , 'fa_storage_key' , 'text' , '' ),
array ( 'changeField' , 'image' , 'img_metadata' , 'bytea' , " decode(img_metadata,'escape') " ),
array ( 'changeField' , 'image' , 'img_size' , 'integer' , '' ),
array ( 'changeField' , 'image' , 'img_width' , 'integer' , '' ),
array ( 'changeField' , 'image' , 'img_height' , 'integer' , '' ),
2012-04-13 18:55:14 +00:00
array ( 'changeField' , 'interwiki' , 'iw_local' , 'smallint' , 'iw_local::smallint' ),
2010-08-22 08:07:26 +00:00
array ( 'changeField' , 'interwiki' , 'iw_trans' , 'smallint' , 'iw_trans::smallint DEFAULT 0' ),
array ( 'changeField' , 'ipblocks' , 'ipb_auto' , 'smallint' , 'ipb_auto::smallint DEFAULT 0' ),
array ( 'changeField' , 'ipblocks' , 'ipb_anon_only' , 'smallint' , " CASE WHEN ipb_anon_only=' ' THEN 0 ELSE ipb_anon_only::smallint END DEFAULT 0 " ),
array ( 'changeField' , 'ipblocks' , 'ipb_create_account' , 'smallint' , " CASE WHEN ipb_create_account=' ' THEN 0 ELSE ipb_create_account::smallint END DEFAULT 1 " ),
array ( 'changeField' , 'ipblocks' , 'ipb_enable_autoblock' , 'smallint' , " CASE WHEN ipb_enable_autoblock=' ' THEN 0 ELSE ipb_enable_autoblock::smallint END DEFAULT 1 " ),
array ( 'changeField' , 'ipblocks' , 'ipb_block_email' , 'smallint' , " CASE WHEN ipb_block_email=' ' THEN 0 ELSE ipb_block_email::smallint END DEFAULT 0 " ),
array ( 'changeField' , 'ipblocks' , 'ipb_address' , 'text' , 'ipb_address::text' ),
array ( 'changeField' , 'ipblocks' , 'ipb_deleted' , 'smallint' , 'ipb_deleted::smallint DEFAULT 0' ),
array ( 'changeField' , 'mwuser' , 'user_token' , 'text' , '' ),
array ( 'changeField' , 'mwuser' , 'user_email_token' , 'text' , '' ),
array ( 'changeField' , 'objectcache' , 'keyname' , 'text' , '' ),
array ( 'changeField' , 'oldimage' , 'oi_height' , 'integer' , '' ),
array ( 'changeField' , 'oldimage' , 'oi_metadata' , 'bytea' , " decode(img_metadata,'escape') " ),
array ( 'changeField' , 'oldimage' , 'oi_size' , 'integer' , '' ),
array ( 'changeField' , 'oldimage' , 'oi_width' , 'integer' , '' ),
array ( 'changeField' , 'page' , 'page_is_redirect' , 'smallint' , 'page_is_redirect::smallint DEFAULT 0' ),
array ( 'changeField' , 'page' , 'page_is_new' , 'smallint' , 'page_is_new::smallint DEFAULT 0' ),
array ( 'changeField' , 'querycache' , 'qc_value' , 'integer' , '' ),
array ( 'changeField' , 'querycachetwo' , 'qcc_value' , 'integer' , '' ),
array ( 'changeField' , 'recentchanges' , 'rc_bot' , 'smallint' , 'rc_bot::smallint DEFAULT 0' ),
array ( 'changeField' , 'recentchanges' , 'rc_deleted' , 'smallint' , '' ),
array ( 'changeField' , 'recentchanges' , 'rc_minor' , 'smallint' , 'rc_minor::smallint DEFAULT 0' ),
array ( 'changeField' , 'recentchanges' , 'rc_new' , 'smallint' , 'rc_new::smallint DEFAULT 0' ),
array ( 'changeField' , 'recentchanges' , 'rc_type' , 'smallint' , 'rc_type::smallint DEFAULT 0' ),
array ( 'changeField' , 'recentchanges' , 'rc_patrolled' , 'smallint' , 'rc_patrolled::smallint DEFAULT 0' ),
array ( 'changeField' , 'revision' , 'rev_deleted' , 'smallint' , 'rev_deleted::smallint DEFAULT 0' ),
array ( 'changeField' , 'revision' , 'rev_minor_edit' , 'smallint' , 'rev_minor_edit::smallint DEFAULT 0' ),
array ( 'changeField' , 'templatelinks' , 'tl_namespace' , 'smallint' , 'tl_namespace::smallint' ),
array ( 'changeField' , 'user_newtalk' , 'user_ip' , 'text' , 'host(user_ip)' ),
2012-04-04 13:48:14 +00:00
array ( 'changeField' , 'uploadstash' , 'us_image_bits' , 'smallint' , '' ),
2010-08-22 08:07:26 +00:00
# null changes
array ( 'changeNullableField' , 'oldimage' , 'oi_bits' , 'NULL' ),
array ( 'changeNullableField' , 'oldimage' , 'oi_timestamp' , 'NULL' ),
array ( 'changeNullableField' , 'oldimage' , 'oi_major_mime' , 'NULL' ),
array ( 'changeNullableField' , 'oldimage' , 'oi_minor_mime' , 'NULL' ),
2012-03-22 02:42:44 +00:00
array ( 'changeNullableField' , 'image' , 'img_metadata' , 'NOT NULL' ),
array ( 'changeNullableField' , 'filearchive' , 'fa_metadata' , 'NOT NULL' ),
array ( 'changeNullableField' , 'recentchanges' , 'rc_cur_id' , 'NULL' ),
2010-08-22 08:07:26 +00:00
array ( 'checkOiDeleted' ),
# New indexes
array ( 'addPgIndex' , 'archive' , 'archive_user_text' , '(ar_user_text)' ),
array ( 'addPgIndex' , 'image' , 'img_sha1' , '(img_sha1)' ),
2012-03-28 02:44:32 +00:00
array ( 'addPgIndex' , 'ipblocks' , 'ipb_parent_block_id' , '(ipb_parent_block_id)' ),
2010-08-22 08:07:26 +00:00
array ( 'addPgIndex' , 'oldimage' , 'oi_sha1' , '(oi_sha1)' ),
array ( 'addPgIndex' , 'page' , 'page_mediawiki_title' , '(page_title) WHERE page_namespace = 8' ),
2010-09-13 15:04:04 +00:00
array ( 'addPgIndex' , 'pagelinks' , 'pagelinks_title' , '(pl_title)' ),
2010-08-22 08:07:26 +00:00
array ( 'addPgIndex' , 'revision' , 'rev_text_id_idx' , '(rev_text_id)' ),
array ( 'addPgIndex' , 'recentchanges' , 'rc_timestamp_bot' , '(rc_timestamp) WHERE rc_bot = 0' ),
array ( 'addPgIndex' , 'templatelinks' , 'templatelinks_from' , '(tl_from)' ),
array ( 'addPgIndex' , 'watchlist' , 'wl_user' , '(wl_user)' ),
array ( 'addPgIndex' , 'logging' , 'logging_user_type_time' , '(log_user, log_type, log_timestamp)' ),
array ( 'addPgIndex' , 'logging' , 'logging_page_id_time' , '(log_page,log_timestamp)' ),
array ( 'addPgIndex' , 'iwlinks' , 'iwl_prefix_title_from' , '(iwl_prefix, iwl_title, iwl_from)' ),
2012-01-12 22:11:12 +00:00
array ( 'addPgIndex' , 'job' , 'job_timestamp_idx' , '(job_timestamp)' ),
2012-10-22 16:59:04 +00:00
array ( 'addPgIndex' , 'job' , 'job_sha1' , '(job_sha1)' ),
array ( 'addPgIndex' , 'job' , 'job_cmd_token' , '(job_cmd, job_token, job_random)' ),
2012-12-26 03:56:17 +00:00
array ( 'addPgIndex' , 'job' , 'job_cmd_token_id' , '(job_cmd, job_token, job_id)' ),
2012-10-20 03:36:03 +00:00
array ( 'addPgIndex' , 'filearchive' , 'fa_sha1' , '(fa_sha1)' ),
2010-08-22 08:07:26 +00:00
2012-03-22 02:42:44 +00:00
array ( 'checkIndex' , 'pagelink_unique' , array (
array ( 'pl_from' , 'int4_ops' , 'btree' , 0 ),
array ( 'pl_namespace' , 'int2_ops' , 'btree' , 0 ),
array ( 'pl_title' , 'text_ops' , 'btree' , 0 ),
),
'CREATE UNIQUE INDEX pagelink_unique ON pagelinks (pl_from,pl_namespace,pl_title)' ),
array ( 'checkIndex' , 'cl_sortkey' , array (
array ( 'cl_to' , 'text_ops' , 'btree' , 0 ),
array ( 'cl_sortkey' , 'text_ops' , 'btree' , 0 ),
array ( 'cl_from' , 'int4_ops' , 'btree' , 0 ),
),
'CREATE INDEX cl_sortkey ON "categorylinks" USING "btree" ("cl_to", "cl_sortkey", "cl_from")' ),
array ( 'checkIndex' , 'logging_times' , array (
array ( 'log_timestamp' , 'timestamptz_ops' , 'btree' , 0 ),
),
'CREATE INDEX "logging_times" ON "logging" USING "btree" ("log_timestamp")' ),
array ( 'dropIndex' , 'oldimage' , 'oi_name' ),
array ( 'checkIndex' , 'oi_name_archive_name' , array (
array ( 'oi_name' , 'text_ops' , 'btree' , 0 ),
array ( 'oi_archive_name' , 'text_ops' , 'btree' , 0 ),
),
'CREATE INDEX "oi_name_archive_name" ON "oldimage" USING "btree" ("oi_name", "oi_archive_name")' ),
array ( 'checkIndex' , 'oi_name_timestamp' , array (
array ( 'oi_name' , 'text_ops' , 'btree' , 0 ),
array ( 'oi_timestamp' , 'timestamptz_ops' , 'btree' , 0 ),
),
'CREATE INDEX "oi_name_timestamp" ON "oldimage" USING "btree" ("oi_name", "oi_timestamp")' ),
array ( 'checkIndex' , 'page_main_title' , array (
array ( 'page_title' , 'text_pattern_ops' , 'btree' , 0 ),
),
'CREATE INDEX "page_main_title" ON "page" USING "btree" ("page_title" "text_pattern_ops") WHERE ("page_namespace" = 0)' ),
array ( 'checkIndex' , 'page_mediawiki_title' , array (
array ( 'page_title' , 'text_pattern_ops' , 'btree' , 0 ),
),
'CREATE INDEX "page_mediawiki_title" ON "page" USING "btree" ("page_title" "text_pattern_ops") WHERE ("page_namespace" = 8)' ),
array ( 'checkIndex' , 'page_project_title' , array (
array ( 'page_title' , 'text_pattern_ops' , 'btree' , 0 ),
),
'CREATE INDEX "page_project_title" ON "page" USING "btree" ("page_title" "text_pattern_ops") WHERE ("page_namespace" = 4)' ),
array ( 'checkIndex' , 'page_talk_title' , array (
array ( 'page_title' , 'text_pattern_ops' , 'btree' , 0 ),
),
'CREATE INDEX "page_talk_title" ON "page" USING "btree" ("page_title" "text_pattern_ops") WHERE ("page_namespace" = 1)' ),
array ( 'checkIndex' , 'page_user_title' , array (
array ( 'page_title' , 'text_pattern_ops' , 'btree' , 0 ),
),
'CREATE INDEX "page_user_title" ON "page" USING "btree" ("page_title" "text_pattern_ops") WHERE ("page_namespace" = 2)' ),
array ( 'checkIndex' , 'page_utalk_title' , array (
array ( 'page_title' , 'text_pattern_ops' , 'btree' , 0 ),
),
'CREATE INDEX "page_utalk_title" ON "page" USING "btree" ("page_title" "text_pattern_ops") WHERE ("page_namespace" = 3)' ),
array ( 'checkIndex' , 'ts2_page_text' , array (
array ( 'textvector' , 'tsvector_ops' , 'gist' , 0 ),
),
'CREATE INDEX "ts2_page_text" ON "pagecontent" USING "gist" ("textvector")' ),
array ( 'checkIndex' , 'ts2_page_title' , array (
array ( 'titlevector' , 'tsvector_ops' , 'gist' , 0 ),
),
'CREATE INDEX "ts2_page_title" ON "page" USING "gist" ("titlevector")' ),
2010-08-22 08:07:26 +00:00
array ( 'checkOiNameConstraint' ),
array ( 'checkPageDeletedTrigger' ),
array ( 'checkRevUserFkey' ),
2012-03-22 02:42:44 +00:00
array ( 'dropIndex' , 'ipblocks' , 'ipb_address' ),
array ( 'checkIndex' , 'ipb_address_unique' , array (
array ( 'ipb_address' , 'text_ops' , 'btree' , 0 ),
array ( 'ipb_user' , 'int4_ops' , 'btree' , 0 ),
array ( 'ipb_auto' , 'int2_ops' , 'btree' , 0 ),
array ( 'ipb_anon_only' , 'int2_ops' , 'btree' , 0 ),
),
'CREATE UNIQUE INDEX ipb_address_unique ON ipblocks (ipb_address,ipb_user,ipb_auto,ipb_anon_only)' ),
2010-08-22 08:07:26 +00:00
array ( 'checkIwlPrefix' ),
# All FK columns should be deferred
array ( 'changeFkeyDeferrable' , 'archive' , 'ar_user' , 'mwuser(user_id) ON DELETE SET NULL' ),
array ( 'changeFkeyDeferrable' , 'categorylinks' , 'cl_from' , 'page(page_id) ON DELETE CASCADE' ),
array ( 'changeFkeyDeferrable' , 'externallinks' , 'el_from' , 'page(page_id) ON DELETE CASCADE' ),
array ( 'changeFkeyDeferrable' , 'filearchive' , 'fa_deleted_user' , 'mwuser(user_id) ON DELETE SET NULL' ),
array ( 'changeFkeyDeferrable' , 'filearchive' , 'fa_user' , 'mwuser(user_id) ON DELETE SET NULL' ),
array ( 'changeFkeyDeferrable' , 'image' , 'img_user' , 'mwuser(user_id) ON DELETE SET NULL' ),
array ( 'changeFkeyDeferrable' , 'imagelinks' , 'il_from' , 'page(page_id) ON DELETE CASCADE' ),
array ( 'changeFkeyDeferrable' , 'ipblocks' , 'ipb_by' , 'mwuser(user_id) ON DELETE CASCADE' ),
array ( 'changeFkeyDeferrable' , 'ipblocks' , 'ipb_user' , 'mwuser(user_id) ON DELETE SET NULL' ),
2012-03-28 02:44:32 +00:00
array ( 'changeFkeyDeferrable' , 'ipblocks' , 'ipb_parent_block_id' , 'ipblocks(ipb_id) ON DELETE SET NULL' ),
2010-08-22 08:07:26 +00:00
array ( 'changeFkeyDeferrable' , 'langlinks' , 'll_from' , 'page(page_id) ON DELETE CASCADE' ),
array ( 'changeFkeyDeferrable' , 'logging' , 'log_user' , 'mwuser(user_id) ON DELETE SET NULL' ),
array ( 'changeFkeyDeferrable' , 'oldimage' , 'oi_name' , 'image(img_name) ON DELETE CASCADE ON UPDATE CASCADE' ),
array ( 'changeFkeyDeferrable' , 'oldimage' , 'oi_user' , 'mwuser(user_id) ON DELETE SET NULL' ),
array ( 'changeFkeyDeferrable' , 'pagelinks' , 'pl_from' , 'page(page_id) ON DELETE CASCADE' ),
array ( 'changeFkeyDeferrable' , 'page_props' , 'pp_page' , 'page (page_id) ON DELETE CASCADE' ),
array ( 'changeFkeyDeferrable' , 'page_restrictions' , 'pr_page' , 'page(page_id) ON DELETE CASCADE' ),
array ( 'changeFkeyDeferrable' , 'protected_titles' , 'pt_user' , 'mwuser(user_id) ON DELETE SET NULL' ),
array ( 'changeFkeyDeferrable' , 'recentchanges' , 'rc_cur_id' , 'page(page_id) ON DELETE SET NULL' ),
array ( 'changeFkeyDeferrable' , 'recentchanges' , 'rc_user' , 'mwuser(user_id) ON DELETE SET NULL' ),
array ( 'changeFkeyDeferrable' , 'redirect' , 'rd_from' , 'page(page_id) ON DELETE CASCADE' ),
array ( 'changeFkeyDeferrable' , 'revision' , 'rev_page' , 'page (page_id) ON DELETE CASCADE' ),
array ( 'changeFkeyDeferrable' , 'revision' , 'rev_user' , 'mwuser(user_id) ON DELETE RESTRICT' ),
array ( 'changeFkeyDeferrable' , 'templatelinks' , 'tl_from' , 'page(page_id) ON DELETE CASCADE' ),
array ( 'changeFkeyDeferrable' , 'user_groups' , 'ug_user' , 'mwuser(user_id) ON DELETE CASCADE' ),
array ( 'changeFkeyDeferrable' , 'user_newtalk' , 'user_id' , 'mwuser(user_id) ON DELETE CASCADE' ),
array ( 'changeFkeyDeferrable' , 'user_properties' , 'up_user' , 'mwuser(user_id) ON DELETE CASCADE' ),
array ( 'changeFkeyDeferrable' , 'watchlist' , 'wl_user' , 'mwuser(user_id) ON DELETE CASCADE' ),
2012-03-22 02:42:44 +00:00
# r81574
array ( 'addInterwikiType' ),
2010-08-22 08:07:26 +00:00
# end
array ( 'tsearchFixes' ),
);
}
protected function getOldGlobalUpdates () {
global $wgExtNewTables , $wgExtPGNewFields , $wgExtPGAlteredFields , $wgExtNewIndexes ;
$updates = array ();
# Add missing extension tables
foreach ( $wgExtNewTables as $tableRecord ) {
$updates [] = array (
'addTable' , $tableRecord [ 0 ], $tableRecord [ 1 ], true
);
}
# Add missing extension fields
2010-10-14 20:31:34 +00:00
foreach ( $wgExtPGNewFields as $fieldRecord ) {
2010-08-22 08:07:26 +00:00
$updates [] = array (
'addPgField' , $fieldRecord [ 0 ], $fieldRecord [ 1 ],
$fieldRecord [ 2 ]
);
}
# Change altered columns
foreach ( $wgExtPGAlteredFields as $fieldRecord ) {
$updates [] = array (
'changeField' , $fieldRecord [ 0 ], $fieldRecord [ 1 ],
$fieldRecord [ 2 ]
);
}
# Add missing extension indexes
2010-10-14 20:34:01 +00:00
foreach ( $wgExtNewIndexes as $fieldRecord ) {
2010-08-22 08:07:26 +00:00
$updates [] = array (
'addPgExtIndex' , $fieldRecord [ 0 ], $fieldRecord [ 1 ],
$fieldRecord [ 2 ]
);
}
2010-12-01 20:15:45 +00:00
2010-08-22 08:07:26 +00:00
return $updates ;
}
protected function describeTable ( $table ) {
$q = <<< END
SELECT attname , attnum FROM pg_namespace , pg_class , pg_attribute
WHERE pg_class . relnamespace = pg_namespace . oid
AND attrelid = pg_class . oid AND attnum > 0
AND relname =% s AND nspname =% s
END ;
$res = $this -> db -> query ( sprintf ( $q ,
$this -> db -> addQuotes ( $table ),
2012-03-09 17:24:57 +00:00
$this -> db -> addQuotes ( $this -> db -> getCoreSchema () ) ) );
2010-08-22 08:07:26 +00:00
if ( ! $res ) {
return null ;
}
$cols = array ();
2010-10-13 23:11:40 +00:00
foreach ( $res as $r ) {
2010-08-22 08:07:26 +00:00
$cols [] = array (
" name " => $r [ 0 ],
" ord " => $r [ 1 ],
);
}
return $cols ;
}
function describeIndex ( $idx ) {
// first fetch the key (which is a list of columns ords) and
// the table the index applies to (an oid)
$q = <<< END
SELECT indkey , indrelid FROM pg_namespace , pg_class , pg_index
WHERE nspname =% s
AND pg_class . relnamespace = pg_namespace . oid
AND relname =% s
AND indexrelid = pg_class . oid
END ;
$res = $this -> db -> query (
sprintf (
$q ,
2012-03-09 19:01:30 +00:00
$this -> db -> addQuotes ( $this -> db -> getCoreSchema () ),
2010-08-22 08:07:26 +00:00
$this -> db -> addQuotes ( $idx )
)
);
if ( ! $res ) {
return null ;
}
if ( ! ( $r = $this -> db -> fetchRow ( $res ) ) ) {
return null ;
}
$indkey = $r [ 0 ];
$relid = intval ( $r [ 1 ] );
$indkeys = explode ( ' ' , $indkey );
$colnames = array ();
foreach ( $indkeys as $rid ) {
$query = <<< END
SELECT attname FROM pg_class , pg_attribute
WHERE attrelid = $relid
AND attnum =% d
AND attrelid = pg_class . oid
END ;
$r2 = $this -> db -> query ( sprintf ( $query , $rid ) );
if ( ! $r2 ) {
return null ;
}
if ( ! ( $row2 = $this -> db -> fetchRow ( $r2 ) ) ) {
return null ;
}
$colnames [] = $row2 [ 0 ];
}
return $colnames ;
}
function fkeyDeltype ( $fkey ) {
$q = <<< END
SELECT confdeltype FROM pg_constraint , pg_namespace
WHERE connamespace = pg_namespace . oid
AND nspname =% s
AND conname =% s ;
END ;
$r = $this -> db -> query (
sprintf (
$q ,
2012-03-09 17:24:57 +00:00
$this -> db -> addQuotes ( $this -> db -> getCoreSchema () ),
2010-08-22 08:07:26 +00:00
$this -> db -> addQuotes ( $fkey )
)
);
if ( ! ( $row = $this -> db -> fetchRow ( $r ) ) ) {
return null ;
}
return $row [ 0 ];
}
function ruleDef ( $table , $rule ) {
$q = <<< END
SELECT definition FROM pg_rules
WHERE schemaname = % s
AND tablename = % s
AND rulename = % s
END ;
$r = $this -> db -> query (
sprintf (
$q ,
2012-03-09 17:24:57 +00:00
$this -> db -> addQuotes ( $this -> db -> getCoreSchema () ),
2010-08-22 08:07:26 +00:00
$this -> db -> addQuotes ( $table ),
$this -> db -> addQuotes ( $rule )
)
);
$row = $this -> db -> fetchRow ( $r );
if ( ! $row ) {
return null ;
}
$d = $row [ 0 ];
return $d ;
}
2012-03-22 02:42:44 +00:00
protected function addSequence ( $table , $pkey , $ns ) {
2010-08-22 08:07:26 +00:00
if ( ! $this -> db -> sequenceExists ( $ns ) ) {
2010-10-01 15:11:06 +00:00
$this -> output ( " Creating sequence $ns\n " );
2010-08-22 08:07:26 +00:00
$this -> db -> query ( " CREATE SEQUENCE $ns " );
2012-03-22 02:42:44 +00:00
if ( $pkey !== false ) {
$this -> setDefault ( $table , $pkey , '"nextval"(\'"' . $ns . '"\'::"regclass")' );
}
2010-08-22 08:07:26 +00:00
}
}
protected function renameSequence ( $old , $new ) {
2011-11-20 17:54:47 +00:00
if ( $this -> db -> sequenceExists ( $new ) ) {
2012-03-14 00:36:11 +00:00
$this -> output ( " ...sequence $new already exists. \n " );
2011-11-20 17:54:47 +00:00
return ;
}
2010-08-22 08:07:26 +00:00
if ( $this -> db -> sequenceExists ( $old ) ) {
2010-10-01 15:11:06 +00:00
$this -> output ( " Renaming sequence $old to $new\n " );
2010-08-22 08:07:26 +00:00
$this -> db -> query ( " ALTER SEQUENCE $old RENAME TO $new " );
}
}
2012-03-22 02:42:44 +00:00
protected function renameTable ( $old , $new , $patch = false ) {
2010-12-01 20:15:45 +00:00
if ( $this -> db -> tableExists ( $old ) ) {
$this -> output ( " Renaming table $old to $new\n " );
2012-03-14 20:20:53 +00:00
$old = $this -> db -> realTableName ( $old , " quoted " );
$new = $this -> db -> realTableName ( $new , " quoted " );
2011-02-23 16:42:42 +00:00
$this -> db -> query ( " ALTER TABLE $old RENAME TO $new " );
2012-03-22 02:42:44 +00:00
if ( $patch !== false ) {
$this -> applyPatch ( $patch );
}
}
}
protected function renameIndex ( $table , $old , $new ) {
if ( $this -> db -> indexExists ( $table , $old ) ) {
$this -> output ( " Renaming index $old to $new\n " );
$this -> db -> query ( " ALTER INDEX $old RENAME TO $new " );
2010-12-01 20:15:45 +00:00
}
}
2010-08-22 08:07:26 +00:00
protected function addPgField ( $table , $field , $type ) {
$fi = $this -> db -> fieldInfo ( $table , $field );
if ( ! is_null ( $fi ) ) {
2012-03-14 00:36:11 +00:00
$this -> output ( " ...column ' $table . $field ' already exists \n " );
2010-08-22 08:07:26 +00:00
return ;
} else {
2011-02-04 20:05:05 +00:00
$this -> output ( " Adding column ' $table . $field ' \n " );
2010-08-22 08:07:26 +00:00
$this -> db -> query ( " ALTER TABLE $table ADD $field $type " );
}
2010-08-15 18:55:08 +00:00
}
2010-08-22 08:07:26 +00:00
protected function changeField ( $table , $field , $newtype , $default ) {
$fi = $this -> db -> fieldInfo ( $table , $field );
if ( is_null ( $fi ) ) {
2012-03-14 00:36:11 +00:00
$this -> output ( " ...ERROR: expected column $table . $field to exist \n " );
2010-08-22 08:07:26 +00:00
exit ( 1 );
}
if ( $fi -> type () === $newtype )
2012-03-14 00:36:11 +00:00
$this -> output ( " ...column ' $table . $field ' is already of type ' $newtype ' \n " );
2010-08-22 08:07:26 +00:00
else {
2011-02-04 20:05:05 +00:00
$this -> output ( " Changing column type of ' $table . $field ' from ' { $fi -> type () } ' to ' $newtype ' \n " );
2010-08-22 08:07:26 +00:00
$sql = " ALTER TABLE $table ALTER $field TYPE $newtype " ;
if ( strlen ( $default ) ) {
$res = array ();
if ( preg_match ( '/DEFAULT (.+)/' , $default , $res ) ) {
$sqldef = " ALTER TABLE $table ALTER $field SET DEFAULT $res[1] " ;
$this -> db -> query ( $sqldef );
$default = preg_replace ( '/\s*DEFAULT .+/' , '' , $default );
}
$sql .= " USING $default " ;
}
$this -> db -> query ( $sql );
}
}
2012-03-22 02:42:44 +00:00
protected function setDefault ( $table , $field , $default ) {
$info = $this -> db -> fieldInfo ( $table , $field );
if ( $info -> defaultValue () !== $default ) {
$this -> output ( " Changing ' $table . $field ' default value \n " );
$this -> db -> query ( " ALTER TABLE $table ALTER $field SET DEFAULT " . $default );
}
}
protected function changeNullableField ( $table , $field , $null ) {
2010-08-22 08:07:26 +00:00
$fi = $this -> db -> fieldInfo ( $table , $field );
if ( is_null ( $fi ) ) {
2012-03-14 00:36:11 +00:00
$this -> output ( " ...ERROR: expected column $table . $field to exist \n " );
2010-08-22 08:07:26 +00:00
exit ( 1 );
}
2010-11-21 19:56:51 +00:00
if ( $fi -> isNullable () ) {
2010-08-22 08:07:26 +00:00
# # It's NULL - does it need to be NOT NULL?
if ( 'NOT NULL' === $null ) {
2011-02-04 20:05:05 +00:00
$this -> output ( " Changing ' $table . $field ' to not allow NULLs \n " );
2010-08-22 08:07:26 +00:00
$this -> db -> query ( " ALTER TABLE $table ALTER $field SET NOT NULL " );
} else {
2012-03-14 00:36:11 +00:00
$this -> output ( " ...column ' $table . $field ' is already set as NULL \n " );
2010-08-22 08:07:26 +00:00
}
} else {
# # It's NOT NULL - does it need to be NULL?
if ( 'NULL' === $null ) {
2011-02-04 20:05:05 +00:00
$this -> output ( " Changing ' $table . $field ' to allow NULLs \n " );
2010-08-22 08:07:26 +00:00
$this -> db -> query ( " ALTER TABLE $table ALTER $field DROP NOT NULL " );
}
else {
2012-03-14 00:36:11 +00:00
$this -> output ( " ...column ' $table . $field ' is already set as NOT NULL \n " );
2010-08-22 08:07:26 +00:00
}
}
}
public function addPgIndex ( $table , $index , $type ) {
if ( $this -> db -> indexExists ( $table , $index ) ) {
2012-03-14 00:36:11 +00:00
$this -> output ( " ...index ' $index ' on table ' $table ' already exists \n " );
2010-08-22 08:07:26 +00:00
} else {
2011-02-04 20:05:05 +00:00
$this -> output ( " Creating index ' $index ' on table ' $table ' $type\n " );
2010-08-22 08:07:26 +00:00
$this -> db -> query ( " CREATE INDEX $index ON $table $type " );
}
}
public function addPgExtIndex ( $table , $index , $type ) {
2010-08-22 08:32:29 +00:00
if ( $this -> db -> indexExists ( $table , $index ) ) {
2012-03-14 00:36:11 +00:00
$this -> output ( " ...index ' $index ' on table ' $table ' already exists \n " );
2010-08-22 08:07:26 +00:00
} else {
if ( preg_match ( '/^\(/' , $type ) ) {
2012-07-08 08:00:36 +00:00
$this -> output ( " Creating index ' $index ' on table ' $table ' \n " );
2010-08-22 08:07:26 +00:00
$this -> db -> query ( " CREATE INDEX $index ON $table $type " );
} else {
2012-07-08 08:00:36 +00:00
$this -> applyPatch ( $type , true , " Creating index ' $index ' on table ' $table ' " );
2010-08-22 08:07:26 +00:00
}
}
}
protected function changeFkeyDeferrable ( $table , $field , $clause ) {
$fi = $this -> db -> fieldInfo ( $table , $field );
if ( is_null ( $fi ) ) {
2011-02-04 20:05:05 +00:00
$this -> output ( " WARNING! Column ' $table . $field ' does not exist but it should! Please report this. \n " );
2010-08-22 08:07:26 +00:00
return ;
}
if ( $fi -> is_deferred () && $fi -> is_deferrable () ) {
return ;
}
2011-02-04 20:05:05 +00:00
$this -> output ( " Altering column ' $table . $field ' to be DEFERRABLE INITIALLY DEFERRED \n " );
2010-08-22 08:07:26 +00:00
$conname = $fi -> conname ();
2012-03-28 21:23:13 +00:00
if ( $fi -> conname () ) {
$conclause = " CONSTRAINT \" $conname\ " " ;
$command = " ALTER TABLE $table DROP CONSTRAINT $conname " ;
$this -> db -> query ( $command );
} else {
$this -> output ( " Column ' $table . $field ' does not have a foreign key constraint, will be added \n " );
$conclause = " " ;
}
$command = " ALTER TABLE $table ADD $conclause FOREIGN KEY ( $field ) REFERENCES $clause DEFERRABLE INITIALLY DEFERRED " ;
2010-08-22 08:07:26 +00:00
$this -> db -> query ( $command );
}
protected function convertArchive2 () {
if ( $this -> db -> tableExists ( " archive2 " ) ) {
if ( $this -> db -> ruleExists ( 'archive' , 'archive_insert' ) ) {
2011-02-04 20:05:05 +00:00
$this -> output ( " Dropping rule 'archive_insert' \n " );
2010-08-22 08:07:26 +00:00
$this -> db -> query ( 'DROP RULE archive_insert ON archive' );
}
if ( $this -> db -> ruleExists ( 'archive' , 'archive_delete' ) ) {
2011-02-04 20:05:05 +00:00
$this -> output ( " Dropping rule 'archive_delete' \n " );
2010-08-22 08:07:26 +00:00
$this -> db -> query ( 'DROP RULE archive_delete ON archive' );
}
2012-07-08 08:00:36 +00:00
$this -> applyPatch ( 'patch-remove-archive2.sql' , false , " Converting 'archive2' back to normal archive table " );
2010-08-22 08:07:26 +00:00
} else {
2012-03-14 00:36:11 +00:00
$this -> output ( " ...obsolete table 'archive2' does not exist \n " );
2010-08-22 08:07:26 +00:00
}
}
protected function checkOiDeleted () {
if ( $this -> db -> fieldInfo ( 'oldimage' , 'oi_deleted' ) -> type () !== 'smallint' ) {
2011-02-04 20:05:05 +00:00
$this -> output ( " Changing 'oldimage.oi_deleted' to type 'smallint' \n " );
2010-08-22 08:07:26 +00:00
$this -> db -> query ( " ALTER TABLE oldimage ALTER oi_deleted DROP DEFAULT " );
$this -> db -> query ( " ALTER TABLE oldimage ALTER oi_deleted TYPE SMALLINT USING (oi_deleted::smallint) " );
$this -> db -> query ( " ALTER TABLE oldimage ALTER oi_deleted SET DEFAULT 0 " );
} else {
2012-03-14 00:36:11 +00:00
$this -> output ( " ...column 'oldimage.oi_deleted' is already of type 'smallint' \n " );
2010-08-22 08:07:26 +00:00
}
}
protected function checkOiNameConstraint () {
if ( $this -> db -> hasConstraint ( " oldimage_oi_name_fkey_cascaded " ) ) {
2012-03-14 00:36:11 +00:00
$this -> output ( " ...table 'oldimage' has correct cascading delete/update foreign key to image \n " );
2010-08-22 08:07:26 +00:00
} else {
if ( $this -> db -> hasConstraint ( " oldimage_oi_name_fkey " ) ) {
$this -> db -> query ( " ALTER TABLE oldimage DROP CONSTRAINT oldimage_oi_name_fkey " );
}
if ( $this -> db -> hasConstraint ( " oldimage_oi_name_fkey_cascade " ) ) {
$this -> db -> query ( " ALTER TABLE oldimage DROP CONSTRAINT oldimage_oi_name_fkey_cascade " );
}
2011-02-04 20:05:05 +00:00
$this -> output ( " Making foreign key on table 'oldimage' (to image) a cascade delete/update \n " );
2010-08-22 08:07:26 +00:00
$this -> db -> query ( " ALTER TABLE oldimage ADD CONSTRAINT oldimage_oi_name_fkey_cascaded " .
" FOREIGN KEY (oi_name) REFERENCES image(img_name) ON DELETE CASCADE ON UPDATE CASCADE " );
}
}
protected function checkPageDeletedTrigger () {
if ( ! $this -> db -> triggerExists ( 'page' , 'page_deleted' ) ) {
2012-07-08 08:00:36 +00:00
$this -> applyPatch ( 'patch-page_deleted.sql' , false , " Adding function and trigger 'page_deleted' to table 'page' " );
2010-08-22 08:07:26 +00:00
} else {
2012-03-14 00:36:11 +00:00
$this -> output ( " ...table 'page' has 'page_deleted' trigger \n " );
2010-08-22 08:07:26 +00:00
}
}
2012-07-05 15:08:10 +00:00
protected function dropIndex ( $table , $index , $patch = '' , $fullpath = false ) {
2012-03-22 02:42:44 +00:00
if ( $this -> db -> indexExists ( $table , $index ) ) {
$this -> output ( " Dropping obsolete index ' $index ' \n " );
$this -> db -> query ( " DROP INDEX \" " . $index . " \" " );
2010-08-22 08:07:26 +00:00
}
}
2012-03-22 02:42:44 +00:00
protected function checkIndex ( $index , $should_be , $good_def ) {
$pu = $this -> db -> indexAttributes ( $index );
if ( ! empty ( $pu ) && $pu != $should_be ) {
$this -> output ( " Dropping obsolete version of index ' $index ' \n " );
$this -> db -> query ( " DROP INDEX \" " . $index . " \" " );
$pu = array ();
2010-08-22 08:07:26 +00:00
} else {
2012-03-22 02:42:44 +00:00
$this -> output ( " ...no need to drop index ' $index ' \n " );
2010-08-22 08:07:26 +00:00
}
2012-03-22 02:42:44 +00:00
if ( empty ( $pu ) ) {
$this -> output ( " Creating index ' $index ' \n " );
$this -> db -> query ( $good_def );
2010-08-22 08:07:26 +00:00
} else {
2012-03-22 02:42:44 +00:00
$this -> output ( " ...index ' $index ' exists \n " );
2010-08-22 08:07:26 +00:00
}
}
protected function checkRevUserFkey () {
if ( $this -> fkeyDeltype ( 'revision_rev_user_fkey' ) == 'r' ) {
2012-03-14 00:36:11 +00:00
$this -> output ( " ...constraint 'revision_rev_user_fkey' is ON DELETE RESTRICT \n " );
2010-08-22 08:07:26 +00:00
} else {
2012-07-08 08:00:36 +00:00
$this -> applyPatch ( 'patch-revision_rev_user_fkey.sql' , false , " Changing constraint 'revision_rev_user_fkey' to ON DELETE RESTRICT " );
2010-08-22 08:07:26 +00:00
}
}
protected function checkIwlPrefix () {
if ( $this -> db -> indexExists ( 'iwlinks' , 'iwl_prefix' ) ) {
2012-07-08 08:00:36 +00:00
$this -> applyPatch ( 'patch-rename-iwl_prefix.sql' , false , " Replacing index 'iwl_prefix' with 'iwl_prefix_from_title' " );
2010-08-22 08:07:26 +00:00
}
}
2012-03-22 02:42:44 +00:00
protected function addInterwikiType () {
2012-07-08 08:00:36 +00:00
$this -> applyPatch ( 'patch-add_interwiki.sql' , false , " Refreshing add_interwiki() " );
2012-03-22 02:42:44 +00:00
}
2010-08-22 08:07:26 +00:00
protected function tsearchFixes () {
# Tweak the page_title tsearch2 trigger to filter out slashes
# This is create or replace, so harmless to call if not needed
2012-07-08 08:00:36 +00:00
$this -> applyPatch ( 'patch-ts2pagetitle.sql' , false , " Refreshing ts2_page_title() " );
2010-08-22 08:07:26 +00:00
2010-12-14 12:47:37 +00:00
# If the server is 8.3 or higher, rewrite the tsearch2 triggers
# in case they have the old 'default' versions
2010-08-22 08:07:26 +00:00
# Gather version numbers in case we need them
if ( $this -> db -> getServerVersion () >= 8.3 ) {
2012-07-08 08:00:36 +00:00
$this -> applyPatch ( 'patch-tsearch2funcs.sql' , false , " Rewriting tsearch2 triggers " );
2010-08-22 08:07:26 +00:00
}
2010-08-15 18:55:08 +00:00
}
}