#!/usr/bin/php
<?php
/*
    This simulates a problem I am having with Xapian/PHP/Ubuntu.  Reduced
    the problem down to this contrived example.
    
    PHP Error: DatabaseCorruptError: Data ran out unexpectedly when reading posting list.
    xapian-check Error: Extra bytes after key for first chunk of posting list for term
    
    The use case is similar to this:
    Many accounts with individual data to be indexed.  Using a handful of
    custom prefixes to do filtering when querying.  When an account is
    disabled, the records are purged from the XapianDatabase.
    
    Errors with:
        Ubuntu Hardy 8.04.1
        libxapian15 1.0.5  (Ubuntu current package)
        php5 5.2.4 (Ubuntu current package)

        -- Did an upgrade install to 1.0.7 and had same problems errors.

    Works fine under:
        Ubuntu Gutsy 7.10
        libxapian15 1.0.2 (Ubuntu current package)
        php5 5.2.3 (Ubuntu current package)
    
*/
require '/usr/share/php5/xapian.php';

$db_file = '/tmp/xapiantest';

try {

    /* Changing keys or values will give mixed results. */
    $recipe_for_fail = array (
      219 => 74,
      221 => 116,
      222 => 199,
      223 => 21,
      224 => 45,
      225 => 155,
      226 => 189,
    );

    $testdata = array ();
    $pos = 0;
    foreach ($recipe_for_fail as $value => $num)
    {
        $testdata += array_fill($pos, $num, $value);
        $pos += $num;
    }

    // Populate Xapian database
    $database = new XapianWritableDatabase($db_file, Xapian::DB_CREATE_OR_OPEN);
    foreach ($testdata as $value)
    {
        $doc = new XapianDocument();
        $doc->add_term('XC' . $value);
        $doc->add_term('XTabc');
        $doc->add_term('XAdef');
        $doc->add_term('XRghi');
        // Magic quantity, if you comment this, it wont error.
        $doc->add_term('XYabc');

        $database->add_document($doc);
    }
    $database = null;
    
    
    
    // Did not normally delete /all/ entries, however, in testing, this
    // gave more consistent results/error.
    // Also of note, in production dont actually open the DB twice, however
    // the error would show up on subsequent calls, doing the second open
    // in here to reproduce multiple calls in one pass.
    $database = new XapianWritableDatabase($db_file, Xapian::DB_CREATE_OR_OPEN);
    foreach (array_keys ($recipe_for_fail) as $value)
    {
        $database->delete_document('XC' . $value);
    }
    $database = null;

    // Running xapian check on DB shows the errors.  In normal use, the
    // database would work somewhat unless querying for one of the deleted
    // records.
    system("xapian-check $db_file");

    echo "Dont forget to remove the db file before next test. ($db_file)\n";
    //echo "Cleanup\n";
    //system("rm -Rf $db_file");

} catch (Exception $e) {
    print $e->getMessage() . "\n";
    exit(1);
}
