From f2d229e83100c72fc54ba87a12ec7ac2d9cdf58e Mon Sep 17 00:00:00 2001 From: Maxim Smakouz Date: Thu, 28 Mar 2024 12:25:36 +0200 Subject: [PATCH 1/5] Fix caching for insert queries with fragments --- src/Driver/CompilerCache.php | 3 +- .../Driver/Common/Query/InsertQueryTest.php | 54 +++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/src/Driver/CompilerCache.php b/src/Driver/CompilerCache.php index 7ca1ecf9..b40cbd72 100644 --- a/src/Driver/CompilerCache.php +++ b/src/Driver/CompilerCache.php @@ -121,7 +121,8 @@ protected function hashInsertQuery(QueryParameters $params, array $tokens): stri if ($value->isArray()) { foreach ($value->getValue() as $child) { - if ($child instanceof FragmentInterface) { + if ($child instanceof FragmentInterface && $child instanceof \Stringable) { + $hash .= '_F_'. $child; continue; } diff --git a/tests/Database/Functional/Driver/Common/Query/InsertQueryTest.php b/tests/Database/Functional/Driver/Common/Query/InsertQueryTest.php index 3fc36f7b..cd3cd0ed 100644 --- a/tests/Database/Functional/Driver/Common/Query/InsertQueryTest.php +++ b/tests/Database/Functional/Driver/Common/Query/InsertQueryTest.php @@ -4,6 +4,8 @@ namespace Cycle\Database\Tests\Functional\Driver\Common\Query; +use Cycle\Database\Injection\Expression; +use Cycle\Database\Injection\Fragment; use Cycle\Database\Query\InsertQuery; use Cycle\Database\Tests\Functional\Driver\Common\BaseTest; @@ -99,4 +101,56 @@ public function testInsertMultipleRowsAsArray(): void $insert ); } + + public function testInsertWithExpressions(): void + { + $insert = $this->database->insert()->into('table')->values([ + 'name' => 'Anton', + 'updated_at' => new Expression('NOW()'), + 'deleted_at' => new Expression('NOW()'), + ]); + + $this->assertSameQuery( + 'INSERT INTO {table} ({name}, {updated_at}, {deleted_at}) VALUES (?, NOW(), NOW())', + $insert + ); + $this->assertSameParameters(['Anton'], $insert); + + $insert = $this->database->insert()->into('table')->values([ + 'name' => 'Anton', + 'updated_at' => new Expression('NOW()'), + 'deleted_at' => null, + ]); + + $this->assertSameQuery( + 'INSERT INTO {table} ({name}, {updated_at}, {deleted_at}) VALUES (?, NOW(), ?)', + $insert, + ); + $this->assertSameParameters(['Anton', null], $insert); + } + + public function testInsertWithFragmentsThatHaveDifferentStatements(): void + { + $insert = $this->database->insert()->into('table')->values([ + 'name' => 'Anton', + 'updated_at' => new Fragment('NOW()'), + 'deleted_at' => new Fragment('NOW()'), + ]); + + $this->assertSameQuery( + 'INSERT INTO {table} ({name}, {updated_at}, {deleted_at}) VALUES (?, NOW(), NOW())', + $insert + ); + + $insert = $this->database->insert()->into('table')->values([ + 'name' => 'Anton', + 'updated_at' => new Fragment('NOW()'), + 'deleted_at' => new Fragment('datetime(\'now\')'), + ]); + + $this->assertSameQuery( + 'INSERT INTO {table} ({name}, {updated_at}, {deleted_at}) VALUES (?, NOW(), datetime(\'now\'))', + $insert, + ); + } } From be7bd09c654e67e752f50f005cee2eaae713947a Mon Sep 17 00:00:00 2001 From: StyleCI Bot Date: Thu, 28 Mar 2024 10:27:21 +0000 Subject: [PATCH 2/5] Apply fixes from StyleCI --- src/Driver/CompilerCache.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Driver/CompilerCache.php b/src/Driver/CompilerCache.php index b40cbd72..f3953a48 100644 --- a/src/Driver/CompilerCache.php +++ b/src/Driver/CompilerCache.php @@ -122,7 +122,7 @@ protected function hashInsertQuery(QueryParameters $params, array $tokens): stri if ($value->isArray()) { foreach ($value->getValue() as $child) { if ($child instanceof FragmentInterface && $child instanceof \Stringable) { - $hash .= '_F_'. $child; + $hash .= '_F_' . $child; continue; } From 3564e946cce53256e8a20dca6be4670a52e58468 Mon Sep 17 00:00:00 2001 From: Maxim Smakouz Date: Thu, 28 Mar 2024 13:20:08 +0200 Subject: [PATCH 3/5] Fix stringable checking --- src/Driver/CompilerCache.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Driver/CompilerCache.php b/src/Driver/CompilerCache.php index f3953a48..ab9603a5 100644 --- a/src/Driver/CompilerCache.php +++ b/src/Driver/CompilerCache.php @@ -121,8 +121,10 @@ protected function hashInsertQuery(QueryParameters $params, array $tokens): stri if ($value->isArray()) { foreach ($value->getValue() as $child) { - if ($child instanceof FragmentInterface && $child instanceof \Stringable) { - $hash .= '_F_' . $child; + if ($child instanceof FragmentInterface) { + if ($child instanceof \Stringable) { + $hash .= '_F_'. $child; + } continue; } From 6d3cb7135dbb40b39190aff1a03ec8edfd51c7fb Mon Sep 17 00:00:00 2001 From: StyleCI Bot Date: Thu, 28 Mar 2024 11:20:23 +0000 Subject: [PATCH 4/5] Apply fixes from StyleCI --- src/Driver/CompilerCache.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Driver/CompilerCache.php b/src/Driver/CompilerCache.php index ab9603a5..8c8d8cf7 100644 --- a/src/Driver/CompilerCache.php +++ b/src/Driver/CompilerCache.php @@ -123,7 +123,7 @@ protected function hashInsertQuery(QueryParameters $params, array $tokens): stri foreach ($value->getValue() as $child) { if ($child instanceof FragmentInterface) { if ($child instanceof \Stringable) { - $hash .= '_F_'. $child; + $hash .= '_F_' . $child; } continue; } From 3c50583cbab8da56d28585d947965f118114ecf3 Mon Sep 17 00:00:00 2001 From: Maxim Smakouz Date: Thu, 28 Mar 2024 13:50:02 +0200 Subject: [PATCH 5/5] Add test with custom fragment --- .../Driver/Common/Query/InsertQueryTest.php | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/tests/Database/Functional/Driver/Common/Query/InsertQueryTest.php b/tests/Database/Functional/Driver/Common/Query/InsertQueryTest.php index cd3cd0ed..e4085ab8 100644 --- a/tests/Database/Functional/Driver/Common/Query/InsertQueryTest.php +++ b/tests/Database/Functional/Driver/Common/Query/InsertQueryTest.php @@ -4,8 +4,10 @@ namespace Cycle\Database\Tests\Functional\Driver\Common\Query; +use Cycle\Database\Driver\CompilerInterface; use Cycle\Database\Injection\Expression; use Cycle\Database\Injection\Fragment; +use Cycle\Database\Injection\FragmentInterface; use Cycle\Database\Query\InsertQuery; use Cycle\Database\Tests\Functional\Driver\Common\BaseTest; @@ -153,4 +155,37 @@ public function testInsertWithFragmentsThatHaveDifferentStatements(): void $insert, ); } + + public function testInsertWithCustomFragment(): void + { + $fragment = $this->createMock(FragmentInterface::class); + $fragment->method('getType')->willReturn(CompilerInterface::FRAGMENT); + $fragment->method('getTokens')->willReturn([ + 'fragment' => 'NOW()', + 'parameters' => [], + ]); + + $insert = $this->database->insert()->into('table')->values([ + 'name' => 'Anton', + 'updated_at' => $fragment, + ]); + + $this->assertSameQuery( + 'INSERT INTO {table} ({name}, {updated_at}) VALUES (?, NOW())', + $insert + ); + $this->assertSameParameters(['Anton'], $insert); + + // cached query + $insert = $this->database->insert()->into('table')->values([ + 'name' => 'Anton', + 'updated_at' => $fragment, + ]); + + $this->assertSameQuery( + 'INSERT INTO {table} ({name}, {updated_at}) VALUES (?, NOW())', + $insert + ); + $this->assertSameParameters(['Anton'], $insert); + } }