Skip to content

Commit

Permalink
Optimize whereKey
Browse files Browse the repository at this point in the history
  • Loading branch information
imanghafoori1 committed Dec 29, 2022
1 parent 3dff584 commit 7c20173
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 19 deletions.
12 changes: 10 additions & 2 deletions src/Illuminate/Database/Eloquent/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,11 @@ public function whereKey($id)
}

if (is_array($id) || $id instanceof Arrayable) {
$this->query->whereIn($this->model->getQualifiedKeyName(), $id);
if ($this->model->getKeyType() === 'int') {
$this->query->whereIntegerInRaw($this->model->getQualifiedKeyName(), $id);
} else {
$this->query->whereIn($this->model->getQualifiedKeyName(), $id);
}

return $this;
}
Expand All @@ -257,7 +261,11 @@ public function whereKeyNot($id)
}

if (is_array($id) || $id instanceof Arrayable) {
$this->query->whereNotIn($this->model->getQualifiedKeyName(), $id);
if ($this->model->getKeyType() === 'int') {
$this->query->whereIntegerNotInRaw($this->model->getQualifiedKeyName(), $id);
} else {
$this->query->whereNotIn($this->model->getQualifiedKeyName(), $id);
}

return $this;
}
Expand Down
51 changes: 34 additions & 17 deletions tests/Database/DatabaseEloquentBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,10 @@ public function testFindManyMethod()
{
// ids are not empty
$builder = m::mock(Builder::class.'[get]', [$this->getMockQueryBuilder()]);
$builder->setModel($this->getMockModel());
$builder->getQuery()->shouldReceive('whereIn')->once()->with('foo_table.foo', ['one', 'two']);
$model = $this->getMockModel();
$model->shouldReceive('getKeyType')->andReturn('int');
$builder->setModel($model);
$builder->getQuery()->shouldReceive('whereIntegerInRaw')->once()->with('foo_table.foo', ['one', 'two']);
$builder->shouldReceive('get')->with(['column'])->andReturn(['baz']);

$result = $builder->findMany(['one', 'two'], ['column']);
Expand All @@ -61,8 +63,9 @@ public function testFindManyMethod()
$builder = m::mock(Builder::class.'[get]', [$this->getMockQueryBuilder()]);
$model = $this->getMockModel();
$model->shouldReceive('newCollection')->once()->withNoArgs()->andReturn('emptycollection');
$model->shouldReceive('getKeyType')->andReturn('int');
$builder->setModel($model);
$builder->getQuery()->shouldNotReceive('whereIn');
$builder->getQuery()->shouldNotReceive('whereIntegerInRaw');
$builder->shouldNotReceive('get');

$result = $builder->findMany([], ['column']);
Expand Down Expand Up @@ -132,10 +135,11 @@ public function testFindOrFailMethodWithManyThrowsModelNotFoundException()

$model = $this->getMockModel();
$model->shouldReceive('getKey')->andReturn(1);
$model->shouldReceive('getKeyType')->andReturn('int');

$builder = m::mock(Builder::class.'[get]', [$this->getMockQueryBuilder()]);
$builder->setModel($model);
$builder->getQuery()->shouldReceive('whereIn')->once()->with('foo_table.foo', [1, 2]);
$builder->getQuery()->shouldReceive('whereIntegerInRaw')->once()->with('foo_table.foo', [1, 2]);
$builder->shouldReceive('get')->with(['column'])->andReturn(new Collection([$model]));
$builder->findOrFail([1, 2], ['column']);
}
Expand All @@ -146,10 +150,11 @@ public function testFindOrFailMethodWithManyUsingCollectionThrowsModelNotFoundEx

$model = $this->getMockModel();
$model->shouldReceive('getKey')->andReturn(1);
$model->shouldReceive('getKeyType')->andReturn('int');

