Skip to content

Commit c843017

Browse files
authored
Merge pull request #186 from dpDesignz/where-group
Where group
2 parents 7f53752 + 8b83dd7 commit c843017

File tree

8 files changed

+171
-9
lines changed

8 files changed

+171
-9
lines changed

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,15 @@ notBetween('column', $value, $value2)
147147
// $value will protected by either using escape or prepare statement
148148
```
149149

150+
```php
151+
// To allow simple grouping of basic $whereConditions,
152+
// wrap the following around a group of the above comparison
153+
// expressions within the where( ...$whereConditions) clause
154+
grouping( eq(key, value, combiner ), eq(key, value, combiner ) )
155+
// The above will wrap beginning and end grouping in a where statement
156+
// where required to break down your where clause.
157+
```
158+
150159
```php
151160
// Supply the the whole query string, and placing '?' within
152161
// With the same number of arguments in an array.

lib/ezFunctions.php

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,14 @@ function where(...$args)
349349
: false;
350350
}
351351

352+
function grouping(...$args)
353+
{
354+
$ezQuery = \getInstance();
355+
return ($ezQuery instanceof DatabaseInterface)
356+
? $ezQuery->grouping(...$args)
357+
: false;
358+
}
359+
352360
function groupBy($groupBy)
353361
{
354362
$ezQuery = \getInstance();
@@ -374,7 +382,7 @@ function innerJoin(
374382
$condition = \EQ
375383
) {
376384
$ezQuery = \getInstance();
377-
return ($ezQuery instanceOf DatabaseInterface)
385+
return ($ezQuery instanceof DatabaseInterface)
378386
? $ezQuery->innerJoin($leftTable, $rightTable, $leftColumn, $rightColumn, $tableAs, $condition)
379387
: false;
380388
}
@@ -388,7 +396,7 @@ function leftJoin(
388396
$condition = \EQ
389397
) {
390398
$ezQuery = \getInstance();
391-
return ($ezQuery instanceOf DatabaseInterface)
399+
return ($ezQuery instanceof DatabaseInterface)
392400
? $ezQuery->leftJoin($leftTable, $rightTable, $leftColumn, $rightColumn, $tableAs, $condition)
393401
: false;
394402
}
@@ -402,7 +410,7 @@ function rightJoin(
402410
$condition = \EQ
403411
) {
404412
$ezQuery = \getInstance();
405-
return ($ezQuery instanceOf DatabaseInterface)
413+
return ($ezQuery instanceof DatabaseInterface)
406414
? $ezQuery->rightJoin($leftTable, $rightTable, $leftColumn, $rightColumn, $tableAs, $condition)
407415
: false;
408416
}
@@ -416,7 +424,7 @@ function fullJoin(
416424
$condition = \EQ
417425
) {
418426
$ezQuery = \getInstance();
419-
return ($ezQuery instanceOf DatabaseInterface)
427+
return ($ezQuery instanceof DatabaseInterface)
420428
? $ezQuery->fullJoin($leftTable, $rightTable, $leftColumn, $rightColumn, $tableAs, $condition)
421429
: false;
422430
}

lib/ezQuery.php

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -342,13 +342,16 @@ public function limit($numberOf, $offset = null)
342342
return 'LIMIT ' . $rows . $value;
343343
}
344344

345-
private function conditions($key, $condition, $value, $combine)
345+
private function conditions($key, $condition, $value, $combine, $extra)
346346
{
347+
$groupStart = (!empty($extra) && $extra === '(') ? $extra : '';
348+
$groupEnd = (!empty($extra) && $extra === ')') ? $extra : '';
349+
347350
if ($this->isPrepareOn()) {
348-
$this->whereSQL .= "$key $condition " . \_TAG . " $combine ";
351+
$this->whereSQL .= "$groupStart $key $condition " . \_TAG . " $groupEnd $combine ";
349352
$this->addPrepare($value);
350353
} else
351-
$this->whereSQL .= "$key $condition '" . $this->escape($value) . "' $combine ";
354+
$this->whereSQL .= "$groupStart $key $condition '" . $this->escape($value) . "' $groupEnd $combine ";
352355
}
353356

