<commit_before>var request = require('request');
var jsonParser = require('../jsonparser.js');
var parseBaseURL = require('../parse-base-url');

var elasticsearch = function(parent, url, index) {
  this.base = parseBaseURL(url, index);
  this.parent = parent;
  this.lastScrollId = null;
  this.totalSearchResults = 0;
  this.hasSkipped = 0;
};
// accept callback
// return (error, arr) where arr is an array of objects
elasticsearch.prototype.get = function(limit, offset, callback) {
  var self = this;
  var type = self.parent.options.type;
  if (type === 'data') {
    self.getData(limit, offset, callback);
  } else if (type === 'mapping') {
    self.getMapping(limit, offset, callback);
  } else if (type === 'analyzer') {
    self.getSettings(limit, offset, callback);
  } else {
    callback(new Error('unknown type option'), null);
  }
};

elasticsearch.prototype.getMapping = function(limit, offset, callback) {
  var self = this;
  if (self.gotMapping === true) {
    callback(null, []);
  } else {
    var url = self.base.url + '/_mapping';
    request.get(url, function(err, response) {
      self.gotMapping = true;
      var payload = [];
      if (!err) {
        response = payload.push(JSON.parse(response.body));
      }
      callback(err, payload);
    });
  }
};

elasticsearch.prototype.getSettings = function(limit, offset, callback) {
  var self = this;
  if (self.gotSettings === true) {
    callback(null, []);
  } else {
    var url = self.base.url + '/_settings';
    request.get(url, function(err, response) {
      self.gotSettings = true;
      var payload = [];
      if (!err) {
        response = payload.push(response.body);
      }
      callback(err, payload);
    });
  }
};

elasticsearch.prototype.getData = function(limit, offset, callback) {
  var searchRequest, self, uri;
  self = this;
  var searchBody = self.parent.options.searchBody;

  if (offset >= self.totalSearchResults && self.totalSearchResults !== 0) {
    callback(null, []);
    return;
  }

  if (self.lastScrollId !== null) {
    scrollResultSet(self, callback);
  } else {
    self.numberOfShards(self.base, function(err, numberOfShards) {
      var shardedLimit = Math.ceil(limit / numberOfShards);

      // previously we used the scan/scroll method, but now we need to change the sort
      // https://www.elastic.co/guide/en/elasticsearch/reference/master/breaking_50_search_changes.html#_literal_search_type_scan_literal_removed

      uri = self.base.url +
        "/" +
        "_search?search_type=scan&scroll=" +
        self.parent.options.scrollTime +
        "&size=" + shardedLimit;

      searchBody.size = shardedLimit;

      searchRequest = {
        "uri": uri,
        "method": "GET",
        "sort": [ "_doc" ],
        "body": JSON.stringify(searchBody)
      };

      request.get(searchRequest, function requestResonse(err, response) {
        if (err) {
          callback(err, []);
          return;
        } else if (response.statusCode !== 200) {
          err = new Error(response.body);
          callback(err, []);
          return;
        }

        var body = jsonParser.parse(response.body);
        self.lastScrollId = body._scroll_id;

        if (self.lastScrollId === undefined) {
          err = new Error("Unable to obtain scrollId; This tends to indicate an error with your index(es)");
          callback(err, []);
          return;
        }
        self.totalSearchResults = body.hits.total;

        scrollResultSet(self, callback, body.hits.hits);
      });
    });
  }
};

// to respect the --limit param, we need to set the scan/sroll limit = limit/#Shards
// http://www.elasticsearch.org/guide/en/elasticsearch/guide/current/scan-scroll.html
elasticsearch.prototype.numberOfShards = function(base, callback) {
  request.get(base.url + "/_settings", function(err, response) {
    if (err) {
      callback(err);
    } else {
      try {
        var body = jsonParser.parse(response.body);
        var numberOfShards = body[base.index].settings.index.number_of_shards;
        callback(err, numberOfShards);
      } catch (e) {
        callback(err, 1);
      }
    }
  });
};

// accept arr, callback where arr is an array of objects
// return (error, writes)
elasticsearch.prototype.set = function(data, limit, offset, callback) {
  var self = this;
  var type = self.parent.options.type;
  if (type === 'data') {
    self.setData(data, limit, offset, callback);
  } else if (type === 'mapping') {
    self.setMapping(data, limit, offset, callback);
  } else if (type === 'analyzer') {
    self.setAnalyzer(data, limit, offset, callback);
  } else {
    callback(new Error('unknown type option'), null);
  }
};

elasticsearch.prototype.setMapping = function(data, limit, offset, callback) {
  var self = this;
  if (self.haveSetMapping === true) {
    callback(null, 0);
  } else {
    request.put(self.base.url, function(err, response) { // ensure the index exists
      try {
        data = data[0];
      } catch (e) {
        return callback(e);
      }
      var started = 0;
      var count = 0;
      for (var index in data) {
        var mappings = data[index]['mappings'];
        var sortedMappings = [];

        // TODO: it seems we need to set the mappings for children with parents first?
        for(var key in mappings){
          if(mappings[key]._parent){
            sortedMappings = [{key: key, data: mappings[key]}].concat(sortedMappings);
          }else{
            sortedMappings.push({key: key, data: mappings[key]});
          }
        }

        sortedMappings.forEach(function(set){
          var mapping = {};
          var url = self.base.url + '/' + encodeURIComponent(set.key) + '/_mapping';
          started++;
          count++;

          var payload = {
            url: url,
            body: JSON.stringify(set.data),
            timeout: self.parent.options.timeout,
          };

          request.put(payload, function(err, response) { // upload the mapping
            started--;
            if (!err) {
              var bodyError = jsonParser.parse(response.body).error;
              if (bodyError) {
                err = bodyError;
              }
            }
            if (started === 0) {
              self.haveSetMapping = true;
              callback(err, count);
            }
          });
        });
      }
    });
  }
};

elasticsearch.prototype.setAnalyzer = function(data, limit, offset, callback) {
  var self = this;
  var updateAnalyzer = function(err, response) {
    try {
      data = jsonParser.parse(data[0]);
    } catch (e) {
      return callback(e);
    }
    var started = 0;
    var count = 0;
    for (var index in data) {
      var settings = data[index]['settings'];
      for (var key in settings) { // iterate through settings
        var setting = {};
        setting[key] = settings[key];
        var url = self.base.url + '/_settings';
        started++;
        count++;

        // ignore all other settings other than 'analysis'
        for (var p in setting[key]) { // iterate through index
          if (p != 'analysis') { // remove everything not 'analysis'
            delete setting[key][p]
          }
        }

        var closeUrl = self.base.url + '/_close'; // close the index
        request.post({
          url: closeUrl,
          timeout: self.parent.options.timeout
        }, function(err, response, body) {
          if (!err) {
            var bodyError = jsonParser.parse(response.body).error;
            if (bodyError) {
              err = bodyError;
            }
            var payload = {
              url: url,
              body: JSON.stringify(setting),
              timeout: self.parent.options.timeout
            };
            request.put(payload, function(err, response) { // upload the analysis settings
              started--;
              if (!err) {
                var bodyError = jsonParser.parse(response.body).error;
                if (bodyError) {
                  err = bodyError;
                }
              } else {
                callback(err, count);
              }
              if (started === 0) {
                self.haveSetAnalyzer = true;
                var openUrl = self.base.url + '/_open'; // open the index
                request.post({
                  url: openUrl,
                  timeout: self.parent.options.timeout
                }, function(err, response) {
                  if (!err) {
                    var bodyError = jsonParser.parse(response.body).error;
                    if (bodyError) {
                      err = bodyError;
                    }
                  }
                  callback(err, count);
                });
              }
            });
          } else {
            callback(err, count);
          }
        });
      }
    }
  }
  if (self.haveSetAnalyzer === true) {
    callback(null, 0);
  } else {
    request.put(self.base.url, function(err, response) { // ensure the index exists
      // use cluster health api to check if the index is ready
      request.get(self.base.host + '/_cluster/health/' + self.base.index + '?wait_for_status=green', updateAnalyzer);
    });
  }
};

elasticsearch.prototype.setData = function(data, limit, offset, callback) {
  var self = this;
  var error = null;
  var extraFields = ['routing', 'parent', 'timestamp', 'ttl'];
  var writes = 0;
  if (data.length === 0) {
    callback(error, writes);
    return;
  }

  var started = 0;
  data.forEach(function(elem) {
    started++;
    var thisUrl = self.base.url + "/";
    if (self.parent.options.all === true) {
      thisUrl += elem._index + "/";
    }
    thisUrl += encodeURIComponent(elem._type) + "/" + encodeURIComponent(elem._id);

    var and = "?";
    extraFields.forEach(function(field) {
      if(elem.fields){
        if (elem.fields[field]) {
          thisUrl += and + field + "=" + encodeURIComponent(elem.fields[field]);
          and = "&";
        }
        if (elem.fields['_' + field]) {
          thisUrl += and + field + "=" + encodeURIComponent(elem.fields['_' + field]);
          and = "&";
        }
      }else{
        if (elem[field]) {
          thisUrl += and + field + "=" + encodeURIComponent(elem[field]);
          and = "&";
        }
        if (elem['_' + field]) {
          thisUrl += and + field + "=" + encodeURIComponent(elem['_' + field]);
          and = "&";
        }
      }
    });

    var payload = {
      url: thisUrl,
      body: JSON.stringify(elem._source),
      timeout: self.parent.options.timeout,
    };
    self.parent.emit('debug', 'thisUrl: ' + thisUrl + ", elem._source: " + JSON.stringify(elem._source));

    request.put(payload, function(err, response) {
      if (err) {
        error = err;
      }
      try {
        var r = jsonParser.parse(response.body);
        if (r.ok === true || r._version >= 1) {
          writes++;
        }
      } catch (e) {}
      started--;
      if (started === 0) {
        self.reindex(function() {
          callback(error, writes);
        });
      }
    });
  });

  if (data.length === 0) {
    process.nextTick(function() {
      callback(error, writes);
    });
  }
};

elasticsearch.prototype.del = function(elem, callback) {
  var self = this;
  var thisUrl = self.base.url + "/" + encodeURIComponent(elem._type) + "/" + encodeURIComponent(elem._id);

  self.parent.emit('debug', 'deleteUrl: ' + thisUrl);
  request.del(thisUrl, function(err, response, body) {
    if (typeof callback === 'function') {
      callback(err, response, body);
    }
  });
};

elasticsearch.prototype.reindex = function(callback) {
  var self = this;
  request.post(self.base.url + "/_refresh", function(err, response) {
    callback(err, response);
  });
};

exports.elasticsearch = elasticsearch;

/////////////
// HELPERS //
/////////////

/**
 * Posts requests to the _search api to fetch the latest
 * scan result with scroll id
 * @param that
 * @param callback
 */
