Skip to content

Commit

Permalink
RIAK-2907 gset support
Browse files Browse the repository at this point in the history
  • Loading branch information
Luke Bakken committed Jan 18, 2017
1 parent 4221663 commit 3992169
Show file tree
Hide file tree
Showing 9 changed files with 359 additions and 4 deletions.
9 changes: 8 additions & 1 deletion src/Riak/Api/Http.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Basho\Riak\Command;
use Basho\Riak\DataType\Counter;
use Basho\Riak\DataType\Map;
use Basho\Riak\DataType\GSet;
use Basho\Riak\DataType\Set;
use Basho\Riak\DataType\Hll;
use Basho\Riak\Location;
Expand Down Expand Up @@ -221,6 +222,7 @@ protected function buildPath()
$this->path = sprintf('/types/%s/buckets/%s/keys/%s', $bucket->getType(), $bucket->getName(), $key);
break;
case 'Basho\Riak\Command\DataType\Counter\Store':
case 'Basho\Riak\Command\DataType\GSet\Store':
case 'Basho\Riak\Command\DataType\Set\Store':
/** @noinspection PhpMissingBreakStatementInspection */
case 'Basho\Riak\Command\DataType\Map\Store':
Expand Down Expand Up @@ -707,12 +709,17 @@ protected function parseResponse()
);
break;

