From c2f342535a43191a4703dec6c3adc31d8681b228 Mon Sep 17 00:00:00 2001 From: Steve Thomas Date: Thu, 20 Aug 2020 00:15:21 +1000 Subject: [PATCH 1/2] [7.x] Cast primary key to string when $keyType is string (#33930) * Cast primary key to string when $keyType is string * fix test * fix remaining tests --- src/Illuminate/Database/Eloquent/Builder.php | 8 ++++ .../Database/DatabaseEloquentBuilderTest.php | 47 ++++++++++++++++++- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/Illuminate/Database/Eloquent/Builder.php b/src/Illuminate/Database/Eloquent/Builder.php index 00131c80054f..dbac4c2034c7 100755 --- a/src/Illuminate/Database/Eloquent/Builder.php +++ b/src/Illuminate/Database/Eloquent/Builder.php @@ -193,6 +193,10 @@ public function whereKey($id) return $this; } + if ($this->model->getKeyType() === 'string') { + $id = (string) $id; + } + return $this->where($this->model->getQualifiedKeyName(), '=', $id); } @@ -210,6 +214,10 @@ public function whereKeyNot($id) return $this; } + if ($this->model->getKeyType() === 'string') { + $id = (string) $id; + } + return $this->where($this->model->getQualifiedKeyName(), '!=', $id); } diff --git a/tests/Database/DatabaseEloquentBuilderTest.php b/tests/Database/DatabaseEloquentBuilderTest.php index 8276ea03e96b..54a46519d550 100755 --- a/tests/Database/DatabaseEloquentBuilderTest.php +++ b/tests/Database/DatabaseEloquentBuilderTest.php @@ -31,7 +31,9 @@ protected function tearDown(): void public function testFindMethod() { $builder = m::mock(Builder::class.'[first]', [$this->getMockQueryBuilder()]); - $builder->setModel($this->getMockModel()); + $model = $this->getMockModel(); + $builder->setModel($model); + $model->shouldReceive('getKeyType')->once()->andReturn('int'); $builder->getQuery()->shouldReceive('where')->once()->with('foo_table.foo', '=', 'bar'); $builder->shouldReceive('first')->with(['column'])->andReturn('baz'); @@ -76,6 +78,7 @@ public function testFindManyMethod() public function testFindOrNewMethodModelFound() { $model = $this->getMockModel(); + $model->shouldReceive('getKeyType')->once()->andReturn('int'); $model->shouldReceive('findOrNew')->once()->andReturn('baz'); $builder = m::mock(Builder::class.'[first]', [$this->getMockQueryBuilder()]); @@ -91,6 +94,7 @@ public function testFindOrNewMethodModelFound() public function testFindOrNewMethodModelNotFound() { $model = $this->getMockModel(); + $model->shouldReceive('getKeyType')->once()->andReturn('int'); $model->shouldReceive('findOrNew')->once()->andReturn(m::mock(Model::class)); $builder = m::mock(Builder::class.'[first]', [$this->getMockQueryBuilder()]); @@ -109,7 +113,9 @@ public function testFindOrFailMethodThrowsModelNotFoundException() $this->expectException(ModelNotFoundException::class); $builder = m::mock(Builder::class.'[first]', [$this->getMockQueryBuilder()]); - $builder->setModel($this->getMockModel()); + $model = $this->getMockModel(); + $model->shouldReceive('getKeyType')->once()->andReturn('int'); + $builder->setModel($model); $builder->getQuery()->shouldReceive('where')->once()->with('foo_table.foo', '=', 'bar'); $builder->shouldReceive('first')->with(['column'])->andReturn(null); $builder->findOrFail('bar', ['column']); @@ -1017,11 +1023,25 @@ public function testWhereKeyMethodWithInt() $int = 1; + $model->shouldReceive('getKeyType')->once()->andReturn('int'); $builder->getQuery()->shouldReceive('where')->once()->with($keyName, '=', $int); $builder->whereKey($int); } + public function testWhereKeyMethodWithStringZero() + { + $model = new EloquentBuilderTestStubStringPrimaryKey(); + $builder = $this->getBuilder()->setModel($model); + $keyName = $model->getQualifiedKeyName(); + + $int = 0; + + $builder->getQuery()->shouldReceive('where')->once()->with($keyName, '=', (string) $int); + + $builder->whereKey($int); + } + public function testWhereKeyMethodWithArray() { $model = $this->getMockModel(); @@ -1048,6 +1068,19 @@ public function testWhereKeyMethodWithCollection() $builder->whereKey($collection); } + public function testWhereKeyNotMethodWithStringZero() + { + $model = new EloquentBuilderTestStubStringPrimaryKey(); + $builder = $this->getBuilder()->setModel($model); + $keyName = $model->getQualifiedKeyName(); + + $int = 0; + + $builder->getQuery()->shouldReceive('where')->once()->with($keyName, '!=', (string) $int); + + $builder->whereKeyNot($int); + } + public function testWhereKeyNotMethodWithInt() { $model = $this->getMockModel(); @@ -1056,6 +1089,7 @@ public function testWhereKeyNotMethodWithInt() $int = 1; + $model->shouldReceive('getKeyType')->once()->andReturn('int'); $builder->getQuery()->shouldReceive('where')->once()->with($keyName, '!=', $int); $builder->whereKeyNot($int); @@ -1414,3 +1448,12 @@ class EloquentBuilderTestStubWithoutTimestamp extends Model protected $table = 'table'; } + +class EloquentBuilderTestStubStringPrimaryKey extends Model +{ + public $incrementing = false; + + protected $table = 'foo_table'; + + protected $keyType = 'string'; +} From 7f09f14ae9cf639759ac85ae802140299fb078f1 Mon Sep 17 00:00:00 2001 From: Dries Vints Date: Thu, 27 Aug 2020 12:06:32 +0200 Subject: [PATCH 2/2] Fix bug with whereKey null --- src/Illuminate/Database/Eloquent/Builder.php | 4 +-- .../Database/DatabaseEloquentBuilderTest.php | 28 +++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/Illuminate/Database/Eloquent/Builder.php b/src/Illuminate/Database/Eloquent/Builder.php index dbac4c2034c7..fe603c18fade 100755 --- a/src/Illuminate/Database/Eloquent/Builder.php +++ b/src/Illuminate/Database/Eloquent/Builder.php @@ -193,7 +193,7 @@ public function whereKey($id) return $this; } - if ($this->model->getKeyType() === 'string') { + if ($id !== null && $this->model->getKeyType() === 'string') { $id = (string) $id; } @@ -214,7 +214,7 @@ public function whereKeyNot($id) return $this; } - if ($this->model->getKeyType() === 'string') { + if ($id !== null && $this->model->getKeyType() === 'string') { $id = (string) $id; } diff --git a/tests/Database/DatabaseEloquentBuilderTest.php b/tests/Database/DatabaseEloquentBuilderTest.php index 54a46519d550..0b4530802a9d 100755 --- a/tests/Database/DatabaseEloquentBuilderTest.php +++ b/tests/Database/DatabaseEloquentBuilderTest.php @@ -1042,6 +1042,20 @@ public function testWhereKeyMethodWithStringZero() $builder->whereKey($int); } + /** @group Foo */ + public function testWhereKeyMethodWithStringNull() + { + $model = new EloquentBuilderTestStubStringPrimaryKey(); + $builder = $this->getBuilder()->setModel($model); + $keyName = $model->getQualifiedKeyName(); + + $builder->getQuery()->shouldReceive('where')->once()->with($keyName, '=', m::on(function ($argument) { + return $argument === null; + })); + + $builder->whereKey(null); + } + public function testWhereKeyMethodWithArray() { $model = $this->getMockModel(); @@ -1081,6 +1095,20 @@ public function testWhereKeyNotMethodWithStringZero() $builder->whereKeyNot($int); } + /** @group Foo */ + public function testWhereKeyNotMethodWithStringNull() + { + $model = new EloquentBuilderTestStubStringPrimaryKey(); + $builder = $this->getBuilder()->setModel($model); + $keyName = $model->getQualifiedKeyName(); + + $builder->getQuery()->shouldReceive('where')->once()->with($keyName, '!=', m::on(function ($argument) { + return $argument === null; + })); + + $builder->whereKeyNot(null); + } + public function testWhereKeyNotMethodWithInt() { $model = $this->getMockModel();