Example #1
0
 var stringify = _.map(obj, function (value, key) {
   // _event key is only used when a string is passed on client's push method
   if(key==='_event') return _.str.capitalize(value)+'';
   if(typeof value === 'object') {
     value = JSON.stringify(obj, undefined, 4);
   }
   return _.str.capitalize(key)+': '+value;
 });
Example #2
0
	this.update = function(options, newValues, cb) {
		if(_.isFunction(options)) {
			cb = options;
			options = null;
		}
		var usage = _.str.capitalize(this.identity) + '.update(criteria, newValues, callback)';
		if(!newValues) return usageError('No updated values specified!', usage, cb);
		if(!_.isFunction(cb)) return usageError('Invalid callback specified!', usage, cb);

		// TODO: Validate constraints using Anchor

		// Automatically change updatedAt (if enabled)
		if (this.autoUpdatedAt) newValues.updatedAt = new Date();

		// If no callback specified, return deferred object
		if(!_.isFunction(cb)) {
			return new Deferred({
				method: 'update',
				collection: this,
				args: {
					options: options,
					newValues: newValues
				},
				argsKeys: ['options', 'newValues']
			});
		} 
		// Build model(s) from result set
		else return adapter.update(this.identity, options, newValues, buildModel(this, cb));
	};
Example #3
0
	this.createEach = function(valuesList, cb) {

		var usage = _.str.capitalize(this.identity) + '.createEach(valuesList, callback)';
		if(!valuesList) return usageError('No valuesList specified!', usage, cb);
		if(!_.isArray(valuesList)) return usageError('Invalid valuesList specified (should be an array!)', usage, cb);
		if(!_.isFunction(cb)) return usageError('Invalid callback specified!', usage, cb);
		if (!_.all(valuesList, function (values) {
			return _.isObject(values) && !_.isArray(values);
		})) return usageError('Invalid valuesList specified (should be an array of valid values objects!)', usage, cb);

		var self = this;
		_.each(valuesList, function (values) {
			// TODO: Populate default values
			// (just use describe(), but first we need an in-memory cache for calls to describe())

			// TODO: Validate constraints using Anchor

			// Automatically add updatedAt and createdAt (if enabled)
			if (self.autoCreatedAt) values.createdAt = new Date();
			if (self.autoUpdatedAt) values.updatedAt = new Date();
		});

		// Build model(s) from result set
		adapter.createEach(this.identity, valuesList, buildModel(this, cb));
	};
Example #4
0
	this.count = function(criteria, options, cb) {
		var usage = _.str.capitalize(this.identity) + '.count([criteria],[options],callback)';
		if(_.isFunction(criteria)) {
			cb = criteria;
			criteria = null;
			options = null;
		} else if(_.isFunction(options)) {
			cb = options;
			options = null;
		}

		// Normalize criteria and fold in options
		criteria = normalize.criteria(criteria);
		if(_.isObject(options) && _.isObject(criteria)) {
			criteria = _.extend({}, criteria, options);
		}

		if(_.isFunction(criteria) || _.isFunction(options)) {
			return usageError('Invalid options specified!', usage, cb);
		}

		// If no callback specified, return deferred object
		if(!_.isFunction(cb)) {
			return new Deferred({
				method: 'count',
				collection: this,
				args: {
					criteria: criteria
				},
				argsKeys: ['criteria']
			});
		} 
		// Build model(s) from result set
		else return adapter.count(this.identity, criteria, cb);
	};
Example #5
0
	this.findAllLike = function(criteria, options, cb) {
		var usage = _.str.capitalize(this.identity) + '.findAllLike([criteria],[options],callback)';

		if(criteria = normalize.likeCriteria(criteria, attributes)) {
			return this.findAll(criteria, options, cb);
		} else return usageError('Criteria must be string or object!', usage, cb);
	};
