Skip to content

Commit 52abd1b

Browse files
committed
Added Couchdb driver, yay !
1 parent 9b19e10 commit 52abd1b

File tree

9 files changed

+442
-12
lines changed

9 files changed

+442
-12
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ language: php
1515
services:
1616
- memcached
1717
- redis-server
18+
- couchdb
1819
before_script:
1920
- |
2021
if [[ $TRAVIS_PHP_VERSION = "hhv"* ]]; then

README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@ One Class uses for All Cache. You don't need to rewrite your code many times aga
1717
|--------------------|---------------------------|---------------------|
1818
| `Apc(u)` | `Cassandra` | `Devnull` |
1919
| `Cookie` | `CouchBase` | `Devfalse` |
20-
| `Files` | `Mongodb` | `Devtrue` |
21-
| `Leveldb` | `Predis` | `Memstatic` |
22-
| `Memcache(d)` | `Redis` | |
23-
| `Sqlite` | `Ssdb` | |
24-
| `Wincache` | `Zend Memory Cache` | |
25-
| `Xcache` | | |
20+
| `Files` | `Couchdb` | `Devtrue` |
21+
| `Leveldb` | `Mongodb` | `Memstatic` |
22+
| `Memcache(d)` | `Predis` | |
23+
| `Sqlite` | `Redis` | |
24+
| `Wincache` | `Ssdb` | |
25+
| `Xcache` | `Zend Memory Cache` | |
2626
| `Zend Disk Cache` | | |
2727

2828
\* Driver descriptions available in DOCS/DRIVERS.md

