src/InfluxDB/Client.php
<?php
namespace InfluxDB;
use InfluxDB\Client\Admin;
use InfluxDB\Client\Exception as ClientException;
use InfluxDB\Driver\DriverInterface;
use InfluxDB\Driver\Exception as DriverException;
use InfluxDB\Driver\Guzzle;
use InfluxDB\Driver\QueryDriverInterface;
use InfluxDB\Driver\UDP;
/**
* Class Client
*
* @package InfluxDB
* @author Stephen "TheCodeAssassin" Hoogendijk
*/
class Client
{
/**
* @var Admin
*/
public $admin;
/**
* @var string
*/
protected $host = '';
/**
* @var int
*/
protected $port = 8086;
/**
* @var string
*/
protected $username = '';
/**
* @var string
*/
protected $password = '';
/**
* @var float
*/
protected $timeout = 0;
/**
* @var float
*/
protected $connectTimeout = 0;
/**
* @var bool
*/
protected $scheme = 'http';
/**
* @var bool
*/
protected $verifySSL = false;
/**
* @var bool
*/
protected $useUdp = false;
/**
* @var int
*/
protected $udpPort = 4444;
/**
* @var
*/
protected $baseURI;
/**
* @var array
*/
protected $options = [];
/**
* @var DriverInterface
*/
protected $driver;
/**
* Stores the last query that ran
*
* @var null
*/
public static $lastQuery = null;
/**
* @param string $host
* @param int $port
* @param string $username
* @param string $password
* @param bool $ssl
* @param bool $verifySSL
* @param float $timeout
* @param float $connectTimeout
*/
public function __construct(
$host,
$port = 8086,
$username = '',
$password = '',
$ssl = false,
$verifySSL = false,
$timeout = 0,
$connectTimeout = 0
) {
$this->host = (string) $host;
$this->port = (int) $port;
$this->username = (string) $username;
$this->password = (string) $password;
$this->timeout = (float) $timeout;
$this->connectTimeout = (float) $connectTimeout;
$this->verifySSL = (bool) $verifySSL;
if ($ssl) {
$this->scheme = 'https';
$this->options['verify'] = $verifySSL;
}
// the the base URI
$this->baseURI = sprintf('%s://%s:%d', $this->scheme, $this->host, $this->port);
// delay driver instantiation until it's actually needed
$this->driver = null;
$this->admin = new Admin($this);
}
/**
* Use the given database
*
* @param string $name
* @return Database
* @throws \InvalidArgumentException
*/
public function selectDB($name)
{
return new Database($name, $this);
}
/**
* Query influxDB
*
* @param string $database
* @param string $query
* @param array $parameters
*
* @return ResultSet
* @throws Exception
*/
public function query($database, $query, $parameters = [])
{
$driver = $this->getDriver();
if (!$driver instanceof QueryDriverInterface) {
throw new Exception('The currently configured driver does not support query operations');
}
if ($database) {
$parameters['db'] = $database;
}
$parameters = [
'url' => 'query?' . http_build_query(array_merge(['q' => $query], $parameters)),
'database' => $database,
'method' => 'get'
];
// add authentication to the driver if needed
if (!empty($this->username) && !empty($this->password)) {
$parameters += ['auth' => [$this->username, $this->password]];
}
$driver->setParameters($parameters);
try {
// store the last query sent
static::$lastQuery = $query;
// perform the query and return the resultset
return $driver->query();
} catch (\Exception $e) {
throw new Exception('Query has failed: ' . $e->getMessage(), $e->getCode(), $e);
}
}
/**
* Write data
*
* @param array $parameters
* @param string|array $payload InfluxDB payload (Or array of payloads) that conform to the Line syntax.
*
* @return bool
*/
public function write(array $parameters, $payload)
{
// retrieve 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
if (is_array($payload)) {
$driver->write(implode("\n", $payload));
} else {
$driver->write($payload);
}
return $driver->isSuccess();
}
/**
* List all the databases
* @throws Exception
*/
public function listDatabases()
{
$result = $this->query(null, 'SHOW DATABASES')->getPoints();
return $this->pointsToArray($result);
}
/**
* List all the users
*
* @return array
* @throws Exception
*/
public function listUsers()
{
$result = $this->query(null, 'SHOW USERS')->getColumns();
return (array) $result;
}
/**
* Build the client from a dsn
* Examples:
*
* https+influxdb://username:pass@localhost:8086/databasename
* udp+influxdb://username:pass@localhost:4444/databasename
*
* @param string $dsn
* @param float $timeout
* @param bool $verifySSL
* @param float $connectTimeout
*
* @return Client|Database
* @throws ClientException
*/
public static function fromDSN($dsn, $timeout = 0, $verifySSL = false, $connectTimeout = 0)
{
$connParams = parse_url($dsn);
if ($connParams === false) {
throw new ClientException('Unable to parse the InfluxDB DSN');
}
$schemeInfo = explode('+', $connParams['scheme']);
$dbName = null;
$modifier = null;
$scheme = $schemeInfo[0];
if (isset($schemeInfo[1])) {
$modifier = strtolower($schemeInfo[0]);
$scheme = $schemeInfo[1];
}
if ($scheme !== 'influxdb') {
throw new ClientException($scheme . ' is not a valid scheme');
}
$ssl = $modifier === 'https';
$dbName = isset($connParams['path']) ? substr($connParams['path'], 1) : null;
$client = new self(
$connParams['host'],
$connParams['port'],
isset($connParams['user']) ? urldecode($connParams['user']) : '',
isset($connParams['pass']) ? urldecode($connParams['pass']) : '',
$ssl,
$verifySSL,
$timeout,
$connectTimeout
);
// set the UDP driver when the DSN specifies UDP
if ($modifier === 'udp') {
$client->setDriver(new UDP($connParams['host'], $connParams['port']));
}
return ($dbName ? $client->selectDB($dbName) : $client);
}
/**
* @return mixed
*/
public function getBaseURI()
{
return $this->baseURI;
}
/**
* @return float
*/
public function getTimeout()
{
return $this->timeout;
}
/**
* @return float
*/
public function getConnectTimeout()
{
return $this->connectTimeout;
}
/**
* @return bool
*/
public function getVerifySSL()
{
return $this->verifySSL;
}
/**
* @param Driver\DriverInterface $driver
*/
public function setDriver(DriverInterface $driver)
{
$this->driver = $driver;
}
/**
* @return DriverInterface|QueryDriverInterface
*/
public function getDriver()
{
if ($this->driver !== null) {
return $this->driver;
}
// set the default driver to guzzle
$this->driver = new Guzzle(
new \GuzzleHttp\Client(
[
'connect_timeout' => $this->connectTimeout,
'timeout' => $this->timeout,
'base_uri' => $this->baseURI,
'verify' => $this->verifySSL
]
)
);
return $this->driver;
}
/**
* @return string
*/
public function getHost()
{
return $this->host;
}
/**
* Returns the last executed query
*
* @return null|string
*/
public function getLastQuery()
{
return static::$lastQuery;
}
/**
* @param Point[] $points
* @return array
*/
protected function pointsToArray(array $points)
{
$names = [];
foreach ($points as $item) {
$names[] = $item['name'];
}
return $names;
}
}