Skip to content

Commit f742a4b

Browse files
authored
Ignorables (#7)
* Added ability to ignore specific tables and sql statements. * Updated readme information for configuration.
1 parent c8ad1a9 commit f742a4b

File tree

4 files changed

+114
-1
lines changed

4 files changed

+114
-1
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,14 @@ Adjust the configuration file to suite your application.
6363
// i.e Console command or Request
6464
],
6565
],
66+
'ignorable_tables' => [
67+
'jobs' // Do you want to capture queries on specific tables?
68+
// If you are utilizing the database queue driver, you need to
69+
// ignore the jobs table or you'll get infinite capture loops.
70+
],
71+
'ignorable_statements' => [
72+
'create' // Do you want to ignore specific SQL statements?
73+
]
6674
],
6775
'listener' => [ // Channel notifications are queued
6876
'connection' => 'sync', // Define what connection to use.

config/querywatcher.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@
1717
'enabled' => true,
1818
],
1919
],
20+
'ignorable_tables' => [
21+
'jobs',
22+
],
23+
'ignorable_statements' => [
24+
'create',
25+
],
2026
],
2127
'listener' => [
2228
'connection' => 'sync',

src/QueryWatcher.php

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace YorCreative\QueryWatcher;
44

5+
use Illuminate\Database\Events\QueryExecuted;
56
use Illuminate\Support\Facades\Config;
67
use Illuminate\Support\Facades\DB;
78
use YorCreative\QueryWatcher\Events\QueryEvent;
@@ -18,7 +19,14 @@ public static function listen(): void
1819
$time_exceeds_ms_enabled = self::timeExceedsMsEnabled();
1920

2021
if ($time_exceeds_ms_enabled && self::getTimeExceedsMs() < $query->time
21-
|| ! $time_exceeds_ms_enabled) {
22+
|| ! $time_exceeds_ms_enabled
23+
&& ! self::ignorable($query)) {
24+
// only capture queries if:
25+
// - time_exceeds_ms is not enabled
26+
// - time_exceeds_ms is enabled and query time exceeds the threshold.
27+
// - query isn't on table that is ignorable.
28+
// - query isn't a sql statement that is ignorable
29+
2230
event(new QueryEvent($query));
2331
}
2432
});
@@ -44,4 +52,27 @@ public static function getTimeExceedsMs(): ?float
4452
{
4553
return config('querywatcher.scope.time_exceeds_ms.threshold') ?? 0;
4654
}
55+
56+
/**
57+
* @param QueryExecuted $queryExecuted
58+
* @return bool
59+
*/
60+
public static function ignorable(QueryExecuted $queryExecuted): bool
61+
{
62+
// check if query is on table that is ignorable
63+
foreach (Config::get('querywatcher.scope.ignorable_tables') as $table) {
64+
if (preg_match('~(from "'.$table.'"|update "'.$table.'"|into "'.$table.'")~i', $queryExecuted->sql)) {
65+
return true;
66+
}
67+
}
68+
69+
// check if query includes ignorable statement
70+
foreach (Config::get('querywatcher.scope.ignorable_statements') as $statement) {
71+
if (str_starts_with(strtolower($queryExecuted->sql), strtolower($statement))) {
72+
return true;
73+
}
74+
}
75+
76+
return false;
77+
}
4778
}

tests/Feature/CaptureQueryTest.php

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Illuminate\Foundation\Testing\DatabaseTransactions;
66
use Illuminate\Support\Facades\Auth;
7+
use Illuminate\Support\Facades\Config;
78
use Illuminate\Support\Facades\Event;
89
use Illuminate\Support\Facades\Http;
910
use YorCreative\QueryWatcher\Events\QueryEvent;
@@ -23,6 +24,73 @@ public function setUp(): void
2324
self::trackQueries();
2425
}
2526

27+
/**
28+
* @test
29+
* @group Feature
30+
*/
31+
public function it_can_ignore_a_query_by_ignorable_table_scope()
32+
{
33+
Event::fake();
34+
35+
Config::set('querywatcher.scope.ignorable_tables', [
36+
'tests',
37+
]);
38+
39+
(new Test())
40+
->newQuery()
41+
->create([
42+
'field' => 'testing',
43+
]);
44+
45+
(new Test())
46+
->newQuery()
47+
->get();
48+
49+
(new Test())
50+
->newQuery()
51+
->where('field', 'testing')
52+
->update([
53+
'field' => 'okay',
54+
]);
55+
56+
Event::assertNotDispatched(QueryEvent::class);
57+
58+
$this->assertQueryCountMatches(3);
59+
}
60+
61+
/**
62+
* @test
63+
* @group Feature
64+
*/
65+
public function it_can_ignore_a_query_by_ignorable_statement_scope()
66+
{
67+
HTTP::fake();
68+
69+
Config::set('querywatcher.scope.ignorable_statements', [
70+
'delete',
71+
]);
72+
73+
(new Test())
74+
->newQuery()
75+
->create([
76+
'field' => 'testing',
77+
]);
78+
79+
$tests = (new Test())
80+
->newQuery()
81+
->get();
82+
83+
$tests->first()->delete();
84+
85+
$this->assertEventBroadcasted(
86+
'query.event',
87+
null,
88+
2
89+
);
90+
91+
$this->assertQueryCountMatches(3);
92+
}
93+
2694
/**
2795
* @test
2896
* @group Feature

0 commit comments

Comments
 (0)