function scrollResultSet(that, callback, loadedHits){
  var self = that;
  var body;

  if(loadedHits && loadedHits.length > 0){
    return callback(null, loadedHits);
  }

  var scrollRequest = {
    "uri": self.base.host + "/_search" + "/scroll?scroll=" + self.parent.options.scrollTime,
    "method": "POST",
    "body": self.lastScrollId
  };

  request.get(scrollRequest, function requestResonse(err, response) {
    if (err) {
      callback(err, []);
      return;
    }

    if (err === null && response.statusCode != 200) {
      err = new Error(response.body);
      callback(err, []);
      return;
    }

    try {
      body = jsonParser.parse(response.body);
    } catch (e) {
      e.message = e.message + " | Cannot Parse: " + response.body;
      callback(e, []);
      return;
    }

    self.lastScrollId = body._scroll_id;
    var hits = body.hits.hits;

    if (self.parent.options.delete === true && hits.length > 0) {
      var started = 0;
      hits.forEach(function(elem) {
        started++;
        self.del(elem, function() {
          started--;
          if (started === 0) {
            self.reindex(function(err) {
              if (hits.length === 0) {
                self.lastScrollId = null;
              }
              callback(err, hits);
            });
          }
        });
      });
    } else {
      if (hits.length === 0) {
        self.lastScrollId = null;
      }

      // are we skipping and we have hits?
      if (self.parent.options.skip !== null && hits.length > 0 && self.hasSkipped < self.parent.options.skip) {
        // lets remove hits until we reach the skip number
        while (hits.length > 0 && self.hasSkipped < self.parent.options.skip) {
          self.hasSkipped++;
          hits.splice(0, 1);
        }

        if (hits.length > 0) {
          // we have some hits after skipping, lets callback
          callback(err, hits);
        } else {
          // we skipped, but now we don't have any hits,
          // scroll again for more data if possible
          scrollResultSet(that, callback);
        }
      } else {
        // not skipping or done skipping
        callback(err, hits);
      }
    }
  });
}
<commit_msg>use just scroll in GET serach<commit_after>var request = require('request');
var jsonParser = require('../jsonparser.js');
var parseBaseURL = require('../parse-base-url');

var elasticsearch = function(parent, url, index) {
  this.base = parseBaseURL(url, index);
  this.parent = parent;
  this.lastScrollId = null;
  this.totalSearchResults = 0;
  this.hasSkipped = 0;
};
// accept callback
// return (error, arr) where arr is an array of objects
elasticsearch.prototype.get = function(limit, offset, callback) {
  var self = this;
  var type = self.parent.options.type;
  if (type === 'data') {
    self.getData(limit, offset, callback);
  } else if (type === 'mapping') {
    self.getMapping(limit, offset, callback);
  } else if (type === 'analyzer') {
    self.getSettings(limit, offset, callback);
  } else {
    callback(new Error('unknown type option'), null);
  }
};

elasticsearch.prototype.getMapping = function(limit, offset, callback) {
  var self = this;
  if (self.gotMapping === true) {
    callback(null, []);
  } else {
    var url = self.base.url + '/_mapping';
    request.get(url, function(err, response) {
      self.gotMapping = true;
      var payload = [];
      if (!err) {
        response = payload.push(JSON.parse(response.body));
      }
      callback(err, payload);
    });
  }
};

elasticsearch.prototype.getSettings = function(limit, offset, callback) {
  var self = this;
  if (self.gotSettings === true) {
    callback(null, []);
  } else {
    var url = self.base.url + '/_settings';
    request.get(url, function(err, response) {
      self.gotSettings = true;
      var payload = [];
      if (!err) {
        response = payload.push(response.body);
      }
      callback(err, payload);
    });
  }
};

elasticsearch.prototype.getData = function(limit, offset, callback) {
  var searchRequest, self, uri;
  self = this;
  var searchBody = self.parent.options.searchBody;

  if (offset >= self.totalSearchResults && self.totalSearchResults !== 0) {
    callback(null, []);
    return;
  }

  if (self.lastScrollId !== null) {
    scrollResultSet(self, callback);
  } else {
    self.numberOfShards(self.base, function(err, numberOfShards) {
      var shardedLimit = Math.ceil(limit / numberOfShards);

      // previously we used the scan/scroll method, but now we need to change the sort
      // https://www.elastic.co/guide/en/elasticsearch/reference/master/breaking_50_search_changes.html#_literal_search_type_scan_literal_removed

      uri = self.base.url +
        "/" +
        "_search?scroll=" +
        self.parent.options.scrollTime +
        "&size=" + shardedLimit;

      searchBody.size = shardedLimit;

      searchRequest = {
        "uri": uri,
        "method": "GET",
        "sort": [ "_doc" ],
        "body": JSON.stringify(searchBody)
      };

      request.get(searchRequest, function requestResonse(err, response) {
        if (err) {
          callback(err, []);
          return;
        } else if (response.statusCode !== 200) {
          err = new Error(response.body);
          callback(err, []);
          return;
        }

        var body = jsonParser.parse(response.body);
        self.lastScrollId = body._scroll_id;

        if (self.lastScrollId === undefined) {
          err = new Error("Unable to obtain scrollId; This tends to indicate an error with your index(es)");
          callback(err, []);
          return;
        }
        self.totalSearchResults = body.hits.total;

        scrollResultSet(self, callback, body.hits.hits);
      });
    });
  }
};

// to respect the --limit param, we need to set the scan/sroll limit = limit/#Shards
// http://www.elasticsearch.org/guide/en/elasticsearch/guide/current/scan-scroll.html
elasticsearch.prototype.numberOfShards = function(base, callback) {
  request.get(base.url + "/_settings", function(err, response) {
    if (err) {
      callback(err);
    } else {
      try {
        var body = jsonParser.parse(response.body);
        var numberOfShards = body[base.index].settings.index.number_of_shards;
        callback(err, numberOfShards);
      } catch (e) {
        callback(err, 1);
      }
    }
  });
};

// accept arr, callback where arr is an array of objects
// return (error, writes)
elasticsearch.prototype.set = function(data, limit, offset, callback) {
  var self = this;
  var type = self.parent.options.type;
  if (type === 'data') {
    self.setData(data, limit, offset, callback);
  } else if (type === 'mapping') {
    self.setMapping(data, limit, offset, callback);
  } else if (type === 'analyzer') {
    self.setAnalyzer(data, limit, offset, callback);
  } else {
    callback(new Error('unknown type option'), null);
  }
};

elasticsearch.prototype.setMapping = function(data, limit, offset, callback) {
  var self = this;
  if (self.haveSetMapping === true) {
    callback(null, 0);
  } else {
    request.put(self.base.url, function(err, response) { // ensure the index exists
      try {
        data = data[0];
      } catch (e) {
        return callback(e);
      }
      var started = 0;
      var count = 0;
      for (var index in data) {
        var mappings = data[index]['mappings'];
        var sortedMappings = [];

        // TODO: it seems we need to set the mappings for children with parents first?
        for(var key in mappings){
          if(mappings[key]._parent){
            sortedMappings = [{key: key, data: mappings[key]}].concat(sortedMappings);
          }else{
            sortedMappings.push({key: key, data: mappings[key]});
          }
        }

        sortedMappings.forEach(function(set){
          var mapping = {};
          var url = self.base.url + '/' + encodeURIComponent(set.key) + '/_mapping';
          started++;
          count++;

          var payload = {
            url: url,
            body: JSON.stringify(set.data),
            timeout: self.parent.options.timeout,
          };

          request.put(payload, function(err, response) { // upload the mapping
            started--;
            if (!err) {
              var bodyError = jsonParser.parse(response.body).error;
              if (bodyError) {
                err = bodyError;
              }
            }
            if (started === 0) {
              self.haveSetMapping = true;
              callback(err, count);
            }
          });
        });
      }
    });
  }
};

elasticsearch.prototype.setAnalyzer = function(data, limit, offset, callback) {
  var self = this;
  var updateAnalyzer = function(err, response) {
    try {
      data = jsonParser.parse(data[0]);
    } catch (e) {
      return callback(e);
    }
    var started = 0;
    var count = 0;
    for (var index in data) {
      var settings = data[index]['settings'];
      for (var key in settings) { // iterate through settings
        var setting = {};
        setting[key] = settings[key];
        var url = self.base.url + '/_settings';
        started++;
        count++;

        // ignore all other settings other than 'analysis'
        for (var p in setting[key]) { // iterate through index
          if (p != 'analysis') { // remove everything not 'analysis'
            delete setting[key][p]
          }
        }

        var closeUrl = self.base.url + '/_close'; // close the index
        request.post({
          url: closeUrl,
          timeout: self.parent.options.timeout
        }, function(err, response, body) {
          if (!err) {
            var bodyError = jsonParser.parse(response.body).error;
            if (bodyError) {
              err = bodyError;
            }
            var payload = {
              url: url,
              body: JSON.stringify(setting),
              timeout: self.parent.options.timeout
            };
            request.put(payload, function(err, response) { // upload the analysis settings
              started--;
              if (!err) {
                var bodyError = jsonParser.parse(response.body).error;
                if (bodyError) {
                  err = bodyError;
                }
              } else {
                callback(err, count);
              }
              if (started === 0) {
                self.haveSetAnalyzer = true;
                var openUrl = self.base.url + '/_open'; // open the index
                request.post({
                  url: openUrl,
                  timeout: self.parent.options.timeout
                }, function(err, response) {
                  if (!err) {
                    var bodyError = jsonParser.parse(response.body).error;
                    if (bodyError) {
                      err = bodyError;
                    }
                  }
                  callback(err, count);
                });
              }
            });
          } else {
            callback(err, count);
          }
        });
      }
    }
  }
  if (self.haveSetAnalyzer === true) {
    callback(null, 0);
  } else {
    request.put(self.base.url, function(err, response) { // ensure the index exists
      // use cluster health api to check if the index is ready
      request.get(self.base.host + '/_cluster/health/' + self.base.index + '?wait_for_status=green', updateAnalyzer);
    });
  }
};

elasticsearch.prototype.setData = function(data, limit, offset, callback) {
  var self = this;
  var error = null;
  var extraFields = ['routing', 'parent', 'timestamp', 'ttl'];
  var writes = 0;
  if (data.length === 0) {
    callback(error, writes);
    return;
  }

  var started = 0;
  data.forEach(function(elem) {
    started++;
    var thisUrl = self.base.url + "/";
    if (self.parent.options.all === true) {
      thisUrl += elem._index + "/";
    }
    thisUrl += encodeURIComponent(elem._type) + "/" + encodeURIComponent(elem._id);

    var and = "?";
    extraFields.forEach(function(field) {
      if(elem.fields){
        if (elem.fields[field]) {
          thisUrl += and + field + "=" + encodeURIComponent(elem.fields[field]);
          and = "&";
        }
        if (elem.fields['_' + field]) {
          thisUrl += and + field + "=" + encodeURIComponent(elem.fields['_' + field]);
          and = "&";
        }
      }else{
        if (elem[field]) {
          thisUrl += and + field + "=" + encodeURIComponent(elem[field]);
          and = "&";
        }
        if (elem['_' + field]) {
          thisUrl += and + field + "=" + encodeURIComponent(elem['_' + field]);
          and = "&";
        }
      }
    });

    var payload = {
      url: thisUrl,
      body: JSON.stringify(elem._source),
      timeout: self.parent.options.timeout,
    };
    self.parent.emit('debug', 'thisUrl: ' + thisUrl + ", elem._source: " + JSON.stringify(elem._source));

    request.put(payload, function(err, response) {
      if (err) {
        error = err;
      }
      try {
        var r = jsonParser.parse(response.body);
        if (r.ok === true || r._version >= 1) {
          writes++;
        }
      } catch (e) {}
      started--;
      if (started === 0) {
        self.reindex(function() {
          callback(error, writes);
        });
      }
    });
  });

  if (data.length === 0) {
    process.nextTick(function() {
      callback(error, writes);
    });
  }
};

