? includes/BlockCache.php
? skins/common/images/logo_mono_3.png
? skins/common/images/postgresql_80x16_1.gif
? skins/common/images/redirect.png
Index: install-utils.inc
===================================================================
RCS file: /cvsroot/wikipedia/phase3/install-utils.inc,v
retrieving revision 1.21
diff -U5 -r1.21 install-utils.inc
--- install-utils.inc	10 Nov 2005 08:06:04 -0000	1.21
+++ install-utils.inc	4 Dec 2005 16:59:01 -0000
@@ -1,7 +1,9 @@
 <?php
 
+require_once( "includes/GlobalFunctions.php" );
+
 function install_version_checks() {
 	# We dare not turn output buffer _off_ since this will break completely
 	# if PHP is globally configured to run through a gzip filter.
 	@ob_implicit_flush( true );
 
@@ -11,24 +13,28 @@
 	}
 	if( version_compare( phpversion(), '4.3.2' ) < 0 ) {
 		die( "PHP 4.3.2 or higher is required. ABORTING.\n" );
 	}
 
-	if (!extension_loaded('mysql')) {
-		if (!dl('mysql.so')) {
-			print 'Could not load MySQL driver! Please compile '.
-				  "php --with-mysql or install the mysql.so module.\n";
-		exit;
-		}
-	}
-
 	global $wgCommandLineMode;
 	$wgCommandLineMode = true;
 	umask( 000 );
 	set_time_limit( 0 );
 }
 
+function check_extension_loaded($ext, $lib) {
+	if (!extension_loaded($ext)) {
+	        wfSuppressWarnings();
+		if (!dl($lib . '.' . PHP_SHLIB_SUFFIX)) {
+			wfRestoreWarnings();
+			return false;
+		}
+		wfRestoreWarnings();
+	}
+	return true;
+}
+
 function copyfile( $sdir, $name, $ddir, $perms = 0664 ) {
 	copyfileto( $sdir, $name, $ddir, $name, $perms );
 }
 
 function copyfileto( $sdir, $sname, $ddir, $dname, $perms = 0664 ) {
Index: config/index.php
===================================================================
RCS file: /cvsroot/wikipedia/phase3/config/index.php,v
retrieving revision 1.141
diff -U5 -r1.141 index.php
--- config/index.php	10 Nov 2005 08:06:04 -0000	1.141
+++ config/index.php	4 Dec 2005 16:59:02 -0000
@@ -84,10 +84,18 @@
 			font-weight: bold;
 			padding: 1em 1.5em;
 			margin: 2em 0 1em;
 		}
 
