ORM: Subqueries IN and NOT

This commit is contained in:
yuri
2017-04-26 16:32:24 +03:00
parent 2202b00600
commit 5eaeabe231
4 changed files with 118 additions and 4 deletions
@@ -985,6 +985,7 @@ class Base
switch ($item['type']) {
case 'or':
case 'and':
case 'not':
if (is_array($item['value'])) {
$arr = array();
foreach ($item['value'] as $i) {
+34 -4
View File
@@ -62,13 +62,15 @@ abstract class Base
);
protected static $comparisonOperators = array(
'!=s' => 'NOT IN',
'=s' => 'IN',
'!=' => '<>',
'*' => 'LIKE',
'>=' => '>=',
'<=' => '<=',
'>' => '>',
'<' => '<',
'=' => '=',
'=' => '='
);
protected $entityFactory;
@@ -636,11 +638,21 @@ abstract class Base
$field = 'AND';
}
if ($field === 'NOT') {
$field = 'id!=s';
$value = array(
'selectParams' => array(
'select' => ['id'],
'whereClause' => $value
)
);
}
if (!in_array($field, self::$sqlOperators)) {
$isComplex = false;
$operator = '=';
$operatorOrm = '=';
$leftPart = null;
@@ -648,6 +660,7 @@ abstract class Base
foreach (self::$comparisonOperators as $op => $opDb) {
if (strpos($field, $op) !== false) {
$field = trim(str_replace($op, '', $field));
$operatorOrm = $op;
$operator = $opDb;
break;
}
@@ -745,9 +758,27 @@ abstract class Base
}
}
}
if (!empty($leftPart)) {
if (!is_array($value)) {
if ($operatorOrm === '=s' || $operatorOrm === '!=s') {
if (!is_array($value)) {
continue;
}
if (!empty($value['entityType'])) {
$subQueryEntityType = $value['entityType'];
} else {
$subQueryEntityType = $entity->getEntityType();
}
$subQuerySelectParams = array();
if (!empty($value['selectParams'])) {
$subQuerySelectParams = $value['selectParams'];
}
$withDeleted = false;
if (!empty($value['withDeleted'])) {
$withDeleted = true;
}
$whereParts[] = $leftPart . " " . $operator . " (" . $this->createSelectQuery($subQueryEntityType, $subQuerySelectParams, $withDeleted) . ")";
} else if (!is_array($value)) {
if (!is_null($value)) {
$whereParts[] = $leftPart . " " . $operator . " " . $this->pdo->quote($value);
} else {
@@ -757,7 +788,6 @@ abstract class Base
$whereParts[] = $leftPart . " IS NOT NULL";
}
}
} else {
$valArr = $value;
foreach ($valArr as $k => $v) {
@@ -243,4 +243,34 @@ class BaseTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('2016-10-10', $selectParams['whereClause'][1]['OR'][0]['date=']);
$this->assertEquals('2016-10-10 10:10:00', $selectParams['whereClause'][1]['OR'][1]['dateTime>']);
}
function testBuildSelectParamsNot()
{
$selectManager = new \Espo\Core\SelectManagers\Base($this->entityManager, $this->user, $this->acl, $this->aclManager, $this->metadata, $this->config);
$selectManager->setEntityType('Test2');
$params = array(
'where' => array(
array(
'type' => 'not',
'value' => array(
array(
'type' => 'equals',
'field'=> 'date',
'value' => '2016-10-10'
),
array(
'type' => 'after',
'field'=> 'dateTime',
'value' => '2016-10-10 10:10:00'
)
)
)
)
);
$selectParams = $selectManager->buildSelectParams($params);
$this->assertEquals('2016-10-10', $selectParams['whereClause'][0]['NOT'][0]['date=']);
}
}
+53
View File
@@ -224,6 +224,59 @@ class QueryTest extends PHPUnit_Framework_TestCase
$this->assertEquals($expectedSql, $sql);
}
public function testSelectWithSubquery()
{
$sql = $this->query->createSelectQuery('Post', array(
'select' => ['id', 'name'],
'whereClause' => array(
'post.id=s' => array(
'entityType' => 'Post',
'selectParams' => array(
'select' => ['id'],
'whereClause' => array(
'name' => 'test'
)
)
)
)
));
$expectedSql = "SELECT post.id AS `id`, post.name AS `name` FROM `post` WHERE post.id IN (SELECT post.id AS `id` FROM `post` WHERE post.name = 'test' AND post.deleted = '0') AND post.deleted = '0'";
$this->assertEquals($expectedSql, $sql);
$sql = $this->query->createSelectQuery('Post', array(
'select' => ['id', 'name'],
'whereClause' => array(
'post.id!=s' => array(
'entityType' => 'Post',
'selectParams' => array(
'select' => ['id'],
'whereClause' => array(
'name' => 'test'
)
)
)
)
));
$expectedSql = "SELECT post.id AS `id`, post.name AS `name` FROM `post` WHERE post.id NOT IN (SELECT post.id AS `id` FROM `post` WHERE post.name = 'test' AND post.deleted = '0') AND post.deleted = '0'";
$this->assertEquals($expectedSql, $sql);
$sql = $this->query->createSelectQuery('Post', array(
'select' => ['id', 'name'],
'whereClause' => array(
'NOT'=> array(
'name' => 'test',
'post.createdById' => '1'
)
)
));
$expectedSql = "SELECT post.id AS `id`, post.name AS `name` FROM `post` WHERE post.id NOT IN (SELECT post.id AS `id` FROM `post` WHERE post.name = 'test' AND post.created_by_id = '1' AND post.deleted = '0') AND post.deleted = '0'";
$this->assertEquals($expectedSql, $sql);
}
public function testOrderBy()
{
$sql = $this->query->createSelectQuery('Comment', array(