Make CONCAT calls database portable, change IF() to standard CASE-WHEN calls.
authorGreg Sabino Mullane <greg@users.mediawiki.org>
Sun, 23 Sep 2007 22:23:01 +0000 (22:23 +0000)
committerGreg Sabino Mullane <greg@users.mediawiki.org>
Sun, 23 Sep 2007 22:23:01 +0000 (22:23 +0000)
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

RELEASE-NOTES
includes/Database.php
includes/DatabasePostgres.php
includes/filerepo/LocalFile.php
maintenance/postgres/tables.sql
maintenance/updaters.inc

index 9ac68ab..4445e08 100644 (file)
@@ -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 ===
 
index fcf2b90..0c92d67 100644 (file)
@@ -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 ) . ')';
+       }
+
 }
 
 /**
index 26e8601..3bc36f3 100644 (file)
@@ -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
 
 
index 1e5fc44..392bfa0 100644 (file)
@@ -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,
index 3ef6d14..fa55d85 100644 (file)
@@ -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,
index eee546d..f72e211 100644 (file)
@@ -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'));