From eda06e8593c12b4359a46cf3b428c1a1a88e40c4 Mon Sep 17 00:00:00 2001 From: Sam Reed Date: Wed, 28 Sep 2011 18:08:48 +0000 Subject: [PATCH] * (bug 31204) Remove old user.user_options Added run of ConvertUserOptions maintenance script into update.php before dropping the column Removed usages of user_options in code Marked User::decodeOptions() deprecated as of 1.19. Made ConvertUserOptions drop out early if the user_options field doesn't exist Made ConvertUserOptions update user_options to '' after migration of user options to mOptions --- includes/User.php | 13 +++++---- includes/installer/DatabaseUpdater.php | 7 +++++ includes/installer/MysqlUpdater.php | 3 ++ includes/installer/SqliteUpdater.php | 2 ++ .../archives/patch-drop-user_options.sql | 1 + maintenance/convertUserOptions.php | 29 +++++++++++++++---- maintenance/tables.sql | 8 +---- tests/selenium/data/SimpleSeleniumTestDB.sql | 1 - .../data/mediawiki118_fresh_installation.sql | 15 +++++----- 9 files changed, 52 insertions(+), 27 deletions(-) create mode 100644 maintenance/archives/patch-drop-user_options.sql diff --git a/includes/User.php b/includes/User.php index 4cf9482e84..b96128558b 100644 --- a/includes/User.php +++ b/includes/User.php @@ -1089,8 +1089,10 @@ class User { $this->mNewpassword = $row->user_newpassword; $this->mNewpassTime = wfTimestampOrNull( TS_MW, $row->user_newpass_time ); $this->mEmail = $row->user_email; - $this->decodeOptions( $row->user_options ); - $this->mTouched = wfTimestamp(TS_MW,$row->user_touched); + if ( isset( $row->user_options ) ) { + $this->decodeOptions( $row->user_options ); + } + $this->mTouched = wfTimestamp( TS_MW, $row->user_touched ); $this->mToken = $row->user_token; $this->mEmailAuthenticated = wfTimestampOrNull( TS_MW, $row->user_email_authenticated ); $this->mEmailToken = $row->user_email_token; @@ -2693,8 +2695,10 @@ class User { /** * Set this user's options from an encoded string * @param $str String Encoded options to import + * + * @deprecated in 1.19 due to removal of user_options from the user table */ - public function decodeOptions( $str ) { + private function decodeOptions( $str ) { if( !$str ) return; @@ -2822,7 +2826,6 @@ class User { 'user_real_name' => $this->mRealName, 'user_email' => $this->mEmail, 'user_email_authenticated' => $dbw->timestampOrNull( $this->mEmailAuthenticated ), - 'user_options' => '', 'user_touched' => $dbw->timestamp( $this->mTouched ), 'user_token' => $this->mToken, 'user_email_token' => $this->mEmailToken, @@ -2890,7 +2893,6 @@ class User { 'user_email' => $user->mEmail, 'user_email_authenticated' => $dbw->timestampOrNull( $user->mEmailAuthenticated ), 'user_real_name' => $user->mRealName, - 'user_options' => '', 'user_token' => $user->mToken, 'user_registration' => $dbw->timestamp( $user->mRegistration ), 'user_editcount' => 0, @@ -2924,7 +2926,6 @@ class User { 'user_email' => $this->mEmail, 'user_email_authenticated' => $dbw->timestampOrNull( $this->mEmailAuthenticated ), 'user_real_name' => $this->mRealName, - 'user_options' => '', 'user_token' => $this->mToken, 'user_registration' => $dbw->timestamp( $this->mRegistration ), 'user_editcount' => 0, diff --git a/includes/installer/DatabaseUpdater.php b/includes/installer/DatabaseUpdater.php index b20054dbbc..4f427badc3 100644 --- a/includes/installer/DatabaseUpdater.php +++ b/includes/installer/DatabaseUpdater.php @@ -566,4 +566,11 @@ abstract class DatabaseUpdater { $task = $this->maintenance->runChild( 'UpdateCollation' ); $task->execute(); } + + protected function doMigrateUserOptions() { + $cl = $this->maintenance->runChild( 'ConvertUserOptions' ); + $this->output( "Migrating remaining user_options... " ); + $cl->execute(); + $this->output( "done.\n" ); + } } diff --git a/includes/installer/MysqlUpdater.php b/includes/installer/MysqlUpdater.php index 14510e3bf8..80d9a0084b 100644 --- a/includes/installer/MysqlUpdater.php +++ b/includes/installer/MysqlUpdater.php @@ -188,6 +188,9 @@ class MysqlUpdater extends DatabaseUpdater { array( 'addTable', 'globaltemplatelinks', 'patch-globaltemplatelinks.sql' ), array( 'addTable', 'globalnamespaces', 'patch-globalnamespaces.sql' ), array( 'addTable', 'globalinterwiki', 'patch-globalinterwiki.sql' ), + array( 'doMigrateUserOptions' ), + array( 'dropField', 'user', 'user_options', 'patch-drop-user_options.sql' ), + ); } diff --git a/includes/installer/SqliteUpdater.php b/includes/installer/SqliteUpdater.php index 46fada1242..a5fba27437 100644 --- a/includes/installer/SqliteUpdater.php +++ b/includes/installer/SqliteUpdater.php @@ -66,6 +66,8 @@ class SqliteUpdater extends DatabaseUpdater { array( 'addTable', 'globaltemplatelinks', 'patch-globaltemplatelinks.sql' ), array( 'addTable', 'globalnamespaces', 'patch-globalnamespaces.sql' ), array( 'addTable', 'globalinterwiki', 'patch-globalinterwiki.sql' ), + array( 'doMigrateUserOptions' ), + array( 'dropField', 'user', 'user_options', 'patch-drop-user_options.sql' ), ); } diff --git a/maintenance/archives/patch-drop-user_options.sql b/maintenance/archives/patch-drop-user_options.sql new file mode 100644 index 0000000000..15b7d27812 --- /dev/null +++ b/maintenance/archives/patch-drop-user_options.sql @@ -0,0 +1 @@ +ALTER TABLE /*_*/user DROP COLUMN user_options; \ No newline at end of file diff --git a/maintenance/convertUserOptions.php b/maintenance/convertUserOptions.php index f46f710d8c..c99566d5f0 100644 --- a/maintenance/convertUserOptions.php +++ b/maintenance/convertUserOptions.php @@ -37,23 +37,34 @@ class ConvertUserOptions extends Maintenance { $id = 0; $dbw = wfGetDB( DB_MASTER ); + if ( !$dbw->fieldExists( 'user', 'user_options ' ) ) { + $this->output( "No user_options field in the user table. Nothing to migrate" ); + return; + } while ( $id !== null ) { - $idCond = 'user_id>' . $dbw->addQuotes( $id ); - $optCond = "user_options!=" . $dbw->addQuotes( '' ); // For compatibility + $idCond = 'user_id > ' . $dbw->addQuotes( $id ); + $optCond = "user_options != " . $dbw->addQuotes( '' ); // For compatibility $res = $dbw->select( 'user', '*', - array( $optCond, $idCond ), __METHOD__, - array( 'LIMIT' => 50, 'FOR UPDATE' ) ); + array( $optCond, $idCond ), __METHOD__, + array( 'LIMIT' => 50, 'FOR UPDATE' ) + ); $id = $this->convertOptionBatch( $res, $dbw ); $dbw->commit(); wfWaitForSlaves(); - if ( $id ) + if ( $id ) { $this->output( "--Converted to ID $id\n" ); + } } $this->output( "Conversion done. Converted " . $this->mConversionCount . " user records.\n" ); } + /** + * @param $res + * @param $dbw DatabaseBase + * @return null|int + */ function convertOptionBatch( $res, $dbw ) { $id = null; foreach ( $res as $row ) { @@ -62,6 +73,14 @@ class ConvertUserOptions extends Maintenance { $u = User::newFromRow( $row ); $u->saveSettings(); + + // Do this here as saveSettings() doesn't set user_options to '' anymore! + $dbw->update( + 'user', + array( 'user_options' => '' ), + array( 'user_id' => $row->user_id ), + __METHOD__ + ); $id = $row->user_id; } diff --git a/maintenance/tables.sql b/maintenance/tables.sql index 556fd54d8c..bacf6ce8e7 100644 --- a/maintenance/tables.sql +++ b/maintenance/tables.sql @@ -86,12 +86,6 @@ CREATE TABLE /*_*/user ( -- Same with passwords. user_email tinytext NOT NULL, - -- Newline-separated list of name=value defining the user - -- preferences - -- Now obsolete in favour of user_properties table; - -- old values will be migrated from here transparently. - user_options blob NOT NULL, - -- This is a timestamp which is updated when a user -- logs in, logs out, changes preferences, or performs -- some other action requiring HTML cache invalidation @@ -1493,7 +1487,7 @@ CREATE TABLE /*_*/globaltemplatelinks ( -- The namespace of the calling page on the remote wiki -- Needed for display purposes, since the foreign namespace ID doesn't necessarily match a local one - -- The link between the namespace and the namespace name is made by the globalnamespaces table + -- The link between the namespace and the namespace name is made by the globalnamespaces table gtl_from_namespace int NOT NULL, -- The title of the calling page on the remote wiki diff --git a/tests/selenium/data/SimpleSeleniumTestDB.sql b/tests/selenium/data/SimpleSeleniumTestDB.sql index 7944c45f42..1a3196c315 100644 --- a/tests/selenium/data/SimpleSeleniumTestDB.sql +++ b/tests/selenium/data/SimpleSeleniumTestDB.sql @@ -1295,7 +1295,6 @@ CREATE TABLE `mw_user` ( `user_newpassword` tinyblob NOT NULL, `user_newpass_time` binary(14) DEFAULT NULL, `user_email` tinytext NOT NULL, - `user_options` blob NOT NULL, `user_touched` binary(14) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0', `user_token` binary(32) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0', `user_email_authenticated` binary(14) DEFAULT NULL, diff --git a/tests/selenium/data/mediawiki118_fresh_installation.sql b/tests/selenium/data/mediawiki118_fresh_installation.sql index 89bc319159..2724bad5c9 100644 --- a/tests/selenium/data/mediawiki118_fresh_installation.sql +++ b/tests/selenium/data/mediawiki118_fresh_installation.sql @@ -767,13 +767,13 @@ CREATE TABLE `mw_objectcache` ( LOCK TABLES `mw_objectcache` WRITE; /*!40000 ALTER TABLE `mw_objectcache` DISABLE KEYS */; -INSERT INTO `mw_objectcache` VALUES ('test_wiki-mw_:messages:en','K´2´ª.¶2·R\ns\r\nöô÷S²Î´2´®\0','2010-12-31 13:16:31'); -INSERT INTO `mw_objectcache` VALUES ('test_wiki-mw_:pcache:idhash:1-0!*!*!!en!*','¥V[oâFÞg~ÅÄ­´ØBšÁP­¢m)$TK»U…û\0£ŒÇÖÌ8$íï9ƒa\rI«l— X>×ïܹãq—Sa,˜»Ê•• x÷Œ?[~ʃ|.ZÇç$å8YŒ\'IñYÞK¶–-\04³Uš‚µËJ©\'&µuB)È:I¸·’µÊñE¡m¥sk`‰`kËQ°v®äa˜ƒ\rZÌÉt§0«ÞÂ+P%GEÚـ¥JX;\n-sŽP£@ËB©bŒÿÀ8~¶ì²’$¡³eaþυ“…fø­¬Ô+„Ü0[,ÝFèx¬­dÝ\'¶zï0“ÎBJÚÁø¯=ø°Äø¡JÁc§\\—¿:éŒ&BêùT¬à\'‘—CáõFdÿ׆FqÀ¶âÁGd±šÌÙ%8Gè0‡ÆAŒI“ù; Ԙ`Ë7í5ˆLI\r“Ù(¨õç{ýc‹¬¶“„g+©Ô8Qrü¢&›Í¦ãËA)úV’‰Ð•PT”¥\\UƧtn·ÞZ¢e¶SfJZ(VýP¿}øý¾µ0êü—O‹N —=jÏ\\H• íyÔ\\áU[h]T:… À†bd›êu”+Õj%\'í6kÝÂf:E;Ç@YךâÓ4…ØïºÈ€¥ÃqÖ ãÈZÓº65{Ñ Áþ§dwå>·=J)\rÓ6t ·ÅXø̸æM¯É­B»\n÷ŖTÃýŒõb>‘qgÐéï„ 7Ô ›z·n7‘§vwr¸-%uÛ-QiþiX1çöNe±’éA#ÎvÛíÓ§ý3Ìó?','2010-12-31 13:16:31'); -INSERT INTO `mw_objectcache` VALUES ('test_wiki-mw_:pcache:idoptions:1','EÁ‚@ Dÿ¥`¶ \"vÆ£á¢ÞWh°‰,†b¢!ü»»⭙7íL+Ú|}ç³t ´¥I©$è®<¨ôœF\rpSlò4£‰ìïOJN`\r\Z´™Á ‹ Õ®¾ãû)ÃœPYäÆ$¶K¬£— Õ£9ùVjp72ëâE¹©žcÌWpž2šäcVxu7îì ­¦»˜p#£r=.µ…¬[>y)Zpóü','2010-12-31 13:16:31'); -INSERT INTO `mw_objectcache` VALUES ('test_wiki-mw_:resourceloader:filter:minify-css:3832ee25d9c44988461f5f339b9b6a48','+¶26²RrÈMMÉLTHÌÉ©V\0‚Z(¿ (3¯(R«d\r\0','2038-01-19 03:14:07'); -INSERT INTO `mw_objectcache` VALUES ('test_wiki-mw_:resourceloader:filter:minify-css:aa0df16258ad99a1d249e796b5067ed9','+¶2±°RrÈMMÉLTHÌÉ©NÔËK-×Q.,ÍLÎNJ,R\0ó«“ósò‹¬”“\r€ ¶VÉ\Z\0','2038-01-19 03:14:07'); -INSERT INTO `mw_objectcache` VALUES ('test_wiki-mw_:resourceloader:filter:minify-js:22814eeadc9cf0a9ebcd844e14198e66','m”ÉrÛ0 †ïy žÚÇrê&Qޡמ!\n’qQ¹Xq;}÷‚¤$ËÃވ øc!]]].o5SØ\nø)Fq íÑL^íŽý—?Œs…F£!«OÆM\\¼¦•öøéù\0–ÈåN¤ÐɁµà‘լłôŒ€è:£å-…j…ƒF¦Ø{ۅ¾Gç\"ižø‡ \ZÝ6’KÁÇÍÏ!ÊY]=ØF[Ñ~竍ÚØ䶃¯ÚÖî`¬Š9NÐÇ´ª•Ï@¹Káü²|zÔí¶±1«AÆÔ@J#_ԁæ7\'úlË1) JÍµê).’3 zÔfÖT†A´˜²HњÀ[#)ðBzRA©7֌˜ë\"TÔ*~SWÎöå‘/Pà‡ä’B®ÅŽ;\Zç”ayƒ6ø€ëÚè+UŠº?.$º6ÀÇ-uTƒv@h…îsÉ&ª¹ÀÙèNØ¥bòfJ’~ê]6–·p£³/q)…>ŸE…1úÎ͔A\neÍL®g\ZE‡`cW’ÿ™¶Ü`fJ©EÍa‚ˆ>‚šb\n¹Ó‘dÑ.u•doܾ[¹\nt£ b³+õ†l\Z?X* ‘Y•(äօ;ßL¶JqÅ¥ɝõÀòd$Ü\"¤WzGûŽ-@b~+‰#™kǞَÅƂ~ˆ¶âÆøÿP)B ï£ø€ã¬ðqŒÒ–2×åÍríRl묀ô`z º4«ÛúÝXímÀ;¨X݁t;r.ÈsA¾äRïy)ÈkAÞ\nRJTª®JÙU©»*…W«ò¿_ߟžîŸ¼4@óvtžþfúà÷>•«½±x„½ÿ','2038-01-19 03:14:07'); -INSERT INTO `mw_objectcache` VALUES ('test_wiki-mw_:resourceloader:filter:minify-js:dd9440c19c575629ac5ec90e489cf62e','+¶21·RâÜԔÌÄðÌìL½œüĔÔ\"½â’Ä’Tj¥â̒T%+¥¢ÔĔJ¥ZMk.%k\0','2038-01-19 03:14:07'); +INSERT INTO `mw_objectcache` VALUES ('test_wiki-mw_:messages:en','K�2��.�2�R\ns\r\n���S�δ2��\0','2010-12-31 13:16:31'); +INSERT INTO `mw_objectcache` VALUES ('test_wiki-mw_:pcache:idhash:1-0!*!*!!en!*','�V[o�F�g~�����B��P��m)$TK�U��\0�����8$��9�a\rI�l��X>��ܹ�q�Sa,��ʕ� x��?[~ʃ|�.Z��$�8Y�\'�I�Y�K��-\04�U����J�\'&�uB)�:I������E�m�sk`�`k�Q�v��a���\rZ��t�0����+P%GE�ـ�JX;\n-s�P�@�B�b���8~�첒$��ea�υ��f��+���0[,�F�x��d�\'�z�0��BJ���=���J��c�\\��:��&B��T��\'��C��Fdÿ׆Fq����Gd����%8G�0��A�I��; Ԙ`�7�5�LI\r��(���{�c�����g+��8Qr�&�ͦ��A)�V��ЕPT��\\UƧtn��Z�e�SfJZ(V�P�}����0��O�N �=j�\\H� �y�\\�U[h]T:� ��bd��u��+�j%\'�6k��f:E�;�@Yך��4���Ȁ��q� ��Z�º65{� ���dw�>�=J)\r�6t ��X����M���B�\n�ŖT����b>�qg���� 7� �z�n7��vwr�-%u�-Qi�iX1��Ne���A#�v��ӧ�3��?','2010-12-31 13:16:31'); +INSERT INTO `mw_objectcache` VALUES ('test_wiki-mw_:pcache:idoptions:1','E���@ D��`� \"v�ƣ��Wh��,�b�!�⭙7�L+�|}�t ��I�$�<���F\rpSl�4����OJN`\r\Z��� � ծ���)��PY��$�K����գ9�Vjp72��E���c�Wp�2��cVxu7�� ����p#�r=.���[>y)Zp��','2010-12-31 13:16:31'); +INSERT INTO `mw_objectcache` VALUES ('test_wiki-mw_:resourceloader:filter:minify-css:3832ee25d9c44988461f5f339b9b6a48','+�26�Rr�MM�LTH�ɩV\0�Z(��(3�(R�d\r\0','2038-01-19 03:14:07'); +INSERT INTO `mw_objectcache` VALUES ('test_wiki-mw_:resourceloader:filter:minify-css:aa0df16258ad99a1d249e796b5067ed9','+�2��Rr�MM�LTH�ɩN��K-�Q.,�L�NJ,R\0��sò‹¬”�\r���V�\Z\0','2038-01-19 03:14:07'); +INSERT INTO `mw_objectcache` VALUES ('test_wiki-mw_:resourceloader:filter:minify-js:22814eeadc9cf0a9ebcd844e14198e66','m��r�0 ��y ����r�&Qޡמ!\n�qQ�Xq;}���$��ވ� �c!]]].o5S�\n�)Fq ��L^��?�s�F�!�O�M\\�������\0���N��Ɂ���լ����:��-�j��F��{ۅ�G�\"i�� \Z�6�K����!��Y]=�F[�~竍���䶃����`��9N�Ǵ���@�K��|z�?1�A��@J#_ԁ�7\'�l�1) J�͵�).�3 z�f�T�A���Hњ�[#)�BzRA�7֌��\"T�*~SW���/P���B�Ŏ;\Z�ay�6����+U��?.$�6��-uT�v@h��s�&�����NØ¥b�fJ�~�]6��p��/q)�>�E�1��͔A\ne�L�g\ZE�`cW�����`fJ�E�a��>��b\n�ӑd�.u�do��[�\nt��b�+���l\Z?X*��Y�(�օ;�L�JqÅ¥ɝ���d$�\"�WzG�-@b~+�#�kǞَ�Ƃ~������P)B ����q�Җ2���r�Rl����`z �4�����ÝX�m�;�X݁t;r.�sA��R��y)�kA�\nR�JT��J�U��*�W��_ߟ�4@�vt��f���>����x���','2038-01-19 03:14:07'); +INSERT INTO `mw_objectcache` VALUES ('test_wiki-mw_:resourceloader:filter:minify-js:dd9440c19c575629ac5ec90e489cf62e','+�21�R���Ԕ�����L���Ĕ�\"��ĒT�j��̒T%+���ĔJ�ZMk.%k\0','2038-01-19 03:14:07'); /*!40000 ALTER TABLE `mw_objectcache` ENABLE KEYS */; UNLOCK TABLES; @@ -1384,7 +1384,6 @@ CREATE TABLE `mw_user` ( `user_newpassword` tinyblob NOT NULL, `user_newpass_time` binary(14) DEFAULT NULL, `user_email` tinytext NOT NULL, - `user_options` blob NOT NULL, `user_touched` binary(14) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0', `user_token` binary(32) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0', `user_email_authenticated` binary(14) DEFAULT NULL, -- 2.20.1