mirror of
https://github.com/stylersnico/librenms.git
synced 2026-07-28 00:24:21 +02:00
Merge commit '4430658932762ead3661231492b8074f144ea4b6' into influxdb-php
Conflicts: lib/influxdb-php/.gitignore lib/influxdb-php/README.md
This commit is contained in:
@@ -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) {
|
||||
|
||||
// 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 ($timestamp <= PHP_INT_MAX && $timestamp >= ~PHP_INT_MAX) {
|
||||
return true;
|
||||
if (!is_numeric($timestamp)) {
|
||||
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 = '';
|
||||
|
||||
/**
|
||||
* @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
|
||||
|
||||
Reference in New Issue
Block a user