using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using InfluxDB.Client.Api.Domain;
using InfluxDB.Client.Api.Service;
using InfluxDB.Client.Core;
using InfluxDB.Client.Core.Flux.Domain;
using InfluxDB.Client.Core.Flux.Internal;
using InfluxDB.Client.Core.Internal;
using RestSharp;
namespace InfluxDB.Client
{
public interface IQueryApi
{
///
/// Executes the Flux query against the InfluxDB 2.x and synchronously map whole response
/// to s.
///
///
/// NOTE: This method is not intended for large query results.
/// Use
/// for large data streaming.
///
///
/// the flux query to execute
/// specifies the source organization. If the org is not specified then is used config from .
/// Token that enables callers to cancel the request.
/// FluxTables that are matched the query
Task> QueryAsync(string query, string org = null,
CancellationToken cancellationToken = default);
///
/// Executes the Flux query against the InfluxDB 2.x and synchronously map whole response
/// to s.
///
///
/// NOTE: This method is not intended for large query results.
/// Use
/// for large data streaming.
///
///
/// the flux query to execute
/// specifies the source organization. If the org is not specified then is used config from .
/// Token that enables callers to cancel the request.
/// FluxTables that are matched the query
Task> QueryAsync(Query query, string org = null,
CancellationToken cancellationToken = default);
///
/// Executes the Flux query against the InfluxDB 2.x and synchronously map whole response
/// to list of object with given type.
///
///
/// NOTE: This method is not intended for large query results.
/// Use
/// for large data streaming.
///
///
/// the flux query to execute
/// specifies the source organization. If the org is not specified then is used config from .
/// Token that enables callers to cancel the request.
/// the type of measurement
/// Measurements which are matched the query
Task> QueryAsync(string query, string org = null,
CancellationToken cancellationToken = default);
///
/// Executes the Flux query against the InfluxDB 2.x and synchronously map whole response
/// to list of object with given type.
///
///
/// NOTE: This method is not intended for large query results.
/// Use
/// for large data streaming.
///
///
/// the flux query to execute
/// specifies the source organization. If the org is not specified then is used config from .
/// Token that enables callers to cancel the request.
/// the type of measurement
/// Measurements which are matched the query
Task> QueryAsync(Query query, string org = null,
CancellationToken cancellationToken = default);
///
/// Executes the Flux query against the InfluxDB 2.x and asynchronously stream
/// to consumer.
///
/// the flux query to execute
/// the callback to consume the FluxRecord result
/// the callback to consume any error notification
/// the callback to consume a notification about successfully end of stream
/// specifies the source organization. If the org is not specified then is used config from .
/// Token that enables callers to cancel the request.
/// async task
Task QueryAsync(string query, Action onNext, Action onError = null,
Action onComplete = null, string org = null, CancellationToken cancellationToken = default);
///
/// Executes the Flux query against the InfluxDB 2.x and asynchronously stream
/// to consumer.
///
/// the flux query to execute
/// the callback to consume the FluxRecord result
/// the callback to consume any error notification
/// the callback to consume a notification about successfully end of stream
/// specifies the source organization. If the org is not specified then is used config from .
/// Token that enables callers to cancel the request.
/// async task
Task QueryAsync(Query query, Action onNext, Action onError = null,
Action onComplete = null, string org = null, CancellationToken cancellationToken = default);
///
/// Executes the Flux query against the InfluxDB 2.x and asynchronously stream Measurements
/// to a consumer.
///
/// the flux query to execute
/// the callback to consume the mapped Measurements
/// the callback to consume any error notification
/// the callback to consume a notification about successfully end of stream
/// specifies the source organization
/// Token that enables callers to cancel the request.
/// the type of measurement
/// async task
Task QueryAsync(string query, Action onNext, Action onError = null,
Action onComplete = null, string org = null, CancellationToken cancellationToken = default);
///
/// Executes the Flux query against the InfluxDB 2.x and asynchronously stream Measurements
/// to a consumer.
///
/// the flux query to execute
/// the callback to consume the mapped Measurements
/// the callback to consume any error notification
/// the callback to consume a notification about successfully end of stream
/// specifies the source organization
/// Token that enables callers to cancel the request.
/// the type of measurement
/// async task
Task QueryAsync(Query query, Action onNext, Action onError = null,
Action onComplete = null, string org = null, CancellationToken cancellationToken = default);
///
/// Executes the Flux query against the InfluxDB 2.x and synchronously map whole response
/// to list of object with given type.
///
///
/// NOTE: This method is not intended for large query results.
/// Use
/// for large data streaming.
///
///
/// the flux query to execute
/// the type of measurement
/// the organization
/// Token that enables callers to cancel the request.
/// Measurements which are matched the query
Task> QueryAsync(string query, Type pocoType, string org = null,
CancellationToken cancellationToken = default);
///
/// Executes the Flux query against the InfluxDB 2.x and synchronously map whole response
/// to list of object with given type.
///
///
/// NOTE: This method is not intended for large query results.
/// Use
/// for large data streaming.
///
///
/// the flux query to execute
/// the type of measurement
/// the organization
/// Token that enables callers to cancel the request.
/// Measurements which are matched the query
Task> QueryAsync(Query query, Type pocoType, string org = null,
CancellationToken cancellationToken = default);
///
/// Executes the Flux query against the InfluxDB 2.x and asynchronously stream Measurements
/// to a consumer.
///
/// the flux query to execute
/// the type of measurement
/// the callback to consume the mapped Measurements
/// the callback to consume any error notification
/// the callback to consume a notification about successfully end of stream
/// specifies the source organization. If the org is not specified then is used config from .
/// Token that enables callers to cancel the request.
/// async task
Task QueryAsync(string query, Type pocoType, Action onNext,
Action onError = null, Action onComplete = null, string org = null,
CancellationToken cancellationToken = default);
///
/// Executes the Flux query against the InfluxDB 2.x and asynchronously stream Measurements
/// to a consumer.
///
/// the flux query to execute
/// the type of measurement
/// the callback to consume the mapped Measurements
/// the callback to consume any error notification
/// the callback to consume a notification about successfully end of stream
/// specifies the source organization. If the org is not specified then is used config from .
/// Token that enables callers to cancel the request.
/// async task
Task QueryAsync(Query query, Type pocoType, Action onNext,
Action onError = null, Action onComplete = null, string org = null,
CancellationToken cancellationToken = default);
///
/// Executes the Flux query against the InfluxDB 2.x and asynchronously maps
/// response to enumerable of objects of type .
///
/// the flux query to execute
/// specifies the source organization. If the org is not specified then is used config from .
/// cancellation token
/// the type of measurement
/// Measurements which are matched the query
IAsyncEnumerable QueryAsyncEnumerable(string query, string org = null,
CancellationToken cancellationToken = default);
///
/// Executes the Flux query against the InfluxDB 2.x and asynchronously maps
/// response to enumerable of objects of type .
///
/// the flux query to execute
/// specifies the source organization. If the org is not specified then is used config from .
/// cancellation token
/// the type of measurement
/// Measurements which are matched the query
IAsyncEnumerable QueryAsyncEnumerable(Query query, string org = null,
CancellationToken cancellationToken = default);
///
/// Executes the Flux query against the InfluxDB and synchronously map whole response to result.
///
///
/// NOTE: This method is not intended for large query results.
/// Use
/// for large data streaming.
///
///
///
/// the flux query to execute
/// Dialect is an object defining the options to use when encoding the response. See dialect SPEC.
/// specifies the source organization. If the org is not specified then is used config from .
/// Token that enables callers to cancel the request.
/// the raw response that matched the query
Task QueryRawAsync(string query, Dialect dialect = null, string org = null,
CancellationToken cancellationToken = default);
///
/// Executes the Flux query against the InfluxDB and synchronously map whole response to result.
///
///
/// NOTE: This method is not intended for large query results.
/// Use
/// for large data streaming.
///
///
///
/// the flux query to execute
/// specifies the source organization. If the org is not specified then is used config from .
/// Token that enables callers to cancel the request.
/// the raw response that matched the query
Task QueryRawAsync(Query query, string org = null,
CancellationToken cancellationToken = default);
///
/// Executes the Flux query against the InfluxDB 2.x and asynchronously stream response
/// (line by line) to .
///
/// the flux query to execute
/// the callback to consume the response line by line
/// Dialect is an object defining the options to use when encoding the response. See dialect SPEC.
/// callback to consume any error notification
/// callback to consume a notification about successfully end of stream
/// specifies the source organization. If the org is not specified then is used config from .
/// Token that enables callers to cancel the request.
///
Task QueryRawAsync(string query, Action onResponse, Dialect dialect = null,
Action onError = null, Action onComplete = null, string org = null,
CancellationToken cancellationToken = default);
///
/// Executes the Flux query against the InfluxDB 2.x and asynchronously stream response
/// (line by line) to .
///
/// the flux query to execute
/// the callback to consume the response line by line
/// callback to consume any error notification
/// callback to consume a notification about successfully end of stream
/// specifies the source organization. If the org is not specified then is used config from .
/// Token that enables callers to cancel the request.
///
Task QueryRawAsync(Query query, Action onResponse, Action onError = null,
Action onComplete = null, string org = null, CancellationToken cancellationToken = default);
}
public class QueryApi : AbstractQueryClient, IQueryApi
{
public static readonly Dialect Dialect = new Dialect
{
Header = true,
Delimiter = ",",
CommentPrefix = "#",
Annotations = new List
{
Dialect.AnnotationsEnum.Datatype,
Dialect.AnnotationsEnum.Group,
Dialect.AnnotationsEnum.Default
}
};
private readonly InfluxDBClientOptions _options;
private readonly QueryService _service;
protected internal QueryApi(InfluxDBClientOptions options, QueryService service, IFluxResultMapper mapper) :
base(mapper)
{
Arguments.CheckNotNull(options, nameof(options));
Arguments.CheckNotNull(service, nameof(service));
_options = options;
_service = service;
RestClient = service.Configuration.ApiClient.RestClient;
}
///
/// Executes the Flux query against the InfluxDB 2.x and synchronously map whole response
/// to s.
///
///
/// NOTE: This method is not intended for large query results.
/// Use
/// for large data streaming.
///
///
/// the flux query to execute
/// specifies the source organization. If the org is not specified then is used config from .
/// Token that enables callers to cancel the request.
/// FluxTables that are matched the query
public Task> QueryAsync(string query, string org = null,
CancellationToken cancellationToken = default)
{
Arguments.CheckNonEmptyString(query, nameof(query));
return QueryAsync(CreateQuery(query, Dialect), org, cancellationToken);
}
///
/// Executes the Flux query against the InfluxDB 2.x and synchronously map whole response
/// to s.
///
///
/// NOTE: This method is not intended for large query results.
/// Use
/// for large data streaming.
///
///
/// the flux query to execute
/// specifies the source organization. If the org is not specified then is used config from .
/// Token that enables callers to cancel the request.
/// FluxTables that are matched the query
public async Task> QueryAsync(Query query, string org = null,
CancellationToken cancellationToken = default)
{
Arguments.CheckNotNull(query, nameof(query));
var consumer = new FluxCsvParser.FluxResponseConsumerTable();
await QueryAsync(query, consumer, ErrorConsumer, EmptyAction, org, cancellationToken)
.ConfigureAwait(false);
return consumer.Tables;
}
///
/// Executes the Flux query against the InfluxDB 2.x and synchronously map whole response
/// to list of object with given type.
///
///
/// NOTE: This method is not intended for large query results.
/// Use
/// for large data streaming.
///
///
/// the flux query to execute
/// specifies the source organization. If the org is not specified then is used config from .
/// Token that enables callers to cancel the request.
/// the type of measurement
/// Measurements which are matched the query
public Task> QueryAsync(string query, string org = null,
CancellationToken cancellationToken = default)
{
Arguments.CheckNonEmptyString(query, nameof(query));
return QueryAsync(CreateQuery(query), org, cancellationToken);
}
///
/// Executes the Flux query against the InfluxDB 2.x and synchronously map whole response
/// to list of object with given type.
///
///
/// NOTE: This method is not intended for large query results.
/// Use
/// for large data streaming.
///
///
/// the flux query to execute
/// specifies the source organization. If the org is not specified then is used config from .
/// Token that enables callers to cancel the request.
/// the type of measurement
/// Measurements which are matched the query
public async Task> QueryAsync(Query query, string org = null,
CancellationToken cancellationToken = default)
{
Arguments.CheckNotNull(query, nameof(query));
var measurements = new List();
var consumer = new FluxResponseConsumerPoco(poco => { measurements.Add(poco); }, Mapper);
await QueryAsync(query, consumer, ErrorConsumer, EmptyAction, org, cancellationToken)
.ConfigureAwait(false);
return measurements;
}
///
/// Executes the Flux query against the InfluxDB 2.x and asynchronously maps
/// response to enumerable of objects of type .
///
/// the flux query to execute
/// specifies the source organization. If the org is not specified then is used config from .
/// cancellation token
/// the type of measurement
/// Measurements which are matched the query
public async IAsyncEnumerable QueryAsyncEnumerable(string query, string org = null,
[EnumeratorCancellation] CancellationToken cancellationToken = default)
{
Arguments.CheckNonEmptyString(query, nameof(query));
var requestMessage = CreateRequest(CreateQuery(query), org);
await foreach (var record in QueryEnumerable(requestMessage, it => Mapper.ConvertToEntity(it),
cancellationToken).ConfigureAwait(false))
yield return record;
}
///
/// Executes the Flux query against the InfluxDB 2.x and asynchronously maps
/// response to enumerable of objects of type .
///
/// the flux query to execute
/// specifies the source organization. If the org is not specified then is used config from .
/// cancellation token
/// the type of measurement
/// Measurements which are matched the query
public async IAsyncEnumerable QueryAsyncEnumerable(Query query, string org = null,
[EnumeratorCancellation] CancellationToken cancellationToken = default)
{
Arguments.CheckNotNull(query, nameof(query));
var requestMessage = CreateRequest(query, org);
await foreach (var record in QueryEnumerable(requestMessage, it => Mapper.ConvertToEntity(it),
cancellationToken).ConfigureAwait(false))
yield return record;
}
///
/// Executes the Flux query against the InfluxDB 2.x and asynchronously stream
/// to consumer.
///
/// the flux query to execute
/// the callback to consume the FluxRecord result
/// the callback to consume any error notification
/// the callback to consume a notification about successfully end of stream
/// specifies the source organization. If the org is not specified then is used config from .
/// Token that enables callers to cancel the request.
/// async task
public Task QueryAsync(string query, Action onNext, Action onError = null,
Action onComplete = null, string org = null, CancellationToken cancellationToken = default)
{
Arguments.CheckNonEmptyString(query, nameof(query));
Arguments.CheckNotNull(onNext, nameof(onNext));
var consumer = new FluxResponseConsumerRecord(onNext);
return QueryAsync(CreateQuery(query, Dialect), consumer, onError, onComplete, org,
cancellationToken);
}
///
/// Executes the Flux query against the InfluxDB 2.x and asynchronously stream
/// to consumer.
///
/// the flux query to execute
/// the callback to consume the FluxRecord result
/// the callback to consume any error notification
/// the callback to consume a notification about successfully end of stream
/// specifies the source organization. If the org is not specified then is used config from .
/// Token that enables callers to cancel the request.
/// async task
public Task QueryAsync(Query query, Action onNext, Action onError = null,
Action onComplete = null, string org = null, CancellationToken cancellationToken = default)
{
Arguments.CheckNotNull(query, nameof(query));
Arguments.CheckNotNull(onNext, nameof(onNext));
var consumer = new FluxResponseConsumerRecord(onNext);
return QueryAsync(query, consumer, onError, onComplete, org, cancellationToken);
}
///
/// Executes the Flux query against the InfluxDB 2.x and asynchronously stream Measurements
/// to a consumer.
///
/// the flux query to execute
/// the callback to consume the mapped Measurements
/// the callback to consume any error notification
/// the callback to consume a notification about successfully end of stream
/// specifies the source organization
/// Token that enables callers to cancel the request.
/// the type of measurement
/// async task
public Task QueryAsync(string query, Action onNext, Action onError = null,
Action onComplete = null, string org = null, CancellationToken cancellationToken = default)
{
Arguments.CheckNonEmptyString(query, nameof(query));
Arguments.CheckNotNull(onNext, nameof(onNext));
var consumer = new FluxResponseConsumerPoco(onNext, Mapper);
return QueryAsync(CreateQuery(query, Dialect), consumer, onError, onComplete, org,
cancellationToken);
}
///
/// Executes the Flux query against the InfluxDB 2.x and asynchronously stream Measurements
/// to a consumer.
///
/// the flux query to execute
/// the callback to consume the mapped Measurements
/// the callback to consume any error notification
/// the callback to consume a notification about successfully end of stream
/// specifies the source organization
/// Token that enables callers to cancel the request.
/// the type of measurement
/// async task
public Task QueryAsync(Query query, Action onNext, Action onError = null,
Action onComplete = null, string org = null, CancellationToken cancellationToken = default)
{
Arguments.CheckNotNull(query, nameof(query));
Arguments.CheckNotNull(onNext, nameof(onNext));
var consumer = new FluxResponseConsumerPoco(onNext, Mapper);
return QueryAsync(query, consumer, onError, onComplete, org, cancellationToken);
}
///
/// Executes the Flux query against the InfluxDB 2.x and synchronously map whole response
/// to list of object with given type.
///
///
/// NOTE: This method is not intended for large query results.
/// Use
/// for large data streaming.
///
///
/// the flux query to execute
/// the type of measurement
/// the organization
/// Token that enables callers to cancel the request.
/// Measurements which are matched the query
public Task> QueryAsync(string query, Type pocoType, string org = null,
CancellationToken cancellationToken = default)
{
return QueryAsync(CreateQuery(query), pocoType, org, cancellationToken);
}
///
/// Executes the Flux query against the InfluxDB 2.x and synchronously map whole response
/// to list of object with given type.
///
///
/// NOTE: This method is not intended for large query results.
/// Use
/// for large data streaming.
///
///
/// the flux query to execute
/// the type of measurement
/// the organization
/// Token that enables callers to cancel the request.
/// Measurements which are matched the query
public async Task> QueryAsync(Query query, Type pocoType, string org = null,
CancellationToken cancellationToken = default)
{
var measurements = new List();
var consumer = new FluxResponseConsumerPoco(poco => { measurements.Add(poco); }, Mapper, pocoType);
await QueryAsync(query, consumer, ErrorConsumer, EmptyAction, org, cancellationToken)
.ConfigureAwait(false);
return measurements;
}
///
/// Executes the Flux query against the InfluxDB 2.x and asynchronously stream Measurements
/// to a consumer.
///
/// the flux query to execute
/// the type of measurement
/// the callback to consume the mapped Measurements
/// the callback to consume any error notification
/// the callback to consume a notification about successfully end of stream
/// specifies the source organization. If the org is not specified then is used config from .
/// Token that enables callers to cancel the request.
/// async task
public Task QueryAsync(string query, Type pocoType, Action onNext,
Action onError = null, Action onComplete = null, string org = null,
CancellationToken cancellationToken = default)
{
return QueryAsync(CreateQuery(query, Dialect), pocoType,
onNext, onError, onComplete, org, cancellationToken);
}
///
/// Executes the Flux query against the InfluxDB 2.x and asynchronously stream Measurements
/// to a consumer.
///
/// the flux query to execute
/// the type of measurement
/// the callback to consume the mapped Measurements
/// the callback to consume any error notification
/// the callback to consume a notification about successfully end of stream
/// specifies the source organization. If the org is not specified then is used config from .
/// Token that enables callers to cancel the request.
/// async task
public Task QueryAsync(Query query, Type pocoType, Action onNext,
Action onError = null, Action onComplete = null, string org = null,
CancellationToken cancellationToken = default)
{
Arguments.CheckNotNull(query, nameof(query));
Arguments.CheckNotNull(onNext, nameof(onNext));
Arguments.CheckNotNull(onError, nameof(onError));
Arguments.CheckNotNull(onComplete, nameof(onComplete));
var consumer = new FluxResponseConsumerPoco(onNext, Mapper, pocoType);
return QueryAsync(query, consumer, onError, onComplete, org, cancellationToken);
}
///
/// Executes the Flux query against the InfluxDB and synchronously map whole response to result.
///
///
/// NOTE: This method is not intended for large query results.
/// Use
/// for large data streaming.
///
///
///
/// the flux query to execute
/// Dialect is an object defining the options to use when encoding the response. See dialect SPEC.
/// specifies the source organization. If the org is not specified then is used config from .
/// Token that enables callers to cancel the request.
/// the raw response that matched the query
public Task QueryRawAsync(string query, Dialect dialect = null, string org = null,
CancellationToken cancellationToken = default)
{
Arguments.CheckNonEmptyString(query, nameof(query));
return QueryRawAsync(CreateQuery(query, dialect), org, cancellationToken);
}
///
/// Executes the Flux query against the InfluxDB and synchronously map whole response to result.
///
///
/// NOTE: This method is not intended for large query results.
/// Use
/// for large data streaming.
///
///
///
/// the flux query to execute
/// specifies the source organization. If the org is not specified then is used config from .
/// Token that enables callers to cancel the request.
/// the raw response that matched the query
public async Task QueryRawAsync(Query query, string org = null,
CancellationToken cancellationToken = default)
{
Arguments.CheckNotNull(query, nameof(query));
var rows = new List();
void Consumer(string row)
{
rows.Add(row);
}
await QueryRawAsync(query, Consumer, ErrorConsumer, EmptyAction, org, cancellationToken)
.ConfigureAwait(false);
return string.Join("\n", rows);
}
///
/// Executes the Flux query against the InfluxDB 2.x and asynchronously stream response
/// (line by line) to .
///
/// the flux query to execute
/// the callback to consume the response line by line
/// Dialect is an object defining the options to use when encoding the response. See dialect SPEC.
/// callback to consume any error notification
/// callback to consume a notification about successfully end of stream
/// specifies the source organization. If the org is not specified then is used config from .
/// Token that enables callers to cancel the request.
///
public Task QueryRawAsync(string query, Action onResponse, Dialect dialect = null,
Action onError = null, Action onComplete = null, string org = null,
CancellationToken cancellationToken = default)
{
Arguments.CheckNonEmptyString(query, nameof(query));
Arguments.CheckNotNull(onResponse, nameof(onResponse));
return QueryRawAsync(CreateQuery(query, dialect), onResponse, onError, onComplete, org, cancellationToken);
}
///
/// Executes the Flux query against the InfluxDB 2.x and asynchronously stream response
/// (line by line) to .
///
/// the flux query to execute
/// the callback to consume the response line by line
/// callback to consume any error notification
/// callback to consume a notification about successfully end of stream
/// specifies the source organization. If the org is not specified then is used config from .
/// Token that enables callers to cancel the request.
///
public Task QueryRawAsync(Query query, Action onResponse, Action onError = null,
Action onComplete = null, string org = null, CancellationToken cancellationToken = default)
{
Arguments.CheckNotNull(query, nameof(query));
Arguments.CheckNotNull(onResponse, nameof(onResponse));
var requestMessage = CreateRequest(query, org);
return QueryRaw(requestMessage, onResponse, onError, onComplete, cancellationToken);
}
protected override void BeforeIntercept(RestRequest request)
{
_service.Configuration.ApiClient.BeforeIntercept(request);
}
protected override T AfterIntercept(int statusCode, Func> headers, T body)
{
return _service.Configuration.ApiClient.AfterIntercept(statusCode, headers, body);
}
private Task QueryAsync(Query query, FluxCsvParser.IFluxResponseConsumer consumer,
Action onError = null, Action onComplete = null, string org = null,
CancellationToken cancellationToken = default)
{
Arguments.CheckNotNull(query, nameof(query));
Arguments.CheckNotNull(consumer, nameof(consumer));
var requestMessage = CreateRequest(query, org);
return Query(requestMessage, consumer, onError ?? ErrorConsumer, onComplete ?? EmptyAction,
cancellationToken);
}
private Func, RestRequest> CreateRequest(Query query, string org = null)
{
Arguments.CheckNotNull(query, nameof(query));
var optionsOrg = org ?? _options.Org;
Arguments.CheckNonEmptyString(optionsOrg, OrgArgumentValidation);
return advancedResponseWriter => _service
.PostQueryWithRestRequest(null, "application/json", null, optionsOrg, null, query)
.AddAdvancedResponseHandler(advancedResponseWriter);
}
internal static Query CreateQuery(string query, Dialect dialect = null)
{
Arguments.CheckNonEmptyString(query, nameof(query));
var created = new Query(query: query, dialect: dialect ?? Dialect);
return created;
}
}
}