Skip to content

Commit d8aab0a

Browse files
meridiusdg
authored andcommitted
Selection: added new method whereOr (#111)
1 parent 8c4cb30 commit d8aab0a

File tree

2 files changed

+138
-0
lines changed

2 files changed

+138
-0
lines changed

src/Database/Table/Selection.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,40 @@ protected function condition($condition, array $params, $tableChain = NULL)
363363
}
364364

365365

366+
/**
367+
* Adds where condition using the OR operator between parameters.
368+
* More calls appends with AND.
369+
* @param array ['column1' => 1, 'column2 > ?' => 2, 'full condition']
370+
* @return self
371+
* @throws \Nette\InvalidArgumentException
372+
*/
373+
public function whereOr(array $parameters)
374+
{
375+
if (count($parameters) < 2) {
376+
return $this->where($parameters);
377+
}
378+
$columns = [];
379+
$values = [];
380+
foreach ($parameters as $key => $val) {
381+
if (is_int($key)) { // whereOr(['full condition'])
382+
$columns[] = $val;
383+
} elseif (strpos($key, '?') === FALSE) { // whereOr(['column1' => 1])
384+
$columns[] = $key . ' ?';
385+
$values[] = $val;
386+
} else { // whereOr(['column1 > ?' => 1])
387+
$qNumber = substr_count($key, '?');
388+
if ($qNumber > 1 && (!is_array($val) || $qNumber !== count($val))) {
389+
throw new Nette\InvalidArgumentException('Argument count does not match placeholder count.');
390+
}
391+
$columns[] = $key;
392+
$values = array_merge($values, $qNumber > 1 ? $val : [$val]);
393+
}
394+
}
395+
$columnsString = '(' . implode(') OR (', $columns) . ')';
396+
return $this->where($columnsString, $values);
397+
}
398+
399+
366400
/**
367401
* Adds order clause, more calls appends to the end.
368402
* @param string for example 'column1, column2 DESC'
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
<?php
2+
3+
/**
4+
* Test: Nette\Database\Table: WhereOr operations
5+
* @dataProvider? ../databases.ini
6+
*/
7+
8+
use Tester\Assert;
9+
10+
require __DIR__ . '/../connect.inc.php'; // create $connection
11+
12+
Nette\Database\Helpers::loadFromFile($connection, __DIR__ . "/../files/{$driverName}-nette_test1.sql");
13+
14+
// without question mark
15+
test(function () use ($context) {
16+
$count = $context->table('book')->whereOr([
17+
'author_id' => 12,
18+
'title' => 'JUSH',
19+
])->count();
20+
Assert::same(3, $count);
21+
});
22+
23+
24+
// full condition
25+
test(function () use ($context) {
26+
$count = $context->table('book')->whereOr([
27+
'translator_id IS NULL',
28+
'title' => 'Dibi',
29+
])->count();
30+
Assert::same(2, $count);
31+
});
32+
33+
34+
// with question mark
35+
test(function () use ($context) {
36+
$count = $context->table('book')->whereOr([
37+
'id > ?' => 3,
38+
'translator_id' => 11,
39+
])->count();
40+
Assert::same(2, $count);
41+
});
42+
43+
44+
// just one condition
45+
test(function () use ($context) {
46+
$count = $context->table('book')->whereOr([
47+
'id > ?' => 3,
48+
])->count();
49+
Assert::same(1, $count);
50+
});
51+
52+
53+
// with question mark
54+
test(function () use ($context) {
55+
$count = $context->table('book')->whereOr([
56+
'id ?' => [3, 4],
57+
'translator_id' => 11,
58+
])->count();
59+
Assert::same(3, $count);
60+
});
61+
62+
63+
// multiple values for one key
64+
test(function () use ($context) {
65+
$count = $context->table('author')->whereOr([
66+
'id > ?' => 12,
67+
'ROUND(id, ?) = ?' => [5, 3],
68+
])->count();
69+
Assert::same(1, $count);
70+
});
71+
72+
73+
// nested condition
74+
test(function () use ($context) {
75+
$books = $context->table('book')->whereOr([
76+
'id = ?' => 4,
77+
'author_id = ? AND translator_id ?' => [11, null],
78+
]);
79+
Assert::same(2, $books->count());
80+
});
81+
82+
83+
// invalid param count
84+
test(function () use ($context) {
85+
$f = function () use ($context) {
86+
$context->table('author')->whereOr([
87+
'id > ?' => 3,
88+
'ROUND(id, ?) = ?' => [5],
89+
])->count();
90+
};
91+
Assert::throws($f, '\Nette\InvalidArgumentException', 'Argument count does not match placeholder count.');
92+
});
93+
94+
95+
// invalid param count
96+
test(function () use ($context) {
97+
$f = function () use ($context) {
98+
$context->table('author')->whereOr([
99+
'id > ?' => 3,
100+
'ROUND(id, ?) = ?' => 5,
101+
])->count();
102+
};
103+
Assert::throws($f, '\Nette\InvalidArgumentException', 'Argument count does not match placeholder count.');
104+
});

0 commit comments

Comments
 (0)