protected static function _initStaticProperties()
    {
        if (self::$_dbConn) {
            return;
        }
        \PFXUtils::validateSettings(self::$_SETTINGS, self::$_SETTING_TESTS);
        /* Since we use the OAuth back end for authentication, and it
           (optionally) uses the database, we can piggyback off its credentials if
           provided. This isn't enforced because some subclasses may be built to
           work correctly with no database connection. */
        if (OAUTH_DB_DSN) {
            self::$_dbConn = \PFXUtils::getDBConn(OAUTH_DB_DSN, OAUTH_DB_USER, OAUTH_DB_PASSWORD);
            /* This table used to pertain only to the Google Analytics back
               end, but then it became obvious that it was more generally useful.
               I retained the old name simply because it created more hassle than
               necessary to change it. */
            self::$_DB_STATEMENTS['google_analytics_api_fetch_log'] = array();
            $q = <<<EOF
INSERT INTO google_analytics_api_fetch_log
(entity, etag, result_count, fetch_date)
VALUES
(:entity, :etag, :result_count, UNIX_TIMESTAMP())
EOF;
            self::$_DB_STATEMENTS['google_analytics_api_fetch_log']['insert'] = self::$_dbConn->prepare($q);
            $q = <<<EOF
SELECT * FROM google_analytics_api_fetch_log
WHERE entity = :entity
ORDER BY id DESC
LIMIT 1
EOF;
            self::$_DB_STATEMENTS['google_analytics_api_fetch_log']['select'] = self::$_dbConn->prepare($q);
        }
    }
 public static function setUpBeforeClass()
 {
     \PFXUtils::validateSettings(array('TEST_DB_DSN' => null, 'TEST_DB_USER' => null, 'TEST_DB_PASSWORD' => null, 'TEST_DB_DBNAME' => null, 'TEST_DB_SCHEMA_HISTORY' => null, 'TEST_DB_SCHEMA_DIRECTORY' => null, 'TEST_DB_BINARY' => null, 'TEST_IGNORE_DB' => false), array('TEST_DB_DSN' => 'str', 'TEST_DB_USER' => 'str', 'TEST_DB_PASSWORD' => 'str', 'TEST_DB_DBNAME' => 'str', 'TEST_DB_SCHEMA_HISTORY' => '?file', 'TEST_DB_SCHEMA_DIRECTORY' => '?string', 'TEST_DB_BINARY' => 'executable'));
     self::$_dbConn = \PFXUtils::getDBConn(TEST_DB_DSN, TEST_DB_USER, TEST_DB_PASSWORD);
     /* If we're ignoring the database, we can bail out now that we have
        satisfied PHPUnit's requirements about what this class has to set up.
        */
     if (TEST_IGNORE_DB) {
         return;
     }
     // Make sure the database is empty first
     $stmt = self::$_dbConn->query('SHOW TABLES');
     if ($stmt->fetch()) {
         throw new \RuntimeException('Cannot execute a test case against a non-empty database.');
     }
     printf('Running scripts against test database %s...%s', TEST_DB_DBNAME, PHP_EOL);
     /* This opens a security hole if the test database user's password is
        sensitive, which it really shouldn't be. */
     $cmd = sprintf('%s %s --user=%s --password=%s', TEST_DB_BINARY, TEST_DB_DBNAME, TEST_DB_USER, TEST_DB_PASSWORD);
     $scripts = array();
     if (TEST_DB_SCHEMA_HISTORY) {
         $fh = fopen(TEST_DB_SCHEMA_HISTORY, 'r');
         $baseDir = dirname(TEST_DB_SCHEMA_HISTORY);
         while ($line = fgets($fh)) {
             $scripts[] = $baseDir . DIRECTORY_SEPARATOR . trim($line);
         }
     }
     if (TEST_DB_SCHEMA_DIRECTORY) {
         // Treat this as a comma-delimited list of directories
         $directories = explode(',', TEST_DB_SCHEMA_DIRECTORY);
         foreach ($directories as $dir) {
             $dir = trim($dir);
             if ($dir[0] != '/') {
                 $dir = realpath(__DIR__ . '/../../schemata') . '/' . $dir;
             }
             $dirH = opendir($dir);
             if ($dirH === false) {
                 throw new RuntimeException('Failed to open the directory ' . $dir . ' for reading.');
             }
             while (false !== ($entry = readdir($dirH))) {
                 $fullPath = $dir . '/' . $entry;
                 if (!is_dir($fullPath)) {
                     $scripts[] = $fullPath;
                 }
             }
             closedir($dirH);
         }
     }
     foreach ($scripts as $script) {
         system($cmd . ' < ' . $script, $returnVal);
         if ($returnVal) {
             throw new \RuntimeException('Execution of database script ' . $script . ' failed ' . 'with exit code ' . $returnVal . '.');
         }
     }
     printf('Done.%s', PHP_EOL);
 }
Example #3
0
 /**
  * Dispatches to methods that handle various requirements of a first
  * instantiation.
  */
 protected static function _initStaticProperties()
 {
     self::_validateSettings();
     // The database functionality is optional
     if (OAUTH_DB_DSN) {
         self::$_dbConn = \PFXUtils::getDBConn(OAUTH_DB_DSN, OAUTH_DB_USER, OAUTH_DB_PASSWORD);
         self::_initDBStatements();
         self::_destroyExpiredTokens();
     }
     self::$_staticPropsReady = true;
 }
 /**
  * Tests PFXUtils::getDBConn().
  */
 public function testGetDBConn()
 {
     $db = PFXUtils::getDBConn(TEST_DB_DSN, TEST_DB_USER, TEST_DB_PASSWORD);
     $this->assertInstanceOf('PDO', $db);
     // The DB connection should throw exceptions on errors
     $this->assertThrows('PDOException', array($db, 'query'), array('SELECT foo FROM bar'));
     /* Subsequent calls with the same credentials and attributes should
        return the same connection instance. */
     $this->assertSame($db, PFXUtils::getDBConn(TEST_DB_DSN, TEST_DB_USER, TEST_DB_PASSWORD));
     $db2 = PFXUtils::getDBConn(TEST_DB_DSN, TEST_DB_USER, TEST_DB_PASSWORD, array(PDO::ATTR_CASE => PDO::CASE_LOWER));
     $this->assertNotSame($db, $db2);
     $this->assertSame($db2, PFXUtils::getDBConn(TEST_DB_DSN, TEST_DB_USER, TEST_DB_PASSWORD, array(PDO::ATTR_CASE => PDO::CASE_LOWER)));
 }