[ Index ] |
PHP Cross Reference of MediaWiki-1.24.0 |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Oracle-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 Oracle. 26 * 27 * @ingroup Deployment 28 * @since 1.17 29 */ 30 class OracleInstaller extends DatabaseInstaller { 31 32 protected $globalNames = array( 33 'wgDBserver', 34 'wgDBname', 35 'wgDBuser', 36 'wgDBpassword', 37 'wgDBprefix', 38 ); 39 40 protected $internalDefaults = array( 41 '_OracleDefTS' => 'USERS', 42 '_OracleTempTS' => 'TEMP', 43 '_InstallUser' => 'SYSTEM', 44 ); 45 46 public $minimumVersion = '9.0.1'; // 9iR1 47 48 protected $connError = null; 49 50 public function getName() { 51 return 'oracle'; 52 } 53 54 public function isCompiled() { 55 return self::checkExtension( 'oci8' ); 56 } 57 58 public function getConnectForm() { 59 if ( $this->getVar( 'wgDBserver' ) == 'localhost' ) { 60 $this->parent->setVar( 'wgDBserver', '' ); 61 } 62 63 return $this->getTextBox( 64 'wgDBserver', 65 'config-db-host-oracle', 66 array(), 67 $this->parent->getHelpBox( 'config-db-host-oracle-help' ) 68 ) . 69 Html::openElement( 'fieldset' ) . 70 Html::element( 'legend', array(), wfMessage( 'config-db-wiki-settings' )->text() ) . 71 $this->getTextBox( 'wgDBprefix', 'config-db-prefix' ) . 72 $this->getTextBox( '_OracleDefTS', 'config-oracle-def-ts' ) . 73 $this->getTextBox( 74 '_OracleTempTS', 75 'config-oracle-temp-ts', 76 array(), 77 $this->parent->getHelpBox( 'config-db-oracle-help' ) 78 ) . 79 Html::closeElement( 'fieldset' ) . 80 $this->parent->getWarningBox( wfMessage( 'config-db-account-oracle-warn' )->text() ) . 81 $this->getInstallUserBox() . 82 $this->getWebUserBox(); 83 } 84 85 public function submitInstallUserBox() { 86 parent::submitInstallUserBox(); 87 $this->parent->setVar( '_InstallDBname', $this->getVar( '_InstallUser' ) ); 88 89 return Status::newGood(); 90 } 91 92 public function submitConnectForm() { 93 // Get variables from the request 94 $newValues = $this->setVarsFromRequest( array( 95 'wgDBserver', 96 'wgDBprefix', 97 'wgDBuser', 98 'wgDBpassword' 99 ) ); 100 $this->parent->setVar( 'wgDBname', $this->getVar( 'wgDBuser' ) ); 101 102 // Validate them 103 $status = Status::newGood(); 104 if ( !strlen( $newValues['wgDBserver'] ) ) { 105 $status->fatal( 'config-missing-db-server-oracle' ); 106 } elseif ( !self::checkConnectStringFormat( $newValues['wgDBserver'] ) ) { 107 $status->fatal( 'config-invalid-db-server-oracle', $newValues['wgDBserver'] ); 108 } 109 if ( !preg_match( '/^[a-zA-Z0-9_]*$/', $newValues['wgDBprefix'] ) ) { 110 $status->fatal( 'config-invalid-schema', $newValues['wgDBprefix'] ); 111 } 112 if ( !$status->isOK() ) { 113 return $status; 114 } 115 116 // Submit user box 117 $status = $this->submitInstallUserBox(); 118 if ( !$status->isOK() ) { 119 return $status; 120 } 121 122 // Try to connect trough multiple scenarios 123 // Scenario 1: Install with a manually created account 124 $status = $this->getConnection(); 125 if ( !$status->isOK() ) { 126 if ( $this->connError == 28009 ) { 127 // _InstallUser seems to be a SYSDBA 128 // Scenario 2: Create user with SYSDBA and install with new user 129 $status = $this->submitWebUserBox(); 130 if ( !$status->isOK() ) { 131 return $status; 132 } 133 $status = $this->openSYSDBAConnection(); 134 if ( !$status->isOK() ) { 135 return $status; 136 } 137 if ( !$this->getVar( '_CreateDBAccount' ) ) { 138 $status->fatal( 'config-db-sys-create-oracle' ); 139 } 140 } else { 141 return $status; 142 } 143 } else { 144 // check for web user credentials 145 // Scenario 3: Install with a priviliged user but use a restricted user 146 $statusIS3 = $this->submitWebUserBox(); 147 if ( !$statusIS3->isOK() ) { 148 return $statusIS3; 149 } 150 } 151 152 /** 153 * @var $conn DatabaseBase 154 */ 155 $conn = $status->value; 156 157 // Check version 158 $version = $conn->getServerVersion(); 159 if ( version_compare( $version, $this->minimumVersion ) < 0 ) { 160 return Status::newFatal( 'config-oracle-old', $this->minimumVersion, $version ); 161 } 162 163 return $status; 164 } 165 166 public function openConnection() { 167 $status = Status::newGood(); 168 try { 169 $db = new DatabaseOracle( 170 $this->getVar( 'wgDBserver' ), 171 $this->getVar( '_InstallUser' ), 172 $this->getVar( '_InstallPassword' ), 173 $this->getVar( '_InstallDBname' ), 174 0, 175 $this->getVar( 'wgDBprefix' ) 176 ); 177 $status->value = $db; 178 } catch ( DBConnectionError $e ) { 179 $this->connError = $e->db->lastErrno(); 180 $status->fatal( 'config-connection-error', $e->getMessage() ); 181 } 182 183 return $status; 184 } 185 186 public function openSYSDBAConnection() { 187 $status = Status::newGood(); 188 try { 189 $db = new DatabaseOracle( 190 $this->getVar( 'wgDBserver' ), 191 $this->getVar( '_InstallUser' ), 192 $this->getVar( '_InstallPassword' ), 193 $this->getVar( '_InstallDBname' ), 194 DBO_SYSDBA, 195 $this->getVar( 'wgDBprefix' ) 196 ); 197 $status->value = $db; 198 } catch ( DBConnectionError $e ) { 199 $this->connError = $e->db->lastErrno(); 200 $status->fatal( 'config-connection-error', $e->getMessage() ); 201 } 202 203 return $status; 204 } 205 206 public function needsUpgrade() { 207 $tempDBname = $this->getVar( 'wgDBname' ); 208 $this->parent->setVar( 'wgDBname', $this->getVar( 'wgDBuser' ) ); 209 $retVal = parent::needsUpgrade(); 210 $this->parent->setVar( 'wgDBname', $tempDBname ); 211 212 return $retVal; 213 } 214 215 public function preInstall() { 216 # Add our user callback to installSteps, right before the tables are created. 217 $callback = array( 218 'name' => 'user', 219 'callback' => array( $this, 'setupUser' ) 220 ); 221 $this->parent->addInstallStep( $callback, 'database' ); 222 } 223 224 public function setupDatabase() { 225 $status = Status::newGood(); 226 227 return $status; 228 } 229 230 public function setupUser() { 231 global $IP; 232 233 if ( !$this->getVar( '_CreateDBAccount' ) ) { 234 return Status::newGood(); 235 } 236 237 // normaly only SYSDBA users can create accounts 238 $status = $this->openSYSDBAConnection(); 239 if ( !$status->isOK() ) { 240 if ( $this->connError == 1031 ) { 241 // insufficient privileges (looks like a normal user) 242 $status = $this->openConnection(); 243 if ( !$status->isOK() ) { 244 return $status; 245 } 246 } else { 247 return $status; 248 } 249 } 250 251 $this->db = $status->value; 252 $this->setupSchemaVars(); 253 254 if ( !$this->db->selectDB( $this->getVar( 'wgDBuser' ) ) ) { 255 $this->db->setFlag( DBO_DDLMODE ); 256 $error = $this->db->sourceFile( "$IP/maintenance/oracle/user.sql" ); 257 if ( $error !== true || !$this->db->selectDB( $this->getVar( 'wgDBuser' ) ) ) { 258 $status->fatal( 'config-install-user-failed', $this->getVar( 'wgDBuser' ), $error ); 259 } 260 } elseif ( $this->db->getFlag( DBO_SYSDBA ) ) { 261 $status->fatal( 'config-db-sys-user-exists-oracle', $this->getVar( 'wgDBuser' ) ); 262 } 263 264 if ( $status->isOK() ) { 265 // user created or already existing, switching back to a normal connection 266 // as the new user has all needed privileges to setup the rest of the schema 267 // i will be using that user as _InstallUser from this point on 268 $this->db->close(); 269 $this->db = false; 270 $this->parent->setVar( '_InstallUser', $this->getVar( 'wgDBuser' ) ); 271 $this->parent->setVar( '_InstallPassword', $this->getVar( 'wgDBpassword' ) ); 272 $this->parent->setVar( '_InstallDBname', $this->getVar( 'wgDBuser' ) ); 273 $status = $this->getConnection(); 274 } 275 276 return $status; 277 } 278 279 /** 280 * Overload: after this action field info table has to be rebuilt 281 * @return Status 282 */ 283 public function createTables() { 284 $this->setupSchemaVars(); 285 $this->db->setFlag( DBO_DDLMODE ); 286 $this->parent->setVar( 'wgDBname', $this->getVar( 'wgDBuser' ) ); 287 $status = parent::createTables(); 288 $this->db->clearFlag( DBO_DDLMODE ); 289 290 $this->db->query( 'BEGIN fill_wiki_info; END;' ); 291 292 return $status; 293 } 294 295 public function getSchemaVars() { 296 $varNames = array( 297 # These variables are used by maintenance/oracle/user.sql 298 '_OracleDefTS', 299 '_OracleTempTS', 300 'wgDBuser', 301 'wgDBpassword', 302 303 # These are used by tables.sql 304 'wgDBprefix', 305 ); 306 $vars = array(); 307 foreach ( $varNames as $name ) { 308 $vars[$name] = $this->getVar( $name ); 309 } 310 311 return $vars; 312 } 313 314 public function getLocalSettings() { 315 $prefix = $this->getVar( 'wgDBprefix' ); 316 317 return "# Oracle specific settings 318 \$wgDBprefix = \"{$prefix}\"; 319 "; 320 } 321 322 /** 323 * Function checks the format of Oracle connect string 324 * The actual validity of the string is checked by attempting to connect 325 * 326 * Regex should be able to validate all connect string formats 327 * [//](host|tns_name)[:port][/service_name][:POOLED] 328 * http://www.orafaq.com/wiki/EZCONNECT 329 * 330 * @since 1.22 331 * 332 * @param string $connect_string 333 * 334 * @return bool Whether the connection string is valid. 335 */ 336 public static function checkConnectStringFormat( $connect_string ) { 337 // @@codingStandardsIgnoreStart Long lines with regular expressions. 338 // @todo Very long regular expression. Make more readable? 339 $isValid = preg_match( '/^[[:alpha:]][\w\-]*(?:\.[[:alpha:]][\w\-]*){0,2}$/', $connect_string ); // TNS name 340 $isValid |= preg_match( '/^(?:\/\/)?[\w\-\.]+(?::[\d]+)?(?:\/(?:[\w\-\.]+(?::(pooled|dedicated|shared))?)?(?:\/[\w\-\.]+)?)?$/', $connect_string ); // EZConnect 341 // @@codingStandardsIgnoreEnd 342 return (bool)$isValid; 343 } 344 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 14:03:12 2014 | Cross-referenced by PHPXref 0.7.1 |