mirror of
https://github.com/librenms/librenms.git
synced 2024-10-07 16:52:45 +00:00
Merge commit '4430658932762ead3661231492b8074f144ea4b6' into influxdb-php
Conflicts: lib/influxdb-php/.gitignore lib/influxdb-php/README.md
This commit is contained in:
@ -1,14 +1,18 @@
|
||||
language: php
|
||||
sudo: false
|
||||
|
||||
php:
|
||||
- 5.5
|
||||
- 5.6
|
||||
- 7.0
|
||||
|
||||
install:
|
||||
- composer selfupdate
|
||||
- composer install
|
||||
|
||||
addons:
|
||||
code_climate:
|
||||
repo_token: 5371d86d298d66eb9007cc8de462d7063e58f6dd85e430928834736edee479a9
|
||||
repo_token: 303a289e61e8e11d8bcae115860c4fffc6e1e7fe2d504d20a773e69bd7641284
|
||||
|
||||
after_script:
|
||||
- vendor/bin/test-reporter
|
||||
|
@ -1,12 +1,12 @@
|
||||
# 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)
|
||||
[](https://travis-ci.org/influxdata/influxdb-php)
|
||||
[](https://codeclimate.com/github/influxdata/influxdb-php)
|
||||
[](https://codeclimate.com/github/influxdata/influxdb-php/coverage)
|
||||
|
||||
### Overview
|
||||
|
||||
A easy to use library for using InfluxDB with PHP.
|
||||
A easy to use library for using InfluxDB with PHP. Maintained by [@thecodeassassin](https://github.com/thecodeassassin), [@gianarb](https://github.com/gianarb).
|
||||
|
||||
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.
|
||||
@ -15,7 +15,9 @@ This way there will be a common abstraction library between different programmin
|
||||
|
||||
Installation can be done with composer:
|
||||
|
||||
composer require influxdb/influxdb-php:dev-master
|
||||
``` bash
|
||||
$ composer require influxdb/influxdb-php
|
||||
```
|
||||
|
||||
### NOTE for PHP 5.3 and PHP 5.4 users
|
||||
|
||||
@ -27,10 +29,7 @@ The 0.1.x branch will work on PHP 5.3 and PHP 5.4 but doesn't contain all the fe
|
||||
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.
|
||||
@ -38,13 +37,11 @@ This will create a new client object which you can use to read and write points
|
||||
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));
|
||||
|
||||
// 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();
|
||||
|
||||
// get the client to retrieve other databases
|
||||
$client = $database->getClient();
|
||||
```
|
||||
|
||||
### Reading
|
||||
@ -52,37 +49,45 @@ It's also possible to create a client from a DSN (Data Source Name):
|
||||
To fetch records from InfluxDB you can do a query directly on a database:
|
||||
|
||||
```php
|
||||
// fetch the database
|
||||
$database = $client->selectDB('influx_test_db');
|
||||
|
||||
// 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();
|
||||
// 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()
|
||||
// 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()
|
||||
// get the query from the QueryBuilder
|
||||
$query = $database->getQueryBuilder()
|
||||
->select('cpucount')
|
||||
->from('test_metric')
|
||||
->where(["region = 'us-west'"])
|
||||
->getQuery();
|
||||
```
|
||||
|
||||
Make sure that you enter single quotes when doing a where query on strings; otherwise InfluxDB will return an empty result.
|
||||
|
||||
You can get the last executed query from the client:
|
||||
|
||||
```php
|
||||
// use the getLastQuery() method
|
||||
$lastQuery = $client->getLastQuery();
|
||||
|
||||
// or access the static variable directly:
|
||||
$lastQuery = Client::lastQuery;
|
||||
```
|
||||
|
||||
### Writing data
|
||||
@ -90,9 +95,8 @@ It's also possible to use the QueryBuilder object. This is a class that simplifi
|
||||
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(
|
||||
// create an array of points
|
||||
$points = array(
|
||||
new Point(
|
||||
'test_metric', // name of the measurement
|
||||
0.64, // the measurement value
|
||||
@ -107,11 +111,10 @@ Writing data is done by providing an array of points to the writePoints method o
|
||||
['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);
|
||||
);
|
||||
|
||||
// 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
|
||||
@ -123,7 +126,7 @@ InfluxDB takes the current time as the default timestamp.
|
||||
You can also write multiple fields to a measurement without specifying a value:
|
||||
|
||||
```php
|
||||
$points = [
|
||||
$points = [
|
||||
new Point(
|
||||
'instance', // the name of the measurement
|
||||
null, // measurement value
|
||||
@ -138,7 +141,7 @@ You can also write multiple fields to a measurement without specifying a value:
|
||||
['cpucount' => 10, 'free' => 2], // measurement fields
|
||||
exec('date +%s%N') // timestamp in nanoseconds on Linux ONLY
|
||||
)
|
||||
];
|
||||
];
|
||||
|
||||
```
|
||||
|
||||
@ -156,11 +159,10 @@ First, set your InfluxDB host to support incoming UDP sockets:
|
||||
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));
|
||||
|
||||
// set the UDP driver in the client
|
||||
$client->setDriver(new \InfluxDB\Driver\UDP($client->getHost(), 4444));
|
||||
|
||||
$points = [
|
||||
$points = [
|
||||
new Point(
|
||||
'test_metric',
|
||||
0.84,
|
||||
@ -168,21 +170,20 @@ Then, configure the UDP driver in the client:
|
||||
['cpucount' => 10],
|
||||
exec('date +%s%N') // this will produce a nanosecond timestamp on Linux ONLY
|
||||
)
|
||||
];
|
||||
];
|
||||
|
||||
// now just write your points like you normally would
|
||||
$result = $database->writePoints($points);
|
||||
// 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');
|
||||
|
||||
// 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);
|
||||
// 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
|
||||
@ -194,21 +195,21 @@ It's important to provide the correct precision when adding a timestamp to a Poi
|
||||
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 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 second precision
|
||||
$newPoints = $database->writePoints($points, Database::PRECISION_SECONDS);
|
||||
|
||||
// Points will require microsecond precision
|
||||
$newPoints = $database->writePoints($points, Database::PRECISION_MICROSECONDS);
|
||||
// Points will require microsecond precision
|
||||
$newPoints = $database->writePoints($points, Database::PRECISION_MICROSECONDS);
|
||||
```
|
||||
|
||||
Please note that `exec('date + %s%N')` does NOT work under MacOS; you can use PHP's `microtime` to get a timestamp with microsecond precision, like such:
|
||||
|
||||
```php
|
||||
list( $usec, $sec ) = explode(' ', microtime() );
|
||||
$timestamp = sprintf( '%d%06d', $sec, $usec*1000000 );
|
||||
list($usec, $sec) = explode(' ', microtime());
|
||||
$timestamp = sprintf('%d%06d', $sec, $usec*1000000);
|
||||
```
|
||||
|
||||
### Creating databases
|
||||
@ -219,41 +220,39 @@ 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, '', '');
|
||||
|
||||
// create the client
|
||||
$client = new \InfluxDB\Client($host, $port, '', '');
|
||||
// select the database
|
||||
$database = $client->selectDB('influx_test_db');
|
||||
|
||||
// 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));
|
||||
|
||||
// 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');
|
||||
|
||||
// check if a database exists then create it if it doesn't
|
||||
$database = $client->selectDB('test_db');
|
||||
|
||||
if (!$database->exists()) {
|
||||
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));
|
||||
$database->alterRetentionPolicy(new RetentionPolicy('test', '2d', 5, true));
|
||||
```
|
||||
|
||||
and list them:
|
||||
|
||||
```php
|
||||
$result = $database->listRetentionPolicies();
|
||||
$result = $database->listRetentionPolicies();
|
||||
```
|
||||
|
||||
You can add more retention policies to a database:
|
||||
|
||||
```php
|
||||
$result = $database->createRetentionPolicy(new RetentionPolicy('test2', '30d', 1, true));
|
||||
$result = $database->createRetentionPolicy(new RetentionPolicy('test2', '30d', 1, true));
|
||||
```
|
||||
|
||||
### Client functions
|
||||
@ -261,12 +260,11 @@ You can add more retention policies to a database:
|
||||
Some functions are too general for a database. So these are available in the client:
|
||||
|
||||
```php
|
||||
// list users
|
||||
$result = $client->listUsers();
|
||||
|
||||
// list users
|
||||
$result = $client->listUsers();
|
||||
|
||||
// list databases
|
||||
$result = $client->listDatabases();
|
||||
// list databases
|
||||
$result = $client->listDatabases();
|
||||
```
|
||||
|
||||
### Admin functionality
|
||||
@ -274,24 +272,24 @@ Some functions are too general for a database. So these are available in the cli
|
||||
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 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);
|
||||
// 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');
|
||||
// drop user testuser123
|
||||
$client->admin->dropUser('testuser123');
|
||||
```
|
||||
|
||||
List all the users:
|
||||
|
||||
```php
|
||||
// show a list of all users
|
||||
$results = $client->admin->showUsers();
|
||||
// show a list of all users
|
||||
$results = $client->admin->showUsers();
|
||||
|
||||
// show users returns a ResultSet object
|
||||
$users = $results->getPoints();
|
||||
// show users returns a ResultSet object
|
||||
$users = $results->getPoints();
|
||||
```
|
||||
|
||||
#### Granting and revoking privileges
|
||||
@ -300,23 +298,21 @@ 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);
|
||||
|
||||
// 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');
|
||||
|
||||
// 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');
|
||||
|
||||
// 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');
|
||||
// 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
|
||||
@ -329,6 +325,37 @@ To grant a user specific privileges on a database, provide a database object or
|
||||
|
||||
## Changelog
|
||||
|
||||
###1.3.0
|
||||
* Added quoting of dbname in queries
|
||||
* Added orderBy to query builder
|
||||
* Fixed wrong orderby tests
|
||||
* Travis container-infra and php 7
|
||||
|
||||
###1.2.2
|
||||
* Fixed issue with listUsers() method
|
||||
* Added more unit tests
|
||||
* Added getColumns method to \InfluxDB\ResultSet
|
||||
|
||||
###1.2.0
|
||||
* Added support for 32 bit systems
|
||||
* Added setters/getters for Point fields
|
||||
|
||||
###1.1.3
|
||||
* Added support for symfony3
|
||||
|
||||
###1.1.2
|
||||
* Fixed issue with authentication when writing data
|
||||
|
||||
###1.1.1
|
||||
* Added support for 0.9.4
|
||||
* Added if not exists support to database->create()
|
||||
* Added getLastQuery method
|
||||
|
||||
###1.1.0
|
||||
* Added support for 0.9.3 rc2
|
||||
* Changed the way we handle the datatypes of values
|
||||
* Changed list retention policies to reflect the changes in 0.9.3
|
||||
|
||||
####1.0.1
|
||||
* Added support for authentication in the guzzle driver
|
||||
* Added admin functionality
|
||||
|
43
lib/influxdb-php/Vagrantfile
vendored
Normal file
43
lib/influxdb-php/Vagrantfile
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
# -*- mode: ruby -*-
|
||||
# vi: set ft=ruby :
|
||||
|
||||
# All Vagrant configuration is done below. The "2" in Vagrant.configure
|
||||
# configures the configuration version (we support older styles for
|
||||
# backwards compatibility). Please don't change it unless you know what
|
||||
# you're doing.
|
||||
#system("
|
||||
# if [ #{ARGV[0]} = 'up' ]; then
|
||||
# ./requirements.sh
|
||||
# fi
|
||||
#")
|
||||
|
||||
|
||||
Vagrant.configure(2) do |config|
|
||||
|
||||
# The most common configuration options are documented and commented below.
|
||||
# For a complete reference, please see the online documentation at
|
||||
# https://docs.vagrantup.com.
|
||||
|
||||
# Every Vagrant development environment requires a box. You can search for
|
||||
# boxes at https://atlas.hashicorp.com/search.
|
||||
config.vm.box = "ubuntu/trusty64"
|
||||
|
||||
config.vm.define :node1 do |node1|
|
||||
#
|
||||
# Networking
|
||||
#
|
||||
node1.vm.network 'private_network', ip: '192.168.33.10'
|
||||
#
|
||||
# VM Setup
|
||||
#
|
||||
# Set the hostname to something useful
|
||||
node1.vm.hostname = 'influxdb-node1'
|
||||
node1.vm.define :influxdb_node1, {}
|
||||
|
||||
node1.vm.provision 'ansible' do |ansible|
|
||||
ansible.playbook = 'ansible/main.yml'
|
||||
ansible.tags = ENV['ANSIBLE_TAGS'] unless ENV['ANSIBLE_TAGS'].to_s.empty?
|
||||
ansible.sudo = true
|
||||
end
|
||||
end
|
||||
end
|
10
lib/influxdb-php/ansible/main.yml
Normal file
10
lib/influxdb-php/ansible/main.yml
Normal file
@ -0,0 +1,10 @@
|
||||
---
|
||||
- hosts: all
|
||||
sudo: yes
|
||||
|
||||
vars:
|
||||
influxdb_udp_enabled: "true"
|
||||
influxdb_udp_bind_address: "0.0.0.0:8090"
|
||||
|
||||
roles:
|
||||
- { role: mtchavez.influxdb }
|
1
lib/influxdb-php/ansible/requirements.txt
Normal file
1
lib/influxdb-php/ansible/requirements.txt
Normal file
@ -0,0 +1 @@
|
||||
mtchavez.influxdb
|
@ -19,14 +19,19 @@
|
||||
{
|
||||
"name": "Daniel Martinez",
|
||||
"email": "danimartcas@hotmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Gianluca Arbezzano",
|
||||
"email": "gianarb92@gmail.com"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.5",
|
||||
"php": "^5.5 | ^7.0",
|
||||
"guzzlehttp/guzzle": "6.*",
|
||||
"symfony/event-dispatcher": "2.*"
|
||||
"symfony/event-dispatcher": "2.*|3.*"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.0",
|
||||
"codeclimate/php-test-reporter": "0.*",
|
||||
"symfony/config": "~2.8",
|
||||
"symfony/console": "~2.8",
|
||||
|
1163
lib/influxdb-php/composer.lock
generated
1163
lib/influxdb-php/composer.lock
generated
File diff suppressed because it is too large
Load Diff
14
lib/influxdb-php/requirements.sh
Executable file
14
lib/influxdb-php/requirements.sh
Executable file
@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
|
||||
#!/bin/bash
|
||||
|
||||
GLEXEC=$(which ansible-galaxy)
|
||||
|
||||
if [ $? = 1 ]; then
|
||||
echo
|
||||
echo "Ansible-galaxy not found, please make sure you have ansible 1.9+ installed."
|
||||
echo
|
||||
exit 1
|
||||
fi
|
||||
|
||||
$GLEXEC install -f -r ansible/requirements.txt
|
@ -88,6 +88,14 @@ class Client
|
||||
*/
|
||||
protected $driver;
|
||||
|
||||
|
||||
/**
|
||||
* Stores the last query that ran
|
||||
*
|
||||
* @var null
|
||||
*/
|
||||
public static $lastQuery = null;
|
||||
|
||||
/**
|
||||
* @param string $host
|
||||
* @param int $port
|
||||
@ -103,7 +111,7 @@ class Client
|
||||
$username = '',
|
||||
$password = '',
|
||||
$ssl = false,
|
||||
$verifySSL = true,
|
||||
$verifySSL = false,
|
||||
$timeout = 0
|
||||
) {
|
||||
$this->host = (string) $host;
|
||||
@ -183,6 +191,9 @@ class Client
|
||||
$driver->setParameters($parameters);
|
||||
|
||||
try {
|
||||
// store the last query sent
|
||||
static::$lastQuery = $query;
|
||||
|
||||
// perform the query and return the resultset
|
||||
return $driver->query();
|
||||
|
||||
@ -191,6 +202,33 @@ class Client
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write data
|
||||
*
|
||||
* @param array $parameters
|
||||
* @param string $payload
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function write(array $parameters, $payload)
|
||||
{
|
||||
// retrive the driver
|
||||
$driver = $this->getDriver();
|
||||
|
||||
// add authentication to the driver if needed
|
||||
if (!empty($this->username) && !empty($this->password)) {
|
||||
$parameters += ['auth' => [$this->username, $this->password]];
|
||||
}
|
||||
|
||||
// set the given parameters
|
||||
$driver->setParameters($parameters);
|
||||
|
||||
// send the points to influxDB
|
||||
$driver->write(implode("\n", $payload));
|
||||
|
||||
return $driver->isSuccess();
|
||||
}
|
||||
|
||||
/**
|
||||
* List all the databases
|
||||
*/
|
||||
@ -209,9 +247,9 @@ class Client
|
||||
*/
|
||||
public function listUsers()
|
||||
{
|
||||
$result = $this->query(null, 'SHOW USERS')->getPoints();
|
||||
$result = $this->query(null, 'SHOW USERS')->getColumns();
|
||||
|
||||
return $this->pointsToArray($result);
|
||||
return (array) $result;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -306,6 +344,16 @@ class Client
|
||||
return $this->host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last executed query
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getLastQuery()
|
||||
{
|
||||
return static::$lastQuery;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Point[] $points
|
||||
* @return array
|
||||
|
@ -77,14 +77,21 @@ class Database
|
||||
* Create this database
|
||||
*
|
||||
* @param RetentionPolicy $retentionPolicy
|
||||
* @param bool $createIfNotExists Only create the database if it does not yet exist
|
||||
*
|
||||
* @return ResultSet
|
||||
* @throws DatabaseException
|
||||
* @throws Exception
|
||||
*/
|
||||
public function create(RetentionPolicy $retentionPolicy = null)
|
||||
public function create(RetentionPolicy $retentionPolicy = null, $createIfNotExists = true)
|
||||
{
|
||||
try {
|
||||
$this->query(sprintf('CREATE DATABASE %s', $this->name));
|
||||
$query = sprintf(
|
||||
'CREATE DATABASE %s"%s"',
|
||||
($createIfNotExists ? 'IF NOT EXISTS ' : ''),
|
||||
$this->name
|
||||
);
|
||||
|
||||
$this->query($query);
|
||||
|
||||
if ($retentionPolicy) {
|
||||
$this->createRetentionPolicy($retentionPolicy);
|
||||
@ -125,25 +132,13 @@ class Database
|
||||
);
|
||||
|
||||
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();
|
||||
return $this->client->write($parameters, $payload);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
throw new Exception($e->getMessage(), $e->getCode());
|
||||
@ -174,7 +169,7 @@ class Database
|
||||
*/
|
||||
public function listRetentionPolicies()
|
||||
{
|
||||
return $this->query(sprintf('SHOW RETENTION POLICIES %s', $this->name))->getPoints();
|
||||
return $this->query(sprintf('SHOW RETENTION POLICIES ON "%s"', $this->name))->getPoints();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -182,7 +177,7 @@ class Database
|
||||
*/
|
||||
public function drop()
|
||||
{
|
||||
$this->query(sprintf('DROP DATABASE %s', $this->name));
|
||||
$this->query(sprintf('DROP DATABASE "%s"', $this->name));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -210,12 +205,8 @@ class Database
|
||||
*/
|
||||
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',
|
||||
'%s RETENTION POLICY "%s" ON "%s" DURATION %s REPLICATION %s',
|
||||
$method,
|
||||
$retentionPolicy->name,
|
||||
$this->name,
|
||||
|
@ -30,6 +30,11 @@ interface DriverInterface
|
||||
*/
|
||||
public function setParameters(array $parameters);
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getParameters();
|
||||
|
||||
/**
|
||||
* Send the data
|
||||
*
|
||||
|
@ -68,6 +68,14 @@ class Guzzle implements DriverInterface, QueryDriverInterface
|
||||
$this->parameters = $parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getParameters()
|
||||
{
|
||||
return $this->parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the data
|
||||
*
|
||||
@ -87,17 +95,10 @@ class Guzzle implements DriverInterface, QueryDriverInterface
|
||||
*/
|
||||
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);
|
||||
|
||||
}
|
||||
@ -109,7 +110,14 @@ class Guzzle implements DriverInterface, QueryDriverInterface
|
||||
*/
|
||||
public function isSuccess()
|
||||
{
|
||||
return in_array($this->response->getStatusCode(), ['200', '204']);
|
||||
$statuscode = $this->response->getStatusCode();
|
||||
|
||||
if(!in_array($statuscode, ['200', '204']))
|
||||
{
|
||||
throw new Exception('HTTP Code ' . $statuscode . ' ' . $this->response->getBody());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -58,6 +58,14 @@ class UDP implements DriverInterface
|
||||
$this->parameters = $parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getParameters()
|
||||
{
|
||||
return $this->parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the data
|
||||
*
|
||||
|
@ -14,22 +14,22 @@ class Point
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $measurement;
|
||||
protected $measurement;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $tags = [];
|
||||
protected $tags = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $fields = [];
|
||||
protected $fields = [];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $timestamp;
|
||||
protected $timestamp;
|
||||
|
||||
/**
|
||||
* The timestamp is optional. If you do not specify a timestamp the server’s
|
||||
@ -55,12 +55,14 @@ class Point
|
||||
|
||||
$this->measurement = (string) $measurement;
|
||||
$this->tags = $tags;
|
||||
$this->fields = $additionalFields;
|
||||
$fields = $additionalFields;
|
||||
|
||||
if ($value) {
|
||||
$this->fields['value'] = $value;
|
||||
if ($value !== null) {
|
||||
$fields['value'] = $value;
|
||||
}
|
||||
|
||||
$this->setFields($fields);
|
||||
|
||||
if ($timestamp && !$this->isValidTimeStamp($timestamp)) {
|
||||
throw new DatabaseException(sprintf('%s is not a valid timestamp', $timestamp));
|
||||
}
|
||||
@ -80,10 +82,10 @@ class Point
|
||||
$string = $this->measurement;
|
||||
|
||||
if (count($this->tags) > 0) {
|
||||
$string .= ',' . $this->arrayToString($this->tags);
|
||||
$string .= ',' . $this->arrayToString($this->escapeCharacters($this->tags));
|
||||
}
|
||||
|
||||
$string .= ' ' . $this->arrayToString($this->fields);
|
||||
$string .= ' ' . $this->arrayToString($this->escapeCharacters($this->fields));
|
||||
|
||||
if ($this->timestamp) {
|
||||
$string .= ' '.$this->timestamp;
|
||||
@ -92,6 +94,116 @@ class Point
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getMeasurement()
|
||||
{
|
||||
return $this->measurement;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $measurement
|
||||
*/
|
||||
public function setMeasurement($measurement)
|
||||
{
|
||||
$this->measurement = $measurement;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getTags()
|
||||
{
|
||||
return $this->tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $tags
|
||||
*/
|
||||
public function setTags($tags)
|
||||
{
|
||||
$this->tags = $tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getFields()
|
||||
{
|
||||
return $this->fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $fields
|
||||
*/
|
||||
public function setFields($fields)
|
||||
{
|
||||
foreach ($fields as &$field) {
|
||||
if (is_integer($field)) {
|
||||
$field = sprintf('%di', $field);
|
||||
} elseif (is_string($field)) {
|
||||
$field = sprintf("\"%s\"", $field);
|
||||
} elseif (is_bool($field)) {
|
||||
$field = ($field ? "true" : "false");
|
||||
}
|
||||
}
|
||||
|
||||
$this->fields = $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTimestamp()
|
||||
{
|
||||
return $this->timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $timestamp
|
||||
*/
|
||||
public function setTimestamp($timestamp)
|
||||
{
|
||||
$this->timestamp = $timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes invalid characters in both the array key and array value
|
||||
*
|
||||
* @param array $arr
|
||||
* @return array
|
||||
*/
|
||||
private function escapeCharacters(array $arr)
|
||||
{
|
||||
$returnArr = [];
|
||||
|
||||
foreach ($arr as $key => $value) {
|
||||
$returnArr[$this->addSlashes($key)] = $this->addSlashes($value);
|
||||
}
|
||||
|
||||
return $returnArr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns strings with space, comma, or equals sign characters backslashed per Influx write protocol syntax
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
private function addSlashes($value)
|
||||
{
|
||||
return str_replace([
|
||||
' ',
|
||||
',',
|
||||
'='
|
||||
],[
|
||||
'\ ',
|
||||
'\,',
|
||||
'\='
|
||||
], $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $arr
|
||||
* @return string
|
||||
@ -113,14 +225,26 @@ class Point
|
||||
*/
|
||||
private function isValidTimeStamp($timestamp)
|
||||
{
|
||||
if ((int) $timestamp === $timestamp) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($timestamp <= PHP_INT_MAX && $timestamp >= ~PHP_INT_MAX) {
|
||||
|
||||
// if the code is run on a 32bit system, loosely check if the timestamp is a valid numeric
|
||||
if (PHP_INT_SIZE == 4 && is_numeric($timestamp)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!is_numeric($timestamp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (intval($timestamp) != $timestamp) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!($timestamp <= PHP_INT_MAX && $timestamp >= ~PHP_INT_MAX)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -60,6 +60,16 @@ class Builder
|
||||
*/
|
||||
protected $limitClause = '';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $groupBy;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $orderBy;
|
||||
|
||||
/**
|
||||
* @param Database $db
|
||||
*/
|
||||
@ -178,6 +188,18 @@ class Builder
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function groupBy($field = 'type') {
|
||||
$this->groupBy[] = $field;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function orderBy($field = 'type', $order = 'ASC') {
|
||||
$this->orderBy[] = "$field $order";
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set's the time range to select data from
|
||||
*
|
||||
@ -244,7 +266,7 @@ class Builder
|
||||
*/
|
||||
protected function parseQuery()
|
||||
{
|
||||
$query = sprintf("SELECT %s FROM %s", $this->selection, $this->metric);
|
||||
$query = sprintf('SELECT %s FROM "%s"', $this->selection, $this->metric);
|
||||
|
||||
if (! $this->metric) {
|
||||
throw new \InvalidArgumentException('No metric provided to from()');
|
||||
@ -262,6 +284,14 @@ class Builder
|
||||
|
||||
}
|
||||
|
||||
if (!empty($this->groupBy)) {
|
||||
$query .= ' GROUP BY ' . implode(',', $this->groupBy);
|
||||
}
|
||||
|
||||
if (!empty($this->orderBy)) {
|
||||
$query .= ' ORDER BY ' . implode(',', $this->orderBy);
|
||||
}
|
||||
|
||||
if ($this->limitClause) {
|
||||
$query .= $this->limitClause;
|
||||
}
|
||||
|
@ -89,6 +89,14 @@ class ResultSet
|
||||
return array_shift($series);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getColumns()
|
||||
{
|
||||
return $this->getSeries()[0]['columns'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $serie
|
||||
* @return array
|
||||
|
68
lib/influxdb-php/test_library.php
Normal file
68
lib/influxdb-php/test_library.php
Normal file
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
/**
|
||||
* @author Stephen "TheCodeAssassin" Hoogendijk
|
||||
*/
|
||||
require 'vendor/autoload.php';
|
||||
|
||||
// vagrant ip
|
||||
$host = '192.168.33.10';
|
||||
|
||||
|
||||
function randFloat($min, $max)
|
||||
{
|
||||
$range = $max-$min;
|
||||
$num = $min + $range * mt_rand(0, 32767)/32767;
|
||||
|
||||
$num = round($num, 4);
|
||||
|
||||
return ((float) $num);
|
||||
}
|
||||
|
||||
$client = new \InfluxDB\Client($host);
|
||||
|
||||
$database = $client->selectDB('test');
|
||||
|
||||
if ($database->exists()) {
|
||||
$database->drop();
|
||||
}
|
||||
|
||||
$database->create(new \InfluxDB\Database\RetentionPolicy('test', '12w', 1, true));
|
||||
|
||||
|
||||
$start = microtime(true);
|
||||
|
||||
$countries = ['nl', 'gb', 'us', 'be', 'th', 'jp', 'nl', 'sa'];
|
||||
$colors = ['orange', 'black', 'yellow', 'white', 'red', 'purple'];
|
||||
$points = [];
|
||||
|
||||
for ($i=0; $i < 1000; $i++) {
|
||||
$points[] = new \InfluxDB\Point(
|
||||
'flags',
|
||||
randFloat(1, 999),
|
||||
['country' => $countries[array_rand($countries)]],
|
||||
['color' => $colors[array_rand($colors)]],
|
||||
(int) shell_exec('date +%s%N')+mt_rand(1,1000)
|
||||
);
|
||||
};
|
||||
|
||||
// insert the points
|
||||
$database->writePoints($points);
|
||||
|
||||
$end = microtime(true);
|
||||
|
||||
$country = $countries[array_rand($countries)];
|
||||
$color = $colors[array_rand($colors)];
|
||||
|
||||
$results = $database->query("SELECT * FROM flags WHERE country = '$country' LIMIT 5")->getPoints();
|
||||
$results2 = $database->query("SELECT * FROM flags WHERE color = '$color' LIMIT 5")->getPoints();
|
||||
|
||||
echo "Showing top 5 flags from country $country:" . PHP_EOL;
|
||||
print_r($results);
|
||||
echo PHP_EOL;
|
||||
|
||||
echo "Showing top 5 flags with color $color:" . PHP_EOL;
|
||||
print_r($results2);
|
||||
|
||||
|
||||
echo PHP_EOL;
|
||||
echo sprintf('Executed 1000 inserts in %.2f seconds', $end - $start);
|
@ -10,7 +10,7 @@ use GuzzleHttp\Handler\MockHandler;
|
||||
use GuzzleHttp\HandlerStack;
|
||||
use InfluxDB\Client;
|
||||
use InfluxDB\Database;
|
||||
use InfluxDB\Driver\Guzzle;
|
||||
use InfluxDB\Driver\Guzzle as GuzzleDriver;
|
||||
use InfluxDB\ResultSet;
|
||||
use PHPUnit_Framework_MockObject_MockObject;
|
||||
use GuzzleHttp\Client as GuzzleClient;
|
||||
@ -44,7 +44,7 @@ abstract class AbstractTest extends \PHPUnit_Framework_TestCase
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->resultData = file_get_contents(dirname(__FILE__) . '/result.example.json');
|
||||
$this->resultData = file_get_contents(dirname(__FILE__) . '/json/result.example.json');
|
||||
|
||||
$this->mockClient->expects($this->any())
|
||||
->method('getBaseURI')
|
||||
@ -52,9 +52,17 @@ abstract class AbstractTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$this->mockClient->expects($this->any())
|
||||
->method('query')
|
||||
->will($this->returnValue(new ResultSet($this->resultData)));
|
||||
->will($this->returnCallback(function ($db, $query) {
|
||||
Client::$lastQuery = $query;
|
||||
|
||||
$httpMockClient = new Guzzle($this->buildHttpMockClient(''));
|
||||
return new ResultSet($this->resultData);
|
||||
}));
|
||||
|
||||
$this->mockClient->expects($this->any())
|
||||
->method('write')
|
||||
->will($this->returnValue(true));
|
||||
|
||||
$httpMockClient = new GuzzleDriver($this->buildHttpMockClient(''));
|
||||
|
||||
// make sure the client has a valid driver
|
||||
$this->mockClient->expects($this->any())
|
||||
@ -88,7 +96,13 @@ abstract class AbstractTest extends \PHPUnit_Framework_TestCase
|
||||
public function buildHttpMockClient($body)
|
||||
{
|
||||
// Create a mock and queue two responses.
|
||||
$mock = new MockHandler([new Response(200, array(), $body)]);
|
||||
$mock = new MockHandler([
|
||||
new Response(200, array(), $body),
|
||||
new Response(200, array(), $body),
|
||||
new Response(400, array(), 'fault{'),
|
||||
new Response(400, array(), $body),
|
||||
new Response(400, array(), $body),
|
||||
]);
|
||||
|
||||
$handler = HandlerStack::create($mock);
|
||||
return new GuzzleClient(['handler' => $handler]);
|
||||
@ -114,7 +128,7 @@ abstract class AbstractTest extends \PHPUnit_Framework_TestCase
|
||||
->getMock();
|
||||
|
||||
if ($emptyResult) {
|
||||
$mockClient->expects($this->once())
|
||||
$mockClient->expects($this->any())
|
||||
->method('query')
|
||||
->will($this->returnValue(new ResultSet($this->getEmptyResult())));
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ class AdminTest extends AbstractTest
|
||||
|
||||
public function testShowUsers()
|
||||
{
|
||||
$testJson = file_get_contents(dirname(__FILE__) . '/result-test-users.example.json');
|
||||
$testJson = file_get_contents(dirname(__FILE__) . '/json/result-test-users.example.json');
|
||||
|
||||
$clientMock = $this->getClientMock();
|
||||
$testResult = new ResultSet($testJson);
|
||||
|
@ -4,6 +4,7 @@ namespace InfluxDB\Test;
|
||||
|
||||
use InfluxDB\Client;
|
||||
use InfluxDB\Driver\Guzzle;
|
||||
use InfluxDB\Point;
|
||||
|
||||
class ClientTest extends AbstractTest
|
||||
{
|
||||
@ -19,16 +20,26 @@ class ClientTest extends AbstractTest
|
||||
/** @var Client $client */
|
||||
protected $client = null;
|
||||
|
||||
public function testGetters()
|
||||
{
|
||||
$client = $this->getClient();
|
||||
|
||||
$this->assertEquals('http://localhost:8086', $client->getBaseURI());
|
||||
$this->assertInstanceOf('InfluxDB\Driver\Guzzle', $client->getDriver());
|
||||
$this->assertEquals('localhost', $client->getHost());
|
||||
$this->assertEquals('0', $client->getTimeout());
|
||||
}
|
||||
|
||||
public function testBaseURl()
|
||||
{
|
||||
$client = new Client('localhost', 8086);
|
||||
$client = $this->getClient();
|
||||
|
||||
$this->assertEquals($client->getBaseURI(), 'http://localhost:8086');
|
||||
}
|
||||
|
||||
public function testSelectDbShouldReturnDatabaseInstance()
|
||||
{
|
||||
$client = new Client('localhost', 8086);
|
||||
$client = $this->getClient();
|
||||
|
||||
$dbName = 'test-database';
|
||||
$database = $client->selectDB($dbName);
|
||||
@ -38,23 +49,110 @@ class ClientTest extends AbstractTest
|
||||
$this->assertEquals($dbName, $database->getName());
|
||||
}
|
||||
|
||||
public function testSecureInstance()
|
||||
{
|
||||
$client = $this->getClient('test', 'test', true);
|
||||
$urlParts = parse_url($client->getBaseURI());
|
||||
|
||||
$this->assertEquals('https', $urlParts['scheme']);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function testGuzzleQuery()
|
||||
{
|
||||
$client = new Client('localhost', 8086);
|
||||
$client = $this->getClient('test', 'test');
|
||||
$query = "some-bad-query";
|
||||
|
||||
$bodyResponse = file_get_contents(dirname(__FILE__) . '/result.example.json');
|
||||
$bodyResponse = file_get_contents(dirname(__FILE__) . '/json/result.example.json');
|
||||
$httpMockClient = $this->buildHttpMockClient($bodyResponse);
|
||||
|
||||
$client->setDriver(new Guzzle($httpMockClient));
|
||||
|
||||
/** @var \InfluxDB\ResultSet $result */
|
||||
$result = $client->query(null, $query);
|
||||
$result = $client->query('somedb', $query);
|
||||
|
||||
$parameters = $client->getDriver()->getParameters();
|
||||
|
||||
$this->assertEquals(['test', 'test'], $parameters['auth']);
|
||||
$this->assertEquals('somedb', $parameters['database']);
|
||||
$this->assertInstanceOf('\InfluxDB\ResultSet', $result);
|
||||
|
||||
$this->assertEquals(
|
||||
true,
|
||||
$client->write(
|
||||
[
|
||||
'url' => 'http://localhost',
|
||||
'database' => 'influx_test_db',
|
||||
'method' => 'post'
|
||||
],
|
||||
[new Point('test', 1.0)]
|
||||
)
|
||||
);
|
||||
|
||||
$this->setExpectedException('\InvalidArgumentException');
|
||||
$client->query('test', 'bad-query');
|
||||
|
||||
$this->setExpectedException('\InfluxDB\Driver\Exception');
|
||||
$client->query('test', 'bad-query');
|
||||
}
|
||||
|
||||
public function testGetLastQuery()
|
||||
{
|
||||
$this->mockClient->query('test', 'SELECT * from test_metric');
|
||||
$this->assertEquals($this->getClient()->getLastQuery(), 'SELECT * from test_metric');
|
||||
}
|
||||
|
||||
public function testListDatabases()
|
||||
{
|
||||
$this->doTestResponse('databases.example.json', ['test', 'test1', 'test2'], 'listDatabases');
|
||||
}
|
||||
public function testListUsers()
|
||||
{
|
||||
$this->doTestResponse('users.example.json', ['user', 'admin'], 'listUsers');
|
||||
}
|
||||
|
||||
public function testFactoryMethod()
|
||||
{
|
||||
$client = $this->getClient('test', 'test', true);
|
||||
|
||||
$staticClient = \InfluxDB\Client::fromDSN('https+influxdb://test:test@localhost:8086/');
|
||||
|
||||
$this->assertEquals($client, $staticClient);
|
||||
|
||||
$db = $client->selectDB('testdb');
|
||||
$staticDB = \InfluxDB\Client::fromDSN('https+influxdb://test:test@localhost:8086/testdb');
|
||||
|
||||
$this->assertEquals($db, $staticDB);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $responseFile
|
||||
* @param array $result
|
||||
* @param string $method
|
||||
*/
|
||||
protected function doTestResponse($responseFile, array $result, $method)
|
||||
{
|
||||
$client = $this->getClient();
|
||||
$bodyResponse = file_get_contents(dirname(__FILE__) . '/json/'. $responseFile);
|
||||
$httpMockClient = $this->buildHttpMockClient($bodyResponse);
|
||||
|
||||
$client->setDriver(new Guzzle($httpMockClient));
|
||||
|
||||
$this->assertEquals($result, $client->$method());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @param bool|false $ssl
|
||||
*
|
||||
* @return Client
|
||||
*/
|
||||
protected function getClient($username = '', $password = '', $ssl = false)
|
||||
{
|
||||
return new Client('localhost', 8086, $username, $password, $ssl);
|
||||
}
|
||||
|
||||
}
|
@ -27,34 +27,54 @@ class DatabaseTest extends AbstractTest
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->resultData = file_get_contents(dirname(__FILE__) . '/result.example.json');
|
||||
$this->resultData = file_get_contents(dirname(__FILE__) . '/json/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');
|
||||
$this->dataToInsert = file_get_contents(dirname(__FILE__) . '/json/input.example.json');
|
||||
|
||||
}
|
||||
|
||||
public function testGetters()
|
||||
{
|
||||
$this->assertInstanceOf('InfluxDB\Client', $this->database->getClient());
|
||||
$this->assertInstanceOf('InfluxDB\Query\Builder', $this->database->getQueryBuilder());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function testQuery()
|
||||
public function testQueries()
|
||||
{
|
||||
$testResultSet = new ResultSet($this->resultData);
|
||||
$this->assertEquals($this->database->query('SELECT * FROM test_metric'), $testResultSet);
|
||||
|
||||
$this->database->drop();
|
||||
$this->assertEquals('DROP DATABASE "influx_test_db"', Client::$lastQuery);
|
||||
|
||||
}
|
||||
|
||||
public function testCreateRetentionPolicy()
|
||||
|
||||
public function testRetentionPolicyQueries()
|
||||
{
|
||||
$retentionPolicy = new Database\RetentionPolicy('test', '1d', 1, true);
|
||||
$retentionPolicy = $this->getTestRetentionPolicy();
|
||||
|
||||
$mockClient = $this->getClientMock(true);
|
||||
$this->assertEquals(
|
||||
$this->getTestDatabase()->createRetentionPolicy($retentionPolicy),
|
||||
new ResultSet($this->getEmptyResult())
|
||||
);
|
||||
|
||||
$database = new Database('test', $mockClient);
|
||||
$this->database->listRetentionPolicies();
|
||||
$this->assertEquals('SHOW RETENTION POLICIES ON "influx_test_db"', Client::$lastQuery);
|
||||
|
||||
$this->assertEquals($database->createRetentionPolicy($retentionPolicy), new ResultSet($this->getEmptyResult()));
|
||||
$this->database->alterRetentionPolicy($this->getTestRetentionPolicy());
|
||||
$this->assertEquals(
|
||||
'ALTER RETENTION POLICY "test" ON "influx_test_db" DURATION 1d REPLICATION 1 DEFAULT',
|
||||
Client::$lastQuery
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -65,6 +85,38 @@ class DatabaseTest extends AbstractTest
|
||||
new Database(null, $this->mockClient);
|
||||
}
|
||||
|
||||
public function testCreate()
|
||||
{
|
||||
// test create with retention policy
|
||||
$this->database->create($this->getTestRetentionPolicy('influx_test_db'), true);
|
||||
$this->assertEquals(
|
||||
'CREATE RETENTION POLICY "influx_test_db" ON "influx_test_db" DURATION 1d REPLICATION 1 DEFAULT',
|
||||
Client::$lastQuery
|
||||
);
|
||||
|
||||
// test creating a database without create if not exists
|
||||
$this->database->create(null, true);
|
||||
$this->assertEquals('CREATE DATABASE IF NOT EXISTS "influx_test_db"', Client::$lastQuery);
|
||||
|
||||
// test creating a database without create if not exists
|
||||
$this->database->create(null, false);
|
||||
$this->assertEquals('CREATE DATABASE "influx_test_db"', Client::$lastQuery);
|
||||
|
||||
|
||||
$this->mockClient->expects($this->any())
|
||||
->method('query')
|
||||
->will($this->returnCallback(function () {
|
||||
throw new \Exception('test exception');
|
||||
}));
|
||||
|
||||
|
||||
// test an exception being handled correctly
|
||||
$this->setExpectedException('\InfluxDB\Database\Exception');
|
||||
$this->database->create($this->getTestRetentionPolicy('influx_test_db'), false);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function testExists()
|
||||
{
|
||||
$database = new Database('test', $this->mockClient);
|
||||
@ -96,5 +148,76 @@ class DatabaseTest extends AbstractTest
|
||||
);
|
||||
|
||||
$this->assertEquals(true, $this->database->writePoints(array($point1, $point2)));
|
||||
|
||||
$this->mockClient->expects($this->once())
|
||||
->method('write')
|
||||
->will($this->throwException(new \Exception('Test exception')));
|
||||
|
||||
$this->setExpectedException('InfluxDB\Exception');
|
||||
|
||||
$this->database->writePoints(array($point1, $point2));
|
||||
|
||||
}
|
||||
|
||||
public function testQueryBuilderOrderBy()
|
||||
{
|
||||
$this->assertEquals(
|
||||
$this->database->getQueryBuilder()
|
||||
->from('test_metric')
|
||||
->orderBy('time', 'DESC')->getQuery(),
|
||||
'SELECT * FROM "test_metric" ORDER BY time DESC');
|
||||
|
||||
$this->assertEquals(
|
||||
$this->database->getQueryBuilder()
|
||||
->from('test_metric')
|
||||
->orderBy('time', 'DESC')
|
||||
->orderBy('some_field', 'ASC')
|
||||
->getQuery(),
|
||||
'SELECT * FROM "test_metric" ORDER BY time DESC,some_field ASC');
|
||||
}
|
||||
|
||||
/**
|
||||
* @see https://github.com/influxdata/influxdb-php/pull/36
|
||||
*/
|
||||
public function testReservedNames()
|
||||
{
|
||||
$database = new Database('stats', $this->mockClient);
|
||||
|
||||
// test handling of reserved keywords in database name
|
||||
$database->create();
|
||||
$this->assertEquals('CREATE DATABASE IF NOT EXISTS "stats"', Client::$lastQuery);
|
||||
|
||||
$database->listRetentionPolicies();
|
||||
$this->assertEquals('SHOW RETENTION POLICIES ON "stats"', Client::$lastQuery);
|
||||
|
||||
// test handling of reserved keywords in retention policy names
|
||||
$database->create($this->getTestRetentionPolicy('default'));
|
||||
$this->assertEquals(
|
||||
'CREATE RETENTION POLICY "default" ON "stats" DURATION 1d REPLICATION 1 DEFAULT',
|
||||
Client::$lastQuery
|
||||
);
|
||||
|
||||
// test handling of reserved keywords in measurement names
|
||||
$this->assertEquals($database->getQueryBuilder()->from('server')->getQuery(), 'SELECT * FROM "server"');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return Database
|
||||
*/
|
||||
protected function getTestDatabase($name = 'test')
|
||||
{
|
||||
return new Database($name, $this->getClientMock(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return Database\RetentionPolicy
|
||||
*/
|
||||
protected function getTestRetentionPolicy($name = 'test')
|
||||
{
|
||||
return new Database\RetentionPolicy($name, '1d', 1, true);
|
||||
}
|
||||
}
|
@ -1,10 +1,4 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: dmartinez
|
||||
* Date: 18-6-15
|
||||
* Time: 17:39
|
||||
*/
|
||||
|
||||
namespace InfluxDB\Test;
|
||||
|
||||
@ -15,16 +9,119 @@ class PointTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testPointStringRepresentation()
|
||||
{
|
||||
$expected = 'cpu_load_short,host=server01,region=us-west cpucount=10,value=0.64 1435222310';
|
||||
$expected = 'instance,host=server01,region=us-west cpucount=10i,free=1i,test="string",bool=false,value=1.11 1440494531376778481';
|
||||
|
||||
$point = new Point(
|
||||
'cpu_load_short',
|
||||
0.64,
|
||||
array('host' => 'server01', 'region' => 'us-west'),
|
||||
array('cpucount' => 10),
|
||||
1435222310
|
||||
);
|
||||
$point = $this->getPoint('1440494531376778481');
|
||||
|
||||
$this->assertEquals($expected, (string) $point);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the Point class throw an exception when invalid timestamp are given.
|
||||
*
|
||||
* @dataProvider wrongTimestampProvider
|
||||
* @expectedException \InfluxDB\Database\Exception
|
||||
*/
|
||||
public function testPointWrongTimestamp($timestamp)
|
||||
{
|
||||
$this->getPoint($timestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the Point class accept all valid timestamp given.
|
||||
*
|
||||
* @dataProvider validTimestampProvider
|
||||
*/
|
||||
public function testPointValidTimestamp($timestamp)
|
||||
{
|
||||
$expected = 'instance,host=server01,region=us-west cpucount=10i,free=1i,test="string",bool=false,value=1.11' . (($timestamp) ? ' ' . $timestamp : '');
|
||||
|
||||
$point = $this->getPoint($timestamp);
|
||||
|
||||
$this->assertEquals($expected, (string) $point);
|
||||
}
|
||||
|
||||
public function testGettersAndSetters()
|
||||
{
|
||||
$timestamp = time();
|
||||
$timestamp2 = time() + 3600;
|
||||
$point = $this->getPoint($timestamp);
|
||||
|
||||
$this->assertEquals($timestamp, $point->getTimestamp());
|
||||
$point->setTimestamp($timestamp2);
|
||||
$this->assertEquals($timestamp2, $point->getTimestamp());
|
||||
|
||||
$this->assertEquals('instance', $point->getMeasurement());
|
||||
$point->setMeasurement('test');
|
||||
$this->assertEquals('test', $point->getMeasurement());
|
||||
|
||||
$fields = $point->getFields();
|
||||
$this->assertEquals(1.11, $fields['value']);
|
||||
$this->assertEquals([
|
||||
'cpucount' => '10i',
|
||||
'free' => '1i',
|
||||
'test' => "\"string\"",
|
||||
'bool' => 'false',
|
||||
'value' => '1.1100000000000001'
|
||||
], $fields);
|
||||
|
||||
$point->setFields(['cpucount' => 11]);
|
||||
$this->assertEquals(['cpucount' => '11i'], $point->getFields());
|
||||
|
||||
$this->assertEquals(['host' => 'server01', 'region' => 'us-west'], $point->getTags());
|
||||
$point->setTags(['test' => 'value']);
|
||||
$this->assertEquals(['test' => 'value'], $point->getTags());
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Provide wrong timestamp value for testing.
|
||||
*/
|
||||
public function wrongTimestampProvider()
|
||||
{
|
||||
return [
|
||||
['2015-10-27 14:17:40'],
|
||||
['INVALID'],
|
||||
['aa778481'],
|
||||
['1477aee'],
|
||||
['15.258'],
|
||||
['15,258'],
|
||||
[15.258],
|
||||
[true]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide valid timestamp value for testing.
|
||||
*/
|
||||
public function validTimestampProvider()
|
||||
{
|
||||
return [
|
||||
[time()], // Current time returned by the PHP time function.
|
||||
[0], // Day 0
|
||||
[~PHP_INT_MAX], // Minimum value integer
|
||||
[PHP_INT_MAX], // Maximum value integer
|
||||
['1440494531376778481'] // Text timestamp
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an instance of \InfluxDB\Point
|
||||
*
|
||||
* @param int $timestamp
|
||||
*
|
||||
* @return Point
|
||||
*/
|
||||
private function getPoint($timestamp)
|
||||
{
|
||||
return new Point(
|
||||
'instance', // the name of the measurement
|
||||
1.11, // measurement value
|
||||
['host' => 'server01', 'region' => 'us-west'],
|
||||
['cpucount' => 10, 'free' => 1, 'test' => "string", 'bool' => false],
|
||||
$timestamp
|
||||
);
|
||||
}
|
||||
|
||||
}
|
@ -10,7 +10,7 @@ class ResultSetTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$resultJsonExample = file_get_contents(dirname(__FILE__) . '/result.example.json');
|
||||
$resultJsonExample = file_get_contents(dirname(__FILE__) . '/json/result.example.json');
|
||||
$this->resultSet = new ResultSet($resultJsonExample);
|
||||
}
|
||||
|
||||
@ -65,7 +65,7 @@ EOD;
|
||||
*/
|
||||
public function testGetPointsFromNameWithoudTags()
|
||||
{
|
||||
$resultJsonExample = file_get_contents(dirname(__FILE__) . '/result-no-tags.example.json');
|
||||
$resultJsonExample = file_get_contents(dirname(__FILE__) . '/json/result-no-tags.example.json');
|
||||
$this->resultSet = new ResultSet($resultJsonExample);
|
||||
|
||||
$measurementName = 'cpu_load_short';
|
||||
@ -95,6 +95,11 @@ EOD;
|
||||
|
||||
}
|
||||
|
||||
public function testGetSeries()
|
||||
{
|
||||
$this->assertEquals(['time', 'value'], $this->resultSet->getColumns());
|
||||
}
|
||||
|
||||
/**
|
||||
* We can get points from measurement
|
||||
*/
|
||||
|
25
lib/influxdb-php/tests/unit/json/databases.example.json
Normal file
25
lib/influxdb-php/tests/unit/json/databases.example.json
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"results":[
|
||||
{
|
||||
"series":[
|
||||
{
|
||||
"name":"databases",
|
||||
"columns":[
|
||||
"name"
|
||||
],
|
||||
"values":[
|
||||
[
|
||||
"test"
|
||||
],
|
||||
[
|
||||
"test1"
|
||||
],
|
||||
[
|
||||
"test2"
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
14
lib/influxdb-php/tests/unit/json/users.example.json
Normal file
14
lib/influxdb-php/tests/unit/json/users.example.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"results":[
|
||||
{
|
||||
"series":[
|
||||
{
|
||||
"columns":[
|
||||
"user",
|
||||
"admin"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
Reference in New Issue
Block a user