+		.warning {
+			color: orange;
+			background-color: #fff;
+			font-weight: bold;
+			left: 1em;
+			font-size: 100%;
+		}
+
 		ul.plain {
 			list-style-type: none;
 			list-style-image: none;
 			float: left;
 			margin: 0;
@@ -193,10 +201,36 @@
 $wgNoOutputBuffer = true;
 $conf = new ConfigData;
 
 install_version_checks();
 
+$availableDb = array();
+
+if (!check_extension_loaded('mysql', 'mysql')) {
+	print "<li><span class=\"warning\">Could not load MySQL driver!  If you want to use MediaWiki with a MySQL database please compile php --with-mysql or install the mysql.so module.</span></li>\n";
+} else {
+	$availableDb[] = 'mysql';
+}
+
+if (!check_extension_loaded('pgsql', 'pgsql')) {
+	print "<li><span class=\"warning\">Could not load PostgreSQL driver!  If you want to use MediaWiki with a PostgreSQL database please compile php --with-pgsql or install the pgsql.so module.</span></li>\n";
+} else {
+	$availableDb[] = 'pgsql';
+}
+
+if (!check_extension_loaded('oci8', 'php_oci8')) {
+	print "<li><span class=\"warning\">Could not load Oracle driver!  If you want to use MediaWiki with an Oracle database please see the <a href=\"http://us3.php.net/oci8\">Oracle driver page</a> for installation instructions.</span></li>\n";
+} else {
+	$availableDb[] = 'oracle';
+}
+
+if (count($availableDb) == 0)
+{
+	print("</ul>\n");
+	die("<span class=\"error\">No database drivers detected.  At least one database driver is required to install MediaWiki.</span>\n");
+}
+
 print "<li>PHP " . phpversion() . " installed</li>\n";
 
 if( ini_get( "register_globals" ) ) {
 	?>
 	<li>
@@ -469,16 +503,21 @@
 		/* Load up the settings and get installin' */
 		$local = writeLocalSettings( $conf );
 		$wgCommandLineMode = false;
 		chdir( ".." );
 		eval($local);
-		if (!in_array($conf->DBtype, array("mysql", "oracle"))) {
+		if (!in_array($conf->DBtype, array("mysql", "oracle", "pgsql"))) {
 			$errs["DBtype"] = "Unknown database type.";
 			continue;
 		}
 		print "<li>Database type: {$conf->DBtype}</li>\n";
 		$dbclass = 'Database'.ucfirst($conf->DBtype);
+		if( $conf->DBtype == "pgsql" )
+		{
+		    $dbclass = "DatabasePostgreSQL";
+		    $wgDBSchema = "";
+		}
 		require_once("$dbclass.php");
 		$wgDBtype = $conf->DBtype;
 		$wgDBadminuser = "root";
 		$wgDBadminpassword = $conf->RootPW;
 		$wgDBprefix = $conf->DBprefix;
@@ -488,19 +527,23 @@
 		chdir( "config" );
 
 		require_once( "maintenance/InitialiseMessages.inc" );
 
 		$wgTitle = Title::newFromText( "Installation script" );
-		$mysqlOldClient = version_compare( mysql_get_client_info(), "4.1.0", "lt" );
-		if( $mysqlOldClient ) {
+
+		if( $wgDBtype == "mysql" )
+		{
+		    $mysqlOldClient = version_compare( mysql_get_client_info(), "4.1.0", "lt" );
+		    if( $mysqlOldClient ) {
 			print "<li><b>PHP is linked with old MySQL client libraries. If you are
-				using a MySQL 4.1 server and have problems connecting to the database,
-				see <a href='http://dev.mysql.com/doc/mysql/en/old-client.html'
-			 	>http://dev.mysql.com/doc/mysql/en/old-client.html</a> for help.</b></li>\n";
+			using a MySQL 4.1 server and have problems connecting to the database,
+			see <a href='http://dev.mysql.com/doc/mysql/en/old-client.html'
+			>http://dev.mysql.com/doc/mysql/en/old-client.html</a> for help.</b></li>\n";
+		    }
 		}
-		$dbc = new $dbclass;
-		if ($conf->DBtype == 'mysql') {
+			$dbc = new $dbclass;
+			if ($conf->DBtype == 'mysql') {
 			print "<li>Trying to connect to database server on $wgDBserver as root...\n";
 			$wgDatabase = $dbc->newFromParams( $wgDBserver, "root", $conf->RootPW, "", 1 );
 
 			if( $wgDatabase->isOpen() ) {
 				$myver = get_db_version();
@@ -566,10 +609,14 @@
 		if ( !$wgDatabase->isOpen() ) {
 			$errs["DBserver"] = "Couldn't connect to database";
 			continue;
 		}
 
+
+		if( $wgDBtype == "mysql" )
+		{
+
 		print "<li>Connected to $myver";
 		if( version_compare( $myver, "4.0.0" ) < 0 ) {
 			die( " -- mysql 4.0 or later required. Aborting." );
 		}
 		$mysqlNewAuth   = version_compare( $myver, "4.1.0", "ge" );
@@ -586,10 +633,11 @@
 				print "; <b class='error'>MySQL 4.1/5.0 charset mode enabled,
 					but older version detected; will likely fail.</b>";
 			}
 		}
 		print "</li>\n";
+		}
 
 		if ($conf->DBtype == 'mysql') {
 			@$sel = mysql_select_db( $wgDBname, $wgDatabase->mConn );
 			if( $sel ) {
 				print "<li>Database <tt>" . htmlspecialchars( $wgDBname ) . "</tt> exists</li>\n";
@@ -611,10 +659,19 @@
 				print "<li>Created database <tt>" . htmlspecialchars( $wgDBname ) . "</tt></li>\n";
 			}
 			$wgDatabase->selectDB( $wgDBname );
 		}
 
+		if( $wgDBtype == "pgsql" ) {
+
+			// check for tsearch
+			if ($wgDatabase->tableExists("pg_ts_dict")) {
+				print("<li>tsearch2 extension appears to be installed.</li>");
+			} else {
+			    die("<li><span class=\"error\">The tsearch2 extension for PostgreSQL must be installed.  Please see <a href=\"test\">these installation instructions</a> on how to install the tsearch2 extension.</span>" );
+			}
+		}
 
 		if( $wgDatabase->tableExists( "cur" ) || $wgDatabase->tableExists( "revision" ) ) {
 			print "<li>There are already MediaWiki tables in this database. Checking if updates are needed...</li>\n";
 
 			# Create user if required
@@ -650,13 +707,16 @@
 				} else {
 					print " using MySQL 4 table defs...";
 					dbsource( "../maintenance/tables.sql", $wgDatabase );
 				}
 				dbsource( "../maintenance/interwiki.sql", $wgDatabase );
-			} else {
+			} else if ($conf->DBtype == "oracle") {
 				dbsource( "../maintenance/oracle/tables.sql", $wgDatabase );
 				dbsource( "../maintenance/oracle/interwiki.sql", $wgDatabase );
+			} else {
+				dbsource( "../maintenance/postgresql/tables.sql", $wgDatabase );
+				dbsource( "../maintenance/postgresql/interwiki.sql", $wgDatabase );
 			}
 
 			print " done.</li>\n";
 
 			print "<li>Initializing data...";
@@ -937,12 +997,33 @@
 
 <div class="config-section">
 <div class="config-input">
 		<label class='column'>Database type:</label>
 		<ul class='plain'>
-			<li><?php aField( $conf, "DBtype", "MySQL", "radio", "mysql"); ?></li>
-			<li><?php aField( $conf, "DBtype", "Oracle", "radio", "oracle" ); ?></li>
+		<?php
+
+		// make sure the default is OK
+		if (!in_array($conf->DBtype, $availableDb) &&
+		    count($availableDb) > 0) {
+			$conf->DBtype = $availableDb[0];
+		}
+	
+		if (in_array('mysql', $availableDb)) {
+			print '<li>';
+			aField( $conf, "DBtype", "MySQL", "radio", "mysql");
+			print '</li>';
+		}
+		if (in_array('oracle', $availableDb)) {
+			print '<li>';
+			aField( $conf, "DBtype", "Oracle", "radio", "oracle");
+			print '</li>';
+		}
+		if (in_array('pgsql', $availableDb)) {
+			print '<li>';
+			aField( $conf, "DBtype", "PostgreSQL", "radio", "pgsql");
+			print '</li>';
+		} ?>
 		</ul>
 	</div>
 
 	<div class="config-input" style="clear:left"><?php
 		aField( $conf, "DBserver", "SQL server host:" );
Index: includes/BagOStuff.php
===================================================================
RCS file: /cvsroot/wikipedia/phase3/includes/BagOStuff.php,v
retrieving revision 1.5
diff -U5 -r1.5 BagOStuff.php
--- includes/BagOStuff.php	20 Aug 2005 03:11:04 -0000	1.5
+++ includes/BagOStuff.php	4 Dec 2005 16:59:03 -0000
@@ -250,11 +250,11 @@
 			$exp = $this->_fromunixtime($exptime);
 		}
 		$this->delete( $key );
 		$this->_doinsert($this->getTableName(), array(
 					'keyname' => $key,
-					'value' => $this->_blobencode($this->_serialize($value)),
+					'value' => $this->_serialize($value),
 					'exptime' => $exp
 				));
 		return true; /* ? */
 	}
 
@@ -290,10 +290,13 @@
 		return str_replace( "'", "''", $str );
 	}
 	function _blobencode($str) {
 		return $str;
 	}
+	function _blobdecode($str) {
+		return $str;
+	}
 	function _doinsert($table, $vals) {
 		die( 'abstract function SqlBagOStuff::_doinsert() must be defined' );
 	}
 	function _doquery($sql) {
 		die( 'abstract function SqlBagOStuff::_doquery() must be defined' );
@@ -353,11 +356,11 @@
 	 * @return string
 	 */
 	function _serialize( &$data ) {
 		$serial = serialize( $data );
 		if( function_exists( 'gzdeflate' ) ) {
-			return gzdeflate( $serial );
+		    return $this->_blobencode(gzdeflate( $serial ));
 		} else {
 			return $serial;
 		}
 	}
 
@@ -365,12 +368,15 @@
 	 * Unserialize and, if necessary, decompress an object.
 	 * @param string $serial
 	 * @return mixed
 	 */
 	function _unserialize( $serial ) {
+
+		$serial = $this->_blobdecode($serial);
+
 		if( function_exists( 'gzinflate' ) ) {
-			$decomp = @gzinflate( $serial );
+		    $decomp = @gzinflate($serial );
 			if( false !== $decomp ) {
 				$serial = $decomp;
 			}
 		}
 		$ret = unserialize( $serial );
@@ -383,16 +389,21 @@
  * @package MediaWiki
  */
 class MediaWikiBagOStuff extends SqlBagOStuff {
 	var $tableInitialised = false;
 
+	function MediaWikiBagOStuff( ) {
+	    parent::SqlBagOStuff();
+	}
+
 	function _doquery($sql) {
 		$dbw =& wfGetDB( DB_MASTER );
 		return $dbw->query($sql, 'MediaWikiBagOStuff::_doquery');
 	}
 	function _doinsert($t, $v) {
 		$dbw =& wfGetDB( DB_MASTER );
+		//return $dbw->insert($t, $dbw->strencode($v), 'MediaWikiBagOStuff::_doinsert');
 		return $dbw->insert($t, $v, 'MediaWikiBagOStuff::_doinsert');
 	}
 	function _fetchobject($result) {
 		$dbw =& wfGetDB( DB_MASTER );
 		return $dbw->fetchObject($result);
@@ -415,10 +426,14 @@
 	}
 	function _strencode($s) {
 		$dbw =& wfGetDB( DB_MASTER );
 		return $dbw->strencode($s);
 	}
+	function _blobdecode($s) {
+		$dbw =& wfGetDB( DB_MASTER );
+		return $dbw->decodeBlob($s);
+	}
 	function _blobencode($s) {
 		$dbw =& wfGetDB( DB_MASTER );
 		return $dbw->encodeBlob($s);
 	}
 	function getTableName() {
Index: includes/Database.php
===================================================================
RCS file: /cvsroot/wikipedia/phase3/includes/Database.php,v
retrieving revision 1.137
diff -U5 -r1.137 Database.php
--- includes/Database.php	1 Dec 2005 07:00:11 -0000	1.137
+++ includes/Database.php	4 Dec 2005 16:59:04 -0000
@@ -91,10 +91,14 @@
 	 */
 	function debug( $debug = NULL ) {
 		return wfSetBit( $this->mFlags, DBO_DEBUG, $debug );
 	}
 
+	function dbtype( ) {
+	    return "mysql";
+	}
+
 	/**
 	 * Turns buffering of SQL result sets on (true) or off (false).
 	 * Default is "on" and it should not be changed without good reasons.
 	 */
 	function bufferResults( $buffer = NULL ) {
@@ -916,11 +920,11 @@
 			return NULL;
 		}
 
 		while ( $row = $this->fetchObject( $res ) ) {
 			if ( $row->Key_name == $index ) {
-				return $row;
+				return new IndexInfo($row);
 			}
 		}
 		return false;
 	}
 
@@ -992,10 +996,11 @@
 		if ( !count( $a ) ) {
 			return true;
 		}
 
 		$table = $this->tableName( $table );
+
 		if ( !is_array( $options ) ) {
 			$options = array( $options );
 		}
 		if ( isset( $a[0] ) && is_array( $a[0] ) ) {
 			$multi = true;
@@ -1673,10 +1678,15 @@
 		return "!= 0";
 	}
 	function isNullTimestamp() {
 		return "= '0'";
 	}
+
+	function unixTimestamp( $col ) {
+	    return "UNIX_TIMESTAMP (".$col.")";
+	}
+	
 }
 
 /**
  * Database abstraction object for mySQL
  * Inherit all methods and properties of Database::Database()
@@ -1685,11 +1695,31 @@
  * @see Database
  */
 class DatabaseMysql extends Database {
 	# Inherit all
 }
+/**
+ * Information container for info about an index, since the info seems to be
+ * reached very diferent on different database versions.
+ */
+class IndexInfo {
 
+    /**
+     * is true when the index is a unique index
+     */
+    var $unique;
+
+    // more fields should be added as theyre needed.
+
+    /**
+     * will be constructed from a "SHOW INDEX" row.
+     */
+    function IndexInfo( $row ) {
+	$this->unique  = !($row->Non_unique);
+    }
+
+}
 
 /**
  * Result wrapper for grabbing data queried by someone else
  *
  * @package MediaWiki
Index: includes/DatabaseOracle.php
===================================================================
RCS file: /cvsroot/wikipedia/phase3/includes/DatabaseOracle.php,v
retrieving revision 1.2
diff -U5 -r1.2 DatabaseOracle.php
--- includes/DatabaseOracle.php	2 Aug 2005 13:35:14 -0000	1.2
+++ includes/DatabaseOracle.php	4 Dec 2005 16:59:04 -0000
@@ -699,8 +699,12 @@
 	}
 
 	function encodeBlob($b) {
 		return new OracleBlob($b);
 	}
+
+	function unixTimestamp( $col ) {
+	    return "UNIX_TIMESTAMP (".$col.")";
+	}
 }
 
 ?>
Index: includes/DatabasePostgreSQL.php
===================================================================
RCS file: /cvsroot/wikipedia/phase3/includes/DatabasePostgreSQL.php,v
retrieving revision 1.41
diff -U5 -r1.41 DatabasePostgreSQL.php
--- includes/DatabasePostgreSQL.php	9 Aug 2005 10:30:20 -0000	1.41
+++ includes/DatabasePostgreSQL.php	4 Dec 2005 16:59:04 -0000
@@ -23,10 +23,13 @@
  * @package MediaWiki
  */
 class DatabasePgsql extends Database {
 	var $mInsertId = NULL;
 	var $mLastResult = NULL;
+	var $mSeq = NULL;
+
+	var $mEncoded = array();
 
 	function DatabasePgsql($server = false, $user = false, $password = false, $dbName = false, 
 		$failFunction = false, $flags = 0, $tablePrefix = 'get from global' )
 	{
 		Database::Database( $server, $user, $password, $dbName, $failFunction, $flags, $tablePrefix );
@@ -53,11 +56,14 @@
 		$this->close();
 		$this->mServer = $server;
 		$this->mUser = $user;
 		$this->mPassword = $password;
 		$this->mDBname = $dbName;
-		$this->mSchemas = array($wgDBschema,'public');
+		$this->mSchemas = array('public');
+		if ($wgDBschema) {
+			array_unshift($this->mSchemas ,$wgDBschema);
+		}
 		
 		$success = false;
 		
 		if ( '' != $dbName ) {
 			# start a database connection
@@ -135,14 +141,18 @@
 	}
 	function numFields( $res ) { return pg_num_fields( $res ); }
 	function fieldName( $res, $n ) { return pg_field_name( $res, $n ); }
 	
 	/**
-	 * This must be called after nextSequenceVal
+	 * This should return the id of the last accessed sequence. Since
+	 * postgresql does not support this directly, we have saved the
+	 * sequence name previously and now select the value
 	 */
 	function insertId() { 
-		return $this->mInsertId;
+		$value = $this->selectField(''," currval('" . $this->mSeq . "')");
+		return $value;
+//		return $this->mInsertId;
 	}
 
 	function dataSeek( $res, $row ) { return pg_result_seek( $res, $row ); }
 	function lastError() { return pg_last_error(); }
 	function lastErrno() { return 1; }
@@ -150,26 +160,27 @@
 	function affectedRows() { 
 		return pg_affected_rows( $this->mLastResult ); 
 	}
 	
 	/**
-	 * Returns information about an index
+	 * Returns information about an index as a IndexInfo.
 	 * If errors are explicitly ignored, returns NULL on failure
 	 */
 	function indexInfo( $table, $index, $fname = 'Database::indexExists' ) {
-		$sql = "SELECT indexname FROM pg_indexes WHERE tablename='$table'";
+		global $wgDBschema;
+		$sql = "SELECT indexname FROM pg_indexes WHERE tablename='$table' AND schemaname='$wgDBschema'
+		AND indexname = '$index'";
 		$res = $this->query( $sql, $fname );
 		if ( !$res ) {
 			return NULL;
 		}
 		
-		while ( $row = $this->fetchObject( $res ) ) {
-			if ( $row->Key_name == $index ) {
-				return $row;
-			}
-		}
-		return false;
+		$row = $this->fetchObject( $res );
+
+		if( !$row ) return NULL;
+
+		return new PgIndexInfo( $row );
 	}
 
 	function indexUnique ($table, $index, $fname = 'Database::indexUnique' ) {
 		$sql = "SELECT indexname FROM pg_indexes WHERE tablename='{$table}'".
 			" AND indexdef LIKE 'CREATE UNIQUE%({$index})'";
@@ -180,10 +191,32 @@
 			return true;
 		return false;
 		
 	}
 
+	/**
+	* Determines whether a field exists in a table
+	* Usually aborts on failure
+	* If errors are explicitly ignored, returns NULL on failure
+	*/
+	function fieldExists( $table, $field, $fname = 'Database::fieldExists' ) {
+
+	    global $wgDBschema;
+
+	    $table = $this->tableName( $table );
+	    $sql = "SELECT * from information_schema.columns where table_schema = '$wgDBschema' AND 
+	    table_name = '$table' and column_name = '$field'";
+
+	    $res = $this->query( $sql, DB_SLAVE, $fname );
+	    if ( !$res ) {
+		return NULL;
+	    }
+
+	    return true;
+	}
+
+
 	function fieldInfo( $table, $field ) {
 		wfDebugDieBacktrace( 'Database::fieldInfo() error : mysql_fetch_field() not implemented for postgre' );
 		/*
 		$res = $this->query( "SELECT * FROM '$table' LIMIT 1" );
 		$n = pg_num_fields( $res );
@@ -201,10 +234,11 @@
 	function insert( $table, $a, $fname = 'Database::insert', $options = array() ) {
 		# PostgreSQL doesn't support options
 		# We have a go at faking one of them
 		# TODO: DELAYED, LOW_PRIORITY 
 
+
 		if ( !is_array($options))
 			$options = array($options);
 
 		if ( in_array( 'IGNORE', $options ) ) 
 			$oldIgnore = $this->ignoreErrors( true );
@@ -235,11 +269,11 @@
 		exec( "php $IP/killthread.php $timeout $tid &>/dev/null &" );*/
 	}
 
 	function tableName( $name ) {
 		# First run any transformations from the parent object
-		$name = parent::tableName( $name );
+//		$name = parent::tableName( $name );
 
 		# Replace backticks into double quotes
 		$name = strtr($name,'`','"');
 
 		# Now quote PG reserved keywords
@@ -252,21 +286,126 @@
 			default:
 				return $name;
 		}
 	}
 
+	function decodeBlob( $s ) {
+
+	    if( is_array($s) )
+	    {
+		foreach($s as $str)
+		{
+		    $str = $this->decodeBlob($str);
+		}
+		return $s;
+	    }
+
+	    $ret = pg_unescape_bytea( $s );
+	    return $ret;
+
+	}
+
+	function encodeBlob( $s ) {
+
+
+	    if( is_array($s) )
+	    {
+		foreach($s as $str)
+		{
+		    $str = $this->encodeBlob($str);
+		}
+		return $s;
+	    }
+	    else
+	    {
+		if( isset($this->mEncoded[crc32($s)]) )
+		{
+		    wfDebug("BUG: double encoding to blob of string\n");
+		    return $s;
+		}
+	    }
+
+	    $ret = pg_escape_bytea( $s );
+
+	    $this->mEncoded[crc32($ret)] = 1;
+
+	    return $ret;
+
+	}
+
+	/**
+	 * If it's a string, adds quotes and backslashes
+	 * Otherwise returns as-is
+	 */
+	function addQuotes( $s ) {
+		if ( is_null( $s ) ) {
+			return 'DEFAULT';
+		} else {
+			# This will also quote numeric values. This should be harmless,
+			# and protects against weird problems that occur when they really
+			# _are_ strings such as article titles and string->number->string
+			# conversion is not 1:1.
+			return "'" . $this->strencode( $s ) . "'";
+		}
+	}
+
 	function strencode( $s ) {
-		return pg_escape_string( $s );
+	    // this below is a test, since sometime there is sent a array and
+	    // not a string...
+
+
+	    if( is_array($s) )
+	    {
+		foreach($s as $str)
+		{
+		    $str = $this->strencode($str);
+		}
+		return $s;
+	    }
+
+	    if( isset($this->mEncoded[crc32($s)]) )
+	    {
+		// the string was already encoded as something
+		wfDebug("BUG: Already encoded in strencde",true);
+		return $s;
+	    }
+
+	    $ret = pg_escape_string( $s );
+	    $this->mEncoded[crc32($ret)] = 1;
+
+	    return $ret;
+
+	}
+
+	function dbtype( ) {
+	    return "pgsql";
+	}
+
+	function isNullTimestamp( ) {
+	    return "= NULL";
 	}
 
+
 	/**
 	 * Return the next in a sequence, save the value for retrieval via insertId()
 	 */
 	function nextSequenceValue( $seqName ) {
+	    // Save for later use, since we have SERIAL datatype we return NULL
+	    // so the value is choosen automagically
+	    
+	    $this->mSeq = $seqName;
+	    return NULL;
+	    /*
+	    $ret = ' nextval('.$seqName.')';
+	    print("RET=$ret<br>");
+	    return $ret;
+	    */
+	    /*
 		$value = $this->selectField(''," nextval('" . $seqName . "')");
 		$this->mInsertId = $value;
 		return $value;
+		*/
 	}
 
 	/**
 	 * USE INDEX clause
 	 * PostgreSQL doesn't have them and returns ""
@@ -309,19 +448,25 @@
 						$sql .= ') OR (';
 					}
 					if ( is_array( $index ) ) {
 						$first2 = true;
 						foreach ( $index as $col ) {
+							if( $row[$col] != NULL )
+							{
 							if ( $first2 ) { 
 								$first2 = false;
 							} else {
 								$sql .= ' AND ';
 							}
-							$sql .= $col.'=' . $this->addQuotes( $row[$col] );
+							    $sql .= $col.'=' . $this->addQuotes( $row[$col] );
+							}
 						}
 					} else {
-						$sql .= $index.'=' . $this->addQuotes( $row[$index] );
+						if( $row[$index] != NULL )
+						{
+						    $sql .= $index.'=' . $this->addQuotes( $row[$index] );
+						}
 					}
 				}
 				$sql .= ')';
 				$this->query( $sql, $fname );
 			}
@@ -373,10 +518,18 @@
 	}
 
 	function limitResult($sql, $limit,$offset) {
         	return "$sql LIMIT $limit ".(is_numeric($offset)?" OFFSET {$offset} ":"");
 	}
+
+	/**
+	 * limiting for update is a questionable practice, so seem to think the
+	 * pg developers too and did not implement it. 
+	 */
+	function limitResultForUpdate($sql, $num) {
+		return $sql;
+	}
 	
 	/**
 	 * Returns an SQL expression for a simple conditional.
 	 * Uses CASE on PostgreSQL.
 	 *
@@ -394,11 +547,11 @@
 		return false;
 	}
 
 	# Return DB-style timestamp used for MySQL schema
 	function timestamp( $ts=0 ) {
-		return wfTimestamp(TS_DB,$ts);
+		return wfTimestamp(TS_POSTGRESQL,$ts);
 	}
 
         /**
          * Return aggregated value function call
          */
@@ -413,10 +566,19 @@
 			"Function: $fname\n" .
 			"Error: $errno $error\n";
 		wfDebugDieBacktrace($message);
 	}
 
+	function getLag() {
+	    return false;
+	}
+
+	function getStatus() {
+	    $result = array('Threads_running' => 0, 'Threads_connected' => 0);
+	    return $result;
+	}
+
 	/**
 	 * @return string wikitext of a link to the server software's web site
 	 */
 	function getSoftwareLink() {
 		return "[http://www.postgresql.org/ PostgreSQL]";
@@ -437,10 +599,36 @@
 		$schemas=$this->mSchemas;
 		if ($schema) { array_unshift($schemas,$schema); }
 		$searchpath=$this->makeList($schemas,LIST_NAMES);
 		$this->query("SET search_path = $searchpath");
 	}
+
+	function tableExists( $table ) {
+	    $table = $this->tableName($table, true);
+	    $res = $this->query( "SELECT COUNT(*) as NUM FROM pg_tables WHERE tablename='"
+	    . $table . "'" );
+	    if (!$res)
+	    return false;
+	    $row = $this->fetchObject($res);
+	    $this->freeResult($res);
+	    return $row->num >= 1;
+	}
+
+	function unixTimestamp( $col ) {
+	    return "EXTRACT ( EPOCH FROM ".$col.")";
+	}
+}
+
+class PgIndexInfo extends IndexInfo {
+    
+    /**
+     * creates the index information from a row of the indexInfo select
+     * statement.
+     */
+    function PgIndexInfo( $row ) {
+	$this->unique = preg_match("/CREATE UNIQUE INDEX/",$row->indexdef );
+    }
 }
 
 /**
  * Just an alias.
  * @package MediaWiki
Index: includes/GlobalFunctions.php
===================================================================
RCS file: /cvsroot/wikipedia/phase3/includes/GlobalFunctions.php,v
retrieving revision 1.234
diff -U5 -r1.234 GlobalFunctions.php
--- includes/GlobalFunctions.php	28 Nov 2005 14:50:56 -0000	1.234
+++ includes/GlobalFunctions.php	4 Dec 2005 16:59:12 -0000
@@ -1186,10 +1186,15 @@
  * Oracle format time.
  */
 define('TS_ORACLE', 6);
 
 /**
+ * PostgreSQL format time. ISO style (YYYY-MM-DD HH:MM:SS-TZ)
+ */
+define('TS_POSTGRESQL', 7);
+
+/**
  * @param mixed $outputtype A timestamp in one of the supported formats, the
  *                          function will autodetect which format is supplied
                             and act accordingly.
  * @return string Time in the format specified in $outputtype
  */
@@ -1214,17 +1219,21 @@
 		$uts=$ts;
 	} elseif (preg_match('/^(\d{1,2})-(...)-(\d\d(\d\d)?) (\d\d)\.(\d\d)\.(\d\d)/', $ts, $da)) {
 		# TS_ORACLE
 		$uts = strtotime(preg_replace('/(\d\d)\.(\d\d)\.(\d\d)(\.(\d+))?/', "$1:$2:$3",
 				str_replace("+00:00", "UTC", $ts)));
+        } elseif (preg_match("/^(\d{4})\-(\d\d)\-(\d\d) (\d\d):(\d\d):(\d\d)[\+\- ](\d\d)$/",$ts,$da)) {
+                # TS_POSTGRESQL
+                $uts=gmmktime((int)$da[4],(int)$da[5],(int)$da[6],
+                           (int)$da[2],(int)$da[3],(int)$da[1]);
 	} elseif (preg_match('/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})Z$/', $ts, $da)) {
 		# TS_ISO_8601
 		$uts=gmmktime((int)$da[4],(int)$da[5],(int)$da[6],
 			(int)$da[2],(int)$da[3],(int)$da[1]);
 	} else {
 		# Bogus value; fall back to the epoch...
-		wfDebug("wfTimestamp() fed bogus time value: $outputtype; $ts\n");
+		wfDebugDieBacktrace("wfTimestamp() fed bogus time value: $outputtype; $ts\n");
 		$uts = 0;
 	}
 
 
  	switch($outputtype) {
@@ -1241,10 +1250,13 @@
 			return gmdate(  'Y:m:d H:i:s', $uts );
 		case TS_RFC2822:
 			return gmdate( 'D, d M Y H:i:s', $uts ) . ' GMT';
 		case TS_ORACLE:
 			return gmdate( 'd-M-y h.i.s A', $uts) . ' +00:00';
+                case TS_POSTGRESQL:
+                        return gmdate( 'Y-m-d H:i:s', $uts );
+
 		default:
 			wfDebugDieBacktrace( 'wfTimestamp() called with illegal output type.');
 	}
 }
 