elasticsearch.prototype.del = function(elem, callback) {
  var self = this;
  var thisUrl = self.base.url + "/" + encodeURIComponent(elem._type) + "/" + encodeURIComponent(elem._id);

  self.parent.emit('debug', 'deleteUrl: ' + thisUrl);
  request.del(thisUrl, function(err, response, body) {
    if (typeof callback === 'function') {
      callback(err, response, body);
    }
  });
};

elasticsearch.prototype.reindex = function(callback) {
  var self = this;
  request.post(self.base.url + "/_refresh", function(err, response) {
    callback(err, response);
  });
};

exports.elasticsearch = elasticsearch;

/////////////
// HELPERS //
/////////////

/**
 * Posts requests to the _search api to fetch the latest
 * scan result with scroll id
 * @param that
 * @param callback
 */
function scrollResultSet(that, callback, loadedHits){
  var self = that;
  var body;

  if(loadedHits && loadedHits.length > 0){
    return callback(null, loadedHits);
  }

  var scrollRequest = {
    "uri": self.base.host + "/_search" + "/scroll?scroll=" + self.parent.options.scrollTime,
    "method": "POST",
    "body": self.lastScrollId
  };

  request.get(scrollRequest, function requestResonse(err, response) {
    if (err) {
      callback(err, []);
      return;
    }

    if (err === null && response.statusCode != 200) {
      err = new Error(response.body);
      callback(err, []);
      return;
    }

    try {
      body = jsonParser.parse(response.body);
    } catch (e) {
      e.message = e.message + " | Cannot Parse: " + response.body;
      callback(e, []);
      return;
    }

    self.lastScrollId = body._scroll_id;
    var hits = body.hits.hits;

    if (self.parent.options.delete === true && hits.length > 0) {
      var started = 0;
      hits.forEach(function(elem) {
        started++;
        self.del(elem, function() {
          started--;
          if (started === 0) {
            self.reindex(function(err) {
              if (hits.length === 0) {
                self.lastScrollId = null;
              }
              callback(err, hits);
            });
          }
        });
      });
    } else {
      if (hits.length === 0) {
        self.lastScrollId = null;
      }

      // are we skipping and we have hits?
      if (self.parent.options.skip !== null && hits.length > 0 && self.hasSkipped < self.parent.options.skip) {
        // lets remove hits until we reach the skip number
        while (hits.length > 0 && self.hasSkipped < self.parent.options.skip) {
          self.hasSkipped++;
          hits.splice(0, 1);
        }

        if (hits.length > 0) {
          // we have some hits after skipping, lets callback
          callback(err, hits);
        } else {
          // we skipped, but now we don't have any hits,
          // scroll again for more data if possible
          scrollResultSet(that, callback);
        }
      } else {
        // not skipping or done skipping
        callback(err, hits);
      }
    }
  });
}
<|endoftext|>


<commit_before>var log = require('vega-logging'),
    ChangeSet = require('./ChangeSet'),
    Collector = require('./Collector'),
    Tuple = require('./Tuple'),
    Node = require('./Node'); // jshint ignore:line

function DataSource(graph, name, facet) {
  this._graph = graph;
  this._name = name;
  this._data = [];
  this._source = null;
  this._facet  = facet;
  this._input  = ChangeSet.create();
  this._output = null; // Output changeset

  this._inputNode  = null;
  this._outputNode = null;
  this._pipeline  = null; // Pipeline of transformations.
  this._collector = null; // Collector to materialize output of pipeline.
  this._mutates = false;  // Does any pipeline operator mutate tuples?
}

var prototype = DataSource.prototype;

prototype.name = function(name) {
  if (!arguments.length) return this._name;
  return (this._name = name, this);
};

prototype.source = function(src) {
  if (!arguments.length) return this._source;
  return (this._source = this._graph.data(src));
};

prototype.insert = function(tuples) {
  this._input.add = this._input.add.concat(tuples.map(Tuple.ingest));
  return this;
};

prototype.remove = function(where) {
  var remove = this._data.filter(where);
  this._input.rem = this._input.rem.concat(remove);
  return this;
};

prototype.update = function(where, field, func) {
  var mod = this._input.mod,
      ids = Tuple.idMap(mod);

  this._input.fields[field] = 1;

  this._data.filter(where).forEach(function(x) {
    var prev = x[field],
        next = func(x);
    if (prev !== next) {
      Tuple.set(x, field, next);
      if (ids[x._id] !== 1) {
        mod.push(x);
        ids[x._id] = 1;
      }
    }
  });

  return this;
};

prototype.values = function(data) {
  if (!arguments.length) return this._collector.data();

  // Replace backing data
  this._input.rem = this._data.slice();
  if (data) { this.insert(data); }
  return this;
};

prototype.mutates = function(m) {
  if (!arguments.length) return this._mutates;
  this._mutates = this._mutates || m;
  return this;
};

prototype.last = function() {
  return this._output;
};

prototype.fire = function(input) {
  if (input) this._input = input;
  this._graph.propagate(this._input, this._pipeline[0]);
  return this;
};

prototype.pipeline = function(pipeline) {
  if (!arguments.length) return this._pipeline;

  var graph = this._graph,
      status;

  pipeline.unshift(this._inputNode = DataSourceInput(this));
  status = graph.preprocess(pipeline);

  if (status.router) {
    pipeline.push(status.collector = new Collector(graph));
  }

  pipeline.push(this._outputNode = DataSourceOutput(this));
  this._collector = status.collector;
  this._mutates = !!status.mutates;
  graph.connect(this._pipeline = pipeline);

  return this;
};

prototype.synchronize = function() {
  this._graph.synchronize(this._pipeline);
  return this;
};

prototype.listener = function() {
  return DataSourceListener(this).addListener(this._inputNode);
};

prototype.addListener = function(l) {
  if (l instanceof DataSource) {
    this._collector.addListener(l.listener());
  } else {
    this._outputNode.addListener(l);
  }
  return this;
};

prototype.removeListener = function(l) {
  this._outputNode.removeListener(l);
};

prototype.listeners = function(ds) {
  return (ds ? this._collector : this._outputNode).listeners();
};

// Input node applies the datasource's delta, and propagates it to
// the rest of the pipeline. It receives touches to reflow data.
function DataSourceInput(ds) {
  var input = new Node(ds._graph)
    .router(true)
    .collector(true);

  input.data = function() {
    return ds._data;
  };

  input.evaluate = function(input) {
    log.debug(input, ['input', ds._name]);

    var delta = ds._input,
        out = ChangeSet.create(input), f;

    // Delta might contain fields updated through API
    for (f in delta.fields) {
      out.fields[f] = 1;
    }

    // update data
    if (delta.rem.length) {
      ds._data = Tuple.idFilter(ds._data, delta.rem);
    }

    if (delta.add.length) {
      ds._data = ds._data.concat(delta.add);
    }

    // if reflowing, add any other tuples not currently in changeset
    if (input.reflow) {
      delta.mod = delta.mod.concat(
        Tuple.idFilter(ds._data, delta.add, delta.mod, delta.rem));
    }

    // reset change list
    ds._input = ChangeSet.create();

    out.add = delta.add;
    out.mod = delta.mod;
    out.rem = delta.rem;
    out.facet = ds._facet;
    return out;
  };

  return input;
}

// Output node captures the last changeset seen by this datasource
// (needed for joins and builds) and materializes any nested data.
// If this datasource is faceted, materializes the values in the facet.
function DataSourceOutput(ds) {
  var output = new Node(ds._graph)
    .router(true)
    .reflows(true)
    .collector(true);

  output.data = function() {
    return ds._collector ? ds._collector.data() : ds._data;
  };

  output.evaluate = function(input) {
    log.debug(input, ['output', ds._name]);

    var out = ChangeSet.create(input, true);

    if (ds._facet) {
      ds._facet.values = ds.values();
      input.facet = null;
    }

    ds._output = input;
    out.data[ds._name] = 1;
    return out;
  };

  return output;
}

function DataSourceListener(ds) {
  var l = new Node(ds._graph).router(true);

  l.evaluate = function(input) {
    // Tuple derivation carries a cost. So only derive if the pipeline has
    // operators that mutate, and thus would override the source data.
    if (ds.mutates()) {
      var map = ds._srcMap || (ds._srcMap = {}), // to propagate tuples correctly
          output = ChangeSet.create(input);

      output.add = input.add.map(function(t) {
        return (map[t._id] = Tuple.derive(t));
      });

      output.mod = input.mod.map(function(t) {
        return Tuple.rederive(t, map[t._id]);
      });

      output.rem = input.rem.map(function(t) {
        var o = map[t._id];
        return (map[t._id] = null, o);
      });

      return (ds._input = output);
    } else {
      return (ds._input = input);
    }
  };

  return l;
}

module.exports = DataSource;
<commit_msg>DataSourceInput should apply sort function.<commit_after>var log = require('vega-logging'),
    ChangeSet = require('./ChangeSet'),
    Collector = require('./Collector'),
    Tuple = require('./Tuple'),
    Node = require('./Node'); // jshint ignore:line

function DataSource(graph, name, facet) {
  this._graph = graph;
  this._name = name;
  this._data = [];
  this._source = null;
  this._facet  = facet;
  this._input  = ChangeSet.create();
  this._output = null; // Output changeset

  this._inputNode  = null;
  this._outputNode = null;
  this._pipeline  = null; // Pipeline of transformations.
  this._collector = null; // Collector to materialize output of pipeline.
  this._mutates = false;  // Does any pipeline operator mutate tuples?
}

var prototype = DataSource.prototype;

prototype.name = function(name) {
  if (!arguments.length) return this._name;
  return (this._name = name, this);
};

prototype.source = function(src) {
  if (!arguments.length) return this._source;
  return (this._source = this._graph.data(src));
};

prototype.insert = function(tuples) {
  this._input.add = this._input.add.concat(tuples.map(Tuple.ingest));
  return this;
};

prototype.remove = function(where) {
  var remove = this._data.filter(where);
  this._input.rem = this._input.rem.concat(remove);
  return this;
};

prototype.update = function(where, field, func) {
  var mod = this._input.mod,
      ids = Tuple.idMap(mod);

  this._input.fields[field] = 1;

  this._data.filter(where).forEach(function(x) {
    var prev = x[field],
        next = func(x);
    if (prev !== next) {
      Tuple.set(x, field, next);
      if (ids[x._id] !== 1) {
        mod.push(x);
        ids[x._id] = 1;
      }
    }
  });

  return this;
};

