Skip to content

Commit 05a1ed4

Browse files
authored
Merge pull request #9 from ppavlovic/master
Added support for Couchbase V4 API and PHP 8.3
2 parents d17b248 + 54cf9d1 commit 05a1ed4

12 files changed

Lines changed: 226 additions & 52 deletions

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,5 @@ vendor
2020
tests/unit/coverage/
2121
tests/unit/fixtures/*
2222
!tests/unit/fixtures/.gitkeep
23+
tests/unit/.phpunit.cache
24+
tests/unit/.phpunit.result.cache

composer.json

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,18 @@
2626
"psr-0": {"G4\\Mcache\\": "src/"}
2727
},
2828
"require-dev": {
29-
"phpunit/phpunit": "5.7.*"
29+
"phpunit/phpunit": "10.*"
3030
},
3131
"require": {
32-
"php" : ">=5.6",
32+
"php" : ">=8.2",
3333
"g4/profiler" : ">=1.10.0",
34-
"g4/value-object" : "*"
34+
"g4/value-object" : "*",
35+
"couchbase/couchbase": "*"
36+
},
37+
"suggest": {
38+
"ext-couchbase": "^4.0"
39+
},
40+
"scripts": {
41+
"unit-test": "./vendor/bin/phpunit --configuration tests/unit/phpunit.xml"
3542
}
3643
}

playground/couchbase4.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
// NOTE: Change the below vendor path to your own.
4+
require_once __DIR__ . '/../vendor/autoload.php';
5+
6+
use Couchbase\ClusterOptions;
7+
use Couchbase\Cluster;
8+
9+
// Update these credentials for your Local instance!
10+
$connectionString = "couchbase://localhost";
11+
$options = new ClusterOptions();
12+
13+
$options->credentials("Administrator", "password");
14+
$cluster = new Cluster($connectionString, $options);
15+
16+
// get a bucket reference
17+
$bucket = $cluster->bucket("travel-sample");
18+
19+
// get a user-defined collection reference
20+
$scope = $bucket->scope("tenant_agent_00");
21+
$collection = $scope->collection("users");
22+
23+
$upsertResult = $collection->upsert("my-document-key", ["name" => "Ted", "Age" => 31]);
24+
25+
$getResult = $collection->get("my-document-key");
26+
27+
print_r($getResult->content());
28+
29+
$queryResult = $cluster->query("select \"Hello World\" as greeting");
30+
31+
// Iterate over the rows to access result data and print to the terminal.
32+
foreach ($queryResult->rows() as $row) {
33+
printf("%s\n", $row["greeting"]);
34+
}

src/G4/Mcache/Driver/Couchbase.php

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@
44

55
use G4\Mcache\Driver\Couchbase\Couchbase1x;
66
use G4\Mcache\Driver\Couchbase\Couchbase2x;
7+
use G4\Mcache\Driver\Couchbase\Couchbase4x;
78
use G4\Mcache\Driver\Couchbase\CouchbaseInterface;
89

910
class Couchbase extends DriverAbstract
1011
{
1112

12-
const DEFAULT_TIMEOUT_VALUE = 2500000; // time in microseconds
13+
private const DEFAULT_TIMEOUT_VALUE = 500000; // time in microseconds
1314

1415
/**
1516
* @var array
@@ -26,10 +27,19 @@ class Couchbase extends DriverAbstract
2627
*/
2728
private $user;
2829

30+
/**
31+
* @var string
32+
*/
2933
private $pass;
3034

35+
/**
36+
* @var bool
37+
*/
3138
private $persistent;
3239

40+
/**
41+
* @var int
42+
*/
3343
private $timeout;
3444

