mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-30 18:46:01 +01:00
Merge pull request #5124 from yariplus/lexistuff
Add additional lexical dbal operations.
This commit is contained in:
@@ -579,16 +579,50 @@ module.exports = function (db, module) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
module.getSortedSetRangeByLex = function (key, min, max, start, count, callback) {
|
module.getSortedSetRangeByLex = function (key, min, max, start, count, callback) {
|
||||||
|
sortedSetLex(key, min, max, 1, start, count, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
module.getSortedSetRevRangeByLex = function (key, max, min, start, count, callback) {
|
||||||
|
sortedSetLex(key, min, max, -1, start, count, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
module.sortedSetLexCount = function (key, min, max, callback) {
|
||||||
|
sortedSetLex(key, min, max, 1, 0, 0, function (err, data) {
|
||||||
|
callback(err, data ? data.length : null);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
function sortedSetLex(key, min, max, sort, start, count, callback) {
|
||||||
|
if (!callback) {
|
||||||
|
callback = start;
|
||||||
|
start = 0;
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
var query = {_key: key};
|
var query = {_key: key};
|
||||||
|
|
||||||
if (min !== '-') {
|
if (min !== '-') {
|
||||||
|
if (min.match(/^\(/)) {
|
||||||
|
query.value = {$gt: min.slice(1)};
|
||||||
|
} else if (min.match(/^\[/)) {
|
||||||
|
query.value = {$gte: min.slice(1)};
|
||||||
|
} else {
|
||||||
query.value = {$gte: min};
|
query.value = {$gte: min};
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (max !== '+') {
|
if (max !== '+') {
|
||||||
query.value = query.value || {};
|
query.value = query.value || {};
|
||||||
|
if (max.match(/^\(/)) {
|
||||||
|
query.value.$lt = max.slice(1);
|
||||||
|
} else if (max.match(/^\[/)) {
|
||||||
|
query.value.$lte = max.slice(1);
|
||||||
|
} else {
|
||||||
query.value.$lte = max;
|
query.value.$lte = max;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
db.collection('objects').find(query, {_id: 0, value: 1})
|
db.collection('objects').find(query, {_id: 0, value: 1})
|
||||||
.sort({value: 1})
|
.sort({value: sort})
|
||||||
.skip(start)
|
.skip(start)
|
||||||
.limit(count === -1 ? 0 : count)
|
.limit(count === -1 ? 0 : count)
|
||||||
.toArray(function (err, data) {
|
.toArray(function (err, data) {
|
||||||
@@ -600,6 +634,36 @@ module.exports = function (db, module) {
|
|||||||
});
|
});
|
||||||
callback(err, data);
|
callback(err, data);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.sortedSetRemoveRangeByLex = function (key, min, max, callback) {
|
||||||
|
callback = callback || helpers.noop;
|
||||||
|
|
||||||
|
var query = {_key: key};
|
||||||
|
|
||||||
|
if (min !== '-') {
|
||||||
|
if (min.match(/^\(/)) {
|
||||||
|
query.value = {$gt: min.slice(1)};
|
||||||
|
} else if (min.match(/^\[/)) {
|
||||||
|
query.value = {$gte: min.slice(1)};
|
||||||
|
} else {
|
||||||
|
query.value = {$gte: min};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (max !== '+') {
|
||||||
|
query.value = query.value || {};
|
||||||
|
if (max.match(/^\(/)) {
|
||||||
|
query.value.$lt = max.slice(1);
|
||||||
|
} else if (max.match(/^\[/)) {
|
||||||
|
query.value.$lte = max.slice(1);
|
||||||
|
} else {
|
||||||
|
query.value.$lte = max;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
db.collection('objects').remove(query, function (err) {
|
||||||
|
callback(err);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
module.processSortedSet = function (setKey, process, batch, callback) {
|
module.processSortedSet = function (setKey, process, batch, callback) {
|
||||||
@@ -639,7 +703,6 @@ module.exports = function (db, module) {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
module.sortedSetIntersectCard = function (keys, callback) {
|
module.sortedSetIntersectCard = function (keys, callback) {
|
||||||
if (!Array.isArray(keys) || !keys.length) {
|
if (!Array.isArray(keys) || !keys.length) {
|
||||||
return callback(null, 0);
|
return callback(null, 0);
|
||||||
|
|||||||
@@ -293,15 +293,50 @@ module.exports = function (redisClient, module) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
module.getSortedSetRangeByLex = function (key, min, max, start, count, callback) {
|
module.getSortedSetRangeByLex = function (key, min, max, start, count, callback) {
|
||||||
if (min !== '-') {
|
sortedSetLex('zrangebylex', false, key, min, max, start, count, callback);
|
||||||
min = '[' + min;
|
|
||||||
}
|
|
||||||
if (max !== '+') {
|
|
||||||
max = '(' + max;
|
|
||||||
}
|
|
||||||
redisClient.zrangebylex([key, min, max, 'LIMIT', start, count], callback);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
module.getSortedSetRevRangeByLex = function (key, max, min, start, count, callback) {
|
||||||
|
sortedSetLex('zrevrangebylex', true, key, max, min, start, count, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
module.sortedSetRemoveRangeByLex = function (key, min, max, callback) {
|
||||||
|
callback = callback || helpers.noop;
|
||||||
|
sortedSetLex('zremrangebylex', false, key, min, max, function (err) {
|
||||||
|
callback(err);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
module.sortedSetLexCount = function (key, min, max, callback) {
|
||||||
|
sortedSetLex('zlexcount', false, key, min, max, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
function sortedSetLex(method, reverse, key, min, max, start, count, callback) {
|
||||||
|
callback = callback || start;
|
||||||
|
|
||||||
|
var minmin, maxmax;
|
||||||
|
if (reverse) {
|
||||||
|
minmin = '+';
|
||||||
|
maxmax = '-';
|
||||||
|
} else {
|
||||||
|
minmin = '-';
|
||||||
|
maxmax = '+';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (min !== minmin) {
|
||||||
|
if (!min.match(/^[\[\(]/)) min = '[' + min;
|
||||||
|
}
|
||||||
|
if (max !== maxmax) {
|
||||||
|
if (!max.match(/^[\[\(]/)) max = '[' + max;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count) {
|
||||||
|
redisClient[method]([key, min, max, 'LIMIT', start, count], callback);
|
||||||
|
} else {
|
||||||
|
redisClient[method]([key, min, max], callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module.sortedSetIntersectCard = function (keys, callback) {
|
module.sortedSetIntersectCard = function (keys, callback) {
|
||||||
if (!Array.isArray(keys) || !keys.length) {
|
if (!Array.isArray(keys) || !keys.length) {
|
||||||
return callback(null, 0);
|
return callback(null, 0);
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ describe('Sorted Set methods', function () {
|
|||||||
},
|
},
|
||||||
function (next) {
|
function (next) {
|
||||||
db.sortedSetAdd('sortedSetTest3', [2, 4], ['value2', 'value4'], next);
|
db.sortedSetAdd('sortedSetTest3', [2, 4], ['value2', 'value4'], next);
|
||||||
|
},
|
||||||
|
function (next) {
|
||||||
|
db.sortedSetAdd('sortedSetLex', [0, 0, 0, 0], ['a', 'b', 'c', 'd'], next);
|
||||||
}
|
}
|
||||||
], done);
|
], done);
|
||||||
});
|
});
|
||||||
@@ -694,6 +697,177 @@ describe('Sorted Set methods', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('getSortedSetRangeByLex', function () {
|
||||||
|
it('should return an array of all values', function (done) {
|
||||||
|
db.getSortedSetRangeByLex('sortedSetLex', '-', '+', function (err, data) {
|
||||||
|
assert.ifError(err);
|
||||||
|
assert.deepEqual(data, ['a', 'b', 'c', 'd']);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return an array with an inclusive range by default', function (done) {
|
||||||
|
db.getSortedSetRangeByLex('sortedSetLex', 'a', 'd', function (err, data) {
|
||||||
|
assert.ifError(err);
|
||||||
|
assert.deepEqual(data, ['a', 'b', 'c', 'd']);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return an array with an inclusive range', function (done) {
|
||||||
|
db.getSortedSetRangeByLex('sortedSetLex', '[a', '[d', function (err, data) {
|
||||||
|
assert.ifError(err);
|
||||||
|
assert.deepEqual(data, ['a', 'b', 'c', 'd']);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return an array with an exclusive range', function (done) {
|
||||||
|
db.getSortedSetRangeByLex('sortedSetLex', '(a', '(d', function (err, data) {
|
||||||
|
assert.ifError(err);
|
||||||
|
assert.deepEqual(data, ['b', 'c']);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return an array limited to the first two values', function (done) {
|
||||||
|
db.getSortedSetRangeByLex('sortedSetLex', '-', '+', 0, 2, function (err, data) {
|
||||||
|
assert.ifError(err);
|
||||||
|
assert.deepEqual(data, ['a', 'b']);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getSortedSetRevRangeByLex', function () {
|
||||||
|
it('should return an array of all values reversed', function (done) {
|
||||||
|
db.getSortedSetRevRangeByLex('sortedSetLex', '+', '-', function (err, data) {
|
||||||
|
assert.ifError(err);
|
||||||
|
assert.deepEqual(data, ['d', 'c', 'b', 'a']);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return an array with an inclusive range by default reversed', function (done) {
|
||||||
|
db.getSortedSetRevRangeByLex('sortedSetLex', 'd', 'a', function (err, data) {
|
||||||
|
assert.ifError(err);
|
||||||
|
assert.deepEqual(data, ['d', 'c', 'b', 'a']);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return an array with an inclusive range reversed', function (done) {
|
||||||
|
db.getSortedSetRevRangeByLex('sortedSetLex', '[d', '[a', function (err, data) {
|
||||||
|
assert.ifError(err);
|
||||||
|
assert.deepEqual(data, ['d', 'c', 'b', 'a']);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return an array with an exclusive range reversed', function (done) {
|
||||||
|
db.getSortedSetRevRangeByLex('sortedSetLex', '(d', '(a', function (err, data) {
|
||||||
|
assert.ifError(err);
|
||||||
|
assert.deepEqual(data, ['c', 'b']);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return an array limited to the first two values reversed', function (done) {
|
||||||
|
db.getSortedSetRevRangeByLex('sortedSetLex', '+', '-', 0, 2, function (err, data) {
|
||||||
|
assert.ifError(err);
|
||||||
|
assert.deepEqual(data, ['d', 'c']);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('sortedSetLexCount', function () {
|
||||||
|
it('should return the count of all values', function (done) {
|
||||||
|
db.sortedSetLexCount('sortedSetLex', '-', '+', function (err, data) {
|
||||||
|
assert.ifError(err);
|
||||||
|
assert.strictEqual(data, 4);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return the count with an inclusive range by default', function (done) {
|
||||||
|
db.sortedSetLexCount('sortedSetLex', 'a', 'd', function (err, data) {
|
||||||
|
assert.ifError(err);
|
||||||
|
assert.strictEqual(data, 4);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return the count with an inclusive range', function (done) {
|
||||||
|
db.sortedSetLexCount('sortedSetLex', '[a', '[d', function (err, data) {
|
||||||
|
assert.ifError(err);
|
||||||
|
assert.strictEqual(data, 4);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return the count with an exclusive range', function (done) {
|
||||||
|
db.sortedSetLexCount('sortedSetLex', '(a', '(d', function (err, data) {
|
||||||
|
assert.ifError(err);
|
||||||
|
assert.strictEqual(data, 2);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('sortedSetRemoveRangeByLex', function () {
|
||||||
|
before(function (done) {
|
||||||
|
db.sortedSetAdd('sortedSetLex2', [0, 0, 0, 0, 0, 0, 0], ['a', 'b', 'c', 'd', 'e', 'f', 'g'], done);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should remove an inclusive range by default', function (done) {
|
||||||
|
db.sortedSetRemoveRangeByLex('sortedSetLex2', 'a', 'b', function (err) {
|
||||||
|
assert.ifError(err);
|
||||||
|
assert.equal(arguments.length, 1);
|
||||||
|
db.getSortedSetRangeByLex('sortedSetLex2', '-', '+', function (err, data) {
|
||||||
|
assert.ifError(err);
|
||||||
|
assert.deepEqual(data, ['c', 'd', 'e', 'f', 'g']);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should remove an inclusive range', function (done) {
|
||||||
|
db.sortedSetRemoveRangeByLex('sortedSetLex2', '[c', '[d', function (err) {
|
||||||
|
assert.ifError(err);
|
||||||
|
assert.equal(arguments.length, 1);
|
||||||
|
db.getSortedSetRangeByLex('sortedSetLex2', '-', '+', function (err, data) {
|
||||||
|
assert.ifError(err);
|
||||||
|
assert.deepEqual(data, ['e', 'f', 'g']);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should remove an exclusive range', function (done) {
|
||||||
|
db.sortedSetRemoveRangeByLex('sortedSetLex2', '(e', '(g', function (err) {
|
||||||
|
assert.ifError(err);
|
||||||
|
assert.equal(arguments.length, 1);
|
||||||
|
db.getSortedSetRangeByLex('sortedSetLex2', '-', '+', function (err, data) {
|
||||||
|
assert.ifError(err);
|
||||||
|
assert.deepEqual(data, ['e', 'g']);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should remove all values', function (done) {
|
||||||
|
db.sortedSetRemoveRangeByLex('sortedSetLex2', '-', '+', function (err) {
|
||||||
|
assert.ifError(err);
|
||||||
|
assert.equal(arguments.length, 1);
|
||||||
|
db.getSortedSetRangeByLex('sortedSetLex2', '-', '+', function (err, data) {
|
||||||
|
assert.ifError(err);
|
||||||
|
assert.deepEqual(data, []);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
after(function (done) {
|
after(function (done) {
|
||||||
db.emptydb(done);
|
db.emptydb(done);
|
||||||
|
|||||||
Reference in New Issue
Block a user