Index: trunk/phase3/includes/installer/PostgresUpdater.php |
— | — | @@ -79,7 +79,6 @@ |
80 | 80 | array( 'addPgField', 'logging', 'log_id', "INTEGER NOT NULL PRIMARY KEY DEFAULT nextval('logging_log_id_seq')" ), |
81 | 81 | array( 'addPgField', 'logging', 'log_params', 'TEXT' ), |
82 | 82 | array( 'addPgField', 'mwuser', 'user_editcount', 'INTEGER' ), |
83 | | - array( 'addPgField', 'mwuser', 'user_hidden', 'SMALLINT NOT NULL DEFAULT 0' ), |
84 | 83 | array( 'addPgField', 'mwuser', 'user_newpass_time', 'TIMESTAMPTZ' ), |
85 | 84 | array( 'addPgField', 'oldimage', 'oi_deleted', 'SMALLINT NOT NULL DEFAULT 0' ), |
86 | 85 | array( 'addPgField', 'oldimage', 'oi_major_mime', "TEXT NOT NULL DEFAULT 'unknown'" ), |
Index: trunk/phase3/includes/installer/Installer.i18n.php |
— | — | @@ -256,7 +256,7 @@ |
257 | 257 | Use only ASCII letters (a-z, A-Z), numbers (0-9), underscores (_) and hyphens (-).', |
258 | 258 | 'config-connection-error' => '$1. |
259 | 259 | |
260 | | -Check the host, username and password below and try again.', |
| 260 | +Check the host, username and password and try again.', |
261 | 261 | 'config-invalid-schema' => 'Invalid schema for MediaWiki "$1". |
262 | 262 | Use only ASCII letters (a-z, A-Z), numbers (0-9) and underscores (_).', |
263 | 263 | 'config-db-sys-create-oracle' => 'Installer only supports using a SYSDBA account for creating a new account.', |
Index: trunk/phase3/includes/installer/Ibm_db2Installer.php |
— | — | @@ -113,7 +113,7 @@ |
114 | 114 | * Open a DB2 database connection |
115 | 115 | * @return Status |
116 | 116 | */ |
117 | | - public function openConnection() { |
| 117 | + public function openConnection( $dbName = null ) { |
118 | 118 | $status = Status::newGood(); |
119 | 119 | try { |
120 | 120 | $db = new DatabaseIbm_db2( |
Index: trunk/phase3/includes/installer/SqliteInstaller.php |
— | — | @@ -122,7 +122,7 @@ |
123 | 123 | /** |
124 | 124 | * @return Status |
125 | 125 | */ |
126 | | - public function openConnection() { |
| 126 | + public function openConnection( $dbName = null ) { |
127 | 127 | global $wgSQLiteDataDir; |
128 | 128 | |
129 | 129 | $status = Status::newGood(); |
Index: trunk/phase3/includes/installer/DatabaseInstaller.php |
— | — | @@ -102,7 +102,7 @@ |
103 | 103 | * |
104 | 104 | * @return Status |
105 | 105 | */ |
106 | | - public abstract function openConnection(); |
| 106 | + public abstract function openConnection( $dbName = null ); |
107 | 107 | |
108 | 108 | /** |
109 | 109 | * Create the database and return a Status object indicating success or |
— | — | @@ -121,11 +121,14 @@ |
122 | 122 | * |
123 | 123 | * @return Status |
124 | 124 | */ |
125 | | - public function getConnection() { |
126 | | - if ( $this->db ) { |
| 125 | + public function getConnection( $dbName = null ) { |
| 126 | + if ( isset($this->db) && $this->db ) { /* Weirdly get E_STRICT |
| 127 | + * errors without the |
| 128 | + * isset */ |
127 | 129 | return Status::newGood( $this->db ); |
128 | 130 | } |
129 | | - $status = $this->openConnection(); |
| 131 | + |
| 132 | + $status = $this->openConnection( $dbName ); |
130 | 133 | if ( $status->isOK() ) { |
131 | 134 | $this->db = $status->value; |
132 | 135 | // Enable autocommit |
Index: trunk/phase3/includes/installer/MysqlInstaller.php |
— | — | @@ -126,7 +126,7 @@ |
127 | 127 | /** |
128 | 128 | * @return Status |
129 | 129 | */ |
130 | | - public function openConnection() { |
| 130 | + public function openConnection( $dbName = null ) { |
131 | 131 | $status = Status::newGood(); |
132 | 132 | try { |
133 | 133 | $db = new DatabaseMysql( |
Index: trunk/phase3/includes/installer/OracleInstaller.php |
— | — | @@ -127,7 +127,7 @@ |
128 | 128 | return $status; |
129 | 129 | } |
130 | 130 | |
131 | | - public function openConnection() { |
| 131 | + public function openConnection( $dbName = null ) { |
132 | 132 | $status = Status::newGood(); |
133 | 133 | try { |
134 | 134 | $db = new DatabaseOracle( |
Index: trunk/phase3/includes/installer/PostgresInstaller.php |
— | — | @@ -101,22 +101,31 @@ |
102 | 102 | return $status; |
103 | 103 | } |
104 | 104 | |
105 | | - public function openConnection() { |
| 105 | + public function openConnection( $dbName = null ) { |
106 | 106 | $status = Status::newGood(); |
107 | 107 | try { |
108 | 108 | if ( $this->useAdmin ) { |
| 109 | + if ( $dbName === null ) $dbName = 'postgres'; |
| 110 | + |
109 | 111 | $db = new DatabasePostgres( |
110 | 112 | $this->getVar( 'wgDBserver' ), |
111 | 113 | $this->getVar( '_InstallUser' ), |
112 | 114 | $this->getVar( '_InstallPassword' ), |
113 | | - 'postgres' ); |
| 115 | + $dbName ); |
114 | 116 | } else { |
| 117 | + if ( $dbName === null ) $dbName = $this->getVar( 'wgDBname' ); |
| 118 | + |
115 | 119 | $db = new DatabasePostgres( |
116 | 120 | $this->getVar( 'wgDBserver' ), |
117 | 121 | $this->getVar( 'wgDBuser' ), |
118 | 122 | $this->getVar( 'wgDBpassword' ), |
119 | | - $this->getVar( 'wgDBname' ) ); |
| 123 | + $dbName ); |
120 | 124 | } |
| 125 | + |
| 126 | + if( $db === null ) throw new DBConnectionError("Unknown problem while connecting."); |
| 127 | + $safeschema = $db->addIdentifierQuotes( $this->getVar( 'wgDBmwschema' ) ); |
| 128 | + if( $db->schemaExists( $this->getVar( 'wgDBmwschema' ) ) ) $db->query( "SET search_path = $safeschema" ); |
| 129 | + |
121 | 130 | $status->value = $db; |
122 | 131 | } catch ( DBConnectionError $e ) { |
123 | 132 | $status->fatal( 'config-connection-error', $e->getMessage() ); |
— | — | @@ -134,15 +143,15 @@ |
135 | 144 | |
136 | 145 | $superuser = $this->getVar( '_InstallUser' ); |
137 | 146 | |
138 | | - $rights = $conn->selectField( 'pg_catalog.pg_user', |
139 | | - 'CASE WHEN usesuper IS TRUE THEN |
140 | | - CASE WHEN usecreatedb IS TRUE THEN 3 ELSE 1 END |
141 | | - ELSE CASE WHEN usecreatedb IS TRUE THEN 2 ELSE 0 END |
142 | | - END AS rights', |
143 | | - array( 'usename' => $superuser ), __METHOD__ |
| 147 | + $rights = $conn->selectField( 'pg_catalog.pg_roles', |
| 148 | + 'CASE WHEN rolsuper then 1 |
| 149 | + WHEN rolcreatedb then 2 |
| 150 | + ELSE 3 |
| 151 | + END as rights', |
| 152 | + array( 'rolname' => $superuser ), __METHOD__ |
144 | 153 | ); |
145 | 154 | |
146 | | - if( !$rights || ( $rights != 1 && $rights != 3 ) ) { |
| 155 | + if( !$rights || $rights == 3 ) { |
147 | 156 | return false; |
148 | 157 | } |
149 | 158 | |
— | — | @@ -226,9 +235,10 @@ |
227 | 236 | $rows = $conn->numRows( $conn->query( $SQL ) ); |
228 | 237 | $safedb = $conn->addIdentifierQuotes( $dbName ); |
229 | 238 | if( !$rows ) { |
230 | | - $conn->query( "CREATE DATABASE $safedb OWNER $safeuser", __METHOD__ ); |
| 239 | + $conn->query( "CREATE DATABASE $safedb", __METHOD__ ); |
| 240 | + $conn->query( "GRANT ALL ON DATABASE $safedb to $safeuser", __METHOD__ ); |
231 | 241 | } else { |
232 | | - $conn->query( "ALTER DATABASE $safedb OWNER TO $safeuser", __METHOD__ ); |
| 242 | + $conn->query( "GRANT ALL ON DATABASE $safedb TO $safeuser", __METHOD__ ); |
233 | 243 | } |
234 | 244 | |
235 | 245 | // Now that we've established the real database exists, connect to it |
— | — | @@ -287,17 +297,18 @@ |
288 | 298 | $safeschema = $this->db->addIdentifierQuotes( $schema ); |
289 | 299 | |
290 | 300 | $rows = $this->db->numRows( |
291 | | - $this->db->query( "SELECT 1 FROM pg_catalog.pg_shadow WHERE usename = $safeusercheck" ) |
| 301 | + $this->db->query( "SELECT 1 FROM pg_catalog.pg_roles WHERE rolname = $safeusercheck" ) |
292 | 302 | ); |
293 | 303 | if ( $rows < 1 ) { |
294 | | - $res = $this->db->query( "CREATE USER $safeuser NOCREATEDB PASSWORD $safepass", __METHOD__ ); |
| 304 | + $res = $this->db->query( "CREATE ROLE $safeuser NOCREATEDB LOGIN PASSWORD $safepass", __METHOD__ ); |
295 | 305 | if ( $res !== true && !( $res instanceOf ResultWrapper ) ) { |
296 | 306 | $status->fatal( 'config-install-user-failed', $this->getVar( 'wgDBuser' ), $res ); |
297 | 307 | } |
298 | 308 | if( $status->isOK() ) { |
299 | | - $this->db->query("ALTER USER $safeuser SET search_path = $safeschema"); |
| 309 | + $this->db->query("ALTER ROLE $safeuser LOGIN"); |
300 | 310 | } |
301 | 311 | } |
| 312 | + $this->db->query("ALTER ROLE $safeuser SET search_path = $safeschema, public"); |
302 | 313 | |
303 | 314 | return $status; |
304 | 315 | } |
— | — | @@ -337,12 +348,11 @@ |
338 | 349 | |
339 | 350 | $this->db->begin( __METHOD__ ); |
340 | 351 | |
| 352 | + // getConnection() should have already selected the schema if it exists |
341 | 353 | if( !$this->db->schemaExists( $schema ) ) { |
342 | 354 | $status->error( 'config-install-pg-schema-not-exist' ); |
343 | 355 | return $status; |
344 | 356 | } |
345 | | - $safeschema = $this->db->addIdentifierQuotes( $schema ); |
346 | | - $this->db->query( "SET search_path = $safeschema" ); |
347 | 357 | $error = $this->db->sourceFile( $this->db->getSchema() ); |
348 | 358 | if( $error !== true ) { |
349 | 359 | $this->db->reportQueryError( $error, 0, '', __METHOD__ ); |
— | — | @@ -359,12 +369,18 @@ |
360 | 370 | } |
361 | 371 | |
362 | 372 | public function setupPLpgSQL() { |
| 373 | + $this->db = null; |
363 | 374 | $this->useAdmin = true; |
364 | | - $status = $this->getConnection(); |
| 375 | + $dbName = $this->getVar( 'wgDBname' ); |
| 376 | + $status = $this->getConnection( $dbName ); |
365 | 377 | if ( !$status->isOK() ) { |
366 | 378 | return $status; |
367 | 379 | } |
| 380 | + $this->db = $status->value; |
368 | 381 | |
| 382 | + /* Admin user has to be connected to the db it just |
| 383 | + created to satisfy ownership requirements for |
| 384 | + "CREATE LANGAUGE" */ |
369 | 385 | $rows = $this->db->numRows( |
370 | 386 | $this->db->query( "SELECT 1 FROM pg_catalog.pg_language WHERE lanname = 'plpgsql'" ) |
371 | 387 | ); |
— | — | @@ -373,7 +389,6 @@ |
374 | 390 | $SQL = "SELECT 1 FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON (n.oid = c.relnamespace) ". |
375 | 391 | "WHERE relname = 'pg_pltemplate' AND nspname='pg_catalog'"; |
376 | 392 | $rows = $this->db->numRows( $this->db->query( $SQL ) ); |
377 | | - $dbName = $this->getVar( 'wgDBname' ); |
378 | 393 | if ( $rows >= 1 ) { |
379 | 394 | $result = $this->db->query( 'CREATE LANGUAGE plpgsql' ); |
380 | 395 | if ( !$result ) { |