Skip to content

Commit 6075bc4

Browse files
committed
Add whereIn() and whereNotIn() and allow to behave as intuitively expected.
1 parent 48b500e commit 6075bc4

File tree

2 files changed

+150
-0
lines changed

2 files changed

+150
-0
lines changed

src/Database/Query.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -889,6 +889,46 @@ public function where($conditions = null, $types = [], $overwrite = false)
889889
return $this;
890890
}
891891

892+
/**
893+
* Adds an IN condition or set of conditions to be used in the WHERE clause for this
894+
* query.
895+
*
896+
* This method does allow empty inputs in contrast to where().
897+
* Be careful about using it without proper sanity checks.
898+
*
899+
* @param string $field Field
900+
* @param array $values Array of values
901+
* @return $this
902+
*/
903+
public function whereIn($field, array $values)
904+
{
905+
if (!$values) {
906+
return $this->where('1=0');
907+
}
908+
909+
return $this->where([$field . ' IN' => $values]);
910+
}
911+
912+
/**
913+
* Adds a NOT IN condition or set of conditions to be used in the WHERE clause for this
914+
* query.
915+
*
916+
* This method does allow empty inputs in contrast to where().
917+
* Be careful about using it without proper sanity checks.
918+
*
919+
* @param string $field Field
920+
* @param array $values Array of values
921+
* @return $this
922+
*/
923+
public function whereNotIn($field, array $values)
924+
{
925+
if (!$values) {
926+
return $this->where('1=1');
927+
}
928+
929+
return $this->where([$field . ' NOT IN' => $values]);
930+
}
931+
892932
/**
893933
* Connects any previously defined set of conditions to the provided list
894934
* using the AND operator. This function accepts the conditions list in the same

tests/TestCase/Database/QueryTest.php

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,16 @@ class QueryTest extends TestCase
3636
const AUTHOR_COUNT = 4;
3737
const COMMENT_COUNT = 6;
3838

39+
/**
40+
* @var \Cake\Database\Connection
41+
*/
42+
protected $connection;
43+
44+
/**
45+
* @var bool
46+
*/
47+
protected $autoQuote;
48+
3949
public function setUp()
4050
{
4151
parent::setUp();
@@ -1703,6 +1713,106 @@ public function testSelectWhereNot2()
17031713
$result->closeCursor();
17041714
}
17051715

1716+
/**
1717+
* Tests whereIn() and its input types.
1718+
*
1719+
* @return void
1720+
*/
1721+
public function testWhereIn()
1722+
{
1723+
$this->loadFixtures('Articles');
1724+
$query = new Query($this->connection);
1725+
$query->select(['id'])
1726+
->from('articles')
1727+
->whereIn('id', [2, 3])
1728+
->execute();
1729+
$sql = $query->sql();
1730+
1731+
$result = $query->execute();
1732+
$this->assertEquals(['id' => '2'], $result->fetch('assoc'));
1733+
1734+
$this->assertQuotedQuery(
1735+
'SELECT <id> FROM <articles> WHERE <id> in \\(:c0,:c1\\)',
1736+
$sql,
1737+
!$this->autoQuote
1738+
);
1739+
}
1740+
1741+
/**
1742+
* Tests whereIn() and empty array input.
1743+
*
1744+
* @return void
1745+
*/
1746+
public function testWhereInEmpty()
1747+
{
1748+
$this->loadFixtures('Articles');
1749+
$query = new Query($this->connection);
1750+
$query->select(['id'])
1751+
->from('articles')
1752+
->whereIn('id', [])
1753+
->execute();
1754+
$sql = $query->sql();
1755+
1756+
$result = $query->execute();
1757+
$this->assertFalse($result->fetch('assoc'));
1758+
1759+
$this->assertQuotedQuery(
1760+
'SELECT <id> FROM <articles> WHERE 1=0',
1761+
$sql,
1762+
!$this->autoQuote
1763+
);
1764+
}
1765+
1766+
/**
1767+
* Tests whereNotIn() and its input types.
1768+
*
1769+
* @return void
1770+
*/
1771+
public function testWhereNotIn()
1772+
{
1773+
$this->loadFixtures('Articles');
1774+
$query = new Query($this->connection);
1775+
$query->select(['id'])
1776+
->from('articles')
1777+
->whereNotIn('id', [1, 3])
1778+
->execute();
1779+
$sql = $query->sql();
1780+
1781+
$result = $query->execute();
1782+
$this->assertEquals(['id' => '2'], $result->fetch('assoc'));
1783+
1784+
$this->assertQuotedQuery(
1785+
'SELECT <id> FROM <articles> WHERE <id> not in \\(:c0,:c1\\)',
1786+
$sql,
1787+
!$this->autoQuote
1788+
);
1789+
}
1790+
1791+
/**
1792+
* Tests whereNotIn() and empty array input.
1793+
*
1794+
* @return void
1795+
*/
1796+
public function testWhereNotInEmpty()
1797+
{
1798+
$this->loadFixtures('Articles');
1799+
$query = new Query($this->connection);
1800+
$query->select(['id'])
1801+
->from('articles')
1802+
->whereNotIn('id', [])
1803+
->execute();
1804+
$sql = $query->sql();
1805+
1806+
$result = $query->execute();
1807+
$this->assertEquals(['id' => '1'], $result->fetch('assoc'));
1808+
1809+
$this->assertQuotedQuery(
1810+
'SELECT <id> FROM <articles> WHERE 1=1',
1811+
$sql,
1812+
!$this->autoQuote
1813+
);
1814+
}
1815+
17061816
/**
17071817
* Tests order() method both with simple fields and expressions
17081818
*

0 commit comments

Comments
 (0)