3545
/**
@@ -58,10 +68,10 @@ private function processOptions()
5868
$this->servers[] = $server;
5969
}
6070
$this->bucket = $options['bucket'];
61-
$this->user = isset($options['user']) ? $options['user'] : '';
62-
$this->pass = isset($options['pass']) ? $options['pass'] : '';
63-
$this->persistent = isset($options['persistent']) ? (bool) $options['persistent'] : false;
64-
$this->timeout = isset($options['timeout']) ? (int) $options['timeout'] : self::DEFAULT_TIMEOUT_VALUE;
71+
$this->user = $options['user'] ?? '';
72+
$this->pass = $options['pass'] ?? '';
73+
$this->persistent = isset($options['persistent']) && (bool)$options['persistent'];
74+
$this->timeout = isset($options['timeout']) ? (int) $options['timeout'] : self::DEFAULT_TIMEOUT_VALUE;
6575

6676
return $this;
6777
}
@@ -103,7 +113,9 @@ private function connect()
103113
$this->persistent,
104114
$this->timeout
105115
);
106-
} else if (class_exists('\CouchbaseCluster')) {
116+
return $this->driver;
117+
}
118+
if (class_exists('\CouchbaseCluster')) {
107119
$this->driver = new Couchbase2x(
108120
$this->servers,
109121
$this->user,
@@ -112,9 +124,21 @@ private function connect()
112124
$this->persistent,
113125
$this->timeout
114126
);
115-
} else {
116-
throw new \Exception('Couchbase client missing!', 601);
127+
return $this->driver;
117128
}
118-
return $this->driver;
129+
130+
if (class_exists('\Couchbase\Cluster')) {
131+
$this->driver = new Couchbase4x(
132+
$this->servers,
133+
$this->user,
134+
$this->pass,
135+
$this->bucket,
136+
$this->persistent,
137+
$this->timeout
138+
);
139+
return $this->driver;
140+
}
141+
142+
throw new \Exception('Couchbase client missing!', 601);
119143
}
120-
}
144+
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
<?php
2+
3+
namespace G4\Mcache\Driver\Couchbase;
4+
5+
use Couchbase\ClusterOptions;
6+
use Couchbase\Cluster;
7+
use Couchbase\UpsertOptions;
8+
use Couchbase\ReplaceOptions;
9+
10+
class Couchbase4x implements CouchbaseInterface
11+
{
12+
private const DEFAULT_CONNECT_TIMEOUT = 500000;
13+
private ?\Couchbase\Cluster $clientCluster;
14+
private ?\Couchbase\Bucket $clientBucket;
15+
16+
public function __construct(
17+
private readonly array $servers,
18+
private readonly string $user,
19+
private readonly string $pass,
20+
private readonly string $bucket,
21+
private readonly bool $persistent,
22+
private int $timeout
23+
) {
24+
$this->clientCluster = null;
25+
$this->clientBucket = null;
26+
$this->timeout = $timeout ?? self::DEFAULT_CONNECT_TIMEOUT;
27+
}
28+
29+
public function delete($key)
30+
{
31+
if (!$this->clientFactory()) {
32+
return false;
33+
}
34+
try {
35+
$mutationResult = $this->clientFactory()->defaultCollection()->remove($key);
36+
return $mutationResult->cas();
37+
} catch (\Exception $e) {
38+
return false;
39+
}
40+
}
41+
42+
public function get($key)
43+
{
44+
if (!$this->clientFactory()) {
45+
return false;
46+
}
47+
try {
48+
return $this->clientFactory()->defaultCollection()->get($key)->content();
49+
} catch (\Exception $e) {
50+
return false;
51+
}
52+
}
53+
54+
public function replace($key, $value, $expiration)
55+
{
56+
if (!$this->clientFactory()) {
57+
return false;
58+
}
59+
$replaceOptions = (new ReplaceOptions())
60+
->expiry($expiration);
61+
try {
62+
$mutationResult = $this->clientFactory()->defaultCollection()->replace($key, $value, $replaceOptions);
63+
return $mutationResult->cas();
64+
} catch (\Exception $e) {
65+
return false;
66+
}
67+
}
68+
69+
public function set($key, $value, $expiration)
70+
{
71+
if (!$this->clientFactory()) {
72+
return false;
73+
}
74+
$upsertOptions = (new UpsertOptions())
75+
->expiry($expiration);
76+
try {
77+
$mutationResult = $this->clientFactory()->defaultCollection()->upsert($key, $value, $upsertOptions);
78+
return $mutationResult->cas();
79+
} catch (\Exception $e) {
80+
return false;
81+
}
82+
}
83+
84+
private function clientFactory()
85+
{
86+
if ($this->clientBucket instanceof \Couchbase\Bucket) {
87+
return $this->clientBucket;
88+
}
89+
90+
$this->connect();
91+
return $this->clientBucket;
92+
}
93+
94+
private function connect()
95+
{
96+
$connectionString = 'couchbase://' . implode(',', $this->servers);
97+
$options = new ClusterOptions();
98+
$options->connectTimeout($this->timeout);
99+
$options->credentials($this->user, $this->pass);
100+
try {
101+
$this->clientCluster = new Cluster($connectionString, $options);
102+
$this->clientBucket = $this->clientCluster->bucket($this->bucket);
103+
} catch (\Exception $e) {
104+
$message = sprintf('Could not connect to couchbase cluster %s, bucket %s, message: %s', $connectionString, $this->bucket, $e->getMessage());
105+
trigger_error($message, E_USER_WARNING);
106+
}
107+
}
108+
}

src/G4/Mcache/FileCache.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,11 @@ public function set($data)
123123

124124
private function getFromCache()
125125
{
126-
return json_decode($this->mcache->get(), true);
126+
$value = $this->mcache->get();
127+
if (!$value) {
128+
return null;
129+
}
130+
return json_decode($value, true);
127131
}
128132

129133
private function setToCache()

tests/unit/phpunit.xml

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
1-
<phpunit bootstrap="bootstrap.php" colors="true">
2-
3-
<testsuite name="Test Suite">
4-
<directory>./src</directory>
5-
</testsuite>
6-
7-
<filter>
8-
<whitelist>
9-
<directory suffix=".php">../../src/</directory>
10-
</whitelist>
11-
</filter>
12-
13-
</phpunit>
1+
<?xml version="1.0"?>
2+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" bootstrap="bootstrap.php" colors="true" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd" cacheDirectory=".phpunit.cache"
3+
displayDetailsOnTestsThatTriggerDeprecations="true"
4+
displayDetailsOnTestsThatTriggerErrors="true"
5+
displayDetailsOnTestsThatTriggerNotices="true"
6+
displayDetailsOnTestsThatTriggerWarnings="true"
7+
>
8+
<testsuite name="Test Suite">
9+
<directory>./src</directory>
10+
</testsuite>
11+
<source>
12+
<include>
13+
<directory suffix=".php">../../src/</directory>
14+
</include>
15+
</source>
16+
</phpunit>

tests/unit/src/G4/Mcache/Driver/FileTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
use G4\Mcache\Driver\File;
44

5-
class FileTest extends PHPUnit_Framework_TestCase
5+
class FileTest extends \PHPUnit\Framework\TestCase
66
{
77

88
public function testInstance()
99
{
10-
10+
$this->markTestSkipped('Skipping testInstance');
1111
}
1212
}

tests/unit/src/G4/Mcache/Driver/LibmemcachedTest.php

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,23 @@
22

33
use G4\Mcache\Mcache;
44

5-
class LibmemcachedTest extends \PHPUnit_Framework_TestCase
5+
class LibmemcachedTest extends \PHPUnit\Framework\TestCase
66
{
77

8-
private $_driver;
8+
private $driver;
99

1010

11-
public function setUp()
11+
public function setUp(): void
1212
{
13-
$this->_driver = new \G4\Mcache\Driver\Libmemcached();
14-
15-
parent::setUp();
13+
$this->driver = new \G4\Mcache\Driver\Libmemcached();
1614
}
1715

1816

19-
public function tearDown()
17+
public function tearDown(): void
2018
{
2119
unset(
22-
$this->_driver
20+
$this->driver
2321
);
24-
25-
parent::tearDown();
2622
}
2723

2824
public function testGet()

tests/unit/src/G4/Mcache/FileCacheTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,19 @@
44
use G4\ValueObject\StringLiteral;
55
use G4\ValueObject\Pathname;
66

7-
class FileCacheTest extends \PHPUnit_Framework_TestCase
7+
class FileCacheTest extends \PHPUnit\Framework\TestCase
88
{
99

1010
private $pathname;
1111
private $key;
1212

13-
protected function setUp()
13+
protected function setUp(): void
1414
{
1515
$this->pathname = new Pathname('');
1616
$this->key = new StringLiteral('KEY');
1717
}
1818

19-
protected function tearDown()
19+
protected function tearDown(): void
2020
{
2121
$this->pathname = null;
2222
$this->key = null;

0 commit comments

Comments
 (0)