composer.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
22
"name": "phpfastcache/phpfastcache",
33
"type" : "library",
4-
"description": "PHP Cache Class - Reduce your database call using cache system. PhpFastCache handles a lot of drivers such as Apc(u), Cassandra, CouchBase, Mongodb, Files, (P)redis, Leveldb, Memcache(d), Ssdb, Sqlite, Wincache, Xcache, Zend Data Cache.",
5-
"keywords": ["cache","caching","php cache","mysql cache","apc","apcu","memcache","memcached","wincache","files cache","pdo cache","cache class","redis","predis","cookie", "mongodb", "cassandra", "couchbase", "LevelDb", "Ssdb", "Wincache", "xcache","zend","zend disk cache","zend memory cache","zend data cache","zend server"],
4+
"description": "PHP Cache Class - Reduce your database call using cache system. PhpFastCache handles a lot of drivers such as Apc(u), Cassandra, CouchBase, Couchdb, Mongodb, Files, (P)redis, Leveldb, Memcache(d), Ssdb, Sqlite, Wincache, Xcache, Zend Data Cache.",
5+
"keywords": ["cache","caching","php cache","mysql cache","apc","apcu","memcache","memcached","wincache","files cache","pdo cache","cache class","redis","predis","cookie", "mongodb", "cassandra", "couchdb", "couchbase", "LevelDb", "Ssdb", "Wincache", "xcache","zend","zend disk cache","zend memory cache","zend data cache","zend server"],
66
"homepage": "http://www.phpfastcache.com",
77
"license": "MIT",
88
"authors": [
@@ -27,7 +27,8 @@
2727
"phpfastcache/phpssdb": "~1.0.0",
2828
"mongodb/mongodb": "^1.1",
2929
"ext-mbstring": "*",
30-
"ext-json": "*"
30+
"ext-json": "*",
31+
"doctrine/couchdb": "@dev"
3132
},
3233
"suggest": {
3334
"ext-apc": "*",

composer.lock

Lines changed: 58 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/DRIVERS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
* A cookie driver to store non-sensitive scalar (only) data. Limited storage up to 4Ko.
1010
* Couchbase
1111
* A very high-performance NoSQL driver using a key-value pair system
12+
* Couchdb
13+
* A very high-performance NoSQL driver using a key-value pair system
1214
* Devfalse
1315
* A development driver that return false for everything except driverCheck()
1416
* Devnull

src/phpFastCache/CacheManager.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@
2424
*
2525
* @method static ExtendedCacheItemPoolInterface Apc() Apc($config = []) Return a driver "apc" instance
2626
* @method static ExtendedCacheItemPoolInterface Apcu() Apcu($config = []) Return a driver "apcu" instance
27+
* @method static ExtendedCacheItemPoolInterface Cassandra() Cassandra($config = []) Return a driver "Cassandra" instance
2728
* @method static ExtendedCacheItemPoolInterface Cookie() Cookie($config = []) Return a driver "cookie" instance
2829
* @method static ExtendedCacheItemPoolInterface Couchbase() Couchbase($config = []) Return a driver "couchbase" instance
30+
* @method static ExtendedCacheItemPoolInterface Couchdb() Couchdb($config = []) Return a driver "Couchdb" instance
2931
* @method static ExtendedCacheItemPoolInterface Files() Files($config = []) Return a driver "files" instance
3032
* @method static ExtendedCacheItemPoolInterface Leveldb() Leveldb($config = []) Return a driver "leveldb" instance
3133
* @method static ExtendedCacheItemPoolInterface Memcache() Memcache($config = []) Return a driver "memcache" instance
@@ -321,6 +323,7 @@ public static function getStaticSystemDrivers()
321323
'Apcu',
322324
'Cassandra',
323325
'Couchbase',
326+
'Couchdb',
324327
'Devnull',
325328
'Files',
326329
'Leveldb',
Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
<?php
2+
/**
3+
*
4+
* This file is part of phpFastCache.
5+
*
6+
* @license MIT License (MIT)
7+
*
8+
* For full copyright and license information, please see the docs/CREDITS.txt file.
9+
*
10+
* @author Khoa Bui (khoaofgod) <[email protected]> http://www.phpfastcache.com
11+
* @author Georges.L (Geolim4) <[email protected]>
12+
*
13+
*/
14+
15+
namespace phpFastCache\Drivers\Couchdb;
16+
17+
use Doctrine\CouchDB\CouchDBClient as CouchdbClient;
18+
use Doctrine\CouchDB\CouchDBException;
19+
use phpFastCache\Core\Pool\DriverBaseTrait;
20+
use phpFastCache\Core\Pool\ExtendedCacheItemPoolInterface;
21+
use phpFastCache\Entities\driverStatistic;
22+
use phpFastCache\Exceptions\phpFastCacheDriverCheckException;
23+
use phpFastCache\Exceptions\phpFastCacheDriverException;
24+
use phpFastCache\Exceptions\phpFastCacheInvalidArgumentException;
25+
use Psr\Cache\CacheItemInterface;
26+
27+
/**
28+
* Class Driver
29+
* @package phpFastCache\Drivers
30+
* @property CouchdbClient $instance Instance of driver service
31+
*/
32+
class Driver implements ExtendedCacheItemPoolInterface
33+
{
34+
use DriverBaseTrait;
35+
36+
/**
37+
* Driver constructor.
38+
* @param array $config
39+
* @throws phpFastCacheDriverException
40+
*/
41+
public function __construct(array $config = [])
42+
{
43+
$this->setup($config);
44+
45+
if (!$this->driverCheck()) {
46+
throw new phpFastCacheDriverCheckException(sprintf(self::DRIVER_CHECK_FAILURE, $this->getDriverName()));
47+
} else {
48+
$this->driverConnect();
49+
}
50+
}
51+
52+
/**
53+
* @return bool
54+
*/
55+
public function driverCheck()
56+
{
57+
return class_exists('Doctrine\CouchDB\CouchDBClient');
58+
}
59+
60+
/**
61+
* @param \Psr\Cache\CacheItemInterface $item
62+
* @return mixed
63+
* @throws phpFastCacheDriverException
64+
* @throws phpFastCacheInvalidArgumentException
65+
*/
66+
protected function driverWrite(CacheItemInterface $item)
67+
{
68+
/**
69+
* Check for Cross-Driver type confusion
70+
*/
71+
if ($item instanceof Item) {
72+
try{
73+
$this->instance->putDocument(['data' => $this->encode($this->driverPreWrap($item))], $item->getEncodedKey(), $this->getLatestDocumentRevision($item->getEncodedKey()));
74+
}catch (CouchDBException $e){
75+
throw new phpFastCacheDriverException('Got error while trying to upsert a document: ' . $e->getMessage(), null, $e);
76+
}
77+
return true;
78+
} else {
79+
throw new phpFastCacheInvalidArgumentException('Cross-Driver type confusion detected');
80+
}
81+
}
82+
83+
/**
84+
* @param \Psr\Cache\CacheItemInterface $item
85+
* @return mixed
86+
* @throws phpFastCacheDriverException
87+
*/
88+
protected function driverRead(CacheItemInterface $item)
89+
{
90+
try{
91+
$response = $this->instance->findDocument($item->getEncodedKey());
92+
}catch (CouchDBException $e){
93+
throw new phpFastCacheDriverException('Got error while trying to get a document: ' . $e->getMessage(), null, $e);
94+
}
95+
96+
if($response->status === 404 || empty($response->body['data'])){
97+
return null;
98+
}else if($response->status === 200){
99+
return $this->decode($response->body['data']);
100+
}else{
101+
throw new phpFastCacheDriverException('Got unexpected HTTP status: ' . $response->status);
102+
}
103+
}
104+
105+
/**
106+
* @param \Psr\Cache\CacheItemInterface $item
107+
* @return bool
108+
* @throws phpFastCacheDriverException
109+
* @throws phpFastCacheInvalidArgumentException
110+
*/
111+
protected function driverDelete(CacheItemInterface $item)
112+
{
113+
/**
114+
* Check for Cross-Driver type confusion
115+
*/
116+
if ($item instanceof Item) {
117+
try{
118+
$this->instance->deleteDocument($item->getEncodedKey(), $this->getLatestDocumentRevision($item->getEncodedKey()));
119+
}catch (CouchDBException $e){
120+
throw new phpFastCacheDriverException('Got error while trying to delete a document: ' . $e->getMessage(), null, $e);
121+
}
122+
return true;
123+
} else {
124+
throw new phpFastCacheInvalidArgumentException('Cross-Driver type confusion detected');
125+
}
126+
}
127+
128+
/**
129+
* @return bool
130+
* @throws phpFastCacheDriverException
131+
*/
132+
protected function driverClear()
133+
{
134+
try{
135+
$this->instance->deleteDatabase($this->getDatabaseName());
136+
$this->createDatabase();
137+
}catch (CouchDBException $e){
138+
throw new phpFastCacheDriverException('Got error while trying to delete and recreate the database: ' . $e->getMessage(), null, $e);
139+
}
140+
141+
142+
return true;
143+
}
144+
145+
/**
146+
* @return bool
147+
*/
148+
protected function driverConnect()
149+
{
150+
if ($this->instance instanceof CouchdbClient) {
151+
throw new \LogicException('Already connected to Couchdb server');
152+
} else {
153+
$host = isset($this->config[ 'host' ]) ? $this->config[ 'host' ] : '127.0.0.1';
154+
$ssl = isset($this->config[ 'ssl' ]) ? $this->config[ 'ssl' ] : false;
155+
$port = isset($this->config[ 'port' ]) ? $this->config[ 'port' ] : 5984;
156+
$path = isset($this->config[ 'path' ]) ? $this->config[ 'path' ] : '/';
157+
$username = isset($this->config[ 'username' ]) ? $this->config[ 'username' ] : '';
158+
$password = isset($this->config[ 'password' ]) ? $this->config[ 'password' ] : '';
159+
$timeout = isset($this->config[ 'timeout' ]) ? $this->config[ 'timeout' ] : 10;
160+
161+
$url = ($ssl ? 'https://' : 'http://');
162+
if($username)
163+
{
164+
$url .= "{$username}";
165+
if($password)
166+
{
167+
$url .= ":{$password}";
168+
}
169+
$url .= '@';
170+
}
171+
$url .= $host;
172+
$url .= ":{$port}";
173+
$url .= $path;
174+
175+
$this->instance = CouchDBClient::create([
176+
'dbname' => $this->getDatabaseName(),
177+
'url' => $url,
178+
'timeout' => $timeout
179+
]);
180+
181+
$this->createDatabase();
182+
}
183+
184+
return true;
185+
}
186+
187+
/**
188+
* @return string|null
189+
*/
190+
protected function getLatestDocumentRevision($docId)
191+
{
192+
$path = '/' . $this->getDatabaseName() . '/' . urlencode($docId);
193+
194+
$response = $this->instance->getHttpClient()->request(
195+
'GET',// At this moment HEAD requests are not working: https://github.com/doctrine/couchdb-client/issues/72
196+
$path,
197+
null,
198+
false
199+
);
200+
if(!empty($response->headers['etag'])){
201+
return trim($response->headers['etag'], " '\"\t\n\r\0\x0B");
202+
}else{
203+
return null;
204+
}
205+
}
206+
207+
/**
208+
* @return string
209+
*/
210+
protected function getDatabaseName()
211+
{
212+
return isset($this->config[ 'database' ]) ? $this->config[ 'database' ] : 'phpfastcache';
213+
}
214+
215+
/**
216+
* @return void
217+
*/
218+
protected function createDatabase()
219+
{
220+
if(!in_array($this->instance->getDatabase(), $this->instance->getAllDatabases(), true)){
221+
$this->instance->createDatabase($this->instance->getDatabase());
222+
}
223+
}
224+
225+
/********************
226+
*
227+
* PSR-6 Extended Methods
228+
*
229+
*******************/
230+
231+
/**
232+
* @return driverStatistic
233+
*/
234+
public function getStats()
235+
{
236+
$info = $this->instance->getDatabaseInfo();
237+
238+
return (new driverStatistic())
239+
->setSize($info['sizes']['active'])
240+
->setRawData($info)
241+
->setData(implode(', ', array_keys($this->itemInstances)))
242+
->setInfo('Couchdb version ' . $this->instance->getVersion() . "\n For more information see RawData.");
243+
}
244+
}

0 commit comments

Comments
 (0)