Skip to content

Commit 8c9d9f9

Browse files
committed
Add builder/grammar support for row values in where condition
1 parent 13ee3f1 commit 8c9d9f9

File tree

3 files changed

+78
-0
lines changed

3 files changed

+78
-0
lines changed

src/Illuminate/Database/Query/Builder.php

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1237,6 +1237,49 @@ public function addWhereExistsQuery(self $query, $boolean = 'and', $not = false)
12371237
return $this;
12381238
}
12391239

1240+
/**
1241+
* Adds a where condition using row values
1242+
*
1243+
* This is mostly used with "keyset pagination" aka "seek method".
1244+
*
1245+
* @param \Illuminate\Database\Query\Builder $query
1246+
* @param array $columns
1247+
* @param string $operator
1248+
* @param array $values
1249+
* @param string $boolean
1250+
* @return $this
1251+
*/
1252+
public function whereRowValues($columns, $operator, $values, $boolean = 'and')
1253+
{
1254+
if (\count($columns) != \count($values)) {
1255+
throw new InvalidArgumentException('The number of columns must match the number of values');
1256+
}
1257+
1258+
$type = 'RowValues';
1259+
1260+
$this->wheres[] = compact('type', 'columns', 'operator', 'values', 'boolean');
1261+
1262+
$this->addBinding($values);
1263+
1264+
return $this;
1265+
}
1266+
1267+
/**
1268+
* Adds a or where condition using row values
1269+
*
1270+
* This is mostly used with "keyset pagination" aka "seek method".
1271+
*
1272+
* @param \Illuminate\Database\Query\Builder $query
1273+
* @param array $columns
1274+
* @param string $operator
1275+
* @param array $values
1276+
* @return $this
1277+
*/
1278+
public function orWhereRowValues($columns, $operator, $values)
1279+
{
1280+
return $this->whereRowValues($columns, $operator, $values, 'or');
1281+
}
1282+
12401283
/**
12411284
* Handles dynamic "where" clauses to the query.
12421285
*

src/Illuminate/Database/Query/Grammars/Grammar.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,21 @@ protected function whereNotExists(Builder $query, $where)
473473
return 'not exists ('.$this->compileSelect($where['query']).')';
474474
}
475475

476+
/**
477+
* Compile a where row values condition.
478+
*
479+
* @param \Illuminate\Database\Query\Builder $query
480+
* @param array $where
481+
* @return string
482+
*/
483+
protected function whereRowValues(Builder $query, $where)
484+
{
485+
$columns = join(', ', $where['columns']);
486+
$values = $this->parameterize($where['values']);
487+
488+
return '('.$columns.') '.$where['operator'].' ('.$values.')';
489+
}
490+
476491
/**
477492
* Compile the "group by" portions of the query.
478493
*

tests/Database/DatabaseQueryBuilderTest.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2363,6 +2363,26 @@ public function testPaginateWhenNoResults()
23632363
]), $result);
23642364
}
23652365

2366+
public function testWhereRowValues()
2367+
{
2368+
$builder = $this->getBuilder();
2369+
$builder->select('*')->from('orders')->whereRowValues(['last_update', 'order_number'], '<', [1, 2]);
2370+
$this->assertEquals('select * from "orders" where (last_update, order_number) < (?, ?)', $builder->toSql());
2371+
2372+
$builder = $this->getBuilder();
2373+
$builder->select('*')->from('orders')->where('company_id', 1)->orWhereRowValues(['last_update', 'order_number'], '<', [1, 2]);
2374+
$this->assertEquals('select * from "orders" where "company_id" = ? or (last_update, order_number) < (?, ?)', $builder->toSql());
2375+
}
2376+
2377+
public function testWhereRowValuesArityMismatch()
2378+
{
2379+
$this->expectException('InvalidArgumentException');
2380+
$this->expectExceptionMessage('The number of columns must match the number of values');
2381+
2382+
$builder = $this->getBuilder();
2383+
$builder->select('*')->from('orders')->whereRowValues(['last_update'], '<', [1, 2]);
2384+
}
2385+
23662386
protected function getBuilder()
23672387
{
23682388
$grammar = new \Illuminate\Database\Query\Grammars\Grammar;

0 commit comments

Comments
 (0)