* feat: zscan

* fix: mongodb tests

* feat: scan, ip search starts with
v1.18.x
Barış Soner Uşaklı 5 years ago committed by GitHub
parent be85123ad5
commit e95cd28f6f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,6 +1,7 @@
'use strict'; 'use strict';
var helpers = module.exports; const helpers = module.exports;
const utils = require('../../utils');
helpers.noop = function () {}; helpers.noop = function () {};
@ -48,3 +49,21 @@ helpers.deserializeData = function (data) {
helpers.valueToString = function (value) { helpers.valueToString = function (value) {
return String(value); return String(value);
}; };
helpers.buildMatchQuery = function (match) {
let _match = match;
if (match.startsWith('*')) {
_match = _match.substring(1);
}
if (match.endsWith('*')) {
_match = _match.substring(0, _match.length - 1);
}
_match = utils.escapeRegexChars(_match);
if (!match.startsWith('*')) {
_match = '^' + _match;
}
if (!match.endsWith('*')) {
_match += '$';
}
return _match;
};

@ -1,6 +1,7 @@
'use strict'; 'use strict';
module.exports = function (module) { module.exports = function (module) {
const helpers = require('./helpers');
module.flushdb = async function () { module.flushdb = async function () {
await module.client.dropDatabase(); await module.client.dropDatabase();
}; };
@ -27,6 +28,13 @@ module.exports = function (module) {
return item !== undefined && item !== null; return item !== undefined && item !== null;
}; };
module.scan = async function (params) {
const match = helpers.buildMatchQuery(params.match);
return await module.client.collection('objects').distinct(
'_key', { _key: { $regex: new RegExp(match) } }
);
};
module.delete = async function (key) { module.delete = async function (key) {
if (!key) { if (!key) {
return; return;

@ -472,20 +472,7 @@ module.exports = function (module) {
project.score = 1; project.score = 1;
} }
let match = params.match; const match = helpers.buildMatchQuery(params.match);
if (params.match.startsWith('*')) {
match = match.substring(1);
}
if (params.match.endsWith('*')) {
match = match.substring(0, match.length - 1);
}
match = utils.escapeRegexChars(match);
if (!params.match.startsWith('*')) {
match = '^' + match;
}
if (!params.match.endsWith('*')) {
match += '$';
}
let regex; let regex;
try { try {
regex = new RegExp(match); regex = new RegExp(match);

@ -42,6 +42,25 @@ module.exports = function (module) {
return res.rows[0].e; return res.rows[0].e;
}; };
module.scan = async function (params) {
let match = params.match;
if (match.startsWith('*')) {
match = '%' + match.substring(1);
}
if (match.endsWith('*')) {
match = match.substring(0, match.length - 1) + '%';
}
const res = await module.pool.query({
text: `
SELECT o."_key"
FROM "legacy_object_live" o
WHERE o."_key" LIKE '${match}'`,
});
return res.rows.map(r => r._key);
};
module.delete = async function (key) { module.delete = async function (key) {
if (!key) { if (!key) {
return; return;

@ -23,6 +23,18 @@ module.exports = function (module) {
return exists === 1; return exists === 1;
}; };
module.scan = async function (params) {
let cursor = '0';
let returnData = [];
do {
/* eslint-disable no-await-in-loop */
const res = await module.client.async.scan(cursor, 'MATCH', params.match, 'COUNT', 10000);
cursor = res[0];
returnData = returnData.concat(res[1]);
} while (cursor !== '0');
return returnData;
};
module.delete = async function (key) { module.delete = async function (key) {
await module.client.async.del(key); await module.client.async.del(key);
module.objectCache.delObjectCache(key); module.objectCache.delObjectCache(key);

@ -7,6 +7,7 @@ module.exports = function (redisClient) {
send_command: util.promisify(redisClient.send_command).bind(redisClient), send_command: util.promisify(redisClient.send_command).bind(redisClient),
exists: util.promisify(redisClient.exists).bind(redisClient), exists: util.promisify(redisClient.exists).bind(redisClient),
scan: util.promisify(redisClient.scan).bind(redisClient),
del: util.promisify(redisClient.del).bind(redisClient), del: util.promisify(redisClient.del).bind(redisClient),
get: util.promisify(redisClient.get).bind(redisClient), get: util.promisify(redisClient.get).bind(redisClient),

@ -1,6 +1,8 @@
'use strict'; 'use strict';
const _ = require('lodash');
const meta = require('../meta'); const meta = require('../meta');
const plugins = require('../plugins'); const plugins = require('../plugins');
const db = require('../database'); const db = require('../database');
@ -128,6 +130,8 @@ module.exports = function (User) {
} }
async function searchByIP(ip) { async function searchByIP(ip) {
return await db.getSortedSetRevRange('ip:' + ip + ':uid', 0, -1); const ipKeys = await db.scan({ match: 'ip:' + ip + '*' });
const uids = await db.getSortedSetRevRange(ipKeys, 0, -1);
return _.uniq(uids);
} }
}; };

@ -61,6 +61,21 @@ describe('Key methods', function () {
}); });
}); });
describe('scan', function () {
it('should scan keys for pattern', async function () {
await db.sortedSetAdd('ip:123:uid', 1, 'a');
await db.sortedSetAdd('ip:123:uid', 2, 'b');
await db.sortedSetAdd('ip:124:uid', 2, 'b');
await db.sortedSetAdd('ip:1:uid', 1, 'a');
await db.sortedSetAdd('ip:23:uid', 1, 'a');
const data = await db.scan({ match: 'ip:1*' });
assert.equal(data.length, 3);
assert(data.includes('ip:123:uid'));
assert(data.includes('ip:124:uid'));
assert(data.includes('ip:1:uid'));
});
});
it('should delete a key without error', function (done) { it('should delete a key without error', function (done) {
db.delete('testKey', function (err) { db.delete('testKey', function (err) {
assert.ifError(err); assert.ifError(err);

Loading…
Cancel
Save