4 Commits

Author SHA1 Message Date
EmanueleMinotto
2117eef3e3 Implement cassandra range query 2019-09-04 22:17:30 +02:00
EmanueleMinotto
ff58187a3b Upgrade doctrine/couchdb to include range query 2019-09-04 22:17:04 +02:00
EmanueleMinotto
e878a42d81 Add drivers to Travis 2019-09-04 22:16:08 +02:00
EmanueleMinotto
55f0840706 Use array as operation result 2019-09-04 22:15:56 +02:00
15 changed files with 458 additions and 310 deletions

View File

@@ -1,9 +1,17 @@
language: php
services:
- cassandra
- couchdb
- mongodb
- redis-server
matrix:
include:
-
dist: precise
php: 5.5
php:
- 5.6
- 7.0
@@ -11,24 +19,7 @@ php:
- 7.2
- 7.3
addons:
apt:
sources:
-
key_url: 'https://packagecloud.io/gpg.key'
sourceline: 'deb https://packagecloud.io/basho/riak/ubuntu/ trusty main'
-
key_url: 'https://packagecloud.io/gpg.key'
sourceline: 'deb-src https://packagecloud.io/basho/riak/ubuntu/ trusty main'
update: true
cache:
apt: true
before_install:
- sudo apt-get install -y --allow-unauthenticated riak
- sudo service riak start
- pecl install --force mongodb
- if [[ ${TRAVIS_PHP_VERSION:0:1} != "7" ]]; then sh ./tests/travis.sh; fi
- composer self-update

View File

@@ -1,7 +0,0 @@
# Upgrade to 0.3
## BC Break: Fixed MongoDB storage usage
Before v0.3 the storage name associated to a class wasn't used when the storage is `MongoDbStorage`.
In order to be consistent with other storage drivers, the `storageName` is now used for the collection name when storing and data.
To get the same behavior as in older versions, pass the collection name given in the constructor arguments as storage name.

View File

@@ -6,16 +6,16 @@
},
"require-dev": {
"datastax/php-driver": "^1.0",
"doctrine/couchdb": "^1.0.0-beta4",
"doctrine/couchdb": "^2.0@alpha",
"phpunit/phpunit": "^4.8|^5.0",
"aws/aws-sdk-php": "^3.8",
"php-riak/riak-client": "^1.0@alpha",
"mongodb/mongodb": "^1.4"
"riak/riak-client": "dev-master"
},
"suggest": {
"aws/aws-sdk-php": "to use the DynamoDB storage",
"doctrine/couchdb": "to use the CouchDB storage",
"ext-couchbase": "to use the Couchbase storage"
"ext-couchbase": "to use the Couchbase storage",
"riak/riak-client": "to use the Riak storage"
},
"description": "Simple Key-Value Store Abstraction Layer that maps to PHP objects, allowing for many backends.",
"license": "MIT",

View File

@@ -8,7 +8,7 @@ This guide covers getting started with the Doctrine Key Value Store.
To use the KeyValueStore you actually need:
- PHP 5.6 or above
- PHP 5.5 or above
- Composer Package Manager (`Install Composer
<http://getcomposer.org/doc/00-intro.md>`_)

View File

@@ -224,35 +224,36 @@ See the `AWS docs <http://docs.aws.amazon.com/amazondynamodb/latest/developergui
MongoDB
-------
MongoDB is based on `mongodb/mongodb <https://github.com/mongodb/mongo-php-library>`_:
MongoDB support is provided using a `Database <https://docs.mongodb.com/php-library/current/reference/class/MongoDBDatabase/>`_
instance.
Mongo support is provided using a `Mongo <http://php.net/manual/en/class.mongo.php>`_
instance, the collection name and the database name.
Both the options ``collection`` and ``database`` are required.
.. code-block:: php
<?php
use MongoDB\Client;
use Doctrine\KeyValueStore\Storage\MongoDbStorage;
$client = new Client(/* connection parameters and options */);
$conn = new \Mongo(/* connection parameters and options */);
$storage = new MongoDbStorage($client->your_database);
$storage = new MongoDbStorage($conn, array(
'collection' => 'your_collection',
'database' => 'your_database',
));
Riak
----
Riak support is provided through the library `php-riak/riak-client <https://github.com/php-riak/riak-client>`_ :
Riak support is provided through the library `riak/riak-client <https://github.com/nacmartin/riak-client>`_ :
.. code-block:: php
<?php
use Doctrine\KeyValueStore\Storage\RiakStorage;
use Riak\Client\RiakClientBuilder;
use Riak\Client;
$conn = (new RiakClientBuilder())
->withNodeUri(/* connection DNS */)
->build();
$conn = new Riak(/* connection parameters */);
$storage = new RiakStorage($conn);

