From: Greg Sabino Mullane Date: Sun, 23 Sep 2007 22:23:01 +0000 (+0000) Subject: Make CONCAT calls database portable, change IF() to standard CASE-WHEN calls. X-Git-Tag: 1.31.0-rc.0~51321 X-Git-Url: http://git.cyclocoop.org/%22%20.%20generer_url_ecrire%28%22suivi_revisions%22%29%20.%20%22?a=commitdiff_plain;h=0ab8c7e910452795b8519056a359ce6286771d5a;p=lhc%2Fweb%2Fwiklou.git Make CONCAT calls database portable, change IF() to standard CASE-WHEN calls. Postgres: replace CHAR(64) with TEXT for fa_storage_key of filearchive Postgres: Add hasConstraint to allow replacing of oldimage fk constraint Postgres: make oldimage cascade delete on image deletion --- diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 9ac68ab9e1..4445e08aab 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -63,6 +63,8 @@ it from source control: http://www.mediawiki.org/wiki/Download_from_SVN when boolean settings are disabled with 'Off' via php_admin_value/php_value * (bug 11292) Fixed unserialize errors with Postgres by creating special Blob object. * (bug 11363) Make all metadata fields bytea when using Postgres. +* (bug 11331) Add buildConcat() and use CASE not IF for DB compatibility. Make oldimage + cascade delete via image table for Postgres, change fa_storage_key TEXT. === API changes in 1.12 === diff --git a/includes/Database.php b/includes/Database.php index fcf2b908d2..0c92d6795f 100644 --- a/includes/Database.php +++ b/includes/Database.php @@ -2302,6 +2302,13 @@ class Database { return $this->tableName( $matches[1] ); } + /* + * Build a concatenation list to feed into a SQL query + */ + function buildConcat( $stringList ) { + return 'CONCAT(' . implode( ',', $stringList ) . ')'; + } + } /** diff --git a/includes/DatabasePostgres.php b/includes/DatabasePostgres.php index 26e860142d..3bc36f3431 100644 --- a/includes/DatabasePostgres.php +++ b/includes/DatabasePostgres.php @@ -112,6 +112,11 @@ class DatabasePostgres extends Database { return true; } + function hasConstraint( $name ) { + $SQL = "SELECT 1 FROM pg_catalog.pg_constraint WHERE conname = '" . pg_escape_string( $name ) . "'"; + return $this->numRows($res = $this->doQuery($SQL)); + } + static function newFromParams( $server, $user, $password, $dbName, $failFunction = false, $flags = 0) { return new DatabasePostgres( $server, $user, $password, $dbName, $failFunction, $flags ); @@ -1235,6 +1240,10 @@ END; return false; } + function buildConcat( $stringList ) { + return implode( ' || ', $stringList ); + } + } // end DatabasePostgres class diff --git a/includes/filerepo/LocalFile.php b/includes/filerepo/LocalFile.php index 1e5fc44952..392bfa0c62 100644 --- a/includes/filerepo/LocalFile.php +++ b/includes/filerepo/LocalFile.php @@ -1188,12 +1188,12 @@ class LocalFileDeleteBatch { list( $oldRels, $deleteCurrent ) = $this->getOldRels(); if ( $deleteCurrent ) { + $concat = $dbw->buildConcat( array( "img_sha1", $encExt ) ); $where = array( 'img_name' => $this->file->getName() ); $dbw->insertSelect( 'filearchive', 'image', array( 'fa_storage_group' => $encGroup, - 'fa_storage_key' => "IF(img_sha1='', '', CONCAT(img_sha1,$encExt))", - + 'fa_storage_key' => "CASE WHEN img_sha1='' THEN '' ELSE $concat END", 'fa_deleted_user' => $encUserId, 'fa_deleted_timestamp' => $encTimestamp, 'fa_deleted_reason' => $encReason, @@ -1217,15 +1217,14 @@ class LocalFileDeleteBatch { } if ( count( $oldRels ) ) { + $concat = $dbw->buildConcat( array( "oi_sha1", $encExt ) ); $where = array( 'oi_name' => $this->file->getName(), 'oi_archive_name IN (' . $dbw->makeList( array_keys( $oldRels ) ) . ')' ); - $dbw->insertSelect( 'filearchive', 'oldimage', array( 'fa_storage_group' => $encGroup, - 'fa_storage_key' => "IF(oi_sha1='', '', CONCAT(oi_sha1,$encExt))", - + 'fa_storage_key' => "CASE WHEN oi_sha1='' THEN '' ELSE $concat END", 'fa_deleted_user' => $encUserId, 'fa_deleted_timestamp' => $encTimestamp, 'fa_deleted_reason' => $encReason, diff --git a/maintenance/postgres/tables.sql b/maintenance/postgres/tables.sql index 3ef6d14750..fa55d85517 100644 --- a/maintenance/postgres/tables.sql +++ b/maintenance/postgres/tables.sql @@ -259,7 +259,7 @@ CREATE INDEX img_timestamp_idx ON image (img_timestamp); CREATE INDEX img_sha1 ON image (img_sha1); CREATE TABLE oldimage ( - oi_name TEXT NOT NULL REFERENCES image(img_name), + oi_name TEXT NOT NULL, oi_archive_name TEXT NOT NULL, oi_size INTEGER NOT NULL, oi_width INTEGER NOT NULL, @@ -276,6 +276,7 @@ CREATE TABLE oldimage ( oi_deleted CHAR NOT NULL DEFAULT '0', oi_sha1 TEXT NOT NULL DEFAULT '' ); +ALTER TABLE oldimage ADD CONSTRAINT oldimage_oi_name_fkey_cascade FOREIGN KEY (oi_name) REFERENCES image(img_name) ON DELETE CASCADE; CREATE INDEX oi_name_timestamp ON oldimage (oi_name,oi_timestamp); CREATE INDEX oi_name_archive_name ON oldimage (oi_name,oi_archive_name); CREATE INDEX oi_sha1 ON oldimage (oi_sha1); @@ -286,7 +287,7 @@ CREATE TABLE filearchive ( fa_name TEXT NOT NULL, fa_archive_name TEXT, fa_storage_group VARCHAR(16), - fa_storage_key CHAR(64), + fa_storage_key TEXT, fa_deleted_user INTEGER NULL REFERENCES mwuser(user_id) ON DELETE SET NULL, fa_deleted_timestamp TIMESTAMPTZ NOT NULL, fa_deleted_reason TEXT, diff --git a/maintenance/updaters.inc b/maintenance/updaters.inc index eee546d8c3..f72e21120d 100644 --- a/maintenance/updaters.inc +++ b/maintenance/updaters.inc @@ -1352,6 +1352,7 @@ function do_postgres_updates() { # table, column, desired type, USING clause if needed $typechanges = array( array("filearchive", "fa_metadata", "bytea", "decode(fa_metadata,'escape')"), + array("filearchive", "fa_storage_key", "text", ""), array("image", "img_metadata", "bytea", "decode(img_metadata,'escape')"), array("image", "img_size", "int4", ""), array("image", "img_width", "int4", ""), @@ -1459,6 +1460,13 @@ function do_postgres_updates() { dbsource(archive($nr[2])); } + if ($wgDatabase->hasConstraint("oldimage_oi_name_fkey")) { + echo "... change oldimage to CASCADE DELETE on image deletion\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"); + } + if (!$wgDatabase->triggerExists("page", "page_deleted")) { echo "... create page_deleted trigger\n"; dbsource(archive('patch-page_deleted.sql'));