Location: PHPKode > projects > DIY Blog > diy-blog/lib/creole/test/classes/creole/drivers/DriverTestManager.php
<?php

include_once 'creole/Creole.php';
include_once 'creole/util/sql/SQLStatementExtractor.php';

/**
 * A static class to help out with executing tests for each driver.
 *
 *
 * @author Hans Lellelid <hide@address.com>
 * @version $Revision: 1.16 $
 */
class DriverTestManager {

    protected static $dsn;
    protected static $conn;

    protected static $schemaStatements;
    protected static $dataStatements;

    protected static $domExchanges;
    protected static $xpExchanges;

    // Look for driver versions of the following classes, if found, add them.
    protected static $driverClasses = array('Connection', 'ResultSet', 'PreparedStatement', 'CallableStatement', 'IdGenerator', 'Statement', 'DatabaseInfo', 'TableInfo');

    public static function setDriverClasses($classes) {
        self::$driverClasses = $classes;
    }

    public static function setDSN($dsn) {
        if (is_string($dsn)) {
            $dsn = Creole::parseDSN($dsn);
        }
        self::$dsn = $dsn;
    }

    public static function getDSN() {
        return self::$dsn;
    }

    public static function getConnection() {
        return self::$conn;
    }

    public static function connect() {
        self::$conn = Creole::getConnection(self::$dsn, Creole::COMPAT_ASSOC_LOWER);
    }

    public static function init() {
        self::connect();
        self::loadStatements();
        self::initDb(self::$conn);
        if (self::$domExchanges === null) {
            self::$domExchanges = new DomDocument();
            self::$domExchanges->load(CREOLE_TEST_BASE . '/etc/exchanges.xml');
            self::$xpExchanges = new DomXPath(self::$domExchanges);
        }
    }

    /**
     * Call this method to destroy and re-create the tables in the db.
     */
    public static function restore() {
        $dsn = self::$conn->getDSN();
        $flags = self::$conn->getFlags();
        self::$conn->close();
        self::$conn->connect($dsn, $flags);
        self::initDb(self::$conn);
    }

    /**
     * Loads & parses the schema SQL files.
     */
    protected static function loadStatements()
    {
        $schema = CREOLE_TEST_BASE . '/etc/db/sql/' . self::$dsn['phptype'] . '/creoletest-schema.sql';
        $data = CREOLE_TEST_BASE . '/etc/db/sql/' . self::$dsn['phptype'] . '/creoletest-data.sql';
        self::$schemaStatements = SQLStatementExtractor::extractFile($schema);
        self::$dataStatements = SQLStatementExtractor::extractFile($data);
    }

    /**
     * Method that loads, parses, and executes the schema files.
     */
    public static function initDb(Connection $conn) {
        self::runStatements(self::$schemaStatements, $conn);
        self::runStatements(self::$dataStatements, $conn);
    }

    /**
     * Executes the passed SQL statements.
     */
    protected static function runStatements($statements, Connection $conn) {
        $stmt = $conn->createStatement();
        foreach($statements as $sql) {
            // print "Executing : $sql \n";
            try {
                $stmt->execute($sql);
            } catch (Exception $e) {
				if (!stripos($e->getMessage(), "drop table")) {
				    print "Error executing SQL: " . $sql . "\n";
                	print $e->getMessage() . "\n";
                	print "=== Attempting to continue === \n";
				}
               
            }
        }
    }

    /**
     * Main worker function.  Adds any available tests to the passed in suite.
     *
     */
    public static function addSuite(PHPUnit2_Framework_TestSuite $parentSuite, $dsn) {

        self::setDSN($dsn);

        // initialize db
        self::init();

        $c = self::$conn;

        // get just the first part of class name (e.g. MySQL from MySQLConnection)
        $camelDriver = str_replace('Connection', '', get_class($c));

        $suite = new PHPUnit2_Framework_TestSuite($camelDriver);

        foreach(self::$driverClasses as $baseClass) {
            // include the test class, based on driver name
            // do we want many?  Let's start by assuming that we'll fit all this in one class.
            $classname = $camelDriver . $baseClass . 'Test';
            $path = 'creole/drivers/' . self::$dsn['phptype'] . '/'. $classname . '.php';
            if (file_exists(CREOLE_TEST_BASE . '/classes/' . $path)) {
                include_once $path;
                if (class_exists($classname)) {
                    $suite->addTestSuite(new ReflectionClass($classname));
                }
            }
        }

        $parentSuite->addTest($suite);

    }


    /**
     * Get an "Exchange" -- which is a query + answer for current RDBMS.
     *
     * @return DBExchange Populated db exchange object.
     */
    public static function getExchange($id) {

        $matches = self::$xpExchanges->query("/exchanges/exchange[@id='".$id."']");

        if (!$matches) {
            print "XPath query matched no nodes: /exchanges/exchange[@id='".$id."']";
            throw new SQLException("XPath query matched no nodes: /exchanges/exchange[@id='".$id."']");
        }

        // otherwise grab first match (there should be only one match)
        $result = is_array($matches) ? $matches[0] : $matches->item(0);

        $exchange = new DBExchange(); // this is the object we send back

        // We know there is a <sql> node
        $sqlNodes = $result->getElementsByTagName("sql");
        // temporary, so we can run this on PHP5b2
        if (is_array($sqlNodes)) $sqlNode = $sqlNodes[0]; else $sqlNode = $sqlNodes->item(0);

        $sql = $sqlNode->nodeValue; // default is to use value of <sql> node.

        // but there may also be a variant for current RDBMS ....
        $variantNodes = $result->getElementsByTagName("sql-variant");
        if ($variantNodes) {
            foreach($variantNodes as $variantNode) {
                if ($variantNode->attributes["id"]->value === self::$dsn['phptype']) {
                    $sql = $variantNode->nodeValue;
                    break;
                }
            }
        }

        $exchange->setSql($sql);

        // now get the result, if any
        $resultNodes = $result->getElementsByTagName("result");
        if ($resultNodes) {
            // temporary, so we can run this on PHP5b2
            $resultNode = is_array($resultNodes) ? $resultNodes[0] : $resultNodes->item(0);
            if ($resultNode) {
                $exchange->setResult($resultNode->nodeValue);
            }
        }

        return $exchange;
    }
}


/**
 * "Inner" class that encapsulates database exchange: query + answer.
 *
 */
class DBExchange {

    private $sql;
    private $res;

    public function setSql($sql) {
        $this->sql = $sql;
    }

    public function getSql() {
        return $this->sql;
    }

    public function setResult($res) {
        $this->res = $res;
    }

    public function getResult() {
        return $this->res;
    }
}
Return current item: DIY Blog