diff --git a/src/database/postgres/list.js b/src/database/postgres/list.js index 4fb4fc40f1..885adb3825 100644 --- a/src/database/postgres/list.js +++ b/src/database/postgres/list.js @@ -9,28 +9,18 @@ module.exports = function (module) { } await module.transaction(async (client) => { - async function doPrepend(value) { - await client.query({ - name: 'listPrepend', - text: ` - INSERT INTO "legacy_list" ("_key", "array") - VALUES ($1::TEXT, ARRAY[$2::TEXT]) - ON CONFLICT ("_key") - DO UPDATE SET "array" = ARRAY[$2::TEXT] || "legacy_list"."array"`, - values: [key, value], - }); - } - await helpers.ensureLegacyObjectType(client, key, 'list'); - if (Array.isArray(value)) { - // TODO: perf make single query - for (const v of value) { - // eslint-disable-next-line - await doPrepend(v); - } - return; - } - await doPrepend(value); + value = Array.isArray(value) ? value : [value]; + value.reverse(); + await client.query({ + name: 'listPrependValues', + text: ` +INSERT INTO "legacy_list" ("_key", "array") +VALUES ($1::TEXT, $2::TEXT[]) +ON CONFLICT ("_key") +DO UPDATE SET "array" = EXCLUDED.array || "legacy_list"."array"`, + values: [key, value], + }); }); }; @@ -39,27 +29,18 @@ module.exports = function (module) { return; } await module.transaction(async (client) => { - async function doAppend(value) { - await client.query({ - name: 'listAppend', - text: ` - INSERT INTO "legacy_list" ("_key", "array") - VALUES ($1::TEXT, ARRAY[$2::TEXT]) - ON CONFLICT ("_key") - DO UPDATE SET "array" = "legacy_list"."array" || ARRAY[$2::TEXT]`, - values: [key, value], - }); - } + value = Array.isArray(value) ? value : [value]; + await helpers.ensureLegacyObjectType(client, key, 'list'); - if (Array.isArray(value)) { - // TODO: perf make single query - for (const v of value) { - // eslint-disable-next-line - await doAppend(v); - } - return; - } - await doAppend(value); + await client.query({ + name: 'listAppend', + text: ` +INSERT INTO "legacy_list" ("_key", "array") +VALUES ($1::TEXT, $2::TEXT[]) +ON CONFLICT ("_key") +DO UPDATE SET "array" = "legacy_list"."array" || EXCLUDED.array`, + values: [key, value], + }); }); }; diff --git a/src/database/postgres/sorted/remove.js b/src/database/postgres/sorted/remove.js index 54bed38505..2b90dd8bc2 100644 --- a/src/database/postgres/sorted/remove.js +++ b/src/database/postgres/sorted/remove.js @@ -71,25 +71,21 @@ DELETE FROM "legacy_zset" }; module.sortedSetRemoveBulk = async function (data) { - // const keys = []; - // const values = []; - - // data.forEach(function (item) { - // keys.push(item[0]); - // values.push(item[1]); - // }); - - const promises = data.map(item => module.sortedSetRemove(item[0], item[1])); - await Promise.all(promises); + if (!Array.isArray(data) || !data.length) { + return; + } + const keys = data.map(d => d[0]); + const values = data.map(d => d[1]); - // TODO - // await query({ - // name: 'sortedSetRemoveBulk', - // text: ` - // DELETE FROM "legacy_zset" - // SELECT k, v - // FROM UNNEST($1::TEXT[], $2::TEXT[]) vs(k, v)`, - // values: [keys, values], - // }); + await module.pool.query({ + name: 'sortedSetRemoveBulk', + text: ` + DELETE FROM "legacy_zset" + WHERE (_key, value) IN ( + SELECT k, v + FROM UNNEST($1::TEXT[], $2::TEXT[]) vs(k, v) + )`, + values: [keys, values], + }); }; }; diff --git a/test/database/sorted.js b/test/database/sorted.js index 8b348961ee..ede6cc8c5d 100644 --- a/test/database/sorted.js +++ b/test/database/sorted.js @@ -1119,6 +1119,29 @@ describe('Sorted Set methods', () => { const members = await db.getSortedSetsMembers(['bulkRemove1', 'bulkRemove2']); assert.deepStrictEqual(members, [[], []]); }); + + it('should not remove wrong elements in bulk remove', async () => { + await db.sortedSetAddBulk([ + ['bulkRemove4', 1, 'value1'], + ['bulkRemove4', 2, 'value2'], + ['bulkRemove4', 3, 'value4'], + ['bulkRemove5', 1, 'value1'], + ['bulkRemove5', 2, 'value2'], + ['bulkRemove5', 3, 'value3'], + ]); + await db.sortedSetRemoveBulk([ + ['bulkRemove4', 'value1'], + ['bulkRemove4', 'value3'], + ['bulkRemove5', 'value1'], + ['bulkRemove5', 'value4'], + ]); + const members = await Promise.all([ + db.getSortedSetRange('bulkRemove4', 0, -1), + db.getSortedSetRange('bulkRemove5', 0, -1), + ]); + assert.deepStrictEqual(members[0], ['value2', 'value4']); + assert.deepStrictEqual(members[1], ['value2', 'value3']); + }); }); describe('sortedSetsRemove()', () => {