all files / lib/waterline/query/ composite.js

85.37% Statements 35/41
80.65% Branches 25/31
100% Functions 3/3
91.89% Lines 34/37
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90                                53×   53×       53× 53×         53×   53×     53× 11×       42×     39×     39×   39×       39× 39×   39×               30×   30×       30× 30× 30×            
/**
 * Composite Queries
 */
 
var async = require('async');
var _ = require('lodash');
var usageError = require('../utils/usageError');
var utils = require('../utils/helpers');
var normalize = require('../utils/normalize');
var Deferred = require('./deferred');
var hasOwnProperty = utils.object.hasOwnProperty;
 
module.exports = {
 
  /**
   * Find or Create a New Record
   *
   * @param {Object} search criteria
   * @param {Object} values to create if no record found
   * @param {Function} callback
   * @return Deferred object if no callback
   */
 
  findOrCreate: function(criteria, values, cb, metaContainer) {
    var self = this;
 
    if (typeof values === 'function') {
      cb = values;
      values = null;
    }
 
    // If no criteria is specified, bail out with a vengeance.
    var usage = utils.capitalize(this.identity) + '.findOrCreate([criteria], values, callback)';
    Iif (typeof cb == 'function' && (!criteria || criteria.length === 0)) {
      return usageError('No criteria option specified!', usage, cb);
    }
 
    // Normalize criteria
    criteria = normalize.criteria(criteria);
    // If no values were specified, use criteria
    if (!values) values = criteria.where ? criteria.where : criteria;
 
    // Return Deferred or pass to adapter
    if (typeof cb !== 'function') {
      return new Deferred(this, this.findOrCreate, criteria, values);
    }
 
    // This is actually an implicit call to findOrCreateEach
    if (Array.isArray(criteria) && Array.isArray(values)) {
      return this.findOrCreateEach(criteria, values, cb);
    }
 
    Iif (typeof cb !== 'function') return usageError('Invalid callback specified!', usage, cb);
 
    // Try a find first.
    var q = this.find(criteria);
 
    Iif(metaContainer) {
      q.meta(metaContainer);
    }
 
    q.exec(function(err, results) {
      Iif (err) return cb(err);
 
      if (results && results.length !== 0) {
 
        // Unserialize values
        results = self._transformer.unserialize(results[0]);
 
        // Return an instance of Model
        var model = new self._model(results);
        return cb(null, model);
      }
 
      // Create a new record if nothing is found.
      var q2 = self.create(values);
 
      Iif(metaContainer) {
        q2.meta(metaContainer);
      }
 
      q2.exec(function(err, result) {
        Iif (err) return cb(err);
        return cb(null, result);
      });
    });
  }
 
};