Example #6
0
exports.get = function(req, res) {
    var entity = _.str.capitalize(req.params.entity);
    var id = Number(req.params.id);

    if (!id) {
        res.json(500, {
            success: false,
            error: 'wrong ID parameter'
        });
        return;
    }

    findModelRouter(entity).then(function(router) {
        try {
            if (router.get) {
                router.get(req, res, id);
            } else {
                throw 'action not supported: get';
            }
        } catch (e) {
            res.json(500, {
                success: false,
                error: e
            });
        }

    }, function(err) {
        res.json(500, {
            success: false,
            error: 'Unknown entity: ' + entity
        });
    });

};
Example #7
0
function ijodRequest(endpoint, basePath, range, cbEach, cbDone) {
  var ijodFn = 'get' + _.str.capitalize(endpoint);

  var pid = idr.pid(basePath);
  // If there is no pid, the IDR likely reference internal or app data
  if (!_.str.include(pid, '@')) {
    return getIJODFromNexus(ijodFn, basePath, range, cbEach, cbDone);
  }

  profileManager.loadProfile(pid, function(err, profile) {
    if (err) return cbDone(err);

    // If the profile doesn't exist, the pid is likely a user@app entry
    if (!profile) {
      return getIJODFromNexus(ijodFn, basePath, range, cbEach, cbDone);
    }

    if (!profile.pod) {
      if (cbEach) return ijod[ijodFn](basePath, range, cbEach, cbDone);
      else return ijod[ijodFn](basePath, range, cbDone);
    }

    podRequest(podUrl(profile.pod, '/' + endpoint), {
      qs: {
        basePath: basePath,
        range: JSON.stringify(range)
      }
    }, function(err, response, body) {
      if (err) return cbDone(err);
      if (body.error) return cbDone(new Error(body.error));
      if (cbEach && body.data) body.data.forEach(cbEach);
      return cbDone(null, body.result);
    });
  });
}
Example #8
0
	this.destroy = function(options, cb) {
		if(_.isFunction(options)) {
			cb = options;
			options = null;
		}
		var usage = _.str.capitalize(this.identity) + '.destroy([options], callback)';


		// Build enhanced callback fn for deferred/promise usage
		cb = buildModel(this, cb);

		// If no callback specified, return deferred object
		if(!_.isFunction(cb)) {
			return new Deferred({
				method: 'destroy',
				collection: this,
				args: {
					options: options
				},
				argsKeys: ['options']
			});
		} 

		// Build model(s) from result set
		else return adapter.destroy(this.identity, options, buildModel(this, cb));
	};
Example #9
0
	this.transaction = function(transactionName, atomicLogic, afterUnlock) {
		var usage = _.str.capitalize(this.identity) + '.transaction(transactionName, atomicLogicFunction, afterUnlockFunction)';
		if(!atomicLogic) {
			return usageError('Missing required parameter: atomicLogicFunction!', usage, cb);
		} else if(!_.isFunction(atomicLogic)) {
			return usageError('Invalid atomicLogicFunction!  Not a function: ' + atomicLogic, usage, cb);
		} else if(afterUnlock && !_.isFunction(afterUnlock)) {
			return usageError('Invalid afterUnlockFunction!  Not a function: ' + afterUnlock, usage, cb);
		} else return adapter.transaction(this.identity + '.' + transactionName, atomicLogic, afterUnlock);
	};
Example #10
0
	this.endsWith = function (criteria, options, cb) {
		var usage = _.str.capitalize(this.identity) + '.startsWith([criteria],[options],callback)';

		if (criteria = normalize.likeCriteria(criteria, attributes, function applyEndsWith(criteria) {
			return '%' + criteria;
		})) {
			return this.findAll(criteria, options, cb);
		} else return usageError('Criteria must be a string or object!', usage, cb);
		throw new notImplementedError();
	};
Example #11
0
	this.sort = function (sort, cb) {
		var usage = _.str.capitalize(this.identity) + '.sort(sort, [callback])';
		if (this.terminated) usageError('Chain is already terminated!');
		
		applyQueryOption('sort',sort);

		// Either call done() or return the deferred object
		if(_.isFunction(cb)) return this.done(cb);
		else return this;
	};
