Index: trunk/phase3/includes/db/DatabaseOracle.php |
— | — | @@ -244,9 +244,9 @@ |
245 | 245 | |
246 | 246 | $session_mode = $this->mFlags & DBO_SYSDBA ? OCI_SYSDBA : OCI_DEFAULT; |
247 | 247 | if ( $this->mFlags & DBO_DEFAULT ) { |
248 | | - $this->mConn = oci_new_connect( $this->mUser, $this->mPassword, $this->mServer, $this->defaultCharset, $session_mode ); |
| 248 | + $this->mConn = @oci_new_connect( $this->mUser, $this->mPassword, $this->mServer, $this->defaultCharset, $session_mode ); |
249 | 249 | } else { |
250 | | - $this->mConn = oci_connect( $this->mUser, $this->mPassword, $this->mServer, $this->defaultCharset, $session_mode ); |
| 250 | + $this->mConn = @oci_connect( $this->mUser, $this->mPassword, $this->mServer, $this->defaultCharset, $session_mode ); |
251 | 251 | } |
252 | 252 | |
253 | 253 | if ( $this->mUser != $this->mDBname ) { |
— | — | @@ -789,12 +789,7 @@ |
790 | 790 | # Returns the size of a text field, or -1 for "unlimited" |
791 | 791 | function textFieldSize( $table, $field ) { |
792 | 792 | $fieldInfoData = $this->fieldInfo( $table, $field ); |
793 | | - if ( $fieldInfoData->type() == 'varchar' ) { |
794 | | - $size = $row->size - 4; // FIXME: $row is undefined |
795 | | - } else { |
796 | | - $size = $row->size; |
797 | | - } |
798 | | - return $size; |
| 793 | + return $fieldInfoData->maxLength(); |
799 | 794 | } |
800 | 795 | |
801 | 796 | function limitResult( $sql, $limit, $offset = false ) { |
Index: trunk/phase3/includes/installer/Installer.i18n.php |
— | — | @@ -170,6 +170,11 @@ |
171 | 171 | |
172 | 172 | If you are using shared web hosting, your hosting provider will either give you a specific database name to use or let you create databases via a control panel.', |
173 | 173 | 'config-db-name-oracle' => 'Database schema:', |
| 174 | + 'config-db-account-oracle-warn' => "There are three supported scenarios for installing Oracle as database backend: |
| 175 | + |
| 176 | +If you wish to create database account as part of the installation process, please supply an account with SYSDBA role as database account for installation and specify the desired credentials for the web-access account, otherwise you can either create the web-access account manually and supply only that account (if it has required permissions to create the schema objects) or supply two different accounts, one with create privileges and a restricted one for web access. |
| 177 | + |
| 178 | +Script for creating an account with required privileges can be found in \"maintenance/oracle/\" directory of this installation. Keep in mind that using a restricted account will disable all maintenance capabilities with the default account.", |
174 | 179 | 'config-db-install-account' => 'User account for installation', |
175 | 180 | 'config-db-username' => 'Database username:', |
176 | 181 | 'config-db-password' => 'Database password:', |
— | — | @@ -249,6 +254,8 @@ |
250 | 255 | Check the host, username and password below and try again.', |
251 | 256 | 'config-invalid-schema' => 'Invalid schema for MediaWiki "$1". |
252 | 257 | Use only ASCII letters (a-z, A-Z), numbers (0-9) and underscores (_).', |
| 258 | + 'config-db-sys-create-oracle' => 'Installer only supports using a SYSDBA account for creating a new account.', |
| 259 | + 'config-db-sys-user-exists-oracle' => 'User account "$1" already exists. SYSDBA can only be used for creating of a new account!', |
253 | 260 | 'config-postgres-old' => 'PostgreSQL $1 or later is required, you have $2.', |
254 | 261 | 'config-sqlite-name-help' => 'Choose a name that identifies your wiki. |
255 | 262 | Do not use spaces or hyphens. |
Index: trunk/phase3/includes/installer/OracleInstaller.php |
— | — | @@ -27,11 +27,9 @@ |
28 | 28 | '_OracleTempTS' => 'TEMP' |
29 | 29 | ); |
30 | 30 | |
31 | | - protected $useSysDBA = false; |
32 | | - |
33 | 31 | public $minimumVersion = '9.0.1'; // 9iR1 |
34 | 32 | |
35 | | - protected $sysConn, $userConn; |
| 33 | + protected $connError = null; |
36 | 34 | |
37 | 35 | public function getName() { |
38 | 36 | return 'oracle'; |
— | — | @@ -41,22 +39,10 @@ |
42 | 40 | return self::checkExtension( 'oci8' ); |
43 | 41 | } |
44 | 42 | |
45 | | - public function getWebUserBox( $noCreateMsg = false ) { |
46 | | - $this->parent->setVar( '_SameAccount', false ); |
47 | | - $this->parent->setVar( '_CreateDBAccount', true ); |
48 | | - $this->parent->setVar( 'wgDBname', '' ); |
49 | | - return Html::openElement( 'fieldset' ) . |
50 | | - Html::element( 'legend', array(), wfMsg( 'config-db-web-account' ) ) . |
51 | | - Html::openElement( 'div', array( 'id' => 'dbOtherAccount' ) ) . |
52 | | - $this->getTextBox( 'wgDBuser', 'config-db-username' ) . |
53 | | - $this->getPasswordBox( 'wgDBpassword', 'config-db-password', array(), $this->parent->getHelpBox( 'config-db-web-help' ) ) . |
54 | | - $this->getCheckBox( '_CreateDBAccount', 'config-db-web-create', array( 'disabled' => true ) ). |
55 | | - Html::closeElement( 'div' ) . Html::closeElement( 'fieldset' ); |
56 | | - } |
57 | | - |
58 | 43 | public function getConnectForm() { |
59 | | - $this->parent->setVar( '_InstallUser', 'sys' ); |
60 | | - $this->parent->setVar( 'wgDBserver', '' ); |
| 44 | + if ( $this->getVar( 'wgDBserver' ) == 'localhost' ) { |
| 45 | + $this->parent->setVar( 'wgDBserver', '' ); |
| 46 | + } |
61 | 47 | return |
62 | 48 | $this->getTextBox( 'wgDBserver', 'config-db-host-oracle', array(), $this->parent->getHelpBox( 'config-db-host-oracle-help' ) ) . |
63 | 49 | Html::openElement( 'fieldset' ) . |
— | — | @@ -65,10 +51,17 @@ |
66 | 52 | $this->getTextBox( '_OracleDefTS', 'config-oracle-def-ts' ) . |
67 | 53 | $this->getTextBox( '_OracleTempTS', 'config-oracle-temp-ts', array(), $this->parent->getHelpBox( 'config-db-oracle-help' ) ) . |
68 | 54 | Html::closeElement( 'fieldset' ) . |
| 55 | + $this->parent->getWarningBox( wfMsg( 'config-db-account-oracle-warn' ) ). |
69 | 56 | $this->getInstallUserBox(). |
70 | 57 | $this->getWebUserBox(); |
71 | 58 | } |
72 | 59 | |
| 60 | + public function submitInstallUserBox() { |
| 61 | + parent::submitInstallUserBox(); |
| 62 | + $this->parent->setVar( '_InstallDBname', $this->getVar( '_InstallUser' ) ); |
| 63 | + return Status::newGood(); |
| 64 | + } |
| 65 | + |
73 | 66 | public function submitConnectForm() { |
74 | 67 | // Get variables from the request |
75 | 68 | $newValues = $this->setVarsFromRequest( array( 'wgDBserver', 'wgDBprefix', 'wgDBuser', 'wgDBpassword' ) ); |
— | — | @@ -94,11 +87,34 @@ |
95 | 88 | return $status; |
96 | 89 | } |
97 | 90 | |
98 | | - // Try to connect |
99 | | - $this->useSysDBA = true; |
| 91 | + // Try to connect trough multiple scenarios |
| 92 | + // Scenario 1: Install with a manually created account |
100 | 93 | $status = $this->getConnection(); |
101 | 94 | if ( !$status->isOK() ) { |
102 | | - return $status; |
| 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 | + } |
103 | 119 | } |
104 | 120 | $conn = $status->value; |
105 | 121 | |
— | — | @@ -114,65 +130,38 @@ |
115 | 131 | public function openConnection() { |
116 | 132 | $status = Status::newGood(); |
117 | 133 | try { |
118 | | - if ( $this->useSysDBA ) { |
119 | | - $db = new DatabaseOracle( |
120 | | - $this->getVar( 'wgDBserver' ), |
121 | | - $this->getVar( '_InstallUser' ), |
122 | | - $this->getVar( '_InstallPassword' ), |
123 | | - $this->getVar( '_InstallUser' ), |
124 | | - DBO_SYSDBA | DBO_DDLMODE, |
125 | | - $this->getVar( 'wgDBprefix' ) |
126 | | - ); |
127 | | - } else { |
128 | | - $db = new DatabaseOracle( |
129 | | - $this->getVar( 'wgDBserver' ), |
130 | | - $this->getVar( 'wgDBuser' ), |
131 | | - $this->getVar( 'wgDBpassword' ), |
132 | | - $this->getVar( 'wgDBname' ), |
133 | | - 0, |
134 | | - $this->getVar( 'wgDBprefix' ) |
135 | | - ); |
136 | | - } |
| 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 | + ); |
137 | 142 | $status->value = $db; |
138 | 143 | } catch ( DBConnectionError $e ) { |
| 144 | + $this->connError = $e->db->lastErrno(); |
139 | 145 | $status->fatal( 'config-connection-error', $e->getMessage() ); |
140 | 146 | } |
141 | 147 | return $status; |
142 | 148 | } |
143 | 149 | |
144 | | - /** |
145 | | - * Cache the two different types of connection which can be returned by |
146 | | - * openConnection(). |
147 | | - * |
148 | | - * $this->db will be set to the last used connection object. |
149 | | - * |
150 | | - * FIXME: openConnection() should not be doing two different things. |
151 | | - */ |
152 | | - public function getConnection() { |
153 | | - // Check cache |
154 | | - if ( $this->useSysDBA ) { |
155 | | - $conn = $this->sysConn; |
156 | | - } else { |
157 | | - $conn = $this->userConn; |
| 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() ); |
158 | 165 | } |
159 | | - if ( $conn !== null ) { |
160 | | - $this->db = $conn; |
161 | | - return Status::newGood( $conn ); |
162 | | - } |
163 | | - |
164 | | - // Open a new connection |
165 | | - $status = $this->openConnection(); |
166 | | - if ( !$status->isOK() ) { |
167 | | - return $status; |
168 | | - } |
169 | | - |
170 | | - // Save to the cache |
171 | | - if ( $this->useSysDBA ) { |
172 | | - $this->sysConn = $status->value; |
173 | | - } else { |
174 | | - $this->userConn = $status->value; |
175 | | - } |
176 | | - $this->db = $status->value; |
177 | 166 | return $status; |
178 | 167 | } |
179 | 168 | |
— | — | @@ -195,7 +184,6 @@ |
196 | 185 | |
197 | 186 | |
198 | 187 | public function setupDatabase() { |
199 | | - $this->useSysDBA = false; |
200 | 188 | $status = Status::newGood(); |
201 | 189 | return $status; |
202 | 190 | } |
— | — | @@ -207,12 +195,20 @@ |
208 | 196 | return Status::newGood(); |
209 | 197 | } |
210 | 198 | |
211 | | - $this->useSysDBA = true; |
212 | | - $status = $this->getConnection(); |
| 199 | + // normaly only SYSDBA users can create accounts |
| 200 | + $status = $this->openSYSDBAConnection(); |
213 | 201 | if ( !$status->isOK() ) { |
214 | | - return $status; |
| 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 | + } |
215 | 211 | } |
216 | | - |
| 212 | + $this->db = $status->value; |
217 | 213 | $this->setupSchemaVars(); |
218 | 214 | |
219 | 215 | if ( !$this->db->selectDB( $this->getVar( 'wgDBuser' ) ) ) { |
— | — | @@ -221,8 +217,19 @@ |
222 | 218 | if ( $error !== true || !$this->db->selectDB( $this->getVar( 'wgDBuser' ) ) ) { |
223 | 219 | $status->fatal( 'config-install-user-failed', $this->getVar( 'wgDBuser' ), $error ); |
224 | 220 | } |
| 221 | + } elseif ( $this->db->getFlag( DBO_SYSDBA ) ) { |
| 222 | + $status->fatal( 'config-db-sys-user-exists-oracle', $this->getVar( 'wgDBuser' ) ); |
225 | 223 | } |
226 | 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 | + } |
227 | 234 | |
228 | 235 | return $status; |
229 | 236 | } |
— | — | @@ -233,7 +240,9 @@ |
234 | 241 | public function createTables() { |
235 | 242 | $this->setupSchemaVars(); |
236 | 243 | $this->db->selectDB( $this->getVar( 'wgDBuser' ) ); |
| 244 | + $this->db->setFlag( DBO_DDLMODE ); |
237 | 245 | $status = parent::createTables(); |
| 246 | + $this->db->clearFlag( DBO_DDLMODE ); |
238 | 247 | |
239 | 248 | $this->db->query( 'BEGIN fill_wiki_info; END;' ); |
240 | 249 | |