[2.0] DDC-325 - Fixed LOCATE() support for all platforms.
This commit is contained in:
parent
371f3d5ecc
commit
6bfbab9f7d
@ -34,6 +34,7 @@ class Driver implements \Doctrine\DBAL\Driver
|
||||
protected $_userDefinedFunctions = array(
|
||||
'sqrt' => array('callback' => array('Doctrine\DBAL\Platforms\SqlitePlatform', 'udfSqrt'), 'numArgs' => 1),
|
||||
'mod' => array('callback' => array('Doctrine\DBAL\Platforms\SqlitePlatform', 'udfMod'), 'numArgs' => 2),
|
||||
'locate' => array('callback' => array('Doctrine\DBAL\Platforms\SqlitePlatform', 'udfLocate'), 'numArgs' => -1),
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -324,16 +324,16 @@ abstract class AbstractPlatform
|
||||
}
|
||||
|
||||
/**
|
||||
* locate
|
||||
* returns the position of the first occurrence of substring $substr in string $str
|
||||
*
|
||||
* @param string $substr literal string to find
|
||||
* @param string $str literal string
|
||||
* @param int $pos position to start at, beginning of string by default
|
||||
* @return integer
|
||||
*/
|
||||
public function getLocateExpression($str, $substr)
|
||||
public function getLocateExpression($str, $substr, $startPos = false)
|
||||
{
|
||||
return 'LOCATE(' . $str . ', ' . $substr . ')';
|
||||
throw DBALException::notSupported(__METHOD__);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -68,6 +68,23 @@ class MySqlPlatform extends AbstractPlatform
|
||||
return 'UUID()';
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the position of the first occurrence of substring $substr in string $str
|
||||
*
|
||||
* @param string $substr literal string to find
|
||||
* @param string $str literal string
|
||||
* @param int $pos position to start at, beginning of string by default
|
||||
* @return integer
|
||||
*/
|
||||
public function getLocateExpression($str, $substr, $startPos = false)
|
||||
{
|
||||
if ($startPos == false) {
|
||||
return 'LOCATE(' . $substr . ', ' . $str . ')';
|
||||
} else {
|
||||
return 'LOCATE(' . $substr . ', ' . $str . ', '.$startPos.')';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a series of strings concatinated
|
||||
*
|
||||
|
@ -74,6 +74,23 @@ class OraclePlatform extends AbstractPlatform
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the position of the first occurrence of substring $substr in string $str
|
||||
*
|
||||
* @param string $substr literal string to find
|
||||
* @param string $str literal string
|
||||
* @param int $pos position to start at, beginning of string by default
|
||||
* @return integer
|
||||
*/
|
||||
public function getLocateExpression($str, $substr, $startPos = false)
|
||||
{
|
||||
if ($startPos == false) {
|
||||
return 'INSTR('.$str.', '.$substr.')';
|
||||
} else {
|
||||
return 'INSTR('.$str.', '.$substr.', '.$startPos.')';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns global unique identifier
|
||||
*
|
||||
|
@ -73,6 +73,24 @@ class PostgreSqlPlatform extends AbstractPlatform
|
||||
{
|
||||
return 'SIMILAR TO';
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the position of the first occurrence of substring $substr in string $str
|
||||
*
|
||||
* @param string $substr literal string to find
|
||||
* @param string $str literal string
|
||||
* @param int $pos position to start at, beginning of string by default
|
||||
* @return integer
|
||||
*/
|
||||
public function getLocateExpression($str, $substr, $startPos = false)
|
||||
{
|
||||
if ($startPos !== false) {
|
||||
$str = $this->getSubstringExpression($str, $startPos);
|
||||
return 'CASE WHEN (POSITION('.$substr.' IN '.$str.') = 0) THEN 0 ELSE (POSITION('.$substr.' IN '.$str.') + '.($startPos-1).') END';
|
||||
} else {
|
||||
return 'POSITION('.$substr.' IN '.$str.')';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* parses a literal boolean value and returns
|
||||
|
@ -109,6 +109,23 @@ class SqlitePlatform extends AbstractPlatform
|
||||
return 'SUBSTR(' . $value . ', ' . $position . ', LENGTH(' . $value . '))';
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the position of the first occurrence of substring $substr in string $str
|
||||
*
|
||||
* @param string $substr literal string to find
|
||||
* @param string $str literal string
|
||||
* @param int $pos position to start at, beginning of string by default
|
||||
* @return integer
|
||||
*/
|
||||
public function getLocateExpression($str, $substr, $startPos = false)
|
||||
{
|
||||
if ($startPos == false) {
|
||||
return 'LOCATE('.$str.', '.$substr.')';
|
||||
} else {
|
||||
return 'LOCATE('.$str.', '.$substr.', '.$startPos.')';
|
||||
}
|
||||
}
|
||||
|
||||
protected function _getTransactionIsolationLevelSql($level)
|
||||
{
|
||||
switch ($level) {
|
||||
@ -403,4 +420,18 @@ class SqlitePlatform extends AbstractPlatform
|
||||
{
|
||||
return ($a % $b);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $str
|
||||
* @param string $substr
|
||||
* @param int $offset
|
||||
*/
|
||||
static public function udfLocate($str, $substr, $offset = 0)
|
||||
{
|
||||
$pos = strpos($str, $substr, $offset);
|
||||
if ($pos !== false) {
|
||||
return $pos+1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -38,20 +38,22 @@ class LocateFunction extends FunctionNode
|
||||
{
|
||||
public $firstStringPrimary;
|
||||
public $secondStringPrimary;
|
||||
public $simpleArithmeticExpression;
|
||||
public $simpleArithmeticExpression = false;
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
|
||||
{
|
||||
//TODO: Use platform to get SQL
|
||||
return 'LOCATE(' . $sqlWalker->walkStringPrimary($this->firstStringPrimary) . ', '
|
||||
. $sqlWalker->walkStringPrimary($this->secondStringPrimary)
|
||||
. (($this->simpleArithmeticExpression)
|
||||
? ', ' . $sqlWalker->walkSimpleArithmeticExpression($this->simpleArithmeticExpression)
|
||||
: ''
|
||||
) . ')';
|
||||
|
||||
return $sqlWalker->getConnection()->getDatabasePlatform()->getLocateExpression(
|
||||
$sqlWalker->walkStringPrimary($this->firstStringPrimary),
|
||||
$sqlWalker->walkStringPrimary($this->secondStringPrimary),
|
||||
(($this->simpleArithmeticExpression)
|
||||
? $sqlWalker->walkSimpleArithmeticExpression($this->simpleArithmeticExpression)
|
||||
: false
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -99,16 +99,21 @@ class QueryDqlFunctionTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
|
||||
public function testFunctionLocate()
|
||||
{
|
||||
$this->markTestIncomplete('Locate is not working equally across platforms, needs some work.');
|
||||
$dql = "SELECT m, LOCATE(LOWER(m.name), 'e') AS loc, LOCATE(LOWER(m.name), 'e', 7) AS loc2 ".
|
||||
"FROM Doctrine\Tests\Models\Company\CompanyManager m";
|
||||
|
||||
$result = $this->_em->createQuery("SELECT m, LOCATE(m.name, 'e') AS locate FROM Doctrine\Tests\Models\Company\CompanyManager m")
|
||||
$result = $this->_em->createQuery($dql)
|
||||
->getArrayResult();
|
||||
|
||||
$this->assertEquals(4, count($result));
|
||||
$this->assertEquals(0, $result[0]['locate']);
|
||||
$this->assertEquals(2, $result[1]['locate']);
|
||||
$this->assertEquals(10, $result[2]['locate']);
|
||||
$this->assertEquals(25, $result[3]['locate']);
|
||||
$this->assertEquals(0, $result[0]['loc']);
|
||||
$this->assertEquals(2, $result[1]['loc']);
|
||||
$this->assertEquals(6, $result[2]['loc']);
|
||||
$this->assertEquals(0, $result[3]['loc']);
|
||||
$this->assertEquals(0, $result[0]['loc2']);
|
||||
$this->assertEquals(10, $result[1]['loc2']);
|
||||
$this->assertEquals(9, $result[2]['loc2']);
|
||||
$this->assertEquals(0, $result[3]['loc2']);
|
||||
}
|
||||
|
||||
public function testFunctionLower()
|
||||
|
Loading…
x
Reference in New Issue
Block a user