case 'Basho\Riak\Command\DataType\GSet\Store':
case 'Basho\Riak\Command\DataType\Set\Store':
case 'Basho\Riak\Command\DataType\Set\Fetch':
$set = null;
$json_object = json_decode($body);
if ($json_object && isset($json_object->value)) {
$set = new Set($json_object->value, $json_object->context);
$context = '';
if (isset($json_object->context)) {
$context = $json_object->context;
}
$set = new Set($json_object->value, $context);
}
$response = new Command\DataType\Set\Response(
$this->success, $this->statusCode, $this->error, $location, $set, $this->getResponseHeader('Date')
Expand Down
66 changes: 66 additions & 0 deletions src/Riak/Command/Builder/UpdateGSet.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

namespace Basho\Riak\Command\Builder;

use Basho\Riak;
use Basho\Riak\Command;

/**
* @author Luke Bakken <[email protected]>
*/
class UpdateGSet extends Command\Builder implements Command\BuilderInterface
{
use LocationTrait;

/**
* @var array
*/
protected $add_all = [];

/**
* @param mixed $element
*
* @return $this
*/
public function add($element)
{
settype($element, 'string');
$this->add_all[] = $element;

return $this;
}

/**
* @return array
*/
public function getAddAll()
{
return $this->add_all;
}

/**
* {@inheritdoc}
*
* @return Command\DataType\GSet\Store
*/
public function build()
{
$this->validate();

return new Command\DataType\GSet\Store($this);
}

/**
* {@inheritdoc}
*/
public function validate()
{
$this->required('Bucket');

$count_add = count($this->add_all);

if ($count_add < 1) {
throw new Exception('At least one element to add needs to be defined.');
}
}
}
64 changes: 64 additions & 0 deletions src/Riak/Command/DataType/GSet/Store.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

namespace Basho\Riak\Command\DataType\GSet;

use Basho\Riak\Command;
use Basho\Riak\CommandInterface;
use Basho\Riak\Location;

/**
* Stores a write update to a gset
*
* @author Luke Bakken <[email protected]>
*/
class Store extends Command implements CommandInterface
{
protected $method = 'POST';

/**
* @var array
*/
protected $add_all = [];

/**
* @var Command\DataType\Set\Response|null
*/
protected $response = NULL;

/**
* @var Location|null
*/
protected $location = NULL;

public function __construct(Command\Builder\UpdateGSet $builder)
{
parent::__construct($builder);

$this->add_all = $builder->getAddAll();
$this->bucket = $builder->getBucket();
$this->location = $builder->getLocation();
}

public function getLocation()
{
return $this->location;
}

public function getEncodedData()
{
return json_encode($this->getData());
}

public function getData()
{
return ['add_all' => $this->add_all];
}

/**
* @return Command\DataType\Set\Response
*/
public function execute()
{
return parent::execute();
}
}
1 change: 1 addition & 0 deletions tests/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ abstract class TestCase extends \PHPUnit_Framework_TestCase
const MAP_BUCKET_TYPE = 'maps';
const SEARCH_BUCKET_TYPE = 'yokozuna';
const SET_BUCKET_TYPE = 'sets';
const GSET_BUCKET_TYPE = 'gsets';

const TEST_IMG = "Basho_Man_Super.png";

Expand Down
141 changes: 141 additions & 0 deletions tests/functional/GSetOperationsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
<?php

namespace Basho\Tests;

use Basho\Riak\Command;

/**
* Functional tests related to GSet CRDTs
*
* @author Luke Bakken <[email protected]>
*/
class GSetTest extends TestCase
{
/**
* Key to be used for tests
*
* @var string
*/
private static $key = '';

public static function setUpBeforeClass()
{
parent::setUpBeforeClass();

// make completely random key based on time
static::$key = md5(rand(0, 99) . time());

try
{
// Skip this suite if the "gsets" bucket type is not present
$command = (new Command\Builder\FetchBucketProperties(static::$riak))
->buildBucket('test', static::GSET_BUCKET_TYPE)
->build();

$response = $command->execute();

if (!$response->isSuccess() || $response->getCode() != 200) {
throw new \PHPUnit_Framework_SkippedTestSuiteError("gsets bucket type is not enabled and activated, skipping");
}
}
catch (\Exception $ex)
{
throw new \PHPUnit_Framework_SkippedTestSuiteError("gsets bucket type is not enabled and activated, skipping");
}
}

public function testAddWithoutKey()
{
// build an object
$command = (new Command\Builder\UpdateGSet(static::$riak))
->add('gosabres poked you.')
->add('phprocks viewed your profile.')
->add('phprocks started following you.')
->buildBucket('default', static::GSET_BUCKET_TYPE)
->build();

$response = $command->execute();

// expects 201 - Created
$this->assertEquals('201', $response->getCode());
$this->assertNotEmpty($response->getLocation());
}

public function testFetchNotFound()
{
$command = (new Command\Builder\FetchSet(static::$riak))
->buildLocation(static::$key, 'default', static::GSET_BUCKET_TYPE)
->build();

$response = $command->execute();

$this->assertEquals('404', $response->getCode());
}

/**
* @depends testFetchNotFound
*/
public function testAddNewWithKey()
{
$command = (new Command\Builder\UpdateGSet(static::$riak))
->add('Sabres')
->add('Canadiens')
->add('Bruins')
->add('Maple Leafs')
->add('Senators')
->add('Red Wings')
->add('Thrashers')
->buildLocation(static::$key, 'Teams', static::GSET_BUCKET_TYPE)
->build();

$response = $command->execute();

// expects 204 - No Content
// this is wonky, its not 201 because the key may have been generated on another node
$this->assertEquals('204', $response->getCode());
$this->assertEmpty($response->getLocation());

$command = (new Command\Builder\FetchSet(static::$riak))
->buildLocation(static::$key, 'Teams', static::GSET_BUCKET_TYPE)
->build();

$response = $command->execute();

$this->assertEquals('200', $response->getCode());
$this->assertInstanceOf('Basho\Riak\DataType\Set', $response->getSet());
$this->assertNotEmpty($response->getSet()->getData());
$this->assertTrue(is_array($response->getSet()->getData()));
$this->assertEquals(7, count($response->getSet()->getData()));
$this->assertEmpty($response->getSet()->getContext());
}

/**
* @depends testAddNewWithKey
*/
public function testAddAnotherNew()
{
// add without context
$command = (new Command\Builder\UpdateGSet(static::$riak))
->add('Lightning')
->buildLocation(static::$key, 'Teams', static::GSET_BUCKET_TYPE)
->build();

$response = $command->execute();

// 204 - No Content
$this->assertEquals('204', $response->getCode());

$command = (new Command\Builder\FetchSet(static::$riak))
->buildLocation(static::$key, 'Teams', static::GSET_BUCKET_TYPE)
->build();

$response = $command->execute();

$this->assertEquals('200', $response->getCode());
$this->assertInstanceOf('Basho\Riak\DataType\Set', $response->getSet());
$this->assertNotEmpty($response->getSet()->getData());
$this->assertTrue(is_array($response->getSet()->getData()));
$this->assertEquals(8, count($response->getSet()->getData()));
$this->assertEmpty($response->getSet()->getContext());
}
}
2 changes: 1 addition & 1 deletion tests/functional/SetOperationsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public function testAddNewWithKey()
/**
* @depends testAddNewWithKey
*/
public function testAddExisting()
public function testAddAnotherNew()
{
// add without context
$command = (new Command\Builder\UpdateSet(static::$riak))
Expand Down
Loading

0 comments on commit 3992169

Please sign in to comment.