MediaWiki  REL1_24
MssqlInstaller.php
Go to the documentation of this file.
00001 <?php
00030 class MssqlInstaller extends DatabaseInstaller {
00031 
00032     protected $globalNames = array(
00033         'wgDBserver',
00034         'wgDBname',
00035         'wgDBuser',
00036         'wgDBpassword',
00037         'wgDBmwschema',
00038         'wgDBprefix',
00039         'wgDBWindowsAuthentication',
00040     );
00041 
00042     protected $internalDefaults = array(
00043         '_InstallUser' => 'sa',
00044         '_InstallWindowsAuthentication' => 'sqlauth',
00045         '_WebWindowsAuthentication' => 'sqlauth',
00046     );
00047 
00048     // SQL Server 2005 RTM
00049     // @todo Are SQL Express version numbers different?)
00050     public $minimumVersion = '9.00.1399';
00051 
00052     // These are schema-level privs
00053     // Note: the web user will be created will full permissions if possible, this permission
00054     // list is only used if we are unable to grant full permissions.
00055     public $webUserPrivs = array(
00056         'DELETE',
00057         'INSERT',
00058         'SELECT',
00059         'UPDATE',
00060         'EXECUTE',
00061     );
00062 
00066     public function getName() {
00067         return 'mssql';
00068     }
00069 
00073     public function isCompiled() {
00074         return self::checkExtension( 'sqlsrv' );
00075     }
00076 
00080     public function getConnectForm() {
00081         if ( $this->getVar( '_InstallWindowsAuthentication' ) == 'windowsauth' ) {
00082             $displayStyle = 'display: none;';
00083         } else {
00084             $displayStyle = 'display: block;';
00085         }
00086 
00087         return $this->getTextBox(
00088             'wgDBserver',
00089             'config-db-host',
00090             array(),
00091             $this->parent->getHelpBox( 'config-db-host-help' )
00092         ) .
00093             Html::openElement( 'fieldset' ) .
00094             Html::element( 'legend', array(), wfMessage( 'config-db-wiki-settings' )->text() ) .
00095             $this->getTextBox( 'wgDBname', 'config-db-name', array( 'dir' => 'ltr' ),
00096                 $this->parent->getHelpBox( 'config-db-name-help' ) ) .
00097             $this->getTextBox( 'wgDBmwschema', 'config-db-schema', array( 'dir' => 'ltr' ),
00098                 $this->parent->getHelpBox( 'config-db-schema-help' ) ) .
00099             $this->getTextBox( 'wgDBprefix', 'config-db-prefix', array( 'dir' => 'ltr' ),
00100                 $this->parent->getHelpBox( 'config-db-prefix-help' ) ) .
00101             Html::closeElement( 'fieldset' ) .
00102             Html::openElement( 'fieldset' ) .
00103             Html::element( 'legend', array(), wfMessage( 'config-db-install-account' )->text() ) .
00104             $this->getRadioSet( array(
00105                 'var' => '_InstallWindowsAuthentication',
00106                 'label' => 'config-mssql-auth',
00107                 'itemLabelPrefix' => 'config-mssql-',
00108                 'values' => array( 'sqlauth', 'windowsauth' ),
00109                 'itemAttribs' => array(
00110                     'sqlauth' => array(
00111                         'class' => 'showHideRadio',
00112                         'rel' => 'dbCredentialBox',
00113                     ),
00114                     'windowsauth' => array(
00115                         'class' => 'hideShowRadio',
00116                         'rel' => 'dbCredentialBox',
00117                     )
00118                 ),
00119                 'help' => $this->parent->getHelpBox( 'config-mssql-install-auth' )
00120             ) ) .
00121             Html::openElement( 'div', array( 'id' => 'dbCredentialBox', 'style' => $displayStyle ) ) .
00122             $this->getTextBox(
00123                 '_InstallUser',
00124                 'config-db-username',
00125                 array( 'dir' => 'ltr' ),
00126                 $this->parent->getHelpBox( 'config-db-install-username' )
00127             ) .
00128             $this->getPasswordBox(
00129                 '_InstallPassword',
00130                 'config-db-password',
00131                 array( 'dir' => 'ltr' ),
00132                 $this->parent->getHelpBox( 'config-db-install-password' )
00133             ) .
00134             Html::closeElement( 'div' ) .
00135             Html::closeElement( 'fieldset' );
00136     }
00137 
00138     public function submitConnectForm() {
00139         // Get variables from the request.
00140         $newValues = $this->setVarsFromRequest( array(
00141             'wgDBserver',
00142             'wgDBname',
00143             'wgDBmwschema',
00144             'wgDBprefix'
00145         ) );
00146 
00147         // Validate them.
00148         $status = Status::newGood();
00149         if ( !strlen( $newValues['wgDBserver'] ) ) {
00150             $status->fatal( 'config-missing-db-host' );
00151         }
00152         if ( !strlen( $newValues['wgDBname'] ) ) {
00153             $status->fatal( 'config-missing-db-name' );
00154         } elseif ( !preg_match( '/^[a-z0-9_]+$/i', $newValues['wgDBname'] ) ) {
00155             $status->fatal( 'config-invalid-db-name', $newValues['wgDBname'] );
00156         }
00157         if ( !preg_match( '/^[a-z0-9_]*$/i', $newValues['wgDBmwschema'] ) ) {
00158             $status->fatal( 'config-invalid-schema', $newValues['wgDBmwschema'] );
00159         }
00160         if ( !preg_match( '/^[a-z0-9_]*$/i', $newValues['wgDBprefix'] ) ) {
00161             $status->fatal( 'config-invalid-db-prefix', $newValues['wgDBprefix'] );
00162         }
00163         if ( !$status->isOK() ) {
00164             return $status;
00165         }
00166 
00167         // Check for blank schema and remap to dbo
00168         if ( $newValues['wgDBmwschema'] === '' ) {
00169             $this->setVar( 'wgDBmwschema', 'dbo' );
00170         }
00171 
00172         // User box
00173         $this->setVarsFromRequest( array(
00174             '_InstallUser',
00175             '_InstallPassword',
00176             '_InstallWindowsAuthentication'
00177         ) );
00178 
00179         // Try to connect
00180         $status = $this->getConnection();
00181         if ( !$status->isOK() ) {
00182             return $status;
00183         }
00187         $conn = $status->value;
00188 
00189         // Check version
00190         $version = $conn->getServerVersion();
00191         if ( version_compare( $version, $this->minimumVersion ) < 0 ) {
00192             return Status::newFatal( 'config-mssql-old', $this->minimumVersion, $version );
00193         }
00194 
00195         return $status;
00196     }
00197 
00201     public function openConnection() {
00202         global $wgDBWindowsAuthentication;
00203         $status = Status::newGood();
00204         $user = $this->getVar( '_InstallUser' );
00205         $password = $this->getVar( '_InstallPassword' );
00206 
00207         if ( $this->getVar( '_InstallWindowsAuthentication' ) == 'windowsauth' ) {
00208             // Use Windows authentication for this connection
00209             $wgDBWindowsAuthentication = true;
00210         } else {
00211             $wgDBWindowsAuthentication = false;
00212         }
00213 
00214         try {
00215             $db = DatabaseBase::factory( 'mssql', array(
00216                 'host' => $this->getVar( 'wgDBserver' ),
00217                 'user' => $user,
00218                 'password' => $password,
00219                 'dbname' => false,
00220                 'flags' => 0,
00221                 'schema' => $this->getVar( 'wgDBmwschema' ),
00222                 'tablePrefix' => $this->getVar( 'wgDBprefix' ) ) );
00223             $db->prepareStatements( false );
00224             $db->scrollableCursor( false );
00225             $status->value = $db;
00226         } catch ( DBConnectionError $e ) {
00227             $status->fatal( 'config-connection-error', $e->getMessage() );
00228         }
00229 
00230         return $status;
00231     }
00232 
00233     public function preUpgrade() {
00234         global $wgDBuser, $wgDBpassword;
00235 
00236         $status = $this->getConnection();
00237         if ( !$status->isOK() ) {
00238             $this->parent->showStatusError( $status );
00239 
00240             return;
00241         }
00245         $conn = $status->value;
00246         $conn->selectDB( $this->getVar( 'wgDBname' ) );
00247 
00248         # Normal user and password are selected after this step, so for now
00249         # just copy these two
00250         $wgDBuser = $this->getVar( '_InstallUser' );
00251         $wgDBpassword = $this->getVar( '_InstallPassword' );
00252     }
00253 
00259     public function canCreateAccounts() {
00260         $status = $this->getConnection();
00261         if ( !$status->isOK() ) {
00262             return false;
00263         }
00265         $conn = $status->value;
00266 
00267         // We need the server-level ALTER ANY LOGIN permission to create new accounts
00268         $res = $conn->query( "SELECT permission_name FROM sys.fn_my_permissions( NULL, 'SERVER' )" );
00269         $serverPrivs = array(
00270             'ALTER ANY LOGIN' => false,
00271             'CONTROL SERVER' => false,
00272         );
00273 
00274         foreach ( $res as $row ) {
00275             $serverPrivs[$row->permission_name] = true;
00276         }
00277 
00278         if ( !$serverPrivs['ALTER ANY LOGIN'] ) {
00279             return false;
00280         }
00281 
00282         // Check to ensure we can grant everything needed as well
00283         // We can't actually tell if we have WITH GRANT OPTION for a given permission, so we assume we do
00284         // and just check for the permission
00285         // http://technet.microsoft.com/en-us/library/ms178569.aspx
00286         // The following array sets up which permissions imply whatever permissions we specify
00287         $implied = array(
00288             // schema           database  server
00289             'DELETE'  => array( 'DELETE', 'CONTROL SERVER' ),
00290             'EXECUTE' => array( 'EXECUTE', 'CONTROL SERVER' ),
00291             'INSERT'  => array( 'INSERT', 'CONTROL SERVER' ),
00292             'SELECT'  => array( 'SELECT', 'CONTROL SERVER' ),
00293             'UPDATE'  => array( 'UPDATE', 'CONTROL SERVER' ),
00294         );
00295 
00296         $grantOptions = array_flip( $this->webUserPrivs );
00297 
00298         // Check for schema and db-level permissions, but only if the schema/db exists
00299         $schemaPrivs = $dbPrivs = array(
00300             'DELETE' => false,
00301             'EXECUTE' => false,
00302             'INSERT' => false,
00303             'SELECT' => false,
00304             'UPDATE' => false,
00305         );
00306 
00307         $dbPrivs['ALTER ANY USER'] = false;
00308 
00309         if ( $this->databaseExists( $this->getVar( 'wgDBname' ) ) ) {
00310             $conn->selectDB( $this->getVar( 'wgDBname' ) );
00311             $res = $conn->query( "SELECT permission_name FROM sys.fn_my_permissions( NULL, 'DATABASE' )" );
00312 
00313             foreach ( $res as $row ) {
00314                 $dbPrivs[$row->permission_name] = true;
00315             }
00316 
00317             // If the db exists, we need ALTER ANY USER privs on it to make a new user
00318             if ( !$dbPrivs['ALTER ANY USER'] ) {
00319                 return false;
00320             }
00321 
00322             if ( $this->schemaExists( $this->getVar( 'wgDBmwschema' ) ) ) {
00323                 // wgDBmwschema is validated to only contain alphanumeric + underscore, so this is safe
00324                 $res = $conn->query( "SELECT permission_name FROM sys.fn_my_permissions( "
00325                     . "'{$this->getVar( 'wgDBmwschema' )}', 'SCHEMA' )" );
00326 
00327                 foreach ( $res as $row ) {
00328                     $schemaPrivs[$row->permission_name] = true;
00329                 }
00330             }
00331         }
00332 
00333         // Now check all the grants we'll need to be doing to see if we can
00334         foreach ( $this->webUserPrivs as $permission ) {
00335             if ( ( isset( $schemaPrivs[$permission] ) && $schemaPrivs[$permission] )
00336                     || ( isset( $dbPrivs[$implied[$permission][0]] )
00337                         && $dbPrivs[$implied[$permission][0]] )
00338                     || ( isset( $serverPrivs[$implied[$permission][1]] )
00339                         && $serverPrivs[$implied[$permission][1]] )
00340             ) {
00341                 unset( $grantOptions[$permission] );
00342             }
00343         }
00344 
00345         if ( count( $grantOptions ) ) {
00346             // Can't grant everything
00347             return false;
00348         }
00349 
00350         return true;
00351     }
00352 
00356     public function getSettingsForm() {
00357         if ( $this->canCreateAccounts() ) {
00358             $noCreateMsg = false;
00359         } else {
00360             $noCreateMsg = 'config-db-web-no-create-privs';
00361         }
00362 
00363         $wrapperStyle = $this->getVar( '_SameAccount' ) ? 'display: none' : '';
00364         $displayStyle = $this->getVar( '_WebWindowsAuthentication' ) == 'windowsauth'
00365             ? 'display: none'
00366             : '';
00367         $s = Html::openElement( 'fieldset' ) .
00368             Html::element( 'legend', array(), wfMessage( 'config-db-web-account' )->text() ) .
00369             $this->getCheckBox(
00370                 '_SameAccount', 'config-db-web-account-same',
00371                 array( 'class' => 'hideShowRadio', 'rel' => 'dbOtherAccount' )
00372             ) .
00373             Html::openElement( 'div', array( 'id' => 'dbOtherAccount', 'style' => $wrapperStyle ) ) .
00374             $this->getRadioSet( array(
00375                 'var' => '_WebWindowsAuthentication',
00376                 'label' => 'config-mssql-auth',
00377                 'itemLabelPrefix' => 'config-mssql-',
00378                 'values' => array( 'sqlauth', 'windowsauth' ),
00379                 'itemAttribs' => array(
00380                     'sqlauth' => array(
00381                         'class' => 'showHideRadio',
00382                         'rel' => 'dbCredentialBox',
00383                     ),
00384                     'windowsauth' => array(
00385                         'class' => 'hideShowRadio',
00386                         'rel' => 'dbCredentialBox',
00387                     )
00388                 ),
00389                 'help' => $this->parent->getHelpBox( 'config-mssql-web-auth' )
00390             ) ) .
00391             Html::openElement( 'div', array( 'id' => 'dbCredentialBox', 'style' => $displayStyle ) ) .
00392             $this->getTextBox( 'wgDBuser', 'config-db-username' ) .
00393             $this->getPasswordBox( 'wgDBpassword', 'config-db-password' ) .
00394             Html::closeElement( 'div' );
00395 
00396         if ( $noCreateMsg ) {
00397             $s .= $this->parent->getWarningBox( wfMessage( $noCreateMsg )->plain() );
00398         } else {
00399             $s .= $this->getCheckBox( '_CreateDBAccount', 'config-db-web-create' );
00400         }
00401 
00402         $s .= Html::closeElement( 'div' ) . Html::closeElement( 'fieldset' );
00403 
00404         return $s;
00405     }
00406 
00410     public function submitSettingsForm() {
00411         $this->setVarsFromRequest( array(
00412                 'wgDBuser',
00413                 'wgDBpassword',
00414                 '_SameAccount',
00415                 '_CreateDBAccount',
00416                 '_WebWindowsAuthentication'
00417         ) );
00418 
00419         if ( $this->getVar( '_SameAccount' ) ) {
00420             $this->setVar( '_WebWindowsAuthentication', $this->getVar( '_InstallWindowsAuthentication' ) );
00421             $this->setVar( 'wgDBuser', $this->getVar( '_InstallUser' ) );
00422             $this->setVar( 'wgDBpassword', $this->getVar( '_InstallPassword' ) );
00423         }
00424 
00425         if ( $this->getVar( '_WebWindowsAuthentication' ) == 'windowsauth' ) {
00426             $this->setVar( 'wgDBuser', '' );
00427             $this->setVar( 'wgDBpassword', '' );
00428             $this->setVar( 'wgDBWindowsAuthentication', true );
00429         } else {
00430             $this->setVar( 'wgDBWindowsAuthentication', false );
00431         }
00432 
00433         if ( $this->getVar( '_CreateDBAccount' )
00434             && $this->getVar( '_WebWindowsAuthentication' ) == 'sqlauth'
00435             && strval( $this->getVar( 'wgDBpassword' ) ) == ''
00436         ) {
00437             return Status::newFatal( 'config-db-password-empty', $this->getVar( 'wgDBuser' ) );
00438         }
00439 
00440         // Validate the create checkbox
00441         $canCreate = $this->canCreateAccounts();
00442         if ( !$canCreate ) {
00443             $this->setVar( '_CreateDBAccount', false );
00444             $create = false;
00445         } else {
00446             $create = $this->getVar( '_CreateDBAccount' );
00447         }
00448 
00449         if ( !$create ) {
00450             // Test the web account
00451             $user = $this->getVar( 'wgDBuser' );
00452             $password = $this->getVar( 'wgDBpassword' );
00453 
00454             if ( $this->getVar( '_WebWindowsAuthentication' ) == 'windowsauth' ) {
00455                 $user = 'windowsauth';
00456                 $password = 'windowsauth';
00457             }
00458 
00459             try {
00460                 DatabaseBase::factory( 'mssql', array(
00461                     'host' => $this->getVar( 'wgDBserver' ),
00462                     'user' => $user,
00463                     'password' => $password,
00464                     'dbname' => false,
00465                     'flags' => 0,
00466                     'tablePrefix' => $this->getVar( 'wgDBprefix' ),
00467                     'schema' => $this->getVar( 'wgDBmwschema' ),
00468                 ) );
00469             } catch ( DBConnectionError $e ) {
00470                 return Status::newFatal( 'config-connection-error', $e->getMessage() );
00471             }
00472         }
00473 
00474         return Status::newGood();
00475     }
00476 
00477     public function preInstall() {
00478         # Add our user callback to installSteps, right before the tables are created.
00479         $callback = array(
00480             'name' => 'user',
00481             'callback' => array( $this, 'setupUser' ),
00482         );
00483         $this->parent->addInstallStep( $callback, 'tables' );
00484     }
00485 
00489     public function setupDatabase() {
00490         $status = $this->getConnection();
00491         if ( !$status->isOK() ) {
00492             return $status;
00493         }
00495         $conn = $status->value;
00496         $dbName = $this->getVar( 'wgDBname' );
00497         $schemaName = $this->getVar( 'wgDBmwschema' );
00498         if ( !$this->databaseExists( $dbName ) ) {
00499             $conn->query(
00500                 "CREATE DATABASE " . $conn->addIdentifierQuotes( $dbName ),
00501                 __METHOD__
00502             );
00503             $conn->selectDB( $dbName );
00504             if ( !$this->schemaExists( $schemaName ) ) {
00505                 $conn->query(
00506                     "CREATE SCHEMA " . $conn->addIdentifierQuotes( $schemaName ),
00507                     __METHOD__
00508                 );
00509             }
00510             if ( !$this->catalogExists( $schemaName ) ) {
00511                 $conn->query(
00512                     "CREATE FULLTEXT CATALOG " . $conn->addIdentifierQuotes( $schemaName ),
00513                     __METHOD__
00514                 );
00515             }
00516         }
00517         $this->setupSchemaVars();
00518 
00519         return $status;
00520     }
00521 
00525     public function setupUser() {
00526         $dbUser = $this->getVar( 'wgDBuser' );
00527         if ( $dbUser == $this->getVar( '_InstallUser' )
00528                 || ( $this->getVar( '_InstallWindowsAuthentication' ) == 'windowsauth'
00529                     && $this->getVar( '_WebWindowsAuthentication' ) == 'windowsauth' ) ) {
00530             return Status::newGood();
00531         }
00532         $status = $this->getConnection();
00533         if ( !$status->isOK() ) {
00534             return $status;
00535         }
00536 
00537         $this->setupSchemaVars();
00538         $dbName = $this->getVar( 'wgDBname' );
00539         $this->db->selectDB( $dbName );
00540         $server = $this->getVar( 'wgDBserver' );
00541         $password = $this->getVar( 'wgDBpassword' );
00542         $schemaName = $this->getVar( 'wgDBmwschema' );
00543 
00544         if ( $this->getVar( '_WebWindowsAuthentication' ) == 'windowsauth' ) {
00545             $dbUser = 'windowsauth';
00546             $password = 'windowsauth';
00547         }
00548 
00549         if ( $this->getVar( '_CreateDBAccount' ) ) {
00550             $tryToCreate = true;
00551         } else {
00552             $tryToCreate = false;
00553         }
00554 
00555         $escUser = $this->db->addIdentifierQuotes( $dbUser );
00556         $escDb = $this->db->addIdentifierQuotes( $dbName );
00557         $escSchema = $this->db->addIdentifierQuotes( $schemaName );
00558         $grantableNames = array();
00559         if ( $tryToCreate ) {
00560             $escPass = $this->db->addQuotes( $password );
00561 
00562             if ( !$this->loginExists( $dbUser ) ) {
00563                 try {
00564                     $this->db->begin();
00565                     $this->db->selectDB( 'master' );
00566                     $logintype = $this->getVar( '_WebWindowsAuthentication' ) == 'windowsauth'
00567                         ? 'FROM WINDOWS'
00568                         : "WITH PASSWORD = $escPass";
00569                     $this->db->query( "CREATE LOGIN $escUser $logintype" );
00570                     $this->db->selectDB( $dbName );
00571                     $this->db->query( "CREATE USER $escUser FOR LOGIN $escUser WITH DEFAULT_SCHEMA = $escSchema" );
00572                     $this->db->commit();
00573                     $grantableNames[] = $dbUser;
00574                 } catch ( DBQueryError $dqe ) {
00575                     $this->db->rollback();
00576                     $status->warning( 'config-install-user-create-failed', $dbUser, $dqe->getText() );
00577                 }
00578             } elseif ( !$this->userExists( $dbUser ) ) {
00579                 try {
00580                     $this->db->begin();
00581                     $this->db->selectDB( $dbName );
00582                     $this->db->query( "CREATE USER $escUser FOR LOGIN $escUser WITH DEFAULT_SCHEMA = $escSchema" );
00583                     $this->db->commit();
00584                     $grantableNames[] = $dbUser;
00585                 } catch ( DBQueryError $dqe ) {
00586                     $this->db->rollback();
00587                     $status->warning( 'config-install-user-create-failed', $dbUser, $dqe->getText() );
00588                 }
00589             } else {
00590                 $status->warning( 'config-install-user-alreadyexists', $dbUser );
00591                 $grantableNames[] = $dbUser;
00592             }
00593         }
00594 
00595         // Try to grant to all the users we know exist or we were able to create
00596         $this->db->selectDB( $dbName );
00597         foreach ( $grantableNames as $name ) {
00598             try {
00599                 // First try to grant full permissions
00600                 $fullPrivArr = array(
00601                     'BACKUP DATABASE', 'BACKUP LOG', 'CREATE FUNCTION', 'CREATE PROCEDURE',
00602                     'CREATE TABLE', 'CREATE VIEW', 'CREATE FULLTEXT CATALOG', 'SHOWPLAN'
00603                 );
00604                 $fullPrivList = implode( ', ', $fullPrivArr );
00605                 $this->db->begin();
00606                 $this->db->query( "GRANT $fullPrivList ON DATABASE :: $escDb TO $escUser", __METHOD__ );
00607                 $this->db->query( "GRANT CONTROL ON SCHEMA :: $escSchema TO $escUser", __METHOD__ );
00608                 $this->db->commit();
00609             } catch ( DBQueryError $dqe ) {
00610                 // If that fails, try to grant the limited subset specified in $this->webUserPrivs
00611                 try {
00612                     $privList = implode( ', ', $this->webUserPrivs );
00613                     $this->db->rollback();
00614                     $this->db->begin();
00615                     $this->db->query( "GRANT $privList ON SCHEMA :: $escSchema TO $escUser", __METHOD__ );
00616                     $this->db->commit();
00617                 } catch ( DBQueryError $dqe ) {
00618                     $this->db->rollback();
00619                     $status->fatal( 'config-install-user-grant-failed', $dbUser, $dqe->getText() );
00620                 }
00621                 // Also try to grant SHOWPLAN on the db, but don't fail if we can't
00622                 // (just makes a couple things in mediawiki run slower since
00623                 // we have to run SELECT COUNT(*) instead of getting the query plan)
00624                 try {
00625                     $this->db->query( "GRANT SHOWPLAN ON DATABASE :: $escDb TO $escUser", __METHOD__ );
00626                 } catch ( DBQueryError $dqe ) {
00627                 }
00628             }
00629         }
00630 
00631         return $status;
00632     }
00633 
00634     public function createTables() {
00635         $status = parent::createTables();
00636 
00637         // Do last-minute stuff like fulltext indexes (since they can't be inside a transaction)
00638         if ( $status->isOk() ) {
00639             $searchindex = $this->db->tableName( 'searchindex' );
00640             $schema = $this->db->addIdentifierQuotes( $this->getVar( 'wgDBmwschema' ) );
00641             try {
00642                 $this->db->query( "CREATE FULLTEXT INDEX ON $searchindex (si_title, si_text) "
00643                     . "KEY INDEX si_page ON $schema" );
00644             } catch ( DBQueryError $dqe ) {
00645                 $status->fatal( 'config-install-tables-failed', $dqe->getText() );
00646             }
00647         }
00648 
00649         return $status;
00650     }
00651 
00652     public function getGlobalDefaults() {
00653         // The default $wgDBmwschema is null, which breaks Postgres and other DBMSes that require
00654         // the use of a schema, so we need to set it here
00655         return array(
00656             'wgDBmwschema' => 'mediawiki',
00657         );
00658     }
00659 
00665     private function loginExists( $user ) {
00666         $res = $this->db->selectField( 'sys.sql_logins', 1, array( 'name' => $user ) );
00667         return (bool)$res;
00668     }
00669 
00676     private function userExists( $user ) {
00677         $res = $this->db->selectField( 'sys.sysusers', 1, array( 'name' => $user ) );
00678         return (bool)$res;
00679     }
00680 
00686     private function databaseExists( $dbName ) {
00687         $res = $this->db->selectField( 'sys.databases', 1, array( 'name' => $dbName ) );
00688         return (bool)$res;
00689     }
00690 
00697     private function schemaExists( $schemaName ) {
00698         $res = $this->db->selectField( 'sys.schemas', 1, array( 'name' => $schemaName ) );
00699         return (bool)$res;
00700     }
00701 
00708     private function catalogExists( $catalogName ) {
00709         $res = $this->db->selectField( 'sys.fulltext_catalogs', 1, array( 'name' => $catalogName ) );
00710         return (bool)$res;
00711     }
00712 
00718     public function getSchemaVars() {
00719         return array(
00720             'wgDBname' => $this->getVar( 'wgDBname' ),
00721             'wgDBmwschema' => $this->getVar( 'wgDBmwschema' ),
00722             'wgDBuser' => $this->getVar( 'wgDBuser' ),
00723             'wgDBpassword' => $this->getVar( 'wgDBpassword' ),
00724         );
00725     }
00726 
00727     public function getLocalSettings() {
00728         $schema = LocalSettingsGenerator::escapePhpString( $this->getVar( 'wgDBmwschema' ) );
00729         $prefix = LocalSettingsGenerator::escapePhpString( $this->getVar( 'wgDBprefix' ) );
00730         $windowsauth = $this->getVar( 'wgDBWindowsAuthentication' ) ? 'true' : 'false';
00731 
00732         return "# MSSQL specific settings
00733 \$wgDBWindowsAuthentication = {$windowsauth};
00734 \$wgDBmwschema = \"{$schema}\";
00735 \$wgDBprefix = \"{$prefix}\";";
00736     }
00737 }