Index: trunk/phase3/maintenance/ora/tables.sql |
— | — | @@ -1,4 +1,5 @@ |
2 | | -DEFINE mw_prefix=''; |
| 2 | +-- defines must comply with ^define\s*([^\s=]*)\s*=\s?'\{\$([^\}]*)\}'; |
| 3 | +define mw_prefix='{$wgDBprefix}'; |
3 | 4 | |
4 | 5 | |
5 | 6 | CREATE SEQUENCE user_user_id_seq MINVALUE 0 START WITH 0; |
— | — | @@ -70,12 +71,13 @@ |
71 | 72 | CREATE INDEX &mw_prefix.page_i01 ON &mw_prefix.page (page_random); |
72 | 73 | CREATE INDEX &mw_prefix.page_i02 ON &mw_prefix.page (page_len); |
73 | 74 | |
| 75 | +/*$mw$*/ |
74 | 76 | CREATE TRIGGER &mw_prefix.page_set_random BEFORE INSERT ON &mw_prefix.page |
75 | | - FOR EACH ROW WHEN (new.page_random IS NULL) |
76 | | - BEGIN |
77 | | - SELECT dbms_random.value INTO :NEW.page_random FROM dual; |
78 | | - END; |
79 | | -/ |
| 77 | + FOR EACH ROW WHEN (new.page_random IS NULL) |
| 78 | +BEGIN |
| 79 | + SELECT dbms_random.value INTO :NEW.page_random FROM dual; |
| 80 | +END; |
| 81 | +/*$mw$*/ |
80 | 82 | |
81 | 83 | CREATE SEQUENCE rev_rev_id_val; |
82 | 84 | CREATE TABLE &mw_prefix.revision ( |
— | — | @@ -463,7 +465,9 @@ |
464 | 466 | CREATE TABLE &mw_prefix.redirect ( |
465 | 467 | rd_from NUMBER NOT NULL REFERENCES &mw_prefix.page(page_id) ON DELETE CASCADE, |
466 | 468 | rd_namespace NUMBER NOT NULL, |
467 | | - rd_title VARCHAR2(255) NOT NULL |
| 469 | + rd_title VARCHAR2(255) NOT NULL, |
| 470 | + rd_interwiki VARCHAR2(32), |
| 471 | + rd_fragment VARCHAR2(255) |
468 | 472 | ); |
469 | 473 | CREATE INDEX &mw_prefix.redirect_i01 ON &mw_prefix.redirect (rd_namespace,rd_title,rd_from); |
470 | 474 | |
— | — | @@ -571,6 +575,7 @@ |
572 | 576 | ); |
573 | 577 | ALTER TABLE &mw_prefix.wiki_field_info_full ADD CONSTRAINT &mw_prefix.wiki_field_info_full_pk PRIMARY KEY (table_name, column_name); |
574 | 578 | |
| 579 | +/*$mw$*/ |
575 | 580 | CREATE PROCEDURE &mw_prefix.fill_wiki_info IS |
576 | 581 | BEGIN |
577 | 582 | DELETE &mw_prefix.wiki_field_info_full; |
— | — | @@ -619,12 +624,17 @@ |
620 | 625 | END LOOP; |
621 | 626 | COMMIT; |
622 | 627 | END; |
| 628 | +/*$mw$*/ |
623 | 629 | |
| 630 | +/*$mw$*/ |
624 | 631 | BEGIN |
625 | 632 | &mw_prefix.fill_wiki_info; |
626 | 633 | END; |
| 634 | +/*$mw$*/ |
627 | 635 | |
| 636 | +/*$mw$*/ |
628 | 637 | CREATE OR REPLACE FUNCTION BITOR (x IN NUMBER, y IN NUMBER) RETURN NUMBER AS |
629 | 638 | BEGIN |
630 | 639 | RETURN (x + y - BITAND(x, y)); |
631 | 640 | END; |
| 641 | +/*$mw$*/ |
Index: trunk/phase3/maintenance/ora/user.sql |
— | — | @@ -1,13 +1,15 @@ |
2 | | -define WIKI_USER=&1 |
3 | | -define WIKI_PASS=&2 |
4 | | -define DEF_TS=&3 |
5 | | -define TEMP_TS=&4 |
6 | | -create user &&wiki_user identified by &&wiki_pass default tablespace &&def_ts temporary tablespace &&temp_ts quota unlimited on &&def_ts; |
7 | | -grant connect, resource to &&wiki_user; |
8 | | -grant alter session to &&wiki_user; |
9 | | -grant ctxapp to &&wiki_user; |
10 | | -grant execute on ctx_ddl to &&wiki_user; |
11 | | -grant create view to &&wiki_user; |
12 | | -grant create synonym to &&wiki_user; |
13 | | -grant create table to &&wiki_user; |
14 | | -grant create sequence to &&wiki_user; |
| 2 | +-- defines must comply with ^define\s*([^\s=]*)\s*=\s?'\{\$([^\}]*)\}'; |
| 3 | +define wiki_user='{$wgDBuser}'; |
| 4 | +define wiki_pass='{$wgDBpassword}'; |
| 5 | +define def_ts='{$wgDBOracleDefTS}'; |
| 6 | +define temp_ts='{$wgDBOracleTempTS}'; |
| 7 | + |
| 8 | +create user &wiki_user. identified by &wiki_pass. default tablespace &def_ts. temporary tablespace &temp_ts. quota unlimited on &def_ts.; |
| 9 | +grant connect, resource to &wiki_user.; |
| 10 | +grant alter session to &wiki_user.; |
| 11 | +grant ctxapp to &wiki_user.; |
| 12 | +grant execute on ctx_ddl to &wiki_user.; |
| 13 | +grant create view to &wiki_user.; |
| 14 | +grant create synonym to &wiki_user.; |
| 15 | +grant create table to &wiki_user.; |
| 16 | +grant create sequence to &wiki_user.; |
Index: trunk/phase3/includes/Defines.php |
— | — | @@ -18,6 +18,7 @@ |
19 | 19 | define( 'DBO_TRX', 8 ); |
20 | 20 | define( 'DBO_DEFAULT', 16 ); |
21 | 21 | define( 'DBO_PERSISTENT', 32 ); |
| 22 | +define( 'DBO_SYSDBA', 64 ); //for oracle maintenance |
22 | 23 | /**#@-*/ |
23 | 24 | |
24 | 25 | # Valid database indexes |
Index: trunk/phase3/includes/db/DatabaseOracle.php |
— | — | @@ -217,14 +217,15 @@ |
218 | 218 | $this->mDBname = $dbName; |
219 | 219 | |
220 | 220 | if (!strlen($user)) { ## e.g. the class is being loaded |
221 | | - return; |
| 221 | + return; |
222 | 222 | } |
223 | 223 | |
224 | 224 | //error_reporting( E_ALL ); //whoever had this bright idea |
| 225 | + $session_mode = $this->mFlags & DBO_SYSDBA ? OCI_SYSDBA : OCI_DEFAULT; |
225 | 226 | if ( $this->mFlags & DBO_DEFAULT ) |
226 | | - $this->mConn = oci_new_connect($user, $password, $dbName); |
| 227 | + $this->mConn = oci_new_connect($user, $password, $dbName, null, $session_mode); |
227 | 228 | else |
228 | | - $this->mConn = oci_connect($user, $password, $dbName); |
| 229 | + $this->mConn = oci_connect($user, $password, $dbName, null, $session_mode); |
229 | 230 | |
230 | 231 | if ($this->mConn == false) { |
231 | 232 | wfDebug("DB connection error\n"); |
— | — | @@ -832,6 +833,101 @@ |
833 | 834 | return $sql; |
834 | 835 | } |
835 | 836 | |
| 837 | + /* defines must comply with ^define\s*([^\s=]*)\s*=\s?'\{\$([^\}]*)\}'; */ |
| 838 | + function sourceStream( $fp, $lineCallback = false, $resultCallback = false ) { |
| 839 | + $cmd = ""; |
| 840 | + $done = false; |
| 841 | + $dollarquote = false; |
| 842 | + |
| 843 | + $replacements = array(); |
| 844 | + |
| 845 | + while ( ! feof( $fp ) ) { |
| 846 | + if ( $lineCallback ) { |
| 847 | + call_user_func( $lineCallback ); |
| 848 | + } |
| 849 | + $line = trim( fgets( $fp, 1024 ) ); |
| 850 | + $sl = strlen( $line ) - 1; |
| 851 | + |
| 852 | + if ( $sl < 0 ) { continue; } |
| 853 | + if ( '-' == $line{0} && '-' == $line{1} ) { continue; } |
| 854 | + |
| 855 | + // Allow dollar quoting for function declarations |
| 856 | + if (substr($line,0,8) == '/*$mw$*/') { |
| 857 | + if ($dollarquote) { |
| 858 | + $dollarquote = false; |
| 859 | + $done = true; |
| 860 | + } |
| 861 | + else { |
| 862 | + $dollarquote = true; |
| 863 | + } |
| 864 | + } |
| 865 | + else if (!$dollarquote) { |
| 866 | + if ( ';' == $line{$sl} && ($sl < 2 || ';' != $line{$sl - 1})) { |
| 867 | + $done = true; |
| 868 | + $line = substr( $line, 0, $sl ); |
| 869 | + } |
| 870 | + } |
| 871 | + |
| 872 | + if ( '' != $cmd ) { $cmd .= ' '; } |
| 873 | + $cmd .= "$line\n"; |
| 874 | + |
| 875 | + if ( $done ) { |
| 876 | + $cmd = str_replace(';;', ";", $cmd); |
| 877 | + if (strtolower(substr($cmd, 0, 6)) == 'define' ) { |
| 878 | + if (preg_match('/^define\s*([^\s=]*)\s*=\s*\'\{\$([^\}]*)\}\'/', $cmd, $defines)) { |
| 879 | + $replacements[$defines[2]] = $defines[1]; |
| 880 | + } |
| 881 | + } else { |
| 882 | + foreach ( $replacements as $mwVar=>$scVar ) { |
| 883 | + $cmd = str_replace( '&' . $scVar . '.', '{$'.$mwVar.'}', $cmd ); |
| 884 | + } |
| 885 | + |
| 886 | + $cmd = $this->replaceVars( $cmd ); |
| 887 | + $res = $this->query( $cmd, __METHOD__ ); |
| 888 | + if ( $resultCallback ) { |
| 889 | + call_user_func( $resultCallback, $res, $this ); |
| 890 | + } |
| 891 | + |
| 892 | + if ( false === $res ) { |
| 893 | + $err = $this->lastError(); |
| 894 | + return "Query \"{$cmd}\" failed with error code \"$err\".\n"; |
| 895 | + } |
| 896 | + } |
| 897 | + |
| 898 | + $cmd = ''; |
| 899 | + $done = false; |
| 900 | + } |
| 901 | + } |
| 902 | + return true; |
| 903 | + } |
| 904 | + |
| 905 | + function setup_database() { |
| 906 | + global $wgVersion, $wgDBmwschema, $wgDBts2schema, $wgDBport, $wgDBuser; |
| 907 | + |
| 908 | + echo "<li>Creating DB objects</li>\n"; |
| 909 | + $res = dbsource( "../maintenance/ora/tables.sql", $this); |
| 910 | + |
| 911 | + // Avoid the non-standard "REPLACE INTO" syntax |
| 912 | + echo "<li>Populating table interwiki</li>\n"; |
| 913 | + $f = fopen( "../maintenance/interwiki.sql", 'r' ); |
| 914 | + if ($f == false ) { |
| 915 | + dieout( "<li>Could not find the interwiki.sql file</li>"); |
| 916 | + } |
| 917 | + |
| 918 | + //do it like the postgres :D |
| 919 | + $SQL = "INSERT INTO interwiki(iw_prefix,iw_url,iw_local) VALUES "; |
| 920 | + while ( ! feof( $f ) ) { |
| 921 | + $line = fgets($f,1024); |
| 922 | + $matches = array(); |
| 923 | + if (!preg_match('/^\s*(\(.+?),(\d)\)/', $line, $matches)) { |
| 924 | + continue; |
| 925 | + } |
| 926 | + $this->query("$SQL $matches[1],$matches[2])"); |
| 927 | + } |
| 928 | + |
| 929 | + echo "<li>Table interwiki successfully populated</li>\n"; |
| 930 | + } |
| 931 | + |
836 | 932 | function strencode($s) { |
837 | 933 | return str_replace("'", "''", $s); |
838 | 934 | } |
— | — | @@ -967,6 +1063,26 @@ |
968 | 1064 | return $this->mServer; |
969 | 1065 | } |
970 | 1066 | |
| 1067 | + public function replaceVars( $ins ) { |
| 1068 | + $varnames = array('wgDBprefix'); |
| 1069 | + if ($this->mFlags & DBO_SYSDBA) { |
| 1070 | + $varnames[] = 'wgDBOracleDefTS'; |
| 1071 | + $varnames[] = 'wgDBOracleTempTS'; |
| 1072 | + } |
| 1073 | + |
| 1074 | + // Ordinary variables |
| 1075 | + foreach ( $varnames as $var ) { |
| 1076 | + if( isset( $GLOBALS[$var] ) ) { |
| 1077 | + $val = addslashes( $GLOBALS[$var] ); // FIXME: safety check? |
| 1078 | + $ins = str_replace( '{$' . $var . '}', $val, $ins ); |
| 1079 | + $ins = str_replace( '/*$' . $var . '*/`', '`' . $val, $ins ); |
| 1080 | + $ins = str_replace( '/*$' . $var . '*/', $val, $ins ); |
| 1081 | + } |
| 1082 | + } |
| 1083 | + |
| 1084 | + return parent::replaceVars($ins); |
| 1085 | + } |
| 1086 | + |
971 | 1087 | /** |
972 | 1088 | * No-op lock functions |
973 | 1089 | */ |
Index: trunk/phase3/config/index.php |
— | — | @@ -87,6 +87,12 @@ |
88 | 88 | $ourdb['ibm_db2']['bgcolor'] = '#ffeba1'; |
89 | 89 | $ourdb['ibm_db2']['rootuser'] = 'db2admin'; |
90 | 90 | |
| 91 | +$ourdb['oracle']['fullname'] = 'Oracle'; |
| 92 | +$ourdb['oracle']['havedriver'] = 0; |
| 93 | +$ourdb['oracle']['compile'] = 'oci8'; |
| 94 | +$ourdb['oracle']['bgcolor'] = '#ffeba1'; |
| 95 | +$ourdb['oracle']['rootuser'] = ''; |
| 96 | + |
91 | 97 | ?> |
92 | 98 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
93 | 99 | <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr"> |
— | — | @@ -634,6 +640,11 @@ |
635 | 641 | $conf->DBmwschema = importPost( "DBmwschema", "mediawiki" ); |
636 | 642 | $conf->DBcataloged = importPost( "DBcataloged", "cataloged" ); |
637 | 643 | |
| 644 | + // Oracle specific |
| 645 | + $conf->DBprefix_ora = importPost( "DBprefix_ora" ); |
| 646 | + $conf->DBdefTS_ora = importPost( "DBdefTS_ora", "USERS" ); |
| 647 | + $conf->DBtempTS_ora = importPost( "DBtempTS_ora", "TEMP" ); |
| 648 | + |
638 | 649 | $conf->ShellLocale = getShellLocale( $conf->LanguageCode ); |
639 | 650 | |
640 | 651 | /* Check for validity */ |
— | — | @@ -659,6 +670,9 @@ |
660 | 671 | } else { |
661 | 672 | untaint( $conf->DBprefix, TC_MYSQL ); |
662 | 673 | } |
| 674 | +if( !preg_match( '/^[A-Za-z_0-9]*$/', $conf->DBprefix_ora ) ) { |
| 675 | + $errs["DBprefix_ora"] = "Invalid table prefix"; |
| 676 | +} |
663 | 677 | |
664 | 678 | error_reporting( E_ALL ); |
665 | 679 | |
— | — | @@ -804,6 +818,9 @@ |
805 | 819 | if( $conf->DBprefix2 != '' ) { |
806 | 820 | // For MSSQL |
807 | 821 | $wgDBprefix = $conf->DBprefix2; |
| 822 | + } elseif( $conf->DBprefix_ora != '' ) { |
| 823 | + // For Oracle |
| 824 | + $wgDBprefix = $conf->DBprefix_ora; |
808 | 825 | } |
809 | 826 | |
810 | 827 | ## DB2 specific: |
— | — | @@ -945,6 +962,46 @@ |
946 | 963 | } |
947 | 964 | if (is_callable(array($wgDatabase, 'initial_setup'))) $wgDatabase->initial_setup('', $wgDBname); |
948 | 965 | echo "ok</li>\n"; |
| 966 | + } elseif ( $conf->DBtype == 'oracle' ) { |
| 967 | + echo "<li>Attempting to connect to database \"" . htmlspecialchars( $wgDBname ) ."\"</li>"; |
| 968 | + $wgDatabase = $dbc->newFromParams('DUMMY', $wgDBuser, $wgDBpassword, $wgDBname, 1); |
| 969 | + if (!$wgDatabase->isOpen()) { |
| 970 | + $ok = true; |
| 971 | + echo "<li>Connect failed.</li>"; |
| 972 | + if ($useRoot) { |
| 973 | + if (ini_get('oci8.privileged_connect') === false) { |
| 974 | + echo "<li>Privileged connect disabled, please set oci8.privileged_connect or run maintenance/ora/user.sql script manually prior to continuing.</li>"; |
| 975 | + $ok = false; |
| 976 | + } else { |
| 977 | + $wgDBadminuser = $conf->RootUser; |
| 978 | + $wgDBadminpassword = $conf->RootPW; |
| 979 | + echo "<li>Attempting to create DB user.</li>"; |
| 980 | + $wgDatabase = $dbc->newFromParams('DUMMY', $wgDBadminuser, $wgDBadminpassword, $wgDBname, 1, 64); |
| 981 | + if ($wgDatabase->isOpen()) { |
| 982 | + $wgDBOracleDefTS = $conf->DBdefTS_ora; |
| 983 | + $wgDBOracleTempTS = $conf->DBtempTS_ora; |
| 984 | + dbsource( "../maintenance/ora/user.sql", $wgDatabase ); |
| 985 | + } else { |
| 986 | + echo "<li>Invalid database superuser, please supply a valid superuser account.</li>"; |
| 987 | + echo "<li>ERR: ".print_r(oci_error(), true)."</li>"; |
| 988 | + $ok = false; |
| 989 | + } |
| 990 | + } |
| 991 | + } else { |
| 992 | + echo "<li>Database superuser missing, please supply a valid superuser account.</li>"; |
| 993 | + $ok = false; |
| 994 | + } |
| 995 | + if (!$ok) { |
| 996 | + $errs["RootUser"] = "Check username"; |
| 997 | + $errs["RootPW"] = "and password"; |
| 998 | + } else { |
| 999 | + echo "<li>Attempting to connect to database with new user \"" . htmlspecialchars( $wgDBname ) ."\"</li>"; |
| 1000 | + $wgDatabase = $dbc->newFromParams('DUMMY', $wgDBuser, $wgDBpassword, $wgDBname, 1); |
| 1001 | + } |
| 1002 | + } |
| 1003 | + if ($ok) { |
| 1004 | + $myver = $wgDatabase->getServerVersion(); |
| 1005 | + } |
949 | 1006 | } else { # not mysql |
950 | 1007 | error_reporting( E_ALL ); |
951 | 1008 | $wgSuperUser = ''; |
— | — | @@ -1578,6 +1635,19 @@ |
1579 | 1636 | </div> |
1580 | 1637 | </fieldset> |
1581 | 1638 | |
| 1639 | + <?php database_switcher('oracle'); ?> |
| 1640 | + <div class="config-input"><?php aField( $conf, "DBprefix_ora", "Database table prefix:" ); ?></div> |
| 1641 | + <div class="config-desc"> |
| 1642 | + <p>If you need to share one database between multiple wikis, or |
| 1643 | + between MediaWiki and another web application, you may choose to |
| 1644 | + add a prefix to all the table names to avoid conflicts.</p> |
| 1645 | + |
| 1646 | + <p>Avoid exotic characters; something like <tt>mw_</tt> is good.</p> |
| 1647 | + </div> |
| 1648 | + <div class="config-input"><?php aField( $conf, "DBdefTS_ora", "Default tablespace:" ); ?></div> |
| 1649 | + <div class="config-input"><?php aField( $conf, "DBtempTS_ora", "Temporary tablespace:" ); ?></div> |
| 1650 | + </fieldset> |
| 1651 | + |
1582 | 1652 | <div class="config-input" style="padding:2em 0 3em"> |
1583 | 1653 | <label class='column'> </label> |
1584 | 1654 | <input type="submit" value="Install MediaWiki!" class="btn-install" /> |
— | — | @@ -1753,6 +1823,10 @@ |
1754 | 1824 | \$wgDBport_db2 = \"{$slconf['DBport_db2']}\"; |
1755 | 1825 | \$wgDBmwschema = \"{$slconf['DBmwschema']}\"; |
1756 | 1826 | \$wgDBcataloged = \"{$slconf['DBcataloged']}\";"; |
| 1827 | + } elseif( $conf->DBtype == 'oracle' ) { |
| 1828 | + $dbsettings = |
| 1829 | +"# Oracle specific settings |
| 1830 | +\$wgDBprefix = \"{$slconf['DBprefix']}\";"; |
1757 | 1831 | } else { |
1758 | 1832 | // ummm... :D |
1759 | 1833 | $dbsettings = ''; |
Index: trunk/phase3/RELEASE-NOTES |
— | — | @@ -38,7 +38,8 @@ |
39 | 39 | * (bug 10837) $wgVariant is a user variant selected in the user's preferences |
40 | 40 | if the $wgContLang does not have variant, then the $wgLang is used instead. |
41 | 41 | * Oracle: maintenance/ora/user.sql script for creating DB user on oracle with |
42 | | - appropriate privileges |
| 42 | + appropriate privileges. Creating this user with web-install page requires |
| 43 | + oci8.privileged_connect set to On in php.ini. |
43 | 44 | |
44 | 45 | === New features in 1.16 === |
45 | 46 | |