text: /**
   * Copyright DataStax, Inc.
   *
   * Please see the license for details:
   * http://www.datastax.com/terms/datastax-dse-driver-license-terms
   */
  'use strict';
  const utils = require('../utils');
  
  /** @module types */
  
  /**
   * Creates a new instance of ResultSet.
   * @class
   * @classdesc Represents the result of a query.
   * @param {Object} response
   * @param {String} host
   * @param {Object} triedHosts
   * @param {Number} speculativeExecutions
   * @param {Number} consistency
   * @param {Boolean} isSchemaInAgreement
   * @constructor
   */
  function ResultSet(response, host, triedHosts, speculativeExecutions, consistency, isSchemaInAgreement) {
    // if no execution was made at all, set to 0.
    if (speculativeExecutions === -1) {
      speculativeExecutions = 0;
    }
    /**
     * Information on the execution of a successful query:
     * @member {Object}
     * @property {Number} achievedConsistency The consistency level that has been actually achieved by the query.
     * @property {String} queriedHost The Cassandra host that coordinated this query.
     * @property {Object} triedHosts Gets the associative array of host that were queried before getting a valid response,
     * being the last host the one that replied correctly.
     * @property {Object} speculativeExecutions The number of speculative executions (not including the first) executed before
     * getting a valid response.
     * @property {Uuid} traceId Identifier of the trace session.
     * @property {Array.<string>} warnings Warning messages generated by the server when executing the query.
     * @property {Boolean} isSchemaInAgreement Whether the cluster had reached schema agreement after the execution of
     * this query.
     * <p>
     *   After a successful schema-altering query (ex: creating a table), the driver will check if
     *   the cluster's nodes agree on the new schema version. If not, it will keep retrying for a given
     *   delay (see <code>protocolOptions.maxSchemaAgreementWaitSeconds</code>).
     * </p>
     * <p>
     *   Note that the schema agreement check is only performed for schema-altering queries For other
     *   query types, this method will always return <code>true</code>. If this method returns <code>false</code>,
     *   clients can call [Metadata.checkSchemaAgreement()]{@link module:metadata~Metadata#checkSchemaAgreement} later to
     *   perform the check manually.
     * </p>
     */
    this.info = {
      queriedHost: host,
      triedHosts: triedHosts,
      speculativeExecutions: speculativeExecutions,
      achievedConsistency: consistency,
      traceId: null,
      warnings: null,
      customPayload: null,
      isSchemaInAgreement
    };
  
    if (response.flags) {
      this.info.traceId = response.flags.traceId;
      this.info.warnings = response.flags.warnings;
      this.info.customPayload = response.flags.customPayload;
    }
    /**
     * Gets an array rows returned by the query, in case the result was buffered.
     * @type {Array.<Row>}
     */
    this.rows = response.rows;
    /**
     * Gets the row length of the result, regardless if the result has been buffered or not
     * @type {Number}
     */
    this.rowLength = this.rows ? this.rows.length : response.rowLength;
    /**
     * Gets the columns returned in this ResultSet.
     * @type {Array.<{name, type}>}
     * @default null
     */
    this.columns = null;
    /**
     * A string token representing the current page state of query. It can be used in the following executions to
     * continue paging and retrieve the remained of the result for the query.
     * @type String
     * @default null
     */
    this.pageState = null;
    /**
     * Method used to manually fetch the next page of results.
     * This method is only exposed when using the {@link Client#eachRow} method and there are more rows available in
     * following pages.
     * @type Function
     */
    this.nextPage = undefined;
  
    const meta = response.meta;
  
    if (meta) {
      this.columns = meta.columns;
  
      if (meta.pageState) {
        this.pageState = meta.pageState.toString('hex');
  
        // Expose rawPageState internally
        Object.defineProperty(this, 'rawPageState', { value: meta.pageState, enumerable: false });
      }
    }
  }
  
  /**
   * Returns the first row or null if the result rows are empty.
   */
  ResultSet.prototype.first = function () {
    if (this.rows && this.rows.length) {
      return this.rows[0];
    }
    return null;
  };
  
  ResultSet.prototype.getPageState = function () {
    // backward-compatibility
    return this.pageState;
  };
  
  ResultSet.prototype.getColumns = function () {
    // backward-compatibility
    return this.columns;
  };
  
  /**
   * When this instance is the result of a conditional update query, it returns whether it was successful.
   * Otherwise, it returns <code>true</code>.
   * <p>
   *   For consistency, this method always returns <code>true</code> for non-conditional queries (although there is
   *   no reason to call the method in that case). This is also the case for conditional DDL statements
   *   (CREATE KEYSPACE... IF NOT EXISTS, CREATE TABLE... IF NOT EXISTS), for which the server doesn't return
   *   information whether it was applied or not.
   * </p>
   */
  ResultSet.prototype.wasApplied = function () {
    if (!this.rows || this.rows.length === 0) {
      return true;
    }
    const firstRow = this.rows[0];
    const applied = firstRow['[applied]'];
    return typeof applied === 'boolean' ? applied : true;
  };
  
  /**
   * Gets the iterator function.
   * <p>
   *   Retrieves the iterator of the underlying fetched rows and will not cause the driver to fetch the following
   *   result pages. For more information on result paging,
   *   [visit the documentation]{@link http://docs.datastax.com/en/developer/nodejs-driver/latest/features/paging/}.
   * </p>
   * @alias module:types~ResultSet#@@iterator
   * @example <caption>Using for...of statement</caption>
   * const query = 'SELECT name, email, address FROM users WHERE id = ?';
   * const result = await client.execute(query, [ id ], { prepare: true });
   * for (let row of result) {
   *   console.log(row['email']);
   * }
   * @returns {Iterator.<Row>}
   */
  ResultSet.prototype[Symbol.iterator] = function getIterator() {
    if (!this.rows) {
      return utils.emptyArray[Symbol.iterator]();
    }
    return this.rows[Symbol.iterator]();
  };
  
  module.exports = ResultSet;