ActionContainer.prototype._getHandler = function () {
  var handlerString = this.conflictHandler;
  var handlerFuncName = "_handleConflict" + _.str.capitalize(handlerString);
  var func = this[handlerFuncName];
  if (typeof func === 'undefined') {
    var msg = "invalid conflict resolution value: " + handlerString;
    throw new Error(msg);
  } else {
    return func;
  }
};
Example #13
0
	this.create = function(values, cb) {
		if (!this.attributes) {
			return cb(new Error("Cannot call default create() behavior without defining attributes in model definition."));
		}
		if(_.isFunction(values)) {
			cb = values;
			values = null;
		}
		else if (_.isArray(values)) {
			return this.createEach(values,cb);
		}

		var usage = _.str.capitalize(this.identity) + '.create({someAttr: "someValue"},callback)';

		// Always cast values to empty object
		if (!values) values = {};

		// And clone the object to prevent inadvertently changing user data
		else values = _.clone(values);

		// Populate default values
		_.each(this.attributes, function (scheme, attrName) {
			// Ignore if value is set
			if(values[attrName]) return;

			// Set default value if available
			if (_.isObject(scheme) && typeof scheme.defaultsTo !== 'undefined') {
				values[attrName] = scheme.defaultsTo;
			}
		});

		// TODO: Validate constraints using Anchor

		// Automatically add updatedAt and createdAt (if enabled)
		if (this.autoCreatedAt) values.createdAt = new Date();
		if (this.autoUpdatedAt) values.updatedAt = new Date();

		// If no callback specified, return deferred object
		if(!_.isFunction(cb)) {
			return new Deferred({
				method: 'create',
				collection: this,
				args: {
					values: values
				},
				argsKeys: ['values']
			});
		} 

		// Build model(s) from result set
		else return adapter.create(this.identity, values, buildModel(this, cb));
	};
Example #14
0
function ijodRequest(endpoint, basePath, range, cbEach, cbDone) {
  var ijodFn = 'get' + _.str.capitalize(endpoint);

  var pid = idr.pid(basePath);
  // If there is no pid, the IDR likely reference internal or app data
  if (!_.str.include(pid, '@')) {
    return getIJODFromNexus(ijodFn, basePath, range, cbEach, cbDone);
  }

  var start = Date.now();
  profileManager.loadProfile(pid, function(err, profile) {
    if (err) return cbDone(err);

    // If the profile doesn't exist, the pid is likely a user@app entry
    if (!profile) {
      return getIJODFromNexus(ijodFn, basePath, range, cbEach, cbDone);
    }

    if (!profile.pod && range.app && lconfig.pods.apps && lconfig.pods.apps[range.app])
    {
      profile.pod = lconfig.pods.apps[range.app];
      logger.debug("setting pod for app", profile.pod, pid, range.app);
    }

    if (!profile.pod && range.pod) profile.pod = range.pod;

    if (!profile.pod) {
      if (cbEach) return ijod[ijodFn](basePath, range, cbEach, cbDone);
      else return ijod[ijodFn](basePath, range, cbDone);
    }

    var pstart = Date.now();
    podRequest(podUrl(profile.pod, '/' + endpoint), {
      qs: {
        basePath: basePath,
        range: JSON.stringify(range)
      }
    }, function(err, response, body) {
      if(Date.now() - start > 5000) logger.warn("slow pod request",Date.now() - start, pstart - start, profile.pod, endpoint, basePath, range.app);
      if (err) return cbDone(err);
      if (body.error) return cbDone(new Error(body.error));
      if (cbEach && body.data) body.data.forEach(cbEach);
      return cbDone(null, body.result);
    });
  });
}
Example #15
0
	this.findOrCreateEach = function(attributesToCheck, valuesList, cb) {
		if(_.isFunction(valuesList)) {
			cb = valuesList;
			valuesList = null;
		}
		var usage = _.str.capitalize(this.identity) + '.findOrCreateEach(attributesToCheck, valuesList, callback)';
		if(!_.isFunction(cb)) return usageError('Invalid callback specified!', usage, cb);
		if(!attributesToCheck) return usageError('No attributesToCheck specified!', usage, cb);
		if(!_.isArray(attributesToCheck)) return usageError('No attributesToCheck specified!', usage, cb);
		if(!valuesList) return usageError('No valuesList specified!', usage, cb);
		if(!_.isArray(valuesList)) return usageError('Invalid valuesList specified (should be an array!)', usage, cb);
		if (!_.all(valuesList, function (values) {
			return _.isObject(values) && !_.isArray(values);
		})) return usageError('Invalid valuesList specified (should be an array of valid values objects!)', usage, cb);

		// Build model(s) from result set
		adapter.findOrCreateEach(this.identity, attributesToCheck, valuesList, buildModel(this, cb));
	};
