diff options
Diffstat (limited to 'maintenance/updaters.inc')
-rw-r--r-- | maintenance/updaters.inc | 466 |
1 files changed, 270 insertions, 196 deletions
diff --git a/maintenance/updaters.inc b/maintenance/updaters.inc index 3c972044..9d7e32cb 100644 --- a/maintenance/updaters.inc +++ b/maintenance/updaters.inc @@ -16,74 +16,120 @@ require_once 'deleteDefaultMessages.php'; # Extension updates require_once( "$IP/includes/Hooks.php" ); -$wgRenamedTables = array( -# from to patch file -# array( 'group', 'groups', 'patch-rename-group.sql' ), -); - -$wgNewTables = array( -# table patch file (in maintenance/archives) - array( 'hitcounter', 'patch-hitcounter.sql' ), - array( 'querycache', 'patch-querycache.sql' ), - array( 'objectcache', 'patch-objectcache.sql' ), - array( 'categorylinks', 'patch-categorylinks.sql' ), - array( 'logging', 'patch-logging.sql' ), - array( 'user_newtalk', 'patch-usernewtalk2.sql' ), - array( 'transcache', 'patch-transcache.sql' ), - array( 'trackbacks', 'patch-trackbacks.sql' ), - array( 'externallinks', 'patch-externallinks.sql' ), - array( 'job', 'patch-job.sql' ), - array( 'langlinks', 'patch-langlinks.sql' ), - array( 'querycache_info', 'patch-querycacheinfo.sql' ), - array( 'filearchive', 'patch-filearchive.sql' ), - array( 'querycachetwo', 'patch-querycachetwo.sql' ), - array( 'redirect', 'patch-redirect.sql' ), +/** + * List of update functions to call on a MySQL-based MediaWiki installation, + * in sequence. First item is function name, rest are parameters to pass. + */ +$wgMysqlUpdates = array( + // 1.2 + // update_passwords obsolete + array( 'add_field', 'ipblocks', 'ipb_id', 'patch-ipblocks.sql' ), + array( 'add_field', 'ipblocks', 'ipb_expiry', 'patch-ipb_expiry.sql' ), + array( 'do_interwiki_update' ), + array( 'do_index_update' ), + // do_linkscc_update obsolete + array( 'add_table', 'hitcounter', 'patch-hitcounter.sql' ), + array( 'add_field', 'recentchanges', 'rc_type', 'patch-rc_type.sql' ), + + // 1.3 + array( 'add_field', 'user', 'user_real_name', 'patch-user-realname.sql' ), + array( 'add_table', 'querycache', 'patch-querycache.sql' ), + array( 'add_table', 'objectcache', 'patch-objectcache.sql' ), + array( 'add_table', 'categorylinks', 'patch-categorylinks.sql' ), + // do_linkscc_1_3_update obsolete + array( 'do_old_links_update' ), + array( 'add_field', 'recentchanges', 'rc_ip', 'patch-rc_ip.sql' ), + + // 1.4 + array( 'do_image_name_unique_update' ), + array( 'add_field', 'recentchanges', 'rc_id', 'patch-rc_id.sql' ), + array( 'add_field', 'recentchanges', 'rc_patrolled', 'patch-rc-patrol.sql' ), + array( 'add_table', 'logging', 'patch-logging.sql' ), + // do_user_rights_update obsolete + array( 'add_field', 'user', 'user_token', 'patch-user_token.sql' ), + // old, old_articleid, patch-remove-old-title-namespace.sql obsolete + // user_groups, patch-userlevels.sql obsolete + // do_group_update() obsolete + array( 'do_watchlist_update' ), + array( 'do_user_update' ), + // do_copy_newtalk_to_watchlist obsolete + + // 1.5 + array( 'do_schema_restructuring' ), + array( 'add_field', 'logging', 'log_params', 'patch-log_params.sql' ), + array( 'do_logging_encoding' ), + array( 'add_field', 'archive', 'ar_rev_id', 'patch-archive-rev_id.sql' ), + array( 'add_field', 'page', 'page_len', 'patch-page_len.sql' ), + array( 'do_inverse_timestamp' ), + array( 'do_text_id' ), + array( 'add_field', 'revision', 'rev_deleted', 'patch-rev_deleted.sql' ), + array( 'add_field', 'image', 'img_width', 'patch-img_width.sql' ), + array( 'add_field', 'image', 'img_metadata', 'patch-img_metadata.sql' ), + array( 'add_field', 'user', 'user_email_token', 'patch-user_email_token.sql' ), + array( 'add_field', 'archive', 'ar_text_id', 'patch-archive-text_id.sql' ), + array( 'do_namespace_size' ), + array( 'add_field', 'image', 'img_media_type', 'patch-img_media_type.sql' ), + array( 'do_pagelinks_update' ), + array( 'do_drop_img_type' ), + array( 'do_user_unique_update' ), + array( 'do_user_groups_update' ), + array( 'add_field', 'site_stats', 'ss_total_pages', 'patch-ss_total_articles.sql' ), + array( 'add_table', 'user_newtalk', 'patch-usernewtalk2.sql' ), + array( 'add_table', 'transcache', 'patch-transcache.sql' ), + array( 'add_field', 'interwiki', 'iw_trans', 'patch-interwiki-trans.sql' ), + array( 'add_table', 'trackbacks', 'patch-trackbacks.sql' ), + + // 1.6 + array( 'do_watchlist_null' ), + // do_image_index_update obsolete + array( 'do_logging_timestamp_index' ), + array( 'add_field', 'ipblocks', 'ipb_range_start', 'patch-ipb_range_start.sql' ), + array( 'do_page_random_update' ), + array( 'add_field', 'user', 'user_registration','patch-user_registration.sql' ), + array( 'do_templatelinks_update' ), + array( 'add_table', 'externallinks', 'patch-externallinks.sql' ), + array( 'add_table', 'job', 'patch-job.sql' ), + array( 'add_field', 'site_stats', 'ss_images', 'patch-ss_images.sql' ), + array( 'add_table', 'langlinks', 'patch-langlinks.sql' ), + array( 'add_table', 'querycache_info', 'patch-querycacheinfo.sql' ), + array( 'add_table', 'filearchive', 'patch-filearchive.sql' ), + array( 'add_field', 'ipblocks', 'ipb_anon_only', 'patch-ipb_anon_only.sql' ), + array( 'do_rc_indices_update' ), + + // 1.9 + array( 'add_field', 'user', 'user_newpass_time', 'patch-user_newpass_time.sql' ), + array( 'add_table', 'redirect', 'patch-redirect.sql' ), + array( 'add_table', 'querycachetwo', 'patch-querycachetwo.sql' ), + array( 'add_field', 'ipblocks', 'ipb_enable_autoblock', 'patch-ipb_optional_autoblock.sql' ), + array( 'do_backlinking_indices_update' ), + array( 'add_field', 'recentchanges', 'rc_old_len', 'patch-rc_len.sql' ), + array( 'add_field', 'user', 'user_editcount', 'patch-user_editcount.sql' ), + + // 1.10 + array( 'do_restrictions_update' ), + array( 'add_field', 'logging', 'log_id', 'patch-log_id.sql' ), + array( 'add_field', 'revision', 'rev_parent_id', 'patch-rev_parent_id.sql' ), + array( 'add_field', 'page_restrictions', 'pr_id', 'patch-page_restrictions_sortkey.sql' ), + array( 'add_field', 'revision', 'rev_len', 'patch-rev_len.sql' ), + array( 'add_field', 'recentchanges', 'rc_deleted', 'patch-rc_deleted.sql' ), + array( 'add_field', 'logging', 'log_deleted', 'patch-log_deleted.sql' ), + array( 'add_field', 'archive', 'ar_deleted', 'patch-ar_deleted.sql' ), + array( 'add_field', 'ipblocks', 'ipb_deleted', 'patch-ipb_deleted.sql' ), + array( 'add_field', 'filearchive', 'fa_deleted', 'patch-fa_deleted.sql' ), + array( 'add_field', 'archive', 'ar_len', 'patch-ar_len.sql' ), + + // 1.11 + array( 'add_field', 'ipblocks', 'ipb_block_email', 'patch-ipb_emailban.sql' ), + array( 'do_categorylinks_indices_update' ), + array( 'add_field', 'oldimage', 'oi_metadata', 'patch-oi_metadata.sql'), + array( 'do_archive_user_index' ), + array( 'do_image_user_index' ), + array( 'do_oldimage_user_index' ), + array( 'add_field', 'archive', 'ar_page_id', 'patch-archive-page_id.sql'), + array( 'add_field', 'image', 'img_sha1', 'patch-img_sha1.sql' ), + array( 'add_table', 'protected_titles', 'patch-protected_titles.sql' ), ); -$wgNewFields = array( -# table field patch file (in maintenance/archives) - array( 'ipblocks', 'ipb_id', 'patch-ipblocks.sql' ), - array( 'ipblocks', 'ipb_expiry', 'patch-ipb_expiry.sql' ), - array( 'recentchanges', 'rc_type', 'patch-rc_type.sql' ), - array( 'recentchanges', 'rc_ip', 'patch-rc_ip.sql' ), - array( 'recentchanges', 'rc_id', 'patch-rc_id.sql' ), - array( 'recentchanges', 'rc_patrolled', 'patch-rc-patrol.sql' ), - array( 'recentchanges', 'rc_old_len', 'patch-rc_len.sql' ), - array( 'user', 'user_real_name', 'patch-user-realname.sql' ), - array( 'user', 'user_token', 'patch-user_token.sql' ), - array( 'user', 'user_email_token', 'patch-user_email_token.sql' ), - array( 'user', 'user_registration','patch-user_registration.sql' ), - array( 'logging', 'log_params', 'patch-log_params.sql' ), - array( 'archive', 'ar_rev_id', 'patch-archive-rev_id.sql' ), - array( 'archive', 'ar_text_id', 'patch-archive-text_id.sql' ), - array( 'page', 'page_len', 'patch-page_len.sql' ), - array( 'revision', 'rev_deleted', 'patch-rev_deleted.sql' ), - array( 'image', 'img_width', 'patch-img_width.sql' ), - array( 'image', 'img_metadata', 'patch-img_metadata.sql' ), - array( 'image', 'img_media_type', 'patch-img_media_type.sql' ), - array( 'site_stats', 'ss_total_pages', 'patch-ss_total_articles.sql' ), - array( 'interwiki', 'iw_trans', 'patch-interwiki-trans.sql' ), - array( 'ipblocks', 'ipb_range_start', 'patch-ipb_range_start.sql' ), - array( 'site_stats', 'ss_images', 'patch-ss_images.sql' ), - array( 'ipblocks', 'ipb_anon_only', 'patch-ipb_anon_only.sql' ), - array( 'ipblocks', 'ipb_enable_autoblock', 'patch-ipb_optional_autoblock.sql' ), - array( 'user', 'user_newpass_time','patch-user_newpass_time.sql' ), - array( 'user', 'user_editcount', 'patch-user_editcount.sql' ), - array( 'recentchanges', 'rc_deleted', 'patch-rc_deleted.sql' ), - array( 'logging', 'log_id', 'patch-log_id.sql' ), - array( 'logging', 'log_deleted', 'patch-log_deleted.sql' ), - array( 'archive', 'ar_deleted', 'patch-ar_deleted.sql' ), - array( 'ipblocks', 'ipb_deleted', 'patch-ipb_deleted.sql' ), - array( 'filearchive', 'fa_deleted', 'patch-fa_deleted.sql' ), - array( 'revision', 'rev_len', 'patch-rev_len.sql' ), - array( 'archive', 'ar_len', 'patch-ar_len.sql' ), - array( 'revision', 'rev_parent_id', 'patch-rev_parent_id.sql' ), - array( 'page_restrictions', 'pr_id', 'patch-page_restrictions_sortkey.sql' ), - array( 'ipblocks', 'ipb_block_email', 'patch-ipb_emailban.sql' ), - array( 'oldimage', 'oi_metadata', 'patch-oi_metadata.sql'), - array( 'archive', 'ar_page_id', 'patch-archive-page_id.sql'), - array( 'image', 'img_sha1', 'patch-img_sha1.sql' ), -); # For extensions only, should be populated via hooks # $wgDBtype should be checked to specifiy the proper file @@ -943,26 +989,16 @@ function do_all_updates( $shared = false, $purge = true ) { do_postgres_updates(); return; } - - # Rename tables - foreach ( $wgRenamedTables as $tableRecord ) { - rename_table( $tableRecord[0], $tableRecord[1], $tableRecord[2] ); - } - - # Add missing tables - foreach ( $wgNewTables as $tableRecord ) { - add_table( $tableRecord[0], $tableRecord[1] ); - flush(); - } - - # Add missing fields - foreach ( $wgNewFields as $fieldRecord ) { - if ( $fieldRecord[0] != 'user' || $doUser ) { - add_field( $fieldRecord[0], $fieldRecord[1], $fieldRecord[2] ); - } + + # Run core updates in sequence... + global $wgMysqlUpdates; + foreach( $wgMysqlUpdates as $params ) { + $func = array_shift( $params ); + call_user_func_array( $func, $params ); flush(); } + /// @fixme clean up this mess too! global $wgExtNewTables, $wgExtNewFields, $wgExtNewIndexes; # Add missing extension tables foreach ( $wgExtNewTables as $tableRecord ) { @@ -982,54 +1018,6 @@ function do_all_updates( $shared = false, $purge = true ) { flush(); } - # Do schema updates which require special handling - do_interwiki_update(); flush(); - do_index_update(); flush(); - do_old_links_update(); flush(); - do_image_name_unique_update(); flush(); - do_watchlist_update(); flush(); - if ( $doUser ) { - do_user_update(); flush(); - } -###### do_copy_newtalk_to_watchlist(); flush(); - do_logging_encoding(); flush(); - - do_schema_restructuring(); flush(); - do_inverse_timestamp(); flush(); - do_text_id(); flush(); - do_namespace_size(); flush(); - - do_pagelinks_update(); flush(); - do_templatelinks_update(); flush(); // after pagelinks - - do_drop_img_type(); flush(); - - if ( $doUser ) { - do_user_unique_update(); flush(); - } - do_user_groups_update(); flush(); - - do_watchlist_null(); flush(); - - //do_image_index_update(); flush(); - - do_logging_timestamp_index(); flush(); - - do_page_random_update(); flush(); - - do_rc_indices_update(); flush(); - - do_backlinking_indices_update(); flush(); - - do_categorylinks_indices_update(); flush(); - - do_restrictions_update(); flush (); - - do_archive_user_index(); flush (); - - do_image_user_index(); flush (); - - do_oldimage_user_index(); flush (); echo "Deleting old default messages (this may take a long time!)..."; flush(); deleteDefaultMessages(); @@ -1260,6 +1248,10 @@ END; function do_postgres_updates() { global $wgDatabase, $wgVersion, $wgDBmwschema, $wgDBts2schema, $wgShowExceptionDetails, $wgDBuser; + ## Gather version numbers in case we need them + $version = $wgDatabase->getServerVersion(); ## long string + $numver = $wgDatabase->numeric_version; ## X.Y e.g. 8.3 + $wgShowExceptionDetails = 1; # Just in case their LocalSettings.php does not have this: @@ -1268,7 +1260,7 @@ function do_postgres_updates() { # Verify that this user is configured correctly $safeuser = $wgDatabase->addQuotes($wgDBuser); - $SQL = "SELECT array_to_string(useconfig,'*') FROM pg_user WHERE usename = $safeuser"; + $SQL = "SELECT array_to_string(useconfig,'*') FROM pg_catalog.pg_user WHERE usename = $safeuser"; $config = pg_fetch_result( $wgDatabase->doQuery( $SQL ), 0, 0 ); $conf = array(); foreach( explode( '*', $config ) as $c ) { @@ -1276,17 +1268,24 @@ function do_postgres_updates() { $conf[$x] = $y; } $newpath = array(); - if( !array_key_exists( 'search_path', $conf ) or strpos( $conf['search_path'],$wgDBmwschema ) === false ) { - print "Adding in schema \"$wgDBmwschema\" to search_path for user \"$wgDBuser\"\n"; - $newpath[$wgDBmwschema] = 1; + if( $wgDBmwschema === 'mediawiki' ) { + if (!array_key_exists( 'search_path', $conf ) or strpos( $conf['search_path'],$wgDBmwschema ) === false ) { + echo "Adding in schema \"$wgDBmwschema\" to search_path for user \"$wgDBuser\"\n"; + $newpath[$wgDBmwschema] = 1; + } } if( !array_key_exists( 'search_path', $conf ) or strpos( $conf['search_path'],$wgDBts2schema ) === false ) { - print "Adding in schema \"$wgDBts2schema\" to search_path for user \"$wgDBuser\"\n"; + echo "Adding in schema \"$wgDBts2schema\" to search_path for user \"$wgDBuser\"\n"; $newpath[$wgDBts2schema] = 1; } $searchpath = implode( ',', array_keys( $newpath ) ); if( strlen( $searchpath ) ) { $wgDatabase->doQuery( "ALTER USER $wgDBuser SET search_path = $searchpath" ); + $wgDatabase->doQuery( "SET search_path = $searchpath" ); + } + else { + $path = $conf['search_path']; + echo "... search_path for user \"$wgDBuser\" looks correct ($path)\n"; } $goodconf = array( 'client_min_messages' => 'error', @@ -1296,8 +1295,12 @@ function do_postgres_updates() { foreach( array_keys( $goodconf ) AS $key ) { $value = $goodconf[$key]; if( !array_key_exists( $key, $conf ) or $conf[$key] !== $value ) { - print "Setting $key to '$value' for user \"$wgDBuser\"\n"; + echo "Setting $key to '$value' for user \"$wgDBuser\"\n"; $wgDatabase->doQuery( "ALTER USER $wgDBuser SET $key = '$value'" ); + $wgDatabase->doQuery( "SET $key = '$value'" ); + } + else { + echo "... default value of \"$key\" is correctly set to \"$value\" for user \"$wgDBuser\"\n"; } } @@ -1313,32 +1316,34 @@ function do_postgres_updates() { array("querycachetwo", "patch-querycachetwo.sql"), array("page_restrictions", "patch-page_restrictions.sql"), array("profiling", "patch-profiling.sql"), + array("protected_titles", "patch-protected_titles.sql"), array("redirect", "patch-redirect.sql"), ); $newcols = array( + array("archive", "ar_deleted", "SMALLINT NOT NULL DEFAULT 0"), array("archive", "ar_len", "INTEGER"), array("archive", "ar_page_id", "INTEGER"), array("image", "img_sha1", "TEXT NOT NULL DEFAULT ''"), array("ipblocks", "ipb_anon_only", "CHAR NOT NULL DEFAULT '0'"), array("ipblocks", "ipb_block_email", "CHAR NOT NULL DEFAULT '0'"), array("ipblocks", "ipb_create_account", "CHAR NOT NULL DEFAULT '1'"), - array("ipblocks", "ipb_deleted", "INTEGER NOT NULL DEFAULT 0"), + array("ipblocks", "ipb_deleted", "SMALLINT NOT NULL DEFAULT 0"), array("ipblocks", "ipb_enable_autoblock", "CHAR NOT NULL DEFAULT '1'"), - array("filearchive", "fa_deleted", "INTEGER NOT NULL DEFAULT 0"), - array("logging", "log_deleted", "INTEGER NOT NULL DEFAULT 0"), + array("filearchive", "fa_deleted", "SMALLINT NOT NULL DEFAULT 0"), + array("logging", "log_deleted", "SMALLINT NOT NULL DEFAULT 0"), array("logging", "log_id", "INTEGER NOT NULL PRIMARY KEY DEFAULT nextval('log_log_id_seq')"), array("logging", "log_params", "TEXT"), array("mwuser", "user_editcount", "INTEGER"), array("mwuser", "user_newpass_time", "TIMESTAMPTZ"), - array("oldimage", "oi_deleted", "CHAR NOT NULL DEFAULT '0'"), + array("oldimage", "oi_deleted", "SMALLINT NOT NULL DEFAULT 0"), array("oldimage", "oi_metadata", "BYTEA NOT NULL DEFAULT ''"), array("oldimage", "oi_media_type", "TEXT"), array("oldimage", "oi_major_mime", "TEXT NOT NULL DEFAULT 'unknown'"), array("oldimage", "oi_minor_mime", "TEXT NOT NULL DEFAULT 'unknown'"), array("oldimage", "oi_sha1", "TEXT NOT NULL DEFAULT ''"), array("page_restrictions", "pr_id", "INTEGER NOT NULL UNIQUE DEFAULT nextval('pr_id_val')"), - array("recentchanges", "rc_deleted", "INTEGER NOT NULL DEFAULT 0"), + array("recentchanges", "rc_deleted", "SMALLINT NOT NULL DEFAULT 0"), array("recentchanges", "rc_log_action", "TEXT"), array("recentchanges", "rc_log_type", "TEXT"), array("recentchanges", "rc_logid", "INTEGER NOT NULL DEFAULT 0"), @@ -1346,21 +1351,55 @@ function do_postgres_updates() { array("recentchanges", "rc_old_len", "INTEGER"), array("recentchanges", "rc_params", "TEXT"), array("revision", "rev_len", "INTEGER"), + array("revision", "rev_deleted", "SMALLINT NOT NULL DEFAULT 0"), ); - # table, column, desired type, USING clause if needed + # table, column, desired type, USING clause if needed (with new default if needed) $typechanges = array( - array("image", "img_size", "int4", ""), - array("image", "img_width", "int4", ""), - array("image", "img_height", "int4", ""), - array("ipblocks", "ipb_address", "text", "ipb_address::text"), - array("math", "math_inputhash", "bytea", "decode(math_inputhash,'escape')"), - array("math", "math_outputhash", "bytea", "decode(math_outputhash,'escape')"), - array("oldimage", "oi_size", "int4", ""), - array("oldimage", "oi_width", "int4", ""), - array("oldimage", "oi_height", "int4", ""), - array("user_newtalk", "user_ip", "text", "host(user_ip)"), + array("archive", "ar_deleted", "smallint", ""), + array("archive", "ar_minor_edit", "smallint", "ar_minor_edit::smallint DEFAULT 0"), + array("filearchive", "fa_deleted", "smallint", ""), + array("filearchive", "fa_height", "integer", ""), + array("filearchive", "fa_metadata", "bytea", "decode(fa_metadata,'escape')"), + array("filearchive", "fa_size", "integer", ""), + array("filearchive", "fa_width", "integer", ""), + array("filearchive", "fa_storage_group","text", ""), + array("filearchive", "fa_storage_key", "text", ""), + array("image", "img_metadata", "bytea", "decode(img_metadata,'escape')"), + array("image", "img_size", "integer", ""), + array("image", "img_width", "integer", ""), + array("image", "img_height", "integer", ""), + array("interwiki", "iw_local", "smallint", "iw_local::smallint DEFAULT 0"), + array("interwiki", "iw_trans", "smallint", "iw_trans::smallint DEFAULT 0"), + array("ipblocks", "ipb_auto", "smallint", "ipb_auto::smallint DEFAULT 0"), + array("ipblocks", "ipb_anon_only", "smallint", "ipb_anon_only::smallint DEFAULT 0"), + array("ipblocks", "ipb_create_account", "smallint", "ipb_create_account::smallint DEFAULT 1"), + array("ipblocks", "ipb_enable_autoblock", "smallint", "ipb_enable_autoblock::smallint DEFAULT 1"), + array("ipblocks", "ipb_block_email", "smallint", "ipb_block_email::smallint DEFAULT 0"), + array("ipblocks", "ipb_address", "text", "ipb_address::text"), + array("ipblocks", "ipb_deleted", "smallint", ""), + array("math", "math_inputhash", "bytea", "decode(math_inputhash,'escape')"), + array("math", "math_outputhash", "bytea", "decode(math_outputhash,'escape')"), + array("mwuser", "user_token", "text", ""), + array("mwuser", "user_email_token","text", ""), + array("objectcache", "keyname", "text", ""), + array("oldimage", "oi_height", "integer", ""), + array("oldimage", "oi_size", "integer", ""), + array("oldimage", "oi_width", "integer", ""), + array("page", "page_is_redirect","smallint", "page_is_redirect::smallint DEFAULT 0"), + array("page", "page_is_new", "smallint", "page_is_new::smallint DEFAULT 0"), + array("querycache", "qc_value", "integer", ""), + array("querycachetwo","qcc_value", "integer", ""), + array("recentchanges","rc_bot", "smallint", "rc_bot::smallint DEFAULT 0"), + array("recentchanges","rc_deleted", "smallint", ""), + array("recentchanges","rc_minor", "smallint", "rc_minor::smallint DEFAULT 0"), + array("recentchanges","rc_new", "smallint", "rc_new::smallint DEFAULT 0"), + array("recentchanges","rc_type", "smallint", "rc_type::smallint DEFAULT 0"), + array("recentchanges","rc_patrolled", "smallint", "rc_patrolled::smallint DEFAULT 0"), + array("revision", "rev_minor_edit", "smallint", "rev_minor_edit::smallint DEFAULT 0"), + array("templatelinks","tl_namespace", "smallint", "tl_namespace::smallint"), + array("user_newtalk", "user_ip", "text", "host(user_ip)"), ); $newindexes = array( @@ -1375,48 +1414,48 @@ function do_postgres_updates() { foreach ($newsequences as $ns) { if ($wgDatabase->sequenceExists($ns)) { - echo "... sequence $ns already exists\n"; + echo "... sequence \"$ns\" already exists\n"; continue; } - echo "... create sequence $ns\n"; + echo "Creating sequence \"$ns\"\n"; $wgDatabase->query("CREATE SEQUENCE $ns"); } foreach ($newtables as $nt) { if ($wgDatabase->tableExists($nt[0])) { - echo "... table $nt[0] already exists\n"; + echo "... table \"$nt[0]\" already exists\n"; continue; } - echo "... create table $nt[0]\n"; + echo "Creating table \"$nt[0]\"\n"; dbsource(archive($nt[1])); } ## Needed before newcols if ($wgDatabase->tableExists("archive2")) { - echo "... convert archive2 back to normal archive table\n"; + echo "Converting \"archive2\" back to normal archive table\n"; if ($wgDatabase->ruleExists("archive", "archive_insert")) { - echo "... drop rule archive_insert\n"; + echo "Dropping rule \"archive_insert\"\n"; $wgDatabase->query("DROP RULE archive_insert ON archive"); } if ($wgDatabase->ruleExists("archive", "archive_delete")) { - echo "... drop rule archive_delete\n"; + echo "Dropping rule \"archive_delete\"\n"; $wgDatabase->query("DROP RULE archive_delete ON archive"); } - dbsource(archive("patch-remove-archive2.sql")); - } else - echo "... obsolete archive2 not present\n"; + } + else + echo "... obsolete table \"archive2\" does not exist\n"; foreach ($newcols as $nc) { $fi = $wgDatabase->fieldInfo($nc[0], $nc[1]); if (!is_null($fi)) { - echo "... column $nc[0].$nc[1] already exists\n"; + echo "... column \"$nc[0].$nc[1]\" already exists\n"; continue; } - echo "... add column $nc[0].$nc[1]\n"; + echo "Adding column \"$nc[0].$nc[1]\"\n"; $wgDatabase->query("ALTER TABLE $nc[0] ADD $nc[1] $nc[2]"); } @@ -1428,11 +1467,17 @@ function do_postgres_updates() { } if ($fi->type() === $tc[2]) - echo "... $tc[0].$tc[1] is already $tc[2]\n"; + echo "... column \"$tc[0].$tc[1]\" is already of type \"$tc[2]\"\n"; else { - echo "... change $tc[0].$tc[1] from {$fi->type()} to $tc[2]\n"; + echo "Changing column type of \"$tc[0].$tc[1]\" from \"{$fi->type()}\" to \"$tc[2]\"\n"; $sql = "ALTER TABLE $tc[0] ALTER $tc[1] TYPE $tc[2]"; if (strlen($tc[3])) { + $default = array(); + if (preg_match( '/DEFAULT (.+)/', $tc[3], $default)) { + $sqldef = "ALTER TABLE $tc[0] ALTER $tc[1] SET DEFAULT $default[1]"; + $wgDatabase->query($sqldef); + $tc[3] = preg_replace( '/\s*DEFAULT .+/', '', $tc[3]); + } $sql .= " USING $tc[3]"; } $sql .= ";\nCOMMIT;\n"; @@ -1440,91 +1485,120 @@ function do_postgres_updates() { } } + if ($wgDatabase->fieldInfo('oldimage','oi_deleted')->type() !== 'smallint') { + echo "Changing \"oldimage.oi_deleted\" to type \"smallint\"\n"; + $wgDatabase->query( "ALTER TABLE oldimage ALTER oi_deleted DROP DEFAULT" ); + $wgDatabase->query( "ALTER TABLE oldimage ALTER oi_deleted TYPE SMALLINT USING (oi_deleted::smallint)" ); + $wgDatabase->query( "ALTER TABLE oldimage ALTER oi_deleted SET DEFAULT 0" ); + } + else + echo "... column \"oldimage.oi_deleted\" is already of type \"smallint\"\n"; + + foreach ($newindexes as $ni) { if (pg_index_exists($ni[0], $ni[1])) { - echo "... index $ni[1] on $ni[0] already exists\n"; + echo "... index \"$ni[1]\" on table \"$ni[0]\" already exists\n"; continue; } - $wgDatabase->query("CREATE INDEX $ni[1] ON $ni[0] $ni[2]"); - echo "create index $ni[1]\n"; + echo "Creating index \"$ni[1]\" on table \"$ni[0]\" $ni[2]\n"; + $wgDatabase->query( "CREATE INDEX $ni[1] ON $ni[0] $ni[2]" ); } foreach ($newrules as $nr) { if ($wgDatabase->ruleExists($nr[0], $nr[1])) { - echo "... rule $nr[1] on $nr[0] already exists\n"; + echo "... rule \"$nr[1]\" on table \"$nr[0]\" already exists\n"; continue; } + echo "Adding rule \"$nr[1]\" to table \"$nr[0]\"\n"; dbsource(archive($nr[2])); } + if ($wgDatabase->hasConstraint("oldimage_oi_name_fkey")) { + echo "Making foriegn key on table \"oldimage\" (to image) a cascade delete\n"; + $wgDatabase->query( "ALTER TABLE oldimage DROP CONSTRAINT oldimage_oi_name_fkey" ); + $wgDatabase->query( "ALTER TABLE oldimage ADD CONSTRAINT oldimage_oi_name_fkey_cascade ". + "FOREIGN KEY (oi_name) REFERENCES image(img_name) ON DELETE CASCADE" ); + } + else + echo "... table \"oldimage\" has correct cascade delete foreign key to image\n"; + if (!$wgDatabase->triggerExists("page", "page_deleted")) { - echo "... create page_deleted trigger\n"; + echo "Adding function and trigger \"page_deleted\" to table \"page\"\n"; dbsource(archive('patch-page_deleted.sql')); } + else + echo "... table \"page\" has \"page_deleted\" trigger\n"; $fi = $wgDatabase->fieldInfo("recentchanges", "rc_cur_id"); if (!$fi->nullable()) { - echo "... remove NOT NULL constraint on recentchanges.rc_cur_id\n"; + echo "Removing NOT NULL constraint from \"recentchanges.rc_cur_id\"\n"; dbsource(archive('patch-rc_cur_id-not-null.sql')); } + else + echo "... column \"recentchanges.rc_cur_id\" has a NOT NULL constraint\n"; $pu = pg_describe_index("pagelink_unique"); if (!is_null($pu) && ($pu[0] != "pl_from" || $pu[1] != "pl_namespace" || $pu[2] != "pl_title")) { - echo "... dropping obsolete pagelink_unique index\n"; + echo "Dropping obsolete version of index \"pagelink_unique index\"\n"; $wgDatabase->query("DROP INDEX pagelink_unique"); $pu = null; - } else - echo "... obsolete pagelink_unique index not present\n"; + } + else + echo "... obsolete version of index \"pagelink_unique index\" does not exist\n"; if (is_null($pu)) { - echo "... adding new pagelink_unique index\n"; + echo "Creating index \"pagelink_unique index\"\n"; $wgDatabase->query("CREATE UNIQUE INDEX pagelink_unique ON pagelinks (pl_from,pl_namespace,pl_title)"); - } else - echo "... already have current pagelink_unique index\n"; + } + else + echo "... index \"pagelink_unique_index\" aready exists\n"; if (pg_fkey_deltype("revision_rev_user_fkey") == 'r') { - echo "... revision_rev_user_fkey is already ON DELETE RESTRICT\n"; - } else { - echo "... change revision_rev_user_fkey to ON DELETE RESTRICT\n"; + echo "... constraint \"revision_rev_user_fkey\" is ON DELETE RESTRICT\n"; + } + else { + echo "Changing constraint \"revision_rev_user_fkey\" to ON DELETE RESTRICT\n"; dbsource(archive('patch-revision_rev_user_fkey.sql')); } - if (is_null($wgDatabase->fieldInfo("archive", "ar_deleted"))) { - echo "... add archive.ar_deleted\n"; - dbsource(archive("patch-archive-ar_deleted.sql")); - } else - echo "... archive.ar_deleted already exists\n"; - global $wgExtNewTables, $wgExtPGNewFields, $wgExtNewIndexes; # Add missing extension tables foreach ( $wgExtNewTables as $nt ) { if ($wgDatabase->tableExists($nt[0])) { - echo "... table $nt[0] already exists\n"; + echo "... table \"$nt[0]\" already exists\n"; continue; } - - echo "... create table $nt[0]\n"; + echo "Creating table \"$nt[0]\"\n"; dbsource($nt[1]); } # Add missing extension fields foreach ( $wgExtPGNewFields as $nc ) { $fi = $wgDatabase->fieldInfo($nc[0], $nc[1]); if (!is_null($fi)) { - echo "... column $nc[0].$nc[1] already exists\n"; + echo "... column \"$nc[0].$nc[1]\" already exists\n"; continue; } - - echo "... add column $nc[0].$nc[1]\n"; - $wgDatabase->query("ALTER TABLE $nc[0] ADD $nc[1] $nc[2]"); + echo "Adding column \"$nc[0].$nc[1]\"\n"; + $wgDatabase->query( "ALTER TABLE $nc[0] ADD $nc[1] $nc[2]" ); } # Add missing extension indexes foreach ( $wgExtNewIndexes as $ni ) { if (pg_index_exists($ni[0], $ni[1])) { - echo "... index $ni[1] on $ni[0] already exists\n"; + echo "... index \"$ni[1]\" on table \"$ni[0]\" already exists\n"; continue; } + echo "Creating index \"$ni[1]\" on table \"$ni[0]\"\n"; dbsource($ni[2]); } + # Tweak the page_title tsearch2 trigger to filter out slashes + # This is create or replace, so harmless to call if not needed + dbsource(archive('patch-ts2pagetitle.sql')); + + ## If the server is 8.3 or higher, rewrite teh tsearch2 triggers + ## in case they have the old 'default' versions + if ( $numver >= 8.3 ) + dbsource(archive('patch-tsearch2funcs.sql')); + return; } |