mirror of
https://github.com/stylersnico/librenms.git
synced 2026-08-02 00:32:09 +02: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
|
language: php
|
||||||
|
sudo: false
|
||||||
|
|
||||||
php:
|
php:
|
||||||
- 5.5
|
- 5.5
|
||||||
- 5.6
|
- 5.6
|
||||||
|
- 7.0
|
||||||
|
|
||||||
install:
|
install:
|
||||||
|
- composer selfupdate
|
||||||
- composer install
|
- composer install
|
||||||
|
|
||||||
addons:
|
addons:
|
||||||
code_climate:
|
code_climate:
|
||||||
repo_token: 5371d86d298d66eb9007cc8de462d7063e58f6dd85e430928834736edee479a9
|
repo_token: 303a289e61e8e11d8bcae115860c4fffc6e1e7fe2d504d20a773e69bd7641284
|
||||||
|
|
||||||
after_script:
|
after_script:
|
||||||
- vendor/bin/test-reporter
|
- vendor/bin/test-reporter
|
||||||
|
|||||||
+169
-142
@@ -1,12 +1,12 @@
|
|||||||
# influxdb-php
|
# influxdb-php
|
||||||
## InfluxDB client library for PHP
|
## InfluxDB client library for PHP
|
||||||
[](https://travis-ci.org/influxdb/influxdb-php)
|
[](https://travis-ci.org/influxdata/influxdb-php)
|
||||||
[](https://codeclimate.com/github/influxdb/influxdb-php)
|
[](https://codeclimate.com/github/influxdata/influxdb-php)
|
||||||
[](https://codeclimate.com/github/influxdb/influxdb-php/coverage)
|
[](https://codeclimate.com/github/influxdata/influxdb-php/coverage)
|
||||||
|
|
||||||
### Overview
|
### 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.
|
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.
|
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:
|
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
|
### 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:
|
Initialize a new client object:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
|
|
||||||
$client = new InfluxDB\Client($host, $port);
|
$client = new InfluxDB\Client($host, $port);
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
This will create a new client object which you can use to read and write points to InfluxDB.
|
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):
|
It's also possible to create a client from a DSN (Data Source Name):
|
||||||
|
|
||||||
```php
|
```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
|
// get the client to retrieve other databases
|
||||||
$database = InfluxDB\Client::fromDSN(sprintf('influxdb://user:pass@%s:%s/%s', $host, $port, $dbname));
|
$client = $database->getClient();
|
||||||
|
|
||||||
// get the client to retrieve other databases
|
|
||||||
$client = $database->getClient();
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Reading
|
### 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:
|
To fetch records from InfluxDB you can do a query directly on a database:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
|
// fetch the database
|
||||||
|
$database = $client->selectDB('influx_test_db');
|
||||||
|
|
||||||
// fetch the database
|
// executing a query will yield a resultset object
|
||||||
$database = $client->selectDB('influx_test_db');
|
$result = $database->query('select * from test_metric LIMIT 5');
|
||||||
|
|
||||||
// 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();
|
|
||||||
|
|
||||||
|
// 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.
|
It's also possible to use the QueryBuilder object. This is a class that simplifies the process of building queries.
|
||||||
|
|
||||||
```php
|
```php
|
||||||
|
// retrieve points with the query builder
|
||||||
|
$result = $database->getQueryBuilder()
|
||||||
|
->select('cpucount')
|
||||||
|
->from('test_metric')
|
||||||
|
->limit(2)
|
||||||
|
->getResultSet()
|
||||||
|
->getPoints();
|
||||||
|
|
||||||
// retrieve points with the query builder
|
// get the query from the QueryBuilder
|
||||||
$result = $database->getQueryBuilder()
|
$query = $database->getQueryBuilder()
|
||||||
->select('cpucount')
|
->select('cpucount')
|
||||||
->from('test_metric')
|
->from('test_metric')
|
||||||
->limit(2)
|
->where(["region = 'us-west'"])
|
||||||
->getResultSet()
|
->getQuery();
|
||||||
->getPoints();
|
```
|
||||||
|
|
||||||
|
Make sure that you enter single quotes when doing a where query on strings; otherwise InfluxDB will return an empty result.
|
||||||
|
|
||||||
// get the query from the QueryBuilder
|
You can get the last executed query from the client:
|
||||||
$query = $database->getQueryBuilder()
|
|
||||||
->select('cpucount')
|
|
||||||
->from('test_metric')
|
|
||||||
->getQuery();
|
|
||||||
|
|
||||||
|
```php
|
||||||
|
// use the getLastQuery() method
|
||||||
|
$lastQuery = $client->getLastQuery();
|
||||||
|
|
||||||
|
// or access the static variable directly:
|
||||||
|
$lastQuery = Client::lastQuery;
|
||||||
```
|
```
|
||||||
|
|
||||||
### Writing data
|
### Writing data
|
||||||
@@ -90,28 +95,26 @@ 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:
|
Writing data is done by providing an array of points to the writePoints method on a database:
|
||||||
|
|
||||||
```php
|
```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!
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
// create an array of points
|
// we are writing unix timestamps, which have a second precision
|
||||||
$points = array(
|
$result = $database->writePoints($points, Database::PRECISION_SECONDS);
|
||||||
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
|
It's possible to add multiple [fields](https://influxdb.com/docs/v0.9/concepts/key_concepts.html) when writing
|
||||||
@@ -123,22 +126,22 @@ InfluxDB takes the current time as the default timestamp.
|
|||||||
You can also write multiple fields to a measurement without specifying a value:
|
You can also write multiple fields to a measurement without specifying a value:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
$points = [
|
$points = [
|
||||||
new Point(
|
new Point(
|
||||||
'instance', // the name of the measurement
|
'instance', // the name of the measurement
|
||||||
null, // measurement value
|
null, // measurement value
|
||||||
['host' => 'server01', 'region' => 'us-west'], // measurement tags
|
['host' => 'server01', 'region' => 'us-west'], // measurement tags
|
||||||
['cpucount' => 10, 'free' => 1], // measurement fields
|
['cpucount' => 10, 'free' => 1], // measurement fields
|
||||||
exec('date +%s%N') // timestamp in nanoseconds on Linux ONLY
|
exec('date +%s%N') // timestamp in nanoseconds on Linux ONLY
|
||||||
),
|
),
|
||||||
new Point(
|
new Point(
|
||||||
'instance', // the name of the measurement
|
'instance', // the name of the measurement
|
||||||
null, // measurement value
|
null, // measurement value
|
||||||
['host' => 'server01', 'region' => 'us-west'], // measurement tags
|
['host' => 'server01', 'region' => 'us-west'], // measurement tags
|
||||||
['cpucount' => 10, 'free' => 2], // measurement fields
|
['cpucount' => 10, 'free' => 2], // measurement fields
|
||||||
exec('date +%s%N') // timestamp in nanoseconds on Linux ONLY
|
exec('date +%s%N') // timestamp in nanoseconds on Linux ONLY
|
||||||
)
|
)
|
||||||
];
|
];
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -156,33 +159,31 @@ First, set your InfluxDB host to support incoming UDP sockets:
|
|||||||
Then, configure the UDP driver in the client:
|
Then, configure the UDP driver in the client:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
|
// set the UDP driver in the client
|
||||||
|
$client->setDriver(new \InfluxDB\Driver\UDP($client->getHost(), 4444));
|
||||||
|
|
||||||
// set the UDP driver in the client
|
$points = [
|
||||||
$client->setDriver(new \InfluxDB\Driver\UDP($client->getHost(), 4444));
|
new Point(
|
||||||
|
'test_metric',
|
||||||
|
0.84,
|
||||||
|
['host' => 'server01', 'region' => 'us-west'],
|
||||||
|
['cpucount' => 10],
|
||||||
|
exec('date +%s%N') // this will produce a nanosecond timestamp on Linux ONLY
|
||||||
|
)
|
||||||
|
];
|
||||||
|
|
||||||
$points = [
|
// now just write your points like you normally would
|
||||||
new Point(
|
$result = $database->writePoints($points);
|
||||||
'test_metric',
|
|
||||||
0.84,
|
|
||||||
['host' => 'server01', 'region' => 'us-west'],
|
|
||||||
['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);
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Or simply use a DSN (Data Source Name) to send metrics using UDP:
|
Or simply use a DSN (Data Source Name) to send metrics using UDP:
|
||||||
|
|
||||||
```php
|
```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)
|
// write your points
|
||||||
$database = \InfluxDB\Client::fromDSN('udp+influxdb://username:pass@localhost:4444/test123');
|
$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
|
*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.
|
if you specify a timestamp in seconds and the default (nanosecond) precision is set; the entered timestamp will be invalid.
|
||||||
|
|
||||||
```php
|
```php
|
||||||
// Points will require a nanosecond precision (this is default as per influxdb standard)
|
// Points will require a nanosecond precision (this is default as per influxdb standard)
|
||||||
$newPoints = $database->writePoints($points);
|
$newPoints = $database->writePoints($points);
|
||||||
|
|
||||||
// Points will require second precision
|
// Points will require second precision
|
||||||
$newPoints = $database->writePoints($points, Database::PRECISION_SECONDS);
|
$newPoints = $database->writePoints($points, Database::PRECISION_SECONDS);
|
||||||
|
|
||||||
// Points will require microsecond precision
|
// Points will require microsecond precision
|
||||||
$newPoints = $database->writePoints($points, Database::PRECISION_MICROSECONDS);
|
$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:
|
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
|
```php
|
||||||
list( $usec, $sec ) = explode(' ', microtime() );
|
list($usec, $sec) = explode(' ', microtime());
|
||||||
$timestamp = sprintf( '%d%06d', $sec, $usec*1000000 );
|
$timestamp = sprintf('%d%06d', $sec, $usec*1000000);
|
||||||
```
|
```
|
||||||
|
|
||||||
### Creating databases
|
### 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:
|
This library makes it easy to provide a retention policy when creating a database:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
|
// create the client
|
||||||
|
$client = new \InfluxDB\Client($host, $port, '', '');
|
||||||
|
|
||||||
// create the client
|
// select the database
|
||||||
$client = new \InfluxDB\Client($host, $port, '', '');
|
$database = $client->selectDB('influx_test_db');
|
||||||
|
|
||||||
// select the database
|
// create the database with a retention policy
|
||||||
$database = $client->selectDB('influx_test_db');
|
$result = $database->create(new RetentionPolicy('test', '5d', 1, true));
|
||||||
|
|
||||||
// create the database with a retention policy
|
// check if a database exists then create it if it doesn't
|
||||||
$result = $database->create(new RetentionPolicy('test', '5d', 1, true));
|
$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()) {
|
|
||||||
$database->create(new RetentionPolicy('test', '1d', 2, true));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (!$database->exists()) {
|
||||||
|
$database->create(new RetentionPolicy('test', '1d', 2, true));
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
You can also alter retention policies:
|
You can also alter retention policies:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
$database->alterRetentionPolicy(new RetentionPolicy('test', '2d', 5, true));
|
$database->alterRetentionPolicy(new RetentionPolicy('test', '2d', 5, true));
|
||||||
```
|
```
|
||||||
|
|
||||||
and list them:
|
and list them:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
$result = $database->listRetentionPolicies();
|
$result = $database->listRetentionPolicies();
|
||||||
```
|
```
|
||||||
|
|
||||||
You can add more retention policies to a database:
|
You can add more retention policies to a database:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
$result = $database->createRetentionPolicy(new RetentionPolicy('test2', '30d', 1, true));
|
$result = $database->createRetentionPolicy(new RetentionPolicy('test2', '30d', 1, true));
|
||||||
```
|
```
|
||||||
|
|
||||||
### Client functions
|
### 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:
|
Some functions are too general for a database. So these are available in the client:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
|
// list users
|
||||||
|
$result = $client->listUsers();
|
||||||
|
|
||||||
// list users
|
// list databases
|
||||||
$result = $client->listUsers();
|
$result = $client->listDatabases();
|
||||||
|
|
||||||
// list databases
|
|
||||||
$result = $client->listDatabases();
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Admin functionality
|
### 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.
|
You can use the client's $client->admin functionality to administer InfluxDB via the API.
|
||||||
|
|
||||||
```php
|
```php
|
||||||
// add a new user without privileges
|
// add a new user without privileges
|
||||||
$client->admin->createUser('testuser123', 'testpassword');
|
$client->admin->createUser('testuser123', 'testpassword');
|
||||||
|
|
||||||
// add a new user with ALL cluster-wide privileges
|
// add a new user with ALL cluster-wide privileges
|
||||||
$client->admin->createUser('admin_user', 'password', \InfluxDB\Client\Admin::PRIVILEGE_ALL);
|
$client->admin->createUser('admin_user', 'password', \InfluxDB\Client\Admin::PRIVILEGE_ALL);
|
||||||
|
|
||||||
// drop user testuser123
|
// drop user testuser123
|
||||||
$client->admin->dropUser('testuser123');
|
$client->admin->dropUser('testuser123');
|
||||||
```
|
```
|
||||||
|
|
||||||
List all the users:
|
List all the users:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
// show a list of all users
|
// show a list of all users
|
||||||
$results = $client->admin->showUsers();
|
$results = $client->admin->showUsers();
|
||||||
|
|
||||||
// show users returns a ResultSet object
|
// show users returns a ResultSet object
|
||||||
$users = $results->getPoints();
|
$users = $results->getPoints();
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Granting and revoking privileges
|
#### 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.
|
To grant a user specific privileges on a database, provide a database object or a database name.
|
||||||
|
|
||||||
```php
|
```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
|
// give user testuser123 read privileges on database test_db
|
||||||
$database = $client->selectDB('test_db');
|
$client->admin->grant(\InfluxDB\Client\Admin::PRIVILEGE_READ, 'testuser123', 'test_db');
|
||||||
$client->admin->grant(\InfluxDB\Client\Admin::PRIVILEGE_READ, 'testuser123', $database);
|
|
||||||
|
|
||||||
// give user testuser123 read privileges on database test_db
|
// revoke user testuser123's read privileges on database test_db
|
||||||
$client->admin->grant(\InfluxDB\Client\Admin::PRIVILEGE_READ, 'testuser123', 'test_db');
|
$client->admin->revoke(\InfluxDB\Client\Admin::PRIVILEGE_READ, 'testuser123', 'test_db');
|
||||||
|
|
||||||
// revoke user testuser123's read privileges on database test_db
|
// grant a user cluster-wide privileges
|
||||||
$client->admin->revoke(\InfluxDB\Client\Admin::PRIVILEGE_READ, 'testuser123', 'test_db');
|
$client->admin->grant(\InfluxDB\Client\Admin::PRIVILEGE_READ, 'testuser123');
|
||||||
|
|
||||||
// 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');
|
|
||||||
|
|
||||||
|
// Revoke an admin's cluster-wide privileges
|
||||||
|
$client->admin->revoke(\InfluxDB\Client\Admin::PRIVILEGE_ALL, 'admin_user');
|
||||||
```
|
```
|
||||||
|
|
||||||
## Todo
|
## Todo
|
||||||
@@ -329,6 +325,37 @@ To grant a user specific privileges on a database, provide a database object or
|
|||||||
|
|
||||||
## Changelog
|
## 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
|
####1.0.1
|
||||||
* Added support for authentication in the guzzle driver
|
* Added support for authentication in the guzzle driver
|
||||||
* Added admin functionality
|
* Added admin functionality
|
||||||
|
|||||||
Vendored
+43
@@ -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
|
||||||
@@ -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 }
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
mtchavez.influxdb
|
||||||
@@ -19,14 +19,19 @@
|
|||||||
{
|
{
|
||||||
"name": "Daniel Martinez",
|
"name": "Daniel Martinez",
|
||||||
"email": "danimartcas@hotmail.com"
|
"email": "danimartcas@hotmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Gianluca Arbezzano",
|
||||||
|
"email": "gianarb92@gmail.com"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=5.5",
|
"php": "^5.5 | ^7.0",
|
||||||
"guzzlehttp/guzzle": "6.*",
|
"guzzlehttp/guzzle": "6.*",
|
||||||
"symfony/event-dispatcher": "2.*"
|
"symfony/event-dispatcher": "2.*|3.*"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "^4.0",
|
||||||
"codeclimate/php-test-reporter": "0.*",
|
"codeclimate/php-test-reporter": "0.*",
|
||||||
"symfony/config": "~2.8",
|
"symfony/config": "~2.8",
|
||||||
"symfony/console": "~2.8",
|
"symfony/console": "~2.8",
|
||||||
|
|||||||
Generated
+1065
-98
File diff suppressed because it is too large
Load Diff
Executable
+14
@@ -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;
|
protected $driver;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores the last query that ran
|
||||||
|
*
|
||||||
|
* @var null
|
||||||
|
*/
|
||||||
|
public static $lastQuery = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $host
|
* @param string $host
|
||||||
* @param int $port
|
* @param int $port
|
||||||
@@ -103,7 +111,7 @@ class Client
|
|||||||
$username = '',
|
$username = '',
|
||||||
$password = '',
|
$password = '',
|
||||||
$ssl = false,
|
$ssl = false,
|
||||||
$verifySSL = true,
|
$verifySSL = false,
|
||||||
$timeout = 0
|
$timeout = 0
|
||||||
) {
|
) {
|
||||||
$this->host = (string) $host;
|
$this->host = (string) $host;
|
||||||
@@ -183,6 +191,9 @@ class Client
|
|||||||
$driver->setParameters($parameters);
|
$driver->setParameters($parameters);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// store the last query sent
|
||||||
|
static::$lastQuery = $query;
|
||||||
|
|
||||||
// perform the query and return the resultset
|
// perform the query and return the resultset
|
||||||
return $driver->query();
|
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
|
* List all the databases
|
||||||
*/
|
*/
|
||||||
@@ -209,9 +247,9 @@ class Client
|
|||||||
*/
|
*/
|
||||||
public function listUsers()
|
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;
|
return $this->host;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the last executed query
|
||||||
|
*
|
||||||
|
* @return null|string
|
||||||
|
*/
|
||||||
|
public function getLastQuery()
|
||||||
|
{
|
||||||
|
return static::$lastQuery;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Point[] $points
|
* @param Point[] $points
|
||||||
* @return array
|
* @return array
|
||||||
|
|||||||
@@ -77,14 +77,21 @@ class Database
|
|||||||
* Create this database
|
* Create this database
|
||||||
*
|
*
|
||||||
* @param RetentionPolicy $retentionPolicy
|
* @param RetentionPolicy $retentionPolicy
|
||||||
|
* @param bool $createIfNotExists Only create the database if it does not yet exist
|
||||||
|
*
|
||||||
* @return ResultSet
|
* @return ResultSet
|
||||||
* @throws DatabaseException
|
* @throws DatabaseException
|
||||||
* @throws Exception
|
|
||||||
*/
|
*/
|
||||||
public function create(RetentionPolicy $retentionPolicy = null)
|
public function create(RetentionPolicy $retentionPolicy = null, $createIfNotExists = true)
|
||||||
{
|
{
|
||||||
try {
|
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) {
|
if ($retentionPolicy) {
|
||||||
$this->createRetentionPolicy($retentionPolicy);
|
$this->createRetentionPolicy($retentionPolicy);
|
||||||
@@ -125,25 +132,13 @@ class Database
|
|||||||
);
|
);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$driver = $this->client->getDriver();
|
|
||||||
|
|
||||||
$parameters = [
|
$parameters = [
|
||||||
'url' => sprintf('write?db=%s&precision=%s', $this->name, $precision),
|
'url' => sprintf('write?db=%s&precision=%s', $this->name, $precision),
|
||||||
'database' => $this->name,
|
'database' => $this->name,
|
||||||
'method' => 'post'
|
'method' => 'post'
|
||||||
];
|
];
|
||||||
|
|
||||||
// add authentication to the driver if needed
|
return $this->client->write($parameters, $payload);
|
||||||
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) {
|
} catch (\Exception $e) {
|
||||||
throw new Exception($e->getMessage(), $e->getCode());
|
throw new Exception($e->getMessage(), $e->getCode());
|
||||||
@@ -174,7 +169,7 @@ class Database
|
|||||||
*/
|
*/
|
||||||
public function listRetentionPolicies()
|
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()
|
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)
|
protected function getRetentionPolicyQuery($method, RetentionPolicy $retentionPolicy)
|
||||||
{
|
{
|
||||||
if (!in_array($method, ['CREATE', 'ALTER'])) {
|
|
||||||
throw new \InvalidArgumentException(sprintf('%s is not a valid method'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$query = sprintf(
|
$query = sprintf(
|
||||||
'%s RETENTION POLICY %s ON %s DURATION %s REPLICATION %s',
|
'%s RETENTION POLICY "%s" ON "%s" DURATION %s REPLICATION %s',
|
||||||
$method,
|
$method,
|
||||||
$retentionPolicy->name,
|
$retentionPolicy->name,
|
||||||
$this->name,
|
$this->name,
|
||||||
|
|||||||
@@ -30,6 +30,11 @@ interface DriverInterface
|
|||||||
*/
|
*/
|
||||||
public function setParameters(array $parameters);
|
public function setParameters(array $parameters);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getParameters();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send the data
|
* Send the data
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -68,6 +68,14 @@ class Guzzle implements DriverInterface, QueryDriverInterface
|
|||||||
$this->parameters = $parameters;
|
$this->parameters = $parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getParameters()
|
||||||
|
{
|
||||||
|
return $this->parameters;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send the data
|
* Send the data
|
||||||
*
|
*
|
||||||
@@ -87,17 +95,10 @@ class Guzzle implements DriverInterface, QueryDriverInterface
|
|||||||
*/
|
*/
|
||||||
public function query()
|
public function query()
|
||||||
{
|
{
|
||||||
|
|
||||||
$response = $this->httpClient->get($this->parameters['url'], $this->getRequestParameters());
|
$response = $this->httpClient->get($this->parameters['url'], $this->getRequestParameters());
|
||||||
|
|
||||||
$raw = (string) $response->getBody();
|
$raw = (string) $response->getBody();
|
||||||
|
|
||||||
$responseJson = json_encode($raw);
|
|
||||||
|
|
||||||
if (isset($responseJson->error)) {
|
|
||||||
throw new Exception($responseJson->error);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new ResultSet($raw);
|
return new ResultSet($raw);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -109,7 +110,14 @@ class Guzzle implements DriverInterface, QueryDriverInterface
|
|||||||
*/
|
*/
|
||||||
public function isSuccess()
|
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;
|
$this->parameters = $parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getParameters()
|
||||||
|
{
|
||||||
|
return $this->parameters;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send the data
|
* Send the data
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -14,22 +14,22 @@ class Point
|
|||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private $measurement;
|
protected $measurement;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private $tags = [];
|
protected $tags = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private $fields = [];
|
protected $fields = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private $timestamp;
|
protected $timestamp;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The timestamp is optional. If you do not specify a timestamp the server’s
|
* 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->measurement = (string) $measurement;
|
||||||
$this->tags = $tags;
|
$this->tags = $tags;
|
||||||
$this->fields = $additionalFields;
|
$fields = $additionalFields;
|
||||||
|
|
||||||
if ($value) {
|
if ($value !== null) {
|
||||||
$this->fields['value'] = $value;
|
$fields['value'] = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->setFields($fields);
|
||||||
|
|
||||||
if ($timestamp && !$this->isValidTimeStamp($timestamp)) {
|
if ($timestamp && !$this->isValidTimeStamp($timestamp)) {
|
||||||
throw new DatabaseException(sprintf('%s is not a valid timestamp', $timestamp));
|
throw new DatabaseException(sprintf('%s is not a valid timestamp', $timestamp));
|
||||||
}
|
}
|
||||||
@@ -80,10 +82,10 @@ class Point
|
|||||||
$string = $this->measurement;
|
$string = $this->measurement;
|
||||||
|
|
||||||
if (count($this->tags) > 0) {
|
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) {
|
if ($this->timestamp) {
|
||||||
$string .= ' '.$this->timestamp;
|
$string .= ' '.$this->timestamp;
|
||||||
@@ -92,6 +94,116 @@ class Point
|
|||||||
return $string;
|
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
|
* @param array $arr
|
||||||
* @return string
|
* @return string
|
||||||
@@ -113,14 +225,26 @@ class Point
|
|||||||
*/
|
*/
|
||||||
private function isValidTimeStamp($timestamp)
|
private function isValidTimeStamp($timestamp)
|
||||||
{
|
{
|
||||||
if ((int) $timestamp === $timestamp) {
|
|
||||||
|
// 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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($timestamp <= PHP_INT_MAX && $timestamp >= ~PHP_INT_MAX) {
|
if (!is_numeric($timestamp)) {
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
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 = '';
|
protected $limitClause = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $groupBy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $orderBy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Database $db
|
* @param Database $db
|
||||||
*/
|
*/
|
||||||
@@ -178,6 +188,18 @@ class Builder
|
|||||||
return $this;
|
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
|
* Set's the time range to select data from
|
||||||
*
|
*
|
||||||
@@ -244,7 +266,7 @@ class Builder
|
|||||||
*/
|
*/
|
||||||
protected function parseQuery()
|
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) {
|
if (! $this->metric) {
|
||||||
throw new \InvalidArgumentException('No metric provided to from()');
|
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) {
|
if ($this->limitClause) {
|
||||||
$query .= $this->limitClause;
|
$query .= $this->limitClause;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,6 +89,14 @@ class ResultSet
|
|||||||
return array_shift($series);
|
return array_shift($series);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function getColumns()
|
||||||
|
{
|
||||||
|
return $this->getSeries()[0]['columns'];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $serie
|
* @param array $serie
|
||||||
* @return array
|
* @return array
|
||||||
|
|||||||
@@ -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 GuzzleHttp\HandlerStack;
|
||||||
use InfluxDB\Client;
|
use InfluxDB\Client;
|
||||||
use InfluxDB\Database;
|
use InfluxDB\Database;
|
||||||
use InfluxDB\Driver\Guzzle;
|
use InfluxDB\Driver\Guzzle as GuzzleDriver;
|
||||||
use InfluxDB\ResultSet;
|
use InfluxDB\ResultSet;
|
||||||
use PHPUnit_Framework_MockObject_MockObject;
|
use PHPUnit_Framework_MockObject_MockObject;
|
||||||
use GuzzleHttp\Client as GuzzleClient;
|
use GuzzleHttp\Client as GuzzleClient;
|
||||||
@@ -44,7 +44,7 @@ abstract class AbstractTest extends \PHPUnit_Framework_TestCase
|
|||||||
->disableOriginalConstructor()
|
->disableOriginalConstructor()
|
||||||
->getMock();
|
->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())
|
$this->mockClient->expects($this->any())
|
||||||
->method('getBaseURI')
|
->method('getBaseURI')
|
||||||
@@ -52,9 +52,17 @@ abstract class AbstractTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
$this->mockClient->expects($this->any())
|
$this->mockClient->expects($this->any())
|
||||||
->method('query')
|
->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
|
// make sure the client has a valid driver
|
||||||
$this->mockClient->expects($this->any())
|
$this->mockClient->expects($this->any())
|
||||||
@@ -88,7 +96,13 @@ abstract class AbstractTest extends \PHPUnit_Framework_TestCase
|
|||||||
public function buildHttpMockClient($body)
|
public function buildHttpMockClient($body)
|
||||||
{
|
{
|
||||||
// Create a mock and queue two responses.
|
// 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);
|
$handler = HandlerStack::create($mock);
|
||||||
return new GuzzleClient(['handler' => $handler]);
|
return new GuzzleClient(['handler' => $handler]);
|
||||||
@@ -114,7 +128,7 @@ abstract class AbstractTest extends \PHPUnit_Framework_TestCase
|
|||||||
->getMock();
|
->getMock();
|
||||||
|
|
||||||
if ($emptyResult) {
|
if ($emptyResult) {
|
||||||
$mockClient->expects($this->once())
|
$mockClient->expects($this->any())
|
||||||
->method('query')
|
->method('query')
|
||||||
->will($this->returnValue(new ResultSet($this->getEmptyResult())));
|
->will($this->returnValue(new ResultSet($this->getEmptyResult())));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ class AdminTest extends AbstractTest
|
|||||||
|
|
||||||
public function testShowUsers()
|
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();
|
$clientMock = $this->getClientMock();
|
||||||
$testResult = new ResultSet($testJson);
|
$testResult = new ResultSet($testJson);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ namespace InfluxDB\Test;
|
|||||||
|
|
||||||
use InfluxDB\Client;
|
use InfluxDB\Client;
|
||||||
use InfluxDB\Driver\Guzzle;
|
use InfluxDB\Driver\Guzzle;
|
||||||
|
use InfluxDB\Point;
|
||||||
|
|
||||||
class ClientTest extends AbstractTest
|
class ClientTest extends AbstractTest
|
||||||
{
|
{
|
||||||
@@ -19,16 +20,26 @@ class ClientTest extends AbstractTest
|
|||||||
/** @var Client $client */
|
/** @var Client $client */
|
||||||
protected $client = null;
|
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()
|
public function testBaseURl()
|
||||||
{
|
{
|
||||||
$client = new Client('localhost', 8086);
|
$client = $this->getClient();
|
||||||
|
|
||||||
$this->assertEquals($client->getBaseURI(), 'http://localhost:8086');
|
$this->assertEquals($client->getBaseURI(), 'http://localhost:8086');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSelectDbShouldReturnDatabaseInstance()
|
public function testSelectDbShouldReturnDatabaseInstance()
|
||||||
{
|
{
|
||||||
$client = new Client('localhost', 8086);
|
$client = $this->getClient();
|
||||||
|
|
||||||
$dbName = 'test-database';
|
$dbName = 'test-database';
|
||||||
$database = $client->selectDB($dbName);
|
$database = $client->selectDB($dbName);
|
||||||
@@ -38,23 +49,110 @@ class ClientTest extends AbstractTest
|
|||||||
$this->assertEquals($dbName, $database->getName());
|
$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()
|
public function testGuzzleQuery()
|
||||||
{
|
{
|
||||||
$client = new Client('localhost', 8086);
|
$client = $this->getClient('test', 'test');
|
||||||
$query = "some-bad-query";
|
$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);
|
$httpMockClient = $this->buildHttpMockClient($bodyResponse);
|
||||||
|
|
||||||
$client->setDriver(new Guzzle($httpMockClient));
|
$client->setDriver(new Guzzle($httpMockClient));
|
||||||
|
|
||||||
/** @var \InfluxDB\ResultSet $result */
|
/** @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->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();
|
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())
|
$this->mockClient->expects($this->any())
|
||||||
->method('listDatabases')
|
->method('listDatabases')
|
||||||
->will($this->returnValue(array('test123', 'test')));
|
->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);
|
$testResultSet = new ResultSet($this->resultData);
|
||||||
$this->assertEquals($this->database->query('SELECT * FROM test_metric'), $testResultSet);
|
$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);
|
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()
|
public function testExists()
|
||||||
{
|
{
|
||||||
$database = new Database('test', $this->mockClient);
|
$database = new Database('test', $this->mockClient);
|
||||||
@@ -96,5 +148,76 @@ class DatabaseTest extends AbstractTest
|
|||||||
);
|
);
|
||||||
|
|
||||||
$this->assertEquals(true, $this->database->writePoints(array($point1, $point2)));
|
$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
|
<?php
|
||||||
/**
|
|
||||||
* Created by PhpStorm.
|
|
||||||
* User: dmartinez
|
|
||||||
* Date: 18-6-15
|
|
||||||
* Time: 17:39
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace InfluxDB\Test;
|
namespace InfluxDB\Test;
|
||||||
|
|
||||||
@@ -15,16 +9,119 @@ class PointTest extends \PHPUnit_Framework_TestCase
|
|||||||
{
|
{
|
||||||
public function testPointStringRepresentation()
|
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(
|
$point = $this->getPoint('1440494531376778481');
|
||||||
'cpu_load_short',
|
|
||||||
0.64,
|
|
||||||
array('host' => 'server01', 'region' => 'us-west'),
|
|
||||||
array('cpucount' => 10),
|
|
||||||
1435222310
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->assertEquals($expected, (string) $point);
|
$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()
|
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);
|
$this->resultSet = new ResultSet($resultJsonExample);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ EOD;
|
|||||||
*/
|
*/
|
||||||
public function testGetPointsFromNameWithoudTags()
|
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);
|
$this->resultSet = new ResultSet($resultJsonExample);
|
||||||
|
|
||||||
$measurementName = 'cpu_load_short';
|
$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
|
* We can get points from measurement
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"results":[
|
||||||
|
{
|
||||||
|
"series":[
|
||||||
|
{
|
||||||
|
"name":"databases",
|
||||||
|
"columns":[
|
||||||
|
"name"
|
||||||
|
],
|
||||||
|
"values":[
|
||||||
|
[
|
||||||
|
"test"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"test1"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"test2"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"results":[
|
||||||
|
{
|
||||||
|
"series":[
|
||||||
|
{
|
||||||
|
"columns":[
|
||||||
|
"user",
|
||||||
|
"admin"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user