Index: config/index.php =================================================================== --- config/index.php (revision 43501) +++ config/index.php (working copy) @@ -79,6 +79,12 @@ $ourdb['mssql']['bgcolor'] = '#ffc0cb'; $ourdb['mssql']['rootuser'] = 'administrator'; +$ourdb['ibm_db2']['fullname'] = 'DB2'; +$ourdb['ibm_db2']['havedriver'] = 0; +$ourdb['ibm_db2']['compile'] = 'ibm_db2'; +$ourdb['ibm_db2']['bgcolor'] = '#ffeba1'; +$ourdb['ibm_db2']['rootuser'] = 'db2admin'; + ?> @@ -615,6 +621,11 @@ ## MSSQL specific // We need a second field so it doesn't overwrite the MySQL one $conf->DBprefix2 = importPost( "DBprefix2" ); + + ## DB2 specific: + $conf->DBport = importPost( "DBport", "" ); + $conf->DBmwschema = importPost( "DBmwschema", "mediawiki" ); + $conf->DBcataloged = importPost( "DBcataloged", "cataloged" ); $conf->ShellLocale = getShellLocale( $conf->LanguageCode ); @@ -781,6 +792,9 @@ $wgDBprefix = $conf->DBprefix2; } + ## DB2 specific: + $wgDBcataloged = $conf->DBcataloged; + $wgCommandLineMode = true; if (! defined ( 'STDERR' ) ) define( 'STDERR', fopen("php://stderr", "wb")); @@ -861,7 +875,7 @@ error_reporting( E_ALL ); $wgSuperUser = ''; ## Possible connect as a superuser - if( $useRoot && $conf->DBtype != 'sqlite' ) { + if( $useRoot && $conf->DBtype == 'postgres' ) { $wgDBsuperuser = $conf->RootUser; echo( "
  • Attempting to connect to database \"postgres\" as superuser \"$wgDBsuperuser\"..." ); $wgDatabase = $dbc->newFromParams($wgDBserver, $wgDBsuperuser, $conf->RootPW, "postgres", 1); @@ -1453,6 +1467,25 @@

    Avoid exotic characters; something like mw_ is good.

    + + +
    +
    +
    Select one:
    + +
    +

    If you need to share one database between multiple wikis, or + between MediaWiki and another web application, you may specify + a different schema to avoid conflicts.

    +
    +
    @@ -1623,6 +1656,12 @@ $dbsettings = "# MSSQL specific settings \$wgDBprefix = \"{$slconf['DBprefix2']}\";"; + } elseif( $conf->DBtype == 'ibm_db2' ) { + $dbsettings = +"# DB2 specific settings +\$wgDBport = \"{$slconf['DBport']}\"; +\$wgDBmwschema = \"{$slconf['DBmwschema']}\"; +\$wgDBcataloged = \"{$slconf['DBcataloged']}\";"; } else { // ummm... :D $dbsettings = ''; Index: includes/AutoLoader.php =================================================================== --- includes/AutoLoader.php (revision 43501) +++ includes/AutoLoader.php (working copy) @@ -319,6 +319,11 @@ 'PostgresField' => 'includes/db/DatabasePostgres.php', 'ResultWrapper' => 'includes/db/Database.php', 'SQLiteField' => 'includes/db/DatabaseSqlite.php', + + 'DatabaseIbm_db2' => 'includes/db/DatabaseIbm_db2.php', + 'IBM_DB2Field' => 'includes/db/DatabaseIbm_db2.php', + 'IBM_DB2SearchResultSet' => 'includes/SearchIBM_DB2.php', + 'SearchIBM_DB2' => 'includes/SearchIBM_DB2.php', # includes/diff 'AncestorComparator' => 'includes/diff/HTMLDiff.php', Index: includes/filerepo/LocalFile.php =================================================================== --- includes/filerepo/LocalFile.php (revision 43501) +++ includes/filerepo/LocalFile.php (working copy) @@ -249,8 +249,9 @@ $array = (array)$row; $prefixLength = strlen( $prefix ); // Sanity check prefix once - if ( substr( key( $array ), 0, $prefixLength ) !== $prefix ) { - throw new MWException( __METHOD__. ': incorrect $prefix parameter' ); + $subpre = substr( key( $array ), 0, $prefixLength ); + if ( $subpre !== $prefix ) { + throw new MWException( __METHOD__. ': incorrect $prefix parameter' . " $subpre != $prefix
    $array" ); } $decoded = array(); foreach ( $array as $name => $value ) { Index: includes/GlobalFunctions.php =================================================================== --- includes/GlobalFunctions.php (revision 43501) +++ includes/GlobalFunctions.php (working copy) @@ -1694,6 +1694,11 @@ define('TS_POSTGRES', 7); /** + * DB2 format time + */ +define('TS_DB2', 8); + +/** * @param mixed $outputtype A timestamp in one of the supported formats, the * function will autodetect which format is supplied * and act accordingly. @@ -1754,6 +1759,8 @@ return gmdate( 'd-M-y h.i.s A', $uts) . ' +00:00'; case TS_POSTGRES: return gmdate( 'Y-m-d H:i:s', $uts) . ' GMT'; + case TS_DB2: + return gmdate( 'Y-m-d H:i:s', $uts); default: throw new MWException( 'wfTimestamp() called with illegal output type.'); } Index: includes/specials/SpecialAncientpages.php =================================================================== --- includes/specials/SpecialAncientpages.php (revision 43501) +++ includes/specials/SpecialAncientpages.php (working copy) @@ -25,8 +25,18 @@ $db = wfGetDB( DB_SLAVE ); $page = $db->tableName( 'page' ); $revision = $db->tableName( 'revision' ); - $epoch = $wgDBtype == 'mysql' ? 'UNIX_TIMESTAMP(rev_timestamp)' : - 'EXTRACT(epoch FROM rev_timestamp)'; + // changed ternary to switch to allow for more database types + switch ($wgDBtype) { + case 'mysql': + $epoch = 'UNIX_TIMESTAMP(rev_timestamp)'; + break; + case 'ibm_db2': + // TODO implement proper conversion to a Unix epoch + $epoch = 'rev_timestamp'; + break; + default: + $epoch = 'EXTRACT(epoch FROM rev_timestamp)'; + } return "SELECT 'Ancientpages' as type, page_namespace as namespace, Index: includes/specials/SpecialNewimages.php =================================================================== --- includes/specials/SpecialNewimages.php (revision 43501) +++ includes/specials/SpecialNewimages.php (working copy) @@ -37,10 +37,12 @@ $image = $dbr->tableName( 'image' ); $sql = "SELECT img_timestamp from $image"; + // Get a database-agnostic limit clause + $limitsql = $dbr->limitResult('', 1); if ($hidebotsql) { $sql .= "$hidebotsql WHERE ug_group IS NULL"; } - $sql .= ' ORDER BY img_timestamp DESC LIMIT 1'; + $sql .= ' ORDER BY img_timestamp DESC' . $limitsql; $res = $dbr->query( $sql, __FUNCTION__ ); $row = $dbr->fetchRow( $res ); if( $row !== false ) { @@ -93,7 +95,8 @@ $sql .= ' WHERE ' . $dbr->makeList( $where, LIST_AND ); } $sql.=' ORDER BY img_timestamp '. ( $invertSort ? '' : ' DESC' ); - $sql.=' LIMIT ' . ( $limit + 1 ); + // Set the limit in a database-agnostic way + $sql.= $dbr->limitResult('', $limit + 1); $res = $dbr->query( $sql, __FUNCTION__ ); /** Index: includes/specials/SpecialRecentchanges.php =================================================================== --- includes/specials/SpecialRecentchanges.php (revision 43501) +++ includes/specials/SpecialRecentchanges.php (working copy) @@ -282,32 +282,55 @@ } wfRunHooks('SpecialRecentChangesQuery', array( &$conds, &$tables, &$join_conds, $opts ) ); + + /** + * SELECT * below was changed to a whitelist of fields + * + * Fields in SELECT * but not in list below: + * user_password + * user_newpassword + * user_options + * + * More fields could be trimmed for better performance + */ + $fields2 = array( + 'rc_id', 'rc_timestamp', 'rc_cur_time', 'rc_user', 'rc_user_text', 'rc_namespace', + 'rc_title', 'rc_comment', 'rc_minor', 'rc_bot', 'rc_new', 'rc_cur_id', 'rc_this_oldid', 'rc_last_oldid', + 'rc_type', 'rc_moved_to_ns', 'rc_moved_to_title', 'rc_patrolled', 'rc_ip', 'rc_old_len', 'rc_new_len', + 'rc_deleted', 'rc_logid', 'rc_log_type', 'rc_log_action', + 'rc_params', 'user_id', 'user_name', 'user_real_name', + 'user_newpass_time', 'user_token', 'user_email', 'user_email_token', 'user_email_token_expires', + 'user_email_authenticated', 'user_touched', 'user_registration', 'user_editcount', + 'wl_user', 'wl_namespace', 'wl_title', 'wl_notificationtimestamp'); + // Is there either one namespace selected or excluded? // Also, if this is "all" or main namespace, just use timestamp index. if( is_null($namespace) || $invert || $namespace == NS_MAIN ) { - $res = $dbr->select( $tables, '*', $conds, __METHOD__, + $res = $dbr->select( $tables, $fields2, $conds, __METHOD__, array( 'ORDER BY' => 'rc_timestamp DESC', 'LIMIT' => $limit, 'USE INDEX' => array('recentchanges' => 'rc_timestamp') ), $join_conds ); // We have a new_namespace_time index! UNION over new=(0,1) and sort result set! } else { // New pages - $sqlNew = $dbr->selectSQLText( $tables, '*', + $sqlNew = $dbr->selectSQLText( $tables, $fields2, array( 'rc_new' => 1 ) + $conds, __METHOD__, array( 'ORDER BY' => 'rc_timestamp DESC', 'LIMIT' => $limit, 'USE INDEX' => array('recentchanges' => 'new_name_timestamp') ), $join_conds ); // Old pages - $sqlOld = $dbr->selectSQLText( $tables, '*', + $sqlOld = $dbr->selectSQLText( $tables, $fields2, array( 'rc_new' => 0 ) + $conds, __METHOD__, array( 'ORDER BY' => 'rc_timestamp DESC', 'LIMIT' => $limit, 'USE INDEX' => array('recentchanges' => 'new_name_timestamp') ), $join_conds ); + // Get database-agnostic limit clause + $limitsql = $dbr->limitResult('', $limit); # Join the two fast queries, and sort the result set - $sql = "($sqlNew) UNION ($sqlOld) ORDER BY rc_timestamp DESC LIMIT $limit"; + $sql = "($sqlNew) UNION ($sqlOld) ORDER BY rc_timestamp DESC $limitsql"; $res = $dbr->query( $sql, __METHOD__ ); } Index: includes/specials/SpecialRecentchangeslinked.php =================================================================== --- includes/specials/SpecialRecentchangeslinked.php (revision 43501) +++ includes/specials/SpecialRecentchangeslinked.php (working copy) @@ -143,8 +143,10 @@ if( count($subsql) == 1 ) $sql = $subsql[0]; else { + // Get database-agnostic limit clause + $limitsql = $dbr->limitResult('', $limit); // need to resort and relimit after union - $sql = "(" . implode( ") UNION (", $subsql ) . ") ORDER BY rc_timestamp DESC LIMIT {$limit}"; + $sql = "(" . implode( ") UNION (", $subsql ) . ") ORDER BY rc_timestamp DESC {$limitsql}"; } $res = $dbr->query( $sql, __METHOD__ ); Index: includes/specials/SpecialWatchlist.php =================================================================== --- includes/specials/SpecialWatchlist.php (revision 43501) +++ includes/specials/SpecialWatchlist.php (working copy) @@ -168,7 +168,8 @@ # Toggle watchlist content (all recent edits or just the latest) if( $wgUser->getOption( 'extendwatchlist' )) { $andLatest=''; - $limitWatchlist = 'LIMIT ' . intval( $wgUser->getOption( 'wllimit' ) ); + // Make a database-agnostic limit clause + $limitsql = $dbr->limitResult('', intval( $wgUser->getOption( 'wllimit' ))); } else { # Top log Ids for a page are not stored $andLatest = 'AND (rc_this_oldid=page_latest OR rc_type=' . RC_LOG . ') '; Index: maintenance/convertLinks.inc =================================================================== --- maintenance/convertLinks.inc (revision 43501) +++ maintenance/convertLinks.inc (working copy) @@ -45,8 +45,10 @@ $dbw = wfGetDB( DB_MASTER ); list ($cur, $links, $links_temp, $links_backup) = $dbw->tableNamesN( 'cur', 'links', 'links_temp', 'links_backup' ); - - $res = $dbw->query( "SELECT l_from FROM $links LIMIT 1" ); + + // Get database-agnostic limit clause + $limit1 = $dbw->limitResult('', 1); + $res = $dbw->query( "SELECT l_from FROM $links $limit1" ); if ( $dbw->fieldType( $res, 0 ) == "int" ) { print "Schema already converted\n"; return; Index: maintenance/nextJobDB.php =================================================================== --- maintenance/nextJobDB.php (revision 43501) +++ maintenance/nextJobDB.php (working copy) @@ -34,14 +34,15 @@ # Padding row for MySQL bug $sql = "(SELECT '-------------------------------------------')"; + $limit1 = $dbConn->limitResult('', 1); foreach ( $dbs as $dbName ) { if ( $sql != '' ) { $sql .= ' UNION '; } if ($type === false) - $sql .= "(SELECT '$dbName' FROM `$dbName`.job LIMIT 1)"; + $sql .= "(SELECT '$dbName' FROM `$dbName`.job $limit1)"; else - $sql .= "(SELECT '$dbName' FROM `$dbName`.job WHERE job_cmd=$stype LIMIT 1)"; + $sql .= "(SELECT '$dbName' FROM `$dbName`.job WHERE job_cmd=$stype $limit1)"; } $res = $dbConn->query( $sql, 'nextJobDB.php' ); $row = $dbConn->fetchRow( $res ); // discard padding row Index: maintenance/storage/compressOld.inc =================================================================== --- maintenance/storage/compressOld.inc (revision 43501) +++ maintenance/storage/compressOld.inc (working copy) @@ -57,7 +57,8 @@ 'old_text' => $compress ), array( /* WHERE */ 'old_id' => $row->old_id - ), $fname, 'LIMIT 1' + ), $fname, + array( 'LIMIT' => 1 ) ); return true; }