prototype.values = function(data) {
  if (!arguments.length) return this._collector.data();

  // Replace backing data
  this._input.rem = this._data.slice();
  if (data) { this.insert(data); }
  return this;
};

prototype.mutates = function(m) {
  if (!arguments.length) return this._mutates;
  this._mutates = this._mutates || m;
  return this;
};

prototype.last = function() {
  return this._output;
};

prototype.fire = function(input) {
  if (input) this._input = input;
  this._graph.propagate(this._input, this._pipeline[0]);
  return this;
};

prototype.pipeline = function(pipeline) {
  if (!arguments.length) return this._pipeline;

  var graph = this._graph,
      status;

  pipeline.unshift(this._inputNode = DataSourceInput(this));
  status = graph.preprocess(pipeline);

  if (status.router) {
    pipeline.push(status.collector = new Collector(graph));
  }

  pipeline.push(this._outputNode = DataSourceOutput(this));
  this._collector = status.collector;
  this._mutates = !!status.mutates;
  graph.connect(this._pipeline = pipeline);

  return this;
};

prototype.synchronize = function() {
  this._graph.synchronize(this._pipeline);
  return this;
};

prototype.listener = function() {
  return DataSourceListener(this).addListener(this._inputNode);
};

prototype.addListener = function(l) {
  if (l instanceof DataSource) {
    this._collector.addListener(l.listener());
  } else {
    this._outputNode.addListener(l);
  }
  return this;
};

prototype.removeListener = function(l) {
  this._outputNode.removeListener(l);
};

prototype.listeners = function(ds) {
  return (ds ? this._collector : this._outputNode).listeners();
};

// Input node applies the datasource's delta, and propagates it to
// the rest of the pipeline. It receives touches to reflow data.
function DataSourceInput(ds) {
  var input = new Node(ds._graph)
    .router(true)
    .collector(true);

  input.data = function() {
    return ds._data;
  };

  input.evaluate = function(input) {
    log.debug(input, ['input', ds._name]);

    var delta = ds._input,
        out = ChangeSet.create(input), f;

    // Delta might contain fields updated through API
    for (f in delta.fields) {
      out.fields[f] = 1;
    }

    // update data
    if (delta.rem.length) {
      ds._data = Tuple.idFilter(ds._data, delta.rem);
    }

    if (delta.add.length) {
      ds._data = ds._data.concat(delta.add);
    }

    if (delta.sort) {
      ds._data.sort(delta.sort);
    }

    // if reflowing, add any other tuples not currently in changeset
    if (input.reflow) {
      delta.mod = delta.mod.concat(
        Tuple.idFilter(ds._data, delta.add, delta.mod, delta.rem));
    }

    // reset change list
    ds._input = ChangeSet.create();

    out.add = delta.add;
    out.mod = delta.mod;
    out.rem = delta.rem;
    out.facet = ds._facet;
    return out;
  };

  return input;
}

// Output node captures the last changeset seen by this datasource
// (needed for joins and builds) and materializes any nested data.
// If this datasource is faceted, materializes the values in the facet.
function DataSourceOutput(ds) {
  var output = new Node(ds._graph)
    .router(true)
    .reflows(true)
    .collector(true);

  output.data = function() {
    return ds._collector ? ds._collector.data() : ds._data;
  };

  output.evaluate = function(input) {
    log.debug(input, ['output', ds._name]);

    var out = ChangeSet.create(input, true);

    if (ds._facet) {
      ds._facet.values = ds.values();
      input.facet = null;
    }

    ds._output = input;
    out.data[ds._name] = 1;
    return out;
  };

  return output;
}

function DataSourceListener(ds) {
  var l = new Node(ds._graph).router(true);

  l.evaluate = function(input) {
    // Tuple derivation carries a cost. So only derive if the pipeline has
    // operators that mutate, and thus would override the source data.
    if (ds.mutates()) {
      var map = ds._srcMap || (ds._srcMap = {}), // to propagate tuples correctly
          output = ChangeSet.create(input);

      output.add = input.add.map(function(t) {
        return (map[t._id] = Tuple.derive(t));
      });

      output.mod = input.mod.map(function(t) {
        return Tuple.rederive(t, map[t._id]);
      });

      output.rem = input.rem.map(function(t) {
        var o = map[t._id];
        return (map[t._id] = null, o);
      });

      return (ds._input = output);
    } else {
      return (ds._input = input);
    }
  };

  return l;
}

module.exports = DataSource;
<|endoftext|>


<commit_before>var express = require('express');
var app = express();
var ejs = require('ejs');

var setting = require("./setting.js");
var mainUI = require("./mainUI.js");

app.engine('ejs', ejs.renderFile);

mainUI.mainUI(app); //mainUIの情報を受け取る

app.get('/js/app.js', function(req, res){
  res.sendFile(__dirname + "/views/js/app.js");
});

app.get('/css/app.css', function(req, res){
  res.sendFile(__dirname + "/views/css/app.css");
});

app.listen(setting.port, setting.host, function(){
  console.log("server listening...  " + setting.host + ":" + setting.port);
});
<commit_msg>seフロント側への初回ページの表示リクエスト<commit_after>var express = require('express'),
    app = express(),
    server = require('http').Server(app),
    io = require('socket.io')(server);
var ejs = require('ejs');
var mongoose = require('mongoose');

var setting = require("./setting.js");
var mainUI = require("./mainUI.js");
var DBModule = require("./DB_method/dbmodule.js");

var dbmodule = new DBModule(mongoose);
dbmodule.dbdefine();

app.engine('ejs', ejs.renderFile);

mainUI.mainUI(app); //mainUIの情報を受け取る

io.sockets.on("connection", function(socket){
  dbmodule.dball(function(docs){
      io.sockets.emit("init_data", docs);
  });
});

app.get('/js/app.js', function(req, res){
  res.sendFile(__dirname + "/views/js/app.js");
});

app.get('/css/app.css', function(req, res){
  res.sendFile(__dirname + "/views/css/app.css");
});

server.listen(setting.port, setting.host, function(){
  console.log("server listening...  " + setting.host + ":" + setting.port);
});
<|endoftext|>


<commit_before>/* global moment */
import {parseDateString, formatDate} from 'ghost/utils/date-formatting';
import SlugGenerator from 'ghost/models/slug-generator';
import boundOneWay from 'ghost/utils/bound-one-way';

var PostSettingsMenuController = Ember.ObjectController.extend({
    init: function () {
        this._super();

        // when creating a new post we want to observe the title
        // to generate the post's slug
        if (this.get('isNew')) {
            this.addObserver('titleScratch', this, 'titleObserver');
        }
    },
    selectedAuthor: Ember.computed.oneWay('author'),
    changeAuthor: function () {
        var author = this.get('author'),
            selectedAuthor = this.get('selectedAuthor'),
            model = this.get('model'),
            self = this;
        //return if nothing changed
        if (selectedAuthor.get('id') === author.get('id')) {
            return;
        }
        model.set('author', selectedAuthor);
        model.save(this.get('saveOptions')).catch(function (errors) {
            self.showErrors(errors);
            self.set('selectedAuthor', author);
            model.rollback();
        });
    }.observes('selectedAuthor'),
    authors: function () {
        //Loaded asynchronously, so must use promise proxies.
        var deferred = {},
            self = this;

        deferred.promise = this.store.find('user').then(function (users) {
            return users.rejectBy('id', 'me');
        }).then(function (users) {
            self.set('selectedAuthor', users.get('firstObject'));

            return users;
        });

        return Ember.ArrayProxy
            .extend(Ember.PromiseProxyMixin)
            .create(deferred);
    }.property(),
    //Changes in the PSM are too minor to warrant NProgress firing
    saveOptions: {disableNProgress: true},
    /**
     * The placeholder is the published date of the post,
     * or the current date if the pubdate has not been set.
     */
    publishedAtPlaceholder: function () {
        var pubDate = this.get('published_at');
        if (pubDate) {
            return formatDate(pubDate);
        }
        return formatDate(moment());
    }.property('publishedAtValue'),
    publishedAtValue: boundOneWay('published_at', formatDate),

    slugValue: boundOneWay('slug'),
    //Lazy load the slug generator for slugPlaceholder
    slugGenerator: Ember.computed(function () {
        return SlugGenerator.create({
            ghostPaths: this.get('ghostPaths'),
            slugType: 'post'
        });
    }),
    //Requests slug from title
    generateSlugPlaceholder: function () {
        var self = this,
            title = this.get('titleScratch');

        this.get('slugGenerator').generateSlug(title).then(function (slug) {
            self.set('slugPlaceholder', slug);
        });
    },
    titleObserver: function () {
        if (this.get('isNew') && !this.get('title')) {
            Ember.run.debounce(this, 'generateSlugPlaceholder', 700);
        }
    },
    slugPlaceholder: function (key, value) {
        var slug = this.get('slug');

        //If the post has a slug, that's its placeholder.
        if (slug) {
            return slug;
        }

        //Otherwise, it's whatever value was set by the
        //  slugGenerator (below)
        if (arguments.length > 1) {
            return value;
        }
        //The title will stand in until the actual slug has been generated
        return this.get('titleScratch');
    }.property(),

    showErrors: function (errors) {
        errors = Ember.isArray(errors) ? errors : [errors];
        this.notifications.closePassive();
        this.notifications.showErrors(errors);
    },
    showSuccess: function (message) {
        this.notifications.closePassive();
        this.notifications.showSuccess(message);
    },
    actions: {
        togglePage: function () {
            var self = this;

            this.toggleProperty('page');
            // If this is a new post.  Don't save the model.  Defer the save
            // to the user pressing the save button
            if (this.get('isNew')) {
                return;
            }

            this.get('model').save(this.get('saveOptions')).catch(function (errors) {
                self.showErrors(errors);
                self.get('model').rollback();
            });
        },
        /**
         * triggered by user manually changing slug
         */
        updateSlug: function (newSlug) {
            var slug = this.get('slug'),
                self = this;

            newSlug = newSlug || slug;

            newSlug = newSlug.trim();

            // Ignore unchanged slugs or candidate slugs that are empty
            if (!newSlug || slug === newSlug) {
                return;
            }

            this.get('slugGenerator').generateSlug(newSlug).then(function (serverSlug) {
                // If after getting the sanitized and unique slug back from the API
                // we end up with a slug that matches the existing slug, abort the change
                if (serverSlug === slug) {
                    return;
                }

                // Because the server transforms the candidate slug by stripping
                // certain characters and appending a number onto the end of slugs
                // to enforce uniqueness, there are cases where we can get back a
                // candidate slug that is a duplicate of the original except for
                // the trailing incrementor (e.g., this-is-a-slug and this-is-a-slug-2)

                // get the last token out of the slug candidate and see if it's a number
                var slugTokens = serverSlug.split('-'),
                    check = Number(slugTokens.pop());

                // if the candidate slug is the same as the existing slug except
                // for the incrementor then the existing slug should be used
                if (_.isNumber(check) && check > 0) {
                    if (slug === slugTokens.join('-') && serverSlug !== newSlug) {
                        return;
                    }
                }

                self.set('slug', serverSlug);

                if (self.hasObserverFor('titleScratch')) {
                    self.removeObserver('titleScratch', self, 'titleObserver');
                }

                // If this is a new post.  Don't save the model.  Defer the save
                // to the user pressing the save button
                if (self.get('isNew')) {
                    return;
                }

                return self.get('model').save(self.get('saveOptions'));
            }).then(function () {
                self.showSuccess('Permalink successfully changed to ' +
                    self.get('slug') + '.');
            }).catch(function (errors) {
                self.showErrors(errors);
                self.get('model').rollback();
            });
        },

        /**
         * Parse user's set published date.
         * Action sent by post settings menu view.
         * (#1351)
         */
        setPublishedAt: function (userInput) {
            var errMessage = '',
                newPublishedAt = parseDateString(userInput),
                publishedAt = this.get('published_at'),
                self = this;

            if (!userInput) {
                //Clear out the published_at field for a draft
                if (this.get('isDraft')) {
                    this.set('published_at', null);
                }
                return;
            }

            // Validate new Published date
            if (!newPublishedAt.isValid()) {
                errMessage = 'Published Date must be a valid date with format: ' +
                    'DD MMM YY @ HH:mm (e.g. 6 Dec 14 @ 15:00)';
            }
            if (newPublishedAt.diff(new Date(), 'h') > 0) {
                errMessage = 'Published Date cannot currently be in the future.';
            }

            //If errors, notify and exit.
            if (errMessage) {
                this.showErrors(errMessage);
                return;
            }

            // Do nothing if the user didn't actually change the date
            if (publishedAt && publishedAt.isSame(newPublishedAt)) {
                return;
            }

            //Validation complete
            this.set('published_at', newPublishedAt);

            // If this is a new post.  Don't save the model.  Defer the save
            // to the user pressing the save button
            if (this.get('isNew')) {
                return;
            }

            this.get('model').save(this.get('saveOptions')).catch(function (errors) {
                self.showErrors(errors);
                self.get('model').rollback();
            });
        }
    }
});

