backbone-db-redis
Advanced tools
Comparing version 0.0.46 to 0.1.1
288
index.js
@@ -1,11 +0,10 @@ | ||
var _ = require('lodash'), | ||
Backbone = require('backbone'), | ||
Db = require('backbone-db'), | ||
redis = require('redis'), | ||
debug = require('debug')('backbone-db-redis'), | ||
indexing = require('./lib/indexing'), | ||
query = require('./lib/query'), | ||
utils = require('./lib/utils'); | ||
var _ = require('lodash'); | ||
var Backbone = require('backdash'); | ||
var Db = require('backbone-db'); | ||
var redis = require('redis'); | ||
var debug = require('debug')('backbone-db-redis'); | ||
var indexing = require('./lib/indexing'); | ||
var query = require('./lib/query'); | ||
var indexedDbMixin = require('./lib/indexed_db_mixin'); | ||
var RedisDb = Backbone.RedisDb = function(name, client) { | ||
@@ -22,5 +21,4 @@ this.name = name || ''; | ||
return key; | ||
} else { | ||
return this.name + ':' + key; | ||
} | ||
return this.name + ':' + key; | ||
}; | ||
@@ -42,3 +40,3 @@ | ||
_.extend(RedisDb.prototype, Db.prototype, { | ||
_.extend(RedisDb.prototype, Db.prototype, indexedDbMixin, { | ||
createClient: function() { | ||
@@ -50,11 +48,11 @@ if (this.redis) { | ||
_getLoadFn: function(model, options) { | ||
_getLoadFn: function(model) { | ||
var type = model.redis_type || 'string'; | ||
return loadFnMap[type.toLowerCase()] || 'get'; | ||
return loadFnMap[type.toLowerCase()] || 'get'; | ||
}, | ||
_getSaveFn: function(model, options) { | ||
_getSaveFn: function(model) { | ||
var type = model.redis_type || 'string'; | ||
return saveFnMap[type.toLowerCase()] || 'set'; | ||
return saveFnMap[type.toLowerCase()] || 'set'; | ||
}, | ||
_getIncFn: function(model, options) { | ||
_getIncFn: function(model) { | ||
var type = model.redis_type || 'string'; | ||
@@ -68,3 +66,3 @@ if (!incFnMap.hasOwnProperty(type)) { | ||
var args = [this.getIdKey(model, options)]; | ||
options = options || {}; | ||
options = options || {}; | ||
if (fn === 'hmset') { | ||
@@ -84,3 +82,3 @@ var data = model.toJSON(); | ||
var args = [this.getIdKey(model, options)]; | ||
options = options || {}; | ||
options = options || {}; | ||
return args; | ||
@@ -116,5 +114,4 @@ }, | ||
return this.name + (key ? ':' + key : ''); | ||
} else { | ||
return key; | ||
} | ||
return key; | ||
}, | ||
@@ -128,5 +125,5 @@ | ||
return this.name + ':' + setKey; | ||
} else { | ||
return setKey; | ||
} | ||
return setKey; | ||
}, | ||
@@ -140,5 +137,4 @@ | ||
return this.name + ':' + setKey; | ||
} else { | ||
return setKey; | ||
} | ||
return setKey; | ||
}, | ||
@@ -176,3 +172,3 @@ | ||
var searchAttrs = {}; | ||
var allIndexed = _.each(objectKeys, function(attr) { | ||
_.each(objectKeys, function(attr) { | ||
if (indexedKeys.indexOf(attr) > -1) { | ||
@@ -198,4 +194,4 @@ searchAttrs[attr] = model.get(attr); | ||
}; | ||
query.queryModels(options, dbOpts, function(err, results) { | ||
callback(err, results && results.length && results[0]); | ||
query.queryModels(options, dbOpts, function(queryErr, results) { | ||
callback(queryErr, results && results.length && results[0]); | ||
}); | ||
@@ -261,3 +257,4 @@ } | ||
var cmd = this.getSaveCommand(model, options); | ||
cmd.args.push(function(err, res) { | ||
cmd.args.push(function(err) { | ||
if (err) return callback(err); | ||
if (model.collection) { | ||
@@ -267,3 +264,4 @@ var setKey = self.getIdKey(model.collection, {}); | ||
debug('adding model ' + modelKey + ' to ' + setKey); | ||
self.redis.sadd(setKey, modelKey, function(err, res) { | ||
self.redis.sadd(setKey, modelKey, function(addErr) { | ||
if (addErr) return callback(addErr); | ||
self._updateIndexes(model, options, callback); | ||
@@ -293,3 +291,3 @@ }); | ||
var key = this.getIdKey(model, options); | ||
debug("DESTROY: " + key); | ||
debug('DESTROY: ' + key); | ||
if (model.isNew()) { | ||
@@ -301,3 +299,3 @@ return false; | ||
debug('removing key: ' + key); | ||
self.redis.del(key, function(err, res) { | ||
self.redis.del(key, function(err) { | ||
callback(err, model.toJSON()); | ||
@@ -310,2 +308,3 @@ }); | ||
}, options), function(err) { | ||
if (err) return callback(err); | ||
if (model.collection) { | ||
@@ -315,4 +314,4 @@ var setKey = self.getIdKey(model.collection, {}); | ||
debug('removing model ' + modelKey + ' from ' + setKey); | ||
self.redis.srem(setKey, modelKey, function(err, res) { | ||
if (err) return callback(err); | ||
self.redis.srem(setKey, modelKey, function(remErr) { | ||
if (remErr) return callback(remErr); | ||
delKey(); | ||
@@ -327,220 +326,4 @@ }); | ||
addToIndex: function(collection, model, options, cb) { | ||
var setKey = collection.indexKey; | ||
var key = model.id; | ||
debug('adding model ' + key + ' to ' + setKey); | ||
if (collection.indexSort) { | ||
this.redis.zadd(setKey, collection.indexSort(model), key, cb); | ||
} else { | ||
this.redis.sadd(setKey, key, function(err, res) { | ||
cb(err, res); | ||
}); | ||
} | ||
}, | ||
readFromIndex: function(collection, options, cb) { | ||
var self = this; | ||
var setKey = options.indexKey || collection.indexKey; | ||
var dynamicSorted = false; | ||
var done = function(err, data) { | ||
data = data || []; // Data might be null on errors | ||
var models = []; | ||
var i = 0; | ||
while (i < data.length) { | ||
var modelData = { | ||
id: data[i] | ||
}; | ||
i++; | ||
if (options.score && options.score.conversion) { | ||
var score = options.score.conversion.fn(data[i]); | ||
modelData[options.score.conversion.attribute] = score; | ||
i++; | ||
} | ||
models.push(modelData); | ||
} | ||
var setOpts = {}; | ||
// disable sort by default here, since it's expected that redis set was sorted | ||
if (collection.indexSort) setOpts.sort = false; | ||
var opts = _.extend(setOpts, options); | ||
if (dynamicSorted) opts.sort = false; | ||
collection.set(models, opts); | ||
return cb(err, models); | ||
}; | ||
var getReadFn = function() { | ||
var params; | ||
if (collection.indexSort) { | ||
var min = '-inf'; | ||
var max = '+inf'; | ||
if (options.score) { | ||
min = options.score.min || min; | ||
max = options.score.max || max; | ||
params = [setKey, max, min]; | ||
if (options.score.conversion) params.push('WITHSCORES'); | ||
if (options.limit || options.offset) { | ||
params = params.concat(['LIMIT', options.offset || 0, options.limit || -1]); | ||
} | ||
if (options.sortOrder === 1) { | ||
return _.bind.apply(null, [self.redis.zrangebyscore, self.redis].concat(params)); | ||
} | ||
return _.bind.apply(null, [self.redis.zrevrangebyscore, self.redis].concat(params)); | ||
} else { | ||
var start = options.offset || 0; | ||
var stop = options.limit ? (start + options.limit - 1) : -1; | ||
if (options.sortOrder === 1) { | ||
return _.bind(self.redis.zrange, self.redis, setKey, start, stop); | ||
} | ||
return _.bind(self.redis.zrevrange, self.redis, setKey, start, stop); | ||
} | ||
} | ||
if (options.sort && collection.model.prototype.redis_type === 'hash') { | ||
dynamicSorted = true; | ||
var m = new collection.model(); | ||
var idKey = self.getIdKey(m); | ||
var parsedSort = utils.parseSort(options.sort); | ||
var sortParams = idKey + ':*->' + parsedSort.sortProp; | ||
params = [setKey, 'BY', sortParams]; | ||
if (options.limit_query !== false && (options.limit || options.offset)) { | ||
params = params.concat(['LIMIT', options.offset || 0, options.limit || -1]); | ||
} | ||
if (parsedSort.sortOrder === -1) { | ||
params.push('DESC'); | ||
} | ||
debug('dynamic sort:', params); | ||
return _.bind.apply(null, [self.redis.sort, self.redis].concat(params)); | ||
} | ||
return _.bind(self.redis.smembers, self.redis, setKey); | ||
}; | ||
// TODO: handle sort order | ||
var readWithRank = function(_done) { | ||
debug('readWithRank'); | ||
if (!collection.indexSort) throw new Error('Cannot read rank of non-sorted set'); | ||
var id = options.before_id ? options.before_id : options.after_id; | ||
// by default order set descending | ||
var order = options.sortOrder ? options.sortOrder : - 1; | ||
var rankFn = 'zrank'; | ||
var rangeFn = 'zrange'; | ||
var start; | ||
var stop; | ||
if (order === -1) { | ||
rankFn = 'zrevrank'; | ||
rangeFn = 'zrevrange'; | ||
} | ||
// first: read rank for given id | ||
self.redis[rankFn](setKey, id, function(err, rank) { | ||
//debug('got rank: %s for id: %s, using %s %s', rank, id, rankFn, rangeFn); | ||
if (options.after_id) { | ||
start = rank + 1; | ||
stop = options.limit ? (start + options.limit -1) : - 1; | ||
} else if (options.before_id) { | ||
if (rank === 0) { | ||
// there`s nothing before given id | ||
return _done(null, []); | ||
} | ||
if (order === 1 && options.limit) { | ||
start = rank - 1; | ||
} else { | ||
start = 0; | ||
} | ||
stop = rank - 1; | ||
if (options.limit) stop = start -1 + options.limit; | ||
} | ||
var params = [setKey, start, stop]; | ||
if (options.score && options.score.conversion) params.push('WITHSCORES'); | ||
params.push(_done); | ||
// second: read results with zrevrange or zrange | ||
self.redis[rangeFn].apply(self.redis, params); | ||
}); | ||
}; | ||
debug('reading keys from: ' + setKey); | ||
if (options.before_id || options.after_id) { | ||
return readWithRank(done); | ||
} | ||
var readFn = getReadFn(); | ||
readFn(done); | ||
}, | ||
/** | ||
* Read from multiple sets, storing union in new set temporarily | ||
*/ | ||
readFromIndexes: function(collection, options, cb) { | ||
var self = this; | ||
var unionKey = options.unionKey; | ||
var params = _.clone(options.indexKeys); | ||
if (collection.indexSort) params.unshift(options.indexKeys.length); // how many sets to union | ||
params.unshift(unionKey); // where to store | ||
if (options.weights) { | ||
params.push('WEIGHTS'); | ||
params.push.apply(params, options.weights); | ||
} | ||
// by default use MAX aggregate option (redis default is SUM) | ||
if (collection.indexSort) { | ||
params.push('AGGREGATE', 'MAX'); | ||
} | ||
var unionFn = collection.indexSort ? | ||
_.bind(this.redis.zunionstore, this.redis) : | ||
_.bind(this.redis.sunionstore, this.redis); | ||
unionFn(params, function(err) { | ||
self.redis.expire(unionKey, 300); | ||
options.indexKey = unionKey; | ||
return self.readFromIndex(collection, _.extend({limit_query: false}, options), cb); | ||
}); | ||
}, | ||
removeFromIndex: function(collection, models, options, cb) { | ||
var setKey = collection.indexKey; | ||
var keys = _.pluck(models, models[0].idAttribute); | ||
var cmd = [setKey].concat(keys); | ||
debug('removing key: ' + keys + ' from: ' + setKey); | ||
if (collection.indexSort) { | ||
this.redis.zrem(cmd, cb); | ||
} else { | ||
this.redis.srem(cmd, cb); | ||
} | ||
}, | ||
// removes the index completely | ||
removeIndex: function(collection, options, cb) { | ||
var setKey = collection.indexKey; | ||
this.redis.del(setKey, cb); | ||
}, | ||
existsInIndex: function(collection, model, options, cb) { | ||
var setKey = collection.indexKey; | ||
var key = model.id; | ||
debug('check existance for: ' + key + ' in: ' + setKey); | ||
function done(err, rank) { | ||
cb(err, rank !== null); | ||
} | ||
if (collection.indexSort) { | ||
this.redis.zrank(setKey, key, done); | ||
} else { | ||
this.redis.sismember(setKey, key, function(err, isMember) { | ||
cb(err, isMember === 1); | ||
}); | ||
} | ||
}, | ||
indexCount: function(collection, options, cb) { | ||
var setKey = collection.indexKey; | ||
debug('get count for: ' + setKey); | ||
if (collection.indexSort) { | ||
this.redis.zcard(setKey, cb); | ||
} else { | ||
this.redis.scard(setKey, cb); | ||
} | ||
}, | ||
// Warning: consider KEYS as a command that should only be used in | ||
// production environments with extreme care | ||
findKeys: function(collection, options, cb) { | ||
@@ -573,4 +356,5 @@ var prefix = options.prefix || (this.getIdKey(collection, {})); | ||
}); | ||
RedisDb.sync = RedisDb.prototype.sync; | ||
RedisDb.Hash = require('./lib/hash'); | ||
module.exports = RedisDb; |
var Promises = require('backbone-promises'); | ||
var Backbone = require('backbone'); | ||
var debug = require('debug')('backbone-db-redis:hash'); | ||
var Hash = module.exports = Promises.Model.extend({ | ||
module.exports = Promises.Model.extend({ | ||
redis_type: 'hash' | ||
}); |
@@ -22,12 +22,14 @@ var debug = require('debug')('backbone-db-redis:indexing'); | ||
/** | ||
params: | ||
options object: | ||
{ | ||
indexes - array of properties to be indexed | ||
data - model.attributes | ||
prevData - model's previous attributes | ||
id - model's id | ||
db - RedisDb instance | ||
} | ||
**/ | ||
* Update indexes automatically | ||
* @param {[Object]} options: | ||
* { | ||
* indexes - array of properties to be indexed | ||
* data - model.attributes | ||
* prevData - model's previous attributes | ||
* id - model's id | ||
* db - RedisDb instance | ||
* } | ||
* | ||
* @param {Function} callback function to call when done | ||
*/ | ||
exports.updateIndexes = function(options, callback) { | ||
@@ -99,2 +101,2 @@ var queue = []; | ||
} | ||
}; | ||
}; |
var Promises = require('backbone-promises'); | ||
var Backbone = require('backbone'); | ||
var List = module.exports = Promises.Collection.extend({ | ||
module.exports = Promises.Collection.extend({ | ||
redis_type: 'list' | ||
}); |
@@ -25,5 +25,4 @@ var _ = require('lodash'); | ||
return objToJSON(data); | ||
} else { | ||
return data && JSON.parse(data); | ||
} | ||
return data && JSON.parse(data); | ||
}); | ||
@@ -132,6 +131,7 @@ } | ||
this.db.redis.zinterstore.apply(this.db.redis, query); | ||
var canSortUsingHash = !canUseIndexForSorting | ||
&& (self.dbOptions.ModelClass.prototype.redis_type === 'hash'); | ||
if (this.filterOptions.customSort) { | ||
return this._customSort(this.destinationSet, this.filterOptions.customSort, cb); | ||
} else if (!canUseIndexForSorting && self.dbOptions.ModelClass.prototype.redis_type === 'hash') { | ||
} else if (canSortUsingHash) { | ||
this._sortUsingHash(this.destinationSet, {}, cb); | ||
@@ -173,3 +173,3 @@ } else { | ||
var parts = id.split(':'); | ||
id = parts[parts.length -1]; | ||
id = parts[parts.length - 1]; | ||
} | ||
@@ -232,3 +232,2 @@ var attrs = {}; | ||
_fetchSorted: function(set, cb) { | ||
var self = this; | ||
var sortOpts = this._getSortSetKeyAndOrder(); | ||
@@ -246,3 +245,3 @@ set = set ? set : sortOpts.sortKey; | ||
if (sortOpts.sortOrder === undefined || sortOpts.sortOrder === 1) { | ||
if (_.isUndefined(sortOpts.sortOrder) || sortOpts.sortOrder === 1) { | ||
this.db.redis.zrange(set, start, end, cb); | ||
@@ -249,0 +248,0 @@ } else { |
@@ -1,4 +0,3 @@ | ||
var redis = require('redis'), | ||
debug = require('debug')('store'), | ||
_ = require('lodash'); | ||
var redis = require('redis'); | ||
var debug = require('debug')('store'); | ||
@@ -34,3 +33,3 @@ /** | ||
debug('getItems'); | ||
this.client.zrange(key,start,end, cb); | ||
this.client.zrange(key, start, end, cb); | ||
}; | ||
@@ -37,0 +36,0 @@ |
var Promises = require('backbone-promises'); | ||
var debug = require('debug')('backbone-db-redis:set'); | ||
var _ = require('lodash'); | ||
@@ -5,0 +3,0 @@ module.exports = Promises.Collection.extend({ |
var Promises = require('backbone-promises'); | ||
var SortedSet = module.exports = Promises.Collection.extend({ | ||
module.exports = Promises.Collection.extend({ | ||
redis_type: 'zset', | ||
model: Promises.Model | ||
}); | ||
}); |
{ | ||
"name": "backbone-db-redis", | ||
"version": "0.0.46", | ||
"version": "0.1.1", | ||
"description": "Redis driver for Backbone.Db", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "make test" | ||
"test": "make test", | ||
"lint": "eslint *.js lib/*.js test/*.js", | ||
"precommit": "npm run lint && npm run test" | ||
}, | ||
@@ -13,18 +15,19 @@ "repository": "", | ||
"dependencies": { | ||
"lodash": "~2.4.1", | ||
"backbone": "~1.1.0", | ||
"redis": "~0.10", | ||
"debug": "~0.8", | ||
"backbone-promises": "~0.2", | ||
"when": "~3.1", | ||
"backbone-db": "~0.4", | ||
"async": "^0.9.0" | ||
"async": "^0.9.0", | ||
"backbone-db": "^0.5.4", | ||
"backbone-db-indexing-adapter": "^0.1.1", | ||
"backbone-promises": "^0.2.9", | ||
"backdash": "^1.1.2-2.4.1", | ||
"debug": "^2.1.2", | ||
"lodash": "^3.5.0", | ||
"redis": "^0.12.1" | ||
}, | ||
"devDependencies": { | ||
"chai": "~1.9.0", | ||
"eslint": "^0.16.2", | ||
"husky": "^0.7.0", | ||
"istanbul": "~0.2", | ||
"mocha": "~1.18", | ||
"istanbul": "~0.2", | ||
"chai": "~1.9.0", | ||
"jshint": "~2.4", | ||
"jscs": "~1.3" | ||
"when": "^3.7.2" | ||
} | ||
} |
var _ = require('lodash'); | ||
var RedisDb = require('../'); | ||
var Backbone = require('backbone'); | ||
var Promises = require('backbone-promises'); | ||
var IndexedCollectionMixin = require('backbone-db-indexing-adapter').IndexedCollectionMixin; | ||
var Model = Promises.Model; | ||
var Collection = Promises.Collection; | ||
var nodefn = require('when/node/function'); | ||
var store = exports.store = new RedisDb('test'); | ||
@@ -43,3 +43,3 @@ var redis = require('redis'); | ||
var IndexedCollection = exports.IndexedCollection = MyCollection.extend({ | ||
exports.IndexedCollection = MyCollection.extend({ | ||
model: IndexedModel | ||
@@ -52,6 +52,6 @@ }); | ||
{id: 3, value: 3, name: 'c', platforms: ['android']}, | ||
{id: 4, value: 2, name: 'c', platforms: ['ios']}, | ||
{id: 4, value: 2, name: 'c', platforms: ['ios']} | ||
]; | ||
var IndexedByDateModel = exports.IndexedByDateModel = MyModel.extend({ | ||
exports.IndexedByDateModel = MyModel.extend({ | ||
indexes: [ | ||
@@ -75,3 +75,3 @@ { | ||
var TestIndexedCollection = exports.TestIndexedCollection = MyCollection.extend({ | ||
exports.TestIndexedCollection = MyCollection.extend(_.extend({}, IndexedCollectionMixin, { | ||
indexDb: store, | ||
@@ -82,81 +82,4 @@ indexKey: 'test:i:Foo:relation', | ||
return model.get('score'); | ||
}, | ||
/** | ||
* Adds a new model to the index. Only specified attribute is indexed. | ||
* Db adapter returns a Promise | ||
*/ | ||
addToIndex: function(model, options) { | ||
options = options ? _.clone(options) : {}; | ||
if (!(model = this._prepareModel(model, options))) return false; | ||
if (!options.wait) this.add(model, options); | ||
return this._callAdapter('addToIndex', options, model); | ||
}, | ||
/** | ||
* Read model ids from the index. Populates collection models with ids, | ||
* for fetching from the main storage. | ||
*/ | ||
readFromIndex: function(options) { | ||
return this._callAdapter('readFromIndex', options); | ||
}, | ||
/** | ||
* Read from multiple indexes | ||
*/ | ||
readFromIndexes: function(options) { | ||
options = options ? _.clone(options) : {}; | ||
options.indexKeys = this.indexKeys || options.indexKeys; | ||
options.unionKey = this.unionKey || options.unionKey; | ||
if (this.indexKey) options.indexKeys.push(this.indexKey); | ||
var args = [this, options]; | ||
return nodefn.apply(_.bind(this.indexDb.readFromIndexes, this.indexDb), args); | ||
}, | ||
/** | ||
* Removes a model from index | ||
*/ | ||
removeFromIndex: function(models, options) { | ||
if(!models) return false; | ||
this.remove(models, options); | ||
var singular = !_.isArray(models); | ||
models = singular ? [models] : _.clone(models); | ||
return this._callAdapter('removeFromIndex', options, models); | ||
}, | ||
destroyAll: function(options) { | ||
return this._callAdapter('removeIndex', options); | ||
}, | ||
/** | ||
* Check if model exists in index | ||
*/ | ||
exists: function(model, options) { | ||
return this._callAdapter('existsInIndex', options, model); | ||
}, | ||
/** | ||
* Get count of items in index | ||
*/ | ||
count: function(options) { | ||
return this._callAdapter('indexCount', options); | ||
}, | ||
findKeys: function(keys, options) { | ||
options = options ? _.clone(options) : {}; | ||
options.keys = keys; | ||
return this._callAdapter('findKeys', options); | ||
}, | ||
_callAdapter: function(fn, options, models) { | ||
options = options ? _.clone(options) : {}; | ||
if (!this.indexDb) { | ||
throw new Error('indexDb must be defined'); | ||
} | ||
options.indexKey = this.indexKey; | ||
var args = [this, options]; | ||
if (models) args.splice(1, 0, models); | ||
return nodefn.apply(_.bind(this.indexDb[fn], this.indexDb), args); | ||
} | ||
}); | ||
})); | ||
@@ -186,2 +109,2 @@ exports.insertFixtureData = function (collection, cb) { | ||
}); | ||
}; | ||
}; |
@@ -8,5 +8,2 @@ require('chai').should(); | ||
var Hash = require('../lib/hash'); | ||
var SortedSet = require('../lib/sortedset'); | ||
var List = require('../lib/list'); | ||
var SetModel = require('../lib/set'); | ||
var setup = require('./setup'); | ||
@@ -76,3 +73,3 @@ var redis = setup.store.redis; | ||
collection.at(2).destroy(), | ||
index.destroyAll(), | ||
index.destroyAll() | ||
]; | ||
@@ -179,3 +176,3 @@ return Promises.when.all(fns).then(function() { | ||
return h.fetch(); | ||
}).then(function(){ | ||
}).then(function() { | ||
h.get('a').should.equal(226); | ||
@@ -245,4 +242,4 @@ }); | ||
}); | ||
async.parallel(fns, function(err, res) { | ||
next(); | ||
async.parallel(fns, function(err) { | ||
next(err); | ||
}); | ||
@@ -277,3 +274,3 @@ }); | ||
it('should fetch from customIndex sorting by value set to customsort with offset and limit', function() { | ||
it('should fetch from customIndex with custom sort, offset and limit', function() { | ||
var opts = { | ||
@@ -280,0 +277,0 @@ sort: 'a', |
@@ -24,2 +24,2 @@ /*var assert = require('assert'); | ||
*/ | ||
*/ |
@@ -7,5 +7,2 @@ var assert = require('assert'); | ||
var setup = require('./setup'); | ||
var MyCollection = setup.MyCollection; | ||
var MyModel = setup.MyModel; | ||
var store = setup.store; | ||
var TestCollection = setup.TestIndexedCollection; | ||
@@ -241,2 +238,11 @@ | ||
it('should get score for model', function() { | ||
var model = collection.at(0); | ||
return collection | ||
.score(model) | ||
.then(function(score) { | ||
Number(score).should.equal(22); | ||
}); | ||
}); | ||
/* | ||
@@ -485,2 +491,2 @@ it('should remove model from index', function(done) { | ||
}); | ||
}); |
var assert = require('assert'); | ||
var _ = require('lodash'); | ||
var Promises = require('backbone-promises'); | ||
@@ -12,3 +10,2 @@ var setup = require('./setup'); | ||
describe('Indexing tests', function() { | ||
var testModel; | ||
@@ -26,15 +23,20 @@ before(function(done) { | ||
it('should check that specified indexes were created', function(done) { | ||
function checkPlatforms() { | ||
redis.smembers('test:i:mymodels:platforms:ios', function(err, ids) { | ||
assert(ids.length === 3); | ||
assert(ids.indexOf('1') > -1); | ||
assert(ids.indexOf('2') > -1); | ||
assert(ids.indexOf('4') > -1); | ||
done(); | ||
}); | ||
} | ||
redis.keys('test:i:mymodel*', function(err, keys) { | ||
if (err) return done(err); | ||
assert(keys.indexOf('test:i:mymodels:value:1') > -1); | ||
assert(keys.indexOf('test:i:mymodels:platforms:android') > -1); | ||
redis.smembers('test:i:mymodels:value:2', function(err, ids) { | ||
redis.smembers('test:i:mymodels:value:2', function(err2, ids) { | ||
if (err2) return done(err2); | ||
assert(ids.indexOf('2') > -1); | ||
assert(ids.indexOf('4') > -1); | ||
redis.smembers('test:i:mymodels:platforms:ios', function(err, ids) { | ||
assert(ids.length === 3); | ||
assert(ids.indexOf('1') > -1); | ||
assert(ids.indexOf('2') > -1); | ||
assert(ids.indexOf('4') > -1); | ||
done(); | ||
}); | ||
checkPlatforms(); | ||
}); | ||
@@ -62,2 +64,3 @@ }); | ||
}, function(err) { | ||
assert(err); | ||
done(); | ||
@@ -94,2 +97,9 @@ }); | ||
it('should update index when updating properties', function(done) { | ||
function checkNameIndex() { | ||
redis.smembers('test:i:mymodels:name:c', function(err, ids) { | ||
assert(ids.indexOf('3') === -1); | ||
assert(ids.indexOf('4') > -1); | ||
done(); | ||
}); | ||
} | ||
var model = collection.findWhere({id: 3}); | ||
@@ -103,7 +113,3 @@ assert(model); | ||
assert(keys.indexOf('test:i:mymodels:name:e') > -1); | ||
redis.smembers('test:i:mymodels:name:c', function(err, ids) { | ||
assert(ids.indexOf('3') === -1); | ||
assert(ids.indexOf('4') > -1); | ||
done(); | ||
}); | ||
checkNameIndex(); | ||
}); | ||
@@ -114,15 +120,20 @@ }); | ||
it('should remove reference to model in index after removing', function(done) { | ||
function checkPlatformIndex() { | ||
redis.smembers('test:i:mymodels:platforms:ios', function(err, ids) { | ||
// 1 & 2 were deleted, only 4 should be left | ||
assert(ids.length === 1); | ||
assert(ids.indexOf('4') > -1); | ||
done(); | ||
}); | ||
} | ||
function checkIndexes() { | ||
redis.keys('test:i:mymodel*', function(err, keys) { | ||
if (err) return done(err); | ||
assert(keys.indexOf('test:i:mymodels:value:2') > -1); | ||
assert(keys.indexOf('test:i:mymodels:name:b') === -1); | ||
redis.smembers('test:i:mymodels:value:2', function(err, ids) { | ||
redis.smembers('test:i:mymodels:value:2', function(err2, ids) { | ||
if (err2) return done(err2); | ||
assert(ids.indexOf('2') === -1); | ||
assert(ids.indexOf('4') > -1); | ||
redis.smembers('test:i:mymodels:platforms:ios', function(err, ids) { | ||
// 1 & 2 were deleted, only 4 should be left | ||
assert(ids.length === 1); | ||
assert(ids.indexOf('4') > -1); | ||
done(); | ||
}); | ||
checkPlatformIndex(); | ||
}); | ||
@@ -146,3 +157,4 @@ }); | ||
redis.keys('test:i:mymodel*', function(err, keys) { | ||
assert(keys.indexOf('test:i:mymodels:name:x') > -1, 'index test:i:mymodels:name:x was not created'); | ||
assert(keys.indexOf('test:i:mymodels:name:x') > -1, | ||
'index test:i:mymodels:name:x was not created'); | ||
done(); | ||
@@ -159,3 +171,3 @@ }); | ||
it('should remove reference to model in index after removing a model without collection defined', function(done) { | ||
it('should remove reference to model in index when collection is not defined', function(done) { | ||
function checkIndexes() { | ||
@@ -201,5 +213,8 @@ redis.keys('test:i:mymodel*', function(err, keys) { | ||
redis.keys('test:z:mymodel*', function(err, keys) { | ||
if (err) return done(err); | ||
var key = 'test:z:mymodels:featured'; | ||
assert(keys.indexOf(key) > -1, 'model should not be added to featured index when attribute is not set'); | ||
redis.zrange(key, 0, -1, function(err, ids) { | ||
assert(keys.indexOf(key) > -1, | ||
'model should not be added to featured index when attribute is not set'); | ||
redis.zrange(key, 0, -1, function(err2, ids) { | ||
if (err2) return done(err2); | ||
assert.equal(ids.length, 1); | ||
@@ -206,0 +221,0 @@ done(); |
@@ -8,9 +8,12 @@ var assert = require('assert'); | ||
it('should .save from store', function(t) { | ||
var m = new MyModel({id: 1, 'asd': 'das'}); | ||
m.save().then(function() { | ||
function check() { | ||
var m2 = new MyModel({id: 1}); | ||
m2.fetch().then(function() { | ||
assert.equal(m2.get('asd'),'das'); | ||
assert.equal(m2.get('asd'), 'das'); | ||
t(); | ||
}); | ||
} | ||
var m = new MyModel({id: 1, 'asd': 'das'}); | ||
m.save().then(function() { | ||
check(); | ||
}); | ||
@@ -27,2 +30,2 @@ }); | ||
}); | ||
}); | ||
}); |
var assert = require('assert'); | ||
var _ = require('lodash'); | ||
var Promises = require('backbone-promises'); | ||
var util = require('util'); | ||
@@ -26,4 +25,2 @@ var when = require('when'); | ||
describe('Query tests', function() { | ||
var testModel; | ||
before(function(done) { | ||
@@ -79,3 +76,3 @@ setup.insertFixtureData(collection, done); | ||
limit: 2, | ||
offset: 1, | ||
offset: 1 | ||
}; | ||
@@ -121,3 +118,2 @@ collection | ||
it('should fetch models with after_id', function(done) { | ||
//TODO | ||
var opts = { | ||
@@ -124,0 +120,0 @@ after_id: 2, |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
94283
6
28
2344
+ Addedbackdash@^1.1.2-2.4.1
+ Addedbackbone-db@0.5.7(transitive)
+ Addedbackbone-db-indexing-adapter@0.1.1(transitive)
+ Addedbackbone-db-local@0.5.13(transitive)
+ Addedbalanced-match@1.0.2(transitive)
+ Addedbrace-expansion@1.1.11(transitive)
+ Addedcli@1.0.1(transitive)
+ Addedconcat-map@0.0.1(transitive)
+ Addedconsole-browserify@1.1.0(transitive)
+ Addedcore-util-is@1.0.3(transitive)
+ Addeddate-now@0.1.4(transitive)
+ Addeddebug@2.6.9(transitive)
+ Addeddom-serializer@0.2.2(transitive)
+ Addeddomelementtype@1.3.12.3.0(transitive)
+ Addeddomhandler@2.3.0(transitive)
+ Addeddomutils@1.5.1(transitive)
+ Addedentities@1.0.02.2.0(transitive)
+ Addedexit@0.1.2(transitive)
+ Addedfs.realpath@1.0.0(transitive)
+ Addedglob@7.2.3(transitive)
+ Addedhtmlparser2@3.8.3(transitive)
+ Addedinflight@1.0.6(transitive)
+ Addedinherits@2.0.4(transitive)
+ Addedisarray@0.0.1(transitive)
+ Addedjshint@2.13.6(transitive)
+ Addedlodash@3.10.14.17.21(transitive)
+ Addedminimatch@3.0.83.1.2(transitive)
+ Addedonce@1.4.0(transitive)
+ Addedpath-is-absolute@1.0.1(transitive)
+ Addedpff@0.2.0(transitive)
+ Addedreadable-stream@1.1.14(transitive)
+ Addedredis@0.12.1(transitive)
+ Addedstring_decoder@0.10.31(transitive)
+ Addedstrip-json-comments@1.0.4(transitive)
+ Addedwrappy@1.0.2(transitive)
- Removedbackbone@~1.1.0
- Removedwhen@~3.1
- Removedbackbone@1.1.2(transitive)
- Removedbackbone-db@0.4.25(transitive)
- Removeddebug@0.8.1(transitive)
- Removedjsonquery@0.1.8(transitive)
- Removedredis@0.10.3(transitive)
- Removedunderscore@1.13.7(transitive)
- Removedwhen@3.1.0(transitive)
Updatedbackbone-db@^0.5.4
Updatedbackbone-promises@^0.2.9
Updateddebug@^2.1.2
Updatedlodash@^3.5.0
Updatedredis@^0.12.1