]> scripts.mit.edu Git - autoinstalls/mediawiki.git/blob - includes/installer/OracleInstaller.php
MediaWiki 1.17.0
[autoinstalls/mediawiki.git] / includes / installer / OracleInstaller.php
1 <?php
2 /**
3  * Oracle-specific installer.
4  *
5  * @file
6  * @ingroup Deployment
7  */
8
9 /**
10  * Class for setting up the MediaWiki database using Oracle.
11  *
12  * @ingroup Deployment
13  * @since 1.17
14  */
15 class OracleInstaller extends DatabaseInstaller {
16
17         protected $globalNames = array(
18                 'wgDBserver',
19                 'wgDBname',
20                 'wgDBuser',
21                 'wgDBpassword',
22                 'wgDBprefix',
23         );
24
25         protected $internalDefaults = array(
26                 '_OracleDefTS' => 'USERS',
27                 '_OracleTempTS' => 'TEMP',
28                 '_InstallUser' => 'SYSDBA',
29         );
30         
31         public $minimumVersion = '9.0.1'; // 9iR1
32
33         protected $connError = null;
34
35         public function getName() {
36                 return 'oracle';
37         }
38
39         public function isCompiled() {
40                 return self::checkExtension( 'oci8' );
41         }
42
43         public function getConnectForm() {
44                 if ( $this->getVar( 'wgDBserver' ) == 'localhost' ) {
45                         $this->parent->setVar( 'wgDBserver', '' );
46                 }
47                 return
48                         $this->getTextBox( 'wgDBserver', 'config-db-host-oracle', array(), $this->parent->getHelpBox( 'config-db-host-oracle-help' ) ) .
49                         Html::openElement( 'fieldset' ) .
50                         Html::element( 'legend', array(), wfMsg( 'config-db-wiki-settings' ) ) .
51                         $this->getTextBox( 'wgDBprefix', 'config-db-prefix' ) .
52                         $this->getTextBox( '_OracleDefTS', 'config-oracle-def-ts' ) .
53                         $this->getTextBox( '_OracleTempTS', 'config-oracle-temp-ts', array(), $this->parent->getHelpBox( 'config-db-oracle-help' ) ) .
54                         Html::closeElement( 'fieldset' ) .
55                         $this->parent->getWarningBox( wfMsg( 'config-db-account-oracle-warn' ) ).
56                         $this->getInstallUserBox().
57                         $this->getWebUserBox();
58         }
59
60         public function submitInstallUserBox() {
61                 parent::submitInstallUserBox();
62                 $this->parent->setVar( '_InstallDBname', $this->getVar( '_InstallUser' ) );
63                 return Status::newGood();
64         }
65
66         public function submitConnectForm() {
67                 // Get variables from the request
68                 $newValues = $this->setVarsFromRequest( array( 'wgDBserver', 'wgDBprefix', 'wgDBuser', 'wgDBpassword' ) );
69                 $this->parent->setVar( 'wgDBname', $this->getVar( 'wgDBuser' ) );
70
71                 // Validate them
72                 $status = Status::newGood();
73                 if ( !strlen( $newValues['wgDBserver'] ) ) {
74                         $status->fatal( 'config-missing-db-server-oracle' );
75                 } elseif ( !preg_match( '/^[a-zA-Z0-9_\.]+$/', $newValues['wgDBserver'] ) ) {
76                         $status->fatal( 'config-invalid-db-server-oracle', $newValues['wgDBserver'] );
77                 }
78                 if ( !preg_match( '/^[a-zA-Z0-9_]*$/', $newValues['wgDBprefix'] ) ) {
79                         $status->fatal( 'config-invalid-schema', $newValues['wgDBprefix'] );
80                 }
81                 if ( !$status->isOK() ) {
82                         return $status;
83                 }
84
85                 // Submit user box
86                 $status = $this->submitInstallUserBox();
87                 if ( !$status->isOK() ) {
88                         return $status;
89                 }
90
91                 // Try to connect trough multiple scenarios
92                 // Scenario 1: Install with a manually created account
93                 $status = $this->getConnection();
94                 if ( !$status->isOK() ) {
95                         if ( $this->connError == 28009 ) { 
96                                 // _InstallUser seems to be a SYSDBA
97                                 // Scenario 2: Create user with SYSDBA and install with new user
98                                 $status = $this->submitWebUserBox();
99                                 if ( !$status->isOK() ) {
100                                         return $status;
101                                 }
102                                 $status = $this->openSYSDBAConnection();
103                                 if ( !$status->isOK() ) {
104                                         return $status;
105                                 }
106                                 if ( !$this->getVar( '_CreateDBAccount' ) ) {
107                                         $status->fatal('config-db-sys-create-oracle');
108                                 }
109                         } else {
110                                 return $status;
111                         }
112                 } else {
113                         // check for web user credentials
114                         // Scenario 3: Install with a priviliged user but use a restricted user
115                         $statusIS3 = $this->submitWebUserBox();
116                         if ( !$statusIS3->isOK() ) {
117                                 return $statusIS3;
118                         }
119                 }
120                 $conn = $status->value;
121
122                 // Check version
123                 $version = $conn->getServerVersion();
124                 if ( version_compare( $version, $this->minimumVersion ) < 0 ) {
125                         return Status::newFatal( 'config-oracle-old', $this->minimumVersion, $version );
126                 }
127
128                 return $status;
129         }
130
131         public function openConnection() {
132                 $status = Status::newGood();
133                 try {
134                         $db = new DatabaseOracle(
135                                 $this->getVar( 'wgDBserver' ),
136                                 $this->getVar( '_InstallUser' ),
137                                 $this->getVar( '_InstallPassword' ),
138                                 $this->getVar( '_InstallDBname' ),
139                                 0,
140                                 $this->getVar( 'wgDBprefix' )
141                         );
142                         $status->value = $db;
143                 } catch ( DBConnectionError $e ) {
144                         $this->connError = $e->db->lastErrno();
145                         $status->fatal( 'config-connection-error', $e->getMessage() );
146                 }
147                 return $status;
148         }
149
150         public function openSYSDBAConnection() {
151                 $status = Status::newGood();
152                 try {
153                         $db = new DatabaseOracle(
154                                 $this->getVar( 'wgDBserver' ),
155                                 $this->getVar( '_InstallUser' ),
156                                 $this->getVar( '_InstallPassword' ),
157                                 $this->getVar( '_InstallDBname' ),
158                                 DBO_SYSDBA,
159                                 $this->getVar( 'wgDBprefix' )
160                         );
161                         $status->value = $db;
162                 } catch ( DBConnectionError $e ) {
163                         $this->connError = $e->db->lastErrno();
164                         $status->fatal( 'config-connection-error', $e->getMessage() );
165                 }
166                 return $status;
167         }
168
169         public function needsUpgrade() {
170                 $tempDBname = $this->getVar( 'wgDBname' );
171                 $this->parent->setVar( 'wgDBname', $this->getVar( 'wgDBuser' ) );
172                 $retVal = parent::needsUpgrade();
173                 $this->parent->setVar( 'wgDBname', $tempDBname );
174                 return $retVal;
175         }
176
177         public function preInstall() {
178                 # Add our user callback to installSteps, right before the tables are created.
179                 $callback = array(
180                         'name' => 'user',
181                         'callback' => array( $this, 'setupUser' )
182                 );
183                 $this->parent->addInstallStep( $callback, 'database' );
184         }
185
186
187         public function setupDatabase() {
188                 $status = Status::newGood();
189                 return $status;
190         }
191
192         public function setupUser() {
193                 global $IP;
194
195                 if ( !$this->getVar( '_CreateDBAccount' ) ) {
196                         return Status::newGood();
197                 }
198
199                 // normaly only SYSDBA users can create accounts
200                 $status = $this->openSYSDBAConnection();
201                 if ( !$status->isOK() ) {
202                         if ( $this->connError == 1031 ) { 
203                                 // insufficient  privileges (looks like a normal user)
204                                 $status = $this->openConnection();
205                                 if ( !$status->isOK() ) {
206                                         return $status;
207                                 }
208                         } else {
209                                 return $status;
210                         }
211                 }
212                 $this->db = $status->value;
213                 $this->setupSchemaVars();
214
215                 if ( !$this->db->selectDB( $this->getVar( 'wgDBuser' ) ) ) {
216                         $this->db->setFlag( DBO_DDLMODE );
217                         $error = $this->db->sourceFile( "$IP/maintenance/oracle/user.sql" );
218                         if ( $error !== true || !$this->db->selectDB( $this->getVar( 'wgDBuser' ) ) ) {
219                                 $status->fatal( 'config-install-user-failed', $this->getVar( 'wgDBuser' ), $error );
220                         }
221                 } elseif ( $this->db->getFlag( DBO_SYSDBA ) ) {
222                         $status->fatal( 'config-db-sys-user-exists-oracle', $this->getVar( 'wgDBuser' ) );
223                 }
224
225                 if ($status->isOK()) {
226                         // user created or already existing, switching back to a normal connection
227                         // as the new user has all needed privileges to setup the rest of the schema
228                         // i will be using that user as _InstallUser from this point on
229                         $this->parent->setVar( '_InstallUser', $this->getVar( 'wgDBuser' ) );
230                         $this->parent->setVar( '_InstallPassword', $this->getVar( 'wgDBpassword' ) );
231                         $this->parent->setVar( '_InstallDBname', $this->getVar( 'wgDBuser' ) );
232                         $status = $this->getConnection();
233                 }
234
235                 return $status;
236         }
237
238         /**
239          * Overload: after this action field info table has to be rebuilt
240          */
241         public function createTables() {
242                 $this->setupSchemaVars();
243                 $this->db->selectDB( $this->getVar( 'wgDBuser' ) );
244                 $this->db->setFlag( DBO_DDLMODE );
245                 $status = parent::createTables();
246                 $this->db->clearFlag( DBO_DDLMODE );
247
248                 $this->db->query( 'BEGIN fill_wiki_info; END;' );
249
250                 return $status;
251         }
252
253         public function getSchemaVars() {
254                 $varNames = array(
255                         # These variables are used by maintenance/oracle/user.sql
256                         '_OracleDefTS',
257                         '_OracleTempTS',
258                         'wgDBuser',
259                         'wgDBpassword',
260
261                         # These are used by tables.sql
262                         'wgDBprefix',
263                 );
264                 $vars = array();
265                 foreach ( $varNames as $name ) {
266                         $vars[$name] = $this->getVar( $name );
267                 }
268                 return $vars;
269         }
270
271         public function getLocalSettings() {
272                 $prefix = $this->getVar( 'wgDBprefix' );
273                 return
274 "# Oracle specific settings
275 \$wgDBprefix         = \"{$prefix}\";
276 ";
277         }
278
279 }