export default PostSettingsMenuController;<commit_msg>Error modifying "author" attribute before post record has been created<commit_after>/* global moment */
import {parseDateString, formatDate} from 'ghost/utils/date-formatting';
import SlugGenerator from 'ghost/models/slug-generator';
import boundOneWay from 'ghost/utils/bound-one-way';

var PostSettingsMenuController = Ember.ObjectController.extend({
    init: function () {
        this._super();

        // when creating a new post we want to observe the title
        // to generate the post's slug
        if (this.get('isNew')) {
            this.addObserver('titleScratch', this, 'titleObserver');
        }
    },
    selectedAuthor: Ember.computed.oneWay('author'),
    changeAuthor: function () {
        var author = this.get('author'),
            selectedAuthor = this.get('selectedAuthor'),
            model = this.get('model'),
            self = this;
        //return if nothing changed
        if (selectedAuthor.get('id') === author.get('id')) {
            return;
        }
        model.set('author', selectedAuthor);

        //if this is a new post (never been saved before), don't try to save it
        if (this.get('isNew')) {
            return;
        }

        model.save(this.get('saveOptions')).catch(function (errors) {
            self.showErrors(errors);
            self.set('selectedAuthor', author);
            model.rollback();
        });
    }.observes('selectedAuthor'),
    authors: function () {
        //Loaded asynchronously, so must use promise proxies.
        var deferred = {},
            self = this;

        deferred.promise = this.store.find('user').then(function (users) {
            return users.rejectBy('id', 'me');
        }).then(function (users) {
            self.set('selectedAuthor', users.get('firstObject'));

            return users;
        });

        return Ember.ArrayProxy
            .extend(Ember.PromiseProxyMixin)
            .create(deferred);
    }.property(),
    //Changes in the PSM are too minor to warrant NProgress firing
    saveOptions: {disableNProgress: true},
    /**
     * The placeholder is the published date of the post,
     * or the current date if the pubdate has not been set.
     */
    publishedAtPlaceholder: function () {
        var pubDate = this.get('published_at');
        if (pubDate) {
            return formatDate(pubDate);
        }
        return formatDate(moment());
    }.property('publishedAtValue'),
    publishedAtValue: boundOneWay('published_at', formatDate),

    slugValue: boundOneWay('slug'),
    //Lazy load the slug generator for slugPlaceholder
    slugGenerator: Ember.computed(function () {
        return SlugGenerator.create({
            ghostPaths: this.get('ghostPaths'),
            slugType: 'post'
        });
    }),
    //Requests slug from title
    generateSlugPlaceholder: function () {
        var self = this,
            title = this.get('titleScratch');

        this.get('slugGenerator').generateSlug(title).then(function (slug) {
            self.set('slugPlaceholder', slug);
        });
    },
    titleObserver: function () {
        if (this.get('isNew') && !this.get('title')) {
            Ember.run.debounce(this, 'generateSlugPlaceholder', 700);
        }
    },
    slugPlaceholder: function (key, value) {
        var slug = this.get('slug');

        //If the post has a slug, that's its placeholder.
        if (slug) {
            return slug;
        }

        //Otherwise, it's whatever value was set by the
        //  slugGenerator (below)
        if (arguments.length > 1) {
            return value;
        }
        //The title will stand in until the actual slug has been generated
        return this.get('titleScratch');
    }.property(),

    showErrors: function (errors) {
        errors = Ember.isArray(errors) ? errors : [errors];
        this.notifications.closePassive();
        this.notifications.showErrors(errors);
    },
    showSuccess: function (message) {
        this.notifications.closePassive();
        this.notifications.showSuccess(message);
    },
    actions: {
        togglePage: function () {
            var self = this;

            this.toggleProperty('page');
            // If this is a new post.  Don't save the model.  Defer the save
            // to the user pressing the save button
            if (this.get('isNew')) {
                return;
            }

            this.get('model').save(this.get('saveOptions')).catch(function (errors) {
                self.showErrors(errors);
                self.get('model').rollback();
            });
        },
        /**
         * triggered by user manually changing slug
         */
        updateSlug: function (newSlug) {
            var slug = this.get('slug'),
                self = this;

            newSlug = newSlug || slug;

            newSlug = newSlug.trim();

            // Ignore unchanged slugs or candidate slugs that are empty
            if (!newSlug || slug === newSlug) {
                return;
            }

            this.get('slugGenerator').generateSlug(newSlug).then(function (serverSlug) {
                // If after getting the sanitized and unique slug back from the API
                // we end up with a slug that matches the existing slug, abort the change
                if (serverSlug === slug) {
                    return;
                }

                // Because the server transforms the candidate slug by stripping
                // certain characters and appending a number onto the end of slugs
                // to enforce uniqueness, there are cases where we can get back a
                // candidate slug that is a duplicate of the original except for
                // the trailing incrementor (e.g., this-is-a-slug and this-is-a-slug-2)

                // get the last token out of the slug candidate and see if it's a number
                var slugTokens = serverSlug.split('-'),
                    check = Number(slugTokens.pop());

                // if the candidate slug is the same as the existing slug except
                // for the incrementor then the existing slug should be used
                if (_.isNumber(check) && check > 0) {
                    if (slug === slugTokens.join('-') && serverSlug !== newSlug) {
                        return;
                    }
                }

                self.set('slug', serverSlug);

                if (self.hasObserverFor('titleScratch')) {
                    self.removeObserver('titleScratch', self, 'titleObserver');
                }

                // If this is a new post.  Don't save the model.  Defer the save
                // to the user pressing the save button
                if (self.get('isNew')) {
                    return;
                }

                return self.get('model').save(self.get('saveOptions'));
            }).then(function () {
                self.showSuccess('Permalink successfully changed to ' +
                    self.get('slug') + '.');
            }).catch(function (errors) {
                self.showErrors(errors);
                self.get('model').rollback();
            });
        },

        /**
         * Parse user's set published date.
         * Action sent by post settings menu view.
         * (#1351)
         */
        setPublishedAt: function (userInput) {
            var errMessage = '',
                newPublishedAt = parseDateString(userInput),
                publishedAt = this.get('published_at'),
                self = this;

            if (!userInput) {
                //Clear out the published_at field for a draft
                if (this.get('isDraft')) {
                    this.set('published_at', null);
                }
                return;
            }

            // Validate new Published date
            if (!newPublishedAt.isValid()) {
                errMessage = 'Published Date must be a valid date with format: ' +
                    'DD MMM YY @ HH:mm (e.g. 6 Dec 14 @ 15:00)';
            }
            if (newPublishedAt.diff(new Date(), 'h') > 0) {
                errMessage = 'Published Date cannot currently be in the future.';
            }

            //If errors, notify and exit.
            if (errMessage) {
                this.showErrors(errMessage);
                return;
            }

            // Do nothing if the user didn't actually change the date
            if (publishedAt && publishedAt.isSame(newPublishedAt)) {
                return;
            }

            //Validation complete
            this.set('published_at', newPublishedAt);

            // If this is a new post.  Don't save the model.  Defer the save
            // to the user pressing the save button
            if (this.get('isNew')) {
                return;
            }

            this.get('model').save(this.get('saveOptions')).catch(function (errors) {
                self.showErrors(errors);
                self.get('model').rollback();
            });
        }
    }
});

export default PostSettingsMenuController;<|endoftext|>


<commit_before>const privateData = new WeakMap()

function fire(name, target) {
  setTimeout(function() {
    target.dispatchEvent(new Event(name))
  }, 0)
}

function handleData(el) {
  return getData(el).then(
    function(html) {
      const parentNode = el.parentNode
      if (parentNode) {
        el.insertAdjacentHTML('afterend', html)
        parentNode.removeChild(el)
      }
    },
    function() {
      el.classList.add('is-error')
    }
  )
}

function getData(el) {
  const src = el.src
  let data = privateData.get(el)
  if (data && data.src === src) {
    return data.data
  } else {
    if (src) {
      data = el.load()
    } else {
      data = Promise.reject(new Error('missing src'))
    }
    privateData.set(el, {src, data})
    return data
  }
}

function isWildcard(accept) {
  return accept && !!accept.split(',').find(x => x.match(/^\s*\*\/\*/))
}

export default class IncludeFragmentElement extends HTMLElement {
  constructor() {
    super()
  }

  static get observedAttributes() {
    return ['src']
  }

  get src() {
    const src = this.getAttribute('src')
    if (src) {
      const link = this.ownerDocument.createElement('a')
      link.href = src
      return link.href
    } else {
      return ''
    }
  }

  set src(val) {
    if (val) {
      this.setAttribute('src', val)
    } else {
      this.removeAttribute('src')
    }
  }

  get accept() {
    return this.getAttribute('accept')
  }

  set accept(val) {
    if (val) {
      this.setAttribute('accept', val)
    } else {
      this.removeAttribute('accept')
    }
  }

  get data() {
    return getData(this)
  }

