diff --git a/CHANGELOG-5.0.md b/CHANGELOG-5.0.md index e972304018..7e237e100c 100644 --- a/CHANGELOG-5.0.md +++ b/CHANGELOG-5.0.md @@ -4,6 +4,7 @@ ### Fixed - Infinite save loop in Model::save() [#16395](https://github.com/phalcon/cphalcon/issues/16395) +- Undefined column with columnMap and model caching [#16420] (https://github.com/phalcon/cphalcon/issues/16420) ## [5.3.0](https://github.com/phalcon/cphalcon/releases/tag/v5.3.0) (2023-08-15) diff --git a/phalcon/Mvc/Model/MetaData.zep b/phalcon/Mvc/Model/MetaData.zep index b8fc27009b..554c48b877 100644 --- a/phalcon/Mvc/Model/MetaData.zep +++ b/phalcon/Mvc/Model/MetaData.zep @@ -832,7 +832,7 @@ abstract class MetaData implements InjectionAwareInterface, MetaDataInterface } if true === isset(this->columnMap[key]) { - return false; + return true; } /** @@ -845,7 +845,7 @@ abstract class MetaData implements InjectionAwareInterface, MetaDataInterface if data !== null { let this->columnMap[key] = data; - return false; + return true; } /** diff --git a/tests/_data/fixtures/Traits/DiTrait.php b/tests/_data/fixtures/Traits/DiTrait.php index 6d4aa2c8f9..2cb2cf9562 100644 --- a/tests/_data/fixtures/Traits/DiTrait.php +++ b/tests/_data/fixtures/Traits/DiTrait.php @@ -35,9 +35,11 @@ use Phalcon\Http\Request; use Phalcon\Http\Response; use Phalcon\Mvc\Model\Manager as ModelsManager; +use Phalcon\Mvc\Model\Metadata\Apcu as MetadataApcu; use Phalcon\Mvc\Model\Metadata\Memory as MetadataMemory; use Phalcon\Mvc\Model\Metadata\Libmemcached as MetadataMemcached; use Phalcon\Mvc\Model\Metadata\Redis as MetadataRedis; +use Phalcon\Mvc\Model\Metadata\Stream as MetadataStream; use Phalcon\Mvc\View; use Phalcon\Mvc\View\Simple; use Phalcon\Session\Adapter\Libmemcached as SessionLibmemcached; @@ -57,6 +59,7 @@ use function getOptionsRedis; use function getOptionsSessionStream; use function getOptionsSqlite; +use function outputDir; /** * Trait DiTrait @@ -174,6 +177,11 @@ protected function newService(string $service, $options = null) return (new Filter\FilterFactory())->newInstance(); case 'metadataMemory': return new MetadataMemory(); + case 'metadataApcu': + return new MetadataApcu( + new AdapterFactory(new SerializerFactory()), + [] + ); case 'metadataLibmemcached': return new MetadataMemcached( new AdapterFactory(new SerializerFactory()), @@ -184,6 +192,11 @@ protected function newService(string $service, $options = null) new AdapterFactory(new SerializerFactory()), getOptionsRedis() ); + case 'metadataStream': + return new MetadataStream( + new AdapterFactory(new SerializerFactory()), + ['options' => ['storageDir' => outputDir()] ], + ); case 'modelsCacheLibmemcached': return new StorageLibmemcached( new SerializerFactory(), diff --git a/tests/database/Mvc/Model/MetaData/GetAttributesCest.php b/tests/database/Mvc/Model/MetaData/GetAttributesCest.php index 3cab1d38be..4095f2a8b1 100644 --- a/tests/database/Mvc/Model/MetaData/GetAttributesCest.php +++ b/tests/database/Mvc/Model/MetaData/GetAttributesCest.php @@ -13,6 +13,7 @@ namespace Phalcon\Tests\Database\Mvc\Model\MetaData; +use Codeception\Example; use DatabaseTester; use Phalcon\Mvc\Model\MetaData; use Phalcon\Tests\Fixtures\Traits\DiTrait; @@ -34,6 +35,11 @@ public function _before(DatabaseTester $I) /** * Tests Phalcon\Mvc\Model\MetaData :: getAttributes() * + * @dataProvider getExamples + * + * @param DatabaseTester $I + * @param Example $example + * * @author Phalcon Team * @since 2020-02-01 * @@ -41,10 +47,22 @@ public function _before(DatabaseTester $I) * @group pgsql * @group sqlite */ - public function mvcModelMetadataGetAttributes(DatabaseTester $I) - { + public function mvcModelMetadataGetAttributes( + DatabaseTester $I, + Example $example + ) { $I->wantToTest('Mvc\Model\MetaData - getAttributes()'); + $service = $example['service']; + + $adapter = $this->newService($service); + $connection = $I->getConnection(); + $adapter->setDi($this->container); + + $adapter->reset(); + + $this->container->setShared('modelsMetadata', $adapter); + /** @var MetaData $metadata */ $metadata = $this->container->get('modelsMetadata'); @@ -59,5 +77,39 @@ public function mvcModelMetadataGetAttributes(DatabaseTester $I) ]; $actual = $metadata->getAttributes($model); $I->assertEquals($expected, $actual); + + $adapter = $this->newService($service); + $this->container->setShared('modelsMetadata', $adapter); + $adapter->setDi($this->container); + + $I->assertNotEquals($adapter, $metadata); + + $actual = $adapter->getAttributes($model); + $I->assertEquals($expected, $actual); + } + + /** + * @return array[] + */ + private function getExamples(): array + { + return [ + [ + 'service' => 'metadataMemory', + 'className' => 'Memory', + ], + [ + 'service' => 'metadataApcu', + 'className' => 'Apcu', + ], + [ + 'service' => 'metadataRedis', + 'className' => 'Redis', + ], + [ + 'service' => 'metadataLibmemcached', + 'className' => 'Libmemcached', + ], + ]; } } diff --git a/tests/database/Mvc/Model/MetaData/GetColumnMapCest.php b/tests/database/Mvc/Model/MetaData/GetColumnMapCest.php index 06edf3bff4..3ca01b19f8 100644 --- a/tests/database/Mvc/Model/MetaData/GetColumnMapCest.php +++ b/tests/database/Mvc/Model/MetaData/GetColumnMapCest.php @@ -13,6 +13,7 @@ namespace Phalcon\Tests\Database\Mvc\Model\MetaData; +use Codeception\Example; use DatabaseTester; use Phalcon\Mvc\Model\MetaData; use Phalcon\Storage\Exception; @@ -47,7 +48,10 @@ public function _before(DatabaseTester $I): void /** * Tests Phalcon\Mvc\Model\MetaData :: getColumnMap() * - * @param DatabaseTester $I + * @dataProvider getExamples + * + * @param DatabaseTester $I + * @param Example $example * * @author Phalcon Team * @since 2020-02-01 @@ -56,10 +60,22 @@ public function _before(DatabaseTester $I): void * @group pgsql * @group sqlite */ - public function mvcModelMetadataGetColumnMap(DatabaseTester $I) - { + public function mvcModelMetadataGetColumnMap( + DatabaseTester $I, + Example $example + ) { $I->wantToTest('Mvc\Model\MetaData - getColumnMap()'); + $service = $example['service']; + + $adapter = $this->newService($service); + $adapter->setDi($this->container); + $connection = $I->getConnection(); + + $adapter->reset(); + + $this->container->setShared('modelsMetadata', $adapter); + /** @var MetaData $metadata */ $metadata = $this->container->get('modelsMetadata'); $model = new Invoices(); @@ -77,5 +93,45 @@ public function mvcModelMetadataGetColumnMap(DatabaseTester $I) ]; $I->assertEquals($expected, $metadata->getColumnMap($model)); + + $I->assertTrue($adapter->isEmpty()); + + /** + * Double check it can get from cache systems and not memory + */ + $adapter = $this->newService($service); + $this->container->setShared('modelsMetadata', $adapter); + $adapter->setDi($this->container); + + $I->assertNotEquals($adapter, $metadata); + + $I->assertTrue($adapter->isEmpty()); + + $I->assertEquals($expected, $adapter->getColumnMap($model)); + } + + /** + * @return array[] + */ + private function getExamples(): array + { + return [ + [ + 'service' => 'metadataMemory', + 'className' => 'Memory', + ], + [ + 'service' => 'metadataApcu', + 'className' => 'Apcu', + ], + [ + 'service' => 'metadataRedis', + 'className' => 'Redis', + ], + [ + 'service' => 'metadataLibmemcached', + 'className' => 'Libmemcached', + ], + ]; } } diff --git a/tests/database/Mvc/Model/MetaData/GetDataTypesCest.php b/tests/database/Mvc/Model/MetaData/GetDataTypesCest.php index 2319a5452a..bfb3034b35 100644 --- a/tests/database/Mvc/Model/MetaData/GetDataTypesCest.php +++ b/tests/database/Mvc/Model/MetaData/GetDataTypesCest.php @@ -13,6 +13,7 @@ namespace Phalcon\Tests\Database\Mvc\Model\MetaData; +use Codeception\Example; use DatabaseTester; use Phalcon\Mvc\Model\MetaData; use Phalcon\Tests\Fixtures\Traits\DiTrait; @@ -34,6 +35,11 @@ public function _before(DatabaseTester $I) /** * Tests Phalcon\Mvc\Model\MetaData :: getDataTypes() * + * @dataProvider getExamples + * + * @param DatabaseTester $I + * @param Example $example + * * @author Phalcon Team * @since 2020-02-01 * @@ -41,10 +47,23 @@ public function _before(DatabaseTester $I) * @group pgsql * @group sqlite */ - public function mvcModelMetadataGetDataTypes(DatabaseTester $I) - { + public function mvcModelMetadataGetDataTypes( + DatabaseTester $I, + Example $example + ) { $I->wantToTest('Mvc\Model\MetaData - getDataTypes()'); + $service = $example['service']; + + $adapter = $this->newService($service); + $adapter->setDi($this->container); + $connection = $I->getConnection(); + + $adapter->reset(); + $I->assertTrue($adapter->isEmpty()); + + $this->container->setShared('modelsMetadata', $adapter); + /** @var MetaData $metadata */ $metadata = $this->container->get('modelsMetadata'); @@ -52,6 +71,22 @@ public function mvcModelMetadataGetDataTypes(DatabaseTester $I) $expected = $this->getTypes($I); $actual = $metadata->getDataTypes($model); $I->assertEquals($expected, $actual); + + $I->assertFalse($adapter->isEmpty()); + + /** + * Double check it can get from cache systems and not memory + */ + $adapter = $this->newService($service); + $this->container->setShared('modelsMetadata', $adapter); + $adapter->setDi($this->container); + + $I->assertNotEquals($adapter, $metadata); + + $I->assertTrue($adapter->isEmpty()); + + $actual = $adapter->getDataTypes($model); + $I->assertEquals($expected, $actual); } private function getTypes(DatabaseTester $I) @@ -87,4 +122,29 @@ private function getTypes(DatabaseTester $I) ]; } } + + /** + * @return array[] + */ + private function getExamples(): array + { + return [ + [ + 'service' => 'metadataMemory', + 'className' => 'Memory', + ], + [ + 'service' => 'metadataApcu', + 'className' => 'Apcu', + ], + [ + 'service' => 'metadataRedis', + 'className' => 'Redis', + ], + [ + 'service' => 'metadataLibmemcached', + 'className' => 'Libmemcached', + ], + ]; + } } diff --git a/tests/database/Mvc/Model/MetaData/GetIdentityFieldCest.php b/tests/database/Mvc/Model/MetaData/GetIdentityFieldCest.php index b6a2fc00c5..67691e2061 100644 --- a/tests/database/Mvc/Model/MetaData/GetIdentityFieldCest.php +++ b/tests/database/Mvc/Model/MetaData/GetIdentityFieldCest.php @@ -13,6 +13,7 @@ namespace Phalcon\Tests\Database\Mvc\Model\MetaData; +use Codeception\Example; use DatabaseTester; use Phalcon\Mvc\Model\MetaData; use Phalcon\Tests\Fixtures\Traits\DiTrait; @@ -34,6 +35,11 @@ public function _before(DatabaseTester $I) /** * Tests Phalcon\Mvc\Model\MetaData :: getIdentityField() * + * @dataProvider getExamples + * + * @param DatabaseTester $I + * @param Example $example + * * @author Phalcon Team * @since 2020-02-01 * @@ -41,10 +47,23 @@ public function _before(DatabaseTester $I) * @group pgsql * @group sqlite */ - public function mvcModelMetadataGetIdentityField(DatabaseTester $I) - { + public function mvcModelMetadataGetIdentityField( + DatabaseTester $I, + Example $example + ) { $I->wantToTest('Mvc\Model\MetaData - getIdentityField()'); + $service = $example['service']; + + $adapter = $this->newService($service); + $adapter->setDi($this->container); + $connection = $I->getConnection(); + + $adapter->reset(); + $I->assertTrue($adapter->isEmpty()); + + $this->container->setShared('modelsMetadata', $adapter); + /** @var MetaData $metadata */ $metadata = $this->container->get('modelsMetadata'); @@ -52,5 +71,48 @@ public function mvcModelMetadataGetIdentityField(DatabaseTester $I) $expected = 'inv_id'; $actual = $metadata->getIdentityField($model); $I->assertEquals($expected, $actual); + + $I->assertFalse($adapter->isEmpty()); + + /** + * Double check it can get from cache systems and not memory + */ + $adapter = $this->newService($service); + $this->container->setShared('modelsMetadata', $adapter); + $adapter->setDi($this->container); + + $I->assertNotEquals($adapter, $metadata); + + $I->assertTrue($adapter->isEmpty()); + + $model = new Invoices(); + $expected = 'inv_id'; + $actual = $adapter->getIdentityField($model); + $I->assertEquals($expected, $actual); + } + + /** + * @return array[] + */ + private function getExamples(): array + { + return [ + [ + 'service' => 'metadataMemory', + 'className' => 'Memory', + ], + [ + 'service' => 'metadataApcu', + 'className' => 'Apcu', + ], + [ + 'service' => 'metadataRedis', + 'className' => 'Redis', + ], + [ + 'service' => 'metadataLibmemcached', + 'className' => 'Libmemcached', + ], + ]; } } diff --git a/tests/database/Mvc/Model/MetaData/GetNonPrimaryKeyAttributesCest.php b/tests/database/Mvc/Model/MetaData/GetNonPrimaryKeyAttributesCest.php index 41dc846e05..c501c82963 100644 --- a/tests/database/Mvc/Model/MetaData/GetNonPrimaryKeyAttributesCest.php +++ b/tests/database/Mvc/Model/MetaData/GetNonPrimaryKeyAttributesCest.php @@ -13,6 +13,7 @@ namespace Phalcon\Tests\Database\Mvc\Model\MetaData; +use Codeception\Example; use DatabaseTester; use Phalcon\Mvc\Model\MetaData; use Phalcon\Tests\Fixtures\Traits\DiTrait; @@ -34,6 +35,11 @@ public function _before(DatabaseTester $I) /** * Tests Phalcon\Mvc\Model\MetaData :: getNonPrimaryKeyAttributes() * + * @dataProvider getExamples + * + * @param DatabaseTester $I + * @param Example $example + * * @author Phalcon Team * @since 2020-02-01 * @@ -41,10 +47,23 @@ public function _before(DatabaseTester $I) * @group pgsql * @group sqlite */ - public function mvcModelMetadataGetNonPrimaryKeyAttributes(DatabaseTester $I) - { + public function mvcModelMetadataGetNonPrimaryKeyAttributes( + DatabaseTester $I, + Example $example + ) { $I->wantToTest('Mvc\Model\MetaData - getNonPrimaryKeyAttributes()'); + + $service = $example['service']; + + $adapter = $this->newService($service); + $adapter->setDi($this->container); + $connection = $I->getConnection(); + + $adapter->reset(); + + $this->container->setShared('modelsMetadata', $adapter); + /** @var MetaData $metadata */ $metadata = $this->container->get('modelsMetadata'); @@ -56,8 +75,48 @@ public function mvcModelMetadataGetNonPrimaryKeyAttributes(DatabaseTester $I) 'inv_total', 'inv_created_at', ]; - $actual = $metadata->getNonPrimaryKeyAttributes($model); + $actual = $metadata->getNonPrimaryKeyAttributes($model); $I->assertEquals($expected, $actual); + + $I->assertFalse($adapter->isEmpty()); + + /** + * Double check it can get from cache systems and not memory + */ + $adapter = $this->newService($service); + $this->container->setShared('modelsMetadata', $adapter); + $adapter->setDi($this->container); + + $I->assertNotEquals($adapter, $metadata); + + $I->assertTrue($adapter->isEmpty()); + $actual = $adapter->getNonPrimaryKeyAttributes($model); + $I->assertEquals($expected, $actual); + } + + /** + * @return array[] + */ + private function getExamples(): array + { + return [ + [ + 'service' => 'metadataMemory', + 'className' => 'Memory', + ], + [ + 'service' => 'metadataApcu', + 'className' => 'Apcu', + ], + [ + 'service' => 'metadataRedis', + 'className' => 'Redis', + ], + [ + 'service' => 'metadataLibmemcached', + 'className' => 'Libmemcached', + ], + ]; } } diff --git a/tests/database/Mvc/Model/MetaData/GetNotNullAttributesCest.php b/tests/database/Mvc/Model/MetaData/GetNotNullAttributesCest.php index f7a682fc5b..25275b458f 100644 --- a/tests/database/Mvc/Model/MetaData/GetNotNullAttributesCest.php +++ b/tests/database/Mvc/Model/MetaData/GetNotNullAttributesCest.php @@ -13,6 +13,7 @@ namespace Phalcon\Tests\Database\Mvc\Model\MetaData; +use Codeception\Example; use DatabaseTester; use Phalcon\Mvc\Model\MetaData; use Phalcon\Tests\Fixtures\Traits\DiTrait; @@ -34,6 +35,11 @@ public function _before(DatabaseTester $I) /** * Tests Phalcon\Mvc\Model\MetaData :: getNotNullAttributes() * + * @dataProvider getExamples + * + * @param DatabaseTester $I + * @param Example $example + * * @author Phalcon Team * @since 2020-02-01 * @@ -41,10 +47,20 @@ public function _before(DatabaseTester $I) * @group pgsql * @group sqlite */ - public function mvcModelMetadataGetNotNullAttributes(DatabaseTester $I) - { + public function mvcModelMetadataGetNotNullAttributes( + DatabaseTester $I, + Example $example + ) { $I->wantToTest('Mvc\Model\MetaData - getNotNullAttributes()'); + $service = $example['service']; + + $adapter = $this->newService($service); + $adapter->setDi($this->container); + $connection = $I->getConnection(); + + $adapter->reset(); + /** @var MetaData $metadata */ $metadata = $this->container->get('modelsMetadata'); @@ -54,5 +70,45 @@ public function mvcModelMetadataGetNotNullAttributes(DatabaseTester $I) ]; $actual = $metadata->getNotNullAttributes($model); $I->assertEquals($expected, $actual); + + $I->assertFalse($metadata->isEmpty()); + + /** + * Double check it can get from cache systems and not memory + */ + $adapter = $this->newService($service); + $this->container->setShared('modelsMetadata', $adapter); + $adapter->setDi($this->container); + + $I->assertNotEquals($adapter, $metadata); + + $I->assertTrue($adapter->isEmpty()); + $actual = $adapter->getNotNullAttributes($model); + $I->assertEquals($expected, $actual); + } + + /** + * @return array[] + */ + private function getExamples(): array + { + return [ + [ + 'service' => 'metadataMemory', + 'className' => 'Memory', + ], + [ + 'service' => 'metadataApcu', + 'className' => 'Apcu', + ], + [ + 'service' => 'metadataRedis', + 'className' => 'Redis', + ], + [ + 'service' => 'metadataLibmemcached', + 'className' => 'Libmemcached', + ], + ]; } } diff --git a/tests/database/Mvc/Model/MetaData/GetSetDICest.php b/tests/database/Mvc/Model/MetaData/GetSetDICest.php index 9d5ea4351b..90a0d6647d 100644 --- a/tests/database/Mvc/Model/MetaData/GetSetDICest.php +++ b/tests/database/Mvc/Model/MetaData/GetSetDICest.php @@ -13,6 +13,7 @@ namespace Phalcon\Tests\Database\Mvc\Model\MetaData; +use Codeception\Example; use DatabaseTester; use Phalcon\Mvc\Model\Exception as ExpectedException; use Phalcon\Mvc\Model\MetaData\Memory; @@ -41,19 +42,26 @@ public function _before(DatabaseTester $I): void /** * Tests Phalcon\Mvc\Model\MetaData :: getDI() / setDI() * - * @param DatabaseTester $I + * @dataProvider getExamples + * + * @param DatabaseTester $I + * @param Example $example * * @author Phalcon Team * @since 2020-02-01 * * @group common */ - public function mvcModelMetadataGetSetDI(DatabaseTester $I) - { + public function mvcModelMetadataGetSetDI( + DatabaseTester $I, + Example $example + ) { $I->wantToTest('Mvc\Model\MetaData - getDI() / setDI()'); - $metadata = new Memory(); - $metadata->setDI($this->container); + $service = $example['service']; + + $metadata = $this->newService($service); + $metadata->setDi($this->container); $I->assertEquals($this->container, $metadata->getDI()); } @@ -81,4 +89,29 @@ function () { } ); } + + /** + * @return array[] + */ + private function getExamples(): array + { + return [ + [ + 'service' => 'metadataMemory', + 'className' => 'Memory', + ], + [ + 'service' => 'metadataApcu', + 'className' => 'Apcu', + ], + [ + 'service' => 'metadataRedis', + 'className' => 'Redis', + ], + [ + 'service' => 'metadataLibmemcached', + 'className' => 'Libmemcached', + ], + ]; + } } diff --git a/tests/database/Mvc/Model/MetaData/HasAttributeCest.php b/tests/database/Mvc/Model/MetaData/HasAttributeCest.php index 0b6e058287..a541cee731 100644 --- a/tests/database/Mvc/Model/MetaData/HasAttributeCest.php +++ b/tests/database/Mvc/Model/MetaData/HasAttributeCest.php @@ -13,6 +13,7 @@ namespace Phalcon\Tests\Database\Mvc\Model\MetaData; +use Codeception\Example; use DatabaseTester; use Phalcon\Mvc\Model\MetaData; use Phalcon\Tests\Fixtures\Traits\DiTrait; @@ -31,9 +32,14 @@ public function _before(DatabaseTester $I) $this->setDatabase($I); } - /** + /** * Tests Phalcon\Mvc\Model\MetaData :: hasAttribute() * + * @dataProvider getExamples + * + * @param DatabaseTester $I + * @param Example $example + * * @author Phalcon Team * @since 2018-11-13 * @@ -41,10 +47,21 @@ public function _before(DatabaseTester $I) * @group pgsql * @group sqlite */ - public function mvcModelMetadataHasAttribute(DatabaseTester $I) - { + public function mvcModelMetadataHasAttribute( + DatabaseTester $I, + Example $example + ) { $I->wantToTest('Mvc\Model\MetaData - hasAttribute()'); + $service = $example['service']; + + $adapter = $this->newService($service); + $adapter->setDi($this->container); + $connection = $I->getConnection(); + + $adapter->reset(); + + $this->container->setShared('modelsMetadata', $adapter); /** @var MetaData $metadata */ $metadata = $this->container->get('modelsMetadata'); @@ -57,5 +74,51 @@ public function mvcModelMetadataHasAttribute(DatabaseTester $I) $I->assertTrue($metadata->hasAttribute($model, 'inv_created_at')); $I->assertFalse($metadata->hasAttribute($model, 'unknown')); + $I->assertFalse($adapter->isEmpty()); + + /** + * Double check it can get from cache systems and not memory + */ + $adapter = $this->newService($service); + $this->container->setShared('modelsMetadata', $adapter); + $adapter->setDi($this->container); + + $I->assertNotEquals($adapter, $metadata); + + $I->assertTrue($adapter->isEmpty()); + + $I->assertTrue($adapter->hasAttribute($model, 'inv_id')); + $I->assertTrue($adapter->hasAttribute($model, 'inv_cst_id')); + $I->assertTrue($adapter->hasAttribute($model, 'inv_status_flag')); + $I->assertTrue($adapter->hasAttribute($model, 'inv_title')); + $I->assertTrue($adapter->hasAttribute($model, 'inv_total')); + $I->assertTrue($adapter->hasAttribute($model, 'inv_created_at')); + + $I->assertFalse($adapter->hasAttribute($model, 'unknown')); + } + + /** + * @return array[] + */ + private function getExamples(): array + { + return [ + [ + 'service' => 'metadataMemory', + 'className' => 'Memory', + ], + [ + 'service' => 'metadataApcu', + 'className' => 'Apcu', + ], + [ + 'service' => 'metadataRedis', + 'className' => 'Redis', + ], + [ + 'service' => 'metadataLibmemcached', + 'className' => 'Libmemcached', + ], + ]; } }