Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

cakefile

  • Loading branch information...
commit b26bcbb735eb50329d587271eb58752a9d0cb27d 1 parent 563c01e
@Radagaisus authored
View
28 Cakefile
@@ -0,0 +1,28 @@
+{spawn, exec} = require 'child_process'
+log = console.log
+
+task 'build', "Compiles to JavaScript", ->
+ run 'coffee -o dist -c lib/*.coffee'
+ run 'cp lib/*.js dist/'
+
+task 'test', "Testing using Jasmine-Node", ->
+ run 'jasmine-node test/orpheus.spec.coffee --verbose --color --forceexit --coffee'
+
+task 'docs', "Create documenations using Docco", ->
+ run 'docco lib/*.coffee'
+
+run = (args...) ->
+ for a in args
+ switch typeof a
+ when 'string' then command = a
+ when 'object'
+ if a instanceof Array then params = a
+ else options = a
+ when 'function' then callback = a
+
+ command += ' ' + params.join ' ' if params?
+ cmd = spawn '/bin/sh', ['-c', command], options
+ cmd.stdout.on 'data', (data) -> process.stdout.write data
+ cmd.stderr.on 'data', (data) -> process.stderr.write data
+ process.on 'SIGHUP', -> cmd.kill()
+ cmd.on 'exit', (code) -> callback() if callback? and code is 0
View
44 dist/commands.js
@@ -0,0 +1,44 @@
+// Generated by CoffeeScript 1.3.3
+(function() {
+
+ module.exports = {
+ str: ['hdel', 'hexists', 'hget', 'hsetnx', 'hset'],
+ num: ['hdel', 'hexists', 'hget', 'hsetnx', 'hset', 'hincrby', 'hincrbyfloat'],
+ list: ['blpop', 'brpop', 'brpoplpush', 'lindex', 'linsert', 'llen', 'lpop', 'lpush', 'lpushx', 'lrange', 'lrem', 'lset', 'ltrim', 'rpop', 'rpoplpush', 'rpush', 'rpushx'],
+ set: ['sadd', 'scard', 'sdiff', 'sdiffstore', 'sinter', 'sinterstore', 'sismember', 'smembers', 'smove', 'spop', 'srandmember', 'srem', 'sunion', 'sunionstore'],
+ zset: ['zadd', 'zcard', 'zcount', 'zincrby', 'zinterstore', 'zrange', 'zrangebyscore', 'zrank', 'zrem', 'zremreangebyrank', 'zremrangebyscore', 'zrevrange', 'zrevrangebyscore', 'zrevrank', 'zscore', 'zunionstore'],
+ hash: ['hdel', 'hexists', 'hget', 'hgetall', 'hincrby', 'hincrbyfloat', 'hkeys', 'hlen', 'hmget', 'hmset', 'hset', 'hsetnx', 'hvals'],
+ shorthands: {
+ str: 'h',
+ num: 'h',
+ list: 'l',
+ set: 's',
+ zset: 'z',
+ hash: 'h'
+ },
+ command_map: {
+ add: {
+ num: 'hincrby',
+ str: 'hset',
+ set: 'sadd',
+ zset: 'zincrby',
+ list: 'lpush'
+ },
+ set: {
+ num: 'hset',
+ str: 'hset',
+ set: 'sadd',
+ zset: 'zadd',
+ list: 'lpush'
+ },
+ "delete": {
+ num: 'hdel',
+ str: 'hdel',
+ set: 'del',
+ zset: 'del',
+ list: 'del'
+ }
+ }
+ };
+
+}).call(this);
View
259 dist/inflector.js
@@ -0,0 +1,259 @@
+/*
+Copyright (c) 2010 Ryan Schuft (ryan.schuft@gmail.com)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+/*
+ This code is based in part on the work done in Ruby to support
+ infection as part of Ruby on Rails in the ActiveSupport's Inflector
+ and Inflections classes. It was initally ported to Javascript by
+ Ryan Schuft (ryan.schuft@gmail.com) in 2007.
+
+ This code was modified and reduced by Almog Melamed. This version
+ does not infect the string prototype. The only functions available
+ are pluralize and singularize.
+
+ The code is available at http://code.google.com/p/inflection-js/
+
+ The basic usage is:
+ 1. inflector = require './inflector'
+ 2. inflector.pluralize(str) // etc
+
+ Currently implemented functions:
+
+ inflector.pluralize(str, plural) == String
+ renders a singular English language noun into its plural form
+ normal results can be overridden by passing in an alternative
+
+ inflector.singularize(str, singular) == String
+ renders a plural English language noun into its singular form
+ normal results can be overridden by passing in an alterative
+*/
+
+/*
+ This sets up some constants for later use
+*/
+InflectionJS =
+{
+ /*
+ This is a list of nouns that use the same form for both singular and plural.
+ This list should remain entirely in lower case to correctly match Strings.
+ */
+ uncountable_words: [
+ 'equipment', 'information', 'rice', 'money', 'species', 'series',
+ 'fish', 'sheep', 'moose', 'deer', 'news'
+ ],
+
+ /*
+ These rules translate from the singular form of a noun to its plural form.
+ */
+ plural_rules: [
+ [new RegExp('(m)an$', 'gi'), '$1en'],
+ [new RegExp('(pe)rson$', 'gi'), '$1ople'],
+ [new RegExp('(child)$', 'gi'), '$1ren'],
+ [new RegExp('^(ox)$', 'gi'), '$1en'],
+ [new RegExp('(ax|test)is$', 'gi'), '$1es'],
+ [new RegExp('(octop|vir)us$', 'gi'), '$1i'],
+ [new RegExp('(alias|status)$', 'gi'), '$1es'],
+ [new RegExp('(bu)s$', 'gi'), '$1ses'],
+ [new RegExp('(buffal|tomat|potat)o$', 'gi'), '$1oes'],
+ [new RegExp('([ti])um$', 'gi'), '$1a'],
+ [new RegExp('sis$', 'gi'), 'ses'],
+ [new RegExp('(?:([^f])fe|([lr])f)$', 'gi'), '$1$2ves'],
+ [new RegExp('(hive)$', 'gi'), '$1s'],
+ [new RegExp('([^aeiouy]|qu)y$', 'gi'), '$1ies'],
+ [new RegExp('(x|ch|ss|sh)$', 'gi'), '$1es'],
+ [new RegExp('(matr|vert|ind)ix|ex$', 'gi'), '$1ices'],
+ [new RegExp('([m|l])ouse$', 'gi'), '$1ice'],
+ [new RegExp('(quiz)$', 'gi'), '$1zes'],
+ [new RegExp('s$', 'gi'), 's'],
+ [new RegExp('$', 'gi'), 's']
+ ],
+
+ /*
+ These rules translate from the plural form of a noun to its singular form.
+ */
+ singular_rules: [
+ [new RegExp('(m)en$', 'gi'), '$1an'],
+ [new RegExp('(pe)ople$', 'gi'), '$1rson'],
+ [new RegExp('(child)ren$', 'gi'), '$1'],
+ [new RegExp('([ti])a$', 'gi'), '$1um'],
+ [new RegExp('((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$','gi'), '$1$2sis'],
+ [new RegExp('(hive)s$', 'gi'), '$1'],
+ [new RegExp('(tive)s$', 'gi'), '$1'],
+ [new RegExp('(curve)s$', 'gi'), '$1'],
+ [new RegExp('([lr])ves$', 'gi'), '$1f'],
+ [new RegExp('([^fo])ves$', 'gi'), '$1fe'],
+ [new RegExp('([^aeiouy]|qu)ies$', 'gi'), '$1y'],
+ [new RegExp('(s)eries$', 'gi'), '$1eries'],
+ [new RegExp('(m)ovies$', 'gi'), '$1ovie'],
+ [new RegExp('(x|ch|ss|sh)es$', 'gi'), '$1'],
+ [new RegExp('([m|l])ice$', 'gi'), '$1ouse'],
+ [new RegExp('(bus)es$', 'gi'), '$1'],
+ [new RegExp('(o)es$', 'gi'), '$1'],
+ [new RegExp('(shoe)s$', 'gi'), '$1'],
+ [new RegExp('(cris|ax|test)es$', 'gi'), '$1is'],
+ [new RegExp('(octop|vir)i$', 'gi'), '$1us'],
+ [new RegExp('(alias|status)es$', 'gi'), '$1'],
+ [new RegExp('^(ox)en', 'gi'), '$1'],
+ [new RegExp('(vert|ind)ices$', 'gi'), '$1ex'],
+ [new RegExp('(matr)ices$', 'gi'), '$1ix'],
+ [new RegExp('(quiz)zes$', 'gi'), '$1'],
+ [new RegExp('s$', 'gi'), '']
+ ],
+
+ /*
+ This is a list of words that should not be capitalized for title case
+ */
+ non_titlecased_words: [
+ 'and', 'or', 'nor', 'a', 'an', 'the', 'so', 'but', 'to', 'of', 'at',
+ 'by', 'from', 'into', 'on', 'onto', 'off', 'out', 'in', 'over',
+ 'with', 'for'
+ ],
+
+ /*
+ These are regular expressions used for converting between String formats
+ */
+ id_suffix: new RegExp('(_ids|_id)$', 'g'),
+ underbar: new RegExp('_', 'g'),
+ space_or_underbar: new RegExp('[\ _]', 'g'),
+ uppercase: new RegExp('([A-Z])', 'g'),
+ underbar_prefix: new RegExp('^_'),
+
+ /*
+ This is a helper method that applies rules based replacement to a String
+ Signature:
+ InflectionJS.apply_rules(str, rules, skip, override) == String
+ Arguments:
+ str - String - String to modify and return based on the passed rules
+ rules - Array: [RegExp, String] - Regexp to match paired with String to use for replacement
+ skip - Array: [String] - Strings to skip if they match
+ override - String (optional) - String to return as though this method succeeded (used to conform to APIs)
+ Returns:
+ String - passed String modified by passed rules
+ Examples:
+ InflectionJS.apply_rules("cows", InflectionJs.singular_rules) === 'cow'
+ */
+ apply_rules: function(str, rules, skip, override)
+ {
+ if (override)
+ {
+ str = override;
+ }
+ else
+ {
+ var ignore = (skip.indexOf(str.toLowerCase()) > -1);
+ if (!ignore)
+ {
+ for (var x = 0; x < rules.length; x++)
+ {
+ if (str.match(rules[x][0]))
+ {
+ str = str.replace(rules[x][0], rules[x][1]);
+ break;
+ }
+ }
+ }
+ }
+ return str;
+ }
+};
+
+/*
+ This lets us detect if an Array contains a given element
+ Signature:
+ Array.indexOf(item, fromIndex, compareFunc) == Integer
+ Arguments:
+ item - Object - object to locate in the Array
+ fromIndex - Integer (optional) - starts checking from this position in the Array
+ compareFunc - Function (optional) - function used to compare Array item vs passed item
+ Returns:
+ Integer - index position in the Array of the passed item
+ Examples:
+ ['hi','there'].indexOf("guys") === -1
+ ['hi','there'].indexOf("hi") === 0
+*/
+if (!Array.prototype.indexOf)
+{
+ Array.prototype.indexOf = function(item, fromIndex, compareFunc)
+ {
+ if (!fromIndex)
+ {
+ fromIndex = -1;
+ }
+ var index = -1;
+ for (var i = fromIndex; i < this.length; i++)
+ {
+ if (this[i] === item || compareFunc && compareFunc(this[i], item))
+ {
+ index = i;
+ break;
+ }
+ }
+ return index;
+ };
+}
+
+
+/*
+ This function adds plurilization support to every String object
+ Signature:
+ String.pluralize(plural) == String
+ Arguments:
+ plural - String (optional) - overrides normal output with said String
+ Returns:
+ String - singular English language nouns are returned in plural form
+ Examples:
+ "person".pluralize() == "people"
+ "octopus".pluralize() == "octopi"
+ "Hat".pluralize() == "Hats"
+ "person".pluralize("guys") == "guys"
+*/
+exports.pluralize = function(s, plural) {
+ return InflectionJS.apply_rules(
+ s,
+ InflectionJS.plural_rules,
+ InflectionJS.uncountable_words,
+ plural
+ );
+};
+
+/*
+ This function adds singularization support to every String object
+ Signature:
+ String.singularize(singular) == String
+ Arguments:
+ singular - String (optional) - overrides normal output with said String
+ Returns:
+ String - plural English language nouns are returned in singular form
+ Examples:
+ "people".singularize() == "person"
+ "octopi".singularize() == "octopus"
+ "Hats".singularize() == "Hat"
+ "guys".singularize("person") == "person"
+*/
+exports.singularize = function(s, singular) {
+ return InflectionJS.apply_rules(
+ s,
+ InflectionJS.plural_rules,
+ InflectionJS.uncountable_words,
+ singular
+ );
+};
View
499 dist/orpheus.js
@@ -0,0 +1,499 @@
+// Generated by CoffeeScript 1.3.3
+(function() {
+ var Orpheus, OrpheusAPI, async, command_map, commands, inflector, log, os, _,
+ __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
+ __hasProp = {}.hasOwnProperty,
+ __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
+ __slice = [].slice;
+
+ _ = require('underscore');
+
+ async = require('async');
+
+ os = require('os');
+
+ inflector = require('./inflector');
+
+ commands = require('./commands');
+
+ command_map = commands.command_map;
+
+ log = console.log;
+
+ Orpheus = (function() {
+
+ function Orpheus() {}
+
+ Orpheus.config = {
+ prefix: 'orpheus'
+ };
+
+ Orpheus.configure = function(o) {
+ return this.config = _.extend(this.config, o);
+ };
+
+ Orpheus.schema = {};
+
+ Orpheus.id_counter = 0;
+
+ Orpheus.unique_id = function() {
+ return this.id_counter++;
+ };
+
+ Orpheus.topics = {};
+
+ Orpheus.trigger = function(topic, o) {
+ var sub, subs, _i, _len, _results;
+ subs = this.topics[topic];
+ if (!subs) {
+ return;
+ }
+ _results = [];
+ for (_i = 0, _len = subs.length; _i < _len; _i++) {
+ sub = subs[_i];
+ _results.push(sub(o));
+ }
+ return _results;
+ };
+
+ Orpheus.on = function(topic, f) {
+ var _base;
+ (_base = this.topics)[topic] || (_base[topic] = []);
+ return this.topics[topic].push(f);
+ };
+
+ Orpheus._errors = [];
+
+ Orpheus.errors = {
+ get: function() {
+ return this._errors;
+ },
+ flush: function() {
+ return this._errors = [];
+ }
+ };
+
+ Orpheus.create = function() {
+ var OrpheusModel, model, name, q;
+ OrpheusModel = (function(_super) {
+
+ __extends(OrpheusModel, _super);
+
+ function OrpheusModel(name, q) {
+ var f, _fn, _i, _len, _ref,
+ _this = this;
+ this.name = name;
+ this.q = q;
+ this.id = __bind(this.id, this);
+
+ this.redis = Orpheus.config.client;
+ this.prefix = Orpheus.config.prefix;
+ this.pname = inflector.pluralize(this.name);
+ this.model = {};
+ this.rels = [];
+ this.rels_qualifiers = [];
+ this.validations = [];
+ this.fields = ['str', 'num', 'list', 'set', 'zset', 'hash'];
+ _ref = this.fields;
+ _fn = function(f) {
+ return _this[f] = function(field, options) {
+ if (options == null) {
+ options = {};
+ }
+ if (this.model[field]) {
+ throw new Error("Field name already taken");
+ }
+ this.model[field] = {
+ type: f,
+ options: options
+ };
+ return field;
+ };
+ };
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ f = _ref[_i];
+ _fn(f);
+ }
+ OrpheusModel.__super__.constructor.call(this);
+ }
+
+ OrpheusModel.prototype.map = function(field) {
+ if (this.model[field].type !== 'str') {
+ throw new Error("Map only works on strings");
+ }
+ return this.model[field].options.map = true;
+ };
+
+ OrpheusModel.prototype.has = function(rel) {
+ var qualifier;
+ this.rels.push(rel);
+ qualifier = rel.substr(0, 2);
+ this.rels_qualifiers.push(qualifier);
+ return this[rel] = function(id) {
+ this["" + qualifier + "_id"] = id;
+ return this;
+ };
+ };
+
+ OrpheusModel.prototype.validate = function(key, func) {
+ var _base;
+ (_base = this.validations)[key] || (_base[key] = []);
+ return this.validations[key].push(func);
+ };
+
+ OrpheusModel.prototype["private"] = function(field) {
+ return this.model[field].options["private"] = true;
+ };
+
+ OrpheusModel.prototype.id = function(id, fn) {
+ var k, new_model, pk, v, _results,
+ _this = this;
+ if (!id || _.isString(id) || _.isNumber(id)) {
+ if (fn) {
+ new_model = new OrpheusAPI(id, this);
+ return fn(null, new_model, new_model.id, false);
+ } else {
+ return new OrpheusAPI(id, this);
+ }
+ } else {
+ _results = [];
+ for (k in id) {
+ v = id[k];
+ pk = inflector.pluralize(k);
+ _results.push(this.redis.hget("" + this.prefix + ":" + this.pname + ":map:" + pk, v, function(err, model_id) {
+ var model;
+ if (err) {
+ return fn(err, false);
+ }
+ if (model_id) {
+ new_model = new OrpheusAPI(model_id, _this);
+ return fn(null, new_model, model_id, false);
+ } else {
+ model = new OrpheusAPI(null, _this);
+ model.add_map(pk, v);
+ return fn(null, model, model.id, true);
+ }
+ }));
+ }
+ return _results;
+ }
+ };
+
+ return OrpheusModel;
+
+ })(this);
+ name = this.toString().match(/function (.*)\(/)[1].toLowerCase();
+ q = name.substr(0, 2);
+ Orpheus.schema[name] = this;
+ model = new OrpheusModel(name, q);
+ return model.id;
+ };
+
+ return Orpheus;
+
+ })();
+
+ OrpheusAPI = (function() {
+
+ function OrpheusAPI(id, model) {
+ var f, key, prel, rel, value, _fn, _fn1, _fn2, _fn3, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref, _ref1, _ref2, _ref3, _ref4,
+ _this = this;
+ this.model = model;
+ _.extend(this, this.model);
+ this._commands = [];
+ this.validation_errors = [];
+ this.id = id || this.generate_id();
+ _ref = this.rels;
+ _fn = function(rel, prel) {
+ return _this[prel].get = function(arr, fn) {
+ var results;
+ if (arr == null) {
+ arr = [];
+ }
+ if (!arr.length) {
+ return fn(null, []);
+ }
+ results = [];
+ return async.until(function() {
+ return results.length === arr.length;
+ }, function(c) {
+ model = Orpheus.schema[rel].create();
+ return model(arr[results.length]).get(function(err, res) {
+ if (err) {
+ err.time = new Date();
+ err.level = 'ERROR';
+ err.type = 'Redis';
+ err.msg = 'Failed retrieving related models';
+ this._errors.push(err);
+ Orpheus.trigger('error', err);
+ } else {
+ results.push(res);
+ }
+ return c(err);
+ });
+ }, function(err) {
+ return fn(err, results);
+ });
+ };
+ };
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ rel = _ref[_i];
+ prel = inflector.pluralize(rel);
+ this[prel] = {};
+ _ref1 = commands.set;
+ _fn1 = function(prel, f) {
+ _this[prel][f] = function() {
+ var args, fn, _k;
+ args = 2 <= arguments.length ? __slice.call(arguments, 0, _k = arguments.length - 1) : (_k = 0, []), fn = arguments[_k++];
+ return _this.redis[f](["" + _this.prefix + ":" + _this.q + ":" + _this.id + ":" + prel].concat(args), fn);
+ };
+ return _this[prel][f.slice(1)] = _this[prel][f];
+ };
+ for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
+ f = _ref1[_j];
+ _fn1(prel, f);
+ }
+ _fn(rel, prel);
+ }
+ _ref2 = this.model;
+ for (key in _ref2) {
+ value = _ref2[key];
+ this[key] = {};
+ _ref3 = commands[value.type];
+ _fn2 = function(key, f) {
+ _this[key][f] = function() {
+ var args;
+ args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
+ _this._commands.push(_.flatten([f, _this.get_key(key), args]));
+ if (_this.model[key].options.map) {
+ _this.extra_commands(key, f, args);
+ }
+ return _this;
+ };
+ if (f[0] === commands.shorthands[value.type]) {
+ return _this[key][f.slice(1)] = _this[key][f];
+ }
+ };
+ for (_k = 0, _len2 = _ref3.length; _k < _len2; _k++) {
+ f = _ref3[_k];
+ _fn2(key, f);
+ }
+ }
+ this.operations = ['add', 'set', 'del'];
+ _ref4 = this.operations;
+ _fn3 = function(f) {
+ return _this[f] = function(o) {
+ var command, k, msg, type, v, valid, _len4, _m, _ref5;
+ for (k in o) {
+ v = o[k];
+ if (this.validations[k]) {
+ _ref5 = this.validations[k];
+ for (_m = 0, _len4 = _ref5.length; _m < _len4; _m++) {
+ valid = _ref5[_m];
+ msg = valid(v);
+ if (msg !== true) {
+ msg = new Error(msg.message);
+ msg.type = 'validation';
+ this.validation_errors.push(msg);
+ }
+ }
+ }
+ type = this.model[k].type;
+ command = command_map[f][type];
+ this[k][command](v);
+ }
+ return this;
+ };
+ };
+ for (_l = 0, _len3 = _ref4.length; _l < _len3; _l++) {
+ f = _ref4[_l];
+ _fn3(f);
+ }
+ }
+
+ OrpheusAPI.prototype.generate_id = function() {
+ var counter, host, pid, s, time, _i, _len, _ref;
+ time = "" + (new Date().getTime());
+ pid = process.pid;
+ host = 0;
+ _ref = os.hostname();
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ s = _ref[_i];
+ host += s.charCodeAt(0);
+ }
+ counter = Orpheus.unique_id();
+ return "" + host + pid + time + counter;
+ };
+
+ OrpheusAPI.prototype.get_key = function(key) {
+ var k, rel, type, _i, _len, _ref;
+ k = "" + this.prefix + ":" + this.q + ":" + this.id;
+ _ref = this.rels_qualifiers;
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ rel = _ref[_i];
+ if (this[rel + "_id"]) {
+ k += (":" + rel + ":") + this[rel + "_id"];
+ }
+ }
+ if (!key) {
+ return k;
+ }
+ type = this.model[key].type;
+ if (key && this.model[key].options.key) {
+ key = this.model[key].options.key();
+ }
+ if (type === 'str' || type === 'num') {
+ return [k, key];
+ } else {
+ return "" + k + ":" + key;
+ }
+ };
+
+ OrpheusAPI.prototype.add_map = function(field, key) {
+ return this._commands.push(['hset', "" + this.prefix + ":" + this.pname + ":map:" + field, key, this.id]);
+ };
+
+ OrpheusAPI.prototype.extra_commands = function(key, command, args) {
+ var pkey;
+ if (this.model[key].options.map && command === 'hset') {
+ pkey = inflector.pluralize(key);
+ return this.add_map(pkey, args[0]);
+ }
+ };
+
+ OrpheusAPI.prototype["delete"] = function(fn) {
+ var hdel_flag, key, type, value, _ref;
+ this._commands = [];
+ this.validation_errors = [];
+ hdel_flag = false;
+ _ref = this.model;
+ for (key in _ref) {
+ value = _ref[key];
+ type = value.type;
+ if (type === 'str' || type === 'num') {
+ if (!hdel_flag) {
+ hdel_flag = true;
+ this._commands.push(['del', this.get_key()]);
+ }
+ } else {
+ this._commands.push(['del', this.get_key(key)]);
+ }
+ }
+ return this.exec(fn);
+ };
+
+ OrpheusAPI.prototype.get = function(fn) {
+ return this.getall(fn, true);
+ };
+
+ OrpheusAPI.prototype.getall = function(fn, get_private) {
+ var hash_parts_are_private, hgetall_flag, hmget, key, not_private, schema, type, value, _ref,
+ _this = this;
+ if (get_private == null) {
+ get_private = false;
+ }
+ not_private = function() {
+ return !get_private || get_private && value.options["private"] !== true;
+ };
+ schema = [];
+ hgetall_flag = false;
+ hash_parts_are_private = false;
+ hmget = [];
+ _ref = this.model;
+ for (key in _ref) {
+ value = _ref[key];
+ type = value.type;
+ switch (type) {
+ case 'str':
+ case 'num':
+ hgetall_flag = true;
+ if (not_private()) {
+ hmget.push(key);
+ } else {
+ hash_parts_are_private = true;
+ }
+ break;
+ case 'list':
+ if (not_private()) {
+ this._commands.push(['lrange', this.get_key(key), 0, -1]);
+ schema.push(key);
+ }
+ break;
+ case 'set':
+ if (not_private()) {
+ this._commands.push(['smembers', this.get_key(key)]);
+ schema.push(key);
+ }
+ break;
+ case 'zset':
+ if (not_private()) {
+ this._commands.push(['zrange', this.get_key(key), 0, -1, 'withscores']);
+ schema.push(key);
+ }
+ }
+ }
+ if (hash_parts_are_private) {
+ if (hmget.length) {
+ this._commands.push(['hmget', this.get_key()].concat(hmget));
+ schema.push(hmget);
+ }
+ } else if (hgetall_flag) {
+ this._commands.push(['hgetall', this.get_key()]);
+ schema.push('hash');
+ }
+ return this.exec(function(err, res, id) {
+ var i, j, o, prop, result, _i, _j, _len, _len1;
+ result = false;
+ if (err) {
+ err.time = new Date();
+ err.level = 'ERROR';
+ err.type = 'Redis';
+ err.msg = 'Failed getting model';
+ _this._errors.push(err);
+ Orpheus.trigger('error', err);
+ } else {
+ result = {};
+ for (i = _i = 0, _len = schema.length; _i < _len; i = ++_i) {
+ o = schema[i];
+ if (o === 'hash') {
+ _.extend(result, res[i]);
+ } else if (Array.isArray(o)) {
+ for (j = _j = 0, _len1 = o.length; _j < _len1; j = ++_j) {
+ prop = o[j];
+ result[prop] = res[i][j];
+ }
+ } else {
+ result[o] = res[i];
+ }
+ }
+ result.id = _this.id;
+ }
+ return fn(err, result, _this.id);
+ });
+ };
+
+ OrpheusAPI.prototype.exec = function(fn) {
+ var _this = this;
+ if (this.validation_errors.length) {
+ return fn(this.validation_errors, false, this.id);
+ }
+ return this.redis.multi(this._commands).exec(function(err, res) {
+ if (err) {
+ err.time = new Date();
+ err.level = 'ERROR';
+ err.type = 'Redis';
+ err.msg = 'Failed Multi Execution';
+ _this._errors.push(err);
+ Orpheus.trigger('error', err);
+ }
+ return fn(err, res, _this.id);
+ });
+ };
+
+ return OrpheusAPI;
+
+ })();
+
+ module.exports = Orpheus;
+
+}).call(this);
View
2  index.js
@@ -1,3 +1,3 @@
// This file is just added for convenience so this repository can be
// directly checked out into a project's deps folder
-module.exports = require('./lib/orpheus');
+module.exports = require('./dist/orpheus');
Please sign in to comment.
Something went wrong with that request. Please try again.