  attributeChangedCallback(attribute) {
    if (attribute === 'src') {
      // Source changed after attached so replace element.
      if (this._attached) {
        handleData(this)
      }
    }
  }

  connectedCallback() {
    this._attached = true
    if (this.src) {
      handleData(this)
    }
  }

  disconnectedCallback() {
    this._attached = false
  }

  request() {
    const src = this.src
    if (!src) {
      throw new Error('missing src')
    }

    return new Request(src, {
      method: 'GET',
      credentials: 'same-origin',
      headers: {
        Accept: this.accept || 'text/html'
      }
    })
  }

  load() {
    return Promise.resolve()
      .then(() => {
        fire('loadstart', this)
        return this.fetch(this.request())
      })
      .then(response => {
        if (response.status !== 200) {
          throw new Error(`Failed to load resource: the server responded with a status of ${response.status}`)
        }
        const ct = response.headers.get('Content-Type')
        if (!isWildcard(this.accept) && (!ct || !ct.match(this.accept ? this.accept : /^text\/html/))) {
          throw new Error(`Failed to load resource: expected ${this.accept || 'text/html'} but was ${ct}`)
        }
        return response
      })
      .then(response => response.text())
      .then(
        data => {
          fire('load', this)
          fire('loadend', this)
          return data
        },
        error => {
          fire('error', this)
          fire('loadend', this)
          throw error
        }
      )
  }

  fetch(request) {
    return fetch(request)
  }
}

if (!window.customElements.get('include-fragment')) {
  window.IncludeFragmentElement = IncludeFragmentElement
  window.customElements.define('include-fragment', IncludeFragmentElement)
}
<commit_msg>Avoid removing attriute on setter<commit_after>const privateData = new WeakMap()

function fire(name, target) {
  setTimeout(function() {
    target.dispatchEvent(new Event(name))
  }, 0)
}

function handleData(el) {
  return getData(el).then(
    function(html) {
      const parentNode = el.parentNode
      if (parentNode) {
        el.insertAdjacentHTML('afterend', html)
        parentNode.removeChild(el)
      }
    },
    function() {
      el.classList.add('is-error')
    }
  )
}

function getData(el) {
  const src = el.src
  let data = privateData.get(el)
  if (data && data.src === src) {
    return data.data
  } else {
    if (src) {
      data = el.load()
    } else {
      data = Promise.reject(new Error('missing src'))
    }
    privateData.set(el, {src, data})
    return data
  }
}

function isWildcard(accept) {
  return accept && !!accept.split(',').find(x => x.match(/^\s*\*\/\*/))
}

export default class IncludeFragmentElement extends HTMLElement {
  constructor() {
    super()
  }

  static get observedAttributes() {
    return ['src']
  }

  get src() {
    const src = this.getAttribute('src')
    if (src) {
      const link = this.ownerDocument.createElement('a')
      link.href = src
      return link.href
    } else {
      return ''
    }
  }

  set src(val) {
    this.setAttribute('src', val)
  }

  get accept() {
    return this.getAttribute('accept')
  }

  set accept(val) {
    this.setAttribute('accept', val)
  }

  get data() {
    return getData(this)
  }

  attributeChangedCallback(attribute) {
    if (attribute === 'src') {
      // Source changed after attached so replace element.
      if (this._attached) {
        handleData(this)
      }
    }
  }

  connectedCallback() {
    this._attached = true
    if (this.src) {
      handleData(this)
    }
  }

  disconnectedCallback() {
    this._attached = false
  }

  request() {
    const src = this.src
    if (!src) {
      throw new Error('missing src')
    }

    return new Request(src, {
      method: 'GET',
      credentials: 'same-origin',
      headers: {
        Accept: this.accept || 'text/html'
      }
    })
  }

  load() {
    return Promise.resolve()
      .then(() => {
        fire('loadstart', this)
        return this.fetch(this.request())
      })
      .then(response => {
        if (response.status !== 200) {
          throw new Error(`Failed to load resource: the server responded with a status of ${response.status}`)
        }
        const ct = response.headers.get('Content-Type')
        if (!isWildcard(this.accept) && (!ct || !ct.match(this.accept ? this.accept : /^text\/html/))) {
          throw new Error(`Failed to load resource: expected ${this.accept || 'text/html'} but was ${ct}`)
        }
        return response
      })
      .then(response => response.text())
      .then(
        data => {
          fire('load', this)
          fire('loadend', this)
          return data
        },
        error => {
          fire('error', this)
          fire('loadend', this)
          throw error
        }
      )
  }

  fetch(request) {
    return fetch(request)
  }
}

if (!window.customElements.get('include-fragment')) {
  window.IncludeFragmentElement = IncludeFragmentElement
  window.customElements.define('include-fragment', IncludeFragmentElement)
}
<|endoftext|>


<commit_before>/**
 * Deferred Object
 *
 * Used for building up a Query
 */
var Q = require('q'),
    _ = require('underscore'),
    normalize = require('../utils/normalize');

var Deferred = module.exports = function(context, method, criteria, values) {

  if(!context) return new Error('Must supply a context to a new Deferred object. Usage: new Deferred(context, method, criteria)');
  if(!method) return new Error('Must supply a method to a new Deferred object. Usage: new Deferred(context, method, criteria)');

  this._context = context;
  this._method = method;
  this._criteria = criteria || {};
  this._values = values || null;

  return this;
};

/**
 * Add a Join clause to the criteria object.
 *
 * Used for populating associations.
 *
 * @param {String} key, the key to populate
 * @return this
 */

Deferred.prototype.populate = function(keyName) {
  var self = this,
      joins = this._criteria.joins || [],
      attr = this._context._attributes[keyName],
      pk = 'id',
      join;

  Object.keys(this._context._attributes).forEach(function(key) {
    if(self._context._attributes[key].hasOwnProperty('primaryKey')) {
      pk = key;
    }
  });

  if(!attr) throw new Error('Attempting to populate an attribute that doesn\'t exist');

  var parentKey = this._context.waterline.collections[this._context.identity].attributes[keyName];

  join = {
    parent: this._context._tableName,
    parentKey: attr.columnName || pk,
    child: attr.references,
    childKey: attr.on,
    select: true,
    removeParentKey: parentKey.model ? true : false
  };

  if(this._context.waterline.schema[attr.references].junctionTable) join.select = false;

  joins.push(join);

  // If a junction table is used add an additional join to get the data
  if(this._context.waterline.schema[attr.references].junctionTable) {
    var reference = _.clone(this._context.waterline.schema[attr.references].attributes);

    Object.keys(reference).forEach(function(key) {
      if(reference[key].hasOwnProperty('references') && reference[key].references !== attr.collection.toLowerCase()) {
        delete reference[key];
      }
    });

    // Get the only remaining key left
    var ref = Object.keys(reference)[0];

    join = {
      parent: attr.references,
      parentKey: reference[ref].columnName,
      child: reference[ref].references,
      childKey: reference[ref].on,
      select: true,
      removeParentKey: parentKey.model ? true : false
    };

    joins.push(join);
  }

  this._criteria.joins = joins;

  return this;
};

/**
 * Add a Where clause to the criteria object
 *
 * @param {Object} criteria to append
 * @return this
 */

Deferred.prototype.where = function(criteria) {

  // Normalize criteria
  criteria = normalize.criteria({ where: criteria });

  var where = this._criteria.where || {};

  if(!criteria.where) return this;

  Object.keys(criteria.where).forEach(function(key) {
    where[key] = criteria.where[key];
  });

  this._criteria.where = where;

  return this;
};

/**
 * Add a Limit clause to the criteria object
 *
 * @param {Integer} number to limit
 * @return this
 */

Deferred.prototype.limit = function(limit) {
  this._criteria.limit = limit;

  return this;
};

/**
 * Add a Skip clause to the criteria object
 *
 * @param {Integer} number to skip
 * @return this
 */

Deferred.prototype.skip = function(skip) {
  this._criteria.skip = skip;

  return this;
};

/**
 * Add a Paginate clause to the criteria object
 *
 * This is syntatical sugar that calls skip and
 * limit from a single function.
 *
 * @param {Object} page and limit
 * @return this
 */
Deferred.prototype.paginate = function(options) {
  var defaultLimit = 10;
  if(options == undefined) var options = {page: 0, limit: defaultLimit};

  var page  = options.page  || 0,
      limit = options.limit || defaultLimit,
      skip  = 0;

  if (page > 0 && limit == 0) skip = page - 1;
  if (page > 0 && limit > 0)  skip = (page * limit) - limit;

  this
  .skip(skip)
  .limit(limit);

  return this;
};

/**
 * Add a groupBy clause to the criteria object
 *
 * @param {Array|Arguments} Keys to group by
 * @return this
 */
Deferred.prototype.groupBy = function() {

  var args = Array.apply([], arguments);

  // If passed in a list, set that as the sum criteria
  if (args[0] instanceof Array) {
    args = args[0];
  }

  this._criteria.groupBy = args || [];

  return this;
};

/**
 * Add a Sort clause to the criteria object
 *
 * @param {String|Object} key and order
 * @return this
 */

Deferred.prototype.sort = function(criteria) {

  // Normalize criteria
  criteria = normalize.criteria({ sort: criteria });

  var sort = this._criteria.sort || {};

  Object.keys(criteria.sort).forEach(function(key) {
    sort[key] = criteria.sort[key];
  });

  this._criteria.sort = sort;

  return this;
};

/**
 * Add a Sum clause to the criteria object
 *
 * @param {Array|Arguments} Keys to sum over
 * @return this
 */
Deferred.prototype.sum = function() {

  var args = Array.apply([], arguments);

  // If passed in a list, set that as the sum criteria
  if (args[0] instanceof Array) {
    args = args[0];
  }

  this._criteria.sum = args || [];

  return this;
};

/**
 * Add an Average clause to the criteria object
 *
 * @param {Array|Arguments} Keys to average over
 * @return this
 */
Deferred.prototype.average = function() {

  var args = Array.apply([], arguments);

  // If passed in a list, set that as the average criteria
  if (args[0] instanceof Array) {
    args = args[0];
  }

  this._criteria.average = args || {};

  return this;
};

/**
 * Add a min clause to the criteria object
 *
 * @param {Array|Arguments} Keys to min over
 * @return this
 */
Deferred.prototype.min = function() {

  var args = Array.apply([], arguments);

  // If passed in a list, set that as the min criteria
  if (args[0] instanceof Array) {
    args = args[0];
  }

  this._criteria.min = args || {};

  return this;
};

/**
 * Add a min clause to the criteria object
 *
 * @param {Array|Arguments} Keys to min over
 * @return this
 */
Deferred.prototype.max = function() {

  var args = Array.apply([], arguments);

  // If passed in a list, set that as the min criteria
  if (args[0] instanceof Array) {
    args = args[0];
  }

  this._criteria.max = args || {};

  return this;
};

/**
 * Add values to be used in update or create query
 *
 * @param {Object, Array} values
 * @return this
 */

Deferred.prototype.set = function(values) {
  this._values = values;

  return this;
};

