<commit_before>var Promise = require("bluebird");
var Err = require(__dirname+"/error.js");
var helper = require(__dirname+"/helper.js");

function Cursor(connection, token, options, type) {
    this.connection = connection;
    this.token = token;

    this._index = 0; // Position in this._data[0]
    this._data = []; // Array of non empty arrays
    this._fetching = false; // Are we fetching data
    this._canFetch = true; // Can we fetch more data?
    this._pendingPromises = []; // Pending promises' resolve/reject
    this.options = options || {};
    this._closed = false;
    this._type = type;
    if (type === 'feed') {
        this.toArray = function() {
            throw new Error("The `toArray` method is not available on feeds.")
        }
    }
}

Cursor.prototype.toString = function() {
    if (this.type === 'feed') {
        return '[object Feed]'
    }
    else {
        return '[object Cursor]'
    }
}

Cursor.prototype.toJSON = function() {
    return "You cannot serialize to JSON a cursor. Retrieve data from the cursor with `toArray` or `next`."
}

Cursor.prototype.next = function() {
    var self = this;
    var p = new Promise(function(resolve, reject) {
        if (self._closed === true) {
            reject(new Err.ReqlDriverError("You cannot called `next` on a closed cursor."))
        }
        else if ((self._data.length === 0) && (self._canFetch === false)) {
            reject(new Err.ReqlDriverError("No more rows in the cursor"))
        }
        else {
            if ((self._data.length > 0) && (self._data[0].length > self._index)) {
                var result = self._data[0][self._index++];
                if (result instanceof Error) {
                    reject(result);
                }
                else {
                    resolve(result);

                    // This could be possible if we get back batch with just one document?
                    if (self._data[0].length === self._index) {
                        self._index = 0;
                        self._data.shift();
                        if ((self._data.length === 1)
                            && (self._canFetch)
                            && (self._fetching === false)
                            && (self._canFetch === true)) {
                                self._fetch();
                        }
                    }
                }
            }
            else {
                self._pendingPromises.push({resolve: resolve, reject: reject});
            }
        }
    });
    return p;
}
Cursor.prototype.hasNext = function() {
    throw new Error("The `hasNext` command has been removed in 1.13, please use `next`.")
}
Cursor.prototype.toArray = function() {
    var self = this;
    var p = new Promise(function(resolve, reject) {
        var result = [];
        self._each(function(err, data) {
            if (err) {
                reject(err);
            }
            else {
                result.push(data);
            }
        }, function() {
            resolve(result);
        });
    });
    return p;
}

Cursor.prototype._fetch = function() {
    var self = this;
    this._fetching = true;

    var p = new Promise(function(resolve, reject) {
        self.connection._continue(self.token, resolve, reject);
    }).then(function(response) {
        self._push(response);
    }).error(function(error) {
        self._fetching = false;
        self._canFetch = false;
        self._pushError(error);
    })
}

Cursor.prototype._push = function(data) {
    if (data.done) this._done();
    response = data.response;
    this._fetching = false;
    if (response.r.length > 0) {
        this._data.push(helper.makeSequence(response, this.options));
    }

    if (this.closeAsap === true) {
        this.connection._end(this.token);
        while (this._pendingPromises.length > 0) {
            this._pendingPromises.shift().reject(new Err.ReqlDriverError("You cannot retrieve data from a cursor that is closed"))
        }
    }
    else {
        if ((this._canFetch) && (this._data.length <= 1)) this._fetch();
        this._flush();

    }
}
// Try to solve as many pending promises as possible
Cursor.prototype._flush = function() {
    while ((this._pendingPromises.length > 0) && (this._data.length > 0)) {
        var fullfiller = this._pendingPromises.shift(); 
        var resolve = fullfiller.resolve;
        var reject = fullfiller.reject;

        var result = this._data[0][this._index++];
        if (result instanceof Error) {
            reject(result);
        }
        else {
            resolve(result);
        }

        if (this._data[0].length === this._index) {
            this._index = 0;
            this._data.shift();
            if ((this._data.length <= 1)
                && (this._canFetch)
                && (this._fetching === false)) {
                    this._fetch();
            }
        }
    }
}
Cursor.prototype._pushError = function(error) {
    this._data.push([error]);
    this._flush();
}

Cursor.prototype._done = function() {
    this._canFetch = false;
}

Cursor.prototype._set = function(ar) {
    this._fetching = false;
    this._data.push(ar);
    this._canFetch = false;
}

