test: return empty array on db.exists([]);

This commit is contained in:
Barış Soner Uşaklı
2024-06-07 21:44:57 -04:00
parent 70b4a0e2ae
commit 1b283ccc29
4 changed files with 52 additions and 22 deletions

View File

@@ -17,11 +17,14 @@ module.exports = function (module) {
}
if (Array.isArray(key)) {
if (!key.length) {
return [];
}
const data = await module.client.collection('objects').find({
_key: { $in: key },
}, { _id: 0, _key: 1 }).toArray();
const map = {};
const map = Object.create(null);
data.forEach((item) => {
map[item._key] = true;
});

View File

@@ -16,28 +16,48 @@ module.exports = function (module) {
if (!key) {
return;
}
const isArray = Array.isArray(key);
if (isArray && !key.length) {
return [];
}
// Redis/Mongo consider empty zsets as non-existent, match that behaviour
const type = await module.type(key);
if (type === 'zset') {
if (Array.isArray(key)) {
const members = await Promise.all(key.map(key => module.getSortedSetRange(key, 0, 0)));
async function checkIfzSetsExist(keys) {
const members = await Promise.all(
keys.map(key => module.getSortedSetRange(key, 0, 0))
);
return members.map(member => member.length > 0);
}
const members = await module.getSortedSetRange(key, 0, 0);
return members.length > 0;
}
if (Array.isArray(key)) {
async function checkIfKeysExist(keys) {
const res = await module.pool.query({
name: 'existsArray',
text: `
SELECT o."_key" k
FROM "legacy_object_live" o
WHERE o."_key" = ANY($1::TEXT[])`,
values: [key],
values: [keys],
});
return key.map(k => res.rows.some(r => r.k === k));
return keys.map(k => res.rows.some(r => r.k === k));
}
// Redis/Mongo consider empty zsets as non-existent, match that behaviour
if (isArray) {
const types = await Promise.all(key.map(module.type));
const zsetKeys = key.filter((_key, i) => types[i] === 'zset');
const otherKeys = key.filter((_key, i) => types[i] !== 'zset');
const [zsetExits, otherExists] = await Promise.all([
checkIfzSetsExist(zsetKeys),
checkIfKeysExist(otherKeys),
]);
const existsMap = Object.create(null);
zsetKeys.forEach((k, i) => { existsMap[k] = zsetExits[i]; });
otherKeys.forEach((k, i) => { existsMap[k] = otherExists[i]; });
return key.map(k => existsMap[k]);
}
const type = await module.type(key);
if (type === 'zset') {
const members = await module.getSortedSetRange(key, 0, 0);
return members.length > 0;
}
const res = await module.pool.query({
name: 'exists',
@@ -48,6 +68,7 @@ module.exports = function (module) {
LIMIT 1) e`,
values: [key],
});
return res.rows[0].e;
};

View File

@@ -14,6 +14,9 @@ module.exports = function (module) {
module.exists = async function (key) {
if (Array.isArray(key)) {
if (!key.length) {
return [];
}
const batch = module.client.batch();
key.forEach(key => batch.exists(key));
const data = await helpers.execBatch(batch);

View File

@@ -64,12 +64,15 @@ describe('Key methods', () => {
});
});
it('should work for an array of keys', (done) => {
db.exists(['testKey', 'doesnotexist'], (err, exists) => {
assert.ifError(err);
assert.deepStrictEqual(exists, [true, false]);
done();
});
it('should work for an array of keys', async () => {
assert.deepStrictEqual(
await db.exists(['testKey', 'doesnotexist']),
[true, false]
);
assert.deepStrictEqual(
await db.exists([]),
[]
);
});
describe('scan', () => {