diff --git a/phpBB/includes/db/dbal.php b/phpBB/includes/db/dbal.php
index cf54d455f7..159703d3be 100644
--- a/phpBB/includes/db/dbal.php
+++ b/phpBB/includes/db/dbal.php
@@ -283,6 +283,37 @@ class dbal
return $this->_sql_like_expression('LIKE \'' . $this->sql_escape($expression) . '\'');
}
+ /**
+ * Build a case expression
+ *
+ * Note: The two statements action_true and action_false must have the same data type (int, vchar, ...) in the database!
+ *
+ * @param string $condition The condition which must be true, to use action_true rather then action_else
+ * @param string $action_true SQL expression that is used, if the condition is true
+ * @param string $action_else SQL expression that is used, if the condition is false, optional
+ * @return string CASE expression including the condition and statements
+ */
+ public function sql_case($condition, $action_true, $action_false = false)
+ {
+ $sql_case = 'CASE WHEN ' . $condition;
+ $sql_case .= ' THEN ' . $action_true;
+ $sql_case .= ($action_false !== false) ? ' ELSE ' . $action_false : '';
+ $sql_case .= ' END';
+ return $sql_case;
+ }
+
+ /**
+ * Build a concatenated expression
+ *
+ * @param string $expr1 Base SQL expression where we append the second one
+ * @param string $expr2 SQL expression that is appended to the first expression
+ * @return string Concatenated string
+ */
+ public function sql_concatenate($expr1, $expr2)
+ {
+ return $expr1 . ' || ' . $expr2;
+ }
+
/**
* Returns whether results of a query need to be buffered to run a transaction while iterating over them.
*
diff --git a/phpBB/includes/db/mssql.php b/phpBB/includes/db/mssql.php
index abeabc389f..fb044b492f 100644
--- a/phpBB/includes/db/mssql.php
+++ b/phpBB/includes/db/mssql.php
@@ -91,6 +91,14 @@ class dbal_mssql extends dbal
return ($this->sql_server_version) ? 'MSSQL
' . $this->sql_server_version : 'MSSQL';
}
+ /**
+ * {@inheritDoc}
+ */
+ public function sql_concatenate($expr1, $expr2)
+ {
+ return $expr1 . ' + ' . $expr2;
+ }
+
/**
* SQL Transaction
* @access private
diff --git a/phpBB/includes/db/mssql_odbc.php b/phpBB/includes/db/mssql_odbc.php
index 6e24f4e9e8..64fa9634d1 100644
--- a/phpBB/includes/db/mssql_odbc.php
+++ b/phpBB/includes/db/mssql_odbc.php
@@ -109,6 +109,14 @@ class dbal_mssql_odbc extends dbal
return ($this->sql_server_version) ? 'MSSQL (ODBC)
' . $this->sql_server_version : 'MSSQL (ODBC)';
}
+ /**
+ * {@inheritDoc}
+ */
+ public function sql_concatenate($expr1, $expr2)
+ {
+ return $expr1 . ' + ' . $expr2;
+ }
+
/**
* SQL Transaction
* @access private
diff --git a/phpBB/includes/db/mssqlnative.php b/phpBB/includes/db/mssqlnative.php
index 8a4503f111..7878615acc 100644
--- a/phpBB/includes/db/mssqlnative.php
+++ b/phpBB/includes/db/mssqlnative.php
@@ -257,6 +257,14 @@ class dbal_mssqlnative extends dbal
return ($this->sql_server_version) ? 'MSSQL
' . $this->sql_server_version : 'MSSQL';
}
+ /**
+ * {@inheritDoc}
+ */
+ public function sql_concatenate($expr1, $expr2)
+ {
+ return $expr1 . ' + ' . $expr2;
+ }
+
/**
* {@inheritDoc}
*/
diff --git a/phpBB/includes/db/mysql.php b/phpBB/includes/db/mysql.php
index eb38e3e913..8d1f805870 100644
--- a/phpBB/includes/db/mysql.php
+++ b/phpBB/includes/db/mysql.php
@@ -119,6 +119,14 @@ class dbal_mysql extends dbal
return ($raw) ? $this->sql_server_version : 'MySQL ' . $this->sql_server_version;
}
+ /**
+ * {@inheritDoc}
+ */
+ public function sql_concatenate($expr1, $expr2)
+ {
+ return 'CONCAT(' . $expr1 . ', ' . $expr2 . ')';
+ }
+
/**
* SQL Transaction
* @access private
diff --git a/phpBB/includes/db/mysqli.php b/phpBB/includes/db/mysqli.php
index 4210a58002..e07cd35e24 100644
--- a/phpBB/includes/db/mysqli.php
+++ b/phpBB/includes/db/mysqli.php
@@ -122,6 +122,14 @@ class dbal_mysqli extends dbal
return ($raw) ? $this->sql_server_version : 'MySQL(i) ' . $this->sql_server_version;
}
+ /**
+ * {@inheritDoc}
+ */
+ public function sql_concatenate($expr1, $expr2)
+ {
+ return 'CONCAT(' . $expr1 . ', ' . $expr2 . ')';
+ }
+
/**
* SQL Transaction
* @access private
diff --git a/tests/dbal/case_test.php b/tests/dbal/case_test.php
new file mode 100644
index 0000000000..57a1729a39
--- /dev/null
+++ b/tests/dbal/case_test.php
@@ -0,0 +1,69 @@
+createXMLDataSet(dirname(__FILE__).'/fixtures/config.xml');
+ }
+
+ public function test_case_int()
+ {
+ $db = $this->new_dbal();
+
+ $sql = 'SELECT ' . $db->sql_case('1 = 1', '1', '2') . ' AS test_num
+ FROM phpbb_config';
+ $result = $db->sql_query_limit($sql, 1);
+
+ $this->assertEquals(1, (int) $db->sql_fetchfield('test_num'));
+
+ $sql = 'SELECT ' . $db->sql_case('1 = 0', '1', '2') . ' AS test_num
+ FROM phpbb_config';
+ $result = $db->sql_query_limit($sql, 1);
+
+ $this->assertEquals(2, (int) $db->sql_fetchfield('test_num'));
+ }
+
+ public function test_case_string()
+ {
+ $db = $this->new_dbal();
+
+ $sql = 'SELECT ' . $db->sql_case('1 = 1', "'foo'", "'bar'") . ' AS test_string
+ FROM phpbb_config';
+ $result = $db->sql_query_limit($sql, 1);
+
+ $this->assertEquals('foo', $db->sql_fetchfield('test_string'));
+
+ $sql = 'SELECT ' . $db->sql_case('1 = 0', "'foo'", "'bar'") . ' AS test_string
+ FROM phpbb_config';
+ $result = $db->sql_query_limit($sql, 1);
+
+ $this->assertEquals('bar', $db->sql_fetchfield('test_string'));
+ }
+
+ public function test_case_column()
+ {
+ $db = $this->new_dbal();
+
+ $sql = 'SELECT ' . $db->sql_case("config_name = 'config1'", 'config_name', 'config_value') . " AS test_string
+ FROM phpbb_config
+ WHERE config_name = 'config1'";
+ $result = $db->sql_query_limit($sql, 1);
+
+ $this->assertEquals('config1', $db->sql_fetchfield('test_string'));
+
+ $sql = 'SELECT ' . $db->sql_case("config_name = 'config1'", 'config_name', 'config_value') . " AS test_string
+ FROM phpbb_config
+ WHERE config_value = 'bar'";
+ $result = $db->sql_query_limit($sql, 1);
+
+ $this->assertEquals('bar', $db->sql_fetchfield('test_string'));
+ }
+}
diff --git a/tests/dbal/concatenate_test.php b/tests/dbal/concatenate_test.php
new file mode 100644
index 0000000000..0891fa58a0
--- /dev/null
+++ b/tests/dbal/concatenate_test.php
@@ -0,0 +1,64 @@
+createXMLDataSet(dirname(__FILE__).'/fixtures/config.xml');
+ }
+
+ public function test_concatenate_string()
+ {
+ $db = $this->new_dbal();
+
+ $sql = 'SELECT config_name, ' . $db->sql_concatenate('config_name', "'" . $db->sql_escape('append') . "'") . ' AS string
+ FROM phpbb_config';
+ $result = $db->sql_query($sql);
+
+ $db->sql_return_on_error(false);
+
+ $this->assertEquals(array(
+ array(
+ 'config_name' => 'config1',
+ 'string' => 'config1append',
+ ),
+ array(
+ 'config_name' => 'config2',
+ 'string' => 'config2append',
+ ),
+ ),
+ $db->sql_fetchrowset($result)
+ );
+ }
+
+ public function test_concatenate_statement()
+ {
+ $db = $this->new_dbal();
+
+ $sql = 'SELECT config_name, ' . $db->sql_concatenate('config_name', 'config_value') . ' AS string
+ FROM phpbb_config';
+ $result = $db->sql_query($sql);
+
+ $db->sql_return_on_error(false);
+
+ $this->assertEquals(array(
+ array(
+ 'config_name' => 'config1',
+ 'string' => 'config1foo',
+ ),
+ array(
+ 'config_name' => 'config2',
+ 'string' => 'config2bar',
+ ),
+ ),
+ $db->sql_fetchrowset($result)
+ );
+ }
+}
diff --git a/tests/dbal/order_lower_test.php b/tests/dbal/order_lower_test.php
index e16c0c20ee..84d454742f 100644
--- a/tests/dbal/order_lower_test.php
+++ b/tests/dbal/order_lower_test.php
@@ -14,7 +14,7 @@ class phpbb_dbal_order_lower_test extends phpbb_database_test_case
return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/styles.xml');
}
- public function test_cross_join()
+ public function test_order_lower()
{
$db = $this->new_dbal();