Cursor.prototype.close = function() {
    var self = this;

    self._closed = true;

    var p = new Promise(function(resolve, reject) {
        if ((self._canFetch === true) && (self._fetching === false)) {
            self.connection._end(self.token, resolve, reject);
        }
        else if ((self._canFetch === false) && (self._fetching === false)) {
            resolve()
        }
        else {
            this._closeAsap = true;
        }
    });
    return p;
}
Cursor.prototype._each = function(callback, onFinish) {
    var self = this;

    var reject = function(err) {
        if (err.message === "No more rows in the cursor.") {
            if (typeof onFinish === 'function') {
                onFinish();
            }
        }
        else {<commit_msg>Fix cursor when an array is returned<commit_after>var Promise = require("bluebird");
var Err = require(__dirname+"/error.js");
var helper = require(__dirname+"/helper.js");

function Cursor(connection, token, options, type) {
    this.connection = connection;
    this.token = token;

    this._index = 0; // Position in this._data[0]
    this._data = []; // Array of non empty arrays
    this._fetching = false; // Are we fetching data
    this._canFetch = true; // Can we fetch more data?
    this._pendingPromises = []; // Pending promises' resolve/reject
    this.options = options || {};
    this._closed = false;
    this._type = type;
    if (type === 'feed') {
        this.toArray = function() {
            throw new Error("The `toArray` method is not available on feeds.")
        }
    }
}

Cursor.prototype.toString = function() {
    if (this.type === 'feed') {
        return '[object Feed]'
    }
    else {
        return '[object Cursor]'
    }
}

Cursor.prototype.toJSON = function() {
    return "You cannot serialize to JSON a cursor. Retrieve data from the cursor with `toArray` or `next`."
}

Cursor.prototype.next = function() {
    var self = this;
    var p = new Promise(function(resolve, reject) {
        if (self._closed === true) {
            reject(new Err.ReqlDriverError("You cannot called `next` on a closed cursor."))
        }
        else if ((self._data.length === 0) && (self._canFetch === false)) {
            reject(new Err.ReqlDriverError("No more rows in the cursor"))
        }
        else {
            if ((self._data.length > 0) && (self._data[0].length > self._index)) {
                var result = self._data[0][self._index++];
                if (result instanceof Error) {
                    reject(result);
                }
                else {
                    resolve(result);

                    // This could be possible if we get back batch with just one document?
                    if (self._data[0].length === self._index) {
                        self._index = 0;
                        self._data.shift();
                        if ((self._data.length === 1)
                            && (self._canFetch)
                            && (self._fetching === false)
                            && (self._canFetch === true)) {
                                self._fetch();
                        }
                    }
                }
            }
            else {
                self._pendingPromises.push({resolve: resolve, reject: reject});
            }
        }
    });
    return p;
}
Cursor.prototype.hasNext = function() {
    throw new Error("The `hasNext` command has been removed in 1.13, please use `next`.")
}
Cursor.prototype.toArray = function() {
    var self = this;
    var p = new Promise(function(resolve, reject) {
        var result = [];
        self._each(function(err, data) {
            if (err) {
                reject(err);
            }
            else {
                result.push(data);
            }
        }, function() {
            resolve(result);
        });
    });
    return p;
}

Cursor.prototype._fetch = function() {
    var self = this;
    this._fetching = true;

    var p = new Promise(function(resolve, reject) {
        self.connection._continue(self.token, resolve, reject);
    }).then(function(response) {
        self._push(response);
    }).error(function(error) {
        self._fetching = false;
        self._canFetch = false;
        self._pushError(error);
    })
}

Cursor.prototype._push = function(data) {
    if (data.done) this._done();
    response = data.response;
    this._fetching = false;
    if (response.r.length > 0) {
        this._data.push(helper.makeSequence(response, this.options));
    }

    if (this.closeAsap === true) {
        this.connection._end(this.token);
        while (this._pendingPromises.length > 0) {
            this._pendingPromises.shift().reject(new Err.ReqlDriverError("You cannot retrieve data from a cursor that is closed"))
        }
    }
    else {
        if ((this._canFetch) && (this._data.length <= 1)) this._fetch();
        this._flush();

    }
}
// Try to solve as many pending promises as possible
Cursor.prototype._flush = function() {
    while ((this._pendingPromises.length > 0) && (this._data.length > 0)) {
        var fullfiller = this._pendingPromises.shift(); 
        var resolve = fullfiller.resolve;
        var reject = fullfiller.reject;

        var result = this._data[0][this._index++];
        if (result instanceof Error) {
            reject(result);
        }
        else {
            resolve(result);
        }

        if (this._data[0].length === this._index) {
            this._index = 0;
            this._data.shift();
            if ((this._data.length <= 1)
                && (this._canFetch)
                && (this._fetching === false)) {
                    this._fetch();
            }
        }
    }
}
Cursor.prototype._pushError = function(error) {
    this._data.push([error]);
    this._flush();
}

Cursor.prototype._done = function() {
    this._canFetch = false;
}

Cursor.prototype._set = function(ar) {
    this._fetching = false;
    this._canFetch = false;
    if (ar.length > 0) {
        this._data.push(ar);
    }
    this._flush();
}

Cursor.prototype.close = function() {
    var self = this;

    self._closed = true;

    var p = new Promise(function(resolve, reject) {
        if ((self._canFetch === true) && (self._fetching === false)) {
            self.connection._end(self.token, resolve, reject);
        }
        else if ((self._canFetch === false) && (self._fetching === false)) {
            resolve()
        }
        else {
            this._closeAsap = true;
        }
    });
    return p;
}
Cursor.prototype._each = function(callback, onFinish) {
    var self = this;

    var reject = function(err) {
        if (err.message === "No more rows in the cursor.") {
            if (typeof onFinish === 'function') {
                onFinish();
            }
        }
        else {
{'fraction_non_alphanumeric': 0.13555943184649888, 'fraction_numerical': 0.003571725226347703, 'mean_word_length': 1.758936755270394, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 16, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5952664', 'n_tokens_mistral': 3414, 'n_tokens_neox': 3304, 'n_words': 820}