From 4d57cc63acfb35838a865979f1524877a4497ed6 Mon Sep 17 00:00:00 2001 From: Chris Morrell Date: Fri, 21 Jan 2022 16:20:39 -0500 Subject: [PATCH 1/5] Introduce annotated builder contracts --- .../Contracts/Database/Eloquent/Builder.php | 16 ++++++++++++++++ .../Contracts/Database/Query/Builder.php | 14 ++++++++++++++ src/Illuminate/Database/Eloquent/Builder.php | 3 ++- .../Database/Eloquent/Relations/Relation.php | 3 ++- src/Illuminate/Database/Query/Builder.php | 3 ++- 5 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 src/Illuminate/Contracts/Database/Eloquent/Builder.php create mode 100644 src/Illuminate/Contracts/Database/Query/Builder.php diff --git a/src/Illuminate/Contracts/Database/Eloquent/Builder.php b/src/Illuminate/Contracts/Database/Eloquent/Builder.php new file mode 100644 index 000000000000..0e3296366b4c --- /dev/null +++ b/src/Illuminate/Contracts/Database/Eloquent/Builder.php @@ -0,0 +1,16 @@ + Date: Fri, 21 Jan 2022 16:25:24 -0500 Subject: [PATCH 2/5] Add tests from previous branch --- ...baseEloquentSoftDeletesIntegrationTest.php | 104 ++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/tests/Database/DatabaseEloquentSoftDeletesIntegrationTest.php b/tests/Database/DatabaseEloquentSoftDeletesIntegrationTest.php index 786c9c35242b..35940d457e47 100644 --- a/tests/Database/DatabaseEloquentSoftDeletesIntegrationTest.php +++ b/tests/Database/DatabaseEloquentSoftDeletesIntegrationTest.php @@ -52,6 +52,7 @@ public function createSchema() $table->increments('id'); $table->integer('user_id'); $table->string('title'); + $table->integer('priority')->default(0); $table->timestamps(); $table->softDeletes(); }); @@ -491,6 +492,109 @@ public function testHasManyRelationshipCanBeSoftDeleted() $this->assertCount(1, $abigail->posts()->withTrashed()->get()); } + public function testRelationToSqlAppliesSoftDelete() + { + $this->createUsers(); + + $abigail = SoftDeletesTestUser::where('email', 'abigailotwell@gmail.com')->first(); + + $this->assertSame( + 'select * from "posts" where "posts"."user_id" = ? and "posts"."user_id" is not null and "posts"."deleted_at" is null', + $abigail->posts()->toSql() + ); + } + + public function testRelationExistsAndDoesntExistHonorsSoftDelete() + { + $this->createUsers(); + $abigail = SoftDeletesTestUser::where('email', 'abigailotwell@gmail.com')->first(); + + // 'exists' should return true before soft delete + $abigail->posts()->create(['title' => 'First Title']); + $this->assertTrue($abigail->posts()->exists()); + $this->assertFalse($abigail->posts()->doesntExist()); + + // 'exists' should return false after soft delete + $abigail->posts()->first()->delete(); + $this->assertFalse($abigail->posts()->exists()); + $this->assertTrue($abigail->posts()->doesntExist()); + + // 'exists' should return true after restore + $abigail->posts()->withTrashed()->restore(); + $this->assertTrue($abigail->posts()->exists()); + $this->assertFalse($abigail->posts()->doesntExist()); + + // 'exists' should return false after a force delete + $abigail->posts()->first()->forceDelete(); + $this->assertFalse($abigail->posts()->exists()); + $this->assertTrue($abigail->posts()->doesntExist()); + } + + public function testRelationCountHonorsSoftDelete() + { + $this->createUsers(); + $abigail = SoftDeletesTestUser::where('email', 'abigailotwell@gmail.com')->first(); + + // check count before soft delete + $abigail->posts()->create(['title' => 'First Title']); + $abigail->posts()->create(['title' => 'Second Title']); + $this->assertEquals(2, $abigail->posts()->count()); + + // check count after soft delete + $abigail->posts()->where('title', 'Second Title')->delete(); + $this->assertEquals(1, $abigail->posts()->count()); + + // check count after restore + $abigail->posts()->withTrashed()->restore(); + $this->assertEquals(2, $abigail->posts()->count()); + + // check count after a force delete + $abigail->posts()->where('title', 'Second Title')->forceDelete(); + $this->assertEquals(1, $abigail->posts()->count()); + } + + public function testRelationAggregatesHonorsSoftDelete() + { + $this->createUsers(); + $abigail = SoftDeletesTestUser::where('email', 'abigailotwell@gmail.com')->first(); + + // check aggregates before soft delete + $abigail->posts()->create(['title' => 'First Title', 'priority' => 2]); + $abigail->posts()->create(['title' => 'Second Title', 'priority' => 4]); + $abigail->posts()->create(['title' => 'Third Title', 'priority' => 6]); + $this->assertEquals(2, $abigail->posts()->min('priority')); + $this->assertEquals(6, $abigail->posts()->max('priority')); + $this->assertEquals(12, $abigail->posts()->sum('priority')); + $this->assertEquals(4, $abigail->posts()->avg('priority')); + + // check aggregates after soft delete + $abigail->posts()->where('title', 'First Title')->delete(); + $this->assertEquals(4, $abigail->posts()->min('priority')); + $this->assertEquals(6, $abigail->posts()->max('priority')); + $this->assertEquals(10, $abigail->posts()->sum('priority')); + $this->assertEquals(5, $abigail->posts()->avg('priority')); + + // check aggregates after restore + $abigail->posts()->withTrashed()->restore(); + $this->assertEquals(2, $abigail->posts()->min('priority')); + $this->assertEquals(6, $abigail->posts()->max('priority')); + $this->assertEquals(12, $abigail->posts()->sum('priority')); + $this->assertEquals(4, $abigail->posts()->avg('priority')); + + // check aggregates after a force delete + $abigail->posts()->where('title', 'Third Title')->forceDelete(); + $this->assertEquals(2, $abigail->posts()->min('priority')); + $this->assertEquals(4, $abigail->posts()->max('priority')); + $this->assertEquals(6, $abigail->posts()->sum('priority')); + $this->assertEquals(3, $abigail->posts()->avg('priority')); + } + + public function testSoftDeleteIsAppliedToNewQuery() + { + $query = (new SoftDeletesTestUser)->newQuery(); + $this->assertSame('select * from "users" where "users"."deleted_at" is null', $query->toSql()); + } + public function testSecondLevelRelationshipCanBeSoftDeleted() { $this->createUsers(); From 38d617d156c5af085ccf74685b9ba4346b627d91 Mon Sep 17 00:00:00 2001 From: Chris Morrell Date: Fri, 21 Jan 2022 16:38:11 -0500 Subject: [PATCH 3/5] StyleCI --- src/Illuminate/Contracts/Database/Eloquent/Builder.php | 1 - src/Illuminate/Contracts/Database/Query/Builder.php | 1 - 2 files changed, 2 deletions(-) diff --git a/src/Illuminate/Contracts/Database/Eloquent/Builder.php b/src/Illuminate/Contracts/Database/Eloquent/Builder.php index 0e3296366b4c..e6c82145193e 100644 --- a/src/Illuminate/Contracts/Database/Eloquent/Builder.php +++ b/src/Illuminate/Contracts/Database/Eloquent/Builder.php @@ -12,5 +12,4 @@ */ interface Builder extends BaseContract { - } diff --git a/src/Illuminate/Contracts/Database/Query/Builder.php b/src/Illuminate/Contracts/Database/Query/Builder.php index 8f3149ea372d..bd0efb1c19be 100644 --- a/src/Illuminate/Contracts/Database/Query/Builder.php +++ b/src/Illuminate/Contracts/Database/Query/Builder.php @@ -10,5 +10,4 @@ */ interface Builder { - } From 5cd1f60e8d990513ad8d7397d39c29b5d73cfc8f Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Mon, 24 Jan 2022 11:26:42 -0600 Subject: [PATCH 4/5] Update Builder.php --- src/Illuminate/Contracts/Database/Eloquent/Builder.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Illuminate/Contracts/Database/Eloquent/Builder.php b/src/Illuminate/Contracts/Database/Eloquent/Builder.php index e6c82145193e..6fdf405c9954 100644 --- a/src/Illuminate/Contracts/Database/Eloquent/Builder.php +++ b/src/Illuminate/Contracts/Database/Eloquent/Builder.php @@ -5,8 +5,7 @@ use Illuminate\Contracts\Database\Query\Builder as BaseContract; /** - * This interface is intentionally empty and exists mostly to improve IDE support - * and provide a simple type-hinting option for those who prefer it. + * This interface is intentionally empty and exists to improve IDE support. * * @mixin \Illuminate\Database\Eloquent\Builder */ From 9f394a272db8ac40c981b55a7f8d75c8d480e885 Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Mon, 24 Jan 2022 11:26:59 -0600 Subject: [PATCH 5/5] Update Builder.php --- src/Illuminate/Contracts/Database/Query/Builder.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Illuminate/Contracts/Database/Query/Builder.php b/src/Illuminate/Contracts/Database/Query/Builder.php index bd0efb1c19be..e116ebf41964 100644 --- a/src/Illuminate/Contracts/Database/Query/Builder.php +++ b/src/Illuminate/Contracts/Database/Query/Builder.php @@ -3,8 +3,7 @@ namespace Illuminate\Contracts\Database\Query; /** - * This interface is intentionally empty and exists mostly to improve IDE support - * and provide a simple type-hinting option for those who prefer it. + * This interface is intentionally empty and exists to improve IDE support. * * @mixin \Illuminate\Database\Query\Builder */