Example #16
0
	this.count = function(criteria, options, cb) {
		var usage = _.str.capitalize(this.identity) + '.count([criteria],[options],callback)';
		if(_.isFunction(criteria)) {
			cb = criteria;
			criteria = null;
			options = null;
		} else if(_.isFunction(options)) {
			cb = options;
			options = null;
		} else if(_.isObject(options)) {
			criteria = _.extend({}, criteria, options);
		} else return usageError('Invalid options specified!', usage, cb);

		if(!_.isFunction(cb)) return usageError('Invalid callback specified!', usage, cb);

		// Build model(s) from result set
		return adapter.count(this.identity, criteria, buildModel(this, cb));
	};
Example #17
0
	this.findOrCreate = function(criteria, values, cb) {
		if(_.isFunction(values)) {
			cb = values;
			values = null;
		}

		// This is actually an implicit call to findOrCreateEach
		if (_.isArray(criteria) && _.isArray(values)) {
			return this.findOrCreateEach(criteria, values, cb);
		}

		var usage = _.str.capitalize(this.identity) + '.findOrCreate([criteria], values, callback)';
		if(!criteria) return usageError('No criteria option specified!', usage, cb);
		if(!_.isFunction(cb)) return usageError('Invalid callback specified!', usage, cb);

		// Build model(s) from result set
		return adapter.findOrCreate(this.identity, criteria, values, buildModel(this, cb));
	};
Example #18
0
	this.done = function (cb) {

		// A callback is always required here, and done() can't be called more than once
		var usage = _.str.capitalize(this.identity) + '.done(callback)';
		if(!_.isFunction(cb)) usageError('Invalid callback specified!',usage);
		if (this.terminated) usageError('Chain is already terminated!');
		this.terminated = true;

		// Iterate through each operation in the call chain
		// If an error is detected, stop
		if (_.isArray(this.callChain) && this.callChain.length > 0) {

			// Used if a resultSet must be returned
			var resultSet;

			// Go through list again and actually perform logic
			async.forEachSeries(this.callChain, function (promise, cb) {
				var methodName = promise.method;
				var method = promise.collection && promise.collection[methodName];
				if (!method) cb(new Error(promise.method+' doesn\'t exist in '+promise.collection.identity));

				// Always tack on callback
				var args = [promiseCallback];

				// Push criteria on argument list
				_.each(promise.argsKeys, function (argName) {
					args.unshift(promise.args[argName]);
				});

				// Execute promise
				method.apply(promise.collection, args);
				function promiseCallback (err,data) {
					if (err) return cb(err);
					resultSet = data;
					return cb(err,data);
				}
			}, 
			// Return result set to caller
			function (err) {
				return cb(err, resultSet);
			});
		}
		else throw new Error ('Trying to resolve a deferred object, but the call chain is invalid!');
	};
Example #19
0
	this.join = function (collection, fk, pk, cb) {
		var usage = _.str.capitalize(this.identity) + '.join(collection, [foreignKey], [callback])';
		if (this.terminated) usageError('Chain is already terminated!');
		if (!collection) usageError('No collection specified!');
		if (_.isFunction (fk)) cb = fk;

		this.callChain.push({
			method: 'join',
			collection: this,
			args: { 
				collection: collection,
				fk: fk,
				pk: pk
			}
		});

		if (_.isFunction(cb)) return this.done(cb);
		else return this;
	};
