mirror of
				https://github.com/NodeBB/NodeBB.git
				synced 2025-10-31 02:55:58 +01:00 
			
		
		
		
	removing leveldb from our dbal
a) It isn't being maintained, especially not by me b) I haven't seen anybody actually interested in this db software so there's no real point in supporting it unless we have a few people who are interested If you ARE interested though - please contact me and we can figure something out in future :)
This commit is contained in:
		| @@ -12,7 +12,7 @@ function success(err, config, callback) { | ||||
| 		return callback(new Error('aborted')); | ||||
| 	} | ||||
|  | ||||
| 	var database = (config.redis || config.mongo || config.level) ? config.secondary_database : config.database; | ||||
| 	var database = (config.redis || config.mongo) ? config.secondary_database : config.database; | ||||
|  | ||||
| 	function dbQuestionsSuccess(err, databaseConfig) { | ||||
| 		if (!databaseConfig) { | ||||
| @@ -39,15 +39,11 @@ function success(err, config, callback) { | ||||
| 				password: databaseConfig['mongo:password'], | ||||
| 				database: databaseConfig['mongo:database'] | ||||
| 			}; | ||||
| 		} else if (database === 'level') { | ||||
| 			config.level = { | ||||
| 				database: databaseConfig['level:database'] | ||||
| 			}; | ||||
| 		} else { | ||||
| 			return callback(new Error('unknown database : ' + database)); | ||||
| 		} | ||||
|  | ||||
| 		var allQuestions = questions.redis.concat(questions.mongo.concat(questions.level)); | ||||
| 		var allQuestions = questions.redis.concat(questions.mongo); | ||||
| 		for(var x=0;x<allQuestions.length;x++) { | ||||
| 			delete config[allQuestions[x].name]; | ||||
| 		} | ||||
| @@ -67,12 +63,6 @@ function success(err, config, callback) { | ||||
| 		} else { | ||||
| 			prompt.get(questions.mongo, dbQuestionsSuccess); | ||||
| 		} | ||||
| 	} else if(database === 'level') { | ||||
| 		if (config['level:database']) { | ||||
| 			dbQuestionsSuccess(null, config); | ||||
| 		} else { | ||||
| 			prompt.get(questions.level, dbQuestionsSuccess); | ||||
| 		} | ||||
| 	} else { | ||||
| 		return callback(new Error('unknown database : ' + database)); | ||||
| 	} | ||||
|   | ||||
| @@ -1,84 +0,0 @@ | ||||
| 'use strict'; | ||||
|  | ||||
| (function(module) { | ||||
| 	/* | ||||
| 	* Okay, so LevelDB was made by Google. Therefore it's skalable. | ||||
| 	* BUT, I created 99% of the rest of NodeBB's expected functionality out of just simple get and set commands. | ||||
| 	* Therefore, it is unskalable. I totally should have read the docs before starting. | ||||
| 	* | ||||
| 	* With much <3, psychobunny. | ||||
| 	*/ | ||||
|  | ||||
|  | ||||
| 	var winston = require('winston'), | ||||
| 		nconf = require('nconf'), | ||||
| 		path = require('path'), | ||||
| 		session = require('express-session'), | ||||
| 		utils = require('./../../public/src/utils.js'), | ||||
| 		levelup, | ||||
| 		leveldown, | ||||
| 		connectLevel, | ||||
| 		db; | ||||
|  | ||||
| 	module.questions = [ | ||||
| 		{ | ||||
| 			name: "level:database", | ||||
| 			description: "Enter the path to your Level database", | ||||
| 			'default': nconf.get('level:database') || '/var/level/nodebb' | ||||
| 		} | ||||
| 	]; | ||||
|  | ||||
| 	module.init = function(callback) { | ||||
| 		try { | ||||
| 			levelup = require('levelup'); | ||||
| 			leveldown = require('leveldown'); | ||||
| 			connectLevel = require('connect-leveldb')(session); | ||||
| 		} catch (err) { | ||||
| 			winston.error('Unable to initialize Level DB! Is Level DB installed? Error :' + err.message); | ||||
| 			process.exit(); | ||||
| 		} | ||||
|  | ||||
| 		if (db) { | ||||
| 			if(typeof callback === 'function') { | ||||
| 				callback(); | ||||
| 			} | ||||
|  | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		db = levelup(nconf.get('level:database'), { | ||||
| 			valueEncoding: 'json' | ||||
| 		}); | ||||
|  | ||||
| 		leveldown(nconf.get('level:database')); | ||||
|  | ||||
| 		db.on('error', function (err) { | ||||
| 			winston.error(err.stack); | ||||
| 		}); | ||||
|  | ||||
| 		module.client = db; | ||||
| 		module.leveldown = leveldown; | ||||
|  | ||||
| 		module.sessionStore = new connectLevel({ | ||||
| 			db: db, | ||||
| 			ttl: 60 * 60 * 24 * 14 | ||||
| 		}); | ||||
|  | ||||
| 		require('./level/main')(db, module); | ||||
| 		require('./level/hash')(db, module); | ||||
| 		require('./level/sets')(db, module); | ||||
| 		require('./level/sorted')(db, module); | ||||
| 		require('./level/list')(db, module); | ||||
|  | ||||
| 		if(typeof callback === 'function') { | ||||
| 			callback(); | ||||
| 		} | ||||
| 	}; | ||||
|  | ||||
| 	module.close = function(callback) { | ||||
| 		db.close(callback); | ||||
| 	}; | ||||
|  | ||||
| 	module.helpers = module.helpers || {}; | ||||
| 	module.helpers.level = require('./level/helpers'); | ||||
| }(exports)); | ||||
| @@ -1,146 +0,0 @@ | ||||
| "use strict"; | ||||
|  | ||||
| var async = require('async'); | ||||
|  | ||||
| module.exports = function(db, module) { | ||||
| 	var helpers = module.helpers.level; | ||||
|  | ||||
| 	module.setObject = function(key, obj, callback) { | ||||
| 		async.parallel([ | ||||
| 			function(next) { | ||||
| 				async.each(Object.keys(obj), function(objKey, next) { | ||||
| 					module.setObjectField(key, objKey, obj[objKey], next); | ||||
| 				}, next); | ||||
| 			}, | ||||
| 			function(next) { | ||||
| 				module.set(key, Object.keys(obj).join('-ldb-')); | ||||
| 				next(); | ||||
| 			} | ||||
| 		], function(err) { | ||||
| 			if (typeof callback === 'function') { | ||||
| 				callback(err); | ||||
| 			} | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	module.setObjectField = function(key, field, value, callback) { | ||||
| 		module.set(key + ':' + field, value, callback); | ||||
| 	}; | ||||
|  | ||||
| 	module.getObject = function(key, callback) { | ||||
| 		var obj = {}; | ||||
|  | ||||
| 		module.getObjectKeys(key, function(err, keys) { | ||||
| 			if (keys) { | ||||
| 				keys = keys.split('-ldb-'); | ||||
| 				async.each(keys, function(field, next) { | ||||
| 					module.getObjectField(key, field, function(err, value) { | ||||
| 						obj[field] = value; | ||||
| 						next(err); | ||||
| 					}); | ||||
| 				}, function(err) { | ||||
| 					if (typeof callback === 'function') { | ||||
| 						callback(err, obj); | ||||
| 					} | ||||
| 				}); | ||||
| 			} else { | ||||
| 				if (typeof callback === 'function') { | ||||
| 					callback(err, {}); | ||||
| 				} | ||||
| 			} | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	module.getObjects = function(keys, callback) { | ||||
| 		var arr = []; | ||||
|  | ||||
| 		async.each(keys, function(key, next) { | ||||
| 			module.getObject(key, function(err, val) { | ||||
| 				arr.push(val); | ||||
| 				next(); | ||||
| 			}); | ||||
| 		}, function(err) { | ||||
| 			callback(err, arr); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	module.getObjectField = function(key, field, callback) { | ||||
| 		module.get(key + ':' + field, function(err, val) { | ||||
| 			callback(err, typeof val !== 'undefined' ? val : ''); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	module.getObjectFields = function(key, fields, callback) { | ||||
| 		// can be improved with multi. | ||||
| 		var obj = {}; | ||||
| 		async.each(fields, function(field, next) { | ||||
| 			module.getObjectField(key, field, function(err, value) { | ||||
| 				obj[field] = value; | ||||
| 				next(); | ||||
| 			}); | ||||
| 		}, function(err) { | ||||
| 			callback(err, obj); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	module.getObjectsFields = function(keys, fields, callback) { | ||||
| 		helpers.iterator('getObjectFields', keys, fields, callback); | ||||
| 	}; | ||||
|  | ||||
| 	module.getObjectKeys = function(key, callback) { | ||||
| 		module.get(key, callback); | ||||
| 	}; | ||||
|  | ||||
| 	module.getObjectValues = function(key, callback) { | ||||
| 		module.getObject(key, function(err, obj) { | ||||
| 			var values = []; | ||||
| 			for (var key in obj) { | ||||
| 				if (obj.hasOwnProperty(key)) { | ||||
| 					values.push(obj[key]); | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			callback(err, values); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	module.isObjectField = function(key, field, callback) { | ||||
| 		module.get(key + ':' + field, function(err, val) { | ||||
| 			callback(err, !!val); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	module.deleteObjectField = function(key, field, callback) { | ||||
| 		module.delete(key + ':' + field, callback); | ||||
| 	}; | ||||
|  | ||||
| 	module.incrObjectField = function(key, field, callback) { | ||||
| 		module.incrObjectFieldBy(key, field, 1, callback); | ||||
| 	}; | ||||
|  | ||||
| 	module.decrObjectField = function(key, field, callback) { | ||||
| 		module.decrObjectFieldBy(key, field, 1, callback); | ||||
| 	}; | ||||
|  | ||||
| 	module.incrObjectFieldBy = function(key, field, value, callback) { | ||||
| 		module.get(key + ':' + field, function(err, val) { | ||||
| 			val = val ? (val + value) : value; | ||||
| 			module.set(key + ':' + field, val, function(err) { | ||||
| 				if (typeof callback === 'function') { | ||||
| 					callback(err, val); | ||||
| 				} | ||||
| 			}); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	module.decrObjectFieldBy = function(key, field, value, callback) { | ||||
| 		module.get(key + ':' + field, function(err, val) { | ||||
| 			val = val ? (val - value) : -value; | ||||
| 			module.set(key + ':' + field, val, function(err) { | ||||
| 				if (typeof callback === 'function') { | ||||
| 					callback(err, val); | ||||
| 				} | ||||
| 			}); | ||||
| 		}); | ||||
| 	}; | ||||
| }; | ||||
| @@ -1,19 +0,0 @@ | ||||
| "use strict"; | ||||
|  | ||||
| var helpers = {}, | ||||
| 	async = require('async'); | ||||
|  | ||||
| helpers.iterator = function(fn, keys, value, callback) { | ||||
| 	var results = []; | ||||
|  | ||||
| 	async.each(keys, function(key, next) { | ||||
| 		module.parent.exports[fn](key, value, function(err, result) { | ||||
| 			results.push(result); | ||||
| 			next(); | ||||
| 		}); | ||||
| 	}, function(err) { | ||||
| 		callback(err, results); | ||||
| 	}); | ||||
| }; | ||||
|  | ||||
| module.exports = helpers; | ||||
| @@ -1,56 +0,0 @@ | ||||
| "use strict"; | ||||
|  | ||||
| module.exports = function(db, module) { | ||||
| 	var helpers = module.helpers.level; | ||||
|  | ||||
| 	module.listPrepend = function(key, value, callback) { | ||||
| 		module.getListRange(key, 0, -1, function(err, list) { | ||||
| 			var arr = list || []; | ||||
| 			arr.unshift(value); | ||||
| 			module.set(key, arr, callback); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	module.listAppend = function(key, value, callback) { | ||||
| 		module.getListRange(key, 0, -1, function(err, list) { | ||||
| 			var arr = list || []; | ||||
| 			arr.push(value); | ||||
| 			module.set(key, arr, function(err) { | ||||
| 				if (typeof callback === 'function') { | ||||
| 					callback(err); | ||||
| 				} | ||||
| 			}); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	module.listRemoveLast = function(key, callback) { | ||||
| 		module.getListRange(key, 0, -1, function(err, list) { | ||||
| 			var arr = list || []; | ||||
| 			list.pop(); | ||||
| 			module.set(key, list, callback); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	module.listRemoveFirst = function(key, callback) { | ||||
| 		module.getListRange(key, 0, -1, function(err, list) { | ||||
| 			var arr = list || []; | ||||
| 			list.shift(); | ||||
| 			module.set(key, list, callback); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	module.listRemoveAll = function(key, value, callback) { | ||||
| 		module.set(key, [], callback); | ||||
| 	}; | ||||
|  | ||||
| 	module.getListRange = function(key, start, stop, callback) { | ||||
| 		// needs testing. | ||||
| 		module.get(key, function(err, list) { | ||||
| 			if (list) { | ||||
| 				callback(err, list.slice(start, stop === -1 ? list.length : stop)); | ||||
| 			} else { | ||||
| 				callback(null, []); | ||||
| 			} | ||||
| 		}); | ||||
| 	}; | ||||
| }; | ||||
| @@ -1,94 +0,0 @@ | ||||
| "use strict"; | ||||
|  | ||||
| var nconf = require('nconf'), | ||||
| 	async = require('async'); | ||||
|  | ||||
| module.exports = function(db, module) { | ||||
| 	var helpers = module.helpers.level; | ||||
|  | ||||
| 	module.searchIndex = function(key, content, id, callback) { | ||||
| 		// o.O | ||||
| 	}; | ||||
|  | ||||
| 	module.search = function(key, term, limit, callback) { | ||||
| 		// O.o | ||||
| 	}; | ||||
|  | ||||
| 	module.searchRemove = function(key, id, callback) { | ||||
| 		// o___O | ||||
| 	}; | ||||
|  | ||||
| 	module.flushdb = function(callback) { | ||||
| 		db.close(function() { | ||||
| 			module.leveldown.destroy(nconf.get('level:database'), function() { | ||||
| 				db.open(callback); | ||||
| 			}); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	module.info = function(callback) { | ||||
| 		// O____O      GIEF FOOD | ||||
| 		//  v v | ||||
| 	}; | ||||
|  | ||||
| 	module.exists = function(key, callback) { | ||||
| 		db.get(key, function(err, value) { | ||||
| 			callback(null, !!value); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	module.delete = function(key, callback) { | ||||
| 		db.del(key, callback); | ||||
| 	}; | ||||
|  | ||||
| 	module.deleteAll = function(keys, callback) { | ||||
| 		async.each(keys, module.delete, callback); | ||||
| 	}; | ||||
|  | ||||
| 	module.get = function(key, callback) { | ||||
| 		db.get(key, function(err, value) { | ||||
| 			callback(false, value); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	module.set = function(key, value, callback, sync) { | ||||
| 		if (value === '') { | ||||
| 			callback(false); | ||||
| 		} else { | ||||
| 			var options = { | ||||
| 				sync: typeof sync !== 'undefined' | ||||
| 			}; | ||||
|  | ||||
| 			db.put(key, value, options, function(err) { | ||||
| 				// uh, err is {}.. why?? | ||||
| 				if (typeof callback === 'function') { | ||||
| 					callback(null); | ||||
| 				} | ||||
| 			}); | ||||
| 		} | ||||
| 	}; | ||||
|  | ||||
| 	module.increment = function(key, callback) { | ||||
| 		// ^_^ | ||||
| 	}; | ||||
|  | ||||
| 	module.rename = function(oldKey, newKey, callback) { | ||||
| 		// G__G | ||||
| 	}; | ||||
|  | ||||
| 	module.expire = function(key, seconds, callback) { | ||||
| 		// >__> | ||||
| 	}; | ||||
|  | ||||
| 	module.expireAt = function(key, timestamp, callback) { | ||||
| 		// <__< | ||||
| 	}; | ||||
|  | ||||
| 	module.pexpire = function(key, ms, callback) { | ||||
| 		// o_o | ||||
| 	}; | ||||
|  | ||||
| 	module.pexpireAt = function(key, timestamp, callback) { | ||||
| 		// d-_-b | ||||
| 	}; | ||||
| }; | ||||
| @@ -1,82 +0,0 @@ | ||||
| "use strict"; | ||||
|  | ||||
| var async = require('async'); | ||||
|  | ||||
| module.exports = function(db, module) { | ||||
| 	var helpers = module.helpers.level; | ||||
|  | ||||
| 	module.setAdd = function(key, value, callback) { | ||||
| 		callback = callback || function() {}; | ||||
| 		module.getListRange(key, 0, -1, function(err, set) { | ||||
| 			if (err) { | ||||
| 				return callback(err); | ||||
| 			} | ||||
| 			if (set.indexOf(value) === -1) { | ||||
| 				module.listAppend(key, value, callback); | ||||
| 			} else { | ||||
| 				callback(null); | ||||
| 			} | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	module.setsAdd = function(keys, value, callback) { | ||||
| 		throw new Error('not-implemented'); | ||||
| 	}; | ||||
|  | ||||
| 	module.setRemove = function(key, value, callback) { | ||||
| 		module.getListRange(key, 0, -1, function(err, set) { | ||||
| 			module.set(key, set.splice(set.indexOf(value), 1), callback); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	module.setsRemove = function(keys, value, callback) { | ||||
| 		throw new Error('not-implemented'); | ||||
| 	}; | ||||
|  | ||||
| 	module.isSetMember = function(key, value, callback) { | ||||
| 		module.getListRange(key, 0, -1, function(err, set) { | ||||
| 			callback(err, set.indexOf(value) !== -1); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	module.isSetMembers = function(key, values, callback) { | ||||
| 		var members = {}; | ||||
|  | ||||
| 		async.each(values, function(value, next) { | ||||
| 			module.isSetMember(key, value, function(err, isMember) { | ||||
| 				members[key] = isMember; | ||||
| 			}); | ||||
| 		}, function(err) { | ||||
| 			callback(err, members); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	module.isMemberOfSets = function(sets, value, callback) { | ||||
| 		helpers.iterator('isSetMember', sets, value, callback); | ||||
| 	}; | ||||
|  | ||||
| 	module.getSetMembers = function(key, callback) { | ||||
| 		module.getListRange(key, 0, -1, function(err, set) { | ||||
| 			callback(err, set); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	module.getSetsMembers = function(keys, callback) { | ||||
| 		throw new Error('not-implemented'); | ||||
| 	}; | ||||
|  | ||||
| 	module.setCount = function(key, callback) { | ||||
| 		module.getListRange(key, 0, -1, function(err, set) { | ||||
| 			callback(err, set.length); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	module.setRemoveRandom = function(key, callback) { | ||||
| 		// how random is this? well, how random are the other implementations of this? | ||||
| 		// imo rename this to setRemoveOne | ||||
|  | ||||
| 		module.getListRange(key, 1, -1, function(err, set) { | ||||
| 			module.set(key, set, callback); | ||||
| 		}); | ||||
| 	}; | ||||
| }; | ||||
| @@ -1,299 +0,0 @@ | ||||
| "use strict"; | ||||
|  | ||||
| var async = require('async'); | ||||
|  | ||||
|  | ||||
| module.exports = function(db, module) { | ||||
| 	var helpers = module.helpers.level; | ||||
|  | ||||
| 	module.sortedSetAdd = function(key, score, value, callback) { | ||||
| 		if (Array.isArray(score) && Array.isArray(value)) { | ||||
| 			return sortedSetAddMulti(key, score, value, callback); | ||||
| 		} | ||||
| 		module.getListRange(key, 0, -1, function(err, set) { | ||||
| 			set = set.filter(function(a) {return a.value !== value.toString();}); | ||||
|  | ||||
| 			set.push({ | ||||
| 				value: value.toString(), | ||||
| 				score: parseInt(score, 10) | ||||
| 			}); | ||||
|  | ||||
| 			set.sort(function(a, b) {return a.score - b.score;}); | ||||
| 			module.set(key, set, callback); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	function sortedSetAddMulti(key, scores, values, callback) { | ||||
| 		throw new Error('not implemented'); | ||||
| 	} | ||||
|  | ||||
| 	module.sortedSetsAdd = function(keys, score, value, callback) { | ||||
| 		async.each(keys, function(key, next) { | ||||
| 			module.sortedSetAdd(key, score, value, next); | ||||
| 		}, function(err) { | ||||
| 			callback(err); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	module.sortedSetRemove = function(key, value, callback) { | ||||
| 		if (!Array.isArray(value)) { | ||||
| 			value = [value]; | ||||
| 		} | ||||
| 		module.getListRange(key, 0, -1, function(err, set) { | ||||
| 			set = set.filter(function(a) { return value.indexOf(a) === -1;}); | ||||
| 			module.set(key, set, callback); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	module.sortedSetsRemove = function(keys, value, callback) { | ||||
| 		async.each(keys, function(key, next) { | ||||
| 			module.sortedSetRemove(key, value, next); | ||||
| 		}, callback); | ||||
| 	}; | ||||
|  | ||||
| 	module.sortedSetsRemoveRangeByScore = function(keys, min, max, callback) { | ||||
| 		throw new Error('not implemented'); | ||||
| 	}; | ||||
|  | ||||
| 	function flattenSortedSet(set, callback) { | ||||
| 		callback(null, !set.length ? [] : set.reduce(function(a, b) { | ||||
| 			return (a.length ? a : [a.value]).concat([b.value]); | ||||
| 		})); | ||||
| 	} | ||||
|  | ||||
| 	module.getSortedSetRange = function(key, start, stop, callback) { | ||||
| 		module.getListRange(key, start, stop, function(err, set) { | ||||
| 			set = !set.length ? [] : set.reduce(function(a, b) { | ||||
| 				return (a.length ? a : [a.value]).concat(b.value); | ||||
| 			}); | ||||
| 			if (set.value) { | ||||
| 				set = [set.value]; | ||||
| 			} | ||||
| 			callback(err, set); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	module.getSortedSetRevRange = function(key, start, stop, callback) { | ||||
| 		module.getListRange(key, start, stop, function(err, set) { | ||||
| 			set = !set.length ? [] : set.reverse().reduce(function(a, b) { | ||||
| 				return (a.length ? a : [a.value]).concat(b.value); | ||||
| 			}); | ||||
| 			if (set.value) { | ||||
| 				set = [set.value]; | ||||
| 			} | ||||
| 			callback(err, set); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	module.getSortedSetRevRangeWithScores = function(key, start, stop, callback) { | ||||
| 		module.getListRange(key, start, stop, function(err, set) { | ||||
| 			if (err) { | ||||
| 				return callback(err); | ||||
| 			} | ||||
| 			set.sort(function(a, b) {return b.score - a.score;}); | ||||
| 			callback(null, set); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	module.getSortedSetRangeByScore = function(key, start, count, min, max, callback) { | ||||
| 		module.getListRange(key, 0, -1, function(err, list) { | ||||
| 			if (min && max) { | ||||
| 				list.filter(function(a) { | ||||
| 					return a.score >= min && a.score <= max; // to check: greater or and equal? | ||||
| 				}); | ||||
| 			} | ||||
|  | ||||
| 			flattenSortedSet(list.slice(start ? start : 0, count ? count : list.length), callback); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	module.getSortedSetRevRangeByScore = function(key, start, count, max, min, callback) { | ||||
| 		module.getListRange(key, 0, -1, function(err, list) { | ||||
| 			if (min && max) { | ||||
| 				list.filter(function(a) { | ||||
| 					return a.score >= min && a.score <= max; // to check: greater or and equal? | ||||
| 				}); | ||||
| 			} | ||||
|  | ||||
| 			flattenSortedSet(list.slice(start ? start : 0, count ? count : list.length).reverse(), callback); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	module.sortedSetCount = function(key, min, max, callback) { | ||||
| 		module.getListRange(key, 0, -1, function(err, list) { | ||||
| 			list.filter(function(a) { | ||||
| 				return a.score >= min && a.score <= max; // to check: greater or and equal? | ||||
| 			}); | ||||
|  | ||||
| 			callback(err, list.length); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	module.sortedSetCard = function(key, callback) { | ||||
| 		module.getListRange(key, 0, -1, function(err, list) { | ||||
| 			callback(err, list.length); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	module.sortedSetsCard = function(keys, callback) { | ||||
| 		async.map(keys, module.sortedSetCard, callback); | ||||
| 	}; | ||||
|  | ||||
| 	module.sortedSetRank = function(key, value, callback) { | ||||
| 		module.getListRange(key, 0, -1, function(err, list) { | ||||
| 			for (var i = 0, ii=list.length; i< ii; i++) { | ||||
| 				if (list[i].value === value) { | ||||
| 					return callback(err, i); | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			callback(err, null); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	module.sortedSetsRanks = function(keys, values, callback) { | ||||
| 		throw new Error('not implemented'); | ||||
| 	}; | ||||
|  | ||||
| 	module.sortedSetRanks = function(key, values, callback) { | ||||
| 		throw new Error('not implemented'); | ||||
| 	}; | ||||
|  | ||||
| 	module.sortedSetRevRank = function(key, value, callback) { | ||||
| 		module.getListRange(key, 0, -1, function(err, list) { | ||||
| 			for (var i = list.length - 1, ii=0; i > ii; i--) { | ||||
| 				if (list[i].value === value.toString()) { | ||||
| 					return callback(err, i); | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			callback(err, null); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	module.sortedSetScore = function(key, value, callback) { | ||||
| 		module.getListRange(key, 0, -1, function(err, list) { | ||||
| 			for (var i = 0, ii=list.length; i< ii; i++) { | ||||
| 				if (list[i].value === value.toString()) { | ||||
| 					return callback(err, list[i].score); | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			callback(err, null); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	module.sortedSetScores = function(key, values, callback) { | ||||
| 		values = values.map(function(value) { | ||||
| 			return value ? value.toString() : value; | ||||
| 		}); | ||||
|  | ||||
| 		module.getListRange(key, 0, -1, function(err, list) { | ||||
| 			if (err) { | ||||
| 				return callback(err); | ||||
| 			} | ||||
|  | ||||
| 			var map = {}; | ||||
| 			list = list.filter(function(item) { | ||||
| 				return values.indexOf(item.value) !== -1; | ||||
| 			}).forEach(function(item) { | ||||
| 				map[item.value] = item.score; | ||||
| 			}); | ||||
|  | ||||
| 			var	returnData = new Array(values.length), | ||||
| 				score; | ||||
|  | ||||
| 			for(var i=0; i<values.length; ++i) { | ||||
| 				score = map[values[i]]; | ||||
| 				returnData[i] = score ? score : null; | ||||
| 			} | ||||
|  | ||||
| 			callback(null, returnData); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	module.isSortedSetMember = function(key, value, callback) { | ||||
| 		// maybe can be improved by having a parallel array | ||||
| 		module.getListRange(key, 0, -1, function(err, list) { | ||||
| 			for (var i = 0, ii=list.length; i< ii; i++) { | ||||
| 				if (list[i].value === value.toString()) { | ||||
| 					return callback(err, true); | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			callback(err, false); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	module.isSortedSetMembers = function(key, values, callback) { | ||||
| 		module.getListRange(key, 0, -1, function(err, list) { | ||||
| 			list = list.map(function(item) { | ||||
| 				return item.value; | ||||
| 			}); | ||||
| 			values = values.map(function(value) { | ||||
| 				return list.indexOf(value.toString()) !== -1; | ||||
| 			}); | ||||
|  | ||||
| 			callback(err, values); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	module.sortedSetsScore = function(keys, value, callback) { | ||||
| 		var sets = {}; | ||||
| 		async.each(keys, function(key, next) { | ||||
| 			module.sortedSetScore(key, value, function(err, score) { | ||||
| 				sets[key] = value; | ||||
| 				next(); | ||||
| 			}); | ||||
| 		}, function(err) { | ||||
| 			callback(err, sets); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	module.getSortedSetUnion = function(sets, start, stop, callback) { | ||||
| 		sortedSetUnion(sets, false, start, stop, callback); | ||||
| 	}; | ||||
|  | ||||
| 	module.getSortedSetRevUnion = function(sets, start, stop, callback) { | ||||
| 		sortedSetUnion(sets, true, start, stop, callback); | ||||
| 	}; | ||||
|  | ||||
| 	function sortedSetUnion(sets, reverse, start, stop, callback) { | ||||
| 		async.map(sets, function(key, next) { | ||||
| 			module.getListRange(key, 0, -1, next); | ||||
| 		}, function(err, results) { | ||||
| 			if (err) { | ||||
| 				return callback(err); | ||||
| 			} | ||||
|  | ||||
| 			var data = {}; | ||||
|  | ||||
| 			results.forEach(function(set) { | ||||
| 				for(var i=0; i<set.length; ++i) { | ||||
| 					data[set[i].value] = data[set[i].value] || {value: set[i].value, score: 0}; | ||||
| 					data[set[i].value].score += parseInt(set[i].score, 10); | ||||
| 				} | ||||
| 			}); | ||||
|  | ||||
| 			var returnData = []; | ||||
|  | ||||
| 			for(var key in data) { | ||||
| 				if (data.hasOwnProperty(key)) { | ||||
| 					returnData.push(data[key]); | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			returnData = returnData.sort(function(a, b) { | ||||
| 				return reverse ? b.score - a.score : a.score - b.score; | ||||
| 			}).map(function(item) { | ||||
| 				return item.value; | ||||
| 			}); | ||||
|  | ||||
| 			callback(null, returnData); | ||||
| 		}); | ||||
| 	} | ||||
|  | ||||
| 	module.sortedSetIncrBy = function(key, increment, value, callback) { | ||||
| 		throw new Error('not implemented'); | ||||
| 	}; | ||||
| }; | ||||
| @@ -15,9 +15,6 @@ var async = require('async'), | ||||
| 		}, | ||||
| 		"mongo": { | ||||
| 			"dependencies": ["mongodb", "connect-mongo"] | ||||
| 		}, | ||||
| 		"level": { | ||||
| 			"dependencies": ["levelup", "leveldown", "connect-leveldb"] | ||||
| 		} | ||||
| 	}; | ||||
|  | ||||
| @@ -161,8 +158,7 @@ function setupConfig(next) { | ||||
| 		var	config = {}, | ||||
| 			redisQuestions = require('./database/redis').questions, | ||||
| 			mongoQuestions = require('./database/mongo').questions, | ||||
| 			levelQuestions = require('./database/level').questions, | ||||
| 			question, x, numQ, allQuestions = questions.main.concat(redisQuestions).concat(mongoQuestions.concat(levelQuestions)); | ||||
| 			question, x, numQ, allQuestions = questions.main.concat(redisQuestions).concat(mongoQuestions); | ||||
|  | ||||
| 		for(x=0,numQ=allQuestions.length;x<numQ;x++) { | ||||
| 			question = allQuestions[x]; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user