354357
private function conditionBetween($key, $condition, $valueOne, $valueTwo, $combine)
@@ -388,8 +391,22 @@ private function conditionIs($key, $condition, $combine)
388391
$this->whereSQL .= "$key $isCondition NULL $combine ";
389392
}
390393

394+
private function flattenWhereConditions($whereConditions)
395+
{
396+
$whereConditionsReturn = [];
397+
foreach ($whereConditions as $whereCondition) {
398+
if (!empty($whereCondition[0]) && is_array($whereCondition[0])) {
399+
$whereConditionsReturn = array_merge($whereConditionsReturn, $this->flattenWhereConditions($whereCondition));
400+
} else {
401+
$whereConditionsReturn[] = $whereCondition;
402+
}
403+
}
404+
return $whereConditionsReturn;
405+
}
406+
391407
private function retrieveConditions($whereConditions)
392408
{
409+
$whereConditions = $this->flattenWhereConditions($whereConditions);
393410
$whereKey = [];
394411
$whereValue = [];
395412
$operator = [];
@@ -408,7 +425,7 @@ private function retrieveConditions($whereConditions)
408425
$combiner[] = \_AND;
409426
$extra[] = null;
410427
} else {
411-
if (isset($checkFields[0])) {
428+
if (!empty($checkFields[0])) {
412429
$whereKey[] = $checkFields[0];
413430
$whereValue[] = (isset($checkFields[2])) ? $checkFields[2] : '';
414431
$combiner[] = (isset($checkFields[3])) ? $checkFields[3] : \_AND;
@@ -434,12 +451,37 @@ private function processConditions($column, $condition, $value, $valueOrCombine,
434451
} elseif ((($condition == \_LIKE) || ($condition == \_notLIKE)) && !\preg_match('/[_%?]/', $value)) {
435452
return $this->clearPrepare();
436453
} else {
437-
$this->conditions($column, $condition, $value, $valueOrCombine);
454+
$this->conditions($column, $condition, $value, $valueOrCombine, $extraCombine);
455+
}
456+
}
457+
458+
public function grouping(...$whereConditions)
459+
{
460+
if (empty($whereConditions))
461+
return false;
462+
463+
$whereOrHaving = ($this->isWhere) ? 'WHERE' : 'HAVING';
464+
465+
if (\is_string($whereConditions[0]) && \strpos($whereConditions[0], $whereOrHaving) !== false)
466+
return $whereConditions[0];
467+
468+
$totalConditions = count($whereConditions) - 1;
469+
470+
if ($totalConditions > 0) {
471+
472+
if (!in_array('(', $whereConditions[0]))
473+
$whereConditions[0][count($whereConditions[0])] = '(';
474+
475+
if (!in_array(')', $whereConditions[$totalConditions]))
476+
$whereConditions[$totalConditions][count($whereConditions[$totalConditions])] = ')';
438477
}
478+
479+
return $whereConditions;
439480
}
440481

441482
public function where(...$whereConditions)
442483
{
484+
443485
if (empty($whereConditions))
444486
return false;
445487

lib/ezQueryInterface.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,33 @@ public function orderBy($orderBy, $order);
294294
*/
295295
public function limit($numberOf, $offset = null);
296296

297+
/**
298+
* Helper adds WHERE grouping to the conditions
299+
*
300+
* format:
301+
* `grouping( comparison(x, y, and) )`
302+
*
303+
* example:
304+
* `grouping( eq(key, value, combiner ), eq(key, value, combiner ) );`
305+
*
306+
* @param array $whereConditions - In the following format:
307+
*
308+
* eq('key/Field/Column', $value, _AND), // combine next expression
309+
* neq('key/Field/Column', $value, _OR), // will combine next expression again
310+
* ne('key/Field/Column', $value), // the default is _AND so will combine next expression
311+
* lt('key/Field/Column', $value)
312+
* lte('key/Field/Column', $value)
313+
* gt('key/Field/Column', $value)
314+
* gte('key/Field/Column', $value)
315+
* isNull('key/Field/Column')
316+
* isNotNull('key/Field/Column')
317+
* like('key/Field/Column', '_%')
318+
* notLike('key/Field/Column', '_%')
319+
*
320+
* @return array modified conditions
321+
*/
322+
public function grouping(...$whereConditions);
323+
297324
/**
298325
* Helper returns an WHERE sql clause string.
299326
*

tests/pdo/pdo_mysqlTest.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,26 @@ public function testSelecting()
265265
$this->assertEquals(0, $this->object->query('DROP TABLE unit_test'));
266266
}
267267

268+
public function testWhereGrouping()
269+
{
270+
$this->assertTrue($this->object->connect('mysql:host=' . self::TEST_DB_HOST . ';dbname=' . self::TEST_DB_NAME . ';port=' . self::TEST_DB_PORT, self::TEST_DB_USER, self::TEST_DB_PASSWORD));
271+
$this->object->query('CREATE TABLE unit_test(id integer, test_key varchar(50), active tinyint(1), PRIMARY KEY (ID))');
272+
$this->object->insert('unit_test', array('id' => '1', 'test_key' => 'testing 1', 'active' => 1));
273+
$this->object->insert('unit_test', array('id' => '2', 'test_key' => 'testing 2', 'active' => 0));
274+
$this->object->insert('unit_test', array('id' => '3', 'test_key' => 'testing 3', 'active' => 1));
275+
$this->object->insert('unit_test', array('id' => '4', 'test_key' => 'testing 4', 'active' => 1));
276+
277+
$result = $this->object->selecting('unit_test', '*', where(eq('active', '1'), grouping(like('test_key', '%1%', _OR), like('test_key', '%3%'))));
278+
$i = 1;
279+
foreach ($result as $row) {
280+
$this->assertEquals($i, $row->id);
281+
$this->assertEquals('testing ' . $i, $row->test_key);
282+
$i = $i + 2;
283+
}
284+
285+
$this->assertEquals(0, $this->object->query('DROP TABLE unit_test'));
286+
}
287+
268288
public function testJoins()
269289
{
270290
$this->assertTrue($this->object->connect('mysql:host=' . self::TEST_DB_HOST . ';dbname=' . self::TEST_DB_NAME . ';port=' . self::TEST_DB_PORT, self::TEST_DB_USER, self::TEST_DB_PASSWORD));

tests/pdo/pdo_pgsqlTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,24 @@ public function testSelecting()
189189
}
190190
}
191191

192+
public function testWhereGrouping()
193+
{
194+
$this->assertTrue($this->object->connect('pgsql:host=' . self::TEST_DB_HOST . ';dbname=' . self::TEST_DB_NAME . ';port=' . self::TEST_DB_PORT, self::TEST_DB_USER, self::TEST_DB_PASSWORD));
195+
$this->object->query('CREATE TABLE unit_test(id integer, test_key varchar(50), active tinyint(1), PRIMARY KEY (ID))');
196+
$this->object->insert('unit_test', array('id' => '1', 'test_key' => 'testing 1', 'active' => 1));
197+
$this->object->insert('unit_test', array('id' => '2', 'test_key' => 'testing 2', 'active' => 0));
198+
$this->object->insert('unit_test', array('id' => '3', 'test_key' => 'testing 3', 'active' => 1));
199+
$this->object->insert('unit_test', array('id' => '4', 'test_key' => 'testing 4', 'active' => 1));
200+
201+
$result = $this->object->selecting('unit_test', '*', where(eq('active', '1'), grouping(like('test_key', '%1%', _OR), like('test_key', '%3%'))));
202+
$i = 1;
203+
foreach ($result as $row) {
204+
$this->assertEquals($i, $row->id);
205+
$this->assertEquals('testing ' . $i, $row->test_key);
206+
$i = $i + 2;
207+
}
208+
}
209+
192210
public function testJoins()
193211
{
194212
$this->assertTrue($this->object->connect('pgsql:host=' . self::TEST_DB_HOST . ';dbname=' . self::TEST_DB_NAME . ';port=' . self::TEST_DB_PORT, self::TEST_DB_USER, self::TEST_DB_PASSWORD));

tests/pdo/pdo_sqliteTest.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,26 @@ public function testSelecting()
216216
$this->assertEquals(1, $this->object->query('DROP TABLE unit_test'));
217217
}
218218

219+
public function testWhereGrouping()
220+
{
221+
$this->assertTrue($this->object->connect('sqlite:' . self::TEST_SQLITE_DB, '', '', array(), true));
222+
$this->object->query('CREATE TABLE unit_test(id integer, test_key varchar(50), active tinyint(1), PRIMARY KEY (ID))');
223+
$this->object->insert('unit_test', array('id' => '1', 'test_key' => 'testing 1', 'active' => 1));
224+
$this->object->insert('unit_test', array('id' => '2', 'test_key' => 'testing 2', 'active' => 0));
225+
$this->object->insert('unit_test', array('id' => '3', 'test_key' => 'testing 3', 'active' => 1));
226+
$this->object->insert('unit_test', array('id' => '4', 'test_key' => 'testing 4', 'active' => 1));
227+
228+
$result = $this->object->selecting('unit_test', '*', where(eq('active', '1'), grouping(like('test_key', '%1%', _OR), like('test_key', '%3%'))));
229+
$i = 1;
230+
foreach ($result as $row) {
231+
$this->assertEquals($i, $row->id);
232+
$this->assertEquals('testing ' . $i, $row->test_key);
233+
$i = $i + 2;
234+
}
235+
236+
$this->assertEquals(1, $this->object->query('DROP TABLE unit_test'));
237+
}
238+
219239
public function testJoins()
220240
{
221241
$this->assertTrue($this->object->connect('sqlite:' . self::TEST_SQLITE_DB, '', '', array(), true));

tests/pdo/pdo_sqlsrvTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,24 @@ public function testSelecting()
193193
}
194194
}
195195

196+
public function testWhereGrouping()
197+
{
198+
$this->assertTrue($this->object->connect('sqlsrv:Server=' . self::TEST_DB_HOST . ';Database=' . self::TEST_DB_NAME, self::TEST_DB_USER, self::TEST_DB_PASSWORD));
199+
$this->object->query('CREATE TABLE unit_test(id integer, test_key varchar(50), active tinyint(1), PRIMARY KEY (ID))');
200+
$this->object->insert('unit_test', array('id' => '1', 'test_key' => 'testing 1', 'active' => 1));
201+
$this->object->insert('unit_test', array('id' => '2', 'test_key' => 'testing 2', 'active' => 0));
202+
$this->object->insert('unit_test', array('id' => '3', 'test_key' => 'testing 3', 'active' => 1));
203+
$this->object->insert('unit_test', array('id' => '4', 'test_key' => 'testing 4', 'active' => 1));
204+
205+
$result = $this->object->selecting('unit_test', '*', where(eq('active', '1'), grouping(like('test_key', '%1%', _OR), like('test_key', '%3%'))));
206+
$i = 1;
207+
foreach ($result as $row) {
208+
$this->assertEquals($i, $row->id);
209+
$this->assertEquals('testing ' . $i, $row->test_key);
210+
$i = $i + 2;
211+
}
212+
}
213+
196214
public function testJoins()
197215
{
198216
$this->assertTrue($this->object->connect('sqlsrv:Server=' . self::TEST_DB_HOST . ';Database=' . self::TEST_DB_NAME, self::TEST_DB_USER, self::TEST_DB_PASSWORD));

0 commit comments

Comments
 (0)