From 28ecd2d5cc05c3619f99af42611877f54371af20 Mon Sep 17 00:00:00 2001 From: erikn69 Date: Wed, 26 Jun 2024 15:56:28 -0500 Subject: [PATCH] Fix database prune, offset not working on some dbs (#948) * Use left join to optimize prune query, and avoid using offset --- src/Drivers/Database.php | 17 +++++++++++++++-- tests/Functional/AuditingTest.php | 15 +++++++++++---- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/Drivers/Database.php b/src/Drivers/Database.php index a762ff66..71bfcf76 100644 --- a/src/Drivers/Database.php +++ b/src/Drivers/Database.php @@ -23,9 +23,22 @@ public function audit(Auditable $model): ?Audit public function prune(Auditable $model): bool { if (($threshold = $model->getAuditThreshold()) > 0) { + $auditClass = get_class($model->audits()->getModel()); + $auditModel = new $auditClass; + return $model->audits() - ->latest() - ->offset($threshold)->limit(PHP_INT_MAX) + ->leftJoinSub( + $model->audits()->select($auditModel->getKeyName())->limit($threshold)->latest(), + 'audit_threshold', + function ($join) use ($auditModel) { + $join->on( + $auditModel->gettable().'.'.$auditModel->getKeyName(), + '=', + 'audit_threshold.'.$auditModel->getKeyName() + ); + } + ) + ->whereNull('audit_threshold.'.$auditModel->getKeyName()) ->delete() > 0; } diff --git a/tests/Functional/AuditingTest.php b/tests/Functional/AuditingTest.php index ffef3721..6bc063d6 100644 --- a/tests/Functional/AuditingTest.php +++ b/tests/Functional/AuditingTest.php @@ -297,16 +297,23 @@ public function itWillRemoveOlderAuditsAboveTheThreshold() ]); $article = factory(Article::class)->create([ - 'reviewed' => 1, + 'title' => 'Title #0', ]); - foreach (range(0, 99) as $count) { + foreach (range(1, 20) as $count) { + if ($count === 11) { + sleep(1); + } + $article->update([ - 'reviewed' => ($count % 2), + 'title' => 'Title #' . $count, ]); } - $this->assertSame(10, $article->audits()->count()); + $audits = $article->audits()->get(); + $this->assertSame(10, $audits->count()); + $this->assertSame('Title #11', $audits->first()->new_values['title']); + $this->assertSame('Title #20', $audits->last()->new_values['title']); } /**