diff --git a/tests/RUNNING_TESTS.txt b/tests/RUNNING_TESTS.txt
index 59197acc0f..705fb28d07 100644
--- a/tests/RUNNING_TESTS.txt
+++ b/tests/RUNNING_TESTS.txt
@@ -43,6 +43,25 @@ will run phpunit with the same parameters as in the shown test_config.php file:
PHPBB_TEST_DBNAME='database' PHPBB_TEST_DBUSER='user' \
PHPBB_TEST_DBPASSWD='password' phpunit
+Special Database Cases
+----------------------
+In order to run tests on some of the databases that we support, it will be
+necessary to provide a custom DSN string in test_config.php. This is only needed for
+MSSQL 2000+ (PHP module), MSSQL via ODBC, and Firebird when PDO_Firebird does not work
+on your system (https://bugs.php.net/bug.php?id=61183). The variable must be named $custom_dsn.
+
+Examples:
+Firebird using http://www.firebirdsql.org/en/odbc-driver/
+$custom_dsn = "Driver={Firebird/InterBase(r) driver};dbname=$dbhost:$dbname";
+
+MSSQL
+$custom_dsn = "Driver={SQL Server Native Client 10.0};Server=$dbhost;Database=$dbname";
+
+The other fields in test_config.php should be filled out as you would normally to connect
+to that database in phpBB.
+
+Additionally, you will need to be running the DbUnit fork from https://github.com/phpbb/dbunit/tree/phpbb.
+
Running
=======
diff --git a/tests/test_framework/phpbb_database_connection_helper.php b/tests/test_framework/phpbb_database_connection_helper.php
new file mode 100644
index 0000000000..e1c50655ed
--- /dev/null
+++ b/tests/test_framework/phpbb_database_connection_helper.php
@@ -0,0 +1,24 @@
+driver = $dbms;
+ $this->version = (double)$version;
+
+ parent::__construct($dsn, $user, $pass);
+ }
+}
\ No newline at end of file
diff --git a/tests/test_framework/phpbb_database_test_case.php b/tests/test_framework/phpbb_database_test_case.php
index e742b543b0..0e5518fef8 100644
--- a/tests/test_framework/phpbb_database_test_case.php
+++ b/tests/test_framework/phpbb_database_test_case.php
@@ -28,6 +28,28 @@ abstract class phpbb_database_test_case extends PHPUnit_Extensions_Database_Test
);
}
+ public function createXMLDataSet($path)
+ {
+ $db_config = $this->get_database_config();
+
+ //Firebird requires table and column names to be uppercase
+ if($db_config['dbms'] == 'firebird')
+ {
+ $xml_data = file_get_contents($path);
+ $xml_data = preg_replace_callback('/(?:(
))/', 'phpbb_database_test_case::to_upper', $xml_data);
+ $xml_data = preg_replace_callback('/(?:())([a-z_]+)(?:(<\/column>))/', 'phpbb_database_test_case::to_upper', $xml_data);
+
+ $temp = tmpfile();
+ fwrite($temp, $xml_data);
+ fseek($temp, 0);
+
+ $meta_data = stream_get_meta_data($temp);
+ $path = $meta_data['uri'];
+ }
+
+ return parent::createXMLDataSet($path);
+ }
+
public function get_test_case_helpers()
{
if (!$this->test_case_helpers)
@@ -106,4 +128,9 @@ abstract class phpbb_database_test_case extends PHPUnit_Extensions_Database_Test
{
return new phpbb_database_test_connection_manager($config);
}
+
+ public static function to_upper($matches)
+ {
+ return $matches[1] . strtoupper($matches[2]) . $matches[3];
+ }
}
diff --git a/tests/test_framework/phpbb_database_test_connection_manager.php b/tests/test_framework/phpbb_database_test_connection_manager.php
index c734c90a1a..328d90fca9 100644
--- a/tests/test_framework/phpbb_database_test_connection_manager.php
+++ b/tests/test_framework/phpbb_database_test_connection_manager.php
@@ -8,6 +8,7 @@
*/
require_once dirname(__FILE__) . '/../../phpBB/includes/functions_install.php';
+require_once 'phpbb_database_connection_helper.php';
class phpbb_database_test_connection_manager
{
@@ -83,9 +84,37 @@ class phpbb_database_test_connection_manager
break;
}
+ //These require different connection strings on the phpBB side than they do in PDO
+ //so you must provide a DSN string for ODBC separately
+ if($this->config['dbms'] == 'mssql' || $this->config['dbms'] == 'firebird')
+ {
+ if(!empty($this->config['custom_dsn']))
+ {
+ $dsn = 'odbc:' . $this->config['custom_dsn'];
+ }
+ }
+
try
{
- $this->pdo = new PDO($dsn, $this->config['dbuser'], $this->config['dbpasswd']);
+ switch($this->config['dbms'])
+ {
+ case 'mssql':
+ case 'mssql_odbc':
+ $this->pdo = new phpbb_database_connection_ODBC_PDO_wrapper('mssql', 0, $dsn, $this->config['dbuser'], $this->config['dbpasswd']);
+ break;
+
+ case 'firebird':
+ if(!empty($this->config['custom_dsn']))
+ {
+ $this->pdo = new phpbb_database_connection_ODBC_PDO_wrapper('firebird', 0, $dsn, $this->config['dbuser'], $this->config['dbpasswd']);
+ break;
+ }
+ //Fall through if they're using the firebird PDO driver and not the generic ODBC driver
+
+ default:
+ $this->pdo = new PDO($dsn, $this->config['dbuser'], $this->config['dbpasswd']);
+ break;
+ }
}
catch (PDOException $e)
{
@@ -93,8 +122,7 @@ class phpbb_database_test_connection_manager
throw new Exception("Unable do connect to $cleaned_dsn using PDO with error: {$e->getMessage()}");
}
- // good for debug
- // $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+ $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
/**
@@ -125,12 +153,41 @@ class phpbb_database_test_connection_manager
}
break;
+ case 'firebird':
+ $this->connect();
+ // Drop all of the tables
+ foreach ($this->get_tables() as $table)
+ {
+ $this->pdo->exec('DROP TABLE ' . $table);
+ }
+ $this->purge_extras();
+ break;
+
+ case 'oracle':
+ $this->connect();
+ // Drop all of the tables
+ foreach ($this->get_tables() as $table)
+ {
+ $this->pdo->exec('DROP TABLE ' . $table . ' CASCADE CONSTRAINTS');
+ }
+ $this->purge_extras();
+ break;
+
default:
$this->connect(false);
try
{
$this->pdo->exec('DROP DATABASE ' . $this->config['dbname']);
+
+ try
+ {
+ $this->pdo->exec('CREATE DATABASE ' . $this->config['dbname']);
+ }
+ catch (PDOException $e)
+ {
+ throw new Exception("Unable to re-create database: {$e->getMessage()}");
+ }
}
catch (PDOException $e)
{
@@ -139,9 +196,8 @@ class phpbb_database_test_connection_manager
{
$this->pdo->exec('DROP TABLE ' . $table);
}
+ $this->purge_extras();
}
-
- $this->pdo->exec('CREATE DATABASE ' . $this->config['dbname']);
break;
}
}
@@ -317,4 +373,44 @@ class phpbb_database_test_connection_manager
throw new Exception($message);
}
}
+
+ /**
+ * Removes extra objects from a database. This is for cases where dropping the database fails.
+ */
+ public function purge_extras()
+ {
+ $this->ensure_connected(__METHOD__);
+ $queries = array();
+
+ switch ($this->config['dbms'])
+ {
+ case 'firebird':
+ $sql = 'SELECT RDB$GENERATOR_NAME
+ FROM RDB$GENERATORS
+ WHERE RDB$SYSTEM_FLAG = 0';
+ $result = $this->pdo->query($sql);
+
+ while ($row = $result->fetch(PDO::FETCH_NUM))
+ {
+ $queries[] = 'DROP GENERATOR ' . current($row);
+ }
+ break;
+
+ case 'oracle':
+ $sql = 'SELECT sequence_name
+ FROM USER_SEQUENCES';
+ $result = $this->pdo->query($sql);
+
+ while ($row = $result->fetch(PDO::FETCH_NUM))
+ {
+ $queries[] = 'DROP SEQUENCE ' . current($row);
+ }
+ break;
+ }
+
+ foreach($queries as $query)
+ {
+ $this->pdo->exec($query);
+ }
+ }
}