Merge pull request #9 from influxdb/1.0.0

New version: 1.0.0
This commit is contained in:
TheCodeAssassin
2015-07-23 09:44:25 +02:00
16 changed files with 724 additions and 191 deletions
-2
View File
@@ -1,7 +1,5 @@
language: php
php:
- 5.3
- 5.4
- 5.5
- 5.6
+15 -2
View File
@@ -8,8 +8,8 @@ Here are a few ways you can help make this project better.
## Team members
Stephen "TheCodeAssassin" Hoogendijk
Daniel "danibrutal" Martinez
* Stephen "TheCodeAssassin" Hoogendijk
* Daniel "danibrutal" Martinez
## Helping out
@@ -29,9 +29,22 @@ In order for your pull requests to get accepted we hold all the code to the foll
* Do not use left hand conditions such as false == $something
* New features need to be documented
* Breaking changes should be well highlighted and explained in the PR
* Only short-array syntax should be used for arrays
* Use regular string concatenation for single-variable strings, and sprintf for multi-variable strings
* Do not align variable assignments
The following is optional but encouraged:
* Code should be documented
* Code should be unit tested
* Do not write conditions like false === $something, rather $something === false.
## Special thanks
We would like to thank the following people for helping to make this library possible:
* InfluxDB Community
* LeaseWeb Technologies
* Paul Dix
* Sean Beckett
* CentaurWarchief
+92 -13
View File
@@ -30,7 +30,7 @@ $client = new InfluxDB\Client($host, $port);
This will create a new client object which you can use to read and write points to InfluxDB.
It's also possible to create a client from a DSN:
It's also possible to create a client from a DSN (Data Source Name):
```php
@@ -89,23 +89,23 @@ Writing data is done by providing an array of points to the writePoints method o
// create an array of points
$points = array(
new Point(
'test_metric',
0.64,
array('host' => 'server01', 'region' => 'us-west'),
array('cpucount' => 10),
'test_metric', // name of the measurement
0.64, // the measurement value
['host' => 'server01', 'region' => 'us-west'], // optional tags
['cpucount' => 10], // optional additional fields
1435255849 // Time precision has to be set to seconds!
),
new Point(
'test_metric',
0.84,
array('host' => 'server01', 'region' => 'us-west'),
array('cpucount' => 10),
1435255850 // Time precision has to be set to seconds!
'test_metric', // name of the measurement
0.84, // the measurement value
['host' => 'server01', 'region' => 'us-west'], // optional tags
['cpucount' => 10], // optional additional fields
1435255849 // Time precision has to be set to seconds!
)
);
// we are writing unix timestamps, which have a second precision
$newPoints = $database->writePoints($points, Database::PRECISION_SECONDS);
$result = $database->writePoints($points, Database::PRECISION_SECONDS);
```
@@ -115,6 +115,74 @@ measurements to InfluxDB. The point class allows one to easily write data in bat
The name of a measurement and the value are mandatory. Additional fields, tags and a timestamp are optional.
InfluxDB takes the current time as the default timestamp.
You can also write multiple fields to a measurement without specifying a value:
```php
$points = [
new Point(
'instance', // the name of the measurement
null, // measurement value
['host' => 'server01', 'region' => 'us-west'], // measurement tags
['cpucount' => 10, 'free' => 1], // measurement fields
exec('date +%s%N') // timestamp in nanoseconds
),
new Point(
'instance', // the name of the measurement
null, // measurement value
['host' => 'server01', 'region' => 'us-west'], // measurement tags
['cpucount' => 10, 'free' => 2], // measurement fields
exec('date +%s%N') // timestamp in nanoseconds
)
];
```
#### Writing data using udp
First, set your InfluxDB host to support incoming UDP sockets:
```ini
[udp]
enabled = true
bind-address = ":4444"
database = "test_db"
```
Then, configure the UDP driver in the client:
```php
// set the UDP driver in the client
$client->setDriver(new \InfluxDB\Driver\UDP($client->getHost(), 4444));
$points = [
new Point(
'test_metric',
0.84,
['host' => 'server01', 'region' => 'us-west'],
['cpucount' => 10],
exec('date +%s%N') // this will produce a nanosecond timestamp in Linux operating systems
)
];
// now just write your points like you normally would
$result = $database->writePoints($points);
```
Or simply use a DSN (Data Source Name) to send metrics using UDP:
```php
// get a database object using a DSN (Data Source Name)
$database = \InfluxDB\Client::fromDSN('udp+influxdb://username:pass@localhost:4444/test123');
// write your points
$result = $database->writePoints($points);
```
*Note:* It is import to note that precision will be *ignored* when you use UDP. You should always use nanosecond
precision when writing data to InfluxDB using UDP.
#### Timestamp precision
It's important to provide the correct precision when adding a timestamp to a Point object. This is because
@@ -147,7 +215,14 @@ This library makes it easy to provide a retention policy when creating a databas
$database = $client->selectDB('influx_test_db');
// create the database with a retention policy
$result = $database->create(new RetentionPolicy('test', '5d', 1, true));
$result = $database->create(new RetentionPolicy('test', '5d', 1, true));
// check if a database exists then create it if it doesn't
$database = $client->selectDB('test_db');
if (!$database->exists()) {
$database->create(new RetentionPolicy('test', '1d', 2, true));
}
```
@@ -184,7 +259,6 @@ Some functions are too general for a database. So these are available in the cli
## Todo
* Add UDP support
* Add more admin features
* More unit tests
* Increase documentation (wiki?)
@@ -194,6 +268,11 @@ Some functions are too general for a database. So these are available in the cli
## Changelog
####1.0.0
* -BREAKING CHANGE- Dropped support for PHP 5.3 and PHP 5.4
* Allowing for custom drivers
* UDP support
####0.1.2
* Added exists method to Database class
* Added time precision to database class
+2 -2
View File
@@ -22,8 +22,8 @@
}
],
"require": {
"php": ">=5.3",
"guzzlehttp/guzzle": "3.*",
"php": ">=5.5",
"guzzlehttp/guzzle": "6.*",
"symfony/event-dispatcher": "2.*"
},
"require-dev": {
Generated
+199 -71
View File
@@ -1,73 +1,47 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"hash": "3db2b5749b72a686e2a905c11e313ae4",
"hash": "ee3f2e2a4eb50f8de36c6efbff37fe71",
"packages": [
{
"name": "guzzlehttp/guzzle",
"version": "v3.8.1",
"version": "dev-master",
"source": {
"type": "git",
"url": "https://github.com/guzzle/guzzle.git",
"reference": "4de0618a01b34aa1c8c33a3f13f396dcd3882eba"
"reference": "1879fbe853b0c64d109e369c7aeff09849e62d1e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/4de0618a01b34aa1c8c33a3f13f396dcd3882eba",
"reference": "4de0618a01b34aa1c8c33a3f13f396dcd3882eba",
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/1879fbe853b0c64d109e369c7aeff09849e62d1e",
"reference": "1879fbe853b0c64d109e369c7aeff09849e62d1e",
"shasum": ""
},
"require": {
"ext-curl": "*",
"php": ">=5.3.3",
"symfony/event-dispatcher": ">=2.1"
},
"replace": {
"guzzle/batch": "self.version",
"guzzle/cache": "self.version",
"guzzle/common": "self.version",
"guzzle/http": "self.version",
"guzzle/inflection": "self.version",
"guzzle/iterator": "self.version",
"guzzle/log": "self.version",
"guzzle/parser": "self.version",
"guzzle/plugin": "self.version",
"guzzle/plugin-async": "self.version",
"guzzle/plugin-backoff": "self.version",
"guzzle/plugin-cache": "self.version",
"guzzle/plugin-cookie": "self.version",
"guzzle/plugin-curlauth": "self.version",
"guzzle/plugin-error-response": "self.version",
"guzzle/plugin-history": "self.version",
"guzzle/plugin-log": "self.version",
"guzzle/plugin-md5": "self.version",
"guzzle/plugin-mock": "self.version",
"guzzle/plugin-oauth": "self.version",
"guzzle/service": "self.version",
"guzzle/stream": "self.version"
"guzzlehttp/promises": "~1.0",
"guzzlehttp/psr7": "~1.1",
"php": ">=5.5.0"
},
"require-dev": {
"doctrine/cache": "*",
"monolog/monolog": "1.*",
"phpunit/phpunit": "3.7.*",
"psr/log": "1.0.*",
"symfony/class-loader": "*",
"zendframework/zend-cache": "<2.3",
"zendframework/zend-log": "<2.3"
"ext-curl": "*",
"phpunit/phpunit": "~4.0",
"psr/log": "~1.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.8-dev"
"dev-master": "6.0-dev"
}
},
"autoload": {
"psr-0": {
"Guzzle": "src/",
"Guzzle\\Tests": "tests/"
"files": [
"src/functions_include.php"
],
"psr-4": {
"GuzzleHttp\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -79,13 +53,9 @@
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
},
{
"name": "Guzzle Community",
"homepage": "https://github.com/guzzle/guzzle/contributors"
}
],
"description": "Guzzle is a PHP HTTP client library and framework for building RESTful web service clients",
"description": "Guzzle is a PHP HTTP client library",
"homepage": "http://guzzlephp.org/",
"keywords": [
"client",
@@ -96,7 +66,165 @@
"rest",
"web service"
],
"time": "2014-01-28 22:29:15"
"time": "2015-07-10 20:04:21"
},
{
"name": "guzzlehttp/promises",
"version": "dev-master",
"source": {
"type": "git",
"url": "https://github.com/guzzle/promises.git",
"reference": "f596be052ef429a16b2f640812fcf84392dd38f7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/promises/zipball/f596be052ef429a16b2f640812fcf84392dd38f7",
"reference": "f596be052ef429a16b2f640812fcf84392dd38f7",
"shasum": ""
},
"require": {
"php": ">=5.5.0"
},
"require-dev": {
"phpunit/phpunit": "~4.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
}
},
"autoload": {
"psr-4": {
"GuzzleHttp\\Promise\\": "src/"
},
"files": [
"src/functions_include.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
}
],
"description": "Guzzle promises library",
"keywords": [
"promise"
],
"time": "2015-06-30 16:39:54"
},
{
"name": "guzzlehttp/psr7",
"version": "1.1.0",
"source": {
"type": "git",
"url": "https://github.com/guzzle/psr7.git",
"reference": "af0e1758de355eb113917ad79c3c0e3604bce4bd"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/af0e1758de355eb113917ad79c3c0e3604bce4bd",
"reference": "af0e1758de355eb113917ad79c3c0e3604bce4bd",
"shasum": ""
},
"require": {
"php": ">=5.4.0",
"psr/http-message": "~1.0"
},
"provide": {
"psr/http-message-implementation": "1.0"
},
"require-dev": {
"phpunit/phpunit": "~4.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
}
},
"autoload": {
"psr-4": {
"GuzzleHttp\\Psr7\\": "src/"
},
"files": [
"src/functions.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
}
],
"description": "PSR-7 message implementation",
"keywords": [
"http",
"message",
"stream",
"uri"
],
"time": "2015-06-24 19:55:15"
},
{
"name": "psr/http-message",
"version": "dev-master",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-message.git",
"reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-message/zipball/85d63699f0dbedb190bbd4b0d2b9dc707ea4c298",
"reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Http\\Message\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interface for HTTP messages",
"keywords": [
"http",
"http-message",
"psr",
"psr-7",
"request",
"response"
],
"time": "2015-05-04 20:22:00"
},
{
"name": "symfony/event-dispatcher",
@@ -423,12 +551,12 @@
"source": {
"type": "git",
"url": "https://github.com/symfony/Config.git",
"reference": "cceb1141805d401e6f7d2e0b1365bf6a15917778"
"reference": "358ec929e494b6f12d8508d88357cbd7383a10ca"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Config/zipball/cceb1141805d401e6f7d2e0b1365bf6a15917778",
"reference": "cceb1141805d401e6f7d2e0b1365bf6a15917778",
"url": "https://api.github.com/repos/symfony/Config/zipball/358ec929e494b6f12d8508d88357cbd7383a10ca",
"reference": "358ec929e494b6f12d8508d88357cbd7383a10ca",
"shasum": ""
},
"require": {
@@ -465,7 +593,7 @@
],
"description": "Symfony Config Component",
"homepage": "https://symfony.com",
"time": "2015-06-28 18:28:18"
"time": "2015-07-09 16:11:14"
},
{
"name": "symfony/console",
@@ -473,12 +601,12 @@
"source": {
"type": "git",
"url": "https://github.com/symfony/Console.git",
"reference": "2a909e48c528c7c9b22caff6ff622c6c69032bfc"
"reference": "fd85e7517e79a2bceafcee8f7e8b7bbd0919a90a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Console/zipball/2a909e48c528c7c9b22caff6ff622c6c69032bfc",
"reference": "2a909e48c528c7c9b22caff6ff622c6c69032bfc",
"url": "https://api.github.com/repos/symfony/Console/zipball/fd85e7517e79a2bceafcee8f7e8b7bbd0919a90a",
"reference": "fd85e7517e79a2bceafcee8f7e8b7bbd0919a90a",
"shasum": ""
},
"require": {
@@ -522,7 +650,7 @@
],
"description": "Symfony Console Component",
"homepage": "https://symfony.com",
"time": "2015-06-22 16:34:55"
"time": "2015-07-16 12:22:14"
},
{
"name": "symfony/filesystem",
@@ -530,12 +658,12 @@
"source": {
"type": "git",
"url": "https://github.com/symfony/Filesystem.git",
"reference": "5db575c1ad5f62363c098114cf482bbd5d15349a"
"reference": "9f70c5625a32b2f1e6fc37222f52b4e0eb437b0e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Filesystem/zipball/5db575c1ad5f62363c098114cf482bbd5d15349a",
"reference": "5db575c1ad5f62363c098114cf482bbd5d15349a",
"url": "https://api.github.com/repos/symfony/Filesystem/zipball/9f70c5625a32b2f1e6fc37222f52b4e0eb437b0e",
"reference": "9f70c5625a32b2f1e6fc37222f52b4e0eb437b0e",
"shasum": ""
},
"require": {
@@ -571,7 +699,7 @@
],
"description": "Symfony Filesystem Component",
"homepage": "https://symfony.com",
"time": "2015-06-18 16:14:27"
"time": "2015-07-09 16:11:14"
},
{
"name": "symfony/stopwatch",
@@ -579,12 +707,12 @@
"source": {
"type": "git",
"url": "https://github.com/symfony/Stopwatch.git",
"reference": "a3cf998e50cae3e32e81e401150c7d4b3ecc03d5"
"reference": "cd5f0dc1d3d0e2c83461dad77e20a9186beb6146"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Stopwatch/zipball/a3cf998e50cae3e32e81e401150c7d4b3ecc03d5",
"reference": "a3cf998e50cae3e32e81e401150c7d4b3ecc03d5",
"url": "https://api.github.com/repos/symfony/Stopwatch/zipball/cd5f0dc1d3d0e2c83461dad77e20a9186beb6146",
"reference": "cd5f0dc1d3d0e2c83461dad77e20a9186beb6146",
"shasum": ""
},
"require": {
@@ -620,7 +748,7 @@
],
"description": "Symfony Stopwatch Component",
"homepage": "https://symfony.com",
"time": "2015-06-04 20:21:09"
"time": "2015-07-01 18:24:26"
},
{
"name": "symfony/yaml",
@@ -628,12 +756,12 @@
"source": {
"type": "git",
"url": "https://github.com/symfony/Yaml.git",
"reference": "f248a72777f3fec2bcafdce3ccd94086250448e1"
"reference": "000e7fc2653335cd42c6d21405dac1c74224a387"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Yaml/zipball/f248a72777f3fec2bcafdce3ccd94086250448e1",
"reference": "f248a72777f3fec2bcafdce3ccd94086250448e1",
"url": "https://api.github.com/repos/symfony/Yaml/zipball/000e7fc2653335cd42c6d21405dac1c74224a387",
"reference": "000e7fc2653335cd42c6d21405dac1c74224a387",
"shasum": ""
},
"require": {
@@ -669,7 +797,7 @@
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
"time": "2015-06-19 15:09:14"
"time": "2015-07-01 14:16:54"
}
],
"aliases": [],
@@ -678,7 +806,7 @@
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
"php": ">=5.3"
"php": ">=5.5"
},
"platform-dev": []
}
+74 -59
View File
@@ -3,6 +3,10 @@
namespace InfluxDB;
use InfluxDB\Client\Exception as ClientException;
use InfluxDB\Driver\DriverInterface;
use InfluxDB\Driver\Guzzle;
use InfluxDB\Driver\QueryDriverInterface;
use InfluxDB\Driver\UDP;
/**
* Class Client
@@ -72,6 +76,11 @@ class Client
*/
protected $options = array();
/**
* @var DriverInterface
*/
protected $driver;
/**
* @param string $host
* @param int $port
@@ -80,8 +89,6 @@ class Client
* @param bool $ssl
* @param bool $verifySSL
* @param int $timeout
*
* @todo add UDP support
*/
public function __construct(
$host,
@@ -101,25 +108,22 @@ class Client
if ($ssl) {
$this->scheme = 'https';
$this->options += array('verify' => $verifySSL);
$this->options['verify'] = $verifySSL;
}
// the the base URI
$this->baseURI = sprintf('%s://%s:%d', $this->scheme, $this->host, $this->port);
$this->httpClient = new \Guzzle\Http\Client($this->getBaseURI());
}
/**
* For testing
*
* @param \Guzzle\Http\Client $client
* @return $this
*/
public function setHttpClient(\Guzzle\Http\Client $client)
{
$this->httpClient = $client;
return $this;
// set the default driver to guzzle
$this->driver = new Guzzle(
new \GuzzleHttp\Client(
[
'timeout' => $this->timeout,
'base_uri' => $this->baseURI,
'verify' => $this->verifySSL
]
)
);
}
/**
@@ -142,53 +146,31 @@ class Client
* @return ResultSet
* @throws Exception
*/
public function query($database, $query, $params = array())
public function query($database, $query, $params = [])
{
if (!$this->driver instanceof QueryDriverInterface) {
throw new Exception('The currently configured driver does not support query operations');
}
if ($database) {
$params['db'] = $database;
}
$params = '?' . http_build_query(array_merge(array('q' => $query), $params));
$driver = $this->getDriver();
$options = array_merge($this->options, array('exceptions' => false, 'timeout' => $this->getTimeout()));
$driver->setParameters([
'url' => 'query?' . http_build_query(array_merge(['q' => $query], $params)),
'database' => $database,
'method' => 'get'
]);
try {
$response = $this->httpClient->get('query'.$params, null, $options);
// perform the query and return the resultset
return $driver->query();
$raw = (string) $response->send()->getBody();
return new ResultSet($raw);
} catch (\Exception $e) {
throw new Exception(sprintf('Query has failed, exception: %s', $e->getMessage()));
}
}
/**
* Write points to the database
*
* @param string $database
* @param string $data
* @param string $precision The timestamp precision
* @return bool
* @throws Exception
*
* @internal Internal method, do not use directly
*/
public function write($database, $data, $precision)
{
try {
$result = $this->httpClient->post(
$this->getBaseURI() .
'/write?db=' . $database .
'&precision=' . $precision,
null,
$data,
array('timeout' => $this->getTimeout())
)->send();
return $result->getStatusCode() === 204;
} catch (\Exception $e) {
throw new Exception(sprintf('Writing has failed, exception: %s', $e->getMessage()));
throw new Exception('Query has failed', $e->getCode(), $e);
}
}
@@ -217,12 +199,16 @@ class Client
/**
* Build the client from a dsn
* Example: https+influxdb://username:pass@localhost:8086/databasename', timeout=5
* Examples:
*
* https+influxdb://username:pass@localhost:8086/databasename
* udp+influxdb://username:pass@localhost:4444/databasename
*
* @param string $dsn
* @param int $timeout
* @param bool $verifySSL
* @return Client|Database
*
*@return Client|Database
* @throws ClientException
*/
public static function fromDSN($dsn, $timeout = 0, $verifySSL = false)
@@ -234,12 +220,12 @@ class Client
$scheme = $schemeInfo[0];
if (isset($schemeInfo[1])) {
$modifier = $schemeInfo[0];
$modifier = strtolower($schemeInfo[0]);
$scheme = $schemeInfo[1];
}
if ($scheme != 'influxdb') {
throw new ClientException(sprintf('%s is not a valid scheme', $scheme));
throw new ClientException($scheme . ' is not a valid scheme');
}
$ssl = $modifier === 'https' ? true : false;
@@ -255,6 +241,11 @@ class Client
$timeout
);
// set the UDP driver when the DSN specifies UDP
if ($modifier == 'udp') {
$client->setDriver(new UDP($connParams['host'], $connParams['port']));
}
return ($dbName ? $client->selectDB($dbName) : $client);
}
@@ -275,12 +266,12 @@ class Client
}
/**
* @param array $points
* @param Point[] $points
* @return array
*/
protected function pointsToArray(array $points)
{
$names = array();
$names = [];
foreach ($points as $item) {
$names[] = $item['name'];
@@ -288,4 +279,28 @@ class Client
return $names;
}
/**
* @param Driver\DriverInterface $driver
*/
public function setDriver(DriverInterface $driver)
{
$this->driver = $driver;
}
/**
* @return DriverInterface|QueryDriverInterface
*/
public function getDriver()
{
return $this->driver;
}
/**
* @return string
*/
public function getHost()
{
return $this->host;
}
}
+21 -4
View File
@@ -70,7 +70,7 @@ class Database
* @return ResultSet
* @throws Exception
*/
public function query($query, $params = array())
public function query($query, $params = [])
{
return $this->client->query($this->name, $query, $params);
}
@@ -93,7 +93,9 @@ class Database
}
} catch (\Exception $e) {
throw new DatabaseException(
sprintf('Failed to created database %s, exception: %s', $this->name, $e->getMessage())
sprintf('Failed to created database %s', $this->name),
$e->getCode(),
$e
);
}
}
@@ -124,7 +126,22 @@ class Database
$points
);
return $this->client->write($this->name, implode(PHP_EOL, $payload), $precision);
try {
$driver = $this->client->getDriver();
$driver->setParameters([
'url' => sprintf('write?db=%s&precision=%s', $this->name, $precision),
'database' => $this->name,
'method' => 'post'
]);
// send the points to influxDB
$driver->write(implode(PHP_EOL, $payload));
return $driver->isSuccess();
} catch (\Exception $e) {
throw new Exception('Writing has failed', $e->getCode(), $e);
}
}
/**
@@ -187,7 +204,7 @@ class Database
*/
protected function getRetentionPolicyQuery($method, RetentionPolicy $retentionPolicy)
{
if (!in_array($method, array('CREATE', 'ALTER'))) {
if (!in_array($method, ['CREATE', 'ALTER'])) {
throw new \InvalidArgumentException(sprintf('%s is not a valid method'));
}
+50
View File
@@ -0,0 +1,50 @@
<?php
/**
* @author Stephen "TheCodeAssassin" Hoogendijk
*/
namespace InfluxDB\Driver;
/**
* Interface DriverInterface
*
* @package InfluxDB\Driver
*/
interface DriverInterface
{
/**
* Called by the client write() method, will pass an array of required parameters such as db name
*
* will contain the following parameters:
*
* [
* 'database' => 'name of the database',
* 'url' => 'URL to the resource',
* 'method' => 'HTTP method used'
* ]
*
* @param array $parameters
*
* @return mixed
*/
public function setParameters(array $parameters);
/**
* Send the data
*
* @param $data
*
* @return mixed
*/
public function write($data = null);
/**
* Should return if sending the data was successful
*
* @return bool
*/
public function isSuccess();
}
+16
View File
@@ -0,0 +1,16 @@
<?php
/**
* @author Stephen "TheCodeAssassin" Hoogendijk
*/
namespace InfluxDB\Driver;
/**
* Class Exception
*
* @package InfluxDB\Driver
*/
class Exception extends \InfluxDB\Client\Exception
{
}
+105
View File
@@ -0,0 +1,105 @@
<?php
/**
* @author Stephen "TheCodeAssassin" Hoogendijk
*/
namespace InfluxDB\Driver;
use GuzzleHttp\Client;
use Guzzle\Http\Message\Response;
use GuzzleHttp\Psr7\Request;
use InfluxDB\ResultSet;
/**
* Class Guzzle
*
* @package InfluxDB\Driver
*/
class Guzzle implements DriverInterface, QueryDriverInterface
{
/**
* Array of options
*
* @var array
*/
private $parameters;
/**
* @var Client
*/
private $httpClient;
/**
* @var Response
*/
private $response;
/**
* Set the config for this driver
*
* @param Client $client
*
* @return mixed
*/
public function __construct(Client $client)
{
$this->httpClient = $client;
}
/**
* Called by the client write() method, will pass an array of required parameters such as db name
*
* will contain the following parameters:
*
* [
* 'database' => 'name of the database',
* 'url' => 'URL to the resource',
* 'method' => 'HTTP method used'
* ]
*
* @param array $parameters
*
* @return mixed
*/
public function setParameters(array $parameters)
{
$this->parameters = $parameters;
}
/**
* Send the data
*
* @param $data
*
* @throws Exception
* @return mixed
*/
public function write($data = null)
{
$this->response = $this->httpClient->post($this->parameters['url'], ['body' => $data]);
}
/**
* @return ResultSet
*/
public function query()
{
$response = $this->httpClient->get($this->parameters['url']);
$raw = (string) $response->getBody();
return new ResultSet($raw);
}
/**
* Should return if sending the data was successful
*
* @return bool
*/
public function isSuccess()
{
return in_array($this->response->getStatusCode(), ['200', '204']);
}
}
@@ -0,0 +1,22 @@
<?php
/**
* @author Stephen "TheCodeAssassin" Hoogendijk
*/
namespace InfluxDB\Driver;
use InfluxDB\ResultSet;
/**
* Interface QueryDriverInterface
*
* @package InfluxDB\Driver
*/
interface QueryDriverInterface
{
/**
* @return ResultSet
*/
public function query();
}
+90
View File
@@ -0,0 +1,90 @@
<?php
/**
* @author Stephen "TheCodeAssassin" Hoogendijk
*/
namespace InfluxDB\Driver;
use Symfony\Component\Config\Definition\Exception\Exception;
/**
* Class UDP
*
* @package InfluxDB\Driver
*/
class UDP implements DriverInterface
{
/**
* Parameters
*
* @var array
*/
private $parameters;
/**
* @var array
*/
private $config;
/**
* @param string $host IP/hostname of the InfluxDB host
* @param int $port Port of the InfluxDB process
*/
public function __construct($host, $port)
{
$this->config['host'] = $host;
$this->config['port'] = $port;
}
/**
* Called by the client write() method, will pass an array of required parameters such as db name
*
* will contain the following parameters:
*
* [
* 'database' => 'name of the database',
* 'url' => 'URL to the resource',
* 'method' => 'HTTP method used'
* ]
*
* @param array $parameters
*
* @return mixed
*/
public function setParameters(array $parameters)
{
$this->parameters = $parameters;
}
/**
* Send the data
*
* @param $data
*
* @return mixed
*/
public function write($data = null)
{
$host = sprintf('udp://%s:%d', $this->config['host'], $this->config['port']);
// stream the data using UDP and suppress any errors
$stream = @stream_socket_client($host);
@stream_socket_sendto($stream, $data);
@fclose($stream);
return true;
}
/**
* Should return if sending the data was successful
*
* @return bool
*/
public function isSuccess()
{
return true;
}
}
+7 -5
View File
@@ -19,12 +19,12 @@ class Point
/**
* @var array
*/
private $tags = array();
private $tags = [];
/**
* @var array
*/
private $fields = array();
private $fields = [];
/**
* @var string
@@ -44,7 +44,7 @@ class Point
*/
public function __construct(
$measurement,
$value,
$value = null,
array $tags = array(),
array $additionalFields = array(),
$timestamp = null
@@ -57,7 +57,9 @@ class Point
$this->tags = $tags;
$this->fields = $additionalFields;
$this->fields['value'] = (float) $value;
if ($value) {
$this->fields['value'] = (float) $value;
}
if ($timestamp && !$this->isValidTimeStamp($timestamp)) {
throw new DatabaseException(sprintf('%s is not a valid timestamp', $timestamp));
@@ -96,7 +98,7 @@ class Point
*/
private function arrayToString(array $arr)
{
$strParts = array();
$strParts = [];
foreach ($arr as $key => $value) {
$strParts[] = sprintf('%s=%s', $key, $value);
+4 -4
View File
@@ -15,7 +15,7 @@ class ResultSet
/**
* @var array|mixed
*/
protected $parsedResults = array();
protected $parsedResults = [];
/**
* @param string $raw
@@ -48,7 +48,7 @@ class ResultSet
*/
public function getPoints($metricName = '', array $tags = array())
{
$points = array();
$points = [];
$series = $this->getSeries();
foreach ($series as $serie) {
@@ -81,7 +81,7 @@ class ResultSet
throw new ClientException($object['error']);
}
return isset($object['series']) ? $object['series'] : array();
return isset($object['series']) ? $object['series'] : [];
},
$this->parsedResults['results']
);
@@ -95,7 +95,7 @@ class ResultSet
*/
private function getPointsFromSerie(array $serie)
{
$points = array();
$points = [];
foreach ($serie['values'] as $point) {
$points[] = array_combine($serie['columns'], $point);
+19 -20
View File
@@ -2,22 +2,24 @@
namespace InfluxDB\Test;
use GuzzleHttp\Client as GuzzleClient;
use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Psr7\Response;
use InfluxDB\Client;
use InfluxDB\ResultSet;
use InfluxDB\Driver\Guzzle;
class ClientTest extends \PHPUnit_Framework_TestCase
{
/** @var Client $client */
protected $client = null;
public function testBaseURl()
{
$client = new Client('localhost', 8086);
$this->assertEquals(
$client->getBaseURI(), 'http://localhost:8086'
);
$this->assertEquals($client->getBaseURI(), 'http://localhost:8086');
}
public function testSelectDbShouldReturnDatabaseInstance()
@@ -25,25 +27,25 @@ class ClientTest extends \PHPUnit_Framework_TestCase
$client = new Client('localhost', 8086);
$dbName = 'test-database';
$db = $client->selectDB($dbName);
$database = $client->selectDB($dbName);
$this->assertInstanceOf('\InfluxDB\Database', $db);
$this->assertInstanceOf('\InfluxDB\Database', $database);
$this->assertEquals($dbName, $db->getName());
$this->assertEquals($dbName, $database->getName());
}
/**
*/
public function testQuery()
public function testGuzzleQuery()
{
$client = new Client('localhost', 8086);
$query = "some-bad-query";
$bodyResponse = file_get_contents(dirname(__FILE__) . '/result.example.json');
$httpMockClient = $this->buildHttpMockClient($bodyResponse);
$httpMockClient = self::buildHttpMockClient($bodyResponse);
$client->setHttpClient($httpMockClient);
$client->setDriver(new Guzzle($httpMockClient));
/** @var \InfluxDB\ResultSet $result */
$result = $client->query(null, $query);
@@ -52,17 +54,14 @@ class ClientTest extends \PHPUnit_Framework_TestCase
}
/**
* @return \Guzzle\Http\Client
* @return GuzzleClient
*/
protected function buildHttpMockClient($body)
public static function buildHttpMockClient($body)
{
$plugin = new \Guzzle\Plugin\Mock\MockPlugin();
$response= new \Guzzle\Http\Message\Response(200);
$response->setBody($body);
$plugin->addResponse($response);
$mockedClient = new \Guzzle\Http\Client();
$mockedClient->addSubscriber($plugin);
// Create a mock and queue two responses.
$mock = new MockHandler([new Response(200, array(), $body)]);
return $mockedClient;
$handler = HandlerStack::create($mock);
return new GuzzleClient(['handler' => $handler]);
}
}
+8 -9
View File
@@ -2,9 +2,9 @@
namespace InfluxDB\Test;
use InfluxDB\Client;
use InfluxDB\Database;
use InfluxDB\Driver\Guzzle;
use InfluxDB\Point;
use InfluxDB\ResultSet;
use PHPUnit_Framework_MockObject_MockObject;
@@ -60,6 +60,12 @@ class DatabaseTest extends PHPUnit_Framework_TestCase
->method('listDatabases')
->will($this->returnValue(array('test123', 'test')));
$httpMockClient = new Guzzle(ClientTest::buildHttpMockClient(''));
// make sure the client has a valid driver
$this->mockClient->expects($this->any())
->method('getDriver')
->will($this->returnValue($httpMockClient));
$this->db = new Database('influx_test_db', $this->mockClient);
@@ -133,13 +139,6 @@ class DatabaseTest extends PHPUnit_Framework_TestCase
0.84
);
$payloadExpected ="$point1\n$point2";
$this->mockClient->expects($this->once())
->method('write')
->with($this->equalTo($this->db->getName()), $this->equalTo($payloadExpected))
->will($this->returnValue(true));
$this->db->writePoints(array($point1, $point2));
$this->assertEquals(true, $this->db->writePoints(array($point1, $point2)));
}
}