$builder = m::mock(Builder::class.'[get]', [$this->getMockQueryBuilder()]);
$builder->setModel($model);
$builder->getQuery()->shouldReceive('whereIn')->once()->with('foo_table.foo', [1, 2]);
$builder->getQuery()->shouldReceive('whereIntegerInRaw')->once()->with('foo_table.foo', [1, 2]);
$builder->shouldReceive('get')->with(['column'])->andReturn(new Collection([$model]));
$builder->findOrFail(new Collection([1, 2]), ['column']);
}
Expand All @@ -176,9 +181,11 @@ public function testFindOrMethodWithMany()
$builder = m::mock(Builder::class.'[get]', [$this->getMockQueryBuilder()]);
$model1 = $this->getMockModel();
$model2 = $this->getMockModel();
$model1->shouldReceive('getKeyType')->andReturn('int');
$model2->shouldReceive('getKeyType')->andReturn('int');
$builder->setModel($model1);
$builder->getQuery()->shouldReceive('whereIn')->with('foo_table.foo', [1, 2])->twice();
$builder->getQuery()->shouldReceive('whereIn')->with('foo_table.foo', [1, 2, 3])->once();
$builder->getQuery()->shouldReceive('whereIntegerInRaw')->with('foo_table.foo', [1, 2])->twice();
$builder->getQuery()->shouldReceive('whereIntegerInRaw')->with('foo_table.foo', [1, 2, 3])->once();
$builder->shouldReceive('get')->andReturn(new Collection([$model1, $model2]))->once();
$builder->shouldReceive('get')->with(['column'])->andReturn(new Collection([$model1, $model2]))->once();
$builder->shouldReceive('get')->andReturn(null)->once();
Expand All @@ -202,9 +209,11 @@ public function testFindOrMethodWithManyUsingCollection()
$builder = m::mock(Builder::class.'[get]', [$this->getMockQueryBuilder()]);
$model1 = $this->getMockModel();
$model2 = $this->getMockModel();
$model1->shouldReceive('getKeyType')->andReturn('int');
$model2->shouldReceive('getKeyType')->andReturn('int');
$builder->setModel($model1);
$builder->getQuery()->shouldReceive('whereIn')->with('foo_table.foo', [1, 2])->twice();
$builder->getQuery()->shouldReceive('whereIn')->with('foo_table.foo', [1, 2, 3])->once();
$builder->getQuery()->shouldReceive('whereIntegerInRaw')->with('foo_table.foo', [1, 2])->twice();
$builder->getQuery()->shouldReceive('whereIntegerInRaw')->with('foo_table.foo', [1, 2, 3])->once();
$builder->shouldReceive('get')->andReturn(new Collection([$model1, $model2]))->once();
$builder->shouldReceive('get')->with(['column'])->andReturn(new Collection([$model1, $model2]))->once();
$builder->shouldReceive('get')->andReturn(null)->once();
Expand Down Expand Up @@ -236,8 +245,10 @@ public function testFirstOrFailMethodThrowsModelNotFoundException()
public function testFindWithMany()
{
$builder = m::mock(Builder::class.'[get]', [$this->getMockQueryBuilder()]);
$builder->getQuery()->shouldReceive('whereIn')->once()->with('foo_table.foo', [1, 2]);
$builder->setModel($this->getMockModel());
$model = $this->getMockModel();
$model->shouldReceive('getKeyType')->andReturn('int');
$builder->getQuery()->shouldReceive('whereIntegerInRaw')->once()->with('foo_table.foo', [1, 2]);
$builder->setModel($model);
$builder->shouldReceive('get')->with(['column'])->andReturn('baz');

$result = $builder->find([1, 2], ['column']);
Expand All @@ -248,8 +259,10 @@ public function testFindWithManyUsingCollection()
{
$ids = collect([1, 2]);
$builder = m::mock(Builder::class.'[get]', [$this->getMockQueryBuilder()]);
$builder->getQuery()->shouldReceive('whereIn')->once()->with('foo_table.foo', [1, 2]);
$builder->setModel($this->getMockModel());
$model = $this->getMockModel();
$model->shouldReceive('getKeyType')->andReturn('int');
$builder->getQuery()->shouldReceive('whereIntegerInRaw')->once()->with('foo_table.foo', [1, 2]);
$builder->setModel($model);
$builder->shouldReceive('get')->with(['column'])->andReturn('baz');

$result = $builder->find($ids, ['column']);
Expand Down Expand Up @@ -1770,25 +1783,27 @@ public function testWhereKeyMethodWithStringNull()
public function testWhereKeyMethodWithArray()
{
$model = $this->getMockModel();
$model->shouldReceive('getKeyType')->andReturn('int');
$builder = $this->getBuilder()->setModel($model);
$keyName = $model->getQualifiedKeyName();

$array = [1, 2, 3];

$builder->getQuery()->shouldReceive('whereIn')->once()->with($keyName, $array);
$builder->getQuery()->shouldReceive('whereIntegerInRaw')->once()->with($keyName, $array);

$builder->whereKey($array);
}

public function testWhereKeyMethodWithCollection()
{
$model = $this->getMockModel();
$model->shouldReceive('getKeyType')->andReturn('int');
$builder = $this->getBuilder()->setModel($model);
$keyName = $model->getQualifiedKeyName();

$collection = new Collection([1, 2, 3]);

$builder->getQuery()->shouldReceive('whereIn')->once()->with($keyName, $collection);
$builder->getQuery()->shouldReceive('whereIntegerInRaw')->once()->with($keyName, $collection);

$builder->whereKey($collection);
}
Expand Down Expand Up @@ -1852,25 +1867,27 @@ public function testWhereKeyNotMethodWithInt()
public function testWhereKeyNotMethodWithArray()
{
$model = $this->getMockModel();
$model->shouldReceive('getKeyType')->andReturn('int');
$builder = $this->getBuilder()->setModel($model);
$keyName = $model->getQualifiedKeyName();

$array = [1, 2, 3];

$builder->getQuery()->shouldReceive('whereNotIn')->once()->with($keyName, $array);
$builder->getQuery()->shouldReceive('whereIntegerNotInRaw')->once()->with($keyName, $array);

$builder->whereKeyNot($array);
}

public function testWhereKeyNotMethodWithCollection()
{
$model = $this->getMockModel();
$model->shouldReceive('getKeyType')->andReturn('int');
$builder = $this->getBuilder()->setModel($model);
$keyName = $model->getQualifiedKeyName();

$collection = new Collection([1, 2, 3]);

$builder->getQuery()->shouldReceive('whereNotIn')->once()->with($keyName, $collection);
$builder->getQuery()->shouldReceive('whereIntegerNotInRaw')->once()->with($keyName, $collection);

$builder->whereKeyNot($collection);
}
Expand Down

0 comments on commit 7c20173

Please sign in to comment.