Example #20
0
	this.stream = function (criteria, transformation) {
		var self = this;
		var usage = _.str.capitalize(this.identity) + '.stream([criteria],[options])';

		// Normalize criteria and fold in options
		criteria = normalize.criteria(criteria);

		// Configure stream to adapter, kick off fetch, and return stream object
		// so that user code can use it as it fires data events
		var stream = new ModelStream(transformation);

		// very important to wait until next tick before triggering adapter
		// otherwise write() and end() won't fire properly
		process.nextTick(function (){
			// Write once immediately to force prefix in case no models are returned
			stream.write();

			adapter.stream(self.identity, criteria, stream);
		});

		return stream;
	};
Example #21
0
exports.list = function(req, res) {
    var entity = _.str.capitalize(req.params.entity);

    findModelRouter(entity).then(function(router) {
        try {
            if (router.list) {
                router.list(req, res);
            } else {
                throw 'action not supported: list';
            }
        } catch (e) {
            res.json(500, {
                success: false,
                error: e
            });
        }
    }, function(err) {
        res.json(500, {
            success: false,
            error: 'Unknown entity: ' + entity
        });
    });
};
Example #22
0
	this.find = function(criteria, cb) {
		var usage = _.str.capitalize(this.identity) + '.find([criteria],callback)';

		if(_.isFunction(criteria)) {
			cb = criteria;
			criteria = null;
		}

		// If no callback specified, return deferred object
		if(!_.isFunction(cb)) {
			return new Deferred({
				method: 'find',
				collection: this,
				args: {
					criteria: criteria
				},
				argsKeys: ['criteria']
			});
		} 

		// Build model(s) from result set 
		else return adapter.find(this.identity, criteria, buildModel(this, cb));
	};
Example #23
0
	this.create = function(values, cb) {
		if(_.isFunction(values)) {
			cb = values;
			values = null;
		}
		else if (_.isArray(values)) {
			return this.createEach(values,cb);
		}
		var usage = _.str.capitalize(this.identity) + '.create({someAttr: "someValue"},callback)';

		// TODO: Populate default values
		// (just use describe(), but first we need an in-memory cache for calls to describe())

		// TODO: Validate constraints using Anchor

		// Always cast values to empty object
		if (!values) values = {};

		// Automatically add updatedAt and createdAt (if enabled)
		if (this.autoCreatedAt) values.createdAt = new Date();
		if (this.autoUpdatedAt) values.updatedAt = new Date();

		// If no callback specified, return deferred object
		if(!_.isFunction(cb)) {
			return new Deferred({
				method: 'create',
				collection: this,
				args: {
					values: values
				},
				argsKeys: ['values']
			});
		} 

		// Build model(s) from result set
		else return adapter.create(this.identity, values, buildModel(this, cb));
	};
