root > WikiSense-trunk > common > WSDatabaseTest.php

WSDatabaseTest.php

application/x-php, 7997 bytes (load raw)
<?php
if (!defined("WS_CONSOLE")) die("bad entry point!");

require_once("WSTest.php");

class WSDatabaseTest extends WSTest {
        function WSDatabaseTest( $dburl ) {
            WSTest::WSTest();
            $this->dburl= $dburl;
        }
       
        function setup() {
            $this->db= openConnection( $this->dburl );
        }
       
        function teardown() {
            if (!$this->db) return;
           
            $this->db->close();
            $this->db= NULL;
        }
       
        function loadDB($file, $truncate=true) {
            if ($truncate) $this->dict->truncateAll();
           
            #$f= dirname(__FILE__).'/'.$file;
            $f= $file;
           
            preg_match('!\.([^/.]+)$!',$f,$m);
            $ext= $m[1];
           
            if (!file_exists($f)) {
                $this->internalError("Data file not found: $f");
                return false;
            }
           
            if ($ext=='tsv') $this->tsv2db($f);
            else if ($ext=='sql') $this->sql2db($f);
            else {
                $this->internalError("Unknown data file extension: $ext");
                return false;
            }
        }
       
        function assertDB($file, $truncate=true) {
           
            #$f= dirname(__FILE__).'/'.$file;
            $f= $file;
           
            preg_match('!\.([^/.]+)$!',$f,$m);
            $ext= $m[1];
           
            if (!file_exists($f)) {
                $this->internalError("Data file not found: $f");
                return false;
            }
           
            if ($ext=='tsv') return $this->tsv2db($f, true);
            else {
                $this->internalError("Unknown data file extension: $ext");
                return false;
            }
           
            if ($truncate) $this->dict->truncateAll();
        }
       
        function tsv2db($file, $inverse = false) {
            $eof= false;
            $f= fopen($file,'r');
           
            if (!$f) {
                $this->internalError("failed to open data file $file");
                return false;
            }

            $tables= array();
            $ok= true;
                       
            $line= 0;
            $table= NULL;
            $fields= NULL;
            $head= false;
            while (1) {
                $s=fgets($f);
                $line+= 1;
               
                if ($s===false || $s===NULL || $s==='') $eof= true;
                if ($eof) break;
               
                $s= preg_replace('/^ +| *[\r\n]*$/','',$s);
                if (trim($s)==='') continue;
               
                if (preg_match('/^\s*\[([^\]\t]+)\]\s*$/',$s,$m)) {
                    $table= trim($m[1]);
                    $head= true;
                    $fields= NULL;
                    continue;
                }
                else if ($head) {
                    $fields= explode("\t", $s);
                    $tables[$table]= $fields;
                    $head= false;
                }
                else {
                    if (!$fields) {
                        $this->internalError("$file [$line]: missing table header: $table\n$s");
                        fclose($f);
                        return false;
                    }
               
                    $data= explode("\t", $s);
                   
                    if (sizeof($data) != sizeof($fields)) {
                        $this->internalError("$file [$line]: bad number of fields: expected ".sizeof($fields).", found ".$sizeof($data)."\n$s");
                        fclose($f);
                        return false;
                    }
                   
                    $data= array_combine($fields, $data);
                    $data= $this->decodeFields($data);
                   
                    if ($inverse) {
                        $c= $this->deleteRow($table, $data, 'tsv2db');
                         
                        if (!$c) {
                            $this->assertionError("missing row in table $table: ".wsfToString($data));
                            $ok= false;
                        }                                       
                    }
                    else $this->insertRow($table, $data, 'tsv2db');
                }
               
                $head= false;
            }
           
            fclose($f);
           
            if ($inverse && $tables) {
                foreach ($tables as $t => $f) {
                    $f= implode(', ', $f);
                    $res= $this->db->query("SELECT $f FROM $t");
                    while ($row= $this->db->fetchRow($res)) {
                        $this->assertionError("found leftover row in $t: ".wsfToString(wsfStripIntKeys($row)));
                        $ok= false;
                    }
                    $this->db->freeResult($res);
                }
            }
           
            return $ok;
        }
       
        function insertRow( $table, $data, $func = 'TEST::insertRow' ) {
             $this->dict->db->insert($table, $data, $func);
        }

        function makeSqlConditions( &$values, $op = 'AND' ) {
            $row= '';
            $first= true;
     
            foreach ($values as $k => $v) {
           
                if ($row !== '') $row.= ' '.$op.' ';
                $row.= $k;
               
                if ($v === NULL) $row.= ' IS NULL';
                else {
                    $row.= ' = ';
                   
                    if (is_int($v)) $row.= $v;
                    else if (is_float($v)) $row.= $v;
                    else if ($v===false) $row.= '0';
                    else if ($v===true) $row.= '1';
                    else $row.= $this->db->addQuotes($v);
                }
            }
           
            return $row;
        }
       
        function deleteRow( $table, $data, $func = 'TEST::deleteRow' ) {
                if (!is_string($data)) $data= $this->makeSqlConditions( $data );
               
                $sql = "DELETE FROM $table  WHERE $data";
                $sql.= " LIMIT 1";
                #print "***$sql***\n";
                $ok= $this->db->query( $sql, $func );
                return $this->db->affectedRows();
        }

        function sql2db($file) {
            $eof= false;
            $f= fopen($file,'r');
           
            if (!$f) {
                $this->internalError("failed to open data file $file");
                return false;
            }
           
            $line= 0;
            $query= '';
            while (1) {
                $s=fgets($f);
                $line+= 1;
               
                if ($s===false || $s===NULL || $s==='') $eof= true;
                $s= trim($s);
               
                if ($s=='' || $eof) {
                    if ($query) $this->dict->db->query($query, 'sql2db');
                    $query= '';
                   
                    continue;
                }
               
                if ($eof) break;
               
                $statement.= $s;
            }
           
            fclose($f);
        }
 
        function assertRowCountWhere($table, $where, $exp, $msg) {
            $val= $this->countRows($table, $where);
           
            if ($val==$exp)  return true;
           
            $this->assertionError("( found $val rows, expected $exp )", $msg);
            return false;
        }       
             
        function countRows($table, $where) {
            if (!is_string($where)) $where= $this->db->makeList( $where, LIST_AND );
            $sql= "SELECT COUNT(*) FROM $table WHERE $where";
            $res= $this->db->query($sql, "assertRowCountWhere");
            $row= $this->db->fetchRow($res);
            $val= $row[0];
            $this->db->freeResult($res);
           
            return $val;
        }       
             
}
?>