Source: query/insert.js

/*! insert.js */

var utils = require('../core/utils');
var ObjectId = require('../core/objectid');

/**
 * This mixin provides
 * [insert()]{@linkcode KagoDB#insert} and
 * [save()]{@linkcode KagoDB#save} methods.
 *
 * @class insert
 * @mixin
 * @example
 * var opts = {
 *   storage: 'memory',
 *   primary_key: '_id' // primary key like MongoDB does
 * };
 * var collection = new KagoDB(opts);
 *
 * var items = [
 *   { name: 'Apple' },
 *   { name: 'Orange' },
 *   { name: 'Grape' }
 * };
 *
 * collection.insert(items, function(err) {
 *   console.log(err || 'no error'); // bulk insert
 * });
 */

module.exports = function() {
  var mixin = {};
  mixin.insert = insert;
  mixin.save = save;
  return mixin;
};

/**
 * This inserts an item to the collection.
 * This requires a primary key defined.
 *
 * @method KagoDB.prototype.insert
 * @param {Object|Array} item - an item or an array of items
 * @param {Function} [callback] - function(err) {}
 * @return {KagoDB} for chaining
 * @example
 * var opts = {
 *   storage: 'memory',
 *   primary_key: '_id' // primary key like MongoDB does
 * };
 * var collection = new KagoDB(opts);
 *
 * var item = {
 *   name: 'Apple'
 * };
 *
 * collection.insert(item, function(err) {
 *   console.log(err || 'no error');
 * });
 */

function insert(item, callback) {
  var self = this;
  var items = (item instanceof Array) ? item : [item];
  var pkey = self.pkey();

  if (!pkey) {
    throw new Error('primary key not defined');
  }

  var builder = this.get('primary_key_builder') || ObjectId;
  var dup = {};
  utils.eachSeries(items, exist_iterator, write_all);
  return this;

  function exist_iterator(item, next) {
    var id = item[pkey];
    if ('undefined' === typeof id || id === null) {
      item[pkey] = builder();
      next();
    } else if (dup[id]) {
      var err = new Error('duplicated item ID: ' + id);
      next(err);
    } else {
      dup[id] = true;
      self.exist(id, function(err, exist) {
        if (!err && exist) {
          err = new Error('item already exist: ' + id);
        }
        next(err);
      });
    }
  }

  function write_all(err) {
    if (err) {
      callback(err);
    } else {
      utils.eachSeries(items, write_iterator, callback);
    }
  }

  function write_iterator(item, next) {
    var id = item[pkey];
    self.write(id, item, next);
  }
}

/**
 * This inserts or updates an item to the collection.
 * This requires a primary key defined.
 *
 * @method KagoDB.prototype.save
 * @param {Object} item - an item
 * @param {Function} [callback] - function(err) {}
 * @return {KagoDB} for chaining
 * @example
 * var opts = {
 *   storage: 'memory',
 *   primary_key: 'name'
 * };
 * var collection = new KagoDB(opts);
 *
 * var item = {
 *   name: 'Apple'
 * };
 *
 * collection.save(item, function(err) {
 *   collection.save(item, function(err) {
 *     console.log(err || 'no error');
 *   });
 * });
 */

function save(item, callback) {
  var self = this;
  var pkey = self.pkey();

  if (!pkey) {
    throw new Error('primary key not defined');
  }

  var id = item[pkey];
  if (id) {
    self.write(id, item, callback);
  } else {
    self.insert(item, callback);
  }

  return this;
}

function NOP() {}