From f2ae7d0e36e82a1dcafdc4850c90e4aab4ac74d1 Mon Sep 17 00:00:00 2001 From: Patrick O'Meara Date: Thu, 25 Jul 2024 20:47:39 +1000 Subject: [PATCH 01/23] Add ConditionalQueryWatcher This piggybacks of the QueryWatcher but only sends queries to ray that satify a conditional callback I've added update here as a helper method. --- src/Ray.php | 32 +++++++++++++++++ src/Watchers/ConditionalQueryWatcher.php | 45 ++++++++++++++++++++++++ tests/Unit/QueryTest.php | 42 ++++++++++++++++++++++ 3 files changed, 119 insertions(+) create mode 100644 src/Watchers/ConditionalQueryWatcher.php diff --git a/src/Ray.php b/src/Ray.php index 7f4ac17..e9a0088 100644 --- a/src/Ray.php +++ b/src/Ray.php @@ -26,6 +26,7 @@ use Spatie\LaravelRay\Payloads\ResponsePayload; use Spatie\LaravelRay\Payloads\ViewPayload; use Spatie\LaravelRay\Watchers\CacheWatcher; +use Spatie\LaravelRay\Watchers\ConditionalQueryWatcher; use Spatie\LaravelRay\Watchers\DuplicateQueryWatcher; use Spatie\LaravelRay\Watchers\EventWatcher; use Spatie\LaravelRay\Watchers\ExceptionWatcher; @@ -433,6 +434,37 @@ public function stopShowingDuplicateQueries(): self return $this; } + public function showConditionalQueries(Closure $condition, $callable = null, $name = 'default') + { + $watcher = app()->instance(ConditionalQueryWatcher::class.':'.$name, new ConditionalQueryWatcher($condition)); + + return $this->handleWatcherCallable($watcher, $callable); + } + + public function stopShowingConditionalQueries($name = 'default'): self + { + app(ConditionalQueryWatcher::class.':'.$name)->disable(); + + return $this; + } + + public function showUpdateQueries($callable = null) + { + return $this + ->showConditionalQueries( + function (string $query) { + return str_starts_with(strtolower($query), 'update'); + }, + $callable, + 'send_update_queries_to_ray', + ); + } + + public function stopShowingUpdateQueries(): self + { + return $this->stopShowingConditionalQueries('send_update_queries_to_ray'); + } + /** * @param null $callable * diff --git a/src/Watchers/ConditionalQueryWatcher.php b/src/Watchers/ConditionalQueryWatcher.php new file mode 100644 index 0000000..09a24ca --- /dev/null +++ b/src/Watchers/ConditionalQueryWatcher.php @@ -0,0 +1,45 @@ +conditionalCallback = $conditionalCallback; + + $this->register(); + + $this->enable(); + } + + public function register(): void + { + Event::listen(QueryExecuted::class, function (QueryExecuted $query) { + if (! $this->enabled()) { + return; + } + + if (! $this->conditionalCallback) { + return; + } + + $ray = app(Ray::class); + + if (($this->conditionalCallback)($query->toRawSql())) { + $payload = new ExecutedQueryPayload($query); + + $ray->sendRequest($payload); + } + + optional($this->rayProxy)->applyCalledMethods($ray); + }); + } +} diff --git a/tests/Unit/QueryTest.php b/tests/Unit/QueryTest.php index 1aabf50..cde2451 100644 --- a/tests/Unit/QueryTest.php +++ b/tests/Unit/QueryTest.php @@ -104,3 +104,45 @@ expect($user)->toBeInstanceOf(User::class); }); + +it('can show only update queries', function () { + ray()->showUpdateQueries(); + + $user = User::query()->create(['email' => 'john@example.com']); + $user->update(['email' => 'joan@example.com']); + $user = User::query()->find($user->id); + $user->delete(); + + expect($this->client->sentPayloads())->toHaveCount(1); + + $payload = $this->client->sentPayloads(); + + $this->assertStringStartsWith('update', Arr::get($payload, '0.content.sql')); +}); + +it('can show only update queries and return the results', function () { + $user = ray()->showUpdateQueries(function (): User { + $user = User::query()->create(['email' => 'john@example.com']); + $user->update(['email' => 'joan@example.com']); + + return $user; + }); + + expect($this->client->sentRequests())->toHaveCount(1); + expect($user)->toBeInstanceOf(User::class); + + $this->assertSame('joan@example.com', $user->email); +}); + +it('can stop showing update queries', function () { + $user = User::query() + ->create(['email' => 'john@example.com']); + + ray()->showUpdateQueries(); + $user->update(['email' => 'joan@example.com']); + ray()->stopShowingUpdateQueries(); + $user->update(['email' => 'joe@example.com']); + + expect($this->client->sentRequests())->toHaveCount(1); +}); + From 57ff4cab7504390051a9db7c67c47cb2175e5fc6 Mon Sep 17 00:00:00 2001 From: Patrick O'Meara Date: Thu, 25 Jul 2024 21:07:16 +1000 Subject: [PATCH 02/23] Show delete queries --- src/Ray.php | 17 +++++++++++++++++ tests/Unit/QueryTest.php | 17 +++++++++++++++-- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/Ray.php b/src/Ray.php index e9a0088..1fd4d90 100644 --- a/src/Ray.php +++ b/src/Ray.php @@ -465,6 +465,23 @@ public function stopShowingUpdateQueries(): self return $this->stopShowingConditionalQueries('send_update_queries_to_ray'); } + public function showDeleteQueries($callable = null) + { + return $this + ->showConditionalQueries( + function (string $query) { + return str_starts_with(strtolower($query), 'delete'); + }, + $callable, + 'send_delete_queries_to_ray', + ); + } + + public function stopShowingDeleteQueries(): self + { + return $this->stopShowingConditionalQueries('send_delete_queries_to_ray'); + } + /** * @param null $callable * diff --git a/tests/Unit/QueryTest.php b/tests/Unit/QueryTest.php index cde2451..f8c37dc 100644 --- a/tests/Unit/QueryTest.php +++ b/tests/Unit/QueryTest.php @@ -135,8 +135,7 @@ }); it('can stop showing update queries', function () { - $user = User::query() - ->create(['email' => 'john@example.com']); + $user = User::query()->create(['email' => 'john@example.com']); ray()->showUpdateQueries(); $user->update(['email' => 'joan@example.com']); @@ -146,3 +145,17 @@ expect($this->client->sentRequests())->toHaveCount(1); }); +it('can show only delete queries', function () { + ray()->showDeleteQueries(); + + $user = User::query()->create(['email' => 'john@example.com']); + $user->update(['email' => 'joan@example.com']); + $user = User::query()->find($user->id); + $user->delete(); + + expect($this->client->sentPayloads())->toHaveCount(1); + + $payload = $this->client->sentPayloads(); + + $this->assertStringStartsWith('delete', Arr::get($payload, '0.content.sql')); +}); From fb42c39e078b227b36453926c2dda262b712f0d9 Mon Sep 17 00:00:00 2001 From: Patrick O'Meara Date: Fri, 26 Jul 2024 05:21:40 +1000 Subject: [PATCH 03/23] Show Insert queries --- src/Ray.php | 17 +++++++++++++++++ tests/Unit/QueryTest.php | 15 +++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/Ray.php b/src/Ray.php index 1fd4d90..5aa5db8 100644 --- a/src/Ray.php +++ b/src/Ray.php @@ -482,6 +482,23 @@ public function stopShowingDeleteQueries(): self return $this->stopShowingConditionalQueries('send_delete_queries_to_ray'); } + public function showInsertQueries($callable = null) + { + return $this + ->showConditionalQueries( + function (string $query) { + return str_starts_with(strtolower($query), 'insert'); + }, + $callable, + 'send_insert_queries_to_ray', + ); + } + + public function stopShowingInsertQueries(): self + { + return $this->stopShowingConditionalQueries('send_insert_queries_to_ray'); + } + /** * @param null $callable * diff --git a/tests/Unit/QueryTest.php b/tests/Unit/QueryTest.php index f8c37dc..0996ce5 100644 --- a/tests/Unit/QueryTest.php +++ b/tests/Unit/QueryTest.php @@ -159,3 +159,18 @@ $this->assertStringStartsWith('delete', Arr::get($payload, '0.content.sql')); }); + +it('can show only insert queries', function () { + ray()->showInsertQueries(); + + $user = User::query()->create(['email' => 'john@example.com']); + $user->update(['email' => 'joan@example.com']); + $user = User::query()->find($user->id); + $user->delete(); + + expect($this->client->sentPayloads())->toHaveCount(1); + + $payload = $this->client->sentPayloads(); + + $this->assertStringStartsWith('insert', Arr::get($payload, '0.content.sql')); +}); From a3a947aa11330767c970215cef9e010945f4e8b3 Mon Sep 17 00:00:00 2001 From: Patrick O'Meara Date: Fri, 26 Jul 2024 05:30:40 +1000 Subject: [PATCH 04/23] show select queries --- src/Ray.php | 17 +++++++++++++++++ tests/Unit/QueryTest.php | 15 +++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/Ray.php b/src/Ray.php index 5aa5db8..1622041 100644 --- a/src/Ray.php +++ b/src/Ray.php @@ -499,6 +499,23 @@ public function stopShowingInsertQueries(): self return $this->stopShowingConditionalQueries('send_insert_queries_to_ray'); } + public function showSelectQueries($callable = null) + { + return $this + ->showConditionalQueries( + function (string $query) { + return str_starts_with(strtolower($query), 'select'); + }, + $callable, + 'send_select_queries_to_ray', + ); + } + + public function stopShowingSelectQueries(): self + { + return $this->stopShowingConditionalQueries('send_select_queries_to_ray'); + } + /** * @param null $callable * diff --git a/tests/Unit/QueryTest.php b/tests/Unit/QueryTest.php index 0996ce5..eb342a6 100644 --- a/tests/Unit/QueryTest.php +++ b/tests/Unit/QueryTest.php @@ -174,3 +174,18 @@ $this->assertStringStartsWith('insert', Arr::get($payload, '0.content.sql')); }); + +it('can show only select queries', function () { + ray()->showSelectQueries(); + + $user = User::query()->create(['email' => 'john@example.com']); + $user->update(['email' => 'joan@example.com']); + $user = User::query()->find($user->id); + $user->delete(); + + expect($this->client->sentPayloads())->toHaveCount(1); + + $payload = $this->client->sentPayloads(); + + $this->assertStringStartsWith('select', Arr::get($payload, '0.content.sql')); +}); From 7bcbad6f36f71c2f39f2227187624469c05797a5 Mon Sep 17 00:00:00 2001 From: Patrick O'Meara Date: Fri, 26 Jul 2024 06:00:00 +1000 Subject: [PATCH 05/23] Use data provider to clean up tests --- tests/Unit/QueryTest.php | 58 +++++++--------------------------------- 1 file changed, 9 insertions(+), 49 deletions(-) diff --git a/tests/Unit/QueryTest.php b/tests/Unit/QueryTest.php index eb342a6..82b124e 100644 --- a/tests/Unit/QueryTest.php +++ b/tests/Unit/QueryTest.php @@ -105,21 +105,6 @@ expect($user)->toBeInstanceOf(User::class); }); -it('can show only update queries', function () { - ray()->showUpdateQueries(); - - $user = User::query()->create(['email' => 'john@example.com']); - $user->update(['email' => 'joan@example.com']); - $user = User::query()->find($user->id); - $user->delete(); - - expect($this->client->sentPayloads())->toHaveCount(1); - - $payload = $this->client->sentPayloads(); - - $this->assertStringStartsWith('update', Arr::get($payload, '0.content.sql')); -}); - it('can show only update queries and return the results', function () { $user = ray()->showUpdateQueries(function (): User { $user = User::query()->create(['email' => 'john@example.com']); @@ -145,23 +130,8 @@ expect($this->client->sentRequests())->toHaveCount(1); }); -it('can show only delete queries', function () { - ray()->showDeleteQueries(); - - $user = User::query()->create(['email' => 'john@example.com']); - $user->update(['email' => 'joan@example.com']); - $user = User::query()->find($user->id); - $user->delete(); - - expect($this->client->sentPayloads())->toHaveCount(1); - - $payload = $this->client->sentPayloads(); - - $this->assertStringStartsWith('delete', Arr::get($payload, '0.content.sql')); -}); - -it('can show only insert queries', function () { - ray()->showInsertQueries(); +it('can show only type queries', function (Closure $showMethod, string $sqlCommand) { + $showMethod(); $user = User::query()->create(['email' => 'john@example.com']); $user->update(['email' => 'joan@example.com']); @@ -172,20 +142,10 @@ $payload = $this->client->sentPayloads(); - $this->assertStringStartsWith('insert', Arr::get($payload, '0.content.sql')); -}); - -it('can show only select queries', function () { - ray()->showSelectQueries(); - - $user = User::query()->create(['email' => 'john@example.com']); - $user->update(['email' => 'joan@example.com']); - $user = User::query()->find($user->id); - $user->delete(); - - expect($this->client->sentPayloads())->toHaveCount(1); - - $payload = $this->client->sentPayloads(); - - $this->assertStringStartsWith('select', Arr::get($payload, '0.content.sql')); -}); + $this->assertStringStartsWith($sqlCommand, Arr::get($payload, '0.content.sql')); +})->with([ + 'update' => [function () {ray()->showUpdateQueries();}, 'update'], + 'delete' => [function () {ray()->showDeleteQueries();}, 'delete'], + 'insert' => [function () {ray()->showInsertQueries();}, 'insert'], + 'select' => [function () {ray()->showSelectQueries();}, 'select'], +]); From 48fb6808c2de05ea4b19a98994c20d6ee1eec0bc Mon Sep 17 00:00:00 2001 From: Patrick O'Meara Date: Fri, 26 Jul 2024 06:01:50 +1000 Subject: [PATCH 06/23] Move into separate test --- tests/Unit/ConditionalQueryTest.php | 49 +++++++++++++++++++++++++++++ tests/Unit/QueryTest.php | 45 -------------------------- 2 files changed, 49 insertions(+), 45 deletions(-) create mode 100644 tests/Unit/ConditionalQueryTest.php diff --git a/tests/Unit/ConditionalQueryTest.php b/tests/Unit/ConditionalQueryTest.php new file mode 100644 index 0000000..7526a4e --- /dev/null +++ b/tests/Unit/ConditionalQueryTest.php @@ -0,0 +1,49 @@ +showUpdateQueries(function (): User { + $user = User::query()->create(['email' => 'john@example.com']); + $user->update(['email' => 'joan@example.com']); + + return $user; + }); + + expect($this->client->sentRequests())->toHaveCount(1); + expect($user)->toBeInstanceOf(User::class); + + $this->assertSame('joan@example.com', $user->email); +}); + +it('can stop showing update queries', function () { + $user = User::query()->create(['email' => 'john@example.com']); + + ray()->showUpdateQueries(); + $user->update(['email' => 'joan@example.com']); + ray()->stopShowingUpdateQueries(); + $user->update(['email' => 'joe@example.com']); + + expect($this->client->sentRequests())->toHaveCount(1); +}); + +it('can show only type queries', function (Closure $rayShowMethod, string $sqlCommand) { + $rayShowMethod(); + + $user = User::query()->create(['email' => 'john@example.com']); + $user->update(['email' => 'joan@example.com']); + $user = User::query()->find($user->id); + $user->delete(); + + expect($this->client->sentPayloads())->toHaveCount(1); + + $payload = $this->client->sentPayloads(); + + $this->assertStringStartsWith($sqlCommand, Arr::get($payload, '0.content.sql')); +})->with([ + 'update' => [function () {ray()->showUpdateQueries();}, 'update'], + 'delete' => [function () {ray()->showDeleteQueries();}, 'delete'], + 'insert' => [function () {ray()->showInsertQueries();}, 'insert'], + 'select' => [function () {ray()->showSelectQueries();}, 'select'], +]); diff --git a/tests/Unit/QueryTest.php b/tests/Unit/QueryTest.php index 82b124e..1aabf50 100644 --- a/tests/Unit/QueryTest.php +++ b/tests/Unit/QueryTest.php @@ -104,48 +104,3 @@ expect($user)->toBeInstanceOf(User::class); }); - -it('can show only update queries and return the results', function () { - $user = ray()->showUpdateQueries(function (): User { - $user = User::query()->create(['email' => 'john@example.com']); - $user->update(['email' => 'joan@example.com']); - - return $user; - }); - - expect($this->client->sentRequests())->toHaveCount(1); - expect($user)->toBeInstanceOf(User::class); - - $this->assertSame('joan@example.com', $user->email); -}); - -it('can stop showing update queries', function () { - $user = User::query()->create(['email' => 'john@example.com']); - - ray()->showUpdateQueries(); - $user->update(['email' => 'joan@example.com']); - ray()->stopShowingUpdateQueries(); - $user->update(['email' => 'joe@example.com']); - - expect($this->client->sentRequests())->toHaveCount(1); -}); - -it('can show only type queries', function (Closure $showMethod, string $sqlCommand) { - $showMethod(); - - $user = User::query()->create(['email' => 'john@example.com']); - $user->update(['email' => 'joan@example.com']); - $user = User::query()->find($user->id); - $user->delete(); - - expect($this->client->sentPayloads())->toHaveCount(1); - - $payload = $this->client->sentPayloads(); - - $this->assertStringStartsWith($sqlCommand, Arr::get($payload, '0.content.sql')); -})->with([ - 'update' => [function () {ray()->showUpdateQueries();}, 'update'], - 'delete' => [function () {ray()->showDeleteQueries();}, 'delete'], - 'insert' => [function () {ray()->showInsertQueries();}, 'insert'], - 'select' => [function () {ray()->showSelectQueries();}, 'select'], -]); From 9e41ad870888f02e8af5f4216309f2a2d6fa89e4 Mon Sep 17 00:00:00 2001 From: Patrick O'Meara Date: Fri, 26 Jul 2024 07:49:45 +1000 Subject: [PATCH 07/23] This doesn't register only listens --- src/Watchers/ConditionalQueryWatcher.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Watchers/ConditionalQueryWatcher.php b/src/Watchers/ConditionalQueryWatcher.php index 09a24ca..25533f7 100644 --- a/src/Watchers/ConditionalQueryWatcher.php +++ b/src/Watchers/ConditionalQueryWatcher.php @@ -15,12 +15,10 @@ public function __construct($conditionalCallback) { $this->conditionalCallback = $conditionalCallback; - $this->register(); - - $this->enable(); + $this->listen(); } - public function register(): void + public function listen(): void { Event::listen(QueryExecuted::class, function (QueryExecuted $query) { if (! $this->enabled()) { From cc39935dd22a9cd032725b169bceacf8721142fc Mon Sep 17 00:00:00 2001 From: Patrick O'Meara Date: Fri, 26 Jul 2024 08:03:37 +1000 Subject: [PATCH 08/23] UpdateQueryWatcher --- src/Ray.php | 16 +++++++--------- src/RayServiceProvider.php | 6 ++++++ src/Watchers/UpdateQueryWatcher.php | 26 ++++++++++++++++++++++++++ stub/ray.php | 20 ++++++++++++++++++++ 4 files changed, 59 insertions(+), 9 deletions(-) create mode 100644 src/Watchers/UpdateQueryWatcher.php diff --git a/src/Ray.php b/src/Ray.php index 1622041..f650df4 100644 --- a/src/Ray.php +++ b/src/Ray.php @@ -35,6 +35,7 @@ use Spatie\LaravelRay\Watchers\QueryWatcher; use Spatie\LaravelRay\Watchers\RequestWatcher; use Spatie\LaravelRay\Watchers\SlowQueryWatcher; +use Spatie\LaravelRay\Watchers\UpdateQueryWatcher; use Spatie\LaravelRay\Watchers\ViewWatcher; use Spatie\LaravelRay\Watchers\Watcher; use Spatie\Ray\Client; @@ -450,19 +451,16 @@ public function stopShowingConditionalQueries($name = 'default'): self public function showUpdateQueries($callable = null) { - return $this - ->showConditionalQueries( - function (string $query) { - return str_starts_with(strtolower($query), 'update'); - }, - $callable, - 'send_update_queries_to_ray', - ); + $watcher = app(UpdateQueryWatcher::class); + + return $this->handleWatcherCallable($watcher, $callable); } public function stopShowingUpdateQueries(): self { - return $this->stopShowingConditionalQueries('send_update_queries_to_ray'); + app(UpdateQueryWatcher::class)->disable(); + + return $this; } public function showDeleteQueries($callable = null) diff --git a/src/RayServiceProvider.php b/src/RayServiceProvider.php index 489185c..7421f36 100644 --- a/src/RayServiceProvider.php +++ b/src/RayServiceProvider.php @@ -29,6 +29,7 @@ use Spatie\LaravelRay\Watchers\QueryWatcher; use Spatie\LaravelRay\Watchers\RequestWatcher; use Spatie\LaravelRay\Watchers\SlowQueryWatcher; +use Spatie\LaravelRay\Watchers\UpdateQueryWatcher; use Spatie\LaravelRay\Watchers\ViewWatcher; use Spatie\Ray\Client; use Spatie\Ray\PayloadFactory; @@ -79,6 +80,10 @@ protected function registerSettings(): self 'send_queries_to_ray' => env('SEND_QUERIES_TO_RAY', false), 'send_duplicate_queries_to_ray' => env('SEND_DUPLICATE_QUERIES_TO_RAY', false), 'send_slow_queries_to_ray' => env('SEND_SLOW_QUERIES_TO_RAY', false), + 'send_update_queries_to_ray' => env('SEND_UPDATE_QUERIES_TO_RAY', false), + 'send_insert_queries_to_ray' => env('SEND_INSERT_QUERIES_TO_RAY', false), + 'send_delete_queries_to_ray' => env('SEND_DELETE_QUERIES_TO_RAY', false), + 'send_select_queries_to_ray' => env('SEND_SELECT_QUERIES_TO_RAY', false), 'send_requests_to_ray' => env('SEND_REQUESTS_TO_RAY', false), 'send_http_client_requests_to_ray' => env('SEND_HTTP_CLIENT_REQUESTS_TO_RAY', false), 'send_views_to_ray' => env('SEND_VIEWS_TO_RAY', false), @@ -142,6 +147,7 @@ protected function registerWatchers(): self QueryWatcher::class, DuplicateQueryWatcher::class, SlowQueryWatcher::class, + UpdateQueryWatcher::class, ViewWatcher::class, CacheWatcher::class, RequestWatcher::class, diff --git a/src/Watchers/UpdateQueryWatcher.php b/src/Watchers/UpdateQueryWatcher.php new file mode 100644 index 0000000..ecb9688 --- /dev/null +++ b/src/Watchers/UpdateQueryWatcher.php @@ -0,0 +1,26 @@ +enabled = $settings->send_update_queries_to_ray ?? false; + } +} diff --git a/stub/ray.php b/stub/ray.php index ce7a33b..5822d18 100644 --- a/stub/ray.php +++ b/stub/ray.php @@ -50,6 +50,26 @@ */ 'slow_query_threshold_in_ms' => env('RAY_SLOW_QUERY_THRESHOLD_IN_MS', 500), + /* + * When enabled, all update queries will automatically be sent to Ray. + */ + 'send_update_queries_to_ray' => env('SEND_UPDATE_QUERIES_TO_RAY', false), + + /* + * When enabled, all update queries will automatically be sent to Ray. + */ + 'send_insert_queries_to_ray' => env('SEND_INSERT_QUERIES_TO_RAY', false), + + /* + * When enabled, all update queries will automatically be sent to Ray. + */ + 'send_delete_queries_to_ray' => env('SEND_DELETE_QUERIES_TO_RAY', false), + + /* + * When enabled, all update queries will automatically be sent to Ray. + */ + 'send_select_queries_to_ray' => env('SEND_SELECT_QUERIES_TO_RAY', false), + /* * When enabled, all requests made to this app will automatically be sent to Ray. */ From 5893ca3ddf480d49e12f05c8b8343e5a3521375f Mon Sep 17 00:00:00 2001 From: Patrick O'Meara Date: Fri, 26 Jul 2024 08:07:44 +1000 Subject: [PATCH 09/23] DeleteQueryWatcher --- src/Ray.php | 14 +++++--------- src/RayServiceProvider.php | 2 ++ src/Watchers/DeleteQueryWatcher.php | 26 ++++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 9 deletions(-) create mode 100644 src/Watchers/DeleteQueryWatcher.php diff --git a/src/Ray.php b/src/Ray.php index f650df4..34a9c54 100644 --- a/src/Ray.php +++ b/src/Ray.php @@ -27,6 +27,7 @@ use Spatie\LaravelRay\Payloads\ViewPayload; use Spatie\LaravelRay\Watchers\CacheWatcher; use Spatie\LaravelRay\Watchers\ConditionalQueryWatcher; +use Spatie\LaravelRay\Watchers\DeleteQueryWatcher; use Spatie\LaravelRay\Watchers\DuplicateQueryWatcher; use Spatie\LaravelRay\Watchers\EventWatcher; use Spatie\LaravelRay\Watchers\ExceptionWatcher; @@ -465,19 +466,14 @@ public function stopShowingUpdateQueries(): self public function showDeleteQueries($callable = null) { - return $this - ->showConditionalQueries( - function (string $query) { - return str_starts_with(strtolower($query), 'delete'); - }, - $callable, - 'send_delete_queries_to_ray', - ); + $watcher = app(DeleteQueryWatcher::class); + + return $this->handleWatcherCallable($watcher, $callable); } public function stopShowingDeleteQueries(): self { - return $this->stopShowingConditionalQueries('send_delete_queries_to_ray'); + return app(DeleteQueryWatcher::class)->disable(); } public function showInsertQueries($callable = null) diff --git a/src/RayServiceProvider.php b/src/RayServiceProvider.php index 7421f36..e9114f4 100644 --- a/src/RayServiceProvider.php +++ b/src/RayServiceProvider.php @@ -18,6 +18,7 @@ use Spatie\LaravelRay\Payloads\QueryPayload; use Spatie\LaravelRay\Watchers\ApplicationLogWatcher; use Spatie\LaravelRay\Watchers\CacheWatcher; +use Spatie\LaravelRay\Watchers\DeleteQueryWatcher; use Spatie\LaravelRay\Watchers\DeprecatedNoticeWatcher; use Spatie\LaravelRay\Watchers\DumpWatcher; use Spatie\LaravelRay\Watchers\DuplicateQueryWatcher; @@ -148,6 +149,7 @@ protected function registerWatchers(): self DuplicateQueryWatcher::class, SlowQueryWatcher::class, UpdateQueryWatcher::class, + DeleteQueryWatcher::class, ViewWatcher::class, CacheWatcher::class, RequestWatcher::class, diff --git a/src/Watchers/DeleteQueryWatcher.php b/src/Watchers/DeleteQueryWatcher.php new file mode 100644 index 0000000..d62f502 --- /dev/null +++ b/src/Watchers/DeleteQueryWatcher.php @@ -0,0 +1,26 @@ +enabled = $settings->send_delete_queries_to_ray ?? false; + } +} From abb83b3b2e183ae75a7c23206f4ae2fda703d361 Mon Sep 17 00:00:00 2001 From: Patrick O'Meara Date: Fri, 26 Jul 2024 08:14:22 +1000 Subject: [PATCH 10/23] InsertQueryWatcher --- src/Ray.php | 14 +++++--------- src/RayServiceProvider.php | 2 ++ src/Watchers/InsertQueryWatcher.php | 26 ++++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 9 deletions(-) create mode 100644 src/Watchers/InsertQueryWatcher.php diff --git a/src/Ray.php b/src/Ray.php index 34a9c54..d31305c 100644 --- a/src/Ray.php +++ b/src/Ray.php @@ -32,6 +32,7 @@ use Spatie\LaravelRay\Watchers\EventWatcher; use Spatie\LaravelRay\Watchers\ExceptionWatcher; use Spatie\LaravelRay\Watchers\HttpClientWatcher; +use Spatie\LaravelRay\Watchers\InsertQueryWatcher; use Spatie\LaravelRay\Watchers\JobWatcher; use Spatie\LaravelRay\Watchers\QueryWatcher; use Spatie\LaravelRay\Watchers\RequestWatcher; @@ -478,19 +479,14 @@ public function stopShowingDeleteQueries(): self public function showInsertQueries($callable = null) { - return $this - ->showConditionalQueries( - function (string $query) { - return str_starts_with(strtolower($query), 'insert'); - }, - $callable, - 'send_insert_queries_to_ray', - ); + $watcher = app(InsertQueryWatcher::class); + + return $this->handleWatcherCallable($watcher, $callable); } public function stopShowingInsertQueries(): self { - return $this->stopShowingConditionalQueries('send_insert_queries_to_ray'); + return app(InsertQueryWatcher::class)->disable(); } public function showSelectQueries($callable = null) diff --git a/src/RayServiceProvider.php b/src/RayServiceProvider.php index e9114f4..bcdbce1 100644 --- a/src/RayServiceProvider.php +++ b/src/RayServiceProvider.php @@ -25,6 +25,7 @@ use Spatie\LaravelRay\Watchers\EventWatcher; use Spatie\LaravelRay\Watchers\ExceptionWatcher; use Spatie\LaravelRay\Watchers\HttpClientWatcher; +use Spatie\LaravelRay\Watchers\InsertQueryWatcher; use Spatie\LaravelRay\Watchers\JobWatcher; use Spatie\LaravelRay\Watchers\LoggedMailWatcher; use Spatie\LaravelRay\Watchers\QueryWatcher; @@ -150,6 +151,7 @@ protected function registerWatchers(): self SlowQueryWatcher::class, UpdateQueryWatcher::class, DeleteQueryWatcher::class, + InsertQueryWatcher::class, ViewWatcher::class, CacheWatcher::class, RequestWatcher::class, diff --git a/src/Watchers/InsertQueryWatcher.php b/src/Watchers/InsertQueryWatcher.php new file mode 100644 index 0000000..86e3ca3 --- /dev/null +++ b/src/Watchers/InsertQueryWatcher.php @@ -0,0 +1,26 @@ +enabled = $settings->send_insert_queries_to_ray ?? false; + } +} From b3dfefe199cf7084b40b2be453cc5444972e8319 Mon Sep 17 00:00:00 2001 From: Patrick O'Meara Date: Fri, 26 Jul 2024 08:16:18 +1000 Subject: [PATCH 11/23] SelectQueryWatcher --- src/Ray.php | 14 +++++--------- src/RayServiceProvider.php | 2 ++ src/Watchers/SelectQueryWatcher.php | 26 ++++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 9 deletions(-) create mode 100644 src/Watchers/SelectQueryWatcher.php diff --git a/src/Ray.php b/src/Ray.php index d31305c..010a932 100644 --- a/src/Ray.php +++ b/src/Ray.php @@ -36,6 +36,7 @@ use Spatie\LaravelRay\Watchers\JobWatcher; use Spatie\LaravelRay\Watchers\QueryWatcher; use Spatie\LaravelRay\Watchers\RequestWatcher; +use Spatie\LaravelRay\Watchers\SelectQueryWatcher; use Spatie\LaravelRay\Watchers\SlowQueryWatcher; use Spatie\LaravelRay\Watchers\UpdateQueryWatcher; use Spatie\LaravelRay\Watchers\ViewWatcher; @@ -491,19 +492,14 @@ public function stopShowingInsertQueries(): self public function showSelectQueries($callable = null) { - return $this - ->showConditionalQueries( - function (string $query) { - return str_starts_with(strtolower($query), 'select'); - }, - $callable, - 'send_select_queries_to_ray', - ); + $watcher = app(SelectQueryWatcher::class); + + return $this->handleWatcherCallable($watcher, $callable); } public function stopShowingSelectQueries(): self { - return $this->stopShowingConditionalQueries('send_select_queries_to_ray'); + return app(SelectQueryWatcher::class)->disable(); } /** diff --git a/src/RayServiceProvider.php b/src/RayServiceProvider.php index bcdbce1..1769460 100644 --- a/src/RayServiceProvider.php +++ b/src/RayServiceProvider.php @@ -30,6 +30,7 @@ use Spatie\LaravelRay\Watchers\LoggedMailWatcher; use Spatie\LaravelRay\Watchers\QueryWatcher; use Spatie\LaravelRay\Watchers\RequestWatcher; +use Spatie\LaravelRay\Watchers\SelectQueryWatcher; use Spatie\LaravelRay\Watchers\SlowQueryWatcher; use Spatie\LaravelRay\Watchers\UpdateQueryWatcher; use Spatie\LaravelRay\Watchers\ViewWatcher; @@ -152,6 +153,7 @@ protected function registerWatchers(): self UpdateQueryWatcher::class, DeleteQueryWatcher::class, InsertQueryWatcher::class, + SelectQueryWatcher::class, ViewWatcher::class, CacheWatcher::class, RequestWatcher::class, diff --git a/src/Watchers/SelectQueryWatcher.php b/src/Watchers/SelectQueryWatcher.php new file mode 100644 index 0000000..fe1d08c --- /dev/null +++ b/src/Watchers/SelectQueryWatcher.php @@ -0,0 +1,26 @@ +enabled = $settings->send_select_queries_to_ray ?? false; + } +} From 49fe7a10215d6a0f73adff691b84c369af6615af Mon Sep 17 00:00:00 2001 From: Patrick O'Meara Date: Fri, 26 Jul 2024 09:02:06 +1000 Subject: [PATCH 12/23] Add stop to tests --- src/Ray.php | 12 ++++++++--- tests/Unit/ConditionalQueryTest.php | 32 +++++++++++++---------------- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/src/Ray.php b/src/Ray.php index 010a932..f078fed 100644 --- a/src/Ray.php +++ b/src/Ray.php @@ -475,7 +475,9 @@ public function showDeleteQueries($callable = null) public function stopShowingDeleteQueries(): self { - return app(DeleteQueryWatcher::class)->disable(); + app(DeleteQueryWatcher::class)->disable(); + + return $this; } public function showInsertQueries($callable = null) @@ -487,7 +489,9 @@ public function showInsertQueries($callable = null) public function stopShowingInsertQueries(): self { - return app(InsertQueryWatcher::class)->disable(); + app(InsertQueryWatcher::class)->disable(); + + return $this; } public function showSelectQueries($callable = null) @@ -499,7 +503,9 @@ public function showSelectQueries($callable = null) public function stopShowingSelectQueries(): self { - return app(SelectQueryWatcher::class)->disable(); + app(SelectQueryWatcher::class)->disable(); + + return $this; } /** diff --git a/tests/Unit/ConditionalQueryTest.php b/tests/Unit/ConditionalQueryTest.php index 7526a4e..8c57167 100644 --- a/tests/Unit/ConditionalQueryTest.php +++ b/tests/Unit/ConditionalQueryTest.php @@ -17,23 +17,11 @@ $this->assertSame('joan@example.com', $user->email); }); -it('can stop showing update queries', function () { - $user = User::query()->create(['email' => 'john@example.com']); - - ray()->showUpdateQueries(); - $user->update(['email' => 'joan@example.com']); - ray()->stopShowingUpdateQueries(); - $user->update(['email' => 'joe@example.com']); - - expect($this->client->sentRequests())->toHaveCount(1); -}); - -it('can show only type queries', function (Closure $rayShowMethod, string $sqlCommand) { +it('can show only type queries', function (Closure $rayShowMethod, Closure $rayStopMethod, string $sqlCommand) { $rayShowMethod(); - $user = User::query()->create(['email' => 'john@example.com']); + $user = User::query()->firstOrCreate(['email' => 'john@example.com']); $user->update(['email' => 'joan@example.com']); - $user = User::query()->find($user->id); $user->delete(); expect($this->client->sentPayloads())->toHaveCount(1); @@ -41,9 +29,17 @@ $payload = $this->client->sentPayloads(); $this->assertStringStartsWith($sqlCommand, Arr::get($payload, '0.content.sql')); + + $rayStopMethod(); + + $user = User::query()->firstOrCreate(['email' => 'sam@example.com']); + $user->update(['email' => 'sarah@example.com']); + $user->delete(); + + expect($this->client->sentPayloads())->toHaveCount(1); })->with([ - 'update' => [function () {ray()->showUpdateQueries();}, 'update'], - 'delete' => [function () {ray()->showDeleteQueries();}, 'delete'], - 'insert' => [function () {ray()->showInsertQueries();}, 'insert'], - 'select' => [function () {ray()->showSelectQueries();}, 'select'], + 'update' => [function () {ray()->showUpdateQueries();}, function () {ray()->stopShowingUpdateQueries();}, 'update'], + 'delete' => [function () {ray()->showDeleteQueries();}, function () {ray()->stopShowingDeleteQueries();}, 'delete'], + 'insert' => [function () {ray()->showInsertQueries();}, function () {ray()->stopShowingInsertQueries();}, 'insert'], + 'select' => [function () {ray()->showSelectQueries();}, function () {ray()->stopShowingSelectQueries();}, 'select'], ]); From 252f68c5c439893157e861140540f8575df6f7f6 Mon Sep 17 00:00:00 2001 From: Patrick O'Meara Date: Fri, 26 Jul 2024 10:26:33 +1000 Subject: [PATCH 13/23] test conditional query --- tests/Unit/ConditionalQueryTest.php | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/Unit/ConditionalQueryTest.php b/tests/Unit/ConditionalQueryTest.php index 8c57167..5376899 100644 --- a/tests/Unit/ConditionalQueryTest.php +++ b/tests/Unit/ConditionalQueryTest.php @@ -43,3 +43,24 @@ 'insert' => [function () {ray()->showInsertQueries();}, function () {ray()->stopShowingInsertQueries();}, 'insert'], 'select' => [function () {ray()->showSelectQueries();}, function () {ray()->stopShowingSelectQueries();}, 'select'], ]); + +it('can take a custom condition and only return those queries', function () { + ray()->showConditionalQueries(function (string $query) { + return str_contains($query, 'joan'); + }); + + User::query()->create(['email' => 'joan@example.com']); + User::query()->create(['email' => 'john@example.com']); + + expect($this->client->sentPayloads())->toHaveCount(1); + + $payload = $this->client->sentPayloads(); + + $this->assertStringContainsString('joan@example.com', Arr::get($payload, '0.content.sql')); + + ray()->stopShowingConditionalQueries(); + + User::query()->create(['email' => 'joanne@example.com']); + + expect($this->client->sentPayloads())->toHaveCount(1); +}); From abf3d609194dc50aa3111c422f1f200df3ead3df Mon Sep 17 00:00:00 2001 From: Patrick O'Meara Date: Fri, 26 Jul 2024 10:41:44 +1000 Subject: [PATCH 14/23] Test multiple conditional watchers with nesting and return type --- tests/Unit/ConditionalQueryTest.php | 49 +++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/tests/Unit/ConditionalQueryTest.php b/tests/Unit/ConditionalQueryTest.php index 5376899..c40dd4a 100644 --- a/tests/Unit/ConditionalQueryTest.php +++ b/tests/Unit/ConditionalQueryTest.php @@ -64,3 +64,52 @@ expect($this->client->sentPayloads())->toHaveCount(1); }); + +it('can handle multiple conditional query watchers', function () { + $john = ray()->showConditionalQueries( + function (string $query) { + return str_contains($query, 'joan'); + }, + function(): User { + ray()->showConditionalQueries( + function (string $query) { + return str_contains($query, 'john'); + }, + null, + 'look for john' + ); + + User::query()->create(['email' => 'joan@example.com']); + User::query()->create(['email' => 'joe@example.com']); + + return User::query()->create(['email' => 'john@example.com']); + }, + 'look for joan' + ); + + // Assert that john was handed back + $this->assertSame('john@example.com', $john->email); + + // Assert that ray only received what we wanted + expect($this->client->sentPayloads())->toHaveCount(2); + + $payload = $this->client->sentPayloads(); + + // Assert that ray received the correct order + $this->assertStringContainsString('joan@example.com', Arr::get($payload, '0.content.sql')); + $this->assertStringContainsString('john@example.com', Arr::get($payload, '1.content.sql')); + + // Looking for joan has been disabled so this should not be sent + $joan = User::query()->where('email', 'joan@example.com')->sole(); + expect($this->client->sentPayloads())->toHaveCount(2); + + // Looking for john is still enabled so this should be sent + $john->update(['email' => 'john@adifferentdomain.com']); + expect($this->client->sentPayloads())->toHaveCount(3); + + ray()->stopShowingConditionalQueries('look for john'); + + // Looking for john has been disabled so this should not be sent + $joan->update(['email' => 'iamjohnnow@example.com']); + expect($this->client->sentPayloads())->toHaveCount(3); +}); From 860f8380eb8c27b8eb413ca8c6714207e810e076 Mon Sep 17 00:00:00 2001 From: Patrick O'Meara Date: Fri, 26 Jul 2024 11:34:26 +1000 Subject: [PATCH 15/23] Run register and type watches --- src/RayServiceProvider.php | 8 ++++++-- stub/ray.php | 6 +++--- tests/Unit/ConditionalQueryTest.php | 25 +++++++++++++++++++++++-- 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/RayServiceProvider.php b/src/RayServiceProvider.php index 1769460..5db6d62 100644 --- a/src/RayServiceProvider.php +++ b/src/RayServiceProvider.php @@ -150,10 +150,10 @@ protected function registerWatchers(): self QueryWatcher::class, DuplicateQueryWatcher::class, SlowQueryWatcher::class, - UpdateQueryWatcher::class, - DeleteQueryWatcher::class, InsertQueryWatcher::class, SelectQueryWatcher::class, + UpdateQueryWatcher::class, + DeleteQueryWatcher::class, ViewWatcher::class, CacheWatcher::class, RequestWatcher::class, @@ -181,6 +181,10 @@ protected function bootWatchers(): self QueryWatcher::class, DuplicateQueryWatcher::class, SlowQueryWatcher::class, + InsertQueryWatcher::class, + SelectQueryWatcher::class, + UpdateQueryWatcher::class, + DeleteQueryWatcher::class, ViewWatcher::class, CacheWatcher::class, RequestWatcher::class, diff --git a/stub/ray.php b/stub/ray.php index 5822d18..e45f69a 100644 --- a/stub/ray.php +++ b/stub/ray.php @@ -56,17 +56,17 @@ 'send_update_queries_to_ray' => env('SEND_UPDATE_QUERIES_TO_RAY', false), /* - * When enabled, all update queries will automatically be sent to Ray. + * When enabled, all insert queries will automatically be sent to Ray. */ 'send_insert_queries_to_ray' => env('SEND_INSERT_QUERIES_TO_RAY', false), /* - * When enabled, all update queries will automatically be sent to Ray. + * When enabled, all delete queries will automatically be sent to Ray. */ 'send_delete_queries_to_ray' => env('SEND_DELETE_QUERIES_TO_RAY', false), /* - * When enabled, all update queries will automatically be sent to Ray. + * When enabled, all select queries will automatically be sent to Ray. */ 'send_select_queries_to_ray' => env('SEND_SELECT_QUERIES_TO_RAY', false), diff --git a/tests/Unit/ConditionalQueryTest.php b/tests/Unit/ConditionalQueryTest.php index c40dd4a..b1ea82f 100644 --- a/tests/Unit/ConditionalQueryTest.php +++ b/tests/Unit/ConditionalQueryTest.php @@ -2,6 +2,8 @@ use Illuminate\Support\Arr; use Spatie\LaravelRay\Tests\TestClasses\User; +use Spatie\LaravelRay\Watchers\SelectQueryWatcher; +use Spatie\Ray\Settings\Settings; it('can show only update queries and return the results', function () { $user = ray()->showUpdateQueries(function (): User { @@ -20,18 +22,20 @@ it('can show only type queries', function (Closure $rayShowMethod, Closure $rayStopMethod, string $sqlCommand) { $rayShowMethod(); + // Run all query types $user = User::query()->firstOrCreate(['email' => 'john@example.com']); $user->update(['email' => 'joan@example.com']); $user->delete(); expect($this->client->sentPayloads())->toHaveCount(1); + // Assert the one we want is picked up. $payload = $this->client->sentPayloads(); - $this->assertStringStartsWith($sqlCommand, Arr::get($payload, '0.content.sql')); $rayStopMethod(); + // Assert that watcher has stopped. $user = User::query()->firstOrCreate(['email' => 'sam@example.com']); $user->update(['email' => 'sarah@example.com']); $user->delete(); @@ -55,7 +59,6 @@ expect($this->client->sentPayloads())->toHaveCount(1); $payload = $this->client->sentPayloads(); - $this->assertStringContainsString('joan@example.com', Arr::get($payload, '0.content.sql')); ray()->stopShowingConditionalQueries(); @@ -113,3 +116,21 @@ function (string $query) { $joan->update(['email' => 'iamjohnnow@example.com']); expect($this->client->sentPayloads())->toHaveCount(3); }); + +it('can start watching from config only', function () { + app(Settings::class)->send_select_queries_to_ray = true; + + // Refresh the watcher and register again to pick up settings change + $this->app->singleton(SelectQueryWatcher::class); + app(SelectQueryWatcher::class)->register(); + + // Run all query types + $user = User::query()->firstOrCreate(['email' => 'john@example.com']); + $user->update(['email' => 'joan@example.com']); + $user->delete(); + + expect($this->client->sentPayloads())->toHaveCount(1); + + $payload = $this->client->sentPayloads(); + $this->assertStringStartsWith('select', Arr::get($payload, '0.content.sql')); +}); From 15abf7c788a45ea4a3fcda0404eb3d95c233788f Mon Sep 17 00:00:00 2001 From: Patrick O'Meara Date: Fri, 26 Jul 2024 11:37:51 +1000 Subject: [PATCH 16/23] format --- src/Watchers/DeleteQueryWatcher.php | 4 ---- src/Watchers/InsertQueryWatcher.php | 4 ---- src/Watchers/SelectQueryWatcher.php | 4 ---- src/Watchers/UpdateQueryWatcher.php | 4 ---- tests/Unit/ConditionalQueryTest.php | 2 +- 5 files changed, 1 insertion(+), 17 deletions(-) diff --git a/src/Watchers/DeleteQueryWatcher.php b/src/Watchers/DeleteQueryWatcher.php index d62f502..1c1ed07 100644 --- a/src/Watchers/DeleteQueryWatcher.php +++ b/src/Watchers/DeleteQueryWatcher.php @@ -2,10 +2,6 @@ namespace Spatie\LaravelRay\Watchers; -use Illuminate\Database\Events\QueryExecuted; -use Illuminate\Support\Facades\Event; -use Spatie\LaravelRay\Payloads\ExecutedQueryPayload; -use Spatie\LaravelRay\Ray; use Spatie\Ray\Settings\Settings; class DeleteQueryWatcher extends ConditionalQueryWatcher diff --git a/src/Watchers/InsertQueryWatcher.php b/src/Watchers/InsertQueryWatcher.php index 86e3ca3..bc9ac02 100644 --- a/src/Watchers/InsertQueryWatcher.php +++ b/src/Watchers/InsertQueryWatcher.php @@ -2,10 +2,6 @@ namespace Spatie\LaravelRay\Watchers; -use Illuminate\Database\Events\QueryExecuted; -use Illuminate\Support\Facades\Event; -use Spatie\LaravelRay\Payloads\ExecutedQueryPayload; -use Spatie\LaravelRay\Ray; use Spatie\Ray\Settings\Settings; class InsertQueryWatcher extends ConditionalQueryWatcher diff --git a/src/Watchers/SelectQueryWatcher.php b/src/Watchers/SelectQueryWatcher.php index fe1d08c..42daad7 100644 --- a/src/Watchers/SelectQueryWatcher.php +++ b/src/Watchers/SelectQueryWatcher.php @@ -2,10 +2,6 @@ namespace Spatie\LaravelRay\Watchers; -use Illuminate\Database\Events\QueryExecuted; -use Illuminate\Support\Facades\Event; -use Spatie\LaravelRay\Payloads\ExecutedQueryPayload; -use Spatie\LaravelRay\Ray; use Spatie\Ray\Settings\Settings; class SelectQueryWatcher extends ConditionalQueryWatcher diff --git a/src/Watchers/UpdateQueryWatcher.php b/src/Watchers/UpdateQueryWatcher.php index ecb9688..0115288 100644 --- a/src/Watchers/UpdateQueryWatcher.php +++ b/src/Watchers/UpdateQueryWatcher.php @@ -2,10 +2,6 @@ namespace Spatie\LaravelRay\Watchers; -use Illuminate\Database\Events\QueryExecuted; -use Illuminate\Support\Facades\Event; -use Spatie\LaravelRay\Payloads\ExecutedQueryPayload; -use Spatie\LaravelRay\Ray; use Spatie\Ray\Settings\Settings; class UpdateQueryWatcher extends ConditionalQueryWatcher diff --git a/tests/Unit/ConditionalQueryTest.php b/tests/Unit/ConditionalQueryTest.php index b1ea82f..c52e45c 100644 --- a/tests/Unit/ConditionalQueryTest.php +++ b/tests/Unit/ConditionalQueryTest.php @@ -73,7 +73,7 @@ function (string $query) { return str_contains($query, 'joan'); }, - function(): User { + function (): User { ray()->showConditionalQueries( function (string $query) { return str_contains($query, 'john'); From 26caf6ae89e13bc6f447d1d3bf4075df9f8cc6af Mon Sep 17 00:00:00 2001 From: Patrick O'Meara Date: Fri, 26 Jul 2024 11:56:05 +1000 Subject: [PATCH 17/23] Don't use __construct --- src/Watchers/ConditionalQueryWatcher.php | 2 +- src/Watchers/DeleteQueryWatcher.php | 11 ++++------- src/Watchers/InsertQueryWatcher.php | 11 ++++------- src/Watchers/SelectQueryWatcher.php | 11 ++++------- src/Watchers/UpdateQueryWatcher.php | 11 ++++------- 5 files changed, 17 insertions(+), 29 deletions(-) diff --git a/src/Watchers/ConditionalQueryWatcher.php b/src/Watchers/ConditionalQueryWatcher.php index 25533f7..01746f5 100644 --- a/src/Watchers/ConditionalQueryWatcher.php +++ b/src/Watchers/ConditionalQueryWatcher.php @@ -11,7 +11,7 @@ class ConditionalQueryWatcher extends QueryWatcher { protected $conditionalCallback; - public function __construct($conditionalCallback) + public function setConditionalCallback($conditionalCallback) { $this->conditionalCallback = $conditionalCallback; diff --git a/src/Watchers/DeleteQueryWatcher.php b/src/Watchers/DeleteQueryWatcher.php index 1c1ed07..e6b4472 100644 --- a/src/Watchers/DeleteQueryWatcher.php +++ b/src/Watchers/DeleteQueryWatcher.php @@ -6,17 +6,14 @@ class DeleteQueryWatcher extends ConditionalQueryWatcher { - public function __construct() - { - parent::__construct(function (string $query) { - return str_starts_with(strtolower($query), 'delete'); - }); - } - public function register(): void { $settings = app(Settings::class); $this->enabled = $settings->send_delete_queries_to_ray ?? false; + + $this->setConditionalCallback(function (string $query) { + return str_starts_with(strtolower($query), 'delete'); + }); } } diff --git a/src/Watchers/InsertQueryWatcher.php b/src/Watchers/InsertQueryWatcher.php index bc9ac02..c3bc16e 100644 --- a/src/Watchers/InsertQueryWatcher.php +++ b/src/Watchers/InsertQueryWatcher.php @@ -6,17 +6,14 @@ class InsertQueryWatcher extends ConditionalQueryWatcher { - public function __construct() - { - parent::__construct(function (string $query) { - return str_starts_with(strtolower($query), 'insert'); - }); - } - public function register(): void { $settings = app(Settings::class); $this->enabled = $settings->send_insert_queries_to_ray ?? false; + + $this->setConditionalCallback(function (string $query) { + return str_starts_with(strtolower($query), 'insert'); + }); } } diff --git a/src/Watchers/SelectQueryWatcher.php b/src/Watchers/SelectQueryWatcher.php index 42daad7..81ca5af 100644 --- a/src/Watchers/SelectQueryWatcher.php +++ b/src/Watchers/SelectQueryWatcher.php @@ -6,17 +6,14 @@ class SelectQueryWatcher extends ConditionalQueryWatcher { - public function __construct() - { - parent::__construct(function (string $query) { - return str_starts_with(strtolower($query), 'select'); - }); - } - public function register(): void { $settings = app(Settings::class); $this->enabled = $settings->send_select_queries_to_ray ?? false; + + $this->setConditionalCallback(function (string $query) { + return str_starts_with(strtolower($query), 'select'); + }); } } diff --git a/src/Watchers/UpdateQueryWatcher.php b/src/Watchers/UpdateQueryWatcher.php index 0115288..de64fae 100644 --- a/src/Watchers/UpdateQueryWatcher.php +++ b/src/Watchers/UpdateQueryWatcher.php @@ -6,17 +6,14 @@ class UpdateQueryWatcher extends ConditionalQueryWatcher { - public function __construct() - { - parent::__construct(function (string $query) { - return str_starts_with(strtolower($query), 'update'); - }); - } - public function register(): void { $settings = app(Settings::class); $this->enabled = $settings->send_update_queries_to_ray ?? false; + + $this->setConditionalCallback(function (string $query) { + return str_starts_with(strtolower($query), 'update'); + }); } } From a0dcbec66fdfc05c09fae4dcf2bc204f76d36a3b Mon Sep 17 00:00:00 2001 From: Patrick O'Meara Date: Fri, 26 Jul 2024 11:57:05 +1000 Subject: [PATCH 18/23] Only child and parent classes of ConditionalQueryWatcher can call register Poor mans abstraction --- src/Watchers/ConditionalQueryWatcher.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Watchers/ConditionalQueryWatcher.php b/src/Watchers/ConditionalQueryWatcher.php index 01746f5..18a507d 100644 --- a/src/Watchers/ConditionalQueryWatcher.php +++ b/src/Watchers/ConditionalQueryWatcher.php @@ -2,6 +2,7 @@ namespace Spatie\LaravelRay\Watchers; +use BadMethodCallException; use Illuminate\Database\Events\QueryExecuted; use Illuminate\Support\Facades\Event; use Spatie\LaravelRay\Payloads\ExecutedQueryPayload; @@ -18,6 +19,11 @@ public function setConditionalCallback($conditionalCallback) $this->listen(); } + public function register(): void + { + throw new BadMethodCallException('ConditionalQueryWatcher cannot be registered. Only its child classes.'); + } + public function listen(): void { Event::listen(QueryExecuted::class, function (QueryExecuted $query) { From cf5bfc326f8e3a66174c1923c7bfd7eb5d2b9811 Mon Sep 17 00:00:00 2001 From: Patrick O'Meara Date: Fri, 26 Jul 2024 11:57:46 +1000 Subject: [PATCH 19/23] Let ConditionalQueryWatcher handle binding and naming --- src/Ray.php | 4 ++-- src/Watchers/ConditionalQueryWatcher.php | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/Ray.php b/src/Ray.php index f078fed..b161c69 100644 --- a/src/Ray.php +++ b/src/Ray.php @@ -440,14 +440,14 @@ public function stopShowingDuplicateQueries(): self public function showConditionalQueries(Closure $condition, $callable = null, $name = 'default') { - $watcher = app()->instance(ConditionalQueryWatcher::class.':'.$name, new ConditionalQueryWatcher($condition)); + $watcher = ConditionalQueryWatcher::buildWatcherForName($condition, $name); return $this->handleWatcherCallable($watcher, $callable); } public function stopShowingConditionalQueries($name = 'default'): self { - app(ConditionalQueryWatcher::class.':'.$name)->disable(); + app(ConditionalQueryWatcher::abstractName($name))->disable(); return $this; } diff --git a/src/Watchers/ConditionalQueryWatcher.php b/src/Watchers/ConditionalQueryWatcher.php index 18a507d..5a02198 100644 --- a/src/Watchers/ConditionalQueryWatcher.php +++ b/src/Watchers/ConditionalQueryWatcher.php @@ -3,6 +3,7 @@ namespace Spatie\LaravelRay\Watchers; use BadMethodCallException; +use Closure; use Illuminate\Database\Events\QueryExecuted; use Illuminate\Support\Facades\Event; use Spatie\LaravelRay\Payloads\ExecutedQueryPayload; @@ -12,6 +13,19 @@ class ConditionalQueryWatcher extends QueryWatcher { protected $conditionalCallback; + public static function buildWatcherForName(Closure $condition, $name) + { + $watcher = new static(); + $watcher->setConditionalCallback($condition); + + return app()->instance(static::abstractName($name), $watcher); + } + + public static function abstractName(string $name) + { + return static::class.':'.$name; + } + public function setConditionalCallback($conditionalCallback) { $this->conditionalCallback = $conditionalCallback; From dd4a49b68121a0be14f2f1b04f6f6bc5aefa8c57 Mon Sep 17 00:00:00 2001 From: Patrick O'Meara Date: Fri, 26 Jul 2024 12:25:33 +1000 Subject: [PATCH 20/23] Pass full QueryExecuted object to callback --- src/Watchers/ConditionalQueryWatcher.php | 2 +- src/Watchers/DeleteQueryWatcher.php | 5 +++-- src/Watchers/InsertQueryWatcher.php | 5 +++-- src/Watchers/SelectQueryWatcher.php | 5 +++-- src/Watchers/UpdateQueryWatcher.php | 5 +++-- tests/Unit/ConditionalQueryTest.php | 13 +++++++------ 6 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/Watchers/ConditionalQueryWatcher.php b/src/Watchers/ConditionalQueryWatcher.php index 5a02198..cdc698a 100644 --- a/src/Watchers/ConditionalQueryWatcher.php +++ b/src/Watchers/ConditionalQueryWatcher.php @@ -51,7 +51,7 @@ public function listen(): void $ray = app(Ray::class); - if (($this->conditionalCallback)($query->toRawSql())) { + if (($this->conditionalCallback)($query)) { $payload = new ExecutedQueryPayload($query); $ray->sendRequest($payload); diff --git a/src/Watchers/DeleteQueryWatcher.php b/src/Watchers/DeleteQueryWatcher.php index e6b4472..43192a0 100644 --- a/src/Watchers/DeleteQueryWatcher.php +++ b/src/Watchers/DeleteQueryWatcher.php @@ -2,6 +2,7 @@ namespace Spatie\LaravelRay\Watchers; +use Illuminate\Database\Events\QueryExecuted; use Spatie\Ray\Settings\Settings; class DeleteQueryWatcher extends ConditionalQueryWatcher @@ -12,8 +13,8 @@ public function register(): void $this->enabled = $settings->send_delete_queries_to_ray ?? false; - $this->setConditionalCallback(function (string $query) { - return str_starts_with(strtolower($query), 'delete'); + $this->setConditionalCallback(function (QueryExecuted $query) { + return str_starts_with(strtolower($query->toRawSql()), 'delete'); }); } } diff --git a/src/Watchers/InsertQueryWatcher.php b/src/Watchers/InsertQueryWatcher.php index c3bc16e..cdf6523 100644 --- a/src/Watchers/InsertQueryWatcher.php +++ b/src/Watchers/InsertQueryWatcher.php @@ -2,6 +2,7 @@ namespace Spatie\LaravelRay\Watchers; +use Illuminate\Database\Events\QueryExecuted; use Spatie\Ray\Settings\Settings; class InsertQueryWatcher extends ConditionalQueryWatcher @@ -12,8 +13,8 @@ public function register(): void $this->enabled = $settings->send_insert_queries_to_ray ?? false; - $this->setConditionalCallback(function (string $query) { - return str_starts_with(strtolower($query), 'insert'); + $this->setConditionalCallback(function (QueryExecuted $query) { + return str_starts_with(strtolower($query->toRawSql()), 'insert'); }); } } diff --git a/src/Watchers/SelectQueryWatcher.php b/src/Watchers/SelectQueryWatcher.php index 81ca5af..fb2dbe8 100644 --- a/src/Watchers/SelectQueryWatcher.php +++ b/src/Watchers/SelectQueryWatcher.php @@ -2,6 +2,7 @@ namespace Spatie\LaravelRay\Watchers; +use Illuminate\Database\Events\QueryExecuted; use Spatie\Ray\Settings\Settings; class SelectQueryWatcher extends ConditionalQueryWatcher @@ -12,8 +13,8 @@ public function register(): void $this->enabled = $settings->send_select_queries_to_ray ?? false; - $this->setConditionalCallback(function (string $query) { - return str_starts_with(strtolower($query), 'select'); + $this->setConditionalCallback(function (QueryExecuted $query) { + return str_starts_with(strtolower($query->toRawSql()), 'select'); }); } } diff --git a/src/Watchers/UpdateQueryWatcher.php b/src/Watchers/UpdateQueryWatcher.php index de64fae..c3efaa0 100644 --- a/src/Watchers/UpdateQueryWatcher.php +++ b/src/Watchers/UpdateQueryWatcher.php @@ -2,6 +2,7 @@ namespace Spatie\LaravelRay\Watchers; +use Illuminate\Database\Events\QueryExecuted; use Spatie\Ray\Settings\Settings; class UpdateQueryWatcher extends ConditionalQueryWatcher @@ -12,8 +13,8 @@ public function register(): void $this->enabled = $settings->send_update_queries_to_ray ?? false; - $this->setConditionalCallback(function (string $query) { - return str_starts_with(strtolower($query), 'update'); + $this->setConditionalCallback(function (QueryExecuted $query) { + return str_starts_with(strtolower($query->toRawSql()), 'update'); }); } } diff --git a/tests/Unit/ConditionalQueryTest.php b/tests/Unit/ConditionalQueryTest.php index c52e45c..813dd85 100644 --- a/tests/Unit/ConditionalQueryTest.php +++ b/tests/Unit/ConditionalQueryTest.php @@ -1,5 +1,6 @@ showConditionalQueries(function (string $query) { - return str_contains($query, 'joan'); + ray()->showConditionalQueries(function (QueryExecuted $query) { + return str_contains($query->toRawSql(), 'joan'); }); User::query()->create(['email' => 'joan@example.com']); @@ -70,13 +71,13 @@ it('can handle multiple conditional query watchers', function () { $john = ray()->showConditionalQueries( - function (string $query) { - return str_contains($query, 'joan'); + function (QueryExecuted $query) { + return str_contains($query->toRawSql(), 'joan'); }, function (): User { ray()->showConditionalQueries( - function (string $query) { - return str_contains($query, 'john'); + function (QueryExecuted $query) { + return str_contains($query->toRawSql(), 'john'); }, null, 'look for john' From ac4647ee9e9071a31d5583d38e741f9b7b57d9fe Mon Sep 17 00:00:00 2001 From: Patrick O'Meara Date: Fri, 26 Jul 2024 12:26:41 +1000 Subject: [PATCH 21/23] Use ConditionalQueryWatcher to clean up SlowQueryWatcher --- src/Watchers/SlowQueryWatcher.php | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/src/Watchers/SlowQueryWatcher.php b/src/Watchers/SlowQueryWatcher.php index ce0f880..a5727d6 100644 --- a/src/Watchers/SlowQueryWatcher.php +++ b/src/Watchers/SlowQueryWatcher.php @@ -3,12 +3,9 @@ namespace Spatie\LaravelRay\Watchers; use Illuminate\Database\Events\QueryExecuted; -use Illuminate\Support\Facades\Event; -use Spatie\LaravelRay\Payloads\ExecutedQueryPayload; -use Spatie\LaravelRay\Ray; use Spatie\Ray\Settings\Settings; -class SlowQueryWatcher extends QueryWatcher +class SlowQueryWatcher extends ConditionalQueryWatcher { protected $minimumTimeInMs = 500; @@ -19,20 +16,8 @@ public function register(): void $this->enabled = $settings->send_slow_queries_to_ray ?? false; $this->minimumTimeInMs = $settings->slow_query_threshold_in_ms ?? $this->minimumTimeInMs; - Event::listen(QueryExecuted::class, function (QueryExecuted $query) { - if (! $this->enabled()) { - return; - } - - $ray = app(Ray::class); - - if ($query->time >= $this->minimumTimeInMs) { - $payload = new ExecutedQueryPayload($query); - - $ray->sendRequest($payload); - } - - optional($this->rayProxy)->applyCalledMethods($ray); + $this->setConditionalCallback(function (QueryExecuted $query) { + return $query->time >= $this->minimumTimeInMs; }); } From 114c2bab655763d36a0e3d3fa7d4373250388050 Mon Sep 17 00:00:00 2001 From: Patrick O'Meara Date: Fri, 26 Jul 2024 13:46:42 +1000 Subject: [PATCH 22/23] Use Str to support PHP 7.4 --- src/Watchers/DeleteQueryWatcher.php | 3 ++- src/Watchers/InsertQueryWatcher.php | 3 ++- src/Watchers/SelectQueryWatcher.php | 3 ++- src/Watchers/UpdateQueryWatcher.php | 3 ++- tests/Unit/ConditionalQueryTest.php | 7 ++++--- 5 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/Watchers/DeleteQueryWatcher.php b/src/Watchers/DeleteQueryWatcher.php index 43192a0..766c3ac 100644 --- a/src/Watchers/DeleteQueryWatcher.php +++ b/src/Watchers/DeleteQueryWatcher.php @@ -3,6 +3,7 @@ namespace Spatie\LaravelRay\Watchers; use Illuminate\Database\Events\QueryExecuted; +use Illuminate\Support\Str; use Spatie\Ray\Settings\Settings; class DeleteQueryWatcher extends ConditionalQueryWatcher @@ -14,7 +15,7 @@ public function register(): void $this->enabled = $settings->send_delete_queries_to_ray ?? false; $this->setConditionalCallback(function (QueryExecuted $query) { - return str_starts_with(strtolower($query->toRawSql()), 'delete'); + return Str::startsWith(strtolower($query->toRawSql()), 'delete'); }); } } diff --git a/src/Watchers/InsertQueryWatcher.php b/src/Watchers/InsertQueryWatcher.php index cdf6523..acc0419 100644 --- a/src/Watchers/InsertQueryWatcher.php +++ b/src/Watchers/InsertQueryWatcher.php @@ -3,6 +3,7 @@ namespace Spatie\LaravelRay\Watchers; use Illuminate\Database\Events\QueryExecuted; +use Illuminate\Support\Str; use Spatie\Ray\Settings\Settings; class InsertQueryWatcher extends ConditionalQueryWatcher @@ -14,7 +15,7 @@ public function register(): void $this->enabled = $settings->send_insert_queries_to_ray ?? false; $this->setConditionalCallback(function (QueryExecuted $query) { - return str_starts_with(strtolower($query->toRawSql()), 'insert'); + return Str::startsWith(strtolower($query->toRawSql()), 'insert'); }); } } diff --git a/src/Watchers/SelectQueryWatcher.php b/src/Watchers/SelectQueryWatcher.php index fb2dbe8..a403dbb 100644 --- a/src/Watchers/SelectQueryWatcher.php +++ b/src/Watchers/SelectQueryWatcher.php @@ -3,6 +3,7 @@ namespace Spatie\LaravelRay\Watchers; use Illuminate\Database\Events\QueryExecuted; +use Illuminate\Support\Str; use Spatie\Ray\Settings\Settings; class SelectQueryWatcher extends ConditionalQueryWatcher @@ -14,7 +15,7 @@ public function register(): void $this->enabled = $settings->send_select_queries_to_ray ?? false; $this->setConditionalCallback(function (QueryExecuted $query) { - return str_starts_with(strtolower($query->toRawSql()), 'select'); + return Str::startsWith(strtolower($query->toRawSql()), 'select'); }); } } diff --git a/src/Watchers/UpdateQueryWatcher.php b/src/Watchers/UpdateQueryWatcher.php index c3efaa0..10d0398 100644 --- a/src/Watchers/UpdateQueryWatcher.php +++ b/src/Watchers/UpdateQueryWatcher.php @@ -3,6 +3,7 @@ namespace Spatie\LaravelRay\Watchers; use Illuminate\Database\Events\QueryExecuted; +use Illuminate\Support\Str; use Spatie\Ray\Settings\Settings; class UpdateQueryWatcher extends ConditionalQueryWatcher @@ -14,7 +15,7 @@ public function register(): void $this->enabled = $settings->send_update_queries_to_ray ?? false; $this->setConditionalCallback(function (QueryExecuted $query) { - return str_starts_with(strtolower($query->toRawSql()), 'update'); + return Str::startsWith(strtolower($query->toRawSql()), 'update'); }); } } diff --git a/tests/Unit/ConditionalQueryTest.php b/tests/Unit/ConditionalQueryTest.php index 813dd85..58c362d 100644 --- a/tests/Unit/ConditionalQueryTest.php +++ b/tests/Unit/ConditionalQueryTest.php @@ -2,6 +2,7 @@ use Illuminate\Database\Events\QueryExecuted; use Illuminate\Support\Arr; +use Illuminate\Support\Str; use Spatie\LaravelRay\Tests\TestClasses\User; use Spatie\LaravelRay\Watchers\SelectQueryWatcher; use Spatie\Ray\Settings\Settings; @@ -51,7 +52,7 @@ it('can take a custom condition and only return those queries', function () { ray()->showConditionalQueries(function (QueryExecuted $query) { - return str_contains($query->toRawSql(), 'joan'); + return Str::contains($query->toRawSql(), 'joan'); }); User::query()->create(['email' => 'joan@example.com']); @@ -72,12 +73,12 @@ it('can handle multiple conditional query watchers', function () { $john = ray()->showConditionalQueries( function (QueryExecuted $query) { - return str_contains($query->toRawSql(), 'joan'); + return Str::contains($query->toRawSql(), 'joan'); }, function (): User { ray()->showConditionalQueries( function (QueryExecuted $query) { - return str_contains($query->toRawSql(), 'john'); + return Str::contains($query->toRawSql(), 'john'); }, null, 'look for john' From 8570d284b6e45bc7a79d7ad8b39d643694db7722 Mon Sep 17 00:00:00 2001 From: Patrick O'Meara Date: Fri, 26 Jul 2024 15:28:17 +1000 Subject: [PATCH 23/23] Support Laravel 7 --- src/Watchers/DeleteQueryWatcher.php | 2 +- src/Watchers/InsertQueryWatcher.php | 2 +- src/Watchers/SelectQueryWatcher.php | 2 +- src/Watchers/UpdateQueryWatcher.php | 2 +- tests/TestCase.php | 13 ++++++++++++ tests/Unit/ConditionalQueryTest.php | 32 ++++++++++++++--------------- 6 files changed, 33 insertions(+), 20 deletions(-) diff --git a/src/Watchers/DeleteQueryWatcher.php b/src/Watchers/DeleteQueryWatcher.php index 766c3ac..000cbdb 100644 --- a/src/Watchers/DeleteQueryWatcher.php +++ b/src/Watchers/DeleteQueryWatcher.php @@ -15,7 +15,7 @@ public function register(): void $this->enabled = $settings->send_delete_queries_to_ray ?? false; $this->setConditionalCallback(function (QueryExecuted $query) { - return Str::startsWith(strtolower($query->toRawSql()), 'delete'); + return Str::startsWith(strtolower($query->sql), 'delete'); }); } } diff --git a/src/Watchers/InsertQueryWatcher.php b/src/Watchers/InsertQueryWatcher.php index acc0419..ac581d1 100644 --- a/src/Watchers/InsertQueryWatcher.php +++ b/src/Watchers/InsertQueryWatcher.php @@ -15,7 +15,7 @@ public function register(): void $this->enabled = $settings->send_insert_queries_to_ray ?? false; $this->setConditionalCallback(function (QueryExecuted $query) { - return Str::startsWith(strtolower($query->toRawSql()), 'insert'); + return Str::startsWith(strtolower($query->sql), 'insert'); }); } } diff --git a/src/Watchers/SelectQueryWatcher.php b/src/Watchers/SelectQueryWatcher.php index a403dbb..2794c45 100644 --- a/src/Watchers/SelectQueryWatcher.php +++ b/src/Watchers/SelectQueryWatcher.php @@ -15,7 +15,7 @@ public function register(): void $this->enabled = $settings->send_select_queries_to_ray ?? false; $this->setConditionalCallback(function (QueryExecuted $query) { - return Str::startsWith(strtolower($query->toRawSql()), 'select'); + return Str::startsWith(strtolower($query->sql), 'select'); }); } } diff --git a/src/Watchers/UpdateQueryWatcher.php b/src/Watchers/UpdateQueryWatcher.php index 10d0398..f884434 100644 --- a/src/Watchers/UpdateQueryWatcher.php +++ b/src/Watchers/UpdateQueryWatcher.php @@ -15,7 +15,7 @@ public function register(): void $this->enabled = $settings->send_update_queries_to_ray ?? false; $this->setConditionalCallback(function (QueryExecuted $query) { - return Str::startsWith(strtolower($query->toRawSql()), 'update'); + return Str::startsWith(strtolower($query->sql), 'update'); }); } } diff --git a/tests/TestCase.php b/tests/TestCase.php index 34eafd9..d4f258a 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -2,9 +2,13 @@ namespace Spatie\LaravelRay\Tests; +use Illuminate\Database\Events\QueryExecuted; +use Illuminate\Database\Query\Builder; use Illuminate\Database\Schema\Blueprint; +use Illuminate\Support\Arr; use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\View; +use Illuminate\Support\Str; use Orchestra\Testbench\TestCase as Orchestra; use Spatie\LaravelRay\Ray; use Spatie\LaravelRay\RayServiceProvider; @@ -70,4 +74,13 @@ protected function useRealUuid() return Ray::create($this->client); }); } + + protected function assertSqlContains($queryContent, $needle): void + { + $sql = method_exists(Builder::class, 'toRawSql') + ? $queryContent['sql'] + : Str::replaceArray('?', $queryContent['bindings'], $queryContent['sql']); + + $this->assertStringContainsString($needle, $sql); + } } diff --git a/tests/Unit/ConditionalQueryTest.php b/tests/Unit/ConditionalQueryTest.php index 58c362d..06f6a8b 100644 --- a/tests/Unit/ConditionalQueryTest.php +++ b/tests/Unit/ConditionalQueryTest.php @@ -21,8 +21,8 @@ $this->assertSame('joan@example.com', $user->email); }); -it('can show only type queries', function (Closure $rayShowMethod, Closure $rayStopMethod, string $sqlCommand) { - $rayShowMethod(); +it('can show only type queries', function (string $rayShowMethod, string $rayStopMethod, string $sqlCommand) { + ray()->$rayShowMethod(); // Run all query types $user = User::query()->firstOrCreate(['email' => 'john@example.com']); @@ -33,9 +33,9 @@ // Assert the one we want is picked up. $payload = $this->client->sentPayloads(); - $this->assertStringStartsWith($sqlCommand, Arr::get($payload, '0.content.sql')); + $this->assertSqlContains(Arr::get($payload, '0.content'), $sqlCommand); - $rayStopMethod(); + ray()->$rayStopMethod(); // Assert that watcher has stopped. $user = User::query()->firstOrCreate(['email' => 'sam@example.com']); @@ -44,15 +44,15 @@ expect($this->client->sentPayloads())->toHaveCount(1); })->with([ - 'update' => [function () {ray()->showUpdateQueries();}, function () {ray()->stopShowingUpdateQueries();}, 'update'], - 'delete' => [function () {ray()->showDeleteQueries();}, function () {ray()->stopShowingDeleteQueries();}, 'delete'], - 'insert' => [function () {ray()->showInsertQueries();}, function () {ray()->stopShowingInsertQueries();}, 'insert'], - 'select' => [function () {ray()->showSelectQueries();}, function () {ray()->stopShowingSelectQueries();}, 'select'], + 'update' => ['showUpdateQueries', 'stopShowingUpdateQueries', 'update'], + 'delete' => ['showDeleteQueries', 'stopShowingDeleteQueries', 'delete'], + 'insert' => ['showInsertQueries', 'stopShowingInsertQueries', 'insert'], + 'select' => ['showSelectQueries', 'stopShowingSelectQueries', 'select'], ]); it('can take a custom condition and only return those queries', function () { ray()->showConditionalQueries(function (QueryExecuted $query) { - return Str::contains($query->toRawSql(), 'joan'); + return Arr::first($query->bindings, fn ($binding) => Str::contains($binding, 'joan')); }); User::query()->create(['email' => 'joan@example.com']); @@ -61,7 +61,7 @@ expect($this->client->sentPayloads())->toHaveCount(1); $payload = $this->client->sentPayloads(); - $this->assertStringContainsString('joan@example.com', Arr::get($payload, '0.content.sql')); + $this->assertSqlContains(Arr::get($payload, '0.content'), 'joan@example.com'); ray()->stopShowingConditionalQueries(); @@ -73,12 +73,12 @@ it('can handle multiple conditional query watchers', function () { $john = ray()->showConditionalQueries( function (QueryExecuted $query) { - return Str::contains($query->toRawSql(), 'joan'); + return Arr::first($query->bindings, fn ($binding) => Str::contains($binding, 'joan')); }, function (): User { ray()->showConditionalQueries( function (QueryExecuted $query) { - return Str::contains($query->toRawSql(), 'john'); + return Arr::first($query->bindings, fn ($binding) => Str::contains($binding, 'john')); }, null, 'look for john' @@ -101,11 +101,11 @@ function (QueryExecuted $query) { $payload = $this->client->sentPayloads(); // Assert that ray received the correct order - $this->assertStringContainsString('joan@example.com', Arr::get($payload, '0.content.sql')); - $this->assertStringContainsString('john@example.com', Arr::get($payload, '1.content.sql')); + $this->assertSqlContains(Arr::get($payload, '0.content'), 'joan@example.com'); + $this->assertSqlContains(Arr::get($payload, '1.content'), 'john@example.com'); // Looking for joan has been disabled so this should not be sent - $joan = User::query()->where('email', 'joan@example.com')->sole(); + $joan = User::query()->where('email', 'joan@example.com')->first(); expect($this->client->sentPayloads())->toHaveCount(2); // Looking for john is still enabled so this should be sent @@ -134,5 +134,5 @@ function (QueryExecuted $query) { expect($this->client->sentPayloads())->toHaveCount(1); $payload = $this->client->sentPayloads(); - $this->assertStringStartsWith('select', Arr::get($payload, '0.content.sql')); + $this->assertSqlContains(Arr::get($payload, '0.content'), 'select'); });