Index: includes/LinkCache.php
===================================================================
RCS file: /cvsroot/wikipedia/phase3/includes/LinkCache.php,v
retrieving revision 1.58
diff -U5 -r1.58 LinkCache.php
--- includes/LinkCache.php	22 Oct 2005 20:52:31 -0000	1.58
+++ includes/LinkCache.php	4 Dec 2005 16:59:13 -0000
@@ -213,10 +213,14 @@
 			}
 		} else {
 			$db =& wfGetDB( DB_SLAVE );
 			$options = '';
 		}
+		if( $db->dbtype() == "pgsql" )
+		{
+		    $options = '';
+		}
 
 		$page = $db->tableName( 'page' );
 		$pagelinks = $db->tableName( 'pagelinks' );
 
 		$sql = "SELECT page_id,pl_namespace,pl_title
Index: includes/LinksUpdate.php
===================================================================
RCS file: /cvsroot/wikipedia/phase3/includes/LinksUpdate.php,v
retrieving revision 1.50
diff -U5 -r1.50 LinksUpdate.php
--- includes/LinksUpdate.php	31 May 2005 09:08:19 -0000	1.50
+++ includes/LinksUpdate.php	4 Dec 2005 16:59:13 -0000
@@ -171,11 +171,13 @@
 					$key = $wgDBname . ':Category:' . md5( $nt->getDBkey() ) . ':adddeltimestamp';
 					$messageMemc->set( $key , wfTimestamp( TS_MW ), 24*3600 );
 					array_push( $arr, array(
 						'cl_from'    => $this->mId,
 						'cl_to'      => $cname,
-						'cl_sortkey' => $sortkey ) );
+						'cl_sortkey' => $sortkey,
+						'cl_timestamp' => $dbw->timestamp()
+					    ) );
 				}
 				// do the actual sql insertion
 				$dbw->insert( 'categorylinks', $arr, $fname, array( 'IGNORE' ) );
 			}
 		}
Index: includes/LoadBalancer.php
===================================================================
RCS file: /cvsroot/wikipedia/phase3/includes/LoadBalancer.php,v
retrieving revision 1.35
diff -U5 -r1.35 LoadBalancer.php
--- includes/LoadBalancer.php	29 Oct 2005 01:41:36 -0000	1.35
+++ includes/LoadBalancer.php	4 Dec 2005 16:59:13 -0000
@@ -431,10 +431,14 @@
 		}
 
 		extract( $server );
 		# Get class for this database type
 		$class = 'Database' . ucfirst( $type );
+		if( $type == "pgsql" )
+		{
+		    $class = "DatabasePostgreSQL";
+		}
 		if ( !class_exists( $class ) ) {
 			require_once( "$class.php" );
 		}
 
 		# Create object
Index: includes/Math.php
===================================================================
RCS file: /cvsroot/wikipedia/phase3/includes/Math.php,v
retrieving revision 1.25
diff -U5 -r1.25 Math.php
--- includes/Math.php	4 Nov 2005 02:33:50 -0000	1.25
+++ includes/Math.php	4 Dec 2005 16:59:14 -0000
@@ -63,11 +63,11 @@
 				# Invoke it within cygwin sh, because texvc expects sh features in its default shell
 				$cmd = 'sh -c ' . wfEscapeShellArg( $cmd );
 			} 
 
 			wfDebug( "TeX: $cmd\n" );
-			$contents = `$cmd`;
+			$contents = exec($cmd);
 			wfDebug( "TeX output:\n $contents\n---\n" );
 		
 			if (strlen($contents) == 0) {
 				return $this->_error( 'math_unknown_error' );
 			}
@@ -142,12 +142,12 @@
 				$md5_sql = pack('H32', $this->md5); # Binary packed, not hex
 				
 				$dbw =& wfGetDB( DB_MASTER );
 				$dbw->replace( 'math', array( 'math_inputhash' ),
 				  array( 
-					'math_inputhash' => $md5_sql, 
-					'math_outputhash' => $outmd5_sql,
+				      'math_inputhash' => $dbw->encodeBlob($md5_sql), 
+				      'math_outputhash' => $dbw->encodeBlob($outmd5_sql),
 					'math_html_conservativeness' => $this->conservativeness,
 					'math_html' => $this->html,
 					'math_mathml' => $this->mathml,
 				  ), $fname, array( 'IGNORE' ) 
 				);
@@ -172,11 +172,11 @@
 
 		$this->md5 = md5( $this->tex );
 		$dbr =& wfGetDB( DB_SLAVE );
 		$rpage = $dbr->selectRow( 'math', 
 			array( 'math_outputhash','math_html_conservativeness','math_html','math_mathml' ),
-			array( 'math_inputhash' => pack("H32", $this->md5)), # Binary packed, not hex
+			array( 'math_inputhash' => $dbr->encodeBlob(pack("H32", $this->md5))), # Binary packed, not hex
 			$fname
 		);
 
 		if( $rpage !== false ) {
 			# Tailing 0x20s can get dropped by the database, add it back on if necessary:
Index: includes/RecentChange.php
===================================================================
RCS file: /cvsroot/wikipedia/phase3/includes/RecentChange.php,v
retrieving revision 1.39
diff -U5 -r1.39 RecentChange.php
--- includes/RecentChange.php	4 Nov 2005 12:07:32 -0000	1.39
+++ includes/RecentChange.php	4 Dec 2005 16:59:22 -0000
@@ -118,11 +118,11 @@
 		}
 
 		# Fixup database timestamps
 		$this->mAttribs['rc_timestamp'] = $dbw->timestamp($this->mAttribs['rc_timestamp']);
 		$this->mAttribs['rc_cur_time'] = $dbw->timestamp($this->mAttribs['rc_cur_time']);