Example #24
0
router.get('/:folder', function(req, res) {
  images = getImages("./public/img/portfolio/" + req.params.folder)
  res.render('portfolio/folder', { folder: req.params.folder, title: 'Folder: ' + _.str.capitalize(req.params.folder) });
});
Example #25
0
function capitalize(str) {
	return _.str.capitalize(str);
}
Example #26
0
module.exports = function enhanceRequest(req, res, controllerName, actionName) {

	// Provide error messages for req.listen and res.broadcast if they don't exist
	req.listen = req.listen || notSupported("req.listen()");
	res.broadcast = res.broadcast || notSupported("res.broadcast()");

	// Always share some data with views
	res.locals({
		userAgent: req.headers['user-agent'],
		session: req.session,
		title: sails.config.appName + " | " + _.str.capitalize(actionName),
		controller: controllerName,
		action: actionName,
		req: req,
		res: res
	});

	// Add req.protocol
	req.protocol = req.protocol ? req.protocol : req.header('X-Forwarded-Protocol') == "https" ? "https" : "http";

	// Add req.host
	// (remove port if it exists)
	req.host = req.host || req.header('host');
	req.rawHost = req.host.split(':')[0];

	// Add req.port
	req.port = req.port ? req.port : sails.express.app.address().port;

	// Add req.rootUrl convenience method
	req.rootUrl = req.protocol + '://' + req.rawHost + (req.port == 80 || req.port == 443 ? '' : ':' + req.port);


	// Set action and controller as request parameters for use in controllers and views
	req.params = req.params || {};
	req.params.controller = req.params.entity = controllerName;
	req.params.action = actionName;

	// Add *verb* attribute to request object
	req.verb = req.method;

	// Add flags to request object
	req.isAjax = req.xhr;
	req.isJson = req.header('content-type') === 'application/json';
	req.acceptJson = req.header('Accept') === 'application/json';
	req.isJsony = req.isJson || req.acceptJson;

	// Add res.view() method to response object
	// res.view() is an enhanced version of  Express's res.render()
	// which automatically renders the appropriate view based on the entity and action
	// Note: the original function is still accessible via res.render()
	res.view = function(specifiedPath, data, fun) {
		data = data || {};

		// By default, generate a path to the view using what we know about the controller+action
		var path = req.param('entity') + "/" + req.param('action');

		// If the path to a view was explicitly specified, use that
		if(_.isString(specifiedPath)) {
			path = specifiedPath;
		}
		// If a map of data is provided as the first argument, use it (and just use the default path)
		else if(_.isObject(specifiedPath)) {
			data = specifiedPath;
		}

		// TODO: work with the appropriate Adapters to fulfill promise objects in *data*

		res.render(path, data, fun);
	};

	// Respond with a message indicating that the feature is not currently supported
	function notSupported(method) {
		return function() {
			sails.log.warn(method + " is only supported using Socket.io!");
		};
	}
};
Example #27
0
function createJetsonUser() {
	var areaCode = 100 + Math.floor(Math.random() * 899);

	var numEmails  = 1 + Faker.random.number(3);
	var numPhone   = 1 + Faker.random.number(2);
	var numAddress = 1 + Faker.random.number(2);
	var numGroups  = Faker.random.number(3);

	// console.log("numEmails is:'%s'", numEmails);
	var i = 0;

	var user = {
		uid: "User:"******"%s.%s", Faker.Lorem.words(1), Faker.random.array_element(domain_suffix));

		if (i === 0)  {
			email.value = fmt("%s%s@%s", user.name.givenName.substring(0,1), user.name.familyName, domain).toLowerCase();
			email.primary = true;
			email.type    = "Work";
		}

		if (i > 0) {
			email.value = fmt("%s.%s@%s", Faker.Lorem.words(1), Faker.Lorem.words(1), domain);
			email.type = Faker.random.array_element(email_types);

			// check that the type is not already in use, and retry until we find an unused one
			while (types_used[email.type]) {
				email.type = Faker.random.array_element(email_types);
			}
		}

		types_used[email.type] = 1;

		user.emails.push(email);
	}

	types_used = {};
	for (i = 0; i < numPhone; i++) {
		var phone = {
			value: areaCode + Faker.Helpers.replaceSymbolWithNumber("-###-####")
			,type: Faker.random.array_element(phone_types)
		};

		// check that the type is not already in use, and retry until we find an unused one
		while (types_used[phone.type]) {
			phone.type = Faker.random.array_element(phone_types);
		}

		types_used[phone.type] = 1;
		user.phoneNumbers.push(phone);
	}

	types_used = {};
	for (i = 0; i < numAddress; i++) {
		var address = {
			type: Faker.random.array_element(address_types)
			,streetAddress: Faker.Address.streetAddress()
			,locality: Faker.Address.city()
			,region: Faker.Address.usState()
			,postalCode: Faker.Address.zipCode()
			,country: "United States"
		};

		if (i === 0)  {
			address.primary = true;
		}

		// check that the type is not already in use, and retry until we find an unused one
		while(types_used[address.type]) {
			address.type = Faker.random.array_element(address_types);
		}

		types_used[address.type] = 1;

		user.addresses.push(address);
	}

	user.organizations[0] = {
		name:	_.str.capitalize(Faker.Lorem.words(1)) + ", Inc."
		,title: Faker.random.array_element(work_title)
	};

	for (i=0; i < numGroups; i++) {
		var group = Faker.random.array_element(groups);
		// console.log('proposed group', group)
		while( user.groups.length < 2 && _.contains(user.groups, group)) {
			// console.log('group exists, retrying', group);
			group = Faker.random.array_element(groups);
		}
		// console.log('adding to group', group);
		user.groups.push(group);
	}


	return user;
}
Example #28
0
		this[actualMethodName] = function dynamicMethod(value, options, cb) {
			if(_.isFunction(options)) {
				cb = options;
				options = null;
			}
			options = options || {};


			var usage = _.str.capitalize(this.identity) + '.' + actualMethodName + '(someValue,[options],callback)';
			if(_.isUndefined(value)) return usageError('No value specified!', usage, cb);
			if(options.where) return usageError('Cannot specify `where` option in a dynamic ' + method + '*() query!', usage, cb);


			// Build criteria query and submit it
			options.where = {};
			options.where[attrName] = value;

			// Make modifications based on method as necessary
			if(method === 'findBy*' || method === 'findBy*In') {
				return self.find(options, cb);
			} else if(method === 'findBy*Like') {
				return self.find(_.extend(options, {
					where: {
						like: options.where
					}
				}), cb);
			}

			// Aggregate finders
			else if(method === 'findAllBy*' || method === 'findAllBy*In') {
				return self.findAll(options, cb);
			} else if(method === 'findAllBy*Like') {
				return self.findAll(_.extend(options, {
					where: {
						like: options.where
					}
				}), cb);
			}

			// Count finders
			else if(method === 'countBy*' || method === 'countBy*In') {
				return self.count(options, cb);
			} else if(method === 'countBy*Like') {
				return self.count(_.extend(options, {
					where: {
						like: options.where
					}
				}), cb);
			}

			// Searchers
			else if (method === '*StartsWith') {
				return self.startsWith(options, cb);
			}
			else if (method === '*Contains') {
				return self.contains(options, cb);
			}
			else if (method === '*EndsWith') {
				return self.endsWith(options, cb);
			}
		};
