Merge "mediawiki.api.test: Refactor to embrace async"
[lhc/web/wiklou.git] / includes / installer / MssqlUpdater.php
1 <?php
2 /**
3 * Microsoft SQL Server-specific installer.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * http://www.gnu.org/copyleft/gpl.html
19 *
20 * @file
21 * @ingroup Deployment
22 */
23
24 /**
25 * Class for setting up the MediaWiki database using Microsoft SQL Server.
26 *
27 * @ingroup Deployment
28 * @since 1.23
29 */
30
31 class MssqlUpdater extends DatabaseUpdater {
32
33 /**
34 * @var DatabaseMssql
35 */
36 protected $db;
37
38 protected function getCoreUpdateList() {
39 return [
40 // 1.23
41 [ 'addField', 'mwuser', 'user_password_expires', 'patch-user_password_expires.sql' ],
42
43 // 1.24
44 [ 'addField', 'page', 'page_lang', 'patch-page-page_lang.sql' ],
45
46 // 1.25
47 [ 'dropTable', 'hitcounter' ],
48 [ 'dropField', 'site_stats', 'ss_total_views', 'patch-drop-ss_total_views.sql' ],
49 [ 'dropField', 'page', 'page_counter', 'patch-drop-page_counter.sql' ],
50 // Constraint updates
51 [ 'updateConstraints', 'category_types', 'categorylinks', 'cl_type' ],
52 [ 'updateConstraints', 'major_mime', 'filearchive', 'fa_major_mime' ],
53 [ 'updateConstraints', 'media_type', 'filearchive', 'fa_media_type' ],
54 [ 'updateConstraints', 'major_mime', 'oldimage', 'oi_major_mime' ],
55 [ 'updateConstraints', 'media_type', 'oldimage', 'oi_media_type' ],
56 [ 'updateConstraints', 'major_mime', 'image', 'img_major_mime' ],
57 [ 'updateConstraints', 'media_type', 'image', 'img_media_type' ],
58 [ 'updateConstraints', 'media_type', 'uploadstash', 'us_media_type' ],
59 // END: Constraint updates
60
61 [ 'modifyField', 'image', 'img_major_mime',
62 'patch-img_major_mime-chemical.sql' ],
63 [ 'modifyField', 'oldimage', 'oi_major_mime',
64 'patch-oi_major_mime-chemical.sql' ],
65 [ 'modifyField', 'filearchive', 'fa_major_mime',
66 'patch-fa_major_mime-chemical.sql' ],
67
68 // 1.27
69 [ 'dropTable', 'msg_resource_links' ],
70 [ 'dropTable', 'msg_resource' ],
71 [ 'addField', 'watchlist', 'wl_id', 'patch-watchlist-wl_id.sql' ],
72 ];
73 }
74
75 /**
76 * Drops unnamed and creates named constraints following the pattern
77 * <column>_ckc
78 *
79 * @param string $constraintType
80 * @param string $table Name of the table to which the field belongs
81 * @param string $field Name of the field to modify
82 * @return bool False if patch is skipped.
83 */
84 protected function updateConstraints( $constraintType, $table, $field ) {
85 global $wgDBname, $wgDBmwschema;
86
87 if ( !$this->doTable( $table ) ) {
88 return true;
89 }
90
91 $this->output( "...updating constraints on [$table].[$field] ..." );
92 $updateKey = "$field-$constraintType-ck";
93 if ( !$this->db->tableExists( $table, __METHOD__ ) ) {
94 $this->output( "...$table table does not exist, skipping modify field patch.\n" );
95 return true;
96 } elseif ( !$this->db->fieldExists( $table, $field, __METHOD__ ) ) {
97 $this->output( "...$field field does not exist in $table table, " .
98 "skipping modify field patch.\n" );
99 return true;
100 } elseif ( $this->updateRowExists( $updateKey ) ) {
101 $this->output( "...$field in table $table already patched.\n" );
102 return true;
103 }
104
105 # After all checks passed, start the update
106 $this->insertUpdateRow( $updateKey );
107 $path = 'named_constraints.sql';
108 $constraintMap = [
109 'category_types' =>
110 "($field in('page', 'subcat', 'file'))",
111 'major_mime' =>
112 "($field in('unknown', 'application', 'audio', 'image', 'text', 'video'," .
113 " 'message', 'model', 'multipart'))",
114 'media_type' =>
115 "($field in('UNKNOWN', 'BITMAP', 'DRAWING', 'AUDIO', 'VIDEO', 'MULTIMEDIA'," .
116 "'OFFICE', 'TEXT', 'EXECUTABLE', 'ARCHIVE'))"
117 ];
118 $constraint = $constraintMap[$constraintType];
119
120 # and hack-in those variables that should be replaced
121 # in our template file right now
122 $this->db->setSchemaVars( [
123 'tableName' => $table,
124 'fieldName' => $field,
125 'checkConstraint' => $constraint,
126 'wgDBname' => $wgDBname,
127 'wgDBmwschema' => $wgDBmwschema,
128 ] );
129
130 # Full path from file name
131 $path = $this->db->patchPath( $path );
132
133 # No need for a cursor allowing result-iteration; just apply a patch
134 # store old value for re-setting later
135 $wasScrollable = $this->db->scrollableCursor( false );
136
137 # Apply patch
138 $this->db->sourceFile( $path );
139
140 # Reset DB instance to have original state
141 $this->db->setSchemaVars( false );
142 $this->db->scrollableCursor( $wasScrollable );
143
144 $this->output( "done.\n" );
145
146 return true;
147 }
148 }