-		$this->mAttribs['rc_id'] = $dbw->nextSequenceValue( 'rc_rc_id_seq' );
+		$this->mAttribs['rc_id'] = $dbw->nextSequenceValue( 'recentchanges_rc_id_seq' );
 
 		# Insert new row
 		$dbw->insert( 'recentchanges', $this->mAttribs, $fname );
 
 		if ( $wgUseRCPatrol ) {
Index: includes/Revision.php
===================================================================
RCS file: /cvsroot/wikipedia/phase3/includes/Revision.php,v
retrieving revision 1.22
diff -U5 -r1.22 Revision.php
--- includes/Revision.php	30 Sep 2005 22:05:58 -0000	1.22
+++ includes/Revision.php	4 Dec 2005 16:59:22 -0000
@@ -523,11 +523,11 @@
 		$mungedText = $this->mText;
 		$flags = Revision::compressRevisionText( $mungedText );
 
 		# Record the text to the text table
 		if( !isset( $this->mTextId ) ) {
-			$old_id = $dbw->nextSequenceValue( 'text_old_id_val' );
+			$old_id = $dbw->nextSequenceValue( 'text_old_id_seq' );
 			$dbw->insert( 'text',
 				array(
 					'old_id'    => $old_id,
 					'old_text'  => $mungedText,
 					'old_flags' => $flags,
@@ -537,11 +537,11 @@
 		}
 
 		# Record the edit in revisions
 		$rev_id = isset( $this->mId )
 			? $this->mId
-			: $dbw->nextSequenceValue( 'rev_rev_id_val' );
+			: $dbw->nextSequenceValue( 'revision_rev_id_seq' );
 		$dbw->insert( 'revision',
 			array(
 				'rev_id'         => $rev_id,
 				'rev_page'       => $this->mPage,
 				'rev_text_id'    => $this->mTextId,
Index: includes/SearchEngine.php
===================================================================
RCS file: /cvsroot/wikipedia/phase3/includes/SearchEngine.php,v
retrieving revision 1.88
diff -U5 -r1.88 SearchEngine.php
--- includes/SearchEngine.php	10 Nov 2005 07:46:56 -0000	1.88
+++ includes/SearchEngine.php	4 Dec 2005 16:59:22 -0000
@@ -194,11 +194,11 @@
 		if( $wgSearchType ) {
 			$class = $wgSearchType;
 		} elseif( $wgDBtype == 'mysql' ) {
 			$class = 'SearchMySQL4';
 			require_once( 'SearchMySQL4.php' );
-		} else if ( $wgDBtype == 'PostgreSQL' ) {
+		} else if ( $wgDBtype == 'pgsql' ) {
 			$class = 'SearchTsearch2';
 			require_once( 'SearchTsearch2.php' );
 		} else {
 			$class = 'SearchEngineDummy';
 		}
@@ -338,10 +338,11 @@
 		return null;
 	}
 	function setLimitOffset($l, $o) {}
 	function legalSearchChars() {}
 	function update() {}
+	function updateTitle() {}
 	function setnamespaces() {}
 	function searchtitle() {}
 	function searchtext() {}
 }
 
Index: includes/SearchTsearch2.php
===================================================================
RCS file: /cvsroot/wikipedia/phase3/includes/SearchTsearch2.php,v
retrieving revision 1.4
diff -U5 -r1.4 SearchTsearch2.php
--- includes/SearchTsearch2.php	27 Jan 2005 19:50:34 -0000	1.4
+++ includes/SearchTsearch2.php	4 Dec 2005 16:59:22 -0000
@@ -34,19 +34,22 @@
 class SearchTsearch2 extends SearchEngine {
 	var $strictMatching = false;
 	
 	function SearchTsearch2( &$db ) {
 		$this->db =& $db;
-		$this->db->setSchema('tsearch');
+//		$this->db->setSchema('tsearch');
 		$this->mRanking = true;
 	}
 	
 	function getIndexField( $fulltext ) {
+	    // looks like this is never called
+	    wfDieDebugBacktrace("getIndexField($fulltext) called");
 		return $fulltext ? 'si_text' : 'si_title';
 	}
 
 	function parseQuery( $filteredText, $fulltext ) {
+	    wfDieDebugBacktrace("parseQuery($filteredText, $fulltext) called");
 		global $wgContLang;
 		$lc = SearchEngine::legalSearchChars();
 		$searchon = '';
 		$this->searchTerms = array();
 
@@ -87,10 +90,11 @@
 			return "";
 	}
 		
 
 	function queryMain( $filteredTerm, $fulltext ) {
+	    wfDieDebugBacktrace("queryMain($filteredTerm, $fulltext )");
 		$match = $this->parseQuery( $filteredTerm, $fulltext );
 		$field = $this->getIndexField( $fulltext );
 		$cur = $this->db->tableName( 'cur' );
 		$searchindex = $this->db->tableName( 'searchindex' );
 		return 'SELECT cur_id, cur_namespace, cur_title, cur_text ' .
@@ -114,14 +118,77 @@
 
         function updateTitle($id,$title) {
                 $dbw=& wfGetDB(DB_MASTER);
                 $searchindex = $dbw->tableName( 'searchindex' );
                 $sql = "UPDATE $searchindex SET si_title=to_tsvector('" .
-                          $db->strencode( $title ) .
+                          $dbw->strencode( $title ) .
                           "') WHERE si_page={$id}";
 
                 $dbw->query( $sql, "SearchMySQL4::updateTitle" );
         }
 
+	function searchText( $st )
+	{
+
+	    // setup the terms for search. spaces mean | for standard search so
+	    // we do that too. myslq supports AND and OR keywords, replace them too
+	    $st = preg_replace( "/ [Aa][Nn][Dd] /","&", $st );
+	    $st = preg_replace( "/ [Oo][Rr] /","|", $st );
+	    $st = preg_replace( "/ /", "|", $st );
+	    $dbw=& wfGetDB(DB_MASTER);
+	    $search = $dbw->addQuotes($st);
+	    $sql = "SELECT si_page,page.page_title,page.page_namespace,headline(old_text,q,'StartSel=\"\", StopSel=\"\"'),rank(si_text,q) FROM text,searchindex,revision,page, to_tsquery(".$search.") AS q WHERE page.page_id = si_page AND revision.rev_id = page.page_latest AND text.old_id = revision.rev_text_id AND  si_text @@ q ORDER BY -rank(si_text,q);";
+	    $res = $dbw->query( $sql );
+
+	    // We save the query as array exploded by & which is used by pg to
+	    // specify AND
+	    $st = explode("&",$st);
+	    return new PGSearchResultSet($res,$st);
+	}
+
+}
+
+class PGSearchResultSet extends SearchResultSet {
+
+    function PGSearchResultSet( $rs , $st ) {
+	$this->mResultSet = $rs;
+	$this->mTerms = $st;
+    }
+
+    function termMatches() {
+	return $this->mTerms;
+    }
+
+    function numRows() {
+	$dbw=& wfGetDB(DB_MASTER);
+	return $dbw->numRows($this->mResultSet);
+    }
+
+    function next() {
+	$dbw=& wfGetDB(DB_MASTER);
+	$row = $dbw->fetchObject($this->mResultSet);
+	if( $row == null ) {
+	    return false;
+	} else {
+	    return new PGSearchResult( $row );
+	}
+    }
+}
+
+class PGSearchResult extends SearchResult
+{
+    function PGSearchResult( $row ) {
+	$this->mRow = $row;
+	$this->mTitle = Title::makeTitle( $row->page_namespace, $row->page_title );
+    }
+
+    function getText() {
+	return $this->mRow->headline;
+    }
+
+    function getScore() {
+	return $this->mRow->rank;
+    }
+
 }
 
 ?>
Index: includes/Skin.php
===================================================================
RCS file: /cvsroot/wikipedia/phase3/includes/Skin.php,v
retrieving revision 1.395
diff -U5 -r1.395 Skin.php
--- includes/Skin.php	1 Dec 2005 19:09:45 -0000	1.395
+++ includes/Skin.php	4 Dec 2005 16:59:25 -0000
@@ -879,13 +879,22 @@
 		return $out;
 	}
 
 	function getPoweredBy() {
 		global $wgStylePath;
-		$url = htmlspecialchars( "$wgStylePath/common/images/poweredby_mediawiki_88x31.png" );
-		$img = '<a href="http://www.mediawiki.org/"><img src="'.$url.'" alt="MediaWiki" /></a>';
-		return $img;
+
+		$url1 = htmlspecialchars( "$wgStylePath/common/images/poweredby_mediawiki_88x31.png" );
+		$img1 = '<a href="http://www.mediawiki.org/"><img src="'.$url1.'" alt="MediaWiki" /></a>';
+		global $wgDBtype;
+		if( $wgDBtype != 'pgsql' )
+		{
+		    return $img1;
+		}
+		$url2 = htmlspecialchars( "$wgStylePath/common/images/postgresql_80x16_1.gif" );
+		$img2 = '<a href="http://www.postgresql.org/"><img src="'.$url2.'" alt="PostgreSQL" /></a>';
+		$ret = "<table><tr><td>".$img1."</td></tr> <tr><td>".$img2."</td></tr></table>";
+		return $ret;
 	}
 
 	function lastModified() {
 		global $wgLang, $wgArticle, $wgLoadBalancer;
 
Index: includes/SkinTemplate.php
===================================================================
RCS file: /cvsroot/wikipedia/phase3/includes/SkinTemplate.php,v
retrieving revision 1.100
diff -U5 -r1.100 SkinTemplate.php
--- includes/SkinTemplate.php	1 Dec 2005 09:47:44 -0000	1.100
+++ includes/SkinTemplate.php	4 Dec 2005 16:59:25 -0000
@@ -148,10 +148,11 @@
 		global $wgMimeType, $wgJsMimeType, $wgOutputEncoding, $wgUseDatabaseMessages, $wgRequest;
 		global $wgDisableCounters, $wgLogo, $action, $wgFeedClasses, $wgHideInterlanguageLinks;
 		global $wgMaxCredits, $wgShowCreditsIfMax;
 		global $wgPageShowWatchingUsers;
 		global $wgUseTrackbacks;
+		global $wgGlobalCSS;
 
 		$fname = 'SkinTemplate::outputPage';
 		wfProfileIn( $fname );
 
 		extract( $wgRequest->getValues( 'oldid', 'diff' ) );
@@ -185,10 +186,16 @@
 			# This won't be used in the standard skins, but we define it to preserve the interface
 			# To save time, we check for existence
 			$this->userpageUrlDetails = $this->makeKnownUrlDetails($this->userpage);
 		}
 
+
+		if($wgGlobalCSS) {
+		    $tpl->set('globalcss','<link rel="stylesheet" href="'.
+		    $wgGlobalCSS.'" type="text/css" />');
+		}
+
 		$this->usercss =  $this->userjs = $this->userjsprev = false;
 		$this->setupUserCss();
 		$this->setupUserJs();
 		$this->titletxt = $this->mTitle->getPrefixedText();
 		wfProfileOut( "$fname-stuff" );
@@ -226,10 +233,11 @@
 			$tpl->set( 'feeds', false );
 		}
 		if ($wgUseTrackbacks && $out->isArticleRelated())
 			$tpl->set( 'trackbackhtml', $wgTitle->trackbackRDF());
 
+
 		$tpl->setRef( 'mimetype', $wgMimeType );
 		$tpl->setRef( 'jsmimetype', $wgJsMimeType );
 		$tpl->setRef( 'charset', $wgOutputEncoding );
 		$tpl->set( 'headlinks', $out->getHeadLinks() );
 		$tpl->set('headscripts', $out->getScript() );
@@ -958,10 +966,11 @@
 		# If we use any dynamic CSS, make a little CDATA block out of it.
 
 		if ( !empty($sitecss) || !empty($usercss) ) {
 			$this->usercss = "/*<![CDATA[*/\n" . $sitecss . $usercss . '/*]]>*/';
 		}
+
 		wfProfileOut( $fname );
 	}
 
 	/**
 	 * @access private
Index: includes/SpecialAncientpages.php
===================================================================
RCS file: /cvsroot/wikipedia/phase3/includes/SpecialAncientpages.php,v
retrieving revision 1.25
diff -U5 -r1.25 SpecialAncientpages.php
--- includes/SpecialAncientpages.php	13 Sep 2005 17:02:43 -0000	1.25
+++ includes/SpecialAncientpages.php	4 Dec 2005 16:59:25 -0000
@@ -33,12 +33,12 @@
 		$revision = $db->tableName( 'revision' );
 		#$use_index = $db->useIndexClause( 'cur_timestamp' ); # FIXME! this is gone
 		return
 			"SELECT 'Ancientpages' as type,
 					page_namespace as namespace,
-			        page_title as title,
-			        UNIX_TIMESTAMP(rev_timestamp) as value
+			        page_title as title,".
+				$db->unixTimestamp("rev_timestamp")." as value
 			FROM $page, $revision
 			WHERE page_namespace=".NS_MAIN." AND page_is_redirect=0
 			  AND page_latest=rev_id";
 	}
 	
Index: includes/SpecialBrokenRedirects.php
===================================================================
RCS file: /cvsroot/wikipedia/phase3/includes/SpecialBrokenRedirects.php,v
retrieving revision 1.18
diff -U5 -r1.18 SpecialBrokenRedirects.php
--- includes/SpecialBrokenRedirects.php	26 Oct 2005 21:29:34 -0000	1.18
+++ includes/SpecialBrokenRedirects.php	4 Dec 2005 16:59:25 -0000
@@ -40,11 +40,10 @@
 		                pl_title
 		           FROM ($pagelinks, $page AS p1)
 		      LEFT JOIN $page AS p2
 		             ON pl_namespace=p2.page_namespace AND pl_title=p2.page_title
 		          WHERE p1.page_is_redirect=1
-		            AND pl_from=p1.page_id
 		            AND p2.page_namespace IS NULL";
 		return $sql;
 	}
 
 	function getOrder() {
Index: includes/SpecialContributions.php
===================================================================
RCS file: /cvsroot/wikipedia/phase3/includes/SpecialContributions.php,v
retrieving revision 1.112
diff -U5 -r1.112 SpecialContributions.php
--- includes/SpecialContributions.php	27 Nov 2005 16:36:06 -0000	1.112
+++ includes/SpecialContributions.php	4 Dec 2005 16:59:25 -0000
@@ -172,13 +172,14 @@
 	}
 	$nt =& Title::makeTitle(NS_USER, $nt->getDBkey());
 
 	list( $limit, $offset) = wfCheckLimits();
 	$offset = $wgRequest->getVal('offset');
-	/* Offset must be an integral. */
-	if (!strlen($offset) || !preg_match('/^[0-9]+$/', $offset))
-		$offset = 0;
+
+	$dbr =& wfGetDB(DB_SLAVE);
+	/* Offset must be an valid timestamp type. */
+	$offset = $dbr->timestamp(wfTimestamp(TS_UNIX,$offset));
 
 	$title = Title::makeTitle(NS_SPECIAL, 'Contributions');
 	$urlbits = 'target=' . wfUrlEncode($target);
 	$myurl = $title->escapeLocalURL($urlbits);
 
Index: includes/SpecialListusers.php
===================================================================
RCS file: /cvsroot/wikipedia/phase3/includes/SpecialListusers.php,v
retrieving revision 1.39
diff -U5 -r1.39 SpecialListusers.php
--- includes/SpecialListusers.php	29 Oct 2005 03:03:10 -0000	1.39
+++ includes/SpecialListusers.php	4 Dec 2005 16:59:25 -0000
@@ -135,11 +135,11 @@
 		$sql = "SELECT 'Listusers' as type, $userspace AS namespace, user_name AS title, " .
 			"user_name as value, user_id, COUNT(ug_group) as numgroups " .
 			"FROM $user ".
 			"LEFT JOIN $user_groups ON user_id=ug_user " .
 			$this->userQueryWhere( $dbr ) .
-			" GROUP BY user_name";
+			" GROUP BY user_name,user_id";
 		
 		return $sql;
 	}
 	
 	function userQueryWhere( &$dbr ) {
Index: includes/SpecialMostcategories.php
===================================================================
RCS file: /cvsroot/wikipedia/phase3/includes/SpecialMostcategories.php,v
retrieving revision 1.1
diff -U5 -r1.1 SpecialMostcategories.php
--- includes/SpecialMostcategories.php	8 Oct 2005 21:20:19 -0000	1.1
+++ includes/SpecialMostcategories.php	4 Dec 2005 16:59:25 -0000
@@ -32,11 +32,11 @@
 				page_title as title,
 				COUNT(*) as value
 			FROM $categorylinks
 			LEFT JOIN $page ON cl_from = page_id
 			WHERE page_namespace = " . NS_MAIN . "
-			GROUP BY cl_from
+			GROUP BY cl_from, page_namespace, page_title
 			HAVING COUNT(*) > 1
 			";
 	}
 
 	function formatResult( $skin, $result ) {
Index: includes/SpecialMostlinked.php
===================================================================
RCS file: /cvsroot/wikipedia/phase3/includes/SpecialMostlinked.php,v
retrieving revision 1.4
diff -U5 -r1.4 SpecialMostlinked.php
--- includes/SpecialMostlinked.php	27 Sep 2005 19:50:50 -0000	1.4
+++ includes/SpecialMostlinked.php	4 Dec 2005 16:59:25 -0000
@@ -36,11 +36,11 @@
 				COUNT(*) AS value,
 				
 				page_namespace
 			FROM $pagelinks
 			LEFT JOIN $page ON pl_namespace=page_namespace AND pl_title=page_title
-			GROUP BY pl_namespace,pl_title
+			GROUP BY pl_namespace,pl_title,page_namespace
 			HAVING COUNT(*) > 1";
 	}
 
 	function formatResult( $skin, $result ) {
 		global $wgContLang;
Index: includes/SpecialMostrevisions.php
===================================================================
RCS file: /cvsroot/wikipedia/phase3/includes/SpecialMostrevisions.php,v
retrieving revision 1.2
diff -U5 -r1.2 SpecialMostrevisions.php
--- includes/SpecialMostrevisions.php	13 Oct 2005 23:45:46 -0000	1.2
+++ includes/SpecialMostrevisions.php	4 Dec 2005 16:59:25 -0000
@@ -34,11 +34,11 @@
 				page_title as title,
 				COUNT(*) as value
 			FROM $revision
 			LEFT JOIN $page ON page_id = rev_page
 			WHERE page_namespace = " . NS_MAIN . "
-			GROUP BY rev_page
+			GROUP BY rev_page, page_namespace, page_title
 			HAVING COUNT(*) > 1
 			";
 	}
 
 	function formatResult( $skin, $result ) {
Index: includes/SpecialRecentchangeslinked.php
===================================================================
RCS file: /cvsroot/wikipedia/phase3/includes/SpecialRecentchangeslinked.php,v
retrieving revision 1.49
diff -U5 -r1.49 SpecialRecentchangeslinked.php
--- includes/SpecialRecentchangeslinked.php	27 Nov 2005 09:53:13 -0000	1.49
+++ includes/SpecialRecentchangeslinked.php	4 Dec 2005 16:59:25 -0000
@@ -87,11 +87,12 @@
              {$cmq}
              AND cl_from=rc_cur_id
              AND cl_to=$catkey
         GROUP BY rc_cur_id,rc_namespace,rc_title,
                  rc_user,rc_comment,rc_user_text,rc_timestamp,rc_minor,
-                 rc_new
+                 rc_new,rc_id,rc_this_oldid,rc_last_oldid,rc_patrolled,
+		 rc_type
         ORDER BY rc_timestamp DESC
            LIMIT {$limit};
  ";
 	} else {
 		$sql =
@@ -116,11 +117,12 @@
      AND pl_namespace=rc_namespace
      AND pl_title=rc_title
      AND pl_from=$id
 GROUP BY rc_cur_id,rc_namespace,rc_title,
          rc_user,rc_comment,rc_user_text,rc_timestamp,rc_minor,
-         rc_new
+         rc_new,rc_id,rc_this_oldid,rc_last_oldid,rc_patrolled,
+	 rc_type
 ORDER BY rc_timestamp DESC
    LIMIT {$limit}";
 	}
 	$res = $dbr->query( $sql, $fname );
 
Index: includes/SpecialSearch.php
===================================================================
RCS file: /cvsroot/wikipedia/phase3/includes/SpecialSearch.php,v
retrieving revision 1.28
diff -U5 -r1.28 SpecialSearch.php
--- includes/SpecialSearch.php	22 Oct 2005 21:33:53 -0000	1.28
+++ includes/SpecialSearch.php	4 Dec 2005 16:59:25 -0000
@@ -289,11 +289,15 @@
 		$fname = 'SpecialSearch::showMatches';
 		wfProfileIn( $fname );
 		
 		global $wgContLang;
 		$tm = $wgContLang->convertForSearchResult( $matches->termMatches() );
