Commit 0833d00b authored by Guilherme Blanco's avatar Guilherme Blanco

Merge pull request #559 from deeky666/fix-sqlanywhere-locate-expression

Fix LOCATE expression on SQL Anywhere and SQLite
parents 3986daf9 ba41ca2a
...@@ -971,10 +971,10 @@ class SQLAnywherePlatform extends AbstractPlatform ...@@ -971,10 +971,10 @@ class SQLAnywherePlatform extends AbstractPlatform
public function getLocateExpression($str, $substr, $startPos = false) public function getLocateExpression($str, $substr, $startPos = false)
{ {
if ($startPos == false) { if ($startPos == false) {
return 'CHARINDEX(' . $substr . ', ' . $str . ')'; return 'LOCATE(' . $str . ', ' . $substr . ')';
} }
return 'CHARINDEX(' . $substr . ', SUBSTR(' . $str . ', ' . ($startPos + 1) . '))'; return 'LOCATE(' . $str . ', ' . $substr . ', ' . $startPos . ')';
} }
/** /**
......
...@@ -543,9 +543,16 @@ class SqlitePlatform extends AbstractPlatform ...@@ -543,9 +543,16 @@ class SqlitePlatform extends AbstractPlatform
*/ */
static public function udfLocate($str, $substr, $offset = 0) static public function udfLocate($str, $substr, $offset = 0)
{ {
// SQL's LOCATE function works on 1-based positions, while PHP's strpos works on 0-based positions.
// So we have to make them compatible if an offset is given.
if ($offset > 0) {
$offset -= 1;
}
$pos = strpos($str, $substr, $offset); $pos = strpos($str, $substr, $offset);
if ($pos !== false) { if ($pos !== false) {
return $pos+1; return $pos + 1;
} }
return 0; return 0;
......
...@@ -522,6 +522,36 @@ class DataAccessTest extends \Doctrine\Tests\DbalFunctionalTestCase ...@@ -522,6 +522,36 @@ class DataAccessTest extends \Doctrine\Tests\DbalFunctionalTestCase
$this->assertEquals('2009-11-01', date('Y-m-d', strtotime($row['sub_month'])), "Adding month should end up on 2009-11-01"); $this->assertEquals('2009-11-01', date('Y-m-d', strtotime($row['sub_month'])), "Adding month should end up on 2009-11-01");
} }
public function testLocateExpression()
{
$platform = $this->_conn->getDatabasePlatform();
$sql = 'SELECT ';
$sql .= $platform->getLocateExpression('test_string', "'oo'") .' AS locate1, ';
$sql .= $platform->getLocateExpression('test_string', "'foo'") .' AS locate2, ';
$sql .= $platform->getLocateExpression('test_string', "'bar'") .' AS locate3, ';
$sql .= $platform->getLocateExpression('test_string', 'test_string') .' AS locate4, ';
$sql .= $platform->getLocateExpression("'foo'", 'test_string') .' AS locate5, ';
$sql .= $platform->getLocateExpression("'barfoobaz'", 'test_string') .' AS locate6, ';
$sql .= $platform->getLocateExpression("'bar'", 'test_string') .' AS locate7, ';
$sql .= $platform->getLocateExpression('test_string', "'oo'", 2) .' AS locate8, ';
$sql .= $platform->getLocateExpression('test_string', "'oo'", 3) .' AS locate9 ';
$sql .= 'FROM fetch_table';
$row = $this->_conn->fetchAssoc($sql);
$row = array_change_key_case($row, CASE_LOWER);
$this->assertEquals(2, $row['locate1']);
$this->assertEquals(1, $row['locate2']);
$this->assertEquals(0, $row['locate3']);
$this->assertEquals(1, $row['locate4']);
$this->assertEquals(1, $row['locate5']);
$this->assertEquals(4, $row['locate6']);
$this->assertEquals(0, $row['locate7']);
$this->assertEquals(2, $row['locate8']);
$this->assertEquals(0, $row['locate9']);
}
public function testQuoteSQLInjection() public function testQuoteSQLInjection()
{ {
$sql = "SELECT * FROM fetch_table WHERE test_string = " . $this->_conn->quote("bar' OR '1'='1"); $sql = "SELECT * FROM fetch_table WHERE test_string = " . $this->_conn->quote("bar' OR '1'='1");
......
...@@ -544,9 +544,8 @@ class SQLAnywherePlatformTest extends AbstractPlatformTestCase ...@@ -544,9 +544,8 @@ class SQLAnywherePlatformTest extends AbstractPlatformTestCase
$this->assertEquals("H:i:s.u", $this->_platform->getTimeFormatString()); $this->assertEquals("H:i:s.u", $this->_platform->getTimeFormatString());
$this->assertEquals('FOR UPDATE BY LOCK', $this->_platform->getForUpdateSQL()); $this->assertEquals('FOR UPDATE BY LOCK', $this->_platform->getForUpdateSQL());
$this->assertEquals('NEWID()', $this->_platform->getGuidExpression()); $this->assertEquals('NEWID()', $this->_platform->getGuidExpression());
$this->assertEquals('CHARINDEX(substring_column, string_column)', $this->_platform->getLocateExpression('string_column', 'substring_column')); $this->assertEquals('LOCATE(string_column, substring_column)', $this->_platform->getLocateExpression('string_column', 'substring_column'));
$this->assertEquals('CHARINDEX(substring_column, string_column)', $this->_platform->getLocateExpression('string_column', 'substring_column')); $this->assertEquals('LOCATE(string_column, substring_column, 1)', $this->_platform->getLocateExpression('string_column', 'substring_column', 1));
$this->assertEquals('CHARINDEX(substring_column, SUBSTR(string_column, 2))', $this->_platform->getLocateExpression('string_column', 'substring_column', 1));
$this->assertEquals("HASH(column, 'MD5')", $this->_platform->getMd5Expression('column')); $this->assertEquals("HASH(column, 'MD5')", $this->_platform->getMd5Expression('column'));
$this->assertEquals('SUBSTRING(column, 5)', $this->_platform->getSubstringExpression('column', 5)); $this->assertEquals('SUBSTRING(column, 5)', $this->_platform->getSubstringExpression('column', 5));
$this->assertEquals('SUBSTRING(column, 5, 2)', $this->_platform->getSubstringExpression('column', 5, 2)); $this->assertEquals('SUBSTRING(column, 5, 2)', $this->_platform->getSubstringExpression('column', 5, 2));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment