An issue of timing

For the Microsoft SQL Server version of the MediaWiki engine (at version 1.13 or so), everything was working except the Special:WantedPages and Special:AllPages. With the new design of Special:AllPages, I can't make heads or tails out of the SQL being generated, so I just reverted to the old behavior and it's fine. Special:WantedPages was different. The SQL was fine, but as the size of the wiki has grown (closing in on 200,000 articles), the database server was timing out before returning any results to the PHP. This problem was relatively easy to fix, using a not-widely-known property of the ADO Connection object, Connection::CommandTimeout. The default for Connection::CommandTimeout is 30 seconds, and no results were being returned for the (expensive) query until about 35 seconds or so. Once a row comes back from the server, ADO doesn't care how much time it takes to complete the query, but it's pretty sensitive to how long it takes for results to START coming back. I went into the ADOdb connector code and in the file adodb-ado5.inc.php added right before the return from the method ADODB_ado::_connect the single line
   $dbc->CommandTimeout = 90;
Although this fixed the timeout problem, it brought out a latent problem. For the Special pages that return true from QueryPage::isExpensive, some of them -- including this one -- were trying to cache the results in a temporary table. This clashed with ADOdb's handling of OFFSET and LIMIT clauses in the SQL, so I have disabled the caching of results from "expensive" Special pages by not performing any activity in the overriden QueryPage::preProcessResults methods for these pages (Special:ShortPages, Special:LongPages, and Special:WantedPages in particular). Down the road, perhaps I'll think of a slightly more clever way to handle SQL OFFSET and LIMIT clauses and I can re-enable the preProcessResults methods.


Another recommended change for ADODB

I'm trying to minimize the number of changes needed to the wiki code, which is still fairly indecisive about retrieving data from the database via column names or column numbers. To make things as simple as possible, I set the fetch mode to ADODB_FETCH_BOTH rather than toggling back and forth between ADODB_FETCH_ASSOC and ADODB_FETCH_NUM, as I had been doing in the past. To make this work right, you'll need to make a change to the file adodb-ado5.inc.php. Change line 654 from
$this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE);
to read
$this->fields = array_merge($this->fields, $this->GetRowAssoc(ADODB_ASSOC_CASE));
Having done this, you'll have an array with both numeric keys and string keys.


MediaWiki 1.13 and ADOdb 5.05

As of today, MediaWiki at approximately the 1.13 level is working while using the new ADOdb library that was released on 11 July 2008. I say approximately 1.13 because I actually work with the MediaWiki edge code from SubVersion, which is now identified as 1.14alpha. Far fewer changes are required these days to keep everything humming along. Thanks to MediaWiki guru "Simetrical" for incorporating some of my recommended changes, since I still don't have commit access to the shared repository. Very minor changes were required to the ADOdb library, very similar to the changes that I'd made to the 4.94 release that I had been using. These changes are actually very simple. First, after downloading and unzipping adodb5.05, find the file ./adodb.inc.php and change line 954 from
$array_2d = is_array($element0) && !is_object(reset($element0));
to read just
$array_2d = is_array($element0);
. If you don't make that change, you'll see error messages whenever you try to save a new article in your wiki. The last part of that statement apparently has to do with something unique to oci8 (Oracle?) descriptors, but wreaks havoc when used in conjunction with SQL Server. Second, also in ./adodb.inc.php, you'll need to modify the function FetchObject. MediaWiki code always expects objects returned from the database to have attributes named with all-lowercase letters. To make that happen, change line 3571 from
function FetchObject($isupper=true)
function FetchObject($isupper=false)
and change line 3588 from
else $n = $name;
else $n = strtolower($name);
. Without that change, you'll witness lots of member not found error messages. Third, in ./drivers/adodb-ado_mssql.inc.php, you'll have to change line 49 from
return $this->GetOne('select SCOPE_IDENTITY()');
return $this->GetOne('select @@IDENTITY');
or you'll get NULL for the last ID used after inserts. Finally, to get the various pagers to work, you'll have to modify ./drivers/adodb-ado5.inc.php around line 423. Change the code from
       if ($this->_currentRow > $row) return false;
       @$rs->Move((integer)$row - $this->_currentRow-1); //adBookmarkFirst
       $fReturn = $rs->Supports( 0x200 /*adMovePrevious*/ );
       if (! $fReturn )
          return false;
       if ( $row == 0 ) {
       } else {
           @$rs->Move((integer)$row - $this->_currentRow-1); //adBookmarkFirst
      $this->_currentRow = $row;
Without that change, most of the special pages won't work. Note that SQL Server 2000 and SQL Server 2005 will both respond that they support adMovePrevious. That's it, the rest of the changes can be found attached to the MediaWiki BugZilla report 9767, or may become part of the MediaWiki code base. The main attachments of interest are the SQL code and the DatabaseADODB.php file. These are fairly up-to-date as I write this, although I've evolved my schema somewhat since uploading the SQL code. It generally falls a little behind because I make the schema changes through Microsoft SQL Server Management Studio and then wind up reverse-engineering those changes into the SQL file.


Getting ready to go into production

Things have come a long way since my last post. The wiki has been running continuously on a test box for a couple of months with no major glitches. It is now based on version 1.12, but is running on SQL Server 2005 instead of SQL Server 2000. Everything works except for images that have funny characters in the names. Even those sort of work (the thumbnails get generated and stored in the appropriate place), but IIS 6 seems unable to server the files from there. The code is stable enough so the boss has decided to put the thing into production. There's still some pieces in this screenshot that show some of the parts of the wiki that are still in development (The collaboration box shows some debugging messages from the presence / chat server). The screw behind the logo means that this is the development version and won't be in the production version.