-		$terms = implode( '|', $tm );
+		if( is_array($tm) ) {
+		    $terms = implode( '|', $tm );
+		} else {
+		    $terms = $tm;
+		}
 		
 		global $wgOut;
 		$off = $this->offset + 1;
 		$out = "<ol start='{$off}'>\n";
 
@@ -364,18 +368,28 @@
 
 			$found = $m[2];
 
 			$line = htmlspecialchars( $pre . $found . $post );
 			$pat2 = '/(' . $terms . ")/i";
+
 			$line = preg_replace( $pat2,
 			  "<span class='searchmatch'>\\1</span>", $line );
 
+			$prel = $lineno - 1;  
+			$extract .= "<br /><small>{$prel}: ".$lines[$prel-1]."</small>\n";
 			$extract .= "<br /><small>{$lineno}: {$line}</small>\n";
+			$nel = $lineno+1;
+			$extract .= "<br /><small>{$nel}: ".$lines[$nel-1]."</small>\n";
 		}
 		wfProfileOut( "$fname-extract" );
 		wfProfileOut( $fname );
-		return "<li>{$link} ({$size}){$extract}</li>\n";
+
+		$rv = wfMsg( 'relevance');
+
+		$score = sprintf("%.2f",$result->getScore() * 100.0);
+		$relevance = "<span class='searchrelevance'>[$rv: $score %]</span>\n";
+		return "<li>{$link} ({$size})$relevance {$extract}</li>\n";
 	}
 	
 	function powerSearchBox( $term ) {
 		$namespaces = '';
 		foreach( SearchEngine::searchableNamespaces() as $ns => $name ) {
Index: includes/SpecialShortpages.php
===================================================================
RCS file: /cvsroot/wikipedia/phase3/includes/SpecialShortpages.php,v
retrieving revision 1.26
diff -U5 -r1.26 SpecialShortpages.php
--- includes/SpecialShortpages.php	12 Nov 2005 23:00:02 -0000	1.26
+++ includes/SpecialShortpages.php	4 Dec 2005 16:59:25 -0000
@@ -41,12 +41,12 @@
 		return
 			"SELECT $name as type,
 				page_namespace as namespace,
 			        page_title as title,
 			        page_len AS value
-			FROM $page FORCE INDEX (page_len)
-			WHERE page_namespace=".NS_MAIN." AND page_is_redirect=0";
+				FROM $page ".$dbr->useIndexClause("page_len").
+			"WHERE page_namespace=".NS_MAIN." AND page_is_redirect=0";
 	}
 	
 	function sortDescending() {
 		return false;
 	}
Index: includes/SpecialWantedpages.php
===================================================================
RCS file: /cvsroot/wikipedia/phase3/includes/SpecialWantedpages.php,v
retrieving revision 1.24
diff -U5 -r1.24 SpecialWantedpages.php
--- includes/SpecialWantedpages.php	29 Oct 2005 03:01:45 -0000	1.24
+++ includes/SpecialWantedpages.php	4 Dec 2005 16:59:26 -0000
@@ -41,11 +41,11 @@
 			        pl_namespace AS namespace,
 			        pl_title AS title,
 			        COUNT(*) AS value
 			 FROM $pagelinks
 			 LEFT JOIN $page
-			 ON pl_namespace=page_namespace AND pl_title=page_title
+			 ON (pl_namespace=page_namespace AND pl_title=page_title)
 			 WHERE page_namespace IS NULL
 			 GROUP BY pl_namespace,pl_title
 			 HAVING COUNT(*) > 1";
 	}
 
Index: includes/SpecialWatchlist.php
===================================================================
RCS file: /cvsroot/wikipedia/phase3/includes/SpecialWatchlist.php,v
retrieving revision 1.70
diff -U5 -r1.70 SpecialWatchlist.php
--- includes/SpecialWatchlist.php	15 Sep 2005 00:40:51 -0000	1.70
+++ includes/SpecialWatchlist.php	4 Dec 2005 16:59:26 -0000
@@ -235,17 +235,17 @@
 			'" /><input type="hidden" name="reset" value="all" /></form>' .
 			"\n\n" );
 	}
 
         $sql = "SELECT
-          rc_namespace page_namespace,rc_title page_title,
-          rc_comment rev_comment, rc_cur_id page_id,
-          rc_user rev_user,rc_user_text rev_user_text,
-          rc_timestamp rev_timestamp,rc_minor rev_minor_edit,
-          rc_this_oldid rev_id,
+          rc_namespace AS page_namespace,rc_title AS page_title,
+          rc_comment AS rev_comment, rc_cur_id AS page_id,
+          rc_user AS rev_user,rc_user_text AS rev_user_text,
+          rc_timestamp AS rev_timestamp,rc_minor AS rev_minor_edit,
+          rc_this_oldid AS rev_id,
           rc_last_oldid,
-          rc_new page_is_new,wl_notificationtimestamp
+          rc_new AS page_is_new,wl_notificationtimestamp
           FROM $watchlist,$recentchanges,$page
           WHERE wl_user=$uid
           AND wl_namespace=rc_namespace
           AND wl_title=rc_title
           AND rc_timestamp > '$cutoff'
Index: includes/SpecialWhatlinkshere.php
===================================================================
RCS file: /cvsroot/wikipedia/phase3/includes/SpecialWhatlinkshere.php,v
retrieving revision 1.25
diff -U5 -r1.25 SpecialWhatlinkshere.php
--- includes/SpecialWhatlinkshere.php	29 Jun 2005 00:59:38 -0000	1.25
+++ includes/SpecialWhatlinkshere.php	4 Dec 2005 16:59:26 -0000
@@ -54,19 +54,27 @@
 	$queryLimit = $limit + 1; 
 	$limitSql = ( $level == 0 )
 		? "$offset,$queryLimit"
 		: $queryLimit;
 
