'Send a query to InfluxDB.
:param query: the actual query string
:type query: str
:param params: additional parameters for the request,
defaults to {}
:type params: dict
:param epoch: response timestamps to be in epoch format either \'h\',
\'m\', \'s\', \'ms\', \'u\', or \'ns\',defaults to `None` which is
RFC3339 UTC format with nanosecond precision
:type epoch: str
:param expected_response_code: the expected status code of response,
defaults to 200
:type expected_response_code: int
:param database: database to query, defaults to None
:type database: str
:param raise_errors: Whether or not to raise exceptions when InfluxDB
returns errors, defaults to True
:type raise_errors: bool
:param chunked: Enable to use chunked responses from InfluxDB.
With ``chunked`` enabled, one ResultSet is returned per chunk
containing all results within that chunk
:type chunked: bool
:param chunk_size: Size of each chunk to tell InfluxDB to use.
:type chunk_size: int
:returns: the queried data
:rtype: :class:`~.ResultSet`'

def query(self, query, params=None, epoch=None, expected_response_code=200, database=None, raise_errors=True, chunked=False, chunk_size=0):

    if (params is None):
        params = {}
    params[u'q'] = query
    params[u'db'] = (database or self._database)
    if (epoch is not None):
        params[u'epoch'] = epoch
    if chunked:
        params[u'chunked'] = u'true'
        if (chunk_size > 0):
            params[u'chunk_size'] = chunk_size
    response = self.request(url=u'query', method=u'GET', params=params, data=None, expected_response_code=expected_response_code)
    if chunked:
        return self._read_chunked_response(response)
    data = response.json()
    results = [ResultSet(result, raise_errors=raise_errors) for result in data.get(u'results', [])]
    if (len(results) == 1):
        return results[0]
    return results
