Skip to content

Commit

Permalink
Fix caching for insert queries with fragments (#177)
Browse files Browse the repository at this point in the history
  • Loading branch information
msmakouz authored Mar 28, 2024
1 parent 9eb6669 commit ab00319
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/Driver/CompilerCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ protected function hashInsertQuery(QueryParameters $params, array $tokens): stri
if ($value->isArray()) {
foreach ($value->getValue() as $child) {
if ($child instanceof FragmentInterface) {
if ($child instanceof \Stringable) {
$hash .= '_F_' . $child;
}
continue;
}

Expand Down
89 changes: 89 additions & 0 deletions tests/Database/Functional/Driver/Common/Query/InsertQueryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +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;

Expand Down Expand Up @@ -99,4 +103,89 @@ 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,
);
}

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);
}
}

0 comments on commit ab00319

Please sign in to comment.