Added query method for Http adapter

This commit is contained in:
Walter Dal Mut
2014-09-12 20:20:23 +02:00
parent ca09343134
commit b835c3a044
10 changed files with 203 additions and 26 deletions
+45
View File
@@ -43,6 +43,51 @@ Actually we using Guzzle as HTTP client
$influx->mark("tcp.test", ["mark" => "element"]);
```
## Query InfluxDB
You can query the time series database using the query method.
```php
$influx->query("select * from mine");
$influx->query("select * from mine", "s"); // with time_precision
```
You can query the database only if the adapter is queryable (implements `QueryableInterface`),
actually `GuzzleAdapter`.
The adapter returns the json decoded body of the InfluxDB response, something like:
```
array(1) {
[0] =>
class stdClass#1 (3) {
public $name =>
string(8) "tcp.test"
public $columns =>
array(3) {
[0] =>
string(4) "time"
[1] =>
string(15) "sequence_number"
[2] =>
string(4) "mark"
}
public $points =>
array(1) {
[0] =>
array(3) {
[0] =>
int(1410545635590)
[1] =>
int(2390001)
[2] =>
string(7) "element"
}
}
}
}
```
## Prepare lib dependencies
Use your DiC or Service Locator in order to provide a configured client
+1 -1
View File
@@ -29,7 +29,7 @@
],
"autoload": {
"psr-0": {
"InfluxDB": ["./src/", "./tests"]
"InfluxDB\\": ["./src/", "./tests"]
}
},
"suggests": {
+19 -2
View File
@@ -11,7 +11,9 @@ class GuzzleAdapterSpec extends ObjectBehavior
{
function let(Client $client, Options $options)
{
$options->getTcpEndpoint()->willReturn("localhost");
$options->getHttpSeriesEndpoint()->willReturn("localhost");
$options->getUsername()->willReturn("one");
$options->getPassword()->willReturn("two");
$this->beConstructedWith($client, $options);
}
@@ -22,8 +24,23 @@ class GuzzleAdapterSpec extends ObjectBehavior
function it_should_send_data_via_post(Client $client, Options $options)
{
$client->post("localhost", ['body' => json_encode(['pippo'])])->shouldBeCalledTimes(1);
$client->post("localhost", [
'auth' => ["one", "two"],
'body' => json_encode(['pippo'])
])->shouldBeCalledTimes(1);
$this->send(["pippo"]);
}
function it_should_query_data(Client $client, Options $options)
{
$client->get("select * from tcp.test", [])->willReturn([]);
$this->query("select * from tcp.test")->shouldReturn([]);
}
function it_should_query_data_with_time_precision(Client $client, Options $options)
{
$client->get("select * from tcp.test", ["time_precision" => "s"])->willReturn([]);
$this->query("select * from tcp.test", "s")->shouldReturn([]);
}
}
+33
View File
@@ -4,6 +4,8 @@ namespace spec\InfluxDB;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use InfluxDB\Adapter\GuzzleAdapter;
use InfluxDB\Adapter\UdpAdapter;
class ClientSpec extends ObjectBehavior
{
@@ -31,4 +33,35 @@ class ClientSpec extends ObjectBehavior
"title" => "Autogrill"
]);
}
function it_should_query_on_querable_adapter(GuzzleAdapter $adapter)
{
$this->setAdapter($adapter);
$adapter->query("select * from tcp.test", false)->willReturn([]);
$this->query("select * from tcp.test")->shouldReturn([]);
}
function it_should_query_with_time_precision(GuzzleAdapter $adapter)
{
$this->setAdapter($adapter);
$adapter->query("select * from tcp.test", "s")->willReturn([]);
$this->query("select * from tcp.test", "s")->shouldReturn([]);
}
function it_should_query_but_skip_invalid_time_precision(GuzzleAdapter $adapter)
{
$this->setAdapter($adapter);
$adapter->query("select * from tcp.test", false)->willReturn([]);
$this->query("select * from tcp.test", "r")->shouldReturn([]);
}
function it_should_thrown_an_exception_on_unquerable_adapter(UdpAdapter $adapter)
{
$this->setAdapter($adapter);
$this->shouldThrow("\\BadMethodCallException")->duringQuery("select * from tcp.test");
}
}
+6 -6
View File
@@ -15,8 +15,8 @@ class OptionsSpec extends ObjectBehavior
function it_should_create_a_valid_tcp_endpoint()
{
$this->setDatabase("mine");
$this->getTcpEndpoint()
->shouldReturn("http://localhost:8086/db/mine/series?u=root&p=root");
$this->getHttpSeriesEndpoint()
->shouldReturn("http://localhost:8086/db/mine/series");
}
function it_should_allows_option_override_for_tcp_endpoint()
@@ -26,15 +26,15 @@ class OptionsSpec extends ObjectBehavior
$this->setUsername("walter");
$this->setPassword("walter");
$this->setDatabase("me");
$this->getTcpEndpoint()
->shouldReturn("http://influx.1.prod.tld:19385/db/me/series?u=walter&p=walter");
$this->getHttpSeriesEndpoint()
->shouldReturn("http://influx.1.prod.tld:19385/db/me/series");
}
function it_should_allows_https_for_tcp_endpoint()
{
$this->setProtocol("https");
$this->setDatabase("me");
$this->getTcpEndpoint()
->shouldReturn("https://localhost:8086/db/me/series?u=root&p=root");
$this->getHttpSeriesEndpoint()
->shouldReturn("https://localhost:8086/db/me/series");
}
}
+20 -3
View File
@@ -5,7 +5,7 @@ namespace InfluxDB\Adapter;
use GuzzleHttp\Client;
use InfluxDB\Options;
class GuzzleAdapter implements AdapterInterface
class GuzzleAdapter implements AdapterInterface, QueryableInterface
{
private $httpClient;
private $options;
@@ -20,10 +20,27 @@ class GuzzleAdapter implements AdapterInterface
public function send($message)
{
$httpMessage = [
"auth" => [$this->options->getUsername(), $this->options->getPassword()],
"body" => json_encode($message)
];
$endpoint = $this->options->getTcpEndpoint();
$endpoint = $this->options->getHttpSeriesEndpoint();
$this->httpClient->post($endpoint, $httpMessage);
return $this->httpClient->post($endpoint, $httpMessage);
}
public function query($query, $timePrecision = false)
{
$options = [
"auth" => [$this->options->getUsername(), $this->options->getPassword()],
'query' => [
"q" => $query,
]
];
if ($timePrecision) {
$options["query"]["time_precision"] = $timePrecision;
}
$endpoint = $this->options->getHttpSeriesEndpoint();
return $this->httpClient->get($endpoint, $options)->json();
}
}
@@ -0,0 +1,7 @@
<?php
namespace InfluxDb\Adapter;
interface QueryableInterface
{
public function query($query, $timePrecision = false);
}
+27
View File
@@ -2,6 +2,8 @@
namespace InfluxDB;
use InfluxDb\Adapter\QueryableInterface;
class Client
{
private $adapter;
@@ -36,4 +38,29 @@ class Client
return $this->getAdapter()->send([$data]);
}
public function query($query, $timePrecision = false)
{
if (!($this->getAdapter() instanceOf QueryableInterface)) {
throw new \BadMethodCallException("You can query the database only if the adapter supports it!");
}
$timePrecision = $this->clearTimePrecision($timePrecision);
return $this->getAdapter()->query($query, $timePrecision);
}
private function clearTimePrecision($timePrecision)
{
switch ($timePrecision) {
case 's':
case 'u':
case 'ms':
break;
default:
$timePrecision = false;
}
return $timePrecision;
}
}
+3 -5
View File
@@ -87,16 +87,14 @@ class Options
return $this;
}
public function getTcpEndpoint()
public function getHttpSeriesEndpoint()
{
return sprintf(
"%s://%s:%d/db/%s/series?u=%s&p=%s",
"%s://%s:%d/db/%s/series",
$this->getProtocol(),
$this->getHost(),
$this->getPort(),
$this->getDatabase(),
$this->getUsername(),
$this->getPassword()
$this->getDatabase()
);
}
}
+42 -9
View File
@@ -16,9 +16,6 @@ class ClientTest extends \PHPUnit_Framework_TestCase
public function setUp()
{
$options = include __DIR__ . '/../bootstrap.php';
$this->options = $options;
$this->object = new Client();
$client = new Crodas(
$options["tcp"]["host"],
@@ -34,11 +31,8 @@ class ClientTest extends \PHPUnit_Framework_TestCase
$client->createDatabase($options["tcp"]["database"]);
$this->anotherClient = $client;
}
public function testGuzzleHttpApiWorksCorrectly()
{
$tcpOptions = $this->options["tcp"];
$tcpOptions = $options["tcp"];
$options = new Options();
$options->setHost($tcpOptions["host"]);
@@ -47,17 +41,56 @@ class ClientTest extends \PHPUnit_Framework_TestCase
$options->setPassword($tcpOptions["password"]);
$options->setDatabase($tcpOptions["database"]);
$this->options = $options;
$guzzleHttp = new GuzzleHttpClient();
$adapter = new InfluxHttpAdapter($guzzleHttp, $options);
$influx = new Client();
$influx->setAdapter($adapter);
$this->object = $influx;
}
$influx->mark("tcp.test", ["mark" => "element"]);
public function testGuzzleHttpApiWorksCorrectly()
{
$this->object->mark("tcp.test", ["mark" => "element"]);
$cursor = $this->anotherClient->getDatabase($tcpOptions["database"])
$cursor = $this->anotherClient->getDatabase($this->options->getDatabase())
->query("select * from tcp.test");
$this->assertCount(1, $cursor);
$this->assertEquals("element", $cursor[0]->mark);
}
public function testGuzzleHttpQueryApiWorksCorrectly()
{
$this->object->mark("tcp.test", ["mark" => "element"]);
$body = $this->object->query("select * from tcp.test");
$this->assertCount(1, $body);
$this->assertEquals("tcp.test", $body[0]["name"]);
$this->assertEquals("element", $body[0]["points"][0][2]);
}
public function testGuzzleHttpQueryApiWithMultipleData()
{
$this->object->mark("tcp.test", ["mark" => "element"]);
$this->object->mark("tcp.test", ["mark" => "element2"]);
$this->object->mark("tcp.test", ["mark" => "element3"]);
$body = $this->object->query("select mark from tcp.test", "s");
$this->assertCount(3, $body[0]["points"]);
$this->assertEquals("tcp.test", $body[0]["name"]);
}
public function testGuzzleHttpQueryApiWithTimePrecision()
{
$this->object->mark("tcp.test", ["mark" => "element"]);
$body = $this->object->query("select mark from tcp.test", "s");
$this->assertCount(1, $body[0]["points"]);
$this->assertEquals("tcp.test", $body[0]["name"]);
}
}