View File

@@ -202,7 +202,7 @@ class RangeQuery
/**
* Execute query and return a result iterator.
*
* @return ResultIterator
* @return array
*/
public function execute()
{

View File

@@ -29,14 +29,14 @@ namespace Doctrine\KeyValueStore\Query;
interface RangeQueryStorage
{
/**
* Execute the range query and return a ResultIterator
* Execute the range query and return an array
*
* @param RangeQuery $query
* @param string $storageName
* @param array $key
* @param Closure $hydrateRow
*
* @return ResultIterator
* @return array
*/
public function executeRangeQuery(RangeQuery $query, $storageName, $key, \Closure $hydrateRow = null);
}

View File

@@ -23,6 +23,8 @@ namespace Doctrine\KeyValueStore\Storage;
use Cassandra\ExecutionOptions;
use Cassandra\Session;
use Doctrine\KeyValueStore\NotFoundException;
use Doctrine\KeyValueStore\Query\RangeQuery;
use Doctrine\KeyValueStore\Query\RangeQueryStorage;
/**
* Cassandra Storage Engine for KeyValueStore.
@@ -31,7 +33,7 @@ use Doctrine\KeyValueStore\NotFoundException;
*
* @uses https://github.com/datastax/php-driver
*/
class CassandraStorage implements Storage
class CassandraStorage implements Storage, RangeQueryStorage
{
/**
* @var \Cassandra\Session
@@ -176,6 +178,13 @@ class CassandraStorage implements Storage
return $data;
}
/**
* {@inheritDoc}
*/
public function executeRangeQuery(RangeQuery $query, $storageName, $key, \Closure $hydrateRow = null)
{
}
/**
* {@inheritDoc}
*/

View File

@@ -21,6 +21,9 @@
namespace Doctrine\KeyValueStore\Storage;
use Doctrine\CouchDB\CouchDBClient;
use Doctrine\CouchDB\Mango\MangoQuery;
use Doctrine\KeyValueStore\Query\RangeQuery;
use Doctrine\KeyValueStore\Query\RangeQueryStorage;
/**
* Key-Value-Storage using a Doctrine CouchDB Client library as backend.
@@ -30,7 +33,7 @@ use Doctrine\CouchDB\CouchDBClient;
*
* @author Emanuele Minotto <minottoemanuele@gmail.com>
*/
final class CouchDbStorage implements Storage
final class CouchDbStorage implements Storage, RangeQueryStorage
{
/**
* @var CouchDBClient
@@ -116,7 +119,7 @@ final class CouchDbStorage implements Storage
/**
* @param string $storageName
* @param array|string $key
*
*
* @return string
*/
private function flattenKey($storageName, $key)
@@ -137,4 +140,72 @@ final class CouchDbStorage implements Storage
return $finalKey;
}
/**
* {@inheritDoc}
*/
public function executeRangeQuery(RangeQuery $query, $storageName, $key, \Closure $hydrateRow = null)
{
$mangoQuery = new MangoQuery();
$partitionKey = $query->getPartitionKey();
$conditions = [];
foreach ($query->getConditions() as $condition) {
switch ($condition[0]) {
case RangeQuery::CONDITION_LE:
$conditions[] = [
$partitionKey => [
'$lte' => $condition[1],
],
];
break;
case RangeQuery::CONDITION_GE:
$conditions[] = [
$partitionKey => [
'$gte' => $condition[1],
],
];
break;
case RangeQuery::CONDITION_NEQ:
$conditions[] = [
$partitionKey => [
'$ne' => $condition[1],
],
];
break;
case RangeQuery::CONDITION_STARTSWITH:
$conditions[] = [
$partitionKey => [
'$regex' => '^'.$condition[1],
],
];
break;
default:
$conditions[] = [
$partitionKey => [
'$'.$condition[0] => $condition[1],
],
];
break;
}
}
$mangoQuery
->select(['_id', $key])
->where(['$and' => $conditions])
->limit($query->getLimit());
$results = [];
$mangoResults = $this->client->find($query);
foreach ($mangoResults as $mangoResult) {
$results[] = $hydrateRow($mangoResult);
}
return $results;
}
}

View File

@@ -21,7 +21,6 @@
namespace Doctrine\KeyValueStore\Storage;
use Doctrine\KeyValueStore\NotFoundException;
use MongoDB\Database;
/**
* MongoDb storage
@@ -31,16 +30,57 @@ use MongoDB\Database;
class MongoDbStorage implements Storage
{
/**
* @var Database
* @var \Mongo
*/
private $database;
protected $mongo;
/**
* @param Database $database
* @var array
*/
public function __construct(Database $database)
protected $dbOptions;
/**
* @var \MongoCollection
*/
protected $collection;
/**
* Constructor
*
* @param \Mongo $mongo
* @param array $dbOptions
*/
public function __construct(\Mongo $mongo, array $dbOptions = [])
{
$this->database = $database;
$this->mongo = $mongo;
$this->dbOptions = array_merge([
'database' => '',
'collection' => '',
], $dbOptions);
}
/**
* Initialize the mongodb collection
*
* @throws \RuntimeException
*/
public function initialize()
{
if (null !== $this->collection) {
return;
}
if (empty($this->dbOptions['database'])) {
throw new \RuntimeException('The option "database" must be set');
}
if (empty($this->dbOptions['collection'])) {
throw new \RuntimeException('The option "collection" must be set');
}
$this->collection = $this
->mongo
->selectDB($this->dbOptions['database'])
->selectCollection($this->dbOptions['collection']);
}
/**
@@ -72,12 +112,14 @@ class MongoDbStorage implements Storage
*/
public function insert($storageName, $key, array $data)
{
$this->database
->selectCollection($storageName)
->insertOne([
'key' => $key,
'value' => $data,
]);
$this->initialize();
$value = [
'key' => $key,
'value' => $data,
];
$this->collection->insert($value);
}
/**
@@ -85,14 +127,14 @@ class MongoDbStorage implements Storage
*/
public function update($storageName, $key, array $data)
{
$this->database
->selectCollection($storageName)
->replaceOne([
'key' => $key,
], [
'key' => $key,
'value' => $data,
]);
$this->initialize();
$value = [
'key' => $key,
'value' => $data,
];
$this->collection->update(['key' => $key], $value);
}
/**
@@ -100,11 +142,9 @@ class MongoDbStorage implements Storage
*/
public function delete($storageName, $key)
{
$this->database
->selectCollection($storageName)
->deleteOne([
'key' => $key,
]);
$this->initialize();
$this->collection->remove(['key' => $key]);
}
/**
@@ -112,23 +152,15 @@ class MongoDbStorage implements Storage
*/
public function find($storageName, $key)
{
$result = $this->database
->selectCollection($storageName, [
'typeMap' => [
'array' => 'array',
'document' => 'array',
'root' => 'array',
],
])
->findOne([
'key' => $key,
]);
$this->initialize();
if (! $result || ! $result['value']) {
throw new NotFoundException();
$value = $this->collection->findOne(['key' => $key], ['value']);
if ($value) {
return $value['value'];
}
return $result['value'];
throw new NotFoundException();
}
/**

View File

@@ -21,14 +21,7 @@
namespace Doctrine\KeyValueStore\Storage;
use Doctrine\KeyValueStore\NotFoundException;
use Riak\Client\Command\Kv\DeleteValue;
use Riak\Client\Command\Kv\FetchValue;
use Riak\Client\Command\Kv\StoreValue;
use Riak\Client\Core\Query\RiakLocation;
use Riak\Client\Core\Query\RiakNamespace;
use Riak\Client\Core\Query\RiakObject;
use Riak\Client\RiakClient;
use Riak\Client\RiakException;
use Riak\Client;
/**
* @author Markus Bachmann <markus.bachmann@bachi.biz>
@@ -36,11 +29,17 @@ use Riak\Client\RiakException;
class RiakStorage implements Storage
{
/**
* @var RiakClient
* @var \Riak\Client
*/
private $client;
protected $client;
public function __construct(RiakClient $riak)
/**
* Constructor
*
* @param \Riak\Client $riak
* @param string $bucketName
*/
public function __construct(Client $riak)
{
$this->client = $riak;
}
@@ -69,25 +68,14 @@ class RiakStorage implements Storage
return false;
}
private function store($storageName, $key, array $data)
{
$location = $this->getRiakLocation($storageName, $key);
$riakObject = new RiakObject();
$riakObject->setContentType('application/json');
$riakObject->setValue(json_encode($data));
$store = StoreValue::builder($location, $riakObject)->build();
$this->client->execute($store);
}
/**
* {@inheritDoc}
*/
public function insert($storageName, $key, array $data)
{
$this->store($storageName, $key, $data);
$bucket = $this->client->bucket($storageName);
$object = $bucket->newObject($key, $data);
$object->store();
}
/**
@@ -95,7 +83,12 @@ class RiakStorage implements Storage
*/
public function update($storageName, $key, array $data)
{
$this->store($storageName, $key, $data);
$bucket = $this->client->bucket($storageName);
/** @var $object \Riak\Object */
$object = $bucket->get($key);
$object->setData($data);
$object->store();
}
/**
@@ -103,15 +96,17 @@ class RiakStorage implements Storage
*/
public function delete($storageName, $key)
{
$location = $this->getRiakLocation($storageName, $key);
$bucket = $this->client->bucket($storageName);
$delete = DeleteValue::builder($location)->build();
/** @var $object \Riak\Object */
$object = $bucket->get($key);
try {
$this->client->execute($delete);
} catch (RiakException $exception) {
// deletion can fail silent
if (! $object->exists()) {
// object does not exist, do nothing
return;
}
$object->delete();
}
/**
@@ -119,29 +114,16 @@ class RiakStorage implements Storage
*/
public function find($storageName, $key)
{
$location = $this->getRiakLocation($storageName, $key);
$bucket = $this->client->bucket($storageName);
// fetch object
$fetch = FetchValue::builder($location)->build();
/** @var $object \Riak\Object */
$object = $bucket->get($key);
try {
$result = $this->client->execute($fetch);
} catch (RiakException $exception) {
throw new NotFoundException();
if (! $object->exists()) {
throw new NotFoundException;
}
$json = (string) $result
->getValue()
->getValue();
return json_decode($json, true);
}
private function getRiakLocation($storageName, $key)
{
$namespace = new RiakNamespace('default', $storageName);
return new RiakLocation($namespace, $key);
return $object->getData();
}
/**

View File

@@ -16,6 +16,5 @@
<var name="DOCTRINE_KEYVALUE_AZURE_AUTHSCHEMA" value="sharedlite" />
<var name="DOCTRINE_KEYVALUE_AZURE_NAME" value="" />
<var name="DOCTRINE_KEYVALUE_AZURE_KEY" value="" />
<env name="RIAK_DNS" value="" />
</php>
</phpunit>

View File

@@ -20,34 +20,40 @@
namespace Doctrine\Tests\KeyValueStore\Storage;
use Doctrine\KeyValueStore\NotFoundException;
use Doctrine\KeyValueStore\Storage\MongoDbStorage;
use MongoDB\Client;
/**
* MongoDb storage testcase
*
* @author Markus Bachmann <markus.bachmann@bachi.biz>
*
* @covers \Doctrine\KeyValueStore\Storage\MongoDbStorage
* @requires extension mongodb
* @requires extension mongo
*/
class MongoDbStorageTest extends \PHPUnit_Framework_TestCase
{
/**
* @var Client
*/
private $client;
/**
* @var MongoDbStorage
*/
private $storage;
protected function setUp()
{
$this->client = new Client();
$this->storage = new MongoDbStorage($this->client->test);
$this->mongo = $this
->getMockBuilder('\Mongo')
->disableOriginalConstructor()
->getMock();
$this->mongodb = $this->getMockBuilder('\MongoDB')->disableOriginalConstructor()->getMock();
$this->mongo->expects($this->any())
->method('selectDB')
->will($this->returnValue($this->mongodb));
$this->collection = $this->getMockBuilder('MongoCollection')->disableOriginalConstructor()->getMock();
$this->mongodb->expects($this->once())
->method('selectCollection')
->will($this->returnValue($this->collection));
$this->storage = new MongoDbStorage($this->mongo, [
'collection' => 'test',
'database' => 'test',
]);
}
public function testInsert()
@@ -57,21 +63,20 @@ class MongoDbStorageTest extends \PHPUnit_Framework_TestCase
'title' => 'example book',
];
$this->storage->insert('mongodb', 'testInsert', $data);
$dbDataset = [];
$result = $this->client
->test
->mongodb
->findOne([
'key' => 'testInsert',
]);
$this->collection->expects($this->once())
->method('insert')
->will($this->returnCallback(function ($data) use (&$dbDataset) {
$dbDataset[] = $data;
}));
$this->assertSame($data, $result['value']->getArrayCopy());
$this->storage->insert('mongodb', '1', $data);
$this->assertCount(1, $dbDataset);
$this->assertEquals([['key' => '1', 'value' => $data]], $dbDataset);
}
/**
* @depends testInsert
*/
public function testUpdate()
{
$data = [
@@ -79,67 +84,80 @@ class MongoDbStorageTest extends \PHPUnit_Framework_TestCase
'title' => 'example book',
];
$this->storage->insert('mongodb', 'testUpdate', [
'foo' => 'bar',
]);
$this->storage->update('mongodb', 'testUpdate', $data);
$dbDataset = [];
$result = $this->client
->test
->mongodb
->findOne([
'key' => 'testUpdate',
]);
$this->collection->expects($this->once())
->method('update')
->will($this->returnCallback(function ($citeria, $data) use (&$dbDataset) {
$dbDataset = [$citeria, $data];
}));
$this->assertSame($data, $result['value']->getArrayCopy());
$this->storage->update('mongodb', '1', $data);
$this->assertEquals(['key' => '1'], $dbDataset[0]);
$this->assertEquals(['key' => '1', 'value' => $data], $dbDataset[1]);
}
/**
* @depends testInsert
*/
public function testDelete()
{
$this->storage->insert('mongodb', 'testDelete', [
'foo' => 'bar',
]);
$dataset = [
[
'key' => 'foobar',
'value' => [
'author' => 'John Doe',
'title' => 'example book',
],
],
];
$this->storage->delete('mongodb', 'testDelete');
$this->collection->expects($this->once())
->method('remove')
->will($this->returnCallback(function ($citeria) use (&$dataset) {
foreach ($dataset as $key => $row) {
if ($row['key'] === $citeria['key']) {
unset($dataset[$key]);
}
}
}
));
$result = $this->client
->test
->mongodb
->findOne([
'key' => 'testDelete',
]);
$this->storage->delete('test', 'foobar');
$this->assertNull($result);
$this->assertCount(0, $dataset);
}
/**
* @depends testInsert
*/
public function testFind()
{
$dataset = [
'author' => 'John Doe',
'title' => 'example book',
[
'key' => 'foobar',
'value' => [
'author' => 'John Doe',
'title' => 'example book',
],
],
];
$this->storage->insert('mongodb', 'testFind', $dataset);
$this->collection->expects($this->once())
->method('findOne')
->will($this->returnCallback(function ($citeria, $fields) use (&$dataset) {
foreach ($dataset as $key => $row) {
if ($row['key'] === $citeria['key']) {
return $row;
}
}
}
));
$data = $this->storage->find('mongodb', 'testFind');
$data = $this->storage->find('test', 'foobar');
$this->assertEquals($dataset, $data);
}
public function testFindWithNotExistKey()
{
$this->setExpectedException(NotFoundException::class);
$this->storage->find('mongodb', 'not-existing-key');
$this->assertEquals($dataset[0]['value'], $data);
}
public function testGetName()
{
$this->storage->initialize();
$this->assertEquals('mongodb', $this->storage->getName());
}
}

View File

@@ -20,46 +20,34 @@
namespace Doctrine\Tests\KeyValueStore\Storage;
use Doctrine\KeyValueStore\NotFoundException;
use Doctrine\KeyValueStore\Storage\RiakStorage;
use PHPUnit_Framework_TestCase;
use Riak\Client\Command\Kv\Builder\ListKeysBuilder;
use Riak\Client\Command\Kv\FetchValue;
use Riak\Client\Core\Query\RiakLocation;
use Riak\Client\Core\Query\RiakNamespace;
use Riak\Client\Core\Query\RiakObject;
use Riak\Client\Core\Transport\RiakTransportException;
use Riak\Client\RiakClient;
use Riak\Client\RiakClientBuilder;
/**
* @author Markus Bachmann <markus.bachmann@bachi.biz>
*/
class RiakStorageTest extends PHPUnit_Framework_TestCase
class RiakStorageTest extends \PHPUnit_Framework_TestCase
{
/**
* @var RiakClient
*/
private $client;
/**
* @var RiakStorage
*/
private $storage;
protected function setUp()
{
$dns = getenv('RIAK_DNS');
/**
* @var \PHPUnit_Framework_MockObject_MockObject
*/
private $riak;
if (empty($dns)) {
$this->markTestSkipped('Missing Riak DNS');
protected function setup()
{
if (PHP_MAJOR_VERSION >= 7) {
$this->markTestSkipped('Riak extension is not available for PHP versions >= 7');
}
$this->client = (new RiakClientBuilder())
->withNodeUri($dns)
->build();
$this->riak = $this->getMockBuilder('Riak\\Client')
->disableOriginalConstructor()
->getMock();
$this->storage = new RiakStorage($this->client);
$this->storage = new RiakStorage($this->riak);
}
public function testSupportsPartialUpdates()
@@ -79,124 +67,186 @@ class RiakStorageTest extends PHPUnit_Framework_TestCase
public function testInsert()
{
$data = [
'title' => 'Riak test',
];
$bucket = $this->getMockBuilder('Riak\Bucket')
->disableOriginalConstructor()
->getMock();
$this->storage->insert('riak-test', 'foobar', $data);
$this->riak->expects($this->once())
->method('bucket')
->will($this->returnValue($bucket));
$location = $this->getRiakLocation();
$objectMock = $this->getMockBuilder('Riak\Object')
->disableOriginalConstructor()
->getMock();
$fetch = FetchValue::builder($location)->build();
$objectMock->expects($this->once())
->method('store');
$json = (string) $this->client
->execute($fetch)
->getValue()
->getValue();
$that = $this;
$bucket->expects($this->once())
->method('newObject')
->will($this->returnCallback(function ($key, $data) use ($objectMock, $that) {
$that->assertEquals('foobar', $key);
$that->assertEquals(['title' => 'Riak test'], $data);
return $objectMock;
}));
$this->assertSame($data, json_decode($json, true));
$this->storage->insert('riak-test', 'foobar', ['title' => 'Riak test']);
}
/**
* @depends testInsert
*/
public function testUpdate()
{
$data = [
'title' => 'Riak update',
];
$objectMock = $this->getMockBuilder('Riak\Object')
->disableOriginalConstructor()
->getMock();
$this->storage->insert('riak-test', 'foobar', [
'title' => 'Riak insert',
]);
$bucket = $this->getMockBuilder('Riak\Bucket')
->disableOriginalConstructor()
->getMock();
$location = $this->getRiakLocation();
$this->riak->expects($this->once())
->method('bucket')
->will($this->returnValue($bucket));
$this->assertTotalBucketKeys(1, $location);
$bucket->expects($this->once())
->method('get')
->will($this->returnValue($objectMock));
$this->storage->update('riak-test', 'foobar', $data);
$that = $this;
$objectMock->expects($this->once())
->method('setData')
->will($this->returnCallback(function ($data) use ($that) {
$that->assertEquals(['title' => 'Riak cookbook'], $data);
}));
$fetch = FetchValue::builder($location)->build();
$objectMock->expects($this->once())
->method('store');
$json = (string) $this->client
->execute($fetch)
->getValue()
->getValue();
$this->assertSame($data, json_decode($json, true));
$this->assertTotalBucketKeys(1, $location);
$this->storage->update('riak-test', 'foobar', ['title' => 'Riak cookbook']);
}
/**
* @depends testInsert
*/
public function testDelete()
{
$this->testInsert();
$objectMock = $this->getMockBuilder('Riak\Object')
->disableOriginalConstructor()
->getMock();
$bucket = $this->getMockBuilder('Riak\Bucket')
->disableOriginalConstructor()
->getMock();
$this->riak->expects($this->once())
->method('bucket')
->will($this->returnValue($bucket));
$bucket->expects($this->once())
->method('get')
->with('foobar')
->will($this->returnValue($objectMock));
$objectMock->expects($this->once())
->method('exists')
->will($this->returnValue(true));
$objectMock->expects($this->once())
->method('delete');
$this->storage->delete('riak-test', 'foobar');
$location = $this->getRiakLocation();
$fetch = FetchValue::builder($location)->build();
$this->setExpectedException(RiakTransportException::class);
$this->client->execute($fetch);
$this->assertTotalBucketKeys(0, $location);
}
/**
* @depends testDelete
*/
public function testDeleteWithNotExistKey()
{
$objectMock = $this->getMockBuilder('Riak\Object')
->disableOriginalConstructor()
->getMock();
$bucket = $this->getMockBuilder('Riak\Bucket')
->disableOriginalConstructor()
->getMock();
$this->riak->expects($this->once())
->method('bucket')
->will($this->returnValue($bucket));
$bucket->expects($this->once())
->method('get')
->with('foobar')
->will($this->returnValue($objectMock));
$objectMock->expects($this->once())
->method('exists')
->will($this->returnValue(false));
$objectMock->expects($this->never())
->method('delete');
$this->storage->delete('riak-test', 'foobar');
$this->storage->delete('riak-test', 'foobar');
}
public function testFind()
{
$objectMock = $this->getMockBuilder('Riak\Object')
->disableOriginalConstructor()
->getMock();
$bucket = $this->getMockBuilder('Riak\Bucket')
->disableOriginalConstructor()
->getMock();
$this->riak->expects($this->once())
->method('bucket')
->will($this->returnValue($bucket));
$bucket->expects($this->once())
->method('get')
->with('foobar')
->will($this->returnValue($objectMock));
$objectMock->expects($this->once())
->method('exists')
->will($this->returnValue(true));
$objectMock->expects($this->once())
->method('getData')
->will($this->returnValue(['title' => 'Riak Test']));
$this->assertEquals(['title' => 'Riak Test'], $this->storage->find('riaktest', 'foobar'));
}
/**
* @depends testInsert
* @expectedException Doctrine\KeyValueStore\NotFoundException
*/
public function testFind()
{
$data = [
'title' => 'Riak test',
];
$this->storage->insert('riak-test', 'foobar', $data);
$result = $this->storage->find('riak-test', 'foobar');
$this->assertSame($data, $result);
}
public function testFindWithNotExistKey()
{
$this->setExpectedException(NotFoundException::class);
$this->storage->find('riak-test', 'foobar-1');
$objectMock = $this->getMockBuilder('Riak\Object')
->disableOriginalConstructor()
->getMock();
$bucket = $this->getMockBuilder('Riak\Bucket')
->disableOriginalConstructor()
->getMock();
$this->riak->expects($this->once())
->method('bucket')
->will($this->returnValue($bucket));
$bucket->expects($this->once())
->method('get')
->with('foobar')
->will($this->returnValue($objectMock));
$objectMock->expects($this->once())
->method('exists')
->will($this->returnValue(false));
$objectMock->expects($this->never())
->method('getData');
$this->storage->find('riak-test', 'foobar');
}
public function testGetName()
{
$this->assertEquals('riak', $this->storage->getName());
}
private function assertTotalBucketKeys($expectedTotal, $location)
{
$command = (new ListKeysBuilder($location->getNamespace()))->build();
$iterator = $this->client
->execute($command)
->getIterator();
$this->assertCount($expectedTotal, iterator_to_array($iterator));
}
private function getRiakLocation()
{
$namespace = new RiakNamespace('default', 'riak-test');
return new RiakLocation($namespace, 'foobar');
}
}

View File

@@ -7,5 +7,7 @@ sudo apt-get install -y libuv-dev libssl-dev
cd /tmp && git clone https://github.com/datastax/php-driver.git && cd php-driver && git submodule update --init
cd ext && ./install.sh && cd "$TRAVIS_BUILD_DIR"
echo "extension=cassandra.so" >> `php --ini | grep "Loaded Configuration" | sed -e "s|.*:\s*||"`
# PHP extensions
yes | pecl install mongo
# PECL extensions
echo "extension = redis.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini