diff --git a/src/database/mongo/sets.js b/src/database/mongo/sets.js index 0dafb61945..eacf60ed7a 100644 --- a/src/database/mongo/sets.js +++ b/src/database/mongo/sets.js @@ -100,11 +100,17 @@ module.exports = function (module) { value = value.map(v => helpers.valueToString(v)); - await module.client.collection('objects').updateMany({ + const coll = module.client.collection('objects'); + await coll.updateMany({ _key: Array.isArray(key) ? { $in: key } : key, }, { $pullAll: { members: value }, }); + + await coll.deleteMany({ + _key: Array.isArray(key) ? { $in: key } : key, + members: { $size: 0 }, + }); }; module.setsRemove = async function (keys, value) { @@ -113,11 +119,17 @@ module.exports = function (module) { } value = helpers.valueToString(value); - await module.client.collection('objects').updateMany({ + const coll = module.client.collection('objects'); + await coll.updateMany({ _key: { $in: keys }, }, { $pull: { members: value }, }); + + await coll.deleteMany({ + _key: { $in: keys }, + members: { $size: 0 }, + }); }; module.isSetMember = async function (key, value) { diff --git a/src/database/postgres/main.js b/src/database/postgres/main.js index 5b3c7f7e9d..f082521a1d 100644 --- a/src/database/postgres/main.js +++ b/src/database/postgres/main.js @@ -28,6 +28,11 @@ module.exports = function (module) { return members.map(member => member.length > 0); } + async function checkIfSetsExist(keys) { + const members = await Promise.all(keys.map(module.getSetMembers)); + return members.map(member => member.length > 0); + } + async function checkIfKeysExist(keys) { const res = await module.pool.query({ name: 'existsArray', @@ -44,13 +49,16 @@ module.exports = function (module) { 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([ + const setKeys = key.filter((_key, i) => types[i] === 'set'); + const otherKeys = key.filter((_key, i) => types[i] !== 'zset' && types[i] !== 'set'); + const [zsetExits, setExists, otherExists] = await Promise.all([ checkIfzSetsExist(zsetKeys), + checkIfSetsExist(setKeys), checkIfKeysExist(otherKeys), ]); const existsMap = Object.create(null); zsetKeys.forEach((k, i) => { existsMap[k] = zsetExits[i]; }); + setKeys.forEach((k, i) => { existsMap[k] = setExists[i]; }); otherKeys.forEach((k, i) => { existsMap[k] = otherExists[i]; }); return key.map(k => existsMap[k]); } @@ -58,6 +66,9 @@ module.exports = function (module) { if (type === 'zset') { const members = await module.getSortedSetRange(key, 0, 0); return members.length > 0; + } else if (type === 'set') { + const members = await module.getSetMembers(key); + return members.length > 0; } const res = await module.pool.query({ name: 'exists', diff --git a/test/database/sets.js b/test/database/sets.js index e8e7a454c6..05d969353f 100644 --- a/test/database/sets.js +++ b/test/database/sets.js @@ -238,57 +238,42 @@ describe('Set methods', () => { }); describe('setRemove()', () => { - before((done) => { - db.setAdd('testSet6', [1, 2], done); + it('should remove an element from set', async () => { + await db.setAdd('testSet6', [1, 2]); + await db.setRemove('testSet6', '2'); + + const isMember = await db.isSetMember('testSet6', '2'); + assert.equal(isMember, false); }); - it('should remove a element from set', (done) => { - db.setRemove('testSet6', '2', function (err) { - assert.equal(err, null); - assert.equal(arguments.length, 1); + it('should remove multiple elements from set', async () => { + await db.setAdd('multiRemoveSet', [1, 2, 3, 4, 5]); + await db.setRemove('multiRemoveSet', [1, 3, 5]); - db.isSetMember('testSet6', '2', (err, isMember) => { - assert.equal(err, null); - assert.equal(isMember, false); - done(); - }); - }); + const members = await db.getSetMembers('multiRemoveSet'); + assert(members.includes('2')); + assert(members.includes('4')); }); - it('should remove multiple elements from set', (done) => { - db.setAdd('multiRemoveSet', [1, 2, 3, 4, 5], (err) => { - assert.ifError(err); - db.setRemove('multiRemoveSet', [1, 3, 5], (err) => { - assert.ifError(err); - db.getSetMembers('multiRemoveSet', (err, members) => { - assert.ifError(err); - assert(members.includes('2')); - assert(members.includes('4')); - done(); - }); - }); - }); + it('should remove multiple values from multiple keys', async () => { + await db.setAdd('multiSetTest1', ['one', 'two', 'three', 'four']); + await db.setAdd('multiSetTest2', ['three', 'four', 'five', 'six']); + await db.setRemove(['multiSetTest1', 'multiSetTest2'], ['three', 'four', 'five', 'doesnt exist']); + + const members = await db.getSetsMembers(['multiSetTest1', 'multiSetTest2']); + assert.equal(members[0].length, 2); + assert.equal(members[1].length, 1); + assert(members[0].includes('one')); + assert(members[0].includes('two')); + assert(members[1].includes('six')); }); - it('should remove multiple values from multiple keys', (done) => { - db.setAdd('multiSetTest1', ['one', 'two', 'three', 'four'], (err) => { - assert.ifError(err); - db.setAdd('multiSetTest2', ['three', 'four', 'five', 'six'], (err) => { - assert.ifError(err); - db.setRemove(['multiSetTest1', 'multiSetTest2'], ['three', 'four', 'five', 'doesnt exist'], (err) => { - assert.ifError(err); - db.getSetsMembers(['multiSetTest1', 'multiSetTest2'], (err, members) => { - assert.ifError(err); - assert.equal(members[0].length, 2); - assert.equal(members[1].length, 1); - assert(members[0].includes('one')); - assert(members[0].includes('two')); - assert(members[1].includes('six')); - done(); - }); - }); - }); - }); + it('should remove set if all elements are removed', async () => { + await db.setAdd('toBeDeletedSet', ['a', 'b']); + await db.setRemove('toBeDeletedSet', ['a', 'b']); + + const exists = await db.exists('toBeDeletedSet'); + assert.equal(exists, false); }); });