diff --git a/.gitignore b/.gitignore index 6fd6e40..034529a 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,5 @@ vendor tests/unit/coverage/ tests/unit/fixtures/* !tests/unit/fixtures/.gitkeep +tests/unit/.phpunit.cache +tests/unit/.phpunit.result.cache \ No newline at end of file diff --git a/composer.json b/composer.json index bb626f4..12e5ded 100644 --- a/composer.json +++ b/composer.json @@ -26,11 +26,18 @@ "psr-0": {"G4\\Mcache\\": "src/"} }, "require-dev": { - "phpunit/phpunit": "5.7.*" + "phpunit/phpunit": "10.*" }, "require": { - "php" : ">=5.6", + "php" : ">=8.2", "g4/profiler" : ">=1.10.0", - "g4/value-object" : "*" + "g4/value-object" : "*", + "couchbase/couchbase": "*" + }, + "suggest": { + "ext-couchbase": "^4.0" + }, + "scripts": { + "unit-test": "./vendor/bin/phpunit --configuration tests/unit/phpunit.xml" } } diff --git a/playground/couchbase4.php b/playground/couchbase4.php new file mode 100644 index 0000000..e7b8f77 --- /dev/null +++ b/playground/couchbase4.php @@ -0,0 +1,34 @@ +credentials("Administrator", "password"); +$cluster = new Cluster($connectionString, $options); + +// get a bucket reference +$bucket = $cluster->bucket("travel-sample"); + +// get a user-defined collection reference +$scope = $bucket->scope("tenant_agent_00"); +$collection = $scope->collection("users"); + +$upsertResult = $collection->upsert("my-document-key", ["name" => "Ted", "Age" => 31]); + +$getResult = $collection->get("my-document-key"); + +print_r($getResult->content()); + +$queryResult = $cluster->query("select \"Hello World\" as greeting"); + +// Iterate over the rows to access result data and print to the terminal. +foreach ($queryResult->rows() as $row) { + printf("%s\n", $row["greeting"]); +} diff --git a/src/G4/Mcache/Driver/Couchbase.php b/src/G4/Mcache/Driver/Couchbase.php index 9164657..53da1de 100644 --- a/src/G4/Mcache/Driver/Couchbase.php +++ b/src/G4/Mcache/Driver/Couchbase.php @@ -4,12 +4,13 @@ use G4\Mcache\Driver\Couchbase\Couchbase1x; use G4\Mcache\Driver\Couchbase\Couchbase2x; +use G4\Mcache\Driver\Couchbase\Couchbase4x; use G4\Mcache\Driver\Couchbase\CouchbaseInterface; class Couchbase extends DriverAbstract { - const DEFAULT_TIMEOUT_VALUE = 2500000; // time in microseconds + private const DEFAULT_TIMEOUT_VALUE = 500000; // time in microseconds /** * @var array @@ -26,10 +27,19 @@ class Couchbase extends DriverAbstract */ private $user; + /** + * @var string + */ private $pass; + /** + * @var bool + */ private $persistent; + /** + * @var int + */ private $timeout; /** @@ -58,10 +68,10 @@ private function processOptions() $this->servers[] = $server; } $this->bucket = $options['bucket']; - $this->user = isset($options['user']) ? $options['user'] : ''; - $this->pass = isset($options['pass']) ? $options['pass'] : ''; - $this->persistent = isset($options['persistent']) ? (bool) $options['persistent'] : false; - $this->timeout = isset($options['timeout']) ? (int) $options['timeout'] : self::DEFAULT_TIMEOUT_VALUE; + $this->user = $options['user'] ?? ''; + $this->pass = $options['pass'] ?? ''; + $this->persistent = isset($options['persistent']) && (bool)$options['persistent']; + $this->timeout = isset($options['timeout']) ? (int) $options['timeout'] : self::DEFAULT_TIMEOUT_VALUE; return $this; } @@ -103,7 +113,9 @@ private function connect() $this->persistent, $this->timeout ); - } else if (class_exists('\CouchbaseCluster')) { + return $this->driver; + } + if (class_exists('\CouchbaseCluster')) { $this->driver = new Couchbase2x( $this->servers, $this->user, @@ -112,9 +124,21 @@ private function connect() $this->persistent, $this->timeout ); - } else { - throw new \Exception('Couchbase client missing!', 601); + return $this->driver; } - return $this->driver; + + if (class_exists('\Couchbase\Cluster')) { + $this->driver = new Couchbase4x( + $this->servers, + $this->user, + $this->pass, + $this->bucket, + $this->persistent, + $this->timeout + ); + return $this->driver; + } + + throw new \Exception('Couchbase client missing!', 601); } -} \ No newline at end of file +} diff --git a/src/G4/Mcache/Driver/Couchbase/Couchbase4x.php b/src/G4/Mcache/Driver/Couchbase/Couchbase4x.php new file mode 100644 index 0000000..4014fa2 --- /dev/null +++ b/src/G4/Mcache/Driver/Couchbase/Couchbase4x.php @@ -0,0 +1,108 @@ +clientCluster = null; + $this->clientBucket = null; + $this->timeout = $timeout ?? self::DEFAULT_CONNECT_TIMEOUT; + } + + public function delete($key) + { + if (!$this->clientFactory()) { + return false; + } + try { + $mutationResult = $this->clientFactory()->defaultCollection()->remove($key); + return $mutationResult->cas(); + } catch (\Exception $e) { + return false; + } + } + + public function get($key) + { + if (!$this->clientFactory()) { + return false; + } + try { + return $this->clientFactory()->defaultCollection()->get($key)->content(); + } catch (\Exception $e) { + return false; + } + } + + public function replace($key, $value, $expiration) + { + if (!$this->clientFactory()) { + return false; + } + $replaceOptions = (new ReplaceOptions()) + ->expiry($expiration); + try { + $mutationResult = $this->clientFactory()->defaultCollection()->replace($key, $value, $replaceOptions); + return $mutationResult->cas(); + } catch (\Exception $e) { + return false; + } + } + + public function set($key, $value, $expiration) + { + if (!$this->clientFactory()) { + return false; + } + $upsertOptions = (new UpsertOptions()) + ->expiry($expiration); + try { + $mutationResult = $this->clientFactory()->defaultCollection()->upsert($key, $value, $upsertOptions); + return $mutationResult->cas(); + } catch (\Exception $e) { + return false; + } + } + + private function clientFactory() + { + if ($this->clientBucket instanceof \Couchbase\Bucket) { + return $this->clientBucket; + } + + $this->connect(); + return $this->clientBucket; + } + + private function connect() + { + $connectionString = 'couchbase://' . implode(',', $this->servers); + $options = new ClusterOptions(); + $options->connectTimeout($this->timeout); + $options->credentials($this->user, $this->pass); + try { + $this->clientCluster = new Cluster($connectionString, $options); + $this->clientBucket = $this->clientCluster->bucket($this->bucket); + } catch (\Exception $e) { + $message = sprintf('Could not connect to couchbase cluster %s, bucket %s, message: %s', $connectionString, $this->bucket, $e->getMessage()); + trigger_error($message, E_USER_WARNING); + } + } +} diff --git a/src/G4/Mcache/FileCache.php b/src/G4/Mcache/FileCache.php index 3766f9f..8f7b440 100644 --- a/src/G4/Mcache/FileCache.php +++ b/src/G4/Mcache/FileCache.php @@ -123,7 +123,11 @@ public function set($data) private function getFromCache() { - return json_decode($this->mcache->get(), true); + $value = $this->mcache->get(); + if (!$value) { + return null; + } + return json_decode($value, true); } private function setToCache() diff --git a/tests/unit/phpunit.xml b/tests/unit/phpunit.xml index 00aa2d9..4c41f3a 100644 --- a/tests/unit/phpunit.xml +++ b/tests/unit/phpunit.xml @@ -1,13 +1,16 @@ - - - - ./src - - - - - ../../src/ - - - - \ No newline at end of file + + + + ./src + + + + ../../src/ + + + diff --git a/tests/unit/src/G4/Mcache/Driver/FileTest.php b/tests/unit/src/G4/Mcache/Driver/FileTest.php index 3e60023..ca84752 100644 --- a/tests/unit/src/G4/Mcache/Driver/FileTest.php +++ b/tests/unit/src/G4/Mcache/Driver/FileTest.php @@ -2,11 +2,11 @@ use G4\Mcache\Driver\File; -class FileTest extends PHPUnit_Framework_TestCase +class FileTest extends \PHPUnit\Framework\TestCase { public function testInstance() { - + $this->markTestSkipped('Skipping testInstance'); } } \ No newline at end of file diff --git a/tests/unit/src/G4/Mcache/Driver/LibmemcachedTest.php b/tests/unit/src/G4/Mcache/Driver/LibmemcachedTest.php index 389fc51..d99657a 100644 --- a/tests/unit/src/G4/Mcache/Driver/LibmemcachedTest.php +++ b/tests/unit/src/G4/Mcache/Driver/LibmemcachedTest.php @@ -2,27 +2,23 @@ use G4\Mcache\Mcache; -class LibmemcachedTest extends \PHPUnit_Framework_TestCase +class LibmemcachedTest extends \PHPUnit\Framework\TestCase { - private $_driver; + private $driver; - public function setUp() + public function setUp(): void { - $this->_driver = new \G4\Mcache\Driver\Libmemcached(); - - parent::setUp(); + $this->driver = new \G4\Mcache\Driver\Libmemcached(); } - public function tearDown() + public function tearDown(): void { unset( - $this->_driver + $this->driver ); - - parent::tearDown(); } public function testGet() diff --git a/tests/unit/src/G4/Mcache/FileCacheTest.php b/tests/unit/src/G4/Mcache/FileCacheTest.php index 31b12e1..da62b27 100644 --- a/tests/unit/src/G4/Mcache/FileCacheTest.php +++ b/tests/unit/src/G4/Mcache/FileCacheTest.php @@ -4,19 +4,19 @@ use G4\ValueObject\StringLiteral; use G4\ValueObject\Pathname; -class FileCacheTest extends \PHPUnit_Framework_TestCase +class FileCacheTest extends \PHPUnit\Framework\TestCase { private $pathname; private $key; - protected function setUp() + protected function setUp(): void { $this->pathname = new Pathname(''); $this->key = new StringLiteral('KEY'); } - protected function tearDown() + protected function tearDown(): void { $this->pathname = null; $this->key = null; diff --git a/tests/unit/src/G4/Mcache/McacheFIleTest.php b/tests/unit/src/G4/Mcache/McacheFIleTest.php index 4c86768..68dbde7 100644 --- a/tests/unit/src/G4/Mcache/McacheFIleTest.php +++ b/tests/unit/src/G4/Mcache/McacheFIleTest.php @@ -6,7 +6,7 @@ use G4\Mcache\McacheFactory; //TODO: Drasko - move to functional tests ! -class McacheFIleTest extends \PHPUnit_Framework_TestCase +class McacheFIleTest extends \PHPUnit\Framework\TestCase { /** @@ -18,7 +18,7 @@ class McacheFIleTest extends \PHPUnit_Framework_TestCase private $data; - protected function setUp() + protected function setUp(): void { $driverName = 'File'; $options = [ @@ -33,7 +33,7 @@ protected function setUp() ]; } - protected function tearDown() + protected function tearDown(): void { $this->mcache = null; $this->key = null; diff --git a/tests/unit/src/G4/Mcache/McacheTest.php b/tests/unit/src/G4/Mcache/McacheTest.php index 5420cb7..4190c1f 100644 --- a/tests/unit/src/G4/Mcache/McacheTest.php +++ b/tests/unit/src/G4/Mcache/McacheTest.php @@ -2,7 +2,7 @@ use G4\Mcache\Mcache; -class McacheTest extends \PHPUnit_Framework_TestCase +class McacheTest extends \PHPUnit\Framework\TestCase { private $_driverStub; @@ -10,23 +10,19 @@ class McacheTest extends \PHPUnit_Framework_TestCase private $_mcache; - public function setUp() + public function setUp(): void { $this->_driverStub = $this->createMock(\G4\Mcache\Driver\Libmemcached::class); $this->_mcache = new \G4\Mcache\Mcache($this->_driverStub); - - parent::setUp(); } - public function tearDown() + public function tearDown(): void { unset( $this->_driverStub, $this->_mcache ); - - parent::tearDown(); }