diff --git a/lib/influxdb-php/.gitignore b/lib/influxdb-php/.gitignore
new file mode 100644
index 0000000000..2826a22d79
--- /dev/null
+++ b/lib/influxdb-php/.gitignore
@@ -0,0 +1,6 @@
+# Created by .gitignore support plugin (hsz.mobi)
+
+vendor/
+.idea
+build/
+test.php
\ No newline at end of file
diff --git a/lib/influxdb-php/.travis.yml b/lib/influxdb-php/.travis.yml
new file mode 100644
index 0000000000..c71c55677b
--- /dev/null
+++ b/lib/influxdb-php/.travis.yml
@@ -0,0 +1,14 @@
+language: php
+php:
+ - 5.5
+ - 5.6
+
+install:
+ - composer install
+
+addons:
+ code_climate:
+ repo_token: 5371d86d298d66eb9007cc8de462d7063e58f6dd85e430928834736edee479a9
+
+after_script:
+ - vendor/bin/test-reporter
diff --git a/lib/influxdb-php/CONTRIBUTE.md b/lib/influxdb-php/CONTRIBUTE.md
new file mode 100644
index 0000000000..d9348f142d
--- /dev/null
+++ b/lib/influxdb-php/CONTRIBUTE.md
@@ -0,0 +1,50 @@
+/* CONTRIBUTE */
+
+This is the contribute.md of influxdb-php. Great to have you here.
+
+Here are a few ways you can help make this project better.
+
+# Contribute.md
+
+## Team members
+
+* Stephen "TheCodeAssassin" Hoogendijk
+* Daniel "danibrutal" Martinez
+
+## Helping out
+
+We appreciate any efforts to help us writing this library. You can contribute in any of the following ways:
+
+* Documentation
+* Unit tests
+* New features
+* Bug fixed
+* Reviewing pull requests
+
+## Guidelines
+
+In order for your pull requests to get accepted we hold all the code to the following criteria:
+
+* PSR-1/PSR-2 compliant
+* 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
\ No newline at end of file
diff --git a/lib/influxdb-php/LICENSE b/lib/influxdb-php/LICENSE
new file mode 100644
index 0000000000..38ee24919e
--- /dev/null
+++ b/lib/influxdb-php/LICENSE
@@ -0,0 +1,20 @@
+The MIT License (MIT)
+
+Copyright (c) 2013 InfluxDB
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/lib/influxdb-php/README.md b/lib/influxdb-php/README.md
new file mode 100644
index 0000000000..06f60943af
--- /dev/null
+++ b/lib/influxdb-php/README.md
@@ -0,0 +1,341 @@
+# influxdb-php
+## InfluxDB client library for PHP
+[](https://travis-ci.org/influxdb/influxdb-php)
+[](https://codeclimate.com/github/influxdb/influxdb-php)
+[](https://codeclimate.com/github/influxdb/influxdb-php/coverage)
+
+### Overview
+
+A easy to use library for using InfluxDB with PHP.
+
+The influxdb-php library was created to have php port of the python influxdb client.
+This way there will be a common abstraction library between different programming languages.
+
+### Installation
+
+Installation can be done with composer:
+
+composer require influxdb/influxdb-php:dev-master
+
+### NOTE for PHP 5.3 and PHP 5.4 users
+
+If you use either PHP 5.3 and PHP 5.4, the 0.1.x release is still supported (bug fixes and new release fixes).
+The 0.1.x branch will work on PHP 5.3 and PHP 5.4 but doesn't contain all the features that the 1.0.0 release has such as UDP support.
+
+### Getting started
+
+Initialize a new client object:
+
+```php
+
+$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 (Data Source Name):
+
+```php
+
+ // directly get the database object
+ $database = InfluxDB\Client::fromDSN(sprintf('influxdb://user:pass@%s:%s/%s', $host, $port, $dbname));
+
+ // get the client to retrieve other databases
+ $client = $database->getClient();
+
+```
+
+### Reading
+
+To fetch records from InfluxDB you can do a query directly on a database:
+
+```php
+
+ // fetch the database
+ $database = $client->selectDB('influx_test_db');
+
+ // executing a query will yield a resultset object
+ $result = $database->query('select * from test_metric LIMIT 5');
+
+ // get the points from the resultset yields an array
+ $points = $result->getPoints();
+
+```
+
+It's also possible to use the QueryBuilder object. This is a class that simplifies the process of building queries.
+
+```php
+
+ // retrieve points with the query builder
+ $result = $database->getQueryBuilder()
+ ->select('cpucount')
+ ->from('test_metric')
+ ->limit(2)
+ ->getResultSet()
+ ->getPoints();
+
+
+ // get the query from the QueryBuilder
+ $query = $database->getQueryBuilder()
+ ->select('cpucount')
+ ->from('test_metric')
+ ->getQuery();
+
+```
+
+### Writing data
+
+Writing data is done by providing an array of points to the writePoints method on a database:
+
+```php
+
+ // create an array of points
+ $points = array(
+ new Point(
+ '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', // 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
+ $result = $database->writePoints($points, Database::PRECISION_SECONDS);
+
+```
+
+It's possible to add multiple [fields](https://influxdb.com/docs/v0.9/concepts/key_concepts.html) when writing
+measurements to InfluxDB. The point class allows one to easily write data in batches to influxDB.
+
+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
+if you specify a timestamp in seconds and the default (nanosecond) precision is set; the entered timestamp will be invalid.
+
+```php
+ // Points will require a nanosecond precision (this is default as per influxdb standard)
+ $newPoints = $database->writePoints($points);
+
+ // Points will require second precision
+ $newPoints = $database->writePoints($points, Database::PRECISION_SECONDS);
+
+ // Points will require microsecond precision
+ $newPoints = $database->writePoints($points, Database::PRECISION_MICROSECONDS);
+```
+
+### Creating databases
+
+When creating a database a default retention policy is added. This retention policy does not have a duration
+so the data will be flushed with the memory.
+
+This library makes it easy to provide a retention policy when creating a database:
+
+```php
+
+ // create the client
+ $client = new \InfluxDB\Client($host, $port, '', '');
+
+ // select the database
+ $database = $client->selectDB('influx_test_db');
+
+ // create the database with a retention policy
+ $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));
+ }
+
+```
+
+You can also alter retention policies:
+
+```php
+ $database->alterRetentionPolicy(new RetentionPolicy('test', '2d', 5, true));
+```
+
+and list them:
+
+```php
+ $result = $database->listRetentionPolicies();
+```
+
+You can add more retention policies to a database:
+
+```php
+ $result = $database->createRetentionPolicy(new RetentionPolicy('test2', '30d', 1, true));
+```
+
+### Client functions
+
+Some functions are too general for a database. So these are available in the client:
+
+```php
+
+ // list users
+ $result = $client->listUsers();
+
+ // list databases
+ $result = $client->listDatabases();
+```
+
+### Admin functionality
+
+You can use the client's $client->admin functionality to administer InfluxDB via the API.
+
+```php
+ // add a new user without privileges
+ $client->admin->createUser('testuser123', 'testpassword');
+
+ // add a new user with ALL cluster-wide privileges
+ $client->admin->createUser('admin_user', 'password', \InfluxDB\Client\Admin::PRIVILEGE_ALL);
+
+ // drop user testuser123
+ $client->admin->dropUser('testuser123');
+```
+
+List all the users:
+
+```php
+ // show a list of all users
+ $results = $client->admin->showUsers();
+
+ // show users returns a ResultSet object
+ $users = $results->getPoints();
+```
+
+#### Granting and revoking privileges
+
+Granting permissions can be done on both the database level and cluster-wide.
+To grant a user specific privileges on a database, provide a database object or a database name.
+
+```php
+
+ // grant permissions using a database object
+ $database = $client->selectDB('test_db');
+ $client->admin->grant(\InfluxDB\Client\Admin::PRIVILEGE_READ, 'testuser123', $database);
+
+ // give user testuser123 read privileges on database test_db
+ $client->admin->grant(\InfluxDB\Client\Admin::PRIVILEGE_READ, 'testuser123', 'test_db');
+
+ // revoke user testuser123's read privileges on database test_db
+ $client->admin->revoke(\InfluxDB\Client\Admin::PRIVILEGE_READ, 'testuser123', 'test_db');
+
+ // grant a user cluster-wide privileges
+ $client->admin->grant(\InfluxDB\Client\Admin::PRIVILEGE_READ, 'testuser123');
+
+ // Revoke an admin's cluster-wide privileges
+ $client->admin->revoke(\InfluxDB\Client\Admin::PRIVILEGE_ALL, 'admin_user');
+
+```
+
+## Todo
+
+* More unit tests
+* Increase documentation (wiki?)
+* Add more features to the query builder
+* Add validation to RetentionPolicy
+
+
+## Changelog
+
+####1.0.1
+* Added support for authentication in the guzzle driver
+* Added admin functionality
+
+####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
+
+####0.1.1
+* Merged repository to influxdb/influxdb-php
+* Added unit test for createRetentionPolicy
+* -BREAKING CHANGE- changed $client->db to $client->selectDB
diff --git a/lib/influxdb-php/composer.json b/lib/influxdb-php/composer.json
new file mode 100644
index 0000000000..7af0fafe8f
--- /dev/null
+++ b/lib/influxdb-php/composer.json
@@ -0,0 +1,47 @@
+{
+ "name": "influxdb/influxdb-php",
+ "description": "InfluxDB client library for PHP",
+ "license": "MIT",
+ "keywords": [
+ "influxdb",
+ "client",
+ "time series",
+ "influxdb client",
+ "influxdb class",
+ "influxdb library"
+ ],
+ "minimum-stability": "dev",
+ "authors": [
+ {
+ "name": "Stephen Hoogendijk",
+ "email": "stephen@tca0.nl"
+ },
+ {
+ "name": "Daniel Martinez",
+ "email": "danimartcas@hotmail.com"
+ }
+ ],
+ "require": {
+ "php": ">=5.5",
+ "guzzlehttp/guzzle": "6.*",
+ "symfony/event-dispatcher": "2.*"
+ },
+ "require-dev": {
+ "codeclimate/php-test-reporter": "0.*",
+ "symfony/config": "~2.8",
+ "symfony/console": "~2.8",
+ "symfony/filesystem": "~2.8",
+ "symfony/stopwatch": "~2.8",
+ "symfony/yaml": "~2.8"
+ },
+ "autoload": {
+ "psr-4": {
+ "InfluxDB\\": "src/InfluxDB"
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "InfluxDB\\Test\\": "tests"
+ }
+ }
+}
diff --git a/lib/influxdb-php/composer.lock b/lib/influxdb-php/composer.lock
new file mode 100644
index 0000000000..a2fb5ba284
--- /dev/null
+++ b/lib/influxdb-php/composer.lock
@@ -0,0 +1,812 @@
+{
+ "_readme": [
+ "This file locks the dependencies of your project to a known state",
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
+ "This file is @generated automatically"
+ ],
+ "hash": "ee3f2e2a4eb50f8de36c6efbff37fe71",
+ "packages": [
+ {
+ "name": "guzzlehttp/guzzle",
+ "version": "dev-master",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/guzzle/guzzle.git",
+ "reference": "1879fbe853b0c64d109e369c7aeff09849e62d1e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/guzzle/guzzle/zipball/1879fbe853b0c64d109e369c7aeff09849e62d1e",
+ "reference": "1879fbe853b0c64d109e369c7aeff09849e62d1e",
+ "shasum": ""
+ },
+ "require": {
+ "guzzlehttp/promises": "~1.0",
+ "guzzlehttp/psr7": "~1.1",
+ "php": ">=5.5.0"
+ },
+ "require-dev": {
+ "ext-curl": "*",
+ "phpunit/phpunit": "~4.0",
+ "psr/log": "~1.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "6.0-dev"
+ }
+ },
+ "autoload": {
+ "files": [
+ "src/functions_include.php"
+ ],
+ "psr-4": {
+ "GuzzleHttp\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ }
+ ],
+ "description": "Guzzle is a PHP HTTP client library",
+ "homepage": "http://guzzlephp.org/",
+ "keywords": [
+ "client",
+ "curl",
+ "framework",
+ "http",
+ "http client",
+ "rest",
+ "web service"
+ ],
+ "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",
+ "version": "2.8.x-dev",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/EventDispatcher.git",
+ "reference": "d7246885b7fe4cb5a2786bda34362d2f0e40b730"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/d7246885b7fe4cb5a2786bda34362d2f0e40b730",
+ "reference": "d7246885b7fe4cb5a2786bda34362d2f0e40b730",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.9"
+ },
+ "require-dev": {
+ "psr/log": "~1.0",
+ "symfony/config": "~2.0,>=2.0.5|~3.0.0",
+ "symfony/dependency-injection": "~2.6|~3.0.0",
+ "symfony/expression-language": "~2.6|~3.0.0",
+ "symfony/phpunit-bridge": "~2.7|~3.0.0",
+ "symfony/stopwatch": "~2.3|~3.0.0"
+ },
+ "suggest": {
+ "symfony/dependency-injection": "",
+ "symfony/http-kernel": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.8-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\EventDispatcher\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony EventDispatcher Component",
+ "homepage": "https://symfony.com",
+ "time": "2015-06-24 15:32:32"
+ }
+ ],
+ "packages-dev": [
+ {
+ "name": "codeclimate/php-test-reporter",
+ "version": "dev-master",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/codeclimate/php-test-reporter.git",
+ "reference": "418ae782307841ac50fe26daa4cfe04520b0de9c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/codeclimate/php-test-reporter/zipball/418ae782307841ac50fe26daa4cfe04520b0de9c",
+ "reference": "418ae782307841ac50fe26daa4cfe04520b0de9c",
+ "shasum": ""
+ },
+ "require": {
+ "ext-curl": "*",
+ "php": ">=5.3",
+ "satooshi/php-coveralls": "0.6.*",
+ "symfony/console": ">=2.0"
+ },
+ "require-dev": {
+ "ext-xdebug": "*",
+ "phpunit/phpunit": "3.7.*@stable"
+ },
+ "bin": [
+ "composer/bin/test-reporter"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "0.1.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "CodeClimate\\Component": "src/",
+ "CodeClimate\\Bundle": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Code Climate",
+ "email": "hello@codeclimate.com",
+ "homepage": "https://codeclimate.com"
+ }
+ ],
+ "description": "PHP client for reporting test coverage to Code Climate",
+ "homepage": "https://github.com/codeclimate/php-test-reporter",
+ "keywords": [
+ "codeclimate",
+ "coverage"
+ ],
+ "time": "2015-04-18 14:43:54"
+ },
+ {
+ "name": "guzzle/guzzle",
+ "version": "dev-master",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/guzzle/guzzle3.git",
+ "reference": "b3f5050cb6270c7a728a0b74ac2de50a262b3e02"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/guzzle/guzzle3/zipball/b3f5050cb6270c7a728a0b74ac2de50a262b3e02",
+ "reference": "b3f5050cb6270c7a728a0b74ac2de50a262b3e02",
+ "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"
+ },
+ "require-dev": {
+ "doctrine/cache": "~1.3",
+ "monolog/monolog": "~1.0",
+ "phpunit/phpunit": "3.7.*",
+ "psr/log": "~1.0",
+ "symfony/class-loader": "~2.1",
+ "zendframework/zend-cache": "2.*,<2.3",
+ "zendframework/zend-log": "2.*,<2.3"
+ },
+ "suggest": {
+ "guzzlehttp/guzzle": "Guzzle 5 has moved to a new package name. The package you have installed, Guzzle 3, is deprecated."
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.9-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Guzzle": "src/",
+ "Guzzle\\Tests": "tests/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ },
+ {
+ "name": "Guzzle Community",
+ "homepage": "https://github.com/guzzle/guzzle/contributors"
+ }
+ ],
+ "description": "PHP HTTP client. This library is deprecated in favor of https://packagist.org/packages/guzzlehttp/guzzle",
+ "homepage": "http://guzzlephp.org/",
+ "keywords": [
+ "client",
+ "curl",
+ "framework",
+ "http",
+ "http client",
+ "rest",
+ "web service"
+ ],
+ "time": "2015-04-29 17:06:53"
+ },
+ {
+ "name": "psr/log",
+ "version": "1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/log.git",
+ "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b",
+ "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b",
+ "shasum": ""
+ },
+ "type": "library",
+ "autoload": {
+ "psr-0": {
+ "Psr\\Log\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for logging libraries",
+ "keywords": [
+ "log",
+ "psr",
+ "psr-3"
+ ],
+ "time": "2012-12-21 11:40:51"
+ },
+ {
+ "name": "satooshi/php-coveralls",
+ "version": "v0.6.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/satooshi/php-coveralls.git",
+ "reference": "dd0df95bd37a7cf5c5c50304dfe260ffe4b50760"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/satooshi/php-coveralls/zipball/dd0df95bd37a7cf5c5c50304dfe260ffe4b50760",
+ "reference": "dd0df95bd37a7cf5c5c50304dfe260ffe4b50760",
+ "shasum": ""
+ },
+ "require": {
+ "ext-curl": "*",
+ "ext-json": "*",
+ "ext-simplexml": "*",
+ "guzzle/guzzle": ">=3.0",
+ "php": ">=5.3",
+ "psr/log": "1.0.0",
+ "symfony/config": ">=2.0",
+ "symfony/console": ">=2.0",
+ "symfony/stopwatch": ">=2.2",
+ "symfony/yaml": ">=2.0"
+ },
+ "require-dev": {
+ "apigen/apigen": "2.8.*@stable",
+ "pdepend/pdepend": "dev-master",
+ "phpmd/phpmd": "dev-master",
+ "phpunit/php-invoker": ">=1.1.0,<1.2.0",
+ "phpunit/phpunit": "3.7.*@stable",
+ "sebastian/finder-facade": "dev-master",
+ "sebastian/phpcpd": "1.4.*@stable",
+ "squizlabs/php_codesniffer": "1.4.*@stable",
+ "theseer/fdomdocument": "dev-master"
+ },
+ "bin": [
+ "composer/bin/coveralls"
+ ],
+ "type": "library",
+ "autoload": {
+ "psr-0": {
+ "Contrib\\Component": "src/",
+ "Contrib\\Bundle": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Kitamura Satoshi",
+ "email": "with.no.parachute@gmail.com",
+ "homepage": "https://www.facebook.com/satooshi.jp"
+ }
+ ],
+ "description": "PHP client library for Coveralls API",
+ "homepage": "https://github.com/satooshi/php-coveralls",
+ "keywords": [
+ "ci",
+ "coverage",
+ "github",
+ "test"
+ ],
+ "time": "2013-05-04 08:07:33"
+ },
+ {
+ "name": "symfony/config",
+ "version": "2.8.x-dev",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/Config.git",
+ "reference": "358ec929e494b6f12d8508d88357cbd7383a10ca"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/Config/zipball/358ec929e494b6f12d8508d88357cbd7383a10ca",
+ "reference": "358ec929e494b6f12d8508d88357cbd7383a10ca",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.9",
+ "symfony/filesystem": "~2.3|~3.0.0"
+ },
+ "require-dev": {
+ "symfony/phpunit-bridge": "~2.7|~3.0.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.8-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Config\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Config Component",
+ "homepage": "https://symfony.com",
+ "time": "2015-07-09 16:11:14"
+ },
+ {
+ "name": "symfony/console",
+ "version": "2.8.x-dev",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/Console.git",
+ "reference": "fd85e7517e79a2bceafcee8f7e8b7bbd0919a90a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/Console/zipball/fd85e7517e79a2bceafcee8f7e8b7bbd0919a90a",
+ "reference": "fd85e7517e79a2bceafcee8f7e8b7bbd0919a90a",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.9"
+ },
+ "require-dev": {
+ "psr/log": "~1.0",
+ "symfony/event-dispatcher": "~2.1|~3.0.0",
+ "symfony/phpunit-bridge": "~2.7|~3.0.0",
+ "symfony/process": "~2.1|~3.0.0"
+ },
+ "suggest": {
+ "psr/log": "For using the console logger",
+ "symfony/event-dispatcher": "",
+ "symfony/process": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.8-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Console\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Console Component",
+ "homepage": "https://symfony.com",
+ "time": "2015-07-16 12:22:14"
+ },
+ {
+ "name": "symfony/filesystem",
+ "version": "2.8.x-dev",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/Filesystem.git",
+ "reference": "9f70c5625a32b2f1e6fc37222f52b4e0eb437b0e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/Filesystem/zipball/9f70c5625a32b2f1e6fc37222f52b4e0eb437b0e",
+ "reference": "9f70c5625a32b2f1e6fc37222f52b4e0eb437b0e",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.9"
+ },
+ "require-dev": {
+ "symfony/phpunit-bridge": "~2.7|~3.0.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.8-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Filesystem\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Filesystem Component",
+ "homepage": "https://symfony.com",
+ "time": "2015-07-09 16:11:14"
+ },
+ {
+ "name": "symfony/stopwatch",
+ "version": "2.8.x-dev",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/Stopwatch.git",
+ "reference": "cd5f0dc1d3d0e2c83461dad77e20a9186beb6146"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/Stopwatch/zipball/cd5f0dc1d3d0e2c83461dad77e20a9186beb6146",
+ "reference": "cd5f0dc1d3d0e2c83461dad77e20a9186beb6146",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.9"
+ },
+ "require-dev": {
+ "symfony/phpunit-bridge": "~2.7|~3.0.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.8-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Stopwatch\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Stopwatch Component",
+ "homepage": "https://symfony.com",
+ "time": "2015-07-01 18:24:26"
+ },
+ {
+ "name": "symfony/yaml",
+ "version": "2.8.x-dev",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/Yaml.git",
+ "reference": "000e7fc2653335cd42c6d21405dac1c74224a387"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/Yaml/zipball/000e7fc2653335cd42c6d21405dac1c74224a387",
+ "reference": "000e7fc2653335cd42c6d21405dac1c74224a387",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.9"
+ },
+ "require-dev": {
+ "symfony/phpunit-bridge": "~2.7|~3.0.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.8-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Yaml\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Yaml Component",
+ "homepage": "https://symfony.com",
+ "time": "2015-07-01 14:16:54"
+ }
+ ],
+ "aliases": [],
+ "minimum-stability": "dev",
+ "stability-flags": [],
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": {
+ "php": ">=5.5"
+ },
+ "platform-dev": []
+}
diff --git a/lib/influxdb-php/phpunit.xml b/lib/influxdb-php/phpunit.xml
new file mode 100644
index 0000000000..9913a0eda8
--- /dev/null
+++ b/lib/influxdb-php/phpunit.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ tests
+
+
+
+
+ src/
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/influxdb-php/src/InfluxDB/Client.php b/lib/influxdb-php/src/InfluxDB/Client.php
new file mode 100644
index 0000000000..b724c63f04
--- /dev/null
+++ b/lib/influxdb-php/src/InfluxDB/Client.php
@@ -0,0 +1,324 @@
+host = (string) $host;
+ $this->port = (int) $port;
+ $this->username = (string) $username;
+ $this->password = (string) $password;
+ $this->timeout = (int) $timeout;
+ $this->verifySSL = (bool) $verifySSL;
+
+ if ($ssl) {
+ $this->scheme = 'https';
+ $this->options['verify'] = $verifySSL;
+ }
+
+ // the the base URI
+ $this->baseURI = sprintf('%s://%s:%d', $this->scheme, $this->host, $this->port);
+
+ // set the default driver to guzzle
+ $this->driver = new Guzzle(
+ new \GuzzleHttp\Client(
+ [
+ 'timeout' => $this->timeout,
+ 'base_uri' => $this->baseURI,
+ 'verify' => $this->verifySSL
+ ]
+ )
+ );
+
+ $this->admin = new Admin($this);
+ }
+
+ /**
+ * Use the given database
+ *
+ * @param string $name
+ * @return Database
+ */
+ public function selectDB($name)
+ {
+ return new Database($name, $this);
+ }
+
+ /**
+ * Query influxDB
+ *
+ * @param string $database
+ * @param string $query
+ * @param array $parameters
+ *
+ * @return ResultSet
+ * @throws Exception
+ */
+ public function query($database, $query, $parameters = [])
+ {
+
+ if (!$this->driver instanceof QueryDriverInterface) {
+ throw new Exception('The currently configured driver does not support query operations');
+ }
+
+ if ($database) {
+ $parameters['db'] = $database;
+ }
+
+ $driver = $this->getDriver();
+
+ $parameters = [
+ 'url' => 'query?' . http_build_query(array_merge(['q' => $query], $parameters)),
+ 'database' => $database,
+ 'method' => 'get'
+ ];
+
+ // add authentication to the driver if needed
+ if (!empty($this->username) && !empty($this->password)) {
+ $parameters += ['auth' => [$this->username, $this->password]];
+ }
+
+ $driver->setParameters($parameters);
+
+ try {
+ // perform the query and return the resultset
+ return $driver->query();
+
+ } catch (DriverException $e) {
+ throw new Exception('Query has failed', $e->getCode(), $e);
+ }
+ }
+
+ /**
+ * List all the databases
+ */
+ public function listDatabases()
+ {
+ $result = $this->query(null, 'SHOW DATABASES')->getPoints();
+
+ return $this->pointsToArray($result);
+ }
+
+ /**
+ * List all the users
+ *
+ * @return array
+ * @throws Exception
+ */
+ public function listUsers()
+ {
+ $result = $this->query(null, 'SHOW USERS')->getPoints();
+
+ return $this->pointsToArray($result);
+ }
+
+ /**
+ * Build the client from a dsn
+ * 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
+ * @throws ClientException
+ */
+ public static function fromDSN($dsn, $timeout = 0, $verifySSL = false)
+ {
+ $connParams = parse_url($dsn);
+ $schemeInfo = explode('+', $connParams['scheme']);
+ $dbName = null;
+ $modifier = null;
+ $scheme = $schemeInfo[0];
+
+ if (isset($schemeInfo[1])) {
+ $modifier = strtolower($schemeInfo[0]);
+ $scheme = $schemeInfo[1];
+ }
+
+ if ($scheme != 'influxdb') {
+ throw new ClientException($scheme . ' is not a valid scheme');
+ }
+
+ $ssl = $modifier === 'https' ? true : false;
+ $dbName = $connParams['path'] ? substr($connParams['path'], 1) : null;
+
+ $client = new self(
+ $connParams['host'],
+ $connParams['port'],
+ $connParams['user'],
+ $connParams['pass'],
+ $ssl,
+ $verifySSL,
+ $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);
+ }
+
+ /**
+ * @return mixed
+ */
+ public function getBaseURI()
+ {
+ return $this->baseURI;
+ }
+
+ /**
+ * @return int
+ */
+ public function getTimeout()
+ {
+ return $this->timeout;
+ }
+
+ /**
+ * @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;
+ }
+
+ /**
+ * @param Point[] $points
+ * @return array
+ */
+ protected function pointsToArray(array $points)
+ {
+ $names = [];
+
+ foreach ($points as $item) {
+ $names[] = $item['name'];
+ }
+
+ return $names;
+ }
+
+}
diff --git a/lib/influxdb-php/src/InfluxDB/Client/Admin.php b/lib/influxdb-php/src/InfluxDB/Client/Admin.php
new file mode 100644
index 0000000000..b62782a38c
--- /dev/null
+++ b/lib/influxdb-php/src/InfluxDB/Client/Admin.php
@@ -0,0 +1,158 @@
+client = $client;
+ }
+
+ /**
+ * Create a user
+ *
+ * @param string $username
+ * @param string $password
+ *
+ * @param string $privilege
+ *
+ * @throws \InfluxDB\Exception
+ * @return \InfluxDB\ResultSet
+ */
+ public function createUser($username, $password, $privilege = null)
+ {
+ $query = sprintf('CREATE USER %s WITH PASSWORD \'%s\'', $username, $password);
+
+ if ($privilege) {
+ $query .= " WITH $privilege PRIVILEGES";
+ }
+
+ return $this->client->query(null, $query);
+ }
+
+ /**
+ * @param string $username
+ *
+ * @return \InfluxDB\ResultSet
+ * @throws \InfluxDB\Exception
+ */
+ public function dropUser($username)
+ {
+ return $this->client->query(null, 'DROP USER ' . $username);
+ }
+
+ /**
+ * Change a users password
+ *
+ * @param string $username
+ * @param string $newPassword
+ *
+ * @return \InfluxDB\ResultSet
+ * @throws \InfluxDB\Exception
+ */
+ public function changeUserPassword($username, $newPassword)
+ {
+ return $this->client->query(null, "SET PASSWORD FOR $username = '$newPassword'");
+ }
+
+ /**
+ * Shows a list of all the users
+ *
+ * @return \InfluxDB\ResultSet
+ * @throws \InfluxDB\Exception
+ */
+ public function showUsers()
+ {
+ return $this->client->query(null, "SHOW USERS");
+ }
+
+ /**
+ * Grants permissions
+ *
+ * @param string $privilege
+ * @param string $username
+ * @param Database|string $database
+ *
+ * @return \InfluxDB\ResultSet
+ */
+ public function grant($privilege, $username, $database = null)
+ {
+ return $this->executePrivilege('GRANT', $privilege, $username, $database);
+ }
+
+ /**
+ * Revokes permissions
+ *
+ * @param string $privilege
+ * @param string $username
+ * @param Database|string $database
+ *
+ * @throws \InfluxDB\Exception
+ * @return \InfluxDB\ResultSet
+ */
+ public function revoke($privilege, $username, $database = null)
+ {
+ return $this->executePrivilege('REVOKE', $privilege, $username, $database);
+ }
+
+ /**
+ * @param string $type
+ * @param string $privilege
+ * @param string $username
+ * @param Database|string $database
+ *
+ * @throws \InfluxDB\Exception
+ * @return \InfluxDB\ResultSet
+ */
+ private function executePrivilege($type, $privilege, $username, $database = null)
+ {
+
+ if (!in_array($privilege, [self::PRIVILEGE_READ, self::PRIVILEGE_WRITE, self::PRIVILEGE_ALL])) {
+ throw new Exception($privilege . ' is not a valid privileges, allowed privileges: READ, WRITE, ALL');
+ }
+
+ if ($privilege != self::PRIVILEGE_ALL && !$database) {
+ throw new Exception('Only grant ALL cluster-wide privileges are allowed');
+ }
+
+ $database = ($database instanceof Database ? $database->getName() : (string) $database);
+
+ $query = "$type $privilege";
+
+ if ($database) {
+ $query .= sprintf(' ON %s ', $database);
+ } else {
+ $query .= " PRIVILEGES ";
+ }
+
+ if ($username && $type == 'GRANT') {
+ $query .= "TO $username";
+ } elseif ($username && $type == 'REVOKE') {
+ $query .= "FROM $username";
+ }
+
+ return $this->client->query(null, $query);
+ }
+}
\ No newline at end of file
diff --git a/lib/influxdb-php/src/InfluxDB/Client/Exception.php b/lib/influxdb-php/src/InfluxDB/Client/Exception.php
new file mode 100644
index 0000000000..0674e86868
--- /dev/null
+++ b/lib/influxdb-php/src/InfluxDB/Client/Exception.php
@@ -0,0 +1,12 @@
+name = (string) $name;
+ $this->client = $client;
+ }
+
+ /**
+ * @return string
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * Query influxDB
+ *
+ * @param string $query
+ * @param array $params
+ * @return ResultSet
+ * @throws Exception
+ */
+ public function query($query, $params = [])
+ {
+ return $this->client->query($this->name, $query, $params);
+ }
+
+ /**
+ * Create this database
+ *
+ * @param RetentionPolicy $retentionPolicy
+ * @return ResultSet
+ * @throws DatabaseException
+ * @throws Exception
+ */
+ public function create(RetentionPolicy $retentionPolicy = null)
+ {
+ try {
+ $this->query(sprintf('CREATE DATABASE %s', $this->name));
+
+ if ($retentionPolicy) {
+ $this->createRetentionPolicy($retentionPolicy);
+ }
+ } catch (\Exception $e) {
+ throw new DatabaseException(
+ sprintf('Failed to created database %s', $this->name),
+ $e->getCode(),
+ $e
+ );
+ }
+ }
+
+ /**
+ * @param RetentionPolicy $retentionPolicy
+ * @return ResultSet
+ */
+ public function createRetentionPolicy(RetentionPolicy $retentionPolicy)
+ {
+ return $this->query($this->getRetentionPolicyQuery('CREATE', $retentionPolicy));
+ }
+
+ /**
+ * Writes points into InfluxDB
+ *
+ * @param Point[] $points Array of points
+ * @param string $precision The timestamp precision (defaults to nanoseconds)
+ * @return bool
+ * @throws Exception
+ */
+ public function writePoints(array $points, $precision = self::PRECISION_NANOSECONDS)
+ {
+ $payload = array_map(
+ function (Point $point) {
+ return (string) $point;
+ },
+ $points
+ );
+
+ try {
+ $driver = $this->client->getDriver();
+
+ $parameters = [
+ 'url' => sprintf('write?db=%s&precision=%s', $this->name, $precision),
+ 'database' => $this->name,
+ 'method' => 'post'
+ ];
+
+ // add authentication to the driver if needed
+ if (!empty($this->username) && !empty($this->password)) {
+ $parameters += ['auth' => [$this->username, $this->password]];
+ }
+
+ $driver->setParameters($parameters);
+
+ // send the points to influxDB
+ $driver->write(implode(PHP_EOL, $payload));
+
+ return $driver->isSuccess();
+
+ } catch (\Exception $e) {
+ throw new Exception($e->getMessage(), $e->getCode());
+ }
+ }
+
+ /**
+ * @return bool
+ */
+ public function exists()
+ {
+ $databases = $this->client->listDatabases();
+
+ return in_array($this->name, $databases);
+ }
+
+ /**
+ * @param RetentionPolicy $retentionPolicy
+ */
+ public function alterRetentionPolicy(RetentionPolicy $retentionPolicy)
+ {
+ $this->query($this->getRetentionPolicyQuery('ALTER', $retentionPolicy));
+ }
+
+ /**
+ * @return array
+ * @throws Exception
+ */
+ public function listRetentionPolicies()
+ {
+ return $this->query(sprintf('SHOW RETENTION POLICIES %s', $this->name))->getPoints();
+ }
+
+ /**
+ * Drop this database
+ */
+ public function drop()
+ {
+ $this->query(sprintf('DROP DATABASE %s', $this->name));
+ }
+
+ /**
+ * Retrieve the query builder
+ *
+ * @return QueryBuilder
+ */
+ public function getQueryBuilder()
+ {
+ return new QueryBuilder($this);
+ }
+
+ /**
+ * @return Client
+ */
+ public function getClient()
+ {
+ return $this->client;
+ }
+
+ /**
+ * @param string $method
+ * @param RetentionPolicy $retentionPolicy
+ * @return string
+ */
+ protected function getRetentionPolicyQuery($method, RetentionPolicy $retentionPolicy)
+ {
+ if (!in_array($method, ['CREATE', 'ALTER'])) {
+ throw new \InvalidArgumentException(sprintf('%s is not a valid method'));
+ }
+
+ $query = sprintf(
+ '%s RETENTION POLICY %s ON %s DURATION %s REPLICATION %s',
+ $method,
+ $retentionPolicy->name,
+ $this->name,
+ $retentionPolicy->duration,
+ $retentionPolicy->replication
+ );
+
+ if ($retentionPolicy->default) {
+ $query .= " DEFAULT";
+ }
+
+ return $query;
+ }
+}
diff --git a/lib/influxdb-php/src/InfluxDB/Database/Exception.php b/lib/influxdb-php/src/InfluxDB/Database/Exception.php
new file mode 100644
index 0000000000..f5142b49ea
--- /dev/null
+++ b/lib/influxdb-php/src/InfluxDB/Database/Exception.php
@@ -0,0 +1,10 @@
+name = (string) $name;
+ $this->duration = $duration;
+ $this->replication = (int) $replication;
+ $this->default = (bool) $default;
+ }
+}
diff --git a/lib/influxdb-php/src/InfluxDB/Driver/DriverInterface.php b/lib/influxdb-php/src/InfluxDB/Driver/DriverInterface.php
new file mode 100644
index 0000000000..fc3a2c2f96
--- /dev/null
+++ b/lib/influxdb-php/src/InfluxDB/Driver/DriverInterface.php
@@ -0,0 +1,49 @@
+ '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();
+
+}
diff --git a/lib/influxdb-php/src/InfluxDB/Driver/Exception.php b/lib/influxdb-php/src/InfluxDB/Driver/Exception.php
new file mode 100644
index 0000000000..237766eeef
--- /dev/null
+++ b/lib/influxdb-php/src/InfluxDB/Driver/Exception.php
@@ -0,0 +1,16 @@
+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'], $this->getRequestParameters($data));
+ }
+
+ /**
+ * @throws Exception
+ * @return ResultSet
+ */
+ public function query()
+ {
+
+ $response = $this->httpClient->get($this->parameters['url'], $this->getRequestParameters());
+
+ $raw = (string) $response->getBody();
+
+ $responseJson = json_encode($raw);
+
+ if (isset($responseJson->error)) {
+ throw new Exception($responseJson->error);
+ }
+
+ 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']);
+ }
+
+ /**
+ * @param null $data
+ *
+ * @return array
+ */
+ protected function getRequestParameters($data = null)
+ {
+ $requestParameters = ['http_errors' => false];
+
+ if ($data) {
+ $requestParameters += ['body' => $data];
+ }
+
+ if (isset($this->parameters['auth'])) {
+ $requestParameters += ['auth' => $this->parameters['auth']];
+ }
+
+ return $requestParameters;
+ }
+}
diff --git a/lib/influxdb-php/src/InfluxDB/Driver/QueryDriverInterface.php b/lib/influxdb-php/src/InfluxDB/Driver/QueryDriverInterface.php
new file mode 100644
index 0000000000..0966cecc3d
--- /dev/null
+++ b/lib/influxdb-php/src/InfluxDB/Driver/QueryDriverInterface.php
@@ -0,0 +1,22 @@
+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;
+ }
+}
\ No newline at end of file
diff --git a/lib/influxdb-php/src/InfluxDB/Exception.php b/lib/influxdb-php/src/InfluxDB/Exception.php
new file mode 100644
index 0000000000..868dd74c48
--- /dev/null
+++ b/lib/influxdb-php/src/InfluxDB/Exception.php
@@ -0,0 +1,10 @@
+measurement = (string) $measurement;
+ $this->tags = $tags;
+ $this->fields = $additionalFields;
+
+ if ($value) {
+ $this->fields['value'] = $value;
+ }
+
+ if ($timestamp && !$this->isValidTimeStamp($timestamp)) {
+ throw new DatabaseException(sprintf('%s is not a valid timestamp', $timestamp));
+ }
+
+ $this->timestamp = $timestamp;
+ }
+
+ /**
+ * @see: https://influxdb.com/docs/v0.9/concepts/reading_and_writing_data.html
+ *
+ * Should return this format
+ * 'cpu_load_short,host=server01,region=us-west value=0.64 1434055562000000000'
+ */
+ public function __toString()
+ {
+
+ $string = $this->measurement;
+
+ if (count($this->tags) > 0) {
+ $string .= ',' . $this->arrayToString($this->tags);
+ }
+
+ $string .= ' ' . $this->arrayToString($this->fields);
+
+ if ($this->timestamp) {
+ $string .= ' '.$this->timestamp;
+ }
+
+ return $string;
+ }
+
+ /**
+ * @param array $arr
+ * @return string
+ */
+ private function arrayToString(array $arr)
+ {
+ $strParts = [];
+
+ foreach ($arr as $key => $value) {
+ $strParts[] = sprintf('%s=%s', $key, $value);
+ }
+
+ return implode(',', $strParts);
+ }
+
+ /**
+ * @param int $timestamp
+ * @return bool
+ */
+ private function isValidTimeStamp($timestamp)
+ {
+ if ((int) $timestamp === $timestamp) {
+ return true;
+ }
+
+ if ($timestamp <= PHP_INT_MAX && $timestamp >= ~PHP_INT_MAX) {
+ return true;
+ }
+
+ return false;
+ }
+}
diff --git a/lib/influxdb-php/src/InfluxDB/Query/Builder.php b/lib/influxdb-php/src/InfluxDB/Query/Builder.php
new file mode 100644
index 0000000000..1060bc39d4
--- /dev/null
+++ b/lib/influxdb-php/src/InfluxDB/Query/Builder.php
@@ -0,0 +1,271 @@
+percentile(95)->setTimeRange($timeFrom, $timeTo)->getResult();
+ *
+ * $series->select('*')->from('*')->getResult();
+ *
+ * @todo add inner join
+ * @todo add merge
+ *
+ * @package InfluxDB\Query
+ * @author Stephen "TheCodeAssassin" Hoogendijk
+ */
+class Builder
+{
+ /**
+ * @var Database
+ */
+ protected $db;
+
+ /**
+ * @var string
+ */
+ protected $selection = '*';
+
+ /**
+ * @var string[]
+ */
+ protected $where = array();
+
+ /**
+ * @var string
+ */
+ protected $startTime;
+
+ /**
+ * @var string
+ */
+ protected $endTime;
+
+ /**
+ * @var string
+ */
+ protected $metric;
+
+ /**
+ * @var string
+ */
+ protected $limitClause = '';
+
+ /**
+ * @param Database $db
+ */
+ public function __construct(Database $db)
+ {
+ $this->db = $db;
+ }
+
+ /**
+ * @param string $metric The metric to select (required)
+ * @return $this
+ */
+ public function from($metric)
+ {
+ $this->metric = $metric;
+
+ return $this;
+ }
+
+ /**
+ * Custom select method
+ *
+ * example:
+ *
+ * $series->select('sum(value)',
+ *
+ * @param string $customSelect
+ * @return $this
+ */
+ public function select($customSelect)
+ {
+ $this->selection = $customSelect;
+
+ return $this;
+ }
+
+ /**
+ * @param array $conditions
+ *
+ * Example: array('time > now()', 'time < now() -1d');
+ *
+ * @return $this
+ */
+ public function where(array $conditions)
+ {
+ foreach ($conditions as $condition) {
+ $this->where[] = $condition;
+ }
+
+ return $this;
+ }
+
+ /**
+ * @param string $field
+ * @return $this
+ */
+ public function count($field = 'type')
+ {
+ $this->selection = sprintf('count(%s)', $field);
+
+ return $this;
+ }
+
+ /**
+ * @param string $field
+ * @return $this
+ */
+ public function median($field = 'type')
+ {
+ $this->selection = sprintf('median(%s)', $field);
+
+ return $this;
+ }
+
+ /**
+ * @param string $field
+ * @return $this
+ */
+ public function mean($field = 'type')
+ {
+ $this->selection = sprintf('mean(%s)', $field);
+
+ return $this;
+ }
+
+ /**
+ * @param string $field
+ * @return $this
+ */
+ public function sum($field = 'type')
+ {
+ $this->selection = sprintf('sum(%s)', $field);
+
+ return $this;
+ }
+
+ /**
+ * @param string $field
+ * @return $this
+ */
+ public function first($field = 'type')
+ {
+ $this->selection = sprintf('first(%s)', $field);
+
+ return $this;
+ }
+
+ /**
+ * @param string $field
+ * @return $this
+ */
+ public function last($field = 'type')
+ {
+ $this->selection = sprintf('last(%s)', $field);
+
+ return $this;
+ }
+
+ /**
+ * Set's the time range to select data from
+ *
+ * @param int $from
+ * @param int $to
+ * @return $this
+ */
+ public function setTimeRange($from, $to)
+ {
+ $fromDate = date('Y-m-d H:i:s', (int) $from);
+ $toDate = date('Y-m-d H:i:s', (int) $to);
+
+ $this->where(array("time > '$fromDate'", "time < '$toDate'"));
+
+ return $this;
+ }
+
+ /**
+ * @param int $percentile Percentage to select (for example 95 for 95th percentile billing)
+ *
+ * @return $this
+ */
+ public function percentile($percentile = 95)
+ {
+ $this->selection = sprintf('percentile(value, %d)', (int) $percentile);
+
+ return $this;
+ }
+
+ /**
+ * Limit the ResultSet to n records
+ *
+ * @param int $count
+ *
+ * @return $this
+ */
+ public function limit($count)
+ {
+ $this->limitClause = sprintf(' LIMIT %s', (int) $count);
+
+ return $this;
+ }
+
+ /**
+ * @return string
+ */
+ public function getQuery()
+ {
+ return $this->parseQuery();
+ }
+
+ /**
+ * Gets the result from the database (builds the query)
+ *
+ * @return ResultSet
+ */
+ public function getResultSet()
+ {
+ return $this->db->query($this->parseQuery());
+ }
+
+ /**
+ * @return string
+ */
+ protected function parseQuery()
+ {
+ $query = sprintf("SELECT %s FROM %s", $this->selection, $this->metric);
+
+ if (! $this->metric) {
+ throw new \InvalidArgumentException('No metric provided to from()');
+ }
+
+ for ($i = 0; $i < count($this->where); $i++) {
+ $selection = 'WHERE';
+
+ if ($i > 0) {
+ $selection = 'AND';
+ }
+
+ $clause = $this->where[$i];
+ $query .= ' ' . $selection . ' ' . $clause;
+
+ }
+
+ if ($this->limitClause) {
+ $query .= $this->limitClause;
+ }
+
+ return $query;
+ }
+}
diff --git a/lib/influxdb-php/src/InfluxDB/Query/Exception.php b/lib/influxdb-php/src/InfluxDB/Query/Exception.php
new file mode 100644
index 0000000000..448a41e979
--- /dev/null
+++ b/lib/influxdb-php/src/InfluxDB/Query/Exception.php
@@ -0,0 +1,10 @@
+parsedResults = json_decode((string) $raw, true);
+
+ if (json_last_error() !== JSON_ERROR_NONE) {
+ throw new \InvalidArgumentException('Invalid JSON');
+ }
+
+ // There was an error in the query thrown by influxdb
+ if (isset($this->parsedResults['error'])) {
+ throw new ClientException($this->parsedResults['error']);
+ }
+
+ // Check if there are errors in the first serie
+ if (isset($this->parsedResults['results'][0]['error'])) {
+ throw new ClientException($this->parsedResults['results'][0]['error']);
+ }
+ }
+
+ /**
+ * @param $metricName
+ * @param array $tags
+ * @return array $points
+ */
+ public function getPoints($metricName = '', array $tags = array())
+ {
+ $points = [];
+ $series = $this->getSeries();
+
+ foreach ($series as $serie) {
+ if ((empty($metricName) && empty($tags)
+ || $serie['name'] == $metricName
+ || (isset($serie['tags']) && array_intersect($tags, $serie['tags'])))
+ && isset($serie['values'])
+ ) {
+ $points = array_merge($points, $this->getPointsFromSerie($serie));
+ }
+ }
+
+ return $points;
+ }
+
+ /**
+ * @see: https://influxdb.com/docs/v0.9/concepts/reading_and_writing_data.html
+ *
+ * results is an array of objects, one for each query,
+ * each containing the keys for a series
+ *
+ * @throws Exception
+ * @return array $series
+ */
+ public function getSeries()
+ {
+ $series = array_map(
+ function ($object) {
+ if (isset($object['error'])) {
+ throw new ClientException($object['error']);
+ }
+
+ return isset($object['series']) ? $object['series'] : [];
+ },
+ $this->parsedResults['results']
+ );
+
+ return array_shift($series);
+ }
+
+ /**
+ * @param array $serie
+ * @return array
+ */
+ private function getPointsFromSerie(array $serie)
+ {
+ $points = [];
+
+ foreach ($serie['values'] as $point) {
+ $points[] = array_combine($serie['columns'], $point);
+ }
+
+ return $points;
+ }
+}
diff --git a/lib/influxdb-php/tests/bootstrap.php b/lib/influxdb-php/tests/bootstrap.php
new file mode 100644
index 0000000000..f94d45bf44
--- /dev/null
+++ b/lib/influxdb-php/tests/bootstrap.php
@@ -0,0 +1,7 @@
+mockClient = $this->getMockBuilder('\InfluxDB\Client')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $this->resultData = file_get_contents(dirname(__FILE__) . '/result.example.json');
+
+ $this->mockClient->expects($this->any())
+ ->method('getBaseURI')
+ ->will($this->returnValue($this->equalTo('http://localhost:8086')));
+
+ $this->mockClient->expects($this->any())
+ ->method('query')
+ ->will($this->returnValue(new ResultSet($this->resultData)));
+
+ $httpMockClient = new Guzzle($this->buildHttpMockClient(''));
+
+ // make sure the client has a valid driver
+ $this->mockClient->expects($this->any())
+ ->method('getDriver')
+ ->will($this->returnValue($httpMockClient));
+
+ $this->database = new Database('influx_test_db', $this->mockClient);
+
+ }
+
+ /**
+ * @return mixed
+ */
+ public function getMockResultSet()
+ {
+ return $this->mockResultSet;
+ }
+
+ /**
+ * @param mixed $mockResultSet
+ */
+ public function setMockResultSet($mockResultSet)
+ {
+ $this->mockResultSet = $mockResultSet;
+ }
+
+
+ /**
+ * @return GuzzleClient
+ */
+ public function buildHttpMockClient($body)
+ {
+ // Create a mock and queue two responses.
+ $mock = new MockHandler([new Response(200, array(), $body)]);
+
+ $handler = HandlerStack::create($mock);
+ return new GuzzleClient(['handler' => $handler]);
+ }
+
+ /**
+ * @return string
+ */
+ public function getEmptyResult()
+ {
+ return $this->emptyResult;
+ }
+
+ /**
+ * @param bool $emptyResult
+ *
+ * @return PHPUnit_Framework_MockObject_MockObject|Client
+ */
+ public function getClientMock($emptyResult = false)
+ {
+ $mockClient = $this->getMockBuilder('\InfluxDB\Client')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ if ($emptyResult) {
+ $mockClient->expects($this->once())
+ ->method('query')
+ ->will($this->returnValue(new ResultSet($this->getEmptyResult())));
+ }
+
+ return $mockClient;
+ }
+}
\ No newline at end of file
diff --git a/lib/influxdb-php/tests/unit/AdminTest.php b/lib/influxdb-php/tests/unit/AdminTest.php
new file mode 100644
index 0000000000..889874f4c6
--- /dev/null
+++ b/lib/influxdb-php/tests/unit/AdminTest.php
@@ -0,0 +1,72 @@
+getAdminObject(true);
+
+ $this->assertEquals(
+ new ResultSet($this->emptyResult),
+ $adminObject->createUser('test', 'test', Client\Admin::PRIVILEGE_ALL)
+ );
+ }
+
+ public function testChangeUserPassword()
+ {
+ $adminObject = $this->getAdminObject(true);
+
+ $this->assertEquals(
+ new ResultSet($this->emptyResult),
+ $adminObject->changeUserPassword('test', 'test')
+ );
+ }
+
+ public function testShowUsers()
+ {
+ $testJson = file_get_contents(dirname(__FILE__) . '/result-test-users.example.json');
+
+ $clientMock = $this->getClientMock();
+ $testResult = new ResultSet($testJson);
+
+ $clientMock->expects($this->once())
+ ->method('query')
+ ->will($this->returnValue($testResult));
+
+ $adminMock = new Client\Admin($clientMock);
+
+ $this->assertEquals($testResult, $adminMock->showUsers());
+ }
+
+ /**
+ * @return Client\Admin
+ */
+ private function getAdminObject()
+ {
+ return new Client\Admin($this->getClientMock(true));
+ }
+
+}
\ No newline at end of file
diff --git a/lib/influxdb-php/tests/unit/ClientTest.php b/lib/influxdb-php/tests/unit/ClientTest.php
new file mode 100644
index 0000000000..09f420d1bf
--- /dev/null
+++ b/lib/influxdb-php/tests/unit/ClientTest.php
@@ -0,0 +1,60 @@
+assertEquals($client->getBaseURI(), 'http://localhost:8086');
+ }
+
+ public function testSelectDbShouldReturnDatabaseInstance()
+ {
+ $client = new Client('localhost', 8086);
+
+ $dbName = 'test-database';
+ $database = $client->selectDB($dbName);
+
+ $this->assertInstanceOf('\InfluxDB\Database', $database);
+
+ $this->assertEquals($dbName, $database->getName());
+ }
+
+
+ /**
+ */
+ 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);
+
+ $client->setDriver(new Guzzle($httpMockClient));
+
+ /** @var \InfluxDB\ResultSet $result */
+ $result = $client->query(null, $query);
+
+ $this->assertInstanceOf('\InfluxDB\ResultSet', $result);
+ }
+
+}
\ No newline at end of file
diff --git a/lib/influxdb-php/tests/unit/DatabaseTest.php b/lib/influxdb-php/tests/unit/DatabaseTest.php
new file mode 100644
index 0000000000..e410385476
--- /dev/null
+++ b/lib/influxdb-php/tests/unit/DatabaseTest.php
@@ -0,0 +1,100 @@
+resultData = file_get_contents(dirname(__FILE__) . '/result.example.json');
+
+ $this->mockClient->expects($this->any())
+ ->method('listDatabases')
+ ->will($this->returnValue(array('test123', 'test')));
+
+ $this->dataToInsert = file_get_contents(dirname(__FILE__) . '/input.example.json');
+
+ }
+
+ /**
+ *
+ */
+ public function testQuery()
+ {
+ $testResultSet = new ResultSet($this->resultData);
+ $this->assertEquals($this->database->query('SELECT * FROM test_metric'), $testResultSet);
+ }
+
+ public function testCreateRetentionPolicy()
+ {
+ $retentionPolicy = new Database\RetentionPolicy('test', '1d', 1, true);
+
+ $mockClient = $this->getClientMock(true);
+
+ $database = new Database('test', $mockClient);
+
+ $this->assertEquals($database->createRetentionPolicy($retentionPolicy), new ResultSet($this->getEmptyResult()));
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testEmptyDatabaseName()
+ {
+ new Database(null, $this->mockClient);
+ }
+
+ public function testExists()
+ {
+ $database = new Database('test', $this->mockClient);
+
+ $this->assertEquals($database->exists(), true);
+ }
+
+
+ public function testNotExists()
+ {
+ $database = new Database('test_not_exists', $this->mockClient);
+
+ $this->assertEquals($database->exists(), false);
+ }
+
+ public function testWritePointsInASingleCall()
+ {
+ $point1 = new Point(
+ 'cpu_load_short',
+ 0.64,
+ array('host' => 'server01', 'region' => 'us-west'),
+ array('cpucount' => 10),
+ 1435222310
+ );
+
+ $point2 = new Point(
+ 'cpu_load_short',
+ 0.84
+ );
+
+ $this->assertEquals(true, $this->database->writePoints(array($point1, $point2)));
+ }
+}
\ No newline at end of file
diff --git a/lib/influxdb-php/tests/unit/PointTest.php b/lib/influxdb-php/tests/unit/PointTest.php
new file mode 100644
index 0000000000..eaee63fe75
--- /dev/null
+++ b/lib/influxdb-php/tests/unit/PointTest.php
@@ -0,0 +1,30 @@
+ 'server01', 'region' => 'us-west'),
+ array('cpucount' => 10),
+ 1435222310
+ );
+
+ $this->assertEquals($expected, (string) $point);
+ }
+}
\ No newline at end of file
diff --git a/lib/influxdb-php/tests/unit/ResultSetTest.php b/lib/influxdb-php/tests/unit/ResultSetTest.php
new file mode 100644
index 0000000000..4c04bf1e9b
--- /dev/null
+++ b/lib/influxdb-php/tests/unit/ResultSetTest.php
@@ -0,0 +1,141 @@
+resultSet = new ResultSet($resultJsonExample);
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testThrowsExceptionIfJSONisNotValid()
+ {
+ $invalidJSON = 'foo';
+
+ new ResultSet($invalidJSON);
+ }
+
+ /**
+ * Throws Exception if something went wrong with influxDB
+ * @expectedException \InfluxDB\Exception
+ */
+ public function testThrowsInfluxDBException()
+ {
+
+ $errorResult = <<resultSet = new ResultSet($resultJsonExample);
+
+ $measurementName = 'cpu_load_short';
+ $expectedNumberOfPoints = 2;
+
+ $points = $this->resultSet->getPoints($measurementName);
+
+ $this->assertTrue(is_array($points));
+
+ $this->assertCount($expectedNumberOfPoints, $points);
+ }
+
+ /**
+ * We can get points from measurement
+ */
+ public function testGetPoints()
+ {
+ $expectedNumberOfPoints = 3;
+
+ $points = $this->resultSet->getPoints();
+
+ $this->assertTrue(
+ is_array($points)
+ );
+
+ $this->assertCount($expectedNumberOfPoints, $points);
+
+ }
+
+ /**
+ * We can get points from measurement
+ */
+ public function testGetPointsFromMeasurementName()
+ {
+ $measurementName = 'cpu_load_short';
+ $expectedNumberOfPoints = 2;
+ $expectedValueFromFirstPoint = 0.64;
+
+ $points = $this->resultSet->getPoints($measurementName);
+
+ $this->assertTrue(
+ is_array($points)
+ );
+
+ $this->assertCount($expectedNumberOfPoints, $points);
+
+ $somePoint = array_shift($points);
+
+ $this->assertEquals($expectedValueFromFirstPoint, $somePoint['value']);
+ }
+
+ public function testGetPointsFromTags()
+ {
+ $tags = array("host" => "server01");
+ $expectedNumberOfPoints = 2;
+
+ $points = $this->resultSet->getPoints('', $tags);
+
+ $this->assertTrue(is_array($points));
+ $this->assertCount($expectedNumberOfPoints, $points);
+ }
+
+ public function testGetPointsFromNameAndTags()
+ {
+ $tags = array("host" => "server01");
+ $expectedNumberOfPoints = 2;
+
+ $points = $this->resultSet->getPoints('', $tags);
+
+ $this->assertTrue(is_array($points));
+ $this->assertCount($expectedNumberOfPoints, $points);
+ }
+}
\ No newline at end of file
diff --git a/lib/influxdb-php/tests/unit/input.example.json b/lib/influxdb-php/tests/unit/input.example.json
new file mode 100644
index 0000000000..f47806261d
--- /dev/null
+++ b/lib/influxdb-php/tests/unit/input.example.json
@@ -0,0 +1,17 @@
+{
+ "database": "mydb",
+ "retentionPolicy": "mypolicy",
+ "points": [
+ {
+ "measurement": "cpu_load_short",
+ "tags": {
+ "host": "server01",
+ "region": "us-west"
+ },
+ "time": "2009-11-10T23:00:00Z",
+ "fields": {
+ "value": 0.64
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/lib/influxdb-php/tests/unit/result-no-tags.example.json b/lib/influxdb-php/tests/unit/result-no-tags.example.json
new file mode 100644
index 0000000000..feba13f256
--- /dev/null
+++ b/lib/influxdb-php/tests/unit/result-no-tags.example.json
@@ -0,0 +1,47 @@
+{
+ "results": [
+ {
+ "series": [
+ {
+ "name": "cpu_load_short",
+ "columns": [
+ "time",
+ "value"
+ ],
+ "values": [
+ [
+ "2015-01-29T21:51:28.968422294Z",
+ 0.64
+ ]
+ ]
+ },
+ {
+ "name": "cpu_load_short",
+ "columns": [
+ "time",
+ "value"
+ ],
+ "values": [
+ [
+ "2015-01-29T21:51:28.968422294Z",
+ 0.65
+ ]
+ ]
+ },
+ {
+ "name": "other_serie",
+ "columns": [
+ "time",
+ "value"
+ ],
+ "values": [
+ [
+ "2015-01-29T21:51:28.968422294Z",
+ 0.66
+ ]
+ ]
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/lib/influxdb-php/tests/unit/result-test-users.example.json b/lib/influxdb-php/tests/unit/result-test-users.example.json
new file mode 100644
index 0000000000..34f5f999b6
--- /dev/null
+++ b/lib/influxdb-php/tests/unit/result-test-users.example.json
@@ -0,0 +1,24 @@
+{
+ "results": [
+ {
+ "series": [
+ {
+ "columns": [
+ "user",
+ "admin"
+ ],
+ "values": [
+ [
+ "test1",
+ true
+ ],
+ [
+ "test2",
+ false
+ ]
+ ]
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/lib/influxdb-php/tests/unit/result.example.json b/lib/influxdb-php/tests/unit/result.example.json
new file mode 100644
index 0000000000..8603cae10f
--- /dev/null
+++ b/lib/influxdb-php/tests/unit/result.example.json
@@ -0,0 +1,59 @@
+{
+ "results": [
+ {
+ "series": [
+ {
+ "name": "cpu_load_short",
+ "tags": {
+ "host": "server01",
+ "region": "us-west"
+ },
+ "columns": [
+ "time",
+ "value"
+ ],
+ "values": [
+ [
+ "2015-01-29T21:51:28.968422294Z",
+ 0.64
+ ]
+ ]
+ },
+ {
+ "name": "cpu_load_short",
+ "tags": {
+ "host": "server02",
+ "region": "us-west"
+ },
+ "columns": [
+ "time",
+ "value"
+ ],
+ "values": [
+ [
+ "2015-01-29T21:51:28.968422294Z",
+ 0.65
+ ]
+ ]
+ },
+ {
+ "name": "other_serie",
+ "tags": {
+ "host": "server01",
+ "region": "us-west"
+ },
+ "columns": [
+ "time",
+ "value"
+ ],
+ "values": [
+ [
+ "2015-01-29T21:51:28.968422294Z",
+ 0.66
+ ]
+ ]
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file