/**
 * Execute a Query using the method passed into the
 * constuctor.
 *
 * @param {Function} callback
 * @return callback with parameters (err, results)
 */

Deferred.prototype.exec = function(cb) {
  if(!cb) {
    console.log(new Error('Error: No Callback supplied, you must define a callback.').message);
  }

  var args = [this._criteria, cb];
  if(this._values) args.splice(1, 0, this._values);
  this._method.apply(this._context, args);
};

/**
 * Alias for .exec
 *
 * Used to keep backwards compatibility
 */

Deferred.prototype.done = function(cb) {
  this.exec.call(this, cb);
};

/**
 * Executes a Query, and returns a promise
 */

Deferred.prototype.toPromise = function() {
  var deferred = Q.defer();

  this.exec(deferred.makeNodeResolver());

  return deferred.promise;
};

/**
 * Executes a Query, and returns a promise that applies cb/ec to the
 * result/error.
 */

Deferred.prototype.then = function(cb, ec) {
  return this.toPromise().then(cb, ec);
};

/**
 * Applies results to function fn.apply, and returns a promise
 */

Deferred.prototype.spread = function(cb) {
  return this.toPromise().spread(cb);
};

/**
 * returns a promise and gets resolved with error
 */

Deferred.prototype.fail = function(cb) {
  return this.toPromise().fail(cb);
};

<commit_msg>update and comment deferred populate for later refactor<commit_after>/**
 * Deferred Object
 *
 * Used for building up a Query
 */
var Q = require('q'),
    _ = require('underscore'),
    normalize = require('../utils/normalize');

var Deferred = module.exports = function(context, method, criteria, values) {

  if(!context) return new Error('Must supply a context to a new Deferred object. Usage: new Deferred(context, method, criteria)');
  if(!method) return new Error('Must supply a method to a new Deferred object. Usage: new Deferred(context, method, criteria)');

  this._context = context;
  this._method = method;
  this._criteria = criteria || {};
  this._values = values || null;

  return this;
};

/**
 * Add a Join clause to the criteria object.
 *
 * Used for populating associations.
 *
 * @param {String} key, the key to populate
 * @return this
 */

Deferred.prototype.populate = function(keyName) {
  var self = this,
      joins = this._criteria.joins || [],
      pk = 'id',
      attr,
      join;

  // Set the attr value to the generated schema attribute
  attr = this._context.waterline.schema[this._context.identity].attributes[keyName];

  // Get the current collection's primary key attribute
  Object.keys(this._context._attributes).forEach(function(key) {
    if(self._context._attributes[key].hasOwnProperty('primaryKey')) {
      pk = key;
    }
  });

  if(!attr) throw new Error('Attempting to populate an attribute that doesn\'t exist');

  // Grab the key being populated to check if it is a has many to belongs to
  // If it's a belongs_to the adapter needs to know that it should replace the foreign key
  // with the associated value.
  var parentKey = this._context.waterline.collections[this._context.identity].attributes[keyName];

  // Build the initial join object that will link this collection to either another collection
  // or to a junction table.
  join = {
    parent: this._context._tableName,
    parentKey: attr.columnName || pk,
    child: attr.references,
    childKey: attr.on,
    select: true,
    removeParentKey: parentKey.model ? true : false
  };

  // If linking to a junction table the attributes shouldn't be included in the return value
  if(this._context.waterline.schema[attr.references].junctionTable) join.select = false;

  joins.push(join);

  // If a junction table is used add an additional join to get the data
  if(this._context.waterline.schema[attr.references].junctionTable) {

    // clone the reference attribute so we can mutate it
    var reference = _.clone(this._context.waterline.schema[attr.references].attributes);

    Object.keys(reference).forEach(function(key) {
      if(reference[key].hasOwnProperty('references') && key !== attr.collection.toLowerCase()) {
        delete reference[key];
      }
    });

    // Get the only remaining key left
    var ref = Object.keys(reference)[0];

    // Build out the second join object that will link a junction table with the
    // values being populated
    join = {
      parent: attr.references,
      parentKey: reference[ref].columnName,
      child: reference[ref].references,
      childKey: reference[ref].on,
      select: true,
      removeParentKey: parentKey.model ? true : false
    };

    joins.push(join);
  }

  // Set the criteria joins
  this._criteria.joins = joins;

  return this;
};

/**
 * Add a Where clause to the criteria object
 *
 * @param {Object} criteria to append
 * @return this
 */

Deferred.prototype.where = function(criteria) {

  // Normalize criteria
  criteria = normalize.criteria({ where: criteria });

  var where = this._criteria.where || {};

  if(!criteria.where) return this;

  Object.keys(criteria.where).forEach(function(key) {
    where[key] = criteria.where[key];
  });

  this._criteria.where = where;

  return this;
};

/**
 * Add a Limit clause to the criteria object
 *
 * @param {Integer} number to limit
 * @return this
 */

Deferred.prototype.limit = function(limit) {
  this._criteria.limit = limit;

  return this;
};

/**
 * Add a Skip clause to the criteria object
 *
 * @param {Integer} number to skip
 * @return this
 */

Deferred.prototype.skip = function(skip) {
  this._criteria.skip = skip;

  return this;
};

/**
 * Add a Paginate clause to the criteria object
 *
 * This is syntatical sugar that calls skip and
 * limit from a single function.
 *
 * @param {Object} page and limit
 * @return this
 */
Deferred.prototype.paginate = function(options) {
  var defaultLimit = 10;
  if(options == undefined) var options = {page: 0, limit: defaultLimit};

  var page  = options.page  || 0,
      limit = options.limit || defaultLimit,
      skip  = 0;

  if (page > 0 && limit == 0) skip = page - 1;
  if (page > 0 && limit > 0)  skip = (page * limit) - limit;

  this
  .skip(skip)
  .limit(limit);

  return this;
};

/**
 * Add a groupBy clause to the criteria object
 *
 * @param {Array|Arguments} Keys to group by
 * @return this
 */
Deferred.prototype.groupBy = function() {

  var args = Array.apply([], arguments);

  // If passed in a list, set that as the sum criteria
  if (args[0] instanceof Array) {
    args = args[0];
  }

  this._criteria.groupBy = args || [];

  return this;
};

/**
 * Add a Sort clause to the criteria object
 *
 * @param {String|Object} key and order
 * @return this
 */

Deferred.prototype.sort = function(criteria) {

  // Normalize criteria
  criteria = normalize.criteria({ sort: criteria });

  var sort = this._criteria.sort || {};

  Object.keys(criteria.sort).forEach(function(key) {
    sort[key] = criteria.sort[key];
  });

  this._criteria.sort = sort;

  return this;
};

/**
 * Add a Sum clause to the criteria object
 *
 * @param {Array|Arguments} Keys to sum over
 * @return this
 */
Deferred.prototype.sum = function() {

  var args = Array.apply([], arguments);

  // If passed in a list, set that as the sum criteria
  if (args[0] instanceof Array) {
    args = args[0];
  }

  this._criteria.sum = args || [];

  return this;
};

/**
 * Add an Average clause to the criteria object
 *
 * @param {Array|Arguments} Keys to average over
 * @return this
 */
Deferred.prototype.average = function() {

  var args = Array.apply([], arguments);

  // If passed in a list, set that as the average criteria
  if (args[0] instanceof Array) {
    args = args[0];
  }

  this._criteria.average = args || {};

  return this;
};

/**
 * Add a min clause to the criteria object
 *
 * @param {Array|Arguments} Keys to min over
 * @return this
 */
Deferred.prototype.min = function() {

  var args = Array.apply([], arguments);

  // If passed in a list, set that as the min criteria
  if (args[0] instanceof Array) {
    args = args[0];
  }

  this._criteria.min = args || {};

  return this;
};

/**
 * Add a min clause to the criteria object
 *
 * @param {Array|Arguments} Keys to min over
 * @return this
 */
Deferred.prototype.max = function() {

  var args = Array.apply([], arguments);

  // If passed in a list, set that as the min criteria
  if (args[0] instanceof Array) {
    args = args[0];
  }

  this._criteria.max = args || {};

  return this;
};

/**
 * Add values to be used in update or create query
 *
 * @param {Object, Array} values
 * @return this
 */

Deferred.prototype.set = function(values) {
  this._values = values;

  return this;
};

/**
 * Execute a Query using the method passed into the
 * constuctor.
 *
 * @param {Function} callback
 * @return callback with parameters (err, results)
 */

Deferred.prototype.exec = function(cb) {
  if(!cb) {
    console.log(new Error('Error: No Callback supplied, you must define a callback.').message);
  }

  var args = [this._criteria, cb];
  if(this._values) args.splice(1, 0, this._values);
  this._method.apply(this._context, args);
};

/**
 * Alias for .exec
 *
 * Used to keep backwards compatibility
 */

Deferred.prototype.done = function(cb) {
  this.exec.call(this, cb);
};

/**
 * Executes a Query, and returns a promise
 */

Deferred.prototype.toPromise = function() {
  var deferred = Q.defer();

  this.exec(deferred.makeNodeResolver());

  return deferred.promise;
};

/**
 * Executes a Query, and returns a promise that applies cb/ec to the
 * result/error.
 */

Deferred.prototype.then = function(cb, ec) {
  return this.toPromise().then(cb, ec);
};

/**
 * Applies results to function fn.apply, and returns a promise
 */

Deferred.prototype.spread = function(cb) {
  return this.toPromise().spread(cb);
};

/**
 * returns a promise and gets resolved with error
 */

Deferred.prototype.fail = function(cb) {
  return this.toPromise().fail(cb);
};

<|endoftext|>


<commit_before>"use strict"

let collection = 'CappedJobs'

module.exports.stream = (dbs) => {
  return dbs.mongo.collection(collection).find({}, {
    tailable: true,
    awaitData: true
  }).stream()
}
<commit_msg>Improve code<commit_after>"use strict"

const assert = require('assert');
const async = require('async');
let collection = 'CappedJobs'

module.exports.stream = (dbs) => {
  return dbs.mongo.collection(collection).find({}, {
    tailable: true,
    awaitData: true,
    timeout: false,
    numberOfRetries: Number.MAX_VALUE
  }).stream()
}

module.exports.restart = (dbs, cb) => {

  async.waterfall([
    function drop(cb) {
      dbs.mongo.collection(collection).drop(cb);
    },

    function create(data, cb) {
      dbs.mongo.createCollection(collection, {
        capped: true,
        size: 100000
      }, cb);
    },

    function insert(data, cb) {
      dbs.mongo.collection(collection).insert({
        a: 1
      }, cb)
    }

  ], (error, result) => {
    assert.equal(null, error);
    cb(error, result)
  })
}<|endoftext|>


<commit_before>import collection from './collection';
import internal from './internal';

export default {
  collection,
  internal,
};
<commit_msg>removed internal<commit_after>import collection from './collection';

export default {
  collection,
};
<|endoftext|>


<commit_before>/*
 * MelonJS Game Engine
 * Copyright (C) 2011, Olivier BIOT
 * http://www.melonjs.org
 *
 *
 */

