Skip to content

Commit

Permalink
[10.x] Fix Postgres cache store failed to put in db transaction
Browse files Browse the repository at this point in the history
  • Loading branch information
yuzhuang committed Nov 10, 2023
1 parent 2703f3e commit fa22473
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/Illuminate/Cache/DatabaseStore.php
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@ public function put($key, $value, $seconds)
$value = $this->serialize($value);
$expiration = $this->getTime() + $seconds;

if ($this->connection instanceof PostgresConnection && $this->connection->transactionLevel() > 0) {
return $this->table()->upsert(compact('key', 'value', 'expiration'), 'key') > 0;
}

try {
return $this->table()->insert(compact('key', 'value', 'expiration'));
} catch (Exception) {
Expand Down
14 changes: 14 additions & 0 deletions tests/Cache/CacheDatabaseStoreTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,24 @@ public function testValueIsUpdatedWhenInsertThrowsException()
$this->assertTrue($result);
}

public function testValueIsUpsertDuringTransactionOnPostgres()
{
$store = $this->getMockBuilder(DatabaseStore::class)->onlyMethods(['getTime'])->setConstructorArgs($this->getPostgresMocks())->getMock();
$table = m::mock(stdClass::class);
$store->getConnection()->shouldReceive('transactionLevel')->once()->andReturn(1);
$store->getConnection()->shouldReceive('table')->once()->with('table')->andReturn($table);
$store->expects($this->once())->method('getTime')->willReturn(1);
$table->shouldReceive('upsert')->once()->with(['key' => 'prefixfoo', 'value' => base64_encode(serialize("\0")), 'expiration' => 61], 'key')->andReturnTrue();

$result = $store->put('foo', "\0", 60);
$this->assertTrue($result);
}

public function testValueIsInsertedOnPostgres()
{
$store = $this->getMockBuilder(DatabaseStore::class)->onlyMethods(['getTime'])->setConstructorArgs($this->getPostgresMocks())->getMock();
$table = m::mock(stdClass::class);
$store->getConnection()->shouldReceive('transactionLevel')->once()->andReturn(0);
$store->getConnection()->shouldReceive('table')->once()->with('table')->andReturn($table);
$store->expects($this->once())->method('getTime')->willReturn(1);
$table->shouldReceive('insert')->once()->with(['key' => 'prefixfoo', 'value' => base64_encode(serialize("\0")), 'expiration' => 61])->andReturnTrue();
Expand Down

0 comments on commit fa22473

Please sign in to comment.