Blog

  • Continuing MediaWiki development

    No fresh download quite yet, but I just made a large commit to the MediaWiki source of the last week’s work. This is going in the trunk — aka MediaWiki 1.16alpha. There are a few bugs I hope to catch this weekend, at which point I’ll put up a fresh archive of working code.

    config/index.php:
    * Made installation on IBM DB2 more robust
    * Replaced E_ALL error reporting mode with E_ALL | E_STRICT

    includes/db/DatabaseIbm_db2.php
    * Enabled DB2_CASE_LOWER option for all connections and statements
    * Enabled DB2_DEFERRED_PREPARE_ON for all statements — delays statement preparation until execution to reduce database load
    * Enabled DB2_ROWCOUNT_PREFETCH_ON for all statements — makes db2_num_rows() work correctly
    * Cleaned up error handling
    * Cleaned up method signatures
    * Rewrote insertion to use prepared statements — required for inserting more than 32k of text
    * Insertion will never try to insert a NULL value into a primary key
    * Now relying on implicit casting in DB2 9.7 — no longer sniffing to see if column is integer or string before adding quotes
    * Implemented actual prepared statement handling — required for correct INSERT, UPDATE behaviour
    * In install mode, the class will print additional messages to the install bullet scroll
    * Added bitwise operation abstraction (BITNOT, BITAND, BITOR)

    includes/specials/SpecialAncientpages.php
    * Added skeleton DB2 syntax to the database-specific switch statement

    maintenance/convertLinks.inc
    * Made limit clause database-agnostic

    maintenance/ibm_db2/README
    * Contents replaced with link to http://www.mediawiki.org/wiki/Manual:IBM_DB2

    maintenance/ibm_db2/tables.sql
    * Revised types to better match the main schema
    * All tables names now the same as MySQL — was using Postgres schema’s names before
    * Added some additional indices
    * Added the change_tag, tag_summary, valid_tag, user_properties, log_search, and l10n_cache tables
    * Added several new columns

    maintenance/storage/compressOld.inc
    * Made limit clause database-agnostic

  • Changing the DB2 hostname

    SQL6031N  Error in the db2nodes.cfg file at line number "1".  Reason code "10".

    DB2 caches your machine’s hostname in several places. If your machine is changing its hostname, or if you are somehow moving an existing installation to a machine with a different hostname, you will need to adjust the hostname stored by DB2. Hostname change is common in virtual and cloud environments, so even better than adjusting it would be writing a script that adjusts it for you.

    Here’s my rudimentary stab at a such a script:

    #!/bin/sh
    echo -n "Discovering the new hostname "
    UNAME_CACHE=$(uname -n)
    
    echo -n "Adjusting hostname list for unconfigured database partitioning feature "
    # this may need to be changed if DPF preconfigured
    if [ -e /home/db2inst1/sqllib/db2nodes.cfg ]; then
        chmod 666 /home/db2inst1/sqllib/db2nodes.cfg
        su - db2inst1 -c "cp /home/db2inst1/sqllib/db2nodes.cfg /home/db2inst1/sqllib/db2nodes.cfg.old"
        su - db2inst1 -c "echo 0 $UNAME_CACHE 0 > /home/db2inst1/sqllib/db2nodes.cfg"
    fi
    
    echo -n "Making registry writable "
    chmod 666 /var/db2/*
    
    echo -n "Adjusting the DB2 hostname "
    UNAME_CACHE=$(uname -n)
    /opt/ibm/db2/V9.7/adm/db2set -g db2system=$UNAME_CACHE
    
    echo -n "Updating DAS configuration "
    # todo
    # db2 uncatalog node 
    db2 catalog admin tcpip node $UNAME_CACHE remote $UNAME_CACHE system $UNAME_CACHE
    db2 update admin cfg using DB2SYSTEM $UNAME_CACHE
    db2 update admin cfg using SMTP_SERVER $UNAME_CACHE
    

    This doesn’t cover all cases. For example, if you use extended operating system security, you may also need to set the db2accountname and db2instowner parameters. A quick check with db2set -all should tell you if this applies in your case — if there is something that looks like a hostname in those parameters already, you need to change them.

    I may also have missed other necessary changes. Please let me know if I did.:-)

    References

  • Oracle kills Virtual Iron

    Only 5 weeks from acquisition to death. No more licenses for existing customers, either. Harsh.

  • DB2 data movement tool

    The DB2 data movement tool sounds like an excellent way to move stuff from, say, MySQL to DB2. I should see if I can use it to move a MediaWiki database.

    Speaking of MediaWiki, I swear I’ll have a patched zip of 1.15 ready any day now.:-)

  • setTimeout() require qualification

    The two javascript functions above are very useful. The first one executes something after a set delay, and the second executes something at regular intervals. The syntax is very similar.

    var time = 2000; // 2 seconds
    window.setTimeout(function() { alert('Yay!'); }, time);
    window.setInterval(function() { alert('Woo!'); }, time);
    

    Unfortunately, they weren’t working for me earlier. It turns out I wasn’t fully-qualifying them. Specifically, I was calling setTimeout() rather than window.setTimeout(). The latter works.

    Most examples use the abbreviated form, which consistently doesn’t work for me.

  • DB2

    I now edit the Computers: Software: Databases: IBM DB2 category at dmoz.org open directory project.

    Directories used to be important in the mid-1990s, as they tended to provide better search results than dumb link crawlers like Altavista. Yahoo started off as a human-edited hierarchical directory of links and adopted the crawler approach later.

    However, since Google has come along with a better search algorithm, directories are in decline. dmoz is the only major one left, and this hasn’t escaped the notice of SEO folk, who chase the prestigious linkback and fill the submission queue with a lot of crud.

    Feel free to suggest a URL for inclusion.:-)

  • DB2 and usernames with spaces

    DB2 v9.5 uses the Windows username as the default schema. Unfortunately, it does not support spaces in schema names. Accordingly, usernames – e.g. “Jane Smith” — that have a space can make DB2 unhappy.

    I recently helped someone resolve an issue with this command:

    db2sampl -force -name SAMPLE
    

    Which brought up this error:

    
      Creating database "SAMPLE"...
      Connecting to database "SAMPLE"...
      Creating tables and data in schema "JANE SMITH"...
    
    --ERROR----
      SQLSTATE = 42601
      Native Error Code = -443
    
    [IBM][CLI Driver][DB2/NT64] SQL0443N  Routine "*L_SAMPLE" (specific name "") has  returned an error SQLSTATE with diagnostic text "SQLSTATE 42601: A character,  token, or clause is invalid or". SQLSTATE=42601
    --
    
      Creating tables with XML columns and XML data in schema "JANE SMITH"...
    
    --ERROR----
      SQLSTATE = 42601
      Native Error Code = -443
    
    [IBM][CLI Driver][DB2/NT64] SQL0443N  Routine "*L_SAMPLE" (specific name "") has  returned an error SQLSTATE with diagnostic text "SQLSTATE 42601: A character,  token, or clause is invalid or". SQLSTATE=42601
    --
    
      'db2sampl' processing complete.
    

    The full routine name is CREATE_SQL_SAMPLE. It tries to create tables for Jane Smith, fails, and blazes bravely on. Interestingly, an empty database results.

    The workaround is to log in as a user without a space, such as “db2admin”, run db2sampl, and then log back in as yourself.

    For running future queries, you can specify a different schema:

    SET SCHEMA=db2admin;
    

    And, of course, you can always explicitly specify a schema in your queries:

    SELECT * FROM db2admin.tablename;
    
  • Dynamic playlists in MusikCube

    On Windows, my music player of choice is musikCube. It’s fast, clean, elegant, and powerful. Oh, and it has an embedded SQL engine underlying its song library.

    musikCube in action

    It has conventional playlists, but it also has dynamic playlists based on queries of the underlying SQL database. For example, this query gives the Top 10 Most Played songs:

     timesplayed > 0  ORDER BY timesplayed DESC  LIMIT 10
    

    And this gives 50 songs with a rating of 4 stars or better in random order:

     rating > 3 ORDER BY random() LIMIT 50
    

    Once created, a dynamic playlist is only a mouseclick away.

    The documentation is incomplete, but the database schema is easy to look up by saving a copy of the library and opening it up with a tool like sqliteman:

    musikCube database schema

    I wanted to subdivide my music into playlists, and then find any song not on a custom playlist. A query similar to this did the trick:

    songid NOT IN (
      SELECT songid
      FROM std_playlist_song
      WHERE std_playlist_id IN (
        SELECT std_playlist_id
        FROM std_playlist
        WHERE std_playlist_name IN ('Gnarly', 'Radical', 'Tubular')
    ))
    

    It finds every song not added to the Gnarly, Radical, or Tubular static playlist. Using this, I finally got my music library sorted and organized.

  • Update Symantec without an uninstall password

    I had to update an old XP Home test machine to run the latest Symantec Suite of Crap. Installation of new Symantec stuff requires a manual uninstall of old Symantec stuff. Here, I ran into a problem — it prompted for an “uninstall password”.

    The default password is “symantec”, but that wasn’t my issue.

    Apparently, whenever an old version of the Symantec corporate authentication server is taken offline, the automatic uninstall password process verification is broken, and it keeps prompting indefinitely.

    Open the registry editor (Start > Run > regedit) and navigate to:

    HKEY_LOCAL_MACHINESOFTWAREINTELLANDeskVirusProtect6CurrentVersionAdministrator OnlySecurityUseVPUninstallPassword

    Set it to 0. It will now not prompt for a password when uninstalling.

    Also look at this.

    HKEY_LOCAL_MACHINESOFTWAREINTELLANDeskVirusProtect6CurrentVersionAdministrator OnlySecurityLockUnloadServices

    Set it to 0 too. You’ll now be able to unload the service.

    Do a Start > Run > services.msc

    Scroll down to Symantec Antivirus, go into Properties > Recovery, and disable automatic reload.

    Now right-click to stop SavRoam and all the other Symantec services.

    You can now uninstall Symantec AntiVirus from the Add/Remove Programs control panel.

    Restart the computer. This resumes some necessary services.

    You can now install the updated Symantec product.

    Useful tools

    References

  • Disabling PHP in a specific directory

    To disable the PHP processor in a given directory, put the following in an .htaccess file. If one doesn’t exist, create it.

    # Disable PHP
    AddHandler default-handler php
    RemoveType application/x-httpd-php php
    
    # Make .php files display as plain text
    AddType text/plain php
    

    This assumes an Apache server. PHP on IIS may involve different steps.

    Files starting with a . are hidden by default on *nix OSes. To see them in listings, use ls -a.