Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .roave-backward-compatibility-check.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
<baseline>
<ignored-regex>#\[BC\] SKIPPED: Roave\\BetterReflection\\Reflection\\ReflectionClass "Yiisoft\\Yii\\Debug\\#</ignored-regex>
<ignored-regex>#\[BC\] SKIPPED: An enum expression Yiisoft\\Db\\QueryBuilder\\Condition\\Like#</ignored-regex>
<ignored-regex>#\[BC\] SKIPPED: Unable to compile initializer in class Yiisoft\\Db\\Driver\\Pdo\\AbstractPdoConnection#</ignored-regex>
</baseline>
</roave-bc-check>
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
- New #1152: Add `UuidValue` expression that represents a UUID value independently of DBMS (@KalimeroMK)
- Enh #1152: Improve the exception message of `DbUuidHelper::toUuid()` when the value isn't a valid UUID
(@KalimeroMK)
- Enh #1201: Make `$psrCache` parameter of `SchemaCache` constructor and `$schemaCache` parameter of
`AbstractSchema` and `AbstractPdoConnection` constructors optional, remove `psr/simple-cache-implementation` from
`require` in `composer.json` (@vjik)

## 2.0.1 February 09, 2026

Expand Down
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,12 @@ To install `yiisoft/db` you must install at least one database driver:
- [`yiisoft/db-mssql`](https://github.com/yiisoft/db-mssql);
- [`yiisoft/db-oracle`](https://github.com/yiisoft/db-oracle).

> [!IMPORTANT]
> It also depends on [PSR-16: Common Interface for Caching Libraries](https://www.php-fig.org/psr/psr-16/) and requires
> the installation of [PSR-16 implementation](https://packagist.org/providers/psr/simple-cache-implementation).
> [!TIP]
> To cache database schema information, install
> [PSR-16 implementation](https://packagist.org/providers/psr/simple-cache-implementation).
> For example, [yiisoft/cache](https://github.com/yiisoft/cache) or one of the other
> [cache handlers](https://github.com/yiisoft/cache#cache-handlers).
> It's strongly recommended for production.

## General Usage

Expand Down
2 changes: 1 addition & 1 deletion composer-dependency-analyser.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
->ignoreErrorsOnPackages(['yiisoft/yii-debug'], [ErrorType::DEV_DEPENDENCY_IN_PROD])
// Virtual packages that are not directly used in the code.
->ignoreErrorsOnPackages(
['psr/simple-cache-implementation', 'yiisoft/db-implementation'],
['yiisoft/db-implementation'],
[ErrorType::UNUSED_DEPENDENCY],
);

Expand Down
3 changes: 1 addition & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,14 @@
"ext-pdo": "*",
"psr/log": "^2.0|^3.0",
"psr/simple-cache": "^2.0|^3.0",
"psr/simple-cache-implementation": "*",
"yiisoft/db-implementation": "1.0.0"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.8.3",
"ext-mbstring": "*",
"friendsofphp/php-cs-fixer": "^3.89.1",
"phpunit/phpunit": "^10.5.45",
"rector/rector": "^2.0.10",
"rector/rector": "^2.6.7",
"shipmonk/composer-dependency-analyser": "^1.8",
"spatie/phpunit-watcher": "^1.24",
"yiisoft/aliases": "^3.0",
Expand Down
7 changes: 4 additions & 3 deletions docs/guide/en/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,11 @@ For [SQLite](https://github.com/yiisoft/db-sqlite):
composer require yiisoft/db-sqlite
```

> [!IMPORTANT]
> It also depends on [PSR-16: Common Interface for Caching Libraries](https://www.php-fig.org/psr/psr-16/) and requires
> the installation of [PSR-16 implementation](https://packagist.org/providers/psr/simple-cache-implementation).
> [!TIP]
> To cache database schema information, install
> [PSR-16 implementation](https://packagist.org/providers/psr/simple-cache-implementation).
> For example, [yiisoft/cache](https://github.com/yiisoft/cache) or one of the other [cache handlers](https://github.com/yiisoft/cache#cache-handlers).
> It's strongly recommended for production.

## Configure schema cache

Expand Down
8 changes: 7 additions & 1 deletion docs/guide/en/schema/cache.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ schema information in [SchemaCache](https://github.com/yiisoft/db/blob/master/sr
When the [Schema](https://github.com/yiisoft/db/blob/master/src/Schema/AbstractSchema.php) needs
retrieve information about the database schema, it first checks the cache.

> [!TIP]
> Configuring schema cache with a real [PSR-16 cache implementation](https://packagist.org/providers/psr/simple-cache-implementation)
> is strongly recommended for production. Without it, schema information is retrieved from the database server on
> every request.

You can configure [SchemaCache](https://github.com/yiisoft/db/blob/master/src/Cache/SchemaCache.php) to use
[PSR-16 cache implementation](https://github.com/php-fig/simple-cache) in two ways:

Expand Down Expand Up @@ -41,7 +46,8 @@ return [
];
```

The `SchemaCache` requires `CacheInterface` and DI container will automatically resolve it.
The `SchemaCache` accepts `CacheInterface` and DI container will automatically resolve it. If `CacheInterface` isn't
configured, `SchemaCache` uses a cache that doesn't store anything, so schema information isn't cached.

## Manual cache configuration

Expand Down
62 changes: 62 additions & 0 deletions src/Cache/NullCache.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Db\Cache;

use DateInterval;
use Psr\SimpleCache\CacheInterface;
use Traversable;

/**
* PSR-16 cache implementation that doesn't store anything.
*
* {@see SchemaCache} uses it when no cache implementation is provided.
*
* @internal
*/
final class NullCache implements CacheInterface
{
public function get(string $key, mixed $default = null): mixed
{
return $default;
}

public function set(string $key, mixed $value, int|DateInterval|null $ttl = null): bool
{
return true;
}

public function delete(string $key): bool
{
return true;
}

public function clear(): bool
{
return true;
}

public function getMultiple(iterable $keys, mixed $default = null): iterable
{
return array_fill_keys(
$keys instanceof Traversable ? iterator_to_array($keys) : $keys,
$default,
);
}

public function setMultiple(iterable $values, int|DateInterval|null $ttl = null): bool
{
return true;
}

public function deleteMultiple(iterable $keys): bool
{
return true;
}

public function has(string $key): bool
{
return false;
}
}
11 changes: 7 additions & 4 deletions src/Cache/SchemaCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,21 @@
*/
final class SchemaCache
{
private readonly CacheInterface $psrCache;
private int|DateInterval|null $duration = 3600;
private bool $enabled = true;
private array $exclude = [];

/**
* @param CacheInterface $psrCache PSR-16 cache implementation to use.
* @param CacheInterface|null $psrCache PSR-16 cache implementation to use. If `null`, a cache that doesn't store
* anything is used.
*
* @link https://www.php-fig.org/psr/psr-16/
*/
public function __construct(
private readonly CacheInterface $psrCache,
) {}
public function __construct(?CacheInterface $psrCache = null)
{
$this->psrCache = $psrCache ?? new NullCache();
}
Comment thread
Tigrov marked this conversation as resolved.

/**
* Remove a value with the specified key from cache.
Expand Down
2 changes: 1 addition & 1 deletion src/Driver/Pdo/AbstractPdoConnection.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ abstract class AbstractPdoConnection extends AbstractConnection implements PdoCo

public function __construct(
protected PdoDriverInterface $driver,
protected SchemaCache $schemaCache,
protected SchemaCache $schemaCache = new SchemaCache(),
protected ?ColumnFactoryInterface $columnFactory = null,
) {}

Expand Down
2 changes: 1 addition & 1 deletion src/Schema/AbstractSchema.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ abstract class AbstractSchema implements SchemaInterface

public function __construct(
protected ConnectionInterface $db,
private readonly SchemaCache $schemaCache,
private readonly SchemaCache $schemaCache = new SchemaCache(),
) {}

public function getDefaultSchema(): string
Expand Down
35 changes: 35 additions & 0 deletions tests/Db/Cache/NullCacheTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Db\Tests\Db\Cache;

use PHPUnit\Framework\TestCase;
use Yiisoft\Db\Cache\NullCache;

/**
* @group db
*/
final class NullCacheTest extends TestCase
{
public function testBase(): void
{
$cache = new NullCache();

$this->assertTrue($cache->set('key', 'value'));
$this->assertFalse($cache->has('key'));
$this->assertNull($cache->get('key'));
$this->assertSame('default', $cache->get('key', 'default'));
$this->assertTrue($cache->delete('key'));
$this->assertTrue($cache->clear());
}

public function testMultiple(): void
{
$cache = new NullCache();

$this->assertTrue($cache->setMultiple(['a' => 1, 'b' => 2]));
$this->assertSame(['a' => 'default', 'b' => 'default'], $cache->getMultiple(['a', 'b'], 'default'));
$this->assertTrue($cache->deleteMultiple(['a', 'b']));
}
}
9 changes: 9 additions & 0 deletions tests/Db/Cache/SchemaCacheTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,15 @@ public function testWithFailSetCache(): void
$schemaCache->set('key', 'test');
}

public function testWithoutPsrCache(): void
{
$schemaCache = new SchemaCache();

$schemaCache->set('key', 'value', 'tag');

$this->assertNull($schemaCache->get('key'));
}

public function testInvalidCacheKey(): void
{
$resource = fopen('php://memory', 'r');
Expand Down
5 changes: 0 additions & 5 deletions tests/Db/Driver/Pdo/PdoConnectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@
namespace Yiisoft\Db\Tests\Db\Driver\Pdo;

use PHPUnit\Framework\TestCase;
use Yiisoft\Db\Cache\SchemaCache;
use Yiisoft\Db\Exception\InvalidCallException;
use Yiisoft\Db\Exception\InvalidConfigException;
use Yiisoft\Db\Tests\Support\Stub\StubConnection;
use Yiisoft\Db\Tests\Support\Stub\StubPdoDriver;
use Yiisoft\Test\Support\SimpleCache\MemorySimpleCache;

/**
* @group db
Expand Down Expand Up @@ -50,9 +48,6 @@ private function createConnection(string $dsn = 'sqlite::memory:'): StubConnecti
{
return new StubConnection(
new StubPdoDriver($dsn),
new SchemaCache(
new MemorySimpleCache(),
),
);
}
}
8 changes: 1 addition & 7 deletions tests/Db/Schema/SchemaTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

namespace Yiisoft\Db\Tests\Db\Schema;

use Yiisoft\Db\Cache\SchemaCache;
use Yiisoft\Db\Constraint\Check;
use Yiisoft\Db\Constraint\DefaultValue;
use Yiisoft\Db\Constraint\ForeignKey;
Expand All @@ -17,7 +16,6 @@
use Yiisoft\Db\Tests\Support\IntegrationTestCase;
use Yiisoft\Db\Tests\Support\Stub\Schema;
use Yiisoft\Db\Tests\Support\TestHelper;
use Yiisoft\Test\Support\SimpleCache\MemorySimpleCache;

use function count;

Expand Down Expand Up @@ -208,13 +206,9 @@ public function testGetTableSchemas(): void
{
$db = $this->getSharedConnection();

$schemaCache = new SchemaCache(
new MemorySimpleCache(),
);

$schemaMock = $this->getMockBuilder(Schema::class)
->onlyMethods(['findTableNames', 'loadTableSchema'])
->setConstructorArgs([$db, $schemaCache])
->setConstructorArgs([$db])
->getMock();
$schemaMock->expects($this->once())->method('findTableNames')->willReturn(['T_constraints_1']);
$schemaMock->expects($this->once())->method('loadTableSchema')->willReturn($this->createTableSchemaStub());
Expand Down
Loading