(function($, undefined) {

	/**
	 *  Base64 decoding
	 *  @see http://www.webtoolkit.info/
	 */
	var Base64 = (function() {

		// hold public stuff in our singletong
		var singleton = {};

		// private property
		var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

		// public method for decoding
		singleton.decode = function(input) {

			// make sure our input string has the right format
			input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

			if (me.sys.nativeBase64) {
				// use native decoder
				return $.atob(input);
			}
			else {
				// use cross-browser decoding
				var output = [], chr1, chr2, chr3, enc1, enc2, enc3, enc4, i = 0;

				while (i < input.length) {
					enc1 = _keyStr.indexOf(input.charAt(i++));
					enc2 = _keyStr.indexOf(input.charAt(i++));
					enc3 = _keyStr.indexOf(input.charAt(i++));
					enc4 = _keyStr.indexOf(input.charAt(i++));

					chr1 = (enc1 << 2) | (enc2 >> 4);
					chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
					chr3 = ((enc3 & 3) << 6) | enc4;

					output.push(String.fromCharCode(chr1));

					if (enc3 != 64) {
						output.push(String.fromCharCode(chr2));
					}
					if (enc4 != 64) {
						output.push(String.fromCharCode(chr3));
					}
				}

				output = output.join('');
				return output;
			}
		};

		return singleton;

	})();

	/**
	 * a collection of utility Function
	 * @final
	 * @memberOf me
	 * @private
	 * @constructor Should not be called by the user.
	 */

	me.utils = (function() {
		// hold public stuff in our singletong
		var api = {};

		/*---------------------------------------------

		   PRIVATE STUFF

		 ---------------------------------------------*/

		// cache rgb converted value
		var rgbCache = {};

		// guid default value
		var GUID_base  = "";
		var GUID_index = 0;

		/*---------------------------------------------

			PUBLIC STUFF

			---------------------------------------------*/

		/**
		 * Decode a base64 encoded string into a binary string
		 *
		 * @param {String} input Base64 encoded data
		 * @return {String} Binary string
		 */
		api.decodeBase64 = function(input) {
			return Base64.decode(input);
		};

		/**
		 * Decode a base64 encoded string into a byte array
		 *
		 * @param {String} input Base64 encoded data
		 * @param {Int} [bytes] number of bytes per array entry
		 * @return {Int[]} Array of bytes
		 */
		api.decodeBase64AsArray = function(input, bytes) {
			bytes = bytes || 1;

			var dec = Base64.decode(input), ar = [], i, j, len;

			for (i = 0, len = dec.length / bytes; i < len; i++) {
				ar[i] = 0;
				for (j = bytes - 1; j >= 0; --j) {
					ar[i] += dec.charCodeAt((i * bytes) + j) << (j << 3);
				}
			}
			return ar;
		};

		/**
		 * Decode a CSV encoded array into a binary array
		 *
		 * @param  {String} input CSV formatted data
		 * @param  {Int} limit row split limit
		 * @return {Int[]} Int Array
		 */
		api.decodeCSV = function(input, limit) {
			input = input.trim().split("\n");

			var result = [];
			for ( var i = 0; i < input.length; i++) {
				entries = input[i].split(",", limit);
				for ( var e = 0; e < entries.length; e++) {
					result.push(+entries[e]);
				}
			}
			return result;
		};

		/* ---

			enable the nocache mechanism

		  ---*/
		api.setNocache = function(enable) {
			me.nocache = enable ? "?" + parseInt(Math.random() * 10000000) : '';
		};

		// a Hex to RGB color function
		api.HexToRGB = function(h, a) {
			// remove the # if present
			h = (h.charAt(0) == "#") ? h.substring(1, 7) : h;
			// check if we already have the converted value cached
			if (rgbCache[h] == null) {
				// else add it (format : "r,g,b")
				rgbCache[h] = parseInt(h.substring(0, 2), 16) + ","
						+ parseInt(h.substring(2, 4), 16) + ","
						+ parseInt(h.substring(4, 6), 16);
			}
			return (a ? "rgba(" : "rgb(") + rgbCache[h]
					+ (a ? "," + a + ")" : ")");
		};

		// a Hex to RGB color function
		api.RGBToHex = function(r, g, b) {
			return r.toHex() + g.toHex() + b.toHex();
		};

		// return the given canvas or image pixels
		api.getPixels = function(arg) {
			if (arg instanceof HTMLImageElement) {
				var c = me.video.createCanvasSurface(arg.width, arg.height);
				c.drawImage(arg, 0, 0);
				return c.getImageData(0, 0, arg.width, arg.height);
			} else {
				// canvas !
				return arg.getContext('2d').getImageData(0, 0, arg.width, arg.height);
			}
		};

		// reset the GUID Base Name
		// the idea here being to have a unique ID
		// per level / object
		api.resetGUID = function(base) {
			// also ensure it's only 8bit ASCII characters
			GUID_base  = base.toUpperCase().toHex();
			GUID_index = 0;
		};

		// create and return a very simple GUID
		// Game Unique ID
		api.createGUID = function() {
			return GUID_base + "-" + (GUID_index++);
		};

		// apply friction to a force
		api.applyFriction = function(v, f) {
			return (v+f<0)?v+(f*me.timer.tick):(v-f>0)?v-(f*me.timer.tick):0;
		};

		// return our object
		return api;

	})();

	/*---------------------------------------------------------*/
	// END END END
	/*---------------------------------------------------------*/
})(window);
<commit_msg>typo correction<commit_after>/*
 * MelonJS Game Engine
 * Copyright (C) 2011, Olivier BIOT
 * http://www.melonjs.org
 *
 *
 */

(function($, undefined) {

	/**
	 *  Base64 decoding
	 *  @see http://www.webtoolkit.info/
	 */
	var Base64 = (function() {

		// hold public stuff in our singleton
		var singleton = {};

		// private property
		var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

		// public method for decoding
		singleton.decode = function(input) {

			// make sure our input string has the right format
			input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

			if (me.sys.nativeBase64) {
				// use native decoder
				return $.atob(input);
			}
			else {
				// use cross-browser decoding
				var output = [], chr1, chr2, chr3, enc1, enc2, enc3, enc4, i = 0;

				while (i < input.length) {
					enc1 = _keyStr.indexOf(input.charAt(i++));
					enc2 = _keyStr.indexOf(input.charAt(i++));
					enc3 = _keyStr.indexOf(input.charAt(i++));
					enc4 = _keyStr.indexOf(input.charAt(i++));

					chr1 = (enc1 << 2) | (enc2 >> 4);
					chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
					chr3 = ((enc3 & 3) << 6) | enc4;

					output.push(String.fromCharCode(chr1));

					if (enc3 != 64) {
						output.push(String.fromCharCode(chr2));
					}
					if (enc4 != 64) {
						output.push(String.fromCharCode(chr3));
					}
				}

				output = output.join('');
				return output;
			}
		};

		return singleton;

	})();

	/**
	 * a collection of utility Function
	 * @final
	 * @memberOf me
	 * @private
	 * @constructor Should not be called by the user.
	 */

	me.utils = (function() {
		// hold public stuff in our singletong
		var api = {};

		/*---------------------------------------------

		   PRIVATE STUFF

		 ---------------------------------------------*/

		// cache rgb converted value
		var rgbCache = {};

		// guid default value
		var GUID_base  = "";
		var GUID_index = 0;

		/*---------------------------------------------

			PUBLIC STUFF

			---------------------------------------------*/

		/**
		 * Decode a base64 encoded string into a binary string
		 *
		 * @param {String} input Base64 encoded data
		 * @return {String} Binary string
		 */
		api.decodeBase64 = function(input) {
			return Base64.decode(input);
		};

		/**
		 * Decode a base64 encoded string into a byte array
		 *
		 * @param {String} input Base64 encoded data
		 * @param {Int} [bytes] number of bytes per array entry
		 * @return {Int[]} Array of bytes
		 */
		api.decodeBase64AsArray = function(input, bytes) {
			bytes = bytes || 1;

			var dec = Base64.decode(input), ar = [], i, j, len;

			for (i = 0, len = dec.length / bytes; i < len; i++) {
				ar[i] = 0;
				for (j = bytes - 1; j >= 0; --j) {
					ar[i] += dec.charCodeAt((i * bytes) + j) << (j << 3);
				}
			}
			return ar;
		};

		/**
		 * Decode a CSV encoded array into a binary array
		 *
		 * @param  {String} input CSV formatted data
		 * @param  {Int} limit row split limit
		 * @return {Int[]} Int Array
		 */
		api.decodeCSV = function(input, limit) {
			input = input.trim().split("\n");

			var result = [];
			for ( var i = 0; i < input.length; i++) {
				entries = input[i].split(",", limit);
				for ( var e = 0; e < entries.length; e++) {
					result.push(+entries[e]);
				}
			}
			return result;
		};

		/* ---

			enable the nocache mechanism

		  ---*/
		api.setNocache = function(enable) {
			me.nocache = enable ? "?" + parseInt(Math.random() * 10000000) : '';
		};

		// a Hex to RGB color function
		api.HexToRGB = function(h, a) {
			// remove the # if present
			h = (h.charAt(0) == "#") ? h.substring(1, 7) : h;
			// check if we already have the converted value cached
			if (rgbCache[h] == null) {
				// else add it (format : "r,g,b")
				rgbCache[h] = parseInt(h.substring(0, 2), 16) + ","
						+ parseInt(h.substring(2, 4), 16) + ","
						+ parseInt(h.substring(4, 6), 16);
			}
			return (a ? "rgba(" : "rgb(") + rgbCache[h]
					+ (a ? "," + a + ")" : ")");
		};

		// a Hex to RGB color function
		api.RGBToHex = function(r, g, b) {
			return r.toHex() + g.toHex() + b.toHex();
		};

		// return the given canvas or image pixels
		api.getPixels = function(arg) {
			if (arg instanceof HTMLImageElement) {
				var c = me.video.createCanvasSurface(arg.width, arg.height);
				c.drawImage(arg, 0, 0);
				return c.getImageData(0, 0, arg.width, arg.height);
			} else {
				// canvas !
				return arg.getContext('2d').getImageData(0, 0, arg.width, arg.height);
			}
		};

		// reset the GUID Base Name
		// the idea here being to have a unique ID
		// per level / object
		api.resetGUID = function(base) {
			// also ensure it's only 8bit ASCII characters
			GUID_base  = base.toUpperCase().toHex();
			GUID_index = 0;
		};

		// create and return a very simple GUID
		// Game Unique ID
		api.createGUID = function() {
			return GUID_base + "-" + (GUID_index++);
		};

		// apply friction to a force
		api.applyFriction = function(v, f) {
			return (v+f<0)?v+(f*me.timer.tick):(v-f>0)?v-(f*me.timer.tick):0;
		};

		// return our object
		return api;

	})();

	/*---------------------------------------------------------*/
	// END END END
	/*---------------------------------------------------------*/
})(window);
<|endoftext|>


<commit_before><commit_msg>Fixing situation where custom conditionals would reset the evaluations.<commit_after><|endoftext|>