+	$sql = "SELECT page_id, page_namespace, page_title, page_is_redirect
+	FROM  pagelinks, page
+	WHERE (pl_from=page_id)
+	AND pl_namespace = ".$dbr->addQuotes($target->getNamespace())."
+	AND pl_title = ".$dbr->addQuotes($target->getDbKey())."";
+	$sql = $dbr->limitResult($sql, $queryLimit, $offset);
+	$res = $dbr->query($sql,"wfShowIndirectLinks");
+/* the "original" query thing
 	$res = $dbr->select( array( 'pagelinks', 'page' ),
 		array( 'page_id', 'page_namespace', 'page_title', 'page_is_redirect' ),
 		array(
 			'pl_from=page_id',
 			'pl_namespace' => $target->getNamespace(),
 			'pl_title'     => $target->getDbKey() ),
 		$fname,
 		array( 'LIMIT' => $limitSql ) );
-
+*/
 	if ( 0 == $dbr->numRows( $res ) ) {
 		if ( 0 == $level ) {
 			$wgOut->addWikiText( wfMsg( 'nolinkshere' ) );
 		}
 		return;
Index: includes/User.php
===================================================================
RCS file: /cvsroot/wikipedia/phase3/includes/User.php,v
retrieving revision 1.192
diff -U5 -r1.192 User.php
--- includes/User.php	1 Dec 2005 10:37:47 -0000	1.192
+++ includes/User.php	4 Dec 2005 16:59:27 -0000
@@ -1178,11 +1178,11 @@
 		// any matching rows
 		if ( $watched ) {
 			$dbw =& wfGetDB( DB_MASTER );
 			$success = $dbw->update( 'watchlist',
 					array( /* SET */
-						'wl_notificationtimestamp' => NULL
+					'wl_notificationtimestamp' => NULL
 					), array( /* WHERE */
 						'wl_title' => $title->getDBkey(),
 						'wl_namespace' => $title->getNamespace(),
 						'wl_user' => $this->getID()
 					), 'User::clearLastVisited'
@@ -1208,11 +1208,11 @@
 		if( $currentUser != 0 )  {
 
 			$dbw =& wfGetDB( DB_MASTER );
 			$success = $dbw->update( 'watchlist',
 				array( /* SET */
-					'wl_notificationtimestamp' => 0
+				'wl_notificationtimestamp' => NULL
 				), array( /* WHERE */
 					'wl_user' => $currentUser
 				), 'UserMailer::clearAll'
 			);
 
@@ -1411,10 +1411,11 @@
 	 */
 	function addToDatabase() {
 		$fname = 'User::addToDatabase';
 		$dbw =& wfGetDB( DB_MASTER );
 		$seqVal = $dbw->nextSequenceValue( 'user_user_id_seq' );
+
 		$dbw->insert( 'user',
 			array(
 				'user_id' => $seqVal,
 				'user_name' => $this->mName,
 				'user_password' => $this->mPassword,
Index: languages/LanguageDe.php
===================================================================
RCS file: /cvsroot/wikipedia/phase3/languages/LanguageDe.php,v
retrieving revision 1.154
diff -U5 -r1.154 LanguageDe.php
--- languages/LanguageDe.php	3 Dec 2005 22:18:35 -0000	1.154
+++ languages/LanguageDe.php	4 Dec 2005 16:59:46 -0000
@@ -466,10 +466,11 @@
 'loadhist'		=> 'Lade Liste mit früheren Versionen',
 'currentrev'	=> 'Aktuelle Version',
 'revisionasof'	=> 'Version vom $1',
 'revisionasofwithlink'	=> 'Version vom $1; $2<br />$3 | $4',
 'nextrevision'		=> '←Nächstjüngere Version',
+'currentrevisionlink'   => 'Aktuelle Version',
 'previousrevision'	=> 'Nächstältere Version→',
 'cur'			=> 'Aktuell',
 'next'			=> 'Nächste',
 'last'			=> 'Vorherige',
 'orig'			=> 'Original',
@@ -738,17 +739,21 @@
 'newpages'		=> 'Neue Artikel',
 'ancientpages' => 'Älteste Artikel',
 'movethispage'	=> 'Artikel verschieben',
 "unusedimagestext" => "<p>Bitte beachten Sie, dass andere Wikis möglicherweise einige dieser Bilder benutzen.",
 "booksources"	=> "Buchhandlungen",
+'categoriespagetext' => 'Die folgenden Kategorien existieren im wiki.',
 "booksourcetext" => "Dies ist eine Liste mit Links zu Internetseiten, die neue und gebrauchte Bücher verkaufen. Dort kann es auch weitere Informationen über die Bücher geben, die Sie interessieren. {{SITENAME}} ist mit keinem dieser Anbieter geschäftlich verbunden.",
 'alphaindexline' => '$1 bis $2',
 'newimages'	=> 'Neue Dateien',
 'mimesearch'	=> 'Suche nach MIME-Typ',
 'mimetype'	=> 'MIME-Typ: ',
 'download'	=> 'Herunterladen',
 'mostlinked'	=> 'Meistverlinke Seiten',
+'mostcategories' => 'Am häufigsten verlinkte Kategorien',
+'mostimages'	=> 'Am häufigsten verlinkte Bilder',
+'mostrevisions' => 'Artikel mit den meisten Revisionen',
 'uncategorizedpages'	=> 'Nicht kategorisierte Artikel',
 'uncategorizedcategories'	=> 'Nicht kategorisierte Kategorien',
 'unusedcategories' => 'Verwaiste Kategorien',
 
 # Special:Allpages
@@ -989,10 +994,27 @@
 'saveusergroups' => 'Speichere Gruppenzugehörigkeit',
 'userrights-groupsmember' => 'Mitglied von: ',
 'userrights-groupsavailable' => 'Verfügbare Gruppen: ',
 'userrights-groupshelp' => 'Wähle die Gruppen, aus denen der Benutzer entfernt oder zu denen er hinzugefügt werden soll.
 Nicht selektierte Gruppen werden nicht geändert. Eine Selektion kann mit Strg + Linksklick (bzw. Ctrl + Linksklick) entfernt werden.',
+'groups-editgroup'          => 'Gruppe bearbeiten',
+'groups-addgroup'           => 'Gruppe hinzufügen',
+'groups-editgroup-preamble' => 'If the name or description starts with a colon, the
+remainder will be treated as a message name, and hence the text will be localised
+using the MediaWiki namespace',
+'groups-editgroup-name'     => 'Gruppen Name:',
+'groups-editgroup-description' => 'Gruppen Beschreibung (max 255 Zeichen):<br />',
+'savegroup'                 => 'Gruppe Speichern',
+'groups-tableheader'        => 'ID || Name || Beschreibung || Rechte',
+'groups-existing'           => 'Existierend Gruppen',
+'groups-noname'             => 'Bitte geben sie einen gültigen Gruppennamen an',
+'groups-already-exists'     => 'Eine Gruppe mit diesem Namen existiert bereits',
+'addgrouplogentry'          => 'Gruppe $2 hinzugefügt',
+'changegrouplogentry'       => 'Gruppe $2 geändert',
+'renamegrouplogentry'       => 'Gruppe $2 nach $3 umbenannt',
+
+
 
 # Move page
 #
 "movepage"		=> "Artikel verschieben",
 "movepagetext"	=> "Mit diesem Formular können Sie einen Artikel umbenennen, mitsamt allen Versionen. Der alte Titel wird zum neuen weiterleiten. Verweise auf den alten Titel werden nicht geändert, und die Diskussionsseite wird auch nicht mitverschoben.",
@@ -1047,10 +1069,13 @@
 'makesysopname'         => 'Name des Benutzers:',
 'makesysopsubmit'       => 'Mache diesen Benutzer zu einem Administrator',
 "makesysopok"           => "<b>Benutzer \"$1\" ist nun ein Administrator.</b>",
 "makesysopfail"         => "<b>Benutzer \"$1\" konnte nicht zu einem Administrator gemacht werden. (Haben Sie den Namen richtig geschrieben?)</b>",
 "makesysop"         => "Mache einen Benutzer zum Administrator",
+'already_sysop'     => 'Dieser Benutzer ist bereits Administrator',
+'already_bureaucrat' => 'Dieser Benutzer ist bereits Bürokrat',
+'already_steward'   => 'Dieser Benutzer ist bereits Steward',
 "bureaucratlogentry"	=> "Rechte für Benutzer \"$1\" auf \"$2\" gesetzt",
 'rights'		=> 'Rechte:',
 'set_user_rights'	=> 'Benutzerrechte setzen',
 "user_rights_set"	=> "<b>Benutzerrechte für \"$1\" aktualisiert</b>",
 "set_rights_fail"	=> "<b>Benutzerrechte für \"$1\" konnten nicht gesetzt werden. (Haben Sie den Namen korrekt eingegeben?)</b>",
@@ -1200,11 +1225,11 @@
 'confirmemail_text' => "Diese Wiki erfordert, dass Sie Ihre E-Mailadresse bestätigen (authentifizieren),
 bevor Sie die erweiterten Mailfunktionen benutzen können. Ein Klick auf die Schaltfläche unten sendet eine E-Mail zu Ihnen.
 Diese Mail enthält einen Link mit einem Kode; durch Klicken auf diesen Link bestätigen Sie, dass Ihre Adresse gültig ist.",
 'confirmemail_send' => 'Anforderung einer E-Mail zur Adressenbestätigung',
 'confirmemail_sent' => 'Es wurde Ihnen eine Mail zur Adressenbestätigung gesendet.',
-'confirmemail_sendfailed' => 'Could not send confirmation mail due to misconfigured server or invalid characters in e-mail address.',
+'confirmemail_sendfailed' => 'Konnte E-Mail zur Adressenbestätigung nicht sendn, da der Mailserver falsch konfiguriert ist, oder die E-Mail Adresse ungültige Zeichen enthält.',
 'confirmemail_invalid' => 'Ungültiger Bestätigungskode. Die Gültigkeitsdauer des Kodes ist eventuell abgelaufen.',
 'confirmemail_success' => 'Ihre E-Mailadresse wurde bestätigt. Sie können sich jetzt einloggen.',
 'confirmemail_loggedin' => 'Ihre E-Mailadresse ist nun bestätigt.',
 'confirmemail_error' => 'Es gab einen Fehler bei der Bestätigung Ihrer E-Mailadresse.',
 
Index: maintenance/userDupes.inc
===================================================================
RCS file: /cvsroot/wikipedia/phase3/maintenance/userDupes.inc,v
retrieving revision 1.6
diff -U5 -r1.6 userDupes.inc
--- maintenance/userDupes.inc	24 Aug 2005 07:25:16 -0000	1.6
+++ maintenance/userDupes.inc	4 Dec 2005 17:00:24 -0000
@@ -44,11 +44,11 @@
 		}
 		
 		# Confusingly, 'Non_unique' is 0 for *unique* indexes,
 		# and 1 for *non-unique* indexes. Pass the crack, MySQL,
 		# it's obviously some good stuff!
-		return ( $info->Non_unique == 0 );
+		return $info->unique;
 	}
 	
 	/**
 	 * Checks the database for duplicate user account records
 	 * and remove them in preparation for application of a unique
@@ -323,6 +323,6 @@
 	}
 	
 }
 
 
-?>
\ No newline at end of file
+?>
Index: maintenance/oracle/tables.sql
===================================================================
RCS file: /cvsroot/wikipedia/phase3/maintenance/oracle/tables.sql,v
retrieving revision 1.2
diff -U5 -r1.2 tables.sql
--- maintenance/oracle/tables.sql	2 Aug 2005 13:35:19 -0000	1.2
+++ maintenance/oracle/tables.sql	4 Dec 2005 17:00:24 -0000
@@ -53,11 +53,11 @@
 );
 CREATE UNIQUE INDEX page_id_namespace_title_idx ON page(page_namespace, page_title);
 CREATE INDEX page_random_idx ON page(page_random);
 CREATE INDEX page_len_idx ON page(page_len);
 
-CREATE SEQUENCE rev_rev_id_val;
+CREATE SEQUENCE revision_rev_id_seq;
 CREATE TABLE revision (
 	rev_id		NUMBER(8) NOT NULL,
 	rev_page	NUMBER(8) NOT NULL
 				REFERENCES page (page_id)
 				ON DELETE CASCADE,
@@ -75,11 +75,11 @@
 CREATE INDEX rev_timestamp_idx ON revision(rev_timestamp);
 CREATE INDEX rev_page_timestamp_idx ON revision(rev_page, rev_timestamp);
 CREATE INDEX rev_user_timestamp_idx ON revision(rev_user, rev_timestamp);
 CREATE INDEX rev_usertext_timestamp_idx ON revision(rev_user_text, rev_timestamp);
 
-CREATE SEQUENCE text_old_id_val;
+CREATE SEQUENCE text_old_id_seq;
 
 CREATE TABLE text (
 	old_id		NUMBER(8) NOT NULL,
 	old_text	CLOB,
 	old_flags	CLOB,
@@ -156,11 +156,11 @@
 
 --
 -- The internet is full of jerks, alas. Sometimes it's handy
 -- to block a vandal or troll account.
 --
-CREATE SEQUENCE ipblocks_ipb_id_val;
+CREATE SEQUENCE ipblocks_ipb_id_seq;
 CREATE TABLE ipblocks (
 	ipb_id		NUMBER(8) NOT NULL,
 	ipb_address	VARCHAR2(40),
 	ipb_user	NUMBER(8),
 	ipb_by		NUMBER(8) NOT NULL
@@ -206,11 +206,11 @@
 	oi_user_text	VARCHAR2(255) NOT NULL,
 	oi_timestamp	TIMESTAMP WITH TIME ZONE NOT NULL
 );
 CREATE INDEX oi_name ON oldimage (oi_name);
 
-CREATE SEQUENCE rc_rc_id_seq;
+CREATE SEQUENCE recentchanges_rc_id_seq;
 CREATE TABLE recentchanges (
 	rc_id 		NUMBER(8) NOT NULL,
 	rc_timestamp	TIMESTAMP WITH TIME ZONE,
 	rc_cur_time	TIMESTAMP WITH TIME ZONE,
 	rc_user		NUMBER(8) DEFAULT 0 NOT NULL,
@@ -339,6 +339,6 @@
 
 CREATE OR REPLACE PROCEDURE add_interwiki (prefix VARCHAR2, url VARCHAR2, is_local NUMBER) AS
 BEGIN
 	INSERT INTO interwiki (iw_prefix, iw_url, iw_local) VALUES(prefix, url, is_local);;
 END add_interwiki;;
-;
\ No newline at end of file
+;
Index: maintenance/postgresql/interwiki.sql
===================================================================
RCS file: maintenance/postgresql/interwiki.sql
diff -N maintenance/postgresql/interwiki.sql
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ maintenance/postgresql/interwiki.sql	4 Dec 2005 17:00:24 -0000
@@ -0,0 +1,178 @@
+-- Based more or less on the public interwiki map from MeatballWiki
+-- Default interwiki prefixes...
+
+SELECT add_interwiki('abbenormal','http://www.ourpla.net/cgi-bin/pikie.cgi?$1',0);
+SELECT add_interwiki('acadwiki','http://xarch.tu-graz.ac.at/autocad/wiki/$1',0);
+SELECT add_interwiki('acronym','http://www.acronymfinder.com/af-query.asp?String=exact&Acronym=$1',0);
+SELECT add_interwiki('advogato','http://www.advogato.org/$1',0);
+SELECT add_interwiki('aiwiki','http://www.ifi.unizh.ch/ailab/aiwiki/aiw.cgi?$1',0);
+SELECT add_interwiki('alife','http://news.alife.org/wiki/index.php?$1',0);
+SELECT add_interwiki('annotation','http://bayle.stanford.edu/crit/nph-med.cgi/$1',0);
+SELECT add_interwiki('annotationwiki','http://www.seedwiki.com/page.cfm?wikiid=368&doc=$1',0);
+SELECT add_interwiki('arxiv','http://www.arxiv.org/abs/$1',0);
+SELECT add_interwiki('aspienetwiki','http://aspie.mela.de/Wiki/index.php?title=$1',0);
+SELECT add_interwiki('bemi','http://bemi.free.fr/vikio/index.php?$1',0);
+SELECT add_interwiki('benefitswiki','http://www.benefitslink.com/cgi-bin/wiki.cgi?$1',0);
+SELECT add_interwiki('brasilwiki','http://rio.ifi.unizh.ch/brasilienwiki/index.php/$1',0);
+SELECT add_interwiki('bridgeswiki','http://c2.com/w2/bridges/$1',0);
+SELECT add_interwiki('c2find','http://c2.com/cgi/wiki?FindPage&value=$1',0);
+SELECT add_interwiki('cache','http://www.google.com/search?q=cache:$1',0);
+SELECT add_interwiki('ciscavate','http://ciscavate.org/index.php/$1',0);
+SELECT add_interwiki('cliki','http://ww.telent.net/cliki/$1',0);
+SELECT add_interwiki('cmwiki','http://www.ourpla.net/cgi-bin/wiki.pl?$1',0);
+SELECT add_interwiki('codersbase','http://www.codersbase.com/$1',0);
+SELECT add_interwiki('commons','http://commons.wikimedia.org/wiki/$1',0);
+SELECT add_interwiki('consciousness','http://teadvus.inspiral.org/',0);
+SELECT add_interwiki('corpknowpedia','http://corpknowpedia.org/wiki/index.php/$1',0);
+SELECT add_interwiki('creationmatters','http://www.ourpla.net/cgi-bin/wiki.pl?$1',0);
+SELECT add_interwiki('dejanews','http://www.deja.com/=dnc/getdoc.xp?AN=$1',0);
+SELECT add_interwiki('demokraatia','http://wiki.demokraatia.ee/',0);
+SELECT add_interwiki('dictionary','http://www.dict.org/bin/Dict?Database=*&Form=Dict1&Strategy=*&Query=$1',0);
+SELECT add_interwiki('disinfopedia','http://www.disinfopedia.org/wiki.phtml?title=$1',0);
+SELECT add_interwiki('diveintoosx','http://diveintoosx.org/$1',0);
+SELECT add_interwiki('docbook','http://docbook.org/wiki/moin.cgi/$1',0);
+SELECT add_interwiki('dolphinwiki','http://www.object-arts.com/wiki/html/Dolphin/$1',0);
+SELECT add_interwiki('drumcorpswiki','http://www.drumcorpswiki.com/index.php/$1',0);
+SELECT add_interwiki('dwjwiki','http://www.suberic.net/cgi-bin/dwj/wiki.cgi?$1',0);
+SELECT add_interwiki('eĉei','http://www.ikso.net/cgi-bin/wiki.pl?$1',0);
+SELECT add_interwiki('echei','http://www.ikso.net/cgi-bin/wiki.pl?$1',0);
+SELECT add_interwiki('ecxei','http://www.ikso.net/cgi-bin/wiki.pl?$1',0);
+SELECT add_interwiki('efnetceewiki','http://purl.net/wiki/c/$1',0);
+SELECT add_interwiki('efnetcppwiki','http://purl.net/wiki/cpp/$1',0);
+SELECT add_interwiki('efnetpythonwiki','http://purl.net/wiki/python/$1',0);
+SELECT add_interwiki('efnetxmlwiki','http://purl.net/wiki/xml/$1',0);
+SELECT add_interwiki('eljwiki','http://elj.sourceforge.net/phpwiki/index.php/$1',0);
+SELECT add_interwiki('emacswiki','http://www.emacswiki.org/cgi-bin/wiki.pl?$1',0);
+SELECT add_interwiki('elibre','http://enciclopedia.us.es/index.php/$1',0);
+SELECT add_interwiki('eokulturcentro','http://esperanto.toulouse.free.fr/wakka.php?wiki=$1',0);
+SELECT add_interwiki('evowiki','http://www.evowiki.org/index.php/$1',0);
+SELECT add_interwiki('finalempire','http://final-empire.sourceforge.net/cgi-bin/wiki.pl?$1',0);
+SELECT add_interwiki('firstwiki','http://firstwiki.org/index.php/$1',0);
+SELECT add_interwiki('foldoc','http://www.foldoc.org/foldoc/foldoc.cgi?$1',0);
+SELECT add_interwiki('foxwiki','http://fox.wikis.com/wc.dll?Wiki~$1',0);
+SELECT add_interwiki('fr.be','http://fr.wikinations.be/$1',0);
+SELECT add_interwiki('fr.ca','http://fr.ca.wikinations.org/$1',0);
+SELECT add_interwiki('fr.fr','http://fr.fr.wikinations.org/$1',0);
+SELECT add_interwiki('fr.org','http://fr.wikinations.org/$1',0);
+SELECT add_interwiki('freebsdman','http://www.FreeBSD.org/cgi/man.cgi?apropos=1&query=$1',0);
+SELECT add_interwiki('gamewiki','http://gamewiki.org/wiki/index.php/$1',0);
+SELECT add_interwiki('gej','http://www.esperanto.de/cgi-bin/aktivikio/wiki.pl?$1',0);
+SELECT add_interwiki('gentoo-wiki','http://gentoo-wiki.com/$1',0);
+SELECT add_interwiki('globalvoices','http://cyber.law.harvard.edu/dyn/globalvoices/wiki/$1',0);
+SELECT add_interwiki('gmailwiki','http://www.gmailwiki.com/index.php/$1',0);
+SELECT add_interwiki('google','http://www.google.com/search?q=$1',0);
+SELECT add_interwiki('googlegroups','http://groups.google.com/groups?q=$1',0);
+SELECT add_interwiki('gotamac','http://www.got-a-mac.org/$1',0);
+SELECT add_interwiki('greencheese','http://www.greencheese.org/$1',0);
+SELECT add_interwiki('hammondwiki','http://www.dairiki.org/HammondWiki/index.php3?$1',0);
+SELECT add_interwiki('haribeau','http://wiki.haribeau.de/cgi-bin/wiki.pl?$1',0);
+SELECT add_interwiki('hewikisource','http://he.wikisource.org/wiki/$1',1);
+SELECT add_interwiki('herzkinderwiki','http://www.herzkinderinfo.de/Mediawiki/index.php/$1',0);
+SELECT add_interwiki('hrwiki','http://www.hrwiki.org/index.php/$1',0);
+SELECT add_interwiki('iawiki','http://www.IAwiki.net/$1',0);
+SELECT add_interwiki('imdb','http://us.imdb.com/Title?$1',0);
+SELECT add_interwiki('infosecpedia','http://www.infosecpedia.org/pedia/index.php/$1',0);
+SELECT add_interwiki('jargonfile','http://sunir.org/apps/meta.pl?wiki=JargonFile&redirect=$1',0);
+SELECT add_interwiki('jefo','http://www.esperanto-jeunes.org/vikio/index.php?$1',0);
+SELECT add_interwiki('jiniwiki','http://www.cdegroot.com/cgi-bin/jini?$1',0);
+SELECT add_interwiki('jspwiki','http://www.ecyrd.com/JSPWiki/Wiki.jsp?page=$1',0);
+SELECT add_interwiki('kerimwiki','http://wiki.oxus.net/$1',0);
+SELECT add_interwiki('kmwiki','http://www.voght.com/cgi-bin/pywiki?$1',0);
+SELECT add_interwiki('knowhow','http://www2.iro.umontreal.ca/~paquetse/cgi-bin/wiki.cgi?$1',0);
+SELECT add_interwiki('lanifexwiki','http://opt.lanifex.com/cgi-bin/wiki.pl?$1',0);
+SELECT add_interwiki('lasvegaswiki','http://wiki.gmnow.com/index.php/$1',0);
+SELECT add_interwiki('linuxwiki','http://www.linuxwiki.de/$1',0);
+SELECT add_interwiki('lojban','http://www.lojban.org/tiki/tiki-index.php?page=$1',0);
+SELECT add_interwiki('lqwiki','http://wiki.linuxquestions.org/wiki/$1',0);
+SELECT add_interwiki('lugkr','http://lug-kr.sourceforge.net/cgi-bin/lugwiki.pl?$1',0);
+SELECT add_interwiki('lutherwiki','http://www.lutheranarchives.com/mw/index.php/$1',0);
+SELECT add_interwiki('mathsongswiki','http://SeedWiki.com/page.cfm?wikiid=237&doc=$1',0);
+SELECT add_interwiki('mbtest','http://www.usemod.com/cgi-bin/mbtest.pl?$1',0);
+SELECT add_interwiki('meatball','http://www.usemod.com/cgi-bin/mb.pl?$1',0);
+SELECT add_interwiki('mediazilla','http://bugzilla.wikipedia.org/$1',1);
+SELECT add_interwiki('memoryalpha','http://www.memory-alpha.org/en/index.php/$1',0);
+SELECT add_interwiki('metaweb','http://www.metaweb.com/wiki/wiki.phtml?title=$1',0);
+SELECT add_interwiki('metawiki','http://sunir.org/apps/meta.pl?$1',0);
+SELECT add_interwiki('metawikipedia','http://meta.wikimedia.org/wiki/$1',0);
+SELECT add_interwiki('moinmoin','http://purl.net/wiki/moin/$1',0);
+SELECT add_interwiki('mozillawiki','http://wiki.mozilla.org/index.php/$1',0);
+SELECT add_interwiki('muweb','http://www.dunstable.com/scripts/MuWebWeb?$1',0);
+SELECT add_interwiki('netvillage','http://www.netbros.com/?$1',0);
+SELECT add_interwiki('oeis','http://www.research.att.com/cgi-bin/access.cgi/as/njas/sequences/eisA.cgi?Anum=$1',0);
+SELECT add_interwiki('openfacts','http://openfacts.berlios.de/index.phtml?title=$1',0);
+SELECT add_interwiki('openwiki','http://openwiki.com/?$1',0);
+SELECT add_interwiki('opera7wiki','http://nontroppo.org/wiki/$1',0);
+SELECT add_interwiki('orgpatterns','http://www.bell-labs.com/cgi-user/OrgPatterns/OrgPatterns?$1',0);
+SELECT add_interwiki('osi reference model','http://wiki.tigma.ee/',0);
+SELECT add_interwiki('pangalacticorg','http://www.pangalactic.org/Wiki/$1',0);
+SELECT add_interwiki('personaltelco','http://www.personaltelco.net/index.cgi/$1',0);
+SELECT add_interwiki('patwiki','http://gauss.ffii.org/$1',0);
+SELECT add_interwiki('phpwiki','http://phpwiki.sourceforge.net/phpwiki/index.php?$1',0);
+SELECT add_interwiki('pikie','http://pikie.darktech.org/cgi/pikie?$1',0);
+SELECT add_interwiki('pmeg','http://www.bertilow.com/pmeg/$1.php',0);
+SELECT add_interwiki('ppr','http://c2.com/cgi/wiki?$1',0);
+SELECT add_interwiki('purlnet','http://purl.oclc.org/NET/$1',0);
+SELECT add_interwiki('pythoninfo','http://www.python.org/cgi-bin/moinmoin/$1',0);
+SELECT add_interwiki('pythonwiki','http://www.pythonwiki.de/$1',0);
+SELECT add_interwiki('pywiki','http://www.voght.com/cgi-bin/pywiki?$1',0);
+SELECT add_interwiki('raec','http://www.raec.clacso.edu.ar:8080/raec/Members/raecpedia/$1',0);
+SELECT add_interwiki('revo','http://purl.org/NET/voko/revo/art/$1.html',0);
+SELECT add_interwiki('rfc','http://www.rfc-editor.org/rfc/rfc$1.txt',0);
+SELECT add_interwiki('s23wiki','http://is-root.de/wiki/index.php/$1',0);
+SELECT add_interwiki('scoutpedia','http://www.scoutpedia.info/index.php/$1',0);
+SELECT add_interwiki('seapig','http://www.seapig.org/$1',0);
+SELECT add_interwiki('seattlewiki','http://seattlewiki.org/wiki/$1',0);
+SELECT add_interwiki('seattlewireless','http://seattlewireless.net/?$1',0);
+SELECT add_interwiki('seeds','http://www.IslandSeeds.org/wiki/$1',0);
+SELECT add_interwiki('senseislibrary','http://senseis.xmp.net/?$1',0);
+SELECT add_interwiki('shakti','http://cgi.algonet.se/htbin/cgiwrap/pgd/ShaktiWiki/$1',0);
+SELECT add_interwiki('slashdot','http://slashdot.org/article.pl?sid=$1',0);
+SELECT add_interwiki('smikipedia','http://www.smikipedia.org/$1',0);
+SELECT add_interwiki('sockwiki','http://wiki.socklabs.com/$1',0);
+SELECT add_interwiki('sourceforge','http://sourceforge.net/$1',0);
+SELECT add_interwiki('squeak','http://minnow.cc.gatech.edu/squeak/$1',0);
+SELECT add_interwiki('strikiwiki','http://ch.twi.tudelft.nl/~mostert/striki/teststriki.pl?$1',0);
+SELECT add_interwiki('susning','http://www.susning.nu/$1',0);
+SELECT add_interwiki('svgwiki','http://www.protocol7.com/svg-wiki/default.asp?$1',0);
+SELECT add_interwiki('tavi','http://tavi.sourceforge.net/$1',0);
+SELECT add_interwiki('tejo','http://www.tejo.org/vikio/$1',0);
+SELECT add_interwiki('terrorwiki','http://www.liberalsagainstterrorism.com/wiki/index.php/$1',0);
+SELECT add_interwiki('tmbw','http://www.tmbw.net/wiki/index.php/$1',0);
+SELECT add_interwiki('tmnet','http://www.technomanifestos.net/?$1',0);
+SELECT add_interwiki('tmwiki','http://www.EasyTopicMaps.com/?page=$1',0);
+SELECT add_interwiki('turismo','http://www.tejo.org/turismo/$1',0);
+SELECT add_interwiki('theopedia','http://www.theopedia.com/$1',0);
+SELECT add_interwiki('twiki','http://twiki.org/cgi-bin/view/$1',0);
+SELECT add_interwiki('twistedwiki','http://purl.net/wiki/twisted/$1',0);
+SELECT add_interwiki('uea','http://www.tejo.org/uea/$1',0);
+SELECT add_interwiki('unreal','http://wiki.beyondunreal.com/wiki/$1',0);
+SELECT add_interwiki('ursine','http://ursine.ca/$1',0);
+SELECT add_interwiki('usej','http://www.tejo.org/usej/$1',0);
+SELECT add_interwiki('usemod','http://www.usemod.com/cgi-bin/wiki.pl?$1',0);
+SELECT add_interwiki('visualworks','http://wiki.cs.uiuc.edu/VisualWorks/$1',0);
+SELECT add_interwiki('warpedview','http://www.warpedview.com/index.php/$1',0);
+SELECT add_interwiki('webdevwikinl','http://www.promo-it.nl/WebDevWiki/index.php?page=$1',0);
+SELECT add_interwiki('webisodes','http://www.webisodes.org/$1',0);
+SELECT add_interwiki('webseitzwiki','http://webseitz.fluxent.com/wiki/$1',0);
+SELECT add_interwiki('why','http://clublet.com/c/c/why?$1',0);
+SELECT add_interwiki('wiki','http://c2.com/cgi/wiki?$1',0);
+SELECT add_interwiki('wikia','http://www.wikia.com/wiki/index.php/$1',0);
+SELECT add_interwiki('wikibooks','http://en.wikibooks.org/wiki/$1',1);
+SELECT add_interwiki('wikicities','http://www.wikicities.com/index.php/$1',0);
+SELECT add_interwiki('wikif1','http://www.wikif1.org/$1',0);
+SELECT add_interwiki('wikinfo','http://www.wikinfo.org/wiki.php?title=$1',0);
+SELECT add_interwiki('wikimedia','http://wikimediafoundation.org/wiki/$1',0);
+SELECT add_interwiki('wikiquote','http://en.wikiquote.org/wiki/$1',1);
+SELECT add_interwiki('wikinews','http://en.wikinews.org/wiki/$1',0);
+SELECT add_interwiki('wikisource','http://sources.wikipedia.org/wiki/$1',1);
+SELECT add_interwiki('wikispecies','http://species.wikipedia.org/wiki/$1',1);
+SELECT add_interwiki('wikitravel','http://wikitravel.org/en/$1',0);
+SELECT add_interwiki('wikiworld','http://WikiWorld.com/wiki/index.php/$1',0);
+SELECT add_interwiki('wiktionary','http://en.wiktionary.org/wiki/$1',1);
+SELECT add_interwiki('wlug','http://www.wlug.org.nz/$1',0);
+SELECT add_interwiki('wlwiki','http://winslowslair.supremepixels.net/wiki/index.php/$1',0);
+SELECT add_interwiki('ypsieyeball','http://sknkwrks.dyndns.org:1957/writewiki/wiki.pl?$1',0);
+SELECT add_interwiki('zwiki','http://www.zwiki.org/$1',0);
+SELECT add_interwiki('zzz wiki','http://wiki.zzz.ee/',0);
+SELECT add_interwiki('wikt','http://en.wiktionary.org/wiki/$1',1);
+
Index: maintenance/postgresql/tables.sql
===================================================================
RCS file: maintenance/postgresql/tables.sql
diff -N maintenance/postgresql/tables.sql
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ maintenance/postgresql/tables.sql	4 Dec 2005 17:00:24 -0000
@@ -0,0 +1,373 @@
+-- postgresql 8.0 setup
+
+CREATE SCHEMA "mediawiki";
+SET search_path = "mediawiki";
+
+CREATE TABLE "user" (
+  user_id		SERIAL NOT NULL PRIMARY KEY,
+  user_name		VARCHAR(255) DEFAULT '' NOT NULL,
+  user_real_name	VARCHAR(255) DEFAULT '',
+  user_password		VARCHAR(128) DEFAULT '',
+  user_newpassword	VARCHAR(128) default '',
+  user_email		VARCHAR(255) default '',
+  user_options		TEXT default '',
+  user_touched		TIMESTAMP WITH TIME ZONE,
+  user_token		CHAR(32) default '',
+  user_email_authenticated TIMESTAMP WITH TIME ZONE DEFAULT NULL,
+  user_email_token	CHAR(32),
+  user_email_token_expires TIMESTAMP WITH TIME ZONE DEFAULT NULL
+);
+CREATE UNIQUE INDEX user_name_idx ON "user" (user_name);
+CREATE INDEX user_email_token_idx ON "user" (user_email_token);
+-- -------------------------------------------------------------------
+CREATE TABLE user_groups (
+	ug_user		INTEGER NOT NULL
+				REFERENCES "user" (user_id)
+				ON DELETE CASCADE,
+	ug_group	VARCHAR(16) NOT NULL,
+	CONSTRAINT user_groups_pk PRIMARY KEY (ug_user, ug_group)
+);
+CREATE INDEX user_groups_group_idx ON user_groups(ug_group);
+-- -------------------------------------------------------------------
+CREATE TABLE user_newtalk (
+	user_id		INTEGER DEFAULT 0 NOT NULL,
+	user_ip		VARCHAR(40) DEFAULT '' NOT NULL
+);
+CREATE INDEX user_newtalk_id_idx ON user_newtalk(user_id);
+CREATE INDEX user_newtalk_ip_idx ON user_newtalk(user_ip);
+-- -------------------------------------------------------------------
+CREATE TABLE page (
+	page_id			SERIAL NOT NULL PRIMARY KEY,
+	page_namespace		INTEGER NOT NULL,
+	page_title		VARCHAR(255) NOT NULL,
+	page_restrictions	TEXT DEFAULT '',
+	page_counter 		INTEGER DEFAULT 0 NOT NULL,
+	page_is_redirect	INTEGER DEFAULT 0 NOT NULL,
+	page_is_new		INTEGER DEFAULT 0 NOT NULL,
+	page_random		NUMERIC NOT NULL,
+	page_touched		TIMESTAMP WITH TIME ZONE,
+	page_latest		INTEGER NOT NULL,
+	page_len 		INTEGER DEFAULT 0
+);
+CREATE UNIQUE INDEX page_id_namespace_title_idx ON page(page_namespace, page_title);
+CREATE INDEX page_random_idx ON page(page_random);
+CREATE INDEX page_len_idx ON page(page_len);
+
+CREATE TABLE revision (
+	rev_id		SERIAL NOT NULL,
+	rev_page	INTEGER NOT NULL
+				REFERENCES page (page_id)
+				ON DELETE CASCADE,
+	rev_text_id	INTEGER NOT NULL,
+	rev_comment	TEXT,
+	rev_user	INTEGER DEFAULT 0 NOT NULL,
+	rev_user_text	VARCHAR(255) DEFAULT '' NOT NULL,
+	rev_timestamp	TIMESTAMP WITH TIME ZONE NOT NULL,
+	rev_minor_edit	INTEGER DEFAULT 0 NOT NULL,
+	rev_deleted	INTEGER DEFAULT 0 NOT NULL,
+	CONSTRAINT revision_pk PRIMARY KEY (rev_page, rev_id)
+);
+
+CREATE UNIQUE INDEX rev_id_idx ON revision(rev_id);
+CREATE INDEX rev_timestamp_idx ON revision(rev_timestamp);
+CREATE INDEX rev_page_timestamp_idx ON revision(rev_page, rev_timestamp);
+CREATE INDEX rev_user_timestamp_idx ON revision(rev_user, rev_timestamp);
+CREATE INDEX rev_usertext_timestamp_idx ON revision(rev_user_text, rev_timestamp);
+
+
+CREATE TABLE text (
+	old_id		SERIAL NOT NULL,
+	old_text	TEXT,
+	old_flags	TEXT,
+	CONSTRAINT text_pk PRIMARY KEY (old_id)
+);
+
+CREATE TABLE archive (
+	ar_namespace	INTEGER NOT NULL,
+	ar_title	VARCHAR(255) NOT NULL,
+	ar_text		TEXT,
+	ar_comment	TEXT,
+	ar_user		INTEGER,
+	ar_user_text	VARCHAR(255) NOT NULL,
+	ar_timestamp	TIMESTAMP WITH TIME ZONE NOT NULL,
+	ar_minor_edit	INTEGER DEFAULT 0 NOT NULL,
+	ar_flags	TEXT,
+	ar_rev_id	INTEGER,
+	ar_text_id	INTEGER
+);
+CREATE INDEX archive_name_title_timestamp ON archive(ar_namespace,ar_title,ar_timestamp);
+
+CREATE TABLE pagelinks (
+	pl_from	INTEGER NOT NULL
+				REFERENCES page(page_id)
+				ON DELETE CASCADE,
+	pl_namespace	INTEGER DEFAULT 0 NOT NULL,
+	pl_title	VARCHAR(255) NOT NULL
+);
+CREATE UNIQUE INDEX pl_from ON pagelinks(pl_from, pl_namespace, pl_title);
+CREATE INDEX pl_namespace ON pagelinks(pl_namespace, pl_title);
+
+CREATE TABLE imagelinks (
+	il_from	 INTEGER NOT NULL REFERENCES page(page_id) ON DELETE CASCADE,
+	il_to	 VARCHAR(255) NOT NULL
+);
+CREATE UNIQUE INDEX il_from ON imagelinks(il_from, il_to);
+CREATE INDEX il_to ON imagelinks(il_to);
+
+CREATE TABLE categorylinks (
+  cl_from	INTEGER NOT NULL REFERENCES page(page_id) ON DELETE CASCADE,
+  cl_to		VARCHAR(255) NOT NULL,
+  cl_sortkey	VARCHAR(86) default '',
+  cl_timestamp	TIMESTAMP WITH TIME ZONE NOT NULL
+);
+CREATE UNIQUE INDEX cl_from ON categorylinks(cl_from, cl_to);
+CREATE INDEX cl_sortkey ON categorylinks(cl_to, cl_sortkey);
+CREATE INDEX cl_timestamp ON categorylinks(cl_to, cl_timestamp);
+
+--
+-- Contains a single row with some aggregate info
+-- on the state of the site.
+--
+CREATE TABLE site_stats (
+  ss_row_id		INTEGER NOT NULL,
+  ss_total_views	INTEGER default 0,
+  ss_total_edits	INTEGER default 0,
+  ss_good_articles	INTEGER default 0,
+  ss_total_pages	INTEGER default -1,
+  ss_users		INTEGER default -1,
+  ss_admins		INTEGER default -1
+);
+CREATE UNIQUE INDEX ss_row_id ON site_stats(ss_row_id);
+
+--
+-- Stores an ID for every time any article is visited;
+-- depending on $wgHitcounterUpdateFreq, it is
+-- periodically cleared and the page_counter column
+-- in the page table updated for the all articles
+-- that have been visited.)
+--
+CREATE TABLE hitcounter (
+	hc_id	INTEGER NOT NULL
+);
+
+--
+-- The internet is full of jerks, alas. Sometimes it's handy
+-- to block a vandal or troll account.
+--
+CREATE TABLE ipblocks (
+	ipb_id		SERIAL NOT NULL,
+	ipb_address	VARCHAR(40),
+	ipb_user	INTEGER,
+	ipb_by		INTEGER NOT NULL
+				REFERENCES "user" (user_id)
+				ON DELETE CASCADE,
+	ipb_reason	TEXT,
+	ipb_timestamp	TIMESTAMP WITH TIME ZONE NOT NULL,
+	ipb_auto	INTEGER DEFAULT 0 NOT NULL,
+	ipb_expiry	TIMESTAMP WITH TIME ZONE,
+
+	ipb_range_start varchar(32) NOT NULL default '',
+	ipb_range_end varchar(32) NOT NULL default '',
+	CONSTRAINT ipblocks_pk PRIMARY KEY (ipb_id)
+);
+CREATE INDEX ipb_address ON ipblocks(ipb_address);
+CREATE INDEX ipb_user ON ipblocks(ipb_user);
+
+CREATE TABLE image (
+	img_name	VARCHAR(255) NOT NULL,
+	img_size	INTEGER NOT NULL,
+	img_width	INTEGER NOT NULL,
+	img_height	INTEGER NOT NULL,
+	img_metadata	TEXT,
+	img_bits	INTEGER,
+	img_media_type	VARCHAR(10),
+	img_major_mime	VARCHAR(12) DEFAULT 'unknown',
+	img_minor_mime	VARCHAR(32) DEFAULT 'unknown',
+	img_description	TEXT NOT NULL,
+	img_user	INTEGER NOT NULL REFERENCES "user"(user_id) ON DELETE CASCADE,
+	img_user_text	VARCHAR(255) NOT NULL,
+	img_timestamp	TIMESTAMP WITH TIME ZONE,
+	CONSTRAINT image_pk PRIMARY KEY (img_name)
+);
+CREATE INDEX img_size_idx ON image(img_size);
+CREATE INDEX img_timestamp_idx ON image(img_timestamp);
+
+CREATE TABLE oldimage (
+	oi_name		VARCHAR(255) NOT NULL,
+	oi_archive_name	VARCHAR(255) NOT NULL,
+	oi_size		INTEGER NOT NULL,
+	oi_width	INTEGER NOT NULL,
+	oi_height	INTEGER NOT NULL,
+	oi_bits		INTEGER NOT NULL,
+	oi_description	TEXT,
+	oi_user		INTEGER NOT NULL REFERENCES "user"(user_id),
+	oi_user_text	VARCHAR(255) NOT NULL,
+	oi_timestamp	TIMESTAMP WITH TIME ZONE NOT NULL
+);
+CREATE INDEX oi_name ON oldimage (oi_name);
+
+CREATE TABLE recentchanges (
+	rc_id 		SERIAL NOT NULL,
+	rc_timestamp	TIMESTAMP WITH TIME ZONE,
+	rc_cur_time	TIMESTAMP WITH TIME ZONE,
+	rc_user		INTEGER DEFAULT 0 NOT NULL,
+	rc_user_text	VARCHAR(255),
+	rc_namespace	INTEGER DEFAULT 0 NOT NULL,
+	rc_title	VARCHAR(255) NOT NULL,
+	rc_comment	VARCHAR(255),
+	rc_minor	INTEGER DEFAULT 0 NOT NULL,
+	rc_bot		INTEGER DEFAULT 0 NOT NULL,
+	rc_new 		INTEGER DEFAULT 0 NOT NULL,
+	rc_cur_id	INTEGER,
+	rc_this_oldid	INTEGER NOT NULL,
+	rc_last_oldid	INTEGER NOT NULL,
+	rc_type		INTEGER DEFAULT 0 NOT NULL,
+	rc_moved_to_ns	INTEGER,
+	rc_moved_to_title	VARCHAR(255),
+	rc_patrolled	INTEGER DEFAULT 0 NOT NULL,
+	rc_ip		VARCHAR(40),
+	CONSTRAINT rc_pk PRIMARY KEY (rc_id)
+);
+CREATE INDEX rc_timestamp ON recentchanges (rc_timestamp);
+CREATE INDEX rc_namespace_title ON recentchanges(rc_namespace, rc_title);
+CREATE INDEX rc_cur_id ON recentchanges(rc_cur_id);
+CREATE INDEX new_name_timestamp ON recentchanges(rc_new, rc_namespace, rc_timestamp);
+CREATE INDEX rc_ip ON recentchanges(rc_ip);
+
+CREATE TABLE watchlist (
+	wl_user				INTEGER NOT NULL
+						REFERENCES "user"(user_id)
+						ON DELETE CASCADE,
+	wl_namespace			INTEGER DEFAULT 0 NOT NULL,
+	wl_title			VARCHAR(255) NOT NULL,
+	wl_notificationtimestamp	TIMESTAMP WITH TIME ZONE DEFAULT NULL
+);
+CREATE UNIQUE INDEX wl_user_namespace_title ON watchlist
+	(wl_user, wl_namespace, wl_title);
+CREATE INDEX wl_namespace_title ON watchlist(wl_namespace, wl_title);
+
+--
+-- Used by texvc math-rendering extension to keep track
+-- of previously-rendered items.
+--
+CREATE TABLE math (
+	math_inputhash			bytea NOT NULL UNIQUE,
+	math_outputhash			bytea NOT NULL,
+	math_html_conservativeness	INTEGER NOT NULL,
+	math_html			TEXT,
+	math_mathml			TEXT
+);
+
+CREATE TABLE /*$wgDBprefix*/searchindex (
+	-- Key to page_id
+	si_page INTEGER NOT NULL,
+
+	-- Munged version of title
+--	si_title VARCHAR(255) NOT NULL default '',
+
+	-- Munged version of body text
+--	si_text TEXT NOT NULL default '',
+
+	si_title tsvector,
+
+	si_text tsvector,
+
+	PRIMARY KEY (si_page)
+);
+
+create index si_text_idx on searchindex using gist(si_text);
+create index si_title_idx on searchindex using gist(si_title);
+
+
+-- Do the following if you have installed tsearch2 properly to get search to work
+-- its still experimental though
+
+
+
+--
+-- Recognized interwiki link prefixes
+--
+CREATE TABLE interwiki (
+	iw_prefix	VARCHAR(32) NOT NULL UNIQUE,
+  iw_url	VARCHAR(127) NOT NULL,
+  iw_local	INTEGER NOT NULL,
+  iw_trans	INTEGER DEFAULT 0 NOT NULL
+);
+
+CREATE TABLE querycache (
+	qc_type		VARCHAR(32) NOT NULL,
+	qc_value	INTEGER DEFAULT 0 NOT NULL,
+	qc_namespace	INTEGER DEFAULT 0 NOT NULL,
+	qc_title	VARCHAR(255)
+);
+CREATE INDEX querycache_type_value ON querycache(qc_type, qc_value);
+
+--
+-- For a few generic cache operations if not using Memcached
+--
+CREATE TABLE objectcache (
+	keyname		CHAR(255) DEFAULT '',
+	value		bytea,
+	exptime		TIMESTAMP WITH TIME ZONE
+);
+CREATE UNIQUE INDEX oc_keyname_idx ON objectcache(keyname);
+CREATE INDEX oc_exptime_idx ON objectcache(exptime);
+
+CREATE TABLE "validate" (
+	val_user	INTEGER DEFAULT 0 NOT NULL,
+	val_page	INTEGER DEFAULT 0 NOT NULL,
+	val_revision	INTEGER DEFAULT 0 NOT NULL,
+	val_type	INTEGER DEFAULT 0 NOT NULL,
+	val_value	INTEGER DEFAULT 0,
+	val_comment	VARCHAR(255),
+	val_ip		VARCHAR(20)
+);
+CREATE INDEX val_user ON "validate" (val_user,val_revision);
+
+CREATE TABLE logging (
+  log_type		VARCHAR(10) NOT NULL,
+  log_action		VARCHAR(10) NOT NULL,
+  log_timestamp		TIMESTAMP WITH TIME ZONE NOT NULL,
+  log_user		INTEGER REFERENCES "user"(user_id),
+  log_namespace		INTEGER,
+  log_title		VARCHAR(255) NOT NULL,
+  log_comment		VARCHAR(255),
+  log_params		TEXT
+);
+CREATE INDEX logging_type_name ON logging(log_type, log_timestamp);
+CREATE INDEX logging_user_time ON logging(log_user, log_timestamp);
+CREATE INDEX logging_page_time ON logging(log_namespace, log_title, log_timestamp);
+
+-- Hold group name and description
+--CREATE TABLE /*$wgDBprefix*/groups (
+--  gr_id int(5) unsigned NOT NULL auto_increment,
+--  gr_name varchar(50) NOT NULL default '',
+--  gr_description varchar(255) NOT NULL default '',
+--  gr_rights tinyblob,
+--  PRIMARY KEY  (gr_id)
+--
+--) TYPE=InnoDB;
+
+--CREATE OR REPLACE PROCEDURE add_user_right (name VARCHAR, new_right VARCHAR) AS
+--	user_id		"user".user_id%TYPE;;
+--	user_is_missing	EXCEPTION;;
+--BEGIN
+--	SELECT user_id INTO user_id FROM "user" WHERE user_name = name;;
+--	INSERT INTO user_groups (ug_user, ug_group) VALUES(user_id, new_right);;
+--EXCEPTION
+--	WHEN NO_DATA_FOUND THEN
+--		DBMS_OUTPUT.PUT_LINE('The specified user does not exist.');;
+--END add_user_right;;
+--;
+--
+--CREATE OR REPLACE PROCEDURE add_interwiki (prefix VARCHAR, url VARCHAR, is_local NUMERIC) AS
+--BEGIN
+--	INSERT INTO interwiki (iw_prefix, iw_url, iw_local) VALUES(prefix, url, is_local);;
+--END add_interwiki;;
+--;
+
+CREATE OR REPLACE FUNCTION add_interwiki (text, text, integer) RETURNS INTEGER AS '
+INSERT INTO interwiki (iw_prefix, iw_url, iw_local) VALUES ($1,$2,$3);;
+SELECT 1;;
+' LANGUAGE 'sql'
+;
Index: skins/MonoBook.php
===================================================================
RCS file: /cvsroot/wikipedia/phase3/skins/MonoBook.php,v
retrieving revision 1.70
diff -U5 -r1.70 MonoBook.php
--- skins/MonoBook.php	2 Dec 2005 02:41:48 -0000	1.70
+++ skins/MonoBook.php	4 Dec 2005 17:00:24 -0000
@@ -68,10 +68,21 @@
 		<?php if($this->data['pagecss'   ]) { ?><style type="text/css"><?php              $this->html('pagecss'   ) ?></style><?php    } ?>
 		<?php if($this->data['usercss'   ]) { ?><style type="text/css"><?php              $this->html('usercss'   ) ?></style><?php    } ?>
 		<?php if($this->data['userjs'    ]) { ?><script type="<?php $this->text('jsmimetype') ?>" src="<?php $this->text('userjs'    ) ?>"></script><?php } ?>
 		<?php if($this->data['userjsprev']) { ?><script type="<?php $this->text('jsmimetype') ?>"><?php      $this->html('userjsprev') ?></script><?php   } ?>
 		<?php if($this->data['trackbackhtml']) print $this->data['trackbackhtml']; ?>
+    <?php if($this->data['globalcss']) print $this->data['globalcss']; ?>
+
+	<!-- google analytics test. according to google, no personal information is collected -->
+	<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
+	    </script>
+	        <script type="text/javascript">
+		    _uacct = "UA-69618-1";
+		        urchinTracker();
+			</script>
+
+
 	</head>
 	<body <?php if($this->data['body_ondblclick']) { ?>ondblclick="<?php $this->text('body_ondblclick') ?>"<?php } ?>
 				<?php if($this->data['body_onload'    ]) { ?>onload="<?php     $this->text('body_onload')     ?>"<?php } ?>
 				<?php if($this->data['nsclass'        ]) { ?>class="<?php      $this->text('nsclass')         ?>"<?php } ?>>
 		<div id="globalWrapper">
Index: skins/monobook/main.css
===================================================================
RCS file: /cvsroot/wikipedia/phase3/skins/monobook/main.css,v
retrieving revision 1.83
diff -U5 -r1.83 main.css
--- skins/monobook/main.css	3 Dec 2005 16:51:25 -0000	1.83
+++ skins/monobook/main.css	4 Dec 2005 17:00:35 -0000
@@ -1165,11 +1165,13 @@
 }
 span.unpatrolled {
 	font-weight: bold;
 	color: red;
 }
-
+span.searchrelevance {
+    color: green;
+}
 span.searchmatch {
 	color: red;
 }
 .sharedUploadNotice {
 	font-style: italic;
