Ejemplo n.º 1
0
Selection.prototype.orderBy = function(fields, options, query, internalOptions) {
  var hasIndex = false;
  if (typeof options.index === "string") {
    if (this.type !== 'TABLE_SLICE') {
      throw new Error.ReqlRuntimeError("Cannot use an index on a selection", query.frames);
    }
    else {
      // We have a table slice, so this.operations.length > 0
      if (this.operations[this.operations.length-1].index !== options.index) {
        query.frames.push(0);
        query.frames.push(0);
        throw new Error.ReqlRuntimeError('Cannot order by index `'+options.index+'` after calling '+this.operations[this.operations.length-1].operation.toUpperCase()+' on index `'+this.operations[this.operations.length-1].index+'`', query.frames);
      }
    }
  }
  if (options.index !== undefined) {
    var index = options.index;
    var order = 'ASC'
    if (util.isAsc(index)) {
      order= 'ASC';
      index = options.index.value;
    }
    else if (util.isDesc(index)) {
      order= 'DESC';
      index = options.index.value;
    }
    query.frames.push('index')
    util.assertType(index, 'STRING', query);
    query.frames.pop();

    if (this.table.indexes[index] === undefined) {
      throw new Error.ReqlRuntimeError('Index `'+index+'` was not found on table `'+this.db+'.'+this.name+'`', query.frames)
    }
  }


  var selection = new Selection([], this.table, {});
  if ((Array.isArray(options.index) || (typeof options.index === "string"))
      && (fields.length === 0)){
    for(var i=0; i<this.operations; i++) {
      selection.addOperation(this.operations[i]);
    }
    selection.addOperation({
      operation: 'orderBy',
      index: options.index
    });
  }

  if (Array.isArray(options.index) || (typeof options.index === "string")) {
    if (this.table.indexes[options.index] === undefined) {
      throw new Error.ReqlRuntimeError('Index `'+options.index+'` was not found on table `'+this.table.db+'.'+this.table.name+'`', query.frames)
    }
  }

  for(var i=0; i<this.length; i++) {
    if (options.index !== undefined) {
      // We drop null and plain objects
      try {
        var varId = util.getVarId(this.table.indexes[index].fn);
        query.context[varId] = this.get(i);
        var indexValue = query.evaluate(this.table.indexes[index].fn, query, internalOptions);
        delete query.context[varId];

        if ((indexValue !== null) || (util.isPlainObject(indexValue) && (indexValue.$reql_type$ === undefined))) {
          selection.push(this.get(i));
        }
      }
      catch(err) {
        if (err.message.match(/^No attribute/)) {
          // We also drop documents where a non existent error was thrown
        }
        else {
          throw err;
        }
      }
    }
    else {
      selection.push(this.get(i));
    }
  }
  if (options.index !== undefined) {
    hasIndex = true;
    fields.unshift(this.table.indexes[index].fn);
  }
  selection._orderBy(fields, hasIndex, query, internalOptions);
  return selection;
}
Ejemplo n.º 2
0
Table.prototype.orderBy = function(fields, options, query, internalOptions) {
  var selection;
  var hasIndex = false;

  if (options.index !== undefined) {
    // Blame RethinkDB
    //query.frames.push('index');
    var index = options.index;
    var order = 'ASC'
    if (util.isAsc(index)) {
      order= 'ASC';
      index = options.index.value;
    }
    else if (util.isDesc(index)) {
      order= 'DESC';
      index = options.index.value;
    }
    query.frames.push('index')
    util.assertType(index, 'STRING', query);
    query.frames.pop();

    if (this.indexes[index] === undefined) {
      throw new Error.ReqlRuntimeError('Index `'+index+'` was not found on table `'+this.db+'.'+this.name+'`', query.frames)
    }
  }

  if ((typeof options.index === "string") && (fields.length === 0)) {
    selection = new Selection([], this, {
      type: 'TABLE_SLICE',
      operation: 'orderBy',
      index: options.index,
      args: {
        order: order
      }
    });
  }
  else {
    selection = new Selection([], this, {});
  }

  if (options.index !== undefined) {
    hasIndex = true;
    for(var internalKey in this.documents) {
      // We drop null and plain objects
      try {
        var varId = util.getVarId(this.indexes[index].fn);
        query.context[varId] = this.documents[internalKey];
        var indexValue = query.evaluate(this.indexes[index].fn, query, internalOptions);
        delete query.context[varId];

        if ((indexValue !== null) || (util.isPlainObject(indexValue) && (indexValue.$reql_type$ === undefined))) {
          selection.push(this.documents[internalKey]);
        }
      }
      catch(err) {
        if (err.message.match(/^No attribute/)) {
          // We also drop documents where a non existent error was thrown
        }
        else {
          throw err;
        }
      }
    }
    if (order === 'DESC') {
      fields.unshift([74, [this.indexes[index].fn], {}]);
    }
    else {
      fields.unshift(this.indexes[index].fn);
    }
  }
  else {
    for(var internalKey in this.documents) {
      selection.push(this.documents[internalKey]);
    }
  }
  selection._orderBy(fields, hasIndex, query);
  return selection;
}
Ejemplo n.º 3
0
Selection.prototype.orderBy = function(fields, options, query, internalOptions) {
  var self = this;
  var hasIndex = false;
  var index;
  var order;
  if (options.index !== undefined) {
    hasIndex = true;
    index = options.index;
    order = 'ASC';
    if (util.isAsc(index)) {
      order = 'ASC';
      index = options.index.value;
    }
    else if (util.isDesc(index)) {
      order = 'DESC';
      index = options.index.value;
    }
    if (this.type !== 'TABLE_SLICE') {
      return Promise.reject(new Error.ReqlRuntimeError("Cannot use an index on a selection", query.frames));
    }
    else {
      // We have a table slice, so this.operations.length > 0
      if (this.operations[this.operations.length-1].index !== index) {
        query.frames.push(0);
        query.frames.push(0);
        return Promise.reject(new Error.ReqlRuntimeError('Cannot order by index `'+index+'` after calling '+this.operations[this.operations.length-1].operation.toUpperCase()+' on index `'+this.operations[this.operations.length-1].index+'`', query.frames));
      }
    }
    query.frames.push('index');
    util.assertType(index, 'STRING', query);
    query.frames.pop();

    if (this.table.indexes[index] === undefined) {
      return Promise.reject(new Error.ReqlRuntimeError('Index `'+index+'` was not found on table `'+this.db+'.'+this.name+'`', query.frames));
    }

    if (order === 'DESC') {
      fields.unshift([74, [this.table.indexes[index].fn], {}]);
    }
    else {
      fields.unshift(this.table.indexes[index].fn);
    }
  }

  var selection = new Selection([], this.table, {
    type: this.type
  });
  //TODO Move in the constructor
  selection.operations = this.operations.slice(0);

  var mainPromise;
  var restrictedSelection = new Selection([], this.table, {});
  if (hasIndex === true) {
    var varId = util.getVarId(self.table.indexes[index].fn);
    mainPromise = Promise.map(self.selection, function(doc) {
      query.context[varId] = doc;
      return query.evaluate(self.table.indexes[index].fn, query, internalOptions).then(function(indexValue) {
        delete query.context[varId];
        if ((indexValue !== null) || (util.isPlainObject(indexValue) && (indexValue.$reql_type$ === undefined))) {
          restrictedSelection.push(doc);
        }
      }).catch(function(err) {
        if (err.message.match(/^No attribute/)) {
          // We also drop documents where a non existent error was thrown
        }
        else {
          throw err;
        }
      });
    }, {concurrency: 1}).then(function() {
      return restrictedSelection;
    });
  }
  else {
    mainPromise = Promise.resolve(this);
  }

  var sequenceToSort = new Sequence();
  return mainPromise.then(function(restrictedSelection) {
    return Promise.map(restrictedSelection.selection, function(ref) {
      var element = {
        original: ref,
        fields: new Sequence()
      };
      return util.computeFields(element, 0, fields, query, internalOptions);
    }, {concurrency: 1}).then(function(resolved) {
      for(var i=0; i<resolved.length; i++) {
        sequenceToSort.push(resolved[i]);
      }
      sequenceToSort._orderBy();
      for(var i=0; i<sequenceToSort.length; i++) {
        selection.push(sequenceToSort.get(i).original);
      }
      return selection;
    });
  });
};