Skip to content

Commit 014fd7d

Browse files
committed
Improved Solr driver integration
1 parent 1cf2e7b commit 014fd7d

File tree

6 files changed

+60
-57
lines changed

6 files changed

+60
-57
lines changed

bin/ci/scripts/install_solr.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ wait_for_solr(){
3333
done
3434
}
3535

36-
run_solr5() {
36+
run_solr() {
3737
dir_name=$1
3838
./$dir_name/bin/solr -p $SOLR_PORT -h $SOLR_HOST
3939
wait_for_solr
@@ -47,7 +47,7 @@ download_and_run() {
4747
dir_name="solr-${version}"
4848
download $url $dir_name
4949

50-
run_solr5 $dir_name
50+
run_solr $dir_name
5151
}
5252

5353

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@
5656
"aws/aws-sdk-php": "~3.0"
5757
},
5858
"conflict": {
59-
"doctrine/couchdb": "<dev-master#9eeb9e5"
59+
"doctrine/couchdb": "<dev-master#9eeb9e5",
60+
"solarium/solarium": "<6.1"
6061
},
6162
"autoload": {
6263
"psr-4": {

lib/Phpfastcache/Drivers/Solr/Config.php

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,20 @@
1818
use Phpfastcache\Config\ConfigurationOption;
1919
use Phpfastcache\Core\Pool\ExtendedCacheItemPoolInterface;
2020
use Phpfastcache\Core\Pool\TaggableCacheItemPoolInterface;
21-
use Phpfastcache\EventManager;
2221
use Phpfastcache\Exceptions\PhpfastcacheInvalidArgumentException;
2322
use Phpfastcache\Exceptions\PhpfastcacheLogicException;
2423
use Psr\EventDispatcher\EventDispatcherInterface;
2524

2625
class Config extends ConfigurationOption
2726
{
28-
protected const DEFAULT_MAPPING_SCHEMA = [
27+
public const DEFAULT_MAPPING_SCHEMA = [
28+
Driver::SOLR_DEFAULT_ID_FIELD => Driver::SOLR_DEFAULT_ID_FIELD,
29+
Driver::SOLR_DISCRIMINATOR_FIELD => Driver::SOLR_DISCRIMINATOR_FIELD . '_s',
2930
ExtendedCacheItemPoolInterface::DRIVER_KEY_WRAPPER_INDEX => ExtendedCacheItemPoolInterface::DRIVER_KEY_WRAPPER_INDEX . '_s',
3031
ExtendedCacheItemPoolInterface::DRIVER_DATA_WRAPPER_INDEX => ExtendedCacheItemPoolInterface::DRIVER_DATA_WRAPPER_INDEX . '_s',
31-
ExtendedCacheItemPoolInterface::DRIVER_EDATE_WRAPPER_INDEX => ExtendedCacheItemPoolInterface::DRIVER_EDATE_WRAPPER_INDEX . '_ss',
32-
ExtendedCacheItemPoolInterface::DRIVER_MDATE_WRAPPER_INDEX => ExtendedCacheItemPoolInterface::DRIVER_MDATE_WRAPPER_INDEX . '_ss',
33-
ExtendedCacheItemPoolInterface::DRIVER_CDATE_WRAPPER_INDEX => ExtendedCacheItemPoolInterface::DRIVER_CDATE_WRAPPER_INDEX . '_ss',
32+
ExtendedCacheItemPoolInterface::DRIVER_EDATE_WRAPPER_INDEX => ExtendedCacheItemPoolInterface::DRIVER_EDATE_WRAPPER_INDEX . '_s',
33+
ExtendedCacheItemPoolInterface::DRIVER_MDATE_WRAPPER_INDEX => ExtendedCacheItemPoolInterface::DRIVER_MDATE_WRAPPER_INDEX . '_s',
34+
ExtendedCacheItemPoolInterface::DRIVER_CDATE_WRAPPER_INDEX => ExtendedCacheItemPoolInterface::DRIVER_CDATE_WRAPPER_INDEX . '_s',
3435
TaggableCacheItemPoolInterface::DRIVER_TAGS_WRAPPER_INDEX => TaggableCacheItemPoolInterface::DRIVER_TAGS_WRAPPER_INDEX . '_ss',
3536
];
3637

lib/Phpfastcache/Drivers/Solr/Driver.php

Lines changed: 47 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@
2020
use Phpfastcache\Core\Pool\ExtendedCacheItemPoolInterface;
2121
use Phpfastcache\Core\Pool\TaggableCacheItemPoolTrait;
2222
use Phpfastcache\Entities\DriverStatistic;
23+
use Phpfastcache\Exceptions\PhpfastcacheDriverCheckException;
2324
use Phpfastcache\Exceptions\PhpfastcacheDriverConnectException;
2425
use Phpfastcache\Exceptions\PhpfastcacheDriverException;
26+
use Phpfastcache\Exceptions\PhpfastcacheInvalidTypeException;
2527
use Phpfastcache\Exceptions\PhpfastcacheLogicException;
2628
use Solarium\Client as SolariumClient;
2729
use Solarium\Core\Client\Adapter\Curl as SolariumCurlAdapter;
@@ -35,6 +37,14 @@
3537
*/
3638
class Driver implements ExtendedCacheItemPoolInterface, AggregatablePoolInterface
3739
{
40+
public const MINIMUM_SOLARIUM_VERSION = '6.1.0';
41+
42+
public const SOLR_DEFAULT_ID_FIELD = 'id';
43+
44+
public const SOLR_DISCRIMINATOR_FIELD = 'type';
45+
46+
public const SOLR_DISCRIMINATOR_VALUE = '_pfc_';
47+
3848
use TaggableCacheItemPoolTrait;
3949

4050
/**
@@ -45,10 +55,20 @@ class Driver implements ExtendedCacheItemPoolInterface, AggregatablePoolInterfac
4555

4656
/**
4757
* @return bool
58+
* @throws PhpfastcacheDriverCheckException
4859
*/
4960
public function driverCheck(): bool
5061
{
51-
return \class_exists(SolariumClient::class);
62+
if (!\class_exists(SolariumClient::class)) {
63+
throw new PhpfastcacheDriverCheckException(
64+
\sprintf(
65+
'Phpfastcache needs Solarium %s or greater to be installed',
66+
self::MINIMUM_SOLARIUM_VERSION
67+
)
68+
);
69+
}
70+
71+
return true;
5272
}
5373

5474
/**
@@ -71,12 +91,10 @@ protected function driverConnect(): bool
7191
]);
7292

7393
try {
74-
$this->instance->ping($this->instance->createPing());
94+
return $this->instance->ping($this->instance->createPing())->getStatus() === 0;
7595
} catch (SolariumExceptionInterface $e) {
7696
throw new PhpfastcacheDriverConnectException($e->getMessage(), 0, $e);
7797
}
78-
79-
return false;
8098
}
8199

82100
/**
@@ -90,24 +108,16 @@ protected function driverWrite(ExtendedCacheItemInterface $item): bool
90108

91109
$doc = $update->createDocument();
92110
/** @SuppressWarnings(PHPMD.UndefinedVariable) */
93-
$doc->id = $item->getEncodedKey();
111+
$doc->{$this->getSolrField(self::SOLR_DEFAULT_ID_FIELD)} = $item->getEncodedKey();
112+
$doc->{$this->getSolrField(self::SOLR_DISCRIMINATOR_FIELD)} = self::SOLR_DISCRIMINATOR_VALUE;
94113
$doc->{$this->getSolrField(self::DRIVER_KEY_WRAPPER_INDEX)} = $item->getKey();
95114
$doc->{$this->getSolrField(self::DRIVER_DATA_WRAPPER_INDEX)} = $this->encode($item->getRawValue());
96115
$doc->{$this->getSolrField(self::DRIVER_TAGS_WRAPPER_INDEX)} = $item->getTags();
97-
$doc->{$this->getSolrField(self::DRIVER_EDATE_WRAPPER_INDEX)} = [
98-
$item->getExpirationDate()->format(\DateTimeInterface::ATOM),
99-
$item->getExpirationDate()->getTimezone()->getName()
100-
];
116+
$doc->{$this->getSolrField(self::DRIVER_EDATE_WRAPPER_INDEX)} = $item->getExpirationDate()->format(\DateTimeInterface::ATOM);
101117

102118
if ($this->getConfig()->isItemDetailedDate()) {
103-
$doc->{$this->getSolrField(self::DRIVER_MDATE_WRAPPER_INDEX)} = [
104-
$item->getModificationDate()->format(\DateTimeInterface::ATOM),
105-
$item->getModificationDate()->getTimezone()->getName()
106-
];
107-
$doc->{$this->getSolrField(self::DRIVER_CDATE_WRAPPER_INDEX)} = [
108-
$item->getCreationDate()->format(\DateTimeInterface::ATOM),
109-
$item->getCreationDate()->getTimezone()->getName()
110-
];
119+
$doc->{$this->getSolrField(self::DRIVER_MDATE_WRAPPER_INDEX)} = $item->getModificationDate()->format(\DateTimeInterface::ATOM);
120+
$doc->{$this->getSolrField(self::DRIVER_CDATE_WRAPPER_INDEX)} = $item->getCreationDate()->format(\DateTimeInterface::ATOM);
111121
}
112122

113123
$update->addDocument($doc);
@@ -124,10 +134,10 @@ protected function driverWrite(ExtendedCacheItemInterface $item): bool
124134
protected function driverRead(ExtendedCacheItemInterface $item): ?array
125135
{
126136
$query = $this->instance->createSelect()
127-
->setQuery('id:' . $item->getEncodedKey())
137+
->setQuery($this->getSolrField(self::SOLR_DEFAULT_ID_FIELD) . ':' . $item->getEncodedKey())
128138
->setRows(1);
129139

130-
$results = $this->instance->execute($query);
140+
$results = $this->instance->execute($query);
131141

132142
if ($results instanceof \IteratorAggregate) {
133143
$document = $results->getIterator()[0] ?? null;
@@ -148,9 +158,17 @@ protected function driverRead(ExtendedCacheItemInterface $item): ?array
148158
protected function decodeDocument(SolariumDocument $document): array
149159
{
150160
$fields = $document->getFields();
161+
$key = $fields[$this->getSolrField(self::DRIVER_KEY_WRAPPER_INDEX)];
162+
163+
if (\is_array($key)) {
164+
throw new PhpfastcacheInvalidTypeException(
165+
'Your Solr core seems to be misconfigured, please check the Phpfastcache wiki to setup the expected schema:
166+
https://github.com/PHPSocialNetwork/phpfastcache/wiki/%5BV9.1%CB%96%5D-Configuring-a-Solr-driver'
167+
);
168+
}
151169

152170
$value = [
153-
self::DRIVER_KEY_WRAPPER_INDEX => $fields[$this->getSolrField(self::DRIVER_KEY_WRAPPER_INDEX)],
171+
self::DRIVER_KEY_WRAPPER_INDEX => $key,
154172
self::DRIVER_TAGS_WRAPPER_INDEX => $fields[$this->getSolrField(self::DRIVER_TAGS_WRAPPER_INDEX)] ?? [],
155173
self::DRIVER_DATA_WRAPPER_INDEX => $this->decode(
156174
$fields[$this->getSolrField(self::DRIVER_DATA_WRAPPER_INDEX)],
@@ -159,26 +177,17 @@ protected function decodeDocument(SolariumDocument $document): array
159177

160178
$eDate = $fields[$this->getSolrField(self::DRIVER_EDATE_WRAPPER_INDEX)];
161179

162-
$value[ExtendedCacheItemPoolInterface::DRIVER_EDATE_WRAPPER_INDEX] = new \DateTime(
163-
$eDate[0],
164-
new \DateTimeZone($eDate[1])
165-
);
180+
$value[ExtendedCacheItemPoolInterface::DRIVER_EDATE_WRAPPER_INDEX] = new \DateTime($eDate);
166181

167182
if ($this->getConfig()->isItemDetailedDate()) {
168183
$cDate = $fields[$this->getSolrField(self::DRIVER_CDATE_WRAPPER_INDEX)];
169-
if (isset($cDate[0], $cDate[1])) {
170-
$value[ExtendedCacheItemPoolInterface::DRIVER_CDATE_WRAPPER_INDEX] = new \DateTime(
171-
$cDate[0],
172-
new \DateTimeZone($cDate[1])
173-
);
184+
if (!empty($cDate)) {
185+
$value[ExtendedCacheItemPoolInterface::DRIVER_CDATE_WRAPPER_INDEX] = new \DateTime($cDate);
174186
}
175187

176188
$mDate = $fields[$this->getSolrField(self::DRIVER_MDATE_WRAPPER_INDEX)];
177-
if (isset($mDate[0], $cDate[1])) {
178-
$value[ExtendedCacheItemPoolInterface::DRIVER_MDATE_WRAPPER_INDEX] = new \DateTime(
179-
$mDate[0],
180-
new \DateTimeZone($mDate[1])
181-
);
189+
if (!empty($mDate)) {
190+
$value[ExtendedCacheItemPoolInterface::DRIVER_MDATE_WRAPPER_INDEX] = new \DateTime($mDate);
182191
}
183192
}
184193

@@ -194,7 +203,8 @@ protected function driverDelete(ExtendedCacheItemInterface $item): bool
194203
{
195204
$update = $this->instance->createUpdate();
196205

197-
$update->addDeleteById($item->getEncodedKey());
206+
$update->addDeleteQuery($this->getSolrField(self::SOLR_DEFAULT_ID_FIELD) . ':' . $item->getEncodedKey());
207+
$update->addDeleteQuery($this->getSolrField(self::SOLR_DISCRIMINATOR_FIELD) . ':' . self::SOLR_DISCRIMINATOR_VALUE);
198208
$update->addCommit();
199209

200210
return $this->instance->update($update)->getStatus() === 0;
@@ -208,10 +218,10 @@ protected function driverClear(): bool
208218
{
209219
// get an update query instance
210220
$update = $this->instance->createUpdate();
211-
$update->addDeleteQuery('*:*');
221+
$update->addDeleteQuery($this->getSolrField(self::SOLR_DISCRIMINATOR_FIELD) . ':' . self::SOLR_DISCRIMINATOR_VALUE);
212222
$update->addCommit();
213223

214-
return $this->instance->update($update)->getStatus() === 0;
224+
return $this->instance->update($update)->getStatus() === 0;
215225
}
216226

217227
/**

tests/Solr.test.php

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@
1313
*/
1414

1515
use Phpfastcache\CacheManager;
16-
use Phpfastcache\Core\Pool\ExtendedCacheItemPoolInterface;
17-
use Phpfastcache\Core\Pool\TaggableCacheItemPoolInterface;
1816
use Phpfastcache\Tests\Helper\TestHelper;
1917
use Phpfastcache\Drivers\Solr\Config as SolrConfig;
2018

@@ -38,14 +36,7 @@
3836
* The keys are the Phpfastcache internal index. All required.
3937
* The values are the name of your Solr schema.
4038
*/
41-
$solrConfig->setMappingSchema([
42-
ExtendedCacheItemPoolInterface::DRIVER_KEY_WRAPPER_INDEX => ExtendedCacheItemPoolInterface::DRIVER_KEY_WRAPPER_INDEX . '_s', // Expect type "string" field
43-
ExtendedCacheItemPoolInterface::DRIVER_DATA_WRAPPER_INDEX => ExtendedCacheItemPoolInterface::DRIVER_DATA_WRAPPER_INDEX . '_s', // Expect type "string" field
44-
ExtendedCacheItemPoolInterface::DRIVER_EDATE_WRAPPER_INDEX => ExtendedCacheItemPoolInterface::DRIVER_EDATE_WRAPPER_INDEX . '_ss', // Expect type "strings" field
45-
ExtendedCacheItemPoolInterface::DRIVER_MDATE_WRAPPER_INDEX => ExtendedCacheItemPoolInterface::DRIVER_MDATE_WRAPPER_INDEX . '_ss', // Expect type "strings" field
46-
ExtendedCacheItemPoolInterface::DRIVER_CDATE_WRAPPER_INDEX => ExtendedCacheItemPoolInterface::DRIVER_CDATE_WRAPPER_INDEX . '_ss', // Expect type "strings" field
47-
TaggableCacheItemPoolInterface::DRIVER_TAGS_WRAPPER_INDEX => TaggableCacheItemPoolInterface::DRIVER_TAGS_WRAPPER_INDEX . '_ss', // Expect type "strings" field
48-
]);
39+
$solrConfig->setMappingSchema($solrConfig::DEFAULT_MAPPING_SCHEMA);
4940

5041
/**
5142
* Optional:
@@ -55,6 +46,6 @@
5546
// $solrConfig->setEventDispatcher($yourEventDispatcher);
5647

5748
$cacheInstance = CacheManager::getInstance('Solr', $solrConfig);
58-
$testHelper->runCRUDTests($cacheInstance);
49+
$testHelper->runCRUDTests($cacheInstance, false);
5950

6051
$testHelper->terminateTest();

tests/lib/Helper/TestHelper.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,7 @@ public function runCRUDTests(ExtendedCacheItemPoolInterface|PhpfastcacheAbstract
503503
}
504504

505505
if ($poolClear) {
506-
if ($pool->deleteItem($cacheKey)) {
506+
if ($pool->deleteItem($cacheKey) && !$pool->getItem($cacheKey)->isHit()) {
507507
$this->assertPass('The pool successfully deleted the cache item.');
508508
} else {
509509
$this->assertFail('The pool failed to delete the cache item.');

0 commit comments

Comments
 (0)