* (bug 2223) Add unique index on user_name field to prevent duplicate accounts
authorBrion Vibber <brion@users.mediawiki.org>
Sun, 5 Jun 2005 11:19:52 +0000 (11:19 +0000)
committerBrion Vibber <brion@users.mediawiki.org>
Sun, 5 Jun 2005 11:19:52 +0000 (11:19 +0000)
RELEASE-NOTES
maintenance/archives/patch-user_nameindex.sql [new file with mode: 0644]
maintenance/tables.sql
maintenance/updaters.inc
maintenance/userDupes.inc
maintenance/userDupes.php

index d1fc875..a0a230f 100644 (file)
@@ -266,6 +266,7 @@ Various bugfixes, small features, and a few experimental things:
 
 * (bug 2319) Fix parse hook tag matching
 * (bug 2329) Fix title formatting in several special pages
+* (bug 2223) Add unique index on user_name field to prevent duplicate accounts
 
 
 === Caveats ===
diff --git a/maintenance/archives/patch-user_nameindex.sql b/maintenance/archives/patch-user_nameindex.sql
new file mode 100644 (file)
index 0000000..9bf0aab
--- /dev/null
@@ -0,0 +1,13 @@
+--
+-- Change the index on user_name to a unique index to prevent
+-- duplicate registrations from creeping in.
+--
+-- Run maintenance/userDupes.php or through the updater first
+-- to clean up any prior duplicate accounts.
+--
+-- Added 2005-06-05
+--
+
+     ALTER TABLE /*$wgDBprefix*/user
+      DROP INDEX user_name,
+ADD UNIQUE INDEX user_name(user_name);
index 2bf8de4..37db68b 100644 (file)
@@ -104,7 +104,7 @@ CREATE TABLE /*$wgDBprefix*/user (
   user_email_token_expires CHAR(14) BINARY,
 
   PRIMARY KEY user_id (user_id),
-  INDEX user_name (user_name(10)),
+  UNIQUE INDEX user_name (user_name),
   INDEX (user_email_token)
 
 ) TYPE=InnoDB;
index e2255c7..735a724 100644 (file)
@@ -8,6 +8,7 @@
 
 require_once 'convertLinks.inc';
 require_once 'InitialiseMessages.inc';
+require_once 'userDupes.inc';
 
 $wgRenamedTables = array(
 #           from             to                  patch file
@@ -556,6 +557,21 @@ function do_old_links_update() {
        }
 }
 
+function do_user_unique_update() {
+       global $wgDatabase;
+       $duper = new UserDupes( $wgDatabase );
+       if( $duper->hasUniqueIndex() ) {
+               echo "Already have unique user_name index.\n";
+       } else {
+               if( !$duper->clearDupes() ) {
+                       echo "WARNING: This next step will probably fail due to unfixed duplicates...\n";
+               }
+               echo "Adding unique index on user_name... ";
+               dbsource( 'maintenance/archives/patch-user_nameindex.sql', $wgDatabase );
+               echo "ok\n";
+       }
+}
+
 function do_all_updates() {
        global $wgNewTables, $wgNewFields, $wgRenamedTables;
        
@@ -598,6 +614,8 @@ function do_all_updates() {
        
        do_drop_img_type(); flush();
        
+       do_user_unique_update(); flush();
+       
        initialiseMessages(); flush();
 }
 
index 0e315aa..e0b2498 100644 (file)
@@ -25,6 +25,30 @@ class UserDupes {
        var $unresolvable;
        var $trimmed;
        
+       function UserDupes( &$database ) {
+               $this->db =& $database;
+       }
+       
+       /**
+        * Check if this database's user table has already had a unique
+        * user_name index applied.
+        * @return bool
+        */
+       function hasUniqueIndex() {
+               $fname = 'UserDupes::hasUniqueIndex';
+               #if( $wgDatabase->indexExists( 'image', 'PRIMARY' ) ) {
+               $info = $this->db->indexInfo( 'user', 'user_name', $fname );
+               if( !$info ) {
+                       echo "WARNING: doesn't seem to have user_name index at all!\n";
+                       return false;
+               }
+               
+               # Confusingly, 'Non_unique' is 0 for *unique* indexes,
+               # and 1 for *non-unique* indexes. Pass the crack, MySQL,
+               # it's obviously some good stuff!
+               return ( $info->Non_unique == 0 );
+       }
+       
        /**
         * Checks the database for duplicate user account records
         * and remove them in preparation for application of a unique
@@ -56,7 +80,11 @@ class UserDupes {
        function checkDupes( $doDelete=false ) {
                global $wgDBname;
                
-               $this->db =& wfGetDB( DB_MASTER );
+               if( $this->hasUniqueIndex() ) {
+                       echo "$wgDBname already has a unique index on its user table.\n";
+                       return true;
+               }
+               
                $this->lock();
                
                echo "Checking for duplicate accounts...\n";
index 45041a5..8dca2b5 100644 (file)
@@ -26,7 +26,8 @@ require_once( 'maintenance/userDupes.inc' );
 $wgTitle = Title::newFromText( 'Dupe user entry cleanup script' );
 
 $fix = isset( $options['fix'] );
-$duper = new UserDupes();
+$dbw =& wfGetDB( DB_MASTER );
+$duper = new UserDupes( $dbw );
 $retval = $duper->checkDupes( $fix );
 
 if( $retval ) {