Example #29
0
	this.generateDynamicFinder = function(attrName, method, dontCapitalize) {

		// Capitalize attribute name if necessary to be syntactically correct
		var preparedAttrName;
		if (dontCapitalize) preparedAttrName = attrName;
		else preparedAttrName = _.str.capitalize(attrName);

		// Figure out actual dynamic method name by injecting attribute name		
		var actualMethodName = method.replace(/\*/g, preparedAttrName);

		// Assign this finder to the collection
		this[actualMethodName] = function dynamicMethod(value, options, cb) {
			if(_.isFunction(options)) {
				cb = options;
				options = null;
			}
			options = options || {};


			var usage = _.str.capitalize(this.identity) + '.' + actualMethodName + '(someValue,[options],callback)';
			if(_.isUndefined(value)) return usageError('No value specified!', usage, cb);
			if(options.where) return usageError('Cannot specify `where` option in a dynamic ' + method + '*() query!', usage, cb);


			// Build criteria query and submit it
			options.where = {};
			options.where[attrName] = value;

			// Make modifications based on method as necessary
			if(method === 'findBy*' || method === 'findBy*In') {
				return self.find(options, cb);
			} else if(method === 'findBy*Like') {
				return self.find(_.extend(options, {
					where: {
						like: options.where
					}
				}), cb);
			}

			// Aggregate finders
			else if(method === 'findAllBy*' || method === 'findAllBy*In') {
				return self.findAll(options, cb);
			} else if(method === 'findAllBy*Like') {
				return self.findAll(_.extend(options, {
					where: {
						like: options.where
					}
				}), cb);
			}

			// Count finders
			else if(method === 'countBy*' || method === 'countBy*In') {
				return self.count(options, cb);
			} else if(method === 'countBy*Like') {
				return self.count(_.extend(options, {
					where: {
						like: options.where
					}
				}), cb);
			}

			// Searchers
			else if (method === '*StartsWith') {
				return self.startsWith(options, cb);
			}
			else if (method === '*Contains') {
				return self.contains(options, cb);
			}
			else if (method === '*EndsWith') {
				return self.endsWith(options, cb);
			}
		};
	};