From: River Tarnell Date: Thu, 8 Mar 2007 02:39:03 +0000 (+0000) Subject: * (bug 9222) PostgreSQL updater should not be version-specific X-Git-Tag: 1.31.0-rc.0~53864 X-Git-Url: http://git.cyclocoop.org/fichier?a=commitdiff_plain;h=bbfad4fc598c2b46cb97566012d8534b4af05697;p=lhc%2Fweb%2Fwiklou.git * (bug 9222) PostgreSQL updater should not be version-specific --- diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 4cb6351228..9a254c27f9 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -252,6 +252,7 @@ lighter making things easier to read. * (bug 9009) Add username entry field to Special:Contributions * (bug 9097) column "pr_pagetype" does not exist * (bug 9217) Balance wfProfile calls in Skin::outputPage +* (bug 9222) PostgreSQL updater should not be version-specific == Languages updated == diff --git a/maintenance/postgres/archives/patch-archive2.sql b/maintenance/postgres/archives/patch-archive2.sql new file mode 100644 index 0000000000..fa900cbfd2 --- /dev/null +++ b/maintenance/postgres/archives/patch-archive2.sql @@ -0,0 +1,15 @@ +ALTER TABLE archive RENAME to archive2; +CREATE VIEW archive AS +SELECT + ar_namespace, ar_title, ar_text, ar_comment, ar_user, ar_user_text, + ar_minor_edit, ar_flags, ar_rev_id, ar_text_id, + TO_CHAR(ar_timestamp, 'YYYYMMDDHH24MISS') AS ar_timestamp +FROM archive2; + +CREATE RULE archive_insert AS ON INSERT TO archive +DO INSTEAD INSERT INTO archive2 VALUES ( + NEW.ar_namespace, NEW.ar_title, NEW.ar_text, NEW.ar_comment, NEW.ar_user, NEW.ar_user_text, + TO_DATE(NEW.ar_timestamp, 'YYYYMMDDHH24MISS'), + NEW.ar_minor_edit, NEW.ar_flags, NEW.ar_rev_id, NEW.ar_text_id +); + diff --git a/maintenance/postgres/archives/patch-archive_delete.sql b/maintenance/postgres/archives/patch-archive_delete.sql new file mode 100644 index 0000000000..4a864c3b81 --- /dev/null +++ b/maintenance/postgres/archives/patch-archive_delete.sql @@ -0,0 +1,5 @@ +CREATE RULE archive_delete AS ON DELETE TO archive +DO INSTEAD DELETE FROM archive2 WHERE + archive2.ar_title = OLD.ar_title AND + archive2.ar_namespace = OLD.ar_namespace AND + archive2.ar_rev_id = OLD.ar_rev_id; diff --git a/maintenance/postgres/archives/patch-mediawiki_version.sql b/maintenance/postgres/archives/patch-mediawiki_version.sql new file mode 100644 index 0000000000..811b38a129 --- /dev/null +++ b/maintenance/postgres/archives/patch-mediawiki_version.sql @@ -0,0 +1,18 @@ +CREATE TABLE mediawiki_version ( + type TEXT NOT NULL, + mw_version TEXT NOT NULL, + notes TEXT NULL, + + pg_version TEXT NULL, + pg_dbname TEXT NULL, + pg_user TEXT NULL, + pg_port TEXT NULL, + mw_schema TEXT NULL, + ts2_schema TEXT NULL, + ctype TEXT NULL, + + sql_version TEXT NULL, + sql_date TEXT NULL, + cdate TIMESTAMPTZ NOT NULL DEFAULT now() +); + diff --git a/maintenance/postgres/archives/patch-mwuser.sql b/maintenance/postgres/archives/patch-mwuser.sql new file mode 100644 index 0000000000..3984703ac0 --- /dev/null +++ b/maintenance/postgres/archives/patch-mwuser.sql @@ -0,0 +1 @@ +ALTER TABLE "user" RENAME TO mwuser; diff --git a/maintenance/postgres/archives/patch-page_deleted.sql b/maintenance/postgres/archives/patch-page_deleted.sql new file mode 100644 index 0000000000..5b0782cbee --- /dev/null +++ b/maintenance/postgres/archives/patch-page_deleted.sql @@ -0,0 +1,11 @@ +CREATE FUNCTION page_deleted() RETURNS TRIGGER LANGUAGE plpgsql AS +$mw$ +BEGIN +DELETE FROM recentchanges WHERE rc_namespace = OLD.page_namespace AND rc_title = OLD.page_title; +RETURN NULL; +END; +$mw$; + +CREATE TRIGGER page_deleted AFTER DELETE ON page + FOR EACH ROW EXECUTE PROCEDURE page_deleted(); + diff --git a/maintenance/postgres/archives/patch-page_restrictions.sql b/maintenance/postgres/archives/patch-page_restrictions.sql new file mode 100644 index 0000000000..1faa14a92e --- /dev/null +++ b/maintenance/postgres/archives/patch-page_restrictions.sql @@ -0,0 +1,10 @@ +CREATE TABLE page_restrictions ( + pr_page INTEGER NULL REFERENCES page (page_id) ON DELETE CASCADE, + pr_type TEXT NOT NULL, + pr_level TEXT NOT NULL, + pr_cascade SMALLINT NOT NULL, + pr_user INTEGER NULL, + pr_expiry TIMESTAMPTZ NULL +); +ALTER TABLE page_restrictions ADD CONSTRAINT page_restrictions_pk PRIMARY KEY (pr_page,pr_type); + diff --git a/maintenance/postgres/archives/patch-pagecontent.sql b/maintenance/postgres/archives/patch-pagecontent.sql new file mode 100644 index 0000000000..c3651f92c6 --- /dev/null +++ b/maintenance/postgres/archives/patch-pagecontent.sql @@ -0,0 +1 @@ +ALTER TABLE "text" RENAME TO pagecontent; diff --git a/maintenance/postgres/archives/patch-profiling.sql b/maintenance/postgres/archives/patch-profiling.sql new file mode 100644 index 0000000000..1c4dce4e28 --- /dev/null +++ b/maintenance/postgres/archives/patch-profiling.sql @@ -0,0 +1,7 @@ +CREATE TABLE profiling ( + pf_count INTEGER NOT NULL DEFAULT 0, + pf_time NUMERIC(18,10) NOT NULL DEFAULT 0, + pf_name TEXT NOT NULL, + pf_server TEXT NULL +); +CREATE UNIQUE INDEX pf_name_server ON profiling (pf_name, pf_server); diff --git a/maintenance/postgres/archives/patch-querycachetwo.sql b/maintenance/postgres/archives/patch-querycachetwo.sql new file mode 100644 index 0000000000..cb70cd89f1 --- /dev/null +++ b/maintenance/postgres/archives/patch-querycachetwo.sql @@ -0,0 +1,12 @@ +CREATE TABLE querycachetwo ( + qcc_type TEXT NOT NULL, + qcc_value SMALLINT NOT NULL DEFAULT 0, + qcc_namespace INTEGER NOT NULL DEFAULT 0, + qcc_title TEXT NOT NULL DEFAULT '', + qcc_namespacetwo INTEGER NOT NULL DEFAULT 0, + qcc_titletwo TEXT NOT NULL DEFAULT '' +); +CREATE INDEX querycachetwo_type_value ON querycachetwo (qcc_type, qcc_value); +CREATE INDEX querycachetwo_title ON querycachetwo (qcc_type,qcc_namespace,qcc_title); +CREATE INDEX querycachetwo_titletwo ON querycachetwo (qcc_type,qcc_namespacetwo,qcc_titletwo); + diff --git a/maintenance/postgres/archives/patch-redirect.sql b/maintenance/postgres/archives/patch-redirect.sql new file mode 100644 index 0000000000..d2922d3b11 --- /dev/null +++ b/maintenance/postgres/archives/patch-redirect.sql @@ -0,0 +1,7 @@ +CREATE TABLE redirect ( + rd_from INTEGER NOT NULL REFERENCES page(page_id) ON DELETE CASCADE, + rd_namespace SMALLINT NOT NULL, + rd_title TEXT NOT NULL +); +CREATE INDEX redirect_ns_title ON redirect (rd_namespace,rd_title,rd_from); + diff --git a/maintenance/postgres/archives/patch-rev_text_id_idx.sql b/maintenance/postgres/archives/patch-rev_text_id_idx.sql new file mode 100644 index 0000000000..036c0be3a1 --- /dev/null +++ b/maintenance/postgres/archives/patch-rev_text_id_idx.sql @@ -0,0 +1 @@ +CREATE INDEX rev_text_id_idx ON revision (rev_text_id); diff --git a/maintenance/updaters.inc b/maintenance/updaters.inc index 590c4f1a0a..321acfab13 100644 --- a/maintenance/updaters.inc +++ b/maintenance/updaters.inc @@ -939,7 +939,8 @@ function do_all_updates( $shared = false, $purge = true ) { function archive($name) { global $wgDBtype, $IP; switch ($wgDBtype) { - // @fixme: add mysql5 and postgres items or....? + case "postgres": + return "$IP/maintenance/postgres/archives/$name"; default: return "$IP/maintenance/archives/$name"; } @@ -1018,6 +1019,113 @@ function do_restrictions_update() { } +function +pg_column_has_type($table, $column, $wanttype) +{ +global $wgDatabase, $wgDBname, $wgDBmwschema; + + $q = <<query(sprintf($q, + $wgDatabase->addQuotes($wgDBmwschema), + $wgDatabase->addQuotes($table), + $wgDatabase->addQuotes($column))); + $row = $wgDatabase->fetchRow($res); + $istype = false; + if ($row) + $istype = $row[0] === $wanttype; + $wgDatabase->freeResult($res); + return $istype; +} + +function +pg_column_exists($table, $column) +{ +global $wgDatabase, $wgDBname, $wgDBmwschema; + + $q = <<query(sprintf($q, + $wgDatabase->addQuotes($wgDBmwschema), + $wgDatabase->addQuotes($table), + $wgDatabase->addQuotes($column))); + $row = $wgDatabase->fetchRow($res); + $exists = !!$row; + $wgDatabase->freeResult($res); + return $exists; +} + +function +pg_table_exists($table) +{ +global $wgDatabase, $wgDBname, $wgDBmwschema; + + $q = <<query(sprintf($q, + $wgDatabase->addQuotes($wgDBmwschema), + $wgDatabase->addQuotes($table))); + $row = $wgDatabase->fetchRow($res); + $exists = !!$row; + $wgDatabase->freeResult($res); + return $exists; +} + +function +pg_trigger_exists($table, $trigger) +{ +global $wgDatabase, $wgDBname, $wgDBmwschema; + + $q = <<query(sprintf($q, + $wgDatabase->addQuotes($wgDBmwschema), + $wgDatabase->addQuotes($table), + $wgDatabase->addQuotes($trigger))); + $row = $wgDatabase->fetchRow($res); + $exists = !!$row; + $wgDatabase->freeResult($res); + return $exists; +} + + +function +pg_index_exists($table, $index) +{ +global $wgDatabase, $wgDBmwschema; + $exists = $wgDatabase->selectField("pg_indexes", "indexname", + array( "indexname" => $index, + "tablename" => $table, + "schemaname" => $wgDBmwschema)); + return $exists === $index; +} + +function +pg_rule_exists($table, $rule) +{ +global $wgDatabase, $wgDBmwschema; + $exists = $wgDatabase->selectField("pg_rules", "rulename", + array( "rulename" => $rule, + "tablename" => $table, + "schemaname" => $wgDBmwschema)); + return $exists === $rule; +} + function do_postgres_updates() { global $wgDatabase, $wgVersion, $wgDBmwschema; @@ -1050,87 +1158,114 @@ function do_postgres_updates() { $upgrade = ''; - ## 1.8 Updater - if ($version < 1008) { - $upgrade .= <<query("ALTER TABLE $nc[0] ADD $nc[1] $nc[2]"); + } -CREATE RULE archive_insert AS ON INSERT TO archive -DO INSTEAD INSERT INTO archive2 VALUES ( - NEW.ar_namespace, NEW.ar_title, NEW.ar_text, NEW.ar_comment, NEW.ar_user, NEW.ar_user_text, - TO_DATE(NEW.ar_timestamp, 'YYYYMMDDHH24MISS'), - NEW.ar_minor_edit, NEW.ar_flags, NEW.ar_rev_id, NEW.ar_text_id -); + foreach ($typechanges as $tc) { + if (!pg_column_exists($tc[0], $tc[1])) { + echo "... error: expected column $tc[0].$tc[1] to exist\n"; + exit(1); + } -CREATE FUNCTION page_deleted() RETURNS TRIGGER LANGUAGE plpgsql AS -\$mw\$ -BEGIN -DELETE FROM recentchanges WHERE rc_namespace = OLD.page_namespace AND rc_title = OLD.page_title; -RETURN NULL; -END; -\$mw\$; + if (pg_column_has_type($tc[0], $tc[1], $tc[2])) + echo "... $tc[0].$tc[1] is already $tc[2]\n"; + else { + echo "... change $tc[0].$tc[1] to $tc[2]\n"; + $wgDatabase->query("ALTER TABLE $tc[0] ALTER $tc[1] TYPE $tc[2];\nCOMMIT;\n"); + } + } + + if (!pg_column_has_type("user_newtalk", "user_ip", "text")) { + echo "... convert user_newtalk.user_ip to text\n"; + $wgDatabase->query("ALTER TABLE user_newtalk ALTER user_ip TYPE TEXT USING host(user_ip)"); + } -CREATE TRIGGER page_deleted AFTER DELETE ON page - FOR EACH ROW EXECUTE PROCEDURE page_deleted(); + foreach ($newindexes as $ni) { + if (pg_index_exists($ni[0], $ni[1])) { + echo "... index $ni[1] on $ni[0] already exists\n"; + continue; + } + dbsource(archive($ni[2])); + } + + foreach ($newrules as $nr) { + if (pg_rule_exists($nr[0], $nr[1])) { + echo "... rule $nr[1] on $nr[0] already exists\n"; + continue; + } + dbsource(archive($nr[2])); + } + + if (!pg_trigger_exists("page", "page_deleted")) { + echo "... create page_deleted trigger\n"; + dbsource(archive('patch-page_deleted.sql')); + } + + ## 1.8 Updater + if ($version < 1008) { + $upgrade .= <<